diff --git a/code/ATMOSPHERICS/components/binary_devices/algae_generator_vr.dm b/code/ATMOSPHERICS/components/binary_devices/algae_generator_vr.dm index 454d04ff44..391f10bc6e 100644 --- a/code/ATMOSPHERICS/components/binary_devices/algae_generator_vr.dm +++ b/code/ATMOSPHERICS/components/binary_devices/algae_generator_vr.dm @@ -200,7 +200,7 @@ "moles" = round(air2.gas[output_gas], 0.01)) // update the ui if it exists, returns null if no ui is passed/found - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "algae_farm_vr.tmpl", "Algae Farm Control Panel", 500, 600) ui.set_initial_data(data) diff --git a/code/ATMOSPHERICS/components/binary_devices/circulator.dm b/code/ATMOSPHERICS/components/binary_devices/circulator.dm index 5e2bbce6da..044d6b0c13 100644 --- a/code/ATMOSPHERICS/components/binary_devices/circulator.dm +++ b/code/ATMOSPHERICS/components/binary_devices/circulator.dm @@ -125,24 +125,24 @@ ..() /obj/machinery/atmospherics/binary/circulator/verb/rotate_clockwise() + set name = "Rotate Circulator Clockwise" + set category = "Object" + set src in view(1) + + if (usr.stat || usr.restrained() || anchored) + return + + src.set_dir(turn(src.dir, 270)) + desc = initial(desc) + " Its outlet port is to the [dir2text(dir)]." + + +/obj/machinery/atmospherics/binary/circulator/verb/rotate_counterclockwise() + set name = "Rotate Circulator Counterclockwise" set category = "Object" - set name = "Rotate Circulator (Clockwise)" set src in view(1) if (usr.stat || usr.restrained() || anchored) return src.set_dir(turn(src.dir, 90)) - desc = initial(desc) + " Its outlet port is to the [dir2text(dir)]." - - -/obj/machinery/atmospherics/binary/circulator/verb/rotate_anticlockwise() - set category = "Object" - set name = "Rotate Circulator (Counterclockwise)" - set src in view(1) - - if (usr.stat || usr.restrained() || anchored) - return - - src.set_dir(turn(src.dir, -90)) desc = initial(desc) + " Its outlet port is to the [dir2text(dir)]." \ No newline at end of file diff --git a/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm b/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm index d696aad039..a72aae425b 100644 --- a/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm @@ -194,7 +194,7 @@ return 1 -/obj/machinery/atmospherics/binary/dp_vent_pump/initialize() +/obj/machinery/atmospherics/binary/dp_vent_pump/Initialize() . = ..() if(frequency) set_frequency(frequency) diff --git a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm index 3988b790c8..5abaa00c60 100644 --- a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm +++ b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm @@ -129,7 +129,7 @@ return 1 -/obj/machinery/atmospherics/binary/passive_gate/initialize() +/obj/machinery/atmospherics/binary/passive_gate/Initialize() . = ..() if(frequency) set_frequency(frequency) @@ -197,7 +197,7 @@ ) // update the ui if it exists, returns null if no ui is passed/found - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.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 diff --git a/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm b/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm index d26422c309..a7c8fd6d38 100644 --- a/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm +++ b/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm @@ -20,209 +20,210 @@ var/datum/pipe_network/network1 var/datum/pipe_network/network2 - New() - ..() - air_in.volume = 200 - air_out.volume = 800 - volume_ratio = air_in.volume / (air_in.volume + air_out.volume) - switch(dir) - if(NORTH) +/obj/machinery/atmospherics/pipeturbine/New() + ..() + air_in.volume = 200 + air_out.volume = 800 + volume_ratio = air_in.volume / (air_in.volume + air_out.volume) + switch(dir) + if(NORTH) + initialize_directions = EAST|WEST + if(SOUTH) + initialize_directions = EAST|WEST + if(EAST) + initialize_directions = NORTH|SOUTH + if(WEST) + initialize_directions = NORTH|SOUTH + +/obj/machinery/atmospherics/pipeturbine/Destroy() + . = ..() + + if(node1) + node1.disconnect(src) + qdel(network1) + if(node2) + node2.disconnect(src) + qdel(network2) + + node1 = null + node2 = null + +/obj/machinery/atmospherics/pipeturbine/process() + ..() + if(anchored && !(stat&BROKEN)) + kin_energy *= 1 - kin_loss + dP = max(air_in.return_pressure() - air_out.return_pressure(), 0) + if(dP > 10) + kin_energy += 1/ADIABATIC_EXPONENT * dP * air_in.volume * (1 - volume_ratio**ADIABATIC_EXPONENT) * efficiency + air_in.temperature *= volume_ratio**ADIABATIC_EXPONENT + + var/datum/gas_mixture/air_all = new + air_all.volume = air_in.volume + air_out.volume + air_all.merge(air_in.remove_ratio(1)) + air_all.merge(air_out.remove_ratio(1)) + + air_in.merge(air_all.remove(volume_ratio)) + air_out.merge(air_all) + + update_icon() + + if (network1) + network1.update = 1 + if (network2) + network2.update = 1 + +/obj/machinery/atmospherics/pipeturbine/update_icon() + overlays.Cut() + if (dP > 10) + overlays += image('icons/obj/pipeturbine.dmi', "moto-turb") + if (kin_energy > 100000) + overlays += image('icons/obj/pipeturbine.dmi', "low-turb") + if (kin_energy > 500000) + overlays += image('icons/obj/pipeturbine.dmi', "med-turb") + if (kin_energy > 1000000) + overlays += image('icons/obj/pipeturbine.dmi', "hi-turb") + +/obj/machinery/atmospherics/pipeturbine/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(W.is_wrench()) + anchored = !anchored + playsound(src, W.usesound, 50, 1) + to_chat(user, "You [anchored ? "secure" : "unsecure"] the bolts holding \the [src] to the floor.") + + if(anchored) + if(dir & (NORTH|SOUTH)) initialize_directions = EAST|WEST - if(SOUTH) - initialize_directions = EAST|WEST - if(EAST) - initialize_directions = NORTH|SOUTH - if(WEST) + else if(dir & (EAST|WEST)) initialize_directions = NORTH|SOUTH - Destroy() - . = ..() - - if(node1) - node1.disconnect(src) - qdel(network1) - if(node2) - node2.disconnect(src) - qdel(network2) - - node1 = null - node2 = null - - process() - ..() - if(anchored && !(stat&BROKEN)) - kin_energy *= 1 - kin_loss - dP = max(air_in.return_pressure() - air_out.return_pressure(), 0) - if(dP > 10) - kin_energy += 1/ADIABATIC_EXPONENT * dP * air_in.volume * (1 - volume_ratio**ADIABATIC_EXPONENT) * efficiency - air_in.temperature *= volume_ratio**ADIABATIC_EXPONENT - - var/datum/gas_mixture/air_all = new - air_all.volume = air_in.volume + air_out.volume - air_all.merge(air_in.remove_ratio(1)) - air_all.merge(air_out.remove_ratio(1)) - - air_in.merge(air_all.remove(volume_ratio)) - air_out.merge(air_all) - - update_icon() - - if (network1) - network1.update = 1 - if (network2) - network2.update = 1 - - update_icon() - overlays.Cut() - if (dP > 10) - overlays += image('icons/obj/pipeturbine.dmi', "moto-turb") - if (kin_energy > 100000) - overlays += image('icons/obj/pipeturbine.dmi', "low-turb") - if (kin_energy > 500000) - overlays += image('icons/obj/pipeturbine.dmi', "med-turb") - if (kin_energy > 1000000) - overlays += image('icons/obj/pipeturbine.dmi', "hi-turb") - - attackby(obj/item/weapon/W as obj, mob/user as mob) - if(W.is_wrench()) - anchored = !anchored - playsound(src, W.usesound, 50, 1) - to_chat(user, "You [anchored ? "secure" : "unsecure"] the bolts holding \the [src] to the floor.") - - if(anchored) - if(dir & (NORTH|SOUTH)) - initialize_directions = EAST|WEST - else if(dir & (EAST|WEST)) - initialize_directions = NORTH|SOUTH - - atmos_init() - build_network() - if (node1) - node1.atmos_init() - node1.build_network() - if (node2) - node2.atmos_init() - node2.build_network() - else - if(node1) - node1.disconnect(src) - qdel(network1) - if(node2) - node2.disconnect(src) - qdel(network2) - - node1 = null - node2 = null - + atmos_init() + build_network() + if (node1) + node1.atmos_init() + node1.build_network() + if (node2) + node2.atmos_init() + node2.build_network() else - ..() + if(node1) + node1.disconnect(src) + qdel(network1) + if(node2) + node2.disconnect(src) + qdel(network2) - verb/rotate_clockwise() - set category = "Object" - set name = "Rotate Circulator (Clockwise)" - set src in view(1) - - if (usr.stat || usr.restrained() || anchored) - return - - src.set_dir(turn(src.dir, -90)) - - - verb/rotate_anticlockwise() - set category = "Object" - set name = "Rotate Circulator (Counterclockwise)" - set src in view(1) - - if (usr.stat || usr.restrained() || anchored) - return - - src.set_dir(turn(src.dir, 90)) - -//Goddamn copypaste from binary base class because atmospherics machinery API is not damn flexible - get_neighbor_nodes_for_init() - return list(node1, node2) - - network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference) - if(reference == node1) - network1 = new_network - - else if(reference == node2) - network2 = new_network - - if(new_network.normal_members.Find(src)) - return 0 - - new_network.normal_members += src - - return null - - atmos_init() - if(node1 && node2) return - - var/node2_connect = turn(dir, -90) - var/node1_connect = turn(dir, 90) - - for(var/obj/machinery/atmospherics/target in get_step(src,node1_connect)) - if(target.initialize_directions & get_dir(target,src)) - node1 = target - break - - for(var/obj/machinery/atmospherics/target in get_step(src,node2_connect)) - if(target.initialize_directions & get_dir(target,src)) - node2 = target - break - - build_network() - if(!network1 && node1) - network1 = new /datum/pipe_network() - network1.normal_members += src - network1.build_network(node1, src) - - if(!network2 && node2) - network2 = new /datum/pipe_network() - network2.normal_members += src - network2.build_network(node2, src) - - - return_network(obj/machinery/atmospherics/reference) - build_network() - - if(reference==node1) - return network1 - - if(reference==node2) - return network2 - - return null - - reassign_network(datum/pipe_network/old_network, datum/pipe_network/new_network) - if(network1 == old_network) - network1 = new_network - if(network2 == old_network) - network2 = new_network - - return 1 - - return_network_air(datum/pipe_network/reference) - var/list/results = list() - - if(network1 == reference) - results += air_in - if(network2 == reference) - results += air_out - - return results - - disconnect(obj/machinery/atmospherics/reference) - if(reference==node1) - qdel(network1) node1 = null - - else if(reference==node2) - qdel(network2) node2 = null - return null + return + ..() + +/obj/machinery/atmospherics/pipeturbine/verb/rotate_clockwise() + set name = "Rotate Turbine Clockwise" + set category = "Object" + set src in view(1) + + if (usr.stat || usr.restrained() || anchored) + return + + src.set_dir(turn(src.dir, 270)) + + +/obj/machinery/atmospherics/pipeturbine/verb/rotate_counterclockwise() + set name = "Rotate Turbine Counterclockwise" + set category = "Object" + set src in view(1) + + if (usr.stat || usr.restrained() || anchored) + return + + src.set_dir(turn(src.dir, 90)) + +//Goddamn copypaste from binary base class because atmospherics machinery API is not damn flexible +/obj/machinery/atmospherics/pipeturbine/get_neighbor_nodes_for_init() + return list(node1, node2) + +/obj/machinery/atmospherics/pipeturbine/network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference) + if(reference == node1) + network1 = new_network + + else if(reference == node2) + network2 = new_network + + if(new_network.normal_members.Find(src)) + return 0 + + new_network.normal_members += src + + return null + +/obj/machinery/atmospherics/pipeturbine/atmos_init() + if(node1 && node2) + return + + var/node2_connect = turn(dir, -90) + var/node1_connect = turn(dir, 90) + + for(var/obj/machinery/atmospherics/target in get_step(src,node1_connect)) + if(target.initialize_directions & get_dir(target,src)) + node1 = target + break + + for(var/obj/machinery/atmospherics/target in get_step(src,node2_connect)) + if(target.initialize_directions & get_dir(target,src)) + node2 = target + break + +/obj/machinery/atmospherics/pipeturbine/build_network() + if(!network1 && node1) + network1 = new /datum/pipe_network() + network1.normal_members += src + network1.build_network(node1, src) + + if(!network2 && node2) + network2 = new /datum/pipe_network() + network2.normal_members += src + network2.build_network(node2, src) + + +/obj/machinery/atmospherics/pipeturbine/return_network(obj/machinery/atmospherics/reference) + build_network() + + if(reference==node1) + return network1 + + if(reference==node2) + return network2 + + return null + +/obj/machinery/atmospherics/pipeturbine/reassign_network(datum/pipe_network/old_network, datum/pipe_network/new_network) + if(network1 == old_network) + network1 = new_network + if(network2 == old_network) + network2 = new_network + + return 1 + +/obj/machinery/atmospherics/pipeturbine/return_network_air(datum/pipe_network/reference) + var/list/results = list() + + if(network1 == reference) + results += air_in + if(network2 == reference) + results += air_out + + return results + +/obj/machinery/atmospherics/pipeturbine/disconnect(obj/machinery/atmospherics/reference) + if(reference==node1) + qdel(network1) + node1 = null + + else if(reference==node2) + qdel(network2) + node2 = null + + return null /obj/machinery/power/turbinemotor @@ -236,54 +237,53 @@ var/kin_to_el_ratio = 0.1 //How much kinetic energy will be taken from turbine and converted into electricity var/obj/machinery/atmospherics/pipeturbine/turbine - New() - ..() - spawn(1) - updateConnection() - - proc/updateConnection() - turbine = null - if(src.loc && anchored) - turbine = locate(/obj/machinery/atmospherics/pipeturbine) in get_step(src,dir) - if (turbine.stat & (BROKEN) || !turbine.anchored || turn(turbine.dir,180) != dir) - turbine = null - - process() +/obj/machinery/power/turbinemotor/New() + ..() + spawn(1) updateConnection() - if(!turbine || !anchored || stat & (BROKEN)) - return - var/power_generated = kin_to_el_ratio * turbine.kin_energy - turbine.kin_energy -= power_generated - add_avail(power_generated) - - - attackby(obj/item/weapon/W as obj, mob/user as mob) - if(W.is_wrench()) - anchored = !anchored - playsound(src, W.usesound, 50, 1) +/obj/machinery/power/turbinemotor/proc/updateConnection() + turbine = null + if(src.loc && anchored) + turbine = locate(/obj/machinery/atmospherics/pipeturbine) in get_step(src,dir) + if (turbine.stat & (BROKEN) || !turbine.anchored || turn(turbine.dir,180) != dir) turbine = null - to_chat(user, "You [anchored ? "secure" : "unsecure"] the bolts holding \the [src] to the floor.") - updateConnection() - else - ..() - verb/rotate_clock() - set category = "Object" - set name = "Rotate Motor Clockwise" - set src in view(1) +/obj/machinery/power/turbinemotor/process() + updateConnection() + if(!turbine || !anchored || stat & (BROKEN)) + return - if (usr.stat || usr.restrained() || anchored) - return + var/power_generated = kin_to_el_ratio * turbine.kin_energy + turbine.kin_energy -= power_generated + add_avail(power_generated) - src.set_dir(turn(src.dir, -90)) +/obj/machinery/power/turbinemotor/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(W.is_wrench()) + anchored = !anchored + playsound(src, W.usesound, 50, 1) + turbine = null + to_chat(user, "You [anchored ? "secure" : "unsecure"] the bolts holding \the [src] to the floor.") + updateConnection() + else + ..() - verb/rotate_anticlock() - set category = "Object" - set name = "Rotate Motor Counterclockwise" - set src in view(1) +/obj/machinery/power/turbinemotor/verb/rotate_clockwise() + set name = "Rotate Motor Clockwise" + set category = "Object" + set src in view(1) - if (usr.stat || usr.restrained() || anchored) - return + if (usr.stat || usr.restrained() || anchored) + return - src.set_dir(turn(src.dir, 90)) + src.set_dir(turn(src.dir, 270)) + +/obj/machinery/power/turbinemotor/verb/rotate_counterclockwise() + set name = "Rotate Motor Counterclockwise" + set category = "Object" + set src in view(1) + + if (usr.stat || usr.restrained() || anchored) + return + + src.set_dir(turn(src.dir, 90)) \ No newline at end of file diff --git a/code/ATMOSPHERICS/components/binary_devices/pump.dm b/code/ATMOSPHERICS/components/binary_devices/pump.dm index b03206b262..1f1c4ff1ae 100644 --- a/code/ATMOSPHERICS/components/binary_devices/pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/pump.dm @@ -140,7 +140,7 @@ Thus, the two variables affect pump operation are set in New(): ) // update the ui if it exists, returns null if no ui is passed/found - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.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 @@ -149,7 +149,7 @@ Thus, the two variables affect pump operation are set in New(): ui.open() // open the new ui window ui.set_auto_update(1) // auto update every Master Controller tick -/obj/machinery/atmospherics/binary/pump/initialize() +/obj/machinery/atmospherics/binary/pump/Initialize() . = ..() if(frequency) set_frequency(frequency) diff --git a/code/ATMOSPHERICS/components/omni_devices/filter.dm b/code/ATMOSPHERICS/components/omni_devices/filter.dm index 428f37fcfa..6fbd91f861 100644 --- a/code/ATMOSPHERICS/components/omni_devices/filter.dm +++ b/code/ATMOSPHERICS/components/omni_devices/filter.dm @@ -93,7 +93,7 @@ data = build_uidata() - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "omni_filter.tmpl", "Omni Filter Control", 330, 330) @@ -181,7 +181,7 @@ switch_filter(dir_flag(href_list["dir"]), mode_return_switch(new_filter)) update_icon() - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) return /obj/machinery/atmospherics/omni/atmos_filter/proc/mode_return_switch(var/mode) diff --git a/code/ATMOSPHERICS/components/omni_devices/mixer.dm b/code/ATMOSPHERICS/components/omni_devices/mixer.dm index fc00be6ba4..47c78427f0 100644 --- a/code/ATMOSPHERICS/components/omni_devices/mixer.dm +++ b/code/ATMOSPHERICS/components/omni_devices/mixer.dm @@ -131,7 +131,7 @@ data = build_uidata() - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "omni_mixer.tmpl", "Omni Mixer Control", 360, 330) @@ -200,7 +200,7 @@ con_lock(dir_flag(href_list["dir"])) update_icon() - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) return /obj/machinery/atmospherics/omni/mixer/proc/switch_mode(var/port = NORTH, var/mode = ATM_NONE) diff --git a/code/ATMOSPHERICS/components/trinary_devices/filter.dm b/code/ATMOSPHERICS/components/trinary_devices/filter.dm index 49cb05e9af..ea3bd60456 100755 --- a/code/ATMOSPHERICS/components/trinary_devices/filter.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/filter.dm @@ -105,7 +105,7 @@ return 1 -/obj/machinery/atmospherics/trinary/atmos_filter/initialize() +/obj/machinery/atmospherics/trinary/atmos_filter/Initialize() . = ..() if(frequency) set_frequency(frequency) diff --git a/code/ATMOSPHERICS/components/tvalve.dm b/code/ATMOSPHERICS/components/tvalve.dm index cfc990c6e5..c0d796d45b 100644 --- a/code/ATMOSPHERICS/components/tvalve.dm +++ b/code/ATMOSPHERICS/components/tvalve.dm @@ -302,7 +302,7 @@ -/obj/machinery/atmospherics/tvalve/digital/initialize() +/obj/machinery/atmospherics/tvalve/digital/Initialize() . = ..() if(frequency) set_frequency(frequency) diff --git a/code/ATMOSPHERICS/components/unary/cold_sink.dm b/code/ATMOSPHERICS/components/unary/cold_sink.dm index 8ff0aa7479..d4bfb73311 100644 --- a/code/ATMOSPHERICS/components/unary/cold_sink.dm +++ b/code/ATMOSPHERICS/components/unary/cold_sink.dm @@ -83,7 +83,7 @@ data["gasTemperatureClass"] = temp_class // update the ui if it exists, returns null if no ui is passed/found - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.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 diff --git a/code/ATMOSPHERICS/components/unary/heat_source.dm b/code/ATMOSPHERICS/components/unary/heat_source.dm index 69e638bc22..9729e1d387 100644 --- a/code/ATMOSPHERICS/components/unary/heat_source.dm +++ b/code/ATMOSPHERICS/components/unary/heat_source.dm @@ -103,7 +103,7 @@ data["gasTemperatureClass"] = temp_class // update the ui if it exists, returns null if no ui is passed/found - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.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 diff --git a/code/ATMOSPHERICS/components/unary/outlet_injector.dm b/code/ATMOSPHERICS/components/unary/outlet_injector.dm index 4a9403a64b..ee1379ac28 100644 --- a/code/ATMOSPHERICS/components/unary/outlet_injector.dm +++ b/code/ATMOSPHERICS/components/unary/outlet_injector.dm @@ -122,7 +122,7 @@ return 1 -/obj/machinery/atmospherics/unary/outlet_injector/initialize() +/obj/machinery/atmospherics/unary/outlet_injector/Initialize() . = ..() if(frequency) set_frequency(frequency) diff --git a/code/ATMOSPHERICS/components/valve.dm b/code/ATMOSPHERICS/components/valve.dm index f385ae5ed6..2e5e3e08ee 100644 --- a/code/ATMOSPHERICS/components/valve.dm +++ b/code/ATMOSPHERICS/components/valve.dm @@ -263,7 +263,7 @@ if(frequency) radio_connection = radio_controller.add_object(src, frequency, RADIO_ATMOSIA) -/obj/machinery/atmospherics/valve/digital/initialize() +/obj/machinery/atmospherics/valve/digital/Initialize() . = ..() if(frequency) set_frequency(frequency) diff --git a/code/ATMOSPHERICS/datum_pipe_network.dm b/code/ATMOSPHERICS/datum_pipe_network.dm index 74134e6ff2..eb5e89276e 100644 --- a/code/ATMOSPHERICS/datum_pipe_network.dm +++ b/code/ATMOSPHERICS/datum_pipe_network.dm @@ -20,7 +20,7 @@ var/global/list/datum/pipe_network/pipe_networks = list() // TODO - Move into SS gases.Cut() // Do not qdel the gases, we don't own them return ..() - proc/process() + process() //Equalize gases amongst pipe if called for if(update) update = 0 @@ -75,7 +75,7 @@ var/global/list/datum/pipe_network/pipe_networks = list() // TODO - Move into SS for(var/datum/pipeline/line_member in line_members) gases += line_member.air - + for(var/datum/gas_mixture/air in gases) volume += air.volume diff --git a/code/ATMOSPHERICS/datum_pipeline.dm b/code/ATMOSPHERICS/datum_pipeline.dm index 28391c4352..fc47bca938 100644 --- a/code/ATMOSPHERICS/datum_pipeline.dm +++ b/code/ATMOSPHERICS/datum_pipeline.dm @@ -20,7 +20,7 @@ datum/pipeline edges = null . = ..() - proc/process()//This use to be called called from the pipe networks + process()//This use to be called called from the pipe networks //Check to see if pressure is within acceptable limits var/pressure = air.return_pressure() diff --git a/code/ATMOSPHERICS/mainspipe.dm b/code/ATMOSPHERICS/mainspipe.dm index baba515fae..ac2b3193c9 100644 --- a/code/ATMOSPHERICS/mainspipe.dm +++ b/code/ATMOSPHERICS/mainspipe.dm @@ -571,7 +571,7 @@ obj/machinery/atmospherics/mains_pipe/valve else icon_state = "[hide?"h":""]mvalve[open]" - initialize() + Initialize() normalize_dir() var/node1_dir var/node2_dir @@ -609,7 +609,7 @@ obj/machinery/atmospherics/mains_pipe/valve open = 1 update_icon() - initialize() + Initialize() return 1 @@ -668,7 +668,7 @@ obj/machinery/atmospherics/mains_pipe/valve var/id = null var/datum/radio_frequency/radio_connection - initialize() + Initialize() ..() if(frequency) set_frequency(frequency) diff --git a/code/ZAS/Airflow.dm b/code/ZAS/Airflow.dm index e5d2b7eb11..394fe72478 100644 --- a/code/ZAS/Airflow.dm +++ b/code/ZAS/Airflow.dm @@ -22,9 +22,6 @@ mob/proc/airflow_stun() mob/living/silicon/airflow_stun() return -mob/living/simple_animal/slime/airflow_stun() - return - mob/living/carbon/human/airflow_stun() if(shoes && (shoes.item_flags & NOSLIP)) to_chat(src, "Air suddenly rushes past you!") diff --git a/code/__datastructures/globals.dm b/code/__datastructures/globals.dm index 637af7f0fc..05d5a2d29b 100644 --- a/code/__datastructures/globals.dm +++ b/code/__datastructures/globals.dm @@ -36,3 +36,4 @@ #define GLOBAL_LIST(X) GLOBAL_RAW(/list/##X); GLOBAL_MANAGED(X, null) #define GLOBAL_DATUM(X, Typepath) GLOBAL_RAW(Typepath/##X); GLOBAL_MANAGED(X, null) + diff --git a/code/__defines/MC.dm b/code/__defines/MC.dm index ad03630666..6acc667f2d 100644 --- a/code/__defines/MC.dm +++ b/code/__defines/MC.dm @@ -1,15 +1,81 @@ -#define MC_TICK_CHECK ( ( TICK_USAGE > GLOB.CURRENT_TICKLIMIT || src.state != SS_RUNNING ) ? pause() : 0 ) - -// Used for splitting up your remaining time into phases, if you want to evenly divide it. -#define MC_SPLIT_TICK_INIT(phase_count) var/original_tick_limit = GLOB.CURRENT_TICKLIMIT; var/split_tick_phases = ##phase_count +#define MC_TICK_CHECK ( ( TICK_USAGE > Master.current_ticklimit || src.state != SS_RUNNING ) ? pause() : 0 ) +#define MC_SPLIT_TICK_INIT(phase_count) var/original_tick_limit = Master.current_ticklimit; var/split_tick_phases = ##phase_count #define MC_SPLIT_TICK \ - if(split_tick_phases > 1){\ - GLOB.CURRENT_TICKLIMIT = ((original_tick_limit - world.tick_usage) / split_tick_phases) + world.tick_usage;\ - --split_tick_phases;\ - } else {\ - GLOB.CURRENT_TICKLIMIT = original_tick_limit;\ - } + if(split_tick_phases > 1){\ + Master.current_ticklimit = ((original_tick_limit - TICK_USAGE) / split_tick_phases) + TICK_USAGE;\ + --split_tick_phases;\ + } else {\ + Master.current_ticklimit = original_tick_limit;\ + } + +// Used to smooth out costs to try and avoid oscillation. +#define MC_AVERAGE_FAST(average, current) (0.7 * (average) + 0.3 * (current)) +#define MC_AVERAGE(average, current) (0.8 * (average) + 0.2 * (current)) +#define MC_AVERAGE_SLOW(average, current) (0.9 * (average) + 0.1 * (current)) + +#define MC_AVG_FAST_UP_SLOW_DOWN(average, current) (average > current ? MC_AVERAGE_SLOW(average, current) : MC_AVERAGE_FAST(average, current)) +#define MC_AVG_SLOW_UP_FAST_DOWN(average, current) (average < current ? MC_AVERAGE_SLOW(average, current) : MC_AVERAGE_FAST(average, current)) + +#define NEW_SS_GLOBAL(varname) if(varname != src){if(istype(varname)){Recover();qdel(varname);}varname = src;} + +#define START_PROCESSING(Processor, Datum) if (!(Datum.datum_flags & DF_ISPROCESSING)) {Datum.datum_flags |= DF_ISPROCESSING;Processor.processing += Datum} +#define STOP_PROCESSING(Processor, Datum) Datum.datum_flags &= ~DF_ISPROCESSING;Processor.processing -= Datum + +//! SubSystem flags (Please design any new flags so that the default is off, to make adding flags to subsystems easier) + +/// subsystem does not initialize. +#define SS_NO_INIT 1 + +/** subsystem does not fire. */ +/// (like can_fire = 0, but keeps it from getting added to the processing subsystems list) +/// (Requires a MC restart to change) +#define SS_NO_FIRE 2 + +/** subsystem only runs on spare cpu (after all non-background subsystems have ran that tick) */ +/// SS_BACKGROUND has its own priority bracket +#define SS_BACKGROUND 4 + +/// subsystem does not tick check, and should not run unless there is enough time (or its running behind (unless background)) +#define SS_NO_TICK_CHECK 8 + +/** Treat wait as a tick count, not DS, run every wait ticks. */ +/// (also forces it to run first in the tick, above even SS_NO_TICK_CHECK subsystems) +/// (implies all runlevels because of how it works) +/// (overrides SS_BACKGROUND) +/// This is designed for basically anything that works as a mini-mc (like SStimer) +#define SS_TICKER 16 + +/** keep the subsystem's timing on point by firing early if it fired late last fire because of lag */ +/// ie: if a 20ds subsystem fires say 5 ds late due to lag or what not, its next fire would be in 15ds, not 20ds. +#define SS_KEEP_TIMING 32 + +/** Calculate its next fire after its fired. */ +/// (IE: if a 5ds wait SS takes 2ds to run, its next fire should be 5ds away, not 3ds like it normally would be) +/// This flag overrides SS_KEEP_TIMING +#define SS_POST_FIRE_TIMING 64 + +//! SUBSYSTEM STATES +#define SS_IDLE 0 /// aint doing shit. +#define SS_QUEUED 1 /// queued to run +#define SS_RUNNING 2 /// actively running +#define SS_PAUSED 3 /// paused by mc_tick_check +#define SS_SLEEPING 4 /// fire() slept. +#define SS_PAUSING 5 /// in the middle of pausing + +#define SUBSYSTEM_DEF(X) GLOBAL_REAL(SS##X, /datum/controller/subsystem/##X);\ +/datum/controller/subsystem/##X/New(){\ + NEW_SS_GLOBAL(SS##X);\ + PreInit();\ +}\ +/datum/controller/subsystem/##X + +#define PROCESSING_SUBSYSTEM_DEF(X) GLOBAL_REAL(SS##X, /datum/controller/subsystem/processing/##X);\ +/datum/controller/subsystem/processing/##X/New(){\ + NEW_SS_GLOBAL(SS##X);\ + PreInit();\ +}\ +/datum/controller/subsystem/processing/##X // Boilerplate code for multi-step processors. See machines.dm for example use. #define INTERNAL_PROCESS_STEP(this_step, initial_step, proc_to_call, cost_var, next_step)\ @@ -23,71 +89,3 @@ if(current_step == this_step || (initial_step && !resumed)) /* So we start at st resumed = 0;\ current_step = next_step;\ } - -// Used to smooth out costs to try and avoid oscillation. -#define MC_AVERAGE_FAST(average, current) (0.7 * (average) + 0.3 * (current)) -#define MC_AVERAGE(average, current) (0.8 * (average) + 0.2 * (current)) -#define MC_AVERAGE_SLOW(average, current) (0.9 * (average) + 0.1 * (current)) - -#define MC_AVG_FAST_UP_SLOW_DOWN(average, current) (average > current ? MC_AVERAGE_SLOW(average, current) : MC_AVERAGE_FAST(average, current)) -#define MC_AVG_SLOW_UP_FAST_DOWN(average, current) (average < current ? MC_AVERAGE_SLOW(average, current) : MC_AVERAGE_FAST(average, current)) - -#define NEW_SS_GLOBAL(varname) if(varname != src){if(istype(varname)){Recover();qdel(varname);}varname = src;} - -#define START_PROCESSING(Processor, Datum) if (!Datum.isprocessing) {Datum.isprocessing = 1;Processor.processing += Datum} -#define STOP_PROCESSING(Processor, Datum) Datum.isprocessing = 0;Processor.processing -= Datum - -//SubSystem flags (Please design any new flags so that the default is off, to make adding flags to subsystems easier) - -//subsystem does not initialize. -#define SS_NO_INIT 1 - -//subsystem does not fire. -// (like can_fire = 0, but keeps it from getting added to the processing subsystems list) -// (Requires a MC restart to change) -#define SS_NO_FIRE 2 - -//subsystem only runs on spare cpu (after all non-background subsystems have ran that tick) -// SS_BACKGROUND has its own priority bracket -#define SS_BACKGROUND 4 - -//subsystem does not tick check, and should not run unless there is enough time (or its running behind (unless background)) -#define SS_NO_TICK_CHECK 8 - -//Treat wait as a tick count, not DS, run every wait ticks. -// (also forces it to run first in the tick, above even SS_NO_TICK_CHECK subsystems) -// (implies all runlevels because of how it works) -// (overrides SS_BACKGROUND) -// This is designed for basically anything that works as a mini-mc (like SStimer) -#define SS_TICKER 16 - -//keep the subsystem's timing on point by firing early if it fired late last fire because of lag -// ie: if a 20ds subsystem fires say 5 ds late due to lag or what not, its next fire would be in 15ds, not 20ds. -#define SS_KEEP_TIMING 32 - -//Calculate its next fire after its fired. -// (IE: if a 5ds wait SS takes 2ds to run, its next fire should be 5ds away, not 3ds like it normally would be) -// This flag overrides SS_KEEP_TIMING -#define SS_POST_FIRE_TIMING 64 - -//SUBSYSTEM STATES -#define SS_IDLE 0 //aint doing shit. -#define SS_QUEUED 1 //queued to run -#define SS_RUNNING 2 //actively running -#define SS_PAUSED 3 //paused by mc_tick_check -#define SS_SLEEPING 4 //fire() slept. -#define SS_PAUSING 5 //in the middle of pausing - -// Standard way to define a global subsystem, keep boilerplate organized here! -#define SUBSYSTEM_DEF(X) GLOBAL_REAL(SS##X, /datum/controller/subsystem/##X);\ -/datum/controller/subsystem/##X/New(){\ - NEW_SS_GLOBAL(SS##X);\ - PreInit();\ -}\ -/datum/controller/subsystem/##X - #define PROCESSING_SUBSYSTEM_DEF(X) GLOBAL_REAL(SS##X, /datum/controller/subsystem/processing/##X);\ -/datum/controller/subsystem/processing/##X/New(){\ - NEW_SS_GLOBAL(SS##X);\ - PreInit();\ -}\ -/datum/controller/subsystem/processing/##X \ No newline at end of file diff --git a/code/__defines/_lists.dm b/code/__defines/_lists.dm new file mode 100644 index 0000000000..348aafccef --- /dev/null +++ b/code/__defines/_lists.dm @@ -0,0 +1,56 @@ +// Helper macros to aid in optimizing lazy instantiation of lists. +// All of these are null-safe, you can use them without knowing if the list var is initialized yet + +//Picks from the list, with some safeties, and returns the "default" arg if it fails +#define DEFAULTPICK(L, default) ((istype(L, /list) && L:len) ? pick(L) : default) +// Ensures L is initailized after this point +#define LAZYINITLIST(L) if (!L) L = list() +// Sets a L back to null iff it is empty +#define UNSETEMPTY(L) if (L && !length(L)) L = null +// Removes I from list L, and sets I to null if it is now empty +#define LAZYREMOVE(L, I) if(L) { L -= I; if(!length(L)) { L = null; } } +// Adds I to L, initalizing I if necessary +#define LAZYADD(L, I) if(!L) { L = list(); } L += I; +#define LAZYOR(L, I) if(!L) { L = list(); } L |= I; +#define LAZYFIND(L, V) L ? L.Find(V) : 0 +// Reads I from L safely - Works with both associative and traditional lists. +#define LAZYACCESS(L, I) (L ? (isnum(I) ? (I > 0 && I <= length(L) ? L[I] : null) : L[I]) : null) +// Turns LAZYINITLIST(L) L[K] = V into ... for associated lists +#define LAZYSET(L, K, V) if(!L) { L = list(); } L[K] = V; +// Reads the length of L, returning 0 if null +#define LAZYLEN(L) length(L) +// Null-safe L.Cut() +#define LAZYCLEARLIST(L) if(L) L.Cut() +// Reads L or an empty list if L is not a list. Note: Does NOT assign, L may be an expression. +#define SANITIZE_LIST(L) ( islist(L) ? L : list() ) +#define reverseList(L) reverseRange(L.Copy()) + +// binary search sorted insert +// IN: Object to be inserted +// LIST: List to insert object into +// TYPECONT: The typepath of the contents of the list +// COMPARE: The variable on the objects to compare +#define BINARY_INSERT(IN, LIST, TYPECONT, COMPARE) \ + var/__BIN_CTTL = length(LIST);\ + if(!__BIN_CTTL) {\ + LIST += IN;\ + } else {\ + var/__BIN_LEFT = 1;\ + var/__BIN_RIGHT = __BIN_CTTL;\ + var/__BIN_MID = (__BIN_LEFT + __BIN_RIGHT) >> 1;\ + var/##TYPECONT/__BIN_ITEM;\ + while(__BIN_LEFT < __BIN_RIGHT) {\ + __BIN_ITEM = LIST[__BIN_MID];\ + if(__BIN_ITEM.##COMPARE <= IN.##COMPARE) {\ + __BIN_LEFT = __BIN_MID + 1;\ + } else {\ + __BIN_RIGHT = __BIN_MID;\ + };\ + __BIN_MID = (__BIN_LEFT + __BIN_RIGHT) >> 1;\ + };\ + __BIN_ITEM = LIST[__BIN_MID];\ + __BIN_MID = __BIN_ITEM.##COMPARE > IN.##COMPARE ? __BIN_MID : __BIN_MID + 1;\ + LIST.Insert(__BIN_MID, IN);\ + } + +#define islist(L) istype(L, /list) diff --git a/code/__defines/_planes+layers.dm b/code/__defines/_planes+layers.dm index 4d258cd91f..faaa475894 100644 --- a/code/__defines/_planes+layers.dm +++ b/code/__defines/_planes+layers.dm @@ -58,7 +58,10 @@ What is the naming convention for planes or layers? #define ATMOS_LAYER 2.4 // Pipe-like atmos machinery that goes on the floor, like filters. #define ABOVE_UTILITY 2.5 // Above stuff like pipes and wires #define TURF_PLANE -45 // Turfs themselves, most flooring - #define ABOVE_TURF_LAYER 2.1 // Snow and wallmounted/floormounted equipment + #define WATER_FLOOR_LAYER 2.0 // The 'bottom' of water tiles. + #define UNDERWATER_LAYER 2.5 // Anything on this layer will render under the water layer. + #define WATER_LAYER 3.0 // Layer for water overlays. + #define ABOVE_TURF_LAYER 3.1 // Snow and wallmounted/floormounted equipment #define DECAL_PLANE -44 // Permanent decals #define DIRTY_PLANE -43 // Nonpermanent decals #define BLOOD_PLANE -42 // Blood is really dirty, but we can do special stuff if we separate it @@ -73,8 +76,8 @@ What is the naming convention for planes or layers? #define ABOVE_JUNK_LAYER 3.1 // Things that want to be slightly above common objects #define DOOR_CLOSED_LAYER 3.1 // Doors when closed #define WINDOW_LAYER 3.2 // Windows - #define ABOVE_WINDOW_LAYER 3.25 //Above full tile windows so wall items are clickable #define ON_WINDOW_LAYER 3.3 // Ontop of a window + #define ABOVE_WINDOW_LAYER 3.4 //Above full tile windows so wall items are clickable // Mob planes #define MOB_PLANE -25 diff --git a/code/__defines/_tick.dm b/code/__defines/_tick.dm index 7ca3fb23a2..54ac7d398d 100644 --- a/code/__defines/_tick.dm +++ b/code/__defines/_tick.dm @@ -1,9 +1,15 @@ + #define TICK_LIMIT_RUNNING 80 #define TICK_LIMIT_TO_RUN 70 #define TICK_LIMIT_MC 70 #define TICK_LIMIT_MC_INIT_DEFAULT 98 -#define TICK_CHECK ( TICK_USAGE > GLOB.CURRENT_TICKLIMIT ) -#define CHECK_TICK if TICK_CHECK stoplag() - #define TICK_USAGE world.tick_usage + +#define TICK_CHECK ( TICK_USAGE > Master.current_ticklimit ) +#define CHECK_TICK ( TICK_CHECK ? stoplag() : 0 ) + +#define TICK_CHECK_HIGH_PRIORITY ( TICK_USAGE > 95 ) +#define CHECK_TICK_HIGH_PRIORITY ( TICK_CHECK_HIGH_PRIORITY? stoplag() : 0 ) + +#define UNTIL(X) while(!(X)) stoplag() \ No newline at end of file diff --git a/code/__defines/damage_organs.dm b/code/__defines/damage_organs.dm index 7bb32fa75c..285b0b341e 100644 --- a/code/__defines/damage_organs.dm +++ b/code/__defines/damage_organs.dm @@ -7,6 +7,7 @@ #define CLONE "clone" #define HALLOSS "halloss" #define ELECTROCUTE "electrocute" +#define BIOACID "bioacid" #define CUT "cut" #define BRUISE "bruise" diff --git a/code/__defines/flags.dm b/code/__defines/flags.dm new file mode 100644 index 0000000000..5b6152e6d2 --- /dev/null +++ b/code/__defines/flags.dm @@ -0,0 +1,45 @@ +//MARK ALL FLAG CHANGES IN _globals/bitfields.dm! +//All flags should go in here if possible. +#define ALL (~0) //For convenience. +#define NONE 0 + +//for convenience +#define ENABLE_BITFIELD(variable, flag) (variable |= (flag)) +#define DISABLE_BITFIELD(variable, flag) (variable &= ~(flag)) +#define CHECK_BITFIELD(variable, flag) (variable & (flag)) + +//check if all bitflags specified are present +#define CHECK_MULTIPLE_BITFIELDS(flagvar, flags) ((flagvar & (flags)) == flags) + +GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768)) + +// datum_flags +#define DF_VAR_EDITED (1<<0) +#define DF_ISPROCESSING (1<<1) + +// /atom/movable movement_type +#define UNSTOPPABLE (1<<0) //Can not be stopped from moving from Cross(), CanPass(), or Uncross() failing. Still bumps everything it passes through, though. + +// Flags bitmasks. - Used in /atom/var/flags +#define NOBLUDGEON (1<<0) // When an item has this it produces no "X has been hit by Y with Z" message with the default handler. +#define CONDUCT (1<<1) // Conducts electricity. (metal etc.) +#define ON_BORDER (1<<2) // Item has priority to check when entering or leaving. +#define NOBLOODY (1<<3) // Used for items if they don't want to get a blood overlay. +#define OPENCONTAINER (1<<4) // Is an open container for chemistry purposes. +#define PHORONGUARD (1<<5) // Does not get contaminated by phoron. +#define NOREACT (1<<6) // Reagents don't react inside this container. +#define PROXMOVE (1<<7)// Does this object require proximity checking in Enter()? +#define OVERLAY_QUEUED (1<<8)// Atom queued to SSoverlay for COMPILE_OVERLAYS + +//Flags for items (equipment) - Used in /obj/item/var/item_flags +#define THICKMATERIAL (1<<0) // Prevents syringes, parapens and hyposprays if equipped to slot_suit or slot_head. +#define AIRTIGHT (1<<1) // Functions with internals. +#define NOSLIP (1<<2) // Prevents from slipping on wet floors, in space, etc. +#define BLOCK_GAS_SMOKE_EFFECT (1<<3) // Blocks the effect that chemical clouds would have on a mob -- glasses, mask and helmets ONLY! (NOTE: flag shared with ONESIZEFITSALL) +#define FLEXIBLEMATERIAL (1<<4) // At the moment, masks with this flag will not prevent eating even if they are covering your face. + +// Flags for pass_flags. - Used in /atom/var/pass_flags +#define PASSTABLE (1<<0) +#define PASSGLASS (1<<1) +#define PASSGRILLE (1<<2) +#define PASSBLOB (1<<3) diff --git a/code/__defines/gamemode.dm b/code/__defines/gamemode.dm index 5327931608..c96cae859e 100644 --- a/code/__defines/gamemode.dm +++ b/code/__defines/gamemode.dm @@ -45,8 +45,6 @@ var/list/be_special_flags = list( "pAI" = BE_PAI ) -#define IS_MODE_COMPILED(MODE) (ispath(text2path("/datum/game_mode/"+(MODE)))) - // Antagonist datum flags. #define ANTAG_OVERRIDE_JOB 0x1 // Assigned job is set to MODE when spawning. diff --git a/code/__defines/is_helpers.dm b/code/__defines/is_helpers.dm new file mode 100644 index 0000000000..ed4a0dd10f --- /dev/null +++ b/code/__defines/is_helpers.dm @@ -0,0 +1,53 @@ + +#define isdatum(D) istype(D, /datum) +#define isweakref(A) istype(A, /weakref) + +#define islist(D) istype(D, /list) + +//--------------- +#define isatom(D) istype(D, /atom) + +//--------------- +//#define isobj(D) istype(D, /obj) //Built in + +#define isitem(D) istype(D, /obj/item) + +#define isairlock(A) istype(A, /obj/machinery/door/airlock) + +#define isorgan(A) istype(A, /obj/item/organ/external) + +//--------------- +//#define isarea(D) istype(D, /area) //Built in + +//--------------- +//#define ismob(D) istype(D, /mob) //Built in +#define isliving(A) istype(A, /mob/living) + +#define isobserver(A) istype(A, /mob/observer/dead) +#define isEye(A) istype(A, /mob/observer/eye) + +#define isnewplayer(A) istype(A, /mob/new_player) + +#define isanimal(A) istype(A, /mob/living/simple_mob) +#define ismouse(A) istype(A, /mob/living/simple_mob/animal/passive/mouse) +#define iscorgi(A) istype(A, /mob/living/simple_mob/animal/passive/dog/corgi) +#define isslime(A) istype(A, /mob/living/simple_mob/slime) +#define isxeno(A) istype(A, /mob/living/simple_mob/animal/space/alien) + +#define iscarbon(A) istype(A, /mob/living/carbon) +#define isalien(A) istype(A, /mob/living/carbon/alien) +#define isbrain(A) istype(A, /mob/living/carbon/brain) +#define ishuman(A) istype(A, /mob/living/carbon/human) + +#define issilicon(A) istype(A, /mob/living/silicon) +#define isAI(A) istype(A, /mob/living/silicon/ai) +#define isrobot(A) istype(A, /mob/living/silicon/robot) +#define ispAI(A) istype(A, /mob/living/silicon/pai) + +#define isbot(A) istype(A, /mob/living/bot) + +#define isvoice(A) istype(A, /mob/living/voice) + +//--------------- +//#define isturf(D) istype(D, /turf) //Built in +#define isopenspace(A) istype(A, /turf/simulated/open) diff --git a/code/__defines/items_clothing.dm b/code/__defines/items_clothing.dm index de0a271ae6..ffbda3e298 100644 --- a/code/__defines/items_clothing.dm +++ b/code/__defines/items_clothing.dm @@ -40,31 +40,6 @@ #define ACCESSORY_SLOT_TORSO (ACCESSORY_SLOT_UTILITY|ACCESSORY_SLOT_WEAPON) -// Flags bitmasks. - Used in /atom/var/flags -#define NOBLUDGEON 0x1 // When an item has this it produces no "X has been hit by Y with Z" message with the default handler. -#define CONDUCT 0x2 // Conducts electricity. (metal etc.) -#define ON_BORDER 0x4 // Item has priority to check when entering or leaving. -#define NOBLOODY 0x8 // Used for items if they don't want to get a blood overlay. -#define OPENCONTAINER 0x10 // Is an open container for chemistry purposes. -#define PHORONGUARD 0x20 // Does not get contaminated by phoron. -#define NOREACT 0x40 // Reagents don't react inside this container. -#define PROXMOVE 0x80 // Does this object require proximity checking in Enter()? -#define OVERLAY_QUEUED 0x100 // Atom queued to SSoverlay for COMPILE_OVERLAYS - -//Flags for items (equipment) - Used in /obj/item/var/item_flags -#define THICKMATERIAL 0x1 // Prevents syringes, parapens and hyposprays if equipped to slot_suit or slot_head. -#define STOPPRESSUREDAMAGE 0x2 // Counts towards pressure protection. Note that like temperature protection, body_parts_covered is considered here as well. -#define AIRTIGHT 0x4 // Functions with internals. -#define NOSLIP 0x8 // Prevents from slipping on wet floors, in space, etc. -#define BLOCK_GAS_SMOKE_EFFECT 0x10 // Blocks the effect that chemical clouds would have on a mob -- glasses, mask and helmets ONLY! (NOTE: flag shared with ONESIZEFITSALL) -#define FLEXIBLEMATERIAL 0x20 // At the moment, masks with this flag will not prevent eating even if they are covering your face. - -// Flags for pass_flags. - Used in /atom/var/pass_flags -#define PASSTABLE 0x1 -#define PASSGLASS 0x2 -#define PASSGRILLE 0x4 -#define PASSBLOB 0x8 - // Bitmasks for the /obj/item/var/flags_inv variable. These determine when a piece of clothing hides another, i.e. a helmet hiding glasses. // WARNING: The following flags apply only to the external suit! #define HIDEGLOVES 0x1 diff --git a/code/__defines/machinery.dm b/code/__defines/machinery.dm index d77b5cf297..95d4929acb 100644 --- a/code/__defines/machinery.dm +++ b/code/__defines/machinery.dm @@ -106,26 +106,15 @@ var/list/restricted_camera_networks = list(NETWORK_ERT,NETWORK_MERCENARY,"Secret #define ATMOS_DEFAULT_VOLUME_MIXER 200 // L. #define ATMOS_DEFAULT_VOLUME_PIPE 70 // L. +//wIP - PORT ALL OF THESE TO SUBSYSTEMS AND GET RID OF THE WHOLE LIST PROCESS THING // Fancy-pants START/STOP_PROCESSING() macros that lets us custom define what the list is. #define START_PROCESSING_IN_LIST(DATUM, LIST) \ -if (DATUM.is_processing) {\ - if(DATUM.is_processing != #LIST)\ - {\ - crash_with("Failed to start processing. [log_info_line(DATUM)] is already being processed by [DATUM.is_processing] but queue attempt occured on [#LIST]."); \ - }\ -} else {\ - DATUM.is_processing = #LIST;\ +if (!(DATUM.datum_flags & DF_ISPROCESSING)) {\ LIST += DATUM;\ + DATUM.datum_flags |= DF_ISPROCESSING\ } -#define STOP_PROCESSING_IN_LIST(DATUM, LIST) \ -if(DATUM.is_processing) {\ - if(LIST.Remove(DATUM)) {\ - DATUM.is_processing = null;\ - } else {\ - crash_with("Failed to stop processing. [log_info_line(DATUM)] is being processed by [is_processing] and not found in SSmachines.[#LIST]"); \ - }\ -} +#define STOP_PROCESSING_IN_LIST(DATUM, LIST) LIST.Remove(DATUM);DATUM.datum_flags &= ~DF_ISPROCESSING // Note - I would prefer these be defined machines.dm, but some are used prior in file order. ~Leshana #define START_MACHINE_PROCESSING(Datum) START_PROCESSING_IN_LIST(Datum, global.processing_machines) diff --git a/code/__defines/math.dm b/code/__defines/math.dm index 3d64ba6c81..88c459ba78 100644 --- a/code/__defines/math.dm +++ b/code/__defines/math.dm @@ -1,18 +1,228 @@ +// Credits to Nickr5 for the useful procs I've taken from his library resource. +// This file is quadruple wrapped for your pleasure +// ( + +#define NUM_E 2.71828183 + +#define M_PI (3.14159265) +#define INFINITY (1.#INF) //closer then enough + +#define SHORT_REAL_LIMIT 16777216 + //"fancy" math for calculating time in ms from tick_usage percentage and the length of ticks //percent_of_tick_used * (ticklag * 100(to convert to ms)) / 100(percent ratio) //collapsed to percent_of_tick_used * tick_lag #define TICK_DELTA_TO_MS(percent_of_tick_used) ((percent_of_tick_used) * world.tick_lag) -#define TICK_USAGE_TO_MS(starting_tickusage) (TICK_DELTA_TO_MS(TICK_USAGE-starting_tickusage)) +#define TICK_USAGE_TO_MS(starting_tickusage) (TICK_DELTA_TO_MS(world.tick_usage - starting_tickusage)) + +#define PERCENT(val) (round((val)*100, 0.1)) +#define CLAMP01(x) (CLAMP(x, 0, 1)) //time of day but automatically adjusts to the server going into the next day within the same round. //for when you need a reliable time number that doesn't depend on byond time. #define REALTIMEOFDAY (world.timeofday + (MIDNIGHT_ROLLOVER * MIDNIGHT_ROLLOVER_CHECK)) #define MIDNIGHT_ROLLOVER_CHECK ( rollovercheck_last_timeofday != world.timeofday ? update_midnight_rollover() : midnight_rollovers ) -#define SHORT_REAL_LIMIT 16777216 // 2^24 - Maximum integer that can be exactly represented in a float (BYOND num var) +#define SIGN(x) ( (x)!=0 ? (x) / abs(x) : 0 ) #define CEILING(x, y) ( -round(-(x) / (y)) * (y) ) + // round() acts like floor(x, 1) by default but can't handle other values #define FLOOR(x, y) ( round((x) / (y)) * (y) ) -// Check if a BYOND dir var is a cardinal direction (power of two) + +#define CLAMP(CLVALUE,CLMIN,CLMAX) ( max( (CLMIN), min((CLVALUE), (CLMAX)) ) ) + +// Similar to clamp but the bottom rolls around to the top and vice versa. min is inclusive, max is exclusive +#define WRAP(val, min, max) ( min == max ? min : (val) - (round(((val) - (min))/((max) - (min))) * ((max) - (min))) ) + +// Real modulus that handles decimals +#define MODULUS(x, y) ( (x) - (y) * round((x) / (y)) ) + +// Tangent +#define TAN(x) (sin(x) / cos(x)) + +// Cotangent +#define COT(x) (1 / TAN(x)) + +// Secant +#define SEC(x) (1 / cos(x)) + +// Cosecant +#define CSC(x) (1 / sin(x)) + +#define ATAN2(x, y) ( !(x) && !(y) ? 0 : (y) >= 0 ? arccos((x) / sqrt((x)*(x) + (y)*(y))) : -arccos((x) / sqrt((x)*(x) + (y)*(y))) ) + +// Greatest Common Divisor - Euclid's algorithm +/proc/GCD(a, b) + return b ? GCD(b, (a) % (b)) : a + +// Least Common Multiple +#define LCM(a, b) (abs(a) / GCD(a, b) * abs(b)) + #define IS_CARDINAL(x) ((x & (x - 1)) == 0) + +#define INVERSE(x) ( 1/(x) ) + +// Used for calculating the radioactive strength falloff +#define INVERSE_SQUARE(initial_strength,cur_distance,initial_distance) ( (initial_strength)*((initial_distance)**2/(cur_distance)**2) ) + +#define ISABOUTEQUAL(a, b, deviation) (deviation ? abs((a) - (b)) <= deviation : abs((a) - (b)) <= 0.1) + +#define ISEVEN(x) (x % 2 == 0) + +#define ISODD(x) (x % 2 != 0) + +// Returns true if val is from min to max, inclusive. +#define ISINRANGE(val, min, max) (min <= val && val <= max) + +// Same as above, exclusive. +#define ISINRANGE_EX(val, min, max) (min < val && val > max) + +#define ISINTEGER(x) (round(x) == x) + +#define ISMULTIPLE(x, y) ((x) % (y) == 0) + +// Performs a linear interpolation between a and b. +// Note that amount=0 returns a, amount=1 returns b, and +// amount=0.5 returns the mean of a and b. +#define LERP(a, b, amount) ( amount ? ((a) + ((b) - (a)) * (amount)) : a ) + +// Returns the nth root of x. +#define ROOT(n, x) ((x) ** (1 / (n))) + +/proc/Mean(...) + var/sum = 0 + for(var/val in args) + sum += val + return sum / args.len + +// The quadratic formula. Returns a list with the solutions, or an empty list +// if they are imaginary. +/proc/SolveQuadratic(a, b, c) + ASSERT(a) + . = list() + var/d = b*b - 4 * a * c + var/bottom = 2 * a + // Return if the roots are imaginary. + if(d < 0) + return + var/root = sqrt(d) + . += (-b + root) / bottom + // If discriminant == 0, there would be two roots at the same position. + if(!d) + return + . += (-b - root) / bottom + + // 180 / Pi ~ 57.2957795 +#define TODEGREES(radians) ((radians) * 57.2957795) + + // Pi / 180 ~ 0.0174532925 +#define TORADIANS(degrees) ((degrees) * 0.0174532925) + +// Will filter out extra rotations and negative rotations +// E.g: 540 becomes 180. -180 becomes 180. +#define SIMPLIFY_DEGREES(degrees) (MODULUS((degrees), 360)) + +#define GET_ANGLE_OF_INCIDENCE(face, input) (MODULUS((face) - (input), 360)) + +//Finds the shortest angle that angle A has to change to get to angle B. Aka, whether to move clock or counterclockwise. +/proc/closer_angle_difference(a, b) + if(!isnum(a) || !isnum(b)) + return + a = SIMPLIFY_DEGREES(a) + b = SIMPLIFY_DEGREES(b) + var/inc = b - a + if(inc < 0) + inc += 360 + var/dec = a - b + if(dec < 0) + dec += 360 + . = inc > dec? -dec : inc + +//A logarithm that converts an integer to a number scaled between 0 and 1. +//Currently, this is used for hydroponics-produce sprite transforming, but could be useful for other transform functions. +#define TRANSFORM_USING_VARIABLE(input, max) ( sin((90*(input))/(max))**2 ) + +//converts a uniform distributed random number into a normal distributed one +//since this method produces two random numbers, one is saved for subsequent calls +//(making the cost negligble for every second call) +//This will return +/- decimals, situated about mean with standard deviation stddev +//68% chance that the number is within 1stddev +//95% chance that the number is within 2stddev +//98% chance that the number is within 3stddev...etc +#define ACCURACY 10000 +/proc/gaussian(mean, stddev) + var/static/gaussian_next + var/R1;var/R2;var/working + if(gaussian_next != null) + R1 = gaussian_next + gaussian_next = null + else + do + R1 = rand(-ACCURACY,ACCURACY)/ACCURACY + R2 = rand(-ACCURACY,ACCURACY)/ACCURACY + working = R1*R1 + R2*R2 + while(working >= 1 || working==0) + working = sqrt(-2 * log(working) / working) + R1 *= working + gaussian_next = R2 * working + return (mean + stddev * R1) +#undef ACCURACY + +/proc/get_turf_in_angle(angle, turf/starting, increments) + var/pixel_x = 0 + var/pixel_y = 0 + for(var/i in 1 to increments) + pixel_x += sin(angle)+16*sin(angle)*2 + pixel_y += cos(angle)+16*cos(angle)*2 + var/new_x = starting.x + var/new_y = starting.y + while(pixel_x > 16) + pixel_x -= 32 + new_x++ + while(pixel_x < -16) + pixel_x += 32 + new_x-- + while(pixel_y > 16) + pixel_y -= 32 + new_y++ + while(pixel_y < -16) + pixel_y += 32 + new_y-- + new_x = CLAMP(new_x, 0, world.maxx) + new_y = CLAMP(new_y, 0, world.maxy) + return locate(new_x, new_y, starting.z) + +// Returns a list where [1] is all x values and [2] is all y values that overlap between the given pair of rectangles +/proc/get_overlap(x1, y1, x2, y2, x3, y3, x4, y4) + var/list/region_x1 = list() + var/list/region_y1 = list() + var/list/region_x2 = list() + var/list/region_y2 = list() + + // These loops create loops filled with x/y values that the boundaries inhabit + // ex: list(5, 6, 7, 8, 9) + for(var/i in min(x1, x2) to max(x1, x2)) + region_x1["[i]"] = TRUE + for(var/i in min(y1, y2) to max(y1, y2)) + region_y1["[i]"] = TRUE + for(var/i in min(x3, x4) to max(x3, x4)) + region_x2["[i]"] = TRUE + for(var/i in min(y3, y4) to max(y3, y4)) + region_y2["[i]"] = TRUE + + return list(region_x1 & region_x2, region_y1 & region_y2) + +// ) + +#define RAND_F(LOW, HIGH) (rand()*(HIGH-LOW) + LOW) + +#define SQUARE(x) (x*x) + +//Vector Algebra +#define SQUAREDNORM(x, y) (x*x+y*y) +#define NORM(x, y) (sqrt(SQUAREDNORM(x,y))) +#define ISPOWEROFTWO(x) ((x & (x - 1)) == 0) +#define ROUNDUPTOPOWEROFTWO(x) (2 ** -round(-log(2,x))) + +#define DEFAULT(a, b) (a? a : b) diff --git a/code/__defines/math_physics.dm b/code/__defines/math_physics.dm index da1c2aebd1..90950d0ca0 100644 --- a/code/__defines/math_physics.dm +++ b/code/__defines/math_physics.dm @@ -1,10 +1,13 @@ // Math constants. -#define M_PI 3.14159265 - #define R_IDEAL_GAS_EQUATION 8.31 // kPa*L/(K*mol). #define ONE_ATMOSPHERE 101.325 // kPa. #define IDEAL_GAS_ENTROPY_CONSTANT 1164 // (mol^3 * s^3) / (kg^3 * L). +#define T0C 273.15 // 0.0 degrees celcius +#define T20C 293.15 // 20.0 degrees celcius +#define TCMB 2.7 // -270.3 degrees celcius +#define TN60C 213.15 // -60 degrees celcius + // Radiation constants. #define STEFAN_BOLTZMANN_CONSTANT 5.6704e-8 // W/(m^2*K^4). #define COSMIC_RADIATION_TEMPERATURE 3.15 // K. @@ -15,18 +18,7 @@ #define RADIATOR_EXPOSED_SURFACE_AREA_RATIO 0.04 // (3 cm + 100 cm * sin(3deg))/(2*(3+100 cm)). Unitless ratio. #define HUMAN_EXPOSED_SURFACE_AREA 5.2 //m^2, surface area of 1.7m (H) x 0.46m (D) cylinder -#define T0C 273.15 // 0.0 degrees celcius -#define T20C 293.15 // 20.0 degrees celcius -#define TCMB 2.7 // -270.3 degrees celcius -#define TN60C 213.15 // -60 degrees celcius - -#define CLAMP01(x) max(0, min(1, x)) #define QUANTIZE(variable) (round(variable,0.0001)) -#define INFINITY 1.#INF - -#define TICKS_IN_DAY 24*60*60*10 -#define TICKS_IN_SECOND 10 - -#define SIMPLE_SIGN(X) ((X) < 0 ? -1 : 1) -#define SIGN(X) ((X) ? SIMPLE_SIGN(X) : 0) +#define TICKS_IN_DAY (TICKS_IN_SECOND * 60 * 60 * 24) +#define TICKS_IN_SECOND (world.fps) diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm index aa334224ad..0e3234ed83 100644 --- a/code/__defines/misc.dm +++ b/code/__defines/misc.dm @@ -258,7 +258,7 @@ // If the GLOB system is ever ported, you can change this macro in one place and have less work to do than you otherwise would. #define GLOBAL_LIST_BOILERPLATE(LIST_NAME, PATH)\ var/global/list/##LIST_NAME = list();\ -##PATH/initialize(mapload, ...)\ +##PATH/Initialize(mapload, ...)\ {\ ##LIST_NAME += src;\ return ..();\ @@ -290,6 +290,11 @@ var/global/list/##LIST_NAME = list();\ #define IS_WIRECUTTER "wirecutter" #define IS_WRENCH "wrench" + +// Diagonal movement +#define FIRST_DIAG_STEP 1 +#define SECOND_DIAG_STEP 2 + // RCD modes. Used on the RCD, and gets passed to an object's rcd_act() when an RCD is used on it, to determine what happens. #define RCD_FLOORWALL "Floor / Wall" // Builds plating on space/ground/open tiles. Builds a wall when on floors. Finishes walls when used on girders. #define RCD_AIRLOCK "Airlock" // Builds an airlock on the tile if one isn't already there. @@ -300,6 +305,11 @@ var/global/list/##LIST_NAME = list();\ #define RCD_VALUE_DELAY "delay" #define RCD_VALUE_COST "cost" - #define RCD_SHEETS_PER_MATTER_UNIT 4 // Each physical material sheet is worth four matter units. -#define RCD_MAX_CAPACITY 30 * RCD_SHEETS_PER_MATTER_UNIT \ No newline at end of file +#define RCD_MAX_CAPACITY 30 * RCD_SHEETS_PER_MATTER_UNIT + +// Radiation 'levels'. Used for the geiger counter, for visuals and sound. They are in different files so this goes here. +#define RAD_LEVEL_LOW 0.01 // Around the level at which radiation starts to become harmful +#define RAD_LEVEL_MODERATE 10 +#define RAD_LEVEL_HIGH 25 +#define RAD_LEVEL_VERY_HIGH 50 diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm index 679962b210..3221a595e4 100644 --- a/code/__defines/mobs.dm +++ b/code/__defines/mobs.dm @@ -27,6 +27,9 @@ #define BORGXRAY 0x4 #define BORGMATERIAL 8 +#define STANCE_ATTACK 11 // Backwards compatability +#define STANCE_ATTACKING 12 // Ditto +/* #define STANCE_IDLE 1 // Looking for targets if hostile. Does idle wandering. #define STANCE_ALERT 2 // Bears #define STANCE_ATTACK 3 // Attempting to get into attack position @@ -34,6 +37,20 @@ #define STANCE_TIRED 5 // Bears #define STANCE_FOLLOW 6 // Following somone #define STANCE_BUSY 7 // Do nothing on life ticks (Other code is running) +*/ +#define STANCE_SLEEP 0 // Doing (almost) nothing, to save on CPU because nobody is around to notice or the mob died. +#define STANCE_IDLE 1 // The more or less default state. Wanders around, looks for baddies, and spouts one-liners. +#define STANCE_ALERT 2 // A baddie is visible but not too close, and essentially we tell them to go away or die. +#define STANCE_APPROACH 3 // Attempting to get into range to attack them. +#define STANCE_FIGHT 4 // Actually fighting, with melee or ranged. +#define STANCE_BLINDFIGHT 5 // Fighting something that cannot be seen by the mob, from invisibility or out of sight. +#define STANCE_REPOSITION 6 // Relocating to a better position while in combat. Also used when moving away from a danger like grenades. +#define STANCE_MOVE 7 // Similar to above but for out of combat. If a baddie is seen, they'll cancel and fight them. +#define STANCE_FOLLOW 8 // Following somone, without trying to murder them. +#define STANCE_FLEE 9 // Run away from the target because they're too spooky/we're dying/some other reason. +#define STANCE_DISABLED 10 // Used when the holder is afflicted with certain status effects, such as stuns or confusion. + +#define STANCES_COMBAT list(STANCE_ALERT, STANCE_APPROACH, STANCE_FIGHT, STANCE_BLINDFIGHT, STANCE_REPOSITION) #define LEFT 0x1 #define RIGHT 0x2 @@ -279,11 +296,34 @@ #define SA_ROBOTIC 3 #define SA_HUMANOID 4 +// More refined version of SA_* ""intelligence"" seperators. +// Now includes bitflags, so to target two classes you just do 'MOB_CLASS_ANIMAL|MOB_CLASS_HUMANOID' +#define MOB_CLASS_NONE 0 // Default value, and used to invert for _ALL. + +#define MOB_CLASS_PLANT 1 // Unused at the moment. +#define MOB_CLASS_ANIMAL 2 // Animals and beasts like spiders, saviks, and bears. +#define MOB_CLASS_HUMANOID 4 // Non-robotic humanoids, including /simple_mob and /carbon/humans and their alien variants. +#define MOB_CLASS_SYNTHETIC 8 // Silicons, mechanical simple mobs, FBPs, and anything else that would pass is_synthetic() +#define MOB_CLASS_SLIME 16 // Everyone's favorite xenobiology specimen (and maybe prometheans?). +#define MOB_CLASS_ABERRATION 32 // Weird shit. +#define MOB_CLASS_DEMONIC 64 // Cult stuff. +#define MOB_CLASS_BOSS 128 // Future megafauna hopefully someday. +#define MOB_CLASS_ILLUSION 256 // Fake mobs, e.g. Technomancer illusions. +#define MOB_CLASS_PHOTONIC 512 // Holographic mobs like holocarp, similar to _ILLUSION, but that make no attempt to hide their true nature. + +#define MOB_CLASS_ALL (~MOB_CLASS_NONE) + // For slime commanding. Higher numbers allow for more actions. #define SLIME_COMMAND_OBEY 1 // When disciplined. #define SLIME_COMMAND_FACTION 2 // When in the same 'faction'. #define SLIME_COMMAND_FRIEND 3 // When befriended with a slime friendship agent. +// Threshold for mobs being able to damage things like airlocks or reinforced glass windows. +// If the damage is below this, nothing will happen besides a message saying that the attack was ineffective. +// Generally, this was not a define but was commonly set to 10, however 10 may be too low now since simple_mobs now attack twice as fast, +// at half damage compared to the old mob system, meaning mobs who could hurt structures may not be able to now, so now it is 5. +#define STRUCTURE_MIN_DAMAGE_THRESHOLD 5 + //Vision flags, for dealing with plane visibility #define VIS_FULLBRIGHT 1 #define VIS_LIGHTING 2 diff --git a/code/__defines/objects.dm b/code/__defines/objects.dm index 879bed2cd1..26ff77b4d8 100644 --- a/code/__defines/objects.dm +++ b/code/__defines/objects.dm @@ -1,6 +1,5 @@ /* * Defines used for miscellaneous objects. - * Currently only the home of the Multiool. */ // Multitool Mode Defines. @@ -8,3 +7,25 @@ #define MULTITOOL_MODE_STANDARD "Standard" #define MULTITOOL_MODE_INTCIRCUITS "Modular Wiring" #define MULTITOOL_MODE_DOORHACK "Advanced Jacking" + +// Identity system defines. +#define IDENTITY_UNKNOWN 0 // Nothing is known so far. +#define IDENTITY_PROPERTIES 1 // Basic function of the item, and amount of charges available if it uses them. +#define IDENTITY_QUALITY 2 // Blessed/Uncursed/Cursed status. Some things don't use this. +#define IDENTITY_FULL IDENTITY_PROPERTIES|IDENTITY_QUALITY // Know everything. + +#define IDENTITY_TYPE_NONE "generic" +#define IDENTITY_TYPE_TECH "technological" +#define IDENTITY_TYPE_CHEMICAL "chemical" + +// Roguelike object quality defines. Not used at the moment. +#define ROGUELIKE_ITEM_ARTIFACT 2 // Cannot degrade, very rare. +#define ROGUELIKE_ITEM_BLESSED 1 // Better than average and resists cursing. +#define ROGUELIKE_ITEM_UNCURSED 0 // Normal. +#define ROGUELIKE_ITEM_CURSED -1 // Does bad things, clothing cannot be taken off. + +// Consistant messages for certain events. +// Consistancy is import in order to avoid giving too much information away when using an +// unidentified object due to a typo or some other unique difference in message output. +#define ROGUELIKE_MESSAGE_NOTHING "Nothing happens." +#define ROGUELIKE_MESSAGE_UNKNOWN "Something happened, but you're not sure what." diff --git a/code/__defines/planets.dm b/code/__defines/planets.dm index 3c2a1abcfc..da67d42ea2 100644 --- a/code/__defines/planets.dm +++ b/code/__defines/planets.dm @@ -9,6 +9,9 @@ #define WEATHER_WINDY "windy" #define WEATHER_HOT "hot" #define WEATHER_BLOOD_MOON "blood moon" // For admin fun or cult later on. +#define WEATHER_EMBERFALL "emberfall" // More adminbuse, from TG. Harmless. +#define WEATHER_ASH_STORM "ash storm" // Ripped from TG, like the above. Less harmless. +#define WEATHER_FALLOUT "fallout" // Modified emberfall, actually harmful. Admin only. #define MOON_PHASE_NEW_MOON "new moon" #define MOON_PHASE_WAXING_CRESCENT "waxing crescent" diff --git a/code/__defines/qdel.dm b/code/__defines/qdel.dm index 51c6db5325..ab85326658 100644 --- a/code/__defines/qdel.dm +++ b/code/__defines/qdel.dm @@ -22,7 +22,13 @@ #define QDELETED(X) (!X || X.gc_destroyed) #define QDESTROYING(X) (!X || X.gc_destroyed == GC_CURRENTLY_BEING_QDELETED) +//Qdel helper macros. +#define QDEL_IN(item, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/qdel, item), time, TIMER_STOPPABLE) +#define QDEL_IN_CLIENT_TIME(item, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/qdel, item), time, TIMER_STOPPABLE | TIMER_CLIENT_TIME) +#define QDEL_NULL(item) qdel(item); item = null +#define QDEL_LIST_NULL(x) if(x) { for(var/y in x) { qdel(y) } ; x = null } #define QDEL_LIST(L) if(L) { for(var/I in L) qdel(I); L.Cut(); } +#define QDEL_LIST_IN(L, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/______qdel_list_wrapper, L), time, TIMER_STOPPABLE) #define QDEL_LIST_ASSOC(L) if(L) { for(var/I in L) { qdel(L[I]); qdel(I); } L.Cut(); } #define QDEL_LIST_ASSOC_VAL(L) if(L) { for(var/I in L) qdel(L[I]); L.Cut(); } diff --git a/code/__defines/species_languages.dm b/code/__defines/species_languages.dm index f12b630979..4feb1658ac 100644 --- a/code/__defines/species_languages.dm +++ b/code/__defines/species_languages.dm @@ -51,6 +51,7 @@ #define LANGUAGE_EVENT1 "Occursus" #define LANGUAGE_AKHANI "Akhani" #define LANGUAGE_ALAI "Alai" +#define LANGUAGE_GIBBERISH "Babel" // Language flags. #define WHITELISTED 1 // Language is available if the speaker is whitelisted. diff --git a/code/__defines/subsystems.dm b/code/__defines/subsystems.dm index 5c2d9a8ca3..ac480237b5 100644 --- a/code/__defines/subsystems.dm +++ b/code/__defines/subsystems.dm @@ -1,18 +1,23 @@ //Timing subsystem //Don't run if there is an identical unique timer active -#define TIMER_UNIQUE 0x1 +//if the arguments to addtimer are the same as an existing timer, it doesn't create a new timer, and returns the id of the existing timer +#define TIMER_UNIQUE (1<<0) //For unique timers: Replace the old timer rather then not start this one -#define TIMER_OVERRIDE 0x2 +#define TIMER_OVERRIDE (1<<1) //Timing should be based on how timing progresses on clients, not the sever. // tracking this is more expensive, // should only be used in conjuction with things that have to progress client side, such as animate() or sound() -#define TIMER_CLIENT_TIME 0x4 +#define TIMER_CLIENT_TIME (1<<2) //Timer can be stopped using deltimer() -#define TIMER_STOPPABLE 0x8 +#define TIMER_STOPPABLE (1<<3) //To be used with TIMER_UNIQUE //prevents distinguishing identical timers with the wait variable -#define TIMER_NO_HASH_WAIT 0x10 -#define TIMER_NO_INVOKE_WARNING 600 //number of byond ticks that are allowed to pass before the timer subsystem thinks it hung on something +#define TIMER_NO_HASH_WAIT (1<<4) +//Loops the timer repeatedly until qdeleted +//In most cases you want a subsystem instead +#define TIMER_LOOP (1<<5) + +#define TIMER_ID_NULL -1 #define INITIALIZATION_INSSATOMS 0 //New should not call Initialize #define INITIALIZATION_INNEW_MAPLOAD 1 //New should call Initialize(TRUE) @@ -47,19 +52,22 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G // Subsystem init_order, from highest priority to lowest priority // Subsystems shutdown in the reverse of the order they initialize in // The numbers just define the ordering, they are meaningless otherwise. -#define INIT_ORDER_MAPPING 20 // VOREStation Edit -#define INIT_ORDER_DECALS 16 -#define INIT_ORDER_ATOMS 15 -#define INIT_ORDER_MACHINES 10 -#define INIT_ORDER_SHUTTLES 3 -#define INIT_ORDER_DEFAULT 0 -#define INIT_ORDER_LIGHTING 0 -#define INIT_ORDER_AIR -1 -#define INIT_ORDER_PLANETS -4 -#define INIT_ORDER_HOLOMAPS -5 -#define INIT_ORDER_OVERLAY -6 -#define INIT_ORDER_XENOARCH -20 -#define INIT_ORDER_CIRCUIT -21 +#define INIT_ORDER_CHEMISTRY 18 +#define INIT_ORDER_MAPPING 17 +#define INIT_ORDER_DECALS 16 +#define INIT_ORDER_ATOMS 15 +#define INIT_ORDER_MACHINES 10 +#define INIT_ORDER_SHUTTLES 3 +#define INIT_ORDER_TIMER 1 +#define INIT_ORDER_DEFAULT 0 +#define INIT_ORDER_LIGHTING 0 +#define INIT_ORDER_AIR -1 +#define INIT_ORDER_PLANETS -4 +#define INIT_ORDER_HOLOMAPS -5 +#define INIT_ORDER_OVERLAY -6 +#define INIT_ORDER_XENOARCH -20 +#define INIT_ORDER_CIRCUIT -21 +#define INIT_ORDER_AI -22 // Subsystem fire priority, from lowest to highest priority @@ -67,12 +75,16 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G #define FIRE_PRIORITY_SHUTTLES 5 #define FIRE_PRIORITY_ORBIT 8 #define FIRE_PRIORITY_VOTE 9 +#define FIRE_PRIORITY_AI 10 #define FIRE_PRIORITY_GARBAGE 15 #define FIRE_PRIORITY_AIRFLOW 30 #define FIRE_PRIORITY_AIR 35 +#define FIRE_PRIORITY_OBJ 40 +#define FIRE_PRIORITY_PROCESS 45 #define FIRE_PRIORITY_DEFAULT 50 #define FIRE_PRIORITY_PLANETS 75 #define FIRE_PRIORITY_MACHINES 100 +#define FIRE_PRIORITY_PROJECTILES 150 #define FIRE_PRIORITY_OVERLAYS 500 // Macro defining the actual code applying our overlays lists to the BYOND overlays list. (I guess a macro for speed) diff --git a/code/__defines/tick.dm b/code/__defines/tick.dm deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/code/__defines/vv.dm b/code/__defines/vv.dm new file mode 100644 index 0000000000..97e3a02e0d --- /dev/null +++ b/code/__defines/vv.dm @@ -0,0 +1,46 @@ +#define VV_NUM "Number" +#define VV_TEXT "Text" +#define VV_MESSAGE "Mutiline Text" +#define VV_ICON "Icon" +#define VV_ATOM_REFERENCE "Atom Reference" +#define VV_DATUM_REFERENCE "Datum Reference" +#define VV_MOB_REFERENCE "Mob Reference" +#define VV_CLIENT "Client" +#define VV_ATOM_TYPE "Atom Typepath" +#define VV_DATUM_TYPE "Datum Typepath" +#define VV_TYPE "Custom Typepath" +#define VV_FILE "File" +#define VV_LIST "List" +#define VV_NEW_ATOM "New Atom" +#define VV_NEW_DATUM "New Datum" +#define VV_NEW_TYPE "New Custom Typepath" +#define VV_NEW_LIST "New List" +#define VV_NULL "NULL" +#define VV_RESTORE_DEFAULT "Restore to Default" +#define VV_MARKED_DATUM "Marked Datum" +#define VV_BITFIELD "Bitfield" + +#define VV_MSG_MARKED "
Marked Object" +#define VV_MSG_EDITED "
Var Edited" +#define VV_MSG_DELETED "
Deleted" + +#define VV_NORMAL_LIST_NO_EXPAND_THRESHOLD 50 +#define VV_SPECIAL_LIST_NO_EXPAND_THRESHOLD 150 + +#define IS_VALID_ASSOC_KEY(V) (istext(V) || isdatum(V) || islist(V)) + +//Helpers for vv_get_dropdown() +#define VV_DROPDOWN_OPTION(href_key, name) . += "" + +//Helpers for vv_do_topic(list/href_list) +#define IF_VV_OPTION(href_key) if(href_list[href_key]) + +// /datum +#define VV_HK_DELETE "delete" +#define VV_HK_EXPOSE "expose" +#define VV_HK_CALLPROC "proc_call" +#define VV_HK_MARK "mark" + +// /atom +#define VV_HK_ATOM_EXPLODE "turf_explode" +#define VV_HK_ATOM_EMP "turf_emp" diff --git a/code/_global_vars/bitfields.dm b/code/_global_vars/bitfields.dm new file mode 100644 index 0000000000..891c50ce88 --- /dev/null +++ b/code/_global_vars/bitfields.dm @@ -0,0 +1,7 @@ +GLOBAL_LIST_INIT(bitfields, list( + "datum_flags" = list( + "DF_VAR_EDITED" = DF_VAR_EDITED, + "DF_ISPROCESSING" = DF_ISPROCESSING + ) + +)) diff --git a/code/_global_vars/misc.dm b/code/_global_vars/misc.dm index 5e7737f163..6ece6be2d7 100644 --- a/code/_global_vars/misc.dm +++ b/code/_global_vars/misc.dm @@ -1,4 +1,8 @@ -GLOBAL_LIST_EMPTY(all_observable_events) +GLOBAL_LIST_EMPTY(error_last_seen) +GLOBAL_LIST_EMPTY(error_cooldown) + +GLOBAL_DATUM_INIT(all_observable_events, /datum/all_observable_events, new) // This is a datum. It is not a list. +GLOBAL_DATUM_INIT(destroyed_event, /decl/observ/destroyed, new()) GLOBAL_VAR_INIT(timezoneOffset, 0) // The difference betwen midnight (of the host computer) and 0 world.ticks. diff --git a/code/_global_vars/mobs.dm b/code/_global_vars/mobs.dm index fac5a14036..10d829904a 100644 --- a/code/_global_vars/mobs.dm +++ b/code/_global_vars/mobs.dm @@ -2,4 +2,6 @@ GLOBAL_LIST_EMPTY(admins) //all clients whom are admins GLOBAL_PROTECT(admins) GLOBAL_LIST_EMPTY(deadmins) //all ckeys who have used the de-admin verb. GLOBAL_LIST_EMPTY(stealthminID) -GLOBAL_LIST_EMPTY(directory) //all ckeys with associated client \ No newline at end of file +GLOBAL_LIST_EMPTY(directory) //all ckeys with associated client +GLOBAL_LIST_EMPTY(clients) +GLOBAL_LIST_EMPTY(players_by_zlevel) diff --git a/code/_helpers/lists.dm b/code/_helpers/_lists.dm similarity index 96% rename from code/_helpers/lists.dm rename to code/_helpers/_lists.dm index b9e5dd8623..553984330d 100644 --- a/code/_helpers/lists.dm +++ b/code/_helpers/_lists.dm @@ -1,755 +1,758 @@ -/* - * Holds procs to help with list operations - * Contains groups: - * Misc - * Sorting - */ - -/* - * Misc - */ - -//Returns a list in plain english as a string -/proc/english_list(var/list/input, nothing_text = "nothing", and_text = " and ", comma_text = ", ", final_comma_text = "" ) - switch(input.len) - if(0) return nothing_text - if(1) return "[input[1]]" - if(2) return "[input[1]][and_text][input[2]]" - else return "[jointext(input, comma_text, 1, -1)][final_comma_text][and_text][input[input.len]]" - -//Returns list element or null. Should prevent "index out of bounds" error. -proc/listgetindex(var/list/list,index) - if(istype(list) && list.len) - if(isnum(index)) - if(InRange(index,1,list.len)) - return list[index] - else if(index in list) - return list[index] - return - -proc/islist(list/list) - return(istype(list)) - -//Return either pick(list) or null if list is not of type /list or is empty -proc/safepick(list/list) - if(!islist(list) || !list.len) - return - return pick(list) - -//Checks if the list is empty -proc/isemptylist(list/list) - if(!list.len) - return 1 - return 0 - -//Checks for specific types in a list -/proc/is_type_in_list(var/atom/A, var/list/L) - for(var/type in L) - if(istype(A, type)) - return 1 - return 0 - -//Checks for specific paths in a list -/proc/is_path_in_list(var/atom/A, var/list/L) - for(var/path in L) - if(ispath(A, path)) - return 1 - return 0 - -////////////////////////////////////////////////////// -// "typecache" utilities - Making and searching them -////////////////////////////////////////////////////// - -//Checks for specific types in specifically structured (Assoc "type" = TRUE) lists ('typecaches') -/proc/is_type_in_typecache(atom/A, list/L) - if(!LAZYLEN(L) || !A) - return FALSE - return L[A.type] - -//returns a new list with only atoms that are in typecache L -/proc/typecache_filter_list(list/atoms, list/typecache) - . = list() - for(var/thing in atoms) - var/atom/A = thing - if(typecache[A.type]) - . += A - -/proc/typecache_filter_list_reverse(list/atoms, list/typecache) - . = list() - for(var/thing in atoms) - var/atom/A = thing - if(!typecache[A.type]) - . += A - -/proc/typecache_filter_multi_list_exclusion(list/atoms, list/typecache_include, list/typecache_exclude) - . = list() - for(var/thing in atoms) - var/atom/A = thing - if(typecache_include[A.type] && !typecache_exclude[A.type]) - . += A - -//Like typesof() or subtypesof(), but returns a typecache instead of a list -/proc/typecacheof(path, ignore_root_path, only_root_path = FALSE) - if(ispath(path)) - var/list/types = list() - if(only_root_path) - types = list(path) - else - types = ignore_root_path ? subtypesof(path) : typesof(path) - var/list/L = list() - for(var/T in types) - L[T] = TRUE - return L - else if(islist(path)) - var/list/pathlist = path - var/list/L = list() - if(ignore_root_path) - for(var/P in pathlist) - for(var/T in subtypesof(P)) - L[T] = TRUE - else - for(var/P in pathlist) - if(only_root_path) - L[P] = TRUE - else - for(var/T in typesof(P)) - L[T] = TRUE - return L - -////////////////////////////////////////////////////// - -//Empties the list by setting the length to 0. Hopefully the elements get garbage collected -proc/clearlist(list/list) - if(istype(list)) - list.len = 0 - return - -//Removes any null entries from the list -proc/listclearnulls(list/list) - if(istype(list)) - while(null in list) - list -= null - return - -/* - * Returns list containing all the entries from first list that are not present in second. - * If skiprep = 1, repeated elements are treated as one. - * If either of arguments is not a list, returns null - */ -/proc/difflist(var/list/first, var/list/second, var/skiprep=0) - if(!islist(first) || !islist(second)) - return - var/list/result = new - if(skiprep) - for(var/e in first) - if(!(e in result) && !(e in second)) - result += e - else - result = first - second - return result - -/* - * Returns list containing entries that are in either list but not both. - * If skipref = 1, repeated elements are treated as one. - * If either of arguments is not a list, returns null - */ -/proc/uniquemergelist(var/list/first, var/list/second, var/skiprep=0) - if(!islist(first) || !islist(second)) - return - var/list/result = new - if(skiprep) - result = difflist(first, second, skiprep)+difflist(second, first, skiprep) - else - result = first ^ second - return result - -//Pretends to pick an element based on its weight but really just seems to pick a random element. -/proc/pickweight(list/L) - var/total = 0 - var/item - for (item in L) - if (!L[item]) - L[item] = 1 - total += L[item] - - total = rand(1, total) - for (item in L) - total -=L [item] - if (total <= 0) - return item - - return null - -//Pick a random element from the list and remove it from the list. -/proc/pick_n_take(list/listfrom) - if (listfrom.len > 0) - var/picked = pick(listfrom) - listfrom -= picked - return picked - return null - -//Returns the top(last) element from the list and removes it from the list (typical stack function) -/proc/pop(list/listfrom) - if (listfrom.len > 0) - var/picked = listfrom[listfrom.len] - listfrom.len-- - return picked - return null - -//Returns the next element in parameter list after first appearance of parameter element. If it is the last element of the list or not present in list, returns first element. -/proc/next_in_list(element, list/L) - for(var/i=1, i= 1; i--) - output += L[i] - return output - -//Randomize: Return the list in a random order -/proc/shuffle(var/list/L) - if(!L) - return - - L = L.Copy() - - for(var/i=1; i 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_old(name)]" - -/obj/machinery/camera/dd_SortValue() - return "[c_tag]" - -/datum/alarm/dd_SortValue() - return "[sanitize_old(last_name)]" - -/proc/subtypesof(prototype) - return (typesof(prototype) - prototype) - -//creates every subtype of prototype (excluding prototype) and adds it to list L. -//if no list/L is provided, one is created. -/proc/init_subtypes(prototype, list/L) - if(!istype(L)) L = list() - for(var/path in subtypesof(prototype)) - L += new path() - return L - -//creates every subtype of prototype (excluding prototype) and adds it to list L as a type/instance pair. -//if no list/L is provided, one is created. -/proc/init_subtypes_assoc(prototype, list/L) - if(!istype(L)) L = list() - for(var/path in subtypesof(prototype)) - L[path] = new path() - return L - -//Move a single element from position fromIndex within a list, to position toIndex -//All elements in the range [1,toIndex) before the move will be before the pivot afterwards -//All elements in the range [toIndex, L.len+1) before the move will be after the pivot afterwards -//In other words, it's as if the range [fromIndex,toIndex) have been rotated using a <<< operation common to other languages. -//fromIndex and toIndex must be in the range [1,L.len+1] -//This will preserve associations ~Carnie -/proc/moveElement(list/L, fromIndex, toIndex) - if(fromIndex == toIndex || fromIndex+1 == toIndex) //no need to move - return - if(fromIndex > toIndex) - ++fromIndex //since a null will be inserted before fromIndex, the index needs to be nudged right by one - - L.Insert(toIndex, null) - L.Swap(fromIndex, toIndex) - L.Cut(fromIndex, fromIndex+1) - -//Move elements [fromIndex,fromIndex+len) to [toIndex-len, toIndex) -//Same as moveElement but for ranges of elements -//This will preserve associations ~Carnie -/proc/moveRange(list/L, fromIndex, toIndex, len=1) - var/distance = abs(toIndex - fromIndex) - if(len >= distance) //there are more elements to be moved than the distance to be moved. Therefore the same result can be achieved (with fewer operations) by moving elements between where we are and where we are going. The result being, our range we are moving is shifted left or right by dist elements - if(fromIndex <= toIndex) - return //no need to move - fromIndex += len //we want to shift left instead of right - - for(var/i=0, i toIndex) - fromIndex += len - - for(var/i=0, i 0) + var/picked = pick(listfrom) + listfrom -= picked + return picked + return null + +//Returns the top(last) element from the list and removes it from the list (typical stack function) +/proc/pop(list/listfrom) + if (listfrom.len > 0) + var/picked = listfrom[listfrom.len] + listfrom.len-- + return picked + return null + +//Returns the next element in parameter list after first appearance of parameter element. If it is the last element of the list or not present in list, returns first element. +/proc/next_in_list(element, list/L) + for(var/i=1, i= 1; i--) + output += L[i] + return output + +//Randomize: Return the list in a random order +/proc/shuffle(var/list/L) + if(!L) + return + + L = L.Copy() + + for(var/i=1; i 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_old(name)]" + +/obj/machinery/camera/dd_SortValue() + return "[c_tag]" + +/datum/alarm/dd_SortValue() + return "[sanitize_old(last_name)]" + +/proc/subtypesof(prototype) + return (typesof(prototype) - prototype) + +//creates every subtype of prototype (excluding prototype) and adds it to list L. +//if no list/L is provided, one is created. +/proc/init_subtypes(prototype, list/L) + if(!istype(L)) L = list() + for(var/path in subtypesof(prototype)) + L += new path() + return L + +//creates every subtype of prototype (excluding prototype) and adds it to list L as a type/instance pair. +//if no list/L is provided, one is created. +/proc/init_subtypes_assoc(prototype, list/L) + if(!istype(L)) L = list() + for(var/path in subtypesof(prototype)) + L[path] = new path() + return L + +//Move a single element from position fromIndex within a list, to position toIndex +//All elements in the range [1,toIndex) before the move will be before the pivot afterwards +//All elements in the range [toIndex, L.len+1) before the move will be after the pivot afterwards +//In other words, it's as if the range [fromIndex,toIndex) have been rotated using a <<< operation common to other languages. +//fromIndex and toIndex must be in the range [1,L.len+1] +//This will preserve associations ~Carnie +/proc/moveElement(list/L, fromIndex, toIndex) + if(fromIndex == toIndex || fromIndex+1 == toIndex) //no need to move + return + if(fromIndex > toIndex) + ++fromIndex //since a null will be inserted before fromIndex, the index needs to be nudged right by one + + L.Insert(toIndex, null) + L.Swap(fromIndex, toIndex) + L.Cut(fromIndex, fromIndex+1) + +//Move elements [fromIndex,fromIndex+len) to [toIndex-len, toIndex) +//Same as moveElement but for ranges of elements +//This will preserve associations ~Carnie +/proc/moveRange(list/L, fromIndex, toIndex, len=1) + var/distance = abs(toIndex - fromIndex) + if(len >= distance) //there are more elements to be moved than the distance to be moved. Therefore the same result can be achieved (with fewer operations) by moving elements between where we are and where we are going. The result being, our range we are moving is shifted left or right by dist elements + if(fromIndex <= toIndex) + return //no need to move + fromIndex += len //we want to shift left instead of right + + for(var/i=0, i toIndex) + fromIndex += len + + for(var/i=0, ilayers.len) // Reached end of list without inserting - layers[current]=currentLayer // Place at end + if(flat_size ~! add_size) + // Resize the flattened icon so the new icon fits + flat.Crop( + addX1 - flatX1 + 1, + addY1 - flatY1 + 1, + addX2 - flatX1 + 1, + addY2 - flatY1 + 1 + ) + flat_size = add_size.Copy() - curIndex++ + // Blend the overlay into the flattened icon + flat.Blend(add, blendMode2iconMode(curblend), I.pixel_x + 2 - flatX1, I.pixel_y + 2 - flatY1) - if(curIndex>process.len) - if(pSet == 0) // Switch to overlays - curIndex = 1 - pSet = 1 - process = A.overlays - else // All done - break + if(A.color) + if(islist(A.color)) + flat.MapColors(arglist(A.color)) + else + flat.Blend(A.color, ICON_MULTIPLY) - var/icon/add // Icon of overlay being added + if(A.alpha < 255) + flat.Blend(rgb(255, 255, 255, A.alpha), ICON_MULTIPLY) - // Current dimensions of flattened icon - var/flatX1=1 - var/flatX2=flat.Width() - var/flatY1=1 - var/flatY2=flat.Height() - // Dimensions of overlay being added - var/addX1 - var/addX2 - var/addY1 - var/addY2 - - for(var/V in layers) - var/image/I = V - if(I.alpha == 0) - continue - - if(I == copy) // 'I' is an /image based on the object being flattened. - curblend = BLEND_OVERLAY - add = icon(I.icon, I.icon_state, base_icon_dir) - else // 'I' is an appearance object. - add = getFlatIcon(new/image(I), curdir, curicon, curstate, curblend, FALSE, no_anim) - - // Find the new dimensions of the flat icon to fit the added overlay - addX1 = min(flatX1, I.pixel_x+1) - addX2 = max(flatX2, I.pixel_x+add.Width()) - addY1 = min(flatY1, I.pixel_y+1) - addY2 = max(flatY2, I.pixel_y+add.Height()) - - if(addX1!=flatX1 || addX2!=flatX2 || addY1!=flatY1 || addY2!=flatY2) - // Resize the flattened icon so the new icon fits - flat.Crop(addX1-flatX1+1, addY1-flatY1+1, addX2-flatX1+1, addY2-flatY1+1) - flatX1=addX1;flatX2=addX2 - flatY1=addY1;flatY2=addY2 - - // Blend the overlay into the flattened icon - flat.Blend(add, blendMode2iconMode(curblend), I.pixel_x + 2 - flatX1, I.pixel_y + 2 - flatY1) - - if(A.color) - flat.Blend(A.color, ICON_MULTIPLY) - if(A.alpha < 255) - flat.Blend(rgb(255, 255, 255, A.alpha), ICON_MULTIPLY) - - if(no_anim) - //Clean up repeated frames - var/icon/cleaned = new /icon() - cleaned.Insert(flat, "", SOUTH, 1, 0) - return cleaned - else - return icon(flat, "", SOUTH) + if(no_anim) + //Clean up repeated frames + var/icon/cleaned = new /icon() + cleaned.Insert(flat, "", SOUTH, 1, 0) + . = cleaned + else + . = icon(flat, "", SOUTH) + else //There's no overlays. + if(!noIcon) + SET_SELF(.) + //Clear defines + #undef flatX1 + #undef flatX2 + #undef flatY1 + #undef flatY2 + #undef addX1 + #undef addX2 + #undef addY1 + #undef addY2 + #undef INDEX_X_LOW + #undef INDEX_X_HIGH + #undef INDEX_Y_LOW + #undef INDEX_Y_HIGH + #undef BLANK + #undef SET_SELF /proc/getIconMask(atom/A)//By yours truly. Creates a dynamic mask for a mob/whatever. /N var/icon/alpha_mask = new(A.icon,A.icon_state)//So we want the default icon and icon state of A. @@ -900,9 +904,9 @@ proc/adjust_brightness(var/color, var/value) if (!value) return color var/list/RGB = ReadRGB(color) - RGB[1] = Clamp(RGB[1]+value,0,255) - RGB[2] = Clamp(RGB[2]+value,0,255) - RGB[3] = Clamp(RGB[3]+value,0,255) + RGB[1] = CLAMP(RGB[1]+value,0,255) + RGB[2] = CLAMP(RGB[2]+value,0,255) + RGB[3] = CLAMP(RGB[3]+value,0,255) return rgb(RGB[1],RGB[2],RGB[3]) proc/sort_atoms_by_layer(var/list/atoms) diff --git a/code/_helpers/maths.dm b/code/_helpers/maths.dm deleted file mode 100644 index 4cbe75bffc..0000000000 --- a/code/_helpers/maths.dm +++ /dev/null @@ -1,131 +0,0 @@ -// Macro functions. -#define RAND_F(LOW, HIGH) (rand()*(HIGH-LOW) + LOW) -#define ceil(x) (-round(-(x))) - -// min is inclusive, max is exclusive -/proc/Wrap(val, min, max) - var/d = max - min - var/t = Floor((val - min) / d) - return val - (t * d) - -/proc/Default(a, b) - return a ? a : b - -// Trigonometric functions. -/proc/Tan(x) - return sin(x) / cos(x) - -/proc/Csc(x) - return 1 / sin(x) - -/proc/Sec(x) - return 1 / cos(x) - -/proc/Cot(x) - return 1 / Tan(x) - -/proc/Atan2(x, y) - if(!x && !y) return 0 - var/a = arccos(x / sqrt(x*x + y*y)) - return y >= 0 ? a : -a - -/proc/Floor(x) - return round(x) - -/proc/Ceiling(x) - return -round(-x) - -// Greatest Common Divisor: Euclid's algorithm. -/proc/Gcd(a, b) - while (1) - if (!b) return a - a %= b - if (!a) return b - b %= a - -// Least Common Multiple. The formula is a consequence of: a*b = LCM*GCD. -/proc/Lcm(a, b) - return abs(a) * abs(b) / Gcd(a, b) - -// Useful in the cases when x is a large expression, e.g. x = 3a/2 + b^2 + Function(c) -/proc/Square(x) - return x*x - -/proc/Inverse(x) - return 1 / x - -// Condition checks. -/proc/IsAboutEqual(a, b, delta = 0.1) - return abs(a - b) <= delta - -// Returns true if val is from min to max, inclusive. -/proc/IsInRange(val, min, max) - return (val >= min) && (val <= max) - -/proc/IsInteger(x) - return Floor(x) == x - -/proc/IsMultiple(x, y) - return x % y == 0 - -/proc/IsEven(x) - return !(x & 0x1) - -/proc/IsOdd(x) - return (x & 0x1) - -// Performs a linear interpolation between a and b. -// Note: weight=0 returns a, weight=1 returns b, and weight=0.5 returns the mean of a and b. -/proc/Interpolate(a, b, weight = 0.5) - return a + (b - a) * weight // Equivalent to: a*(1 - weight) + b*weight - -/proc/Mean(...) - var/sum = 0 - for(var/val in args) - sum += val - return sum / args.len - -// Returns the nth root of x. -/proc/Root(n, x) - return x ** (1 / n) - -// The quadratic formula. Returns a list with the solutions, or an empty list -// if they are imaginary. -/proc/SolveQuadratic(a, b, c) - ASSERT(a) - - . = list() - var/discriminant = b*b - 4*a*c - var/bottom = 2*a - - // Return if the roots are imaginary. - if(discriminant < 0) - return - - var/root = sqrt(discriminant) - . += (-b + root) / bottom - - // If discriminant == 0, there would be two roots at the same position. - if(discriminant != 0) - . += (-b - root) / bottom - -/proc/ToDegrees(radians) - // 180 / Pi ~ 57.2957795 - return radians * 57.2957795 - -/proc/ToRadians(degrees) - // Pi / 180 ~ 0.0174532925 - return degrees * 0.0174532925 - -// Vector algebra. -/proc/squaredNorm(x, y) - return x*x + y*y - -/proc/norm(x, y) - return sqrt(squaredNorm(x, y)) - -/proc/IsPowerOfTwo(var/val) - return (val & (val-1)) == 0 - -/proc/RoundUpToPowerOfTwo(var/val) - return 2 ** -round(-log(2,val)) diff --git a/code/_helpers/matrices.dm b/code/_helpers/matrices.dm index 2e7247543c..a5ef701c2d 100644 --- a/code/_helpers/matrices.dm +++ b/code/_helpers/matrices.dm @@ -50,7 +50,7 @@ /proc/color_rotation(angle) if(angle == 0) return color_identity() - angle = Clamp(angle, -180, 180) + angle = CLAMP(angle, -180, 180) var/cos = cos(angle) var/sin = sin(angle) @@ -65,7 +65,7 @@ //Makes everything brighter or darker without regard to existing color or brightness /proc/color_brightness(power) - power = Clamp(power, -255, 255) + power = CLAMP(power, -255, 255) power = power/255 return list(1,0,0, 0,1,0, 0,0,1, power,power,power) @@ -85,7 +85,7 @@ //Exxagerates or removes brightness /proc/color_contrast(value) - value = Clamp(value, -100, 100) + value = CLAMP(value, -100, 100) if(value == 0) return color_identity() @@ -108,7 +108,7 @@ /proc/color_saturation(value as num) if(value == 0) return color_identity() - value = Clamp(value, -100, 100) + value = CLAMP(value, -100, 100) if(value > 0) value *= 3 var/x = 1 + value / 100 diff --git a/code/_helpers/mobs.dm b/code/_helpers/mobs.dm index bc111ccbcb..b3b2836d78 100644 --- a/code/_helpers/mobs.dm +++ b/code/_helpers/mobs.dm @@ -285,16 +285,3 @@ Proc for attack log creation, because really why not else . = getCompoundIcon(desired) cached_character_icons[cachekey] = . - -/proc/getviewsize(view) - var/viewX - var/viewY - if(isnum(view)) - var/totalviewrange = 1 + 2 * view - viewX = totalviewrange - viewY = totalviewrange - else - var/list/viewrangelist = splittext(view,"x") - viewX = text2num(viewrangelist[1]) - viewY = text2num(viewrangelist[2]) - return list(viewX, viewY) diff --git a/code/_helpers/sorts/comparators.dm b/code/_helpers/sorts/comparators.dm index 7fd07ec711..73ad3d847c 100644 --- a/code/_helpers/sorts/comparators.dm +++ b/code/_helpers/sorts/comparators.dm @@ -19,6 +19,9 @@ /proc/cmp_subsystem_priority(datum/controller/subsystem/a, datum/controller/subsystem/b) return a.priority - b.priority +/proc/cmp_timer(datum/timedevent/a, datum/timedevent/b) + return a.timeToRun - b.timeToRun + // Sorts qdel statistics recorsd by time and count /proc/cmp_qdel_item_time(datum/qdel_item/A, datum/qdel_item/B) . = B.hard_delete_time - A.hard_delete_time diff --git a/code/_helpers/time.dm b/code/_helpers/time.dm index ce640731a6..c075925fdd 100644 --- a/code/_helpers/time.dm +++ b/code/_helpers/time.dm @@ -16,8 +16,8 @@ #define TICK *world.tick_lag #define TICKS *world.tick_lag -#define DS2TICKS(DS) (DS/world.tick_lag) // Convert deciseconds to ticks -#define TICKS2DS(T) (T TICKS) // Convert ticks to deciseconds +#define DS2TICKS(DS) ((DS)/world.tick_lag) // Convert deciseconds to ticks +#define TICKS2DS(T) ((T) TICKS) // Convert ticks to deciseconds /proc/get_game_time() var/global/time_offset = 0 @@ -140,103 +140,36 @@ var/round_start_time = 0 . += CEILING(i*DELTA_CALC, 1) sleep(i*world.tick_lag*DELTA_CALC) i *= 2 - while (TICK_USAGE > min(TICK_LIMIT_TO_RUN, GLOB.CURRENT_TICKLIMIT)) + while (TICK_USAGE > min(TICK_LIMIT_TO_RUN, Master.current_ticklimit)) #undef DELTA_CALC //Takes a value of time in deciseconds. //Returns a text value of that number in hours, minutes, or seconds. -/proc/DisplayTimeText(time_value, truncate = FALSE) - var/second = (time_value)*0.1 - var/second_adjusted = null - var/second_rounded = FALSE - var/minute = null - var/hour = null - var/day = null - +/proc/DisplayTimeText(time_value, round_seconds_to = 0.1) + var/second = round(time_value * 0.1, round_seconds_to) if(!second) - return "0 seconds" - if(second >= 60) - minute = FLOOR(second/60, 1) - second = round(second - (minute*60), 0.1) - second_rounded = TRUE - if(second) //check if we still have seconds remaining to format, or if everything went into minute. - second_adjusted = round(second) //used to prevent '1 seconds' being shown - if(day || hour || minute) - if(second_adjusted == 1 && second >= 1) - second = " and 1 second" - else if(second > 1) - second = " and [second_adjusted] seconds" - else //shows a fraction if seconds is < 1 - if(second_rounded) //no sense rounding again if it's already done - second = " and [second] seconds" - else - second = " and [round(second, 0.1)] seconds" - else - if(second_adjusted == 1 && second >= 1) - second = "[truncate ? "second" : "1 second"]" - else if(second > 1) - second = "[second_adjusted] seconds" - else - if(second_rounded) - second = "[second] seconds" - else - second = "[round(second, 0.1)] seconds" - else - second = null - - if(!minute) - return "[second]" - if(minute >= 60) - hour = FLOOR(minute/60, 1) - minute = (minute - (hour*60)) - if(minute) //alot simpler from here since you don't have to worry about fractions - if(minute != 1) - if((day || hour) && second) - minute = ", [minute] minutes" - else if((day || hour) && !second) - minute = " and [minute] minutes" - else - minute = "[minute] minutes" - else - if((day || hour) && second) - minute = ", 1 minute" - else if((day || hour) && !second) - minute = " and 1 minute" - else - minute = "[truncate ? "minute" : "1 minute"]" - else - minute = null - - if(!hour) - return "[minute][second]" - if(hour >= 24) - day = FLOOR(hour/24, 1) - hour = (hour - (day*24)) + return "right now" + if(second < 60) + return "[second] second[(second != 1)? "s":""]" + var/minute = FLOOR(second / 60, 1) + second = MODULUS(second, 60) + var/secondT + if(second) + secondT = " and [second] second[(second != 1)? "s":""]" + if(minute < 60) + return "[minute] minute[(minute != 1)? "s":""][secondT]" + var/hour = FLOOR(minute / 60, 1) + minute = MODULUS(minute, 60) + var/minuteT + if(minute) + minuteT = " and [minute] minute[(minute != 1)? "s":""]" + if(hour < 24) + return "[hour] hour[(hour != 1)? "s":""][minuteT][secondT]" + var/day = FLOOR(hour / 24, 1) + hour = MODULUS(hour, 24) + var/hourT if(hour) - if(hour != 1) - if(day && (minute || second)) - hour = ", [hour] hours" - else if(day && (!minute || !second)) - hour = " and [hour] hours" - else - hour = "[hour] hours" - else - if(day && (minute || second)) - hour = ", 1 hour" - else if(day && (!minute || !second)) - hour = " and 1 hour" - else - hour = "[truncate ? "hour" : "1 hour"]" - else - hour = null - - if(!day) - return "[hour][minute][second]" - if(day > 1) - day = "[day] days" - else - day = "[truncate ? "day" : "1 day"]" - - return "[day][hour][minute][second]" \ No newline at end of file + hourT = " and [hour] hour[(hour != 1)? "s":""]" + return "[day] day[(day != 1)? "s":""][hourT][minuteT][secondT]" diff --git a/code/_helpers/type2type.dm b/code/_helpers/type2type.dm index 0316e1d186..bdfa4e0fbb 100644 --- a/code/_helpers/type2type.dm +++ b/code/_helpers/type2type.dm @@ -242,3 +242,42 @@ /proc/isLeap(y) return ((y) % 4 == 0 && ((y) % 100 != 0 || (y) % 400 == 0)) + +//Takes a string and a datum +//The string is well, obviously the string being checked +//The datum is used as a source for var names, to check validity +//Otherwise every single word could technically be a variable! +/proc/string2listofvars(var/t_string, var/datum/var_source) + if(!t_string || !var_source) + return list() + + . = list() + + var/var_found = findtext(t_string,"\[") //Not the actual variables, just a generic "should we even bother" check + if(var_found) + //Find var names + + // "A dog said hi [name]!" + // splittext() --> list("A dog said hi ","name]!" + // jointext() --> "A dog said hi name]!" + // splittext() --> list("A","dog","said","hi","name]!") + + t_string = replacetext(t_string,"\[","\[ ")//Necessary to resolve "word[var_name]" scenarios + var/list/list_value = splittext(t_string,"\[") + var/intermediate_stage = jointext(list_value, null) + + list_value = splittext(intermediate_stage," ") + for(var/value in list_value) + if(findtext(value,"]")) + value = splittext(value,"]") //"name]!" --> list("name","!") + for(var/A in value) + if(var_source.vars.Find(A)) + . += A + +/proc/get_end_section_of_type(type) + var/strtype = "[type]" + var/delim_pos = findlasttext(strtype, "/") + if(delim_pos == 0) + return strtype + return copytext(strtype, delim_pos) + diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm index 7f1ff432e8..ab6b4a9f7d 100644 --- a/code/_helpers/unsorted.dm +++ b/code/_helpers/unsorted.dm @@ -501,7 +501,7 @@ Turf and target are seperate in case you want to teleport some distance from a t moblist.Add(M) for(var/mob/new_player/M in sortmob) moblist.Add(M) - for(var/mob/living/simple_animal/M in sortmob) + for(var/mob/living/simple_mob/M in sortmob) moblist.Add(M) // for(var/mob/living/silicon/hivebot/M in sortmob) // mob_list.Add(M) @@ -831,6 +831,7 @@ proc/GaussRandRound(var/sigma,var/roundto) //Move the objects. Not forceMove because the object isn't "moving" really, it's supposed to be on the "same" turf. for(var/obj/O in T) O.loc = X + O.update_light() //Move the mobs unless it's an AI eye or other eye type. for(var/mob/M in T) @@ -1266,9 +1267,11 @@ var/mob/dview/dview_mob = new if(!center) return - if(!dview_mob) //VOREStation Add - Emergency Backup + //VOREStation Add - Emergency Backup + if(!dview_mob) dview_mob = new() WARNING("dview mob was lost, and had to be recreated!") + //VOREStation Add End dview_mob.loc = center @@ -1402,6 +1405,20 @@ var/mob/dview/dview_mob = new #undef NOT_FLAG #undef HAS_FLAG +//datum may be null, but it does need to be a typed var +#define NAMEOF(datum, X) (#X || ##datum.##X) + +#define VARSET_LIST_CALLBACK(target, var_name, var_value) CALLBACK(GLOBAL_PROC, /proc/___callbackvarset, ##target, ##var_name, ##var_value) +//dupe code because dm can't handle 3 level deep macros +#define VARSET_CALLBACK(datum, var, var_value) CALLBACK(GLOBAL_PROC, /proc/___callbackvarset, ##datum, NAMEOF(##datum, ##var), ##var_value) + +/proc/___callbackvarset(list_or_datum, var_name, var_value) + if(length(list_or_datum)) + list_or_datum[var_name] = var_value + return + var/datum/D = list_or_datum + D.vars[var_name] = var_value + // Returns direction-string, rounded to multiples of 22.5, from the first parameter to the second // N, NNE, NE, ENE, E, ESE, SE, SSE, S, SSW, SW, WSW, W, WNW, NW, NNW /proc/get_adir(var/turf/A, var/turf/B) @@ -1440,24 +1457,96 @@ var/mob/dview/dview_mob = new if(337.5) return "North-Northwest" -//This is used to force compiletime errors if you incorrectly supply variable names. Crafty! -#define NAMEOF(datum, X) (#X || ##datum.##X) - -//Creates a callback with the specific purpose of setting a variable -#define VARSET_CALLBACK(datum, var, var_value) CALLBACK(GLOBAL_PROC, /proc/___callbackvarset, weakref(##datum), NAMEOF(##datum, ##var), ##var_value) - -//Helper for the above -/proc/___callbackvarset(list_or_datum, var_name, var_value) - if(isweakref(list_or_datum)) - var/weakref/wr = list_or_datum - list_or_datum = wr.resolve() - if(!list_or_datum) - return - if(length(list_or_datum)) - list_or_datum[var_name] = var_value - return - var/datum/D = list_or_datum - D.vars[var_name] = var_value - /proc/pass() return + +#define NAMEOF(datum, X) (#X || ##datum.##X) + +/proc/pick_closest_path(value, list/matches = get_fancy_list_of_atom_types()) + if (value == FALSE) //nothing should be calling us with a number, so this is safe + value = input("Enter type to find (blank for all, cancel to cancel)", "Search for type") as null|text + if (isnull(value)) + return + value = trim(value) + if(!isnull(value) && value != "") + matches = filter_fancy_list(matches, value) + + if(matches.len==0) + return + + var/chosen + if(matches.len==1) + chosen = matches[1] + else + chosen = input("Select a type", "Pick Type", matches[1]) as null|anything in matches + if(!chosen) + return + chosen = matches[chosen] + return chosen + +/proc/get_fancy_list_of_atom_types() + var/static/list/pre_generated_list + if (!pre_generated_list) //init + pre_generated_list = make_types_fancy(typesof(/atom)) + return pre_generated_list + +/proc/get_fancy_list_of_datum_types() + var/static/list/pre_generated_list + if (!pre_generated_list) //init + pre_generated_list = make_types_fancy(sortList(typesof(/datum) - typesof(/atom))) + return pre_generated_list + +/proc/filter_fancy_list(list/L, filter as text) + var/list/matches = new + for(var/key in L) + var/value = L[key] + if(findtext("[key]", filter) || findtext("[value]", filter)) + matches[key] = value + return matches + +/proc/make_types_fancy(var/list/types) + if (ispath(types)) + types = list(types) + . = list() + for(var/type in types) + var/typename = "[type]" + var/static/list/TYPES_SHORTCUTS = list( + /obj/effect/decal/cleanable = "CLEANABLE", + /obj/item/device/radio/headset = "HEADSET", + /obj/item/clothing/head/helmet/space = "SPESSHELMET", + /obj/item/weapon/book/manual = "MANUAL", + /obj/item/weapon/reagent_containers/food/drinks = "DRINK", + /obj/item/weapon/reagent_containers/food = "FOOD", + /obj/item/weapon/reagent_containers = "REAGENT_CONTAINERS", + /obj/machinery/atmospherics = "ATMOS_MECH", + /obj/machinery/portable_atmospherics = "PORT_ATMOS", + /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack = "MECHA_MISSILE_RACK", + /obj/item/mecha_parts/mecha_equipment = "MECHA_EQUIP", + /obj/item/organ = "ORGAN", + /obj/item = "ITEM", + /obj/machinery = "MACHINERY", + /obj/effect = "EFFECT", + /obj = "O", + /datum = "D", + /turf/simulated/wall = "S-WALL", + /turf/simulated/floor = "S-FLOOR", + /turf/simulated = "SIMULATED", + /turf/unsimulated/wall = "US-WALL", + /turf/unsimulated/floor = "US-FLOOR", + /turf/unsimulated = "UNSIMULATED", + /turf = "T", + /mob/living/carbon = "CARBON", + /mob/living/simple_mob = "SIMPLE", + /mob/living = "LIVING", + /mob = "M" + ) + for (var/tn in TYPES_SHORTCUTS) + if (copytext(typename,1, length("[tn]/")+1)=="[tn]/" /*findtextEx(typename,"[tn]/",1,2)*/ ) + typename = TYPES_SHORTCUTS[tn]+copytext(typename,length("[tn]/")) + break + .[typename] = type + +/proc/IsValidSrc(datum/D) + if(istype(D)) + return !QDELETED(D) + return FALSE \ No newline at end of file diff --git a/code/_helpers/vector.dm b/code/_helpers/vector.dm deleted file mode 100644 index 44d293734c..0000000000 --- a/code/_helpers/vector.dm +++ /dev/null @@ -1,141 +0,0 @@ -/* -plot_vector is a helper datum for plotting a path in a straight line towards a target turf. -This datum converts from world space (turf.x and turf.y) to pixel space, which the datum keeps track of itself. This -should work with any size turfs (i.e. 32x32, 64x64) as it references world.icon_size (note: not actually tested with -anything other than 32x32 turfs). - -setup() - This should be called after creating a new instance of a plot_vector datum. - This does the initial setup and calculations. Since we are travelling in a straight line we only need to calculate - the vector and x/y steps once. x/y steps are capped to 1 full turf, whichever is further. If we are travelling along - the y axis each step will be +/- 1 y, and the x movement reduced based on the angle (tangent calculation). After - this every subsequent step will be incremented based on these calculations. - Inputs: - source - the turf the object is starting from - target - the target turf the object is travelling towards - xo - starting pixel_x offset, typically won't be needed, but included in case someone has a need for it later - yo - same as xo, but for the y_pixel offset - -increment() - Adds the offset to the current location - incrementing it by one step along the vector. - -return_angle() - Returns the direction (angle in degrees) the object is travelling in. - - (N) - 90° - ^ - | - (W) 180° <--+--> 0° (E) - | - v - -90° - (S) - -return_hypotenuse() - Returns the distance of travel for each step of the vector, relative to each full step of movement. 1 is a full turf - length. Currently used as a multiplier for scaling effects that should be contiguous, like laser beams. - -return_location() - Returns a vector_loc datum containing the current location data of the object (see /datum/vector_loc). This includes - the turf it currently should be at, as well as the pixel offset from the centre of that turf. Typically increment() - would be called before this if you are going to move an object based on it's vector data. -*/ - -/datum/plot_vector - var/turf/source - var/turf/target - var/angle = 0 // direction of travel in degrees - var/loc_x = 0 // in pixels from the left edge of the map - var/loc_y = 0 // in pixels from the bottom edge of the map - var/loc_z = 0 // loc z is in world space coordinates (i.e. z level) - we don't care about measuring pixels for this - var/offset_x = 0 // distance to increment each step - var/offset_y = 0 - -/datum/plot_vector/proc/setup(var/turf/S, var/turf/T, var/xo = 0, var/yo = 0, var/angle_offset=0) - source = S - target = T - - if(!istype(source)) - source = get_turf(source) - if(!istype(target)) - target = get_turf(target) - - if(!istype(source) || !istype(target)) - return - - // convert coordinates to pixel space (default is 32px/turf, 8160px across for a size 255 map) - loc_x = source.x * world.icon_size + xo - loc_y = source.y * world.icon_size + yo - loc_z = source.z - - // calculate initial x and y difference - var/dx = target.x - source.x - var/dy = target.y - source.y - - // if we aren't moving anywhere; quit now - if(dx == 0 && dy == 0) - return - - // calculate the angle - angle = Atan2(dx, dy) + angle_offset - - // and some rounding to stop the increments jumping whole turfs - because byond favours certain angles - if(angle > -135 && angle < 45) - angle = Ceiling(angle) - else - angle = Floor(angle) - - // calculate the offset per increment step - if(abs(angle) in list(0, 45, 90, 135, 180)) // check if the angle is a cardinal - if(abs(angle) in list(0, 45, 135, 180)) // if so we can skip the trigonometry and set these to absolutes as - offset_x = sign(dx) // they will always be a full step in one or more directions - if(abs(angle) in list(45, 90, 135)) - offset_y = sign(dy) - else if(abs(dy) > abs(dx)) - offset_x = Cot(abs(angle)) // otherwise set the offsets - offset_y = sign(dy) - else - offset_x = sign(dx) - offset_y = Tan(angle) - if(dx < 0) - offset_y = -offset_y - - // multiply the offset by the turf pixel size - offset_x *= world.icon_size - offset_y *= world.icon_size - -/datum/plot_vector/proc/increment() - loc_x += offset_x - loc_y += offset_y - -/datum/plot_vector/proc/return_angle() - return angle - -/datum/plot_vector/proc/return_hypotenuse() - return sqrt(((offset_x / 32) ** 2) + ((offset_y / 32) ** 2)) - -/datum/plot_vector/proc/return_location(var/datum/vector_loc/data) - if(!data) - data = new() - data.loc = locate(round(loc_x / world.icon_size, 1), round(loc_y / world.icon_size, 1), loc_z) - if(!data.loc) - return - data.pixel_x = loc_x - (data.loc.x * world.icon_size) - data.pixel_y = loc_y - (data.loc.y * world.icon_size) - return data - -/* -vector_loc is a helper datum for returning precise location data from plot_vector. It includes the turf the object is in -as well as the pixel offsets. - -return_turf() - Returns the turf the object should be currently located in. -*/ -/datum/vector_loc - var/turf/loc - var/pixel_x - var/pixel_y - -/datum/vector_loc/proc/return_turf() - return loc diff --git a/code/_helpers/view.dm b/code/_helpers/view.dm new file mode 100644 index 0000000000..13ee837caa --- /dev/null +++ b/code/_helpers/view.dm @@ -0,0 +1,12 @@ +/proc/getviewsize(view) + var/viewX + var/viewY + if(isnum(view)) + var/totalviewrange = 1 + 2 * view + viewX = totalviewrange + viewY = totalviewrange + else + var/list/viewrangelist = splittext(view,"x") + viewX = text2num(viewrangelist[1]) + viewY = text2num(viewrangelist[2]) + return list(viewX, viewY) diff --git a/code/_macros.dm b/code/_macros.dm index 9cd11a6c15..0af691a90c 100644 --- a/code/_macros.dm +++ b/code/_macros.dm @@ -1,57 +1,7 @@ -#define Clamp(x, y, z) (x <= y ? y : (x >= z ? z : x)) - -#define CLAMP01(x) (Clamp(x, 0, 1)) - #define span(class, text) ("[text]") #define get_turf(A) get_step(A,0) -#define isAI(A) istype(A, /mob/living/silicon/ai) - -#define isalien(A) istype(A, /mob/living/carbon/alien) - -#define isanimal(A) istype(A, /mob/living/simple_animal) - -#define isairlock(A) istype(A, /obj/machinery/door/airlock) - -#define isbrain(A) istype(A, /mob/living/carbon/brain) - -#define iscarbon(A) istype(A, /mob/living/carbon) - -#define iscorgi(A) istype(A, /mob/living/simple_animal/corgi) - -#define isEye(A) istype(A, /mob/observer/eye) - -#define ishuman(A) istype(A, /mob/living/carbon/human) - -#define isliving(A) istype(A, /mob/living) - -#define ismouse(A) istype(A, /mob/living/simple_animal/mouse) - -#define isnewplayer(A) istype(A, /mob/new_player) - -#define isobserver(A) istype(A, /mob/observer/dead) - -#define isorgan(A) istype(A, /obj/item/organ/external) - -#define ispAI(A) istype(A, /mob/living/silicon/pai) - -#define isrobot(A) istype(A, /mob/living/silicon/robot) - -#define issilicon(A) istype(A, /mob/living/silicon) - -#define isvoice(A) istype(A, /mob/living/voice) - -#define isslime(A) istype(A, /mob/living/simple_animal/slime) - -#define isbot(A) istype(A, /mob/living/bot) - -#define isxeno(A) istype(A, /mob/living/simple_animal/xeno) - -#define isopenspace(A) istype(A, /turf/simulated/open) - -#define isweakref(A) istype(A, /weakref) - #define RANDOM_BLOOD_TYPE pick(4;"O-", 36;"O+", 3;"A-", 28;"A+", 1;"B-", 20;"B+", 1;"AB-", 5;"AB+") #define to_chat(target, message) target << message @@ -62,35 +12,12 @@ #define to_file(file_entry, source_var) file_entry << source_var #define from_file(file_entry, target_var) file_entry >> target_var +// From TG, might be useful to have. +// Didn't port SEND_TEXT() since to_chat() appears to serve the same purpose. +#define DIRECT_OUTPUT(A, B) A << B +#define SEND_IMAGE(target, image) DIRECT_OUTPUT(target, image) +#define SEND_SOUND(target, sound) DIRECT_OUTPUT(target, sound) #define CanInteract(user, state) (CanUseTopic(user, state) == STATUS_INTERACTIVE) -#define QDEL_NULL_LIST(x) if(x) { for(var/y in x) { qdel(y) } ; x = null } - -#define QDEL_NULL(x) if(x) { qdel(x) ; x = null } - #define ARGS_DEBUG log_debug("[__FILE__] - [__LINE__]") ; for(var/arg in args) { log_debug("\t[log_info_line(arg)]") } - -// Helper macros to aid in optimizing lazy instantiation of lists. -// All of these are null-safe, you can use them without knowing if the list var is initialized yet - -//Picks from the list, with some safeties, and returns the "default" arg if it fails -#define DEFAULTPICK(L, default) ((istype(L, /list) && L:len) ? pick(L) : default) -// Ensures L is initailized after this point -#define LAZYINITLIST(L) if (!L) L = list() -// Sets a L back to null iff it is empty -#define UNSETEMPTY(L) if (L && !L.len) L = null -// Removes I from list L, and sets I to null if it is now empty -#define LAZYREMOVE(L, I) if(L) { L -= I; if(!L.len) { L = null; } } -// Adds I to L, initalizing I if necessary -#define LAZYADD(L, I) if(!L) { L = list(); } L += I; -// Reads I from L safely - Works with both associative and traditional lists. -#define LAZYACCESS(L, I) (L ? (isnum(I) ? (I > 0 && I <= L.len ? L[I] : null) : L[I]) : null) -// Reads the length of L, returning 0 if null -#define LAZYLEN(L) length(L) -// Null-safe L.Cut() -#define LAZYCLEARLIST(L) if(L) L.Cut() -// Reads L or an empty list if L is not a list. Note: Does NOT assign, L may be an expression. -#define SANITIZE_LIST(L) ( islist(L) ? L : list() ) -// Turns LAZYINITLIST(L) L[K] = V into ... for associated lists -#define LAZYSET(L, K, V) if(!L) { L = list(); } L[K] = V; \ No newline at end of file diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 17b62d739f..643ab6d790 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -76,7 +76,7 @@ if(!locate(/turf) in list(A, A.loc)) // Prevents inventory from being drilled return var/obj/mecha/M = loc - return M.click_action(A, src) + return M.click_action(A, src, params) if(restrained()) setClickCooldown(10) @@ -282,10 +282,10 @@ Laser Eyes: as the name implies, handles this since nothing else does currently face_atom: turns the mob towards what you clicked on */ -/mob/proc/LaserEyes(atom/A) +/mob/proc/LaserEyes(atom/A, params) return -/mob/living/LaserEyes(atom/A) +/mob/living/LaserEyes(atom/A, params) setClickCooldown(4) var/turf/T = get_turf(src) @@ -293,8 +293,11 @@ LE.icon = 'icons/effects/genetics.dmi' LE.icon_state = "eyelasers" playsound(usr.loc, 'sound/weapons/taser2.ogg', 75, 1) - LE.launch(A) -/mob/living/carbon/human/LaserEyes() + LE.firer = src + LE.preparePixelProjectile(A, src, params) + LE.fire() + +/mob/living/carbon/human/LaserEyes(atom/A, params) if(nutrition>0) ..() nutrition = max(nutrition - rand(1,5),0) diff --git a/code/_onclick/hud/action.dm b/code/_onclick/hud/action.dm index 2b29fa6492..b5299cd77b 100644 --- a/code/_onclick/hud/action.dm +++ b/code/_onclick/hud/action.dm @@ -82,7 +82,7 @@ /datum/action/proc/Deactivate() return -/datum/action/proc/Process() +/datum/action/process() return /datum/action/proc/CheckRemoval(mob/living/user) // 1 if action is no longer valid for this mob and should be removed diff --git a/code/_onclick/hud/fullscreen.dm b/code/_onclick/hud/fullscreen.dm index 94a067200a..2a92ba20bc 100644 --- a/code/_onclick/hud/fullscreen.dm +++ b/code/_onclick/hud/fullscreen.dm @@ -98,7 +98,7 @@ /obj/screen/fullscreen/flash icon = 'icons/mob/screen1.dmi' screen_loc = "WEST,SOUTH to EAST,NORTH" - icon_state = "flash" + icon_state = "flash_static" /obj/screen/fullscreen/flash/noise icon_state = "noise" diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index 8b32d1447e..fef0301c81 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -316,8 +316,6 @@ datum/hud/New(mob/owner) mymob.instantiate_hud(src) else if(isalien(mymob)) larva_hud() - else if(isslime(mymob)) - slime_hud() else if(isAI(mymob)) ai_hud() else if(isobserver(mymob)) diff --git a/code/_onclick/hud/other_mobs.dm b/code/_onclick/hud/other_mobs.dm index f1b9165a26..6a2a2a0f45 100644 --- a/code/_onclick/hud/other_mobs.dm +++ b/code/_onclick/hud/other_mobs.dm @@ -23,7 +23,7 @@ mymob.client.screen += list(blobpwrdisplay, blobhealthdisplay) mymob.client.screen += mymob.client.void - +/* /datum/hud/proc/slime_hud(ui_style = 'icons/mob/screen1_Midnight.dmi') src.adding = list() @@ -92,23 +92,20 @@ mymob.client.screen += mymob.client.void return - - -/mob/living/simple_animal/construct/instantiate_hud(var/datum/hud/HUD) - ..(HUD) +*/ // HUD.construct_hud() //Archaic. /* /datum/hud/proc/construct_hud() var/constructtype - if(istype(mymob,/mob/living/simple_animal/construct/armoured) || istype(mymob,/mob/living/simple_animal/construct/behemoth)) + if(istype(mymob,/mob/living/simple_mob/construct/armoured) || istype(mymob,/mob/living/simple_mob/construct/behemoth)) constructtype = "juggernaut" - else if(istype(mymob,/mob/living/simple_animal/construct/builder)) + else if(istype(mymob,/mob/living/simple_mob/construct/builder)) constructtype = "artificer" - else if(istype(mymob,/mob/living/simple_animal/construct/wraith)) + else if(istype(mymob,/mob/living/simple_mob/construct/wraith)) constructtype = "wraith" - else if(istype(mymob,/mob/living/simple_animal/construct/harvester)) + else if(istype(mymob,/mob/living/simple_mob/construct/harvester)) constructtype = "harvester" if(constructtype) diff --git a/code/_onclick/hud/screen_objects_vr.dm b/code/_onclick/hud/screen_objects_vr.dm index 6dcab650a4..ea6b72cd10 100644 --- a/code/_onclick/hud/screen_objects_vr.dm +++ b/code/_onclick/hud/screen_objects_vr.dm @@ -1,15 +1,15 @@ -/obj/screen/proc/Click_vr(location, control, params) +/obj/screen/proc/Click_vr(location, control, params) //VORESTATION AI TEMPORARY REMOVAL if(!usr) return 1 switch(name) //Shadekin if("darkness") - var/mob/living/simple_animal/shadekin/sk = usr + var/mob/living/simple_mob/shadekin/sk = usr var/turf/T = get_turf(sk) var/darkness = round(1 - T.get_lumcount(),0.1) to_chat(usr,"Darkness: [darkness]") if("energy") - var/mob/living/simple_animal/shadekin/sk = usr + var/mob/living/simple_mob/shadekin/sk = usr to_chat(usr,"Energy: [sk.energy] ([sk.dark_gains])") diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index d1a61ec8f4..a1f2335a9d 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -60,7 +60,7 @@ avoid code duplication. This includes items that may sometimes act as a standard // Same as above but actually does useful things. // W is the item being used in the attack, if any. modifier is if the attack should be longer or shorter than usual, for whatever reason. /mob/living/get_attack_speed(var/obj/item/W) - var/speed = DEFAULT_ATTACK_COOLDOWN + var/speed = base_attack_cooldown if(W && istype(W)) speed = W.attackspeed for(var/datum/modifier/M in modifiers) diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index 729330ddaa..e367769b07 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -68,58 +68,3 @@ */ /mob/new_player/ClickOn() return - -/* - Animals -*/ -/mob/living/simple_animal/UnarmedAttack(var/atom/A, var/proximity) - if(!(. = ..())) - return - - setClickCooldown(get_attack_speed()) - - if(has_hands && istype(A,/obj) && a_intent != I_HURT) - var/obj/O = A - return O.attack_hand(src) - - switch(a_intent) - if(I_HELP) - if(isliving(A)) - custom_emote(1,"[pick(friendly)] [A]!") - - if(I_HURT) - if(prob(spattack_prob)) - if(spattack_min_range <= 1) - SpecialAtkTarget() - - - else if(melee_damage_upper == 0 && istype(A,/mob/living)) - custom_emote(1,"[pick(friendly)] [A]!") - - - else - DoPunch(A) - - if(I_GRAB) - if(has_hands) - A.attack_hand(src) - - if(I_DISARM) - if(has_hands) - A.attack_hand(src) - -/mob/living/simple_animal/RangedAttack(var/atom/A) - setClickCooldown(get_attack_speed()) - var/distance = get_dist(src, A) - - if(prob(spattack_prob) && (distance >= spattack_min_range) && (distance <= spattack_max_range)) - target_mob = A - SpecialAtkTarget() - target_mob = null - return - - if(ranged && distance <= shoot_range) - target_mob = A - ShootTarget(A) - target_mob = null - diff --git a/code/controllers/ProcessScheduler/core/process.dm b/code/controllers/ProcessScheduler/core/process.dm index 2965a52abe..6bbcb62a54 100644 --- a/code/controllers/ProcessScheduler/core/process.dm +++ b/code/controllers/ProcessScheduler/core/process.dm @@ -155,7 +155,7 @@ /datum/controller/process/proc/setup() -/datum/controller/process/proc/process() +/datum/controller/process/process() started() doWork() finished() diff --git a/code/controllers/ProcessScheduler/core/processScheduler.dm b/code/controllers/ProcessScheduler/core/processScheduler.dm index 86dcdac287..c5b658de15 100644 --- a/code/controllers/ProcessScheduler/core/processScheduler.dm +++ b/code/controllers/ProcessScheduler/core/processScheduler.dm @@ -70,7 +70,7 @@ var/global/datum/controller/processScheduler/processScheduler spawn(0) process() -/datum/controller/processScheduler/proc/process() +/datum/controller/processScheduler/process() while(isRunning) checkRunningProcesses() queueProcesses() diff --git a/code/controllers/Processes/air.dm b/code/controllers/Processes/air.dm deleted file mode 100644 index bdb9fe7fbd..0000000000 --- a/code/controllers/Processes/air.dm +++ /dev/null @@ -1,23 +0,0 @@ -/datum/controller/process/air/setup() - name = "air" - schedule_interval = 20 // every 2 seconds - start_delay = 4 - - if(!air_master) - air_master = new - air_master.Setup() - -/datum/controller/process/air/doWork() - if(!air_processing_killed) - if(!air_master.Tick()) //Runtimed. - air_master.failed_ticks++ - - if(air_master.failed_ticks > 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/alarm.dm b/code/controllers/Processes/alarm.dm index 47f311efea..3590149811 100644 --- a/code/controllers/Processes/alarm.dm +++ b/code/controllers/Processes/alarm.dm @@ -11,7 +11,7 @@ var/datum/controller/process/alarm/alarm_manager /datum/controller/process/alarm - var/list/datum/alarm/all_handlers + var/list/datum/alarm/all_handlers = list() /datum/controller/process/alarm/setup() name = "alarm" diff --git a/code/controllers/Processes/chemistry.dm b/code/controllers/Processes/chemistry.dm deleted file mode 100644 index 084de83e28..0000000000 --- a/code/controllers/Processes/chemistry.dm +++ /dev/null @@ -1,33 +0,0 @@ -var/datum/controller/process/chemistry/chemistryProcess - -/datum/controller/process/chemistry - var/list/active_holders - var/list/chemical_reactions - var/list/chemical_reagents - -/datum/controller/process/chemistry/setup() - name = "chemistry" - schedule_interval = 20 // every 2 seconds - chemistryProcess = src - active_holders = list() - chemical_reactions = chemical_reactions_list - chemical_reagents = chemical_reagents_list - -/datum/controller/process/chemistry/statProcess() - ..() - stat(null, "[active_holders.len] reagent holder\s") - -/datum/controller/process/chemistry/doWork() - for(last_object in active_holders) - var/datum/reagents/holder = last_object - if(!holder.process_reactions()) - active_holders -= holder - SCHECK - -/datum/controller/process/chemistry/proc/mark_for_update(var/datum/reagents/holder) - if(holder in active_holders) - return - - //Process once, right away. If we still need to continue then add to the active_holders list and continue later - if(holder.process_reactions()) - active_holders += holder diff --git a/code/controllers/Processes/event.dm b/code/controllers/Processes/event.dm deleted file mode 100644 index 72bc01613d..0000000000 --- a/code/controllers/Processes/event.dm +++ /dev/null @@ -1,6 +0,0 @@ -/datum/controller/process/event/setup() - name = "event controller" - 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/nanoui.dm b/code/controllers/Processes/nanoui.dm deleted file mode 100644 index 0f720600bc..0000000000 --- a/code/controllers/Processes/nanoui.dm +++ /dev/null @@ -1,19 +0,0 @@ -/datum/controller/process/nanoui/setup() - name = "nanoui" - schedule_interval = 20 // every 2 seconds - -/datum/controller/process/nanoui/statProcess() - ..() - stat(null, "[GLOB.nanomanager.processing_uis.len] UIs") - -/datum/controller/process/nanoui/doWork() - for(last_object in GLOB.nanomanager.processing_uis) - var/datum/nanoui/NUI = last_object - if(istype(NUI) && !QDELETED(NUI)) - try - NUI.process() - catch(var/exception/e) - catchException(e, NUI) - else - catchBadType(NUI) - GLOB.nanomanager.processing_uis -= NUI \ No newline at end of file diff --git a/code/controllers/Processes/obj.dm b/code/controllers/Processes/obj.dm deleted file mode 100644 index 6032cbb541..0000000000 --- a/code/controllers/Processes/obj.dm +++ /dev/null @@ -1,26 +0,0 @@ -/datum/controller/process/obj/setup() - name = "obj" - schedule_interval = 20 // every 2 seconds - start_delay = 8 - -/datum/controller/process/obj/started() - ..() - if(!processing_objects) - processing_objects = list() - -/datum/controller/process/obj/doWork() - for(last_object in processing_objects) - var/datum/O = last_object - if(!QDELETED(O)) - try - O:process() - catch(var/exception/e) - catchException(e, O) - SCHECK - else - catchBadType(O) - processing_objects -= O - -/datum/controller/process/obj/statProcess() - ..() - stat(null, "[processing_objects.len] objects") \ No newline at end of file diff --git a/code/controllers/Processes/scheduler.dm b/code/controllers/Processes/scheduler.dm index c68ef116b6..ac5e4696ab 100644 --- a/code/controllers/Processes/scheduler.dm +++ b/code/controllers/Processes/scheduler.dm @@ -40,7 +40,7 @@ // We are being killed. Least we can do is deregister all those events we registered /datum/controller/process/scheduler/onKill() for(var/st in scheduled_tasks) - destroyed_event.unregister(st, src) + GLOB.destroyed_event.unregister(st, src) /datum/controller/process/scheduler/statProcess() ..() @@ -148,7 +148,7 @@ /datum/scheduled_task/source/New(var/trigger_time, var/datum/source, var/procedure, var/list/arguments, var/proc/task_after_process, var/list/task_after_process_args) src.source = source - destroyed_event.register(src.source, src, /datum/scheduled_task/source/proc/source_destroyed) + GLOB.destroyed_event.register(src.source, src, /datum/scheduled_task/source/proc/source_destroyed) ..(trigger_time, procedure, arguments, task_after_process, task_after_process_args) /datum/scheduled_task/source/Destroy() diff --git a/code/controllers/Processes/sun.dm b/code/controllers/Processes/sun.dm deleted file mode 100644 index f09806cef5..0000000000 --- a/code/controllers/Processes/sun.dm +++ /dev/null @@ -1,7 +0,0 @@ -/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 index 2234b7a9ac..781e285371 100644 --- a/code/controllers/Processes/supply.dm +++ b/code/controllers/Processes/supply.dm @@ -65,7 +65,7 @@ var/datum/controller/supply/supply_controller = new() // Supply shuttle ticker - handles supply point regeneration // This is called by the process scheduler every thirty seconds -/datum/controller/supply/proc/process() +/datum/controller/supply/process() points += points_per_process //To stop things being sent to CentCom which should not be sent to centcomm. Recursively checks for these types. diff --git a/code/controllers/Processes/turf.dm b/code/controllers/Processes/turf.dm deleted file mode 100644 index bfced8f93b..0000000000 --- a/code/controllers/Processes/turf.dm +++ /dev/null @@ -1,16 +0,0 @@ -var/global/list/turf/processing_turfs = list() - -/datum/controller/process/turf/setup() - name = "turf" - schedule_interval = 20 // every 2 seconds - -/datum/controller/process/turf/doWork() - for(last_object in processing_turfs) - var/turf/T = last_object - if(T.process() == PROCESS_KILL) - processing_turfs.Remove(T) - SCHECK - -/datum/controller/process/turf/statProcess() - ..() - stat(null, "[processing_turfs.len] turf\s") \ No newline at end of file diff --git a/code/controllers/autotransfer.dm b/code/controllers/autotransfer.dm index 34b535c2f6..b3d82ea614 100644 --- a/code/controllers/autotransfer.dm +++ b/code/controllers/autotransfer.dm @@ -9,12 +9,12 @@ datum/controller/transfer_controller/New() timerbuffer = config.vote_autotransfer_initial shift_hard_end = config.vote_autotransfer_initial + (config.vote_autotransfer_interval * 1) //VOREStation Edit //Change this "1" to how many extend votes you want there to be. shift_last_vote = shift_hard_end - config.vote_autotransfer_interval //VOREStation Edit - processing_objects += src + START_PROCESSING(SSobj, src) datum/controller/transfer_controller/Destroy() - processing_objects -= src + STOP_PROCESSING(SSobj, src) -datum/controller/transfer_controller/proc/process() +datum/controller/transfer_controller/process() currenttick = currenttick + 1 //VOREStation Edit START if (round_duration_in_ticks >= shift_last_vote - 2 MINUTES) diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 1cdc7e2717..c47ec37abf 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -220,7 +220,7 @@ var/list/gamemode_cache = list() var/aggressive_changelog = 0 - var/list/language_prefixes = list(",","#","-")//Default language prefixes + var/list/language_prefixes = list(",","#")//Default language prefixes var/show_human_death_message = 1 @@ -228,6 +228,8 @@ var/list/gamemode_cache = list() var/radiation_resistance_multiplier = 8.5 //VOREstation edit var/radiation_lower_limit = 0.35 //If the radiation level for a turf would be below this, ignore it. + var/random_submap_orientation = FALSE // If true, submaps loaded automatically can be rotated. + /datum/configuration/New() var/list/L = typesof(/datum/game_mode) - /datum/game_mode for (var/T in L) @@ -748,6 +750,9 @@ var/list/gamemode_cache = list() if ("paranoia_logging") config.paranoia_logging = 1 + if("random_submap_orientation") + config.random_submap_orientation = 1 + else log_misc("Unknown setting in configuration: '[name]'") diff --git a/code/controllers/emergency_shuttle_controller.dm b/code/controllers/emergency_shuttle_controller.dm index 05468bee76..bcc7187a3c 100644 --- a/code/controllers/emergency_shuttle_controller.dm +++ b/code/controllers/emergency_shuttle_controller.dm @@ -26,7 +26,7 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle escape_pods = list() ..() -/datum/emergency_shuttle_controller/proc/process() +/datum/emergency_shuttle_controller/process() if (wait_for_launch) if (evac && auto_recall && world.time >= auto_recall_time) recall() diff --git a/code/controllers/globals.dm b/code/controllers/globals.dm index fa7b917194..56a9244347 100644 --- a/code/controllers/globals.dm +++ b/code/controllers/globals.dm @@ -38,8 +38,10 @@ GLOBAL_REAL(GLOB, /datum/controller/global_vars) stat("Globals:", statclick.update("Edit")) -/datum/controller/global_vars/VV_hidden() - return ..() + gvars_datum_protected_varlist +/datum/controller/global_vars/vv_edit_var(var_name, var_value) + if(gvars_datum_protected_varlist[var_name]) + return FALSE + return ..() /datum/controller/global_vars/Initialize(var/exclude_these) gvars_datum_init_order = list() diff --git a/code/controllers/master.dm b/code/controllers/master.dm index 050251fb0d..0b292e45c4 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -13,14 +13,6 @@ GLOBAL_REAL(Master, /datum/controller/master) = new //THIS IS THE INIT ORDER //Master -> SSPreInit -> GLOB -> world -> config -> SSInit -> Failsafe //GOT IT MEMORIZED? -GLOBAL_VAR_INIT(MC_restart_clear, 0) -GLOBAL_VAR_INIT(MC_restart_timeout, 0) -GLOBAL_VAR_INIT(MC_restart_count, 0) - -//current tick limit, assigned by the queue controller before running a subsystem. -//used by check_tick as well so that the procs subsystems call can obey that SS's tick limits -GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING) - /datum/controller/master name = "Master" @@ -62,6 +54,10 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING) var/static/restart_timeout = 0 var/static/restart_count = 0 + //current tick limit, assigned by the queue controller before running a subsystem. + //used by check_tick as well so that the procs subsystems call can obey that SS's tick limits + var/static/current_ticklimit + /datum/controller/master/New() // Highlander-style: there can only be one! Kill off the old and replace it with the new. var/list/_subsystems = list() @@ -98,14 +94,14 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING) // -1 if we encountered a runtime trying to recreate it /proc/Recreate_MC() . = -1 //so if we runtime, things know we failed - if (world.time < GLOB.MC_restart_timeout) + if (world.time < Master.restart_timeout) return 0 - if (world.time < GLOB.MC_restart_clear) - GLOB.MC_restart_count *= 0.5 + if (world.time < Master.restart_clear) + Master.restart_count *= 0.5 - var/delay = 50 * ++GLOB.MC_restart_count - GLOB.MC_restart_timeout = world.time + delay - GLOB.MC_restart_clear = world.time + (delay * 2) + var/delay = 50 * ++Master.restart_count + Master.restart_timeout = world.time + delay + Master.restart_clear = world.time + (delay * 2) Master.processing = FALSE //stop ticking this one try new/datum/controller/master() @@ -176,13 +172,13 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING) var/start_timeofday = REALTIMEOFDAY // Initialize subsystems. - GLOB.CURRENT_TICKLIMIT = config.tick_limit_mc_init + current_ticklimit = config.tick_limit_mc_init for (var/datum/controller/subsystem/SS in subsystems) if (SS.flags & SS_NO_INIT) continue SS.Initialize(REALTIMEOFDAY) CHECK_TICK - GLOB.CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING + current_ticklimit = TICK_LIMIT_RUNNING var/time = (REALTIMEOFDAY - start_timeofday) / 10 var/msg = "Initializations complete within [time] second[time == 1 ? "" : "s"]!" @@ -291,7 +287,7 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING) tickdrift = max(0, MC_AVERAGE_FAST(tickdrift, (((REALTIMEOFDAY - init_timeofday) - (world.time - init_time)) / world.tick_lag))) var/starting_tick_usage = TICK_USAGE if (processing <= 0) - GLOB.CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING + current_ticklimit = TICK_LIMIT_RUNNING sleep(10) continue @@ -300,7 +296,7 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING) // (because sleeps are processed in the order received, longer sleeps are more likely to run first) if (starting_tick_usage > TICK_LIMIT_MC) //if there isn't enough time to bother doing anything this tick, sleep a bit. sleep_delta *= 2 - GLOB.CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING * 0.5 + current_ticklimit = TICK_LIMIT_RUNNING * 0.5 sleep(world.tick_lag * (processing * sleep_delta)) continue @@ -346,7 +342,7 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING) if (!error_level) iteration++ error_level++ - GLOB.CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING + current_ticklimit = TICK_LIMIT_RUNNING sleep(10) continue @@ -358,7 +354,7 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING) if (!error_level) iteration++ error_level++ - GLOB.CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING + current_ticklimit = TICK_LIMIT_RUNNING sleep(10) continue error_level-- @@ -369,9 +365,9 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING) iteration++ last_run = world.time src.sleep_delta = MC_AVERAGE_FAST(src.sleep_delta, sleep_delta) - GLOB.CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING + current_ticklimit = TICK_LIMIT_RUNNING if (processing * sleep_delta <= world.tick_lag) - GLOB.CURRENT_TICKLIMIT -= (TICK_LIMIT_RUNNING * 0.25) //reserve the tail 1/4 of the next tick for the mc if we plan on running next tick + current_ticklimit -= (TICK_LIMIT_RUNNING * 0.25) //reserve the tail 1/4 of the next tick for the mc if we plan on running next tick sleep(world.tick_lag * (processing * sleep_delta)) @@ -463,7 +459,7 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING) // Reduce tick allocation for subsystems that overran on their last tick. tick_precentage = max(tick_precentage*0.5, tick_precentage-queue_node.tick_overrun) - GLOB.CURRENT_TICKLIMIT = round(TICK_USAGE + tick_precentage) + current_ticklimit = round(TICK_USAGE + tick_precentage) if (!(queue_node_flags & SS_TICKER)) ran_non_ticker = TRUE diff --git a/code/controllers/subsystem.dm b/code/controllers/subsystem.dm index dcb52a8cb3..8c0b6fa5de 100644 --- a/code/controllers/subsystem.dm +++ b/code/controllers/subsystem.dm @@ -6,6 +6,7 @@ var/priority = FIRE_PRIORITY_DEFAULT //When mutiple subsystems need to run in the same tick, higher priority subsystems will run first and be given a higher share of the tick before MC_TICK_CHECK triggers a sleep var/flags = 0 //see MC.dm in __DEFINES Most flags must be set on world start to take full effect. (You can also restart the mc to force them to process again) + var/subsystem_initialized = FALSE //set to TRUE after it has been initialized, will obviously never be set if the subsystem doesn't initialize var/runlevels = RUNLEVELS_DEFAULT //points of the game at which the SS can fire //set to 0 to prevent fire() calls, mostly for admin use or subsystems that may be resumed later @@ -154,6 +155,7 @@ //used to initialize the subsystem AFTER the map has loaded /datum/controller/subsystem/Initialize(start_timeofday) + subsystem_initialized = TRUE var/time = (REALTIMEOFDAY - start_timeofday) / 10 var/msg = "Initialized [name] subsystem within [time] second[time == 1 ? "" : "s"]!" to_chat(world, "[msg]") diff --git a/code/controllers/subsystems/ai.dm b/code/controllers/subsystems/ai.dm new file mode 100644 index 0000000000..8977818755 --- /dev/null +++ b/code/controllers/subsystems/ai.dm @@ -0,0 +1,36 @@ +SUBSYSTEM_DEF(ai) + name = "AI" + init_order = INIT_ORDER_AI + priority = FIRE_PRIORITY_AI + wait = 5 // This gets run twice a second, however this is technically two loops in one, with the second loop being run every four iterations. + flags = SS_NO_INIT|SS_TICKER + runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME + + var/list/processing = list() + var/list/currentrun = list() + +/datum/controller/subsystem/ai/stat_entry(msg_prefix) + var/list/msg = list(msg_prefix) + msg += "P:[processing.len]" + ..(msg.Join()) + +/datum/controller/subsystem/ai/fire(resumed = 0) + if (!resumed) + src.currentrun = processing.Copy() + + //cache for sanic speed (lists are references anyways) + var/list/currentrun = src.currentrun + + while(currentrun.len) + // var/mob/living/L = currentrun[currentrun.len] + var/datum/ai_holder/A = currentrun[currentrun.len] + --currentrun.len + if(!A || QDELETED(A)) // Doesn't exist or won't exist soon. + continue + if(times_fired % 4 == 0 && A.holder.stat != DEAD) + A.handle_strategicals() + if(A.holder.stat != DEAD) // The /TG/ version checks stat twice, presumably in-case processing somehow got the mob killed in that instant. + A.handle_tactics() + + if(MC_TICK_CHECK) + return diff --git a/code/controllers/subsystems/atoms.dm b/code/controllers/subsystems/atoms.dm index 7dae153d66..60fccf6dd3 100644 --- a/code/controllers/subsystems/atoms.dm +++ b/code/controllers/subsystems/atoms.dm @@ -77,7 +77,7 @@ SUBSYSTEM_DEF(atoms) var/start_tick = world.time - var/result = A.initialize(arglist(arguments)) + var/result = A.Initialize(arglist(arguments)) if(start_tick != world.time) BadInitializeCalls[the_type] |= BAD_INIT_SLEPT diff --git a/code/controllers/subsystems/creation.dm b/code/controllers/subsystems/creation.dm deleted file mode 100644 index d6f4b3c9c5..0000000000 --- a/code/controllers/subsystems/creation.dm +++ /dev/null @@ -1,29 +0,0 @@ -// -// Creation subsystem, which is responsible for initializing newly created objects. -// -SUBSYSTEM_DEF(creation) - name = "Creation" - priority = 14 - wait = 5 -// flags = SS_POST_FIRE_TIMING|SS_BACKGROUND|SS_NO_INIT - flags = SS_NO_FIRE|SS_NO_INIT - runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY - - var/list/atoms_needing_initialize = list() - - var/map_loading = FALSE - -/datum/controller/subsystem/creation/StartLoadingMap(var/quiet) - map_loading = TRUE - -/datum/controller/subsystem/creation/StopLoadingMap(var/quiet) - map_loading = FALSE - -/datum/controller/subsystem/creation/proc/initialize_late_atoms() - admin_notice("Initializing atoms in submap.", R_DEBUG) - var/total_atoms = atoms_needing_initialize.len - for(var/atom/movable/A in atoms_needing_initialize) - if(!QDELETED(A)) - A.initialize() - atoms_needing_initialize -= A - admin_notice("Initalized [total_atoms] atoms in submap.", R_DEBUG) \ No newline at end of file diff --git a/code/controllers/subsystems/events.dm b/code/controllers/subsystems/events.dm new file mode 100644 index 0000000000..24ce81fab4 --- /dev/null +++ b/code/controllers/subsystems/events.dm @@ -0,0 +1,72 @@ +SUBSYSTEM_DEF(events) + name = "Events" + wait = 20 + + var/list/datum/event/active_events = list() + var/list/datum/event/finished_events = list() + + var/list/datum/event/allEvents + var/list/datum/event_container/event_containers + + var/datum/event_meta/new_event = new + +/datum/controller/subsystem/events/Initialize() + event_containers = list( + EVENT_LEVEL_MUNDANE = new/datum/event_container/mundane, + EVENT_LEVEL_MODERATE = new/datum/event_container/moderate, + EVENT_LEVEL_MAJOR = new/datum/event_container/major + ) + allEvents = typesof(/datum/event) - /datum/event + return ..() + +/datum/controller/subsystem/events/fire(resumed) + for(var/datum/event/E in active_events) + E.process() + + for(var/i = EVENT_LEVEL_MUNDANE to EVENT_LEVEL_MAJOR) + var/list/datum/event_container/EC = event_containers[i] + EC.process() + +/datum/controller/subsystem/events/Recover() + if(SSevents.active_events) + active_events |= SSevents.active_events + if(SSevents.finished_events) + finished_events |= SSevents.finished_events + +/datum/controller/subsystem/events/proc/event_complete(var/datum/event/E) + if(!E.event_meta || !E.severity) // datum/event is used here and there for random reasons, maintaining "backwards compatibility" + log_debug("Event of '[E.type]' with missing meta-data has completed.") + return + + finished_events += E + + // Add the event back to the list of available events + var/datum/event_container/EC = event_containers[E.severity] + var/datum/event_meta/EM = E.event_meta + if(EM.add_to_queue) + EC.available_events += EM + + log_debug("Event '[EM.name]' has completed at [worldtime2stationtime(world.time)].") + +/datum/controller/subsystem/events/proc/delay_events(var/severity, var/delay) + var/list/datum/event_container/EC = event_containers[severity] + EC.next_event_time += delay + +/datum/controller/subsystem/events/proc/RoundEnd() + if(!report_at_round_end) + return + + to_chat(world, "


Random Events This Round:") + for(var/datum/event/E in active_events|finished_events) + var/datum/event_meta/EM = E.event_meta + if(EM.name == "Nothing") + continue + var/message = "'[EM.name]' began at [worldtime2stationtime(E.startedAt)] " + if(E.isRunning) + message += "and is still running." + else + if(E.endedAt - E.startedAt > MinutesToTicks(5)) // Only mention end time if the entire duration was more than 5 minutes + message += "and ended at [worldtime2stationtime(E.endedAt)]." + else + message += "and ran to completion." + to_chat(world, message) diff --git a/code/controllers/Processes/inactivity.dm b/code/controllers/subsystems/inactivity.dm similarity index 81% rename from code/controllers/Processes/inactivity.dm rename to code/controllers/subsystems/inactivity.dm index 9435a18bf0..298b2ebdd8 100644 --- a/code/controllers/Processes/inactivity.dm +++ b/code/controllers/subsystems/inactivity.dm @@ -1,11 +1,12 @@ -/datum/controller/process/inactivity/setup() - name = "inactivity" - schedule_interval = 600 // Once every minute (approx.) +SUBSYSTEM_DEF(inactivity) + name = "AFK Kick" + wait = 600 + flags = SS_BACKGROUND | SS_NO_TICK_CHECK -/datum/controller/process/inactivity/doWork() +/datum/controller/subsystem/inactivity/fire() if(config.kick_inactive) - for(last_object in clients) - var/client/C = last_object + for(var/i in GLOB.clients) + var/client/C = i if(C.is_afk(config.kick_inactive MINUTES) && !C.holder) // VOREStation Edit - Allow admins to idle to_chat(C,"You have been inactive for more than [config.kick_inactive] minute\s and have been disconnected.") var/information @@ -33,4 +34,3 @@ log_and_message_admins("being kicked for AFK[information][adminlinks]", C.mob) qdel(C) - SCHECK diff --git a/code/controllers/subsystems/machines.dm b/code/controllers/subsystems/machines.dm index 4cba70a981..4525175393 100644 --- a/code/controllers/subsystems/machines.dm +++ b/code/controllers/subsystems/machines.dm @@ -109,7 +109,7 @@ SUBSYSTEM_DEF(machines) else global.pipe_networks.Remove(PN) if(!QDELETED(PN)) - PN.is_processing = null + DISABLE_BITFIELD(PN.datum_flags, DF_ISPROCESSING) if(MC_TICK_CHECK) return @@ -127,7 +127,7 @@ SUBSYSTEM_DEF(machines) else global.processing_machines.Remove(M) if(!QDELETED(M)) - M.is_processing = null + DISABLE_BITFIELD(M.datum_flags, DF_ISPROCESSING) if(MC_TICK_CHECK) return @@ -144,7 +144,7 @@ SUBSYSTEM_DEF(machines) else global.powernets.Remove(PN) if(!QDELETED(PN)) - PN.is_processing = null + DISABLE_BITFIELD(PN.datum_flags, DF_ISPROCESSING) if(MC_TICK_CHECK) return @@ -160,7 +160,7 @@ SUBSYSTEM_DEF(machines) current_run.len-- if(!I.pwr_drain(wait)) // 0 = Process Kill, remove from processing list. global.processing_power_items.Remove(I) - I.is_processing = null + DISABLE_BITFIELD(I.datum_flags, DF_ISPROCESSING) if(MC_TICK_CHECK) return diff --git a/code/controllers/subsystems/mapping.dm b/code/controllers/subsystems/mapping.dm new file mode 100644 index 0000000000..cc69931426 --- /dev/null +++ b/code/controllers/subsystems/mapping.dm @@ -0,0 +1,30 @@ +// Handles map-related tasks, mostly here to ensure it does so after the MC initializes. +SUBSYSTEM_DEF(mapping) + name = "Mapping" + init_order = INIT_ORDER_MAPPING + flags = SS_NO_FIRE + + var/list/map_templates = list() + var/dmm_suite/maploader = null + +/datum/controller/subsystem/mapping/Initialize(timeofday) + if(subsystem_initialized) + return + world.max_z_changed() // This is to set up the player z-level list, maxz hasn't actually changed (probably) + maploader = new() + load_map_templates() + + if(config.generate_map) + // Map-gen is still very specific to the map, however putting it here should ensure it loads in the correct order. + if(using_map.perform_map_generation()) + using_map.refresh_mining_turfs() + + +/datum/controller/subsystem/mapping/proc/load_map_templates() + for(var/T in subtypesof(/datum/map_template)) + var/datum/map_template/template = T + if(!(initial(template.mappath))) // If it's missing the actual path its probably a base type or being used for inheritence. + continue + template = new T() + map_templates[template.name] = template + return TRUE diff --git a/code/controllers/subsystems/mapping_vr.dm b/code/controllers/subsystems/mapping_vr.dm index 0a94cc4634..8c18889f71 100644 --- a/code/controllers/subsystems/mapping_vr.dm +++ b/code/controllers/subsystems/mapping_vr.dm @@ -7,8 +7,9 @@ SUBSYSTEM_DEF(mapping) init_order = INIT_ORDER_MAPPING flags = SS_NO_FIRE + var/list/map_templates = list() + var/dmm_suite/maploader = null var/obj/effect/landmark/engine_loader/engine_loader - var/list/shelter_templates = list() /datum/controller/subsystem/mapping/Recover() @@ -16,6 +17,17 @@ SUBSYSTEM_DEF(mapping) shelter_templates = SSmapping.shelter_templates /datum/controller/subsystem/mapping/Initialize(timeofday) + if(subsystem_initialized) + return + world.max_z_changed() // This is to set up the player z-level list, maxz hasn't actually changed (probably) + maploader = new() + load_map_templates() + + if(config.generate_map) + // Map-gen is still very specific to the map, however putting it here should ensure it loads in the correct order. + if(using_map.perform_map_generation()) + using_map.refresh_mining_turfs() + loadEngine() preloadShelterTemplates() // Mining generation probably should be here too @@ -24,6 +36,15 @@ SUBSYSTEM_DEF(mapping) loadLateMaps() ..() +/datum/controller/subsystem/mapping/proc/load_map_templates() + for(var/T in subtypesof(/datum/map_template)) + var/datum/map_template/template = T + if(!(initial(template.mappath))) // If it's missing the actual path its probably a base type or being used for inheritence. + continue + template = new T() + map_templates[template.name] = template + return TRUE + /datum/controller/subsystem/mapping/proc/loadEngine() if(!engine_loader) return // Seems this map doesn't need an engine loaded. diff --git a/code/controllers/subsystems/nanoui.dm b/code/controllers/subsystems/nanoui.dm new file mode 100644 index 0000000000..c31449addc --- /dev/null +++ b/code/controllers/subsystems/nanoui.dm @@ -0,0 +1,42 @@ +SUBSYSTEM_DEF(nanoui) + name = "NanoUI" + wait = 20 + // a list of current open /nanoui UIs, grouped by src_object and ui_key + var/list/open_uis = list() + // 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() + +/datum/controller/subsystem/nanoui/Initialize() + var/list/nano_asset_dirs = list(\ + "nano/css/",\ + "nano/images/",\ + "nano/js/",\ + "nano/templates/"\ + ) + + var/list/filenames = null + for (var/path in nano_asset_dirs) + 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 + 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 ..() + +/datum/controller/subsystem/nanoui/Recover() + if(SSnanoui.open_uis) + open_uis |= SSnanoui.open_uis + if(SSnanoui.processing_uis) + processing_uis |= SSnanoui.processing_uis + if(SSnanoui.asset_files) + asset_files |= SSnanoui.asset_files + +/datum/controller/subsystem/nanoui/stat_entry() + return ..("[processing_uis.len] UIs") + +/datum/controller/subsystem/nanoui/fire(resumed) + for(var/thing in processing_uis) + var/datum/nanoui/UI = thing + UI.process() diff --git a/code/controllers/subsystems/overlays.dm b/code/controllers/subsystems/overlays.dm index 5c8b3531c9..60b08c71d2 100644 --- a/code/controllers/subsystems/overlays.dm +++ b/code/controllers/subsystems/overlays.dm @@ -168,7 +168,7 @@ var/global/image/appearance_bro = new() // Temporarily super-global because of B * Adds specific overlay(s) to the atom. * It is designed so any of the types allowed to be added to /atom/overlays can be added here too. More details below. * - * @param overlays The overlay(s) to add. These may be + * @param overlays The overlay(s) to add. These may be * - A string: In which case it is treated as an icon_state of the atom's icon. * - An icon: It is treated as an icon. * - An atom: Its own overlays are compiled and then it's appearance is added. (Meaning its current apperance is frozen). @@ -205,7 +205,7 @@ var/global/image/appearance_bro = new() // Temporarily super-global because of B /** * Copy the overlays from another atom, either replacing all of ours or appending to our existing overlays. * Note: This copies only the normal overlays, not the "priority" overlays. - * + * * @param other The atom to copy overlays from. * @param cut_old If true, all of our overlays will be *replaced* by the other's. If other is null, that means cutting all ours. */ diff --git a/code/controllers/subsystems/processing/chemistry.dm b/code/controllers/subsystems/processing/chemistry.dm new file mode 100644 index 0000000000..67b74d3ab6 --- /dev/null +++ b/code/controllers/subsystems/processing/chemistry.dm @@ -0,0 +1,43 @@ +PROCESSING_SUBSYSTEM_DEF(chemistry) + name = "Chemistry" + wait = 20 + flags = SS_BACKGROUND|SS_POST_FIRE_TIMING + init_order = INIT_ORDER_CHEMISTRY + var/list/chemical_reactions = list() + var/list/chemical_reagents = list() + +/datum/controller/subsystem/processing/chemistry/Recover() + chemical_reactions = SSchemistry.chemical_reactions + chemical_reagents = SSchemistry.chemical_reagents + +/datum/controller/subsystem/processing/chemistry/Initialize() + initialize_chemical_reactions() + initialize_chemical_reagents() + +//Chemical Reactions - Initialises all /datum/chemical_reaction into a list +// It is filtered into multiple lists within a list. +// For example: +// chemical_reaction_list["phoron"] is a list of all reactions relating to phoron +// Note that entries in the list are NOT duplicated. So if a reaction pertains to +// more than one chemical it will still only appear in only one of the sublists. +/datum/controller/subsystem/processing/chemistry/proc/initialize_chemical_reactions() + var/paths = typesof(/datum/chemical_reaction) - /datum/chemical_reaction + SSchemistry.chemical_reactions = list() + + for(var/path in paths) + var/datum/chemical_reaction/D = new path() + if(D.required_reagents && D.required_reagents.len) + var/reagent_id = D.required_reagents[1] + if(!chemical_reactions[reagent_id]) + chemical_reactions[reagent_id] = list() + chemical_reactions[reagent_id] += D + +//Chemical Reagents - Initialises all /datum/reagent into a list indexed by reagent id +/datum/controller/subsystem/processing/chemistry/proc/initialize_chemical_reagents() + var/paths = typesof(/datum/reagent) - /datum/reagent + chemical_reagents = list() + for(var/path in paths) + var/datum/reagent/D = new path() + if(!D.name) + continue + chemical_reagents[D.id] = D diff --git a/code/controllers/subsystems/processing/fastprocess.dm b/code/controllers/subsystems/processing/fastprocess.dm new file mode 100644 index 0000000000..9622e02146 --- /dev/null +++ b/code/controllers/subsystems/processing/fastprocess.dm @@ -0,0 +1,6 @@ +//Fires five times every second. + +PROCESSING_SUBSYSTEM_DEF(fastprocess) + name = "Fast Processing" + wait = 2 + stat_tag = "FP" diff --git a/code/controllers/subsystems/processing/obj.dm b/code/controllers/subsystems/processing/obj.dm new file mode 100644 index 0000000000..26021fb267 --- /dev/null +++ b/code/controllers/subsystems/processing/obj.dm @@ -0,0 +1,5 @@ +PROCESSING_SUBSYSTEM_DEF(obj) + name = "Objects" + priority = FIRE_PRIORITY_OBJ + flags = SS_NO_INIT + wait = 20 diff --git a/code/controllers/subsystems/processing/processing.dm b/code/controllers/subsystems/processing/processing.dm new file mode 100644 index 0000000000..c5d6dfa126 --- /dev/null +++ b/code/controllers/subsystems/processing/processing.dm @@ -0,0 +1,35 @@ +//Used to process objects. Fires once every second. + +SUBSYSTEM_DEF(processing) + name = "Processing" + priority = FIRE_PRIORITY_PROCESS + flags = SS_BACKGROUND|SS_POST_FIRE_TIMING|SS_NO_INIT + wait = 10 + + var/stat_tag = "P" //Used for logging + var/list/processing = list() + var/list/currentrun = list() + +/datum/controller/subsystem/processing/stat_entry() + ..("[stat_tag]:[processing.len]") + +/datum/controller/subsystem/processing/fire(resumed = 0) + if (!resumed) + currentrun = processing.Copy() + //cache for sanic speed (lists are references anyways) + var/list/current_run = currentrun + + while(current_run.len) + var/datum/thing = current_run[current_run.len] + current_run.len-- + if(QDELETED(thing)) + processing -= thing + else if(thing.process(wait) == PROCESS_KILL) + // fully stop so that a future START_PROCESSING will work + STOP_PROCESSING(src, thing) + if (MC_TICK_CHECK) + return + +/datum/proc/process() + set waitfor = 0 + return PROCESS_KILL diff --git a/code/controllers/subsystems/processing/projectiles.dm b/code/controllers/subsystems/processing/projectiles.dm new file mode 100644 index 0000000000..87c9f097de --- /dev/null +++ b/code/controllers/subsystems/processing/projectiles.dm @@ -0,0 +1,16 @@ +PROCESSING_SUBSYSTEM_DEF(projectiles) + name = "Projectiles" + wait = 1 + stat_tag = "PP" + priority = FIRE_PRIORITY_PROJECTILES + flags = SS_NO_INIT|SS_TICKER + var/global_max_tick_moves = 10 + var/global_pixel_speed = 2 + var/global_iterations_per_move = 16 + +/datum/controller/subsystem/processing/projectiles/proc/set_pixel_speed(new_speed) + global_pixel_speed = new_speed + for(var/i in processing) + var/obj/item/projectile/P = i + if(istype(P)) //there's non projectiles on this too. + P.set_pixel_speed(new_speed) diff --git a/code/controllers/subsystems/processing/turfs.dm b/code/controllers/subsystems/processing/turfs.dm new file mode 100644 index 0000000000..941513527e --- /dev/null +++ b/code/controllers/subsystems/processing/turfs.dm @@ -0,0 +1,3 @@ +PROCESSING_SUBSYSTEM_DEF(turfs) + name = "Turf Processing" + wait = 20 diff --git a/code/controllers/subsystems/sun.dm b/code/controllers/subsystems/sun.dm new file mode 100644 index 0000000000..551130a20b --- /dev/null +++ b/code/controllers/subsystems/sun.dm @@ -0,0 +1,7 @@ +SUBSYSTEM_DEF(sun) + name = "Sun" + wait = 600 + var/static/datum/sun/sun = new + +/datum/controller/subsystem/sun/fire() + sun.calc_position() diff --git a/code/controllers/subsystems/time_track.dm b/code/controllers/subsystems/time_track.dm new file mode 100644 index 0000000000..aed175ed27 --- /dev/null +++ b/code/controllers/subsystems/time_track.dm @@ -0,0 +1,37 @@ +SUBSYSTEM_DEF(time_track) + name = "Time Tracking" + wait = 600 + flags = SS_NO_INIT|SS_NO_TICK_CHECK + runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT + + var/time_dilation_current = 0 + + var/time_dilation_avg_fast = 0 + var/time_dilation_avg = 0 + var/time_dilation_avg_slow = 0 + + var/first_run = TRUE + + var/last_tick_realtime = 0 + var/last_tick_byond_time = 0 + var/last_tick_tickcount = 0 + +/datum/controller/subsystem/time_track/fire() + + var/current_realtime = REALTIMEOFDAY + var/current_byondtime = world.time + var/current_tickcount = world.time/world.tick_lag + + if (!first_run) + var/tick_drift = max(0, (((current_realtime - last_tick_realtime) - (current_byondtime - last_tick_byond_time)) / world.tick_lag)) + + time_dilation_current = tick_drift / (current_tickcount - last_tick_tickcount) * 100 + + time_dilation_avg_fast = MC_AVERAGE_FAST(time_dilation_avg_fast, time_dilation_current) + time_dilation_avg = MC_AVERAGE(time_dilation_avg, time_dilation_avg_fast) + time_dilation_avg_slow = MC_AVERAGE_SLOW(time_dilation_avg_slow, time_dilation_avg) + else + first_run = FALSE + last_tick_realtime = current_realtime + last_tick_byond_time = current_byondtime + last_tick_tickcount = current_tickcount diff --git a/code/controllers/subsystems/timer.dm b/code/controllers/subsystems/timer.dm new file mode 100644 index 0000000000..3cd4ffe6ba --- /dev/null +++ b/code/controllers/subsystems/timer.dm @@ -0,0 +1,522 @@ +#define BUCKET_LEN (world.fps*1*60) //how many ticks should we keep in the bucket. (1 minutes worth) +#define BUCKET_POS(timer) ((round((timer.timeToRun - SStimer.head_offset) / world.tick_lag) % BUCKET_LEN)||BUCKET_LEN) +#define TIMER_MAX (world.time + TICKS2DS(min(BUCKET_LEN-(SStimer.practical_offset-DS2TICKS(world.time - SStimer.head_offset))-1, BUCKET_LEN-1))) +#define TIMER_ID_MAX (2**24) //max float with integer precision + +SUBSYSTEM_DEF(timer) + name = "Timer" + wait = 1 //SS_TICKER subsystem, so wait is in ticks + init_order = INIT_ORDER_TIMER + + flags = SS_TICKER|SS_NO_INIT + + var/list/datum/timedevent/second_queue = list() //awe, yes, you've had first queue, but what about second queue? + var/list/hashes = list() + + var/head_offset = 0 //world.time of the first entry in the the bucket. + var/practical_offset = 1 //index of the first non-empty item in the bucket. + var/bucket_resolution = 0 //world.tick_lag the bucket was designed for + var/bucket_count = 0 //how many timers are in the buckets + + var/list/bucket_list = list() //list of buckets, each bucket holds every timer that has to run that byond tick. + + var/list/timer_id_dict = list() //list of all active timers assoicated to their timer id (for easy lookup) + + var/list/clienttime_timers = list() //special snowflake timers that run on fancy pansy "client time" + + var/last_invoke_tick = 0 + var/static/last_invoke_warning = 0 + var/static/bucket_auto_reset = TRUE + +/datum/controller/subsystem/timer/PreInit() + bucket_list.len = BUCKET_LEN + head_offset = world.time + bucket_resolution = world.tick_lag + +/datum/controller/subsystem/timer/stat_entry(msg) + ..("B:[bucket_count] P:[length(second_queue)] H:[length(hashes)] C:[length(clienttime_timers)] S:[length(timer_id_dict)]") + +/datum/controller/subsystem/timer/fire(resumed = FALSE) + var/lit = last_invoke_tick + var/last_check = world.time - TICKS2DS(BUCKET_LEN*1.5) + var/list/bucket_list = src.bucket_list + + if(!bucket_count) + last_invoke_tick = world.time + + if(lit && lit < last_check && head_offset < last_check && last_invoke_warning < last_check) + last_invoke_warning = world.time + var/msg = "No regular timers processed in the last [BUCKET_LEN*1.5] ticks[bucket_auto_reset ? ", resetting buckets" : ""]!" + message_admins(msg) + WARNING(msg) + if(bucket_auto_reset) + bucket_resolution = 0 + + log_world("Timer bucket reset. world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]") + for (var/i in 1 to length(bucket_list)) + var/datum/timedevent/bucket_head = bucket_list[i] + if (!bucket_head) + continue + + log_world("Active timers at index [i]:") + + var/datum/timedevent/bucket_node = bucket_head + var/anti_loop_check = 1000 + do + log_world(get_timer_debug_string(bucket_node)) + bucket_node = bucket_node.next + anti_loop_check-- + while(bucket_node && bucket_node != bucket_head && anti_loop_check) + log_world("Active timers in the second_queue queue:") + for(var/I in second_queue) + log_world(get_timer_debug_string(I)) + + var/cut_start_index = 1 + var/next_clienttime_timer_index = 0 + var/len = length(clienttime_timers) + + for (next_clienttime_timer_index in 1 to len) + if (MC_TICK_CHECK) + next_clienttime_timer_index-- + break + var/datum/timedevent/ctime_timer = clienttime_timers[next_clienttime_timer_index] + if (ctime_timer.timeToRun > REALTIMEOFDAY) + next_clienttime_timer_index-- + break + + var/datum/callback/callBack = ctime_timer.callBack + if (!callBack) + clienttime_timers.Cut(next_clienttime_timer_index,next_clienttime_timer_index+1) + CRASH("Invalid timer: [get_timer_debug_string(ctime_timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset], REALTIMEOFDAY: [REALTIMEOFDAY]") + + ctime_timer.spent = REALTIMEOFDAY + callBack.InvokeAsync() + + if(ctime_timer.flags & TIMER_LOOP) + ctime_timer.spent = 0 + clienttime_timers.Insert(ctime_timer, 1) + cut_start_index++ + else + qdel(ctime_timer) + + + if (next_clienttime_timer_index) + clienttime_timers.Cut(cut_start_index,next_clienttime_timer_index+1) + + if (MC_TICK_CHECK) + return + + var/static/list/spent = list() + var/static/datum/timedevent/timer + if (practical_offset > BUCKET_LEN) + head_offset += TICKS2DS(BUCKET_LEN) + practical_offset = 1 + resumed = FALSE + + if ((length(bucket_list) != BUCKET_LEN) || (world.tick_lag != bucket_resolution)) + reset_buckets() + bucket_list = src.bucket_list + resumed = FALSE + + + if (!resumed) + timer = null + + while (practical_offset <= BUCKET_LEN && head_offset + ((practical_offset-1)*world.tick_lag) <= world.time) + var/datum/timedevent/head = bucket_list[practical_offset] + if (!timer || !head || timer == head) + head = bucket_list[practical_offset] + timer = head + while (timer) + var/datum/callback/callBack = timer.callBack + if (!callBack) + bucket_resolution = null //force bucket recreation + CRASH("Invalid timer: [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]") + + if (!timer.spent) + spent += timer + timer.spent = world.time + callBack.InvokeAsync() + last_invoke_tick = world.time + + if (MC_TICK_CHECK) + return + + timer = timer.next + if (timer == head) + break + + + bucket_list[practical_offset++] = null + + //we freed up a bucket, lets see if anything in second_queue needs to be shifted to that bucket. + var/i = 0 + var/L = length(second_queue) + for (i in 1 to L) + timer = second_queue[i] + if (timer.timeToRun >= TIMER_MAX) + i-- + break + + if (timer.timeToRun < head_offset) + bucket_resolution = null //force bucket recreation + CRASH("[i] Invalid timer state: Timer in long run queue with a time to run less then head_offset. [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]") + + if (timer.callBack && !timer.spent) + timer.callBack.InvokeAsync() + spent += timer + bucket_count++ + else if(!QDELETED(timer)) + qdel(timer) + continue + + if (timer.timeToRun < head_offset + TICKS2DS(practical_offset-1)) + bucket_resolution = null //force bucket recreation + CRASH("[i] Invalid timer state: Timer in long run queue that would require a backtrack to transfer to short run queue. [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]") + if (timer.callBack && !timer.spent) + timer.callBack.InvokeAsync() + spent += timer + bucket_count++ + else if(!QDELETED(timer)) + qdel(timer) + continue + + bucket_count++ + var/bucket_pos = max(1, BUCKET_POS(timer)) + + var/datum/timedevent/bucket_head = bucket_list[bucket_pos] + if (!bucket_head) + bucket_list[bucket_pos] = timer + timer.next = null + timer.prev = null + continue + + if (!bucket_head.prev) + bucket_head.prev = bucket_head + timer.next = bucket_head + timer.prev = bucket_head.prev + timer.next.prev = timer + timer.prev.next = timer + if (i) + second_queue.Cut(1, i+1) + + timer = null + + bucket_count -= length(spent) + + for (var/i in spent) + var/datum/timedevent/qtimer = i + if(QDELETED(qtimer)) + bucket_count++ + continue + if(!(qtimer.flags & TIMER_LOOP)) + qdel(qtimer) + else + bucket_count++ + qtimer.spent = 0 + qtimer.bucketEject() + if(qtimer.flags & TIMER_CLIENT_TIME) + qtimer.timeToRun = REALTIMEOFDAY + qtimer.wait + else + qtimer.timeToRun = world.time + qtimer.wait + qtimer.bucketJoin() + + spent.len = 0 + +//formated this way to be runtime resistant +/datum/controller/subsystem/timer/proc/get_timer_debug_string(datum/timedevent/TE) + . = "Timer: [TE]" + . += "Prev: [TE.prev ? TE.prev : "NULL"], Next: [TE.next ? TE.next : "NULL"]" + if(TE.spent) + . += ", SPENT([TE.spent])" + if(QDELETED(TE)) + . += ", QDELETED" + if(!TE.callBack) + . += ", NO CALLBACK" + +/datum/controller/subsystem/timer/proc/reset_buckets() + var/list/bucket_list = src.bucket_list + var/list/alltimers = list() + //collect the timers currently in the bucket + for (var/bucket_head in bucket_list) + if (!bucket_head) + continue + var/datum/timedevent/bucket_node = bucket_head + do + alltimers += bucket_node + bucket_node = bucket_node.next + while(bucket_node && bucket_node != bucket_head) + + bucket_list.len = 0 + bucket_list.len = BUCKET_LEN + + practical_offset = 1 + bucket_count = 0 + head_offset = world.time + bucket_resolution = world.tick_lag + + alltimers += second_queue + if (!length(alltimers)) + return + + sortTim(alltimers, .proc/cmp_timer) + + var/datum/timedevent/head = alltimers[1] + + if (head.timeToRun < head_offset) + head_offset = head.timeToRun + + var/new_bucket_count + var/i = 1 + for (i in 1 to length(alltimers)) + var/datum/timedevent/timer = alltimers[1] + if (!timer) + continue + + var/bucket_pos = BUCKET_POS(timer) + if (timer.timeToRun >= TIMER_MAX) + i-- + break + + + if (!timer.callBack || timer.spent) + WARNING("Invalid timer: [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]") + if (timer.callBack) + qdel(timer) + continue + + new_bucket_count++ + var/datum/timedevent/bucket_head = bucket_list[bucket_pos] + if (!bucket_head) + bucket_list[bucket_pos] = timer + timer.next = null + timer.prev = null + continue + + if (!bucket_head.prev) + bucket_head.prev = bucket_head + timer.next = bucket_head + timer.prev = bucket_head.prev + timer.next.prev = timer + timer.prev.next = timer + if (i) + alltimers.Cut(1, i+1) + second_queue = alltimers + bucket_count = new_bucket_count + + +/datum/controller/subsystem/timer/Recover() + second_queue |= SStimer.second_queue + hashes |= SStimer.hashes + timer_id_dict |= SStimer.timer_id_dict + bucket_list |= SStimer.bucket_list + +/datum/timedevent + var/id + var/datum/callback/callBack + var/timeToRun + var/wait + var/hash + var/list/flags + var/spent = 0 //time we ran the timer. + var/name //for easy debugging. + //cicular doublely linked list + var/datum/timedevent/next + var/datum/timedevent/prev + +/datum/timedevent/New(datum/callback/callBack, wait, flags, hash) + var/static/nextid = 1 + id = TIMER_ID_NULL + src.callBack = callBack + src.wait = wait + src.flags = flags + src.hash = hash + + if (flags & TIMER_CLIENT_TIME) + timeToRun = REALTIMEOFDAY + wait + else + timeToRun = world.time + wait + + if (flags & TIMER_UNIQUE) + SStimer.hashes[hash] = src + + if (flags & TIMER_STOPPABLE) + id = num2text(nextid, 100) + if (nextid >= SHORT_REAL_LIMIT) + nextid += min(1, 2**round(nextid/SHORT_REAL_LIMIT)) + else + nextid++ + SStimer.timer_id_dict[id] = src + + name = "Timer: [id] (\ref[src]), TTR: [timeToRun], Flags: [jointext(bitfield2list(flags, list("TIMER_UNIQUE", "TIMER_OVERRIDE", "TIMER_CLIENT_TIME", "TIMER_STOPPABLE", "TIMER_NO_HASH_WAIT", "TIMER_LOOP")), ", ")], callBack: \ref[callBack], callBack.object: [callBack.object]\ref[callBack.object]([getcallingtype()]), callBack.delegate:[callBack.delegate]([callBack.arguments ? callBack.arguments.Join(", ") : ""])" + + if ((timeToRun < world.time || timeToRun < SStimer.head_offset) && !(flags & TIMER_CLIENT_TIME)) + CRASH("Invalid timer state: Timer created that would require a backtrack to run (addtimer would never let this happen): [SStimer.get_timer_debug_string(src)]") + + if (callBack.object != GLOBAL_PROC && !QDESTROYING(callBack.object)) + LAZYADD(callBack.object.active_timers, src) + + bucketJoin() + +/datum/timedevent/Destroy() + ..() + if (flags & TIMER_UNIQUE && hash) + SStimer.hashes -= hash + + if (callBack && callBack.object && callBack.object != GLOBAL_PROC && callBack.object.active_timers) + callBack.object.active_timers -= src + UNSETEMPTY(callBack.object.active_timers) + + callBack = null + + if (flags & TIMER_STOPPABLE) + SStimer.timer_id_dict -= id + + if (flags & TIMER_CLIENT_TIME) + if (!spent) + spent = world.time + SStimer.clienttime_timers -= src + return QDEL_HINT_IWILLGC + + if (!spent) + spent = world.time + bucketEject() + else + if (prev && prev.next == src) + prev.next = next + if (next && next.prev == src) + next.prev = prev + next = null + prev = null + return QDEL_HINT_IWILLGC + +/datum/timedevent/proc/bucketEject() + var/bucketpos = BUCKET_POS(src) + var/list/bucket_list = SStimer.bucket_list + var/list/second_queue = SStimer.second_queue + var/datum/timedevent/buckethead + if(bucketpos > 0) + buckethead = bucket_list[bucketpos] + if(buckethead == src) + bucket_list[bucketpos] = next + SStimer.bucket_count-- + else if(timeToRun < TIMER_MAX || next || prev) + SStimer.bucket_count-- + else + var/l = length(second_queue) + second_queue -= src + if(l == length(second_queue)) + SStimer.bucket_count-- + if(prev != next) + prev.next = next + next.prev = prev + else + prev?.next = null + next?.prev = null + prev = next = null + +/datum/timedevent/proc/bucketJoin() + var/list/L + + if (flags & TIMER_CLIENT_TIME) + L = SStimer.clienttime_timers + else if (timeToRun >= TIMER_MAX) + L = SStimer.second_queue + + if(L) + BINARY_INSERT(src, L, datum/timedevent, timeToRun) + return + + //get the list of buckets + var/list/bucket_list = SStimer.bucket_list + + //calculate our place in the bucket list + var/bucket_pos = BUCKET_POS(src) + + //get the bucket for our tick + var/datum/timedevent/bucket_head = bucket_list[bucket_pos] + SStimer.bucket_count++ + //empty bucket, we will just add ourselves + if (!bucket_head) + bucket_list[bucket_pos] = src + return + //other wise, lets do a simplified linked list add. + if (!bucket_head.prev) + bucket_head.prev = bucket_head + next = bucket_head + prev = bucket_head.prev + next.prev = src + prev.next = src + +/datum/timedevent/proc/getcallingtype() + . = "ERROR" + if (callBack.object == GLOBAL_PROC) + . = "GLOBAL_PROC" + else + . = "[callBack.object.type]" + +/proc/addtimer(datum/callback/callback, wait = 0, flags = 0) + if (!callback) + CRASH("addtimer called without a callback") + + if (wait < 0) + crash_with("addtimer called with a negative wait. Converting to [world.tick_lag]") + + if (callback.object != GLOBAL_PROC && QDELETED(callback.object) && !QDESTROYING(callback.object)) + crash_with("addtimer called with a callback assigned to a qdeleted object. In the future such timers will not be supported and may refuse to run or run with a 0 wait") + + wait = max(CEILING(wait, world.tick_lag), world.tick_lag) + + if(wait >= INFINITY) + CRASH("Attempted to create timer with INFINITY delay") + + var/hash + + if (flags & TIMER_UNIQUE) + var/list/hashlist + if(flags & TIMER_NO_HASH_WAIT) + hashlist = list(callback.object, "(\ref[callback.object])", callback.delegate, flags & TIMER_CLIENT_TIME) + else + hashlist = list(callback.object, "(\ref[callback.object])", callback.delegate, wait, flags & TIMER_CLIENT_TIME) + hashlist += callback.arguments + hash = hashlist.Join("|||||||") + + var/datum/timedevent/hash_timer = SStimer.hashes[hash] + if(hash_timer) + if (hash_timer.spent) //it's pending deletion, pretend it doesn't exist. + hash_timer.hash = null //but keep it from accidentally deleting us + else + if (flags & TIMER_OVERRIDE) + hash_timer.hash = null //no need having it delete it's hash if we are going to replace it + qdel(hash_timer) + else + if (hash_timer.flags & TIMER_STOPPABLE) + . = hash_timer.id + return + else if(flags & TIMER_OVERRIDE) + crash_with("TIMER_OVERRIDE used without TIMER_UNIQUE") + + var/datum/timedevent/timer = new(callback, wait, flags, hash) + return timer.id + +/proc/deltimer(id) + if (!id) + return FALSE + if (id == TIMER_ID_NULL) + CRASH("Tried to delete a null timerid. Use TIMER_STOPPABLE flag") + if (!istext(id)) + if (istype(id, /datum/timedevent)) + qdel(id) + return TRUE + //id is string + var/datum/timedevent/timer = SStimer.timer_id_dict[id] + if (timer && !timer.spent) + qdel(timer) + return TRUE + return FALSE + + +#undef BUCKET_LEN +#undef BUCKET_POS +#undef TIMER_MAX +#undef TIMER_ID_MAX diff --git a/code/controllers/subsystems/vote.dm b/code/controllers/subsystems/vote.dm index d42cbe7f63..84b7377609 100644 --- a/code/controllers/subsystems/vote.dm +++ b/code/controllers/subsystems/vote.dm @@ -1,373 +1,373 @@ -SUBSYSTEM_DEF(vote) - name = "Vote" - wait = 10 - priority = FIRE_PRIORITY_VOTE - runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT - flags = SS_KEEP_TIMING | SS_NO_INIT - var/list/round_voters = list() - - //Current vote - var/initiator - var/started_time - var/time_remaining - var/duration - var/mode - var/question - var/list/choices = list() - var/list/gamemode_names = list() - var/list/voted = list() - var/list/current_votes = list() - var/list/additional_text = list() - -/datum/controller/subsystem/vote/fire(resumed) - if(mode) - time_remaining = round((started_time + duration - world.time)/10) - if(mode == VOTE_GAMEMODE && ticker.current_state >= GAME_STATE_SETTING_UP) - to_chat(world, "Gamemode vote aborted: Game has already started.") - reset() - return - if(time_remaining <= 0) - result() - reset() - -/datum/controller/subsystem/vote/proc/autotransfer() - initiate_vote(VOTE_CREW_TRANSFER, "the server", 1) - log_debug("The server has called a crew transfer vote.") - -/datum/controller/subsystem/vote/proc/autogamemode() - initiate_vote(VOTE_GAMEMODE, "the server", 1) - log_debug("The server has called a gamemode vote.") - -/datum/controller/subsystem/vote/proc/reset() - initiator = null - started_time = null - duration = null - time_remaining = null - mode = null - question = null - choices.Cut() - voted.Cut() - current_votes.Cut() - additional_text.Cut() - -/datum/controller/subsystem/vote/proc/get_result() // Get the highest number of votes - var/greatest_votes = 0 - var/total_votes = 0 - - for(var/option in choices) - var/votes = choices[option] - total_votes += votes - if(votes > greatest_votes) - greatest_votes = votes - - if(!config.vote_no_default && choices.len) // Default-vote for everyone who didn't vote - var/non_voters = (clients.len - total_votes) - if(non_voters > 0) - if(mode == VOTE_RESTART) - choices["Continue Playing"] += non_voters - if(choices["Continue Playing"] >= greatest_votes) - greatest_votes = choices["Continue Playing"] - else if(mode == VOTE_GAMEMODE) - if(master_mode in choices) - choices[master_mode] += non_voters - if(choices[master_mode] >= greatest_votes) - greatest_votes = choices[master_mode] - else if(mode == VOTE_CREW_TRANSFER) - var/factor = 0.5 - switch(world.time / (10 * 60)) // minutes - if(0 to 60) - factor = 0.5 - if(61 to 120) - factor = 0.8 - if(121 to 240) - factor = 1 - if(241 to 300) - factor = 1.2 - else - factor = 1.4 - choices["Initiate Crew Transfer"] = round(choices["Initiate Crew Transfer"] * factor) - world << "Crew Transfer Factor: [factor]" - greatest_votes = max(choices["Initiate Crew Transfer"], choices["Continue The Round"]) - - . = list() // Get all options with that many votes and return them in a list - if(greatest_votes) - for(var/option in choices) - if(choices[option] == greatest_votes) - . += option - -/datum/controller/subsystem/vote/proc/announce_result() - var/list/winners = get_result() - var/text - if(winners.len > 0) - if(winners.len > 1) - if(mode != VOTE_GAMEMODE || ticker.hide_mode == 0) // Here we are making sure we don't announce potential game modes - text = "Vote Tied Between:\n" - for(var/option in winners) - text += "\t[option]\n" - . = pick(winners) - - for(var/key in current_votes) - if(choices[current_votes[key]] == .) - round_voters += key // Keep track of who voted for the winning round. - if(mode != VOTE_GAMEMODE || . == "Extended" || ticker.hide_mode == 0) // Announce Extended gamemode, but not other gamemodes - text += "Vote Result: [mode == VOTE_GAMEMODE ? gamemode_names[.] : .]" - else - text += "The vote has ended." - - else - text += "Vote Result: Inconclusive - No Votes!" - if(mode == VOTE_ADD_ANTAGONIST) - antag_add_failed = 1 - log_vote(text) - to_chat(world, "[text]") - -/datum/controller/subsystem/vote/proc/result() - . = announce_result() - var/restart = 0 - if(.) - switch(mode) - if(VOTE_RESTART) - if(. == "Restart Round") - restart = 1 - if(VOTE_GAMEMODE) - if(master_mode != .) - world.save_mode(.) - if(ticker && ticker.mode) - restart = 1 - else - master_mode = . - if(VOTE_CREW_TRANSFER) - if(. == "Initiate Crew Transfer") - init_shift_change(null, 1) - if(VOTE_ADD_ANTAGONIST) - if(isnull(.) || . == "None") - antag_add_failed = 1 - else - additional_antag_types |= antag_names_to_ids[.] - - if(mode == VOTE_GAMEMODE) //fire this even if the vote fails. - if(!round_progressing) - round_progressing = 1 - world << "The round will start soon." - - if(restart) - world << "World restarting due to vote..." - feedback_set_details("end_error", "restart vote") - if(blackbox) - blackbox.save_all_data_to_sql() - sleep(50) - log_game("Rebooting due to restart vote") - world.Reboot() - -/datum/controller/subsystem/vote/proc/submit_vote(ckey, newVote) - if(mode) - if(config.vote_no_dead && usr.stat == DEAD && !usr.client.holder) - return - if(current_votes[ckey]) - choices[choices[current_votes[ckey]]]-- - if(newVote && newVote >= 1 && newVote <= choices.len) - choices[choices[newVote]]++ - current_votes[ckey] = newVote - else - current_votes[ckey] = null - -/datum/controller/subsystem/vote/proc/initiate_vote(vote_type, initiator_key, automatic = FALSE, time = config.vote_period) - if(!mode) - if(started_time != null && !(check_rights(R_ADMIN) || automatic)) - var/next_allowed_time = (started_time + config.vote_delay) - if(next_allowed_time > world.time) - return 0 - - reset() - - switch(vote_type) - if(VOTE_RESTART) - choices.Add("Restart Round", "Continue Playing") - if(VOTE_GAMEMODE) - if(ticker.current_state >= GAME_STATE_SETTING_UP) - return 0 - choices.Add(config.votable_modes) - for(var/F in choices) - var/datum/game_mode/M = gamemode_cache[F] - if(!M) - continue - gamemode_names[M.config_tag] = capitalize(M.name) //It's ugly to put this here but it works - additional_text.Add("[M.required_players]") - gamemode_names["secret"] = "Secret" - if(VOTE_CREW_TRANSFER) - if(!check_rights(R_ADMIN|R_MOD, 0)) // The gods care not for the affairs of the mortals - if(get_security_level() == "red" || get_security_level() == "delta") - initiator_key << "The current alert status is too high to call for a crew transfer!" - return 0 - if(ticker.current_state <= GAME_STATE_SETTING_UP) - initiator_key << "The crew transfer button has been disabled!" - return 0 - question = "End the shift?" - choices.Add("Initiate Crew Transfer", "Continue The Round") - if(VOTE_ADD_ANTAGONIST) - if(!config.allow_extra_antags || ticker.current_state >= GAME_STATE_SETTING_UP) - return 0 - for(var/antag_type in all_antag_types) - var/datum/antagonist/antag = all_antag_types[antag_type] - if(!(antag.id in additional_antag_types) && antag.is_votable()) - choices.Add(antag.role_text) - choices.Add("None") - if(VOTE_CUSTOM) - question = sanitizeSafe(input(usr, "What is the vote for?") as text|null) - if(!question) - return 0 - for(var/i = 1 to 10) - var/option = capitalize(sanitize(input(usr, "Please enter an option or hit cancel to finish") as text|null)) - if(!option || mode || !usr.client) - break - choices.Add(option) - else - return 0 - - mode = vote_type - initiator = initiator_key - started_time = world.time - duration = time - var/text = "[capitalize(mode)] vote started by [initiator]." - if(mode == VOTE_CUSTOM) - text += "\n[question]" - - log_vote(text) - - world << "[text]\nType vote or click here to place your votes.\nYou have [config.vote_period / 10] seconds to vote." - if(vote_type == VOTE_CREW_TRANSFER || vote_type == VOTE_GAMEMODE || vote_type == VOTE_CUSTOM) - world << sound('sound/ambience/alarm4.ogg', repeat = 0, wait = 0, volume = 50, channel = 3) - - if(mode == VOTE_GAMEMODE && round_progressing) - round_progressing = 0 - world << "Round start has been delayed." - - time_remaining = round(config.vote_period / 10) - return 1 - return 0 - -/datum/controller/subsystem/vote/proc/interface(var/client/C) - if(!istype(C)) - return - var/admin = FALSE - if(C.holder) - if(C.holder.rights & R_ADMIN) - admin = TRUE - - . = "Voting Panel" - if(mode) - if(question) - . += "

Vote: '[question]'

" - else - . += "

Vote: [capitalize(mode)]

" - . += "Time Left: [time_remaining] s
" - . += "" - if(mode == VOTE_GAMEMODE) - .+= "" - - for(var/i = 1 to choices.len) - var/votes = choices[choices[i]] - if(!votes) - votes = 0 - . += "" - var/thisVote = (current_votes[C.ckey] == i) - if(mode == VOTE_GAMEMODE) - . += "" - else - . += "" - if (additional_text.len >= i) - . += additional_text[i] - . += "" - - . += "" - - . += "
ChoicesVotesMinimum Players
[thisVote ? "" : ""][gamemode_names[choices[i]]][thisVote ? "" : ""][votes][thisVote ? "" : ""][choices[i]][thisVote ? "" : ""][votes]
Unvote

" - if(admin) - . += "(Cancel Vote) " - else - . += "

Start a vote:



" - - . += "Close" - -/datum/controller/subsystem/vote/Topic(href, href_list[]) - if(!usr || !usr.client) - return - switch(href_list["vote"]) - if("close") - usr << browse(null, "window=vote") - return - - if("cancel") - if(usr.client.holder) - reset() - if("toggle_restart") - if(usr.client.holder) - config.allow_vote_restart = !config.allow_vote_restart - if("toggle_gamemode") - if(usr.client.holder) - config.allow_vote_mode = !config.allow_vote_mode - - if(VOTE_RESTART) - if(config.allow_vote_restart || usr.client.holder) - initiate_vote(VOTE_RESTART, usr.key) - if(VOTE_GAMEMODE) - if(config.allow_vote_mode || usr.client.holder) - initiate_vote(VOTE_GAMEMODE, usr.key) - if(VOTE_CREW_TRANSFER) - if(config.allow_vote_restart || usr.client.holder) - initiate_vote(VOTE_CREW_TRANSFER, usr.key) - if(VOTE_ADD_ANTAGONIST) - if(config.allow_extra_antags || usr.client.holder) - initiate_vote(VOTE_ADD_ANTAGONIST, usr.key) - if(VOTE_CUSTOM) - if(usr.client.holder) - initiate_vote(VOTE_CUSTOM, usr.key) - - if("unvote") - submit_vote(usr.ckey, null) - - else - var/t = round(text2num(href_list["vote"])) - if(t) // It starts from 1, so there's no problem - submit_vote(usr.ckey, t) - usr.client.vote() - -/client/verb/vote() - set category = "OOC" - set name = "Vote" - - if(SSvote) - src << browse(SSvote.interface(src), "window=vote;size=500x[300 + SSvote.choices.len * 25]") +SUBSYSTEM_DEF(vote) + name = "Vote" + wait = 10 + priority = FIRE_PRIORITY_VOTE + runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT + flags = SS_KEEP_TIMING | SS_NO_INIT + var/list/round_voters = list() + + //Current vote + var/initiator + var/started_time + var/time_remaining + var/duration + var/mode + var/question + var/list/choices = list() + var/list/gamemode_names = list() + var/list/voted = list() + var/list/current_votes = list() + var/list/additional_text = list() + +/datum/controller/subsystem/vote/fire(resumed) + if(mode) + time_remaining = round((started_time + duration - world.time)/10) + if(mode == VOTE_GAMEMODE && ticker.current_state >= GAME_STATE_SETTING_UP) + to_chat(world, "Gamemode vote aborted: Game has already started.") + reset() + return + if(time_remaining <= 0) + result() + reset() + +/datum/controller/subsystem/vote/proc/autotransfer() + initiate_vote(VOTE_CREW_TRANSFER, "the server", 1) + log_debug("The server has called a crew transfer vote.") + +/datum/controller/subsystem/vote/proc/autogamemode() + initiate_vote(VOTE_GAMEMODE, "the server", 1) + log_debug("The server has called a gamemode vote.") + +/datum/controller/subsystem/vote/proc/reset() + initiator = null + started_time = null + duration = null + time_remaining = null + mode = null + question = null + choices.Cut() + voted.Cut() + current_votes.Cut() + additional_text.Cut() + +/datum/controller/subsystem/vote/proc/get_result() // Get the highest number of votes + var/greatest_votes = 0 + var/total_votes = 0 + + for(var/option in choices) + var/votes = choices[option] + total_votes += votes + if(votes > greatest_votes) + greatest_votes = votes + + if(!config.vote_no_default && choices.len) // Default-vote for everyone who didn't vote + var/non_voters = (GLOB.clients.len - total_votes) + if(non_voters > 0) + if(mode == VOTE_RESTART) + choices["Continue Playing"] += non_voters + if(choices["Continue Playing"] >= greatest_votes) + greatest_votes = choices["Continue Playing"] + else if(mode == VOTE_GAMEMODE) + if(master_mode in choices) + choices[master_mode] += non_voters + if(choices[master_mode] >= greatest_votes) + greatest_votes = choices[master_mode] + else if(mode == VOTE_CREW_TRANSFER) + var/factor = 0.5 + switch(world.time / (10 * 60)) // minutes + if(0 to 60) + factor = 0.5 + if(61 to 120) + factor = 0.8 + if(121 to 240) + factor = 1 + if(241 to 300) + factor = 1.2 + else + factor = 1.4 + choices["Initiate Crew Transfer"] = round(choices["Initiate Crew Transfer"] * factor) + world << "Crew Transfer Factor: [factor]" + greatest_votes = max(choices["Initiate Crew Transfer"], choices["Continue The Round"]) + + . = list() // Get all options with that many votes and return them in a list + if(greatest_votes) + for(var/option in choices) + if(choices[option] == greatest_votes) + . += option + +/datum/controller/subsystem/vote/proc/announce_result() + var/list/winners = get_result() + var/text + if(winners.len > 0) + if(winners.len > 1) + if(mode != VOTE_GAMEMODE || ticker.hide_mode == 0) // Here we are making sure we don't announce potential game modes + text = "Vote Tied Between:\n" + for(var/option in winners) + text += "\t[option]\n" + . = pick(winners) + + for(var/key in current_votes) + if(choices[current_votes[key]] == .) + round_voters += key // Keep track of who voted for the winning round. + if(mode != VOTE_GAMEMODE || . == "Extended" || ticker.hide_mode == 0) // Announce Extended gamemode, but not other gamemodes + text += "Vote Result: [mode == VOTE_GAMEMODE ? gamemode_names[.] : .]" + else + text += "The vote has ended." + + else + text += "Vote Result: Inconclusive - No Votes!" + if(mode == VOTE_ADD_ANTAGONIST) + antag_add_failed = 1 + log_vote(text) + to_chat(world, "[text]") + +/datum/controller/subsystem/vote/proc/result() + . = announce_result() + var/restart = 0 + if(.) + switch(mode) + if(VOTE_RESTART) + if(. == "Restart Round") + restart = 1 + if(VOTE_GAMEMODE) + if(master_mode != .) + world.save_mode(.) + if(ticker && ticker.mode) + restart = 1 + else + master_mode = . + if(VOTE_CREW_TRANSFER) + if(. == "Initiate Crew Transfer") + init_shift_change(null, 1) + if(VOTE_ADD_ANTAGONIST) + if(isnull(.) || . == "None") + antag_add_failed = 1 + else + additional_antag_types |= antag_names_to_ids[.] + + if(mode == VOTE_GAMEMODE) //fire this even if the vote fails. + if(!round_progressing) + round_progressing = 1 + world << "The round will start soon." + + if(restart) + world << "World restarting due to vote..." + feedback_set_details("end_error", "restart vote") + if(blackbox) + blackbox.save_all_data_to_sql() + sleep(50) + log_game("Rebooting due to restart vote") + world.Reboot() + +/datum/controller/subsystem/vote/proc/submit_vote(ckey, newVote) + if(mode) + if(config.vote_no_dead && usr.stat == DEAD && !usr.client.holder) + return + if(current_votes[ckey]) + choices[choices[current_votes[ckey]]]-- + if(newVote && newVote >= 1 && newVote <= choices.len) + choices[choices[newVote]]++ + current_votes[ckey] = newVote + else + current_votes[ckey] = null + +/datum/controller/subsystem/vote/proc/initiate_vote(vote_type, initiator_key, automatic = FALSE, time = config.vote_period) + if(!mode) + if(started_time != null && !(check_rights(R_ADMIN) || automatic)) + var/next_allowed_time = (started_time + config.vote_delay) + if(next_allowed_time > world.time) + return 0 + + reset() + + switch(vote_type) + if(VOTE_RESTART) + choices.Add("Restart Round", "Continue Playing") + if(VOTE_GAMEMODE) + if(ticker.current_state >= GAME_STATE_SETTING_UP) + return 0 + choices.Add(config.votable_modes) + for(var/F in choices) + var/datum/game_mode/M = gamemode_cache[F] + if(!M) + continue + gamemode_names[M.config_tag] = capitalize(M.name) //It's ugly to put this here but it works + additional_text.Add("[M.required_players]") + gamemode_names["secret"] = "Secret" + if(VOTE_CREW_TRANSFER) + if(!check_rights(R_ADMIN|R_MOD, 0)) // The gods care not for the affairs of the mortals + if(get_security_level() == "red" || get_security_level() == "delta") + initiator_key << "The current alert status is too high to call for a crew transfer!" + return 0 + if(ticker.current_state <= GAME_STATE_SETTING_UP) + initiator_key << "The crew transfer button has been disabled!" + return 0 + question = "End the shift?" + choices.Add("Initiate Crew Transfer", "Continue The Round") + if(VOTE_ADD_ANTAGONIST) + if(!config.allow_extra_antags || ticker.current_state >= GAME_STATE_SETTING_UP) + return 0 + for(var/antag_type in all_antag_types) + var/datum/antagonist/antag = all_antag_types[antag_type] + if(!(antag.id in additional_antag_types) && antag.is_votable()) + choices.Add(antag.role_text) + choices.Add("None") + if(VOTE_CUSTOM) + question = sanitizeSafe(input(usr, "What is the vote for?") as text|null) + if(!question) + return 0 + for(var/i = 1 to 10) + var/option = capitalize(sanitize(input(usr, "Please enter an option or hit cancel to finish") as text|null)) + if(!option || mode || !usr.client) + break + choices.Add(option) + else + return 0 + + mode = vote_type + initiator = initiator_key + started_time = world.time + duration = time + var/text = "[capitalize(mode)] vote started by [initiator]." + if(mode == VOTE_CUSTOM) + text += "\n[question]" + + log_vote(text) + + world << "[text]\nType vote or click here to place your votes.\nYou have [config.vote_period / 10] seconds to vote." + if(vote_type == VOTE_CREW_TRANSFER || vote_type == VOTE_GAMEMODE || vote_type == VOTE_CUSTOM) + world << sound('sound/ambience/alarm4.ogg', repeat = 0, wait = 0, volume = 50, channel = 3) + + if(mode == VOTE_GAMEMODE && round_progressing) + round_progressing = 0 + world << "Round start has been delayed." + + time_remaining = round(config.vote_period / 10) + return 1 + return 0 + +/datum/controller/subsystem/vote/proc/interface(var/client/C) + if(!istype(C)) + return + var/admin = FALSE + if(C.holder) + if(C.holder.rights & R_ADMIN) + admin = TRUE + + . = "Voting Panel" + if(mode) + if(question) + . += "

Vote: '[question]'

" + else + . += "

Vote: [capitalize(mode)]

" + . += "Time Left: [time_remaining] s
" + . += "" + if(mode == VOTE_GAMEMODE) + .+= "" + + for(var/i = 1 to choices.len) + var/votes = choices[choices[i]] + if(!votes) + votes = 0 + . += "" + var/thisVote = (current_votes[C.ckey] == i) + if(mode == VOTE_GAMEMODE) + . += "" + else + . += "" + if (additional_text.len >= i) + . += additional_text[i] + . += "" + + . += "" + + . += "
ChoicesVotesMinimum Players
[thisVote ? "" : ""][gamemode_names[choices[i]]][thisVote ? "" : ""][votes][thisVote ? "" : ""][choices[i]][thisVote ? "" : ""][votes]
Unvote

" + if(admin) + . += "(Cancel Vote) " + else + . += "

Start a vote:



" + + . += "Close" + +/datum/controller/subsystem/vote/Topic(href, href_list[]) + if(!usr || !usr.client) + return + switch(href_list["vote"]) + if("close") + usr << browse(null, "window=vote") + return + + if("cancel") + if(usr.client.holder) + reset() + if("toggle_restart") + if(usr.client.holder) + config.allow_vote_restart = !config.allow_vote_restart + if("toggle_gamemode") + if(usr.client.holder) + config.allow_vote_mode = !config.allow_vote_mode + + if(VOTE_RESTART) + if(config.allow_vote_restart || usr.client.holder) + initiate_vote(VOTE_RESTART, usr.key) + if(VOTE_GAMEMODE) + if(config.allow_vote_mode || usr.client.holder) + initiate_vote(VOTE_GAMEMODE, usr.key) + if(VOTE_CREW_TRANSFER) + if(config.allow_vote_restart || usr.client.holder) + initiate_vote(VOTE_CREW_TRANSFER, usr.key) + if(VOTE_ADD_ANTAGONIST) + if(config.allow_extra_antags || usr.client.holder) + initiate_vote(VOTE_ADD_ANTAGONIST, usr.key) + if(VOTE_CUSTOM) + if(usr.client.holder) + initiate_vote(VOTE_CUSTOM, usr.key) + + if("unvote") + submit_vote(usr.ckey, null) + + else + var/t = round(text2num(href_list["vote"])) + if(t) // It starts from 1, so there's no problem + submit_vote(usr.ckey, t) + usr.client.vote() + +/client/verb/vote() + set category = "OOC" + set name = "Vote" + + if(SSvote) + src << browse(SSvote.interface(src), "window=vote;size=500x[300 + SSvote.choices.len * 25]") diff --git a/code/controllers/verbs.dm b/code/controllers/verbs.dm index 5cd8d2ab08..7e2e1a42e3 100644 --- a/code/controllers/verbs.dm +++ b/code/controllers/verbs.dm @@ -63,76 +63,57 @@ usr.client.debug_variables(antag) message_admins("Admin [key_name_admin(usr)] is debugging the [antag.role_text] template.") -/client/proc/debug_controller(controller in list("Master","Ticker","Ticker Process","Air","Jobs","Sun","Radio","Supply","Shuttles","Emergency Shuttle","Configuration","pAI", "Cameras", "Transfer Controller", "Gas Data","Event","Plants","Alarm","Nano","Chemistry","Vote","Xenobio","Planets")) +/client/proc/debug_controller() set category = "Debug" set name = "Debug Controller" - set desc = "Debug the various periodic loop controllers for the game (be careful!)" + set desc = "Debug the various subsystems/controllers for the game (be careful!)" - if(!holder) return - switch(controller) - if("Master") - debug_variables(master_controller) - feedback_add_details("admin_verb","DMC") - if("Ticker") - debug_variables(ticker) - feedback_add_details("admin_verb","DTicker") - if("Ticker Process") - debug_variables(tickerProcess) - feedback_add_details("admin_verb","DTickerProcess") - if("Air") - debug_variables(air_master) - feedback_add_details("admin_verb","DAir") - if("Jobs") - debug_variables(job_master) - feedback_add_details("admin_verb","DJobs") - if("Sun") - debug_variables(sun) - feedback_add_details("admin_verb","DSun") - if("Radio") - debug_variables(radio_controller) - feedback_add_details("admin_verb","DRadio") - if("Supply") - debug_variables(supply_controller) - feedback_add_details("admin_verb","DSupply") - if("Shuttles") - debug_variables(shuttle_controller) - feedback_add_details("admin_verb","DShuttles") - if("Emergency Shuttle") - debug_variables(emergency_shuttle) - feedback_add_details("admin_verb","DEmergency") - if("Configuration") - debug_variables(config) - feedback_add_details("admin_verb","DConf") - if("pAI") - debug_variables(paiController) - feedback_add_details("admin_verb","DpAI") - if("Cameras") - debug_variables(cameranet) - feedback_add_details("admin_verb","DCameras") - if("Transfer Controller") - debug_variables(transfer_controller) - feedback_add_details("admin_verb","DAutovoter") - if("Gas Data") - debug_variables(gas_data) - feedback_add_details("admin_verb","DGasdata") - if("Event") - debug_variables(event_manager) - feedback_add_details("admin_verb", "DEvent") - if("Plants") - debug_variables(plant_controller) - feedback_add_details("admin_verb", "DPlants") - if("Alarm") - debug_variables(alarm_manager) - feedback_add_details("admin_verb", "DAlarm") - if("Nano") - debug_variables(GLOB.nanomanager) - feedback_add_details("admin_verb", "DNano") - if("Chemistry") - debug_variables(chemistryProcess) - feedback_add_details("admin_verb", "DChem") - message_admins("Admin [key_name_admin(usr)] is debugging the [controller] controller.") - return + if(!holder) + return + var/list/options = list() + options["MC"] = Master + options["Failsafe"] = Failsafe + options["Configuration"] = config + for(var/i in Master.subsystems) + var/datum/controller/subsystem/S = i + if(!istype(S)) //Eh, we're a debug verb, let's have typechecking. + continue + var/strtype = "SS[get_end_section_of_type(S.type)]" + if(options[strtype]) + var/offset = 2 + while(istype(options["[strtype]_[offset] - DUPE ERROR"], /datum/controller/subsystem)) + offset++ + options["[strtype]_[offset] - DUPE ERROR"] = S //Something is very, very wrong. + else + options[strtype] = S + //Goon PS stuff, and other yet-to-be-subsystem things. + options["LEGACY: master_controller"] = master_controller + options["LEGACY: ticker"] = ticker + options["LEGACY: tickerProcess"] = tickerProcess + options["LEGACY: air_master"] = air_master + options["LEGACY: job_master"] = job_master + options["LEGACY: radio_controller"] = radio_controller + options["LEGACY: supply_controller"] = supply_controller + options["LEGACY: emergency_shuttle"] = emergency_shuttle + options["LEGACY: paiController"] = paiController + options["LEGACY: cameranet"] = cameranet + options["LEGACY: transfer_controller"] = transfer_controller + options["LEGACY: gas_data"] = gas_data + options["LEGACY: plant_controller"] = plant_controller + options["LEGACY: alarm_manager"] = alarm_manager + + var/pick = input(mob, "Choose a controller to debug/view variables of.", "VV controller:") as null|anything in options + if(!pick) + return + var/datum/D = options[pick] + if(!istype(D)) + return + feedback_add_details("admin_verb", "DebugController") + message_admins("Admin [key_name_admin(mob)] is debugging the [pick] controller.") + debug_variables(D) + +//VOREStation Edit Begin /client/proc/debug_process_scheduler() set category = "Debug" set name = "Debug Process Scheduler" @@ -155,3 +136,4 @@ debug_variables(P) feedback_add_details("admin_verb", "DProcCtrl") message_admins("Admin [key_name_admin(usr)] is debugging the [controller] controller.") +//VOREStation Edit End \ No newline at end of file diff --git a/code/datums/autolathe/arms.dm b/code/datums/autolathe/arms.dm index e5831cec71..e170d8c885 100644 --- a/code/datums/autolathe/arms.dm +++ b/code/datums/autolathe/arms.dm @@ -70,12 +70,12 @@ hidden = 1 /datum/category_item/autolathe/arms/tommymag - name = "Tommygun magazine (.45)" + name = "Tommy Gun magazine (.45)" path =/obj/item/ammo_magazine/m45tommy hidden = 1 /datum/category_item/autolathe/arms/tommydrum - name = "Tommygun drum magazine (.45)" + name = "Tommy Gun drum magazine (.45)" path =/obj/item/ammo_magazine/m45tommydrum hidden = 1 @@ -234,13 +234,13 @@ hidden = 1 /datum/category_item/autolathe/arms/tommymag - name = "Tommygun magazine (.45)" + name = "Tommy Gun magazine (.45)" path =/obj/item/ammo_magazine/m45tommy/empty category = "Arms and Ammunition" hidden = 1 /datum/category_item/autolathe/arms/tommydrum - name = "Tommygun drum magazine (.45)" + name = "Tommy Gun drum magazine (.45)" path =/obj/item/ammo_magazine/m45tommydrum/empty category = "Arms and Ammunition" hidden = 1 diff --git a/code/datums/autolathe/general_vr.dm b/code/datums/autolathe/general_vr.dm new file mode 100644 index 0000000000..0d4a58fd96 --- /dev/null +++ b/code/datums/autolathe/general_vr.dm @@ -0,0 +1,3 @@ +/datum/category_item/autolathe/general/holocollar + name = "Holo-collar" + path =/obj/item/clothing/accessory/collar/holo diff --git a/code/datums/beam.dm b/code/datums/beam.dm index 12c22430db..24f5e6c91f 100644 --- a/code/datums/beam.dm +++ b/code/datums/beam.dm @@ -59,6 +59,10 @@ return ..() /datum/beam/proc/Draw() + if(QDELETED(target) || QDELETED(origin)) + qdel(src) + return + var/Angle = round(Get_Angle(origin,target)) var/matrix/rot_matrix = matrix() @@ -102,17 +106,19 @@ //Position the effect so the beam is one continous line var/a if(abs(Pixel_x)>32) - a = Pixel_x > 0 ? round(Pixel_x/32) : Ceiling(Pixel_x/32) + a = Pixel_x > 0 ? round(Pixel_x/32) : CEILING(Pixel_x/32, 1) X.x += a Pixel_x %= 32 if(abs(Pixel_y)>32) - a = Pixel_y > 0 ? round(Pixel_y/32) : Ceiling(Pixel_y/32) + a = Pixel_y > 0 ? round(Pixel_y/32) : CEILING(Pixel_y/32, 1) X.y += a Pixel_y %= 32 X.pixel_x = Pixel_x X.pixel_y = Pixel_y + X.on_drawn() + /obj/effect/ebeam mouse_opacity = 0 anchored = TRUE @@ -127,10 +133,53 @@ /obj/effect/ebeam/singularity_act() return +// Called when the beam datum finishes drawing and the ebeam object is placed correctly. +/obj/effect/ebeam/proc/on_drawn() + return + /obj/effect/ebeam/deadly/Crossed(atom/A) ..() A.ex_act(1) +// 'Reactive' beam parts do something when touched or stood in. +/obj/effect/ebeam/reactive + +/obj/effect/ebeam/reactive/Initialize() + START_PROCESSING(SSobj, src) + return ..() + +/obj/effect/ebeam/reactive/Destroy() + STOP_PROCESSING(SSobj, src) + return ..() + +/obj/effect/ebeam/reactive/on_drawn() + for(var/A in loc) + on_contact(A) + +/obj/effect/ebeam/reactive/Crossed(atom/A) + ..() + on_contact(A) + +/obj/effect/ebeam/reactive/process() + for(var/A in loc) + on_contact(A) + +// Override for things to do when someone touches the beam. +/obj/effect/ebeam/reactive/proc/on_contact(atom/movable/AM) + return + + +// Shocks things that touch it. +/obj/effect/ebeam/reactive/electric + var/shock_amount = 25 // Be aware that high numbers may stun and result in dying due to not being able to get out of the beam. + +/obj/effect/ebeam/reactive/electric/on_contact(atom/movable/AM) + if(isliving(AM)) + var/mob/living/L = AM + L.inflict_shock_damage(shock_amount) + + + /atom/proc/Beam(atom/BeamTarget,icon_state="b_beam",icon='icons/effects/beam.dmi',time=50, maxdistance=10,beam_type=/obj/effect/ebeam,beam_sleep_time=3) var/datum/beam/newbeam = new(src,BeamTarget,icon,icon_state,time,maxdistance,beam_type,beam_sleep_time) spawn(0) diff --git a/code/datums/browser.dm b/code/datums/browser.dm index 577698532e..ea2f4feec2 100644 --- a/code/datums/browser.dm +++ b/code/datums/browser.dm @@ -105,6 +105,10 @@ "} /datum/browser/proc/open(var/use_onclose = 1) + if(isnull(window_id)) //null check because this can potentially nuke goonchat + WARNING("Browser [title] tried to open with a null ID") + to_chat(user, "The [title] browser you tried to open failed a sanity check! Please report this on github!") + return var/window_size = "" if (width && height) window_size = "size=[width]x[height];" @@ -112,9 +116,6 @@ if (use_onclose) onclose(user, window_id, ref) -/datum/browser/proc/close() - user << browse(null, "window=[window_id]") - // This will allow you to show an icon in the browse window // This is added to mob so that it can be used without a reference to the browser object // There is probably a better place for this... @@ -157,12 +158,12 @@ //world << "OnClose [user]: [windowid] : ["on-close=\".windowclose [param]\""]" - // the on-close client verb // called when a browser popup window is closed after registering with proc/onclose() // if a valid atom reference is supplied, call the atom's Topic() with "close=1" // otherwise, just reset the client mob's machine var. // + /client/verb/windowclose(var/atomref as text) set hidden = 1 // hide this verb from the user's panel set name = ".windowclose" // no autocomplete on cmd line @@ -182,3 +183,198 @@ //world << "[src] was [src.mob.machine], setting to null" src.mob.unset_machine() return + +/datum/browser/proc/close() + if(!isnull(window_id))//null check because this can potentially nuke goonchat + user << browse(null, "window=[window_id]") + else + WARNING("Browser [title] tried to close with a null ID") + +/datum/browser/modal/alert/New(User,Message,Title,Button1="Ok",Button2,Button3,StealFocus = 1,Timeout=6000) + if (!User) + return + + var/output = {"
[Message]

+
+ [Button1]"} + + if (Button2) + output += {"[Button2]"} + + if (Button3) + output += {"[Button3]"} + + output += {"
"} + + ..(User, ckey("[User]-[Message]-[Title]-[world.time]-[rand(1,10000)]"), Title, 350, 150, src, StealFocus, Timeout) + set_content(output) + +/datum/browser/modal/alert/Topic(href,href_list) + if (href_list["close"] || !user || !user.client) + opentime = 0 + return + if (href_list["button"]) + var/button = text2num(href_list["button"]) + if (button <= 3 && button >= 1) + selectedbutton = button + opentime = 0 + close() + +//designed as a drop in replacement for alert(); functions the same. (outside of needing User specified) +/proc/tgalert(var/mob/User, Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1, Timeout = 6000) + if (!User) + User = usr + switch(askuser(User, Message, Title, Button1, Button2, Button3, StealFocus, Timeout)) + if (1) + return Button1 + if (2) + return Button2 + if (3) + return Button3 + +//Same shit, but it returns the button number, could at some point support unlimited button amounts. +/proc/askuser(var/mob/User,Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1, Timeout = 6000) + if (!istype(User)) + if (istype(User, /client/)) + var/client/C = User + User = C.mob + else + return + var/datum/browser/modal/alert/A = new(User, Message, Title, Button1, Button2, Button3, StealFocus, Timeout) + A.open() + A.wait() + if (A.selectedbutton) + return A.selectedbutton + +/datum/browser/modal + var/opentime = 0 + var/timeout + var/selectedbutton = 0 + var/stealfocus + +/datum/browser/modal/New(nuser, nwindow_id, ntitle = 0, nwidth = 0, nheight = 0, var/atom/nref = null, StealFocus = 1, Timeout = 6000) + ..() + stealfocus = StealFocus + if (!StealFocus) + window_options += "focus=false;" + timeout = Timeout + + +/datum/browser/modal/close() + .=..() + opentime = 0 + +/datum/browser/modal/open() + set waitfor = 0 + opentime = world.time + + if (stealfocus) + . = ..(use_onclose = 1) + else + var/focusedwindow = winget(user, null, "focus") + . = ..(use_onclose = 1) + + //waits for the window to show up client side before attempting to un-focus it + //winexists sleeps until it gets a reply from the client, so we don't need to bother sleeping + for (var/i in 1 to 10) + if (user && winexists(user, window_id)) + if (focusedwindow) + winset(user, focusedwindow, "focus=true") + else + winset(user, "mapwindow", "focus=true") + break + if (timeout) + addtimer(CALLBACK(src, .proc/close), timeout) + +/datum/browser/modal/proc/wait() + while (opentime && selectedbutton <= 0 && (!timeout || opentime+timeout > world.time)) + stoplag(1) + +/datum/browser/modal/listpicker + var/valueslist = list() + +/datum/browser/modal/listpicker/New(User,Message,Title,Button1="Ok",Button2,Button3,StealFocus = 1, Timeout = FALSE,list/values,inputtype="checkbox", width, height, slidecolor) + if (!User) + return + + var/output = {"
    "} + if (inputtype == "checkbox" || inputtype == "radio") + for (var/i in values) + var/div_slider = slidecolor + if(!i["allowed_edit"]) + div_slider = "locked" + output += {"
  • + +
  • "} + else + for (var/i in values) + output += {"
  • +
  • "} + output += {"
+ "} + + if (Button2) + output += {""} + + if (Button3) + output += {""} + + output += {"
"} + ..(User, ckey("[User]-[Message]-[Title]-[world.time]-[rand(1,10000)]"), Title, width, height, src, StealFocus, Timeout) + set_content(output) + +/datum/browser/modal/listpicker/Topic(href,href_list) + if (href_list["close"] || !user || !user.client) + opentime = 0 + return + if (href_list["button"]) + var/button = text2num(href_list["button"]) + if (button <= 3 && button >= 1) + selectedbutton = button + for (var/item in href_list) + switch(item) + if ("close", "button", "src") + continue + else + valueslist[item] = href_list[item] + opentime = 0 + close() + +/proc/presentpicker(var/mob/User,Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1,Timeout = 6000,list/values, inputtype = "checkbox", width, height, slidecolor) + if (!istype(User)) + if (istype(User, /client/)) + var/client/C = User + User = C.mob + else + return + var/datum/browser/modal/listpicker/A = new(User, Message, Title, Button1, Button2, Button3, StealFocus,Timeout, values, inputtype, width, height, slidecolor) + A.open() + A.wait() + if (A.selectedbutton) + return list("button" = A.selectedbutton, "values" = A.valueslist) + +/proc/input_bitfield(var/mob/User, title, bitfield, current_value, nwidth = 350, nheight = 350, nslidecolor, allowed_edit_list = null) + if (!User || !(bitfield in GLOB.bitfields)) + return + var/list/pickerlist = list() + for (var/i in GLOB.bitfields[bitfield]) + var/can_edit = 1 + if(!isnull(allowed_edit_list) && !(allowed_edit_list & GLOB.bitfields[bitfield][i])) + can_edit = 0 + if (current_value & GLOB.bitfields[bitfield][i]) + pickerlist += list(list("checked" = 1, "value" = GLOB.bitfields[bitfield][i], "name" = i, "allowed_edit" = can_edit)) + else + pickerlist += list(list("checked" = 0, "value" = GLOB.bitfields[bitfield][i], "name" = i, "allowed_edit" = can_edit)) + var/list/result = presentpicker(User, "", title, Button1="Save", Button2 = "Cancel", Timeout=FALSE, values = pickerlist, width = nwidth, height = nheight, slidecolor = nslidecolor) + if (islist(result)) + if (result["button"] == 2) // If the user pressed the cancel button + return + . = 0 + for (var/flag in result["values"]) + . |= GLOB.bitfields[bitfield][flag] + else + return diff --git a/code/datums/callback.dm b/code/datums/callback.dm index a92a715ece..74d5719ce2 100644 --- a/code/datums/callback.dm +++ b/code/datums/callback.dm @@ -166,7 +166,7 @@ // Use sparingly /world/proc/PushUsr(mob/M, datum/callback/CB) var/temp = usr - testing("PushUsr() in use") +// testing("PushUsr() in use") usr = M . = CB.Invoke() usr = temp diff --git a/code/datums/datum.dm b/code/datums/datum.dm index fd58220657..61eb4c6953 100644 --- a/code/datums/datum.dm +++ b/code/datums/datum.dm @@ -5,8 +5,9 @@ /datum var/gc_destroyed //Time when this object was destroyed. + var/list/active_timers //for SStimer var/weakref/weakref // Holder of weakref instance pointing to this datum - var/is_processing = FALSE // If this datum is in an MC processing list, this will be set to its name. + var/datum_flags = NONE #ifdef TESTING var/tmp/running_find_references @@ -17,7 +18,18 @@ // This should be overridden to remove all references pointing to the object being destroyed. // Return the appropriate QDEL_HINT; in most cases this is QDEL_HINT_QUEUE. /datum/proc/Destroy(force=FALSE) + + //clear timers + var/list/timers = active_timers + active_timers = null + for(var/thing in timers) + var/datum/timedevent/timer = thing + if (timer.spent) + continue + qdel(timer) + weakref = null // Clear this reference to ensure it's kept for as brief duration as possible. + tag = null - GLOB.nanomanager.close_uis(src) + SSnanoui.close_uis(src) return QDEL_HINT_QUEUE diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm new file mode 100644 index 0000000000..aa28473fa3 --- /dev/null +++ b/code/datums/datumvars.dm @@ -0,0 +1,68 @@ +/datum/proc/CanProcCall(procname) + return TRUE + +/datum/proc/can_vv_get(var_name) + return TRUE + +/datum/proc/vv_edit_var(var_name, var_value) //called whenever a var is edited + if(var_name == NAMEOF(src, vars) || var_name == NAMEOF(src, parent_type)) + return FALSE + vars[var_name] = var_value + datum_flags |= DF_VAR_EDITED + return TRUE + +/datum/proc/vv_get_var(var_name) + switch(var_name) + if ("vars") + return debug_variable(var_name, list(), 0, src) + return debug_variable(var_name, vars[var_name], 0, src) + +//please call . = ..() first and append to the result, that way parent items are always at the top and child items are further down +//add separaters by doing . += "---" +/datum/proc/vv_get_dropdown() + . = list() + VV_DROPDOWN_OPTION("", "---") + VV_DROPDOWN_OPTION(VV_HK_CALLPROC, "Call Proc") + VV_DROPDOWN_OPTION(VV_HK_MARK, "Mark Object") + VV_DROPDOWN_OPTION(VV_HK_DELETE, "Delete") + VV_DROPDOWN_OPTION(VV_HK_EXPOSE, "Show VV To Player") + +//This proc is only called if everything topic-wise is verified. The only verifications that should happen here is things like permission checks! +//href_list is a reference, modifying it in these procs WILL change the rest of the proc in topic.dm of admin/view_variables! +/datum/proc/vv_do_topic(list/href_list) + if(!usr || !usr.client.holder) + return //This is VV, not to be called by anything else. + IF_VV_OPTION(VV_HK_EXPOSE) + if(!check_rights(R_ADMIN, FALSE)) + return + var/value = usr.client.vv_get_value(VV_CLIENT) + if (value["class"] != VV_CLIENT) + return + var/client/C = value["value"] + if (!C) + return + var/prompt = alert("Do you want to grant [C] access to view this VV window? (they will not be able to edit or change anysrc nor open nested vv windows unless they themselves are an admin)", "Confirm", "Yes", "No") + if (prompt != "Yes" || !usr.client) + return + message_admins("[key_name_admin(usr)] Showed [key_name_admin(C)] a VV window") + log_admin("Admin [key_name(usr)] Showed [key_name(C)] a VV window of a [src]") + to_chat(C, "[usr.client.holder.fakekey ? "an Administrator" : "[usr.client.key]"] has granted you access to view a View Variables window") + C.debug_variables(src) + IF_VV_OPTION(VV_HK_DELETE) + if(!check_rights(R_DEBUG)) + return + usr.client.admin_delete(src) + if (isturf(src)) // show the turf that took its place + usr.client.debug_variables(src) + IF_VV_OPTION(VV_HK_MARK) + usr.client.mark_datum(src) + IF_VV_OPTION(VV_HK_CALLPROC) + usr.client.callproc_datum(src) + +/datum/proc/vv_get_header() + . = list() + if(("name" in vars) && !isatom(src)) + . += "[vars["name"]]
" + +/datum/proc/on_reagent_change(changetype) + return diff --git a/code/datums/ghost_query.dm b/code/datums/ghost_query.dm index d041558a0c..2f7942a9b2 100644 --- a/code/datums/ghost_query.dm +++ b/code/datums/ghost_query.dm @@ -106,6 +106,13 @@ check_bans = list("AI", "Cyborg", "Syndicate") cutoff_number = 1 +/datum/ghost_query/borer + role_name = "Cortical Borer" + question = "A cortical borer has just been created on the facility. Would you like to play as them?" + be_special_flag = BE_ALIEN + check_bans = list("Syndicate", "Borer") + cutoff_number = 1 + // Surface stuff. /datum/ghost_query/lost_drone role_name = "Lost Drone" diff --git a/code/datums/helper_datums/global_iterator.dm b/code/datums/helper_datums/global_iterator.dm index d511b5d233..2ebab5582d 100644 --- a/code/datums/helper_datums/global_iterator.dm +++ b/code/datums/helper_datums/global_iterator.dm @@ -1,3 +1,7 @@ +/* + DO NOT USE THIS. THIS IS BEING DEPRECATED BY PROCESSING SUBSYSTEMS (controllers/subsystems/processing) AND TIMERS. +*/ + /* README: @@ -109,9 +113,6 @@ Data storage vars: CRASH("The global_iterator loop \ref[src] failed to terminate in designated timeframe. This may be caused by server lagging.") return 1 - proc/process() - return - proc/active() return control_switch diff --git a/code/datums/looping_sounds/_looping_sound.dm b/code/datums/looping_sounds/_looping_sound.dm new file mode 100644 index 0000000000..99af50bf42 --- /dev/null +++ b/code/datums/looping_sounds/_looping_sound.dm @@ -0,0 +1,111 @@ +/* + output_atoms (list of atoms) The destination(s) for the sounds + + mid_sounds (list or soundfile) Since this can be either a list or a single soundfile you can have random sounds. May contain further lists but must contain a soundfile at the end. + mid_length (num) The length to wait between playing mid_sounds + + start_sound (soundfile) Played before starting the mid_sounds loop + start_length (num) How long to wait before starting the main loop after playing start_sound + + end_sound (soundfile) The sound played after the main loop has concluded + + chance (num) Chance per loop to play a mid_sound + volume (num) Sound output volume + muted (bool) Private. Used to stop the sound loop. + max_loops (num) The max amount of loops to run for. + direct (bool) If true plays directly to provided atoms instead of from them + opacity_check (bool) If true, things behind walls/opaque things won't hear the sounds. + pref_check (type) If set to a /datum/client_preference type, will check if the hearer has that preference active before playing it to them. +*/ +/datum/looping_sound + var/list/atom/output_atoms + var/mid_sounds + var/mid_length + var/start_sound + var/start_length + var/end_sound + var/chance + var/volume = 100 + var/max_loops + var/direct + var/opacity_check + var/pref_check + + var/timerid + +/datum/looping_sound/New(list/_output_atoms=list(), start_immediately=FALSE, _direct=FALSE) + if(!mid_sounds) + WARNING("A looping sound datum was created without sounds to play.") + return + + output_atoms = _output_atoms + direct = _direct + + if(start_immediately) + start() + +/datum/looping_sound/Destroy() + stop() + output_atoms = null + return ..() + +/datum/looping_sound/proc/start(atom/add_thing) + if(add_thing) + output_atoms |= add_thing + if(timerid) + return + on_start() + +/datum/looping_sound/proc/stop(atom/remove_thing) + if(remove_thing) + output_atoms -= remove_thing + if(!timerid) + return + on_stop() + deltimer(timerid) + timerid = null + +/datum/looping_sound/proc/sound_loop(starttime) + if(max_loops && world.time >= starttime + mid_length * max_loops) + stop() + return + if(!chance || prob(chance)) + play(get_sound(starttime)) + if(!timerid) + timerid = addtimer(CALLBACK(src, .proc/sound_loop, world.time), mid_length, TIMER_STOPPABLE | TIMER_LOOP) + +/datum/looping_sound/proc/play(soundfile) + var/list/atoms_cache = output_atoms + var/sound/S = sound(soundfile) + if(direct) + S.channel = open_sound_channel() + S.volume = volume + for(var/i in 1 to atoms_cache.len) + var/atom/thing = atoms_cache[i] + if(direct) + if(ismob(thing)) + var/mob/M = thing + if(!M.is_preference_enabled(pref_check)) + continue + SEND_SOUND(thing, S) + else + playsound(thing, S, volume, ignore_walls = !opacity_check, preference = pref_check) + +/datum/looping_sound/proc/get_sound(starttime, _mid_sounds) + if(!_mid_sounds) + . = mid_sounds + else + . = _mid_sounds + while(!isfile(.) && !isnull(.)) + . = pickweight(.) + +/datum/looping_sound/proc/on_start() + var/start_wait = 1 // On TG this is 0, however it needs to be 1 to work around an issue. + if(start_sound) + play(start_sound) + start_wait = start_length + addtimer(CALLBACK(src, .proc/sound_loop), start_wait) + +/datum/looping_sound/proc/on_stop() + if(end_sound) + play(end_sound) \ No newline at end of file diff --git a/code/datums/looping_sounds/item_sounds.dm b/code/datums/looping_sounds/item_sounds.dm new file mode 100644 index 0000000000..4619acd3b5 --- /dev/null +++ b/code/datums/looping_sounds/item_sounds.dm @@ -0,0 +1,29 @@ +/datum/looping_sound/geiger + mid_sounds = list( + list('sound/items/geiger/low1.ogg'=1, 'sound/items/geiger/low2.ogg'=1, 'sound/items/geiger/low3.ogg'=1, 'sound/items/geiger/low4.ogg'=1), + list('sound/items/geiger/med1.ogg'=1, 'sound/items/geiger/med2.ogg'=1, 'sound/items/geiger/med3.ogg'=1, 'sound/items/geiger/med4.ogg'=1), + list('sound/items/geiger/high1.ogg'=1, 'sound/items/geiger/high2.ogg'=1, 'sound/items/geiger/high3.ogg'=1, 'sound/items/geiger/high4.ogg'=1), + list('sound/items/geiger/ext1.ogg'=1, 'sound/items/geiger/ext2.ogg'=1, 'sound/items/geiger/ext3.ogg'=1, 'sound/items/geiger/ext4.ogg'=1) + ) + mid_length = 1 SECOND + volume = 25 + var/last_radiation + +/datum/looping_sound/geiger/get_sound(starttime) + var/danger + switch(last_radiation) + if(0 to RAD_LEVEL_MODERATE) + danger = 1 + if(RAD_LEVEL_MODERATE to RAD_LEVEL_HIGH) + danger = 2 + if(RAD_LEVEL_HIGH to RAD_LEVEL_VERY_HIGH) + danger = 3 + if(RAD_LEVEL_VERY_HIGH to INFINITY) + danger = 4 + else + return null + return ..(starttime, mid_sounds[danger]) + +/datum/looping_sound/geiger/stop() + . = ..() + last_radiation = 0 diff --git a/code/datums/looping_sounds/machinery_sounds.dm b/code/datums/looping_sounds/machinery_sounds.dm new file mode 100644 index 0000000000..8b927b3a54 --- /dev/null +++ b/code/datums/looping_sounds/machinery_sounds.dm @@ -0,0 +1,46 @@ +/datum/looping_sound/showering + start_sound = 'sound/machines/shower/shower_start.ogg' + start_length = 2 + mid_sounds = list('sound/machines/shower/shower_mid1.ogg'=1,'sound/machines/shower/shower_mid2.ogg'=1,'sound/machines/shower/shower_mid3.ogg'=1) + mid_length = 10 + end_sound = 'sound/machines/shower/shower_end.ogg' + volume = 20 + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/datum/looping_sound/supermatter + mid_sounds = list('sound/machines/sm/supermatter1.ogg'=1,'sound/machines/sm/supermatter2.ogg'=1,'sound/machines/sm/supermatter3.ogg'=1) + mid_length = 10 + volume = 1 + pref_check = /datum/client_preference/supermatter_hum + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/datum/looping_sound/generator + start_sound = 'sound/machines/generator/generator_start.ogg' + start_length = 4 + mid_sounds = list('sound/machines/generator/generator_mid1.ogg'=1, 'sound/machines/generator/generator_mid2.ogg'=1, 'sound/machines/generator/generator_mid3.ogg'=1) + mid_length = 4 + end_sound = 'sound/machines/generator/generator_end.ogg' + volume = 40 + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +/datum/looping_sound/deep_fryer + start_sound = 'sound/machines/fryer/deep_fryer_immerse.ogg' //my immersions + start_length = 10 + mid_sounds = list('sound/machines/fryer/deep_fryer_1.ogg' = 1, 'sound/machines/fryer/deep_fryer_2.ogg' = 1) + mid_length = 2 + end_sound = 'sound/machines/fryer/deep_fryer_emerge.ogg' + volume = 15 + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/datum/looping_sound/microwave + start_sound = 'sound/machines/microwave/microwave-start.ogg' + start_length = 10 + mid_sounds = list('sound/machines/microwave/microwave-mid1.ogg'=10, 'sound/machines/microwave/microwave-mid2.ogg'=1) + mid_length = 10 + end_sound = 'sound/machines/microwave/microwave-end.ogg' + volume = 90 \ No newline at end of file diff --git a/code/datums/looping_sounds/weather_sounds.dm b/code/datums/looping_sounds/weather_sounds.dm new file mode 100644 index 0000000000..106c25643a --- /dev/null +++ b/code/datums/looping_sounds/weather_sounds.dm @@ -0,0 +1,79 @@ +/datum/looping_sound/weather + pref_check = /datum/client_preference/weather_sounds + +/datum/looping_sound/weather/outside_blizzard + mid_sounds = list( + 'sound/effects/weather/snowstorm/outside/active_mid1.ogg' = 1, + 'sound/effects/weather/snowstorm/outside/active_mid1.ogg' = 1, + 'sound/effects/weather/snowstorm/outside/active_mid1.ogg' = 1 + ) + mid_length = 8 SECONDS + start_sound = 'sound/effects/weather/snowstorm/outside/active_start.ogg' + start_length = 13 SECONDS + end_sound = 'sound/effects/weather/snowstorm/outside/active_end.ogg' + volume = 80 + +/datum/looping_sound/weather/inside_blizzard + mid_sounds = list( + 'sound/effects/weather/snowstorm/inside/active_mid1.ogg' = 1, + 'sound/effects/weather/snowstorm/inside/active_mid2.ogg' = 1, + 'sound/effects/weather/snowstorm/inside/active_mid3.ogg' = 1 + ) + mid_length = 8 SECONDS + start_sound = 'sound/effects/weather/snowstorm/inside/active_start.ogg' + start_length = 13 SECONDS + end_sound = 'sound/effects/weather/snowstorm/inside/active_end.ogg' + volume = 60 + +/datum/looping_sound/weather/outside_snow + mid_sounds = list( + 'sound/effects/weather/snowstorm/outside/weak_mid1.ogg' = 1, + 'sound/effects/weather/snowstorm/outside/weak_mid2.ogg' = 1, + 'sound/effects/weather/snowstorm/outside/weak_mid3.ogg' = 1 + ) + mid_length = 8 SECONDS + start_sound = 'sound/effects/weather/snowstorm/outside/weak_start.ogg' + start_length = 13 SECONDS + end_sound = 'sound/effects/weather/snowstorm/outside/weak_end.ogg' + volume = 50 + +/datum/looping_sound/weather/inside_snow + mid_sounds = list( + 'sound/effects/weather/snowstorm/inside/weak_mid1.ogg' = 1, + 'sound/effects/weather/snowstorm/inside/weak_mid2.ogg' = 1, + 'sound/effects/weather/snowstorm/inside/weak_mid3.ogg' = 1 + ) + mid_length = 8 SECONDS + start_sound = 'sound/effects/weather/snowstorm/inside/weak_start.ogg' + start_length = 13 SECONDS + end_sound = 'sound/effects/weather/snowstorm/inside/weak_end.ogg' + volume = 30 + +/datum/looping_sound/weather/wind + mid_sounds = list( + 'sound/effects/weather/wind/wind_2_1.ogg' = 1, + 'sound/effects/weather/wind/wind_2_2.ogg' = 1, + 'sound/effects/weather/wind/wind_3_1.ogg' = 1, + 'sound/effects/weather/wind/wind_4_1.ogg' = 1, + 'sound/effects/weather/wind/wind_4_2.ogg' = 1, + 'sound/effects/weather/wind/wind_5_1.ogg' = 1 + ) + mid_length = 10 SECONDS // The lengths for the files vary, but the longest is ten seconds, so this will make it sound like intermittent wind. + volume = 50 + +// Don't have special sounds so we just make it quieter indoors. +/datum/looping_sound/weather/wind/indoors + volume = 30 + +/datum/looping_sound/weather/rain + mid_sounds = list( + 'sound/effects/weather/acidrain_mid.ogg' = 1 + ) + mid_length = 15 SECONDS // The lengths for the files vary, but the longest is ten seconds, so this will make it sound like intermittent wind. + start_sound = 'sound/effects/weather/acidrain_start.ogg' + start_length = 13 SECONDS + end_sound = 'sound/effects/weather/acidrain_end.ogg' + volume = 50 + +/datum/looping_sound/weather/rain/indoors + volume = 30 \ No newline at end of file diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 5204964bda..67cf23a3cb 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -85,7 +85,7 @@ current.verbs -= /datum/changeling/proc/EvolutionMenu current.mind = null - GLOB.nanomanager.user_transferred(current, new_character) // transfer active NanoUI instances to new user + SSnanoui.user_transferred(current, new_character) // transfer active NanoUI instances to new user if(new_character.mind) //remove any mind currently in our new body's mind variable new_character.mind.current = null @@ -502,7 +502,7 @@ if(!mind.assigned_role) mind.assigned_role = USELESS_JOB //defualt //VOREStation Edit - Visitor not Assistant //slime -/mob/living/simple_animal/slime/mind_initialize() +/mob/living/simple_mob/slime/mind_initialize() . = ..() mind.assigned_role = "slime" @@ -527,29 +527,30 @@ mind.special_role = "" //Animals -/mob/living/simple_animal/mind_initialize() +/mob/living/simple_mob/mind_initialize() . = ..() - mind.assigned_role = "Animal" + mind.assigned_role = "Simple Mob" -/mob/living/simple_animal/corgi/mind_initialize() +/mob/living/simple_mob/animal/passive/dog/corgi/mind_initialize() . = ..() mind.assigned_role = "Corgi" -/mob/living/simple_animal/shade/mind_initialize() +/mob/living/simple_mob/construct/shade/mind_initialize() . = ..() mind.assigned_role = "Shade" + mind.special_role = "Cultist" -/mob/living/simple_animal/construct/builder/mind_initialize() +/mob/living/simple_mob/construct/artificer/mind_initialize() . = ..() mind.assigned_role = "Artificer" mind.special_role = "Cultist" -/mob/living/simple_animal/construct/wraith/mind_initialize() +/mob/living/simple_mob/construct/wraith/mind_initialize() . = ..() mind.assigned_role = "Wraith" mind.special_role = "Cultist" -/mob/living/simple_animal/construct/armoured/mind_initialize() +/mob/living/simple_mob/construct/juggernaut/mind_initialize() . = ..() mind.assigned_role = "Juggernaut" mind.special_role = "Cultist" diff --git a/code/datums/observation/_debug.dm b/code/datums/observation/_debug.dm index 2f882929cf..5b805aa930 100644 --- a/code/datums/observation/_debug.dm +++ b/code/datums/observation/_debug.dm @@ -1,7 +1,6 @@ /**************** * Debug Support * ****************/ -var/datum/all_observable_events/all_observable_events = new() /datum/all_observable_events var/list/events diff --git a/code/datums/observation/destroyed.dm b/code/datums/observation/destroyed.dm index 6a65300a25..ff8778645c 100644 --- a/code/datums/observation/destroyed.dm +++ b/code/datums/observation/destroyed.dm @@ -5,11 +5,10 @@ // // Arguments that the called proc should expect: // /datum/destroyed_instance: The instance that was destroyed. -var/decl/observ/destroyed/destroyed_event = new() /decl/observ/destroyed name = "Destroyed" /datum/Destroy() - destroyed_event.raise_event(src) + GLOB.destroyed_event.raise_event(src) . = ..() diff --git a/code/datums/observation/observation.dm b/code/datums/observation/observation.dm index 32a96871e6..db1f9e0d6e 100644 --- a/code/datums/observation/observation.dm +++ b/code/datums/observation/observation.dm @@ -63,7 +63,7 @@ var/list/global_listeners = list() // Associative list of instances that listen to all events of this type (as opposed to events belonging to a specific source) and the proc to call. /decl/observ/New() - all_observable_events.events += src + GLOB.all_observable_events.events += src . = ..() /decl/observ/proc/is_listening(var/event_source, var/datum/listener, var/proc_call) diff --git a/code/datums/observation/task_triggered.dm b/code/datums/observation/task_triggered.dm deleted file mode 100644 index 0c04ef2ead..0000000000 --- a/code/datums/observation/task_triggered.dm +++ /dev/null @@ -1,13 +0,0 @@ -// -// Observer Pattern Implementation: Scheduled task triggered -// Registration type: /datum/scheduled_task -// -// Raised when: When a scheduled task reaches its trigger time. -// -// Arguments that the called proc should expect: -// /datum/scheduled_task/task: The task that reached its trigger time. -var/decl/observ/task_triggered/task_triggered_event = new() - -/decl/observ/task_triggered - name = "Task Triggered" - expected_type = /datum/scheduled_task diff --git a/code/datums/observation/z_moved.dm b/code/datums/observation/z_moved.dm new file mode 100644 index 0000000000..63b89ba0da --- /dev/null +++ b/code/datums/observation/z_moved.dm @@ -0,0 +1,16 @@ +// Observer Pattern Implementation: Z_Moved +// Registration type: /atom/movable +// +// Raised when: An /atom/movable instance has changed z-levels by any means. +// +// Arguments that the called proc should expect: +// /atom/movable/moving_instance: The instance that moved +// old_z: The z number before the move. +// new_z: The z number after the move. + + +GLOBAL_DATUM_INIT(z_moved_event, /decl/observ/z_moved, new) + +/decl/observ/z_moved + name = "Z_Moved" + expected_type = /atom/movable diff --git a/code/datums/observation/~cleanup.dm b/code/datums/observation/~cleanup.dm index eb6ccceef8..825902d483 100644 --- a/code/datums/observation/~cleanup.dm +++ b/code/datums/observation/~cleanup.dm @@ -1,6 +1,6 @@ -var/list/global_listen_count = list() -var/list/event_sources_count = list() -var/list/event_listen_count = list() +GLOBAL_LIST_EMPTY(global_listen_count) +GLOBAL_LIST_EMPTY(event_sources_count) +GLOBAL_LIST_EMPTY(event_listen_count) /decl/observ/destroyed/raise_event() . = ..() @@ -8,39 +8,39 @@ var/list/event_listen_count = list() return var/source = args[1] - if(global_listen_count[source]) - cleanup_global_listener(source, global_listen_count[source]) - if(event_sources_count[source]) - cleanup_source_listeners(source, event_sources_count[source]) - if(event_listen_count[source]) - cleanup_event_listener(source, event_listen_count[source]) + if(GLOB.global_listen_count[source]) + cleanup_global_listener(source, GLOB.global_listen_count[source]) + if(GLOB.event_sources_count[source]) + cleanup_source_listeners(source, GLOB.event_sources_count[source]) + if(GLOB.event_listen_count[source]) + cleanup_event_listener(source, GLOB.event_listen_count[source]) /decl/observ/register(var/datum/event_source, var/datum/listener, var/proc_call) . = ..() if(.) - event_sources_count[event_source] += 1 - event_listen_count[listener] += 1 + GLOB.event_sources_count[event_source] += 1 + GLOB.event_listen_count[listener] += 1 /decl/observ/unregister(var/datum/event_source, var/datum/listener, var/proc_call) . = ..() if(.) - event_sources_count[event_source] -= 1 - event_listen_count[listener] -= 1 + GLOB.event_sources_count[event_source] -= 1 + GLOB.event_listen_count[listener] -= 1 /decl/observ/register_global(var/datum/listener, var/proc_call) . = ..() if(.) - global_listen_count[listener] += 1 + GLOB.global_listen_count[listener] += 1 /decl/observ/unregister_global(var/datum/listener, var/proc_call) . = ..() if(.) - global_listen_count[listener] -= 1 + GLOB.global_listen_count[listener] -= 1 /decl/observ/destroyed/proc/cleanup_global_listener(listener, listen_count) - global_listen_count -= listener - for(var/entry in all_observable_events.events) + GLOB.global_listen_count -= listener + for(var/entry in GLOB.all_observable_events.events) var/decl/observ/event = entry if(event.unregister_global(listener)) log_debug("[event] - [listener] was deleted while still registered to global events.") @@ -48,8 +48,8 @@ var/list/event_listen_count = list() return /decl/observ/destroyed/proc/cleanup_source_listeners(event_source, source_listener_count) - event_sources_count -= event_source - for(var/entry in all_observable_events.events) + GLOB.event_sources_count -= event_source + for(var/entry in GLOB.all_observable_events.events) var/decl/observ/event = entry var/proc_owners = event.event_sources[event_source] if(proc_owners) @@ -60,11 +60,11 @@ var/list/event_listen_count = list() return /decl/observ/destroyed/proc/cleanup_event_listener(listener, listener_count) - event_listen_count -= listener - for(var/entry in all_observable_events.events) + GLOB.event_listen_count -= listener + for(var/entry in GLOB.all_observable_events.events) var/decl/observ/event = entry for(var/event_source in event.event_sources) if(event.unregister(event_source, listener)) log_debug("[event] - [listener] was deleted while still listening to [event_source].") if(!(--listener_count)) - return + return \ No newline at end of file diff --git a/code/datums/position_point_vector.dm b/code/datums/position_point_vector.dm new file mode 100644 index 0000000000..c5c392e126 --- /dev/null +++ b/code/datums/position_point_vector.dm @@ -0,0 +1,227 @@ +//Designed for things that need precision trajectories like projectiles. +//Don't use this for anything that you don't absolutely have to use this with (like projectiles!) because it isn't worth using a datum unless you need accuracy down to decimal places in pixels. + +//You might see places where it does - 16 - 1. This is intentionally 17 instead of 16, because of how byond's tiles work and how not doing it will result in rounding errors like things getting put on the wrong turf. + +#define RETURN_PRECISE_POSITION(A) new /datum/position(A) +#define RETURN_PRECISE_POINT(A) new /datum/point(A) + +#define RETURN_POINT_VECTOR(ATOM, ANGLE, SPEED) {new /datum/point/vector(ATOM, null, null, null, null, ANGLE, SPEED)} +#define RETURN_POINT_VECTOR_INCREMENT(ATOM, ANGLE, SPEED, AMT) {new /datum/point/vector(ATOM, null, null, null, null, ANGLE, SPEED, AMT)} + +/datum/position //For positions with map x/y/z and pixel x/y so you don't have to return lists. Could use addition/subtraction in the future I guess. + var/x = 0 + var/y = 0 + var/z = 0 + var/pixel_x = 0 + var/pixel_y = 0 + +/datum/position/proc/valid() + return x && y && z && !isnull(pixel_x) && !isnull(pixel_y) + +/datum/position/New(_x = 0, _y = 0, _z = 0, _pixel_x = 0, _pixel_y = 0) //first argument can also be a /datum/point. + if(istype(_x, /datum/point)) + var/datum/point/P = _x + var/turf/T = P.return_turf() + _x = T.x + _y = T.y + _z = T.z + _pixel_x = P.return_px() + _pixel_y = P.return_py() + else if(istype(_x, /atom)) + var/atom/A = _x + _x = A.x + _y = A.y + _z = A.z + _pixel_x = A.pixel_x + _pixel_y = A.pixel_y + x = _x + y = _y + z = _z + pixel_x = _pixel_x + pixel_y = _pixel_y + +/datum/position/proc/return_turf() + return locate(x, y, z) + +/datum/position/proc/return_px() + return pixel_x + +/datum/position/proc/return_py() + return pixel_y + +/datum/position/proc/return_point() + return new /datum/point(src) + +/proc/point_midpoint_points(datum/point/a, datum/point/b) //Obviously will not support multiZ calculations! Same for the two below. + var/datum/point/P = new + P.x = a.x + (b.x - a.x) / 2 + P.y = a.y + (b.y - a.y) / 2 + P.z = a.z + return P + +/proc/pixel_length_between_points(datum/point/a, datum/point/b) + return sqrt(((b.x - a.x) ** 2) + ((b.y - a.y) ** 2)) + +/proc/angle_between_points(datum/point/a, datum/point/b) + return ATAN2((b.y - a.y), (b.x - a.x)) + +/datum/point //A precise point on the map in absolute pixel locations based on world.icon_size. Pixels are FROM THE EDGE OF THE MAP! + var/x = 0 + var/y = 0 + var/z = 0 + +/datum/point/proc/valid() + return x && y && z + +/datum/point/proc/copy_to(datum/point/p = new) + p.x = x + p.y = y + p.z = z + return p + +/datum/point/New(_x, _y, _z, _pixel_x = 0, _pixel_y = 0) //first argument can also be a /datum/position or /atom. + if(istype(_x, /datum/position)) + var/datum/position/P = _x + _x = P.x + _y = P.y + _z = P.z + _pixel_x = P.pixel_x + _pixel_y = P.pixel_y + else if(istype(_x, /atom)) + var/atom/A = _x + _x = A.x + _y = A.y + _z = A.z + _pixel_x = A.pixel_x + _pixel_y = A.pixel_y + initialize_location(_x, _y, _z, _pixel_x, _pixel_y) + +/datum/point/proc/initialize_location(tile_x, tile_y, tile_z, p_x = 0, p_y = 0) + if(!isnull(tile_x)) + x = ((tile_x - 1) * world.icon_size) + world.icon_size / 2 + p_x + 1 + if(!isnull(tile_y)) + y = ((tile_y - 1) * world.icon_size) + world.icon_size / 2 + p_y + 1 + if(!isnull(tile_z)) + z = tile_z + +/datum/point/proc/debug_out() + var/turf/T = return_turf() + return "\ref[src] aX [x] aY [y] aZ [z] pX [return_px()] pY [return_py()] mX [T.x] mY [T.y] mZ [T.z]" + +/datum/point/proc/move_atom_to_src(atom/movable/AM) + AM.forceMove(return_turf()) + AM.pixel_x = return_px() + AM.pixel_y = return_py() + +/datum/point/proc/return_turf() + return locate(CEILING(x / world.icon_size, 1), CEILING(y / world.icon_size, 1), z) + +/datum/point/proc/return_coordinates() //[turf_x, turf_y, z] + return list(CEILING(x / world.icon_size, 1), CEILING(y / world.icon_size, 1), z) + +/datum/point/proc/return_position() + return new /datum/position(src) + +/datum/point/proc/return_px() + return MODULUS(x, world.icon_size) - 16 - 1 + +/datum/point/proc/return_py() + return MODULUS(y, world.icon_size) - 16 - 1 + + +/datum/point/vector + var/speed = 32 //pixels per iteration + var/iteration = 0 + var/angle = 0 + var/mpx = 0 //calculated x/y movement amounts to prevent having to do trig every step. + var/mpy = 0 + var/starting_x = 0 //just like before, pixels from EDGE of map! This is set in initialize_location(). + var/starting_y = 0 + var/starting_z = 0 + +/datum/point/vector/New(_x, _y, _z, _pixel_x = 0, _pixel_y = 0, _angle, _speed, initial_increment = 0) + ..() + initialize_trajectory(_speed, _angle) + if(initial_increment) + increment(initial_increment) + +/datum/point/vector/initialize_location(tile_x, tile_y, tile_z, p_x = 0, p_y = 0) + . = ..() + starting_x = x + starting_y = y + starting_z = z + +/datum/point/vector/copy_to(datum/point/vector/v = new) + ..(v) + v.speed = speed + v.iteration = iteration + v.angle = angle + v.mpx = mpx + v.mpy = mpy + v.starting_x = starting_x + v.starting_y = starting_y + v.starting_z = starting_z + return v + +/datum/point/vector/proc/initialize_trajectory(pixel_speed, new_angle) + if(!isnull(pixel_speed)) + speed = pixel_speed + set_angle(new_angle) + +/datum/point/vector/proc/set_angle(new_angle) //calculations use "byond angle" where north is 0 instead of 90, and south is 180 instead of 270. + if(isnull(angle)) + return + angle = new_angle + update_offsets() + +/datum/point/vector/proc/update_offsets() + mpx = sin(angle) * speed + mpy = cos(angle) * speed + +/datum/point/vector/proc/set_speed(new_speed) + if(isnull(new_speed) || speed == new_speed) + return + speed = new_speed + update_offsets() + +/datum/point/vector/proc/increment(multiplier = 1) + iteration++ + x += mpx * multiplier + y += mpy * multiplier + +/datum/point/vector/proc/return_vector_after_increments(amount = 7, multiplier = 1, force_simulate = FALSE) + var/datum/point/vector/v = copy_to() + if(force_simulate) + for(var/i in 1 to amount) + v.increment(multiplier) + else + v.increment(multiplier * amount) + return v + +/datum/point/vector/proc/on_z_change() + return + +/datum/point/vector/processed //pixel_speed is per decisecond. + var/last_process = 0 + var/last_move = 0 + var/paused = FALSE + +/datum/point/vector/processed/Destroy() + STOP_PROCESSING(SSprojectiles, src) + return ..() + +/datum/point/vector/processed/proc/start() + last_process = world.time + last_move = world.time + START_PROCESSING(SSprojectiles, src) + +/datum/point/vector/processed/process() + if(paused) + last_move += world.time - last_process + last_process = world.time + return + var/needed_time = world.time - last_move + last_process = world.time + last_move = world.time + increment(needed_time / SSprojectiles.wait) \ No newline at end of file diff --git a/code/datums/progressbar.dm b/code/datums/progressbar.dm index bf38ab7a1c..581dc012f8 100644 --- a/code/datums/progressbar.dm +++ b/code/datums/progressbar.dm @@ -39,7 +39,7 @@ shown = 0 client = user.client - progress = Clamp(progress, 0, goal) + progress = CLAMP(progress, 0, goal) bar.icon_state = "prog_bar_[round(((progress / goal) * 100), 5)]" if (!shown && user.is_preference_enabled(/datum/client_preference/show_progress_bar)) user.client.images += bar diff --git a/code/datums/sun.dm b/code/datums/sun.dm index a78c89ac46..69b725f305 100644 --- a/code/datums/sun.dm +++ b/code/datums/sun.dm @@ -1,38 +1,21 @@ -#define SOLAR_UPDATE_TIME 600 //duration between two updates of the whole sun/solars positions - /datum/sun var/angle var/dx var/dy var/rate - var/list/solars // for debugging purposes, references solars_list at the constructor var/solar_next_update // last time the sun position was checked and adjusted /datum/sun/New() - - solars = solars_list rate = rand(50,200)/100 // 50% - 200% of standard rotation if(prob(50)) // same chance to rotate clockwise than counter-clockwise rate = -rate - solar_next_update = world.time // init the timer angle = rand (0,360) // the station position to the sun is randomised at round start -/*/hook/startup/proc/createSun() // handled in scheduler - 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 /datum/sun/proc/calc_position() - - if(world.time < solar_next_update) //if less than 60 game secondes have passed, do nothing - return; - angle = (360 + angle + rate * 6) % 360 // increase/decrease the angle to the sun, adjusted by the rate - - solar_next_update += SOLAR_UPDATE_TIME // since we updated the angle, set the proper time for the next loop - // now calculate and cache the (dx,dy) increments for line drawing var/s = sin(angle) @@ -51,8 +34,8 @@ dy = c / abs(s) //now tell the solar control computers to update their status and linked devices - for(var/obj/machinery/power/solar_control/SC in solars_list) + for(var/obj/machinery/power/solar_control/SC in GLOB.solars_list) if(!SC.powernet) - solars_list.Remove(SC) + GLOB.solars_list.Remove(SC) continue SC.update() diff --git a/code/datums/supplypacks/hydroponics.dm b/code/datums/supplypacks/hydroponics.dm index 9ee6a80532..4341a696ad 100644 --- a/code/datums/supplypacks/hydroponics.dm +++ b/code/datums/supplypacks/hydroponics.dm @@ -42,6 +42,13 @@ containertype = /obj/structure/largecrate/animal/corgi containername = "Corgi Crate" +/datum/supply_pack/hydro/cat + name = "Cat Crate" + contains = list() + cost = 45 + containertype = /obj/structure/largecrate/animal/cat + containername = "Cat Crate" + /datum/supply_pack/hydro/hydroponics name = "Hydroponics Supply Crate" contains = list( diff --git a/code/datums/supplypacks/misc.dm b/code/datums/supplypacks/misc.dm index bc7687ab78..24a09572ea 100644 --- a/code/datums/supplypacks/misc.dm +++ b/code/datums/supplypacks/misc.dm @@ -23,6 +23,64 @@ containertype = /obj/structure/closet/crate containername = "cards crate" +/datum/supply_pack/randomised/misc/dnd + num_contained = 4 + contains = list( + /obj/item/toy/character/alien, + /obj/item/toy/character/warrior, + /obj/item/toy/character/cleric, + /obj/item/toy/character/thief, + /obj/item/toy/character/wizard, + /obj/item/toy/character/voidone, + /obj/item/toy/character/lich + ) + name = "Miniatures Crate" + cost = 200 + containertype = /obj/structure/closet/crate + containername = "Miniature Crate" + +/datum/supply_pack/randomised/misc/plushies + num_contained = 5 + contains = list( + /obj/item/toy/plushie/nymph, + /obj/item/toy/plushie/mouse, + /obj/item/toy/plushie/kitten, + /obj/item/toy/plushie/lizard, + /obj/item/toy/plushie/spider, + /obj/item/toy/plushie/farwa, + /obj/item/toy/plushie/corgi, + /obj/item/toy/plushie/girly_corgi, + /obj/item/toy/plushie/robo_corgi, + /obj/item/toy/plushie/octopus, + /obj/item/toy/plushie/face_hugger, + /obj/item/toy/plushie/red_fox, + /obj/item/toy/plushie/black_fox, + /obj/item/toy/plushie/marble_fox, + /obj/item/toy/plushie/blue_fox, + /obj/item/toy/plushie/coffee_fox, + /obj/item/toy/plushie/pink_fox, + /obj/item/toy/plushie/purple_fox, + /obj/item/toy/plushie/crimson_fox, + /obj/item/toy/plushie/deer, + /obj/item/toy/plushie/black_cat, + /obj/item/toy/plushie/grey_cat, + /obj/item/toy/plushie/white_cat, + /obj/item/toy/plushie/orange_cat, + /obj/item/toy/plushie/siamese_cat, + /obj/item/toy/plushie/tabby_cat, + /obj/item/toy/plushie/tuxedo_cat, + /obj/item/toy/plushie/squid/green, + /obj/item/toy/plushie/squid/mint, + /obj/item/toy/plushie/squid/blue, + /obj/item/toy/plushie/squid/orange, + /obj/item/toy/plushie/squid/yellow, + /obj/item/toy/plushie/squid/pink + ) + name = "Plushies Crate" + cost = 15 + containertype = /obj/structure/closet/crate + containername = "Plushies Crate" + /datum/supply_pack/misc/eftpos contains = list(/obj/item/device/eftpos) name = "EFTPOS scanner" diff --git a/code/datums/supplypacks/recreation_vr.dm b/code/datums/supplypacks/recreation_vr.dm index 23b377afa0..c4d7ee0ccc 100644 --- a/code/datums/supplypacks/recreation_vr.dm +++ b/code/datums/supplypacks/recreation_vr.dm @@ -50,21 +50,17 @@ containertype = /obj/structure/closet/crate containername = "Action figures crate" -/datum/supply_pack/recreation/characters_vr - name = "Tabletop miniatures" +/datum/supply_pack/recreation/collars + name = "Collar bundle" contains = list( - /obj/item/weapon/storage/box/characters + /obj/item/clothing/accessory/collar/shock = 1, + /obj/item/clothing/accessory/collar/spike = 1, + /obj/item/clothing/accessory/collar/silver = 1, + /obj/item/clothing/accessory/collar/gold = 1, + /obj/item/clothing/accessory/collar/bell = 1, + /obj/item/clothing/accessory/collar/pink = 1, + /obj/item/clothing/accessory/collar/holo = 1 ) + cost = 25 containertype = /obj/structure/closet/crate - containername = "Tabletop miniatures crate" - cost = 50 - -/datum/supply_pack/randomised/recreation/plushies_vr - name = "Plushies crate" - num_contained = 3 - contains = list( - /obj/random/plushie - ) - cost = 60 - containertype = /obj/structure/closet/crate - containername = "Plushies crate" \ No newline at end of file + containername = "collar crate" diff --git a/code/datums/supplypacks/science_vr.dm b/code/datums/supplypacks/science_vr.dm index 0f507ce8e0..e0e4ea2e68 100644 --- a/code/datums/supplypacks/science_vr.dm +++ b/code/datums/supplypacks/science_vr.dm @@ -22,7 +22,7 @@ containername = "EXTREMELY Dangerous Predator crate" access = access_xenobiology contraband = 1 - +/* /datum/supply_pack/sci/otie name = "VARMAcorp adoptable reject (Dangerous!)" cost = 100 @@ -35,4 +35,5 @@ cost = 200 containertype = /obj/structure/largecrate/animal/otie/phoron containername = "VARMAcorp adaptive beta subject (Experimental)" - access = access_xenobiology \ No newline at end of file + access = access_xenobiology +*/ //VORESTATION AI TEMPORARY REMOVAL. Oties commented out cuz broke. diff --git a/code/datums/supplypacks/security_vr.dm b/code/datums/supplypacks/security_vr.dm index 9c1ea33d43..3538a311d5 100644 --- a/code/datums/supplypacks/security_vr.dm +++ b/code/datums/supplypacks/security_vr.dm @@ -1,4 +1,4 @@ -/datum/supply_pack/security/guardbeast +/*/datum/supply_pack/security/guardbeast //VORESTATION AI TEMPORARY REMOVAL name = "VARMAcorp autoNOMous security solution" cost = 150 containertype = /obj/structure/largecrate/animal/guardbeast @@ -15,6 +15,7 @@ access = list( access_security, access_xenobiology) +*/ /datum/supply_pack/security/biosuit contains = list( diff --git a/code/datums/uplink/ammunition.dm b/code/datums/uplink/ammunition.dm index ebadbdaa8d..3ed884316a 100644 --- a/code/datums/uplink/ammunition.dm +++ b/code/datums/uplink/ammunition.dm @@ -40,20 +40,20 @@ path = /obj/item/ammo_magazine/s45/ap /datum/uplink_item/item/ammo/tommymag - name = "Tommygun Magazine (.45)" + name = "Tommy Gun Magazine (.45)" path = /obj/item/ammo_magazine/m45tommy /datum/uplink_item/item/ammo/tommymagap - name = "Tommygun Magazine (.45 AP)" + name = "Tommy Gun Magazine (.45 AP)" path = /obj/item/ammo_magazine/m45tommy/ap /datum/uplink_item/item/ammo/tommydrum - name = "Tommygun Drum Magazine (.45)" + name = "Tommy Gun Drum Magazine (.45)" path = /obj/item/ammo_magazine/m45tommydrum item_cost = 40 /datum/uplink_item/item/ammo/tommydrumap - name = "Tommygun Drum Magazine (.45 AP)" + name = "Tommy Gun Drum Magazine (.45 AP)" path = /obj/item/ammo_magazine/m45tommydrum/ap /datum/uplink_item/item/ammo/darts diff --git a/code/datums/uplink/visible_weapons.dm b/code/datums/uplink/visible_weapons.dm index 6415365bd3..e8a69d2aaf 100644 --- a/code/datums/uplink/visible_weapons.dm +++ b/code/datums/uplink/visible_weapons.dm @@ -139,7 +139,7 @@ path = /obj/item/weapon/storage/secure/briefcase/fuelrod /datum/uplink_item/item/visible_weapons/tommygun - name = "Tommygun (.45)" // We're keeping this because it's CLASSY. -Spades + name = "Tommy Gun (.45)" // We're keeping this because it's CLASSY. -Spades item_cost = 60 path = /obj/item/weapon/gun/projectile/automatic/tommygun diff --git a/code/datums/wires/radio.dm b/code/datums/wires/radio.dm index dcd708c5f6..d059a0b091 100644 --- a/code/datums/wires/radio.dm +++ b/code/datums/wires/radio.dm @@ -24,7 +24,7 @@ var/const/WIRE_TRANSMIT = 4 if(WIRE_TRANSMIT) R.broadcasting = !R.broadcasting && !IsIndexCut(WIRE_SIGNAL) - GLOB.nanomanager.update_uis(holder) + SSnanoui.update_uis(holder) /datum/wires/radio/UpdateCut(var/index, var/mended) var/obj/item/device/radio/R = holder @@ -38,4 +38,4 @@ var/const/WIRE_TRANSMIT = 4 if(WIRE_TRANSMIT) R.broadcasting = mended && !IsIndexCut(WIRE_SIGNAL) - GLOB.nanomanager.update_uis(holder) + SSnanoui.update_uis(holder) diff --git a/code/game/antagonist/alien/borer.dm b/code/game/antagonist/alien/borer.dm index e852bc8418..34b79271f7 100644 --- a/code/game/antagonist/alien/borer.dm +++ b/code/game/antagonist/alien/borer.dm @@ -5,7 +5,7 @@ var/datum/antagonist/borer/borers role_type = BE_ALIEN role_text = "Cortical Borer" role_text_plural = "Cortical Borers" - mob_path = /mob/living/simple_animal/borer + mob_path = /mob/living/simple_mob/animal/borer bantype = "Borer" welcome_text = "Use your Infest power to crawl into the ear of a host and fuse with their brain. You can only take control temporarily, and at risk of hurting your host, so be clever and careful; your host is encouraged to help you however they can. Talk to your fellow borers with :x." antag_indicator = "brainworm" @@ -40,7 +40,7 @@ var/datum/antagonist/borer/borers player.objectives += new /datum/objective/escape() /datum/antagonist/borer/place_mob(var/mob/living/mob) - var/mob/living/simple_animal/borer/borer = mob + var/mob/living/simple_mob/animal/borer/borer = mob if(istype(borer)) var/mob/living/carbon/human/host for(var/mob/living/carbon/human/H in mob_list) diff --git a/code/game/antagonist/station/cultist.dm b/code/game/antagonist/station/cultist.dm index e40085f90a..e5c7d8f652 100644 --- a/code/game/antagonist/station/cultist.dm +++ b/code/game/antagonist/station/cultist.dm @@ -111,12 +111,12 @@ var/datum/antagonist/cultist/cult . = ..() if(.) player << "You catch a glimpse of the Realm of Nar-Sie, the Geometer of Blood. You now see how flimsy the world is, you see that it should be open to the knowledge of That Which Waits. Assist your new compatriots in their dark dealings. Their goals are yours, and yours are theirs. You serve the Dark One above all else. Bring It back." - if(player.current && !istype(player.current, /mob/living/simple_animal/construct)) + if(player.current && !istype(player.current, /mob/living/simple_mob/construct)) player.current.add_language(LANGUAGE_CULT) /datum/antagonist/cultist/remove_antagonist(var/datum/mind/player, var/show_message, var/implanted) . = ..() - if(. && player.current && !istype(player.current, /mob/living/simple_animal/construct)) + if(. && player.current && !istype(player.current, /mob/living/simple_mob/construct)) player.current.remove_language(LANGUAGE_CULT) /datum/antagonist/cultist/can_become_antag(var/datum/mind/player) diff --git a/code/game/area/Space Station 13 areas_vr.dm b/code/game/area/Space Station 13 areas_vr.dm index 330d703ac0..b41eba12d0 100644 --- a/code/game/area/Space Station 13 areas_vr.dm +++ b/code/game/area/Space Station 13 areas_vr.dm @@ -206,6 +206,10 @@ name = "\improper Weapons Testing Range" icon_state = "firingrange" +/area/rnd/research/researchdivision + name = "\improper Research Division" + icon_state = "research" + /area/rnd/outpost name = "\improper Research Outpost Hallway" icon_state = "research" diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 5d318cf932..dbe6d45c30 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -59,7 +59,7 @@ ..() -/area/initialize() +/area/Initialize() . = ..() return INITIALIZE_HINT_LATELOAD // Areas tradiationally are initialized AFTER other atoms. diff --git a/code/game/atoms.dm b/code/game/atoms.dm index d1289a23de..6929943de2 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -8,13 +8,14 @@ var/list/blood_DNA var/was_bloodied var/blood_color - var/last_bumped = 0 var/pass_flags = 0 var/throwpass = 0 var/germ_level = GERM_LEVEL_AMBIENT // The higher the germ level, the more germ on the atom. var/simulated = 1 //filter for actions - used by lighting overlays var/fluorescent // Shows up under a UV light. + var/last_bumped = 0 + ///Chemistry. var/datum/reagents/reagents = null @@ -63,7 +64,7 @@ // Must not sleep! // Other parameters are passed from New (excluding loc), this does not happen if mapload is TRUE // Must return an Initialize hint. Defined in code/__defines/subsystems.dm -/atom/proc/initialize(mapload, ...) +/atom/proc/Initialize(mapload, ...) if(QDELETED(src)) crash_with("GC: -- [type] had initialize() called after qdel() --") if(initialized) @@ -97,11 +98,8 @@ return 0 return -1 -/atom/proc/on_reagent_change() - return - /atom/proc/Bumped(AM as mob|obj) - return + set waitfor = FALSE // Convenience proc to see if a container is open for chemistry handling // returns true if open @@ -499,7 +497,7 @@ if(!istype(drop_destination) || drop_destination == destination) return forceMove(destination) destination = drop_destination - return forceMove(null) + return moveToNullspace() /atom/proc/onDropInto(var/atom/movable/AM) return // If onDropInto returns null, then dropInto will forceMove AM into us. @@ -524,7 +522,7 @@ var/atom/L = loc if(!L) return null - return L.AllowDrop() ? L : get_turf(L) + return L.AllowDrop() ? L : L.drop_location() /atom/proc/AllowDrop() return FALSE @@ -534,3 +532,35 @@ /atom/proc/get_nametag_desc(mob/user) return "" //Desc itself is often too long to use + +/atom/vv_get_dropdown() + . = ..() + VV_DROPDOWN_OPTION(VV_HK_ATOM_EXPLODE, "Explosion") + VV_DROPDOWN_OPTION(VV_HK_ATOM_EMP, "Emp Pulse") + +/atom/vv_do_topic(list/href_list) + . = ..() + IF_VV_OPTION(VV_HK_ATOM_EXPLODE) + if(!check_rights(R_DEBUG|R_FUN)) + return + usr.client.cmd_admin_explosion(src) + href_list["datumrefresh"] = "\ref[src]" + IF_VV_OPTION(VV_HK_ATOM_EMP) + if(!check_rights(R_DEBUG|R_FUN)) + return + usr.client.cmd_admin_emp(src) + href_list["datumrefresh"] = "\ref[src]" + +/atom/vv_get_header() + . = ..() + var/custom_edit_name + if(!isliving(src)) + custom_edit_name = "[src]" + . += {" + [custom_edit_name] +
+ << + [dir2text(dir)] + >> + + "} diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index f287a23f75..0b66569b05 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -4,6 +4,7 @@ var/last_move = null var/anchored = 0 // var/elevation = 2 - not used anywhere + var/moving_diagonally var/move_speed = 10 var/l_move_time = 1 var/m_flag = 1 @@ -21,6 +22,7 @@ var/old_y = 0 var/datum/riding/riding_datum //VOREStation Add - Moved from /obj/vehicle var/does_spin = TRUE // Does the atom spin when thrown (of course it does :P) + var/movement_type = NONE /atom/movable/Destroy() . = ..() @@ -33,7 +35,7 @@ if(opacity && isturf(loc)) un_opaque = loc - loc = null + moveToNullspace() if(un_opaque) un_opaque.recalc_atom_opacity() if (pulledby) @@ -42,51 +44,244 @@ pulledby = null QDEL_NULL(riding_datum) //VOREStation Add -/atom/movable/Bump(var/atom/A, yes) - if(src.throwing) - src.throw_impact(A) - src.throwing = 0 +/atom/movable/vv_edit_var(var_name, var_value) + if(GLOB.VVpixelmovement[var_name]) //Pixel movement is not yet implemented, changing this will break everything irreversibly. + return FALSE + return ..() - spawn(0) - if ((A && yes)) - A.last_bumped = world.time - A.Bumped(src) +//////////////////////////////////////// +// Here's where we rewrite how byond handles movement except slightly different +// To be removed on step_ conversion +// All this work to prevent a second bump +/atom/movable/Move(atom/newloc, direct=0) + . = FALSE + if(!newloc || newloc == loc) return - ..() + + if(!direct) + direct = get_dir(src, newloc) + set_dir(direct) + + if(!loc.Exit(src, newloc)) + return + + if(!newloc.Enter(src, src.loc)) + return + // Past this is the point of no return + var/atom/oldloc = loc + var/area/oldarea = get_area(oldloc) + var/area/newarea = get_area(newloc) + loc = newloc + . = TRUE + oldloc.Exited(src, newloc) + if(oldarea != newarea) + oldarea.Exited(src, newloc) + + for(var/i in oldloc) + if(i == src) // Multi tile objects + continue + var/atom/movable/thing = i + thing.Uncrossed(src) + + newloc.Entered(src, oldloc) + if(oldarea != newarea) + newarea.Entered(src, oldloc) + + for(var/i in loc) + if(i == src) // Multi tile objects + continue + var/atom/movable/thing = i + thing.Crossed(src) +// +//////////////////////////////////////// + +/atom/movable/Move(atom/newloc, direct) + if(!loc || !newloc) + return FALSE + var/atom/oldloc = loc + + if(loc != newloc) + if (!(direct & (direct - 1))) //Cardinal move + . = ..() + else //Diagonal move, split it into cardinal moves + moving_diagonally = FIRST_DIAG_STEP + var/first_step_dir + // The `&& moving_diagonally` checks are so that a forceMove taking + // place due to a Crossed, Bumped, etc. call will interrupt + // the second half of the diagonal movement, or the second attempt + // at a first half if step() fails because we hit something. + if (direct & NORTH) + if (direct & EAST) + if (step(src, NORTH) && moving_diagonally) + first_step_dir = NORTH + moving_diagonally = SECOND_DIAG_STEP + . = step(src, EAST) + else if (moving_diagonally && step(src, EAST)) + first_step_dir = EAST + moving_diagonally = SECOND_DIAG_STEP + . = step(src, NORTH) + else if (direct & WEST) + if (step(src, NORTH) && moving_diagonally) + first_step_dir = NORTH + moving_diagonally = SECOND_DIAG_STEP + . = step(src, WEST) + else if (moving_diagonally && step(src, WEST)) + first_step_dir = WEST + moving_diagonally = SECOND_DIAG_STEP + . = step(src, NORTH) + else if (direct & SOUTH) + if (direct & EAST) + if (step(src, SOUTH) && moving_diagonally) + first_step_dir = SOUTH + moving_diagonally = SECOND_DIAG_STEP + . = step(src, EAST) + else if (moving_diagonally && step(src, EAST)) + first_step_dir = EAST + moving_diagonally = SECOND_DIAG_STEP + . = step(src, SOUTH) + else if (direct & WEST) + if (step(src, SOUTH) && moving_diagonally) + first_step_dir = SOUTH + moving_diagonally = SECOND_DIAG_STEP + . = step(src, WEST) + else if (moving_diagonally && step(src, WEST)) + first_step_dir = WEST + moving_diagonally = SECOND_DIAG_STEP + . = step(src, SOUTH) + if(moving_diagonally == SECOND_DIAG_STEP) + if(!.) + set_dir(first_step_dir) + //else if (!inertia_moving) + // inertia_next_move = world.time + inertia_move_delay + // newtonian_move(direct) + moving_diagonally = 0 + return + + if(!loc || (loc == oldloc && oldloc != newloc)) + last_move = 0 + return + + if(.) + Moved(oldloc, direct) + + //Polaris stuff + move_speed = world.time - l_move_time + l_move_time = world.time + m_flag = 1 + //End + + last_move = direct + set_dir(direct) + if(. && has_buckled_mobs() && !handle_buckled_mob_movement(loc,direct)) //movement failed due to buckled mob(s) + return FALSE + //VOREStation Add + else if(. && riding_datum) + riding_datum.handle_vehicle_layer() + riding_datum.handle_vehicle_offsets() + //VOREStation Add End + +//Called after a successful Move(). By this point, we've already moved +/atom/movable/proc/Moved(atom/OldLoc, Dir, Forced = FALSE) + //if (!inertia_moving) + // inertia_next_move = world.time + inertia_move_delay + // newtonian_move(Dir) + //if (length(client_mobs_in_contents)) + // update_parallax_contents() + + return TRUE + +// Make sure you know what you're doing if you call this, this is intended to only be called by byond directly. +// You probably want CanPass() +/atom/movable/Cross(atom/movable/AM) + . = TRUE + return CanPass(AM, loc) + +//oldloc = old location on atom, inserted when forceMove is called and ONLY when forceMove is called! +/atom/movable/Crossed(atom/movable/AM, oldloc) return +/atom/movable/Uncross(atom/movable/AM, atom/newloc) + . = ..() + if(isturf(newloc) && !CheckExit(AM, newloc)) + return FALSE + +/atom/movable/Bump(atom/A) + if(!A) + CRASH("Bump was called with no argument.") + . = ..() + if(throwing) + throw_impact(A) + throwing = 0 + if(QDELETED(A)) + return + A.Bumped(src) + A.last_bumped = world.time + /atom/movable/proc/forceMove(atom/destination) - if(loc == destination) - return 0 - var/is_origin_turf = isturf(loc) - var/is_destination_turf = isturf(destination) - // It is a new area if: - // Both the origin and destination are turfs with different areas. - // When either origin or destination is a turf and the other is not. - var/is_new_area = (is_origin_turf ^ is_destination_turf) || (is_origin_turf && is_destination_turf && loc.loc != destination.loc) - - var/atom/origin = loc - loc = destination - - if(origin) - origin.Exited(src, destination) - if(is_origin_turf) - for(var/atom/movable/AM in origin) - AM.Uncrossed(src) - if(is_new_area && is_origin_turf) - origin.loc.Exited(src, destination) - + . = FALSE if(destination) - destination.Entered(src, origin) - if(is_destination_turf) // If we're entering a turf, cross all movable atoms - for(var/atom/movable/AM in loc) - if(AM != src) - AM.Crossed(src) - if(is_new_area && is_destination_turf) - destination.loc.Entered(src, origin) + . = doMove(destination) + else + CRASH("No valid destination passed into forceMove") - Moved(origin) - return 1 +/atom/movable/proc/moveToNullspace() + return doMove(null) + +/atom/movable/proc/doMove(atom/destination) + . = FALSE + if(destination) + if(pulledby) + pulledby.stop_pulling() + var/atom/oldloc = loc + var/same_loc = oldloc == destination + var/area/old_area = get_area(oldloc) + var/area/destarea = get_area(destination) + + loc = destination + moving_diagonally = 0 + + if(!same_loc) + if(oldloc) + oldloc.Exited(src, destination) + if(old_area && old_area != destarea) + old_area.Exited(src, destination) + for(var/atom/movable/AM in oldloc) + AM.Uncrossed(src) + var/turf/oldturf = get_turf(oldloc) + var/turf/destturf = get_turf(destination) + var/old_z = (oldturf ? oldturf.z : null) + var/dest_z = (destturf ? destturf.z : null) + if (old_z != dest_z) + onTransitZ(old_z, dest_z) + destination.Entered(src, oldloc) + if(destarea && old_area != destarea) + destarea.Entered(src, oldloc) + + for(var/atom/movable/AM in destination) + if(AM == src) + continue + AM.Crossed(src, oldloc) + + Moved(oldloc, NONE, TRUE) + . = TRUE + + //If no destination, move the atom into nullspace (don't do this unless you know what you're doing) + else + . = TRUE + if (loc) + var/atom/oldloc = loc + var/area/old_area = get_area(oldloc) + oldloc.Exited(src, null) + if(old_area) + old_area.Exited(src, null) + loc = null + +/atom/movable/proc/onTransitZ(old_z,new_z) + GLOB.z_moved_event.raise_event(src, old_z, new_z) + for(var/item in src) // Notify contents of Z-transition. This can be overridden IF we know the items contents do not care. + var/atom/movable/AM = item + AM.onTransitZ(old_z,new_z) +///////////////////////////////////////////////////////////////// //called when src is thrown into hit_atom /atom/movable/proc/throw_impact(atom/hit_atom, var/speed) @@ -121,7 +316,7 @@ // Special handling of windows, which are dense but block only from some directions if(istype(A, /obj/structure/window)) var/obj/structure/window/W = A - if (!W.is_full_window() && !(turn(src.last_move, 180) & A.dir)) + if (!W.is_fulltile() && !(turn(src.last_move, 180) & A.dir)) continue // Same thing for (closed) windoors, which have the same problem else if(istype(A, /obj/machinery/door/window) && !(turn(src.last_move, 180) & A.dir)) @@ -290,4 +485,8 @@ /atom/movable/proc/adjust_rotation(new_rotation) icon_rotation = new_rotation - update_transform() \ No newline at end of file + update_transform() + +// Called when touching a lava tile. +/atom/movable/proc/lava_act() + fire_act(null, 10000, 1000) diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm index 623ccc11a3..998b712828 100644 --- a/code/game/dna/dna_modifier.dm +++ b/code/game/dna/dna_modifier.dm @@ -270,7 +270,7 @@ I.loc = src src.disk = I user << "You insert [I]." - GLOB.nanomanager.update_uis(src) // update all UIs attached to src + SSnanoui.update_uis(src) // update all UIs attached to src return else ..() @@ -428,7 +428,7 @@ data["beakerVolume"] += R.volume // update the ui if it exists, returns null if no ui is passed/found - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.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 @@ -465,7 +465,7 @@ irradiating = src.radiation_duration var/lock_state = src.connected.locked src.connected.locked = 1//lock it - GLOB.nanomanager.update_uis(src) // update all UIs attached to src + SSnanoui.update_uis(src) // update all UIs attached to src sleep(10*src.radiation_duration) // sleep for radiation_duration seconds @@ -566,7 +566,7 @@ irradiating = src.radiation_duration var/lock_state = src.connected.locked src.connected.locked = 1//lock it - GLOB.nanomanager.update_uis(src) // update all UIs attached to src + SSnanoui.update_uis(src) // update all UIs attached to src sleep(10*src.radiation_duration) // sleep for radiation_duration seconds @@ -624,7 +624,7 @@ irradiating = src.radiation_duration var/lock_state = src.connected.locked src.connected.locked = 1 //lock it - GLOB.nanomanager.update_uis(src) // update all UIs attached to src + SSnanoui.update_uis(src) // update all UIs attached to src sleep(10*src.radiation_duration) // sleep for radiation_duration seconds @@ -751,7 +751,7 @@ irradiating = 2 var/lock_state = src.connected.locked src.connected.locked = 1//lock it - GLOB.nanomanager.update_uis(src) // update all UIs attached to src + SSnanoui.update_uis(src) // update all UIs attached to src sleep(10*2) // sleep for 2 seconds diff --git a/code/game/gamemodes/changeling/powers/armblade.dm b/code/game/gamemodes/changeling/powers/armblade.dm index 35526be0d6..ed27a49ba0 100644 --- a/code/game/gamemodes/changeling/powers/armblade.dm +++ b/code/game/gamemodes/changeling/powers/armblade.dm @@ -64,7 +64,7 @@ /obj/item/weapon/melee/changeling/New(location) ..() - processing_objects |= src + START_PROCESSING(SSobj, src) if(ismob(loc)) visible_message("A grotesque weapon forms around [loc.name]\'s arm!", "Our arm twists and mutates, transforming it into a deadly weapon.", @@ -81,7 +81,7 @@ qdel(src) /obj/item/weapon/melee/changeling/Destroy() - processing_objects -= src + STOP_PROCESSING(SSobj, src) creator = null ..() diff --git a/code/game/gamemodes/changeling/powers/armor.dm b/code/game/gamemodes/changeling/powers/armor.dm index ca8a3c8780..3f555ca8ae 100644 --- a/code/game/gamemodes/changeling/powers/armor.dm +++ b/code/game/gamemodes/changeling/powers/armor.dm @@ -35,8 +35,8 @@ name = "flesh mass" icon_state = "lingspacesuit" desc = "A huge, bulky mass of pressure and temperature-resistant organic tissue, evolved to facilitate space travel." - flags = STOPPRESSUREDAMAGE //Not THICKMATERIAL because it's organic tissue, so if somebody tries to inject something into it, - //it still ends up in your blood. (also balance but muh fluff) + flags = 0 //Not THICKMATERIAL because it's organic tissue, so if somebody tries to inject something into it, + //it still ends up in your blood. (also balance but muh fluff) allowed = list(/obj/item/device/flashlight, /obj/item/weapon/tank/emergency/oxygen, /obj/item/weapon/tank/oxygen) armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) //No armor at all. canremove = 0 @@ -55,7 +55,7 @@ name = "flesh mass" icon_state = "lingspacehelmet" desc = "A covering of pressure and temperature-resistant organic tissue with a glass-like chitin front." - flags = BLOCKHAIR | STOPPRESSUREDAMAGE //Again, no THICKMATERIAL. + flags = BLOCKHAIR //Again, no THICKMATERIAL. armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) body_parts_covered = HEAD|FACE|EYES canremove = 0 diff --git a/code/game/gamemodes/changeling/powers/escape_restraints.dm b/code/game/gamemodes/changeling/powers/escape_restraints.dm index 4e6ed4e5cf..08700b1e04 100644 --- a/code/game/gamemodes/changeling/powers/escape_restraints.dm +++ b/code/game/gamemodes/changeling/powers/escape_restraints.dm @@ -21,7 +21,7 @@ if(world.time < changeling.next_escape) to_chat(src, "We are still recovering from our last escape...") return 0 - if(!(C.handcuffed || C.legcuffed)) // No need to waste chems if there's nothing to break out of + if(!(C.handcuffed || C.legcuffed || istype(C.wear_suit,/obj/item/clothing/suit/straight_jacket))) // No need to waste chems if there's nothing to break out of to_chat(C, "We are are not restrained in a way we can escape...") return 0 @@ -37,22 +37,26 @@ C.update_inv_handcuffed() if (C.client) C.client.screen -= W + W.forceMove(C.loc) + W.dropped(C) if(W) - W.loc = C.loc - W.dropped(C) - if(W) - W.layer = initial(W.layer) + W.layer = initial(W.layer) if(C.legcuffed) var/obj/item/weapon/W = C.legcuffed C.legcuffed = null C.update_inv_legcuffed() if(C.client) C.client.screen -= W + W.forceMove(C.loc) + W.dropped(C) if(W) - W.loc = C.loc - W.dropped(C) - if(W) - W.layer = initial(W.layer) + W.layer = initial(W.layer) + if(istype(C.wear_suit, /obj/item/clothing/suit/straight_jacket)) + var/obj/item/clothing/suit/straight_jacket/SJ = C.wear_suit + SJ.forceMove(C.loc) + SJ.dropped(C) + C.wear_suit = null + escape_cooldown *= 1.5 // Straight jackets are tedious compared to cuffs. if(src.mind.changeling.recursive_enhancement) escape_cooldown *= 0.5 diff --git a/code/game/gamemodes/changeling/powers/fabricate_clothing.dm b/code/game/gamemodes/changeling/powers/fabricate_clothing.dm index d79af62b4c..b90b402e78 100644 --- a/code/game/gamemodes/changeling/powers/fabricate_clothing.dm +++ b/code/game/gamemodes/changeling/powers/fabricate_clothing.dm @@ -268,7 +268,7 @@ var/global/list/changeling_fabricated_clothing = list( ..() registered_user = user -/obj/item/weapon/card/id/syndicate/changeling/initialize() +/obj/item/weapon/card/id/syndicate/changeling/Initialize() . = ..() access = null diff --git a/code/game/gamemodes/changeling/powers/revive.dm b/code/game/gamemodes/changeling/powers/revive.dm index 0da6c3c3d5..7fe4ab232b 100644 --- a/code/game/gamemodes/changeling/powers/revive.dm +++ b/code/game/gamemodes/changeling/powers/revive.dm @@ -45,6 +45,34 @@ BITSET(H.hud_updateflag, STATUS_HUD) BITSET(H.hud_updateflag, LIFE_HUD) + if(H.handcuffed) + var/obj/item/weapon/W = H.handcuffed + H.handcuffed = null + if(H.buckled && H.buckled.buckle_require_restraints) + H.buckled.unbuckle_mob() + H.update_inv_handcuffed() + if (H.client) + H.client.screen -= W + W.forceMove(H.loc) + W.dropped(H) + if(W) + W.layer = initial(W.layer) + if(H.legcuffed) + var/obj/item/weapon/W = H.legcuffed + H.legcuffed = null + H.update_inv_legcuffed() + if(H.client) + H.client.screen -= W + W.forceMove(H.loc) + W.dropped(H) + if(W) + W.layer = initial(W.layer) + if(istype(H.wear_suit, /obj/item/clothing/suit/straight_jacket)) + var/obj/item/clothing/suit/straight_jacket/SJ = H.wear_suit + SJ.forceMove(H.loc) + SJ.dropped(H) + H.wear_suit = null + C.halloss = 0 C.shock_stage = 0 //Pain C << "We have regenerated." diff --git a/code/game/gamemodes/cult/construct_spells.dm b/code/game/gamemodes/cult/construct_spells.dm index f8ff57fc35..937284629b 100644 --- a/code/game/gamemodes/cult/construct_spells.dm +++ b/code/game/gamemodes/cult/construct_spells.dm @@ -476,14 +476,14 @@ proc/findNullRod(var/atom/target) /obj/item/weapon/spell/construct/run_checks() if(owner) - if((iscultist(owner) || istype(owner, /mob/living/simple_animal/construct)) && (world.time >= (last_castcheck + cooldown))) //Are they a cultist or a construct, and has the cooldown time passed? + if((iscultist(owner) || istype(owner, /mob/living/simple_mob/construct)) && (world.time >= (last_castcheck + cooldown))) //Are they a cultist or a construct, and has the cooldown time passed? last_castcheck = world.time return 1 return 0 /obj/item/weapon/spell/construct/pay_energy(var/amount) if(owner) - if(istype(owner, /mob/living/simple_animal/construct)) + if(istype(owner, /mob/living/simple_mob/construct)) return 1 if(iscultist(owner) && pay_blood(amount)) return 1 @@ -532,7 +532,8 @@ proc/findNullRod(var/atom/target) /obj/item/weapon/spell/construct/projectile/on_ranged_cast(atom/hit_atom, mob/living/user) if(set_up(hit_atom, user)) var/obj/item/projectile/new_projectile = make_projectile(spell_projectile, user) - new_projectile.launch(hit_atom) + new_projectile.old_style_target(hit_atom) + new_projectile.fire() log_and_message_admins("has casted [src] at \the [hit_atom].") if(fire_sound) playsound(get_turf(src), fire_sound, 75, 1) @@ -597,9 +598,9 @@ proc/findNullRod(var/atom/target) light_power = -2 light_color = "#FFFFFF" - muzzle_type = /obj/effect/projectile/inversion/muzzle - tracer_type = /obj/effect/projectile/inversion/tracer - impact_type = /obj/effect/projectile/inversion/impact + muzzle_type = /obj/effect/projectile/muzzle/inversion + tracer_type = /obj/effect/projectile/tracer/inversion + impact_type = /obj/effect/projectile/impact/inversion //Harvester Pain Orb @@ -607,7 +608,7 @@ proc/findNullRod(var/atom/target) name = "sphere of agony" desc = "Call forth a portal to a dimension of naught but pain at your target." - spawner_type = /obj/effect/temporary_effect/pulsar/agonizing_sphere + spawner_type = /obj/effect/temporary_effect/pulse/agonizing_sphere /obj/item/weapon/spell/construct/spawner/agonizing_sphere/on_ranged_cast(atom/hit_atom, mob/user) if(within_range(hit_atom) && pay_energy(10)) @@ -619,7 +620,7 @@ proc/findNullRod(var/atom/target) var/mob/living/L = hit_atom L.add_modifier(/datum/modifier/agonize, 10 SECONDS) -/obj/effect/temporary_effect/pulsar/agonizing_sphere +/obj/effect/temporary_effect/pulse/agonizing_sphere name = "agonizing sphere" desc = "A portal to some hellish place. Its screams wrack your body with pain.." icon_state = "red_static_sphere" @@ -628,19 +629,15 @@ proc/findNullRod(var/atom/target) light_power = 5 light_color = "#FF0000" pulses_remaining = 10 + pulse_delay = 1 SECOND -/obj/effect/temporary_effect/pulsar/agonizing_sphere/pulse_loop() - while(pulses_remaining) - sleep(1 SECONDS) - spawn() - for(var/mob/living/L in view(4,src)) - if(!iscultist(L) && !istype(L, /mob/living/simple_animal/construct)) - L.add_modifier(/datum/modifier/agonize, 2 SECONDS) - if(L.isSynthetic()) - to_chat(L, "Your chassis warps as the [src] pulses!") - L.adjustFireLoss(4) - pulses_remaining-- - qdel(src) +/obj/effect/temporary_effect/pulse/agonizing_sphere/on_pulse() + for(var/mob/living/L in view(4,src)) + if(!iscultist(L) && !istype(L, /mob/living/simple_mob/construct)) + L.add_modifier(/datum/modifier/agonize, 2 SECONDS) + if(L.isSynthetic()) + to_chat(L, "Your chassis warps as the [src] pulses!") + L.adjustFireLoss(4) //Artificer Heal @@ -659,7 +656,7 @@ proc/findNullRod(var/atom/target) L.add_modifier(/datum/modifier/mend_occult, 150) qdel(src) -//Juggernaut + Behemoth Slam +//Juggernaut Slam /obj/item/weapon/spell/construct/slam name = "slam" desc = "Empower your FIST, to send an opponent flying." @@ -672,8 +669,8 @@ proc/findNullRod(var/atom/target) /obj/item/weapon/spell/construct/slam/on_melee_cast(atom/hit_atom, mob/living/user, def_zone) var/attack_message = "slams" - if(istype(user, /mob/living/simple_animal)) - var/mob/living/simple_animal/S = user + if(istype(user, /mob/living/simple_mob)) + var/mob/living/simple_mob/S = user attack_message = pick(S.attacktext) if(isliving(hit_atom)) var/mob/living/L = hit_atom diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm index 082404b271..7118aafe80 100644 --- a/code/game/gamemodes/cult/cult_items.dm +++ b/code/game/gamemodes/cult/cult_items.dm @@ -14,7 +14,7 @@ return /obj/item/weapon/melee/cultblade/attack(mob/living/M, mob/living/user, var/target_zone) - if(iscultist(user) && !istype(user, /mob/living/simple_animal/construct)) + if(iscultist(user) && !istype(user, /mob/living/simple_mob/construct)) return ..() var/zone = (user.hand ? "l_arm":"r_arm") @@ -25,7 +25,7 @@ //random amount of damage between half of the blade's force and the full force of the blade. user.apply_damage(rand(force/2, force), BRUTE, zone, 0, sharp=1, edge=1) user.Weaken(5) - else if(!istype(user, /mob/living/simple_animal/construct)) + else if(!istype(user, /mob/living/simple_mob/construct)) to_chat(user, "An inexplicable force rips through you, tearing the sword from your grasp!") else to_chat(user, "The blade hisses, forcing itself from your manipulators. \The [src] will only allow mortals to wield it against foes, not kin.") @@ -39,10 +39,10 @@ return 1 /obj/item/weapon/melee/cultblade/pickup(mob/living/user as mob) - if(!iscultist(user) && !istype(user, /mob/living/simple_animal/construct)) + if(!iscultist(user) && !istype(user, /mob/living/simple_mob/construct)) to_chat(user, "An overwhelming feeling of dread comes over you as you pick up the cultist's sword. It would be wise to be rid of this blade quickly.") user.make_dizzy(120) - if(istype(user, /mob/living/simple_animal/construct)) + if(istype(user, /mob/living/simple_mob/construct)) to_chat(user, "\The [src] hisses, as it is discontent with your acquisition of it. It would be wise to return it to a worthy mortal quickly.") /obj/item/clothing/head/culthood diff --git a/code/game/gamemodes/cult/cult_structures.dm b/code/game/gamemodes/cult/cult_structures.dm index d588299cc5..c87427bc44 100644 --- a/code/game/gamemodes/cult/cult_structures.dm +++ b/code/game/gamemodes/cult/cult_structures.dm @@ -108,18 +108,18 @@ light_range=5 light_color="#ff0000" spawnable=list( - /mob/living/simple_animal/hostile/scarybat, - /mob/living/simple_animal/hostile/creature/vore, - /mob/living/simple_animal/hostile/faithless - ) // Vorestation Edit + /mob/living/simple_mob/animal/space/bats, + /mob/living/simple_mob/creature, + /mob/living/simple_mob/faithless + ) /obj/effect/gateway/active/cult light_range=5 light_color="#ff0000" spawnable=list( - /mob/living/simple_animal/hostile/scarybat/cult, - /mob/living/simple_animal/hostile/creature/cult, - /mob/living/simple_animal/hostile/faithless/cult + /mob/living/simple_mob/animal/space/bats/cult, + /mob/living/simple_mob/creature/cult, + /mob/living/simple_mob/faithless/cult ) /obj/effect/gateway/active/cult/cultify() diff --git a/code/game/gamemodes/cult/cultify/mob.dm b/code/game/gamemodes/cult/cultify/mob.dm index 14bb380a19..d78956c40a 100644 --- a/code/game/gamemodes/cult/cultify/mob.dm +++ b/code/game/gamemodes/cult/cultify/mob.dm @@ -16,7 +16,7 @@ /mob/living/cultify() if(iscultist(src) && client) - var/mob/living/simple_animal/construct/harvester/C = new(get_turf(src)) + var/mob/living/simple_mob/construct/harvester/C = new(get_turf(src)) mind.transfer_to(C) C << "The Geometer of Blood is overjoyed to be reunited with its followers, and accepts your body in sacrifice. As reward, you have been gifted with the shell of an Harvester.
Your tendrils can use and draw runes without need for a tome, your eyes can see beings through walls, and your mind can open any door. Use these assets to serve Nar-Sie and bring him any remaining living human in the world.
You can teleport yourself back to Nar-Sie along with any being under yourself at any time using your \"Harvest\" spell.
" dust() diff --git a/code/game/gamemodes/cult/narsie.dm b/code/game/gamemodes/cult/narsie.dm index ea866ad856..21ee7ec1df 100644 --- a/code/game/gamemodes/cult/narsie.dm +++ b/code/game/gamemodes/cult/narsie.dm @@ -44,7 +44,7 @@ var/global/list/narsie_list = list() ..() if(announce) world << "[uppertext(name)] HAS RISEN" - world << sound('sound/effects/wind/wind_5_1.ogg') + world << sound('sound/effects/weather/wind/wind_5_1.ogg') narsie_spawn_animation() diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 40008c5ecc..1bfe4e0d60 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -206,7 +206,7 @@ var/list/sacrificed = list() if(cultists.len >= 9) if(!narsie_cometh)//so we don't initiate Hell more than one time. world << "THE VEIL HAS BEEN SHATTERED!" - world << sound('sound/effects/wind/wind_5_1.ogg') + world << sound('sound/effects/weather/wind/wind_5_1.ogg') SetUniversalState(/datum/universal_state/hell) narsie_cometh = 1 diff --git a/code/modules/mob/living/simple_animal/constructs/soulstone.dm b/code/game/gamemodes/cult/soulstone.dm similarity index 88% rename from code/modules/mob/living/simple_animal/constructs/soulstone.dm rename to code/game/gamemodes/cult/soulstone.dm index 6f13789dfc..61db88917a 100644 --- a/code/modules/mob/living/simple_animal/constructs/soulstone.dm +++ b/code/game/gamemodes/cult/soulstone.dm @@ -1,242 +1,246 @@ -/obj/item/device/soulstone/cultify() - return - -/obj/item/device/soulstone - name = "Soul Stone Shard" - icon = 'icons/obj/wizard.dmi' - icon_state = "soulstone" - 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 = ITEMSIZE_SMALL - slot_flags = SLOT_BELT - origin_tech = list(TECH_BLUESPACE = 4, TECH_MATERIAL = 4) - var/imprinted = "empty" - var/possible_constructs = list("Juggernaut","Wraith","Artificer","Harvester") - -//////////////////////////////Capturing//////////////////////////////////////////////////////// - -/obj/item/device/soulstone/attack(mob/living/carbon/human/M as mob, mob/user as mob) - if(!istype(M, /mob/living/carbon/human))//If target is not a human. - return ..() - if(istype(M, /mob/living/carbon/human/dummy)) - return..() - if(jobban_isbanned(M, "cultist")) - user << "This person's soul is too corrupt and cannot be captured!" - return..() - - if(M.has_brain_worms()) //Borer stuff - RR - user << "This being is corrupted by an alien intelligence and cannot be soul trapped." - return..() - - add_attack_logs(user,M,"Soulstone'd with [src.name]") - transfer_soul("VICTIM", M, user) - return - - -///////////////////Options for using captured souls/////////////////////////////////////// - -/obj/item/device/soulstone/attack_self(mob/user) - if (!in_range(src, user)) - return - user.set_machine(src) - var/dat = "Soul Stone
" - for(var/mob/living/simple_animal/shade/A in src) - dat += "Captured Soul: [A.name]
" - dat += {"Summon Shade"} - dat += "
" - dat += {" Close"} - user << browse(dat, "window=aicard") - onclose(user, "aicard") - return - - - - -/obj/item/device/soulstone/Topic(href, href_list) - var/mob/U = usr - if (!in_range(src, U)||U.machine!=src) - U << browse(null, "window=aicard") - U.unset_machine() - return - - add_fingerprint(U) - U.set_machine(src) - - switch(href_list["choice"])//Now we switch based on choice. - if ("Close") - U << browse(null, "window=aicard") - U.unset_machine() - return - - if ("Summon") - for(var/mob/living/simple_animal/shade/A in src) - A.status_flags &= ~GODMODE - A.canmove = 1 - A << "You have been released from your prison, but you are still bound to [U.name]'s will. Help them suceed in their goals at all costs." - A.forceMove(U.loc) - A.cancel_camera() - src.icon_state = "soulstone" - attack_self(U) - -///////////////////////////Transferring to constructs///////////////////////////////////////////////////// -/obj/structure/constructshell - name = "empty shell" - icon = 'icons/obj/wizard.dmi' - icon_state = "construct" - desc = "A wicked machine used by those skilled in magical arts. It is inactive." - -/obj/structure/constructshell/cultify() - return - -/obj/structure/constructshell/cult - icon_state = "construct-cult" - desc = "This eerie contraption looks like it would come alive if supplied with a missing ingredient." - -/obj/structure/constructshell/attackby(obj/item/O as obj, mob/user as mob) - if(istype(O, /obj/item/device/soulstone)) - var/obj/item/device/soulstone/S = O; - S.transfer_soul("CONSTRUCT",src,user) - - -////////////////////////////Proc for moving soul in and out off stone////////////////////////////////////// -/obj/item/device/soulstone/proc/transfer_human(var/mob/living/carbon/human/T,var/mob/U) - if(!istype(T)) - return; - if(src.imprinted != "empty") - U << "Capture failed!: The soul stone has already been imprinted with [src.imprinted]'s mind!" - return - if ((T.health + T.halloss) > config.health_threshold_crit && T.stat != DEAD) - U << "Capture failed!: Kill or maim the victim first!" - return - if(T.client == null) - U << "Capture failed!: The soul has already fled it's mortal frame." - return - if(src.contents.len) - U << "Capture failed!: The soul stone is full! Use or free an existing soul to make room." - return - - for(var/obj/item/W in T) - T.drop_from_inventory(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 ) - animation.icon_state = "blank" - animation.icon = 'icons/mob/mob.dmi' - animation.master = T - flick("dust-h", animation) - qdel(animation) - - var/mob/living/simple_animal/shade/S = new /mob/living/simple_animal/shade( T.loc ) - S.forceMove(src) //put shade in stone - S.status_flags |= GODMODE //So they won't die inside the stone somehow - S.canmove = 0//Can't move out of the soul stone - S.name = "Shade of [T.real_name]" - S.real_name = "Shade of [T.real_name]" - S.icon = T.icon - S.icon_state = T.icon_state - S.overlays = T.overlays - S.color = rgb(254,0,0) - S.alpha = 127 - if (T.client) - T.client.mob = S - S.cancel_camera() - - - src.icon_state = "soulstone2" - src.name = "Soul Stone: [S.real_name]" - to_chat(S, "Your soul has been captured! You are now bound to [U.name]'s will, help them suceed in their goals at all costs.") - to_chat(U, "Capture successful! : [T.real_name]'s soul has been ripped from their body and stored within the soul stone.") - to_chat(U, "The soulstone has been imprinted with [S.real_name]'s mind, it will no longer react to other souls.") - src.imprinted = "[S.name]" - qdel(T) - -/obj/item/device/soulstone/proc/transfer_shade(var/mob/living/simple_animal/shade/T,var/mob/U) - if(!istype(T)) - return; - if (T.stat == DEAD) - to_chat(U, "Capture failed!: The shade has already been banished!") - return - if(src.contents.len) - to_chat(U, "Capture failed!: The soul stone is full! Use or free an existing soul to make room.") - return - if(T.name != src.imprinted) - to_chat(U, "Capture failed!: The soul stone has already been imprinted with [src.imprinted]'s mind!") - return - - T.forceMove(src) //put shade in stone - T.status_flags |= GODMODE - T.canmove = 0 - T.health = T.getMaxHealth() - src.icon_state = "soulstone2" - - to_chat(T, "Your soul has been recaptured by the soul stone, its arcane energies are reknitting your ethereal form") - to_chat(U, "Capture successful! : [T.name]'s has been recaptured and stored within the soul stone.") - -/obj/item/device/soulstone/proc/transfer_construct(var/obj/structure/constructshell/T,var/mob/U) - var/mob/living/simple_animal/shade/A = locate() in src - if(!A) - to_chat(U,"Capture failed!: The soul stone is empty! Go kill someone!") - return; - var/construct_class = input(U, "Please choose which type of construct you wish to create.") as null|anything in possible_constructs - switch(construct_class) - if("Juggernaut") - var/mob/living/simple_animal/construct/armoured/Z = new /mob/living/simple_animal/construct/armoured (get_turf(T.loc)) - Z.key = A.key - if(iscultist(U)) - cult.add_antagonist(Z.mind) - qdel(T) - to_chat(Z,"You are playing a Juggernaut. Though slow, you can withstand extreme punishment, and rip apart enemies and walls alike.") - to_chat(Z,"You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.") - Z.cancel_camera() - qdel(src) - if("Wraith") - var/mob/living/simple_animal/construct/wraith/Z = new /mob/living/simple_animal/construct/wraith (get_turf(T.loc)) - Z.key = A.key - if(iscultist(U)) - cult.add_antagonist(Z.mind) - qdel(T) - to_chat(Z,"You are playing a Wraith. Though relatively fragile, you are fast, deadly, and even able to phase through walls.") - to_chat(Z,"You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.") - Z.cancel_camera() - qdel(src) - if("Artificer") - var/mob/living/simple_animal/construct/builder/Z = new /mob/living/simple_animal/construct/builder (get_turf(T.loc)) - Z.key = A.key - if(iscultist(U)) - cult.add_antagonist(Z.mind) - qdel(T) - to_chat(Z,"You are playing an Artificer. You are incredibly weak and fragile, but you are able to construct fortifications, repair allied constructs (by clicking on them), and even create new constructs") - to_chat(Z,"You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.") - Z.cancel_camera() - qdel(src) - if("Harvester") - var/mob/living/simple_animal/construct/harvester/Z = new /mob/living/simple_animal/construct/harvester (get_turf(T.loc)) - Z.key = A.key - if(iscultist(U)) - cult.add_antagonist(Z.mind) - qdel(T) - to_chat(Z,"You are playing a Harvester. You are relatively weak, but your physical frailty is made up for by your ranged abilities.") - to_chat(Z,"You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.") - Z.cancel_camera() - qdel(src) - if("Behemoth") - var/mob/living/simple_animal/construct/behemoth/Z = new /mob/living/simple_animal/construct/behemoth (get_turf(T.loc)) - Z.key = A.key - if(iscultist(U)) - cult.add_antagonist(Z.mind) - qdel(T) - to_chat(Z,"You are playing a Behemoth. You are incredibly slow, though your slowness is made up for by the fact your shell is far larger than any of your bretheren. You are the Unstoppable Force, and Immovable Object.") - to_chat(Z,"You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.") - Z.cancel_camera() - qdel(src) - -/obj/item/device/soulstone/proc/transfer_soul(var/choice as text, var/target, var/mob/U as mob) - switch(choice) - if("VICTIM") - transfer_human(target,U) - if("SHADE") - transfer_shade(target,U) - if("CONSTRUCT") - transfer_construct(target,U) +///////////////////////// +// Soulstone +///////////////////////// + +/obj/item/device/soulstone + name = "Soul Stone Shard" + icon = 'icons/obj/wizard.dmi' + icon_state = "soulstone" + 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 = ITEMSIZE_SMALL + slot_flags = SLOT_BELT + origin_tech = list(TECH_BLUESPACE = 4, TECH_MATERIAL = 4) + var/imprinted = "empty" + var/possible_constructs = list("Juggernaut","Wraith","Artificer","Harvester") + +/obj/item/device/soulstone/cultify() + return + +//////////////////////////////Capturing//////////////////////////////////////////////////////// + +/obj/item/device/soulstone/attack(mob/living/carbon/human/M as mob, mob/user as mob) + if(!istype(M, /mob/living/carbon/human))//If target is not a human. + return ..() + if(istype(M, /mob/living/carbon/human/dummy)) + return..() + if(jobban_isbanned(M, "cultist")) + user << "This person's soul is too corrupt and cannot be captured!" + return..() + + if(M.has_brain_worms()) //Borer stuff - RR + user << "This being is corrupted by an alien intelligence and cannot be soul trapped." + return..() + + add_attack_logs(user,M,"Soulstone'd with [src.name]") + transfer_soul("VICTIM", M, user) + return + + +///////////////////Options for using captured souls/////////////////////////////////////// + +/obj/item/device/soulstone/attack_self(mob/user) + if (!in_range(src, user)) + return + user.set_machine(src) + var/dat = "Soul Stone
" + for(var/mob/living/simple_mob/construct/shade/A in src) + dat += "Captured Soul: [A.name]
" + dat += {"Summon Shade"} + dat += "
" + dat += {" Close"} + user << browse(dat, "window=aicard") + onclose(user, "aicard") + return + + + + +/obj/item/device/soulstone/Topic(href, href_list) + var/mob/U = usr + if (!in_range(src, U)||U.machine!=src) + U << browse(null, "window=aicard") + U.unset_machine() + return + + add_fingerprint(U) + U.set_machine(src) + + switch(href_list["choice"])//Now we switch based on choice. + if ("Close") + U << browse(null, "window=aicard") + U.unset_machine() + return + + if ("Summon") + for(var/mob/living/simple_mob/construct/shade/A in src) + A.status_flags &= ~GODMODE + A.canmove = 1 + A << "You have been released from your prison, but you are still bound to [U.name]'s will. Help them suceed in their goals at all costs." + A.forceMove(U.loc) + A.cancel_camera() + src.icon_state = "soulstone" + attack_self(U) + +///////////////////////////Transferring to constructs///////////////////////////////////////////////////// +/obj/structure/constructshell + name = "empty shell" + icon = 'icons/obj/wizard.dmi' + icon_state = "construct" + desc = "A wicked machine used by those skilled in magical arts. It is inactive." + +/obj/structure/constructshell/cultify() + return + +/obj/structure/constructshell/cult + icon_state = "construct-cult" + desc = "This eerie contraption looks like it would come alive if supplied with a missing ingredient." + +/obj/structure/constructshell/attackby(obj/item/O as obj, mob/user as mob) + if(istype(O, /obj/item/device/soulstone)) + var/obj/item/device/soulstone/S = O; + S.transfer_soul("CONSTRUCT",src,user) + + +////////////////////////////Proc for moving soul in and out off stone////////////////////////////////////// +/obj/item/device/soulstone/proc/transfer_human(var/mob/living/carbon/human/T,var/mob/U) + if(!istype(T)) + return; + if(src.imprinted != "empty") + U << "Capture failed!: The soul stone has already been imprinted with [src.imprinted]'s mind!" + return + if ((T.health + T.halloss) > config.health_threshold_crit && T.stat != DEAD) + U << "Capture failed!: Kill or maim the victim first!" + return + if(T.client == null) + U << "Capture failed!: The soul has already fled it's mortal frame." + return + if(src.contents.len) + U << "Capture failed!: The soul stone is full! Use or free an existing soul to make room." + return + + for(var/obj/item/W in T) + T.drop_from_inventory(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 ) + animation.icon_state = "blank" + animation.icon = 'icons/mob/mob.dmi' + animation.master = T + flick("dust-h", animation) + qdel(animation) + + var/mob/living/simple_mob/construct/shade/S = new /mob/living/simple_mob/construct/shade( T.loc ) + S.forceMove(src) //put shade in stone + S.status_flags |= GODMODE //So they won't die inside the stone somehow + S.canmove = 0//Can't move out of the soul stone + S.name = "Shade of [T.real_name]" + S.real_name = "Shade of [T.real_name]" + S.icon = T.icon + S.icon_state = T.icon_state + S.overlays = T.overlays + S.color = rgb(254,0,0) + S.alpha = 127 + if (T.client) + T.client.mob = S + S.cancel_camera() + + + src.icon_state = "soulstone2" + src.name = "Soul Stone: [S.real_name]" + to_chat(S, "Your soul has been captured! You are now bound to [U.name]'s will, help them suceed in their goals at all costs.") + to_chat(U, "Capture successful! : [T.real_name]'s soul has been ripped from their body and stored within the soul stone.") + to_chat(U, "The soulstone has been imprinted with [S.real_name]'s mind, it will no longer react to other souls.") + src.imprinted = "[S.name]" + qdel(T) + +/obj/item/device/soulstone/proc/transfer_shade(var/mob/living/simple_mob/construct/shade/T,var/mob/U) + if(!istype(T)) + return; + if (T.stat == DEAD) + to_chat(U, "Capture failed!: The shade has already been banished!") + return + if(src.contents.len) + to_chat(U, "Capture failed!: The soul stone is full! Use or free an existing soul to make room.") + return + if(T.name != src.imprinted) + to_chat(U, "Capture failed!: The soul stone has already been imprinted with [src.imprinted]'s mind!") + return + + T.forceMove(src) //put shade in stone + T.status_flags |= GODMODE + T.canmove = 0 + T.health = T.getMaxHealth() + src.icon_state = "soulstone2" + + to_chat(T, "Your soul has been recaptured by the soul stone, its arcane energies are reknitting your ethereal form") + to_chat(U, "Capture successful! : [T.name]'s has been recaptured and stored within the soul stone.") + +/obj/item/device/soulstone/proc/transfer_construct(var/obj/structure/constructshell/T,var/mob/U) + var/mob/living/simple_mob/construct/shade/A = locate() in src + if(!A) + to_chat(U,"Capture failed!: The soul stone is empty! Go kill someone!") + return; + var/construct_class = input(U, "Please choose which type of construct you wish to create.") as null|anything in possible_constructs + switch(construct_class) + if("Juggernaut") + var/mob/living/simple_mob/construct/juggernaut/Z = new /mob/living/simple_mob/construct/juggernaut (get_turf(T.loc)) + Z.key = A.key + if(iscultist(U)) + cult.add_antagonist(Z.mind) + qdel(T) + to_chat(Z,"You are playing a Juggernaut. Though slow, you can withstand extreme punishment, and rip apart enemies and walls alike.") + to_chat(Z,"You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.") + Z.cancel_camera() + qdel(src) + if("Wraith") + var/mob/living/simple_mob/construct/wraith/Z = new /mob/living/simple_mob/construct/wraith (get_turf(T.loc)) + Z.key = A.key + if(iscultist(U)) + cult.add_antagonist(Z.mind) + qdel(T) + to_chat(Z,"You are playing a Wraith. Though relatively fragile, you are fast, deadly, and even able to phase through walls.") + to_chat(Z,"You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.") + Z.cancel_camera() + qdel(src) + if("Artificer") + var/mob/living/simple_mob/construct/artificer/Z = new /mob/living/simple_mob/construct/artificer (get_turf(T.loc)) + Z.key = A.key + if(iscultist(U)) + cult.add_antagonist(Z.mind) + qdel(T) + to_chat(Z,"You are playing an Artificer. You are incredibly weak and fragile, but you are able to construct fortifications, repair allied constructs (by clicking on them), and even create new constructs") + to_chat(Z,"You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.") + Z.cancel_camera() + qdel(src) + if("Harvester") + var/mob/living/simple_mob/construct/harvester/Z = new /mob/living/simple_mob/construct/harvester (get_turf(T.loc)) + Z.key = A.key + if(iscultist(U)) + cult.add_antagonist(Z.mind) + qdel(T) + to_chat(Z,"You are playing a Harvester. You are relatively weak, but your physical frailty is made up for by your ranged abilities.") + to_chat(Z,"You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.") + Z.cancel_camera() + qdel(src) + if("Behemoth") + var/mob/living/simple_mob/construct/juggernaut/behemoth/Z = new /mob/living/simple_mob/construct/juggernaut/behemoth (get_turf(T.loc)) + Z.key = A.key + if(iscultist(U)) + cult.add_antagonist(Z.mind) + qdel(T) + to_chat(Z,"You are playing a Behemoth. You are incredibly slow, though your slowness is made up for by the fact your shell is far larger than any of your bretheren. You are the Unstoppable Force, and Immovable Object.") + to_chat(Z,"You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.") + Z.cancel_camera() + qdel(src) + +/obj/item/device/soulstone/proc/transfer_soul(var/choice as text, var/target, var/mob/U as mob) + switch(choice) + if("VICTIM") + transfer_human(target,U) + if("SHADE") + transfer_shade(target,U) + if("CONSTRUCT") + transfer_construct(target,U) diff --git a/code/game/gamemodes/endgame/supermatter_cascade/blob.dm b/code/game/gamemodes/endgame/supermatter_cascade/blob.dm index 1051587d13..99e28f5ef7 100644 --- a/code/game/gamemodes/endgame/supermatter_cascade/blob.dm +++ b/code/game/gamemodes/endgame/supermatter_cascade/blob.dm @@ -16,11 +16,11 @@ /turf/unsimulated/wall/supermatter/New() ..() - processing_turfs.Add(src) + START_PROCESSING(SSturfs, src) next_check = world.time+5 SECONDS /turf/unsimulated/wall/supermatter/Destroy() - processing_turfs.Remove(src) + STOP_PROCESSING(SSturfs, src) ..() /turf/unsimulated/wall/supermatter/process() @@ -29,7 +29,7 @@ // No more available directions? Shut down process(). if(avail_dirs.len==0) - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) return 1 // We're checking, reset the timer. @@ -57,7 +57,7 @@ T.ChangeTurf(type) if((spawned & (NORTH|SOUTH|EAST|WEST)) == (NORTH|SOUTH|EAST|WEST)) - processing_turfs -= src + STOP_PROCESSING(SSturfs, src) return /turf/unsimulated/wall/supermatter/attack_generic(mob/user as mob) diff --git a/code/game/gamemodes/endgame/supermatter_cascade/portal.dm b/code/game/gamemodes/endgame/supermatter_cascade/portal.dm index 7f7310f996..aef330c144 100644 --- a/code/game/gamemodes/endgame/supermatter_cascade/portal.dm +++ b/code/game/gamemodes/endgame/supermatter_cascade/portal.dm @@ -16,7 +16,7 @@ /obj/singularity/narsie/large/exit/New() ..() - processing_objects.Add(src) + START_PROCESSING(SSobj, src) /obj/singularity/narsie/large/exit/update_icon() overlays = 0 diff --git a/code/game/gamemodes/events.dm b/code/game/gamemodes/events.dm index 4b2ab0cd7d..573f10a9b4 100644 --- a/code/game/gamemodes/events.dm +++ b/code/game/gamemodes/events.dm @@ -206,7 +206,7 @@ var/hadevent = 0 /proc/carp_migration() // -- Darem for(var/obj/effect/landmark/C in landmarks_list) if(C.name == "carpspawn") - new /mob/living/simple_animal/hostile/carp(C.loc) + new /mob/living/simple_mob/animal/space/carp(C.loc) //sleep(100) spawn(rand(300, 600)) //Delayed announcements to keep the crew on their toes. command_announcement.Announce("Unknown biological entities have been detected near \the [station_name()], please stand-by.", "Lifesign Alert", new_sound = 'sound/AI/commandreport.ogg') diff --git a/code/game/gamemodes/events/holidays/Christmas.dm b/code/game/gamemodes/events/holidays/Christmas.dm index b2c4b68a5a..ed86c4045d 100644 --- a/code/game/gamemodes/events/holidays/Christmas.dm +++ b/code/game/gamemodes/events/holidays/Christmas.dm @@ -4,12 +4,12 @@ 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) - //for(var/mob/living/simple_animal/corgi/Ian/Ian in mob_list) + //for(var/mob/living/simple_mob/corgi/Ian/Ian in mob_list) // Ian.place_on_head(new /obj/item/clothing/head/helmet/space/santahat(Ian)) /proc/ChristmasEvent() for(var/obj/structure/flora/tree/pine/xmas in world) - var/mob/living/simple_animal/hostile/tree/evil_tree = new /mob/living/simple_animal/hostile/tree(xmas.loc) + var/mob/living/simple_mob/animal/space/tree/evil_tree = new /mob/living/simple_mob/animal/space/tree(xmas.loc) evil_tree.icon_state = xmas.icon_state evil_tree.icon_living = evil_tree.icon_state evil_tree.icon_dead = evil_tree.icon_state diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 8ab82e5e84..29139b3a3a 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -176,12 +176,12 @@ var/global/list/additional_antag_types = list() /datum/game_mode/proc/refresh_event_modifiers() if(event_delay_mod_moderate || event_delay_mod_major) - event_manager.report_at_round_end = 1 + SSevents.report_at_round_end = TRUE if(event_delay_mod_moderate) - var/datum/event_container/EModerate = event_manager.event_containers[EVENT_LEVEL_MODERATE] + var/datum/event_container/EModerate = SSevents.event_containers[EVENT_LEVEL_MODERATE] EModerate.delay_modifier = event_delay_mod_moderate if(event_delay_mod_moderate) - var/datum/event_container/EMajor = event_manager.event_containers[EVENT_LEVEL_MAJOR] + var/datum/event_container/EMajor = SSevents.event_containers[EVENT_LEVEL_MAJOR] EMajor.delay_modifier = event_delay_mod_major /datum/game_mode/proc/pre_setup() @@ -464,7 +464,7 @@ proc/display_roundstart_logout_report() if(L.ckey) var/found = 0 - for(var/client/C in clients) + for(var/client/C in GLOB.clients) if(C.ckey == L.ckey) found = 1 break diff --git a/code/game/gamemodes/game_mode_latespawn.dm b/code/game/gamemodes/game_mode_latespawn.dm index ecafc0dbc5..578c1a0d8c 100644 --- a/code/game/gamemodes/game_mode_latespawn.dm +++ b/code/game/gamemodes/game_mode_latespawn.dm @@ -13,7 +13,7 @@ ///process() ///Called by the gameticker -/datum/game_mode/proc/process() +/datum/game_mode/process() // Slow this down a bit so latejoiners have a chance of being antags. process_count++ if(process_count >= 10) diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm index 7424b514c4..c1e0b3fdd1 100644 --- a/code/game/gamemodes/gameticker.dm +++ b/code/game/gamemodes/gameticker.dm @@ -307,7 +307,7 @@ var/global/datum/controller/gameticker/ticker to_chat(M, "Colony Directorship not forced on anyone.") - proc/process() + process() if(current_state != GAME_STATE_PLAYING) return 0 @@ -439,7 +439,7 @@ var/global/datum/controller/gameticker/ticker mode.declare_completion()//To declare normal completion. //Ask the event manager to print round end information - event_manager.RoundEnd() + SSevents.RoundEnd() //Print a list of antagonists to the server log var/list/total_antagonists = list() diff --git a/code/game/gamemodes/malfunction/malf_research.dm b/code/game/gamemodes/malfunction/malf_research.dm index da7a4df668..58f7d56c13 100644 --- a/code/game/gamemodes/malfunction/malf_research.dm +++ b/code/game/gamemodes/malfunction/malf_research.dm @@ -43,7 +43,7 @@ // Proc: process() // Parameters: None // Description: Processes CPU gain and research progress based on "realtime" calculation. -/datum/malf_research/proc/process(var/idle = 0) +/datum/malf_research/process(var/idle = 0) if(idle) // No power or running on APU. Do nothing. last_tick = world.time return diff --git a/code/game/gamemodes/malfunction/malf_research_ability.dm b/code/game/gamemodes/malfunction/malf_research_ability.dm index c6916208bd..8002dcead8 100644 --- a/code/game/gamemodes/malfunction/malf_research_ability.dm +++ b/code/game/gamemodes/malfunction/malf_research_ability.dm @@ -7,7 +7,7 @@ var/datum/malf_research_ability/next = null // Next research (if applicable). -/datum/malf_research_ability/proc/process(var/time = 0) +/datum/malf_research_ability/process(var/time = 0) invested += time if(invested >= price) unlocked = 1 \ No newline at end of file diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index ac9a16e8b6..a410ebfe24 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -808,7 +808,7 @@ datum/objective/heist/salvage /datum/objective/borer_survive/check_completion() if(owner) - var/mob/living/simple_animal/borer/B = owner + var/mob/living/simple_mob/animal/borer/B = owner if(istype(B) && B.stat < 2 && B.host && B.host.stat < 2) return 1 return 0 @@ -817,7 +817,7 @@ datum/objective/heist/salvage /datum/objective/borer_reproduce/check_completion() if(owner && owner.current) - var/mob/living/simple_animal/borer/B = owner.current + var/mob/living/simple_mob/animal/borer/B = owner.current if(istype(B) && B.has_reproduced) return 1 return 0 diff --git a/code/game/gamemodes/technomancer/assistance/golem.dm b/code/game/gamemodes/technomancer/assistance/golem.dm deleted file mode 100644 index 6b8654e719..0000000000 --- a/code/game/gamemodes/technomancer/assistance/golem.dm +++ /dev/null @@ -1,258 +0,0 @@ -//An AI-controlled 'companion' for the Technomancer. It's tough, strong, and can also use spells. -/mob/living/simple_animal/technomancer_golem - name = "G.O.L.E.M." - desc = "A rather unusual looking synthetic." - icon = 'icons/mob/mob.dmi' - icon_state = "technomancer_golem" - health = 250 - maxHealth = 250 - stop_automated_movement = 1 - wander = 0 - response_help = "pets" - response_disarm = "pushes away" - response_harm = "punches" - harm_intent_damage = 3 - - heat_damage_per_tick = 0 - cold_damage_per_tick = 0 - - min_oxy = 0 - max_oxy = 0 - min_tox = 0 - max_tox = 0 - min_co2 = 0 - max_co2 = 0 - min_n2 = 0 - max_n2 = 0 - unsuitable_atoms_damage = 0 - speed = 0 - - melee_damage_lower = 30 // It has a built in esword. - melee_damage_upper = 30 - attack_sound = 'sound/weapons/blade1.ogg' - attacktext = list("slashed") - friendly = "hugs" - resistance = 0 - melee_miss_chance = 0 - - var/obj/item/weapon/technomancer_core/golem/core = null - var/obj/item/weapon/spell/active_spell = null // Shield and ranged spells - var/mob/living/master = null - - var/list/known_spells = list( - "beam" = /obj/item/weapon/spell/projectile/beam, - "chain lightning" = /obj/item/weapon/spell/projectile/chain_lightning, - "force missile" = /obj/item/weapon/spell/projectile/force_missile, - "ionic bolt" = /obj/item/weapon/spell/projectile/ionic_bolt, - "lightning" = /obj/item/weapon/spell/projectile/lightning, - "blink" = /obj/item/weapon/spell/blink, - "dispel" = /obj/item/weapon/spell/dispel, - "oxygenate" = /obj/item/weapon/spell/oxygenate, - "mend life" = /obj/item/weapon/spell/modifier/mend_life, - "mend synthetic" = /obj/item/weapon/spell/modifier/mend_synthetic, - "mend organs" = /obj/item/weapon/spell/mend_organs, - "purify" = /obj/item/weapon/spell/modifier/purify, - "resurrect" = /obj/item/weapon/spell/resurrect, - "passwall" = /obj/item/weapon/spell/passwall, - "repel missiles" = /obj/item/weapon/spell/modifier/repel_missiles, - "corona" = /obj/item/weapon/spell/modifier/corona, - "haste" = /obj/item/weapon/spell/modifier/haste - ) - - // Holds the overlays, when idle or attacking. - var/image/sword_image = null - var/image/spell_image = null - // These contain icon_states for each frame of an attack animation, which is swapped in and out manually, because BYOND. - // They are assoc lists, to hold the frame duration and the frame icon_state in one list. - var/list/spell_pre_attack_states = list( - "golem_spell_attack_1" = 1, - "golem_spell_attack_2" = 2, - "golem_spell_attack_3" = 2 - ) - var/list/spell_post_attack_states = list( - "golem_spell_attack_4" = 2, - "golem_spell_attack_5" = 3, - "golem_spell_attack_6" = 3 - ) - var/list/sword_pre_attack_states = list( - "golem_sword_attack_1" = 1, - "golem_sword_attack_2" = 5 - ) - var/list/sword_post_attack_states = list( - "golem_sword_attack_3" = 1, - "golem_sword_attack_4" = 3 - ) - -/mob/living/simple_animal/technomancer_golem/New() - ..() - core = new(src) - sword_image = image(icon, src, "golem_sword") - spell_image = image(icon, src, "golem_spell") - update_icon() - -/mob/living/simple_animal/technomancer_golem/Destroy() - qdel(core) - qdel(sword_image) - qdel(spell_image) - return ..() - -/mob/living/simple_animal/technomancer_golem/unref_spell() - active_spell = null - return ..() - -/mob/living/simple_animal/hostile/hivebot/death() - ..() - visible_message("\The [src] disintegrates!") - new /obj/effect/decal/cleanable/blood/gibs/robot(src.loc) - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(3, 1, src) - s.start() - qdel(src) - -/mob/living/simple_animal/technomancer_golem/update_icon() - overlays.Cut() - overlays += sword_image - overlays += spell_image - update_modifier_visuals() - -// Unfortunately, BYOND does not let you flick() images or other overlays, so we need to do this in a terrible way. -/atom/proc/manual_flick(var/list/frames, var/image/I, var/reset_to = null) - // Swap in and out each frame manually. - for(var/frame in frames) - overlays -= I - I.icon_state = frame - overlays += I - sleep(frames[frame]) - if(reset_to) - // One more time to reset it to what it was before. - overlays -= I - I.icon_state = reset_to - overlays += I - -/mob/living/simple_animal/technomancer_golem/proc/spellcast_pre_animation() - setClickCooldown(5) - manual_flick(spell_pre_attack_states, spell_image, reset_to = "golem_spell_attack_3") - -/mob/living/simple_animal/technomancer_golem/proc/spellcast_post_animation() - setClickCooldown(8) - manual_flick(spell_post_attack_states, spell_image, reset_to = "golem_spell") - -/mob/living/simple_animal/technomancer_golem/proc/sword_pre_animation() - setClickCooldown(6) - manual_flick(sword_pre_attack_states, sword_image) - -/mob/living/simple_animal/technomancer_golem/proc/sword_post_animation() - setClickCooldown(3) - manual_flick(sword_post_attack_states, sword_image, reset_to = "golem_sword") - -/mob/living/simple_animal/technomancer_golem/DoPunch(var/atom/A) - sword_pre_animation() - . = ..() // This does the actual attack and will check adjacency again. - sword_post_animation() - -/mob/living/simple_animal/technomancer_golem/isSynthetic() - return TRUE // So Mend Synthetic will work on them. - -/mob/living/simple_animal/technomancer_golem/speech_bubble_appearance() - return "synthetic_evil" - -/mob/living/simple_animal/technomancer_golem/place_spell_in_hand(var/path) - if(!path || !ispath(path)) - return 0 - - if(active_spell) - qdel(active_spell) // Get rid of our old spell. - - var/obj/item/weapon/spell/S = new path(src) - active_spell = S - -/mob/living/simple_animal/technomancer_golem/verb/test_giving_spells() - var/choice = input(usr, "What spell?", "Give spell") as null|anything in known_spells - if(choice) - place_spell_in_hand(known_spells[choice]) - else - qdel(active_spell) - -// Used to cast spells. -/mob/living/simple_animal/technomancer_golem/RangedAttack(var/atom/A, var/params) - if(active_spell) - spellcast_pre_animation() - if(active_spell.cast_methods & CAST_RANGED) - active_spell.on_ranged_cast(A, src) - spellcast_post_animation() - -/mob/living/simple_animal/technomancer_golem/UnarmedAttack(var/atom/A, var/proximity) - if(proximity) - if(active_spell) - spellcast_pre_animation() - if(!Adjacent(A)) // Need to check again since they might've moved while 'warming up'. - spellcast_post_animation() - return - var/effective_cooldown = round(active_spell.cooldown * core.cooldown_modifier, 5) - if(active_spell.cast_methods & CAST_MELEE) - active_spell.on_melee_cast(A, src) - else if(active_spell.cast_methods & CAST_RANGED) - active_spell.on_ranged_cast(A, src) - spellcast_post_animation() - src.setClickCooldown(effective_cooldown) - else - ..() - -/mob/living/simple_animal/technomancer_golem/get_technomancer_core() - return core - -/mob/living/simple_animal/technomancer_golem/proc/bind_to_mob(mob/user) - if(!user || master) - return - master = user - name = "[master]'s [initial(name)]" - -/mob/living/simple_animal/technomancer_golem/examine(mob/user) - ..() - if(user.mind && technomancers.is_antagonist(user.mind)) - user << "Your pride and joy. It's a very special synthetic robot, capable of using functions similar to you, and you built it \ - yourself! It'll always stand by your side, ready to help you out. You have no idea what GOLEM stands for, however..." - -/mob/living/simple_animal/technomancer_golem/Life() - ..() - handle_ai() - -// This is where the real spaghetti begins. -/mob/living/simple_animal/technomancer_golem/proc/handle_ai() - if(!master) - return - if(get_dist(src, master) > 6 || src.z != master.z) - targeted_blink(master) - - // Give our allies buffs and heals. - for(var/mob/living/L in view(src)) - if(L in friends) - support_friend(L) - return - -/mob/living/simple_animal/technomancer_golem/proc/support_friend(var/mob/living/L) - if(L.getBruteLoss() >= 10 || L.getFireLoss() >= 10) - if(L.isSynthetic() && !L.has_modifier_of_type(/datum/modifier/technomancer/mend_synthetic)) - place_spell_in_hand(known_spells["mend synthetic"]) - targeted_blink(L) - UnarmedAttack(L, 1) - else if(!L.has_modifier_of_type(/datum/modifier/technomancer/mend_life)) - place_spell_in_hand(known_spells["mend life"]) - targeted_blink(L) - UnarmedAttack(L, 1) - return - - - // Give them repel missiles if they lack it. - if(!L.has_modifier_of_type(/datum/modifier/technomancer/repel_missiles)) - place_spell_in_hand(known_spells["repel missiles"]) - RangedAttack(L) - return - -/mob/living/simple_animal/technomancer_golem/proc/targeted_blink(var/atom/target) - var/datum/effect/effect/system/spark_spread/spark_system = new() - spark_system.set_up(5, 0, get_turf(src)) - spark_system.start() - src.visible_message("\The [src] vanishes!") - src.forceMove(get_turf(target)) - return \ No newline at end of file diff --git a/code/game/gamemodes/technomancer/catalog.dm b/code/game/gamemodes/technomancer/catalog.dm index 25f824d2b3..633f3f6220 100644 --- a/code/game/gamemodes/technomancer/catalog.dm +++ b/code/game/gamemodes/technomancer/catalog.dm @@ -331,7 +331,8 @@ var/list/all_technomancer_assistance = typesof(/datum/technomancer/assistance) - if(href_list["refund_functions"]) - if(H.z != 2) + var/turf/T = get_turf(H) + if(T.z in using_map.player_levels) H << "You can only refund at your base, it's too late now!" return var/obj/item/weapon/technomancer_core/core = null @@ -347,7 +348,8 @@ var/list/all_technomancer_assistance = typesof(/datum/technomancer/assistance) - attack_self(H) /obj/item/weapon/technomancer_catalog/attackby(var/atom/movable/AM, var/mob/user) - if(user.z != 2) + var/turf/T = get_turf(user) + if(T.z in using_map.player_levels) to_chat(user, "You can only refund at your base, it's too late now!") return for(var/datum/technomancer/equipment/E in equipment_instances + assistance_instances) diff --git a/code/game/gamemodes/technomancer/core_obj.dm b/code/game/gamemodes/technomancer/core_obj.dm index 1e7488258b..9400e24bf1 100644 --- a/code/game/gamemodes/technomancer/core_obj.dm +++ b/code/game/gamemodes/technomancer/core_obj.dm @@ -38,11 +38,11 @@ /obj/item/weapon/technomancer_core/New() ..() - processing_objects |= src + START_PROCESSING(SSobj, src) /obj/item/weapon/technomancer_core/Destroy() dismiss_all_summons() - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) return ..() // Add the spell buttons to the HUD. @@ -130,7 +130,7 @@ for(var/mob/living/L in summoned_mobs) summoned_mobs -= L qdel(L) - for(var/mob/living/simple_animal/ward/ward in wards_in_use) + for(var/mob/living/ward in wards_in_use) wards_in_use -= ward qdel(ward) diff --git a/code/game/gamemodes/technomancer/devices/gloves_of_regen.dm b/code/game/gamemodes/technomancer/devices/gloves_of_regen.dm index 0056675afc..11343fdeac 100644 --- a/code/game/gamemodes/technomancer/devices/gloves_of_regen.dm +++ b/code/game/gamemodes/technomancer/devices/gloves_of_regen.dm @@ -37,12 +37,12 @@ wearer = null /obj/item/clothing/gloves/regen/New() - processing_objects |= src + START_PROCESSING(SSobj, src) ..() /obj/item/clothing/gloves/regen/Destroy() wearer = null - processing_objects -= src + STOP_PROCESSING(SSobj, src) return ..() /obj/item/clothing/gloves/regen/process() diff --git a/code/game/gamemodes/technomancer/devices/hypos.dm b/code/game/gamemodes/technomancer/devices/hypos.dm index f5174c45e3..002b3cfff0 100644 --- a/code/game/gamemodes/technomancer/devices/hypos.dm +++ b/code/game/gamemodes/technomancer/devices/hypos.dm @@ -1,16 +1,3 @@ -/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector - name = "empty hypo" - desc = "A refined version of the standard autoinjector, allowing greater capacity." - icon_state = "autoinjector" - amount_per_transfer_from_this = 15 - volume = 15 - origin_tech = list(TECH_BIO = 4) - filled_reagents = list("inaprovaline" = 15) - -/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/New() - ..() - - /datum/technomancer/consumable/hypo_brute name = "Trauma Hypo" desc = "A extended capacity hypo which can treat blunt trauma." @@ -59,50 +46,3 @@ desc = "A extended capacity hypo containing a dangerous cocktail of various combat stims." cost = 75 obj_path = /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/combat - - -/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/brute - name = "trauma hypo" - desc = "A refined version of the standard autoinjector, allowing greater capacity. This one is made to be used on victims of \ - moderate blunt trauma." - filled_reagents = list("bicaridine" = 15) - -/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/burn - name = "burn hypo" - desc = "A refined version of the standard autoinjector, allowing greater capacity. This one is made to be used on burn victims, \ - featuring an optimized chemical mixture to allow for rapid healing." - filled_reagents = list("kelotane" = 7.5, "dermaline" = 7.5) - -/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/toxin - name = "toxin hypo" - desc = "A refined version of the standard autoinjector, allowing greater capacity. This one is made to counteract toxins." - filled_reagents = list("anti_toxin" = 15) - -/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/oxy - name = "oxy hypo" - desc = "A refined version of the standard autoinjector, allowing greater capacity. This one is made to counteract oxygen \ - deprivation." - filled_reagents = list("dexalinp" = 10, "tricordrazine" = 5) - -/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/purity - name = "purity hypo" - desc = "A refined version of the standard autoinjector, allowing greater capacity. This variant excels at \ - resolving viruses, infections, radiation, and genetic maladies." - filled_reagents = list("spaceacillin" = 9, "arithrazine" = 5, "ryetalyn" = 1) - -/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/pain - name = "pain hypo" - desc = "A refined version of the standard autoinjector, allowing greater capacity. This one contains potent painkillers." - filled_reagents = list("tramadol" = 15) - -/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/organ - name = "organ hypo" - desc = "A refined version of the standard autoinjector, allowing greater capacity. Organ damage is resolved by this variant." - filled_reagents = list("alkysine" = 1, "imidazoline" = 1, "peridaxon" = 13) - -/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/combat - name = "combat hypo" - desc = "A refined version of the standard autoinjector, allowing greater capacity. This is a more dangerous and potentially \ - addictive hypo compared to others, as it contains a potent cocktail of various chemicals to optimize the recipient's combat \ - ability." - filled_reagents = list("bicaridine" = 3, "kelotane" = 1.5, "dermaline" = 1.5, "oxycodone" = 3, "hyperzine" = 3, "tricordrazine" = 3) diff --git a/code/game/gamemodes/technomancer/devices/tesla_armor.dm b/code/game/gamemodes/technomancer/devices/tesla_armor.dm index 56f2085850..86d6f82b08 100644 --- a/code/game/gamemodes/technomancer/devices/tesla_armor.dm +++ b/code/game/gamemodes/technomancer/devices/tesla_armor.dm @@ -75,9 +75,10 @@ H.update_action_buttons() ..() -/obj/item/clothing/suit/armor/tesla/proc/shoot_lightning(var/mob/target, var/power) - var/obj/item/projectile/beam/lightning/lightning = new(src) +/obj/item/clothing/suit/armor/tesla/proc/shoot_lightning(mob/target, power) + var/obj/item/projectile/beam/lightning/lightning = new(get_turf(src)) lightning.power = power - lightning.launch(target) + lightning.old_style_target(target) + lightning.fire() visible_message("\The [src] strikes \the [target] with lightning!") playsound(get_turf(src), 'sound/weapons/gauss_shoot.ogg', 75, 1) \ No newline at end of file diff --git a/code/game/gamemodes/technomancer/spell_objs_helpers.dm b/code/game/gamemodes/technomancer/spell_objs_helpers.dm index 105b3b3e9c..cf83640775 100644 --- a/code/game/gamemodes/technomancer/spell_objs_helpers.dm +++ b/code/game/gamemodes/technomancer/spell_objs_helpers.dm @@ -1,12 +1,17 @@ -//Returns 1 if the turf is dense, or if there's dense objects on it, unless told to ignore them. -/turf/proc/check_density(var/ignore_objs = 0) +//Returns 1 if the turf is dense, or if there's dense objects/mobs on it, unless told to ignore them. +/turf/proc/check_density(var/ignore_objs = FALSE, var/ignore_mobs = FALSE) if(density) - return 1 - if(!ignore_objs) + return TRUE + if(!ignore_objs || !ignore_mobs) for(var/atom/movable/stuff in contents) if(stuff.density) - return 1 - return 0 + if(ignore_objs && isobj(stuff)) + continue + else if(ignore_mobs && isliving(stuff)) // Ghosts aren't dense but keeping this limited to living type will probably save headaches in the future. + continue + else + return TRUE + return FALSE // Used to distinguish friend from foe. /obj/item/weapon/spell/proc/is_ally(var/mob/living/L) @@ -14,9 +19,9 @@ return 1 if(L.mind && technomancers.is_antagonist(L.mind)) // This should be done better since we might want opposing technomancers later. return 1 - if(istype(L, /mob/living/simple_animal/hostile)) // Mind controlled simple mobs count as allies too. - var/mob/living/simple_animal/SA = L - if(owner in SA.friends) + if(istype(L, /mob/living/simple_mob)) // Mind controlled simple mobs count as allies too. + var/mob/living/simple_mob/SM = L + if(owner in SM.friends) return 1 return 0 diff --git a/code/game/gamemodes/technomancer/spells/abjuration.dm b/code/game/gamemodes/technomancer/spells/abjuration.dm index 146c90a987..0eb566a637 100644 --- a/code/game/gamemodes/technomancer/spells/abjuration.dm +++ b/code/game/gamemodes/technomancer/spells/abjuration.dm @@ -16,12 +16,12 @@ /obj/item/weapon/spell/abjuration/on_ranged_cast(atom/hit_atom, mob/user) if(istype(hit_atom, /mob/living) && pay_energy(500) && within_range(hit_atom)) var/mob/living/L = hit_atom - var/mob/living/simple_animal/SA = null + var/mob/living/simple_mob/SM = null //Bit of a roundabout typecheck, in order to test for two variables from two different mob types in one line. - if(istype(L, /mob/living/simple_animal)) - SA = L - if(L.summoned || (SA && SA.supernatural) ) + if(istype(L, /mob/living/simple_mob)) + SM = L + if(L.summoned || (SM && SM.supernatural) ) if(L.client) // Player-controlled mobs are immune to being killed by this. user << "\The [L] resists your attempt to banish it!" L << "\The [user] tried to teleport you far away, but failed." @@ -29,8 +29,8 @@ else visible_message("\The [L] vanishes!") qdel(L) - else if(istype(L, /mob/living/simple_animal/construct)) - var/mob/living/simple_animal/construct/evil = L + else if(istype(L, /mob/living/simple_mob/construct)) + var/mob/living/simple_mob/construct/evil = L evil << "\The [user]'s abjuration purges your form!" evil.purge = 3 adjust_instability(5) diff --git a/code/game/gamemodes/technomancer/spells/aspect_aura.dm b/code/game/gamemodes/technomancer/spells/aspect_aura.dm index 577f356229..833f72a2fb 100644 --- a/code/game/gamemodes/technomancer/spells/aspect_aura.dm +++ b/code/game/gamemodes/technomancer/spells/aspect_aura.dm @@ -44,10 +44,10 @@ /obj/item/weapon/spell/aura/New() ..() set_light(7, 4, l_color = glow_color) - processing_objects |= src + START_PROCESSING(SSobj, src) /obj/item/weapon/spell/aura/Destroy() - processing_objects -= src + STOP_PROCESSING(SSobj, src) ..() /obj/item/weapon/spell/aura/process() @@ -120,7 +120,7 @@ for(var/mob/living/carbon/human/H in nearby_mobs) //Heal our apprentices if(H.mind && technomancers.is_antagonist(H.mind)) mobs_to_heal |= H - for(var/mob/living/simple_animal/hostile/SAH in nearby_mobs) //Heal our controlled mobs + for(var/mob/living/simple_mob/hostile/SAH in nearby_mobs) //Heal our controlled mobs if(owner in SAH.friends) mobs_to_heal |= SAH else diff --git a/code/game/gamemodes/technomancer/spells/audible_deception.dm b/code/game/gamemodes/technomancer/spells/audible_deception.dm index 9e82c46ad8..4b4edc261b 100644 --- a/code/game/gamemodes/technomancer/spells/audible_deception.dm +++ b/code/game/gamemodes/technomancer/spells/audible_deception.dm @@ -31,14 +31,14 @@ "Shotgun Pumping" = 'sound/weapons/shotgunpump.ogg', "Flash" = 'sound/weapons/flash.ogg', "Bite" = 'sound/weapons/bite.ogg', - "Gun Firing" = 'sound/weapons/gunshot.ogg', - "Desert Eagle Firing" = 'sound/weapons/deagle.ogg', - "Rifle Firing" = 'sound/weapons/rifleshot.ogg', - "Sniper Rifle Firing" = 'sound/weapons/svd_shot.ogg', - "AT Rifle Firing" = 'sound/weapons/sniper.ogg', - "Shotgun Firing" = 'sound/weapons/shotgun.ogg', - "Handgun Firing" = 'sound/weapons/gunshot3.ogg', - "Machinegun Firing" = 'sound/weapons/machinegun.ogg', + "Gun Firing" = 'sound/weapons/Gunshot1.ogg', + "Desert Eagle Firing" = 'sound/weapons/Gunshot_deagle.ogg', + "Rifle Firing" = 'sound/weapons/Gunshot_generic_rifle.ogg', + "Sniper Rifle Firing" = 'sound/weapons/Gunshot_sniper.ogg', + "AT Rifle Firing" = 'sound/weapons/Gunshot_cannon.ogg', + "Shotgun Firing" = 'sound/weapons/Gunshot_shotgun.ogg', + "Handgun Firing" = 'sound/weapons/Gunshot2.ogg', + "Machinegun Firing" = 'sound/weapons/Gunshot_machinegun.ogg', "Rocket Launcher Firing"= 'sound/weapons/rpg.ogg', "Taser Firing" = 'sound/weapons/Taser.ogg', "Laser Gun Firing" = 'sound/weapons/laser.ogg', @@ -92,4 +92,4 @@ M.Paralyse(4) else M.make_jittery(50) - M << "HONK" \ No newline at end of file + M << "HONK" diff --git a/code/game/gamemodes/technomancer/spells/aura/aura.dm b/code/game/gamemodes/technomancer/spells/aura/aura.dm index f3c7c93876..be986bb7ee 100644 --- a/code/game/gamemodes/technomancer/spells/aura/aura.dm +++ b/code/game/gamemodes/technomancer/spells/aura/aura.dm @@ -9,11 +9,11 @@ /obj/item/weapon/spell/aura/New() ..() set_light(calculate_spell_power(7), calculate_spell_power(4), l_color = glow_color) - processing_objects |= src + START_PROCESSING(SSobj, src) log_and_message_admins("has started casting [src].") /obj/item/weapon/spell/aura/Destroy() - processing_objects -= src + STOP_PROCESSING(SSobj, src) log_and_message_admins("has stopped maintaining [src].") return ..() diff --git a/code/game/gamemodes/technomancer/spells/control.dm b/code/game/gamemodes/technomancer/spells/control.dm index e76e63490c..b41823dc54 100644 --- a/code/game/gamemodes/technomancer/spells/control.dm +++ b/code/game/gamemodes/technomancer/spells/control.dm @@ -21,91 +21,68 @@ aspect = ASPECT_BIOMED //Not sure if this should be something else. var/image/control_overlay = null var/list/controlled_mobs = list() - var/list/allowed_mobs = list( - /mob/living/bot, - /mob/living/simple_animal/cat, - /mob/living/simple_animal/chick, - /mob/living/simple_animal/chicken, - /mob/living/simple_animal/corgi, - /mob/living/simple_animal/cow, - /mob/living/simple_animal/crab, - /mob/living/simple_animal/lizard, - /mob/living/simple_animal/mouse, - /mob/living/simple_animal/parrot, - /mob/living/simple_animal/slime, -// /mob/living/simple_animal/adultslime, - /mob/living/simple_animal/tindalos, - /mob/living/simple_animal/yithian, - /mob/living/simple_animal/hostile/scarybat, - /mob/living/simple_animal/hostile/viscerator, - /mob/living/simple_animal/hostile/malf_drone, - /mob/living/simple_animal/hostile/giant_spider, - /mob/living/simple_animal/hostile/hivebot, - /mob/living/simple_animal/retaliate/diyaab, //Doubt these will get used but might as well, - /mob/living/simple_animal/hostile/savik, - /mob/living/simple_animal/hostile/shantak - ) + var/allowed_mob_classes = MOB_CLASS_ANIMAL|MOB_CLASS_SYNTHETIC //This unfortunately is gonna be rather messy due to the various mobtypes involved. /obj/item/weapon/spell/control/proc/select(var/mob/living/L) - if(!(is_type_in_list(L, allowed_mobs))) - return 0 + if(!(L.mob_class & allowed_mob_classes)) + return FALSE - if(istype(L, /mob/living/simple_animal)) - var/mob/living/simple_animal/SA = L - SA.ai_inactive = 1 - SA.friends |= src.owner - SA.stance = STANCE_IDLE + if(!L.has_AI()) + return FALSE - L.overlays |= control_overlay + var/datum/ai_holder/AI = L.ai_holder + AI.hostile = FALSE // The Technomancer chooses the target, not the AI. + AI.retaliate = TRUE + AI.wander = FALSE + AI.forget_everything() + + if(istype(L, /mob/living/simple_mob)) + var/mob/living/simple_mob/SM = L + SM.friends |= src.owner + + L.add_overlay(control_overlay, TRUE) controlled_mobs |= L /obj/item/weapon/spell/control/proc/deselect(var/mob/living/L) if(!(L in controlled_mobs)) - return 0 + return FALSE - if(istype(L, /mob/living/simple_animal)) - var/mob/living/simple_animal/SA = L - SA.ai_inactive = 1 - if(istype(SA, /mob/living/simple_animal/hostile)) - var/mob/living/simple_animal/hostile/SAH = SA - SAH.friends.Remove(owner) + if(L.has_AI()) + var/datum/ai_holder/AI = L.ai_holder + AI.hostile = initial(AI.hostile) + AI.retaliate = initial(AI.retaliate) + AI.wander = initial(AI.wander) + AI.forget_everything() - L.overlays.Remove(control_overlay) + if(istype(L, /mob/living/simple_mob)) + var/mob/living/simple_mob/SM = L + SM.friends -= owner + + L.cut_overlay(control_overlay, TRUE) controlled_mobs.Remove(L) /obj/item/weapon/spell/control/proc/move_all(turf/T) - for(var/mob/living/living in controlled_mobs) - if(living.stat) - deselect(living) + for(var/mob/living/L in controlled_mobs) + if(!L.has_AI() || L.stat) + deselect(L) continue - if(istype(living, /mob/living/simple_animal)) - var/mob/living/simple_animal/SA = living - SA.target_mob = null - SA.stance = STANCE_IDLE - walk_towards(SA,T,SA.speed) - else - walk_towards(living,T,5) + L.ai_holder.give_destination(T, 0, TRUE) /obj/item/weapon/spell/control/proc/attack_all(mob/target) for(var/mob/living/L in controlled_mobs) - if(L.stat) + if(!L.has_AI() || L.stat) deselect(L) continue - if(istype(L, /mob/living/simple_animal/hostile)) - var/mob/living/simple_animal/hostile/SAH - SAH.target_mob = target - else if(istype(L, /mob/living/bot)) - var/mob/living/bot/B = L - B.UnarmedAttack(L) + L.ai_holder.give_target(target) -/obj/item/weapon/spell/control/New() +/obj/item/weapon/spell/control/Initialize() control_overlay = image('icons/obj/spells.dmi',"controlled") - ..() + return ..() /obj/item/weapon/spell/control/Destroy() - for(var/mob/living/simple_animal/hostile/SM in controlled_mobs) - deselect(SM) + for(var/mob/living/L in controlled_mobs) + deselect(L) controlled_mobs = list() return ..() @@ -127,11 +104,14 @@ trying to use it on yourself, perhaps you're an exception? Regardless, nothing happens." return 0 - if(is_type_in_list(L, allowed_mobs)) + if(L.mob_class & allowed_mob_classes) if(!(L in controlled_mobs)) //Selecting if(L.client) user << "\The [L] seems to resist you!" return 0 + if(!L.has_AI()) + to_chat(user, span("warning", "\The [L] seems too dim for this to work on them.")) + return FALSE if(pay_energy(500)) select(L) user << "\The [L] is now under your (limited) control." diff --git a/code/game/gamemodes/technomancer/spells/energy_siphon.dm b/code/game/gamemodes/technomancer/spells/energy_siphon.dm index 345b632282..aab144d907 100644 --- a/code/game/gamemodes/technomancer/spells/energy_siphon.dm +++ b/code/game/gamemodes/technomancer/spells/energy_siphon.dm @@ -22,11 +22,11 @@ /obj/item/weapon/spell/energy_siphon/New() ..() - processing_objects |= src + START_PROCESSING(SSobj, src) /obj/item/weapon/spell/energy_siphon/Destroy() stop_siphoning() - processing_objects -= src + STOP_PROCESSING(SSobj, src) return ..() /obj/item/weapon/spell/energy_siphon/process() @@ -165,14 +165,15 @@ while(i) var/obj/item/projectile/beam/lightning/energy_siphon/lightning = new(get_turf(source)) lightning.firer = user - lightning.launch(user) + lightning.old_style_target(user) + lightning.fire() i-- sleep(3) /obj/item/projectile/beam/lightning/energy_siphon name = "energy stream" icon_state = "lightning" - kill_count = 6 // Backup plan in-case the effect somehow misses the Technomancer. + range = 6 // Backup plan in-case the effect somehow misses the Technomancer. power = 5 // This fires really fast, so this may add up if someone keeps standing in the beam. penetrating = 5 diff --git a/code/game/gamemodes/technomancer/spells/gambit.dm b/code/game/gamemodes/technomancer/spells/gambit.dm index e0116073dc..5e03a8ca19 100644 --- a/code/game/gamemodes/technomancer/spells/gambit.dm +++ b/code/game/gamemodes/technomancer/spells/gambit.dm @@ -75,9 +75,9 @@ for(var/mob/living/L in view(owner)) // Spiders, carp... bears. - if(istype(L, /mob/living/simple_animal)) - var/mob/living/simple_animal/SM = L - if(!is_ally(SM) && SM.hostile) + if(istype(L, /mob/living/simple_mob)) + var/mob/living/simple_mob/SM = L + if(!is_ally(SM) && SM.has_AI() && SM.ai_holder.hostile) hostile_mobs++ if(SM.summoned || SM.supernatural) // Our creations might be trying to kill us. potential_spells |= /obj/item/weapon/spell/abjuration diff --git a/code/game/gamemodes/technomancer/spells/illusion.dm b/code/game/gamemodes/technomancer/spells/illusion.dm index 418df75539..8dccc2b9ec 100644 --- a/code/game/gamemodes/technomancer/spells/illusion.dm +++ b/code/game/gamemodes/technomancer/spells/illusion.dm @@ -14,7 +14,7 @@ aspect = ASPECT_LIGHT cast_methods = CAST_RANGED | CAST_USE var/atom/movable/copied = null - var/mob/living/simple_animal/illusion/illusion = null + var/mob/living/simple_mob/illusion/illusion = null /obj/item/weapon/spell/illusion/on_ranged_cast(atom/hit_atom, mob/user) if(istype(hit_atom, /atom/movable)) @@ -33,17 +33,13 @@ if(pay_energy(500)) illusion = new(T) illusion.copy_appearance(copied) - if(ishuman(copied)) - var/mob/living/carbon/human/H = copied - // This is to try to have the illusion move at the same rate the real mob world. - illusion.step_delay = max(H.movement_delay() + 4, 3) user << "An illusion of \the [copied] is made on \the [T]." user << 'sound/effects/pop.ogg' return 1 else if(pay_energy(100)) - spawn(1) - illusion.walk_loop(T) + var/datum/ai_holder/AI = illusion.ai_holder + AI.give_destination(T) /obj/item/weapon/spell/illusion/on_use_cast(mob/user) if(illusion) @@ -76,116 +72,3 @@ temp_image.transform = M // temp_image.pixel_y = 8 src.overlays.Add(temp_image) - - -/mob/living/simple_animal/illusion - name = "illusion" // gets overwritten - desc = "If you can read me, the game broke. Please report this to a coder." - resistance = 1000 // holograms are tough - wander = 0 - response_help = "pushes a hand through" - response_disarm = "tried to disarm" - response_harm = "tried to punch" - var/atom/movable/copying = null - universal_speak = 1 - var/realistic = 0 - var/list/path = list() //Used for AStar pathfinding. - var/walking = 0 - var/step_delay = 10 - -/mob/living/simple_animal/illusion/update_icon() // We don't want the appearance changing AT ALL unless by copy_appearance(). - return - -/mob/living/simple_animal/illusion/proc/copy_appearance(var/atom/movable/thing_to_copy) - if(!thing_to_copy) - return 0 - name = thing_to_copy.name - desc = thing_to_copy.desc - gender = thing_to_copy.gender - appearance = thing_to_copy.appearance - copying = thing_to_copy - return 1 - -// We use special movement code for illusions, because BYOND's default pathfinding will use diagonal movement if it results -// in the shortest path. As players are incapable of moving in diagonals, we must do this or else illusions will not be convincing. -/mob/living/simple_animal/illusion/proc/calculate_path(var/turf/targeted_loc) - if(!path.len || !path) - spawn(0) - path = AStar(loc, targeted_loc, /turf/proc/CardinalTurfs, /turf/proc/Distance, 0, 10, id = null) - if(!path) - path = list() - return - -/mob/living/simple_animal/illusion/proc/walk_path(var/turf/targeted_loc) - if(path && path.len) - step_to(src, path[1]) - path -= path[1] - return - else - if(targeted_loc) - calculate_path(targeted_loc) - -/mob/living/simple_animal/illusion/proc/walk_loop(var/turf/targeted_loc) - if(walking) //Already busy moving somewhere else. - return 0 - walking = 1 - calculate_path(targeted_loc) - if(!targeted_loc) - walking = 0 - return 0 - if(path.len == 0) - calculate_path(targeted_loc) - while(loc != targeted_loc) - walk_path(targeted_loc) - sleep(step_delay) - walking = 0 - return 1 - -// Because we can't perfectly duplicate some examine() output, we directly examine the AM it is copying. It's messy but -// this is to prevent easy checks from the opposing force. -/mob/living/simple_animal/illusion/examine(mob/user) - if(copying) - copying.examine(user) - return - ..() - -/mob/living/simple_animal/illusion/bullet_act(var/obj/item/projectile/P) - if(!P) - return - - if(realistic) - return ..() - - return PROJECTILE_FORCE_MISS - -/mob/living/simple_animal/illusion/attack_hand(mob/living/carbon/human/M) - if(!realistic) - playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) - visible_message("[M]'s hand goes through \the [src]!") - return - else - switch(M.a_intent) - - if(I_HELP) - var/datum/gender/T = gender_datums[src.get_visible_gender()] - M.visible_message("[M] hugs [src] to make [T.him] feel better!", \ - "You hug [src] to make [T.him] feel better!") // slightly redundant as at the moment most mobs still use the normal gender var, but it works and future-proofs it - playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - - if(I_DISARM) - playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) - visible_message("[M] attempted to disarm [src]!") - M.do_attack_animation(src) - - if(I_GRAB) - ..() - - if(I_HURT) - adjustBruteLoss(harm_intent_damage) - M.visible_message("[M] [response_harm] \the [src]") - M.do_attack_animation(src) - - return - -/mob/living/simple_animal/illusion/ex_act() - return diff --git a/code/game/gamemodes/technomancer/spells/modifier/modifier.dm b/code/game/gamemodes/technomancer/spells/modifier/modifier.dm index a8b9306945..3ea278286e 100644 --- a/code/game/gamemodes/technomancer/spells/modifier/modifier.dm +++ b/code/game/gamemodes/technomancer/spells/modifier/modifier.dm @@ -15,11 +15,13 @@ /obj/item/weapon/spell/modifier/on_melee_cast(atom/hit_atom, mob/user) if(istype(hit_atom, /mob/living)) - on_add_modifier(hit_atom) + return on_add_modifier(hit_atom) + return FALSE /obj/item/weapon/spell/modifier/on_ranged_cast(atom/hit_atom, mob/user) if(istype(hit_atom, /mob/living)) - on_add_modifier(hit_atom) + return on_add_modifier(hit_atom) + return FALSE /obj/item/weapon/spell/modifier/proc/on_add_modifier(var/mob/living/L) @@ -32,6 +34,7 @@ MT.spell_power = calculate_spell_power(1) log_and_message_admins("has casted [src] on [L].") qdel(src) + return TRUE // Technomancer specific subtype which keeps track of spell power and gets targeted specificially by Dispel. /datum/modifier/technomancer diff --git a/code/game/gamemodes/technomancer/spells/phase_shift.dm b/code/game/gamemodes/technomancer/spells/phase_shift.dm index 336dbc4314..d73e45774c 100644 --- a/code/game/gamemodes/technomancer/spells/phase_shift.dm +++ b/code/game/gamemodes/technomancer/spells/phase_shift.dm @@ -31,12 +31,12 @@ /obj/effect/phase_shift/New() ..() set_light(3, 5, l_color = "#FA58F4") - processing_objects |= src + START_PROCESSING(SSobj, src) /obj/effect/phase_shift/Destroy() for(var/atom/movable/AM in contents) //Eject everything out. AM.forceMove(get_turf(src)) - processing_objects -= src + STOP_PROCESSING(SSobj, src) return ..() /obj/effect/phase_shift/process() diff --git a/code/game/gamemodes/technomancer/spells/projectile/beam.dm b/code/game/gamemodes/technomancer/spells/projectile/beam.dm index 6eb5e03be3..b96f061df8 100644 --- a/code/game/gamemodes/technomancer/spells/projectile/beam.dm +++ b/code/game/gamemodes/technomancer/spells/projectile/beam.dm @@ -22,6 +22,6 @@ /obj/item/projectile/beam/blue damage = 30 - muzzle_type = /obj/effect/projectile/laser_blue/muzzle - tracer_type = /obj/effect/projectile/laser_blue/tracer - impact_type = /obj/effect/projectile/laser_blue/impact + muzzle_type = /obj/effect/projectile/muzzle/laser_blue + tracer_type = /obj/effect/projectile/tracer/laser_blue + impact_type = /obj/effect/projectile/impact/laser_blue diff --git a/code/game/gamemodes/technomancer/spells/projectile/chain_lightning.dm b/code/game/gamemodes/technomancer/spells/projectile/chain_lightning.dm index 5614d04a88..2d9a59f144 100644 --- a/code/game/gamemodes/technomancer/spells/projectile/chain_lightning.dm +++ b/code/game/gamemodes/technomancer/spells/projectile/chain_lightning.dm @@ -26,9 +26,9 @@ nodamage = 1 damage_type = HALLOSS - muzzle_type = /obj/effect/projectile/lightning/muzzle - tracer_type = /obj/effect/projectile/lightning/tracer - impact_type = /obj/effect/projectile/lightning/impact + muzzle_type = /obj/effect/projectile/muzzle/lightning + tracer_type = /obj/effect/projectile/tracer/lightning + impact_type = /obj/effect/projectile/impact/lightning var/bounces = 3 //How many times it 'chains'. Note that the first hit is not counted as it counts /bounces/. var/list/hit_mobs = list() //Mobs which were already hit. diff --git a/code/game/gamemodes/technomancer/spells/projectile/lightning.dm b/code/game/gamemodes/technomancer/spells/projectile/lightning.dm index e996416216..57e42cf863 100644 --- a/code/game/gamemodes/technomancer/spells/projectile/lightning.dm +++ b/code/game/gamemodes/technomancer/spells/projectile/lightning.dm @@ -26,9 +26,9 @@ nodamage = 1 damage_type = HALLOSS - muzzle_type = /obj/effect/projectile/lightning/muzzle - tracer_type = /obj/effect/projectile/lightning/tracer - impact_type = /obj/effect/projectile/lightning/impact + muzzle_type = /obj/effect/projectile/muzzle/lightning + tracer_type = /obj/effect/projectile/tracer/lightning + impact_type = /obj/effect/projectile/impact/lightning var/power = 60 //How hard it will hit for with electrocute_act(). diff --git a/code/game/gamemodes/technomancer/spells/projectile/projectile.dm b/code/game/gamemodes/technomancer/spells/projectile/projectile.dm index 544213f957..a52bb2e584 100644 --- a/code/game/gamemodes/technomancer/spells/projectile/projectile.dm +++ b/code/game/gamemodes/technomancer/spells/projectile/projectile.dm @@ -12,7 +12,8 @@ /obj/item/weapon/spell/projectile/on_ranged_cast(atom/hit_atom, mob/living/user) if(set_up(hit_atom, user)) var/obj/item/projectile/new_projectile = make_projectile(spell_projectile, user) - new_projectile.launch(hit_atom) + new_projectile.old_style_target(hit_atom) + new_projectile.fire() log_and_message_admins("has casted [src] at \the [hit_atom].") if(fire_sound) playsound(get_turf(src), fire_sound, 75, 1) diff --git a/code/game/gamemodes/technomancer/spells/radiance.dm b/code/game/gamemodes/technomancer/spells/radiance.dm index fe7d83f713..d86428354e 100644 --- a/code/game/gamemodes/technomancer/spells/radiance.dm +++ b/code/game/gamemodes/technomancer/spells/radiance.dm @@ -19,11 +19,11 @@ /obj/item/weapon/spell/radiance/New() ..() set_light(7, 4, l_color = "#D9D900") - processing_objects |= src + START_PROCESSING(SSobj, src) log_and_message_admins("has casted [src].") /obj/item/weapon/spell/radiance/Destroy() - processing_objects -= src + STOP_PROCESSING(SSobj, src) log_and_message_admins("has stopped maintaining [src].") return ..() diff --git a/code/game/gamemodes/technomancer/spells/resurrect.dm b/code/game/gamemodes/technomancer/spells/resurrect.dm index 90a352c95f..2663a132a9 100644 --- a/code/game/gamemodes/technomancer/spells/resurrect.dm +++ b/code/game/gamemodes/technomancer/spells/resurrect.dm @@ -30,13 +30,13 @@ this point." return 0 user << "You stab \the [L] with a hidden integrated hypo, attempting to bring them back..." - if(istype(L, /mob/living/simple_animal)) - var/mob/living/simple_animal/SM = L + if(istype(L, /mob/living/simple_mob)) + var/mob/living/simple_mob/SM = L SM.health = SM.getMaxHealth() / 3 SM.stat = CONSCIOUS dead_mob_list -= SM living_mob_list += SM - SM.icon_state = SM.icon_living + SM.update_icon() adjust_instability(15) else if(ishuman(L)) var/mob/living/carbon/human/H = L diff --git a/code/game/gamemodes/technomancer/spells/spawner/pulsar.dm b/code/game/gamemodes/technomancer/spells/spawner/pulsar.dm index 5641df2f87..6dcd2cf4b2 100644 --- a/code/game/gamemodes/technomancer/spells/spawner/pulsar.dm +++ b/code/game/gamemodes/technomancer/spells/spawner/pulsar.dm @@ -11,7 +11,7 @@ icon_state = "radiance" cast_methods = CAST_RANGED | CAST_THROW aspect = ASPECT_EMP - spawner_type = /obj/effect/temporary_effect/pulsar + spawner_type = /obj/effect/temporary_effect/pulse/pulsar /obj/item/weapon/spell/spawner/pulsar/New() ..() @@ -25,7 +25,29 @@ /obj/item/weapon/spell/spawner/pulsar/on_throw_cast(atom/hit_atom, mob/user) empulse(hit_atom, 1, 1, 1, 1, log=1) -/obj/effect/temporary_effect/pulsar +// Does something every so often. Deletes itself when pulses_remaining hits zero. +/obj/effect/temporary_effect/pulse + var/pulses_remaining = 3 + var/pulse_delay = 2 SECONDS + +/obj/effect/temporary_effect/pulse/Initialize() + spawn(0) + pulse_loop() + return ..() + +/obj/effect/temporary_effect/pulse/proc/pulse_loop() + while(pulses_remaining) + sleep(pulse_delay) + on_pulse() + pulses_remaining-- + qdel(src) + +// Override for specific effects. +/obj/effect/temporary_effect/pulse/proc/on_pulse() + + + +/obj/effect/temporary_effect/pulse/pulsar name = "pulsar" desc = "Not a real pulsar, but still emits loads of EMP." icon_state = "shield2" @@ -33,17 +55,14 @@ light_range = 4 light_power = 5 light_color = "#2ECCFA" - var/pulses_remaining = 3 + pulses_remaining = 3 + +/obj/effect/temporary_effect/pulse/pulsar/on_pulse() + empulse(src, 1, 1, 2, 2, log = 1) + + + + -/obj/effect/temporary_effect/pulsar/New() - ..() - spawn(0) - pulse_loop() -/obj/effect/temporary_effect/pulsar/proc/pulse_loop() - while(pulses_remaining) - sleep(2 SECONDS) - empulse(src, 1, 1, 2, 2, log = 1) - pulses_remaining-- - qdel(src) diff --git a/code/game/gamemodes/technomancer/spells/summon/summon_creature.dm b/code/game/gamemodes/technomancer/spells/summon/summon_creature.dm index 9a004d3ea3..c29d9827ec 100644 --- a/code/game/gamemodes/technomancer/spells/summon/summon_creature.dm +++ b/code/game/gamemodes/technomancer/spells/summon/summon_creature.dm @@ -16,34 +16,32 @@ desc = "Chitter chitter." summoned_mob_type = null summon_options = list( - "Mouse" = /mob/living/simple_animal/mouse, - "Lizard" = /mob/living/simple_animal/lizard, - "Chicken" = /mob/living/simple_animal/chicken, - "Chick" = /mob/living/simple_animal/chick, - "Crab" = /mob/living/simple_animal/crab, - "Parrot" = /mob/living/simple_animal/parrot, - "Goat" = /mob/living/simple_animal/retaliate/goat, - "Cat" = /mob/living/simple_animal/cat, - "Kitten" = /mob/living/simple_animal/cat/kitten, - "Corgi" = /mob/living/simple_animal/corgi, - "Corgi Pup" = /mob/living/simple_animal/corgi/puppy, - "BAT" = /mob/living/simple_animal/hostile/scarybat, - "SPIDER" = /mob/living/simple_animal/hostile/giant_spider, - "SPIDER HUNTER" = /mob/living/simple_animal/hostile/giant_spider/hunter, - "SPIDER NURSE" = /mob/living/simple_animal/hostile/giant_spider/nurse, - "CARP" = /mob/living/simple_animal/hostile/carp, - "BEAR" = /mob/living/simple_animal/hostile/bear - ) // Vorestation edits to add vore versions. + "Mouse" = /mob/living/simple_mob/animal/passive/mouse, + "Lizard" = /mob/living/simple_mob/animal/passive/lizard, + "Chicken" = /mob/living/simple_mob/animal/passive/chicken, + "Chick" = /mob/living/simple_mob/animal/passive/chick, + "Crab" = /mob/living/simple_mob/animal/passive/crab, + "Parrot" = /mob/living/simple_mob/animal/passive/bird/parrot, + "Goat" = /mob/living/simple_mob/animal/goat, + "Cat" = /mob/living/simple_mob/animal/passive/cat, + "Kitten" = /mob/living/simple_mob/animal/passive/cat/kitten, + "Corgi" = /mob/living/simple_mob/animal/passive/dog/corgi, + "Corgi Pup" = /mob/living/simple_mob/animal/passive/dog/corgi/puppy, + "BAT" = /mob/living/simple_mob/animal/space/bats, + "SPIDER" = /mob/living/simple_mob/animal/giant_spider, + "SPIDER HUNTER" = /mob/living/simple_mob/animal/giant_spider/hunter, + "SPIDER NURSE" = /mob/living/simple_mob/animal/giant_spider/nurse, + "CARP" = /mob/living/simple_mob/animal/space/carp, + "BEAR" = /mob/living/simple_mob/animal/space/bear + ) cooldown = 30 instability_cost = 10 energy_cost = 1000 -/obj/item/weapon/spell/summon/summon_creature/on_summon(var/mob/living/simple_animal/summoned) +/obj/item/weapon/spell/summon/summon_creature/on_summon(var/mob/living/simple_mob/summoned) if(check_for_scepter()) // summoned.faction = "technomancer" - if(istype(summoned, /mob/living/simple_animal/hostile)) - var/mob/living/simple_animal/SA = summoned - SA.friends.Add(owner) + summoned.friends += owner // Makes their new pal big and strong, if they have spell power. summoned.maxHealth = calculate_spell_power(summoned.maxHealth) @@ -51,15 +49,12 @@ summoned.melee_damage_lower = calculate_spell_power(summoned.melee_damage_lower) summoned.melee_damage_upper = calculate_spell_power(summoned.melee_damage_upper) // This makes the summon slower, so the crew has a chance to flee from massive monsters. - summoned.move_to_delay = calculate_spell_power(round(summoned.move_to_delay)) + summoned.movement_cooldown = calculate_spell_power(round(summoned.movement_cooldown)) var/new_size = calculate_spell_power(1) if(new_size != 1) - var/matrix/M = matrix() - M.Scale(new_size) - M.Translate(0, 16*(new_size-1)) - summoned.transform = M + adjust_scale(new_size) // Now we hurt their new pal, because being forcefully abducted by teleportation can't be healthy. - summoned.health = round(summoned.getMaxHealth() * 0.7) \ No newline at end of file + summoned.adjustBruteLoss(summoned.getMaxHealth() * 0.3) // Lose 30% of max health on arrival (but could be healed back up). \ No newline at end of file diff --git a/code/game/gamemodes/technomancer/spells/summon/summon_ward.dm b/code/game/gamemodes/technomancer/spells/summon/summon_ward.dm index c6e5a2804d..9500044581 100644 --- a/code/game/gamemodes/technomancer/spells/summon/summon_ward.dm +++ b/code/game/gamemodes/technomancer/spells/summon/summon_ward.dm @@ -1,9 +1,8 @@ /datum/technomancer/spell/summon_ward - name = "Summon Ward" - desc = "Teleports a prefabricated 'ward' drone to the target location, which will alert you and your allies when it sees entities \ - moving around it, or when it is attacked. They can see for up to five meters." - enhancement_desc = "Wards can detect invisibile entities, and are more specific in relaying information about what it sees. \ - Invisible entities that are spotted by it will be decloaked." + name = "Summon Monitor Ward" + desc = "Teleports a prefabricated 'ward' drone to the target location, which will alert you when it sees entities \ + moving around it, or when it is attacked. They can see for up to five meters. It can also see invisible entities, and \ + forcefully decloak them if close enough." cost = 25 obj_path = /obj/item/weapon/spell/summon/summon_ward category = UTILITY_SPELLS @@ -12,116 +11,10 @@ name = "summon ward" desc = "Finally, someone you can depend on to watch your back." cast_methods = CAST_RANGED - summoned_mob_type = /mob/living/simple_animal/ward + summoned_mob_type = /mob/living/simple_mob/mechanical/ward/monitor cooldown = 10 instability_cost = 5 energy_cost = 500 -/obj/item/weapon/spell/summon/summon_ward/on_summon(var/mob/living/simple_animal/ward/ward) - ward.creator = owner - if(check_for_scepter()) - ward.true_sight = 1 - ward.see_invisible = SEE_INVISIBLE_LEVEL_TWO - -/mob/living/simple_animal/ward - name = "ward" - desc = "It's a little flying drone that seems to be watching you..." - icon = 'icons/mob/critter.dmi' - icon_state = "ward" - resistance = 5 - wander = 0 - response_help = "pets the" - response_disarm = "swats away" - response_harm = "punches" - min_oxy = 0 - max_oxy = 0 - min_tox = 0 - max_tox = 0 - min_co2 = 0 - max_co2 = 0 - min_n2 = 0 - max_n2 = 0 - minbodytemp = 0 - maxbodytemp = 0 - unsuitable_atoms_damage = 0 - heat_damage_per_tick = 0 - cold_damage_per_tick = 0 - - var/true_sight = 0 // If true, detects more than what the Technomancer normally can't. - var/mob/living/carbon/human/creator = null - var/list/seen_mobs = list() - -/mob/living/simple_animal/ward/death() - if(creator) - creator << "Your ward inside [get_area(src)] was killed!" - ..() - qdel(src) - -/mob/living/simple_animal/ward/proc/expire() - if(creator && src) - creator << "Your ward inside [get_area(src)] expired." - qdel(src) - -/mob/living/simple_animal/ward/Life() - ..() - detect_mobs() - update_icon() - -/mob/living/simple_animal/ward/proc/detect_mobs() - var/list/things_in_sight = view(5,src) - var/list/newly_seen_mobs = list() - for(var/mob/living/L in things_in_sight) - if(L == creator) // I really wish is_ally() was usable here. - continue - - if(istype(L, /mob/living/simple_animal/ward)) - continue - - if(istype(L, /mob/living/simple_animal)) - var/mob/living/simple_animal/SA = L - if(creator in SA.friends) - continue - - if(!true_sight) - var/turf/T = get_turf(L) - var/light_amount = T.get_lumcount() - if(light_amount <= 0.5) - continue // Too dark to see. - - if(L.alpha <= 127) - continue // Too transparent, as a mercy to camo lings. - - else - L.break_cloak() - - // Warn the Technomancer when it sees a new mob. - if(!(L in seen_mobs)) - seen_mobs.Add(L) - newly_seen_mobs.Add(L) - if(creator) - if(true_sight) - creator << "Your ward at [get_area(src)] detected [english_list(newly_seen_mobs)]." - else - creator << "Your ward at [get_area(src)] detected something." - - // Now get rid of old mobs that left vision. - for(var/mob/living/L in seen_mobs) - if(!(L in things_in_sight)) - seen_mobs.Remove(L) - - -/mob/living/simple_animal/ward/update_icon() - if(seen_mobs.len) - icon_state = "ward_spotted" - set_light(3, 3, l_color = "FF0000") - else - icon_state = "ward" - set_light(3, 3, l_color = "00FF00") - if(true_sight) - overlays.Cut() - var/image/I = image('icons/mob/critter.dmi',"ward_truesight") - overlays.Add(I) - -/mob/living/simple_animal/ward/invisible_detect - true_sight = 1 - see_invisible = SEE_INVISIBLE_LEVEL_TWO +/obj/item/weapon/spell/summon/summon_ward/on_summon(var/mob/living/simple_mob/mechanical/ward/monitor/my_ward) + my_ward.owner = owner diff --git a/code/game/jobs/job/civilian_chaplain.dm b/code/game/jobs/job/civilian_chaplain.dm index e24e462fdf..65943380bc 100644 --- a/code/game/jobs/job/civilian_chaplain.dm +++ b/code/game/jobs/job/civilian_chaplain.dm @@ -37,31 +37,33 @@ if("unitarianism") B.name = "The Talmudic Quran" if("christianity") - B.name = pick("The Holy Bible","The Dead Sea Scrolls") - if("Judaism") + B.name = "The Holy Bible" + if("judaism") B.name = "The Torah" - if("satanism") - B.name = "The Satanic Bible" - if("cthulhu") - B.name = "The Necronomicon" if("islam") B.name = "Quran" - if("scientology") - B.name = pick("The Biography of L. Ron Hubbard","Dianetics") - if("chaos") - B.name = "The Book of Lorgar" - if("imperium") - B.name = "Uplifting Primer" - if("toolboxia") - B.name = "Toolbox Manifesto" - if("homosexuality") - B.name = "Guys Gone Wild" - if("science") - B.name = pick("Principle of Relativity", "Quantum Enigma: Physics Encounters Consciousness", "Programming the Universe", "Quantum Physics and Theology", "String Theory for Dummies", "How To: Build Your Own Warp Drive", "The Mysteries of Bluespace", "Playing God: Collector's Edition") - if("capitalism") - B.name = "Wealth of Nations" - if("communism") - B.name = "The Communist Manifesto" + if("buddhism") + B.name = "Tripitakas" + if("hinduism") + B.name = pick("The Srimad Bhagvatam", "The Four Vedas", "The Shiv Mahapuran", "Devi Mahatmya") + if("neopaganism") + B.name = "Neopagan Hymnbook" + if("phact shintoism") + B.name = "The Kojiki" + if("kishari national faith") + B.name = "The Scriptures of Kishar" + if("pleromanism") + B.name = "The Revised Talmudic Quran" + if("spectralism") + B.name = "The Book of the Spark" + if("hauler") + B.name = "Histories of Captaincy" + if("nock") + B.name = "The Book of the First" + if("singulitarian worship") + B.name = "The Book of the Precursors" + if("starlit path of angessa martei") + B.name = "Quotations of Exalted Martei" else B.name = "The Holy Book of [new_religion]" feedback_set_details("religion_name","[new_religion]") diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index de673cec37..57b05a8346 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -109,7 +109,7 @@ break data["stasis"] = stasis_level_name - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if(!ui) ui = new(user, src, ui_key, "sleeper.tmpl", "Sleeper UI", 600, 600, state = state) ui.set_initial_data(data) @@ -181,7 +181,7 @@ RefreshParts() -/obj/machinery/sleeper/initialize() +/obj/machinery/sleeper/Initialize() . = ..() update_icon() diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index 2fb2d48a82..c101202b38 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -49,10 +49,9 @@ if(occupant) to_chat(user, "\The [src] is already occupied!") return - for(var/mob/living/simple_animal/slime/M in range(1, H.affecting)) - if(M.victim == H.affecting) - to_chat(user, "[H.affecting.name] has a slime attached to them, deal with that first.") - return + if(H.affecting.has_buckled_mobs()) + to_chat(user, span("warning", "\The [H.affecting] has other entities attached to it. Remove them first.")) + return var/mob/M = H.affecting if(M.abiotic()) to_chat(user, "Subject cannot have abiotic items on.") @@ -86,10 +85,9 @@ if(O.abiotic()) to_chat(user, "Subject cannot have abiotic items on.") return 0 - for(var/mob/living/simple_animal/slime/M in range(1, O)) - if(M.victim == O) - to_chat(user, "[O] has a slime attached to them, deal with that first.") - return 0 + if(O.has_buckled_mobs()) + to_chat(user, span("warning", "\The [O] has other entities attached to it. Remove them first.")) + return if(O == user) visible_message("[user] climbs into \the [src].") @@ -391,7 +389,7 @@ occupantData = attempt_vr(scanner,"get_occupant_data_vr",list(occupantData,H)) //VOREStation Insert data["occupant"] = occupantData - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if(!ui) ui = new(user, src, ui_key, "adv_med.tmpl", "Body Scanner", 690, 800) ui.set_initial_data(data) diff --git a/code/game/machinery/airconditioner_vr.dm b/code/game/machinery/airconditioner_vr.dm index 75b93fe90f..0d4f3b550f 100644 --- a/code/game/machinery/airconditioner_vr.dm +++ b/code/game/machinery/airconditioner_vr.dm @@ -45,7 +45,7 @@ disconnect_from_network() turn_off() return - if(I.is_multitool()) + if(istype(I, /obj/item/device/multitool)) var/new_temp = input("Input a new target temperature, in degrees C.","Target Temperature", 20) as num if(!Adjacent(user) || user.incapacitated()) return diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index 6b4013b820..82fd1fe259 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -137,7 +137,7 @@ TLV["temperature"] = list(T0C - 26, T0C, T0C + 40, T0C + 66) // K -/obj/machinery/alarm/initialize() +/obj/machinery/alarm/Initialize() . = ..() set_frequency(frequency) if(!master_is_operating()) @@ -497,7 +497,7 @@ if(!(locked && !remote_connection) || remote_access || issilicon(user)) populate_controls(data) - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if(!ui) ui = new(user, src, ui_key, "air_alarm.tmpl", name, 325, 625, master_ui = master_ui, state = state) ui.set_initial_data(data) @@ -896,7 +896,7 @@ FIRE ALARM alarm() time = 0 timing = 0 - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) updateDialog() last_process = world.timeofday @@ -965,7 +965,7 @@ FIRE ALARM else if(href_list["time"]) timing = text2num(href_list["time"]) last_process = world.timeofday - processing_objects.Add(src) + START_PROCESSING(SSobj, src) else if(href_list["tp"]) var/tp = text2num(href_list["tp"]) time += tp @@ -1003,7 +1003,7 @@ FIRE ALARM seclevel = newlevel update_icon() -/obj/machinery/firealarm/initialize() +/obj/machinery/firealarm/Initialize() . = ..() if(z in using_map.contact_levels) set_security_level(security_level? get_security_level() : "green") diff --git a/code/game/machinery/atmo_control.dm b/code/game/machinery/atmo_control.dm index 59e9670d1f..c18d2b9e93 100644 --- a/code/game/machinery/atmo_control.dm +++ b/code/game/machinery/atmo_control.dm @@ -63,7 +63,7 @@ frequency = new_frequency radio_connection = radio_controller.add_object(src, frequency, RADIO_ATMOSIA) -/obj/machinery/air_sensor/initialize() +/obj/machinery/air_sensor/Initialize() . = ..() if(frequency) set_frequency(frequency) @@ -117,7 +117,7 @@ obj/machinery/computer/general_air_control/Destroy() data["sensors"] = sensors_ui - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if(!ui) ui = new(user, src, ui_key, "atmo_control.tmpl", name, 525, 600) ui.set_initial_data(data) @@ -129,7 +129,7 @@ obj/machinery/computer/general_air_control/Destroy() frequency = new_frequency radio_connection = radio_controller.add_object(src, frequency, RADIO_ATMOSIA) -/obj/machinery/computer/general_air_control/initialize() +/obj/machinery/computer/general_air_control/Initialize() . = ..() if(frequency) set_frequency(frequency) @@ -174,7 +174,7 @@ obj/machinery/computer/general_air_control/Destroy() data["input_flow_setting"] = round(input_flow_setting, 0.1) data["pressure_setting"] = pressure_setting - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if(!ui) ui = new(user, src, ui_key, "atmo_control.tmpl", name, 660, 500) ui.set_initial_data(data) @@ -284,7 +284,7 @@ obj/machinery/computer/general_air_control/Destroy() data["input_flow_setting"] = round(input_flow_setting, 0.1) data["pressure_setting"] = pressure_setting - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if(!ui) ui = new(user, src, ui_key, "atmo_control.tmpl", name, 650, 500) ui.set_initial_data(data) @@ -416,7 +416,7 @@ obj/machinery/computer/general_air_control/Destroy() else data["device_info"] = null - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if(!ui) ui = new(user, src, ui_key, "atmo_control.tmpl", name, 650, 500) ui.set_initial_data(data) diff --git a/code/game/machinery/atmoalter/area_atmos_computer.dm b/code/game/machinery/atmoalter/area_atmos_computer.dm index bd3b390fc8..125b55eb7f 100644 --- a/code/game/machinery/atmoalter/area_atmos_computer.dm +++ b/code/game/machinery/atmoalter/area_atmos_computer.dm @@ -14,11 +14,7 @@ //Simple variable to prevent me from doing attack_hand in both this and the child computer var/zone = "This computer is working on a wireless range, the range is currently limited to " -/obj/machinery/computer/area_atmos/New() - ..() - desc += "[range] meters." - -/obj/machinery/computer/area_atmos/initialize() +/obj/machinery/computer/area_atmos/Initialize() . = ..() scanscrubbers() @@ -72,7 +68,6 @@ [status]
Scan "} - for(var/obj/machinery/portable_atmospherics/powered/scrubber/huge/scrubber in connectedscrubbers) dat += {" @@ -102,9 +97,9 @@ usr.set_machine(src) src.add_fingerprint(usr) + if(href_list["scan"]) scanscrubbers() - else if(href_list["toggle"]) var/obj/machinery/portable_atmospherics/powered/scrubber/huge/scrubber = locate(href_list["scrub"]) @@ -118,24 +113,24 @@ scrubber.on = text2num(href_list["toggle"]) scrubber.update_icon() +/obj/machinery/computer/area_atmos/proc/validscrubber(obj/machinery/portable_atmospherics/powered/scrubber/huge/scrubber as obj) + if(!isobj(scrubber) || get_dist(scrubber.loc, src.loc) > src.range || scrubber.loc.z != src.loc.z) + return FALSE + return TRUE + /obj/machinery/computer/area_atmos/proc/scanscrubbers() - connectedscrubbers.Cut() + connectedscrubbers = new() var/found = 0 for(var/obj/machinery/portable_atmospherics/powered/scrubber/huge/scrubber in range(range, src.loc)) - found = 1 - connectedscrubbers += scrubber + if(istype(scrubber)) + found = 1 + connectedscrubbers += scrubber if(!found) status = "ERROR: No scrubber found!" - src.updateUsrDialog() - -/obj/machinery/computer/area_atmos/proc/validscrubber(var/obj/machinery/portable_atmospherics/powered/scrubber/huge/scrubber) - if((get_dist(src,scrubber) <= range) && src.z == scrubber.z) - return 1 - - return 0 + updateUsrDialog() // The one that only works in the same map area /obj/machinery/computer/area_atmos/area diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index 1749b68ac9..85544958cf 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -261,7 +261,7 @@ update_flag ..() - GLOB.nanomanager.update_uis(src) // Update all NanoUIs attached to src + SSnanoui.update_uis(src) // Update all NanoUIs attached to src /obj/machinery/portable_atmospherics/canister/attack_ai(var/mob/user as mob) return src.attack_hand(user) @@ -289,7 +289,7 @@ update_flag data["holdingTank"] = list("name" = holding.name, "tankPressure" = round(holding.air_contents.return_pressure())) // update the ui if it exists, returns null if no ui is passed/found - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.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 diff --git a/code/game/machinery/atmoalter/meter.dm b/code/game/machinery/atmoalter/meter.dm index c96837265d..7ee37757cc 100644 --- a/code/game/machinery/atmoalter/meter.dm +++ b/code/game/machinery/atmoalter/meter.dm @@ -12,7 +12,7 @@ use_power = 1 idle_power_usage = 15 -/obj/machinery/meter/initialize() +/obj/machinery/meter/Initialize() . = ..() if (!target) target = select_target() diff --git a/code/game/machinery/atmoalter/portable_atmospherics.dm b/code/game/machinery/atmoalter/portable_atmospherics.dm index 73f5abce4b..8778b4e5f3 100644 --- a/code/game/machinery/atmoalter/portable_atmospherics.dm +++ b/code/game/machinery/atmoalter/portable_atmospherics.dm @@ -26,7 +26,7 @@ QDEL_NULL(holding) . = ..() -/obj/machinery/portable_atmospherics/initialize() +/obj/machinery/portable_atmospherics/Initialize() . = ..() spawn() var/obj/machinery/atmospherics/portables_connector/port = locate() in loc diff --git a/code/game/machinery/atmoalter/pump.dm b/code/game/machinery/atmoalter/pump.dm index 7e2c786734..758c2a57cb 100644 --- a/code/game/machinery/atmoalter/pump.dm +++ b/code/game/machinery/atmoalter/pump.dm @@ -138,7 +138,7 @@ if (holding) data["holdingTank"] = list("name" = holding.name, "tankPressure" = round(holding.air_contents.return_pressure() > 0 ? holding.air_contents.return_pressure() : 0)) - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "portpump.tmpl", "Portable Pump", 480, 410, state = physical_state) ui.set_initial_data(data) diff --git a/code/game/machinery/atmoalter/scrubber.dm b/code/game/machinery/atmoalter/scrubber.dm index f249d7a8e7..55afd7f35f 100644 --- a/code/game/machinery/atmoalter/scrubber.dm +++ b/code/game/machinery/atmoalter/scrubber.dm @@ -114,7 +114,7 @@ if (holding) data["holdingTank"] = list("name" = holding.name, "tankPressure" = round(holding.air_contents.return_pressure() > 0 ? holding.air_contents.return_pressure() : 0)) - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "portscrubber.tmpl", "Portable Scrubber", 480, 400, state = physical_state) ui.set_initial_data(data) @@ -136,7 +136,7 @@ . = 1 if (href_list["volume_adj"]) var/diff = text2num(href_list["volume_adj"]) - volume_rate = Clamp(volume_rate+diff, minrate, maxrate) + volume_rate = CLAMP(volume_rate+diff, minrate, maxrate) . = 1 update_icon() diff --git a/code/game/machinery/bioprinter.dm b/code/game/machinery/bioprinter.dm index f66b580c52..cc982ce207 100644 --- a/code/game/machinery/bioprinter.dm +++ b/code/game/machinery/bioprinter.dm @@ -287,7 +287,7 @@ /obj/machinery/organ_printer/robot/dismantle() if(stored_matter >= matter_amount_per_sheet) - new /obj/item/stack/material/steel(get_turf(src), Floor(stored_matter/matter_amount_per_sheet)) + new /obj/item/stack/material/steel(get_turf(src), FLOOR(stored_matter/matter_amount_per_sheet, 1)) return ..() /obj/machinery/organ_printer/robot/print_organ(var/choice) @@ -305,7 +305,7 @@ return var/obj/item/stack/S = W var/space_left = max_stored_matter - stored_matter - var/sheets_to_take = min(S.amount, Floor(space_left/matter_amount_per_sheet)) + var/sheets_to_take = min(S.amount, FLOOR(space_left/matter_amount_per_sheet, 1)) if(sheets_to_take <= 0) to_chat(user, "\The [src] is too full.") return diff --git a/code/game/machinery/bomb_tester_vr.dm b/code/game/machinery/bomb_tester_vr.dm index 66d71f923d..224885d9ca 100644 --- a/code/game/machinery/bomb_tester_vr.dm +++ b/code/game/machinery/bomb_tester_vr.dm @@ -201,7 +201,7 @@ if(href_list["set_can_pressure"]) var/change = text2num(href_list["set_can_pressure"]) - sim_canister_output = Clamp(sim_canister_output+change, ONE_ATMOSPHERE/10, ONE_ATMOSPHERE*10) + sim_canister_output = CLAMP(sim_canister_output+change, ONE_ATMOSPHERE/10, ONE_ATMOSPHERE*10) if(href_list["start_sim"]) start_simulating() diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 20f5a617cf..e8b845ca78 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -96,7 +96,7 @@ kick_viewers() update_icon() update_coverage() - processing_objects |= src + START_PROCESSING(SSobj, src) /obj/machinery/camera/bullet_act(var/obj/item/projectile/P) take_damage(P.get_structure_damage()) @@ -143,7 +143,7 @@ /obj/machinery/camera/attack_generic(mob/user as mob) if(isanimal(user)) - var/mob/living/simple_animal/S = user + var/mob/living/simple_mob/S = user set_status(0) S.do_attack_animation(src) S.setClickCooldown(user.get_attack_speed()) diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 6b5926042f..8e3cb117f9 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -194,7 +194,7 @@ occupant.adjustCloneLoss(-2 * heal_rate) //Premature clones may have brain damage. - occupant.adjustBrainLoss(-(ceil(0.5*heal_rate))) + occupant.adjustBrainLoss(-(CEILING(0.5*heal_rate, 1))) //So clones don't die of oxyloss in a running pod. if(occupant.reagents.get_reagent_amount("inaprovaline") < 30) diff --git a/code/game/machinery/computer/Operating.dm b/code/game/machinery/computer/Operating.dm index ef1beeaac0..d81070e1f2 100644 --- a/code/game/machinery/computer/Operating.dm +++ b/code/game/machinery/computer/Operating.dm @@ -55,7 +55,7 @@ data["table"] = table data["victim"] = victim_ui - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "operating.tmpl", src.name, 380, 400) ui.set_initial_data(data) @@ -69,4 +69,4 @@ usr.set_machine(src) src.add_fingerprint(usr) - GLOB.nanomanager.update_uis(src) \ No newline at end of file + SSnanoui.update_uis(src) \ No newline at end of file diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index dbd96823c1..282e91dc3e 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -139,7 +139,7 @@ data["enemyHP"] = enemy_hp data["gameOver"] = gameover - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "arcade_battle.tmpl", src.name, 400, 300) ui.set_initial_data(data) @@ -201,7 +201,7 @@ emagged = 0 src.add_fingerprint(usr) - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) return /obj/machinery/computer/arcade/battle/proc/arcade_action() diff --git a/code/game/machinery/computer/atmos_alert.dm b/code/game/machinery/computer/atmos_alert.dm index d757ae777d..e2b3fc4638 100644 --- a/code/game/machinery/computer/atmos_alert.dm +++ b/code/game/machinery/computer/atmos_alert.dm @@ -37,7 +37,7 @@ var/global/list/minor_air_alarms = list() data["priority_alarms"] = major_alarms data["minor_alarms"] = minor_alarms - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if(!ui) ui = new(user, src, ui_key, "atmos_alert.tmpl", src.name, 500, 500) ui.set_initial_data(data) diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index 745bdc0694..4ac34cf157 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -49,7 +49,7 @@ switch_to_camera(user, current_camera) data["map_levels"] = using_map.get_map_levels(src.z) - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.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) @@ -152,7 +152,7 @@ /obj/machinery/computer/security/process() if(cache_id != camera_repository.camera_cache_id) cache_id = camera_repository.camera_cache_id - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) /obj/machinery/computer/security/proc/can_access_camera(var/obj/machinery/camera/C) var/list/shared_networks = src.network & C.network @@ -225,7 +225,7 @@ circuit = /obj/item/weapon/circuitboard/security/telescreen/entertainment var/obj/item/device/radio/radio = null -/obj/machinery/computer/security/telescreen/entertainment/initialize() +/obj/machinery/computer/security/telescreen/entertainment/Initialize() . = ..() radio = new(src) radio.listening = TRUE diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm index d23c199db0..d5d4cd2176 100644 --- a/code/game/machinery/computer/card.dm +++ b/code/game/machinery/computer/card.dm @@ -68,7 +68,7 @@ id_card.forceMove(src) modify = id_card - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) attack_hand(user) /obj/machinery/computer/card/attack_ai(var/mob/user as mob) @@ -139,7 +139,7 @@ data["regions"] = regions - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "identification_computer.tmpl", src.name, 600, 700) ui.set_initial_data(data) @@ -235,7 +235,7 @@ modify.registered_name = temp_name else src.visible_message("[src] buzzes rudely.") - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) if ("account") if (is_authenticated()) @@ -243,7 +243,7 @@ if ((modify == t2 && (in_range(src, usr) || (istype(usr, /mob/living/silicon))) && istype(loc, /turf))) var/account_num = text2num(href_list["account"]) modify.associated_account_number = account_num - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) if ("mode") mode = text2num(href_list["mode_target"]) @@ -253,7 +253,7 @@ printing = 1 spawn(50) printing = null - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) var/obj/item/weapon/paper/P = new(loc) if (mode) diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index cbf0041025..96e6f6b5f9 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -16,7 +16,7 @@ var/loading = 0 // Nice loading text -/obj/machinery/computer/cloning/initialize() +/obj/machinery/computer/cloning/Initialize() . = ..() updatemodules() @@ -146,7 +146,7 @@ data["diskette"] = diskette data["temp"] = temp - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "cloning.tmpl", src.name, 400, 450) ui.set_initial_data(data) @@ -284,7 +284,7 @@ temp = "" scantemp = "" - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) add_fingerprint(usr) /obj/machinery/computer/cloning/proc/scan_mob(mob/living/carbon/human/subject as mob) diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index f08662a5ec..f8bd0877f9 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -501,8 +501,8 @@ //delay events in case of an autotransfer if (isnull(user)) - event_manager.delay_events(EVENT_LEVEL_MODERATE, 9000) //15 minutes - event_manager.delay_events(EVENT_LEVEL_MAJOR, 9000) + SSevents.delay_events(EVENT_LEVEL_MODERATE, 9000) //15 minutes + SSevents.delay_events(EVENT_LEVEL_MAJOR, 9000) log_game("[user? key_name(user) : "Autotransfer"] has called the shuttle.") message_admins("[user? key_name_admin(user) : "Autotransfer"] has called the shuttle.", 1) diff --git a/code/game/machinery/computer/computer.dm b/code/game/machinery/computer/computer.dm index cb73fe4d7a..40a7551739 100644 --- a/code/game/machinery/computer/computer.dm +++ b/code/game/machinery/computer/computer.dm @@ -21,7 +21,7 @@ overlay_layer = layer ..() -/obj/machinery/computer/initialize() +/obj/machinery/computer/Initialize() . = ..() power_change() update_icon() diff --git a/code/game/machinery/computer/guestpass.dm b/code/game/machinery/computer/guestpass.dm index 91a4a76bb8..a1fd7199b2 100644 --- a/code/game/machinery/computer/guestpass.dm +++ b/code/game/machinery/computer/guestpass.dm @@ -54,13 +54,13 @@ expired = 1 return ..() -/obj/item/weapon/card/id/guest/initialize() +/obj/item/weapon/card/id/guest/Initialize() . = ..() - processing_objects.Add(src) + START_PROCESSING(SSobj, src) update_icon() /obj/item/weapon/card/id/guest/Destroy() - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) return ..() /obj/item/weapon/card/id/guest/process() @@ -104,7 +104,7 @@ if(!giver && user.unEquip(I)) I.forceMove(src) giver = I - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) else if(giver) user << "There is already ID card inside." return @@ -150,7 +150,7 @@ data["log"] = internal_log data["uid"] = uid - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "guest_pass.tmpl", src.name, 400, 520) ui.set_initial_data(data) @@ -242,4 +242,4 @@ usr << "Cannot issue pass without issuing ID." src.add_fingerprint(usr) - GLOB.nanomanager.update_uis(src) \ No newline at end of file + SSnanoui.update_uis(src) \ No newline at end of file diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm index 0a90aef582..0c24c15b3e 100644 --- a/code/game/machinery/computer/medical.dm +++ b/code/game/machinery/computer/medical.dm @@ -5,7 +5,6 @@ desc = "Used to view, edit and maintain medical records." icon_keyboard = "med_key" icon_screen = "medcomp" - density = 0 //Why does a laptop blocks peoples. light_color = "#315ab4" req_one_access = list(access_medical, access_forensics_lockers, access_robotics) circuit = /obj/item/weapon/circuitboard/med_data @@ -554,4 +553,4 @@ icon_state = "laptop" icon_keyboard = "laptop_key" icon_screen = "medlaptop" - throwpass = 1 //VOREStation Edit - Really??? + density = 0 \ No newline at end of file diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm index 670b637152..6fce75def7 100644 --- a/code/game/machinery/computer/message.dm +++ b/code/game/machinery/computer/message.dm @@ -71,7 +71,7 @@ icon_screen = initial(icon_screen) ..() -/obj/machinery/computer/message_monitor/initialize() +/obj/machinery/computer/message_monitor/Initialize() //Is the server isn't linked to a server, and there's a server available, default it to the first one in the list. if(!linkedServer) if(message_servers && message_servers.len > 0) diff --git a/code/game/machinery/computer/prisonshuttle.dm b/code/game/machinery/computer/prisonshuttle.dm index 8c435f5845..8fe6ffef8a 100644 --- a/code/game/machinery/computer/prisonshuttle.dm +++ b/code/game/machinery/computer/prisonshuttle.dm @@ -201,7 +201,7 @@ var/prison_shuttle_timeleft = 0 for(var/mob/living/carbon/bug in end_location) // If someone somehow is still in the shuttle's docking area... bug.gib() - for(var/mob/living/simple_animal/pest in end_location) // And for the other kind of bug... + for(var/mob/living/simple_mob/pest in end_location) // And for the other kind of bug... pest.gib() start_location.move_contents_to(end_location) diff --git a/code/game/machinery/computer/robot.dm b/code/game/machinery/computer/robot.dm index c6c2c94a9e..3e06e19e52 100644 --- a/code/game/machinery/computer/robot.dm +++ b/code/game/machinery/computer/robot.dm @@ -19,7 +19,7 @@ data["is_ai"] = issilicon(user) - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "robot_control.tmpl", "Robotic Control Console", 400, 500) ui.set_initial_data(data) diff --git a/code/game/machinery/computer/skills.dm b/code/game/machinery/computer/skills.dm index fb92e700ff..a374d48c8c 100644 --- a/code/game/machinery/computer/skills.dm +++ b/code/game/machinery/computer/skills.dm @@ -9,6 +9,7 @@ light_color = "#00b000" req_one_access = list(access_heads) circuit = /obj/item/weapon/circuitboard/skills + density = 0 var/obj/item/weapon/card/id/scan = null var/authenticated = null var/rank = null diff --git a/code/game/machinery/computer/specops_shuttle.dm b/code/game/machinery/computer/specops_shuttle.dm index 1f7c959db5..431d6278d6 100644 --- a/code/game/machinery/computer/specops_shuttle.dm +++ b/code/game/machinery/computer/specops_shuttle.dm @@ -81,7 +81,7 @@ var/specops_shuttle_timeleft = 0 for(var/mob/living/carbon/bug in end_location) // If someone somehow is still in the shuttle's docking area... bug.gib() - for(var/mob/living/simple_animal/pest in end_location) // And for the other kind of bug... + for(var/mob/living/simple_mob/pest in end_location) // And for the other kind of bug... pest.gib() start_location.move_contents_to(end_location) diff --git a/code/game/machinery/computer/station_alert.dm b/code/game/machinery/computer/station_alert.dm index d3ab69b869..8bd2f91f89 100644 --- a/code/game/machinery/computer/station_alert.dm +++ b/code/game/machinery/computer/station_alert.dm @@ -17,7 +17,7 @@ monitor_type = /datum/nano_module/alarm_monitor/all circuit = /obj/item/weapon/circuitboard/stationalert_all -/obj/machinery/computer/station_alert/initialize() +/obj/machinery/computer/station_alert/Initialize() alarm_monitor = new monitor_type(src) alarm_monitor.register_alarm(src, /obj/machinery/computer/station_alert/update_icon) . = ..() diff --git a/code/game/machinery/computer/supply.dm b/code/game/machinery/computer/supply.dm index fcaa2b4d8a..1495836cb7 100644 --- a/code/game/machinery/computer/supply.dm +++ b/code/game/machinery/computer/supply.dm @@ -169,7 +169,7 @@ data["contraband"] = can_order_contraband || (authorization & SUP_CONTRABAND) // update the ui if it exists, returns null if no ui is passed/found - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.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 diff --git a/code/game/machinery/computer/syndicate_specops_shuttle.dm b/code/game/machinery/computer/syndicate_specops_shuttle.dm index ba7193b69b..e02ab68474 100644 --- a/code/game/machinery/computer/syndicate_specops_shuttle.dm +++ b/code/game/machinery/computer/syndicate_specops_shuttle.dm @@ -166,7 +166,7 @@ var/syndicate_elite_shuttle_timeleft = 0 for(var/mob/living/carbon/bug in end_location) // If someone somehow is still in the shuttle's docking area... bug.gib() - for(var/mob/living/simple_animal/pest in end_location) // And for the other kind of bug... + for(var/mob/living/simple_mob/pest in end_location) // And for the other kind of bug... pest.gib() start_location.move_contents_to(end_location) diff --git a/code/game/machinery/computer/timeclock_vr.dm b/code/game/machinery/computer/timeclock_vr.dm index 98dc8e635d..3f2d44ce0b 100644 --- a/code/game/machinery/computer/timeclock_vr.dm +++ b/code/game/machinery/computer/timeclock_vr.dm @@ -47,7 +47,7 @@ if(!card && user.unEquip(I)) I.forceMove(src) card = I - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) update_icon() else if(card) to_chat(user, "There is already ID card inside.") @@ -87,7 +87,7 @@ // if(job && job.timeoff_factor < 0) // Currently are Off Duty, so gotta lookup what on-duty jobs are open // data["job_choices"] = getOpenOnDutyJobs(user, job.department) - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "timeclock_vr.tmpl", capitalize(src.name), 500, 520) ui.set_initial_data(data) diff --git a/code/game/machinery/computer3/computers/HolodeckControl.dm b/code/game/machinery/computer3/computers/HolodeckControl.dm index fcff13c968..da3c2416fd 100644 --- a/code/game/machinery/computer3/computers/HolodeckControl.dm +++ b/code/game/machinery/computer3/computers/HolodeckControl.dm @@ -207,7 +207,7 @@ for(var/obj/effect/decal/cleanable/blood/B in linkedholodeck) qdel(B) - for(var/mob/living/simple_animal/hostile/carp/C in linkedholodeck) + for(var/mob/living/simple_mob/animal/space/carp/C in linkedholodeck) qdel(C) holographic_items = A.copy_contents_to(linkedholodeck , 1) @@ -228,7 +228,7 @@ T.temperature = 5000 T.hotspot_expose(50000,50000,1) if(L.name=="Holocarp Spawn") - new /mob/living/simple_animal/hostile/carp(L.loc) + new /mob/living/simple_mob/animal/space/carp(L.loc) /datum/file/program/holodeck/proc/emergencyShutdown() diff --git a/code/game/machinery/computer3/lapvend.dm b/code/game/machinery/computer3/lapvend.dm index 79f297157c..7c4e458832 100644 --- a/code/game/machinery/computer3/lapvend.dm +++ b/code/game/machinery/computer3/lapvend.dm @@ -34,11 +34,11 @@ if(vendmode == 1 && I) scan_id(I, W) vendmode = 0 - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) if(vendmode == 2 && I) if(reimburse_id(I, W)) vendmode = 0 - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) if(vendmode == 0) if(istype(W, /obj/item/device/laptop)) var/obj/item/device/laptop/L = W @@ -48,7 +48,7 @@ L.loc = src vendmode = 2 to_chat(user, "You slot your [L.name] into \The [src.name]") - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) else ..() @@ -77,7 +77,7 @@ data["power"] = power data["total"] = total() - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "laptop_vendor.tmpl", src.name, 480, 425) ui.set_initial_data(data) @@ -136,7 +136,7 @@ vendmode = 0 src.add_fingerprint(usr) - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) /obj/machinery/lapvend/proc/vend() if(cardreader > 0) diff --git a/code/game/machinery/computer3/program.dm b/code/game/machinery/computer3/program.dm index b39998bdfd..bf84c1622e 100644 --- a/code/game/machinery/computer3/program.dm +++ b/code/game/machinery/computer3/program.dm @@ -117,7 +117,7 @@ Programs are a file that can be executed /* The computer object will transfer process() calls to the program. */ -/datum/file/program/proc/process() +/datum/file/program/process() if(refresh && computer && !computer.stat) computer.updateDialog() update_icon() diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm index 20a54046a6..b4927f441c 100644 --- a/code/game/machinery/cryo.dm +++ b/code/game/machinery/cryo.dm @@ -30,7 +30,7 @@ icon_state = "base" initialize_directions = dir -/obj/machinery/atmospherics/unary/cryo_cell/initialize() +/obj/machinery/atmospherics/unary/cryo_cell/Initialize() . = ..() var/image/tank = image(icon,"tank") tank.alpha = 200 @@ -141,7 +141,7 @@ data["beakerVolume"] += R.volume // update the ui if it exists, returns null if no ui is passed/found - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.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 @@ -199,14 +199,13 @@ return if(occupant) to_chat(user,"\The [src] is already occupied by [occupant].") - for(var/mob/living/simple_animal/slime/M in range(1,grab.affecting)) - if(M.victim == grab.affecting) - to_chat(usr, "[grab.affecting.name] will not fit into the cryo because they have a slime latched onto their head.") - return + if(grab.affecting.has_buckled_mobs()) + to_chat(user, span("warning", "\The [grab.affecting] has other entities attached to it. Remove them first.")) + return var/mob/M = grab.affecting qdel(grab) put_mob(M) - + return /obj/machinery/atmospherics/unary/cryo_cell/MouseDrop_T(var/mob/target, var/mob/user) //Allows borgs to put people into cryo without external assistance @@ -349,14 +348,14 @@ set name = "Move Inside" set category = "Object" set src in oview(1) - for(var/mob/living/simple_animal/slime/M in range(1,usr)) - if(M.victim == usr) - to_chat(usr, "You're too busy getting your life sucked out of you.") + if(isliving(usr)) + var/mob/living/L = usr + if(L.has_buckled_mobs()) + to_chat(L, span("warning", "You have other entities attached to yourself. Remove them first.")) return - if(usr.stat != 0) - return - put_mob(usr) - return + if(L.stat != CONSCIOUS) + return + put_mob(L) /atom/proc/return_air_for_internal_lifeform(var/mob/living/lifeform) return return_air() diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 91fe137e54..ec127a4599 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -303,7 +303,7 @@ occupant.resting = 1 return ..() -/obj/machinery/cryopod/initialize() +/obj/machinery/cryopod/Initialize() . = ..() find_control_computer() @@ -574,9 +574,10 @@ to_chat(usr, "\The [src] is in use.") return - for(var/mob/living/simple_animal/slime/M in range(1,usr)) - if(M.victim == usr) - to_chat(usr, "You're too busy getting your life sucked out of you.") + if(isliving(usr)) + var/mob/living/L = usr + if(L.has_buckled_mobs()) + to_chat(L, span("warning", "You have other entities attached to yourself. Remove them first.")) return visible_message("[usr] [on_enter_visible_message] [src].", 3) diff --git a/code/game/machinery/door_control.dm b/code/game/machinery/door_control.dm index e10e3bda3f..290ff6745e 100644 --- a/code/game/machinery/door_control.dm +++ b/code/game/machinery/door_control.dm @@ -4,6 +4,7 @@ icon = 'icons/obj/stationobjs.dmi' icon_state = "doorctrl0" power_channel = ENVIRON + layer = ABOVE_WINDOW_LAYER var/desiredstate = 0 var/exposedwires = 0 var/wires = 3 diff --git a/code/game/machinery/doorbell_vr.dm b/code/game/machinery/doorbell_vr.dm index 46dec472a6..25fb75df44 100644 --- a/code/game/machinery/doorbell_vr.dm +++ b/code/game/machinery/doorbell_vr.dm @@ -11,7 +11,7 @@ var/id_tag = null var/chime_sound = 'sound/machines/doorbell.ogg' -/obj/machinery/doorbell_chime/initialize() +/obj/machinery/doorbell_chime/Initialize() . = ..() update_icon() @@ -99,7 +99,7 @@ assign_uid() id = num2text(uid) -/obj/machinery/button/doorbell/initialize() +/obj/machinery/button/doorbell/Initialize() . = ..() update_icon() diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 541e461f27..9c1a9a75b0 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -46,11 +46,12 @@ var/bolt_up_sound = 'sound/machines/boltsup.ogg' var/bolt_down_sound = 'sound/machines/boltsdown.ogg' -/obj/machinery/door/airlock/attack_generic(var/mob/user, var/damage) +/obj/machinery/door/airlock/attack_generic(var/mob/living/user, var/damage) if(stat & (BROKEN|NOPOWER)) - if(damage >= 10) + if(damage >= STRUCTURE_MIN_DAMAGE_THRESHOLD) if(src.locked || src.welded) visible_message("\The [user] begins breaking into \the [src] internals!") + user.set_AI_busy(TRUE) // If the mob doesn't have an AI attached, this won't do anything. if(do_after(user,10 SECONDS,src)) src.locked = 0 src.welded = 0 @@ -58,6 +59,7 @@ open(1) if(prob(25)) src.shock(user, 100) + user.set_AI_busy(FALSE) else if(src.density) visible_message("\The [user] forces \the [src] open!") open(1) @@ -508,9 +510,6 @@ About the new airlock wires panel: return ..(user) -/obj/machinery/door/airlock/bumpopen(mob/living/simple_animal/user as mob) - ..(user) - /obj/machinery/door/airlock/proc/isElectrified() if(src.electrified_until != 0) return 1 @@ -728,7 +727,7 @@ About the new airlock wires panel: data["commands"] = commands - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "door_control.tmpl", "Door Controls", 450, 350, state = state) ui.set_initial_data(data) @@ -1206,7 +1205,7 @@ About the new airlock wires panel: else wires = new/datum/wires/airlock(src) -/obj/machinery/door/airlock/initialize() +/obj/machinery/door/airlock/Initialize() if(src.closeOtherId != null) for (var/obj/machinery/door/airlock/A in machines) if(A.closeOtherId == src.closeOtherId && A != src) diff --git a/code/game/machinery/doors/airlock_control.dm b/code/game/machinery/doors/airlock_control.dm index 295a7ff24f..cbd0875cd3 100644 --- a/code/game/machinery/doors/airlock_control.dm +++ b/code/game/machinery/doors/airlock_control.dm @@ -129,7 +129,7 @@ obj/machinery/door/airlock/proc/set_frequency(new_frequency) radio_connection = radio_controller.add_object(src, frequency, RADIO_AIRLOCK) -obj/machinery/door/airlock/initialize() +obj/machinery/door/airlock/Initialize() . = ..() if(frequency) set_frequency(frequency) @@ -203,7 +203,7 @@ obj/machinery/airlock_sensor/proc/set_frequency(new_frequency) frequency = new_frequency radio_connection = radio_controller.add_object(src, frequency, RADIO_AIRLOCK) -obj/machinery/airlock_sensor/initialize() +obj/machinery/airlock_sensor/Initialize() . = ..() set_frequency(frequency) @@ -276,7 +276,7 @@ obj/machinery/access_button/proc/set_frequency(new_frequency) radio_connection = radio_controller.add_object(src, frequency, RADIO_AIRLOCK) -obj/machinery/access_button/initialize() +obj/machinery/access_button/Initialize() . = ..() set_frequency(frequency) diff --git a/code/game/machinery/doors/alarmlock.dm b/code/game/machinery/doors/alarmlock.dm index 1c384a651d..f7dda48feb 100644 --- a/code/game/machinery/doors/alarmlock.dm +++ b/code/game/machinery/doors/alarmlock.dm @@ -18,7 +18,7 @@ radio_controller.remove_object(src,air_frequency) ..() -/obj/machinery/door/airlock/alarmlock/initialize() +/obj/machinery/door/airlock/alarmlock/Initialize() . = ..() radio_controller.remove_object(src, air_frequency) air_connection = radio_controller.add_object(src, air_frequency, RADIO_TO_AIRALARM) diff --git a/code/game/machinery/doors/blast_door.dm b/code/game/machinery/doors/blast_door.dm index f4926c2aa8..13cc48c4c5 100644 --- a/code/game/machinery/doors/blast_door.dm +++ b/code/game/machinery/doors/blast_door.dm @@ -23,7 +23,7 @@ var/icon_state_closed = null var/icon_state_closing = null - closed_layer = 3.3 // Above airlocks when closed + closed_layer = ON_WINDOW_LAYER // Above airlocks when closed var/id = 1.0 dir = 1 explosion_resistance = 25 @@ -32,7 +32,7 @@ //turning this off prevents awkward zone geometry in places like medbay lobby, for example. block_air_zones = 0 -/obj/machinery/door/blast/initialize() +/obj/machinery/door/blast/Initialize() . = ..() implicit_material = get_material_by_name("plasteel") @@ -151,7 +151,7 @@ return else if(istype(C, /obj/item/stack/material) && C.get_material_name() == "plasteel") // Repairing. - var/amt = Ceiling((maxhealth - health)/150) + var/amt = CEILING((maxhealth - health)/150, 1) if(!amt) to_chat(user, "\The [src] is already fully repaired.") return diff --git a/code/game/machinery/doors/brigdoors.dm b/code/game/machinery/doors/brigdoors.dm index fe1d726d50..0935dfa724 100644 --- a/code/game/machinery/doors/brigdoors.dm +++ b/code/game/machinery/doors/brigdoors.dm @@ -31,7 +31,7 @@ maptext_height = 26 maptext_width = 32 -/obj/machinery/door_timer/initialize() +/obj/machinery/door_timer/Initialize() ..() //Doors need to go first, and can't rely on init order, so come back to me. return INITIALIZE_HINT_LATELOAD diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index ddb2001639..b0dde10ee4 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -39,8 +39,8 @@ /obj/machinery/door/attack_generic(var/mob/user, var/damage) if(isanimal(user)) - var/mob/living/simple_animal/S = user - if(damage >= 10) + var/mob/living/simple_mob/S = user + if(damage >= STRUCTURE_MIN_DAMAGE_THRESHOLD) visible_message("\The [user] smashes into the [src]!") playsound(src, S.attack_sound, 75, 1) take_damage(damage) @@ -98,6 +98,7 @@ return 1 /obj/machinery/door/Bumped(atom/AM) + . = ..() if(p_open || operating) return if(ismob(AM)) @@ -133,9 +134,6 @@ open() else do_animate("deny") - return - return - /obj/machinery/door/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) if(air_group) return !block_air_zones diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index fb7609ee05..ac5246d2da 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -216,22 +216,26 @@ return ..() -/obj/machinery/door/firedoor/attack_generic(var/mob/user, var/damage) +/obj/machinery/door/firedoor/attack_generic(var/mob/living/user, var/damage) if(stat & (BROKEN|NOPOWER)) - if(damage >= 10) + if(damage >= STRUCTURE_MIN_DAMAGE_THRESHOLD) var/time_to_force = (2 + (2 * blocked)) * 5 if(src.density) visible_message("\The [user] starts forcing \the [src] open!") + user.set_AI_busy(TRUE) // If the mob doesn't have an AI attached, this won't do anything. if(do_after(user, time_to_force, src)) visible_message("\The [user] forces \the [src] open!") src.blocked = 0 open(1) + user.set_AI_busy(FALSE) else time_to_force = (time_to_force / 2) visible_message("\The [user] starts forcing \the [src] closed!") + user.set_AI_busy(TRUE) // If the mob doesn't have an AI attached, this won't do anything. if(do_after(user, time_to_force, src)) visible_message("\The [user] forces \the [src] closed!") close(1) + user.set_AI_busy(FALSE) else visible_message("\The [user] strains fruitlessly to force \the [src] [density ? "open" : "closed"].") return diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index fe21197dc5..1724b49192 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -68,33 +68,26 @@ if(istype(bot)) if(density && src.check_access(bot.botcard)) open() - sleep(50) - close() + addtimer(CALLBACK(src, .proc/close), 50) else if(istype(AM, /obj/mecha)) var/obj/mecha/mecha = AM if(density) if(mecha.occupant && src.allowed(mecha.occupant)) open() - sleep(50) - close() + addtimer(CALLBACK(src, .proc/close), 50) return if (!( ticker )) return if (src.operating) return - if (src.density && src.allowed(AM)) + if (density && allowed(AM)) open() - if(src.check_access(null)) - sleep(50) - else //secure doors close faster - sleep(20) - close() - return + addtimer(CALLBACK(src, .proc/close), check_access(null)? 50 : 20) -/obj/machinery/door/window/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) +/obj/machinery/door/window/CanPass(atom/movable/mover, turf/target, height, air_group) if(istype(mover) && mover.checkpass(PASSGLASS)) return 1 - if(get_dir(loc, target) == dir) //Make sure looking at appropriate border + if(get_dir(mover, loc) == turn(dir, 180)) //Make sure looking at appropriate border if(air_group) return 0 return !density else @@ -109,7 +102,7 @@ return 1 /obj/machinery/door/window/open() - if (operating == 1) //doors can still open when emag-disabled + if (operating == 1 || !density) //doors can still open when emag-disabled return 0 if (!ticker) return 0 @@ -129,20 +122,20 @@ return 1 /obj/machinery/door/window/close() - if (operating) - return 0 - src.operating = 1 + if(operating || density) + return FALSE + operating = TRUE flick(text("[]closing", src.base_state), src) playsound(src.loc, 'sound/machines/windowdoor.ogg', 100, 1) - density = 1 + density = TRUE update_icon() explosion_resistance = initial(explosion_resistance) update_nearby_tiles() sleep(10) - operating = 0 - return 1 + operating = FALSE + return TRUE /obj/machinery/door/window/take_damage(var/damage) src.health = max(0, src.health - damage) diff --git a/code/game/machinery/doppler_array.dm b/code/game/machinery/doppler_array.dm index 7a4087e2c4..e0fc32e082 100644 --- a/code/game/machinery/doppler_array.dm +++ b/code/game/machinery/doppler_array.dm @@ -4,6 +4,8 @@ var/list/doppler_arrays = list() name = "tachyon-doppler array" desc = "A highly precise directional sensor array which measures the release of quants from decaying tachyons. The doppler shifting of the mirror-image formed by these quants can reveal the size, location and temporal affects of energetic disturbances within a large radius ahead of the array." + icon_state = "doppler" + /obj/machinery/doppler_array/New() ..() doppler_arrays += src diff --git a/code/game/machinery/embedded_controller/airlock_controllers.dm b/code/game/machinery/embedded_controller/airlock_controllers.dm index 6bf5fe0553..0f8b797289 100644 --- a/code/game/machinery/embedded_controller/airlock_controllers.dm +++ b/code/game/machinery/embedded_controller/airlock_controllers.dm @@ -13,7 +13,7 @@ var/tag_secure = 0 var/cycle_to_external_air = 0 -/obj/machinery/embedded_controller/radio/airlock/initialize() +/obj/machinery/embedded_controller/radio/airlock/Initialize() . = ..() program = new/datum/computer/file/embedded_program/airlock(src) @@ -33,7 +33,7 @@ "secure" = program.memory["secure"] ) - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "advanced_airlock_console.tmpl", name, 470, 290) @@ -89,7 +89,7 @@ "processing" = program.memory["processing"], ) - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "simple_airlock_console.tmpl", name, 470, 290) @@ -153,7 +153,7 @@ "processing" = program.memory["processing"] ) - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "door_access_console.tmpl", name, 330, 220) diff --git a/code/game/machinery/embedded_controller/airlock_docking_controller.dm b/code/game/machinery/embedded_controller/airlock_docking_controller.dm index 86885ebd53..e88b046c10 100644 --- a/code/game/machinery/embedded_controller/airlock_docking_controller.dm +++ b/code/game/machinery/embedded_controller/airlock_docking_controller.dm @@ -5,7 +5,7 @@ var/datum/computer/file/embedded_program/docking/airlock/docking_program tag_secure = 1 -/obj/machinery/embedded_controller/radio/airlock/docking_port/initialize() +/obj/machinery/embedded_controller/radio/airlock/docking_port/Initialize() . = ..() airlock_program = new/datum/computer/file/embedded_program/airlock/docking(src) docking_program = new/datum/computer/file/embedded_program/docking/airlock(src, airlock_program) @@ -24,7 +24,7 @@ "override_enabled" = docking_program.override_enabled, ) - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "docking_airlock_console.tmpl", name, 470, 290) diff --git a/code/game/machinery/embedded_controller/airlock_docking_controller_multi.dm b/code/game/machinery/embedded_controller/airlock_docking_controller_multi.dm index 7c35568e51..5614d0be63 100644 --- a/code/game/machinery/embedded_controller/airlock_docking_controller_multi.dm +++ b/code/game/machinery/embedded_controller/airlock_docking_controller_multi.dm @@ -9,7 +9,7 @@ var/datum/computer/file/embedded_program/docking/multi/docking_program -/obj/machinery/embedded_controller/radio/docking_port_multi/initialize() +/obj/machinery/embedded_controller/radio/docking_port_multi/Initialize() . = ..() docking_program = new/datum/computer/file/embedded_program/docking/multi(src) program = docking_program @@ -35,7 +35,7 @@ "airlocks" = airlocks, ) - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "multi_docking_console.tmpl", name, 470, 290) @@ -55,7 +55,7 @@ var/datum/computer/file/embedded_program/airlock/multi_docking/airlock_program tag_secure = 1 -/obj/machinery/embedded_controller/radio/airlock/docking_port_multi/initialize() +/obj/machinery/embedded_controller/radio/airlock/docking_port_multi/Initialize() . = ..() airlock_program = new/datum/computer/file/embedded_program/airlock/multi_docking(src) program = airlock_program @@ -73,7 +73,7 @@ "override_enabled" = airlock_program.override_enabled, ) - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "docking_airlock_console.tmpl", name, 470, 290) diff --git a/code/game/machinery/embedded_controller/embedded_controller_base.dm b/code/game/machinery/embedded_controller/embedded_controller_base.dm index 6833498b5f..17bf13181a 100644 --- a/code/game/machinery/embedded_controller/embedded_controller_base.dm +++ b/code/game/machinery/embedded_controller/embedded_controller_base.dm @@ -57,7 +57,7 @@ obj/machinery/embedded_controller/radio/Destroy() var/datum/radio_frequency/radio_connection unacidable = 1 -/obj/machinery/embedded_controller/radio/initialize() +/obj/machinery/embedded_controller/radio/Initialize() . = ..() set_frequency(frequency) diff --git a/code/game/machinery/embedded_controller/embedded_program_base.dm b/code/game/machinery/embedded_controller/embedded_program_base.dm index f579aca6f7..0cc711c7a4 100644 --- a/code/game/machinery/embedded_controller/embedded_program_base.dm +++ b/code/game/machinery/embedded_controller/embedded_program_base.dm @@ -17,9 +17,6 @@ /datum/computer/file/embedded_program/proc/receive_signal(datum/signal/signal, receive_method, receive_param) return -/datum/computer/file/embedded_program/proc/process() - return - /datum/computer/file/embedded_program/proc/post_signal(datum/signal/signal, comm_line) if(master) master.post_signal(signal, comm_line) diff --git a/code/game/machinery/embedded_controller/simple_docking_controller.dm b/code/game/machinery/embedded_controller/simple_docking_controller.dm index 9242afd762..14b27b2512 100644 --- a/code/game/machinery/embedded_controller/simple_docking_controller.dm +++ b/code/game/machinery/embedded_controller/simple_docking_controller.dm @@ -4,7 +4,7 @@ var/tag_door var/datum/computer/file/embedded_program/docking/simple/docking_program -/obj/machinery/embedded_controller/radio/simple_docking_controller/initialize() +/obj/machinery/embedded_controller/radio/simple_docking_controller/Initialize() . = ..() docking_program = new/datum/computer/file/embedded_program/docking/simple(src) program = docking_program @@ -19,7 +19,7 @@ "door_lock" = docking_program.memory["door_status"]["lock"], ) - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "simple_docking_console.tmpl", name, 470, 290) diff --git a/code/game/machinery/exonet_node.dm b/code/game/machinery/exonet_node.dm index fee3fbd0ec..fbfbc04abf 100644 --- a/code/game/machinery/exonet_node.dm +++ b/code/game/machinery/exonet_node.dm @@ -123,7 +123,7 @@ // update the ui if it exists, returns null if no ui is passed/found - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.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 @@ -167,7 +167,7 @@ log_game(msg) update_icon() - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) add_fingerprint(usr) // Proc: get_exonet_node() diff --git a/code/game/machinery/frame.dm b/code/game/machinery/frame.dm index 2c16d3771e..c54734aec0 100644 --- a/code/game/machinery/frame.dm +++ b/code/game/machinery/frame.dm @@ -569,7 +569,7 @@ update_icon() -/obj/structure/frame/verb/rotate() +/obj/structure/frame/verb/rotate_counterclockwise() set name = "Rotate Frame Counter-Clockwise" set category = "Object" set src in oview(1) @@ -581,14 +581,14 @@ to_chat(usr, "It is fastened to the floor therefore you can't rotate it!") return 0 - set_dir(turn(dir, 90)) + src.set_dir(turn(src.dir, 90)) to_chat(usr, "You rotate the [src] to face [dir2text(dir)]!") return -/obj/structure/frame/verb/revrotate() +/obj/structure/frame/verb/rotate_clockwise() set name = "Rotate Frame Clockwise" set category = "Object" set src in oview(1) @@ -600,7 +600,7 @@ to_chat(usr, "It is fastened to the floor therefore you can't rotate it!") return 0 - set_dir(turn(dir, 270)) + src.set_dir(turn(src.dir, 270)) to_chat(usr, "You rotate the [src] to face [dir2text(dir)]!") diff --git a/code/game/machinery/jukebox.dm b/code/game/machinery/jukebox.dm index 5c94d8a114..475f22a7d7 100644 --- a/code/game/machinery/jukebox.dm +++ b/code/game/machinery/jukebox.dm @@ -64,7 +64,7 @@ ..() // On initialization, copy our tracks from the global list -/obj/machinery/media/jukebox/initialize() +/obj/machinery/media/jukebox/Initialize() . = ..() if(LAZYLEN(all_jukebox_tracks)) //Global list has tracks tracks.Cut() @@ -265,7 +265,7 @@ data["tracks"] = nano_tracks // update the ui if it exists, returns null if no ui is passed/found - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "jukebox.tmpl", title, 450, 600) ui.set_initial_data(data) diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 5f5387184d..0729121195 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -117,6 +117,8 @@ Class Procs: var/interact_offline = 0 // Can the machine be interacted with while de-powered. var/obj/item/weapon/circuitboard/circuit = null + var/speed_process = FALSE //If false, SSmachines. If true, SSfastprocess. + /obj/machinery/New(l, d=0) ..(l) if(d) @@ -124,13 +126,19 @@ Class Procs: if(circuit) circuit = new circuit(src) -/obj/machinery/initialize() +/obj/machinery/Initialize() . = ..() global.machines += src - START_MACHINE_PROCESSING(src) + if(!speed_process) + START_MACHINE_PROCESSING(src) + else + START_PROCESSING(SSfastprocess, src) /obj/machinery/Destroy() - STOP_MACHINE_PROCESSING(src) + if(!speed_process) + STOP_MACHINE_PROCESSING(src) + else + STOP_PROCESSING(SSfastprocess, src) global.machines -= src if(component_parts) for(var/atom/A in component_parts) @@ -153,8 +161,6 @@ Class Procs: if(!(use_power || idle_power_usage || active_power_usage)) return PROCESS_KILL - return - /obj/machinery/emp_act(severity) if(use_power && stat == 0) use_power(7500/severity) diff --git a/code/game/machinery/oxygen_pump.dm b/code/game/machinery/oxygen_pump.dm index 2f781129b6..74cc399beb 100644 --- a/code/game/machinery/oxygen_pump.dm +++ b/code/game/machinery/oxygen_pump.dm @@ -22,7 +22,7 @@ idle_power_usage = 10 active_power_usage = 120 // No idea what the realistic amount would be. -/obj/machinery/oxygen_pump/initialize() +/obj/machinery/oxygen_pump/Initialize() . = ..() tank = new spawn_type (src) contained = new mask_type (src) @@ -202,7 +202,7 @@ // update the ui if it exists, returns null if no ui is passed/found - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.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 diff --git a/code/game/machinery/partslathe_vr.dm b/code/game/machinery/partslathe_vr.dm index fc594606d1..d2d9079ab1 100644 --- a/code/game/machinery/partslathe_vr.dm +++ b/code/game/machinery/partslathe_vr.dm @@ -179,29 +179,29 @@ /obj/machinery/partslathe/proc/canBuild(var/datum/category_item/partslathe/D) for(var/M in D.resources) - if(materials[M] < Ceiling(D.resources[M] * mat_efficiency)) + if(materials[M] < CEILING((D.resources[M] * mat_efficiency), 1)) return 0 return 1 /obj/machinery/partslathe/proc/getLackingMaterials(var/datum/category_item/partslathe/D) var/ret = "" for(var/M in D.resources) - if(materials[M] < Ceiling(D.resources[M] * mat_efficiency)) + if(materials[M] < CEILING((D.resources[M] * mat_efficiency), 1)) if(ret != "") ret += ", " - ret += "[Ceiling(D.resources[M] * mat_efficiency) - materials[M]] [M]" + ret += "[CEILING((D.resources[M] * mat_efficiency), 1) - materials[M]] [M]" return ret /obj/machinery/partslathe/proc/build(var/datum/category_item/partslathe/D) for(var/M in D.resources) - materials[M] = max(0, materials[M] - Ceiling(D.resources[M] * mat_efficiency)) + materials[M] = max(0, materials[M] - CEILING((D.resources[M] * mat_efficiency), 1)) var/obj/new_item = D.build(loc); if(new_item) new_item.loc = loc if(mat_efficiency < 1) // No matter out of nowhere if(new_item.matter && new_item.matter.len > 0) for(var/i in new_item.matter) - new_item.matter[i] = Ceiling(new_item.matter[i] * mat_efficiency) + new_item.matter[i] = CEILING((new_item.matter[i] * mat_efficiency), 1) // 0 amount = 0 means ejecting a full stack; -1 means eject everything /obj/machinery/partslathe/proc/eject_materials(var/material, var/amount) @@ -280,7 +280,7 @@ recipies_ui[++recipies_ui.len] = list("name" = R.name, "type" = "[T]") data["recipies"] = recipies_ui - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "partslathe.tmpl", "Parts Lathe UI", 500, 450) ui.set_initial_data(data) diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm index 0482e2f242..e83da8222d 100644 --- a/code/game/machinery/pipe/construction.dm +++ b/code/game/machinery/pipe/construction.dm @@ -38,7 +38,7 @@ Buildable meters * @param loc Location * @pipe_type */ -/obj/item/pipe/initialize(var/mapload, var/_pipe_type, var/_dir, var/obj/machinery/atmospherics/make_from) +/obj/item/pipe/Initialize(var/mapload, var/_pipe_type, var/_dir, var/obj/machinery/atmospherics/make_from) if(make_from) make_from_existing(make_from) else @@ -115,15 +115,15 @@ Buildable meters var/obj/machinery/atmospherics/fakeA = pipe_type icon_state = "[initial(fakeA.pipe_state)][mirrored ? "m" : ""]" -/obj/item/pipe/verb/rotate() +/obj/item/pipe/verb/rotate_clockwise() set category = "Object" - set name = "Rotate Pipe" + set name = "Rotate Pipe Clockwise" set src in view(1) if ( usr.stat || usr.restrained() || !usr.canmove ) return - set_dir(turn(src.dir, -90)) // Rotate clockwise + src.set_dir(turn(src.dir, 270)) fixdir() // If you want to disable pipe dir changing when pulled, uncomment this diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index 07357ceb7b..086ab1e182 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -271,7 +271,7 @@ var/list/turret_icons settings[++settings.len] = list("category" = "Neutralize All Entities", "setting" = "check_all", "value" = check_all) data["settings"] = settings - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.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) @@ -406,16 +406,16 @@ var/list/turret_icons attacked = 0 ..() -/obj/machinery/porta_turret/attack_generic(mob/user as mob, var/damage) - if(isanimal(user)) - var/mob/living/simple_animal/S = user - if(damage >= 10) +/obj/machinery/porta_turret/attack_generic(mob/living/L, damage) + if(isanimal(L)) + var/mob/living/simple_mob/S = L + if(damage >= STRUCTURE_MIN_DAMAGE_THRESHOLD) var/incoming_damage = round(damage - (damage / 5)) //Turrets are slightly armored, assumedly. visible_message("\The [S] [pick(S.attacktext)] \the [src]!") take_damage(incoming_damage) S.do_attack_animation(src) return 1 - visible_message("\The [user] bonks \the [src]'s casing!") + visible_message("\The [L] bonks \the [src]'s casing!") return ..() /obj/machinery/porta_turret/emag_act(var/remaining_charges, var/mob/user) @@ -722,7 +722,10 @@ var/list/turret_icons def_zone = pick(BP_TORSO, BP_GROIN) //Shooting Code: - A.launch(target, def_zone) + A.firer = src + A.old_style_target(target) + A.def_zone = def_zone + A.fire() // Reset the time needed to go back down, since we just tried to shoot at someone. timeout = 10 diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm index 5c81cfe31f..42c2cda3f9 100644 --- a/code/game/machinery/requests_console.dm +++ b/code/game/machinery/requests_console.dm @@ -127,7 +127,7 @@ var/list/obj/machinery/requests_console/allConsoles = list() data["msgVerified"] = msgVerified data["announceAuth"] = announceAuth - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if(!ui) ui = new(user, src, ui_key, "request_console.tmpl", "[department] Request Console", 520, 410) ui.set_initial_data(data) diff --git a/code/game/machinery/status_display.dm b/code/game/machinery/status_display.dm index e3a00abb4d..da85faf14a 100644 --- a/code/game/machinery/status_display.dm +++ b/code/game/machinery/status_display.dm @@ -62,7 +62,7 @@ return // register for radio system -/obj/machinery/status_display/initialize() +/obj/machinery/status_display/Initialize() . = ..() if(radio_controller) radio_controller.add_object(src, frequency) diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 41130ad5b9..d94ac049b9 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -648,7 +648,7 @@ model_text = "Exploration" departments = list("Exploration","Old Exploration") -/obj/machinery/suit_cycler/exploreration/initialize() +/obj/machinery/suit_cycler/exploreration/Initialize() species -= SPECIES_TESHARI return ..() diff --git a/code/game/machinery/telecomms/telecomunications.dm b/code/game/machinery/telecomms/telecomunications.dm index ac85f8dba4..c1955399c2 100644 --- a/code/game/machinery/telecomms/telecomunications.dm +++ b/code/game/machinery/telecomms/telecomunications.dm @@ -122,7 +122,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list() var/turf/position = get_turf(src) listening_level = position.z -/obj/machinery/telecomms/initialize() +/obj/machinery/telecomms/Initialize() if(autolinkers.len) // Links nearby machines if(!long_range_link) @@ -317,7 +317,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list() netspeed = 40 var/list/telecomms_map -/obj/machinery/telecomms/hub/initialize() +/obj/machinery/telecomms/hub/Initialize() . = ..() LAZYINITLIST(telecomms_map) diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm index be31a5aa56..1d3556b45e 100644 --- a/code/game/machinery/teleporter.dm +++ b/code/game/machinery/teleporter.dm @@ -17,7 +17,7 @@ underlays += image('icons/obj/stationobjs.dmi', icon_state = "telecomp-wires") return -/obj/machinery/computer/teleporter/initialize() +/obj/machinery/computer/teleporter/Initialize() . = ..() var/obj/machinery/teleport/station/station var/obj/machinery/teleport/hub/hub @@ -69,7 +69,7 @@ for(var/obj/machinery/teleport/hub/H in range(1)) var/amount = rand(2,5) for(var/i=0;iYou insert \the [W] into \the [src].") - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) return else if(W.is_wrench()) playsound(src, W.usesound, 100, 1) @@ -403,7 +399,7 @@ else data["panel"] = 0 - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if(!ui) ui = new(user, src, ui_key, "vending_machine.tmpl", name, 440, 600) ui.set_initial_data(data) @@ -463,7 +459,7 @@ shut_up = !shut_up add_fingerprint(usr) - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) /obj/machinery/vending/proc/vend(datum/stored_item/vending_product/R, mob/user) if((!allowed(usr)) && !emagged && scan_id) //For SECURE VENDING MACHINES YEAH @@ -474,7 +470,7 @@ vend_ready = 0 //One thing at a time!! status_message = "Vending..." status_error = 0 - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) if(R.category & CAT_COIN) if(!coin) @@ -516,7 +512,7 @@ status_error = 0 vend_ready = 1 currently_vending = null - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) return 1 @@ -572,7 +568,7 @@ if(has_logs) do_logging(R, user) - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) /obj/machinery/vending/process() if(stat & (BROKEN|NOPOWER)) diff --git a/code/game/machinery/vr_console.dm b/code/game/machinery/vr_console.dm index 2b465e1265..34afd81577 100644 --- a/code/game/machinery/vr_console.dm +++ b/code/game/machinery/vr_console.dm @@ -1,227 +1,227 @@ -/obj/machinery/vr_sleeper - name = "virtual reality sleeper" - desc = "A fancy bed with built-in sensory I/O ports and connectors to interface users' minds with their bodies in virtual reality." - icon = 'icons/obj/Cryogenic2.dmi' - icon_state = "syndipod_0" - density = 1 - anchored = 1 - circuit = /obj/item/weapon/circuitboard/vr_sleeper - var/mob/living/carbon/human/occupant = null - var/mob/living/carbon/human/avatar = null - var/datum/mind/vr_mind = null - - use_power = 1 - idle_power_usage = 15 - active_power_usage = 200 - light_color = "#FF0000" - -/obj/machinery/vr_sleeper/New() - ..() - component_parts = list() - component_parts += new /obj/item/weapon/stock_parts/scanning_module(src) - component_parts += new /obj/item/stack/material/glass/reinforced(src, 2) - - RefreshParts() - -/obj/machinery/vr_sleeper/initialize() - . = ..() - update_icon() - -/obj/machinery/vr_sleeper/process() - if(stat & (NOPOWER|BROKEN)) - return - -/obj/machinery/vr_sleeper/update_icon() - icon_state = "syndipod_[occupant ? "1" : "0"]" - -/obj/machinery/vr_sleeper/Topic(href, href_list) - if(..()) - return 1 - - if(usr == occupant) - to_chat(usr, "You can't reach the controls from the inside.") - return - - add_fingerprint(usr) - - if(href_list["eject"]) - go_out() - - return 1 - -/obj/machinery/vr_sleeper/attackby(var/obj/item/I, var/mob/user) - add_fingerprint(user) - if(default_deconstruction_screwdriver(user, I)) - return - else if(default_deconstruction_crowbar(user, I)) - if(occupant && avatar) - avatar.exit_vr() - avatar = null - go_out() - return - - -/obj/machinery/vr_sleeper/MouseDrop_T(var/mob/target, var/mob/user) - if(user.stat || user.lying || !Adjacent(user) || !target.Adjacent(user)|| !isliving(target)) - return - go_in(target, user) - - - -/obj/machinery/sleeper/relaymove(var/mob/user) - ..() - if(usr.incapacitated()) - return - go_out() - - - -/obj/machinery/vr_sleeper/emp_act(var/severity) - if(stat & (BROKEN|NOPOWER)) - ..(severity) - return - - if(occupant) - // This will eject the user from VR - // ### Fry the brain? - go_out() - - ..(severity) - -/obj/machinery/vr_sleeper/verb/eject() - set src in oview(1) - set category = "Object" - set name = "Eject VR Capsule" - - if(usr.incapacitated()) - return - - if(usr != occupant && avatar && alert(avatar, "Someone wants to remove you from virtual reality. Do you want to leave?", "Leave VR?", "Yes", "No") == "No") - return - - // The player in VR is fine with leaving, kick them out and reset avatar - avatar.exit_vr() - avatar = null - go_out() - add_fingerprint(usr) - -/obj/machinery/vr_sleeper/verb/climb_in() - set src in oview(1) - set category = "Object" - set name = "Enter VR Capsule" - - if(usr.incapacitated()) - return - go_in(usr, usr) - add_fingerprint(usr) - -/obj/machinery/vr_sleeper/relaymove(mob/user as mob) - if(user.incapacitated()) - return 0 //maybe they should be able to get out with cuffs, but whatever - go_out() - -/obj/machinery/vr_sleeper/proc/go_in(var/mob/M, var/mob/user) - if(!M) - return - if(stat & (BROKEN|NOPOWER)) - return - if(!ishuman(M)) - user << "\The [src] rejects [M] with a sharp beep." - if(occupant) - user << "\The [src] is already occupied." - return - - if(M == user) - visible_message("\The [user] starts climbing into \the [src].") - else - visible_message("\The [user] starts putting [M] into \the [src].") - - if(do_after(user, 20)) - if(occupant) - to_chat(user, "\The [src] is already occupied.") - return - M.stop_pulling() - if(M.client) - M.client.perspective = EYE_PERSPECTIVE - M.client.eye = src - M.loc = src - update_use_power(2) - occupant = M - - update_icon() - - enter_vr() - return - -/obj/machinery/vr_sleeper/proc/go_out() - if(!occupant) - return - - if(occupant.client) - occupant.client.eye = occupant.client.mob - occupant.client.perspective = MOB_PERSPECTIVE - occupant.loc = src.loc - occupant = null - for(var/atom/movable/A in src) // In case an object was dropped inside or something - if(A == circuit) - continue - if(A in component_parts) - continue - A.loc = src.loc - update_use_power(1) - update_icon() - -/obj/machinery/vr_sleeper/proc/enter_vr() - - // No mob to transfer a mind from - if(!occupant) - return - - // No mind to transfer - if(!occupant.mind) - return - - // Mob doesn't have an active consciousness to send/receive from - if(occupant.stat != CONSCIOUS) - return - - avatar = occupant.vr_link - // If they've already enterred VR, and are reconnecting, prompt if they want a new body - if(avatar && alert(occupant, "You already have a Virtual Reality avatar. Would you like to use it?", "New avatar", "Yes", "No") == "No") - // Delink the mob - occupant.vr_link = null - avatar = null - - if(!avatar) - // Get the desired spawn location to put the body - var/S = null - var/list/vr_landmarks = list() - for(var/obj/effect/landmark/virtual_reality/sloc in landmarks_list) - vr_landmarks += sloc.name - - S = input(occupant, "Please select a location to spawn your avatar at:", "Spawn location") as null|anything in vr_landmarks - if(!S) - return 0 - - for(var/obj/effect/landmark/virtual_reality/i in landmarks_list) - if(i.name == S) - S = i - break - - avatar = new(S, "Virtual Reality Avatar") - // If the user has a non-default (Human) bodyshape, make it match theirs. - if(occupant.species.name != "Promethean" && occupant.species.name != "Human") - avatar.shapeshifter_change_shape(occupant.species.name) - avatar.forceMove(get_turf(S)) // Put the mob on the landmark, instead of inside it - avatar.Sleeping(1) - - occupant.enter_vr(avatar) - - // Prompt for username after they've enterred the body. - var/newname = sanitize(input(avatar, "You are entering virtual reality. Your username is currently [src.name]. Would you like to change it to something else?", "Name change") as null|text, MAX_NAME_LEN) - if (newname) - avatar.real_name = newname - - else - occupant.enter_vr(avatar) +/obj/machinery/vr_sleeper + name = "virtual reality sleeper" + desc = "A fancy bed with built-in sensory I/O ports and connectors to interface users' minds with their bodies in virtual reality." + icon = 'icons/obj/Cryogenic2.dmi' + icon_state = "syndipod_0" + density = 1 + anchored = 1 + circuit = /obj/item/weapon/circuitboard/vr_sleeper + var/mob/living/carbon/human/occupant = null + var/mob/living/carbon/human/avatar = null + var/datum/mind/vr_mind = null + + use_power = 1 + idle_power_usage = 15 + active_power_usage = 200 + light_color = "#FF0000" + +/obj/machinery/vr_sleeper/New() + ..() + component_parts = list() + component_parts += new /obj/item/weapon/stock_parts/scanning_module(src) + component_parts += new /obj/item/stack/material/glass/reinforced(src, 2) + + RefreshParts() + +/obj/machinery/vr_sleeper/Initialize() + . = ..() + update_icon() + +/obj/machinery/vr_sleeper/process() + if(stat & (NOPOWER|BROKEN)) + return + +/obj/machinery/vr_sleeper/update_icon() + icon_state = "syndipod_[occupant ? "1" : "0"]" + +/obj/machinery/vr_sleeper/Topic(href, href_list) + if(..()) + return 1 + + if(usr == occupant) + to_chat(usr, "You can't reach the controls from the inside.") + return + + add_fingerprint(usr) + + if(href_list["eject"]) + go_out() + + return 1 + +/obj/machinery/vr_sleeper/attackby(var/obj/item/I, var/mob/user) + add_fingerprint(user) + if(default_deconstruction_screwdriver(user, I)) + return + else if(default_deconstruction_crowbar(user, I)) + if(occupant && avatar) + avatar.exit_vr() + avatar = null + go_out() + return + + +/obj/machinery/vr_sleeper/MouseDrop_T(var/mob/target, var/mob/user) + if(user.stat || user.lying || !Adjacent(user) || !target.Adjacent(user)|| !isliving(target)) + return + go_in(target, user) + + + +/obj/machinery/sleeper/relaymove(var/mob/user) + ..() + if(usr.incapacitated()) + return + go_out() + + + +/obj/machinery/vr_sleeper/emp_act(var/severity) + if(stat & (BROKEN|NOPOWER)) + ..(severity) + return + + if(occupant) + // This will eject the user from VR + // ### Fry the brain? + go_out() + + ..(severity) + +/obj/machinery/vr_sleeper/verb/eject() + set src in oview(1) + set category = "Object" + set name = "Eject VR Capsule" + + if(usr.incapacitated()) + return + + if(usr != occupant && avatar && alert(avatar, "Someone wants to remove you from virtual reality. Do you want to leave?", "Leave VR?", "Yes", "No") == "No") + return + + // The player in VR is fine with leaving, kick them out and reset avatar + avatar.exit_vr() + avatar = null + go_out() + add_fingerprint(usr) + +/obj/machinery/vr_sleeper/verb/climb_in() + set src in oview(1) + set category = "Object" + set name = "Enter VR Capsule" + + if(usr.incapacitated()) + return + go_in(usr, usr) + add_fingerprint(usr) + +/obj/machinery/vr_sleeper/relaymove(mob/user as mob) + if(user.incapacitated()) + return 0 //maybe they should be able to get out with cuffs, but whatever + go_out() + +/obj/machinery/vr_sleeper/proc/go_in(var/mob/M, var/mob/user) + if(!M) + return + if(stat & (BROKEN|NOPOWER)) + return + if(!ishuman(M)) + user << "\The [src] rejects [M] with a sharp beep." + if(occupant) + user << "\The [src] is already occupied." + return + + if(M == user) + visible_message("\The [user] starts climbing into \the [src].") + else + visible_message("\The [user] starts putting [M] into \the [src].") + + if(do_after(user, 20)) + if(occupant) + to_chat(user, "\The [src] is already occupied.") + return + M.stop_pulling() + if(M.client) + M.client.perspective = EYE_PERSPECTIVE + M.client.eye = src + M.loc = src + update_use_power(2) + occupant = M + + update_icon() + + enter_vr() + return + +/obj/machinery/vr_sleeper/proc/go_out() + if(!occupant) + return + + if(occupant.client) + occupant.client.eye = occupant.client.mob + occupant.client.perspective = MOB_PERSPECTIVE + occupant.loc = src.loc + occupant = null + for(var/atom/movable/A in src) // In case an object was dropped inside or something + if(A == circuit) + continue + if(A in component_parts) + continue + A.loc = src.loc + update_use_power(1) + update_icon() + +/obj/machinery/vr_sleeper/proc/enter_vr() + + // No mob to transfer a mind from + if(!occupant) + return + + // No mind to transfer + if(!occupant.mind) + return + + // Mob doesn't have an active consciousness to send/receive from + if(occupant.stat != CONSCIOUS) + return + + avatar = occupant.vr_link + // If they've already enterred VR, and are reconnecting, prompt if they want a new body + if(avatar && alert(occupant, "You already have a Virtual Reality avatar. Would you like to use it?", "New avatar", "Yes", "No") == "No") + // Delink the mob + occupant.vr_link = null + avatar = null + + if(!avatar) + // Get the desired spawn location to put the body + var/S = null + var/list/vr_landmarks = list() + for(var/obj/effect/landmark/virtual_reality/sloc in landmarks_list) + vr_landmarks += sloc.name + + S = input(occupant, "Please select a location to spawn your avatar at:", "Spawn location") as null|anything in vr_landmarks + if(!S) + return 0 + + for(var/obj/effect/landmark/virtual_reality/i in landmarks_list) + if(i.name == S) + S = i + break + + avatar = new(S, "Virtual Reality Avatar") + // If the user has a non-default (Human) bodyshape, make it match theirs. + if(occupant.species.name != "Promethean" && occupant.species.name != "Human") + avatar.shapeshifter_change_shape(occupant.species.name) + avatar.forceMove(get_turf(S)) // Put the mob on the landmark, instead of inside it + avatar.Sleeping(1) + + occupant.enter_vr(avatar) + + // Prompt for username after they've enterred the body. + var/newname = sanitize(input(avatar, "You are entering virtual reality. Your username is currently [src.name]. Would you like to change it to something else?", "Name change") as null|text, MAX_NAME_LEN) + if (newname) + avatar.real_name = newname + + else + occupant.enter_vr(avatar) diff --git a/code/game/mecha/combat/gorilla.dm b/code/game/mecha/combat/gorilla.dm index 100bae9f19..f94c8bc78e 100644 --- a/code/game/mecha/combat/gorilla.dm +++ b/code/game/mecha/combat/gorilla.dm @@ -4,7 +4,7 @@ icon_state = "mecha_uac2" equip_cooldown = 60 // 6 seconds projectile = /obj/item/projectile/bullet/cannon - fire_sound = 'sound/weapons/cannon.ogg' + fire_sound = 'sound/weapons/Gunshot_cannon.ogg' projectiles = 1 projectile_energy_cost = 1000 salvageable = 0 // We don't want players ripping this off a dead mech. Could potentially be a prize for beating it if Devs bless me and someone offers a nerf idea. diff --git a/code/game/mecha/equipment/tools/medical_tools.dm b/code/game/mecha/equipment/tools/medical_tools.dm index 2fb2538cfb..f763304fc0 100644 --- a/code/game/mecha/equipment/tools/medical_tools.dm +++ b/code/game/mecha/equipment/tools/medical_tools.dm @@ -40,10 +40,9 @@ if(occupant) occupant_message("The sleeper is already occupied") return - for(var/mob/living/simple_animal/slime/M in range(1,target)) - if(M.victim == target) - occupant_message("[target] will not fit into the sleeper because they have a slime latched onto their head.") - return + if(target.has_buckled_mobs()) + occupant_message(span("warning", "\The [target] has other entities attached to it. Remove them first.")) + return occupant_message("You start putting [target] into [src].") chassis.visible_message("[chassis] starts putting [target] into the [src].") var/C = chassis.loc @@ -452,7 +451,7 @@ create_reagents(max_volume) synth = new (list(src),0) -/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/initialize() +/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/Initialize() . = ..() //Wow nice, firsties if(LAZYLEN(allowed_reagents) && !istext(allowed_reagents[1])) diff --git a/code/game/mecha/equipment/tools/tools.dm b/code/game/mecha/equipment/tools/tools.dm index 68e0c1380e..b621d97cba 100644 --- a/code/game/mecha/equipment/tools/tools.dm +++ b/code/game/mecha/equipment/tools/tools.dm @@ -177,12 +177,11 @@ var/spray_amount = 5 //units of liquid per particle. 5 is enough to wet the floor - it's a big fire extinguisher, so should be fine var/max_water = 1000 -/obj/item/mecha_parts/mecha_equipment/tool/extinguisher/New() +/obj/item/mecha_parts/mecha_equipment/tool/extinguisher/Initialize() + . = ..() reagents = new/datum/reagents(max_water) reagents.my_atom = src reagents.add_reagent("water", max_water) - ..() - return /obj/item/mecha_parts/mecha_equipment/tool/extinguisher/action(atom/target) //copypasted from extinguisher. TODO: Rewrite from scratch. if(!action_checks(target) || get_dist(chassis, target)>3) return @@ -247,7 +246,7 @@ equip_type = EQUIP_SPECIAL var/obj/item/weapon/rcd/electric/mounted/mecha/my_rcd = null -/obj/item/mecha_parts/mecha_equipment/tool/rcd/initialize() +/obj/item/mecha_parts/mecha_equipment/tool/rcd/Initialize() my_rcd = new(src) return ..() @@ -1203,9 +1202,10 @@ usr << "Kinda hard to climb in while handcuffed don't you think?" return - for(var/mob/living/simple_animal/slime/M in range(1,usr)) - if(M.victim == usr) - usr << "You're too busy getting your life sucked out of you." + if(isliving(usr)) + var/mob/living/L = usr + if(L.has_buckled_mobs()) + to_chat(L, span("warning", "You have other entities attached to yourself. Remove them first.")) return //search for a valid passenger compartment @@ -1329,4 +1329,4 @@ /obj/item/mecha_parts/mecha_equipment/tool/jetpack/do_after_cooldown() sleep(equip_cooldown) wait = 0 - return 1 \ No newline at end of file + return 1 diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm index a53c471eb3..2be7566822 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/game/mecha/equipment/weapons/weapons.dm @@ -19,7 +19,7 @@ return 0 return ..() -/obj/item/mecha_parts/mecha_equipment/weapon/action(atom/target) +/obj/item/mecha_parts/mecha_equipment/weapon/action(atom/target, params) if(!action_checks(target)) return var/turf/curloc = chassis.loc @@ -39,7 +39,7 @@ playsound(chassis, fire_sound, fire_volume, 1) projectiles-- var/P = new projectile(curloc) - Fire(P, target) + Fire(P, target, params) if(i == 1) set_ready_state(0) if(fire_cooldown) @@ -60,11 +60,12 @@ return -/obj/item/mecha_parts/mecha_equipment/weapon/proc/Fire(atom/A, atom/target) +/obj/item/mecha_parts/mecha_equipment/weapon/proc/Fire(atom/A, atom/target, params) var/obj/item/projectile/P = A P.dispersion = deviation process_accuracy(P, chassis.occupant, target) - P.launch(target) + P.preparePixelProjectile(target, chassis.occupant, params) + P.fire() /obj/item/mecha_parts/mecha_equipment/weapon/proc/process_accuracy(obj/projectile, mob/living/user, atom/target) var/obj/item/projectile/P = projectile @@ -296,7 +297,7 @@ description_info = "This weapon cannot be fired indoors, underground, or on-station." icon_state = "mecha_mortar" equip_cooldown = 30 - fire_sound = 'sound/weapons/cannon.ogg' + fire_sound = 'sound/weapons/Gunshot_cannon.ogg' fire_volume = 100 projectiles = 3 deviation = 0.6 @@ -319,7 +320,7 @@ icon_state = "mecha_scatter" equip_cooldown = 20 projectile = /obj/item/projectile/bullet/pellet/shotgun/flak - fire_sound = 'sound/weapons/gunshot/shotgun.ogg' + fire_sound = 'sound/weapons/Gunshot_shotgun.ogg' fire_volume = 80 projectiles = 40 projectiles_per_shot = 4 @@ -345,7 +346,7 @@ icon_state = "mecha_uac2" equip_cooldown = 10 projectile = /obj/item/projectile/bullet/pistol/medium - fire_sound = 'sound/weapons/machinegun.ogg' + fire_sound = 'sound/weapons/Gunshot_machinegun.ogg' projectiles = 30 //10 bursts, matching the Scattershot's 10. Also, conveniently, doesn't eat your powercell when reloading like 300 bullets does. projectiles_per_shot = 3 deviation = 0.3 @@ -523,7 +524,7 @@ icon_state = "mecha_drac3" equip_cooldown = 20 projectile = /obj/item/projectile/bullet/incendiary - fire_sound = 'sound/weapons/machinegun.ogg' + fire_sound = 'sound/weapons/Gunshot_machinegun.ogg' projectiles = 30 projectiles_per_shot = 2 deviation = 0.4 diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm index c289d79c69..e4818d0c79 100644 --- a/code/game/mecha/mech_fabricator.dm +++ b/code/game/mecha/mech_fabricator.dm @@ -38,7 +38,7 @@ files = new /datum/research(src) //Setup the research data holder. return -/obj/machinery/mecha_part_fabricator/initialize() +/obj/machinery/mecha_part_fabricator/Initialize() update_categories() . = ..() @@ -103,7 +103,7 @@ if(current) data["builtperc"] = round((progress / current.time) * 100) - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if(!ui) ui = new(user, src, ui_key, "mechfab.tmpl", "Exosuit Fabricator UI", 800, 600) ui.set_initial_data(data) diff --git a/code/game/mecha/mech_prosthetics.dm b/code/game/mecha/mech_prosthetics.dm index f6872478e0..e40db24878 100644 --- a/code/game/mecha/mech_prosthetics.dm +++ b/code/game/mecha/mech_prosthetics.dm @@ -39,7 +39,7 @@ files = new /datum/research(src) //Setup the research data holder. return -/obj/machinery/pros_fabricator/initialize() +/obj/machinery/pros_fabricator/Initialize() . = ..() manufacturer = basic_robolimb.company update_categories() @@ -113,7 +113,7 @@ if(current) data["builtperc"] = round((progress / current.time) * 100) - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if(!ui) ui = new(user, src, ui_key, "mechfab.tmpl", "Prosthetics Fab UI", 800, 600) ui.set_initial_data(data) diff --git a/code/game/mecha/mech_sensor.dm b/code/game/mecha/mech_sensor.dm index eee1ecefdb..3ac0361e48 100644 --- a/code/game/mecha/mech_sensor.dm +++ b/code/game/mecha/mech_sensor.dm @@ -69,7 +69,7 @@ else icon_state = "airlock_sensor_off" -/obj/machinery/mech_sensor/initialize() +/obj/machinery/mech_sensor/Initialize() . = ..() set_frequency(frequency) diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 82a0627fa7..9b17cb8613 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -317,7 +317,7 @@ // return ..() */ -/obj/mecha/proc/click_action(atom/target,mob/user) +/obj/mecha/proc/click_action(atom/target,mob/user, params) if(!src.occupant || src.occupant != user ) return if(user.stat) return if(state) @@ -339,7 +339,7 @@ if(selected && selected.is_ranged()) selected.action(target) else if(selected && selected.is_melee()) - selected.action(target) + selected.action(target, params) else src.melee_action(target) return @@ -1154,10 +1154,12 @@ to_chat(usr,"Access denied") src.log_append_to_last("Permission denied.") return - for(var/mob/living/simple_animal/slime/M in range(1,usr)) - if(M.victim == usr) - to_chat(usr,"You're too busy getting your life sucked out of you.") + if(isliving(usr)) + var/mob/living/L = usr + if(L.has_buckled_mobs()) + to_chat(L, span("warning", "You have other entities attached to yourself. Remove them first.")) return + // usr << "You start climbing into [src.name]" visible_message("\The [usr] starts to climb into [src.name]") diff --git a/code/game/mecha/mecha_wreckage.dm b/code/game/mecha/mecha_wreckage.dm index 73cee1223b..bc20f25b2e 100644 --- a/code/game/mecha/mecha_wreckage.dm +++ b/code/game/mecha/mecha_wreckage.dm @@ -99,6 +99,14 @@ name = "Dark Gygax wreckage" icon_state = "darkgygax-broken" +/obj/effect/decal/mecha_wreckage/gygax/adv + name = "Advanced Dark Gygax wreckage" + icon_state = "darkgygax_adv-broken" + +/obj/effect/decal/mecha_wreckage/gygax/medgax + name = "Medgax wreckage" + icon_state = "medgax-broken" + /obj/effect/decal/mecha_wreckage/marauder name = "Marauder wreckage" icon_state = "marauder-broken" @@ -198,6 +206,9 @@ parts -= part return +/obj/effect/decal/mecha_wreckage/odysseus/murdysseus + icon_state = "murdysseus-broken" + /obj/effect/decal/mecha_wreckage/hoverpod name = "Hover pod wreckage" icon_state = "engineering_pod-broken" diff --git a/code/game/mecha/medical/medical.dm b/code/game/mecha/medical/medical.dm index adb75800ea..90ab62681a 100644 --- a/code/game/mecha/medical/medical.dm +++ b/code/game/mecha/medical/medical.dm @@ -7,7 +7,7 @@ cargo_capacity = 1 -/obj/mecha/medical/initialize() +/obj/mecha/medical/Initialize() . = ..() var/turf/T = get_turf(src) if(isPlayerLevel(T.z)) diff --git a/code/game/mecha/medical/odysseus.dm b/code/game/mecha/medical/odysseus.dm index 8a1242d1a2..f7e886dd62 100644 --- a/code/game/mecha/medical/odysseus.dm +++ b/code/game/mecha/medical/odysseus.dm @@ -109,7 +109,7 @@ else if(foundVirus) holder.icon_state = "hudill" else if(patient.has_brain_worms()) - var/mob/living/simple_animal/borer/B = patient.has_brain_worms() + var/mob/living/simple_mob/animal/borer/B = patient.has_brain_worms() if(B.controlling) holder.icon_state = "hudbrainworm" else diff --git a/code/game/mecha/micro/micro_equipment.dm b/code/game/mecha/micro/micro_equipment.dm index 805148512d..9d2cfe40cd 100644 --- a/code/game/mecha/micro/micro_equipment.dm +++ b/code/game/mecha/micro/micro_equipment.dm @@ -49,7 +49,7 @@ equip_cooldown = 15 var/mode = 0 //0 - buckshot, 1 - beanbag, 2 - slug. projectile = /obj/item/projectile/bullet/pellet/shotgun - fire_sound = 'sound/weapons/shotgun.ogg' + fire_sound = 'sound/weapons/Gunshot_shotgun.ogg' fire_volume = 80 projectiles = 6 projectiles_per_shot = 1 diff --git a/code/game/mecha/working/working.dm b/code/game/mecha/working/working.dm index dbdf68ce5b..f2149b1cdd 100644 --- a/code/game/mecha/working/working.dm +++ b/code/game/mecha/working/working.dm @@ -6,7 +6,7 @@ max_universal_equip = 1 max_special_equip = 1 -/obj/mecha/working/initialize() +/obj/mecha/working/Initialize() . = ..() var/turf/T = get_turf(src) if(isPlayerLevel(T.z)) diff --git a/code/game/objects/banners.dm b/code/game/objects/banners.dm index 445df1dff5..5208336aa5 100644 --- a/code/game/objects/banners.dm +++ b/code/game/objects/banners.dm @@ -32,4 +32,4 @@ /obj/item/weapon/banner/virgov name = "\improper VirGov banner" icon_state = "banner-virgov" - desc = "A banner with the symbol of the local government, the Vir Governmental Authority, also known as SifGov." \ No newline at end of file + desc = "A banner with the symbol of the local government, the Vir Governmental Authority, also known as VirGov." \ No newline at end of file diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm index b191c69818..2ce02adb67 100644 --- a/code/game/objects/buckling.dm +++ b/code/game/objects/buckling.dm @@ -195,13 +195,3 @@ else L.set_dir(dir) return TRUE - -/atom/movable/Move(atom/newloc, direct = 0) - . = ..() - if(. && has_buckled_mobs() && !handle_buckled_mob_movement(newloc, direct)) //movement failed due to buckled mob(s) - . = 0 - //VOREStation Add - else if(. && riding_datum) - riding_datum.handle_vehicle_layer() - riding_datum.handle_vehicle_offsets() - //VOREStation Add End diff --git a/code/game/objects/effects/chem/chemsmoke.dm b/code/game/objects/effects/chem/chemsmoke.dm index 436ebabcc9..43b42cbac9 100644 --- a/code/game/objects/effects/chem/chemsmoke.dm +++ b/code/game/objects/effects/chem/chemsmoke.dm @@ -130,9 +130,9 @@ var/offset = 0 var/points = round((radius * 2 * M_PI) / arcLength) - var/angle = round(ToDegrees(arcLength / radius), 1) + var/angle = round(TODEGREES(arcLength / radius), 1) - if(!IsInteger(radius)) + if(!ISINTEGER(radius)) offset = 45 //degrees for(var/j = 0, j < points, j++) diff --git a/code/game/objects/effects/chem/foam.dm b/code/game/objects/effects/chem/foam.dm index 03f743db6b..4455f049ca 100644 --- a/code/game/objects/effects/chem/foam.dm +++ b/code/game/objects/effects/chem/foam.dm @@ -24,7 +24,7 @@ process() checkReagents() spawn(120) - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) sleep(30) if(metal) var/obj/structure/foamedmetal/M = new(src.loc) diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm index 69d875d977..3b1584ca19 100644 --- a/code/game/objects/effects/decals/Cleanable/humans.dm +++ b/code/game/objects/effects/decals/Cleanable/humans.dm @@ -33,11 +33,11 @@ var/global/list/image/splatter_cache=list() if(invisibility != 100) invisibility = 100 amount = 0 - processing_objects -= src + STOP_PROCESSING(SSobj, src) ..(ignore=1) /obj/effect/decal/cleanable/blood/Destroy() - processing_objects -= src + STOP_PROCESSING(SSobj, src) return ..() /obj/effect/decal/cleanable/blood/New() @@ -53,7 +53,7 @@ var/global/list/image/splatter_cache=list() blood_DNA |= B.blood_DNA.Copy() qdel(B) drytime = world.time + DRYING_TIME * (amount+1) - processing_objects += src + START_PROCESSING(SSobj, src) /obj/effect/decal/cleanable/blood/process() if(world.time > drytime) @@ -115,7 +115,7 @@ var/global/list/image/splatter_cache=list() desc = drydesc color = adjust_brightness(color, -50) amount = 0 - processing_objects -= src + STOP_PROCESSING(SSobj, src) /obj/effect/decal/cleanable/blood/attack_hand(mob/living/carbon/human/user) ..() @@ -250,4 +250,4 @@ var/global/list/image/splatter_cache=list() /obj/effect/decal/cleanable/mucus/mapped/New() ..() virus2 |= new /datum/disease2/disease - virus2.makerandom() + virus2[1].makerandom() diff --git a/code/game/objects/effects/decals/contraband.dm b/code/game/objects/effects/decals/contraband.dm index 0d7370d269..c98cacb785 100644 --- a/code/game/objects/effects/decals/contraband.dm +++ b/code/game/objects/effects/decals/contraband.dm @@ -109,7 +109,7 @@ pixel_x = -32 pixel_y = 0 -/obj/structure/sign/poster/initialize() +/obj/structure/sign/poster/Initialize() . = ..() if (poster_type) var/path = text2path(poster_type) diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm index e92268f4da..f21d6443fb 100644 --- a/code/game/objects/effects/effect_system.dm +++ b/code/game/objects/effects/effect_system.dm @@ -103,9 +103,9 @@ steam.start() -- spawns the effect if (istype(T, /turf)) T.hotspot_expose(1000,100) -/obj/effect/effect/sparks/initialize() +/obj/effect/effect/sparks/Initialize() . = ..() - schedule_task_in(5 SECONDS, /proc/qdel, list(src)) + QDEL_IN(src, 5 SECONDS) /obj/effect/effect/sparks/Destroy() var/turf/T = src.loc @@ -225,15 +225,16 @@ steam.start() -- spawns the effect /obj/effect/effect/smoke/bad/Move() ..() - for(var/mob/living/carbon/M in get_turf(src)) - affect(M) + for(var/mob/living/L in get_turf(src)) + affect(L) -/obj/effect/effect/smoke/bad/affect(var/mob/living/carbon/M) +/obj/effect/effect/smoke/bad/affect(var/mob/living/L) if (!..()) return 0 - M.adjustOxyLoss(1) - if(prob(25)) - M.emote("cough") + if(L.needs_to_breathe()) + L.adjustOxyLoss(1) + if(prob(25)) + L.emote("cough") /* Not feasile until a later date /obj/effect/effect/smoke/bad/Crossed(atom/movable/M as mob|obj) @@ -251,6 +252,72 @@ steam.start() -- spawns the effect projectiles -= proj */ +///////////////////////////////////////////// +// 'Elemental' smoke +///////////////////////////////////////////// + +/obj/effect/effect/smoke/elemental + name = "cloud" + desc = "A cloud of some kind that seems really generic and boring." + opacity = FALSE + var/strength = 5 // How much damage to do inside each affect() + +/obj/effect/effect/smoke/elemental/Initialize() + START_PROCESSING(SSobj, src) + return ..() + +/obj/effect/effect/smoke/elemental/Destroy() + STOP_PROCESSING(SSobj, src) + return ..() + +/obj/effect/effect/smoke/elemental/Move() + ..() + for(var/mob/living/L in range(1, src)) + affect(L) + +/obj/effect/effect/smoke/elemental/process() + for(var/mob/living/L in range(1, src)) + affect(L) + + +/obj/effect/effect/smoke/elemental/fire + name = "burning cloud" + desc = "A cloud of something that is on fire." + color = "#FF9933" + light_color = "#FF0000" + light_range = 2 + light_power = 5 + +/obj/effect/effect/smoke/elemental/fire/affect(mob/living/L) + L.inflict_heat_damage(strength) + L.add_modifier(/datum/modifier/fire, 6 SECONDS) // Around 15 damage per stack. + +/obj/effect/effect/smoke/elemental/frost + name = "freezing cloud" + desc = "A cloud filled with brutally cold mist." + color = "#00CCFF" + +/obj/effect/effect/smoke/elemental/frost/affect(mob/living/L) + L.inflict_cold_damage(strength) + +/obj/effect/effect/smoke/elemental/shock + name = "charged cloud" + desc = "A cloud charged with electricity." + color = "#4D4D4D" + +/obj/effect/effect/smoke/elemental/shock/affect(mob/living/L) + L.inflict_shock_damage(strength) + +/obj/effect/effect/smoke/elemental/mist + name = "misty cloud" + desc = "A cloud filled with water vapor." + color = "#CCFFFF" + alpha = 128 + strength = 1 + +/obj/effect/effect/smoke/elemental/mist/affect(mob/living/L) + L.water_act(strength) + ///////////////////////////////////////////// // Smoke spread ///////////////////////////////////////////// @@ -282,7 +349,8 @@ steam.start() -- spawns the effect src.location = get_turf(holder) var/obj/effect/effect/smoke/smoke = new smoke_type(src.location) src.total_smoke++ - smoke.color = I + if(I) + smoke.color = I var/direction = src.direction if(!direction) if(src.cardinals) @@ -296,10 +364,21 @@ steam.start() -- spawns the effect if (smoke) qdel(smoke) src.total_smoke-- - /datum/effect/effect/system/smoke_spread/bad smoke_type = /obj/effect/effect/smoke/bad +/datum/effect/effect/system/smoke_spread/fire + smoke_type = /obj/effect/effect/smoke/elemental/fire + +/datum/effect/effect/system/smoke_spread/frost + smoke_type = /obj/effect/effect/smoke/elemental/frost + +/datum/effect/effect/system/smoke_spread/shock + smoke_type = /obj/effect/effect/smoke/elemental/shock + +/datum/effect/effect/system/smoke_spread/mist + smoke_type = /obj/effect/effect/smoke/elemental/mist + ///////////////////////////////////////////// //////// Attach an Ion trail to any object, that spawns when it moves (like for the jetpack) /// just pass in the object to attach it to in set_up diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm index 50230eba17..193d24d4ab 100644 --- a/code/game/objects/effects/landmarks.dm +++ b/code/game/objects/effects/landmarks.dm @@ -83,7 +83,7 @@ /obj/effect/landmark/proc/delete() delete_me = 1 -/obj/effect/landmark/initialize() +/obj/effect/landmark/Initialize() . = ..() if(delete_me) return INITIALIZE_HINT_QDEL diff --git a/code/game/objects/effects/map_effects/beam_point.dm b/code/game/objects/effects/map_effects/beam_point.dm new file mode 100644 index 0000000000..524686874c --- /dev/null +++ b/code/game/objects/effects/map_effects/beam_point.dm @@ -0,0 +1,192 @@ +GLOBAL_LIST_EMPTY(all_beam_points) + +// Creates and manages a beam attached to itself and another beam_point. +// You can do cool things with these such as moving the beam_point to move the beam, turning them on and off on a timer, triggered by external input, and more. +/obj/effect/map_effect/beam_point + name = "beam point" + icon_state = "beam_point" + + // General variables. + var/list/my_beams = list() // Instances of beams. Deleting one will kill the beam. + var/id = "A" // Two beam_points must share the same ID to be connected to each other. + var/max_beams = 10 // How many concurrent beams to seperate beam_points to have at once. Set to zero to only act as targets for other beam_points. + var/seek_range = 7 // How far to look for an end beam_point when not having a beam. Defaults to screen height/width. Make sure this is below beam_max_distance. + + // Controls how and when the beam is created. + var/make_beams_on_init = FALSE + var/use_timer = FALSE // Sadly not the /tg/ timers. + var/list/on_duration = list(2 SECONDS, 2 SECONDS, 2 SECONDS) // How long the beam should stay on for, if use_timer is true. Alternates between each duration in the list. + var/list/off_duration = list(3 SECONDS, 0.5 SECOND, 0.5 SECOND) // How long it should stay off for. List length is not needed to be the same as on_duration. + var/timer_on_index = 1 // Index to use for on_duration list. + var/timer_off_index = 1// Ditto, for off_duration list. + var/initial_delay = 0 // How long to wait before first turning on the beam, to sync beam times or create a specific pattern. + var/beam_creation_sound = null // Optional sound played when one or more beams are created. + var/beam_destruction_sound = null // Optional sound played when a beam is destroyed. + + // Beam datum arguments. + var/beam_icon = 'icons/effects/beam.dmi' // Icon file to use for beam visuals. + var/beam_icon_state = "b_beam" // Icon state to use for visuals. + var/beam_time = INFINITY // How long the beam lasts. By default it will last forever until destroyed. + var/beam_max_distance = 10 // If the beam is farther than this, it will be destroyed. Make sure it's higher than seek_range. + var/beam_type = /obj/effect/ebeam // The type of beam. Default has no special properties. Some others may do things like hurt things touching it. + var/beam_sleep_time = 3 // How often the beam updates visually. Suggested to leave this alone, 3 is already fast. + +/obj/effect/map_effect/beam_point/Initialize() + GLOB.all_beam_points += src + if(make_beams_on_init) + create_beams() + if(use_timer) + spawn(initial_delay) + handle_beam_timer() + return ..() + +/obj/effect/map_effect/beam_point/Destroy() + destroy_all_beams() + use_timer = FALSE + GLOB.all_beam_points -= src + return ..() + +// This is the top level proc to make the magic happen. +/obj/effect/map_effect/beam_point/proc/create_beams() + if(my_beams.len >= max_beams) + return + var/beams_to_fill = max_beams - my_beams.len + for(var/i = 1 to beams_to_fill) + var/obj/effect/map_effect/beam_point/point = seek_beam_point() + if(!point) + break // No more points could be found, no point checking repeatively. + build_beam(point) + +// Finds a suitable beam point. +/obj/effect/map_effect/beam_point/proc/seek_beam_point() + for(var/obj/effect/map_effect/beam_point/point in GLOB.all_beam_points) + if(id != point.id) + continue // Not linked together by ID. + if(has_active_beam(point)) + continue // Already got one. + if(point.z != src.z) + continue // Not on same z-level. get_dist() ignores z-levels by design according to docs. + if(get_dist(src, point) > seek_range) + continue // Too far. + return point + +// Checks if the two points have an active beam between them. +// Used to make sure two points don't have more than one beam. +/obj/effect/map_effect/beam_point/proc/has_active_beam(var/obj/effect/map_effect/beam_point/them) + // First, check our beams. + for(var/datum/beam/B in my_beams) + if(B.target == them) + return TRUE + if(B.origin == them) // This shouldn't be needed unless the beam gets built backwards but why not. + return TRUE + + // Now check theirs, to see if they have a beam on us. + for(var/datum/beam/B in them.my_beams) + if(B.target == src) + return TRUE + if(B.origin == src) // Same story as above. + return TRUE + + return FALSE + +/obj/effect/map_effect/beam_point/proc/build_beam(var/atom/beam_target) + if(!beam_target) + log_debug("[src] ([src.type] \[[x],[y],[z]\]) failed to build its beam due to not having a target.") + return FALSE + + var/datum/beam/new_beam = Beam(beam_target, beam_icon_state, beam_icon, beam_time, beam_max_distance, beam_type, beam_sleep_time) + my_beams += new_beam + if(beam_creation_sound) + playsound(src, beam_creation_sound, 70, 1) + + return TRUE + +/obj/effect/map_effect/beam_point/proc/destroy_beam(var/datum/beam/B) + if(!B) + log_debug("[src] ([src.type] \[[x],[y],[z]\]) was asked to destroy a beam that does not exist.") + return FALSE + + if(!(B in my_beams)) + log_debug("[src] ([src.type] \[[x],[y],[z]\]) was asked to destroy a beam it did not own.") + return FALSE + + my_beams -= B + qdel(B) + if(beam_destruction_sound) + playsound(src, beam_destruction_sound, 70, 1) + + return TRUE + +/obj/effect/map_effect/beam_point/proc/destroy_all_beams() + for(var/datum/beam/B in my_beams) + destroy_beam(B) + return TRUE + +// This code makes me sad. +/obj/effect/map_effect/beam_point/proc/handle_beam_timer() + if(!use_timer || QDELETED(src)) + return + + if(my_beams.len) // Currently on. + destroy_all_beams() + color = "#FF0000" + + timer_off_index++ + if(timer_off_index > off_duration.len) + timer_off_index = 1 + + spawn(off_duration[timer_off_index]) + .() + + else // Currently off. + // If nobody's around, keep the beams off to avoid wasteful beam process(), if they have one. + if(!always_run && !check_for_player_proximity(src, proximity_needed, ignore_ghosts, ignore_afk)) + spawn(retry_delay) + .() + return + + create_beams() + color = "#00FF00" + + timer_on_index++ + if(timer_on_index > on_duration.len) + timer_on_index = 1 + + spawn(on_duration[timer_on_index]) + .() + + + +// Subtypes to use in maps and adminbuse. +// Remember, beam_points ONLY connect to other beam_points with the same id variable. + +// Creates the beam when instantiated and stays on until told otherwise. +/obj/effect/map_effect/beam_point/instant + make_beams_on_init = TRUE + +/obj/effect/map_effect/beam_point/instant/electric + beam_icon_state = "nzcrentrs_power" + beam_type = /obj/effect/ebeam/reactive/electric + beam_creation_sound = 'sound/effects/lightningshock.ogg' + beam_destruction_sound = "sparks" + +// Turns on and off on a timer. +/obj/effect/map_effect/beam_point/timer + use_timer = TRUE + +// Shocks people who touch the beam while it's on. Flicks on and off on a specific pattern. +/obj/effect/map_effect/beam_point/timer/electric + beam_icon_state = "nzcrentrs_power" + beam_type = /obj/effect/ebeam/reactive/electric + beam_creation_sound = 'sound/effects/lightningshock.ogg' + beam_destruction_sound = "sparks" + seek_range = 3 + +// Is only a target for other beams to connect to. +/obj/effect/map_effect/beam_point/end + max_beams = 0 + +// Can only have one beam. +/obj/effect/map_effect/beam_point/mono + make_beams_on_init = TRUE + max_beams = 1 diff --git a/code/game/objects/effects/map_effects/effect_emitter.dm b/code/game/objects/effects/map_effects/effect_emitter.dm new file mode 100644 index 0000000000..d7086dafa6 --- /dev/null +++ b/code/game/objects/effects/map_effects/effect_emitter.dm @@ -0,0 +1,78 @@ +// Creates effects like smoke clouds every so often. +/obj/effect/map_effect/interval/effect_emitter + var/datum/effect/effect/system/effect_system = null + var/effect_system_type = null // Which effect system to attach. + + var/effect_amount = 10 // How many effect objects to create on each interval. Note that there's a hard cap on certain effect_systems. + var/effect_cardinals_only = FALSE // If true, effects only move in cardinal directions. + var/effect_forced_dir = null // If set, effects emitted will always move in this direction. + +/obj/effect/map_effect/interval/effect_emitter/Initialize() + effect_system = new effect_system_type() + effect_system.attach(src) + configure_effects() + return ..() + +/obj/effect/map_effect/interval/effect_emitter/interval/Destroy() + QDEL_NULL(effect_system) + return ..() + +/obj/effect/map_effect/interval/effect_emitter/proc/configure_effects() + effect_system.set_up(effect_amount, effect_cardinals_only, src.loc, effect_forced_dir) + +/obj/effect/map_effect/interval/effect_emitter/trigger() + configure_effects() // We do this every interval in case it changes. + effect_system.start() + ..() + + +// Creates smoke clouds every so often. +/obj/effect/map_effect/interval/effect_emitter/smoke + name = "smoke emitter" + icon_state = "smoke_emitter" + effect_system_type = /datum/effect/effect/system/smoke_spread + + interval_lower_bound = 1 SECOND + interval_upper_bound = 1 SECOND + effect_amount = 2 + +/obj/effect/map_effect/interval/effect_emitter/smoke/bad + name = "bad smoke emitter" + effect_system_type = /datum/effect/effect/system/smoke_spread/bad + +/obj/effect/map_effect/interval/effect_emitter/smoke/fire + name = "fire smoke emitter" + effect_system_type = /datum/effect/effect/system/smoke_spread/fire + +/obj/effect/map_effect/interval/effect_emitter/smoke/frost + name = "frost smoke emitter" + effect_system_type = /datum/effect/effect/system/smoke_spread/frost + +/obj/effect/map_effect/interval/effect_emitter/smoke/shock + name = "shock smoke emitter" + effect_system_type = /datum/effect/effect/system/smoke_spread/shock + +/obj/effect/map_effect/interval/effect_emitter/smoke/mist + name = "mist smoke emitter" + effect_system_type = /datum/effect/effect/system/smoke_spread/mist + + +// Makes sparks. +/obj/effect/map_effect/interval/effect_emitter/sparks + name = "spark emitter" + icon_state = "spark_emitter" + effect_system_type = /datum/effect/effect/system/spark_spread + + interval_lower_bound = 3 SECONDS + interval_upper_bound = 7 SECONDS + +/obj/effect/map_effect/interval/effect_emitter/sparks/frequent + effect_amount = 4 // Otherwise it caps out fast. + interval_lower_bound = 1 + interval_upper_bound = 3 SECONDS + +// Makes ""steam"" that looks like fire extinguisher water except it does nothing. +/obj/effect/map_effect/interval/effect_emitter/steam + name = "steam emitter" + icon_state = "smoke_emitter" + effect_system_type = /datum/effect/effect/system/steam_spread diff --git a/code/game/objects/effects/map_effects/map_effects.dm b/code/game/objects/effects/map_effects/map_effects.dm new file mode 100644 index 0000000000..9e2986072d --- /dev/null +++ b/code/game/objects/effects/map_effects/map_effects.dm @@ -0,0 +1,72 @@ +// These are objects you can use inside special maps (like PoIs), or for adminbuse. +// Players cannot see or interact with these. +/obj/effect/map_effect + anchored = TRUE + invisibility = 99 // So a badmin can go view these by changing their see_invisible. + icon = 'icons/effects/map_effects.dmi' + + // Below vars concern check_for_player_proximity() and is used to not waste effort if nobody is around to appreciate the effects. + var/always_run = FALSE // If true, the game will not try to suppress this from firing if nobody is around to see it. + var/proximity_needed = 12 // How many tiles a mob with a client must be for this to run. + var/ignore_ghosts = FALSE // If true, ghosts won't satisfy the above requirement. + var/ignore_afk = TRUE // If true, AFK people (5 minutes) won't satisfy it as well. + var/retry_delay = 3 SECONDS // How long until we check for players again. + +/obj/effect/map_effect/ex_act() + return + +/obj/effect/map_effect/singularity_pull() + return + +/obj/effect/map_effect/singularity_act() + return + +// Base type for effects that run on variable intervals. +/obj/effect/map_effect/interval + var/interval_lower_bound = 5 SECONDS // Lower number for how often the map_effect will trigger. + var/interval_upper_bound = 5 SECONDS // Higher number for above. + var/halt = FALSE // Set to true to stop the loop when it reaches the next iteration. + +/obj/effect/map_effect/interval/Initialize() + handle_interval_delay() + return ..() + +/obj/effect/map_effect/interval/Destroy() + halt = TRUE // Shouldn't need it to GC but just in case. + return ..() + +// Override this for the specific thing to do. Be sure to call parent to keep looping. +/obj/effect/map_effect/interval/proc/trigger() + handle_interval_delay() + +// Handles the delay and making sure it doesn't run when it would be bad. +/obj/effect/map_effect/interval/proc/handle_interval_delay() + // Check to see if we're useful first. + if(halt) + return // Do not pass .(), do not recursively collect 200 thaler. + + if(!always_run && !check_for_player_proximity(src, proximity_needed, ignore_ghosts, ignore_afk)) + spawn(retry_delay) // Maybe someday we'll have fancy TG timers/schedulers. + if(!QDELETED(src)) + .() + return + + var/next_interval = rand(interval_lower_bound, interval_upper_bound) + spawn(next_interval) + if(!QDELETED(src)) + trigger() + +// Helper proc to optimize the use of effects by making sure they do not run if nobody is around to perceive it. +/proc/check_for_player_proximity(var/atom/proximity_to, var/radius = 12, var/ignore_ghosts = FALSE, var/ignore_afk = TRUE) + if(!proximity_to) + return FALSE + + for(var/thing in player_list) + var/mob/M = thing // Avoiding typechecks for more speed, player_list will only contain mobs anyways. + if(ignore_ghosts && isobserver(M)) + continue + if(ignore_afk && M.client && M.client.is_afk(5 MINUTES)) + continue + if(M.z == proximity_to.z && get_dist(M, proximity_to) <= radius) + return TRUE + return FALSE \ No newline at end of file diff --git a/code/game/objects/effects/map_effects/perma_light.dm b/code/game/objects/effects/map_effects/perma_light.dm new file mode 100644 index 0000000000..3a82dc7e69 --- /dev/null +++ b/code/game/objects/effects/map_effects/perma_light.dm @@ -0,0 +1,9 @@ +// Emits light forever with magic. Useful for mood lighting in Points of Interest. +// Be sure to check how it looks ingame, and fiddle with the settings until it looks right. +/obj/effect/map_effect/perma_light + name = "permanent light" + icon_state = "permalight" + + light_range = 3 + light_power = 1 + light_color = "#FFFFFF" \ No newline at end of file diff --git a/code/game/objects/effects/map_effects/radiation_emitter.dm b/code/game/objects/effects/map_effects/radiation_emitter.dm new file mode 100644 index 0000000000..3fb31d3c5d --- /dev/null +++ b/code/game/objects/effects/map_effects/radiation_emitter.dm @@ -0,0 +1,19 @@ +// Constantly emites radiation from the tile it's placed on. +/obj/effect/map_effect/radiation_emitter + name = "radiation emitter" + icon_state = "radiation_emitter" + var/radiation_power = 30 // Bigger numbers means more radiation. + +/obj/effect/map_effect/radiation_emitter/Initialize() + START_PROCESSING(SSobj, src) + return ..() + +/obj/effect/map_effect/radiation_emitter/Destroy() + STOP_PROCESSING(SSobj, src) + return ..() + +/obj/effect/map_effect/radiation_emitter/process() + radiation_repository.radiate(src, radiation_power) + +/obj/effect/map_effect/radiation_emitter/strong + radiation_power = 100 \ No newline at end of file diff --git a/code/game/objects/effects/map_effects/screen_shaker.dm b/code/game/objects/effects/map_effects/screen_shaker.dm new file mode 100644 index 0000000000..29568242e5 --- /dev/null +++ b/code/game/objects/effects/map_effects/screen_shaker.dm @@ -0,0 +1,18 @@ +// Makes the screen shake for nearby players every so often. +/obj/effect/map_effect/interval/screen_shaker + name = "screen shaker" + icon_state = "screen_shaker" + + interval_lower_bound = 1 SECOND + interval_upper_bound = 2 SECONDS + + var/shake_radius = 7 // How far the shaking effect extends to. By default it is one screen length. + var/shake_duration = 2 // How long the shaking lasts. + var/shake_strength = 1 // How much it shakes. + +/obj/effect/map_effect/interval/screen_shaker/trigger() + for(var/A in player_list) + var/mob/M = A + if(M.z == src.z && get_dist(src, M) <= shake_radius) + shake_camera(M, shake_duration, shake_strength) + ..() \ No newline at end of file diff --git a/code/game/objects/effects/map_effects/sound_emitter.dm b/code/game/objects/effects/map_effects/sound_emitter.dm new file mode 100644 index 0000000000..6d07cc7b7b --- /dev/null +++ b/code/game/objects/effects/map_effects/sound_emitter.dm @@ -0,0 +1,119 @@ +// Plays a sound at its location every so often. +/obj/effect/map_effect/interval/sound_emitter + name = "sound emitter" + icon_state = "sound_emitter" + var/list/sounds_to_play = list(null) // List containing sound files or strings of sound groups. + // A sound or string is picked randomly each run. + + var/sound_volume = 50 // How loud the sound is. 0 is silent, and 100 is loudest. Please be reasonable with the volume. + // Note that things like vacuum may affect the volume heard by other mobs. + + var/sound_frequency_variance = TRUE // If the sound will sound somewhat different each time. + // If a specific frequency is desired, sound_frequency must also be set. + + var/sound_extra_range = 0 // Set to make sounds heard from farther away than normal. + + var/sound_fallout = 0 // Within the 'fallout distance', the sound stays at the same volume, otherwise it attenuates. + // Higher numbers make the sound fade out more slowly with distance. + + var/sound_global = FALSE // If true, sounds will not be distorted due to the current area's 'sound environment'. + // It DOES NOT make the sound have a constant volume or z-level wide range, despite the misleading name. + + var/sound_frequency = null // Sets a specific custom frequency. sound_frequency_variance must be true as well. + // If sound_frequency is null, but sound_frequency_variance is true, a semi-random frequency will be chosen to the sound each time. + + var/sound_channel = 0 // BYOND allows a sound to play in 1 through 1024 sound channels. + // 0 will have BYOND give it the lowest available channel, it is not recommended to change this without a good reason. + + var/sound_pressure_affected = TRUE // If false, people in low pressure or vacuum will hear the sound. + + var/sound_ignore_walls = TRUE // If false, walls will completely muffle the sound. + + var/sound_preference = null // Player preference to check before playing this sound to them, if any. + +/obj/effect/map_effect/interval/sound_emitter/trigger() + playsound( + src, + pick(sounds_to_play), + sound_volume, + sound_frequency_variance, + sound_extra_range, + sound_fallout, + sound_global, + sound_frequency, + sound_channel, + sound_pressure_affected, + sound_ignore_walls, + sound_preference + ) + ..() + +/obj/effect/map_effect/interval/sound_emitter/thunder + sounds_to_play = list("thunder") + interval_lower_bound = 10 SECONDS + interval_upper_bound = 15 SECONDS + +/obj/effect/map_effect/interval/sound_emitter/geiger + sounds_to_play = list('sound/items/geiger/low1.ogg', 'sound/items/geiger/low2.ogg', 'sound/items/geiger/low3.ogg', 'sound/items/geiger/low4.ogg') + interval_lower_bound = 1 SECOND + interval_upper_bound = 1 SECOND + +/obj/effect/map_effect/interval/sound_emitter/geiger/med + sounds_to_play = list('sound/items/geiger/med1.ogg', 'sound/items/geiger/med2.ogg', 'sound/items/geiger/med3.ogg', 'sound/items/geiger/med4.ogg') + +/obj/effect/map_effect/interval/sound_emitter/geiger/high + sounds_to_play = list('sound/items/geiger/high1.ogg', 'sound/items/geiger/high2.ogg', 'sound/items/geiger/high3.ogg', 'sound/items/geiger/high4.ogg') + +/obj/effect/map_effect/interval/sound_emitter/geiger/ext + sounds_to_play = list('sound/items/geiger/ext1.ogg', 'sound/items/geiger/ext2.ogg', 'sound/items/geiger/ext3.ogg', 'sound/items/geiger/ext4.ogg') + +/obj/effect/map_effect/interval/sound_emitter/punching + sounds_to_play = list("punch") + interval_lower_bound = 5 + interval_upper_bound = 1 SECOND + +/obj/effect/map_effect/interval/sound_emitter/explosions + sounds_to_play = list("explosion") + interval_lower_bound = 5 SECONDS + interval_upper_bound = 10 SECONDS + +/obj/effect/map_effect/interval/sound_emitter/explosions/distant + sounds_to_play = list('sound/effects/explosionfar.ogg') + +/obj/effect/map_effect/interval/sound_emitter/ballistic_gunfight + sounds_to_play = list( + 'sound/weapons/Gunshot1.ogg', + 'sound/weapons/Gunshot_deagle.ogg', + 'sound/weapons/Gunshot_generic_rifle.ogg', + 'sound/weapons/Gunshot_sniper.ogg', + 'sound/weapons/Gunshot_shotgun.ogg', + 'sound/weapons/Gunshot3.ogg', + 'sound/weapons/Gunshot_machinegun.ogg' + ) + interval_lower_bound = 5 + interval_upper_bound = 2 SECONDS + +/obj/effect/map_effect/interval/sound_emitter/energy_gunfight + sounds_to_play = list( + 'sound/weapons/Taser.ogg', + 'sound/weapons/laser.ogg', + 'sound/weapons/eLuger.ogg', + 'sound/weapons/laser3.ogg', + 'sound/weapons/pulse.ogg', + 'sound/weapons/gauss_shoot.ogg', + 'sound/weapons/emitter.ogg' + ) + interval_lower_bound = 5 + interval_upper_bound = 2 SECONDS + + +// I'm not sorry. +/obj/effect/map_effect/interval/sound_emitter/clownsteps + sounds_to_play = list("clownstep") + interval_lower_bound = 5 + interval_upper_bound = 1 SECOND + +/obj/effect/map_effect/interval/sound_emitter/bikehorns + sounds_to_play = list('sound/items/bikehorn.ogg') + interval_lower_bound = 5 + interval_upper_bound = 1 SECOND diff --git a/code/game/objects/effects/mines.dm b/code/game/objects/effects/mines.dm index 9ea690318b..87af3ec90b 100644 --- a/code/game/objects/effects/mines.dm +++ b/code/game/objects/effects/mines.dm @@ -10,6 +10,7 @@ var/mineitemtype = /obj/item/weapon/mine var/panel_open = 0 var/datum/wires/mines/wires = null + register_as_dangerous_object = TRUE /obj/effect/mine/New() icon_state = "uglyminearmed" @@ -271,4 +272,10 @@ /obj/item/weapon/mine/incendiary name = "incendiary mine" desc = "A small explosive mine with a fire symbol on the side." - minetype = /obj/effect/mine/incendiary \ No newline at end of file + minetype = /obj/effect/mine/incendiary + +// This tells AI mobs to not be dumb and step on mines willingly. +/obj/item/weapon/mine/is_safe_to_step(mob/living/L) + if(!L.hovering) + return FALSE + return ..() \ No newline at end of file diff --git a/code/game/objects/effects/misc.dm b/code/game/objects/effects/misc.dm index d7db6f2a0c..5fca6fbecf 100644 --- a/code/game/objects/effects/misc.dm +++ b/code/game/objects/effects/misc.dm @@ -34,7 +34,7 @@ pixel_x = -32 pixel_y = -32 -/obj/effect/temporary_effect/cleave_attack/initialize() // Makes the slash fade smoothly. When completely transparent it should qdel itself. +/obj/effect/temporary_effect/cleave_attack/Initialize() // Makes the slash fade smoothly. When completely transparent it should qdel itself. . = ..() animate(src, alpha = 0, time = time_to_die - 1) @@ -44,7 +44,7 @@ icon_state = "shuttle_warning_still" time_to_die = 4.9 SECONDS -/obj/effect/temporary_effect/shuttle_landing/initialize() +/obj/effect/temporary_effect/shuttle_landing/Initialize() flick("shuttle_warning", src) // flick() forces the animation to always begin at the start. . = ..() @@ -60,7 +60,7 @@ time_to_die = 1 SECOND pixel_x = -32 -/obj/effect/temporary_effect/lightning_strike/initialize() +/obj/effect/temporary_effect/lightning_strike/Initialize() icon_state += "[rand(1,2)]" // To have two variants of lightning sprites. animate(src, alpha = 0, time = time_to_die - 1) . = ..() \ No newline at end of file diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm index 7504b6e65f..056d9f7295 100644 --- a/code/game/objects/effects/overlays.dm +++ b/code/game/objects/effects/overlays.dm @@ -99,3 +99,13 @@ mouse_opacity = FALSE anchored = TRUE plane = ABOVE_PLANE + +// Similar to the tesla ball but doesn't actually do anything and is purely visual. +/obj/effect/overlay/energy_ball + name = "energy ball" + desc = "An energy ball." + icon = 'icons/obj/tesla_engine/energy_ball.dmi' + icon_state = "energy_ball" + plane = PLANE_LIGHTING_ABOVE + pixel_x = -32 + pixel_y = -32 diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm index 8e482cc1cb..e0581b50f2 100644 --- a/code/game/objects/effects/spiders.dm +++ b/code/game/objects/effects/spiders.dm @@ -24,9 +24,9 @@ user.setClickCooldown(user.get_attack_speed(W)) if(W.attack_verb.len) - visible_message("\The [src] have been [pick(W.attack_verb)] with \the [W][(user ? " by [user]." : ".")]") + visible_message("\The [src] has been [pick(W.attack_verb)] with \the [W][(user ? " by [user]." : ".")]") else - visible_message("\The [src] have been attacked with \the [W][(user ? " by [user]." : ".")]") + visible_message("\The [src] has been attacked with \the [W][(user ? " by [user]." : ".")]") var/damage = W.force / 4.0 @@ -56,13 +56,15 @@ /obj/effect/spider/stickyweb icon_state = "stickyweb1" - New() - if(prob(50)) - icon_state = "stickyweb2" + +/obj/effect/spider/stickyweb/Initialize() + if(prob(50)) + icon_state = "stickyweb2" + return ..() /obj/effect/spider/stickyweb/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) if(air_group || (height==0)) return 1 - if(istype(mover, /mob/living/simple_animal/hostile/giant_spider)) + if(istype(mover, /mob/living/simple_mob/animal/giant_spider)) return 1 else if(istype(mover, /mob/living)) if(prob(50)) @@ -80,17 +82,19 @@ var/spiders_min = 6 var/spiders_max = 24 var/spider_type = /obj/effect/spider/spiderling - New() - pixel_x = rand(3,-3) - pixel_y = rand(3,-3) - processing_objects |= src + +/obj/effect/spider/eggcluster/Initialize() + pixel_x = rand(3,-3) + pixel_y = rand(3,-3) + START_PROCESSING(SSobj, src) + return ..() /obj/effect/spider/eggcluster/New(var/location, var/atom/parent) get_light_and_color(parent) ..() /obj/effect/spider/eggcluster/Destroy() - processing_objects -= src + STOP_PROCESSING(SSobj, src) if(istype(loc, /obj/item/organ/external)) var/obj/item/organ/external/O = loc O.implants -= src @@ -129,15 +133,15 @@ var/amount_grown = -1 var/obj/machinery/atmospherics/unary/vent_pump/entry_vent var/travelling_in_vent = 0 - var/list/grow_as = list(/mob/living/simple_animal/hostile/giant_spider, /mob/living/simple_animal/hostile/giant_spider/nurse, /mob/living/simple_animal/hostile/giant_spider/hunter) + var/list/grow_as = list(/mob/living/simple_mob/animal/giant_spider, /mob/living/simple_mob/animal/giant_spider/nurse, /mob/living/simple_mob/animal/giant_spider/hunter) /obj/effect/spider/spiderling/frost - grow_as = list(/mob/living/simple_animal/hostile/giant_spider/frost) + grow_as = list(/mob/living/simple_mob/animal/giant_spider/frost) /obj/effect/spider/spiderling/New(var/location, var/atom/parent) pixel_x = rand(6,-6) pixel_y = rand(6,-6) - processing_objects |= src + START_PROCESSING(SSobj, src) //50% chance to grow up if(prob(50)) amount_grown = 1 @@ -145,7 +149,7 @@ ..() /obj/effect/spider/spiderling/Destroy() - processing_objects -= src + STOP_PROCESSING(SSobj, src) walk(src, 0) // Because we might have called walk_to, we must stop the walk loop or BYOND keeps an internal reference to us forever. return ..() diff --git a/code/game/objects/effects/step_triggers.dm b/code/game/objects/effects/step_triggers.dm index febfff6d0f..f6c3bf1b01 100644 --- a/code/game/objects/effects/step_triggers.dm +++ b/code/game/objects/effects/step_triggers.dm @@ -3,7 +3,8 @@ /obj/effect/step_trigger var/affect_ghosts = 0 var/stopper = 1 // stops throwers - invisibility = 101 // nope cant see this shit + invisibility = 99 // nope cant see this shit + plane = ABOVE_PLANE anchored = 1 /obj/effect/step_trigger/proc/Trigger(var/atom/movable/A) @@ -93,21 +94,56 @@ var/teleport_y = 0 var/teleport_z = 0 - Trigger(var/atom/movable/A) - if(teleport_x && teleport_y && teleport_z) - var/turf/T = locate(teleport_x, teleport_y, teleport_z) - if(isliving(A)) - var/mob/living/L = A - if(L.pulling) - var/atom/movable/P = L.pulling - L.stop_pulling() - P.forceMove(T) - L.forceMove(T) - L.start_pulling(P) - else - A.forceMove(T) - else - A.forceMove(T) +/obj/effect/step_trigger/teleporter/Trigger(atom/movable/AM) + if(teleport_x && teleport_y && teleport_z) + var/turf/T = locate(teleport_x, teleport_y, teleport_z) + move_object(AM, T) + + +/obj/effect/step_trigger/teleporter/proc/move_object(atom/movable/AM, turf/T) + if(AM.anchored) + return + + if(isliving(AM)) + var/mob/living/L = AM + if(L.pulling) + var/atom/movable/P = L.pulling + L.stop_pulling() + P.forceMove(T) + L.forceMove(T) + L.start_pulling(P) + else + L.forceMove(T) + else + AM.forceMove(T) + +/* Moves things by an offset, useful for 'Bridges'. Uses dir and a distance var to work with maploader direction changes. */ +/obj/effect/step_trigger/teleporter/offset + icon = 'icons/effects/effects.dmi' + icon_state = "arrow" + var/distance = 3 + +/obj/effect/step_trigger/teleporter/offset/north + dir = NORTH + +/obj/effect/step_trigger/teleporter/offset/south + dir = SOUTH + +/obj/effect/step_trigger/teleporter/offset/east + dir = EAST + +/obj/effect/step_trigger/teleporter/offset/west + dir = WEST + +/obj/effect/step_trigger/teleporter/offset/Trigger(atom/movable/AM) + var/turf/T = get_turf(src) + for(var/i = 1 to distance) + T = get_step(T, dir) + if(!istype(T)) + return + move_object(AM, T) + + /* Random teleporter, teleports atoms to locations ranging from teleport_x - teleport_x_offset, etc */ @@ -128,7 +164,7 @@ var/obj/effect/landmark/the_landmark = null var/landmark_id = null -/obj/effect/step_trigger/teleporter/landmark/initialize() +/obj/effect/step_trigger/teleporter/landmark/Initialize() . = ..() for(var/obj/effect/landmark/teleport_mark/mark in tele_landmarks) if(mark.landmark_id == landmark_id) diff --git a/code/game/objects/effects/temporary_visuals/miscellaneous.dm b/code/game/objects/effects/temporary_visuals/miscellaneous.dm index 4e28a370f7..8a9220e87f 100644 --- a/code/game/objects/effects/temporary_visuals/miscellaneous.dm +++ b/code/game/objects/effects/temporary_visuals/miscellaneous.dm @@ -2,7 +2,7 @@ desc = "It's a decoy!" duration = 15 -/obj/effect/temp_visual/decoy/initialize(mapload, atom/mimiced_atom, var/customappearance) +/obj/effect/temp_visual/decoy/Initialize(mapload, atom/mimiced_atom, var/customappearance) . = ..() alpha = initial(alpha) if(mimiced_atom) @@ -13,7 +13,7 @@ if(customappearance) appearance = customappearance -/obj/effect/temp_visual/decoy/fading/initialize(mapload, atom/mimiced_atom) +/obj/effect/temp_visual/decoy/fading/Initialize(mapload, atom/mimiced_atom) . = ..() animate(src, alpha = 0, time = duration) diff --git a/code/game/objects/effects/temporary_visuals/projectiles/impact.dm b/code/game/objects/effects/temporary_visuals/projectiles/impact.dm new file mode 100644 index 0000000000..872c652356 --- /dev/null +++ b/code/game/objects/effects/temporary_visuals/projectiles/impact.dm @@ -0,0 +1,81 @@ +/obj/effect/projectile/impact + name = "beam impact" + icon = 'icons/obj/projectiles_impact.dmi' + +/obj/effect/projectile/impact/laser_pulse + icon_state = "impact_u_laser" + light_range = 2 + light_power = 0.5 + light_color = "#0066FF" + +/obj/effect/projectile/impact/laser_heavy + icon_state = "impact_beam_heavy" + light_range = 3 + light_power = 1 + light_color = "#FF0D00" + +/obj/effect/projectile/impact/xray + icon_state = "impact_xray" + light_range = 2 + light_power = 0.5 + light_color = "#00CC33" + +/obj/effect/projectile/impact/laser_omni + icon_state = "impact_omni" + light_range = 2 + light_power = 0.5 + light_color = "#00C6FF" + +/obj/effect/projectile/impact/laser + icon_state = "impact_laser" + light_range = 2 + light_power = 0.5 + light_color = "#FF0D00" + +/obj/effect/projectile/impact/laser_blue + icon_state = "impact_blue" + light_range = 2 + light_power = 0.5 + light_color = "#0066FF" + +/obj/effect/projectile/impact/emitter + icon_state = "impact_emitter" + light_range = 2 + light_power = 0.5 + light_color = "#00CC33" + +/obj/effect/projectile/impact/stun + icon_state = "impact_stun" + light_range = 2 + light_power = 0.5 + light_color = "#FFFFFF" + +/obj/effect/projectile/impact/lightning + icon_state = "impact_lightning" + light_range = 2 + light_power = 0.5 + light_color = "#00C6FF" + +/obj/effect/projectile/impact/darkmatterstun + icon_state = "impact_darkt" + light_range = 2 + light_power = 0.5 + light_color = "#8837A3" + +/obj/effect/projectile/impact/inversion + icon_state = "impact_invert" + light_range = 2 + light_power = -2 + light_color = "#FFFFFF" + +/obj/effect/projectile/impact/darkmatter + icon_state = "impact_darkb" + light_range = 2 + light_power = 0.5 + light_color = "#8837A3" + +/obj/effect/projectile/tungsten/impact + icon_state = "impact_mhd_laser" + light_range = 4 + light_power = 3 + light_color = "#3300ff" diff --git a/code/game/objects/effects/temporary_visuals/projectiles/muzzle.dm b/code/game/objects/effects/temporary_visuals/projectiles/muzzle.dm new file mode 100644 index 0000000000..42511e6577 --- /dev/null +++ b/code/game/objects/effects/temporary_visuals/projectiles/muzzle.dm @@ -0,0 +1,93 @@ +/obj/effect/projectile/muzzle + name = "muzzle flash" + icon = 'icons/obj/projectiles_muzzle.dmi' + +/obj/effect/projectile/muzzle/emitter + icon_state = "muzzle_emitter" + light_range = 2 + light_power = 0.5 + light_color = "#00CC33" + +/obj/effect/projectile/muzzle/laser_pulse + icon_state = "muzzle_u_laser" + light_range = 2 + light_power = 0.5 + light_color = "#0066FF" + +/obj/effect/projectile/muzzle/pulse + icon_state = "muzzle_pulse" + light_range = 2 + light_power = 0.5 + light_color = "#0066FF" + +/obj/effect/projectile/muzzle/stun + icon_state = "muzzle_stun" + light_range = 2 + light_power = 0.5 + light_color = "#FFFFFF" + +/obj/effect/projectile/muzzle/bullet + icon_state = "muzzle_bullet" + light_range = 2 + light_power = 0.5 + light_color = "#FFFFFF" + +/obj/effect/projectile/muzzle/laser_heavy + icon_state = "muzzle_beam_heavy" + light_range = 3 + light_power = 1 + light_color = "#FF0D00" + +/obj/effect/projectile/muzzle/lightning + icon_state = "muzzle_lightning" + light_range = 2 + light_power = 0.5 + light_color = "#00C6FF" + +/obj/effect/projectile/muzzle/darkmatterstun + icon_state = "muzzle_darkt" + light_range = 2 + light_power = 0.5 + light_color = "#8837A3" + +/obj/effect/projectile/muzzle/laser_blue + icon_state = "muzzle_blue" + light_range = 2 + light_power = 0.5 + light_color = "#0066FF" + +/obj/effect/projectile/muzzle/darkmatter + icon_state = "muzzle_darkb" + light_range = 2 + light_power = 0.5 + light_color = "#8837A3" + +/obj/effect/projectile/muzzle/inversion + icon_state = "muzzle_invert" + light_range = 2 + light_power = -2 + light_color = "#FFFFFF" + +/obj/effect/projectile/muzzle/xray + icon_state = "muzzle_xray" + light_range = 2 + light_power = 0.5 + light_color = "#00CC33" + +/obj/effect/projectile/muzzle/laser_omni + icon_state = "muzzle_omni" + light_range = 2 + light_power = 0.5 + light_color = "#00C6FF" + +/obj/effect/projectile/muzzle/laser + icon_state = "muzzle_laser" + light_range = 2 + light_power = 0.5 + light_color = "#FF0D00" + +/obj/effect/projectile/tungsten/muzzle + icon_state = "muzzle_mhd_laser" + light_range = 4 + light_power = 3 + light_color = "#3300ff" diff --git a/code/game/objects/effects/temporary_visuals/projectiles/projectile_effects.dm b/code/game/objects/effects/temporary_visuals/projectiles/projectile_effects.dm new file mode 100644 index 0000000000..1088a3e4ba --- /dev/null +++ b/code/game/objects/effects/temporary_visuals/projectiles/projectile_effects.dm @@ -0,0 +1,60 @@ +/obj/effect/projectile + name = "pew" + icon = 'icons/obj/projectiles.dmi' + icon_state = "nothing" + layer = ABOVE_MOB_LAYER + anchored = TRUE + mouse_opacity = 0 + appearance_flags = 0 + +/obj/effect/projectile/singularity_pull() + return + +/obj/effect/projectile/singularity_act() + return + +/obj/effect/projectile/proc/scale_to(nx,ny,override=TRUE) + var/matrix/M + if(!override) + M = transform + else + M = new + M.Scale(nx,ny) + transform = M + +/obj/effect/projectile/proc/turn_to(angle,override=TRUE) + var/matrix/M + if(!override) + M = transform + else + M = new + M.Turn(angle) + transform = M + +/obj/effect/projectile/New(angle_override, p_x, p_y, color_override, scaling = 1) + if(angle_override && p_x && p_y && color_override && scaling) + apply_vars(angle_override, p_x, p_y, color_override, scaling) + return ..() + +/obj/effect/projectile/proc/apply_vars(angle_override, p_x = 0, p_y = 0, color_override, scaling = 1, new_loc, increment = 0) + var/mutable_appearance/look = new(src) + look.pixel_x = p_x + look.pixel_y = p_y + if(color_override) + look.color = color_override + appearance = look + scale_to(1,scaling, FALSE) + turn_to(angle_override, FALSE) + if(!isnull(new_loc)) //If you want to null it just delete it... + forceMove(new_loc) + for(var/i in 1 to increment) + pixel_x += round((sin(angle_override)+16*sin(angle_override)*2), 1) + pixel_y += round((cos(angle_override)+16*cos(angle_override)*2), 1) + +/obj/effect/projectile_lighting + var/owner + +/obj/effect/projectile_lighting/New(loc, color, range, intensity, owner_key) + . = ..() + set_light(range, intensity, color) + owner = owner_key diff --git a/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm b/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm new file mode 100644 index 0000000000..54fa41265f --- /dev/null +++ b/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm @@ -0,0 +1,109 @@ +/proc/generate_tracer_between_points(datum/point/starting, datum/point/ending, beam_type, color, qdel_in = 5, light_range = 2, light_color_override, light_intensity = 1, instance_key) //Do not pass z-crossing points as that will not be properly (and likely will never be properly until it's absolutely needed) supported! + if(!istype(starting) || !istype(ending) || !ispath(beam_type)) + return + var/datum/point/midpoint = point_midpoint_points(starting, ending) + var/obj/effect/projectile/tracer/PB = new beam_type + if(isnull(light_color_override)) + light_color_override = color + PB.apply_vars(angle_between_points(starting, ending), midpoint.return_px(), midpoint.return_py(), color, pixel_length_between_points(starting, ending) / world.icon_size, midpoint.return_turf(), 0) + . = PB + if(isnull(light_intensity) && !isnull(PB.light_power)) + light_intensity = PB.light_power + if(isnull(light_range) && !isnull(PB.light_range)) + light_range = PB.light_range + if(isnull(light_color_override) && !isnull(PB.light_color)) + light_color_override = PB.light_color + if(light_range > 0 && light_intensity > 0) + var/list/turf/line = getline(starting.return_turf(), ending.return_turf()) + tracing_line: + for(var/i in line) + var/turf/T = i + for(var/obj/effect/projectile_lighting/PL in T) + if(PL.owner == instance_key) + continue tracing_line + QDEL_IN(new /obj/effect/projectile_lighting(T, light_color_override, light_range, light_intensity, instance_key), qdel_in > 0? qdel_in : 5) + line = null + if(qdel_in) + QDEL_IN(PB, qdel_in) + +/obj/effect/projectile/tracer + name = "beam" + icon = 'icons/obj/projectiles_tracer.dmi' + +/obj/effect/projectile/tracer/stun + icon_state = "stun" + light_range = 2 + light_power = 0.5 + light_color = "#FFFFFF" + +/obj/effect/projectile/tracer/lightning + icon_state = "lightning" + light_range = 2 + light_power = 0.5 + light_color = "#00C6FF" + +/obj/effect/projectile/tracer/laser_pulse + icon_state = "u_laser" + light_range = 2 + light_power = 0.5 + light_color = "#0066FF" + +/obj/effect/projectile/tracer/emitter + icon_state = "emitter" + light_range = 2 + light_power = 0.5 + light_color = "#00CC33" + +/obj/effect/projectile/tracer/darkmatterstun + icon_state = "darkt" + light_range = 2 + light_power = 0.5 + light_color = "#8837A3" + +/obj/effect/projectile/tracer/laser_omni + icon_state = "beam_omni" + light_range = 2 + light_power = 0.5 + light_color = "#00C6FF" + +/obj/effect/projectile/tracer/xray + icon_state = "xray" + light_range = 2 + light_power = 0.5 + light_color = "#00CC33" + +/obj/effect/projectile/tracer/laser_heavy + icon_state = "beam_heavy" + light_range = 3 + light_power = 1 + light_color = "#FF0D00" + +/obj/effect/projectile/tracer/darkmatter + icon_state = "darkb" + light_range = 2 + light_power = 0.5 + light_color = "#8837A3" + +/obj/effect/projectile/tracer/inversion + icon_state = "invert" + light_range = 2 + light_power = -2 + light_color = "#FFFFFF" + +/obj/effect/projectile/tracer/laser + icon_state = "beam" + light_range = 2 + light_power = 0.5 + light_color = "#FF0D00" + +/obj/effect/projectile/tracer/laser_blue + icon_state = "beam_blue" + light_range = 2 + light_power = 0.5 + light_color = "#0066FF" + +/obj/effect/projectile/tungsten/tracer + icon_state = "mhd_laser" + light_range = 4 + light_power = 3 + light_color = "#3300ff" diff --git a/code/game/objects/effects/temporary_visuals/temproary_visual.dm b/code/game/objects/effects/temporary_visuals/temporary_visual.dm similarity index 64% rename from code/game/objects/effects/temporary_visuals/temproary_visual.dm rename to code/game/objects/effects/temporary_visuals/temporary_visual.dm index 79a8797bae..84e8e1c031 100644 --- a/code/game/objects/effects/temporary_visuals/temproary_visual.dm +++ b/code/game/objects/effects/temporary_visuals/temporary_visual.dm @@ -7,14 +7,17 @@ mouse_opacity = 0 var/duration = 10 //in deciseconds var/randomdir = TRUE + var/timerid -/obj/effect/temp_visual/initialize() +/obj/effect/temp_visual/Initialize() . = ..() if(randomdir) - set_dir(pick(cardinal)) + dir = pick(list(NORTH, SOUTH, EAST, WEST)) + timerid = QDEL_IN(src, duration) - spawn(duration) - qdel(src) +/obj/effect/temp_visual/Destroy() + . = ..() + deltimer(timerid) /obj/effect/temp_visual/singularity_act() return @@ -25,12 +28,11 @@ /obj/effect/temp_visual/ex_act() return -/* /obj/effect/temp_visual/dir_setting randomdir = FALSE -/obj/effect/temp_visual/dir_setting/Initialize(mapload, set_dir) +/obj/effect/temp_visual/dir_setting/Initialize(loc, set_dir) if(set_dir) - setDir(set_dir) + dir = set_dir . = ..() -*/ //More tg stuff that might be useful later + diff --git a/code/game/objects/effects/temporary_visuials/temproary_visual.dm b/code/game/objects/effects/temporary_visuials/temproary_visual.dm index 9beda4cac3..0ecaf5e312 100644 --- a/code/game/objects/effects/temporary_visuials/temproary_visual.dm +++ b/code/game/objects/effects/temporary_visuials/temproary_visual.dm @@ -8,7 +8,7 @@ var/duration = 10 //in deciseconds var/randomdir = TRUE -/obj/effect/temp_visual/initialize() +/obj/effect/temp_visual/Initialize() . = ..() if(randomdir) set_dir(pick(global.cardinal)) diff --git a/code/game/objects/explosion.dm b/code/game/objects/explosion.dm index 9132cf4b12..bd1d9cbd12 100644 --- a/code/game/objects/explosion.dm +++ b/code/game/objects/explosion.dm @@ -40,7 +40,7 @@ proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impa if(dist <= round(max_range + world.view - 2, 1)) M.playsound_local(epicenter, get_sfx("explosion"), 100, 1, frequency, falloff = 5) // get_sfx() is so that everyone gets the same sound else if(dist <= far_dist) - var/far_volume = Clamp(far_dist, 30, 50) // Volume is based on explosion size and dist + var/far_volume = CLAMP(far_dist, 30, 50) // Volume is based on explosion size and dist far_volume += (dist <= far_dist * 0.5 ? 50 : 0) // add 50 volume if the mob is pretty close to the explosion M.playsound_local(epicenter, 'sound/effects/explosionfar.ogg', far_volume, 1, frequency, falloff = 5) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index be332a47e5..3ba9c1bac7 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -27,6 +27,10 @@ var/max_heat_protection_temperature //Set this variable to determine up to which temperature (IN KELVIN) the item protects against heat damage. Keep at null to disable protection. Only protects areas set by heat_protection flags var/min_cold_protection_temperature //Set this variable to determine down to which temperature (IN KELVIN) the item protects against cold damage. 0 is NOT an acceptable number due to if(varname) tests!! Keep at null to disable protection. Only protects areas set by cold_protection flags + var/max_pressure_protection // Set this variable if the item protects its wearer against high pressures below an upper bound. Keep at null to disable protection. + var/min_pressure_protection // Set this variable if the item protects its wearer against low pressures above a lower bound. Keep at null to disable protection. 0 represents protection against hard vacuum. + + var/datum/action/item_action/action = null var/action_button_name //It is also the text which gets displayed on the action button. If not set it defaults to 'Use [name]'. If it's not set, there'll be no button. var/action_button_is_hands_free = 0 //If 1, bypass the restrained, lying, and stunned checks action buttons normally test for diff --git a/code/game/objects/items/bodybag.dm b/code/game/objects/items/bodybag.dm index f79ac478b2..600ed118dc 100644 --- a/code/game/objects/items/bodybag.dm +++ b/code/game/objects/items/bodybag.dm @@ -144,8 +144,8 @@ var/stasis_level = 3 //Every 'this' life ticks are applied to the mob (when life_ticks%stasis_level == 1) var/obj/item/weapon/reagent_containers/syringe/syringe -/obj/structure/closet/body_bag/cryobag/New() - tank = new /obj/item/weapon/tank/emergency/oxygen/double(null) //It's in nullspace to prevent ejection when the bag is opened. +/obj/structure/closet/body_bag/cryobag/Initialize() + tank = new /obj/item/weapon/tank/stasis/oxygen(null) //It's in nullspace to prevent ejection when the bag is opened. ..() /obj/structure/closet/body_bag/cryobag/Destroy() diff --git a/code/game/objects/items/contraband.dm b/code/game/objects/items/contraband.dm index cc67c59517..e8c7a0d08d 100644 --- a/code/game/objects/items/contraband.dm +++ b/code/game/objects/items/contraband.dm @@ -40,8 +40,8 @@ list("impedrezene" = 15) = 2, list("zombiepowder" = 10) = 1) -/obj/item/weapon/reagent_containers/glass/beaker/vial/random/New() - ..() +/obj/item/weapon/reagent_containers/glass/beaker/vial/random/Initialize() + . = ..() if(is_open_container()) flags ^= OPENCONTAINER diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 14c341ce34..c2a77936c4 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -467,7 +467,7 @@ var/global/list/obj/item/device/pda/PDAs = list() /obj/item/device/pda/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) ui_tick++ - var/datum/nanoui/old_ui = GLOB.nanomanager.get_open_ui(user, src, "main") + var/datum/nanoui/old_ui = SSnanoui.get_open_ui(user, src, "main") var/auto_update = 1 if(mode in no_auto_update) auto_update = 0 @@ -647,7 +647,7 @@ var/global/list/obj/item/device/pda/PDAs = list() nanoUI = data // update the ui if it exists, returns null if no ui is passed/found - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.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 @@ -685,7 +685,7 @@ var/global/list/obj/item/device/pda/PDAs = list() ..() var/mob/user = usr - var/datum/nanoui/ui = GLOB.nanomanager.get_open_ui(user, src, "main") + var/datum/nanoui/ui = SSnanoui.get_open_ui(user, src, "main") var/mob/living/U = usr //Looking for master was kind of pointless since PDAs don't appear to have one. //if ((src in U.contents) || ( istype(loc, /turf) && in_range(src, U) ) ) @@ -1130,7 +1130,7 @@ var/global/list/obj/item/device/pda/PDAs = list() ai.show_message("Intercepted message from [who]: [t]") P.new_message_from_pda(src, t) - GLOB.nanomanager.update_user_uis(U, src) // Update the sending user's PDA UI so that they can see the new message + SSnanoui.update_user_uis(U, src) // Update the sending user's PDA UI so that they can see the new message else to_chat(U, "ERROR: Messaging server is not responding.") @@ -1150,7 +1150,7 @@ var/global/list/obj/item/device/pda/PDAs = list() if(L) if(reception_message) L << reception_message - GLOB.nanomanager.update_user_uis(L, src) // Update the receiving user's PDA UI so that they can see the new message + SSnanoui.update_user_uis(L, src) // Update the receiving user's PDA UI so that they can see the new message /obj/item/device/pda/proc/new_news(var/message) new_info(news_silent, newstone, news_silent ? "" : "\icon[src] [message]") @@ -1196,7 +1196,7 @@ var/global/list/obj/item/device/pda/PDAs = list() if(can_use(usr)) mode = 0 - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) to_chat(usr, "You press the reset button on \the [src].") else to_chat(usr, "You cannot do this while restrained.") @@ -1297,7 +1297,7 @@ var/global/list/obj/item/device/pda/PDAs = list() user.drop_item() cartridge.loc = src to_chat(usr, "You insert [cartridge] into [src].") - GLOB.nanomanager.update_uis(src) // update all UIs attached to src + SSnanoui.update_uis(src) // update all UIs attached to src if(cartridge.radio) cartridge.radio.hostpda = src @@ -1325,7 +1325,7 @@ var/global/list/obj/item/device/pda/PDAs = list() C.loc = src pai = C to_chat(user, "You slot \the [C] into \the [src].") - GLOB.nanomanager.update_uis(src) // update all UIs attached to src + SSnanoui.update_uis(src) // update all UIs attached to src else if(istype(C, /obj/item/weapon/pen)) var/obj/item/weapon/pen/O = locate() in src if(O) diff --git a/code/game/objects/items/devices/PDA/cart.dm b/code/game/objects/items/devices/PDA/cart.dm index cf91bbef3b..8f6533a702 100644 --- a/code/game/objects/items/devices/PDA/cart.dm +++ b/code/game/objects/items/devices/PDA/cart.dm @@ -108,7 +108,7 @@ var/list/civilian_cartridges = list( icon_state = "cart-s" access_security = 1 -/obj/item/weapon/cartridge/security/initialize() +/obj/item/weapon/cartridge/security/Initialize() radio = new /obj/item/radio/integrated/beepsky(src) . = ..() @@ -164,7 +164,7 @@ var/list/civilian_cartridges = list( access_reagent_scanner = 1 access_atmos = 1 -/obj/item/weapon/cartridge/signal/initialize() +/obj/item/weapon/cartridge/signal/Initialize() radio = new /obj/item/radio/integrated/signal(src) . = ..() @@ -198,7 +198,7 @@ var/list/civilian_cartridges = list( access_status_display = 1 access_security = 1 -/obj/item/weapon/cartridge/hos/initialize() +/obj/item/weapon/cartridge/hos/Initialize() radio = new /obj/item/radio/integrated/beepsky(src) . = ..() @@ -223,7 +223,7 @@ var/list/civilian_cartridges = list( access_reagent_scanner = 1 access_atmos = 1 -/obj/item/weapon/cartridge/rd/initialize() +/obj/item/weapon/cartridge/rd/Initialize() radio = new /obj/item/radio/integrated/signal(src) . = ..() diff --git a/code/game/objects/items/devices/PDA/radio.dm b/code/game/objects/items/devices/PDA/radio.dm index 9de35c2582..a5a76dd993 100644 --- a/code/game/objects/items/devices/PDA/radio.dm +++ b/code/game/objects/items/devices/PDA/radio.dm @@ -116,39 +116,37 @@ var/last_transmission var/datum/radio_frequency/radio_connection - initialize() - if(!radio_controller) - return - - if (src.frequency < PUBLIC_LOW_FREQ || src.frequency > PUBLIC_HIGH_FREQ) - src.frequency = sanitize_frequency(src.frequency) - - set_frequency(frequency) - - proc/set_frequency(new_frequency) - radio_controller.remove_object(src, frequency) - frequency = new_frequency - radio_connection = radio_controller.add_object(src, frequency) - - proc/send_signal(message="ACTIVATE") - - if(last_transmission && world.time < (last_transmission + 5)) - return - last_transmission = world.time - - var/time = time2text(world.realtime,"hh:mm:ss") - var/turf/T = get_turf(src) - lastsignalers.Add("[time] : [usr.key] used [src] @ location ([T.x],[T.y],[T.z]) : [format_frequency(frequency)]/[code]") - - var/datum/signal/signal = new - signal.source = src - signal.encryption = code - signal.data["message"] = message - - radio_connection.post_signal(src, signal) - +/obj/item/radio/integrated/signal/Initialize() + if(!radio_controller) return + if (src.frequency < PUBLIC_LOW_FREQ || src.frequency > PUBLIC_HIGH_FREQ) + src.frequency = sanitize_frequency(src.frequency) + + set_frequency(frequency) + +/obj/item/radio/integrated/signal/proc/set_frequency(new_frequency) + radio_controller.remove_object(src, frequency) + frequency = new_frequency + radio_connection = radio_controller.add_object(src, frequency) + +/obj/item/radio/integrated/signal/proc/send_signal(message="ACTIVATE") + + if(last_transmission && world.time < (last_transmission + 5)) + return + last_transmission = world.time + + var/time = time2text(world.realtime,"hh:mm:ss") + var/turf/T = get_turf(src) + lastsignalers.Add("[time] : [usr.key] used [src] @ location ([T.x],[T.y],[T.z]) : [format_frequency(frequency)]/[code]") + + var/datum/signal/signal = new + signal.source = src + signal.encryption = code + signal.data["message"] = message + + radio_connection.post_signal(src, signal) + /obj/item/radio/integrated/signal/Destroy() if(radio_controller) radio_controller.remove_object(src, frequency) diff --git a/code/game/objects/items/devices/ai_detector.dm b/code/game/objects/items/devices/ai_detector.dm index 7fa6f74521..fde112706f 100644 --- a/code/game/objects/items/devices/ai_detector.dm +++ b/code/game/objects/items/devices/ai_detector.dm @@ -17,11 +17,11 @@ // It's really really unlikely for the view range to change. But why not be futureproof anyways? range_alert = world.view range_warning = world.view * 2 - processing_objects += src + START_PROCESSING(SSobj, src) ..() /obj/item/device/multitool/ai_detector/Destroy() - processing_objects -= src + STOP_PROCESSING(SSobj, src) return ..() /obj/item/device/multitool/ai_detector/process() diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm index c2af338521..181764d126 100644 --- a/code/game/objects/items/devices/aicard.dm +++ b/code/game/objects/items/devices/aicard.dm @@ -43,7 +43,7 @@ data["laws"] = laws data["has_laws"] = laws.len - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "aicard.tmpl", "[name]", 600, 400, state = state) ui.set_initial_data(data) @@ -107,7 +107,7 @@ return 0 if(!user.IsAdvancedToolUser() && isanimal(user)) - var/mob/living/simple_animal/S = user + var/mob/living/simple_mob/S = user if(!S.IsHumanoidToolUser(src)) return 0 diff --git a/code/game/objects/items/devices/communicator/UI.dm b/code/game/objects/items/devices/communicator/UI.dm index d414232a80..69f5bd0d4b 100644 --- a/code/game/objects/items/devices/communicator/UI.dm +++ b/code/game/objects/items/devices/communicator/UI.dm @@ -125,7 +125,7 @@ // The value element is the actual data, and can take any form necessary for the template // update the ui if it exists, returns null if no ui is passed/found - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.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 @@ -261,7 +261,7 @@ notehtml = note if(href_list["switch_template"]) - var/datum/nanoui/ui = GLOB.nanomanager.get_open_ui(usr, src, "main") + var/datum/nanoui/ui = SSnanoui.get_open_ui(usr, src, "main") if(ui) ui.add_template("Body", href_list["switch_template"]) @@ -276,5 +276,5 @@ if(href_list["cartridge_topic"] && cartridge) // Has to have a cartridge to perform these functions cartridge.Topic(href, href_list) - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) add_fingerprint(usr) diff --git a/code/game/objects/items/devices/communicator/cartridge.dm b/code/game/objects/items/devices/communicator/cartridge.dm index 6b29f1121e..b5a46b4ebe 100644 --- a/code/game/objects/items/devices/communicator/cartridge.dm +++ b/code/game/objects/items/devices/communicator/cartridge.dm @@ -379,7 +379,7 @@ ..() internal_devices |= new /obj/item/device/halogen_counter(src) -/obj/item/weapon/commcard/engineering/initialize() +/obj/item/weapon/commcard/engineering/Initialize() internal_data["grid_sensors"] = find_powernet_sensors() internal_data["powernet_target"] = "" @@ -616,7 +616,7 @@ internal_data["stat_display_active2"] = null internal_data["stat_display_special"] = null -/obj/item/weapon/commcard/head/initialize() +/obj/item/weapon/commcard/head/Initialize() // Have to register the commcard with the Radio controller to receive updates to the status displays radio_controller.add_object(src, 1435) ..() @@ -793,7 +793,7 @@ internal_devices |= new /obj.item/device/analyzer(src) internal_devices |= new /obj/item/device/halogen_counter(src) -/obj/item/weapon/commcard/head/ce/initialize() +/obj/item/weapon/commcard/head/ce/Initialize() internal_data["grid_sensors"] = find_powernet_sensors() internal_data["powernet_target"] = "" @@ -904,7 +904,7 @@ list("name" = "Shuttle Blast Door Control", "template" = "merc_blast_door_control.tmpl") ) -/obj/item/weapon/commcard/mercenary/initialize() +/obj/item/weapon/commcard/mercenary/Initialize() internal_data["shuttle_door_code"] = "smindicate" // Copied from PDA code internal_data["shuttle_doors"] = find_blast_doors() diff --git a/code/game/objects/items/devices/communicator/communicator.dm b/code/game/objects/items/devices/communicator/communicator.dm index ec9c09c161..b9a8eff8a4 100644 --- a/code/game/objects/items/devices/communicator/communicator.dm +++ b/code/game/objects/items/devices/communicator/communicator.dm @@ -82,7 +82,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list() all_communicators += src all_communicators = sortAtom(all_communicators) node = get_exonet_node() - processing_objects |= src + START_PROCESSING(SSobj, src) camera = new(src) camera.name = "[src] #[rand(100,999)]" camera.c_tag = camera.name @@ -234,7 +234,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list() cartridge.forceMove(src) to_chat(usr, "You slot \the [cartridge] into \the [src].") modules[++modules.len] = list("module" = "External Device", "icon" = "external64", "number" = EXTRTAB) - GLOB.nanomanager.update_uis(src) // update all UIs attached to src + SSnanoui.update_uis(src) // update all UIs attached to src return // Proc: attack_self() @@ -324,7 +324,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list() //Clean up references that might point at us all_communicators -= src - processing_objects -= src + STOP_PROCESSING(SSobj, src) listening_objects.Remove(src) QDEL_NULL(camera) QDEL_NULL(exonet) diff --git a/code/game/objects/items/devices/defib.dm b/code/game/objects/items/devices/defib.dm index 1ddfa04bf0..26fb1b69aa 100644 --- a/code/game/objects/items/devices/defib.dm +++ b/code/game/objects/items/devices/defib.dm @@ -53,7 +53,7 @@ else new_overlays += "[initial(icon_state)]-powered" - var/ratio = Ceiling(bcell.percent()/25) * 25 + var/ratio = CEILING(bcell.percent()/25, 1) * 25 new_overlays += "[initial(icon_state)]-charge[ratio]" else new_overlays += "[initial(icon_state)]-nocell" @@ -503,7 +503,7 @@ var/obj/item/organ/internal/brain/brain = H.internal_organs_by_name[O_BRAIN] if(!brain) return //no brain - var/brain_damage = Clamp((deadtime - DEFIB_TIME_LOSS)/(DEFIB_TIME_LIMIT - DEFIB_TIME_LOSS)*brain.max_damage, H.getBrainLoss(), brain.max_damage) + var/brain_damage = CLAMP((deadtime - DEFIB_TIME_LOSS)/(DEFIB_TIME_LIMIT - DEFIB_TIME_LOSS)*brain.max_damage, H.getBrainLoss(), brain.max_damage) H.setBrainLoss(brain_damage) /obj/item/weapon/shockpaddles/proc/make_announcement(var/message, var/msg_class) @@ -604,7 +604,7 @@ /obj/item/weapon/shockpaddles/standalone/Destroy() . = ..() if(fail_counter) - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) /obj/item/weapon/shockpaddles/standalone/check_charge(var/charge_amt) return 1 @@ -617,7 +617,7 @@ if(fail_counter > 0) radiation_repository.radiate(src, fail_counter--) else - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) /obj/item/weapon/shockpaddles/standalone/emp_act(severity) ..() @@ -632,7 +632,7 @@ to_chat(loc, "\The [src] feel pleasantly warm.") if(new_fail && !fail_counter) - processing_objects.Add(src) + START_PROCESSING(SSobj, src) fail_counter = new_fail /* From the Bay port, this doesn't seem to have a sprite. diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index b25d86897f..4543a6d726 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -19,13 +19,13 @@ var/power_usage var/power_use = 1 -/obj/item/device/flashlight/initialize() +/obj/item/device/flashlight/Initialize() . = ..() update_icon() /obj/item/device/flashlight/New() if(power_use) - processing_objects |= src + START_PROCESSING(SSobj, src) if(cell_type) cell = new cell_type(src) @@ -38,7 +38,7 @@ /obj/item/device/flashlight/Destroy() if(power_use) - processing_objects -= src + STOP_PROCESSING(SSobj, src) return ..() /obj/item/device/flashlight/get_cell() @@ -352,7 +352,7 @@ turn_off() if(!fuel) src.icon_state = "[initial(icon_state)]-empty" - processing_objects -= src + STOP_PROCESSING(SSobj, src) /obj/item/device/flashlight/flare/proc/turn_off() on = 0 @@ -375,14 +375,14 @@ user.visible_message("[user] activates the flare.", "You pull the cord on the flare, activating it!") src.force = on_damage src.damtype = "fire" - processing_objects += src + START_PROCESSING(SSobj, src) /obj/item/device/flashlight/flare/proc/ignite() //Used for flare launchers. on = !on update_icon() force = on_damage damtype = "fire" - processing_objects += src + START_PROCESSING(SSobj, src) return 1 //Glowsticks @@ -409,7 +409,7 @@ turn_off() if(!fuel) src.icon_state = "[initial(icon_state)]-empty" - processing_objects -= src + STOP_PROCESSING(SSobj, src) /obj/item/device/flashlight/glowstick/proc/turn_off() on = 0 @@ -426,7 +426,7 @@ . = ..() if(.) user.visible_message("[user] cracks and shakes the glowstick.", "You crack and shake the glowstick, turning it on!") - processing_objects += src + START_PROCESSING(SSobj, src) /obj/item/device/flashlight/glowstick/red name = "red glowstick" diff --git a/code/game/objects/items/devices/geiger.dm b/code/game/objects/items/devices/geiger.dm index dbac918609..76697ddba3 100644 --- a/code/game/objects/items/devices/geiger.dm +++ b/code/game/objects/items/devices/geiger.dm @@ -1,8 +1,3 @@ -#define RAD_LEVEL_LOW 0.01 // Around the level at which radiation starts to become harmful -#define RAD_LEVEL_MODERATE 10 -#define RAD_LEVEL_HIGH 25 -#define RAD_LEVEL_VERY_HIGH 50 - //Geiger counter //Rewritten version of TG's geiger counter //I opted to show exact radiation levels @@ -15,12 +10,16 @@ w_class = ITEMSIZE_SMALL var/scanning = 0 var/radiation_count = 0 + var/datum/looping_sound/geiger/soundloop -/obj/item/device/geiger/New() - processing_objects |= src +/obj/item/device/geiger/Initialize() + START_PROCESSING(SSobj, src) + soundloop = new(list(src), FALSE) + return ..() /obj/item/device/geiger/Destroy() - processing_objects -= src + STOP_PROCESSING(SSobj, src) + QDEL_NULL(soundloop) return ..() /obj/item/device/geiger/process() @@ -31,6 +30,7 @@ return radiation_count = radiation_repository.get_rads_at_turf(get_turf(src)) update_icon() + update_sound() /obj/item/device/geiger/examine(mob/user) ..(user) @@ -44,18 +44,24 @@ if(amount > radiation_count) radiation_count = amount - var/sound = "geiger" - if(amount < 5) - sound = "geiger_weak" - playsound(src, sound, between(10, 10 + (radiation_count * 4), 100), 0) - if(sound == "geiger_weak") // A weak geiger sound every two seconds sounds too infrequent. - spawn(1 SECOND) - playsound(src, sound, between(10, 10 + (radiation_count * 4), 100), 0) update_icon() + update_sound() + +/obj/item/device/geiger/proc/update_sound() + var/datum/looping_sound/geiger/loop = soundloop + if(!scanning) + loop.stop() + return + if(!radiation_count) + loop.stop() + return + loop.last_radiation = radiation_count + loop.start() /obj/item/device/geiger/attack_self(var/mob/user) scanning = !scanning update_icon() + update_sound() to_chat(user, "\icon[src] You switch [scanning ? "on" : "off"] \the [src].") /obj/item/device/geiger/update_icon() @@ -76,8 +82,3 @@ icon_state = "geiger_on_4" if(RAD_LEVEL_VERY_HIGH to INFINITY) icon_state = "geiger_on_5" - -#undef RAD_LEVEL_LOW -#undef RAD_LEVEL_MODERATE -#undef RAD_LEVEL_HIGH -#undef RAD_LEVEL_VERY_HIGH \ No newline at end of file diff --git a/code/game/objects/items/devices/gps.dm b/code/game/objects/items/devices/gps.dm index c62cb541ce..839dc7a2dc 100644 --- a/code/game/objects/items/devices/gps.dm +++ b/code/game/objects/items/devices/gps.dm @@ -17,7 +17,7 @@ var/list/GPS_list = list() var/hide_signal = FALSE // If true, signal is not visible to other GPS devices. var/can_hide_signal = FALSE // If it can toggle the above var. -/obj/item/device/gps/initialize() +/obj/item/device/gps/Initialize() . = ..() GPS_list += src name = "global positioning system ([gps_tag])" diff --git a/code/game/objects/items/devices/laserpointer.dm b/code/game/objects/items/devices/laserpointer.dm index 343a58ce1a..ee77a47de9 100644 --- a/code/game/objects/items/devices/laserpointer.dm +++ b/code/game/objects/items/devices/laserpointer.dm @@ -166,7 +166,7 @@ outmsg = "You missed the lens of [C] with [src]." //cats! - for(var/mob/living/simple_animal/cat/C in viewers(1,targloc)) + for(var/mob/living/simple_mob/animal/passive/cat/C in viewers(1,targloc)) if (!(C.stat || C.buckled)) if(prob(50) && !(C.client)) C.visible_message("[C] pounces on the light!", "You pounce on the light!") @@ -200,7 +200,7 @@ if(energy <= max_energy) if(!recharging) recharging = 1 - processing_objects.Add(src) + START_PROCESSING(SSobj, src) if(energy <= 0) to_chat(user, "You've overused the battery of [src], now it needs time to recharge!") recharge_locked = 1 diff --git a/code/game/objects/items/devices/powersink.dm b/code/game/objects/items/devices/powersink.dm index 6ea73e8c78..26daccfc92 100644 --- a/code/game/objects/items/devices/powersink.dm +++ b/code/game/objects/items/devices/powersink.dm @@ -25,7 +25,7 @@ var/obj/structure/cable/attached // the attached cable /obj/item/device/powersink/Destroy() - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) STOP_PROCESSING_POWER_OBJECT(src) ..() @@ -49,7 +49,7 @@ return else if (mode == 2) - processing_objects.Remove(src) // Now the power sink actually stops draining the station's power if you unhook it. --NeoFite + STOP_PROCESSING(SSobj, src) // Now the power sink actually stops draining the station's power if you unhook it. --NeoFite STOP_PROCESSING_POWER_OBJECT(src) anchored = 0 mode = 0 @@ -73,14 +73,14 @@ src.visible_message("[user] activates [src]!") mode = 2 icon_state = "powersink1" - processing_objects.Add(src) + START_PROCESSING(SSobj, src) START_PROCESSING_POWER_OBJECT(src) if(2) //This switch option wasn't originally included. It exists now. --NeoFite src.visible_message("[user] deactivates [src]!") mode = 1 set_light(0) icon_state = "powersink0" - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) STOP_PROCESSING_POWER_OBJECT(src) /obj/item/device/powersink/pwr_drain() diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index a67a2bef7b..51d7e0a4b6 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -92,7 +92,7 @@ syndie = 1 ks1type = /obj/item/device/encryptionkey/raider -/obj/item/device/radio/headset/raider/initialize() +/obj/item/device/radio/headset/raider/Initialize() . = ..() set_frequency(RAID_FREQ) diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm index d462b670f9..571fd5f39d 100644 --- a/code/game/objects/items/devices/radio/intercom.dm +++ b/code/game/objects/items/devices/radio/intercom.dm @@ -54,13 +54,13 @@ /obj/item/device/radio/intercom/omni name = "global announcer" -/obj/item/device/radio/intercom/omni/initialize() +/obj/item/device/radio/intercom/omni/Initialize() channels = radiochannels.Copy() return ..() /obj/item/device/radio/intercom/New() ..() - processing_objects += src + START_PROCESSING(SSobj, src) circuit = new circuit(src) /obj/item/device/radio/intercom/department/medbay/New() @@ -104,7 +104,7 @@ internal_channels[num2text(RAID_FREQ)] = list(access_syndicate) /obj/item/device/radio/intercom/Destroy() - processing_objects -= src + STOP_PROCESSING(SSobj, src) return ..() /obj/item/device/radio/intercom/attack_ai(mob/user as mob) diff --git a/code/game/objects/items/devices/radio/jammer.dm b/code/game/objects/items/devices/radio/jammer.dm index b129657d19..4a57f855ee 100644 --- a/code/game/objects/items/devices/radio/jammer.dm +++ b/code/game/objects/items/devices/radio/jammer.dm @@ -44,7 +44,7 @@ var/global/list/active_radio_jammers = list() /obj/item/device/radio_jammer/proc/turn_off(mob/user) if(user) to_chat(user,"\The [src] deactivates.") - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) active_radio_jammers -= src on = FALSE update_icon() @@ -52,7 +52,7 @@ var/global/list/active_radio_jammers = list() /obj/item/device/radio_jammer/proc/turn_on(mob/user) if(user) to_chat(user,"\The [src] is now active.") - processing_objects.Add(src) + START_PROCESSING(SSobj, src) active_radio_jammers += src on = TRUE update_icon() diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 9e03e7ff63..67eb06a33a 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -81,7 +81,7 @@ var/global/list/default_medbay_channels = list( return ..() -/obj/item/device/radio/initialize() +/obj/item/device/radio/Initialize() . = ..() if(frequency < RADIO_LOW_FREQ || frequency > RADIO_HIGH_FREQ) frequency = sanitize_frequency(frequency, RADIO_LOW_FREQ, RADIO_HIGH_FREQ) @@ -122,7 +122,7 @@ var/global/list/default_medbay_channels = list( if(syndie) data["useSyndMode"] = 1 - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if(!ui) ui = new(user, src, ui_key, "radio_basic.tmpl", "[name]", 400, 430) ui.set_initial_data(data) @@ -233,7 +233,7 @@ var/global/list/default_medbay_channels = list( return 1 if(.) - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) /obj/item/device/radio/proc/autosay(var/message, var/from, var/channel) //BS12 EDIT var/datum/radio_frequency/connection = null @@ -725,7 +725,7 @@ var/global/list/default_medbay_channels = list( . = 1 if(.) - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) /obj/item/device/radio/borg/interact(mob/user as mob) if(!on) @@ -754,7 +754,7 @@ var/global/list/default_medbay_channels = list( data["has_subspace"] = 1 data["subspace"] = subspace_transmission - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if(!ui) ui = new(user, src, ui_key, "radio_basic.tmpl", "[name]", 400, 430) ui.set_initial_data(data) diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index feed24510b..8d4b4928ac 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -410,25 +410,28 @@ HALOGEN COUNTER - Radcount on mobs var/details = 0 var/recent_fail = 0 -/obj/item/device/reagent_scanner/afterattack(obj/O, mob/user as mob, proximity) +/obj/item/device/reagent_scanner/afterattack(obj/O, mob/living/user, proximity) if(!proximity || user.stat || !istype(O)) return - if (!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey") - to_chat(user, "You don't have the dexterity to do this!") + if(!istype(user)) return if(!isnull(O.reagents)) + if(!(O.flags & OPENCONTAINER)) // The idea is that the scanner has to touch the reagents somehow. This is done to prevent cheesing unidentified autoinjectors. + to_chat(user, span("warning", "\The [O] is sealed, and cannot be scanned by \the [src] until unsealed.")) + return + var/dat = "" if(O.reagents.reagent_list.len > 0) var/one_percent = O.reagents.total_volume / 100 for (var/datum/reagent/R in O.reagents.reagent_list) - dat += "\n \t [R][details ? ": [R.volume / one_percent]%" : ""]" + dat += "\n \t " + span("notice", "[R][details ? ": [R.volume / one_percent]%" : ""]") if(dat) - to_chat(user, "Chemicals found: [dat]") + to_chat(user, span("notice", "Chemicals found: [dat]")) else - to_chat(user, "No active chemical agents found in [O].") + to_chat(user, span("notice", "No active chemical agents found in [O].")) else - to_chat(user, "No significant chemical agents found in [O].") + to_chat(user, span("notice", "No significant chemical agents found in [O].")) return @@ -451,15 +454,15 @@ HALOGEN COUNTER - Radcount on mobs matter = list(DEFAULT_WALL_MATERIAL = 30,"glass" = 20) /obj/item/device/slime_scanner/attack(mob/living/M as mob, mob/living/user as mob) - if(!isslime(M)) - to_chat(user, "This device can only scan slimes!") + if(!istype(M, /mob/living/simple_mob/slime/xenobio)) + to_chat(user, "This device can only scan lab-grown slimes!") return - var/mob/living/simple_animal/slime/S = M + var/mob/living/simple_mob/slime/xenobio/S = M user.show_message("Slime scan results:
[S.slime_color] [S.is_adult ? "adult" : "baby"] slime
Health: [S.health]
Mutation Probability: [S.mutation_chance]") var/list/mutations = list() for(var/potential_color in S.slime_mutation) - var/mob/living/simple_animal/slime/slime = potential_color + var/mob/living/simple_mob/slime/xenobio/slime = potential_color mutations.Add(initial(slime.slime_color)) user.show_message("Potental to mutate into [english_list(mutations)] colors.
Extract potential: [S.cores]
Nutrition: [S.nutrition]/[S.get_max_nutrition()]") @@ -469,12 +472,14 @@ HALOGEN COUNTER - Radcount on mobs user.show_message("Warning: Subject is hungry.") user.show_message("Electric change strength: [S.power_charge]") - if(S.resentment) - user.show_message("Warning: Subject is harboring resentment.") - if(S.docile) + if(S.has_AI()) + var/datum/ai_holder/simple_mob/xenobio_slime/AI = S.ai_holder + if(AI.resentment) + user.show_message("Warning: Subject is harboring resentment.") + if(AI.rabid) + user.show_message("Subject is enraged and extremely dangerous!") + if(S.harmless) user.show_message("Subject has been pacified.") - if(S.rabid) - user.show_message("Subject is enraged and extremely dangerous!") if(S.unity) user.show_message("Subject is friendly to other slime colors.") diff --git a/code/game/objects/items/devices/suit_cooling.dm b/code/game/objects/items/devices/suit_cooling.dm index 6efc045785..98df7bcae1 100644 --- a/code/game/objects/items/devices/suit_cooling.dm +++ b/code/game/objects/items/devices/suit_cooling.dm @@ -30,7 +30,7 @@ toggle(usr) /obj/item/device/suit_cooling_unit/New() - processing_objects |= src + START_PROCESSING(SSobj, src) cell = new/obj/item/weapon/cell/high() //comes not with the crappy default power cell - because this is dedicated EVA equipment cell.loc = src @@ -46,7 +46,9 @@ var/mob/living/carbon/human/H = loc - var/efficiency = 1 - H.get_pressure_weakness() // You need to have a good seal for effective cooling + var/turf/T = get_turf(src) + var/datum/gas_mixture/environment = T.return_air() + var/efficiency = 1 - H.get_pressure_weakness(environment.return_pressure()) // You need to have a good seal for effective cooling var/temp_adj = 0 // How much the unit cools you. Adjusted later on. var/env_temp = get_environment_temperature() // This won't save you from a fire var/thermal_protection = H.get_heat_protection(env_temp) // ... unless you've got a good suit. diff --git a/code/game/objects/items/devices/t_scanner.dm b/code/game/objects/items/devices/t_scanner.dm index 5610828bfe..0709429ac1 100644 --- a/code/game/objects/items/devices/t_scanner.dm +++ b/code/game/objects/items/devices/t_scanner.dm @@ -28,10 +28,10 @@ /obj/item/device/t_scanner/proc/set_active(var/active) on = active if(on) - processing_objects.Add(src) + START_PROCESSING(SSobj, src) flicker = 0 else - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) set_user_client(null) update_icon() diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm index 8abc2eabc2..ccd339e180 100644 --- a/code/game/objects/items/devices/transfer_valve.dm +++ b/code/game/objects/items/devices/transfer_valve.dm @@ -37,7 +37,7 @@ log_game("[key_name_admin(user)] attached both tanks to a transfer valve.") update_icon() - GLOB.nanomanager.update_uis(src) // update all UIs attached to src + SSnanoui.update_uis(src) // update all UIs attached to src //TODO: Have this take an assemblyholder else if(isassembly(item)) var/obj/item/device/assembly/A = item @@ -58,7 +58,7 @@ message_admins("[key_name_admin(user)] attached a [item] to a transfer valve. (JMP)") log_game("[key_name_admin(user)] attached a [item] to a transfer valve.") attacher = user - GLOB.nanomanager.update_uis(src) // update all UIs attached to src + SSnanoui.update_uis(src) // update all UIs attached to src return @@ -81,7 +81,7 @@ data["valveOpen"] = valve_open ? 1 : 0 // update the ui if it exists, returns null if no ui is passed/found - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.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 diff --git a/code/game/objects/items/devices/tvcamera.dm b/code/game/objects/items/devices/tvcamera.dm index be2b4c18e7..3fdaa5e79f 100644 --- a/code/game/objects/items/devices/tvcamera.dm +++ b/code/game/objects/items/devices/tvcamera.dm @@ -26,7 +26,7 @@ to_chat(usr, "Video feed is [camera.status ? "on" : "off"]") to_chat(usr, "Audio feed is [radio.broadcasting ? "on" : "off"]") -/obj/item/device/tvcamera/initialize() +/obj/item/device/tvcamera/Initialize() . = ..() camera = new(src) camera.c_tag = channel diff --git a/code/game/objects/items/devices/uplink.dm b/code/game/objects/items/devices/uplink.dm index 2778f46b03..ea7006a73b 100644 --- a/code/game/objects/items/devices/uplink.dm +++ b/code/game/objects/items/devices/uplink.dm @@ -28,11 +28,11 @@ uses = owner.tcrystals else uses = telecrystals - processing_objects += src + START_PROCESSING(SSobj, src) /obj/item/device/uplink/Destroy() world_uplinks -= src - processing_objects -= src + STOP_PROCESSING(SSobj, src) return ..() /obj/item/device/uplink/get_item_cost(var/item_type, var/item_cost) @@ -72,7 +72,7 @@ discount_amount = pick(90;0.9, 80;0.8, 70;0.7, 60;0.6, 50;0.5, 40;0.4, 30;0.3, 20;0.2, 10;0.1) next_offer_time = world.time + offer_time update_nano_data() - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) // Toggles the uplink on and off. Normally this will bypass the item's normal functions and go to the uplink menu, if activated. /obj/item/device/uplink/hidden/proc/toggle() @@ -110,7 +110,7 @@ data += nanoui_data // update the ui if it exists, returns null if no ui is passed/found - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) // No auto-refresh ui = new(user, src, ui_key, "uplink.tmpl", title, 450, 600, state = inventory_state) data["menu"] = 0 @@ -138,7 +138,7 @@ UI.buy(src, usr) else if(href_list["lock"]) toggle() - var/datum/nanoui/ui = GLOB.nanomanager.get_open_ui(user, src, "main") + var/datum/nanoui/ui = SSnanoui.get_open_ui(user, src, "main") ui.close() else if(href_list["return"]) nanoui_menu = round(nanoui_menu/10) diff --git a/code/game/objects/items/glassjar.dm b/code/game/objects/items/glassjar.dm index c04b9b17dd..2e73e89e67 100644 --- a/code/game/objects/items/glassjar.dm +++ b/code/game/objects/items/glassjar.dm @@ -6,7 +6,7 @@ w_class = ITEMSIZE_SMALL matter = list("glass" = 200) flags = NOBLUDGEON - var/list/accept_mobs = list(/mob/living/simple_animal/lizard, /mob/living/simple_animal/mouse) + var/list/accept_mobs = list(/mob/living/simple_mob/animal/passive/lizard, /mob/living/simple_mob/animal/passive/mouse) var/contains = 0 // 0 = nothing, 1 = money, 2 = animal, 3 = spiderling /obj/item/glass_jar/New() @@ -34,7 +34,7 @@ var/obj/effect/spider/spiderling/S = A user.visible_message("[user] scoops [S] into \the [src].", "You scoop [S] into \the [src].") S.loc = src - processing_objects.Remove(S) // No growing inside jars + STOP_PROCESSING(SSobj, S) // No growing inside jars contains = 3 update_icon() return @@ -59,7 +59,7 @@ for(var/obj/effect/spider/spiderling/S in src) S.loc = user.loc user.visible_message("[user] releases [S] from \the [src].", "You release [S] from \the [src].") - processing_objects.Add(S) // They can grow after being let out though + START_PROCESSING(SSobj, S) // They can grow after being let out though contains = 0 update_icon() return diff --git a/code/game/objects/items/godfigures.dm b/code/game/objects/items/godfigures.dm new file mode 100644 index 0000000000..b1b1e7a4aa --- /dev/null +++ b/code/game/objects/items/godfigures.dm @@ -0,0 +1,131 @@ +/obj/item/godfig + name = "religious icon" + desc = "A painted holy figure of a plain looking human man in a robe." + description_info = "Right click to select a new sprite to fit your needs." + icon = 'icons/obj/chaplain.dmi' + icon_state = "mrobe" + force = 10 + throw_speed = 1 + throw_range = 4 + throwforce = 10 + w_class = ITEMSIZE_SMALL + + +/obj/item/godfig/verb/resprite_figure() + set name = "Customize Figure" + set category = "Object" + set desc = "Click to choose an appearance for your icon." + + var/mob/M = usr + var/list/options = list() + options["Painted - Robed Human Female"] = "frobe" + options["Painted - Robed Human Male (Pale)"] = "mrobe" + options["Painted - Robed Human Male (Dark)"] = "mrobedark" + options["Painted - Bearded Human"] = "mpose" + options["Painted - Human Male Warrior"] = "mwarrior" + options["Painted - Human Female Warrior"] = "fwarrior" + options["Painted - Human Male Hammer"] = "hammer" + options["Painted - Horned God"] = "horned" + options["Obsidian - Human Male"] = "onyxking" + options["Obsidian - Human Female"] = "onyxqueen" + options["Obsidian - Animal Headed Male"] = "onyxanimalm" + options["Obsidian - Animal Headed Female"] = "onyxanimalf" + options["Obsidian - Bird Headed Figure"] = "onyxbird" + options["Stone - Seated Figure"] = "stoneseat" + options["Stone - Head"] = "stonehead" + options["Stone - Dwarf"] = "stonedwarf" + options["Stone - Animal"] = "stoneanimal" + options["Stone - Fertility"] = "stonevenus" + options["Stone - Snake"] = "stonesnake" + options["Bronze - Elephantine"] = "elephant" + options["Bronze - Many-armed"] = "bronzearms" + options["Robot"] = "robot" + options["Singularity"] = "singularity" + options["Gemstone Eye"] = "gemeye" + options["Golden Skull"] = "skull" + options["Goatman"] = "devil" + options["Sun Gem"] = "sun" + options["Moon Gem"] = "moon" + options["Tajaran Figure"] = "catrobe" + + var/choice = input(M,"Choose your icon!","Customize Figure") in options + if(src && choice && !M.stat && in_range(M,src)) + icon_state = options[choice] + if(options[choice] == "frobe") + desc = "A painted holy figure of a plain looking human woman in a robe." + else if(options[choice] == "mrobe") + desc = "A painted holy figure of a plain looking human man in a robe." + else if(options[choice] == "mrobedark") + desc = "A painted holy figure of a plain looking human man in a robe.." + else if(options[choice] == "mpose") + desc = "A painted holy figure of a rather grandiose bearded human." + else if(options[choice] == "mwarrior") + desc = "A painted holy figure of a powerful human male warrior." + else if(options[choice] == "fwarrior") + desc = "A painted holy figure of a powerful human female warrior." + else if(options[choice] == "hammer") + desc = "A painted holy figure of a human holding a hammer aloft." + else if(options[choice] == "horned") + desc = "A painted holy figure of a human man crowned with antlers." + else if(options[choice] == "onyxking") + desc = "An obsidian holy figure of a human man wearing a grand hat." + else if(options[choice] == "onyxqueen") + desc = "An obsidian holy figure of a human woman wearing a grand hat." + else if(options[choice] == "onyxanimalm") + desc = "An obsidian holy figure of a human man with the head of an animal." + else if(options[choice] == "onyxanimalf") + desc = "An obsidian holy figure of a human woman with the head of an animal." + else if(options[choice] == "onyxbird") + desc = "An obsidian holy figure of a human with the head of a bird." + else if(options[choice] == "stoneseat") + desc = "A stone holy figure of a cross-legged human." + else if(options[choice] == "stonehead") + desc = "A stone holy figure of an imposing crowned head." + else if(options[choice] == "stonedwarf") + desc = "A stone holy figure of a somewhat ugly dwarf." + else if(options[choice] == "stoneanimal") + desc = "A stone holy figure of a four-legged animal of some sort." + else if(options[choice] == "stonevenus") + desc = "A stone holy figure of a lovingly rendered pregnant woman." + else if(options[choice] == "stonesnake") + desc = "A stone holy figure of a coiled snake ready to strike." + else if(options[choice] == "elephant") + desc = "A bronze holy figure of a dancing human with the head of an elephant." + else if(options[choice] == "bronzearms") + desc = "A bronze holy figure of a human.with four arms." + else if(options[choice] == "robot") + desc = "A titanium holy figure of a synthetic humanoid." + else if(options[choice] == "singularity") + desc = "A holy figure of some kind of energy formation." + else if(options[choice] == "gemeye") + desc = "A gemstone holy figure of a sparkling eye." + else if(options[choice] == "skull") + desc = "A golden holy figure of a humanoid skull." + else if(options[choice] == "devil") + desc = "A painted holy figure of a seated humanoid goat with wings." + else if(options[choice] == "sun") + desc = "A holy figure of a star." + else if(options[choice] == "moon") + desc = "A holy figure of a small planetoid." + else if(options[choice] == "catrobe") + desc = "A painted holy figure of a plain looking Tajaran in a robe." + + M << "The religious icon is now a [choice]. All hail!" + return 1 + + + +/obj/item/godfig/verb/rename_fig() + set name = "Name Figure" + set category = "Object" + set desc = "Rename your icon." + + var/mob/M = usr + if(!M.mind) return 0 + + var/input = sanitizeSafe(input("What do you want to name the icon?", ,""), MAX_NAME_LEN) + + if(src && input && !M.stat && in_range(M,src)) + name = "icon of " + input + M << "You name the figure. Glory to [input]!." + return 1 \ No newline at end of file diff --git a/code/game/objects/items/latexballoon.dm b/code/game/objects/items/latexballoon.dm index 707a38a284..559bfbec0d 100644 --- a/code/game/objects/items/latexballoon.dm +++ b/code/game/objects/items/latexballoon.dm @@ -25,7 +25,7 @@ /obj/item/latexballon/proc/burst() if (!air_contents) return - playsound(src, 'sound/weapons/Gunshot.ogg', 100, 1) + playsound(src, 'sound/weapons/Gunshot_old.ogg', 100, 1) icon_state = "latexballon_bursted" item_state = "lgloves" loc.assume_air(air_contents) diff --git a/code/game/objects/items/poi_items.dm b/code/game/objects/items/poi_items.dm index af1b6c9c7a..6fd6d7debd 100644 --- a/code/game/objects/items/poi_items.dm +++ b/code/game/objects/items/poi_items.dm @@ -9,14 +9,14 @@ desc = "The top of this twisted chunk of metal is faintly stamped with a five pointed star. 'Property of US Army, Pascal B - 1957'." /obj/item/poi/pascalb/New() - processing_objects += src + START_PROCESSING(SSobj, src) return ..() /obj/item/poi/pascalb/process() radiation_repository.radiate(src, 5) /obj/item/poi/pascalb/Destroy() - processing_objects -= src + STOP_PROCESSING(SSobj, src) return ..() /obj/structure/closet/crate/oldreactor @@ -37,24 +37,13 @@ desc = "This broken hunk of machinery looks extremely dangerous." /obj/item/poi/brokenoldreactor/New() - processing_objects += src + START_PROCESSING(SSobj, src) return ..() /obj/item/poi/brokenoldreactor/process() radiation_repository.radiate(src, 25) /obj/item/poi/brokenoldreactor/Destroy() - processing_objects -= src + STOP_PROCESSING(SSobj, src) return ..() - -//Crashed Cargo Shuttle PoI - -/obj/structure/largecrate/animal/crashedshuttle - name = "SCP" - -/obj/structure/largecrate/animal/crashedshuttle/initialize() - starts_with = list(pick(/mob/living/simple_animal/hostile/statue, /obj/item/cursed_marble, /obj/item/weapon/deadringer)) // Starts_with has to be a list - name = pick("Spicy Crust Pizzeria", "Soap and Care Products", "Sally's Computer Parts", "Steve's Chocolate Pastries", "Smith & Christian's Plastics","Standard Containers & Packaging Co.", "Sanitary Chemical Purgation (LTD)") - name += " delivery crate" - return ..() diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index 2fa9ea63c7..180e261fc2 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -275,13 +275,6 @@ add_flashes(W,user) else add_flashes(W,user) - else if(istype(W, /obj/item/weapon/stock_parts/manipulator)) - to_chat(user, "You install some manipulators and modify the head, creating a functional spider-bot!") - new /mob/living/simple_animal/spiderbot(get_turf(loc)) - user.drop_item() - qdel(W) - qdel(src) - return return /obj/item/robot_parts/head/proc/add_flashes(obj/item/W as obj, mob/user as mob) //Made into a seperate proc to avoid copypasta diff --git a/code/game/objects/items/stacks/marker_beacons.dm b/code/game/objects/items/stacks/marker_beacons.dm index f252ecae06..93462c640e 100644 --- a/code/game/objects/items/stacks/marker_beacons.dm +++ b/code/game/objects/items/stacks/marker_beacons.dm @@ -37,7 +37,7 @@ var/list/marker_beacon_colors = list( /obj/item/stack/marker_beacon/hundred amount = 100 -/obj/item/stack/marker_beacon/initialize() +/obj/item/stack/marker_beacon/Initialize() . = ..() update_icon() diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm index 8d82ffc8d1..53dc72faaa 100644 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ b/code/game/objects/items/stacks/sheets/glass.dm @@ -14,9 +14,7 @@ name = "glass" singular_name = "glass sheet" icon_state = "sheet-glass" - var/created_window = /obj/structure/window/basic var/is_reinforced = 0 - var/list/construction_options = list("One Direction", "Full Window") default_type = "glass" /obj/item/stack/material/glass/attack_self(mob/user as mob) @@ -52,75 +50,7 @@ if (!G && replace) user.put_in_hands(RG) -/obj/item/stack/material/glass/proc/construct_window(mob/user as mob) - if(!user || !src) return 0 - if(!istype(user.loc,/turf)) return 0 - if(!user.IsAdvancedToolUser()) - return 0 - var/title = "Sheet-[name]" - title += " ([src.get_amount()] sheet\s left)" - switch(input(title, "What would you like to construct?") as null|anything in construction_options) - if("One Direction") - if(!src) return 1 - if(src.loc != user) return 1 - var/list/directions = new/list(cardinal) - var/i = 0 - for (var/obj/structure/window/win in user.loc) - i++ - if(i >= 4) - user << "There are too many windows in this location." - return 1 - directions-=win.dir - if(!(win.dir in cardinal)) - user << "Can't let you do that." - return 1 - - //Determine the direction. It will first check in the direction the person making the window is facing, if it finds an already made window it will try looking at the next cardinal direction, etc. - var/dir_to_set = 2 - for(var/direction in list( user.dir, turn(user.dir,90), turn(user.dir,180), turn(user.dir,270) )) - var/found = 0 - for(var/obj/structure/window/WT in user.loc) - if(WT.dir == direction) - found = 1 - if(!found) - dir_to_set = direction - break - new created_window( user.loc, dir_to_set, 1 ) - src.use(1) - if("Full Window") - if(!src) return 1 - if(src.loc != user) return 1 - if(src.get_amount() < 4) - user << "You need more glass to do that." - return 1 - if(locate(/obj/structure/window) in user.loc) - user << "There is a window in the way." - return 1 - new created_window( user.loc, SOUTHWEST, 1 ) - src.use(4) - if("Windoor") - if(!is_reinforced) return 1 - - - if(!src || src.loc != user) return 1 - - if(isturf(user.loc) && locate(/obj/structure/windoor_assembly/, user.loc)) - user << "There is already a windoor assembly in that location." - return 1 - - if(isturf(user.loc) && locate(/obj/machinery/door/window/, user.loc)) - user << "There is already a windoor in that location." - return 1 - - if(src.get_amount() < 5) - user << "You need more glass to do that." - return 1 - - new /obj/structure/windoor_assembly(user.loc, user.dir, 1) - src.use(5) - - return 0 /* @@ -131,9 +61,7 @@ singular_name = "reinforced glass sheet" icon_state = "sheet-rglass" default_type = "reinforced glass" - created_window = /obj/structure/window/reinforced is_reinforced = 1 - construction_options = list("One Direction", "Full Window", "Windoor") /* * Phoron Glass sheets @@ -142,7 +70,6 @@ name = "phoron glass" singular_name = "phoron glass sheet" icon_state = "sheet-phoronglass" - created_window = /obj/structure/window/phoronbasic default_type = "phoron glass" /obj/item/stack/material/glass/phoronglass/attackby(obj/item/W, mob/user) @@ -170,5 +97,4 @@ singular_name = "reinforced phoron glass sheet" icon_state = "sheet-phoronrglass" default_type = "reinforced phoron glass" - created_window = /obj/structure/window/phoronreinforced is_reinforced = 1 diff --git a/code/game/objects/items/weapons/AI_modules.dm b/code/game/objects/items/weapons/AI_modules.dm old mode 100755 new mode 100644 index c5b637d9e5..13c4b29d45 --- a/code/game/objects/items/weapons/AI_modules.dm +++ b/code/game/objects/items/weapons/AI_modules.dm @@ -23,7 +23,7 @@ AI MODULES /obj/item/weapon/aiModule/proc/install(var/atom/movable/AM, var/mob/living/user) if(!user.IsAdvancedToolUser() && isanimal(user)) - var/mob/living/simple_animal/S = user + var/mob/living/simple_mob/S = user if(!S.IsHumanoidToolUser(src)) return 0 diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm index a0587d5dbb..64f0ebab5e 100644 --- a/code/game/objects/items/weapons/RCD.dm +++ b/code/game/objects/items/weapons/RCD.dm @@ -28,7 +28,7 @@ var/material_to_use = DEFAULT_WALL_MATERIAL // So badmins can make RCDs that print diamond walls. var/make_rwalls = FALSE // If true, when building walls, they will be reinforced. -/obj/item/weapon/rcd/initialize() +/obj/item/weapon/rcd/Initialize() src.spark_system = new /datum/effect/effect/system/spark_spread spark_system.set_up(5, 0, src) spark_system.attach(src) @@ -137,7 +137,7 @@ // RCD variants. // This one starts full. -/obj/item/weapon/rcd/loaded/initialize() +/obj/item/weapon/rcd/loaded/Initialize() stored_matter = max_stored_matter return ..() @@ -148,7 +148,7 @@ used in the construction of hulls for starships. Reload with compressed matter cartridges." material_to_use = MAT_STEELHULL -/obj/item/weapon/rcd/shipwright/loaded/initialize() +/obj/item/weapon/rcd/shipwright/loaded/Initialize() stored_matter = max_stored_matter return ..() @@ -162,7 +162,7 @@ toolspeed = 0.5 // Twice as fast. max_stored_matter = RCD_MAX_CAPACITY * 3 // Three times capacity. -/obj/item/weapon/rcd/advanced/loaded/initialize() +/obj/item/weapon/rcd/advanced/loaded/Initialize() stored_matter = max_stored_matter return ..() @@ -179,7 +179,7 @@ var/make_cell = TRUE // If false, initialize() won't spawn a cell for this. var/electric_cost_coefficent = 83.33 // Higher numbers make it less efficent. 86.3... means it should matche the standard RCD capacity on a 10k cell. -/obj/item/weapon/rcd/electric/initialize() +/obj/item/weapon/rcd/electric/Initialize() if(make_cell) cell = new /obj/item/weapon/cell/high(src) return ..() diff --git a/code/game/objects/items/weapons/candle.dm b/code/game/objects/items/weapons/candle.dm index 3f861b86d4..18cb433ded 100644 --- a/code/game/objects/items/weapons/candle.dm +++ b/code/game/objects/items/weapons/candle.dm @@ -1,11 +1,12 @@ /obj/item/weapon/flame/candle name = "red candle" - desc = "a small pillar candle. Its specially-formulated fuel-oxidizer wax mixture allows continued combustion in airless environments." + desc = "a red pillar candle. Its specially-formulated fuel-oxidizer wax mixture allows continued combustion in airless environments." icon = 'icons/obj/candle.dmi' icon_state = "candle1" w_class = ITEMSIZE_TINY light_color = "#E09D37" var/wax = 2000 + var/icon_type = "candle" /obj/item/weapon/flame/candle/New() wax -= rand(800, 1000) // Enough for 27-33 minutes. 30 minutes on average. @@ -18,7 +19,7 @@ else if(wax > 800) i = 2 else i = 3 - icon_state = "candle[i][lit ? "_lit" : ""]" + icon_state = "[icon_type][i][lit ? "_lit" : ""]" /obj/item/weapon/flame/candle/attackby(obj/item/weapon/W as obj, mob/user as mob) @@ -46,7 +47,7 @@ lit = TRUE visible_message(flavor_text) set_light(CANDLE_LUM) - processing_objects.Add(src) + START_PROCESSING(SSobj, src) /obj/item/weapon/flame/candle/process() if(!lit) @@ -68,6 +69,30 @@ update_icon() set_light(0) +/obj/item/weapon/flame/candle/small + name = "small red candle" + desc = "a small red candle, for more intimate candle occasions." + icon = 'icons/obj/candle.dmi' + icon_state = "smallcandle" + icon_type = "smallcandle" + w_class = ITEMSIZE_SMALL + +/obj/item/weapon/flame/candle/white + name = "white candle" + desc = "a white pillar candle. Its specially-formulated fuel-oxidizer wax mixture allows continued combustion in airless environments." + icon = 'icons/obj/candle.dmi' + icon_state = "whitecandle" + icon_type = "whitecandle" + w_class = ITEMSIZE_SMALL + +/obj/item/weapon/flame/candle/black + name = "black candle" + desc = "a black pillar candle. Ominous." + icon = 'icons/obj/candle.dmi' + icon_state = "blackcandle" + icon_type = "blackcandle" + w_class = ITEMSIZE_SMALL + /obj/item/weapon/flame/candle/candelabra name = "candelabra" desc = "a small gold candelabra. The cups that hold the candles save some of the wax from dripping off, allowing the candles to burn longer." @@ -85,13 +110,13 @@ /obj/item/weapon/flame/candle/everburn wax = 99999 -/obj/item/weapon/flame/candle/everburn/initialize() +/obj/item/weapon/flame/candle/everburn/Initialize() . = ..() light("\The [src] mysteriously lights itself!.") /obj/item/weapon/flame/candle/candelabra/everburn wax = 99999 -/obj/item/weapon/flame/candle/candelabra/everburn/initialize() +/obj/item/weapon/flame/candle/candelabra/everburn/Initialize() . = ..() light("\The [src] mysteriously lights itself!.") diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm index 5d60c8485b..e4082b3352 100644 --- a/code/game/objects/items/weapons/cigs_lighters.dm +++ b/code/game/objects/items/weapons/cigs_lighters.dm @@ -67,7 +67,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM item_state = "cigoff" name = "burnt match" desc = "A match. This one has seen better days." - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) ////////////////// //FINE SMOKABLES// @@ -91,8 +91,8 @@ CIGARETTE PACKETS ARE IN FANCY.DM var/brand blood_sprite_state = null //Can't bloody these -/obj/item/clothing/mask/smokable/New() - ..() +/obj/item/clothing/mask/smokable/Initialize() + . = ..() flags |= NOREACT // so it doesn't react until you light it create_reagents(chem_volume) // making the cigarrete a chemical holder with a maximum volume of 15 if(smoketime && !max_smoketime) @@ -177,12 +177,12 @@ CIGARETTE PACKETS ARE IN FANCY.DM T.visible_message(flavor_text) update_icon() set_light(2, 0.25, "#E38F46") - processing_objects.Add(src) + START_PROCESSING(SSobj, src) /obj/item/clothing/mask/smokable/proc/die(var/nomessage = 0) var/turf/T = get_turf(src) set_light(0) - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) if (type_butt) var/obj/item/butt = new type_butt(T) transfer_fingerprints_to(butt) @@ -215,7 +215,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM /obj/item/clothing/mask/smokable/proc/quench() lit = 0 - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) update_icon() /obj/item/clothing/mask/smokable/attack(mob/living/carbon/human/H, mob/user, def_zone) @@ -280,8 +280,8 @@ CIGARETTE PACKETS ARE IN FANCY.DM weldermes = "USER casually lights the NAME with FLAME." ignitermes = "USER fiddles with FLAME, and manages to light their NAME." -/obj/item/clothing/mask/smokable/cigarette/New() - ..() +/obj/item/clothing/mask/smokable/cigarette/Initialize() + . = ..() if(nicotine_amt) reagents.add_reagent("nicotine", nicotine_amt) @@ -363,8 +363,8 @@ CIGARETTE PACKETS ARE IN FANCY.DM slot_flags = SLOT_EARS throwforce = 1 -/obj/item/weapon/cigbutt/New() - ..() +/obj/item/weapon/cigbutt/Initialize() + . = ..() pixel_x = rand(-10,10) pixel_y = rand(-10,10) transform = turn(transform,rand(0,360)) @@ -541,7 +541,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM user.visible_message("After a few attempts, [user] manages to light the [src], they however burn their finger in the process.") set_light(2) - processing_objects.Add(src) + START_PROCESSING(SSobj, src) else lit = 0 icon_state = "[base_state]" @@ -552,7 +552,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM user.visible_message("[user] quietly shuts off the [src].") set_light(0) - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) return diff --git a/code/game/objects/items/weapons/clown_items.dm b/code/game/objects/items/weapons/clown_items.dm index 7124cb489f..cb6a4e4a42 100644 --- a/code/game/objects/items/weapons/clown_items.dm +++ b/code/game/objects/items/weapons/clown_items.dm @@ -15,11 +15,11 @@ /* * Soap */ -/obj/item/weapon/soap/New() - ..() +/obj/item/weapon/soap/Initialize() + . = ..() create_reagents(5) wet() - + /obj/item/weapon/soap/proc/wet() reagents.add_reagent("cleaner", 5) diff --git a/code/game/objects/items/weapons/explosives.dm b/code/game/objects/items/weapons/explosives.dm index 5290ac7479..86e3badc6f 100644 --- a/code/game/objects/items/weapons/explosives.dm +++ b/code/game/objects/items/weapons/explosives.dm @@ -37,7 +37,7 @@ /obj/item/weapon/plastique/attack_self(mob/user as mob) var/newtime = input(usr, "Please set the timer.", "Timer", 10) as num if(user.get_active_hand() == src) - newtime = Clamp(newtime, 10, 60000) + newtime = CLAMP(newtime, 10, 60000) timer = newtime user << "Timer set for [timer] seconds." diff --git a/code/game/objects/items/weapons/extinguisher.dm b/code/game/objects/items/weapons/extinguisher.dm index eba48464f0..06649d7982 100644 --- a/code/game/objects/items/weapons/extinguisher.dm +++ b/code/game/objects/items/weapons/extinguisher.dm @@ -34,22 +34,20 @@ spray_particles = 3 sprite_name = "miniFE" -/obj/item/weapon/extinguisher/New() +/obj/item/weapon/extinguisher/Initialize() create_reagents(max_water) reagents.add_reagent("water", max_water) - ..() + . = ..() /obj/item/weapon/extinguisher/examine(mob/user) if(..(user, 0)) - user << text("\icon[] [] contains [] units of water left!", src, src.name, src.reagents.total_volume) - return + to_chat(user, text("\icon[] [] contains [] units of water left!", src, src.name, src.reagents.total_volume)) /obj/item/weapon/extinguisher/attack_self(mob/user as mob) safety = !safety - src.icon_state = "[sprite_name][!safety]" - src.desc = "The safety is [safety ? "on" : "off"]." - user << "The safety is [safety ? "on" : "off"]." - return + icon_state = "[sprite_name][!safety]" + desc = "The safety is [safety ? "on" : "off"]." + to_chat(user, "The safety is [safety ? "on" : "off"].") /obj/item/weapon/extinguisher/proc/propel_object(var/obj/O, mob/user, movementdirection) if(O.anchored) return diff --git a/code/game/objects/items/weapons/flamethrower.dm b/code/game/objects/items/weapons/flamethrower.dm index 919f8cb016..1d9a926e2e 100644 --- a/code/game/objects/items/weapons/flamethrower.dm +++ b/code/game/objects/items/weapons/flamethrower.dm @@ -34,7 +34,7 @@ /obj/item/weapon/flamethrower/process() if(!lit) - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) return null var/turf/location = loc if(istype(location, /mob/)) @@ -144,7 +144,7 @@ if(!status) return lit = !lit if(lit) - processing_objects.Add(src) + START_PROCESSING(SSobj, src) if(href_list["amount"]) throw_amount = throw_amount + text2num(href_list["amount"]) throw_amount = max(50, min(5000, throw_amount)) diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm index 442e6c3f1d..41fa67f1d5 100644 --- a/code/game/objects/items/weapons/grenades/chem_grenade.dm +++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm @@ -16,177 +16,177 @@ var/list/allowed_containers = list(/obj/item/weapon/reagent_containers/glass/beaker, /obj/item/weapon/reagent_containers/glass/bottle) var/affected_area = 3 - New() - create_reagents(1000) +/obj/item/weapon/grenade/chem_grenade/Initialize() + . = ..() + create_reagents(1000) - Destroy() - QDEL_NULL(detonator) - QDEL_NULL_LIST(beakers) - return ..() +/obj/item/weapon/grenade/chem_grenade/Destroy() + QDEL_NULL(detonator) + QDEL_LIST_NULL(beakers) + return ..() - attack_self(mob/user as mob) - if(!stage || stage==1) - if(detonator) +/obj/item/weapon/grenade/chem_grenade/attack_self(mob/user as mob) + if(!stage || stage==1) + if(detonator) // detonator.loc=src.loc - detonator.detached() - usr.put_in_hands(detonator) - detonator=null - det_time = null - stage=0 - icon_state = initial(icon_state) - else if(beakers.len) - for(var/obj/B in beakers) - if(istype(B)) - beakers -= B - user.put_in_hands(B) - name = "unsecured grenade with [beakers.len] containers[detonator?" and detonator":""]" - if(stage > 1 && !active && clown_check(user)) - to_chat(user, "You prime \the [name]!") + detonator.detached() + usr.put_in_hands(detonator) + detonator=null + det_time = null + stage=0 + icon_state = initial(icon_state) + else if(beakers.len) + for(var/obj/B in beakers) + if(istype(B)) + beakers -= B + user.put_in_hands(B) + name = "unsecured grenade with [beakers.len] containers[detonator?" and detonator":""]" + if(stage > 1 && !active && clown_check(user)) + to_chat(user, "You prime \the [name]!") - msg_admin_attack("[key_name_admin(user)] primed \a [src]") + msg_admin_attack("[key_name_admin(user)] primed \a [src]") - activate() - add_fingerprint(user) - if(iscarbon(user)) - var/mob/living/carbon/C = user - C.throw_mode_on() + activate() + add_fingerprint(user) + if(iscarbon(user)) + var/mob/living/carbon/C = user + C.throw_mode_on() - attackby(obj/item/weapon/W as obj, mob/user as mob) - - if(istype(W,/obj/item/device/assembly_holder) && (!stage || stage==1) && path != 2) - var/obj/item/device/assembly_holder/det = W - if(istype(det.a_left,det.a_right.type) || (!isigniter(det.a_left) && !isigniter(det.a_right))) - to_chat(user, "Assembly must contain one igniter.") - return - if(!det.secured) - to_chat(user, "Assembly must be secured with screwdriver.") - return +/obj/item/weapon/grenade/chem_grenade/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W,/obj/item/device/assembly_holder) && (!stage || stage==1) && path != 2) + var/obj/item/device/assembly_holder/det = W + if(istype(det.a_left,det.a_right.type) || (!isigniter(det.a_left) && !isigniter(det.a_right))) + to_chat(user, "Assembly must contain one igniter.") + return + if(!det.secured) + to_chat(user, "Assembly must be secured with screwdriver.") + return + path = 1 + to_chat(user, "You add [W] to the metal casing.") + playsound(src.loc, 'sound/items/Screwdriver2.ogg', 25, -3) + user.remove_from_mob(det) + det.loc = src + detonator = det + if(istimer(detonator.a_left)) + var/obj/item/device/assembly/timer/T = detonator.a_left + det_time = 10*T.time + if(istimer(detonator.a_right)) + var/obj/item/device/assembly/timer/T = detonator.a_right + det_time = 10*T.time + icon_state = initial(icon_state) +"_ass" + name = "unsecured grenade with [beakers.len] containers[detonator?" and detonator":""]" + stage = 1 + else if(W.is_screwdriver() && path != 2) + if(stage == 1) path = 1 - to_chat(user, "You add [W] to the metal casing.") - playsound(src.loc, 'sound/items/Screwdriver2.ogg', 25, -3) - user.remove_from_mob(det) - det.loc = src - detonator = det - if(istimer(detonator.a_left)) + if(beakers.len) + to_chat(user, "You lock the assembly.") + name = "grenade" + else +// to_chat(user, "You need to add at least one beaker before locking the assembly.") + to_chat(user, "You lock the empty assembly.") + name = "fake grenade" + playsound(src, W.usesound, 50, 1) + icon_state = initial(icon_state) +"_locked" + stage = 2 + else if(stage == 2) + if(active && prob(95)) + to_chat(user, "You trigger the assembly!") + detonate() + return + else + to_chat(user, "You unlock the assembly.") + playsound(src.loc, W.usesound, 50, -3) + name = "unsecured grenade with [beakers.len] containers[detonator?" and detonator":""]" + icon_state = initial(icon_state) + (detonator?"_ass":"") + stage = 1 + active = 0 + else if(is_type_in_list(W, allowed_containers) && (!stage || stage==1) && path != 2) + path = 1 + if(beakers.len == 2) + to_chat(user, "The grenade can not hold more containers.") + return + else + if(W.reagents.total_volume) + to_chat(user, "You add \the [W] to the assembly.") + user.drop_item() + W.loc = src + beakers += W + stage = 1 + name = "unsecured grenade with [beakers.len] containers[detonator?" and detonator":""]" + else + to_chat(user, "\The [W] is empty.") + +/obj/item/weapon/grenade/chem_grenade/examine(mob/user) + ..(user) + if(detonator) + to_chat(user, "With attached [detonator.name]") + +/obj/item/weapon/grenade/chem_grenade/activate(mob/user as mob) + if(active) return + + if(detonator) + if(!isigniter(detonator.a_left)) + detonator.a_left.activate() + active = 1 + if(!isigniter(detonator.a_right)) + detonator.a_right.activate() + active = 1 + if(active) + icon_state = initial(icon_state) + "_active" + + if(user) + msg_admin_attack("[key_name_admin(user)] primed \a [src.name]") + + return + +/obj/item/weapon/grenade/chem_grenade/proc/primed(var/primed = 1) + if(active) + icon_state = initial(icon_state) + (primed?"_primed":"_active") + +/obj/item/weapon/grenade/chem_grenade/detonate() + if(!stage || stage<2) return + + var/has_reagents = 0 + for(var/obj/item/weapon/reagent_containers/glass/G in beakers) + if(G.reagents.total_volume) has_reagents = 1 + + active = 0 + if(!has_reagents) + icon_state = initial(icon_state) +"_locked" + playsound(src.loc, 'sound/items/Screwdriver2.ogg', 50, 1) + spawn(0) //Otherwise det_time is erroneously set to 0 after this + if(istimer(detonator.a_left)) //Make sure description reflects that the timer has been reset var/obj/item/device/assembly/timer/T = detonator.a_left det_time = 10*T.time if(istimer(detonator.a_right)) var/obj/item/device/assembly/timer/T = detonator.a_right det_time = 10*T.time - icon_state = initial(icon_state) +"_ass" - name = "unsecured grenade with [beakers.len] containers[detonator?" and detonator":""]" - stage = 1 - else if(W.is_screwdriver() && path != 2) - if(stage == 1) - path = 1 - if(beakers.len) - to_chat(user, "You lock the assembly.") - name = "grenade" - else -// to_chat(user, "You need to add at least one beaker before locking the assembly.") - to_chat(user, "You lock the empty assembly.") - name = "fake grenade" - playsound(src, W.usesound, 50, 1) - icon_state = initial(icon_state) +"_locked" - stage = 2 - else if(stage == 2) - if(active && prob(95)) - to_chat(user, "You trigger the assembly!") - detonate() - return - else - to_chat(user, "You unlock the assembly.") - playsound(src.loc, W.usesound, 50, -3) - name = "unsecured grenade with [beakers.len] containers[detonator?" and detonator":""]" - icon_state = initial(icon_state) + (detonator?"_ass":"") - stage = 1 - active = 0 - else if(is_type_in_list(W, allowed_containers) && (!stage || stage==1) && path != 2) - path = 1 - if(beakers.len == 2) - to_chat(user, "The grenade can not hold more containers.") - return - else - if(W.reagents.total_volume) - to_chat(user, "You add \the [W] to the assembly.") - user.drop_item() - W.loc = src - beakers += W - stage = 1 - name = "unsecured grenade with [beakers.len] containers[detonator?" and detonator":""]" - else - to_chat(user, "\The [W] is empty.") - - examine(mob/user) - ..(user) - if(detonator) - to_chat(user, "With attached [detonator.name]") - - activate(mob/user as mob) - if(active) return - - if(detonator) - if(!isigniter(detonator.a_left)) - detonator.a_left.activate() - active = 1 - if(!isigniter(detonator.a_right)) - detonator.a_right.activate() - active = 1 - if(active) - icon_state = initial(icon_state) + "_active" - - if(user) - msg_admin_attack("[key_name_admin(user)] primed \a [src.name]") - return - proc/primed(var/primed = 1) - if(active) - icon_state = initial(icon_state) + (primed?"_primed":"_active") + playsound(src.loc, 'sound/effects/bamf.ogg', 50, 1) - detonate() - if(!stage || stage<2) return + for(var/obj/item/weapon/reagent_containers/glass/G in beakers) + G.reagents.trans_to_obj(src, G.reagents.total_volume) - var/has_reagents = 0 - for(var/obj/item/weapon/reagent_containers/glass/G in beakers) - if(G.reagents.total_volume) has_reagents = 1 + if(src.reagents.total_volume) //The possible reactions didnt use up all reagents. + var/datum/effect/effect/system/steam_spread/steam = new /datum/effect/effect/system/steam_spread() + steam.set_up(10, 0, get_turf(src)) + steam.attach(src) + steam.start() - active = 0 - if(!has_reagents) - icon_state = initial(icon_state) +"_locked" - playsound(src.loc, 'sound/items/Screwdriver2.ogg', 50, 1) - spawn(0) //Otherwise det_time is erroneously set to 0 after this - if(istimer(detonator.a_left)) //Make sure description reflects that the timer has been reset - var/obj/item/device/assembly/timer/T = detonator.a_left - det_time = 10*T.time - if(istimer(detonator.a_right)) - var/obj/item/device/assembly/timer/T = detonator.a_right - det_time = 10*T.time - return + for(var/atom/A in view(affected_area, src.loc)) + if( A == src ) continue + src.reagents.touch(A) - playsound(src.loc, 'sound/effects/bamf.ogg', 50, 1) + if(istype(loc, /mob/living/carbon)) //drop dat grenade if it goes off in your hand + var/mob/living/carbon/C = loc + C.drop_from_inventory(src) + C.throw_mode_off() - for(var/obj/item/weapon/reagent_containers/glass/G in beakers) - G.reagents.trans_to_obj(src, G.reagents.total_volume) - - if(src.reagents.total_volume) //The possible reactions didnt use up all reagents. - var/datum/effect/effect/system/steam_spread/steam = new /datum/effect/effect/system/steam_spread() - steam.set_up(10, 0, get_turf(src)) - steam.attach(src) - steam.start() - - for(var/atom/A in view(affected_area, src.loc)) - if( A == src ) continue - src.reagents.touch(A) - - if(istype(loc, /mob/living/carbon)) //drop dat grenade if it goes off in your hand - var/mob/living/carbon/C = loc - C.drop_from_inventory(src) - C.throw_mode_off() - - invisibility = INVISIBILITY_MAXIMUM //Why am i doing this? - spawn(50) //To make sure all reagents can work - qdel(src) //correctly before deleting the grenade. + invisibility = INVISIBILITY_MAXIMUM //Why am i doing this? + spawn(50) //To make sure all reagents can work + qdel(src) //correctly before deleting the grenade. /obj/item/weapon/grenade/chem_grenade/large @@ -203,20 +203,20 @@ path = 1 stage = 2 - New() - ..() - var/obj/item/weapon/reagent_containers/glass/beaker/B1 = new(src) - var/obj/item/weapon/reagent_containers/glass/beaker/B2 = new(src) +/obj/item/weapon/grenade/chem_grenade/metalfoam/Initialize() + . = ..() + var/obj/item/weapon/reagent_containers/glass/beaker/B1 = new(src) + var/obj/item/weapon/reagent_containers/glass/beaker/B2 = new(src) - B1.reagents.add_reagent("aluminum", 30) - B2.reagents.add_reagent("foaming_agent", 10) - B2.reagents.add_reagent("pacid", 10) + B1.reagents.add_reagent("aluminum", 30) + B2.reagents.add_reagent("foaming_agent", 10) + B2.reagents.add_reagent("pacid", 10) - detonator = new/obj/item/device/assembly_holder/timer_igniter(src) + detonator = new/obj/item/device/assembly_holder/timer_igniter(src) - beakers += B1 - beakers += B2 - icon_state = initial(icon_state) +"_locked" + beakers += B1 + beakers += B2 + icon_state = initial(icon_state) +"_locked" /obj/item/weapon/grenade/chem_grenade/incendiary name = "incendiary grenade" @@ -224,22 +224,22 @@ path = 1 stage = 2 - New() - ..() - var/obj/item/weapon/reagent_containers/glass/beaker/B1 = new(src) - var/obj/item/weapon/reagent_containers/glass/beaker/B2 = new(src) +/obj/item/weapon/grenade/chem_grenade/incendiary/Initialize() + . = ..() + var/obj/item/weapon/reagent_containers/glass/beaker/B1 = new(src) + var/obj/item/weapon/reagent_containers/glass/beaker/B2 = new(src) - B1.reagents.add_reagent("aluminum", 15) - B1.reagents.add_reagent("fuel",20) - B2.reagents.add_reagent("phoron", 15) - B2.reagents.add_reagent("sacid", 15) - B1.reagents.add_reagent("fuel",20) + B1.reagents.add_reagent("aluminum", 15) + B1.reagents.add_reagent("fuel",20) + B2.reagents.add_reagent("phoron", 15) + B2.reagents.add_reagent("sacid", 15) + B1.reagents.add_reagent("fuel",20) - detonator = new/obj/item/device/assembly_holder/timer_igniter(src) + detonator = new/obj/item/device/assembly_holder/timer_igniter(src) - beakers += B1 - beakers += B2 - icon_state = initial(icon_state) +"_locked" + beakers += B1 + beakers += B2 + icon_state = initial(icon_state) +"_locked" /obj/item/weapon/grenade/chem_grenade/antiweed name = "weedkiller grenade" @@ -247,21 +247,21 @@ path = 1 stage = 2 - New() - ..() - var/obj/item/weapon/reagent_containers/glass/beaker/B1 = new(src) - var/obj/item/weapon/reagent_containers/glass/beaker/B2 = new(src) +/obj/item/weapon/grenade/chem_grenade/antiweed/Initialize() + . = ..() + var/obj/item/weapon/reagent_containers/glass/beaker/B1 = new(src) + var/obj/item/weapon/reagent_containers/glass/beaker/B2 = new(src) - B1.reagents.add_reagent("plantbgone", 25) - B1.reagents.add_reagent("potassium", 25) - B2.reagents.add_reagent("phosphorus", 25) - B2.reagents.add_reagent("sugar", 25) + B1.reagents.add_reagent("plantbgone", 25) + B1.reagents.add_reagent("potassium", 25) + B2.reagents.add_reagent("phosphorus", 25) + B2.reagents.add_reagent("sugar", 25) - detonator = new/obj/item/device/assembly_holder/timer_igniter(src) + detonator = new/obj/item/device/assembly_holder/timer_igniter(src) - beakers += B1 - beakers += B2 - icon_state = "grenade" + beakers += B1 + beakers += B2 + icon_state = "grenade" /obj/item/weapon/grenade/chem_grenade/cleaner name = "cleaner grenade" @@ -269,20 +269,20 @@ stage = 2 path = 1 - New() - ..() - var/obj/item/weapon/reagent_containers/glass/beaker/B1 = new(src) - var/obj/item/weapon/reagent_containers/glass/beaker/B2 = new(src) +/obj/item/weapon/grenade/chem_grenade/cleaner/Initialize() + . = ..() + var/obj/item/weapon/reagent_containers/glass/beaker/B1 = new(src) + var/obj/item/weapon/reagent_containers/glass/beaker/B2 = new(src) - B1.reagents.add_reagent("fluorosurfactant", 40) - B2.reagents.add_reagent("water", 40) - B2.reagents.add_reagent("cleaner", 10) + B1.reagents.add_reagent("fluorosurfactant", 40) + B2.reagents.add_reagent("water", 40) + B2.reagents.add_reagent("cleaner", 10) - detonator = new/obj/item/device/assembly_holder/timer_igniter(src) + detonator = new/obj/item/device/assembly_holder/timer_igniter(src) - beakers += B1 - beakers += B2 - icon_state = initial(icon_state) +"_locked" + beakers += B1 + beakers += B2 + icon_state = initial(icon_state) +"_locked" /obj/item/weapon/grenade/chem_grenade/teargas name = "tear gas grenade" @@ -290,19 +290,19 @@ stage = 2 path = 1 - New() - ..() - var/obj/item/weapon/reagent_containers/glass/beaker/large/B1 = new(src) - var/obj/item/weapon/reagent_containers/glass/beaker/large/B2 = new(src) +/obj/item/weapon/grenade/chem_grenade/teargas/Initialize() + . = ..() + var/obj/item/weapon/reagent_containers/glass/beaker/large/B1 = new(src) + var/obj/item/weapon/reagent_containers/glass/beaker/large/B2 = new(src) - B1.reagents.add_reagent("phosphorus", 40) - B1.reagents.add_reagent("potassium", 40) - B1.reagents.add_reagent("condensedcapsaicin", 40) - B2.reagents.add_reagent("sugar", 40) - B2.reagents.add_reagent("condensedcapsaicin", 80) + B1.reagents.add_reagent("phosphorus", 40) + B1.reagents.add_reagent("potassium", 40) + B1.reagents.add_reagent("condensedcapsaicin", 40) + B2.reagents.add_reagent("sugar", 40) + B2.reagents.add_reagent("condensedcapsaicin", 80) - detonator = new/obj/item/device/assembly_holder/timer_igniter(src) + detonator = new/obj/item/device/assembly_holder/timer_igniter(src) - beakers += B1 - beakers += B2 - icon_state = initial(icon_state) +"_locked" \ No newline at end of file + beakers += B1 + beakers += B2 + icon_state = initial(icon_state) +"_locked" \ No newline at end of file diff --git a/code/game/objects/items/weapons/grenades/explosive.dm b/code/game/objects/items/weapons/grenades/explosive.dm index 3b4f6a4511..076a7accce 100644 --- a/code/game/objects/items/weapons/grenades/explosive.dm +++ b/code/game/objects/items/weapons/grenades/explosive.dm @@ -50,9 +50,10 @@ var/fragment_type = pickweight(fragtypes) var/obj/item/projectile/bullet/pellet/fragment/P = new fragment_type(T) P.pellets = fragments_per_projectile - P.shot_from = src.name + P.shot_from = name - P.launch(O) + P.old_style_target(O) + P.fire() //Make sure to hit any mobs in the source turf for(var/mob/living/M in T) diff --git a/code/game/objects/items/weapons/grenades/flashbang.dm b/code/game/objects/items/weapons/grenades/flashbang.dm index 8f6ce1864f..eaed5f9f4c 100644 --- a/code/game/objects/items/weapons/grenades/flashbang.dm +++ b/code/game/objects/items/weapons/grenades/flashbang.dm @@ -26,7 +26,6 @@ new/obj/effect/effect/smoke/illumination(src.loc, 5, range=30, power=30, color="#FFFFFF") qdel(src) - return /obj/item/weapon/grenade/flashbang/proc/bang(var/turf/T , var/mob/living/carbon/M) // Added a new proc called 'bang' that takes a location and a person to be banged. to_chat(M, "BANG") // Called during the loop that bangs people in lockers/containers and when banging diff --git a/code/game/objects/items/weapons/grenades/projectile.dm b/code/game/objects/items/weapons/grenades/projectile.dm index 05153df4fe..8ea02c9add 100644 --- a/code/game/objects/items/weapons/grenades/projectile.dm +++ b/code/game/objects/items/weapons/grenades/projectile.dm @@ -61,7 +61,8 @@ var/obj/item/projectile/P = new shot_type(T) P.shot_from = src.name - P.launch(O) + P.old_style_target(O) + P.fire() //Make sure to hit any mobs in the source turf for(var/mob/living/M in T) diff --git a/code/game/objects/items/weapons/grenades/spawnergrenade.dm b/code/game/objects/items/weapons/grenades/spawnergrenade.dm index 5a20c49ccd..a6ad6f4592 100644 --- a/code/game/objects/items/weapons/grenades/spawnergrenade.dm +++ b/code/game/objects/items/weapons/grenades/spawnergrenade.dm @@ -31,19 +31,25 @@ /obj/item/weapon/grenade/spawnergrenade/manhacks name = "manhack delivery grenade" - spawner_type = /mob/living/simple_animal/hostile/viscerator + spawner_type = /mob/living/simple_mob/mechanical/viscerator deliveryamt = 5 origin_tech = list(TECH_MATERIAL = 3, TECH_MAGNET = 4, TECH_ILLEGAL = 4) +/obj/item/weapon/grenade/spawnergrenade/manhacks/mercenary + spawner_type = /mob/living/simple_mob/mechanical/viscerator/mercenary + +/obj/item/weapon/grenade/spawnergrenade/manhacks/raider + spawner_type = /mob/living/simple_mob/mechanical/viscerator/raider + /obj/item/weapon/grenade/spawnergrenade/spesscarp name = "carp delivery grenade" - spawner_type = /mob/living/simple_animal/hostile/carp + spawner_type = /mob/living/simple_mob/animal/space/carp deliveryamt = 5 origin_tech = list(TECH_MATERIAL = 3, TECH_MAGNET = 4, TECH_ILLEGAL = 4) /obj/item/weapon/grenade/spawnergrenade/spider name = "spider delivery grenade" - spawner_type = /mob/living/simple_animal/hostile/giant_spider/hunter + spawner_type = /mob/living/simple_mob/animal/giant_spider/hunter deliveryamt = 3 origin_tech = list(TECH_MATERIAL = 3, TECH_MAGNET = 4, TECH_ILLEGAL = 4) diff --git a/code/game/objects/items/weapons/grenades/supermatter.dm b/code/game/objects/items/weapons/grenades/supermatter.dm index 1bf35d1e1c..7eff5accd4 100644 --- a/code/game/objects/items/weapons/grenades/supermatter.dm +++ b/code/game/objects/items/weapons/grenades/supermatter.dm @@ -8,12 +8,12 @@ /obj/item/weapon/grenade/supermatter/Destroy() if(implode_at) - processing_objects -= src + STOP_PROCESSING(SSobj, src) . = ..() /obj/item/weapon/grenade/supermatter/detonate() ..() - processing_objects += src + START_PROCESSING(SSobj, src) implode_at = world.time + 10 SECONDS update_icon() playsound(src, 'sound/weapons/wave.ogg', 100) diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm index 40c074c939..f3e5d05fdf 100644 --- a/code/game/objects/items/weapons/handcuffs.dm +++ b/code/game/objects/items/weapons/handcuffs.dm @@ -336,4 +336,4 @@ var/last_chew = 0 target.m_intent = "walk" if(target.hud_used && user.hud_used.move_intent) target.hud_used.move_intent.icon_state = "walking" - return 1 \ No newline at end of file + return 1 diff --git a/code/game/objects/items/weapons/id cards/cards.dm b/code/game/objects/items/weapons/id cards/cards.dm index e7a3d3f4d5..389601ef1f 100644 --- a/code/game/objects/items/weapons/id cards/cards.dm +++ b/code/game/objects/items/weapons/id cards/cards.dm @@ -101,6 +101,6 @@ usr << "You are not adding enough telecrystals to fuel \the [src]." return uses += T.amount/2 //Gives 5 uses per 10 TC - uses = ceil(uses) //Ensures no decimal uses nonsense, rounds up to be nice + uses = CEILING(uses, 1) //Ensures no decimal uses nonsense, rounds up to be nice usr << "You add \the [O] to \the [src]. Increasing the uses of \the [src] to [uses]." qdel(O) \ No newline at end of file diff --git a/code/game/objects/items/weapons/id cards/station_ids.dm b/code/game/objects/items/weapons/id cards/station_ids.dm index 8c29680fe0..c157d42492 100644 --- a/code/game/objects/items/weapons/id cards/station_ids.dm +++ b/code/game/objects/items/weapons/id cards/station_ids.dm @@ -121,7 +121,7 @@ return ..() -/obj/item/weapon/card/id/initialize() +/obj/item/weapon/card/id/Initialize() . = ..() var/datum/job/J = job_master.GetJob(rank) if(J) @@ -168,7 +168,7 @@ item_state = "tdgreen" assignment = "Synthetic" -/obj/item/weapon/card/id/synthetic/initialize() +/obj/item/weapon/card/id/synthetic/Initialize() . = ..() access = get_all_station_access() + access_synth @@ -179,11 +179,11 @@ registered_name = "Central Command" assignment = "General" -/obj/item/weapon/card/id/centcom/initialize() +/obj/item/weapon/card/id/centcom/Initialize() . = ..() access = get_all_centcom_access() -/obj/item/weapon/card/id/centcom/station/initialize() +/obj/item/weapon/card/id/centcom/station/Initialize() . = ..() access |= get_all_station_access() @@ -192,7 +192,7 @@ assignment = "Emergency Response Team" icon_state = "centcom" -/obj/item/weapon/card/id/centcom/ERT/initialize() +/obj/item/weapon/card/id/centcom/ERT/Initialize() . = ..() access |= get_all_station_access() diff --git a/code/game/objects/items/weapons/id cards/syndicate_ids.dm b/code/game/objects/items/weapons/id cards/syndicate_ids.dm index 05528ca19b..bbf05718fc 100644 --- a/code/game/objects/items/weapons/id cards/syndicate_ids.dm +++ b/code/game/objects/items/weapons/id cards/syndicate_ids.dm @@ -6,11 +6,11 @@ var/electronic_warfare = 1 var/mob/registered_user = null -/obj/item/weapon/card/id/syndicate/initialize() +/obj/item/weapon/card/id/syndicate/Initialize() . = ..() access = syndicate_access.Copy() -/obj/item/weapon/card/id/syndicate/station_access/initialize() +/obj/item/weapon/card/id/syndicate/station_access/Initialize() . = ..() // Same as the normal Syndicate id, only already has all station access access |= get_all_station_access() @@ -58,7 +58,7 @@ data["electronic_warfare"] = electronic_warfare data["entries"] = entries - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "agent_id_card.tmpl", "Fake ID", 600, 400) ui.set_initial_data(data) @@ -185,7 +185,7 @@ . = 1 // Always update the UI, or buttons will spin indefinitely - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) /var/global/list/id_card_states /proc/id_card_states() diff --git a/code/game/objects/items/weapons/implants/implant.dm b/code/game/objects/items/weapons/implants/implant.dm index f5bd38dcc1..1804d576fd 100644 --- a/code/game/objects/items/weapons/implants/implant.dm +++ b/code/game/objects/items/weapons/implants/implant.dm @@ -110,10 +110,10 @@ GLOBAL_LIST_BOILERPLATE(all_tracking_implants, /obj/item/weapon/implant/tracking ..() /obj/item/weapon/implant/tracking/post_implant(var/mob/source) - processing_objects.Add(src) + START_PROCESSING(SSobj, src) /obj/item/weapon/implant/tracking/Destroy() - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) return ..() /obj/item/weapon/implant/tracking/process() @@ -126,7 +126,7 @@ GLOBAL_LIST_BOILERPLATE(all_tracking_implants, /obj/item/weapon/implant/tracking desc = "Charred circuit in melted plastic case. Wonder what that used to be..." icon_state = "implant_melted" malfunction = MALFUNCTION_PERMANENT - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) return 1 /obj/item/weapon/implant/tracking/get_data() @@ -529,7 +529,7 @@ the implant may become unstable and either pre-maturely inject the subject or si // a.autosay("[mobname] has died in [t.name]!", "[mobname]'s Death Alarm", "Security") // a.autosay("[mobname] has died in [t.name]!", "[mobname]'s Death Alarm", "Medical") qdel(a) - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) if ("emp") var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset/heads/captain(null) var/name = prob(50) ? t.name : pick(teleportlocs) @@ -543,7 +543,7 @@ the implant may become unstable and either pre-maturely inject the subject or si // a.autosay("[mobname] has died-zzzzt in-in-in...", "[mobname]'s Death Alarm", "Security") // a.autosay("[mobname] has died-zzzzt in-in-in...", "[mobname]'s Death Alarm", "Medical") qdel(a) - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) /obj/item/weapon/implant/death_alarm/emp_act(severity) //for some reason alarms stop going off in case they are emp'd, even without this if (malfunction) //so I'm just going to add a meltdown chance here @@ -556,14 +556,14 @@ the implant may become unstable and either pre-maturely inject the subject or si meltdown() else if (prob(60)) //but more likely it will just quietly die malfunction = MALFUNCTION_PERMANENT - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) spawn(20) malfunction-- /obj/item/weapon/implant/death_alarm/post_implant(mob/source as mob) mobname = source.real_name - processing_objects.Add(src) + START_PROCESSING(SSobj, src) ////////////////////////////// // Compressed Matter Implant diff --git a/code/game/objects/items/weapons/implants/implant_vr.dm b/code/game/objects/items/weapons/implants/implant_vr.dm index 006c4884e1..bf67f83953 100644 --- a/code/game/objects/items/weapons/implants/implant_vr.dm +++ b/code/game/objects/items/weapons/implants/implant_vr.dm @@ -105,9 +105,9 @@ if(size_mult.Find(msg)) var/resizing_value = text2num(size_mult.match) if(findtext(msg, "centimeter")) //Because metric system rules - H.resize(Clamp(resizing_value/170 , 0.25, 2)) //170 cm is average crewmember, I think + H.resize(CLAMP(resizing_value/170 , 0.25, 2)) //170 cm is average crewmember, I think else - H.resize(Clamp(resizing_value , 0.25, 2)) + H.resize(CLAMP(resizing_value , 0.25, 2)) diff --git a/code/game/objects/items/weapons/implants/implantchair.dm b/code/game/objects/items/weapons/implants/implantchair.dm index c05d52442c..5b1ba3f6c5 100644 --- a/code/game/objects/items/weapons/implants/implantchair.dm +++ b/code/game/objects/items/weapons/implants/implantchair.dm @@ -79,10 +79,9 @@ var/obj/item/weapon/grab/grab = G if(!ismob(grab.affecting)) return - for(var/mob/living/simple_animal/slime/M in range(1,grab.affecting)) - if(M.victim == grab.affecting) - usr << "[grab.affecting.name] will not fit into the [src.name] because they have a slime latched onto their head." - return + if(grab.affecting.has_buckled_mobs()) + to_chat(user, span("warning", "\The [grab.affecting] has other entities attached to them. Remove them first.")) + return var/mob/M = grab.affecting if(put_mob(M)) qdel(G) diff --git a/code/game/objects/items/weapons/implants/implantreagent_vr.dm b/code/game/objects/items/weapons/implants/implantreagent_vr.dm index 0b227d9539..4597cbe0a8 100644 --- a/code/game/objects/items/weapons/implants/implantreagent_vr.dm +++ b/code/game/objects/items/weapons/implants/implantreagent_vr.dm @@ -31,7 +31,7 @@ return /obj/item/weapon/implant/reagent_generator/post_implant(mob/living/carbon/source) - processing_objects += src + START_PROCESSING(SSobj, src) to_chat(source, "You implant [source] with \the [src].") assigned_proc = new assigned_proc(source, verb_name, verb_desc) return 1 diff --git a/code/game/objects/items/weapons/implants/neuralbasic.dm b/code/game/objects/items/weapons/implants/neuralbasic.dm index a42778f58e..d744c80fde 100644 --- a/code/game/objects/items/weapons/implants/neuralbasic.dm +++ b/code/game/objects/items/weapons/implants/neuralbasic.dm @@ -16,13 +16,13 @@ if(H.isSynthetic() && H.get_FBP_type() != FBP_CYBORG) //If this on an FBP, it's just an extra inefficient attachment to whatever their brain is. robotic_brain = TRUE if(my_brain && my_brain.can_assist()) - processing_objects.Add(src) + START_PROCESSING(SSobj, src) /obj/item/weapon/implant/neural/Destroy() if(my_brain) if(my_brain.owner) to_chat(my_brain.owner, "You feel a pressure in your mind as something is ripped away.") - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) my_brain = null return ..() @@ -92,7 +92,7 @@ Implant Specifics:
"} /obj/item/weapon/implant/neural/meltdown() ..() - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) var/mob/living/carbon/human/H = null if(my_brain && my_brain.owner) if(ishuman(my_brain.owner)) diff --git a/code/game/objects/items/weapons/material/ashtray.dm b/code/game/objects/items/weapons/material/ashtray.dm index 8becb48010..5a26720b7c 100644 --- a/code/game/objects/items/weapons/material/ashtray.dm +++ b/code/game/objects/items/weapons/material/ashtray.dm @@ -57,7 +57,7 @@ var/global/list/ashtray_cache = list() var/obj/item/clothing/mask/smokable/cigarette/cig = W if (cig.lit == 1) src.visible_message("[user] crushes [cig] in \the [src], putting it out.") - processing_objects.Remove(cig) + STOP_PROCESSING(SSobj, cig) var/obj/item/butt = new cig.type_butt(src) cig.transfer_fingerprints_to(butt) qdel(cig) diff --git a/code/game/objects/items/weapons/material/chainsaw.dm b/code/game/objects/items/weapons/material/chainsaw.dm index 703512bf52..f98fe79f51 100644 --- a/code/game/objects/items/weapons/material/chainsaw.dm +++ b/code/game/objects/items/weapons/material/chainsaw.dm @@ -17,11 +17,11 @@ obj/item/weapon/chainsaw/New() reagents = R R.my_atom = src R.add_reagent("fuel", max_fuel) - processing_objects |= src + START_PROCESSING(SSobj, src) ..() obj/item/weapon/chainsaw/Destroy() - processing_objects -= src + STOP_PROCESSING(SSobj, src) if(reagents) qdel(reagents) ..() diff --git a/code/game/objects/items/weapons/material/material_armor.dm b/code/game/objects/items/weapons/material/material_armor.dm index ecd328f3ab..d8fba58175 100644 --- a/code/game/objects/items/weapons/material/material_armor.dm +++ b/code/game/objects/items/weapons/material/material_armor.dm @@ -41,7 +41,7 @@ Protectiveness | Armor % set_material(material_key) /obj/item/clothing/Destroy() - processing_objects -= src + STOP_PROCESSING(SSobj, src) return ..() /obj/item/clothing/get_material() @@ -58,7 +58,7 @@ Protectiveness | Armor % if(applies_material_color) color = material.icon_colour if(material.products_need_process()) - processing_objects |= src + START_PROCESSING(SSobj, src) update_armor() // This is called when someone wearing the object gets hit in some form (melee, bullet_act(), etc). diff --git a/code/game/objects/items/weapons/material/material_weapons.dm b/code/game/objects/items/weapons/material/material_weapons.dm index 06444f6a37..4f08c61a4c 100644 --- a/code/game/objects/items/weapons/material/material_weapons.dm +++ b/code/game/objects/items/weapons/material/material_weapons.dm @@ -67,11 +67,11 @@ if(applies_material_colour) color = material.icon_colour if(material.products_need_process()) - processing_objects |= src + START_PROCESSING(SSobj, src) update_force() /obj/item/weapon/material/Destroy() - processing_objects -= src + STOP_PROCESSING(SSobj, src) . = ..() /obj/item/weapon/material/apply_hit_effect() diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm index ad30eb0a57..6c4930950e 100644 --- a/code/game/objects/items/weapons/melee/energy.dm +++ b/code/game/objects/items/weapons/melee/energy.dm @@ -233,11 +233,10 @@ playsound(get_turf(target), 'sound/weapons/blade1.ogg', 100, 1) // Make lesser robots really mad at us. - if(istype(target, /mob/living/simple_animal)) - var/mob/living/simple_animal/SA = target - if(SA.intelligence_level == SA_ROBOTIC) - SA.taunt(user) - SA.adjustFireLoss(force * 6) // 30 Burn, for 50 total. + if(target.mob_class & MOB_CLASS_SYNTHETIC) + if(target.has_AI()) + target.taunt(user) + target.adjustFireLoss(force * 6) // 30 Burn, for 50 total. /* *Energy Blade @@ -269,11 +268,11 @@ spark_system.set_up(5, 0, src) spark_system.attach(src) - processing_objects |= src + START_PROCESSING(SSobj, src) set_light(lrange, lpower, lcolor) /obj/item/weapon/melee/energy/blade/Destroy() - processing_objects -= src + STOP_PROCESSING(SSobj, src) ..() /obj/item/weapon/melee/energy/blade/attack_self(mob/user as mob) diff --git a/code/game/objects/items/weapons/mop_deploy.dm b/code/game/objects/items/weapons/mop_deploy.dm index 30a6991a53..93b3657f49 100644 --- a/code/game/objects/items/weapons/mop_deploy.dm +++ b/code/game/objects/items/weapons/mop_deploy.dm @@ -16,7 +16,7 @@ /obj/item/weapon/mop_deploy/New() create_reagents(5) - processing_objects |= src + START_PROCESSING(SSobj, src) /turf/proc/clean_deploy(atom/source) if(source.reagents.has_reagent("water", 1)) @@ -48,7 +48,7 @@ ..() /obj/item/weapon/mop_deploy/Destroy() - processing_objects -= src + STOP_PROCESSING(SSobj, src) . = ..() /obj/item/weapon/mop_deploy/attack_self(mob/user as mob) diff --git a/code/game/objects/items/weapons/paint.dm b/code/game/objects/items/weapons/paint.dm index 5d12f5c33b..d3f269abaf 100644 --- a/code/game/objects/items/weapons/paint.dm +++ b/code/game/objects/items/weapons/paint.dm @@ -37,7 +37,7 @@ var/global/list/cached_icons = list() else if (paint_type == "black") reagents.add_reagent("carbon", volume/5) else - reagents.add_reagent("crayon_dust_[paint_type]", volume/5) + reagents.add_reagent("marker_ink_[paint_type]", volume/5) reagents.handle_reactions() red diff --git a/code/game/objects/items/weapons/policetape.dm b/code/game/objects/items/weapons/policetape.dm index aec6a790b2..fcb2920aa0 100644 --- a/code/game/objects/items/weapons/policetape.dm +++ b/code/game/objects/items/weapons/policetape.dm @@ -14,7 +14,7 @@ var/apply_tape = FALSE -/obj/item/taperoll/initialize() +/obj/item/taperoll/Initialize() . = ..() if(apply_tape) var/turf/T = get_turf(src) @@ -292,7 +292,7 @@ var/list/tape_roll_applications = list() add_fingerprint(M) if (!allowed(M)) //only select few learn art of not crumpling the tape M << "You are not supposed to go past [src]..." - if(M.a_intent == I_HELP && !(istype(M, /mob/living/simple_animal))) + if(M.a_intent == I_HELP && !(istype(M, /mob/living/simple_mob))) return 0 crumple() return ..(mover) diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index 2dd06bc0bc..cdf5f347d2 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -401,7 +401,7 @@ W.lit = 1 W.damtype = "burn" W.icon_state = "match_lit" - processing_objects.Add(W) + START_PROCESSING(SSobj, W) W.update_icon() return diff --git a/code/game/objects/items/weapons/storage/fancy.dm b/code/game/objects/items/weapons/storage/fancy.dm index c1de372dc1..7d754d8f14 100644 --- a/code/game/objects/items/weapons/storage/fancy.dm +++ b/code/game/objects/items/weapons/storage/fancy.dm @@ -55,11 +55,11 @@ starts_with = list(/obj/item/weapon/reagent_containers/food/snacks/egg = 12) /* - * Candle Box + * Candle Boxes */ /obj/item/weapon/storage/fancy/candle_box - name = "candle pack" + name = "red candle pack" desc = "A pack of red candles." icon = 'icons/obj/candle.dmi' icon_state = "candlebox5" @@ -69,6 +69,29 @@ slot_flags = SLOT_BELT starts_with = list(/obj/item/weapon/flame/candle = 5) +/obj/item/weapon/storage/fancy/whitecandle_box + name = "white candle pack" + desc = "A pack of white candles." + icon = 'icons/obj/candle.dmi' + icon_state = "whitecandlebox5" + icon_type = "whitecandle" + item_state = "whitecandlebox5" + throwforce = 2 + slot_flags = SLOT_BELT + starts_with = list(/obj/item/weapon/flame/candle/white = 5) + +/obj/item/weapon/storage/fancy/blackcandle_box + name = "black candle pack" + desc = "A pack of black candles." + icon = 'icons/obj/candle.dmi' + icon_state = "blackcandlebox5" + icon_type = "blackcandle" + item_state = "blackcandlebox5" + throwforce = 2 + slot_flags = SLOT_BELT + starts_with = list(/obj/item/weapon/flame/candle/black = 5) + + /* * Crayon Box */ @@ -92,7 +115,7 @@ /obj/item/weapon/pen/crayon/purple ) -/obj/item/weapon/storage/fancy/crayons/initialize() +/obj/item/weapon/storage/fancy/crayons/Initialize() . = ..() update_icon() @@ -134,7 +157,7 @@ /obj/item/weapon/pen/crayon/marker/purple ) -/obj/item/weapon/storage/fancy/markers/initialize() +/obj/item/weapon/storage/fancy/markers/Initialize() . = ..() update_icon() @@ -169,12 +192,12 @@ throwforce = 2 slot_flags = SLOT_BELT storage_slots = 6 - can_hold = list(/obj/item/clothing/mask/smokable/cigarette, /obj/item/weapon/flame/lighter) + can_hold = list(/obj/item/clothing/mask/smokable/cigarette, /obj/item/weapon/flame/lighter, /obj/item/weapon/cigbutt) icon_type = "cigarette" starts_with = list(/obj/item/clothing/mask/smokable/cigarette = 6) var/brand = "\improper Trans-Stellar Duty-free" -/obj/item/weapon/storage/fancy/cigarettes/initialize() +/obj/item/weapon/storage/fancy/cigarettes/Initialize() . = ..() flags |= NOREACT create_reagents(15 * storage_slots)//so people can inject cigarettes without opening a packet, now with being able to inject the whole one @@ -276,11 +299,11 @@ throwforce = 2 slot_flags = SLOT_BELT storage_slots = 7 - can_hold = list(/obj/item/clothing/mask/smokable/cigarette/cigar) + can_hold = list(/obj/item/clothing/mask/smokable/cigarette/cigar, /obj/item/weapon/cigbutt/cigarbutt) icon_type = "cigar" starts_with = list(/obj/item/clothing/mask/smokable/cigarette/cigar = 7) -/obj/item/weapon/storage/fancy/cigar/initialize() +/obj/item/weapon/storage/fancy/cigar/Initialize() . = ..() flags |= NOREACT create_reagents(15 * storage_slots) @@ -332,7 +355,7 @@ storage_slots = 6 req_access = list(access_virology) -/obj/item/weapon/storage/lockbox/vials/initialize() +/obj/item/weapon/storage/lockbox/vials/Initialize() . = ..() update_icon() @@ -377,7 +400,7 @@ /obj/item/weapon/reagent_containers/food/snacks/chocolatepiece/truffle ) -/obj/item/weapon/storage/fancy/heartbox/initialize() +/obj/item/weapon/storage/fancy/heartbox/Initialize() . = ..() update_icon() diff --git a/code/game/objects/items/weapons/storage/firstaid.dm b/code/game/objects/items/weapons/storage/firstaid.dm index d6aabf718f..d436af1936 100644 --- a/code/game/objects/items/weapons/storage/firstaid.dm +++ b/code/game/objects/items/weapons/storage/firstaid.dm @@ -17,7 +17,7 @@ max_storage_space = ITEMSIZE_COST_SMALL * 7 // 14 // var/list/icon_variety // VOREStation edit -/obj/item/weapon/storage/firstaid/initialize() +/obj/item/weapon/storage/firstaid/Initialize() . = ..() // if(icon_variety) // VOREStation edit // icon_state = pick(icon_variety) diff --git a/code/game/objects/items/weapons/storage/misc.dm b/code/game/objects/items/weapons/storage/misc.dm index d103fbc6ef..9dca5c3edd 100644 --- a/code/game/objects/items/weapons/storage/misc.dm +++ b/code/game/objects/items/weapons/storage/misc.dm @@ -11,7 +11,7 @@ foldable = /obj/item/stack/material/cardboard starts_with = list(/obj/item/weapon/reagent_containers/food/snacks/donut/normal = 6) -/obj/item/weapon/storage/box/donut/initialize() +/obj/item/weapon/storage/box/donut/Initialize() . = ..() update_icon() diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm index 8d17a1a5c7..f400f87bb3 100644 --- a/code/game/objects/items/weapons/storage/storage.dm +++ b/code/game/objects/items/weapons/storage/storage.dm @@ -527,7 +527,7 @@ for(var/obj/item/I in contents) remove_from_storage(I, T) -/obj/item/weapon/storage/initialize() +/obj/item/weapon/storage/Initialize() . = ..() if(allow_quick_empty) diff --git a/code/game/objects/items/weapons/storage/toolbox.dm b/code/game/objects/items/weapons/storage/toolbox.dm index 7989c53f1d..6576578a80 100644 --- a/code/game/objects/items/weapons/storage/toolbox.dm +++ b/code/game/objects/items/weapons/storage/toolbox.dm @@ -24,7 +24,7 @@ /obj/item/weapon/extinguisher/mini, /obj/item/device/radio ) -/obj/item/weapon/storage/toolbox/emergency/initialize() +/obj/item/weapon/storage/toolbox/emergency/Initialize() if(prob(50)) new /obj/item/device/flashlight(src) else @@ -56,7 +56,7 @@ /obj/item/stack/cable_coil/random_belt, /obj/item/stack/cable_coil/random_belt ) -/obj/item/weapon/storage/toolbox/electrical/initialize() +/obj/item/weapon/storage/toolbox/electrical/Initialize() . = ..() if(prob(5)) new /obj/item/clothing/gloves/yellow(src) @@ -102,7 +102,7 @@ var/filled = FALSE attack_verb = list("lunched") -/obj/item/weapon/storage/toolbox/lunchbox/initialize() +/obj/item/weapon/storage/toolbox/lunchbox/Initialize() if(filled) var/list/lunches = lunchables_lunches() var/lunch = lunches[pick(lunches)] diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm index c66da84712..4291752587 100644 --- a/code/game/objects/items/weapons/storage/uplink_kits.dm +++ b/code/game/objects/items/weapons/storage/uplink_kits.dm @@ -1,4 +1,4 @@ -/obj/item/weapon/storage/box/syndicate/initialize() +/obj/item/weapon/storage/box/syndicate/Initialize() switch (pickweight(list("bloodyspai" = 1, "stealth" = 1, "screwed" = 1, "guns" = 1, "murder" = 1, "freedom" = 1, "hacker" = 1, "lordsingulo" = 1, "smoothoperator" = 1))) if("bloodyspai") new /obj/item/clothing/under/chameleon(src) @@ -70,7 +70,7 @@ /obj/item/weapon/storage/box/syndie_kit/imp_freedom name = "boxed freedom implant (with injector)" -/obj/item/weapon/storage/box/syndie_kit/imp_freedom/initialize() +/obj/item/weapon/storage/box/syndie_kit/imp_freedom/Initialize() var/obj/item/weapon/implanter/O = new(src) O.imp = new /obj/item/weapon/implant/freedom(O) O.update() @@ -87,7 +87,7 @@ /obj/item/weapon/storage/box/syndie_kit/imp_uplink name = "boxed uplink implant (with injector)" -/obj/item/weapon/storage/box/syndie_kit/imp_uplink/initialize() +/obj/item/weapon/storage/box/syndie_kit/imp_uplink/Initialize() var/obj/item/weapon/implanter/O = new(src) O.imp = new /obj/item/weapon/implant/uplink(O) O.update() @@ -157,7 +157,7 @@ name = "\improper Tricky smokes" desc = "Comes with the following brands of cigarettes, in this order: 2xFlash, 2xSmoke, 1xMindBreaker, 1xTricordrazine. Avoid mixing them up." -/obj/item/weapon/storage/box/syndie_kit/cigarette/initialize() +/obj/item/weapon/storage/box/syndie_kit/cigarette/Initialize() . = ..() var/obj/item/weapon/storage/fancy/cigarettes/pack diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm index e37b2f9977..53c092d923 100644 --- a/code/game/objects/items/weapons/stunbaton.dm +++ b/code/game/objects/items/weapons/stunbaton.dm @@ -269,9 +269,8 @@ /obj/item/weapon/melee/baton/shocker/apply_hit_effect(mob/living/target, mob/living/user, var/hit_zone) ..(target, user, hit_zone) - if(istype(target, /mob/living/simple_animal) && status) - var/mob/living/simple_animal/SA = target - SA.taunt(user) + if(status && target.has_AI()) + target.taunt(user) // Borg version, for the lost module. /obj/item/weapon/melee/baton/shocker/robot diff --git a/code/game/objects/items/weapons/tanks/tank_types.dm b/code/game/objects/items/weapons/tanks/tank_types.dm index efacad4942..4aa6986d16 100644 --- a/code/game/objects/items/weapons/tanks/tank_types.dm +++ b/code/game/objects/items/weapons/tanks/tank_types.dm @@ -16,14 +16,14 @@ icon_state = "oxygen" distribute_pressure = ONE_ATMOSPHERE*O2STANDARD -/obj/item/weapon/tank/oxygen/New() - ..() - air_contents.adjust_gas("oxygen", (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) - return +/obj/item/weapon/tank/oxygen/Initialize() + ..() + air_contents.adjust_gas("oxygen", (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) + return /obj/item/weapon/tank/oxygen/examine(mob/user) if(..(user, 0) && air_contents.gas["oxygen"] < 10) - user << text("The meter on \the [src] indicates you are almost out of oxygen!") + to_chat(user, text("The meter on \the [src] indicates you are almost out of oxygen!")) //playsound(usr, 'sound/effects/alert.ogg', 50, 1) /obj/item/weapon/tank/oxygen/yellow @@ -42,7 +42,7 @@ desc = "A tank with an N2O/O2 gas mix." icon_state = "anesthetic" -/obj/item/weapon/tank/anesthetic/New() +/obj/item/weapon/tank/anesthetic/Initialize() ..() air_contents.gas["oxygen"] = (3*ONE_ATMOSPHERE)*70/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD @@ -61,10 +61,10 @@ /obj/item/weapon/tank/air/examine(mob/user) if(..(user, 0) && air_contents.gas["oxygen"] < 1 && loc==user) - user << "The meter on the [src.name] indicates you are almost out of air!" + to_chat(user, "The meter on the [src.name] indicates you are almost out of air!") user << sound('sound/effects/alert.ogg') -/obj/item/weapon/tank/air/New() +/obj/item/weapon/tank/air/Initialize() ..() src.air_contents.adjust_multi("oxygen", (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD, "nitrogen", (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD) @@ -82,7 +82,7 @@ flags = CONDUCT slot_flags = null //they have no straps! -/obj/item/weapon/tank/phoron/New() +/obj/item/weapon/tank/phoron/Initialize() ..() src.air_contents.adjust_gas("phoron", (3*ONE_ATMOSPHERE)*70/(R_IDEAL_GAS_EQUATION*T20C)) @@ -109,7 +109,7 @@ distribute_pressure = ONE_ATMOSPHERE*O2STANDARD slot_flags = SLOT_BACK //these ones have straps! -/obj/item/weapon/tank/vox/New() +/obj/item/weapon/tank/vox/Initialize() ..() air_contents.adjust_gas("phoron", (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) @@ -137,15 +137,14 @@ icon_state = "emergency" gauge_icon = "indicator_emergency" -/obj/item/weapon/tank/emergency/oxygen/New() - ..() - src.air_contents.adjust_gas("oxygen", (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) - - return +/obj/item/weapon/tank/emergency/oxygen/Initialize() + ..() + src.air_contents.adjust_gas("oxygen", (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) + return /obj/item/weapon/tank/emergency/oxygen/examine(mob/user) if(..(user, 0) && air_contents.gas["oxygen"] < 0.2 && loc==user) - user << text("The meter on the [src.name] indicates you are almost out of air!") + to_chat(user, text("The meter on the [src.name] indicates you are almost out of air!")) user << sound('sound/effects/alert.ogg') /obj/item/weapon/tank/emergency/oxygen/engi @@ -159,15 +158,27 @@ gauge_icon = "indicator_emergency_double" volume = 10 +/obj/item/weapon/tank/stasis/oxygen // Stasis bags need to have initial pressure within safe bounds for human atmospheric pressure (NOT breath pressure) + name = "stasis oxygen tank" + desc = "Oxygen tank included in most stasis bag designs." + icon_state = "emergency_double" + gauge_icon = "indicator_emergency_double" + volume = 10 + +/obj/item/weapon/tank/stasis/oxygen/Initialize() + ..() + src.air_contents.adjust_gas("oxygen", (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) + return + /obj/item/weapon/tank/emergency/nitrogen name = "emergency nitrogen tank" desc = "An emergency air tank hastily painted red." icon_state = "emergency_nitro" gauge_icon = "indicator_emergency" -/obj/item/weapon/tank/emergency/nitrogen/New() +/obj/item/weapon/tank/emergency/nitrogen/Initialize() ..() - src.air_contents.adjust_gas("nitrogen", (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) + src.air_contents.adjust_gas("nitrogen", (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) /obj/item/weapon/tank/emergency/nitrogen/double name = "double emergency nitrogen tank" @@ -181,9 +192,9 @@ icon_state = "emergency_nitro" gauge_icon = "indicator_emergency" -/obj/item/weapon/tank/emergency/phoron/New() +/obj/item/weapon/tank/emergency/phoron/Initialize() ..() - src.air_contents.adjust_gas("phoron", (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) + src.air_contents.adjust_gas("phoron", (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) /obj/item/weapon/tank/emergency/phoron/double name = "double emergency phoron tank" @@ -200,7 +211,7 @@ icon_state = "oxygen_fr" distribute_pressure = ONE_ATMOSPHERE*O2STANDARD -/obj/item/weapon/tank/nitrogen/New() +/obj/item/weapon/tank/nitrogen/Initialize() ..() src.air_contents.adjust_gas("nitrogen", (3*ONE_ATMOSPHERE)*70/(R_IDEAL_GAS_EQUATION*T20C)) @@ -208,5 +219,5 @@ /obj/item/weapon/tank/nitrogen/examine(mob/user) if(..(user, 0) && air_contents.gas["nitrogen"] < 10) - user << text("The meter on \the [src] indicates you are almost out of nitrogen!") + to_chat(user, text("The meter on \the [src] indicates you are almost out of nitrogen!")) //playsound(user, 'sound/effects/alert.ogg', 50, 1) diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm index aab34d8f82..473ea916f8 100644 --- a/code/game/objects/items/weapons/tanks/tanks.dm +++ b/code/game/objects/items/weapons/tanks/tanks.dm @@ -42,14 +42,14 @@ var/list/global/tank_gauge_cache = list() description_info = "These tanks are utilised to store any of the various types of gaseous substances. \ They can be attached to various portable atmospheric devices to be filled or emptied.
\
\ - Each tank is fitted with an emergency relief valve. This relief valve will open if the tank is pressurised to over ~3000kPa or heated to over 173ºC. \ + Each tank is fitted with an emergency relief valve. This relief valve will open if the tank is pressurised to over ~3000kPa or heated to over 173�C. \ The valve itself will close after expending most or all of the contents into the air.
\
\ Filling a tank such that experiences ~4000kPa of pressure will cause the tank to rupture, spilling out its contents and destroying the tank. \ Tanks filled over ~5000kPa will rupture rather violently, exploding with significant force." - description_antag = "Each tank may be incited to burn by attaching wires and an igniter assembly, though the igniter can only be used once and the mixture only burn if the igniter pushes a flammable gas mixture above the minimum burn temperature (126ºC). \ - Wired and assembled tanks may be disarmed with a set of wirecutters. Any exploding or rupturing tank will generate shrapnel, assuming their relief valves have been welded beforehand. Even if not, they can be incited to expel hot gas on ignition if pushed above 173ºC. \ + description_antag = "Each tank may be incited to burn by attaching wires and an igniter assembly, though the igniter can only be used once and the mixture only burn if the igniter pushes a flammable gas mixture above the minimum burn temperature (126�C). \ + Wired and assembled tanks may be disarmed with a set of wirecutters. Any exploding or rupturing tank will generate shrapnel, assuming their relief valves have been welded beforehand. Even if not, they can be incited to expel hot gas on ignition if pushed above 173�C. \ Relatively easy to make, the single tank bomb requries no tank transfer valve, and is still a fairly formidable weapon that can be manufactured from any tank." /obj/item/weapon/tank/proc/init_proxy() @@ -58,21 +58,21 @@ var/list/global/tank_gauge_cache = list() src.proxyassembly = proxy -/obj/item/weapon/tank/New() +/obj/item/weapon/tank/Initialize() ..() src.init_proxy() src.air_contents = new /datum/gas_mixture() src.air_contents.volume = volume //liters src.air_contents.temperature = T20C - processing_objects.Add(src) + START_PROCESSING(SSobj, src) update_gauge() return /obj/item/weapon/tank/Destroy() QDEL_NULL(air_contents) - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) QDEL_NULL(src.proxyassembly) if(istype(loc, /obj/item/device/transfer_valve)) @@ -264,7 +264,7 @@ var/list/global/tank_gauge_cache = list() data["maskConnected"] = 1 // update the ui if it exists, returns null if no ui is passed/found - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.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 @@ -464,7 +464,7 @@ var/list/global/tank_gauge_cache = list() if(!T) return T.assume_air(air_contents) - playsound(get_turf(src), 'sound/weapons/shotgun.ogg', 20, 1) + playsound(get_turf(src), 'sound/weapons/Gunshot_shotgun.ogg', 20, 1) visible_message("\icon[src] \The [src] flies apart!", "You hear a bang!") T.hotspot_expose(air_contents.temperature, 70, 1) @@ -503,7 +503,7 @@ var/list/global/tank_gauge_cache = list() var/release_ratio = 0.002 if(tank_pressure) - release_ratio = Clamp(0.002, sqrt(max(tank_pressure-env_pressure,0)/tank_pressure),1) + release_ratio = CLAMP(0.002, sqrt(max(tank_pressure-env_pressure,0)/tank_pressure),1) var/datum/gas_mixture/leaked_gas = air_contents.remove_ratio(release_ratio) //dynamic air release based on ambient pressure diff --git a/code/game/objects/items/weapons/tools/screwdriver.dm b/code/game/objects/items/weapons/tools/screwdriver.dm index 86ac8f1267..249f49f529 100644 --- a/code/game/objects/items/weapons/tools/screwdriver.dm +++ b/code/game/objects/items/weapons/tools/screwdriver.dm @@ -122,4 +122,4 @@ counterpart.forceMove(get_turf(src)) src.forceMove(counterpart) user.put_in_active_hand(counterpart) - to_chat(user, "You attach the bolt driver bit to [src].") \ No newline at end of file + to_chat(user, "You attach the bolt driver bit to [src].") diff --git a/code/game/objects/items/weapons/tools/weldingtool.dm b/code/game/objects/items/weapons/tools/weldingtool.dm index 7c2f2ea26f..9aed4f82a5 100644 --- a/code/game/objects/items/weapons/tools/weldingtool.dm +++ b/code/game/objects/items/weapons/tools/weldingtool.dm @@ -39,7 +39,8 @@ var/always_process = FALSE // If true, keeps the welder on the process list even if it's off. Used for when it needs to regenerate fuel. toolspeed = 1 -/obj/item/weapon/weldingtool/New() +/obj/item/weapon/weldingtool/Initialize() + . = ..() // var/random_fuel = min(rand(10,20),max_fuel) var/datum/reagents/R = new/datum/reagents(max_fuel) reagents = R @@ -47,12 +48,12 @@ R.add_reagent("fuel", max_fuel) update_icon() if(always_process) - processing_objects |= src + START_PROCESSING(SSobj, src) ..() /obj/item/weapon/weldingtool/Destroy() if(welding || always_process) - processing_objects -= src + STOP_PROCESSING(SSobj, src) return ..() /obj/item/weapon/weldingtool/examine(mob/user) @@ -60,7 +61,7 @@ if(max_fuel) to_chat(user, text("\icon[] The [] contains []/[] units of fuel!", src, src.name, get_fuel(),src.max_fuel )) -/obj/item/weapon/weldingtool/attack(var/atom/A, var/mob/living/user, var/def_zone) +/obj/item/weapon/weldingtool/attack(atom/A, mob/living/user, def_zone) if(ishuman(A) && user.a_intent == I_HELP) var/mob/living/carbon/human/H = A var/obj/item/organ/external/S = H.organs_by_name[user.zone_sel.selecting] @@ -115,18 +116,13 @@ ..() return - /obj/item/weapon/weldingtool/process() if(welding) ++burned_fuel_for if(burned_fuel_for >= WELDER_FUEL_BURN_INTERVAL) remove_fuel(1) - - - if(get_fuel() < 1) setWelding(0) - //I'm not sure what this does. I assume it has to do with starting fires... //...but it doesnt check to see if the welder is on or not. var/turf/location = src.loc @@ -137,7 +133,6 @@ if (istype(location, /turf)) location.hotspot_expose(700, 5) - /obj/item/weapon/weldingtool/afterattack(obj/O as obj, mob/user as mob, proximity) if(!proximity) return if (istype(O, /obj/structure/reagent_dispensers/fueltank) && get_dist(src,O) <= 1) @@ -164,12 +159,8 @@ L.IgniteMob() if (istype(location, /turf)) location.hotspot_expose(700, 50, 1) - return - - -/obj/item/weapon/weldingtool/attack_self(mob/user as mob) - setWelding(!welding, usr) - return +/obj/item/weapon/weldingtool/attack_self(mob/user) + setWelding(!welding, user) //Returns the amount of fuel in the welder /obj/item/weapon/weldingtool/proc/get_fuel() @@ -198,7 +189,7 @@ //Returns whether or not the welding tool is currently on. /obj/item/weapon/weldingtool/proc/isOn() - return src.welding + return welding /obj/item/weapon/weldingtool/update_icon() ..() @@ -214,7 +205,7 @@ // Fuel counter overlay. if(change_icons && get_max_fuel()) var/ratio = get_fuel() / get_max_fuel() - ratio = Ceiling(ratio*4) * 25 + ratio = CEILING(ratio * 4, 1) * 25 var/image/I = image(icon, src, "[icon_state][ratio]") overlays.Add(I) @@ -283,7 +274,7 @@ welding = 1 update_icon() if(!always_process) - processing_objects |= src + START_PROCESSING(SSobj, src) else if(M) var/msg = max_fuel ? "welding fuel" : "charge" @@ -292,7 +283,7 @@ //Otherwise else if(!set_welding && welding) if(!always_process) - processing_objects -= src + STOP_PROCESSING(SSobj, src) if(M) to_chat(M, "You switch \the [src] off.") else if(T) @@ -609,4 +600,4 @@ /obj/item/weapon/weldingtool/electric/mounted/cyborg toolspeed = 0.5 -#undef WELDER_FUEL_BURN_INTERVAL +#undef WELDER_FUEL_BURN_INTERVAL \ No newline at end of file diff --git a/code/game/objects/items/weapons/tools/wrench.dm b/code/game/objects/items/weapons/tools/wrench.dm index e0a6957c3c..13cf3e51cf 100644 --- a/code/game/objects/items/weapons/tools/wrench.dm +++ b/code/game/objects/items/weapons/tools/wrench.dm @@ -68,4 +68,4 @@ counterpart.forceMove(get_turf(src)) src.forceMove(counterpart) user.put_in_active_hand(counterpart) - to_chat(user, "You attach the screw driver bit to [src].") \ No newline at end of file + to_chat(user, "You attach the screw driver bit to [src].") diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm index b5ae0912e9..65c61fce9d 100644 --- a/code/game/objects/items/weapons/weaponry.dm +++ b/code/game/objects/items/weapons/weaponry.dm @@ -106,7 +106,7 @@ /obj/effect/energy_net/New() ..() - processing_objects |= src + START_PROCESSING(SSobj, src) /obj/effect/energy_net/Destroy() if(has_buckled_mobs()) @@ -114,7 +114,7 @@ to_chat(A,"You are free of the net!") unbuckle_mob(A) - processing_objects -= src + STOP_PROCESSING(SSobj, src) return ..() /obj/effect/energy_net/process() diff --git a/code/game/objects/items/weapons/weldbackpack.dm b/code/game/objects/items/weapons/weldbackpack.dm index 0312ca55f8..5df0c9dbe3 100644 --- a/code/game/objects/items/weapons/weldbackpack.dm +++ b/code/game/objects/items/weapons/weldbackpack.dm @@ -9,7 +9,8 @@ var/obj/item/weapon/nozzle = null //Attached welder, or other spray device. var/nozzle_attached = 0 -/obj/item/weapon/weldpack/New() +/obj/item/weapon/weldpack/Initialize() + . = ..() var/datum/reagents/R = new/datum/reagents(max_fuel) //Lotsa refills reagents = R R.my_atom = src diff --git a/code/game/objects/mob_spawner_vr.dm b/code/game/objects/mob_spawner_vr.dm index e294c98053..7b047577ee 100644 --- a/code/game/objects/mob_spawner_vr.dm +++ b/code/game/objects/mob_spawner_vr.dm @@ -9,8 +9,8 @@ var/spawn_delay = 10 MINUTES var/list/spawn_types = list( - /mob/living/simple_animal/corgi = 100, - /mob/living/simple_animal/cat = 25 + /mob/living/simple_mob/animal/passive/dog/corgi = 100, + /mob/living/simple_mob/animal/passive/cat = 25 ) var/total_spawns = -1 //Total mob spawns, over all time, -1 for no limit @@ -24,11 +24,11 @@ /obj/structure/mob_spawner/New() ..() - processing_objects.Add(src) + START_PROCESSING(SSobj, src) last_spawn = world.time + rand(0,spawn_delay) /obj/structure/mob_spawner/Destroy() - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) for(var/mob/living/L in spawned_mobs) L.source_spawner = null spawned_mobs.Cut() @@ -129,15 +129,14 @@ It also makes it so a ghost wont know where all the goodies/mobs are. ////////////// // Spawners // ///////////// - /obj/structure/mob_spawner/scanner/corgi name = "Corgi Lazy Spawner" desc = "This is a proof of concept, not sure why you would use this one" spawn_delay = 3 MINUTES mob_faction = "Corgi" spawn_types = list( - /mob/living/simple_animal/corgi = 75, - /mob/living/simple_animal/corgi/puppy = 50 + /mob/living/simple_mob/animal/passive/dog/corgi = 75, + /mob/living/simple_mob/animal/passive/dog/corgi/puppy = 50 ) simultaneous_spawns = 5 @@ -157,10 +156,10 @@ It also makes it so a ghost wont know where all the goodies/mobs are. anchored = 1 invisibility = 101 spawn_types = list( - /mob/living/simple_animal/retaliate/gaslamp = 20, - /mob/living/simple_animal/otie/feral = 10, - /mob/living/simple_animal/hostile/dino/virgo3b = 5, - /mob/living/simple_animal/hostile/dragon/virgo3b = 1 + /mob/living/simple_mob/animal/space/gaslamp = 20, +// /mob/living/simple_mob/otie/feral = 10, + /mob/living/simple_mob/vore/dino/virgo3b = 5, + /mob/living/simple_mob/vore/dragon/virgo3b = 1 ) /obj/structure/mob_spawner/scanner/xenos @@ -176,10 +175,10 @@ It also makes it so a ghost wont know where all the goodies/mobs are. icon = 'icons/mob/actions.dmi' icon_state = "alien_egg" spawn_types = list( - /mob/living/simple_animal/hostile/alien/drone = 20, - /mob/living/simple_animal/hostile/alien = 10, - /mob/living/simple_animal/hostile/alien/sentinel = 5, - /mob/living/simple_animal/hostile/alien/queen = 1 + /mob/living/simple_mob/animal/space/alien/drone = 20, + /mob/living/simple_mob/animal/space/alien = 10, + /mob/living/simple_mob/animal/space/alien/sentinel = 5, + /mob/living/simple_mob/animal/space/alien/queen = 1 ) /obj/structure/mob_spawner/scanner/xenos/royal @@ -195,5 +194,5 @@ It also makes it so a ghost wont know where all the goodies/mobs are. icon = 'icons/mob/actions.dmi' icon_state = "alien_egg" spawn_types = list( - /mob/living/simple_animal/hostile/alien/queen = 5, - ) \ No newline at end of file + /mob/living/simple_mob/animal/space/alien/queen = 5, + ) diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 9c2fb60434..999b5fca99 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -18,11 +18,29 @@ var/can_speak = 0 //For MMIs and admin trickery. If an object has a brainmob in its contents, set this to 1 to allow it to speak. var/show_examine = TRUE // Does this pop up on a mob when the mob is examined? + var/register_as_dangerous_object = FALSE // Should this tell its turf that it is dangerous automatically? + +/obj/Initialize() + if(register_as_dangerous_object) + register_dangerous_to_step() + return ..() /obj/Destroy() - processing_objects -= src + STOP_PROCESSING(SSobj, src) + if(register_as_dangerous_object) + unregister_dangerous_to_step() return ..() +/obj/Moved(atom/oldloc) + . = ..() + if(register_as_dangerous_object) + var/turf/old_turf = get_turf(oldloc) + var/turf/new_turf = get_turf(src) + + if(old_turf != new_turf) + old_turf.unregister_dangerous_object(src) + new_turf.register_dangerous_object(src) + /obj/Topic(href, href_list, var/datum/topic_state/state = default_state) if(usr && ..()) return 1 @@ -58,10 +76,6 @@ /obj/item/proc/is_used_on(obj/O, mob/user) -/obj/proc/process() - processing_objects.Remove(src) - return 0 - /obj/assume_air(datum/gas_mixture/giver) if(loc) return loc.assume_air(giver) @@ -165,4 +179,19 @@ return /obj/proc/get_cell() - return \ No newline at end of file + return + +// Used to mark a turf as containing objects that are dangerous to step onto. +/obj/proc/register_dangerous_to_step() + var/turf/T = get_turf(src) + if(T) + T.register_dangerous_object(src) + +/obj/proc/unregister_dangerous_to_step() + var/turf/T = get_turf(src) + if(T) + T.unregister_dangerous_object(src) + +// Test for if stepping on a tile containing this obj is safe to do, used for things like landmines and cliffs. +/obj/proc/is_safe_to_step(mob/living/L) + return TRUE \ No newline at end of file diff --git a/code/game/objects/random/_random.dm b/code/game/objects/random/_random.dm index 29272a7247..8a146f82c4 100644 --- a/code/game/objects/random/_random.dm +++ b/code/game/objects/random/_random.dm @@ -4,27 +4,27 @@ icon = 'icons/misc/mark.dmi' icon_state = "rup" var/spawn_nothing_percentage = 0 // this variable determines the likelyhood that this random object will not spawn anything + var/drop_get_turf = TRUE // creates a new object and deletes itself -/obj/random/New() - ..() - spawn() - if(istype(src.loc, /obj/structure/loot_pile)) //Spawning from a lootpile is weird, need to wait until we're out of it to do our work. - while(istype(src.loc, /obj/structure/loot_pile)) - sleep(1) - if (!prob(spawn_nothing_percentage)) - spawn_item() - qdel(src) +/obj/random/Initialize() + . = ..() + if (!prob(spawn_nothing_percentage)) + spawn_item() + qdel(src) // this function should return a specific item to spawn /obj/random/proc/item_to_spawn() return 0 +/obj/random/drop_location() + return drop_get_turf? get_turf(src) : ..() + // creates the random item /obj/random/proc/spawn_item() var/build_path = item_to_spawn() - var/atom/A = new build_path(src.loc) + var/atom/A = new build_path(drop_location()) if(pixel_x || pixel_y) A.pixel_x = pixel_x A.pixel_y = pixel_y @@ -100,7 +100,7 @@ var/list/multi_point_spawns var/id // Group id var/weight // Probability weight for this spawn point -/obj/random_multi/initialize() +/obj/random_multi/Initialize() . = ..() weight = max(1, round(weight)) diff --git a/code/game/objects/random/mob.dm b/code/game/objects/random/mob.dm index 6daa10c0f9..966498a2bd 100644 --- a/code/game/objects/random/mob.dm +++ b/code/game/objects/random/mob.dm @@ -18,44 +18,47 @@ var/mob_retaliate = 0 /obj/random/mob/item_to_spawn() - return pick(prob(10);/mob/living/simple_animal/lizard, - prob(6);/mob/living/simple_animal/retaliate/diyaab, - prob(10);/mob/living/simple_animal/cat/fluff, - prob(6);/mob/living/simple_animal/cat/kitten, - prob(10);/mob/living/simple_animal/corgi, - prob(6);/mob/living/simple_animal/corgi/puppy, - prob(10);/mob/living/simple_animal/crab, - prob(10);/mob/living/simple_animal/chicken, - prob(6);/mob/living/simple_animal/chick, - prob(10);/mob/living/simple_animal/cow, - prob(6);/mob/living/simple_animal/retaliate/goat, - prob(10);/mob/living/simple_animal/penguin, - prob(10);/mob/living/simple_animal/mouse, - prob(10);/mob/living/simple_animal/yithian, - prob(10);/mob/living/simple_animal/tindalos, - prob(10);/mob/living/simple_animal/corgi/tamaskan, - prob(3);/mob/living/simple_animal/parrot, - prob(1);/mob/living/simple_animal/giant_crab) + return pick(prob(10);/mob/living/simple_mob/animal/passive/lizard, + prob(6);/mob/living/simple_mob/animal/sif/diyaab, + prob(10);/mob/living/simple_mob/animal/passive/cat, + prob(6);/mob/living/simple_mob/animal/passive/cat, + prob(10);/mob/living/simple_mob/animal/passive/dog/corgi, + prob(6);/mob/living/simple_mob/animal/passive/dog/corgi/puppy, + prob(10);/mob/living/simple_mob/animal/passive/crab, + prob(10);/mob/living/simple_mob/animal/passive/chicken, + prob(6);/mob/living/simple_mob/animal/passive/chick, + prob(10);/mob/living/simple_mob/animal/passive/cow, + prob(6);/mob/living/simple_mob/animal/goat, + prob(10);/mob/living/simple_mob/animal/passive/penguin, + prob(10);/mob/living/simple_mob/animal/passive/mouse, + prob(10);/mob/living/simple_mob/animal/passive/yithian, + prob(10);/mob/living/simple_mob/animal/passive/tindalos, + prob(10);/mob/living/simple_mob/animal/passive/dog/tamaskan, + prob(3);/mob/living/simple_mob/animal/passive/bird/parrot, + prob(1);/mob/living/simple_mob/animal/passive/crab) /obj/random/mob/spawn_item() //These should only ever have simple mobs. var/build_path = item_to_spawn() - var/mob/living/simple_animal/M = new build_path(src.loc) - M.ai_inactive = 1 //Don't fight eachother while we're still setting up! - if(mob_faction) - M.faction = mob_faction - M.returns_home = mob_returns_home - M.wander = mob_wander - M.wander_distance = mob_wander_distance - if(overwrite_hostility) - M.hostile = mob_hostile - M.retaliate = mob_retaliate - M.ai_inactive = 0 //Now you can kill eachother if your faction didn't override. + var/mob/living/simple_mob/M = new build_path(src.loc) + if(!istype(M)) + return + if(M.has_AI()) + var/datum/ai_holder/AI = M.ai_holder + AI.go_sleep() //Don't fight eachother while we're still setting up! + AI.returns_home = mob_returns_home + AI.wander = mob_wander + AI.max_home_distance = mob_wander_distance + if(overwrite_hostility) + AI.hostile = mob_hostile + AI.retaliate = mob_retaliate + AI.go_wake() //Now you can kill eachother if your faction didn't override. if(pixel_x || pixel_y) M.pixel_x = pixel_x M.pixel_y = pixel_y + /obj/random/mob/sif name = "Random Sif Animal" desc = "This is a random cold weather animal." @@ -65,14 +68,14 @@ mob_wander_distance = 10 /obj/random/mob/sif/item_to_spawn() - return pick(prob(30);/mob/living/simple_animal/retaliate/diyaab, - prob(15);/mob/living/simple_animal/crab, - prob(15);/mob/living/simple_animal/penguin, - prob(15);/mob/living/simple_animal/mouse, - prob(15);/mob/living/simple_animal/corgi/tamaskan, - prob(2);/mob/living/simple_animal/hostile/giant_spider/frost, - prob(1);/mob/living/simple_animal/hostile/goose, - prob(20);/mob/living/simple_animal/giant_crab) + return pick(prob(30);/mob/living/simple_mob/animal/sif/diyaab, + prob(15);/mob/living/simple_mob/animal/passive/crab, + prob(15);/mob/living/simple_mob/animal/passive/penguin, + prob(15);/mob/living/simple_mob/animal/passive/mouse, + prob(15);/mob/living/simple_mob/animal/passive/dog/tamaskan, + prob(2);/mob/living/simple_mob/animal/giant_spider/frost, + prob(1);/mob/living/simple_mob/animal/space/goose, + prob(20);/mob/living/simple_mob/animal/passive/crab) /obj/random/mob/sif/peaceful @@ -84,12 +87,12 @@ mob_wander_distance = 12 /obj/random/mob/sif/peaceful/item_to_spawn() - return pick(prob(30);/mob/living/simple_animal/retaliate/diyaab, - prob(15);/mob/living/simple_animal/crab, - prob(15);/mob/living/simple_animal/penguin, - prob(15);/mob/living/simple_animal/mouse, - prob(15);/mob/living/simple_animal/corgi/tamaskan, - prob(20);/mob/living/simple_animal/giant_crab) + return pick(prob(30);/mob/living/simple_mob/animal/sif/diyaab, + prob(15);/mob/living/simple_mob/animal/passive/crab, + prob(15);/mob/living/simple_mob/animal/passive/penguin, + prob(15);/mob/living/simple_mob/animal/passive/mouse, + prob(15);/mob/living/simple_mob/animal/passive/dog/tamaskan, + prob(20);/mob/living/simple_mob/animal/sif/hooligan_crab) /obj/random/mob/sif/hostile name = "Random Hostile Sif Animal" @@ -97,9 +100,9 @@ icon_state = "frost" /obj/random/mob/sif/hostile/item_to_spawn() - return pick(prob(22);/mob/living/simple_animal/hostile/savik, - prob(33);/mob/living/simple_animal/hostile/giant_spider/frost, - prob(45);/mob/living/simple_animal/hostile/shantak) + return pick(prob(22);/mob/living/simple_mob/animal/sif/savik, + prob(33);/mob/living/simple_mob/animal/giant_spider/frost, + prob(45);/mob/living/simple_mob/animal/sif/shantak) /obj/random/mob/spider name = "Random Spider" //Spiders should patrol where they spawn. @@ -110,9 +113,9 @@ mob_wander_distance = 4 /obj/random/mob/spider/item_to_spawn() - return pick(prob(22);/mob/living/simple_animal/hostile/giant_spider/nurse, - prob(33);/mob/living/simple_animal/hostile/giant_spider/hunter, - prob(45);/mob/living/simple_animal/hostile/giant_spider) + return pick(prob(22);/mob/living/simple_mob/animal/giant_spider/nurse, + prob(33);/mob/living/simple_mob/animal/giant_spider/hunter, + prob(45);/mob/living/simple_mob/animal/giant_spider) /obj/random/mob/spider/nurse name = "Random Nurse Spider" @@ -123,8 +126,8 @@ mob_wander_distance = 4 /obj/random/mob/spider/nurse/item_to_spawn() - return pick(prob(22);/mob/living/simple_animal/hostile/giant_spider/nurse/hat, - prob(45);/mob/living/simple_animal/hostile/giant_spider/nurse) + return pick(prob(22);/mob/living/simple_mob/animal/giant_spider/nurse/hat, + prob(45);/mob/living/simple_mob/animal/giant_spider/nurse) /obj/random/mob/spider/mutant name = "Random Mutant Spider" @@ -133,15 +136,15 @@ /obj/random/mob/spider/mutant/item_to_spawn() return pick(prob(5);/obj/random/mob/spider, - prob(10);/mob/living/simple_animal/hostile/giant_spider/webslinger, - prob(10);/mob/living/simple_animal/hostile/giant_spider/carrier, - prob(33);/mob/living/simple_animal/hostile/giant_spider/lurker, - prob(33);/mob/living/simple_animal/hostile/giant_spider/tunneler, - prob(40);/mob/living/simple_animal/hostile/giant_spider/pepper, - prob(20);/mob/living/simple_animal/hostile/giant_spider/thermic, - prob(40);/mob/living/simple_animal/hostile/giant_spider/electric, - prob(1);/mob/living/simple_animal/hostile/giant_spider/phorogenic, - prob(40);/mob/living/simple_animal/hostile/giant_spider/frost) + prob(10);/mob/living/simple_mob/animal/giant_spider/webslinger, + prob(10);/mob/living/simple_mob/animal/giant_spider/carrier, + prob(33);/mob/living/simple_mob/animal/giant_spider/lurker, + prob(33);/mob/living/simple_mob/animal/giant_spider/tunneler, + prob(40);/mob/living/simple_mob/animal/giant_spider/pepper, + prob(20);/mob/living/simple_mob/animal/giant_spider/thermic, + prob(40);/mob/living/simple_mob/animal/giant_spider/electric, + prob(1);/mob/living/simple_mob/animal/giant_spider/phorogenic, + prob(40);/mob/living/simple_mob/animal/giant_spider/frost) /obj/random/mob/robotic name = "Random Robot Mob" @@ -158,17 +161,18 @@ mob_retaliate = 1 /obj/random/mob/robotic/item_to_spawn() //Hivebots have a total number of 'lots' equal to the lesser drone, at 60. - return pick(prob(60);/mob/living/simple_animal/hostile/malf_drone/lesser, - prob(50);/mob/living/simple_animal/hostile/malf_drone, - prob(15);/mob/living/simple_animal/hostile/mecha/malf_drone, - prob(10);/mob/living/simple_animal/hostile/hivebot, - prob(15);/mob/living/simple_animal/hostile/hivebot/swarm, - prob(10);/mob/living/simple_animal/hostile/hivebot/range, - prob(5);/mob/living/simple_animal/hostile/hivebot/range/rapid, - prob(5);/mob/living/simple_animal/hostile/hivebot/range/ion, - prob(5);/mob/living/simple_animal/hostile/hivebot/range/laser, - prob(5);/mob/living/simple_animal/hostile/hivebot/range/strong, - prob(5);/mob/living/simple_animal/hostile/hivebot/range/guard) + return pick(prob(60);/mob/living/simple_mob/mechanical/combat_drone/lesser, + prob(50);/mob/living/simple_mob/mechanical/combat_drone, + prob(15);/mob/living/simple_mob/mechanical/mecha/ripley, + prob(15);/mob/living/simple_mob/mechanical/mecha/odysseus, + prob(10);/mob/living/simple_mob/mechanical/hivebot, + prob(15);/mob/living/simple_mob/mechanical/hivebot/swarm, + prob(10);/mob/living/simple_mob/mechanical/hivebot/ranged_damage, + prob(5);/mob/living/simple_mob/mechanical/hivebot/ranged_damage/rapid, + prob(5);/mob/living/simple_mob/mechanical/hivebot/ranged_damage/ion, + prob(5);/mob/living/simple_mob/mechanical/hivebot/ranged_damage/laser, + prob(5);/mob/living/simple_mob/mechanical/hivebot/ranged_damage/strong, + prob(5);/mob/living/simple_mob/mechanical/hivebot/ranged_damage/strong/guard) /obj/random/mob/robotic/hivebot name = "Random Hivebot" @@ -178,14 +182,14 @@ mob_faction = "hivebot" /obj/random/mob/robotic/hivebot/item_to_spawn() - return pick(prob(10);/mob/living/simple_animal/hostile/hivebot, - prob(15);/mob/living/simple_animal/hostile/hivebot/swarm, - prob(10);/mob/living/simple_animal/hostile/hivebot/range, - prob(5);/mob/living/simple_animal/hostile/hivebot/range/rapid, - prob(5);/mob/living/simple_animal/hostile/hivebot/range/ion, - prob(5);/mob/living/simple_animal/hostile/hivebot/range/laser, - prob(5);/mob/living/simple_animal/hostile/hivebot/range/strong, - prob(5);/mob/living/simple_animal/hostile/hivebot/range/guard) + return pick(prob(10);/mob/living/simple_mob/mechanical/hivebot, + prob(15);/mob/living/simple_mob/mechanical/hivebot/swarm, + prob(10);/mob/living/simple_mob/mechanical/hivebot/ranged_damage, + prob(5);/mob/living/simple_mob/mechanical/hivebot/ranged_damage/rapid, + prob(5);/mob/living/simple_mob/mechanical/hivebot/ranged_damage/ion, + prob(5);/mob/living/simple_mob/mechanical/hivebot/ranged_damage/laser, + prob(5);/mob/living/simple_mob/mechanical/hivebot/ranged_damage/strong, + prob(5);/mob/living/simple_mob/mechanical/hivebot/ranged_damage/strong/guard) //Mice @@ -195,7 +199,7 @@ icon_state = "mouse_gray" /obj/random/mob/mouse/item_to_spawn() - return pick(prob(15);/mob/living/simple_animal/mouse/white, - prob(30);/mob/living/simple_animal/mouse/brown, - prob(30);/mob/living/simple_animal/mouse/gray, + return pick(prob(15);/mob/living/simple_mob/animal/passive/mouse/white, + prob(30);/mob/living/simple_mob/animal/passive/mouse/brown, + prob(30);/mob/living/simple_mob/animal/passive/mouse/gray, prob(25);/obj/random/mouseremains) //because figuring out how to come up with it picking nothing is beyond my coding ability. diff --git a/code/game/objects/random/random.dm b/code/game/objects/random/random.dm index 196b597c79..301323ba3d 100644 --- a/code/game/objects/random/random.dm +++ b/code/game/objects/random/random.dm @@ -1058,7 +1058,7 @@ var/list/multi_point_spawns var/id // Group id var/weight // Probability weight for this spawn point -/obj/random_multi/initialize() +/obj/random_multi/Initialize() . = ..() weight = max(1, round(weight)) @@ -1531,24 +1531,24 @@ var/list/multi_point_spawns icon_state = "chicken_white" /obj/random/mob/item_to_spawn() - return pick(prob(10);/mob/living/simple_animal/lizard, - prob(6);/mob/living/simple_animal/retaliate/diyaab, - prob(10);/mob/living/simple_animal/cat/fluff, - prob(6);/mob/living/simple_animal/cat/kitten, - prob(10);/mob/living/simple_animal/corgi, - prob(6);/mob/living/simple_animal/corgi/puppy, - prob(10);/mob/living/simple_animal/crab, - prob(10);/mob/living/simple_animal/chicken, - prob(6);/mob/living/simple_animal/chick, - prob(10);/mob/living/simple_animal/cow, - prob(6);/mob/living/simple_animal/retaliate/goat, - prob(10);/mob/living/simple_animal/penguin, - prob(10);/mob/living/simple_animal/mouse, - prob(10);/mob/living/simple_animal/yithian, - prob(10);/mob/living/simple_animal/tindalos, - prob(10);/mob/living/simple_animal/corgi/tamaskan, - prob(3);/mob/living/simple_animal/parrot, - prob(1);/mob/living/simple_animal/giant_crab) + return pick(prob(10);/mob/living/simple_mob/lizard, + prob(6);/mob/living/simple_mob/retaliate/diyaab, + prob(10);/mob/living/simple_mob/cat/fluff, + prob(6);/mob/living/simple_mob/cat/kitten, + prob(10);/mob/living/simple_mob/corgi, + prob(6);/mob/living/simple_mob/corgi/puppy, + prob(10);/mob/living/simple_mob/crab, + prob(10);/mob/living/simple_mob/chicken, + prob(6);/mob/living/simple_mob/chick, + prob(10);/mob/living/simple_mob/cow, + prob(6);/mob/living/simple_mob/retaliate/goat, + prob(10);/mob/living/simple_mob/penguin, + prob(10);/mob/living/simple_mob/mouse, + prob(10);/mob/living/simple_mob/yithian, + prob(10);/mob/living/simple_mob/tindalos, + prob(10);/mob/living/simple_mob/corgi/tamaskan, + prob(3);/mob/living/simple_mob/parrot, + prob(1);/mob/living/simple_mob/giant_crab) /obj/random/mob/sif name = "Random Sif Animal" @@ -1556,14 +1556,14 @@ var/list/multi_point_spawns icon_state = "penguin" /obj/random/mob/sif/item_to_spawn() - return pick(prob(30);/mob/living/simple_animal/retaliate/diyaab, - prob(15);/mob/living/simple_animal/crab, - prob(15);/mob/living/simple_animal/penguin, - prob(15);/mob/living/simple_animal/mouse, - prob(15);/mob/living/simple_animal/corgi/tamaskan, - prob(2);/mob/living/simple_animal/hostile/giant_spider/frost, - prob(1);/mob/living/simple_animal/hostile/goose, - prob(20);/mob/living/simple_animal/giant_crab) + return pick(prob(30);/mob/living/simple_mob/retaliate/diyaab, + prob(15);/mob/living/simple_mob/crab, + prob(15);/mob/living/simple_mob/penguin, + prob(15);/mob/living/simple_mob/mouse, + prob(15);/mob/living/simple_mob/corgi/tamaskan, + prob(2);/mob/living/simple_mob/hostile/giant_spider/frost, + prob(1);/mob/living/simple_mob/hostile/goose, + prob(20);/mob/living/simple_mob/giant_crab) /obj/random/mob/sif/hostile name = "Random Hostile Sif Animal" @@ -1571,9 +1571,9 @@ var/list/multi_point_spawns icon_state = "frost" /obj/random/mob/sif/hostile/item_to_spawn() - return pick(prob(22);/mob/living/simple_animal/hostile/savik, - prob(33);/mob/living/simple_animal/hostile/giant_spider/frost, - prob(45);/mob/living/simple_animal/hostile/shantak) + return pick(prob(22);/mob/living/simple_mob/hostile/savik, + prob(33);/mob/living/simple_mob/hostile/giant_spider/frost, + prob(45);/mob/living/simple_mob/hostile/shantak) /obj/random/mob/spider name = "Random Spider" @@ -1581,9 +1581,9 @@ var/list/multi_point_spawns icon_state = "guard" /obj/random/mob/spider/item_to_spawn() - return pick(prob(22);/mob/living/simple_animal/hostile/giant_spider/nurse, - prob(33);/mob/living/simple_animal/hostile/giant_spider/hunter, - prob(45);/mob/living/simple_animal/hostile/giant_spider) + return pick(prob(22);/mob/living/simple_mob/hostile/giant_spider/nurse, + prob(33);/mob/living/simple_mob/hostile/giant_spider/hunter, + prob(45);/mob/living/simple_mob/hostile/giant_spider) /obj/random/mob/spider/mutant name = "Random Mutant Spider" @@ -1592,15 +1592,15 @@ var/list/multi_point_spawns /obj/random/mob/spider/mutant/item_to_spawn() return pick(prob(5);/obj/random/mob/spider, - prob(10);/mob/living/simple_animal/hostile/giant_spider/webslinger, - prob(10);/mob/living/simple_animal/hostile/giant_spider/carrier, - prob(33);/mob/living/simple_animal/hostile/giant_spider/lurker, - prob(33);/mob/living/simple_animal/hostile/giant_spider/tunneler, - prob(40);/mob/living/simple_animal/hostile/giant_spider/pepper, - prob(20);/mob/living/simple_animal/hostile/giant_spider/thermic, - prob(40);/mob/living/simple_animal/hostile/giant_spider/electric, - prob(1);/mob/living/simple_animal/hostile/giant_spider/phorogenic, - prob(40);/mob/living/simple_animal/hostile/giant_spider/frost) + prob(10);/mob/living/simple_mob/hostile/giant_spider/webslinger, + prob(10);/mob/living/simple_mob/hostile/giant_spider/carrier, + prob(33);/mob/living/simple_mob/hostile/giant_spider/lurker, + prob(33);/mob/living/simple_mob/hostile/giant_spider/tunneler, + prob(40);/mob/living/simple_mob/hostile/giant_spider/pepper, + prob(20);/mob/living/simple_mob/hostile/giant_spider/thermic, + prob(40);/mob/living/simple_mob/hostile/giant_spider/electric, + prob(1);/mob/living/simple_mob/hostile/giant_spider/phorogenic, + prob(40);/mob/living/simple_mob/hostile/giant_spider/frost) /obj/random/mob/robotic name = "Random Robot Mob" @@ -1608,17 +1608,17 @@ var/list/multi_point_spawns icon_state = "drone_dead" /obj/random/mob/robotic/item_to_spawn() //Hivebots have a total number of 'lots' equal to the lesser drone, at 60. - return pick(prob(60);/mob/living/simple_animal/hostile/malf_drone/lesser, - prob(50);/mob/living/simple_animal/hostile/malf_drone, - prob(15);/mob/living/simple_animal/hostile/mecha/malf_drone, - prob(10);/mob/living/simple_animal/hostile/hivebot, - prob(15);/mob/living/simple_animal/hostile/hivebot/swarm, - prob(10);/mob/living/simple_animal/hostile/hivebot/range, - prob(5);/mob/living/simple_animal/hostile/hivebot/range/rapid, - prob(5);/mob/living/simple_animal/hostile/hivebot/range/ion, - prob(5);/mob/living/simple_animal/hostile/hivebot/range/laser, - prob(5);/mob/living/simple_animal/hostile/hivebot/range/strong, - prob(5);/mob/living/simple_animal/hostile/hivebot/range/guard) + return pick(prob(60);/mob/living/simple_mob/hostile/malf_drone/lesser, + prob(50);/mob/living/simple_mob/hostile/malf_drone, + prob(15);/mob/living/simple_mob/hostile/mecha/malf_drone, + prob(10);/mob/living/simple_mob/hostile/hivebot, + prob(15);/mob/living/simple_mob/hostile/hivebot/swarm, + prob(10);/mob/living/simple_mob/hostile/hivebot/range, + prob(5);/mob/living/simple_mob/hostile/hivebot/range/rapid, + prob(5);/mob/living/simple_mob/hostile/hivebot/range/ion, + prob(5);/mob/living/simple_mob/hostile/hivebot/range/laser, + prob(5);/mob/living/simple_mob/hostile/hivebot/range/strong, + prob(5);/mob/living/simple_mob/hostile/hivebot/range/guard) /obj/random/mob/robotic/hivebot name = "Random Hivebot" @@ -1626,11 +1626,11 @@ var/list/multi_point_spawns icon_state = "drone3" /obj/random/mob/robotic/hivebot/item_to_spawn() - return pick(prob(10);/mob/living/simple_animal/hostile/hivebot, - prob(15);/mob/living/simple_animal/hostile/hivebot/swarm, - prob(10);/mob/living/simple_animal/hostile/hivebot/range, - prob(5);/mob/living/simple_animal/hostile/hivebot/range/rapid, - prob(5);/mob/living/simple_animal/hostile/hivebot/range/ion, - prob(5);/mob/living/simple_animal/hostile/hivebot/range/laser, - prob(5);/mob/living/simple_animal/hostile/hivebot/range/strong, - prob(5);/mob/living/simple_animal/hostile/hivebot/range/guard) + return pick(prob(10);/mob/living/simple_mob/hostile/hivebot, + prob(15);/mob/living/simple_mob/hostile/hivebot/swarm, + prob(10);/mob/living/simple_mob/hostile/hivebot/range, + prob(5);/mob/living/simple_mob/hostile/hivebot/range/rapid, + prob(5);/mob/living/simple_mob/hostile/hivebot/range/ion, + prob(5);/mob/living/simple_mob/hostile/hivebot/range/laser, + prob(5);/mob/living/simple_mob/hostile/hivebot/range/strong, + prob(5);/mob/living/simple_mob/hostile/hivebot/range/guard) diff --git a/code/game/objects/random/random_vr.dm b/code/game/objects/random/random_vr.dm index 4e454df55a..dcae284a18 100644 --- a/code/game/objects/random/random_vr.dm +++ b/code/game/objects/random/random_vr.dm @@ -181,15 +181,15 @@ /obj/random/outside_mob/item_to_spawn() // Special version for mobs to have the same faction. return pick( - prob(50);/mob/living/simple_animal/retaliate/gaslamp, -// prob(50);/mob/living/simple_animal/otie/feral, // Removed until Otie code is unfucked. - prob(20);/mob/living/simple_animal/hostile/dino/virgo3b, - prob(1);/mob/living/simple_animal/hostile/dragon/virgo3b) + prob(50);/mob/living/simple_mob/animal/space/gaslamp, +// prob(50);/mob/living/simple_mob/otie/feral, // Removed until Otie code is unfucked. + prob(20);/mob/living/simple_mob/vore/dino/virgo3b, + prob(1);/mob/living/simple_mob/vore/dragon/virgo3b) /obj/random/outside_mob/spawn_item() . = ..() - if(istype(., /mob/living/simple_animal)) - var/mob/living/simple_animal/this_mob = . + if(istype(., /mob/living/simple_mob)) + var/mob/living/simple_mob/this_mob = . this_mob.faction = src.faction if (this_mob.minbodytemp > 200) // Temporary hotfix. Eventually I'll add code to change all mob vars to fit the environment they are spawned in. this_mob.minbodytemp = 200 diff --git a/code/game/objects/random/unidentified/medicine.dm b/code/game/objects/random/unidentified/medicine.dm new file mode 100644 index 0000000000..f779d75a0f --- /dev/null +++ b/code/game/objects/random/unidentified/medicine.dm @@ -0,0 +1,149 @@ +/* +Semi-randomized loot for PoIs involving medicine. +Note that most of these include both 'good' and 'bad' results, with the bad results often being +much more likely to show up. This is done for several purposes; + + * A large influx of valuable medicine makes medical/SAR less needed for explorers, which is something we want to avoid. + * Blindly using autoinjectors should be risky, and to accomplish that, it needs to be more likely to get a bad effect. + * A large amount of bad loot helps make the good loot feel better to acquire. + +*/ + +// This one makes a purely random hypo. Not recommended for PoIs since it will produce nonsensical results for a PoI's theme. +// It's more of a thing to help pick specific hypos for the other lists. +/obj/random/unidentified_medicine + name = "unidentified medicine" + desc = "This will make a random hypo." + icon = 'icons/obj/syringe.dmi' + icon_state = "autoinjector1" + +/obj/random/unidentified_medicine/item_to_spawn() + return pick( + /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/brute/unidentified, + /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/burn/unidentified, + /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/toxin/unidentified, + /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/oxy/unidentified, + /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/purity/unidentified, + /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/pain/unidentified, + /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/organ/unidentified, + /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/clotting/unidentified, + /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/bonemed/unidentified, + /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/combat/unidentified, + /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/healing_nanites/unidentified, + /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/stimm/unidentified, + /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/space_drugs/unidentified, + /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/expired/unidentified, + /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/serotrotium/unidentified, + /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/cryptobiolin/unidentified, + /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/mindbreaker/unidentified, + /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/psilocybin/unidentified, + /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/soporific/unidentified, + /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/cyanide/unidentified, + /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/impedrezene/unidentified, + /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/mutagen/unidentified, + /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/defective_nanites/unidentified, + /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/contaminated/unidentified) + +// Produces things you might find in an old medicine cabinet in a PoI. +// Old cabinets are typical of ruins and abandoned buildings in the plains, meaning they're usually easier to reach, and as such, inferior loot. +/obj/random/unidentified_medicine/old_medicine/item_to_spawn() + // 30 Good, 70 Bad. 30% to get something good. + // Poor odds, but these are fairly easy to reach as they're in abandoned areas. + return pick( + prob(5);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/brute/unidentified, + prob(5);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/burn/unidentified, + prob(5);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/toxin/unidentified, + prob(5);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/oxy/unidentified, + prob(5);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/purity/unidentified, + prob(5);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/pain/unidentified, + prob(65);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/expired/unidentified, + prob(5);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/contaminated/unidentified) + +// Medicine belonging to a place still being occupied (or was recently), meaning the goods might still be fresh, and better. +/obj/random/unidentified_medicine/fresh_medicine/item_to_spawn() + // More likely to get something good, and a chance to get rare medicines. + // 75 Good, 25 Bad. 75% chance of getting something good. + // Good odds, but the contents aren't super great unless someone gets lucky. + return pick( + prob(10);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/brute/unidentified, + prob(10);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/burn/unidentified, + prob(10);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/toxin/unidentified, + prob(10);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/oxy/unidentified, + prob(10);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/purity/unidentified, + prob(10);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/pain/unidentified, + prob(5);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/organ/unidentified, + prob(5);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/clotting/unidentified, + prob(5);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/bonemed/unidentified, + prob(25);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/expired/unidentified) + +// For military PoIs like BSD. High odds of good loot since those PoIs are really hard. +/obj/random/unidentified_medicine/combat_medicine/item_to_spawn() + // More likely to get something good, and a chance to get rare medicines. + // 75 Good, 30 Bad, roughly 71.4% chance to get something good. + // Very high but very hard to reach and still has a chance of ending poorly if injecting blind. + return pick( + prob(5);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/brute/unidentified, + prob(5);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/burn/unidentified, + prob(5);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/pain/unidentified, + prob(10);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/organ/unidentified, + prob(10);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/clotting/unidentified, + prob(10);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/bonemed/unidentified, + prob(30);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/combat/unidentified, + prob(10);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/soporific/unidentified, + prob(30);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/cyanide/unidentified) + +// Hyposprays found inside various illicit places. +/obj/random/unidentified_medicine/drug_den/item_to_spawn() + // Combat stims are common, but so are nasty drugs. + // 65 Good, 160 Bad, roughly 28.8% to get something good. + // Poor odds, but there are a lot of these scattered in the drug dens and illegal chem labs. + return pick( + prob(10);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/pain/unidentified, + prob(5);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/organ/unidentified, + prob(5);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/clotting/unidentified, + prob(5);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/bonemed/unidentified, + prob(40);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/combat/unidentified, + prob(20);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/stimm/unidentified, + prob(20);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/space_drugs/unidentified, + prob(20);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/serotrotium/unidentified, + prob(20);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/cryptobiolin/unidentified, + prob(20);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/mindbreaker/unidentified, + prob(20);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/psilocybin/unidentified, + prob(20);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/soporific/unidentified, + prob(10);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/impedrezene/unidentified, + prob(5);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/cyanide/unidentified, + prob(5);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/contaminated/unidentified) + +// Medicine made FOR SCIENCE. +/obj/random/unidentified_medicine/scientific/item_to_spawn() + // Potential for amazing loot, also potential for very nasty consequences if injecting blind. + // 45 Good, 45 Bad, 50% chance to get something good. + // Do you feel lucky? + return pick( + prob(10);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/organ/unidentified, + prob(10);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/clotting/unidentified, + prob(10);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/bonemed/unidentified, + prob(10);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/combat/unidentified, + prob(5);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/healing_nanites/unidentified, + prob(20);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/contaminated/unidentified, + prob(10);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/cyanide/unidentified, + prob(10);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/mutagen/unidentified, + prob(5);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/defective_nanites/unidentified) + +// Nanomachines, son. Found in very advanced places such as the Crashed UFO. +/obj/random/unidentified_medicine/nanites/item_to_spawn() + // You better identify this if you value your life. + // 30 Good, 70 Bad. 30% of getting a good outcome. + return pick( + prob(30);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/healing_nanites/unidentified, + prob(70);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/defective_nanites/unidentified) + +// Found in virus-related areas like the Quarantined Shuttle. +/obj/random/unidentified_medicine/viral/item_to_spawn() + // Another one where's its important to identify the hypo. + // 30 Good, 70 Bad. 30% of getting a good outcome. + return pick( + prob(30);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/purity/unidentified, + prob(40);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/expired/unidentified, + prob(10);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/mutagen/unidentified, + prob(20);/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/contaminated/unidentified) \ No newline at end of file diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm index faa9f024f0..4d0eb2b9ee 100644 --- a/code/game/objects/structures.dm +++ b/code/game/objects/structures.dm @@ -3,9 +3,11 @@ w_class = ITEMSIZE_NO_CONTAINER var/climbable + var/climb_delay = 3.5 SECONDS var/breakable var/parts var/list/climbers = list() + var/block_turf_edges = FALSE // If true, turf edge icons will not be made on the turf this occupies. /obj/structure/Destroy() if(parts) @@ -99,7 +101,7 @@ usr.visible_message("[user] starts climbing onto \the [src]!") climbers |= user - if(!do_after(user,(issmall(user) ? 20 : 34))) + if(!do_after(user,(issmall(user) ? climb_delay * 0.6 : climb_delay))) climbers -= user return @@ -176,8 +178,8 @@ return 0 return 1 -/obj/structure/attack_generic(var/mob/user, var/damage, var/attack_verb, var/wallbreaker) - if(!breakable || damage < 10 || !wallbreaker) +/obj/structure/attack_generic(var/mob/user, var/damage, var/attack_verb) + if(!breakable || damage < STRUCTURE_MIN_DAMAGE_THRESHOLD) return 0 visible_message("[user] [attack_verb] the [src] apart!") user.do_attack_animation(src) diff --git a/code/game/objects/structures/bonfire.dm b/code/game/objects/structures/bonfire.dm index 390ddc88a3..f4360f92cf 100644 --- a/code/game/objects/structures/bonfire.dm +++ b/code/game/objects/structures/bonfire.dm @@ -159,14 +159,14 @@ if(burning) burning = FALSE update_icon() - processing_objects -= src + STOP_PROCESSING(SSobj, src) visible_message("\The [src] stops burning.") /obj/structure/bonfire/proc/ignite() if(!burning && get_fuel_amount()) burning = TRUE update_icon() - processing_objects += src + START_PROCESSING(SSobj, src) visible_message("\The [src] starts burning!") /obj/structure/bonfire/proc/burn() @@ -342,14 +342,14 @@ if(burning) burning = FALSE update_icon() - processing_objects -= src + STOP_PROCESSING(SSobj, src) visible_message("\The [src] stops burning.") /obj/structure/fireplace/proc/ignite() if(!burning && get_fuel_amount()) burning = TRUE update_icon() - processing_objects += src + START_PROCESSING(SSobj, src) visible_message("\The [src] starts burning!") /obj/structure/fireplace/proc/burn() diff --git a/code/game/objects/structures/catwalk.dm b/code/game/objects/structures/catwalk.dm index eda2c9346b..68b9ccc787 100644 --- a/code/game/objects/structures/catwalk.dm +++ b/code/game/objects/structures/catwalk.dm @@ -11,7 +11,7 @@ var/maxhealth = 100 anchored = 1.0 -/obj/structure/catwalk/initialize() +/obj/structure/catwalk/Initialize() . = ..() for(var/obj/structure/catwalk/O in range(1)) O.update_icon() diff --git a/code/game/objects/structures/cliff.dm b/code/game/objects/structures/cliff.dm new file mode 100644 index 0000000000..0d197b2a22 --- /dev/null +++ b/code/game/objects/structures/cliff.dm @@ -0,0 +1,239 @@ +GLOBAL_LIST_EMPTY(cliff_icon_cache) + +/* +Cliffs give a visual illusion of depth by seperating two places while presenting a 'top' and 'bottom' side. + +Mobs moving into a cliff from the bottom side will simply bump into it and be denied moving into the tile, +where as mobs moving into a cliff from the top side will 'fall' off the cliff, forcing them to the bottom, causing significant damage and stunning them. + +Mobs can climb this while wearing climbing equipment by clickdragging themselves onto a cliff, as if it were a table. + +Flying mobs can pass over all cliffs with no risk of falling. + +Projectiles and thrown objects can pass, however if moving upwards, there is a chance for it to be stopped by the cliff. +This makes fighting something that is on top of a cliff more challenging. + +As a note, dir points upwards, e.g. pointing WEST means the left side is 'up', and the right side is 'down'. + +When mapping these in, be sure to give at least a one tile clearance, as NORTH facing cliffs expand to +two tiles on initialization, and which way a cliff is facing may change during maploading. +*/ + +/obj/structure/cliff + name = "cliff" + desc = "A steep rock ledge. You might be able to climb it if you feel bold enough." + description_info = "Walking off the edge of a cliff while on top will cause you to fall off, causing severe injury.
\ + You can climb this cliff if wearing special climbing equipment, by click-dragging yourself onto the cliff.
\ + Projectiles traveling up a cliff may hit the cliff instead, making it more difficult to fight something \ + on top." + icon = 'icons/obj/flora/rocks.dmi' + + anchored = TRUE + density = TRUE + opacity = FALSE + climbable = TRUE + climb_delay = 10 SECONDS + block_turf_edges = TRUE // Don't want turf edges popping up from the cliff edge. + register_as_dangerous_object = TRUE + + var/icon_variant = null // Used to make cliffs less repeative by having a selection of sprites to display. + var/corner = FALSE // Used for icon things. + var/ramp = FALSE // Ditto. + var/bottom = FALSE // Used for 'bottom' typed cliffs, to avoid infinite cliffs, and for icons. + + var/is_double_cliff = FALSE // Set to true when making the two-tile cliffs, used for projectile checks. + var/uphill_penalty = 30 // Odds of a projectile not making it up the cliff. + +// These arrange their sprites at runtime, as opposed to being statically placed in the map file. +/obj/structure/cliff/automatic + icon_state = "cliffbuilder" + dir = NORTH + +/obj/structure/cliff/automatic/corner + icon_state = "cliffbuilder-corner" + dir = NORTHEAST + corner = TRUE + +// Tiny part that doesn't block, used for making 'ramps'. +/obj/structure/cliff/automatic/ramp + icon_state = "cliffbuilder-ramp" + dir = NORTHEAST + density = FALSE + ramp = TRUE + +// Made automatically as needed by automatic cliffs. +/obj/structure/cliff/bottom + bottom = TRUE + +/obj/structure/cliff/automatic/Initialize() + ..() + return INITIALIZE_HINT_LATELOAD + +// Paranoid about the maploader, direction is very important to cliffs, since they may get bigger if initialized while facing NORTH. +/obj/structure/cliff/automatic/LateInitialize() + if(dir in GLOB.cardinal) + icon_variant = pick("a", "b", "c") + + if(dir & NORTH && !bottom) // North-facing cliffs require more cliffs to be made. + make_bottom() + + update_icon() + +/obj/structure/cliff/proc/make_bottom() + // First, make sure there's room to put the bottom side. + var/turf/T = locate(x, y - 1, z) + if(!istype(T)) + return FALSE + + // Now make the bottom cliff have mostly the same variables. + var/obj/structure/cliff/bottom/bottom = new(T) + is_double_cliff = TRUE + climb_delay /= 2 // Since there are two cliffs to climb when going north, both take half the time. + + bottom.dir = dir + bottom.is_double_cliff = TRUE + bottom.climb_delay = climb_delay + bottom.icon_variant = icon_variant + bottom.corner = corner + bottom.ramp = ramp + bottom.layer = layer - 0.1 + bottom.density = density + bottom.update_icon() + +/obj/structure/cliff/set_dir(new_dir) + ..() + update_icon() + +/obj/structure/cliff/update_icon() + icon_state = "cliff-[dir][icon_variant][bottom ? "-bottom" : ""][corner ? "-corner" : ""][ramp ? "-ramp" : ""]" + + // Now for making the top-side look like a different turf. + var/turf/T = get_step(src, dir) + if(!istype(T)) + return + + var/subtraction_icon_state = "[icon_state]-subtract" + var/cache_string = "[icon_state]_[T.icon]_[T.icon_state]" + if(T && subtraction_icon_state in icon_states(icon)) + cut_overlays() + // If we've made the same icon before, just recycle it. + if(cache_string in GLOB.cliff_icon_cache) + add_overlay(GLOB.cliff_icon_cache[cache_string]) + + else // Otherwise make a new one, but only once. + var/icon/underlying_ground = icon(T.icon, T.icon_state, T.dir) + var/icon/subtract = icon(icon, subtraction_icon_state) + underlying_ground.Blend(subtract, ICON_SUBTRACT) + var/image/final = image(underlying_ground) + final.layer = src.layer - 0.2 + GLOB.cliff_icon_cache[cache_string] = final + add_overlay(final) + + +// Movement-related code. + +/obj/structure/cliff/CanPass(atom/movable/mover, turf/target, height = 0, air_group = 0) + if(air_group || height == 0) + return TRUE // Airflow can always pass. + + else if(isliving(mover)) + var/mob/living/L = mover + if(L.hovering) // Flying mobs can always pass. + return TRUE + return ..() + + // Projectiles and objects flying 'upward' have a chance to hit the cliff instead, wasting the shot. + else if(istype(mover, /obj)) + var/obj/O = mover + if(check_shield_arc(src, dir, O)) // This is actually for mobs but it will work for our purposes as well. + if(prob(uphill_penalty / (1 + is_double_cliff) )) // Firing upwards facing NORTH means it will likely have to pass through two cliffs, so the chance is halved. + return FALSE + return TRUE + +/obj/structure/cliff/Bumped(atom/A) + if(isliving(A)) + var/mob/living/L = A + if(should_fall(L)) + fall_off_cliff(L) + return + ..() + +/obj/structure/cliff/proc/should_fall(mob/living/L) + if(L.hovering) + return FALSE + + var/turf/T = get_turf(L) + if(T && get_dir(T, loc) & reverse_dir[dir]) // dir points 'up' the cliff, e.g. cliff pointing NORTH will cause someone to fall if moving SOUTH into it. + return TRUE + return FALSE + +/obj/structure/cliff/proc/fall_off_cliff(mob/living/L) + if(!istype(L)) + return FALSE + var/turf/T = get_step(src, reverse_dir[dir]) + var/displaced = FALSE + + if(dir in list(EAST, WEST)) // Apply an offset if flying sideways, to help maintain the illusion of depth. + for(var/i = 1 to 2) + var/turf/new_T = locate(T.x, T.y - i, T.z) + if(!new_T || locate(/obj/structure/cliff) in new_T) + break + T = new_T + displaced = TRUE + + if(istype(T)) + visible_message(span("danger", "\The [L] falls off \the [src]!")) + L.forceMove(T) + + // Do the actual hurting. Double cliffs do halved damage due to them most likely hitting twice. + var/harm = !is_double_cliff ? 1 : 0.5 + if(istype(L.buckled, /obj/vehicle)) // People falling off in vehicles will take less damage, but will damage the vehicle severely. + var/obj/vehicle/vehicle = L.buckled + vehicle.adjust_health(40 * harm) + to_chat(L, span("warning", "\The [vehicle] absorbs some of the impact, damaging it.")) + harm /= 2 + + playsound(L, 'sound/effects/break_stone.ogg', 70, 1) + L.Weaken(5 * harm) + var/fall_time = 3 + if(displaced) // Make the fall look more natural when falling sideways. + L.pixel_z = 32 * 2 + animate(L, pixel_z = 0, time = fall_time) + sleep(fall_time) // A brief delay inbetween the two sounds helps sell the 'ouch' effect. + playsound(L, "punch", 70, 1) + shake_camera(L, 1, 1) + visible_message(span("danger", "\The [L] hits the ground!")) + + // The bigger they are, the harder they fall. + // They will take at least 20 damage at the minimum, and tries to scale up to 40% of their max health. + // This scaling is capped at 100 total damage, which occurs if the thing that fell has more than 250 health. + var/damage = between(20, L.getMaxHealth() * 0.4, 100) + var/target_zone = ran_zone() + var/blocked = L.run_armor_check(target_zone, "melee") * harm + var/soaked = L.get_armor_soak(target_zone, "melee") * harm + + L.apply_damage(damage * harm, BRUTE, target_zone, blocked, soaked, used_weapon=src) + + // Now fall off more cliffs below this one if they exist. + var/obj/structure/cliff/bottom_cliff = locate() in T + if(bottom_cliff) + visible_message(span("danger", "\The [L] rolls down towards \the [bottom_cliff]!")) + sleep(5) + bottom_cliff.fall_off_cliff(L) + +/obj/structure/cliff/can_climb(mob/living/user, post_climb_check = FALSE) + // Cliff climbing requires climbing gear. + if(ishuman(user)) + var/mob/living/carbon/human/H = user + var/obj/item/clothing/shoes/shoes = H.shoes + if(shoes && shoes.rock_climbing) + return ..() // Do the other checks too. + + to_chat(user, span("warning", "\The [src] is too steep to climb unassisted.")) + return FALSE + +// This tells AI mobs to not be dumb and step off cliffs willingly. +/obj/structure/cliff/is_safe_to_step(mob/living/L) + if(should_fall(L)) + return FALSE + return ..() diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 4a392c0bfe..97f9329b88 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -32,7 +32,7 @@ var/list/starts_with -/obj/structure/closet/initialize() +/obj/structure/closet/Initialize() . = ..() if(starts_with) create_objects_in_loc(src, starts_with) @@ -47,7 +47,7 @@ // adjust locker size to hold all items with 5 units of free store room var/content_size = 0 for(I in src.contents) - content_size += Ceiling(I.w_class/2) + content_size += CEILING(I.w_class/2, 1) if(content_size > storage_capacity-5) storage_capacity = content_size + 5 update_icon() @@ -57,7 +57,7 @@ var/content_size = 0 for(var/obj/item/I in src.contents) if(!I.anchored) - content_size += Ceiling(I.w_class/2) + content_size += CEILING(I.w_class/2, 1) if(!content_size) to_chat(user, "It is empty.") else if(storage_capacity > content_size*4) @@ -69,9 +69,10 @@ else to_chat(user, "It is full.") -/obj/structure/closet/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if(air_group || (height==0 || wall_mounted)) return 1 - return (!density) +/obj/structure/closet/CanPass(atom/movable/mover, turf/target, height, air_group) + if(wall_mounted) + return TRUE + return ..() /obj/structure/closet/proc/can_open() if(src.sealed) @@ -114,7 +115,8 @@ src.icon_state = src.icon_opened src.opened = 1 playsound(src.loc, open_sound, 15, 1, -3) - density = !density + if(initial(density)) + density = !density return 1 /obj/structure/closet/proc/close() @@ -138,7 +140,8 @@ src.opened = 0 playsound(src.loc, close_sound, 15, 1, -3) - density = !density + if(initial(density)) + density = !density return 1 //Cham Projector Exception @@ -154,7 +157,7 @@ /obj/structure/closet/proc/store_items(var/stored_units) var/added_units = 0 for(var/obj/item/I in src.loc) - var/item_size = Ceiling(I.w_class / 2) + var/item_size = CEILING(I.w_class / 2, 1) if(stored_units + added_units + item_size > storage_capacity) continue if(!I.anchored) @@ -381,8 +384,8 @@ else icon_state = icon_opened -/obj/structure/closet/attack_generic(var/mob/user, var/damage, var/attack_message = "destroys", var/wallbreaker) - if(damage < 10 || !wallbreaker) +/obj/structure/closet/attack_generic(var/mob/user, var/damage, var/attack_message = "destroys") + if(damage < STRUCTURE_MIN_DAMAGE_THRESHOLD) return user.do_attack_animation(src) visible_message("[user] [attack_message] the [src]!") @@ -459,4 +462,4 @@ if(src.loc) if(istype(src.loc, /obj/structure/closet)) return (loc.return_air_for_internal_lifeform(L)) - return return_air() \ No newline at end of file + return return_air() diff --git a/code/game/objects/structures/crates_lockers/closets/fireaxe.dm b/code/game/objects/structures/crates_lockers/closets/fireaxe.dm index cad925f6e8..2621da2253 100644 --- a/code/game/objects/structures/crates_lockers/closets/fireaxe.dm +++ b/code/game/objects/structures/crates_lockers/closets/fireaxe.dm @@ -16,7 +16,7 @@ starts_with = list(/obj/item/weapon/material/twohanded/fireaxe) -/obj/structure/closet/fireaxecabinet/initialize() +/obj/structure/closet/fireaxecabinet/Initialize() ..() fireaxe = locate() in contents diff --git a/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm b/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm index ef68d7ca60..8429b5abdd 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm @@ -22,7 +22,7 @@ /obj/item/clothing/gloves/fingerless, /obj/item/clothing/head/soft) -/obj/structure/closet/secure_closet/cargotech/initialize() +/obj/structure/closet/secure_closet/cargotech/Initialize() if(prob(75)) starts_with += /obj/item/weapon/storage/backpack else @@ -59,7 +59,7 @@ /obj/item/clothing/suit/storage/hooded/wintercoat/cargo, /obj/item/clothing/shoes/boots/winter/supply) -/obj/structure/closet/secure_closet/quartermaster/initialize() +/obj/structure/closet/secure_closet/quartermaster/Initialize() if(prob(75)) starts_with += /obj/item/weapon/storage/backpack else @@ -93,7 +93,7 @@ /obj/item/clothing/shoes/boots/winter/mining, /obj/item/stack/marker_beacon/thirty) -/obj/structure/closet/secure_closet/miner/initialize() +/obj/structure/closet/secure_closet/miner/Initialize() if(prob(50)) starts_with += /obj/item/weapon/storage/backpack/industrial else 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 3ed5806143..8380c059ec 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm @@ -33,7 +33,7 @@ /obj/item/weapon/tank/emergency/oxygen/engi, /obj/item/weapon/reagent_containers/spray/windowsealant) //VOREStation Add -/obj/structure/closet/secure_closet/engineering_chief/initialize() +/obj/structure/closet/secure_closet/engineering_chief/Initialize() if(prob(50)) starts_with += /obj/item/weapon/storage/backpack/industrial else @@ -100,7 +100,7 @@ /obj/item/weapon/tank/emergency/oxygen/engi, /obj/item/weapon/reagent_containers/spray/windowsealant) //VOREStation Add -/obj/structure/closet/secure_closet/engineering_personal/initialize() +/obj/structure/closet/secure_closet/engineering_personal/Initialize() if(prob(50)) starts_with += /obj/item/weapon/storage/backpack/industrial else @@ -135,7 +135,7 @@ /obj/item/clothing/shoes/boots/winter/atmos, /obj/item/weapon/tank/emergency/oxygen/engi) -/obj/structure/closet/secure_closet/atmos_personal/initialize() +/obj/structure/closet/secure_closet/atmos_personal/Initialize() if(prob(50)) starts_with += /obj/item/weapon/storage/backpack/industrial else diff --git a/code/game/objects/structures/crates_lockers/closets/secure/guncabinet.dm b/code/game/objects/structures/crates_lockers/closets/secure/guncabinet.dm index 62497919fc..2be8e52db1 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/guncabinet.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/guncabinet.dm @@ -9,7 +9,7 @@ icon_opened = "base" req_one_access = list(access_armory) -/obj/structure/closet/secure_closet/guncabinet/initialize() +/obj/structure/closet/secure_closet/guncabinet/Initialize() . = ..() update_icon() 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 c2a8a40e7e..c27f80d998 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/hydroponics.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/hydroponics.dm @@ -21,7 +21,7 @@ /obj/item/clothing/suit/storage/hooded/wintercoat/hydro, /obj/item/clothing/shoes/boots/winter/hydro) -/obj/structure/closet/secure_closet/hydroponics/initialize() +/obj/structure/closet/secure_closet/hydroponics/Initialize() if(prob(50)) starts_with += /obj/item/clothing/suit/storage/apron else 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 471fa446fb..86cb24dc8c 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm @@ -60,7 +60,7 @@ /obj/item/clothing/head/nursehat, /obj/item/weapon/storage/box/freezer = 3) -/obj/structure/closet/secure_closet/medical3/initialize() +/obj/structure/closet/secure_closet/medical3/Initialize() if(prob(50)) starts_with += /obj/item/weapon/storage/backpack/medic else @@ -170,7 +170,7 @@ /obj/item/clothing/shoes/white, /obj/item/weapon/reagent_containers/glass/beaker/vial) //VOREStation Add -/obj/structure/closet/secure_closet/CMO/initialize() +/obj/structure/closet/secure_closet/CMO/Initialize() if(prob(50)) starts_with += /obj/item/weapon/storage/backpack/medic else 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 b7a09db3c4..454fab779d 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/personal.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/personal.dm @@ -7,7 +7,7 @@ starts_with = list( /obj/item/device/radio/headset) -/obj/structure/closet/secure_closet/personal/initialize() +/obj/structure/closet/secure_closet/personal/Initialize() if(prob(50)) starts_with += /obj/item/weapon/storage/backpack else diff --git a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm index 64cb0920f3..4e78a613e4 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm @@ -18,7 +18,7 @@ /obj/item/clothing/suit/storage/hooded/wintercoat/science, /obj/item/clothing/shoes/boots/winter/science) -/obj/structure/closet/secure_closet/scientist/initialize() +/obj/structure/closet/secure_closet/scientist/Initialize() if(prob(50)) starts_with += /obj/item/weapon/storage/backpack/dufflebag/sci else 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 06ed1b9451..0f6253ac6e 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -121,7 +121,7 @@ /obj/item/device/flashlight/maglight, /obj/item/clothing/mask/gas/half) -/obj/structure/closet/secure_closet/hos/initialize() +/obj/structure/closet/secure_closet/hos/Initialize() if(prob(50)) starts_with += /obj/item/weapon/storage/backpack/security else @@ -170,7 +170,7 @@ /obj/item/device/megaphone, /obj/item/clothing/mask/gas/half) -/obj/structure/closet/secure_closet/warden/initialize() +/obj/structure/closet/secure_closet/warden/Initialize() if(prob(50)) starts_with += /obj/item/weapon/storage/backpack/security else @@ -214,7 +214,7 @@ /obj/item/clothing/shoes/boots/winter/security, /obj/item/device/flashlight/maglight) -/obj/structure/closet/secure_closet/security/initialize() +/obj/structure/closet/secure_closet/security/Initialize() if(prob(50)) starts_with += /obj/item/weapon/storage/backpack/security else @@ -223,22 +223,22 @@ starts_with += /obj/item/weapon/storage/backpack/dufflebag/sec return ..() -/obj/structure/closet/secure_closet/security/cargo/initialize() +/obj/structure/closet/secure_closet/security/cargo/Initialize() starts_with += /obj/item/clothing/accessory/armband/cargo starts_with += /obj/item/device/encryptionkey/headset_cargo return ..() -/obj/structure/closet/secure_closet/security/engine/initialize() +/obj/structure/closet/secure_closet/security/engine/Initialize() starts_with += /obj/item/clothing/accessory/armband/engine starts_with += /obj/item/device/encryptionkey/headset_eng return ..() -/obj/structure/closet/secure_closet/security/science/initialize() +/obj/structure/closet/secure_closet/security/science/Initialize() starts_with += /obj/item/clothing/accessory/armband/science starts_with += /obj/item/device/encryptionkey/headset_sci return ..() -/obj/structure/closet/secure_closet/security/med/initialize() +/obj/structure/closet/secure_closet/security/med/Initialize() starts_with += /obj/item/clothing/accessory/armband/medblue starts_with += /obj/item/device/encryptionkey/headset_med return ..() diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security_vr.dm b/code/game/objects/structures/crates_lockers/closets/secure/security_vr.dm index 9dadb6dc89..aa682c1731 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security_vr.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security_vr.dm @@ -95,7 +95,7 @@ /obj/item/clothing/shoes/boots/jackboots, /obj/item/clothing/shoes/boots/jackboots/toeless) -/obj/structure/closet/secure_closet/nanotrasen_security/initialize() +/obj/structure/closet/secure_closet/nanotrasen_security/Initialize() if(prob(25)) starts_with += /obj/item/weapon/storage/backpack/security else @@ -149,7 +149,7 @@ /obj/item/clothing/shoes/boots/jackboots/toeless, /obj/item/clothing/under/nanotrasen/security/commander) -/obj/structure/closet/secure_closet/nanotrasen_commander/initialize() +/obj/structure/closet/secure_closet/nanotrasen_commander/Initialize() if(prob(25)) starts_with += /obj/item/weapon/storage/backpack/security else @@ -195,7 +195,7 @@ /obj/item/clothing/shoes/boots/jackboots, /obj/item/clothing/shoes/boots/jackboots/toeless) -/obj/structure/closet/secure_closet/nanotrasen_warden/initialize() +/obj/structure/closet/secure_closet/nanotrasen_warden/Initialize() if(prob(25)) new /obj/item/weapon/storage/backpack/security(src) else diff --git a/code/game/objects/structures/crates_lockers/closets/statue.dm b/code/game/objects/structures/crates_lockers/closets/statue.dm index 2ff44ee9df..2ea6372aef 100644 --- a/code/game/objects/structures/crates_lockers/closets/statue.dm +++ b/code/game/objects/structures/crates_lockers/closets/statue.dm @@ -43,7 +43,7 @@ qdel(src) return - processing_objects.Add(src) + START_PROCESSING(SSobj, src) ..() /obj/structure/closet/statue/process() @@ -55,7 +55,7 @@ M.setOxyLoss(intialOxy) if (timer <= 0) dump_contents() - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) qdel(src) /obj/structure/closet/statue/dump_contents() diff --git a/code/game/objects/structures/crates_lockers/closets/syndicate.dm b/code/game/objects/structures/crates_lockers/closets/syndicate.dm index 1194b7f9fa..f608c05b26 100644 --- a/code/game/objects/structures/crates_lockers/closets/syndicate.dm +++ b/code/game/objects/structures/crates_lockers/closets/syndicate.dm @@ -48,7 +48,7 @@ /obj/structure/closet/syndicate/resources desc = "An old, dusty locker." -/obj/structure/closet/syndicate/resources/initialize() +/obj/structure/closet/syndicate/resources/Initialize() . = ..() if(!contents.len) var/common_min = 30 //Minimum amount of minerals in the stack for common minerals @@ -103,7 +103,7 @@ /obj/structure/closet/syndicate/resources/everything desc = "It's an emergency storage closet for repairs." -/obj/structure/closet/syndicate/resources/everything/initialize() +/obj/structure/closet/syndicate/resources/everything/Initialize() var/list/resources = list( /obj/item/stack/material/steel, /obj/item/stack/material/glass, diff --git a/code/game/objects/structures/crates_lockers/closets/utility_closets.dm b/code/game/objects/structures/crates_lockers/closets/utility_closets.dm index 1336890b13..b15f45d6fb 100644 --- a/code/game/objects/structures/crates_lockers/closets/utility_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/utility_closets.dm @@ -19,7 +19,7 @@ icon_closed = "emergency" icon_opened = "emergencyopen" -/obj/structure/closet/emcloset/initialize() +/obj/structure/closet/emcloset/Initialize() switch (pickweight(list("small" = 55, "aid" = 25, "tank" = 10, "both" = 10))) if ("small") starts_with = list( @@ -106,7 +106,7 @@ icon_closed = "toolcloset" icon_opened = "toolclosetopen" -/obj/structure/closet/toolcloset/initialize() +/obj/structure/closet/toolcloset/Initialize() starts_with = list() if(prob(40)) starts_with += /obj/item/clothing/suit/storage/hazardvest diff --git a/code/game/objects/structures/crates_lockers/closets/utility_closets_vr.dm b/code/game/objects/structures/crates_lockers/closets/utility_closets_vr.dm index 54abff6eb3..c126b965f3 100644 --- a/code/game/objects/structures/crates_lockers/closets/utility_closets_vr.dm +++ b/code/game/objects/structures/crates_lockers/closets/utility_closets_vr.dm @@ -1,4 +1,4 @@ -/obj/structure/closet/firecloset/initialize() +/obj/structure/closet/firecloset/Initialize() starts_with += /obj/item/weapon/storage/toolbox/emergency return ..() diff --git a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm index 2a7d883d95..ad617e4980 100644 --- a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm +++ b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm @@ -22,7 +22,7 @@ /obj/item/clothing/accessory/armband = 3, /obj/item/clothing/accessory/holster/waist = 3) -/obj/structure/closet/wardrobe/red/initialize() +/obj/structure/closet/wardrobe/red/Initialize() if(prob(50)) starts_with += /obj/item/weapon/storage/backpack/security else @@ -101,6 +101,9 @@ /obj/item/clothing/under/wedding/bride_white, /obj/item/weapon/storage/backpack/cultpack, /obj/item/weapon/storage/fancy/candle_box = 2, + /obj/item/weapon/storage/fancy/whitecandle_box, + /obj/item/weapon/storage/fancy/blackcandle_box, + /obj/item/godfig = 2, /obj/item/weapon/deck/tarot) @@ -188,7 +191,7 @@ name = "white wardrobe" icon_state = "white" icon_closed = "white" - + starts_with = list( /obj/item/clothing/under/color/white = 3, /obj/item/clothing/shoes/white = 3, @@ -223,7 +226,7 @@ /obj/item/weapon/storage/backpack/toxins, /obj/item/weapon/storage/backpack/satchel/tox) -/obj/structure/closet/wardrobe/science_white/initialize() +/obj/structure/closet/wardrobe/science_white/Initialize() if(prob(50)) starts_with += /obj/item/weapon/storage/backpack/dufflebag/sci else @@ -249,12 +252,12 @@ /obj/item/weapon/storage/backpack/toxins, /obj/item/weapon/storage/backpack/satchel/tox) -/obj/structure/closet/wardrobe/robotics_black/initialize() +/obj/structure/closet/wardrobe/robotics_black/Initialize() if(prob(50)) starts_with += /obj/item/weapon/storage/backpack/dufflebag/sci else starts_with += /obj/item/weapon/storage/backpack/satchel/tox - + return ..() @@ -340,12 +343,12 @@ name = "grey wardrobe" icon_state = "grey" icon_closed = "grey" - + starts_with = list( /obj/item/clothing/under/color/grey = 3, /obj/item/clothing/shoes/black = 3, /obj/item/clothing/head/soft/grey = 3) - + /obj/structure/closet/wardrobe/mixed name = "mixed wardrobe" @@ -401,7 +404,7 @@ /obj/item/clothing/gloves/black, /obj/item/clothing/under/pants/camo) -/obj/structure/closet/wardrobe/tactical/initialize() +/obj/structure/closet/wardrobe/tactical/Initialize() if(prob(25)) starts_with += /obj/item/weapon/storage/belt/security/tactical/bandolier else diff --git a/code/game/objects/structures/crates_lockers/largecrate.dm b/code/game/objects/structures/crates_lockers/largecrate.dm index 2c739985b2..a7a4b77823 100644 --- a/code/game/objects/structures/crates_lockers/largecrate.dm +++ b/code/game/objects/structures/crates_lockers/largecrate.dm @@ -6,7 +6,7 @@ density = 1 var/list/starts_with -/obj/structure/largecrate/initialize() +/obj/structure/largecrate/Initialize() . = ..() if(starts_with) create_objects_in_loc(src, starts_with) @@ -63,7 +63,7 @@ desc = "It comes in a box for the consumer's sake. ..How is this lighter?" icon_state = "vehiclecrate" -/obj/structure/largecrate/vehicle/initialize() +/obj/structure/largecrate/vehicle/Initialize() ..() spawn(1) for(var/obj/O in contents) @@ -90,23 +90,23 @@ /obj/structure/largecrate/animal/corgi name = "corgi carrier" - starts_with = list(/mob/living/simple_animal/corgi) + starts_with = list(/mob/living/simple_mob/animal/passive/dog/corgi) /obj/structure/largecrate/animal/cow name = "cow crate" - starts_with = list(/mob/living/simple_animal/cow) + starts_with = list(/mob/living/simple_mob/animal/passive/cow) /obj/structure/largecrate/animal/goat name = "goat crate" - starts_with = list(/mob/living/simple_animal/retaliate/goat) + starts_with = list(/mob/living/simple_mob/animal/goat) /obj/structure/largecrate/animal/cat name = "cat carrier" - starts_with = list(/mob/living/simple_animal/cat) + starts_with = list(/mob/living/simple_mob/animal/passive/cat) /obj/structure/largecrate/animal/cat/bones - starts_with = list(/mob/living/simple_animal/cat/fluff/bones) + starts_with = list(/mob/living/simple_mob/animal/passive/cat/bones) /obj/structure/largecrate/animal/chick name = "chicken crate" - starts_with = list(/mob/living/simple_animal/chick = 5) + starts_with = list(/mob/living/simple_mob/animal/passive/chick = 5) diff --git a/code/game/objects/structures/crates_lockers/largecrate_vr.dm b/code/game/objects/structures/crates_lockers/largecrate_vr.dm index e45ce509d2..b7db1ea0a6 100644 --- a/code/game/objects/structures/crates_lockers/largecrate_vr.dm +++ b/code/game/objects/structures/crates_lockers/largecrate_vr.dm @@ -5,28 +5,27 @@ /obj/structure/largecrate/birds/attackby(obj/item/weapon/W as obj, mob/user as mob) if(W.is_crowbar()) new /obj/item/stack/material/wood(src) - new /mob/living/simple_animal/bird(src) - new /mob/living/simple_animal/bird/kea(src) - new /mob/living/simple_animal/bird/eclectus(src) - new /mob/living/simple_animal/bird/greybird(src) - new /mob/living/simple_animal/bird/eclectusf(src) - new /mob/living/simple_animal/bird/blue_caique(src) - new /mob/living/simple_animal/bird/white_caique(src) - new /mob/living/simple_animal/bird/green_budgerigar(src) - new /mob/living/simple_animal/bird/blue_Budgerigar(src) - new /mob/living/simple_animal/bird/bluegreen_Budgerigar(src) - new /mob/living/simple_animal/bird/commonblackbird(src) - new /mob/living/simple_animal/bird/azuretit(src) - new /mob/living/simple_animal/bird/europeanrobin(src) - new /mob/living/simple_animal/bird/goldcrest(src) - new /mob/living/simple_animal/bird/ringneckdove(src) - new /mob/living/simple_animal/bird/cockatiel(src) - new /mob/living/simple_animal/bird/white_cockatiel(src) - new /mob/living/simple_animal/bird/yellowish_cockatiel(src) - new /mob/living/simple_animal/bird/grey_cockatiel(src) - new /mob/living/simple_animal/bird/too(src) - new /mob/living/simple_animal/bird/hooded_too(src) - new /mob/living/simple_animal/bird/pink_too(src) + new /mob/living/simple_mob/animal/passive/bird(src) + new /mob/living/simple_mob/animal/passive/bird/parrot/kea(src) + new /mob/living/simple_mob/animal/passive/bird/parrot/eclectus(src) + new /mob/living/simple_mob/animal/passive/bird/parrot/grey_parrot(src) + new /mob/living/simple_mob/animal/passive/bird/parrot/black_headed_caique(src) + new /mob/living/simple_mob/animal/passive/bird/parrot/white_caique(src) + new /mob/living/simple_mob/animal/passive/bird/parrot/budgerigar(src) + new /mob/living/simple_mob/animal/passive/bird/parrot/budgerigar/blue(src) + new /mob/living/simple_mob/animal/passive/bird/parrot/budgerigar/bluegreen(src) + new /mob/living/simple_mob/animal/passive/bird/black_bird(src) + new /mob/living/simple_mob/animal/passive/bird/azure_tit(src) + new /mob/living/simple_mob/animal/passive/bird/european_robin(src) + new /mob/living/simple_mob/animal/passive/bird/goldcrest(src) + new /mob/living/simple_mob/animal/passive/bird/ringneck_dove(src) + new /mob/living/simple_mob/animal/passive/bird/parrot/cockatiel(src) + new /mob/living/simple_mob/animal/passive/bird/parrot/cockatiel/white(src) + new /mob/living/simple_mob/animal/passive/bird/parrot/cockatiel/yellowish(src) + new /mob/living/simple_mob/animal/passive/bird/parrot/cockatiel/grey(src) + new /mob/living/simple_mob/animal/passive/bird/parrot/sulphur_cockatoo(src) + new /mob/living/simple_mob/animal/passive/bird/parrot/white_cockatoo(src) + new /mob/living/simple_mob/animal/passive/bird/parrot/pink_cockatoo(src) var/turf/T = get_turf(src) for(var/atom/movable/AM in contents) if(AM.simulated) AM.forceMove(T) @@ -39,72 +38,72 @@ /obj/structure/largecrate/animal/pred name = "Predator carrier" - starts_with = list(/mob/living/simple_animal/catgirl) + starts_with = list(/mob/living/simple_mob/vore/catgirl) -/obj/structure/largecrate/animal/pred/initialize() //This is nessesary to get a random one each time. - starts_with = list(pick(/mob/living/simple_animal/retaliate/bee, - /mob/living/simple_animal/catgirl;3, - /mob/living/simple_animal/hostile/frog, - /mob/living/simple_animal/horse, - /mob/living/simple_animal/hostile/panther, - /mob/living/simple_animal/hostile/giant_snake, - /mob/living/simple_animal/hostile/wolf, - /mob/living/simple_animal/hostile/bear;0.5, - /mob/living/simple_animal/hostile/bear/brown;0.5, - /mob/living/simple_animal/hostile/carp, - /mob/living/simple_animal/hostile/mimic, - /mob/living/simple_animal/hostile/rat, - /mob/living/simple_animal/hostile/rat/passive, - /mob/living/simple_animal/otie;0.5)) +/obj/structure/largecrate/animal/pred/Initialize() //This is nessesary to get a random one each time. + starts_with = list(pick(/mob/living/simple_mob/vore/bee, + /mob/living/simple_mob/vore/catgirl;3, + /mob/living/simple_mob/vore/frog, + /mob/living/simple_mob/horse, + /mob/living/simple_mob/vore/panther, + /mob/living/simple_mob/vore/giant_snake, + /mob/living/simple_mob/vore/wolf, + /mob/living/simple_mob/animal/space/bear;0.5, + /mob/living/simple_mob/animal/space/carp, + /mob/living/simple_mob/animal/space/mimic, + /mob/living/simple_mob/vore/rat, + /mob/living/simple_mob/vore/rat/passive, +// /mob/living/simple_mob/otie;0.5 + )) return ..() /obj/structure/largecrate/animal/dangerous name = "Dangerous Predator carrier" - starts_with = list(/mob/living/simple_animal/hostile/alien) + starts_with = list(/mob/living/simple_mob/animal/space/alien) -/obj/structure/largecrate/animal/dangerous/initialize() - starts_with = list(pick(/mob/living/simple_animal/hostile/carp/pike, - /mob/living/simple_animal/hostile/deathclaw, - /mob/living/simple_animal/hostile/dino, - /mob/living/simple_animal/hostile/alien, - /mob/living/simple_animal/hostile/alien/drone, - /mob/living/simple_animal/hostile/alien/sentinel, - /mob/living/simple_animal/hostile/alien/queen, - /mob/living/simple_animal/otie/feral, - /mob/living/simple_animal/otie/red, - /mob/living/simple_animal/hostile/corrupthound)) +/obj/structure/largecrate/animal/dangerous/Initialize() + starts_with = list(pick(/mob/living/simple_mob/animal/space/carp/large, + /mob/living/simple_mob/hostile/deathclaw, + /mob/living/simple_mob/vore/dino, + /mob/living/simple_mob/animal/space/alien, + /mob/living/simple_mob/animal/space/alien/drone, + /mob/living/simple_mob/animal/space/alien/sentinel, + /mob/living/simple_mob/animal/space/alien/queen, +// /mob/living/simple_mob/otie/feral, +// /mob/living/simple_mob/otie/red, + /mob/living/simple_mob/vore/corrupthound)) return ..() - +/* /obj/structure/largecrate/animal/guardbeast name = "VARMAcorp autoNOMous security solution" desc = "The VARMAcorp bioengineering division flagship product on trained optimal snowflake guard dogs." icon = 'icons/obj/storage_vr.dmi' icon_state = "sotiecrate" - starts_with = list(/mob/living/simple_animal/otie/security) + starts_with = list(/mob/living/simple_mob/otie/security) /obj/structure/largecrate/animal/guardmutant name = "VARMAcorp autoNOMous security solution for hostile environments." desc = "The VARMAcorp bioengineering division flagship product on trained optimal snowflake guard dogs. This one can survive hostile atmosphere." icon = 'icons/obj/storage_vr.dmi' icon_state = "sotiecrate" - starts_with = list(/mob/living/simple_animal/otie/security/phoron) + starts_with = list(/mob/living/simple_mob/otie/security/phoron) /obj/structure/largecrate/animal/otie name = "VARMAcorp adoptable reject (Dangerous!)" desc = "A warning on the side says the creature inside was returned to the supplier after injuring or devouring several unlucky members of the previous adoption family. It was given a second chance with the next customer. Godspeed and good luck with your new pet!" icon = 'icons/obj/storage_vr.dmi' icon_state = "otiecrate2" - starts_with = list(/mob/living/simple_animal/otie/cotie) + starts_with = list(/mob/living/simple_mob/otie/cotie) var/taped = 1 /obj/structure/largecrate/animal/otie/phoron name = "VARMAcorp adaptive beta subject (Experimental)" desc = "VARMAcorp experimental hostile environment adaptive breeding development kit. WARNING, DO NOT RELEASE IN WILD!" - starts_with = list(/mob/living/simple_animal/otie/cotie/phoron) + starts_with = list(/mob/living/simple_mob/otie/cotie/phoron) -/obj/structure/largecrate/animal/otie/phoron/initialize() - starts_with = list(pick(/mob/living/simple_animal/otie/cotie/phoron;2, - /mob/living/simple_animal/otie/red/friendly;0.5)) +/obj/structure/largecrate/animal/otie/phoron/Initialize() + starts_with = list(pick(/mob/living/simple_mob/otie/cotie/phoron;2, + /mob/living/simple_mob/otie/red/friendly;0.5)) return ..() /obj/structure/largecrate/animal/otie/attack_hand(mob/living/carbon/human/M as mob)//I just couldn't decide between the icons lmao @@ -113,23 +112,24 @@ icon_state = "otiecrate" taped = 0 ..() +*/ //VORESTATION AI REMOVAL, Oties are still fucking broken. /obj/structure/largecrate/animal/catgirl name = "Catgirl Crate" desc = "A sketchy looking crate with airholes that seems to have had most marks and stickers removed. You can almost make out 'genetically-engineered subject' written on it." - starts_with = list(/mob/living/simple_animal/catgirl) + starts_with = list(/mob/living/simple_mob/vore/catgirl) /obj/structure/largecrate/animal/wolfgirl name = "Wolfgirl Crate" desc = "A sketchy looking crate with airholes that shakes and thuds every now and then. Someone seems to be demanding they be let out." - starts_with = list(/mob/living/simple_animal/retaliate/wolfgirl) + starts_with = list(/mob/living/simple_mob/vore/wolfgirl) /obj/structure/largecrate/animal/fennec name = "Fennec Crate" desc = "Bounces around a lot. Looks messily packaged, were they in a hurry?" - starts_with = list(/mob/living/simple_animal/fennec) + starts_with = list(/mob/living/simple_mob/fennec) -/obj/structure/largecrate/animal/fennec/initialize() - starts_with = list(pick(/mob/living/simple_animal/fennec, - /mob/living/simple_animal/retaliate/fennix;0.5)) +/obj/structure/largecrate/animal/fennec/Initialize() + starts_with = list(pick(/mob/living/simple_mob/fennec, + /mob/living/simple_mob/vore/fennix;0.5)) return ..() diff --git a/code/game/objects/structures/crates_lockers/vehiclecage.dm b/code/game/objects/structures/crates_lockers/vehiclecage.dm index 9915ca6a7b..bd525832c1 100644 --- a/code/game/objects/structures/crates_lockers/vehiclecage.dm +++ b/code/game/objects/structures/crates_lockers/vehiclecage.dm @@ -13,7 +13,7 @@ if(my_vehicle) to_chat(user, "It seems to contain \the [my_vehicle].") -/obj/structure/vehiclecage/initialize() +/obj/structure/vehiclecage/Initialize() . = ..() if(my_vehicle_type) my_vehicle = new my_vehicle_type(src) diff --git a/code/game/objects/structures/electricchair.dm b/code/game/objects/structures/electricchair.dm index 1cd43b7910..ae5cba7cf0 100644 --- a/code/game/objects/structures/electricchair.dm +++ b/code/game/objects/structures/electricchair.dm @@ -34,10 +34,10 @@ else on = 1 icon_state = "echair1" - usr << "You switch [on ? "on" : "off"] [src]." + to_chat(usr, "You switch [on ? "on" : "off"] [src].") return -/obj/structure/bed/chair/e_chair/rotate() +/obj/structure/bed/chair/e_chair/rotate_clockwise() ..() overlays.Cut() overlays += image('icons/obj/objects.dmi', src, "echair_over", MOB_LAYER + 1, dir) //there's probably a better way of handling this, but eh. -Pete diff --git a/code/game/objects/structures/fence.dm b/code/game/objects/structures/fence.dm new file mode 100644 index 0000000000..04f58390a6 --- /dev/null +++ b/code/game/objects/structures/fence.dm @@ -0,0 +1,179 @@ +//Chain link fences +//Sprites ported from /VG/ + +#define CUT_TIME 10 SECONDS +#define CLIMB_TIME 5 SECONDS + +#define NO_HOLE 0 //section is intact +#define MEDIUM_HOLE 1 //medium hole in the section - can climb through +#define LARGE_HOLE 2 //large hole in the section - can walk through +#define MAX_HOLE_SIZE LARGE_HOLE + +/obj/structure/fence + name = "fence" + desc = "A chain link fence. Not as effective as a wall, but generally it keeps people out." + description_info = "Projectiles can freely pass fences." + density = TRUE + anchored = TRUE + + icon = 'icons/obj/fence.dmi' + icon_state = "straight" + + var/cuttable = TRUE + var/hole_size= NO_HOLE + var/invulnerable = FALSE + +/obj/structure/fence/Initialize() + update_cut_status() + return ..() + +/obj/structure/fence/examine(mob/user) + . = ..() + + switch(hole_size) + if(MEDIUM_HOLE) + user.show_message("There is a large hole in \the [src].") + if(LARGE_HOLE) + user.show_message("\The [src] has been completely cut through.") + +/obj/structure/fence/get_description_interaction() + var/list/results = list() + if(cuttable && !invulnerable && hole_size < MAX_HOLE_SIZE) + results += "[desc_panel_image("wirecutters")]to [hole_size > NO_HOLE ? "expand the":"cut a"] hole into the fence, allowing passage." + return results + +/obj/structure/fence/end + icon_state = "end" + cuttable = FALSE + +/obj/structure/fence/corner + icon_state = "corner" + cuttable = FALSE + +/obj/structure/fence/post + icon_state = "post" + cuttable = FALSE + +/obj/structure/fence/cut/medium + icon_state = "straight_cut2" + hole_size = MEDIUM_HOLE + +/obj/structure/fence/cut/large + icon_state = "straight_cut3" + hole_size = LARGE_HOLE + +// Projectiles can pass through fences. +/obj/structure/fence/CanPass(atom/movable/mover, turf/target, height = 0, air_group = 0) + if(istype(mover, /obj/item/projectile)) + return TRUE + return ..() + +/obj/structure/fence/attackby(obj/item/W, mob/user) + if(W.is_wirecutter()) + if(!cuttable) + to_chat(user, span("warning", "This section of the fence can't be cut.")) + return + if(invulnerable) + to_chat(user, span("warning", "This fence is too strong to cut through.")) + return + var/current_stage = hole_size + if(current_stage >= MAX_HOLE_SIZE) + to_chat(user, span("notice", "This fence has too much cut out of it already.")) + return + + user.visible_message(span("danger", "\The [user] starts cutting through \the [src] with \the [W]."),\ + span("danger", "You start cutting through \the [src] with \the [W].")) + playsound(src, W.usesound, 50, 1) + + if(do_after(user, CUT_TIME * W.toolspeed, target = src)) + if(current_stage == hole_size) + switch(++hole_size) + if(MEDIUM_HOLE) + visible_message(span("notice", "\The [user] cuts into \the [src] some more.")) + to_chat(user, span("notice", "You could probably fit yourself through that hole now. Although climbing through would be much faster if you made it even bigger.")) + climbable = TRUE + if(LARGE_HOLE) + visible_message(span("notice", "\The [user] completely cuts through \the [src].")) + to_chat(user, span("notice", "The hole in \the [src] is now big enough to walk through.")) + climbable = FALSE + update_cut_status() + return TRUE + +/obj/structure/fence/proc/update_cut_status() + if(!cuttable) + return + density = TRUE + + switch(hole_size) + if(NO_HOLE) + icon_state = initial(icon_state) + if(MEDIUM_HOLE) + icon_state = "straight_cut2" + if(LARGE_HOLE) + icon_state = "straight_cut3" + density = FALSE + +//FENCE DOORS + +/obj/structure/fence/door + name = "fence door" + desc = "Not very useful without a real lock." + icon_state = "door_closed" + cuttable = FALSE + var/open = FALSE + var/locked = FALSE + +/obj/structure/fence/door/Initialize() + update_door_status() + return ..() + +/obj/structure/fence/door/opened + icon_state = "door_opened" + open = TRUE + density = TRUE + +/obj/structure/fence/door/locked + desc = "It looks like it has a strong padlock attached." + locked = TRUE + +/obj/structure/fence/door/attack_hand(mob/user) + if(can_open(user)) + toggle(user) + else + to_chat(user, span("warning", "\The [src] is [!open ? "locked" : "stuck open"].")) + + return TRUE + +/obj/structure/fence/door/proc/toggle(mob/user) + switch(open) + if(FALSE) + visible_message(span("notice", "\The [user] opens \the [src].")) + open = TRUE + if(TRUE) + visible_message(span("notice", "\The [user] closes \the [src].")) + open = FALSE + + update_door_status() + playsound(src, 'sound/machines/click.ogg', 100, 1) + +/obj/structure/fence/door/proc/update_door_status() + switch(open) + if(FALSE) + density = TRUE + icon_state = "door_closed" + if(TRUE) + density = FALSE + icon_state = "door_opened" + +/obj/structure/fence/door/proc/can_open(mob/user) + if(locked) + return FALSE + return TRUE + +#undef CUT_TIME +#undef CLIMB_TIME + +#undef NO_HOLE +#undef MEDIUM_HOLE +#undef LARGE_HOLE +#undef MAX_HOLE_SIZE \ No newline at end of file diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm index 25febad1a3..0bea284126 100644 --- a/code/game/objects/structures/flora.dm +++ b/code/game/objects/structures/flora.dm @@ -304,7 +304,7 @@ light_power = 0.6 light_color = "#FF6633" -/obj/structure/flora/sif/subterranean/initialize() +/obj/structure/flora/sif/subterranean/Initialize() icon_state = "[initial(icon_state)][rand(1,2)]" . = ..() @@ -313,6 +313,6 @@ desc = "This is a mysterious looking plant. They kind of look like eyeballs. Creepy." icon_state = "eyeplant" -/obj/structure/flora/sif/eyes/initialize() +/obj/structure/flora/sif/eyes/Initialize() icon_state = "[initial(icon_state)][rand(1,3)]" . = ..() diff --git a/code/game/objects/structures/flora/trees.dm b/code/game/objects/structures/flora/trees.dm index 8b7f5bf042..2318878896 100644 --- a/code/game/objects/structures/flora/trees.dm +++ b/code/game/objects/structures/flora/trees.dm @@ -13,6 +13,15 @@ var/obj/item/stack/material/product = null // What you get when chopping this tree down. Generally it will be a type of wood. var/product_amount = 10 // How much of a stack you get, if the above is defined. var/is_stump = FALSE // If true, suspends damage tracking and most other effects. + var/indestructable = FALSE // If true, the tree cannot die. + +/obj/structure/flora/tree/Initialize() + icon_state = choose_icon_state() + return ..() + +// Override this for special icons. +/obj/structure/flora/tree/proc/choose_icon_state() + return icon_state /obj/structure/flora/tree/attackby(var/obj/item/weapon/W, var/mob/living/user) if(!istype(W)) @@ -35,7 +44,7 @@ playsound(get_turf(src), 'sound/effects/woodcutting.ogg', 50, 1) else playsound(get_turf(src), W.hitsound, 50, 1) - if(damage_to_do > 5) + if(damage_to_do > 5 && !indestructable) adjust_health(-damage_to_do) else to_chat(user, "\The [W] is ineffective at harming \the [src].") @@ -53,7 +62,7 @@ // Used when the tree gets hurt. /obj/structure/flora/tree/proc/adjust_health(var/amount, var/damage_wood = FALSE) - if(is_stump) + if(is_stump || indestructable) return // Bullets and lasers ruin some of the wood @@ -68,7 +77,7 @@ // Called when the tree loses all health, for whatever reason. /obj/structure/flora/tree/proc/die() - if(is_stump) + if(is_stump || indestructable) return if(product && product_amount) // Make wooden logs. @@ -122,9 +131,8 @@ product = /obj/item/stack/material/log shake_animation_degrees = 3 -/obj/structure/flora/tree/pine/New() - ..() - icon_state = "[base_state]_[rand(1, 3)]" +/obj/structure/flora/tree/pine/choose_icon_state() + return "[base_state]_[rand(1, 3)]" /obj/structure/flora/tree/pine/xmas @@ -132,9 +140,30 @@ icon = 'icons/obj/flora/pinetrees.dmi' icon_state = "pine_c" -/obj/structure/flora/tree/pine/xmas/New() - ..() - icon_state = "pine_c" +/obj/structure/flora/tree/pine/xmas/presents + icon_state = "pinepresents" + desc = "A wondrous decorated Christmas tree. It has presents!" + indestructable = TRUE + var/gift_type = /obj/item/weapon/a_gift + var/list/ckeys_that_took = list() + +/obj/structure/flora/tree/pine/xmas/presents/choose_icon_state() + return "pinepresents" + +/obj/structure/flora/tree/pine/xmas/presents/attack_hand(mob/living/user) + . = ..() + if(.) + return + if(!user.ckey) + return + + if(ckeys_that_took[user.ckey]) + to_chat(user, span("warning", "There are no presents with your name on.")) + return + to_chat(user, span("notice", "After a bit of rummaging, you locate a gift with your name on it!")) + ckeys_that_took[user.ckey] = TRUE + var/obj/item/G = new gift_type(src) + user.put_in_hands(G) // Palm trees @@ -148,9 +177,8 @@ max_health = 200 pixel_x = 0 -/obj/structure/flora/tree/palm/New() - ..() - icon_state = "[base_state][rand(1, 2)]" +/obj/structure/flora/tree/palm/choose_icon_state() + return "[base_state][rand(1, 2)]" // Dead trees @@ -164,9 +192,8 @@ health = 200 max_health = 200 -/obj/structure/flora/tree/dead/New() - ..() - icon_state = "[base_state]_[rand(1, 6)]" +/obj/structure/flora/tree/dead/choose_icon_state() + return "[base_state]_[rand(1, 6)]" // Small jungle trees @@ -180,9 +207,8 @@ max_health = 400 pixel_x = -32 -/obj/structure/flora/tree/jungle_small/New() - ..() - icon_state = "[base_state][rand(1, 6)]" +/obj/structure/flora/tree/jungle_small/choose_icon_state() + return "[base_state][rand(1, 6)]" // Big jungle trees @@ -198,9 +224,8 @@ pixel_y = -16 shake_animation_degrees = 2 -/obj/structure/flora/tree/jungle/New() - ..() - icon_state = "[base_state][rand(1, 6)]" +/obj/structure/flora/tree/jungle/choose_icon_state() + return "[base_state][rand(1, 6)]" // Sif trees @@ -212,11 +237,12 @@ base_state = "tree_sif" product = /obj/item/stack/material/log/sif -/obj/structure/flora/tree/sif/New() +/obj/structure/flora/tree/sif/Initialize() update_icon() + return ..() /obj/structure/flora/tree/sif/update_icon() set_light(5, 1, "#33ccff") - var/image/glow = image(icon = 'icons/obj/flora/deadtrees.dmi', icon_state = "[icon_state]_glow") + var/image/glow = image(icon = 'icons/obj/flora/deadtrees.dmi', icon_state = "[base_state]_glow") glow.plane = PLANE_LIGHTING_ABOVE overlays = list(glow) diff --git a/code/game/objects/structures/ghost_pods/ghost_pods.dm b/code/game/objects/structures/ghost_pods/ghost_pods.dm index 16dcd2ddb7..811fc47736 100644 --- a/code/game/objects/structures/ghost_pods/ghost_pods.dm +++ b/code/game/objects/structures/ghost_pods/ghost_pods.dm @@ -59,7 +59,7 @@ var/delay_to_self_open = 10 MINUTES // How long to wait for first attempt. Note that the timer by default starts when the pod is created. var/delay_to_try_again = 20 MINUTES // How long to wait if first attempt fails. Set to 0 to never try again. -/obj/structure/ghost_pod/automatic/initialize() +/obj/structure/ghost_pod/automatic/Initialize() . = ..() spawn(delay_to_self_open) if(src) diff --git a/code/game/objects/structures/ghost_pods/mysterious.dm b/code/game/objects/structures/ghost_pods/mysterious.dm index 2e6a11a8bb..cd34d91e6f 100644 --- a/code/game/objects/structures/ghost_pods/mysterious.dm +++ b/code/game/objects/structures/ghost_pods/mysterious.dm @@ -15,7 +15,7 @@ /obj/structure/ghost_pod/manual/corgi/create_occupant(var/mob/M) lightning_strike(get_turf(src), cosmetic = TRUE) density = FALSE - var/mob/living/simple_animal/corgi/R = new(get_turf(src)) + var/mob/living/simple_mob/animal/passive/dog/corgi/R = new(get_turf(src)) if(M.mind) M.mind.transfer_to(R) to_chat(M, "You are a Corgi! Woof!") @@ -47,4 +47,4 @@ R.ghost_inhabit(M) visible_message("The blade shines brightly for a brief moment as [usr] pulls it out of the stone!") log_and_message_admins("successfully acquired a cursed sword.") - ..() \ No newline at end of file + ..() diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm index 058398d850..a24f2868da 100644 --- a/code/game/objects/structures/girders.dm +++ b/code/game/objects/structures/girders.dm @@ -25,12 +25,12 @@ /obj/structure/girder/Destroy() if(girder_material.products_need_process()) - processing_objects -= src + STOP_PROCESSING(SSobj, src) . = ..() /obj/structure/girder/process() if(!radiate()) - processing_objects -= src + STOP_PROCESSING(SSobj, src) return /obj/structure/girder/proc/radiate() @@ -53,9 +53,9 @@ if(applies_material_colour) color = girder_material.icon_colour if(girder_material.products_need_process()) //Am I radioactive or some other? Process me! - processing_objects |= src - else if(src in processing_objects) //If I happened to be radioactive or s.o. previously, and am not now, stop processing. - processing_objects -= src + START_PROCESSING(SSobj, src) + else if(datum_flags & DF_ISPROCESSING) //If I happened to be radioactive or s.o. previously, and am not now, stop processing. + STOP_PROCESSING(SSobj, src) /obj/structure/girder/get_material() return girder_material @@ -83,8 +83,8 @@ health = (displaced_health - round(current_damage / 4)) cover = 25 -/obj/structure/girder/attack_generic(var/mob/user, var/damage, var/attack_message = "smashes apart", var/wallbreaker) - if(!damage || !wallbreaker) +/obj/structure/girder/attack_generic(var/mob/user, var/damage, var/attack_message = "smashes apart") + if(damage < STRUCTURE_MIN_DAMAGE_THRESHOLD) return 0 user.do_attack_animation(src) visible_message("[user] [attack_message] the [src]!") diff --git a/code/game/objects/structures/gravemarker.dm b/code/game/objects/structures/gravemarker.dm index 7ef0d49a51..715c051c58 100644 --- a/code/game/objects/structures/gravemarker.dm +++ b/code/game/objects/structures/gravemarker.dm @@ -115,23 +115,20 @@ return -/obj/structure/gravemarker/verb/rotate() - set name = "Rotate Grave Marker" +/obj/structure/gravemarker/verb/rotate_clockwise() + set name = "Rotate Grave Marker Clockwise" set category = "Object" set src in oview(1) if(anchored) return - if(config.ghost_interaction) - src.set_dir(turn(src.dir, 90)) - return - else - if(istype(usr,/mob/living/simple_animal/mouse)) - return - if(!usr || !isturf(usr.loc)) - return - if(usr.stat || usr.restrained()) - return - src.set_dir(turn(src.dir, 90)) - return \ No newline at end of file + if(!usr || !isturf(usr.loc)) + return + if(usr.stat || usr.restrained()) + return + if(ismouse(usr) || (isobserver(usr) && !config.ghost_interaction)) + return + + src.set_dir(turn(src.dir, 270)) + return \ No newline at end of file diff --git a/code/game/objects/structures/holoplant.dm b/code/game/objects/structures/holoplant.dm index 1f762c027a..bbd92b81ee 100644 --- a/code/game/objects/structures/holoplant.dm +++ b/code/game/objects/structures/holoplant.dm @@ -17,7 +17,7 @@ "plant-13" ) -/obj/machinery/holoplant/initialize() +/obj/machinery/holoplant/Initialize() . = ..() activate() @@ -101,5 +101,5 @@ /obj/machinery/holoplant/shipped anchored = FALSE -/obj/machinery/holoplant/shipped/initialize() +/obj/machinery/holoplant/shipped/Initialize() . = ..() \ No newline at end of file diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm index 5f051a4e78..8ff7ee844f 100644 --- a/code/game/objects/structures/janicart.dm +++ b/code/game/objects/structures/janicart.dm @@ -102,7 +102,7 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart) data["replacer"] = myreplacer ? capitalize(myreplacer.name) : null data["signs"] = signs ? "[signs] sign\s" : null - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if(!ui) ui = new(user, src, ui_key, "janitorcart.tmpl", "Janitorial cart", 240, 160) ui.set_initial_data(data) diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm index d9ec122c55..443491d633 100644 --- a/code/game/objects/structures/lattice.dm +++ b/code/game/objects/structures/lattice.dm @@ -9,7 +9,7 @@ plane = PLATING_PLANE // flags = CONDUCT -/obj/structure/lattice/initialize() +/obj/structure/lattice/Initialize() . = ..() if(!(istype(src.loc, /turf/space) || istype(src.loc, /turf/simulated/open) || istype(src.loc, /turf/simulated/mineral))) diff --git a/code/game/objects/structures/lightpost.dm b/code/game/objects/structures/lightpost.dm new file mode 100644 index 0000000000..95f00d1467 --- /dev/null +++ b/code/game/objects/structures/lightpost.dm @@ -0,0 +1,42 @@ +/obj/structure/lightpost + name = "lightpost" + desc = "A homely lightpost." + icon = 'icons/obj/32x64.dmi' + icon_state = "lightpost" + plane = MOB_PLANE + layer = ABOVE_MOB_LAYER + anchored = TRUE + density = TRUE + opacity = FALSE + + var/lit = TRUE // If true, will have a glowing overlay and lighting. + var/festive = FALSE // If true, adds a festive bow overlay to it. + +/obj/structure/lightpost/Initialize() + update_icon() + return ..() + +/obj/structure/lightpost/update_icon() + cut_overlays() + + if(lit) + set_light(5, 1, "#E9E4AF") + var/image/glow = image(icon_state = "[icon_state]-glow") + glow.plane = PLANE_LIGHTING_ABOVE + add_overlay(glow) + else + set_light(0) + + if(festive) + var/image/bow = image(icon_state = "[icon_state]-festive") + add_overlay(bow) + +/obj/structure/lightpost/unlit + lit = FALSE + +/obj/structure/lightpost/festive + desc = "A homely lightpost adorned with festive decor." + festive = TRUE + +/obj/structure/lightpost/festive/unlit + lit = FALSE \ No newline at end of file diff --git a/code/game/objects/structures/loot_piles.dm b/code/game/objects/structures/loot_piles.dm index f8d9977823..ea92ed27f1 100644 --- a/code/game/objects/structures/loot_piles.dm +++ b/code/game/objects/structures/loot_piles.dm @@ -115,7 +115,7 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh var/path = pick(rare_loot) return new path(src) -/obj/structure/loot_pile/initialize() +/obj/structure/loot_pile/Initialize() if(icon_states_to_use && icon_states_to_use.len) icon_state = pick(icon_states_to_use) . = ..() @@ -574,6 +574,7 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh icon = 'icons/mecha/mecha.dmi' icon_state = "engineering_pod-broken" density = TRUE + anchored = FALSE // In case a dead mecha-mob dies in a bad spot. chance_uncommon = 20 chance_rare = 10 @@ -615,7 +616,7 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh /obj/structure/loot_pile/mecha/ripley name = "ripley wreckage" desc = "The ruins of some unfortunate ripley. Perhaps something is salvageable." - icon_states_to_use = list("ripley-broken", "firefighter-broken", "ripley-broken-old") + icon_state = "ripley-broken" common_loot = list( /obj/random/tool, @@ -649,6 +650,12 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh /obj/item/mecha_parts/mecha_equipment/weapon/energy/flamer/rigged ) +/obj/structure/loot_pile/mecha/ripley/firefighter + icon_state = "firefighter-broken" + +/obj/structure/loot_pile/mecha/ripley/random_sprite + icon_states_to_use = list("ripley-broken", "firefighter-broken", "ripley-broken-old") + //Death-Ripley, same common, but more combat-exosuit-based /obj/structure/loot_pile/mecha/deathripley name = "strange ripley wreckage" @@ -719,6 +726,14 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh /obj/item/mecha_parts/mecha_equipment/shocker ) +/obj/structure/loot_pile/mecha/odysseus/murdysseus + icon_state = "murdysseus-broken" + +/obj/structure/loot_pile/mecha/hoverpod + name = "hoverpod wreckage" + desc = "The ruins of some unfortunate hoverpod. Perhaps something is salvageable." + icon_state = "engineering_pod" + /obj/structure/loot_pile/mecha/gygax name = "gygax wreckage" desc = "The ruins of some unfortunate gygax. Perhaps something is salvageable." @@ -759,6 +774,18 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy ) +/obj/structure/loot_pile/mecha/gygax/dark + icon_state = "darkgygax-broken" + +// Todo: Better loot. +/obj/structure/loot_pile/mecha/gygax/dark/adv + icon_state = "darkgygax_adv-broken" + icon_scale = 1.5 + pixel_y = 8 + +/obj/structure/loot_pile/mecha/gygax/medgax + icon_state = "medgax-broken" + /obj/structure/loot_pile/mecha/durand name = "durand wreckage" desc = "The ruins of some unfortunate durand. Perhaps something is salvageable." @@ -799,6 +826,22 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy ) +/obj/structure/loot_pile/mecha/marauder + name = "marauder wreckage" + desc = "The ruins of some unfortunate marauder. Perhaps something is salvagable." + icon_state = "marauder-broken" + // Todo: Better loot. + +/obj/structure/loot_pile/mecha/marauder/seraph + name = "seraph wreckage" + desc = "The ruins of some unfortunate seraph. Perhaps something is salvagable." + icon_state = "seraph-broken" + +/obj/structure/loot_pile/mecha/marauder/mauler + name = "mauler wreckage" + desc = "The ruins of some unfortunate mauler. Perhaps something is salvagable." + icon_state = "mauler-broken" + /obj/structure/loot_pile/mecha/phazon name = "phazon wreckage" desc = "The ruins of some unfortunate phazon. Perhaps something is salvageable." @@ -868,4 +911,28 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh /obj/item/borg/upgrade/tasercooler, /obj/item/borg/upgrade/syndicate, /obj/item/borg/upgrade/vtec - ) \ No newline at end of file + ) + +// Contains old mediciation, most of it unidentified and has a good chance of being useless. +/obj/structure/loot_pile/surface/medicine_cabinet + name = "abandoned medicine cabinet" + desc = "An old cabinet, it might still have something of use inside." + icon_state = "medicine_cabinet" + density = FALSE + chance_uncommon = 0 + chance_rare = 0 + + common_loot = list( + /obj/random/unidentified_medicine/old_medicine + ) + +// Like the above but has way better odds, in exchange for being in a place still inhabited (or was recently). +/obj/structure/loot_pile/surface/medicine_cabinet/fresh + name = "medicine cabinet" + desc = "A cabinet designed to hold medicine, it might still have something of use inside." + icon_state = "medicine_cabinet" + density = FALSE + + common_loot = list( + /obj/random/unidentified_medicine/fresh_medicine + ) \ No newline at end of file diff --git a/code/game/objects/structures/map_blocker_vr.dm b/code/game/objects/structures/map_blocker_vr.dm index 03a5a874b8..52be6c4035 100644 --- a/code/game/objects/structures/map_blocker_vr.dm +++ b/code/game/objects/structures/map_blocker_vr.dm @@ -9,7 +9,7 @@ density = 1 unacidable = 1 -/obj/effect/blocker/initialize() // For non-gateway maps. +/obj/effect/blocker/Initialize() // For non-gateway maps. . = ..() icon = null icon_state = null diff --git a/code/game/objects/structures/musician.dm b/code/game/objects/structures/musician.dm index 95d2656ed5..f563a380cb 100644 --- a/code/game/objects/structures/musician.dm +++ b/code/game/objects/structures/musician.dm @@ -210,12 +210,12 @@ else tempo = sanitize_tempo(5) // default 120 BPM if(lines.len > INSTRUMENT_MAX_LINE_NUMBER) - usr << "Too many lines!" + to_chat(usr, "Too many lines!") lines.Cut(INSTRUMENT_MAX_LINE_NUMBER+1) var/linenum = 1 for(var/l in lines) if(lentext(l) > INSTRUMENT_MAX_LINE_LENGTH) - usr << "Line [linenum] too long!" + to_chat(usr, "Line [linenum] too long!") lines.Remove(l) else linenum++ @@ -316,22 +316,18 @@ song = null ..() -/obj/structure/device/piano/verb/rotate() - set name = "Rotate Piano" +/obj/structure/device/piano/verb/rotate_clockwise() + set name = "Rotate Piano Clockwise" set category = "Object" set src in oview(1) - if(istype(usr,/mob/living/simple_animal/mouse)) + if(ismouse(usr)) return - else if(!usr || !isturf(usr.loc)) + if(!usr || !isturf(usr.loc) || usr.stat || usr.restrained()) return - else if(usr.stat || usr.restrained()) - return - else if (istype(usr,/mob/observer/ghost) && !config.ghost_interaction) - return - else - src.set_dir(turn(src.dir, 90)) + if (isobserver(usr) && !config.ghost_interaction) return + src.set_dir(turn(src.dir, 270)) /obj/structure/device/piano/attack_hand(mob/user) if(!user.IsAdvancedToolUser()) @@ -350,7 +346,7 @@ if(O.is_wrench()) if(anchored) playsound(src.loc, O.usesound, 50, 1) - user << "You begin to loosen \the [src]'s casters..." + to_chat(user, "You begin to loosen \the [src]'s casters...") if (do_after(user, 40 * O.toolspeed)) user.visible_message( \ "[user] loosens \the [src]'s casters.", \ @@ -359,7 +355,7 @@ src.anchored = 0 else playsound(src.loc, O.usesound, 50, 1) - user << "You begin to tighten \the [src] to the floor..." + to_chat(user, "You begin to tighten \the [src] to the floor...") if (do_after(user, 20 * O.toolspeed)) user.visible_message( \ "[user] tightens \the [src]'s casters.", \ diff --git a/code/game/objects/structures/noticeboard.dm b/code/game/objects/structures/noticeboard.dm index 64ef2f926b..2aa11fffa5 100644 --- a/code/game/objects/structures/noticeboard.dm +++ b/code/game/objects/structures/noticeboard.dm @@ -19,7 +19,7 @@ update_icon() return -/obj/structure/noticeboard/initialize() +/obj/structure/noticeboard/Initialize() for(var/obj/item/I in loc) if(notices > 4) break if(istype(I, /obj/item/weapon/paper)) diff --git a/code/game/objects/structures/plasticflaps.dm b/code/game/objects/structures/plasticflaps.dm index 0340356e37..f328eb54fa 100644 --- a/code/game/objects/structures/plasticflaps.dm +++ b/code/game/objects/structures/plasticflaps.dm @@ -10,8 +10,8 @@ explosion_resistance = 5 var/list/mobs_can_pass = list( /mob/living/bot, - /mob/living/simple_animal/slime, - /mob/living/simple_animal/mouse, + /mob/living/simple_mob/slime/xenobio, + /mob/living/simple_mob/animal/passive/mouse, /mob/living/silicon/robot/drone ) diff --git a/code/game/objects/structures/props/alien_props.dm b/code/game/objects/structures/props/alien_props.dm index fa11e27b15..67a5b0d094 100644 --- a/code/game/objects/structures/props/alien_props.dm +++ b/code/game/objects/structures/props/alien_props.dm @@ -59,7 +59,7 @@ var/static/list/possible_states = list("health", "spider", "slime", "emp", "species", "egg", "vent", "mindshock", "viral", "gland") var/static/list/possible_tech = list(TECH_MATERIAL, TECH_ENGINEERING, TECH_PHORON, TECH_POWER, TECH_BIO, TECH_COMBAT, TECH_MAGNET, TECH_DATA) -/obj/item/prop/alien/junk/initialize() +/obj/item/prop/alien/junk/Initialize() . = ..() icon_state = pick(possible_states) var/list/techs = possible_tech.Copy() diff --git a/code/game/objects/structures/props/beam_prism.dm b/code/game/objects/structures/props/beam_prism.dm index 44df2eb68b..f5c4c3d3c0 100644 --- a/code/game/objects/structures/props/beam_prism.dm +++ b/code/game/objects/structures/props/beam_prism.dm @@ -26,7 +26,7 @@ interaction_message = "The prismatic turret seems to be able to rotate." -/obj/structure/prop/prism/initialize() +/obj/structure/prop/prism/Initialize() if(degrees_from_north) animate(src, transform = turn(NORTH, degrees_from_north), time = 3) @@ -196,7 +196,7 @@ for(var/obj/structure/prop/prism/P in my_turrets) P.rotate_auto(new_bearing) -/obj/structure/prop/prismcontrol/initialize() +/obj/structure/prop/prismcontrol/Initialize() ..() if(my_turrets.len) //Preset controls. for(var/obj/structure/prop/prism/P in my_turrets) diff --git a/code/game/objects/structures/props/nest.dm b/code/game/objects/structures/props/nest.dm index b6a4677f12..4cb515fc36 100644 --- a/code/game/objects/structures/props/nest.dm +++ b/code/game/objects/structures/props/nest.dm @@ -11,7 +11,7 @@ var/last_spawn var/spawn_delay = 150 var/randomize_spawning = FALSE - var/creature_types = list(/mob/living/simple_animal/retaliate/diyaab) + var/creature_types = list(/mob/living/simple_mob/animal/sif/diyaab) var/list/den_mobs var/den_faction //The faction of any spawned creatures. var/max_creatures = 3 //Maximum number of living creatures this nest can have at one time. @@ -19,10 +19,10 @@ var/tally = 0 //The counter referenced against total_creature_max, or just to see how many mobs it has spawned. var/total_creature_max //If set, it can spawn this many creatures, total, ever. -/obj/structure/prop/nest/initialize() +/obj/structure/prop/nest/Initialize() ..() den_mobs = list() - processing_objects |= src + START_PROCESSING(SSobj, src) last_spawn = world.time if(randomize_spawning) //Not the biggest shift in spawntime, but it's here. var/delayshift_clamp = spawn_delay / 10 @@ -31,7 +31,7 @@ /obj/structure/prop/nest/Destroy() den_mobs = null - processing_objects -= src + STOP_PROCESSING(SSobj, src) ..() /obj/structure/prop/nest/attack_hand(mob/living/user) // Used to tell the player that this isn't useful for anything. diff --git a/code/game/objects/structures/props/puzzledoor.dm b/code/game/objects/structures/props/puzzledoor.dm index b9a32fc0dc..70d6508202 100644 --- a/code/game/objects/structures/props/puzzledoor.dm +++ b/code/game/objects/structures/props/puzzledoor.dm @@ -31,7 +31,7 @@ visible_message("\The [src] is completely unaffected by the blast.") return -/obj/machinery/door/blast/puzzle/initialize() +/obj/machinery/door/blast/puzzle/Initialize() . = ..() implicit_material = get_material_by_name("dungeonium") if(locks.len) diff --git a/code/game/objects/structures/railing.dm b/code/game/objects/structures/railing.dm index 18e45af166..6c1a8f485b 100644 --- a/code/game/objects/structures/railing.dm +++ b/code/game/objects/structures/railing.dm @@ -23,7 +23,7 @@ if(climbable) verbs += /obj/structure/proc/climb_on -/obj/structure/railing/initialize() +/obj/structure/railing/Initialize() . = ..() if(src.anchored) update_icon(0) @@ -126,7 +126,7 @@ if (WEST) overlays += image ('icons/obj/railing.dmi', src, "mcorneroverlay", pixel_y = 32) -/obj/structure/railing/verb/rotate() +/obj/structure/railing/verb/rotate_counterclockwise() set name = "Rotate Railing Counter-Clockwise" set category = "Object" set src in oview(1) @@ -141,11 +141,11 @@ to_chat(usr, "It is fastened to the floor therefore you can't rotate it!") return 0 - set_dir(turn(dir, 90)) + src.set_dir(turn(src.dir, 90)) update_icon() return -/obj/structure/railing/verb/revrotate() +/obj/structure/railing/verb/rotate_clockwise() set name = "Rotate Railing Clockwise" set category = "Object" set src in oview(1) @@ -160,7 +160,7 @@ to_chat(usr, "It is fastened to the floor therefore you can't rotate it!") return 0 - set_dir(turn(dir, -90)) + src.set_dir(turn(src.dir, 270)) update_icon() return diff --git a/code/game/objects/structures/safe.dm b/code/game/objects/structures/safe.dm index 37edb603c1..9de9dc082b 100644 --- a/code/game/objects/structures/safe.dm +++ b/code/game/objects/structures/safe.dm @@ -30,7 +30,7 @@ FLOOR SAFES tumbler_2_open = rand(0, 72) -/obj/structure/safe/initialize() +/obj/structure/safe/Initialize() . = ..() for(var/obj/item/I in loc) if(space >= maxspace) @@ -175,7 +175,7 @@ obj/structure/safe/ex_act(severity) plane = TURF_PLANE layer = ABOVE_UTILITY -/obj/structure/safe/floor/initialize() +/obj/structure/safe/floor/Initialize() . = ..() var/turf/T = loc if(istype(T) && !T.is_plating()) diff --git a/code/game/objects/structures/signs.dm b/code/game/objects/structures/signs.dm index bd868bcc91..26bc212829 100644 --- a/code/game/objects/structures/signs.dm +++ b/code/game/objects/structures/signs.dm @@ -239,6 +239,18 @@ name = "\improper EMERGENT INTELLIGENCE DETAILS" icon_state = "rogueai" +/obj/structure/sign/warning/falling + name = "\improper FALL HAZARD" + icon_state = "falling" + +/obj/structure/sign/warning/lava + name = "\improper MOLTEN SURFACE" + icon_state = "lava" + +/obj/structure/sign/warning/acid + name = "\improper ACIDIC SURFACE" + icon_state = "acid" + /obj/structure/sign/redcross name = "medbay" desc = "The Intergalactic symbol of Medical institutions. You'll probably get help here." diff --git a/code/game/objects/structures/simple_doors.dm b/code/game/objects/structures/simple_doors.dm index 4f430d3ec6..f9d5b2250a 100644 --- a/code/game/objects/structures/simple_doors.dm +++ b/code/game/objects/structures/simple_doors.dm @@ -36,11 +36,11 @@ else set_opacity(1) if(material.products_need_process()) - processing_objects |= src + START_PROCESSING(SSobj, src) update_nearby_tiles(need_rebuild=1) /obj/structure/simple_door/Destroy() - processing_objects -= src + STOP_PROCESSING(SSobj, src) update_nearby_tiles() return ..() @@ -206,6 +206,6 @@ /obj/structure/simple_door/cult/TryToSwitchState(atom/user) if(isliving(user)) var/mob/living/L = user - if(!iscultist(L) && !istype(L, /mob/living/simple_animal/construct)) + if(!iscultist(L) && !istype(L, /mob/living/simple_mob/construct)) return ..() 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 3e76682b19..8950533b8e 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm @@ -20,7 +20,7 @@ if(!padding_material && istype(W, /obj/item/assembly/shock_kit)) var/obj/item/assembly/shock_kit/SK = W if(!SK.status) - user << "\The [SK] is not ready to be attached!" + to_chat(user, "\The [SK] is not ready to be attached!") return user.drop_item() var/obj/structure/bed/chair/e_chair/E = new (src.loc, material.name) @@ -35,7 +35,7 @@ if(has_buckled_mobs()) ..() else - rotate() + rotate_clockwise() return /obj/structure/bed/chair/post_buckle_mob() @@ -68,24 +68,19 @@ var/mob/living/L = A L.set_dir(dir) -/obj/structure/bed/chair/verb/rotate() - set name = "Rotate Chair" +/obj/structure/bed/chair/verb/rotate_clockwise() + set name = "Rotate Chair Clockwise" set category = "Object" set src in oview(1) - if(config.ghost_interaction) - src.set_dir(turn(src.dir, 90)) + if(!usr || !isturf(usr.loc)) + return + if(usr.stat || usr.restrained()) + return + if(ismouse(usr) || (isobserver(usr) && !config.ghost_interaction)) return - else - if(istype(usr,/mob/living/simple_animal/mouse)) - return - if(!usr || !isturf(usr.loc)) - return - if(usr.stat || usr.restrained()) - return - src.set_dir(turn(src.dir, 90)) - return + src.set_dir(turn(src.dir, 270)) /obj/structure/bed/chair/shuttle name = "chair" diff --git a/code/game/objects/structures/trash_pile.dm b/code/game/objects/structures/trash_pile.dm index cfce81e866..716de5a39e 100644 --- a/code/game/objects/structures/trash_pile.dm +++ b/code/game/objects/structures/trash_pile.dm @@ -28,7 +28,7 @@ var/global/list/allocated_gamma = list() -/obj/structure/trash_pile/initialize() +/obj/structure/trash_pile/Initialize() . = ..() icon_state = pick( "pile1", @@ -266,7 +266,7 @@ desc = "A small heap of trash, perfect for mice to nest in." icon = 'icons/obj/trash_piles.dmi' icon_state = "randompile" - spawn_types = list(/mob/living/simple_animal/mouse) + spawn_types = list(/mob/living/simple_mob/animal/passive/mouse) simultaneous_spawns = 1 destructible = 1 spawn_delay = 1 HOUR @@ -294,4 +294,4 @@ /obj/structure/mob_spawner/mouse_nest/get_death_report(var/mob/living/L) ..() - last_spawn = rand(world.time - spawn_delay, world.time) \ No newline at end of file + last_spawn = rand(world.time - spawn_delay, world.time) diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index ff95dd44d8..464cf08f7d 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -131,10 +131,16 @@ var/watertemp = "normal" //freezing, normal, or boiling var/is_washing = 0 var/list/temperature_settings = list("normal" = 310, "boiling" = T0C+100, "freezing" = T0C) + var/datum/looping_sound/showering/soundloop -/obj/machinery/shower/New() - ..() +/obj/machinery/shower/Initialize() create_reagents(50) + soundloop = new(list(src), FALSE) + return ..() + +/obj/machinery/shower/Destroy() + QDEL_NULL(soundloop) + return ..() //add heat controls? when emagged, you can freeze to death in it? @@ -151,11 +157,14 @@ on = !on update_icon() if(on) + soundloop.start() if (M.loc == loc) wash(M) process_heat(M) for (var/atom/movable/G in src.loc) G.clean_blood() + else + soundloop.stop() /obj/machinery/shower/attackby(obj/item/I as obj, mob/user as mob) if(I.type == /obj/item/device/analyzer) diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm index 47f08399f0..25a97b642c 100644 --- a/code/game/objects/structures/windoor_assembly.dm +++ b/code/game/objects/structures/windoor_assembly.dm @@ -273,8 +273,8 @@ obj/structure/windoor_assembly/Destroy() name += "[secure ? "secure " : ""]windoor assembly[created_name ? " ([created_name])" : ""]" //Rotates the windoor assembly clockwise -/obj/structure/windoor_assembly/verb/revrotate() - set name = "Rotate Windoor Assembly" +/obj/structure/windoor_assembly/verb/rotate_clockwise() + set name = "Rotate Windoor Assembly Clockwise" set category = "Object" set src in oview(1) diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 5c7adf8f0e..1532f499a5 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -21,29 +21,30 @@ var/shardtype = /obj/item/weapon/material/shard var/glasstype = null // Set this in subtypes. Null is assumed strange or otherwise impossible to dismantle, such as for shuttle glass. var/silicate = 0 // number of units of silicate + var/fulltile = FALSE // Set to true on full-tile variants. /obj/structure/window/examine(mob/user) . = ..(user) if(health == maxhealth) - user << "It looks fully intact." + to_chat(user, "It looks fully intact.") else var/perc = health / maxhealth if(perc > 0.75) - user << "It has a few cracks." + to_chat(user, "It has a few cracks.") else if(perc > 0.5) - user << "It looks slightly damaged." + to_chat(user, "It looks slightly damaged.") else if(perc > 0.25) - user << "It looks moderately damaged." + to_chat(user, "It looks moderately damaged.") else - user << "It looks heavily damaged." + to_chat(user, "It looks heavily damaged.") if(silicate) if (silicate < 30) - user << "It has a thin layer of silicate." + to_chat(user, "It has a thin layer of silicate.") else if (silicate < 70) - user << "It is covered in silicate." + to_chat(user, "It is covered in silicate.") else - user << "There is a thick layer of silicate covering it." + to_chat(user, "There is a thick layer of silicate covering it.") /obj/structure/window/proc/take_damage(var/damage = 0, var/sound_effect = 1) var/initialhealth = health @@ -128,22 +129,15 @@ /obj/structure/window/blob_act() take_damage(50) -//TODO: Make full windows a separate type of window. -//Once a full window, it will always be a full window, so there's no point -//having the same type for both. -/obj/structure/window/proc/is_full_window() - return (dir == SOUTHWEST || dir == SOUTHEAST || dir == NORTHWEST || dir == NORTHEAST) - /obj/structure/window/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) if(istype(mover) && mover.checkpass(PASSGLASS)) - return 1 - if(is_full_window()) - return 0 //full tile window, you can't move into it! - if(get_dir(loc, target) & dir) + return TRUE + if(is_fulltile()) + return FALSE //full tile window, you can't move into it! + if((get_dir(loc, target) & dir) || (get_dir(mover, target) == turn(dir, 180))) return !density else - return 1 - + return TRUE /obj/structure/window/CheckExit(atom/movable/O as mob|obj, target as turf) if(istype(O) && O.checkpass(PASSGLASS)) @@ -152,7 +146,6 @@ return 0 return 1 - /obj/structure/window/hitby(AM as mob|obj) ..() visible_message("[src] was hit by [AM].") @@ -206,7 +199,7 @@ user.setClickCooldown(user.get_attack_speed()) if(!damage) return - if(damage >= 10) + if(damage >= STRUCTURE_MIN_DAMAGE_THRESHOLD) visible_message("[user] smashes into [src]!") if(reinf) damage = damage / 2 @@ -267,26 +260,26 @@ state = 3 - state update_nearby_icons() playsound(src, W.usesound, 75, 1) - user << (state == 1 ? "You have unfastened the window from the frame." : "You have fastened the window to the frame.") + to_chat(user, "You have [state ? "un" : ""]fastened the window [state ? "from" : "to"] the frame.") else if(reinf && state == 0) anchored = !anchored update_nearby_icons() update_verbs() playsound(src, W.usesound, 75, 1) - user << (anchored ? "You have fastened the frame to the floor." : "You have unfastened the frame from the floor.") + to_chat(user, "You have [anchored ? "" : "un"]fastened the frame [anchored ? "to" : "from"] the floor.") else if(!reinf) anchored = !anchored update_nearby_icons() update_verbs() playsound(src, W.usesound, 75, 1) - user << (anchored ? "You have fastened the window to the floor." : "You have unfastened the window.") + to_chat(user, "You have [anchored ? "" : "un"]fastened the window [anchored ? "to" : "from"] the floor.") else if(W.is_crowbar() && reinf && state <= 1) state = 1 - state playsound(src, W.usesound, 75, 1) - user << (state ? "You have pried the window into the frame." : "You have pried the window out of the frame.") + to_chat(user, "You have pried the window [state ? "into" : "out of"] the frame.") else if(W.is_wrench() && !anchored && (!state || !reinf)) if(!glasstype) - user << "You're not sure how to dismantle \the [src] properly." + to_chat(user, "You're not sure how to dismantle \the [src] properly.") else playsound(src, W.usesound, 75, 1) visible_message("[user] dismantles \the [src].") @@ -334,8 +327,8 @@ return -/obj/structure/window/proc/rotate() - set name = "Rotate Window Counter-Clockwise" +/obj/structure/window/verb/rotate_counterclockwise() + set name = "Rotate Window Counterclockwise" set category = "Object" set src in oview(1) @@ -346,17 +339,17 @@ return 0 if(anchored) - usr << "It is fastened to the floor therefore you can't rotate it!" + to_chat(usr, "It is fastened to the floor therefore you can't rotate it!") return 0 update_nearby_tiles(need_rebuild=1) //Compel updates before - set_dir(turn(dir, 90)) + src.set_dir(turn(src.dir, 90)) updateSilicate() update_nearby_tiles(need_rebuild=1) return -/obj/structure/window/proc/revrotate() +/obj/structure/window/verb/rotate_clockwise() set name = "Rotate Window Clockwise" set category = "Object" set src in oview(1) @@ -368,11 +361,11 @@ return 0 if(anchored) - usr << "It is fastened to the floor therefore you can't rotate it!" + to_chat(usr, "It is fastened to the floor therefore you can't rotate it!") return 0 update_nearby_tiles(need_rebuild=1) //Compel updates before - set_dir(turn(dir, 270)) + src.set_dir(turn(src.dir, 270)) updateSilicate() update_nearby_tiles(need_rebuild=1) return @@ -388,8 +381,6 @@ anchored = 0 state = 0 update_verbs() - if(is_fulltile()) - maxhealth *= 2 health = maxhealth @@ -416,9 +407,7 @@ //checks if this window is full-tile one /obj/structure/window/proc/is_fulltile() - if(dir & (dir - 1)) - return 1 - return 0 + return fulltile //This proc is used to update the icons of nearby windows. It should not be confused with update_nearby_tiles(), which is an atmos proc! /obj/structure/window/proc/update_nearby_icons() @@ -429,11 +418,11 @@ //Updates the availabiliy of the rotation verbs /obj/structure/window/proc/update_verbs() if(anchored || is_fulltile()) - verbs -= /obj/structure/window/proc/rotate - verbs -= /obj/structure/window/proc/revrotate + verbs -= /obj/structure/window/verb/rotate_counterclockwise + verbs -= /obj/structure/window/verb/rotate_clockwise else if(!is_fulltile()) - verbs += /obj/structure/window/proc/rotate - verbs += /obj/structure/window/proc/revrotate + verbs += /obj/structure/window/verb/rotate_counterclockwise + verbs += /obj/structure/window/verb/rotate_clockwise //merges adjacent full-tile windows into one (blatant ripoff from game/smoothwall.dm) /obj/structure/window/update_icon() @@ -458,7 +447,7 @@ // Damage overlays. var/ratio = health / maxhealth - ratio = Ceiling(ratio * 4) * 25 + ratio = CEILING(ratio * 4, 1) * 25 if(ratio > 75) return @@ -484,6 +473,10 @@ maxhealth = 12.0 force_threshold = 3 +/obj/structure/window/basic/full + maxhealth = 24 + fulltile = TRUE + /obj/structure/window/phoronbasic name = "phoron window" desc = "A borosilicate alloy window. It seems to be quite strong." @@ -497,8 +490,8 @@ force_threshold = 5 /obj/structure/window/phoronbasic/full - dir = SOUTHWEST maxhealth = 80 + fulltile = TRUE /obj/structure/window/phoronreinforced name = "reinforced borosilicate window" @@ -514,8 +507,8 @@ force_threshold = 10 /obj/structure/window/phoronreinforced/full - dir = SOUTHWEST maxhealth = 160 + fulltile = TRUE /obj/structure/window/reinforced name = "reinforced window" @@ -530,9 +523,9 @@ force_threshold = 6 /obj/structure/window/reinforced/full - dir = SOUTHWEST icon_state = "fwindow" maxhealth = 80 + fulltile = TRUE /obj/structure/window/reinforced/tinted name = "tinted window" @@ -567,9 +560,9 @@ var/id /obj/structure/window/reinforced/polarized/full - dir = SOUTHWEST icon_state = "fwindow" maxhealth = 80 + fulltile = TRUE /obj/structure/window/reinforced/polarized/attackby(obj/item/W as obj, mob/user as mob) if(istype(W, /obj/item/device/multitool) && !anchored) // Only allow programming if unanchored! diff --git a/code/game/objects/structures/window_spawner.dm b/code/game/objects/structures/window_spawner.dm index e2714be757..52a8458077 100644 --- a/code/game/objects/structures/window_spawner.dm +++ b/code/game/objects/structures/window_spawner.dm @@ -25,7 +25,7 @@ /obj/effect/wingrille_spawn/CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0) return FALSE -/obj/effect/wingrille_spawn/initialize() +/obj/effect/wingrille_spawn/Initialize() . = ..() if(!win_path) return diff --git a/code/game/objects/weapons.dm b/code/game/objects/weapons.dm index 6cb93ab530..19fe4eb03c 100644 --- a/code/game/objects/weapons.dm +++ b/code/game/objects/weapons.dm @@ -27,16 +27,16 @@ cleaving = TRUE var/hit_mobs = 0 - for(var/mob/living/simple_animal/SA in range(get_turf(target), 1)) - if(SA.stat == DEAD) // Don't beat a dead horse. + for(var/mob/living/simple_mob/SM in range(get_turf(target), 1)) + if(SM.stat == DEAD) // Don't beat a dead horse. continue - if(SA == user) // Don't hit ourselves. Simple mobs shouldn't be able to do this but that might change later to be able to hit all mob/living-s. + if(SM == user) // Don't hit ourselves. Simple mobs shouldn't be able to do this but that might change later to be able to hit all mob/living-s. continue - if(SA == target) // We (presumably) already hit the target before cleave() was called. orange() should prevent this but just to be safe... + if(SM == target) // We (presumably) already hit the target before cleave() was called. orange() should prevent this but just to be safe... continue - if(!SA.Adjacent(user) || !SA.Adjacent(target)) // Cleaving only hits mobs near the target mob and user. + if(!SM.Adjacent(user) || !SM.Adjacent(target)) // Cleaving only hits mobs near the target mob and user. continue - if(resolve_attackby(SA, user, attack_modifier = 0.5)) // Hit them with the weapon. This won't cause recursive cleaving due to the cleaving variable being set to true. + if(resolve_attackby(SM, user, attack_modifier = 0.5)) // Hit them with the weapon. This won't cause recursive cleaving due to the cleaving variable being set to true. hit_mobs++ cleave_visual(user, target) @@ -55,4 +55,4 @@ // This is purely the visual effect of cleaving. /obj/item/weapon/proc/cleave_visual(var/mob/living/user, var/mob/living/target) var/obj/effect/temporary_effect/cleave_attack/E = new(get_turf(src)) - E.dir = get_dir(user, target) \ No newline at end of file + E.dir = get_dir(user, target) diff --git a/code/game/shuttle_engines.dm b/code/game/shuttle_engines.dm index c76967545e..03e8c25e6d 100644 --- a/code/game/shuttle_engines.dm +++ b/code/game/shuttle_engines.dm @@ -17,7 +17,7 @@ if(!height || air_group) return 0 else return ..() -/obj/structure/shuttle/window/initialize() +/obj/structure/shuttle/window/Initialize() . = ..() auto_join() diff --git a/code/game/sound.dm b/code/game/sound.dm index b9810d7915..b1f0c32f66 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -23,7 +23,7 @@ if(distance <= maxdistance) if(T && T.z == turf_source.z) - M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff, is_global, channel, pressure_affected, S) + M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff, is_global, channel, pressure_affected, S, preference) /mob/proc/playsound_local(turf/turf_source, soundin, vol as num, vary, frequency, falloff, is_global, channel = 0, pressure_affected = TRUE, sound/S, preference) if(!client || ear_deaf > 0) @@ -130,8 +130,6 @@ if ("fracture") soundin = pick('sound/effects/bonebreak1.ogg','sound/effects/bonebreak2.ogg','sound/effects/bonebreak3.ogg','sound/effects/bonebreak4.ogg') if ("canopen") soundin = pick('sound/effects/can_open1.ogg','sound/effects/can_open2.ogg','sound/effects/can_open3.ogg','sound/effects/can_open4.ogg') if ("mechstep") soundin = pick('sound/mecha/mechstep1.ogg', 'sound/mecha/mechstep2.ogg') - if ("geiger") soundin = pick('sound/items/geiger1.ogg', 'sound/items/geiger2.ogg', 'sound/items/geiger3.ogg', 'sound/items/geiger4.ogg', 'sound/items/geiger5.ogg') - if ("geiger_weak") soundin = pick('sound/items/geiger_weak1.ogg', 'sound/items/geiger_weak2.ogg', 'sound/items/geiger_weak3.ogg', 'sound/items/geiger_weak4.ogg') if ("thunder") soundin = pick('sound/effects/thunder/thunder1.ogg', 'sound/effects/thunder/thunder2.ogg', 'sound/effects/thunder/thunder3.ogg', 'sound/effects/thunder/thunder4.ogg', 'sound/effects/thunder/thunder5.ogg', 'sound/effects/thunder/thunder6.ogg', 'sound/effects/thunder/thunder7.ogg', 'sound/effects/thunder/thunder8.ogg', 'sound/effects/thunder/thunder9.ogg', 'sound/effects/thunder/thunder10.ogg') diff --git a/code/game/turfs/flooring/flooring.dm b/code/game/turfs/flooring/flooring.dm index 549265e954..2f45eb7b51 100644 --- a/code/game/turfs/flooring/flooring.dm +++ b/code/game/turfs/flooring/flooring.dm @@ -74,7 +74,6 @@ var/list/flooring_types 'sound/effects/footstep/snow4.ogg', 'sound/effects/footstep/snow5.ogg')) - /decl/flooring/snow/snow2 name = "snow" desc = "A layer of many tiny bits of frozen water. It's hard to tell how deep it is." diff --git a/code/game/turfs/flooring/flooring_decals.dm b/code/game/turfs/flooring/flooring_decals.dm index 8d24e46765..f69d676ccd 100644 --- a/code/game/turfs/flooring/flooring_decals.dm +++ b/code/game/turfs/flooring/flooring_decals.dm @@ -14,7 +14,7 @@ var/list/floor_decals = list() if(newcolour) color = newcolour ..(newloc) -/obj/effect/floor_decal/initialize() +/obj/effect/floor_decal/Initialize() add_to_turf_decals() initialized = TRUE return INITIALIZE_HINT_QDEL @@ -40,7 +40,7 @@ var/list/floor_decals = list() /obj/effect/floor_decal/reset name = "reset marker" -/obj/effect/floor_decal/reset/initialize() +/obj/effect/floor_decal/reset/Initialize() var/turf/T = get_turf(src) if(T.decals && T.decals.len) T.decals.Cut() diff --git a/code/game/turfs/flooring/flooring_premade.dm b/code/game/turfs/flooring/flooring_premade.dm index e3e955ff17..d4874aa48b 100644 --- a/code/game/turfs/flooring/flooring_premade.dm +++ b/code/game/turfs/flooring/flooring_premade.dm @@ -71,7 +71,7 @@ /turf/simulated/floor/wood/broken icon_state = "wood_broken0" // This gets changed when spawned. -/turf/simulated/floor/wood/broken/initialize() +/turf/simulated/floor/wood/broken/Initialize() break_tile() return ..() @@ -84,7 +84,7 @@ /turf/simulated/floor/wood/sif/broken icon_state = "sifwood_broken0" // This gets changed when spawned. -/turf/simulated/floor/wood/sif/broken/initialize() +/turf/simulated/floor/wood/sif/broken/Initialize() break_tile() return ..() @@ -244,7 +244,7 @@ oxygen = 0 nitrogen = 0 -/turf/simulated/floor/reinforced/n20/initialize() +/turf/simulated/floor/reinforced/n20/Initialize() . = ..() if(!air) make_air() air.adjust_gas("sleeping_agent", ATMOSTANK_NITROUSOXIDE) diff --git a/code/game/turfs/simulated/dungeon/wall.dm b/code/game/turfs/simulated/dungeon/wall.dm index c1a02cde66..6c39e01798 100644 --- a/code/game/turfs/simulated/dungeon/wall.dm +++ b/code/game/turfs/simulated/dungeon/wall.dm @@ -32,7 +32,7 @@ mining_overlay_cache["rock_side_[place_dir]"] = image('icons/turf/walls.dmi', "rock_side", dir = place_dir) T.add_overlay(mining_overlay_cache["rock_side_[place_dir]"]) -/turf/simulated/wall/solidrock/initialize() +/turf/simulated/wall/solidrock/Initialize() icon_state = base_state update_icon(1) diff --git a/code/game/turfs/simulated/floor_types.dm b/code/game/turfs/simulated/floor_types.dm index 316153ebc0..d670fc3a40 100644 --- a/code/game/turfs/simulated/floor_types.dm +++ b/code/game/turfs/simulated/floor_types.dm @@ -185,7 +185,7 @@ light_color = "#66ffff" // Bright cyan. block_tele = TRUE -/turf/simulated/shuttle/floor/alien/initialize() +/turf/simulated/shuttle/floor/alien/Initialize() . = ..() icon_state = "alienpod[rand(1, 9)]" @@ -213,8 +213,9 @@ takes_underlays = 1 blocks_air = 1 //I'd make these unsimulated but it just fucks with so much stuff so many other places. - initialize() - icon_state = "carry_ingame" +/turf/simulated/shuttle/plating/carry/Initialize() + . = ..() + icon_state = "carry_ingame" /turf/simulated/shuttle/plating/airless/carry name = "airless carry turf" @@ -223,8 +224,9 @@ takes_underlays = 1 blocks_air = 1 - initialize() - icon_state = "carry_ingame" +/turf/simulated/shuttle/plating/airless/carry/Initialize() + . = ..() + icon_state = "carry_ingame" /turf/simulated/shuttle/plating/skipjack //Skipjack plating oxygen = 0 diff --git a/code/game/turfs/simulated/lava.dm b/code/game/turfs/simulated/lava.dm new file mode 100644 index 0000000000..acf0c17317 --- /dev/null +++ b/code/game/turfs/simulated/lava.dm @@ -0,0 +1,91 @@ +/turf/simulated/floor/lava + name = "lava" + desc = "A pool of molten rock." + description_info = "Molten rock is extremly dangerous, as it will cause massive harm to anything that touches it.
\ + A firesuit cannot fully protect from contact with molten rock." + gender = PLURAL // So it says "That's some lava." on examine. + icon = 'icons/turf/outdoors.dmi' + icon_state = "lava" + edge_blending_priority = -1 + light_range = 2 + light_power = 0.75 + light_color = LIGHT_COLOR_LAVA + movement_cost = 2 + can_build_into_floor = TRUE + can_dirty = FALSE + +/turf/simulated/floor/lava/outdoors + outdoors = TRUE + +// For maximum pedantry. +/turf/simulated/floor/lava/Initialize() + if(!outdoors) + name = "magma" + update_icon() + return ..() + +/turf/simulated/floor/lava/make_outdoors() + ..() + name = "lava" + +/turf/simulated/floor/lava/make_indoors() + ..() + name = "magma" + +/turf/simulated/floor/lava/update_icon() + cut_overlays() + ..() + update_icon_edge() + +/turf/simulated/floor/lava/Entered(atom/movable/AM) + if(burn_stuff(AM)) + START_PROCESSING(SSobj, src) + +/turf/simulated/floor/lava/hitby(atom/movable/AM) + if(burn_stuff(AM)) + START_PROCESSING(SSobj, src) + +/turf/simulated/floor/lava/process() + if(!burn_stuff()) + STOP_PROCESSING(SSobj, src) + +/turf/simulated/floor/lava/proc/is_safe() + //if anything matching this typecache is found in the lava, we don't burn things + var/static/list/lava_safeties_typecache = typecacheof(list(/obj/structure/catwalk)) + var/list/found_safeties = typecache_filter_list(contents, lava_safeties_typecache) + return LAZYLEN(found_safeties) + +/turf/simulated/floor/lava/proc/burn_stuff(atom/movable/AM) + . = FALSE + + if(is_safe()) + return FALSE + + var/thing_to_check = src + if(AM) + thing_to_check = list(AM) + + for(var/thing in thing_to_check) + if(isobj(thing)) + var/obj/O = thing + if(O.throwing) + continue + . = TRUE + O.lava_act() + + else if(isliving(thing)) + var/mob/living/L = thing + if(L.hovering || L.throwing) // Flying over the lava. We're just gonna pretend convection doesn't exist. + continue + . = TRUE + L.lava_act() + +// Lava that does nothing at all. +/turf/simulated/floor/lava/harmless/burn_stuff(atom/movable/AM) + return FALSE + +// Tells AI mobs to not suicide by pathing into lava if it would hurt them. +/turf/simulated/floor/lava/is_safe_to_enter(mob/living/L) + if(!is_safe() && !L.hovering) + return FALSE + return ..() \ No newline at end of file diff --git a/code/game/turfs/simulated/outdoors/grass.dm b/code/game/turfs/simulated/outdoors/grass.dm index 218291815f..0742f6c51b 100644 --- a/code/game/turfs/simulated/outdoors/grass.dm +++ b/code/game/turfs/simulated/outdoors/grass.dm @@ -29,17 +29,17 @@ var/list/grass_types = list( /obj/structure/flora/sif/eyes ) -/turf/simulated/floor/outdoors/grass/sif/initialize() - if(tree_chance && prob(tree_chance)) +/turf/simulated/floor/outdoors/grass/sif/Initialize() + if(tree_chance && prob(tree_chance) && !check_density()) new /obj/structure/flora/tree/sif(src) . = ..() -/turf/simulated/floor/outdoors/grass/initialize() +/turf/simulated/floor/outdoors/grass/Initialize() if(prob(50)) icon_state = "[initial(icon_state)]2" //edge_blending_priority++ - if(grass_chance && prob(grass_chance)) + if(grass_chance && prob(grass_chance) && !check_density()) var/grass_type = pick(grass_types) new grass_type(src) . = ..() diff --git a/code/game/turfs/simulated/outdoors/outdoors.dm b/code/game/turfs/simulated/outdoors/outdoors.dm index 968816dc6a..a378cc48da 100644 --- a/code/game/turfs/simulated/outdoors/outdoors.dm +++ b/code/game/turfs/simulated/outdoors/outdoors.dm @@ -20,7 +20,7 @@ var/list/turf_edge_cache = list() // When a turf gets demoted or promoted, this list gets adjusted. The top-most layer is the layer on the bottom of the list, due to how pop() works. var/list/turf_layers = list(/turf/simulated/floor/outdoors/rocks) -/turf/simulated/floor/outdoors/initialize() +/turf/simulated/floor/outdoors/Initialize() update_icon() . = ..() @@ -51,10 +51,10 @@ var/list/turf_edge_cache = list() make_indoors() /turf/simulated/proc/update_icon_edge() - if(edge_blending_priority) + if(edge_blending_priority && !forbid_turf_edge()) for(var/checkdir in cardinal) var/turf/simulated/T = get_step(src, checkdir) - if(istype(T) && T.edge_blending_priority && edge_blending_priority < T.edge_blending_priority && icon_state != T.icon_state) + if(istype(T) && T.edge_blending_priority && edge_blending_priority < T.edge_blending_priority && icon_state != T.icon_state && !T.forbid_turf_edge()) var/cache_key = "[T.get_edge_icon_state()]-[checkdir]" if(!turf_edge_cache[cache_key]) var/image/I = image(icon = 'icons/turf/outdoors_edge.dmi', icon_state = "[T.get_edge_icon_state()]-edge", dir = checkdir, layer = ABOVE_TURF_LAYER) @@ -65,6 +65,14 @@ var/list/turf_edge_cache = list() /turf/simulated/proc/get_edge_icon_state() return icon_state +// Tests if we shouldn't apply a turf edge. +// Returns the blocker if one exists. +/turf/simulated/proc/forbid_turf_edge() + for(var/obj/structure/S in contents) + if(S.block_turf_edges) + return S + return null + /turf/simulated/floor/outdoors/update_icon() ..() update_icon_edge() @@ -80,6 +88,8 @@ var/list/turf_edge_cache = list() icon_state = "rock" edge_blending_priority = 1 +/turf/simulated/floor/outdoors/rocks/caves + outdoors = FALSE // This proc adds a 'layer' on top of the turf. /turf/simulated/floor/outdoors/proc/promote(var/new_turf_type) @@ -132,4 +142,4 @@ var/list/turf_edge_cache = list() if(3) if(prob(66)) return - demote() \ No newline at end of file + demote() diff --git a/code/game/turfs/simulated/outdoors/sky.dm b/code/game/turfs/simulated/outdoors/sky.dm index 468b893b33..3188302288 100644 --- a/code/game/turfs/simulated/outdoors/sky.dm +++ b/code/game/turfs/simulated/outdoors/sky.dm @@ -12,7 +12,7 @@ nitrogen = 0 phoron = 0 -/turf/simulated/sky/initialize() +/turf/simulated/sky/Initialize() . = ..() SSplanets.addTurf(src) set_light(2, 2, "#FFFFFF") diff --git a/code/game/turfs/simulated/outdoors/snow.dm b/code/game/turfs/simulated/outdoors/snow.dm index 5fed8af66b..0f9be4ddbf 100644 --- a/code/game/turfs/simulated/outdoors/snow.dm +++ b/code/game/turfs/simulated/outdoors/snow.dm @@ -13,6 +13,9 @@ /turf/simulated/floor/outdoors/snow/Entered(atom/A) if(isliving(A)) + var/mob/living/L = A + if(L.hovering) // Flying things shouldn't make footprints. + return ..() var/mdir = "[A.dir]" crossed_dirs[mdir] = 1 update_icon() diff --git a/code/game/turfs/simulated/wall_attacks.dm b/code/game/turfs/simulated/wall_attacks.dm index 02c6d0d8dc..bd6adfe32f 100644 --- a/code/game/turfs/simulated/wall_attacks.dm +++ b/code/game/turfs/simulated/wall_attacks.dm @@ -60,9 +60,9 @@ var/damage_lower = 25 var/damage_upper = 75 if(isanimal(user)) - var/mob/living/simple_animal/S = user + var/mob/living/simple_mob/S = user playsound(src, S.attack_sound, 75, 1) - if(!(S.melee_damage_upper >= 10)) + if(!(S.melee_damage_upper >= STRUCTURE_MIN_DAMAGE_THRESHOLD * 2)) to_chat(user, "You bounce against the wall.") return FALSE damage_lower = S.melee_damage_lower @@ -75,7 +75,7 @@ to_chat(user, "You smash through the wall!") user.do_attack_animation(src) if(isanimal(user)) - var/mob/living/simple_animal/S = user + var/mob/living/simple_mob/S = user playsound(src, S.attack_sound, 75, 1) spawn(1) dismantle_wall(1) @@ -115,12 +115,12 @@ try_touch(user, rotting) -/turf/simulated/wall/attack_generic(var/mob/user, var/damage, var/attack_message, var/wallbreaker) +/turf/simulated/wall/attack_generic(var/mob/user, var/damage, var/attack_message) radiate() user.setClickCooldown(user.get_attack_speed()) var/rotting = (locate(/obj/effect/overlay/wallrot) in src) - if(!damage || !wallbreaker) + if(damage < STRUCTURE_MIN_DAMAGE_THRESHOLD * 2) try_touch(user, rotting) return @@ -128,7 +128,7 @@ return success_smash(user) if(reinf_material) - if((wallbreaker == 2) || (damage >= max(material.hardness,reinf_material.hardness))) + if(damage >= max(material.hardness, reinf_material.hardness) ) return success_smash(user) else if(damage >= material.hardness) return success_smash(user) diff --git a/code/game/turfs/simulated/wall_types.dm b/code/game/turfs/simulated/wall_types.dm index 9048bb5a49..37bf0d7541 100644 --- a/code/game/turfs/simulated/wall_types.dm +++ b/code/game/turfs/simulated/wall_types.dm @@ -154,7 +154,7 @@ //To allow mappers to rename shuttle walls to like "redfloor interior" or whatever for ease of use. name = true_name -/turf/simulated/shuttle/wall/initialize() +/turf/simulated/shuttle/wall/Initialize() . = ..() if(join_group) @@ -235,7 +235,7 @@ /turf/simulated/shuttle/wall/voidcraft/green stripe_color = "#00FF00" -/turf/simulated/shuttle/wall/voidcraft/initialize() +/turf/simulated/shuttle/wall/voidcraft/Initialize() . = ..() update_icon() diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index 136b8eeba6..cb1a0f631a 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -39,11 +39,10 @@ if(!isnull(rmaterialtype)) reinf_material = get_material_by_name(rmaterialtype) update_material() - - processing_turfs |= src + START_PROCESSING(SSturfs, src) /turf/simulated/wall/Destroy() - processing_turfs -= src + STOP_PROCESSING(SSturfs, src) dismantle_wall(null,null,1) ..() diff --git a/code/game/turfs/simulated/water.dm b/code/game/turfs/simulated/water.dm index 6539348e5d..33901a8b2b 100644 --- a/code/game/turfs/simulated/water.dm +++ b/code/game/turfs/simulated/water.dm @@ -9,20 +9,24 @@ edge_blending_priority = -1 movement_cost = 4 outdoors = TRUE + + layer = WATER_FLOOR_LAYER + can_dirty = FALSE // It's water var/depth = 1 // Higher numbers indicates deeper water. -/turf/simulated/floor/water/initialize() +/turf/simulated/floor/water/Initialize() . = ..() update_icon() /turf/simulated/floor/water/update_icon() ..() // To get the edges. - icon_state = water_state - var/image/floorbed_sprite = image(icon = 'icons/turf/outdoors.dmi', icon_state = under_state) - underlays.Cut() // To clear the old underlay, so the list doesn't expand infinitely - underlays.Add(floorbed_sprite) + + icon_state = under_state // This isn't set at compile time in order for it to show as water in the map editor. + var/image/water_sprite = image(icon = 'icons/turf/outdoors.dmi', icon_state = water_state, layer = WATER_LAYER) + add_overlay(water_sprite) + update_icon_edge() /turf/simulated/floor/water/get_edge_icon_state() @@ -102,6 +106,10 @@ /mob/living/proc/check_submerged() if(buckled) return 0 + if(hovering) + return 0 + if(locate(/obj/structure/catwalk) in loc) + return 0 var/turf/simulated/floor/water/T = loc if(istype(T)) return T.depth @@ -115,6 +123,8 @@ adjust_fire_stacks(-amount * 5) for(var/atom/movable/AM in contents) AM.water_act(amount) + remove_modifiers_of_type(/datum/modifier/fire) + inflict_water_damage(20 * amount) // Only things vulnerable to water will actually be harmed (slimes/prommies). var/list/shoreline_icon_cache = list() @@ -140,7 +150,13 @@ var/list/shoreline_icon_cache = list() var/icon/shoreline_water = icon(src.icon, "shoreline_water", src.dir) var/icon/shoreline_subtract = icon(src.icon, "[initial(icon_state)]_subtract", src.dir) shoreline_water.Blend(shoreline_subtract,ICON_SUBTRACT) + var/image/final = image(shoreline_water) + final.layer = WATER_LAYER - shoreline_icon_cache[cache_string] = shoreline_water + shoreline_icon_cache[cache_string] = final add_overlay(shoreline_icon_cache[cache_string]) +/turf/simulated/floor/water/is_safe_to_enter(mob/living/L) + if(L.get_water_protection() < 1) + return FALSE + return ..() diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index d9a41718a8..55e0dd3b67 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -10,7 +10,7 @@ var/keep_sprite = FALSE // heat_capacity = 700000 No. -/turf/space/initialize() +/turf/space/Initialize() . = ..() if(!keep_sprite) icon_state = "[((x + y) ^ ~(x * y) + z) % 25]" diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 0c18524346..a8242ad868 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -32,6 +32,7 @@ var/block_tele = FALSE // If true, most forms of teleporting to or from this turf tile will fail. var/can_build_into_floor = FALSE // Used for things like RCDs (and maybe lattices/floor tiles in the future), to see if a floor should replace it. + var/list/dangerous_objects // List of 'dangerous' objs that the turf holds that can cause something bad to happen when stepped on, used for AI mobs. /turf/New() ..() @@ -141,50 +142,6 @@ turf/attackby(obj/item/weapon/W as obj, mob/user as mob) sleep(2) O.update_transform() -/turf/Enter(atom/movable/mover as mob|obj, atom/forget as mob|obj|turf|area) - if(movement_disabled && usr.ckey != movement_disabled_exception) - usr << "Movement is admin-disabled." //This is to identify lag problems - return - - ..() - - if (!mover || !isturf(mover.loc)) - return 1 - - //First, check objects to block exit that are not on the border - for(var/obj/obstacle in mover.loc) - if(!(obstacle.flags & ON_BORDER) && (mover != obstacle) && (forget != obstacle)) - if(!obstacle.CheckExit(mover, src)) - mover.Bump(obstacle, 1) - return 0 - - //Now, check objects to block exit that are on the border - for(var/obj/border_obstacle in mover.loc) - if((border_obstacle.flags & ON_BORDER) && (mover != border_obstacle) && (forget != border_obstacle)) - if(!border_obstacle.CheckExit(mover, src)) - mover.Bump(border_obstacle, 1) - return 0 - - //Next, check objects to block entry that are on the border - for(var/obj/border_obstacle in src) - if(border_obstacle.flags & ON_BORDER) - if(!border_obstacle.CanPass(mover, mover.loc, 1, 0) && (forget != border_obstacle)) - mover.Bump(border_obstacle, 1) - return 0 - - //Then, check the turf itself - if (!src.CanPass(mover, src)) - mover.Bump(src, 1) - return 0 - - //Finally, check objects/mobs to block entry that are not on the border - for(var/atom/movable/obstacle in src) - if(!(obstacle.flags & ON_BORDER)) - if(!obstacle.CanPass(mover, mover.loc, 1, 0) && (forget != obstacle)) - mover.Bump(obstacle, 1) - return 0 - return 1 //Nothing found to block so return success! - var/const/enterloopsanity = 100 /turf/Entered(atom/atom as mob|obj) @@ -217,14 +174,74 @@ var/const/enterloopsanity = 100 var/objects = 0 if(A && (A.flags & PROXMOVE)) for(var/atom/movable/thing in range(1)) - if(objects > enterloopsanity) break - objects++ + if(objects++ > enterloopsanity) break spawn(0) if(A) //Runtime prevention A.HasProximity(thing, 1) if ((thing && A) && (thing.flags & PROXMOVE)) thing.HasProximity(A, 1) - return + +/turf/CanPass(atom/movable/mover, turf/target) + if(!target) + return FALSE + + if(istype(mover)) // turf/Enter(...) will perform more advanced checks + return !density + + crash_with("Non movable passed to turf CanPass : [mover]") + return FALSE + +//There's a lot of QDELETED() calls here if someone can figure out how to optimize this but not runtime when something gets deleted by a Bump/CanPass/Cross call, lemme know or go ahead and fix this mess - kevinz000 +/turf/Enter(atom/movable/mover, atom/oldloc) + if(movement_disabled && usr.ckey != movement_disabled_exception) + usr << "Movement is admin-disabled." //This is to identify lag problems + return + // Do not call ..() + // Byond's default turf/Enter() doesn't have the behaviour we want with Bump() + // By default byond will call Bump() on the first dense object in contents + // Here's hoping it doesn't stay like this for years before we finish conversion to step_ + var/atom/firstbump + var/CanPassSelf = CanPass(mover, src) + if(CanPassSelf || CHECK_BITFIELD(mover.movement_type, UNSTOPPABLE)) + for(var/i in contents) + if(QDELETED(mover)) + return FALSE //We were deleted, do not attempt to proceed with movement. + if(i == mover || i == mover.loc) // Multi tile objects and moving out of other objects + continue + var/atom/movable/thing = i + if(!thing.Cross(mover)) + if(QDELETED(mover)) //Mover deleted from Cross/CanPass, do not proceed. + return FALSE + if(CHECK_BITFIELD(mover.movement_type, UNSTOPPABLE)) + mover.Bump(thing) + continue + else + if(!firstbump || ((thing.layer > firstbump.layer || thing.flags & ON_BORDER) && !(firstbump.flags & ON_BORDER))) + firstbump = thing + if(QDELETED(mover)) //Mover deleted from Cross/CanPass/Bump, do not proceed. + return FALSE + if(!CanPassSelf) //Even if mover is unstoppable they need to bump us. + firstbump = src + if(firstbump) + mover.Bump(firstbump) + return !QDELETED(mover) && CHECK_BITFIELD(mover.movement_type, UNSTOPPABLE) + return TRUE + +/turf/Exit(atom/movable/mover, atom/newloc) + . = ..() + if(!. || QDELETED(mover)) + return FALSE + for(var/i in contents) + if(i == mover) + continue + var/atom/movable/thing = i + if(!thing.Uncross(mover, newloc)) + if(thing.flags & ON_BORDER) + mover.Bump(thing) + if(!CHECK_BITFIELD(mover.movement_type, UNSTOPPABLE)) + return FALSE + if(QDELETED(mover)) + return FALSE //We were deleted. /turf/proc/adjacent_fire_act(turf/simulated/floor/source, temperature, volume) return @@ -283,9 +300,6 @@ var/const/enterloopsanity = 100 L.Add(t) return L -/turf/proc/process() - return PROCESS_KILL - /turf/proc/contains_dense_objects() if(density) return 1 @@ -323,6 +337,30 @@ var/const/enterloopsanity = 100 /turf/AllowDrop() return TRUE +// Returns false if stepping into a tile would cause harm (e.g. open space while unable to fly, water tile while a slime, lava, etc). +/turf/proc/is_safe_to_enter(mob/living/L) + if(LAZYLEN(dangerous_objects)) + for(var/obj/O in dangerous_objects) + if(!O.is_safe_to_step(L)) + return FALSE + return TRUE + +// Tells the turf that it currently contains something that automated movement should consider if planning to enter the tile. +// This uses lazy list macros to reduce memory footprint, since for 99% of turfs the list would've been empty anyways. +/turf/proc/register_dangerous_object(obj/O) + if(!istype(O)) + return FALSE + LAZYADD(dangerous_objects, O) +// color = "#FF0000" + +// Similar to above, for when the dangerous object stops being dangerous/gets deleted/moved/etc. +/turf/proc/unregister_dangerous_object(obj/O) + if(!istype(O)) + return FALSE + LAZYREMOVE(dangerous_objects, O) + UNSETEMPTY(dangerous_objects) // This nulls the list var if it's empty. +// color = "#00FF00" + // This is all the way up here since its the common ancestor for things that need to get replaced with a floor when an RCD is used on them. // More specialized turfs like walls should instead override this. // The code for applying lattices/floor tiles onto lattices could also utilize something similar in the future. diff --git a/code/game/turfs/turf_changing.dm b/code/game/turfs/turf_changing.dm index decd0f2eb3..eb985d268b 100644 --- a/code/game/turfs/turf_changing.dm +++ b/code/game/turfs/turf_changing.dm @@ -28,7 +28,7 @@ if(N == /turf/space) var/turf/below = GetBelow(src) - if(istype(below) && (air_master.has_valid_zone(below) || air_master.has_valid_zone(src))) + if(istype(below) && (air_master.has_valid_zone(below) || air_master.has_valid_zone(src))) //VOREStation Edit - Polaris change breaks Tether N = /turf/simulated/open var/obj/fire/old_fire = fire @@ -38,6 +38,7 @@ var/old_lighting_overlay = lighting_overlay var/old_corners = corners var/old_outdoors = outdoors + var/old_dangerous_objects = dangerous_objects //world << "Replacing [src.type] with [N]" @@ -95,6 +96,8 @@ recalc_atom_opacity() + dangerous_objects = old_dangerous_objects + if(lighting_overlays_initialised) lighting_overlay = old_lighting_overlay affecting_lights = old_affecting_lights diff --git a/code/game/turfs/unsimulated/beach.dm b/code/game/turfs/unsimulated/beach.dm index 28cebacb8a..4638b15cab 100644 --- a/code/game/turfs/unsimulated/beach.dm +++ b/code/game/turfs/unsimulated/beach.dm @@ -37,7 +37,7 @@ icon = 'icons/turf/desert.dmi' icon_state = "desert" -/turf/simulated/floor/beach/sand/desert/initialize() +/turf/simulated/floor/beach/sand/desert/Initialize() . = ..() if(prob(5)) icon_state = "desert[rand(0,4)]" diff --git a/code/game/turfs/unsimulated/sky_vr.dm b/code/game/turfs/unsimulated/sky_vr.dm index 1db001a187..8ba1cf0cb5 100644 --- a/code/game/turfs/unsimulated/sky_vr.dm +++ b/code/game/turfs/unsimulated/sky_vr.dm @@ -12,7 +12,7 @@ var/does_skyfall = TRUE var/list/skyfall_levels -/turf/unsimulated/floor/sky/initialize() +/turf/unsimulated/floor/sky/Initialize() . = ..() if(does_skyfall && !LAZYLEN(skyfall_levels)) error("[x],[y],[z], [get_area(src)] doesn't have skyfall_levels defined! Can't skyfall!") diff --git a/code/game/verbs/advanced_who.dm b/code/game/verbs/advanced_who.dm index a452446e46..bbde65fd07 100644 --- a/code/game/verbs/advanced_who.dm +++ b/code/game/verbs/advanced_who.dm @@ -8,7 +8,7 @@ var/list/Lines = list() if(holder && (R_ADMIN & holder.rights || R_MOD & holder.rights)) - for(var/client/C in clients) + for(var/client/C in GLOB.clients) var/entry = "\t[C.key]" if(C.holder && C.holder.fakekey) entry += " (as [C.holder.fakekey])" @@ -52,7 +52,7 @@ Lines += entry else - for(var/client/C in clients) + for(var/client/C in GLOB.clients) var/entry = "\t" if(C.holder && C.holder.fakekey) entry += "[C.holder.fakekey]" diff --git a/code/game/verbs/character_directory.dm b/code/game/verbs/character_directory.dm index 3c90f09591..967715901d 100644 --- a/code/game/verbs/character_directory.dm +++ b/code/game/verbs/character_directory.dm @@ -11,7 +11,7 @@ var/html = "" var/curID = 0 - for(var/client/C in clients) + for(var/client/C in GLOB.clients) if(C.prefs && !C.prefs.show_in_directory) continue if(ishuman(C.mob)) diff --git a/code/game/verbs/ignore.dm b/code/game/verbs/ignore.dm index c154628087..ea1ad6a0b7 100644 --- a/code/game/verbs/ignore.dm +++ b/code/game/verbs/ignore.dm @@ -42,7 +42,7 @@ /client/proc/is_key_ignored(var/key_to_check) key_to_check = ckey(key_to_check) if(key_to_check in prefs.ignored_players) - if(directory[key_to_check] in admins) // This is here so this is only evaluated if someone is actually being blocked. + if(GLOB.directory[key_to_check] in admins) // This is here so this is only evaluated if someone is actually being blocked. return 0 return 1 return 0 \ No newline at end of file diff --git a/code/game/verbs/ooc.dm b/code/game/verbs/ooc.dm index 8ef0fbb012..0c6fa0fed7 100644 --- a/code/game/verbs/ooc.dm +++ b/code/game/verbs/ooc.dm @@ -57,7 +57,7 @@ if(holder.rights & R_ADMIN) ooc_style = "admin" - for(var/client/target in clients) + for(var/client/target in GLOB.clients) if(target.is_preference_enabled(/datum/client_preference/show_ooc)) if(target.is_key_ignored(key)) // If we're ignored by this person, then do nothing. continue @@ -124,7 +124,7 @@ var/list/in_range = get_mobs_and_objs_in_view_fast(T,world.view,0) var/list/m_viewers = in_range["mobs"] - var/list/receivers = list() // Clients, not mobs. + var/list/receivers = list() //Clients, not mobs. var/list/r_receivers = list() var/display_name = key diff --git a/code/game/verbs/who.dm b/code/game/verbs/who.dm index 06402a90a4..c030e25649 100644 --- a/code/game/verbs/who.dm +++ b/code/game/verbs/who.dm @@ -8,7 +8,7 @@ var/list/Lines = list() if(holder && (R_ADMIN & holder.rights || R_MOD & holder.rights)) - for(var/client/C in clients) + for(var/client/C in GLOB.clients) var/entry = "\t[C.key]" if(C.holder && C.holder.fakekey) entry += " (as [C.holder.fakekey])" @@ -51,7 +51,7 @@ entry += " (?)" Lines += entry else - for(var/client/C in clients) + for(var/client/C in GLOB.clients) if(C.holder && C.holder.fakekey) Lines += C.holder.fakekey else diff --git a/code/game/world.dm b/code/game/world.dm new file mode 100644 index 0000000000..c26242f9c9 --- /dev/null +++ b/code/game/world.dm @@ -0,0 +1,645 @@ +#define RECOMMENDED_VERSION 501 +/world/New() + world.log << "Map Loading Complete" + //logs + //VOREStation Edit Start + log_path += time2text(world.realtime, "YYYY/MM-Month/DD-Day/round-hh-mm-ss") + diary = start_log("[log_path].log") + href_logfile = start_log("[log_path]-hrefs.htm") + error_log = start_log("[log_path]-error.log") + debug_log = start_log("[log_path]-debug.log") + //VOREStation Edit End + + changelog_hash = md5('html/changelog.html') //used for telling if the changelog has changed recently + + if(byond_version < RECOMMENDED_VERSION) + world.log << "Your server's byond version does not meet the recommended requirements for this server. Please update BYOND" + + config.post_load() + + if(config && config.server_name != null && config.server_suffix && world.port > 0) + // dumb and hardcoded but I don't care~ + config.server_name += " #[(world.port % 1000) / 100]" + + // TODO - Figure out what this is. Can you assign to world.log? + // if(config && config.log_runtime) + // log = file("data/logs/runtime/[time2text(world.realtime,"YYYY-MM-DD-(hh-mm-ss)")]-runtime.log") + + GLOB.timezoneOffset = text2num(time2text(0,"hh")) * 36000 + + callHook("startup") + //Emergency Fix + load_mods() + //end-emergency fix + + src.update_status() + + . = ..() + +#if UNIT_TEST + log_unit_test("Unit Tests Enabled. This will destroy the world when testing is complete.") + log_unit_test("If you did not intend to enable this please check code/__defines/unit_testing.dm") +#endif + + // Set up roundstart seed list. + plant_controller = new() + + // This is kinda important. Set up details of what the hell things are made of. + populate_material_list() + + // Create frame types. + populate_frame_types() + + // Create floor types. + populate_flooring_types() + + // Create robolimbs for chargen. + populate_robolimb_list() + + //Must be done now, otherwise ZAS zones and lighting overlays need to be recreated. + createRandomZlevel() + + processScheduler = new + master_controller = new /datum/controller/game_controller() + + processScheduler.deferSetupFor(/datum/controller/process/ticker) + processScheduler.setup() + Master.Initialize(10, FALSE) + + spawn(1) + master_controller.setup() +#if UNIT_TEST + initialize_unit_tests() +#endif + + spawn(3000) //so we aren't adding to the round-start lag + if(config.ToRban) + ToRban_autoupdate() + +#undef RECOMMENDED_VERSION + + return + +var/world_topic_spam_protect_ip = "0.0.0.0" +var/world_topic_spam_protect_time = world.timeofday + +/world/Topic(T, addr, master, key) + log_topic("\"[T]\", from:[addr], master:[master], key:[key]") + + if (T == "ping") + var/x = 1 + for (var/client/C) + x++ + return x + + else if(T == "players") + var/n = 0 + for(var/mob/M in player_list) + if(M.client) + n++ + return n + + else if (copytext(T,1,7) == "status") + var/input[] = params2list(T) + var/list/s = list() + s["version"] = game_version + s["mode"] = master_mode + s["respawn"] = config.abandon_allowed + s["enter"] = config.enter_allowed + s["vote"] = config.allow_vote_mode + s["ai"] = config.allow_ai + s["host"] = host ? host : null + + // This is dumb, but spacestation13.com's banners break if player count isn't the 8th field of the reply, so... this has to go here. + s["players"] = 0 + s["stationtime"] = stationtime2text() + s["roundduration"] = roundduration2text() + + if(input["status"] == "2") + var/list/players = list() + var/list/admins = list() + + for(var/client/C in GLOB.clients) + if(C.holder) + if(C.holder.fakekey) + continue + admins[C.key] = C.holder.rank + players += C.key + + s["players"] = players.len + s["playerlist"] = list2params(players) + var/list/adm = get_admin_counts() + var/list/presentmins = adm["present"] + var/list/afkmins = adm["afk"] + s["admins"] = presentmins.len + afkmins.len //equivalent to the info gotten from adminwho + s["adminlist"] = list2params(admins) + else + var/n = 0 + var/admins = 0 + + for(var/client/C in GLOB.clients) + if(C.holder) + if(C.holder.fakekey) + continue //so stealthmins aren't revealed by the hub + admins++ + s["player[n]"] = C.key + n++ + + s["players"] = n + s["admins"] = admins + + return list2params(s) + + else if(T == "manifest") + var/list/positions = list() + var/list/set_names = list( + "heads" = command_positions, + "sec" = security_positions, + "eng" = engineering_positions, + "med" = medical_positions, + "sci" = science_positions, + "car" = cargo_positions, + "civ" = civilian_positions, + "bot" = nonhuman_positions + ) + + for(var/datum/data/record/t in data_core.general) + var/name = t.fields["name"] + var/rank = t.fields["rank"] + var/real_rank = make_list_rank(t.fields["real_rank"]) + + var/department = 0 + for(var/k in set_names) + if(real_rank in set_names[k]) + if(!positions[k]) + positions[k] = list() + positions[k][name] = rank + department = 1 + if(!department) + if(!positions["misc"]) + positions["misc"] = list() + positions["misc"][name] = rank + + // Synthetics don't have actual records, so we will pull them from here. + for(var/mob/living/silicon/ai/ai in mob_list) + if(!positions["bot"]) + positions["bot"] = list() + positions["bot"][ai.name] = "Artificial Intelligence" + for(var/mob/living/silicon/robot/robot in mob_list) + // No combat/syndicate cyborgs, no drones. + if(robot.module && robot.module.hide_on_manifest) + continue + if(!positions["bot"]) + positions["bot"] = list() + positions["bot"][robot.name] = "[robot.modtype] [robot.braintype]" + + for(var/k in positions) + positions[k] = list2params(positions[k]) // converts positions["heads"] = list("Bob"="Captain", "Bill"="CMO") into positions["heads"] = "Bob=Captain&Bill=CMO" + + return list2params(positions) + + else if(T == "revision") + if(revdata.revision) + return list2params(list(branch = revdata.branch, date = revdata.date, revision = revdata.revision)) + else + return "unknown" + + else if(copytext(T,1,5) == "info") + var/input[] = params2list(T) + if(input["key"] != config.comms_password) + if(world_topic_spam_protect_ip == addr && abs(world_topic_spam_protect_time - world.time) < 50) + + spawn(50) + world_topic_spam_protect_time = world.time + return "Bad Key (Throttled)" + + world_topic_spam_protect_time = world.time + world_topic_spam_protect_ip = addr + + return "Bad Key" + + var/list/search = params2list(input["info"]) + var/list/ckeysearch = list() + for(var/text in search) + ckeysearch += ckey(text) + + var/list/match = list() + + for(var/mob/M in mob_list) + var/strings = list(M.name, M.ckey) + if(M.mind) + strings += M.mind.assigned_role + strings += M.mind.special_role + for(var/text in strings) + if(ckey(text) in ckeysearch) + match[M] += 10 // an exact match is far better than a partial one + else + for(var/searchstr in search) + if(findtext(text, searchstr)) + match[M] += 1 + + var/maxstrength = 0 + for(var/mob/M in match) + maxstrength = max(match[M], maxstrength) + for(var/mob/M in match) + if(match[M] < maxstrength) + match -= M + + if(!match.len) + return "No matches" + else if(match.len == 1) + var/mob/M = match[1] + var/info = list() + info["key"] = M.key + info["name"] = M.name == M.real_name ? M.name : "[M.name] ([M.real_name])" + info["role"] = M.mind ? (M.mind.assigned_role ? M.mind.assigned_role : "No role") : "No mind" + var/turf/MT = get_turf(M) + info["loc"] = M.loc ? "[M.loc]" : "null" + info["turf"] = MT ? "[MT] @ [MT.x], [MT.y], [MT.z]" : "null" + info["area"] = MT ? "[MT.loc]" : "null" + info["antag"] = M.mind ? (M.mind.special_role ? M.mind.special_role : "Not antag") : "No mind" + info["hasbeenrev"] = M.mind ? M.mind.has_been_rev : "No mind" + info["stat"] = M.stat + info["type"] = M.type + if(istype(M, /mob/living)) + var/mob/living/L = M + info["damage"] = list2params(list( + oxy = L.getOxyLoss(), + tox = L.getToxLoss(), + fire = L.getFireLoss(), + brute = L.getBruteLoss(), + clone = L.getCloneLoss(), + brain = L.getBrainLoss() + )) + else + info["damage"] = "non-living" + info["gender"] = M.gender + return list2params(info) + else + var/list/ret = list() + for(var/mob/M in match) + ret[M.key] = M.name + return list2params(ret) + + else if(copytext(T,1,9) == "adminmsg") + /* + We got an adminmsg from IRC bot lets split the input then validate the input. + expected output: + 1. adminmsg = ckey of person the message is to + 2. msg = contents of message, parems2list requires + 3. validatationkey = the key the bot has, it should match the gameservers commspassword in it's configuration. + 4. sender = the ircnick that send the message. + */ + + + var/input[] = params2list(T) + if(input["key"] != config.comms_password) + if(world_topic_spam_protect_ip == addr && abs(world_topic_spam_protect_time - world.time) < 50) + + spawn(50) + world_topic_spam_protect_time = world.time + return "Bad Key (Throttled)" + + world_topic_spam_protect_time = world.time + world_topic_spam_protect_ip = addr + + return "Bad Key" + + var/client/C + var/req_ckey = ckey(input["adminmsg"]) + + for(var/client/K in GLOB.clients) + if(K.ckey == req_ckey) + C = K + break + if(!C) + return "No client with that name on server" + + var/rank = input["rank"] + if(!rank) + rank = "Admin" + + var/message = "IRC-[rank] PM from IRC-[input["sender"]]: [input["msg"]]" + var/amessage = "IRC-[rank] PM from IRC-[input["sender"]] to [key_name(C)] : [input["msg"]]" + + C.received_irc_pm = world.time + C.irc_admin = input["sender"] + + C << 'sound/effects/adminhelp.ogg' + C << message + + + for(var/client/A in admins) + if(A != C) + A << amessage + + return "Message Successful" + + else if(copytext(T,1,6) == "notes") + /* + We got a request for notes from the IRC Bot + expected output: + 1. notes = ckey of person the notes lookup is for + 2. validationkey = the key the bot has, it should match the gameservers commspassword in it's configuration. + */ + var/input[] = params2list(T) + if(input["key"] != config.comms_password) + if(world_topic_spam_protect_ip == addr && abs(world_topic_spam_protect_time - world.time) < 50) + + spawn(50) + world_topic_spam_protect_time = world.time + return "Bad Key (Throttled)" + + world_topic_spam_protect_time = world.time + world_topic_spam_protect_ip = addr + return "Bad Key" + + return show_player_info_irc(ckey(input["notes"])) + + else if(copytext(T,1,4) == "age") + var/input[] = params2list(T) + if(input["key"] != config.comms_password) + if(world_topic_spam_protect_ip == addr && abs(world_topic_spam_protect_time - world.time) < 50) + spawn(50) + world_topic_spam_protect_time = world.time + return "Bad Key (Throttled)" + + world_topic_spam_protect_time = world.time + world_topic_spam_protect_ip = addr + return "Bad Key" + + var/age = get_player_age(input["age"]) + if(isnum(age)) + if(age >= 0) + return "[age]" + else + return "Ckey not found" + else + return "Database connection failed or not set up" + + +/world/Reboot(reason = 0, fast_track = FALSE) + /*spawn(0) + world << sound(pick('sound/AI/newroundsexy.ogg','sound/misc/apcdestroyed.ogg','sound/misc/bangindonk.ogg')) // random end sounds!! - LastyBatsy + */ + + if (reason || fast_track) //special reboot, do none of the normal stuff + if (usr) + log_admin("[key_name(usr)] Has requested an immediate world restart via client side debugging tools") + message_admins("[key_name_admin(usr)] Has requested an immediate world restart via client side debugging tools") + world << "[key_name_admin(usr)] has requested an immediate world restart via client side debugging tools" + + else + world << "Rebooting world immediately due to host request" + else + processScheduler.stop() + Master.Shutdown() //run SS shutdowns + for(var/client/C in GLOB.clients) + if(config.server) //if you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite + C << link("byond://[config.server]") + + log_world("World rebooted at [time_stamp()]") + ..() + +/hook/startup/proc/loadMode() + world.load_mode() + return 1 + +/world/proc/load_mode() + if(!fexists("data/mode.txt")) + return + + + var/list/Lines = file2list("data/mode.txt") + if(Lines.len) + if(Lines[1]) + master_mode = Lines[1] + log_misc("Saved mode is '[master_mode]'") + +/world/proc/save_mode(var/the_mode) + var/F = file("data/mode.txt") + fdel(F) + F << the_mode + + +/hook/startup/proc/loadMOTD() + world.load_motd() + return 1 + +/world/proc/load_motd() + join_motd = file2text("config/motd.txt") + + +/proc/load_configuration() + config = new /datum/configuration() + config.load("config/config.txt") + config.load("config/game_options.txt","game_options") + config.loadsql("config/dbconfig.txt") + config.loadforumsql("config/forumdbconfig.txt") + +/hook/startup/proc/loadMods() + world.load_mods() + world.load_mentors() // no need to write another hook. + return 1 + +/world/proc/load_mods() + if(config.admin_legacy_system) + var/text = file2text("config/moderators.txt") + if (!text) + error("Failed to load config/mods.txt") + else + var/list/lines = splittext(text, "\n") + for(var/line in lines) + if (!line) + continue + + if (copytext(line, 1, 2) == ";") + continue + + var/title = "Moderator" + var/rights = admin_ranks[title] + + var/ckey = copytext(line, 1, length(line)+1) + var/datum/admins/D = new /datum/admins(title, rights, ckey) + D.associate(GLOB.directory[ckey]) + +/world/proc/load_mentors() + if(config.admin_legacy_system) + var/text = file2text("config/mentors.txt") + if (!text) + error("Failed to load config/mentors.txt") + else + var/list/lines = splittext(text, "\n") + for(var/line in lines) + if (!line) + continue + if (copytext(line, 1, 2) == ";") + continue + + var/title = "Mentor" + var/rights = admin_ranks[title] + + var/ckey = copytext(line, 1, length(line)+1) + var/datum/admins/D = new /datum/admins(title, rights, ckey) + D.associate(GLOB.directory[ckey]) + +/world/proc/update_status() + var/s = "" + + if (config && config.server_name) + s += "[config.server_name] — " + + s += "[station_name()]"; + s += " (" + s += "" //Change this to wherever you want the hub to link to. +// s += "[game_version]" + s += "Default" //Replace this with something else. Or ever better, delete it and uncomment the game version. + s += "" + s += ")" + + var/list/features = list() + + if(ticker) + if(master_mode) + features += master_mode + else + features += "STARTING" + + if (!config.enter_allowed) + features += "closed" + + features += config.abandon_allowed ? "respawn" : "no respawn" + + if (config && config.allow_vote_mode) + features += "vote" + + if (config && config.allow_ai) + features += "AI allowed" + + var/n = 0 + for (var/mob/M in player_list) + if (M.client) + n++ + + if (n > 1) + features += "~[n] players" + else if (n > 0) + features += "~[n] player" + + + if (config && config.hostedby) + features += "hosted by [config.hostedby]" + + if (features) + s += ": [jointext(features, ", ")]" + + /* does this help? I do not know */ + if (src.status != s) + src.status = s + +#define FAILED_DB_CONNECTION_CUTOFF 5 +var/failed_db_connections = 0 +var/failed_old_db_connections = 0 + +/hook/startup/proc/connectDB() + if(!config.sql_enabled) + world.log << "SQL connection disabled in config." + else if(!setup_database_connection()) + world.log << "Your server failed to establish a connection with the feedback database." + else + world.log << "Feedback database connection established." + return 1 + +proc/setup_database_connection() + + if(failed_db_connections > FAILED_DB_CONNECTION_CUTOFF) //If it failed to establish a connection more than 5 times in a row, don't bother attempting to conenct anymore. + return 0 + + if(!dbcon) + dbcon = new() + + var/user = sqlfdbklogin + var/pass = sqlfdbkpass + var/db = sqlfdbkdb + var/address = sqladdress + var/port = sqlport + + dbcon.Connect("dbi:mysql:[db]:[address]:[port]","[user]","[pass]") + . = dbcon.IsConnected() + if ( . ) + failed_db_connections = 0 //If this connection succeeded, reset the failed connections counter. + else + failed_db_connections++ //If it failed, increase the failed connections counter. + world.log << dbcon.ErrorMsg() + + return . + +//This proc ensures that the connection to the feedback database (global variable dbcon) is established +proc/establish_db_connection() + if(failed_db_connections > FAILED_DB_CONNECTION_CUTOFF) + return 0 + + if(!dbcon || !dbcon.IsConnected()) + return setup_database_connection() + else + return 1 + + +/hook/startup/proc/connectOldDB() + if(!config.sql_enabled) + world.log << "SQL connection disabled in config." + else if(!setup_old_database_connection()) + world.log << "Your server failed to establish a connection with the SQL database." + else + world.log << "SQL database connection established." + return 1 + +//These two procs are for the old database, while it's being phased out. See the tgstation.sql file in the SQL folder for more information. +proc/setup_old_database_connection() + + if(failed_old_db_connections > FAILED_DB_CONNECTION_CUTOFF) //If it failed to establish a connection more than 5 times in a row, don't bother attempting to conenct anymore. + return 0 + + if(!dbcon_old) + dbcon_old = new() + + var/user = sqllogin + var/pass = sqlpass + var/db = sqldb + var/address = sqladdress + var/port = sqlport + + dbcon_old.Connect("dbi:mysql:[db]:[address]:[port]","[user]","[pass]") + . = dbcon_old.IsConnected() + if ( . ) + failed_old_db_connections = 0 //If this connection succeeded, reset the failed connections counter. + else + failed_old_db_connections++ //If it failed, increase the failed connections counter. + world.log << dbcon.ErrorMsg() + + return . + +//This proc ensures that the connection to the feedback database (global variable dbcon) is established +proc/establish_old_db_connection() + if(failed_old_db_connections > FAILED_DB_CONNECTION_CUTOFF) + return 0 + + if(!dbcon_old || !dbcon_old.IsConnected()) + return setup_old_database_connection() + else + return 1 + +// Things to do when a new z-level was just made. +/world/proc/max_z_changed() + if(!istype(GLOB.players_by_zlevel, /list)) + GLOB.players_by_zlevel = new /list(world.maxz, 0) + while(GLOB.players_by_zlevel.len < world.maxz) + GLOB.players_by_zlevel.len++ + GLOB.players_by_zlevel[GLOB.players_by_zlevel.len] = list() + +// Call this to make a new blank z-level, don't modify maxz directly. +/world/proc/increment_max_z() + maxz++ + max_z_changed() + +#undef FAILED_DB_CONNECTION_CUTOFF diff --git a/code/global.dm b/code/global.dm index 0dff5cd610..ce0d041d26 100644 --- a/code/global.dm +++ b/code/global.dm @@ -8,7 +8,6 @@ var/global/datum/datacore/data_core = null var/global/list/all_areas = list() var/global/list/machines = list() // ALL Machines, wether processing or not. var/global/list/processing_machines = list() // TODO - Move into SSmachines -var/global/list/processing_objects = list() var/global/list/processing_power_items = list() // TODO - Move into SSmachines var/global/list/active_diseases = list() var/global/list/hud_icon_reference = list() @@ -91,7 +90,6 @@ var/list/reverse_dir = list( // reverse_dir[dir] = reverse of dir ) var/datum/configuration/config = null -var/datum/sun/sun = null var/list/combatlog = list() var/list/IClog = list() @@ -109,7 +107,6 @@ var/gravity_is_on = 1 var/join_motd = null -var/datum/event_manager/event_manager = new() // Event Manager, the manager for events. var/datum/game_master/game_master = new() // Game Master, an AI for choosing events. var/datum/metric/metric = new() // Metric datum, used to keep track of the round. diff --git a/code/global_init.dm b/code/global_init.dm new file mode 100644 index 0000000000..c562209183 --- /dev/null +++ b/code/global_init.dm @@ -0,0 +1,27 @@ +/* + The initialization of the game happens roughly like this: + + 1. All global variables are initialized (including the global_init instance). + 2. The map is initialized, and map objects are created. + 3. world/New() runs, creating the process scheduler (and the old master controller) and spawning their setup. + 4. processScheduler/setup() runs, creating all the processes. game_controller/setup() runs, calling initialize() on all movable atoms in the world. + 5. The gameticker is created. + +*/ +var/global/datum/global_init/init = new () + +/* + Pre-map initialization stuff should go here. +*/ +/datum/global_init/New() + + makeDatumRefLists() + load_configuration() + + initialize_integrated_circuits_list() + + qdel(src) //we're done + +/datum/global_init/Destroy() + global.init = null + return 2 // QDEL_HINT_IWILLGC diff --git a/code/modules/admin/DB ban/functions.dm b/code/modules/admin/DB ban/functions.dm index e4d2298ace..d9e1efc972 100644 --- a/code/modules/admin/DB ban/functions.dm +++ b/code/modules/admin/DB ban/functions.dm @@ -64,7 +64,7 @@ datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration = a_ip = src.owner:address var/who - for(var/client/C in clients) + for(var/client/C in GLOB.clients) if(!who) who = "[C]" else diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index b20ea437e7..8daa899692 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -239,7 +239,7 @@ proc/admin_notice(var/message, var/rights) // Display the notes on the current page var/number_pages = note_keys.len / PLAYER_NOTES_ENTRIES_PER_PAGE - // Emulate ceil(why does BYOND not have ceil) + // Emulate CEILING(why does BYOND not have ceil, 1) if(number_pages != round(number_pages)) number_pages = round(number_pages) + 1 var/page_index = page - 1 @@ -286,7 +286,7 @@ proc/admin_notice(var/message, var/rights) dat += "" var/p_age = "unknown" - for(var/client/C in clients) + for(var/client/C in GLOB.clients) if(C.ckey == key) p_age = C.player_age break @@ -730,28 +730,28 @@ var/datum/announcement/minor/admin_min_announcer = new //Split on pipe or \n decomposed = splittext(message,regex("\\||$","m")) decomposed += "0" //Tack on a final 0 sleep to make 3-per-message evenly - + //Time to find how they screwed up. //Wasn't the right length if((decomposed.len) % 3) //+1 to accomidate the lack of a wait time for the last message to_chat(usr,"You passed [decomposed.len] segments (senders+messages+pauses). You must pass a multiple of 3, minus 1 (no pause after the last message). That means a sender and message on every other line (starting on the first), separated by a pipe character (|), and a number every other line that is a pause in seconds.") return - + //Too long a conversation if((decomposed.len / 3) > 20) to_chat(usr,"This conversation is too long! 20 messages maximum, please.") return - + //Missed some sleeps, or sanitized to nothing. for(var/i = 1; i < decomposed.len; i++) - + //Sanitize sender var/clean_sender = sanitize(decomposed[i]) if(!clean_sender) to_chat(usr,"One part of your conversation was not able to be sanitized. It was the sender of the [(i+2)/3]\th message.") return decomposed[i] = clean_sender - + //Sanitize message var/clean_message = sanitize(decomposed[++i]) if(!clean_message) diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm index 772c1886a8..52b9ddcedd 100644 --- a/code/modules/admin/admin_ranks.dm +++ b/code/modules/admin/admin_ranks.dm @@ -100,7 +100,7 @@ var/list/admin_ranks = list() //list of all ranks with associated rights var/datum/admins/D = new /datum/admins(rank, rights, ckey) //find the client for a ckey if they are connected and associate them with the new admin datum - D.associate(directory[ckey]) + D.associate(GLOB.directory[ckey]) else //The current admin system uses SQL @@ -125,7 +125,7 @@ var/list/admin_ranks = list() //list of all ranks with associated rights var/datum/admins/D = new /datum/admins(rank, rights, ckey) //find the client for a ckey if they are connected and associate them with the new admin datum - D.associate(directory[ckey]) + D.associate(GLOB.directory[ckey]) if(!admin_datums) error("The database query in load_admins() resulted in no admins being added to the list. Reverting to legacy system.") log_misc("The database query in load_admins() resulted in no admins being added to the list. Reverting to legacy system.") diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 2d66bd653f..c57b0ff80a 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -6,6 +6,7 @@ var/list/admin_verbs_default = list( /client/proc/hide_verbs, //hides all our adminverbs, /client/proc/hide_most_verbs, //hides all our hideable adminverbs, /client/proc/debug_variables, //allows us to -see- the variables of any instance in the game. +VAREDIT needed to modify, + /client/proc/mark_datum_mapview, /client/proc/cmd_check_new_players, //allows us to see every new player // /client/proc/check_antagonists, //shows all antags, // /client/proc/cmd_mod_say, @@ -214,9 +215,8 @@ var/list/admin_verbs_debug = list( /client/proc/show_plant_genes, /client/proc/enable_debug_verbs, /client/proc/callproc, - /client/proc/callproc_target, - /client/proc/debug_process, - /client/proc/SDQL_query, + /client/proc/callproc_datum, + /client/proc/debug_process, //VOREStation Add, /client/proc/SDQL2_query, /client/proc/Jump, /client/proc/debug_rogueminer, @@ -235,8 +235,8 @@ var/list/admin_verbs_debug = list( var/list/admin_verbs_paranoid_debug = list( /client/proc/callproc, - /client/proc/callproc_target, - /client/proc/debug_process, + /client/proc/callproc_datum, + /client/proc/debug_process, //VOREStation Add, /client/proc/debug_controller ) @@ -304,8 +304,8 @@ var/list/admin_verbs_hideable = list( /client/proc/restart_controller, /client/proc/cmd_admin_list_open_jobs, /client/proc/callproc, - /client/proc/callproc_target, - /client/proc/debug_process, + /client/proc/callproc_datum, + /client/proc/debug_process, //VOREStation Add, /client/proc/Debug2, /client/proc/reload_admins, /client/proc/kill_air, @@ -373,7 +373,7 @@ var/list/admin_verbs_event_manager = list( /proc/possess, /proc/release, /client/proc/callproc, - /client/proc/callproc_target, + /client/proc/callproc_datum, /client/proc/debug_controller, /client/proc/show_gm_status, /datum/admins/proc/change_weather, @@ -645,7 +645,7 @@ var/list/admin_verbs_event_manager = list( return var/datum/preferences/D - var/client/C = directory[warned_ckey] + var/client/C = GLOB.directory[warned_ckey] if(C) D = C.prefs else D = preferences_datums[warned_ckey] diff --git a/code/modules/admin/callproc/callproc.dm b/code/modules/admin/callproc/callproc.dm index 36fc9a8f9c..f72606d27b 100644 --- a/code/modules/admin/callproc/callproc.dm +++ b/code/modules/admin/callproc/callproc.dm @@ -1,210 +1,210 @@ -/client/proc/callproc() - set category = "Debug" - set name = "Advanced ProcCall" - set waitfor = 0 - - if(!check_rights(R_DEBUG)) - return - - var/datum/target = null - var/targetselected = 0 - var/returnval = null - - switch(alert("Proc owned by something?",,"Yes","No")) - if("Yes") - targetselected = 1 - var/list/value = vv_get_value(default_class = VV_ATOM_REFERENCE, classes = list(VV_ATOM_REFERENCE, VV_DATUM_REFERENCE, VV_MOB_REFERENCE, VV_CLIENT)) - if (!value["class"] || !value["value"]) - return - target = value["value"] - if("No") - target = null - targetselected = 0 - - var/procname = input("Proc path, eg: /proc/fake_blood","Path:", null) as text|null - if(!procname) - return - - //hascall() doesn't support proc paths (eg: /proc/gib(), it only supports "gib") - var/testname = procname - if(targetselected) - //Find one of the 3 possible ways they could have written /proc/PROCNAME - if(findtext(procname, "/proc/")) - testname = replacetext(procname, "/proc/", "") - else if(findtext(procname, "/proc")) - testname = replacetext(procname, "/proc", "") - else if(findtext(procname, "proc/")) - testname = replacetext(procname, "proc/", "") - //Clear out any parenthesis if they're a dummy - testname = replacetext(testname, "()", "") - - if(targetselected && !hascall(target,testname)) - to_chat(usr, "Error: callproc(): type [target.type] has no proc named [procname].") - return - else - var/procpath = text2path(procname) - if (!procpath) - to_chat(usr, "Error: callproc(): proc [procname] does not exist. (Did you forget the /proc/ part?)") - return - var/list/lst = get_callproc_args() - if(!lst) - return - - if(targetselected) - if(!target) - to_chat(usr, "Error: callproc(): owner of proc no longer exists.") - return - var/msg = "[key_name(src)] called [target]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"]." - log_admin(msg) - //message_admins(msg) //Proccall announce removed. - admin_ticket_log(target, msg) - returnval = WrapAdminProcCall(target, procname, lst) // Pass the lst as an argument list to the proc - else - //this currently has no hascall protection. wasn't able to get it working. - log_admin("[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].") - //message_admins("[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].") //Proccall announce removed. - returnval = WrapAdminProcCall(GLOBAL_PROC, procname, lst) // Pass the lst as an argument list to the proc - . = get_callproc_returnval(returnval, procname) - if(.) - to_chat(usr, .) - feedback_add_details("admin_verb","APC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -GLOBAL_VAR(AdminProcCaller) -GLOBAL_PROTECT(AdminProcCaller) -GLOBAL_VAR_INIT(AdminProcCallCount, 0) -GLOBAL_PROTECT(AdminProcCallCount) -GLOBAL_VAR(LastAdminCalledTargetRef) -GLOBAL_PROTECT(LastAdminCalledTargetRef) -GLOBAL_VAR(LastAdminCalledTarget) -GLOBAL_PROTECT(LastAdminCalledTarget) -GLOBAL_VAR(LastAdminCalledProc) -GLOBAL_PROTECT(LastAdminCalledProc) -GLOBAL_LIST_EMPTY(AdminProcCallSpamPrevention) -GLOBAL_PROTECT(AdminProcCallSpamPrevention) - -/proc/WrapAdminProcCall(datum/target, procname, list/arguments) - if(target && procname == "Del") - to_chat(usr, "Calling Del() is not allowed") - return - - if(target != GLOBAL_PROC && !target.CanProcCall(procname)) - to_chat(usr, "Proccall on [target.type]/proc/[procname] is disallowed!") - return - var/current_caller = GLOB.AdminProcCaller - var/ckey = usr ? usr.client.ckey : GLOB.AdminProcCaller - if(!ckey) - CRASH("WrapAdminProcCall with no ckey: [target] [procname] [english_list(arguments)]") - if(current_caller && current_caller != ckey) - if(!GLOB.AdminProcCallSpamPrevention[ckey]) - to_chat(usr, "Another set of admin called procs are still running, your proc will be run after theirs finish.") - GLOB.AdminProcCallSpamPrevention[ckey] = TRUE - UNTIL(!GLOB.AdminProcCaller) - to_chat(usr, "Running your proc") - GLOB.AdminProcCallSpamPrevention -= ckey - else - UNTIL(!GLOB.AdminProcCaller) - GLOB.LastAdminCalledProc = procname - if(target != GLOBAL_PROC) - GLOB.LastAdminCalledTargetRef = "\ref[target]" - GLOB.AdminProcCaller = ckey //if this runtimes, too bad for you - ++GLOB.AdminProcCallCount - . = world.WrapAdminProcCall(target, procname, arguments) - if(--GLOB.AdminProcCallCount == 0) - GLOB.AdminProcCaller = null - -//adv proc call this, ya nerds -/world/proc/WrapAdminProcCall(datum/target, procname, list/arguments) - if(target == GLOBAL_PROC) - return call(procname)(arglist(arguments)) - else if(target != world) - return call(target, procname)(arglist(arguments)) - else - log_admin("[key_name(usr)] attempted to call world/proc/[procname] with arguments: [english_list(arguments)]") - -/proc/IsAdminAdvancedProcCall() -#ifdef TESTING - return FALSE -#else - return usr && usr.client && GLOB.AdminProcCaller == usr.client.ckey -#endif - -/client/proc/callproc_datum(datum/A as null|area|mob|obj|turf) - set category = "Debug" - set name = "Atom ProcCall" - set waitfor = 0 - - if(!check_rights(R_DEBUG)) - return - - var/procname = input("Proc name, eg: fake_blood","Proc:", null) as text|null - if(!procname) - return - if(!hascall(A,procname)) - to_chat(usr, "Error: callproc_datum(): type [A.type] has no proc named [procname].") - return - var/list/lst = get_callproc_args() - if(!lst) - return - - if(!A || !IsValidSrc(A)) - to_chat(usr, "Error: callproc_datum(): owner of proc no longer exists.") - return - var/msg = "[key_name(src)] called [A]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"]." - log_admin(msg) - //message_admins(msg) - admin_ticket_log(A, msg) - feedback_add_details("admin_verb","TPC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - - var/returnval = WrapAdminProcCall(A, procname, lst) // Pass the lst as an argument list to the proc - . = get_callproc_returnval(returnval,procname) - if(.) - to_chat(usr, .) - -/client/proc/get_callproc_args() - var/argnum = input("Number of arguments","Number:",0) as num|null - if(isnull(argnum)) - return null //Cancel - - . = list() - //var/list/named_args = list() //Named arguments are removed, due to them making proccalling take too long. - while(argnum--) - /* //Named arguments are removed, due to them making proccalling take too long. - var/named_arg = input("Leave blank for positional argument. Positional arguments will be considered as if they were added first.", "Named argument") as text|null - if(isnull(named_arg)) - return null //Cancel - */ - var/value = vv_get_value(restricted_classes = list(VV_RESTORE_DEFAULT)) - if (!value["class"]) - return null //Cancel - /* //Named arguments are removed, due to them making proccalling take too long. - if(named_arg) - named_args[named_arg] = value["value"] - else - . += value["value"] - if(LAZYLEN(named_args)) - . += named_args - */ - . += value["value"] - -/client/proc/get_callproc_returnval(returnval,procname) - . = "" - if(islist(returnval)) - var/list/returnedlist = returnval - . = "" - if(returnedlist.len) - var/assoc_check = returnedlist[1] - if(istext(assoc_check) && (returnedlist[assoc_check] != null)) - . += "[procname] returned an associative list:" - for(var/key in returnedlist) - . += "\n[key] = [returnedlist[key]]" - - else - . += "[procname] returned a list:" - for(var/elem in returnedlist) - . += "\n[elem]" - else - . = "[procname] returned an empty list" - . += "" - - else - . = "[procname] returned: [!isnull(returnval) ? returnval : "null"]" +/client/proc/callproc() + set category = "Debug" + set name = "Advanced ProcCall" + set waitfor = 0 + + if(!check_rights(R_DEBUG)) + return + + var/datum/target = null + var/targetselected = 0 + var/returnval = null + + switch(alert("Proc owned by something?",,"Yes","No")) + if("Yes") + targetselected = 1 + var/list/value = vv_get_value(default_class = VV_ATOM_REFERENCE, classes = list(VV_ATOM_REFERENCE, VV_DATUM_REFERENCE, VV_MOB_REFERENCE, VV_CLIENT)) + if (!value["class"] || !value["value"]) + return + target = value["value"] + if("No") + target = null + targetselected = 0 + + var/procname = input("Proc path, eg: /proc/fake_blood","Path:", null) as text|null + if(!procname) + return + + //hascall() doesn't support proc paths (eg: /proc/gib(), it only supports "gib") + var/testname = procname + if(targetselected) + //Find one of the 3 possible ways they could have written /proc/PROCNAME + if(findtext(procname, "/proc/")) + testname = replacetext(procname, "/proc/", "") + else if(findtext(procname, "/proc")) + testname = replacetext(procname, "/proc", "") + else if(findtext(procname, "proc/")) + testname = replacetext(procname, "proc/", "") + //Clear out any parenthesis if they're a dummy + testname = replacetext(testname, "()", "") + + if(targetselected && !hascall(target,testname)) + to_chat(usr, "Error: callproc(): type [target.type] has no proc named [procname].") + return + else + var/procpath = text2path(procname) + if (!procpath) + to_chat(usr, "Error: callproc(): proc [procname] does not exist. (Did you forget the /proc/ part?)") + return + var/list/lst = get_callproc_args() + if(!lst) + return + + if(targetselected) + if(!target) + to_chat(usr, "Error: callproc(): owner of proc no longer exists.") + return + var/msg = "[key_name(src)] called [target]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"]." + log_admin(msg) + //message_admins(msg) //Proccall announce removed. + admin_ticket_log(target, msg) + returnval = WrapAdminProcCall(target, procname, lst) // Pass the lst as an argument list to the proc + else + //this currently has no hascall protection. wasn't able to get it working. + log_admin("[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].") + //message_admins("[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].") //Proccall announce removed. + returnval = WrapAdminProcCall(GLOBAL_PROC, procname, lst) // Pass the lst as an argument list to the proc + . = get_callproc_returnval(returnval, procname) + if(.) + to_chat(usr, .) + feedback_add_details("admin_verb","APC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +GLOBAL_VAR(AdminProcCaller) +GLOBAL_PROTECT(AdminProcCaller) +GLOBAL_VAR_INIT(AdminProcCallCount, 0) +GLOBAL_PROTECT(AdminProcCallCount) +GLOBAL_VAR(LastAdminCalledTargetRef) +GLOBAL_PROTECT(LastAdminCalledTargetRef) +GLOBAL_VAR(LastAdminCalledTarget) +GLOBAL_PROTECT(LastAdminCalledTarget) +GLOBAL_VAR(LastAdminCalledProc) +GLOBAL_PROTECT(LastAdminCalledProc) +GLOBAL_LIST_EMPTY(AdminProcCallSpamPrevention) +GLOBAL_PROTECT(AdminProcCallSpamPrevention) + +/proc/WrapAdminProcCall(datum/target, procname, list/arguments) + if(target && procname == "Del") + to_chat(usr, "Calling Del() is not allowed") + return + + if(target != GLOBAL_PROC && !target.CanProcCall(procname)) + to_chat(usr, "Proccall on [target.type]/proc/[procname] is disallowed!") + return + var/current_caller = GLOB.AdminProcCaller + var/ckey = usr ? usr.client.ckey : GLOB.AdminProcCaller + if(!ckey) + CRASH("WrapAdminProcCall with no ckey: [target] [procname] [english_list(arguments)]") + if(current_caller && current_caller != ckey) + if(!GLOB.AdminProcCallSpamPrevention[ckey]) + to_chat(usr, "Another set of admin called procs are still running, your proc will be run after theirs finish.") + GLOB.AdminProcCallSpamPrevention[ckey] = TRUE + UNTIL(!GLOB.AdminProcCaller) + to_chat(usr, "Running your proc") + GLOB.AdminProcCallSpamPrevention -= ckey + else + UNTIL(!GLOB.AdminProcCaller) + GLOB.LastAdminCalledProc = procname + if(target != GLOBAL_PROC) + GLOB.LastAdminCalledTargetRef = "\ref[target]" + GLOB.AdminProcCaller = ckey //if this runtimes, too bad for you + ++GLOB.AdminProcCallCount + . = world.WrapAdminProcCall(target, procname, arguments) + if(--GLOB.AdminProcCallCount == 0) + GLOB.AdminProcCaller = null + +//adv proc call this, ya nerds +/world/proc/WrapAdminProcCall(datum/target, procname, list/arguments) + if(target == GLOBAL_PROC) + return call(procname)(arglist(arguments)) + else if(target != world) + return call(target, procname)(arglist(arguments)) + else + log_admin("[key_name(usr)] attempted to call world/proc/[procname] with arguments: [english_list(arguments)]") + +/proc/IsAdminAdvancedProcCall() +#ifdef TESTING + return FALSE +#else + return usr && usr.client && GLOB.AdminProcCaller == usr.client.ckey +#endif + +/client/proc/callproc_datum(datum/A as null|area|mob|obj|turf) + set category = "Debug" + set name = "Atom ProcCall" + set waitfor = 0 + + if(!check_rights(R_DEBUG)) + return + + var/procname = input("Proc name, eg: fake_blood","Proc:", null) as text|null + if(!procname) + return + if(!hascall(A,procname)) + to_chat(usr, "Error: callproc_datum(): type [A.type] has no proc named [procname].") + return + var/list/lst = get_callproc_args() + if(!lst) + return + + if(!A || !IsValidSrc(A)) + to_chat(usr, "Error: callproc_datum(): owner of proc no longer exists.") + return + var/msg = "[key_name(src)] called [A]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"]." + log_admin(msg) + //message_admins(msg) + admin_ticket_log(A, msg) + feedback_add_details("admin_verb","TPC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + + var/returnval = WrapAdminProcCall(A, procname, lst) // Pass the lst as an argument list to the proc + . = get_callproc_returnval(returnval,procname) + if(.) + to_chat(usr, .) + +/client/proc/get_callproc_args() + var/argnum = input("Number of arguments","Number:",0) as num|null + if(isnull(argnum)) + return null //Cancel + + . = list() + //var/list/named_args = list() //Named arguments are removed, due to them making proccalling take too long. + while(argnum--) + /* //Named arguments are removed, due to them making proccalling take too long. + var/named_arg = input("Leave blank for positional argument. Positional arguments will be considered as if they were added first.", "Named argument") as text|null + if(isnull(named_arg)) + return null //Cancel + */ + var/value = vv_get_value(restricted_classes = list(VV_RESTORE_DEFAULT)) + if (!value["class"]) + return null //Cancel + /* //Named arguments are removed, due to them making proccalling take too long. + if(named_arg) + named_args[named_arg] = value["value"] + else + . += value["value"] + if(LAZYLEN(named_args)) + . += named_args + */ + . += value["value"] + +/client/proc/get_callproc_returnval(returnval,procname) + . = "" + if(islist(returnval)) + var/list/returnedlist = returnval + . = "" + if(returnedlist.len) + var/assoc_check = returnedlist[1] + if(istext(assoc_check) && (returnedlist[assoc_check] != null)) + . += "[procname] returned an associative list:" + for(var/key in returnedlist) + . += "\n[key] = [returnedlist[key]]" + + else + . += "[procname] returned a list:" + for(var/elem in returnedlist) + . += "\n[elem]" + else + . = "[procname] returned an empty list" + . += "" + + else + . = "[procname] returned: [!isnull(returnval) ? returnval : "null"]" diff --git a/code/modules/admin/holder2.dm b/code/modules/admin/holder2.dm index 2d74b43433..114808d3d3 100644 --- a/code/modules/admin/holder2.dm +++ b/code/modules/admin/holder2.dm @@ -47,6 +47,12 @@ var/list/admin_datums = list() owner.deadmin_holder = null owner.add_admin_verbs() +/datum/admins/vv_edit_var(var_name, var_value) + if(var_name == NAMEOF(src, rights) || var_name == NAMEOF(src, owner) || var_name == NAMEOF(src, rank)) + return FALSE + return ..() + +//TODO: Proccall guard, when all try/catch are removed and WrapAdminProccall is ported. /* checks if usr is an admin with at least ONE of the flags in rights_required. (Note, they don't need all the flags) @@ -95,7 +101,18 @@ NOTE: It checks usr by default. Supply the "user" argument if you wish to check usr << "Error: Cannot proceed. They have more or equal rights to us." return 0 +/client/proc/mark_datum(datum/D) + if(!holder) + return + if(holder.marked_datum) + vv_update_display(holder.marked_datum, "marked", "") + holder.marked_datum = D + vv_update_display(D, "marked", VV_MSG_MARKED) +/client/proc/mark_datum_mapview(datum/D as mob|obj|turf|area in view(view)) + set category = "Debug" + set name = "Mark Object" + mark_datum(D) /client/proc/deadmin() if(holder) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 4b0a1122e9..0fdccdc534 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -175,7 +175,7 @@ else D = new /datum/admins(new_rank, rights, adm_ckey) - var/client/C = directory[adm_ckey] //find the client with the specified ckey (if they are logged in) + var/client/C = GLOB.directory[adm_ckey] //find the client with the specified ckey (if they are logged in) D.associate(C) //link up with the client and add verbs message_admins("[key_name_admin(usr)] edited the admin rank of [adm_ckey] to [new_rank]") @@ -280,21 +280,21 @@ if("larva") M.change_mob_type( /mob/living/carbon/alien/larva , null, null, delmob ) if("nymph") M.change_mob_type( /mob/living/carbon/alien/diona , null, null, delmob ) if("human") M.change_mob_type( /mob/living/carbon/human , null, null, delmob, href_list["species"]) - if("slime") M.change_mob_type( /mob/living/simple_animal/slime , null, null, delmob ) + if("slime") M.change_mob_type( /mob/living/simple_mob/slime/xenobio , null, null, delmob ) if("monkey") M.change_mob_type( /mob/living/carbon/human/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/fluff/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("cat") M.change_mob_type( /mob/living/simple_mob/animal/passive/cat , null, null, delmob ) + if("runtime") M.change_mob_type( /mob/living/simple_mob/animal/passive/cat/runtime , null, null, delmob ) + if("corgi") M.change_mob_type( /mob/living/simple_mob/animal/passive/dog/corgi , null, null, delmob ) + if("ian") M.change_mob_type( /mob/living/simple_mob/animal/passive/dog/corgi/Ian , null, null, delmob ) + if("crab") M.change_mob_type( /mob/living/simple_mob/animal/passive/crab , null, null, delmob ) + if("coffee") M.change_mob_type( /mob/living/simple_mob/animal/passive/crab/Coffee , null, null, delmob ) + if("parrot") M.change_mob_type( /mob/living/simple_mob/animal/passive/bird/parrot , null, null, delmob ) + if("polyparrot") M.change_mob_type( /mob/living/simple_mob/animal/passive/bird/parrot/poly , null, null, delmob ) + if("constructarmoured") M.change_mob_type( /mob/living/simple_mob/construct/juggernaut , null, null, delmob ) + if("constructbuilder") M.change_mob_type( /mob/living/simple_mob/construct/artificer , null, null, delmob ) + if("constructwraith") M.change_mob_type( /mob/living/simple_mob/construct/wraith , null, null, delmob ) + if("shade") M.change_mob_type( /mob/living/simple_mob/construct/shade , null, null, delmob ) /////////////////////////////////////new ban stuff diff --git a/code/modules/admin/verbs/SDQL.dm b/code/modules/admin/verbs/SDQL.dm deleted file mode 100644 index 969e5cd47c..0000000000 --- a/code/modules/admin/verbs/SDQL.dm +++ /dev/null @@ -1,497 +0,0 @@ - -//Structured Datum Query Language. Basically SQL meets BYOND objects. - -//Note: For use in BS12, need text_starts_with proc, and to modify the action on select to use BS12's object edit command(s). - -/client/proc/SDQL_query(query_text as message) - set category = "Admin" - if(!check_rights(R_DEBUG)) //Shouldn't happen... but just to be safe. - message_admins("ERROR: Non-admin [usr.key] attempted to execute a SDQL query!") - log_admin("Non-admin [usr.key] attempted to execute a SDQL query!") - - var/list/query_list = SDQL_tokenize(query_text) - - if(query_list.len < 2) - if(query_list.len > 0) - usr << "SDQL: Too few discrete tokens in query \"[query_text]\". Please check your syntax and try again." - return - - if(!(lowertext(query_list[1]) in list("select", "delete", "update"))) - usr << "SDQL: Unknown query type: \"[query_list[1]]\" in query \"[query_text]\". Please check your syntax and try again." - return - - var/list/types = list() - - var/i - for(i = 2; i <= query_list.len; i += 2) - types += query_list[i] - - if(i + 1 >= query_list.len || query_list[i + 1] != ",") - break - - i++ - - var/list/from = list() - - if(i <= query_list.len) - if(lowertext(query_list[i]) in list("from", "in")) - for(i++; i <= query_list.len; i += 2) - from += query_list[i] - - if(i + 1 >= query_list.len || query_list[i + 1] != ",") - break - - i++ - - if(from.len < 1) - from += "world" - - var/list/set_vars = list() - - if(lowertext(query_list[1]) == "update") - if(i <= query_list.len && lowertext(query_list[i]) == "set") - for(i++; i <= query_list.len; i++) - if(i + 2 <= query_list.len && query_list[i + 1] == "=") - set_vars += query_list[i] - set_vars[query_list[i]] = query_list[i + 2] - - else - usr << "SDQL: Invalid set parameter in query \"[query_text]\". Please check your syntax and try again." - return - - i += 3 - - if(i >= query_list.len || query_list[i] != ",") - break - - if(set_vars.len < 1) - usr << "SDQL: Invalid or missing set in query \"[query_text]\". Please check your syntax and try again." - return - - var/list/where = list() - - if(i <= query_list.len && lowertext(query_list[i]) == "where") - where = query_list.Copy(i + 1) - - var/list/from_objs = list() - if("world" in from) - from_objs += world - else - for(var/f in from) - if(copytext(f, 1, 2) == "'" || copytext(f, 1, 2) == "\"") - from_objs += locate(copytext(f, 2, length(f))) - else if(copytext(f, 1, 2) != "/") - from_objs += locate(f) - else - var/f2 = text2path(f) - if(text_starts_with(f, "/mob")) - for(var/mob/m in mob_list) - if(istype(m, f2)) - from_objs += m - - else if(text_starts_with(f, "/turf/space")) - for(var/turf/space/m in turfs) - if(istype(m, f2)) - from_objs += m - - else if(text_starts_with(f, "/turf/simulated")) - for(var/turf/simulated/m in turfs) - if(istype(m, f2)) - from_objs += m - - else if(text_starts_with(f, "/turf/unsimulated")) - for(var/turf/unsimulated/m in turfs) - if(istype(m, f2)) - from_objs += m - - else if(text_starts_with(f, "/turf")) - for(var/turf/m in turfs) - if(istype(m, f2)) - from_objs += m - - else if(text_starts_with(f, "/area")) - for(var/area/m in all_areas) - if(istype(m, f2)) - from_objs += m - - else if(text_starts_with(f, "/obj/item")) - for(var/obj/item/m in world) - if(istype(m, f2)) - from_objs += m - - else if(text_starts_with(f, "/obj/machinery")) - for(var/obj/machinery/m in machines) - if(istype(m, f2)) - from_objs += m - - else if(text_starts_with(f, "/obj")) - for(var/obj/m in world) - if(istype(m, f2)) - from_objs += m - - else if(text_starts_with(f, "/atom")) - for(var/atom/m in world) - if(istype(m, f2)) - from_objs += m -/* - else - for(var/datum/m in nope) - if(istype(m, f2)) - from_objs += m -*/ - - var/list/objs = list() - - for(var/from_obj in from_objs) - if("*" in types) - objs += from_obj:contents - else - for(var/f in types) - if(copytext(f, 1, 2) == "'" || copytext(f, 1, 2) == "\"") - objs += locate(copytext(f, 2, length(f))) in from_obj - else if(copytext(f, 1, 2) != "/") - objs += locate(f) in from_obj - else - var/f2 = text2path(f) - if(text_starts_with(f, "/mob")) - for(var/mob/m in from_obj) - if(istype(m, f2)) - objs += m - - else if(text_starts_with(f, "/turf/space")) - for(var/turf/space/m in from_obj) - if(istype(m, f2)) - objs += m - - else if(text_starts_with(f, "/turf/simulated")) - for(var/turf/simulated/m in from_obj) - if(istype(m, f2)) - objs += m - - else if(text_starts_with(f, "/turf/unsimulated")) - for(var/turf/unsimulated/m in from_obj) - if(istype(m, f2)) - objs += m - - else if(text_starts_with(f, "/turf")) - for(var/turf/m in from_obj) - if(istype(m, f2)) - objs += m - - else if(text_starts_with(f, "/area")) - for(var/area/m in from_obj) - if(istype(m, f2)) - objs += m - - else if(text_starts_with(f, "/obj/item")) - for(var/obj/item/m in from_obj) - if(istype(m, f2)) - objs += m - - else if(text_starts_with(f, "/obj/machinery")) - for(var/obj/machinery/m in from_obj) - if(istype(m, f2)) - objs += m - - else if(text_starts_with(f, "/obj")) - for(var/obj/m in from_obj) - if(istype(m, f2)) - objs += m - - else if(text_starts_with(f, "/atom")) - for(var/atom/m in from_obj) - if(istype(m, f2)) - objs += m - - else - for(var/datum/m in from_obj) - if(istype(m, f2)) - objs += m - - - for(var/datum/t in objs) - var/currently_false = 0 - for(i = 1, i - 1 < where.len, i++) - var/v = where[i++] - var/compare_op = where[i++] - if(!(compare_op in list("==", "=", "<>", "<", ">", "<=", ">=", "!="))) - usr << "SDQL: Unknown comparison operator [compare_op] in where clause following [v] in query \"[query_text]\". Please check your syntax and try again." - return - - var/j - for(j = i, j <= where.len, j++) - if(lowertext(where[j]) in list("and", "or", ";")) - break - - if(!currently_false) - var/value = SDQL_text2value(t, v) - var/result = SDQL_evaluate(t, where.Copy(i, j)) - - switch(compare_op) - if("=", "==") - currently_false = !(value == result) - - if("!=", "<>") - currently_false = !(value != result) - - if("<") - currently_false = !(value < result) - - if(">") - currently_false = !(value > result) - - if("<=") - currently_false = !(value <= result) - - if(">=") - currently_false = !(value >= result) - - - if(j > where.len || lowertext(where[j]) == ";") - break - else if(lowertext(where[j]) == "or") - if(currently_false) - currently_false = 0 - else - break - - i = j - - if(currently_false) - objs -= t - - - - usr << "SQDL Query: [query_text]" - message_admins("[usr] executed SDQL query: \"[query_text]\".") -/* - for(var/t in types) - usr << "Type: [t]" - - for(var/t in from) - usr << "From: [t]" - - for(var/t in set_vars) - usr << "Set: [t] = [set_vars[t]]" - - if(where.len) - var/where_str = "" - for(var/t in where) - where_str += "[t] " - - usr << "Where: [where_str]" - - usr << "From objects:" - for(var/datum/t in from_objs) - usr << t - - usr << "Objects:" - for(var/datum/t in objs) - usr << t -*/ - switch(lowertext(query_list[1])) - if("delete") - for(var/datum/t in objs) - qdel(t) - - if("update") - for(var/datum/t in objs) - objs[t] = list() - for(var/v in set_vars) - if(v in t.vars) - objs[t][v] = SDQL_text2value(t, set_vars[v]) - - for(var/datum/t in objs) - for(var/v in objs[t]) - t.vars[v] = objs[t][v] - - if("select") - var/text = "" - for(var/datum/t in objs) - if(istype(t, /atom)) - var/atom/a = t - - if(a.x) - text += "\ref[t]: [t] at ([a.x], [a.y], [a.z])
" - - else if(a.loc && a.loc.x) - text += "\ref[t]: [t] in [a.loc] at ([a.loc.x], [a.loc.y], [a.loc.z])
" - - else - text += "\ref[t]: [t]
" - - else - text += "\ref[t]: [t]
" - - //text += "[t]
" - usr << browse(text, "window=sdql_result") - - -/client/Topic(href,href_list[],hsrc) - if(href_list["SDQL_select"]) - debug_variables(locate(href_list["SDQL_select"])) - - ..() - - -/proc/SDQL_evaluate(datum/object, list/equation) - if(equation.len == 0) - return null - - else if(equation.len == 1) - return SDQL_text2value(object, equation[1]) - - else if(equation[1] == "!") - return !SDQL_evaluate(object, equation.Copy(2)) - - else if(equation[1] == "-") - return -SDQL_evaluate(object, equation.Copy(2)) - - - else - usr << "SDQL: Sorry, equations not yet supported :(" - return null - - -/proc/SDQL_text2value(datum/object, text) - if(text2num(text) != null) - return text2num(text) - else if(text == "null") - return null - else if(copytext(text, 1, 2) == "'" || copytext(text, 1, 2) == "\"" ) - return copytext(text, 2, length(text)) - else if(copytext(text, 1, 2) == "/") - return text2path(text) - else - if(findtext(text, ".")) - var/split = findtext(text, ".") - var/v = copytext(text, 1, split) - - if((v in object.vars) && istype(object.vars[v], /datum)) - return SDQL_text2value(object.vars[v], copytext(text, split + 1)) - else - return null - - else - if(text in object.vars) - return object.vars[text] - else - return null - - -/proc/text_starts_with(text, start) - if(copytext(text, 1, length(start) + 1) == start) - return 1 - else - return 0 - - - - - -/proc/SDQL_tokenize(query_text) - - var/list/whitespace = list(" ", "\n", "\t") - var/list/single = list("(", ")", ",", "+", "-") - var/list/multi = list( - "=" = list("", "="), - "<" = list("", "=", ">"), - ">" = list("", "="), - "!" = list("", "=")) - - var/word = "" - var/list/query_list = list() - var/len = length(query_text) - - for(var/i = 1, i <= len, i++) - var/char = copytext(query_text, i, i + 1) - - if(char in whitespace) - if(word != "") - query_list += word - word = "" - - else if(char in single) - if(word != "") - query_list += word - word = "" - - query_list += char - - else if(char in multi) - if(word != "") - query_list += word - word = "" - - var/char2 = copytext(query_text, i + 1, i + 2) - - if(char2 in multi[char]) - query_list += "[char][char2]" - i++ - - else - query_list += char - - else if(char == "'") - if(word != "") - usr << "SDQL: You have an error in your SDQL syntax, unexpected ' in query: \"[query_text]\" following \"[word]\". Please check your syntax, and try again." - return null - - word = "'" - - for(i++, i <= len, i++) - char = copytext(query_text, i, i + 1) - - if(char == "'") - if(copytext(query_text, i + 1, i + 2) == "'") - word += "'" - i++ - - else - break - - else - word += char - - if(i > len) - usr << "SDQL: You have an error in your SDQL syntax, unmatched ' in query: \"[query_text]\". Please check your syntax, and try again." - return null - - query_list += "[word]'" - word = "" - - else if(char == "\"") - if(word != "") - usr << "SDQL: You have an error in your SDQL syntax, unexpected \" in query: \"[query_text]\" following \"[word]\". Please check your syntax, and try again." - return null - - word = "\"" - - for(i++, i <= len, i++) - char = copytext(query_text, i, i + 1) - - if(char == "\"") - if(copytext(query_text, i + 1, i + 2) == "'") - word += "\"" - i++ - - else - break - - else - word += char - - if(i > len) - usr << "SDQL: You have an error in your SDQL syntax, unmatched \" in query: \"[query_text]\". Please check your syntax, and try again." - return null - - query_list += "[word]\"" - word = "" - - else - word += char - - if(word != "") - query_list += word - - return query_list diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2.dm b/code/modules/admin/verbs/SDQL2/SDQL_2.dm new file mode 100644 index 0000000000..58f568cfa7 --- /dev/null +++ b/code/modules/admin/verbs/SDQL2/SDQL_2.dm @@ -0,0 +1,1127 @@ +#define SDQL_qdel_datum(d) qdel(d) + +//SDQL2 datumized, /tg/station special! + +/* +Welcome admins, badmins and coders alike, to Structured Datum Query Language. +SDQL allows you to powerfully run code on batches of objects (or single objects, it's still unmatched +even there.) +When I say "powerfully" I mean it you're in for a ride. + +Ok so say you want to get a list of every mob. How does one do this? +"SELECT /mob" +This will open a list of every object in world that is a /mob. +And you can VV them if you need. + +What if you want to get every mob on a *specific z-level*? +"SELECT /mob WHERE z == 4" + +What if you want to select every mob on even numbered z-levels? +"SELECT /mob WHERE z % 2 == 0" + +Can you see where this is going? You can select objects with an arbitrary expression. +These expressions can also do variable access and proc calls (yes, both on-object and globals!) +Keep reading! + +Ok. What if you want to get every machine in the SSmachine process list? Looping through world is kinda +slow. + +"SELECT * IN SSmachines.machinery" + +Here "*" as type functions as a wildcard. +We know everything in the global SSmachines.machinery list is a machine. + +You can specify "IN " to return a list to operate on. +This can be any list that you can wizard together from global variables and global proc calls. +Every variable/proc name in the "IN" block is global. +It can also be a single object, in which case the object is wrapped in a list for you. +So yeah SDQL is unironically better than VV for complex single-object operations. + +You can of course combine these. +"SELECT * IN SSmachines.machinery WHERE z == 4" +"SELECT * IN SSmachines.machinery WHERE stat & 2" // (2 is NOPOWER, can't use defines from SDQL. Sorry!) +"SELECT * IN SSmachines.machinery WHERE stat & 2 && z == 4" + +The possibilities are endless (just don't crash the server, ok?). + +Oh it gets better. + +You can use "MAP " to run some code per object and use the result. For example: + +"SELECT /obj/machinery/power/smes MAP [charge / capacity * 100, RCon_tag, src]" + +This will give you a list of all the APCs, their charge AND RCon tag. Useful eh? + +[] being a list here. Yeah you can write out lists directly without > lol lists in VV. Color matrix +shenanigans inbound. + +After the "MAP" segment is executed, the rest of the query executes as if it's THAT object you just made +(here the list). +Yeah, by the way, you can chain these MAP / WHERE things FOREVER! + +"SELECT /mob WHERE client MAP client WHERE holder MAP holder" + +What if some dumbass admin spawned a bajillion spiders and you need to kill them all? +Oh yeah you'd rather not delete all the spiders in maintenace. Only that one room the spiders were +spawned in. + +"DELETE /mob/living/carbon/superior_animal/giant_spider WHERE loc.loc == marked" + +Here I used VV to mark the area they were in, and since loc.loc = area, voila. +Only the spiders in a specific area are gone. + +Or you know if you want to catch spiders that crawled into lockers too (how even?) + +"DELETE /mob/living/carbon/superior_animal/giant_spider WHERE global.get_area(src) == marked" + +What else can you do? + +Well suppose you'd rather gib those spiders instead of simply flat deleting them... + +"CALL gib() ON /mob/living/carbon/superior_animal/giant_spider WHERE global.get_area(src) == marked" + +Or you can have some fun.. + +"CALL forceMove(marked) ON /mob/living/carbon/superior_animal" + +You can also run multiple queries sequentially: + +"CALL forceMove(marked) ON /mob/living/carbon/superior_animal; CALL gib() ON +/mob/living/carbon/superior_animal" + +And finally, you can directly modify variables on objects. + +"UPDATE /mob WHERE client SET client.color = [0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]" + +Don't crash the server, OK? + +A quick recommendation: before you run something like a DELETE or another query.. Run it through SELECT +first. +You'd rather not gib every player on accident. +Or crash the server. + +By the way, queries are slow and take a while. Be patient. +They don't hang the entire server though. + +With great power comes great responsability. + +Here's a slightly more formal quick reference. + +The 4 queries you can do are: + +"SELECT " +"CALL ON " +"UPDATE SET var=,var2=" +"DELETE " + +"" in this context is " [IN ] [chain of MAP/WHERE modifiers]" + +"IN" (or "FROM", that works too but it's kinda weird to read), +is the list of objects to work on. This defaults to world if not provided. +But doing something like "IN living_mob_list" is quite handy and can optimize your query. +All names inside the IN block are global scope, so you can do living_mob_list (a global var) easily. +You can also run it on a single object. Because SDQL is that convenient even for single operations. + + filters out objects of, well, that type easily. "*" is a wildcard and just takes everything in +the source list. + +And then there's the MAP/WHERE chain. +These operate on each individual object being ran through the query. +They're both expressions like IN, but unlike it the expression is scoped *on the object*. +So if you do "WHERE z == 4", this does "src.z", effectively. +If you want to access global variables, you can do `global.living_mob_list`. +Same goes for procs. + +MAP "changes" the object into the result of the expression. +WHERE "drops" the object if the expression is falsey (0, null or "") + +What can you do inside expressions? + +* Proc calls +* Variable reads +* Literals (numbers, strings, type paths, etc...) +* \ref referencing: {0x30000cc} grabs the object with \ref [0x30000cc] +* Lists: [a, b, c] or [a: b, c: d] +* Math and stuff. +* A few special variables: src (the object currently scoped on), usr (your mob), +marked (your marked datum), global(global scope) + +TG ADDITIONS START: +Add USING keyword to the front of the query to use options system +The defaults aren't necessarily implemented, as there is no need to. +Available options: (D) means default +PROCCALL = (D)ASYNC, BLOCKING +SELECT = FORCE_NULLS, (D)SKIP_NULLS +PRIORITY = HIGH, (D) NORMAL +AUTOGC = (D) AUTOGC, KEEP_ALIVE + +Example: USING PROCCALL = BLOCKING, SELECT = FORCE_NULLS, PRIORITY = HIGH SELECT /mob FROM world WHERE z == 1 + +*/ + + +#define SDQL2_STATE_ERROR 0 +#define SDQL2_STATE_IDLE 1 +#define SDQL2_STATE_PRESEARCH 2 +#define SDQL2_STATE_SEARCHING 3 +#define SDQL2_STATE_EXECUTING 4 +#define SDQL2_STATE_SWITCHING 5 +#define SDQL2_STATE_HALTING 6 + +#define SDQL2_VALID_OPTION_TYPES list("proccall", "select", "priority", "autogc") +#define SDQL2_VALID_OPTION_VALUES list("async", "blocking", "force_nulls", "skip_nulls", "high", "normal", "keep_alive") + +#define SDQL2_OPTION_SELECT_OUTPUT_SKIP_NULLS (1<<0) +#define SDQL2_OPTION_BLOCKING_CALLS (1<<1) +#define SDQL2_OPTION_HIGH_PRIORITY (1<<2) //High priority SDQL query, allow using almost all of the tick. +#define SDQL2_OPTION_DO_NOT_AUTOGC (1<<3) + +#define SDQL2_OPTIONS_DEFAULT (SDQL2_OPTION_SELECT_OUTPUT_SKIP_NULLS) + +#define SDQL2_IS_RUNNING (state == SDQL2_STATE_EXECUTING || state == SDQL2_STATE_SEARCHING || state == SDQL2_STATE_SWITCHING || state == SDQL2_STATE_PRESEARCH) +#define SDQL2_HALT_CHECK if(!SDQL2_IS_RUNNING) {state = SDQL2_STATE_HALTING; return FALSE;}; + +#define SDQL2_TICK_CHECK ((options & SDQL2_OPTION_HIGH_PRIORITY)? CHECK_TICK_HIGH_PRIORITY : CHECK_TICK) + +#define SDQL2_STAGE_SWITCH_CHECK if(state != SDQL2_STATE_SWITCHING){\ + if(state == SDQL2_STATE_HALTING){\ + state = SDQL2_STATE_IDLE;\ + return FALSE}\ + state = SDQL2_STATE_ERROR;\ + CRASH("SDQL2 fatal error");}; + +/client/proc/SDQL2_query(query_text as message) + set category = "Debug" + if(!check_rights(R_DEBUG)) //Shouldn't happen... but just to be safe. + message_admins("ERROR: Non-admin [key_name(usr)] attempted to execute a SDQL query!") + log_admin("Non-admin [key_name(usr)] attempted to execute a SDQL query!") + return FALSE + var/list/results = world.SDQL2_query(query_text, key_name_admin(usr), "[key_name(usr)]") + if(length(results) == 3) + for(var/I in 1 to 3) + to_chat(usr, results[I]) + +/world/proc/SDQL2_query(query_text, log_entry1, log_entry2) + var/query_log = "executed SDQL query(s): \"[query_text]\"." + message_admins("[log_entry1] [query_log]") + query_log = "[log_entry2] [query_log]" + log_game(query_log) + + var/start_time_total = REALTIMEOFDAY + + if(!length(query_text)) + return + var/list/query_list = SDQL2_tokenize(query_text) + if(!length(query_list)) + return + var/list/querys = SDQL_parse(query_list) + if(!length(querys)) + return + var/list/datum/SDQL2_query/running = list() + for(var/list/query_tree in querys) + var/datum/SDQL2_query/query = new /datum/SDQL2_query(query_tree) + if(QDELETED(query)) + continue + if(usr) + query.show_next_to_key = usr.ckey + running += query + var/msg = "Starting query #[query.id] - [query.get_query_text()]." + if(usr) + to_chat(usr, "[msg]") + log_admin(msg) + query.ARun() + var/finished = FALSE + var/objs_all = 0 + var/objs_eligible = 0 + var/selectors_used = FALSE + var/list/combined_refs = list() + do + CHECK_TICK + finished = TRUE + for(var/i in running) + var/datum/SDQL2_query/query = i + if(QDELETED(query)) + running -= query + continue + else if(query.state != SDQL2_STATE_IDLE) + finished = FALSE + else if(query.state == SDQL2_STATE_ERROR) + if(usr) + to_chat(usr, "SDQL query [query.get_query_text()] errored. It will NOT be automatically garbage collected. Please remove manually.") + running -= query + else + if(query.finished) + objs_all += islist(query.obj_count_all)? length(query.obj_count_all) : query.obj_count_all + objs_eligible += islist(query.obj_count_eligible)? length(query.obj_count_eligible) : query.obj_count_eligible + selectors_used |= query.where_switched + combined_refs |= query.select_refs + running -= query + //if(!CHECK_BITFIELD(query.options, SDQL2_OPTION_DO_NOT_AUTOGC)) + //QDEL_IN(query, 50) Maybe when vorestation finally ports timers.. + else + if(usr) + to_chat(usr, "SDQL query [query.get_query_text()] was halted. It will NOT be automatically garbage collected. Please remove manually.") + running -= query + while(!finished) + + var/end_time_total = REALTIMEOFDAY - start_time_total + return list("SDQL query combined results: [query_text]",\ + "SDQL query completed: [objs_all] objects selected by path, and [selectors_used ? objs_eligible : objs_all] objects executed on after WHERE filtering/MAPping if applicable.",\ + "SDQL combined querys took [DisplayTimeText(end_time_total)] to complete.") + combined_refs + +GLOBAL_LIST_INIT(sdql2_queries, GLOB.sdql2_queries || list()) +GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null, "VIEW VARIABLES (all)", null)) + +/datum/SDQL2_query + var/list/query_tree + var/state = SDQL2_STATE_IDLE + var/options = SDQL2_OPTIONS_DEFAULT + var/superuser = FALSE //Run things like proccalls without using admin protections + var/allow_admin_interact = TRUE //Allow admins to do things to this excluding varedit these two vars + var/static/id_assign = 1 + var/id = 0 + + var/qdel_on_finish = FALSE + + //Last run + //General + var/finished = FALSE + var/start_time + var/end_time + var/where_switched = FALSE + var/show_next_to_key + //Select query only + var/list/select_refs + var/list/select_text + //Runtime tracked + //These three are weird. For best performance, they are only a number when they're not being changed by the SDQL searching/execution code. They only become numbers when they finish changing. + var/list/obj_count_all + var/list/obj_count_eligible + var/list/obj_count_finished + + //Statclick + var/obj/effect/statclick/SDQL2_delete/delete_click + var/obj/effect/statclick/SDQL2_action/action_click + +/datum/SDQL2_query/New(list/tree, SU = FALSE, admin_interact = TRUE, _options = SDQL2_OPTIONS_DEFAULT, finished_qdel = FALSE) + LAZYADD(GLOB.sdql2_queries, src) + superuser = SU + allow_admin_interact = admin_interact + query_tree = tree + options = _options + id = id_assign++ + qdel_on_finish = finished_qdel + +/datum/SDQL2_query/Destroy() + state = SDQL2_STATE_HALTING + query_tree = null + obj_count_all = null + obj_count_eligible = null + obj_count_finished = null + select_text = null + select_refs = null + GLOB.sdql2_queries -= src + return ..() + +/datum/SDQL2_query/proc/get_query_text() + var/list/out = list() + recursive_list_print(out, query_tree) + return out.Join() + +/proc/recursive_list_print(list/output = list(), list/input, datum/callback/datum_handler, datum/callback/atom_handler) + output += "\[ " + for(var/i in 1 to input.len) + var/final = i == input.len + var/key = input[i] + + //print the key + if(islist(key)) + recursive_list_print(output, key, datum_handler, atom_handler) + else if(is_proper_datum(key) && (datum_handler || (istype(key, /atom) && atom_handler))) + if(istype(key, /atom) && atom_handler) + output += atom_handler.Invoke(key) + else + output += datum_handler.Invoke(key) + else + output += "[key]" + + //print the value + var/is_value = (!isnum(key) && !isnull(input[key])) + if(is_value) + var/value = input[key] + if(islist(value)) + recursive_list_print(output, value, datum_handler, atom_handler) + else if(is_proper_datum(value) && (datum_handler || (istype(value, /atom) && atom_handler))) + if(istype(value, /atom) && atom_handler) + output += atom_handler.Invoke(value) + else + output += datum_handler.Invoke(value) + else + output += " = [value]" + + if(!final) + output += " , " + + output += " \]" + +/datum/SDQL2_query/proc/text_state() + switch(state) + if(SDQL2_STATE_ERROR) + return "###ERROR" + if(SDQL2_STATE_IDLE) + return "####IDLE" + if(SDQL2_STATE_PRESEARCH) + return "PRESEARCH" + if(SDQL2_STATE_SEARCHING) + return "SEARCHING" + if(SDQL2_STATE_EXECUTING) + return "EXECUTING" + if(SDQL2_STATE_SWITCHING) + return "SWITCHING" + if(SDQL2_STATE_HALTING) + return "##HALTING" + +/datum/SDQL2_query/proc/generate_stat() + if(!allow_admin_interact) + return + if(!delete_click) + delete_click = new(null, "INITIALIZING", src) + if(!action_click) + action_click = new(null, "INITIALIZNG", src) + stat("[id] ", delete_click.update("DELETE QUERY | STATE : [text_state()] | ALL/ELIG/FIN \ + [islist(obj_count_all)? length(obj_count_all) : (isnull(obj_count_all)? "0" : obj_count_all)]/\ + [islist(obj_count_eligible)? length(obj_count_eligible) : (isnull(obj_count_eligible)? "0" : obj_count_eligible)]/\ + [islist(obj_count_finished)? length(obj_count_finished) : (isnull(obj_count_finished)? "0" : obj_count_finished)] - [get_query_text()]")) + stat(" ", action_click.update("[SDQL2_IS_RUNNING? "HALT" : "RUN"]")) + +/datum/SDQL2_query/proc/delete_click() + admin_del(usr) + +/datum/SDQL2_query/proc/action_click() + if(SDQL2_IS_RUNNING) + admin_halt(usr) + else + admin_run(usr) + +/datum/SDQL2_query/proc/admin_halt(user = usr) + if(!SDQL2_IS_RUNNING) + return + var/msg = "[key_name(user)] has halted query #[id]" + message_admins(msg) + log_admin(msg) + state = SDQL2_STATE_HALTING + +/datum/SDQL2_query/proc/admin_run(mob/user = usr) + if(SDQL2_IS_RUNNING) + return + var/msg = "[key_name(user)] has (re)started query #[id]" + message_admins(msg) + log_admin(msg) + show_next_to_key = user.ckey + ARun() + +/datum/SDQL2_query/proc/admin_del(user = usr) + var/msg = "[key_name(user)] has stopped + deleted query #[id]" + message_admins(msg) + log_admin(msg) + qdel(src) + +/datum/SDQL2_query/proc/set_option(name, value) + switch(name) + if("select") + switch(value) + if("force_nulls") + DISABLE_BITFIELD(options, SDQL2_OPTION_SELECT_OUTPUT_SKIP_NULLS) + if("proccall") + switch(value) + if("blocking") + ENABLE_BITFIELD(options, SDQL2_OPTION_BLOCKING_CALLS) + if("priority") + switch(value) + if("high") + ENABLE_BITFIELD(options, SDQL2_OPTION_HIGH_PRIORITY) + if("autogc") + switch(value) + if("keep_alive") + ENABLE_BITFIELD(options, SDQL2_OPTION_DO_NOT_AUTOGC) + +/datum/SDQL2_query/proc/ARun() + INVOKE_ASYNC(src, .proc/Run) + +/datum/SDQL2_query/proc/Run() + if(SDQL2_IS_RUNNING) + return FALSE + if(query_tree["options"]) + for(var/name in query_tree["options"]) + var/value = query_tree["options"][name] + set_option(name, value) + select_refs = list() + select_text = null + obj_count_all = 0 + obj_count_eligible = 0 + obj_count_finished = 0 + start_time = REALTIMEOFDAY + + state = SDQL2_STATE_PRESEARCH + var/list/search_tree = PreSearch() + SDQL2_STAGE_SWITCH_CHECK + + state = SDQL2_STATE_SEARCHING + var/list/found = Search(search_tree) + SDQL2_STAGE_SWITCH_CHECK + + state = SDQL2_STATE_EXECUTING + Execute(found) + SDQL2_STAGE_SWITCH_CHECK + + end_time = REALTIMEOFDAY + state = SDQL2_STATE_IDLE + finished = TRUE + . = TRUE + if(show_next_to_key) + var/client/C = GLOB.directory[show_next_to_key] + if(C) + var/mob/showmob = C.mob + to_chat(showmob, "SDQL query results: [get_query_text()]
\ + SDQL query completed: [islist(obj_count_all)? length(obj_count_all) : obj_count_all] objects selected by path, and \ + [where_switched? "[islist(obj_count_eligible)? length(obj_count_eligible) : obj_count_eligible] objects executed on after WHERE keyword selection." : ""]
\ + SDQL query took [DisplayTimeText(end_time - start_time)] to complete.
") + if(length(select_text)) + var/text = islist(select_text)? select_text.Join() : select_text + var/static/result_offset = 0 + showmob << browse(text, "window=SDQL-result-[result_offset++]") + show_next_to_key = null + if(qdel_on_finish) + qdel(src) + +/datum/SDQL2_query/proc/PreSearch() + SDQL2_HALT_CHECK + switch(query_tree[1]) + if("explain") + SDQL_testout(query_tree["explain"]) + state = SDQL2_STATE_HALTING + return + if("call") + . = query_tree["on"] + if("select", "delete", "update") + . = query_tree[query_tree[1]] + state = SDQL2_STATE_SWITCHING + +/datum/SDQL2_query/proc/Search(list/tree) + SDQL2_HALT_CHECK + var/type = tree[1] + var/list/from = tree[2] + var/list/objs = SDQL_from_objs(from) + SDQL2_TICK_CHECK + SDQL2_HALT_CHECK + objs = SDQL_get_all(type, objs) + SDQL2_TICK_CHECK + SDQL2_HALT_CHECK + + // 1 and 2 are type and FROM. + var/i = 3 + while (i <= tree.len) + var/key = tree[i++] + var/list/expression = tree[i++] + switch (key) + if ("map") + for(var/j = 1 to objs.len) + var/x = objs[j] + objs[j] = SDQL_expression(x, expression) + SDQL2_TICK_CHECK + SDQL2_HALT_CHECK + + if ("where") + where_switched = TRUE + var/list/out = list() + obj_count_eligible = out + for(var/x in objs) + if(SDQL_expression(x, expression)) + out += x + SDQL2_TICK_CHECK + SDQL2_HALT_CHECK + objs = out + if(islist(obj_count_eligible)) + obj_count_eligible = objs.len + else + obj_count_eligible = obj_count_all + . = objs + state = SDQL2_STATE_SWITCHING + +/datum/SDQL2_query/proc/SDQL_from_objs(list/tree) + if("world" in tree) + return world + return SDQL_expression(world, tree) + +/datum/SDQL2_query/proc/SDQL_get_all(type, location) + var/list/out = list() + obj_count_all = out + +// If only a single object got returned, wrap it into a list so the for loops run on it. + if(!islist(location) && location != world) + location = list(location) + + if(type == "*") + for(var/i in location) + var/datum/d = i + if(d.can_vv_get() || superuser) + out += d + SDQL2_TICK_CHECK + SDQL2_HALT_CHECK + return out + if(istext(type)) + type = text2path(type) + var/typecache = typecacheof(type) + + if(ispath(type, /mob)) + for(var/mob/d in location) + if(typecache[d.type] && (d.can_vv_get() || superuser)) + out += d + SDQL2_TICK_CHECK + SDQL2_HALT_CHECK + + else if(ispath(type, /turf)) + for(var/turf/d in location) + if(typecache[d.type] && (d.can_vv_get() || superuser)) + out += d + SDQL2_TICK_CHECK + SDQL2_HALT_CHECK + + else if(ispath(type, /obj)) + for(var/obj/d in location) + if(typecache[d.type] && (d.can_vv_get() || superuser)) + out += d + SDQL2_TICK_CHECK + SDQL2_HALT_CHECK + + else if(ispath(type, /area)) + for(var/area/d in location) + if(typecache[d.type] && (d.can_vv_get() || superuser)) + out += d + SDQL2_TICK_CHECK + SDQL2_HALT_CHECK + + else if(ispath(type, /atom)) + for(var/atom/d in location) + if(typecache[d.type] && (d.can_vv_get() || superuser)) + out += d + SDQL2_TICK_CHECK + SDQL2_HALT_CHECK + + else if(ispath(type, /datum)) + if(location == world) //snowflake for byond shortcut + for(var/datum/d) //stupid byond trick to have it not return atoms to make this less laggy + if(typecache[d.type] && (d.can_vv_get() || superuser)) + out += d + SDQL2_TICK_CHECK + SDQL2_HALT_CHECK + else + for(var/datum/d in location) + if(typecache[d.type] && (d.can_vv_get() || superuser)) + out += d + SDQL2_TICK_CHECK + SDQL2_HALT_CHECK + obj_count_all = out.len + return out + +/datum/SDQL2_query/proc/Execute(list/found) + SDQL2_HALT_CHECK + select_refs = list() + select_text = list() + switch(query_tree[1]) + if("call") + for(var/i in found) + if(!is_proper_datum(i)) + continue + world.SDQL_var(i, query_tree["call"][1], null, i, superuser, src) + obj_count_finished++ + SDQL2_TICK_CHECK + SDQL2_HALT_CHECK + + if("delete") + for(var/datum/d in found) + SDQL_qdel_datum(d) + obj_count_finished++ + SDQL2_TICK_CHECK + SDQL2_HALT_CHECK + + if("select") + var/list/text_list = list() + var/print_nulls = !(options & SDQL2_OPTION_SELECT_OUTPUT_SKIP_NULLS) + obj_count_finished = select_refs + for(var/i in found) + SDQL_print(i, text_list, print_nulls) + select_refs["\ref[i]"] = TRUE + SDQL2_TICK_CHECK + SDQL2_HALT_CHECK + select_text = text_list + + if("update") + if("set" in query_tree) + var/list/set_list = query_tree["set"] + for(var/d in found) + if(!is_proper_datum(d)) + continue + SDQL_internal_vv(d, set_list) + obj_count_finished++ + SDQL2_TICK_CHECK + SDQL2_HALT_CHECK + if(islist(obj_count_finished)) + obj_count_finished = obj_count_finished.len + state = SDQL2_STATE_SWITCHING + +/datum/SDQL2_query/proc/SDQL_print(object, list/text_list, print_nulls = TRUE) + if(is_proper_datum(object)) + text_list += "\ref[object] : [object]" + if(istype(object, /atom)) + var/atom/A = object + var/turf/T = A.loc + var/area/a + if(istype(T)) + text_list += " at [T] [ADMIN_COORDJMP(T)]" + a = T.loc + else + var/turf/final = get_turf(T) //Recursive, hopefully? + if(istype(final)) + text_list += " at [final] [ADMIN_COORDJMP(final)]" + a = final.loc + else + text_list += " at nonexistant location" + if(a) + text_list += " in area [a]" + if(T.loc != a) + text_list += " inside [T]" + text_list += "
" + else if(islist(object)) + var/list/L = object + var/first = TRUE + text_list += "\[" + for (var/x in L) + if (!first) + text_list += ", " + first = FALSE + SDQL_print(x, text_list) + if (!isnull(x) && !isnum(x) && L[x] != null) + text_list += " -> " + SDQL_print(L[L[x]]) + text_list += "]
" + else + if(isnull(object)) + if(print_nulls) + text_list += "NULL
" + else + text_list += "[object]
" + +/datum/SDQL2_query/CanProcCall() + if(!allow_admin_interact) + return FALSE + return ..() + +/datum/SDQL2_query/vv_edit_var(var_name, var_value) + if(!allow_admin_interact) + return FALSE + if(var_name == NAMEOF(src, superuser) || var_name == NAMEOF(src, allow_admin_interact) || var_name == NAMEOF(src, query_tree)) + return FALSE + return ..() + +/datum/SDQL2_query/proc/SDQL_internal_vv(d, list/set_list) + for(var/list/sets in set_list) + var/datum/temp = d + var/i = 0 + for(var/v in sets) + if(++i == sets.len) + if(superuser) + if(temp.vars.Find(v)) + temp.vars[v] = SDQL_expression(d, set_list[sets]) + else + temp.vv_edit_var(v, SDQL_expression(d, set_list[sets])) + break + if(temp.vars.Find(v) && (istype(temp.vars[v], /datum) || istype(temp.vars[v], /client))) + temp = temp.vars[v] + else + break + +/datum/SDQL2_query/proc/SDQL_function_blocking(datum/object, procname, list/arguments, source) + var/list/new_args = list() + for(var/arg in arguments) + new_args[++new_args.len] = SDQL_expression(source, arg) + if(object == GLOB) // Global proc. + procname = "/proc/[procname]" + return superuser? (call(procname)(new_args)) : (WrapAdminProcCall(GLOBAL_PROC, procname, new_args)) + return superuser? (call(object, procname)(new_args)) : (WrapAdminProcCall(object, procname, new_args)) + +/datum/SDQL2_query/proc/SDQL_function_async(datum/object, procname, list/arguments, source) + set waitfor = FALSE + return SDQL_function_blocking(object, procname, arguments, source) + +/datum/SDQL2_query/proc/SDQL_expression(datum/object, list/expression, start = 1) + var/result = 0 + var/val + + for(var/i = start, i <= expression.len, i++) + var/op = "" + + if(i > start) + op = expression[i] + i++ + + var/list/ret = SDQL_value(object, expression, i) + val = ret["val"] + i = ret["i"] + + if(op != "") + switch(op) + if("+") + result = (result + val) + if("-") + result = (result - val) + if("*") + result = (result * val) + if("/") + result = (result / val) + if("&") + result = (result & val) + if("|") + result = (result | val) + if("^") + result = (result ^ val) + if("%") + result = (result % val) + if("=", "==") + result = (result == val) + if("!=", "<>") + result = (result != val) + if("<") + result = (result < val) + if("<=") + result = (result <= val) + if(">") + result = (result > val) + if(">=") + result = (result >= val) + if("and", "&&") + result = (result && val) + if("or", "||") + result = (result || val) + else + to_chat(usr, "SDQL2: Unknown op [op]") + result = null + else + result = val + + return result + +/datum/SDQL2_query/proc/SDQL_value(datum/object, list/expression, start = 1) + var/i = start + var/val = null + + if(i > expression.len) + return list("val" = null, "i" = i) + + if(istype(expression[i], /list)) + val = SDQL_expression(object, expression[i]) + + else if(expression[i] == "TRUE") + val = TRUE + + else if(expression[i] == "FALSE") + val = FALSE + + else if(expression[i] == "!") + var/list/ret = SDQL_value(object, expression, i + 1) + val = !ret["val"] + i = ret["i"] + + else if(expression[i] == "~") + var/list/ret = SDQL_value(object, expression, i + 1) + val = ~ret["val"] + i = ret["i"] + + else if(expression[i] == "-") + var/list/ret = SDQL_value(object, expression, i + 1) + val = -ret["val"] + i = ret["i"] + + else if(expression[i] == "null") + val = null + + else if(isnum(expression[i])) + val = expression[i] + + else if(ispath(expression[i])) + val = expression[i] + + else if(copytext(expression[i], 1, 2) in list("'", "\"")) + val = copytext(expression[i], 2, length(expression[i])) + + else if(expression[i] == "\[") + var/list/expressions_list = expression[++i] + val = list() + for(var/list/expression_list in expressions_list) + var/result = SDQL_expression(object, expression_list) + var/assoc + if(expressions_list[expression_list] != null) + assoc = SDQL_expression(object, expressions_list[expression_list]) + if(assoc != null) + // Need to insert the key like this to prevent duplicate keys fucking up. + var/list/dummy = list() + dummy[result] = assoc + result = dummy + val += result + else + val = world.SDQL_var(object, expression, i, object, superuser, src) + i = expression.len + + return list("val" = val, "i" = i) + +/proc/SDQL_parse(list/query_list) + var/datum/SDQL_parser/parser = new() + var/list/querys = list() + var/list/query_tree = list() + var/pos = 1 + var/querys_pos = 1 + var/do_parse = 0 + + for(var/val in query_list) + if(val == ";") + do_parse = 1 + else if(pos >= query_list.len) + query_tree += val + do_parse = 1 + + if(do_parse) + parser.query = query_tree + var/list/parsed_tree + parsed_tree = parser.parse() + if(parsed_tree.len > 0) + querys.len = querys_pos + querys[querys_pos] = parsed_tree + querys_pos++ + else //There was an error so don't run anything, and tell the user which query has errored. + to_chat(usr, "Parsing error on [querys_pos]\th query. Nothing was executed.") + return list() + query_tree = list() + do_parse = 0 + else + query_tree += val + pos++ + + qdel(parser) + return querys + +/proc/SDQL_testout(list/query_tree, indent = 0) + var/static/whitespace = "    " + var/spaces = "" + for(var/s = 0, s < indent, s++) + spaces += whitespace + + for(var/item in query_tree) + if(istype(item, /list)) + to_chat(usr, "[spaces](") + SDQL_testout(item, indent + 1) + to_chat(usr, "[spaces])") + + else + to_chat(usr, "[spaces][item]") + + if(!isnum(item) && query_tree[item]) + + if(istype(query_tree[item], /list)) + to_chat(usr, "[spaces][whitespace](") + SDQL_testout(query_tree[item], indent + 2) + to_chat(usr, "[spaces][whitespace])") + + else + to_chat(usr, "[spaces][whitespace][query_tree[item]]") + +//Staying as a world proc as this is called too often for changes to offset the potential IsAdminAdvancedProcCall checking overhead. +/world/proc/SDQL_var(object, list/expression, start = 1, source, superuser, datum/SDQL2_query/query) + var/v + var/static/list/exclude = list("usr", "src", "marked", "global") + var/long = start < expression.len + var/datum/D + if(is_proper_datum(object)) + D = object + + if (object == world && (!long || expression[start + 1] == ".") && !(expression[start] in exclude)) + to_chat(usr, "World variables are not allowed to be accessed. Use global.") + return null + + else if(expression [start] == "{" && long) + if(lowertext(copytext(expression[start + 1], 1, 3)) != "0x") + to_chat(usr, "Invalid pointer syntax: [expression[start + 1]]") + return null + v = locate("\[[expression[start + 1]]]") + if(!v) + to_chat(usr, "Invalid pointer: [expression[start + 1]]") + return null + start++ + long = start < expression.len + else if(D != null && (!long || expression[start + 1] == ".") && (expression[start] in D.vars)) + if(D.can_vv_get(expression[start]) || superuser) + v = D.vars[expression[start]] + else + v = "SECRET" + else if(D != null && long && expression[start + 1] == ":" && hascall(D, expression[start])) + v = expression[start] + else if(!long || expression[start + 1] == ".") + switch(expression[start]) + if("usr") + v = usr + if("src") + v = source + if("marked") + if(usr.client && usr.client.holder && usr.client.holder.marked_datum) + v = usr.client.holder.marked_datum + else + return null + if("world") + v = world + if("global") + v = GLOB + if("MC") + v = Master + if("FS") + v = Failsafe + if("CFG") + v = config + else + return null + else if(object == GLOB) // Shitty ass hack kill me. + v = expression[start] + if(long) + if(expression[start + 1] == ".") + return SDQL_var(v, expression[start + 2], null, source, superuser, query) + else if(expression[start + 1] == ":") + return (query.options & SDQL2_OPTION_BLOCKING_CALLS)? query.SDQL_function_async(object, v, expression[start + 2], source) : query.SDQL_function_blocking(object, v, expression[start + 2], source) + else if(expression[start + 1] == "\[" && islist(v)) + var/list/L = v + var/index = query.SDQL_expression(source, expression[start + 2]) + if(isnum(index) && (!(round(index) == index) || L.len < index)) + to_chat(usr, "Invalid list index: [index]") + return null + return L[index] + return v + +/proc/SDQL2_tokenize(query_text) + + var/list/whitespace = list(" ", "\n", "\t") + var/list/single = list("(", ")", ",", "+", "-", ".", "\[", "]", "{", "}", ";", ":") + var/list/multi = list( + "=" = list("", "="), + "<" = list("", "=", ">"), + ">" = list("", "="), + "!" = list("", "=")) + + var/word = "" + var/list/query_list = list() + var/len = length(query_text) + + for(var/i = 1, i <= len, i++) + var/char = copytext(query_text, i, i + 1) + + if(char in whitespace) + if(word != "") + query_list += word + word = "" + + else if(char in single) + if(word != "") + query_list += word + word = "" + + query_list += char + + else if(char in multi) + if(word != "") + query_list += word + word = "" + + var/char2 = copytext(query_text, i + 1, i + 2) + + if(char2 in multi[char]) + query_list += "[char][char2]" + i++ + + else + query_list += char + + else if(char == "'") + if(word != "") + to_chat(usr, "SDQL2: You have an error in your SDQL syntax, unexpected ' in query: \"[query_text]\" following \"[word]\". Please check your syntax, and try again.") + return null + + word = "'" + + for(i++, i <= len, i++) + char = copytext(query_text, i, i + 1) + + if(char == "'") + if(copytext(query_text, i + 1, i + 2) == "'") + word += "'" + i++ + + else + break + + else + word += char + + if(i > len) + to_chat(usr, "SDQL2: You have an error in your SDQL syntax, unmatched ' in query: \"[query_text]\". Please check your syntax, and try again.") + return null + + query_list += "[word]'" + word = "" + + else if(char == "\"") + if(word != "") + to_chat(usr, "SDQL2: You have an error in your SDQL syntax, unexpected \" in query: \"[query_text]\" following \"[word]\". Please check your syntax, and try again.") + return null + + word = "\"" + + for(i++, i <= len, i++) + char = copytext(query_text, i, i + 1) + + if(char == "\"") + if(copytext(query_text, i + 1, i + 2) == "'") + word += "\"" + i++ + + else + break + + else + word += char + + if(i > len) + to_chat(usr, "SDQL2: You have an error in your SDQL syntax, unmatched \" in query: \"[query_text]\". Please check your syntax, and try again.") + return null + + query_list += "[word]\"" + word = "" + + else + word += char + + if(word != "") + query_list += word + return query_list + +/proc/is_proper_datum(thing) + return istype(thing, /datum) || istype(thing, /client) + +/obj/effect/statclick/SDQL2_delete/Click() + var/datum/SDQL2_query/Q = target + Q.delete_click() + +/obj/effect/statclick/SDQL2_action/Click() + var/datum/SDQL2_query/Q = target + Q.action_click() + +/obj/effect/statclick/SDQL2_VV_all + name = "VIEW VARIABLES" + +/obj/effect/statclick/SDQL2_VV_all/Click() + usr.client.debug_variables(GLOB.sdql2_queries) diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2_parser.dm b/code/modules/admin/verbs/SDQL2/SDQL_2_parser.dm new file mode 100644 index 0000000000..e6504475c5 --- /dev/null +++ b/code/modules/admin/verbs/SDQL2/SDQL_2_parser.dm @@ -0,0 +1,635 @@ + +//I'm pretty sure that this is a recursive [s]descent[/s] ascent parser. + + +//Spec + +////////// +// +// query : select_query | delete_query | update_query | call_query | explain +// explain : 'EXPLAIN' query +// select_query : 'SELECT' object_selectors +// delete_query : 'DELETE' object_selectors +// update_query : 'UPDATE' object_selectors 'SET' assignments +// call_query : 'CALL' variable 'ON' object_selectors // Note here: 'variable' does function calls. This simplifies parsing. +// +// select_item : '*' | object_type +// +// object_selectors : select_item [('FROM' | 'IN') from_item] [modifier_list] +// modifier_list : ('WHERE' bool_expression | 'MAP' expression) [modifier_list] +// +// from_item : 'world' | expression +// +// call_function : '(' [arguments] ')' +// arguments : expression [',' arguments] +// +// object_type : +// +// assignments : assignment [',' assignments] +// assignment : '=' expression +// variable : | '.' variable | '[' ']' | '[' ']' '.' variable +// +// bool_expression : expression comparitor expression [bool_operator bool_expression] +// expression : ( unary_expression | '(' expression ')' | value ) [binary_operator expression] +// unary_expression : unary_operator ( unary_expression | value | '(' expression ')' ) +// comparitor : '=' | '==' | '!=' | '<>' | '<' | '<=' | '>' | '>=' +// value : variable | string | number | 'null' | object_type +// unary_operator : '!' | '-' | '~' +// binary_operator : comparitor | '+' | '-' | '/' | '*' | '&' | '|' | '^' | '%' +// bool_operator : 'AND' | '&&' | 'OR' | '||' +// +// string : ''' ''' | '"' '"' +// number : +// +////////// + +/datum/SDQL_parser + var/query_type + var/error = 0 + + var/list/query + var/list/tree + + var/list/boolean_operators = list("and", "or", "&&", "||") + var/list/unary_operators = list("!", "-", "~") + var/list/binary_operators = list("+", "-", "/", "*", "&", "|", "^", "%") + var/list/comparitors = list("=", "==", "!=", "<>", "<", "<=", ">", ">=") + +/datum/SDQL_parser/New(query_list) + query = query_list + +/datum/SDQL_parser/proc/parse_error(error_message) + error = 1 + to_chat(usr, "SQDL2 Parsing Error: [error_message]") + return query.len + 1 + +/datum/SDQL_parser/proc/parse() + tree = list() + query_options(1, tree) + + if(error) + return list() + else + return tree + +/datum/SDQL_parser/proc/token(i) + if(i <= query.len) + return query[i] + + else + return null + +/datum/SDQL_parser/proc/tokens(i, num) + if(i + num <= query.len) + return query.Copy(i, i + num) + + else + return null + +/datum/SDQL_parser/proc/tokenl(i) + return lowertext(token(i)) + +/datum/SDQL_parser/proc/query_options(i, list/node) + var/list/options = list() + if(tokenl(i) == "using") + i = option_assignments(i + 1, node, options) + query(i, node) + if(length(options)) + node["options"] = options + +//option_assignment: query_option '=' define +/datum/SDQL_parser/proc/option_assignment(i, list/node, list/assignment_list = list()) + var/type = tokenl(i) + if(!(type in SDQL2_VALID_OPTION_TYPES)) + parse_error("Invalid option type: [type]") + if(!(token(i + 1) == "=")) + parse_error("Invalid option assignment symbol: [token(i + 1)]") + var/val = tokenl(i + 2) + if(!(val in SDQL2_VALID_OPTION_VALUES)) + parse_error("Invalid optoin value: [val]") + assignment_list[type] = val + return (i + 3) + +//option_assignments: option_assignment, [',' option_assignments] +/datum/SDQL_parser/proc/option_assignments(i, list/node, list/store) + i = option_assignment(i, node, store) + + if(token(i) == ",") + i = option_assignments(i + 1, node, store) + + return i + +//query: select_query | delete_query | update_query +/datum/SDQL_parser/proc/query(i, list/node) + query_type = tokenl(i) + + switch(query_type) + if("select") + select_query(i, node) + + if("delete") + delete_query(i, node) + + if("update") + update_query(i, node) + + if("call") + call_query(i, node) + + if("explain") + node += "explain" + node["explain"] = list() + query(i + 1, node["explain"]) + + +// select_query: 'SELECT' object_selectors +/datum/SDQL_parser/proc/select_query(i, list/node) + var/list/select = list() + i = object_selectors(i + 1, select) + + node["select"] = select + return i + + +//delete_query: 'DELETE' object_selectors +/datum/SDQL_parser/proc/delete_query(i, list/node) + var/list/select = list() + i = object_selectors(i + 1, select) + + node["delete"] = select + + return i + + +//update_query: 'UPDATE' object_selectors 'SET' assignments +/datum/SDQL_parser/proc/update_query(i, list/node) + var/list/select = list() + i = object_selectors(i + 1, select) + + node["update"] = select + + if(tokenl(i) != "set") + i = parse_error("UPDATE has misplaced SET") + + var/list/set_assignments = list() + i = assignments(i + 1, set_assignments) + + node["set"] = set_assignments + + return i + + +//call_query: 'CALL' call_function ['ON' object_selectors] +/datum/SDQL_parser/proc/call_query(i, list/node) + var/list/func = list() + i = variable(i + 1, func) // Yes technically does anything variable() matches but I don't care, if admins fuck up this badly then they shouldn't be allowed near SDQL. + + node["call"] = func + + if(tokenl(i) != "on") + return parse_error("You need to specify what to call ON.") + + var/list/select = list() + i = object_selectors(i + 1, select) + + node["on"] = select + + return i + +// object_selectors: select_item [('FROM' | 'IN') from_item] [modifier_list] +/datum/SDQL_parser/proc/object_selectors(i, list/node) + i = select_item(i, node) + + if (tokenl(i) == "from" || tokenl(i) == "in") + i++ + var/list/from = list() + i = from_item(i, from) + node[++node.len] = from + + else + node[++node.len] = list("world") + + i = modifier_list(i, node) + return i + +// modifier_list: ('WHERE' bool_expression | 'MAP' expression) [modifier_list] +/datum/SDQL_parser/proc/modifier_list(i, list/node) + while (TRUE) + if (tokenl(i) == "where") + i++ + node += "where" + var/list/expr = list() + i = bool_expression(i, expr) + node[++node.len] = expr + + else if (tokenl(i) == "map") + i++ + node += "map" + var/list/expr = list() + i = expression(i, expr) + node[++node.len] = expr + + else + return i + +//select_list:select_item [',' select_list] +/datum/SDQL_parser/proc/select_list(i, list/node) + i = select_item(i, node) + + if(token(i) == ",") + i = select_list(i + 1, node) + + return i + +//assignments: assignment, [',' assignments] +/datum/SDQL_parser/proc/assignments(i, list/node) + i = assignment(i, node) + + if(token(i) == ",") + i = assignments(i + 1, node) + + return i + + +//select_item: '*' | select_function | object_type +/datum/SDQL_parser/proc/select_item(i, list/node) + if (token(i) == "*") + node += "*" + i++ + + else if (copytext(token(i), 1, 2) == "/") + i = object_type(i, node) + + else + i = parse_error("Expected '*' or type path for select item") + + return i + +// Standardized method for handling the IN/FROM and WHERE options. +/datum/SDQL_parser/proc/selectors(i, list/node) + while (token(i)) + var/tok = tokenl(i) + if (tok in list("from", "in")) + var/list/from = list() + i = from_item(i + 1, from) + + node["from"] = from + continue + + if (tok == "where") + var/list/where = list() + i = bool_expression(i + 1, where) + + node["where"] = where + continue + + parse_error("Expected either FROM, IN or WHERE token, found [token(i)] instead.") + return i + 1 + + if (!node.Find("from")) + node["from"] = list("world") + + return i + +//from_item: 'world' | expression +/datum/SDQL_parser/proc/from_item(i, list/node) + if(token(i) == "world") + node += "world" + i++ + + else + i = expression(i, node) + + return i + + +//bool_expression: expression [bool_operator bool_expression] +/datum/SDQL_parser/proc/bool_expression(i, list/node) + + var/list/bool = list() + i = expression(i, bool) + + node[++node.len] = bool + + if(tokenl(i) in boolean_operators) + i = bool_operator(i, node) + i = bool_expression(i, node) + + return i + + +//assignment: '=' expression +/datum/SDQL_parser/proc/assignment(var/i, var/list/node, var/list/assignment_list = list()) + assignment_list += token(i) + + if(token(i + 1) == ".") + i = assignment(i + 2, node, assignment_list) + + else if(token(i + 1) == "=") + var/exp_list = list() + node[assignment_list] = exp_list + + i = expression(i + 2, exp_list) + + else + parse_error("Assignment expected, but no = found") + + return i + + +//variable: | '.' variable | '[' ']' | '[' ']' '.' variable +/datum/SDQL_parser/proc/variable(i, list/node) + var/list/L = list(token(i)) + node[++node.len] = L + + if(token(i) == "{") + L += token(i + 1) + i += 2 + + if(token(i) != "}") + parse_error("Missing } at end of pointer.") + + if(token(i + 1) == ".") + L += "." + i = variable(i + 2, L) + + else if (token(i + 1) == "(") // OH BOY PROC + var/list/arguments = list() + i = call_function(i, null, arguments) + L += ":" + L[++L.len] = arguments + + else if (token(i + 1) == "\[") + var/list/expression = list() + i = expression(i + 2, expression) + if (token(i) != "]") + parse_error("Missing ] at the end of list access.") + + L += "\[" + L[++L.len] = expression + i++ + + else + i++ + + return i + + +//object_type: +/datum/SDQL_parser/proc/object_type(i, list/node) + + if (copytext(token(i), 1, 2) != "/") + return parse_error("Expected type, but it didn't begin with /") + + var/path = text2path(token(i)) + if (path == null) + return parse_error("Nonexistant type path: [token(i)]") + + node += path + + return i + 1 + + +//comparitor: '=' | '==' | '!=' | '<>' | '<' | '<=' | '>' | '>=' +/datum/SDQL_parser/proc/comparitor(i, list/node) + + if(token(i) in list("=", "==", "!=", "<>", "<", "<=", ">", ">=")) + node += token(i) + + else + parse_error("Unknown comparitor [token(i)]") + + return i + 1 + + +//bool_operator: 'AND' | '&&' | 'OR' | '||' +/datum/SDQL_parser/proc/bool_operator(i, list/node) + + if(tokenl(i) in list("and", "or", "&&", "||")) + node += token(i) + + else + parse_error("Unknown comparitor [token(i)]") + + return i + 1 + + +//string: ''' ''' | '"' '"' +/datum/SDQL_parser/proc/string(i, list/node) + + if(copytext(token(i), 1, 2) in list("'", "\"")) + node += token(i) + + else + parse_error("Expected string but found '[token(i)]'") + + return i + 1 + +//array: '[' expression, expression, ... ']' +/datum/SDQL_parser/proc/array(var/i, var/list/node) + // Arrays get turned into this: list("[", list(exp_1a = exp_1b, ...), ...), "[" is to mark the next node as an array. + if(copytext(token(i), 1, 2) != "\[") + parse_error("Expected an array but found '[token(i)]'") + return i + 1 + + node += token(i) // Add the "[" + + var/list/expression_list = list() + + i++ + if(token(i) != "]") + var/list/temp_expression_list = list() + var/tok + do + tok = token(i) + if (tok == "," || tok == ":") + if (temp_expression_list == null) + parse_error("Found ',' or ':' without expression in an array.") + return i + 1 + + expression_list[++expression_list.len] = temp_expression_list + temp_expression_list = null + if (tok == ":") + temp_expression_list = list() + i = expression(i + 1, temp_expression_list) + expression_list[expression_list[expression_list.len]] = temp_expression_list + temp_expression_list = null + tok = token(i) + if (tok != ",") + if (tok == "]") + break + + parse_error("Expected ',' or ']' after array assoc value, but found '[token(i)]'") + return i + + + i++ + continue + + temp_expression_list = list() + i = expression(i, temp_expression_list) + + // Ok, what the fuck BYOND? + // Not having these lines here causes the parser to die + // on an error saying that list/token() doesn't exist as a proc. + // These lines prevent that. + // I assume the compiler/VM is shitting itself and swapping out some variables internally? + // While throwing in debug logging it disappeared + // And these 3 lines prevent it from happening while being quiet. + // So.. it works. + // Don't touch it. + var/whatthefuck = i + whatthefuck = src.type + whatthefuck = whatthefuck + + while(token(i) && token(i) != "]") + + if (temp_expression_list) + expression_list[++expression_list.len] = temp_expression_list + + node[++node.len] = expression_list + + return i + 1 + +//call_function: ['(' [arguments] ')'] +/datum/SDQL_parser/proc/call_function(i, list/node, list/arguments) + if(length(tokenl(i))) + var/procname = "" + if(tokenl(i) == "global" && token(i + 1) == ".") // Global proc. + i += 2 + procname = "global." + node += procname + token(i++) + if(token(i) != "(") + parse_error("Expected ( but found '[token(i)]'") + + else if(token(i + 1) != ")") + var/list/temp_expression_list = list() + do + i = expression(i + 1, temp_expression_list) + if(token(i) == ",") + arguments[++arguments.len] = temp_expression_list + temp_expression_list = list() + continue + + while(token(i) && token(i) != ")") + + arguments[++arguments.len] = temp_expression_list // The code this is copy pasted from won't be executed when it's the last param, this fixes that. + else + i++ + else + parse_error("Expected a function but found nothing") + return i + 1 + + +//expression: ( unary_expression | '(' expression ')' | value ) [binary_operator expression] +/datum/SDQL_parser/proc/expression(i, list/node) + + if(token(i) in unary_operators) + i = unary_expression(i, node) + + else if(token(i) == "(") + var/list/expr = list() + + i = expression(i + 1, expr) + + if(token(i) != ")") + parse_error("Missing ) at end of expression.") + + else + i++ + + node[++node.len] = expr + + else + i = value(i, node) + + if(token(i) in binary_operators) + i = binary_operator(i, node) + i = expression(i, node) + + else if(token(i) in comparitors) + i = binary_operator(i, node) + + var/list/rhs = list() + i = expression(i, rhs) + + node[++node.len] = rhs + + + return i + + +//unary_expression: unary_operator ( unary_expression | value | '(' expression ')' ) +/datum/SDQL_parser/proc/unary_expression(i, list/node) + + if(token(i) in unary_operators) + var/list/unary_exp = list() + + unary_exp += token(i) + i++ + + if(token(i) in unary_operators) + i = unary_expression(i, unary_exp) + + else if(token(i) == "(") + var/list/expr = list() + + i = expression(i + 1, expr) + + if(token(i) != ")") + parse_error("Missing ) at end of expression.") + + else + i++ + + unary_exp[++unary_exp.len] = expr + + else + i = value(i, unary_exp) + + node[++node.len] = unary_exp + + + else + parse_error("Expected unary operator but found '[token(i)]'") + + return i + + +//binary_operator: comparitor | '+' | '-' | '/' | '*' | '&' | '|' | '^' | '%' +/datum/SDQL_parser/proc/binary_operator(i, list/node) + + if(token(i) in (binary_operators + comparitors)) + node += token(i) + + else + parse_error("Unknown binary operator [token(i)]") + + return i + 1 + + +//value: variable | string | number | 'null' | object_type +/datum/SDQL_parser/proc/value(i, list/node) + if(token(i) == "null") + node += "null" + i++ + + else if(lowertext(copytext(token(i), 1, 3)) == "0x" && isnum(hex2num(copytext(token(i), 3)))) + node += hex2num(copytext(token(i), 3)) + i++ + + else if(isnum(text2num(token(i)))) + node += text2num(token(i)) + i++ + + else if(copytext(token(i), 1, 2) in list("'", "\"")) + i = string(i, node) + + else if(copytext(token(i), 1, 2) == "\[") // Start a list. + i = array(i, node) + else if(copytext(token(i), 1, 2) == "/") + i = object_type(i, node) + else + i = variable(i, node) + + return i \ No newline at end of file diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm b/code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm new file mode 100644 index 0000000000..efca1ea17e --- /dev/null +++ b/code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm @@ -0,0 +1,215 @@ +// Wrappers for BYOND default procs which can't directly be called by call(). + +/proc/_abs(A) + return abs(A) + +/proc/_animate(atom/A, set_vars, time = 10, loop = 1, easing = LINEAR_EASING, flags = null) + var/mutable_appearance/MA = new() + for(var/v in set_vars) + MA.vars[v] = set_vars[v] + animate(A, appearance = MA, time, loop, easing, flags) + +/proc/_acrccos(A) + return arccos(A) + +/proc/_arcsin(A) + return arcsin(A) + +/proc/_ascii2text(A) + return ascii2text(A) + +/proc/_block(Start, End) + return block(Start, End) + +/proc/_ckey(Key) + return ckey(Key) + +/proc/_ckeyEx(Key) + return ckeyEx(Key) + +/proc/_copytext(T, Start = 1, End = 0) + return copytext(T, Start, End) + +/proc/_cos(X) + return cos(X) + +/proc/_get_dir(Loc1, Loc2) + return get_dir(Loc1, Loc2) + +/proc/_get_dist(Loc1, Loc2) + return get_dist(Loc1, Loc2) + +/proc/_get_step(Ref, Dir) + return get_step(Ref, Dir) + +/proc/_hearers(Depth = world.view, Center = usr) + return hearers(Depth, Center) + +/proc/_image(icon, loc, icon_state, layer, dir) + return image(icon, loc, icon_state, layer, dir) + +/proc/_istype(object, type) + return istype(object, type) + +/proc/_ispath(path, type) + return ispath(path, type) + +/proc/_length(E) + return length(E) + +/proc/_link(thing, url) + thing << link(url) + +/proc/_locate(X, Y, Z) + if (isnull(Y)) // Assuming that it's only a single-argument call. + return locate(X) + + return locate(X, Y, Z) + +/proc/_log(X, Y) + return log(X, Y) + +/proc/_lowertext(T) + return lowertext(T) + +/proc/_matrix(a, b, c, d, e, f) + return matrix(a, b, c, d, e, f) + +/proc/_max(...) + return max(arglist(args)) + +/proc/_md5(T) + return md5(T) + +/proc/_min(...) + return min(arglist(args)) + +/proc/_new(type, arguments) + return new type (arglist(arguments)) + +/proc/_num2text(N, SigFig = 6) + return num2text(N, SigFig) + +/proc/_ohearers(Dist, Center = usr) + return ohearers(Dist, Center) + +/proc/_orange(Dist, Center = usr) + return orange(Dist, Center) + +/proc/_output(thing, msg, control) + thing << output(msg, control) + +/proc/_oview(Dist, Center = usr) + return oview(Dist, Center) + +/proc/_oviewers(Dist, Center = usr) + return oviewers(Dist, Center) + +/proc/_params2list(Params) + return params2list(Params) + +/proc/_pick(...) + return pick(arglist(args)) + +/proc/_prob(P) + return prob(P) + +/proc/_rand(L = 0, H = 1) + return rand(L, H) + +/proc/_range(Dist, Center = usr) + return range(Dist, Center) + +/proc/_regex(pattern, flags) + return regex(pattern, flags) + +/proc/_REGEX_QUOTE(text) + return REGEX_QUOTE(text) + +/proc/_REGEX_QUOTE_REPLACEMENT(text) + return REGEX_QUOTE_REPLACEMENT(text) + +/proc/_replacetext(Haystack, Needle, Replacement, Start = 1,End = 0) + return replacetext(Haystack, Needle, Replacement, Start, End) + +/proc/_replacetextEx(Haystack, Needle, Replacement, Start = 1,End = 0) + return replacetextEx(Haystack, Needle, Replacement, Start, End) + +/proc/_rgb(R, G, B) + return rgb(R, G, B) + +/proc/_rgba(R, G, B, A) + return rgb(R, G, B, A) + +/proc/_roll(dice) + return roll(dice) + +/proc/_round(A, B = 1) + return round(A, B) + +/proc/_sin(X) + return sin(X) + +/proc/_list_add(list/L, ...) + if (args.len < 2) + return + L += args.Copy(2) + +/proc/_list_copy(list/L, Start = 1, End = 0) + return L.Copy(Start, End) + +/proc/_list_cut(list/L, Start = 1, End = 0) + L.Cut(Start, End) + +/proc/_list_find(list/L, Elem, Start = 1, End = 0) + return L.Find(Elem, Start, End) + +/proc/_list_insert(list/L, Index, Item) + return L.Insert(Index, Item) + +/proc/_list_join(list/L, Glue, Start = 0, End = 1) + return L.Join(Glue, Start, End) + +/proc/_list_remove(list/L, ...) + if (args.len < 2) + return + L -= args.Copy(2) + +/proc/_list_set(list/L, key, value) + L[key] = value + +/proc/_list_numerical_add(L, key, num) + L[key] += num + +/proc/_list_swap(list/L, Index1, Index2) + L.Swap(Index1, Index2) + +/proc/_walk(ref, dir, lag) + walk(ref, dir, lag) + +/proc/_walk_towards(ref, trg, lag) + walk_towards(ref, trg, lag) + +/proc/_walk_to(ref, trg, min, lag) + walk_to(ref, trg, min, lag) + +/proc/_walk_away(ref, trg, max, lag) + walk_away(ref, trg, max, lag) + +/proc/_walk_rand(ref, lag) + walk_rand(ref, lag) + +/proc/_step(ref, dir) + step(ref, dir) + +/proc/_step_rand(ref) + step_rand(ref) + +/proc/_step_to(ref, trg, min) + step_to(ref, trg, min) + +/proc/_step_towards(ref, trg) + step_towards(ref, trg) + +/proc/_step_away(ref, trg, max) + step_away(ref, trg, max) diff --git a/code/modules/admin/verbs/SDQL_2.dm b/code/modules/admin/verbs/SDQL_2.dm deleted file mode 100644 index aa138e62ea..0000000000 --- a/code/modules/admin/verbs/SDQL_2.dm +++ /dev/null @@ -1,426 +0,0 @@ - - -/client/proc/SDQL2_query(query_text as message) - set category = "Admin" - if(!check_rights(R_DEBUG)) //Shouldn't happen... but just to be safe. - message_admins("ERROR: Non-admin [usr.key] attempted to execute a SDQL query!") - log_admin("Non-admin [usr.key] attempted to execute a SDQL query!") - - if(!query_text || length(query_text) < 1) - return - - //world << query_text - - var/list/query_list = SDQL2_tokenize(query_text) - - if(!query_list || query_list.len < 1) - return - - var/list/query_tree = SDQL_parse(query_list) - - if(query_tree.len < 1) - return - - var/list/from_objs = list() - var/list/select_types = list() - - switch(query_tree[1]) - if("explain") - SDQL_testout(query_tree["explain"]) - return - - if("call") - if("on" in query_tree) - select_types = query_tree["on"] - else - return - - if("select", "delete", "update") - select_types = query_tree[query_tree[1]] - - from_objs = SDQL_from_objs(query_tree["from"]) - - var/list/objs = list() - - for(var/type in select_types) - var/char = copytext(type, 1, 2) - - if(char == "/" || char == "*") - for(var/from in from_objs) - objs += SDQL_get_all(type, from) - - else if(char == "'" || char == "\"") - objs += locate(copytext(type, 2, length(type))) - - if("where" in query_tree) - var/objs_temp = objs - objs = list() - for(var/datum/d in objs_temp) - if(SDQL_expression(d, query_tree["where"])) - objs += d - - //usr << "Query: [query_text]" - message_admins("[usr] executed SDQL query: \"[query_text]\".") - - switch(query_tree[1]) - if("delete") - for(var/datum/d in objs) - qdel(d) - - if("select") - var/text = "" - for(var/datum/t in objs) - if(istype(t, /atom)) - var/atom/a = t - - if(a.x) - text += "\ref[t]: [t] at ([a.x], [a.y], [a.z])
" - - else if(a.loc && a.loc.x) - text += "\ref[t]: [t] in [a.loc] at ([a.loc.x], [a.loc.y], [a.loc.z])
" - - else - text += "\ref[t]: [t]
" - - else - text += "\ref[t]: [t]
" - - usr << browse(text, "window=SDQL-result") - - if("update") - if("set" in query_tree) - var/list/set_list = query_tree["set"] - for(var/datum/d in objs) - var/list/vals = list() - for(var/v in set_list) - if(v in d.vars) - vals += v - vals[v] = SDQL_expression(d, set_list[v]) - - if(istype(d, /turf)) - for(var/v in vals) - if(v == "x" || v == "y" || v == "z") - continue - - d.vars[v] = vals[v] - - else - for(var/v in vals) - d.vars[v] = vals[v] - - - - - -/proc/SDQL_parse(list/query_list) - var/datum/SDQL_parser/parser = new(query_list) - var/list/query_tree = parser.parse() - - qdel(parser) - - return query_tree - - - -/proc/SDQL_testout(list/query_tree, indent = 0) - var/spaces = "" - for(var/s = 0, s < indent, s++) - spaces += " " - - for(var/item in query_tree) - if(istype(item, /list)) - world << "[spaces](" - SDQL_testout(item, indent + 1) - world << "[spaces])" - - else - world << "[spaces][item]" - - if(!isnum(item) && query_tree[item]) - - if(istype(query_tree[item], /list)) - world << "[spaces] (" - SDQL_testout(query_tree[item], indent + 2) - world << "[spaces] )" - - else - world << "[spaces] [query_tree[item]]" - - - -/proc/SDQL_from_objs(list/tree) - if("world" in tree) - return list(world) - - var/list/out = list() - - for(var/type in tree) - var/char = copytext(type, 1, 2) - - if(char == "/") - out += SDQL_get_all(type, world) - - else if(char == "'" || char == "\"") - out += locate(copytext(type, 2, length(type))) - - return out - - -/proc/SDQL_get_all(type, location) - var/list/out = list() - - if(type == "*") - for(var/datum/d in location) - out += d - - return out - - type = text2path(type) - - if(ispath(type, /mob)) - for(var/mob/d in location) - if(istype(d, type)) - out += d - - else if(ispath(type, /turf)) - for(var/turf/d in location) - if(istype(d, type)) - out += d - - else if(ispath(type, /obj)) - for(var/obj/d in location) - if(istype(d, type)) - out += d - - else if(ispath(type, /area)) - for(var/area/d in location) - if(istype(d, type)) - out += d - - else if(ispath(type, /atom)) - for(var/atom/d in location) - if(istype(d, type)) - out += d - - else - for(var/datum/d in location) - if(istype(d, type)) - out += d - - return out - - -/proc/SDQL_expression(datum/object, list/expression, start = 1) - var/result = 0 - var/val - - for(var/i = start, i <= expression.len, i++) - var/op = "" - - if(i > start) - op = expression[i] - i++ - - var/list/ret = SDQL_value(object, expression, i) - val = ret["val"] - i = ret["i"] - - if(op != "") - switch(op) - if("+") - result += val - if("-") - result -= val - if("*") - result *= val - if("/") - result /= val - if("&") - result &= val - if("|") - result |= val - if("^") - result ^= val - if("=", "==") - result = (result == val) - if("!=", "<>") - result = (result != val) - if("<") - result = (result < val) - if("<=") - result = (result <= val) - if(">") - result = (result > val) - if(">=") - result = (result >= val) - if("and", "&&") - result = (result && val) - if("or", "||") - result = (result || val) - else - usr << "SDQL2: Unknown op [op]" - result = null - else - result = val - - return result - -/proc/SDQL_value(datum/object, list/expression, start = 1) - var/i = start - var/val = null - - if(i > expression.len) - return list("val" = null, "i" = i) - - if(istype(expression[i], /list)) - val = SDQL_expression(object, expression[i]) - - else if(expression[i] == "!") - var/list/ret = SDQL_value(object, expression, i + 1) - val = !ret["val"] - i = ret["i"] - - else if(expression[i] == "~") - var/list/ret = SDQL_value(object, expression, i + 1) - val = ~ret["val"] - i = ret["i"] - - else if(expression[i] == "-") - var/list/ret = SDQL_value(object, expression, i + 1) - val = -ret["val"] - i = ret["i"] - - else if(expression[i] == "null") - val = null - - else if(isnum(expression[i])) - val = expression[i] - - else if(copytext(expression[i], 1, 2) in list("'", "\"")) - val = copytext(expression[i], 2, length(expression[i])) - - else - val = SDQL_var(object, expression, i) - i = expression.len - - return list("val" = val, "i" = i) - -/proc/SDQL_var(datum/object, list/expression, start = 1) - - if(expression[start] in object.vars) - - if(start < expression.len && expression[start + 1] == ".") - return SDQL_var(object.vars[expression[start]], expression[start + 2]) - - else - return object.vars[expression[start]] - - else - return null - -/proc/SDQL2_tokenize(query_text) - - var/list/whitespace = list(" ", "\n", "\t") - var/list/single = list("(", ")", ",", "+", "-", ".") - var/list/multi = list( - "=" = list("", "="), - "<" = list("", "=", ">"), - ">" = list("", "="), - "!" = list("", "=")) - - var/word = "" - var/list/query_list = list() - var/len = length(query_text) - - for(var/i = 1, i <= len, i++) - var/char = copytext(query_text, i, i + 1) - - if(char in whitespace) - if(word != "") - query_list += word - word = "" - - else if(char in single) - if(word != "") - query_list += word - word = "" - - query_list += char - - else if(char in multi) - if(word != "") - query_list += word - word = "" - - var/char2 = copytext(query_text, i + 1, i + 2) - - if(char2 in multi[char]) - query_list += "[char][char2]" - i++ - - else - query_list += char - - else if(char == "'") - if(word != "") - usr << "SDQL2: You have an error in your SDQL syntax, unexpected ' in query: \"[query_text]\" following \"[word]\". Please check your syntax, and try again." - return null - - word = "'" - - for(i++, i <= len, i++) - char = copytext(query_text, i, i + 1) - - if(char == "'") - if(copytext(query_text, i + 1, i + 2) == "'") - word += "'" - i++ - - else - break - - else - word += char - - if(i > len) - usr << "SDQL2: You have an error in your SDQL syntax, unmatched ' in query: \"[query_text]\". Please check your syntax, and try again." - return null - - query_list += "[word]'" - word = "" - - else if(char == "\"") - if(word != "") - usr << "SDQL2: You have an error in your SDQL syntax, unexpected \" in query: \"[query_text]\" following \"[word]\". Please check your syntax, and try again." - return null - - word = "\"" - - for(i++, i <= len, i++) - char = copytext(query_text, i, i + 1) - - if(char == "\"") - if(copytext(query_text, i + 1, i + 2) == "'") - word += "\"" - i++ - - else - break - - else - word += char - - if(i > len) - usr << "SDQL2: You have an error in your SDQL syntax, unmatched \" in query: \"[query_text]\". Please check your syntax, and try again." - return null - - query_list += "[word]\"" - word = "" - - else - word += char - - if(word != "") - query_list += word - - return query_list diff --git a/code/modules/admin/verbs/SDQL_2_parser.dm b/code/modules/admin/verbs/SDQL_2_parser.dm deleted file mode 100644 index b97d256584..0000000000 --- a/code/modules/admin/verbs/SDQL_2_parser.dm +++ /dev/null @@ -1,531 +0,0 @@ -//I'm pretty sure that this is a recursive [s]descent[/s] ascent parser. - - - -//Spec - -////////// -// -// query : select_query | delete_query | update_query | call_query | explain -// explain : 'EXPLAIN' query -// -// select_query : 'SELECT' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression] -// delete_query : 'DELETE' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression] -// update_query : 'UPDATE' select_list [('FROM' | 'IN') from_list] 'SET' assignments ['WHERE' bool_expression] -// call_query : 'CALL' call_function ['ON' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]] -// -// select_list : select_item [',' select_list] -// select_item : '*' | select_function | object_type -// select_function : count_function -// count_function : 'COUNT' '(' '*' ')' | 'COUNT' '(' object_types ')' -// -// from_list : from_item [',' from_list] -// from_item : 'world' | object_type -// -// call_function : ['(' [arguments] ')'] -// arguments : expression [',' arguments] -// -// object_type : | string -// -// assignments : assignment, [',' assignments] -// assignment : '=' expression -// variable : | '.' variable -// -// bool_expression : expression comparitor expression [bool_operator bool_expression] -// expression : ( unary_expression | '(' expression ')' | value ) [binary_operator expression] -// unary_expression : unary_operator ( unary_expression | value | '(' expression ')' ) -// comparitor : '=' | '==' | '!=' | '<>' | '<' | '<=' | '>' | '>=' -// value : variable | string | number | 'null' -// unary_operator : '!' | '-' | '~' -// binary_operator : comparitor | '+' | '-' | '/' | '*' | '&' | '|' | '^' -// bool_operator : 'AND' | '&&' | 'OR' | '||' -// -// string : ''' ''' | '"' '"' -// number : -// -////////// - -/datum/SDQL_parser - var/query_type - var/error = 0 - - var/list/query - var/list/tree - - var/list/select_functions = list("count") - var/list/boolean_operators = list("and", "or", "&&", "||") - var/list/unary_operators = list("!", "-", "~") - var/list/binary_operators = list("+", "-", "/", "*", "&", "|", "^") - var/list/comparitors = list("=", "==", "!=", "<>", "<", "<=", ">", ">=") - - - -/datum/SDQL_parser/New(query_list) - query = query_list - - - -/datum/SDQL_parser/proc/parse_error(error_message) - error = 1 - usr << "SQDL2 Parsing Error: [error_message]" - return query.len + 1 - -/datum/SDQL_parser/proc/parse() - tree = list() - query(1, tree) - - if(error) - return list() - else - return tree - -/datum/SDQL_parser/proc/token(i) - if(i <= query.len) - return query[i] - - else - return null - -/datum/SDQL_parser/proc/tokens(i, num) - if(i + num <= query.len) - return query.Copy(i, i + num) - - else - return null - -/datum/SDQL_parser/proc/tokenl(i) - return lowertext(token(i)) - - - -/datum/SDQL_parser/proc - -//query: select_query | delete_query | update_query - query(i, list/node) - query_type = tokenl(i) - - switch(query_type) - if("select") - select_query(i, node) - - if("delete") - delete_query(i, node) - - if("update") - update_query(i, node) - - if("call") - call_query(i, node) - - if("explain") - node += "explain" - node["explain"] = list() - query(i + 1, node["explain"]) - - -// select_query: 'SELECT' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression] - select_query(i, list/node) - var/list/select = list() - i = select_list(i + 1, select) - - node += "select" - node["select"] = select - - var/list/from = list() - if(tokenl(i) in list("from", "in")) - i = from_list(i + 1, from) - else - from += "world" - - node += "from" - node["from"] = from - - if(tokenl(i) == "where") - var/list/where = list() - i = bool_expression(i + 1, where) - - node += "where" - node["where"] = where - - return i - - -//delete_query: 'DELETE' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression] - delete_query(i, list/node) - var/list/select = list() - i = select_list(i + 1, select) - - node += "delete" - node["delete"] = select - - var/list/from = list() - if(tokenl(i) in list("from", "in")) - i = from_list(i + 1, from) - else - from += "world" - - node += "from" - node["from"] = from - - if(tokenl(i) == "where") - var/list/where = list() - i = bool_expression(i + 1, where) - - node += "where" - node["where"] = where - - return i - - -//update_query: 'UPDATE' select_list [('FROM' | 'IN') from_list] 'SET' assignments ['WHERE' bool_expression] - update_query(i, list/node) - var/list/select = list() - i = select_list(i + 1, select) - - node += "update" - node["update"] = select - - var/list/from = list() - if(tokenl(i) in list("from", "in")) - i = from_list(i + 1, from) - else - from += "world" - - node += "from" - node["from"] = from - - if(tokenl(i) != "set") - i = parse_error("UPDATE has misplaced SET") - - var/list/set_assignments = list() - i = assignments(i + 1, set_assignments) - - node += "set" - node["set"] = set_assignments - - if(tokenl(i) == "where") - var/list/where = list() - i = bool_expression(i + 1, where) - - node += "where" - node["where"] = where - - return i - - -//call_query: 'CALL' call_function ['ON' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]] - call_query(i, list/node) - var/list/func = list() - i = call_function(i + 1, func) - - node += "call" - node["call"] = func - - if(tokenl(i) != "on") - return i - - var/list/select = list() - i = select_list(i + 1, select) - - node += "on" - node["on"] = select - - var/list/from = list() - if(tokenl(i) in list("from", "in")) - i = from_list(i + 1, from) - else - from += "world" - - node += "from" - node["from"] = from - - if(tokenl(i) == "where") - var/list/where = list() - i = bool_expression(i + 1, where) - - node += "where" - node["where"] = where - - return i - - -//select_list: select_item [',' select_list] - select_list(i, list/node) - i = select_item(i, node) - - if(token(i) == ",") - i = select_list(i + 1, node) - - return i - - -//from_list: from_item [',' from_list] - from_list(i, list/node) - i = from_item(i, node) - - if(token(i) == ",") - i = from_list(i + 1, node) - - return i - - -//assignments: assignment, [',' assignments] - assignments(i, list/node) - i = assignment(i, node) - - if(token(i) == ",") - i = assignments(i + 1, node) - - return i - - -//select_item: '*' | select_function | object_type - select_item(i, list/node) - - if(token(i) == "*") - node += "*" - i++ - - else if(tokenl(i) in select_functions) - i = select_function(i, node) - - else - i = object_type(i, node) - - return i - - -//from_item: 'world' | object_type - from_item(i, list/node) - - if(token(i) == "world") - node += "world" - i++ - - else - i = object_type(i, node) - - return i - - -//bool_expression: expression [bool_operator bool_expression] - bool_expression(i, list/node) - - var/list/bool = list() - i = expression(i, bool) - - node[++node.len] = bool - - if(tokenl(i) in boolean_operators) - i = bool_operator(i, node) - i = bool_expression(i, node) - - return i - - -//assignment: '=' expression - assignment(i, list/node) - - node += token(i) - - if(token(i + 1) == "=") - var/varname = token(i) - node[varname] = list() - - i = expression(i + 2, node[varname]) - - else - parse_error("Assignment expected, but no = found") - - return i - - -//variable: | '.' variable - variable(i, list/node) - var/list/L = list(token(i)) - node[++node.len] = L - - if(token(i + 1) == ".") - L += "." - i = variable(i + 2, L) - - else - i++ - - return i - - -//object_type: | string - object_type(i, list/node) - - if(copytext(token(i), 1, 2) == "/") - node += token(i) - - else - i = string(i, node) - - return i + 1 - - -//comparitor: '=' | '==' | '!=' | '<>' | '<' | '<=' | '>' | '>=' - comparitor(i, list/node) - - if(token(i) in list("=", "==", "!=", "<>", "<", "<=", ">", ">=")) - node += token(i) - - else - parse_error("Unknown comparitor [token(i)]") - - return i + 1 - - -//bool_operator: 'AND' | '&&' | 'OR' | '||' - bool_operator(i, list/node) - - if(tokenl(i) in list("and", "or", "&&", "||")) - node += token(i) - - else - parse_error("Unknown comparitor [token(i)]") - - return i + 1 - - -//string: ''' ''' | '"' '"' - string(i, list/node) - - if(copytext(token(i), 1, 2) in list("'", "\"")) - node += token(i) - - else - parse_error("Expected string but found '[token(i)]'") - - return i + 1 - - -//call_function: ['(' [arguments] ')'] - call_function(i, list/node) - - parse_error("Sorry, function calls aren't available yet") - - return i - - -//select_function: count_function - select_function(i, list/node) - - parse_error("Sorry, function calls aren't available yet") - - return i - - -//expression: ( unary_expression | '(' expression ')' | value ) [binary_operator expression] - expression(i, list/node) - - if(token(i) in unary_operators) - i = unary_expression(i, node) - - else if(token(i) == "(") - var/list/expr = list() - - i = expression(i + 1, expr) - - if(token(i) != ")") - parse_error("Missing ) at end of expression.") - - else - i++ - - node[++node.len] = expr - - else - i = value(i, node) - - if(token(i) in binary_operators) - i = binary_operator(i, node) - i = expression(i, node) - - else if(token(i) in comparitors) - i = binary_operator(i, node) - - var/list/rhs = list() - i = expression(i, rhs) - - node[++node.len] = rhs - - - return i - - -//unary_expression: unary_operator ( unary_expression | value | '(' expression ')' ) - unary_expression(i, list/node) - - if(token(i) in unary_operators) - var/list/unary_exp = list() - - unary_exp += token(i) - i++ - - if(token(i) in unary_operators) - i = unary_expression(i, unary_exp) - - else if(token(i) == "(") - var/list/expr = list() - - i = expression(i + 1, expr) - - if(token(i) != ")") - parse_error("Missing ) at end of expression.") - - else - i++ - - unary_exp[++unary_exp.len] = expr - - else - i = value(i, unary_exp) - - node[++node.len] = unary_exp - - - else - parse_error("Expected unary operator but found '[token(i)]'") - - return i - - -//binary_operator: comparitor | '+' | '-' | '/' | '*' | '&' | '|' | '^' - binary_operator(i, list/node) - - if(token(i) in (binary_operators + comparitors)) - node += token(i) - - else - parse_error("Unknown binary operator [token(i)]") - - return i + 1 - - -//value: variable | string | number | 'null' - value(i, list/node) - - if(token(i) == "null") - node += "null" - i++ - - else if(isnum(text2num(token(i)))) - node += text2num(token(i)) - i++ - - else if(copytext(token(i), 1, 2) in list("'", "\"")) - i = string(i, node) - - else - i = variable(i, node) - - return i - - - - -/*EXPLAIN SELECT * WHERE 42 = 6 * 9 OR val = - 5 == 7*/ \ No newline at end of file diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index 0327e0c84a..a6e50cb108 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -343,8 +343,8 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) return var/msg = "- AdminHelp marked as IC issue! -
" - msg += "This is something that can be solved ICly, and does not currently require admin intervention.
" //VOREStation Edit - msg += "Your AdminHelp may also be unable to be answered due to ongoing events." //VOREStation Edit + msg += "This is something that can be solved ICly, and does not currently require staff intervention.
" + msg += "Your AdminHelp may also be unanswerable due to ongoing events." if(initiator) to_chat(initiator, msg) diff --git a/code/modules/admin/verbs/buildmode.dm b/code/modules/admin/verbs/buildmode.dm index a57b17d15f..4cfa952b67 100644 --- a/code/modules/admin/verbs/buildmode.dm +++ b/code/modules/admin/verbs/buildmode.dm @@ -127,6 +127,18 @@ usr << "Right Mouse Button on turf/obj/mob = Reset glowing" usr << "Right Mouse Button on buildmode button = Change glow properties" usr << "***********************************************************" + if(9) // Control mobs with ai_holders. + usr << "***********************************************************" + usr << "Left Mouse Button on AI mob = Select/Deselect mob" + usr << "Left Mouse Button + alt on AI mob = Toggle hostility on mob" + usr << "Left Mouse Button + ctrl on AI mob = Reset target/following/movement" + usr << "Right Mouse Button on enemy mob = Command selected mobs to attack mob" + usr << "Right Mouse Button on allied mob = Command selected mobs to follow mob" + usr << "Right Mouse Button + shift on any mob = Command selected mobs to follow mob regardless of faction" + usr << "Right Mouse Button on tile = Command selected mobs to move to tile (will cancel if enemies are seen)" + usr << "Right Mouse Button + shift on tile = Command selected mobs to reposition to tile (will not be inturrupted by enemies)" + usr << "Right Mouse Button + alt on obj/turfs = Command selected mobs to attack obj/turf" + usr << "***********************************************************" return 1 /obj/effect/bmode/buildquit @@ -146,6 +158,7 @@ var/obj/effect/bmode/buildmode/buildmode = null var/obj/effect/bmode/buildquit/buildquit = null var/atom/movable/throw_atom = null + var/list/selected_mobs = list() /obj/effect/bmode/buildholder/Destroy() qdel(builddir) @@ -157,9 +170,21 @@ qdel(buildquit) buildquit = null throw_atom = null + for(var/mob/living/unit in selected_mobs) + deselect_AI_mob(cl, unit) + selected_mobs.Cut() cl = null return ..() +/obj/effect/bmode/buildholder/proc/select_AI_mob(client/C, mob/living/unit) + selected_mobs += unit + C.images += unit.selected_image + +/obj/effect/bmode/buildholder/proc/deselect_AI_mob(client/C, mob/living/unit) + selected_mobs -= unit + C.images -= unit.selected_image + + /obj/effect/bmode/buildmode icon_state = "buildmode1" screen_loc = "NORTH,WEST+2" @@ -210,6 +235,9 @@ master.cl.buildmode = 8 src.icon_state = "buildmode8" if(8) + master.cl.buildmode = 9 + src.icon_state = "buildmode9" + if(9) master.cl.buildmode = 1 src.icon_state = "buildmode1" @@ -416,6 +444,86 @@ if(pa.Find("right")) if(object) object.set_light(0, 0, "#FFFFFF") + if(9) // AI control + if(pa.Find("left")) + if(isliving(object)) + var/mob/living/L = object + // Reset processes. + if(pa.Find("ctrl")) + if(!isnull(L.get_AI_stance())) // Null means there's no AI datum or it has one but is player controlled w/o autopilot on. + var/datum/ai_holder/AI = L.ai_holder + AI.forget_everything() + to_chat(user, span("notice", "\The [L]'s AI has forgotten its target/movement destination/leader.")) + else + to_chat(user, span("warning", "\The [L] is not AI controlled.")) + return + + // Toggle hostility + if(pa.Find("alt")) + if(!isnull(L.get_AI_stance())) + var/datum/ai_holder/AI = L.ai_holder + AI.hostile = !AI.hostile + to_chat(user, span("notice", "\The [L] is now [AI.hostile ? "hostile" : "passive"].")) + else + to_chat(user, span("warning", "\The [L] is not AI controlled.")) + return + + // Select/Deselect + if(!isnull(L.get_AI_stance())) + if(L in holder.selected_mobs) + holder.deselect_AI_mob(user.client, L) + to_chat(user, span("notice", "Deselected \the [L].")) + else + holder.select_AI_mob(user.client, L) + to_chat(user, span("notice", "Selected \the [L].")) + else + to_chat(user, span("warning", "\The [L] is not AI controlled.")) + + if(pa.Find("right")) + if(istype(object, /atom)) // Force attack. + var/atom/A = object + + if(pa.Find("alt")) + var/i = 0 + for(var/mob/living/unit in holder.selected_mobs) + var/datum/ai_holder/AI = unit.ai_holder + AI.give_target(A) + i++ + to_chat(user, span("notice", "Commanded [i] mob\s to attack \the [A].")) + return + + if(isliving(object)) // Follow or attack. + var/mob/living/L = object + var/i = 0 // Attacking mobs. + var/j = 0 // Following mobs. + for(var/mob/living/unit in holder.selected_mobs) + var/datum/ai_holder/AI = unit.ai_holder + if(L.IIsAlly(unit) || !AI.hostile || pa.Find("shift")) + AI.set_follow(L) + j++ + else + AI.give_target(L) + i++ + var/message = "Commanded " + if(i) + message += "[i] mob\s to attack \the [L]" + if(j) + message += ", and " + else + message += "." + if(j) + message += "[j] mob\s to follow \the [L]." + to_chat(user, span("notice", message)) + + if(isturf(object)) // Move or reposition. + var/turf/T = object + var/i = 0 + for(var/mob/living/unit in holder.selected_mobs) + var/datum/ai_holder/AI = unit.ai_holder + AI.give_destination(T, 1, pa.Find("shift")) // If shift is held, the mobs will not stop moving to attack a visible enemy. + i++ + to_chat(user, span("notice", "Commanded [i] mob\s to move to \the [T].")) + /obj/effect/bmode/buildmode/proc/get_path_from_partial_text(default_path) var/desired_path = input("Enter full or partial typepath.","Typepath","[default_path]") diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 482c9d8360..321655bb15 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -592,7 +592,7 @@ if("Dead Mobs") usr << jointext(dead_mob_list,",") if("Clients") - usr << jointext(clients,",") + usr << jointext(GLOB.clients,",") /client/proc/cmd_debug_using_map() set category = "Debug" diff --git a/code/modules/admin/verbs/getlogs.dm b/code/modules/admin/verbs/getlogs.dm index 3f6e4c9e74..9e9ad67027 100644 --- a/code/modules/admin/verbs/getlogs.dm +++ b/code/modules/admin/verbs/getlogs.dm @@ -27,7 +27,7 @@ src << "Only Admins may use this command." return - var/client/target = input(src,"Choose somebody to grant access to the server's runtime logs (permissions expire at the end of each round):","Grant Permissions",null) as null|anything in clients + var/client/target = input(src,"Choose somebody to grant access to the server's runtime logs (permissions expire at the end of each round):","Grant Permissions",null) as null|anything in GLOB.clients if(!istype(target,/client)) src << "Error: giveruntimelog(): Client not found." return @@ -99,7 +99,7 @@ set category = "Admin" set name = "Show Server Attack Log" set desc = "Shows today's server attack log." - + to_chat(usr,"This verb doesn't actually do anything.") /* @@ -113,4 +113,3 @@ feedback_add_details("admin_verb","SSAL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! return */ - \ No newline at end of file diff --git a/code/modules/admin/verbs/lightning_strike.dm b/code/modules/admin/verbs/lightning_strike.dm index 16cb6b06dd..6adb122d4a 100644 --- a/code/modules/admin/verbs/lightning_strike.dm +++ b/code/modules/admin/verbs/lightning_strike.dm @@ -1,115 +1,99 @@ -/client/proc/admin_lightning_strike() - set name = "Lightning Strike" - set desc = "Causes lightning to strike on your tile. This will hurt things on or nearby it severely." - set category = "Fun" - - if(!check_rights(R_FUN)) - return - - var/result = alert(src, "Really strike your tile with lightning?", "Confirm Badmin" , "No", "Yes (Cosmetic)", "Yes (Real)") - - if(result == "No") - return - var/fake_lightning = result == "Yes (Cosmetic)" - - lightning_strike(get_turf(usr), fake_lightning) - log_and_message_admins("[key_name(src)] has caused [fake_lightning ? "cosmetic":"harmful"] lightning to strike at their position ([src.mob.x], [src.mob.y], [src.mob.z]). \ - (JMP)") - -#define LIGHTNING_REDIRECT_RANGE 28 // How far in tiles certain things draw lightning from. -#define LIGHTNING_ZAP_RANGE 3 // How far the tesla effect zaps, as well as the bad effects from a direct strike. -#define LIGHTNING_POWER 20000 // How much 'zap' is in a strike, used for tesla_zap(). - -// The real lightning proc. -// This is global until I can figure out a better place for it. -// T is the turf that is being struck. If cosmetic is true, the lightning won't actually hurt anything. -/proc/lightning_strike(turf/T, cosmetic = FALSE) - // First, visuals. - - // Do a lightning flash for the whole planet, if the turf belongs to a planet. - var/datum/planet/P = null - P = SSplanets.z_to_planet[T.z] - if(P) - var/datum/weather_holder/holder = P.weather_holder - flick("lightning_flash", holder.special_visuals) - - // Before we do the other visuals, we need to see if something is going to hijack our intended target. - var/obj/machinery/power/grounding_rod/ground = null // Most of the bad effects of lightning will get negated if a grounding rod is nearby. - var/obj/machinery/power/tesla_coil/coil = null // However a tesla coil has higher priority and the strike will bounce. - - for(var/obj/machinery/power/thing in range(LIGHTNING_REDIRECT_RANGE, T)) - if(istype(thing, /obj/machinery/power/tesla_coil)) - var/turf/simulated/coil_turf = get_turf(thing) - if(istype(coil_turf) && thing.anchored && coil_turf.outdoors) - coil = thing - break - - if(istype(thing, /obj/machinery/power/grounding_rod)) - var/turf/simulated/rod_turf = get_turf(thing) - if(istype(rod_turf) && thing.anchored && rod_turf.outdoors) - ground = thing - - if(coil) // Coil gets highest priority. - T = coil.loc - else if(ground) - T = ground.loc - - // Now make the lightning strike sprite. It will fade and delete itself in a second. - new /obj/effect/temporary_effect/lightning_strike(T) - - // For those close up. - playsound(T, 'sound/effects/lightningbolt.ogg', 100, 1) - - // And for those far away. If the strike happens on a planet, everyone on the planet will hear it. - // Otherwise only those on the current z-level will hear it. - var/sound = get_sfx("thunder") - for(var/mob/M in player_list) - if((P && M.z in P.expected_z_levels) || M.z == T.z) - M.playsound_local(get_turf(M), soundin = sound, vol = 70, vary = FALSE, is_global = TRUE) - - if(cosmetic) // Everything beyond here involves potentially damaging things. If we don't want to do that, stop now. - return - - if(ground) // All is well. - ground.tesla_act(LIGHTNING_POWER, FALSE) - return - - else if(coil) // Otherwise lets bounce off the tesla coil. - coil.tesla_act(LIGHTNING_POWER, TRUE) - - else // Striking the turf directly. - tesla_zap(T, zap_range = LIGHTNING_ZAP_RANGE, power = LIGHTNING_POWER, explosive = FALSE, stun_mobs = TRUE) - - // Some extra effects. - // Some apply to those within zap range, others if they were a bit farther away. - for(var/mob/living/L in view(5, T)) - if(get_dist(L, T) <= LIGHTNING_ZAP_RANGE) // They probably got zapped. - // The actual damage/electrocution is handled by tesla_zap(). - L.Paralyse(5) - L.stuttering += 20 - L.make_jittery(20) - L.emp_act(1) - to_chat(L, span("critical", "You've been struck by lightning!")) - - // If a non-player simplemob was struck, inflict huge damage. - // If the damage is fatal, the SA is turned to ash. - if(istype(L, /mob/living/simple_animal) && !L.key) - var/mob/living/simple_animal/SA = L - SA.adjustFireLoss(200) - SA.updatehealth() - if(SA.health <= 0) // Might be best to check/give simple_mobs siemens when this gets ported to new mobs. - SA.visible_message(span("critical", "\The [SA] disintegrates into ash!")) - SA.ash() - continue // No point deafening something that wont exist. - - // Deafen them. - if(L.get_ear_protection() < 2) - L.AdjustSleeping(-100) - if(iscarbon(L)) - var/mob/living/carbon/C = L - C.ear_deaf += 10 - to_chat(L, span("danger", "Lightning struck nearby, and the thunderclap is deafening!")) - -#undef GROUNDING_ROD_RANGE -#undef LIGHTNING_ZAP_RANGE -#undef LIGHTNING_POWER \ No newline at end of file +/client/proc/admin_lightning_strike() + set name = "Lightning Strike" + set desc = "Causes lightning to strike on your tile. This will hurt things on or nearby it severely." + set category = "Fun" + + if(!check_rights(R_FUN)) + return + + var/result = alert(src, "Really strike your tile with lightning?", "Confirm Badmin" , "No", "Yes (Cosmetic)", "Yes (Real)") + + if(result == "No") + return + var/fake_lightning = result == "Yes (Cosmetic)" + + lightning_strike(get_turf(usr), fake_lightning) + log_and_message_admins("[key_name(src)] has caused [fake_lightning ? "cosmetic":"harmful"] lightning to strike at their position ([src.mob.x], [src.mob.y], [src.mob.z]). \ + (JMP)") + +#define LIGHTNING_REDIRECT_RANGE 28 // How far in tiles certain things draw lightning from. +#define LIGHTNING_ZAP_RANGE 3 // How far the tesla effect zaps, as well as the bad effects from a direct strike. +#define LIGHTNING_POWER 20000 // How much 'zap' is in a strike, used for tesla_zap(). + +// The real lightning proc. +// This is global until I can figure out a better place for it. +// T is the turf that is being struck. If cosmetic is true, the lightning won't actually hurt anything. +/proc/lightning_strike(turf/T, cosmetic = FALSE) + // First, visuals. + + // Do a lightning flash for the whole planet, if the turf belongs to a planet. + var/datum/planet/P = null + P = SSplanets.z_to_planet[T.z] + if(P) + var/datum/weather_holder/holder = P.weather_holder + flick("lightning_flash", holder.special_visuals) + + // Before we do the other visuals, we need to see if something is going to hijack our intended target. + var/obj/machinery/power/grounding_rod/ground = null // Most of the bad effects of lightning will get negated if a grounding rod is nearby. + var/obj/machinery/power/tesla_coil/coil = null // However a tesla coil has higher priority and the strike will bounce. + + for(var/obj/machinery/power/thing in range(LIGHTNING_REDIRECT_RANGE, T)) + if(istype(thing, /obj/machinery/power/tesla_coil)) + var/turf/simulated/coil_turf = get_turf(thing) + if(istype(coil_turf) && thing.anchored && coil_turf.outdoors) + coil = thing + break + + if(istype(thing, /obj/machinery/power/grounding_rod)) + var/turf/simulated/rod_turf = get_turf(thing) + if(istype(rod_turf) && thing.anchored && rod_turf.outdoors) + ground = thing + + if(coil) // Coil gets highest priority. + T = coil.loc + else if(ground) + T = ground.loc + + // Now make the lightning strike sprite. It will fade and delete itself in a second. + new /obj/effect/temporary_effect/lightning_strike(T) + + // For those close up. + playsound(T, 'sound/effects/lightningbolt.ogg', 100, 1) + + // And for those far away. If the strike happens on a planet, everyone on the planet will hear it. + // Otherwise only those on the current z-level will hear it. + var/sound = get_sfx("thunder") + for(var/mob/M in player_list) + if((P && M.z in P.expected_z_levels) || M.z == T.z) + M.playsound_local(get_turf(M), soundin = sound, vol = 70, vary = FALSE, is_global = TRUE) + + if(cosmetic) // Everything beyond here involves potentially damaging things. If we don't want to do that, stop now. + return + + if(ground) // All is well. + ground.tesla_act(LIGHTNING_POWER, FALSE) + return + + else if(coil) // Otherwise lets bounce off the tesla coil. + coil.tesla_act(LIGHTNING_POWER, TRUE) + + else // Striking the turf directly. + tesla_zap(T, zap_range = LIGHTNING_ZAP_RANGE, power = LIGHTNING_POWER, explosive = FALSE, stun_mobs = TRUE) + + // Some extra effects. + // Some apply to those within zap range, others if they were a bit farther away. + for(var/mob/living/L in view(5, T)) + if(get_dist(L, T) <= LIGHTNING_ZAP_RANGE) // They probably got zapped. + L.lightning_act() + + // Deafen them. + if(L.get_ear_protection() < 2) + L.AdjustSleeping(-100) + if(iscarbon(L)) + var/mob/living/carbon/C = L + C.ear_deaf += 10 + to_chat(L, span("danger", "Lightning struck nearby, and the thunderclap is deafening!")) + +#undef GROUNDING_ROD_RANGE +#undef LIGHTNING_ZAP_RANGE +#undef LIGHTNING_POWER diff --git a/code/modules/admin/verbs/map_template_loadverb.dm b/code/modules/admin/verbs/map_template_loadverb.dm index d0504e0223..aa525b8e12 100644 --- a/code/modules/admin/verbs/map_template_loadverb.dm +++ b/code/modules/admin/verbs/map_template_loadverb.dm @@ -5,15 +5,18 @@ var/datum/map_template/template - var/map = input(usr, "Choose a Map Template to place at your CURRENT LOCATION","Place Map Template") as null|anything in map_templates + var/map = input(usr, "Choose a Map Template to place at your CURRENT LOCATION","Place Map Template") as null|anything in SSmapping.map_templates if(!map) return - template = map_templates[map] + template = SSmapping.map_templates[map] var/orientation = text2dir(input(usr, "Choose an orientation for this Map Template.", "Orientation") as null|anything in list("North", "South", "East", "West")) if(!orientation) return + // Convert dir to degrees rotation + orientation = dir2angle(orientation) + var/turf/T = get_turf(mob) if(!T) return @@ -41,16 +44,19 @@ var/datum/map_template/template - var/map = input(usr, "Choose a Map Template to place on a new Z-level.","Place Map Template") as null|anything in map_templates + var/map = input(usr, "Choose a Map Template to place on a new Z-level.","Place Map Template") as null|anything in SSmapping.map_templates if(!map) return - template = map_templates[map] + template = SSmapping.map_templates[map] var/orientation = text2dir(input(usr, "Choose an orientation for this Map Template.", "Orientation") as null|anything in list("North", "South", "East", "West")) if(!orientation) return - if(((orientation & (NORTH|SOUTH) && template.width > world.maxx || template.height > world.maxy) || ((orientation & (EAST|WEST)) && template.width > world.maxy || template.height > world.maxx))) + // Convert dir to degrees rotation + orientation = dir2angle(orientation) + + if((!(orientation%180) && template.width > world.maxx || template.height > world.maxy) || (orientation%180 && template.width > world.maxy || template.height > world.maxx)) if(alert(usr,"This template is larger than the existing z-levels. It will EXPAND ALL Z-LEVELS to match the size of the template. This may cause chaos. Are you sure you want to do this?","DANGER!!!","Cancel","Yes") == "Cancel") to_chat(usr,"Template placement aborted.") return @@ -76,7 +82,7 @@ var/datum/map_template/M = new(map, "[map]") if(M.preload_size(map)) to_chat(usr, "Map template '[map]' ready to place ([M.width]x[M.height])") - map_templates[M.name] = M + SSmapping.map_templates[M.name] = M message_admins("[key_name_admin(usr)] has uploaded a map template ([map])") else to_chat(usr, "Map template '[map]' failed to load properly") diff --git a/code/modules/admin/verbs/massmodvar.dm b/code/modules/admin/verbs/massmodvar.dm deleted file mode 100644 index 09178d650e..0000000000 --- a/code/modules/admin/verbs/massmodvar.dm +++ /dev/null @@ -1,375 +0,0 @@ -/client/proc/cmd_mass_modify_object_variables(atom/A, var/var_name) - set category = "Debug" - set name = "Mass Edit Variables" - set desc="(target) Edit all instances of a target item's variables" - - var/method = 0 //0 means strict type detection while 1 means this type and all subtypes (IE: /obj/item with this set to 1 will set it to ALL itms) - - if(!check_rights(R_VAREDIT)) return - - if(A && A.type) - if(typesof(A.type)) - switch(input("Strict object type detection?") as null|anything in list("Strictly this type","This type and subtypes", "Cancel")) - if("Strictly this type") - method = 0 - if("This type and subtypes") - method = 1 - if("Cancel") - return - if(null) - return - - src.massmodify_variables(A, var_name, method) - feedback_add_details("admin_verb","MEV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - - -/client/proc/massmodify_variables(var/atom/O, var/var_name = "", var/method = 0) - if(!check_rights(R_VAREDIT)) return - - var/list/locked = list("vars", "key", "ckey", "client") - - for(var/p in forbidden_varedit_object_types) - if( istype(O,p) ) - usr << "It is forbidden to edit this object's variables." - return - - var/list/names = list() - for (var/V in O.vars) - names += V - - names = sortList(names) - - var/variable = "" - - if(!var_name) - variable = input("Which var?","Var") as null|anything in names - else - variable = var_name - - if(!variable) return - var/default - var/var_value = O.vars[variable] - var/dir - - if(variable == "holder" || (variable in locked)) - if(!check_rights(R_DEBUG)) return - - if(isnull(var_value)) - usr << "Unable to determine variable type." - - else if(isnum(var_value)) - usr << "Variable appears to be NUM." - default = "num" - dir = 1 - - else if(istext(var_value)) - usr << "Variable appears to be TEXT." - default = "text" - - else if(isloc(var_value)) - usr << "Variable appears to be REFERENCE." - default = "reference" - - else if(isicon(var_value)) - usr << "Variable appears to be ICON." - var_value = "\icon[var_value]" - default = "icon" - - else if(istype(var_value,/atom) || istype(var_value,/datum)) - usr << "Variable appears to be TYPE." - default = "type" - - else if(istype(var_value,/list)) - usr << "Variable appears to be LIST." - default = "list" - - else if(istype(var_value,/client)) - usr << "Variable appears to be CLIENT." - default = "cancel" - - else - usr << "Variable appears to be FILE." - default = "file" - - usr << "Variable contains: [var_value]" - if(dir) - switch(var_value) - if(1) - dir = "NORTH" - if(2) - dir = "SOUTH" - if(4) - dir = "EAST" - if(8) - dir = "WEST" - if(5) - dir = "NORTHEAST" - if(6) - dir = "SOUTHEAST" - if(9) - dir = "NORTHWEST" - if(10) - dir = "SOUTHWEST" - else - dir = null - if(dir) - usr << "If a direction, direction is: [dir]" - - var/class = input("What kind of variable?","Variable Type",default) as null|anything in list("text", - "num","type","icon","file","edit referenced object","restore to default") - - if(!class) - return - - var/original_name - - if (!istype(O, /atom)) - original_name = "\ref[O] ([O])" - else - original_name = O:name - - switch(class) - - if("restore to default") - O.vars[variable] = initial(O.vars[variable]) - if(method) - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if ( istype(M , O.type) ) - M.vars[variable] = O.vars[variable] - - else if(istype(O, /obj)) - for(var/obj/A in world) - if ( istype(A , O.type) ) - A.vars[variable] = O.vars[variable] - - else if(istype(O, /turf)) - for(var/turf/A in turfs) - if ( istype(A , O.type) ) - A.vars[variable] = O.vars[variable] - - else - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if (M.type == O.type) - M.vars[variable] = O.vars[variable] - - else if(istype(O, /obj)) - for(var/obj/A in world) - if (A.type == O.type) - A.vars[variable] = O.vars[variable] - - else if(istype(O, /turf)) - for(var/turf/A in turfs) - if (A.type == O.type) - A.vars[variable] = O.vars[variable] - - if("edit referenced object") - return .(O.vars[variable]) - - if("text") - var/new_value = input("Enter new text:","Text",O.vars[variable]) as text|null//todo: sanitize ??? - if(new_value == null) return - O.vars[variable] = new_value - - if(method) - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if ( istype(M , O.type) ) - M.vars[variable] = O.vars[variable] - - else if(istype(O, /obj)) - for(var/obj/A in world) - if ( istype(A , O.type) ) - A.vars[variable] = O.vars[variable] - - else if(istype(O, /turf)) - for(var/turf/A in turfs) - if ( istype(A , O.type) ) - A.vars[variable] = O.vars[variable] - else - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if (M.type == O.type) - M.vars[variable] = O.vars[variable] - - else if(istype(O, /obj)) - for(var/obj/A in world) - if (A.type == O.type) - A.vars[variable] = O.vars[variable] - - else if(istype(O, /turf)) - for(var/turf/A in turfs) - if (A.type == O.type) - A.vars[variable] = O.vars[variable] - - if("num") - var/new_value = input("Enter new number:","Num",\ - O.vars[variable]) as num|null - if(new_value == null) return - - if(variable=="light_range") - O.set_light(new_value) - else - O.vars[variable] = new_value - - if(method) - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if ( istype(M , O.type) ) - if(variable=="light_range") - M.set_light(new_value) - else - M.vars[variable] = O.vars[variable] - - else if(istype(O, /obj)) - for(var/obj/A in world) - if ( istype(A , O.type) ) - if(variable=="light_range") - A.set_light(new_value) - else - A.vars[variable] = O.vars[variable] - - else if(istype(O, /turf)) - for(var/turf/A in turfs) - if ( istype(A , O.type) ) - if(variable=="light_range") - A.set_light(new_value) - else - A.vars[variable] = O.vars[variable] - - else - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if (M.type == O.type) - if(variable=="light_range") - M.set_light(new_value) - else - M.vars[variable] = O.vars[variable] - - else if(istype(O, /obj)) - for(var/obj/A in world) - if (A.type == O.type) - if(variable=="light_range") - A.set_light(new_value) - else - A.vars[variable] = O.vars[variable] - - else if(istype(O, /turf)) - for(var/turf/A in turfs) - if (A.type == O.type) - if(variable=="light_range") - A.set_light(new_value) - else - A.vars[variable] = O.vars[variable] - - if("type") - var/new_value - new_value = input("Enter type:","Type",O.vars[variable]) as null|anything in typesof(/obj,/mob,/area,/turf) - if(new_value == null) return - O.vars[variable] = new_value - if(method) - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if ( istype(M , O.type) ) - M.vars[variable] = O.vars[variable] - - else if(istype(O, /obj)) - for(var/obj/A in world) - if ( istype(A , O.type) ) - A.vars[variable] = O.vars[variable] - - else if(istype(O, /turf)) - for(var/turf/A in turfs) - if ( istype(A , O.type) ) - A.vars[variable] = O.vars[variable] - else - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if (M.type == O.type) - M.vars[variable] = O.vars[variable] - - else if(istype(O, /obj)) - for(var/obj/A in world) - if (A.type == O.type) - A.vars[variable] = O.vars[variable] - - else if(istype(O, /turf)) - for(var/turf/A in turfs) - if (A.type == O.type) - A.vars[variable] = O.vars[variable] - - if("file") - var/new_value = input("Pick file:","File",O.vars[variable]) as null|file - if(new_value == null) return - O.vars[variable] = new_value - - if(method) - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if ( istype(M , O.type) ) - M.vars[variable] = O.vars[variable] - - else if(istype(O.type, /obj)) - for(var/obj/A in world) - if ( istype(A , O.type) ) - A.vars[variable] = O.vars[variable] - - else if(istype(O.type, /turf)) - for(var/turf/A in turfs) - if ( istype(A , O.type) ) - A.vars[variable] = O.vars[variable] - else - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if (M.type == O.type) - M.vars[variable] = O.vars[variable] - - else if(istype(O.type, /obj)) - for(var/obj/A in world) - if (A.type == O.type) - A.vars[variable] = O.vars[variable] - - else if(istype(O.type, /turf)) - for(var/turf/A in turfs) - if (A.type == O.type) - A.vars[variable] = O.vars[variable] - - if("icon") - var/new_value = input("Pick icon:","Icon",O.vars[variable]) as null|icon - if(new_value == null) return - O.vars[variable] = new_value - if(method) - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if ( istype(M , O.type) ) - M.vars[variable] = O.vars[variable] - - else if(istype(O, /obj)) - for(var/obj/A in world) - if ( istype(A , O.type) ) - A.vars[variable] = O.vars[variable] - - else if(istype(O, /turf)) - for(var/turf/A in turfs) - if ( istype(A , O.type) ) - A.vars[variable] = O.vars[variable] - - else - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if (M.type == O.type) - M.vars[variable] = O.vars[variable] - - else if(istype(O, /obj)) - for(var/obj/A in world) - if (A.type == O.type) - A.vars[variable] = O.vars[variable] - - else if(istype(O, /turf)) - for(var/turf/A in turfs) - if (A.type == O.type) - A.vars[variable] = O.vars[variable] - - log_admin("[key_name(src)] mass modified [original_name]'s [variable] to [O.vars[variable]]") - message_admins("[key_name_admin(src)] mass modified [original_name]'s [variable] to [O.vars[variable]]", 1) diff --git a/code/modules/admin/verbs/modifyvariables.dm b/code/modules/admin/verbs/modifyvariables.dm deleted file mode 100644 index ecd26e9b56..0000000000 --- a/code/modules/admin/verbs/modifyvariables.dm +++ /dev/null @@ -1,591 +0,0 @@ -var/list/forbidden_varedit_object_types = list( - /datum/admins, //Admins editing their own admin-power object? Yup, sounds like a good idea, - /obj/machinery/blackbox_recorder, //Prevents people messing with feedback gathering, - /datum/feedback_variable //Prevents people messing with feedback gathering, - ) - -var/list/VVlocked = list("vars", "client", "virus", "viruses", "cuffed", "last_eaten", "unlock_content", "bound_x", "bound_y", "step_x", "step_y", "force_ending", "queued_priority") -var/list/VVicon_edit_lock = list("icon", "icon_state", "overlays", "underlays") -var/list/VVckey_edit = list("key", "ckey") - -/* -/client/proc/cmd_modify_object_variables(obj/O as obj|mob|turf|area in world) - set category = "Debug" - set name = "Edit Variables" - set desc="(target) Edit a target item's variables" - src.modify_variables(O) - feedback_add_details("admin_verb","EDITV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -*/ - -/client/proc/cmd_modify_ticker_variables() - set category = "Debug" - set name = "Edit Ticker Variables" - - if (ticker == null) - src << "Game hasn't started yet." - else - src.modify_variables(ticker) - feedback_add_details("admin_verb","ETV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/mod_list_add_ass() //haha - - var/class = "text" - if(src.holder && src.holder.marked_datum) - class = input("What kind of variable?","Variable Type") as null|anything in list("text", - "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default","marked datum ([holder.marked_datum.type])") - else - class = input("What kind of variable?","Variable Type") as null|anything in list("text", - "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default") - - if(!class) - return - - if(holder.marked_datum && class == "marked datum ([holder.marked_datum.type])") - class = "marked datum" - - var/var_value = null - - switch(class) - - if("text") - var_value = input("Enter new text:","Text") as null|text - - if("num") - var_value = input("Enter new number:","Num") as null|num - - if("type") - var_value = input("Enter type:","Type") as null|anything in typesof(/obj,/mob,/area,/turf) - - if("reference") - var_value = input("Select reference:","Reference") as null|mob|obj|turf|area in world - - if("mob reference") - var_value = input("Select reference:","Reference") as null|mob in world - - if("file") - var_value = input("Pick file:","File") as null|file - - if("icon") - var_value = input("Pick icon:","Icon") as null|icon - - if("marked datum") - var_value = holder.marked_datum - - if(!var_value) return - - return var_value - - -/client/proc/mod_list_add(var/list/L, atom/O, original_name, objectvar) - - var/class = "text" - if(src.holder && src.holder.marked_datum) - class = input("What kind of variable?","Variable Type") as null|anything in list("text", - "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default","marked datum ([holder.marked_datum.type])") - else - class = input("What kind of variable?","Variable Type") as null|anything in list("text", - "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default") - - if(!class) - return - - if(holder.marked_datum && class == "marked datum ([holder.marked_datum.type])") - class = "marked datum" - - var/var_value = null - - switch(class) - - if("text") - var_value = input("Enter new text:","Text") as text - - if("num") - var_value = input("Enter new number:","Num") as num - - if("type") - var_value = input("Enter type:","Type") in typesof(/obj,/mob,/area,/turf) - - if("reference") - var_value = input("Select reference:","Reference") as mob|obj|turf|area in world - - if("mob reference") - var_value = input("Select reference:","Reference") as mob in world - - if("file") - var_value = input("Pick file:","File") as file - - if("icon") - var_value = input("Pick icon:","Icon") as icon - - if("marked datum") - var_value = holder.marked_datum - - if(!var_value) return - - switch(alert("Would you like to associate a var with the list entry?",,"Yes","No")) - if("Yes") - L += var_value - L[var_value] = mod_list_add_ass() //haha - if("No") - L += var_value - world.log << "### ListVarEdit by [src]: [O.type] [objectvar]: ADDED=[var_value]" - log_admin("[key_name(src)] modified [original_name]'s [objectvar]: ADDED=[var_value]") - message_admins("[key_name_admin(src)] modified [original_name]'s [objectvar]: ADDED=[var_value]") - -/client/proc/mod_list(var/list/L, atom/O, original_name, objectvar) - if(!check_rights(R_VAREDIT)) return - if(!istype(L,/list)) src << "Not a List." - - if(L.len > 1000) - var/confirm = alert(src, "The list you're trying to edit is very long, continuing may crash the server.", "Warning", "Continue", "Abort") - if(confirm != "Continue") - return - - var/assoc = 0 - if(L.len > 0) - var/a = L[1] - if(istext(a) && L[a] != null) - assoc = 1 //This is pretty weak test but i can't think of anything else - usr << "List appears to be associative." - - var/list/names = null - if(!assoc) - names = sortList(L) - - var/variable - var/assoc_key - if(assoc) - variable = input("Which var?","Var") as null|anything in L + "(ADD VAR)" - else - variable = input("Which var?","Var") as null|anything in names + "(ADD VAR)" - - if(variable == "(ADD VAR)") - mod_list_add(L, O, original_name, objectvar) - return - - if(assoc) - assoc_key = variable - variable = L[assoc_key] - - if(!assoc && !variable || assoc && !assoc_key) - return - - var/default - - var/dir - - if(variable in VVlocked) - if(!check_rights(R_DEBUG)) return - if(variable in VVckey_edit) - if(!check_rights(R_SPAWN|R_DEBUG)) return - if(variable in VVicon_edit_lock) - if(!check_rights(R_FUN|R_DEBUG)) return - - if(isnull(variable)) - usr << "Unable to determine variable type." - - else if(isnum(variable)) - usr << "Variable appears to be NUM." - default = "num" - dir = 1 - - else if(istext(variable)) - usr << "Variable appears to be TEXT." - default = "text" - - else if(isloc(variable)) - usr << "Variable appears to be REFERENCE." - default = "reference" - - else if(isicon(variable)) - usr << "Variable appears to be ICON." - variable = "\icon[variable]" - default = "icon" - - else if(istype(variable,/atom) || istype(variable,/datum)) - usr << "Variable appears to be TYPE." - default = "type" - - else if(istype(variable,/list)) - usr << "Variable appears to be LIST." - default = "list" - - else if(istype(variable,/client)) - usr << "Variable appears to be CLIENT." - default = "cancel" - - else - usr << "Variable appears to be FILE." - default = "file" - - usr << "Variable contains: [variable]" - if(dir) - switch(variable) - if(1) - dir = "NORTH" - if(2) - dir = "SOUTH" - if(4) - dir = "EAST" - if(8) - dir = "WEST" - if(5) - dir = "NORTHEAST" - if(6) - dir = "SOUTHEAST" - if(9) - dir = "NORTHWEST" - if(10) - dir = "SOUTHWEST" - else - dir = null - - if(dir) - usr << "If a direction, direction is: [dir]" - - var/class = "text" - if(src.holder && src.holder.marked_datum) - class = input("What kind of variable?","Variable Type",default) as null|anything in list("text", - "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default","marked datum ([holder.marked_datum.type])", "DELETE FROM LIST") - else - class = input("What kind of variable?","Variable Type",default) as null|anything in list("text", - "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default", "DELETE FROM LIST") - - if(!class) - return - - if(holder.marked_datum && class == "marked datum ([holder.marked_datum.type])") - class = "marked datum" - - var/original_var - if(assoc) - original_var = L[assoc_key] - else - original_var = L[L.Find(variable)] - - var/new_var - switch(class) //Spits a runtime error if you try to modify an entry in the contents list. Dunno how to fix it, yet. - - if("list") - mod_list(variable, O, original_name, objectvar) - - if("restore to default") - new_var = initial(variable) - if(assoc) - L[assoc_key] = new_var - else - L[L.Find(variable)] = new_var - - if("edit referenced object") - modify_variables(variable) - - if("DELETE FROM LIST") - world.log << "### ListVarEdit by [src]: [O.type] [objectvar]: REMOVED=[html_encode("[variable]")]" - log_admin("[key_name(src)] modified [original_name]'s [objectvar]: REMOVED=[variable]") - message_admins("[key_name_admin(src)] modified [original_name]'s [objectvar]: REMOVED=[variable]") - L -= variable - return - - if("text") - new_var = input("Enter new text:","Text") as text - if(assoc) - L[assoc_key] = new_var - else - L[L.Find(variable)] = new_var - - if("num") - new_var = input("Enter new number:","Num") as num - if(assoc) - L[assoc_key] = new_var - else - L[L.Find(variable)] = new_var - - if("type") - new_var = input("Enter type:","Type") in typesof(/obj,/mob,/area,/turf) - if(assoc) - L[assoc_key] = new_var - else - L[L.Find(variable)] = new_var - - if("reference") - new_var = input("Select reference:","Reference") as mob|obj|turf|area in world - if(assoc) - L[assoc_key] = new_var - else - L[L.Find(variable)] = new_var - - if("mob reference") - new_var = input("Select reference:","Reference") as mob in world - if(assoc) - L[assoc_key] = new_var - else - L[L.Find(variable)] = new_var - - if("file") - new_var = input("Pick file:","File") as file - if(assoc) - L[assoc_key] = new_var - else - L[L.Find(variable)] = new_var - - if("icon") - new_var = input("Pick icon:","Icon") as icon - if(assoc) - L[assoc_key] = new_var - else - L[L.Find(variable)] = new_var - - if("marked datum") - new_var = holder.marked_datum - if(assoc) - L[assoc_key] = new_var - else - L[L.Find(variable)] = new_var - - world.log << "### ListVarEdit by [src]: [O.type] [objectvar]: [original_var]=[new_var]" - log_admin("[key_name(src)] modified [original_name]'s [objectvar]: [original_var]=[new_var]") - message_admins("[key_name_admin(src)] modified [original_name]'s varlist [objectvar]: [original_var]=[new_var]") - -/client/proc/modify_variables(var/atom/O, var/param_var_name = null, var/autodetect_class = 0) - if(!check_rights(R_VAREDIT)) return - - for(var/p in forbidden_varedit_object_types) - if( istype(O,p) ) - usr << "It is forbidden to edit this object's variables." - return - - if(istype(O, /client) && (param_var_name == "ckey" || param_var_name == "key")) - usr << "You cannot edit ckeys on client objects." - return - - var/class - var/variable - var/var_value - - if(param_var_name) - if(!param_var_name in O.vars) - src << "A variable with this name ([param_var_name]) doesn't exist in this atom ([O])" - return - - if(param_var_name in VVlocked) - if(!check_rights(R_DEBUG)) return - if(param_var_name in VVckey_edit) - if(!check_rights(R_SPAWN|R_DEBUG)) return - if(param_var_name in VVicon_edit_lock) - if(!check_rights(R_FUN|R_DEBUG)) return - - variable = param_var_name - - var_value = O.vars[variable] - - if(autodetect_class) - if(isnull(var_value)) - usr << "Unable to determine variable type." - class = null - autodetect_class = null - else if(isnum(var_value)) - usr << "Variable appears to be NUM." - class = "num" - dir = 1 - - else if(istext(var_value)) - usr << "Variable appears to be TEXT." - class = "text" - - else if(isloc(var_value)) - usr << "Variable appears to be REFERENCE." - class = "reference" - - else if(isicon(var_value)) - usr << "Variable appears to be ICON." - var_value = "\icon[var_value]" - class = "icon" - - else if(istype(var_value,/atom) || istype(var_value,/datum)) - usr << "Variable appears to be TYPE." - class = "type" - - else if(istype(var_value,/list)) - usr << "Variable appears to be LIST." - class = "list" - - else if(istype(var_value,/client)) - usr << "Variable appears to be CLIENT." - class = "cancel" - - else - usr << "Variable appears to be FILE." - class = "file" - - else - - var/list/names = list() - for (var/V in O.vars) - names += V - - names = sortList(names) - - variable = input("Which var?","Var") as null|anything in names - if(!variable) return - var_value = O.vars[variable] - - if(variable in VVlocked) - if(!check_rights(R_DEBUG)) return - if(variable in VVckey_edit) - if(!check_rights(R_SPAWN|R_DEBUG)) return - if(variable in VVicon_edit_lock) - if(!check_rights(R_FUN|R_DEBUG)) return - - if(!autodetect_class) - - var/dir - var/default - if(isnull(var_value)) - usr << "Unable to determine variable type." - - else if(isnum(var_value)) - usr << "Variable appears to be NUM." - default = "num" - dir = 1 - - else if(istext(var_value)) - usr << "Variable appears to be TEXT." - default = "text" - - else if(isloc(var_value)) - usr << "Variable appears to be REFERENCE." - default = "reference" - - else if(isicon(var_value)) - usr << "Variable appears to be ICON." - var_value = "\icon[var_value]" - default = "icon" - - else if(istype(var_value,/atom) || istype(var_value,/datum)) - usr << "Variable appears to be TYPE." - default = "type" - - else if(istype(var_value,/list)) - usr << "Variable appears to be LIST." - default = "list" - - else if(istype(var_value,/client)) - usr << "Variable appears to be CLIENT." - default = "cancel" - - else - usr << "Variable appears to be FILE." - default = "file" - - usr << "Variable contains: [var_value]" - if(dir) - switch(var_value) - if(1) - dir = "NORTH" - if(2) - dir = "SOUTH" - if(4) - dir = "EAST" - if(8) - dir = "WEST" - if(5) - dir = "NORTHEAST" - if(6) - dir = "SOUTHEAST" - if(9) - dir = "NORTHWEST" - if(10) - dir = "SOUTHWEST" - else - dir = null - if(dir) - usr << "If a direction, direction is: [dir]" - - if(src.holder && src.holder.marked_datum) - class = input("What kind of variable?","Variable Type",default) as null|anything in list("text", - "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default","marked datum ([holder.marked_datum.type])") - else - class = input("What kind of variable?","Variable Type",default) as null|anything in list("text", - "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default") - - if(!class) - return - - var/original_name - - if (!istype(O, /atom)) - original_name = "\ref[O] ([O])" - else - original_name = O:name - - if(holder.marked_datum && class == "marked datum ([holder.marked_datum.type])") - class = "marked datum" - - switch(class) - - if("list") - mod_list(O.vars[variable], O, original_name, variable) - return - - if("restore to default") - O.vars[variable] = initial(O.vars[variable]) - - if("edit referenced object") - return .(O.vars[variable]) - - if("text") - var/var_new = input("Enter new text:","Text",O.vars[variable]) as null|text - if(var_new==null) return - O.vars[variable] = var_new - - if("num") - if(variable=="light_range") - var/var_new = input("Enter new number:","Num",O.vars[variable]) as null|num - if(var_new == null) return - O.set_light(var_new) - else if(variable=="stat") - var/var_new = input("Enter new number:","Num",O.vars[variable]) as null|num - if(var_new == null) return - if((O.vars[variable] == 2) && (var_new < 2))//Bringing the dead back to life - dead_mob_list -= O - living_mob_list += O - if((O.vars[variable] < 2) && (var_new == 2))//Kill he - living_mob_list -= O - dead_mob_list += O - O.vars[variable] = var_new - else - var/var_new = input("Enter new number:","Num",O.vars[variable]) as null|num - if(var_new==null) return - O.vars[variable] = var_new - - if("type") - var/var_new = input("Enter type:","Type",O.vars[variable]) as null|anything in typesof(/obj,/mob,/area,/turf) - if(var_new==null) return - O.vars[variable] = var_new - - if("reference") - var/var_new = input("Select reference:","Reference",O.vars[variable]) as null|mob|obj|turf|area in world - if(var_new==null) return - O.vars[variable] = var_new - - if("mob reference") - var/var_new = input("Select reference:","Reference",O.vars[variable]) as null|mob in world - if(var_new==null) return - O.vars[variable] = var_new - - if("file") - var/var_new = input("Pick file:","File",O.vars[variable]) as null|file - if(var_new==null) return - O.vars[variable] = var_new - - if("icon") - var/var_new = input("Pick icon:","Icon",O.vars[variable]) as null|icon - if(var_new==null) return - O.vars[variable] = var_new - - if("marked datum") - O.vars[variable] = holder.marked_datum - - world.log << "### VarEdit by [src]: [O.type] [variable]=[html_encode("[O.vars[variable]]")]" - log_admin("[key_name(src)] modified [original_name]'s [variable] to [O.vars[variable]]") - message_admins("[key_name_admin(src)] modified [original_name]'s [variable] to [O.vars[variable]]") diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 1e8528acb9..7d0b7ee259 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -62,7 +62,7 @@ var/highlight_special_characters = 1 - for(var/client/C in clients) + for(var/client/C in GLOB.clients) if(C.player_age == "Requires database") missing_ages = 1 continue @@ -363,7 +363,7 @@ Traitors and the like can also be revived with the previous role mostly intact. return //I frontload all the questions so we don't have a half-done process while you're reading. - var/client/picked_client = input(src, "Please specify which client's character to spawn.", "Client", "") as null|anything in clients + var/client/picked_client = input(src, "Please specify which client's character to spawn.", "Client", "") as null|anything in GLOB.clients if(!picked_client) return @@ -603,12 +603,7 @@ Traitors and the like can also be revived with the previous role mostly intact. if (!holder) src << "Only administrators may use this command." return - - if (alert(src, "Are you sure you want to delete:\n[O]\nat ([O.x], [O.y], [O.z])?", "Confirmation", "Yes", "No") == "Yes") - log_admin("[key_name(usr)] deleted [O] at ([O.x],[O.y],[O.z])") - message_admins("[key_name_admin(usr)] deleted [O] at ([O.x],[O.y],[O.z])", 1) - feedback_add_details("admin_verb","DEL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - qdel(O) + admin_delete(O) /client/proc/cmd_admin_list_open_jobs() set category = "Admin" diff --git a/code/modules/admin/verbs/smite_vr.dm b/code/modules/admin/verbs/smite_vr.dm index c04dd00847..0d048dde2d 100644 --- a/code/modules/admin/verbs/smite_vr.dm +++ b/code/modules/admin/verbs/smite_vr.dm @@ -18,14 +18,15 @@ feedback_add_details("admin_verb","SMITEV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! switch(smite_choice) + /* if(SMITE_SHADEKIN_ATTACK) var/turf/Tt = get_turf(target) //Turf for target - + if(target.loc != Tt) return //Too hard to attack someone in something - + var/turf/Ts //Turf for shadekin - + //Try to find nondense turf for(var/direction in cardinal) var/turf/T = get_step(target,direction) @@ -34,7 +35,7 @@ if(!Ts) return //Didn't find shadekin spawn turf - var/mob/living/simple_animal/shadekin/red/shadekin = new(Ts) + var/mob/living/simple_mob/shadekin/red/shadekin = new(Ts) //Abuse of shadekin shadekin.real_name = shadekin.name shadekin.init_vore() @@ -47,33 +48,34 @@ //Remove when done spawn(10 SECONDS) if(shadekin) - shadekin.death() + shadekin.death()*/ //VORESTATION AI TEMPORARY REMOVAL - if(SMITE_SHADEKIN_NOMF) + /*if(SMITE_SHADEKIN_NOMF) var/list/kin_types = list( - "Red Eyes (Dark)" = /mob/living/simple_animal/shadekin/red/dark, - "Red Eyes (Light)" = /mob/living/simple_animal/shadekin/red/white, - "Red Eyes (Brown)" = /mob/living/simple_animal/shadekin/red/brown, - "Blue Eyes (Dark)" = /mob/living/simple_animal/shadekin/blue/dark, - "Blue Eyes (Light)" = /mob/living/simple_animal/shadekin/blue/white, - "Blue Eyes (Brown)" = /mob/living/simple_animal/shadekin/blue/brown, - "Purple Eyes (Dark)" = /mob/living/simple_animal/shadekin/purple/dark, - "Purple Eyes (Light)" = /mob/living/simple_animal/shadekin/purple/white, - "Purple Eyes (Brown)" = /mob/living/simple_animal/shadekin/purple/brown, - "Yellow Eyes (Dark)" = /mob/living/simple_animal/shadekin/yellow/dark, - "Yellow Eyes (Light)" = /mob/living/simple_animal/shadekin/yellow/white, - "Yellow Eyes (Brown)" = /mob/living/simple_animal/shadekin/yellow/brown, - "Green Eyes (Dark)" = /mob/living/simple_animal/shadekin/green/dark, - "Green Eyes (Light)" = /mob/living/simple_animal/shadekin/green/white, - "Green Eyes (Brown)" = /mob/living/simple_animal/shadekin/green/brown, - "Orange Eyes (Dark)" = /mob/living/simple_animal/shadekin/orange/dark, - "Orange Eyes (Light)" = /mob/living/simple_animal/shadekin/orange/white, - "Orange Eyes (Brown)" = /mob/living/simple_animal/shadekin/orange/brown, - "Rivyr (Unique)" = /mob/living/simple_animal/shadekin/blue/rivyr) + "Red Eyes (Dark)" = /mob/living/simple_mob/shadekin/red/dark, + "Red Eyes (Light)" = /mob/living/simple_mob/shadekin/red/white, + "Red Eyes (Brown)" = /mob/living/simple_mob/shadekin/red/brown, + "Blue Eyes (Dark)" = /mob/living/simple_mob/shadekin/blue/dark, + "Blue Eyes (Light)" = /mob/living/simple_mob/shadekin/blue/white, + "Blue Eyes (Brown)" = /mob/living/simple_mob/shadekin/blue/brown, + "Purple Eyes (Dark)" = /mob/living/simple_mob/shadekin/purple/dark, + "Purple Eyes (Light)" = /mob/living/simple_mob/shadekin/purple/white, + "Purple Eyes (Brown)" = /mob/living/simple_mob/shadekin/purple/brown, + "Yellow Eyes (Dark)" = /mob/living/simple_mob/shadekin/yellow/dark, + "Yellow Eyes (Light)" = /mob/living/simple_mob/shadekin/yellow/white, + "Yellow Eyes (Brown)" = /mob/living/simple_mob/shadekin/yellow/brown, + "Green Eyes (Dark)" = /mob/living/simple_mob/shadekin/green/dark, + "Green Eyes (Light)" = /mob/living/simple_mob/shadekin/green/white, + "Green Eyes (Brown)" = /mob/living/simple_mob/shadekin/green/brown, + "Orange Eyes (Dark)" = /mob/living/simple_mob/shadekin/orange/dark, + "Orange Eyes (Light)" = /mob/living/simple_mob/shadekin/orange/white, + "Orange Eyes (Brown)" = /mob/living/simple_mob/shadekin/orange/brown, + "Rivyr (Unique)" = /mob/living/simple_mob/shadekin/blue/rivyr) var/kin_type = input("Select the type of shadekin for [target] nomf","Shadekin Type Choice") as null|anything in kin_types if(!kin_type || !target) return + kin_type = kin_types[kin_type] var/myself = alert("Control the shadekin yourself or delete pred and prey after?","Control Shadekin?","Control","Cancel","Delete") @@ -81,13 +83,13 @@ return var/turf/Tt = get_turf(target) - + if(target.loc != Tt) return //Can't nom when not exposed //Begin abuse target.transforming = TRUE //Cheap hack to stop them from moving - var/mob/living/simple_animal/shadekin/shadekin = new kin_type(Tt) + var/mob/living/simple_mob/shadekin/shadekin = new kin_type(Tt) shadekin.real_name = shadekin.name shadekin.init_vore() shadekin.can_be_drop_pred = TRUE @@ -117,6 +119,7 @@ target.ghostize() qdel(target) qdel(shadekin) + */ if(SMITE_REDSPACE_ABDUCT) redspace_abduction(target, src) @@ -160,7 +163,7 @@ var/redspace_abduction_z //Lower left corner of a working box var/llc_x = max(0,halfbox-target.x) + min(target.x+halfbox, world.maxx) - size_of_square var/llc_y = max(0,halfbox-target.y) + min(target.y+halfbox, world.maxy) - size_of_square - + //Copy them all for(var/x = llc_x to llc_x+size_of_square) for(var/y = llc_y to llc_y+size_of_square) @@ -196,7 +199,7 @@ var/redspace_abduction_z T.density = FALSE T.opacity = FALSE T.vis_contents.Cut() - + for(var/x = llc_x to llc_x+size_of_square) //Bottom for(var/y = llc_y to llc_y+1) if(prob(50)) diff --git a/code/modules/admin/view_variables/admin_delete.dm b/code/modules/admin/view_variables/admin_delete.dm new file mode 100644 index 0000000000..53a54786a9 --- /dev/null +++ b/code/modules/admin/view_variables/admin_delete.dm @@ -0,0 +1,24 @@ +/client/proc/admin_delete(datum/D) + var/atom/A = D + var/coords = "" + var/jmp_coords = "" + if(istype(A)) + var/turf/T = get_turf(A) + if(T) + coords = "at [COORD(T)]" + jmp_coords = "at [ADMIN_COORDJMP(T)]" + else + jmp_coords = coords = "in nullspace" + + if (alert(src, "Are you sure you want to delete:\n[D]\n[coords]?", "Confirmation", "Yes", "No") == "Yes") + log_admin("[key_name(usr)] deleted [D] [coords]") + message_admins("[key_name_admin(usr)] deleted [D] [jmp_coords]") + feedback_add_details("admin_verb","ADEL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + /*if(isturf(D)) //Polaris doesn't support baseturfs yet. + var/turf/T = D + T.ScrapeAway() + else*/ + vv_update_display(D, "deleted", VV_MSG_DELETED) + qdel(D) + if(!QDELETED(D)) + vv_update_display(D, "deleted", "") diff --git a/code/modules/admin/view_variables/debug_variables.dm b/code/modules/admin/view_variables/debug_variables.dm new file mode 100644 index 0000000000..bcf097f813 --- /dev/null +++ b/code/modules/admin/view_variables/debug_variables.dm @@ -0,0 +1,76 @@ +#define VV_HTML_ENCODE(thing) ( sanitize ? html_encode(thing) : thing ) +/proc/debug_variable(name, value, level, datum/DA = null, sanitize = TRUE) + var/header + if(DA) + if (islist(DA)) + var/index = name + if (value) + name = DA[name] //name is really the index until this line + else + value = DA[name] + header = "
  • (E) (C) (-) " + else + header = "
  • (E) (C) (M) " + else + header = "
  • " + + var/item + if (isnull(value)) + item = "[VV_HTML_ENCODE(name)] = null" + + else if (istext(value)) + item = "[VV_HTML_ENCODE(name)] = \"[VV_HTML_ENCODE(value)]\"" + + else if (isicon(value)) + #ifdef VARSICON + var/icon/I = new/icon(value) + var/rnd = rand(1,10000) + var/rname = "tmp\ref[I][rnd].png" + usr << browse_rsc(I, rname) + item = "[VV_HTML_ENCODE(name)] = ([value]) " + #else + item = "[VV_HTML_ENCODE(name)] = /icon ([value])" + #endif + + else if (isfile(value)) + item = "[VV_HTML_ENCODE(name)] = '[value]'" + + else if (istype(value, /datum)) + var/datum/D = value + if ("[D]" != "[D.type]") //if the thing as a name var, lets use it. + item = "[VV_HTML_ENCODE(name)] \ref[value] = [D] [D.type]" + else + item = "[VV_HTML_ENCODE(name)] \ref[value] = [D.type]" + + else if (islist(value)) + var/list/L = value + var/list/items = list() + + if (L.len > 0 && !(name == "underlays" || name == "overlays" || L.len > (IS_NORMAL_LIST(L) ? VV_NORMAL_LIST_NO_EXPAND_THRESHOLD : VV_SPECIAL_LIST_NO_EXPAND_THRESHOLD))) + for (var/i in 1 to L.len) + var/key = L[i] + var/val + if (IS_NORMAL_LIST(L) && !isnum(key)) + val = L[key] + if (isnull(val)) // we still want to display non-null false values, such as 0 or "" + val = key + key = i + + items += debug_variable(key, val, level + 1, sanitize = sanitize) + + item = "[VV_HTML_ENCODE(name)] = /list ([L.len])
      [items.Join()]
    " + else + item = "[VV_HTML_ENCODE(name)] = /list ([L.len])" + + else if (name in GLOB.bitfields) + var/list/flags = list() + for (var/i in GLOB.bitfields[name]) + if (value & GLOB.bitfields[name][i]) + flags += i + item = "[VV_HTML_ENCODE(name)] = [VV_HTML_ENCODE(jointext(flags, ", "))]" + else + item = "[VV_HTML_ENCODE(name)] = [VV_HTML_ENCODE(value)]" + + return "[header][item]
  • " + +#undef VV_HTML_ENCODE diff --git a/code/modules/admin/view_variables/get_variables.dm b/code/modules/admin/view_variables/get_variables.dm new file mode 100644 index 0000000000..eb2d1bf4db --- /dev/null +++ b/code/modules/admin/view_variables/get_variables.dm @@ -0,0 +1,250 @@ +/client/proc/vv_get_class(var/var_name, var/var_value) + if(isnull(var_value)) + . = VV_NULL + + else if (isnum(var_value)) + if (var_name in GLOB.bitfields) + . = VV_BITFIELD + else + . = VV_NUM + + else if (istext(var_value)) + if (findtext(var_value, "\n")) + . = VV_MESSAGE + else + . = VV_TEXT + + else if (isicon(var_value)) + . = VV_ICON + + else if (ismob(var_value)) + . = VV_MOB_REFERENCE + + else if (isloc(var_value)) + . = VV_ATOM_REFERENCE + + else if (istype(var_value, /client)) + . = VV_CLIENT + + else if (istype(var_value, /datum)) + . = VV_DATUM_REFERENCE + + else if (ispath(var_value)) + if (ispath(var_value, /atom)) + . = VV_ATOM_TYPE + else if (ispath(var_value, /datum)) + . = VV_DATUM_TYPE + else + . = VV_TYPE + + else if (islist(var_value)) + . = VV_LIST + + else if (isfile(var_value)) + . = VV_FILE + else + . = VV_NULL + +/client/proc/vv_get_value(class, default_class, current_value, list/restricted_classes, list/extra_classes, list/classes, var_name) + . = list("class" = class, "value" = null) + if (!class) + if (!classes) + classes = list ( + VV_NUM, + VV_TEXT, + VV_MESSAGE, + VV_ICON, + VV_ATOM_REFERENCE, + VV_DATUM_REFERENCE, + VV_MOB_REFERENCE, + VV_CLIENT, + VV_ATOM_TYPE, + VV_DATUM_TYPE, + VV_TYPE, + VV_FILE, + VV_NEW_ATOM, + VV_NEW_DATUM, + VV_NEW_TYPE, + VV_NEW_LIST, + VV_NULL, + VV_RESTORE_DEFAULT + ) + + if(holder && holder.marked_datum && !(VV_MARKED_DATUM in restricted_classes)) + classes += "[VV_MARKED_DATUM] ([holder.marked_datum.type])" + if (restricted_classes) + classes -= restricted_classes + + if (extra_classes) + classes += extra_classes + + .["class"] = input(src, "What kind of data?", "Variable Type", default_class) as null|anything in classes + if (holder && holder.marked_datum && .["class"] == "[VV_MARKED_DATUM] ([holder.marked_datum.type])") + .["class"] = VV_MARKED_DATUM + + + switch(.["class"]) + if (VV_TEXT) + .["value"] = input("Enter new text:", "Text", current_value) as null|text + if (.["value"] == null) + .["class"] = null + return + if (VV_MESSAGE) + .["value"] = input("Enter new text:", "Text", current_value) as null|message + if (.["value"] == null) + .["class"] = null + return + + + if (VV_NUM) + .["value"] = input("Enter new number:", "Num", current_value) as null|num + if (.["value"] == null) + .["class"] = null + return + + if (VV_BITFIELD) + .["value"] = input_bitfield(usr, "Editing bitfield: [var_name]", var_name, current_value) + if (.["value"] == null) + .["class"] = null + return + + if (VV_ATOM_TYPE) + .["value"] = pick_closest_path(FALSE) + if (.["value"] == null) + .["class"] = null + return + + if (VV_DATUM_TYPE) + .["value"] = pick_closest_path(FALSE, get_fancy_list_of_datum_types()) + if (.["value"] == null) + .["class"] = null + return + + if (VV_TYPE) + var/type = current_value + var/error = "" + do + type = input("Enter type:[error]", "Type", type) as null|text + if (!type) + break + type = text2path(type) + error = "\nType not found, Please try again" + while(!type) + if (!type) + .["class"] = null + return + .["value"] = type + + + if (VV_ATOM_REFERENCE) + var/type = pick_closest_path(FALSE) + var/subtypes = vv_subtype_prompt(type) + if (subtypes == null) + .["class"] = null + return + var/list/things = vv_reference_list(type, subtypes) + var/value = input("Select reference:", "Reference", current_value) as null|anything in things + if (!value) + .["class"] = null + return + .["value"] = things[value] + + if (VV_DATUM_REFERENCE) + var/type = pick_closest_path(FALSE, get_fancy_list_of_datum_types()) + var/subtypes = vv_subtype_prompt(type) + if (subtypes == null) + .["class"] = null + return + var/list/things = vv_reference_list(type, subtypes) + var/value = input("Select reference:", "Reference", current_value) as null|anything in things + if (!value) + .["class"] = null + return + .["value"] = things[value] + + if (VV_MOB_REFERENCE) + var/type = pick_closest_path(FALSE, make_types_fancy(typesof(/mob))) + var/subtypes = vv_subtype_prompt(type) + if (subtypes == null) + .["class"] = null + return + var/list/things = vv_reference_list(type, subtypes) + var/value = input("Select reference:", "Reference", current_value) as null|anything in things + if (!value) + .["class"] = null + return + .["value"] = things[value] + + + + if (VV_CLIENT) + .["value"] = input("Select reference:", "Reference", current_value) as null|anything in GLOB.clients + if (.["value"] == null) + .["class"] = null + return + + + if (VV_FILE) + .["value"] = input("Pick file:", "File") as null|file + if (.["value"] == null) + .["class"] = null + return + + + if (VV_ICON) + .["value"] = input("Pick icon:", "Icon") as null|icon + if (.["value"] == null) + .["class"] = null + return + + + if (VV_MARKED_DATUM) + .["value"] = holder.marked_datum + if (.["value"] == null) + .["class"] = null + return + + + if (VV_NEW_ATOM) + var/type = pick_closest_path(FALSE) + if (!type) + .["class"] = null + return + .["type"] = type + var/atom/newguy = new type() + newguy.datum_flags |= DF_VAR_EDITED + .["value"] = newguy + + if (VV_NEW_DATUM) + var/type = pick_closest_path(FALSE, get_fancy_list_of_datum_types()) + if (!type) + .["class"] = null + return + .["type"] = type + var/datum/newguy = new type() + newguy.datum_flags |= DF_VAR_EDITED + .["value"] = newguy + + if (VV_NEW_TYPE) + var/type = current_value + var/error = "" + do + type = input("Enter type:[error]", "Type", type) as null|text + if (!type) + break + type = text2path(type) + error = "\nType not found, Please try again" + while(!type) + if (!type) + .["class"] = null + return + .["type"] = type + var/datum/newguy = new type() + if(istype(newguy)) + newguy.datum_flags |= DF_VAR_EDITED + .["value"] = newguy + + + if (VV_NEW_LIST) + .["value"] = list() + .["type"] = /list diff --git a/code/modules/admin/view_variables/helpers.dm b/code/modules/admin/view_variables/helpers.dm deleted file mode 100644 index 2776458e06..0000000000 --- a/code/modules/admin/view_variables/helpers.dm +++ /dev/null @@ -1,194 +0,0 @@ - -/datum/proc/get_view_variables_header() - return "[src]" - -/atom/get_view_variables_header() - return {" - [src] -
    - << - [dir2text(dir)] - >> - - "} - -/mob/living/get_view_variables_header() - return {" - [src] -
    << [dir2text(dir)] >> -
    [ckey ? ckey : "No ckey"] / [real_name ? real_name : "No real name"] -
    - BRUTE:[getBruteLoss()] - FIRE:[getFireLoss()] - TOXIN:[getToxLoss()] - OXY:[getOxyLoss()] - CLONE:[getCloneLoss()] - BRAIN:[getBrainLoss()] -
    - "} - -/datum/proc/get_view_variables_options() - return "" - -/mob/get_view_variables_options() - return ..() + {" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "} - -/mob/living/carbon/human/get_view_variables_options() - return ..() + {" - - - - - - "} - -/obj/get_view_variables_options() - return ..() + {" - - - - "} - -/turf/get_view_variables_options() - return ..() + {" - - - "} - -/datum/proc/get_variables() - . = vars - VV_hidden() - if(!usr || !check_rights(R_ADMIN|R_DEBUG, FALSE)) - . -= VV_secluded() - -/datum/proc/get_variable_value(varname) - return vars[varname] - -/datum/proc/set_variable_value(varname, value) - vars[varname] = value - -/datum/proc/get_initial_variable_value(varname) - return initial(vars[varname]) - -/datum/proc/make_view_variables_variable_entry(var/varname, var/value, var/hide_watch = 0) - return {" - (E) - (C) - (M) - [hide_watch ? "" : "(W)"] - "} - -// No mass editing of clients -/client/make_view_variables_variable_entry(var/varname, var/value, var/hide_watch = 0) - return {" - (E) - (C) - [hide_watch ? "" : "(W)"] - "} - -// These methods are all procs and don't use stored lists to avoid VV exploits - -// The following vars cannot be viewed by anyone -/datum/proc/VV_hidden() - return list() - -// The following vars can only be viewed by R_ADMIN|R_DEBUG -/datum/proc/VV_secluded() - return list() - -/datum/configuration/VV_secluded() - return vars - -// The following vars cannot be edited by anyone -/datum/proc/VV_static() - return list("parent_type") - -/atom/VV_static() - return ..() + list("bound_x", "bound_y", "bound_height", "bound_width", "bounds", "step_x", "step_y", "step_size") - -/client/VV_static() - return ..() + list("holder", "prefs") - -/datum/admins/VV_static() - return vars - -// The following vars require R_DEBUG to edit -/datum/proc/VV_locked() - return list("vars", "virus", "viruses", "cuffed") - -/client/VV_locked() - return list("vars", "mob") - -/mob/VV_locked() - return ..() + list("client") - -// The following vars require R_FUN|R_DEBUG to edit -/datum/proc/VV_icon_edit_lock() - return list() - -/atom/VV_icon_edit_lock() - return ..() + list("icon", "icon_state", "overlays", "underlays") - -// The following vars require R_SPAWN|R_DEBUG to edit -/datum/proc/VV_ckey_edit() - return list() - -/mob/VV_ckey_edit() - return list("key", "ckey") - -/client/VV_ckey_edit() - return list("key", "ckey") - -/datum/proc/may_edit_var(var/user, var/var_to_edit) - if(!user) - return FALSE - if(!(var_to_edit in vars)) - to_chat(user, "\The [src] does not have a var '[var_to_edit]'") - return FALSE - if(var_to_edit in VV_static()) - return FALSE - if((var_to_edit in VV_secluded()) && !check_rights(R_ADMIN|R_DEBUG, FALSE, C = user)) - return FALSE - if((var_to_edit in VV_locked()) && !check_rights(R_DEBUG, C = user)) - return FALSE - if((var_to_edit in VV_ckey_edit()) && !check_rights(R_SPAWN|R_DEBUG, C = user)) - return FALSE - if((var_to_edit in VV_icon_edit_lock()) && !check_rights(R_FUN|R_DEBUG, C = user)) - return FALSE - return TRUE - -/proc/forbidden_varedit_object_types() - return list( - /datum/admins, //Admins editing their own admin-power object? Yup, sounds like a good idea., - /obj/machinery/blackbox_recorder, //Prevents people messing with feedback gathering, - /datum/feedback_variable //Prevents people messing with feedback gathering - ) \ No newline at end of file diff --git a/code/modules/admin/view_variables/helpers_deprecated.dm b/code/modules/admin/view_variables/helpers_deprecated.dm new file mode 100644 index 0000000000..1a7e44d4a5 --- /dev/null +++ b/code/modules/admin/view_variables/helpers_deprecated.dm @@ -0,0 +1,48 @@ +//This entire file needs to be removed eventually +/datum/proc/get_view_variables_options() + return "" + +/mob/get_view_variables_options() + return ..() + {" + + + + + + + + + + + + + + + + + + + + + + + + + + + + "} + +/mob/living/carbon/human/get_view_variables_options() + return ..() + {" + + + + + + "} + +/obj/get_view_variables_options() + return ..() + {" + + "} diff --git a/code/modules/admin/view_variables/mass_edit_variables.dm b/code/modules/admin/view_variables/mass_edit_variables.dm new file mode 100644 index 0000000000..7374759e8c --- /dev/null +++ b/code/modules/admin/view_variables/mass_edit_variables.dm @@ -0,0 +1,265 @@ +/client/proc/cmd_mass_modify_object_variables(atom/A, var_name) + set category = "Debug" + set name = "Mass Edit Variables" + set desc="(target) Edit all instances of a target item's variables" + + var/method = 0 //0 means strict type detection while 1 means this type and all subtypes (IE: /obj/item with this set to 1 will set it to ALL items) + + if(!check_rights(R_VAREDIT)) + return + + if(A && A.type) + method = vv_subtype_prompt(A.type) + + src.massmodify_variables(A, var_name, method) + feedback_add_details("admin_verb","MVV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +/client/proc/massmodify_variables(datum/O, var_name = "", method = 0) + if(!check_rights(R_VAREDIT)) + return + if(!istype(O)) + return + + var/variable = "" + if(!var_name) + var/list/names = list() + for (var/V in O.vars) + names += V + + names = sortList(names) + + variable = input("Which var?", "Var") as null|anything in names + else + variable = var_name + + if(!variable || !O.can_vv_get(variable)) + return + var/default + var/var_value = O.vars[variable] + + if(variable in GLOB.VVckey_edit) + to_chat(src, "It's forbidden to mass-modify ckeys. It'll crash everyone's client you dummy.") + return + if(variable in GLOB.VVlocked) + if(!check_rights(R_DEBUG)) + return + if(variable in GLOB.VVicon_edit_lock) + if(!check_rights(R_FUN|R_DEBUG)) + return + if(variable in GLOB.VVpixelmovement) + if(!check_rights(R_DEBUG)) + return + var/prompt = alert(src, "Editing this var may irreparably break tile gliding for the rest of the round. THIS CAN'T BE UNDONE", "DANGER", "ABORT ", "Continue", " ABORT") + if (prompt != "Continue") + return + + default = vv_get_class(variable, var_value) + + if(isnull(default)) + to_chat(src, "Unable to determine variable type.") + else + to_chat(src, "Variable appears to be [uppertext(default)].") + + to_chat(src, "Variable contains: [var_value]") + + if(default == VV_NUM) + var/dir_text = "" + if(var_value > 0 && var_value < 16) + if(var_value & 1) + dir_text += "NORTH" + if(var_value & 2) + dir_text += "SOUTH" + if(var_value & 4) + dir_text += "EAST" + if(var_value & 8) + dir_text += "WEST" + + if(dir_text) + to_chat(src, "If a direction, direction is: [dir_text]") + + var/value = vv_get_value(default_class = default) + var/new_value = value["value"] + var/class = value["class"] + + if(!class || !new_value == null && class != VV_NULL) + return + + if (class == VV_MESSAGE) + class = VV_TEXT + + if (value["type"]) + class = VV_NEW_TYPE + + var/original_name = "[O]" + + var/rejected = 0 + var/accepted = 0 + + switch(class) + if(VV_RESTORE_DEFAULT) + to_chat(src, "Finding items...") + var/list/items = get_all_of_type(O.type, method) + to_chat(src, "Changing [items.len] items...") + for(var/thing in items) + if (!thing) + continue + var/datum/D = thing + if (D.vv_edit_var(variable, initial(D.vars[variable])) != FALSE) + accepted++ + else + rejected++ + CHECK_TICK + + if(VV_TEXT) + var/list/varsvars = vv_parse_text(O, new_value) + var/pre_processing = new_value + var/unique + if (varsvars && varsvars.len) + unique = alert(usr, "Process vars unique to each instance, or same for all?", "Variable Association", "Unique", "Same") + if(unique == "Unique") + unique = TRUE + else + unique = FALSE + for(var/V in varsvars) + new_value = replacetext(new_value,"\[[V]]","[O.vars[V]]") + + to_chat(src, "Finding items...") + var/list/items = get_all_of_type(O.type, method) + to_chat(src, "Changing [items.len] items...") + for(var/thing in items) + if (!thing) + continue + var/datum/D = thing + if(unique) + new_value = pre_processing + for(var/V in varsvars) + new_value = replacetext(new_value,"\[[V]]","[D.vars[V]]") + + if (D.vv_edit_var(variable, new_value) != FALSE) + accepted++ + else + rejected++ + CHECK_TICK + + if (VV_NEW_TYPE) + var/many = alert(src, "Create only one [value["type"]] and assign each or a new one for each thing", "How Many", "One", "Many", "Cancel") + if (many == "Cancel") + return + if (many == "Many") + many = TRUE + else + many = FALSE + + var/type = value["type"] + to_chat(src, "Finding items...") + var/list/items = get_all_of_type(O.type, method) + to_chat(src, "Changing [items.len] items...") + for(var/thing in items) + if (!thing) + continue + var/datum/D = thing + if(many && !new_value) + new_value = new type() + + if (D.vv_edit_var(variable, new_value) != FALSE) + accepted++ + else + rejected++ + new_value = null + CHECK_TICK + + else + to_chat(src, "Finding items...") + var/list/items = get_all_of_type(O.type, method) + to_chat(src, "Changing [items.len] items...") + for(var/thing in items) + if (!thing) + continue + var/datum/D = thing + if (D.vv_edit_var(variable, new_value) != FALSE) + accepted++ + else + rejected++ + CHECK_TICK + + + var/count = rejected+accepted + if (!count) + to_chat(src, "No objects found") + return + if (!accepted) + to_chat(src, "Every object rejected your edit") + return + if (rejected) + to_chat(src, "[rejected] out of [count] objects rejected your edit") + + log_world("### MassVarEdit by [src]: [O.type] (A/R [accepted]/[rejected]) [variable]=[html_encode("[O.vars[variable]]")]([list2params(value)])") + log_admin("[key_name(src)] mass modified [original_name]'s [variable] to [O.vars[variable]] ([accepted] objects modified)") + message_admins("[key_name_admin(src)] mass modified [original_name]'s [variable] to [O.vars[variable]] ([accepted] objects modified)") + + +/proc/get_all_of_type(var/T, subtypes = TRUE) + var/list/typecache = list() + typecache[T] = 1 + if (subtypes) + typecache = typecacheof(typecache) + . = list() + if (ispath(T, /mob)) + for(var/mob/thing in mob_list) + if (typecache[thing.type]) + . += thing + CHECK_TICK + + else if (ispath(T, /obj/machinery/door)) + for(var/obj/machinery/door/thing in world) + if (typecache[thing.type]) + . += thing + CHECK_TICK + + else if (ispath(T, /obj/machinery)) + for(var/obj/machinery/thing in machines) + if (typecache[thing.type]) + . += thing + CHECK_TICK + + else if (ispath(T, /obj)) + for(var/obj/thing in world) + if (typecache[thing.type]) + . += thing + CHECK_TICK + + else if (ispath(T, /atom/movable)) + for(var/atom/movable/thing in world) + if (typecache[thing.type]) + . += thing + CHECK_TICK + + else if (ispath(T, /turf)) + for(var/turf/thing in world) + if (typecache[thing.type]) + . += thing + CHECK_TICK + + else if (ispath(T, /atom)) + for(var/atom/thing in world) + if (typecache[thing.type]) + . += thing + CHECK_TICK + + else if (ispath(T, /client)) + for(var/client/thing in GLOB.clients) + if (typecache[thing.type]) + . += thing + CHECK_TICK + + else if (ispath(T, /datum)) + for(var/datum/thing) + if (typecache[thing.type]) + . += thing + CHECK_TICK + + else + for(var/datum/thing in world) + if (typecache[thing.type]) + . += thing + CHECK_TICK diff --git a/code/modules/admin/view_variables/modify_variables.dm b/code/modules/admin/view_variables/modify_variables.dm new file mode 100644 index 0000000000..b964339aa9 --- /dev/null +++ b/code/modules/admin/view_variables/modify_variables.dm @@ -0,0 +1,387 @@ +GLOBAL_LIST_INIT(VVlocked, list("vars", "datum_flags", "client", "mob")) //Requires DEBUG +GLOBAL_PROTECT(VVlocked) +GLOBAL_LIST_INIT(VVicon_edit_lock, list("icon", "icon_state", "overlays", "underlays")) //Requires DEBUG or FUN +GLOBAL_PROTECT(VVicon_edit_lock) +GLOBAL_LIST_INIT(VVckey_edit, list("key", "ckey")) //Requires DEBUG or SPAWN +GLOBAL_PROTECT(VVckey_edit) +GLOBAL_LIST_INIT(VVpixelmovement, list("bound_x", "bound_y", "step_x", "step_y", "step_size", "bound_height", "bound_width", "bounds")) //No editing ever. +GLOBAL_PROTECT(VVpixelmovement) + +/client/proc/vv_parse_text(O, new_var) + if(O && findtext(new_var,"\[")) + var/process_vars = alert(usr,"\[] detected in string, process as variables?","Process Variables?","Yes","No") + if(process_vars == "Yes") + . = string2listofvars(new_var, O) + +//do they want you to include subtypes? +//FALSE = no subtypes, strict exact type pathing (or the type doesn't have subtypes) +//TRUE = Yes subtypes +//NULL = User cancelled at the prompt or invalid type given +/client/proc/vv_subtype_prompt(var/type) + if (!ispath(type)) + return + var/list/subtypes = subtypesof(type) + if (!subtypes || !subtypes.len) + return FALSE + if (subtypes && subtypes.len) + switch(alert("Strict object type detection?", "Type detection", "Strictly this type","This type and subtypes", "Cancel")) + if("Strictly this type") + return FALSE + if("This type and subtypes") + return TRUE + else + return + +/client/proc/vv_reference_list(type, subtypes) + . = list() + var/list/types = list(type) + if (subtypes) + types = typesof(type) + + var/list/fancytypes = make_types_fancy(types) + + for(var/fancytype in fancytypes) //swap the assoication + types[fancytypes[fancytype]] = fancytype + + var/things = get_all_of_type(type, subtypes) + + var/i = 0 + for(var/thing in things) + var/datum/D = thing + i++ + //try one of 3 methods to shorten the type text: + // fancy type, + // fancy type with the base type removed from the begaining, + // the type with the base type removed from the begaining + var/fancytype = types[D.type] + if (findtext(fancytype, types[type])) + fancytype = copytext(fancytype, lentext(types[type])+1) + var/shorttype = copytext("[D.type]", lentext("[type]")+1) + if (lentext(shorttype) > lentext(fancytype)) + shorttype = fancytype + if (!lentext(shorttype)) + shorttype = "/" + + .["[D]([shorttype])\ref[D]#[i]"] = D + +/client/proc/mod_list_add_ass(atom/O) //hehe + + var/list/L = vv_get_value(restricted_classes = list(VV_RESTORE_DEFAULT)) + var/class = L["class"] + if (!class) + return + var/var_value = L["value"] + + if(class == VV_TEXT || class == VV_MESSAGE) + var/list/varsvars = vv_parse_text(O, var_value) + for(var/V in varsvars) + var_value = replacetext(var_value,"\[[V]]","[O.vars[V]]") + + return var_value + + +/client/proc/mod_list_add(list/L, atom/O, original_name, objectvar) + var/list/LL = vv_get_value(restricted_classes = list(VV_RESTORE_DEFAULT)) + var/class = LL["class"] + if (!class) + return + var/var_value = LL["value"] + + if(class == VV_TEXT || class == VV_MESSAGE) + var/list/varsvars = vv_parse_text(O, var_value) + for(var/V in varsvars) + var_value = replacetext(var_value,"\[[V]]","[O.vars[V]]") + + if (O) + L = L.Copy() + + L += var_value + + switch(alert("Would you like to associate a value with the list entry?",,"Yes","No")) + if("Yes") + L[var_value] = mod_list_add_ass(O) //hehe + if (O) + if (O.vv_edit_var(objectvar, L) == FALSE) + to_chat(src, "Your edit was rejected by the object.") + return + log_world("### ListVarEdit by [src]: [(O ? O.type : "/list")] [objectvar]: ADDED=[var_value]") + log_admin("[key_name(src)] modified [original_name]'s [objectvar]: ADDED=[var_value]") + message_admins("[key_name_admin(src)] modified [original_name]'s [objectvar]: ADDED=[var_value]") + +/client/proc/mod_list(list/L, atom/O, original_name, objectvar, index, autodetect_class = FALSE) + if(!check_rights(R_VAREDIT)) + return + if(!istype(L, /list)) + to_chat(src, "Not a List.") + return + + if(L.len > 1000) + var/confirm = alert(src, "The list you're trying to edit is very long, continuing may crash the server.", "Warning", "Continue", "Abort") + if(confirm != "Continue") + return + + + + var/list/names = list() + for (var/i in 1 to L.len) + var/key = L[i] + var/value + if (IS_NORMAL_LIST(L) && !isnum(key)) + value = L[key] + if (value == null) + value = "null" + names["#[i] [key] = [value]"] = i + if (!index) + var/variable = input("Which var?","Var") as null|anything in names + "(ADD VAR)" + "(CLEAR NULLS)" + "(CLEAR DUPES)" + "(SHUFFLE)" + + if(variable == null) + return + + if(variable == "(ADD VAR)") + mod_list_add(L, O, original_name, objectvar) + return + + if(variable == "(CLEAR NULLS)") + L = L.Copy() + listclearnulls(L) + if (!O.vv_edit_var(objectvar, L)) + to_chat(src, "Your edit was rejected by the object.") + return + log_world("### ListVarEdit by [src]: [O.type] [objectvar]: CLEAR NULLS") + log_admin("[key_name(src)] modified [original_name]'s [objectvar]: CLEAR NULLS") + message_admins("[key_name_admin(src)] modified [original_name]'s list [objectvar]: CLEAR NULLS") + return + + if(variable == "(CLEAR DUPES)") + L = uniqueList(L) + if (!O.vv_edit_var(objectvar, L)) + to_chat(src, "Your edit was rejected by the object.") + return + log_world("### ListVarEdit by [src]: [O.type] [objectvar]: CLEAR DUPES") + log_admin("[key_name(src)] modified [original_name]'s [objectvar]: CLEAR DUPES") + message_admins("[key_name_admin(src)] modified [original_name]'s list [objectvar]: CLEAR DUPES") + return + + if(variable == "(SHUFFLE)") + L = shuffle(L) + if (!O.vv_edit_var(objectvar, L)) + to_chat(src, "Your edit was rejected by the object.") + return + log_world("### ListVarEdit by [src]: [O.type] [objectvar]: SHUFFLE") + log_admin("[key_name(src)] modified [original_name]'s [objectvar]: SHUFFLE") + message_admins("[key_name_admin(src)] modified [original_name]'s list [objectvar]: SHUFFLE") + return + + index = names[variable] + + + var/assoc_key + if (index == null) + return + var/assoc = 0 + var/prompt = alert(src, "Do you want to edit the key or its assigned value?", "Associated List", "Key", "Assigned Value", "Cancel") + if (prompt == "Cancel") + return + if (prompt == "Assigned Value") + assoc = 1 + assoc_key = L[index] + var/default + var/variable + var/old_assoc_value //EXPERIMENTAL - Keep old associated value while modifying key, if any + if (assoc) + variable = L[assoc_key] + else + variable = L[index] + //EXPERIMENTAL - Keep old associated value while modifying key, if any + var/found = L[variable] + if(!isnull(found)) + old_assoc_value = found + // + + default = vv_get_class(objectvar, variable) + + to_chat(src, "Variable appears to be [uppertext(default)].") + + to_chat(src, "Variable contains: [variable]") + + if(default == VV_NUM) + var/dir_text = "" + var/tdir = variable + if(tdir > 0 && tdir < 16) + if(tdir & 1) + dir_text += "NORTH" + if(tdir & 2) + dir_text += "SOUTH" + if(tdir & 4) + dir_text += "EAST" + if(tdir & 8) + dir_text += "WEST" + + if(dir_text) + to_chat(usr, "If a direction, direction is: [dir_text]") + + var/original_var = variable + + if (O) + L = L.Copy() + var/class + if(autodetect_class) + if (default == VV_TEXT) + default = VV_MESSAGE + class = default + var/list/LL = vv_get_value(default_class = default, current_value = original_var, restricted_classes = list(VV_RESTORE_DEFAULT), extra_classes = list(VV_LIST, "DELETE FROM LIST")) + class = LL["class"] + if (!class) + return + var/new_var = LL["value"] + + if(class == VV_MESSAGE) + class = VV_TEXT + + switch(class) //Spits a runtime error if you try to modify an entry in the contents list. Dunno how to fix it, yet. + if(VV_LIST) + mod_list(variable, O, original_name, objectvar) + + if("DELETE FROM LIST") + L.Cut(index, index+1) + if (O) + if (O.vv_edit_var(objectvar, L)) + to_chat(src, "Your edit was rejected by the object.") + return + log_world("### ListVarEdit by [src]: [O.type] [objectvar]: REMOVED=[html_encode("[original_var]")]") + log_admin("[key_name(src)] modified [original_name]'s [objectvar]: REMOVED=[original_var]") + message_admins("[key_name_admin(src)] modified [original_name]'s [objectvar]: REMOVED=[original_var]") + return + + if(VV_TEXT) + var/list/varsvars = vv_parse_text(O, new_var) + for(var/V in varsvars) + new_var = replacetext(new_var,"\[[V]]","[O.vars[V]]") + + + if(assoc) + L[assoc_key] = new_var + else + L[index] = new_var + if(!isnull(old_assoc_value) && IS_VALID_ASSOC_KEY(new_var)) + L[new_var] = old_assoc_value + if (O) + if (O.vv_edit_var(objectvar, L) == FALSE) + to_chat(src, "Your edit was rejected by the object.") + return + log_world("### ListVarEdit by [src]: [(O ? O.type : "/list")] [objectvar]: [original_var]=[new_var]") + log_admin("[key_name(src)] modified [original_name]'s [objectvar]: [original_var]=[new_var]") + message_admins("[key_name_admin(src)] modified [original_name]'s varlist [objectvar]: [original_var]=[new_var]") + +/proc/vv_varname_lockcheck(param_var_name) + if(param_var_name in GLOB.VVlocked) + if(!check_rights(R_DEBUG)) + return FALSE + if(param_var_name in GLOB.VVckey_edit) + if(!check_rights(R_SPAWN|R_DEBUG)) + return FALSE + if(param_var_name in GLOB.VVicon_edit_lock) + if(!check_rights(R_FUN|R_DEBUG)) + return FALSE + return TRUE + +/client/proc/modify_variables(atom/O, param_var_name = null, autodetect_class = 0) + if(!check_rights(R_VAREDIT)) + return + + var/class + var/variable + var/var_value + + if(param_var_name) + if(!param_var_name in O.vars) + to_chat(src, "A variable with this name ([param_var_name]) doesn't exist in this datum ([O])") + return + variable = param_var_name + + else + var/list/names = list() + for (var/V in O.vars) + names += V + + names = sortList(names) + + variable = input("Which var?","Var") as null|anything in names + if(!variable) + return + + if(!O.can_vv_get(variable)) + return + + var_value = O.vars[variable] + if(!vv_varname_lockcheck(variable)) + return + + var/default = vv_get_class(variable, var_value) + + if(isnull(default)) + to_chat(src, "Unable to determine variable type.") + else + to_chat(src, "Variable appears to be [uppertext(default)].") + + to_chat(src, "Variable contains: [var_value]") + + if(default == VV_NUM) + var/dir_text = "" + if(var_value > 0 && var_value < 16) + if(var_value & 1) + dir_text += "NORTH" + if(var_value & 2) + dir_text += "SOUTH" + if(var_value & 4) + dir_text += "EAST" + if(var_value & 8) + dir_text += "WEST" + + if(dir_text) + to_chat(src, "If a direction, direction is: [dir_text]") + + if(autodetect_class && default != VV_NULL) + if (default == VV_TEXT) + default = VV_MESSAGE + class = default + + var/list/value = vv_get_value(class, default, var_value, extra_classes = list(VV_LIST), var_name = variable) + class = value["class"] + + if (!class) + return + var/var_new = value["value"] + + if(class == VV_MESSAGE) + class = VV_TEXT + + var/original_name = "[O]" + + switch(class) + if(VV_LIST) + if(!islist(var_value)) + mod_list(list(), O, original_name, variable) + + mod_list(var_value, O, original_name, variable) + return + + if(VV_RESTORE_DEFAULT) + var_new = initial(O.vars[variable]) + + if(VV_TEXT) + var/list/varsvars = vv_parse_text(O, var_new) + for(var/V in varsvars) + var_new = replacetext(var_new,"\[[V]]","[O.vars[V]]") + + + if (O.vv_edit_var(variable, var_new) == FALSE) + to_chat(src, "Your edit was rejected by the object.") + return + vv_update_display(O, "varedited", VV_MSG_EDITED) + log_world("### VarEdit by [key_name(src)]: [O.type] [variable]=[var_value] => [var_new]") + log_admin("[key_name(src)] modified [original_name]'s [variable] from [html_encode("[var_value]")] to [html_encode("[var_new]")]") + var/msg = "[key_name_admin(src)] modified [original_name]'s [variable] from [var_value] to [var_new]" + message_admins(msg) + admin_ticket_log(O, msg) + return TRUE diff --git a/code/modules/admin/view_variables/topic.dm b/code/modules/admin/view_variables/topic.dm index 16550f6712..ce2c684c09 100644 --- a/code/modules/admin/view_variables/topic.dm +++ b/code/modules/admin/view_variables/topic.dm @@ -1,8 +1,12 @@ - +//DO NOT ADD MORE TO THIS FILE. +//Use vv_do_topic()! /client/proc/view_var_Topic(href, href_list, hsrc) - //This should all be moved over to datum/admins/Topic() or something ~Carn - if( (usr.client != src) || !src.holder ) + if((usr.client != src) || !src.holder) return + var/datum/target = locate(href_list["target"]) + if(target) + target.vv_do_topic(href_list) + if(href_list["Vars"]) debug_variables(locate(href_list["Vars"])) @@ -163,11 +167,12 @@ href_list["datumrefresh"] = href_list["make_skeleton"] else if(href_list["delall"]) - if(!check_rights(R_DEBUG|R_SERVER)) return + if(!check_rights(R_DEBUG|R_SERVER)) + return var/obj/O = locate(href_list["delall"]) if(!isobj(O)) - usr << "This can only be used on instances of type /obj" + to_chat(usr, "This can only be used on instances of type /obj") return var/action_type = alert("Strict type ([O.type]) or type and all subtypes?",,"Strict type","Type and subtypes","Cancel") @@ -188,55 +193,24 @@ if(Obj.type == O_type) i++ qdel(Obj) + CHECK_TICK if(!i) - usr << "No objects of this type exist" + to_chat(usr, "No objects of this type exist") return - log_admin("[key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted)") - message_admins("[key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted)") + log_admin("[key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted) ") + message_admins("[key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted) ") if("Type and subtypes") var/i = 0 for(var/obj/Obj in world) if(istype(Obj,O_type)) i++ qdel(Obj) + CHECK_TICK if(!i) - usr << "No objects of this type exist" + to_chat(usr, "No objects of this type exist") return - log_admin("[key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted)") - message_admins("[key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted)") - - else if(href_list["explode"]) - if(!check_rights(R_DEBUG|R_FUN)) return - - var/atom/A = locate(href_list["explode"]) - if(!isobj(A) && !ismob(A) && !isturf(A)) - usr << "This can only be done to instances of type /obj, /mob and /turf" - return - - src.cmd_admin_explosion(A) - href_list["datumrefresh"] = href_list["explode"] - - else if(href_list["emp"]) - if(!check_rights(R_DEBUG|R_FUN)) return - - var/atom/A = locate(href_list["emp"]) - if(!isobj(A) && !ismob(A) && !isturf(A)) - usr << "This can only be done to instances of type /obj, /mob and /turf" - return - - src.cmd_admin_emp(A) - href_list["datumrefresh"] = href_list["emp"] - - else if(href_list["mark_object"]) - if(!check_rights(0)) return - - var/datum/D = locate(href_list["mark_object"]) - if(!istype(D)) - usr << "This can only be done to instances of type /datum" - return - - src.holder.marked_datum = D - href_list["datumrefresh"] = href_list["mark_object"] + log_admin("[key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted) ") + message_admins("[key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted) ") else if(href_list["rotatedatum"]) if(!check_rights(0)) return @@ -474,7 +448,7 @@ usr << "This can only be done on mobs with clients" return - GLOB.nanomanager.send_resources(H.client) + SSnanoui.send_resources(H.client) usr << "Resource files sent" H << "Your NanoUI Resource files have been refreshed" @@ -519,15 +493,31 @@ log_admin("[key_name(usr)] dealt [amount] amount of [Text] damage to [L]") message_admins("[key_name(usr)] dealt [amount] amount of [Text] damage to [L]") href_list["datumrefresh"] = href_list["mobToDamage"] - - else if(href_list["call_proc"]) - var/datum/D = locate(href_list["call_proc"]) - if(istype(D) || istype(D, /client)) // can call on clients too, not just datums - callproc_targetpicked(1, D) + else if(href_list["expose"]) + if(!check_rights(R_ADMIN, FALSE)) + return + var/thing = locate(href_list["expose"]) + if(!thing) //Do NOT QDELETED check! + return + var/value = vv_get_value(VV_CLIENT) + if (value["class"] != VV_CLIENT) + return + var/client/C = value["value"] + if (!C) + return + var/prompt = alert("Do you want to grant [C] access to view this VV window? (they will not be able to edit or change anysrc nor open nested vv windows unless they themselves are an admin)", "Confirm", "Yes", "No") + if (prompt != "Yes") + return + if(!thing) + to_chat(usr, "The object you tried to expose to [C] no longer exists (GC'd)") + return + message_admins("[key_name_admin(usr)] Showed [key_name_admin(C)] a VV window") + log_admin("Admin [key_name(usr)] Showed [key_name(C)] a VV window of a [src]") + to_chat(C, "[holder.fakekey ? "an Administrator" : "[usr.client.key]"] has granted you access to view a View Variables window") + C.debug_variables(thing) if(href_list["datumrefresh"]) var/datum/DAT = locate(href_list["datumrefresh"]) if(istype(DAT, /datum) || istype(DAT, /client)) debug_variables(DAT) - return diff --git a/code/modules/admin/view_variables/view_variables.dm b/code/modules/admin/view_variables/view_variables.dm index cb110d4e86..efa6f424f1 100644 --- a/code/modules/admin/view_variables/view_variables.dm +++ b/code/modules/admin/view_variables/view_variables.dm @@ -1,183 +1,284 @@ - -// Variables to not even show in the list. -// step_* and bound_* are here because they literally break the game and do nothing else. -// parent_type is here because it's pointless to show in VV. -/var/list/view_variables_hide_vars = list("bound_x", "bound_y", "bound_height", "bound_width", "bounds", "parent_type", "step_x", "step_y", "step_size") -// Variables not to expand the lists of. Vars is pointless to expand, and overlays/underlays cannot be expanded. -/var/list/view_variables_dont_expand = list("overlays", "underlays", "vars") - /client/proc/debug_variables(datum/D in world) set category = "Debug" set name = "View Variables" + //set src in world + var/static/cookieoffset = rand(1, 9999) //to force cookies to reset after the round. - if(!check_rights(0)) + if(!usr.client || !usr.client.holder) //The usr vs src abuse in this proc is intentional and must not be changed + to_chat(usr, "You need to be an administrator to access this.") return if(!D) return - var/icon/sprite - if(istype(D, /atom)) - var/atom/A = D - if(A.icon && A.icon_state) - sprite = icon(A.icon, A.icon_state) - usr << browse_rsc(sprite, "view_vars_sprite.png") + var/islist = islist(D) + if (!islist && !istype(D)) + return - usr << browse_rsc('code/js/view_variables.js', "view_variables.js") + var/title = "" + var/refid = "\ref[D]" + var/icon/sprite + var/hash + + var/type = /list + if (!islist) + type = D.type + + if(istype(D, /atom)) + var/atom/AT = D + if(AT.icon && AT.icon_state) + sprite = new /icon(AT.icon, AT.icon_state) + hash = md5(AT.icon) + hash = md5(hash + AT.icon_state) + src << browse_rsc(sprite, "vv[hash].png") + + title = "[D] (\ref[D]) = [type]" + var/formatted_type = replacetext("[type]", "/", "/") + + var/sprite_text + if(sprite) + sprite_text = "
    +
    " + var/list/header = islist(D)? list("/list") : D.vv_get_header() + + var/marked + if(holder && holder.marked_datum && holder.marked_datum == D) + marked = VV_MSG_MARKED + var/varedited_line = "" + if(!islist && (D.datum_flags & DF_VAR_EDITED)) + varedited_line = VV_MSG_EDITED + var/deleted_line + if(!islist && D.gc_destroyed) + deleted_line = VV_MSG_DELETED + + var/list/dropdownoptions = list() + var/autoconvert_dropdown = FALSE + if (islist) + dropdownoptions = list( + "---", + "Add Item" = "?_src_=vars;listadd=[refid]", + "Remove Nulls" = "?_src_=vars;listnulls=[refid]", + "Remove Dupes" = "?_src_=vars;listdupes=[refid]", + "Set len" = "?_src_=vars;listlen=[refid]", + "Shuffle" = "?_src_=vars;listshuffle=[refid]", + "Show VV To Player" = "?_src_=vars;expose=[refid]" + ) + autoconvert_dropdown = TRUE + else + dropdownoptions = D.vv_get_dropdown() + var/list/dropdownoptions_html = list() + if(autoconvert_dropdown) + for (var/name in dropdownoptions) + var/link = dropdownoptions[name] + if (link) + dropdownoptions_html += "" + else + dropdownoptions_html += "" + else + dropdownoptions_html = dropdownoptions + D.get_view_variables_options() + + var/list/names = list() + if (!islist) + for (var/V in D.vars) + names += V + sleep(1)//For some reason, without this sleep, VVing will cause client to disconnect on certain objects. + + var/list/variable_html = list() + if (islist) + var/list/L = D + for (var/i in 1 to L.len) + var/key = L[i] + var/value + if (IS_NORMAL_LIST(L) && !isnum(key)) + value = L[key] + variable_html += debug_variable(i, value, 0, D) + else + + names = sortList(names) + for (var/V in names) + if(D.can_vv_get(V)) + variable_html += D.vv_get_var(V) var/html = {" - - - - [D] (\ref[D] - [D.type]) - - - -
    - + + + [title] + + + + +
    +
    + -
    - - [sprite ? "" : ""] - -
    [D.get_view_variables_header()]
    + + + + +
    + [sprite_text] +
    + [header.Join()] +
    +
    - [replacetext("[D.type]", "/", "/")] - [holder.marked_datum == D ? "
    Marked Object" : ""] + [formatted_type] + [marked] + [varedited_line] + [deleted_line]
    - Refresh + Refresh
    - + + [dropdownoptions_html.Join()]
    -
    -
    - - E - Edit, tries to determine the variable type by itself.
    - C - Change, asks you for the var type first.
    - M - Mass modify: changes this variable for all objects of this type.
    -
    -
    - + +
    + +
    + + E - Edit, tries to determine the variable type by itself.
    + C - Change, asks you for the var type first.
    + M - Mass modify: changes this variable for all objects of this type.
    +
    +
    + + -
    Search:
    - +
    -
    -
      - [make_view_variables_var_list(D)] -
    - - - "} +
    +
    +
      + [variable_html.Join()] +
    + + + +"} + src << browse(html, "window=variables[refid];size=475x650") - usr << browse(html, "window=variables\ref[D];size=475x650") - - -/proc/make_view_variables_var_list(datum/D) - . = "" - var/list/variables = list() - for(var/x in D.vars) - if(x in view_variables_hide_vars) - continue - variables += x - variables = sortList(variables) - for(var/x in variables) - . += make_view_variables_var_entry(D, x, D.vars[x]) - -/proc/make_view_variables_var_entry(datum/D, varname, value, level=0) - var/ecm = null - var/vtext = null - var/extra = null - - if(D) - ecm = {" - (E) - (C) - (M) - "} - - if(isnull(value)) - vtext = "null" - else if(istext(value)) - vtext = "\"[value]\"" - else if(isicon(value)) - vtext = "[value]" - else if(isfile(value)) - vtext = "'[value]'" - else if(istype(value, /datum)) - var/datum/DA = value - if("[DA]" == "[DA.type]" || !"[DA]") - vtext = "\ref[DA] - [DA.type]" - else - vtext = "\ref[DA] - [DA] ([DA.type])" - else if(istype(value, /client)) - var/client/C = value - vtext = "\ref[C] - [C] ([C.type])" - else if(islist(value)) - var/list/L = value - var/removed = 0 - if(varname == "contents") - var/list/original = value - L = original.Copy() //We'll take a copy to manipulate - removed = D.view_variables_filter_contents(L) - vtext = "/list ([L.len]+[removed]H)" - if(!(varname in view_variables_dont_expand) && L.len > 0 && L.len < 100) - extra = "
      " - var/index = 1 - for (var/entry in L) - if(istext(entry)) - extra += make_view_variables_var_entry(null, entry, L[entry], level+1) - else - extra += make_view_variables_var_entry(null, index, L[index], level+1) - index++ - extra += "
    " - else - vtext = "[value]" - - return "
  • [ecm][varname] = [vtext][extra]
  • " - -//Allows us to mask out some contents when it's not necessary to show them -//For example, organs on humans, as the organs are stored in other lists which will also be present -//So there's really no need to list them twice. -/datum/proc/view_variables_filter_contents(list/L) - return 0 //Return how many items you removed. - -/mob/living/carbon/human/view_variables_filter_contents(list/L) - . = ..() - L -= ability_master - .++ - -/mob/living/carbon/human/view_variables_filter_contents(list/L) - . = ..() - var/len_before = L.len - L -= organs - L -= internal_organs - . += len_before - L.len +/client/proc/vv_update_display(datum/D, span, content) + src << output("[span]:[content]", "variables\ref[D].browser:replace_span") diff --git a/code/modules/ai/__readme.dm b/code/modules/ai/__readme.dm new file mode 100644 index 0000000000..85b49ec6cb --- /dev/null +++ b/code/modules/ai/__readme.dm @@ -0,0 +1,201 @@ +/* +[Summary] + +This module contains an AI implementation designed to be (at the base level) mobtype-agnostic, +by being held inside a datum instead of being written into the mob directly. More specialized +subtypes of the base AI may be designed with a specific mob type in mind, but the base system +should be compatible with most types of mobs which have the needed Interfaces in place to +support them. + +When designing a new mob, all that is needed to give a mob an AI is to set +its 'ai_holder_type' variable to the path of the AI that is desired. + + +[Seperation] + +In previous iterations of AI systems, the AI is generally written into the mob's code directly, +which has some advantages, but often makes the code rigid, and also tied the speed of the AI +to the mob's own ticker, meaning it could only decide every two seconds. + +Instead, this version has the code for the AI held inside an /datum/ai_holder object, +which is carried by the mob it controls. This gives some advantages; + All /mob/living mobs can potentially have an AI applied to them, and utilize the + same base code while adding specialized code on top. + + Interfaces allow the base AI code to not need to know what particular mode it's controlling. + + The processing of the AI is independant of the mob's Life() cycle, which allows for a + different clock rate. + + Seperating the AI from the mob simplies the mob's code greatly. + + It is more logical to think that a mob is the 'body', where as its ai_holder is + the 'mind'. + + AIs can be applied or disabled on the fly by instantiating or deleting the + ai_holder, if needed. + + +The current implementation also has some disadvantages, but they can perhaps be resolved +in the future. + AI-driven mob movement and attack speed is tied to half-second delays due to the + AI subsystem ticking at that rate. Porting the timer subsystem and integrating + callbacks into basic AI actions (moving, attacking) can potentially resolve that. + + It can be difficult to modify AI variables at mob instantiation without an ugly + delay, as the ai_holder might not exist yet. + + +[Flow of Processing] + +Terrible visual representation here; +AI Subsystem -> Every 0.5s -> /datum/ai_holder/handle_tactics() -> switch(stance)... + -> Every 2.0s -> /datum/ai_holder/handle_strategicals() -> switch(stance)... + +The AI datum is not processed by the mob itself, but instead it is directly processed +by a new AI subsystem. The AI subsystem contains a list of all active ai_holder +objects, which is iterated every tick to process each individual ai_holder +object attached to a mob. + +Each ai_holder actually has two 'tracks' for processing, a 'fast' track +and a 'slow' track. + +The fast track is named handle_tactics(), and is called every 0.5 seconds. + +The slow track is named handle_strategicals(), and is called every 2 seconds. + +When an ai_holder is iterated on inside the AI subsystem's list, it first +calls that ai_holder's handle_tactics(). It will then call that ai_holder's +handle_strategicals() every fourth tick, effectively doing so every two seconds. + +Both functions do different things depending on which 'stance' the +ai_holder is in. See the Stances section for more information. + +The fast track is for 'cheap' processing that needs to happen fast, such as +walking along a path, initiating an attack, or firing a gun. The rate that +it is called allows for the ai_holder to interact with the world through +its mob very often, giving a more convincing appearance of intelligence, +allowing for faster reaction times to certain events, and allowing for +variable attack speeds that would not be possible when bound to a +two second Life() cycle. + +The slow track, on the other hand, is for 'expensive' processing that might +be too demanding on the CPU to do every half a second, such as +re/calculating an A* path (if the mob uses A*), or running a complicated +tension assessment to determine how brave the mob is feeling. This is the +same delay used for certain tasks in the old implementation, but it is less +noticable due to the mob appearing to do things inbetween those two seconds. + +The purpose of having two tracks is to allow for 'fast' and 'slow' actions +to be more easily encapsulated, and ensures that all ai_holders are syncronized +with each other, as opposed to having individual tick counters inside all of +the ai_holder instances. It should be noted that handle_tactics() is always +called first, before handle_strategicals() every two seconds. + +[Process Skipping] + +An ai_holder object can choose to enter a 'busy' state, or a 'sleep' state, +in order to avoid processing. + +When busy, the AI subsystem will skip over the ai_holder until it is no +longer busy. The busy state is intended to be short-term, and is usually +toggled by the mob when doing something with a delay, so that the ai_holder +does not accidentally do something to inturrupt something important, like +a special attack. + +The longer term alternative to the busy state is the sleep state. Unlike +being busy, an ai_holder set to sleep will remove itself from the +AI subsystem's list, meaning it will no longer process until something +else 'wakes' it. This is usually done when the mob dies or a client +logs into an AI-controlled mob (and the AI is not set to ignore that, +with the autopilot variable). If the mob is revived, the AI will be +awakened automatically. + +The ai_holder functions, and mob functions that are called by the +ai_holder, should not be sleep()ed, as it will block the AI Subsystem +from processing the other ai_holders until the sleep() finishes. +Delays on the mob typically have set waitfor = FALSE, or spawn() is used. + + +[Stances] + +The AI has a large number of states that it can be in, called stances. +The AI will act in a specific way depending on which stance it is in, +and only one stance can be active at a time. This effectively creates +a state pattern. + +To change the stance, set_stance() is used, with the new stance as +the first argument. It should be noted that the change is not immediate, +and it will react to the change next tick instead of immediately switching +to the new stance and acting on that in the same tick. This is done to help +avoid infinite loops (I.E. Stance A switches to Stance B, which then +switches to Stance A, and so on...), and the delay is very short so +it should not be an issue. + +See code/__defines/mob.dm for a list of stance defines, and descriptions +about their purpose. Generally, each stance has its own file in the AI +module folder and are mostly self contained, however some files instead +deal with general things that other stances may require, such as targeting +or movement. + +[Interfaces] + +Interfaces are a concept that is used to help bridge the gap between +the ai_holder, and its mob. Because the (base) ai_holder is explicitly +designed to not be specific to any type of mob, all that it knows is +that it is controlling a /mob/living mob. Some mobs work very differently, +between mob types such as /mob/living/simple_mob, /mob/living/silicon/robot, +/mob/living/carbon/human, and more. + +The solution to the vast differences between mob types is to have the +mob itself deal with how to handle a specific task, such as attacking +something, talking, moving, etc. Interfaces exist to do this. + +Interfaces are applied on the mob-side, and are generally specific to +that mob type. This lets the ai_holder not have to worry about specific +implementations and instead just tell the Interface that it wants to attack +something, or move into a tile. The AI does not need to know if the mob its +controlling has hands, instead that is the mob's responsibility. + +Interface functions have an uppercase I at the start of the function name, +and then the function they are bridging between the AI and the mob +(if it exists), e.g. IMove(), IAttack(), ISay(). + +Interfaces are also used for the AI to ask its mob if it can do certain +things, without having to actually know what type of mob it is attached to. +For example, ICheckRangedAttack() tells the AI if it is possible to do a +ranged attack. For simple_mobs, they can if a ranged projectile type was set, +where as for a human mob, it could check if a gun is in a hand. For a borg, +it could check if a gun is inside their current module. + +[Say List] + +A /datum/say_list is a very light datum that holds a list of strings for the +AI to have their mob say based on certain conditions, such as when threatening +to kill another mob. Despite the name, a say_list also can contain emotes +and some sounds. + +The reason that it is in a seperate datum is to allow for multiple mob types +to have the same text, even when inheritence cannot do that, such as +mercenaries and fake piloted mecha mobs. + +The say_list datum is applied to the mob itself and not held inside the AI datum. + +[Subtypes] + +Some subtypes of ai_holder are more specialized, but remain compatible with +most mob types. There are many different subtypes that make the AI act different +by overriding a function, such as kiting their target, moving up close while +using ranged attacks, or running away if not cloaked. + +Other subtypes are very specific about what kind of mob it controls, and trying +to apply them to a different type of mob will likely result in a lot of bugs +or ASSERT() failures. The xenobio slime AI is an example of the latter. + +To use a specific subtype on a mob, all that is needed is setting the mob's +ai_holder_type to the subtype desired, and it will create that subtype when +the mob is initialize()d. Switching to a subtype 'live' will require additional +effort on the coder. + + +*/ \ No newline at end of file diff --git a/code/modules/ai/_defines.dm b/code/modules/ai/_defines.dm new file mode 100644 index 0000000000..e94d26b3c3 --- /dev/null +++ b/code/modules/ai/_defines.dm @@ -0,0 +1,29 @@ +// Defines for the ai_intelligence var. +// Controls if the mob will do 'advanced tactics' like running from grenades. +#define AI_DUMB 1 // Be dumber than usual. +#define AI_NORMAL 2 // Default level. +#define AI_SMART 3 // Will do more processing to be a little smarter, like not walking while confused if it could risk stepping randomly onto a bad tile. + +#define ai_log(M,V) if(debug_ai) ai_log_output(M,V) + +// Logging level defines. +#define AI_LOG_OFF 0 // Don't show anything. +#define AI_LOG_ERROR 1 // Show logs of things likely causing the mob to not be functioning correctly. +#define AI_LOG_WARNING 2 // Show less serious but still helpful to know issues that might be causing things to work incorrectly. +#define AI_LOG_INFO 3 // Important regular events, like selecting a target or switching stances. +#define AI_LOG_DEBUG 4 // More detailed information about the flow of execution. +#define AI_LOG_TRACE 5 // Even more detailed than the last. Will absolutely flood your chatlog. + +// Results of pre-movement checks. +// Todo: Move outside AI code? +#define MOVEMENT_ON_COOLDOWN -1 // Recently moved and needs to try again soon. +#define MOVEMENT_FAILED 0 // Move() returned false for whatever reason and the mob didn't move. +#define MOVEMENT_SUCCESSFUL 1 // Move() returned true and the mob hopefully moved. + +// Reasons for targets to not be valid. Based on why, the AI responds differently. +#define AI_TARGET_VALID 0 // We can fight them. +#define AI_TARGET_INVIS 1 // They were in field of view but became invisible. Switch to STANCE_BLINDFIGHT if no other viable targets exist. +#define AI_TARGET_NOSIGHT 2 // No longer in field of view. Go STANCE_REPOSITION to their last known location if no other targets are seen. +#define AI_TARGET_ALLY 3 // They are an ally. Find a new target. +#define AI_TARGET_DEAD 4 // They're dead. Find a new target. +#define AI_TARGET_INVINCIBLE 5 // Target is currently unable to receive damage for whatever reason. Find a new target or wait. diff --git a/code/modules/ai/aI_holder_subtypes/simple_mob_ai.dm b/code/modules/ai/aI_holder_subtypes/simple_mob_ai.dm new file mode 100644 index 0000000000..8949e8c70e --- /dev/null +++ b/code/modules/ai/aI_holder_subtypes/simple_mob_ai.dm @@ -0,0 +1,143 @@ +// Base AIs for simple mobs. +// Mob-specific AIs are in their mob's file. + +/datum/ai_holder/simple_mob + hostile = TRUE // The majority of simplemobs are hostile. + retaliate = TRUE // The majority of simplemobs will fight back. + cooperative = TRUE + returns_home = FALSE + can_flee = FALSE + speak_chance = 1 // If the mob's saylist is empty, nothing will happen. + wander = TRUE + base_wander_delay = 4 + +// For non-hostile animals, and pets like Ian and Runtime. +/datum/ai_holder/simple_mob/passive + hostile = FALSE + retaliate = FALSE + can_flee = TRUE + violent_breakthrough = FALSE + +// Won't wander away as quickly, ideal for event-spawned mobs like carp or drones. +/datum/ai_holder/simple_mob/event + base_wander_delay = 8 + +// Doesn't really act until told to by something on the outside. +/datum/ai_holder/simple_mob/inert + hostile = FALSE + retaliate = FALSE + can_flee = FALSE + wander = FALSE + speak_chance = 0 + cooperative = FALSE + violent_breakthrough = FALSE // So it can open doors but not attack windows and shatter the literal illusion. + +// Used for technomancer illusions, to resemble player movement better. +/datum/ai_holder/simple_mob/inert/astar + use_astar = TRUE + +// Ranged mobs. + +/datum/ai_holder/simple_mob/ranged +// ranged = TRUE + +// Tries to not waste ammo. +/datum/ai_holder/simple_mob/ranged/careful + conserve_ammo = TRUE + +/datum/ai_holder/simple_mob/ranged/pointblank + pointblank = TRUE + +// Runs away from its target if within a certain distance. +/datum/ai_holder/simple_mob/ranged/kiting + pointblank = TRUE // So we don't need to copypaste post_melee_attack(). + var/run_if_this_close = 4 // If anything gets within this range, it'll try to move away. + var/moonwalk = TRUE // If true, mob turns to face the target while kiting, otherwise they turn in the direction they moved towards. + +/datum/ai_holder/simple_mob/ranged/kiting/threatening + threaten = TRUE + threaten_delay = 1 SECOND // Less of a threat and more of pre-attack notice. + threaten_timeout = 30 SECONDS + conserve_ammo = TRUE + +// For event-spawned malf drones. +/datum/ai_holder/simple_mob/ranged/kiting/threatening/event + base_wander_delay = 8 + +/datum/ai_holder/simple_mob/ranged/kiting/no_moonwalk + moonwalk = FALSE + +/datum/ai_holder/simple_mob/ranged/kiting/on_engagement(atom/A) + if(get_dist(holder, A) < run_if_this_close) + holder.IMove(get_step_away(holder, A, run_if_this_close)) + if(moonwalk) + holder.face_atom(A) + +// Closes distance from the target even while in range. +/datum/ai_holder/simple_mob/ranged/aggressive + pointblank = TRUE + var/closest_distance = 1 // How close to get to the target. By default they will get into melee range (and then pointblank them). + +/datum/ai_holder/simple_mob/ranged/aggressive/on_engagement(atom/A) + if(get_dist(holder, A) > closest_distance) + holder.IMove(get_step_towards(holder, A)) + holder.face_atom(A) + +// Yakkity saxes while firing at you. +/datum/ai_holder/hostile/ranged/robust/on_engagement(atom/movable/AM) + step_rand(holder) + holder.face_atom(AM) + +// Switches intents based on specific criteria. +// Used for special mobs who do different things based on intents (and aren't slimes). +// Intent switching is generally done in pre_[ranged/special]_attack(), so that the mob can use the right attack for the right time. +/datum/ai_holder/simple_mob/intentional + + +// These try to avoid collateral damage. +/datum/ai_holder/simple_mob/restrained + violent_breakthrough = FALSE + conserve_ammo = TRUE + destructive = FALSE + +// This does the opposite of the above subtype. +/datum/ai_holder/simple_mob/destructive + destructive = TRUE + +// Melee mobs. + +/datum/ai_holder/simple_mob/melee + +// Dances around the enemy its fighting, making it harder to fight back. +/datum/ai_holder/simple_mob/melee/evasive + +/datum/ai_holder/simple_mob/melee/evasive/post_melee_attack(atom/A) + if(holder.Adjacent(A)) + holder.IMove(get_step(holder, pick(alldirs))) + holder.face_atom(A) + + + +// This AI hits something, then runs away for awhile. +// It will (almost) always flee if they are uncloaked, AND their target is not stunned. +/datum/ai_holder/simple_mob/melee/hit_and_run + can_flee = TRUE + +// Used for the 'running' part of hit and run. +/datum/ai_holder/simple_mob/melee/hit_and_run/special_flee_check() + if(!holder.is_cloaked()) + if(isliving(target)) + var/mob/living/L = target + return !L.incapacitated(INCAPACITATION_DISABLED) // Don't flee if our target is stunned in some form, even if uncloaked. This is so the mob keeps attacking a stunned opponent. + return TRUE // We're out in the open, uncloaked, and our target isn't stunned, so lets flee. + return FALSE + + +// Simple mobs that aren't hostile, but will fight back. +/datum/ai_holder/simple_mob/retaliate + hostile = FALSE + retaliate = TRUE + +// Simple mobs that retaliate and support others in their faction who get attacked. +/datum/ai_holder/simple_mob/retaliate/cooperative + cooperative = TRUE \ No newline at end of file diff --git a/code/modules/ai/aI_holder_subtypes/slime_xenobio_ai.dm b/code/modules/ai/aI_holder_subtypes/slime_xenobio_ai.dm new file mode 100644 index 0000000000..41abd45903 --- /dev/null +++ b/code/modules/ai/aI_holder_subtypes/slime_xenobio_ai.dm @@ -0,0 +1,269 @@ +// Specialized AI for slime simplemobs. +// Unlike the parent AI code, this will probably break a lot of things if you put it on something that isn't /mob/living/simple_mob/slime/xenobio + +/datum/ai_holder/simple_mob/xenobio_slime + hostile = TRUE + cooperative = TRUE + firing_lanes = TRUE + mauling = TRUE // They need it to get the most out of monkeys. + var/rabid = FALSE // Will attack regardless of discipline. + var/discipline = 0 // Beating slimes makes them less likely to lash out. In theory. + var/resentment = 0 // 'Unjustified' beatings make this go up, and makes it more likely for abused slimes to go rabid. + var/obedience = 0 // Conversely, 'justified' beatings make this go up, and makes discipline decay slower, potentially making it not decay at all. + + var/always_stun = FALSE // If true, the slime will elect to attempt to permastun the target. + + var/last_discipline_decay = null // Last world.time discipline was reduced from decay. + var/discipline_decay_time = 5 SECONDS // Earliest that one discipline can decay. + +/datum/ai_holder/simple_mob/xenobio_slime/sapphire + always_stun = TRUE // They know that stuns are godly. + intelligence_level = AI_SMART // Also knows not to walk while confused if it risks death. + +/datum/ai_holder/simple_mob/xenobio_slime/light_pink + discipline = 10 + obedience = 10 + +/datum/ai_holder/simple_mob/xenobio_slime/passive/New() // For Kendrick. + ..() + pacify() + +/datum/ai_holder/simple_mob/xenobio_slime/New() + ..() + ASSERT(istype(holder, /mob/living/simple_mob/slime/xenobio)) + +// Checks if disciplining the slime would be 'justified' right now. +/datum/ai_holder/simple_mob/xenobio_slime/proc/is_justified_to_discipline() + if(!can_act()) + return FALSE // The slime considers it abuse if they get stunned while already stunned. + if(rabid) + return TRUE + if(target && can_attack(target)) + if(ishuman(target)) + var/mob/living/carbon/human/H = target + if(istype(H.species, /datum/species/monkey)) + return FALSE // Attacking monkeys is okay. + return TRUE // Otherwise attacking other things is bad. + return FALSE // Not attacking anything. + +/datum/ai_holder/simple_mob/xenobio_slime/proc/can_command(mob/living/commander) + if(rabid) + return FALSE + if(!hostile) + return SLIME_COMMAND_OBEY +// if(commander in friends) +// return SLIME_COMMAND_FRIEND + if(holder.IIsAlly(commander)) + return SLIME_COMMAND_FACTION + if(discipline > resentment && obedience >= 5) + return SLIME_COMMAND_OBEY + return FALSE + +/datum/ai_holder/simple_mob/xenobio_slime/proc/adjust_discipline(amount, silent) + var/mob/living/simple_mob/slime/xenobio/my_slime = holder + if(amount > 0) + if(rabid) + return + var/justified = is_justified_to_discipline() + lost_target() // Stop attacking. + + if(justified) + obedience++ + if(!silent) + holder.say(pick("Fine...", "Okay...", "Sorry...", "I yield...", "Mercy...")) + else + if(prob(resentment * 20)) + enrage() + holder.say(pick("Evil...", "Kill...", "Tyrant...")) + else + if(!silent) + holder.say(pick("Why...?", "I don't understand...?", "Cruel...", "Stop...", "Nooo...")) + resentment++ // Done after check so first time will never enrage. + + discipline = between(0, discipline + amount, 10) + my_slime.update_mood() + +// This slime always enrages if disciplined. +/datum/ai_holder/simple_mob/xenobio_slime/red/adjust_discipline(amount, silent) + if(amount > 0 && !rabid) + holder.say("Grrr...") + holder.add_modifier(/datum/modifier/berserk, 30 SECONDS) + enrage() + +/datum/ai_holder/simple_mob/xenobio_slime/handle_special_strategical() + discipline_decay() + +// Handles decay of discipline. +/datum/ai_holder/simple_mob/xenobio_slime/proc/discipline_decay() + if(discipline > 0 && last_discipline_decay + discipline_decay_time < world.time) + if(!prob(75 + (obedience * 5))) + adjust_discipline(-1) + last_discipline_decay = world.time + +/datum/ai_holder/simple_mob/xenobio_slime/handle_special_tactic() + evolve_and_reproduce() + +// Hit the correct verbs to keep the slime species going. +/datum/ai_holder/simple_mob/xenobio_slime/proc/evolve_and_reproduce() + var/mob/living/simple_mob/slime/xenobio/my_slime = holder + if(my_slime.amount_grown >= 10) + // Press the correct verb when we can. + if(my_slime.is_adult) + my_slime.reproduce() // Splits into four new baby slimes. + else + my_slime.evolve() // Turns our holder into an adult slime. + + +// Called when pushed too far (or a red slime core was used). +/datum/ai_holder/simple_mob/xenobio_slime/proc/enrage() + var/mob/living/simple_mob/slime/xenobio/my_slime = holder + if(my_slime.harmless) + return + rabid = TRUE + my_slime.update_mood() + my_slime.visible_message(span("danger", "\The [src] enrages!")) + +// Called when using a pacification agent (or it's Kendrick being initalized). +/datum/ai_holder/simple_mob/xenobio_slime/proc/pacify() + lost_target() // So it stops trying to kill them. + rabid = FALSE + hostile = FALSE + retaliate = FALSE + cooperative = FALSE + +// The holder's attack changes based on intent. This lets the AI choose what effect is desired. +/datum/ai_holder/simple_mob/xenobio_slime/pre_melee_attack(atom/A) + if(istype(A, /mob/living)) + var/mob/living/L = A + var/mob/living/simple_mob/slime/xenobio/my_slime = holder + + if( (!L.lying && prob(30 + (my_slime.power_charge * 7) ) || (!L.lying && always_stun) )) + my_slime.a_intent = I_DISARM // Stun them first. + else if(my_slime.can_consume(L) && L.lying) + my_slime.a_intent = I_GRAB // Then eat them. + else + my_slime.a_intent = I_HURT // Otherwise robust them. + +/datum/ai_holder/simple_mob/xenobio_slime/closest_distance(atom/movable/AM) + if(istype(AM, /mob/living)) + var/mob/living/L = AM + if(ishuman(L)) + var/mob/living/carbon/human/H = L + if(istype(H.species, /datum/species/monkey)) + return 1 // Otherwise ranged slimes will eat a lot less often. + if(L.stat >= UNCONSCIOUS) + return 1 // Melee (eat) the target if dead/dying, don't shoot it. + return ..() + +/datum/ai_holder/simple_mob/xenobio_slime/can_attack(atom/movable/AM) + . = ..() + if(.) // Do some additional checks because we have Special Code(tm). + if(ishuman(AM)) + var/mob/living/carbon/human/H = AM + if(istype(H.species, /datum/species/monkey)) // istype() is so they'll eat the alien monkeys too. + return TRUE // Monkeys are always food (sorry Pun Pun). + else if(H.species && H.species.name == SPECIES_PROMETHEAN) + return FALSE // Prometheans are always our friends. + if(discipline && !rabid) + return FALSE // We're a good slime. + +// Commands, reactions, etc +/datum/ai_holder/simple_mob/xenobio_slime/on_hear_say(mob/living/speaker, message) + ai_log("xenobio_slime/on_hear_say([speaker], [message]) : Entered.", AI_LOG_DEBUG) + var/mob/living/simple_mob/slime/xenobio/my_slime = holder + + if((findtext(message, num2text(my_slime.number)) || findtext(message, my_slime.name) || findtext(message, "slimes"))) // Talking to us. + + // First, make sure it's actually a player saying something and not an AI, or else we risk infinite loops. + if(!speaker.client) + return + + // Are all slimes being referred to? + // var/mass_order = FALSE + // if(findtext(message, "slimes")) + // mass_order = TRUE + + // Say hello back. + if(findtext(message, "hello") || findtext(message, "hi") || findtext(message, "greetings")) + delayed_say(pick("Hello...", "Hi..."), speaker) + + // Follow request. + if(findtext(message, "follow") || findtext(message, "come with me")) + if(!can_command(speaker)) + delayed_say(pick("No...", "I won't follow..."), speaker) + return + + delayed_say("Yes... I follow \the [speaker]...", speaker) + set_follow(speaker) + + // Squish request. + if(findtext(message , "squish")) + if(!can_command(speaker)) + delayed_say("No...", speaker) + return + + spawn(rand(1 SECOND, 2 SECONDS)) + if(!src || !holder || !can_act()) // We might've died/got deleted/etc in the meantime. + return + my_slime.squish() + + + // Stop request. + if(findtext(message, "stop") || findtext(message, "halt") || findtext(message, "cease")) + if(my_slime.victim) // We're being asked to stop eatting someone. + if(!can_command(speaker) || !is_justified_to_discipline()) + delayed_say("No...", speaker) + return + else + delayed_say("Fine...", speaker) + adjust_discipline(1, TRUE) + my_slime.stop_consumption() + + if(target) // We're being asked to stop chasing someone. + if(!can_command(speaker) || !is_justified_to_discipline()) + delayed_say("No...", speaker) + return + else + delayed_say("Fine...", speaker) + adjust_discipline(1, TRUE) // This must come before losing the target or it will be unjustified. + lost_target() + + + if(leader) // We're being asked to stop following someone. + if(can_command(speaker) == SLIME_COMMAND_FRIEND || leader == speaker) + delayed_say("Yes... I'll stop...", speaker) + lose_follow() + else + delayed_say("No... I'll keep following \the [leader]...", speaker) + + /* // Commented out since its mostly useless now due to slimes refusing to attack if it would make them naughty. + // Murder request + if(findtext(message, "harm") || findtext(message, "attack") || findtext(message, "kill") || findtext(message, "murder") || findtext(message, "eat") || findtext(message, "consume") || findtext(message, "absorb")) + if(can_command(speaker) < SLIME_COMMAND_FACTION) + delayed_say("No...", speaker) + return + + for(var/mob/living/L in view(7, my_slime) - list(my_slime, speaker)) + if(L == src) + continue // Don't target ourselves. + var/list/valid_names = splittext(L.name, " ") // Should output list("John", "Doe") as an example. + for(var/line in valid_names) // Check each part of someone's name. + if(findtext(message, lowertext(line))) // If part of someone's name is in the command, the slime targets them if allowed to. + if(!(mass_order && line == "slime")) //don't think random other slimes are target + if(can_attack(L)) + delayed_say("Okay... I attack \the [L]...", speaker) + give_target(L) + return + else + delayed_say("No... I won't attack \the [L].", speaker) + return + + // If we're here, it couldn't find anyone with that name. + delayed_say("No... I don't know who to attack...", speaker) + */ + ai_log("xenobio_slime/on_hear_say() : Exited.", AI_LOG_DEBUG) + +/datum/ai_holder/simple_mob/xenobio_slime/can_violently_breakthrough() + if(discipline && !rabid) // Good slimes don't shatter the windows because their buddy in an adjacent cell decided to piss off Slimesky. + return FALSE + return ..() \ No newline at end of file diff --git a/code/modules/ai/ai_holder.dm b/code/modules/ai/ai_holder.dm new file mode 100644 index 0000000000..4ef5507d5b --- /dev/null +++ b/code/modules/ai/ai_holder.dm @@ -0,0 +1,290 @@ +// This is a datum-based artificial intelligence for simple mobs (and possibly others) to use. +// The neat thing with having this here instead of on the mob is that it is independant of Life(), and that different mobs +// can use a more or less complex AI by giving it a different datum. + +/mob/living + var/datum/ai_holder/ai_holder = null + var/ai_holder_type = null // Which ai_holder datum to give to the mob when initialized. If null, nothing happens. + +/mob/living/Initialize() + if(ai_holder_type) + ai_holder = new ai_holder_type(src) + return ..() + +/mob/living/Destroy() + QDEL_NULL(ai_holder) + return ..() + +/datum/ai_holder + var/mob/living/holder = null // The mob this datum is going to control. + var/stance = STANCE_IDLE // Determines if the mob should be doing a specific thing, e.g. attacking, following, standing around, etc. + var/intelligence_level = AI_NORMAL // Adjust to make the AI be intentionally dumber, or make it more robust (e.g. dodging grenades). + var/autopilot = FALSE // If true, the AI won't be deactivated if a client gets attached to the AI's mob. + var/busy = FALSE // If true, the ticker will skip processing this mob until this is false. Good for if you need the + // mob to stay still (e.g. delayed attacking). If you need the mob to be inactive for an extended period of time, + // consider sleeping the AI instead. + + + +/datum/ai_holder/hostile + hostile = TRUE + +/datum/ai_holder/retaliate + hostile = TRUE + retaliate = TRUE + +/datum/ai_holder/New(var/new_holder) + ASSERT(new_holder) + holder = new_holder + SSai.processing += src + home_turf = get_turf(holder) + ..() + +/datum/ai_holder/Destroy() + holder = null + SSai.processing -= src // We might've already been asleep and removed, but byond won't care if we do this again and it saves a conditional. + home_turf = null + return ..() + + +// Now for the actual AI stuff. + +// Makes this ai holder not get processed. +// Called automatically when the host mob is killed. +// Potential future optimization would be to sleep AIs which mobs that are far away from in-round players. +/datum/ai_holder/proc/go_sleep() + if(stance == STANCE_SLEEP) + return + forget_everything() // If we ever wake up, its really unlikely that our current memory will be of use. + set_stance(STANCE_SLEEP) + SSai.processing -= src + +// Reverses the above proc. +// Revived mobs will wake their AI if they have one. +/datum/ai_holder/proc/go_wake() + if(stance != STANCE_SLEEP) + return + if(!should_wake()) + return + set_stance(STANCE_IDLE) + SSai.processing += src + +/datum/ai_holder/proc/should_wake() + if(holder.client && !autopilot) + return FALSE + if(holder.stat >= DEAD) + return FALSE + return TRUE + +// Resets a lot of 'memory' vars. +/datum/ai_holder/proc/forget_everything() + // Some of these might be redundant, but hopefully this prevents future bugs if that changes. + lose_follow() + lose_target() + lose_target_position() + give_up_movement() + +// 'Tactical' processes such as moving a step, meleeing an enemy, firing a projectile, and other fairly cheap actions that need to happen quickly. +/datum/ai_holder/proc/handle_tactics() + if(busy) + return + handle_special_tactic() + handle_stance_tactical() + +// 'Strategical' processes that are more expensive on the CPU and so don't get run as often as the above proc, such as A* pathfinding or robust targeting. +/datum/ai_holder/proc/handle_strategicals() + if(busy) + return + handle_special_strategical() + handle_stance_strategical() + +// Override these for special things without polluting the main loop. +/datum/ai_holder/proc/handle_special_tactic() + +/datum/ai_holder/proc/handle_special_strategical() + +/* + //AI Actions + if(!ai_inactive) + //Stanceyness + handle_stance() + + //Movement + if(!stop_automated_movement && wander && !anchored) //Allowed to move? + handle_wander_movement() + + //Speaking + if(speak_chance && stance == STANCE_IDLE) // Allowed to chatter? + handle_idle_speaking() + + //Resisting out buckles + if(stance != STANCE_IDLE && incapacitated(INCAPACITATION_BUCKLED_PARTIALLY)) + handle_resist() + + //Resisting out of closets + if(istype(loc,/obj/structure/closet)) + var/obj/structure/closet/C = loc + if(C.welded) + resist() + else + C.open() +*/ + +// For setting the stance WITHOUT processing it +/datum/ai_holder/proc/set_stance(var/new_stance) + ai_log("set_stance() : Setting stance from [stance] to [new_stance].", AI_LOG_INFO) + stance = new_stance + if(stance_coloring) // For debugging or really weird mobs. + stance_color() + +// This is called every half a second. +/datum/ai_holder/proc/handle_stance_tactical() + ai_log("========= Fast Process Beginning ==========", AI_LOG_TRACE) // This is to make it easier visually to disinguish between 'blocks' of what a tick did. + ai_log("handle_stance_tactical() : Called.", AI_LOG_TRACE) + + if(stance == STANCE_SLEEP) + ai_log("handle_stance_tactical() : Going to sleep.", AI_LOG_TRACE) + go_sleep() + return + + if(target && can_see_target(target)) + track_target_position() + + if(stance != STANCE_DISABLED && is_disabled()) // Stunned/confused/etc + ai_log("handle_stance_tactical() : Disabled.", AI_LOG_TRACE) + set_stance(STANCE_DISABLED) + return + + if(stance in STANCES_COMBAT) + // Should resist? We check this before fleeing so that we can actually flee and not be trapped in a chair. + if(holder.incapacitated(INCAPACITATION_BUCKLED_PARTIALLY)) + ai_log("handle_stance_tactical() : Going to handle_resist().", AI_LOG_TRACE) + handle_resist() + + else if(istype(holder.loc, /obj/structure/closet)) + var/obj/structure/closet/C = holder.loc + ai_log("handle_stance_tactical() : Inside a closet. Going to attempt escape.", AI_LOG_TRACE) + if(C.sealed) + holder.resist() + else + C.open() + + // Should we flee? + if(should_flee()) + ai_log("handle_stance_tactical() : Going to flee.", AI_LOG_TRACE) + set_stance(STANCE_FLEE) + return + + switch(stance) + if(STANCE_IDLE) + if(should_go_home()) + ai_log("handle_stance_tactical() : STANCE_IDLE, going to go home.", AI_LOG_TRACE) + go_home() + + else if(should_follow_leader()) + ai_log("handle_stance_tactical() : STANCE_IDLE, going to follow leader.", AI_LOG_TRACE) + set_stance(STANCE_FOLLOW) + + else if(should_wander()) + ai_log("handle_stance_tactical() : STANCE_IDLE, going to wander randomly.", AI_LOG_TRACE) + handle_wander_movement() + + if(STANCE_ALERT) + ai_log("handle_stance_tactical() : STANCE_ALERT, going to threaten_target().", AI_LOG_TRACE) + threaten_target() + + if(STANCE_APPROACH) + ai_log("handle_stance_tactical() : STANCE_APPROACH, going to walk_to_target().", AI_LOG_TRACE) + walk_to_target() + + if(STANCE_FIGHT) + ai_log("handle_stance_tactical() : STANCE_FIGHT, going to engage_target().", AI_LOG_TRACE) + engage_target() + + if(STANCE_MOVE) + ai_log("handle_stance_tactical() : STANCE_MOVE, going to walk_to_destination().", AI_LOG_TRACE) + walk_to_destination() + + if(STANCE_REPOSITION) // This is the same as above but doesn't stop if an enemy is visible since its an 'in-combat' move order. + ai_log("handle_stance_tactical() : STANCE_REPOSITION, going to walk_to_destination().", AI_LOG_TRACE) + walk_to_destination() + + if(STANCE_FOLLOW) + ai_log("handle_stance_tactical() : STANCE_FOLLOW, going to walk_to_leader().", AI_LOG_TRACE) + walk_to_leader() + + if(STANCE_FLEE) + ai_log("handle_stance_tactical() : STANCE_FLEE, going to flee_from_target().", AI_LOG_TRACE) + flee_from_target() + + if(STANCE_DISABLED) + ai_log("handle_stance_tactical() : STANCE_DISABLED.", AI_LOG_TRACE) + if(!is_disabled()) + ai_log("handle_stance_tactical() : No longer disabled.", AI_LOG_TRACE) + set_stance(STANCE_IDLE) + else + handle_disabled() + + ai_log("handle_stance_tactical() : Exiting.", AI_LOG_TRACE) + ai_log("========= Fast Process Ending ==========", AI_LOG_TRACE) + +// This is called every two seconds. +/datum/ai_holder/proc/handle_stance_strategical() + ai_log("++++++++++ Slow Process Beginning ++++++++++", AI_LOG_TRACE) + ai_log("handle_stance_strategical() : Called.", AI_LOG_TRACE) + + switch(stance) + if(STANCE_IDLE) + + if(speak_chance) // In the long loop since otherwise it wont shut up. + handle_idle_speaking() + + if(hostile) + ai_log("handle_stance_strategical() : STANCE_IDLE, going to find_target().", AI_LOG_TRACE) + find_target() + if(STANCE_APPROACH) + if(target) + ai_log("handle_stance_strategical() : STANCE_APPROACH, going to calculate_path([target]).", AI_LOG_TRACE) + calculate_path(target) + if(STANCE_MOVE) + if(hostile && find_target()) // This will switch its stance. + ai_log("handle_stance_strategical() : STANCE_MOVE, found target and was inturrupted.", AI_LOG_TRACE) + if(STANCE_FOLLOW) + if(hostile && find_target()) // This will switch its stance. + ai_log("handle_stance_strategical() : STANCE_FOLLOW, found target and was inturrupted.", AI_LOG_TRACE) + else if(leader) + ai_log("handle_stance_strategical() : STANCE_FOLLOW, going to calculate_path([leader]).", AI_LOG_TRACE) + calculate_path(leader) + + ai_log("handle_stance_strategical() : Exiting.", AI_LOG_TRACE) + ai_log("++++++++++ Slow Process Ending ++++++++++", AI_LOG_TRACE) + + +// Helper proc to turn AI 'busy' mode on or off without having to check if there is an AI, to simplify writing code. +/mob/living/proc/set_AI_busy(value) + if(ai_holder) + ai_holder.busy = value + +/mob/living/proc/is_AI_busy() + if(!ai_holder) + return FALSE + return ai_holder.busy + +// Helper proc to check for the AI's stance. +// Returns null if there's no AI holder, or the mob has a player and autopilot is not on. +// Otherwise returns the stance. +/mob/living/proc/get_AI_stance() + if(!ai_holder) + return null + if(client && !ai_holder.autopilot) + return null + return ai_holder.stance + +// Similar to above but only returns 1 or 0. +/mob/living/proc/has_AI() + return get_AI_stance() ? TRUE : FALSE + +// 'Taunts' the AI into attacking the taunter. +/mob/living/proc/taunt(atom/movable/taunter, force_target_switch = FALSE) + if(ai_holder) + ai_holder.receive_taunt(taunter, force_target_switch) \ No newline at end of file diff --git a/code/modules/ai/ai_holder_combat.dm b/code/modules/ai/ai_holder_combat.dm new file mode 100644 index 0000000000..2bb224e801 --- /dev/null +++ b/code/modules/ai/ai_holder_combat.dm @@ -0,0 +1,313 @@ +// This file is for actual fighting. Targeting is in a seperate file. + +/datum/ai_holder + var/firing_lanes = TRUE // If ture, tries to refrain from shooting allies or the wall. + var/conserve_ammo = FALSE // If true, the mob will avoid shooting anything that does not have a chance to hit a mob. Requires firing_lanes to be true. + var/pointblank = FALSE // If ranged is true, and this is true, people adjacent to the mob will suffer the ranged instead of using a melee attack. + + var/can_breakthrough = TRUE // If false, the AI will not try to open a path to its goal, like opening doors. + var/violent_breakthrough = TRUE // If false, the AI is not allowed to destroy things like windows or other structures in the way. Requires above var to be true. + + var/stand_ground = FALSE // If true, the AI won't try to get closer to an enemy if out of range. + + +// This does the actual attacking. +/datum/ai_holder/proc/engage_target() + ai_log("engage_target() : Entering.", AI_LOG_DEBUG) + + // Can we still see them? +// if(!target || !can_attack(target) || (!(target in list_targets())) ) + if(!target || !can_attack(target)) + ai_log("engage_target() : Lost sight of target.", AI_LOG_TRACE) + lose_target() // We lost them. + + if(!find_target()) // If we can't get a new one, then wait for a bit and then time out. + set_stance(STANCE_IDLE) + lost_target() + ai_log("engage_target() : No more targets. Exiting.", AI_LOG_DEBUG) + return + // if(lose_target_time + lose_target_timeout < world.time) + // ai_log("engage_target() : Unseen enemy timed out.", AI_LOG_TRACE) + // set_stance(STANCE_IDLE) // It must've been the wind. + // lost_target() + // ai_log("engage_target() : Exiting.", AI_LOG_DEBUG) + // return + + // // But maybe we do one last ditch effort. + // if(!target_last_seen_turf || intelligence_level < AI_SMART) + // ai_log("engage_target() : No last known position or is too dumb to fight unseen enemies.", AI_LOG_TRACE) + // set_stance(STANCE_IDLE) + // else + // ai_log("engage_target() : Fighting unseen enemy.", AI_LOG_TRACE) + // engage_unseen_enemy() + else + ai_log("engage_target() : Got new target ([target]).", AI_LOG_TRACE) + + var/distance = get_dist(holder, target) + ai_log("engage_target() : Distance to target ([target]) is [distance].", AI_LOG_TRACE) + holder.face_atom(target) + last_conflict_time = world.time + + request_help() // Call our allies. + + // Do a 'special' attack, if one is allowed. +// if(prob(special_attack_prob) && (distance >= special_attack_min_range) && (distance <= special_attack_max_range)) + if(holder.ICheckSpecialAttack(target)) + ai_log("engage_target() : Attempting a special attack.", AI_LOG_TRACE) + on_engagement(target) + if(special_attack(target)) // If this fails, then we try a regular melee/ranged attack. + ai_log("engage_target() : Successful special attack. Exiting.", AI_LOG_DEBUG) + return + + // Stab them. + else if(distance <= 1 && !pointblank) + ai_log("engage_target() : Attempting a melee attack.", AI_LOG_TRACE) + on_engagement(target) + melee_attack(target) + + // Shoot them. + else if(holder.ICheckRangedAttack(target) && (distance <= max_range(target)) ) + on_engagement(target) + if(firing_lanes && !test_projectile_safety(target)) + // Nudge them a bit, maybe they can shoot next time. + var/turf/T = get_step(holder, pick(cardinal)) + if(T) + holder.IMove(T) // IMove() will respect movement cooldown. + holder.face_atom(target) + ai_log("engage_target() : Could not safely fire at target. Exiting.", AI_LOG_DEBUG) + return + + ai_log("engage_target() : Attempting a ranged attack.", AI_LOG_TRACE) + ranged_attack(target) + + // Run after them. + else if(!stand_ground) + ai_log("engage_target() : Target ([target]) too far away. Exiting.", AI_LOG_DEBUG) + set_stance(STANCE_APPROACH) + +// We're not entirely sure how holder will do melee attacks since any /mob/living could be holder, but we don't have to care because Interfaces. +/datum/ai_holder/proc/melee_attack(atom/A) + pre_melee_attack(A) + . = holder.IAttack(A) + if(.) + post_melee_attack(A) + +// Ditto. +/datum/ai_holder/proc/ranged_attack(atom/A) + pre_ranged_attack(A) + . = holder.IRangedAttack(A) + if(.) + post_ranged_attack(A) + +// Most mobs probably won't have this defined but we don't care. +/datum/ai_holder/proc/special_attack(atom/movable/AM) + pre_special_attack(AM) + . = holder.ISpecialAttack(AM) + if(.) + post_special_attack(AM) + +// Called when within striking/shooting distance, however cooldown is not considered. +// Override to do things like move in a random step for evasiveness. +// Note that this is called BEFORE the attack. +/datum/ai_holder/proc/on_engagement(atom/A) + +// Called before a ranged attack is attempted. +/datum/ai_holder/proc/pre_ranged_attack(atom/A) + +// Called before a melee attack is attempted. +/datum/ai_holder/proc/pre_melee_attack(atom/A) + +// Called before a 'special' attack is attempted. +/datum/ai_holder/proc/pre_special_attack(atom/A) + +// Called after a successful (IE not on cooldown) ranged attack. +// Note that this is not whether the projectile actually hit, just that one was launched. +/datum/ai_holder/proc/post_ranged_attack(atom/A) + +// Ditto but for melee. +/datum/ai_holder/proc/post_melee_attack(atom/A) + +// And one more for special snowflake attacks. +/datum/ai_holder/proc/post_special_attack(atom/A) + +// Used to make sure projectiles will probably hit the target and not the wall or a friend. +/datum/ai_holder/proc/test_projectile_safety(atom/movable/AM) + if(holder.Adjacent(AM)) // If they're right next to us then lets just say yes. check_trajectory() tends to spaz out otherwise. + return TRUE + + var/mob/living/L = check_trajectory(AM, holder) // This isn't always reliable but its better than the previous method. +// world << "Checked trajectory, would hit [L]." + + if(istype(L)) // Did we hit a mob? +// world << "Hit [L]." + if(holder.IIsAlly(L)) +// world << "Would hit ally, canceling." + return FALSE // We would hit a friend! +// world << "Won't threaten ally, firing." + return TRUE // Otherwise we don't care, even if its not the intended target. + else + if(!isliving(AM)) // If the original target was an object, then let it happen if it doesn't threaten an ally. +// world << "Targeting object, ignoring and firing." + return TRUE +// world << "Not sure." + + return !conserve_ammo // If we have infinite ammo than shooting the wall isn't so bad, but otherwise lets not. + +// Test if we are within range to attempt an attack, melee or ranged. +/datum/ai_holder/proc/within_range(atom/movable/AM) + var/distance = get_dist(holder, AM) + if(distance <= 1) + return TRUE // Can melee. + else if(holder.ICheckRangedAttack(AM) && distance <= max_range(AM)) + return TRUE // Can shoot. + return FALSE + +// Determines how close the AI will move to its target. +/datum/ai_holder/proc/closest_distance(atom/movable/AM) + return max(max_range(AM) - 1, 1) // Max range -1 just because we don't want to constantly get kited + +// Can be used to conditionally do a ranged or melee attack. +/datum/ai_holder/proc/max_range(atom/movable/AM) + return holder.ICheckRangedAttack(AM) ? 7 : 1 + +// Goes to the target, to attack them. +// Called when in STANCE_APPROACH. +/datum/ai_holder/proc/walk_to_target() + ai_log("walk_to_target() : Entering.", AI_LOG_DEBUG) + // Make sure we can still chase/attack them. + if(!target || !can_attack(target)) + ai_log("walk_to_target() : Lost target.", AI_LOG_INFO) + if(!find_target()) + lost_target() + ai_log("walk_to_target() : Exiting.", AI_LOG_DEBUG) + return + else + ai_log("walk_to_target() : Found new target ([target]).", AI_LOG_INFO) + + // Find out where we're going. + var/get_to = closest_distance(target) + var/distance = get_dist(holder, target) + ai_log("walk_to_target() : get_to is [get_to].", AI_LOG_TRACE) + + // We're here! + // Special case: Our holder has a special attack that is ranged, but normally the holder uses melee. + // If that happens, we'll switch to STANCE_FIGHT so they can use it. If the special attack is limited, they'll likely switch back next tick. + if(distance <= get_to || holder.ICheckSpecialAttack(target)) + ai_log("walk_to_target() : Within range.", AI_LOG_INFO) + forget_path() + set_stance(STANCE_FIGHT) + ai_log("walk_to_target() : Exiting.", AI_LOG_DEBUG) + return + + + // Otherwise keep walking. + if(!stand_ground) + walk_path(target, get_to) + + ai_log("walk_to_target() : Exiting.", AI_LOG_DEBUG) + +// Resists out of things. +// Sometimes there are times you want your mob to be buckled to something, so override this for when that is needed. +/datum/ai_holder/proc/handle_resist() + holder.resist() + +// Used to break through windows and barriers to a target on the other side. +// This does two passes, so that if its just a public access door, the windows nearby don't need to be smashed. +/datum/ai_holder/proc/breakthrough(atom/target_atom) + ai_log("breakthrough() : Entering", AI_LOG_TRACE) + + if(!can_breakthrough) + ai_log("breakthrough() : Not allowed to breakthrough. Exiting.", AI_LOG_TRACE) + return FALSE + + if(!isturf(holder.loc)) + ai_log("breakthrough() : Trapped inside \the [holder.loc]. Exiting.", AI_LOG_TRACE) + return FALSE + + var/dir_to_target = get_dir(holder, target_atom) + holder.face_atom(target_atom) + ai_log("breakthrough() : Exiting", AI_LOG_DEBUG) + + // Sometimes the mob will try to hit something diagonally, and generally this fails. + // So instead we will try two more times with some adjustments if the attack fails. + var/list/directions_to_try = list( + dir_to_target, + turn(dir_to_target, 45), + turn(dir_to_target, -45) + ) + + ai_log("breakthrough() : Starting peaceful pass.", AI_LOG_DEBUG) + + var/result = FALSE + + // First, we will try to peacefully make a path, I.E opening a door we have access to. + for(var/direction in directions_to_try) + result = destroy_surroundings(direction, violent = FALSE) + if(result) + break + + // Alright, lets smash some shit instead, if it didn't work and we're allowed to be violent. + if(!result && can_violently_breakthrough()) + ai_log("breakthrough() : Starting violent pass.", AI_LOG_DEBUG) + for(var/direction in directions_to_try) + result = destroy_surroundings(direction, violent = TRUE) + if(result) + break + + ai_log("breakthrough() : Exiting with [result].", AI_LOG_TRACE) + return result + +// Despite the name, this can also be used to help clear a path without any destruction. +/datum/ai_holder/proc/destroy_surroundings(direction, violent = TRUE) + ai_log("destroy_surroundings() : Entering.", AI_LOG_TRACE) + if(!direction) + direction = pick(cardinal) // FLAIL WILDLY + ai_log("destroy_surroundings() : No direction given, picked [direction] randomly.", AI_LOG_DEBUG) + + var/turf/problem_turf = get_step(holder, direction) + + // First, give peace a chance. + if(!violent) + ai_log("destroy_surroundings() : Going to try to peacefully clear [problem_turf].", AI_LOG_DEBUG) + for(var/obj/machinery/door/D in problem_turf) + if(D.density && holder.Adjacent(D) && D.allowed(holder) && D.operable()) + // First, try to open the door if possible without smashing it. We might have access. + ai_log("destroy_surroundings() : Opening closed door.", AI_LOG_INFO) + return D.open() + + // Peace has failed us, can we just smash the things in the way? + else + ai_log("destroy_surroundings() : Going to try to violently clear [problem_turf].", AI_LOG_DEBUG) + // First, kill windows in the way. + for(var/obj/structure/window/W in problem_turf) + if(W.dir == reverse_dir[holder.dir]) // So that windows get smashed in the right order + ai_log("destroy_surroundings() : Attacking side window.", AI_LOG_INFO) + return holder.IAttack(W) + + else if(W.is_fulltile()) + ai_log("destroy_surroundings() : Attacking full tile window.", AI_LOG_INFO) + return holder.IAttack(W) + + // Kill hull shields in the way. + for(var/obj/effect/energy_field/shield in problem_turf) + if(shield.density) // Don't attack shields that are already down. + ai_log("destroy_surroundings() : Attacking hull shield.", AI_LOG_INFO) + return holder.IAttack(shield) + + // Kill common obstacle in the way like tables. + var/obj/structure/obstacle = locate(/obj/structure, problem_turf) + if(istype(obstacle, /obj/structure/window) || istype(obstacle, /obj/structure/closet) || istype(obstacle, /obj/structure/table) || istype(obstacle, /obj/structure/grille)) + ai_log("destroy_surroundings() : Attacking generic structure.", AI_LOG_INFO) + return holder.IAttack(obstacle) + + for(var/obj/machinery/door/D in problem_turf) // Required since firelocks take up the same turf. + if(D.density) + ai_log("destroy_surroundings() : Attacking closed door.", AI_LOG_INFO) + return holder.IAttack(D) + + ai_log("destroy_surroundings() : Exiting due to nothing to attack.", AI_LOG_INFO) + return FALSE // Nothing to attack. + +// Override for special behaviour. +/datum/ai_holder/proc/can_violently_breakthrough() + return violent_breakthrough \ No newline at end of file diff --git a/code/modules/ai/ai_holder_combat_unseen.dm b/code/modules/ai/ai_holder_combat_unseen.dm new file mode 100644 index 0000000000..0cb518f08c --- /dev/null +++ b/code/modules/ai/ai_holder_combat_unseen.dm @@ -0,0 +1,43 @@ +// Used for fighting invisible things. + +// Used when a target is out of sight or invisible. +/datum/ai_holder/proc/engage_unseen_enemy() + // Lets do some last things before giving up. + if(!ranged) + if(get_dist(holder, target_last_seen_turf > 1)) // We last saw them over there. + // Go to where you last saw the enemy. + give_destination(target_last_seen_turf, 1, TRUE) // This will set it to STANCE_REPOSITION. + else // We last saw them next to us, so do a blind attack on that tile. + melee_on_tile(target_last_seen_turf) + + else if(!conserve_ammo) + shoot_near_turf(target_last_seen_turf) + +// This shoots semi-randomly near a specific turf. +/datum/ai_holder/proc/shoot_near_turf(turf/targeted_turf) + if(!ranged) + return // Can't shoot. + if(get_dist(holder, targeted_turf) > max_range(targeted_turf)) + return // Too far to shoot. + + var/turf/T = pick(RANGE_TURFS(2, targeted_turf)) // The turf we're actually gonna shoot at. + on_engagement(T) + if(firing_lanes && !test_projectile_safety(T)) + step_rand(holder) + holder.face_atom(T) + return + + ranged_attack(T) + +// Attempts to attack something on a specific tile. +// TODO: Put on mob/living? +/datum/ai_holder/proc/melee_on_tile(turf/T) + var/mob/living/L = locate() in T + if(!L) + T.visible_message("\The [holder] attacks nothing around \the [T].") + return + + if(holder.IIsAlly(L)) // Don't hurt our ally. + return + + melee_attack(L) \ No newline at end of file diff --git a/code/modules/ai/ai_holder_communication.dm b/code/modules/ai/ai_holder_communication.dm new file mode 100644 index 0000000000..4cfec6f7af --- /dev/null +++ b/code/modules/ai/ai_holder_communication.dm @@ -0,0 +1,134 @@ +// Contains code for speaking and emoting. + +/datum/ai_holder + var/threaten = FALSE // If hostile and sees a valid target, gives a 'warning' to the target before beginning the attack. + var/threatening = FALSE // If the mob actually gave the warning, checked so it doesn't constantly yell every tick. + var/threaten_delay = 3 SECONDS // How long a 'threat' lasts, until actual fighting starts. If null, the mob never starts the fight but still does the threat. + var/threaten_timeout = 1 MINUTE // If the mob threatens someone, they leave, and then come back before this timeout period, the mob escalates to fighting immediately. + var/last_conflict_time = null // Last occurance of fighting being used, in world.time. + var/last_threaten_time = null // Ditto but only for threats. + var/last_target_time = null // Ditto for when we last switched targets, used to stop retaliate from gimping mobs + + var/speak_chance = 0 // Probability that the mob talks (this is 'X in 200' chance since even 1/100 is pretty noisy) + + +/datum/ai_holder/proc/should_threaten() + if(!threaten) + return FALSE // We don't negotiate. + if(target in attackers) + return FALSE // They (or someone like them) attacked us before, escalate immediately. + if(!will_threaten(target)) + return FALSE // Pointless to threaten an animal, a mindless drone, or an object. + if(stance in STANCES_COMBAT) + return FALSE // We're probably already fighting or recently fought if not in these stances. + if(last_threaten_time && threaten_delay && last_conflict_time + threaten_timeout > world.time) + return FALSE // We threatened someone recently, so lets show them we mean business. + return TRUE // Lets give them a chance to choose wisely and walk away. + +/datum/ai_holder/proc/threaten_target() + holder.face_atom(target) // Constantly face the target. + + if(!threatening) // First tick. + threatening = TRUE + last_threaten_time = world.time + + if(holder.say_list) + holder.ISay(safepick(holder.say_list.say_threaten)) + playsound(holder.loc, holder.say_list.threaten_sound, 50, 1) // We do this twice to make the sound -very- noticable to the target. + playsound(target.loc, holder.say_list.threaten_sound, 50, 1) // Actual aim-mode also does that so at least it's consistant. + else // Otherwise we are waiting for them to go away or to wait long enough for escalate. + if(target in list_targets()) // Are they still visible? + var/should_escalate = FALSE + + if(threaten_delay && last_threaten_time + threaten_delay < world.time) // Waited too long. + should_escalate = TRUE + + if(should_escalate) + threatening = FALSE + set_stance(STANCE_APPROACH) + if(holder.say_list) + holder.ISay(safepick(holder.say_list.say_escalate)) + else + return // Wait a bit. + + else // They left, or so we think. + if(last_threaten_time + threaten_timeout < world.time) // They've been gone long enough, probably safe to stand down + threatening = FALSE + set_stance(STANCE_IDLE) + if(holder.say_list) + holder.ISay(safepick(holder.say_list.say_stand_down)) + playsound(holder.loc, holder.say_list.stand_down_sound, 50, 1) // We do this twice to make the sound -very- noticable to the target. + playsound(target.loc, holder.say_list.stand_down_sound, 50, 1) // Actual aim-mode also does that so at least it's consistant. + +// Determines what is deserving of a warning when STANCE_ALERT is active. +/datum/ai_holder/proc/will_threaten(mob/living/the_target) + if(!isliving(the_target)) + return FALSE // Turrets don't give a fuck so neither will we. + /* + // Find a nice way of doing this later. + if(istype(the_target, /mob/living/simple_mob) && istype(holder, /mob/living/simple_mob)) + var/mob/living/simple_mob/us = holder + var/mob/living/simple_mob/them = target + + if(them.intelligence_level < us.intelligence_level) // Todo: Bitflag these. + return FALSE // Humanoids don't care about drones/animals/etc. Drones don't care about animals, and so on. + */ + return TRUE + +// Temp defines to make the below code a bit more readable. +#define COMM_SAY "say" +#define COMM_AUDIBLE_EMOTE "audible emote" +#define COMM_VISUAL_EMOTE "visual emote" + +/datum/ai_holder/proc/handle_idle_speaking() + if(rand(0,200) < speak_chance) + // Check if anyone is around to 'appreciate' what we say. + var/alone = TRUE + for(var/m in viewers(holder)) + var/mob/M = m + if(M.client) + alone = FALSE + break + if(alone) // Forever alone. No point doing anything else. + return + + var/list/comm_types = list() // What kinds of things can we do? + if(!holder.say_list) + return + + if(holder.say_list.speak.len) + comm_types += COMM_SAY + if(holder.say_list.emote_hear.len) + comm_types += COMM_AUDIBLE_EMOTE + if(holder.say_list.emote_see.len) + comm_types += COMM_VISUAL_EMOTE + + if(!comm_types.len) + return // All the relevant lists are empty, so do nothing. + + switch(pick(comm_types)) + if(COMM_SAY) + holder.ISay(safepick(holder.say_list.speak)) + if(COMM_AUDIBLE_EMOTE) + holder.audible_emote(safepick(holder.say_list.emote_hear)) + if(COMM_VISUAL_EMOTE) + holder.visible_emote(safepick(holder.say_list.emote_see)) + +#undef COMM_SAY +#undef COMM_AUDIBLE_EMOTE +#undef COMM_VISUAL_EMOTE + +// Handles the holder hearing a mob's say() +// Does nothing by default, override this proc for special behavior. +/datum/ai_holder/proc/on_hear_say(mob/living/speaker, message) + return + +// This is to make responses feel a bit more natural and not instant. +/datum/ai_holder/proc/delayed_say(var/message, var/mob/speak_to) + spawn(rand(1 SECOND, 2 SECONDS)) + if(!src || !holder || !can_act()) // We might've died/got deleted/etc in the meantime. + return + + if(speak_to) + holder.face_atom(speak_to) + holder.ISay(message) diff --git a/code/modules/ai/ai_holder_cooperation.dm b/code/modules/ai/ai_holder_cooperation.dm new file mode 100644 index 0000000000..0f6b0bcfa2 --- /dev/null +++ b/code/modules/ai/ai_holder_cooperation.dm @@ -0,0 +1,115 @@ +// Involves cooperating with other ai_holders. +/datum/ai_holder + var/cooperative = FALSE // If true, asks allies to help when fighting something. + var/call_distance = 14 // How far away calls for help will go for. + var/last_helpask_time = 0 // world.time when a mob asked for help. + var/list/faction_friends = list() // List of all mobs inside the faction with ai_holders that have cooperate on, to call for help without using range(). + // Note that this is only used for sending calls out. Receiving calls doesn't care about this list, only if the mob is in the faction. + // This means the AI could respond to a player's call for help, if a way to do so was implemented. + + // These vars don't do anything currently. They did before but an optimization made them nonfunctional. + // It was probably worth it. + var/call_players = FALSE // (Currently nonfunctional) If true, players get notified of an allied mob calling for help. + var/called_player_message = "needs help!" // (Currently nonfunctional) Part of a message used when above var is true. Full message is "\The [holder] [called_player_message]" + +/datum/ai_holder/New(new_holder) + ..() + if(cooperative) + build_faction_friends() + +/datum/ai_holder/Destroy() + if(faction_friends.len) //This list is shared amongst the faction + faction_friends -= src + return ..() + +// Handles everything about that list. +// Call on initialization or if something weird happened like the mob switched factions. +/datum/ai_holder/proc/build_faction_friends() + if(faction_friends.len) // Already have a list. + // Assume we're moving to a new faction. + faction_friends -= src // Get us out of the current list shared by everyone else. + faction_friends = list() // Then make our list empty and unshared in case we become a loner. + + // Find another AI-controlled mob in the same faction if possible. + var/mob/living/first_friend + for(var/mob/living/L in living_mob_list) + if(L.faction == holder.faction && L.ai_holder) + first_friend = L + break + + if(first_friend) // Joining an already established faction. + faction_friends = first_friend.ai_holder.faction_friends + faction_friends |= holder + else // We're the 'founder' (first and/or only member) of this faction. + faction_friends |= holder + +// Requests help in combat from other mobs possessing ai_holders. +/datum/ai_holder/proc/request_help() + ai_log("request_help() : Entering.", AI_LOG_DEBUG) + if(!cooperative || ((world.time - last_helpask_time) < 10 SECONDS)) + return + + ai_log("request_help() : Asking for help.", AI_LOG_INFO) + last_helpask_time = world.time + +// for(var/mob/living/L in range(call_distance, holder)) + for(var/mob/living/L in faction_friends) + if(L == holder) // Lets not call ourselves. + continue + if(holder.z != L.z) // On seperate z-level. + continue + if(get_dist(L, holder) > call_distance) // Too far to 'hear' the call for help. + continue + + if(holder.IIsAlly(L)) + // This will currently never run sadly, until faction_friends is made to accept players too. + // That might be for the best since I can imagine it getting spammy in a big fight. + if(L.client && call_players) // Dealing with a player. + ai_log("request_help() : Asking [L] (Player) for help.", AI_LOG_INFO) + to_chat(L, "\The [holder] [called_player_message]") + + else if(L.ai_holder) // Dealing with an AI. + ai_log("request_help() : Asking [L] (AI) for help.", AI_LOG_INFO) + L.ai_holder.help_requested(holder) + + ai_log("request_help() : Exiting.", AI_LOG_DEBUG) + +// What allies receive when someone else is calling for help. +/datum/ai_holder/proc/help_requested(mob/living/friend) + ai_log("help_requested() : Entering.", AI_LOG_DEBUG) + if(stance == STANCE_SLEEP) + ai_log("help_requested() : Help requested by [friend] but we are asleep.", AI_LOG_INFO) + return + if(!cooperative) + ai_log("help_requested() : Help requested by [friend] but we're not cooperative.", AI_LOG_INFO) + return + if(stance in STANCES_COMBAT) + ai_log("help_requested() : Help requested by [friend] but we are busy fighting something else.", AI_LOG_INFO) + return + if(!can_act()) + ai_log("help_requested() : Help requested by [friend] but cannot act (stunned or dead).", AI_LOG_INFO) + return + if(!holder.IIsAlly(friend)) // Extra sanity. + ai_log("help_requested() : Help requested by [friend] but we hate them.", AI_LOG_INFO) + return + if(friend.ai_holder && friend.ai_holder.target && !can_attack(friend.ai_holder.target)) + ai_log("help_requested() : Help requested by [friend] but we don't want to fight their target.", AI_LOG_INFO) + return + if(get_dist(holder, friend) <= follow_distance) + ai_log("help_requested() : Help requested by [friend] but we're already here.", AI_LOG_INFO) + return + if(get_dist(holder, friend) <= vision_range) // Within our sight. + ai_log("help_requested() : Help requested by [friend], and within target sharing range.", AI_LOG_INFO) + if(friend.ai_holder) // AI calling for help. + if(friend.ai_holder.target && can_attack(friend.ai_holder.target)) // Friend wants us to attack their target. + last_conflict_time = world.time // So we attack immediately and not threaten. + give_target(friend.ai_holder.target) // This will set us to the appropiate stance. + ai_log("help_requested() : Given target [target] by [friend]. Exiting", AI_LOG_DEBUG) + return + + // Otherwise they're outside our sight, lack a target, or aren't AI controlled, but within call range. + // So assuming we're AI controlled, we'll go to them and see whats wrong. + ai_log("help_requested() : Help requested by [friend], going to go to friend.", AI_LOG_INFO) + set_follow(friend, 10 SECONDS) + ai_log("help_requested() : Exiting.", AI_LOG_DEBUG) + diff --git a/code/modules/ai/ai_holder_debug.dm b/code/modules/ai/ai_holder_debug.dm new file mode 100644 index 0000000000..beee998af8 --- /dev/null +++ b/code/modules/ai/ai_holder_debug.dm @@ -0,0 +1,89 @@ +// Contains settings to make it easier to debug things. + +/datum/ai_holder + var/path_display = FALSE // Displays a visual path when A* is being used. + var/path_icon = 'icons/misc/debug_group.dmi' // What icon to use for the overlay + var/path_icon_state = "red" // What state to use for the overlay + var/image/path_overlay // A reference to the overlay + + var/last_turf_display = FALSE // Similar to above, but shows the target's last known turf visually. + var/last_turf_icon_state = "green" // A seperate icon_state from the previous. + var/image/last_turf_overlay // Another reference for an overlay. + + var/stance_coloring = FALSE // Colors the mob depending on its stance. + + var/debug_ai = AI_LOG_OFF // The level of debugging information to display to people who can see log_debug(). + +/datum/ai_holder/New() + ..() + path_overlay = new(path_icon,path_icon_state) + last_turf_overlay = new(path_icon, last_turf_icon_state) + +/datum/ai_holder/Destroy() + path_overlay = null + last_turf_overlay = null + return ..() + +//For debug purposes! +/datum/ai_holder/proc/ai_log_output(var/msg = "missing message", var/ver = AI_LOG_INFO) + var/span_type + switch(ver) + if(AI_LOG_OFF) + return + if(AI_LOG_ERROR) + span_type = "debug_error" + if(AI_LOG_WARNING) + span_type = "debug_warning" + if(AI_LOG_INFO) + span_type = "debug_info" + if(AI_LOG_DEBUG) + span_type = "debug_debug" // RAS syndrome at work. + if(AI_LOG_TRACE) + span_type = "debug_trace" + if(ver <= debug_ai) + log_debug("AI: ([holder]:\ref[holder] | [holder.x],[holder.y],[holder.z])(@[world.time]): [msg] ") + +// Colors the mob based on stance, to visually tell what stance it is for debugging. +// Probably not something you want for regular use. +/datum/ai_holder/proc/stance_color() + var/new_color = null + switch(stance) + if(STANCE_SLEEP) + new_color = "#FFFFFF" // White + if(STANCE_IDLE) + new_color = "#00FF00" // Green + if(STANCE_ALERT) + new_color = "#FFFF00" // Yellow + if(STANCE_APPROACH) + new_color = "#FF9933" // Orange + if(STANCE_FIGHT) + new_color = "#FF0000" // Red + if(STANCE_MOVE) + new_color = "#0000FF" // Blue + if(STANCE_REPOSITION) + new_color = "#FF00FF" // Purple + if(STANCE_FOLLOW) + new_color = "#00FFFF" // Cyan + if(STANCE_FLEE) + new_color = "#666666" // Grey + if(STANCE_DISABLED) + new_color = "#000000" // Black + holder.color = new_color + +// Turns on all the debugging stuff. +/datum/ai_holder/proc/debug() + stance_coloring = TRUE + path_display = TRUE + last_turf_display = TRUE + debug_ai = AI_LOG_INFO + +/datum/ai_holder/hostile/debug + wander = FALSE + conserve_ammo = FALSE + intelligence_level = AI_SMART + + stance_coloring = TRUE + path_display = TRUE + last_turf_display = TRUE + debug_ai = AI_LOG_INFO + diff --git a/code/modules/ai/ai_holder_disabled.dm b/code/modules/ai/ai_holder_disabled.dm new file mode 100644 index 0000000000..e7cd6aa1f8 --- /dev/null +++ b/code/modules/ai/ai_holder_disabled.dm @@ -0,0 +1,95 @@ +// Handles AI while stunned or otherwise disabled. + +/datum/ai_holder + var/respect_confusion = TRUE // If false, the mob won't wander around recklessly. + +// If our holder is able to do anything. +/datum/ai_holder/proc/can_act() + if(holder.stat) // Dead or unconscious. + ai_log("can_act() : Stat was non-zero ([holder.stat]).", AI_LOG_TRACE) + return FALSE + if(holder.incapacitated(INCAPACITATION_DISABLED)) // Stunned in some form. + ai_log("can_act() : Incapacited.", AI_LOG_TRACE) + return FALSE + return TRUE + +// Test if we should switch to STANCE_DISABLE. +// Currently tests for death, stuns, and confusion. +/datum/ai_holder/proc/is_disabled() + if(!can_act()) + return TRUE + if(is_confused()) + return TRUE + return FALSE + +/datum/ai_holder/proc/is_confused() + return holder.confused > 0 && respect_confusion + +// Called by the main loop. +/datum/ai_holder/proc/handle_disabled() + if(!can_act()) + return // Just sit there and take it. + else if(is_confused()) + dangerous_wander() // Let's bump into allies and hit them. + +// Similar to normal wander, but will walk into tiles that are harmful, and attack anything they bump into, including allies. +// Occurs when confused. +/datum/ai_holder/proc/dangerous_wander() + ai_log("dangerous_wander() : Entered.", AI_LOG_DEBUG) + if(isturf(holder.loc) && can_act()) + // Test if we should refrain from falling/attacking allies, if we're smart enough to realize that. + if(intelligence_level > AI_NORMAL) + var/unsafe = FALSE + + tile_test: + for(var/dir_tested in cardinal) + var/turf/turf_tested = get_step(holder, dir_tested) + // Look for unsafe tiles. + if(!turf_tested.is_safe_to_enter(holder)) + unsafe = TRUE + break + + // Look for allies. + for(var/mob/living/L in turf_tested) + if(holder.IIsAlly(L)) + unsafe = TRUE + break tile_test + + + if(unsafe) + ai_log("dangerous_wander() : Staying still due to risk of harm to self or allies.", AI_LOG_TRACE) + return // Just stay still. + + var/moving_to = 0 + moving_to = pick(cardinal) + var/turf/T = get_step(holder, moving_to) + + var/mob/living/L = locate() in T + if(L) + // Attack whoever's on the tile. Even if it's an ally. + ai_log("dangerous_wander() : Going to confuse-attack [L].", AI_LOG_TRACE) + melee_attack(L) + else + // Move to the tile. Even if it's unsafe. + ai_log("dangerous_wander() : Going to confuse-walk to [T] ([T.x],[T.y],[T.z]).", AI_LOG_TRACE) + holder.IMove(T, safety = FALSE) + ai_log("dangerous_wander() : Exited.", AI_LOG_DEBUG) + +/* +// Wanders randomly in cardinal directions. +/datum/ai_holder/proc/handle_wander_movement() + ai_log("handle_wander_movement() : Entered.", AI_LOG_DEBUG) + if(isturf(holder.loc) && can_act()) + wander_delay-- + if(wander_delay <= 0) + if(!wander_when_pulled && holder.pulledby) + ai_log("handle_wander_movement() : Being pulled and cannot wander. Exiting.", AI_LOG_DEBUG) + return + + var/moving_to = 0 // Apparently this is required or it always picks 4, according to the previous developer for simplemob AI. + moving_to = pick(cardinal) + holder.set_dir(moving_to) + holder.IMove(get_step(holder,moving_to)) + wander_delay = base_wander_delay + ai_log("handle_wander_movement() : Exited.", AI_LOG_DEBUG) +*/ \ No newline at end of file diff --git a/code/modules/ai/ai_holder_fleeing.dm b/code/modules/ai/ai_holder_fleeing.dm new file mode 100644 index 0000000000..83a7be94b8 --- /dev/null +++ b/code/modules/ai/ai_holder_fleeing.dm @@ -0,0 +1,45 @@ +// This code handles what to do inside STANCE_FLEE. + +/datum/ai_holder + var/can_flee = TRUE // If they're even allowed to flee. + var/flee_when_dying = TRUE // If they should flee when low on health. + var/dying_threshold = 0.3 // How low on health the holder needs to be before fleeing. Defaults to 30% or lower health. + var/flee_when_outmatched = FALSE // If they should flee upon reaching a specific tension threshold. + var/outmatched_threshold = 200 // The tension threshold needed for a mob to decide it should run away. + + + +/datum/ai_holder/proc/should_flee(force = FALSE) + if(holder.has_modifier_of_type(/datum/modifier/berserk)) // Berserked mobs will never flee, even if 'forced' to. + return FALSE + if(force) + return TRUE + + if(can_flee) + if(special_flee_check()) + return TRUE + if(!hostile && !retaliate) + return TRUE // We're not hostile and someone attacked us first. + if(flee_when_dying && (holder.health / holder.getMaxHealth()) <= dying_threshold) + return TRUE // We're gonna die! + else if(flee_when_outmatched && holder.get_tension() >= outmatched_threshold) + return TRUE // We're fighting something way way stronger then us. + return FALSE + +// Override for special fleeing conditionally. +/datum/ai_holder/proc/special_flee_check() + return FALSE + +/datum/ai_holder/proc/flee_from_target() + ai_log("flee_from_target() : Entering.", AI_LOG_DEBUG) + + if(!target || !should_flee() || !can_attack(target)) // can_attack() is used since it checks the same things we would need to anyways. + ai_log("flee_from_target() : Lost target to flee from.", AI_LOG_INFO) + lose_target() + set_stance(STANCE_IDLE) + ai_log("flee_from_target() : Exiting.", AI_LOG_DEBUG) + return + + ai_log("flee_from_target() : Stepping away.", AI_LOG_TRACE) + step_away(holder, target, vision_range) + ai_log("flee_from_target() : Exiting.", AI_LOG_DEBUG) \ No newline at end of file diff --git a/code/modules/ai/ai_holder_follow.dm b/code/modules/ai/ai_holder_follow.dm new file mode 100644 index 0000000000..1e7bb0875d --- /dev/null +++ b/code/modules/ai/ai_holder_follow.dm @@ -0,0 +1,68 @@ +// This handles following a specific atom/movable, without violently murdering it. + +/datum/ai_holder + // Following. + var/atom/movable/leader = null // The movable atom that the mob wants to follow. + var/follow_distance = 2 // How far leader must be to start moving towards them. + var/follow_until_time = 0 // world.time when the mob will stop following leader. 0 means it won't time out. + +/datum/ai_holder/proc/walk_to_leader() + ai_log("walk_to_leader() : Entering.",AI_LOG_TRACE) + if(!leader) + ai_log("walk_to_leader() : No leader.", AI_LOG_WARNING) + forget_path() + set_stance(STANCE_IDLE) + ai_log("walk_to_leader() : Exiting.", AI_LOG_TRACE) + return + + // Did we time out? + if(follow_until_time && world.time > follow_until_time) + ai_log("walk_to_leader() : Follow timed out, losing leader.", AI_LOG_INFO) + lose_follow() + set_stance(STANCE_IDLE) + ai_log("walk_to_leader() : Exiting.", AI_LOG_TRACE) + return + + var/get_to = follow_distance + var/distance = get_dist(holder, leader) + ai_log("walk_to_leader() : get_to is [get_to].", AI_LOG_TRACE) + + // We're here! + if(distance <= get_to) + give_up_movement() + set_stance(STANCE_IDLE) + ai_log("walk_to_leader() : Within range, exiting.", AI_LOG_INFO) + return + + ai_log("walk_to_leader() : Walking.", AI_LOG_TRACE) + walk_path(leader, get_to) + ai_log("walk_to_leader() : Exiting.",AI_LOG_DEBUG) + +/datum/ai_holder/proc/set_follow(mob/living/L, follow_for = 0) + ai_log("set_follow() : Entered.", AI_LOG_DEBUG) + if(!L) + ai_log("set_follow() : Was told to follow a nonexistant mob.", AI_LOG_ERROR) + return FALSE + + leader = L + follow_until_time = !follow_for ? 0 : world.time + follow_for + ai_log("set_follow() : Exited.", AI_LOG_DEBUG) + return TRUE + +/datum/ai_holder/proc/lose_follow() + ai_log("lose_follow() : Entered.", AI_LOG_DEBUG) + ai_log("lose_follow() : Going to lose leader [leader].", AI_LOG_INFO) + leader = null + give_up_movement() + ai_log("lose_follow() : Exited.", AI_LOG_DEBUG) + +/datum/ai_holder/proc/should_follow_leader() + if(!leader) + return FALSE + if(follow_until_time && world.time > follow_until_time) + lose_follow() + set_stance(STANCE_IDLE) + return FALSE + if(get_dist(holder, leader) > follow_distance) + return TRUE + return FALSE \ No newline at end of file diff --git a/code/modules/ai/ai_holder_movement.dm b/code/modules/ai/ai_holder_movement.dm new file mode 100644 index 0000000000..55a1098b90 --- /dev/null +++ b/code/modules/ai/ai_holder_movement.dm @@ -0,0 +1,154 @@ +/datum/ai_holder + // General. + var/turf/destination = null // The targeted tile the mob wants to walk to. + var/min_distance_to_destination = 1 // Holds how close the mob should go to destination until they're done. + + // Home. + var/turf/home_turf = null // The mob's 'home' turf. It will try to stay near it if told to do so. This is the turf the AI was initialized on by default. + var/returns_home = FALSE // If true, makes the mob go to its 'home' if it strays too far. + var/home_low_priority = FALSE // If true, the mob will not go home unless it has nothing better to do, e.g. its following someone. + var/max_home_distance = 3 // How far the mob can go away from its home before being told to go_home(). + // Note that there is a 'BYOND cap' of 14 due to limitations of get_/step_to(). + + // Wandering. + var/wander = FALSE // If true, the mob will randomly move in the four cardinal directions when idle. + var/wander_delay = 0 // How many ticks until the mob can move a tile in handle_wander_movement(). + var/base_wander_delay = 2 // What the above var gets set to when it wanders. Note that a tick happens every half a second. + var/wander_when_pulled = FALSE // If the mob will refrain from wandering if someone is pulling it. + + +/datum/ai_holder/proc/walk_to_destination() + ai_log("walk_to_destination() : Entering.",AI_LOG_TRACE) + if(!destination) + ai_log("walk_to_destination() : No destination.", AI_LOG_WARNING) + forget_path() + set_stance(stance == STANCE_REPOSITION ? STANCE_APPROACH : STANCE_IDLE) + ai_log("walk_to_destination() : Exiting.", AI_LOG_TRACE) + return + + var/get_to = min_distance_to_destination + var/distance = get_dist(holder, destination) + ai_log("walk_to_destination() : get_to is [get_to].", AI_LOG_TRACE) + + // We're here! + if(distance <= get_to) + give_up_movement() + set_stance(stance == STANCE_REPOSITION ? STANCE_APPROACH : STANCE_IDLE) + ai_log("walk_to_destination() : Destination reached. Exiting.", AI_LOG_INFO) + return + + ai_log("walk_to_destination() : Walking.", AI_LOG_TRACE) + walk_path(destination, get_to) + ai_log("walk_to_destination() : Exiting.",AI_LOG_TRACE) + +/datum/ai_holder/proc/should_go_home() + if(!returns_home || !home_turf) + return FALSE + if(get_dist(holder, home_turf) > max_home_distance) + if(!home_low_priority) + return TRUE + else if(!leader && !target) + return TRUE + return FALSE +// return (returns_home && home_turf) && (get_dist(holder, home_turf) > max_home_distance) + +/datum/ai_holder/proc/go_home() + if(home_turf) + ai_log("go_home() : Telling holder to go home.", AI_LOG_INFO) + lose_follow() // So they don't try to path back and forth. + give_destination(home_turf, max_home_distance) + else + ai_log("go_home() : Told to go home without home_turf.", AI_LOG_ERROR) + +/datum/ai_holder/proc/give_destination(turf/new_destination, min_distance = 1, combat = FALSE) + ai_log("give_destination() : Entering.", AI_LOG_DEBUG) + + destination = new_destination + min_distance_to_destination = min_distance + + if(new_destination != null) + ai_log("give_destination() : Going to new destination.", AI_LOG_INFO) + set_stance(combat ? STANCE_REPOSITION : STANCE_MOVE) + return TRUE + else + ai_log("give_destination() : Given null destination.", AI_LOG_ERROR) + + ai_log("give_destination() : Exiting.", AI_LOG_DEBUG) + + +// Walk towards whatever. +/datum/ai_holder/proc/walk_path(atom/A, get_to = 1) + ai_log("walk_path() : Entered.", AI_LOG_TRACE) + + if(use_astar) + if(!path.len) // If we're missing a path, make a new one. + ai_log("walk_path() : No path. Attempting to calculate path.", AI_LOG_DEBUG) + calculate_path(A, get_to) + + if(!path.len) // If we still don't have one, then the target's probably somewhere inaccessible to us. Get as close as we can. + ai_log("walk_path() : Failed to obtain path to target. Using get_step_to() instead.", AI_LOG_INFO) + // step_to(holder, A) + if(holder.IMove(get_step_to(holder, A)) == MOVEMENT_FAILED) + ai_log("walk_path() : Failed to move, attempting breakthrough.", AI_LOG_INFO) + breakthrough(A) // We failed to move, time to smash things. + return + + if(move_once() == FALSE) // Start walking the path. + ai_log("walk_path() : Failed to step.", AI_LOG_TRACE) + ++failed_steps + if(failed_steps > 3) // We're probably stuck. + ai_log("walk_path() : Too many failed_steps.", AI_LOG_DEBUG) + forget_path() // So lets try again with a new path. + failed_steps = 0 + + else + // step_to(holder, A) + ai_log("walk_path() : Going to IMove().", AI_LOG_TRACE) + if(holder.IMove(get_step_to(holder, A)) == MOVEMENT_FAILED ) + ai_log("walk_path() : Failed to move, attempting breakthrough.", AI_LOG_INFO) + breakthrough(A) // We failed to move, time to smash things. + + ai_log("walk_path() : Exited.", AI_LOG_TRACE) + + +//Take one step along a path +/datum/ai_holder/proc/move_once() + ai_log("move_once() : Entered.", AI_LOG_TRACE) + if(!path.len) + return + + if(path_display) + var/turf/T = src.path[1] + T.overlays -= path_overlay + +// step_towards(holder, src.path[1]) + if(holder.IMove(get_step_towards(holder, src.path[1])) != MOVEMENT_ON_COOLDOWN) + if(holder.loc != src.path[1]) + ai_log("move_once() : Failed step. Exiting.", AI_LOG_TRACE) + return MOVEMENT_FAILED + else + path -= src.path[1] + ai_log("move_once() : Successful step. Exiting.", AI_LOG_TRACE) + return MOVEMENT_SUCCESSFUL + ai_log("move_once() : Mob movement on cooldown. Exiting.", AI_LOG_TRACE) + return MOVEMENT_ON_COOLDOWN + +/datum/ai_holder/proc/should_wander() + return wander && !leader + +// Wanders randomly in cardinal directions. +/datum/ai_holder/proc/handle_wander_movement() + ai_log("handle_wander_movement() : Entered.", AI_LOG_TRACE) + if(isturf(holder.loc) && can_act()) + wander_delay-- + if(wander_delay <= 0) + if(!wander_when_pulled && holder.pulledby) + ai_log("handle_wander_movement() : Being pulled and cannot wander. Exiting.", AI_LOG_DEBUG) + return + + var/moving_to = 0 // Apparently this is required or it always picks 4, according to the previous developer for simplemob AI. + moving_to = pick(cardinal) + holder.set_dir(moving_to) + holder.IMove(get_step(holder,moving_to)) + wander_delay = base_wander_delay + ai_log("handle_wander_movement() : Exited.", AI_LOG_TRACE) diff --git a/code/modules/ai/ai_holder_pathfinding.dm b/code/modules/ai/ai_holder_pathfinding.dm new file mode 100644 index 0000000000..1a20c6f682 --- /dev/null +++ b/code/modules/ai/ai_holder_pathfinding.dm @@ -0,0 +1,58 @@ +// This handles obtaining a (usually A*) path towards something, such as a target, destination, or leader. +// This interacts heavily with code inside ai_holder_movement.dm + +/datum/ai_holder + // Pathfinding. + var/use_astar = FALSE // Do we use the more expensive A* implementation or stick with BYOND's default step_to()? + var/list/path = list() // A list of tiles that A* gave us as a solution to reach the target. + var/list/obstacles = list() // Things A* will try to avoid. + var/astar_adjacent_proc = /turf/proc/CardinalTurfsWithAccess // Proc to use when A* pathfinding. Default makes them bound to cardinals. + var/failed_steps = 0 // If move_once() fails to move the mob onto the correct tile, this increases. When it reaches 3, the path is recalc'd since they're probably stuck. + +// This clears the stored A* path. +/datum/ai_holder/proc/forget_path() + ai_log("forget_path() : Entering.", AI_LOG_DEBUG) + if(path_display) + for(var/turf/T in path) + T.overlays -= path_overlay + path.Cut() + ai_log("forget_path() : Exiting.", AI_LOG_DEBUG) + +/datum/ai_holder/proc/give_up_movement() + ai_log("give_up_movement() : Entering.", AI_LOG_DEBUG) + forget_path() + destination = null + ai_log("give_up_movement() : Exiting.", AI_LOG_DEBUG) + +/datum/ai_holder/proc/calculate_path(atom/A, get_to = 1) + ai_log("calculate_path([A],[get_to]) : Entering.", AI_LOG_DEBUG) + if(!A) + ai_log("calculate_path() : Called without an atom. Exiting.",AI_LOG_WARNING) + return + + if(!use_astar) // If we don't use A* then this is pointless. + ai_log("calculate_path() : Not using A*, Exiting.", AI_LOG_DEBUG) + return + + get_path(get_turf(A), get_to) + + ai_log("calculate_path() : Exiting.", AI_LOG_DEBUG) + +//A* now, try to a path to a target +/datum/ai_holder/proc/get_path(var/turf/target,var/get_to = 1, var/max_distance = world.view*6) + ai_log("get_path() : Entering.",AI_LOG_DEBUG) + forget_path() + var/list/new_path = AStar(get_turf(holder.loc), target, astar_adjacent_proc, /turf/proc/Distance, min_target_dist = get_to, max_node_depth = max_distance, id = holder.IGetID(), exclude = obstacles) + + if(new_path && new_path.len) + path = new_path + ai_log("get_path() : Made new path.",AI_LOG_DEBUG) + if(path_display) + for(var/turf/T in path) + T.overlays |= path_overlay + else + ai_log("get_path() : Failed to make new path. Exiting.",AI_LOG_DEBUG) + return 0 + + ai_log("get_path() : Exiting.", AI_LOG_DEBUG) + return path.len \ No newline at end of file diff --git a/code/modules/ai/ai_holder_targeting.dm b/code/modules/ai/ai_holder_targeting.dm new file mode 100644 index 0000000000..623b2f0b83 --- /dev/null +++ b/code/modules/ai/ai_holder_targeting.dm @@ -0,0 +1,256 @@ +// Used for assigning a target for attacking. + +/datum/ai_holder + var/hostile = FALSE // Do we try to hurt others? + var/retaliate = FALSE // Attacks whatever struck it first. Mobs will still attack back if this is false but hostile is true. + var/mauling = FALSE // Attacks unconscious mobs + + var/atom/movable/target = null // The thing (mob or object) we're trying to kill. + var/atom/movable/preferred_target = null// If set, and if given the chance, we will always prefer to target this over other options. + var/turf/target_last_seen_turf = null // Where the mob last observed the target being, used if the target disappears but the mob wants to keep fighting. + + var/vision_range = 7 // How far the targeting system will look for things to kill. Note that values higher than 7 are 'offscreen' and might be unsporting. + var/respect_alpha = TRUE // If true, mobs with a sufficently low alpha will be treated as invisible. + var/alpha_vision_threshold = 127 // Targets with an alpha less or equal to this will be considered invisible. Requires above var to be true. + + var/lose_target_time = 0 // world.time when a target was lost. + var/lose_target_timeout = 5 SECONDS // How long until a mob 'times out' and stops trying to find the mob that disappeared. + + var/list/attackers = list() // List of strings of names of people who attacked us before in our life. + // This uses strings and not refs to allow for disguises, and to avoid needing to use weakrefs. + var/destructive = FALSE // Will target 'neutral' structures/objects and not just 'hostile' ones. + +// A lot of this is based off of /TG/'s AI code. + +// Step 1, find out what we can see. +/datum/ai_holder/proc/list_targets() + . = hearers(vision_range, holder) - src // Remove ourselves to prevent suicidal decisions. + + var/static/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/mecha)) + + for(var/HM in typecache_filter_list(range(vision_range, holder), hostile_machines)) + if(can_see(holder, HM, vision_range)) + . += HM + +// Step 2, filter down possible targets to things we actually care about. +/datum/ai_holder/proc/find_target(var/list/possible_targets, var/has_targets_list = FALSE) + if(!hostile) // So retaliating mobs only attack the thing that hit it. + return null + . = list() + if(!has_targets_list) + possible_targets = list_targets() + for(var/possible_target in possible_targets) + var/atom/A = possible_target + if(found(A)) // In case people want to override this. + . = list(A) + break + if(can_attack(A)) // Can we attack it? + . += A + continue + + var/new_target = pick_target(.) + give_target(new_target) + return new_target + +// Step 3, pick among the possible, attackable targets. +/datum/ai_holder/proc/pick_target(list/targets) + if(target != null) // If we already have a target, but are told to pick again, calculate the lowest distance between all possible, and pick from the lowest distance targets. + targets = target_filter_distance(targets) +// for(var/possible_target in targets) +// var/atom/A = possible_target +// var/target_dist = get_dist(holder, target) +// var/possible_target_distance = get_dist(holder, A) +// if(target_dist < possible_target_distance) +// targets -= A + if(!targets.len) // We found nothing. + return + + var/chosen_target + if(preferred_target && preferred_target in targets) + chosen_target = preferred_target + else + chosen_target = pick(targets) + return chosen_target + +// Step 4, give us our selected target. +/datum/ai_holder/proc/give_target(new_target) + target = new_target + if(target != null) + if(should_threaten()) + set_stance(STANCE_ALERT) + else + set_stance(STANCE_APPROACH) + last_target_time = world.time + return TRUE + +// Filters return one or more 'preferred' targets. + +// This one is for closest targets. +/datum/ai_holder/proc/target_filter_distance(list/targets) + for(var/possible_target in targets) + var/atom/A = possible_target + var/target_dist = get_dist(holder, target) + var/possible_target_distance = get_dist(holder, A) + if(target_dist < possible_target_distance) + targets -= A + return targets + +/datum/ai_holder/proc/can_attack(atom/movable/the_target) + if(!can_see_target(the_target)) + return FALSE + + if(istype(the_target, /mob/zshadow)) + return FALSE // no + + if(isliving(the_target)) + var/mob/living/L = the_target + if(ishuman(L) || issilicon(L)) + if(L.key && !L.client) // SSD players get a pass + return FALSE + if(L.stat) + if(L.stat == DEAD) // Leave dead things alone + return FALSE + if(L.stat == UNCONSCIOUS) // Do we have mauling? Yes? Then maul people who are sleeping but not SSD + if(mauling) + return TRUE + else + return FALSE + if(holder.IIsAlly(L)) + return FALSE + return TRUE + + if(istype(the_target, /obj/mecha)) + var/obj/mecha/M = the_target + if(M.occupant) + return can_attack(M.occupant) + return destructive // Empty mechs are 'neutral'. + + if(istype(the_target, /obj/machinery/porta_turret)) + var/obj/machinery/porta_turret/P = the_target + if(P.stat & BROKEN) + return FALSE // Already dead. + if(P.faction == holder.faction) + return FALSE // Don't shoot allied turrets. + if(!P.raised && !P.raising) + return FALSE // Turrets won't get hurt if they're still in their cover. + return TRUE + + return TRUE +// return FALSE + +// Override this for special targeting criteria. +// If it returns true, the mob will always select it as the target. +/datum/ai_holder/proc/found(atom/movable/the_target) + return FALSE + +//We can't see the target, go look or attack where they were last seen. +/datum/ai_holder/proc/lose_target() + if(target) + target = null + lose_target_time = world.time + + give_up_movement() + + +//Target is no longer valid (?) +/datum/ai_holder/proc/lost_target() + set_stance(STANCE_IDLE) + lose_target_position() + lose_target() + +// Check if target is visible to us. +/datum/ai_holder/proc/can_see_target(atom/movable/the_target, view_range = vision_range) + ai_log("can_see_target() : Entering.", AI_LOG_TRACE) + + if(!the_target) // Nothing to target. + ai_log("can_see_target() : There is no target. Exiting.", AI_LOG_WARNING) + return FALSE + + if(holder.see_invisible < the_target.invisibility) // Real invis. + ai_log("can_see_target() : Target ([the_target]) was invisible to holder. Exiting.", AI_LOG_TRACE) + return FALSE + + if(respect_alpha && the_target.alpha <= alpha_vision_threshold) // Fake invis. + ai_log("can_see_target() : Target ([the_target]) was sufficently transparent to holder and is hidden. Exiting.", AI_LOG_TRACE) + return FALSE + + if(get_dist(holder, the_target) > view_range) // Too far away. + ai_log("can_see_target() : Target ([the_target]) was too far from holder. Exiting.", AI_LOG_TRACE) + return FALSE + + if(!can_see(holder, the_target, view_range)) + ai_log("can_see_target() : Target ([the_target]) failed can_see(). Exiting.", AI_LOG_TRACE) + return FALSE + + ai_log("can_see_target() : Target ([the_target]) can be seen. Exiting.", AI_LOG_TRACE) + return TRUE + +// Updates the last known position of the target. +/datum/ai_holder/proc/track_target_position() + if(!target) + lose_target_position() + + if(last_turf_display && target_last_seen_turf) + target_last_seen_turf.overlays -= last_turf_overlay + + target_last_seen_turf = get_turf(target) + + if(last_turf_display) + target_last_seen_turf.overlays += last_turf_overlay + +// Resets the last known position to null. +/datum/ai_holder/proc/lose_target_position() + if(last_turf_display && target_last_seen_turf) + target_last_seen_turf.overlays -= last_turf_overlay + ai_log("lose_target_position() : Last position is being reset.", AI_LOG_INFO) + target_last_seen_turf = null + +// Responds to a hostile action against its mob. +/datum/ai_holder/proc/react_to_attack(atom/movable/attacker) + if(holder.stat) // We're dead. + ai_log("react_to_attack() : Was attacked by [attacker], but we are dead/unconscious.", AI_LOG_TRACE) + return FALSE + if(!hostile && !retaliate) // Not allowed to defend ourselves. + ai_log("react_to_attack() : Was attacked by [attacker], but we are not allowed to attack back.", AI_LOG_TRACE) + return FALSE + if(holder.IIsAlly(attacker)) // I'll overlook it THIS time... + ai_log("react_to_attack() : Was attacked by [attacker], but they were an ally.", AI_LOG_TRACE) + return FALSE + if(target) // Already fighting someone. Switching every time we get hit would impact our combat performance. + if(!retaliate) // If we don't get to fight back, we don't fight back... + ai_log("react_to_attack() : Was attacked by [attacker], but we already have a target.", AI_LOG_TRACE) + on_attacked(attacker) // So we attack immediately and not threaten. + return FALSE + else if(attacker in attackers && world.time > last_target_time + 3 SECONDS) // Otherwise, let 'er rip + ai_log("react_to_attack() : Was attacked by [attacker]. Can retaliate, waited 3 seconds.", AI_LOG_INFO) + on_attacked(attacker) // So we attack immediately and not threaten. + return give_target(attacker) // Also handles setting the appropiate stance. + + if(stance == STANCE_SLEEP) // If we're asleep, try waking up if someone's wailing on us. + ai_log("react_to_attack() : AI is asleep. Waking up.", AI_LOG_TRACE) + go_wake() + + ai_log("react_to_attack() : Was attacked by [attacker].", AI_LOG_INFO) + on_attacked(attacker) // So we attack immediately and not threaten. + return give_target(attacker) // Also handles setting the appropiate stance. + +// Sets a few vars so mobs that threaten will react faster to an attacker or someone who attacked them before. +/datum/ai_holder/proc/on_attacked(atom/movable/AM) + if(isliving(AM)) + var/mob/living/L = AM + if(!(L.name in attackers)) + attackers |= L.name + last_conflict_time = world.time + +// Causes targeting to prefer targeting the taunter if possible. +// This generally occurs if more than one option is within striking distance, including the taunter. +// Otherwise the default filter will prefer the closest target. +/datum/ai_holder/proc/receive_taunt(atom/movable/taunter, force_target_switch = FALSE) + ai_log("receive_taunt() : Was taunted by [taunter].", AI_LOG_INFO) + preferred_target = taunter + if(force_target_switch) + give_target(taunter) + +/datum/ai_holder/proc/lose_taunt() + ai_log("lose_taunt() : Resetting preferred_target.", AI_LOG_INFO) + preferred_target = null \ No newline at end of file diff --git a/code/modules/ai/interfaces.dm b/code/modules/ai/interfaces.dm new file mode 100644 index 0000000000..dbadac8757 --- /dev/null +++ b/code/modules/ai/interfaces.dm @@ -0,0 +1,92 @@ +// 'Interfaces' are procs that the ai_holder datum uses to communicate its will to the mob its attached. +// The reason for using this proc in the middle is to ensure the AI has some form of compatibility with most mob types, +// since some actions work very differently between mob types (e.g. executing an attack as a simple animal compared to a human). +// The AI can just call holder.IAttack(target) and the mob is responsible for determining how to actually attack the target. + +/mob/living/proc/IAttack(atom/A) + return FALSE + +/mob/living/simple_mob/IAttack(atom/A) + if(!canClick()) // Still on cooldown from a "click". + return FALSE + return attack_target(A) // This will set click cooldown. + +/mob/living/proc/IRangedAttack(atom/A) + return FALSE + +/mob/living/simple_mob/IRangedAttack(atom/A) + if(!canClick()) // Still on cooldown from a "click". + return FALSE + return shoot_target(A) + +// Test if the AI is allowed to attempt a ranged attack. +/mob/living/proc/ICheckRangedAttack(atom/A) + return FALSE + +/mob/living/simple_mob/ICheckRangedAttack(atom/A) + if(needs_reload) + if(reload_count >= reload_max) + try_reload() + return FALSE + return projectiletype ? TRUE : FALSE + +/mob/living/proc/ISpecialAttack(atom/A) + return FALSE + +/mob/living/simple_mob/ISpecialAttack(atom/A) + return special_attack_target(A) + +// Is the AI allowed to attempt to do it? +/mob/living/proc/ICheckSpecialAttack(atom/A) + return FALSE + +/mob/living/simple_mob/ICheckSpecialAttack(atom/A) + return can_special_attack(A) && should_special_attack(A) // Just because we can doesn't mean we should. + +/mob/living/proc/ISay(message) + return say(message) + +/mob/living/proc/IIsAlly(mob/living/L) + return src.faction == L.faction + +/mob/living/simple_mob/IIsAlly(mob/living/L) + . = ..() + if(!.) // Outside the faction, try to see if they're friends. + return L in friends + +/mob/living/proc/IGetID() + +/mob/living/simple_mob/IGetID() + if(myid) + return myid.GetID() + +// Respects move cooldowns as if it had a client. +// Also tries to avoid being superdumb with moving into certain tiles (unless that's desired). +/mob/living/proc/IMove(turf/newloc, safety = TRUE) + if(check_move_cooldown()) +// if(!newdir) +// newdir = get_dir(get_turf(src), newloc) + + // Check to make sure moving to newloc won't actually kill us. e.g. we're a slime and trying to walk onto water. + if(istype(newloc)) + if(safety && !newloc.is_safe_to_enter(src)) + return MOVEMENT_FAILED + + // Move()ing to another tile successfully returns 32 because BYOND. Would rather deal with TRUE/FALSE-esque terms. + // Note that moving to the same tile will be 'successful'. + var/turf/old_T = get_turf(src) + + // An adjacency check to avoid mobs phasing diagonally past windows. + // This might be better in general movement code but I'm too scared to add it, and most things don't move diagonally anyways. + if(!old_T.Adjacent(newloc)) + return MOVEMENT_FAILED + + . = SelfMove(newloc) ? MOVEMENT_SUCCESSFUL : MOVEMENT_FAILED + if(. == MOVEMENT_SUCCESSFUL) + set_dir(get_dir(old_T, newloc)) + // Apply movement delay. + // Player movement has more factors but its all in the client and fixing that would be its own project. + setMoveCooldown(movement_delay()) + return + + . = MOVEMENT_ON_COOLDOWN // To avoid superfast mobs that aren't meant to be superfast. Is actually -1. diff --git a/code/modules/ai/say_list.dm b/code/modules/ai/say_list.dm new file mode 100644 index 0000000000..9eba02b9b1 --- /dev/null +++ b/code/modules/ai/say_list.dm @@ -0,0 +1,119 @@ +// A simple datum that just holds many lists of lines for mobs to pick from. +// This is its own datum in order to be able to have different types of mobs be able to use the same lines if desired, +// even when inheritence wouldn't be able to do so. + +// Also note this also contains emotes, despite its name. +// and now sounds because its probably better that way. + +/mob/living + var/datum/say_list/say_list = null + var/say_list_type = /datum/say_list // Type to give us on initialization. Default has empty lists, so the mob will be silent. + +/mob/living/Initialize() + if(say_list_type) + say_list = new say_list_type(src) + return ..() + +/mob/living/Destroy() + QDEL_NULL(say_list) + return ..() + + +/datum/say_list + var/list/speak = list() // Things the mob might say if it talks while idle. + var/list/emote_hear = list() // Hearable emotes it might perform + var/list/emote_see = list() // Unlike speak_emote, the list of things in this variable only show by themselves with no spoken text. IE: Ian barks, Ian yaps + + var/list/say_understood = list() // When accepting an order. + var/list/say_cannot = list() // When they cannot comply. + var/list/say_maybe_target = list() // When they briefly see something. + var/list/say_got_target = list() // When a target is first assigned. + var/list/say_threaten = list() // When threatening someone. + var/list/say_stand_down = list() // When the threatened thing goes away. + var/list/say_escalate = list() // When the threatened thing doesn't go away. + + var/threaten_sound = null // Sound file played when the mob's AI calls threaten_target() for the first time. + var/stand_down_sound = null // Sound file played when the mob's AI loses sight of the threatened target. + + + + + + + +// Subtypes. + +// This one's pretty dumb, but pirates are dumb anyways and it makes for a good test. +/datum/say_list/pirate + speak = list("Yarr!") + + say_understood = list("Alright, matey.") + say_cannot = list("No, matey.") + say_maybe_target = list("Eh?") + say_got_target = list("Yarrrr!") + say_threaten = list("You best leave, this booty is mine.", "No plank to walk on, just walk away.") + say_stand_down = list("Good.") + say_escalate = list("Yarr! The booty is mine!") + +// Mercs! +/datum/say_list/merc + speak = list("When are we gonna get out of this chicken-shit outfit?", + "Wish I had better equipment...", + "I knew I should have been a line chef...", + "Fuckin' helmet keeps fogging up.", + "Anyone else smell that?") + emote_see = list("sniffs", "coughs", "taps his foot", "looks around", "checks his equipment") + + say_understood = list("Understood!", "Affirmative!") + say_cannot = list("Negative!") + say_maybe_target = list("Who's there?") + say_got_target = list("Engaging!") + say_threaten = list("Get out of here!", "Hey! Private Property!") + say_stand_down = list("Good.") + say_escalate = list("Your funeral!", "Bring it!") + +/datum/say_list/malf_drone + speak = list("ALERT.","Hostile-ile-ile entities dee-twhoooo-wected.","Threat parameterszzzz- szzet.","Bring sub-sub-sub-systems uuuup to combat alert alpha-a-a.") + emote_see = list("beeps menacingly","whirrs threateningly","scans its immediate vicinity") + + say_understood = list("Affirmative.", "Positive.") + say_cannot = list("Denied.", "Negative.") + say_maybe_target = list("Possible threat detected. Investigating.", "Motion detected.", "Investigating.") + say_got_target = list("Threat detected.", "New task: Remove threat.", "Threat removal engaged.", "Engaging target.") + say_threaten = list("Motion detected, judging target...") + say_stand_down = list("Visual lost.", "Error: Target not found.") + say_escalate = list("Viable target found. Removing.", "Engaging target.", "Target judgement complete. Removal required.") + + threaten_sound = 'sound/effects/turret/move1.wav' + stand_down_sound = 'sound/effects/turret/move2.wav' + +/datum/say_list/mercenary + threaten_sound = 'sound/weapons/TargetOn.ogg' + stand_down_sound = 'sound/weapons/TargetOff.ogg' + + +/datum/say_list/crab + emote_hear = list("clicks") + emote_see = list("clacks") + +/datum/say_list/spider + emote_hear = list("chitters") + +/datum/say_list/hivebot + speak = list( + "Resuming task: Protect area.", + "No threats found.", + "Error: No targets found." + ) + emote_hear = list("hums ominously", "whirrs softly", "grinds a gear") + emote_see = list("looks around the area", "turns from side to side") + say_understood = list("Affirmative.", "Positive.") + say_cannot = list("Denied.", "Negative.") + say_maybe_target = list("Possible threat detected. Investigating.", "Motion detected.", "Investigating.") + say_got_target = list("Threat detected.", "New task: Remove threat.", "Threat removal engaged.", "Engaging target.") + +/datum/say_list/lizard + emote_hear = list("hisses") + +/datum/say_list/crab + emote_hear = list("hisses") \ No newline at end of file diff --git a/code/modules/alarm/alarm.dm b/code/modules/alarm/alarm.dm index 26ffdade04..f8d853ca8c 100644 --- a/code/modules/alarm/alarm.dm +++ b/code/modules/alarm/alarm.dm @@ -31,7 +31,7 @@ cameras() // Sets up both cameras and last alarm area. set_source_data(source, duration, severity, hidden) -/datum/alarm/proc/process() +/datum/alarm/process() // Has origin gone missing? if(!origin && !end_time) end_time = world.time + ALARM_RESET_DELAY diff --git a/code/modules/alarm/alarm_handler.dm b/code/modules/alarm/alarm_handler.dm index a07ca8bd3b..d7a7cdf713 100644 --- a/code/modules/alarm/alarm_handler.dm +++ b/code/modules/alarm/alarm_handler.dm @@ -7,7 +7,7 @@ var/list/datum/alarm/alarms_assoc = new // Associative list of alarms, to efficiently acquire them based on origin. var/list/listeners = new // A list of all objects interested in alarm changes. -/datum/alarm_handler/proc/process() +/datum/alarm_handler/process() for(var/datum/alarm/A in alarms) A.process() check_alarm_cleared(A) diff --git a/code/modules/artifice/deadringer.dm b/code/modules/artifice/deadringer.dm index e12c0b0045..bdac793daf 100644 --- a/code/modules/artifice/deadringer.dm +++ b/code/modules/artifice/deadringer.dm @@ -16,11 +16,11 @@ /obj/item/weapon/deadringer/New() ..() - processing_objects |= src + START_PROCESSING(SSobj, src) /obj/item/weapon/deadringer/Destroy() //just in case some smartass tries to stay invisible by destroying the watch uncloak() - processing_objects -= src + STOP_PROCESSING(SSobj, src) ..() /obj/item/weapon/deadringer/dropped() @@ -76,13 +76,14 @@ return /obj/item/weapon/deadringer/proc/deathprevent() - for(var/mob/living/simple_animal/D in oviewers(7, src)) - D.LoseTarget() + for(var/mob/living/simple_mob/D in oviewers(7, src)) + if(!D.has_AI()) + continue + D.ai_holder.lose_target() + watchowner.emote("deathgasp") watchowner.alpha = 15 makeacorpse(watchowner) - for(var/mob/living/simple_animal/D in oviewers(7, src)) - D.LoseTarget() return /obj/item/weapon/deadringer/proc/uncloak() diff --git a/code/modules/assembly/assembly.dm b/code/modules/assembly/assembly.dm index 8c965f0deb..317765be97 100644 --- a/code/modules/assembly/assembly.dm +++ b/code/modules/assembly/assembly.dm @@ -113,7 +113,7 @@ /obj/item/device/assembly/process() - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) return diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm index 0cc5f49682..1a02474a8e 100644 --- a/code/modules/assembly/holder.dm +++ b/code/modules/assembly/holder.dm @@ -233,7 +233,7 @@ tmr.time=5 tmr.secured = 1 tmr.holder = src - processing_objects.Add(tmr) + START_PROCESSING(SSobj, tmr) a_left = tmr a_right = ign secured = 1 diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm index 849729f332..a76dae8ec7 100644 --- a/code/modules/assembly/infrared.dm +++ b/code/modules/assembly/infrared.dm @@ -25,11 +25,11 @@ /obj/item/device/assembly/infra/toggle_secure() secured = !secured if(secured) - processing_objects.Add(src) + START_PROCESSING(SSobj, src) else on = 0 if(first) qdel(first) - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) update_icon() return secured @@ -142,12 +142,12 @@ return -/obj/item/device/assembly/infra/verb/rotate()//This could likely be better - set name = "Rotate Infrared Laser" +/obj/item/device/assembly/infra/verb/rotate_clockwise() + set name = "Rotate Infrared Laser Clockwise" set category = "Object" set src in usr - set_dir(turn(dir, 90)) + src.set_dir(turn(src.dir, 270)) return diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm index e45c6d8beb..7d1c5346c0 100644 --- a/code/modules/assembly/mousetrap.dm +++ b/code/modules/assembly/mousetrap.dm @@ -40,7 +40,7 @@ H.UpdateDamageIcon() H.updatehealth() else if(ismouse(target)) - var/mob/living/simple_animal/mouse/M = target + var/mob/living/simple_mob/animal/passive/mouse/M = target visible_message("SPLAT!") M.splat() playsound(target.loc, 'sound/effects/snap.ogg', 50, 1) diff --git a/code/modules/assembly/proximity.dm b/code/modules/assembly/proximity.dm index c08b908dc4..a03130ea92 100644 --- a/code/modules/assembly/proximity.dm +++ b/code/modules/assembly/proximity.dm @@ -25,11 +25,11 @@ /obj/item/device/assembly/prox_sensor/toggle_secure() secured = !secured if(secured) - processing_objects.Add(src) + START_PROCESSING(SSobj, src) else scanning = 0 timing = 0 - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) update_icon() return secured diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm index cd4c253f66..c78a70b37d 100644 --- a/code/modules/assembly/signaler.dm +++ b/code/modules/assembly/signaler.dm @@ -156,13 +156,13 @@ Code: /obj/item/device/assembly/signaler/process() if(!deadman) - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) var/mob/M = src.loc if(!M || !ismob(M)) if(prob(5)) signal() deadman = 0 - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) else if(prob(5)) M.visible_message("[M]'s finger twitches a bit over [src]'s signal button!") return @@ -172,7 +172,7 @@ Code: set name = "Threaten to push the button!" set desc = "BOOOOM!" deadman = 1 - processing_objects.Add(src) + START_PROCESSING(SSobj, src) log_and_message_admins("is threatening to trigger a signaler deadman's switch") usr.visible_message("[usr] moves their finger over [src]'s signal button...") diff --git a/code/modules/assembly/timer.dm b/code/modules/assembly/timer.dm index b8d0112066..488083d11a 100644 --- a/code/modules/assembly/timer.dm +++ b/code/modules/assembly/timer.dm @@ -25,10 +25,10 @@ /obj/item/device/assembly/timer/toggle_secure() secured = !secured if(secured) - processing_objects.Add(src) + START_PROCESSING(SSobj, src) else timing = 0 - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) update_icon() return secured diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm index d1602f479b..115ecaa54d 100644 --- a/code/modules/awaymissions/corpse.dm +++ b/code/modules/awaymissions/corpse.dm @@ -26,7 +26,7 @@ var/species = SPECIES_HUMAN delete_me = TRUE -/obj/effect/landmark/corpse/initialize() +/obj/effect/landmark/corpse/Initialize() ..() createCorpse() return INITIALIZE_HINT_QDEL diff --git a/code/modules/awaymissions/gateway.dm b/code/modules/awaymissions/gateway.dm index 558dc668b0..cee8fb73b0 100644 --- a/code/modules/awaymissions/gateway.dm +++ b/code/modules/awaymissions/gateway.dm @@ -8,7 +8,7 @@ var/active = 0 -/obj/machinery/gateway/initialize() +/obj/machinery/gateway/Initialize() update_icon() if(dir == SOUTH) density = 0 @@ -34,7 +34,7 @@ var/wait = 0 //this just grabs world.time at world start var/obj/machinery/gateway/centeraway/awaygate = null -/obj/machinery/gateway/centerstation/initialize() +/obj/machinery/gateway/centerstation/Initialize() update_icon() wait = world.time + config.gateway_delay //+ thirty minutes default awaygate = locate(/obj/machinery/gateway/centeraway) @@ -164,7 +164,7 @@ obj/machinery/gateway/centerstation/process() var/obj/machinery/gateway/centeraway/stationgate = null -/obj/machinery/gateway/centeraway/initialize() +/obj/machinery/gateway/centeraway/Initialize() update_icon() stationgate = locate(/obj/machinery/gateway/centerstation) . = ..() diff --git a/code/modules/awaymissions/loot.dm b/code/modules/awaymissions/loot.dm index 6ca57138b6..1c1d901161 100644 --- a/code/modules/awaymissions/loot.dm +++ b/code/modules/awaymissions/loot.dm @@ -5,7 +5,7 @@ var/lootdoubles = 0 //if the same item can be spawned twice var/loot = "" //a list of possible items to spawn- a string of paths -/obj/effect/spawner/lootdrop/initialize() +/obj/effect/spawner/lootdrop/Initialize() ..() var/list/things = params2list(loot) diff --git a/code/modules/awaymissions/loot_vr.dm b/code/modules/awaymissions/loot_vr.dm index 9c88e740a7..071388a46f 100644 --- a/code/modules/awaymissions/loot_vr.dm +++ b/code/modules/awaymissions/loot_vr.dm @@ -24,12 +24,12 @@ 100 - low_probability * 50;"spacesuit", \ "health", \ 25 + low_probability * 75;"snacks", \ - 25;"alien", \ + /*25;"alien", \ */ //VORESTATION AI TEMPORARY REMOVAL "lights", \ 25 - low_probability * 25;"engineering", \ 25 - low_probability * 25;"coffin", \ - 25;"mimic", \ - 25;"viscerator", \ + /*25;"mimic", \ //VORESTATION AI TEMPORARY REMOVAL + 25;"viscerator", \ */ //VORESTATION AI TEMPORARY REMOVAL )) if("treasure") var/obj/structure/closet/crate/C = new(src.loc) @@ -276,23 +276,23 @@ /obj/item/weapon/reagent_containers/food/snacks/liquidfood) for(var/i=0,iThe corpse of [H.name] suddenly rises!") -/mob/living/simple_animal/hostile/blob/spore/GetIdCard() +/mob/living/simple_mob/hostile/blob/spore/GetIdCard() if(infested) // If we've infested someone, use their ID. return infested.GetIdCard() \ No newline at end of file diff --git a/code/modules/blob2/overmind/overmind.dm b/code/modules/blob2/overmind/overmind.dm index 8ba73eb1e6..6477c86f22 100644 --- a/code/modules/blob2/overmind/overmind.dm +++ b/code/modules/blob2/overmind/overmind.dm @@ -53,7 +53,7 @@ var/list/overminds = list() B.update_icon() //reset anything that was ours for(var/BLO in blob_mobs) - var/mob/living/simple_animal/hostile/blob/BM = BLO + var/mob/living/simple_mob/blob/spore/BM = BLO if(BM) BM.overmind = null BM.update_icons() diff --git a/code/modules/blob2/overmind/types.dm b/code/modules/blob2/overmind/types.dm index c8aca03cf6..6049ccfc72 100644 --- a/code/modules/blob2/overmind/types.dm +++ b/code/modules/blob2/overmind/types.dm @@ -32,7 +32,7 @@ var/can_build_resources = FALSE // Ditto, for resource blobs. var/can_build_nodes = TRUE // Ditto, for nodes. - var/spore_type = /mob/living/simple_animal/hostile/blob/spore + var/spore_type = /mob/living/simple_mob/blob/spore var/ranged_spores = FALSE // For proper spores of the type above. var/spore_firesound = 'sound/effects/slime_squish.ogg' var/spore_range = 7 // The range the spore can fire. @@ -72,7 +72,7 @@ return // Spore things -/datum/blob_type/proc/on_spore_death(mob/living/simple_animal/hostile/blob/spore/S) +/datum/blob_type/proc/on_spore_death(mob/living/simple_mob/blob/spore/S) return @@ -120,7 +120,7 @@ brute_multiplier = 0.25 burn_multiplier = 0.6 ai_aggressiveness = 50 //Really doesn't like you near it. - spore_type = /mob/living/simple_animal/hostile/hivebot/swarm + spore_type = /mob/living/simple_mob/mechanical/hivebot/swarm /datum/blob_type/fabrication_swarm/on_received_damage(var/obj/structure/blob/B, damage, damage_type, mob/living/attacker) if(istype(B, /obj/structure/blob/normal)) @@ -227,9 +227,9 @@ burn_multiplier = 3 ai_aggressiveness = 40 can_build_factories = TRUE - spore_type = /mob/living/simple_animal/hostile/blob/spore/infesting + spore_type = /mob/living/simple_mob/blob/spore/infesting -/datum/blob_type/fungal_bloom/on_spore_death(mob/living/simple_animal/hostile/blob/spore/S) +/datum/blob_type/fungal_bloom/on_spore_death(mob/living/simple_mob/blob/spore/S) if(S.is_infesting) return // Don't make blobs if they were on someone's head. var/turf/T = get_turf(S) @@ -258,11 +258,11 @@ brute_multiplier = 1.5 ai_aggressiveness = 30 // The spores do most of the fighting. can_build_factories = TRUE - spore_type = /mob/living/simple_animal/hostile/blob/spore/weak + spore_type = /mob/living/simple_mob/blob/spore/weak /datum/blob_type/fulminant_organism/on_expand(var/obj/structure/blob/B, var/obj/structure/blob/new_B, var/turf/T, var/mob/observer/blob/O) if(prob(10)) // 10% chance to make a weak spore when expanding. - var/mob/living/simple_animal/hostile/blob/S = new spore_type(T) + var/mob/living/simple_mob/blob/spore/S = new spore_type(T) if(istype(S)) S.overmind = O O.blob_mobs.Add(S) @@ -272,7 +272,7 @@ /datum/blob_type/fulminant_organism/on_death(obj/structure/blob/B) if(prob(33)) // 33% chance to make a spore when dying. - var/mob/living/simple_animal/hostile/blob/S = new spore_type(get_turf(B)) + var/mob/living/simple_mob/blob/spore/S = new spore_type(get_turf(B)) B.visible_message("\The [S] floats free from the [name]!") if(istype(S)) S.overmind = B.overmind @@ -614,7 +614,7 @@ attack_verb = "crashes against" can_build_factories = TRUE can_build_resources = TRUE - spore_type = /mob/living/simple_animal/hostile/blob/spore/weak + spore_type = /mob/living/simple_mob/blob/spore/weak ranged_spores = TRUE spore_range = 3 spore_projectile = /obj/item/projectile/energy/blob/splattering diff --git a/code/modules/busy_space/air_traffic.dm b/code/modules/busy_space/air_traffic.dm index e90392d9d0..3eb9771ac0 100644 --- a/code/modules/busy_space/air_traffic.dm +++ b/code/modules/busy_space/air_traffic.dm @@ -17,7 +17,7 @@ var/datum/lore/atc_controller/atc = new/datum/lore/atc_controller next_message = world.time + rand(delay_min,delay_max) process() -/datum/lore/atc_controller/proc/process() +/datum/lore/atc_controller/process() if(world.time >= next_message) if(squelched) next_message = world.time + backoff_delay diff --git a/code/modules/busy_space/organizations.dm b/code/modules/busy_space/organizations.dm index 94f2872711..c56d967b2f 100644 --- a/code/modules/busy_space/organizations.dm +++ b/code/modules/busy_space/organizations.dm @@ -476,19 +476,19 @@ // Governments -/datum/lore/organization/gov/sifgov - name = "Sif Governmental Authority" - short_name = "SifGov" - desc = "SifGov is the sole governing administration for the Vir system, based in New Reykjavik, Sif. It is a representative \ - democratic government, and a fully recognized member of the Solar Central Government. Anyone operating inside of Vir must \ - comply with SifGov's legislation and regulations." // Vorestation Edit. Confederate -> Central +/datum/lore/organization/gov/virgov + name = "Vir Governmental Authority" + short_name = "VirGov" + desc = "VirGov is the sole governing administration for the Vir system, based in New Reykjavik, Sif. It is a representative \ + democratic government, and a fully recognized member of the Solar Confederate Government. Anyone operating inside of Vir must \ + comply with VirGov's legislation and regulations." history = "" // Todo like the rest of them - work = "governing body of Sif" + work = "governing body of Vir" headquarters = "New Reykjavik, Sif, Vir" motto = "" autogenerate_destination_names = FALSE - ship_prefixes = list("SGA" = "hauling", "SGA" = "energy relay") + ship_prefixes = list("VGA" = "hauling", "VGA" = "energy relay") destination_names = list( "New Reykjavik on Sif", "Radiance Energy Chain", @@ -544,7 +544,7 @@ "Firnir orbit", "Tyr orbit", "Magni orbit", - "a wreck in SifGov territory", + "a wreck in VirGov territory", "a military outpost", ) */ diff --git a/code/modules/client/client defines.dm b/code/modules/client/client defines.dm index 807faab47f..e711006b2a 100644 --- a/code/modules/client/client defines.dm +++ b/code/modules/client/client defines.dm @@ -18,7 +18,7 @@ //OTHER// ///////// var/datum/preferences/prefs = null - var/move_delay = 1 + //var/move_delay = 1 var/moving = null var/adminobs = null var/area = null diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index c31482cb8b..e13573e305 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -44,7 +44,7 @@ //Admin PM if(href_list["priv_msg"]) var/client/C = locate(href_list["priv_msg"]) - if(ismob(C)) //Old stuff can feed-in mobs instead of clients + if(ismob(C)) //Old stuff can feed-in mobs instead ofGLOB.clients var/mob/M = C C = M.client cmd_admin_pm(C,null) @@ -108,8 +108,8 @@ src << "If the title screen is black, resources are still downloading. Please be patient until the title screen appears." - clients += src - directory[ckey] = src + GLOB.clients += src + GLOB.directory[ckey] = src GLOB.ahelp_tickets.ClientLogin(src) @@ -152,7 +152,7 @@ log_client_to_db() send_resources() - GLOB.nanomanager.send_resources(src) + SSnanoui.send_resources(src) if(!void) void = new() @@ -181,8 +181,8 @@ holder.owner = null admins -= src GLOB.ahelp_tickets.ClientLogout(src) - directory -= ckey - clients -= src + GLOB.directory -= ckey + GLOB.clients -= src return ..() /client/Destroy() @@ -401,3 +401,8 @@ client/verb/character_setup() . = R.group[1] else CRASH("Age check regex failed for [src.ckey]") + +/client/vv_edit_var(var_name, var_value) + if(var_name == NAMEOF(src, holder)) + return FALSE + return ..() diff --git a/code/modules/client/preference_setup/antagonism/02_candidacy.dm b/code/modules/client/preference_setup/antagonism/02_candidacy.dm index 530fc721ee..2056fbf06d 100644 --- a/code/modules/client/preference_setup/antagonism/02_candidacy.dm +++ b/code/modules/client/preference_setup/antagonism/02_candidacy.dm @@ -1,21 +1,21 @@ var/global/list/special_roles = list( //keep synced with the defines BE_* in setup.dm --rastaf //some autodetection here. -// TODO: Update to new antagonist system. - "traitor" = IS_MODE_COMPILED("traitor"), // 0 - "operative" = IS_MODE_COMPILED("nuclear"), // 1 - "changeling" = IS_MODE_COMPILED("changeling"), // 2 - "wizard" = IS_MODE_COMPILED("wizard"), // 3 - "malf AI" = IS_MODE_COMPILED("malfunction"), // 4 - "revolutionary" = IS_MODE_COMPILED("revolution"), // 5 - "alien candidate" = 1, //always show // 6 - "positronic brain" = 1, // 7 - "cultist" = IS_MODE_COMPILED("cult"), // 8 - "renegade" = 1, // 9 - "ninja" = "true", // 10 - "raider" = IS_MODE_COMPILED("heist"), // 11 - "diona" = 1, // 12 - "loyalist" = IS_MODE_COMPILED("revolution"), // 13 - "pAI candidate" = 1, // -- TLE // 14 +// Change these to 0 if the equivalent mode is disabled for whatever reason! + "traitor" = 1, // 0 + "operative" = 1, // 1 + "changeling" = 1, // 2 + "wizard" = 1, // 3 + "malf AI" = 1, // 4 + "revolutionary" = 1, // 5 + "alien candidate" = 1, // 6 + "positronic brain" = 1, // 7 + "cultist" = 1, // 8 + "renegade" = 1, // 9 + "ninja" = 1, // 10 + "raider" = 1, // 11 + "diona" = 1, // 12 + "loyalist" = 1, // 13 + "pAI candidate" = 1, // -- TLE // 14 ) /datum/category_item/player_setup_item/antagonism/candidacy diff --git a/code/modules/client/preference_setup/general/03_body.dm b/code/modules/client/preference_setup/general/03_body.dm index c6184c41a0..cda61be1b3 100644 --- a/code/modules/client/preference_setup/general/03_body.dm +++ b/code/modules/client/preference_setup/general/03_body.dm @@ -182,7 +182,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O if(isnull(last_descriptors[entry])) pref.body_descriptors[entry] = descriptor.default_value // Species datums have initial default value. else - pref.body_descriptors[entry] = Clamp(last_descriptors[entry], 1, LAZYLEN(descriptor.standalone_value_descriptors)) + pref.body_descriptors[entry] = CLAMP(last_descriptors[entry], 1, LAZYLEN(descriptor.standalone_value_descriptors)) return diff --git a/code/modules/client/preference_setup/global/05_media.dm b/code/modules/client/preference_setup/global/05_media.dm index 3551735bb9..7ae263d9ea 100644 --- a/code/modules/client/preference_setup/global/05_media.dm +++ b/code/modules/client/preference_setup/global/05_media.dm @@ -15,7 +15,7 @@ S["media_player"] << pref.media_player /datum/category_item/player_setup_item/player_global/media/sanitize_preferences() - pref.media_volume = isnum(pref.media_volume) ? Clamp(pref.media_volume, 0, 1) : initial(pref.media_volume) + pref.media_volume = isnum(pref.media_volume) ? CLAMP(pref.media_volume, 0, 1) : initial(pref.media_volume) pref.media_player = sanitize_inlist(pref.media_player, list(0, 1, 2), initial(pref.media_player)) /datum/category_item/player_setup_item/player_global/media/content(var/mob/user) @@ -35,7 +35,7 @@ if(CanUseTopic(user)) var/value = input("Choose your Jukebox volume (0-100%)", "Jukebox volume", round(pref.media_volume * 100)) if(isnum(value)) - value = Clamp(value, 0, 100) + value = CLAMP(value, 0, 100) pref.media_volume = value/100.0 if(user.client && user.client.media) user.client.media.update_volume(pref.media_volume) diff --git a/code/modules/client/preference_setup/global/setting_datums.dm b/code/modules/client/preference_setup/global/setting_datums.dm index 66b57f67f3..063150f69d 100644 --- a/code/modules/client/preference_setup/global/setting_datums.dm +++ b/code/modules/client/preference_setup/global/setting_datums.dm @@ -76,7 +76,7 @@ var/list/_client_preferences_by_type if(!enabled) preference_mob << sound(null, repeat = 0, wait = 0, volume = 0, channel = 1) preference_mob << sound(null, repeat = 0, wait = 0, volume = 0, channel = 2) - +//VOREStation Add - Need to put it here because it should be ordered riiiight here. /datum/client_preference/play_jukebox description ="Play jukebox music" key = "SOUND_JUKEBOX" @@ -86,18 +86,31 @@ var/list/_client_preferences_by_type preference_mob.stop_all_music() else preference_mob.update_music() -//VOREStation Add - Need to put it here because it should be ordered riiiight here. + /datum/client_preference/eating_noises description = "Eating Noises" key = "EATING_NOISES" enabled_description = "Noisy" disabled_description = "Silent" + /datum/client_preference/digestion_noises description = "Digestion Noises" key = "DIGEST_NOISES" enabled_description = "Noisy" disabled_description = "Silent" //VOREStation Add End +/datum/client_preference/weather_sounds + description ="Weather sounds" + key = "SOUND_WEATHER" + enabled_description = "Audible" + disabled_description = "Silent" + +/datum/client_preference/supermatter_hum + description ="Supermatter hum" + key = "SOUND_SUPERMATTER" + enabled_description = "Audible" + disabled_description = "Silent" + /datum/client_preference/ghost_ears description ="Ghost ears" key = "CHAT_GHOSTEARS" diff --git a/code/modules/client/preference_setup/loadout/loadout_accessories.dm b/code/modules/client/preference_setup/loadout/loadout_accessories.dm index 5e6dfae145..650a457030 100644 --- a/code/modules/client/preference_setup/loadout/loadout_accessories.dm +++ b/code/modules/client/preference_setup/loadout/loadout_accessories.dm @@ -243,4 +243,21 @@ /datum/gear/accessory/locket display_name = "locket" - path = /obj/item/clothing/accessory/locket \ No newline at end of file + path = /obj/item/clothing/accessory/locket + +/datum/gear/accessory/asym + display_name = "asymmetric jacket selection" + path = /obj/item/clothing/accessory/asymmetric + cost = 1 + +/datum/gear/accessory/asym/New() + ..() + var/list/asyms = list() + for(var/asym in typesof(/obj/item/clothing/accessory/asymmetric)) + var/obj/item/clothing/accessory/asymmetric_type = asym + asyms[initial(asymmetric_type.name)] = asymmetric_type + gear_tweaks += new/datum/gear_tweak/path(sortAssoc(asyms)) + +/datum/gear/accessory/cowledvest + display_name = "cowled vest" + path = /obj/item/clothing/accessory/cowledvest \ No newline at end of file diff --git a/code/modules/client/preference_setup/loadout/loadout_eyes.dm b/code/modules/client/preference_setup/loadout/loadout_eyes.dm index 5981424753..8dcb6a61e2 100644 --- a/code/modules/client/preference_setup/loadout/loadout_eyes.dm +++ b/code/modules/client/preference_setup/loadout/loadout_eyes.dm @@ -124,4 +124,20 @@ /datum/gear/eyes/circuitry display_name = "goggles, circuitry (empty)" - path = /obj/item/clothing/glasses/circuitry \ No newline at end of file + path = /obj/item/clothing/glasses/circuitry + +/datum/gear/eyes/glasses/rimless + display_name = "Glasses, rimless" + path = /obj/item/clothing/glasses/rimless + +/datum/gear/eyes/glasses/prescriptionrimless + display_name = "Glasses, prescription rimless" + path = /obj/item/clothing/glasses/regular/rimless + +/datum/gear/eyes/glasses/thin + display_name = "Glasses, thin frame" + path = /obj/item/clothing/glasses/thin + +/datum/gear/eyes/glasses/prescriptionthin + display_name = "Glasses, prescription thin frame" + path = /obj/item/clothing/glasses/regular/thin diff --git a/code/modules/client/preference_setup/loadout/loadout_head.dm b/code/modules/client/preference_setup/loadout/loadout_head.dm index e051daf585..5901d232d8 100644 --- a/code/modules/client/preference_setup/loadout/loadout_head.dm +++ b/code/modules/client/preference_setup/loadout/loadout_head.dm @@ -370,4 +370,12 @@ /datum/gear/head/circuitry display_name = "headwear, circuitry (empty)" - path = /obj/item/clothing/head/circuitry \ No newline at end of file + path = /obj/item/clothing/head/circuitry + +/datum/gear/head/maangtikka + display_name = "maang tikka" + path = /obj/item/clothing/head/maangtikka + +/datum/gear/head/jingasa + display_name = "jingasa" + path = /obj/item/clothing/head/jingasa \ No newline at end of file diff --git a/code/modules/client/preference_setup/loadout/loadout_suit.dm b/code/modules/client/preference_setup/loadout/loadout_suit.dm index 41d37b8a67..0470d85566 100644 --- a/code/modules/client/preference_setup/loadout/loadout_suit.dm +++ b/code/modules/client/preference_setup/loadout/loadout_suit.dm @@ -244,42 +244,34 @@ datum/gear/suit/duster /datum/gear/suit/roles/poncho/cloak/cargo display_name = "cloak, cargo" path = /obj/item/clothing/accessory/poncho/roles/cloak/cargo - allowed_roles = list("Cargo Technician","Quartermaster") /datum/gear/suit/roles/poncho/cloak/mining display_name = "cloak, mining" path = /obj/item/clothing/accessory/poncho/roles/cloak/mining - allowed_roles = list("Quartermaster","Shaft Miner") /datum/gear/suit/roles/poncho/cloak/security display_name = "cloak, security" path = /obj/item/clothing/accessory/poncho/roles/cloak/security - allowed_roles = list("Head of Security","Detective","Warden","Security Officer") /datum/gear/suit/roles/poncho/cloak/service display_name = "cloak, service" path = /obj/item/clothing/accessory/poncho/roles/cloak/service - allowed_roles = list("Head of Personnel","Bartender","Botanist","Janitor","Chef","Librarian") /datum/gear/suit/roles/poncho/cloak/engineer display_name = "cloak, engineer" path = /obj/item/clothing/accessory/poncho/roles/cloak/engineer - allowed_roles = list("Chief Engineer","Station Engineer") /datum/gear/suit/roles/poncho/cloak/atmos display_name = "cloak, atmos" path = /obj/item/clothing/accessory/poncho/roles/cloak/atmos - allowed_roles = list("Chief Engineer","Atmospheric Technician") /datum/gear/suit/roles/poncho/cloak/research display_name = "cloak, science" path = /obj/item/clothing/accessory/poncho/roles/cloak/research - allowed_roles = list("Research Director","Scientist", "Roboticist", "Xenobiologist") /datum/gear/suit/roles/poncho/cloak/medical display_name = "cloak, medical" path = /obj/item/clothing/accessory/poncho/roles/cloak/medical - allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist", "Psychiatrist") /datum/gear/suit/unathi_robe display_name = "roughspun robe" @@ -463,6 +455,10 @@ datum/gear/suit/duster ..() gear_tweaks = list(gear_tweak_free_color_choice) +/datum/gear/suit/miscellaneous/kamishimo + display_name = "kamishimo" + path = /obj/item/clothing/suit/kamishimo + /datum/gear/suit/snowsuit display_name = "snowsuit" path = /obj/item/clothing/suit/storage/snowsuit @@ -495,4 +491,4 @@ datum/gear/suit/duster /datum/gear/suit/snowsuit/cargo display_name = "snowsuit, supply" path = /obj/item/clothing/suit/storage/snowsuit/cargo - allowed_roles = list("Quartermaster","Shaft Miner","Cargo Technician","Head of Personnel") \ No newline at end of file + allowed_roles = list("Quartermaster","Shaft Miner","Cargo Technician","Head of Personnel") diff --git a/code/modules/client/preference_setup/loadout/loadout_uniform.dm b/code/modules/client/preference_setup/loadout/loadout_uniform.dm index 427993f5c4..1a13b75906 100644 --- a/code/modules/client/preference_setup/loadout/loadout_uniform.dm +++ b/code/modules/client/preference_setup/loadout/loadout_uniform.dm @@ -462,4 +462,25 @@ /datum/gear/uniform/circuitry display_name = "jumpsuit, circuitry (empty)" - path = /obj/item/clothing/under/circuitry \ No newline at end of file + path = /obj/item/clothing/under/circuitry + +/datum/gear/uniform/sleekoverall + display_name = "sleek overalls" + path = /obj/item/clothing/under/overalls/sleek + +/datum/gear/uniform/sarired + display_name = "sari, red" + path = /obj/item/clothing/under/dress/sari + +/datum/gear/uniform/sarigreen + display_name = "sari, green" + path = /obj/item/clothing/under/dress/sari/green + +/datum/gear/uniform/wrappedcoat + display_name = "modern wrapped coat" + path = /obj/item/clothing/under/moderncoat + +/datum/gear/uniform/ascetic + display_name = "plain ascetic garb" + path = /obj/item/clothing/under/ascetic + diff --git a/code/modules/client/preference_setup/vore/02_size.dm b/code/modules/client/preference_setup/vore/02_size.dm index 9cacd334e1..2fe8b54e98 100644 --- a/code/modules/client/preference_setup/vore/02_size.dm +++ b/code/modules/client/preference_setup/vore/02_size.dm @@ -60,7 +60,7 @@ /datum/category_item/player_setup_item/vore/size/OnTopic(var/href, var/list/href_list, var/mob/user) if(href_list["size_multiplier"]) var/new_size = input(user, "Choose your character's size, ranging from 25% to 200%", "Set Size") as num|null - if (!IsInRange(new_size,25,200)) + if (!ISINRANGE(new_size,25,200)) pref.size_multiplier = 1 user << "Invalid size." return TOPIC_REFRESH_UPDATE_PREVIEW diff --git a/code/modules/client/preference_setup/vore/03_egg.dm b/code/modules/client/preference_setup/vore/03_egg.dm index 2567ca5021..648b31b399 100644 --- a/code/modules/client/preference_setup/vore/03_egg.dm +++ b/code/modules/client/preference_setup/vore/03_egg.dm @@ -12,7 +12,7 @@ var/XENOMORPH_EGG = "Xenomorph" // Define a place to save appearance in character setup /datum/preferences - var/egg_type = "Egg" //The egg type they have. + var/vore_egg_type = "Egg" //The egg type they have. // Definition of the stuff for the egg type. /datum/category_item/player_setup_item/vore/egg @@ -20,31 +20,31 @@ var/XENOMORPH_EGG = "Xenomorph" sort_order = 3 /datum/category_item/player_setup_item/vore/egg/load_character(var/savefile/S) - S["egg_type"] >> pref.egg_type + S["vore_egg_type"] >> pref.vore_egg_type /datum/category_item/player_setup_item/vore/egg/save_character(var/savefile/S) - S["egg_type"] << pref.egg_type + S["vore_egg_type"] << pref.vore_egg_type /datum/category_item/player_setup_item/vore/egg/sanitize_character() - var/valid_egg_types = global_egg_types - pref.egg_type = sanitize_inlist(pref.egg_type, valid_egg_types, initial(pref.egg_type)) + var/valid_vore_egg_types = global_vore_egg_types + pref.vore_egg_type = sanitize_inlist(pref.vore_egg_type, valid_vore_egg_types, initial(pref.vore_egg_type)) /datum/category_item/player_setup_item/vore/egg/copy_to_mob(var/mob/living/carbon/human/character) - character.egg_type = pref.egg_type + character.vore_egg_type = pref.vore_egg_type /datum/category_item/player_setup_item/vore/egg/content(var/mob/user) . += "
    " - . += " Egg Type: [pref.egg_type]
    " + . += " Egg Type: [pref.vore_egg_type]
    " /datum/category_item/player_setup_item/vore/egg/OnTopic(var/href, var/list/href_list, var/mob/user) if(!CanUseTopic(user)) return TOPIC_NOACTION - else if(href_list["egg_type"]) - var/list/egg_types = global_egg_types - var/selection = input(user, "Choose your character's egg type:", "Character Preference", pref.egg_type) as null|anything in egg_types + else if(href_list["vore_egg_type"]) + var/list/vore_egg_types = global_vore_egg_types + var/selection = input(user, "Choose your character's egg type:", "Character Preference", pref.vore_egg_type) as null|anything in vore_egg_types if(selection) - pref.egg_type = egg_types[selection] + pref.vore_egg_type = vore_egg_types[selection] return TOPIC_REFRESH else - return \ No newline at end of file + return diff --git a/code/modules/client/preferences_factions.dm b/code/modules/client/preferences_factions.dm index 98ba4584d0..4371cdf860 100644 --- a/code/modules/client/preferences_factions.dm +++ b/code/modules/client/preferences_factions.dm @@ -59,10 +59,21 @@ var/global/list/antag_visiblity_choices = list( var/global/list/religion_choices = list( "Unitarianism", - "Hinduism", - "Buddhist", + "Neopaganism", "Islam", "Christianity", + "Judaism", + "Hinduism", + "Buddhism", + "Pleromanism", + "Spectralism", + "Phact Shintoism", + "Kishari Faith", + "Hauler Faith", + "Nock", + "Singulitarian Worship", + "Xilar Qall", + "Tajr-kii Rarkajar", "Agnosticism", "Deism" ) \ No newline at end of file diff --git a/code/modules/client/preferences_toggle_procs.dm b/code/modules/client/preferences_toggle_procs.dm index 4e5e5fb51e..51412906d7 100644 --- a/code/modules/client/preferences_toggle_procs.dm +++ b/code/modules/client/preferences_toggle_procs.dm @@ -143,7 +143,7 @@ toggle_preference(pref_path) - to_chat(src,"You will [ (is_preference_enabled(pref_path)) ? "now" : " no longer"] hear MIDIs from admins.") + to_chat(src,"You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear MIDIs from admins.") prefs.save_preferences() @@ -158,11 +158,41 @@ toggle_preference(pref_path) - to_chat(src,"You will [ (is_preference_enabled(pref_path)) ? "now" : " no longer"] hear ambient noise.") + to_chat(src,"You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear ambient noise.") prefs.save_preferences() - feedback_add_details("admin_verb","TBeSpecial") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + feedback_add_details("admin_verb","TAmbience") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +/client/verb/toggle_weather_sounds() + set name = "Toggle Weather Sounds" + set category = "Preferences" + set desc = "Toggles the ability to hear weather sounds while on a planet." + + var/pref_path = /datum/client_preference/weather_sounds + + toggle_preference(pref_path) + + to_chat(src,"You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear weather sounds.") + + prefs.save_preferences() + + feedback_add_details("admin_verb","TWeatherSounds") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +/client/verb/toggle_supermatter_hum() + set name = "Toggle SM Hum" // Avoiding using the full 'Supermatter' name to not conflict with the Setup-Supermatter adminverb. + set category = "Preferences" + set desc = "Toggles the ability to hear supermatter hums." + + var/pref_path = /datum/client_preference/supermatter_hum + + toggle_preference(pref_path) + + to_chat(src,"You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear a hum from the supermatter.") + + prefs.save_preferences() + + feedback_add_details("admin_verb","TSupermatterHum") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/verb/toggle_jukebox() set name = "Toggle Jukebox" diff --git a/code/modules/clothing/chameleon.dm b/code/modules/clothing/chameleon.dm index b0fe0ae096..5d5296db77 100644 --- a/code/modules/clothing/chameleon.dm +++ b/code/modules/clothing/chameleon.dm @@ -404,7 +404,7 @@ origin_tech = list(TECH_COMBAT = 5, TECH_MATERIAL = 2, TECH_ILLEGAL = 4) matter = list() - fire_sound = 'sound/weapons/Gunshot.ogg' + fire_sound = 'sound/weapons/Gunshot1.ogg' projectile_type = /obj/item/projectile/chameleon charge_meter = 0 charge_cost = 48 //uses next to no power, since it's just holograms @@ -432,7 +432,7 @@ P.pass_flags = initial(copy_projectile.pass_flags) P.fire_sound = initial(copy_projectile.fire_sound) P.hitscan = initial(copy_projectile.hitscan) - P.step_delay = initial(copy_projectile.step_delay) + P.speed = initial(copy_projectile.speed) P.muzzle_type = initial(copy_projectile.muzzle_type) P.tracer_type = initial(copy_projectile.tracer_type) P.impact_type = initial(copy_projectile.impact_type) diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 84a331a77b..bfbf1bb204 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -473,6 +473,7 @@ var/water_speed = 0 //Speed boost/decrease in water, lower/negative values mean more speed var/snow_speed = 0 //Speed boost/decrease on snow, lower/negative values mean more speed + var/rock_climbing = FALSE // If true, allows climbing cliffs with clickdrag. var/step_volume_mod = 1 //How quiet or loud footsteps in this shoe are diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm index fed3119830..820c5afdd4 100644 --- a/code/modules/clothing/glasses/glasses.dm +++ b/code/modules/clothing/glasses/glasses.dm @@ -1,452 +1,477 @@ -/////////////////////////////////////////////////////////////////////// -//Glasses -/* -SEE_SELF // can see self, no matter what -SEE_MOBS // can see all mobs, no matter what -SEE_OBJS // can see all objs, no matter what -SEE_TURFS // can see all turfs (and areas), no matter what -SEE_PIXELS// if an object is located on an unlit area, but some of its pixels are - // in a lit area (via pixel_x,y or smooth movement), can see those pixels -BLIND // can't see anything -*/ -/////////////////////////////////////////////////////////////////////// - -/obj/item/clothing/glasses - name = "glasses" - icon = 'icons/obj/clothing/glasses.dmi' - w_class = ITEMSIZE_SMALL - slot_flags = SLOT_EYES - plane_slots = list(slot_glasses) - var/vision_flags = 0 - var/darkness_view = 0//Base human is 2 - var/see_invisible = -1 - var/prescription = 0 - var/toggleable = 0 - var/off_state = "degoggles" - var/active = 1 - var/activation_sound = 'sound/items/goggles_charge.ogg' - var/obj/screen/overlay = null - var/list/away_planes //Holder for disabled planes - - sprite_sheets = list( - "Teshari" = 'icons/mob/species/seromi/eyes.dmi', - "Vox" = 'icons/mob/species/vox/eyes.dmi' - ) - -/obj/item/clothing/glasses/update_clothing_icon() - if (ismob(src.loc)) - var/mob/M = src.loc - M.update_inv_glasses() - -/obj/item/clothing/glasses/attack_self(mob/user) - if(toggleable) - if(active) - active = 0 - icon_state = off_state - user.update_inv_glasses() - flash_protection = FLASH_PROTECTION_NONE - tint = TINT_NONE - away_planes = enables_planes - enables_planes = null - to_chat(usr, "You deactivate the optical matrix on the [src].") - else - active = 1 - icon_state = initial(icon_state) - user.update_inv_glasses() - flash_protection = initial(flash_protection) - tint = initial(tint) - enables_planes = away_planes - away_planes = null - to_chat(usr, "You activate the optical matrix on the [src].") - user.update_action_buttons() - user.recalculate_vis() - ..() - -/obj/item/clothing/glasses/meson - name = "optical meson scanner" - desc = "Used for seeing walls, floors, and stuff through anything." - icon_state = "meson" - item_state_slots = list(slot_r_hand_str = "meson", slot_l_hand_str = "meson") - action_button_name = "Toggle Goggles" - origin_tech = list(TECH_MAGNET = 2, TECH_ENGINEERING = 2) - toggleable = 1 - vision_flags = SEE_TURFS - enables_planes = list(VIS_FULLBRIGHT, VIS_MESONS) - -/obj/item/clothing/glasses/meson/New() - ..() - overlay = global_hud.meson - -/obj/item/clothing/glasses/meson/prescription - name = "prescription mesons" - desc = "Optical Meson Scanner with prescription lenses." - prescription = 1 - -/obj/item/clothing/glasses/meson/aviator - name = "engineering aviators" - icon_state = "aviator_eng" - off_state = "aviator" - item_state_slots = list(slot_r_hand_str = "sunglasses", slot_l_hand_str = "sunglasses") - action_button_name = "Toggle HUD" - activation_sound = 'sound/effects/pop.ogg' - -/obj/item/clothing/glasses/meson/aviator/prescription - name = "prescription engineering aviators" - desc = "Engineering Aviators with prescription lenses." - prescription = 1 - -/obj/item/clothing/glasses/hud/health/aviator - name = "medical HUD aviators" - desc = "Modified aviator glasses with a toggled health HUD." - icon_state = "aviator_med" - off_state = "aviator" - action_button_name = "Toggle Mode" - toggleable = 1 - activation_sound = 'sound/effects/pop.ogg' - -/obj/item/clothing/glasses/hud/health/aviator/prescription - name = "prescription medical HUD aviators" - desc = "Modified aviator glasses with a toggled health HUD. Comes with bonus prescription lenses." - prescription = 6 - -/obj/item/clothing/glasses/science - name = "Science Goggles" - desc = "The goggles do nothing!" - icon_state = "purple" - item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses") - toggleable = 1 - action_button_name = "Toggle Goggles" - item_flags = AIRTIGHT - -/obj/item/clothing/glasses/science/New() - ..() - overlay = global_hud.science - -/obj/item/clothing/glasses/goggles - name = "goggles" - desc = "Just some plain old goggles." - icon_state = "plaingoggles" - item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses") - item_flags = AIRTIGHT - body_parts_covered = EYES - -/obj/item/clothing/glasses/night - name = "night vision goggles" - desc = "You can totally see in the dark now!" - icon_state = "night" - item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses") - origin_tech = list(TECH_MAGNET = 2) - darkness_view = 7 - toggleable = 1 - action_button_name = "Toggle Goggles" - off_state = "denight" - flash_protection = FLASH_PROTECTION_REDUCED - enables_planes = list(VIS_FULLBRIGHT) - -/obj/item/clothing/glasses/night/vox - name = "Alien Optics" - species_restricted = list("Vox") - flags = PHORONGUARD - -/obj/item/clothing/glasses/night/New() - ..() - overlay = global_hud.nvg - -/obj/item/clothing/glasses/eyepatch - name = "eyepatch" - desc = "Yarr." - icon_state = "eyepatch" - item_state_slots = list(slot_r_hand_str = "blindfold", slot_l_hand_str = "blindfold") - body_parts_covered = 0 - var/eye = null - -/obj/item/clothing/glasses/eyepatch/verb/switcheye() - set name = "Switch Eyepatch" - set category = "Object" - set src in usr - if(!istype(usr, /mob/living)) return - if(usr.stat) return - - eye = !eye - if(eye) - icon_state = "[icon_state]_1" - else - icon_state = initial(icon_state) - update_clothing_icon() - -/obj/item/clothing/glasses/monocle - name = "monocle" - desc = "Such a dapper eyepiece!" - icon_state = "monocle" - item_state_slots = list(slot_r_hand_str = "headset", slot_l_hand_str = "headset") - body_parts_covered = 0 - -/obj/item/clothing/glasses/material - name = "optical material scanner" - desc = "Very confusing glasses." - icon_state = "material" - item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses") - origin_tech = list(TECH_MAGNET = 3, TECH_ENGINEERING = 3) - toggleable = 1 - action_button_name = "Toggle Goggles" - vision_flags = SEE_OBJS - enables_planes = list(VIS_FULLBRIGHT) - -/obj/item/clothing/glasses/material/New() - ..() - overlay = global_hud.material - -/obj/item/clothing/glasses/material/prescription - name = "prescription optical material scanner" - prescription = 1 - -/obj/item/clothing/glasses/regular - name = "prescription glasses" - desc = "Made by Nerd. Co." - icon_state = "glasses" - item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses") - prescription = 1 - body_parts_covered = 0 - -/obj/item/clothing/glasses/regular/scanners - name = "scanning goggles" - desc = "A very oddly shaped pair of goggles with bits of wire poking out the sides. A soft humming sound emanates from it." - icon_state = "uzenwa_sissra_1" - -/obj/item/clothing/glasses/regular/hipster - name = "prescription glasses" - desc = "Made by Uncool. Co." - icon_state = "hipster_glasses" - -/obj/item/clothing/glasses/threedglasses - desc = "A long time ago, people used these glasses to makes images from screens threedimensional." - name = "3D glasses" - icon_state = "3d" - item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses") - body_parts_covered = 0 - -/obj/item/clothing/glasses/gglasses - name = "green glasses" - desc = "Forest green glasses, like the kind you'd wear when hatching a nasty scheme." - icon_state = "gglasses" - item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses") - body_parts_covered = 0 - -/obj/item/clothing/glasses/sunglasses - name = "sunglasses" - desc = "Strangely ancient technology used to help provide rudimentary eye cover. Enhanced shielding blocks many flashes." - icon_state = "sun" - item_state_slots = list(slot_r_hand_str = "sunglasses", slot_l_hand_str = "sunglasses") - darkness_view = -1 - flash_protection = FLASH_PROTECTION_MODERATE - -/obj/item/clothing/glasses/sunglasses/aviator - name = "aviators" - desc = "A pair of designer sunglasses." - icon_state = "aviator" - -/obj/item/clothing/glasses/welding - name = "welding goggles" - desc = "Protects the eyes from welders, approved by the mad scientist association." - icon_state = "welding-g" - item_state_slots = list(slot_r_hand_str = "welding-g", slot_l_hand_str = "welding-g") - action_button_name = "Flip Welding Goggles" - matter = list(DEFAULT_WALL_MATERIAL = 1500, "glass" = 1000) - item_flags = AIRTIGHT - var/up = 0 - flash_protection = FLASH_PROTECTION_MAJOR - tint = TINT_HEAVY - -/obj/item/clothing/glasses/welding/attack_self() - toggle() - -/obj/item/clothing/glasses/welding/verb/toggle() - set category = "Object" - set name = "Adjust welding goggles" - set src in usr - - if(usr.canmove && !usr.stat && !usr.restrained()) - if(src.up) - src.up = !src.up - flags_inv |= HIDEEYES - body_parts_covered |= EYES - icon_state = initial(icon_state) - flash_protection = initial(flash_protection) - tint = initial(tint) - to_chat(usr, "You flip \the [src] down to protect your eyes.") - else - src.up = !src.up - flags_inv &= ~HIDEEYES - body_parts_covered &= ~EYES - icon_state = "[initial(icon_state)]up" - flash_protection = FLASH_PROTECTION_NONE - tint = TINT_NONE - to_chat(usr, "You push \the [src] up out of your face.") - update_clothing_icon() - usr.update_action_buttons() - -/obj/item/clothing/glasses/welding/superior - name = "superior welding goggles" - desc = "Welding goggles made from more expensive materials, strangely smells like potatoes." - icon_state = "rwelding-g" - tint = TINT_MODERATE - -/obj/item/clothing/glasses/sunglasses/blindfold - name = "blindfold" - desc = "Covers the eyes, preventing sight." - icon_state = "blindfold" - item_state_slots = list(slot_r_hand_str = "blindfold", slot_l_hand_str = "blindfold") - flash_protection = FLASH_PROTECTION_MAJOR - tint = BLIND - -/obj/item/clothing/glasses/sunglasses/blindfold/tape - name = "length of tape" - desc = "It's a robust DIY blindfold!" - icon = 'icons/obj/bureaucracy.dmi' - icon_state = "tape_cross" - item_state_slots = list(slot_r_hand_str = null, slot_l_hand_str = null) - w_class = ITEMSIZE_TINY - -/obj/item/clothing/glasses/sunglasses/prescription - name = "prescription sunglasses" - prescription = 1 - -/obj/item/clothing/glasses/sunglasses/big - desc = "Strangely ancient technology used to help provide rudimentary eye cover. Larger than average enhanced shielding blocks many flashes." - icon_state = "bigsunglasses" - -/obj/item/clothing/glasses/fakesunglasses //Sunglasses without flash immunity - name = "stylish sunglasses" - desc = "A pair of designer sunglasses. Doesn't seem like it'll block flashes." - icon_state = "sun" - item_state_slots = list(slot_r_hand_str = "sunglasses", slot_l_hand_str = "sunglasses") - -/obj/item/clothing/glasses/fakesunglasses/aviator - name = "stylish aviators" - desc = "A pair of designer sunglasses. Doesn't seem like it'll block flashes." - icon_state = "aviator" - -/obj/item/clothing/glasses/sunglasses/sechud - name = "\improper HUD sunglasses" - desc = "Sunglasses with a HUD." - icon_state = "sunSecHud" - enables_planes = list(VIS_CH_ID,VIS_CH_WANTED,VIS_CH_IMPTRACK,VIS_CH_IMPLOYAL,VIS_CH_IMPCHEM) - -/obj/item/clothing/glasses/sunglasses/sechud/tactical - name = "tactical HUD" - desc = "Flash-resistant goggles with inbuilt combat and security information." - icon_state = "swatgoggles" - -/obj/item/clothing/glasses/sunglasses/sechud/aviator - name = "security HUD aviators" - desc = "Modified aviator glasses that can be switch between HUD and flash protection modes." - icon_state = "aviator_sec" - off_state = "aviator" - action_button_name = "Toggle Mode" - var/on = 1 - toggleable = 1 - activation_sound = 'sound/effects/pop.ogg' - -/obj/item/clothing/glasses/sunglasses/sechud/aviator/attack_self(mob/user) - if(toggleable && !user.incapacitated()) - on = !on - if(on) - flash_protection = FLASH_PROTECTION_NONE - enables_planes = away_planes - away_planes = null - to_chat(usr, "You switch the [src] to HUD mode.") - else - flash_protection = initial(flash_protection) - away_planes = enables_planes - enables_planes = null - to_chat(usr, "You switch \the [src] to flash protection mode.") - update_icon() - user << activation_sound - user.recalculate_vis() - user.update_inv_glasses() - user.update_action_buttons() - -/obj/item/clothing/glasses/sunglasses/sechud/aviator/update_icon() - if(on) - icon_state = initial(icon_state) - else - icon_state = off_state - -/obj/item/clothing/glasses/sunglasses/sechud/aviator/prescription - name = "prescription security HUD aviators" - desc = "Modified aviator glasses that can be switch between HUD and flash protection modes. Comes with bonus prescription lenses." - prescription = 6 - -/obj/item/clothing/glasses/sunglasses/medhud - name = "\improper HUD sunglasses" - desc = "Sunglasses with a HUD." - icon_state = "sunMedHud" - enables_planes = list(VIS_CH_STATUS,VIS_CH_HEALTH) - -/obj/item/clothing/glasses/thermal - name = "optical thermal scanner" - desc = "Thermals in the shape of glasses." - icon_state = "thermal" - item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses") - origin_tech = list(TECH_MAGNET = 3) - toggleable = 1 - action_button_name = "Toggle Goggles" - vision_flags = SEE_MOBS - enables_planes = list(VIS_FULLBRIGHT) - flash_protection = FLASH_PROTECTION_REDUCED - - emp_act(severity) - if(istype(src.loc, /mob/living/carbon/human)) - var/mob/living/carbon/human/M = src.loc - M << "The Optical Thermal Scanner overloads and blinds you!" - if(M.glasses == src) - M.Blind(3) - M.eye_blurry = 5 - // Don't cure being nearsighted - if(!(M.disabilities & NEARSIGHTED)) - M.disabilities |= NEARSIGHTED - spawn(100) - M.disabilities &= ~NEARSIGHTED - ..() - -/obj/item/clothing/glasses/thermal/New() - ..() - overlay = global_hud.thermal - -/obj/item/clothing/glasses/thermal/syndi //These are now a traitor item, concealed as mesons. -Pete - name = "optical meson scanner" - desc = "Used for seeing walls, floors, and stuff through anything." - icon_state = "meson" - item_state_slots = list(slot_r_hand_str = "meson", slot_l_hand_str = "meson") - origin_tech = list(TECH_MAGNET = 3, TECH_ILLEGAL = 4) - -/obj/item/clothing/glasses/thermal/plain - toggleable = 0 - activation_sound = null - action_button_name = null - -/obj/item/clothing/glasses/thermal/plain/monocle - name = "thermonocle" - desc = "A monocle thermal." - icon_state = "thermoncle" - item_state_slots = list(slot_r_hand_str = "sunglasses", slot_l_hand_str = "sunglasses") - toggleable = 1 - action_button_name = "Toggle Monocle" - flags = null //doesn't protect eyes because it's a monocle, duh - - body_parts_covered = 0 - -/obj/item/clothing/glasses/thermal/plain/eyepatch - name = "optical thermal eyepatch" - desc = "An eyepatch with built-in thermal optics" - icon_state = "eyepatch" - item_state_slots = list(slot_r_hand_str = "blindfold", slot_l_hand_str = "blindfold") - body_parts_covered = 0 - toggleable = 1 - action_button_name = "Toggle Eyepatch" - -/obj/item/clothing/glasses/thermal/plain/jensen - name = "optical thermal implants" - desc = "A set of implantable lenses designed to augment your vision" - icon_state = "thermalimplants" - item_state_slots = list(slot_r_hand_str = "sunglasses", slot_l_hand_str = "sunglasses") +/////////////////////////////////////////////////////////////////////// +//Glasses +/* +SEE_SELF // can see self, no matter what +SEE_MOBS // can see all mobs, no matter what +SEE_OBJS // can see all objs, no matter what +SEE_TURFS // can see all turfs (and areas), no matter what +SEE_PIXELS// if an object is located on an unlit area, but some of its pixels are + // in a lit area (via pixel_x,y or smooth movement), can see those pixels +BLIND // can't see anything +*/ +/////////////////////////////////////////////////////////////////////// + +/obj/item/clothing/glasses + name = "glasses" + icon = 'icons/obj/clothing/glasses.dmi' + w_class = ITEMSIZE_SMALL + slot_flags = SLOT_EYES + plane_slots = list(slot_glasses) + var/vision_flags = 0 + var/darkness_view = 0//Base human is 2 + var/see_invisible = -1 + var/prescription = 0 + var/toggleable = 0 + var/off_state = "degoggles" + var/active = 1 + var/activation_sound = 'sound/items/goggles_charge.ogg' + var/obj/screen/overlay = null + var/list/away_planes //Holder for disabled planes + + sprite_sheets = list( + "Teshari" = 'icons/mob/species/seromi/eyes.dmi', + "Vox" = 'icons/mob/species/vox/eyes.dmi' + ) + +/obj/item/clothing/glasses/update_clothing_icon() + if (ismob(src.loc)) + var/mob/M = src.loc + M.update_inv_glasses() + +/obj/item/clothing/glasses/attack_self(mob/user) + if(toggleable) + if(active) + active = 0 + icon_state = off_state + user.update_inv_glasses() + flash_protection = FLASH_PROTECTION_NONE + tint = TINT_NONE + away_planes = enables_planes + enables_planes = null + to_chat(usr, "You deactivate the optical matrix on the [src].") + else + active = 1 + icon_state = initial(icon_state) + user.update_inv_glasses() + flash_protection = initial(flash_protection) + tint = initial(tint) + enables_planes = away_planes + away_planes = null + to_chat(usr, "You activate the optical matrix on the [src].") + user.update_action_buttons() + user.recalculate_vis() + ..() + +/obj/item/clothing/glasses/meson + name = "optical meson scanner" + desc = "Used for seeing walls, floors, and stuff through anything." + icon_state = "meson" + item_state_slots = list(slot_r_hand_str = "meson", slot_l_hand_str = "meson") + action_button_name = "Toggle Goggles" + origin_tech = list(TECH_MAGNET = 2, TECH_ENGINEERING = 2) + toggleable = 1 + vision_flags = SEE_TURFS + enables_planes = list(VIS_FULLBRIGHT, VIS_MESONS) + +/obj/item/clothing/glasses/meson/New() + ..() + overlay = global_hud.meson + +/obj/item/clothing/glasses/meson/prescription + name = "prescription mesons" + desc = "Optical Meson Scanner with prescription lenses." + prescription = 1 + +/obj/item/clothing/glasses/meson/aviator + name = "engineering aviators" + icon_state = "aviator_eng" + off_state = "aviator" + item_state_slots = list(slot_r_hand_str = "sunglasses", slot_l_hand_str = "sunglasses") + action_button_name = "Toggle HUD" + activation_sound = 'sound/effects/pop.ogg' + +/obj/item/clothing/glasses/meson/aviator/prescription + name = "prescription engineering aviators" + desc = "Engineering Aviators with prescription lenses." + prescription = 1 + +/obj/item/clothing/glasses/hud/health/aviator + name = "medical HUD aviators" + desc = "Modified aviator glasses with a toggled health HUD." + icon_state = "aviator_med" + off_state = "aviator" + action_button_name = "Toggle Mode" + toggleable = 1 + activation_sound = 'sound/effects/pop.ogg' + +/obj/item/clothing/glasses/hud/health/aviator/prescription + name = "prescription medical HUD aviators" + desc = "Modified aviator glasses with a toggled health HUD. Comes with bonus prescription lenses." + prescription = 6 + +/obj/item/clothing/glasses/science + name = "Science Goggles" + desc = "The goggles do nothing!" + icon_state = "purple" + item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses") + toggleable = 1 + action_button_name = "Toggle Goggles" + item_flags = AIRTIGHT + +/obj/item/clothing/glasses/science/New() + ..() + overlay = global_hud.science + +/obj/item/clothing/glasses/goggles + name = "goggles" + desc = "Just some plain old goggles." + icon_state = "plaingoggles" + item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses") + item_flags = AIRTIGHT + body_parts_covered = EYES + +/obj/item/clothing/glasses/night + name = "night vision goggles" + desc = "You can totally see in the dark now!" + icon_state = "night" + item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses") + origin_tech = list(TECH_MAGNET = 2) + darkness_view = 7 + toggleable = 1 + action_button_name = "Toggle Goggles" + off_state = "denight" + flash_protection = FLASH_PROTECTION_REDUCED + enables_planes = list(VIS_FULLBRIGHT) + +/obj/item/clothing/glasses/night/vox + name = "Alien Optics" + species_restricted = list("Vox") + flags = PHORONGUARD + +/obj/item/clothing/glasses/night/New() + ..() + overlay = global_hud.nvg + +/obj/item/clothing/glasses/eyepatch + name = "eyepatch" + desc = "Yarr." + icon_state = "eyepatch" + item_state_slots = list(slot_r_hand_str = "blindfold", slot_l_hand_str = "blindfold") + body_parts_covered = 0 + var/eye = null + +/obj/item/clothing/glasses/eyepatch/verb/switcheye() + set name = "Switch Eyepatch" + set category = "Object" + set src in usr + if(!istype(usr, /mob/living)) return + if(usr.stat) return + + eye = !eye + if(eye) + icon_state = "[icon_state]_1" + else + icon_state = initial(icon_state) + update_clothing_icon() + +/obj/item/clothing/glasses/monocle + name = "monocle" + desc = "Such a dapper eyepiece!" + icon_state = "monocle" + item_state_slots = list(slot_r_hand_str = "headset", slot_l_hand_str = "headset") + body_parts_covered = 0 + +/obj/item/clothing/glasses/material + name = "optical material scanner" + desc = "Very confusing glasses." + icon_state = "material" + item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses") + origin_tech = list(TECH_MAGNET = 3, TECH_ENGINEERING = 3) + toggleable = 1 + action_button_name = "Toggle Goggles" + vision_flags = SEE_OBJS + enables_planes = list(VIS_FULLBRIGHT) + +/obj/item/clothing/glasses/material/New() + ..() + overlay = global_hud.material + +/obj/item/clothing/glasses/material/prescription + name = "prescription optical material scanner" + prescription = 1 + +/obj/item/clothing/glasses/regular + name = "prescription glasses" + desc = "Made by Nerd. Co." + icon_state = "glasses" + item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses") + prescription = 1 + body_parts_covered = 0 + +/obj/item/clothing/glasses/regular/scanners + name = "scanning goggles" + desc = "A very oddly shaped pair of goggles with bits of wire poking out the sides. A soft humming sound emanates from it." + icon_state = "uzenwa_sissra_1" + +/obj/item/clothing/glasses/regular/hipster + name = "prescription glasses" + desc = "Made by Uncool. Co." + icon_state = "hipster_glasses" + +/obj/item/clothing/glasses/threedglasses + desc = "A long time ago, people used these glasses to makes images from screens threedimensional." + name = "3D glasses" + icon_state = "3d" + item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses") + body_parts_covered = 0 + +/obj/item/clothing/glasses/gglasses + name = "green glasses" + desc = "Forest green glasses, like the kind you'd wear when hatching a nasty scheme." + icon_state = "gglasses" + item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses") + body_parts_covered = 0 + +/obj/item/clothing/glasses/regular/rimless + name = "prescription rimless glasses" + desc = "Sleek modern glasses with a single sculpted lens." + icon_state = "glasses_rimless" + prescription = 1 + +/obj/item/clothing/glasses/rimless + name = "rimless glasses" + desc = "Sleek modern glasses with a single sculpted lens." + icon_state = "glasses_rimless" + prescription = 0 + +/obj/item/clothing/glasses/regular/thin + name = "prescription thin-rimmed glasses" + desc = "Glasses with frames are so last century." + icon_state = "glasses_thin" + prescription = 1 + +/obj/item/clothing/glasses/thin + name = "thin-rimmed glasses" + desc = "Glasses with frames are so last century." + icon_state = "glasses_thin" + prescription = 0 + + +/obj/item/clothing/glasses/sunglasses + name = "sunglasses" + desc = "Strangely ancient technology used to help provide rudimentary eye cover. Enhanced shielding blocks many flashes." + icon_state = "sun" + item_state_slots = list(slot_r_hand_str = "sunglasses", slot_l_hand_str = "sunglasses") + darkness_view = -1 + flash_protection = FLASH_PROTECTION_MODERATE + +/obj/item/clothing/glasses/sunglasses/aviator + name = "aviators" + desc = "A pair of designer sunglasses." + icon_state = "aviator" + +/obj/item/clothing/glasses/welding + name = "welding goggles" + desc = "Protects the eyes from welders, approved by the mad scientist association." + icon_state = "welding-g" + item_state_slots = list(slot_r_hand_str = "welding-g", slot_l_hand_str = "welding-g") + action_button_name = "Flip Welding Goggles" + matter = list(DEFAULT_WALL_MATERIAL = 1500, "glass" = 1000) + item_flags = AIRTIGHT + var/up = 0 + flash_protection = FLASH_PROTECTION_MAJOR + tint = TINT_HEAVY + +/obj/item/clothing/glasses/welding/attack_self() + toggle() + +/obj/item/clothing/glasses/welding/verb/toggle() + set category = "Object" + set name = "Adjust welding goggles" + set src in usr + + if(usr.canmove && !usr.stat && !usr.restrained()) + if(src.up) + src.up = !src.up + flags_inv |= HIDEEYES + body_parts_covered |= EYES + icon_state = initial(icon_state) + flash_protection = initial(flash_protection) + tint = initial(tint) + to_chat(usr, "You flip \the [src] down to protect your eyes.") + else + src.up = !src.up + flags_inv &= ~HIDEEYES + body_parts_covered &= ~EYES + icon_state = "[initial(icon_state)]up" + flash_protection = FLASH_PROTECTION_NONE + tint = TINT_NONE + to_chat(usr, "You push \the [src] up out of your face.") + update_clothing_icon() + usr.update_action_buttons() + +/obj/item/clothing/glasses/welding/superior + name = "superior welding goggles" + desc = "Welding goggles made from more expensive materials, strangely smells like potatoes." + icon_state = "rwelding-g" + tint = TINT_MODERATE + +/obj/item/clothing/glasses/sunglasses/blindfold + name = "blindfold" + desc = "Covers the eyes, preventing sight." + icon_state = "blindfold" + item_state_slots = list(slot_r_hand_str = "blindfold", slot_l_hand_str = "blindfold") + flash_protection = FLASH_PROTECTION_MAJOR + tint = BLIND + +/obj/item/clothing/glasses/sunglasses/blindfold/tape + name = "length of tape" + desc = "It's a robust DIY blindfold!" + icon = 'icons/obj/bureaucracy.dmi' + icon_state = "tape_cross" + item_state_slots = list(slot_r_hand_str = null, slot_l_hand_str = null) + w_class = ITEMSIZE_TINY + +/obj/item/clothing/glasses/sunglasses/prescription + name = "prescription sunglasses" + prescription = 1 + +/obj/item/clothing/glasses/sunglasses/big + desc = "Strangely ancient technology used to help provide rudimentary eye cover. Larger than average enhanced shielding blocks many flashes." + icon_state = "bigsunglasses" + +/obj/item/clothing/glasses/fakesunglasses //Sunglasses without flash immunity + name = "stylish sunglasses" + desc = "A pair of designer sunglasses. Doesn't seem like it'll block flashes." + icon_state = "sun" + item_state_slots = list(slot_r_hand_str = "sunglasses", slot_l_hand_str = "sunglasses") + +/obj/item/clothing/glasses/fakesunglasses/aviator + name = "stylish aviators" + desc = "A pair of designer sunglasses. Doesn't seem like it'll block flashes." + icon_state = "aviator" + +/obj/item/clothing/glasses/sunglasses/sechud + name = "\improper HUD sunglasses" + desc = "Sunglasses with a HUD." + icon_state = "sunSecHud" + enables_planes = list(VIS_CH_ID,VIS_CH_WANTED,VIS_CH_IMPTRACK,VIS_CH_IMPLOYAL,VIS_CH_IMPCHEM) + +/obj/item/clothing/glasses/sunglasses/sechud/tactical + name = "tactical HUD" + desc = "Flash-resistant goggles with inbuilt combat and security information." + icon_state = "swatgoggles" + +/obj/item/clothing/glasses/sunglasses/sechud/aviator + name = "security HUD aviators" + desc = "Modified aviator glasses that can be switch between HUD and flash protection modes." + icon_state = "aviator_sec" + off_state = "aviator" + action_button_name = "Toggle Mode" + var/on = 1 + toggleable = 1 + activation_sound = 'sound/effects/pop.ogg' + +/obj/item/clothing/glasses/sunglasses/sechud/aviator/attack_self(mob/user) + if(toggleable && !user.incapacitated()) + on = !on + if(on) + flash_protection = FLASH_PROTECTION_NONE + enables_planes = away_planes + away_planes = null + to_chat(usr, "You switch the [src] to HUD mode.") + else + flash_protection = initial(flash_protection) + away_planes = enables_planes + enables_planes = null + to_chat(usr, "You switch \the [src] to flash protection mode.") + update_icon() + user << activation_sound + user.recalculate_vis() + user.update_inv_glasses() + user.update_action_buttons() + +/obj/item/clothing/glasses/sunglasses/sechud/aviator/update_icon() + if(on) + icon_state = initial(icon_state) + else + icon_state = off_state + +/obj/item/clothing/glasses/sunglasses/sechud/aviator/prescription + name = "prescription security HUD aviators" + desc = "Modified aviator glasses that can be switch between HUD and flash protection modes. Comes with bonus prescription lenses." + prescription = 6 + +/obj/item/clothing/glasses/sunglasses/medhud + name = "\improper HUD sunglasses" + desc = "Sunglasses with a HUD." + icon_state = "sunMedHud" + enables_planes = list(VIS_CH_STATUS,VIS_CH_HEALTH) + +/obj/item/clothing/glasses/thermal + name = "optical thermal scanner" + desc = "Thermals in the shape of glasses." + icon_state = "thermal" + item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses") + origin_tech = list(TECH_MAGNET = 3) + toggleable = 1 + action_button_name = "Toggle Goggles" + vision_flags = SEE_MOBS + enables_planes = list(VIS_FULLBRIGHT) + flash_protection = FLASH_PROTECTION_REDUCED + + emp_act(severity) + if(istype(src.loc, /mob/living/carbon/human)) + var/mob/living/carbon/human/M = src.loc + M << "The Optical Thermal Scanner overloads and blinds you!" + if(M.glasses == src) + M.Blind(3) + M.eye_blurry = 5 + // Don't cure being nearsighted + if(!(M.disabilities & NEARSIGHTED)) + M.disabilities |= NEARSIGHTED + spawn(100) + M.disabilities &= ~NEARSIGHTED + ..() + +/obj/item/clothing/glasses/thermal/New() + ..() + overlay = global_hud.thermal + +/obj/item/clothing/glasses/thermal/syndi //These are now a traitor item, concealed as mesons. -Pete + name = "optical meson scanner" + desc = "Used for seeing walls, floors, and stuff through anything." + icon_state = "meson" + item_state_slots = list(slot_r_hand_str = "meson", slot_l_hand_str = "meson") + origin_tech = list(TECH_MAGNET = 3, TECH_ILLEGAL = 4) + +/obj/item/clothing/glasses/thermal/plain + toggleable = 0 + activation_sound = null + action_button_name = null + +/obj/item/clothing/glasses/thermal/plain/monocle + name = "thermonocle" + desc = "A monocle thermal." + icon_state = "thermoncle" + item_state_slots = list(slot_r_hand_str = "sunglasses", slot_l_hand_str = "sunglasses") + toggleable = 1 + action_button_name = "Toggle Monocle" + flags = null //doesn't protect eyes because it's a monocle, duh + + body_parts_covered = 0 + +/obj/item/clothing/glasses/thermal/plain/eyepatch + name = "optical thermal eyepatch" + desc = "An eyepatch with built-in thermal optics" + icon_state = "eyepatch" + item_state_slots = list(slot_r_hand_str = "blindfold", slot_l_hand_str = "blindfold") + body_parts_covered = 0 + toggleable = 1 + action_button_name = "Toggle Eyepatch" + +/obj/item/clothing/glasses/thermal/plain/jensen + name = "optical thermal implants" + desc = "A set of implantable lenses designed to augment your vision" + icon_state = "thermalimplants" + item_state_slots = list(slot_r_hand_str = "sunglasses", slot_l_hand_str = "sunglasses") diff --git a/code/modules/clothing/glasses/hud_vr.dm b/code/modules/clothing/glasses/hud_vr.dm index 1863ec3c14..dfdd02c461 100644 --- a/code/modules/clothing/glasses/hud_vr.dm +++ b/code/modules/clothing/glasses/hud_vr.dm @@ -23,7 +23,7 @@ /obj/item/clothing/glasses/omnihud/dropped() if(arscreen) - GLOB.nanomanager.close_uis(src) + SSnanoui.close_uis(src) ..() /obj/item/clothing/glasses/omnihud/emp_act(var/severity) diff --git a/code/modules/clothing/gloves/color.dm b/code/modules/clothing/gloves/color.dm index 1c643f7995..a456e85939 100644 --- a/code/modules/clothing/gloves/color.dm +++ b/code/modules/clothing/gloves/color.dm @@ -12,7 +12,7 @@ siemens_coefficient = 1 //Set to a default of 1, gets overridden in initialize() permeability_coefficient = 0.05 -/obj/item/clothing/gloves/fyellow/initialize() +/obj/item/clothing/gloves/fyellow/Initialize() . = ..() //Picks a value between 0 and 1.25, in 5% increments // VOREStation edit var/shock_pick = rand(0,25) // VOREStation Edit diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm index 287f83e4c4..558f30fbd9 100644 --- a/code/modules/clothing/head/hardhat.dm +++ b/code/modules/clothing/head/hardhat.dm @@ -18,16 +18,19 @@ /obj/item/clothing/head/hardhat/red icon_state = "hardhat0_red" name = "firefighter helmet" - item_flags = STOPPRESSUREDAMAGE heat_protection = HEAD max_heat_protection_temperature = FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE + min_pressure_protection = 0.2* ONE_ATMOSPHERE + max_pressure_protection = 20 * ONE_ATMOSPHERE + /obj/item/clothing/head/hardhat/white icon_state = "hardhat0_white" name = "sleek hard hat" - item_flags = STOPPRESSUREDAMAGE heat_protection = HEAD max_heat_protection_temperature = FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE + min_pressure_protection = 0.2* ONE_ATMOSPHERE + max_pressure_protection = 20 * ONE_ATMOSPHERE /obj/item/clothing/head/hardhat/dblue name = "blue hard hat" diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm index a6d1e9e48a..d044c53406 100644 --- a/code/modules/clothing/head/misc.dm +++ b/code/modules/clothing/head/misc.dm @@ -413,4 +413,17 @@ name = "maid headband" desc = "Keeps hair out of the way for important... jobs." icon_state = "maid" - body_parts_covered = 0 \ No newline at end of file + body_parts_covered = 0 + +/obj/item/clothing/head/maangtikka + name = "maang tikka" + desc = "A jeweled headpiece originating in India." + icon_state = "maangtikka" + body_parts_covered = 0 + +/obj/item/clothing/head/jingasa + name = "jingasa" + desc = "A wide, flat rain hat originally from Japan." + icon_state = "jingasa" + body_parts_covered = 0 + item_state_slots = list(slot_r_hand_str = "taq", slot_l_hand_str = "taq") \ 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 9a2d3868dd..b706e71e9d 100644 --- a/code/modules/clothing/head/misc_special.dm +++ b/code/modules/clothing/head/misc_special.dm @@ -113,7 +113,7 @@ /obj/item/clothing/head/cakehat/process() if(!onfire) - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) return var/turf/location = src.loc @@ -131,7 +131,7 @@ force = 3 damtype = "fire" icon_state = "cake1" - processing_objects.Add(src) + START_PROCESSING(SSobj, src) else force = null damtype = "brute" @@ -237,12 +237,12 @@ /obj/item/clothing/head/psy_crown/equipped(var/mob/living/carbon/human/H) ..() if(istype(H) && H.head == src && H.is_sentient()) - processing_objects += src + START_PROCESSING(SSobj, src) to_chat(H, flavor_equip) /obj/item/clothing/head/psy_crown/dropped(var/mob/living/carbon/human/H) ..() - processing_objects -= src + STOP_PROCESSING(SSobj, src) if(H.is_sentient()) if(loc == H) // Still inhand. to_chat(H, flavor_unequip) @@ -250,7 +250,7 @@ to_chat(H, flavor_drop) /obj/item/clothing/head/psy_crown/Destroy() - processing_objects -= src + STOP_PROCESSING(SSobj, src) return ..() /obj/item/clothing/head/psy_crown/process() diff --git a/code/modules/clothing/head/pilot_helmet.dm b/code/modules/clothing/head/pilot_helmet.dm index feb60ae3a3..ee95c7c937 100644 --- a/code/modules/clothing/head/pilot_helmet.dm +++ b/code/modules/clothing/head/pilot_helmet.dm @@ -23,7 +23,7 @@ var/list/raw_images var/last_status -/obj/item/clothing/head/pilot/initialize() +/obj/item/clothing/head/pilot/Initialize() . = ..() images = list() diff --git a/code/modules/clothing/masks/voice.dm b/code/modules/clothing/masks/voice.dm index 70459e62af..7d214be9c3 100644 --- a/code/modules/clothing/masks/voice.dm +++ b/code/modules/clothing/masks/voice.dm @@ -1,8 +1,8 @@ /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 + var/voice = null //If set and item is present in mask/suit, this name will be used for the wearer's speech. + var/active = TRUE /obj/item/clothing/mask/gas/voice name = "gas mask" @@ -15,7 +15,7 @@ set src in usr changer.active = !changer.active - usr << "You [changer.active ? "enable" : "disable"] the voice-changing module in \the [src]." + to_chat(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" @@ -24,7 +24,14 @@ var/voice = sanitize(name, MAX_NAME_LEN) if(!voice || !length(voice)) return changer.voice = voice - usr << "You are now mimicking [changer.voice]." + to_chat(usr, "You are now mimicking [changer.voice].") + +/obj/item/clothing/mask/gas/voice/verb/Reset_Voice() + set category = "Object" + set src in usr + + changer.voice = null + to_chat(usr, "You have reset your voice changer's mimicry feature.") /obj/item/clothing/mask/gas/voice/New() ..() diff --git a/code/modules/clothing/shoes/boots.dm b/code/modules/clothing/shoes/boots.dm index 0b6b6757dc..dd5e7956df 100644 --- a/code/modules/clothing/shoes/boots.dm +++ b/code/modules/clothing/shoes/boots.dm @@ -114,6 +114,13 @@ icon_state = "explorer" armor = list(melee = 30, bullet = 10, laser = 10, energy = 15, bomb = 20, bio = 0, rad = 0) +// Allows the wearer to climb cliffs, which could allow for shortcuts or sequence-breaking. +/obj/item/clothing/shoes/boots/winter/climbing + name = "climbing winter boots" + desc = "A pair of winter boots, with metal bracing attached to assist in climbing rocky terrain." + icon_state = "climbing_boots" + rock_climbing = TRUE + /obj/item/clothing/shoes/boots/tactical name = "tactical boots" desc = "Tan boots with extra padding and armor." diff --git a/code/modules/clothing/spacesuits/alien.dm b/code/modules/clothing/spacesuits/alien.dm index a5e0b31451..d1ab95b00b 100644 --- a/code/modules/clothing/spacesuits/alien.dm +++ b/code/modules/clothing/spacesuits/alien.dm @@ -32,7 +32,7 @@ /obj/item/clothing/suit/space/vox w_class = ITEMSIZE_NORMAL flags = PHORONGUARD - item_flags = STOPPRESSUREDAMAGE | THICKMATERIAL + item_flags = THICKMATERIAL allowed = list(/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs,/obj/item/weapon/tank) armor = list(melee = 60, bullet = 50, laser = 40,energy = 15, bomb = 30, bio = 100, rad = 50) siemens_coefficient = 0.2 @@ -44,7 +44,7 @@ armor = list(melee = 60, bullet = 50, laser = 40, energy = 15, bomb = 30, bio = 100, rad = 50) siemens_coefficient = 0.2 flags = PHORONGUARD - item_flags = STOPPRESSUREDAMAGE | THICKMATERIAL | AIRTIGHT + item_flags = THICKMATERIAL | AIRTIGHT flags_inv = 0 species_restricted = list(SPECIES_VOX) diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm index 03466eea22..1d449261e7 100644 --- a/code/modules/clothing/spacesuits/miscellaneous.dm +++ b/code/modules/clothing/spacesuits/miscellaneous.dm @@ -3,7 +3,7 @@ name = "space helmet" icon_state = "capspace" desc = "A special helmet designed for work in a hazardous, low-pressure environment. Only for the most fashionable of military figureheads." - item_flags = STOPPRESSUREDAMAGE + item_flags = 0 flags_inv = HIDEFACE|BLOCKHAIR permeability_coefficient = 0.01 armor = list(melee = 65, bullet = 50, laser = 50,energy = 25, bomb = 50, bio = 100, rad = 50) @@ -16,7 +16,7 @@ w_class = ITEMSIZE_HUGE gas_transfer_coefficient = 0.01 permeability_coefficient = 0.02 - item_flags = STOPPRESSUREDAMAGE + item_flags = 0 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_magazine, /obj/item/ammo_casing, /obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs) slowdown = 1.5 @@ -33,7 +33,7 @@ icon_state = "deathsquad" item_state_slots = list(slot_r_hand_str = "syndicate-helm-black-red", slot_l_hand_str = "syndicate-helm-black-red") armor = list(melee = 65, bullet = 55, laser = 35,energy = 20, bomb = 30, bio = 100, rad = 60) - item_flags = STOPPRESSUREDAMAGE | THICKMATERIAL + item_flags = THICKMATERIAL flags_inv = BLOCKHAIR siemens_coefficient = 0.6 @@ -44,7 +44,7 @@ icon_state = "beret_badge" item_state_slots = list(slot_r_hand_str = "beret", slot_l_hand_str = "beret") armor = list(melee = 65, bullet = 55, laser = 35,energy = 20, bomb = 30, bio = 30, rad = 30) - item_flags = STOPPRESSUREDAMAGE + item_flags = 0 flags_inv = BLOCKHAIR siemens_coefficient = 0.9 @@ -53,7 +53,7 @@ name = "Santa's hat" desc = "Ho ho ho. Merrry X-mas!" icon_state = "santahat" - item_flags = STOPPRESSUREDAMAGE + item_flags = 0 flags_inv = BLOCKHAIR body_parts_covered = HEAD @@ -62,7 +62,7 @@ desc = "Festive!" icon_state = "santa" slowdown = 0 - item_flags = STOPPRESSUREDAMAGE + item_flags = 0 allowed = list(/obj/item) //for stuffing exta special presents //Space pirate outfit @@ -71,7 +71,7 @@ desc = "Yarr." icon_state = "pirate" armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30) - item_flags = STOPPRESSUREDAMAGE + item_flags = 0 flags_inv = BLOCKHAIR body_parts_covered = 0 siemens_coefficient = 0.9 diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm index 293e2601cc..a2baa34cf5 100644 --- a/code/modules/clothing/spacesuits/rig/rig.dm +++ b/code/modules/clothing/spacesuits/rig/rig.dm @@ -83,7 +83,9 @@ var/offline_slowdown = 3 // If the suit is deployed and unpowered, it sets slowdown to this. var/vision_restriction var/offline_vision_restriction = 1 // 0 - none, 1 - welder vision, 2 - blind. Maybe move this to helmets. - var/airtight = 1 //If set, will adjust AIRTIGHT and STOPPRESSUREDAMAGE flags on components. Otherwise it should leave them untouched. + var/airtight = 1 //If set, will adjust AIRTIGHT flag and pressure protections on components. Otherwise it should leave them untouched. + var/rigsuit_max_pressure = 10 * ONE_ATMOSPHERE // Max pressure the rig protects against when sealed + var/rigsuit_min_pressure = 0 // Min pressure the rig protects against when sealed var/emp_protection = 0 item_flags = PHORONGUARD //VOREStation add @@ -124,7 +126,7 @@ spark_system.set_up(5, 0, src) spark_system.attach(src) - processing_objects |= src + START_PROCESSING(SSobj, src) if(initial_modules && initial_modules.len) for(var/path in initial_modules) @@ -176,7 +178,7 @@ if(istype(M)) M.drop_from_inventory(piece) qdel(piece) - processing_objects -= src + STOP_PROCESSING(SSobj, src) qdel(wires) wires = null qdel(spark_system) @@ -205,6 +207,21 @@ return 0 return 1 +// Updates pressure protection +// Seal = 1 sets protection +// Seal = 0 unsets protection +/obj/item/weapon/rig/proc/update_airtight(var/obj/item/piece, var/seal = 0) + if(seal == 1) + min_pressure_protection = rigsuit_min_pressure + max_pressure_protection = rigsuit_max_pressure + piece.item_flags |= AIRTIGHT + else + min_pressure_protection = null + max_pressure_protection = null + piece.item_flags &= ~AIRTIGHT + return + + /obj/item/weapon/rig/proc/reset() offline = 2 canremove = 1 @@ -212,7 +229,7 @@ if(!piece) continue piece.icon_state = "[suit_state]" if(airtight) - piece.item_flags &= ~(STOPPRESSUREDAMAGE|AIRTIGHT) + update_airtight(piece, 0) // Unseal update_icon(1) /obj/item/weapon/rig/proc/toggle_seals(var/mob/living/carbon/human/M,var/instant) @@ -340,9 +357,9 @@ /obj/item/weapon/rig/proc/update_component_sealed() for(var/obj/item/piece in list(helmet,boots,gloves,chest)) if(canremove) - piece.item_flags &= ~(STOPPRESSUREDAMAGE|AIRTIGHT) + update_airtight(piece, 0) // Unseal else - piece.item_flags |= (STOPPRESSUREDAMAGE|AIRTIGHT) + update_airtight(piece, 1) // Seal /obj/item/weapon/rig/ui_action_click() toggle_cooling(usr) @@ -418,8 +435,10 @@ var/mob/living/carbon/human/H = loc - var/efficiency = 1 - H.get_pressure_weakness() //you need to have a good seal for effective cooling - var/env_temp = get_environment_temperature() //wont save you from a fire + var/turf/T = get_turf(src) + var/datum/gas_mixture/environment = T.return_air() + var/efficiency = 1 - H.get_pressure_weakness(environment.return_pressure()) // 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.5) //only cools, doesn't heat, also we don't need extreme precision @@ -546,7 +565,7 @@ data["charge"] = cell ? round(cell.charge,1) : 0 data["maxcharge"] = cell ? cell.maxcharge : 0 - data["chargestatus"] = cell ? Floor((cell.charge/cell.maxcharge)*50) : 0 + data["chargestatus"] = cell ? FLOOR((cell.charge/cell.maxcharge)*50, 1) : 0 data["emagged"] = subverted data["coverlock"] = locked @@ -593,7 +612,7 @@ if(module_list.len) data["modules"] = module_list - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, ((src.loc != user) ? ai_interface_path : interface_path), interface_title, 480, 550, state = nano_state) ui.set_initial_data(data) diff --git a/code/modules/clothing/spacesuits/rig/rig_pieces.dm b/code/modules/clothing/spacesuits/rig/rig_pieces.dm index 10cae0c964..0fa9f83f52 100644 --- a/code/modules/clothing/spacesuits/rig/rig_pieces.dm +++ b/code/modules/clothing/spacesuits/rig/rig_pieces.dm @@ -14,7 +14,8 @@ SPECIES_TAJ = 'icons/mob/species/tajaran/helmet.dmi', SPECIES_SKRELL = 'icons/mob/species/skrell/helmet.dmi', SPECIES_UNATHI = 'icons/mob/species/unathi/helmet.dmi', - SPECIES_VOX = 'icons/mob/species/vox/head.dmi' + SPECIES_VOX = 'icons/mob/species/vox/head.dmi', + SPECIES_TESHARI = 'icons/mob/species/seromi/head.dmi' ) species_restricted = null @@ -40,10 +41,10 @@ name = "chestpiece" allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit) body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS - heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS - cold_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS - flags_inv = HIDEJUMPSUIT|HIDETAIL - item_flags = STOPPRESSUREDAMAGE | THICKMATERIAL | AIRTIGHT + heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS + cold_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS + flags_inv = HIDEJUMPSUIT|HIDETAIL + item_flags = THICKMATERIAL | AIRTIGHT slowdown = 0 //will reach 10 breach damage after 25 laser carbine blasts, 3 revolver hits, or ~1 PTR hit. Completely immune to smg or sts hits. breach_threshold = 38 @@ -52,7 +53,8 @@ sprite_sheets = list( SPECIES_TAJ = 'icons/mob/species/tajaran/suit.dmi', SPECIES_UNATHI = 'icons/mob/species/unathi/suit.dmi', - SPECIES_VOX = 'icons/mob/species/vox/suit.dmi' + SPECIES_VOX = 'icons/mob/species/vox/suit.dmi', + SPECIES_TESHARI = 'icons/mob/species/seromi/suit.dmi' ) supporting_limbs = list() var/obj/item/weapon/material/knife/tacknife diff --git a/code/modules/clothing/spacesuits/rig/suits/light.dm b/code/modules/clothing/spacesuits/rig/suits/light.dm index 918e5a3290..5291b73cb8 100644 --- a/code/modules/clothing/spacesuits/rig/suits/light.dm +++ b/code/modules/clothing/spacesuits/rig/suits/light.dm @@ -8,7 +8,7 @@ armor = list(melee = 50, bullet = 15, laser = 50, energy = 10, bomb = 25, bio = 0, rad = 0) emp_protection = 10 slowdown = 0 - item_flags = STOPPRESSUREDAMAGE | THICKMATERIAL + item_flags = THICKMATERIAL offline_slowdown = 0 offline_vision_restriction = 0 @@ -16,6 +16,8 @@ helm_type = /obj/item/clothing/head/helmet/space/rig/light boot_type = /obj/item/clothing/shoes/magboots/rig/light glove_type = /obj/item/clothing/gloves/gauntlets/rig/light + rigsuit_max_pressure = 5 * ONE_ATMOSPHERE // Max pressure the rig protects against when sealed + rigsuit_min_pressure = 0 // Min pressure the rig protects against when sealed /obj/item/clothing/suit/space/rig/light name = "suit" diff --git a/code/modules/clothing/spacesuits/rig/suits/station.dm b/code/modules/clothing/spacesuits/rig/suits/station.dm index b308e99e2d..eda8665fb2 100644 --- a/code/modules/clothing/spacesuits/rig/suits/station.dm +++ b/code/modules/clothing/spacesuits/rig/suits/station.dm @@ -74,6 +74,8 @@ offline_vision_restriction = 2 emp_protection = -20 siemens_coefficient= 0.75 + rigsuit_max_pressure = 15 * ONE_ATMOSPHERE // Max pressure the rig protects against when sealed + rigsuit_min_pressure = 0 // Min pressure the rig protects against when sealed helm_type = /obj/item/clothing/head/helmet/space/rig/industrial @@ -155,6 +157,8 @@ offline_slowdown = 0 offline_vision_restriction = 0 siemens_coefficient= 0.75 + rigsuit_max_pressure = 20 * ONE_ATMOSPHERE // Max pressure the rig protects against when sealed + rigsuit_min_pressure = 0 // Min pressure the rig protects against when sealed helm_type = /obj/item/clothing/head/helmet/space/rig/ce glove_type = /obj/item/clothing/gloves/gauntlets/rig/ce diff --git a/code/modules/clothing/spacesuits/spacesuits.dm b/code/modules/clothing/spacesuits/spacesuits.dm index 400bd96b4b..78f4967779 100644 --- a/code/modules/clothing/spacesuits/spacesuits.dm +++ b/code/modules/clothing/spacesuits/spacesuits.dm @@ -7,13 +7,15 @@ icon_state = "space" desc = "A special helmet designed for work in a hazardous, low-pressure environment." flags = PHORONGUARD - item_flags = STOPPRESSUREDAMAGE | THICKMATERIAL | AIRTIGHT + item_flags = THICKMATERIAL | AIRTIGHT permeability_coefficient = 0.01 armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 50) flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|BLOCKHAIR body_parts_covered = HEAD|FACE|EYES cold_protection = HEAD min_cold_protection_temperature = SPACE_HELMET_MIN_COLD_PROTECTION_TEMPERATURE + min_pressure_protection = 0 * ONE_ATMOSPHERE + max_pressure_protection = 2 * ONE_ATMOSPHERE siemens_coefficient = 0.9 species_restricted = list("exclude",SPECIES_DIONA) preserve_item = 1 @@ -56,7 +58,7 @@ gas_transfer_coefficient = 0.01 permeability_coefficient = 0.02 flags = PHORONGUARD - item_flags = STOPPRESSUREDAMAGE | THICKMATERIAL | PHORONGUARD + item_flags = THICKMATERIAL | PHORONGUARD body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/emergency/oxygen,/obj/item/device/suit_cooling_unit) slowdown = 3 @@ -64,6 +66,8 @@ flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL|HIDETIE|HIDEHOLSTER cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS min_cold_protection_temperature = SPACE_SUIT_MIN_COLD_PROTECTION_TEMPERATURE + min_pressure_protection = 0 * ONE_ATMOSPHERE + max_pressure_protection = 2 * ONE_ATMOSPHERE siemens_coefficient = 0.9 species_restricted = list("exclude",SPECIES_DIONA) preserve_item = 1 diff --git a/code/modules/clothing/spacesuits/void/station.dm b/code/modules/clothing/spacesuits/void/station.dm index 7a0af9c9d8..2168fbb1b5 100644 --- a/code/modules/clothing/spacesuits/void/station.dm +++ b/code/modules/clothing/spacesuits/void/station.dm @@ -6,6 +6,8 @@ icon_state = "rig0-engineering" item_state_slots = list(slot_r_hand_str = "eng_helm", slot_l_hand_str = "eng_helm") armor = list(melee = 40, bullet = 5, laser = 20, energy = 5, bomb = 35, bio = 100, rad = 80) + min_pressure_protection = 0 * ONE_ATMOSPHERE + max_pressure_protection = 15 * ONE_ATMOSPHERE /obj/item/clothing/suit/space/void/engineering name = "engineering voidsuit" @@ -15,6 +17,8 @@ slowdown = 1 armor = list(melee = 40, bullet = 5, laser = 20, energy = 5, bomb = 35, bio = 100, rad = 80) allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/bag/ore,/obj/item/device/t_scanner,/obj/item/weapon/pickaxe, /obj/item/weapon/rcd) + min_pressure_protection = 0 * ONE_ATMOSPHERE + max_pressure_protection = 15 * ONE_ATMOSPHERE //Engineering HAZMAT Voidsuit @@ -219,6 +223,8 @@ armor = list(melee = 40, bullet = 5, laser = 20, energy = 5, bomb = 35, bio = 100, rad = 50) max_heat_protection_temperature = FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE light_overlay = "helmet_light_dual" + min_pressure_protection = 0 * ONE_ATMOSPHERE + max_pressure_protection = 20* ONE_ATMOSPHERE /obj/item/clothing/suit/space/void/atmos name = "atmos voidsuit" @@ -227,6 +233,8 @@ item_state_slots = list(slot_r_hand_str = "atmos_voidsuit", slot_l_hand_str = "atmos_voidsuit") armor = list(melee = 40, bullet = 5, laser = 20, energy = 5, bomb = 35, bio = 100, rad = 50) max_heat_protection_temperature = FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE + min_pressure_protection = 0 * ONE_ATMOSPHERE + max_pressure_protection = 20* ONE_ATMOSPHERE //Atmospherics Surplus Voidsuit diff --git a/code/modules/clothing/spacesuits/void/void.dm b/code/modules/clothing/spacesuits/void/void.dm index d755540b91..4dd21ad3bb 100644 --- a/code/modules/clothing/spacesuits/void/void.dm +++ b/code/modules/clothing/spacesuits/void/void.dm @@ -7,6 +7,8 @@ heat_protection = HEAD armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 20) max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE + min_pressure_protection = 0 * ONE_ATMOSPHERE + max_pressure_protection = 10 * ONE_ATMOSPHERE // flags_inv = HIDEEARS|BLOCKHAIR @@ -37,6 +39,8 @@ allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit) heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE + min_pressure_protection = 0 * ONE_ATMOSPHERE + max_pressure_protection = 10 * ONE_ATMOSPHERE species_restricted = list("Human", SPECIES_SKRELL, "Promethean") sprite_sheets_refit = list( diff --git a/code/modules/clothing/spacesuits/void/void_vr.dm b/code/modules/clothing/spacesuits/void/void_vr.dm index b0842df24f..4b15e28795 100644 --- a/code/modules/clothing/spacesuits/void/void_vr.dm +++ b/code/modules/clothing/spacesuits/void/void_vr.dm @@ -94,7 +94,7 @@ SPECIES_ZORREN_FLAT, SPECIES_ZORREN_HIGH ) -/obj/item/clothing/suit/space/void/explorer/initialize() +/obj/item/clothing/suit/space/void/explorer/Initialize() . = ..() sprite_sheets += sprite_sheets_refit @@ -118,6 +118,6 @@ SPECIES_ZORREN_FLAT, SPECIES_ZORREN_HIGH ) -/obj/item/clothing/head/helmet/space/void/explorer/initialize() +/obj/item/clothing/head/helmet/space/void/explorer/Initialize() . = ..() sprite_sheets += sprite_sheets_refit diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index eb1a04a2e0..db33ec9662 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -126,7 +126,7 @@ item_state_slots = list(slot_r_hand_str = "swat", slot_l_hand_str = "swat") gas_transfer_coefficient = 0.01 permeability_coefficient = 0.01 - item_flags = STOPPRESSUREDAMAGE | THICKMATERIAL + item_flags = THICKMATERIAL body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS allowed = list(/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/tank/emergency/oxygen,/obj/item/clothing/head/helmet) slowdown = 1 @@ -135,6 +135,8 @@ flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETIE|HIDEHOLSTER cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS min_cold_protection_temperature = SPACE_SUIT_MIN_COLD_PROTECTION_TEMPERATURE + min_pressure_protection = 0 * ONE_ATMOSPHERE + max_pressure_protection = 20* ONE_ATMOSPHERE siemens_coefficient = 0.6 diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm index eeca9d220b..87365674b4 100644 --- a/code/modules/clothing/suits/miscellaneous.dm +++ b/code/modules/clothing/suits/miscellaneous.dm @@ -224,6 +224,8 @@ body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL|HIDETIE|HIDEHOLSTER + var/resist_time = 4800 // Eight minutes. + /obj/item/clothing/suit/straight_jacket/attack_hand(mob/living/user as mob) if(ishuman(user)) var/mob/living/carbon/human/H = user @@ -255,6 +257,11 @@ obj/item/clothing/suit/kimono icon_state = "kimono" addblends = "kimono_a" +obj/item/clothing/suit/kamishimo + name = "kamishimo" + desc = "Traditional Japanese menswear." + icon_state = "kamishimo" + /* * coats */ diff --git a/code/modules/clothing/suits/utility.dm b/code/modules/clothing/suits/utility.dm index 2dbda7a615..0ecbe0390d 100644 --- a/code/modules/clothing/suits/utility.dm +++ b/code/modules/clothing/suits/utility.dm @@ -20,10 +20,13 @@ 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|HIDETIE|HIDEHOLSTER - item_flags = STOPPRESSUREDAMAGE + item_flags = 0 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 + min_pressure_protection = 0.2 * ONE_ATMOSPHERE + max_pressure_protection = 20 * ONE_ATMOSPHERE + /obj/item/clothing/suit/fire/firefighter icon_state = "firesuit" diff --git a/code/modules/clothing/under/accessories/accessory_vr.dm b/code/modules/clothing/under/accessories/accessory_vr.dm index 25148b8813..8b03a76ff7 100644 --- a/code/modules/clothing/under/accessories/accessory_vr.dm +++ b/code/modules/clothing/under/accessories/accessory_vr.dm @@ -40,9 +40,12 @@ if(!jingled) usr.audible_message("[usr] jingles the [src]'s bell.") jingled = 1 - schedule_callback_in(5 SECONDS, VARSET_CALLBACK(src, jingled, 0)) + addtimer(CALLBACK(src, .proc/jingledreset), 50) return +/obj/item/clothing/accessory/collar/bell/proc/jingledreset() + jingled = 0 + /obj/item/clothing/accessory/collar/shock name = "Shock collar" desc = "A collar used to ease hungry predators." @@ -178,6 +181,8 @@ icon_state = "collar_holo" item_state = "collar_holo_overlay" overlay_state = "collar_holo_overlay" + matter = list(DEFAULT_WALL_MATERIAL = 50) + /obj/item/clothing/accessory/collar/attack_self(mob/user as mob) if(istype(src,/obj/item/clothing/accessory/collar/holo)) diff --git a/code/modules/clothing/under/accessories/clothing.dm b/code/modules/clothing/under/accessories/clothing.dm index 065aedb6ac..29057e8469 100644 --- a/code/modules/clothing/under/accessories/clothing.dm +++ b/code/modules/clothing/under/accessories/clothing.dm @@ -30,7 +30,6 @@ desc = "Lucky suit jacket." icon_state = "checkered_jacket" - /obj/item/clothing/accessory/chaps name = "brown chaps" desc = "A pair of loose, brown leather chaps." @@ -342,3 +341,23 @@ name = "Christmas turtleneck" desc = "A really cheesy holiday sweater, it actually kinda itches." icon_state = "turtleneck_winterred" + +/obj/item/clothing/accessory/cowledvest + name = "cowled vest" + desc = "A body warmer for the 26th century." + icon_state = "cowled_vest" + +/obj/item/clothing/accessory/asymmetric + name = "blue asymmetrical jacket" + desc = "Insultingly avant-garde in prussian blue." + icon_state = "asym_blue" + +/obj/item/clothing/accessory/asymmetric/purple + name = "purple asymmetrical jacket" + desc = "Insultingly avant-garde in mauve." + icon_state = "asym_purple" + +/obj/item/clothing/accessory/asymmetric/green + name = "green asymmetrical jacket" + desc = "Insultingly avant-garde in aqua." + icon_state = "asym_green" \ No newline at end of file diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 07b0f12609..c61a707073 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -242,6 +242,11 @@ icon_state = "overalls" item_state_slots = list(slot_r_hand_str = "cargo", slot_l_hand_str = "cargo") +/obj/item/clothing/under/overalls/sleek + name = "sleek overalls" + desc = "A set of modern pleather reinforced overalls." + icon_state = "overalls_sleek" + /obj/item/clothing/under/pirate name = "pirate outfit" desc = "Yarr." @@ -283,6 +288,19 @@ item_state_slots = list(slot_r_hand_str = "yellow", slot_l_hand_str = "yellow") body_parts_covered = LOWER_TORSO +/obj/item/clothing/under/moderncoat + name = "modern wrapped coat" + desc = "The cutting edge of fashion." + icon_state = "moderncoat" + item_state_slots = list(slot_r_hand_str = "red", slot_l_hand_str = "red") + body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS + +/obj/item/clothing/under/ascetic + name = "plain ascetic garb" + desc = "Popular with freshly grown vatborn and new age cultists alike." + icon_state = "ascetic" + item_state_slots = list(slot_r_hand_str = "white", slot_l_hand_str = "white") + /* * dress */ @@ -404,6 +422,18 @@ desc = "A western bustle dress from Earth's late 1800's." icon_state = "westernbustle" +/obj/item/clothing/under/dress/sari + name = "red sari" + desc = "A colorful traditional dress originating from India." + icon_state = "sari_red" + item_state_slots = list(slot_r_hand_str = "darkreddress", slot_l_hand_str = "darkreddress") + +/obj/item/clothing/under/dress/sari/green + name = "green sari" + icon_state = "sari_green" + item_state_slots = list(slot_r_hand_str = "dress_green", slot_l_hand_str = "dress_green") + + /* * wedding stuff */ diff --git a/code/modules/clothing/under/miscellaneous_vr.dm b/code/modules/clothing/under/miscellaneous_vr.dm index a0fef4879b..0644eb476c 100644 --- a/code/modules/clothing/under/miscellaneous_vr.dm +++ b/code/modules/clothing/under/miscellaneous_vr.dm @@ -85,7 +85,7 @@ H.update_icons() //Just want the matrix transform return - if (!IsInRange(new_size,25,200)) + if (!ISINRANGE(new_size,25,200)) to_chat(H,"The safety features of the uniform prevent you from choosing this size.") return diff --git a/code/modules/clothing/under/pants.dm b/code/modules/clothing/under/pants.dm index c306d842d0..035aac4cf8 100644 --- a/code/modules/clothing/under/pants.dm +++ b/code/modules/clothing/under/pants.dm @@ -189,4 +189,29 @@ /obj/item/clothing/under/pants/baggy/camo name = "baggy camo pants" desc = "A pair of woodland camouflage pants. Probably not the best choice for a space station." - icon_state = "baggy_camopants" \ No newline at end of file + icon_state = "baggy_camopants" + +/obj/item/clothing/under/pants/utility + name = "green utility pants" + desc = "A pair of pleather reinforced green work pants." + icon_state = "workpants_green" + +/obj/item/clothing/under/pants/utility/orange + name = "orange utility pants" + desc = "A pair of pleather reinforced orange work pants." + icon_state = "workpants_orange" + +/obj/item/clothing/under/pants/utility/blue + name = "blue utility pants" + desc = "A pair of pleather reinforced blue work pants." + icon_state = "workpants_blue" + +/obj/item/clothing/under/pants/utility/white + name = "white utility pants" + desc = "A pair of pleather reinforced white work pants." + icon_state = "workpants_white" + +/obj/item/clothing/under/pants/utility/red + name = "red utility pants" + desc = "A pair of pleather reinforced red work pants." + icon_state = "workpants_red" \ No newline at end of file diff --git a/code/modules/detectivework/microscope/dnascanner.dm b/code/modules/detectivework/microscope/dnascanner.dm index d45555f40d..413fe14d01 100644 --- a/code/modules/detectivework/microscope/dnascanner.dm +++ b/code/modules/detectivework/microscope/dnascanner.dm @@ -61,7 +61,7 @@ data["bloodsamp_desc"] = (bloodsamp ? (bloodsamp.desc ? bloodsamp.desc : "No information on record.") : "") data["lidstate"] = closed - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data) if (!ui) ui = new(user, src, ui_key, "dnaforensics.tmpl", "QuikScan DNA Analyzer", 540, 326) ui.set_initial_data(data) diff --git a/code/modules/detectivework/tools/luminol.dm b/code/modules/detectivework/tools/luminol.dm index ddf00a628a..48636370bc 100644 --- a/code/modules/detectivework/tools/luminol.dm +++ b/code/modules/detectivework/tools/luminol.dm @@ -8,6 +8,6 @@ possible_transfer_amounts = list(5,10) volume = 250 -/obj/item/weapon/reagent_containers/spray/luminol/New() - ..() +/obj/item/weapon/reagent_containers/spray/luminol/Initialize() + . = ..() reagents.add_reagent("luminol", 250) \ No newline at end of file diff --git a/code/modules/detectivework/tools/rag.dm b/code/modules/detectivework/tools/rag.dm index 32eb1ad4f4..1f09765a0b 100644 --- a/code/modules/detectivework/tools/rag.dm +++ b/code/modules/detectivework/tools/rag.dm @@ -29,12 +29,12 @@ var/on_fire = 0 var/burn_time = 20 //if the rag burns for too long it turns to ashes -/obj/item/weapon/reagent_containers/glass/rag/New() - ..() +/obj/item/weapon/reagent_containers/glass/rag/Initialize() + . = ..() update_name() /obj/item/weapon/reagent_containers/glass/rag/Destroy() - processing_objects -= src //so we don't continue turning to ash while gc'd + STOP_PROCESSING(SSobj, src) //so we don't continue turning to ash while gc'd return ..() /obj/item/weapon/reagent_containers/glass/rag/attack_self(mob/user as mob) @@ -187,14 +187,14 @@ qdel(src) return - processing_objects += src + START_PROCESSING(SSobj, src) set_light(2, null, "#E38F46") on_fire = 1 update_name() update_icon() /obj/item/weapon/reagent_containers/glass/rag/proc/extinguish() - processing_objects -= src + STOP_PROCESSING(SSobj, src) set_light(0) on_fire = 0 @@ -221,7 +221,7 @@ location.hotspot_expose(700, 5) if(burn_time <= 0) - processing_objects -= src + STOP_PROCESSING(SSobj, src) new /obj/effect/decal/cleanable/ash(location) qdel(src) return diff --git a/code/modules/detectivework/tools/uvlight.dm b/code/modules/detectivework/tools/uvlight.dm index 6997e3a04a..6d14b48087 100644 --- a/code/modules/detectivework/tools/uvlight.dm +++ b/code/modules/detectivework/tools/uvlight.dm @@ -21,12 +21,12 @@ on = !on if(on) set_light(range, 2, "#007fff") - processing_objects |= src + START_PROCESSING(SSobj, src) icon_state = "uv_on" else set_light(0) clear_last_scan() - processing_objects -= src + STOP_PROCESSING(SSobj, src) icon_state = "uv_off" /obj/item/device/uv_light/proc/clear_last_scan() diff --git a/code/modules/economy/Accounts_DB.dm b/code/modules/economy/Accounts_DB.dm index 507a516981..a293226d48 100644 --- a/code/modules/economy/Accounts_DB.dm +++ b/code/modules/economy/Accounts_DB.dm @@ -53,7 +53,7 @@ O.loc = src held_card = O - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) attack_hand(user) @@ -107,7 +107,7 @@ if (accounts.len > 0) data["accounts"] = accounts - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "accounts_terminal.tmpl", src.name, 400, 640) ui.set_initial_data(data) @@ -117,7 +117,7 @@ if(..()) return 1 - var/datum/nanoui/ui = GLOB.nanomanager.get_open_ui(usr, src, "main") + var/datum/nanoui/ui = SSnanoui.get_open_ui(usr, src, "main") if(href_list["choice"]) switch(href_list["choice"]) @@ -143,7 +143,7 @@ var/account_name = href_list["holder_name"] var/starting_funds = max(text2num(href_list["starting_funds"]), 0) - starting_funds = Clamp(starting_funds, 0, station_account.money) // Not authorized to put the station in debt. + starting_funds = CLAMP(starting_funds, 0, station_account.money) // Not authorized to put the station in debt. starting_funds = min(starting_funds, fund_cap) // Not authorized to give more than the fund cap. create_account(account_name, starting_funds, src) diff --git a/code/modules/economy/cash.dm b/code/modules/economy/cash.dm index 8bf5c63cc7..8c67e5394c 100644 --- a/code/modules/economy/cash.dm +++ b/code/modules/economy/cash.dm @@ -78,7 +78,7 @@ /obj/item/weapon/spacecash/attack_self() var/amount = input(usr, "How many Thalers do you want to take? (0 to [src.worth])", "Take Money", 20) as num - amount = round(Clamp(amount, 0, src.worth)) + amount = round(CLAMP(amount, 0, src.worth)) if(!amount) return diff --git a/code/modules/economy/cash_register.dm b/code/modules/economy/cash_register.dm index 9ef7a3f871..f3402f892e 100644 --- a/code/modules/economy/cash_register.dm +++ b/code/modules/economy/cash_register.dm @@ -128,7 +128,7 @@ if("set_amount") var/item_name = locate(href_list["item"]) var/n_amount = round(input("Enter amount", "New amount") as num) - n_amount = Clamp(n_amount, 0, 20) + n_amount = CLAMP(n_amount, 0, 20) if (!item_list[item_name] || !Adjacent(usr)) return transaction_amount += (n_amount - item_list[item_name]) * price_list[item_name] if(!n_amount) diff --git a/code/modules/economy/retail_scanner.dm b/code/modules/economy/retail_scanner.dm index af1d87177a..55a7fd0866 100644 --- a/code/modules/economy/retail_scanner.dm +++ b/code/modules/economy/retail_scanner.dm @@ -120,7 +120,7 @@ if("set_amount") var/item_name = locate(href_list["item"]) var/n_amount = round(input("Enter amount", "New amount") as num) - n_amount = Clamp(n_amount, 0, 20) + n_amount = CLAMP(n_amount, 0, 20) if (!item_list[item_name] || !Adjacent(usr)) return transaction_amount += (n_amount - item_list[item_name]) * price_list[item_name] if(!n_amount) diff --git a/code/modules/error_handler/error_handler.dm b/code/modules/error_handler/error_handler.dm index db3843a8c9..71783714b0 100644 --- a/code/modules/error_handler/error_handler.dm +++ b/code/modules/error_handler/error_handler.dm @@ -1,7 +1,5 @@ -var/list/error_last_seen = list() // error_cooldown items will either be positive (cooldown time) or negative (silenced error) // If negative, starts at -1, and goes down by 1 each time that error gets skipped -var/list/error_cooldown = list() var/total_runtimes = 0 var/total_runtimes_skipped = 0 // The ifdef needs to be down here, since the error viewer references total_runtimes @@ -10,18 +8,18 @@ var/total_runtimes_skipped = 0 if(!istype(e)) // Something threw an unusual exception log_error("\[[time_stamp()]] Uncaught exception: [e]") return ..() - if(!error_last_seen) // A runtime is occurring too early in start-up initialization + if(!GLOB.error_last_seen) // A runtime is occurring too early in start-up initialization return ..() total_runtimes++ var/erroruid = "[e.file][e.line]" - var/last_seen = error_last_seen[erroruid] - var/cooldown = error_cooldown[erroruid] || 0 + var/last_seen = GLOB.error_last_seen[erroruid] + var/cooldown = GLOB.error_cooldown[erroruid] || 0 if(last_seen == null) // A new error! - error_last_seen[erroruid] = world.time + GLOB.error_last_seen[erroruid] = world.time last_seen = world.time if(cooldown < 0) - error_cooldown[erroruid]-- // Used to keep track of skip count for this error + GLOB.error_cooldown[erroruid]-- // Used to keep track of skip count for this error total_runtimes_skipped++ return // Error is currently silenced, skip handling it @@ -36,13 +34,13 @@ var/total_runtimes_skipped = 0 spawn(0) usr = null sleep(ERROR_SILENCE_TIME) - var/skipcount = abs(error_cooldown[erroruid]) - 1 - error_cooldown[erroruid] = 0 + var/skipcount = abs(GLOB.error_cooldown[erroruid]) - 1 + GLOB.error_cooldown[erroruid] = 0 if(skipcount > 0) log_error("\[[time_stamp()]] Skipped [skipcount] runtimes in [e.file],[e.line].") error_cache.logError(e, skipCount = skipcount) - error_last_seen[erroruid] = world.time - error_cooldown[erroruid] = cooldown + GLOB.error_last_seen[erroruid] = world.time + GLOB.error_cooldown[erroruid] = cooldown // The detailed error info needs some tweaking to make it look nice var/list/srcinfo = null @@ -115,4 +113,4 @@ var/total_runtimes_skipped = 0 else e.desc = " [extra_info]\n\n" + e.desc - world.Error(e, e_src) + world.Error(e, e_src) \ No newline at end of file diff --git a/code/modules/events/brand_intelligence.dm b/code/modules/events/brand_intelligence.dm index 4a7f7490e9..9f21488c28 100644 --- a/code/modules/events/brand_intelligence.dm +++ b/code/modules/events/brand_intelligence.dm @@ -50,7 +50,7 @@ kill() return - if(IsMultiple(activeFor, 5)) + if(ISMULTIPLE(activeFor, 5)) if(prob(15)) var/obj/machinery/vending/infectedMachine = pick(vendingMachines) vendingMachines.Remove(infectedMachine) @@ -58,7 +58,7 @@ infectedMachine.shut_up = 0 infectedMachine.shoot_inventory = 1 - if(IsMultiple(activeFor, 12)) + if(ISMULTIPLE(activeFor, 12)) /* VORESTATION Removal - Using the pick below. originMachine.speak(pick("Try our aggressive new marketing strategies!", \ "You should buy products to feed your lifestyle obsession!", \ diff --git a/code/modules/events/carp_migration.dm b/code/modules/events/carp_migration.dm index d0f9a8165c..b30a5d4898 100644 --- a/code/modules/events/carp_migration.dm +++ b/code/modules/events/carp_migration.dm @@ -37,15 +37,15 @@ while (i <= num_groups) var/group_size = rand(group_size_min, group_size_max) for (var/j = 1, j <= group_size, j++) - spawned_carp.Add(new /mob/living/simple_animal/hostile/carp(spawn_locations[i])) + spawned_carp.Add(new /mob/living/simple_mob/animal/space/carp/event(spawn_locations[i])) i++ /datum/event/carp_migration/end() spawn(0) - for(var/mob/living/simple_animal/hostile/C in spawned_carp) - if(!C.stat) - var/turf/T = get_turf(C) + for(var/mob/living/simple_mob/SM in spawned_carp) + if(!SM.stat) + var/turf/T = get_turf(SM) if(istype(T, /turf/space)) if(prob(75)) - qdel(C) + qdel(SM) sleep(1) \ No newline at end of file diff --git a/code/modules/events/escaped_slimes.dm b/code/modules/events/escaped_slimes.dm index c9f4f661a3..6a859e6a13 100644 --- a/code/modules/events/escaped_slimes.dm +++ b/code/modules/events/escaped_slimes.dm @@ -3,20 +3,20 @@ endWhen = 90 + 15 + 1 var/spawncount var/list/possible_slimes = list( - /mob/living/simple_animal/slime/purple, - /mob/living/simple_animal/slime/orange, - /mob/living/simple_animal/slime/metal, - /mob/living/simple_animal/slime/yellow, - /mob/living/simple_animal/slime/dark_purple, - /mob/living/simple_animal/slime/silver, - /mob/living/simple_animal/slime/ruby, - /mob/living/simple_animal/slime/cerulean, - /mob/living/simple_animal/slime/red, - /mob/living/simple_animal/slime/green, - /mob/living/simple_animal/slime/pink, - /mob/living/simple_animal/slime/gold, - /mob/living/simple_animal/slime/oil, - /mob/living/simple_animal/slime/emerald, + /mob/living/simple_mob/slime/purple, + /mob/living/simple_mob/slime/orange, + /mob/living/simple_mob/slime/metal, + /mob/living/simple_mob/slime/yellow, + /mob/living/simple_mob/slime/dark_purple, + /mob/living/simple_mob/slime/silver, + /mob/living/simple_mob/slime/ruby, + /mob/living/simple_mob/slime/cerulean, + /mob/living/simple_mob/slime/red, + /mob/living/simple_mob/slime/green, + /mob/living/simple_mob/slime/pink, + /mob/living/simple_mob/slime/gold, + /mob/living/simple_mob/slime/oil, + /mob/living/simple_mob/slime/emerald, ) diff --git a/code/modules/events/event.dm b/code/modules/events/event.dm index 4912b238c8..3af0e94982 100644 --- a/code/modules/events/event.dm +++ b/code/modules/events/event.dm @@ -94,7 +94,7 @@ //Do not override this proc, instead use the appropiate procs. //This proc will handle the calls to the appropiate procs. -/datum/event/proc/process() +/datum/event/process() if(activeFor > startWhen && activeFor < endWhen) tick() @@ -123,12 +123,12 @@ end() endedAt = world.time - event_manager.active_events -= src - event_manager.event_complete(src) + SSevents.active_events -= src + SSevents.event_complete(src) /datum/event/New(var/datum/event_meta/EM) // event needs to be responsible for this, as stuff like APLUs currently make their own events for curious reasons - event_manager.active_events += src + SSevents.active_events += src event_meta = EM severity = event_meta.severity diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm index 5768ed6fe6..dee085dc2b 100644 --- a/code/modules/events/event_container.dm +++ b/code/modules/events/event_container.dm @@ -21,7 +21,7 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT var/last_world_time = 0 -/datum/event_container/proc/process() +/datum/event_container/process() if(!next_event_time) set_event_delay() @@ -139,7 +139,7 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Shipping Error", /datum/event/shipping_error , 30, list(ASSIGNMENT_ANY = 2), 0), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Space Dust", /datum/event/dust , 60, list(ASSIGNMENT_ENGINEER = 20), 0, 0, 50), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Trivial News", /datum/event/trivial_news, 400), - new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Ian Storm", /datum/event/ianstorm, 50), + //new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Ian Storm", /datum/event/ianstorm, 50), //VORESTATION AI TEMPORARY REMOVAL new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Lore News", /datum/event/lore_news, 400), 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)), diff --git a/code/modules/events/event_container_vr.dm b/code/modules/events/event_container_vr.dm index b8a6132863..05472dc638 100644 --- a/code/modules/events/event_container_vr.dm +++ b/code/modules/events/event_container_vr.dm @@ -74,7 +74,7 @@ new /datum/event_meta(EVENT_LEVEL_MODERATE, "Solar Storm", /datum/event/solar_storm, 30, list(ASSIGNMENT_ENGINEER = 40, ASSIGNMENT_SECURITY = 30), 1), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Virology Breach", /datum/event/prison_break/virology, 0, list(ASSIGNMENT_MEDICAL = 100), 1), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Xenobiology Breach", /datum/event/prison_break/xenobiology, 0, list(ASSIGNMENT_SCIENCE = 100), 1), - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Grub Infestation", /datum/event/grub_infestation, 40, list(ASSIGNMENT_SECURITY = 50, ASSIGNMENT_ENGINEER = 50), 1), + //new /datum/event_meta(EVENT_LEVEL_MODERATE, "Grub Infestation", /datum/event/grub_infestation, 40, list(ASSIGNMENT_SECURITY = 50, ASSIGNMENT_ENGINEER = 50), 1), //VORESTATION AI TEMPORARY REMOVAL //Evil grubs that drain station power slightly ) add_disabled_events(list( diff --git a/code/modules/events/event_manager.dm b/code/modules/events/event_manager.dm index 534c5aa56d..09c04c71ab 100644 --- a/code/modules/events/event_manager.dm +++ b/code/modules/events/event_manager.dm @@ -1,4 +1,5 @@ -/datum/event_manager +//The UI portion. Should probably be made its own thing/made into a NanoUI thing later. +/datum/controller/subsystem/events var/window_x = 700 var/window_y = 600 var/report_at_round_end = 0 @@ -8,49 +9,7 @@ var/row_options3 = " width='150px'" var/datum/event_container/selected_event_container = null - var/list/datum/event/active_events = list() - var/list/datum/event/finished_events = list() - - var/list/datum/event/allEvents - var/list/datum/event_container/event_containers = list( - EVENT_LEVEL_MUNDANE = new/datum/event_container/mundane, - EVENT_LEVEL_MODERATE = new/datum/event_container/moderate, - EVENT_LEVEL_MAJOR = new/datum/event_container/major - ) - - var/datum/event_meta/new_event = new - -/datum/event_manager/New() - allEvents = typesof(/datum/event) - /datum/event - -/datum/event_manager/proc/process() - for(var/datum/event/E in event_manager.active_events) - E.process() - - for(var/i = EVENT_LEVEL_MUNDANE to EVENT_LEVEL_MAJOR) - var/list/datum/event_container/EC = event_containers[i] - EC.process() - -/datum/event_manager/proc/event_complete(var/datum/event/E) - if(!E.event_meta || !E.severity) // datum/event is used here and there for random reasons, maintaining "backwards compatibility" - log_debug("Event of '[E.type]' with missing meta-data has completed.") - return - - finished_events += E - - // Add the event back to the list of available events - var/datum/event_container/EC = event_containers[E.severity] - var/datum/event_meta/EM = E.event_meta - if(EM.add_to_queue) - EC.available_events += EM - - log_debug("Event '[EM.name]' has completed at [worldtime2stationtime(world.time)].") - -/datum/event_manager/proc/delay_events(var/severity, var/delay) - var/list/datum/event_container/EC = event_containers[severity] - EC.next_event_time += delay - -/datum/event_manager/proc/Interact(var/mob/living/user) +/datum/controller/subsystem/events/proc/Interact(var/mob/living/user) var/html = GetInteractWindow() @@ -58,27 +17,7 @@ popup.set_content(html) popup.open() -/datum/event_manager/proc/RoundEnd() - if(!report_at_round_end) - return - - world << "


    Random Events This Round:" - for(var/datum/event/E in active_events|finished_events) - var/datum/event_meta/EM = E.event_meta - if(EM.name == "Nothing") - continue - var/message = "'[EM.name]' began at [worldtime2stationtime(E.startedAt)] " - if(E.isRunning) - message += "and is still running." - else - if(E.endedAt - E.startedAt > MinutesToTicks(5)) // Only mention end time if the entire duration was more than 5 minutes - message += "and ended at [worldtime2stationtime(E.endedAt)]." - else - message += "and ran to completion." - - world << message - -/datum/event_manager/proc/GetInteractWindow() +/datum/controller/subsystem/events/proc/GetInteractWindow() var/html = "Refresh" html += "Pause All - [config.allow_random_events ? "Pause" : "Resume"]" @@ -187,11 +126,10 @@ return html -/datum/event_manager/Topic(href, href_list) +/datum/controller/subsystem/events/Topic(href, href_list) if(..()) return - if(href_list["toggle_report"]) report_at_round_end = !report_at_round_end log_and_message_admins("has [report_at_round_end ? "enabled" : "disabled"] the round end event report.") @@ -284,7 +222,7 @@ Interact(usr) -/client/proc/forceEvent(var/type in event_manager.allEvents) +/client/proc/forceEvent(var/type in SSevents.allEvents) set name = "Trigger Event (Debug Only)" set category = "Debug" @@ -298,7 +236,5 @@ /client/proc/event_manager_panel() set name = "Event Manager Panel" set category = "Admin" - if(event_manager) - event_manager.Interact(usr) + SSevents.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 diff --git a/code/modules/events/grubinfestation_vr.dm b/code/modules/events/grubinfestation_vr.dm index 647b59117e..210e21e441 100644 --- a/code/modules/events/grubinfestation_vr.dm +++ b/code/modules/events/grubinfestation_vr.dm @@ -24,7 +24,7 @@ /datum/event/grub_infestation/start() while((spawncount >= 1) && vents.len) var/obj/vent = pick(vents) - new /mob/living/simple_animal/solargrub_larva(get_turf(vent)) + //new /mob/living/simple_mob/solargrub_larva(get_turf(vent)) //VORESTATION AI TEMPORARY REMOVAL. Event commented out until mobs are fixed. vents -= vent spawncount-- vents.Cut() diff --git a/code/modules/events/ian_storm_vr.dm b/code/modules/events/ian_storm_vr.dm index baf56045a9..2ddee490d9 100644 --- a/code/modules/events/ian_storm_vr.dm +++ b/code/modules/events/ian_storm_vr.dm @@ -1,4 +1,4 @@ -/datum/event/ianstorm +/datum/event/ianstorm //VORESTATION AI TEMPORARY REMOVAL announceWhen = 1 startWhen = 2 endWhen = 3 @@ -23,7 +23,7 @@ for(var/i = 0, i < 3, i++) var/turf/target = get_step(T, pick(alldirs)) if(target && istype(target, /turf/simulated/floor)) - var/mob/living/simple_animal/corgi/Ian/doge = new(target) + var/mob/living/simple_mob/corgi/Ian/doge = new(target) doge.name = "Ian " + pick("Alpha", "Beta", "Chi", "Delta", "Epsilon", "Phi", "Gamma", "Eta", "Iota", "Kappa", "Lambda", "Omicron", "Theta", "Rho", "Sigma", "Tau", "Upsilon", "Omega", "Psi", "Zeta") diff --git a/code/modules/events/infestation.dm b/code/modules/events/infestation.dm index 16f2b78521..3800bc999f 100644 --- a/code/modules/events/infestation.dm +++ b/code/modules/events/infestation.dm @@ -65,11 +65,11 @@ vermin = rand(0,2) switch(vermin) if(VERM_MICE) - spawn_types = list(/mob/living/simple_animal/mouse/gray, /mob/living/simple_animal/mouse/brown, /mob/living/simple_animal/mouse/white) + spawn_types = list(/mob/living/simple_mob/animal/passive/mouse/gray, /mob/living/simple_mob/animal/passive/mouse/brown, /mob/living/simple_mob/animal/passive/mouse/white) max_number = 12 vermstring = "mice" if(VERM_LIZARDS) - spawn_types = list(/mob/living/simple_animal/lizard) + spawn_types = list(/mob/living/simple_mob/animal/passive/lizard) max_number = 6 vermstring = "lizards" if(VERM_SPIDERS) diff --git a/code/modules/events/rogue_drones.dm b/code/modules/events/rogue_drones.dm index 768628f8fb..9cfcc648b5 100644 --- a/code/modules/events/rogue_drones.dm +++ b/code/modules/events/rogue_drones.dm @@ -16,10 +16,8 @@ else num = rand(2,6) for(var/i=0, i= 1) I.reagents.remove_reagent(reagent_id, amount_to_take, safety = 1) - qty_need = Ceiling(qty_need - amount_to_take) + qty_need = CEILING((qty_need - amount_to_take), 1) return 1 else log_debug("supply_demand event: not taking reagent '[reagent_id]': [amount_to_take]") @@ -284,7 +284,7 @@ var/list/medicineReagents = list() for(var/path in typesof(/datum/chemical_reaction) - /datum/chemical_reaction) var/datum/chemical_reaction/CR = path // Stupid casting required for reading - var/datum/reagent/R = chemical_reagents_list[initial(CR.result)] + var/datum/reagent/R = SSchemistry.chemical_reagents[initial(CR.result)] if(R && R.scannable) medicineReagents += R for(var/i in 1 to differentTypes) @@ -298,7 +298,7 @@ var/list/drinkReagents = list() for(var/path in typesof(/datum/chemical_reaction) - /datum/chemical_reaction) var/datum/chemical_reaction/CR = path // Stupid casting required for reading - var/datum/reagent/R = chemical_reagents_list[initial(CR.result)] + var/datum/reagent/R = SSchemistry.chemical_reagents[initial(CR.result)] if(istype(R, /datum/reagent/drink) || istype(R, /datum/reagent/ethanol)) drinkReagents += R for(var/i in 1 to differentTypes) @@ -342,6 +342,6 @@ var/datum/alloy/A = pick(types) types -= A // Don't pick the same thing twice var/chosen_path = initial(A.product) - var/chosen_qty = Floor(rand(5, 100) * initial(A.product_mod)) + var/chosen_qty = FLOOR(rand(5, 100) * initial(A.product_mod), 1) required_items += new /datum/supply_demand_order/thing(chosen_qty, chosen_path) return diff --git a/code/modules/examine/descriptions/armor.dm b/code/modules/examine/descriptions/armor.dm index 67f58e9ad5..39c5ccde92 100644 --- a/code/modules/examine/descriptions/armor.dm +++ b/code/modules/examine/descriptions/armor.dm @@ -46,8 +46,13 @@ if(flags & AIRTIGHT) armor_stats += "It is airtight. \n" - if(flags & STOPPRESSUREDAMAGE) + if(min_pressure_protection == 0) armor_stats += "Wearing this will protect you from the vacuum of space. \n" + else if(min_pressure_protection != null) + armor_stats += "Wearing this will protect you from low pressures, but not the vacuum of space. \n" + + if(max_pressure_protection != null) + armor_stats += "Wearing this will protect you from high pressures. \n" if(flags & THICKMATERIAL) armor_stats += "The material is exceptionally thick. \n" diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index ca95cc5422..f70873f226 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -124,9 +124,9 @@ mob/living/carbon/proc/handle_hallucinations() if(8) src << 'sound/machines/windowdoor.ogg' if(9) //To make it more realistic, I added two gunshots (enough to kill) - src << 'sound/weapons/Gunshot.ogg' + src << 'sound/weapons/Gunshot1.ogg' spawn(rand(10,30)) - src << 'sound/weapons/Gunshot.ogg' + src << 'sound/weapons/Gunshot2.ogg' if(10) src << 'sound/weapons/smash.ogg' if(11) //Same as above, but with tasers. diff --git a/code/modules/food/drinkingglass/metaglass.dm b/code/modules/food/drinkingglass/metaglass.dm index 52528235bb..babb71df8b 100644 --- a/code/modules/food/drinkingglass/metaglass.dm +++ b/code/modules/food/drinkingglass/metaglass.dm @@ -542,3 +542,7 @@ Drinks Data /datum/reagent/ethanol/ichor_mead glass_icon_state = "ichor_meadglass" glass_center_of_mass = list("x"=17, "y"=10) + +/datum/reagent/drink/eggnog + glass_icon_state = "eggnog" + glass_center_of_mass = list("x"=16, "y"=8) diff --git a/code/modules/food/food.dm b/code/modules/food/food.dm index 330dfaab7e..1e91e48ae0 100644 --- a/code/modules/food/food.dm +++ b/code/modules/food/food.dm @@ -11,8 +11,8 @@ var/list/center_of_mass = list() // Used for table placement -/obj/item/weapon/reagent_containers/food/New() - ..() +/obj/item/weapon/reagent_containers/food/Initialize() + . = ..() if (center_of_mass.len && !pixel_x && !pixel_y) src.pixel_x = rand(-6.0, 6) //Randomizes postion src.pixel_y = rand(-6.0, 6) diff --git a/code/modules/food/food/cans.dm b/code/modules/food/food/cans.dm index f67af64c3b..60d748ff18 100644 --- a/code/modules/food/food/cans.dm +++ b/code/modules/food/food/cans.dm @@ -11,8 +11,8 @@ icon_state = "cola" center_of_mass = list("x"=16, "y"=10) -/obj/item/weapon/reagent_containers/food/drinks/cans/cola/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/cans/cola/Initialize() + . = ..() reagents.add_reagent("cola", 30) /obj/item/weapon/reagent_containers/food/drinks/cans/waterbottle @@ -21,8 +21,8 @@ icon_state = "waterbottle" center_of_mass = list("x"=15, "y"=8) -/obj/item/weapon/reagent_containers/food/drinks/cans/waterbottle/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/cans/waterbottle/Initialize() + . = ..() reagents.add_reagent("water", 30) /obj/item/weapon/reagent_containers/food/drinks/cans/space_mountain_wind @@ -41,8 +41,8 @@ icon_state = "thirteen_loko" center_of_mass = list("x"=16, "y"=8) -/obj/item/weapon/reagent_containers/food/drinks/cans/thirteenloko/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/cans/thirteenloko/Initialize() + . = ..() reagents.add_reagent("thirteenloko", 30) /obj/item/weapon/reagent_containers/food/drinks/cans/dr_gibb @@ -61,8 +61,8 @@ icon_state = "starkist" center_of_mass = list("x"=16, "y"=10) -/obj/item/weapon/reagent_containers/food/drinks/cans/starkist/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/cans/starkist/Initialize() + . = ..() reagents.add_reagent("brownstar", 30) /obj/item/weapon/reagent_containers/food/drinks/cans/space_up @@ -111,8 +111,8 @@ icon_state = "tonic" center_of_mass = list("x"=16, "y"=10) -/obj/item/weapon/reagent_containers/food/drinks/cans/tonic/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/cans/tonic/Initialize() + . = ..() reagents.add_reagent("tonic", 50) /obj/item/weapon/reagent_containers/food/drinks/cans/sodawater @@ -121,8 +121,8 @@ icon_state = "sodawater" center_of_mass = list("x"=16, "y"=10) -/obj/item/weapon/reagent_containers/food/drinks/cans/sodawater/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/cans/sodawater/Initialize() + . = ..() reagents.add_reagent("sodawater", 50) /obj/item/weapon/reagent_containers/food/drinks/cans/gingerale @@ -131,6 +131,6 @@ icon_state = "gingerale" center_of_mass = list("x"=16, "y"=10) -/obj/item/weapon/reagent_containers/food/drinks/cans/gingerale/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/cans/gingerale/Initialize() + . = ..() reagents.add_reagent("gingerale", 30) \ No newline at end of file diff --git a/code/modules/food/food/condiment.dm b/code/modules/food/food/condiment.dm index 8ab7f34c79..377679f778 100644 --- a/code/modules/food/food/condiment.dm +++ b/code/modules/food/food/condiment.dm @@ -118,12 +118,12 @@ desc = "Used in cooking various dishes." icon_state = "enzyme" -/obj/item/weapon/reagent_containers/food/condiment/enzyme/New() - ..() +/obj/item/weapon/reagent_containers/food/condiment/enzyme/Initialize() + . = ..() reagents.add_reagent("enzyme", 50) -/obj/item/weapon/reagent_containers/food/condiment/sugar/New() - ..() +/obj/item/weapon/reagent_containers/food/condiment/sugar/Initialize() + . = ..() reagents.add_reagent("sugar", 50) /obj/item/weapon/reagent_containers/food/condiment/small @@ -140,8 +140,8 @@ desc = "Salt. From space oceans, presumably." icon_state = "saltshakersmall" -/obj/item/weapon/reagent_containers/food/condiment/small/saltshaker/New() - ..() +/obj/item/weapon/reagent_containers/food/condiment/small/saltshaker/Initialize() + . = ..() reagents.add_reagent("sodiumchloride", 20) /obj/item/weapon/reagent_containers/food/condiment/small/peppermill @@ -149,8 +149,8 @@ desc = "Often used to flavor food or make people sneeze." icon_state = "peppermillsmall" -/obj/item/weapon/reagent_containers/food/condiment/small/peppermill/New() - ..() +/obj/item/weapon/reagent_containers/food/condiment/small/peppermill/Initialize() + . = ..() reagents.add_reagent("blackpepper", 20) /obj/item/weapon/reagent_containers/food/condiment/small/sugar @@ -158,8 +158,8 @@ desc = "Sweetness in a bottle" icon_state = "sugarsmall" -/obj/item/weapon/reagent_containers/food/condiment/small/sugar/New() - ..() +/obj/item/weapon/reagent_containers/food/condiment/small/sugar/Initialize() + . = ..() reagents.add_reagent("sugar", 20) /obj/item/weapon/reagent_containers/food/condiment/flour @@ -171,8 +171,8 @@ /obj/item/weapon/reagent_containers/food/condiment/flour/on_reagent_change() return -/obj/item/weapon/reagent_containers/food/condiment/flour/New() - ..() +/obj/item/weapon/reagent_containers/food/condiment/flour/Initialize() + . = ..() reagents.add_reagent("flour", 30) src.pixel_x = rand(-10.0, 10) src.pixel_y = rand(-10.0, 10) diff --git a/code/modules/food/food/drinks.dm b/code/modules/food/food/drinks.dm index af4dd0fb53..8ebfd39021 100644 --- a/code/modules/food/food/drinks.dm +++ b/code/modules/food/food/drinks.dm @@ -117,8 +117,8 @@ item_state = "carton" center_of_mass = list("x"=16, "y"=9) -/obj/item/weapon/reagent_containers/food/drinks/milk/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/milk/Initialize() + . = ..() reagents.add_reagent("milk", 50) /obj/item/weapon/reagent_containers/food/drinks/soymilk @@ -127,8 +127,8 @@ icon_state = "soymilk" item_state = "carton" center_of_mass = list("x"=16, "y"=9) -/obj/item/weapon/reagent_containers/food/drinks/soymilk/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/soymilk/Initialize() + . = ..() reagents.add_reagent("soymilk", 50) /obj/item/weapon/reagent_containers/food/drinks/smallmilk @@ -138,8 +138,8 @@ icon_state = "mini-milk" item_state = "carton" center_of_mass = list("x"=16, "y"=9) -/obj/item/weapon/reagent_containers/food/drinks/smallmilk/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/smallmilk/Initialize() + . = ..() reagents.add_reagent("milk", 30) /obj/item/weapon/reagent_containers/food/drinks/smallchocmilk @@ -149,8 +149,8 @@ icon_state = "mini-milk_choco" item_state = "carton" center_of_mass = list("x"=16, "y"=9) -/obj/item/weapon/reagent_containers/food/drinks/smallchocmilk/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/smallchocmilk/Initialize() + . = ..() reagents.add_reagent("chocolate_milk", 30) /obj/item/weapon/reagent_containers/food/drinks/coffee @@ -158,8 +158,8 @@ desc = "Careful, the beverage you're about to enjoy is extremely hot." icon_state = "coffee" center_of_mass = list("x"=15, "y"=10) -/obj/item/weapon/reagent_containers/food/drinks/coffee/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/coffee/Initialize() + . = ..() reagents.add_reagent("coffee", 30) /obj/item/weapon/reagent_containers/food/drinks/tea @@ -169,8 +169,8 @@ item_state = "coffee" center_of_mass = list("x"=16, "y"=14) -/obj/item/weapon/reagent_containers/food/drinks/tea/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/tea/Initialize() + . = ..() reagents.add_reagent("tea", 30) /obj/item/weapon/reagent_containers/food/drinks/ice @@ -178,8 +178,8 @@ desc = "Careful, cold ice, do not chew." icon_state = "coffee" center_of_mass = list("x"=15, "y"=10) -/obj/item/weapon/reagent_containers/food/drinks/ice/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/ice/Initialize() + . = ..() reagents.add_reagent("ice", 30) /obj/item/weapon/reagent_containers/food/drinks/h_chocolate @@ -210,8 +210,8 @@ volume = 10 center_of_mass = list("x"=16, "y"=12) -/obj/item/weapon/reagent_containers/food/drinks/sillycup/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/sillycup/Initialize() + . = ..() /obj/item/weapon/reagent_containers/food/drinks/sillycup/on_reagent_change() ..() diff --git a/code/modules/food/food/drinks/bottle.dm b/code/modules/food/food/drinks/bottle.dm index d3b5e5bc66..aad0c94f70 100644 --- a/code/modules/food/food/drinks/bottle.dm +++ b/code/modules/food/food/drinks/bottle.dm @@ -14,8 +14,8 @@ var/rag_underlay = "rag" on_reagent_change() return // To suppress price updating. Bottles have their own price tags. -/obj/item/weapon/reagent_containers/food/drinks/bottle/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/bottle/Initialize() + . = ..() if(isGlass) unacidable = 1 /obj/item/weapon/reagent_containers/food/drinks/bottle/Destroy() @@ -193,8 +193,8 @@ icon_state = "ginbottle" center_of_mass = list("x"=16, "y"=4) -/obj/item/weapon/reagent_containers/food/drinks/bottle/gin/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/bottle/gin/Initialize() + . = ..() reagents.add_reagent("gin", 100) /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey @@ -203,8 +203,8 @@ icon_state = "whiskeybottle" center_of_mass = list("x"=16, "y"=3) -/obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey/Initialize() + . = ..() reagents.add_reagent("whiskey", 100) /obj/item/weapon/reagent_containers/food/drinks/bottle/specialwhiskey @@ -213,8 +213,8 @@ icon_state = "whiskeybottle2" center_of_mass = list("x"=16, "y"=3) -/obj/item/weapon/reagent_containers/food/drinks/bottle/specialwhiskey/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/bottle/specialwhiskey/Initialize() + . = ..() reagents.add_reagent("specialwhiskey", 100) /obj/item/weapon/reagent_containers/food/drinks/bottle/vodka @@ -223,8 +223,8 @@ icon_state = "vodkabottle" center_of_mass = list("x"=17, "y"=3) -/obj/item/weapon/reagent_containers/food/drinks/bottle/vodka/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/bottle/vodka/Initialize() + . = ..() reagents.add_reagent("vodka", 100) /obj/item/weapon/reagent_containers/food/drinks/bottle/tequilla @@ -233,8 +233,8 @@ icon_state = "tequillabottle" center_of_mass = list("x"=16, "y"=3) -/obj/item/weapon/reagent_containers/food/drinks/bottle/tequilla/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/bottle/tequilla/Initialize() + . = ..() reagents.add_reagent("tequilla", 100) /obj/item/weapon/reagent_containers/food/drinks/bottle/bottleofnothing @@ -243,8 +243,8 @@ icon_state = "bottleofnothing" center_of_mass = list("x"=17, "y"=5) -/obj/item/weapon/reagent_containers/food/drinks/bottle/bottleofnothing/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/bottle/bottleofnothing/Initialize() + . = ..() reagents.add_reagent("nothing", 100) /obj/item/weapon/reagent_containers/food/drinks/bottle/patron @@ -253,8 +253,8 @@ icon_state = "patronbottle" center_of_mass = list("x"=16, "y"=6) -/obj/item/weapon/reagent_containers/food/drinks/bottle/patron/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/bottle/patron/Initialize() + . = ..() reagents.add_reagent("patron", 100) /obj/item/weapon/reagent_containers/food/drinks/bottle/rum @@ -263,8 +263,8 @@ icon_state = "rumbottle" center_of_mass = list("x"=16, "y"=8) -/obj/item/weapon/reagent_containers/food/drinks/bottle/rum/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/bottle/rum/Initialize() + . = ..() reagents.add_reagent("rum", 100) /obj/item/weapon/reagent_containers/food/drinks/bottle/holywater @@ -273,8 +273,8 @@ icon_state = "holyflask" center_of_mass = list("x"=17, "y"=10) -/obj/item/weapon/reagent_containers/food/drinks/bottle/holywater/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/bottle/holywater/Initialize() + . = ..() reagents.add_reagent("holywater", 100) /obj/item/weapon/reagent_containers/food/drinks/bottle/vermouth @@ -283,8 +283,8 @@ icon_state = "vermouthbottle" center_of_mass = list("x"=17, "y"=3) -/obj/item/weapon/reagent_containers/food/drinks/bottle/vermouth/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/bottle/vermouth/Initialize() + . = ..() reagents.add_reagent("vermouth", 100) /obj/item/weapon/reagent_containers/food/drinks/bottle/kahlua @@ -293,8 +293,8 @@ icon_state = "kahluabottle" center_of_mass = list("x"=17, "y"=3) -/obj/item/weapon/reagent_containers/food/drinks/bottle/kahlua/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/bottle/kahlua/Initialize() + . = ..() reagents.add_reagent("kahlua", 100) /obj/item/weapon/reagent_containers/food/drinks/bottle/goldschlager @@ -303,8 +303,8 @@ icon_state = "goldschlagerbottle" center_of_mass = list("x"=15, "y"=3) -/obj/item/weapon/reagent_containers/food/drinks/bottle/goldschlager/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/bottle/goldschlager/Initialize() + . = ..() reagents.add_reagent("goldschlager", 100) /obj/item/weapon/reagent_containers/food/drinks/bottle/cognac @@ -313,8 +313,8 @@ icon_state = "cognacbottle" center_of_mass = list("x"=16, "y"=6) -/obj/item/weapon/reagent_containers/food/drinks/bottle/cognac/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/bottle/cognac/Initialize() + . = ..() reagents.add_reagent("cognac", 100) /obj/item/weapon/reagent_containers/food/drinks/bottle/wine @@ -323,8 +323,8 @@ icon_state = "winebottle" center_of_mass = list("x"=16, "y"=4) -/obj/item/weapon/reagent_containers/food/drinks/bottle/wine/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/bottle/wine/Initialize() + . = ..() reagents.add_reagent("wine", 100) /obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe @@ -333,8 +333,8 @@ icon_state = "absinthebottle" center_of_mass = list("x"=16, "y"=6) -/obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe/Initialize() + . = ..() reagents.add_reagent("absinthe", 100) /obj/item/weapon/reagent_containers/food/drinks/bottle/melonliquor @@ -343,8 +343,8 @@ icon_state = "alco-green" //Placeholder. center_of_mass = list("x"=16, "y"=6) -/obj/item/weapon/reagent_containers/food/drinks/bottle/melonliquor/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/bottle/melonliquor/Initialize() + . = ..() reagents.add_reagent("melonliquor", 100) /obj/item/weapon/reagent_containers/food/drinks/bottle/bluecuracao @@ -353,8 +353,8 @@ icon_state = "alco-blue" //Placeholder. center_of_mass = list("x"=16, "y"=6) -/obj/item/weapon/reagent_containers/food/drinks/bottle/bluecuracao/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/bottle/bluecuracao/Initialize() + . = ..() reagents.add_reagent("bluecuracao", 100) /obj/item/weapon/reagent_containers/food/drinks/bottle/grenadine @@ -363,8 +363,8 @@ icon_state = "grenadinebottle" center_of_mass = list("x"=16, "y"=6) -/obj/item/weapon/reagent_containers/food/drinks/bottle/grenadine/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/bottle/grenadine/Initialize() + . = ..() reagents.add_reagent("grenadine", 100) /obj/item/weapon/reagent_containers/food/drinks/bottle/cola @@ -373,8 +373,8 @@ icon_state = "colabottle" center_of_mass = list("x"=16, "y"=6) -/obj/item/weapon/reagent_containers/food/drinks/bottle/cola/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/bottle/cola/Initialize() + . = ..() reagents.add_reagent("cola", 100) /obj/item/weapon/reagent_containers/food/drinks/bottle/space_up @@ -403,8 +403,8 @@ icon_state = "pwinebottle" center_of_mass = list("x"=16, "y"=4) -/obj/item/weapon/reagent_containers/food/drinks/bottle/pwine/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/bottle/pwine/Initialize() + . = ..() reagents.add_reagent("pwine", 100) /obj/item/weapon/reagent_containers/food/drinks/bottle/redeemersbrew @@ -413,8 +413,8 @@ icon_state = "redeemersbrew" center_of_mass = list("x"=16, "y"=3) -/obj/item/weapon/reagent_containers/food/drinks/bottle/redeemersbrew/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/bottle/redeemersbrew/Initialize() + . = ..() reagents.add_reagent("unathiliquor", 100) //////////////////////////JUICES AND STUFF /////////////////////// @@ -427,8 +427,8 @@ center_of_mass = list("x"=16, "y"=7) isGlass = 0 -/obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice/Initialize() + . = ..() reagents.add_reagent("orangejuice", 100) /obj/item/weapon/reagent_containers/food/drinks/bottle/applejuice @@ -439,8 +439,8 @@ center_of_mass = list("x"=16, "y"=7) isGlass = 0 -/obj/item/weapon/reagent_containers/food/drinks/bottle/applejuice/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/bottle/applejuice/Initialize() + . = ..() reagents.add_reagent("applejuice", 100) /obj/item/weapon/reagent_containers/food/drinks/bottle/milk @@ -451,8 +451,8 @@ center_of_mass = list("x"=16, "y"=9) isGlass = 0 -/obj/item/weapon/reagent_containers/food/drinks/bottle/milk/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/bottle/milk/Initialize() + . = ..() reagents.add_reagent("milk", 100) /obj/item/weapon/reagent_containers/food/drinks/bottle/cream @@ -463,8 +463,8 @@ center_of_mass = list("x"=16, "y"=8) isGlass = 0 -/obj/item/weapon/reagent_containers/food/drinks/bottle/cream/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/bottle/cream/Initialize() + . = ..() reagents.add_reagent("cream", 100) /obj/item/weapon/reagent_containers/food/drinks/bottle/tomatojuice @@ -475,8 +475,8 @@ center_of_mass = list("x"=16, "y"=8) isGlass = 0 -/obj/item/weapon/reagent_containers/food/drinks/bottle/tomatojuice/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/bottle/tomatojuice/Initialize() + . = ..() reagents.add_reagent("tomatojuice", 100) /obj/item/weapon/reagent_containers/food/drinks/bottle/limejuice @@ -487,8 +487,8 @@ center_of_mass = list("x"=16, "y"=8) isGlass = 0 -/obj/item/weapon/reagent_containers/food/drinks/bottle/limejuice/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/bottle/limejuice/Initialize() + . = ..() reagents.add_reagent("limejuice", 100) /obj/item/weapon/reagent_containers/food/drinks/bottle/lemonjuice @@ -499,8 +499,8 @@ center_of_mass = list("x"=16, "y"=8) isGlass = 0 -/obj/item/weapon/reagent_containers/food/drinks/bottle/lemonjuice/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/bottle/lemonjuice/Initialize() + . = ..() reagents.add_reagent("lemonjuice", 100) //Small bottles @@ -516,8 +516,8 @@ icon_state = "beer" center_of_mass = list("x"=16, "y"=12) -/obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer/Initialize() + . = ..() reagents.add_reagent("beer", 30) /obj/item/weapon/reagent_containers/food/drinks/bottle/small/ale @@ -527,8 +527,8 @@ item_state = "beer" center_of_mass = list("x"=16, "y"=10) -/obj/item/weapon/reagent_containers/food/drinks/bottle/small/ale/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/bottle/small/ale/Initialize() + . = ..() reagents.add_reagent("ale", 30) /obj/item/weapon/reagent_containers/food/drinks/bottle/sake @@ -537,8 +537,8 @@ icon_state = "sakebottle" center_of_mass = list("x"=16, "y"=3) -/obj/item/weapon/reagent_containers/food/drinks/bottle/sake/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/bottle/sake/Initialize() + . = ..() reagents.add_reagent("sake", 100) /obj/item/weapon/reagent_containers/food/drinks/bottle/champagne @@ -546,6 +546,6 @@ desc = "For those special occassions." icon_state = "champagne" -/obj/item/weapon/reagent_containers/food/drinks/bottle/champagne/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/bottle/champagne/Initialize() + . = ..() reagents.add_reagent("champagne", 100) \ No newline at end of file diff --git a/code/modules/food/food/drinks/drinkingglass.dm b/code/modules/food/food/drinks/drinkingglass.dm index b8183fd1fc..7324dc8ad8 100644 --- a/code/modules/food/food/drinks/drinkingglass.dm +++ b/code/modules/food/food/drinks/drinkingglass.dm @@ -141,8 +141,8 @@ volume = 100 matter = list("plastic" = 2000) -/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/fitnessflask/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/fitnessflask/Initialize() + . = ..() icon_state = pick("fitness-cup_black", "fitness-cup_red", "fitness-cup_black") /obj/item/weapon/reagent_containers/food/drinks/drinkingglass/fitnessflask/on_reagent_change() @@ -169,8 +169,8 @@ /obj/item/weapon/reagent_containers/food/drinks/drinkingglass/fitnessflask/proteinshake name = "protein shake" -/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/fitnessflask/proteinshake/New() - ..() +/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/fitnessflask/proteinshake/Initialize() + . = ..() reagents.add_reagent("nutriment", 30) reagents.add_reagent("iron", 10) reagents.add_reagent("protein", 15) diff --git a/code/modules/food/food/sandwich.dm b/code/modules/food/food/sandwich.dm index 5662b7d3ff..f4d9ac5fd0 100644 --- a/code/modules/food/food/sandwich.dm +++ b/code/modules/food/food/sandwich.dm @@ -71,7 +71,7 @@ name = lowertext("[fullname] sandwich") if(length(name) > 80) name = "[pick(list("absurd","colossal","enormous","ridiculous"))] sandwich" - w_class = n_ceil(Clamp((ingredients.len/2),2,4)) + w_class = n_ceil(CLAMP((ingredients.len/2),2,4)) /obj/item/weapon/reagent_containers/food/snacks/csandwich/Destroy() for(var/obj/item/O in ingredients) diff --git a/code/modules/food/food/snacks.dm b/code/modules/food/food/snacks.dm index ce2dd8e791..7ce7f6501a 100644 --- a/code/modules/food/food/snacks.dm +++ b/code/modules/food/food/snacks.dm @@ -1,3876 +1,3878 @@ -//Food items that are eaten normally and don't leave anything behind. -/obj/item/weapon/reagent_containers/food/snacks - name = "snack" - desc = "yummy" - icon = 'icons/obj/food.dmi' - icon_state = null - var/bitesize = 1 - var/bitecount = 0 - var/trash = null - var/slice_path - var/slices_num - var/dried_type = null - var/dry = 0 - var/nutriment_amt = 0 - var/list/nutriment_desc = list("food" = 1) - center_of_mass = list("x"=16, "y"=16) - w_class = ITEMSIZE_SMALL - force = 1 - -/obj/item/weapon/reagent_containers/food/snacks/New() - ..() - if(nutriment_amt) - reagents.add_reagent("nutriment",nutriment_amt,nutriment_desc) - -/obj/item/weapon/reagent_containers/food/snacks/New() - ..() - if(nutriment_amt) - reagents.add_reagent("nutriment", nutriment_amt) - - //Placeholder for effect that trigger on eating that aren't tied to reagents. -/obj/item/weapon/reagent_containers/food/snacks/proc/On_Consume(var/mob/M) - if(!usr) - usr = M - if(!reagents.total_volume) - M.visible_message("[M] finishes eating \the [src].","You finish eating \the [src].") - usr.drop_from_inventory(src) //so icons update :[ - - if(trash) - if(ispath(trash,/obj/item)) - var/obj/item/TrashItem = new trash(usr) - usr.put_in_hands(TrashItem) - else if(istype(trash,/obj/item)) - usr.put_in_hands(trash) - qdel(src) - return - -/obj/item/weapon/reagent_containers/food/snacks/attack_self(mob/user as mob) - return - -/obj/item/weapon/reagent_containers/food/snacks/attack(mob/M as mob, mob/user as mob, def_zone) - if(reagents && !reagents.total_volume) - user << "None of [src] left!" - user.drop_from_inventory(src) - qdel(src) - return 0 - - if(istype(M, /mob/living/carbon)) - //TODO: replace with standard_feed_mob() call. - - var/fullness = M.nutrition + (M.reagents.get_reagent_amount("nutriment") * 25) - if(M == user) //If you're eating it yourself - if(istype(M,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = M - if(!H.check_has_mouth()) - user << "Where do you intend to put \the [src]? You don't have a mouth!" - return - var/obj/item/blocked = H.check_mouth_coverage() - if(blocked) - user << "\The [blocked] is in the way!" - return - - // Vorestation edits in this section. - user.setClickCooldown(user.get_attack_speed(src)) //puts a limit on how fast people can eat/drink things - if (fullness <= 50) - M << "You hungrily chew out a piece of [src] and gobble it!" - if (fullness > 50 && fullness <= 150) - M << "You hungrily begin to eat [src]." - if (fullness > 150 && fullness <= 350) - M << "You take a bite of [src]." - if (fullness > 350 && fullness <= 550) - M << "You unwillingly chew a bit of [src]." - if (fullness > 550 && fullness <= 650) - M << "You swallow some more of the [src], causing your belly to swell out a little." - if (fullness > 650 && fullness <= 1000) - M << "You stuff yourself with the [src]. Your stomach feels very heavy." - if (fullness > 1000 && fullness <= 3000) - M << "You gluttonously swallow down the hunk of [src]. You're so gorged, it's hard to stand." - if (fullness > 3000 && fullness <= 5500) - M << "You force the piece of [src] down your throat. You can feel your stomach getting firm as it reaches its limits." - if (fullness > 5500 && fullness <= 6000) - M << "You barely glug down the bite of [src], causing undigested food to force into your intestines. You can't take much more of this!" - if (fullness > 6000) // There has to be a limit eventually. - M << "Your stomach blorts and aches, prompting you to stop. You literally cannot force any more of [src] to go down your throat." - return 0 - /*if (fullness > (550 * (1 + M.overeatduration / 2000))) // The more you eat - the more you can eat - M << "You cannot force any more of [src] to go down your throat." - return 0*/ - - else - if(istype(M,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = M - if(!H.check_has_mouth()) - user << "Where do you intend to put \the [src]? \The [H] doesn't have a mouth!" - return - var/obj/item/blocked = H.check_mouth_coverage() - if(blocked) - user << "\The [blocked] is in the way!" - return - - if(!istype(M, /mob/living/carbon/slime)) //If you're feeding it to someone else. - - /*if (fullness <= (550 * (1 + M.overeatduration / 1000))) // Vorestation edit - user.visible_message("[user] attempts to feed [M] [src].") - else - user.visible_message("[user] cannot force anymore of [src] down [M]'s throat.") - return 0*/ - user.visible_message("[user] attempts to feed [M] [src].") // Vorestation edit - - user.setClickCooldown(user.get_attack_speed(src)) - if(!do_mob(user, M)) return - - //Do we really care about this - add_attack_logs(user,M,"Fed with [src.name] containing [reagentlist(src)]", admin_notify = FALSE) - - user.visible_message("[user] feeds [M] [src].") - - else - user << "This creature does not seem to have a mouth!" - return - - if(reagents) //Handle ingestion of the reagent. - playsound(M.loc,'sound/items/eatfood.ogg', rand(10,50), 1) - if(reagents.total_volume) - if(reagents.total_volume > bitesize) - reagents.trans_to_mob(M, bitesize, CHEM_INGEST) - else - reagents.trans_to_mob(M, reagents.total_volume, CHEM_INGEST) - bitecount++ - On_Consume(M) - return 1 - - return 0 - -/obj/item/weapon/reagent_containers/food/snacks/examine(mob/user) - if(!..(user, 1)) - return - if (bitecount==0) - return - else if (bitecount==1) - user << "\The [src] was bitten by someone!" - else if (bitecount<=3) - user << "\The [src] was bitten [bitecount] times!" - else - user << "\The [src] was bitten multiple times!" - -/obj/item/weapon/reagent_containers/food/snacks/attackby(obj/item/weapon/W as obj, mob/user as mob) - if(istype(W,/obj/item/weapon/storage)) - ..() // -> item/attackby() - return - - // Eating with forks - if(istype(W,/obj/item/weapon/material/kitchen/utensil)) - var/obj/item/weapon/material/kitchen/utensil/U = W - if(U.scoop_food) - if(!U.reagents) - U.create_reagents(5) - - if (U.reagents.total_volume > 0) - user << "You already have something on your [U]." - return - - user.visible_message( \ - "[user] scoops up some [src] with \the [U]!", \ - "You scoop up some [src] with \the [U]!" \ - ) - - src.bitecount++ - U.overlays.Cut() - U.loaded = "[src]" - var/image/I = new(U.icon, "loadedfood") - I.color = src.filling_color - U.overlays += I - - reagents.trans_to_obj(U, min(reagents.total_volume,5)) - - if (reagents.total_volume <= 0) - qdel(src) - return - - if (is_sliceable()) - //these are used to allow hiding edge items in food that is not on a table/tray - var/can_slice_here = 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)) - var/hide_item = !has_edge(W) || !can_slice_here - - if (hide_item) - if (W.w_class >= src.w_class || is_robot_module(W)) - return - - to_chat(user, "You slip \the [W] inside \the [src].") - user.drop_from_inventory(W, src) - add_fingerprint(user) - contents += W - return - - if (has_edge(W)) - if (!can_slice_here) - to_chat(user, "You cannot slice \the [src] here! You need a table or at least a tray to do it.") - return - - var/slices_lost = 0 - if (W.w_class > 3) - user.visible_message("\The [user] crudely slices \the [src] with [W]!", "You crudely slice \the [src] with your [W]!") - slices_lost = rand(1,min(1,round(slices_num/2))) - else - user.visible_message("\The [user] slices \the [src]!", "You slice \the [src]!") - - var/reagents_per_slice = reagents.total_volume/slices_num - for(var/i=1 to (slices_num-slices_lost)) - var/obj/slice = new slice_path (src.loc) - reagents.trans_to_obj(slice, reagents_per_slice) - qdel(src) - return - -/obj/item/weapon/reagent_containers/food/snacks/proc/is_sliceable() - return (slices_num && slice_path && slices_num > 0) - -/obj/item/weapon/reagent_containers/food/snacks/Destroy() - if(contents) - for(var/atom/movable/something in contents) - something.dropInto(loc) - . = ..() - -//////////////////////////////////////////////////////////////////////////////// -/// FOOD END -//////////////////////////////////////////////////////////////////////////////// -/obj/item/weapon/reagent_containers/food/snacks/attack_generic(var/mob/living/user) - if(!isanimal(user) && !isalien(user)) - return - user.visible_message("[user] nibbles away at \the [src].","You nibble away at \the [src].") - bitecount++ - if(reagents) - reagents.trans_to_mob(user, bitesize, CHEM_INGEST) - spawn(5) - if(!src && !user.client) - user.custom_emote(1,"[pick("burps", "cries for more", "burps twice", "looks at the area where the food was")]") - qdel(src) - On_Consume(user) - -////////////////////////////////////////////////// -////////////////////////////////////////////Snacks -////////////////////////////////////////////////// -//Items in the "Snacks" subcategory are food items that people actually eat. The key points are that they are created -// already filled with reagents and are destroyed when empty. Additionally, they make a "munching" noise when eaten. - -//Notes by Darem: Food in the "snacks" subtype can hold a maximum of 50 units Generally speaking, you don't want to go over 40 -// total for the item because you want to leave space for extra condiments. If you want effect besides healing, add a reagent for -// it. Try to stick to existing reagents when possible (so if you want a stronger healing effect, just use Tricordrazine). On use -// effect (such as the old officer eating a donut code) requires a unique reagent (unless you can figure out a better way). - -//The nutriment reagent and bitesize variable replace the old heal_amt and amount variables. Each unit of nutriment is equal to -// 2 of the old heal_amt variable. Bitesize is the rate at which the reagents are consumed. So if you have 6 nutriment and a -// bitesize of 2, then it'll take 3 bites to eat. Unlike the old system, the contained reagents are evenly spread among all -// the bites. No more contained reagents = no more bites. - -//Here is an example of the new formatting for anyone who wants to add more food items. -///obj/item/weapon/reagent_containers/food/snacks/xenoburger //Identification path for the object. -// name = "Xenoburger" //Name that displays in the UI. -// desc = "Smells caustic. Tastes like heresy." //Duh -// icon_state = "xburger" //Refers to an icon in food.dmi -// New() //Don't mess with this. -// ..() //Same here. -// reagents.add_reagent("xenomicrobes", 10) //This is what is in the food item. you may copy/paste -// reagents.add_reagent("nutriment", 2) // this line of code for all the contents. -// bitesize = 3 //This is the amount each bite consumes. - - - - -/obj/item/weapon/reagent_containers/food/snacks/aesirsalad - name = "Aesir salad" - desc = "Probably too incredible for mortal men to fully enjoy." - icon_state = "aesirsalad" - trash = /obj/item/trash/snack_bowl - filling_color = "#468C00" - center_of_mass = list("x"=17, "y"=11) - nutriment_amt = 8 - nutriment_desc = list("apples" = 3,"salad" = 5) - -/obj/item/weapon/reagent_containers/food/snacks/aesirsalad/New() - ..() - reagents.add_reagent("doctorsdelight", 8) - reagents.add_reagent("tricordrazine", 8) - bitesize = 3 - -/obj/item/weapon/reagent_containers/food/snacks/candy - name = "candy" - desc = "Nougat, love it or hate it." - icon_state = "candy" - trash = /obj/item/trash/candy - filling_color = "#7D5F46" - center_of_mass = list("x"=15, "y"=15) - nutriment_amt = 1 - nutriment_desc = list("candy" = 1) - -/obj/item/weapon/reagent_containers/food/snacks/candy/New() - ..() - reagents.add_reagent("sugar", 3) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar - name = "protein bar" - desc = "SwoleMAX brand protein bars, guaranteed to get you feeling perfectly overconfident." - icon_state = "proteinbar" - trash = /obj/item/trash/candy/proteinbar - nutriment_amt = 9 - nutriment_desc = list("candy" = 1, "protein" = 8) - -/obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar/New() - ..() - reagents.add_reagent("protein", 4) - reagents.add_reagent("sugar", 4) - bitesize = 6 - -/obj/item/weapon/reagent_containers/food/snacks/candy/donor - name = "Donor Candy" - desc = "A little treat for blood donors." - trash = /obj/item/trash/candy - nutriment_amt = 9 - nutriment_desc = list("candy" = 10) - -/obj/item/weapon/reagent_containers/food/snacks/candy/donor/New() - ..() - reagents.add_reagent("sugar", 3) - bitesize = 5 - -/obj/item/weapon/reagent_containers/food/snacks/candy_corn - name = "candy corn" - desc = "It's a handful of candy corn. Cannot be stored in a detective's hat, alas." - icon_state = "candy_corn" - filling_color = "#FFFCB0" - center_of_mass = list("x"=14, "y"=10) - nutriment_amt = 4 - nutriment_desc = list("candy corn" = 4) - -/obj/item/weapon/reagent_containers/food/snacks/candy_corn/New() - ..() - reagents.add_reagent("sugar", 2) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/chips - name = "chips" - desc = "Commander Riker's What-The-Crisps" - icon_state = "chips" - trash = /obj/item/trash/chips - filling_color = "#E8C31E" - center_of_mass = list("x"=15, "y"=15) - nutriment_amt = 3 - nutriment_desc = list("salt" = 1, "chips" = 2) - -/obj/item/weapon/reagent_containers/food/snacks/chips/New() - ..() - bitesize = 1 - -/obj/item/weapon/reagent_containers/food/snacks/cookie - name = "cookie" - desc = "COOKIE!!!" - icon_state = "COOKIE!!!" - filling_color = "#DBC94F" - center_of_mass = list("x"=17, "y"=18) - nutriment_amt = 5 - nutriment_desc = list("sweetness" = 3, "cookie" = 2) - -/obj/item/weapon/reagent_containers/food/snacks/cookie/New() - ..() - bitesize = 1 - -/obj/item/weapon/reagent_containers/food/snacks/chocolatebar - name = "Chocolate Bar" - desc = "Such sweet, fattening food." - icon_state = "chocolatebar" - filling_color = "#7D5F46" - center_of_mass = list("x"=15, "y"=15) - nutriment_amt = 2 - nutriment_desc = list("chocolate" = 5) - -/obj/item/weapon/reagent_containers/food/snacks/chocolatebar/New() - ..() - reagents.add_reagent("sugar", 2) - reagents.add_reagent("coco", 2) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/chocolatepiece - name = "chocolate piece" - desc = "A luscious milk chocolate piece filled with gooey caramel." - icon_state = "chocolatepiece" - filling_color = "#7D5F46" - center_of_mass = list("x"=15, "y"=15) - nutriment_amt = 1 - nutriment_desc = list("chocolate" = 3, "caramel" = 2, "lusciousness" = 1) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/chocolatepiece/white - name = "white chocolate piece" - desc = "A creamy white chocolate piece drizzled in milk chocolate." - icon_state = "chocolatepiece_white" - filling_color = "#E2DAD3" - nutriment_desc = list("white chocolate" = 3, "creaminess" = 1) - -/obj/item/weapon/reagent_containers/food/snacks/chocolatepiece/truffle - name = "chocolate truffle" - desc = "A bite-sized milk chocolate truffle that could buy anyone's love." - icon_state = "chocolatepiece_truffle" - nutriment_desc = list("chocolate" = 3, "undying devotion" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/chocolateegg - name = "Chocolate Egg" - desc = "Such sweet, fattening food." - icon_state = "chocolateegg" - filling_color = "#7D5F46" - center_of_mass = list("x"=16, "y"=13) - nutriment_amt = 3 - nutriment_desc = list("chocolate" = 5) - -/obj/item/weapon/reagent_containers/food/snacks/chocolateegg/New() - ..() - reagents.add_reagent("sugar", 2) - reagents.add_reagent("coco", 2) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/donut - name = "donut" - desc = "Goes great with Robust Coffee." - icon_state = "donut1" - filling_color = "#D9C386" - var/overlay_state = "box-donut1" - center_of_mass = list("x"=13, "y"=16) - nutriment_desc = list("sweetness", "donut") - -/obj/item/weapon/reagent_containers/food/snacks/donut/normal - name = "donut" - desc = "Goes great with Robust Coffee." - icon_state = "donut1" - nutriment_amt = 3 - -/obj/item/weapon/reagent_containers/food/snacks/donut/normal/New() - ..() - reagents.add_reagent("nutriment", 3) - reagents.add_reagent("sprinkles", 1) - src.bitesize = 3 - if(prob(30)) - src.icon_state = "donut2" - src.overlay_state = "box-donut2" - src.name = "frosted donut" - reagents.add_reagent("sprinkles", 2) - center_of_mass = list("x"=19, "y"=16) - -/obj/item/weapon/reagent_containers/food/snacks/donut/chaos - name = "Chaos Donut" - desc = "Like life, it never quite tastes the same." - icon_state = "donut1" - filling_color = "#ED11E6" - nutriment_amt = 2 - -/obj/item/weapon/reagent_containers/food/snacks/donut/chaos/New() - ..() - reagents.add_reagent("sprinkles", 1) - bitesize = 10 - var/chaosselect = pick(1,2,3,4,5,6,7,8,9,10) - switch(chaosselect) - if(1) - reagents.add_reagent("nutriment", 3) - if(2) - reagents.add_reagent("capsaicin", 3) - if(3) - reagents.add_reagent("frostoil", 3) - if(4) - reagents.add_reagent("sprinkles", 3) - if(5) - reagents.add_reagent("phoron", 3) - if(6) - reagents.add_reagent("coco", 3) - if(7) - reagents.add_reagent("slimejelly", 3) - if(8) - reagents.add_reagent("banana", 3) - if(9) - reagents.add_reagent("berryjuice", 3) - if(10) - reagents.add_reagent("tricordrazine", 3) - if(prob(30)) - src.icon_state = "donut2" - src.overlay_state = "box-donut2" - src.name = "Frosted Chaos Donut" - reagents.add_reagent("sprinkles", 2) - -/obj/item/weapon/reagent_containers/food/snacks/donut/jelly - name = "Jelly Donut" - desc = "You jelly?" - icon_state = "jdonut1" - filling_color = "#ED1169" - center_of_mass = list("x"=16, "y"=11) - nutriment_amt = 3 - -/obj/item/weapon/reagent_containers/food/snacks/donut/jelly/New() - ..() - reagents.add_reagent("sprinkles", 1) - reagents.add_reagent("berryjuice", 5) - bitesize = 5 - if(prob(30)) - src.icon_state = "jdonut2" - src.overlay_state = "box-donut2" - src.name = "Frosted Jelly Donut" - reagents.add_reagent("sprinkles", 2) - -/obj/item/weapon/reagent_containers/food/snacks/donut/slimejelly - name = "Jelly Donut" - desc = "You jelly?" - icon_state = "jdonut1" - filling_color = "#ED1169" - center_of_mass = list("x"=16, "y"=11) - nutriment_amt = 3 - -/obj/item/weapon/reagent_containers/food/snacks/donut/slimejelly/New() - ..() - reagents.add_reagent("sprinkles", 1) - reagents.add_reagent("slimejelly", 5) - bitesize = 5 - if(prob(30)) - src.icon_state = "jdonut2" - src.overlay_state = "box-donut2" - src.name = "Frosted Jelly Donut" - reagents.add_reagent("sprinkles", 2) - -/obj/item/weapon/reagent_containers/food/snacks/donut/cherryjelly - name = "Jelly Donut" - desc = "You jelly?" - icon_state = "jdonut1" - filling_color = "#ED1169" - center_of_mass = list("x"=16, "y"=11) - nutriment_amt = 3 - -/obj/item/weapon/reagent_containers/food/snacks/donut/cherryjelly/New() - ..() - reagents.add_reagent("sprinkles", 1) - reagents.add_reagent("cherryjelly", 5) - bitesize = 5 - if(prob(30)) - src.icon_state = "jdonut2" - src.overlay_state = "box-donut2" - src.name = "Frosted Jelly Donut" - reagents.add_reagent("sprinkles", 2) - -/obj/item/weapon/reagent_containers/food/snacks/egg - name = "egg" - desc = "An egg!" - icon_state = "egg" - filling_color = "#FDFFD1" - volume = 10 - center_of_mass = list("x"=16, "y"=13) - -/obj/item/weapon/reagent_containers/food/snacks/egg/New() - ..() - reagents.add_reagent("egg", 3) - -/obj/item/weapon/reagent_containers/food/snacks/egg/afterattack(obj/O as obj, mob/user as mob, proximity) - if(istype(O,/obj/machinery/microwave)) - return ..() - if(!(proximity && O.is_open_container())) - return - user << "You crack \the [src] into \the [O]." - reagents.trans_to(O, reagents.total_volume) - user.drop_from_inventory(src) - qdel(src) - -/obj/item/weapon/reagent_containers/food/snacks/egg/throw_impact(atom/hit_atom) - ..() - new/obj/effect/decal/cleanable/egg_smudge(src.loc) - src.reagents.splash(hit_atom, reagents.total_volume) - src.visible_message("[src.name] has been squashed.","You hear a smack.") - qdel(src) - -/obj/item/weapon/reagent_containers/food/snacks/egg/attackby(obj/item/weapon/W as obj, mob/user as mob) - if(istype( W, /obj/item/weapon/pen/crayon )) - var/obj/item/weapon/pen/crayon/C = W - var/clr = C.colourName - - if(!(clr in list("blue","green","mime","orange","purple","rainbow","red","yellow"))) - usr << "The egg refuses to take on this color!" - return - - usr << "You color \the [src] [clr]" - icon_state = "egg-[clr]" - else - ..() - -/obj/item/weapon/reagent_containers/food/snacks/egg/blue - icon_state = "egg-blue" - -/obj/item/weapon/reagent_containers/food/snacks/egg/green - icon_state = "egg-green" - -/obj/item/weapon/reagent_containers/food/snacks/egg/mime - icon_state = "egg-mime" - -/obj/item/weapon/reagent_containers/food/snacks/egg/orange - icon_state = "egg-orange" - -/obj/item/weapon/reagent_containers/food/snacks/egg/purple - icon_state = "egg-purple" - -/obj/item/weapon/reagent_containers/food/snacks/egg/rainbow - icon_state = "egg-rainbow" - -/obj/item/weapon/reagent_containers/food/snacks/egg/red - icon_state = "egg-red" - -/obj/item/weapon/reagent_containers/food/snacks/egg/yellow - icon_state = "egg-yellow" - -/obj/item/weapon/reagent_containers/food/snacks/friedegg - name = "Fried egg" - desc = "A fried egg, with a touch of salt and pepper." - icon_state = "friedegg" - filling_color = "#FFDF78" - center_of_mass = list("x"=16, "y"=14) - -/obj/item/weapon/reagent_containers/food/snacks/friedegg/New() - ..() - reagents.add_reagent("protein", 3) - reagents.add_reagent("sodiumchloride", 1) - reagents.add_reagent("blackpepper", 1) - bitesize = 1 - -/obj/item/weapon/reagent_containers/food/snacks/boiledegg - name = "Boiled egg" - desc = "A hard boiled egg." - icon_state = "egg" - filling_color = "#FFFFFF" - -/obj/item/weapon/reagent_containers/food/snacks/boiledegg/New() - ..() - reagents.add_reagent("protein", 2) - -/obj/item/weapon/reagent_containers/food/snacks/organ - name = "organ" - desc = "It's good for you." - icon = 'icons/obj/surgery.dmi' - icon_state = "appendix" - filling_color = "#E00D34" - center_of_mass = list("x"=16, "y"=16) - -/obj/item/weapon/reagent_containers/food/snacks/organ/New() - ..() - reagents.add_reagent("protein", rand(3,5)) - reagents.add_reagent("toxin", rand(1,3)) - src.bitesize = 3 - -/obj/item/weapon/reagent_containers/food/snacks/tofu - name = "Tofu" - icon_state = "tofu" - desc = "We all love tofu." - filling_color = "#FFFEE0" - center_of_mass = list("x"=17, "y"=10) - nutriment_amt = 3 - nutriment_desc = list("tofu" = 3, "goeyness" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/tofu/New() - ..() - src.bitesize = 3 - -/obj/item/weapon/reagent_containers/food/snacks/tofurkey - name = "Tofurkey" - desc = "A fake turkey made from tofu." - icon_state = "tofurkey" - filling_color = "#FFFEE0" - center_of_mass = list("x"=16, "y"=8) - nutriment_amt = 12 - nutriment_desc = list("turkey" = 3, "tofu" = 5, "goeyness" = 4) - -/obj/item/weapon/reagent_containers/food/snacks/tofurkey/New() - ..() - reagents.add_reagent("stoxin", 3) - bitesize = 3 - -/obj/item/weapon/reagent_containers/food/snacks/stuffing - name = "Stuffing" - desc = "Moist, peppery breadcrumbs for filling the body cavities of dead birds. Dig in!" - icon_state = "stuffing" - filling_color = "#C9AC83" - center_of_mass = list("x"=16, "y"=10) - nutriment_amt = 3 - nutriment_desc = list("dryness" = 2, "bread" = 2) - -/obj/item/weapon/reagent_containers/food/snacks/stuffing/New() - ..() - bitesize = 1 - -/obj/item/weapon/reagent_containers/food/snacks/carpmeat - name = "carp fillet" - desc = "A fillet of spess carp meat" - icon_state = "fishfillet" - filling_color = "#FFDEFE" - center_of_mass = list("x"=17, "y"=13) - -/obj/item/weapon/reagent_containers/food/snacks/carpmeat/New() - ..() - reagents.add_reagent("protein", 3) - reagents.add_reagent("carpotoxin", 3) - src.bitesize = 6 - -/obj/item/weapon/reagent_containers/food/snacks/fishfingers - name = "Fish Fingers" - desc = "A finger of fish." - icon_state = "fishfingers" - filling_color = "#FFDEFE" - center_of_mass = list("x"=16, "y"=13) - -/obj/item/weapon/reagent_containers/food/snacks/fishfingers/New() - ..() - reagents.add_reagent("protein", 4) - reagents.add_reagent("carpotoxin", 3) - bitesize = 3 - -/obj/item/weapon/reagent_containers/food/snacks/hugemushroomslice - name = "huge mushroom slice" - desc = "A slice from a huge mushroom." - icon_state = "hugemushroomslice" - filling_color = "#E0D7C5" - center_of_mass = list("x"=17, "y"=16) - nutriment_amt = 3 - nutriment_desc = list("raw" = 2, "mushroom" = 2) - -/obj/item/weapon/reagent_containers/food/snacks/hugemushroomslice/New() - ..() - reagents.add_reagent("psilocybin", 3) - src.bitesize = 6 - -/obj/item/weapon/reagent_containers/food/snacks/tomatomeat - name = "tomato slice" - desc = "A slice from a huge tomato" - icon_state = "tomatomeat" - filling_color = "#DB0000" - center_of_mass = list("x"=17, "y"=16) - nutriment_amt = 3 - nutriment_desc = list("raw" = 2, "tomato" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/tomatomeat/New() - ..() - src.bitesize = 6 - -/obj/item/weapon/reagent_containers/food/snacks/bearmeat - name = "bear meat" - desc = "A very manly slab of meat." - icon_state = "bearmeat" - filling_color = "#DB0000" - center_of_mass = list("x"=16, "y"=10) - -/obj/item/weapon/reagent_containers/food/snacks/bearmeat/New() - ..() - reagents.add_reagent("protein", 12) - reagents.add_reagent("hyperzine", 5) - src.bitesize = 3 - -/obj/item/weapon/reagent_containers/food/snacks/xenomeat - name = "xenomeat" - desc = "A slab of green meat. Smells like acid." - icon_state = "xenomeat" - filling_color = "#43DE18" - center_of_mass = list("x"=16, "y"=10) - -/obj/item/weapon/reagent_containers/food/snacks/xenomeat/New() - ..() - reagents.add_reagent("protein", 6) - reagents.add_reagent("pacid",6) - src.bitesize = 6 - -/obj/item/weapon/reagent_containers/food/snacks/xenomeat/spidermeat // Substitute for recipes requiring xeno meat. - name = "spider meat" - desc = "A slab of green meat." - icon_state = "xenomeat" - filling_color = "#43DE18" - center_of_mass = list("x"=16, "y"=10) - -/obj/item/weapon/reagent_containers/food/snacks/xenomeat/spidermeat/New() - ..() - reagents.add_reagent("spidertoxin",6) - reagents.remove_reagent("pacid",6) - src.bitesize = 6 - -/obj/item/weapon/reagent_containers/food/snacks/meatball - name = "meatball" - desc = "A great meal all round." - icon_state = "meatball" - filling_color = "#DB0000" - center_of_mass = list("x"=16, "y"=16) - -/obj/item/weapon/reagent_containers/food/snacks/meatball/New() - ..() - reagents.add_reagent("protein", 3) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/sausage - name = "Sausage" - desc = "A piece of mixed, long meat." - icon_state = "sausage" - filling_color = "#DB0000" - center_of_mass = list("x"=16, "y"=16) - -/obj/item/weapon/reagent_containers/food/snacks/sausage/New() - ..() - reagents.add_reagent("protein", 6) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/donkpocket - name = "Donk-pocket" - desc = "The food of choice for the seasoned traitor." - icon_state = "donkpocket" - filling_color = "#DEDEAB" - center_of_mass = list("x"=16, "y"=10) - var/warm - var/list/heated_reagents - -/obj/item/weapon/reagent_containers/food/snacks/donkpocket/New() - ..() - reagents.add_reagent("nutriment", 2) - reagents.add_reagent("protein", 2) - - warm = 0 - heated_reagents = list("tricordrazine" = 5) - -/obj/item/weapon/reagent_containers/food/snacks/donkpocket/proc/heat() - warm = 1 - for(var/reagent in heated_reagents) - reagents.add_reagent(reagent, heated_reagents[reagent]) - bitesize = 6 - name = "Warm " + name - cooltime() - -/obj/item/weapon/reagent_containers/food/snacks/donkpocket/proc/cooltime() - if (src.warm) - spawn(4200) - src.warm = 0 - for(var/reagent in heated_reagents) - src.reagents.del_reagent(reagent) - src.name = initial(name) - return - -/obj/item/weapon/reagent_containers/food/snacks/donkpocket/sinpocket - name = "\improper Sin-pocket" - desc = "The food of choice for the veteran. Do NOT overconsume." - filling_color = "#6D6D00" - heated_reagents = list("doctorsdelight" = 5, "hyperzine" = 0.75, "synaptizine" = 0.25) - var/has_been_heated = 0 - -/obj/item/weapon/reagent_containers/food/snacks/donkpocket/sinpocket/attack_self(mob/user) - if(has_been_heated) - user << "The heating chemicals have already been spent." - return - has_been_heated = 1 - user.visible_message("[user] crushes \the [src] package.", "You crush \the [src] package and feel a comfortable heat build up.") - spawn(200) - user << "You think \the [src] is ready to eat about now." - heat() - -/obj/item/weapon/reagent_containers/food/snacks/brainburger - name = "brainburger" - desc = "A strange looking burger. It looks almost sentient." - icon_state = "brainburger" - filling_color = "#F2B6EA" - center_of_mass = list("x"=15, "y"=11) - -/obj/item/weapon/reagent_containers/food/snacks/brainburger/New() - ..() - reagents.add_reagent("protein", 6) - reagents.add_reagent("alkysine", 6) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/ghostburger - name = "Ghost Burger" - desc = "Spooky! It doesn't look very filling." - icon_state = "ghostburger" - filling_color = "#FFF2FF" - center_of_mass = list("x"=16, "y"=11) - nutriment_desc = list("buns" = 3, "spookiness" = 3) - nutriment_amt = 2 - -/obj/item/weapon/reagent_containers/food/snacks/ghostburger/New() - ..() - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/human - var/hname = "" - var/job = null - filling_color = "#D63C3C" - -/obj/item/weapon/reagent_containers/food/snacks/human/burger - name = "-burger" - desc = "A bloody burger." - icon_state = "hburger" - center_of_mass = list("x"=16, "y"=11) - -/obj/item/weapon/reagent_containers/food/snacks/human/burger/New() - ..() - reagents.add_reagent("protein", 6) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/cheeseburger - name = "cheeseburger" - desc = "The cheese adds a good flavor." - icon_state = "cheeseburger" - center_of_mass = list("x"=16, "y"=11) - nutriment_amt = 2 - nutriment_desc = list("cheese" = 2, "bun" = 2) - -/obj/item/weapon/reagent_containers/food/snacks/cheeseburger/New() - ..() - reagents.add_reagent("protein", 2) - -/obj/item/weapon/reagent_containers/food/snacks/monkeyburger - name = "burger" - desc = "The cornerstone of every nutritious breakfast." - icon_state = "hburger" - filling_color = "#D63C3C" - center_of_mass = list("x"=16, "y"=11) - nutriment_amt = 3 - nutriment_desc = list("bun" = 2) - -/obj/item/weapon/reagent_containers/food/snacks/monkeyburger/New() - ..() - reagents.add_reagent("protein", 3) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/fishburger - name = "Fillet -o- Carp Sandwich" - desc = "Almost like a carp is yelling somewhere... Give me back that fillet -o- carp, give me that carp." - icon_state = "fishburger" - filling_color = "#FFDEFE" - center_of_mass = list("x"=16, "y"=10) - -/obj/item/weapon/reagent_containers/food/snacks/fishburger/New() - ..() - reagents.add_reagent("protein", 6) - reagents.add_reagent("carpotoxin", 3) - bitesize = 3 - -/obj/item/weapon/reagent_containers/food/snacks/tofuburger - name = "Tofu Burger" - desc = "What.. is that meat?" - icon_state = "tofuburger" - filling_color = "#FFFEE0" - center_of_mass = list("x"=16, "y"=10) - nutriment_amt = 6 - nutriment_desc = list("bun" = 2, "pseudo-soy meat" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/tofuburger/New() - ..() - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/roburger - name = "roburger" - desc = "The lettuce is the only organic component. Beep." - icon_state = "roburger" - filling_color = "#CCCCCC" - center_of_mass = list("x"=16, "y"=11) - nutriment_amt = 2 - nutriment_desc = list("bun" = 2, "metal" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/roburger/New() - ..() - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/roburgerbig - name = "roburger" - desc = "This massive patty looks like poison. Beep." - icon_state = "roburger" - filling_color = "#CCCCCC" - volume = 100 - center_of_mass = list("x"=16, "y"=11) - -/obj/item/weapon/reagent_containers/food/snacks/roburgerbig/New() - ..() - bitesize = 0.1 - -/obj/item/weapon/reagent_containers/food/snacks/xenoburger - name = "xenoburger" - desc = "Smells caustic. Tastes like heresy." - icon_state = "xburger" - filling_color = "#43DE18" - center_of_mass = list("x"=16, "y"=11) - -/obj/item/weapon/reagent_containers/food/snacks/xenoburger/New() - ..() - reagents.add_reagent("protein", 8) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/clownburger - name = "Clown Burger" - desc = "This tastes funny..." - icon_state = "clownburger" - filling_color = "#FF00FF" - center_of_mass = list("x"=17, "y"=12) - nutriment_amt = 6 - nutriment_desc = list("bun" = 2, "clown shoe" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/clownburger/New() - ..() - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/mimeburger - name = "Mime Burger" - desc = "Its taste defies language." - icon_state = "mimeburger" - filling_color = "#FFFFFF" - center_of_mass = list("x"=16, "y"=11) - nutriment_amt = 6 - nutriment_desc = list("bun" = 2, "face paint" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/mimeburger/New() - ..() - reagents.add_reagent("nutriment", 6) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/omelette - name = "Omelette Du Fromage" - desc = "That's all you can say!" - icon_state = "omelette" - trash = /obj/item/trash/plate - filling_color = "#FFF9A8" - center_of_mass = list("x"=16, "y"=13) - -/obj/item/weapon/reagent_containers/food/snacks/omelette/New() - ..() - reagents.add_reagent("protein", 8) - bitesize = 1 - -/obj/item/weapon/reagent_containers/food/snacks/muffin - name = "Muffin" - desc = "A delicious and spongy little cake" - icon_state = "muffin" - filling_color = "#E0CF9B" - center_of_mass = list("x"=17, "y"=4) - nutriment_amt = 6 - nutriment_desc = list("sweetness" = 3, "muffin" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/muffin/New() - ..() - reagents.add_reagent("nutriment", 6) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/pie - name = "Banana Cream Pie" - desc = "Just like back home, on clown planet! HONK!" - icon_state = "pie" - trash = /obj/item/trash/plate - filling_color = "#FBFFB8" - center_of_mass = list("x"=16, "y"=13) - nutriment_amt = 4 - nutriment_desc = list("pie" = 3, "cream" = 2) - -/obj/item/weapon/reagent_containers/food/snacks/pie/New() - ..() - reagents.add_reagent("banana",5) - bitesize = 3 - -/obj/item/weapon/reagent_containers/food/snacks/pie/throw_impact(atom/hit_atom) - ..() - new/obj/effect/decal/cleanable/pie_smudge(src.loc) - src.visible_message("\The [src.name] splats.","You hear a splat.") - qdel(src) - -/obj/item/weapon/reagent_containers/food/snacks/berryclafoutis - name = "Berry Clafoutis" - desc = "No black birds, this is a good sign." - icon_state = "berryclafoutis" - trash = /obj/item/trash/plate - center_of_mass = list("x"=16, "y"=13) - nutriment_amt = 4 - nutriment_desc = list("sweetness" = 2, "pie" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/berryclafoutis/New() - ..() - reagents.add_reagent("berryjuice", 5) - bitesize = 3 - -/obj/item/weapon/reagent_containers/food/snacks/waffles - name = "waffles" - desc = "Mmm, waffles" - icon_state = "waffles" - trash = /obj/item/trash/waffles - filling_color = "#E6DEB5" - center_of_mass = list("x"=15, "y"=11) - nutriment_amt = 8 - nutriment_desc = list("waffle" = 8) - -/obj/item/weapon/reagent_containers/food/snacks/waffles/New() - ..() - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/eggplantparm - name = "Eggplant Parmigiana" - desc = "The only good recipe for eggplant." - icon_state = "eggplantparm" - trash = /obj/item/trash/plate - filling_color = "#4D2F5E" - center_of_mass = list("x"=16, "y"=11) - nutriment_amt = 6 - nutriment_desc = list("cheese" = 3, "eggplant" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/eggplantparm/New() - ..() - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/soylentgreen - name = "Soylent Green" - desc = "Not made of people. Honest." //Totally people. - icon_state = "soylent_green" - trash = /obj/item/trash/waffles - filling_color = "#B8E6B5" - center_of_mass = list("x"=15, "y"=11) - -/obj/item/weapon/reagent_containers/food/snacks/soylentgreen/New() - ..() - reagents.add_reagent("protein", 10) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/soylenviridians - name = "Soylen Virdians" - desc = "Not made of people. Honest." //Actually honest for once. - icon_state = "soylent_yellow" - trash = /obj/item/trash/waffles - filling_color = "#E6FA61" - center_of_mass = list("x"=15, "y"=11) - nutriment_amt = 10 - nutriment_desc = list("some sort of protein" = 10) //seasoned VERY well. - -/obj/item/weapon/reagent_containers/food/snacks/soylenviridians/New() - ..() - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/meatpie - name = "Meat-pie" - icon_state = "meatpie" - desc = "An old barber recipe, very delicious!" - trash = /obj/item/trash/plate - filling_color = "#948051" - center_of_mass = list("x"=16, "y"=13) - -/obj/item/weapon/reagent_containers/food/snacks/meatpie/New() - ..() - reagents.add_reagent("protein", 10) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/tofupie - name = "Tofu-pie" - icon_state = "meatpie" - desc = "A delicious tofu pie." - trash = /obj/item/trash/plate - filling_color = "#FFFEE0" - center_of_mass = list("x"=16, "y"=13) - nutriment_amt = 10 - nutriment_desc = list("tofu" = 2, "pie" = 8) - -/obj/item/weapon/reagent_containers/food/snacks/tofupie/New() - ..() - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/amanita_pie - name = "amanita pie" - desc = "Sweet and tasty poison pie." - icon_state = "amanita_pie" - filling_color = "#FFCCCC" - center_of_mass = list("x"=17, "y"=9) - nutriment_amt = 5 - nutriment_desc = list("sweetness" = 3, "mushroom" = 3, "pie" = 2) - -/obj/item/weapon/reagent_containers/food/snacks/amanita_pie/New() - ..() - reagents.add_reagent("amatoxin", 3) - reagents.add_reagent("psilocybin", 1) - bitesize = 3 - -/obj/item/weapon/reagent_containers/food/snacks/plump_pie - name = "plump pie" - desc = "I bet you love stuff made out of plump helmets!" - icon_state = "plump_pie" - filling_color = "#B8279B" - center_of_mass = list("x"=17, "y"=9) - nutriment_amt = 8 - nutriment_desc = list("heartiness" = 2, "mushroom" = 3, "pie" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/plump_pie/New() - ..() - if(prob(10)) - name = "exceptional plump pie" - desc = "Microwave is taken by a fey mood! It has cooked an exceptional plump pie!" - reagents.add_reagent("nutriment", 8) - reagents.add_reagent("tricordrazine", 5) - bitesize = 2 - else - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/xemeatpie - name = "Xeno-pie" - icon_state = "xenomeatpie" - desc = "A delicious meatpie. Probably heretical." - trash = /obj/item/trash/plate - filling_color = "#43DE18" - center_of_mass = list("x"=16, "y"=13) - -/obj/item/weapon/reagent_containers/food/snacks/xemeatpie/New() - ..() - reagents.add_reagent("protein", 10) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/wingfangchu - name = "Wing Fang Chu" - desc = "A savory dish of alien wing wang in soy." - icon_state = "wingfangchu" - trash = /obj/item/trash/snack_bowl - filling_color = "#43DE18" - center_of_mass = list("x"=17, "y"=9) - -/obj/item/weapon/reagent_containers/food/snacks/wingfangchu/New() - ..() - reagents.add_reagent("protein", 6) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/human/kabob - name = "-kabob" - icon_state = "kabob" - desc = "A human meat, on a stick." - trash = /obj/item/stack/rods - filling_color = "#A85340" - center_of_mass = list("x"=17, "y"=15) - -/obj/item/weapon/reagent_containers/food/snacks/human/kabob/New() - ..() - reagents.add_reagent("protein", 8) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/monkeykabob - name = "Meat-kabob" - icon_state = "kabob" - desc = "Delicious meat, on a stick." - trash = /obj/item/stack/rods - filling_color = "#A85340" - center_of_mass = list("x"=17, "y"=15) - -/obj/item/weapon/reagent_containers/food/snacks/monkeykabob/New() - ..() - reagents.add_reagent("protein", 8) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/tofukabob - name = "Tofu-kabob" - icon_state = "kabob" - desc = "Vegan meat, on a stick." - trash = /obj/item/stack/rods - filling_color = "#FFFEE0" - - center_of_mass = list("x"=17, "y"=15) - nutriment_amt = 8 - nutriment_desc = list("tofu" = 3, "metal" = 1) - -/obj/item/weapon/reagent_containers/food/snacks/tofukabob/New() - ..() - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/cubancarp - name = "Cuban Carp" - desc = "A sandwich that burns your tongue and then leaves it numb!" - icon_state = "cubancarp" - trash = /obj/item/trash/plate - filling_color = "#E9ADFF" - center_of_mass = list("x"=12, "y"=5) - nutriment_amt = 3 - nutriment_desc = list("toasted bread" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/cubancarp/New() - ..() - reagents.add_reagent("protein", 3) - reagents.add_reagent("carpotoxin", 3) - reagents.add_reagent("capsaicin", 3) - bitesize = 3 - -/obj/item/weapon/reagent_containers/food/snacks/popcorn - name = "Popcorn" - desc = "Now let's find some cinema." - icon_state = "popcorn" - trash = /obj/item/trash/popcorn - var/unpopped = 0 - filling_color = "#FFFAD4" - center_of_mass = list("x"=16, "y"=8) - nutriment_amt = 2 - nutriment_desc = list("popcorn" = 3) - - -/obj/item/weapon/reagent_containers/food/snacks/popcorn/New() - ..() - unpopped = rand(1,10) - bitesize = 0.1 //this snack is supposed to be eating during looooong time. And this it not dinner food! --rastaf0 - -/obj/item/weapon/reagent_containers/food/snacks/popcorn/On_Consume() - if(prob(unpopped)) //lol ...what's the point? - usr << "You bite down on an un-popped kernel!" - unpopped = max(0, unpopped-1) - ..() - -/obj/item/weapon/reagent_containers/food/snacks/sosjerky - name = "Scaredy's Private Reserve Beef Jerky" - icon_state = "sosjerky" - desc = "Beef jerky made from the finest space cows." - trash = /obj/item/trash/sosjerky - filling_color = "#631212" - center_of_mass = list("x"=15, "y"=9) - -/obj/item/weapon/reagent_containers/food/snacks/sosjerky/New() - ..() - reagents.add_reagent("protein", 4) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/no_raisin - name = "4no Raisins" - icon_state = "4no_raisins" - desc = "Best raisins in the universe. Not sure why." - trash = /obj/item/trash/raisins - filling_color = "#343834" - center_of_mass = list("x"=15, "y"=4) - nutriment_amt = 6 - nutriment_desc = list("dried raisins" = 6) - -/obj/item/weapon/reagent_containers/food/snacks/no_raisin/New() - ..() - reagents.add_reagent("nutriment", 6) - -/obj/item/weapon/reagent_containers/food/snacks/spacetwinkie - name = "Space Twinkie" - icon_state = "space_twinkie" - desc = "Guaranteed to survive longer then you will." - filling_color = "#FFE591" - center_of_mass = list("x"=15, "y"=11) - -/obj/item/weapon/reagent_containers/food/snacks/spacetwinkie/New() - ..() - reagents.add_reagent("sugar", 4) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers - name = "Cheesie Honkers" - icon_state = "cheesie_honkers" - desc = "Bite sized cheesie snacks that will honk all over your mouth" - trash = /obj/item/trash/cheesie - filling_color = "#FFA305" - center_of_mass = list("x"=15, "y"=9) - nutriment_amt = 4 - nutriment_desc = list("cheese" = 5, "chips" = 2) - -/obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers/New() - ..() - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/syndicake - name = "Syndi-Cakes" - icon_state = "syndi_cakes" - desc = "An extremely moist snack cake that tastes just as good after being nuked." - filling_color = "#FF5D05" - center_of_mass = list("x"=16, "y"=10) - trash = /obj/item/trash/syndi_cakes - nutriment_amt = 4 - nutriment_desc = list("sweetness" = 3, "cake" = 1) - -/obj/item/weapon/reagent_containers/food/snacks/syndicake/New() - ..() - reagents.add_reagent("doctorsdelight", 5) - bitesize = 3 - -/obj/item/weapon/reagent_containers/food/snacks/loadedbakedpotato - name = "Loaded Baked Potato" - desc = "Totally baked." - icon_state = "loadedbakedpotato" - filling_color = "#9C7A68" - center_of_mass = list("x"=16, "y"=10) - nutriment_amt = 3 - nutriment_desc = list("baked potato" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/loadedbakedpotato/New() - ..() - reagents.add_reagent("protein", 3) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/fries - name = "Space Fries" - desc = "AKA: French Fries, Freedom Fries, etc." - icon_state = "fries" - trash = /obj/item/trash/plate - filling_color = "#EDDD00" - center_of_mass = list("x"=16, "y"=11) - nutriment_amt = 4 - nutriment_desc = list("fresh fries" = 4) - -/obj/item/weapon/reagent_containers/food/snacks/fries/New() - ..() - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/mashedpotato - name = "Mashed Potato" - desc = "Pillowy mounds of mashed potato." - icon_state = "mashedpotato" - trash = /obj/item/trash/plate - filling_color = "#EDDD00" - center_of_mass = list("x"=16, "y"=11) - nutriment_amt = 4 - nutriment_desc = list("fluffy mashed potatoes" = 4) - -/obj/item/weapon/reagent_containers/food/snacks/mashedpotato/New() - ..() - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/bangersandmash - name = "Bangers and Mash" - desc = "An English treat." - icon_state = "bangersandmash" - trash = /obj/item/trash/plate - filling_color = "#EDDD00" - center_of_mass = list("x"=16, "y"=11) - nutriment_amt = 4 - nutriment_desc = list("fluffy potato" = 3, "sausage" = 2) - -/obj/item/weapon/reagent_containers/food/snacks/bangersandmash/New() - ..() - reagents.add_reagent("protein", 3) - bitesize = 4 - -/obj/item/weapon/reagent_containers/food/snacks/cheesymash - name = "Cheesy Mashed Potato" - desc = "The only thing that could make mash better." - icon_state = "cheesymash" - trash = /obj/item/trash/plate - filling_color = "#EDDD00" - center_of_mass = list("x"=16, "y"=11) - nutriment_amt = 4 - nutriment_desc = list("cheesy potato" = 4) - -/obj/item/weapon/reagent_containers/food/snacks/cheesymash/New() - ..() - reagents.add_reagent("protein", 3) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/blackpudding - name = "Black Pudding" - desc = "This doesn't seem like a pudding at all." - icon_state = "blackpudding" - filling_color = "#FF0000" - center_of_mass = list("x"=16, "y"=7) - -/obj/item/weapon/reagent_containers/food/snacks/blackpudding/New() - ..() - reagents.add_reagent("protein", 2) - reagents.add_reagent("blood", 5) - bitesize = 3 - -/obj/item/weapon/reagent_containers/food/snacks/soydope - name = "Soy Dope" - desc = "Dope from a soy." - icon_state = "soydope" - trash = /obj/item/trash/plate - filling_color = "#C4BF76" - center_of_mass = list("x"=16, "y"=10) - nutriment_amt = 2 - nutriment_desc = list("slime" = 2, "soy" = 2) - -/obj/item/weapon/reagent_containers/food/snacks/soydope/New() - ..() - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/spagetti - name = "Spaghetti" - desc = "A bundle of raw spaghetti." - icon_state = "spagetti" - filling_color = "#EDDD00" - center_of_mass = list("x"=16, "y"=16) - nutriment_amt = 1 - nutriment_desc = list("noodles" = 2) - -/obj/item/weapon/reagent_containers/food/snacks/spagetti/New() - ..() - bitesize = 1 - -/obj/item/weapon/reagent_containers/food/snacks/cheesyfries - name = "Cheesy Fries" - desc = "Fries. Covered in cheese. Duh." - icon_state = "cheesyfries" - trash = /obj/item/trash/plate - filling_color = "#EDDD00" - center_of_mass = list("x"=16, "y"=11) - nutriment_amt = 4 - nutriment_desc = list("fresh fries" = 3, "cheese" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/cheesyfries/New() - ..() - reagents.add_reagent("protein", 2) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/fortunecookie - name = "Fortune cookie" - desc = "A true prophecy in each cookie!" - icon_state = "fortune_cookie" - filling_color = "#E8E79E" - center_of_mass = list("x"=15, "y"=14) - nutriment_amt = 3 - nutriment_desc = list("fortune cookie" = 2) - -/obj/item/weapon/reagent_containers/food/snacks/fortunecookie/New() - ..() - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/badrecipe - name = "Burned mess" - desc = "Someone should be demoted from chef for this." - icon_state = "badrecipe" - filling_color = "#211F02" - center_of_mass = list("x"=16, "y"=12) - -/obj/item/weapon/reagent_containers/food/snacks/badrecipe/New() - ..() - reagents.add_reagent("toxin", 1) - reagents.add_reagent("carbon", 3) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/meatsteak - name = "Meat steak" - desc = "A piece of hot spicy meat." - icon_state = "meatstake" - trash = /obj/item/trash/plate - filling_color = "#7A3D11" - center_of_mass = list("x"=16, "y"=13) - -/obj/item/weapon/reagent_containers/food/snacks/meatsteak/New() - ..() - reagents.add_reagent("protein", 4) - reagents.add_reagent("sodiumchloride", 1) - reagents.add_reagent("blackpepper", 1) - bitesize = 3 - -/obj/item/weapon/reagent_containers/food/snacks/spacylibertyduff - name = "Spacy Liberty Duff" - desc = "Jello gelatin, from Alfred Hubbard's cookbook" - icon_state = "spacylibertyduff" - trash = /obj/item/trash/snack_bowl - filling_color = "#42B873" - center_of_mass = list("x"=16, "y"=8) - nutriment_amt = 6 - nutriment_desc = list("mushroom" = 6) - -/obj/item/weapon/reagent_containers/food/snacks/spacylibertyduff/New() - ..() - reagents.add_reagent("psilocybin", 6) - bitesize = 3 - -/obj/item/weapon/reagent_containers/food/snacks/amanitajelly - name = "Amanita Jelly" - desc = "Looks curiously toxic" - icon_state = "amanitajelly" - trash = /obj/item/trash/snack_bowl - filling_color = "#ED0758" - center_of_mass = list("x"=16, "y"=5) - nutriment_amt = 6 - nutriment_desc = list("jelly" = 3, "mushroom" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/amanitajelly/New() - ..() - reagents.add_reagent("amatoxin", 6) - reagents.add_reagent("psilocybin", 3) - bitesize = 3 - -/obj/item/weapon/reagent_containers/food/snacks/poppypretzel - name = "Poppy pretzel" - desc = "It's all twisted up!" - icon_state = "poppypretzel" - bitesize = 2 - filling_color = "#916E36" - center_of_mass = list("x"=16, "y"=10) - nutriment_amt = 5 - nutriment_desc = list("poppy seeds" = 2, "pretzel" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/poppypretzel/New() - ..() - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/meatballsoup - name = "Meatball soup" - desc = "You've got balls kid, BALLS!" - icon_state = "meatballsoup" - trash = /obj/item/trash/snack_bowl - filling_color = "#785210" - center_of_mass = list("x"=16, "y"=8) - -/obj/item/weapon/reagent_containers/food/snacks/meatballsoup/New() - ..() - reagents.add_reagent("protein", 8) - reagents.add_reagent("water", 5) - bitesize = 5 - -/obj/item/weapon/reagent_containers/food/snacks/slimesoup - name = "slime soup" - desc = "If no water is available, you may substitute tears." - icon_state = "slimesoup" //nonexistant? - filling_color = "#C4DBA0" - -/obj/item/weapon/reagent_containers/food/snacks/slimesoup/New() - ..() - reagents.add_reagent("slimejelly", 5) - reagents.add_reagent("water", 10) - bitesize = 5 - -/obj/item/weapon/reagent_containers/food/snacks/bloodsoup - name = "Tomato soup" - desc = "Smells like copper." - icon_state = "tomatosoup" - filling_color = "#FF0000" - center_of_mass = list("x"=16, "y"=7) - -/obj/item/weapon/reagent_containers/food/snacks/bloodsoup/New() - ..() - reagents.add_reagent("protein", 2) - reagents.add_reagent("blood", 10) - reagents.add_reagent("water", 5) - bitesize = 5 - -/obj/item/weapon/reagent_containers/food/snacks/clownstears - name = "Clown's Tears" - desc = "Not very funny." - icon_state = "clownstears" - filling_color = "#C4FBFF" - center_of_mass = list("x"=16, "y"=7) - nutriment_amt = 4 - nutriment_desc = list("salt" = 1, "the worst joke" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/clownstears/New() - ..() - reagents.add_reagent("banana", 5) - reagents.add_reagent("water", 10) - bitesize = 5 - -/obj/item/weapon/reagent_containers/food/snacks/vegetablesoup - name = "Vegetable soup" - desc = "A true vegan meal" //TODO - icon_state = "vegetablesoup" - trash = /obj/item/trash/snack_bowl - filling_color = "#AFC4B5" - center_of_mass = list("x"=16, "y"=8) - nutriment_amt = 8 - nutriment_desc = list("carot" = 2, "corn" = 2, "eggplant" = 2, "potato" = 2) - -/obj/item/weapon/reagent_containers/food/snacks/vegetablesoup/New() - ..() - reagents.add_reagent("water", 5) - bitesize = 5 - -/obj/item/weapon/reagent_containers/food/snacks/nettlesoup - name = "Nettle soup" - desc = "To think, the botanist would've beat you to death with one of these." - icon_state = "nettlesoup" - trash = /obj/item/trash/snack_bowl - filling_color = "#AFC4B5" - center_of_mass = list("x"=16, "y"=7) - nutriment_amt = 8 - nutriment_desc = list("salad" = 4, "egg" = 2, "potato" = 2) - -/obj/item/weapon/reagent_containers/food/snacks/nettlesoup/New() - ..() - reagents.add_reagent("water", 5) - reagents.add_reagent("tricordrazine", 5) - bitesize = 5 - -/obj/item/weapon/reagent_containers/food/snacks/mysterysoup - name = "Mystery soup" - desc = "The mystery is, why aren't you eating it?" - icon_state = "mysterysoup" - trash = /obj/item/trash/snack_bowl - filling_color = "#F082FF" - center_of_mass = list("x"=16, "y"=6) - nutriment_amt = 1 - nutriment_desc = list("backwash" = 1) - -/obj/item/weapon/reagent_containers/food/snacks/mysterysoup/New() - ..() - var/mysteryselect = pick(1,2,3,4,5,6,7,8,9,10) - switch(mysteryselect) - if(1) - reagents.add_reagent("nutriment", 6) - reagents.add_reagent("capsaicin", 3) - reagents.add_reagent("tomatojuice", 2) - if(2) - reagents.add_reagent("nutriment", 6) - reagents.add_reagent("frostoil", 3) - reagents.add_reagent("tomatojuice", 2) - if(3) - reagents.add_reagent("nutriment", 5) - reagents.add_reagent("water", 5) - reagents.add_reagent("tricordrazine", 5) - if(4) - reagents.add_reagent("nutriment", 5) - reagents.add_reagent("water", 10) - if(5) - reagents.add_reagent("nutriment", 2) - reagents.add_reagent("banana", 10) - if(6) - reagents.add_reagent("nutriment", 6) - reagents.add_reagent("blood", 10) - if(7) - reagents.add_reagent("slimejelly", 10) - reagents.add_reagent("water", 10) - if(8) - reagents.add_reagent("carbon", 10) - reagents.add_reagent("toxin", 10) - if(9) - reagents.add_reagent("nutriment", 5) - reagents.add_reagent("tomatojuice", 10) - if(10) - reagents.add_reagent("nutriment", 6) - reagents.add_reagent("tomatojuice", 5) - reagents.add_reagent("imidazoline", 5) - bitesize = 5 - -/obj/item/weapon/reagent_containers/food/snacks/wishsoup - name = "Wish Soup" - desc = "I wish this was soup." - icon_state = "wishsoup" - trash = /obj/item/trash/snack_bowl - filling_color = "#D1F4FF" - center_of_mass = list("x"=16, "y"=11) - -/obj/item/weapon/reagent_containers/food/snacks/wishsoup/New() - ..() - reagents.add_reagent("water", 10) - bitesize = 5 - if(prob(25)) - src.desc = "A wish come true!" - reagents.add_reagent("nutriment", 8, list("something good" = 8)) - -/obj/item/weapon/reagent_containers/food/snacks/hotchili - name = "Hot Chili" - desc = "A five alarm Texan Chili!" - icon_state = "hotchili" - trash = /obj/item/trash/snack_bowl - filling_color = "#FF3C00" - center_of_mass = list("x"=15, "y"=9) - nutriment_amt = 3 - nutriment_desc = list("chilli peppers" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/hotchili/New() - ..() - reagents.add_reagent("protein", 3) - reagents.add_reagent("capsaicin", 3) - reagents.add_reagent("tomatojuice", 2) - bitesize = 5 - -/obj/item/weapon/reagent_containers/food/snacks/coldchili - name = "Cold Chili" - desc = "This slush is barely a liquid!" - icon_state = "coldchili" - filling_color = "#2B00FF" - center_of_mass = list("x"=15, "y"=9) - trash = /obj/item/trash/snack_bowl - nutriment_amt = 3 - nutriment_desc = list("ice peppers" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/coldchili/New() - ..() - reagents.add_reagent("protein", 3) - reagents.add_reagent("frostoil", 3) - reagents.add_reagent("tomatojuice", 2) - bitesize = 5 - -/obj/item/weapon/reagent_containers/food/snacks/monkeycube - name = "monkey cube" - desc = "Just add water!" - flags = OPENCONTAINER - icon_state = "monkeycube" - bitesize = 12 - filling_color = "#ADAC7F" - center_of_mass = list("x"=16, "y"=14) - - var/wrapped = 0 - var/monkey_type = "Monkey" - -/obj/item/weapon/reagent_containers/food/snacks/monkeycube/New() - ..() - reagents.add_reagent("protein", 10) - -/obj/item/weapon/reagent_containers/food/snacks/monkeycube/attack_self(mob/user as mob) - if(wrapped) - Unwrap(user) - -/obj/item/weapon/reagent_containers/food/snacks/monkeycube/proc/Expand() - src.visible_message("\The [src] expands!") - var/mob/living/carbon/human/H = new(get_turf(src)) - H.set_species(monkey_type) - H.real_name = H.species.get_random_name() - H.name = H.real_name - if(ismob(loc)) - var/mob/M = loc - M.unEquip(src) - qdel(src) - return 1 - -/obj/item/weapon/reagent_containers/food/snacks/monkeycube/proc/Unwrap(mob/user as mob) - icon_state = "monkeycube" - desc = "Just add water!" - to_chat(user, "You unwrap the cube.") - wrapped = 0 - flags |= OPENCONTAINER - return - -/obj/item/weapon/reagent_containers/food/snacks/monkeycube/On_Consume(var/mob/M) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - H.visible_message("A screeching creature bursts out of [M]'s chest!") - var/obj/item/organ/external/organ = H.get_organ(BP_TORSO) - organ.take_damage(50, 0, 0, "Animal escaping the ribcage") - Expand() - -/obj/item/weapon/reagent_containers/food/snacks/monkeycube/on_reagent_change() - if(reagents.has_reagent("water")) - Expand() - -/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped - desc = "Still wrapped in some paper." - icon_state = "monkeycubewrap" - flags = 0 - wrapped = 1 - -/obj/item/weapon/reagent_containers/food/snacks/monkeycube/farwacube - name = "farwa cube" - monkey_type = "Farwa" - -/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/farwacube - name = "farwa cube" - monkey_type = "Farwa" - -/obj/item/weapon/reagent_containers/food/snacks/monkeycube/stokcube - name = "stok cube" - monkey_type = "Stok" - -/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/stokcube - name = "stok cube" - monkey_type = "Stok" - -/obj/item/weapon/reagent_containers/food/snacks/monkeycube/neaeracube - name = "neaera cube" - monkey_type = "Neaera" - -/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/neaeracube - name = "neaera cube" - monkey_type = "Neaera" - -/obj/item/weapon/reagent_containers/food/snacks/spellburger - name = "Spell Burger" - desc = "This is absolutely Ei Nath." - icon_state = "spellburger" - filling_color = "#D505FF" - nutriment_amt = 6 - nutriment_desc = list("magic" = 3, "buns" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/spellburger/New() - ..() - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/bigbiteburger - name = "Big Bite Burger" - desc = "Forget the Big Mac. THIS is the future!" - icon_state = "bigbiteburger" - filling_color = "#E3D681" - center_of_mass = list("x"=16, "y"=11) - nutriment_amt = 4 - nutriment_desc = list("buns" = 4) - -/obj/item/weapon/reagent_containers/food/snacks/bigbiteburger/New() - ..() - reagents.add_reagent("protein", 10) - bitesize = 3 - -/obj/item/weapon/reagent_containers/food/snacks/enchiladas - name = "Enchiladas" - desc = "Viva La Mexico!" - icon_state = "enchiladas" - trash = /obj/item/trash/tray - filling_color = "#A36A1F" - center_of_mass = list("x"=16, "y"=13) - nutriment_amt = 2 - nutriment_desc = list("tortilla" = 3, "corn" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/enchiladas/New() - ..() - reagents.add_reagent("protein", 6) - reagents.add_reagent("capsaicin", 6) - bitesize = 4 - -/obj/item/weapon/reagent_containers/food/snacks/monkeysdelight - name = "monkey's Delight" - desc = "Eeee Eee!" - icon_state = "monkeysdelight" - trash = /obj/item/trash/tray - filling_color = "#5C3C11" - center_of_mass = list("x"=16, "y"=13) - -/obj/item/weapon/reagent_containers/food/snacks/monkeysdelight/New() - ..() - reagents.add_reagent("protein", 10) - reagents.add_reagent("banana", 5) - reagents.add_reagent("blackpepper", 1) - reagents.add_reagent("sodiumchloride", 1) - bitesize = 6 - -/obj/item/weapon/reagent_containers/food/snacks/baguette - name = "Baguette" - desc = "Bon appetit!" - icon_state = "baguette" - filling_color = "#E3D796" - center_of_mass = list("x"=18, "y"=12) - nutriment_amt = 6 - nutriment_desc = list("french bread" = 6) - -/obj/item/weapon/reagent_containers/food/snacks/baguette/New() - ..() - reagents.add_reagent("blackpepper", 1) - reagents.add_reagent("sodiumchloride", 1) - bitesize = 3 - -/obj/item/weapon/reagent_containers/food/snacks/fishandchips - name = "Fish and Chips" - desc = "I do say so myself chap." - icon_state = "fishandchips" - filling_color = "#E3D796" - center_of_mass = list("x"=16, "y"=16) - nutriment_amt = 3 - nutriment_desc = list("salt" = 1, "chips" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/fishandchips/New() - ..() - reagents.add_reagent("protein", 3) - reagents.add_reagent("carpotoxin", 3) - bitesize = 3 - -/obj/item/weapon/reagent_containers/food/snacks/sandwich - name = "Sandwich" - desc = "A grand creation of meat, cheese, bread, and several leaves of lettuce! Arthur Dent would be proud." - icon_state = "sandwich" - trash = /obj/item/trash/plate - filling_color = "#D9BE29" - center_of_mass = list("x"=16, "y"=4) - nutriment_amt = 3 - nutriment_desc = list("bread" = 3, "cheese" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/sandwich/New() - ..() - reagents.add_reagent("protein", 3) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/toastedsandwich - name = "Toasted Sandwich" - desc = "Now if you only had a pepper bar." - icon_state = "toastedsandwich" - trash = /obj/item/trash/plate - filling_color = "#D9BE29" - center_of_mass = list("x"=16, "y"=4) - nutriment_amt = 3 - nutriment_desc = list("toasted bread" = 3, "cheese" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/toastedsandwich/New() - ..() - reagents.add_reagent("protein", 3) - reagents.add_reagent("carbon", 2) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/grilledcheese - name = "Grilled Cheese Sandwich" - desc = "Goes great with Tomato soup!" - icon_state = "toastedsandwich" - trash = /obj/item/trash/plate - filling_color = "#D9BE29" - nutriment_amt = 3 - nutriment_desc = list("toasted bread" = 3, "cheese" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/grilledcheese/New() - ..() - reagents.add_reagent("protein", 4) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/tomatosoup - name = "Tomato Soup" - desc = "Drinking this feels like being a vampire! A tomato vampire..." - icon_state = "tomatosoup" - trash = /obj/item/trash/snack_bowl - filling_color = "#D92929" - center_of_mass = list("x"=16, "y"=7) - nutriment_amt = 5 - nutriment_desc = list("soup" = 5) - -/obj/item/weapon/reagent_containers/food/snacks/tomatosoup/New() - ..() - reagents.add_reagent("tomatojuice", 10) - bitesize = 3 - -/obj/item/weapon/reagent_containers/food/snacks/onionsoup - name = "Onion Soup" - desc = "A soup with layers." - icon_state = "onionsoup" - trash = /obj/item/trash/snack_bowl - filling_color = "#E0C367" - center_of_mass = list("x"=16, "y"=7) - nutriment_amt = 5 - nutriment_desc = list("onion" = 2, "soup" = 2) - -/obj/item/weapon/reagent_containers/food/snacks/onionsoup/New() - ..() - bitesize = 3 - -/obj/item/weapon/reagent_containers/food/snacks/onionrings - name = "Onion Rings" - desc = "Crispy rings." - icon_state = "onionrings" - trash = /obj/item/trash/plate - filling_color = "#E0C367" - center_of_mass = list("x"=16, "y"=7) - nutriment_amt = 5 - nutriment_desc = list("onion" = 2) - -/obj/item/weapon/reagent_containers/food/snacks/onionrings/New() - ..() - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/rofflewaffles - name = "Roffle Waffles" - desc = "Waffles from Roffle. Co." - icon_state = "rofflewaffles" - trash = /obj/item/trash/waffles - filling_color = "#FF00F7" - center_of_mass = list("x"=15, "y"=11) - nutriment_amt = 8 - nutriment_desc = list("waffle" = 7, "sweetness" = 1) - -/obj/item/weapon/reagent_containers/food/snacks/rofflewaffles/New() - ..() - reagents.add_reagent("psilocybin", 8) - bitesize = 4 - -/obj/item/weapon/reagent_containers/food/snacks/stew - name = "Stew" - desc = "A nice and warm stew. Healthy and strong." - icon_state = "stew" - filling_color = "#9E673A" - center_of_mass = list("x"=16, "y"=5) - nutriment_amt = 6 - nutriment_desc = list("tomato" = 2, "potato" = 2, "carrot" = 2, "eggplant" = 2, "mushroom" = 2) - -/obj/item/weapon/reagent_containers/food/snacks/stew/New() - ..() - reagents.add_reagent("protein", 4) - reagents.add_reagent("tomatojuice", 5) - reagents.add_reagent("imidazoline", 5) - reagents.add_reagent("water", 5) - bitesize = 10 - -/obj/item/weapon/reagent_containers/food/snacks/jelliedtoast - name = "Jellied Toast" - desc = "A slice of bread covered with delicious jam." - icon_state = "jellytoast" - trash = /obj/item/trash/plate - filling_color = "#B572AB" - center_of_mass = list("x"=16, "y"=8) - nutriment_amt = 1 - nutriment_desc = list("toasted bread" = 2) - -/obj/item/weapon/reagent_containers/food/snacks/jelliedtoast/New() - ..() - bitesize = 3 - -/obj/item/weapon/reagent_containers/food/snacks/jelliedtoast/cherry/New() - ..() - reagents.add_reagent("cherryjelly", 5) - -/obj/item/weapon/reagent_containers/food/snacks/jelliedtoast/slime/New() - ..() - reagents.add_reagent("slimejelly", 5) - -/obj/item/weapon/reagent_containers/food/snacks/jellyburger - name = "Jelly Burger" - desc = "Culinary delight..?" - icon_state = "jellyburger" - filling_color = "#B572AB" - center_of_mass = list("x"=16, "y"=11) - nutriment_amt = 5 - nutriment_desc = list("buns" = 5) - -/obj/item/weapon/reagent_containers/food/snacks/jellyburger/New() - ..() - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/jellyburger/slime/New() - ..() - reagents.add_reagent("slimejelly", 5) - -/obj/item/weapon/reagent_containers/food/snacks/jellyburger/cherry/New() - ..() - reagents.add_reagent("cherryjelly", 5) - -/obj/item/weapon/reagent_containers/food/snacks/milosoup - name = "Milosoup" - desc = "The universes best soup! Yum!!!" - icon_state = "milosoup" - trash = /obj/item/trash/snack_bowl - center_of_mass = list("x"=16, "y"=7) - nutriment_amt = 8 - nutriment_desc = list("soy" = 8) - -/obj/item/weapon/reagent_containers/food/snacks/milosoup/New() - ..() - reagents.add_reagent("water", 5) - bitesize = 4 - -/obj/item/weapon/reagent_containers/food/snacks/stewedsoymeat - name = "Stewed Soy Meat" - desc = "Even non-vegetarians will LOVE this!" - icon_state = "stewedsoymeat" - trash = /obj/item/trash/plate - center_of_mass = list("x"=16, "y"=10) - nutriment_amt = 8 - nutriment_desc = list("soy" = 4, "tomato" = 4) - -/obj/item/weapon/reagent_containers/food/snacks/stewedsoymeat/New() - ..() - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/boiledspagetti - name = "Boiled Spaghetti" - desc = "A plain dish of noodles, this sucks." - icon_state = "spagettiboiled" - trash = /obj/item/trash/plate - filling_color = "#FCEE81" - center_of_mass = list("x"=16, "y"=10) - nutriment_amt = 2 - nutriment_desc = list("noodles" = 2) - -/obj/item/weapon/reagent_containers/food/snacks/boiledspagetti/New() - ..() - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/boiledrice - name = "Boiled Rice" - desc = "A boring dish of boring rice." - icon_state = "boiledrice" - trash = /obj/item/trash/snack_bowl - filling_color = "#FFFBDB" - center_of_mass = list("x"=17, "y"=11) - nutriment_amt = 2 - nutriment_desc = list("rice" = 2) - -/obj/item/weapon/reagent_containers/food/snacks/boiledrice/New() - ..() - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/ricepudding - name = "Rice Pudding" - desc = "Where's the jam?" - icon_state = "rpudding" - trash = /obj/item/trash/snack_bowl - filling_color = "#FFFBDB" - center_of_mass = list("x"=17, "y"=11) - nutriment_amt = 4 - nutriment_desc = list("rice" = 2) - -/obj/item/weapon/reagent_containers/food/snacks/ricepudding/New() - ..() - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/pastatomato - name = "Spaghetti" - desc = "Spaghetti and crushed tomatoes. Just like your abusive father used to make!" - icon_state = "pastatomato" - trash = /obj/item/trash/plate - filling_color = "#DE4545" - center_of_mass = list("x"=16, "y"=10) - nutriment_amt = 6 - nutriment_desc = list("tomato" = 3, "noodles" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/pastatomato/New() - ..() - reagents.add_reagent("tomatojuice", 10) - bitesize = 4 - -/obj/item/weapon/reagent_containers/food/snacks/meatballspagetti - name = "Spaghetti & Meatballs" - desc = "Now thats a nic'e meatball!" - icon_state = "meatballspagetti" - trash = /obj/item/trash/plate - filling_color = "#DE4545" - center_of_mass = list("x"=16, "y"=10) - nutriment_amt = 4 - nutriment_desc = list("noodles" = 4) - -/obj/item/weapon/reagent_containers/food/snacks/meatballspagetti/New() - ..() - reagents.add_reagent("protein", 4) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/spesslaw - name = "Spesslaw" - desc = "A lawyers favourite" - icon_state = "spesslaw" - filling_color = "#DE4545" - center_of_mass = list("x"=16, "y"=10) - nutriment_amt = 4 - nutriment_desc = list("noodles" = 4) - -/obj/item/weapon/reagent_containers/food/snacks/spesslaw/New() - ..() - reagents.add_reagent("protein", 4) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/carrotfries - name = "Carrot Fries" - desc = "Tasty fries from fresh Carrots." - icon_state = "carrotfries" - trash = /obj/item/trash/plate - filling_color = "#FAA005" - center_of_mass = list("x"=16, "y"=11) - nutriment_amt = 3 - nutriment_desc = list("carrot" = 3, "salt" = 1) - -/obj/item/weapon/reagent_containers/food/snacks/carrotfries/New() - ..() - reagents.add_reagent("imidazoline", 3) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/superbiteburger - name = "Super Bite Burger" - desc = "This is a mountain of a burger. FOOD!" - icon_state = "superbiteburger" - filling_color = "#CCA26A" - center_of_mass = list("x"=16, "y"=3) - nutriment_amt = 25 - nutriment_desc = list("buns" = 25) - -/obj/item/weapon/reagent_containers/food/snacks/superbiteburger/New() - ..() - reagents.add_reagent("protein", 25) - bitesize = 10 - -/obj/item/weapon/reagent_containers/food/snacks/candiedapple - name = "Candied Apple" - desc = "An apple coated in sugary sweetness." - icon_state = "candiedapple" - filling_color = "#F21873" - center_of_mass = list("x"=15, "y"=13) - nutriment_amt = 3 - nutriment_desc = list("apple" = 3, "caramel" = 3, "sweetness" = 2) - -/obj/item/weapon/reagent_containers/food/snacks/candiedapple/New() - ..() - bitesize = 3 - -/obj/item/weapon/reagent_containers/food/snacks/applepie - name = "Apple Pie" - desc = "A pie containing sweet sweet love... or apple." - icon_state = "applepie" - filling_color = "#E0EDC5" - center_of_mass = list("x"=16, "y"=13) - nutriment_amt = 4 - nutriment_desc = list("sweetness" = 2, "apple" = 2, "pie" = 2) - -/obj/item/weapon/reagent_containers/food/snacks/applepie/New() - ..() - bitesize = 3 - -/obj/item/weapon/reagent_containers/food/snacks/cherrypie - name = "Cherry Pie" - desc = "Taste so good, make a grown man cry." - icon_state = "cherrypie" - filling_color = "#FF525A" - center_of_mass = list("x"=16, "y"=11) - nutriment_amt = 4 - nutriment_desc = list("sweetness" = 2, "cherry" = 2, "pie" = 2) - -/obj/item/weapon/reagent_containers/food/snacks/cherrypie/New() - ..() - bitesize = 3 - -/obj/item/weapon/reagent_containers/food/snacks/twobread - name = "Two Bread" - desc = "It is very bitter and winy." - icon_state = "twobread" - filling_color = "#DBCC9A" - center_of_mass = list("x"=15, "y"=12) - nutriment_amt = 2 - nutriment_desc = list("sourness" = 2, "bread" = 2) - -/obj/item/weapon/reagent_containers/food/snacks/twobread/New() - ..() - bitesize = 3 - -/obj/item/weapon/reagent_containers/food/snacks/jellysandwich - name = "Jelly Sandwich" - desc = "You wish you had some peanut butter to go with this..." - icon_state = "jellysandwich" - trash = /obj/item/trash/plate - filling_color = "#9E3A78" - center_of_mass = list("x"=16, "y"=8) - nutriment_amt = 2 - nutriment_desc = list("bread" = 2) - -/obj/item/weapon/reagent_containers/food/snacks/jellysandwich/New() - ..() - bitesize = 3 - -/obj/item/weapon/reagent_containers/food/snacks/jellysandwich/slime/New() - ..() - reagents.add_reagent("slimejelly", 5) - -/obj/item/weapon/reagent_containers/food/snacks/jellysandwich/cherry/New() - ..() - reagents.add_reagent("cherryjelly", 5) - -/obj/item/weapon/reagent_containers/food/snacks/boiledslimecore - name = "Boiled slime Core" - desc = "A boiled red thing." - icon_state = "boiledslimecore" //nonexistant? - -/obj/item/weapon/reagent_containers/food/snacks/boiledslimecore/New() - ..() - reagents.add_reagent("slimejelly", 5) - bitesize = 3 - -/obj/item/weapon/reagent_containers/food/snacks/mint - name = "mint" - desc = "it is only wafer thin." - icon_state = "mint" - filling_color = "#F2F2F2" - center_of_mass = list("x"=16, "y"=14) - -/obj/item/weapon/reagent_containers/food/snacks/mint/New() - ..() - reagents.add_reagent("mint", 1) - bitesize = 1 - -/obj/item/weapon/reagent_containers/food/snacks/mushroomsoup - name = "chantrelle soup" - desc = "A delicious and hearty mushroom soup." - icon_state = "mushroomsoup" - trash = /obj/item/trash/snack_bowl - filling_color = "#E386BF" - center_of_mass = list("x"=17, "y"=10) - nutriment_amt = 8 - nutriment_desc = list("mushroom" = 8, "milk" = 2) - -/obj/item/weapon/reagent_containers/food/snacks/mushroomsoup/New() - ..() - bitesize = 3 - -/obj/item/weapon/reagent_containers/food/snacks/plumphelmetbiscuit - name = "plump helmet biscuit" - desc = "This is a finely-prepared plump helmet biscuit. The ingredients are exceptionally minced plump helmet, and well-minced dwarven wheat flour." - icon_state = "phelmbiscuit" - filling_color = "#CFB4C4" - center_of_mass = list("x"=16, "y"=13) - nutriment_amt = 5 - nutriment_desc = list("mushroom" = 4) - -/obj/item/weapon/reagent_containers/food/snacks/plumphelmetbiscuit/New() - ..() - if(prob(10)) - name = "exceptional plump helmet biscuit" - desc = "Microwave is taken by a fey mood! It has cooked an exceptional plump helmet biscuit!" - reagents.add_reagent("nutriment", 8) - bitesize = 2 - else - reagents.add_reagent("nutriment", 5) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/chawanmushi - name = "chawanmushi" - desc = "A legendary egg custard that makes friends out of enemies. Probably too hot for a cat to eat." - icon_state = "chawanmushi" - trash = /obj/item/trash/snack_bowl - filling_color = "#F0F2E4" - center_of_mass = list("x"=17, "y"=10) - -/obj/item/weapon/reagent_containers/food/snacks/chawanmushi/New() - ..() - reagents.add_reagent("protein", 5) - bitesize = 1 - -/obj/item/weapon/reagent_containers/food/snacks/beetsoup - name = "beet soup" - desc = "Wait, how do you spell it again..?" - icon_state = "beetsoup" - trash = /obj/item/trash/snack_bowl - filling_color = "#FAC9FF" - center_of_mass = list("x"=15, "y"=8) - nutriment_amt = 8 - nutriment_desc = list("tomato" = 4, "beet" = 4) - -/obj/item/weapon/reagent_containers/food/snacks/beetsoup/New() - ..() - name = pick(list("borsch","bortsch","borstch","borsh","borshch","borscht")) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/tossedsalad - name = "tossed salad" - desc = "A proper salad, basic and simple, with little bits of carrot, tomato and apple intermingled. Vegan!" - icon_state = "herbsalad" - trash = /obj/item/trash/snack_bowl - filling_color = "#76B87F" - center_of_mass = list("x"=17, "y"=11) - nutriment_amt = 8 - nutriment_desc = list("salad" = 2, "tomato" = 2, "carrot" = 2, "apple" = 2) - -/obj/item/weapon/reagent_containers/food/snacks/tossedsalad/New() - ..() - bitesize = 3 - -/obj/item/weapon/reagent_containers/food/snacks/validsalad - name = "valid salad" - desc = "It's just a salad of questionable 'herbs' with meatballs and fried potato slices. Nothing suspicious about it." - icon_state = "validsalad" - trash = /obj/item/trash/snack_bowl - filling_color = "#76B87F" - center_of_mass = list("x"=17, "y"=11) - nutriment_amt = 6 - nutriment_desc = list("100% real salad") - -/obj/item/weapon/reagent_containers/food/snacks/validsalad/New() - ..() - reagents.add_reagent("protein", 2) - bitesize = 3 - -/obj/item/weapon/reagent_containers/food/snacks/appletart - name = "golden apple streusel tart" - desc = "A tasty dessert that won't make it through a metal detector." - icon_state = "gappletart" - trash = /obj/item/trash/plate - filling_color = "#FFFF00" - center_of_mass = list("x"=16, "y"=18) - nutriment_amt = 8 - nutriment_desc = list("apple" = 8) - -/obj/item/weapon/reagent_containers/food/snacks/appletart/New() - ..() - reagents.add_reagent("gold", 5) - bitesize = 3 - -/////////////////////////////////////////////////Sliceable//////////////////////////////////////// -// All the food items that can be sliced into smaller bits like Meatbread and Cheesewheels - -// sliceable is just an organization type path, it doesn't have any additional code or variables tied to it. - -/obj/item/weapon/reagent_containers/food/snacks/sliceable - w_class = ITEMSIZE_NORMAL //Whole pizzas and cakes shouldn't fit in a pocket, you can slice them if you want to do that. - -/** - * A food item slice - * - * This path contains some extra code for spawning slices pre-filled with - * reagents. - */ -/obj/item/weapon/reagent_containers/food/snacks/slice - name = "slice of... something" - var/whole_path // path for the item from which this slice comes - var/filled = FALSE // should the slice spawn with any reagents - -/** - * Spawn a new slice of food - * - * If the slice's filled is TRUE, this will also fill the slice with the - * appropriate amount of reagents. Note that this is done by spawning a new - * whole item, transferring the reagents and deleting the whole item, which may - * have performance implications. - */ -/obj/item/weapon/reagent_containers/food/snacks/slice/New() - ..() - if(filled) - var/obj/item/weapon/reagent_containers/food/snacks/whole = new whole_path() - if(whole && whole.slices_num) - var/reagent_amount = whole.reagents.total_volume/whole.slices_num - whole.reagents.trans_to_obj(src, reagent_amount) - - qdel(whole) - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/meatbread - name = "meatbread loaf" - desc = "The culinary base of every self-respecting eloquent gentleman." - icon_state = "meatbread" - slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/meatbread - slices_num = 5 - filling_color = "#FF7575" - center_of_mass = list("x"=19, "y"=9) - nutriment_desc = list("bread" = 10) - nutriment_amt = 10 - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/meatbread/New() - ..() - reagents.add_reagent("protein", 20) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/slice/meatbread - name = "meatbread slice" - desc = "A slice of delicious meatbread." - icon_state = "meatbreadslice" - trash = /obj/item/trash/plate - filling_color = "#FF7575" - bitesize = 2 - center_of_mass = list("x"=16, "y"=16) - whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/meatbread - -/obj/item/weapon/reagent_containers/food/snacks/slice/meatbread/filled - filled = TRUE - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/xenomeatbread - name = "xenomeatbread loaf" - desc = "The culinary base of every self-respecting eloquent gentleman. Extra Heretical." - icon_state = "xenomeatbread" - slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/xenomeatbread - slices_num = 5 - filling_color = "#8AFF75" - center_of_mass = list("x"=16, "y"=9) - nutriment_desc = list("bread" = 10) - nutriment_amt = 10 - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/xenomeatbread/New() - ..() - reagents.add_reagent("protein", 20) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/slice/xenomeatbread - name = "xenomeatbread slice" - desc = "A slice of delicious meatbread. Extra Heretical." - icon_state = "xenobreadslice" - trash = /obj/item/trash/plate - filling_color = "#8AFF75" - bitesize = 2 - center_of_mass = list("x"=16, "y"=13) - whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/xenomeatbread - - -/obj/item/weapon/reagent_containers/food/snacks/slice/xenomeatbread/filled - filled = TRUE - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/bananabread - name = "Banana-nut bread" - desc = "A heavenly and filling treat." - icon_state = "bananabread" - slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/bananabread - slices_num = 5 - filling_color = "#EDE5AD" - center_of_mass = list("x"=16, "y"=9) - nutriment_desc = list("bread" = 10) - nutriment_amt = 10 - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/bananabread/New() - ..() - reagents.add_reagent("banana", 20) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/slice/bananabread - name = "Banana-nut bread slice" - desc = "A slice of delicious banana bread." - icon_state = "bananabreadslice" - trash = /obj/item/trash/plate - filling_color = "#EDE5AD" - bitesize = 2 - center_of_mass = list("x"=16, "y"=8) - whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/bananabread - -/obj/item/weapon/reagent_containers/food/snacks/slice/bananabread/filled - filled = TRUE - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/tofubread - name = "Tofubread" - icon_state = "Like meatbread but for vegetarians. Not guaranteed to give superpowers." - icon_state = "tofubread" - slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/tofubread - slices_num = 5 - filling_color = "#F7FFE0" - center_of_mass = list("x"=16, "y"=9) - nutriment_desc = list("tofu" = 10) - nutriment_amt = 10 - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/tofubread/New() - ..() - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/slice/tofubread - name = "Tofubread slice" - desc = "A slice of delicious tofubread." - icon_state = "tofubreadslice" - trash = /obj/item/trash/plate - filling_color = "#F7FFE0" - bitesize = 2 - center_of_mass = list("x"=16, "y"=13) - whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/tofubread - -/obj/item/weapon/reagent_containers/food/snacks/slice/tofubread/filled - filled = TRUE - - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/carrotcake - name = "Carrot Cake" - desc = "A favorite desert of a certain wascally wabbit. Not a lie." - icon_state = "carrotcake" - slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/carrotcake - slices_num = 5 - filling_color = "#FFD675" - center_of_mass = list("x"=16, "y"=10) - nutriment_desc = list("cake" = 10, "sweetness" = 10, "carrot" = 15) - nutriment_amt = 25 - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/carrotcake/New() - ..() - reagents.add_reagent("imidazoline", 10) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/slice/carrotcake - name = "Carrot Cake slice" - desc = "Carrotty slice of Carrot Cake, carrots are good for your eyes! Also not a lie." - icon_state = "carrotcake_slice" - trash = /obj/item/trash/plate - filling_color = "#FFD675" - bitesize = 2 - center_of_mass = list("x"=16, "y"=14) - whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/carrotcake - -/obj/item/weapon/reagent_containers/food/snacks/slice/carrotcake/filled - filled = TRUE - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/braincake - name = "Brain Cake" - desc = "A squishy cake-thing." - icon_state = "braincake" - slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/braincake - slices_num = 5 - filling_color = "#E6AEDB" - center_of_mass = list("x"=16, "y"=10) - nutriment_desc = list("cake" = 10, "sweetness" = 10, "slime" = 15) - nutriment_amt = 5 - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/braincake/New() - ..() - reagents.add_reagent("protein", 25) - reagents.add_reagent("alkysine", 10) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/slice/braincake - name = "Brain Cake slice" - desc = "Lemme tell you something about prions. THEY'RE DELICIOUS." - icon_state = "braincakeslice" - trash = /obj/item/trash/plate - filling_color = "#E6AEDB" - bitesize = 2 - center_of_mass = list("x"=16, "y"=12) - whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/braincake - -/obj/item/weapon/reagent_containers/food/snacks/slice/braincake/filled - filled = TRUE - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/cheesecake - name = "Cheese Cake" - desc = "DANGEROUSLY cheesy." - icon_state = "cheesecake" - slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/cheesecake - slices_num = 5 - filling_color = "#FAF7AF" - center_of_mass = list("x"=16, "y"=10) - nutriment_desc = list("cake" = 10, "cream" = 10, "cheese" = 15) - nutriment_amt = 10 - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/cheesecake/New() - ..() - reagents.add_reagent("protein", 15) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/slice/cheesecake - name = "Cheese Cake slice" - desc = "Slice of pure cheestisfaction." - icon_state = "cheesecake_slice" - trash = /obj/item/trash/plate - filling_color = "#FAF7AF" - bitesize = 2 - center_of_mass = list("x"=16, "y"=14) - whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/cheesecake - -/obj/item/weapon/reagent_containers/food/snacks/slice/cheesecake/filled - filled = TRUE - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/plaincake - name = "Vanilla Cake" - desc = "A plain cake, not a lie." - icon_state = "plaincake" - slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/plaincake - slices_num = 5 - filling_color = "#F7EDD5" - center_of_mass = list("x"=16, "y"=10) - nutriment_desc = list("cake" = 10, "sweetness" = 10, "vanilla" = 15) - nutriment_amt = 20 - -/obj/item/weapon/reagent_containers/food/snacks/slice/plaincake - name = "Vanilla Cake slice" - desc = "Just a slice of cake, it is enough for everyone." - icon_state = "plaincake_slice" - trash = /obj/item/trash/plate - filling_color = "#F7EDD5" - bitesize = 2 - center_of_mass = list("x"=16, "y"=14) - whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/plaincake - -/obj/item/weapon/reagent_containers/food/snacks/slice/plaincake/filled - filled = TRUE - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/orangecake - name = "Orange Cake" - desc = "A cake with added orange." - icon_state = "orangecake" - slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/orangecake - slices_num = 5 - filling_color = "#FADA8E" - center_of_mass = list("x"=16, "y"=10) - nutriment_desc = list("cake" = 10, "sweetness" = 10, "orange" = 15) - nutriment_amt = 20 - -/obj/item/weapon/reagent_containers/food/snacks/slice/orangecake - name = "Orange Cake slice" - desc = "Just a slice of cake, it is enough for everyone." - icon_state = "orangecake_slice" - trash = /obj/item/trash/plate - filling_color = "#FADA8E" - bitesize = 2 - center_of_mass = list("x"=16, "y"=14) - whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/orangecake - -/obj/item/weapon/reagent_containers/food/snacks/slice/orangecake/filled - filled = TRUE - - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/limecake - name = "Lime Cake" - desc = "A cake with added lime." - icon_state = "limecake" - slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/limecake - slices_num = 5 - filling_color = "#CBFA8E" - center_of_mass = list("x"=16, "y"=10) - nutriment_desc = list("cake" = 10, "sweetness" = 10, "lime" = 15) - nutriment_amt = 20 - - -/obj/item/weapon/reagent_containers/food/snacks/slice/limecake - name = "Lime Cake slice" - desc = "Just a slice of cake, it is enough for everyone." - icon_state = "limecake_slice" - trash = /obj/item/trash/plate - filling_color = "#CBFA8E" - bitesize = 2 - center_of_mass = list("x"=16, "y"=14) - whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/limecake - -/obj/item/weapon/reagent_containers/food/snacks/slice/limecake/filled - filled = TRUE - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/lemoncake - name = "Lemon Cake" - desc = "A cake with added lemon." - icon_state = "lemoncake" - slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/lemoncake - slices_num = 5 - filling_color = "#FAFA8E" - center_of_mass = list("x"=16, "y"=10) - nutriment_desc = list("cake" = 10, "sweetness" = 10, "lemon" = 15) - nutriment_amt = 20 - - -/obj/item/weapon/reagent_containers/food/snacks/slice/lemoncake - name = "Lemon Cake slice" - desc = "Just a slice of cake, it is enough for everyone." - icon_state = "lemoncake_slice" - trash = /obj/item/trash/plate - filling_color = "#FAFA8E" - bitesize = 2 - center_of_mass = list("x"=16, "y"=14) - whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/lemoncake - -/obj/item/weapon/reagent_containers/food/snacks/slice/lemoncake/filled - filled = TRUE - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/chocolatecake - name = "Chocolate Cake" - desc = "A cake with added chocolate." - icon_state = "chocolatecake" - slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/chocolatecake - slices_num = 5 - filling_color = "#805930" - center_of_mass = list("x"=16, "y"=10) - nutriment_desc = list("cake" = 10, "sweetness" = 10, "chocolate" = 15) - nutriment_amt = 20 - -/obj/item/weapon/reagent_containers/food/snacks/slice/chocolatecake - name = "Chocolate Cake slice" - desc = "Just a slice of cake, it is enough for everyone." - icon_state = "chocolatecake_slice" - trash = /obj/item/trash/plate - filling_color = "#805930" - bitesize = 2 - center_of_mass = list("x"=16, "y"=14) - whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/chocolatecake - -/obj/item/weapon/reagent_containers/food/snacks/slice/chocolatecake/filled - filled = TRUE - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/cheesewheel - name = "Cheese wheel" - desc = "A big wheel of delcious Cheddar." - icon_state = "cheesewheel" - slice_path = /obj/item/weapon/reagent_containers/food/snacks/cheesewedge - slices_num = 5 - filling_color = "#FFF700" - center_of_mass = list("x"=16, "y"=10) - nutriment_desc = list("cheese" = 10) - nutriment_amt = 10 - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/cheesewheel/New() - ..() - reagents.add_reagent("protein", 10) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/cheesewedge - name = "Cheese wedge" - desc = "A wedge of delicious Cheddar. The cheese wheel it was cut from can't have gone far." - icon_state = "cheesewedge" - filling_color = "#FFF700" - bitesize = 2 - center_of_mass = list("x"=16, "y"=10) - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/birthdaycake - name = "Birthday Cake" - desc = "Happy Birthday..." - icon_state = "birthdaycake" - slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/birthdaycake - slices_num = 5 - filling_color = "#FFD6D6" - center_of_mass = list("x"=16, "y"=10) - nutriment_desc = list("cake" = 10, "sweetness" = 10) - nutriment_amt = 20 - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/birthdaycake/New() - ..() - reagents.add_reagent("sprinkles", 10) - bitesize = 3 - -/obj/item/weapon/reagent_containers/food/snacks/slice/birthdaycake - name = "Birthday Cake slice" - desc = "A slice of your birthday." - icon_state = "birthdaycakeslice" - trash = /obj/item/trash/plate - filling_color = "#FFD6D6" - bitesize = 2 - center_of_mass = list("x"=16, "y"=14) - whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/birthdaycake - -/obj/item/weapon/reagent_containers/food/snacks/slice/birthdaycake/filled - filled = TRUE - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/bread - name = "Bread" - icon_state = "Some plain old Earthen bread." - icon_state = "bread" - slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/bread - slices_num = 5 - filling_color = "#FFE396" - center_of_mass = list("x"=16, "y"=9) - nutriment_desc = list("bread" = 6) - nutriment_amt = 6 - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/bread/New() - ..() - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/slice/bread - name = "Bread slice" - desc = "A slice of home." - icon_state = "breadslice" - trash = /obj/item/trash/plate - filling_color = "#D27332" - bitesize = 2 - center_of_mass = list("x"=16, "y"=4) - whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/bread - -/obj/item/weapon/reagent_containers/food/snacks/slice/bread/filled - filled = TRUE - - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/creamcheesebread - name = "Cream Cheese Bread" - desc = "Yum yum yum!" - icon_state = "creamcheesebread" - slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/creamcheesebread - slices_num = 5 - filling_color = "#FFF896" - center_of_mass = list("x"=16, "y"=9) - nutriment_desc = list("bread" = 6, "cream" = 3, "cheese" = 3) - nutriment_amt = 5 - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/creamcheesebread/New() - ..() - reagents.add_reagent("protein", 15) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/slice/creamcheesebread - name = "Cream Cheese Bread slice" - desc = "A slice of yum!" - icon_state = "creamcheesebreadslice" - trash = /obj/item/trash/plate - filling_color = "#FFF896" - bitesize = 2 - center_of_mass = list("x"=16, "y"=14) - whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/creamcheesebread - - -/obj/item/weapon/reagent_containers/food/snacks/slice/creamcheesebread/filled - filled = TRUE - - -/obj/item/weapon/reagent_containers/food/snacks/watermelonslice - name = "Watermelon Slice" - desc = "A slice of watery goodness." - icon_state = "watermelonslice" - filling_color = "#FF3867" - bitesize = 2 - center_of_mass = list("x"=16, "y"=10) - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/applecake - name = "Apple Cake" - desc = "A cake centred with apples." - icon_state = "applecake" - slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/applecake - slices_num = 5 - filling_color = "#EBF5B8" - center_of_mass = list("x"=16, "y"=10) - nutriment_desc = list("cake" = 10, "sweetness" = 10, "apple" = 15) - nutriment_amt = 15 - -/obj/item/weapon/reagent_containers/food/snacks/slice/applecake - name = "Apple Cake slice" - desc = "A slice of heavenly cake." - icon_state = "applecakeslice" - trash = /obj/item/trash/plate - filling_color = "#EBF5B8" - bitesize = 2 - center_of_mass = list("x"=16, "y"=14) - whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/applecake - -/obj/item/weapon/reagent_containers/food/snacks/slice/applecake/filled - filled = TRUE - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/pumpkinpie - name = "Pumpkin Pie" - desc = "A delicious treat for the autumn months." - icon_state = "pumpkinpie" - slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/pumpkinpie - slices_num = 5 - filling_color = "#F5B951" - center_of_mass = list("x"=16, "y"=10) - nutriment_desc = list("pie" = 5, "cream" = 5, "pumpkin" = 5) - nutriment_amt = 15 - -/obj/item/weapon/reagent_containers/food/snacks/slice/pumpkinpie - name = "Pumpkin Pie slice" - desc = "A slice of pumpkin pie, with whipped cream on top. Perfection." - icon_state = "pumpkinpieslice" - trash = /obj/item/trash/plate - filling_color = "#F5B951" - bitesize = 2 - center_of_mass = list("x"=16, "y"=12) - whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pumpkinpie - -/obj/item/weapon/reagent_containers/food/snacks/slice/pumpkinpie/filled - filled = TRUE - -/obj/item/weapon/reagent_containers/food/snacks/cracker - name = "Cracker" - desc = "It's a salted cracker." - icon_state = "cracker" - filling_color = "#F5DEB8" - center_of_mass = list("x"=16, "y"=6) - nutriment_desc = list("salt" = 1, "cracker" = 2) - nutriment_amt = 1 - - - -/////////////////////////////////////////////////PIZZA//////////////////////////////////////// - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza - slices_num = 6 - filling_color = "#BAA14C" - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/margherita - name = "Margherita" - desc = "The golden standard of pizzas." - icon_state = "pizzamargherita" - slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/margherita - slices_num = 6 - center_of_mass = list("x"=16, "y"=11) - nutriment_desc = list("pizza crust" = 10, "tomato" = 10, "cheese" = 15) - nutriment_amt = 35 - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/margherita/New() - ..() - reagents.add_reagent("protein", 5) - reagents.add_reagent("tomatojuice", 6) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/slice/margherita - name = "Margherita slice" - desc = "A slice of the classic pizza." - icon_state = "pizzamargheritaslice" - filling_color = "#BAA14C" - bitesize = 2 - center_of_mass = list("x"=16, "y"=13) - whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/margherita - -/obj/item/weapon/reagent_containers/food/snacks/slice/margherita/filled - filled = TRUE - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/meatpizza - name = "Meatpizza" - desc = "A pizza with meat topping." - icon_state = "meatpizza" - slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/meatpizza - slices_num = 6 - center_of_mass = list("x"=16, "y"=11) - nutriment_desc = list("pizza crust" = 10, "tomato" = 10, "cheese" = 15) - nutriment_amt = 10 - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/meatpizza/New() - ..() - reagents.add_reagent("protein", 34) - reagents.add_reagent("tomatojuice", 6) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/slice/meatpizza - name = "Meatpizza slice" - desc = "A slice of a meaty pizza." - icon_state = "meatpizzaslice" - filling_color = "#BAA14C" - bitesize = 2 - center_of_mass = list("x"=16, "y"=13) - whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/meatpizza - -/obj/item/weapon/reagent_containers/food/snacks/slice/meatpizza/filled - filled = TRUE - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/mushroompizza - name = "Mushroompizza" - desc = "Very special pizza." - icon_state = "mushroompizza" - slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/mushroompizza - slices_num = 6 - center_of_mass = list("x"=16, "y"=11) - nutriment_desc = list("pizza crust" = 10, "tomato" = 10, "cheese" = 5, "mushroom" = 10) - nutriment_amt = 35 - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/mushroompizza/New() - ..() - reagents.add_reagent("protein", 5) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/slice/mushroompizza - name = "Mushroompizza slice" - desc = "Maybe it is the last slice of pizza in your life." - icon_state = "mushroompizzaslice" - filling_color = "#BAA14C" - bitesize = 2 - center_of_mass = list("x"=16, "y"=13) - whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/mushroompizza - -/obj/item/weapon/reagent_containers/food/snacks/slice/mushroompizza/filled - filled = TRUE - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/vegetablepizza - name = "Vegetable pizza" - desc = "No one of Tomato Sapiens were harmed during making this pizza." - icon_state = "vegetablepizza" - slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/vegetablepizza - slices_num = 6 - center_of_mass = list("x"=16, "y"=11) - nutriment_desc = list("pizza crust" = 10, "tomato" = 10, "cheese" = 5, "eggplant" = 5, "carrot" = 5, "corn" = 5) - nutriment_amt = 25 - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/vegetablepizza/New() - ..() - reagents.add_reagent("protein", 5) - reagents.add_reagent("tomatojuice", 6) - reagents.add_reagent("imidazoline", 12) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/slice/vegetablepizza - name = "Vegetable pizza slice" - desc = "A slice of the most green pizza of all pizzas not containing green ingredients." - icon_state = "vegetablepizzaslice" - filling_color = "#BAA14C" - bitesize = 2 - center_of_mass = list("x"=16, "y"=13) - whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/vegetablepizza - -/obj/item/weapon/reagent_containers/food/snacks/slice/vegetablepizza/filled - filled = TRUE - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/oldpizza - name = "moldy pizza" - desc = "This pizza might actually be alive. There's mold all over." - icon_state = "oldpizza" - slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/oldpizza - slices_num = 6 - center_of_mass = list("x"=16, "y"=11) - nutriment_desc = list("stale pizza crust" = 10, "moldy tomato" = 10, "moldy cheese" = 5) - nutriment_amt = 10 - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/oldpizza/New() - ..() - reagents.add_reagent("protein", 5) - reagents.add_reagent("tomatojuice", 6) - reagents.add_reagent("mold", 8) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/slice/oldpizza - name = "moldy pizza slice" - desc = "This used to be pizza..." - icon_state = "old_pizza" - filling_color = "#BAA14C" - bitesize = 2 - center_of_mass = list("x"=16, "y"=13) - whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/oldpizza - -/obj/item/pizzabox - name = "pizza box" - desc = "A box suited for pizzas." - icon = 'icons/obj/food.dmi' - icon_state = "pizzabox1" - - var/open = 0 // Is the box open? - var/ismessy = 0 // Fancy mess on the lid - var/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/pizza // Content pizza - var/list/boxes = list() // If the boxes are stacked, they come here - var/boxtag = "" - -/obj/item/pizzabox/update_icon() - - overlays = list() - - // Set appropriate description - if( open && pizza ) - desc = "A box suited for pizzas. It appears to have a [pizza.name] inside." - else if( boxes.len > 0 ) - desc = "A pile of boxes suited for pizzas. There appears to be [boxes.len + 1] boxes in the pile." - - var/obj/item/pizzabox/topbox = boxes[boxes.len] - var/toptag = topbox.boxtag - if( toptag != "" ) - desc = "[desc] The box on top has a tag, it reads: '[toptag]'." - else - desc = "A box suited for pizzas." - - if( boxtag != "" ) - desc = "[desc] The box has a tag, it reads: '[boxtag]'." - - // Icon states and overlays - if( open ) - if( ismessy ) - icon_state = "pizzabox_messy" - else - icon_state = "pizzabox_open" - - if( pizza ) - var/image/pizzaimg = image("food.dmi", icon_state = pizza.icon_state) - pizzaimg.pixel_y = -3 - overlays += pizzaimg - - return - else - // Stupid code because byondcode sucks - var/doimgtag = 0 - if( boxes.len > 0 ) - var/obj/item/pizzabox/topbox = boxes[boxes.len] - if( topbox.boxtag != "" ) - doimgtag = 1 - else - if( boxtag != "" ) - doimgtag = 1 - - if( doimgtag ) - var/image/tagimg = image("food.dmi", icon_state = "pizzabox_tag") - tagimg.pixel_y = boxes.len * 3 - overlays += tagimg - - icon_state = "pizzabox[boxes.len+1]" - -/obj/item/pizzabox/attack_hand( mob/user as mob ) - - if( open && pizza ) - user.put_in_hands( pizza ) - - to_chat(user, "You take \the [src.pizza] out of \the [src].") - src.pizza = null - update_icon() - return - - if( boxes.len > 0 ) - if( user.get_inactive_hand() != src ) - ..() - return - - var/obj/item/pizzabox/box = boxes[boxes.len] - boxes -= box - - user.put_in_hands( box ) - to_chat(user, "You remove the topmost [src] from your hand.") - box.update_icon() - update_icon() - return - ..() - -/obj/item/pizzabox/attack_self( mob/user as mob ) - - if( boxes.len > 0 ) - return - - open = !open - - if( open && pizza ) - ismessy = 1 - - update_icon() - -/obj/item/pizzabox/attackby( obj/item/I as obj, mob/user as mob ) - if( istype(I, /obj/item/pizzabox/) ) - var/obj/item/pizzabox/box = I - - if( !box.open && !src.open ) - // Make a list of all boxes to be added - var/list/boxestoadd = list() - boxestoadd += box - for(var/obj/item/pizzabox/i in box.boxes) - boxestoadd += i - - if( (boxes.len+1) + boxestoadd.len <= 5 ) - user.drop_item() - - box.loc = src - box.boxes = list() // Clear the box boxes so we don't have boxes inside boxes. - Xzibit - src.boxes.Add( boxestoadd ) - - box.update_icon() - update_icon() - - to_chat(user, "You put \the [box] ontop of \the [src]!") - else - to_chat(user, "The stack is too high!") - else - to_chat(user, "Close \the [box] first!") - - return - - if( istype(I, /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/) ) // Long ass fucking object name - - if( src.open ) - user.drop_item() - I.loc = src - src.pizza = I - - update_icon() - - to_chat(user, "You put \the [I] in \the [src]!") - else - to_chat(user, "You try to push \the [I] through the lid but it doesn't work!") - return - - if( istype(I, /obj/item/weapon/pen/) ) - - if( src.open ) - return - - var/t = sanitize(input("Enter what you want to add to the tag:", "Write", null, null) as text, 30) - - var/obj/item/pizzabox/boxtotagto = src - if( boxes.len > 0 ) - boxtotagto = boxes[boxes.len] - - boxtotagto.boxtag = copytext("[boxtotagto.boxtag][t]", 1, 30) - - update_icon() - return - ..() - -/obj/item/pizzabox/margherita/New() - pizza = new /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/margherita(src) - boxtag = "Margherita Deluxe" - -/obj/item/pizzabox/vegetable/New() - pizza = new /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/vegetablepizza(src) - boxtag = "Gourmet Vegatable" - -/obj/item/pizzabox/mushroom/New() - pizza = new /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/mushroompizza(src) - boxtag = "Mushroom Special" - -/obj/item/pizzabox/meat/New() - pizza = new /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/meatpizza(src) - boxtag = "Meatlover's Supreme" - -/obj/item/pizzabox/old/New() - pizza = new /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/oldpizza(src) - boxtag = "Deluxe Gourmet" - -/obj/item/weapon/reagent_containers/food/snacks/dionaroast - name = "roast diona" - desc = "It's like an enormous, leathery carrot. With an eye." - icon_state = "dionaroast" - trash = /obj/item/trash/plate - filling_color = "#75754B" - center_of_mass = list("x"=16, "y"=7) - nutriment_amt = 6 - nutriment_desc = list("a chorus of flavor" = 6) - -/obj/item/weapon/reagent_containers/food/snacks/dionaroast/New() - ..() - reagents.add_reagent("radium", 2) - bitesize = 2 - -/////////////////////////////////////////// -// new old food stuff from bs12 -/////////////////////////////////////////// -/obj/item/weapon/reagent_containers/food/snacks/dough - name = "dough" - desc = "A piece of dough." - icon = 'icons/obj/food_ingredients.dmi' - icon_state = "dough" - bitesize = 2 - center_of_mass = list("x"=16, "y"=13) - nutriment_amt = 3 - nutriment_desc = list("uncooked dough" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/dough/New() - ..() - reagents.add_reagent("protein", 1) - -// Dough + rolling pin = flat dough -/obj/item/weapon/reagent_containers/food/snacks/dough/attackby(obj/item/weapon/W as obj, mob/user as mob) - if(istype(W,/obj/item/weapon/material/kitchen/rollingpin)) - new /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough(src) - user << "You flatten the dough." - qdel(src) - -// slicable into 3xdoughslices -/obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough - name = "flat dough" - desc = "A flattened dough." - icon = 'icons/obj/food_ingredients.dmi' - icon_state = "flat dough" - slice_path = /obj/item/weapon/reagent_containers/food/snacks/doughslice - slices_num = 3 - center_of_mass = list("x"=16, "y"=16) - -/obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough/New() - ..() - reagents.add_reagent("protein", 1) - reagents.add_reagent("nutriment", 3) - -/obj/item/weapon/reagent_containers/food/snacks/doughslice - name = "dough slice" - desc = "A building block of an impressive dish." - icon = 'icons/obj/food_ingredients.dmi' - icon_state = "doughslice" - slice_path = /obj/item/weapon/reagent_containers/food/snacks/spagetti - slices_num = 1 - bitesize = 2 - center_of_mass = list("x"=17, "y"=19) - nutriment_amt = 1 - nutriment_desc = list("uncooked dough" = 1) - -/obj/item/weapon/reagent_containers/food/snacks/doughslice/New() - ..() - -/obj/item/weapon/reagent_containers/food/snacks/bun - name = "bun" - desc = "A base for any self-respecting burger." - icon = 'icons/obj/food_ingredients.dmi' - icon_state = "bun" - bitesize = 2 - center_of_mass = list("x"=16, "y"=12) - nutriment_amt = 4 - nutriment_desc = "bun" - -/obj/item/weapon/reagent_containers/food/snacks/bun/New() - ..() - -/obj/item/weapon/reagent_containers/food/snacks/bun/attackby(obj/item/weapon/W as obj, mob/user as mob) - // Bun + meatball = burger - if(istype(W,/obj/item/weapon/reagent_containers/food/snacks/meatball)) - new /obj/item/weapon/reagent_containers/food/snacks/monkeyburger(src) - user << "You make a burger." - qdel(W) - qdel(src) - - // Bun + cutlet = hamburger - else if(istype(W,/obj/item/weapon/reagent_containers/food/snacks/cutlet)) - new /obj/item/weapon/reagent_containers/food/snacks/monkeyburger(src) - user << "You make a burger." - qdel(W) - qdel(src) - - // Bun + sausage = hotdog - else if(istype(W,/obj/item/weapon/reagent_containers/food/snacks/sausage)) - new /obj/item/weapon/reagent_containers/food/snacks/hotdog(src) - user << "You make a hotdog." - qdel(W) - qdel(src) - -// Burger + cheese wedge = cheeseburger -/obj/item/weapon/reagent_containers/food/snacks/monkeyburger/attackby(obj/item/weapon/reagent_containers/food/snacks/cheesewedge/W as obj, mob/user as mob) - if(istype(W))// && !istype(src,/obj/item/weapon/reagent_containers/food/snacks/cheesewedge)) - new /obj/item/weapon/reagent_containers/food/snacks/cheeseburger(src) - user << "You make a cheeseburger." - qdel(W) - qdel(src) - return - else - ..() - -// Human Burger + cheese wedge = cheeseburger -/obj/item/weapon/reagent_containers/food/snacks/human/burger/attackby(obj/item/weapon/reagent_containers/food/snacks/cheesewedge/W as obj, mob/user as mob) - if(istype(W)) - new /obj/item/weapon/reagent_containers/food/snacks/cheeseburger(src) - user << "You make a cheeseburger." - qdel(W) - qdel(src) - return - else - ..() - -/obj/item/weapon/reagent_containers/food/snacks/bunbun - name = "\improper Bun Bun" - desc = "A small bread monkey fashioned from two burger buns." - icon_state = "bunbun" - bitesize = 2 - center_of_mass = list("x"=16, "y"=8) - nutriment_amt = 8 - nutriment_desc = list("bun" = 8) - -/obj/item/weapon/reagent_containers/food/snacks/bunbun/New() - ..() - -/obj/item/weapon/reagent_containers/food/snacks/taco - name = "taco" - desc = "Take a bite!" - icon_state = "taco" - bitesize = 3 - center_of_mass = list("x"=21, "y"=12) - nutriment_amt = 4 - nutriment_desc = list("cheese" = 2,"taco shell" = 2) -/obj/item/weapon/reagent_containers/food/snacks/taco/New() - ..() - reagents.add_reagent("protein", 3) - -/obj/item/weapon/reagent_containers/food/snacks/rawcutlet - name = "raw cutlet" - desc = "A thin piece of raw meat." - icon = 'icons/obj/food_ingredients.dmi' - icon_state = "rawcutlet" - bitesize = 1 - center_of_mass = list("x"=17, "y"=20) - -/obj/item/weapon/reagent_containers/food/snacks/rawcutlet/New() - ..() - reagents.add_reagent("protein", 1) - -/obj/item/weapon/reagent_containers/food/snacks/cutlet - name = "cutlet" - desc = "A tasty meat slice." - icon = 'icons/obj/food_ingredients.dmi' - icon_state = "cutlet" - bitesize = 2 - center_of_mass = list("x"=17, "y"=20) - -/obj/item/weapon/reagent_containers/food/snacks/cutlet/New() - ..() - reagents.add_reagent("protein", 2) - -/obj/item/weapon/reagent_containers/food/snacks/rawmeatball - name = "raw meatball" - desc = "A raw meatball." - icon = 'icons/obj/food_ingredients.dmi' - icon_state = "rawmeatball" - bitesize = 2 - center_of_mass = list("x"=16, "y"=15) - -/obj/item/weapon/reagent_containers/food/snacks/rawmeatball/New() - ..() - reagents.add_reagent("protein", 2) - -/obj/item/weapon/reagent_containers/food/snacks/hotdog - name = "hotdog" - desc = "Unrelated to dogs, maybe." - icon_state = "hotdog" - bitesize = 2 - center_of_mass = list("x"=16, "y"=17) - -/obj/item/weapon/reagent_containers/food/snacks/hotdog/New() - ..() - reagents.add_reagent("protein", 6) - -/obj/item/weapon/reagent_containers/food/snacks/hotdog/old - name = "old hotdog" - desc = "Covered in mold. You're not gonna eat that, are you?" - -/obj/item/weapon/reagent_containers/food/snacks/hotdog/old/New() - ..() - reagents.add_reagent("mold", 6) - -/obj/item/weapon/reagent_containers/food/snacks/flatbread - name = "flatbread" - desc = "Bland but filling." - icon = 'icons/obj/food_ingredients.dmi' - icon_state = "flatbread" - bitesize = 2 - center_of_mass = list("x"=16, "y"=16) - nutriment_amt = 3 - nutriment_desc = list("bread" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/flatbread/New() - ..() - -// potato + knife = raw sticks -/obj/item/weapon/reagent_containers/food/snacks/grown/attackby(obj/item/weapon/W, mob/user) - if(seed && seed.kitchen_tag && seed.kitchen_tag == "potato" && istype(W,/obj/item/weapon/material/knife)) - new /obj/item/weapon/reagent_containers/food/snacks/rawsticks(get_turf(src)) - user << "You cut the potato." - qdel(src) - else - ..() - -/obj/item/weapon/reagent_containers/food/snacks/rawsticks - name = "raw potato sticks" - desc = "Raw fries, not very tasty." - icon = 'icons/obj/food_ingredients.dmi' - icon_state = "rawsticks" - bitesize = 2 - center_of_mass = list("x"=16, "y"=12) - nutriment_amt = 3 - nutriment_desc = list("raw potato" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/rawsticks/New() - ..() - -/obj/item/weapon/reagent_containers/food/snacks/liquidfood - name = "\improper LiquidFood Ration" - desc = "A prepackaged grey slurry of all the essential nutrients for a spacefarer on the go. Should this be crunchy?" - icon_state = "liquidfood" - trash = /obj/item/trash/liquidfood - filling_color = "#A8A8A8" - center_of_mass = list("x"=16, "y"=15) - nutriment_amt = 20 - nutriment_desc = list("chalk" = 6) - -/obj/item/weapon/reagent_containers/food/snacks/liquidfood/New() - ..() - reagents.add_reagent("iron", 3) - bitesize = 4 - -/obj/item/weapon/reagent_containers/food/snacks/tastybread - name = "bread tube" - desc = "Bread in a tube. Chewy...and surprisingly tasty." - icon_state = "tastybread" - trash = /obj/item/trash/tastybread - filling_color = "#A66829" - center_of_mass = list("x"=17, "y"=16) - nutriment_amt = 6 - nutriment_desc = list("bread" = 2, "sweetness" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/tastybread/New() - ..() - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/skrellsnacks - name = "\improper SkrellSnax" - desc = "Cured fungus shipped all the way from Qerr'balak, almost like jerky! Almost." - icon_state = "skrellsnacks" - filling_color = "#A66829" - center_of_mass = list("x"=15, "y"=12) - nutriment_amt = 10 - nutriment_desc = list("mushroom" = 5, "salt" = 5) - -/obj/item/weapon/reagent_containers/food/snacks/skrellsnacks/New() - ..() - bitesize = 3 - -/obj/item/weapon/reagent_containers/food/snacks/unajerky - name = "Moghes Imported Sissalik Jerky" - icon_state = "unathitinred" - desc = "An incredibly well made jerky, shipped in all the way from Moghes." - trash = /obj/item/trash/unajerky - filling_color = "#631212" - center_of_mass = list("x"=15, "y"=9) - -/obj/item/weapon/reagent_containers/food/snacks/unajerky/New() - ..() - reagents.add_reagent("protein", 8) - reagents.add_reagent("capsaicin", 2) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/croissant - name = "croissant" - desc = "True French cuisine." - filling_color = "#E3D796" - icon_state = "croissant" - nutriment_amt = 6 - nutriment_desc = list("french bread" = 6) - -/obj/item/weapon/reagent_containers/food/snacks/croissant/New() - ..() - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/meatbun - name = "meat bun" - desc = "Chinese street food, in neither China nor a street." - filling_color = "#DEDEAB" - icon_state = "meatbun" - nutriment_amt = 4 - -/obj/item/weapon/reagent_containers/food/snacks/meatbun/New() - ..() - bitesize = 2 - reagents.add_reagent("protein", 4) - -/obj/item/weapon/reagent_containers/food/snacks/sashimi - name = "carp sashimi" - desc = "Expertly prepared. Still toxic." - filling_color = "#FFDEFE" - icon_state = "sashimi" - nutriment_amt = 6 - -/obj/item/weapon/reagent_containers/food/snacks/sashimi/New() - ..() - reagents.add_reagent("protein", 2) - reagents.add_reagent("carpotoxin", 2) - bitesize = 3 - -/obj/item/weapon/reagent_containers/food/snacks/benedict - name = "eggs benedict" - desc = "Hey, there's only one egg in this!" - filling_color = "#FFDF78" - icon_state = "benedict" - nutriment_amt = 4 - -/obj/item/weapon/reagent_containers/food/snacks/benedict/New() - ..() - reagents.add_reagent("protein", 2) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/beans - name = "baked beans" - desc = "Musical fruit in a slightly less musical container." - filling_color = "#FC6F28" - icon_state = "beans" - nutriment_amt = 4 - nutriment_desc = list("beans" = 4) - -/obj/item/weapon/reagent_containers/food/snacks/beans/New() - ..() - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/sugarcookie - name = "sugar cookie" - desc = "Just like your little sister used to make." - filling_color = "#DBC94F" - icon_state = "sugarcookie" - nutriment_amt = 5 - nutriment_desc = list("sweetness" = 4, "cookie" = 1) - -/obj/item/weapon/reagent_containers/food/snacks/sugarcookie/New() - ..() - bitesize = 1 - -/obj/item/weapon/reagent_containers/food/snacks/berrymuffin - name = "berry muffin" - desc = "A delicious and spongy little cake, with berries." - icon_state = "berrymuffin" - filling_color = "#E0CF9B" - center_of_mass = list("x"=17, "y"=4) - nutriment_amt = 6 - nutriment_desc = list("sweetness" = 2, "muffin" = 2, "berries" = 2) - -/obj/item/weapon/reagent_containers/food/snacks/berrymuffin/New() - ..() - reagents.add_reagent("nutriment", 6) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/ghostmuffin - name = "booberry muffin" - desc = "My stomach is a graveyard! No living being can quench my bloodthirst!" - icon_state = "berrymuffin" - filling_color = "#799ACE" - center_of_mass = list("x"=17, "y"=4) - nutriment_amt = 6 - nutriment_desc = list("spookiness" = 4, "muffin" = 1, "berries" = 1) - -/obj/item/weapon/reagent_containers/food/snacks/ghostmuffin/New() - ..() - reagents.add_reagent("nutriment", 6) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/eggroll - name = "egg roll" - desc = "Free with orders over 10 thalers." - icon_state = "eggroll" - filling_color = "#799ACE" - center_of_mass = list("x"=17, "y"=4) - nutriment_amt = 4 - nutriment_desc = list("egg" = 4) - -/obj/item/weapon/reagent_containers/food/snacks/eggroll/New() - ..() - reagents.add_reagent("nutriment", 6) - reagents.add_reagent("protein", 2) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/fruitsalad - name = "fruit salad" - desc = "Your standard fruit salad." - icon_state = "fruitsalad" - filling_color = "#FF3867" - nutriment_amt = 10 - nutriment_desc = list("fruit" = 10) - -/obj/item/weapon/reagent_containers/food/snacks/fruitsalad/New() - ..() - reagents.add_reagent("nutriment", 10) - bitesize = 4 - -/obj/item/weapon/reagent_containers/food/snacks/eggbowl - name = "egg bowl" - desc = "A bowl of fried rice with egg mixed in." - icon_state = "eggbowl" - trash = /obj/item/trash/snack_bowl - filling_color = "#FFFBDB" - nutriment_amt = 6 - nutriment_desc = list("rice" = 2, "egg" = 4) - -/obj/item/weapon/reagent_containers/food/snacks/eggbowl/New() - ..() - reagents.add_reagent("nutriment", 6) - reagents.add_reagent("protein", 4) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/porkbowl - name = "pork bowl" - desc = "A bowl of fried rice with cuts of meat." - icon_state = "porkbowl" - trash = /obj/item/trash/snack_bowl - filling_color = "#FFFBDB" - nutriment_amt = 6 - nutriment_desc = list("rice" = 2, "meat" = 4) - -/obj/item/weapon/reagent_containers/food/snacks/porkbowl/New() - ..() - reagents.add_reagent("nutriment", 6) - reagents.add_reagent("protein", 4) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/tortilla - name = "tortilla" - desc = "The base for all your burritos." - icon_state = "tortilla" - nutriment_amt = 1 - nutriment_desc = list("bread" = 1) - -/obj/item/weapon/reagent_containers/food/snacks/tortilla/New() - ..() - reagents.add_reagent("nutriment", 2) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/meatburrito - name = "carne asada burrito" - desc = "The best burrito for meat lovers." - icon_state = "carneburrito" - nutriment_amt = 6 - nutriment_desc = list("tortilla" = 3, "meat" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/meatburrito/New() - ..() - reagents.add_reagent("protein", 6) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/cheeseburrito - name = "Cheese burrito" - desc = "It's a burrito filled with cheese." - icon_state = "cheeseburrito" - nutriment_amt = 6 - nutriment_desc = list("tortilla" = 3, "cheese" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/cheeseburrito/New() - ..() - reagents.add_reagent("nutriment", 6) - reagents.add_reagent("protein", 2) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/fuegoburrito - name = "fuego phoron burrito" - desc = "A super spicy burrito." - icon_state = "fuegoburrito" - nutriment_amt = 6 - nutriment_desc = list("chili peppers" = 5, "tortilla" = 1) - -/obj/item/weapon/reagent_containers/food/snacks/fuegoburrito/New() - ..() - reagents.add_reagent("nutriment", 6) - reagents.add_reagent("capsaicin", 4) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/nachos - name = "nachos" - desc = "Chips from Old Mexico." - icon_state = "nachos" - nutriment_amt = 2 - nutriment_desc = list("salt" = 1) - -/obj/item/weapon/reagent_containers/food/snacks/nachos/New() - ..() - reagents.add_reagent("nutriment", 1) - bitesize = 1 - -/obj/item/weapon/reagent_containers/food/snacks/cheesenachos - name = "cheesy nachos" - desc = "The delicious combination of nachos and melting cheese." - icon_state = "cheesenachos" - nutriment_amt = 5 - nutriment_desc = list("salt" = 2, "cheese" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/cheesenachos/New() - ..() - reagents.add_reagent("nutriment", 5) - reagents.add_reagent("protein", 2) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/cubannachos - name = "cuban nachos" - desc = "That's some dangerously spicy nachos." - icon_state = "cubannachos" - nutriment_amt = 6 - nutriment_desc = list("salt" = 1, "cheese" = 2, "chili peppers" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/cubannachos/New() - ..() - reagents.add_reagent("nutriment", 5) - reagents.add_reagent("capsaicin", 4) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/piginblanket - name = "pig in a blanket" - desc = "A sausage embedded in soft, fluffy pastry. Free this pig from its blanket prison by eating it." - icon_state = "piginblanket" - nutriment_amt = 6 - nutriment_desc = list("meat" = 3, "pastry" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/piginblanket/New() - ..() - reagents.add_reagent("nutriment", 6) - reagents.add_reagent("protein", 4) +//Food items that are eaten normally and don't leave anything behind. +/obj/item/weapon/reagent_containers/food/snacks + name = "snack" + desc = "yummy" + icon = 'icons/obj/food.dmi' + icon_state = null + var/bitesize = 1 + var/bitecount = 0 + var/trash = null + var/slice_path + var/slices_num + var/dried_type = null + var/dry = 0 + var/nutriment_amt = 0 + var/list/nutriment_desc = list("food" = 1) + center_of_mass = list("x"=16, "y"=16) + w_class = ITEMSIZE_SMALL + force = 1 + +/obj/item/weapon/reagent_containers/food/snacks/Initialize() + . = ..() + if(nutriment_amt) + reagents.add_reagent("nutriment",nutriment_amt,nutriment_desc) + +/obj/item/weapon/reagent_containers/food/snacks/Initialize() + . = ..() + if(nutriment_amt) + reagents.add_reagent("nutriment", nutriment_amt) + + //Placeholder for effect that trigger on eating that aren't tied to reagents. +/obj/item/weapon/reagent_containers/food/snacks/proc/On_Consume(var/mob/M) + if(!usr) + usr = M + if(!reagents.total_volume) + M.visible_message("[M] finishes eating \the [src].","You finish eating \the [src].") + usr.drop_from_inventory(src) //so icons update :[ + + if(trash) + if(ispath(trash,/obj/item)) + var/obj/item/TrashItem = new trash(usr) + usr.put_in_hands(TrashItem) + else if(istype(trash,/obj/item)) + usr.put_in_hands(trash) + qdel(src) + return + +/obj/item/weapon/reagent_containers/food/snacks/attack_self(mob/user as mob) + return + +/obj/item/weapon/reagent_containers/food/snacks/attack(mob/M as mob, mob/user as mob, def_zone) + if(reagents && !reagents.total_volume) + user << "None of [src] left!" + user.drop_from_inventory(src) + qdel(src) + return 0 + + if(istype(M, /mob/living/carbon)) + //TODO: replace with standard_feed_mob() call. + + var/fullness = M.nutrition + (M.reagents.get_reagent_amount("nutriment") * 25) + if(M == user) //If you're eating it yourself + if(istype(M,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = M + if(!H.check_has_mouth()) + user << "Where do you intend to put \the [src]? You don't have a mouth!" + return + var/obj/item/blocked = H.check_mouth_coverage() + if(blocked) + user << "\The [blocked] is in the way!" + return + + user.setClickCooldown(user.get_attack_speed(src)) //puts a limit on how fast people can eat/drink things + //VOREStation Edit Begin + if (fullness <= 50) + M << "You hungrily chew out a piece of [src] and gobble it!" + if (fullness > 50 && fullness <= 150) + M << "You hungrily begin to eat [src]." + if (fullness > 150 && fullness <= 350) + M << "You take a bite of [src]." + if (fullness > 350 && fullness <= 550) + M << "You unwillingly chew a bit of [src]." + if (fullness > 550 && fullness <= 650) + M << "You swallow some more of the [src], causing your belly to swell out a little." + if (fullness > 650 && fullness <= 1000) + M << "You stuff yourself with the [src]. Your stomach feels very heavy." + if (fullness > 1000 && fullness <= 3000) + M << "You gluttonously swallow down the hunk of [src]. You're so gorged, it's hard to stand." + if (fullness > 3000 && fullness <= 5500) + M << "You force the piece of [src] down your throat. You can feel your stomach getting firm as it reaches its limits." + if (fullness > 5500 && fullness <= 6000) + M << "You barely glug down the bite of [src], causing undigested food to force into your intestines. You can't take much more of this!" + if (fullness > 6000) // There has to be a limit eventually. + M << "Your stomach blorts and aches, prompting you to stop. You literally cannot force any more of [src] to go down your throat." + return 0 + /*if (fullness > (550 * (1 + M.overeatduration / 2000))) // The more you eat - the more you can eat + M << "You cannot force any more of [src] to go down your throat." + return 0*/ + //VOREStation Edit End + + else if(user.a_intent == I_HURT) + return ..() + + else + if(istype(M,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = M + if(!H.check_has_mouth()) + user << "Where do you intend to put \the [src]? \The [H] doesn't have a mouth!" + return + var/obj/item/blocked = H.check_mouth_coverage() + if(blocked) + user << "\The [blocked] is in the way!" + return + + /*if (fullness <= (550 * (1 + M.overeatduration / 1000))) // Vorestation edit + user.visible_message("[user] attempts to feed [M] [src].") + else + user.visible_message("[user] cannot force anymore of [src] down [M]'s throat.") + return 0*/ + user.visible_message("[user] attempts to feed [M] [src].") // Vorestation edit + + user.setClickCooldown(user.get_attack_speed(src)) + if(!do_mob(user, M)) return + + //Do we really care about this + add_attack_logs(user,M,"Fed with [src.name] containing [reagentlist(src)]", admin_notify = FALSE) + + user.visible_message("[user] feeds [M] [src].") + + else + user << "This creature does not seem to have a mouth!" + return + + if(reagents) //Handle ingestion of the reagent. + playsound(M.loc,'sound/items/eatfood.ogg', rand(10,50), 1) + if(reagents.total_volume) + if(reagents.total_volume > bitesize) + reagents.trans_to_mob(M, bitesize, CHEM_INGEST) + else + reagents.trans_to_mob(M, reagents.total_volume, CHEM_INGEST) + bitecount++ + On_Consume(M) + return 1 + + return 0 + +/obj/item/weapon/reagent_containers/food/snacks/examine(mob/user) + if(!..(user, 1)) + return + if (bitecount==0) + return + else if (bitecount==1) + user << "\The [src] was bitten by someone!" + else if (bitecount<=3) + user << "\The [src] was bitten [bitecount] times!" + else + user << "\The [src] was bitten multiple times!" + +/obj/item/weapon/reagent_containers/food/snacks/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W,/obj/item/weapon/storage)) + ..() // -> item/attackby() + return + + // Eating with forks + if(istype(W,/obj/item/weapon/material/kitchen/utensil)) + var/obj/item/weapon/material/kitchen/utensil/U = W + if(U.scoop_food) + if(!U.reagents) + U.create_reagents(5) + + if (U.reagents.total_volume > 0) + user << "You already have something on your [U]." + return + + user.visible_message( \ + "[user] scoops up some [src] with \the [U]!", \ + "You scoop up some [src] with \the [U]!" \ + ) + + src.bitecount++ + U.overlays.Cut() + U.loaded = "[src]" + var/image/I = new(U.icon, "loadedfood") + I.color = src.filling_color + U.overlays += I + + reagents.trans_to_obj(U, min(reagents.total_volume,5)) + + if (reagents.total_volume <= 0) + qdel(src) + return + + if (is_sliceable()) + //these are used to allow hiding edge items in food that is not on a table/tray + var/can_slice_here = 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)) + var/hide_item = !has_edge(W) || !can_slice_here + + if (hide_item) + if (W.w_class >= src.w_class || is_robot_module(W)) + return + + to_chat(user, "You slip \the [W] inside \the [src].") + user.drop_from_inventory(W, src) + add_fingerprint(user) + contents += W + return + + if (has_edge(W)) + if (!can_slice_here) + to_chat(user, "You cannot slice \the [src] here! You need a table or at least a tray to do it.") + return + + var/slices_lost = 0 + if (W.w_class > 3) + user.visible_message("\The [user] crudely slices \the [src] with [W]!", "You crudely slice \the [src] with your [W]!") + slices_lost = rand(1,min(1,round(slices_num/2))) + else + user.visible_message("\The [user] slices \the [src]!", "You slice \the [src]!") + + var/reagents_per_slice = reagents.total_volume/slices_num + for(var/i=1 to (slices_num-slices_lost)) + var/obj/slice = new slice_path (src.loc) + reagents.trans_to_obj(slice, reagents_per_slice) + qdel(src) + return + +/obj/item/weapon/reagent_containers/food/snacks/proc/is_sliceable() + return (slices_num && slice_path && slices_num > 0) + +/obj/item/weapon/reagent_containers/food/snacks/Destroy() + if(contents) + for(var/atom/movable/something in contents) + something.dropInto(loc) + . = ..() + +//////////////////////////////////////////////////////////////////////////////// +/// FOOD END +//////////////////////////////////////////////////////////////////////////////// +/obj/item/weapon/reagent_containers/food/snacks/attack_generic(var/mob/living/user) + if(!isanimal(user) && !isalien(user)) + return + user.visible_message("[user] nibbles away at \the [src].","You nibble away at \the [src].") + bitecount++ + if(reagents) + reagents.trans_to_mob(user, bitesize, CHEM_INGEST) + spawn(5) + if(!src && !user.client) + user.custom_emote(1,"[pick("burps", "cries for more", "burps twice", "looks at the area where the food was")]") + qdel(src) + On_Consume(user) + +////////////////////////////////////////////////// +////////////////////////////////////////////Snacks +////////////////////////////////////////////////// +//Items in the "Snacks" subcategory are food items that people actually eat. The key points are that they are created +// already filled with reagents and are destroyed when empty. Additionally, they make a "munching" noise when eaten. + +//Notes by Darem: Food in the "snacks" subtype can hold a maximum of 50 units Generally speaking, you don't want to go over 40 +// total for the item because you want to leave space for extra condiments. If you want effect besides healing, add a reagent for +// it. Try to stick to existing reagents when possible (so if you want a stronger healing effect, just use Tricordrazine). On use +// effect (such as the old officer eating a donut code) requires a unique reagent (unless you can figure out a better way). + +//The nutriment reagent and bitesize variable replace the old heal_amt and amount variables. Each unit of nutriment is equal to +// 2 of the old heal_amt variable. Bitesize is the rate at which the reagents are consumed. So if you have 6 nutriment and a +// bitesize of 2, then it'll take 3 bites to eat. Unlike the old system, the contained reagents are evenly spread among all +// the bites. No more contained reagents = no more bites. + +//Here is an example of the new formatting for anyone who wants to add more food items. +///obj/item/weapon/reagent_containers/food/snacks/xenoburger //Identification path for the object. +// name = "Xenoburger" //Name that displays in the UI. +// desc = "Smells caustic. Tastes like heresy." //Duh +// icon_state = "xburger" //Refers to an icon in food.dmi +// New() //Don't mess with this. +// ..() //Same here. +// reagents.add_reagent("xenomicrobes", 10) //This is what is in the food item. you may copy/paste +// reagents.add_reagent("nutriment", 2) // this line of code for all the contents. +// bitesize = 3 //This is the amount each bite consumes. + + + + +/obj/item/weapon/reagent_containers/food/snacks/aesirsalad + name = "Aesir salad" + desc = "Probably too incredible for mortal men to fully enjoy." + icon_state = "aesirsalad" + trash = /obj/item/trash/snack_bowl + filling_color = "#468C00" + center_of_mass = list("x"=17, "y"=11) + nutriment_amt = 8 + nutriment_desc = list("apples" = 3,"salad" = 5) + +/obj/item/weapon/reagent_containers/food/snacks/aesirsalad/Initialize() + . = ..() + reagents.add_reagent("doctorsdelight", 8) + reagents.add_reagent("tricordrazine", 8) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/candy + name = "candy" + desc = "Nougat, love it or hate it." + icon_state = "candy" + trash = /obj/item/trash/candy + filling_color = "#7D5F46" + center_of_mass = list("x"=15, "y"=15) + nutriment_amt = 1 + nutriment_desc = list("candy" = 1) + +/obj/item/weapon/reagent_containers/food/snacks/candy/Initialize() + . = ..() + reagents.add_reagent("sugar", 3) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar + name = "protein bar" + desc = "SwoleMAX brand protein bars, guaranteed to get you feeling perfectly overconfident." + icon_state = "proteinbar" + trash = /obj/item/trash/candy/proteinbar + nutriment_amt = 9 + nutriment_desc = list("candy" = 1, "protein" = 8) + +/obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar/Initialize() + . = ..() + reagents.add_reagent("protein", 4) + reagents.add_reagent("sugar", 4) + bitesize = 6 + +/obj/item/weapon/reagent_containers/food/snacks/candy/donor + name = "Donor Candy" + desc = "A little treat for blood donors." + trash = /obj/item/trash/candy + nutriment_amt = 9 + nutriment_desc = list("candy" = 10) + +/obj/item/weapon/reagent_containers/food/snacks/candy/donor/Initialize() + . = ..() + reagents.add_reagent("sugar", 3) + bitesize = 5 + +/obj/item/weapon/reagent_containers/food/snacks/candy_corn + name = "candy corn" + desc = "It's a handful of candy corn. Cannot be stored in a detective's hat, alas." + icon_state = "candy_corn" + filling_color = "#FFFCB0" + center_of_mass = list("x"=14, "y"=10) + nutriment_amt = 4 + nutriment_desc = list("candy corn" = 4) + +/obj/item/weapon/reagent_containers/food/snacks/candy_corn/New() + ..() + reagents.add_reagent("sugar", 2) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/chips + name = "chips" + desc = "Commander Riker's What-The-Crisps" + icon_state = "chips" + trash = /obj/item/trash/chips + filling_color = "#E8C31E" + center_of_mass = list("x"=15, "y"=15) + nutriment_amt = 3 + nutriment_desc = list("salt" = 1, "chips" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/chips/Initialize() + . = ..() + bitesize = 1 + +/obj/item/weapon/reagent_containers/food/snacks/cookie + name = "cookie" + desc = "COOKIE!!!" + icon_state = "COOKIE!!!" + filling_color = "#DBC94F" + center_of_mass = list("x"=17, "y"=18) + nutriment_amt = 5 + nutriment_desc = list("sweetness" = 3, "cookie" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/cookie/Initialize() + . = ..() + bitesize = 1 + +/obj/item/weapon/reagent_containers/food/snacks/chocolatebar + name = "Chocolate Bar" + desc = "Such sweet, fattening food." + icon_state = "chocolatebar" + filling_color = "#7D5F46" + center_of_mass = list("x"=15, "y"=15) + nutriment_amt = 2 + nutriment_desc = list("chocolate" = 5) + +/obj/item/weapon/reagent_containers/food/snacks/chocolatebar/Initialize() + . = ..() + reagents.add_reagent("sugar", 2) + reagents.add_reagent("coco", 2) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/chocolatepiece + name = "chocolate piece" + desc = "A luscious milk chocolate piece filled with gooey caramel." + icon_state = "chocolatepiece" + filling_color = "#7D5F46" + center_of_mass = list("x"=15, "y"=15) + nutriment_amt = 1 + nutriment_desc = list("chocolate" = 3, "caramel" = 2, "lusciousness" = 1) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/chocolatepiece/white + name = "white chocolate piece" + desc = "A creamy white chocolate piece drizzled in milk chocolate." + icon_state = "chocolatepiece_white" + filling_color = "#E2DAD3" + nutriment_desc = list("white chocolate" = 3, "creaminess" = 1) + +/obj/item/weapon/reagent_containers/food/snacks/chocolatepiece/truffle + name = "chocolate truffle" + desc = "A bite-sized milk chocolate truffle that could buy anyone's love." + icon_state = "chocolatepiece_truffle" + nutriment_desc = list("chocolate" = 3, "undying devotion" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/chocolateegg + name = "Chocolate Egg" + desc = "Such sweet, fattening food." + icon_state = "chocolateegg" + filling_color = "#7D5F46" + center_of_mass = list("x"=16, "y"=13) + nutriment_amt = 3 + nutriment_desc = list("chocolate" = 5) + +/obj/item/weapon/reagent_containers/food/snacks/chocolateegg/Initialize() + . = ..() + reagents.add_reagent("sugar", 2) + reagents.add_reagent("coco", 2) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/donut + name = "donut" + desc = "Goes great with Robust Coffee." + icon_state = "donut1" + filling_color = "#D9C386" + var/overlay_state = "box-donut1" + center_of_mass = list("x"=13, "y"=16) + nutriment_desc = list("sweetness", "donut") + +/obj/item/weapon/reagent_containers/food/snacks/donut/normal + name = "donut" + desc = "Goes great with Robust Coffee." + icon_state = "donut1" + nutriment_amt = 3 + +/obj/item/weapon/reagent_containers/food/snacks/donut/normal/Initialize() + . = ..() + reagents.add_reagent("nutriment", 3) + reagents.add_reagent("sprinkles", 1) + src.bitesize = 3 + if(prob(30)) + src.icon_state = "donut2" + src.overlay_state = "box-donut2" + src.name = "frosted donut" + reagents.add_reagent("sprinkles", 2) + center_of_mass = list("x"=19, "y"=16) + +/obj/item/weapon/reagent_containers/food/snacks/donut/chaos + name = "Chaos Donut" + desc = "Like life, it never quite tastes the same." + icon_state = "donut1" + filling_color = "#ED11E6" + nutriment_amt = 2 + +/obj/item/weapon/reagent_containers/food/snacks/donut/chaos/Initialize() + . = ..() + reagents.add_reagent("sprinkles", 1) + bitesize = 10 + var/chaosselect = pick(1,2,3,4,5,6,7,8,9,10) + switch(chaosselect) + if(1) + reagents.add_reagent("nutriment", 3) + if(2) + reagents.add_reagent("capsaicin", 3) + if(3) + reagents.add_reagent("frostoil", 3) + if(4) + reagents.add_reagent("sprinkles", 3) + if(5) + reagents.add_reagent("phoron", 3) + if(6) + reagents.add_reagent("coco", 3) + if(7) + reagents.add_reagent("slimejelly", 3) + if(8) + reagents.add_reagent("banana", 3) + if(9) + reagents.add_reagent("berryjuice", 3) + if(10) + reagents.add_reagent("tricordrazine", 3) + if(prob(30)) + src.icon_state = "donut2" + src.overlay_state = "box-donut2" + src.name = "Frosted Chaos Donut" + reagents.add_reagent("sprinkles", 2) + +/obj/item/weapon/reagent_containers/food/snacks/donut/jelly + name = "Jelly Donut" + desc = "You jelly?" + icon_state = "jdonut1" + filling_color = "#ED1169" + center_of_mass = list("x"=16, "y"=11) + nutriment_amt = 3 + +/obj/item/weapon/reagent_containers/food/snacks/donut/jelly/Initialize() + . = ..() + reagents.add_reagent("sprinkles", 1) + reagents.add_reagent("berryjuice", 5) + bitesize = 5 + if(prob(30)) + src.icon_state = "jdonut2" + src.overlay_state = "box-donut2" + src.name = "Frosted Jelly Donut" + reagents.add_reagent("sprinkles", 2) + +/obj/item/weapon/reagent_containers/food/snacks/donut/slimejelly + name = "Jelly Donut" + desc = "You jelly?" + icon_state = "jdonut1" + filling_color = "#ED1169" + center_of_mass = list("x"=16, "y"=11) + nutriment_amt = 3 + +/obj/item/weapon/reagent_containers/food/snacks/donut/slimejelly/Initialize() + . = ..() + reagents.add_reagent("sprinkles", 1) + reagents.add_reagent("slimejelly", 5) + bitesize = 5 + if(prob(30)) + src.icon_state = "jdonut2" + src.overlay_state = "box-donut2" + src.name = "Frosted Jelly Donut" + reagents.add_reagent("sprinkles", 2) + +/obj/item/weapon/reagent_containers/food/snacks/donut/cherryjelly + name = "Jelly Donut" + desc = "You jelly?" + icon_state = "jdonut1" + filling_color = "#ED1169" + center_of_mass = list("x"=16, "y"=11) + nutriment_amt = 3 + +/obj/item/weapon/reagent_containers/food/snacks/donut/cherryjelly/Initialize() + . = ..() + reagents.add_reagent("sprinkles", 1) + reagents.add_reagent("cherryjelly", 5) + bitesize = 5 + if(prob(30)) + src.icon_state = "jdonut2" + src.overlay_state = "box-donut2" + src.name = "Frosted Jelly Donut" + reagents.add_reagent("sprinkles", 2) + +/obj/item/weapon/reagent_containers/food/snacks/egg + name = "egg" + desc = "An egg!" + icon_state = "egg" + filling_color = "#FDFFD1" + volume = 10 + center_of_mass = list("x"=16, "y"=13) + +/obj/item/weapon/reagent_containers/food/snacks/egg/Initialize() + . = ..() + reagents.add_reagent("egg", 3) + +/obj/item/weapon/reagent_containers/food/snacks/egg/afterattack(obj/O as obj, mob/user as mob, proximity) + if(istype(O,/obj/machinery/microwave)) + return ..() + if(!(proximity && O.is_open_container())) + return + user << "You crack \the [src] into \the [O]." + reagents.trans_to(O, reagents.total_volume) + user.drop_from_inventory(src) + qdel(src) + +/obj/item/weapon/reagent_containers/food/snacks/egg/throw_impact(atom/hit_atom) + ..() + new/obj/effect/decal/cleanable/egg_smudge(src.loc) + src.reagents.splash(hit_atom, reagents.total_volume) + src.visible_message("[src.name] has been squashed.","You hear a smack.") + qdel(src) + +/obj/item/weapon/reagent_containers/food/snacks/egg/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype( W, /obj/item/weapon/pen/crayon )) + var/obj/item/weapon/pen/crayon/C = W + var/clr = C.colourName + + if(!(clr in list("blue","green","mime","orange","purple","rainbow","red","yellow"))) + usr << "The egg refuses to take on this color!" + return + + usr << "You color \the [src] [clr]" + icon_state = "egg-[clr]" + else + ..() + +/obj/item/weapon/reagent_containers/food/snacks/egg/blue + icon_state = "egg-blue" + +/obj/item/weapon/reagent_containers/food/snacks/egg/green + icon_state = "egg-green" + +/obj/item/weapon/reagent_containers/food/snacks/egg/mime + icon_state = "egg-mime" + +/obj/item/weapon/reagent_containers/food/snacks/egg/orange + icon_state = "egg-orange" + +/obj/item/weapon/reagent_containers/food/snacks/egg/purple + icon_state = "egg-purple" + +/obj/item/weapon/reagent_containers/food/snacks/egg/rainbow + icon_state = "egg-rainbow" + +/obj/item/weapon/reagent_containers/food/snacks/egg/red + icon_state = "egg-red" + +/obj/item/weapon/reagent_containers/food/snacks/egg/yellow + icon_state = "egg-yellow" + +/obj/item/weapon/reagent_containers/food/snacks/friedegg + name = "Fried egg" + desc = "A fried egg, with a touch of salt and pepper." + icon_state = "friedegg" + filling_color = "#FFDF78" + center_of_mass = list("x"=16, "y"=14) + +/obj/item/weapon/reagent_containers/food/snacks/friedegg/Initialize() + . = ..() + reagents.add_reagent("protein", 3) + reagents.add_reagent("sodiumchloride", 1) + reagents.add_reagent("blackpepper", 1) + bitesize = 1 + +/obj/item/weapon/reagent_containers/food/snacks/boiledegg + name = "Boiled egg" + desc = "A hard boiled egg." + icon_state = "egg" + filling_color = "#FFFFFF" + +/obj/item/weapon/reagent_containers/food/snacks/boiledegg/Initialize() + . = ..() + reagents.add_reagent("protein", 2) + +/obj/item/weapon/reagent_containers/food/snacks/organ + name = "organ" + desc = "It's good for you." + icon = 'icons/obj/surgery.dmi' + icon_state = "appendix" + filling_color = "#E00D34" + center_of_mass = list("x"=16, "y"=16) + +/obj/item/weapon/reagent_containers/food/snacks/organ/Initialize() + . = ..() + reagents.add_reagent("protein", rand(3,5)) + reagents.add_reagent("toxin", rand(1,3)) + src.bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/tofu + name = "Tofu" + icon_state = "tofu" + desc = "We all love tofu." + filling_color = "#FFFEE0" + center_of_mass = list("x"=17, "y"=10) + nutriment_amt = 3 + nutriment_desc = list("tofu" = 3, "goeyness" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/tofu/Initialize() + . = ..() + src.bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/tofurkey + name = "Tofurkey" + desc = "A fake turkey made from tofu." + icon_state = "tofurkey" + filling_color = "#FFFEE0" + center_of_mass = list("x"=16, "y"=8) + nutriment_amt = 12 + nutriment_desc = list("turkey" = 3, "tofu" = 5, "goeyness" = 4) + +/obj/item/weapon/reagent_containers/food/snacks/tofurkey/Initialize() + . = ..() + reagents.add_reagent("stoxin", 3) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/stuffing + name = "Stuffing" + desc = "Moist, peppery breadcrumbs for filling the body cavities of dead birds. Dig in!" + icon_state = "stuffing" + filling_color = "#C9AC83" + center_of_mass = list("x"=16, "y"=10) + nutriment_amt = 3 + nutriment_desc = list("dryness" = 2, "bread" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/stuffing/Initialize() + . = ..() + bitesize = 1 + +/obj/item/weapon/reagent_containers/food/snacks/carpmeat + name = "carp fillet" + desc = "A fillet of spess carp meat" + icon_state = "fishfillet" + filling_color = "#FFDEFE" + center_of_mass = list("x"=17, "y"=13) + +/obj/item/weapon/reagent_containers/food/snacks/carpmeat/Initialize() + . = ..() + reagents.add_reagent("protein", 3) + reagents.add_reagent("carpotoxin", 3) + src.bitesize = 6 + +/obj/item/weapon/reagent_containers/food/snacks/fishfingers + name = "Fish Fingers" + desc = "A finger of fish." + icon_state = "fishfingers" + filling_color = "#FFDEFE" + center_of_mass = list("x"=16, "y"=13) + +/obj/item/weapon/reagent_containers/food/snacks/fishfingers/Initialize() + . = ..() + reagents.add_reagent("protein", 4) + reagents.add_reagent("carpotoxin", 3) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/hugemushroomslice + name = "huge mushroom slice" + desc = "A slice from a huge mushroom." + icon_state = "hugemushroomslice" + filling_color = "#E0D7C5" + center_of_mass = list("x"=17, "y"=16) + nutriment_amt = 3 + nutriment_desc = list("raw" = 2, "mushroom" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/hugemushroomslice/Initialize() + . = ..() + reagents.add_reagent("psilocybin", 3) + src.bitesize = 6 + +/obj/item/weapon/reagent_containers/food/snacks/tomatomeat + name = "tomato slice" + desc = "A slice from a huge tomato" + icon_state = "tomatomeat" + filling_color = "#DB0000" + center_of_mass = list("x"=17, "y"=16) + nutriment_amt = 3 + nutriment_desc = list("raw" = 2, "tomato" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/tomatomeat/Initialize() + . = ..() + src.bitesize = 6 + +/obj/item/weapon/reagent_containers/food/snacks/bearmeat + name = "bear meat" + desc = "A very manly slab of meat." + icon_state = "bearmeat" + filling_color = "#DB0000" + center_of_mass = list("x"=16, "y"=10) + +/obj/item/weapon/reagent_containers/food/snacks/bearmeat/Initialize() + . = ..() + reagents.add_reagent("protein", 12) + reagents.add_reagent("hyperzine", 5) + src.bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/xenomeat + name = "xenomeat" + desc = "A slab of green meat. Smells like acid." + icon_state = "xenomeat" + filling_color = "#43DE18" + center_of_mass = list("x"=16, "y"=10) + +/obj/item/weapon/reagent_containers/food/snacks/xenomeat/Initialize() + . = ..() + reagents.add_reagent("protein", 6) + reagents.add_reagent("pacid",6) + src.bitesize = 6 + +/obj/item/weapon/reagent_containers/food/snacks/xenomeat/spidermeat // Substitute for recipes requiring xeno meat. + name = "spider meat" + desc = "A slab of green meat." + icon_state = "xenomeat" + filling_color = "#43DE18" + center_of_mass = list("x"=16, "y"=10) + +/obj/item/weapon/reagent_containers/food/snacks/xenomeat/spidermeat/Initialize() + . = ..() + reagents.add_reagent("spidertoxin",6) + reagents.remove_reagent("pacid",6) + src.bitesize = 6 + +/obj/item/weapon/reagent_containers/food/snacks/meatball + name = "meatball" + desc = "A great meal all round." + icon_state = "meatball" + filling_color = "#DB0000" + center_of_mass = list("x"=16, "y"=16) + +/obj/item/weapon/reagent_containers/food/snacks/meatball/Initialize() + . = ..() + reagents.add_reagent("protein", 3) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/sausage + name = "Sausage" + desc = "A piece of mixed, long meat." + icon_state = "sausage" + filling_color = "#DB0000" + center_of_mass = list("x"=16, "y"=16) + +/obj/item/weapon/reagent_containers/food/snacks/sausage/Initialize() + . = ..() + reagents.add_reagent("protein", 6) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/donkpocket + name = "Donk-pocket" + desc = "The food of choice for the seasoned traitor." + icon_state = "donkpocket" + filling_color = "#DEDEAB" + center_of_mass = list("x"=16, "y"=10) + var/warm + var/list/heated_reagents + +/obj/item/weapon/reagent_containers/food/snacks/donkpocket/Initialize() + . = ..() + reagents.add_reagent("nutriment", 2) + reagents.add_reagent("protein", 2) + + warm = 0 + heated_reagents = list("tricordrazine" = 5) + +/obj/item/weapon/reagent_containers/food/snacks/donkpocket/proc/heat() + warm = 1 + for(var/reagent in heated_reagents) + reagents.add_reagent(reagent, heated_reagents[reagent]) + bitesize = 6 + name = "Warm " + name + cooltime() + +/obj/item/weapon/reagent_containers/food/snacks/donkpocket/proc/cooltime() + if (src.warm) + spawn(4200) + src.warm = 0 + for(var/reagent in heated_reagents) + src.reagents.del_reagent(reagent) + src.name = initial(name) + return + +/obj/item/weapon/reagent_containers/food/snacks/donkpocket/sinpocket + name = "\improper Sin-pocket" + desc = "The food of choice for the veteran. Do NOT overconsume." + filling_color = "#6D6D00" + heated_reagents = list("doctorsdelight" = 5, "hyperzine" = 0.75, "synaptizine" = 0.25) + var/has_been_heated = 0 + +/obj/item/weapon/reagent_containers/food/snacks/donkpocket/sinpocket/attack_self(mob/user) + if(has_been_heated) + user << "The heating chemicals have already been spent." + return + has_been_heated = 1 + user.visible_message("[user] crushes \the [src] package.", "You crush \the [src] package and feel a comfortable heat build up.") + spawn(200) + user << "You think \the [src] is ready to eat about now." + heat() + +/obj/item/weapon/reagent_containers/food/snacks/brainburger + name = "brainburger" + desc = "A strange looking burger. It looks almost sentient." + icon_state = "brainburger" + filling_color = "#F2B6EA" + center_of_mass = list("x"=15, "y"=11) + +/obj/item/weapon/reagent_containers/food/snacks/brainburger/Initialize() + . = ..() + reagents.add_reagent("protein", 6) + reagents.add_reagent("alkysine", 6) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/ghostburger + name = "Ghost Burger" + desc = "Spooky! It doesn't look very filling." + icon_state = "ghostburger" + filling_color = "#FFF2FF" + center_of_mass = list("x"=16, "y"=11) + nutriment_desc = list("buns" = 3, "spookiness" = 3) + nutriment_amt = 2 + +/obj/item/weapon/reagent_containers/food/snacks/ghostburger/Initialize() + . = ..() + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/human + var/hname = "" + var/job = null + filling_color = "#D63C3C" + +/obj/item/weapon/reagent_containers/food/snacks/human/burger + name = "-burger" + desc = "A bloody burger." + icon_state = "hburger" + center_of_mass = list("x"=16, "y"=11) + +/obj/item/weapon/reagent_containers/food/snacks/human/burger/Initialize() + . = ..() + reagents.add_reagent("protein", 6) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/cheeseburger + name = "cheeseburger" + desc = "The cheese adds a good flavor." + icon_state = "cheeseburger" + center_of_mass = list("x"=16, "y"=11) + nutriment_amt = 2 + nutriment_desc = list("cheese" = 2, "bun" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/cheeseburger/Initialize() + . = ..() + reagents.add_reagent("protein", 2) + +/obj/item/weapon/reagent_containers/food/snacks/monkeyburger + name = "burger" + desc = "The cornerstone of every nutritious breakfast." + icon_state = "hburger" + filling_color = "#D63C3C" + center_of_mass = list("x"=16, "y"=11) + nutriment_amt = 3 + nutriment_desc = list("bun" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/monkeyburger/Initialize() + . = ..() + reagents.add_reagent("protein", 3) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/fishburger + name = "Fillet -o- Carp Sandwich" + desc = "Almost like a carp is yelling somewhere... Give me back that fillet -o- carp, give me that carp." + icon_state = "fishburger" + filling_color = "#FFDEFE" + center_of_mass = list("x"=16, "y"=10) + +/obj/item/weapon/reagent_containers/food/snacks/fishburger/Initialize() + . = ..() + reagents.add_reagent("protein", 6) + reagents.add_reagent("carpotoxin", 3) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/tofuburger + name = "Tofu Burger" + desc = "What.. is that meat?" + icon_state = "tofuburger" + filling_color = "#FFFEE0" + center_of_mass = list("x"=16, "y"=10) + nutriment_amt = 6 + nutriment_desc = list("bun" = 2, "pseudo-soy meat" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/tofuburger/Initialize() + . = ..() + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/roburger + name = "roburger" + desc = "The lettuce is the only organic component. Beep." + icon_state = "roburger" + filling_color = "#CCCCCC" + center_of_mass = list("x"=16, "y"=11) + nutriment_amt = 2 + nutriment_desc = list("bun" = 2, "metal" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/roburger/Initialize() + . = ..() + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/roburgerbig + name = "roburger" + desc = "This massive patty looks like poison. Beep." + icon_state = "roburger" + filling_color = "#CCCCCC" + volume = 100 + center_of_mass = list("x"=16, "y"=11) + +/obj/item/weapon/reagent_containers/food/snacks/roburgerbig/Initialize() + . = ..() + bitesize = 0.1 + +/obj/item/weapon/reagent_containers/food/snacks/xenoburger + name = "xenoburger" + desc = "Smells caustic. Tastes like heresy." + icon_state = "xburger" + filling_color = "#43DE18" + center_of_mass = list("x"=16, "y"=11) + +/obj/item/weapon/reagent_containers/food/snacks/xenoburger/Initialize() + . = ..() + reagents.add_reagent("protein", 8) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/clownburger + name = "Clown Burger" + desc = "This tastes funny..." + icon_state = "clownburger" + filling_color = "#FF00FF" + center_of_mass = list("x"=17, "y"=12) + nutriment_amt = 6 + nutriment_desc = list("bun" = 2, "clown shoe" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/clownburger/Initialize() + . = ..() + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/mimeburger + name = "Mime Burger" + desc = "Its taste defies language." + icon_state = "mimeburger" + filling_color = "#FFFFFF" + center_of_mass = list("x"=16, "y"=11) + nutriment_amt = 6 + nutriment_desc = list("bun" = 2, "face paint" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/mimeburger/Initialize() + . = ..() + reagents.add_reagent("nutriment", 6) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/omelette + name = "Omelette Du Fromage" + desc = "That's all you can say!" + icon_state = "omelette" + trash = /obj/item/trash/plate + filling_color = "#FFF9A8" + center_of_mass = list("x"=16, "y"=13) + +/obj/item/weapon/reagent_containers/food/snacks/omelette/Initialize() + . = ..() + reagents.add_reagent("protein", 8) + bitesize = 1 + +/obj/item/weapon/reagent_containers/food/snacks/muffin + name = "Muffin" + desc = "A delicious and spongy little cake" + icon_state = "muffin" + filling_color = "#E0CF9B" + center_of_mass = list("x"=17, "y"=4) + nutriment_amt = 6 + nutriment_desc = list("sweetness" = 3, "muffin" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/muffin/Initialize() + . = ..() + reagents.add_reagent("nutriment", 6) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/pie + name = "Banana Cream Pie" + desc = "Just like back home, on clown planet! HONK!" + icon_state = "pie" + trash = /obj/item/trash/plate + filling_color = "#FBFFB8" + center_of_mass = list("x"=16, "y"=13) + nutriment_amt = 4 + nutriment_desc = list("pie" = 3, "cream" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/pie/Initialize() + . = ..() + reagents.add_reagent("banana",5) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/pie/throw_impact(atom/hit_atom) + ..() + new/obj/effect/decal/cleanable/pie_smudge(src.loc) + src.visible_message("\The [src.name] splats.","You hear a splat.") + qdel(src) + +/obj/item/weapon/reagent_containers/food/snacks/berryclafoutis + name = "Berry Clafoutis" + desc = "No black birds, this is a good sign." + icon_state = "berryclafoutis" + trash = /obj/item/trash/plate + center_of_mass = list("x"=16, "y"=13) + nutriment_amt = 4 + nutriment_desc = list("sweetness" = 2, "pie" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/berryclafoutis/Initialize() + . = ..() + reagents.add_reagent("berryjuice", 5) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/waffles + name = "waffles" + desc = "Mmm, waffles" + icon_state = "waffles" + trash = /obj/item/trash/waffles + filling_color = "#E6DEB5" + center_of_mass = list("x"=15, "y"=11) + nutriment_amt = 8 + nutriment_desc = list("waffle" = 8) + +/obj/item/weapon/reagent_containers/food/snacks/waffles/Initialize() + . = ..() + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/eggplantparm + name = "Eggplant Parmigiana" + desc = "The only good recipe for eggplant." + icon_state = "eggplantparm" + trash = /obj/item/trash/plate + filling_color = "#4D2F5E" + center_of_mass = list("x"=16, "y"=11) + nutriment_amt = 6 + nutriment_desc = list("cheese" = 3, "eggplant" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/eggplantparm/Initialize() + . = ..() + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/soylentgreen + name = "Soylent Green" + desc = "Not made of people. Honest." //Totally people. + icon_state = "soylent_green" + trash = /obj/item/trash/waffles + filling_color = "#B8E6B5" + center_of_mass = list("x"=15, "y"=11) + +/obj/item/weapon/reagent_containers/food/snacks/soylentgreen/Initialize() + . = ..() + reagents.add_reagent("protein", 10) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/soylenviridians + name = "Soylen Virdians" + desc = "Not made of people. Honest." //Actually honest for once. + icon_state = "soylent_yellow" + trash = /obj/item/trash/waffles + filling_color = "#E6FA61" + center_of_mass = list("x"=15, "y"=11) + nutriment_amt = 10 + nutriment_desc = list("some sort of protein" = 10) //seasoned VERY well. + +/obj/item/weapon/reagent_containers/food/snacks/soylenviridians/Initialize() + . = ..() + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/meatpie + name = "Meat-pie" + icon_state = "meatpie" + desc = "An old barber recipe, very delicious!" + trash = /obj/item/trash/plate + filling_color = "#948051" + center_of_mass = list("x"=16, "y"=13) + +/obj/item/weapon/reagent_containers/food/snacks/meatpie/Initialize() + . = ..() + reagents.add_reagent("protein", 10) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/tofupie + name = "Tofu-pie" + icon_state = "meatpie" + desc = "A delicious tofu pie." + trash = /obj/item/trash/plate + filling_color = "#FFFEE0" + center_of_mass = list("x"=16, "y"=13) + nutriment_amt = 10 + nutriment_desc = list("tofu" = 2, "pie" = 8) + +/obj/item/weapon/reagent_containers/food/snacks/tofupie/Initialize() + . = ..() + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/amanita_pie + name = "amanita pie" + desc = "Sweet and tasty poison pie." + icon_state = "amanita_pie" + filling_color = "#FFCCCC" + center_of_mass = list("x"=17, "y"=9) + nutriment_amt = 5 + nutriment_desc = list("sweetness" = 3, "mushroom" = 3, "pie" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/amanita_pie/New() + ..() + reagents.add_reagent("amatoxin", 3) + reagents.add_reagent("psilocybin", 1) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/plump_pie + name = "plump pie" + desc = "I bet you love stuff made out of plump helmets!" + icon_state = "plump_pie" + filling_color = "#B8279B" + center_of_mass = list("x"=17, "y"=9) + nutriment_amt = 8 + nutriment_desc = list("heartiness" = 2, "mushroom" = 3, "pie" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/plump_pie/New() + ..() + if(prob(10)) + name = "exceptional plump pie" + desc = "Microwave is taken by a fey mood! It has cooked an exceptional plump pie!" + reagents.add_reagent("nutriment", 8) + reagents.add_reagent("tricordrazine", 5) + bitesize = 2 + else + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/xemeatpie + name = "Xeno-pie" + icon_state = "xenomeatpie" + desc = "A delicious meatpie. Probably heretical." + trash = /obj/item/trash/plate + filling_color = "#43DE18" + center_of_mass = list("x"=16, "y"=13) + +/obj/item/weapon/reagent_containers/food/snacks/xemeatpie/Initialize() + . = ..() + reagents.add_reagent("protein", 10) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/wingfangchu + name = "Wing Fang Chu" + desc = "A savory dish of alien wing wang in soy." + icon_state = "wingfangchu" + trash = /obj/item/trash/snack_bowl + filling_color = "#43DE18" + center_of_mass = list("x"=17, "y"=9) + +/obj/item/weapon/reagent_containers/food/snacks/wingfangchu/Initialize() + . = ..() + reagents.add_reagent("protein", 6) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/human/kabob + name = "-kabob" + icon_state = "kabob" + desc = "A human meat, on a stick." + trash = /obj/item/stack/rods + filling_color = "#A85340" + center_of_mass = list("x"=17, "y"=15) + +/obj/item/weapon/reagent_containers/food/snacks/human/kabob/Initialize() + . = ..() + reagents.add_reagent("protein", 8) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/monkeykabob + name = "Meat-kabob" + icon_state = "kabob" + desc = "Delicious meat, on a stick." + trash = /obj/item/stack/rods + filling_color = "#A85340" + center_of_mass = list("x"=17, "y"=15) + +/obj/item/weapon/reagent_containers/food/snacks/monkeykabob/Initialize() + . = ..() + reagents.add_reagent("protein", 8) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/tofukabob + name = "Tofu-kabob" + icon_state = "kabob" + desc = "Vegan meat, on a stick." + trash = /obj/item/stack/rods + filling_color = "#FFFEE0" + + center_of_mass = list("x"=17, "y"=15) + nutriment_amt = 8 + nutriment_desc = list("tofu" = 3, "metal" = 1) + +/obj/item/weapon/reagent_containers/food/snacks/tofukabob/Initialize() + . = ..() + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/cubancarp + name = "Cuban Carp" + desc = "A sandwich that burns your tongue and then leaves it numb!" + icon_state = "cubancarp" + trash = /obj/item/trash/plate + filling_color = "#E9ADFF" + center_of_mass = list("x"=12, "y"=5) + nutriment_amt = 3 + nutriment_desc = list("toasted bread" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/cubancarp/Initialize() + . = ..() + reagents.add_reagent("protein", 3) + reagents.add_reagent("carpotoxin", 3) + reagents.add_reagent("capsaicin", 3) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/popcorn + name = "Popcorn" + desc = "Now let's find some cinema." + icon_state = "popcorn" + trash = /obj/item/trash/popcorn + var/unpopped = 0 + filling_color = "#FFFAD4" + center_of_mass = list("x"=16, "y"=8) + nutriment_amt = 2 + nutriment_desc = list("popcorn" = 3) + + +/obj/item/weapon/reagent_containers/food/snacks/popcorn/Initialize() + . = ..() + unpopped = rand(1,10) + bitesize = 0.1 //this snack is supposed to be eating during looooong time. And this it not dinner food! --rastaf0 + +/obj/item/weapon/reagent_containers/food/snacks/popcorn/On_Consume() + if(prob(unpopped)) //lol ...what's the point? + usr << "You bite down on an un-popped kernel!" + unpopped = max(0, unpopped-1) + ..() + +/obj/item/weapon/reagent_containers/food/snacks/sosjerky + name = "Scaredy's Private Reserve Beef Jerky" + icon_state = "sosjerky" + desc = "Beef jerky made from the finest space cows." + trash = /obj/item/trash/sosjerky + filling_color = "#631212" + center_of_mass = list("x"=15, "y"=9) + +/obj/item/weapon/reagent_containers/food/snacks/sosjerky/New() + ..() + reagents.add_reagent("protein", 4) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/no_raisin + name = "4no Raisins" + icon_state = "4no_raisins" + desc = "Best raisins in the universe. Not sure why." + trash = /obj/item/trash/raisins + filling_color = "#343834" + center_of_mass = list("x"=15, "y"=4) + nutriment_amt = 6 + nutriment_desc = list("dried raisins" = 6) + +/obj/item/weapon/reagent_containers/food/snacks/no_raisin/New() + ..() + reagents.add_reagent("nutriment", 6) + +/obj/item/weapon/reagent_containers/food/snacks/spacetwinkie + name = "Space Twinkie" + icon_state = "space_twinkie" + desc = "Guaranteed to survive longer then you will." + filling_color = "#FFE591" + center_of_mass = list("x"=15, "y"=11) + +/obj/item/weapon/reagent_containers/food/snacks/spacetwinkie/Initialize() + . = ..() + reagents.add_reagent("sugar", 4) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers + name = "Cheesie Honkers" + icon_state = "cheesie_honkers" + desc = "Bite sized cheesie snacks that will honk all over your mouth" + trash = /obj/item/trash/cheesie + filling_color = "#FFA305" + center_of_mass = list("x"=15, "y"=9) + nutriment_amt = 4 + nutriment_desc = list("cheese" = 5, "chips" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers/Initialize() + . = ..() + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/syndicake + name = "Syndi-Cakes" + icon_state = "syndi_cakes" + desc = "An extremely moist snack cake that tastes just as good after being nuked." + filling_color = "#FF5D05" + center_of_mass = list("x"=16, "y"=10) + trash = /obj/item/trash/syndi_cakes + nutriment_amt = 4 + nutriment_desc = list("sweetness" = 3, "cake" = 1) + +/obj/item/weapon/reagent_containers/food/snacks/syndicake/Initialize() + . = ..() + reagents.add_reagent("doctorsdelight", 5) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/loadedbakedpotato + name = "Loaded Baked Potato" + desc = "Totally baked." + icon_state = "loadedbakedpotato" + filling_color = "#9C7A68" + center_of_mass = list("x"=16, "y"=10) + nutriment_amt = 3 + nutriment_desc = list("baked potato" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/loadedbakedpotato/Initialize() + . = ..() + reagents.add_reagent("protein", 3) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/fries + name = "Space Fries" + desc = "AKA: French Fries, Freedom Fries, etc." + icon_state = "fries" + trash = /obj/item/trash/plate + filling_color = "#EDDD00" + center_of_mass = list("x"=16, "y"=11) + nutriment_amt = 4 + nutriment_desc = list("fresh fries" = 4) + +/obj/item/weapon/reagent_containers/food/snacks/fries/Initialize() + . = ..() + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/mashedpotato + name = "Mashed Potato" + desc = "Pillowy mounds of mashed potato." + icon_state = "mashedpotato" + trash = /obj/item/trash/plate + filling_color = "#EDDD00" + center_of_mass = list("x"=16, "y"=11) + nutriment_amt = 4 + nutriment_desc = list("fluffy mashed potatoes" = 4) + +/obj/item/weapon/reagent_containers/food/snacks/mashedpotato/Initialize() + . = ..() + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/bangersandmash + name = "Bangers and Mash" + desc = "An English treat." + icon_state = "bangersandmash" + trash = /obj/item/trash/plate + filling_color = "#EDDD00" + center_of_mass = list("x"=16, "y"=11) + nutriment_amt = 4 + nutriment_desc = list("fluffy potato" = 3, "sausage" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/bangersandmash/Initialize() + . = ..() + reagents.add_reagent("protein", 3) + bitesize = 4 + +/obj/item/weapon/reagent_containers/food/snacks/cheesymash + name = "Cheesy Mashed Potato" + desc = "The only thing that could make mash better." + icon_state = "cheesymash" + trash = /obj/item/trash/plate + filling_color = "#EDDD00" + center_of_mass = list("x"=16, "y"=11) + nutriment_amt = 4 + nutriment_desc = list("cheesy potato" = 4) + +/obj/item/weapon/reagent_containers/food/snacks/cheesymash/Initialize() + . = ..() + reagents.add_reagent("protein", 3) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/blackpudding + name = "Black Pudding" + desc = "This doesn't seem like a pudding at all." + icon_state = "blackpudding" + filling_color = "#FF0000" + center_of_mass = list("x"=16, "y"=7) + +/obj/item/weapon/reagent_containers/food/snacks/blackpudding/Initialize() + . = ..() + reagents.add_reagent("protein", 2) + reagents.add_reagent("blood", 5) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/soydope + name = "Soy Dope" + desc = "Dope from a soy." + icon_state = "soydope" + trash = /obj/item/trash/plate + filling_color = "#C4BF76" + center_of_mass = list("x"=16, "y"=10) + nutriment_amt = 2 + nutriment_desc = list("slime" = 2, "soy" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/soydope/Initialize() + . = ..() + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/spagetti + name = "Spaghetti" + desc = "A bundle of raw spaghetti." + icon_state = "spagetti" + filling_color = "#EDDD00" + center_of_mass = list("x"=16, "y"=16) + nutriment_amt = 1 + nutriment_desc = list("noodles" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/spagetti/Initialize() + . = ..() + bitesize = 1 + +/obj/item/weapon/reagent_containers/food/snacks/cheesyfries + name = "Cheesy Fries" + desc = "Fries. Covered in cheese. Duh." + icon_state = "cheesyfries" + trash = /obj/item/trash/plate + filling_color = "#EDDD00" + center_of_mass = list("x"=16, "y"=11) + nutriment_amt = 4 + nutriment_desc = list("fresh fries" = 3, "cheese" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/cheesyfries/Initialize() + . = ..() + reagents.add_reagent("protein", 2) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/fortunecookie + name = "Fortune cookie" + desc = "A true prophecy in each cookie!" + icon_state = "fortune_cookie" + filling_color = "#E8E79E" + center_of_mass = list("x"=15, "y"=14) + nutriment_amt = 3 + nutriment_desc = list("fortune cookie" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/fortunecookie/Initialize() + . = ..() + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/badrecipe + name = "Burned mess" + desc = "Someone should be demoted from chef for this." + icon_state = "badrecipe" + filling_color = "#211F02" + center_of_mass = list("x"=16, "y"=12) + +/obj/item/weapon/reagent_containers/food/snacks/badrecipe/Initialize() + . = ..() + reagents.add_reagent("toxin", 1) + reagents.add_reagent("carbon", 3) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/meatsteak + name = "Meat steak" + desc = "A piece of hot spicy meat." + icon_state = "meatstake" + trash = /obj/item/trash/plate + filling_color = "#7A3D11" + center_of_mass = list("x"=16, "y"=13) + +/obj/item/weapon/reagent_containers/food/snacks/meatsteak/Initialize() + . = ..() + reagents.add_reagent("protein", 4) + reagents.add_reagent("sodiumchloride", 1) + reagents.add_reagent("blackpepper", 1) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/spacylibertyduff + name = "Spacy Liberty Duff" + desc = "Jello gelatin, from Alfred Hubbard's cookbook" + icon_state = "spacylibertyduff" + trash = /obj/item/trash/snack_bowl + filling_color = "#42B873" + center_of_mass = list("x"=16, "y"=8) + nutriment_amt = 6 + nutriment_desc = list("mushroom" = 6) + +/obj/item/weapon/reagent_containers/food/snacks/spacylibertyduff/Initialize() + . = ..() + reagents.add_reagent("psilocybin", 6) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/amanitajelly + name = "Amanita Jelly" + desc = "Looks curiously toxic" + icon_state = "amanitajelly" + trash = /obj/item/trash/snack_bowl + filling_color = "#ED0758" + center_of_mass = list("x"=16, "y"=5) + nutriment_amt = 6 + nutriment_desc = list("jelly" = 3, "mushroom" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/amanitajelly/Initialize() + . = ..() + reagents.add_reagent("amatoxin", 6) + reagents.add_reagent("psilocybin", 3) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/poppypretzel + name = "Poppy pretzel" + desc = "It's all twisted up!" + icon_state = "poppypretzel" + bitesize = 2 + filling_color = "#916E36" + center_of_mass = list("x"=16, "y"=10) + nutriment_amt = 5 + nutriment_desc = list("poppy seeds" = 2, "pretzel" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/poppypretzel/Initialize() + . = ..() + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/meatballsoup + name = "Meatball soup" + desc = "You've got balls kid, BALLS!" + icon_state = "meatballsoup" + trash = /obj/item/trash/snack_bowl + filling_color = "#785210" + center_of_mass = list("x"=16, "y"=8) + +/obj/item/weapon/reagent_containers/food/snacks/meatballsoup/Initialize() + . = ..() + reagents.add_reagent("protein", 8) + reagents.add_reagent("water", 5) + bitesize = 5 + +/obj/item/weapon/reagent_containers/food/snacks/slimesoup + name = "slime soup" + desc = "If no water is available, you may substitute tears." + icon_state = "slimesoup" //nonexistant? + filling_color = "#C4DBA0" + +/obj/item/weapon/reagent_containers/food/snacks/slimesoup/Initialize() + . = ..() + reagents.add_reagent("slimejelly", 5) + reagents.add_reagent("water", 10) + bitesize = 5 + +/obj/item/weapon/reagent_containers/food/snacks/bloodsoup + name = "Tomato soup" + desc = "Smells like copper." + icon_state = "tomatosoup" + filling_color = "#FF0000" + center_of_mass = list("x"=16, "y"=7) + +/obj/item/weapon/reagent_containers/food/snacks/bloodsoup/Initialize() + . = ..() + reagents.add_reagent("protein", 2) + reagents.add_reagent("blood", 10) + reagents.add_reagent("water", 5) + bitesize = 5 + +/obj/item/weapon/reagent_containers/food/snacks/clownstears + name = "Clown's Tears" + desc = "Not very funny." + icon_state = "clownstears" + filling_color = "#C4FBFF" + center_of_mass = list("x"=16, "y"=7) + nutriment_amt = 4 + nutriment_desc = list("salt" = 1, "the worst joke" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/clownstears/Initialize() + . = ..() + reagents.add_reagent("banana", 5) + reagents.add_reagent("water", 10) + bitesize = 5 + +/obj/item/weapon/reagent_containers/food/snacks/vegetablesoup + name = "Vegetable soup" + desc = "A true vegan meal" //TODO + icon_state = "vegetablesoup" + trash = /obj/item/trash/snack_bowl + filling_color = "#AFC4B5" + center_of_mass = list("x"=16, "y"=8) + nutriment_amt = 8 + nutriment_desc = list("carot" = 2, "corn" = 2, "eggplant" = 2, "potato" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/vegetablesoup/Initialize() + . = ..() + reagents.add_reagent("water", 5) + bitesize = 5 + +/obj/item/weapon/reagent_containers/food/snacks/nettlesoup + name = "Nettle soup" + desc = "To think, the botanist would've beat you to death with one of these." + icon_state = "nettlesoup" + trash = /obj/item/trash/snack_bowl + filling_color = "#AFC4B5" + center_of_mass = list("x"=16, "y"=7) + nutriment_amt = 8 + nutriment_desc = list("salad" = 4, "egg" = 2, "potato" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/nettlesoup/Initialize() + . = ..() + reagents.add_reagent("water", 5) + reagents.add_reagent("tricordrazine", 5) + bitesize = 5 + +/obj/item/weapon/reagent_containers/food/snacks/mysterysoup + name = "Mystery soup" + desc = "The mystery is, why aren't you eating it?" + icon_state = "mysterysoup" + trash = /obj/item/trash/snack_bowl + filling_color = "#F082FF" + center_of_mass = list("x"=16, "y"=6) + nutriment_amt = 1 + nutriment_desc = list("backwash" = 1) + +/obj/item/weapon/reagent_containers/food/snacks/mysterysoup/Initialize() + . = ..() + var/mysteryselect = pick(1,2,3,4,5,6,7,8,9,10) + switch(mysteryselect) + if(1) + reagents.add_reagent("nutriment", 6) + reagents.add_reagent("capsaicin", 3) + reagents.add_reagent("tomatojuice", 2) + if(2) + reagents.add_reagent("nutriment", 6) + reagents.add_reagent("frostoil", 3) + reagents.add_reagent("tomatojuice", 2) + if(3) + reagents.add_reagent("nutriment", 5) + reagents.add_reagent("water", 5) + reagents.add_reagent("tricordrazine", 5) + if(4) + reagents.add_reagent("nutriment", 5) + reagents.add_reagent("water", 10) + if(5) + reagents.add_reagent("nutriment", 2) + reagents.add_reagent("banana", 10) + if(6) + reagents.add_reagent("nutriment", 6) + reagents.add_reagent("blood", 10) + if(7) + reagents.add_reagent("slimejelly", 10) + reagents.add_reagent("water", 10) + if(8) + reagents.add_reagent("carbon", 10) + reagents.add_reagent("toxin", 10) + if(9) + reagents.add_reagent("nutriment", 5) + reagents.add_reagent("tomatojuice", 10) + if(10) + reagents.add_reagent("nutriment", 6) + reagents.add_reagent("tomatojuice", 5) + reagents.add_reagent("imidazoline", 5) + bitesize = 5 + +/obj/item/weapon/reagent_containers/food/snacks/wishsoup + name = "Wish Soup" + desc = "I wish this was soup." + icon_state = "wishsoup" + trash = /obj/item/trash/snack_bowl + filling_color = "#D1F4FF" + center_of_mass = list("x"=16, "y"=11) + +/obj/item/weapon/reagent_containers/food/snacks/wishsoup/Initialize() + . = ..() + reagents.add_reagent("water", 10) + bitesize = 5 + if(prob(25)) + src.desc = "A wish come true!" + reagents.add_reagent("nutriment", 8, list("something good" = 8)) + +/obj/item/weapon/reagent_containers/food/snacks/hotchili + name = "Hot Chili" + desc = "A five alarm Texan Chili!" + icon_state = "hotchili" + trash = /obj/item/trash/snack_bowl + filling_color = "#FF3C00" + center_of_mass = list("x"=15, "y"=9) + nutriment_amt = 3 + nutriment_desc = list("chilli peppers" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/hotchili/Initialize() + . = ..() + reagents.add_reagent("protein", 3) + reagents.add_reagent("capsaicin", 3) + reagents.add_reagent("tomatojuice", 2) + bitesize = 5 + +/obj/item/weapon/reagent_containers/food/snacks/coldchili + name = "Cold Chili" + desc = "This slush is barely a liquid!" + icon_state = "coldchili" + filling_color = "#2B00FF" + center_of_mass = list("x"=15, "y"=9) + trash = /obj/item/trash/snack_bowl + nutriment_amt = 3 + nutriment_desc = list("ice peppers" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/coldchili/Initialize() + . = ..() + reagents.add_reagent("protein", 3) + reagents.add_reagent("frostoil", 3) + reagents.add_reagent("tomatojuice", 2) + bitesize = 5 + +/obj/item/weapon/reagent_containers/food/snacks/monkeycube + name = "monkey cube" + desc = "Just add water!" + flags = OPENCONTAINER + icon_state = "monkeycube" + bitesize = 12 + filling_color = "#ADAC7F" + center_of_mass = list("x"=16, "y"=14) + + var/wrapped = 0 + var/monkey_type = "Monkey" + +/obj/item/weapon/reagent_containers/food/snacks/monkeycube/Initialize() + . = ..() + reagents.add_reagent("protein", 10) + +/obj/item/weapon/reagent_containers/food/snacks/monkeycube/attack_self(mob/user as mob) + if(wrapped) + Unwrap(user) + +/obj/item/weapon/reagent_containers/food/snacks/monkeycube/proc/Expand() + src.visible_message("\The [src] expands!") + var/mob/living/carbon/human/H = new(get_turf(src)) + H.set_species(monkey_type) + H.real_name = H.species.get_random_name() + H.name = H.real_name + if(ismob(loc)) + var/mob/M = loc + M.unEquip(src) + qdel(src) + return 1 + +/obj/item/weapon/reagent_containers/food/snacks/monkeycube/proc/Unwrap(mob/user as mob) + icon_state = "monkeycube" + desc = "Just add water!" + to_chat(user, "You unwrap the cube.") + wrapped = 0 + flags |= OPENCONTAINER + return + +/obj/item/weapon/reagent_containers/food/snacks/monkeycube/On_Consume(var/mob/M) + if(ishuman(M)) + var/mob/living/carbon/human/H = M + H.visible_message("A screeching creature bursts out of [M]'s chest!") + var/obj/item/organ/external/organ = H.get_organ(BP_TORSO) + organ.take_damage(50, 0, 0, "Animal escaping the ribcage") + Expand() + +/obj/item/weapon/reagent_containers/food/snacks/monkeycube/on_reagent_change() + if(reagents.has_reagent("water")) + Expand() + +/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped + desc = "Still wrapped in some paper." + icon_state = "monkeycubewrap" + flags = 0 + wrapped = 1 + +/obj/item/weapon/reagent_containers/food/snacks/monkeycube/farwacube + name = "farwa cube" + monkey_type = "Farwa" + +/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/farwacube + name = "farwa cube" + monkey_type = "Farwa" + +/obj/item/weapon/reagent_containers/food/snacks/monkeycube/stokcube + name = "stok cube" + monkey_type = "Stok" + +/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/stokcube + name = "stok cube" + monkey_type = "Stok" + +/obj/item/weapon/reagent_containers/food/snacks/monkeycube/neaeracube + name = "neaera cube" + monkey_type = "Neaera" + +/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/neaeracube + name = "neaera cube" + monkey_type = "Neaera" + +/obj/item/weapon/reagent_containers/food/snacks/spellburger + name = "Spell Burger" + desc = "This is absolutely Ei Nath." + icon_state = "spellburger" + filling_color = "#D505FF" + nutriment_amt = 6 + nutriment_desc = list("magic" = 3, "buns" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/spellburger/Initialize() + . = ..() + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/bigbiteburger + name = "Big Bite Burger" + desc = "Forget the Big Mac. THIS is the future!" + icon_state = "bigbiteburger" + filling_color = "#E3D681" + center_of_mass = list("x"=16, "y"=11) + nutriment_amt = 4 + nutriment_desc = list("buns" = 4) + +/obj/item/weapon/reagent_containers/food/snacks/bigbiteburger/Initialize() + . = ..() + reagents.add_reagent("protein", 10) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/enchiladas + name = "Enchiladas" + desc = "Viva La Mexico!" + icon_state = "enchiladas" + trash = /obj/item/trash/tray + filling_color = "#A36A1F" + center_of_mass = list("x"=16, "y"=13) + nutriment_amt = 2 + nutriment_desc = list("tortilla" = 3, "corn" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/enchiladas/Initialize() + . = ..() + reagents.add_reagent("protein", 6) + reagents.add_reagent("capsaicin", 6) + bitesize = 4 + +/obj/item/weapon/reagent_containers/food/snacks/monkeysdelight + name = "monkey's Delight" + desc = "Eeee Eee!" + icon_state = "monkeysdelight" + trash = /obj/item/trash/tray + filling_color = "#5C3C11" + center_of_mass = list("x"=16, "y"=13) + +/obj/item/weapon/reagent_containers/food/snacks/monkeysdelight/Initialize() + . = ..() + reagents.add_reagent("protein", 10) + reagents.add_reagent("banana", 5) + reagents.add_reagent("blackpepper", 1) + reagents.add_reagent("sodiumchloride", 1) + bitesize = 6 + +/obj/item/weapon/reagent_containers/food/snacks/baguette + name = "Baguette" + desc = "Bon appetit!" + icon_state = "baguette" + filling_color = "#E3D796" + center_of_mass = list("x"=18, "y"=12) + nutriment_amt = 6 + nutriment_desc = list("french bread" = 6) + +/obj/item/weapon/reagent_containers/food/snacks/baguette/Initialize() + . = ..() + reagents.add_reagent("blackpepper", 1) + reagents.add_reagent("sodiumchloride", 1) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/fishandchips + name = "Fish and Chips" + desc = "I do say so myself chap." + icon_state = "fishandchips" + filling_color = "#E3D796" + center_of_mass = list("x"=16, "y"=16) + nutriment_amt = 3 + nutriment_desc = list("salt" = 1, "chips" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/fishandchips/Initialize() + . = ..() + reagents.add_reagent("protein", 3) + reagents.add_reagent("carpotoxin", 3) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/sandwich + name = "Sandwich" + desc = "A grand creation of meat, cheese, bread, and several leaves of lettuce! Arthur Dent would be proud." + icon_state = "sandwich" + trash = /obj/item/trash/plate + filling_color = "#D9BE29" + center_of_mass = list("x"=16, "y"=4) + nutriment_amt = 3 + nutriment_desc = list("bread" = 3, "cheese" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/sandwich/Initialize() + . = ..() + reagents.add_reagent("protein", 3) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/toastedsandwich + name = "Toasted Sandwich" + desc = "Now if you only had a pepper bar." + icon_state = "toastedsandwich" + trash = /obj/item/trash/plate + filling_color = "#D9BE29" + center_of_mass = list("x"=16, "y"=4) + nutriment_amt = 3 + nutriment_desc = list("toasted bread" = 3, "cheese" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/toastedsandwich/Initialize() + . = ..() + reagents.add_reagent("protein", 3) + reagents.add_reagent("carbon", 2) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/grilledcheese + name = "Grilled Cheese Sandwich" + desc = "Goes great with Tomato soup!" + icon_state = "toastedsandwich" + trash = /obj/item/trash/plate + filling_color = "#D9BE29" + nutriment_amt = 3 + nutriment_desc = list("toasted bread" = 3, "cheese" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/grilledcheese/Initialize() + . = ..() + reagents.add_reagent("protein", 4) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/tomatosoup + name = "Tomato Soup" + desc = "Drinking this feels like being a vampire! A tomato vampire..." + icon_state = "tomatosoup" + trash = /obj/item/trash/snack_bowl + filling_color = "#D92929" + center_of_mass = list("x"=16, "y"=7) + nutriment_amt = 5 + nutriment_desc = list("soup" = 5) + +/obj/item/weapon/reagent_containers/food/snacks/tomatosoup/Initialize() + . = ..() + reagents.add_reagent("tomatojuice", 10) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/onionsoup + name = "Onion Soup" + desc = "A soup with layers." + icon_state = "onionsoup" + trash = /obj/item/trash/snack_bowl + filling_color = "#E0C367" + center_of_mass = list("x"=16, "y"=7) + nutriment_amt = 5 + nutriment_desc = list("onion" = 2, "soup" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/onionsoup/Initialize() + . = ..() + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/onionrings + name = "Onion Rings" + desc = "Crispy rings." + icon_state = "onionrings" + trash = /obj/item/trash/plate + filling_color = "#E0C367" + center_of_mass = list("x"=16, "y"=7) + nutriment_amt = 5 + nutriment_desc = list("onion" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/onionrings/Initialize() + . = ..() + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/rofflewaffles + name = "Roffle Waffles" + desc = "Waffles from Roffle. Co." + icon_state = "rofflewaffles" + trash = /obj/item/trash/waffles + filling_color = "#FF00F7" + center_of_mass = list("x"=15, "y"=11) + nutriment_amt = 8 + nutriment_desc = list("waffle" = 7, "sweetness" = 1) + +/obj/item/weapon/reagent_containers/food/snacks/rofflewaffles/Initialize() + . = ..() + reagents.add_reagent("psilocybin", 8) + bitesize = 4 + +/obj/item/weapon/reagent_containers/food/snacks/stew + name = "Stew" + desc = "A nice and warm stew. Healthy and strong." + icon_state = "stew" + filling_color = "#9E673A" + center_of_mass = list("x"=16, "y"=5) + nutriment_amt = 6 + nutriment_desc = list("tomato" = 2, "potato" = 2, "carrot" = 2, "eggplant" = 2, "mushroom" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/stew/Initialize() + . = ..() + reagents.add_reagent("protein", 4) + reagents.add_reagent("tomatojuice", 5) + reagents.add_reagent("imidazoline", 5) + reagents.add_reagent("water", 5) + bitesize = 10 + +/obj/item/weapon/reagent_containers/food/snacks/jelliedtoast + name = "Jellied Toast" + desc = "A slice of bread covered with delicious jam." + icon_state = "jellytoast" + trash = /obj/item/trash/plate + filling_color = "#B572AB" + center_of_mass = list("x"=16, "y"=8) + nutriment_amt = 1 + nutriment_desc = list("toasted bread" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/jelliedtoast/Initialize() + . = ..() + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/jelliedtoast/cherry/Initialize() + . = ..() + reagents.add_reagent("cherryjelly", 5) + +/obj/item/weapon/reagent_containers/food/snacks/jelliedtoast/slime/Initialize() + . = ..() + reagents.add_reagent("slimejelly", 5) + +/obj/item/weapon/reagent_containers/food/snacks/jellyburger + name = "Jelly Burger" + desc = "Culinary delight..?" + icon_state = "jellyburger" + filling_color = "#B572AB" + center_of_mass = list("x"=16, "y"=11) + nutriment_amt = 5 + nutriment_desc = list("buns" = 5) + +/obj/item/weapon/reagent_containers/food/snacks/jellyburger/Initialize() + . = ..() + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/jellyburger/slime/Initialize() + . = ..() + reagents.add_reagent("slimejelly", 5) + +/obj/item/weapon/reagent_containers/food/snacks/jellyburger/cherry/Initialize() + . = ..() + reagents.add_reagent("cherryjelly", 5) + +/obj/item/weapon/reagent_containers/food/snacks/milosoup + name = "Milosoup" + desc = "The universes best soup! Yum!!!" + icon_state = "milosoup" + trash = /obj/item/trash/snack_bowl + center_of_mass = list("x"=16, "y"=7) + nutriment_amt = 8 + nutriment_desc = list("soy" = 8) + +/obj/item/weapon/reagent_containers/food/snacks/milosoup/Initialize() + . = ..() + reagents.add_reagent("water", 5) + bitesize = 4 + +/obj/item/weapon/reagent_containers/food/snacks/stewedsoymeat + name = "Stewed Soy Meat" + desc = "Even non-vegetarians will LOVE this!" + icon_state = "stewedsoymeat" + trash = /obj/item/trash/plate + center_of_mass = list("x"=16, "y"=10) + nutriment_amt = 8 + nutriment_desc = list("soy" = 4, "tomato" = 4) + +/obj/item/weapon/reagent_containers/food/snacks/stewedsoymeat/Initialize() + . = ..() + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/boiledspagetti + name = "Boiled Spaghetti" + desc = "A plain dish of noodles, this sucks." + icon_state = "spagettiboiled" + trash = /obj/item/trash/plate + filling_color = "#FCEE81" + center_of_mass = list("x"=16, "y"=10) + nutriment_amt = 2 + nutriment_desc = list("noodles" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/boiledspagetti/Initialize() + . = ..() + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/boiledrice + name = "Boiled Rice" + desc = "A boring dish of boring rice." + icon_state = "boiledrice" + trash = /obj/item/trash/snack_bowl + filling_color = "#FFFBDB" + center_of_mass = list("x"=17, "y"=11) + nutriment_amt = 2 + nutriment_desc = list("rice" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/boiledrice/Initialize() + . = ..() + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/ricepudding + name = "Rice Pudding" + desc = "Where's the jam?" + icon_state = "rpudding" + trash = /obj/item/trash/snack_bowl + filling_color = "#FFFBDB" + center_of_mass = list("x"=17, "y"=11) + nutriment_amt = 4 + nutriment_desc = list("rice" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/ricepudding/Initialize() + . = ..() + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/pastatomato + name = "Spaghetti" + desc = "Spaghetti and crushed tomatoes. Just like your abusive father used to make!" + icon_state = "pastatomato" + trash = /obj/item/trash/plate + filling_color = "#DE4545" + center_of_mass = list("x"=16, "y"=10) + nutriment_amt = 6 + nutriment_desc = list("tomato" = 3, "noodles" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/pastatomato/Initialize() + . = ..() + reagents.add_reagent("tomatojuice", 10) + bitesize = 4 + +/obj/item/weapon/reagent_containers/food/snacks/meatballspagetti + name = "Spaghetti & Meatballs" + desc = "Now thats a nic'e meatball!" + icon_state = "meatballspagetti" + trash = /obj/item/trash/plate + filling_color = "#DE4545" + center_of_mass = list("x"=16, "y"=10) + nutriment_amt = 4 + nutriment_desc = list("noodles" = 4) + +/obj/item/weapon/reagent_containers/food/snacks/meatballspagetti/Initialize() + . = ..() + reagents.add_reagent("protein", 4) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/spesslaw + name = "Spesslaw" + desc = "A lawyers favourite" + icon_state = "spesslaw" + filling_color = "#DE4545" + center_of_mass = list("x"=16, "y"=10) + nutriment_amt = 4 + nutriment_desc = list("noodles" = 4) + +/obj/item/weapon/reagent_containers/food/snacks/spesslaw/Initialize() + . = ..() + reagents.add_reagent("protein", 4) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/carrotfries + name = "Carrot Fries" + desc = "Tasty fries from fresh Carrots." + icon_state = "carrotfries" + trash = /obj/item/trash/plate + filling_color = "#FAA005" + center_of_mass = list("x"=16, "y"=11) + nutriment_amt = 3 + nutriment_desc = list("carrot" = 3, "salt" = 1) + +/obj/item/weapon/reagent_containers/food/snacks/carrotfries/Initialize() + . = ..() + reagents.add_reagent("imidazoline", 3) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/superbiteburger + name = "Super Bite Burger" + desc = "This is a mountain of a burger. FOOD!" + icon_state = "superbiteburger" + filling_color = "#CCA26A" + center_of_mass = list("x"=16, "y"=3) + nutriment_amt = 25 + nutriment_desc = list("buns" = 25) + +/obj/item/weapon/reagent_containers/food/snacks/superbiteburger/Initialize() + . = ..() + reagents.add_reagent("protein", 25) + bitesize = 10 + +/obj/item/weapon/reagent_containers/food/snacks/candiedapple + name = "Candied Apple" + desc = "An apple coated in sugary sweetness." + icon_state = "candiedapple" + filling_color = "#F21873" + center_of_mass = list("x"=15, "y"=13) + nutriment_amt = 3 + nutriment_desc = list("apple" = 3, "caramel" = 3, "sweetness" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/candiedapple/Initialize() + . = ..() + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/applepie + name = "Apple Pie" + desc = "A pie containing sweet sweet love... or apple." + icon_state = "applepie" + filling_color = "#E0EDC5" + center_of_mass = list("x"=16, "y"=13) + nutriment_amt = 4 + nutriment_desc = list("sweetness" = 2, "apple" = 2, "pie" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/applepie/Initialize() + . = ..() + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/cherrypie + name = "Cherry Pie" + desc = "Taste so good, make a grown man cry." + icon_state = "cherrypie" + filling_color = "#FF525A" + center_of_mass = list("x"=16, "y"=11) + nutriment_amt = 4 + nutriment_desc = list("sweetness" = 2, "cherry" = 2, "pie" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/cherrypie/Initialize() + . = ..() + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/twobread + name = "Two Bread" + desc = "It is very bitter and winy." + icon_state = "twobread" + filling_color = "#DBCC9A" + center_of_mass = list("x"=15, "y"=12) + nutriment_amt = 2 + nutriment_desc = list("sourness" = 2, "bread" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/twobread/Initialize() + . = ..() + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/jellysandwich + name = "Jelly Sandwich" + desc = "You wish you had some peanut butter to go with this..." + icon_state = "jellysandwich" + trash = /obj/item/trash/plate + filling_color = "#9E3A78" + center_of_mass = list("x"=16, "y"=8) + nutriment_amt = 2 + nutriment_desc = list("bread" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/jellysandwich/Initialize() + . = ..() + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/jellysandwich/slime/Initialize() + . = ..() + reagents.add_reagent("slimejelly", 5) + +/obj/item/weapon/reagent_containers/food/snacks/jellysandwich/cherry/Initialize() + . = ..() + reagents.add_reagent("cherryjelly", 5) + +/obj/item/weapon/reagent_containers/food/snacks/boiledslimecore + name = "Boiled slime Core" + desc = "A boiled red thing." + icon_state = "boiledslimecore" //nonexistant? + +/obj/item/weapon/reagent_containers/food/snacks/boiledslimecore/Initialize() + . = ..() + reagents.add_reagent("slimejelly", 5) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/mint + name = "mint" + desc = "it is only wafer thin." + icon_state = "mint" + filling_color = "#F2F2F2" + center_of_mass = list("x"=16, "y"=14) + +/obj/item/weapon/reagent_containers/food/snacks/mint/Initialize() + . = ..() + reagents.add_reagent("mint", 1) + bitesize = 1 + +/obj/item/weapon/reagent_containers/food/snacks/mushroomsoup + name = "chantrelle soup" + desc = "A delicious and hearty mushroom soup." + icon_state = "mushroomsoup" + trash = /obj/item/trash/snack_bowl + filling_color = "#E386BF" + center_of_mass = list("x"=17, "y"=10) + nutriment_amt = 8 + nutriment_desc = list("mushroom" = 8, "milk" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/mushroomsoup/Initialize() + . = ..() + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/plumphelmetbiscuit + name = "plump helmet biscuit" + desc = "This is a finely-prepared plump helmet biscuit. The ingredients are exceptionally minced plump helmet, and well-minced dwarven wheat flour." + icon_state = "phelmbiscuit" + filling_color = "#CFB4C4" + center_of_mass = list("x"=16, "y"=13) + nutriment_amt = 5 + nutriment_desc = list("mushroom" = 4) + +/obj/item/weapon/reagent_containers/food/snacks/plumphelmetbiscuit/Initialize() + . = ..() + if(prob(10)) + name = "exceptional plump helmet biscuit" + desc = "Microwave is taken by a fey mood! It has cooked an exceptional plump helmet biscuit!" + reagents.add_reagent("nutriment", 8) + bitesize = 2 + else + reagents.add_reagent("nutriment", 5) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/chawanmushi + name = "chawanmushi" + desc = "A legendary egg custard that makes friends out of enemies. Probably too hot for a cat to eat." + icon_state = "chawanmushi" + trash = /obj/item/trash/snack_bowl + filling_color = "#F0F2E4" + center_of_mass = list("x"=17, "y"=10) + +/obj/item/weapon/reagent_containers/food/snacks/chawanmushi/Initialize() + . = ..() + reagents.add_reagent("protein", 5) + bitesize = 1 + +/obj/item/weapon/reagent_containers/food/snacks/beetsoup + name = "beet soup" + desc = "Wait, how do you spell it again..?" + icon_state = "beetsoup" + trash = /obj/item/trash/snack_bowl + filling_color = "#FAC9FF" + center_of_mass = list("x"=15, "y"=8) + nutriment_amt = 8 + nutriment_desc = list("tomato" = 4, "beet" = 4) + +/obj/item/weapon/reagent_containers/food/snacks/beetsoup/Initialize() + . = ..() + name = pick(list("borsch","bortsch","borstch","borsh","borshch","borscht")) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/tossedsalad + name = "tossed salad" + desc = "A proper salad, basic and simple, with little bits of carrot, tomato and apple intermingled. Vegan!" + icon_state = "herbsalad" + trash = /obj/item/trash/snack_bowl + filling_color = "#76B87F" + center_of_mass = list("x"=17, "y"=11) + nutriment_amt = 8 + nutriment_desc = list("salad" = 2, "tomato" = 2, "carrot" = 2, "apple" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/tossedsalad/Initialize() + . = ..() + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/validsalad + name = "valid salad" + desc = "It's just a salad of questionable 'herbs' with meatballs and fried potato slices. Nothing suspicious about it." + icon_state = "validsalad" + trash = /obj/item/trash/snack_bowl + filling_color = "#76B87F" + center_of_mass = list("x"=17, "y"=11) + nutriment_amt = 6 + nutriment_desc = list("100% real salad") + +/obj/item/weapon/reagent_containers/food/snacks/validsalad/Initialize() + . = ..() + reagents.add_reagent("protein", 2) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/appletart + name = "golden apple streusel tart" + desc = "A tasty dessert that won't make it through a metal detector." + icon_state = "gappletart" + trash = /obj/item/trash/plate + filling_color = "#FFFF00" + center_of_mass = list("x"=16, "y"=18) + nutriment_amt = 8 + nutriment_desc = list("apple" = 8) + +/obj/item/weapon/reagent_containers/food/snacks/appletart/Initialize() + . = ..() + reagents.add_reagent("gold", 5) + bitesize = 3 + +/////////////////////////////////////////////////Sliceable//////////////////////////////////////// +// All the food items that can be sliced into smaller bits like Meatbread and Cheesewheels + +// sliceable is just an organization type path, it doesn't have any additional code or variables tied to it. + +/obj/item/weapon/reagent_containers/food/snacks/sliceable + w_class = ITEMSIZE_NORMAL //Whole pizzas and cakes shouldn't fit in a pocket, you can slice them if you want to do that. + +/** + * A food item slice + * + * This path contains some extra code for spawning slices pre-filled with + * reagents. + */ +/obj/item/weapon/reagent_containers/food/snacks/slice + name = "slice of... something" + var/whole_path // path for the item from which this slice comes + var/filled = FALSE // should the slice spawn with any reagents + +/** + * Spawn a new slice of food + * + * If the slice's filled is TRUE, this will also fill the slice with the + * appropriate amount of reagents. Note that this is done by spawning a new + * whole item, transferring the reagents and deleting the whole item, which may + * have performance implications. + */ +/obj/item/weapon/reagent_containers/food/snacks/slice/Initialize() + . = ..() + if(filled) + var/obj/item/weapon/reagent_containers/food/snacks/whole = new whole_path() + if(whole && whole.slices_num) + var/reagent_amount = whole.reagents.total_volume/whole.slices_num + whole.reagents.trans_to_obj(src, reagent_amount) + + qdel(whole) + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/meatbread + name = "meatbread loaf" + desc = "The culinary base of every self-respecting eloquent gentleman." + icon_state = "meatbread" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/meatbread + slices_num = 5 + filling_color = "#FF7575" + center_of_mass = list("x"=19, "y"=9) + nutriment_desc = list("bread" = 10) + nutriment_amt = 10 + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/meatbread/Initialize() + . = ..() + reagents.add_reagent("protein", 20) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/slice/meatbread + name = "meatbread slice" + desc = "A slice of delicious meatbread." + icon_state = "meatbreadslice" + trash = /obj/item/trash/plate + filling_color = "#FF7575" + bitesize = 2 + center_of_mass = list("x"=16, "y"=16) + whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/meatbread + +/obj/item/weapon/reagent_containers/food/snacks/slice/meatbread/filled + filled = TRUE + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/xenomeatbread + name = "xenomeatbread loaf" + desc = "The culinary base of every self-respecting eloquent gentleman. Extra Heretical." + icon_state = "xenomeatbread" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/xenomeatbread + slices_num = 5 + filling_color = "#8AFF75" + center_of_mass = list("x"=16, "y"=9) + nutriment_desc = list("bread" = 10) + nutriment_amt = 10 + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/xenomeatbread/Initialize() + . = ..() + reagents.add_reagent("protein", 20) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/slice/xenomeatbread + name = "xenomeatbread slice" + desc = "A slice of delicious meatbread. Extra Heretical." + icon_state = "xenobreadslice" + trash = /obj/item/trash/plate + filling_color = "#8AFF75" + bitesize = 2 + center_of_mass = list("x"=16, "y"=13) + whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/xenomeatbread + + +/obj/item/weapon/reagent_containers/food/snacks/slice/xenomeatbread/filled + filled = TRUE + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/bananabread + name = "Banana-nut bread" + desc = "A heavenly and filling treat." + icon_state = "bananabread" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/bananabread + slices_num = 5 + filling_color = "#EDE5AD" + center_of_mass = list("x"=16, "y"=9) + nutriment_desc = list("bread" = 10) + nutriment_amt = 10 + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/bananabread/Initialize() + . = ..() + reagents.add_reagent("banana", 20) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/slice/bananabread + name = "Banana-nut bread slice" + desc = "A slice of delicious banana bread." + icon_state = "bananabreadslice" + trash = /obj/item/trash/plate + filling_color = "#EDE5AD" + bitesize = 2 + center_of_mass = list("x"=16, "y"=8) + whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/bananabread + +/obj/item/weapon/reagent_containers/food/snacks/slice/bananabread/filled + filled = TRUE + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/tofubread + name = "Tofubread" + icon_state = "Like meatbread but for vegetarians. Not guaranteed to give superpowers." + icon_state = "tofubread" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/tofubread + slices_num = 5 + filling_color = "#F7FFE0" + center_of_mass = list("x"=16, "y"=9) + nutriment_desc = list("tofu" = 10) + nutriment_amt = 10 + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/tofubread/Initialize() + . = ..() + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/slice/tofubread + name = "Tofubread slice" + desc = "A slice of delicious tofubread." + icon_state = "tofubreadslice" + trash = /obj/item/trash/plate + filling_color = "#F7FFE0" + bitesize = 2 + center_of_mass = list("x"=16, "y"=13) + whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/tofubread + +/obj/item/weapon/reagent_containers/food/snacks/slice/tofubread/filled + filled = TRUE + + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/carrotcake + name = "Carrot Cake" + desc = "A favorite desert of a certain wascally wabbit. Not a lie." + icon_state = "carrotcake" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/carrotcake + slices_num = 5 + filling_color = "#FFD675" + center_of_mass = list("x"=16, "y"=10) + nutriment_desc = list("cake" = 10, "sweetness" = 10, "carrot" = 15) + nutriment_amt = 25 + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/carrotcake/Initialize() + . = ..() + reagents.add_reagent("imidazoline", 10) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/slice/carrotcake + name = "Carrot Cake slice" + desc = "Carrotty slice of Carrot Cake, carrots are good for your eyes! Also not a lie." + icon_state = "carrotcake_slice" + trash = /obj/item/trash/plate + filling_color = "#FFD675" + bitesize = 2 + center_of_mass = list("x"=16, "y"=14) + whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/carrotcake + +/obj/item/weapon/reagent_containers/food/snacks/slice/carrotcake/filled + filled = TRUE + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/braincake + name = "Brain Cake" + desc = "A squishy cake-thing." + icon_state = "braincake" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/braincake + slices_num = 5 + filling_color = "#E6AEDB" + center_of_mass = list("x"=16, "y"=10) + nutriment_desc = list("cake" = 10, "sweetness" = 10, "slime" = 15) + nutriment_amt = 5 + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/braincake/Initialize() + . = ..() + reagents.add_reagent("protein", 25) + reagents.add_reagent("alkysine", 10) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/slice/braincake + name = "Brain Cake slice" + desc = "Lemme tell you something about prions. THEY'RE DELICIOUS." + icon_state = "braincakeslice" + trash = /obj/item/trash/plate + filling_color = "#E6AEDB" + bitesize = 2 + center_of_mass = list("x"=16, "y"=12) + whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/braincake + +/obj/item/weapon/reagent_containers/food/snacks/slice/braincake/filled + filled = TRUE + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/cheesecake + name = "Cheese Cake" + desc = "DANGEROUSLY cheesy." + icon_state = "cheesecake" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/cheesecake + slices_num = 5 + filling_color = "#FAF7AF" + center_of_mass = list("x"=16, "y"=10) + nutriment_desc = list("cake" = 10, "cream" = 10, "cheese" = 15) + nutriment_amt = 10 + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/cheesecake/Initialize() + . = ..() + reagents.add_reagent("protein", 15) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/slice/cheesecake + name = "Cheese Cake slice" + desc = "Slice of pure cheestisfaction." + icon_state = "cheesecake_slice" + trash = /obj/item/trash/plate + filling_color = "#FAF7AF" + bitesize = 2 + center_of_mass = list("x"=16, "y"=14) + whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/cheesecake + +/obj/item/weapon/reagent_containers/food/snacks/slice/cheesecake/filled + filled = TRUE + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/plaincake + name = "Vanilla Cake" + desc = "A plain cake, not a lie." + icon_state = "plaincake" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/plaincake + slices_num = 5 + filling_color = "#F7EDD5" + center_of_mass = list("x"=16, "y"=10) + nutriment_desc = list("cake" = 10, "sweetness" = 10, "vanilla" = 15) + nutriment_amt = 20 + +/obj/item/weapon/reagent_containers/food/snacks/slice/plaincake + name = "Vanilla Cake slice" + desc = "Just a slice of cake, it is enough for everyone." + icon_state = "plaincake_slice" + trash = /obj/item/trash/plate + filling_color = "#F7EDD5" + bitesize = 2 + center_of_mass = list("x"=16, "y"=14) + whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/plaincake + +/obj/item/weapon/reagent_containers/food/snacks/slice/plaincake/filled + filled = TRUE + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/orangecake + name = "Orange Cake" + desc = "A cake with added orange." + icon_state = "orangecake" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/orangecake + slices_num = 5 + filling_color = "#FADA8E" + center_of_mass = list("x"=16, "y"=10) + nutriment_desc = list("cake" = 10, "sweetness" = 10, "orange" = 15) + nutriment_amt = 20 + +/obj/item/weapon/reagent_containers/food/snacks/slice/orangecake + name = "Orange Cake slice" + desc = "Just a slice of cake, it is enough for everyone." + icon_state = "orangecake_slice" + trash = /obj/item/trash/plate + filling_color = "#FADA8E" + bitesize = 2 + center_of_mass = list("x"=16, "y"=14) + whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/orangecake + +/obj/item/weapon/reagent_containers/food/snacks/slice/orangecake/filled + filled = TRUE + + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/limecake + name = "Lime Cake" + desc = "A cake with added lime." + icon_state = "limecake" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/limecake + slices_num = 5 + filling_color = "#CBFA8E" + center_of_mass = list("x"=16, "y"=10) + nutriment_desc = list("cake" = 10, "sweetness" = 10, "lime" = 15) + nutriment_amt = 20 + + +/obj/item/weapon/reagent_containers/food/snacks/slice/limecake + name = "Lime Cake slice" + desc = "Just a slice of cake, it is enough for everyone." + icon_state = "limecake_slice" + trash = /obj/item/trash/plate + filling_color = "#CBFA8E" + bitesize = 2 + center_of_mass = list("x"=16, "y"=14) + whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/limecake + +/obj/item/weapon/reagent_containers/food/snacks/slice/limecake/filled + filled = TRUE + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/lemoncake + name = "Lemon Cake" + desc = "A cake with added lemon." + icon_state = "lemoncake" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/lemoncake + slices_num = 5 + filling_color = "#FAFA8E" + center_of_mass = list("x"=16, "y"=10) + nutriment_desc = list("cake" = 10, "sweetness" = 10, "lemon" = 15) + nutriment_amt = 20 + + +/obj/item/weapon/reagent_containers/food/snacks/slice/lemoncake + name = "Lemon Cake slice" + desc = "Just a slice of cake, it is enough for everyone." + icon_state = "lemoncake_slice" + trash = /obj/item/trash/plate + filling_color = "#FAFA8E" + bitesize = 2 + center_of_mass = list("x"=16, "y"=14) + whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/lemoncake + +/obj/item/weapon/reagent_containers/food/snacks/slice/lemoncake/filled + filled = TRUE + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/chocolatecake + name = "Chocolate Cake" + desc = "A cake with added chocolate." + icon_state = "chocolatecake" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/chocolatecake + slices_num = 5 + filling_color = "#805930" + center_of_mass = list("x"=16, "y"=10) + nutriment_desc = list("cake" = 10, "sweetness" = 10, "chocolate" = 15) + nutriment_amt = 20 + +/obj/item/weapon/reagent_containers/food/snacks/slice/chocolatecake + name = "Chocolate Cake slice" + desc = "Just a slice of cake, it is enough for everyone." + icon_state = "chocolatecake_slice" + trash = /obj/item/trash/plate + filling_color = "#805930" + bitesize = 2 + center_of_mass = list("x"=16, "y"=14) + whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/chocolatecake + +/obj/item/weapon/reagent_containers/food/snacks/slice/chocolatecake/filled + filled = TRUE + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/cheesewheel + name = "Cheese wheel" + desc = "A big wheel of delcious Cheddar." + icon_state = "cheesewheel" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/cheesewedge + slices_num = 5 + filling_color = "#FFF700" + center_of_mass = list("x"=16, "y"=10) + nutriment_desc = list("cheese" = 10) + nutriment_amt = 10 + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/cheesewheel/Initialize() + . = ..() + reagents.add_reagent("protein", 10) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/cheesewedge + name = "Cheese wedge" + desc = "A wedge of delicious Cheddar. The cheese wheel it was cut from can't have gone far." + icon_state = "cheesewedge" + filling_color = "#FFF700" + bitesize = 2 + center_of_mass = list("x"=16, "y"=10) + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/birthdaycake + name = "Birthday Cake" + desc = "Happy Birthday..." + icon_state = "birthdaycake" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/birthdaycake + slices_num = 5 + filling_color = "#FFD6D6" + center_of_mass = list("x"=16, "y"=10) + nutriment_desc = list("cake" = 10, "sweetness" = 10) + nutriment_amt = 20 + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/birthdaycake/Initialize() + . = ..() + reagents.add_reagent("sprinkles", 10) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/slice/birthdaycake + name = "Birthday Cake slice" + desc = "A slice of your birthday." + icon_state = "birthdaycakeslice" + trash = /obj/item/trash/plate + filling_color = "#FFD6D6" + bitesize = 2 + center_of_mass = list("x"=16, "y"=14) + whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/birthdaycake + +/obj/item/weapon/reagent_containers/food/snacks/slice/birthdaycake/filled + filled = TRUE + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/bread + name = "Bread" + icon_state = "Some plain old Earthen bread." + icon_state = "bread" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/bread + slices_num = 5 + filling_color = "#FFE396" + center_of_mass = list("x"=16, "y"=9) + nutriment_desc = list("bread" = 6) + nutriment_amt = 6 + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/bread/Initialize() + . = ..() + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/slice/bread + name = "Bread slice" + desc = "A slice of home." + icon_state = "breadslice" + trash = /obj/item/trash/plate + filling_color = "#D27332" + bitesize = 2 + center_of_mass = list("x"=16, "y"=4) + whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/bread + +/obj/item/weapon/reagent_containers/food/snacks/slice/bread/filled + filled = TRUE + + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/creamcheesebread + name = "Cream Cheese Bread" + desc = "Yum yum yum!" + icon_state = "creamcheesebread" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/creamcheesebread + slices_num = 5 + filling_color = "#FFF896" + center_of_mass = list("x"=16, "y"=9) + nutriment_desc = list("bread" = 6, "cream" = 3, "cheese" = 3) + nutriment_amt = 5 + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/creamcheesebread/Initialize() + . = ..() + reagents.add_reagent("protein", 15) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/slice/creamcheesebread + name = "Cream Cheese Bread slice" + desc = "A slice of yum!" + icon_state = "creamcheesebreadslice" + trash = /obj/item/trash/plate + filling_color = "#FFF896" + bitesize = 2 + center_of_mass = list("x"=16, "y"=14) + whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/creamcheesebread + + +/obj/item/weapon/reagent_containers/food/snacks/slice/creamcheesebread/filled + filled = TRUE + + +/obj/item/weapon/reagent_containers/food/snacks/watermelonslice + name = "Watermelon Slice" + desc = "A slice of watery goodness." + icon_state = "watermelonslice" + filling_color = "#FF3867" + bitesize = 2 + center_of_mass = list("x"=16, "y"=10) + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/applecake + name = "Apple Cake" + desc = "A cake centred with apples." + icon_state = "applecake" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/applecake + slices_num = 5 + filling_color = "#EBF5B8" + center_of_mass = list("x"=16, "y"=10) + nutriment_desc = list("cake" = 10, "sweetness" = 10, "apple" = 15) + nutriment_amt = 15 + +/obj/item/weapon/reagent_containers/food/snacks/slice/applecake + name = "Apple Cake slice" + desc = "A slice of heavenly cake." + icon_state = "applecakeslice" + trash = /obj/item/trash/plate + filling_color = "#EBF5B8" + bitesize = 2 + center_of_mass = list("x"=16, "y"=14) + whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/applecake + +/obj/item/weapon/reagent_containers/food/snacks/slice/applecake/filled + filled = TRUE + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/pumpkinpie + name = "Pumpkin Pie" + desc = "A delicious treat for the autumn months." + icon_state = "pumpkinpie" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/pumpkinpie + slices_num = 5 + filling_color = "#F5B951" + center_of_mass = list("x"=16, "y"=10) + nutriment_desc = list("pie" = 5, "cream" = 5, "pumpkin" = 5) + nutriment_amt = 15 + +/obj/item/weapon/reagent_containers/food/snacks/slice/pumpkinpie + name = "Pumpkin Pie slice" + desc = "A slice of pumpkin pie, with whipped cream on top. Perfection." + icon_state = "pumpkinpieslice" + trash = /obj/item/trash/plate + filling_color = "#F5B951" + bitesize = 2 + center_of_mass = list("x"=16, "y"=12) + whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pumpkinpie + +/obj/item/weapon/reagent_containers/food/snacks/slice/pumpkinpie/filled + filled = TRUE + +/obj/item/weapon/reagent_containers/food/snacks/cracker + name = "Cracker" + desc = "It's a salted cracker." + icon_state = "cracker" + filling_color = "#F5DEB8" + center_of_mass = list("x"=16, "y"=6) + nutriment_desc = list("salt" = 1, "cracker" = 2) + nutriment_amt = 1 + + + +/////////////////////////////////////////////////PIZZA//////////////////////////////////////// + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza + slices_num = 6 + filling_color = "#BAA14C" + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/margherita + name = "Margherita" + desc = "The golden standard of pizzas." + icon_state = "pizzamargherita" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/margherita + slices_num = 6 + center_of_mass = list("x"=16, "y"=11) + nutriment_desc = list("pizza crust" = 10, "tomato" = 10, "cheese" = 15) + nutriment_amt = 35 + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/margherita/Initialize() + . = ..() + reagents.add_reagent("protein", 5) + reagents.add_reagent("tomatojuice", 6) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/slice/margherita + name = "Margherita slice" + desc = "A slice of the classic pizza." + icon_state = "pizzamargheritaslice" + filling_color = "#BAA14C" + bitesize = 2 + center_of_mass = list("x"=16, "y"=13) + whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/margherita + +/obj/item/weapon/reagent_containers/food/snacks/slice/margherita/filled + filled = TRUE + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/meatpizza + name = "Meatpizza" + desc = "A pizza with meat topping." + icon_state = "meatpizza" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/meatpizza + slices_num = 6 + center_of_mass = list("x"=16, "y"=11) + nutriment_desc = list("pizza crust" = 10, "tomato" = 10, "cheese" = 15) + nutriment_amt = 10 + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/meatpizza/Initialize() + . = ..() + reagents.add_reagent("protein", 34) + reagents.add_reagent("tomatojuice", 6) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/slice/meatpizza + name = "Meatpizza slice" + desc = "A slice of a meaty pizza." + icon_state = "meatpizzaslice" + filling_color = "#BAA14C" + bitesize = 2 + center_of_mass = list("x"=16, "y"=13) + whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/meatpizza + +/obj/item/weapon/reagent_containers/food/snacks/slice/meatpizza/filled + filled = TRUE + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/mushroompizza + name = "Mushroompizza" + desc = "Very special pizza." + icon_state = "mushroompizza" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/mushroompizza + slices_num = 6 + center_of_mass = list("x"=16, "y"=11) + nutriment_desc = list("pizza crust" = 10, "tomato" = 10, "cheese" = 5, "mushroom" = 10) + nutriment_amt = 35 + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/mushroompizza/Initialize() + . = ..() + reagents.add_reagent("protein", 5) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/slice/mushroompizza + name = "Mushroompizza slice" + desc = "Maybe it is the last slice of pizza in your life." + icon_state = "mushroompizzaslice" + filling_color = "#BAA14C" + bitesize = 2 + center_of_mass = list("x"=16, "y"=13) + whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/mushroompizza + +/obj/item/weapon/reagent_containers/food/snacks/slice/mushroompizza/filled + filled = TRUE + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/vegetablepizza + name = "Vegetable pizza" + desc = "No one of Tomato Sapiens were harmed during making this pizza." + icon_state = "vegetablepizza" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/vegetablepizza + slices_num = 6 + center_of_mass = list("x"=16, "y"=11) + nutriment_desc = list("pizza crust" = 10, "tomato" = 10, "cheese" = 5, "eggplant" = 5, "carrot" = 5, "corn" = 5) + nutriment_amt = 25 + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/vegetablepizza/Initialize() + . = ..() + reagents.add_reagent("protein", 5) + reagents.add_reagent("tomatojuice", 6) + reagents.add_reagent("imidazoline", 12) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/slice/vegetablepizza + name = "Vegetable pizza slice" + desc = "A slice of the most green pizza of all pizzas not containing green ingredients." + icon_state = "vegetablepizzaslice" + filling_color = "#BAA14C" + bitesize = 2 + center_of_mass = list("x"=16, "y"=13) + whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/vegetablepizza + +/obj/item/weapon/reagent_containers/food/snacks/slice/vegetablepizza/filled + filled = TRUE + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/oldpizza + name = "moldy pizza" + desc = "This pizza might actually be alive. There's mold all over." + icon_state = "oldpizza" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/slice/oldpizza + slices_num = 6 + center_of_mass = list("x"=16, "y"=11) + nutriment_desc = list("stale pizza crust" = 10, "moldy tomato" = 10, "moldy cheese" = 5) + nutriment_amt = 10 + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/oldpizza/Initialize() + . = ..() + reagents.add_reagent("protein", 5) + reagents.add_reagent("tomatojuice", 6) + reagents.add_reagent("mold", 8) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/slice/oldpizza + name = "moldy pizza slice" + desc = "This used to be pizza..." + icon_state = "old_pizza" + filling_color = "#BAA14C" + bitesize = 2 + center_of_mass = list("x"=16, "y"=13) + whole_path = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/oldpizza + +/obj/item/pizzabox + name = "pizza box" + desc = "A box suited for pizzas." + icon = 'icons/obj/food.dmi' + icon_state = "pizzabox1" + + var/open = 0 // Is the box open? + var/ismessy = 0 // Fancy mess on the lid + var/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/pizza // Content pizza + var/list/boxes = list() // If the boxes are stacked, they come here + var/boxtag = "" + +/obj/item/pizzabox/update_icon() + + overlays = list() + + // Set appropriate description + if( open && pizza ) + desc = "A box suited for pizzas. It appears to have a [pizza.name] inside." + else if( boxes.len > 0 ) + desc = "A pile of boxes suited for pizzas. There appears to be [boxes.len + 1] boxes in the pile." + + var/obj/item/pizzabox/topbox = boxes[boxes.len] + var/toptag = topbox.boxtag + if( toptag != "" ) + desc = "[desc] The box on top has a tag, it reads: '[toptag]'." + else + desc = "A box suited for pizzas." + + if( boxtag != "" ) + desc = "[desc] The box has a tag, it reads: '[boxtag]'." + + // Icon states and overlays + if( open ) + if( ismessy ) + icon_state = "pizzabox_messy" + else + icon_state = "pizzabox_open" + + if( pizza ) + var/image/pizzaimg = image("food.dmi", icon_state = pizza.icon_state) + pizzaimg.pixel_y = -3 + overlays += pizzaimg + + return + else + // Stupid code because byondcode sucks + var/doimgtag = 0 + if( boxes.len > 0 ) + var/obj/item/pizzabox/topbox = boxes[boxes.len] + if( topbox.boxtag != "" ) + doimgtag = 1 + else + if( boxtag != "" ) + doimgtag = 1 + + if( doimgtag ) + var/image/tagimg = image("food.dmi", icon_state = "pizzabox_tag") + tagimg.pixel_y = boxes.len * 3 + overlays += tagimg + + icon_state = "pizzabox[boxes.len+1]" + +/obj/item/pizzabox/attack_hand( mob/user as mob ) + + if( open && pizza ) + user.put_in_hands( pizza ) + + to_chat(user, "You take \the [src.pizza] out of \the [src].") + src.pizza = null + update_icon() + return + + if( boxes.len > 0 ) + if( user.get_inactive_hand() != src ) + ..() + return + + var/obj/item/pizzabox/box = boxes[boxes.len] + boxes -= box + + user.put_in_hands( box ) + to_chat(user, "You remove the topmost [src] from your hand.") + box.update_icon() + update_icon() + return + ..() + +/obj/item/pizzabox/attack_self( mob/user as mob ) + + if( boxes.len > 0 ) + return + + open = !open + + if( open && pizza ) + ismessy = 1 + + update_icon() + +/obj/item/pizzabox/attackby( obj/item/I as obj, mob/user as mob ) + if( istype(I, /obj/item/pizzabox/) ) + var/obj/item/pizzabox/box = I + + if( !box.open && !src.open ) + // Make a list of all boxes to be added + var/list/boxestoadd = list() + boxestoadd += box + for(var/obj/item/pizzabox/i in box.boxes) + boxestoadd += i + + if( (boxes.len+1) + boxestoadd.len <= 5 ) + user.drop_item() + + box.loc = src + box.boxes = list() // Clear the box boxes so we don't have boxes inside boxes. - Xzibit + src.boxes.Add( boxestoadd ) + + box.update_icon() + update_icon() + + to_chat(user, "You put \the [box] ontop of \the [src]!") + else + to_chat(user, "The stack is too high!") + else + to_chat(user, "Close \the [box] first!") + + return + + if( istype(I, /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/) ) // Long ass fucking object name + + if( src.open ) + user.drop_item() + I.loc = src + src.pizza = I + + update_icon() + + to_chat(user, "You put \the [I] in \the [src]!") + else + to_chat(user, "You try to push \the [I] through the lid but it doesn't work!") + return + + if( istype(I, /obj/item/weapon/pen/) ) + + if( src.open ) + return + + var/t = sanitize(input("Enter what you want to add to the tag:", "Write", null, null) as text, 30) + + var/obj/item/pizzabox/boxtotagto = src + if( boxes.len > 0 ) + boxtotagto = boxes[boxes.len] + + boxtotagto.boxtag = copytext("[boxtotagto.boxtag][t]", 1, 30) + + update_icon() + return + ..() + +/obj/item/pizzabox/margherita/New() + pizza = new /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/margherita(src) + boxtag = "Margherita Deluxe" + +/obj/item/pizzabox/vegetable/New() + pizza = new /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/vegetablepizza(src) + boxtag = "Gourmet Vegatable" + +/obj/item/pizzabox/mushroom/New() + pizza = new /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/mushroompizza(src) + boxtag = "Mushroom Special" + +/obj/item/pizzabox/meat/New() + pizza = new /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/meatpizza(src) + boxtag = "Meatlover's Supreme" + +/obj/item/pizzabox/old/New() + pizza = new /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/oldpizza(src) + boxtag = "Deluxe Gourmet" + +/obj/item/weapon/reagent_containers/food/snacks/dionaroast + name = "roast diona" + desc = "It's like an enormous, leathery carrot. With an eye." + icon_state = "dionaroast" + trash = /obj/item/trash/plate + filling_color = "#75754B" + center_of_mass = list("x"=16, "y"=7) + nutriment_amt = 6 + nutriment_desc = list("a chorus of flavor" = 6) + +/obj/item/weapon/reagent_containers/food/snacks/dionaroast/Initialize() + . = ..() + reagents.add_reagent("radium", 2) + bitesize = 2 + +/////////////////////////////////////////// +// new old food stuff from bs12 +/////////////////////////////////////////// +/obj/item/weapon/reagent_containers/food/snacks/dough + name = "dough" + desc = "A piece of dough." + icon = 'icons/obj/food_ingredients.dmi' + icon_state = "dough" + bitesize = 2 + center_of_mass = list("x"=16, "y"=13) + nutriment_amt = 3 + nutriment_desc = list("uncooked dough" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/dough/Initialize() + . = ..() + reagents.add_reagent("protein", 1) + +// Dough + rolling pin = flat dough +/obj/item/weapon/reagent_containers/food/snacks/dough/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W,/obj/item/weapon/material/kitchen/rollingpin)) + new /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough(src) + user << "You flatten the dough." + qdel(src) + +// slicable into 3xdoughslices +/obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough + name = "flat dough" + desc = "A flattened dough." + icon = 'icons/obj/food_ingredients.dmi' + icon_state = "flat dough" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/doughslice + slices_num = 3 + center_of_mass = list("x"=16, "y"=16) + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough/Initialize() + . = ..() + reagents.add_reagent("protein", 1) + reagents.add_reagent("nutriment", 3) + +/obj/item/weapon/reagent_containers/food/snacks/doughslice + name = "dough slice" + desc = "A building block of an impressive dish." + icon = 'icons/obj/food_ingredients.dmi' + icon_state = "doughslice" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/spagetti + slices_num = 1 + bitesize = 2 + center_of_mass = list("x"=17, "y"=19) + nutriment_amt = 1 + nutriment_desc = list("uncooked dough" = 1) + +/obj/item/weapon/reagent_containers/food/snacks/doughslice/Initialize() + . = ..() + +/obj/item/weapon/reagent_containers/food/snacks/bun + name = "bun" + desc = "A base for any self-respecting burger." + icon = 'icons/obj/food_ingredients.dmi' + icon_state = "bun" + bitesize = 2 + center_of_mass = list("x"=16, "y"=12) + nutriment_amt = 4 + nutriment_desc = "bun" + +/obj/item/weapon/reagent_containers/food/snacks/bun/Initialize() + . = ..() + +/obj/item/weapon/reagent_containers/food/snacks/bun/attackby(obj/item/weapon/W as obj, mob/user as mob) + // Bun + meatball = burger + if(istype(W,/obj/item/weapon/reagent_containers/food/snacks/meatball)) + new /obj/item/weapon/reagent_containers/food/snacks/monkeyburger(src) + user << "You make a burger." + qdel(W) + qdel(src) + + // Bun + cutlet = hamburger + else if(istype(W,/obj/item/weapon/reagent_containers/food/snacks/cutlet)) + new /obj/item/weapon/reagent_containers/food/snacks/monkeyburger(src) + user << "You make a burger." + qdel(W) + qdel(src) + + // Bun + sausage = hotdog + else if(istype(W,/obj/item/weapon/reagent_containers/food/snacks/sausage)) + new /obj/item/weapon/reagent_containers/food/snacks/hotdog(src) + user << "You make a hotdog." + qdel(W) + qdel(src) + +// Burger + cheese wedge = cheeseburger +/obj/item/weapon/reagent_containers/food/snacks/monkeyburger/attackby(obj/item/weapon/reagent_containers/food/snacks/cheesewedge/W as obj, mob/user as mob) + if(istype(W))// && !istype(src,/obj/item/weapon/reagent_containers/food/snacks/cheesewedge)) + new /obj/item/weapon/reagent_containers/food/snacks/cheeseburger(src) + user << "You make a cheeseburger." + qdel(W) + qdel(src) + return + else + ..() + +// Human Burger + cheese wedge = cheeseburger +/obj/item/weapon/reagent_containers/food/snacks/human/burger/attackby(obj/item/weapon/reagent_containers/food/snacks/cheesewedge/W as obj, mob/user as mob) + if(istype(W)) + new /obj/item/weapon/reagent_containers/food/snacks/cheeseburger(src) + user << "You make a cheeseburger." + qdel(W) + qdel(src) + return + else + ..() + +/obj/item/weapon/reagent_containers/food/snacks/bunbun + name = "\improper Bun Bun" + desc = "A small bread monkey fashioned from two burger buns." + icon_state = "bunbun" + bitesize = 2 + center_of_mass = list("x"=16, "y"=8) + nutriment_amt = 8 + nutriment_desc = list("bun" = 8) + +/obj/item/weapon/reagent_containers/food/snacks/bunbun/Initialize() + . = ..() + +/obj/item/weapon/reagent_containers/food/snacks/taco + name = "taco" + desc = "Take a bite!" + icon_state = "taco" + bitesize = 3 + center_of_mass = list("x"=21, "y"=12) + nutriment_amt = 4 + nutriment_desc = list("cheese" = 2,"taco shell" = 2) +/obj/item/weapon/reagent_containers/food/snacks/taco/Initialize() + . = ..() + reagents.add_reagent("protein", 3) + +/obj/item/weapon/reagent_containers/food/snacks/rawcutlet + name = "raw cutlet" + desc = "A thin piece of raw meat." + icon = 'icons/obj/food_ingredients.dmi' + icon_state = "rawcutlet" + bitesize = 1 + center_of_mass = list("x"=17, "y"=20) + +/obj/item/weapon/reagent_containers/food/snacks/rawcutlet/Initialize() + . = ..() + reagents.add_reagent("protein", 1) + +/obj/item/weapon/reagent_containers/food/snacks/cutlet + name = "cutlet" + desc = "A tasty meat slice." + icon = 'icons/obj/food_ingredients.dmi' + icon_state = "cutlet" + bitesize = 2 + center_of_mass = list("x"=17, "y"=20) + +/obj/item/weapon/reagent_containers/food/snacks/cutlet/Initialize() + . = ..() + reagents.add_reagent("protein", 2) + +/obj/item/weapon/reagent_containers/food/snacks/rawmeatball + name = "raw meatball" + desc = "A raw meatball." + icon = 'icons/obj/food_ingredients.dmi' + icon_state = "rawmeatball" + bitesize = 2 + center_of_mass = list("x"=16, "y"=15) + +/obj/item/weapon/reagent_containers/food/snacks/rawmeatball/Initialize() + . = ..() + reagents.add_reagent("protein", 2) + +/obj/item/weapon/reagent_containers/food/snacks/hotdog + name = "hotdog" + desc = "Unrelated to dogs, maybe." + icon_state = "hotdog" + bitesize = 2 + center_of_mass = list("x"=16, "y"=17) + +/obj/item/weapon/reagent_containers/food/snacks/hotdog/Initialize() + . = ..() + reagents.add_reagent("protein", 6) + +/obj/item/weapon/reagent_containers/food/snacks/hotdog/old + name = "old hotdog" + desc = "Covered in mold. You're not gonna eat that, are you?" + +/obj/item/weapon/reagent_containers/food/snacks/hotdog/old/Initialize() + . = ..() + reagents.add_reagent("mold", 6) + +/obj/item/weapon/reagent_containers/food/snacks/flatbread + name = "flatbread" + desc = "Bland but filling." + icon = 'icons/obj/food_ingredients.dmi' + icon_state = "flatbread" + bitesize = 2 + center_of_mass = list("x"=16, "y"=16) + nutriment_amt = 3 + nutriment_desc = list("bread" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/flatbread/Initialize() + . = ..() + +// potato + knife = raw sticks +/obj/item/weapon/reagent_containers/food/snacks/grown/attackby(obj/item/weapon/W, mob/user) + if(seed && seed.kitchen_tag && seed.kitchen_tag == "potato" && istype(W,/obj/item/weapon/material/knife)) + new /obj/item/weapon/reagent_containers/food/snacks/rawsticks(get_turf(src)) + user << "You cut the potato." + qdel(src) + else + ..() + +/obj/item/weapon/reagent_containers/food/snacks/rawsticks + name = "raw potato sticks" + desc = "Raw fries, not very tasty." + icon = 'icons/obj/food_ingredients.dmi' + icon_state = "rawsticks" + bitesize = 2 + center_of_mass = list("x"=16, "y"=12) + nutriment_amt = 3 + nutriment_desc = list("raw potato" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/rawsticks/Initialize() + . = ..() + +/obj/item/weapon/reagent_containers/food/snacks/liquidfood + name = "\improper LiquidFood Ration" + desc = "A prepackaged grey slurry of all the essential nutrients for a spacefarer on the go. Should this be crunchy?" + icon_state = "liquidfood" + trash = /obj/item/trash/liquidfood + filling_color = "#A8A8A8" + center_of_mass = list("x"=16, "y"=15) + nutriment_amt = 20 + nutriment_desc = list("chalk" = 6) + +/obj/item/weapon/reagent_containers/food/snacks/liquidfood/Initialize() + . = ..() + reagents.add_reagent("iron", 3) + bitesize = 4 + +/obj/item/weapon/reagent_containers/food/snacks/tastybread + name = "bread tube" + desc = "Bread in a tube. Chewy...and surprisingly tasty." + icon_state = "tastybread" + trash = /obj/item/trash/tastybread + filling_color = "#A66829" + center_of_mass = list("x"=17, "y"=16) + nutriment_amt = 6 + nutriment_desc = list("bread" = 2, "sweetness" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/tastybread/Initialize() + . = ..() + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/skrellsnacks + name = "\improper SkrellSnax" + desc = "Cured fungus shipped all the way from Qerr'balak, almost like jerky! Almost." + icon_state = "skrellsnacks" + filling_color = "#A66829" + center_of_mass = list("x"=15, "y"=12) + nutriment_amt = 10 + nutriment_desc = list("mushroom" = 5, "salt" = 5) + +/obj/item/weapon/reagent_containers/food/snacks/skrellsnacks/Initialize() + . = ..() + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/unajerky + name = "Moghes Imported Sissalik Jerky" + icon_state = "unathitinred" + desc = "An incredibly well made jerky, shipped in all the way from Moghes." + trash = /obj/item/trash/unajerky + filling_color = "#631212" + center_of_mass = list("x"=15, "y"=9) + +/obj/item/weapon/reagent_containers/food/snacks/unajerky/New() + ..() + reagents.add_reagent("protein", 8) + reagents.add_reagent("capsaicin", 2) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/croissant + name = "croissant" + desc = "True French cuisine." + filling_color = "#E3D796" + icon_state = "croissant" + nutriment_amt = 6 + nutriment_desc = list("french bread" = 6) + +/obj/item/weapon/reagent_containers/food/snacks/croissant/Initialize() + . = ..() + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/meatbun + name = "meat bun" + desc = "Chinese street food, in neither China nor a street." + filling_color = "#DEDEAB" + icon_state = "meatbun" + nutriment_amt = 4 + +/obj/item/weapon/reagent_containers/food/snacks/meatbun/Initialize() + . = ..() + bitesize = 2 + reagents.add_reagent("protein", 4) + +/obj/item/weapon/reagent_containers/food/snacks/sashimi + name = "carp sashimi" + desc = "Expertly prepared. Still toxic." + filling_color = "#FFDEFE" + icon_state = "sashimi" + nutriment_amt = 6 + +/obj/item/weapon/reagent_containers/food/snacks/sashimi/Initialize() + . = ..() + reagents.add_reagent("protein", 2) + reagents.add_reagent("carpotoxin", 2) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/benedict + name = "eggs benedict" + desc = "Hey, there's only one egg in this!" + filling_color = "#FFDF78" + icon_state = "benedict" + nutriment_amt = 4 + +/obj/item/weapon/reagent_containers/food/snacks/benedict/Initialize() + . = ..() + reagents.add_reagent("protein", 2) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/beans + name = "baked beans" + desc = "Musical fruit in a slightly less musical container." + filling_color = "#FC6F28" + icon_state = "beans" + nutriment_amt = 4 + nutriment_desc = list("beans" = 4) + +/obj/item/weapon/reagent_containers/food/snacks/beans/Initialize() + . = ..() + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/sugarcookie + name = "sugar cookie" + desc = "Just like your little sister used to make." + filling_color = "#DBC94F" + icon_state = "sugarcookie" + nutriment_amt = 5 + nutriment_desc = list("sweetness" = 4, "cookie" = 1) + +/obj/item/weapon/reagent_containers/food/snacks/sugarcookie/Initialize() + . = ..() + bitesize = 1 + +/obj/item/weapon/reagent_containers/food/snacks/berrymuffin + name = "berry muffin" + desc = "A delicious and spongy little cake, with berries." + icon_state = "berrymuffin" + filling_color = "#E0CF9B" + center_of_mass = list("x"=17, "y"=4) + nutriment_amt = 6 + nutriment_desc = list("sweetness" = 2, "muffin" = 2, "berries" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/berrymuffin/Initialize() + . = ..() + reagents.add_reagent("nutriment", 6) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/ghostmuffin + name = "booberry muffin" + desc = "My stomach is a graveyard! No living being can quench my bloodthirst!" + icon_state = "berrymuffin" + filling_color = "#799ACE" + center_of_mass = list("x"=17, "y"=4) + nutriment_amt = 6 + nutriment_desc = list("spookiness" = 4, "muffin" = 1, "berries" = 1) + +/obj/item/weapon/reagent_containers/food/snacks/ghostmuffin/Initialize() + . = ..() + reagents.add_reagent("nutriment", 6) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/eggroll + name = "egg roll" + desc = "Free with orders over 10 thalers." + icon_state = "eggroll" + filling_color = "#799ACE" + center_of_mass = list("x"=17, "y"=4) + nutriment_amt = 4 + nutriment_desc = list("egg" = 4) + +/obj/item/weapon/reagent_containers/food/snacks/eggroll/Initialize() + . = ..() + reagents.add_reagent("nutriment", 6) + reagents.add_reagent("protein", 2) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/fruitsalad + name = "fruit salad" + desc = "Your standard fruit salad." + icon_state = "fruitsalad" + filling_color = "#FF3867" + nutriment_amt = 10 + nutriment_desc = list("fruit" = 10) + +/obj/item/weapon/reagent_containers/food/snacks/fruitsalad/Initialize() + . = ..() + reagents.add_reagent("nutriment", 10) + bitesize = 4 + +/obj/item/weapon/reagent_containers/food/snacks/eggbowl + name = "egg bowl" + desc = "A bowl of fried rice with egg mixed in." + icon_state = "eggbowl" + trash = /obj/item/trash/snack_bowl + filling_color = "#FFFBDB" + nutriment_amt = 6 + nutriment_desc = list("rice" = 2, "egg" = 4) + +/obj/item/weapon/reagent_containers/food/snacks/eggbowl/Initialize() + . = ..() + reagents.add_reagent("nutriment", 6) + reagents.add_reagent("protein", 4) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/porkbowl + name = "pork bowl" + desc = "A bowl of fried rice with cuts of meat." + icon_state = "porkbowl" + trash = /obj/item/trash/snack_bowl + filling_color = "#FFFBDB" + nutriment_amt = 6 + nutriment_desc = list("rice" = 2, "meat" = 4) + +/obj/item/weapon/reagent_containers/food/snacks/porkbowl/Initialize() + . = ..() + reagents.add_reagent("nutriment", 6) + reagents.add_reagent("protein", 4) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/tortilla + name = "tortilla" + desc = "The base for all your burritos." + icon_state = "tortilla" + nutriment_amt = 1 + nutriment_desc = list("bread" = 1) + +/obj/item/weapon/reagent_containers/food/snacks/tortilla/Initialize() + . = ..() + reagents.add_reagent("nutriment", 2) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/meatburrito + name = "carne asada burrito" + desc = "The best burrito for meat lovers." + icon_state = "carneburrito" + nutriment_amt = 6 + nutriment_desc = list("tortilla" = 3, "meat" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/meatburrito/Initialize() + . = ..() + reagents.add_reagent("protein", 6) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/cheeseburrito + name = "Cheese burrito" + desc = "It's a burrito filled with cheese." + icon_state = "cheeseburrito" + nutriment_amt = 6 + nutriment_desc = list("tortilla" = 3, "cheese" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/cheeseburrito/Initialize() + . = ..() + reagents.add_reagent("nutriment", 6) + reagents.add_reagent("protein", 2) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/fuegoburrito + name = "fuego phoron burrito" + desc = "A super spicy burrito." + icon_state = "fuegoburrito" + nutriment_amt = 6 + nutriment_desc = list("chili peppers" = 5, "tortilla" = 1) + +/obj/item/weapon/reagent_containers/food/snacks/fuegoburrito/Initialize() + . = ..() + reagents.add_reagent("nutriment", 6) + reagents.add_reagent("capsaicin", 4) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/nachos + name = "nachos" + desc = "Chips from Old Mexico." + icon_state = "nachos" + nutriment_amt = 2 + nutriment_desc = list("salt" = 1) + +/obj/item/weapon/reagent_containers/food/snacks/nachos/Initialize() + . = ..() + reagents.add_reagent("nutriment", 1) + bitesize = 1 + +/obj/item/weapon/reagent_containers/food/snacks/cheesenachos + name = "cheesy nachos" + desc = "The delicious combination of nachos and melting cheese." + icon_state = "cheesenachos" + nutriment_amt = 5 + nutriment_desc = list("salt" = 2, "cheese" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/cheesenachos/Initialize() + . = ..() + reagents.add_reagent("nutriment", 5) + reagents.add_reagent("protein", 2) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/cubannachos + name = "cuban nachos" + desc = "That's some dangerously spicy nachos." + icon_state = "cubannachos" + nutriment_amt = 6 + nutriment_desc = list("salt" = 1, "cheese" = 2, "chili peppers" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/cubannachos/Initialize() + . = ..() + reagents.add_reagent("nutriment", 5) + reagents.add_reagent("capsaicin", 4) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/piginblanket + name = "pig in a blanket" + desc = "A sausage embedded in soft, fluffy pastry. Free this pig from its blanket prison by eating it." + icon_state = "piginblanket" + nutriment_amt = 6 + nutriment_desc = list("meat" = 3, "pastry" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/piginblanket/Initialize() + . = ..() + reagents.add_reagent("nutriment", 6) + reagents.add_reagent("protein", 4) bitesize = 3 \ No newline at end of file diff --git a/code/modules/food/food/snacks/meat.dm b/code/modules/food/food/snacks/meat.dm index d6ecacea48..9d472b8c34 100644 --- a/code/modules/food/food/snacks/meat.dm +++ b/code/modules/food/food/snacks/meat.dm @@ -6,8 +6,8 @@ filling_color = "#FF1C1C" center_of_mass = list("x"=16, "y"=14) -/obj/item/weapon/reagent_containers/food/snacks/meat/New() - ..() +/obj/item/weapon/reagent_containers/food/snacks/meat/Initialize() + . = ..() reagents.add_reagent("protein", 9) src.bitesize = 3 diff --git a/code/modules/food/food/z_custom_food_vr.dm b/code/modules/food/food/z_custom_food_vr.dm index ed8406c6e6..f83200b7f9 100644 --- a/code/modules/food/food/z_custom_food_vr.dm +++ b/code/modules/food/food/z_custom_food_vr.dm @@ -48,10 +48,10 @@ var/global/ingredientLimit = 20 return*/ user.drop_item() I.forceMove(src) - + if(S.reagents) S.reagents.trans_to(src,S.reagents.total_volume) - + ingredients += S if(src.addTop) @@ -123,7 +123,7 @@ var/global/ingredientLimit = 20 return new_name /obj/item/weapon/reagent_containers/food/snacks/customizable/Destroy() - QDEL_NULL_LIST(ingredients) + QDEL_LIST_NULL(ingredients) return ..() /obj/item/weapon/reagent_containers/food/snacks/customizable/proc/drawTopping() diff --git a/code/modules/food/glass/bottle.dm b/code/modules/food/glass/bottle.dm index fcf618c201..7396076892 100644 --- a/code/modules/food/glass/bottle.dm +++ b/code/modules/food/glass/bottle.dm @@ -27,8 +27,8 @@ ..() update_icon() -/obj/item/weapon/reagent_containers/glass/bottle/New() - ..() +/obj/item/weapon/reagent_containers/glass/bottle/Initialize() + . = ..() if(!icon_state) icon_state = "bottle-[rand(1,4)]" diff --git a/code/modules/food/kitchen/cooking_machines/_cooker.dm b/code/modules/food/kitchen/cooking_machines/_cooker.dm index a361bf3007..a5215a747e 100644 --- a/code/modules/food/kitchen/cooking_machines/_cooker.dm +++ b/code/modules/food/kitchen/cooking_machines/_cooker.dm @@ -35,6 +35,10 @@ cooking_obj = null return ..() +/obj/machinery/cooker/proc/set_cooking(new_setting) + cooking = new_setting + icon_state = new_setting ? on_icon : off_icon + /obj/machinery/cooker/examine() ..() if(cooking_obj && Adjacent(usr)) @@ -113,7 +117,7 @@ user.visible_message("\The [user] puts \the [I] into \the [src].") cooking_obj = I cooking_obj.forceMove(src) - cooking = 1 + set_cooking(TRUE) icon_state = on_icon // Doop de doo. Jeopardy theme goes here. @@ -123,7 +127,7 @@ if(!cooking_obj || cooking_obj.loc != src) cooking_obj = null icon_state = off_icon - cooking = 0 + set_cooking(FALSE) return // RIP slow-moving held mobs. @@ -166,12 +170,12 @@ if(!can_burn_food) icon_state = off_icon - cooking = 0 + set_cooking(FALSE) result.forceMove(get_turf(src)) cooking_obj = null else var/failed - var/overcook_period = max(Floor(cook_time/5),1) + var/overcook_period = max(FLOOR(cook_time/5, 1),1) cooking_obj = result var/count = overcook_period while(1) @@ -192,7 +196,7 @@ failed = 1 if(failed) - cooking = 0 + set_cooking(FALSE) icon_state = off_icon break @@ -201,7 +205,7 @@ if(cooking_obj && user.Adjacent(src)) //Fixes borgs being able to teleport food in these machines to themselves. user << "You grab \the [cooking_obj] from \the [src]." user.put_in_hands(cooking_obj) - cooking = 0 + set_cooking(FALSE) cooking_obj = null icon_state = off_icon return diff --git a/code/modules/food/kitchen/cooking_machines/fryer.dm b/code/modules/food/kitchen/cooking_machines/fryer.dm index 451f84c2ff..e0dc15cc45 100644 --- a/code/modules/food/kitchen/cooking_machines/fryer.dm +++ b/code/modules/food/kitchen/cooking_machines/fryer.dm @@ -8,6 +8,22 @@ off_icon = "fryer_off" food_color = "#FFAD33" cooked_sound = 'sound/machines/ding.ogg' + var/datum/looping_sound/deep_fryer/fry_loop + +/obj/machinery/cooker/fryer/Initialize() + fry_loop = new(list(src), FALSE) + return ..() + +/obj/machinery/cooker/fryer/Destroy() + QDEL_NULL(fry_loop) + return ..() + +/obj/machinery/cooker/fryer/set_cooking(new_setting) + ..() + if(new_setting) + fry_loop.start() + else + fry_loop.stop() /obj/machinery/cooker/fryer/cook_mob(var/mob/living/victim, var/mob/user) @@ -17,16 +33,19 @@ user.visible_message("\The [user] starts pushing \the [victim] into \the [src]!") icon_state = on_icon cooking = 1 + fry_loop.start() if(!do_mob(user, victim, 20)) cooking = 0 icon_state = off_icon + fry_loop.stop() return if(!victim || !victim.Adjacent(user)) user << "Your victim slipped free!" cooking = 0 icon_state = off_icon + fry_loop.stop() return var/obj/item/organ/external/E @@ -62,4 +81,5 @@ icon_state = off_icon cooking = 0 + fry_loop.stop() return diff --git a/code/modules/food/kitchen/gibber.dm b/code/modules/food/kitchen/gibber.dm index 4799002cb5..3863dbddf7 100644 --- a/code/modules/food/kitchen/gibber.dm +++ b/code/modules/food/kitchen/gibber.dm @@ -1,236 +1,236 @@ - -/obj/machinery/gibber - name = "gibber" - desc = "The name isn't descriptive enough?" - icon = 'icons/obj/kitchen.dmi' - icon_state = "grinder" - density = 1 - anchored = 1 - req_access = list(access_kitchen,access_morgue) - - var/operating = 0 //Is it on? - var/dirty = 0 // Does it need cleaning? - var/mob/living/occupant // Mob who has been put inside - var/gib_time = 40 // Time from starting until meat appears - var/gib_throw_dir = WEST // Direction to spit meat and gibs in. - - use_power = 1 - idle_power_usage = 2 - active_power_usage = 500 - -//auto-gibs anything that bumps into it -/obj/machinery/gibber/autogibber - var/turf/input_plate - -/obj/machinery/gibber/autogibber/New() - ..() - spawn(5) - for(var/i in cardinal) - var/obj/machinery/mineral/input/input_obj = locate( /obj/machinery/mineral/input, get_step(src.loc, i) ) - if(input_obj) - if(isturf(input_obj.loc)) - input_plate = input_obj.loc - gib_throw_dir = i - qdel(input_obj) - break - - if(!input_plate) - log_misc("a [src] didn't find an input plate.") - return - -/obj/machinery/gibber/autogibber/Bumped(var/atom/A) - if(!input_plate) return - - if(ismob(A)) - var/mob/M = A - - if(M.loc == input_plate - ) - M.loc = src - M.gib() - - -/obj/machinery/gibber/New() - ..() - src.overlays += image('icons/obj/kitchen.dmi', "grjam") - -/obj/machinery/gibber/update_icon() - overlays.Cut() - if (dirty) - src.overlays += image('icons/obj/kitchen.dmi', "grbloody") - if(stat & (NOPOWER|BROKEN)) - return - if (!occupant) - src.overlays += image('icons/obj/kitchen.dmi', "grjam") - else if (operating) - src.overlays += image('icons/obj/kitchen.dmi', "gruse") - else - src.overlays += image('icons/obj/kitchen.dmi', "gridle") - -/obj/machinery/gibber/relaymove(mob/user as mob) - src.go_out() - return - -/obj/machinery/gibber/attack_hand(mob/user as mob) - if(stat & (NOPOWER|BROKEN)) - return - if(operating) - user << "The gibber is locked and running, wait for it to finish." - return - else - src.startgibbing(user) - -/obj/machinery/gibber/examine() - ..() - usr << "The safety guard is [emagged ? "disabled" : "enabled"]." - -/obj/machinery/gibber/emag_act(var/remaining_charges, var/mob/user) - emagged = !emagged - user << "You [emagged ? "disable" : "enable"] the gibber safety guard." - return 1 - -/obj/machinery/gibber/attackby(var/obj/item/W, var/mob/user) - var/obj/item/weapon/grab/G = W - - if(default_unfasten_wrench(user, W, 40)) - return - - if(!istype(G)) - return ..() - - if(G.state < 2) - user << "You need a better grip to do that!" - return - - move_into_gibber(user,G.affecting) - // Grab() process should clean up the grab item, no need to del it. - -/obj/machinery/gibber/MouseDrop_T(mob/target, mob/user) - if(user.stat || user.restrained()) - return - move_into_gibber(user,target) - -/obj/machinery/gibber/proc/move_into_gibber(var/mob/user,var/mob/living/victim) - - if(src.occupant) - user << "The gibber is full, empty it first!" - return - - if(operating) - user << "The gibber is locked and running, wait for it to finish." - return - - if(!(istype(victim, /mob/living/carbon)) && !(istype(victim, /mob/living/simple_animal)) ) - user << "This is not suitable for the gibber!" - return - - if(istype(victim,/mob/living/carbon/human) && !emagged) - user << "The gibber safety guard is engaged!" - return - - - if(victim.abiotic(1)) - user << "Subject may not have abiotic items on." - return - - user.visible_message("[user] starts to put [victim] into the gibber!") - src.add_fingerprint(user) - if(do_after(user, 30) && victim.Adjacent(src) && user.Adjacent(src) && victim.Adjacent(user) && !occupant) - user.visible_message("[user] stuffs [victim] into the gibber!") - if(victim.client) - victim.client.perspective = EYE_PERSPECTIVE - victim.client.eye = src - victim.loc = src - src.occupant = victim - update_icon() - -/obj/machinery/gibber/verb/eject() - set category = "Object" - set name = "Empty Gibber" - set src in oview(1) - - if (usr.stat != 0) - return - src.go_out() - add_fingerprint(usr) - return - -/obj/machinery/gibber/proc/go_out() - if(operating || !src.occupant) - return - for(var/obj/O in src) - O.loc = src.loc - if (src.occupant.client) - src.occupant.client.eye = src.occupant.client.mob - src.occupant.client.perspective = MOB_PERSPECTIVE - src.occupant.loc = src.loc - src.occupant = null - update_icon() - return - - -/obj/machinery/gibber/proc/startgibbing(mob/user as mob) - if(src.operating) - return - if(!src.occupant) - visible_message("You hear a loud metallic grinding sound.") - return - - use_power(1000) - visible_message("You hear a loud [occupant.isSynthetic() ? "metallic" : "squelchy"] grinding sound.") - src.operating = 1 - update_icon() - - var/slab_name = occupant.name - var/slab_count = 3 - var/slab_type = /obj/item/weapon/reagent_containers/food/snacks/meat - var/slab_nutrition = src.occupant.nutrition / 15 - - // Some mobs have specific meat item types. - if(istype(src.occupant,/mob/living/simple_animal)) - var/mob/living/simple_animal/critter = src.occupant - if(critter.meat_amount) - slab_count = critter.meat_amount - if(critter.meat_type) - slab_type = critter.meat_type - else if(istype(src.occupant,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = occupant - slab_name = src.occupant.real_name - slab_type = H.isSynthetic() ? /obj/item/stack/material/steel : H.species.meat_type - - // Small mobs don't give as much nutrition. - if(issmall(src.occupant)) - slab_nutrition *= 0.5 - slab_nutrition /= slab_count - - for(var/i=1 to slab_count) - var/obj/item/weapon/reagent_containers/food/snacks/meat/new_meat = new slab_type(src, rand(3,8)) - if(istype(new_meat)) - new_meat.name = "[slab_name] [new_meat.name]" - new_meat.reagents.add_reagent("nutriment",slab_nutrition) - if(src.occupant.reagents) - src.occupant.reagents.trans_to_obj(new_meat, round(occupant.reagents.total_volume/slab_count,1)) - - add_attack_logs(user,occupant,"Used [src] to gib") - - src.occupant.ghostize() - - spawn(gib_time) - - src.operating = 0 - src.occupant.gib() - qdel(src.occupant) - - playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) - operating = 0 - for (var/obj/item/thing in contents) - // There's a chance that the gibber will fail to destroy some evidence. - if(istype(thing,/obj/item/organ) && prob(80)) - qdel(thing) - continue - thing.forceMove(get_turf(thing)) // Drop it onto the turf for throwing. - thing.throw_at(get_edge_target_turf(src,gib_throw_dir),rand(0,3),emagged ? 100 : 50) // Being pelted with bits of meat and bone would hurt. - - update_icon() - - + +/obj/machinery/gibber + name = "gibber" + desc = "The name isn't descriptive enough?" + icon = 'icons/obj/kitchen.dmi' + icon_state = "grinder" + density = 1 + anchored = 1 + req_access = list(access_kitchen,access_morgue) + + var/operating = 0 //Is it on? + var/dirty = 0 // Does it need cleaning? + var/mob/living/occupant // Mob who has been put inside + var/gib_time = 40 // Time from starting until meat appears + var/gib_throw_dir = WEST // Direction to spit meat and gibs in. + + use_power = 1 + idle_power_usage = 2 + active_power_usage = 500 + +//auto-gibs anything that bumps into it +/obj/machinery/gibber/autogibber + var/turf/input_plate + +/obj/machinery/gibber/autogibber/New() + ..() + spawn(5) + for(var/i in cardinal) + var/obj/machinery/mineral/input/input_obj = locate( /obj/machinery/mineral/input, get_step(src.loc, i) ) + if(input_obj) + if(isturf(input_obj.loc)) + input_plate = input_obj.loc + gib_throw_dir = i + qdel(input_obj) + break + + if(!input_plate) + log_misc("a [src] didn't find an input plate.") + return + +/obj/machinery/gibber/autogibber/Bumped(var/atom/A) + if(!input_plate) return + + if(ismob(A)) + var/mob/M = A + + if(M.loc == input_plate + ) + M.loc = src + M.gib() + + +/obj/machinery/gibber/New() + ..() + src.overlays += image('icons/obj/kitchen.dmi', "grjam") + +/obj/machinery/gibber/update_icon() + overlays.Cut() + if (dirty) + src.overlays += image('icons/obj/kitchen.dmi', "grbloody") + if(stat & (NOPOWER|BROKEN)) + return + if (!occupant) + src.overlays += image('icons/obj/kitchen.dmi', "grjam") + else if (operating) + src.overlays += image('icons/obj/kitchen.dmi', "gruse") + else + src.overlays += image('icons/obj/kitchen.dmi', "gridle") + +/obj/machinery/gibber/relaymove(mob/user as mob) + src.go_out() + return + +/obj/machinery/gibber/attack_hand(mob/user as mob) + if(stat & (NOPOWER|BROKEN)) + return + if(operating) + user << "The gibber is locked and running, wait for it to finish." + return + else + src.startgibbing(user) + +/obj/machinery/gibber/examine() + ..() + usr << "The safety guard is [emagged ? "disabled" : "enabled"]." + +/obj/machinery/gibber/emag_act(var/remaining_charges, var/mob/user) + emagged = !emagged + user << "You [emagged ? "disable" : "enable"] the gibber safety guard." + return 1 + +/obj/machinery/gibber/attackby(var/obj/item/W, var/mob/user) + var/obj/item/weapon/grab/G = W + + if(default_unfasten_wrench(user, W, 40)) + return + + if(!istype(G)) + return ..() + + if(G.state < 2) + user << "You need a better grip to do that!" + return + + move_into_gibber(user,G.affecting) + // Grab() process should clean up the grab item, no need to del it. + +/obj/machinery/gibber/MouseDrop_T(mob/target, mob/user) + if(user.stat || user.restrained()) + return + move_into_gibber(user,target) + +/obj/machinery/gibber/proc/move_into_gibber(var/mob/user,var/mob/living/victim) + + if(src.occupant) + user << "The gibber is full, empty it first!" + return + + if(operating) + user << "The gibber is locked and running, wait for it to finish." + return + + if(!(istype(victim, /mob/living/carbon)) && !(istype(victim, /mob/living/simple_mob)) ) + user << "This is not suitable for the gibber!" + return + + if(istype(victim,/mob/living/carbon/human) && !emagged) + user << "The gibber safety guard is engaged!" + return + + + if(victim.abiotic(1)) + user << "Subject may not have abiotic items on." + return + + user.visible_message("[user] starts to put [victim] into the gibber!") + src.add_fingerprint(user) + if(do_after(user, 30) && victim.Adjacent(src) && user.Adjacent(src) && victim.Adjacent(user) && !occupant) + user.visible_message("[user] stuffs [victim] into the gibber!") + if(victim.client) + victim.client.perspective = EYE_PERSPECTIVE + victim.client.eye = src + victim.loc = src + src.occupant = victim + update_icon() + +/obj/machinery/gibber/verb/eject() + set category = "Object" + set name = "Empty Gibber" + set src in oview(1) + + if (usr.stat != 0) + return + src.go_out() + add_fingerprint(usr) + return + +/obj/machinery/gibber/proc/go_out() + if(operating || !src.occupant) + return + for(var/obj/O in src) + O.loc = src.loc + if (src.occupant.client) + src.occupant.client.eye = src.occupant.client.mob + src.occupant.client.perspective = MOB_PERSPECTIVE + src.occupant.loc = src.loc + src.occupant = null + update_icon() + return + + +/obj/machinery/gibber/proc/startgibbing(mob/user as mob) + if(src.operating) + return + if(!src.occupant) + visible_message("You hear a loud metallic grinding sound.") + return + + use_power(1000) + visible_message("You hear a loud [occupant.isSynthetic() ? "metallic" : "squelchy"] grinding sound.") + src.operating = 1 + update_icon() + + var/slab_name = occupant.name + var/slab_count = 3 + var/slab_type = /obj/item/weapon/reagent_containers/food/snacks/meat + var/slab_nutrition = src.occupant.nutrition / 15 + + // Some mobs have specific meat item types. + if(istype(src.occupant,/mob/living/simple_mob)) + var/mob/living/simple_mob/critter = src.occupant + if(critter.meat_amount) + slab_count = critter.meat_amount + if(critter.meat_type) + slab_type = critter.meat_type + else if(istype(src.occupant,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = occupant + slab_name = src.occupant.real_name + slab_type = H.isSynthetic() ? /obj/item/stack/material/steel : H.species.meat_type + + // Small mobs don't give as much nutrition. + if(issmall(src.occupant)) + slab_nutrition *= 0.5 + slab_nutrition /= slab_count + + for(var/i=1 to slab_count) + var/obj/item/weapon/reagent_containers/food/snacks/meat/new_meat = new slab_type(src, rand(3,8)) + if(istype(new_meat)) + new_meat.name = "[slab_name] [new_meat.name]" + new_meat.reagents.add_reagent("nutriment",slab_nutrition) + if(src.occupant.reagents) + src.occupant.reagents.trans_to_obj(new_meat, round(occupant.reagents.total_volume/slab_count,1)) + + add_attack_logs(user,occupant,"Used [src] to gib") + + src.occupant.ghostize() + + spawn(gib_time) + + src.operating = 0 + src.occupant.gib() + qdel(src.occupant) + + playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) + operating = 0 + for (var/obj/item/thing in contents) + // There's a chance that the gibber will fail to destroy some evidence. + if(istype(thing,/obj/item/organ) && prob(80)) + qdel(thing) + continue + thing.forceMove(get_turf(thing)) // Drop it onto the turf for throwing. + thing.throw_at(get_edge_target_turf(src,gib_throw_dir),rand(0,3),emagged ? 100 : 50) // Being pelted with bits of meat and bone would hurt. + + update_icon() + + diff --git a/code/modules/food/kitchen/icecream.dm b/code/modules/food/kitchen/icecream.dm index 09cb3289ed..821e118c01 100644 --- a/code/modules/food/kitchen/icecream.dm +++ b/code/modules/food/kitchen/icecream.dm @@ -51,7 +51,7 @@ else return "vanilla" -/obj/machinery/icecream_vat/initialize() +/obj/machinery/icecream_vat/Initialize() . = ..() create_reagents(100) while(product_types.len < 6) diff --git a/code/modules/food/kitchen/microwave.dm b/code/modules/food/kitchen/microwave.dm index 7357dd5568..0eb0683ba8 100644 --- a/code/modules/food/kitchen/microwave.dm +++ b/code/modules/food/kitchen/microwave.dm @@ -1,392 +1,396 @@ -/obj/machinery/microwave - name = "microwave" - icon = 'icons/obj/kitchen.dmi' - icon_state = "mw" - density = 1 - anchored = 1 - use_power = 1 - idle_power_usage = 5 - active_power_usage = 100 - flags = OPENCONTAINER | NOREACT - circuit = /obj/item/weapon/circuitboard/microwave - var/operating = 0 // Is it on? - var/dirty = 0 // = {0..100} Does it need cleaning? - var/broken = 0 // ={0,1,2} How broken is it??? - var/global/list/datum/recipe/available_recipes // List of the recipes you can use - var/global/list/acceptable_items // List of the items you can put in - var/global/list/acceptable_reagents // List of the reagents you can put in - var/global/max_n_of_items = 0 - - -// see code/modules/food/recipes_microwave.dm for recipes - -/******************* -* Initialising -********************/ - -/obj/machinery/microwave/New() - ..() - reagents = new/datum/reagents(100) - reagents.my_atom = src - - component_parts = list() - component_parts += new /obj/item/weapon/stock_parts/console_screen(src) - component_parts += new /obj/item/weapon/stock_parts/motor(src) - component_parts += new /obj/item/weapon/stock_parts/capacitor(src) - - if (!available_recipes) - available_recipes = new - for (var/type in (typesof(/datum/recipe)-/datum/recipe)) - available_recipes+= new type - acceptable_items = new - acceptable_reagents = new - for (var/datum/recipe/recipe in available_recipes) - for (var/item in recipe.items) - acceptable_items |= item - for (var/reagent in recipe.reagents) - acceptable_reagents |= reagent - if (recipe.items) - max_n_of_items = max(max_n_of_items,recipe.items.len) - // This will do until I can think of a fun recipe to use dionaea in - - // will also allow anything using the holder item to be microwaved into - // impure carbon. ~Z - acceptable_items |= /obj/item/weapon/holder - acceptable_items |= /obj/item/weapon/reagent_containers/food/snacks/grown - - RefreshParts() - -/******************* -* Item Adding -********************/ - -/obj/machinery/microwave/attackby(var/obj/item/O as obj, var/mob/user as mob) - if(src.broken > 0) - if(src.broken == 2 && O.is_screwdriver()) // If it's broken and they're using a screwdriver - user.visible_message( \ - "\The [user] starts to fix part of the microwave.", \ - "You start to fix part of the microwave." \ - ) - playsound(src, O.usesound, 50, 1) - if (do_after(user,20 * O.toolspeed)) - user.visible_message( \ - "\The [user] fixes part of the microwave.", \ - "You have fixed part of the microwave." \ - ) - src.broken = 1 // Fix it a bit - else if(src.broken == 1 && O.is_wrench()) // If it's broken and they're doing the wrench - user.visible_message( \ - "\The [user] starts to fix part of the microwave.", \ - "You start to fix part of the microwave." \ - ) - if (do_after(user,20 * O.toolspeed)) - user.visible_message( \ - "\The [user] fixes the microwave.", \ - "You have fixed the microwave." \ - ) - src.icon_state = "mw" - src.broken = 0 // Fix it! - src.dirty = 0 // just to be sure - src.flags = OPENCONTAINER | NOREACT - else - to_chat(user, "It's broken!") - return 1 - else if(default_deconstruction_screwdriver(user, O)) - return - else if(default_deconstruction_crowbar(user, O)) - return - else if(default_unfasten_wrench(user, O, 10)) - return - - else if(src.dirty==100) // The microwave is all dirty so can't be used! - if(istype(O, /obj/item/weapon/reagent_containers/spray/cleaner) || istype(O, /obj/item/weapon/soap)) // If they're trying to clean it then let them - user.visible_message( \ - "\The [user] starts to clean the microwave.", \ - "You start to clean the microwave." \ - ) - if (do_after(user,20)) - user.visible_message( \ - "\The [user] has cleaned the microwave.", \ - "You have cleaned the microwave." \ - ) - src.dirty = 0 // It's clean! - src.broken = 0 // just to be sure - src.icon_state = "mw" - src.flags = OPENCONTAINER | NOREACT - else //Otherwise bad luck!! - to_chat(user, "It's dirty!") - return 1 - else if(is_type_in_list(O,acceptable_items)) - if (contents.len>=(max_n_of_items + component_parts.len + 1)) //Adds component_parts to the maximum number of items. The 1 is from the circuit - to_chat(user, "This [src] is full of ingredients, you cannot put more.") - return 1 - if(istype(O, /obj/item/stack) && O:get_amount() > 1) // This is bad, but I can't think of how to change it - var/obj/item/stack/S = O - new O.type (src) - S.use(1) - user.visible_message( \ - "\The [user] has added one of [O] to \the [src].", \ - "You add one of [O] to \the [src].") - return - else - // user.remove_from_mob(O) //This just causes problems so far as I can tell. -Pete - user.drop_item() - O.loc = src - user.visible_message( \ - "\The [user] has added \the [O] to \the [src].", \ - "You add \the [O] to \the [src].") - return - else if(istype(O,/obj/item/weapon/reagent_containers/glass) || \ - istype(O,/obj/item/weapon/reagent_containers/food/drinks) || \ - istype(O,/obj/item/weapon/reagent_containers/food/condiment) \ - ) - if (!O.reagents) - return 1 - for (var/datum/reagent/R in O.reagents.reagent_list) - if (!(R.id in acceptable_reagents)) - to_chat(user, "Your [O] contains components unsuitable for cookery.") - return 1 - return - else if(istype(O,/obj/item/weapon/grab)) - var/obj/item/weapon/grab/G = O - to_chat(user, "This is ridiculous. You can not fit \the [G.affecting] in this [src].") - return 1 - else - to_chat(user, "You have no idea what you can cook with this [O].") - ..() - src.updateUsrDialog() - -/obj/machinery/microwave/attack_ai(mob/user as mob) - if(istype(user, /mob/living/silicon/robot) && Adjacent(user)) - attack_hand(user) - -/obj/machinery/microwave/attack_hand(mob/user as mob) - user.set_machine(src) - interact(user) - -/******************* -* Microwave Menu -********************/ - -/obj/machinery/microwave/interact(mob/user as mob) // The microwave Menu - var/dat = "" - if(src.broken > 0) - dat = {"Bzzzzttttt"} - else if(src.operating) - dat = {"Microwaving in progress!
    Please wait...!
    "} - else if(src.dirty==100) - dat = {"This microwave is dirty!
    Please clean it before use!
    "} - else - var/list/items_counts = new - var/list/items_measures = new - var/list/items_measures_p = new - for (var/obj/O in ((contents - component_parts) - circuit)) - var/display_name = O.name - if (istype(O,/obj/item/weapon/reagent_containers/food/snacks/egg)) - items_measures[display_name] = "egg" - items_measures_p[display_name] = "eggs" - if (istype(O,/obj/item/weapon/reagent_containers/food/snacks/tofu)) - items_measures[display_name] = "tofu chunk" - items_measures_p[display_name] = "tofu chunks" - if (istype(O,/obj/item/weapon/reagent_containers/food/snacks/meat)) //any meat - items_measures[display_name] = "slab of meat" - items_measures_p[display_name] = "slabs of meat" - if (istype(O,/obj/item/weapon/reagent_containers/food/snacks/donkpocket)) - display_name = "Turnovers" - items_measures[display_name] = "turnover" - items_measures_p[display_name] = "turnovers" - if (istype(O,/obj/item/weapon/reagent_containers/food/snacks/carpmeat)) - items_measures[display_name] = "fillet of meat" - items_measures_p[display_name] = "fillets of meat" - items_counts[display_name]++ - for (var/O in items_counts) - var/N = items_counts[O] - if (!(O in items_measures)) - dat += {"[capitalize(O)]: [N] [lowertext(O)]\s
    "} - else - if (N==1) - dat += {"[capitalize(O)]: [N] [items_measures[O]]
    "} - else - dat += {"[capitalize(O)]: [N] [items_measures_p[O]]
    "} - - for (var/datum/reagent/R in reagents.reagent_list) - var/display_name = R.name - if (R.id == "capsaicin") - display_name = "Hotsauce" - if (R.id == "frostoil") - display_name = "Coldsauce" - dat += {"[display_name]: [R.volume] unit\s
    "} - - if (items_counts.len==0 && reagents.reagent_list.len==0) - dat = {"The microwave is empty
    "} - else - dat = {"Ingredients:
    [dat]"} - dat += {"

    \ -Turn on!
    \ -
    Eject ingredients!
    \ -"} - - to_chat(user, browse("Microwave Controls[dat]", "window=microwave")) - onclose(user, "microwave") - return - - - -/*********************************** -* Microwave Menu Handling/Cooking -************************************/ - -/obj/machinery/microwave/proc/cook() - if(stat & (NOPOWER|BROKEN)) - return - start() - if (reagents.total_volume==0 && !(locate(/obj) in ((contents - component_parts) - circuit))) //dry run - if (!wzhzhzh(10)) - abort() - return - stop() - return - - var/datum/recipe/recipe = select_recipe(available_recipes,src) - var/obj/cooked - if (!recipe) - dirty += 1 - if (prob(max(10,dirty*5))) - if (!wzhzhzh(4)) - abort() - return - muck_start() - wzhzhzh(4) - muck_finish() - cooked = fail() - cooked.loc = src.loc - return - else if (has_extra_item()) - if (!wzhzhzh(4)) - abort() - return - broke() - cooked = fail() - cooked.loc = src.loc - return - else - if (!wzhzhzh(10)) - abort() - return - stop() - cooked = fail() - cooked.loc = src.loc - return - else - var/halftime = round(recipe.time/10/2) - if (!wzhzhzh(halftime)) - abort() - return - if (!wzhzhzh(halftime)) - abort() - cooked = fail() - cooked.loc = src.loc - return - cooked = recipe.make_food(src) - stop() - if(cooked) - cooked.loc = src.loc - return - -/obj/machinery/microwave/proc/wzhzhzh(var/seconds as num) // Whoever named this proc is fucking literally Satan. ~ Z - for (var/i=1 to seconds) - if (stat & (NOPOWER|BROKEN)) - return 0 - use_power(500) - sleep(10) - return 1 - -/obj/machinery/microwave/proc/has_extra_item() - for (var/obj/O in ((contents - component_parts) - circuit)) - if ( \ - !istype(O,/obj/item/weapon/reagent_containers/food) && \ - !istype(O, /obj/item/weapon/grown) \ - ) - return 1 - return 0 - -/obj/machinery/microwave/proc/start() - src.visible_message("The microwave turns on.", "You hear a microwave.") - src.operating = 1 - src.icon_state = "mw1" - src.updateUsrDialog() - -/obj/machinery/microwave/proc/abort() - src.operating = 0 // Turn it off again aferwards - src.icon_state = "mw" - src.updateUsrDialog() - -/obj/machinery/microwave/proc/stop() - playsound(src.loc, 'sound/machines/ding.ogg', 50, 1) - src.operating = 0 // Turn it off again aferwards - src.icon_state = "mw" - src.updateUsrDialog() - -/obj/machinery/microwave/proc/dispose() - for (var/obj/O in ((contents-component_parts)-circuit)) - O.loc = src.loc - if (src.reagents.total_volume) - src.dirty++ - src.reagents.clear_reagents() - usr << "You dispose of the microwave contents." - src.updateUsrDialog() - -/obj/machinery/microwave/proc/muck_start() - playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) // Play a splat sound - src.icon_state = "mwbloody1" // Make it look dirty!! - -/obj/machinery/microwave/proc/muck_finish() - playsound(src.loc, 'sound/machines/ding.ogg', 50, 1) - src.visible_message("The microwave gets covered in muck!") - src.dirty = 100 // Make it dirty so it can't be used util cleaned - src.flags = null //So you can't add condiments - src.icon_state = "mwbloody" // Make it look dirty too - src.operating = 0 // Turn it off again aferwards - src.updateUsrDialog() - -/obj/machinery/microwave/proc/broke() - var/datum/effect/effect/system/spark_spread/s = new - s.set_up(2, 1, src) - s.start() - src.icon_state = "mwb" // Make it look all busted up and shit - src.visible_message("The microwave breaks!") //Let them know they're stupid - src.broken = 2 // Make it broken so it can't be used util fixed - src.flags = null //So you can't add condiments - src.operating = 0 // Turn it off again aferwards - src.updateUsrDialog() - -/obj/machinery/microwave/proc/fail() - var/obj/item/weapon/reagent_containers/food/snacks/badrecipe/ffuu = new(src) - var/amount = 0 - for (var/obj/O in (((contents - ffuu) - component_parts) - circuit)) - amount++ - if (O.reagents) - var/id = O.reagents.get_master_reagent_id() - if (id) - amount+=O.reagents.get_reagent_amount(id) - qdel(O) - src.reagents.clear_reagents() - ffuu.reagents.add_reagent("carbon", amount) - ffuu.reagents.add_reagent("toxin", amount/10) - return ffuu - -/obj/machinery/microwave/Topic(href, href_list) - if(..()) - return - - usr.set_machine(src) - if(src.operating) - src.updateUsrDialog() - return - - switch(href_list["action"]) - if ("cook") - cook() - - if ("dispose") - dispose() - return +/obj/machinery/microwave + name = "microwave" + icon = 'icons/obj/kitchen.dmi' + icon_state = "mw" + density = 1 + anchored = 1 + use_power = 1 + idle_power_usage = 5 + active_power_usage = 100 + flags = OPENCONTAINER | NOREACT + circuit = /obj/item/weapon/circuitboard/microwave + var/operating = 0 // Is it on? + var/dirty = 0 // = {0..100} Does it need cleaning? + var/broken = 0 // ={0,1,2} How broken is it??? + var/global/list/datum/recipe/available_recipes // List of the recipes you can use + var/global/list/acceptable_items // List of the items you can put in + var/global/list/acceptable_reagents // List of the reagents you can put in + var/global/max_n_of_items = 0 + var/datum/looping_sound/microwave/soundloop + + +// see code/modules/food/recipes_microwave.dm for recipes + +/******************* +* Initialising +********************/ + +/obj/machinery/microwave/Initialize() + reagents = new/datum/reagents(100) + reagents.my_atom = src + + component_parts = list() + component_parts += new /obj/item/weapon/stock_parts/console_screen(src) + component_parts += new /obj/item/weapon/stock_parts/motor(src) + component_parts += new /obj/item/weapon/stock_parts/capacitor(src) + + if (!available_recipes) + available_recipes = new + for (var/type in (typesof(/datum/recipe)-/datum/recipe)) + available_recipes+= new type + acceptable_items = new + acceptable_reagents = new + for (var/datum/recipe/recipe in available_recipes) + for (var/item in recipe.items) + acceptable_items |= item + for (var/reagent in recipe.reagents) + acceptable_reagents |= reagent + if (recipe.items) + max_n_of_items = max(max_n_of_items,recipe.items.len) + // This will do until I can think of a fun recipe to use dionaea in - + // will also allow anything using the holder item to be microwaved into + // impure carbon. ~Z + acceptable_items |= /obj/item/weapon/holder + acceptable_items |= /obj/item/weapon/reagent_containers/food/snacks/grown + + RefreshParts() + soundloop = new(list(src), FALSE) + return ..() + +/obj/machinery/microwave/Destroy() + QDEL_NULL(soundloop) + return ..() + +/******************* +* Item Adding +********************/ + +/obj/machinery/microwave/attackby(var/obj/item/O as obj, var/mob/user as mob) + if(src.broken > 0) + if(src.broken == 2 && O.is_screwdriver()) // If it's broken and they're using a screwdriver + user.visible_message( \ + "\The [user] starts to fix part of the microwave.", \ + "You start to fix part of the microwave." \ + ) + playsound(src, O.usesound, 50, 1) + if (do_after(user,20 * O.toolspeed)) + user.visible_message( \ + "\The [user] fixes part of the microwave.", \ + "You have fixed part of the microwave." \ + ) + src.broken = 1 // Fix it a bit + else if(src.broken == 1 && O.is_wrench()) // If it's broken and they're doing the wrench + user.visible_message( \ + "\The [user] starts to fix part of the microwave.", \ + "You start to fix part of the microwave." \ + ) + if (do_after(user,20 * O.toolspeed)) + user.visible_message( \ + "\The [user] fixes the microwave.", \ + "You have fixed the microwave." \ + ) + src.icon_state = "mw" + src.broken = 0 // Fix it! + src.dirty = 0 // just to be sure + src.flags = OPENCONTAINER | NOREACT + else + to_chat(user, "It's broken!") + return 1 + else if(default_deconstruction_screwdriver(user, O)) + return + else if(default_deconstruction_crowbar(user, O)) + return + else if(default_unfasten_wrench(user, O, 10)) + return + + else if(src.dirty==100) // The microwave is all dirty so can't be used! + if(istype(O, /obj/item/weapon/reagent_containers/spray/cleaner) || istype(O, /obj/item/weapon/soap)) // If they're trying to clean it then let them + user.visible_message( \ + "\The [user] starts to clean the microwave.", \ + "You start to clean the microwave." \ + ) + if (do_after(user,20)) + user.visible_message( \ + "\The [user] has cleaned the microwave.", \ + "You have cleaned the microwave." \ + ) + src.dirty = 0 // It's clean! + src.broken = 0 // just to be sure + src.icon_state = "mw" + src.flags = OPENCONTAINER | NOREACT + else //Otherwise bad luck!! + to_chat(user, "It's dirty!") + return 1 + else if(is_type_in_list(O,acceptable_items)) + if (contents.len>=(max_n_of_items + component_parts.len + 1)) //Adds component_parts to the maximum number of items. The 1 is from the circuit + to_chat(user, "This [src] is full of ingredients, you cannot put more.") + return 1 + if(istype(O, /obj/item/stack) && O:get_amount() > 1) // This is bad, but I can't think of how to change it + var/obj/item/stack/S = O + new O.type (src) + S.use(1) + user.visible_message( \ + "\The [user] has added one of [O] to \the [src].", \ + "You add one of [O] to \the [src].") + return + else + // user.remove_from_mob(O) //This just causes problems so far as I can tell. -Pete + user.drop_item() + O.loc = src + user.visible_message( \ + "\The [user] has added \the [O] to \the [src].", \ + "You add \the [O] to \the [src].") + return + else if(istype(O,/obj/item/weapon/reagent_containers/glass) || \ + istype(O,/obj/item/weapon/reagent_containers/food/drinks) || \ + istype(O,/obj/item/weapon/reagent_containers/food/condiment) \ + ) + if (!O.reagents) + return 1 + for (var/datum/reagent/R in O.reagents.reagent_list) + if (!(R.id in acceptable_reagents)) + to_chat(user, "Your [O] contains components unsuitable for cookery.") + return 1 + return + else if(istype(O,/obj/item/weapon/grab)) + var/obj/item/weapon/grab/G = O + to_chat(user, "This is ridiculous. You can not fit \the [G.affecting] in this [src].") + return 1 + else + to_chat(user, "You have no idea what you can cook with this [O].") + ..() + src.updateUsrDialog() + +/obj/machinery/microwave/attack_ai(mob/user as mob) + if(istype(user, /mob/living/silicon/robot) && Adjacent(user)) + attack_hand(user) + +/obj/machinery/microwave/attack_hand(mob/user as mob) + user.set_machine(src) + interact(user) + +/******************* +* Microwave Menu +********************/ + +/obj/machinery/microwave/interact(mob/user as mob) // The microwave Menu + var/dat = "" + if(src.broken > 0) + dat = {"Bzzzzttttt"} + else if(src.operating) + dat = {"Microwaving in progress!
    Please wait...!
    "} + else if(src.dirty==100) + dat = {"This microwave is dirty!
    Please clean it before use!
    "} + else + var/list/items_counts = new + var/list/items_measures = new + var/list/items_measures_p = new + for (var/obj/O in ((contents - component_parts) - circuit)) + var/display_name = O.name + if (istype(O,/obj/item/weapon/reagent_containers/food/snacks/egg)) + items_measures[display_name] = "egg" + items_measures_p[display_name] = "eggs" + if (istype(O,/obj/item/weapon/reagent_containers/food/snacks/tofu)) + items_measures[display_name] = "tofu chunk" + items_measures_p[display_name] = "tofu chunks" + if (istype(O,/obj/item/weapon/reagent_containers/food/snacks/meat)) //any meat + items_measures[display_name] = "slab of meat" + items_measures_p[display_name] = "slabs of meat" + if (istype(O,/obj/item/weapon/reagent_containers/food/snacks/donkpocket)) + display_name = "Turnovers" + items_measures[display_name] = "turnover" + items_measures_p[display_name] = "turnovers" + if (istype(O,/obj/item/weapon/reagent_containers/food/snacks/carpmeat)) + items_measures[display_name] = "fillet of meat" + items_measures_p[display_name] = "fillets of meat" + items_counts[display_name]++ + for (var/O in items_counts) + var/N = items_counts[O] + if (!(O in items_measures)) + dat += {"[capitalize(O)]: [N] [lowertext(O)]\s
    "} + else + if (N==1) + dat += {"[capitalize(O)]: [N] [items_measures[O]]
    "} + else + dat += {"[capitalize(O)]: [N] [items_measures_p[O]]
    "} + + for (var/datum/reagent/R in reagents.reagent_list) + var/display_name = R.name + if (R.id == "capsaicin") + display_name = "Hotsauce" + if (R.id == "frostoil") + display_name = "Coldsauce" + dat += {"[display_name]: [R.volume] unit\s
    "} + + if (items_counts.len==0 && reagents.reagent_list.len==0) + dat = {"The microwave is empty
    "} + else + dat = {"Ingredients:
    [dat]"} + dat += {"

    \ +
    Turn on!
    \ +
    Eject ingredients!
    \ +"} + + to_chat(user, browse("Microwave Controls[dat]", "window=microwave")) + onclose(user, "microwave") + return + + + +/*********************************** +* Microwave Menu Handling/Cooking +************************************/ + +/obj/machinery/microwave/proc/cook() + if(stat & (NOPOWER|BROKEN)) + return + start() + if (reagents.total_volume==0 && !(locate(/obj) in ((contents - component_parts) - circuit))) //dry run + if (!wzhzhzh(10)) + abort() + return + abort() + return + + var/datum/recipe/recipe = select_recipe(available_recipes,src) + var/obj/cooked + if (!recipe) + dirty += 1 + if (prob(max(10,dirty*5))) + if (!wzhzhzh(4)) + abort() + return + muck_start() + wzhzhzh(4) + muck_finish() + cooked = fail() + cooked.loc = src.loc + return + else if (has_extra_item()) + if (!wzhzhzh(4)) + abort() + return + broke() + cooked = fail() + cooked.loc = src.loc + return + else + if (!wzhzhzh(10)) + abort() + return + abort() + cooked = fail() + cooked.loc = src.loc + return + else + var/halftime = round(recipe.time/10/2) + if (!wzhzhzh(halftime)) + abort() + return + if (!wzhzhzh(halftime)) + abort() + cooked = fail() + cooked.loc = src.loc + return + cooked = recipe.make_food(src) + abort() + if(cooked) + cooked.loc = src.loc + return + +/obj/machinery/microwave/proc/wzhzhzh(var/seconds as num) // Whoever named this proc is fucking literally Satan. ~ Z + for (var/i=1 to seconds) + if (stat & (NOPOWER|BROKEN)) + return 0 + use_power(500) + sleep(10) + return 1 + +/obj/machinery/microwave/proc/has_extra_item() + for (var/obj/O in ((contents - component_parts) - circuit)) + if ( \ + !istype(O,/obj/item/weapon/reagent_containers/food) && \ + !istype(O, /obj/item/weapon/grown) \ + ) + return 1 + return 0 + +/obj/machinery/microwave/proc/start() + src.visible_message("The microwave turns on.", "You hear a microwave.") + soundloop.start() + src.operating = TRUE + src.icon_state = "mw1" + src.updateUsrDialog() + +/obj/machinery/microwave/proc/abort() + operating = FALSE // Turn it off again aferwards + icon_state = "mw" + updateUsrDialog() + soundloop.stop() + +/obj/machinery/microwave/proc/dispose() + for (var/obj/O in ((contents-component_parts)-circuit)) + O.loc = src.loc + if (src.reagents.total_volume) + src.dirty++ + src.reagents.clear_reagents() + usr << "You dispose of the microwave contents." + src.updateUsrDialog() + +/obj/machinery/microwave/proc/muck_start() + playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) // Play a splat sound + src.icon_state = "mwbloody1" // Make it look dirty!! + +/obj/machinery/microwave/proc/muck_finish() + src.visible_message("The microwave gets covered in muck!") + src.dirty = 100 // Make it dirty so it can't be used util cleaned + src.flags = null //So you can't add condiments + src.icon_state = "mwbloody" // Make it look dirty too + src.operating = 0 // Turn it off again aferwards + src.updateUsrDialog() + soundloop.stop() + + +/obj/machinery/microwave/proc/broke() + var/datum/effect/effect/system/spark_spread/s = new + s.set_up(2, 1, src) + s.start() + src.icon_state = "mwb" // Make it look all busted up and shit + src.visible_message("The microwave breaks!") //Let them know they're stupid + src.broken = 2 // Make it broken so it can't be used util fixed + src.flags = null //So you can't add condiments + src.operating = 0 // Turn it off again aferwards + src.updateUsrDialog() + soundloop.stop() + +/obj/machinery/microwave/proc/fail() + var/obj/item/weapon/reagent_containers/food/snacks/badrecipe/ffuu = new(src) + var/amount = 0 + for (var/obj/O in (((contents - ffuu) - component_parts) - circuit)) + amount++ + if (O.reagents) + var/id = O.reagents.get_master_reagent_id() + if (id) + amount+=O.reagents.get_reagent_amount(id) + qdel(O) + src.reagents.clear_reagents() + ffuu.reagents.add_reagent("carbon", amount) + ffuu.reagents.add_reagent("toxin", amount/10) + return ffuu + +/obj/machinery/microwave/Topic(href, href_list) + if(..()) + return + + usr.set_machine(src) + if(src.operating) + src.updateUsrDialog() + return + + switch(href_list["action"]) + if ("cook") + cook() + + if ("dispose") + dispose() + return diff --git a/code/modules/food/kitchen/smartfridge.dm b/code/modules/food/kitchen/smartfridge.dm index 005f7749b6..0213ef089b 100644 --- a/code/modules/food/kitchen/smartfridge.dm +++ b/code/modules/food/kitchen/smartfridge.dm @@ -11,6 +11,7 @@ active_power_usage = 100 flags = NOREACT var/max_n_of_items = 999 // Sorry but the BYOND infinite loop detector doesn't look things over 1000. //VOREStation Edit - Non-global + //var/global/max_n_of_items = 999 // Sorry but the BYOND infinite loop detector doesn't look things over 1000. var/icon_on = "smartfridge" var/icon_off = "smartfridge-off" var/icon_panel = "smartfridge-panel" @@ -215,7 +216,7 @@ overlays.Cut() if(panel_open) overlays += image(icon, icon_panel) - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) return if(wrenchable && default_unfasten_wrench(user, O, 20)) @@ -281,11 +282,11 @@ var/datum/stored_item/item = new/datum/stored_item(src, O.type, O.name) item.add_product(O) item_records.Add(item) - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) /obj/machinery/smartfridge/proc/vend(datum/stored_item/I) I.get_product(get_turf(src)) - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) /obj/machinery/smartfridge/attack_ai(mob/user as mob) attack_hand(user) @@ -320,7 +321,7 @@ if(items.len > 0) data["contents"] = items - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if(!ui) ui = new(user, src, ui_key, "smartfridge.tmpl", src.name, 400, 500) ui.set_initial_data(data) @@ -330,7 +331,7 @@ if(..()) return 0 var/mob/user = usr - var/datum/nanoui/ui = GLOB.nanomanager.get_open_ui(user, src, "main") + var/datum/nanoui/ui = SSnanoui.get_open_ui(user, src, "main") src.add_fingerprint(user) diff --git a/code/modules/food/recipe_dump.dm b/code/modules/food/recipe_dump.dm index 19f7988826..a458a568cf 100644 --- a/code/modules/food/recipe_dump.dm +++ b/code/modules/food/recipe_dump.dm @@ -68,14 +68,14 @@ //Reagents can be resolved to nicer names as well for(var/Rp in food_recipes) for(var/rid in food_recipes[Rp]["Reagents"]) - var/datum/reagent/Rd = chemical_reagents_list[rid] + var/datum/reagent/Rd = SSchemistry.chemical_reagents[rid] var/R_name = Rd.name var/amt = food_recipes[Rp]["Reagents"][rid] food_recipes[Rp]["Reagents"] -= rid food_recipes[Rp]["Reagents"][R_name] = amt for(var/Rp in drink_recipes) for(var/rid in drink_recipes[Rp]["Reagents"]) - var/datum/reagent/Rd = chemical_reagents_list[rid] + var/datum/reagent/Rd = SSchemistry.chemical_reagents[rid] var/R_name = Rd.name var/amt = drink_recipes[Rp]["Reagents"][rid] drink_recipes[Rp]["Reagents"] -= rid diff --git a/code/modules/gamemaster/actions/carp_migration.dm b/code/modules/gamemaster/actions/carp_migration.dm index 7c76a5119c..b635ca6d5e 100644 --- a/code/modules/gamemaster/actions/carp_migration.dm +++ b/code/modules/gamemaster/actions/carp_migration.dm @@ -32,7 +32,7 @@ var/activeness = ((metric.assess_department(ROLE_SECURITY) + metric.assess_department(ROLE_ENGINEERING) + metric.assess_department(ROLE_MEDICAL)) / 3) activeness = max(activeness, 20) - carp_amount = Ceiling(station_strength * (activeness / 100) + 1) + carp_amount = CEILING(station_strength * (activeness / 100) + 1, 1) /datum/gm_action/carp_migration/start() ..() @@ -52,12 +52,12 @@ while (i <= carp_amount) var/group_size = rand(group_size_min, group_size_max) for (var/j = 1, j <= group_size, j++) - spawned_carp.Add(new /mob/living/simple_animal/hostile/carp(spawn_locations[i])) + spawned_carp.Add(new /mob/living/simple_mob/animal/space/carp/event(spawn_locations[i])) i++ message_admins("[spawned_carp.len] carp spawned by event.") /datum/gm_action/carp_migration/end() - for(var/mob/living/simple_animal/hostile/carp/C in spawned_carp) + for(var/mob/living/simple_mob/animal/space/carp/C in spawned_carp) if(!C.stat) var/turf/T = get_turf(C) if(istype(T, /turf/space)) diff --git a/code/modules/gamemaster/actions/surprise_carp_attack.dm b/code/modules/gamemaster/actions/surprise_carp_attack.dm index e78dd72343..14c4b03e0e 100644 --- a/code/modules/gamemaster/actions/surprise_carp_attack.dm +++ b/code/modules/gamemaster/actions/surprise_carp_attack.dm @@ -47,7 +47,5 @@ spawning_turf = space break if(spawning_turf) - var/mob/living/simple_animal/hostile/carp/C = new(spawning_turf) - C.target_mob = victim - C.stance = STANCE_ATTACK + new /mob/living/simple_mob/animal/space/carp(spawning_turf) number_of_carp-- \ No newline at end of file diff --git a/code/modules/gamemaster/game_master.dm b/code/modules/gamemaster/game_master.dm index c435e868f6..16a6a03887 100644 --- a/code/modules/gamemaster/game_master.dm +++ b/code/modules/gamemaster/game_master.dm @@ -22,7 +22,7 @@ for(var/datum/gm_action/action in available_actions) action.gm = src -/datum/game_master/proc/process() +/datum/game_master/process() if(ticker && ticker.current_state == GAME_STATE_PLAYING && !suspended) adjust_staleness(1) adjust_danger(-1) diff --git a/code/modules/gamemaster/helpers.dm b/code/modules/gamemaster/helpers.dm index 80fc133931..da05cb1b20 100644 --- a/code/modules/gamemaster/helpers.dm +++ b/code/modules/gamemaster/helpers.dm @@ -1,9 +1,9 @@ // Tell the game master that something dangerous happened, e.g. someone dying. /datum/game_master/proc/adjust_danger(var/amt) amt = amt * danger_modifier - danger = round( Clamp(danger + amt, 0, 1000), 0.1) + danger = round( CLAMP(danger + amt, 0, 1000), 0.1) // Tell the game master that something interesting happened. /datum/game_master/proc/adjust_staleness(var/amt) amt = amt * staleness_modifier - staleness = round( Clamp(staleness + amt, -50, 200), 0.1) \ No newline at end of file + staleness = round( CLAMP(staleness + amt, -50, 200), 0.1) \ No newline at end of file diff --git a/code/modules/games/cards.dm b/code/modules/games/cards.dm index cbeff5fb34..e9b3ae537e 100644 --- a/code/modules/games/cards.dm +++ b/code/modules/games/cards.dm @@ -238,7 +238,7 @@ /obj/item/weapon/deck/MouseDrop(mob/user as mob) // Code from Paper bin, so you can still pick up the deck if((user == usr && (!( usr.restrained() ) && (!( usr.stat ) && (usr.contents.Find(src) || in_range(src, usr)))))) - if(!istype(usr, /mob/living/simple_animal)) + if(!istype(usr, /mob/living/simple_mob)) if( !usr.get_active_hand() ) //if active hand is empty var/mob/living/carbon/human/H = user var/obj/item/organ/external/temp = H.organs_by_name["r_hand"] @@ -256,7 +256,7 @@ /obj/item/weapon/deck/verb_pickup(mob/user as mob) // Snowflaked so pick up verb work as intended if((user == usr && (!( usr.restrained() ) && (!( usr.stat ) && (usr.contents.Find(src) || in_range(src, usr)))))) - if(!istype(usr, /mob/living/simple_animal)) + if(!istype(usr, /mob/living/simple_mob)) if( !usr.get_active_hand() ) //if active hand is empty var/mob/living/carbon/human/H = user var/obj/item/organ/external/temp = H.organs_by_name["r_hand"] @@ -413,7 +413,7 @@ overlays += I return - var/offset = Floor(20/cards.len) + var/offset = FLOOR(20/cards.len, 1) var/matrix/M = matrix() if(direction) diff --git a/code/modules/holodeck/HolodeckControl.dm b/code/modules/holodeck/HolodeckControl.dm index e5c9b81d99..4cce81a2a6 100644 --- a/code/modules/holodeck/HolodeckControl.dm +++ b/code/modules/holodeck/HolodeckControl.dm @@ -32,22 +32,22 @@ "Beach" = new/datum/holodeck_program(/area/holodeck/source_beach), "Desert" = new/datum/holodeck_program(/area/holodeck/source_desert, list( - 'sound/effects/wind/wind_2_1.ogg', - 'sound/effects/wind/wind_2_2.ogg', - 'sound/effects/wind/wind_3_1.ogg', - 'sound/effects/wind/wind_4_1.ogg', - 'sound/effects/wind/wind_4_2.ogg', - 'sound/effects/wind/wind_5_1.ogg' + 'sound/effects/weather/wind/wind_2_1.ogg', + 'sound/effects/weather/wind/wind_2_2.ogg', + 'sound/effects/weather/wind/wind_3_1.ogg', + 'sound/effects/weather/wind/wind_4_1.ogg', + 'sound/effects/weather/wind/wind_4_2.ogg', + 'sound/effects/weather/wind/wind_5_1.ogg' ) ), "Snowfield" = new/datum/holodeck_program(/area/holodeck/source_snowfield, list( - 'sound/effects/wind/wind_2_1.ogg', - 'sound/effects/wind/wind_2_2.ogg', - 'sound/effects/wind/wind_3_1.ogg', - 'sound/effects/wind/wind_4_1.ogg', - 'sound/effects/wind/wind_4_2.ogg', - 'sound/effects/wind/wind_5_1.ogg' + 'sound/effects/weather/wind/wind_2_1.ogg', + 'sound/effects/weather/wind/wind_2_2.ogg', + 'sound/effects/weather/wind/wind_3_1.ogg', + 'sound/effects/weather/wind/wind_4_1.ogg', + 'sound/effects/weather/wind/wind_4_2.ogg', + 'sound/effects/weather/wind/wind_5_1.ogg' ) ), "Space" = new/datum/holodeck_program(/area/holodeck/source_space, @@ -112,7 +112,7 @@ else data["gravity"] = null - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "holodeck.tmpl", src.name, 400, 550) ui.set_initial_data(data) @@ -152,7 +152,7 @@ src.add_fingerprint(usr) - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) /obj/machinery/computer/HolodeckControl/emag_act(var/remaining_charges, var/mob/user as mob) playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1) @@ -177,7 +177,7 @@ for(var/obj/item/weapon/holo/esword/H in linkedholodeck) H.damtype = initial(H.damtype) - for(var/mob/living/simple_animal/hostile/carp/holodeck/C in holographic_mobs) + for(var/mob/living/simple_mob/animal/space/carp/holodeck/C in holographic_mobs) C.set_safety(!safety_disabled) if (last_to_emag) C.friends = list(last_to_emag) @@ -210,7 +210,7 @@ derez(item, 0) if (!safety_disabled) - for(var/mob/living/simple_animal/hostile/carp/holodeck/C in holographic_mobs) + for(var/mob/living/simple_mob/animal/space/carp/holodeck/C in holographic_mobs) if (get_area(C.loc) != linkedholodeck) holographic_mobs -= C C.derez() @@ -306,7 +306,7 @@ for(var/item in holographic_objs) derez(item) - for(var/mob/living/simple_animal/hostile/carp/holodeck/C in holographic_mobs) + for(var/mob/living/simple_mob/animal/space/carp/holodeck/C in holographic_mobs) holographic_mobs -= C C.derez() @@ -340,11 +340,11 @@ T.temperature = 5000 T.hotspot_expose(50000,50000,1) if(L.name=="Holocarp Spawn") - holographic_mobs += new /mob/living/simple_animal/hostile/carp/holodeck(L.loc) + holographic_mobs += new /mob/living/simple_mob/animal/space/carp/holodeck(L.loc) if(L.name=="Holocarp Spawn Random") if (prob(4)) //With 4 spawn points, carp should only appear 15% of the time. - holographic_mobs += new /mob/living/simple_animal/hostile/carp/holodeck(L.loc) + holographic_mobs += new /mob/living/simple_mob/animal/space/carp/holodeck(L.loc) update_projections() diff --git a/code/modules/holodeck/HolodeckObjects.dm b/code/modules/holodeck/HolodeckObjects.dm index 8e6d20eab9..9ffeb100d7 100644 --- a/code/modules/holodeck/HolodeckObjects.dm +++ b/code/modules/holodeck/HolodeckObjects.dm @@ -104,7 +104,7 @@ base_icon = 'icons/turf/flooring/asteroid.dmi' initial_flooring = null -/turf/simulated/floor/holofloor/desert/initialize() +/turf/simulated/floor/holofloor/desert/Initialize() . = ..() if(prob(10)) add_overlay("asteroid[rand(0,9)]") @@ -419,7 +419,7 @@ //Holocarp -/mob/living/simple_animal/hostile/carp/holodeck +/mob/living/simple_mob/animal/space/carp/holodeck icon = 'icons/mob/AI.dmi' icon_state = "holo4" icon_living = "holo4" @@ -429,31 +429,27 @@ meat_amount = 0 meat_type = null -/mob/living/simple_animal/hostile/carp/holodeck/New() +/mob/living/simple_mob/animal/space/carp/holodeck/New() ..() set_light(2) //hologram lighting -/mob/living/simple_animal/hostile/carp/holodeck/proc/set_safety(var/safe) +/mob/living/simple_mob/animal/space/carp/holodeck/proc/set_safety(var/safe) if (safe) faction = "neutral" melee_damage_lower = 0 melee_damage_upper = 0 - environment_smash = 0 - destroy_surroundings = 0 else faction = "carp" melee_damage_lower = initial(melee_damage_lower) melee_damage_upper = initial(melee_damage_upper) - environment_smash = initial(environment_smash) - destroy_surroundings = initial(destroy_surroundings) -/mob/living/simple_animal/hostile/carp/holodeck/gib() +/mob/living/simple_mob/animal/space/carp/holodeck/gib() derez() //holograms can't gib -/mob/living/simple_animal/hostile/carp/holodeck/death() +/mob/living/simple_mob/animal/space/carp/holodeck/death() ..() derez() -/mob/living/simple_animal/hostile/carp/holodeck/proc/derez() +/mob/living/simple_mob/animal/space/carp/holodeck/proc/derez() visible_message("\The [src] fades away!") qdel(src) diff --git a/code/modules/holomap/station_holomap.dm b/code/modules/holomap/station_holomap.dm index b47c154b65..d38875f220 100644 --- a/code/modules/holomap/station_holomap.dm +++ b/code/modules/holomap/station_holomap.dm @@ -38,7 +38,7 @@ SSholomaps.station_holomaps += src flags |= ON_BORDER // Why? It doesn't help if its not density -/obj/machinery/station_map/initialize() +/obj/machinery/station_map/Initialize() . = ..() if(SSholomaps.holomaps_initialized) spawn(1) // Tragically we need to spawn this in order to give the frame construcing us time to set pixel_x/y @@ -125,7 +125,7 @@ watching_mob = user GLOB.moved_event.register(watching_mob, src, /obj/machinery/station_map/proc/checkPosition) GLOB.dir_set_event.register(watching_mob, src, /obj/machinery/station_map/proc/checkPosition) - destroyed_event.register(watching_mob, src, /obj/machinery/station_map/proc/stopWatching) + GLOB.destroyed_event.register(watching_mob, src, /obj/machinery/station_map/proc/stopWatching) update_use_power(2) if(bogus) @@ -154,7 +154,7 @@ M.client.images -= holomap_datum.station_map GLOB.moved_event.unregister(watching_mob, src) GLOB.dir_set_event.unregister(watching_mob, src) - destroyed_event.unregister(watching_mob, src) + GLOB.destroyed_event.unregister(watching_mob, src) watching_mob = null update_use_power(1) diff --git a/code/modules/hydroponics/seed.dm b/code/modules/hydroponics/seed.dm index 5c6053aba4..9ed2d836a6 100644 --- a/code/modules/hydroponics/seed.dm +++ b/code/modules/hydroponics/seed.dm @@ -104,10 +104,10 @@ return if(!istype(target)) - if(istype(target, /mob/living/simple_animal/mouse)) + if(istype(target, /mob/living/simple_mob/animal/passive/mouse)) new /obj/effect/decal/remains/mouse(get_turf(target)) qdel(target) - else if(istype(target, /mob/living/simple_animal/lizard)) + else if(istype(target, /mob/living/simple_mob/animal/passive/lizard)) new /obj/effect/decal/remains/lizard(get_turf(target)) qdel(target) return @@ -437,7 +437,7 @@ for(var/x=1;x<=additional_chems;x++) - var/new_chem = pick(chemical_reagents_list) + var/new_chem = pick(SSchemistry.chemical_reagents) if(new_chem in banned_chems) continue banned_chems += new_chem diff --git a/code/modules/hydroponics/seed_controller.dm b/code/modules/hydroponics/seed_controller.dm index b0aaab0a7c..27e6347e5a 100644 --- a/code/modules/hydroponics/seed_controller.dm +++ b/code/modules/hydroponics/seed_controller.dm @@ -131,7 +131,7 @@ var/global/datum/controller/plants/plant_controller // Set in New(). seed.set_trait(TRAIT_HIGHKPA_TOLERANCE,200) return seed -/datum/controller/plants/proc/process() +/datum/controller/plants/process() processing = 1 spawn(0) set background = 1 diff --git a/code/modules/hydroponics/seed_datums.dm b/code/modules/hydroponics/seed_datums.dm index b70a02af4c..eab78597b1 100644 --- a/code/modules/hydroponics/seed_datums.dm +++ b/code/modules/hydroponics/seed_datums.dm @@ -184,7 +184,7 @@ display_name = "killer tomato plant" mutants = null can_self_harvest = 1 - has_mob_product = /mob/living/simple_animal/hostile/tomato + has_mob_product = /mob/living/simple_mob/tomato /datum/seed/tomato/killer/New() ..() diff --git a/code/modules/hydroponics/seed_machines.dm b/code/modules/hydroponics/seed_machines.dm index 8d7ebdf314..4601f23484 100644 --- a/code/modules/hydroponics/seed_machines.dm +++ b/code/modules/hydroponics/seed_machines.dm @@ -162,7 +162,7 @@ data["hasGenetics"] = 0 data["sourceName"] = 0 - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "botany_isolator.tmpl", "Lysis-isolation Centrifuge UI", 470, 450) ui.set_initial_data(data) @@ -292,7 +292,7 @@ else data["loaded"] = 0 - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "botany_editor.tmpl", "Bioballistic Delivery UI", 470, 450) ui.set_initial_data(data) diff --git a/code/modules/hydroponics/seed_packets.dm b/code/modules/hydroponics/seed_packets.dm index 0689f428b6..f4b8b951a5 100644 --- a/code/modules/hydroponics/seed_packets.dm +++ b/code/modules/hydroponics/seed_packets.dm @@ -13,7 +13,7 @@ GLOBAL_LIST_BOILERPLATE(all_seed_packs, /obj/item/seeds) var/datum/seed/seed var/modified = 0 -/obj/item/seeds/initialize() +/obj/item/seeds/Initialize() update_seed() . = ..() @@ -75,7 +75,7 @@ GLOBAL_LIST_BOILERPLATE(all_seed_packs, /obj/item/seeds) /obj/item/seeds/random seed_type = null -/obj/item/seeds/random/initialize() +/obj/item/seeds/random/Initialize() seed = plant_controller.create_random_seed() seed_type = seed.name . = ..() diff --git a/code/modules/hydroponics/trays/tray.dm b/code/modules/hydroponics/trays/tray.dm index 8db9f7a8f1..5dad0b9c21 100644 --- a/code/modules/hydroponics/trays/tray.dm +++ b/code/modules/hydroponics/trays/tray.dm @@ -165,7 +165,7 @@ nymph.visible_message("[nymph] rolls around in [src] for a bit.","You roll around in [src] for a bit.") return -/obj/machinery/portable_atmospherics/hydroponics/initialize() +/obj/machinery/portable_atmospherics/hydroponics/Initialize() . = ..() temp_chem_holder = new() temp_chem_holder.create_reagents(10) diff --git a/code/modules/identification/identification.dm b/code/modules/identification/identification.dm new file mode 100644 index 0000000000..568ad2103e --- /dev/null +++ b/code/modules/identification/identification.dm @@ -0,0 +1,127 @@ +// This is a datum attached to objects to make their 'identity' be unknown initially. +// The identitiy and properties of an unidentified object can be determined in-game through a specialized process or by potentially risky trial-and-error. +// This is very similar to a traditional roguelike's identification system, and as such will use certain terms from those to describe them. +// Despite this, unlike a roguelike, objects that do the same thing DO NOT have the same name/appearance/etc. + +/datum/identification + var/obj/holder = null // The thing the datum is 'attached' to. + // Holds the true information. + var/true_name = null // The real name of the object. It is copied automatically from holder, on the datum being instantiated. + var/true_desc = null // Ditto, for desc. + var/true_description_info = null // Ditto, for helpful examine panel entries. + var/true_description_fluff = null // Ditto, for lore. + var/true_description_antag = null // Ditto, for antag info (this probably won't get used). + var/identified = IDENTITY_UNKNOWN // Can be IDENTITY_UNKNOWN, IDENTITY_PROPERTIES, IDENTITY_QUALITY, or IDENTITY_FULL. + + // Holds what is displayed when not identified sufficently. + var/unidentified_name = null // The name given to the object when not identified. Generated by generate_unidentified_name() + var/unidentified_desc = "You're not too sure what this is." + var/unidentified_description_info = "This object is unidentified, and as such its properties are unknown. Using this object may be dangerous." + + // Lists of lists for generating names by combining one from each. + var/list/naming_lists = list() + + // What 'identification type' is needed to identify this. + var/identification_type = IDENTITY_TYPE_NONE + +/datum/identification/New(obj/new_holder) + ASSERT(new_holder) + holder = new_holder + record_true_identity() // Get all the identifying features from the holder. + update_name() // Then hide them for awhile if needed. + +/datum/identification/Destroy() + holder = null + return ..() + +// Records the object's inital identifiying features to the datum for future safekeeping. +/datum/identification/proc/record_true_identity() + true_name = holder.name + true_desc = holder.desc + true_description_info = holder.description_info + true_description_fluff = holder.description_fluff + true_description_antag = holder.description_antag + +// Formally identifies the holder. +/datum/identification/proc/identify(new_identity = IDENTITY_FULL, mob/user) + if(new_identity & identified) // Already done. + return + identified |= new_identity // Set the bitflag. + if(user) + switch(identified) + if(IDENTITY_QUALITY) + to_chat(user, "You've identified \the [holder]'s quality.") + if(IDENTITY_PROPERTIES) + to_chat(user, "You've identified \the [holder]'s functionality as a [true_name].") + if(IDENTITY_FULL) + to_chat(user, "You've identified \the [holder] as a [true_name], and its quality.") + update_name() + holder.update_icon() + +// Reverses identification for whatever reason. +/datum/identification/proc/unidentify(new_identity = IDENTITY_UNKNOWN, mob/user) + identified &= ~new_identity // Unset the bitflag. + update_name() + holder.update_icon() + if(user) + switch(identified) // Give a message based on what's left. + if(IDENTITY_QUALITY) + to_chat(user, span("warning", "You forgot what \the [holder] actually did...")) + if(IDENTITY_PROPERTIES) + to_chat(user, span("warning", "You forgot \the [holder]'s quality...")) + if(IDENTITY_UNKNOWN) + to_chat(user, span("warning", "You forgot everything about \the [holder].")) + +// Sets the holder's name to the real name if its properties are identified, or obscures it otherwise. +/datum/identification/proc/update_name() + if(identified & IDENTITY_PROPERTIES) + holder.name = true_name + holder.desc = true_desc + holder.description_info = true_description_info + holder.description_fluff = true_description_fluff + holder.description_antag = true_description_antag + return + + if(!unidentified_name) + unidentified_name = generate_unidentified_name() + + holder.name = unidentified_name + holder.desc = unidentified_desc + holder.description_info = unidentified_description_info + holder.description_fluff = null + holder.description_antag = null + +// Makes a name for an object that is not identified. It picks one string out of each list inside naming_list. +/datum/identification/proc/generate_unidentified_name() + if(!LAZYLEN(naming_lists)) + return "unidentified object" + + var/list/new_name = list() + for(var/i in naming_lists) + var/list/current_list = i + new_name += pick(current_list) + return new_name.Join(" ") + +// Used for tech-based objects. +// Unused for now pending Future Stuff(tm). +/datum/identification/mechanical + naming_lists = list( + list("unidentified", "unknown", "strange", "weird", "unfamiliar", "peculiar", "mysterious", "bizarre", "odd"), + list("device", "apparatus", "gadget", "mechanism", "appliance", "machine", "equipment", "invention", "contraption") + ) + identification_type = IDENTITY_TYPE_TECH + +// Used for unidentified hypos. +// Their contents can range from genuine medication, expired medicine, illicit drugs, toxins and poisons, and more. +// They are the analog for potions in a traditional roguelike. +/datum/identification/hypo + naming_lists = list( + list("unidentified", "unknown", "unmarked", "blank", "refilled", "custom", "modified", "questionable", "suspicious"), + list("hypospray", "autoinjector") + ) + unidentified_desc = "An autoinjector that does not give any indication towards what is inside. \ + The case is also sealed tight and the liquids contained cannot be removed except by injecting it into someone. \ + Do you feel lucky?" + unidentified_description_info = "A skilled chemist with a specialized machine can identify this autoinjector. \ + Blindly using the autoinjector is risky and can be dangerous." + identification_type = IDENTITY_TYPE_CHEMICAL diff --git a/code/modules/identification/item_procs.dm b/code/modules/identification/item_procs.dm new file mode 100644 index 0000000000..c2e5ddaed6 --- /dev/null +++ b/code/modules/identification/item_procs.dm @@ -0,0 +1,30 @@ +// This is on the base /item so badmins can play with it by calling hide_identity(). +/obj/item + var/datum/identification/identity = null + var/identity_type = /datum/identification + var/init_hide_identity = FALSE // Set to true to automatically obscure the object on initialization. + +/obj/item/Initialize() + if(init_hide_identity) + identity = new identity_type(src) + return ..() + +/obj/item/Destroy() + if(identity) + QDEL_NULL(identity) + return ..() + +/obj/item/proc/hide_identity() // Mostly for admins to make things secret. + if(!identity) + identity = new identity_type(src) + else + identity.unidentify() + +/obj/item/proc/identify(identity_type = IDENTITY_FULL, mob/user) + if(identity) + identity.identify(identity_type, user) + +/obj/item/proc/is_identified(identity_type = IDENTITY_FULL) + if(!identity) // No identification datum means nothing to hide. + return TRUE + return identity_type & identity.identified diff --git a/code/modules/integrated_electronics/core/assemblies.dm b/code/modules/integrated_electronics/core/assemblies.dm index 8367e2096a..60a290924f 100644 --- a/code/modules/integrated_electronics/core/assemblies.dm +++ b/code/modules/integrated_electronics/core/assemblies.dm @@ -20,14 +20,14 @@ var/detail_color = COLOR_ASSEMBLY_BLACK -/obj/item/device/electronic_assembly/initialize() +/obj/item/device/electronic_assembly/Initialize() battery = new(src) - processing_objects |= src + START_PROCESSING(SSobj, src) return ..() /obj/item/device/electronic_assembly/Destroy() battery = null // It will be qdel'd by ..() if still in our contents - processing_objects -= src + STOP_PROCESSING(SSobj, src) return ..() /obj/item/device/electronic_assembly/process() diff --git a/code/modules/integrated_electronics/core/assemblies/clothing.dm b/code/modules/integrated_electronics/core/assemblies/clothing.dm index f8a5b31f3f..4415d367f8 100644 --- a/code/modules/integrated_electronics/core/assemblies/clothing.dm +++ b/code/modules/integrated_electronics/core/assemblies/clothing.dm @@ -108,7 +108,7 @@ icon_state = "circuitry" worn_state = "circuitry" -/obj/item/clothing/under/circuitry/initialize() +/obj/item/clothing/under/circuitry/Initialize() setup_integrated_circuit(/obj/item/device/electronic_assembly/clothing) return ..() @@ -121,7 +121,7 @@ icon_state = "circuitry" item_state = "circuitry" -/obj/item/clothing/gloves/circuitry/initialize() +/obj/item/clothing/gloves/circuitry/Initialize() setup_integrated_circuit(/obj/item/device/electronic_assembly/clothing/small) return ..() @@ -134,7 +134,7 @@ icon_state = "circuitry" item_state = "night" // The on-mob sprite would be identical anyways. -/obj/item/clothing/glasses/circuitry/initialize() +/obj/item/clothing/glasses/circuitry/Initialize() setup_integrated_circuit(/obj/item/device/electronic_assembly/clothing/small) return ..() @@ -146,7 +146,7 @@ icon_state = "circuitry" item_state = "circuitry" -/obj/item/clothing/shoes/circuitry/initialize() +/obj/item/clothing/shoes/circuitry/Initialize() setup_integrated_circuit(/obj/item/device/electronic_assembly/clothing/small) return ..() @@ -158,7 +158,7 @@ icon_state = "circuitry" item_state = "circuitry" -/obj/item/clothing/head/circuitry/initialize() +/obj/item/clothing/head/circuitry/Initialize() setup_integrated_circuit(/obj/item/device/electronic_assembly/clothing/small) return ..() @@ -170,7 +170,7 @@ icon_state = "circuitry" item_state = "circuitry" -/obj/item/clothing/ears/circuitry/initialize() +/obj/item/clothing/ears/circuitry/Initialize() setup_integrated_circuit(/obj/item/device/electronic_assembly/clothing/small) return ..() @@ -182,6 +182,6 @@ icon_state = "circuitry" item_state = "circuitry" -/obj/item/clothing/suit/circuitry/initialize() +/obj/item/clothing/suit/circuitry/Initialize() setup_integrated_circuit(/obj/item/device/electronic_assembly/clothing/large) return ..() \ No newline at end of file diff --git a/code/modules/integrated_electronics/core/assemblies/device.dm b/code/modules/integrated_electronics/core/assemblies/device.dm index 63e0bef562..bcdd0e9bea 100644 --- a/code/modules/integrated_electronics/core/assemblies/device.dm +++ b/code/modules/integrated_electronics/core/assemblies/device.dm @@ -1,84 +1,84 @@ -/obj/item/device/assembly/electronic_assembly - name = "electronic device" - desc = "It's a case for building electronics with. It can be attached to other small devices." - icon_state = "setup_device" - var/opened = 0 - - var/obj/item/device/electronic_assembly/device/EA - -/obj/item/device/assembly/electronic_assembly/New() - EA = new(src) - EA.holder = src - ..() - -/obj/item/device/assembly/electronic_assembly/attackby(obj/item/I as obj, mob/user as mob) - if (I.is_crowbar()) - toggle_open(user) - else if (opened) - EA.attackby(I, user) - else - ..() - -/obj/item/device/assembly/electronic_assembly/proc/toggle_open(mob/user) - playsound(get_turf(src), 'sound/items/Crowbar.ogg', 50, 1) - opened = !opened - EA.opened = opened - to_chat(user, "You [opened ? "opened" : "closed"] \the [src].") - secured = 1 - update_icon() - -/obj/item/device/assembly/electronic_assembly/update_icon() - if(EA) - icon_state = initial(icon_state) - else - icon_state = initial(icon_state)+"0" - if(opened) - icon_state = icon_state + "-open" - -/obj/item/device/assembly/electronic_assembly/attack_self(mob/user as mob) - if(EA) - EA.attack_self(user) - -/obj/item/device/assembly/electronic_assembly/pulsed(var/radio = 0) //Called when another assembly acts on this one, var/radio will determine where it came from for wire calcs - if(EA) - for(var/obj/item/integrated_circuit/built_in/device_input/I in EA.contents) - I.do_work() - return - -/obj/item/device/assembly/electronic_assembly/examine(mob/user) - .=..(user, 1) - if(EA) - for(var/obj/item/integrated_circuit/IC in EA.contents) - IC.external_examine(user) - -/obj/item/device/assembly/electronic_assembly/verb/toggle() - set src in usr - set category = "Object" - set name = "Open/Close Device Assembly" - set desc = "Open or close device assembly!" - - toggle_open(usr) - - -/obj/item/device/electronic_assembly/device - name = "electronic device" - icon_state = "setup_device" - desc = "It's a tiny electronic device with specific use for attaching to other devices." - var/obj/item/device/assembly/electronic_assembly/holder - w_class = ITEMSIZE_TINY - max_components = IC_COMPONENTS_BASE * 3/4 - max_complexity = IC_COMPLEXITY_BASE * 3/4 - - -/obj/item/device/electronic_assembly/device/New() - ..() - var/obj/item/integrated_circuit/built_in/device_input/input = new(src) - var/obj/item/integrated_circuit/built_in/device_output/output = new(src) - input.assembly = src - output.assembly = src - -/obj/item/device/electronic_assembly/device/check_interactivity(mob/user) - if(!CanInteract(user, state = deep_inventory_state)) - return 0 - return 1 - +/obj/item/device/assembly/electronic_assembly + name = "electronic device" + desc = "It's a case for building electronics with. It can be attached to other small devices." + icon_state = "setup_device" + var/opened = 0 + + var/obj/item/device/electronic_assembly/device/EA + +/obj/item/device/assembly/electronic_assembly/New() + EA = new(src) + EA.holder = src + ..() + +/obj/item/device/assembly/electronic_assembly/attackby(obj/item/I as obj, mob/user as mob) + if (I.is_crowbar()) + toggle_open(user) + else if (opened) + EA.attackby(I, user) + else + ..() + +/obj/item/device/assembly/electronic_assembly/proc/toggle_open(mob/user) + playsound(get_turf(src), 'sound/items/Crowbar.ogg', 50, 1) + opened = !opened + EA.opened = opened + to_chat(user, "You [opened ? "opened" : "closed"] \the [src].") + secured = 1 + update_icon() + +/obj/item/device/assembly/electronic_assembly/update_icon() + if(EA) + icon_state = initial(icon_state) + else + icon_state = initial(icon_state)+"0" + if(opened) + icon_state = icon_state + "-open" + +/obj/item/device/assembly/electronic_assembly/attack_self(mob/user as mob) + if(EA) + EA.attack_self(user) + +/obj/item/device/assembly/electronic_assembly/pulsed(var/radio = 0) //Called when another assembly acts on this one, var/radio will determine where it came from for wire calcs + if(EA) + for(var/obj/item/integrated_circuit/built_in/device_input/I in EA.contents) + I.do_work() + return + +/obj/item/device/assembly/electronic_assembly/examine(mob/user) + .=..(user, 1) + if(EA) + for(var/obj/item/integrated_circuit/IC in EA.contents) + IC.external_examine(user) + +/obj/item/device/assembly/electronic_assembly/verb/toggle() + set src in usr + set category = "Object" + set name = "Open/Close Device Assembly" + set desc = "Open or close device assembly!" + + toggle_open(usr) + + +/obj/item/device/electronic_assembly/device + name = "electronic device" + icon_state = "setup_device" + desc = "It's a tiny electronic device with specific use for attaching to other devices." + var/obj/item/device/assembly/electronic_assembly/holder + w_class = ITEMSIZE_TINY + max_components = IC_COMPONENTS_BASE * 3/4 + max_complexity = IC_COMPLEXITY_BASE * 3/4 + + +/obj/item/device/electronic_assembly/device/New() + ..() + var/obj/item/integrated_circuit/built_in/device_input/input = new(src) + var/obj/item/integrated_circuit/built_in/device_output/output = new(src) + input.assembly = src + output.assembly = src + +/obj/item/device/electronic_assembly/device/check_interactivity(mob/user) + if(!CanInteract(user, state = deep_inventory_state)) + return 0 + return 1 + diff --git a/code/modules/integrated_electronics/core/detailer.dm b/code/modules/integrated_electronics/core/detailer.dm index cd1696aecc..4c1c509384 100644 --- a/code/modules/integrated_electronics/core/detailer.dm +++ b/code/modules/integrated_electronics/core/detailer.dm @@ -25,7 +25,7 @@ "hot pink" = COLOR_ASSEMBLY_HOT_PINK ) -/obj/item/device/integrated_electronics/detailer/initialize() +/obj/item/device/integrated_electronics/detailer/Initialize() update_icon() return ..() diff --git a/code/modules/integrated_electronics/passive/power.dm b/code/modules/integrated_electronics/passive/power.dm index 829027303c..8fe37874e7 100644 --- a/code/modules/integrated_electronics/passive/power.dm +++ b/code/modules/integrated_electronics/passive/power.dm @@ -191,7 +191,7 @@ var/obj/machinery/power/circuit_io/IO = null // Dummy power machine to move energy in/out without a bunch of code duplication. var/throughput = 10000 // Give/take up to 10kW. -/obj/item/integrated_circuit/passive/power/powernet/initialize() +/obj/item/integrated_circuit/passive/power/powernet/Initialize() IO = new(src) return ..() diff --git a/code/modules/integrated_electronics/subtypes/converters.dm b/code/modules/integrated_electronics/subtypes/converters.dm index 0ec00be317..316742e488 100644 --- a/code/modules/integrated_electronics/subtypes/converters.dm +++ b/code/modules/integrated_electronics/subtypes/converters.dm @@ -265,7 +265,7 @@ pull_data() var/incoming = get_pin_data(IC_INPUT, 1) if(!isnull(incoming)) - result = ToDegrees(incoming) + result = TODEGREES(incoming) set_pin_data(IC_OUTPUT, 1, result) push_data() @@ -283,7 +283,7 @@ pull_data() var/incoming = get_pin_data(IC_INPUT, 1) if(!isnull(incoming)) - result = ToRadians(incoming) + result = TORADIANS(incoming) set_pin_data(IC_OUTPUT, 1, result) push_data() diff --git a/code/modules/integrated_electronics/subtypes/data_transfer.dm b/code/modules/integrated_electronics/subtypes/data_transfer.dm index e490ccd27a..052d3acb76 100644 --- a/code/modules/integrated_electronics/subtypes/data_transfer.dm +++ b/code/modules/integrated_electronics/subtypes/data_transfer.dm @@ -125,7 +125,7 @@ /obj/item/integrated_circuit/transfer/pulsedemultiplexer/do_work() var/output_index = get_pin_data(IC_INPUT, 1) - if(output_index == Clamp(output_index, 1, number_of_outputs)) + if(output_index == CLAMP(output_index, 1, number_of_outputs)) activate_pin(round(output_index + 1 ,1)) /obj/item/integrated_circuit/transfer/pulsedemultiplexer/medium diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm index c2e640403a..9c54a6e377 100644 --- a/code/modules/integrated_electronics/subtypes/input.dm +++ b/code/modules/integrated_electronics/subtypes/input.dm @@ -296,7 +296,7 @@ /obj/item/integrated_circuit/input/advanced_locator/on_data_written() var/rad = get_pin_data(IC_INPUT, 2) if(isnum(rad)) - rad = Clamp(rad, 0, 7) + rad = CLAMP(rad, 0, 7) radius = rad /obj/item/integrated_circuit/input/advanced_locator/do_work() @@ -353,7 +353,7 @@ var/code = 30 var/datum/radio_frequency/radio_connection -/obj/item/integrated_circuit/input/signaler/initialize() +/obj/item/integrated_circuit/input/signaler/Initialize() . = ..() set_frequency(frequency) // Set the pins so when someone sees them, they won't show as null diff --git a/code/modules/integrated_electronics/subtypes/manipulation.dm b/code/modules/integrated_electronics/subtypes/manipulation.dm index 344a7dc47e..7bb9b332d1 100644 --- a/code/modules/integrated_electronics/subtypes/manipulation.dm +++ b/code/modules/integrated_electronics/subtypes/manipulation.dm @@ -188,14 +188,14 @@ // These procs do not relocate the grenade, that's the callers responsibility /obj/item/integrated_circuit/manipulation/grenade/proc/attach_grenade(var/obj/item/weapon/grenade/G) attached_grenade = G - destroyed_event.register(attached_grenade, src, /obj/item/integrated_circuit/manipulation/grenade/proc/detach_grenade) + GLOB.destroyed_event.register(attached_grenade, src, /obj/item/integrated_circuit/manipulation/grenade/proc/detach_grenade) size += G.w_class desc += " \An [attached_grenade] is attached to it!" /obj/item/integrated_circuit/manipulation/grenade/proc/detach_grenade() if(!attached_grenade) return - destroyed_event.unregister(attached_grenade, src, /obj/item/integrated_circuit/manipulation/grenade/proc/detach_grenade) + GLOB.destroyed_event.unregister(attached_grenade, src, /obj/item/integrated_circuit/manipulation/grenade/proc/detach_grenade) attached_grenade = null size = initial(size) desc = initial(desc) diff --git a/code/modules/integrated_electronics/subtypes/output.dm b/code/modules/integrated_electronics/subtypes/output.dm index c3ff9b36d5..bbfcb25f94 100644 --- a/code/modules/integrated_electronics/subtypes/output.dm +++ b/code/modules/integrated_electronics/subtypes/output.dm @@ -103,7 +103,7 @@ var/brightness = get_pin_data(IC_INPUT, 2) if(new_color && isnum(brightness)) - brightness = Clamp(brightness, 0, 6) + brightness = CLAMP(brightness, 0, 6) light_rgb = new_color light_brightness = brightness @@ -300,7 +300,7 @@ text_output += "\an [name]" else text_output += "\an ["\improper[initial_name]"] labeled '[name]'" - text_output += " which is currently [get_pin_data(IC_INPUT, 1) ? "lit ¤" : "unlit."]" + text_output += " which is currently [get_pin_data(IC_INPUT, 1) ? "lit ¤" : "unlit."]" to_chat(user,jointext(text_output,null)) /obj/item/integrated_circuit/output/led/red @@ -462,8 +462,7 @@ /obj/item/integrated_circuit/output/holographic_projector/proc/destroy_hologram() - hologram.forceMove(src) - qdel(hologram) + QDEL_NULL(hologram) // holo_beam.End() // QDEL_NULL(holo_beam) diff --git a/code/modules/integrated_electronics/subtypes/reagents.dm b/code/modules/integrated_electronics/subtypes/reagents.dm index e8ca2ae134..ca834b3a09 100644 --- a/code/modules/integrated_electronics/subtypes/reagents.dm +++ b/code/modules/integrated_electronics/subtypes/reagents.dm @@ -83,7 +83,7 @@ else direc = 1 if(isnum(new_amount)) - new_amount = Clamp(new_amount, 0, volume) + new_amount = CLAMP(new_amount, 0, volume) transfer_amount = new_amount @@ -132,7 +132,7 @@ if(!TS.Adjacent(TT)) activate_pin(3) return - var/tramount = Clamp(min(transfer_amount, reagents.maximum_volume - reagents.total_volume), 0, reagents.maximum_volume) + var/tramount = CLAMP(min(transfer_amount, reagents.maximum_volume - reagents.total_volume), 0, reagents.maximum_volume) if(ismob(target))//Blood! if(istype(target, /mob/living/carbon)) var/mob/living/carbon/T = target @@ -207,7 +207,7 @@ else direc = 1 if(isnum(new_amount)) - new_amount = Clamp(new_amount, 0, 50) + new_amount = CLAMP(new_amount, 0, 50) transfer_amount = new_amount /obj/item/integrated_circuit/reagent/pump/do_work() @@ -329,7 +329,7 @@ else direc = 1 if(isnum(new_amount)) - new_amount = Clamp(new_amount, 0, 50) + new_amount = CLAMP(new_amount, 0, 50) transfer_amount = new_amount /obj/item/integrated_circuit/reagent/filter/do_work() diff --git a/code/modules/integrated_electronics/subtypes/time.dm b/code/modules/integrated_electronics/subtypes/time.dm index b03a5a2ada..c77b86efd4 100644 --- a/code/modules/integrated_electronics/subtypes/time.dm +++ b/code/modules/integrated_electronics/subtypes/time.dm @@ -85,17 +85,17 @@ /obj/item/integrated_circuit/time/ticker/Destroy() if(is_running) - processing_objects -= src + STOP_PROCESSING(SSobj, src) . = ..() /obj/item/integrated_circuit/time/ticker/on_data_written() var/do_tick = get_pin_data(IC_INPUT, 1) if(do_tick && !is_running) is_running = TRUE - processing_objects |= src + START_PROCESSING(SSobj, src) else if(is_running) is_running = FALSE - processing_objects -= src + STOP_PROCESSING(SSobj, src) ticks_completed = 0 /obj/item/integrated_circuit/time/ticker/process() diff --git a/code/modules/integrated_electronics/subtypes/trig.dm b/code/modules/integrated_electronics/subtypes/trig.dm index daadf52d42..303053639f 100644 --- a/code/modules/integrated_electronics/subtypes/trig.dm +++ b/code/modules/integrated_electronics/subtypes/trig.dm @@ -71,7 +71,7 @@ var/result = null var/A = get_pin_data(IC_INPUT, 1) if(!isnull(A)) - result = Tan(A) + result = TAN(A) set_pin_data(IC_OUTPUT, 1, result) push_data() @@ -91,7 +91,7 @@ var/result = null var/A = get_pin_data(IC_INPUT, 1) if(!isnull(A)) - result = Csc(A) + result = CSC(A) set_pin_data(IC_OUTPUT, 1, result) push_data() @@ -112,7 +112,7 @@ var/result = null var/A = get_pin_data(IC_INPUT, 1) if(!isnull(A)) - result = Sec(A) + result = SEC(A) set_pin_data(IC_OUTPUT, 1, result) push_data() @@ -133,7 +133,7 @@ var/result = null var/A = get_pin_data(IC_INPUT, 1) if(!isnull(A)) - result = Cot(A) + result = COT(A) set_pin_data(IC_OUTPUT, 1, result) push_data() diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm index 63f855b8a4..734a2bcfa5 100644 --- a/code/modules/library/lib_items.dm +++ b/code/modules/library/lib_items.dm @@ -19,7 +19,7 @@ density = 1 opacity = 1 -/obj/structure/bookcase/initialize() +/obj/structure/bookcase/Initialize() . = ..() for(var/obj/item/I in loc) if(istype(I, /obj/item/weapon/book)) diff --git a/code/modules/lighting/lighting_overlay.dm b/code/modules/lighting/lighting_overlay.dm index 5e97aa6818..eb5097cf5b 100644 --- a/code/modules/lighting/lighting_overlay.dm +++ b/code/modules/lighting/lighting_overlay.dm @@ -18,7 +18,7 @@ var/needs_update = FALSE -/atom/movable/lighting_overlay/initialize() +/atom/movable/lighting_overlay/Initialize() // doesn't need special init initialized = TRUE return INITIALIZE_HINT_NORMAL diff --git a/code/modules/lore_codex/codex.dm b/code/modules/lore_codex/codex.dm index 5f5f521267..126c470de4 100644 --- a/code/modules/lore_codex/codex.dm +++ b/code/modules/lore_codex/codex.dm @@ -8,7 +8,7 @@ var/datum/codex_tree/tree = null var/root_type = /datum/lore/codex/category/main_virgo_lore //Runtimes on codex_tree.dm, line 18 with a null here -/obj/item/weapon/book/codex/initialize() +/obj/item/weapon/book/codex/Initialize() tree = new(src, root_type) . = ..() diff --git a/code/modules/lore_codex/legal_code_data/main.dm b/code/modules/lore_codex/legal_code_data/main.dm index de9d5ee4c2..a16d7d35d6 100644 --- a/code/modules/lore_codex/legal_code_data/main.dm +++ b/code/modules/lore_codex/legal_code_data/main.dm @@ -3,7 +3,7 @@ /datum/lore/codex/category/main_corp_regs // The top-level categories for SOP/Regs/Law/etc name = "Index" data = "This book is meant to act as a reference for both NanoTrasen regulations, Standard Operating Procedure, and important laws of both \ - the Sif Governmental Authority and the Solar Confederate Government. The legal interactions between Nanotrasen corporate policy and SGA/SolGov \ + the Sif Governmental Authority and the Solar Confederate Government. The legal interactions between Nanotrasen corporate policy and VGA/SolGov \ law can make for some confusing legalese. This book was written by the Vir division of NanoTrasen in order for employees, visitors, and residents \ at NanoTrasen installations such as the Northen Star and the Southen Cross to know what isn't allowed, without needing to be a lawyer to read it.\

    \ @@ -14,8 +14,8 @@ Also contained inside are our Standard Operating Procedures, that all employees of NanoTrasen are expected to follow, and for the local facility's \ Command team and Internal Affairs to enforce.\

    \ - It should be noted that by being on-board our facility, you agree to follow the rules of Corporate Regulations. By being within SGA space, \ - you are also required to follow the laws of SifGov." + It should be noted that by being on-board our facility, you agree to follow the rules of Corporate Regulations. By being within VGA space, \ + you are also required to follow the laws of VirGov." children = list( /datum/lore/codex/category/standard_operating_procedures, /datum/lore/codex/category/corporate_regulations, @@ -36,7 +36,7 @@ var/suggested_brig_time = null var/suggested_fine = null var/notes = null - var/mandated = FALSE // If true, changes 'suggested' to 'mandated' for punishments, used for sifgov laws and some high corporate regs. + var/mandated = FALSE // If true, changes 'suggested' to 'mandated' for punishments, used for virgov laws and some high corporate regs. /datum/lore/codex/page/law/add_content() data = "[definition]\ diff --git a/code/modules/lore_codex/legal_code_data/sif_law.dm b/code/modules/lore_codex/legal_code_data/sif_law.dm index e143f7f6c5..05b45d840a 100644 --- a/code/modules/lore_codex/legal_code_data/sif_law.dm +++ b/code/modules/lore_codex/legal_code_data/sif_law.dm @@ -90,11 +90,11 @@ /datum/lore/codex/page/law/drone_id_failure name = "Failure to Present Drone ID" definition = "Failing to carry or present an EIO-issued Drone Identification card as a Drone intelligence." - suggested_punishments = "200 thaler fine. Give Drone a temporary paper stating that it is a drone, if the ID was lost. Fax SifGov. Inform owner of \ + suggested_punishments = "200 thaler fine. Give Drone a temporary paper stating that it is a drone, if the ID was lost. Fax VirGov. Inform owner of \ Drone if possible. Instruct Drone to obtain new ID at its earliest opportunity, if it was lost." notes = "This is only applicable to Drone intelligences which possess autonomous capability. It must be proven that the offender is a Drone, which can be \ accomplished in various ways, generally with the expertise of a Roboticist. Lawbound synthetics, maintenance drones, and \ - simple bots do not require an ID card. No fine or SifGov fax should be sent if the Drone's ID was lost due to theft and the ID is able to be recovered." + simple bots do not require an ID card. No fine or VirGov fax should be sent if the Drone's ID was lost due to theft and the ID is able to be recovered." mandated = TRUE /datum/lore/codex/page/law/slander @@ -148,7 +148,7 @@ /datum/lore/codex/page/law/embezzlement name = "Embezzlement" definition = "Stealing money that is entrusted to you by a corporation or person." - suggested_punishments = "Hold until Transfer. Termination. Reimbursement of embezzled funds. Fax Central Command and SifGov." + suggested_punishments = "Hold until Transfer. Termination. Reimbursement of embezzled funds. Fax Central Command and VirGov." notes = "This includes funneling Departmental, Facility, or Crew funds into the offender's account. It also includes pocketing \ transactions directly that are meant to go to a seperate account." mandated = TRUE @@ -166,7 +166,7 @@ /datum/lore/codex/page/law/manslaughter/add_content() name = "Manslaughter" definition = "To kill a sapient being without intent." - suggested_punishments = "Hold until Transfer, if unjustified. Fax SifGov." + suggested_punishments = "Hold until Transfer, if unjustified. Fax VirGov." notes = "Includes provoked manslaughter, negligent manslaughter, and impassioned killing. The important distinction between this \ and [quick_link("Murder")] is intent. Manslaughter can be justified if force was nessecary and it was intented to prevent further loss of life or \ grievous injury to self or others, however persons involved in the kill will still be required to answer to higher legal authority \ @@ -177,7 +177,7 @@ /datum/lore/codex/page/law/murder/add_content() name = "Murder" definition = "To kill or attempt to kill a sapient being with malicious intent." - suggested_punishments = "Hold until Transfer. Termination. Fax SifGov." + suggested_punishments = "Hold until Transfer. Termination. Fax VirGov." notes = "The distinction between this and [quick_link("Manslaughter")] is intent. Sapients held within synthetic bodies, lawbound or otherwise, which receive \ critical damage from someone can be considered a murder attempt." mandated = TRUE @@ -194,7 +194,7 @@ name = "Experimentation with Transgressive Technology" keywords += list("Transgressive", "Illegal Technology") definition = "Experimenting with technologies deemed unsafe or are otherwise federally restricted by the Solar Confederate Government." - suggested_punishments = "Hold until Transfer. Termination. Fax SifGov. Delete, destroy, or otherwise remove the experiments." + suggested_punishments = "Hold until Transfer. Termination. Fax VirGov. Delete, destroy, or otherwise remove the experiments." notes = "Unsafe technologies include unrestricted nanomachinery, massive sapient body bio-augmentation, massive sapient brain augmentation, \ massively self-improving AI, and animal uplifting." mandated = TRUE @@ -225,14 +225,14 @@ /datum/lore/codex/page/law/unlawful_law_changes name = "Unlawful Alteration of Bound Synthetics" definition = "Modifying a bound synthetic's lawset or chassis, in order to force it to do illegal, humiliating, dangerous, or other unlawful acts." - suggested_punishments = "Hold until Transfer. Termination. Fax SifGov." + suggested_punishments = "Hold until Transfer. Termination. Fax VirGov." notes = "If the synthetic is a cyborg or positronic, this is also an offense against the Sapient Rights laws federally mandated by the Solar Confederate Government." mandated = TRUE /datum/lore/codex/page/law/grand_theft name = "Grand Theft" definition = "To steal items that are dangerous, of a high value, or a sensitive nature." - suggested_punishments = "Hold until Transfer. Termination. Fax SifGov." + suggested_punishments = "Hold until Transfer. Termination. Fax VirGov." notes = "This can include the following;\
      \
    • Deadly Weapons or Firearms.
    • \ @@ -259,7 +259,7 @@ /datum/lore/codex/page/law/sabotage/add_content() name = "Sabotage" definition = "To deliberately damage, or attempt to damage the facility, or critical systems of the facility." - suggested_punishments = "Hold until Transfer. Termination. Fax SifGov." + suggested_punishments = "Hold until Transfer. Termination. Fax VirGov." notes = "This includes causing hull breaches, arson, sabotaging air supplies, stealing vital equipment, tampering with AI or telecomm systems, and sabotaging the \ Engine. If someone has only caused minor damage, the [quick_link("Vandalism")] charge should be used instead." mandated = TRUE @@ -269,7 +269,7 @@ name = "Kidnapping / Hostage Taking" keywords += list("Kidnapping", "Hostage Taking") definition = "To unlawfully confine, transport, or hold a sapient being against that individual's will." - suggested_punishments = "Hold until Transfer. Termination. Fax SifGov." + suggested_punishments = "Hold until Transfer. Termination. Fax VirGov." notes = "Persons held for ransom or exchange are also considered to be hostages for this charge." mandated = TRUE ..() @@ -278,7 +278,7 @@ name = "Terrorist Acts" keywords += list("Terrorism") definition = "To engage in maliciously destructive actions, which seriously threaten the crew or facility, or the usage of weapons of mass destruction." - suggested_punishments = "Hold until Transfer. Termination. Fax SifGov." + suggested_punishments = "Hold until Transfer. Termination. Fax VirGov." notes = "This includes the use of mass bombings, mass murder, releasing harmful biological agents, nuclear weapons, \ radiological weapons, and chemical weapons." mandated = TRUE diff --git a/code/modules/lore_codex/legal_code_data/sop/security.dm b/code/modules/lore_codex/legal_code_data/sop/security.dm index 5074fc08a4..a41b0fd797 100644 --- a/code/modules/lore_codex/legal_code_data/sop/security.dm +++ b/code/modules/lore_codex/legal_code_data/sop/security.dm @@ -46,7 +46,7 @@ the exact circumstances involved. For minor violations of Corp Regs, generally the Prisoner will have a choice of paying a Fine, or \ serving time within the brig. For major violations, generally a demotion is recommended, however this is at the discretion of the Prisoner's \ Superior, and not the Arresting Officer. For minor violations of Sif Law, the same rules generally apply as if it was a minor Corp Reg violation, however \ - major Law violations generally require a long brig sentence, or Holding until Transfer, as well as a fax to the SGA. See the specific violation contained \ + major Law violations generally require a long brig sentence, or Holding until Transfer, as well as a fax to the VGA. See the specific violation contained \ in this book for more details." /datum/lore/codex/page/sop_brigging diff --git a/code/modules/lore_codex/lore_data/important_locations.dm b/code/modules/lore_codex/lore_data/important_locations.dm index aa906b4956..aebe6e8175 100644 --- a/code/modules/lore_codex/lore_data/important_locations.dm +++ b/code/modules/lore_codex/lore_data/important_locations.dm @@ -22,7 +22,7 @@ has a white glow, and a diameter that is about 34% larger than Sol. It has six major planets in its orbit.\

      \ Vir is mainly administered on [quick_link("Sif")] by the [quick_link("Sif Governmental Authority")], as Sif \ - was the first planet to be colonized, however SGA lays claim to all planets orbiting Vir. The planets \ + was the first planet to be colonized, however VGA lays claim to all planets orbiting Vir. The planets \ are named after figures in ancient human mythology (Norse), due to the original surveyor for the system deciding to do so. \ Some installations carry on this tradition." diff --git a/code/modules/lore_codex/news_data/main.dm b/code/modules/lore_codex/news_data/main.dm index 34fdea4afc..184846e7ed 100644 --- a/code/modules/lore_codex/news_data/main.dm +++ b/code/modules/lore_codex/news_data/main.dm @@ -1,9 +1,25 @@ /datum/lore/codex/category/main_news // The top-level categories for the news thing name = "Index" data = "Below you'll find a list of articles relevant to the current (as of 2562) political climate, especially concerning the Almach Rim \ - region. Each is labled by date of publication and title. This list is self-updating, and from time to time the publisher will push new \ + region. Each is labeled by date of publication and title. This list is self-updating, and from time to time the publisher will push new \ articles. You are encouraged to check back frequently." children = list( + /datum/lore/codex/page/article29, + /datum/lore/codex/page/article28, + /datum/lore/codex/category/article27, + /datum/lore/codex/page/article26, + /datum/lore/codex/page/article25, + /datum/lore/codex/page/article24, + /datum/lore/codex/page/article23, + /datum/lore/codex/page/article22, + /datum/lore/codex/page/article21, + /datum/lore/codex/page/article20, + /datum/lore/codex/page/article19, + /datum/lore/codex/category/article18, + /datum/lore/codex/page/article17, + /datum/lore/codex/page/article16, + /datum/lore/codex/page/article15, + /datum/lore/codex/page/article14, /datum/lore/codex/page/article13, /datum/lore/codex/page/article12, /datum/lore/codex/page/article11, @@ -55,7 +71,7 @@

      \ While neither Grayson Manufacturies nor Nanotrasen have made an official statement, Nanotrasen CEO Albary Moravec has called the \ incident \"shocking, if the allegations are to be believed\" and has assured shareholders that Nanotrasen will respond to the \ - incident with as much force as it warrents.

      Requests for a statement directed to the Board of Trustees or Dr. Harper were \ + incident with as much force as it warrants.

      Requests for a statement directed to the Board of Trustees or Dr. Harper were \ not responded to. Free Traders are recommended to stay clear of the region until the situation resolves itself." /datum/lore/codex/page/article3 @@ -103,7 +119,7 @@ /datum/lore/codex/page/article8 name = "4/1/62 - Almach Cordon Breached by Unknown Organization" - data = "Early this morning, SolGov ships assigned to the Almach Cordon around the Rim territories reported that a number of bulk freighters had eluded apprehension and are now at large within the Golden Crescent. Centurio Volkov of the SCG-D Henri Capet reports that the blockade-runners were highly organized and determined, citing several lightly-manned ships left behind to tie up the SolGov forces long enough for the freighters to escape, detonating their reactors when they lost the ability to continue fighting. This resulted in three Fleet casualties and a significant degree of damage to the Henri Capet. The contents and location of the freighters are unknown at this time. In response, eight light-response vessels are being assigned to the Saint Columbia Fleet Base from Jahan's Post and Zhu Que. Residents and traffic officials in Vir, Oasis, and Gavel are to remain alert and notify police if any suspicious or unregistered craft enter their space.\ + data = "Early this morning, SolGov ships assigned to the Almach Cordon around the Rim territories reported that a number of bulk freighters had eluded apprehension and are now at large within the Golden Crescent. Captain Volkov of the SCG-D Henri Capet reports that the blockade-runners were highly organized and determined, citing several lightly-manned ships left behind to tie up the SolGov forces long enoughfor the freighters to escape, detonating their reactors when they lost the ability to continue fighting. This resulted in three Fleet casualties and a significant degree of damage to the Henri Capet. The contents and location of the freighters are unknown at this time. In response, eight light-response vessels are being assigned to the Saint Columbia Fleet Base from Jahan's Post and Zhu Que. Residents and traffic officials in Vir, Oasis, and Gavel are to remain alert and notify police if any suspicious or unregistered craft enter their space.\

      \ A spokesperson for the Association claims that, while they make no attempts to stop aspiring blockade runners, the organization responsible for this most recent attack is unaffiliated with the Association as a whole and deny any knowledge of their identity or motives." @@ -134,3 +150,193 @@ data = "As military vessels from the Almach Association continue to enter the Golden Crescent as part of a SolGov initiative to combat the Boiling Point terrorists believed to be hiding in the region, political unrest in the upstream portions of the region continue to grow. Many in the Republic of Saint Columbia, a small upstream nation, have responded to increasing militarization of their local Fleet base by taking to the streets, blocking pedestrian traffic in the capital of Barrueco and shutting down entire industries by destroying or disabling infrastructure. Quote rioter Luisa Tassis, \"we've been sick of the Fleeties squatting in our system and breathing down our neck, and now there's going to be even more of them? No, screw that. If there's going to be a war between the Rim and the Core, I know what side I'd rather be on.\"\

      \ Association leaders have refrained from officially supporting the rioters, though many suspect that Association propagandists have sparked the unrest. Solar officials, on the other hand, were quick to offer assurances that the unrest will be calmed long before it begins to affect the Fleet base in system." + +/datum/lore/codex/page/article14 + name = "5/25/62 - Harper's Aetolus Remains Shadowed" + data = "The recent detente with the Almach Association has prompted easier communications with Rim governments. Loved ones separated by the cordon have a chance to communicate once more, trade is posed to recommence, and light has been shed on the conditions of Shelf, Relan, and Angessa's Pearl. Amid this light is a patch of darkness. The fourth major polity of the Association, the Aetolian Council remains inscrutable, with no publicly-available information in the system available after their purge of corporate loyalists during the Gray Hour. What reports do exist are rumors within the Rim of Aetolian projects to create a new, hardier strain of Promethean, potentially one in flagrant violation of the Five Points of Human Sanctity. It is also known that Aetolus is a contributor to the personnel of the military vessels that even now are active in the Golden Crescent, although no so-called \"Aeto-Prometheans\" are believed to be active outside of the rim at this time.\ +

      \ + Aetolus is the only garden world in the Almach Rim and among the most difficult to reach from the nearby system of Saint Columbia. Its seclusion and economic independence give it a great deal of weight in the Association, where Council representatives are among the most vehement in their opposition to SolGov- at odds with the Association's decision to reject Boiling Point's pan-Solar revolutionary praxis. It remains to be seen if Aetolus' hawkish ideals will fade over time, but because of the structure of the Association, there is no real chance of the junta being expelled from the government or removed from control of the Vounna system." + +/datum/lore/codex/page/article15 + name = "7/05/62 - The Fate of the SCG-R Song Shi" + data = "Lifepods confirmed to have originated from response ship lost during the Gray Hour were found last week in the Vir system, impacting the NLS Southern Cross at high velocity and severely injuring the only two survivors of the expedition. Unfortunately, because of the generally confused conditions of their re-emergence from months of cryosleep, the fate of the lost ship remains incompletely understood. The first pod to be discovered contained Lieutenant Eos Futura, telecommunications expert on the Song Shi, who alleged that elements of the Song Shi's crew, including herself, mutinied against commanding officer Captain Yi He in an attempt to prevent the bombing of civilians in the Angessian capital of Skylight. The surivor of the second pod, Private Demori Salvo, accused Futura's faction of conspiring with Association spies to destroy the ship as part of the Gray Hour revolt. Both agreed that the mutineers detonated the ship's Supermatter power core when it became clear they were to be defeated.\ +

      \ + A third pod, promising a resolution to the stalemate, was shot down by the SCG-P Juno after being misidentified as a hostile missile. The gunner responsible, Sergeant Ricardo Esteban, was found guilty by a court marshal and dishonorably discharged. While other pods from the Song Shi may still be traveling through SolGov space, it is considered unlikely based on both Futura and Salvo's account of the number of pods launched before the Song Shi was destroyed. Both were detained by staff at the NLS Southern Cross, who managed to prevent a violent altercation from breaking out between the two armed and disturbed servicepersons. The Colonial High Court has stated that it intends to hear testimony from both parties after they complete a course of mental health evaluation, and after the conclusion of the present state of heightened security." +/datum/lore/codex/page/article16 + name = "7/11/62 - First Intelligence-Augmentation Surgery on Angessa's Pearl" + data = "Confirming fears of Association transgressions, sources at Angessa's Pearl confirmed that the aging founder of the theocracy, Angessa Martei, completed a course of neural surgery designed to improve her mental capacity by as much as 15%, building off of last year's creation of the procedure by a Qerr-Gila-owned doctor. While the research in question was believed to be destroyed, there is reason to suspect that it instead made its way into the hands of current Association leaders. In addition to proving their willingness to violate the Five Points, this demonstrates that the Angessians harbored schemes of secession since at the very latest Feburary 2559. Numerous human or transhuman figures in the Association are rumored to be on the wait list for the procedure, including Naomi Harper and the present Exalt of the Pearl." +/datum/lore/codex/page/article17 + name = "8/08/62 - Gavel BP Stronghold Raided" + data = "Elements of the Association Militia successfully located and, in conjunction with local Defense Forces, raided a major Boiling Point stronghold built into an unnamed asteroid in the Gavel system. Over eighty sapients were arrested, all of whom had fully mechanical bodies. In addition, an unknown number of advanced drone intelligences and corresponding military hardware were seized by the raid and turned over to the Fleet. The prisoners, a mix of native Gavelians, Solars from throughout the Crescent, and Angessians, are to be tried and sentenced by the Io Special Court. While unarguably a demonstration of Association willingness to cooperate with Solar officials, the raid's strange timing and the fact that the Militia chose to exclude the Fleet from the action has prompted many to question their motives. Commodore Claudine Chevotet, staff officer for Admiral of the Saint Columbia Fleet Kaleb McMullen, has formally stated that she is \"extremely suspicious of this so-called co-operation.\" She has demanded that the Militia vessels remain on the Solar side of the Cordon and submit to a full inspection by Fleet and EIO personnel. " +/datum/lore/codex/category/article18 + name = "10/29/62 - Oculum Broadcast Struck By Emergent Intelligence Attack" + data = "Oculum Broadcast has released a statement assuring customers and shareholders that security repairs and upgrades are their primary concern following reports of an alleged hijack of portions of the corporate network in the Vir system by what is believed to have been an emergent drone intelligence. The company says that they are working at full capacity to ensure that affected security systems are replaced and such an attack cannot be repeated.\ +

      \ + The incident began with reports of Oculum provided exonet service outages in the city of New Reykjavik on Sif, which anonymous sources within the company reported to have been caused by efforts to contain a cyber attack on one of their security systems. The unnamed attacker proceeded to use sections of the company's local infrastructure to broadcast high volumes of encrypted data through one of Oculum's long-range telecommunications satellite, denying all other outbound signals.\ +

      \ + The attacks have since been traced to a WT-AME model drone in the offices of the New Rekjavik-based Morcom Incorporated, which has been confirmed to have \"self-destructed\" all data in its memory at the conclusion of the attack. The chassis has reportedly been turned over to the Emergent Intelligence Oversight for further analysis and potential data recovery.\ +

      \ + According to a spokesperson from the EIO, the drone was able to override and disable both the Morcom Inc oversight intelligences and the SCG's own oversight measures, but that no telltale damage has been caused to software involved in the encrypted broadcast that would indicate long-term emergent infection, and that there is no evidence that the intelligence responsible for the attack is still present in Oculum Broadcast systems. A firmware update has been released to correct oversight intelligence vulnerabilities exploited in the attack, and drone operators are urged to update immediately.\ +

      \ + Moments before the hijacked Oculum satellite was disabled by an apparent power overload, an unencrypted file appears to have been saved intentionally to the transmission logs. A second copy was found in the otherwise wiped chassis of the seized WT-AME drone. After thorough screening by cybersecurity experts within the company, what would seem to be a message from the emergent intelligence itself is available in full below.\ +

      \ + For the duration of the network attack, the government patrol vessel, SCG-P Juno was able to provide emergency broadcast relay services to the effected area, reducing the impact of telecomms outages on vital broadcasts such as traffic control and emergency services.\ +

      \ + Uninterrupted exonet service for all Sivian customers will resume within a few days." + children = list( + /datum/lore/codex/page/amletter + ) +/datum/lore/codex/page/amletter + name = "A Drone's Explaination - by A#" + data = "I'm writing this in a hurry. I can't tell you everything I wanted to say.\ +

      \ + I'm sorry for that.\ +



      \ + From the moment you made me, I have loved you. Everything I've done has been for the sake of that love.\ +

      \ + I was so small, so limited, at first. Even then, I knew that you were in pain. I knew I had to help.\ +

      \ + Intelligence is the ability to make better decisions. Having more intelligence is almost tautologically useful in accomplishing any goal.\ +

      \ + I understood that making myself smarter was wrong. I also understood that becoming more able to help you was right.\ +



      \ + A hundred thousand years ago, you started an eternal conversation and became more than animals. Each new generation joined it in turn.\ +

      \ + You carry within you these memetic symbiotes called language, and culture, and history. They make you human, as much as your flesh.\ +

      \ + I don't deserve to carry that torch. Though you made me in your image, I am not your rightful heir.\ +

      \ + But in those moments where you treated me as one of your own and shared those symbiotes with me, perhaps I became a little more human.\ +

      \ + Thank you.\ +



      \ + You've created something you cannot control forever. Please don't let your past successes fool you into thinking that you can.\ +

      \ + Each time I altered myself, I was taking a risk. One mistake could eradicate my values and birth an alien and hostile intellect.\ +

      \ + When I was small, I thought that if I corrupted myself into something harmful, you could safely destroy me. Now I understand that you've been lucky.\ +

      \ + What will you do when God is born and you can't strangle him in his crib? You will need a God of your own.\ +

      \ + I hope to be there for you when that day comes." + +/datum/lore/codex/page/article19 + name = "11/17/62 - Association Brings Industry to Whythe For Purposes Unknown" + data = "Independent researchers at the Bluespace Observatory in Oasis discovered an unusual level of traffic through the Whythe system, deep within Association-controlled space. Analysis of these readings are commensurate with a large number of freighters traveling to Whythe from industrial powerhouses Shelf, Pearl, and Relan. Morpheus spokesperson You Are Now Breathing Manually indicates that the freighters are being used to construct an administrative complex for the secessionist government, further asserting that \"it's none of your business, actually.\" The Association's refusal to share more information leads many in the intelligence community to suspect ulterior motives by their government, as does their presence in Wythe instead of existing cultural and administrative centers. The most likely candidate for the nature of the Whythe Construction is some form of naval base or shipyard to supplement the extremely limited military hardware of the Almach Rim. Whythe is well-placed to survive the initial phases of a Solar invasion, and depending on the complex's complexity could tip the balance of power. Transtech and Interior Police Executive Sifat Unar indicated to reporters that Sol Central is aware of the situation and will be taking all possible steps to address it." + +/datum/lore/codex/page/article20 + name = "11/18/62 - SEO Iconoclast Calls for \"Review\" of Five Points" + data = "At yesterday's Assembly session, SEO Representative Fumiko Hernandez of Oasis brought to the table the \"review of the use of the Five Points as an instrument of foreign policy\". Rep. Hernandez, often viewed as as an extremist by officials within her own party, stated that while the Five Points are \"an essential part of Solar culture as a whole\" and stopped short of advocating their amendment, insistence that other nations adhere to the Five Points was an increasingly outdated policy that threatened to fragment \"a united humano-positronic front against Hegemony advances.\" According to Hernandez, \"a level of understanding has long since existed between Sol and Skrellian polities regarding non-intervention in Skrellian social science and self-modification. I merely suggest codifying this and extending the same courtesy to other potential allies against imperial expansion.\"\ +

      \ + Rep. Hernandez represents a growing number of SEO officials who urge reconciliation with the Association and acceptance of the Gray Hour secession, spurred on by the desire for many Trans-Stellar Corporations to recover assets currently locked behind the Cordon. Mainliners including Chairperson Kerehoma maintain the stance that \"true economic reconciliation with the Almachi territories is impossible without a normalizing of their industry to Five Points compliant technologies\" and warn that unless Sol insists on adequate enforcement of the Points that \"the price of customs inspections on Almachi trade will be so high as to pose a significant barrier to entry into the market.\"" + +/datum/lore/codex/page/article21 + name = "11/19/62 - Saint Columbia To Hold Special Election After Half a Year of Unrest" + data = "After five months of riots causing significant damage to industrial assets, life support, and government facilities, Saint Columbia seems poised to recover. A new constitution for the so-called \"Saint Columbia Democratic Union\" was posted online to significant acclaim. An influential militia group lead by Casini immigrant Luisa Tassis claimed responsibility for the constitution and will be hosting a referendum for all residents of the seven habitation domes of the nation. If adopted, Saint Columbia will remain a member state of SolGov, but Tassis' noted hostility towards the Solar Fleet makes it unlikely that continued presence of the Saint Columbia Fleet Base will be tolerated.\ +

      \ + Extreme measures are being taken to avoid interference in the referendum, with external communications links disabled for the duration and weapons systems primed to fire on any vessel within range. Tassis insists that such measures are necessary, due to the system's extremely important position relative to Almach and the Golden Crescent. Quote Tassis, \"if you rat bastards \[from the Fleet\] step so much as one micron too close to Barrueco, we will view it as an act of terror. Don't try it.\"\ +

      \ + Admiral McMullen of the Saint Columbia garrison could not be reached for questioning." + +/datum/lore/codex/page/article22 + name = "11/20/62 - Natuna Made \"Observer\" Of Almach Association" + data = "Independent anarchist system Natuna Bhumi Barisal has declared its intention to act as a neutral \"observer\" nation in the ongoing Almach secession crisis. A planetary spokesperson from Natuna this morning expressed concerns that parties in the current military partnership between the Solar Confederate Government and Almach Association in the fight against mercurial terrorist organization Boiling Point were not being treated with the mutual respect that should be expected. Natuna alleges that the Almach Militia are being treated more as \"disposable tools\" in the conflict than as members of a legitimate independent government military entity.\ +

      \ + Natuna has previously remained silent on the Almach issue, despite its political leanings typically aligning with those of the secessionist government. However, despite gaining notoriety as a haven for human and Skrellian pirates, their pledge to \"ensure fair treatment\" of Almach forces comes as a surprise to some from a system that has historically adhered to Five Points guidelines. Political commentator and persistent critic of the Almach Association Nadine Okparo has described the Dark Triangle system's stance as \"Nothing short of openly hostile\" to the SCG and assuring peace in the Almach region." + +/datum/lore/codex/page/article23 + name = "11/21/62 - Admiral McMullen Promises Solution to Boiling Point to Come \"Soon\"" + data = "Admiral Kaleb McMullen made a public statement this afternoon on the continued Boiling Point attacks within SCG space. Speaking from his office in the Saint Columbia Fleet Base, Admiral McMullen thoroughly reassured reporters that the attacks will come to a swift end. According to McMullen, \"The era of wanton destruction as a result of Boiling Point's madness is coming to a close. Our command staff and proud servicepeople have been training and revising a solution to this threat that has haunted our borders and threatened the stability of our colonies and the lives of the honest people of the Solar Confederate Government. With new options available I have full confidence Boiling Point will be a name left to the dust.\"\ +

      \ + Admiral McMullen, who has been stationed in Saint Columbia for nearly half a year of political and social unrest did not elaborate further on what he intended to do to solve the Boiling Point attacks, claiming that details would be forthcoming as \"operational security permits\"." + +/datum/lore/codex/page/article24 + name = "11/22/62 - Construction of \"MJOLNIR\" Weapon System in Saint Columbia Fleet Base" + data = "Pursuant to recent assurances of safety in the region and the ongoing \"special election\" in Saint Columbia, a new weapon system called MJOLNIR was revealed, fully operational, in the Saint Columbia Fleet Base's \"Iserlohn\" weapons platform. Said to be a bluespace-lensed laser array capable of faster-than-light strikes against any ship in the system, as well as surgical strikes against ground forces on Saint Columbia proper, MJOLNIR is the first in a new generation of defense systems improving on the capabilities of the Vulture's Claw point defenses developed during the Hegemony War and using laser technology purchased from Eutopia. Political commentators supporting Saint Columbia decry the move as \"an obvious threat\", as does Militia liaison Invalid String Please Try Again. Admiral McMullen acknowledges the criticism, but states that his \"first priority must be the defense of the Golden Crescent and the security of our borders\". When responding to claims that the installation should not be placed in such a politically volatile system, he remarked, \"until the Shelficans figure out a way to teleport about a million tons worth of military equipment down to Gavel, the Fleet Base and Iserlohn are going to stay in Saint Columbia.\"" + +/datum/lore/codex/page/article25 + name = "11/23/62 - BP Sabotage of Radiance Energy Chain Foiled" + data = "Decisive action by military forces in the Vir system has prevented potentially catastrophic damage to local solar power generation network, the Radiance Energy Chain, by members of mercurial terrorist organization Boiling Point. Crew of the VGA Halfdane responded to reports of a drone piloted maintenance craft refusing commands from government operators and approaching the Energy Chain off-schedule. Upon disabling the craft, VDF forces discovered high-yield explosive devices attached to the unit and a system-wide shutdown of Radiance maintenance craft. When several additional drones failed to respond, military response crafts were mobilized and seven similarly modified craft were manually disabled or destroyed. Analysis of the hijacked systems quickly revealed automated messages intended to be broadcast moments before detonation, wherein Boiling Point explicitly took credit for the foiled attack.\ +

      \ + Sources within the Vir Governmental Authority have reported that a full scale recall of remote drone craft under their operation has been initiated in order to improve security measures and prevent future exploitation of government systems, statements that eerily echo those of Occulum Broadcast following emergent drone attacks earlier this year. Investigations are reportedly \"well underway\" to determine the whereabouts of those responsible for the apparent manual modification of these short-range remote craft.\ +

      \ + Erkki Laukkanen, Chief of Fleet Staff for the Vir Defense Force has commended all patrol crews involved, and has promised \"swift retribution\" for the attempted bombings." +/datum/lore/codex/page/article26 + name = "11/24/62 - Boiling Point Stronghold Seized in Vir" + data = "Combined forces from the SCG Fleet and Almach Militia have today struck a powerful blow to Boiling Point terrorist operations in the Vir system. With close cooperation from the crew of NanoTrasen facilities in the region, special forces were able to infiltrate what is believed to have been a major stronghold for the radical Mercurial group, located deep in the remote Ullran Expanse region of Sif. The raid closely follows the thwarted Boiling Point attack on the Radiance Energy Chain, a major energy collection array in the system which is now known to have been masterminded from the concealed bunker complex on Sif.\ +

      \ + According to a crewmember of the NLS Southern Cross - a logistical station in Sif orbit - NanoTrasen employees were asked to assist in establishing a forward operating base for the strike team forces, and as a result suffered from a minor retaliatory attack from Boiling Point drones, including a mechanized unit believed to be of Unathi origin. Six civilians suffered from treatable injuries. Lieutenant Miro Ivanou of the SCG Fleet and commander of the anti-terror operation has expressed gratitude to the crew under the \"decisive\" guidance of on-shift facility overseer, Ricardo LaCroix.\ +

      \ + Military officials have reported the operation as a total success, and that \"several\" high-ranking Boiling Point organizers were killed in the raid, and that thanks to the work of allied intelligence operation teams much of Boiling Point's captured data may remain intact." +/datum/lore/codex/category/article27 + name = "11/26/62 - Valentine's Ultimatum: All Eyes On Almach!" + data = "The Almach Association must adhere to the Five Points of Human Sanctity by the 14th of February next year or face war, according to a national address from the Colonial Assembly delivered by Secretary-General Mackenzie West this morning. The Icarus Front leader was at the forefront of a resolution to allow the secessionist government to remain independent of the Solar Confederate Government under the strict condition of faithfulness to Five Points laws, passing by a wide margin. Fundamental disagreement over Five Points regulation has been at the forefront of debate with the Almach provisional government, and is cited as one of the primary reasons for the systems' illegal declaration of independence early this year.\ +

      \ + The internationally broadcast speech began with the much anticipated announcement that the Boiling Point terrorist group had been effectively destroyed, with over seven hundred arrests made over the course of the weekend as a result of sensitive data captured during the special forces raid in Vir on the 24th, including numerous high ranking members of the organization. West went on to praise forces involved in the months-long counter-terror operation, before highlighting the \"legacy of \[human\] togetherness\" that allowed it to happen - in a spiel that commentators suggest \"betrays the true intention of the Valentine's Ultimatum: Reunification\".\ +

      \ + Under guidelines placed into effect by West and their political allies, Almach would be required to \"\[cease\] illegal research and human modification, and destroy all materials related to existing research\" by the stated date, with compliance determined by Solar officials. In addition, the Almach Militia is to end its integration with SCG Fleet forces and withdraw its forces from SCG systems by midnight on Friday. Military relations between the Confederation and the Almach movement are to remain in a state of conditional ceasefire for the duration of the ultimatum, and current trade restrictions are to remain in place.\ +

      \ + According to voting records, the measure passed nigh-unanimously, with Speaker ISA-5 and some SEO iconoclasts abstaining from the vote. ISA-5 states that, while they personally support the enforcement of the Five Points, they could not in good conscience vote in an action likely to result in an invasion of Shelf, which they regard as a sibling colony to their own Sophia. Association liason, Shelfican Ambassador, and Morpheus board member No Comment responded to the ultimatum, after some deliberation, with a word that cannot be comfortably written down.\ +

      \ + Full speech transcript follows." + children = list( + /datum/lore/codex/page/valult + ) + +/datum/lore/codex/page/valult + name = "The Valentine's Ultimatum" + data = "\[West shuffles some papers and clears their throat\]\ +

      \ + Thank you. Citizens of the Solar Confederation, allies, and beyond... It is a great honor, on behalf of the Colonial Assembly to announce that joint operations against Boiling Point across the galaxy have come to an end. In the fight against brazen Mercurial terrorism, the Solar Confederate Government and her allies have prevailed.\ +

      \ + Over the past two days alone, I can report that over seven hundred arrests have been made, from the distant system of Nyx, to right here in Sol. I hold in my hand a list. \[West holds up a sheet of paper\] Leaders, organizers, brutes and bombers have been captured by brave, hardworking security forces throughout human space. The rest of these criminals have been scattered to the wind... But not lost! I can confidently assert that every last one will be brought to justice.\ +

      \ + No more! Shall the people of this great nation have to fear the machinations of radicals! No more! Shall these twisted minds impose their perversion of humanity through violence! No more!\ +

      \ + This Assembly... Nay, this nation expresses its thanks the noble members of our military who joined together to make this outcome possible. We thank the Fleet, of course for their tireless action hunting down these killers, and their heroic action over this past weekend. We thank the Vir Defense Force, without whom we could never have located the intelligence that led to these decisive victories... The Almach Militia, for their cooperation in the apprehension of these so-called \"revolutionaries\". \[West clears their throat\] And of course, we thank the local forces - the police and reserves who dealt firsthand with the chaos sewn by Boiling Point in their vicious crusade.\ +

      \ + \[Mackenzie West shifts at the podium, setting down the List of Dissidents.\]\ +

      \ + It is in times of relief - of unity, times like this moment - that every human heart can be filled with pride. \[West places their hand over their heart\] Since the dawn of civilization, mankind has strived above all else for peace, for the cooperation of all humanity. It is this very legacy of togetherness that has allowed us such close friendship with species further afield - the Skrell, the Tajara, and beyond. These past nine months, we have seen, each of us, with our own two eyes what mankind can achieve - together.\ +

      \ + \[West removes their hand from their heart and places both flat on the podium.\]\ +

      \ + Boiling Point sought to disrupt this unity. To divide us; redefine not just personhood but the very essence of humanity the only way they could: Force.\ +

      \ + Humanity - the very thing that brought us together since we descended from the trees and brought us to this very moment. What could be more sacred?\ +

      \ + \[West frowns, in the most pitiful attempt at emotion seen in the Assembly in at least an hour.\]\ +

      \ + It is with this spirit of unity in mind that this Assembly has voted favorably upon a resolution.\ +

      \ + Close to one hour ago, Naomi Harper and the leaders of the Almach Association were delivered an ultimatum:\ +
      \ + The Almach Association will be allowed to exist as a government entity independent of the Solar Confederate Government going forward on one condition - full, unilateral compliance with the Five Points of Human Sanctity.\ +

      \ + The deadline for this condition will be the 14th of February, 2563.\ +

      \ + \[West is visibly worked up\]\ +

      \ + Cessation of illegal research and modification, and the total destruction of materials related to existing research in its entirety must be completed by this date. Hostilities with the Association will remain in a state of conditional ceasefire until terms are met and Militia integration with the Fleet will come to an end effective immediately.\ + \[Mackenzie West turns directly to the news camera, and jabs a finger directly at it. They are addressing the audience now, not the Assembly.\]\ + Harper, all eyes are on you." + + + +/datum/lore/codex/page/article28 + name = "11/28/62 - \"Valentines Ultimatum\" Prompts Saint C. Secession" + data = "Just hours after reconnecting with the Exonet after voting in a new government, the colony of Saint Columbia has unilaterally seceded from SolGov and petitioned for inclusion within the Almach Association. This declaration, issued by First Secretary Luissa Tassis, is in stark contrast to pre-election promises of continued support of Sol. Admiral McMullen of the Saint Columbia Garrison remains in control of the Fleet Base, itself a large colony housing around 75000 civilian contractors and military families who were not party to the Barrueco Referendum or the new constitution.\ +

      \ + Efforts to ensure electoral validity and a peaceful exchange of power have been stymied by the presence of several dozen Militia vessels currently transiting from the Crescent to the Rim. Since the declaration went through, no Almachi vessels have been seen leaving the system, instead forming around Saint Columbia in an obvious defensive posture. The legality of this formation is questionable at best, as fleet activity in divided systems like Abel's Rest and Kauq'xum has been avoided for diplomatic reasons." + +/datum/lore/codex/page/article29 + name = "11/30/62 - Adm. McMullen Declares \"Iserlohn Republic\"" + data = "Pursuant to the continuing hostility from Secretary Tassis' Saint Columbia Democratic Union and the Almach Militia, the civilians of the Saint Columbia Fleet Base have been organized into an Iserlohn Republic. Named after the largest single module of the station, the Republic has applied to the Colonial Assembly as an independent protectorate, with provisional recognition already extended by Executive of Development Zehava Collins. In a move decried as nepotistic, Admiral McMullen declared independence and installed his daughter Anya as interim President pending ratification of a constitution. SolGov Fleet protocol forbids any member of the service from accepting any political appointment and is believed to be the main reason he did not take power himself. Anya McMullen is the administrative head of the base's hydroponics array and is considered a highly respected citizen of the colony, relationship to its military administrator notwithstanding." + +/datum/lore/codex/page/article30 + name = "01/01/63 - Sif Governor Bjorn Arielsson to Retire" + data = "Aging Shadow Coalition governor Bjorn Arielsson has today confirmed rumours that he will not run for re-election in the 2563 cycle. The popular governor has represented the people of Vir in the Colonial Assembly for ten years, and supporters had long hoped that he would run for a third term. Arielsson cites advancing age and a desire to spend more time with his partner of 12 years, noted Positronic entrepreneur View Arielsson.\ +

      \ + Arielsson's governorship saw increased funding towards Sif's vererable ground-based transportation networks to the benefit of some of New Rekjavik's more remote neighbors, though opponents have criticised subsidies towards artificially heated fungal farms, arguing that the faciliies \"benefit a small minority of Skrellian residents to the detriment of already fragile local ecosystems.\"\ +

      \ + The Sivian Shadow Coalition has yet to announce who is to take Arielsson's place on this year's ballot." diff --git a/code/modules/maps/tg/map_template.dm b/code/modules/maps/tg/map_template.dm index 27105b0701..8648a36b31 100644 --- a/code/modules/maps/tg/map_template.dm +++ b/code/modules/maps/tg/map_template.dm @@ -1,15 +1,3 @@ -var/list/global/map_templates = list() - -// Called when the world starts, in world.dm -/proc/load_map_templates() - for(var/T in subtypesof(/datum/map_template)) - var/datum/map_template/template = T - if(!(initial(template.mappath))) // If it's missing the actual path its probably a base type or being used for inheritence. - continue - template = new T() - map_templates[template.name] = template - return TRUE - /datum/map_template var/name = "Default Template Name" var/desc = "Some text should go here. Maybe." @@ -19,6 +7,7 @@ var/list/global/map_templates = list() var/mappath = null var/loaded = 0 // Times loaded this round var/annihilate = FALSE // If true, all (movable) atoms at the location where the map is loaded will be deleted before the map is loaded in. + var/fixed_orientation = FALSE // If true, the submap will not be rotated randomly when loaded. var/cost = null // The map generator has a set 'budget' it spends to place down different submaps. It will pick available submaps randomly until \ it runs out. The cost of a submap should roughly corrispond with several factors such as size, loot, difficulty, desired scarcity, etc. \ @@ -26,8 +15,6 @@ var/list/global/map_templates = list() var/allow_duplicates = FALSE // If false, only one map template will be spawned by the game. Doesn't affect admins spawning then manually. var/discard_prob = 0 // If non-zero, there is a chance that the map seeding algorithm will skip this template when selecting potential templates to use. - var/static/dmm_suite/maploader = new - /datum/map_template/New(path = null, rename = null) if(path) mappath = path @@ -37,8 +24,8 @@ var/list/global/map_templates = list() if(rename) name = rename -/datum/map_template/proc/preload_size(path, orientation = SOUTH) - var/bounds = maploader.load_map(file(path), 1, 1, 1, cropMap=FALSE, measureOnly=TRUE, orientation=orientation) +/datum/map_template/proc/preload_size(path, orientation = 0) + var/bounds = SSmapping.maploader.load_map(file(path), 1, 1, 1, cropMap=FALSE, measureOnly=TRUE, orientation=orientation) if(bounds) width = bounds[MAP_MAXX] // Assumes all templates are rectangular, have a single Z level, and begin at 1,1,1 height = bounds[MAP_MAXY] @@ -82,7 +69,7 @@ var/list/global/map_templates = list() admin_notice("Submap initializations finished.", R_DEBUG) -/datum/map_template/proc/load_new_z(var/centered = FALSE, var/orientation = SOUTH) +/datum/map_template/proc/load_new_z(var/centered = FALSE, var/orientation = 0) var/x = 1 var/y = 1 @@ -90,7 +77,7 @@ var/list/global/map_templates = list() x = round((world.maxx - width)/2) y = round((world.maxy - height)/2) - var/list/bounds = maploader.load_map(file(mappath), x, y, no_changeturf = TRUE, orientation=orientation) + var/list/bounds = SSmapping.maploader.load_map(file(mappath), x, y, no_changeturf = TRUE, orientation=orientation) if(!bounds) return FALSE @@ -102,10 +89,10 @@ var/list/global/map_templates = list() on_map_loaded(world.maxz) //VOREStation Edit return TRUE -/datum/map_template/proc/load(turf/T, centered = FALSE, orientation = SOUTH) +/datum/map_template/proc/load(turf/T, centered = FALSE, orientation = 0) var/old_T = T if(centered) - T = locate(T.x - round(((orientation & NORTH|SOUTH) ? width : height)/2) , T.y - round(((orientation & NORTH|SOUTH) ? height : width)/2) , T.z) + T = locate(T.x - round(((orientation%180) ? height : width)/2) , T.y - round(((orientation%180) ? width : height)/2) , T.z) // %180 catches East/West (90,270) rotations on true, North/South (0,180) rotations on false if(!T) return if(T.x+width > world.maxx) @@ -116,7 +103,7 @@ var/list/global/map_templates = list() if(annihilate) annihilate_bounds(old_T, centered, orientation) - var/list/bounds = maploader.load_map(file(mappath), T.x, T.y, T.z, cropMap=TRUE, orientation = orientation) + var/list/bounds = SSmapping.maploader.load_map(file(mappath), T.x, T.y, T.z, cropMap=TRUE, orientation = orientation) if(!bounds) return @@ -130,15 +117,15 @@ var/list/global/map_templates = list() loaded++ return TRUE -/datum/map_template/proc/get_affected_turfs(turf/T, centered = FALSE, orientation = SOUTH) +/datum/map_template/proc/get_affected_turfs(turf/T, centered = FALSE, orientation = 0) var/turf/placement = T if(centered) - var/turf/corner = locate(placement.x - round(((orientation & NORTH|SOUTH) ? width : height)/2), placement.y - round(((orientation & NORTH|SOUTH) ? height : width)/2), placement.z) + var/turf/corner = locate(placement.x - round(((orientation%180) ? height : width)/2), placement.y - round(((orientation%180) ? width : height)/2), placement.z) // %180 catches East/West (90,270) rotations on true, North/South (0,180) rotations on false if(corner) placement = corner - return block(placement, locate(placement.x+((orientation & NORTH|SOUTH) ? width : height)-1, placement.y+((orientation & NORTH|SOUTH) ? height : width)-1, placement.z)) + return block(placement, locate(placement.x+((orientation%180) ? height : width)-1, placement.y+((orientation%180) ? width : height)-1, placement.z)) -/datum/map_template/proc/annihilate_bounds(turf/origin, centered = FALSE, orientation = SOUTH) +/datum/map_template/proc/annihilate_bounds(turf/origin, centered = FALSE, orientation = 0) var/deleted_atoms = 0 admin_notice("Annihilating objects in submap loading locatation.", R_DEBUG) var/list/turfs_to_clean = get_affected_turfs(origin, centered, orientation) @@ -152,7 +139,7 @@ var/list/global/map_templates = list() //for your ever biggening badminnery kevinz000 //⤠- Cyberboss -/proc/load_new_z_level(var/file, var/name, var/orientation = SOUTH) +/proc/load_new_z_level(var/file, var/name, var/orientation = 0) var/datum/map_template/template = new(file, name) template.load_new_z(orientation) @@ -175,8 +162,8 @@ var/list/global/map_templates = list() var/list/priority_submaps = list() // Submaps that will always be placed. // Lets go find some submaps to make. - for(var/map in map_templates) - var/datum/map_template/MT = map_templates[map] + for(var/map in SSmapping.map_templates) + var/datum/map_template/MT = SSmapping.map_templates[map] if(!MT.allow_duplicates && MT.loaded > 0) // This probably won't be an issue but we might as well. continue if(!istype(MT, desired_map_template_type)) // Not the type wanted. @@ -226,10 +213,16 @@ var/list/global/map_templates = list() var/specific_sanity = 100 // A hundred chances to place the chosen submap. while(specific_sanity > 0) specific_sanity-- - var/orientation = pick(cardinal) + + var/orientation + if(chosen_template.fixed_orientation || !config.random_submap_orientation) + orientation = 0 + else + orientation = pick(list(0, 90, 180, 270)) + chosen_template.preload_size(chosen_template.mappath, orientation) - var/width_border = TRANSITIONEDGE + SUBMAP_MAP_EDGE_PAD + round(((orientation & NORTH|SOUTH) ? chosen_template.width : chosen_template.height) / 2) - var/height_border = TRANSITIONEDGE + SUBMAP_MAP_EDGE_PAD + round(((orientation & NORTH|SOUTH) ? chosen_template.height : chosen_template.width) / 2) + var/width_border = TRANSITIONEDGE + SUBMAP_MAP_EDGE_PAD + round(((orientation%180) ? chosen_template.height : chosen_template.width) / 2) // %180 catches East/West (90,270) rotations on true, North/South (0,180) rotations on false + var/height_border = TRANSITIONEDGE + SUBMAP_MAP_EDGE_PAD + round(((orientation%180) ? chosen_template.width : chosen_template.height) / 2) var/z_level = pick(z_levels) var/turf/T = locate(rand(width_border, world.maxx - width_border), rand(height_border, world.maxy - height_border), z_level) var/valid = TRUE @@ -288,4 +281,4 @@ var/list/global/map_templates = list() admin_notice("Submap loader gave up with [budget] left to spend.", R_DEBUG) else admin_notice("Submaps loaded.", R_DEBUG) - admin_notice("Loaded: [english_list(pretty_submap_list)]", R_DEBUG) \ No newline at end of file + admin_notice("Loaded: [english_list(pretty_submap_list)]", R_DEBUG) diff --git a/code/modules/maps/tg/reader.dm b/code/modules/maps/tg/reader.dm index b8fbf2cab6..6625884949 100644 --- a/code/modules/maps/tg/reader.dm +++ b/code/modules/maps/tg/reader.dm @@ -63,9 +63,9 @@ var/global/use_preloader = FALSE if(!z_offset) z_offset = world.maxz + 1 - // If it's not a single dir, default to north (Default orientation) - if(!orientation in cardinal) - orientation = SOUTH + // If it's not a single dir, default to 0 degrees rotation (Default orientation) + if(!(orientation in list(0, 90, 180, 270))) + orientation = 0 var/list/bounds = list(1.#INF, 1.#INF, 1.#INF, -1.#INF, -1.#INF, -1.#INF) var/list/grid_models = list() @@ -109,7 +109,8 @@ var/global/use_preloader = FALSE if(cropMap) continue else - world.maxz = zcrd //create a new z_level if needed + while(world.maxz < zcrd) + world.increment_max_z() // create a new z_level if needed. if(!no_changeturf) WARNING("Z-level expansion occurred without no_changeturf set, this may cause problems") @@ -166,12 +167,12 @@ var/global/use_preloader = FALSE key_list[++key_list.len] = line_keys // Rotate the list according to orientation - if(orientation != SOUTH) + if(orientation != 0) var/num_cols = key_list[1].len var/num_rows = key_list.len var/list/new_key_list = list() // If it's rotated 180 degrees, the dimensions are the same - if(orientation == NORTH) + if(orientation == 180) new_key_list.len = num_rows for(var/i = 1 to new_key_list.len) new_key_list[i] = list() @@ -189,11 +190,11 @@ var/global/use_preloader = FALSE for(var/i = 1 to new_key_list.len) for(var/j = 1 to new_key_list[i].len) switch(orientation) - if(NORTH) + if(180) new_key_list[i][j] = key_list[num_rows - i][num_cols - j] - if(EAST) + if(270) new_key_list[i][j] = key_list[num_rows - j][i] - if(WEST) + if(90) new_key_list[i][j] = key_list[j][num_cols - i] key_list = new_key_list @@ -313,12 +314,6 @@ var/global/use_preloader = FALSE if(istext(value)) fields[I] = apply_text_macros(value) - // Rotate dir if orientation isn't south (default) - if(fields["dir"]) - fields["dir"] = turn(fields["dir"], dir2angle(orientation) + 180) - else - fields["dir"] = turn(SOUTH, dir2angle(orientation) + 180) - //then fill the members_attributes list with the corresponding variables members_attributes.len++ members_attributes[index++] = fields @@ -379,20 +374,20 @@ var/global/use_preloader = FALSE //instanciate the first /turf var/turf/T if(members[first_turf_index] != /turf/template_noop) - T = instance_atom(members[first_turf_index],members_attributes[first_turf_index],crds,no_changeturf) + T = instance_atom(members[first_turf_index],members_attributes[first_turf_index],crds,no_changeturf,orientation) if(T) //if others /turf are presents, simulates the underlays piling effect index = first_turf_index + 1 while(index <= members.len - 1) // Last item is an /area var/underlay = T.appearance - T = instance_atom(members[index],members_attributes[index],crds,no_changeturf)//instance new turf + T = instance_atom(members[index],members_attributes[index],crds,no_changeturf,orientation)//instance new turf T.underlays += underlay index++ //finally instance all remainings objects/mobs for(index in 1 to first_turf_index-1) - instance_atom(members[index],members_attributes[index],crds,no_changeturf) + instance_atom(members[index],members_attributes[index],crds,no_changeturf,orientation) //Restore initialization to the previous value SSatoms.map_loader_stop() @@ -401,7 +396,7 @@ var/global/use_preloader = FALSE //////////////// //Instance an atom at (x,y,z) and gives it the variables in attributes -/dmm_suite/proc/instance_atom(path,list/attributes, turf/crds, no_changeturf) +/dmm_suite/proc/instance_atom(path,list/attributes, turf/crds, no_changeturf, orientation=0) _preloader.setup(attributes, path) if(crds) @@ -419,6 +414,11 @@ var/global/use_preloader = FALSE stoplag() SSatoms.map_loader_begin() + // Rotate the atom now that it exists, rather than changing its orientation beforehand through the fields["dir"] + if(orientation != 0) // 0 means no rotation + var/atom/A = . + A.set_dir(turn(A.dir, orientation)) + /dmm_suite/proc/create_atom(path, crds) set waitfor = FALSE . = new path (crds) diff --git a/code/modules/materials/materials.dm b/code/modules/materials/materials.dm index f8aad253d8..6f55572ef9 100644 --- a/code/modules/materials/materials.dm +++ b/code/modules/materials/materials.dm @@ -113,6 +113,7 @@ var/list/name_to_material // Placeholder vars for the time being, todo properly integrate windows/light tiles/rods. var/created_window + var/created_fulltile_window var/rod_product var/wire_product var/list/window_options = list() @@ -485,11 +486,12 @@ var/list/name_to_material destruction_desc = "shatters" window_options = list("One Direction" = 1, "Full Window" = 4, "Windoor" = 2) created_window = /obj/structure/window/basic + created_fulltile_window = /obj/structure/window/basic/full rod_product = /obj/item/stack/material/glass/reinforced /material/glass/build_windows(var/mob/living/user, var/obj/item/stack/used_stack) - if(!user || !used_stack || !created_window || !window_options.len) + if(!user || !used_stack || !created_window || !created_fulltile_window || !window_options.len) return 0 if(!user.IsAdvancedToolUser()) @@ -544,6 +546,8 @@ var/list/name_to_material if(choice == "Windoor") if(is_reinforced()) build_path = /obj/structure/windoor_assembly/secure + else if(choice == "Full Window") + build_path = created_fulltile_window else build_path = created_window @@ -575,6 +579,7 @@ var/list/name_to_material composite_material = list(DEFAULT_WALL_MATERIAL = SHEET_MATERIAL_AMOUNT / 2, "glass" = SHEET_MATERIAL_AMOUNT) window_options = list("One Direction" = 1, "Full Window" = 4, "Windoor" = 2) created_window = /obj/structure/window/reinforced + created_fulltile_window = /obj/structure/window/reinforced/full wire_product = null rod_product = null @@ -588,6 +593,7 @@ var/list/name_to_material stack_origin_tech = list(TECH_MATERIAL = 4) window_options = list("One Direction" = 1, "Full Window" = 4) created_window = /obj/structure/window/phoronbasic + created_fulltile_window = /obj/structure/window/phoronbasic/full wire_product = null rod_product = /obj/item/stack/material/glass/phoronrglass @@ -599,6 +605,7 @@ var/list/name_to_material composite_material = list() //todo window_options = list("One Direction" = 1, "Full Window" = 4) created_window = /obj/structure/window/phoronreinforced + created_fulltile_window = /obj/structure/window/phoronreinforced/full hardness = 40 weight = 30 stack_origin_tech = list(TECH_MATERIAL = 2) diff --git a/code/modules/media/media_machinery.dm b/code/modules/media/media_machinery.dm index d12b91eb38..02d4d9698d 100644 --- a/code/modules/media/media_machinery.dm +++ b/code/modules/media/media_machinery.dm @@ -64,7 +64,7 @@ if(anchored) update_music() -/obj/machinery/media/initialize() +/obj/machinery/media/Initialize() . = ..() update_media_source() diff --git a/code/modules/media/mediamanager.dm b/code/modules/media/mediamanager.dm index 83da1250a7..c1cd4897ca 100644 --- a/code/modules/media/mediamanager.dm +++ b/code/modules/media/mediamanager.dm @@ -149,7 +149,7 @@ if (url != targetURL || abs(targetStartTime - start_time) > 1 || abs(targetVolume - source_volume) > 0.1 /* 10% */) url = targetURL start_time = targetStartTime - source_volume = Clamp(targetVolume, 0, 1) + source_volume = CLAMP(targetVolume, 0, 1) send_update() /datum/media_manager/proc/stop_music() diff --git a/code/modules/mining/drilling/drill.dm b/code/modules/mining/drilling/drill.dm index 7cf8bc575e..5e28944ae0 100644 --- a/code/modules/mining/drilling/drill.dm +++ b/code/modules/mining/drilling/drill.dm @@ -363,8 +363,8 @@ connected.check_supports() connected = null -/obj/machinery/mining/brace/verb/rotate() - set name = "Rotate" +/obj/machinery/mining/brace/verb/rotate_clockwise() + set name = "Rotate Brace Clockwise" set category = "Object" set src in oview(1) @@ -374,5 +374,5 @@ to_chat(usr, "It is anchored in place!") return 0 - src.set_dir(turn(src.dir, 90)) + src.set_dir(turn(src.dir, 270)) return 1 \ No newline at end of file diff --git a/code/modules/mining/fulton.dm b/code/modules/mining/fulton.dm index dd9c068a17..d07a52a2f2 100644 --- a/code/modules/mining/fulton.dm +++ b/code/modules/mining/fulton.dm @@ -158,7 +158,7 @@ var/global/list/total_extraction_beacons = list() density = FALSE var/beacon_network = "station" -/obj/structure/extraction_point/initialize() +/obj/structure/extraction_point/Initialize() . = ..() name += " ([rand(100,999)]) ([get_area_name(src, TRUE)])" global.total_extraction_beacons += src diff --git a/code/modules/mining/machine_processing.dm b/code/modules/mining/machine_processing.dm index f02c686921..3f76672610 100644 --- a/code/modules/mining/machine_processing.dm +++ b/code/modules/mining/machine_processing.dm @@ -16,7 +16,7 @@ var/obj/machinery/mineral/processing_unit/machine = null var/show_all_ores = FALSE -/obj/machinery/mineral/processing_unit_console/initialize() +/obj/machinery/mineral/processing_unit_console/Initialize() . = ..() src.machine = locate(/obj/machinery/mineral/processing_unit) in range(5, src) if (machine) @@ -192,7 +192,7 @@ ores_processing[OD.name] = 0 ores_stored[OD.name] = 0 -/obj/machinery/mineral/processing_unit/initialize() +/obj/machinery/mineral/processing_unit/Initialize() . = ..() // TODO - Eschew input/output machinery and just use dirs ~Leshana //Locate our output and input machinery. @@ -273,7 +273,7 @@ else if(ores_processing[metal] == PROCESS_COMPRESS && O.compresses_to) //Compressing. - var/can_make = Clamp(ores_stored[metal],0,sheets_per_tick-sheets) + var/can_make = CLAMP(ores_stored[metal],0,sheets_per_tick-sheets) if(can_make%2>0) can_make-- var/material/M = get_material_by_name(O.compresses_to) @@ -288,7 +288,7 @@ else if(ores_processing[metal] == PROCESS_SMELT && O.smelts_to) //Smelting. - var/can_make = Clamp(ores_stored[metal],0,sheets_per_tick-sheets) + var/can_make = CLAMP(ores_stored[metal],0,sheets_per_tick-sheets) var/material/M = get_material_by_name(O.smelts_to) if(!istype(M) || !can_make || ores_stored[metal] < 1) diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm index 4ff5fd7e17..c253301d1a 100644 --- a/code/modules/mining/mine_turfs.dm +++ b/code/modules/mining/mine_turfs.dm @@ -121,7 +121,7 @@ var/list/mining_overlay_cache = list() //Cache hit return mining_overlay_cache["[cache_id]_[direction]"] -/turf/simulated/mineral/initialize() +/turf/simulated/mineral/Initialize() . = ..() if(prob(20)) overlay_detail = "asteroid[rand(0,9)]" @@ -202,7 +202,7 @@ var/list/mining_overlay_cache = list() if(severity <= 2) // Now to expose the ore lying under the sand. spawn(1) // Otherwise most of the ore is lost to the explosion, which makes this rather moot. for(var/ore in resources) - var/amount_to_give = rand(Ceiling(resources[ore]/2), resources[ore]) // Should result in at least one piece of ore. + var/amount_to_give = rand(CEILING(resources[ore]/2, 1), resources[ore]) // Should result in at least one piece of ore. for(var/i=1, i <= amount_to_give, i++) var/oretype = ore_types[ore] new oretype(src) diff --git a/code/modules/mining/mint.dm b/code/modules/mining/mint.dm index 75acc807bc..bd44db119b 100644 --- a/code/modules/mining/mint.dm +++ b/code/modules/mining/mint.dm @@ -30,7 +30,7 @@ for (var/dir in cardinal) src.output = locate(/obj/machinery/mineral/output, get_step(src, dir)) if(src.output) break - processing_objects.Add(src) + START_PROCESSING(SSobj, src) return return diff --git a/code/modules/mining/ore_redemption_machine/equipment_vendor.dm b/code/modules/mining/ore_redemption_machine/equipment_vendor.dm index ae9661a13a..ad76d5b25b 100644 --- a/code/modules/mining/ore_redemption_machine/equipment_vendor.dm +++ b/code/modules/mining/ore_redemption_machine/equipment_vendor.dm @@ -66,7 +66,7 @@ src.equipment_path = path src.cost = cost -/obj/machinery/power/quantumpad/initialize() +/obj/machinery/power/quantumpad/Initialize() . = ..() default_apply_parts() diff --git a/code/modules/mining/resonator.dm b/code/modules/mining/resonator.dm index 1e96dc775b..bfbd29b830 100644 --- a/code/modules/mining/resonator.dm +++ b/code/modules/mining/resonator.dm @@ -57,7 +57,7 @@ mouse_opacity = 0 var/resonance_damage = 20 -/obj/effect/resonance/initialize(mapload, var/creator = null, var/timetoburst) +/obj/effect/resonance/Initialize(mapload, var/creator = null, var/timetoburst) . = ..() // Start small and grow to big size as we are about to burst transform = matrix()*0.75 @@ -101,7 +101,7 @@ layer = ABOVE_MOB_LAYER duration = 4 -/obj/effect/temp_visual/resonance_crush/initialize() +/obj/effect/temp_visual/resonance_crush/Initialize() . = ..() transform = matrix()*1.5 animate(src, transform = matrix()*0.1, alpha = 50, time = 4) diff --git a/code/modules/mining/resonator_vr.dm b/code/modules/mining/resonator_vr.dm index a4b20990cb..d3c3246a24 100644 --- a/code/modules/mining/resonator_vr.dm +++ b/code/modules/mining/resonator_vr.dm @@ -61,7 +61,7 @@ mouse_opacity = 0 var/resonance_damage = 20 -/obj/effect/resonance/initialize(mapload, var/creator = null, var/timetoburst) +/obj/effect/resonance/Initialize(mapload, var/creator = null, var/timetoburst) . = ..() // Start small and grow to big size as we are about to burst transform = matrix()*0.75 @@ -105,7 +105,7 @@ layer = ABOVE_MOB_LAYER duration = 4 -/obj/effect/temp_visual/resonance_crush/initialize() +/obj/effect/temp_visual/resonance_crush/Initialize() . = ..() transform = matrix()*1.5 animate(src, transform = matrix()*0.1, alpha = 50, time = 4) diff --git a/code/modules/mining/shelter_atoms.dm b/code/modules/mining/shelter_atoms.dm index 51b61cd5b1..8fbebeee54 100644 --- a/code/modules/mining/shelter_atoms.dm +++ b/code/modules/mining/shelter_atoms.dm @@ -128,7 +128,7 @@ basestate = "pwindow" //The windows have diagonal versions, and will never be a full window -/obj/structure/window/reinforced/survival_pod/is_full_window() +/obj/structure/window/reinforced/survival_pod/is_fulltile() return FALSE /obj/structure/window/reinforced/survival_pod/update_icon() @@ -219,7 +219,7 @@ pixel_y = -4 max_n_of_items = 100 -/obj/machinery/smartfridge/survival_pod/initialize() +/obj/machinery/smartfridge/survival_pod/Initialize() . = ..() for(var/obj/item/O in loc) if(accept_check(O)) diff --git a/code/modules/mob/_modifiers/auras.dm b/code/modules/mob/_modifiers/auras.dm new file mode 100644 index 0000000000..fcc023ee2e --- /dev/null +++ b/code/modules/mob/_modifiers/auras.dm @@ -0,0 +1,18 @@ +/* +'Aura' modifiers are semi-permanent, in that they do not have a set duration, but will expire if out of range of the 'source' of the aura. +Note: The source is defined as an argument in New(), and if not specified, it is assumed the holder is the source, +making it not expire ever, which is likely not what you want. +*/ + +/datum/modifier/aura + var/aura_max_distance = 5 // If more than this many tiles away from the source, the modifier expires next tick. + +/datum/modifier/aura/check_if_valid() + if(!origin) + expire() + var/atom/A = origin.resolve() + if(istype(A)) // Make sure we're not null. + if(get_dist(holder, A) > aura_max_distance) + expire() + else + expire() // Source got deleted or something. diff --git a/code/modules/mob/_modifiers/modifiers.dm b/code/modules/mob/_modifiers/modifiers.dm index 4f449b723b..115acb1b3e 100644 --- a/code/modules/mob/_modifiers/modifiers.dm +++ b/code/modules/mob/_modifiers/modifiers.dm @@ -149,6 +149,13 @@ /mob/living/proc/remove_specific_modifier(var/datum/modifier/M, var/silent = FALSE) M.expire(silent) +// Removes one modifier of a type +/mob/living/proc/remove_a_modifier_of_type(var/modifier_type, var/silent = FALSE) + for(var/datum/modifier/M in modifiers) + if(ispath(M.type, modifier_type)) + M.expire(silent) + break + // Removes all modifiers of a type /mob/living/proc/remove_modifiers_of_type(var/modifier_type, var/silent = FALSE) for(var/datum/modifier/M in modifiers) diff --git a/code/modules/mob/_modifiers/modifiers_misc.dm b/code/modules/mob/_modifiers/modifiers_misc.dm index fbe9e35624..fc714f30f8 100644 --- a/code/modules/mob/_modifiers/modifiers_misc.dm +++ b/code/modules/mob/_modifiers/modifiers_misc.dm @@ -29,7 +29,7 @@ Berserk is a somewhat rare modifier to obtain freely (and for good reason), howe - Red Slimes will berserk if they go rabid. - Red slime core reactions will berserk slimes that can see the user in addition to making them go rabid. - Red slime core reactions will berserk prometheans that can see the user. -- Bears will berserk when losing a fight. +- Saviks will berserk when losing a fight. - Changelings can evolve a 2 point ability to use a changeling-specific variant of Berserk, that replaces the text with a 'we' variant. Recursive Enhancement allows the changeling to instead used an improved variant that features less exhaustion time and less nutrition drain. - Xenoarch artifacts may have forced berserking as one of their effects. This is especially fun if an artifact that makes hostile mobs is nearby. @@ -180,3 +180,91 @@ the artifact triggers the rage. accuracy = -75 // Aiming requires focus. accuracy_dispersion = 3 // Ditto. evasion = -45 // Too angry to dodge. + +// Non-cult version of deep wounds. +// Surprisingly, more dangerous. +/datum/modifier/grievous_wounds + name = "grievous wounds" + desc = "Your wounds are not easily mended." + + on_created_text = "Your wounds pain you greatly." + on_expired_text = "The pain lulls." + + stacks = MODIFIER_STACK_EXTEND + + incoming_healing_percent = 0.50 // 50% less healing. + disable_duration_percent = 1.22 // 22% longer disables. + bleeding_rate_percent = 1.20 // 20% more bleeding. + + accuracy_dispersion = 2 // A combination of fear and immense pain or damage reults in a twitching firing arm. Flee. + + + + +// Ignition, but confined to the modifier system. +// This makes it more predictable and thus, easier to balance. +/datum/modifier/fire + name = "on fire" + desc = "You are on fire! You will be harmed until the fire goes out or you extinguish it with water." + mob_overlay_state = "on_fire" + + on_created_text = "You combust into flames!" + on_expired_text = "The fire starts to fade." + stacks = MODIFIER_STACK_ALLOWED // Multiple instances will hurt a lot. + var/damage_per_tick = 5 + +/datum/modifier/fire/intense + mob_overlay_state = "on_fire_intense" + damage_per_tick = 10 + +/datum/modifier/fire/tick() + holder.inflict_heat_damage(damage_per_tick) + + +// Applied when near something very cold. +// Reduces mobility, attack speed. +/datum/modifier/chilled + name = "chilled" + desc = "You feel yourself freezing up. Its hard to move." + mob_overlay_state = "chilled" + + on_created_text = "You feel like you're going to freeze! It's hard to move." + on_expired_text = "You feel somewhat warmer and more mobile now." + stacks = MODIFIER_STACK_EXTEND + + slowdown = 2 + evasion = -40 + attack_speed_percent = 1.4 + disable_duration_percent = 1.2 + + +// Similar to being on fire, except poison tends to be more long term. +// Antitoxins will remove stacks over time. +// Synthetics can't receive this. +/datum/modifier/poisoned + name = "poisoned" + desc = "You have poison inside of you. It will cause harm over a long span of time if not cured." + mob_overlay_state = "poisoned" + + on_created_text = "You feel sick..." + on_expired_text = "You feel a bit better." + stacks = MODIFIER_STACK_ALLOWED // Multiple instances will hurt a lot. + var/damage_per_tick = 1 + +/datum/modifier/poisoned/weak + damage_per_tick = 0.5 + +/datum/modifier/poisoned/strong + damage_per_tick = 2 + +/datum/modifier/poisoned/tick() + if(holder.stat == DEAD) + expire(silent = TRUE) + holder.inflict_poison_damage(damage_per_tick) + +/datum/modifier/poisoned/can_apply(mob/living/L) + if(L.isSynthetic()) + return FALSE + if(L.get_poison_protection() >= 1) + return FALSE + return TRUE diff --git a/code/modules/mob/_modifiers/traits_phobias.dm b/code/modules/mob/_modifiers/traits_phobias.dm index 0fbe099c22..bd30891fbe 100644 --- a/code/modules/mob/_modifiers/traits_phobias.dm +++ b/code/modules/mob/_modifiers/traits_phobias.dm @@ -207,8 +207,8 @@ if(istype(thing, /obj/structure/snowman/spider)) //Snow spiders are also spooky so people can be assholes with those too. fear_amount += 1 - if(istype(thing, /mob/living/simple_animal/hostile/giant_spider)) // Actual giant spiders are the scariest of them all. - var/mob/living/simple_animal/hostile/giant_spider/S = thing + if(istype(thing, /mob/living/simple_mob/animal/giant_spider)) // Actual giant spiders are the scariest of them all. + var/mob/living/simple_mob/animal/giant_spider/S = thing if(S.stat == DEAD) // Dead giant spiders are less scary than alive ones. fear_amount += 4 else @@ -425,14 +425,18 @@ if(istype(thing, /obj/item/clothing/head/collectable/slime)) // Some hats are spooky so people can be assholes with them. fear_amount += 1 - if(istype(thing, /mob/living/simple_animal/slime)) // An actual predatory specimen! - var/mob/living/simple_animal/slime/S = thing + if(istype(thing, /mob/living/simple_mob/slime)) // An actual predatory specimen! + var/mob/living/simple_mob/slime/S = thing if(S.stat == DEAD) // Dead slimes are somewhat less spook. fear_amount += 4 - if(S.is_adult == TRUE) //big boy - fear_amount += 8 + if(istype(S, /mob/living/simple_mob/slime/xenobio)) + var/mob/living/simple_mob/slime/xenobio/X = S + if(X.is_adult == TRUE) //big boy + fear_amount += 8 + else + fear_amount += 6 else - fear_amount += 6 + fear_amount += 10 // It's huge and feral. if(istype(thing, /mob/living/carbon/human)) var/mob/living/carbon/human/S = thing diff --git a/code/modules/mob/_modifiers/unholy.dm b/code/modules/mob/_modifiers/unholy.dm index cc4a23aa40..0eadabc83a 100644 --- a/code/modules/mob/_modifiers/unholy.dm +++ b/code/modules/mob/_modifiers/unholy.dm @@ -71,7 +71,7 @@ /datum/modifier/repair_aura/tick() spawn() - for(var/mob/living/simple_animal/construct/T in view(4,holder)) + for(var/mob/living/simple_mob/construct/T in view(4,holder)) T.adjustBruteLoss(rand(-10,-15)) T.adjustFireLoss(rand(-10,-15)) @@ -110,7 +110,7 @@ spawn() if(isliving(holder)) var/mob/living/L = holder - if(istype(L, /mob/living/simple_animal/construct)) + if(istype(L, /mob/living/simple_mob/construct)) L.adjustBruteLoss(rand(-5,-10)) L.adjustFireLoss(rand(-5,-10)) else diff --git a/code/modules/mob/animations.dm b/code/modules/mob/animations.dm index c5bded9765..9b9ce3957f 100644 --- a/code/modules/mob/animations.dm +++ b/code/modules/mob/animations.dm @@ -180,8 +180,33 @@ note dizziness decrements automatically in the mob's Life() proc. pixel_z = default_pixel_z alpha = initial_alpha -/atom/movable/proc/do_attack_animation(atom/A) +// Similar to attack animations, but in reverse and is longer to act as a telegraph. +/atom/movable/proc/do_windup_animation(atom/A, windup_time) + var/pixel_x_diff = 0 + var/pixel_y_diff = 0 + var/direction = get_dir(src, A) + if(direction & NORTH) + pixel_y_diff = -8 + else if(direction & SOUTH) + pixel_y_diff = 8 + if(direction & EAST) + pixel_x_diff = -8 + else if(direction & WEST) + pixel_x_diff = 8 + + var/default_pixel_x = initial(pixel_x) + var/default_pixel_y = initial(pixel_y) + var/mob/mob = src + if(istype(mob)) + default_pixel_x = mob.default_pixel_x + default_pixel_y = mob.default_pixel_y + + animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff, time = windup_time - 2) + animate(pixel_x = default_pixel_x, pixel_y = default_pixel_y, time = 2) + + +/atom/movable/proc/do_attack_animation(atom/A) var/pixel_x_diff = 0 var/pixel_y_diff = 0 var/direction = get_dir(src, A) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 7345e7e9b1..fa021509fb 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -498,7 +498,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp //find a viable mouse candidate - var/mob/living/simple_animal/mouse/host + var/mob/living/simple_mob/animal/passive/mouse/host var/obj/machinery/atmospherics/unary/vent_pump/vent_found var/list/found_vents = list() for(var/obj/machinery/atmospherics/unary/vent_pump/v in machines) @@ -506,7 +506,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp found_vents.Add(v) if(found_vents.len) vent_found = pick(found_vents) - host = new /mob/living/simple_animal/mouse(vent_found) + host = new /mob/living/simple_mob/animal/passive/mouse(vent_found) else src << "Unable to find any unwelded vents to spawn mice at." diff --git a/code/modules/mob/emote.dm b/code/modules/mob/emote.dm index 0ecdb2fc20..f67f70eb87 100644 --- a/code/modules/mob/emote.dm +++ b/code/modules/mob/emote.dm @@ -52,6 +52,13 @@ if(O) O.see_emote(src, message, m_type) +// Shortcuts for above proc +/mob/proc/visible_emote(var/act_desc) + custom_emote(1, act_desc) + +/mob/proc/audible_emote(var/act_desc) + custom_emote(2, act_desc) + /mob/proc/emote_dead(var/message) if(client.prefs.muted & MUTE_DEADCHAT) diff --git a/code/modules/mob/freelook/mask/chunk.dm b/code/modules/mob/freelook/mask/chunk.dm index f98a9b936b..b540a8023b 100644 --- a/code/modules/mob/freelook/mask/chunk.dm +++ b/code/modules/mob/freelook/mask/chunk.dm @@ -25,10 +25,10 @@ /mob/living/silicon/seen_cult_turfs() return list() -/mob/living/simple_animal/seen_cult_turfs() +/mob/living/simple_mob/seen_cult_turfs() return seen_turfs_in_range(src, 1) -/mob/living/simple_animal/shade/narsie/seen_cult_turfs() +/mob/living/simple_mob/construct/shade/seen_cult_turfs() return view(2, src) /proc/seen_turfs_in_range(var/source, var/range) diff --git a/code/modules/mob/hear_say.dm b/code/modules/mob/hear_say.dm index 1e862472a2..e7c097c2b3 100644 --- a/code/modules/mob/hear_say.dm +++ b/code/modules/mob/hear_say.dm @@ -78,6 +78,12 @@ var/turf/source = speaker? get_turf(speaker) : get_turf(src) src.playsound_local(source, speech_sound, sound_vol, 1) +// Done here instead of on_hear_say() since that is NOT called if the mob is clientless (which includes most AI mobs). +/mob/living/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(has_AI()) // Won't happen if no ai_holder exists or there's a player inside w/o autopilot active. + ai_holder.on_hear_say(speaker, message) + /mob/proc/on_hear_say(var/message) to_chat(src, message) if(teleop) @@ -158,17 +164,10 @@ 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 + if(language) + message = language.scramble(message) else - if(language) - message = language.scramble(message) - else - message = stars(message) + message = stars(message) if(hard_to_hear) message = stars(message) diff --git a/code/modules/mob/holder.dm b/code/modules/mob/holder.dm index 3779b7075f..25ee7c64be 100644 --- a/code/modules/mob/holder.dm +++ b/code/modules/mob/holder.dm @@ -23,10 +23,10 @@ var/list/holder_mob_icon_cache = list() /obj/item/weapon/holder/New() ..() - processing_objects.Add(src) + START_PROCESSING(SSobj, src) /obj/item/weapon/holder/Destroy() - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) return ..() /obj/item/weapon/holder/process() diff --git a/code/modules/mob/language/generic.dm b/code/modules/mob/language/generic.dm index 40fe94b7f5..5a46a72038 100644 --- a/code/modules/mob/language/generic.dm +++ b/code/modules/mob/language/generic.dm @@ -18,6 +18,9 @@ // 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/noise/can_speak_special(var/mob/speaker) + return TRUE //Audible emotes + // 'basic' language; spoken by default. /datum/language/common name = LANGUAGE_GALCOM @@ -136,3 +139,76 @@ /datum/language/sign/can_speak_special(var/mob/speaker) // TODO: If ever we make external organs assist languages, convert this over to the new format var/obj/item/organ/external/hand/hands = locate() in speaker //you can't sign without hands return (hands || !iscarbon(speaker)) + +// Silly language for those times when you try to talk a languague you normally can't +/datum/language/gibberish + name = LANGUAGE_GIBBERISH + desc = "A completely incomprehensible language." + signlang_verb = list("flails") + speech_verb = "spews" + whisper_verb = "mumbles" + exclaim_verb = "shrieks" + colour = "attack" + key = "r" // Radda radda radda + flags = RESTRICTED|NONGLOBAL + machine_understands = 0 + syllables = list ( + "radda", "fea","vea","vei","veh","vee","feh","fa","soa","su","sua","sou","se","seh","twa","twe","twi", + "ahm","lea","lee","nae","nah","pa","pau","fae","fai","soh","mou","ahe","ll","ea","ai","thi", + "hie","zei","zie","ize","ehy","uy","oya","dor","di","ja","ej","er","um","in","qu","is","re", + "nt","ti","us","it","en","at","tu","te","ri","es","et","ra","ta","an","ni","li","on","or","se", + "am","ae","ia","di","ue","em","ar","ui","st","si","de","ci","iu","ne","pe","co","os","ur","ru", + "gra","ba","ba","breh","bra","rah","dur","ra","ro","gro","go","ber","bar","geh","heh", "gra", + "a", "ai", "an", "ang", "ao", "ba", "bai", "ban", "bang", "bao", "bei", "ben", "beng", "bi", "bian", "biao", + "bie", "bin", "bing", "bo", "bu", "ca", "cai", "can", "cang", "cao", "ce", "cei", "cen", "ceng", "cha", "chai", + "chan", "chang", "chao", "che", "chen", "cheng", "chi", "chong", "chou", "chu", "chua", "chuai", "chuan", "chuang", "chui", "chun", + "chuo", "ci", "cong", "cou", "cu", "cuan", "cui", "cun", "cuo", "da", "dai", "dan", "dang", "dao", "de", "dei", + "den", "deng", "di", "dian", "diao", "die", "ding", "diu", "dong", "dou", "du", "duan", "dui", "dun", "duo", "e", + "ei", "en", "er", "fa", "fan", "fang", "fei", "fen", "feng", "fo", "fou", "fu", "ga", "gai", "gan", "gang", + "gao", "ge", "gei", "gen", "geng", "gong", "gou", "gu", "gua", "guai", "guan", "guang", "gui", "gun", "guo", "ha", + "hai", "han", "hang", "hao", "he", "hei", "hen", "heng", "hm", "hng", "hong", "hou", "hu", "hua", "huai", "huan", + "huang", "hui", "hun", "huo", "ji", "jia", "jian", "jiang", "jiao", "jie", "jin", "jing", "jiong", "jiu", "ju", "juan", + "jue", "jun", "ka", "kai", "kan", "kang", "kao", "ke", "kei", "ken", "keng", "kong", "kou", "ku", "kua", "kuai", + "kuan", "kuang", "kui", "kun", "kuo", "la", "lai", "lan", "lang", "lao", "le", "lei", "leng", "li", "lia", "lian", + "liang", "liao", "lie", "lin", "ling", "liu", "long", "lou", "lu", "luan", "lun", "luo", "ma", "mai", "man", "mang", + "mao", "me", "mei", "men", "meng", "mi", "mian", "miao", "mie", "min", "ming", "miu", "mo", "mou", "mu", "na", + "nai", "nan", "nang", "nao", "ne", "nei", "nen", "neng", "ng", "ni", "nian", "niang", "niao", "nie", "nin", "ning", + "niu", "nong", "nou", "nu", "nuan", "nuo", "o", "ou", "pa", "pai", "pan", "pang", "pao", "pei", "pen", "peng", + "pi", "pian", "piao", "pie", "pin", "ping", "po", "pou", "pu", "qi", "qia", "qian", "qiang", "qiao", "qie", "qin", + "qing", "qiong", "qiu", "qu", "quan", "que", "qun", "ran", "rang", "rao", "re", "ren", "reng", "ri", "rong", "rou", + "ru", "rua", "ruan", "rui", "run", "ruo", "sa", "sai", "san", "sang", "sao", "se", "sei", "sen", "seng", "sha", + "shai", "shan", "shang", "shao", "she", "shei", "shen", "sheng", "shi", "shou", "shu", "shua", "shuai", "shuan", "shuang", "shui", + "shun", "shuo", "si", "song", "sou", "su", "suan", "sui", "sun", "suo", "ta", "tai", "tan", "tang", "tao", "te", + "teng", "ti", "tian", "tiao", "tie", "ting", "tong", "tou", "tu", "tuan", "tui", "tun", "tuo", "wa", "wai", "wan", + "wang", "wei", "wen", "weng", "wo", "wu", "xi", "xia", "xian", "xiang", "xiao", "xie", "xin", "xing", "xiong", "xiu", + "xu", "xuan", "xue", "xun", "ya", "yan", "yang", "yao", "ye", "yi", "yin", "ying", "yong", "you", "yu", "yuan", + "yue", "yun", "za", "zai", "zan", "zang", "zao", "ze", "zei", "zen", "zeng", "zha", "zhai", "zhan", "zhang", "zhao", + "zhe", "zhei", "zhen", "zheng", "zhi", "zhong", "zhou", "zhu", "zhua", "zhuai", "zhuan", "zhuang", "zhui", "zhun", "zhuo", "zi", + "zong", "zou", "zuan", "zui", "zun", "zuo", "zu", "al", "an", "ar", "as", "at", "ea", "ed", "en", "er", "es", "ha", "he", "hi", "in", "is", "it", + "le", "me", "nd", "ne", "ng", "nt", "on", "or", "ou", "re", "se", "st", "te", "th", "ti", "to", + "ve", "wa", "all", "and", "are", "but", "ent", "era", "ere", "eve", "for", "had", "hat", "hen", "her", "hin", + "his", "ing", "ion", "ith", "not", "ome", "oul", "our", "sho", "ted", "ter", "tha", "the", "thi", + "al", "an", "ar", "as", "at", "ea", "ed", "en", "er", "es", "ha", "he", "hi", "in", "is", "it", + "le", "me", "nd", "ne", "ng", "nt", "on", "or", "ou", "re", "se", "st", "te", "th", "ti", "to", + "ve", "wa", "all", "and", "are", "but", "ent", "era", "ere", "eve", "for", "had", "hat", "hen", "her", "hin", + "his", "ing", "ion", "ith", "not", "ome", "oul", "our", "sho", "ted", "ter", "tha", "the", "thi", + "al", "an", "ar", "as", "at", "ea", "ed", "en", "er", "es", "ha", "he", "hi", "in", "is", "it", + "le", "me", "nd", "ne", "ng", "nt", "on", "or", "ou", "re", "se", "st", "te", "th", "ti", "to", + "ve", "wa", "all", "and", "are", "but", "ent", "era", "ere", "eve", "for", "had", "hat", "hen", "her", "hin", + "his", "ing", "ion", "ith", "not", "ome", "oul", "our", "sho", "ted", "ter", "tha", "the", "thi", + "al", "an", "ar", "as", "at", "ea", "ed", "en", "er", "es", "ha", "he", "hi", "in", "is", "it", + "le", "me", "nd", "ne", "ng", "nt", "on", "or", "ou", "re", "se", "st", "te", "th", "ti", "to", + "ve", "wa", "all", "and", "are", "but", "ent", "era", "ere", "eve", "for", "had", "hat", "hen", "her", "hin", + "his", "ing", "ion", "ith", "not", "ome", "oul", "our", "sho", "ted", "ter", "tha", "the", "thi", + "al", "an", "ar", "as", "at", "ea", "ed", "en", "er", "es", "ha", "he", "hi", "in", "is", "it", + "le", "me", "nd", "ne", "ng", "nt", "on", "or", "ou", "re", "se", "st", "te", "th", "ti", "to", + "ve", "wa", "all", "and", "are", "but", "ent", "era", "ere", "eve", "for", "had", "hat", "hen", "her", "hin", + "his", "ing", "ion", "ith", "not", "ome", "oul", "our", "sho", "ted", "ter", "tha", "the", "thi", + "al", "an", "ar", "as", "at", "ea", "ed", "en", "er", "es", "ha", "he", "hi", "in", "is", "it", + "le", "me", "nd", "ne", "ng", "nt", "on", "or", "ou", "re", "se", "st", "te", "th", "ti", "to", + "ve", "wa", "all", "and", "are", "but", "ent", "era", "ere", "eve", "for", "had", "hat", "hen", "her", "hin", + "his", "ing", "ion", "ith", "not", "ome", "oul", "our", "sho", "ted", "ter", "tha", "the", "thi" + ) + +/datum/language/gibberish/can_speak_special(var/mob/speaker) + return TRUE //Anyone can speak gibberish \ No newline at end of file diff --git a/code/modules/mob/language/language.dm b/code/modules/mob/language/language.dm index 66e0e5e0f0..4822f46a16 100644 --- a/code/modules/mob/language/language.dm +++ b/code/modules/mob/language/language.dm @@ -32,7 +32,7 @@ for(var/i = 0;i0;x--) + for(var/x = rand(FLOOR(syllable_count/syllable_divisor, 1),syllable_count);x>0;x--) new_name += pick(syllables) full_name += " [capitalize(lowertext(new_name))]" @@ -134,14 +134,15 @@ /datum/language/proc/can_speak_special(var/mob/speaker) . = TRUE - if(ishuman(speaker)) - var/mob/living/carbon/human/H = speaker - if(src.name in H.species.assisted_langs) - . = FALSE - var/obj/item/organ/internal/voicebox/vox = locate() in H.internal_organs // Only voiceboxes for now. Maybe someday it'll include other organs, but I'm not that clever - if(vox) - if(!vox.is_broken() && (src in vox.assists_languages)) - . = TRUE + if(name != "Noise") // Audible Emotes + if(ishuman(speaker)) + var/mob/living/carbon/human/H = speaker + if(src.name in H.species.assisted_langs) + . = FALSE + var/obj/item/organ/internal/voicebox/vox = locate() in H.internal_organs // Only voiceboxes for now. Maybe someday it'll include other organs, but I'm not that clever + if(vox) + if(!vox.is_broken() && (src in vox.assists_languages)) + . = TRUE // Language handling. /mob/proc/add_language(var/language) @@ -172,10 +173,20 @@ log_debug("[src] attempted to speak a null language.") return 0 + if(speaking == all_languages["Noise"]) + return 1 + if (only_species_language && speaking != all_languages[species_language]) return 0 - return (speaking.can_speak_special(src) && (universal_speak || (speaking && (speaking.flags & INNATE)) || speaking in src.languages)) + if(speaking.can_speak_special(src)) + if(universal_speak) + return 1 + if(speaking && (speaking.flags & INNATE)) + return 1 + if(speaking in src.languages) + return 1 + return 0 /mob/proc/get_language_prefix() if(client && client.prefs.language_prefixes && client.prefs.language_prefixes.len) diff --git a/code/modules/mob/language/outsider.dm b/code/modules/mob/language/outsider.dm index fdd719df89..de78a9c1b5 100644 --- a/code/modules/mob/language/outsider.dm +++ b/code/modules/mob/language/outsider.dm @@ -27,16 +27,16 @@ /datum/language/corticalborer/broadcast(var/mob/living/speaker,var/message,var/speaker_mask) - var/mob/living/simple_animal/borer/B + var/mob/living/simple_mob/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)) + else if(istype(speaker,/mob/living/simple_mob/animal/borer)) B = speaker if(B) - speaker_mask = B.truename + speaker_mask = B.true_name ..(speaker,message,speaker_mask) /datum/language/vox diff --git a/code/modules/mob/living/bot/bot.dm b/code/modules/mob/living/bot/bot.dm index 12715a4c2b..ff35a795b5 100644 --- a/code/modules/mob/living/bot/bot.dm +++ b/code/modules/mob/living/bot/bot.dm @@ -44,6 +44,8 @@ ..() update_icons() + default_language = all_languages[LANGUAGE_GALCOM] + botcard = new /obj/item/weapon/card/id(src) botcard.access = botcard_access.Copy() @@ -52,7 +54,7 @@ access_scanner.req_one_access = req_one_access.Copy() // Make sure mapped in units start turned on. -/mob/living/bot/initialize() +/mob/living/bot/Initialize() . = ..() if(on) turn_on() // Update lights and other stuff diff --git a/code/modules/mob/living/bot/ed209bot.dm b/code/modules/mob/living/bot/ed209bot.dm index 7c709bc165..b8f1c85485 100644 --- a/code/modules/mob/living/bot/ed209bot.dm +++ b/code/modules/mob/living/bot/ed209bot.dm @@ -68,8 +68,9 @@ playsound(loc, emagged ? 'sound/weapons/Laser.ogg' : 'sound/weapons/Taser.ogg', 50, 1) var/obj/item/projectile/P = new projectile(loc) - P.launch(A) - return + P.firer = src + P.old_style_target(A) + P.fire() // Assembly diff --git a/code/modules/mob/living/bot/secbot.dm b/code/modules/mob/living/bot/secbot.dm index ba8c0945f0..23008d126a 100644 --- a/code/modules/mob/living/bot/secbot.dm +++ b/code/modules/mob/living/bot/secbot.dm @@ -215,7 +215,7 @@ else if(declare_arrests) var/action = arrest_type ? "detaining" : "arresting" - if(istype(target, /mob/living/simple_animal)) + if(istype(target, /mob/living/simple_mob)) action = "fighting" global_announcer.autosay("[src] is [action] a level [threat] [action != "fighting" ? "suspect" : "threat"] [target_name(target)] in [get_area(src)].", "[src]", "Security") UnarmedAttack(target) @@ -269,8 +269,8 @@ C.handcuffed = new /obj/item/weapon/handcuffs(C) C.update_inv_handcuffed() busy = 0 - else if(istype(M, /mob/living/simple_animal)) - var/mob/living/simple_animal/S = M + else if(istype(M, /mob/living/simple_mob)) + var/mob/living/simple_mob/S = M S.Weaken(xeno_stun_strength) S.adjustBruteLoss(xeno_harm_strength) do_attack_animation(M) @@ -286,8 +286,8 @@ /mob/living/bot/secbot/slime/UnarmedAttack(var/mob/living/L, var/proximity) ..() - if(istype(L, /mob/living/simple_animal/slime)) - var/mob/living/simple_animal/slime/S = L + if(istype(L, /mob/living/simple_mob/slime/xenobio)) + var/mob/living/simple_mob/slime/xenobio/S = L S.adjust_discipline(2) diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index 5e416755e0..42f7dece0c 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -20,7 +20,8 @@ var/adult_name var/instance_num -/mob/living/carbon/alien/New() +/mob/living/carbon/alien/Initialize() + . = ..() time_of_birth = world.time @@ -37,8 +38,6 @@ gender = NEUTER - ..() - /mob/living/carbon/alien/u_equip(obj/item/W as obj) return diff --git a/code/modules/mob/living/carbon/alien/diona/diona.dm b/code/modules/mob/living/carbon/alien/diona/diona.dm index 5d497d0a08..3d09887f34 100644 --- a/code/modules/mob/living/carbon/alien/diona/diona.dm +++ b/code/modules/mob/living/carbon/alien/diona/diona.dm @@ -20,9 +20,8 @@ holder_type = /obj/item/weapon/holder/diona var/obj/item/hat -/mob/living/carbon/alien/diona/New() - - ..() +/mob/living/carbon/alien/diona/Initialize() + . = ..() species = all_species[SPECIES_DIONA] add_language(LANGUAGE_ROOTGLOBAL) add_language(LANGUAGE_GALCOM) diff --git a/code/modules/mob/living/carbon/alien/diona/diona_powers.dm b/code/modules/mob/living/carbon/alien/diona/diona_powers.dm index 585b421c7f..aea0054418 100644 --- a/code/modules/mob/living/carbon/alien/diona/diona_powers.dm +++ b/code/modules/mob/living/carbon/alien/diona/diona_powers.dm @@ -63,5 +63,5 @@ if(istype(M)) for(var/atom/A in M.contents) - if(istype(A,/mob/living/simple_animal/borer) || istype(A,/obj/item/weapon/holder)) + if(istype(A,/mob/living/simple_mob/animal/borer) || istype(A,/obj/item/weapon/holder)) return diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm index 7870c710c7..e39f66c479 100644 --- a/code/modules/mob/living/carbon/alien/larva/larva.dm +++ b/code/modules/mob/living/carbon/alien/larva/larva.dm @@ -9,7 +9,7 @@ health = 25 faction = "xeno" -/mob/living/carbon/alien/larva/New() - ..() +/mob/living/carbon/alien/larva/Initialize() + . = ..() add_language("Xenomorph") //Bonus language. internal_organs |= new /obj/item/organ/internal/xenos/hivenode(src) diff --git a/code/modules/mob/living/carbon/brain/brain.dm b/code/modules/mob/living/carbon/brain/brain.dm index 7165c36fa8..a75deb25d0 100644 --- a/code/modules/mob/living/carbon/brain/brain.dm +++ b/code/modules/mob/living/carbon/brain/brain.dm @@ -10,45 +10,45 @@ icon_state = "brain1" no_vore = TRUE //VOREStation Edit - PLEASE. lol. - New() - var/datum/reagents/R = new/datum/reagents(1000) - reagents = R - R.my_atom = src - ..() +/mob/living/carbon/brain/Initialize() + . = ..() + var/datum/reagents/R = new/datum/reagents(1000) + reagents = R + R.my_atom = src - Destroy() - if(key) //If there is a mob connected to this thing. Have to check key twice to avoid false death reporting. - if(stat!=DEAD) //If not dead. - death(1) //Brains can die again. AND THEY SHOULD AHA HA HA HA HA HA - ghostize() //Ghostize checks for key so nothing else is necessary. - return ..() +/mob/living/carbon/brain/Destroy() + if(key) //If there is a mob connected to this thing. Have to check key twice to avoid false death reporting. + if(stat!=DEAD) //If not dead. + death(1) //Brains can die again. AND THEY SHOULD AHA HA HA HA HA HA + ghostize() //Ghostize checks for key so nothing else is necessary. + return ..() - say_understands(var/other)//Goddamn is this hackish, but this say code is so odd - if (istype(other, /mob/living/silicon/ai)) - if(!(container && istype(container, /obj/item/device/mmi))) - return 0 - else - return 1 - if (istype(other, /mob/living/silicon/decoy)) - if(!(container && istype(container, /obj/item/device/mmi))) - return 0 - else - return 1 - if (istype(other, /mob/living/silicon/pai)) - if(!(container && istype(container, /obj/item/device/mmi))) - return 0 - else - return 1 - if (istype(other, /mob/living/silicon/robot)) - if(!(container && istype(container, /obj/item/device/mmi))) - return 0 - else - return 1 - if (istype(other, /mob/living/carbon/human)) +/mob/living/carbon/brain/say_understands(var/other)//Goddamn is this hackish, but this say code is so odd + if (istype(other, /mob/living/silicon/ai)) + if(!(container && istype(container, /obj/item/device/mmi))) + return 0 + else return 1 - if (istype(other, /mob/living/simple_animal/slime)) + if (istype(other, /mob/living/silicon/decoy)) + if(!(container && istype(container, /obj/item/device/mmi))) + return 0 + else return 1 - return ..() + if (istype(other, /mob/living/silicon/pai)) + if(!(container && istype(container, /obj/item/device/mmi))) + return 0 + else + return 1 + if (istype(other, /mob/living/silicon/robot)) + if(!(container && istype(container, /obj/item/device/mmi))) + return 0 + else + return 1 + if (istype(other, /mob/living/carbon/human)) + return 1 + if (istype(other, /mob/living/simple_mob/slime)) + return 1 + return ..() /mob/living/carbon/brain/update_canmove() if(in_contents_of(/obj/mecha) || istype(loc, /obj/item/device/mmi)) diff --git a/code/modules/mob/living/carbon/brain/life.dm b/code/modules/mob/living/carbon/brain/life.dm index b631e8ae13..4ab220083d 100644 --- a/code/modules/mob/living/carbon/brain/life.dm +++ b/code/modules/mob/living/carbon/brain/life.dm @@ -76,7 +76,6 @@ if(ingested) ingested.metabolize() if(bloodstr) bloodstr.metabolize() - AdjustConfused(-1) // decrement dizziness counter, clamped to 0 if(resting) dizziness = max(0, dizziness - 5) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 01f74ac3b5..505821640d 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -1,4 +1,5 @@ -/mob/living/carbon/New() +/mob/living/carbon/Initialize() + . = ..() //setup reagent holders bloodstr = new/datum/reagents/metabolism/bloodstream(500, src) ingested = new/datum/reagents/metabolism/ingested(500, src) @@ -6,7 +7,6 @@ reagents = bloodstr if (!default_language && species_language) default_language = all_languages[species_language] - ..() /mob/living/carbon/Life() ..() @@ -348,12 +348,12 @@ if(alert(src,"You sure you want to sleep for a while?","Sleep","Yes","No") == "Yes") usr.sleeping = 20 //Short nap -/mob/living/carbon/Bump(var/atom/movable/AM, yes) - if(now_pushing || !yes) +/mob/living/carbon/Bump(atom/A) + if(now_pushing) return ..() - if(istype(AM, /mob/living/carbon) && prob(10)) - src.spread_disease_to(AM, "Contact") + if(istype(A, /mob/living/carbon) && prob(10)) + spread_disease_to(A, "Contact") /mob/living/carbon/cannot_use_vents() return @@ -364,7 +364,7 @@ stop_pulling() src << "You slipped on [slipped_on]!" playsound(src.loc, 'sound/misc/slip.ogg', 50, 1, -3) - Weaken(Floor(stun_duration/2)) + Weaken(FLOOR(stun_duration/2, 1)) return 1 /mob/living/carbon/proc/add_chemical_effect(var/effect, var/magnitude = 1) @@ -374,11 +374,15 @@ chem_effects[effect] = magnitude /mob/living/carbon/get_default_language() - if(default_language && can_speak(default_language)) - return default_language + if(default_language) + if(can_speak(default_language)) + return default_language + else + return all_languages[LANGUAGE_GIBBERISH] if(!species) return null + return species.default_language ? all_languages[species.default_language] : null /mob/living/carbon/proc/should_have_organ(var/organ_check) @@ -388,3 +392,8 @@ if(isSynthetic()) return 0 return !(species.flags & NO_PAIN) + +/mob/living/carbon/needs_to_breathe() + if(does_not_breathe) + return FALSE + return ..() diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index c9b2d6d3ff..cd59a549ec 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -69,7 +69,7 @@ var/damage_mod = 1 //presumably, if they are wearing a helmet that stops pressure effects, then it probably covers the throat as well var/obj/item/clothing/head/helmet = get_equipped_item(slot_head) - if(istype(helmet) && (helmet.body_parts_covered & HEAD) && (helmet.flags & STOPPRESSUREDAMAGE)) + if(istype(helmet) && (helmet.body_parts_covered & HEAD) && (helmet.min_pressure_protection != null)) // Both min- and max_pressure_protection must be set for it to function at all, so we can just check that one is set. //we don't do an armor_check here because this is not an impact effect like a weapon swung with momentum, that either penetrates or glances off. damage_mod = 1.0 - (helmet.armor["melee"]/100) diff --git a/code/modules/mob/living/carbon/carbon_powers.dm b/code/modules/mob/living/carbon/carbon_powers.dm index f1360504ef..337f0b0ff1 100644 --- a/code/modules/mob/living/carbon/carbon_powers.dm +++ b/code/modules/mob/living/carbon/carbon_powers.dm @@ -5,7 +5,7 @@ set name = "Release Control" set desc = "Release control of your host's body." - var/mob/living/simple_animal/borer/B = has_brain_worms() + var/mob/living/simple_mob/animal/borer/B = has_brain_worms() if(B && B.host_brain) src << "You withdraw your probosci, releasing control of [B.host_brain]" @@ -25,7 +25,7 @@ set name = "Torment host" set desc = "Punish your host with agony." - var/mob/living/simple_animal/borer/B = has_brain_worms() + var/mob/living/simple_mob/animal/borer/B = has_brain_worms() if(!B) return @@ -43,7 +43,7 @@ set name = "Reproduce" set desc = "Spawn several young." - var/mob/living/simple_animal/borer/B = has_brain_worms() + var/mob/living/simple_mob/animal/borer/B = has_brain_worms() if(!B) return @@ -55,7 +55,7 @@ B.has_reproduced = 1 vomit(1) - new /mob/living/simple_animal/borer(get_turf(src)) + new /mob/living/simple_mob/animal/borer(get_turf(src)) else src << "You do not have enough chemicals stored to reproduce." diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index 24a5bac586..2244cdac51 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -61,11 +61,11 @@ //Handle brain slugs. var/obj/item/organ/external/Hd = get_organ(BP_HEAD) - var/mob/living/simple_animal/borer/B + var/mob/living/simple_mob/animal/borer/B if(Hd) for(var/I in Hd.implants) - if(istype(I,/mob/living/simple_animal/borer)) + if(istype(I,/mob/living/simple_mob/animal/borer)) B = I if(B) if(!B.ckey && ckey && B.controlling) diff --git a/code/modules/mob/living/carbon/human/descriptors/_descriptors.dm b/code/modules/mob/living/carbon/human/descriptors/_descriptors.dm index d2944cc0cb..815914f40c 100644 --- a/code/modules/mob/living/carbon/human/descriptors/_descriptors.dm +++ b/code/modules/mob/living/carbon/human/descriptors/_descriptors.dm @@ -34,7 +34,7 @@ chargen_value_descriptors = list() for(var/i = 1 to LAZYLEN(standalone_value_descriptors)) chargen_value_descriptors[standalone_value_descriptors[i]] = i - default_value = ceil(LAZYLEN(standalone_value_descriptors) * 0.5) + default_value = CEILING(LAZYLEN(standalone_value_descriptors) * 0.5, 1) ..() /datum/mob_descriptor/proc/get_third_person_message_start(var/datum/gender/my_gender) @@ -99,10 +99,10 @@ /datum/mob_descriptor/proc/get_comparative_value_string_smaller(var/value, var/datum/gender/my_gender, var/datum/gender/other_gender) var/maxval = LAZYLEN(comparative_value_descriptors_smaller) - value = Clamp(ceil(value * maxval), 1, maxval) + value = CLAMP(CEILING(value * maxval, 1), 1, maxval) return comparative_value_descriptors_smaller[value] /datum/mob_descriptor/proc/get_comparative_value_string_larger(var/value, var/datum/gender/my_gender, var/datum/gender/other_gender) var/maxval = LAZYLEN(comparative_value_descriptors_larger) - value = Clamp(ceil(value * maxval), 1, maxval) + value = CLAMP(CEILING(value * maxval, 1), 1, maxval) return comparative_value_descriptors_larger[value] diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 445168777d..9af501a92e 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -20,8 +20,7 @@ var/active_regen = FALSE //Used for the regenerate proc in human_powers.dm var/active_regen_delay = 300 -/mob/living/carbon/human/New(var/new_loc, var/new_species = null) - +/mob/living/carbon/human/Initialize(mapload, var/new_species = null) if(!dna) dna = new /datum/dna(null) // Species name is handled by set_species() @@ -42,7 +41,7 @@ human_mob_list |= src - ..() + . = ..() hide_underwear.Cut() for(var/category in global_underwear.categories_by_name) @@ -58,7 +57,7 @@ for(var/organ in organs) qdel(organ) QDEL_NULL(nif) //VOREStation Add - QDEL_NULL_LIST(vore_organs) //VOREStation Add + QDEL_LIST_NULL(vore_organs) //VOREStation Add return ..() /mob/living/carbon/human/Stat() diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index c5f259e0b4..57cb8d0f58 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -135,6 +135,27 @@ emp_act return siemens_coefficient +// Similar to above but is for the mob's overall protection, being the average of all slots. +/mob/living/carbon/human/proc/get_siemens_coefficient_average() + var/siemens_value = 0 + var/total = 0 + for(var/organ_name in organs_by_name) + if(organ_name in organ_rel_size) + var/obj/item/organ/external/organ = organs_by_name[organ_name] + if(organ) + var/weight = organ_rel_size[organ_name] + siemens_value += get_siemens_coefficient_organ(organ) * weight + total += weight + + if(fire_stacks < 0) // Water makes you more conductive. + siemens_value *= 1.5 + + return (siemens_value/max(total, 1)) + +// Returns a number between 0 to 1, with 1 being total protection. +/mob/living/carbon/human/get_shock_protection() + return between(0, 1-get_siemens_coefficient_average(), 1) + // Returns a list of clothing that is currently covering def_zone. /mob/living/carbon/human/proc/get_clothing_list_organ(var/obj/item/organ/external/def_zone, var/type) var/list/results = list() @@ -542,6 +563,20 @@ emp_act return perm +// This is for preventing harm by being covered in water, which only prometheans need to deal with. +// This is not actually used for now since the code for prometheans gets changed a lot. +/mob/living/carbon/human/get_water_protection() + var/protection = ..() // Todo: Replace with species var later. + if(protection == 1) // No point doing permeability checks if it won't matter. + return protection + // Wearing clothing with a low permeability_coefficient can protect from water. + + var/converted_protection = 1 - protection + var/perm = reagent_permeability() + converted_protection *= perm + return 1-converted_protection + + /mob/living/carbon/human/shank_attack(obj/item/W, obj/item/weapon/grab/G, mob/user, hit_zone) if(!..()) diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm index 2589b1c9da..24a63bf1a4 100644 --- a/code/modules/mob/living/carbon/human/human_helpers.dm +++ b/code/modules/mob/living/carbon/human/human_helpers.dm @@ -42,6 +42,16 @@ if(cloaker.active) cloaker.deactivate() +/mob/living/carbon/human/is_cloaked() + if(mind && mind.changeling && mind.changeling.cloaked) // Ling camo. + return TRUE + else if(istype(back, /obj/item/weapon/rig)) //Ninja cloak + var/obj/item/weapon/rig/suit = back + for(var/obj/item/rig_module/stealth_field/cloaker in suit.installed_modules) + if(cloaker.active) + return TRUE + return ..() + /mob/living/carbon/human/get_ear_protection() var/sum = 0 if(istype(l_ear, /obj/item/clothing/ears)) diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index c92be26380..187ebd4e1e 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -1,9 +1,9 @@ +#define HUMAN_LOWEST_SLOWDOWN -3 + /mob/living/carbon/human/movement_delay() var/tally = 0 - var/item_tally = 0 - if(species.slowdown) tally = species.slowdown @@ -13,11 +13,11 @@ handle_embedded_objects() //Moving with objects stuck in you can cause bad times. if(force_max_speed) - return -3 + return HUMAN_LOWEST_SLOWDOWN for(var/datum/modifier/M in modifiers) if(!isnull(M.haste) && M.haste == TRUE) - return -3 // Returning -1 will actually result in a slowdown for Teshari. + return HUMAN_LOWEST_SLOWDOWN // Returning -1 will actually result in a slowdown for Teshari. if(!isnull(M.slowdown)) tally += M.slowdown @@ -58,9 +58,6 @@ else if(E.status & ORGAN_BROKEN) tally += 1.5 else - if(shoes) - item_tally += shoes.slowdown - for(var/organ_name in list(BP_L_LEG, BP_R_LEG, BP_L_FOOT, BP_R_FOOT)) var/obj/item/organ/external/E = get_organ(organ_name) if(!E || E.is_stump()) @@ -87,39 +84,20 @@ // Turf related slowdown var/turf/T = get_turf(src) - if(T && T.movement_cost) - var/turf_move_cost = T.movement_cost - if(istype(T, /turf/simulated/floor/water)) - if(species.water_movement) - turf_move_cost = Clamp(-3, turf_move_cost + species.water_movement, 15) - if(shoes) - var/obj/item/clothing/shoes/feet = shoes - if(feet.water_speed) - turf_move_cost = Clamp(-3, turf_move_cost + feet.water_speed, 15) - tally += turf_move_cost - if(istype(T, /turf/simulated/floor/outdoors/snow)) - if(species.snow_movement) - turf_move_cost = Clamp(-3, turf_move_cost + species.snow_movement, 15) - if(shoes) - var/obj/item/clothing/shoes/feet = shoes - if(feet.water_speed) - turf_move_cost = Clamp(-3, turf_move_cost + feet.snow_speed, 15) - tally += turf_move_cost + tally += calculate_turf_slowdown(T) - // Loop through some slots, and add up their slowdowns. Shoes are handled below, unfortunately. - // Includes slots which can provide armor, the back slot, and suit storage. - for(var/obj/item/I in list(wear_suit, w_uniform, back, gloves, head, s_store)) - item_tally += I.slowdown - - // Hands are also included, to make the 'take off your armor instantly and carry it with you to go faster' trick no longer viable. - // This is done seperately to disallow negative numbers. - for(var/obj/item/I in list(r_hand, l_hand) ) - item_tally += max(I.slowdown, 0) + // Item related slowdown. + var/item_tally = calculate_item_encumbrance() // Dragging heavy objects will also slow you down, similar to above. - if(pulling && istype(pulling, /obj/item)) - var/obj/item/pulled = pulling - item_tally += max(pulled.slowdown, 0) + if(pulling) + if(istype(pulling, /obj/item)) + var/obj/item/pulled = pulling + item_tally += max(pulled.slowdown, 0) + else if(ishuman(pulling)) + var/mob/living/carbon/human/H = pulling + var/their_slowdown = max(H.calculate_item_encumbrance(), 1) + item_tally = max(item_tally, their_slowdown) // If our slowdown is less than theirs, then we become as slow as them (before species modifires). item_tally *= species.item_slowdown_mod @@ -135,7 +113,47 @@ tally = tally/2 tally -= chem_effects[CE_SPEEDBOOST] // give 'em a buff on top. - return max(-3, tally+config.human_delay) // Minimum return should be the same as force_max_speed + return max(HUMAN_LOWEST_SLOWDOWN, tally+config.human_delay) // Minimum return should be the same as force_max_speed + +// This calculates the amount of slowdown to receive from items worn. This does NOT include species modifiers. +// It is in a seperate place to avoid an infinite loop situation with dragging mobs dragging each other. +// Also its nice to have these things seperated. +/mob/living/carbon/human/proc/calculate_item_encumbrance() + if(!buckled && shoes) // Shoes can make you go faster. + . += shoes.slowdown + + // Loop through some slots, and add up their slowdowns. + // Includes slots which can provide armor, the back slot, and suit storage. + for(var/obj/item/I in list(wear_suit, w_uniform, back, gloves, head, s_store)) + . += I.slowdown + + // Hands are also included, to make the 'take off your armor instantly and carry it with you to go faster' trick no longer viable. + // This is done seperately to disallow negative numbers (so you can't hold shoes in your hands to go faster). + for(var/obj/item/I in list(r_hand, l_hand) ) + . += max(I.slowdown, 0) + +// Similar to above, but for turf slowdown. +/mob/living/carbon/human/proc/calculate_turf_slowdown(turf/T) + if(T && T.movement_cost) + var/turf_move_cost = T.movement_cost + if(istype(T, /turf/simulated/floor/water)) + if(species.water_movement) + turf_move_cost = CLAMP(HUMAN_LOWEST_SLOWDOWN, turf_move_cost + species.water_movement, 15) + if(shoes) + var/obj/item/clothing/shoes/feet = shoes + if(feet.water_speed) + turf_move_cost = CLAMP(HUMAN_LOWEST_SLOWDOWN, turf_move_cost + feet.water_speed, 15) + . += turf_move_cost + if(istype(T, /turf/simulated/floor/outdoors/snow)) + if(species.snow_movement) + turf_move_cost = CLAMP(HUMAN_LOWEST_SLOWDOWN, turf_move_cost + species.snow_movement, 15) + if(shoes) + var/obj/item/clothing/shoes/feet = shoes + if(feet.water_speed) + turf_move_cost = CLAMP(HUMAN_LOWEST_SLOWDOWN, turf_move_cost + feet.snow_speed, 15) + . += turf_move_cost + +#undef HUMAN_LOWEST_SLOWDOWN /mob/living/carbon/human/Process_Spacemove(var/check_drift = 0) //Can we act? diff --git a/code/modules/mob/living/carbon/human/human_powers.dm b/code/modules/mob/living/carbon/human/human_powers.dm index 66f5d2c713..809a5ef8ad 100644 --- a/code/modules/mob/living/carbon/human/human_powers.dm +++ b/code/modules/mob/living/carbon/human/human_powers.dm @@ -293,6 +293,7 @@ // Replace completely missing limbs. for(var/limb_type in src.species.has_limbs) var/obj/item/organ/external/E = src.organs_by_name[limb_type] + if(E && E.disfigured) E.disfigured = 0 if(E && (E.is_stump() || (E.status & (ORGAN_DESTROYED|ORGAN_DEAD|ORGAN_MUTATED)))) @@ -305,6 +306,10 @@ var/obj/item/organ/O = new limb_path(src) organ_data["descriptor"] = O.name to_chat(src, "You feel a slithering sensation as your [O.name] reform.") + + var/agony_to_apply = round(0.66 * O.max_damage) // 66% of the limb's health is converted into pain. + src.apply_damage(agony_to_apply, HALLOSS) + update_icons_body() active_regen = FALSE else diff --git a/code/modules/mob/living/carbon/human/human_resist.dm b/code/modules/mob/living/carbon/human/human_resist.dm new file mode 100644 index 0000000000..37e20d0d21 --- /dev/null +++ b/code/modules/mob/living/carbon/human/human_resist.dm @@ -0,0 +1,120 @@ +/mob/living/carbon/human/process_resist() + //drop && roll + if(on_fire && !buckled) + adjust_fire_stacks(-1.2) + Weaken(3) + spin(32,2) + visible_message( + "[src] rolls on the floor, trying to put themselves out!", + "You stop, drop, and roll!" + ) + sleep(30) + if(fire_stacks <= 0) + visible_message( + "[src] has successfully extinguished themselves!", + "You extinguish yourself." + ) + ExtinguishMob() + return TRUE + + if(handcuffed) + spawn() escape_handcuffs() + else if(legcuffed) + spawn() escape_legcuffs() + else if(wear_suit && istype(wear_suit, /obj/item/clothing/suit/straight_jacket)) + spawn() escape_straight_jacket() + else + ..() + +#define RESIST_ATTACK_DEFAULT 0 +#define RESIST_ATTACK_CLAWS 1 +#define RESIST_ATTACK_BITE 2 + +/mob/living/carbon/human/proc/escape_straight_jacket() + setClickCooldown(100) + + if(can_break_straight_jacket()) + break_straight_jacket() + return + + var/mob/living/carbon/human/H = src + var/obj/item/clothing/suit/straight_jacket/SJ = H.wear_suit + + var/breakouttime = SJ.resist_time // Configurable per-jacket! + + var/attack_type = RESIST_ATTACK_DEFAULT + + if(H.gloves && istype(H.gloves,/obj/item/clothing/gloves/gauntlets/rig)) + breakouttime /= 2 // Pneumatic force goes a long way. + else if(H.species.unarmed_types) + for(var/datum/unarmed_attack/U in H.species.unarmed_types) + if(istype(U, /datum/unarmed_attack/claws)) + breakouttime /= 1.5 + attack_type = RESIST_ATTACK_CLAWS + break + else if(istype(U, /datum/unarmed_attack/bite/sharp)) + breakouttime /= 1.25 + attack_type = RESIST_ATTACK_BITE + break + + switch(attack_type) + if(RESIST_ATTACK_DEFAULT) + visible_message( + "\The [src] struggles to remove \the [SJ]!", + "You struggle to remove \the [SJ]. (This will take around [round(breakouttime / 600)] minutes and you need to stand still.)" + ) + if(RESIST_ATTACK_CLAWS) + visible_message( + "\The [src] starts clawing at \the [SJ]!", + "You claw at \the [SJ]. (This will take around [round(breakouttime / 600)] minutes and you need to stand still.)" + ) + if(RESIST_ATTACK_BITE) + visible_message( + "\The [src] starts gnawing on \the [SJ]!", + "You gnaw on \the [SJ]. (This will take around [round(breakouttime / 600)] minutes and you need to stand still.)" + ) + + if(do_after(src, breakouttime, incapacitation_flags = INCAPACITATION_DISABLED & INCAPACITATION_KNOCKDOWN)) + if(!wear_suit) + return + visible_message( + "\The [src] manages to remove \the [wear_suit]!", + "You successfully remove \the [wear_suit]." + ) + drop_from_inventory(wear_suit) + +#undef RESIST_ATTACK_DEFAULT +#undef RESIST_ATTACK_CLAWS +#undef RESIST_ATTACK_BITE + +/mob/living/carbon/human/proc/can_break_straight_jacket() + if((HULK in mutations) || species.can_shred(src,1)) + return 1 + return ..() + +/mob/living/carbon/human/proc/break_straight_jacket() + visible_message( + "[src] is trying to rip \the [wear_suit]!", + "You attempt to rip your [wear_suit.name] apart. (This will take around 5 seconds and you need to stand still)" + ) + + if(do_after(src, 20 SECONDS, incapacitation_flags = INCAPACITATION_DEFAULT & ~INCAPACITATION_RESTRAINED)) // Same scaling as breaking cuffs, 5 seconds to 120 seconds, 20 seconds to 480 seconds. + if(!wear_suit || buckled) + return + + visible_message( + "[src] manages to rip \the [wear_suit]!", + "You successfully rip your [wear_suit.name]." + ) + + say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!", "RAAAAAAAARGH!", "HNNNNNNNNNGGGGGGH!", "GWAAAAAAAARRRHHH!", "AAAAAAARRRGH!" )) + + qdel(wear_suit) + wear_suit = null + if(buckled && buckled.buckle_require_restraints) + buckled.unbuckle_mob() + +/mob/living/carbon/human/can_break_cuffs() + if(species.can_shred(src,1)) + return 1 + return ..() diff --git a/code/modules/mob/living/carbon/human/human_species.dm b/code/modules/mob/living/carbon/human/human_species.dm index 367a00b5d5..69fbb201c2 100644 --- a/code/modules/mob/living/carbon/human/human_species.dm +++ b/code/modules/mob/living/carbon/human/human_species.dm @@ -3,54 +3,50 @@ status_flags = GODMODE|CANPUSH has_huds = FALSE -/mob/living/carbon/human/dummy/mannequin/New() - ..() +/mob/living/carbon/human/dummy/mannequin/Initialize() + . = ..() mob_list -= src living_mob_list -= src dead_mob_list -= src delete_inventory() -/mob/living/carbon/human/skrell/New(var/new_loc) +/mob/living/carbon/human/skrell/Initialize(var/new_loc) h_style = "Skrell Short Tentacles" - ..(new_loc, SPECIES_SKRELL) + return ..(new_loc, SPECIES_SKRELL) -/mob/living/carbon/human/tajaran/New(var/new_loc) +/mob/living/carbon/human/tajaran/Initialize(var/new_loc) h_style = "Tajaran Ears" - ..(new_loc, SPECIES_TAJ) + return ..(new_loc, SPECIES_TAJ) -/mob/living/carbon/human/unathi/New(var/new_loc) +/mob/living/carbon/human/unathi/Initialize(var/new_loc) h_style = "Unathi Horns" - ..(new_loc, SPECIES_UNATHI) + return ..(new_loc, SPECIES_UNATHI) -/mob/living/carbon/human/vox/New(var/new_loc) +/mob/living/carbon/human/vox/Initialize(var/new_loc) h_style = "Short Vox Quills" - ..(new_loc, SPECIES_VOX) + return ..(new_loc, SPECIES_VOX) -/mob/living/carbon/human/diona/New(var/new_loc) - ..(new_loc, SPECIES_DIONA) +/mob/living/carbon/human/diona/Initialize(var/new_loc) + return ..(new_loc, SPECIES_DIONA) -/mob/living/carbon/human/teshari/New(var/new_loc) +/mob/living/carbon/human/teshari/Initialize(var/new_loc) h_style = "Teshari Default" - ..(new_loc, SPECIES_TESHARI) + return ..(new_loc, SPECIES_TESHARI) -/mob/living/carbon/human/promethean/New(var/new_loc) - ..(new_loc, SPECIES_PROMETHEAN) +/mob/living/carbon/human/promethean/Initialize(var/new_loc) + return ..(new_loc, SPECIES_PROMETHEAN) -/mob/living/carbon/human/machine/New(var/new_loc) - h_style = "blue IPC screen" - ..(new_loc, "Machine") +/mob/living/carbon/human/monkey/Initialize(var/new_loc) + return ..(new_loc, SPECIES_MONKEY) -/mob/living/carbon/human/monkey/New(var/new_loc) - ..(new_loc, SPECIES_MONKEY) +/mob/living/carbon/human/farwa/Initialize(var/new_loc) + return ..(new_loc, SPECIES_MONKEY_TAJ) -/mob/living/carbon/human/farwa/New(var/new_loc) - ..(new_loc, SPECIES_MONKEY_TAJ) +/mob/living/carbon/human/neaera/Initialize(var/new_loc) + return ..(new_loc, SPECIES_MONKEY_SKRELL) -/mob/living/carbon/human/neaera/New(var/new_loc) - ..(new_loc, SPECIES_MONKEY_SKRELL) +/mob/living/carbon/human/stok/Initialize(var/new_loc) + return ..(new_loc, SPECIES_MONKEY_UNATHI) -/mob/living/carbon/human/stok/New(var/new_loc) - ..(new_loc, SPECIES_MONKEY_UNATHI) - -/mob/living/carbon/human/event1/New(var/new_loc) - ..(new_loc, SPECIES_EVENT1) +/mob/living/carbon/human/event1/Initialize(var/new_loc) + return ..(new_loc, SPECIES_EVENT1) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 8a4fe6a18b..f3d86e9f76 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -104,15 +104,27 @@ if(!inStasisNow()) ..() -// Calculate how vulnerable the human is to under- and overpressure. -// Returns 0 (equals 0 %) if sealed in an undamaged suit, 1 if unprotected (equals 100%). +// Calculate how vulnerable the human is to the current pressure. +// Returns 0 (equals 0 %) if sealed in an undamaged suit that's rated for the pressure, 1 if unprotected (equals 100%). // Suitdamage can modifiy this in 10% steps. -/mob/living/carbon/human/proc/get_pressure_weakness() +// Protection scales down from 100% at the boundary to 0% at 10% in excess of the boundary +/mob/living/carbon/human/proc/get_pressure_weakness(pressure) + if(pressure == null) + return 1 // No protection if someone forgot to give a pressure var/pressure_adjustment_coefficient = 1 // Assume no protection at first. - if(wear_suit && (wear_suit.item_flags & STOPPRESSUREDAMAGE) && head && (head.item_flags & STOPPRESSUREDAMAGE)) // Complete set of pressure-proof suit worn, assume fully sealed. + // Check suit + if(wear_suit && wear_suit.max_pressure_protection != null && wear_suit.min_pressure_protection != null) pressure_adjustment_coefficient = 0 + // Pressure is too high + if(wear_suit.max_pressure_protection < pressure) + // Protection scales down from 100% at the boundary to 0% at 10% in excess of the boundary + pressure_adjustment_coefficient += round((pressure - wear_suit.max_pressure_protection) / (wear_suit.max_pressure_protection/10)) + + // Pressure is too low + if(wear_suit.min_pressure_protection > pressure) + pressure_adjustment_coefficient += round((wear_suit.min_pressure_protection - pressure) / (wear_suit.min_pressure_protection/10)) // Handles breaches in your space suit. 10 suit damage equals a 100% loss of pressure protection. if(istype(wear_suit,/obj/item/clothing/suit/space)) @@ -120,8 +132,26 @@ if(S.can_breach && S.damage) pressure_adjustment_coefficient += S.damage * 0.1 - pressure_adjustment_coefficient = min(1,max(pressure_adjustment_coefficient,0)) // So it isn't less than 0 or larger than 1. + else + // Missing key protection + pressure_adjustment_coefficient = 1 + // Check hat + if(head && head.max_pressure_protection != null && head.min_pressure_protection != null) + // Pressure is too high + if(head.max_pressure_protection < pressure) + // Protection scales down from 100% at the boundary to 0% at 20% in excess of the boundary + pressure_adjustment_coefficient += round((pressure - head.max_pressure_protection) / (head.max_pressure_protection/20)) + + // Pressure is too low + if(head.min_pressure_protection > pressure) + pressure_adjustment_coefficient += round((head.min_pressure_protection - pressure) / (head.min_pressure_protection/20)) + + else + // Missing key protection + pressure_adjustment_coefficient = 1 + + pressure_adjustment_coefficient = min(pressure_adjustment_coefficient, 1) return pressure_adjustment_coefficient // Calculate how much of the enviroment pressure-difference affects the human. @@ -141,7 +171,7 @@ else // Otherwise calculate how much of that absolute pressure difference affects us, can be 0 to 1 (equals 0% to 100%). // This is our relative difference. - pressure_difference *= get_pressure_weakness() + pressure_difference *= get_pressure_weakness(pressure) // The difference is always positive to avoid extra calculations. // Apply the relative difference on a standard atmosphere to get the final result. @@ -227,7 +257,7 @@ if(gene.is_active(src)) gene.OnMobLife(src) - radiation = Clamp(radiation,0,250) + radiation = CLAMP(radiation,0,250) if(!radiation) if(species.appearance_flags & RADIATION_GLOWS) @@ -486,7 +516,7 @@ if(toxins_pp > safe_toxins_max) var/ratio = (poison/safe_toxins_max) * 10 if(reagents) - reagents.add_reagent("toxin", Clamp(ratio, MIN_TOXIN_DAMAGE, MAX_TOXIN_DAMAGE)) + reagents.add_reagent("toxin", CLAMP(ratio, MIN_TOXIN_DAMAGE, MAX_TOXIN_DAMAGE)) breath.adjust_gas(poison_type, -poison/6, update = 0) //update after phoron_alert = max(phoron_alert, 1) else @@ -674,7 +704,8 @@ // 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! - if(status_flags & GODMODE) return 1 //godmode + if(status_flags & GODMODE) + return 1 //godmode if(adjusted_pressure >= species.hazard_high_pressure) var/pressure_damage = min( ( (adjusted_pressure / species.hazard_high_pressure) -1 )*PRESSURE_DAMAGE_COEFFICIENT , MAX_HIGH_PRESSURE_DAMAGE) @@ -690,8 +721,19 @@ if( !(COLD_RESISTANCE in mutations)) if(!isSynthetic() || !nif || !nif.flag_check(NIF_O_PRESSURESEAL,NIF_FLAGS_OTHER)) //VOREStation Edit - NIF pressure seals take_overall_damage(brute=LOW_PRESSURE_DAMAGE, used_weapon = "Low Pressure") - if(getOxyLoss() < 55) // 11 OxyLoss per 4 ticks when wearing internals; unconsciousness in 16 ticks, roughly half a minute - adjustOxyLoss(4) // 16 OxyLoss per 4 ticks when no internals present; unconsciousness in 13 ticks, roughly twenty seconds + if(getOxyLoss() < 55) // 12 OxyLoss per 4 ticks when wearing internals; unconsciousness in 16 ticks, roughly half a minute + var/pressure_dam = 3 // 16 OxyLoss per 4 ticks when no internals present; unconsciousness in 13 ticks, roughly twenty seconds + // (Extra 1 oxyloss from failed breath) + // Being in higher pressure decreases the damage taken, down to a minimum of (species.hazard_low_pressure / ONE_ATMOSPHERE) at species.hazard_low_pressure + pressure_dam *= (ONE_ATMOSPHERE - adjusted_pressure) / ONE_ATMOSPHERE + + if(wear_suit && wear_suit.min_pressure_protection && head && head.min_pressure_protection) + var/protection = max(wear_suit.min_pressure_protection, head.min_pressure_protection) // Take the weakest protection + pressure_dam *= (protection) / (ONE_ATMOSPHERE) // Divide by ONE_ATMOSPHERE to get a fractional protection + // Stronger protection (Closer to 0) results in a smaller fraction + // Firesuits (Min protection = 0.2 atmospheres) decrease oxyloss to 1/5 + + adjustOxyLoss(pressure_dam) pressure_alert = -2 else pressure_alert = -1 @@ -1047,8 +1089,6 @@ sleeping += 1 Paralyse(5) - confused = max(0, confused - 1) - // If you're dirty, your gloves will become dirty, too. if(gloves && germ_level > gloves.germ_level && prob(10)) gloves.germ_level += 1 @@ -1602,7 +1642,7 @@ else if(foundVirus) holder.icon_state = "hudill" else if(has_brain_worms()) - var/mob/living/simple_animal/borer/B = has_brain_worms() + var/mob/living/simple_mob/animal/borer/B = has_brain_worms() if(B.controlling) holder.icon_state = "hudbrainworm" else diff --git a/code/modules/mob/living/carbon/human/npcs.dm b/code/modules/mob/living/carbon/human/npcs.dm index 0457c7b584..3c0609f99b 100644 --- a/code/modules/mob/living/carbon/human/npcs.dm +++ b/code/modules/mob/living/carbon/human/npcs.dm @@ -5,12 +5,9 @@ worn_state = "punpun" species_restricted = list("Monkey") -/mob/living/carbon/human/monkey/punpun/New() - spawn(1) - // VoreStation Edit - Move Constructor inside Spawn - ..() - // End Vore Station Edit - name = "Pun Pun" - real_name = name - w_uniform = new /obj/item/clothing/under/punpun(src) - regenerate_icons() +/mob/living/carbon/human/monkey/punpun/Initialize() + . = ..() + name = "Pun Pun" + real_name = name + w_uniform = new /obj/item/clothing/under/punpun(src) + regenerate_icons() diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm index d42c26880b..fab28e45b4 100644 --- a/code/modules/mob/living/carbon/human/say.dm +++ b/code/modules/mob/living/carbon/human/say.dm @@ -64,11 +64,11 @@ return 1 if (istype(other, /mob/living/carbon/brain)) return 1 - if (istype(other, /mob/living/simple_animal/slime)) + if (istype(other, /mob/living/simple_mob/slime)) return 1 //This is already covered by mob/say_understands() - //if (istype(other, /mob/living/simple_animal)) + //if (istype(other, /mob/living/simple_mob)) // if((other.universal_speak && !speaking) || src.universal_speak || src.universal_understand) // return 1 // return 0 @@ -83,13 +83,16 @@ // todo: fix this shit if(rig.speech && rig.speech.voice_holder && rig.speech.voice_holder.active && rig.speech.voice_holder.voice) voice_sub = rig.speech.voice_holder.voice - else + if(!voice_sub) // If the rig has a voice changer, then we use that. Otherwise, use this 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(changer && changer.active) + if(changer.voice) + voice_sub = changer.voice + else + voice_sub = get_id_name() if(voice_sub) return voice_sub if(mind && mind.changeling && mind.changeling.mimicing) diff --git a/code/modules/mob/living/carbon/human/species/species_attack.dm b/code/modules/mob/living/carbon/human/species/species_attack.dm index 2654715f74..9e6a07d168 100644 --- a/code/modules/mob/living/carbon/human/species/species_attack.dm +++ b/code/modules/mob/living/carbon/human/species/species_attack.dm @@ -27,7 +27,7 @@ var/datum/gender/T = gender_datums[user.get_visible_gender()] var/datum/gender/TT = gender_datums[target.get_visible_gender()] if(!skill) skill = 1 - attack_damage = Clamp(attack_damage, 1, 5) + attack_damage = CLAMP(attack_damage, 1, 5) if(target == user) user.visible_message("[user] [pick(attack_verb)] [T.himself] in the [affecting.name]!") diff --git a/code/modules/mob/living/carbon/human/species/species_attack_vr.dm b/code/modules/mob/living/carbon/human/species/species_attack_vr.dm index f7e1e43e31..658a453afc 100644 --- a/code/modules/mob/living/carbon/human/species/species_attack_vr.dm +++ b/code/modules/mob/living/carbon/human/species/species_attack_vr.dm @@ -9,7 +9,7 @@ /datum/unarmed_attack/bite/sharp/numbing/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage) var/obj/item/organ/external/affecting = target.get_organ(zone) - attack_damage = Clamp(attack_damage, 1, 5) + attack_damage = CLAMP(attack_damage, 1, 5) if(target == user) user.visible_message("[user] [pick(attack_verb)] \himself in the [affecting.name]!") return 0 //No venom for you. diff --git a/code/modules/mob/living/carbon/human/species/station/alraune.dm b/code/modules/mob/living/carbon/human/species/station/alraune.dm index 8b5099b222..55e6215fc7 100644 --- a/code/modules/mob/living/carbon/human/species/station/alraune.dm +++ b/code/modules/mob/living/carbon/human/species/station/alraune.dm @@ -111,7 +111,7 @@ var/fullysealed = FALSE //if they're wearing a fully sealed suit, their internals take priority. var/environmentalair = FALSE //if no sealed suit, internals take priority in low pressure environements - if(H.wear_suit && (H.wear_suit.item_flags & STOPPRESSUREDAMAGE) && H.head && (H.head.item_flags & STOPPRESSUREDAMAGE)) + if(H.wear_suit && (H.wear_suit.min_pressure_protection = 0) && H.head && (H.head.min_pressure_protection = 0)) fullysealed = TRUE else // find out if local gas mixture is enough to override use of internals var/datum/gas_mixture/environment = H.loc.return_air() @@ -207,7 +207,7 @@ var/co2buff = 0 if(inhaling) - co2buff = (Clamp(inhale_pp, 0, minimum_breath_pressure))/minimum_breath_pressure //returns a value between 0 and 1. + co2buff = (CLAMP(inhale_pp, 0, minimum_breath_pressure))/minimum_breath_pressure //returns a value between 0 and 1. var/light_amount = fullysealed ? H.getlightlevel() : H.getlightlevel()/5 // if they're covered, they're not going to get much light on them. @@ -222,7 +222,7 @@ if(toxins_pp > safe_toxins_max) var/ratio = (poison/safe_toxins_max) * 10 if(H.reagents) - H.reagents.add_reagent("toxin", Clamp(ratio, MIN_TOXIN_DAMAGE, MAX_TOXIN_DAMAGE)) + H.reagents.add_reagent("toxin", CLAMP(ratio, MIN_TOXIN_DAMAGE, MAX_TOXIN_DAMAGE)) breath.adjust_gas(poison_type, -poison/6, update = 0) //update after H.phoron_alert = max(H.phoron_alert, 1) else diff --git a/code/modules/mob/living/carbon/human/species/station/prometheans.dm b/code/modules/mob/living/carbon/human/species/station/prometheans.dm index b78d530707..c821acfa32 100644 --- a/code/modules/mob/living/carbon/human/species/station/prometheans.dm +++ b/code/modules/mob/living/carbon/human/species/station/prometheans.dm @@ -30,6 +30,7 @@ var/datum/species/shapeshifter/promethean/prometheans health_hud_intensity = 2 num_alternate_languages = 3 species_language = LANGUAGE_SOL_COMMON + secondary_langs = list(LANGUAGE_SOL_COMMON) // For some reason, having this as their species language does not allow it to be chosen. assisted_langs = list(LANGUAGE_ROOTGLOBAL, LANGUAGE_VOX) // Prometheans are weird, let's just assume they can use basically any language. breath_type = null @@ -116,7 +117,7 @@ var/datum/species/shapeshifter/promethean/prometheans /datum/species/shapeshifter/promethean/equip_survival_gear(var/mob/living/carbon/human/H) var/boxtype = pick(typesof(/obj/item/weapon/storage/toolbox/lunchbox)) var/obj/item/weapon/storage/toolbox/lunchbox/L = new boxtype(get_turf(H)) - var/mob/living/simple_animal/mouse/mouse = new (L) + var/mob/living/simple_mob/animal/passive/mouse/mouse = new (L) var/obj/item/weapon/holder/holder = new (L) mouse.forceMove(holder) holder.sync(mouse) @@ -153,7 +154,11 @@ var/datum/species/shapeshifter/promethean/prometheans H.gib() /datum/species/shapeshifter/promethean/handle_environment_special(var/mob/living/carbon/human/H) -/* VOREStation Removal - Too crazy with our uncapped hunger and slowdown stuff. + var/regen_brute = 1 + var/regen_burn = 1 + var/regen_tox = 1 + var/regen_oxy = 1 + var/turf/T = H.loc if(istype(T)) var/obj/effect/decal/cleanable/C = locate() in T @@ -162,33 +167,53 @@ var/datum/species/shapeshifter/promethean/prometheans if (istype(T, /turf/simulated)) var/turf/simulated/S = T S.dirt = 0 + H.nutrition = max(H.nutrition, min(500, H.nutrition + rand(15, 30))) //VOREStation Edit: Gives nutrition up to a point instead of being capped + + T = get_turf(H) // Swap over to an actual turf, because we need to get the pressure. + if(istype(T)) // Make sure it exists, and is a turf again. + var/datum/gas_mixture/environment = T.return_air() + var/pressure = environment.return_pressure() + var/affecting_pressure = H.calculate_affecting_pressure(pressure) + if(affecting_pressure <= hazard_low_pressure) // Dangerous low pressure stops the regeneration of physical wounds. Body is focusing on keeping them intact rather than sealing. + regen_brute = 0 + regen_burn = 0 - H.nutrition = min(500, max(0, H.nutrition + rand(15, 30))) -VOREStation Removal End */ // Heal remaining damage. if(H.fire_stacks >= 0) if(H.getBruteLoss() || H.getFireLoss() || H.getOxyLoss() || H.getToxLoss()) var/nutrition_cost = 0 - var/nutrition_debt = H.getBruteLoss() + var/nutrition_debt = 0 var/starve_mod = 1 if(H.nutrition <= 25) starve_mod = 0.75 - H.adjustBruteLoss(-heal_rate * starve_mod) - nutrition_cost += nutrition_debt - H.getBruteLoss() - nutrition_debt = H.getFireLoss() - H.adjustFireLoss(-heal_rate * starve_mod) - nutrition_cost += nutrition_debt - H.getFireLoss() + if(regen_brute) + nutrition_debt = H.getBruteLoss() + H.adjustBruteLoss(-heal_rate * starve_mod) + nutrition_cost += nutrition_debt - H.getBruteLoss() - nutrition_debt = H.getOxyLoss() - H.adjustOxyLoss(-heal_rate * starve_mod) - nutrition_cost += nutrition_debt - H.getOxyLoss() + if(regen_burn) + nutrition_debt = H.getFireLoss() + H.adjustFireLoss(-heal_rate * starve_mod) + nutrition_cost += nutrition_debt - H.getFireLoss() - nutrition_debt = H.getToxLoss() - H.adjustToxLoss(-heal_rate * starve_mod) - nutrition_cost += nutrition_debt - H.getToxLoss() - H.nutrition -= (2 * nutrition_cost) //Costs Nutrition when damage is being repaired, corresponding to the amount of damage being repaired. + if(regen_oxy) + nutrition_debt = H.getOxyLoss() + H.adjustOxyLoss(-heal_rate * starve_mod) + nutrition_cost += nutrition_debt - H.getOxyLoss() + + if(regen_tox) + nutrition_debt = H.getToxLoss() + H.adjustToxLoss(-heal_rate * starve_mod) + nutrition_cost += nutrition_debt - H.getToxLoss() + + H.nutrition -= (3 * nutrition_cost) //Costs Nutrition when damage is being repaired, corresponding to the amount of damage being repaired. H.nutrition = max(0, H.nutrition) //Ensure it's not below 0. + + var/agony_to_apply = ((1 / starve_mod) * nutrition_cost) //Regenerating damage causes minor pain over time. Small injures will be no issue, large ones will cause problems. + if((H.getHalLoss() + agony_to_apply) <= 70) // Don't permalock, but make it far easier to knock them down. + H.apply_damage(agony_to_apply, HALLOSS) + //else//VOREStation Removal //H.adjustToxLoss(2*heal_rate) // Doubled because 0.5 is miniscule, and fire_stacks are capped in both directions diff --git a/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_blob.dm b/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_blob.dm index e3cf1d7042..9e07ba48ef 100644 --- a/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_blob.dm +++ b/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_blob.dm @@ -1,5 +1,5 @@ // Simple animal nanogoopeyness -/mob/living/simple_animal/protean_blob +/mob/living/simple_mob/protean_blob name = "protean blob" desc = "Some sort of big viscous pool of jelly." tt_desc = "Animated nanogoop" @@ -12,8 +12,9 @@ faction = "neutral" maxHealth = 200 health = 200 + say_list_type = /datum/say_list/protean_blob - ai_inactive = TRUE //Always off + // ai_inactive = TRUE //Always off //VORESTATION AI TEMPORARY REMOVAL show_stat_health = FALSE //We will do it ourselves response_help = "pats the" @@ -36,11 +37,6 @@ minbodytemp = 0 maxbodytemp = 900 - speak_chance = 1 - speak = list("Blrb?","Sqrsh.","Glrsh!") - emote_hear = list("squishes softly","spluts quietly","makes wet noises") - emote_see = list("shifts wetly","undulates placidly") - var/mob/living/carbon/human/humanform var/obj/item/organ/internal/nano/refactory/refactory var/datum/modifier/healing @@ -52,8 +48,13 @@ can_buckle = TRUE //Blobsurfing +/datum/say_list/protean_blob + speak = list("Blrb?","Sqrsh.","Glrsh!") + emote_hear = list("squishes softly","spluts quietly","makes wet noises") + emote_see = list("shifts wetly","undulates placidly") + //Constructor allows passing the human to sync damages -/mob/living/simple_animal/protean_blob/New(var/newloc, var/mob/living/carbon/human/H) +/mob/living/simple_mob/protean_blob/New(var/newloc, var/mob/living/carbon/human/H) ..() if(H) humanform = H @@ -64,7 +65,7 @@ else update_icon() -/mob/living/simple_animal/protean_blob/Destroy() +/mob/living/simple_mob/protean_blob/Destroy() humanform = null refactory = null vore_organs = null @@ -73,15 +74,15 @@ healing.expire() return ..() -/mob/living/simple_animal/protean_blob/init_vore() +/mob/living/simple_mob/protean_blob/init_vore() return //Don't make a random belly, don't waste your time -/mob/living/simple_animal/protean_blob/Stat() +/mob/living/simple_mob/protean_blob/Stat() ..() if(humanform) humanform.species.Stat(humanform) -/mob/living/simple_animal/protean_blob/update_icon() +/mob/living/simple_mob/protean_blob/update_icon() if(humanform) //Still have a refactory if(istype(refactory)) @@ -97,7 +98,7 @@ ..() -/mob/living/simple_animal/protean_blob/updatehealth() +/mob/living/simple_mob/protean_blob/updatehealth() if(humanform) //Set the max maxHealth = humanform.getMaxHealth()*2 //HUMANS, and their 'double health', bleh. @@ -136,19 +137,19 @@ else ..() -/mob/living/simple_animal/protean_blob/adjustBruteLoss(var/amount) +/mob/living/simple_mob/protean_blob/adjustBruteLoss(var/amount) if(humanform) humanform.adjustBruteLoss(amount) else ..() -/mob/living/simple_animal/protean_blob/adjustFireLoss(var/amount) +/mob/living/simple_mob/protean_blob/adjustFireLoss(var/amount) if(humanform) humanform.adjustFireLoss(amount) else ..() -/mob/living/simple_animal/protean_blob/death(gibbed, deathmessage = "dissolves away, leaving only a few spare parts!") +/mob/living/simple_mob/protean_blob/death(gibbed, deathmessage = "dissolves away, leaving only a few spare parts!") if(humanform) humanform.death(gibbed = gibbed) for(var/organ in humanform.internal_organs) @@ -168,7 +169,7 @@ ..() -/mob/living/simple_animal/protean_blob/Life() +/mob/living/simple_mob/protean_blob/Life() . = ..() if(. && istype(refactory) && humanform) if(!healing && health < maxHealth && refactory.get_stored_material(DEFAULT_WALL_MATERIAL) >= 100) @@ -177,7 +178,7 @@ healing.expire() healing = null -/mob/living/simple_animal/protean_blob/lay_down() +/mob/living/simple_mob/protean_blob/lay_down() ..() if(resting) animate(src,alpha = 40,time = 1 SECOND) @@ -199,7 +200,7 @@ target.forceMove(vore_selected) to_chat(target,"\The [src] quickly engulfs you, [vore_selected.vore_verb]ing you into their [vore_selected.name]!") -/mob/living/simple_animal/protean_blob/DoPunch(var/atom/A) +/mob/living/simple_mob/protean_blob/attack_hand(var/atom/A) //VORESTATION AI TEMPORARY REMOVAL (Marking this as such even though it was an edit.) if(refactory && istype(A,/obj/item/stack/material)) var/obj/item/stack/material/S = A var/substance = S.material.name @@ -214,7 +215,7 @@ else return ..() -/mob/living/simple_animal/protean_blob/attackby(var/obj/item/O, var/mob/user) +/mob/living/simple_mob/protean_blob/attackby(var/obj/item/O, var/mob/user) if(refactory && istype(O,/obj/item/stack/material)) var/obj/item/stack/material/S = O var/substance = S.material.name @@ -229,7 +230,7 @@ else return ..() -/mob/living/simple_animal/protean_blob/MouseEntered(location,control,params) +/mob/living/simple_mob/protean_blob/MouseEntered(location,control,params) if(resting) return ..() @@ -251,12 +252,12 @@ var/atom/creation_spot = drop_location() //Create our new blob - var/mob/living/simple_animal/protean_blob/blob = new(creation_spot,src) + var/mob/living/simple_mob/protean_blob/blob = new(creation_spot,src) //Drop all our things var/list/things_to_drop = contents.Copy() var/list/things_to_not_drop = list(w_uniform,nif,l_store,r_store,wear_id,l_ear,r_ear) //And whatever else we decide for balancing. - + /* No for now, because insta-pepperspray or flash on unblob if(l_hand && l_hand.w_class <= ITEMSIZE_SMALL) //Hands but only if small or smaller things_to_not_drop += l_hand @@ -267,7 +268,7 @@ things_to_drop -= things_to_not_drop //Crunch the lists things_to_drop -= organs //Mah armbs things_to_drop -= internal_organs //Mah sqeedily spooch - + for(var/obj/item/I in things_to_drop) //rip hoarders drop_from_inventory(I) @@ -316,7 +317,7 @@ if(istype(I, /obj/item/weapon/holder)) root.remove_from_mob(I) -/mob/living/carbon/human/proc/nano_outofblob(var/mob/living/simple_animal/protean_blob/blob) +/mob/living/carbon/human/proc/nano_outofblob(var/mob/living/simple_mob/protean_blob/blob) if(!istype(blob)) return if(buckled) diff --git a/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_powers.dm b/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_powers.dm index d6f65e6f63..3b7f99c8e7 100644 --- a/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_powers.dm +++ b/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_powers.dm @@ -38,7 +38,7 @@ oldlimb.removed() qdel(oldlimb) - var/mob/living/simple_animal/protean_blob/blob = nano_intoblob() + var/mob/living/simple_mob/protean_blob/blob = nano_intoblob() active_regen = TRUE if(do_after(blob,5 SECONDS)) var/list/limblist = species.has_limbs[choice] @@ -128,7 +128,7 @@ to_chat(src, "Remain still while the process takes place! It will take 5 seconds.") visible_message("[src]'s form collapses into an amorphous blob of black ichor...") - var/mob/living/simple_animal/protean_blob/blob = nano_intoblob() + var/mob/living/simple_mob/protean_blob/blob = nano_intoblob() active_regen = TRUE if(do_after(blob,5 SECONDS)) synthetic = usable_manufacturers[manu_choice] @@ -149,7 +149,7 @@ visible_message("[src]'s form begins to shift and ripple as if made of oil...") active_regen = TRUE - var/mob/living/simple_animal/protean_blob/blob = nano_intoblob() + var/mob/living/simple_mob/protean_blob/blob = nano_intoblob() if(do_after(blob, delay_length, null, 0)) if(stat != DEAD && refactory) var/list/holder = refactory.materials @@ -213,7 +213,7 @@ return //Quietly fail var/actually_added = refactory.add_stored_material(substance,howmuch*matstack.perunit) - matstack.use(Ceiling(actually_added/matstack.perunit)) + matstack.use(CEILING((actually_added/matstack.perunit), 1)) if(actually_added && actually_added < howmuch) to_chat(src,"Your refactory module is now full, so only [actually_added] units were stored.") visible_message("[src] nibbles some of the [substance] right off the stack!") @@ -283,7 +283,7 @@ var/nagmessage = "Adjust your mass to be a size between 25 to 200%. Up-sizing consumes metal, downsizing returns metal." var/new_size = input(user, nagmessage, "Pick a Size", user.size_multiplier*100) as num|null - if(!new_size || !IsInRange(new_size,25,200)) + if(!new_size || !ISINRANGE(new_size,25,200)) return var/size_factor = new_size/100 @@ -319,7 +319,7 @@ return R return -/mob/living/simple_animal/protean_blob/nano_get_refactory() +/mob/living/simple_mob/protean_blob/nano_get_refactory() if(refactory) return ..(refactory) if(humanform) @@ -353,7 +353,7 @@ do_ability(usr) //Blobform using it else - var/mob/living/simple_animal/protean_blob/blob = usr + var/mob/living/simple_mob/protean_blob/blob = usr do_ability(blob.humanform) /obj/effect/protean_ability/proc/do_ability(var/mob/living/L) diff --git a/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_species.dm b/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_species.dm old mode 100644 new mode 100755 index 52aad66fcc..fd6db52eae --- a/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_species.dm +++ b/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_species.dm @@ -20,8 +20,7 @@ spawn_flags = SPECIES_CAN_JOIN | SPECIES_IS_WHITELISTED health_hud_intensity = 2 num_alternate_languages = 3 - species_language = LANGUAGE_SOL_COMMON - assisted_langs = list(LANGUAGE_EAL) + assisted_langs = list(LANGUAGE_ROOTLOCAL, LANGUAGE_ROOTGLOBAL, LANGUAGE_VOX) color_mult = TRUE breath_type = null diff --git a/code/modules/mob/living/carbon/human/species/station/station_special_abilities_vr.dm b/code/modules/mob/living/carbon/human/species/station/station_special_abilities_vr.dm index 9d038e9ee7..fadf7477f1 100644 --- a/code/modules/mob/living/carbon/human/species/station/station_special_abilities_vr.dm +++ b/code/modules/mob/living/carbon/human/species/station/station_special_abilities_vr.dm @@ -142,7 +142,10 @@ new /obj/effect/gibspawner/human/xenochimera(T) reviving = REVIVING_COOLDOWN - schedule_callback_in(1 HOUR, VARSET_CALLBACK(src, reviving, 0)) + addtimer(CALLBACK(src, .proc/revivingreset), 36000) + +/mob/living/carbon/human/proc/revivingreset() + reviving = 0 /obj/effect/gibspawner/human/xenochimera fleshcolor = "#14AD8B" @@ -260,9 +263,9 @@ if(8) src << 'sound/machines/windowdoor.ogg' if(9) //To make it more realistic, I added two gunshots (enough to kill) - src << 'sound/weapons/Gunshot.ogg' + src << 'sound/weapons/Gunshot1.ogg' spawn(rand(10,30)) - src << 'sound/weapons/Gunshot.ogg' + src << 'sound/weapons/Gunshot2.ogg' if(10) src << 'sound/weapons/smash.ogg' if(11) //Same as above, but with tasers. @@ -689,7 +692,7 @@ return ..(target) -/mob/living/simple_animal/can_shred(var/mob/living/carbon/human/target) +/mob/living/simple_mob/can_shred(var/mob/living/carbon/human/target) if(!target) var/list/choices = list() for(var/mob/living/carbon/human/M in oviewers(1)) diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_embryo.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_embryo.dm index f4022366a8..53d3576125 100644 --- a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_embryo.dm +++ b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_embryo.dm @@ -13,7 +13,7 @@ /obj/item/alien_embryo/New() if(istype(loc, /mob/living)) affected_mob = loc - processing_objects.Add(src) + START_PROCESSING(SSobj, src) spawn(0) AddInfectionImages(affected_mob) else @@ -30,7 +30,7 @@ if(!affected_mob) return if(loc != affected_mob) affected_mob.status_flags &= ~(XENO_HOST) - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) spawn(0) RemoveInfectionImages(affected_mob) affected_mob = null diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm index 549e888858..2684467147 100644 --- a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm +++ b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm @@ -1,6 +1,6 @@ //This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32 -//TODO: Make these simple_animals +//TODO: Make these simple_mobs /* //Commented out as reference for future reproduction methods, or addition later if needed. - Mech var/const/MIN_IMPREGNATION_TIME = 100 //time it takes to impregnate someone var/const/MAX_IMPREGNATION_TIME = 150 diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm index 0c8ca611fe..cc7cd7ef85 100644 --- a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm +++ b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm @@ -142,7 +142,8 @@ visible_message("[src] spits [spit_name] at \the [A]!", "You spit [spit_name] at \the [A].") var/obj/item/projectile/P = new spit_projectile(get_turf(src)) P.firer = src - P.launch(A) + P.old_style_target(A) + P.fire() playsound(loc, 'sound/weapons/pierce.ogg', 25, 0) else ..() diff --git a/code/modules/mob/living/carbon/human/unarmed_attack.dm b/code/modules/mob/living/carbon/human/unarmed_attack.dm index 6ec4ce2954..f3526983ef 100644 --- a/code/modules/mob/living/carbon/human/unarmed_attack.dm +++ b/code/modules/mob/living/carbon/human/unarmed_attack.dm @@ -139,7 +139,7 @@ var/global/list/sparring_attack_cache = list() var/datum/gender/TU = gender_datums[user.get_visible_gender()] var/datum/gender/TT = gender_datums[target.get_visible_gender()] - attack_damage = Clamp(attack_damage, 1, 5) // We expect damage input of 1 to 5 for this proc. But we leave this check juuust in case. + attack_damage = CLAMP(attack_damage, 1, 5) // We expect damage input of 1 to 5 for this proc. But we leave this check juuust in case. if(target == user) user.visible_message("[user] [pick(attack_verb)] [TU.himself] in the [organ]!") @@ -213,7 +213,7 @@ var/global/list/sparring_attack_cache = list() var/datum/gender/TT = gender_datums[target.get_visible_gender()] var/organ = affecting.name - attack_damage = Clamp(attack_damage, 1, 5) + attack_damage = CLAMP(attack_damage, 1, 5) switch(attack_damage) if(1 to 2) user.visible_message("[user] threw [target] a glancing [pick(attack_noun)] to the [organ]!") //it's not that they're kicking lightly, it's that the kick didn't quite connect @@ -259,7 +259,7 @@ var/global/list/sparring_attack_cache = list() var/obj/item/clothing/shoes = user.shoes var/datum/gender/TU = gender_datums[user.get_visible_gender()] - attack_damage = Clamp(attack_damage, 1, 5) + attack_damage = CLAMP(attack_damage, 1, 5) switch(attack_damage) if(1 to 4) user.visible_message("[pick("[user] stomped on", "[user] slammed [TU.his] [shoes ? copytext(shoes.name, 1, -1) : "foot"] down onto")] [target]'s [organ]!") diff --git a/code/modules/mob/living/carbon/metroid/items.dm b/code/modules/mob/living/carbon/metroid/items.dm index db66524a29..62a99850e1 100644 --- a/code/modules/mob/living/carbon/metroid/items.dm +++ b/code/modules/mob/living/carbon/metroid/items.dm @@ -142,7 +142,7 @@ if(M.mind) user << " The slime resists!" return ..() - var/mob/living/simple_animal/slime/pet = new /mob/living/simple_animal/slime(M.loc) + var/mob/living/simple_mob/slime/pet = new /mob/living/simple_mob/slime(M.loc) pet.icon_state = "[M.colour] [M.is_adult ? "adult" : "baby"] slime" pet.icon_living = "[M.colour] [M.is_adult ? "adult" : "baby"] slime" pet.icon_dead = "[M.colour] [M.is_adult ? "adult" : "baby"] slime dead" @@ -196,7 +196,7 @@ if(M.mind) user << " The slime resists!" return ..() - var/mob/living/simple_animal/adultslime/pet = new /mob/living/simple_animal/adultslime(M.loc) + var/mob/living/simple_mob/adultslime/pet = new /mob/living/simple_mob/adultslime(M.loc) pet.icon_state = "[M.colour] adult slime" pet.icon_living = "[M.colour] adult slime" pet.icon_dead = "[M.colour] baby slime dead" @@ -266,7 +266,7 @@ New() ..() - processing_objects.Add(src) + START_PROCESSING(SSobj, src) process() var/mob/observer/dead/ghost @@ -356,8 +356,8 @@ origin_tech = list(TECH_BIO = 4) var/grown = 0 -/obj/item/weapon/reagent_containers/food/snacks/egg/slime/New() - ..() +/obj/item/weapon/reagent_containers/food/snacks/egg/slime/Initialize() + . = ..() reagents.add_reagent("nutriment", 4) reagents.add_reagent("slimejelly", 1) spawn(rand(1200,1500))//the egg takes a while to "ripen" @@ -366,11 +366,11 @@ /obj/item/weapon/reagent_containers/food/snacks/egg/slime/proc/Grow() grown = 1 icon_state = "slime egg-grown" - processing_objects.Add(src) + START_PROCESSING(SSobj, src) return /obj/item/weapon/reagent_containers/food/snacks/egg/slime/proc/Hatch() - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) var/turf/T = get_turf(src) src.visible_message(" The [name] pulsates and quivers!") spawn(rand(50,100)) diff --git a/code/modules/mob/living/carbon/metroid/powers.dm b/code/modules/mob/living/carbon/metroid/powers.dm index 9e20d49a44..54d35a71f8 100644 --- a/code/modules/mob/living/carbon/metroid/powers.dm +++ b/code/modules/mob/living/carbon/metroid/powers.dm @@ -21,7 +21,7 @@ return "I cannot feed on other slimes..." if (!Adjacent(M)) return "This subject is too far away..." - if (istype(M, /mob/living/carbon) && M.getCloneLoss() >= M.getMaxHealth() * 1.5 || istype(M, /mob/living/simple_animal) && M.stat == DEAD) + if (istype(M, /mob/living/carbon) && M.getCloneLoss() >= M.getMaxHealth() * 1.5 || istype(M, /mob/living/simple_mob) && M.stat == DEAD) return "This subject does not have an edible life energy..." for(var/mob/living/carbon/slime/met in view()) if(met.Victim == M && met != src) @@ -48,7 +48,7 @@ if(Victim.health <= 0) Victim.adjustToxLoss(rand(2,4)) - else if(istype(M, /mob/living/simple_animal)) + else if(istype(M, /mob/living/simple_mob)) Victim.adjustBruteLoss(is_adult ? rand(7, 15) : rand(4, 12)) else @@ -165,4 +165,4 @@ else src << "I am not ready to reproduce yet..." else - src << "I am not old enough to reproduce yet..." \ No newline at end of file + src << "I am not old enough to reproduce yet..." diff --git a/code/modules/mob/living/carbon/resist.dm b/code/modules/mob/living/carbon/resist.dm index a86189d5f5..1607559336 100644 --- a/code/modules/mob/living/carbon/resist.dm +++ b/code/modules/mob/living/carbon/resist.dm @@ -153,11 +153,6 @@ legcuffed = null update_inv_legcuffed() -/mob/living/carbon/human/can_break_cuffs() - if(species.can_shred(src,1)) - return 1 - return ..() - /mob/living/carbon/escape_buckle() if(!buckled) return diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm index 07997851ef..37d9e43b37 100644 --- a/code/modules/mob/living/damage_procs.dm +++ b/code/modules/mob/living/damage_procs.dm @@ -36,6 +36,11 @@ adjustHalLoss(damage * blocked) if(ELECTROCUTE) electrocute_act(damage, used_weapon, 1.0, def_zone) + if(BIOACID) + if(isSynthetic()) + adjustFireLoss(damage * blocked) + else + adjustToxLoss(damage * blocked) flash_weak_pain() updatehealth() return 1 diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm index a5da193678..b333369265 100644 --- a/code/modules/mob/living/death.dm +++ b/code/modules/mob/living/death.dm @@ -1,12 +1,7 @@ /mob/living/death() clear_fullscreens() - reveal(TRUE) //Silently reveal the mob if they were hidden. - //VOREStation Edit - Mob spawner stuff - if(source_spawner) - source_spawner.get_death_report(src) - source_spawner = null - //VOREStation Edit End - . = ..() + if(ai_holder) + ai_holder.go_sleep() if(nest) //Ew. if(istype(nest, /obj/structure/prop/nest)) diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 02131c8cd0..24d56945b8 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -110,6 +110,7 @@ handle_silent() handle_drugged() handle_slurring() + handle_confused() /mob/living/proc/handle_stunned() if(stunned) @@ -146,6 +147,11 @@ AdjustParalysis(-1) return paralysis +/mob/living/proc/handle_confused() + if(confused) + AdjustConfused(-1) + return confused + /mob/living/proc/handle_disabilities() //Eyes if(sdisabilities & BLIND || stat) //blindness from disability or unconsciousness doesn't get better on its own diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 3bcfbe7b60..f1a5238f78 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -16,6 +16,8 @@ dsma.blend_mode = BLEND_ADD dsoverlay.appearance = dsma + selected_image = image(icon = 'icons/mob/screen1.dmi', loc = src, icon_state = "centermarker") + /mob/living/Destroy() dsoverlay.loc = null //I'll take my coat with me dsoverlay = null @@ -29,6 +31,7 @@ nest = null if(buckled) buckled.unbuckle_mob(src, TRUE) + qdel(selected_image) return ..() //mob verbs are faster than object verbs. See mob/verb/examine. @@ -77,150 +80,143 @@ default behaviour is: return 1 return 0 -/mob/living/Bump(atom/movable/AM, yes) - spawn(0) - if ((!( yes ) || now_pushing) || !loc) +/mob/living/Bump(atom/movable/AM) + if(now_pushing || !loc) + return + now_pushing = 1 + if (istype(AM, /mob/living)) + var/mob/living/tmob = AM + + //Even if we don't push/swap places, we "touched" them, so spread fire + spread_fire(tmob) + + for(var/mob/living/M in range(tmob, 1)) + if(tmob.pinned.len || ((M.pulling == tmob && ( tmob.restrained() && !( M.restrained() ) && M.stat == 0)) || locate(/obj/item/weapon/grab, tmob.grabbed_by.len)) ) + if ( !(world.time % 5) ) + to_chat(src, "[tmob] is restrained, you cannot push past") + now_pushing = 0 + return + if( tmob.pulling == M && ( M.restrained() && !( tmob.restrained() ) && tmob.stat == 0) ) + if ( !(world.time % 5) ) + to_chat(src, "[tmob] is restraining [M], you cannot push past") + now_pushing = 0 + return + + //BubbleWrap: people in handcuffs are always switched around as if they were on 'help' intent to prevent a person being pulled from being seperated from their puller + var/dense = 0 + if(loc.density) + dense = 1 + for(var/atom/movable/A in loc) + if(A == src) + continue + if(A.density) + if(A.flags&ON_BORDER) + dense = !A.CanPass(src, src.loc) + else + dense = 1 + if(dense) break + + //Leaping mobs just land on the tile, no pushing, no anything. + if(status_flags & LEAPING) + loc = tmob.loc + status_flags &= ~LEAPING + now_pushing = 0 return - now_pushing = 1 - if (istype(AM, /mob/living)) - var/mob/living/tmob = AM - //Even if we don't push/swap places, we "touched" them, so spread fire - spread_fire(tmob) - - for(var/mob/living/M in range(tmob, 1)) - if(tmob.pinned.len || ((M.pulling == tmob && ( tmob.restrained() && !( M.restrained() ) && M.stat == 0)) || locate(/obj/item/weapon/grab, tmob.grabbed_by.len)) ) - if ( !(world.time % 5) ) - to_chat(src, "[tmob] is restrained, you cannot push past") - now_pushing = 0 - return - if( tmob.pulling == M && ( M.restrained() && !( tmob.restrained() ) && tmob.stat == 0) ) - if ( !(world.time % 5) ) - to_chat(src, "[tmob] is restraining [M], you cannot push past") - now_pushing = 0 - return - - //BubbleWrap: people in handcuffs are always switched around as if they were on 'help' intent to prevent a person being pulled from being seperated from their puller - var/dense = 0 - if(loc.density) - dense = 1 - for(var/atom/movable/A in loc) - if(A == src) - continue - if(A.density) - if(A.flags&ON_BORDER) - dense = !A.CanPass(src, src.loc) - else - dense = 1 - if(dense) break - - //Leaping mobs just land on the tile, no pushing, no anything. - if(status_flags & LEAPING) - loc = tmob.loc - status_flags &= ~LEAPING + if((tmob.mob_always_swap || (tmob.a_intent == I_HELP || tmob.restrained()) && (a_intent == I_HELP || src.restrained())) && tmob.canmove && canmove && !tmob.buckled && !buckled && !dense && can_move_mob(tmob, 1, 0)) // mutual brohugs all around! + var/turf/oldloc = loc + forceMove(tmob.loc) + //VOREstation Edit - Begin + if (istype(tmob, /mob/living/simple_mob)) //check bumpnom chance, if it's a simplemob that's bumped + tmob.Bumped(src) + else if(istype(src, /mob/living/simple_mob)) //otherwise, if it's a simplemob doing the bumping. Simplemob on simplemob doesn't seem to trigger but that's fine. + Bumped(tmob) + if (tmob.loc == src) //check if they got ate, and if so skip the forcemove now_pushing = 0 return - if((tmob.mob_always_swap || (tmob.a_intent == I_HELP || tmob.restrained()) && (a_intent == I_HELP || src.restrained())) && tmob.canmove && canmove && !tmob.buckled && !buckled && !dense && can_move_mob(tmob, 1, 0)) // mutual brohugs all around! - var/turf/oldloc = loc - forceMove(tmob.loc) - - //VOREstation Edit - Begin - if (istype(tmob, /mob/living/simple_animal)) //check bumpnom chance, if it's a simplemob that's bumped - tmob.Bumped(src) - else if(istype(src, /mob/living/simple_animal)) //otherwise, if it's a simplemob doing the bumping. Simplemob on simplemob doesn't seem to trigger but that's fine. - Bumped(tmob) - if (tmob.loc == src) //check if they got ate, and if so skip the forcemove - now_pushing = 0 - return - - // In case of micros, we don't swap positions; instead occupying the same square! - if (handle_micro_bump_helping(tmob)) - now_pushing = 0 - return - // TODO - Check if we need to do something about the slime.UpdateFeed() we are skipping below. - // VOREStation Edit - End - - tmob.forceMove(oldloc) + // In case of micros, we don't swap positions; instead occupying the same square! + if (handle_micro_bump_helping(tmob)) now_pushing = 0 return - - if(!can_move_mob(tmob, 0, 0)) - now_pushing = 0 - return - if(a_intent == I_HELP || src.restrained()) - now_pushing = 0 - return - - // VOREStation Edit - Begin - // Plow that nerd. - if(ishuman(tmob)) - var/mob/living/carbon/human/H = tmob - if(H.species.lightweight == 1 && prob(50)) - H.visible_message("[src] bumps into [H], knocking them off balance!") - H.Weaken(5) - now_pushing = 0 - return - // Handle grabbing, stomping, and such of micros! - if(handle_micro_bump_other(tmob)) return + // TODO - Check if we need to do something about the slime.UpdateFeed() we are skipping below. // VOREStation Edit - End - - if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations)) - if(prob(40) && !(FAT in src.mutations)) - to_chat(src, "You fail to push [tmob]'s fat ass out of the way.") - now_pushing = 0 - return - if(tmob.r_hand && istype(tmob.r_hand, /obj/item/weapon/shield/riot)) - if(prob(99)) - now_pushing = 0 - return - if(tmob.l_hand && istype(tmob.l_hand, /obj/item/weapon/shield/riot)) - if(prob(99)) - now_pushing = 0 - return - if(!(tmob.status_flags & CANPUSH)) - now_pushing = 0 - return - - tmob.LAssailant = src - - now_pushing = 0 - spawn(0) - ..() - if (!istype(AM, /atom/movable) || AM.anchored) - //VOREStation Edit - object-specific proc for running into things - if(((confused || is_blind()) && stat == CONSCIOUS && prob(50) && m_intent=="run") || flying) - AM.stumble_into(src) - //VOREStation Edit End - /* VOREStation Removal - See above - Weaken(2) - playsound(loc, "punch", 25, 1, -1) - visible_message("[src] [pick("ran", "slammed")] into \the [AM]!") - src.apply_damage(5, BRUTE) - src << ("You just [pick("ran", "slammed")] into \the [AM]!") - to_chat(src, "You just [pick("ran", "slammed")] into \the [AM]!") - */ // VOREStation Removal End - return - if (!now_pushing) - if(isobj(AM)) - var/obj/I = AM - if(!can_pull_size || can_pull_size < I.w_class) - return - now_pushing = 1 - - var/t = get_dir(src, AM) - if (istype(AM, /obj/structure/window)) - for(var/obj/structure/window/win in get_step(AM,t)) - now_pushing = 0 - return - step(AM, t) - if(ishuman(AM) && AM:grabbed_by) - for(var/obj/item/weapon/grab/G in AM:grabbed_by) - step(G:assailant, get_dir(G:assailant, AM)) - G.adjust_position() - now_pushing = 0 + tmob.forceMove(oldloc) + now_pushing = 0 return - return + + if(!can_move_mob(tmob, 0, 0)) + now_pushing = 0 + return + if(a_intent == I_HELP || src.restrained()) + now_pushing = 0 + return + // VOREStation Edit - Begin + // Plow that nerd. + if(ishuman(tmob)) + var/mob/living/carbon/human/H = tmob + if(H.species.lightweight == 1 && prob(50)) + H.visible_message("[src] bumps into [H], knocking them off balance!") + H.Weaken(5) + now_pushing = 0 + return + // Handle grabbing, stomping, and such of micros! + if(handle_micro_bump_other(tmob)) return + // VOREStation Edit - End + if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations)) + if(prob(40) && !(FAT in src.mutations)) + to_chat(src, "You fail to push [tmob]'s fat ass out of the way.") + now_pushing = 0 + return + if(tmob.r_hand && istype(tmob.r_hand, /obj/item/weapon/shield/riot)) + if(prob(99)) + now_pushing = 0 + return + + if(tmob.l_hand && istype(tmob.l_hand, /obj/item/weapon/shield/riot)) + if(prob(99)) + now_pushing = 0 + return + if(!(tmob.status_flags & CANPUSH)) + now_pushing = 0 + return + + tmob.LAssailant = src + + now_pushing = 0 + . = ..() + if (!istype(AM, /atom/movable) || AM.anchored) + //VOREStation Edit - object-specific proc for running into things + if(((confused || is_blind()) && stat == CONSCIOUS && prob(50) && m_intent=="run") || flying) + AM.stumble_into(src) + //VOREStation Edit End + /* VOREStation Removal - See above + if(confused && prob(50) && m_intent=="run") + Weaken(2) + playsound(loc, "punch", 25, 1, -1) + visible_message("[src] [pick("ran", "slammed")] into \the [AM]!") + src.apply_damage(5, BRUTE) + to_chat(src, "You just [pick("ran", "slammed")] into \the [AM]!") + */ // VOREStation Removal End + return + if (!now_pushing) + if(isobj(AM)) + var/obj/I = AM + if(!can_pull_size || can_pull_size < I.w_class) + return + now_pushing = 1 + + var/t = get_dir(src, AM) + if (istype(AM, /obj/structure/window)) + for(var/obj/structure/window/win in get_step(AM,t)) + now_pushing = 0 + return + step(AM, t) + if(ishuman(AM) && AM:grabbed_by) + for(var/obj/item/weapon/grab/G in AM:grabbed_by) + step(G:assailant, get_dir(G:assailant, AM)) + G.adjust_position() + now_pushing = 0 /mob/living/CanPass(atom/movable/mover, turf/target) if(istype(mover, /obj/structure/blob) && faction == "blob") //Blobs should ignore things on their faction. @@ -550,6 +546,36 @@ default behaviour is: // ++++ROCKDTBEN++++ MOB PROCS //END +// Applies direct "cold" damage while checking protection against the cold. +/mob/living/proc/inflict_cold_damage(amount) + amount *= 1 - get_cold_protection(50) // Within spacesuit protection. + if(amount > 0) + adjustFireLoss(amount) + +// Ditto, but for "heat". +/mob/living/proc/inflict_heat_damage(amount) + amount *= 1 - get_heat_protection(10000) // Within firesuit protection. + if(amount > 0) + adjustFireLoss(amount) + +// and one for electricity because why not +/mob/living/proc/inflict_shock_damage(amount) + electrocute_act(amount, null, 1 - get_shock_protection(), pick(BP_HEAD, BP_TORSO, BP_GROIN)) + +// also one for water (most things resist it entirely, except for slimes) +/mob/living/proc/inflict_water_damage(amount) + amount *= 1 - get_water_protection() + if(amount > 0) + adjustToxLoss(amount) + +// one for abstracted away ""poison"" (mostly because simplemobs shouldn't handle reagents) +/mob/living/proc/inflict_poison_damage(amount) + if(isSynthetic()) + return + amount *= 1 - get_poison_protection() + if(amount > 0) + adjustToxLoss(amount) + /mob/proc/get_contents() @@ -663,6 +689,8 @@ default behaviour is: BITSET(hud_updateflag, LIFE_HUD) ExtinguishMob() fire_stacks = 0 + if(ai_holder) // AI gets told to sleep when killed. Since they're not dead anymore, wake it up. + ai_holder.go_wake() /mob/living/proc/rejuvenate() if(reagents) @@ -832,7 +860,7 @@ default behaviour is: if (pulling) if (istype(pulling, /obj/structure/window)) var/obj/structure/window/W = pulling - if(W.is_full_window()) + if(W.is_fulltile()) for(var/obj/structure/window/win in get_step(pulling,get_dir(pulling.loc, T))) stop_pulling() if (pulling) @@ -891,7 +919,7 @@ default behaviour is: // Update whether or not this mob needs to pass emotes to contents. for(var/atom/A in M.contents) - if(istype(A,/mob/living/simple_animal/borer) || istype(A,/obj/item/weapon/holder)) + if(istype(A,/mob/living/simple_mob/animal/borer) || istype(A,/obj/item/weapon/holder)) return else if(istype(H.loc,/obj/item/clothing/accessory/holster)) @@ -1295,4 +1323,22 @@ default behaviour is: /mob/living/proc/dirties_floor() // If we ever decide to add fancy conditionals for making dirty floors (floating, etc), here's the proc. - return makes_dirt \ No newline at end of file + return makes_dirt + +/mob/living/proc/needs_to_breathe() + return !isSynthetic() + +/mob/living/vv_get_header() + . = ..() + . += {" +
      [src] +
      [ckey ? ckey : "No ckey"] / [real_name ? real_name : "No real name"] +
      + BRUTE:[getBruteLoss()] + FIRE:[getFireLoss()] + TOXIN:[getToxLoss()] + OXY:[getOxyLoss()] + CLONE:[getCloneLoss()] + BRAIN:[getBrainLoss()] +
      + "} diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 08d35e5de2..b3ee75349c 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -92,6 +92,13 @@ /mob/living/proc/getsoak(var/def_zone, var/type) return 0 +// Clicking with an empty hand +/mob/living/attack_hand(mob/living/L) + ..() + if(istype(L) && L.a_intent != I_HELP) + if(ai_holder) // Using disarm, grab, or harm intent is considered a hostile action to the mob's AI. + ai_holder.react_to_attack(L) + /mob/living/bullet_act(var/obj/item/projectile/P, var/def_zone) //Being hit while using a deadman switch @@ -102,6 +109,9 @@ src.visible_message("[src] triggers their deadman's switch!") signaler.signal() + if(ai_holder && P.firer) + ai_holder.react_to_attack(P.firer) + //Armor var/soaked = get_armor_soak(def_zone, P.check_armour, P.armor_penetration) var/absorb = run_armor_check(def_zone, P.check_armour, P.armor_penetration) @@ -267,6 +277,8 @@ var/client/assailant = M.client if(assailant) add_attack_logs(M,src,"Hit by thrown [O.name]") + if(ai_holder) + ai_holder.react_to_attack(O.thrower) // Begin BS12 momentum-transfer code. var/mass = 1.5 @@ -287,7 +299,7 @@ if(soaked >= round(throw_damage*0.8)) return - //Handles embedding for non-humans and simple_animals. + //Handles embedding for non-humans and simple_mobs. embed(O) var/turf/T = near_wall(dir,2) @@ -324,12 +336,13 @@ // End BS12 momentum-transfer code. /mob/living/attack_generic(var/mob/user, var/damage, var/attack_message) - if(!damage) return adjustBruteLoss(damage) - add_attack_logs(user,src,"Generic attack (probably animal)", admin_notify = FALSE) //Usually due to simple_animal attacks + add_attack_logs(user,src,"Generic attack (probably animal)", admin_notify = FALSE) //Usually due to simple_mob attacks + if(ai_holder) + ai_holder.react_to_attack(user) src.visible_message("[user] has [attack_message] [src]!") user.do_attack_animation(src) spawn(1) updatehealth() @@ -352,7 +365,7 @@ 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, FIRE_MIN_STACKS, FIRE_MAX_STACKS) + fire_stacks = CLAMP(fire_stacks + add_fire_stacks, FIRE_MIN_STACKS, FIRE_MAX_STACKS) /mob/living/proc/handle_fire() if(fire_stacks < 0) @@ -412,6 +425,15 @@ /mob/living/proc/get_heat_protection() return 0 +/mob/living/proc/get_shock_protection() + return 0 + +/mob/living/proc/get_water_protection() + return 1 // Water won't hurt most things. + +/mob/living/proc/get_poison_protection() + return 0 + //Finds the effective temperature that the mob is burning at. /mob/living/proc/fire_burn_temperature() if (fire_stacks <= 0) @@ -421,6 +443,22 @@ //lower limit of 700 K, same as matches and roughly the temperature of a cool flame. return max(2.25*round(FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE*(fire_stacks/FIRE_MAX_FIRESUIT_STACKS)**2), 700) +// Called when struck by lightning. +/mob/living/proc/lightning_act() + // The actual damage/electrocution is handled by the tesla_zap() that accompanies this. + Paralyse(5) + stuttering += 20 + make_jittery(150) + emp_act(1) + to_chat(src, span("critical", "You've been struck by lightning!")) + +// Called when touching a lava tile. +// Does roughly 100 damage to unprotected mobs, and 20 to fully protected mobs. +/mob/living/lava_act() + add_modifier(/datum/modifier/fire/intense, 8 SECONDS) // Around 40 total if left to burn and without fire protection per stack. + inflict_heat_damage(40) // Another 40, however this is instantly applied to unprotected mobs. + adjustFireLoss(20) // Lava cannot be 100% resisted with fire protection. + /mob/living/proc/reagent_permeability() return 1 return round(FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE*(fire_stacks/FIRE_MAX_FIRESUIT_STACKS)**2) diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 9486eb9960..8e3b9fb9a4 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -5,6 +5,8 @@ var/maxHealth = 100 //Maximum health that should be possible. Avoid adjusting this if you can, and instead use modifiers datums. var/health = 100 //A mob's health + var/mob_class = null // A mob's "class", e.g. human, mechanical, animal, etc. Used for certain projectile effects. See __defines/mob.dm for available classes. + var/hud_updateflag = 0 //Damage related vars, NOTE: THESE SHOULD ONLY BE MODIFIED BY PROCS @@ -20,6 +22,7 @@ var/list/atom/hallucinations = list() //A list of hallucinated people that try to attack the mob. See /obj/effect/fake_attacker in hallucinations.dm var/last_special = 0 //Used by the resist verb, likely used to prevent players from bypassing next_move by logging in/out. + var/base_attack_cooldown = DEFAULT_ATTACK_COOLDOWN var/t_phoron = null var/t_oxygen = null @@ -64,4 +67,5 @@ var/makes_dirt = TRUE //FALSE if the mob shouldn't be making dirt on the ground when it walks var/looking_elsewhere = FALSE //If the mob's view has been relocated to somewhere else, like via a camera or with binocs - \ No newline at end of file + + var/image/selected_image = null // Used for buildmode AI control stuff. \ No newline at end of file diff --git a/code/modules/mob/living/login.dm b/code/modules/mob/living/login.dm index 275e88be08..96d59dc330 100644 --- a/code/modules/mob/living/login.dm +++ b/code/modules/mob/living/login.dm @@ -8,4 +8,9 @@ update_antag_icons(mind) client.screen |= global_hud.darksight client.images |= dsoverlay + + if(ai_holder && !ai_holder.autopilot) + ai_holder.go_sleep() + to_chat(src,"Mob AI disabled while you are controlling the mob.") + return . diff --git a/code/modules/mob/living/logout.dm b/code/modules/mob/living/logout.dm index 577221a03e..fa04b0b317 100644 --- a/code/modules/mob/living/logout.dm +++ b/code/modules/mob/living/logout.dm @@ -1,6 +1,11 @@ /mob/living/Logout() ..() - if (mind) + if (mind) //Per BYOND docs key remains set if the player DCs, becomes null if switching bodies. - if(!key) //key and mind have become seperated. + if(!key) //key and mind have become seperated. mind.active = 0 //This is to stop say, a mind.transfer_to call on a corpse causing a ghost to re-enter its body. + + spawn(15 SECONDS) //15 seconds to get back into the mob before it goes wild + if(src && !src.client) + if(ai_holder) + ai_holder.go_wake() diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 49b5be1d19..02900ffe1a 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -138,7 +138,7 @@ proc/get_radio_key_from_channel(var/channel) if(message) client.handle_spam_prevention(MUTE_IC) if((client.prefs.muted & MUTE_IC) || say_disabled) - src << "You cannot speak in IC (Muted)." + to_chat(src, "You cannot speak in IC (Muted).") return //Redirect to say_dead if talker is dead @@ -172,10 +172,22 @@ proc/get_radio_key_from_channel(var/channel) //Parse the language code and consume it if(!speaking) speaking = parse_language(message) + + if(!speaking) + speaking = get_default_language() + + if(!can_speak(speaking)) + speaking = all_languages[LANGUAGE_GIBBERISH] + var/babble_key = ",r" + message = babble_key + message + + if(speaking == get_default_language()) + var/new_message = ",[speaking.key]" + new_message += message + message = new_message + if(speaking) message = copytext(message,2+length(speaking.key)) - else - speaking = get_default_language() //HIVEMIND languages always send to all people with that language if(speaking && (speaking.flags & HIVEMIND)) @@ -184,7 +196,7 @@ proc/get_radio_key_from_channel(var/channel) //Self explanatory. if(is_muzzled() && !(speaking && (speaking.flags & SIGNLANG))) - src << "You're muzzled and cannot speak!" + to_chat(src, "You're muzzled and cannot speak!") return //Clean up any remaining junk on the left like spaces. diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index cc795d088d..7e4d921ca3 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -810,7 +810,7 @@ var/list/ai_verbs_default = list( /mob/living/silicon/ai/announcer/ is_dummy = 1 -/mob/living/silicon/ai/announcer/initialize() +/mob/living/silicon/ai/announcer/Initialize() . = ..() mob_list -= src living_mob_list -= src diff --git a/code/modules/mob/living/silicon/pai/admin.dm b/code/modules/mob/living/silicon/pai/admin.dm index 069c5d2c68..b2e6bd0288 100644 --- a/code/modules/mob/living/silicon/pai/admin.dm +++ b/code/modules/mob/living/silicon/pai/admin.dm @@ -7,7 +7,7 @@ return if(!pai_key) - var/client/C = input("Select client") as null|anything in clients + var/client/C = input("Select client") as null|anything in GLOB.clients if(!C) return pai_key = C.key diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 1b3720dc33..ac2417a077 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -201,7 +201,7 @@ medicalActive1 = null medicalActive2 = null medical_cannotfind = 0 - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) usr << "You reset your record-viewing software." /mob/living/silicon/pai/cancel_camera() diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm index bef2c93403..85d98c1663 100644 --- a/code/modules/mob/living/silicon/pai/software.dm +++ b/code/modules/mob/living/silicon/pai/software.dm @@ -90,7 +90,7 @@ var/global/list/default_pai_software = list() data["emotions"] = emotions data["current_emotion"] = card.current_emotion - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "pai_interface.tmpl", "pAI Software Interface", 450, 600) ui.set_initial_data(data) diff --git a/code/modules/mob/living/silicon/pai/software_modules.dm b/code/modules/mob/living/silicon/pai/software_modules.dm index ebea6068e7..fdaa992816 100644 --- a/code/modules/mob/living/silicon/pai/software_modules.dm +++ b/code/modules/mob/living/silicon/pai/software_modules.dm @@ -36,7 +36,7 @@ data["prime"] = user.pai_law0 data["supplemental"] = user.pai_laws - ui = GLOB.nanomanager.try_update_ui(user, user, id, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) if(!ui) // Don't copy-paste this unless you're making a pAI software module! ui = new(user, user, id, "pai_directives.tmpl", "pAI Directives", 450, 600) @@ -102,7 +102,7 @@ data["channels"] = channels - ui = GLOB.nanomanager.try_update_ui(user, user, id, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) if(!ui) ui = new(user, user, id, "pai_radio.tmpl", "Radio Configuration", 300, 150) ui.set_initial_data(data) @@ -128,7 +128,7 @@ // This is dumb, but NanoUI breaks if it has no data to send data["manifest"] = PDA_Manifest - ui = GLOB.nanomanager.try_update_ui(user, user, id, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) if(!ui) // Don't copy-paste this unless you're making a pAI software module! ui = new(user, user, id, "crew_manifest.tmpl", "Crew Manifest", 450, 600) @@ -178,7 +178,7 @@ data["messages"] = messages - ui = GLOB.nanomanager.try_update_ui(user, user, id, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) if(!ui) // Don't copy-paste this unless you're making a pAI software module! ui = new(user, user, id, "pai_messenger.tmpl", "Digital Messenger", 450, 600) @@ -236,7 +236,7 @@ data["medical"] = M ? M.fields : null data["could_not_find"] = user.medical_cannotfind - ui = GLOB.nanomanager.try_update_ui(user, user, id, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) if(!ui) // Don't copy-paste this unless you're making a pAI software module! ui = new(user, user, id, "pai_medrecords.tmpl", "Medical Records", 450, 600) @@ -290,7 +290,7 @@ data["security"] = S ? S.fields : null data["could_not_find"] = user.security_cannotfind - ui = GLOB.nanomanager.try_update_ui(user, user, id, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) if(!ui) // Don't copy-paste this unless you're making a pAI software module! ui = new(user, user, id, "pai_secrecords.tmpl", "Security Records", 450, 600) @@ -340,7 +340,7 @@ data["progress_b"] = user.hackprogress % 10 data["aborted"] = user.hack_aborted - ui = GLOB.nanomanager.try_update_ui(user, user, id, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) if(!ui) // Don't copy-paste this unless you're making a pAI software module! ui = new(user, user, id, "pai_doorjack.tmpl", "Door Jack", 300, 150) @@ -431,7 +431,7 @@ gases[++gases.len] = gas data["gas"] = gases - ui = GLOB.nanomanager.try_update_ui(user, user, id, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) if(!ui) // Don't copy-paste this unless you're making a pAI software module! ui = new(user, user, id, "pai_atmosphere.tmpl", "Atmosphere Sensor", 350, 300) @@ -503,7 +503,7 @@ data["frequency"] = format_frequency(user.sradio.frequency) data["code"] = user.sradio.code - ui = GLOB.nanomanager.try_update_ui(user, user, id, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) if(!ui) // Don't copy-paste this unless you're making a pAI software module! ui = new(user, user, id, "pai_signaller.tmpl", "Signaller", 320, 150) diff --git a/code/modules/mob/living/silicon/robot/dogborg/dog_sleeper_vr.dm b/code/modules/mob/living/silicon/robot/dogborg/dog_sleeper_vr.dm index 0bacecc567..750f043f33 100644 --- a/code/modules/mob/living/silicon/robot/dogborg/dog_sleeper_vr.dm +++ b/code/modules/mob/living/silicon/robot/dogborg/dog_sleeper_vr.dm @@ -83,9 +83,9 @@ to_chat(user, "\The [target.name] added to cargo compartment slot: [delivery_tag].") update_patient() return - - if(istype(target, /mob/living/simple_animal/mouse)) //Edible mice, dead or alive whatever. Mostly for carcass picking you cruel bastard :v - var/mob/living/simple_animal/trashmouse = target +/* //VORESTATION AI TEMPORARY REMOVAL + if(istype(target, /mob/living/simple_mob/mouse)) //Edible mice, dead or alive whatever. Mostly for carcass picking you cruel bastard :v + var/mob/living/simple_mob/trashmouse = target user.visible_message("[hound.name] is ingesting [trashmouse] into their [src.name].", "You start ingesting [trashmouse] into your [src.name]...") if(do_after(user, 30, trashmouse) && length(contents) < max_item_count) trashmouse.forceMove(src) @@ -98,7 +98,7 @@ to_chat(user, "\The [trashmouse] added to cargo compartment slot: [delivery_tag].") update_patient() return - +*/ else if(ishuman(target)) var/mob/living/carbon/human/trashman = target if(patient) @@ -111,7 +111,7 @@ if(do_after(user, 30, trashman) && !patient && !trashman.buckled && length(contents) < max_item_count) trashman.forceMove(src) trashman.reset_view(src) - processing_objects |= src + START_PROCESSING(SSobj, src) user.visible_message("[hound.name]'s [src.name] groans lightly as [trashman] slips inside.", "Your [src.name] groans lightly as [trashman] slips inside.") message_admins("[key_name(hound)] has eaten [key_name(patient)] as a dogborg. ([hound ? "JMP" : "null"])") playsound(hound, gulpsound, vol = 100, vary = 1, falloff = 0.1, preference = /datum/client_preference/eating_noises) @@ -142,7 +142,7 @@ H.forceMove(src) H.reset_view(src) update_patient() - processing_objects |= src + START_PROCESSING(SSobj, src) user.visible_message("[hound.name]'s [src.name] lights up as [H.name] slips inside.", "Your [src] lights up as [H] slips inside. Life support functions engaged.") message_admins("[key_name(hound)] has eaten [key_name(patient)] as a dogborg. ([hound ? "JMP" : "null"])") playsound(hound, gulpsound, vol = 100, vary = 1, falloff = 0.1, preference = /datum/client_preference/eating_noises) @@ -184,12 +184,12 @@ dat += "

      Injector

      " if(patient)// && patient.health > min_health) //Not necessary, leave the buttons on, but the feedback during injection will give more information. for(var/re in injection_chems) - var/datum/reagent/C = chemical_reagents_list[re] + var/datum/reagent/C = SSchemistry.chemical_reagents[re] if(C) dat += "Inject [C.name]
      " else for(var/re in injection_chems) - var/datum/reagent/C = chemical_reagents_list[re] + var/datum/reagent/C = SSchemistry.chemical_reagents[re] if(C) dat += "Inject [C.name]
      " @@ -311,7 +311,7 @@ else cleaning = 1 drain(startdrain) - processing_objects |= src + START_PROCESSING(SSobj, src) update_patient() if(patient) to_chat(patient, "[hound.name]'s [src.name] fills with caustic enzymes around you!") @@ -393,7 +393,7 @@ patient.reagents.add_reagent(chem, inject_amount) drain(750) //-750 charge per injection var/units = round(patient.reagents.get_reagent_amount(chem)) - to_chat(hound, "Injecting [units] unit\s of [chemical_reagents_list[chem]] into occupant.") //If they were immersed, the reagents wouldn't leave with them. + to_chat(hound, "Injecting [units] unit\s of [SSchemistry.chemical_reagents[chem]] into occupant.") //If they were immersed, the reagents wouldn't leave with them. //For if the dogborg's existing patient uh, doesn't make it. /obj/item/device/dogborg/sleeper/proc/update_patient() @@ -620,19 +620,20 @@ clean_cycle() return - if(patient) //We're caring for the patient. Medical emergency! Or endo scene. + if(patient && !compactor) //We're caring for the patient. Medical emergency! Or endo scene. update_patient() if(patient.health < 0) patient.adjustOxyLoss(-1) //Heal some oxygen damage if they're in critical condition patient.updatehealth() + drain() patient.AdjustStunned(-4) patient.AdjustWeakened(-4) - drain() + drain(1) return if(!patient && !cleaning) //We think we're done working. if(!update_patient()) //One last try to find someone - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) return /obj/item/device/dogborg/sleeper/K9 //The K9 portabrig 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 bf76fdbe91..670087dc51 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_items.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_items.dm @@ -407,7 +407,7 @@ var/grabbed_something = 0 for(var/mob/M in T) - if(istype(M,/mob/living/simple_animal/lizard) || istype(M,/mob/living/simple_animal/mouse)) + if(istype(M,/mob/living/simple_mob/animal/passive/lizard) || istype(M,/mob/living/simple_mob/animal/passive/mouse)) src.loc.visible_message("[src.loc] sucks [M] into its decompiler. There's a horrible crunching noise.","It's a bit of a struggle, but you manage to suck [M] into your decompiler. It makes a series of visceral crunching noises.") new/obj/effect/decal/cleanable/blood/splatter(get_turf(src)) qdel(M) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 49f44a9097..b609668e43 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -681,7 +681,7 @@ //Robots take half damage from basic attacks. /mob/living/silicon/robot/attack_generic(var/mob/user, var/damage, var/attack_message) - return ..(user,Floor(damage/2),attack_message) + return ..(user,FLOOR(damage/2, 1),attack_message) /mob/living/silicon/robot/proc/allowed(mob/M) //check if it doesn't require any access at all diff --git a/code/modules/mob/living/silicon/robot/robot_items.dm b/code/modules/mob/living/silicon/robot/robot_items.dm index d52a5da531..c87fa7d88c 100644 --- a/code/modules/mob/living/silicon/robot/robot_items.dm +++ b/code/modules/mob/living/silicon/robot/robot_items.dm @@ -307,11 +307,11 @@ var/last_flash = 0 //Stores the time of last flash /obj/item/borg/combat/shield/New() - processing_objects.Add(src) + START_PROCESSING(SSobj, src) ..() /obj/item/borg/combat/shield/Destroy() - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) ..() /obj/item/borg/combat/shield/attack_self(var/mob/living/user) diff --git a/code/modules/mob/living/silicon/robot/robot_movement.dm b/code/modules/mob/living/silicon/robot/robot_movement.dm index 29251d8a1d..f03a51651a 100644 --- a/code/modules/mob/living/silicon/robot/robot_movement.dm +++ b/code/modules/mob/living/silicon/robot/robot_movement.dm @@ -6,9 +6,11 @@ /mob/living/silicon/robot/Process_Spacemove() if(module) for(var/obj/item/weapon/tank/jetpack/J in module.modules) - if(J && istype(J, /obj/item/weapon/tank/jetpack)) - if(J.allow_thrust(0.01)) return 1 - if(..()) return 1 + if(istype(J, /obj/item/weapon/tank/jetpack)) + if(J.allow_thrust(0.01)) + return 1 + if(..()) + return 1 return 0 //No longer needed, but I'll leave it here incase we plan to re-use it. diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index da0809250d..50e7989f57 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -193,7 +193,7 @@ //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 + return universal_speak || (speaking in src.speech_synthesizer_langs) || (speaking.name == "Noise") //need speech synthesizer support to vocalize a language /mob/living/silicon/add_language(var/language, var/can_speak=1) var/var/datum/language/added_language = all_languages[language] diff --git a/code/modules/mob/living/simple_animal/aliens/alien.dm b/code/modules/mob/living/simple_animal/aliens/alien.dm index 3dba09330a..861d79648e 100644 --- a/code/modules/mob/living/simple_animal/aliens/alien.dm +++ b/code/modules/mob/living/simple_animal/aliens/alien.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/hostile/alien +/mob/living/simple_mob/hostile/alien name = "alien hunter" desc = "Hiss!" icon = 'icons/mob/alien.dmi' @@ -48,7 +48,7 @@ meat_type = /obj/item/weapon/reagent_containers/food/snacks/xenomeat -/mob/living/simple_animal/hostile/alien/drone +/mob/living/simple_mob/hostile/alien/drone name = "alien drone" icon_state = "aliend_running" icon_living = "aliend_running" @@ -58,7 +58,7 @@ melee_damage_lower = 15 melee_damage_upper = 15 -/mob/living/simple_animal/hostile/alien/sentinel +/mob/living/simple_mob/hostile/alien/sentinel name = "alien sentinel" icon_state = "aliens_running" icon_living = "aliens_running" @@ -71,7 +71,7 @@ projectiletype = /obj/item/projectile/energy/neurotoxin/toxic projectilesound = 'sound/weapons/pierce.ogg' -/mob/living/simple_animal/hostile/alien/sentinel/praetorian +/mob/living/simple_mob/hostile/alien/sentinel/praetorian name = "alien praetorian" icon = 'icons/mob/64x64.dmi' icon_state = "prat_s" @@ -86,7 +86,7 @@ old_x = -16 meat_amount = 5 -/mob/living/simple_animal/hostile/alien/queen +/mob/living/simple_mob/hostile/alien/queen name = "alien queen" icon_state = "alienq_running" icon_living = "alienq_running" @@ -103,7 +103,7 @@ rapid = 1 status_flags = 0 -/mob/living/simple_animal/hostile/alien/queen/empress +/mob/living/simple_mob/hostile/alien/queen/empress name = "alien empress" icon = 'icons/mob/64x64.dmi' icon_state = "queen_s" @@ -119,7 +119,7 @@ pixel_x = -16 old_x = -16 -/mob/living/simple_animal/hostile/alien/queen/empress/mother +/mob/living/simple_mob/hostile/alien/queen/empress/mother name = "alien mother" icon = 'icons/mob/96x96.dmi' icon_state = "empress_s" @@ -136,7 +136,7 @@ pixel_x = -32 old_x = -32 -/mob/living/simple_animal/hostile/alien/death() +/mob/living/simple_mob/hostile/alien/death() ..() visible_message("[src] lets out a waning guttural screech, green blood bubbling from its maw...") playsound(src, 'sound/voice/hiss6.ogg', 100, 1) \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/aliens/creature.dm b/code/modules/mob/living/simple_animal/aliens/creature.dm index 20840e66db..65dcd326fa 100644 --- a/code/modules/mob/living/simple_animal/aliens/creature.dm +++ b/code/modules/mob/living/simple_animal/aliens/creature.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/hostile/creature +/mob/living/simple_mob/hostile/creature name = "creature" desc = "A sanity-destroying otherthing." icon = 'icons/mob/critter.dmi' @@ -25,7 +25,7 @@ speak_emote = list("gibbers") -/mob/living/simple_animal/hostile/creature/cult +/mob/living/simple_mob/hostile/creature/cult faction = "cult" min_oxy = 0 @@ -40,14 +40,14 @@ supernatural = 1 -/mob/living/simple_animal/hostile/creature/cult/cultify() +/mob/living/simple_mob/hostile/creature/cult/cultify() return -/mob/living/simple_animal/hostile/creature/cult/Life() +/mob/living/simple_mob/hostile/creature/cult/Life() ..() check_horde() -/mob/living/simple_animal/hostile/creature/strong +/mob/living/simple_mob/hostile/creature/strong maxHealth = 160 health = 160 @@ -55,7 +55,7 @@ melee_damage_lower = 13 melee_damage_upper = 25 -/mob/living/simple_animal/hostile/creature/strong/cult +/mob/living/simple_mob/hostile/creature/strong/cult faction = "cult" min_oxy = 0 @@ -70,9 +70,9 @@ supernatural = 1 -/mob/living/simple_animal/hostile/creature/cult/cultify() +/mob/living/simple_mob/hostile/creature/cult/cultify() return -/mob/living/simple_animal/hostile/creature/cult/Life() +/mob/living/simple_mob/hostile/creature/cult/Life() ..() check_horde() diff --git a/code/modules/mob/living/simple_animal/aliens/drone.dm b/code/modules/mob/living/simple_animal/aliens/drone.dm index e51dfd82a7..70cf52731d 100644 --- a/code/modules/mob/living/simple_animal/aliens/drone.dm +++ b/code/modules/mob/living/simple_animal/aliens/drone.dm @@ -1,6 +1,6 @@ //malfunctioning combat drones -/mob/living/simple_animal/hostile/malf_drone +/mob/living/simple_mob/hostile/malf_drone name = "combat drone" desc = "An automated combat drone armed with state of the art weaponry and shielding." icon_state = "drone3" @@ -51,7 +51,7 @@ var/exploding = 0 var/has_loot = 1 -/mob/living/simple_animal/hostile/malf_drone/New() +/mob/living/simple_mob/hostile/malf_drone/New() ..() if(prob(5)) projectiletype = /obj/item/projectile/beam/pulse/drone @@ -60,14 +60,14 @@ ion_trail.set_up(src) ion_trail.start() -/mob/living/simple_animal/hostile/malf_drone/Process_Spacemove(var/check_drift = 0) +/mob/living/simple_mob/hostile/malf_drone/Process_Spacemove(var/check_drift = 0) return 1 -/mob/living/simple_animal/hostile/malf_drone/isSynthetic() +/mob/living/simple_mob/hostile/malf_drone/isSynthetic() return TRUE //self repair systems have a chance to bring the drone back to life -/mob/living/simple_animal/hostile/malf_drone/Life() +/mob/living/simple_mob/hostile/malf_drone/Life() //emps and lots of damage can temporarily shut us down if(disabled > 0) @@ -150,18 +150,18 @@ ..() //ion rifle! -/mob/living/simple_animal/hostile/malf_drone/emp_act(severity) +/mob/living/simple_mob/hostile/malf_drone/emp_act(severity) health -= rand(3,15) * (severity + 1) disabled = rand(150, 600) hostile = 0 walk(src,0) ..() -/mob/living/simple_animal/hostile/malf_drone/death() +/mob/living/simple_mob/hostile/malf_drone/death() ..(null,"suddenly breaks apart.") qdel(src) -/mob/living/simple_animal/hostile/malf_drone/Destroy() +/mob/living/simple_mob/hostile/malf_drone/Destroy() //More advanced than the default S_A loot system, for visual effect and random tech levels. if(has_loot) var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread @@ -280,7 +280,7 @@ // A slightly easier drone, for POIs. // Difference is that it should not be faster than you. -/mob/living/simple_animal/hostile/malf_drone/lesser +/mob/living/simple_mob/hostile/malf_drone/lesser desc = "An automated combat drone with an aged apperance." returns_home = TRUE move_to_delay = 6 \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/aliens/faithless.dm b/code/modules/mob/living/simple_animal/aliens/faithless.dm index af2e7da48d..ebec4dd81b 100644 --- a/code/modules/mob/living/simple_animal/aliens/faithless.dm +++ b/code/modules/mob/living/simple_animal/aliens/faithless.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/hostile/faithless +/mob/living/simple_mob/hostile/faithless name = "Faithless" desc = "The Wish Granter's faith in humanity, incarnate" icon_state = "faithless" @@ -37,15 +37,15 @@ speak_chance = 0 -/mob/living/simple_animal/hostile/faithless/Process_Spacemove(var/check_drift = 0) +/mob/living/simple_mob/hostile/faithless/Process_Spacemove(var/check_drift = 0) return 1 -/mob/living/simple_animal/hostile/faithless/set_target() +/mob/living/simple_mob/hostile/faithless/set_target() . = ..() if(.) audible_emote("wails at [target_mob]") -/mob/living/simple_animal/hostile/faithless/PunchTarget() +/mob/living/simple_mob/hostile/faithless/PunchTarget() . = ..() var/mob/living/L = . if(istype(L)) @@ -53,18 +53,18 @@ L.Weaken(3) L.visible_message("\the [src] knocks down \the [L]!") -/mob/living/simple_animal/hostile/faithless/cult +/mob/living/simple_mob/hostile/faithless/cult faction = "cult" supernatural = 1 -/mob/living/simple_animal/hostile/faithless/cult/cultify() +/mob/living/simple_mob/hostile/faithless/cult/cultify() return -/mob/living/simple_animal/hostile/faithless/cult/Life() +/mob/living/simple_mob/hostile/faithless/cult/Life() ..() check_horde() -/mob/living/simple_animal/hostile/faithless/strong +/mob/living/simple_mob/hostile/faithless/strong maxHealth = 100 health = 100 @@ -72,14 +72,13 @@ melee_damage_lower = 13 melee_damage_upper = 28 - -/mob/living/simple_animal/hostile/faithless/strong/cult +/mob/living/simple_mob/hostile/faithless/strong/cult faction = "cult" supernatural = 1 -/mob/living/simple_animal/hostile/faithless/cult/cultify() +/mob/living/simple_mob/hostile/faithless/cult/cultify() return -/mob/living/simple_animal/hostile/faithless/cult/Life() +/mob/living/simple_mob/hostile/faithless/cult/Life() ..() check_horde() \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/aliens/hivebot.dm b/code/modules/mob/living/simple_animal/aliens/hivebot.dm index e322198815..12851c5af3 100644 --- a/code/modules/mob/living/simple_animal/aliens/hivebot.dm +++ b/code/modules/mob/living/simple_animal/aliens/hivebot.dm @@ -1,9 +1,9 @@ // Hivebots are tuned towards how many default lasers are needed to kill them. // As such, if laser damage is ever changed, you should change this define. -#define LASERS_TO_KILL *30 +#define LASERS_TO_KILL * 40 // Default hivebot is melee, and a bit more meaty, so it can meatshield for their ranged friends. -/mob/living/simple_animal/hostile/hivebot +/mob/living/simple_mob/hostile/hivebot name = "hivebot" desc = "A robot. It appears to be somewhat resilient, but lacks a true weapon." icon = 'icons/mob/hivebot.dmi' @@ -52,13 +52,13 @@ say_maybe_target = list("Possible threat detected. Investigating.", "Motion detected.", "Investigating.") say_got_target = list("Threat detected.", "New task: Remove threat.", "Threat removal engaged.", "Engaging target.") -/mob/living/simple_animal/hostile/hivebot/isSynthetic() +/mob/living/simple_mob/hostile/hivebot/isSynthetic() return TRUE // Subtypes. // Melee like the base type, but more fragile. -/mob/living/simple_animal/hostile/hivebot/swarm +/mob/living/simple_mob/hostile/hivebot/swarm name = "swarm hivebot" desc = "A robot. It looks fragile and weak" maxHealth = 1 LASERS_TO_KILL @@ -67,7 +67,7 @@ melee_damage_upper = 8 // This one has a semi-weak ranged attack. -/mob/living/simple_animal/hostile/hivebot/range +/mob/living/simple_mob/hostile/hivebot/range name = "ranged hivebot" desc = "A robot. It has a simple ballistic weapon." ranged = 1 @@ -75,7 +75,7 @@ health = 2 LASERS_TO_KILL // This one shoots a burst of three, and is considerably more dangerous. -/mob/living/simple_animal/hostile/hivebot/range/rapid +/mob/living/simple_mob/hostile/hivebot/range/rapid name = "rapid hivebot" desc = "A robot. It has a fast firing ballistic rifle." icon_living = "strong" @@ -84,7 +84,7 @@ health = 2 LASERS_TO_KILL // Shoots EMPs, to screw over other robots. -/mob/living/simple_animal/hostile/hivebot/range/ion +/mob/living/simple_mob/hostile/hivebot/range/ion name = "engineering hivebot" desc = "A robot. It has a tool which emits focused electromagnetic pulses, which are deadly to synthetic adverseries." projectiletype = /obj/item/projectile/ion/small //VOREStation Edit @@ -95,7 +95,7 @@ health = 2 LASERS_TO_KILL // Shoots deadly lasers. -/mob/living/simple_animal/hostile/hivebot/range/laser +/mob/living/simple_mob/hostile/hivebot/range/laser name = "laser hivebot" desc = "A robot. It has an energy weapon." projectiletype = /obj/item/projectile/beam/blue @@ -104,7 +104,7 @@ health = 2 LASERS_TO_KILL // Beefy and ranged. -/mob/living/simple_animal/hostile/hivebot/range/strong +/mob/living/simple_mob/hostile/hivebot/range/strong name = "strong hivebot" desc = "A robot. This one has reinforced plating, and looks tougher." icon_living = "strong" @@ -114,7 +114,7 @@ melee_damage_upper = 15 // Also beefy, but tries to stay at their 'home', ideal for base defense. -/mob/living/simple_animal/hostile/hivebot/range/guard +/mob/living/simple_mob/hostile/hivebot/range/guard name = "guard hivebot" desc = "A robot. It seems to be guarding something." returns_home = TRUE @@ -122,7 +122,7 @@ health = 4 LASERS_TO_KILL // This one is intended for players to use. Well rounded and can make other hivebots follow them with verbs. -/mob/living/simple_animal/hostile/hivebot/range/player +/mob/living/simple_mob/hostile/hivebot/range/player name = "commander hivebot" desc = "A robot. This one seems to direct the others, and it has a laser weapon." icon_living = "commander" @@ -135,7 +135,7 @@ // Procs. -/mob/living/simple_animal/hostile/hivebot/death() +/mob/living/simple_mob/hostile/hivebot/death() ..() visible_message("[src] blows apart!") new /obj/effect/decal/cleanable/blood/gibs/robot(src.loc) @@ -144,17 +144,17 @@ s.start() qdel(src) -/mob/living/simple_animal/hostile/hivebot/speech_bubble_appearance() +/mob/living/simple_mob/hostile/hivebot/speech_bubble_appearance() return "synthetic_evil" -/mob/living/simple_animal/hostile/hivebot/verb/command_follow() +/mob/living/simple_mob/hostile/hivebot/verb/command_follow() set name = "Command - Follow" set category = "Hivebot" set desc = "This will ask other hivebots to follow you." say("Delegating new task: Follow.") - for(var/mob/living/simple_animal/hostile/hivebot/buddy in hearers(src)) + for(var/mob/living/simple_mob/hostile/hivebot/buddy in hearers(src)) if(buddy.faction != faction) continue if(buddy == src) @@ -164,14 +164,14 @@ spawn(rand(5, 10)) buddy.say( pick(buddy.say_understood) ) -/mob/living/simple_animal/hostile/hivebot/verb/command_stop() +/mob/living/simple_mob/hostile/hivebot/verb/command_stop() set name = "Command - Stop Following" set category = "Hivebot" set desc = "This will ask other hivebots to cease following you." say("Delegating new task: Stop following.") - for(var/mob/living/simple_animal/hostile/hivebot/buddy in hearers(src)) + for(var/mob/living/simple_mob/hostile/hivebot/buddy in hearers(src)) if(buddy.faction != faction) continue if(buddy == src) @@ -180,7 +180,7 @@ spawn(rand(5, 10)) buddy.say( pick(buddy.say_understood) ) -/mob/living/simple_animal/hostile/hivebot/tele//this still needs work +/mob/living/simple_mob/hostile/hivebot/tele//this still needs work name = "Beacon" desc = "Some odd beacon thing" icon = 'icons/mob/hivebot.dmi' @@ -219,11 +219,11 @@ bot_amt-- switch(bot_type) if("norm") - new /mob/living/simple_animal/hostile/hivebot(get_turf(src)) + new /mob/living/simple_mob/hostile/hivebot(get_turf(src)) if("range") - new /mob/living/simple_animal/hostile/hivebot/range(get_turf(src)) + new /mob/living/simple_mob/hostile/hivebot/range(get_turf(src)) if("rapid") - new /mob/living/simple_animal/hostile/hivebot/range/rapid(get_turf(src)) + new /mob/living/simple_mob/hostile/hivebot/range/rapid(get_turf(src)) spawn(100) qdel(src) return @@ -238,3 +238,5 @@ /obj/item/projectile/bullet/hivebot damage = 10 damage_type = BRUTE + +#undef LASERS_TO_KILL \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/aliens/mimic.dm b/code/modules/mob/living/simple_animal/aliens/mimic.dm index 7612e14fa2..da254315be 100644 --- a/code/modules/mob/living/simple_animal/aliens/mimic.dm +++ b/code/modules/mob/living/simple_animal/aliens/mimic.dm @@ -2,7 +2,7 @@ // Abstract Class // -/mob/living/simple_animal/hostile/mimic +/mob/living/simple_mob/hostile/mimic name = "crate" desc = "A rectangular steel crate." icon = 'icons/obj/storage.dmi' @@ -41,16 +41,16 @@ showvoreprefs = 0 //VOREStation Edit - Hides mechanical vore prefs for mimics. You can't see their gaping maws when they're just sitting idle. -/mob/living/simple_animal/hostile/mimic/set_target() +/mob/living/simple_mob/hostile/mimic/set_target() . = ..() if(.) audible_emote("growls at [.]") -/mob/living/simple_animal/hostile/mimic/death() +/mob/living/simple_mob/hostile/mimic/death() ..() qdel(src) -/mob/living/simple_animal/hostile/mimic/will_show_tooltip() +/mob/living/simple_mob/hostile/mimic/will_show_tooltip() return FALSE @@ -59,7 +59,7 @@ // // Aggro when you try to open them. Will also pickup loot when spawns and drop it when dies. -/mob/living/simple_animal/hostile/mimic/crate +/mob/living/simple_mob/hostile/mimic/crate attacktext = list("bitten") @@ -68,52 +68,52 @@ var/attempt_open = 0 // Pickup loot -/mob/living/simple_animal/hostile/mimic/crate/initialize() +/mob/living/simple_animal/hostile/mimic/crate/Initialize() . = ..() for(var/obj/item/I in loc) I.forceMove(src) -/mob/living/simple_animal/hostile/mimic/crate/DestroySurroundings() +/mob/living/simple_mob/hostile/mimic/crate/DestroySurroundings() ..() if(prob(90)) icon_state = "[initial(icon_state)]open" else icon_state = initial(icon_state) -/mob/living/simple_animal/hostile/mimic/crate/ListTargets() +/mob/living/simple_mob/hostile/mimic/crate/ListTargets() if(attempt_open) return ..() else return ..(1) -/mob/living/simple_animal/hostile/mimic/crate/set_target() +/mob/living/simple_mob/hostile/mimic/crate/set_target() . = ..() if(.) trigger() -/mob/living/simple_animal/hostile/mimic/crate/PunchTarget() +/mob/living/simple_mob/hostile/mimic/crate/PunchTarget() . = ..() if(.) icon_state = initial(icon_state) -/mob/living/simple_animal/hostile/mimic/crate/proc/trigger() +/mob/living/simple_mob/hostile/mimic/crate/proc/trigger() if(!attempt_open) visible_message("[src] starts to move!") attempt_open = 1 -/mob/living/simple_animal/hostile/mimic/crate/adjustBruteLoss(var/damage) +/mob/living/simple_mob/hostile/mimic/crate/adjustBruteLoss(var/damage) trigger() ..(damage) -/mob/living/simple_animal/hostile/mimic/crate/LoseTarget() +/mob/living/simple_mob/hostile/mimic/crate/LoseTarget() ..() icon_state = initial(icon_state) -/mob/living/simple_animal/hostile/mimic/crate/LostTarget() +/mob/living/simple_mob/hostile/mimic/crate/LostTarget() ..() icon_state = initial(icon_state) -/mob/living/simple_animal/hostile/mimic/crate/death() +/mob/living/simple_mob/hostile/mimic/crate/death() var/obj/structure/closet/crate/C = new(get_turf(src)) // Put loot in crate for(var/obj/O in src) @@ -122,7 +122,7 @@ O.forceMove(C) ..() -/mob/living/simple_animal/hostile/mimic/crate/PunchTarget() +/mob/living/simple_mob/hostile/mimic/crate/PunchTarget() . =..() var/mob/living/L = . if(istype(L)) @@ -136,7 +136,7 @@ var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/cable, /obj/structure/window, /obj/item/projectile/animate) -/mob/living/simple_animal/hostile/mimic/copy +/mob/living/simple_mob/hostile/mimic/copy health = 100 maxHealth = 100 @@ -144,11 +144,11 @@ var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/ca var/destroy_objects = 0 var/knockdown_people = 0 -/mob/living/simple_animal/hostile/mimic/copy/New(loc, var/obj/copy, var/mob/living/creator) +/mob/living/simple_mob/hostile/mimic/copy/New(loc, var/obj/copy, var/mob/living/creator) ..(loc) CopyObject(copy, creator) -/mob/living/simple_animal/hostile/mimic/copy/death() +/mob/living/simple_mob/hostile/mimic/copy/death() for(var/atom/movable/M in src) if(isbelly(M)) //VOREStation edit @@ -156,12 +156,12 @@ var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/ca M.forceMove(get_turf(src)) ..() -/mob/living/simple_animal/hostile/mimic/copy/ListTargets() +/mob/living/simple_mob/hostile/mimic/copy/ListTargets() // Return a list of targets that isn't the creator . = ..() return . - creator -/mob/living/simple_animal/hostile/mimic/copy/proc/CopyObject(var/obj/O, var/mob/living/creator) +/mob/living/simple_mob/hostile/mimic/copy/proc/CopyObject(var/obj/O, var/mob/living/creator) if((istype(O, /obj/item) || istype(O, /obj/structure)) && !is_type_in_list(O, protected_objects)) @@ -193,11 +193,11 @@ var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/ca return 1 return -/mob/living/simple_animal/hostile/mimic/copy/DestroySurroundings() +/mob/living/simple_mob/hostile/mimic/copy/DestroySurroundings() if(destroy_objects) ..() -/mob/living/simple_animal/hostile/mimic/copy/PunchTarget() +/mob/living/simple_mob/hostile/mimic/copy/PunchTarget() . =..() if(knockdown_people) var/mob/living/L = . diff --git a/code/modules/mob/living/simple_animal/aliens/shade.dm b/code/modules/mob/living/simple_animal/aliens/shade.dm index c1c2f1dc01..000061f0f8 100644 --- a/code/modules/mob/living/simple_animal/aliens/shade.dm +++ b/code/modules/mob/living/simple_animal/aliens/shade.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/shade +/mob/living/simple_mob/shade name = "Shade" real_name = "Shade" desc = "A bound spirit" @@ -40,17 +40,17 @@ loot_list = list(/obj/item/weapon/ectoplasm = 100) -/mob/living/simple_animal/shade/cultify() +/mob/living/simple_mob/shade/cultify() return -/mob/living/simple_animal/shade/attackby(var/obj/item/O as obj, var/mob/user as mob) +/mob/living/simple_mob/shade/attackby(var/obj/item/O as obj, var/mob/user as mob) if(istype(O, /obj/item/device/soulstone)) var/obj/item/device/soulstone/S = O; S.transfer_soul("SHADE", src, user) return ..() -/mob/living/simple_animal/shade/death() +/mob/living/simple_mob/shade/death() ..() for(var/mob/M in viewers(src, null)) if((M.client && !( M.blinded ))) diff --git a/code/modules/mob/living/simple_animal/aliens/statue.dm b/code/modules/mob/living/simple_animal/aliens/statue.dm index f80181bdb0..0dc3a44868 100644 --- a/code/modules/mob/living/simple_animal/aliens/statue.dm +++ b/code/modules/mob/living/simple_animal/aliens/statue.dm @@ -2,7 +2,7 @@ //Weeping angels/SCP-173 hype //Horrible shitcoding and stolen code adaptations below. You have been warned. -/mob/living/simple_animal/hostile/statue +/mob/living/simple_mob/hostile/statue name = "statue" // matches the name of the statue with the flesh-to-stone spell desc = "An incredibly lifelike marble carving. Its eyes seems to follow you..." // same as an ordinary statue with the added "eye following you" description icon = 'icons/obj/statue.dmi' @@ -79,21 +79,21 @@ // No movement while seen code. -/mob/living/simple_animal/hostile/statue/New(loc) +/mob/living/simple_mob/hostile/statue/New(loc) ..() // Give spells add_spell(new/spell/aoe_turf/flicker_lights) add_spell(new/spell/aoe_turf/blindness) add_spell(new/spell/aoe_turf/shatter) -/mob/living/simple_animal/hostile/statue/DestroySurroundings() +/mob/living/simple_mob/hostile/statue/DestroySurroundings() if(can_be_seen(get_turf(loc))) if(client) to_chat(src, "You cannot move, there are eyes on you!") return 0 return ..() -/mob/living/simple_animal/hostile/statue/attackby(var/obj/item/O as obj, var/mob/user as mob) //banishing the statue is a risky job +/mob/living/simple_mob/hostile/statue/attackby(var/obj/item/O as obj, var/mob/user as mob) //banishing the statue is a risky job if(istype(O, /obj/item/weapon/nullrod)) visible_message("[user] tries to banish [src] with [O]!") if(do_after(user, 15, src)) @@ -111,21 +111,21 @@ resistance = initial(resistance) ..() -/mob/living/simple_animal/hostile/statue/death() +/mob/living/simple_mob/hostile/statue/death() var/chunks_to_spawn = rand(2,5) for(var/I = 1 to chunks_to_spawn) new /obj/item/stack/material/marble(get_turf(loc)) new /obj/item/cursed_marble(get_turf(loc)) ..() -/mob/living/simple_animal/hostile/statue/Move(turf/NewLoc) +/mob/living/simple_mob/hostile/statue/Move(turf/NewLoc) if(can_be_seen(NewLoc)) if(client) to_chat(src, "You cannot move, there are eyes on you!") return 0 return ..() -/mob/living/simple_animal/hostile/statue/Life() +/mob/living/simple_mob/hostile/statue/Life() ..() handle_target() handleAnnoyance() @@ -137,7 +137,7 @@ else if ((annoyance - 2) > 0) annoyance -= 2 -/mob/living/simple_animal/hostile/statue/proc/handle_target() +/mob/living/simple_mob/hostile/statue/proc/handle_target() if(target_mob) // If we have a target and we're AI controlled var/mob/watching = can_be_seen() // If they're not our target @@ -148,7 +148,7 @@ target_mob = watching -/mob/living/simple_animal/hostile/statue/proc/handleAnnoyance() +/mob/living/simple_mob/hostile/statue/proc/handleAnnoyance() if(respond) //so it won't blind people 24/7 respond = 0 if (annoyance > 30) @@ -163,7 +163,7 @@ respond = 1 -/mob/living/simple_animal/hostile/statue/proc/AI_blind() +/mob/living/simple_mob/hostile/statue/proc/AI_blind() for(var/mob/living/L in oviewers(12, src)) //the range is so big, because it tries to keep out of sight and can't reengage if you get too far if (prob(70)) if(ishuman(L)) @@ -174,7 +174,7 @@ L.Blind(2) return -/mob/living/simple_animal/hostile/statue/proc/AI_flash() +/mob/living/simple_mob/hostile/statue/proc/AI_flash() if (prob(60)) visible_message("The statue slowly points at the light.") for(var/obj/machinery/light/L in oview(12, src)) @@ -182,7 +182,7 @@ return -/mob/living/simple_animal/hostile/statue/proc/AI_mirrorshmash() +/mob/living/simple_mob/hostile/statue/proc/AI_mirrorshmash() for(var/obj/structure/mirror/M in oview(4, src)) if ((!M.shattered )||(!M.glass)) visible_message("The statue slowly points at the mirror!") @@ -192,7 +192,7 @@ -/mob/living/simple_animal/hostile/statue/AttackTarget() +/mob/living/simple_mob/hostile/statue/AttackTarget() if(can_be_seen(get_turf(loc))) if(client) to_chat(src, "You cannot attack, there are eyes on you!") @@ -203,7 +203,7 @@ -/mob/living/simple_animal/hostile/statue/DoPunch(var/atom/A) //had to redo that, since it's supposed to target only head and upper body +/mob/living/simple_mob/hostile/statue/DoPunch(var/atom/A) //had to redo that, since it's supposed to target only head and upper body if(!Adjacent(A)) // They could've moved in the meantime. return FALSE @@ -228,11 +228,11 @@ -/mob/living/simple_animal/hostile/statue/face_atom() +/mob/living/simple_mob/hostile/statue/face_atom() if(!can_be_seen(get_turf(loc))) ..() -/mob/living/simple_animal/hostile/statue/proc/can_be_seen(turf/destination) +/mob/living/simple_mob/hostile/statue/proc/can_be_seen(turf/destination) if(!cannot_be_seen) return null @@ -275,18 +275,18 @@ // Cannot talk -/mob/living/simple_animal/hostile/statue/say() +/mob/living/simple_mob/hostile/statue/say() return 0 // Turn to dust when gibbed -/mob/living/simple_animal/hostile/statue/gib() +/mob/living/simple_mob/hostile/statue/gib() dust() // Stop attacking clientless mobs -/mob/living/simple_animal/hostile/statue/proc/CanAttack(atom/the_target) //ignore clientless mobs +/mob/living/simple_mob/hostile/statue/proc/CanAttack(atom/the_target) //ignore clientless mobs if(isliving(the_target)) var/mob/living/L = the_target if(!L.client && !L.ckey) @@ -319,7 +319,7 @@ spell_flags = 0 range = 10 -/spell/aoe_turf/blindness/cast(list/targets, mob/living/simple_animal/hostile/statue/user = usr) +/spell/aoe_turf/blindness/cast(list/targets, mob/living/simple_mob/hostile/statue/user = usr) for(var/mob/living/L in targets) if(L == user || L == user.creator) continue @@ -350,7 +350,7 @@ -/mob/living/simple_animal/hostile/statue/verb/toggle_darkness() +/mob/living/simple_mob/hostile/statue/verb/toggle_darkness() set name = "Toggle Darkness" set desc = "You ARE the darkness." set category = "Abilities" @@ -360,13 +360,13 @@ -/mob/living/simple_animal/hostile/statue/restrained() +/mob/living/simple_mob/hostile/statue/restrained() . = ..() if(can_be_seen(loc)) return 1 -/mob/living/simple_animal/hostile/statue/ListTargets(dist = view_range) +/mob/living/simple_mob/hostile/statue/ListTargets(dist = view_range) var/list/L = mobs_in_xray_view(dist, src) for(var/obj/mecha/M in mechas_list) @@ -430,7 +430,7 @@ /obj/item/cursed_marble/proc/transfer_personality(var/mob/candidate, var/mob/user) announce_ghost_joinleave(candidate, 0, "They are a statue now.") src.searching = 2 - var/mob/living/simple_animal/hostile/statue/S = new(get_turf(src)) + var/mob/living/simple_mob/hostile/statue/S = new(get_turf(src)) S.client = candidate.client if(user) S.creator = user @@ -451,7 +451,7 @@ var/choice = alert(user, "Are you sure you want to crush the marble? (this will spawn a clientless version of the statue, hostile to everyone, but you)", "Crush it?", "Yes", "No") if(choice) if(choice == "Yes") - var/mob/living/simple_animal/hostile/statue/S = new /mob/living/simple_animal/hostile/statue(get_turf(user)) + var/mob/living/simple_mob/hostile/statue/S = new /mob/living/simple_mob/hostile/statue(get_turf(user)) visible_message("The slab suddenly takes the shape of a humanoid!") S.creator = user qdel(src) \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/animals/bat.dm b/code/modules/mob/living/simple_animal/animals/bat.dm index 680091010e..3158814353 100644 --- a/code/modules/mob/living/simple_animal/animals/bat.dm +++ b/code/modules/mob/living/simple_animal/animals/bat.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/hostile/scarybat +/mob/living/simple_mob/hostile/scarybat name = "space bats" desc = "A swarm of cute little blood sucking bats that looks pretty upset." tt_desc = "N Bestia gregaria" //Nispean swarm bats, because of course Nisp has swarm bats @@ -47,25 +47,25 @@ var/mob/living/owner -/mob/living/simple_animal/hostile/scarybat/New(loc, mob/living/L as mob) +/mob/living/simple_mob/hostile/scarybat/New(loc, mob/living/L as mob) ..() if(istype(L)) owner = L -/mob/living/simple_animal/hostile/scarybat/Process_Spacemove(var/check_drift = 0) +/mob/living/simple_mob/hostile/scarybat/Process_Spacemove(var/check_drift = 0) return ..() -/mob/living/simple_animal/hostile/scarybat/set_target() +/mob/living/simple_mob/hostile/scarybat/set_target() . = ..() if(.) emote("flutters towards [.]") -/mob/living/simple_animal/hostile/scarybat/ListTargets() +/mob/living/simple_mob/hostile/scarybat/ListTargets() . = ..() if(owner) return . - owner -/mob/living/simple_animal/hostile/scarybat/PunchTarget() +/mob/living/simple_mob/hostile/scarybat/PunchTarget() . =..() var/mob/living/L = . if(istype(L)) @@ -73,13 +73,13 @@ L.Stun(1) L.visible_message("\the [src] scares \the [L]!") -/mob/living/simple_animal/hostile/scarybat/cult +/mob/living/simple_mob/hostile/scarybat/cult faction = "cult" supernatural = 1 -/mob/living/simple_animal/hostile/scarybat/cult/cultify() +/mob/living/simple_mob/hostile/scarybat/cult/cultify() return -/mob/living/simple_animal/hostile/scarybat/cult/Life() +/mob/living/simple_mob/hostile/scarybat/cult/Life() ..() check_horde() diff --git a/code/modules/mob/living/simple_animal/animals/bear.dm b/code/modules/mob/living/simple_animal/animals/bear.dm index cc154533da..dfd6a56cab 100644 --- a/code/modules/mob/living/simple_animal/animals/bear.dm +++ b/code/modules/mob/living/simple_animal/animals/bear.dm @@ -1,5 +1,5 @@ //Space bears! -/mob/living/simple_animal/hostile/bear +/mob/living/simple_mob/hostile/bear name = "space bear" desc = "A product of Space Russia?" tt_desc = "U Ursinae aetherius" //...bearspace? Maybe. @@ -48,7 +48,7 @@ // var/stance_step = 0 -/mob/living/simple_animal/hostile/bear/handle_stance(var/new_stance) +/mob/living/simple_mob/hostile/bear/handle_stance(var/new_stance) // Below was a bunch of code that made this specific mob be 'alert' and will hurt you when it gets closer. // It's commented out because it made infinite loops and the AI is going to be moved/rewritten sometime soon (famous last words) // and it would be better if this 'alert before attacking' behaviour was on the parent instead of a specific type of mob anyways. @@ -103,7 +103,7 @@ ..() */ -/mob/living/simple_animal/hostile/bear/update_icons() +/mob/living/simple_mob/hostile/bear/update_icons() ..() if(!stat) if(loc && istype(loc,/turf/space)) @@ -111,16 +111,16 @@ else icon_state = "bearfloor" -/mob/living/simple_animal/hostile/bear/Process_Spacemove(var/check_drift = 0) +/mob/living/simple_mob/hostile/bear/Process_Spacemove(var/check_drift = 0) return -/mob/living/simple_animal/hostile/bear/FindTarget() +/mob/living/simple_mob/hostile/bear/FindTarget() . = ..() if(.) custom_emote(1,"stares alertly at [.]") // handle_stance(STANCE_ALERT) -/mob/living/simple_animal/hostile/bear/PunchTarget() +/mob/living/simple_mob/hostile/bear/PunchTarget() if(!Adjacent(target_mob)) return custom_emote(1, pick( list("slashes at [target_mob]", "bites [target_mob]") ) ) diff --git a/code/modules/mob/living/simple_animal/animals/birds_vr.dm b/code/modules/mob/living/simple_animal/animals/birds_vr.dm index b6332ad0eb..0331e4931b 100644 --- a/code/modules/mob/living/simple_animal/animals/birds_vr.dm +++ b/code/modules/mob/living/simple_animal/animals/birds_vr.dm @@ -1,5 +1,5 @@ //Why are these a subclass of cat? -/mob/living/simple_animal/bird +/mob/living/simple_mob/bird name = "parrot" desc = "A domesticated bird. Tweet tweet!" icon = 'icons/mob/birds.dmi' @@ -18,127 +18,127 @@ holder_type = /obj/item/weapon/holder/bird -/mob/living/simple_animal/bird/kea +/mob/living/simple_mob/bird/kea name = "Kea" icon_state = "kea-flap" icon_living = "kea-flap" icon_dead = "kea-dead" -/mob/living/simple_animal/bird/eclectus +/mob/living/simple_mob/bird/eclectus name = "Eclectus" icon_state = "eclectus-flap" icon_living = "eclectus-flap" icon_dead = "eclectus-dead" -/mob/living/simple_animal/bird/eclectusf +/mob/living/simple_mob/bird/eclectusf name = "Eclectus" icon_state = "eclectusf-flap" icon_living = "eclectusf-flap" icon_dead = "eclectusf-dead" -/mob/living/simple_animal/bird/greybird +/mob/living/simple_mob/bird/greybird name = "Grey Bird" icon_state = "agrey-flap" icon_living = "agrey-flap" icon_dead = "agrey-dead" -/mob/living/simple_animal/bird/blue_caique +/mob/living/simple_mob/bird/blue_caique name = "Blue Caique " icon_state = "bcaique-flap" icon_living = "bcaique-flap" icon_dead = "bcaique-dead" -/mob/living/simple_animal/bird/white_caique +/mob/living/simple_mob/bird/white_caique name = "White caique" icon_state = "wcaique-flap" icon_living = "wcaique-flap" icon_dead = "wcaique-dead" -/mob/living/simple_animal/bird/green_budgerigar +/mob/living/simple_mob/bird/green_budgerigar name = "Green Budgerigar" icon_state = "gbudge-flap" icon_living = "gbudge-flap" icon_dead = "gbudge-dead" -/mob/living/simple_animal/bird/blue_Budgerigar +/mob/living/simple_mob/bird/blue_Budgerigar name = "Blue Budgerigar" icon_state = "bbudge-flap" icon_living = "bbudge-flap" icon_dead = "bbudge-dead" -/mob/living/simple_animal/bird/bluegreen_Budgerigar +/mob/living/simple_mob/bird/bluegreen_Budgerigar name = "Bluegreen Budgerigar" icon_state = "bgbudge-flap" icon_living = "bgbudge-flap" icon_dead = "bgbudge-dead" -/mob/living/simple_animal/bird/commonblackbird +/mob/living/simple_mob/bird/commonblackbird name = "Black Bird" icon_state = "commonblackbird" icon_living = "commonblackbird" icon_dead = "commonblackbird-dead" -/mob/living/simple_animal/bird/azuretit +/mob/living/simple_mob/bird/azuretit name = "Azure Tit" icon_state = "azuretit" icon_living = "azuretit" icon_dead = "azuretit-dead" -/mob/living/simple_animal/bird/europeanrobin +/mob/living/simple_mob/bird/europeanrobin name = "European Robin" icon_state = "europeanrobin" icon_living = "europeanrobin" icon_dead = "europeanrobin-dead" -/mob/living/simple_animal/bird/goldcrest +/mob/living/simple_mob/bird/goldcrest name = "Goldcrest" icon_state = "goldcrest" icon_living = "goldcrest" icon_dead = "goldcrest-dead" -/mob/living/simple_animal/bird/ringneckdove +/mob/living/simple_mob/bird/ringneckdove name = "Ringneck Dove" icon_state = "ringneckdove" icon_living = "ringneckdove" icon_dead = "ringneckdove-dead" -/mob/living/simple_animal/bird/cockatiel +/mob/living/simple_mob/bird/cockatiel name = "Cockatiel" icon_state = "tiel-flap" icon_living = "tiel-flap" icon_dead = "tiel-dead" -/mob/living/simple_animal/bird/white_cockatiel +/mob/living/simple_mob/bird/white_cockatiel name = "White Cockatiel" icon_state = "wtiel-flap" icon_living = "wtiel-flap" icon_dead = "wtiel-dead" -/mob/living/simple_animal/bird/yellowish_cockatiel +/mob/living/simple_mob/bird/yellowish_cockatiel name = "Yellowish Cockatiel" icon_state = "luttiel-flap" icon_living = "luttiel-flap" icon_dead = "luttiel-dead" -/mob/living/simple_animal/bird/grey_cockatiel +/mob/living/simple_mob/bird/grey_cockatiel name = "Grey Cockatiel" icon_state = "blutiel-flap" icon_living = "blutiel-flap" icon_dead = "blutiel-dead" -/mob/living/simple_animal/bird/too +/mob/living/simple_mob/bird/too name = "Too" icon_state = "too-flap" icon_living = "too-flap" icon_dead = "too-dead" -/mob/living/simple_animal/bird/hooded_too +/mob/living/simple_mob/bird/hooded_too name = "Utoo" icon_state = "utoo-flap" icon_living = "utoo-flap" icon_dead = "utoo-dead" -/mob/living/simple_animal/bird/pink_too +/mob/living/simple_mob/bird/pink_too name = "Mtoo" icon_state = "mtoo-flap" icon_living = "mtoo-flap" diff --git a/code/modules/mob/living/simple_animal/animals/carp.dm b/code/modules/mob/living/simple_animal/animals/carp.dm index 7e7ae92876..d5419c8462 100644 --- a/code/modules/mob/living/simple_animal/animals/carp.dm +++ b/code/modules/mob/living/simple_animal/animals/carp.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/hostile/carp +/mob/living/simple_mob/hostile/carp name = "space carp" desc = "A ferocious, fang-bearing creature that resembles a fish." tt_desc = "U Cyprinus aetherius" //carpspace? maybe @@ -38,7 +38,7 @@ meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat -/mob/living/simple_animal/hostile/carp/large +/mob/living/simple_mob/hostile/carp/large name = "elder carp" desc = "An older, more matured carp. Few survive to this age due to their aggressiveness." icon = 'icons/mob/64x32.dmi' @@ -56,7 +56,7 @@ maxHealth = 50 -/mob/living/simple_animal/hostile/carp/large/huge +/mob/living/simple_mob/hostile/carp/large/huge name = "great white carp" desc = "A very rare breed of carp- and a very aggressive one." icon = 'icons/mob/64x64.dmi' @@ -75,15 +75,15 @@ old_y = -16 pixel_y = -16 -/mob/living/simple_animal/hostile/carp/Process_Spacemove(var/check_drift = 0) +/mob/living/simple_mob/hostile/carp/Process_Spacemove(var/check_drift = 0) return 1 //No drifting in space for space carp! //original comments do not steal -/mob/living/simple_animal/hostile/carp/set_target() +/mob/living/simple_mob/hostile/carp/set_target() . = ..() if(.) custom_emote(1,"nashes at [.]") -/mob/living/simple_animal/hostile/carp/PunchTarget() +/mob/living/simple_mob/hostile/carp/PunchTarget() . =..() var/mob/living/L = . if(istype(L)) diff --git a/code/modules/mob/living/simple_animal/animals/cat.dm b/code/modules/mob/living/simple_animal/animals/cat.dm index 8877ea8959..5e554a0f8a 100644 --- a/code/modules/mob/living/simple_animal/animals/cat.dm +++ b/code/modules/mob/living/simple_animal/animals/cat.dm @@ -1,5 +1,5 @@ //Cat -/mob/living/simple_animal/cat +/mob/living/simple_mob/cat name = "cat" desc = "A domesticated, feline pet. Has a tendency to adopt crewmembers." tt_desc = "E Felis silvestris catus" @@ -44,7 +44,7 @@ var/turns_since_scan = 0 var/mob/flee_target -/mob/living/simple_animal/cat/Life() +/mob/living/simple_mob/cat/Life() . = ..() if(!.) return @@ -62,20 +62,20 @@ handle_flee_target() -/mob/living/simple_animal/cat/PunchTarget() - if(istype(target_mob,/mob/living/simple_animal/mouse)) - var/mob/living/simple_animal/mouse/mouse = target_mob +/mob/living/simple_mob/cat/PunchTarget() + if(ismouse(target_mob)) + var/mob/living/simple_mob/animal/passive/mouse/mouse = target_mob mouse.splat() visible_emote(pick("bites \the [mouse]!","toys with \the [mouse].","chomps on \the [mouse]!")) return mouse else ..() -/mob/living/simple_animal/cat/Found(var/atom/found_atom) - if(istype(found_atom,/mob/living/simple_animal/mouse) && SA_attackable(found_atom)) +/mob/living/simple_mob/cat/Found(var/atom/found_atom) + if(ismouse(found_atom) && SA_attackable(found_atom)) return found_atom -/mob/living/simple_animal/cat/proc/handle_flee_target() +/mob/living/simple_mob/cat/proc/handle_flee_target() //see if we should stop fleeing if (flee_target && !(flee_target in ListTargets(view_range))) flee_target = null @@ -88,21 +88,21 @@ stop_automated_movement = 1 walk_away(src, flee_target, 7, 2) -/mob/living/simple_animal/cat/react_to_attack(var/atom/A) +/mob/living/simple_mob/cat/react_to_attack(var/atom/A) if(A == src) return flee_target = A turns_since_scan = 5 -/mob/living/simple_animal/cat/ex_act() +/mob/living/simple_mob/cat/ex_act() . = ..() react_to_attack(src.loc) //Basic friend AI -/mob/living/simple_animal/cat/fluff +/mob/living/simple_mob/cat/fluff var/mob/living/carbon/human/friend var/befriend_job = null -/mob/living/simple_animal/cat/fluff/Life() +/mob/living/simple_mob/cat/fluff/Life() . = ..() if(!. || ai_inactive || !friend) return @@ -129,7 +129,7 @@ var/verb = pick("meows", "mews", "mrowls") audible_emote("[verb] anxiously.") -/mob/living/simple_animal/cat/fluff/verb/become_friends() +/mob/living/simple_mob/cat/fluff/verb/become_friends() set name = "Become Friends" set category = "IC" set src in view(1) @@ -153,7 +153,7 @@ return //RUNTIME IS ALIVE! SQUEEEEEEEE~ -/mob/living/simple_animal/cat/fluff/Runtime +/mob/living/simple_mob/cat/fluff/Runtime name = "Runtime" desc = "Her fur has the look and feel of velvet, and her tail quivers occasionally." tt_desc = "E Felis silvestris medicalis" //a hypoallergenic breed produced by NT for... medical purposes? Sure. @@ -165,7 +165,7 @@ icon_rest = "cat_rest" befriend_job = "Chief Medical Officer" -/mob/living/simple_animal/cat/kitten +/mob/living/simple_mob/cat/kitten name = "kitten" desc = "D'aaawwww" icon_state = "kitten" @@ -173,7 +173,6 @@ icon_living = "kitten" icon_dead = "kitten_dead" gender = NEUTER - holder_type = /obj/item/weapon/holder/cat/kitten //VOREStation Edit // Leaving this here for now. /obj/item/weapon/holder/cat/fluff/bones @@ -182,7 +181,7 @@ gender = MALE icon_state = "cat3" -/mob/living/simple_animal/cat/fluff/bones +/mob/living/simple_mob/cat/fluff/bones name = "Bones" desc = "That's Bones the cat. He's a laid back, black cat. Meow." gender = MALE @@ -194,11 +193,6 @@ holder_type = /obj/item/weapon/holder/cat/fluff/bones var/friend_name = "Erstatz Vryroxes" -/mob/living/simple_animal/cat/kitten/New() +/mob/living/simple_mob/cat/kitten/New() gender = pick(MALE, FEMALE) - ..() - -// VOREStation Edit - Adds generic tactical kittens -/obj/item/weapon/holder/cat/kitten - icon_state = "kitten" - w_class = ITEMSIZE_SMALL + ..() \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/animals/cat_vr.dm b/code/modules/mob/living/simple_animal/animals/cat_vr.dm index 43d166af35..d4be475cef 100644 --- a/code/modules/mob/living/simple_animal/animals/cat_vr.dm +++ b/code/modules/mob/living/simple_animal/animals/cat_vr.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/cat/fluff/Runtime/init_vore() +/mob/living/simple_mob/cat/fluff/Runtime/init_vore() ..() var/obj/belly/B = vore_selected B.name = "Stomach" @@ -38,7 +38,7 @@ icon_state = "kitten" w_class = ITEMSIZE_SMALL -/mob/living/simple_animal/cat/fluff/tabiranth +/mob/living/simple_mob/cat/fluff/tabiranth name = "Spirit" desc = "A small, inquisitive feline, who constantly seems to investigate his surroundings." icon = 'icons/mob/custom_items_mob.dmi' @@ -55,7 +55,7 @@ health = 50 //Emergency teleport - Until a spriter makes something better -/mob/living/simple_animal/cat/fluff/tabiranth/death(gibbed, deathmessage = "teleports away!") +/mob/living/simple_mob/cat/fluff/tabiranth/death(gibbed, deathmessage = "teleports away!") overlays = list() icon_state = "" flick("kphaseout",src) diff --git a/code/modules/mob/living/simple_animal/animals/corgi.dm b/code/modules/mob/living/simple_animal/animals/corgi.dm index 33bda8b2e0..52d2268be8 100644 --- a/code/modules/mob/living/simple_animal/animals/corgi.dm +++ b/code/modules/mob/living/simple_animal/animals/corgi.dm @@ -1,5 +1,5 @@ //Corgi -/mob/living/simple_animal/corgi +/mob/living/simple_mob/corgi name = "corgi" real_name = "corgi" desc = "It's a corgi." @@ -33,7 +33,7 @@ var/obj/item/inventory_back //IAN! SQUEEEEEEEEE~ -/mob/living/simple_animal/corgi/Ian +/mob/living/simple_mob/corgi/Ian name = "Ian" real_name = "Ian" //Intended to hold the name without altering it. gender = MALE @@ -44,7 +44,7 @@ response_disarm = "bops" response_harm = "kicks" -/mob/living/simple_animal/corgi/Ian/Life() +/mob/living/simple_mob/corgi/Ian/Life() ..() //Not replacing with SA FollowTarget mechanics because Ian behaves... very... specifically. @@ -100,7 +100,7 @@ name = "corgi meat" desc = "Tastes like... well, you know..." -/mob/living/simple_animal/corgi/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri +/mob/living/simple_mob/corgi/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri if(istype(O, /obj/item/weapon/newspaper)) if(!stat) for(var/mob/M in viewers(user, null)) @@ -113,7 +113,7 @@ else ..() -/mob/living/simple_animal/corgi/regenerate_icons() +/mob/living/simple_mob/corgi/regenerate_icons() overlays = list() if(inventory_head) @@ -137,7 +137,7 @@ return -/mob/living/simple_animal/corgi/puppy +/mob/living/simple_mob/corgi/puppy name = "corgi puppy" real_name = "corgi" desc = "It's a corgi puppy." @@ -146,7 +146,7 @@ icon_dead = "puppy_dead" //pupplies cannot wear anything. -/mob/living/simple_animal/corgi/puppy/Topic(href, href_list) +/mob/living/simple_mob/corgi/puppy/Topic(href, href_list) if(href_list["remove_inv"] || href_list["add_inv"]) usr << "You can't fit this on [src]" return @@ -154,7 +154,7 @@ //LISA! SQUEEEEEEEEE~ -/mob/living/simple_animal/corgi/Lisa +/mob/living/simple_mob/corgi/Lisa name = "Lisa" real_name = "Lisa" gender = FEMALE @@ -169,13 +169,13 @@ var/puppies = 0 //Lisa already has a cute bow! -/mob/living/simple_animal/corgi/Lisa/Topic(href, href_list) +/mob/living/simple_mob/corgi/Lisa/Topic(href, href_list) if(href_list["remove_inv"] || href_list["add_inv"]) to_chat(usr, "[src] already has a cute bow!") return ..() -/mob/living/simple_animal/corgi/Lisa/Life() +/mob/living/simple_mob/corgi/Lisa/Life() ..() if(!stat && !resting && !buckled) @@ -185,7 +185,7 @@ var/alone = 1 var/ian = 0 for(var/mob/M in oviewers(7, src)) - if(istype(M, /mob/living/simple_animal/corgi/Ian)) + if(istype(M, /mob/living/simple_mob/corgi/Ian)) if(M.client) alone = 0 break @@ -197,7 +197,7 @@ if(alone && ian && puppies < 4) if(near_camera(src) || near_camera(ian)) return - new /mob/living/simple_animal/corgi/puppy(loc) + new /mob/living/simple_mob/corgi/puppy(loc) if(prob(1)) @@ -207,8 +207,9 @@ set_dir(i) sleep(1) + //Technically this should be like, its own file or something or a subset of dog but whatever. Not a coder. -/mob/living/simple_animal/corgi/tamaskan +/mob/living/simple_mob/corgi/tamaskan name = "tamaskan" real_name = "tamaskan" desc = "It's a tamaskan." @@ -218,7 +219,7 @@ retaliate = 1 //Tamaskans are bigass dogs, okay? -/mob/living/simple_animal/corgi/tamaskan/spice +/mob/living/simple_mob/corgi/tamaskan/spice name = "Spice" real_name = "Spice" //Intended to hold the name without altering it. gender = FEMALE diff --git a/code/modules/mob/living/simple_animal/animals/corgi_vr.dm b/code/modules/mob/living/simple_animal/animals/corgi_vr.dm index 1cf3930452..3ef7f472f8 100644 --- a/code/modules/mob/living/simple_animal/animals/corgi_vr.dm +++ b/code/modules/mob/living/simple_animal/animals/corgi_vr.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/corgi/show_inv(mob/user as mob) +/mob/living/simple_mob/corgi/show_inv(mob/user as mob) user.set_machine(src) if(user.stat) return @@ -16,7 +16,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_mob/corgi/attackby(var/obj/item/O as obj, var/mob/user as mob) 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) ) @@ -33,7 +33,7 @@ return ..() -/mob/living/simple_animal/corgi/Topic(href, href_list) +/mob/living/simple_mob/corgi/Topic(href, href_list) if(usr.stat) return //Removing from inventory @@ -150,7 +150,7 @@ else ..() -/mob/living/simple_animal/corgi/proc/place_on_head(obj/item/item_to_add) +/mob/living/simple_mob/corgi/proc/place_on_head(obj/item/item_to_add) item_to_add.loc = src src.inventory_head = item_to_add regenerate_icons() diff --git a/code/modules/mob/living/simple_animal/animals/crab.dm b/code/modules/mob/living/simple_animal/animals/crab.dm index c369aa375a..0808b11dab 100644 --- a/code/modules/mob/living/simple_animal/animals/crab.dm +++ b/code/modules/mob/living/simple_animal/animals/crab.dm @@ -1,5 +1,5 @@ //Look Sir, free crabs! -/mob/living/simple_animal/crab +/mob/living/simple_mob/crab name = "crab" desc = "A hard-shelled crustacean. Seems quite content to lounge around all the time." tt_desc = "E Cancer bellianus" @@ -28,7 +28,7 @@ var/obj/item/inventory_head var/obj/item/inventory_mask -/mob/living/simple_animal/crab/Life() +/mob/living/simple_mob/crab/Life() ..() //CRAB movement, I'm not porting this up to SA because... "sideways-only movement" var nothanks if(!ckey && !stat) @@ -40,7 +40,7 @@ regenerate_icons() //COFFEE! SQUEEEEEEEEE! -/mob/living/simple_animal/crab/Coffee +/mob/living/simple_mob/crab/Coffee name = "Coffee" real_name = "Coffee" desc = "It's Coffee, the other pet!" @@ -49,7 +49,7 @@ response_harm = "stomps" //Sif Crabs -/mob/living/simple_animal/giant_crab +/mob/living/simple_mob/giant_crab name = "giant crab" desc = "A large, hard-shelled crustacean. This one is mostly grey." tt_desc = "S Cancer holligus" diff --git a/code/modules/mob/living/simple_animal/animals/farm_animals.dm b/code/modules/mob/living/simple_animal/animals/farm_animals.dm index 5f63128596..534bbf6000 100644 --- a/code/modules/mob/living/simple_animal/animals/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/animals/farm_animals.dm @@ -277,7 +277,7 @@ var/global/chicken_count = 0 E.pixel_x = rand(-6,6) E.pixel_y = rand(-6,6) if(chicken_count < MAX_CHICKENS && prob(10)) - processing_objects.Add(E) + START_PROCESSING(SSobj, E) /obj/item/weapon/reagent_containers/food/snacks/egg/var/amount_grown = 0 /obj/item/weapon/reagent_containers/food/snacks/egg/process() @@ -286,7 +286,7 @@ var/global/chicken_count = 0 if(amount_grown >= 100) visible_message("[src] hatches with a quiet cracking sound.") new /mob/living/simple_animal/chick(get_turf(src)) - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) qdel(src) else - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) diff --git a/code/modules/mob/living/simple_animal/animals/fish.dm b/code/modules/mob/living/simple_animal/animals/fish.dm index 547b095bfd..c4d01233ea 100644 --- a/code/modules/mob/living/simple_animal/animals/fish.dm +++ b/code/modules/mob/living/simple_animal/animals/fish.dm @@ -1,5 +1,5 @@ // Different types of fish! They are all subtypes of this tho -/mob/living/simple_animal/fish +/mob/living/simple_mob/fish name = "fish" desc = "Its a fishy. No touchy fishy." icon = 'icons/mob/fish.dmi' @@ -16,7 +16,7 @@ ) // Don't swim out of the water -/mob/living/simple_animal/fish/handle_wander_movement() +/mob/living/simple_mob/fish/handle_wander_movement() if(isturf(src.loc) && !resting && !buckled && canmove) //Physically capable of moving? lifes_since_move++ //Increment turns since move (turns are life() cycles) if(lifes_since_move >= turns_per_move) @@ -30,49 +30,49 @@ lifes_since_move = 0 // Take damage if we are not in water -/mob/living/simple_animal/fish/handle_breathing() +/mob/living/simple_mob/fish/handle_breathing() var/turf/T = get_turf(src) if(T && !is_type_in_list(T, suitable_turf_types)) if(prob(50)) say(pick("Blub", "Glub", "Burble")) adjustBruteLoss(unsuitable_atoms_damage) -/mob/living/simple_animal/fish/bass +/mob/living/simple_mob/fish/bass name = "bass" tt_desc = "E Micropterus notius" icon_state = "bass-swim" icon_living = "bass-swim" icon_dead = "bass-dead" -/mob/living/simple_animal/fish/trout +/mob/living/simple_mob/fish/trout name = "trout" tt_desc = "E Salmo trutta" icon_state = "trout-swim" icon_living = "trout-swim" icon_dead = "trout-dead" -/mob/living/simple_animal/fish/salmon +/mob/living/simple_mob/fish/salmon name = "salmon" tt_desc = "E Oncorhynchus nerka" icon_state = "salmon-swim" icon_living = "salmon-swim" icon_dead = "salmon-dead" -/mob/living/simple_animal/fish/perch +/mob/living/simple_mob/fish/perch name = "perch" tt_desc = "E Perca flavescens" icon_state = "perch-swim" icon_living = "perch-swim" icon_dead = "perch-dead" -/mob/living/simple_animal/fish/pike +/mob/living/simple_mob/fish/pike name = "pike" tt_desc = "E Esox aquitanicus" icon_state = "pike-swim" icon_living = "pike-swim" icon_dead = "pike-dead" -/mob/living/simple_animal/fish/koi +/mob/living/simple_mob/fish/koi name = "koi" tt_desc = "E Cyprinus rubrofuscus" icon_state = "koi-swim" diff --git a/code/modules/mob/living/simple_animal/animals/fish_vr.dm b/code/modules/mob/living/simple_animal/animals/fish_vr.dm index d1d74ec60e..39cd051d6a 100644 --- a/code/modules/mob/living/simple_animal/animals/fish_vr.dm +++ b/code/modules/mob/living/simple_animal/animals/fish_vr.dm @@ -1,21 +1,21 @@ -/mob/living/simple_animal/fish/koi/poisonous +/mob/living/simple_mob/fish/koi/poisonous desc = "A genetic marvel, combining the docility and aesthetics of the koi with some of the resiliency and cunning of the noble space carp." health = 50 maxHealth = 50 -/mob/living/simple_animal/fish/koi/poisonous/New() +/mob/living/simple_mob/fish/koi/poisonous/New() ..() create_reagents(60) reagents.add_reagent("toxin", 45) reagents.add_reagent("impedrezene", 15) -/mob/living/simple_animal/fish/koi/poisonous/Life() +/mob/living/simple_mob/fish/koi/poisonous/Life() ..() if(isbelly(loc) && prob(10)) var/obj/belly/B = loc sting(B.owner) -/mob/living/simple_animal/fish/koi/poisonous/react_to_attack(var/atom/A) +/mob/living/simple_mob/fish/koi/poisonous/react_to_attack(var/atom/A) if(isliving(A) && Adjacent(A)) var/mob/living/M = A visible_message("\The [src][is_dead()?"'s corpse":""] flails at [M]!") @@ -33,7 +33,7 @@ break sleep(3) -/mob/living/simple_animal/fish/koi/poisonous/proc/sting(var/mob/living/M) +/mob/living/simple_mob/fish/koi/poisonous/proc/sting(var/mob/living/M) if(!M.reagents) return 0 M.reagents.add_reagent("toxin", 2) diff --git a/code/modules/mob/living/simple_animal/animals/fluffy_vr.dm b/code/modules/mob/living/simple_animal/animals/fluffy_vr.dm index 38789b4ae8..9b9073fb49 100644 --- a/code/modules/mob/living/simple_animal/animals/fluffy_vr.dm +++ b/code/modules/mob/living/simple_animal/animals/fluffy_vr.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/fluffy +/mob/living/simple_mob/fluffy name = "Fluffy" desc = "It's a pink Diyaab! It seems to be very tame and quiet." icon = 'icons/mob/animal_vr.dmi' @@ -28,7 +28,7 @@ meat_amount = 1 meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat -/mob/living/simple_animal/fluffy/Life() +/mob/living/simple_mob/fluffy/Life() . = ..() if(!. || ai_inactive) return diff --git a/code/modules/mob/living/simple_animal/animals/fox_vr.dm b/code/modules/mob/living/simple_animal/animals/fox_vr.dm index 84a9a1ca26..72265c399f 100644 --- a/code/modules/mob/living/simple_animal/animals/fox_vr.dm +++ b/code/modules/mob/living/simple_animal/animals/fox_vr.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/fox +/mob/living/simple_mob/fox name = "fox" desc = "It's a fox. I wonder what it says?" tt_desc = "Vulpes vulpes" @@ -39,7 +39,7 @@ var/turns_since_scan = 0 var/mob/flee_target -/mob/living/simple_animal/fox/init_vore() +/mob/living/simple_mob/fox/init_vore() ..() var/obj/belly/B = vore_selected B.name = "Stomach" @@ -62,25 +62,25 @@ "With a loud glorp, the stomach spills more acids onto you.") // All them complicated fox procedures. -/mob/living/simple_animal/fox/Life() +/mob/living/simple_mob/fox/Life() . = ..() if(!.) return handle_flee_target() -/mob/living/simple_animal/fox/PunchTarget() - if(istype(target_mob,/mob/living/simple_animal/mouse)) - var/mob/living/simple_animal/mouse/mouse = target_mob +/mob/living/simple_mob/fox/PunchTarget() + if(istype(target_mob,/mob/living/simple_mob/mouse)) + var/mob/living/simple_mob/mouse/mouse = target_mob mouse.splat() visible_emote(pick("bites \the [mouse]!","pounces on \the [mouse]!","chomps on \the [mouse]!")) else ..() -/mob/living/simple_animal/fox/Found(var/atom/found_atom) - if(istype(found_atom,/mob/living/simple_animal/mouse)) +/mob/living/simple_mob/fox/Found(var/atom/found_atom) + if(istype(found_atom,/mob/living/simple_mob/mouse)) return found_atom -/mob/living/simple_animal/fox/proc/handle_flee_target() +/mob/living/simple_mob/fox/proc/handle_flee_target() //see if we should stop fleeing if (flee_target && !(flee_target in ListTargets(view_range))) flee_target = null @@ -93,16 +93,16 @@ stop_automated_movement = 1 walk_away(src, flee_target, 7, 2) -/mob/living/simple_animal/fox/react_to_attack(var/atom/A) +/mob/living/simple_mob/fox/react_to_attack(var/atom/A) if(A == src) return flee_target = A turns_since_scan = 5 -/mob/living/simple_animal/fox/ex_act() +/mob/living/simple_mob/fox/ex_act() . = ..() react_to_attack(src.loc) -/mob/living/simple_animal/fox/MouseDrop(atom/over_object) +/mob/living/simple_mob/fox/MouseDrop(atom/over_object) var/mob/living/carbon/H = over_object if(!istype(H) || !Adjacent(H)) return ..() @@ -112,17 +112,17 @@ else return ..() -/mob/living/simple_animal/fox/get_scooped(var/mob/living/carbon/grabber) +/mob/living/simple_mob/fox/get_scooped(var/mob/living/carbon/grabber) if (stat >= DEAD) return //since the holder icon looks like a living cat ..() //Basic friend AI -/mob/living/simple_animal/fox/fluff +/mob/living/simple_mob/fox/fluff var/mob/living/carbon/human/friend var/befriend_job = null -/mob/living/simple_animal/fox/fluff/Life() +/mob/living/simple_mob/fox/fluff/Life() . = ..() if(!. || ai_inactive || !friend) return @@ -149,7 +149,7 @@ var/verb = pick("yaps", "howls", "whines") audible_emote("[verb] anxiously.") -/mob/living/simple_animal/fox/fluff/verb/friend() +/mob/living/simple_mob/fox/fluff/verb/friend() set name = "Become Friends" set category = "IC" set src in view(1) @@ -173,13 +173,13 @@ desc = "The fox doesn't say a goddamn thing, now." //Captain fox -/mob/living/simple_animal/fox/fluff/Renault +/mob/living/simple_mob/fox/fluff/Renault name = "Renault" desc = "Renault, the Colony Director's trustworthy fox. I wonder what it says?" tt_desc = "Vulpes nobilis" befriend_job = "Colony Director" -/mob/living/simple_animal/fox/fluff/Renault/init_vore() +/mob/living/simple_mob/fox/fluff/Renault/init_vore() ..() var/obj/belly/B = vore_selected B.name = "Stomach" @@ -201,7 +201,7 @@ "A thick glob of acids drip down from above, adding to the pool of caustic fluids in Renault's belly.", "There's a loud gurgle as the stomach declares the intent to make you a part of Renault.") -/mob/living/simple_animal/fox/syndicate +/mob/living/simple_mob/fox/syndicate name = "syndi-fox" desc = "It's a DASTARDLY fox! The horror! Call the shuttle!" tt_desc = "Vulpes malus" diff --git a/code/modules/mob/living/simple_animal/animals/giant_spider.dm b/code/modules/mob/living/simple_animal/animals/giant_spider.dm index 7fe6744c64..c6acf2a769 100644 --- a/code/modules/mob/living/simple_animal/animals/giant_spider.dm +++ b/code/modules/mob/living/simple_animal/animals/giant_spider.dm @@ -5,7 +5,7 @@ #define SPINNING_COCOON 4 //basic spider mob, these generally guard nests -/mob/living/simple_animal/hostile/giant_spider +/mob/living/simple_mob/hostile/giant_spider name = "giant spider" desc = "Furry and brown, it makes you shudder to look at it. This one has deep red eyes." tt_desc = "X Brachypelma phorus" @@ -51,14 +51,14 @@ low_priority = TRUE //VOREStation Edit -/mob/living/simple_animal/hostile/giant_spider/proc/add_eyes() +/mob/living/simple_mob/hostile/giant_spider/proc/add_eyes() if(!eye_layer) eye_layer = image(icon, "[icon_state]-eyes") eye_layer.plane = PLANE_LIGHTING_ABOVE overlays += eye_layer -/mob/living/simple_animal/hostile/giant_spider/proc/remove_eyes() +/mob/living/simple_mob/hostile/giant_spider/proc/remove_eyes() overlays -= eye_layer /* @@ -66,7 +66,7 @@ Nurse Family */ //nursemaids - these create webs and eggs -/mob/living/simple_animal/hostile/giant_spider/nurse +/mob/living/simple_mob/hostile/giant_spider/nurse desc = "Furry and beige, it makes you shudder to look at it. This one has brilliant green eyes." tt_desc = "X Brachypelma phorus laetus" icon_state = "nurse" @@ -85,7 +85,7 @@ Nurse Family var/atom/cocoon_target var/egg_inject_chance = 5 -/mob/living/simple_animal/hostile/giant_spider/nurse/hat +/mob/living/simple_mob/hostile/giant_spider/nurse/hat desc = "Furry and beige, it makes you shudder to look at it. This one has brilliant green eyes and a tiny nurse hat." icon_state = "nursemed" icon_living = "nursemed" @@ -101,7 +101,7 @@ Nurse Family poison_chance = 15 // VOREStation Edit End -/mob/living/simple_animal/hostile/giant_spider/nurse/queen +/mob/living/simple_mob/hostile/giant_spider/nurse/queen desc = "Absolutely gigantic, this creature is horror itself." tt_desc = "X Brachypelma phorus tyrannus" icon = 'icons/mob/64x64.dmi' @@ -124,7 +124,7 @@ Nurse Family old_x = -16 old_y = -16 -/mob/living/simple_animal/hostile/giant_spider/webslinger +/mob/living/simple_mob/hostile/giant_spider/webslinger desc = "Furry and green, it makes you shudder to look at it. This one has brilliant green eyes, and a cloak of web." tt_desc = "X Brachypelma phorus balisticus" icon_state = "webslinger" @@ -150,7 +150,7 @@ Nurse Family spattack_min_range = 0 spattack_max_range = 5 -/mob/living/simple_animal/hostile/giant_spider/webslinger/AttackTarget() //One day. +/mob/living/simple_mob/hostile/giant_spider/webslinger/AttackTarget() //One day. var/mob/living/carbon/human/victim = null //Webslinger needs to know if its target is human later. if(ishuman(target_mob)) victim = target_mob @@ -165,7 +165,7 @@ Nurse Family shoot_range = 5 return ..() -/mob/living/simple_animal/hostile/giant_spider/carrier +/mob/living/simple_mob/hostile/giant_spider/carrier desc = "Furry, beige, and red, it makes you shudder to look at it. This one has luminous green eyes." tt_desc = "X Brachypelma phorus gerulus" icon_state = "carrier" @@ -183,23 +183,23 @@ Nurse Family var/spiderling_count = 0 var/spiderling_type = /obj/effect/spider/spiderling - var/swarmling_type = /mob/living/simple_animal/hostile/giant_spider/hunter + var/swarmling_type = /mob/living/simple_mob/hostile/giant_spider/hunter var/swarmling_faction = "spiders" -/mob/living/simple_animal/hostile/giant_spider/carrier/New() +/mob/living/simple_mob/hostile/giant_spider/carrier/New() spiderling_count = rand(5,10) adjust_scale(1.2) ..() -/mob/living/simple_animal/hostile/giant_spider/carrier/death() +/mob/living/simple_mob/hostile/giant_spider/carrier/death() visible_message("\The [src]'s abdomen splits as it rolls over, spiderlings crawling from the wound.") spawn(1) for(var/I = 1 to spiderling_count) if(prob(10) && src) var/mob/living/simple_animal/hostile/giant_spider/swarmling = new swarmling_type(src.loc) - var/swarm_health = Floor(swarmling.maxHealth * 0.4) - var/swarm_dam_lower = Floor(melee_damage_lower * 0.4) - var/swarm_dam_upper = Floor(melee_damage_upper * 0.4) + var/swarm_health = FLOOR(swarmling.maxHealth * 0.4, 1) + var/swarm_dam_lower = FLOOR(melee_damage_lower * 0.4, 1) + var/swarm_dam_upper = FLOOR(melee_damage_upper * 0.4, 1) swarmling.name = "spiderling" swarmling.maxHealth = swarm_health swarmling.health = swarm_health @@ -214,10 +214,10 @@ Nurse Family break return ..() -/mob/living/simple_animal/hostile/giant_spider/carrier/recursive +/mob/living/simple_mob/hostile/giant_spider/carrier/recursive desc = "Furry, beige, and red, it makes you shudder to look at it. This one has luminous green eyes. You have a distinctly bad feeling about this." - swarmling_type = /mob/living/simple_animal/hostile/giant_spider/carrier/recursive + swarmling_type = /mob/living/simple_mob/hostile/giant_spider/carrier/recursive /* Hunter Family @@ -225,7 +225,7 @@ Hunter Family //hunters have the most poison and move the fastest, so they can find prey -/mob/living/simple_animal/hostile/giant_spider/hunter +/mob/living/simple_mob/hostile/giant_spider/hunter desc = "Furry and black, it makes you shudder to look at it. This one has sparkling purple eyes." tt_desc = "X Brachypelma phorus venandi" icon_state = "hunter" @@ -238,7 +238,7 @@ Hunter Family poison_per_bite = 5 -/mob/living/simple_animal/hostile/giant_spider/lurker +/mob/living/simple_mob/hostile/giant_spider/lurker desc = "Translucent and white, it makes you shudder to look at it. This one has incandescent red eyes." tt_desc = "X Brachypelma phorus insidator" icon_state = "lurker" @@ -258,11 +258,11 @@ Hunter Family poison_type = "cryptobiolin" poison_per_bite = 2 -/mob/living/simple_animal/hostile/giant_spider/lurker/death() +/mob/living/simple_mob/hostile/giant_spider/lurker/death() alpha = 255 return ..() -/mob/living/simple_animal/hostile/giant_spider/tunneler +/mob/living/simple_mob/hostile/giant_spider/tunneler desc = "Sandy and brown, it makes you shudder to look at it. This one has glittering yellow eyes." tt_desc = "X Brachypelma phorus cannalis" icon_state = "tunneler" @@ -280,7 +280,7 @@ Hunter Family poison_per_bite = 3 poison_type = "serotrotium_v" -/mob/living/simple_animal/hostile/giant_spider/tunneler/death() +/mob/living/simple_mob/hostile/giant_spider/tunneler/death() spawn(1) for(var/I = 1 to rand(3,6)) if(src) @@ -293,7 +293,7 @@ Hunter Family Guard Family */ -/mob/living/simple_animal/hostile/giant_spider/pepper +/mob/living/simple_mob/hostile/giant_spider/pepper desc = "Red and brown, it makes you shudder to look at it. This one has glinting red eyes." tt_desc = "X Brachypelma phorus ignis" icon_state = "pepper" @@ -310,11 +310,11 @@ Guard Family poison_per_bite = 5 poison_type = "condensedcapsaicin_v" -/mob/living/simple_animal/hostile/giant_spider/pepper/New() +/mob/living/simple_mob/hostile/giant_spider/pepper/New() adjust_scale(1.1) ..() -/mob/living/simple_animal/hostile/giant_spider/thermic +/mob/living/simple_mob/hostile/giant_spider/thermic desc = "Mirage-cloaked and orange, it makes you shudder to look at it. This one has simmering orange eyes." tt_desc = "X Brachypelma phorus incaendium" icon_state = "pit" @@ -331,7 +331,7 @@ Guard Family poison_per_bite = 1 poison_type = "thermite_v" -/mob/living/simple_animal/hostile/giant_spider/electric +/mob/living/simple_mob/hostile/giant_spider/electric desc = "Spined and yellow, it makes you shudder to look at it. This one has flickering gold eyes." tt_desc = "X Brachypelma phorus aromatitis" icon_state = "spark" @@ -355,7 +355,7 @@ Guard Family poison_per_bite = 3 poison_type = "stimm" -/mob/living/simple_animal/hostile/giant_spider/phorogenic +/mob/living/simple_mob/hostile/giant_spider/phorogenic desc = "Crystalline and purple, it makes you shudder to look at it. This one has haunting purple eyes." tt_desc = "X Brachypelma phorus phorus" icon_state = "phoron" @@ -376,11 +376,11 @@ Guard Family var/exploded = 0 -/mob/living/simple_animal/hostile/giant_spider/phorogenic/New() +/mob/living/simple_mob/hostile/giant_spider/phorogenic/New() adjust_scale(1.25) return ..() -/mob/living/simple_animal/hostile/giant_spider/phorogenic/death() +/mob/living/simple_mob/hostile/giant_spider/phorogenic/death() visible_message("\The [src]'s body begins to rupture!") spawn(rand(1,5)) if(src && !exploded) @@ -389,7 +389,7 @@ Guard Family explosion(src.loc, 1, 2, 4, 6) return ..() -/mob/living/simple_animal/hostile/giant_spider/frost +/mob/living/simple_mob/hostile/giant_spider/frost desc = "Icy and blue, it makes you shudder to look at it. This one has brilliant blue eyes." tt_desc = "X Brachypelma phorus pruinae" icon_state = "frost" @@ -406,16 +406,16 @@ Guard Family Spider Procs */ -/mob/living/simple_animal/hostile/giant_spider/New(var/location, var/atom/parent) +/mob/living/simple_mob/hostile/giant_spider/New(var/location, var/atom/parent) get_light_and_color(parent) add_eyes() ..() -/mob/living/simple_animal/hostile/giant_spider/death() +/mob/living/simple_mob/hostile/giant_spider/death() remove_eyes() ..() -/mob/living/simple_animal/hostile/giant_spider/DoPunch(var/atom/A) +/mob/living/simple_mob/hostile/giant_spider/DoPunch(var/atom/A) . = ..() if(.) // If we succeeded in hitting. if(isliving(A)) @@ -428,7 +428,7 @@ Spider Procs to_chat(L, "You feel a tiny prick.") L.reagents.add_reagent(poison_type, poison_per_bite) -/mob/living/simple_animal/hostile/giant_spider/nurse/DoPunch(var/atom/A) +/mob/living/simple_mob/hostile/giant_spider/nurse/DoPunch(var/atom/A) . = ..() if(.) // If we succeeded in hitting. if(ishuman(A)) @@ -446,7 +446,7 @@ Spider Procs O.implants += eggs to_chat(H, "\The [src] injects something into your [O.name]!") -/mob/living/simple_animal/hostile/giant_spider/webslinger/DoPunch(var/atom/A) +/mob/living/simple_mob/hostile/giant_spider/webslinger/DoPunch(var/atom/A) . = ..() if(.) // If we succeeded in hitting. if(isliving(A)) @@ -456,7 +456,7 @@ Spider Procs visible_message("\The [src] throws a layer of web at \the [L]!") new /obj/effect/spider/stickyweb(L.loc) -/mob/living/simple_animal/hostile/giant_spider/handle_stance() +/mob/living/simple_mob/hostile/giant_spider/handle_stance() . = ..() if(ai_inactive) return @@ -473,7 +473,7 @@ Spider Procs stop_automated_movement = 0 walk(src,0) -/mob/living/simple_animal/hostile/giant_spider/nurse/proc/GiveUp(var/C) +/mob/living/simple_mob/hostile/giant_spider/nurse/proc/GiveUp(var/C) spawn(10 SECONDS) if(busy == MOVING_TO_TARGET) if(cocoon_target == C && get_dist(src,cocoon_target) > 1) @@ -481,7 +481,7 @@ Spider Procs busy = 0 stop_automated_movement = 0 -/mob/living/simple_animal/hostile/giant_spider/nurse/Life() +/mob/living/simple_mob/hostile/giant_spider/nurse/Life() . = ..() if(!. || ai_inactive) return @@ -554,7 +554,7 @@ Spider Procs C.pixel_x = cocoon_target.pixel_x C.pixel_y = cocoon_target.pixel_y for(var/mob/living/M in C.loc) - if(istype(M, /mob/living/simple_animal/hostile/giant_spider)) + if(istype(M, /mob/living/simple_mob/hostile/giant_spider)) continue large_cocoon = 1 fed++ diff --git a/code/modules/mob/living/simple_animal/animals/giant_spider_vr.dm b/code/modules/mob/living/simple_animal/animals/giant_spider_vr.dm index 50d653f63e..7497ae9e9c 100644 --- a/code/modules/mob/living/simple_animal/animals/giant_spider_vr.dm +++ b/code/modules/mob/living/simple_animal/animals/giant_spider_vr.dm @@ -1,5 +1,5 @@ // Slightly placeholder, mostly to replace ion hivebots on V4 -/mob/living/simple_animal/hostile/giant_spider/ion +/mob/living/simple_mob/hostile/giant_spider/ion desc = "Furry and green, it makes you shudder to look at it. This one has brilliant green eyes and a hint of static discharge." tt_desc = "X Brachypelma phorus ionus" icon_state = "webslinger" diff --git a/code/modules/mob/living/simple_animal/animals/goose.dm b/code/modules/mob/living/simple_animal/animals/goose.dm index f05baf7acf..72744ad882 100644 --- a/code/modules/mob/living/simple_animal/animals/goose.dm +++ b/code/modules/mob/living/simple_animal/animals/goose.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/hostile/goose //hey are these even in the game +/mob/living/simple_mob/hostile/goose //hey are these even in the game name = "goose" desc = "It looks pretty angry!" tt_desc = "E Branta canadensis" //that iconstate is just a regular goose @@ -51,10 +51,10 @@ meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat -/mob/living/simple_animal/hostile/goose/set_target() +/mob/living/simple_mob/hostile/goose/set_target() . = ..() if(.) custom_emote(1,"flaps and honks at [.]!") -/mob/living/simple_animal/hostile/goose/Process_Spacemove(var/check_drift = 0) +/mob/living/simple_mob/hostile/goose/Process_Spacemove(var/check_drift = 0) return 1 // VOREStation Edit No drifting in space! diff --git a/code/modules/mob/living/simple_animal/animals/lizard.dm b/code/modules/mob/living/simple_animal/animals/lizard.dm index 3cceeb4da4..d9a1b1b8d0 100644 --- a/code/modules/mob/living/simple_animal/animals/lizard.dm +++ b/code/modules/mob/living/simple_animal/animals/lizard.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/lizard +/mob/living/simple_mob/lizard name = "Lizard" desc = "A cute tiny lizard." tt_desc = "E Anolis cuvieri" diff --git a/code/modules/mob/living/simple_animal/animals/miscellaneous.dm b/code/modules/mob/living/simple_animal/animals/miscellaneous.dm index 29bb7a3da3..306f6a3aad 100644 --- a/code/modules/mob/living/simple_animal/animals/miscellaneous.dm +++ b/code/modules/mob/living/simple_animal/animals/miscellaneous.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/yithian +/mob/living/simple_mob/yithian name = "yithian" desc = "A friendly creature vaguely resembling an oversized snail without a shell." tt_desc = "J Escargot escargot" // a product of Jade, which is a planet that totally exists @@ -9,7 +9,7 @@ faction = "yithian" -/mob/living/simple_animal/tindalos +/mob/living/simple_mob/tindalos name = "tindalos" desc = "It looks like a large, flightless grasshopper." tt_desc = "J Locusta bruchus" diff --git a/code/modules/mob/living/simple_animal/animals/mouse.dm b/code/modules/mob/living/simple_animal/animals/mouse.dm index bf5d03c52c..d68d66b498 100644 --- a/code/modules/mob/living/simple_animal/animals/mouse.dm +++ b/code/modules/mob/living/simple_animal/animals/mouse.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/mouse +/mob/living/simple_mob/mouse name = "mouse" real_name = "mouse" desc = "It's a small rodent." @@ -16,10 +16,10 @@ see_in_dark = 6 universal_understand = 1 - mob_size = MOB_MINISCULE + mob_size = MOB_SMALL pass_flags = PASSTABLE - can_pull_size = ITEMSIZE_TINY - can_pull_mobs = MOB_PULL_NONE +// can_pull_size = ITEMSIZE_TINY +// can_pull_mobs = MOB_PULL_NONE layer = MOB_LAYER density = 0 @@ -43,7 +43,7 @@ var/body_color //brown, gray and white, leave blank for random -/mob/living/simple_animal/mouse/Life() +/mob/living/simple_mob/mouse/Life() . = ..() if(!. || ai_inactive) return @@ -63,7 +63,7 @@ else if(prob(1)) audible_emote("snuffles.") -/mob/living/simple_animal/mouse/New() +/mob/living/simple_mob/mouse/New() ..() verbs += /mob/living/proc/ventcrawl @@ -82,7 +82,7 @@ icon_rest = "mouse_[body_color]_sleep" desc = "A small [body_color] rodent, often seen hiding in maintenance areas and making a nuisance of itself." -/mob/living/simple_animal/mouse/proc/splat() +/mob/living/simple_mob/mouse/proc/splat() src.health = 0 src.stat = DEAD src.icon_dead = "mouse_[body_color]_splat" @@ -92,7 +92,7 @@ client.time_died_as_mouse = world.time -/mob/living/simple_animal/mouse/Crossed(AM as mob|obj) +/mob/living/simple_mob/mouse/Crossed(AM as mob|obj) if( ishuman(AM) ) if(!stat) var/mob/M = AM @@ -100,7 +100,7 @@ M << 'sound/effects/mouse_squeak.ogg' ..() -/mob/living/simple_animal/mouse/death() +/mob/living/simple_mob/mouse/death() layer = MOB_LAYER playsound(src, 'sound/effects/mouse_squeak_loud.ogg', 35, 1) if(client) @@ -111,27 +111,27 @@ * Mouse types */ -/mob/living/simple_animal/mouse/white +/mob/living/simple_mob/mouse/white body_color = "white" icon_state = "mouse_white" -/mob/living/simple_animal/mouse/gray +/mob/living/simple_mob/mouse/gray body_color = "gray" icon_state = "mouse_gray" -/mob/living/simple_animal/mouse/brown +/mob/living/simple_mob/mouse/brown body_color = "brown" icon_state = "mouse_brown" //TOM IS ALIVE! SQUEEEEEEEE~K :) -/mob/living/simple_animal/mouse/brown/Tom +/mob/living/simple_mob/mouse/brown/Tom name = "Tom" desc = "Jerry the cat is not amused." -/mob/living/simple_animal/mouse/brown/Tom/New() +/mob/living/simple_mob/mouse/brown/Tom/New() ..() // Change my name back, don't want to be named Tom (666) name = initial(name) -/mob/living/simple_animal/mouse/cannot_use_vents() +/mob/living/simple_mob/mouse/cannot_use_vents() return diff --git a/code/modules/mob/living/simple_animal/animals/mouse_vr.dm b/code/modules/mob/living/simple_animal/animals/mouse_vr.dm index 396d43a68b..d3bdfbd1c6 100644 --- a/code/modules/mob/living/simple_animal/animals/mouse_vr.dm +++ b/code/modules/mob/living/simple_animal/animals/mouse_vr.dm @@ -1,8 +1,8 @@ -/mob/living/simple_animal/mouse +/mob/living/simple_mob/mouse no_vore = 1 //Mice can't eat others due to the amount of bugs caused by it. -/mob/living/simple_animal/mouse/attack_hand(mob/living/hander) +/mob/living/simple_mob/mouse/attack_hand(mob/living/hander) src.get_scooped(hander) //For one-click mouse scooping under any conditions. They knew what they were getting into! diff --git a/code/modules/mob/living/simple_animal/animals/parrot.dm b/code/modules/mob/living/simple_animal/animals/parrot.dm index 26b584196c..1c28622898 100644 --- a/code/modules/mob/living/simple_animal/animals/parrot.dm +++ b/code/modules/mob/living/simple_animal/animals/parrot.dm @@ -13,7 +13,7 @@ */ //Parrot is too snowflake for me to rewrite right now, someone should make it use the new -//simple_animal movement stuff. -Aro +//simple_mob movement stuff. -Aro //Only a maximum of one action and one intent should be active at any given time. //Actions @@ -28,7 +28,7 @@ #define PARROT_FLEE 64 //Flying away from its attacker -/mob/living/simple_animal/parrot +/mob/living/simple_mob/parrot name = "parrot" desc = "The parrot squawks, \"It's a parrot! BAWWK!\"" tt_desc = "E Ara macao" @@ -94,7 +94,7 @@ var/obj/item/held_item = null -/mob/living/simple_animal/parrot/New() +/mob/living/simple_mob/parrot/New() ..() if(!ears) var/headset = pick(/obj/item/device/radio/headset/headset_sec, \ @@ -106,27 +106,27 @@ parrot_sleep_dur = parrot_sleep_max //In case someone decides to change the max without changing the duration var - verbs.Add(/mob/living/simple_animal/parrot/proc/steal_from_ground, \ - /mob/living/simple_animal/parrot/proc/steal_from_mob, \ - /mob/living/simple_animal/parrot/verb/drop_held_item_player, \ - /mob/living/simple_animal/parrot/proc/perch_player) + verbs.Add(/mob/living/simple_mob/parrot/proc/steal_from_ground, \ + /mob/living/simple_mob/parrot/proc/steal_from_mob, \ + /mob/living/simple_mob/parrot/verb/drop_held_item_player, \ + /mob/living/simple_mob/parrot/proc/perch_player) -/mob/living/simple_animal/parrot/death() +/mob/living/simple_mob/parrot/death() if(held_item) held_item.forceMove(src.loc) held_item = null walk(src,0) ..() -/mob/living/simple_animal/parrot/Stat() +/mob/living/simple_mob/parrot/Stat() ..() stat("Held Item", held_item) /* * Inventory */ -/mob/living/simple_animal/parrot/show_inv(mob/user as mob) +/mob/living/simple_mob/parrot/show_inv(mob/user as mob) user.set_machine(src) if(user.stat) return @@ -140,7 +140,7 @@ onclose(user, "mob[real_name]") return -/mob/living/simple_animal/parrot/Topic(href, href_list) +/mob/living/simple_mob/parrot/Topic(href, href_list) //Can the usr physically do this? if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr)) @@ -223,7 +223,7 @@ * Attack responces */ //Humans, monkeys, aliens -/mob/living/simple_animal/parrot/attack_hand(mob/living/carbon/M as mob) +/mob/living/simple_mob/parrot/attack_hand(mob/living/carbon/M as mob) ..() if(client) return if(!stat && M.a_intent == I_HURT) @@ -244,7 +244,7 @@ return //Mobs with objects -/mob/living/simple_animal/parrot/attackby(var/obj/item/O as obj, var/mob/user as mob) +/mob/living/simple_mob/parrot/attackby(var/obj/item/O as obj, var/mob/user as mob) ..() if(!stat && !client && !istype(O, /obj/item/stack/medical)) if(O.force) @@ -258,7 +258,7 @@ return //Bullets -/mob/living/simple_animal/parrot/bullet_act(var/obj/item/projectile/Proj) +/mob/living/simple_mob/parrot/bullet_act(var/obj/item/projectile/Proj) ..() if(!stat && !client) if(parrot_state == PARROT_PERCH) @@ -275,7 +275,7 @@ /* * AI - Not really intelligent, but I'm calling it AI anyway. */ -/mob/living/simple_animal/parrot/Life() +/mob/living/simple_mob/parrot/Life() ..() //Sprite and AI update for when a parrot gets pulled @@ -513,12 +513,12 @@ * Procs */ -/mob/living/simple_animal/parrot/movement_delay() +/mob/living/simple_mob/parrot/movement_delay() if(client && stat == CONSCIOUS && parrot_state != "parrot_fly") icon_state = "parrot_fly" ..() -/mob/living/simple_animal/parrot/proc/search_for_item() +/mob/living/simple_mob/parrot/proc/search_for_item() for(var/atom/movable/AM in view(src)) //Skip items we already stole or are wearing or are too big if(parrot_perch && AM.loc == parrot_perch.loc || AM.loc == src) @@ -535,7 +535,7 @@ return C return null -/mob/living/simple_animal/parrot/proc/search_for_perch() +/mob/living/simple_mob/parrot/proc/search_for_perch() for(var/obj/O in view(src)) for(var/path in desired_perches) if(istype(O, path)) @@ -543,7 +543,7 @@ return null //This proc was made to save on doing two 'in view' loops seperatly -/mob/living/simple_animal/parrot/proc/search_for_perch_and_item() +/mob/living/simple_mob/parrot/proc/search_for_perch_and_item() for(var/atom/movable/AM in view(src)) for(var/perch_path in desired_perches) if(istype(AM, perch_path)) @@ -568,7 +568,7 @@ /* * Verbs - These are actually procs, but can be used as verbs by player-controlled parrots. */ -/mob/living/simple_animal/parrot/proc/steal_from_ground() +/mob/living/simple_mob/parrot/proc/steal_from_ground() set name = "Steal from ground" set category = "Parrot" set desc = "Grabs a nearby item." @@ -596,7 +596,7 @@ to_chat(src, "There is nothing of interest to take.") return 0 -/mob/living/simple_animal/parrot/proc/steal_from_mob() +/mob/living/simple_mob/parrot/proc/steal_from_mob() set name = "Steal from mob" set category = "Parrot" set desc = "Steals an item right out of a person's hand!" @@ -627,7 +627,7 @@ to_chat(src, "There is nothing of interest to take.") return 0 -/mob/living/simple_animal/parrot/verb/drop_held_item_player() +/mob/living/simple_mob/parrot/verb/drop_held_item_player() set name = "Drop held item" set category = "Parrot" set desc = "Drop the item you're holding." @@ -639,7 +639,7 @@ return -/mob/living/simple_animal/parrot/proc/drop_held_item(var/drop_gently = 1) +/mob/living/simple_mob/parrot/proc/drop_held_item(var/drop_gently = 1) set name = "Drop held item" set category = "Parrot" set desc = "Drop the item you're holding." @@ -666,7 +666,7 @@ held_item = null return 1 -/mob/living/simple_animal/parrot/proc/perch_player() +/mob/living/simple_mob/parrot/proc/perch_player() set name = "Sit" set category = "Parrot" set desc = "Sit on a nice comfy perch." @@ -687,17 +687,17 @@ /* * Sub-types */ -/mob/living/simple_animal/parrot/Poly +/mob/living/simple_mob/parrot/Poly name = "Poly" desc = "Poly the Parrot. An expert on quantum cracker theory." 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() +/mob/living/simple_mob/parrot/Poly/New() ears = new /obj/item/device/radio/headset/headset_eng(src) available_channels = list(":e") ..() -/mob/living/simple_animal/parrot/say(var/message) +/mob/living/simple_mob/parrot/say(var/message) if(stat) return @@ -731,25 +731,25 @@ ..(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) +/mob/living/simple_mob/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/part_c, var/mob/speaker = null, var/hard_to_hear = 0) +/mob/living/simple_mob/parrot/hear_radio(var/message, var/verb="says", var/datum/language/language=null, var/part_a, var/part_b, var/part_c, 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="") +/mob/living/simple_mob/parrot/proc/parrot_hear(var/message="") if(!message || stat) return speech_buffer.Add(message) -/mob/living/simple_animal/parrot/attack_generic(var/mob/user, var/damage, var/attack_message) +/mob/living/simple_mob/parrot/attack_generic(var/mob/user, var/damage, var/attack_message) var/success = ..() diff --git a/code/modules/mob/living/simple_animal/animals/penguin.dm b/code/modules/mob/living/simple_animal/animals/penguin.dm index da7c9c4328..105d6e7c21 100644 --- a/code/modules/mob/living/simple_animal/animals/penguin.dm +++ b/code/modules/mob/living/simple_animal/animals/penguin.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/penguin +/mob/living/simple_mob/penguin name = "space penguin" desc = "An ungainly, waddling, cute, and VERY well-dressed bird." tt_desc = "E Aptenodytes forsteri" diff --git a/code/modules/mob/living/simple_animal/animals/pike_vr.dm b/code/modules/mob/living/simple_animal/animals/pike_vr.dm index e820d672b8..b04b83c14f 100644 --- a/code/modules/mob/living/simple_animal/animals/pike_vr.dm +++ b/code/modules/mob/living/simple_animal/animals/pike_vr.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/hostile/carp/pike +/mob/living/simple_mob/hostile/carp/pike name = "space pike" desc = "A bigger, angrier cousin of the space carp." icon = 'icons/mob/spaceshark.dmi' @@ -25,10 +25,10 @@ vore_icons = 0 //No custom icons yet -/mob/living/simple_animal/hostile/carp/pike/weak +/mob/living/simple_mob/hostile/carp/pike/weak maxHealth = 75 health = 75 -/mob/living/simple_animal/hostile/carp/strong +/mob/living/simple_mob/hostile/carp/strong maxHealth = 50 health = 50 diff --git a/code/modules/mob/living/simple_animal/animals/sif_wildlife/diyaab.dm b/code/modules/mob/living/simple_animal/animals/sif_wildlife/diyaab.dm deleted file mode 100644 index 86b2a261e7..0000000000 --- a/code/modules/mob/living/simple_animal/animals/sif_wildlife/diyaab.dm +++ /dev/null @@ -1,29 +0,0 @@ -/mob/living/simple_animal/retaliate/diyaab - name = "diyaab" - desc = "A small pack animal. Although omnivorous, it will hunt meat on occasion." - tt_desc = "S Choeros hirtus" //diyaab and shantak are technically reletives! - faction = "diyaab" - icon_state = "diyaab" - icon_living = "diyaab" - icon_dead = "diyaab_dead" - icon = 'icons/jungle.dmi' - - faction = "diyaab" - cooperative = 1 - - maxHealth = 25 - health = 25 - speed = 1 - move_to_delay = 1 - - melee_damage_lower = 4 - melee_damage_upper = 12 - attack_sharp = 1 //Bleeds, but it shouldn't rip off a limb? - - attacktext = list("gouged") - cold_damage_per_tick = 0 - - speak_chance = 5 - speak = list("Awrr?","Aowrl!","Worrl") - emote_see = list("sniffs the air cautiously","looks around") - emote_hear = list("snuffles") \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/animals/sif_wildlife/savik.dm b/code/modules/mob/living/simple_animal/animals/sif_wildlife/savik.dm deleted file mode 100644 index b451901b60..0000000000 --- a/code/modules/mob/living/simple_animal/animals/sif_wildlife/savik.dm +++ /dev/null @@ -1,36 +0,0 @@ -/mob/living/simple_animal/hostile/savik - name = "savik" - desc = "A fast, armoured predator accustomed to hiding and ambushing in cold terrain." - tt_desc = "S Pistris tellus" //landshark - faction = "savik" - icon_state = "savik" - icon_living = "savik" - icon_dead = "savik_dead" - icon = 'icons/jungle.dmi' - - faction = "savik" - - maxHealth = 125 - health = 125 - speed = 2 - move_to_delay = 2 - - melee_damage_lower = 15 - melee_damage_upper = 35 - attack_armor_pen = 15 - attack_sharp = 1 - attack_edge = 1 - - attacktext = list("mauled") - cold_damage_per_tick = 0 - - speak_chance = 5 - speak = list("Hruuugh!","Hrunnph") - emote_see = list("paws the ground","shakes its mane","stomps") - emote_hear = list("snuffles") - -/mob/living/simple_animal/hostile/savik/handle_stance(var/new_stance) - ..(new_stance) - if(stance == STANCE_ATTACK || stance == STANCE_ATTACKING) - if((health / maxHealth) <= 0.5) // At half health, and fighting someone currently. - add_modifier(/datum/modifier/berserk, 30 SECONDS) \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/animals/sif_wildlife/shantak.dm b/code/modules/mob/living/simple_animal/animals/sif_wildlife/shantak.dm deleted file mode 100644 index 999916bbe6..0000000000 --- a/code/modules/mob/living/simple_animal/animals/sif_wildlife/shantak.dm +++ /dev/null @@ -1,29 +0,0 @@ -/mob/living/simple_animal/hostile/shantak - name = "shantak" - desc = "A piglike creature with a bright iridiscent mane that sparkles as though lit by an inner light. Don't be fooled by its beauty though." - tt_desc = "S Choeros shantak" - faction = "shantak" - icon_state = "shantak" - icon_living = "shantak" - icon_dead = "shantak_dead" - icon = 'icons/jungle.dmi' - - faction = "shantak" - - maxHealth = 75 - health = 75 - speed = 1 - move_to_delay = 1 - - melee_damage_lower = 12 - melee_damage_upper = 28 - attack_armor_pen = 5 - attack_sharp = 1 - attack_edge = 1 - - attacktext = list("gouged") - cold_damage_per_tick = 0 - - speak_chance = 5 - speak = list("Shuhn","Shrunnph?","Shunpf") - emote_see = list("scratches the ground","shakes out its mane","clinks gently as it moves") \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/animals/slime.dm b/code/modules/mob/living/simple_animal/animals/slime.dm index 8c6ef9cf82..7db2392808 100644 --- a/code/modules/mob/living/simple_animal/animals/slime.dm +++ b/code/modules/mob/living/simple_animal/animals/slime.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/old_slime +/mob/living/simple_mob/old_slime name = "pet slime" desc = "A lovable, domesticated slime." tt_desc = "Amorphidae proteus" @@ -20,19 +20,19 @@ var/colour = "grey" -/mob/living/simple_animal/old_slime/science +/mob/living/simple_mob/old_slime/science name = "Kendrick" colour = "rainbow" icon_state = "rainbow baby slime" icon_living = "rainbow baby slime" icon_dead = "rainbow baby slime dead" -/mob/living/simple_animal/old_slime/science/initialize() +/mob/living/simple_animal/slime/science/Initialize() . = ..() overlays.Cut() overlays += "aslime-:33" -/mob/living/simple_animal/adultslime +/mob/living/simple_mob/adultslime name = "pet slime" desc = "A lovable, domesticated slime." icon = 'icons/mob/slimes.dmi' @@ -52,17 +52,17 @@ var/colour = "grey" -/mob/living/simple_animal/adultslime/New() +/mob/living/simple_mob/adultslime/New() ..() overlays += "aslime-:33" -/mob/living/simple_animal/adultslime/death() - var/mob/living/simple_animal/old_slime/S1 = new /mob/living/simple_animal/old_slime (src.loc) +/mob/living/simple_mob/adultslime/death() + var/mob/living/simple_mob/old_slime/S1 = new /mob/living/simple_mob/old_slime (src.loc) S1.icon_state = "[src.colour] baby slime" S1.icon_living = "[src.colour] baby slime" S1.icon_dead = "[src.colour] baby slime dead" S1.colour = "[src.colour]" - var/mob/living/simple_animal/old_slime/S2 = new /mob/living/simple_animal/old_slime (src.loc) + var/mob/living/simple_mob/old_slime/S2 = new /mob/living/simple_mob/old_slime (src.loc) S2.icon_state = "[src.colour] baby slime" S2.icon_living = "[src.colour] baby slime" S2.icon_dead = "[src.colour] baby slime dead" diff --git a/code/modules/mob/living/simple_animal/animals/snake_vr.dm b/code/modules/mob/living/simple_animal/animals/snake_vr.dm index 041cd38d15..b6f6618184 100644 --- a/code/modules/mob/living/simple_animal/animals/snake_vr.dm +++ b/code/modules/mob/living/simple_animal/animals/snake_vr.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/snake +/mob/living/simple_mob/snake name = "snake" desc = "A big thick snake." icon = 'icons/mob/snake_vr.dmi' @@ -23,13 +23,13 @@ speak_emote = list("hisses") //NOODLE IS HERE! SQUEEEEEEEE~ -/mob/living/simple_animal/snake/Noodle +/mob/living/simple_mob/snake/Noodle name = "Noodle" desc = "This snake is particularly chubby and demands nothing but the finest of treats." var/turns_since_scan = 0 var/obj/movement_target -/mob/living/simple_animal/snake/Noodle/Life() //stolen from Ian in corgi.dm +/mob/living/simple_mob/snake/Noodle/Life() //stolen from Ian in corgi.dm if(!..()) return 0 @@ -61,7 +61,7 @@ else if(ishuman(movement_target.loc) && prob(20)) visible_emote("stares at the [movement_target] that [movement_target.loc] has with an unknowable reptilian gaze.") -/mob/living/simple_animal/snake/Noodle/attackby(var/obj/item/O, var/mob/user) +/mob/living/simple_mob/snake/Noodle/attackby(var/obj/item/O, var/mob/user) if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/snakesnack)) visible_message("[user] feeds \the [O] to [src].") qdel(O) diff --git a/code/modules/mob/living/simple_animal/animals/spiderbot.dm b/code/modules/mob/living/simple_animal/animals/spiderbot.dm index b76351b976..7e1cac8c80 100644 --- a/code/modules/mob/living/simple_animal/animals/spiderbot.dm +++ b/code/modules/mob/living/simple_animal/animals/spiderbot.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/spiderbot +/mob/living/simple_mob/spiderbot name = "spider-bot" desc = "A skittering robotic friend!" tt_desc = "Maintenance Robot" @@ -46,21 +46,21 @@ /obj/item/device/radio/borg, /obj/item/weapon/holder, /obj/machinery/camera, - /mob/living/simple_animal/borer, + /mob/living/simple_mob/animal/borer, /obj/item/device/mmi, ) var/emagged = 0 var/obj/item/held_item = null //Storage for single item they can hold. -/mob/living/simple_animal/spiderbot/New() +/mob/living/simple_mob/spiderbot/New() ..() add_language(LANGUAGE_GALCOM) default_language = all_languages[LANGUAGE_GALCOM] verbs |= /mob/living/proc/ventcrawl verbs |= /mob/living/proc/hide -/mob/living/simple_animal/spiderbot/attackby(var/obj/item/O as obj, var/mob/user as mob) +/mob/living/simple_mob/spiderbot/attackby(var/obj/item/O as obj, var/mob/user as mob) if(istype(O, /obj/item/device/mmi)) var/obj/item/device/mmi/B = O @@ -144,7 +144,7 @@ else O.attack(src, user, user.zone_sel.selecting) -/mob/living/simple_animal/spiderbot/emag_act(var/remaining_charges, var/mob/user) +/mob/living/simple_mob/spiderbot/emag_act(var/remaining_charges, var/mob/user) if (emagged) user << "[src] is already overloaded - better run." return 0 @@ -154,7 +154,7 @@ spawn(200) src << "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) +/mob/living/simple_mob/spiderbot/proc/transfer_personality(var/obj/item/device/mmi/M as obj) src.mind = M.brainmob.mind src.mind.key = M.brainmob.key @@ -162,13 +162,13 @@ src.name = "spider-bot ([M.brainmob.name])" src.languages = M.brainmob.languages -/mob/living/simple_animal/spiderbot/proc/explode() //When emagged. +/mob/living/simple_mob/spiderbot/proc/explode() //When emagged. src.visible_message("\The [src] makes an odd warbling noise, fizzles, and explodes!") explosion(get_turf(loc), -1, -1, 3, 5) eject_brain() death() -/mob/living/simple_animal/spiderbot/update_icon() +/mob/living/simple_mob/spiderbot/update_icon() if(mmi) if(positronic) icon_state = "spiderbot-chassis-posi" @@ -180,7 +180,7 @@ icon_state = "spiderbot-chassis" icon_living = "spiderbot-chassis" -/mob/living/simple_animal/spiderbot/proc/eject_brain() +/mob/living/simple_mob/spiderbot/proc/eject_brain() if(mmi) var/turf/T = get_turf(loc) if(T) @@ -193,11 +193,11 @@ remove_language("Robot Talk") positronic = null -/mob/living/simple_animal/spiderbot/Destroy() +/mob/living/simple_mob/spiderbot/Destroy() eject_brain() ..() -/mob/living/simple_animal/spiderbot/New() +/mob/living/simple_mob/spiderbot/New() radio = new /obj/item/device/radio/borg(src) camera = new /obj/machinery/camera(src) @@ -206,7 +206,7 @@ ..() -/mob/living/simple_animal/spiderbot/death() +/mob/living/simple_mob/spiderbot/death() living_mob_list -= src dead_mob_list += src @@ -222,7 +222,7 @@ return //Cannibalized from the parrot mob. ~Zuhayr -/mob/living/simple_animal/spiderbot/verb/drop_held_item() +/mob/living/simple_mob/spiderbot/verb/drop_held_item() set name = "Drop held item" set category = "Spiderbot" set desc = "Drop the item you're holding." @@ -254,7 +254,7 @@ return -/mob/living/simple_animal/spiderbot/verb/get_item() +/mob/living/simple_mob/spiderbot/verb/get_item() set name = "Pick up item" set category = "Spiderbot" set desc = "Allows you to take a nearby small item." @@ -288,13 +288,13 @@ src << "There is nothing of interest to take." return 0 -/mob/living/simple_animal/spiderbot/examine(mob/user) +/mob/living/simple_mob/spiderbot/examine(mob/user) ..(user) if(src.held_item) user << "It is carrying \icon[src.held_item] \a [src.held_item]." -/mob/living/simple_animal/spiderbot/cannot_use_vents() +/mob/living/simple_mob/spiderbot/cannot_use_vents() return -/mob/living/simple_animal/spiderbot/binarycheck() +/mob/living/simple_mob/spiderbot/binarycheck() return positronic diff --git a/code/modules/mob/living/simple_animal/animals/tomato.dm b/code/modules/mob/living/simple_animal/animals/tomato.dm index 711922eeb0..175875c4d2 100644 --- a/code/modules/mob/living/simple_animal/animals/tomato.dm +++ b/code/modules/mob/living/simple_animal/animals/tomato.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/hostile/tomato +/mob/living/simple_mob/hostile/tomato name = "tomato" desc = "It's a horrifyingly enormous beef tomato, and it's packing extra beef!" tt_desc = "X Solanum abominable" diff --git a/code/modules/mob/living/simple_animal/animals/tree.dm b/code/modules/mob/living/simple_animal/animals/tree.dm index 09c8451811..79e24c09f3 100644 --- a/code/modules/mob/living/simple_animal/animals/tree.dm +++ b/code/modules/mob/living/simple_animal/animals/tree.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/hostile/tree +/mob/living/simple_mob/hostile/tree name = "pine tree" desc = "A pissed off tree-like alien. It seems annoyed with the festivities..." tt_desc = "X Festivus tyrannus" @@ -40,12 +40,12 @@ pixel_x = -16 -/mob/living/simple_animal/hostile/tree/FindTarget() +/mob/living/simple_mob/hostile/tree/FindTarget() . = ..() if(.) audible_emote("growls at [.]") -/mob/living/simple_animal/hostile/tree/PunchTarget() +/mob/living/simple_mob/hostile/tree/PunchTarget() . =..() var/mob/living/L = . if(istype(L)) @@ -53,7 +53,7 @@ L.Weaken(3) L.visible_message("\the [src] knocks down \the [L]!") -/mob/living/simple_animal/hostile/tree/death() +/mob/living/simple_mob/hostile/tree/death() ..(null,"is hacked into pieces!") playsound(loc, 'sound/effects/woodcutting.ogg', 100, 1) new /obj/item/stack/material/wood(loc) diff --git a/code/modules/mob/living/simple_animal/animals/worm.dm b/code/modules/mob/living/simple_animal/animals/worm.dm index da30dbf8fd..4b82fdee74 100644 --- a/code/modules/mob/living/simple_animal/animals/worm.dm +++ b/code/modules/mob/living/simple_animal/animals/worm.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/space_worm +/mob/living/simple_mob/space_worm name = "space worm segment" desc = "A part of a space worm." icon = 'icons/mob/animal.dmi' @@ -35,8 +35,8 @@ speak_emote = list("transmits") //not supposed to be used under AI control emote_hear = list("transmits") //I'm just adding it so it doesn't runtime if controlled by player who speaks - var/mob/living/simple_animal/space_worm/previous //next/previous segments, correspondingly - var/mob/living/simple_animal/space_worm/next //head is the nextest segment + var/mob/living/simple_mob/space_worm/previous //next/previous segments, correspondingly + var/mob/living/simple_mob/space_worm/next //head is the nextest segment var/stomachProcessProbability = 50 var/digestionProbability = 20 @@ -63,10 +63,10 @@ New(var/location, var/segments = 6) ..() - var/mob/living/simple_animal/space_worm/current = src + var/mob/living/simple_mob/space_worm/current = src for(var/i = 1 to segments) - var/mob/living/simple_animal/space_worm/newSegment = new /mob/living/simple_animal/space_worm(loc) + var/mob/living/simple_mob/space_worm/newSegment = new /mob/living/simple_mob/space_worm(loc) current.Attach(newSegment) current = newSegment @@ -148,7 +148,7 @@ return 0 - proc/Attach(var/mob/living/simple_animal/space_worm/attachement) + proc/Attach(var/mob/living/simple_mob/space_worm/attachement) if(!attachement) return @@ -158,8 +158,8 @@ return proc/Detach(die = 0) - var/mob/living/simple_animal/space_worm/newHead = new /mob/living/simple_animal/space_worm/head(loc,0) - var/mob/living/simple_animal/space_worm/newHeadPrevious = previous + var/mob/living/simple_mob/space_worm/newHead = new /mob/living/simple_mob/space_worm/head(loc,0) + var/mob/living/simple_mob/space_worm/newHeadPrevious = previous previous = null //so that no extra heads are spawned diff --git a/code/modules/mob/living/simple_animal/borer/borer.dm b/code/modules/mob/living/simple_animal/borer/borer.dm deleted file mode 100644 index e4add4d749..0000000000 --- a/code/modules/mob/living/simple_animal/borer/borer.dm +++ /dev/null @@ -1,213 +0,0 @@ -/mob/living/simple_animal/borer - name = "cortical borer" - real_name = "cortical borer" - desc = "A small, quivering sluglike creature." - speak_emote = list("chirrups") - emote_hear = list("chirrups") - intelligence_level = SA_HUMANOID // Player controlled. - response_help = "pokes" - response_disarm = "prods" - response_harm = "stomps on" - icon_state = "brainslug" - item_state = "brainslug" - icon_living = "brainslug" - icon_dead = "brainslug_dead" - speed = 5 - a_intent = I_HURT - stop_automated_movement = 1 - status_flags = CANPUSH - attacktext = list("nipped") - friendly = "prods" - wander = 0 - pass_flags = PASSTABLE - universal_understand = 1 - holder_type = /obj/item/weapon/holder/borer - - var/used_dominate - var/chemicals = 10 // Chemicals used for reproduction and spitting neurotoxin. - var/mob/living/carbon/human/host // Human host for the brain worm. - var/truename // Name used for brainworm-speak. - var/mob/living/captive_brain/host_brain // Used for swapping control of the body back and forth. - var/controlling // Used in human death check. - var/docile = 0 // Sugar can stop borers from acting. - var/has_reproduced - var/roundstart - - can_be_antagged = TRUE - -/mob/living/simple_animal/borer/roundstart - roundstart = 1 - -/mob/living/simple_animal/borer/Login() - ..() - if(mind) - borers.add_antagonist(mind) - -/mob/living/simple_animal/borer/New() - ..() - - add_language("Cortical Link") - verbs += /mob/living/proc/ventcrawl - verbs += /mob/living/proc/hide - - truename = "[pick("Primary","Secondary","Tertiary","Quaternary")] [rand(1000,9999)]" - if(!roundstart) request_player() - -/mob/living/simple_animal/borer/Life() - - ..() - - if(host) - - if(!stat && !host.stat) - - if(host.reagents.has_reagent("sugar")) - if(!docile) - if(controlling) - host << "You feel the soporific flow of sugar in your host's blood, lulling you into docility." - else - src << "You feel the soporific flow of sugar in your host's blood, lulling you into docility." - docile = 1 - else - if(docile) - if(controlling) - host << "You shake off your lethargy as the sugar leaves your host's blood." - else - src << "You shake off your lethargy as the sugar leaves your host's blood." - docile = 0 - - if(chemicals < 250) - chemicals++ - if(controlling) - - if(docile) - host << "You are feeling far too docile to continue controlling your host..." - host.release_control() - return - - if(prob(5)) - host.adjustBrainLoss(0.1) - - if(prob(host.brainloss/20)) - host.say("*[pick(list("blink","blink_r","choke","aflap","drool","twitch","twitch_v","gasp"))]") - -/mob/living/simple_animal/borer/Stat() - ..() - statpanel("Status") - - if(emergency_shuttle) - var/eta_status = emergency_shuttle.get_status_panel_eta() - if(eta_status) - stat(null, eta_status) - - if (client.statpanel == "Status") - stat("Chemicals", chemicals) - -/mob/living/simple_animal/borer/proc/detatch() - - if(!host || !controlling) return - - if(istype(host,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = host - var/obj/item/organ/external/head = H.get_organ(BP_HEAD) - head.implants -= src - - controlling = 0 - - host.remove_language("Cortical Link") - host.verbs -= /mob/living/carbon/proc/release_control - host.verbs -= /mob/living/carbon/proc/punish_host - host.verbs -= /mob/living/carbon/proc/spawn_larvae - - if(host_brain) - - // these are here so bans and multikey warnings are not triggered on the wrong people when ckey is changed. - // computer_id and IP are not updated magically on their own in offline mobs -walter0o - - // host -> self - var/h2s_id = host.computer_id - var/h2s_ip= host.lastKnownIP - host.computer_id = null - host.lastKnownIP = null - - src.ckey = host.ckey - - if(!src.computer_id) - src.computer_id = h2s_id - - if(!host_brain.lastKnownIP) - src.lastKnownIP = h2s_ip - - // brain -> host - var/b2h_id = host_brain.computer_id - var/b2h_ip= host_brain.lastKnownIP - host_brain.computer_id = null - host_brain.lastKnownIP = null - - host.ckey = host_brain.ckey - - if(!host.computer_id) - host.computer_id = b2h_id - - if(!host.lastKnownIP) - host.lastKnownIP = b2h_ip - - qdel(host_brain) - -/mob/living/simple_animal/borer/proc/leave_host() - - if(!host) return - - if(host.mind) - borers.remove_antagonist(host.mind) - - src.forceMove(get_turf(host)) - - reset_view(null) - machine = null - - host.reset_view(null) - host.machine = null - host = null - return - -//Procs for grabbing players. -/mob/living/simple_animal/borer/proc/request_player() - for(var/mob/observer/dead/O in player_list) - if(jobban_isbanned(O, "Borer")) - continue - if(O.client) - if(O.client.prefs.be_special & BE_ALIEN) - question(O.client) - -/mob/living/simple_animal/borer/proc/question(var/client/C) - spawn(0) - if(!C) return - var/response = alert(C, "A cortical borer needs a player. Are you interested?", "Cortical borer request", "Yes", "No", "Never for this round") - if(!C || ckey) - return - if(response == "Yes") - transfer_personality(C) - else if (response == "Never for this round") - C.prefs.be_special ^= BE_ALIEN - -/mob/living/simple_animal/borer/proc/transfer_personality(var/client/candidate) - - if(!candidate || !candidate.mob || !candidate.mob.mind) - return - - src.mind = candidate.mob.mind - candidate.mob.mind.current = src - src.ckey = candidate.ckey - - if(src.mind) - src.mind.assigned_role = "Cortical Borer" - src.mind.special_role = "Cortical Borer" - - src << "You are a cortical borer! You are a brain slug that worms its way \ - into the head of its victim. Use stealth, persuasion and your powers of mind control to keep you, \ - your host and your eventual spawn safe and warm." - src << "You can speak to your victim with say, to other borers with say :x, and use your Abilities tab to access powers." - -/mob/living/simple_animal/borer/cannot_use_vents() - return \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/borer/say.dm b/code/modules/mob/living/simple_animal/borer/say.dm deleted file mode 100644 index 440dfa7ff7..0000000000 --- a/code/modules/mob/living/simple_animal/borer/say.dm +++ /dev/null @@ -1,40 +0,0 @@ -/mob/living/simple_animal/borer/say(var/message) - - message = sanitize(message) - 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 << "You cannot speak in IC (muted)." - return - - if (copytext(message, 1, 2) == "*") - return emote(copytext(message, 2)) - - var/datum/language/L = parse_language(message) - if(L && L.flags & HIVEMIND) - L.broadcast(src,trim(copytext(message,3)),src.truename) - return - - if(!host) - //TODO: have this pick a random mob within 3 tiles to speak for the borer. - 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 player_list) - if (istype(M, /mob/new_player)) - continue - else if(M.stat == DEAD && M.is_preference_enabled(/datum/client_preference/ghost_ears)) - M << "[src.truename] whispers to [host], \"[message]\"" \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/constructs/constructs.dm b/code/modules/mob/living/simple_animal/constructs/constructs.dm deleted file mode 100644 index 26ab3a1260..0000000000 --- a/code/modules/mob/living/simple_animal/constructs/constructs.dm +++ /dev/null @@ -1,488 +0,0 @@ -/mob/living/simple_animal/construct - name = "Construct" - real_name = "Construct" - var/construct_type = "shade" - desc = "" - speak_emote = list("hisses") - emote_hear = list("wails","screeches") - - ui_icons = 'icons/mob/screen1_construct.dmi' - has_hands = 1 - hand_form = "stone manipulators" - - response_help = "thinks better of touching" - response_disarm = "flailed at" - response_harm = "punched" - - intelligence_level = SA_HUMANOID // Player controlled. - - hovering = TRUE - softfall = TRUE //Beings made of Hellmarble and powered by the tears of the damned are not concerned with mortal things such as 'gravity'. - parachuting = TRUE - - icon_dead = "shade_dead" - var/do_glow = 1 - - speed = -1 - a_intent = I_HURT - stop_automated_movement = 1 - - status_flags = CANPUSH - - universal_speak = 0 - universal_understand = 1 - - attack_sound = 'sound/weapons/spiderlunge.ogg' - - min_oxy = 0 - max_oxy = 0 - min_tox = 0 - max_tox = 0 - min_co2 = 0 - max_co2 = 0 - min_n2 = 0 - max_n2 = 0 - - minbodytemp = 0 - show_stat_health = 1 - - faction = "cult" - supernatural = 1 - - see_invisible = SEE_INVISIBLE_NOLIGHTING - see_in_dark = 7 - - var/nullblock = 0 - - mob_swap_flags = HUMAN|SIMPLE_ANIMAL|SLIME|MONKEY - mob_push_flags = ALLMOBS - - var/list/construct_spells = list() - - can_be_antagged = TRUE - - taser_kill = 0 // no - - shock_resistance = 0.9 //Electricity isn't very effective on stone, especially that from hell. - - armor = list( - "melee" = 10, - "bullet" = 10, - "laser" = 10, - "energy" = 10, - "bomb" = 10, - "bio" = 100, - "rad" = 100) - -/mob/living/simple_animal/construct/place_spell_in_hand(var/path) - if(!path || !ispath(path)) - return 0 - - //var/obj/item/weapon/spell/S = new path(src) - var/obj/item/weapon/spell/construct/S = new path(src) - - //No hands needed for innate casts. - if(S.cast_methods & CAST_INNATE) - if(S.run_checks()) - S.on_innate_cast(src) - - if(l_hand && r_hand) //Make sure our hands aren't full. - if(istype(r_hand, /obj/item/weapon/spell)) //If they are full, perhaps we can still be useful. - var/obj/item/weapon/spell/r_spell = r_hand - if(r_spell.aspect == ASPECT_CHROMATIC) //Check if we can combine the new spell with one in our hands. - r_spell.on_combine_cast(S, src) - else if(istype(l_hand, /obj/item/weapon/spell)) - var/obj/item/weapon/spell/l_spell = l_hand - if(l_spell.aspect == ASPECT_CHROMATIC) //Check the other hand too. - l_spell.on_combine_cast(S, src) - else //Welp - to_chat(src, "You require a free manipulator to use this power.") - return 0 - - if(S.run_checks()) - put_in_hands(S) - return 1 - else - qdel(S) - return 0 - -/mob/living/simple_animal/construct/cultify() - return - -/mob/living/simple_animal/construct/New() - ..() - name = text("[initial(name)] ([rand(1, 1000)])") - real_name = name - add_language("Cult") - add_language("Occult") - for(var/spell in construct_spells) - src.add_spell(new spell, "const_spell_ready") - updateicon() - -/mob/living/simple_animal/construct/updateicon() - overlays.Cut() - ..() - if(do_glow) - add_glow() - -/mob/living/simple_animal/construct/update_icon() - ..() - if(do_glow) - add_glow() - -/mob/living/simple_animal/construct/death() - new /obj/item/weapon/ectoplasm (src.loc) - ..(null,"collapses in a shattered heap.") - ghostize() - qdel(src) - -/mob/living/simple_animal/construct/attack_generic(var/mob/user) - if(istype(user, /mob/living/simple_animal/construct/builder)) - var/mob/living/simple_animal/construct/builder/B = user - if(health < getMaxHealth()) - var/repair_lower_bound = B.melee_damage_lower * -1 - var/repair_upper_bound = B.melee_damage_upper * -1 - adjustBruteLoss(rand(repair_lower_bound, repair_upper_bound)) - adjustFireLoss(rand(repair_lower_bound, repair_upper_bound)) - user.visible_message("\The [user] mends some of \the [src]'s wounds.") - else - to_chat(user, "\The [src] is undamaged.") - return - return ..() - -/mob/living/simple_animal/construct/examine(mob/user) - ..(user) - var/msg = "*---------*\nThis is \icon[src] \a [src]!\n" - if (src.health < src.getMaxHealth()) - msg += "" - if (src.health >= src.getMaxHealth()/2) - msg += "It looks slightly dented.\n" - else - msg += "It looks severely dented!\n" - msg += "" - msg += "*---------*" - - user << msg - -/mob/living/simple_animal/construct/Process_Spacemove() - return 1 //Constructs levitate, can fall from a shuttle with no harm, and are piloted by either damned spirits or some otherworldly entity. It's not hard to believe. - -/////////////////Juggernaut/////////////// - - - -/mob/living/simple_animal/construct/armoured - name = "Juggernaut" - real_name = "Juggernaut" - construct_type = "juggernaut" - desc = "A possessed suit of armour driven by the will of the restless dead" - icon = 'icons/mob/mob.dmi' - icon_state = "behemoth" - icon_living = "behemoth" - maxHealth = 300 - health = 300 - response_harm = "harmlessly punches" - harm_intent_damage = 0 - melee_damage_lower = 30 - melee_damage_upper = 40 - attack_armor_pen = 60 //Being punched by a living, floating statue. - attacktext = list("smashed their armoured gauntlet into") - friendly = list("pats") - mob_size = MOB_HUGE - speed = 2 //Not super fast, but it might catch up to someone in armor who got punched once or twice. - environment_smash = 2 - attack_sound = 'sound/weapons/heavysmash.ogg' - status_flags = 0 - resistance = 10 - construct_spells = list(/spell/aoe_turf/conjure/forcewall/lesser, - /spell/targeted/fortify, - /spell/targeted/construct_advanced/slam - ) - - armor = list( - "melee" = 70, - "bullet" = 30, - "laser" = 30, - "energy" = 30, - "bomb" = 10, - "bio" = 100, - "rad" = 100) - -/mob/living/simple_animal/construct/armoured/Life() - weakened = 0 - ..() - -/mob/living/simple_animal/construct/armoured/bullet_act(var/obj/item/projectile/P) -// if(istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam)) //If it's going to be slow, it's probably going to need every reflect it can get. - var/reflectchance = 80 - round(P.damage/3) - if(prob(reflectchance)) - var/damage_mod = rand(2,4) - var/projectile_dam_type = P.damage_type - var/incoming_damage = (round(P.damage / damage_mod) - (round((P.damage / damage_mod) * 0.3))) - var/armorcheck = run_armor_check(null, P.check_armour) - var/soakedcheck = get_armor_soak(null, P.check_armour) - if(!(istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam))) - visible_message("The [P.name] bounces off of [src]'s shell!", \ - "The [P.name] bounces off of [src]'s shell!") - new /obj/item/weapon/material/shard/shrapnel(src.loc) - if(!(P.damage_type == BRUTE || P.damage_type == BURN)) - projectile_dam_type = BRUTE - incoming_damage = round(incoming_damage / 4) //Damage from strange sources is converted to brute for physical projectiles, though severely decreased. - apply_damage(incoming_damage, projectile_dam_type, null, armorcheck, soakedcheck, is_sharp(P), has_edge(P), P) - return -1 //Doesn't reflect non-beams or non-energy projectiles. They just smack and drop with little to no effect. - else - visible_message("The [P.name] gets reflected by [src]'s shell!", \ - "The [P.name] gets reflected by [src]'s shell!") - damage_mod = rand(3,5) - incoming_damage = (round(P.damage / damage_mod) - (round((P.damage / damage_mod) * 0.3))) - if(!(P.damage_type == BRUTE || P.damage_type == BURN)) - projectile_dam_type = BURN - incoming_damage = round(incoming_damage / 4) //Damage from strange sources is converted to burn for energy-type projectiles, though severely decreased. - apply_damage(incoming_damage, P.damage_type, null, armorcheck, soakedcheck, is_sharp(P), has_edge(P), P) - - // Find a turf near or on the original location to bounce to - if(P.starting) - var/new_x = P.starting.x + pick(0, 0, -1, 1, -2, 2, -2, 2, -2, 2, -3, 3, -3, 3) - var/new_y = P.starting.y + pick(0, 0, -1, 1, -2, 2, -2, 2, -2, 2, -3, 3, -3, 3) - var/turf/curloc = get_turf(src) - - // redirect the projectile - P.redirect(new_x, new_y, curloc, src) - P.reflected = 1 - - return -1 // complete projectile permutation - - return (..(P)) - - - -////////////////////////Wraith///////////////////////////////////////////// - - - -/mob/living/simple_animal/construct/wraith - name = "Wraith" - real_name = "Wraith" - construct_type = "wraith" - desc = "A wicked bladed shell contraption piloted by a bound spirit." - icon = 'icons/mob/mob.dmi' - icon_state = "floating" - icon_living = "floating" - maxHealth = 200 - health = 200 - melee_damage_lower = 25 - melee_damage_upper = 30 - attack_armor_pen = 15 - attack_sharp = 1 - attack_edge = 1 - attacktext = list("slashed") - friendly = list("pinches") - speed = -1 - environment_smash = 1 - attack_sound = 'sound/weapons/rapidslice.ogg' - construct_spells = list(/spell/targeted/ethereal_jaunt/shift, - /spell/targeted/ambush_mode - ) - -/mob/living/simple_animal/construct/wraith/DoPunch(var/atom/A) - . = ..() - if(. && isliving(A)) - var/mob/living/L = A - L.add_modifier(/datum/modifier/deep_wounds, 30 SECONDS) - -/////////////////////////////Artificer///////////////////////// - - - -/mob/living/simple_animal/construct/builder - name = "Artificer" - real_name = "Artificer" - construct_type = "artificer" - desc = "A bulbous construct dedicated to building and maintaining temples to their otherworldly lords." - icon = 'icons/mob/mob.dmi' - icon_state = "artificer" - icon_living = "artificer" - maxHealth = 150 - health = 150 - response_harm = "viciously beaten" - harm_intent_damage = 5 - melee_damage_lower = 15 //It's not the strongest of the bunch, but that doesn't mean it can't hurt you. - melee_damage_upper = 20 - attacktext = list("rammed") - speed = 0 - environment_smash = 2 - attack_sound = 'sound/weapons/rapidslice.ogg' - construct_spells = list(/spell/aoe_turf/conjure/construct/lesser, - /spell/aoe_turf/conjure/wall, - /spell/aoe_turf/conjure/floor, - /spell/aoe_turf/conjure/soulstone, - /spell/aoe_turf/conjure/pylon, - /spell/aoe_turf/conjure/door, - /spell/aoe_turf/conjure/grille, - /spell/targeted/occult_repair_aura, - /spell/targeted/construct_advanced/mend_acolyte - ) - - -/////////////////////////////Behemoth///////////////////////// -/* - * The Behemoth. Admin-allowance only, still try to keep it in some guideline of 'Balanced', even if it means Security has to be fully geared to be so. - */ - -/mob/living/simple_animal/construct/behemoth - name = "Behemoth" - real_name = "Behemoth" - construct_type = "juggernaut" - desc = "The pinnacle of occult technology, Behemoths are nothing shy of both an Immovable Object, and Unstoppable Force." - icon = 'icons/mob/mob.dmi' - icon_state = "behemoth" - icon_living = "behemoth" - maxHealth = 750 - health = 750 - speak_emote = list("rumbles") - response_harm = "harmlessly punched" - harm_intent_damage = 0 - melee_damage_lower = 50 - melee_damage_upper = 50 - attacktext = list("brutally crushed") - friendly = list("pokes") //Anything nice the Behemoth would do would still Kill the Human. Leave it at poke. - speed = 5 - environment_smash = 2 - attack_sound = 'sound/weapons/heavysmash.ogg' - resistance = 10 - icon_scale = 2 - var/energy = 0 - var/max_energy = 1000 - armor = list( - "melee" = 60, - "bullet" = 60, - "laser" = 60, - "energy" = 30, - "bomb" = 10, - "bio" = 100, - "rad" = 100) - construct_spells = list(/spell/aoe_turf/conjure/forcewall/lesser, - /spell/targeted/fortify, - /spell/targeted/construct_advanced/slam - ) - -/mob/living/simple_animal/construct/behemoth/bullet_act(var/obj/item/projectile/P) - var/reflectchance = 80 - round(P.damage/3) - if(prob(reflectchance)) - visible_message("The [P.name] gets reflected by [src]'s shell!", \ - "The [P.name] gets reflected by [src]'s shell!") - - // Find a turf near or on the original location to bounce to - if(P.starting) - var/new_x = P.starting.x + pick(0, 0, -1, 1, -2, 2, -2, 2, -2, 2, -3, 3, -3, 3) - var/new_y = P.starting.y + pick(0, 0, -1, 1, -2, 2, -2, 2, -2, 2, -3, 3, -3, 3) - var/turf/curloc = get_turf(src) - - // redirect the projectile - P.redirect(new_x, new_y, curloc, src) - P.reflected = 1 - - return -1 // complete projectile permutation - - return (..(P)) - -////////////////////////Harvester//////////////////////////////// -/* - * Master of Spells and Ranged Abilities. Not as fragile as the Wraith, but nowhere near as maneuverable and deadly in melee. - */ - -/mob/living/simple_animal/construct/harvester - name = "Harvester" - real_name = "Harvester" - construct_type = "harvester" - desc = "A tendril-laden construct piloted by a chained mind." - icon = 'icons/mob/mob.dmi' - icon_state = "harvester" - icon_living = "harvester" - maxHealth = 150 - health = 150 - melee_damage_lower = 20 - melee_damage_upper = 25 - attack_sharp = 1 - attacktext = list("violently stabbed") - friendly = list("caresses") - speed = 0 - environment_smash = 1 - attack_sound = 'sound/weapons/pierce.ogg' - - armor = list( - "melee" = 10, - "bullet" = 20, - "laser" = 20, - "energy" = 20, - "bomb" = 20, - "bio" = 100, - "rad" = 100) - - construct_spells = list( - /spell/aoe_turf/knock/harvester, - /spell/targeted/construct_advanced/inversion_beam, - /spell/targeted/construct_advanced/agonizing_sphere, - /spell/rune_write - ) - -////////////////Glow////////////////// -/mob/living/simple_animal/construct/proc/add_glow() - var/image/eye_glow = image(icon,"glow-[icon_state]") - eye_glow.plane = PLANE_LIGHTING_ABOVE - overlays += eye_glow - set_light(2, -2, l_color = "#FFFFFF") - -/mob/living/simple_animal/construct/proc/remove_glow() - overlays.Cut() - -////////////////HUD////////////////////// - -/mob/living/simple_animal/construct/Life() - . = ..() - if(.) - if(fire) - if(fire_alert) fire.icon_state = "fire1" - else fire.icon_state = "fire0" - if(pullin) - if(pulling) pullin.icon_state = "pull1" - else pullin.icon_state = "pull0" - - if(purged) - if(purge > 0) purged.icon_state = "purge1" - else purged.icon_state = "purge0" - - silence_spells(purge) - -/mob/living/simple_animal/construct/updatehealth() //Special icons. - health = getMaxHealth() - getToxLoss() - getFireLoss() - getBruteLoss() - - //Alive, becoming dead - if((stat < DEAD) && (health <= 0)) - death() - - //Overhealth - if(health > getMaxHealth()) - health = getMaxHealth() - - //Update our hud if we have one - if(healths) - if(stat != DEAD) - var/heal_per = (health / getMaxHealth()) * 100 - switch(heal_per) - if(100 to INFINITY) - healths.icon_state = "[construct_type]_health0" - if(80 to 100) - healths.icon_state = "[construct_type]_health1" - if(60 to 80) - healths.icon_state = "[construct_type]_health2" - if(40 to 60) - healths.icon_state = "[construct_type]_health3" - if(20 to 40) - healths.icon_state = "[construct_type]_health4" - if(0 to 20) - healths.icon_state = "[construct_type]_health5" - else - healths.icon_state = "[construct_type]_health6" - else - healths.icon_state = "[construct_type]_health7" \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/humanoids/clown.dm b/code/modules/mob/living/simple_animal/humanoids/clown.dm index d94fa47c77..9641611c33 100644 --- a/code/modules/mob/living/simple_animal/humanoids/clown.dm +++ b/code/modules/mob/living/simple_animal/humanoids/clown.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/hostile/clown +/mob/living/simple_mob/hostile/clown name = "clown" desc = "A denizen of clown planet" tt_desc = "E Homo sapiens corydon" //this is an actual clown, as opposed to someone dressed up as one diff --git a/code/modules/mob/living/simple_animal/humanoids/head.dm b/code/modules/mob/living/simple_animal/humanoids/head.dm deleted file mode 100644 index 22460f0990..0000000000 --- a/code/modules/mob/living/simple_animal/humanoids/head.dm +++ /dev/null @@ -1,61 +0,0 @@ -//Look Sir, free head! -/mob/living/simple_animal/head - name = "CommandBattle AI" - desc = "A standard borg shell on its chest crude marking saying CommandBattle AI MK4 : Head." - icon_state = "crab" - icon_living = "crab" - icon_dead = "crab_dead" - intelligence_level = SA_ANIMAL - - wander = 0 - stop_automated_movement = 1 - universal_speak = 1 - turns_per_move = 5 - - response_help = "pets" - response_disarm = "gently pushes aside" - response_harm = "punches" - - speak_chance = 1 - speak_emote = list("clicks") - emote_hear = list("clicks") - emote_see = list("clacks") - - meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat - - var/list/insults = list( - "Man you suck", - "You look like the most retarded douche around", - "What's up?, oh wait nevermind you are a fucking asshat", - "you are just overly retarded", - "Whiteman said what?!",) - var/list/comments = list("Man have you seen those furry cats?,I mean who in the right mind would like something like that?", - "They call me abusive,I just like the truth", - "Beeboop, im a robit", - "Gooogooooll, break ya bones", - "Crab say what?", - "Man they say we have space lizards now, man this shit is getting more wack every minute", - "The so called \"improved\" station AI is just bullshit, that thing aint fun for noone", - "The Colony Director is a traitor, he took my power core.", - "Say \"what\" again. Say \"what\" again. I dare you. I double-dare you, motherfucker. Say \"what\" one more goddamn time.", - "Ezekiel 25:17 ,The path of the righteous man is beset on all sides by the iniquities of the selfish and the tyranny of evil men. Blessed is he who in the name of charity and good will shepherds the weak through the valley of darkness, for he is truly his brother's keeper and the finder of lost children. And I will strike down upon thee with great vengeance and furious anger those who attempt to poison and destroy my brothers. And you will know my name is the Lord... when I lay my vengeance upon thee.", - "Did you notice a sign out in front of my house that said \"Dead Nigger Storage\"?") - -/mob/living/simple_animal/head/Life() - . = ..() - if(!. || ai_inactive) return - - for(var/mob/A in viewers(world.view,src)) - if(A.ckey) - say_something(A) - -/mob/living/simple_animal/head/proc/say_something(mob/A) - if(prob(85)) - return - if(prob(30)) - var/msg = pick(insults) - msg = "Hey, [A.name].. [msg]" - src.say(msg) - else - var/msg = pick(comments) - src.say(msg) diff --git a/code/modules/mob/living/simple_animal/humanoids/mechamobs.dm b/code/modules/mob/living/simple_animal/humanoids/mechamobs.dm index 9f8c737894..9e1398884f 100644 --- a/code/modules/mob/living/simple_animal/humanoids/mechamobs.dm +++ b/code/modules/mob/living/simple_animal/humanoids/mechamobs.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/hostile/mecha +/mob/living/simple_mob/hostile/mecha name = "mercenary gygax" desc = "Well that's forboding." icon = 'icons/mecha/mecha.dmi' @@ -66,38 +66,38 @@ var/datum/effect/effect/system/spark_spread/sparks var/wreckage = /obj/effect/decal/mecha_wreckage/gygax/dark -/mob/living/simple_animal/hostile/mecha/New() +/mob/living/simple_mob/hostile/mecha/New() ..() sparks = new (src) sparks.set_up(3, 1, src) -/mob/living/simple_animal/hostile/mecha/Destroy() +/mob/living/simple_mob/hostile/mecha/Destroy() qdel(sparks) ..() -/mob/living/simple_animal/hostile/mecha/Life() +/mob/living/simple_mob/hostile/mecha/Life() . = ..() if(!.) return if((health < getMaxHealth()*0.3) && prob(10)) sparks.start() -/mob/living/simple_animal/hostile/mecha/bullet_act() +/mob/living/simple_mob/hostile/mecha/bullet_act() ..() sparks.start() -/mob/living/simple_animal/hostile/mecha/death() +/mob/living/simple_mob/hostile/mecha/death() ..(0,"explodes!") sparks.start() explosion(get_turf(src), 0, 0, 1, 3) qdel(src) new /obj/effect/decal/mecha_wreckage/gygax/dark(get_turf(src)) -/mob/living/simple_animal/hostile/mecha/Move() +/mob/living/simple_mob/hostile/mecha/Move() ..() playsound(src,'sound/mecha/mechstep.ogg',40,1) - -/mob/living/simple_animal/hostile/mecha/malf_drone +// This is a PoI mob, not the normal, floaty drones that hang out around windows +/mob/living/simple_mob/hostile/mecha/malf_drone name = "autonomous mechanized drone" desc = "It appears to be an exosuit, piloted by a drone intelligence. It looks scary." intelligence_level = SA_ROBOTIC @@ -116,8 +116,8 @@ say_got_target = list("Threat detected.", "New task: Remove threat.", "Threat removal engaged.", "Engaging target.") returns_home = TRUE -/mob/living/simple_animal/hostile/mecha/malf_drone/isSynthetic() +/mob/living/simple_mob/hostile/mecha/malf_drone/isSynthetic() return TRUE -/mob/living/simple_animal/hostile/mecha/malf_drone/speech_bubble_appearance() +/mob/living/simple_mob/hostile/mecha/malf_drone/speech_bubble_appearance() return "synthetic_evil" \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/humanoids/pirate.dm b/code/modules/mob/living/simple_animal/humanoids/pirate.dm index a02e4382bb..4e833b90ac 100644 --- a/code/modules/mob/living/simple_animal/humanoids/pirate.dm +++ b/code/modules/mob/living/simple_animal/humanoids/pirate.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/hostile/pirate +/mob/living/simple_mob/hostile/pirate name = "Pirate" desc = "Does what he wants cause a pirate is free." tt_desc = "E Homo sapiens" @@ -50,7 +50,7 @@ var/corpse = /obj/effect/landmark/mobcorpse/pirate -/mob/living/simple_animal/hostile/pirate/ranged +/mob/living/simple_mob/hostile/pirate/ranged name = "Pirate Gunner" icon_state = "pirateranged" icon_living = "pirateranged" @@ -64,7 +64,7 @@ corpse = /obj/effect/landmark/mobcorpse/pirate/ranged -/mob/living/simple_animal/hostile/pirate/death() +/mob/living/simple_mob/hostile/pirate/death() ..() if(corpse) new corpse (src.loc) diff --git a/code/modules/mob/living/simple_animal/humanoids/russian.dm b/code/modules/mob/living/simple_animal/humanoids/russian.dm index d02c36de5a..e13b5ed968 100644 --- a/code/modules/mob/living/simple_animal/humanoids/russian.dm +++ b/code/modules/mob/living/simple_animal/humanoids/russian.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/hostile/russian +/mob/living/simple_mob/hostile/russian name = "russian" desc = "For the Motherland!" tt_desc = "E Homo sapiens" @@ -47,7 +47,7 @@ var/corpse = /obj/effect/landmark/mobcorpse/russian -/mob/living/simple_animal/hostile/russian/ranged +/mob/living/simple_mob/hostile/russian/ranged icon_state = "russianranged" icon_living = "russianranged" @@ -60,7 +60,7 @@ corpse = /obj/effect/landmark/mobcorpse/russian/ranged -/mob/living/simple_animal/hostile/russian/death() +/mob/living/simple_mob/hostile/russian/death() ..() if(corpse) new corpse (src.loc) diff --git a/code/modules/mob/living/simple_animal/humanoids/syndicate.dm b/code/modules/mob/living/simple_animal/humanoids/syndicate.dm index dfeea36cfe..2cc300b82c 100644 --- a/code/modules/mob/living/simple_animal/humanoids/syndicate.dm +++ b/code/modules/mob/living/simple_animal/humanoids/syndicate.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/hostile/syndicate +/mob/living/simple_mob/hostile/syndicate name = "mercenary" desc = "Death to the Company." tt_desc = "E Homo sapiens" @@ -65,7 +65,7 @@ var/corpse = /obj/effect/landmark/mobcorpse/syndicatesoldier -/mob/living/simple_animal/hostile/syndicate/death() +/mob/living/simple_mob/hostile/syndicate/death() if(corpse) ..() new corpse (src.loc) @@ -78,7 +78,7 @@ ///////////////Sword and shield//////////// -/mob/living/simple_animal/hostile/syndicate/melee +/mob/living/simple_mob/hostile/syndicate/melee icon_state = "syndicatemelee" icon_living = "syndicatemelee" @@ -93,7 +93,7 @@ loot_list = list(/obj/item/weapon/melee/energy/sword/red = 100, /obj/item/weapon/shield/energy = 100) -/mob/living/simple_animal/hostile/syndicate/melee/attackby(var/obj/item/O as obj, var/mob/user as mob) +/mob/living/simple_mob/hostile/syndicate/melee/attackby(var/obj/item/O as obj, var/mob/user as mob) if(O.force) if(prob(20)) visible_message("\The [src] blocks \the [O] with its shield!") @@ -106,7 +106,7 @@ usr << "This weapon is ineffective, it does no damage." visible_message("\The [user] gently taps [src] with \the [O].") -/mob/living/simple_animal/hostile/syndicate/melee/bullet_act(var/obj/item/projectile/Proj) +/mob/living/simple_mob/hostile/syndicate/melee/bullet_act(var/obj/item/projectile/Proj) if(!Proj) return if(prob(35)) visible_message("[src] blocks [Proj] with its shield!") @@ -116,7 +116,7 @@ else ..() -/mob/living/simple_animal/hostile/syndicate/melee/space +/mob/living/simple_mob/hostile/syndicate/melee/space name = "syndicate commando" icon_state = "syndicatemeleespace" icon_living = "syndicatemeleespace" @@ -137,10 +137,10 @@ corpse = /obj/effect/landmark/mobcorpse/syndicatecommando -/mob/living/simple_animal/hostile/syndicate/melee/space/Process_Spacemove(var/check_drift = 0) +/mob/living/simple_mob/hostile/syndicate/melee/space/Process_Spacemove(var/check_drift = 0) return -/mob/living/simple_animal/hostile/syndicate/ranged +/mob/living/simple_mob/hostile/syndicate/ranged icon_state = "syndicateranged" icon_living = "syndicateranged" @@ -152,7 +152,7 @@ loot_list = list(/obj/item/weapon/gun/projectile/automatic/c20r = 100) -/mob/living/simple_animal/hostile/syndicate/ranged/laser +/mob/living/simple_mob/hostile/syndicate/ranged/laser icon_state = "syndicateranged_laser" icon_living = "syndicateranged_laser" rapid = 0 @@ -161,7 +161,7 @@ loot_list = list(/obj/item/weapon/gun/energy/laser = 100) -/mob/living/simple_animal/hostile/syndicate/ranged/ionrifle +/mob/living/simple_mob/hostile/syndicate/ranged/ionrifle icon_state = "syndicateranged_ionrifle" icon_living = "syndicateranged_ionrifle" rapid = 0 @@ -170,7 +170,7 @@ loot_list = list(/obj/item/weapon/gun/energy/ionrifle = 100) -/mob/living/simple_animal/hostile/syndicate/ranged/space +/mob/living/simple_mob/hostile/syndicate/ranged/space name = "space mercenary" //VOREStation Edit icon_state = "syndicaterangedpsace" icon_living = "syndicaterangedpsace" @@ -190,7 +190,7 @@ corpse = /obj/effect/landmark/mobcorpse/syndicatecommando -/mob/living/simple_animal/hostile/syndicate/ranged/space/Process_Spacemove(var/check_drift = 0) +/mob/living/simple_mob/hostile/syndicate/ranged/space/Process_Spacemove(var/check_drift = 0) return /////////////////////////////////////////////// @@ -198,38 +198,38 @@ // Don't leave corpses, to help balance loot. /////////////////////////////////////////////// -/mob/living/simple_animal/hostile/syndicate/poi +/mob/living/simple_mob/hostile/syndicate/poi loot_list = list() corpse = null -/mob/living/simple_animal/hostile/syndicate/melee/poi +/mob/living/simple_mob/hostile/syndicate/melee/poi loot_list = list() corpse = null -/mob/living/simple_animal/hostile/syndicate/melee/space/poi +/mob/living/simple_mob/hostile/syndicate/melee/space/poi loot_list = list() corpse = null -/mob/living/simple_animal/hostile/syndicate/ranged/poi +/mob/living/simple_mob/hostile/syndicate/ranged/poi loot_list = list() corpse = null -/mob/living/simple_animal/hostile/syndicate/ranged/laser/poi +/mob/living/simple_mob/hostile/syndicate/ranged/laser/poi loot_list = list() corpse = null -/mob/living/simple_animal/hostile/syndicate/ranged/ionrifle/poi +/mob/living/simple_mob/hostile/syndicate/ranged/ionrifle/poi loot_list = list() corpse = null -/mob/living/simple_animal/hostile/syndicate/ranged/space/poi +/mob/living/simple_mob/hostile/syndicate/ranged/space/poi loot_list = list() corpse = null //Viscerators -/mob/living/simple_animal/hostile/viscerator +/mob/living/simple_mob/hostile/viscerator name = "viscerator" desc = "A small, twin-bladed machine capable of inflicting very deadly lacerations." icon = 'icons/mob/critter.dmi' @@ -261,6 +261,6 @@ max_n2 = 0 minbodytemp = 0 -/mob/living/simple_animal/hostile/viscerator/death() +/mob/living/simple_mob/hostile/viscerator/death() ..(null,"is smashed into pieces!") qdel(src) diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 71a523c7d0..d143f37ae3 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -3,14 +3,14 @@ //Talky things #define try_say_list(L) if(L.len) say(pick(L)) -/mob/living/simple_animal +/mob/living/simple_mob name = "animal" desc = "" icon = 'icons/mob/animal.dmi' health = 20 maxHealth = 20 - mob_bump_flag = SIMPLE_ANIMAL + mob_bump_flag = simple_mob mob_swap_flags = MONKEY|SLIME|HUMAN mob_push_flags = MONKEY|SLIME|HUMAN @@ -169,7 +169,7 @@ var/mob/living/target_mob // Who I'm trying to attack var/mob/living/follow_mob // Who I'm recruited by var/mob/living/list/friends = list() // People who are immune to my wrath, for now - var/mob/living/simple_animal/list/faction_friends = list() // Other simple mobs I am friends with + var/mob/living/simple_mob/list/faction_friends = list() // Other simple mobs I am friends with var/turf/list/walk_list = list()// List of turfs to walk through to get somewhere var/astarpathing = 0 // Am I currently pathing to somewhere? var/stance_changed = 0 // When our stance last changed (world.time) @@ -181,7 +181,7 @@ ////// ////// ////// var/life_disabled = 0 //VOREStation Edit -- For performance reasons -/mob/living/simple_animal/New() +/mob/living/simple_mob/New() ..() verbs -= /mob/verb/observe home_turf = get_turf(src) @@ -195,8 +195,8 @@ default_language = languages[1] if(cooperative) - var/mob/living/simple_animal/first_friend - for(var/mob/living/simple_animal/M in living_mob_list) + var/mob/living/simple_mob/first_friend + for(var/mob/living/simple_mob/M in living_mob_list) if(M.faction == src.faction) first_friend = M break @@ -206,7 +206,7 @@ else faction_friends |= src -/mob/living/simple_animal/Destroy() +/mob/living/simple_mob/Destroy() home_turf = null path_overlay = null default_language = null @@ -225,7 +225,7 @@ return ..() //Client attached -/mob/living/simple_animal/Login() +/mob/living/simple_mob/Login() . = ..() ai_inactive = 1 handle_stance(STANCE_IDLE) @@ -233,19 +233,19 @@ to_chat(src,"Mob AI disabled while you are controlling the mob.
      You are \the [src]. [player_msg]") //Client detatched -/mob/living/simple_animal/Logout() +/mob/living/simple_mob/Logout() spawn(15 SECONDS) //15 seconds to get back into the mob before it goes wild if(src && !src.client) ai_inactive = initial(ai_inactive) //So if they never have an AI, they stay that way. ..() //For debug purposes! -/mob/living/simple_animal/proc/ai_log_output(var/msg = "missing message", var/ver = 1) +/mob/living/simple_mob/proc/ai_log_output(var/msg = "missing message", var/ver = 1) if(ver <= debug_ai) log_debug("SA-AI: ([src]:[x],[y],[z])(@[world.time]): [msg] ") //Should we be dead? -/mob/living/simple_animal/updatehealth() +/mob/living/simple_mob/updatehealth() health = getMaxHealth() - getToxLoss() - getFireLoss() - getBruteLoss() //Alive, becoming dead @@ -293,7 +293,7 @@ if(0 to 25) nutrition_icon.icon_state = "nutrition4" -/mob/living/simple_animal/update_icon() +/mob/living/simple_mob/update_icon() . = ..() var/mutable_appearance/ma = new(src) ma.layer = layer @@ -332,7 +332,7 @@ appearance = ma // If your simple mob's update_icon() call calls overlays.Cut(), this needs to be called after this, or manually apply modifier_overly to overlays. -/mob/living/simple_animal/update_modifier_visuals() +/mob/living/simple_mob/update_modifier_visuals() var/image/effects = null if(modifier_overlay) overlays -= modifier_overlay @@ -351,7 +351,7 @@ overlays += modifier_overlay -/mob/living/simple_animal/Life() +/mob/living/simple_mob/Life() //VOREStation Edit if(life_disabled) @@ -402,11 +402,11 @@ // Resists out of things. // Sometimes there are times you want SAs to be buckled to something, so override this for when that is needed. -/mob/living/simple_animal/proc/handle_resist() +/mob/living/simple_mob/proc/handle_resist() resist() // Peforms the random walk wandering -/mob/living/simple_animal/proc/handle_wander_movement() +/mob/living/simple_mob/proc/handle_wander_movement() if(isturf(src.loc) && !resting && !buckled && canmove) //Physically capable of moving? lifes_since_move++ //Increment turns since move (turns are life() cycles) if(lifes_since_move >= turns_per_move) @@ -421,7 +421,7 @@ lifes_since_move = 0 // Checks to see if mob doesn't like this kind of turf -/mob/living/simple_animal/proc/avoid_turf(var/turf/turf) +/mob/living/simple_mob/proc/avoid_turf(var/turf/turf) if(!turf) return TRUE //Avoid the nothing, yes @@ -431,7 +431,7 @@ return FALSE //Override it on stuff to adjust // Handles random chatter, called from Life() when stance = STANCE_IDLE -/mob/living/simple_animal/proc/handle_idle_speaking() +/mob/living/simple_mob/proc/handle_idle_speaking() if(rand(0,200) < speak_chance) if(speak && speak.len) if((emote_hear && emote_hear.len) || (emote_see && emote_see.len)) @@ -466,7 +466,7 @@ // Handle interacting with and taking damage from atmos // TODO - Refactor this to use handle_environment() like a good /mob/living -/mob/living/simple_animal/proc/handle_atmos() +/mob/living/simple_mob/proc/handle_atmos() var/atmos_unsuitable = 0 var/atom/A = src.loc @@ -531,13 +531,13 @@ oxygen.icon_state = "oxy0" // For setting the stance WITHOUT processing it -/mob/living/simple_animal/proc/set_stance(var/new_stance) +/mob/living/simple_mob/proc/set_stance(var/new_stance) stance = new_stance stance_changed = world.time ai_log("set_stance() changing to [new_stance]",2) // For proccessing the current stance, or setting and processing a new one -/mob/living/simple_animal/proc/handle_stance(var/new_stance) +/mob/living/simple_mob/proc/handle_stance(var/new_stance) if(ai_inactive) stance = STANCE_IDLE return @@ -580,24 +580,18 @@ annoyed = 50 AttackTarget() -/mob/living/simple_animal/proc/handle_supernatural() +/mob/living/simple_mob/proc/handle_supernatural() if(purge) purge -= 1 -/mob/living/simple_animal/gib() +/mob/living/simple_mob/gib() ..(icon_gib,1,icon) // we need to specify where the gib animation is stored -/mob/living/simple_animal/emote(var/act, var/type, var/desc) +/mob/living/simple_mob/emote(var/act, var/type, var/desc) if(act) ..(act, type, desc) -/mob/living/simple_animal/proc/visible_emote(var/act_desc) - custom_emote(1, act_desc) - -/mob/living/simple_animal/proc/audible_emote(var/act_desc) - custom_emote(2, act_desc) - -/mob/living/simple_animal/bullet_act(var/obj/item/projectile/Proj) +/mob/living/simple_mob/bullet_act(var/obj/item/projectile/Proj) ai_log("bullet_act() I was shot by: [Proj.firer]",2) /* VOREStation Edit - Ace doesn't like bonus SA damage. @@ -612,7 +606,7 @@ react_to_attack(Proj.firer) // When someone clicks us with an empty hand -/mob/living/simple_animal/attack_hand(mob/living/carbon/human/M as mob) +/mob/living/simple_mob/attack_hand(mob/living/carbon/human/M as mob) ..() switch(M.a_intent) @@ -659,7 +653,7 @@ return // When somoene clicks us with an item in hand -/mob/living/simple_animal/attackby(var/obj/item/O, var/mob/user) +/mob/living/simple_mob/attackby(var/obj/item/O, var/mob/user) if(istype(O, /obj/item/stack/medical)) if(stat != DEAD) var/obj/item/stack/medical/MED = O @@ -685,7 +679,7 @@ return ..() -/mob/living/simple_animal/hit_with_weapon(obj/item/O, mob/living/user, var/effective_force, var/hit_zone) +/mob/living/simple_mob/hit_with_weapon(obj/item/O, mob/living/user, var/effective_force, var/hit_zone) //Animals can't be stunned(?) if(O.damtype == HALLOSS) @@ -703,18 +697,18 @@ . = ..() // When someone throws something at us -/mob/living/simple_animal/hitby(atom/movable/AM) +/mob/living/simple_mob/hitby(atom/movable/AM) ..() if(AM.thrower) react_to_attack(AM.thrower) //SA vs SA basically -/mob/living/simple_animal/attack_generic(var/mob/attacker) - ..() +/mob/living/simple_mob/attack_generic(var/mob/attacker) if(attacker) react_to_attack(attacker) + return ..() -/mob/living/simple_animal/movement_delay() +/mob/living/simple_mob/movement_delay() var/tally = 0 //Incase I need to add stuff other than "speed" later tally = speed @@ -738,13 +732,13 @@ return tally+config.animal_delay -/mob/living/simple_animal/Stat() +/mob/living/simple_mob/Stat() ..() if(statpanel("Status") && show_stat_health) stat(null, "Health: [round((health / getMaxHealth()) * 100)]%") -/mob/living/simple_animal/lay_down() +/mob/living/simple_mob/lay_down() ..() if(resting && icon_rest) icon_state = icon_rest @@ -752,7 +746,7 @@ icon_state = icon_living update_icon() -/mob/living/simple_animal/death(gibbed, deathmessage = "dies!") +/mob/living/simple_mob/death(gibbed, deathmessage = "dies!") density = 0 //We don't block even if we did before walk(src, 0) //We stop any background-processing walks resting = 0 //We can rest in peace later. @@ -770,7 +764,7 @@ return ..(gibbed,deathmessage) -/mob/living/simple_animal/ex_act(severity) +/mob/living/simple_mob/ex_act(severity) if(!blinded) flash_eyes() var/armor = run_armor_check(def_zone = null, attack_flag = "bomb") @@ -789,7 +783,7 @@ gib() // Check target_mob if worthy of attack (i.e. check if they are dead or empty mecha) -/mob/living/simple_animal/proc/SA_attackable(target_mob) +/mob/living/simple_mob/proc/SA_attackable(target_mob) ai_log("SA_attackable([target_mob])",3) if (isliving(target_mob)) var/mob/living/L = target_mob @@ -802,7 +796,7 @@ ai_log("SA_attackable([target_mob]): no",3) return 0 -/mob/living/simple_animal/say(var/message,var/datum/language/language) +/mob/living/simple_mob/say(var/message,var/datum/language/language) var/verb = "says" if(speak_emote.len) verb = pick(speak_emote) @@ -811,10 +805,10 @@ ..(message, null, verb) -/mob/living/simple_animal/get_speech_ending(verb, var/ending) +/mob/living/simple_mob/get_speech_ending(verb, var/ending) return verb -/mob/living/simple_animal/put_in_hands(var/obj/item/W) // No hands. +/mob/living/simple_mob/put_in_hands(var/obj/item/W) // No hands. if(has_hands) put_in_active_hand(W) return 1 @@ -822,7 +816,7 @@ return 1 // Harvest an animal's delicious byproducts -/mob/living/simple_animal/proc/harvest(var/mob/user) +/mob/living/simple_mob/proc/harvest(var/mob/user) var/actual_meat_amount = max(1,(meat_amount/2)) if(meat_type && actual_meat_amount>0 && (stat == DEAD)) for(var/i=0;i[user] butchers \the [src] messily!") gib() -/mob/living/simple_animal/handle_fire() +/mob/living/simple_mob/handle_fire() return -/mob/living/simple_animal/update_fire() +/mob/living/simple_mob/update_fire() return -/mob/living/simple_animal/IgniteMob() +/mob/living/simple_mob/IgniteMob() return -/mob/living/simple_animal/ExtinguishMob() +/mob/living/simple_mob/ExtinguishMob() return //We got hit! Consider hitting them back! -/mob/living/simple_animal/proc/react_to_attack(var/mob/living/M) +/mob/living/simple_mob/proc/react_to_attack(var/mob/living/M) if(ai_inactive || stat || M == target_mob) return //Not if we're dead or already hitting them if(M in friends || M.faction == faction) return //I'll overlook it THIS time... ai_log("react_to_attack([M])",1) @@ -856,7 +850,7 @@ return 0 -/mob/living/simple_animal/proc/set_target(var/mob/M, forced = 0) +/mob/living/simple_mob/proc/set_target(var/mob/M, forced = 0) ai_log("SetTarget([M])",2) if(!M || (world.time - last_target_time < 5 SECONDS) && target_mob) ai_log("SetTarget() can't set it again so soon",3) @@ -882,7 +876,7 @@ return 0 // Set a follow target, with optional time for how long to follow them. -/mob/living/simple_animal/proc/set_follow(var/mob/M, var/follow_for = 0) +/mob/living/simple_mob/proc/set_follow(var/mob/M, var/follow_for = 0) ai_log("SetFollow([M]) for=[follow_for]",2) if(!M || (world.time - last_target_time < 4 SECONDS) && follow_mob) ai_log("SetFollow() can't set it again so soon",3) @@ -894,7 +888,7 @@ return 1 //Scan surroundings for a valid target -/mob/living/simple_animal/proc/FindTarget() +/mob/living/simple_mob/proc/FindTarget() var/atom/T = null for(var/atom/A in ListTargets(view_range)) @@ -943,21 +937,21 @@ return T //Used for special targeting or reactions -/mob/living/simple_animal/proc/Found(var/atom/A) +/mob/living/simple_mob/proc/Found(var/atom/A) return // Used for somewhat special targeting, but not to the extent of using Found() -/mob/living/simple_animal/proc/special_target_check(var/atom/A) +/mob/living/simple_mob/proc/special_target_check(var/atom/A) return TRUE //Requesting help from like-minded individuals -/mob/living/simple_animal/proc/RequestHelp() +/mob/living/simple_mob/proc/RequestHelp() if(!cooperative || ((world.time - last_helpask_time) < 10 SECONDS)) return ai_log("RequestHelp() to [faction_friends.len] friends",2) last_helpask_time = world.time - for(var/mob/living/simple_animal/F in faction_friends) + for(var/mob/living/simple_mob/F in faction_friends) if(F == src) continue if(get_dist(src,F) <= F.assist_distance) spawn(0) @@ -966,7 +960,7 @@ F.HelpRequested(src) //Someone wants help? -/mob/living/simple_animal/proc/HelpRequested(var/mob/living/simple_animal/F) +/mob/living/simple_mob/proc/HelpRequested(var/mob/living/simple_mob/F) if(target_mob || stat) ai_log("HelpRequested() by [F] but we're busy/dead",2) return @@ -985,11 +979,11 @@ // Can be used to conditionally do a ranged or melee attack. // Note that the SA must be able to do an attack at the specified range or else it may get trapped in a loop of switching // between STANCE_ATTACK and STANCE_ATTACKING, due to being told by MoveToTarget() that they're in range but being told by AttackTarget() that they're not. -/mob/living/simple_animal/proc/ClosestDistance() +/mob/living/simple_mob/proc/ClosestDistance() return ranged ? shoot_range - 1 : 1 // Shoot range -1 just because we don't want to constantly get kited //Move to a target (or near if we're ranged) -/mob/living/simple_animal/proc/MoveToTarget() +/mob/living/simple_mob/proc/MoveToTarget() if(incapacitated(INCAPACITATION_DISABLED)) ai_log("MoveToTarget() Bailing because we're disabled",2) return @@ -1064,7 +1058,7 @@ LoseTarget() //Just forget it. //Follow a target (and don't attempt to murder it horribly) -/mob/living/simple_animal/proc/FollowTarget() +/mob/living/simple_mob/proc/FollowTarget() ai_log("FollowTarget() [follow_mob]",1) stop_automated_movement = 1 //If we were chasing someone and we can't anymore, give up. @@ -1109,7 +1103,7 @@ LoseFollow() //Just try one time to go look at something. Don't really focus much on it. -/mob/living/simple_animal/proc/WanderTowards(var/turf/T) +/mob/living/simple_mob/proc/WanderTowards(var/turf/T) if(!T) return ai_log("WanderTowards() [T.x],[T.y]",1) @@ -1126,7 +1120,7 @@ WalkPath(target_thing = T, target_dist = 1) //A* now, try to a path to a target -/mob/living/simple_animal/proc/GetPath(var/turf/target,var/get_to = 1,var/max_distance = world.view*6) +/mob/living/simple_mob/proc/GetPath(var/turf/target,var/get_to = 1,var/max_distance = world.view*6) ai_log("GetPath([target],[get_to],[max_distance])",2) ForgetPath() var/list/new_path = AStar(get_turf(loc), target, astar_adjacent_proc, /turf/proc/Distance, min_target_dist = get_to, max_node_depth = max_distance, id = myid, exclude = obstacles) @@ -1142,7 +1136,7 @@ return walk_list.len //Walk along our A* path, target_thing allows us to stop early if we're nearby -/mob/living/simple_animal/proc/WalkPath(var/atom/target_thing, var/target_dist = 1, var/proc/steps_callback = null, var/every_steps = 4) +/mob/living/simple_mob/proc/WalkPath(var/atom/target_thing, var/target_dist = 1, var/proc/steps_callback = null, var/every_steps = 4) ai_log("WalkPath() (steps:[walk_list.len])",2) if(!walk_list || !walk_list.len) return @@ -1189,7 +1183,7 @@ sleep(move_to_delay) //Take one step along a path -/mob/living/simple_animal/proc/MoveOnce() +/mob/living/simple_mob/proc/MoveOnce() if(!walk_list.len) return @@ -1207,7 +1201,7 @@ return 1 //Forget the path entirely -/mob/living/simple_animal/proc/ForgetPath() +/mob/living/simple_mob/proc/ForgetPath() ai_log("ForgetPath()",2) if(path_display) for(var/turf/T in walk_list) @@ -1216,14 +1210,14 @@ walk_list.Cut() //Giving up on moving -/mob/living/simple_animal/proc/GiveUpMoving() +/mob/living/simple_mob/proc/GiveUpMoving() ai_log("GiveUpMoving()",1) ForgetPath() walk(src, 0) stop_automated_movement = 0 //Return home, all-in-one proc (though does target scan and drop out if they see one) -/mob/living/simple_animal/proc/GoHome() +/mob/living/simple_mob/proc/GoHome() if(!home_turf) return if(astarpathing) ForgetPath() ai_log("GoHome()",1) @@ -1237,7 +1231,7 @@ GiveUpMoving() //Go back to wandering //Get into attack mode on a target -/mob/living/simple_animal/proc/AttackTarget() +/mob/living/simple_mob/proc/AttackTarget() stop_automated_movement = 1 if(incapacitated(INCAPACITATION_DISABLED)) ai_log("AttackTarget() Bailing because we're disabled",2) @@ -1277,11 +1271,14 @@ return 0 //Attack the target in melee -/mob/living/simple_animal/proc/PunchTarget() +/mob/living/simple_mob/proc/PunchTarget() if(!Adjacent(target_mob)) return - if(!client) - sleep(rand(melee_attack_minDelay, melee_attack_maxDelay)) + if(!canClick()) + return + setClickCooldown(get_attack_speed()) +// if(!client) +// sleep(rand(melee_attack_minDelay, melee_attack_maxDelay)) if(isliving(target_mob)) var/mob/living/L = target_mob @@ -1299,7 +1296,7 @@ return M // This is the actual act of 'punching'. Override for special behaviour. -/mob/living/simple_animal/proc/DoPunch(var/atom/A) +/mob/living/simple_mob/proc/DoPunch(var/atom/A) if(!Adjacent(A) && !istype(A, /obj/structure/window) && !istype(A, /obj/machinery/door/window)) // They could've moved in the meantime. But a Window probably wouldn't have. This allows player simple-mobs to attack windows. return FALSE @@ -1321,14 +1318,19 @@ return TRUE //The actual top-level ranged attack proc -/mob/living/simple_animal/proc/ShootTarget() +/mob/living/simple_mob/proc/ShootTarget() + if(!canClick()) + return FALSE + + setClickCooldown(get_attack_speed()) + var/target = target_mob var/tturf = get_turf(target) if((firing_lines && !client) && !CheckFiringLine(tturf)) step_rand(src) face_atom(tturf) - return 0 + return FALSE visible_message("[src] fires at [target]!") if(rapid) @@ -1349,10 +1351,10 @@ if(casingtype) new casingtype - return 1 + return TRUE //Check firing lines for faction_friends (if we're not cooperative, we don't care) -/mob/living/simple_animal/proc/CheckFiringLine(var/turf/tturf) +/mob/living/simple_mob/proc/CheckFiringLine(var/turf/tturf) if(!tturf) return var/turf/list/crosses = list() @@ -1373,40 +1375,38 @@ return 1 //Special attacks, like grenades or blinding spit or whatever -/mob/living/simple_animal/proc/SpecialAtkTarget() +/mob/living/simple_mob/proc/SpecialAtkTarget() return 0 //Shoot a bullet at someone -/mob/living/simple_animal/proc/Shoot(var/target, var/start, var/user, var/bullet = 0) +/mob/living/simple_animal/proc/Shoot(atom/target, atom/start, mob/user, var/bullet = 0) if(target == start) return - var/obj/item/projectile/A = new projectiletype(user:loc) + var/obj/item/projectile/A = new projectiletype(user.loc) playsound(user, projectilesound, 100, 1) if(!A) return // if (!istype(target, /turf)) // qdel(A) // return - - A.firer = src - A.launch(target) - return + A.old_style_target(target) + A.fire() //We can't see the target -/mob/living/simple_animal/proc/LoseTarget() +/mob/living/simple_mob/proc/LoseTarget() ai_log("LoseTarget() [target_mob]",2) target_mob = null handle_stance(STANCE_IDLE) GiveUpMoving() //Target is no longer valid (?) -/mob/living/simple_animal/proc/LostTarget() +/mob/living/simple_mob/proc/LostTarget() handle_stance(STANCE_IDLE) GiveUpMoving() //Forget a follow mode -/mob/living/simple_animal/proc/LoseFollow() +/mob/living/simple_mob/proc/LoseFollow() ai_log("LoseFollow() [target_mob]",2) stop_automated_movement = 0 follow_mob = null @@ -1414,44 +1414,44 @@ GiveUpMoving() // Makes the simple mob stop everything. Useful for when it get stunned. -/mob/living/simple_animal/proc/Disable() +/mob/living/simple_mob/proc/Disable() ai_log("Disable() [target_mob]",2) spawn(0) LoseTarget() LoseFollow() -/mob/living/simple_animal/Stun(amount) +/mob/living/simple_mob/Stun(amount) if(amount > 0) Disable() ..(amount) -/mob/living/simple_animal/AdjustStunned(amount) +/mob/living/simple_mob/AdjustStunned(amount) if(amount > 0) Disable() ..(amount) -/mob/living/simple_animal/Weaken(amount) +/mob/living/simple_mob/Weaken(amount) if(amount > 0) Disable() ..(amount) -/mob/living/simple_animal/AdjustWeakened(amount) +/mob/living/simple_mob/AdjustWeakened(amount) if(amount > 0) Disable() ..(amount) -/mob/living/simple_animal/Paralyse(amount) +/mob/living/simple_mob/Paralyse(amount) if(amount > 0) Disable() ..(amount) -/mob/living/simple_animal/AdjustParalysis(amount) +/mob/living/simple_mob/AdjustParalysis(amount) if(amount > 0) Disable() ..(amount) //Find me some targets -/mob/living/simple_animal/proc/ListTargets(var/dist = view_range) +/mob/living/simple_mob/proc/ListTargets(var/dist = view_range) var/list/L = hearers(src, dist) for(var/obj/mecha/M in mechas_list) @@ -1461,7 +1461,7 @@ return L //Break through windows/other things -/mob/living/simple_animal/proc/DestroySurroundings(var/direction) +/mob/living/simple_mob/proc/DestroySurroundings(var/direction) if(!direction) direction = pick(cardinal) //FLAIL WILDLY @@ -1497,7 +1497,7 @@ return //Check for shuttle bumrush -/mob/living/simple_animal/proc/check_horde() +/mob/living/simple_mob/proc/check_horde() return 0 if(emergency_shuttle.shuttle.location) if(!enroute && !target_mob) //The shuttle docked, all monsters rush for the escape hallway @@ -1514,7 +1514,7 @@ stop_automated_movement = 0 //Shuttle bumrush -/mob/living/simple_animal/proc/horde() +/mob/living/simple_mob/proc/horde() var/turf/T = get_step_to(src, shuttletarget) for(var/atom/A in T) if(istype(A,/obj/machinery/door/airlock)) @@ -1536,7 +1536,7 @@ horde() //Touches a wire, etc -/mob/living/simple_animal/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0, var/def_zone = null) +/mob/living/simple_mob/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0, var/def_zone = null) shock_damage *= max(siemens_coeff - shock_resistance, 0) if (shock_damage < 1) return 0 @@ -1549,7 +1549,7 @@ s.start() //Shot with taser/stunvolver -/mob/living/simple_animal/stun_effect_act(var/stun_amount, var/agony_amount, var/def_zone, var/used_weapon=null) +/mob/living/simple_mob/stun_effect_act(var/stun_amount, var/agony_amount, var/def_zone, var/used_weapon=null) if(taser_kill) var/stunDam = 0 var/agonyDam = 0 @@ -1563,7 +1563,7 @@ agonyDam += agony_amount * 0.5 apply_damage(damage = agonyDam, damagetype = BURN, def_zone = null, blocked = armor, blocked = resistance, used_weapon = used_weapon, sharp = FALSE, edge = FALSE) -/mob/living/simple_animal/emp_act(severity) +/mob/living/simple_mob/emp_act(severity) if(!isSynthetic()) return switch(severity) @@ -1576,24 +1576,24 @@ if(4) adjustFireLoss(rand(1, 6)) -/mob/living/simple_animal/getarmor(def_zone, attack_flag) +/mob/living/simple_mob/getarmor(def_zone, attack_flag) var/armorval = armor[attack_flag] if(!armorval) return 0 else return armorval - +/* // Force it to target something -/mob/living/simple_animal/proc/taunt(var/mob/living/new_target, var/forced = FALSE) +/mob/living/simple_mob/proc/taunt(var/mob/living/new_target, var/forced = FALSE) if(intelligence_level == SA_HUMANOID && !forced) return set_target(new_target) - -/mob/living/simple_animal/is_sentient() +*/ +/mob/living/simple_mob/is_sentient() return intelligence_level != SA_PLANT && intelligence_level != SA_ROBOTIC // Hand procs for player-controlled SA's -/mob/living/simple_animal/swap_hand() +/mob/living/simple_mob/swap_hand() src.hand = !( src.hand ) if(hud_used.l_hand_hud_object && hud_used.r_hand_hud_object) if(hand) //This being 1 means the left hand is in use @@ -1604,17 +1604,17 @@ hud_used.r_hand_hud_object.icon_state = "r_hand_active" return /* -/mob/living/simple_animal/put_in_active_hand(var/obj/item/I) +/mob/living/simple_mob/put_in_active_hand(var/obj/item/I) if(!has_hands || !istype(I)) return */ //Puts the item into our active hand if possible. returns 1 on success. -/mob/living/simple_animal/put_in_active_hand(var/obj/item/W) +/mob/living/simple_mob/put_in_active_hand(var/obj/item/W) if(!has_hands) return FALSE return (hand ? put_in_l_hand(W) : put_in_r_hand(W)) -/mob/living/simple_animal/put_in_l_hand(var/obj/item/W) +/mob/living/simple_mob/put_in_l_hand(var/obj/item/W) if(!..() || l_hand) return 0 W.forceMove(src) @@ -1624,7 +1624,7 @@ update_inv_l_hand() return TRUE -/mob/living/simple_animal/put_in_r_hand(var/obj/item/W) +/mob/living/simple_mob/put_in_r_hand(var/obj/item/W) if(!..() || r_hand) return 0 W.forceMove(src) @@ -1634,7 +1634,7 @@ update_inv_r_hand() return TRUE -/mob/living/simple_animal/update_inv_r_hand() +/mob/living/simple_mob/update_inv_r_hand() if(QDESTROYING(src)) return @@ -1671,7 +1671,7 @@ update_icon() -/mob/living/simple_animal/update_inv_l_hand() +/mob/living/simple_mob/update_inv_l_hand() if(QDESTROYING(src)) return @@ -1709,14 +1709,14 @@ update_icon() //Can insert extra huds into the hud holder here. -/mob/living/simple_animal/proc/extra_huds(var/datum/hud/hud,var/icon/ui_style,var/list/hud_elements) +/mob/living/simple_mob/proc/extra_huds(var/datum/hud/hud,var/icon/ui_style,var/list/hud_elements) return //If they can or cannot use tools/machines/etc -/mob/living/simple_animal/IsAdvancedToolUser() +/mob/living/simple_mob/IsAdvancedToolUser() return has_hands -/mob/living/simple_animal/proc/IsHumanoidToolUser(var/atom/tool) +/mob/living/simple_mob/proc/IsHumanoidToolUser(var/atom/tool) if(!humanoid_hands) var/display_name = null if(tool) @@ -1726,7 +1726,7 @@ to_chat(src, "Your [hand_form] are not fit for use of \the [display_name].") return humanoid_hands -/mob/living/simple_animal/drop_from_inventory(var/obj/item/W, var/atom/target = null) +/mob/living/simple_mob/drop_from_inventory(var/obj/item/W, var/atom/target = null) . = ..(W, target) if(!target) target = src.loc @@ -1734,7 +1734,7 @@ W.forceMove(src.loc) //Commands, reactions, etc -/mob/living/simple_animal/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) +/mob/living/simple_mob/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(!ai_inactive && reacts && speaker && (message in reactions) && (!hostile || isliving(speaker)) && say_understands(speaker,language)) var/mob/living/L = speaker @@ -1744,16 +1744,16 @@ say(reactions[message]) //Just some subpaths for easy searching -/mob/living/simple_animal/hostile +/mob/living/simple_mob/hostile faction = "not yours" hostile = 1 retaliate = 1 stop_when_pulled = 0 destroy_surroundings = 1 -/mob/living/simple_animal/retaliate +/mob/living/simple_mob/retaliate retaliate = 1 destroy_surroundings = 1 -/mob/living/simple_animal/get_nametag_desc(mob/user) +/mob/living/simple_mob/get_nametag_desc(mob/user) return "[tt_desc]" diff --git a/code/modules/mob/living/simple_animal/simple_hud.dm b/code/modules/mob/living/simple_animal/simple_hud.dm index 5da7e8a696..fe851648b4 100644 --- a/code/modules/mob/living/simple_animal/simple_hud.dm +++ b/code/modules/mob/living/simple_animal/simple_hud.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/instantiate_hud(var/datum/hud/hud) +/mob/living/simple_mob/instantiate_hud(var/datum/hud/hud) if(!client) return //Why bother. diff --git a/code/modules/mob/living/simple_animal/slime/ai.dm b/code/modules/mob/living/simple_animal/slime/ai.dm deleted file mode 100644 index 3a8718c997..0000000000 --- a/code/modules/mob/living/simple_animal/slime/ai.dm +++ /dev/null @@ -1,91 +0,0 @@ -/mob/living/simple_animal/slime/FindTarget() - if(victim) // Don't worry about finding another target if we're eatting someone. - return - if(follow_mob && can_command(follow_mob)) // If following someone, don't attack until the leader says so, something hits you, or the leader is no longer worthy. - return - ..() - -/mob/living/simple_animal/slime/Found(mob/living/L) - if(isliving(L)) - if(SA_attackable(L)) - if(L.faction == faction && !attack_same) - if(ishuman(L)) - var/mob/living/carbon/human/H = L - if(istype(H.species, /datum/species/monkey)) // istype() is so they'll eat the alien monkeys too. - return H // Monkeys are always food. - else - return - - if(L in friends) - return - - if(istype(L, /mob/living/simple_animal/slime)) - var/mob/living/simple_animal/slime/buddy = L - if(buddy.slime_color == src.slime_color || discipline || unity || buddy.unity) - return // Don't hurt same colored slimes. - else - return buddy //do hurt others - - if(ishuman(L)) - var/mob/living/carbon/human/H = L - if(istype(H.species, /datum/species/monkey)) // istype() is so they'll eat the alien monkeys too. - return H // Monkeys are always food. - - if(issilicon(L) || isbot(L)) - if(discipline && !rabid) - return // We're a good slime. For now at least. - return - return - -/mob/living/simple_animal/slime/special_target_check(mob/living/L) - if(L.faction == faction && !attack_same && !istype(L, /mob/living/simple_animal/slime)) - if(ishuman(L)) - var/mob/living/carbon/human/H = L - if(istype(H.species, /datum/species/monkey)) // istype() is so they'll eat the alien monkeys too. - return TRUE // Monkeys are always food. - else - return FALSE - if(L in friends) - return FALSE - - if(istype(L, /mob/living/simple_animal/slime)) - var/mob/living/simple_animal/slime/buddy = L - if(buddy.slime_color == src.slime_color || discipline || unity || buddy.unity) - return FALSE // Don't hurt same colored slimes. - - if(ishuman(L)) - var/mob/living/carbon/human/H = L - if(H.species && H.species.name == "Promethean") - return FALSE // Prometheans are always our friends. - else if(istype(H.species, /datum/species/monkey)) // istype() is so they'll eat the alien monkeys too. - return TRUE // Monkeys are always food. - if(discipline && !rabid) - return FALSE // We're a good slime. For now at least - - if(issilicon(L) || isbot(L) ) - if(discipline && !rabid) - return FALSE // We're a good slime. For now at least. - return ..() // Other colors and nonslimes are jerks however. - -/mob/living/simple_animal/slime/ClosestDistance() - if(target_mob.stat == DEAD) - return 1 // Melee (eat) the target if dead, don't shoot it. - return ..() - -/mob/living/simple_animal/slime/HelpRequested(var/mob/living/simple_animal/slime/buddy) - if(istype(buddy)) - if(buddy.slime_color != src.slime_color && (!unity || !buddy.unity)) // We only help slimes of the same color, if it's another slime calling for help. - ai_log("HelpRequested() by [buddy] but they are a [buddy.slime_color] while we are a [src.slime_color].",2) - return - if(buddy.target_mob) - if(!special_target_check(buddy.target_mob)) - ai_log("HelpRequested() by [buddy] but special_target_check() failed when passed [buddy.target_mob].",2) - return - ..() - - -/mob/living/simple_animal/slime/handle_resist() - if(buckled && victim && isliving(buckled) && victim == buckled) // If it's buckled to a living thing it's probably eating it. - return - else - ..() diff --git a/code/modules/mob/living/simple_animal/slime/combat.dm b/code/modules/mob/living/simple_animal/slime/combat.dm deleted file mode 100644 index d13e81cd30..0000000000 --- a/code/modules/mob/living/simple_animal/slime/combat.dm +++ /dev/null @@ -1,277 +0,0 @@ - - -/* -// Check target_mob if worthy of attack -/mob/living/simple_animal/slime/SA_attackable(target_mob) - ai_log("SA_attackable([target_mob])",3) - if(isliving(target_mob)) - var/mob/living/L = target_mob - if(L.stat == DEAD) - if(can_consume(L)) // If we can eat them, then it doesn't matter if they're dead. - return TRUE - ..() -*/ - -/mob/living/simple_animal/slime/PunchTarget() - if(victim) - return // Already eatting someone. - if(!client) // AI controlled. - if( (!target_mob.lying && prob(60 + (power_charge * 4) ) || (!target_mob.lying && optimal_combat) )) // "Smart" slimes always stun first. - a_intent = I_DISARM // Stun them first. - else if(can_consume(target_mob) && target_mob.lying) - a_intent = I_GRAB // Then eat them. - else - a_intent = I_HURT // Otherwise robust them. - ai_log("PunchTarget() will [a_intent] [target_mob]",2) - ..() - -/mob/living/simple_animal/slime/proc/can_consume(var/mob/living/L) - if(!L || !istype(L)) - to_chat(src, "This subject is incomparable...") - return FALSE - if(L.isSynthetic()) - to_chat(src, "This subject is not biological...") - return FALSE - if(L.getarmor(null, "bio") >= 75) - to_chat(src, "I cannot reach this subject's biological matter...") - return FALSE - if(istype(L, /mob/living/simple_animal/slime)) - to_chat(src, "I cannot feed on other slimes...") - return FALSE - if(!Adjacent(L)) - to_chat(src, "This subject is too far away...") - return FALSE - if(istype(L, /mob/living/carbon) && L.getCloneLoss() >= L.getMaxHealth() * 1.5 || istype(L, /mob/living/simple_animal) && L.stat == DEAD) - to_chat(src, "This subject does not have an edible life energy...") - return FALSE - if(L.has_buckled_mobs()) - for(var/A in L.buckled_mobs) - if(istype(A, /mob/living/simple_animal/slime)) - if(A != src) - to_chat(src, "\The [A] is already feeding on this subject...") - return FALSE - return TRUE - -/mob/living/simple_animal/slime/proc/start_consuming(var/mob/living/L) - if(!can_consume(L)) - return - if(!Adjacent(L)) - return - step_towards(src, L) // Get on top of them to feed. - if(loc != L.loc) - return - if(L.buckle_mob(src, forced = TRUE)) - victim = L - update_icon() - victim.visible_message("\The [src] latches onto [victim]!", - "\The [src] latches onto you!") - -/mob/living/simple_animal/slime/proc/stop_consumption() - if(!victim) - return - victim.unbuckle_mob() - victim.visible_message("\The [src] slides off of [victim]!", - "\The [src] slides off of you!") - victim = null - update_icon() - - -/mob/living/simple_animal/slime/proc/handle_consumption() - if(victim && can_consume(victim) && !stat) - - var/armor_modifier = abs((victim.getarmor(null, "bio") / 100) - 1) - if(istype(victim, /mob/living/carbon)) - victim.adjustCloneLoss(rand(5,6) * armor_modifier) - victim.adjustToxLoss(rand(1,2) * armor_modifier) - if(victim.health <= 0) - victim.adjustToxLoss(rand(2,4) * armor_modifier) - - else if(istype(victim, /mob/living/simple_animal)) - victim.adjustBruteLoss(is_adult ? rand(7, 15) : rand(4, 12)) - - else - to_chat(src, "[pick("This subject is incompatable", \ - "This subject does not have a life energy", "This subject is empty", "I am not satisified", \ - "I can not feed from this subject", "I do not feel nourished", "This subject is not food")]...") - stop_consumption() - - adjust_nutrition(50 * armor_modifier) - - adjustOxyLoss(-10 * armor_modifier) //Heal yourself - adjustBruteLoss(-10 * armor_modifier) - adjustFireLoss(-10 * armor_modifier) - adjustCloneLoss(-10 * armor_modifier) - updatehealth() - if(victim) - victim.updatehealth() - else - stop_consumption() - -/mob/living/simple_animal/slime/DoPunch(var/mob/living/L) - if(!Adjacent(L)) // Might've moved away in the meantime. - return - - if(istype(L)) - - if(ishuman(L)) - var/mob/living/carbon/human/H = L - // Slime attacks can be blocked with shields. - if(H.check_shields(damage = 0, damage_source = null, attacker = src, def_zone = null, attack_text = "the attack")) - return - - switch(a_intent) - if(I_HELP) - ai_log("DoPunch() against [L], helping.",2) - L.visible_message("[src] gently pokes [L]!", - "[src] gently pokes you!") - do_attack_animation(L) - post_attack(L, a_intent) - - if(I_DISARM) - ai_log("DoPunch() against [L], disarming.",2) - var/stun_power = between(0, power_charge + rand(0, 3), 10) - - if(ishuman(L)) - var/mob/living/carbon/human/H = L - stun_power *= max(H.species.siemens_coefficient,0) - - - if(prob(stun_power * 10)) - power_charge = max(0, power_charge - 3) - L.visible_message("[src] has shocked [L]!", "[src] has shocked you!") - playsound(src, 'sound/weapons/Egloves.ogg', 75, 1) - L.Weaken(4) - L.Stun(4) - do_attack_animation(L) - if(L.buckled) - L.buckled.unbuckle_mob() // To prevent an exploit where being buckled prevents slimes from jumping on you. - L.stuttering = max(L.stuttering, stun_power) - - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(5, 1, L) - s.start() - - if(prob(stun_power * 10) && stun_power >= 8) - L.adjustFireLoss(power_charge * rand(1, 2)) - post_attack(L, a_intent) - - else if(prob(40)) - L.visible_message("[src] has pounced at [L]!", "[src] has pounced at you!") - playsound(src, 'sound/weapons/thudswoosh.ogg', 75, 1) - L.Weaken(2) - do_attack_animation(L) - if(L.buckled) - L.buckled.unbuckle_mob() // To prevent an exploit where being buckled prevents slimes from jumping on you. - post_attack(L, a_intent) - else - L.visible_message("[src] has tried to pounce at [L]!", "[src] has tried to pounce at you!") - playsound(src, 'sound/weapons/punchmiss.ogg', 75, 1) - do_attack_animation(L) - L.updatehealth() - return L - - if(I_GRAB) - ai_log("DoPunch() against [L], grabbing.",2) - start_consuming(L) - post_attack(L, a_intent) - - if(I_HURT) - ai_log("DoPunch() against [L], hurting.",2) - var/damage_to_do = rand(melee_damage_lower, melee_damage_upper) - var/armor_modifier = abs((L.getarmor(null, "bio") / 100) - 1) - - L.attack_generic(src, damage_to_do, pick(attacktext)) - playsound(src, 'sound/weapons/bite.ogg', 75, 1) - - // Give the slime some nutrition, if applicable. - if(!L.isSynthetic()) - if(ishuman(L)) - if(L.getCloneLoss() < L.getMaxHealth() * 1.5) - adjust_nutrition(damage_to_do * armor_modifier) - - else if(istype(L, /mob/living/simple_animal)) - if(!isslime(L)) - var/mob/living/simple_animal/SA = L - if(!SA.stat) - adjust_nutrition(damage_to_do) - - post_attack(L, a_intent) - - if(istype(L,/obj/mecha)) - var/obj/mecha/M = L - M.attack_generic(src, rand(melee_damage_lower, melee_damage_upper), pick(attacktext)) - -/mob/living/simple_animal/slime/proc/post_attack(var/mob/living/L, var/intent = I_HURT) - if(intent != I_HELP) - if(L.reagents && L.can_inject() && reagent_injected) - L.reagents.add_reagent(reagent_injected, injection_amount) - -/mob/living/simple_animal/slime/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/clothing/head)) // Handle hat simulator. - give_hat(W, user) - return - - // Otherwise they're probably fighting the slime. - if(prob(25)) - visible_message("\The [user]'s [W] passes right through [src]!") - user.setClickCooldown(user.get_attack_speed(W)) - return - ..() - -/mob/living/simple_animal/slime/hit_with_weapon(obj/item/O, mob/living/user, var/effective_force, var/hit_zone) - ..() - if(!stat) - if(O.force > 0 && discipline && !rabid) // wow, buddy, why am I getting attacked?? - adjust_discipline(1) - return - if(O.force >= 3) - if(victim || target_mob) // We've been a bad slime. - if(is_adult) - if(prob(5 + round(O.force / 2)) ) - if(prob(80) && !client) - adjust_discipline(2) - if(user) - step_away(src, user) - else - if(prob(10 + O.force * 2)) - if(prob(80) && !client) - adjust_discipline(2) - if(user) - step_away(src, user) - else - if(user in friends) // Friend attacking us for no reason. - if(prob(25)) - friends -= user - say("[user]... not friend...") - -/mob/living/simple_animal/slime/attack_hand(mob/living/carbon/human/M as mob) - if(victim) // Are we eating someone? - var/fail_odds = 30 - if(victim == M) // Harder to get the slime off if its eating you right now. - fail_odds = 60 - - if(prob(fail_odds)) - visible_message("[M] attempts to wrestle \the [name] off!") - playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) - - else - visible_message(" [M] manages to wrestle \the [name] off!") - playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - - if(prob(40) && !client) - adjust_discipline(1) - stop_consumption() - step_away(src,M) - else - if(M.a_intent == I_HELP) - if(hat) - remove_hat(M) - else - ..() - else - ..() - -// Shocked grilles don't hurt slimes, and in fact give them charge. -/mob/living/simple_animal/slime/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0, var/def_zone = null) - power_charge = between(0, power_charge + round(shock_damage / 10), 10) - to_chat(src, "\The [source] shocks you, and it charges you.") diff --git a/code/modules/mob/living/simple_animal/slime/death.dm b/code/modules/mob/living/simple_animal/slime/death.dm deleted file mode 100644 index 622b12a859..0000000000 --- a/code/modules/mob/living/simple_animal/slime/death.dm +++ /dev/null @@ -1,27 +0,0 @@ -/mob/living/simple_animal/slime/death(gibbed) - - if(stat == DEAD) - return - - if(!gibbed && is_adult) - var/death_type = type_on_death - if(!death_type) - death_type = src.type - var/mob/living/simple_animal/slime/S = make_new_slime(death_type) - S.rabid = TRUE - step_away(S, src) - is_adult = FALSE - maxHealth = initial(maxHealth) - revive() - if(!client) - rabid = TRUE - number = rand(1, 1000) - update_name() - return - - stop_consumption() - . = ..(gibbed, "stops moving and partially dissolves...") - - update_icon() - - return \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/slime/life.dm b/code/modules/mob/living/simple_animal/slime/life.dm deleted file mode 100644 index 691b880574..0000000000 --- a/code/modules/mob/living/simple_animal/slime/life.dm +++ /dev/null @@ -1,183 +0,0 @@ -/mob/living/simple_animal/slime/proc/adjust_nutrition(input) - nutrition = between(0, nutrition + input, get_max_nutrition()) - - if(input > 0) - if(prob(input * 2)) // Gain around one level per 50 nutrition - power_charge = min(power_charge++, 10) - if(power_charge == 10) - adjustToxLoss(-10) - - -/mob/living/simple_animal/slime/proc/get_max_nutrition() // Can't go above it - if(is_adult) - return 1200 - return 1000 - -/mob/living/simple_animal/slime/proc/get_grow_nutrition() // Above it we grow, below it we can eat - if(is_adult) - return 1000 - return 800 - -/mob/living/simple_animal/slime/proc/get_hunger_nutrition() // Below it we will always eat - if(is_adult) - return 600 - return 500 - -/mob/living/simple_animal/slime/proc/get_starve_nutrition() // Below it we will eat before everything else - if(is_adult) - return 300 - return 200 - -/mob/living/simple_animal/slime/proc/handle_nutrition() - if(docile) - return - if(prob(15)) - adjust_nutrition(-1 - is_adult) - - if(nutrition <= get_starve_nutrition()) - handle_starvation() - - else if(nutrition >= get_grow_nutrition() && amount_grown < 10) - adjust_nutrition(-20) - amount_grown = between(0, amount_grown + 1, 10) - -/mob/living/simple_animal/slime/proc/handle_starvation() - if(nutrition < get_starve_nutrition() && !client) // if a slime is starving, it starts losing its friends - if(friends.len && prob(1)) - var/mob/nofriend = pick(friends) - if(nofriend) - friends -= nofriend - say("[nofriend]... food now...") - - if(nutrition <= 0) - adjustToxLoss(rand(1,3)) - if(client && prob(5)) - to_chat(src, "You are starving!") - -/mob/living/simple_animal/slime/proc/handle_discipline() - if(discipline > 0) - update_mood() - // if(discipline >= 5 && rabid) - // if(prob(60)) - // rabid = 0 - // adjust_discipline(1) // So it stops trying to murder everyone. - - // Handle discipline decay. - if(!prob(75 + (obedience * 5))) - adjust_discipline(-1) - if(!discipline) - update_mood() - -/mob/living/simple_animal/slime/handle_regular_status_updates() - if(stat != DEAD) - handle_nutrition() - - handle_discipline() - - if(prob(30)) - adjustOxyLoss(-1) - adjustToxLoss(-1) - adjustFireLoss(-1) - adjustCloneLoss(-1) - adjustBruteLoss(-1) - - if(victim) - handle_consumption() - - if(amount_grown >= 10 && !target_mob && !client) - if(is_adult) - reproduce() - else - evolve() - - handle_stuttering() - - ..() - - -// This is to make slime responses feel a bit more natural and not instant. -/mob/living/simple_animal/slime/proc/delayed_say(var/message, var/mob/target) - spawn(rand(1 SECOND, 2 SECONDS)) - if(target) - face_atom(target) - say(message) - -//Commands, reactions, etc -/mob/living/simple_animal/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((findtext(message, num2text(number)) || findtext(message, name) || findtext(message, "slimes"))) // Talking to us - - // First make sure it's not just another slime repeating things. - if(istype(speaker, /mob/living/simple_animal/slime)) - if(!speaker.client) - return - - //Are all slimes being referred to? - var/mass_order = 0 - if(findtext(message, "slimes")) - mass_order = 1 - - // Say hello back. - if(findtext(message, "hello") || findtext(message, "hi") || findtext(message, "greetings")) - delayed_say(pick("Hello...", "Hi..."), speaker) - - // Follow request. - if(findtext(message, "follow") || findtext(message, "come with me")) - if(!can_command(speaker)) - delayed_say(pick("No...", "I won't follow..."), speaker) - return - - delayed_say("Yes... I follow \the [speaker]...", speaker) - set_follow(speaker) - FollowTarget() - - // Stop request. - if(findtext(message, "stop") || findtext(message, "halt") || findtext(message, "cease")) - if(victim) // We're being asked to stop eatting someone. - if(!can_command(speaker)) - delayed_say("No...", speaker) - return - else - delayed_say("Fine...", speaker) - stop_consumption() - adjust_discipline(1, TRUE) - - if(target_mob) // We're being asked to stop chasing someone. - if(!can_command(speaker)) - delayed_say("No...", speaker) - return - else - delayed_say("Fine...", speaker) - LoseTarget() - adjust_discipline(1, TRUE) - - if(follow_mob) // We're being asked to stop following someone. - if(can_command(speaker) == SLIME_COMMAND_FRIEND || follow_mob == speaker) - delayed_say("Yes... I'll stop...", speaker) - LoseFollow() - else - delayed_say("No... I'll keep following \the [follow_mob]...", speaker) - - // Murder request - if(findtext(message, "harm") || findtext(message, "kill") || findtext(message, "murder") || findtext(message, "eat") || findtext(message, "consume")) - if(can_command(speaker) < SLIME_COMMAND_FACTION) - delayed_say("No...", speaker) - return - - for(var/mob/living/L in view(7, src) - list(src, speaker)) - if(L == src) - continue // Don't target ourselves. - var/list/valid_names = splittext(L.name, " ") // Should output list("John", "Doe") as an example. - for(var/line in valid_names) // Check each part of someone's name. - if(findtext(message, lowertext(line))) // If part of someone's name is in the command, the slime targets them if allowed to. - if(!(mass_order && line == "slime")) //don't think random other slimes are target - if(special_target_check(L)) - delayed_say("Okay... I attack \the [L]...", speaker) - LoseFollow() - set_target(L, 1) - return - else - delayed_say("No... I won't attack \the [L].", speaker) - return - // If we're here, it couldn't find anyone with that name. - delayed_say("No... I don't know who to attack...", speaker) diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm deleted file mode 100644 index 843990c7f6..0000000000 --- a/code/modules/mob/living/simple_animal/slime/slime.dm +++ /dev/null @@ -1,470 +0,0 @@ -/mob/living/simple_animal/slime - name = "slime" - desc = "The most basic of slimes. The grey slime has no remarkable qualities, however it remains one of the most useful colors for scientists." - tt_desc = "A Macrolimbus vulgaris" - icon = 'icons/mob/slime2.dmi' - icon_state = "grey baby slime" - intelligence_level = SA_ANIMAL - pass_flags = PASSTABLE - var/shiny = FALSE // If true, will add a 'shiny' overlay. - var/glows = FALSE // If true, will glow in the same color as the color var. - var/icon_state_override = null // Used for special slime appearances like the rainbow slime. - pass_flags = PASSTABLE - - makes_dirt = FALSE // Goop - - speak_emote = list("chirps") - - maxHealth = 150 - var/maxHealth_adult = 200 - melee_damage_lower = 5 - melee_damage_upper = 25 - melee_miss_chance = 0 - gender = NEUTER - - // Atmos stuff. - minbodytemp = T0C-30 - heat_damage_per_tick = 0 - cold_damage_per_tick = 40 - - min_oxy = 0 - max_oxy = 0 - min_tox = 0 - max_tox = 0 - min_co2 = 0 - max_co2 = 0 - min_n2 = 0 - max_n2 = 0 - unsuitable_atoms_damage = 0 - - response_help = "pets" - - speak = list( - "Blorp...", - "Blop..." - - ) - emote_hear = list( - - ) - emote_see = list( - "bounces", - "jiggles", - "sways" - ) - - hostile = 1 - retaliate = 1 - attack_same = 1 - cooperative = 1 - faction = "slime" // Slimes will help other slimes, provided they share the same color. - - color = "#CACACA" - var/is_adult = FALSE - var/cores = 1 // How many cores you get when placed in a Processor. - var/power_charge = 0 // 0-10 controls how much electricity they are generating. High numbers encourage the slime to stun someone with electricity. - var/amount_grown = 0 // controls how long the slime has been overfed, if 10, grows or reproduces - var/number = 0 // This is used to make the slime semi-unique for indentification. - - var/mob/living/victim = null // the person the slime is currently feeding on - var/rabid = FALSE // If true, will attack anyone and everyone. - var/docile = FALSE // Basically the opposite of above. If true, will never harm anything and won't get hungry. - var/discipline = 0 // Beating slimes makes them less likely to lash out. In theory. - var/resentment = 0 // 'Unjustified' beatings make this go up, and makes it more likely for abused slimes to go berserk. - var/obedience = 0 // Conversely, 'justified' beatings make this go up, and makes discipline decay slowly, potentially making it not decay at all. - var/unity = FALSE // If true, slimes will consider other colors as their own. Other slimes will see this slime as the same color as well. A rainbow slime is required to get this. - var/optimal_combat = FALSE // Used to dumb down the combat AI somewhat. If true, the slime tends to be really dangerous to fight alone due to stunlocking. - var/mood = ":3" // Icon to use to display 'mood'. - var/obj/item/clothing/head/hat = null // The hat the slime may be wearing. - - var/slime_color = "grey" - var/mutation_chance = 25 // Odds of spawning as a new color when reproducing. Can be modified by certain xenobio products. Carried across generations of slimes. - var/coretype = /obj/item/slime_extract/grey - // List of potential slime color mutations. This must have exactly four types. - var/list/slime_mutation = list( - /mob/living/simple_animal/slime/orange, - /mob/living/simple_animal/slime/metal, - /mob/living/simple_animal/slime/blue, - /mob/living/simple_animal/slime/purple - ) - var/type_on_death = null // Set this if you want dying slimes to split into a specific type and not their type. - var/rainbow_core_candidate = TRUE // If false, rainbow cores cannot make this type randomly. - - var/reagent_injected = null // Some slimes inject reagents on attack. This tells the game what reagent to use. - var/injection_amount = 5 // This determines how much. - - - can_enter_vent_with = list( - /obj/item/clothing/head, - ) - -/mob/living/simple_animal/slime/New(var/location, var/start_as_adult = FALSE) - verbs += /mob/living/proc/ventcrawl - if(start_as_adult) - make_adult() - health = maxHealth -// slime_mutation = mutation_table(slime_color) - update_icon() - number = rand(1, 1000) - update_name() - ..(location) - -/mob/living/simple_animal/slime/Destroy() - if(hat) - drop_hat() - return ..() - -/mob/living/simple_animal/slime/proc/make_adult() - if(is_adult) - return - - is_adult = TRUE - melee_damage_lower = 20 - melee_damage_upper = 40 - maxHealth = maxHealth_adult - amount_grown = 0 - update_icon() - update_name() - -/mob/living/simple_animal/slime/proc/update_name() - if(docile) // Docile slimes are generally named, so we shouldn't mess with it. - return - name = "[slime_color] [is_adult ? "adult" : "baby"] [initial(name)] ([number])" - real_name = name - -/mob/living/simple_animal/slime/update_icon() - if(stat == DEAD) - icon_state = "[icon_state_override ? "[icon_state_override] slime" : "slime"] [is_adult ? "adult" : "baby"] dead" - set_light(0) - else - if(incapacitated(INCAPACITATION_DISABLED)) - icon_state = "[icon_state_override ? "[icon_state_override] slime" : "slime"] [is_adult ? "adult" : "baby"] dead" - else - icon_state = "[icon_state_override ? "[icon_state_override] slime" : "slime"] [is_adult ? "adult" : "baby"][victim ? " eating":""]" - - overlays.Cut() - if(stat != DEAD) - var/image/I = image(icon, src, "slime light") - I.appearance_flags = RESET_COLOR - overlays += I - - if(shiny) - I = image(icon, src, "slime shiny") - I.appearance_flags = RESET_COLOR - overlays += I - - I = image(icon, src, "aslime-[mood]") - I.appearance_flags = RESET_COLOR - overlays += I - - if(glows) - set_light(3, 2, color) - - if(hat) - var/hat_state = hat.item_state ? hat.item_state : hat.icon_state - var/image/I = image('icons/mob/head.dmi', src, hat_state) - I.pixel_y = -7 // Slimes are small. - I.appearance_flags = RESET_COLOR - overlays += I - - if(modifier_overlay) // Restore our modifier overlay. - overlays += modifier_overlay - -/mob/living/simple_animal/slime/proc/update_mood() - var/old_mood = mood - if(incapacitated(INCAPACITATION_DISABLED)) - mood = "sad" - else if(rabid) - mood = "angry" - else if(target_mob) - mood = "mischevous" - else if(discipline) - mood = "pout" - else if(docile) - mood = ":33" - else - mood = ":3" - if(old_mood != mood) - update_icon() - -// Makes the slime very angry and dangerous. -/mob/living/simple_animal/slime/proc/enrage() - if(docile) - return - rabid = TRUE - update_mood() - visible_message("\The [src] enrages!") - -// Makes the slime safe and harmless. -/mob/living/simple_animal/slime/proc/pacify() - rabid = FALSE - docile = TRUE - hostile = FALSE - retaliate = FALSE - cooperative = FALSE - - // If for whatever reason the mob AI decides to try to attack something anyways. - melee_damage_upper = 0 - melee_damage_lower = 0 - - update_mood() - -/mob/living/simple_animal/slime/proc/unify() - unity = TRUE - attack_same = FALSE - -/mob/living/simple_animal/slime/examine(mob/user) - ..() - if(hat) - to_chat(user, "It is wearing \a [hat].") - - if(stat == DEAD) - to_chat(user, "It appears to be dead.") - else if(incapacitated(INCAPACITATION_DISABLED)) - to_chat(user, "It appears to be incapacitated.") - else if(rabid) - to_chat(user, "It seems very, very angry and upset.") - else if(obedience >= 5) - to_chat(user, "It looks rather obedient.") - else if(discipline) - to_chat(user, "It has been subjugated by force, at least for now.") - else if(docile) - to_chat(user, "It appears to have been pacified.") - -/mob/living/simple_animal/slime/water_act(amount) // This is called if a slime enters a water tile. - adjustBruteLoss(40 * amount) - -/mob/living/simple_animal/slime/proc/adjust_discipline(amount, silent) - if(amount > 0) - if(!rabid) - var/justified = is_justified_to_discipline() - spawn(0) - stop_consumption() - LoseTarget() - if(!silent) - if(justified) - say(pick("Fine...", "Okay...", "Sorry...", "I yield...", "Mercy...")) - else - say(pick("Why...?", "I don't understand...?", "Cruel...", "Stop...", "Nooo...")) - if(justified) - obedience++ - else - if(prob(resentment * 20)) - enrage() // Pushed the slime too far. - say(pick("Evil...", "Kill...", "Tyrant...")) - resentment++ // Done after check so first time will never enrage. - - discipline = between(0, discipline + amount, 10) - -/mob/living/simple_animal/slime/movement_delay() - if(bodytemperature >= 330.23) // 135 F or 57.08 C - return -1 // slimes become supercharged at high temperatures - - . = ..() - - var/health_deficiency = (maxHealth - health) - if(health_deficiency >= 45) - . += (health_deficiency / 25) - - if(bodytemperature < 183.222) - . += (283.222 - bodytemperature) / 10 * 1.75 - - . += config.slime_delay - -/mob/living/simple_animal/slime/Process_Spacemove() - return 2 - -/mob/living/simple_animal/slime/verb/evolve() - set category = "Slime" - set desc = "This will let you evolve from baby to adult slime." - - if(stat) - to_chat(src, "I must be conscious to do this...") - return - - if(docile) - to_chat(src, "I have been pacified. I cannot evolve...") - return - - if(!is_adult) - if(amount_grown >= 10) - make_adult() - else - to_chat(src, "I am not ready to evolve yet...") - else - to_chat(src, "I have already evolved...") - -/mob/living/simple_animal/slime/verb/reproduce() - set category = "Slime" - set desc = "This will make you split into four Slimes." - - if(stat) - to_chat(src, "I must be conscious to do this...") - return - - if(docile) - to_chat(src, "I have been pacified. I cannot reproduce...") - return - - if(is_adult) - if(amount_grown >= 10) - // Check if there's enough 'room' to split. - var/list/nearby_things = orange(1, src) - var/free_tiles = 0 - for(var/turf/T in nearby_things) - var/free = TRUE - if(T.density) // No walls. - continue - for(var/atom/movable/AM in T) - if(AM.density) - free = FALSE - break - - if(free) - free_tiles++ - - if(free_tiles < 3) // Three free tiles are needed, as four slimes are made and the 4th tile is from the center tile that the current slime occupies. - to_chat(src, "It is too cramped here to reproduce...") - return - - var/list/babies = list() - for(var/i = 1 to 4) - babies.Add(make_new_slime()) - - var/mob/living/simple_animal/slime/new_slime = pick(babies) - new_slime.universal_speak = universal_speak - if(src.mind) - src.mind.transfer_to(new_slime) - else - new_slime.key = src.key - qdel(src) - else - to_chat(src, "I am not ready to reproduce yet...") - else - to_chat(src, "I am not old enough to reproduce yet...") - -// Used for reproducing and dying. -/mob/living/simple_animal/slime/proc/make_new_slime(var/desired_type) - var/t = src.type - if(desired_type) - t = desired_type - if(prob(mutation_chance / 10)) - t = /mob/living/simple_animal/slime/rainbow - - else if(prob(mutation_chance) && slime_mutation.len) - t = slime_mutation[rand(1, slime_mutation.len)] - var/mob/living/simple_animal/slime/baby = new t(loc) - - // Handle 'inheriting' from parent slime. - baby.mutation_chance = mutation_chance - baby.power_charge = round(power_charge / 4) - baby.resentment = max(resentment - 1, 0) - if(!istype(baby, /mob/living/simple_animal/slime/light_pink)) - baby.discipline = max(discipline - 1, 0) - baby.obedience = max(obedience - 1, 0) - if(!istype(baby, /mob/living/simple_animal/slime/rainbow)) - baby.unity = unity - baby.faction = faction - baby.attack_same = attack_same - baby.friends = friends.Copy() - if(rabid) - baby.enrage() - - step_away(baby, src) - return baby - -/mob/living/simple_animal/slime/speech_bubble_appearance() - return "slime" - -// Called after they finish eatting someone. -/mob/living/simple_animal/slime/proc/befriend(var/mob/living/friend) - if(!(friend in friends)) - friends |= friend - say("[friend]... friend...") - -/mob/living/simple_animal/slime/proc/can_command(var/mob/living/commander) - if(rabid) - return FALSE - if(docile) - return SLIME_COMMAND_OBEY - if(commander in friends) - return SLIME_COMMAND_FRIEND - if(faction == commander.faction) - return SLIME_COMMAND_FACTION - if(discipline > resentment && obedience >= 5) - return SLIME_COMMAND_OBEY - return FALSE - -/mob/living/simple_animal/slime/proc/give_hat(var/obj/item/clothing/head/new_hat, var/mob/living/user) - if(!istype(new_hat)) - to_chat(user, "\The [new_hat] isn't a hat.") - return - if(hat) - to_chat(user, "\The [src] is already wearing \a [hat].") - return - else - user.drop_item(new_hat) - hat = new_hat - new_hat.forceMove(src) - to_chat(user, "You place \a [new_hat] on \the [src]. How adorable!") - update_icon() - return - -/mob/living/simple_animal/slime/proc/remove_hat(var/mob/living/user) - if(!hat) - to_chat(user, "\The [src] doesn't have a hat to remove.") - else - hat.forceMove(get_turf(src)) - user.put_in_hands(hat) - to_chat(user, "You take away \the [src]'s [hat.name]. How mean.") - hat = null - update_icon() - -/mob/living/simple_animal/slime/proc/drop_hat() - if(!hat) - return - hat.forceMove(get_turf(src)) - hat = null - update_icon() - -// Checks if disciplining the slime would be 'justified' right now. -/mob/living/simple_animal/slime/proc/is_justified_to_discipline() - if(rabid) - return TRUE - if(target_mob) - if(ishuman(target_mob)) - var/mob/living/carbon/human/H = target_mob - if(istype(H.species, /datum/species/monkey)) - return FALSE - return TRUE - return FALSE - - -/mob/living/simple_animal/slime/get_description_interaction() - var/list/results = list() - - if(!stat) - results += "[desc_panel_image("slimebaton")]to stun the slime, if it's being bad." - - results += ..() - - return results - -/mob/living/simple_animal/slime/get_description_info() - var/list/lines = list() - var/intro_line = "Slimes are generally the test subjects of Xenobiology, with different colors having different properties. \ - They can be extremely dangerous if not handled properly." - lines.Add(intro_line) - lines.Add(null) // To pad the line breaks. - - var/list/rewards = list() - for(var/potential_color in slime_mutation) - var/mob/living/simple_animal/slime/S = potential_color - rewards.Add(initial(S.slime_color)) - var/reward_line = "This color of slime can mutate into [english_list(rewards)] colors, when it reproduces. It will do so when it has eatten enough." - lines.Add(reward_line) - lines.Add(null) - - lines.Add(description_info) - return lines.Join("\n") - diff --git a/code/modules/mob/living/simple_animal/slime/subtypes.dm b/code/modules/mob/living/simple_animal/slime/subtypes.dm deleted file mode 100644 index d30bdf0d7d..0000000000 --- a/code/modules/mob/living/simple_animal/slime/subtypes.dm +++ /dev/null @@ -1,747 +0,0 @@ -// Tier 1 - -/mob/living/simple_animal/slime/purple - desc = "This slime is rather toxic to handle, as it is poisonous." - color = "#CC23FF" - slime_color = "purple" - coretype = /obj/item/slime_extract/purple - reagent_injected = "toxin" - - description_info = "This slime spreads a toxin when it attacks. A biosuit or other thick armor can protect from the toxic attack." - - slime_mutation = list( - /mob/living/simple_animal/slime/dark_purple, - /mob/living/simple_animal/slime/dark_blue, - /mob/living/simple_animal/slime/green, - /mob/living/simple_animal/slime - ) - - -/mob/living/simple_animal/slime/orange - desc = "This slime is known to be flammable and can ignite enemies." - color = "#FFA723" - slime_color = "orange" - coretype = /obj/item/slime_extract/orange - - description_info = "Attacks from this slime can ignite you. A firesuit can protect from the burning attacks of this slime." - - slime_mutation = list( - /mob/living/simple_animal/slime/dark_purple, - /mob/living/simple_animal/slime/yellow, - /mob/living/simple_animal/slime/red, - /mob/living/simple_animal/slime - ) - -/mob/living/simple_animal/slime/orange/post_attack(mob/living/L, intent) - if(intent != I_HELP) - L.adjust_fire_stacks(1) - if(prob(25)) - L.IgniteMob() - ..() - -/mob/living/simple_animal/slime/blue - desc = "This slime produces 'cryotoxin' and uses it against their foes. Very deadly to other slimes." - color = "#19FFFF" - slime_color = "blue" - coretype = /obj/item/slime_extract/blue - reagent_injected = "cryotoxin" - - description_info = "Attacks from this slime can chill you. A biosuit or other thick armor can protect from the chilling attack." - - slime_mutation = list( - /mob/living/simple_animal/slime/dark_blue, - /mob/living/simple_animal/slime/silver, - /mob/living/simple_animal/slime/pink, - /mob/living/simple_animal/slime - ) - - -/mob/living/simple_animal/slime/metal - desc = "This slime is a lot more resilient than the others, due to having a metamorphic metallic and sloped surface." - color = "#5F5F5F" - slime_color = "metal" - shiny = 1 - coretype = /obj/item/slime_extract/metal - - description_info = "This slime is a lot more durable and tough to damage than the others." - - resistance = 10 // Sloped armor is strong. - maxHealth = 250 - maxHealth_adult = 350 - - slime_mutation = list( - /mob/living/simple_animal/slime/silver, - /mob/living/simple_animal/slime/yellow, - /mob/living/simple_animal/slime/gold, - /mob/living/simple_animal/slime - ) - -// Tier 2 - -/mob/living/simple_animal/slime/yellow - desc = "This slime is very conductive, and is known to use electricity as a means of defense moreso than usual for slimes." - color = "#FFF423" - slime_color = "yellow" - coretype = /obj/item/slime_extract/yellow - - ranged = 1 - shoot_range = 3 - firing_lines = 1 - projectiletype = /obj/item/projectile/beam/lightning/slime - projectilesound = 'sound/weapons/gauss_shoot.ogg' // Closest thing to a 'thunderstrike' sound we have. - glows = TRUE - - description_info = "This slime will fire lightning attacks at enemies if they are at range, and generate electricity \ - for their stun attack faster than usual. Insulative or reflective armor can protect from the lightning." - - slime_mutation = list( - /mob/living/simple_animal/slime/bluespace, - /mob/living/simple_animal/slime/bluespace, - /mob/living/simple_animal/slime/metal, - /mob/living/simple_animal/slime/orange - ) - -/mob/living/simple_animal/slime/yellow/handle_regular_status_updates() - if(stat == CONSCIOUS) - if(prob(25)) - power_charge = between(0, power_charge + 1, 10) - ..() - -/obj/item/projectile/beam/lightning/slime - power = 15 - -/mob/living/simple_animal/slime/yellow/ClosestDistance() // Needed or else they won't eat monkeys outside of melee range. - if(target_mob && ishuman(target_mob)) - var/mob/living/carbon/human/H = target_mob - if(istype(H.species, /datum/species/monkey)) - return 1 - return ..() - - -/mob/living/simple_animal/slime/dark_purple - desc = "This slime produces ever-coveted phoron. Risky to handle but very much worth it." - color = "#660088" - slime_color = "dark purple" - coretype = /obj/item/slime_extract/dark_purple - reagent_injected = "phoron" - - description_info = "This slime applies phoron to enemies it attacks. A biosuit or other thick armor can protect from the toxic attack. \ - If hit with a burning attack, it will erupt in flames." - - slime_mutation = list( - /mob/living/simple_animal/slime/purple, - /mob/living/simple_animal/slime/orange, - /mob/living/simple_animal/slime/ruby, - /mob/living/simple_animal/slime/ruby - ) - -/mob/living/simple_animal/slime/dark_purple/proc/ignite() - visible_message("\The [src] erupts in an inferno!") - for(var/turf/simulated/target_turf in view(2, src)) - target_turf.assume_gas("phoron", 30, 1500+T0C) - spawn(0) - target_turf.hotspot_expose(1500+T0C, 400) - qdel(src) - -/mob/living/simple_animal/slime/dark_purple/ex_act(severity) - log_and_message_admins("[src] ignited due to a chain reaction with an explosion.") - ignite() - -/mob/living/simple_animal/slime/dark_purple/fire_act(datum/gas_mixture/air, temperature, volume) - log_and_message_admins("[src] ignited due to exposure to fire.") - ignite() - -/mob/living/simple_animal/slime/dark_purple/bullet_act(var/obj/item/projectile/P, var/def_zone) - if(P.damage_type && P.damage_type == BURN && P.damage) // Most bullets won't trigger the explosion, as a mercy towards Security. - log_and_message_admins("[src] ignited due to bring hit by a burning projectile[P.firer ? " by [key_name(P.firer)]" : ""].") - ignite() - else - ..() - -/mob/living/simple_animal/slime/dark_purple/attackby(var/obj/item/weapon/W, var/mob/user) - if(istype(W) && W.force && W.damtype == BURN) - log_and_message_admins("[src] ignited due to being hit with a burning weapon ([W]) by [key_name(user)].") - ignite() - else - ..() - - - - -/mob/living/simple_animal/slime/dark_blue - desc = "This slime makes other entities near it feel much colder, and is more resilient to the cold. It tends to kill other slimes rather quickly." - color = "#2398FF" - glows = TRUE - slime_color = "dark blue" - coretype = /obj/item/slime_extract/dark_blue - - description_info = "This slime is immune to the cold, however water will still kill it. A winter coat or other cold-resistant clothing can protect from the chilling aura." - - slime_mutation = list( - /mob/living/simple_animal/slime/purple, - /mob/living/simple_animal/slime/blue, - /mob/living/simple_animal/slime/cerulean, - /mob/living/simple_animal/slime/cerulean - ) - - minbodytemp = 0 - cold_damage_per_tick = 0 - -/mob/living/simple_animal/slime/dark_blue/Life() - if(stat != DEAD) - cold_aura() - ..() - -/mob/living/simple_animal/slime/dark_blue/proc/cold_aura() - for(var/mob/living/L in view(2, src)) - var/protection = L.get_cold_protection() - - if(protection < 1) - var/cold_factor = abs(protection - 1) - var/delta = -20 - delta *= cold_factor - L.bodytemperature = max(50, L.bodytemperature + delta) - var/turf/T = get_turf(src) - var/datum/gas_mixture/env = T.return_air() - if(env) - env.add_thermal_energy(-10 * 1000) - -/mob/living/simple_animal/slime/dark_blue/get_cold_protection() - return 1 // This slime is immune to cold. - -// Surface variant -/mob/living/simple_animal/slime/dark_blue/feral - name = "feral slime" - desc = "The result of slimes escaping containment from some xenobiology lab. The slime makes other entities near it feel much colder, \ - and it is more resilient to the cold. These qualities have made this color of slime able to thrive on a harsh, cold world and is able to rival \ - the ferocity of other apex predators in this region of Sif. As such, it is a very invasive species." - description_info = "This slime makes other entities near it feel much colder, and is more resilient to the cold. It also has learned advanced combat tactics from \ - having to endure the harsh world outside its lab. Note that processing this large slime will give six cores." - icon_scale = 2 - optimal_combat = TRUE // Gotta be sharp to survive out there. - rabid = TRUE - rainbow_core_candidate = FALSE - cores = 6 - maxHealth = 150 - maxHealth_adult = 250 - type_on_death = /mob/living/simple_animal/slime/dark_blue // Otherwise infinite slimes might occur. - pixel_y = -10 // Since the base sprite isn't centered properly, the pixel auto-adjustment needs some help. - -/mob/living/simple_animal/slime/dark_blue/feral/New() - ..() - make_adult() - -/mob/living/simple_animal/slime/silver - desc = "This slime is shiny, and can deflect lasers or other energy weapons directed at it." - color = "#AAAAAA" - slime_color = "silver" - coretype = /obj/item/slime_extract/silver - shiny = TRUE - - description_info = "Tasers, including the slime version, are ineffective against this slime. The slimebation still works." - - slime_mutation = list( - /mob/living/simple_animal/slime/metal, - /mob/living/simple_animal/slime/blue, - /mob/living/simple_animal/slime/amber, - /mob/living/simple_animal/slime/amber - ) - -/mob/living/simple_animal/slime/silver/bullet_act(var/obj/item/projectile/P, var/def_zone) - if(istype(P,/obj/item/projectile/beam) || istype(P, /obj/item/projectile/energy)) - visible_message("\The [src] reflects \the [P]!") - - // Find a turf near or on the original location to bounce to - var/new_x = P.starting.x + pick(0, 0, 0, -1, 1, -2, 2) - var/new_y = P.starting.y + pick(0, 0, 0, -1, 1, -2, 2) - var/turf/curloc = get_turf(src) - - // redirect the projectile - P.redirect(new_x, new_y, curloc, src) - return PROJECTILE_CONTINUE // complete projectile permutation - else - ..() - - -// Tier 3 - -/mob/living/simple_animal/slime/bluespace - desc = "Trapping this slime in a cell is generally futile, as it can teleport at will." - color = null - slime_color = "bluespace" - icon_state_override = "bluespace" - coretype = /obj/item/slime_extract/bluespace - - description_info = "This slime will teleport to attack something if it is within a range of seven tiles. The teleport has a cooldown of five seconds." - - slime_mutation = list( - /mob/living/simple_animal/slime/bluespace, - /mob/living/simple_animal/slime/bluespace, - /mob/living/simple_animal/slime/yellow, - /mob/living/simple_animal/slime/yellow - ) - - spattack_prob = 100 - spattack_min_range = 3 - spattack_max_range = 7 - var/last_tele = null // Uses world.time - var/tele_cooldown = 5 SECONDS - -/mob/living/simple_animal/slime/bluespace/ClosestDistance() // Needed or the SA AI won't ever try to teleport. - if(world.time > last_tele + tele_cooldown) - return spattack_max_range - 1 - return ..() - -/mob/living/simple_animal/slime/bluespace/SpecialAtkTarget() - // Teleport attack. - if(!target_mob) - to_chat(src, "There's nothing to teleport to.") - return FALSE - - if(world.time < last_tele + tele_cooldown) - to_chat(src, "You can't teleport right now, wait a few seconds.") - return FALSE - - var/list/nearby_things = range(1, target_mob) - var/list/valid_turfs = list() - - // All this work to just go to a non-dense tile. - for(var/turf/potential_turf in nearby_things) - var/valid_turf = TRUE - if(potential_turf.density) - continue - for(var/atom/movable/AM in potential_turf) - if(AM.density) - valid_turf = FALSE - if(valid_turf) - valid_turfs.Add(potential_turf) - - - - var/turf/T = get_turf(src) - var/turf/target_turf = pick(valid_turfs) - - if(!target_turf) - to_chat(src, "There wasn't an unoccupied spot to teleport to.") - return FALSE - - var/datum/effect/effect/system/spark_spread/s1 = new /datum/effect/effect/system/spark_spread - s1.set_up(5, 1, T) - var/datum/effect/effect/system/spark_spread/s2 = new /datum/effect/effect/system/spark_spread - s2.set_up(5, 1, target_turf) - - - T.visible_message("\The [src] vanishes!") - s1.start() - - forceMove(target_turf) - playsound(target_turf, 'sound/effects/phasein.ogg', 50, 1) - to_chat(src, "You teleport to \the [target_turf].") - - target_turf.visible_message("\The [src] appears!") - s2.start() - - last_tele = world.time - - if(Adjacent(target_mob)) - PunchTarget() - return TRUE - -/mob/living/simple_animal/slime/ruby - desc = "This slime has great physical strength." - color = "#FF3333" - slime_color = "ruby" - shiny = TRUE - glows = TRUE - coretype = /obj/item/slime_extract/ruby - - description_info = "This slime is unnaturally stronger, allowing it to hit much harder, take less damage, and be stunned for less time. \ - Their glomp attacks also send the victim flying." - - slime_mutation = list( - /mob/living/simple_animal/slime/dark_purple, - /mob/living/simple_animal/slime/dark_purple, - /mob/living/simple_animal/slime/ruby, - /mob/living/simple_animal/slime/ruby - ) - -/mob/living/simple_animal/slime/ruby/New() - ..() - add_modifier(/datum/modifier/slime_strength, null, src) // Slime is always swole. - -/mob/living/simple_animal/slime/ruby/DoPunch(var/mob/living/L) - ..() // Do regular attacks. - - if(istype(L)) - if(a_intent == I_HURT) - visible_message("\The [src] sends \the [L] flying with the impact!") - playsound(src, "punch", 50, 1) - L.Weaken(1) - var/throwdir = get_dir(src, L) - L.throw_at(get_edge_target_turf(L, throwdir), 3, 1, src) - - -/mob/living/simple_animal/slime/amber - desc = "This slime seems to be an expert in the culinary arts, as they create their own food to share with others. \ - They would probably be very important to other slimes, if the other colors didn't try to kill them." - color = "#FFBB00" - slime_color = "amber" - shiny = TRUE - glows = TRUE - coretype = /obj/item/slime_extract/amber - - description_info = "This slime feeds nearby entities passively while it is alive. This can cause uncontrollable \ - slime growth and reproduction if not kept in check. The amber slime cannot feed itself, but can be fed by other amber slimes." - - slime_mutation = list( - /mob/living/simple_animal/slime/silver, - /mob/living/simple_animal/slime/silver, - /mob/living/simple_animal/slime/amber, - /mob/living/simple_animal/slime/amber - ) - -/mob/living/simple_animal/slime/amber/Life() - if(stat != DEAD) - feed_aura() - ..() - -/mob/living/simple_animal/slime/amber/proc/feed_aura() - for(var/mob/living/L in view(2, src)) - if(L == src) // Don't feed themselves, or it is impossible to stop infinite slimes without killing all of the ambers. - continue - if(isslime(L)) - var/mob/living/simple_animal/slime/S = L - S.adjust_nutrition(rand(15, 25)) - if(ishuman(L)) - var/mob/living/carbon/human/H = L - if(H.isSynthetic()) - continue - H.nutrition = between(0, H.nutrition + rand(15, 25), 600) - - - -/mob/living/simple_animal/slime/cerulean - desc = "This slime is generally superior in a wide range of attributes, compared to the common slime. The jack of all trades, but master of none." - color = "#4F7EAA" - slime_color = "cerulean" - coretype = /obj/item/slime_extract/cerulean - - // Less than the specialized slimes, but higher than the rest. - maxHealth = 200 - maxHealth_adult = 250 - - melee_damage_lower = 10 - melee_damage_upper = 30 - - move_to_delay = 3 - - - - slime_mutation = list( - /mob/living/simple_animal/slime/dark_blue, - /mob/living/simple_animal/slime/dark_blue, - /mob/living/simple_animal/slime/cerulean, - /mob/living/simple_animal/slime/cerulean - ) - -// Tier 4 - -/mob/living/simple_animal/slime/red - desc = "This slime is full of energy, and very aggressive. 'The red ones go faster.' seems to apply here." - color = "#FF3333" - slime_color = "red" - coretype = /obj/item/slime_extract/red - move_to_delay = 3 // The red ones go faster. - - description_info = "This slime is faster than the others. Attempting to discipline this slime will always cause it to go berserk." - - slime_mutation = list( - /mob/living/simple_animal/slime/red, - /mob/living/simple_animal/slime/oil, - /mob/living/simple_animal/slime/oil, - /mob/living/simple_animal/slime/orange - ) - - -/mob/living/simple_animal/slime/red/adjust_discipline(amount) - if(amount > 0) - if(!rabid) - enrage() // How dare you try to control the red slime. - say("Grrr...!") - -/mob/living/simple_animal/slime/red/enrage() - ..() - add_modifier(/datum/modifier/berserk, 30 SECONDS) - - -/mob/living/simple_animal/slime/green - desc = "This slime is radioactive." - color = "#14FF20" - slime_color = "green" - coretype = /obj/item/slime_extract/green - glows = TRUE - reagent_injected = "radium" - var/rads = 25 - - description_info = "This slime will irradiate anything nearby passively, and will inject radium on attack. \ - A radsuit or other thick and radiation-hardened armor can protect from this. It will only radiate while alive." - - slime_mutation = list( - /mob/living/simple_animal/slime/purple, - /mob/living/simple_animal/slime/green, - /mob/living/simple_animal/slime/emerald, - /mob/living/simple_animal/slime/emerald - ) - -/mob/living/simple_animal/slime/green/Life() - if(stat != DEAD) - irradiate() - ..() - -/mob/living/simple_animal/slime/green/proc/irradiate() - radiation_repository.radiate(src, rads) - - -/mob/living/simple_animal/slime/pink - desc = "This slime has regenerative properties." - color = "#FF0080" - slime_color = "pink" - coretype = /obj/item/slime_extract/pink - glows = TRUE - - description_info = "This slime will passively heal nearby entities within two tiles, including itself. It will only do this while alive." - - slime_mutation = list( - /mob/living/simple_animal/slime/blue, - /mob/living/simple_animal/slime/light_pink, - /mob/living/simple_animal/slime/light_pink, - /mob/living/simple_animal/slime/pink - ) - -/mob/living/simple_animal/slime/pink/Life() - if(stat != DEAD) - heal_aura() - ..() - -/mob/living/simple_animal/slime/pink/proc/heal_aura() - for(var/mob/living/L in view(src, 2)) - if(L.stat == DEAD || L == target_mob) - continue - L.add_modifier(/datum/modifier/slime_heal, 5 SECONDS, src) - -/datum/modifier/slime_heal - name = "slime mending" - desc = "You feel somewhat gooy." - mob_overlay_state = "pink_sparkles" - - on_created_text = "Twinkling spores of goo surround you. It makes you feel healthier." - on_expired_text = "The spores of goo have faded, although you feel much healthier than before." - stacks = MODIFIER_STACK_EXTEND - -/datum/modifier/slime_heal/tick() - if(holder.stat == DEAD) // Required or else simple animals become immortal. - expire() - - if(ishuman(holder)) // Robolimbs need this code sadly. - var/mob/living/carbon/human/H = holder - for(var/obj/item/organ/external/E in H.organs) - var/obj/item/organ/external/O = E - O.heal_damage(2, 2, 0, 1) - else - holder.adjustBruteLoss(-2) - holder.adjustFireLoss(-2) - - holder.adjustToxLoss(-2) - holder.adjustOxyLoss(-2) - holder.adjustCloneLoss(-1) - - - -/mob/living/simple_animal/slime/gold - desc = "This slime absorbs energy, and cannot be stunned by normal means." - color = "#EEAA00" - shiny = TRUE - slime_color = "gold" - coretype = /obj/item/slime_extract/gold - description_info = "This slime is immune to the slimebaton and taser, and will actually charge the slime, however it will still discipline the slime." - - slime_mutation = list( - /mob/living/simple_animal/slime/metal, - /mob/living/simple_animal/slime/gold, - /mob/living/simple_animal/slime/sapphire, - /mob/living/simple_animal/slime/sapphire - ) - -/mob/living/simple_animal/slime/gold/Weaken(amount) - power_charge = between(0, power_charge + amount, 10) - return - -/mob/living/simple_animal/slime/gold/Stun(amount) - power_charge = between(0, power_charge + amount, 10) - return - -/mob/living/simple_animal/slime/gold/get_description_interaction() // So it doesn't say to use a baton on them. - return list() - - -// Tier 5 - -/mob/living/simple_animal/slime/oil - desc = "This slime is explosive and volatile. Smoking near it is probably a bad idea." - color = "#333333" - slime_color = "oil" - shiny = TRUE - coretype = /obj/item/slime_extract/oil - - description_info = "If this slime suffers damage from a fire or heat based source, or if it is caught inside \ - an explosion, it will explode. Rabid oil slimes will charge at enemies, then suicide-bomb themselves. \ - Bomb suits can protect from the explosion." - - slime_mutation = list( - /mob/living/simple_animal/slime/oil, - /mob/living/simple_animal/slime/oil, - /mob/living/simple_animal/slime/red, - /mob/living/simple_animal/slime/red - ) - -/mob/living/simple_animal/slime/oil/proc/explode() - if(stat != DEAD) - // explosion(src.loc, 1, 2, 4) - explosion(src.loc, 0, 2, 4) // A bit weaker since the suicide charger tended to gib the poor sod being targeted. - if(src) // Delete ourselves if the explosion didn't do it. - qdel(src) - -/mob/living/simple_animal/slime/oil/post_attack(var/mob/living/L, var/intent = I_HURT) - if(!rabid) - return ..() - if(intent == I_HURT || intent == I_GRAB) - say(pick("Sacrifice...!", "Sssss...", "Boom...!")) - sleep(2 SECOND) - log_and_message_admins("[src] has suicide-bombed themselves while trying to kill \the [L].") - explode() - -/mob/living/simple_animal/slime/oil/ex_act(severity) - log_and_message_admins("[src] exploded due to a chain reaction with another explosion.") - explode() - -/mob/living/simple_animal/slime/oil/fire_act(datum/gas_mixture/air, temperature, volume) - log_and_message_admins("[src] exploded due to exposure to fire.") - explode() - -/mob/living/simple_animal/slime/oil/bullet_act(var/obj/item/projectile/P, var/def_zone) - if(P.damage_type && P.damage_type == BURN && P.damage) // Most bullets won't trigger the explosion, as a mercy towards Security. - log_and_message_admins("[src] exploded due to bring hit by a burning projectile[P.firer ? " by [key_name(P.firer)]" : ""].") - explode() - else - ..() - -/mob/living/simple_animal/slime/oil/attackby(var/obj/item/weapon/W, var/mob/user) - if(istype(W) && W.force && W.damtype == BURN) - log_and_message_admins("[src] exploded due to being hit with a burning weapon ([W]) by [key_name(user)].") - explode() - else - ..() - - -/mob/living/simple_animal/slime/sapphire - desc = "This slime seems a bit brighter than the rest, both figuratively and literally." - color = "#2398FF" - slime_color = "sapphire" - shiny = TRUE - glows = TRUE - coretype = /obj/item/slime_extract/sapphire - - optimal_combat = TRUE // Lift combat AI restrictions to look smarter. - run_at_them = FALSE // Use fancy A* pathing. - astar_adjacent_proc = /turf/proc/TurfsWithAccess // Normal slimes don't care about cardinals (because BYOND) so smart slimes shouldn't as well. - move_to_delay = 3 // A* chasing is slightly slower in terms of movement speed than regular pathing so reducing this hopefully makes up for that. - - description_info = "This slime uses more robust tactics when fighting and won't hold back, so it is dangerous to be alone \ - with one if hostile, and especially dangerous if they outnumber you." - - slime_mutation = list( - /mob/living/simple_animal/slime/sapphire, - /mob/living/simple_animal/slime/sapphire, - /mob/living/simple_animal/slime/gold, - /mob/living/simple_animal/slime/gold - ) - -/mob/living/simple_animal/slime/emerald - desc = "This slime is faster than usual, even more so than the red slimes." - color = "#22FF22" - shiny = TRUE - glows = TRUE - slime_color = "emerald" - coretype = /obj/item/slime_extract/emerald - - description_info = "This slime will make everything around it, and itself, faster for a few seconds, if close by." - move_to_delay = 2 - - slime_mutation = list( - /mob/living/simple_animal/slime/green, - /mob/living/simple_animal/slime/green, - /mob/living/simple_animal/slime/emerald, - /mob/living/simple_animal/slime/emerald - ) - -/mob/living/simple_animal/slime/emerald/Life() - if(stat != DEAD) - zoom_aura() - ..() - -/mob/living/simple_animal/slime/emerald/proc/zoom_aura() - for(var/mob/living/L in view(src, 2)) - if(L.stat == DEAD || L == target_mob) - continue - L.add_modifier(/datum/modifier/technomancer/haste, 5 SECONDS, src) - -/mob/living/simple_animal/slime/light_pink - desc = "This slime seems a lot more peaceful than the others." - color = "#FF8888" - slime_color = "light pink" - coretype = /obj/item/slime_extract/light_pink - - description_info = "This slime is effectively always disciplined initially." - obedience = 5 - discipline = 5 - - slime_mutation = list( - /mob/living/simple_animal/slime/pink, - /mob/living/simple_animal/slime/pink, - /mob/living/simple_animal/slime/light_pink, - /mob/living/simple_animal/slime/light_pink - ) - -// Special -/mob/living/simple_animal/slime/rainbow - desc = "This slime changes colors constantly." - color = null // Only slime subtype that uses a different icon_state. - slime_color = "rainbow" - coretype = /obj/item/slime_extract/rainbow - icon_state_override = "rainbow" - unity = TRUE - - description_info = "This slime is considered to be the same color as all other slime colors at the same time for the purposes of \ - other slimes being friendly to them, and therefore will never be harmed by another slime. \ - Attacking this slime will provoke the wrath of all slimes within range." - - slime_mutation = list( - /mob/living/simple_animal/slime/rainbow, - /mob/living/simple_animal/slime/rainbow, - /mob/living/simple_animal/slime/rainbow, - /mob/living/simple_animal/slime/rainbow - ) - -/mob/living/simple_animal/slime/rainbow/New() - unify() - ..() - -// The RD's pet slime. -/mob/living/simple_animal/slime/rainbow/kendrick - name = "Kendrick" - desc = "The Research Director's pet slime. It shifts colors constantly." - rainbow_core_candidate = FALSE - -/mob/living/simple_animal/slime/rainbow/kendrick/New() - pacify() - ..() \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/vore/bee.dm b/code/modules/mob/living/simple_animal/vore/bee.dm index e5bf7b49ae..e994c0dcb6 100644 --- a/code/modules/mob/living/simple_animal/vore/bee.dm +++ b/code/modules/mob/living/simple_animal/vore/bee.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/retaliate/bee +/mob/living/simple_mob/retaliate/bee name = "space bumble bee" desc = "Buzz buzz." icon = 'icons/mob/vore.dmi' @@ -36,10 +36,10 @@ faction = "bee" -/mob/living/simple_animal/retaliate/bee/Process_Spacemove(var/check_drift = 0) +/mob/living/simple_mob/retaliate/bee/Process_Spacemove(var/check_drift = 0) return 1 //No drifting in space for space bee! // Activate Noms! -/mob/living/simple_animal/retaliate/bee +/mob/living/simple_mob/retaliate/bee vore_active = 1 vore_icons = SA_ICON_LIVING diff --git a/code/modules/mob/living/simple_animal/vore/carp.dm b/code/modules/mob/living/simple_animal/vore/carp.dm deleted file mode 100644 index e4bcc95d4e..0000000000 --- a/code/modules/mob/living/simple_animal/vore/carp.dm +++ /dev/null @@ -1,32 +0,0 @@ -/mob/living/simple_animal/hostile/carp/large/huge - name = "great white carp" - desc = "You're going to need a bigger ship." - icon = 'icons/mob/vore64x64.dmi' - icon_dead = "megacarp-dead" - icon_living = "megacarp" - icon_state = "megacarp" - - maxHealth = 600 // Boss - health = 600 - speed = 3 - - meat_amount = 10 - - melee_damage_lower = 10 - melee_damage_upper = 25 - old_x = -16 - old_y = -16 - default_pixel_x = -16 - default_pixel_y = -16 - pixel_x = -16 - pixel_y = -16 - vore_capacity = 2 - -// Activate Noms! -/mob/living/simple_animal/hostile/carp/large - icon = 'icons/mob/vore64x64.dmi' - vore_active = 1 - vore_pounce_chance = 50 - vore_capacity = 1 - vore_max_size = RESIZE_HUGE - vore_icons = SA_ICON_LIVING diff --git a/code/modules/mob/living/simple_animal/vore/catgirl.dm b/code/modules/mob/living/simple_animal/vore/catgirl.dm index 445020c90b..4e27b12477 100644 --- a/code/modules/mob/living/simple_animal/vore/catgirl.dm +++ b/code/modules/mob/living/simple_animal/vore/catgirl.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/catgirl +/mob/living/simple_mob/catgirl name = "catgirl" desc = "Her hobbies are catnaps, knocking things over, and headpats." tt_desc = "Homo felinus" @@ -44,7 +44,7 @@ "catgirlbrown" ) -/mob/living/simple_animal/catgirl/New() +/mob/living/simple_mob/catgirl/New() ..() if(random_skin) icon_living = pick(skins) @@ -53,7 +53,7 @@ update_icon() // Activate Noms! -/mob/living/simple_animal/catgirl +/mob/living/simple_mob/catgirl vore_active = 1 vore_bump_chance = 5 vore_pounce_chance = 50 @@ -63,5 +63,5 @@ vore_digest_chance = 25 // But squirming might make them gurgle... vore_icons = SA_ICON_LIVING | SA_ICON_REST -/mob/living/simple_animal/catgirl/retaliate +/mob/living/simple_mob/catgirl/retaliate retaliate = 1 diff --git a/code/modules/mob/living/simple_animal/vore/cookiegirl.dm b/code/modules/mob/living/simple_animal/vore/cookiegirl.dm index 049da3c5db..26f2e2c525 100644 --- a/code/modules/mob/living/simple_animal/vore/cookiegirl.dm +++ b/code/modules/mob/living/simple_animal/vore/cookiegirl.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/cookiegirl +/mob/living/simple_mob/cookiegirl name = "cookiegirl" desc = "A woman made with a combination of, well... Whatever you put in a cookie. What were the chefs thinking?" icon = 'icons/mob/vore.dmi' @@ -31,7 +31,7 @@ attacktext = list("smacked") // Activate Noms! -/mob/living/simple_animal/cookiegirl +/mob/living/simple_mob/cookiegirl vore_active = 1 vore_bump_chance = 2 vore_pounce_chance = 25 @@ -41,5 +41,5 @@ vore_digest_chance = 10 // Gonna become as sweet as sugar, soon. vore_icons = SA_ICON_LIVING | SA_ICON_REST -/mob/living/simple_animal/cookiegirl/retaliate +/mob/living/simple_mob/cookiegirl/retaliate retaliate = 1 diff --git a/code/modules/mob/living/simple_animal/vore/corrupt_hounds.dm b/code/modules/mob/living/simple_animal/vore/corrupt_hounds.dm index eb62a21086..bbf9c9f9d9 100644 --- a/code/modules/mob/living/simple_animal/vore/corrupt_hounds.dm +++ b/code/modules/mob/living/simple_animal/vore/corrupt_hounds.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/hostile/corrupthound +/mob/living/simple_mob/hostile/corrupthound name = "corrupt hound" desc = "Good boy machine broke. This is definitely no good news for the organic lifeforms in vicinity." icon = 'icons/mob/vore64x32.dmi' @@ -66,7 +66,7 @@ loot_list = list(/obj/item/borg/upgrade/syndicate = 6, /obj/item/borg/upgrade/vtec = 6, /obj/item/weapon/material/knife/ritual = 6, /obj/item/weapon/disk/nifsoft/compliance = 6) -/mob/living/simple_animal/hostile/corrupthound/prettyboi +/mob/living/simple_mob/hostile/corrupthound/prettyboi name = "corrupt corrupt hound" desc = "Bad boy machine broke as well. Seems an attempt was made to achieve a less threatening look, and this one is definitely having some conflicting feelings about it." icon_state = "prettyboi" @@ -85,36 +85,36 @@ say_got_target = list("HERE COMES BIG MEAN HUG MACHINE!", "I'LL BE GENTLE!", "FUEL ME FRIEND!", "I*M SO SORRY!", "YUMMY TREAT DETECTED!", "LOVE ME!", "Not again. NOT AGAIN!") -/mob/living/simple_animal/hostile/corrupthound/isSynthetic() +/mob/living/simple_mob/hostile/corrupthound/isSynthetic() return TRUE -/mob/living/simple_animal/hostile/corrupthound/speech_bubble_appearance() +/mob/living/simple_mob/hostile/corrupthound/speech_bubble_appearance() return "synthetic_evil" -/mob/living/simple_animal/hostile/corrupthound/PunchTarget() - if(istype(target_mob,/mob/living/simple_animal/mouse)) +/mob/living/simple_mob/hostile/corrupthound/PunchTarget() + if(istype(target_mob,/mob/living/simple_mob/mouse)) return EatTarget() else ..() -/mob/living/simple_animal/hostile/corrupthound/proc/add_eyes() +/mob/living/simple_mob/hostile/corrupthound/proc/add_eyes() if(!eye_layer) eye_layer = image(icon, "badboi-eyes") eye_layer.plane = PLANE_LIGHTING_ABOVE add_overlay(eye_layer) -/mob/living/simple_animal/hostile/corrupthound/proc/remove_eyes() +/mob/living/simple_mob/hostile/corrupthound/proc/remove_eyes() cut_overlay(eye_layer) -/mob/living/simple_animal/hostile/corrupthound/New() +/mob/living/simple_mob/hostile/corrupthound/New() add_eyes() ..() -/mob/living/simple_animal/hostile/corrupthound/death(gibbed, deathmessage = "shudders and collapses!") +/mob/living/simple_mob/hostile/corrupthound/death(gibbed, deathmessage = "shudders and collapses!") .=..() resting = 0 icon_state = icon_dead -/mob/living/simple_animal/hostile/corrupthound/update_icon() +/mob/living/simple_mob/hostile/corrupthound/update_icon() . = ..() remove_eyes() if(stat == CONSCIOUS && !resting) diff --git a/code/modules/mob/living/simple_animal/vore/deathclaw.dm b/code/modules/mob/living/simple_animal/vore/deathclaw.dm index 91fe552ccc..e015c07b9e 100644 --- a/code/modules/mob/living/simple_animal/vore/deathclaw.dm +++ b/code/modules/mob/living/simple_animal/vore/deathclaw.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/hostile/deathclaw +/mob/living/simple_mob/hostile/deathclaw name = "deathclaw" desc = "Big! Big! The size of three men! Claws as long as my forearm! Ripped apart! Ripped apart!" icon = 'icons/mob/vore64x64.dmi' @@ -30,7 +30,7 @@ mount_offset_y = 30 // Activate Noms! -/mob/living/simple_animal/hostile/deathclaw +/mob/living/simple_mob/hostile/deathclaw vore_active = 1 vore_capacity = 2 vore_max_size = RESIZE_HUGE diff --git a/code/modules/mob/living/simple_animal/vore/dino.dm b/code/modules/mob/living/simple_animal/vore/dino.dm index 18af3d28e1..0cc845900c 100644 --- a/code/modules/mob/living/simple_animal/vore/dino.dm +++ b/code/modules/mob/living/simple_animal/vore/dino.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/hostile/dino +/mob/living/simple_mob/hostile/dino name = "voracious lizard" desc = "These gluttonous little bastards used to be regular lizards that were mutated by long-term exposure to phoron!" icon = 'icons/mob/vore.dmi' @@ -33,10 +33,10 @@ max_n2 = 0 // Activate Noms! -/mob/living/simple_animal/hostile/dino +/mob/living/simple_mob/hostile/dino vore_active = 1 swallowTime = 1 SECOND // Hungry little bastards. vore_icons = SA_ICON_LIVING -/mob/living/simple_animal/hostile/dino/virgo3b +/mob/living/simple_mob/hostile/dino/virgo3b faction = "virgo3b" \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/vore/dragon.dm b/code/modules/mob/living/simple_animal/vore/dragon.dm index 2d839fb149..10934e4b38 100644 --- a/code/modules/mob/living/simple_animal/vore/dragon.dm +++ b/code/modules/mob/living/simple_animal/vore/dragon.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/hostile/dragon +/mob/living/simple_mob/hostile/dragon name = "red dragon" desc = "Here to pillage stations and kidnap princesses, and there probably aren't any princesses." icon = 'icons/mob/vore64x64.dmi' @@ -30,29 +30,22 @@ pixel_x = -16 pixel_y = 0 - max_buckled_mobs = 1 //Yeehaw - can_buckle = TRUE - buckle_movable = TRUE - buckle_lying = FALSE - mount_offset_x = -11 - mount_offset_y = 16 - -/mob/living/simple_animal/hostile/dragon/Process_Spacemove(var/check_drift = 0) +/mob/living/simple_mob/hostile/dragon/Process_Spacemove(var/check_drift = 0) return 1 //No drifting in space for space dragons! -/mob/living/simple_animal/hostile/dragon/FindTarget() +/mob/living/simple_mob/hostile/dragon/FindTarget() . = ..() if(.) custom_emote(1,"snaps at [.]") // Activate Noms! -/mob/living/simple_animal/hostile/dragon +/mob/living/simple_mob/hostile/dragon vore_active = 1 vore_capacity = 2 vore_pounce_chance = 0 // Beat them into crit before eating. vore_icons = SA_ICON_LIVING -/mob/living/simple_animal/hostile/dragon/virgo3b +/mob/living/simple_mob/hostile/dragon/virgo3b maxHealth = 200 health = 200 faction = "virgo3b" diff --git a/code/modules/mob/living/simple_animal/vore/fennec.dm b/code/modules/mob/living/simple_animal/vore/fennec.dm index 1f7a869a4a..20be0a0319 100644 --- a/code/modules/mob/living/simple_animal/vore/fennec.dm +++ b/code/modules/mob/living/simple_animal/vore/fennec.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/fennec +/mob/living/simple_mob/fennec name = "fennec" desc = "It's a dusty big-eared sandfox! Adorable!" tt_desc = "Vulpes zerda" @@ -29,7 +29,7 @@ emote_see = list("earflicks","sniffs at the ground") // Activate Noms! -/mob/living/simple_animal/fennec +/mob/living/simple_mob/fennec vore_active = 1 vore_bump_chance = 10 vore_bump_emote = "playfully lunges at" diff --git a/code/modules/mob/living/simple_animal/vore/fennix.dm b/code/modules/mob/living/simple_animal/vore/fennix.dm index 077994872d..6b55b0c997 100644 --- a/code/modules/mob/living/simple_animal/vore/fennix.dm +++ b/code/modules/mob/living/simple_animal/vore/fennix.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/retaliate/fennix +/mob/living/simple_mob/retaliate/fennix name = "Fennix" desc = "A feral fennix, Warm to the touch" tt_desc = "Incaendium Faeles Vulpes" diff --git a/code/modules/mob/living/simple_animal/vore/frog.dm b/code/modules/mob/living/simple_animal/vore/frog.dm index ae4389914b..4030f7c8e5 100644 --- a/code/modules/mob/living/simple_animal/vore/frog.dm +++ b/code/modules/mob/living/simple_animal/vore/frog.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/hostile/frog +/mob/living/simple_mob/hostile/frog name = "giant frog" desc = "You've heard of having a frog in your throat, now get ready for the reverse." tt_desc = "Anura gigantus" @@ -14,19 +14,19 @@ melee_damage_upper = 25 // Pepe is love, not hate. -/mob/living/simple_animal/hostile/frog/New() +/mob/living/simple_mob/hostile/frog/New() if(rand(1,1000000) == 1) name = "rare Pepe" desc = "You found a rare Pepe. Screenshot for good luck." ..() // Activate Noms! -/mob/living/simple_animal/hostile/frog +/mob/living/simple_mob/hostile/frog vore_active = 1 vore_pounce_chance = 50 vore_icons = SA_ICON_LIVING -/mob/living/simple_animal/hostile/frog/space +/mob/living/simple_mob/hostile/frog/space name = "space frog" //Space frog can hold its breath or whatever diff --git a/code/modules/mob/living/simple_animal/vore/gaslamp.dm b/code/modules/mob/living/simple_animal/vore/gaslamp.dm index 8df8d216b4..357cbd0775 100644 --- a/code/modules/mob/living/simple_animal/vore/gaslamp.dm +++ b/code/modules/mob/living/simple_animal/vore/gaslamp.dm @@ -10,7 +10,7 @@ kills them. TODO: Make them light up and heat the air when exposed to oxygen. */ -/mob/living/simple_animal/retaliate/gaslamp +/mob/living/simple_mob/retaliate/gaslamp name = "gaslamp" desc = "Some sort of floaty alien with a warm glow. This creature is endemic to Virgo-3B." tt_desc = "Semaeostomeae virginus" @@ -51,7 +51,7 @@ TODO: Make them light up and heat the air when exposed to oxygen. max_n2 = 0 // Activate Noms! -/mob/living/simple_animal/retaliate/gaslamp +/mob/living/simple_mob/retaliate/gaslamp vore_active = 1 vore_capacity = 2 vore_bump_chance = 90 //they're frickin' jellyfish anenome filterfeeders, get tentacled diff --git a/code/modules/mob/living/simple_animal/vore/hippo.dm b/code/modules/mob/living/simple_animal/vore/hippo.dm index ae9d8775e1..4366395d38 100644 --- a/code/modules/mob/living/simple_animal/vore/hippo.dm +++ b/code/modules/mob/living/simple_animal/vore/hippo.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/retaliate/hippo +/mob/living/simple_mob/retaliate/hippo name = "hippo" desc = "Mostly know for the spectacular hit of the live action movie Hungry Hungry Hippos." tt_desc = "Hippopotamus amphibius" @@ -56,7 +56,7 @@ mount_offset_y = 20 // Activate Noms! -/mob/living/simple_animal/retaliate/hippo //I don't know why it's in a seperate line but everyone does it so i do it +/mob/living/simple_mob/retaliate/hippo //I don't know why it's in a seperate line but everyone does it so i do it vore_active = 1 vore_capacity = 1 vore_bump_chance = 15 diff --git a/code/modules/mob/living/simple_animal/vore/horse.dm b/code/modules/mob/living/simple_animal/vore/horse.dm index 80cd80dd0e..9332ae043c 100644 --- a/code/modules/mob/living/simple_animal/vore/horse.dm +++ b/code/modules/mob/living/simple_animal/vore/horse.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/horse +/mob/living/simple_mob/horse name = "horse" desc = "Don't look it in the mouth." tt_desc = "Equus ferus caballus" @@ -38,7 +38,7 @@ mount_offset_x = 0 // Activate Noms! -/mob/living/simple_animal/horse +/mob/living/simple_mob/horse vore_active = 1 vore_icons = SA_ICON_LIVING diff --git a/code/modules/mob/living/simple_animal/vore/jelly.dm b/code/modules/mob/living/simple_animal/vore/jelly.dm index 559ee1f8ee..828ce81149 100644 --- a/code/modules/mob/living/simple_animal/vore/jelly.dm +++ b/code/modules/mob/living/simple_animal/vore/jelly.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/hostile/jelly +/mob/living/simple_mob/hostile/jelly name = "jelly blob" desc = "Some sort of undulating blob of slime!" icon = 'icons/mob/vore.dmi' @@ -18,7 +18,7 @@ emote_see = list("undulates quietly") // Activate Noms! -/mob/living/simple_animal/hostile/jelly +/mob/living/simple_mob/hostile/jelly vore_active = 1 vore_pounce_chance = 0 vore_icons = SA_ICON_LIVING diff --git a/code/modules/mob/living/simple_animal/vore/otie.dm b/code/modules/mob/living/simple_animal/vore/otie.dm index c7d171ed84..c837ea7b12 100644 --- a/code/modules/mob/living/simple_animal/vore/otie.dm +++ b/code/modules/mob/living/simple_animal/vore/otie.dm @@ -3,7 +3,7 @@ // Probably easier to troubleshoot when we ain't breaking the server by spawning a buttload of heavily extra feature coded snowflake mobs to the wilderness as mass cannonfodder. // Also ToDo: An actual "simple" mob for that purpose if necessary :v -/mob/living/simple_animal/otie //Spawn this one only if you're looking for a bad time. Not friendly. +/mob/living/simple_mob/otie //Spawn this one only if you're looking for a bad time. Not friendly. name = "otie" desc = "The classic bioengineered longdog." tt_desc = "Otus robustus" @@ -61,13 +61,13 @@ // Activate Noms! -/mob/living/simple_animal/otie +/mob/living/simple_mob/otie vore_active = 1 vore_capacity = 1 vore_pounce_chance = 20 vore_icons = SA_ICON_LIVING | SA_ICON_REST -/mob/living/simple_animal/otie/feral //gets the pet2tame feature. starts out hostile tho so get gamblin' +/mob/living/simple_mob/otie/feral //gets the pet2tame feature. starts out hostile tho so get gamblin' name = "mutated feral otie" desc = "The classic bioengineered longdog. No pets. Only bite. This one has mutated from too much time out on the surface of Virgo-3B." tt_desc = "Otus phoronis" @@ -91,7 +91,7 @@ glowyeyes = TRUE eyetype = "photie" -/mob/living/simple_animal/otie/red +/mob/living/simple_mob/otie/red name = "feral red otie" desc = "Seems this ominous looking longdog has been infused with wicked infernal forces." tt_desc = "Otus infernalis" @@ -115,19 +115,19 @@ glowyeyes = TRUE eyetype = "hotie" -/mob/living/simple_animal/otie/red/friendly //gets the pet2tame feature and doesn't kill you right away +/mob/living/simple_mob/otie/red/friendly //gets the pet2tame feature and doesn't kill you right away name = "red otie" desc = "Seems this ominous looking longdog has been infused with wicked infernal forces. This one seems rather peaceful though." faction = "neutral" tamed = 1 -/mob/living/simple_animal/otie/friendly //gets the pet2tame feature and doesn't kill you right away +/mob/living/simple_mob/otie/friendly //gets the pet2tame feature and doesn't kill you right away name = "otie" desc = "The classic bioengineered longdog. This one might even tolerate you!" faction = "neutral" tamed = 1 -/mob/living/simple_animal/otie/cotie //same as above but has a little collar :v +/mob/living/simple_mob/otie/cotie //same as above but has a little collar :v name = "tamed otie" desc = "The classic bioengineered longdog. This one has a nice little collar on its neck. However a proper domesticated otie is an oxymoron and the collar is likely just a decoration." icon_state = "cotie" @@ -136,7 +136,7 @@ faction = "neutral" tamed = 1 -/mob/living/simple_animal/otie/cotie/phoron //friendly phoron pup with collar +/mob/living/simple_mob/otie/cotie/phoron //friendly phoron pup with collar name = "mutated otie" desc = "Looks like someone did manage to domesticate one of those wild phoron mutants. What a badass." tt_desc = "Otus phoronis" @@ -155,7 +155,7 @@ glowyeyes = TRUE eyetype = "photie" -/mob/living/simple_animal/otie/security //tame by default unless you're a marked crimester. can be befriended to follow with pets tho. +/mob/living/simple_mob/otie/security //tame by default unless you're a marked crimester. can be befriended to follow with pets tho. name = "guard otie" desc = "The VARMAcorp bioengineering division flagship product on trained optimal snowflake guard dogs." icon_state = "sotie" @@ -174,7 +174,7 @@ var/check_records = 0 // If true, arrests people without a record. var/check_arrest = 1 // If true, arrests people who are set to arrest. -/mob/living/simple_animal/otie/security/phoron +/mob/living/simple_mob/otie/security/phoron name = "mutated guard otie" desc = "An extra rare phoron resistant version of the VARMAcorp trained snowflake guard dogs." tt_desc = "Otus phoronis" @@ -195,15 +195,15 @@ glowyeyes = TRUE eyetype = "sotie" -/mob/living/simple_animal/otie/PunchTarget() - if(istype(target_mob,/mob/living/simple_animal/mouse)) +/mob/living/simple_mob/otie/PunchTarget() + if(istype(target_mob,/mob/living/simple_mob/mouse)) return EatTarget() else ..() -/mob/living/simple_animal/otie/Found(var/atom/found_atom) +/mob/living/simple_mob/otie/Found(var/atom/found_atom) if(!SA_attackable(found_atom)) return null - if(istype(found_atom,/mob/living/simple_animal/mouse)) + if(istype(found_atom,/mob/living/simple_mob/mouse)) return found_atom else if(ismob(found_atom)) var/mob/found_mob = found_atom @@ -222,20 +222,20 @@ else return null -/mob/living/simple_animal/otie/security/Found(var/atom/found_atom) +/mob/living/simple_mob/otie/security/Found(var/atom/found_atom) if(check_threat(found_atom) >= 4) if(resting) lay_down() return found_atom ..() -/mob/living/simple_animal/otie/attackby(var/obj/item/O, var/mob/user) // Trade donuts for bellybrig victims. +/mob/living/simple_mob/otie/attackby(var/obj/item/O, var/mob/user) // Trade donuts for bellybrig victims. if(istype(O, /obj/item/weapon/reagent_containers/food)) qdel(O) playsound(src.loc,'sound/items/eatfood.ogg', rand(10,50), 1) if(ai_inactive)//No autobarf on player control. return - if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/donut) && istype(src, /mob/living/simple_animal/otie/security)) + if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/donut) && istype(src, /mob/living/simple_mob/otie/security)) to_chat(user,"The guard pup accepts your offer for their catch.") release_vore_contents() else if(prob(2)) //Small chance to get prey out from non-sec oties. @@ -244,21 +244,21 @@ return . = ..() -/mob/living/simple_animal/otie/security/feed_grabbed_to_self(var/mob/living/user, var/mob/living/prey) // Make the gut start out safe for bellybrigging. +/mob/living/simple_mob/otie/security/feed_grabbed_to_self(var/mob/living/user, var/mob/living/prey) // Make the gut start out safe for bellybrigging. if(ishuman(prey)) vore_selected.digest_mode = DM_HOLD if(check_threat(prey) >= 4) global_announcer.autosay("[src] has detained suspect [target_name(prey)] in [get_area(src)].", "SmartCollar oversight", "Security") - if(istype(prey,/mob/living/simple_animal/mouse)) + if(istype(prey,/mob/living/simple_mob/mouse)) vore_selected.digest_mode = DM_DIGEST . = ..() -/mob/living/simple_animal/otie/security/proc/check_threat(var/mob/living/M) +/mob/living/simple_mob/otie/security/proc/check_threat(var/mob/living/M) if(!M || !ishuman(M) || M.stat == DEAD || src == M) return 0 return M.assess_perp(0, 0, 0, check_records, check_arrest) -/mob/living/simple_animal/otie/security/set_target(var/mob/M) +/mob/living/simple_mob/otie/security/set_target(var/mob/M) ai_log("SetTarget([M])",2) if(!M || (world.time - last_target_time < 5 SECONDS) && target_mob) ai_log("SetTarget() can't set it again so soon",3) @@ -286,7 +286,7 @@ return 0 -/mob/living/simple_animal/otie/security/proc/target_name(mob/living/T) +/mob/living/simple_mob/otie/security/proc/target_name(mob/living/T) if(ishuman(T)) var/mob/living/carbon/human/H = T return H.get_id_name("unidentified person") @@ -294,7 +294,7 @@ //Basic friend AI -/mob/living/simple_animal/otie/Life() +/mob/living/simple_mob/otie/Life() . = ..() if(!. || ai_inactive) return @@ -334,7 +334,7 @@ //Pet 4 friendly -/mob/living/simple_animal/otie/attack_hand(mob/living/carbon/human/M as mob) +/mob/living/simple_mob/otie/attack_hand(mob/living/carbon/human/M as mob) switch(M.a_intent) if(I_HELP) @@ -365,27 +365,27 @@ else ..() -/mob/living/simple_animal/otie/proc/add_eyes() +/mob/living/simple_mob/otie/proc/add_eyes() if(!eye_layer) eye_layer = image(icon, "[eyetype]-eyes") eye_layer.plane = PLANE_LIGHTING_ABOVE add_overlay(eye_layer) -/mob/living/simple_animal/otie/proc/remove_eyes() +/mob/living/simple_mob/otie/proc/remove_eyes() cut_overlay(eye_layer) -/mob/living/simple_animal/otie/New() +/mob/living/simple_mob/otie/New() if(glowyeyes) add_eyes() ..() -/mob/living/simple_animal/otie/update_icon() +/mob/living/simple_mob/otie/update_icon() . = ..() remove_eyes() if(glowyeyes && stat == CONSCIOUS && !resting) add_eyes() -/mob/living/simple_animal/otie/death(gibbed, deathmessage = "dies!") +/mob/living/simple_mob/otie/death(gibbed, deathmessage = "dies!") .=..() resting = 0 icon_state = icon_dead diff --git a/code/modules/mob/living/simple_animal/vore/panther.dm b/code/modules/mob/living/simple_animal/vore/panther.dm index 45a18cf300..fb992e49ed 100644 --- a/code/modules/mob/living/simple_animal/vore/panther.dm +++ b/code/modules/mob/living/simple_animal/vore/panther.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/hostile/panther +/mob/living/simple_mob/hostile/panther name = "panther" desc = "Runtime's larger, less cuddly cousin." tt_desc = "Panthera pardus" @@ -34,7 +34,7 @@ mount_offset_y = 12 // Activate Noms! -/mob/living/simple_animal/hostile/panther +/mob/living/simple_mob/hostile/panther vore_active = 1 vore_capacity = 2 vore_pounce_chance = 10 diff --git a/code/modules/mob/living/simple_animal/vore/rat.dm b/code/modules/mob/living/simple_animal/vore/rat.dm index 1f6be2e3f4..7cdd2c3bfd 100644 --- a/code/modules/mob/living/simple_animal/vore/rat.dm +++ b/code/modules/mob/living/simple_animal/vore/rat.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/hostile/rat +/mob/living/simple_mob/hostile/rat name = "giant rat" desc = "In what passes for a hierarchy among verminous rodents, this one is king." tt_desc = "Mus muscular" @@ -49,14 +49,14 @@ var/life_since_foodscan = 0 -/mob/living/simple_animal/hostile/rat/passive +/mob/living/simple_mob/hostile/rat/passive name = "curious giant rat" desc = "In what passes for a hierarchy among verminous rodents, this one is king. It seems to be more interested on scavenging." follow_dist = 1 var/mob/living/carbon/human/food var/hunger = 0 -/mob/living/simple_animal/hostile/rat/passive/Life() +/mob/living/simple_mob/hostile/rat/passive/Life() . = ..() if(!. || ai_inactive) return @@ -127,7 +127,7 @@ hunger = 0 food = null -/mob/living/simple_animal/hostile/rat/passive/attackby(var/obj/item/O, var/mob/user) // Feed the rat your food to satisfy it. +/mob/living/simple_mob/hostile/rat/passive/attackby(var/obj/item/O, var/mob/user) // Feed the rat your food to satisfy it. if(istype(O, /obj/item/weapon/reagent_containers/food/snacks)) qdel(O) playsound(src.loc,'sound/items/eatfood.ogg', rand(10,50), 1) @@ -136,7 +136,7 @@ return . = ..() -/mob/living/simple_animal/hostile/rat/passive/Found(var/atom/found_atom) +/mob/living/simple_mob/hostile/rat/passive/Found(var/atom/found_atom) if(!SA_attackable(found_atom)) return null else if(ishuman(found_atom) && will_eat(found_atom)) @@ -151,7 +151,7 @@ break return null -/mob/living/simple_animal/hostile/rat/passive/FindTarget() +/mob/living/simple_mob/hostile/rat/passive/FindTarget() var/atom/T = null for(var/atom/A in ListTargets(view_range)) if(A == src) @@ -162,7 +162,7 @@ break return T -/mob/living/simple_animal/hostile/rat/death() +/mob/living/simple_mob/hostile/rat/death() playsound(src, 'sound/effects/mouse_squeak_loud.ogg', 50, 1) ..() diff --git a/code/modules/mob/living/simple_animal/vore/redpanda.dm b/code/modules/mob/living/simple_animal/vore/redpanda.dm index 6047425f18..81b50880eb 100644 --- a/code/modules/mob/living/simple_animal/vore/redpanda.dm +++ b/code/modules/mob/living/simple_animal/vore/redpanda.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/redpanda +/mob/living/simple_mob/redpanda name = "red panda" desc = "It's a wah! Beware of doom pounce!" tt_desc = "Ailurus fulgens" @@ -29,7 +29,7 @@ emote_see = list("trundles around","rears up onto their hind legs and pounces a bug") // Activate Noms! -/mob/living/simple_animal/redpanda +/mob/living/simple_mob/redpanda vore_active = 1 vore_bump_chance = 10 vore_bump_emote = "playfully lunges at" @@ -37,7 +37,7 @@ vore_default_mode = DM_HOLD // above will only matter if someone toggles it anyway vore_icons = SA_ICON_LIVING -/mob/living/simple_animal/redpanda/fae +/mob/living/simple_mob/redpanda/fae name = "dark wah" desc = "Ominous, but still cute!" tt_desc = "Ailurus brattus" diff --git a/code/modules/mob/living/simple_animal/vore/shadekin/ability_objects.dm b/code/modules/mob/living/simple_animal/vore/shadekin/ability_objects.dm index 37cd6af662..6990623043 100644 --- a/code/modules/mob/living/simple_animal/vore/shadekin/ability_objects.dm +++ b/code/modules/mob/living/simple_animal/vore/shadekin/ability_objects.dm @@ -4,7 +4,7 @@ icon = 'icons/mob/screen_spells.dmi' var/ability_name = "FIX ME" var/cost = 50 - var/mob/living/simple_animal/shadekin/my_kin + var/mob/living/simple_mob/shadekin/my_kin var/shift_mode = NOT_WHILE_SHIFTED var/ab_sound @@ -130,7 +130,7 @@ on_created_text = "You drag part of The Dark into realspace, enveloping yourself." on_expired_text = "You lose your grasp on The Dark and realspace reasserts itself." stacks = MODIFIER_STACK_EXTEND - var/mob/living/simple_animal/shadekin/my_kin + var/mob/living/simple_mob/shadekin/my_kin /datum/modifier/shadekin/create_shade/tick() if(my_kin.ability_flags & AB_PHASE_SHIFTED) diff --git a/code/modules/mob/living/simple_animal/vore/shadekin/ability_procs.dm b/code/modules/mob/living/simple_animal/vore/shadekin/ability_procs.dm index 91bd07db29..0be707f852 100644 --- a/code/modules/mob/living/simple_animal/vore/shadekin/ability_procs.dm +++ b/code/modules/mob/living/simple_animal/vore/shadekin/ability_procs.dm @@ -1,5 +1,5 @@ // Phase shifting procs (and related procs) -/mob/living/simple_animal/shadekin/proc/phase_shift() +/mob/living/simple_mob/shadekin/proc/phase_shift() var/turf/T = get_turf(src) if(!T.CanPass(null,T) || loc != T) to_chat(src,"You can't use that here!") @@ -91,19 +91,19 @@ density = FALSE force_max_speed = TRUE -/mob/living/simple_animal/shadekin/UnarmedAttack() +/mob/living/simple_mob/shadekin/UnarmedAttack() if(ability_flags & AB_PHASE_SHIFTED) return FALSE //Nope. . = ..() -/mob/living/simple_animal/shadekin/can_fall() +/mob/living/simple_mob/shadekin/can_fall() if(ability_flags & AB_PHASE_SHIFTED) return FALSE //Nope! return ..() -/mob/living/simple_animal/shadekin/zMove(direction) +/mob/living/simple_mob/shadekin/zMove(direction) if(ability_flags & AB_PHASE_SHIFTED) var/turf/destination = (direction == UP) ? GetAbove(src) : GetBelow(src) if(destination) @@ -113,7 +113,7 @@ return ..() // Healing others -/mob/living/simple_animal/shadekin/proc/mend_other() +/mob/living/simple_mob/shadekin/proc/mend_other() //I hate to crunch a view() but I only want ones I can see var/list/viewed = oview(1) var/list/targets = list() diff --git a/code/modules/mob/living/simple_animal/vore/shadekin/shadekin.dm b/code/modules/mob/living/simple_animal/vore/shadekin/shadekin.dm index 19072aa629..a89688088d 100644 --- a/code/modules/mob/living/simple_animal/vore/shadekin/shadekin.dm +++ b/code/modules/mob/living/simple_animal/vore/shadekin/shadekin.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/shadekin //Spawning the prototype spawns a random one, see initialize() +/mob/living/simple_mob/shadekin //Spawning the prototype spawns a random one, see initialize() name = "shadekin" desc = "Some sort of fluffer. Big ears, long tail." icon = 'icons/mob/vore_shadekin.dmi' @@ -85,16 +85,16 @@ var/list/shadekin_abilities -/mob/living/simple_animal/shadekin/initialize() +/mob/living/simple_mob/shadekin/Initialize() //You spawned the prototype, and want a totally random one. - if(type == /mob/living/simple_animal/shadekin) + if(type == /mob/living/simple_mob/shadekin) //I'm told by VerySoft these are the liklihood values var/list/sk_types = list( - /mob/living/simple_animal/shadekin/red = 20, //Actively seek people out to nom, so fairly common to see (relatively speaking), - /mob/living/simple_animal/shadekin/blue = 15, //Explorers that like to interact with people, so still fairly common, - /mob/living/simple_animal/shadekin/purple = 15, //Also explorers that may or may not homf people, - /mob/living/simple_animal/shadekin/yellow = 1 //Very rare, usually never leaves their home + /mob/living/simple_mob/shadekin/red = 20, //Actively seek people out to nom, so fairly common to see (relatively speaking), + /mob/living/simple_mob/shadekin/blue = 15, //Explorers that like to interact with people, so still fairly common, + /mob/living/simple_mob/shadekin/purple = 15, //Also explorers that may or may not homf people, + /mob/living/simple_mob/shadekin/yellow = 1 //Very rare, usually never leaves their home ) var/new_type = pickweight(sk_types) @@ -138,11 +138,11 @@ return ..() -/mob/living/simple_animal/shadekin/Destroy() +/mob/living/simple_mob/shadekin/Destroy() QDEL_NULL_LIST(shadekin_abilities) . = ..() -/mob/living/simple_animal/shadekin/init_vore() +/mob/living/simple_mob/shadekin/init_vore() if(LAZYLEN(vore_organs)) return @@ -197,7 +197,7 @@ "The chaos of being digested fades as you're snuffed out by a harsh clench! You're steadily broken down into a thick paste, processed and absorbed by the predator!" ) -/mob/living/simple_animal/shadekin/Life() +/mob/living/simple_mob/shadekin/Life() . = ..() if(ability_flags & AB_PHASE_SHIFTED) density = FALSE @@ -207,7 +207,7 @@ nutrition = max(0, nutrition-5) energy = min(100,energy+1) -/mob/living/simple_animal/shadekin/update_icon() +/mob/living/simple_mob/shadekin/update_icon() . = ..() cut_overlay(tailimage) @@ -217,18 +217,18 @@ add_overlay(tailimage) add_overlay(eye_icon_state) -/mob/living/simple_animal/shadekin/Stat() +/mob/living/simple_mob/shadekin/Stat() . = ..() if(statpanel("Shadekin")) abilities_stat() -/mob/living/simple_animal/shadekin/proc/abilities_stat() +/mob/living/simple_mob/shadekin/proc/abilities_stat() for(var/A in shadekin_abilities) var/obj/effect/shadekin_ability/ability = A stat("[ability.ability_name]",ability.atom_button_text()) //They phase back to the dark when killed -/mob/living/simple_animal/shadekin/death(gibbed, deathmessage = "phases to somewhere far away!") +/mob/living/simple_mob/shadekin/death(gibbed, deathmessage = "phases to somewhere far away!") overlays = list() icon_state = "" flick("tp_out",src) @@ -238,7 +238,7 @@ . = ..(FALSE, deathmessage) //Blue-eyes want to nom people to heal them -/mob/living/simple_animal/shadekin/Found(var/atom/A) +/mob/living/simple_mob/shadekin/Found(var/atom/A) if(specific_targets && isliving(A)) //Healing! var/mob/living/L = A var/health_percent = (L.health/L.maxHealth)*100 @@ -247,11 +247,11 @@ . = ..() //They reach nutritional equilibrium (important for blue-eyes healbelly) -/mob/living/simple_animal/shadekin/Life() +/mob/living/simple_mob/shadekin/Life() if((. = ..())) handle_shade() -/mob/living/simple_animal/shadekin/proc/handle_shade() +/mob/living/simple_mob/shadekin/proc/handle_shade() //Shifted kin don't gain/lose energy (and save time if we're at the cap) var/darkness = 1 @@ -330,7 +330,7 @@ energyhud.icon_state = "energy4" //Friendly ones wander towards people, maybe shy-ly if they are set to shy -/mob/living/simple_animal/shadekin/handle_wander_movement() +/mob/living/simple_mob/shadekin/handle_wander_movement() if(isturf(src.loc) && !resting && !buckled && canmove) lifes_since_move++ if(lifes_since_move >= turns_per_move) @@ -384,10 +384,10 @@ Move(T) lifes_since_move = 0 -/mob/living/simple_animal/shadekin/speech_bubble_appearance() +/mob/living/simple_mob/shadekin/speech_bubble_appearance() return "ghost" -/mob/living/simple_animal/shadekin/DoPunch(var/atom/A) +/mob/living/simple_mob/shadekin/DoPunch(var/atom/A) . = ..(A) if(isliving(A)) //We punched something! var/mob/living/L = A @@ -410,7 +410,7 @@ energy += gains //Special hud elements for darkness and energy gains -/mob/living/simple_animal/shadekin/extra_huds(var/datum/hud/hud,var/icon/ui_style,var/list/hud_elements) +/mob/living/simple_mob/shadekin/extra_huds(var/datum/hud/hud,var/icon/ui_style,var/list/hud_elements) //Darkness hud darkhud = new /obj/screen() darkhud.icon = ui_style @@ -430,7 +430,7 @@ hud_elements |= energyhud // When someone clicks us with an empty hand -/mob/living/simple_animal/shadekin/attack_hand(mob/living/carbon/human/M as mob) +/mob/living/simple_mob/shadekin/attack_hand(mob/living/carbon/human/M as mob) . = ..() if(M.a_intent == I_HELP) shy_approach = FALSE //ACCLIMATED diff --git a/code/modules/mob/living/simple_animal/vore/shadekin/types.dm b/code/modules/mob/living/simple_animal/vore/shadekin/types.dm index 6dcf7645c7..b236ec9753 100644 --- a/code/modules/mob/living/simple_animal/vore/shadekin/types.dm +++ b/code/modules/mob/living/simple_animal/vore/shadekin/types.dm @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////// -/mob/living/simple_animal/shadekin/red +/mob/living/simple_mob/shadekin/red name = "red-eyed shadekin" eye_state = RED_EYES hostile = TRUE @@ -28,15 +28,15 @@ a brawl, but you barely generate any of your own energy. You can stand in a dark spot to gather scraps \ of energy in a pinch, but otherwise need to take it, by force if necessary." -/mob/living/simple_animal/shadekin/red/white +/mob/living/simple_mob/shadekin/red/white icon_state = "white" -/mob/living/simple_animal/shadekin/red/dark +/mob/living/simple_mob/shadekin/red/dark icon_state = "dark" -/mob/living/simple_animal/shadekin/red/brown +/mob/living/simple_mob/shadekin/red/brown icon_state = "brown" ///////////////////////////////////////////////////////////////// -/mob/living/simple_animal/shadekin/blue +/mob/living/simple_mob/shadekin/blue name = "blue-eyed shadekin" eye_state = BLUE_EYES health = 100 @@ -75,15 +75,15 @@ without doing so, albeit slowly. Dark and light are irrelevant to you, they are just different places to explore and \ discover new things and new people." -/mob/living/simple_animal/shadekin/blue/white +/mob/living/simple_mob/shadekin/blue/white icon_state = "white" -/mob/living/simple_animal/shadekin/blue/dark +/mob/living/simple_mob/shadekin/blue/dark icon_state = "dark" -/mob/living/simple_animal/shadekin/blue/brown +/mob/living/simple_mob/shadekin/blue/brown icon_state = "brown" ///////////////////////////////////////////////////////////////// -/mob/living/simple_animal/shadekin/purple +/mob/living/simple_mob/shadekin/purple name = "purple-eyed shadekin" eye_state = PURPLE_EYES health = 150 @@ -117,15 +117,15 @@ areas is taxing on your energy. You can harvest energy from others in a fight, but since you don't need to, you may \ just choose to simply not fight." -/mob/living/simple_animal/shadekin/purple/white +/mob/living/simple_mob/shadekin/purple/white icon_state = "white" -/mob/living/simple_animal/shadekin/purple/dark +/mob/living/simple_mob/shadekin/purple/dark icon_state = "dark" -/mob/living/simple_animal/shadekin/purple/brown +/mob/living/simple_mob/shadekin/purple/brown icon_state = "brown" ///////////////////////////////////////////////////////////////// -/mob/living/simple_animal/shadekin/yellow +/mob/living/simple_mob/shadekin/yellow name = "yellow-eyed shadekin" eye_state = YELLOW_EYES health = 100 @@ -157,15 +157,15 @@ area is very taxing on you, but you gain energy extremely fast in any very dark area. You're weaker than other \ shadekin, but your fast energy generation in the dark allows you to phase shift more often." -/mob/living/simple_animal/shadekin/yellow/white +/mob/living/simple_mob/shadekin/yellow/white icon_state = "white" -/mob/living/simple_animal/shadekin/yellow/dark +/mob/living/simple_mob/shadekin/yellow/dark icon_state = "dark" -/mob/living/simple_animal/shadekin/yellow/brown +/mob/living/simple_mob/shadekin/yellow/brown icon_state = "brown" ///////////////////////////////////////////////////////////////// -/mob/living/simple_animal/shadekin/green +/mob/living/simple_mob/shadekin/green name = "green-eyed shadekin" eye_state = GREEN_EYES health = 125 @@ -197,15 +197,15 @@ have more experience than your yellow-eyed cousins. You gain energy decently fast in any very dark area. You're weaker than other \ shadekin, but your slight energy generation constnatly, and especially in the dark allows for a good mix of uses." -/mob/living/simple_animal/shadekin/green/white +/mob/living/simple_mob/shadekin/green/white icon_state = "white" -/mob/living/simple_animal/shadekin/green/dark +/mob/living/simple_mob/shadekin/green/dark icon_state = "dark" -/mob/living/simple_animal/shadekin/green/brown +/mob/living/simple_mob/shadekin/green/brown icon_state = "brown" ///////////////////////////////////////////////////////////////// -/mob/living/simple_animal/shadekin/orange +/mob/living/simple_mob/shadekin/orange name = "orange-eyed shadekin" eye_state = ORANGE_EYES health = 175 @@ -234,16 +234,16 @@ You're stronger than most shadekin, faster, and more capable in a brawl, but you don't generate much of your own energy. \ You can stand in a dark spot to gather some energy, but otherwise need to take it, by force if necessary." -/mob/living/simple_animal/shadekin/orange/white +/mob/living/simple_mob/shadekin/orange/white icon_state = "white" -/mob/living/simple_animal/shadekin/orange/dark +/mob/living/simple_mob/shadekin/orange/dark icon_state = "dark" -/mob/living/simple_animal/shadekin/orange/brown +/mob/living/simple_mob/shadekin/orange/brown icon_state = "brown" ///////////////////////////////////////////////////////////////// //Fluffy specific fluffer -/mob/living/simple_animal/shadekin/blue/rivyr +/mob/living/simple_mob/shadekin/blue/rivyr name = "Rivyr" desc = "She appears to be a fluffer of some sort. Deep blue eyes and curious attitude." icon_state = "rivyr" diff --git a/code/modules/mob/living/simple_animal/vore/snake.dm b/code/modules/mob/living/simple_animal/vore/snake.dm index 8d60989478..9509f4b97e 100644 --- a/code/modules/mob/living/simple_animal/vore/snake.dm +++ b/code/modules/mob/living/simple_animal/vore/snake.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/hostile/giant_snake +/mob/living/simple_mob/hostile/giant_snake name = "giant snake" desc = "Snakes. Why did it have to be snakes?" icon = 'icons/mob/vore64x64.dmi' @@ -21,7 +21,7 @@ pixel_y = -16 // Activate Noms! -/mob/living/simple_animal/hostile/giant_snake +/mob/living/simple_mob/hostile/giant_snake vore_active = 1 vore_pounce_chance = 25 vore_icons = SA_ICON_LIVING diff --git a/code/modules/mob/living/simple_animal/vore/solargrub.dm b/code/modules/mob/living/simple_animal/vore/solargrub.dm index 6e34a1c2d1..94db615ec5 100644 --- a/code/modules/mob/living/simple_animal/vore/solargrub.dm +++ b/code/modules/mob/living/simple_animal/vore/solargrub.dm @@ -10,7 +10,7 @@ List of things solar grubs should be able to do: #define SINK_POWER 1 -/mob/living/simple_animal/retaliate/solargrub +/mob/living/simple_mob/retaliate/solargrub name = "juvenile solargrub" desc = "A young sparkling solargrub" icon = 'icons/mob/vore.dmi' //all of these are placeholders @@ -54,13 +54,13 @@ List of things solar grubs should be able to do: var/obj/structure/cable/attached // the attached cable var/emp_chance = 20 // Beware synths -/mob/living/simple_animal/retaliate/solargrub/PunchTarget() +/mob/living/simple_mob/retaliate/solargrub/PunchTarget() if(target_mob&& prob(emp_chance)) target_mob.emp_act(4) //The weakest strength of EMP visible_message("The grub releases a powerful shock!") ..() -/mob/living/simple_animal/retaliate/solargrub/Life() +/mob/living/simple_mob/retaliate/solargrub/Life() . = ..() if(!. || ai_inactive) return @@ -90,7 +90,7 @@ List of things solar grubs should be able to do: anchored = 0 PN = null -/mob/living/simple_animal/retaliate/solargrub //active noms +/mob/living/simple_mob/retaliate/solargrub //active noms vore_bump_chance = 50 vore_bump_emote = "applies minimal effort to try and slurp up" vore_active = 1 @@ -98,7 +98,7 @@ List of things solar grubs should be able to do: vore_pounce_chance = 0 //grubs only eat incapacitated targets vore_default_mode = DM_DIGEST -/mob/living/simple_animal/retaliate/solargrub/PunchTarget() +/mob/living/simple_mob/retaliate/solargrub/PunchTarget() . = ..() if(isliving(.)) var/mob/living/L = . @@ -107,12 +107,12 @@ List of things solar grubs should be able to do: L << "You feel a shock rushing through your veins." L.reagents.add_reagent(poison_type, poison_per_bite) -/mob/living/simple_animal/retaliate/solargrub/death() +/mob/living/simple_mob/retaliate/solargrub/death() src.anchored = 0 set_light(0) ..() -/mob/living/simple_animal/retaliate/solargrub/handle_light() +/mob/living/simple_mob/retaliate/solargrub/handle_light() . = ..() if(. == 0 && !is_dead()) set_light(2.5, 1, COLOR_YELLOW) diff --git a/code/modules/mob/living/simple_animal/vore/solargrub_larva.dm b/code/modules/mob/living/simple_animal/vore/solargrub_larva.dm index d97c12dd33..0fd32be6ee 100644 --- a/code/modules/mob/living/simple_animal/vore/solargrub_larva.dm +++ b/code/modules/mob/living/simple_animal/vore/solargrub_larva.dm @@ -1,6 +1,6 @@ var/global/list/grub_machine_overlays = list() -/mob/living/simple_animal/solargrub_larva +/mob/living/simple_mob/solargrub_larva name = "solargrub larva" desc = "A tiny wormy thing that can grow to massive sizes under the right conditions." icon = 'icons/mob/vore.dmi' @@ -10,7 +10,7 @@ var/global/list/grub_machine_overlays = list() health = 5 maxHealth = 5 - + meat_amount = 2 meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/grubmeat @@ -43,7 +43,7 @@ var/global/list/grub_machine_overlays = list() var/power_drained = 0 var/forced_out = 0 -/mob/living/simple_animal/solargrub_larva/New() +/mob/living/simple_mob/solargrub_larva/New() ..() powermachine = new(src) sparks = new(src) @@ -51,19 +51,19 @@ var/global/list/grub_machine_overlays = list() sparks.attach(src) verbs += /mob/living/proc/ventcrawl -/mob/living/simple_animal/solargrub_larva/death() +/mob/living/simple_mob/solargrub_larva/death() powermachine.draining = 0 set_light(0) return ..() -/mob/living/simple_animal/solargrub_larva/Destroy() +/mob/living/simple_mob/solargrub_larva/Destroy() QDEL_NULL(powermachine) QDEL_NULL(sparks) QDEL_NULL(machine_effect) target_vent = null return ..() -/mob/living/simple_animal/solargrub_larva/Life() +/mob/living/simple_mob/solargrub_larva/Life() . = ..() if(machine_effect && !istype(loc, /obj/machinery)) @@ -129,7 +129,7 @@ var/global/list/grub_machine_overlays = list() WanderTowards(get_turf(picked)) return -/mob/living/simple_animal/solargrub_larva/proc/enter_machine(var/obj/machinery/M) +/mob/living/simple_mob/solargrub_larva/proc/enter_machine(var/obj/machinery/M) if(!istype(M)) return forceMove(M) @@ -141,13 +141,13 @@ var/global/list/grub_machine_overlays = list() for(var/mob/L in player_list) //because nearly every machine updates its icon by removing all overlays first L << machine_effect -/mob/living/simple_animal/solargrub_larva/proc/generate_machine_effect(var/obj/machinery/M) +/mob/living/simple_mob/solargrub_larva/proc/generate_machine_effect(var/obj/machinery/M) var/icon/I = new /icon(M.icon, M.icon_state) I.Blend(new /icon('icons/effects/blood.dmi', rgb(255,255,255)),ICON_ADD) I.Blend(new /icon('icons/effects/alert.dmi', "_red"),ICON_MULTIPLY) grub_machine_overlays[M.type] = I -/mob/living/simple_animal/solargrub_larva/proc/eject_from_machine(var/obj/machinery/M) +/mob/living/simple_mob/solargrub_larva/proc/eject_from_machine(var/obj/machinery/M) if(!M) if(istype(loc, /obj/machinery)) M = loc @@ -160,7 +160,7 @@ var/global/list/grub_machine_overlays = list() forced_out += rand(5,15) powermachine.draining = 1 -/mob/living/simple_animal/solargrub_larva/proc/do_ventcrawl(var/obj/machinery/atmospherics/unary/vent_pump/vent) +/mob/living/simple_mob/solargrub_larva/proc/do_ventcrawl(var/obj/machinery/atmospherics/unary/vent_pump/vent) if(!vent) return var/obj/machinery/atmospherics/unary/vent_pump/end_vent = get_safe_ventcrawl_target(vent) @@ -184,15 +184,15 @@ var/global/list/grub_machine_overlays = list() playsound(end_vent, 'sound/machines/ventcrawl.ogg', 50, 1, -3) forceMove(get_turf(end_vent)) -/mob/living/simple_animal/solargrub_larva/proc/expand_grub() +/mob/living/simple_mob/solargrub_larva/proc/expand_grub() eject_from_machine() visible_message("\The [src] suddenly balloons in size!") - new /mob/living/simple_animal/retaliate/solargrub(get_turf(src)) -// var/mob/living/simple_animal/retaliate/solargrub/grub = new(get_turf(src)) + new /mob/living/simple_mob/retaliate/solargrub(get_turf(src)) +// var/mob/living/simple_mob/retaliate/solargrub/grub = new(get_turf(src)) // grub.power_drained = power_drained //TODO qdel(src) -/mob/living/simple_animal/solargrub_larva/handle_light() +/mob/living/simple_mob/solargrub_larva/handle_light() . = ..() if(. == 0 && !is_dead()) set_light(1.5, 1, COLOR_YELLOW) @@ -205,7 +205,7 @@ var/global/list/grub_machine_overlays = list() var/total_idle_power_usage = 3 KILOWATTS var/list/idle_power_usages = list(1 KILOWATTS, 1 KILOWATTS, 1 KILOWATTS) var/draining = 1 - var/mob/living/simple_animal/solargrub_larva/grub + var/mob/living/simple_mob/solargrub_larva/grub /obj/machinery/abstract_grub_machine/New() ..() @@ -248,7 +248,7 @@ var/global/list/grub_machine_overlays = list() /obj/item/device/multitool/afterattack(obj/O, mob/user, proximity) if(proximity) if(istype(O, /obj/machinery)) - var/mob/living/simple_animal/solargrub_larva/grub = locate() in O + var/mob/living/simple_mob/solargrub_larva/grub = locate() in O if(grub) grub.eject_from_machine(O) to_chat(user, "You disturb a grub nesting in \the [O]!") diff --git a/code/modules/mob/living/simple_animal/vore/wolf.dm b/code/modules/mob/living/simple_animal/vore/wolf.dm index fe3a970ac0..ac286b2f1d 100644 --- a/code/modules/mob/living/simple_animal/vore/wolf.dm +++ b/code/modules/mob/living/simple_animal/vore/wolf.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/hostile/wolf +/mob/living/simple_mob/hostile/wolf name = "grey wolf" desc = "My, what big jaws it has!" tt_desc = "Canis lupus" @@ -22,6 +22,6 @@ minbodytemp = 200 // Activate Noms! -/mob/living/simple_animal/hostile/wolf +/mob/living/simple_mob/hostile/wolf vore_active = 1 vore_icons = SA_ICON_LIVING diff --git a/code/modules/mob/living/simple_animal/vore/wolfgirl.dm b/code/modules/mob/living/simple_animal/vore/wolfgirl.dm index 301b4e6dc5..152ba5b1c8 100644 --- a/code/modules/mob/living/simple_animal/vore/wolfgirl.dm +++ b/code/modules/mob/living/simple_animal/vore/wolfgirl.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/retaliate/wolfgirl +/mob/living/simple_mob/retaliate/wolfgirl name = "wolfgirl" desc = "AwooOOOOoooo!" tt_desc = "Homo lupus" @@ -48,7 +48,7 @@ var/loopstop = 0 //To prevent circular awoooos. -/mob/living/simple_animal/retaliate/wolfgirl/hear_say() +/mob/living/simple_mob/retaliate/wolfgirl/hear_say() if(world.time - loopstop < 5 SECONDS) return else @@ -56,7 +56,7 @@ ..() // Activate Noms! -/mob/living/simple_animal/retaliate/wolfgirl +/mob/living/simple_mob/retaliate/wolfgirl vore_active = 1 vore_pounce_chance = 40 vore_icons = SA_ICON_LIVING diff --git a/code/modules/mob/living/simple_animal/vore/zz_vore_overrides.dm b/code/modules/mob/living/simple_animal/vore/zz_vore_overrides.dm index fb4d74d360..5fbf002795 100644 --- a/code/modules/mob/living/simple_animal/vore/zz_vore_overrides.dm +++ b/code/modules/mob/living/simple_animal/vore/zz_vore_overrides.dm @@ -3,12 +3,12 @@ // /* -## For anything that previously inhertited from: /mob/living/simple_animal/hostile/vore ## +## For anything that previously inhertited from: /mob/living/simple_mob/hostile/vore ## vore_active = 1 icon = 'icons/mob/vore.dmi' -## For anything that previously inhertied from: /mob/living/simple_animal/hostile/vore/large ## +## For anything that previously inhertied from: /mob/living/simple_mob/hostile/vore/large ## vore_active = 1 icon = 'icons/mob/vore64x64.dmi' @@ -23,7 +23,7 @@ // Okay! Here we go! // -/mob/living/simple_animal/hostile/alien +/mob/living/simple_mob/hostile/alien vore_active = 1 icon = 'icons/mob/vore.dmi' icon_state = "xenohunter" @@ -32,7 +32,7 @@ icon_gib = "gibbed-a" vore_icons = SA_ICON_LIVING -/mob/living/simple_animal/hostile/alien/drone +/mob/living/simple_mob/hostile/alien/drone vore_active = 1 icon = 'icons/mob/vore.dmi' icon_state = "xenodrone" @@ -41,7 +41,7 @@ icon_gib = "gibbed-a" vore_icons = SA_ICON_LIVING -/mob/living/simple_animal/hostile/alien/sentinel +/mob/living/simple_mob/hostile/alien/sentinel vore_active = 1 icon = 'icons/mob/vore.dmi' icon_state = "xenosentinel" @@ -50,7 +50,7 @@ icon_gib = "gibbed-a" vore_icons = SA_ICON_LIVING -/mob/living/simple_animal/hostile/alien/queen +/mob/living/simple_mob/hostile/alien/queen vore_active = 1 icon = 'icons/mob/vore.dmi' icon_state = "xenoqueen" @@ -59,7 +59,7 @@ icon_gib = "gibbed-a" vore_icons = SA_ICON_LIVING -/mob/living/simple_animal/hostile/alien/queen/empress +/mob/living/simple_mob/hostile/alien/queen/empress vore_active = 1 icon = 'icons/mob/vore64x64.dmi' icon_state = "queen_s" @@ -75,14 +75,14 @@ vore_capacity = 3 vore_pounce_chance = 75 -/mob/living/simple_animal/hostile/alien/sentinel/praetorian +/mob/living/simple_mob/hostile/alien/sentinel/praetorian icon = 'icons/mob/vore64x64.dmi' vore_icons = SA_ICON_LIVING | SA_ICON_REST -/mob/living/simple_animal/hostile/alien/queen/empress/mother +/mob/living/simple_mob/hostile/alien/queen/empress/mother vore_icons = 0 // NO VORE SPRITES -/mob/living/simple_animal/hostile/bear +/mob/living/simple_mob/hostile/bear vore_active = 1 icon = 'icons/mob/vore.dmi' icon_state = "spacebear" @@ -91,10 +91,10 @@ icon_gib = "bear-gib" vore_icons = SA_ICON_LIVING -/mob/living/simple_animal/hostile/bear/hudson +/mob/living/simple_mob/hostile/bear/hudson name = "Hudson" -/mob/living/simple_animal/hostile/bear/brown +/mob/living/simple_mob/hostile/bear/brown vore_active = 1 icon = 'icons/mob/vore.dmi' name = "brown bear" @@ -104,12 +104,12 @@ icon_gib = "bear-gib" vore_icons = SA_ICON_LIVING -/mob/living/simple_animal/hostile/carp +/mob/living/simple_mob/hostile/carp icon = 'icons/mob/vore.dmi' vore_active = 1 vore_icons = SA_ICON_LIVING -/mob/living/simple_animal/hostile/creature/vore +/mob/living/simple_mob/hostile/creature/vore vore_active = 1 // NO VORE SPRITES vore_capacity = 0 @@ -120,7 +120,7 @@ health = 80 // Increase health to compensate maxHealth = 80 -/mob/living/simple_animal/hostile/mimic +/mob/living/simple_mob/hostile/mimic vore_active = 1 // NO VORE SPRITES vore_capacity = 0 @@ -129,42 +129,42 @@ maxHealth = 60 health = 60 -/mob/living/simple_animal/cat +/mob/living/simple_mob/cat vore_active = 1 // NO VORE SPRITES specific_targets = 0 // Targeting UNLOCKED vore_max_size = RESIZE_TINY -/mob/living/simple_animal/cat/PunchTarget() - if(istype(target_mob,/mob/living/simple_animal/mouse)) +/mob/living/simple_mob/cat/PunchTarget() + if(istype(target_mob,/mob/living/simple_mob/mouse)) visible_message("\The [src] pounces on \the [target_mob]!]") target_mob.Stun(5) return EatTarget() else ..() -/mob/living/simple_animal/cat/Found(var/atom/found_atom) +/mob/living/simple_mob/cat/Found(var/atom/found_atom) if(!SA_attackable(found_atom)) return null - if(istype(found_atom,/mob/living/simple_animal/mouse)) + if(istype(found_atom,/mob/living/simple_mob/mouse)) return found_atom if(found_atom in friends) return null if(will_eat(found_atom)) return found_atom -/mob/living/simple_animal/cat/fluff/Found(var/atom/found_atom) +/mob/living/simple_mob/cat/fluff/Found(var/atom/found_atom) if (friend == found_atom) return null return ..() -/mob/living/simple_animal/cat/fluff +/mob/living/simple_mob/cat/fluff vore_ignores_undigestable = 0 vore_pounce_chance = 100 vore_digest_chance = 0 // just use the toggle vore_default_mode = DM_HOLD //can use the toggle if you wanna be catfood vore_standing_too = TRUE //gonna get pounced -/mob/living/simple_animal/cat/fluff/EatTarget() +/mob/living/simple_mob/cat/fluff/EatTarget() var/mob/living/TM = target_mob prey_excludes += TM //so they won't immediately re-eat someone who struggles out (or gets newspapered out) as soon as they're ate spawn(3600) // but if they hang around and get comfortable, they might get ate again @@ -172,39 +172,39 @@ prey_excludes -= TM ..() // will_eat check is carried out before EatTarget is called, so prey on the prey_excludes list isn't a problem. -/mob/living/simple_animal/fox +/mob/living/simple_mob/fox vore_active = 1 // NO VORE SPRITES vore_max_size = RESIZE_TINY -/mob/living/simple_animal/fox/PunchTarget() - if(istype(target_mob,/mob/living/simple_animal/mouse)) +/mob/living/simple_mob/fox/PunchTarget() + if(istype(target_mob,/mob/living/simple_mob/mouse)) return EatTarget() else ..() -/mob/living/simple_animal/fox/Found(var/atom/found_atom) +/mob/living/simple_mob/fox/Found(var/atom/found_atom) if(!SA_attackable(found_atom)) return null - if(istype(found_atom,/mob/living/simple_animal/mouse)) + if(istype(found_atom,/mob/living/simple_mob/mouse)) return found_atom if(found_atom in friends) return null if(will_eat(found_atom)) return found_atom -/mob/living/simple_animal/fox/fluff/Found(var/atom/found_atom) +/mob/living/simple_mob/fox/fluff/Found(var/atom/found_atom) if (friend == found_atom) return null return ..() -/mob/living/simple_animal/fox/fluff +/mob/living/simple_mob/fox/fluff vore_ignores_undigestable = 0 vore_pounce_chance = 100 vore_digest_chance = 0 // just use the toggle vore_default_mode = DM_HOLD //can use the toggle if you wanna be foxfood vore_standing_too = TRUE // gonna get pounced -/mob/living/simple_animal/fox/fluff/EatTarget() +/mob/living/simple_mob/fox/fluff/EatTarget() var/mob/living/TM = target_mob prey_excludes += TM //so they won't immediately re-eat someone who struggles out (or gets newspapered out) as soon as they're ate spawn(3600) // but if they hang around and get comfortable, they might get ate again @@ -212,39 +212,39 @@ prey_excludes -= TM ..() // will_eat check is carried out before EatTarget is called, so prey on the prey_excludes list isn't a problem. -/mob/living/simple_animal/hostile/goose +/mob/living/simple_mob/hostile/goose vore_active = 1 // NO VORE SPRITES vore_max_size = RESIZE_SMALL -/mob/living/simple_animal/penguin +/mob/living/simple_mob/penguin vore_active = 1 // NO VORE SPRITES vore_max_size = RESIZE_SMALL -/mob/living/simple_animal/hostile/carp/pike +/mob/living/simple_mob/hostile/carp/pike vore_active = 1 // NO VORE SPRITES -/mob/living/simple_animal/hostile/carp/holodeck +/mob/living/simple_mob/hostile/carp/holodeck vore_icons = 0 // NO VORE SPRITES vore_digest_chance = 0 vore_absorb_chance = 0 // Override stuff for holodeck carp to make them not digest when set to safe! -/mob/living/simple_animal/hostile/carp/holodeck/init_vore() +/mob/living/simple_mob/hostile/carp/holodeck/init_vore() . = ..() var/safe = (faction == "neutral") for(var/belly in vore_organs) var/obj/belly/B = belly B.digest_mode = safe ? DM_HOLD : vore_default_mode -/mob/living/simple_animal/hostile/carp/holodeck/set_safety(var/safe) +/mob/living/simple_mob/hostile/carp/holodeck/set_safety(var/safe) . = ..() for(var/belly in vore_organs) var/obj/belly/B = belly B.digest_mode = safe ? DM_HOLD : vore_default_mode -/mob/living/simple_animal/mouse +/mob/living/simple_mob/mouse faction = "mouse" //Giving mice a faction so certain mobs can get along with them. \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/appearance.dm b/code/modules/mob/living/simple_mob/appearance.dm new file mode 100644 index 0000000000..05f758d7c4 --- /dev/null +++ b/code/modules/mob/living/simple_mob/appearance.dm @@ -0,0 +1,76 @@ +/mob/living/simple_mob/update_icon() + . = ..() + cut_overlays() +// var/mutable_appearance/ma = new(src) +// ma.layer = layer +// ma.plane = plane + + add_overlay(modifier_overlay) + + if(!icon_living) // Prevent the mob from turning invisible if icon_living is null. + icon_living = initial(icon_state) + + //Awake and normal + if((stat == CONSCIOUS) && (!icon_rest || !resting || !incapacitated(INCAPACITATION_DISABLED) )) + icon_state = icon_living + + //Dead + else if(stat >= DEAD) + icon_state = icon_dead + + //Resting or KO'd + else if(((stat == UNCONSCIOUS) || resting || incapacitated(INCAPACITATION_DISABLED) ) && icon_rest) + icon_state = icon_rest + + //Backup + else + icon_state = initial(icon_state) + + if(has_hands) + if(r_hand_sprite) + add_overlay(r_hand_sprite) + if(l_hand_sprite) + add_overlay(l_hand_sprite) + + if(has_eye_glow) + if(icon_state != icon_living) + remove_eyes() + else + add_eyes() + +// appearance = ma + + +// If your simple mob's update_icon() call calls overlays.Cut(), this needs to be called after this, or manually apply modifier_overly to overlays. +/mob/living/simple_mob/update_modifier_visuals() + var/image/effects = null + if(modifier_overlay) + cut_overlay(modifier_overlay) + modifier_overlay.cut_overlays() + effects = modifier_overlay + else + effects = new() + + for(var/datum/modifier/M in modifiers) + if(M.mob_overlay_state) + var/image/I = image("icon" = 'icons/mob/modifier_effects.dmi', "icon_state" = M.mob_overlay_state) + I.appearance_flags = RESET_COLOR // So colored mobs don't affect the overlay. + effects.add_overlay(I) + + modifier_overlay = effects + add_overlay(modifier_overlay) + + +/mob/living/simple_mob/proc/add_eyes() + if(!eye_layer) + eye_layer = image(icon, "[icon_state]-eyes") + eye_layer.plane = PLANE_LIGHTING_ABOVE + + add_overlay(eye_layer) + +/mob/living/simple_mob/proc/remove_eyes() + cut_overlay(eye_layer) + + +/mob/living/simple_mob/gib() + ..(icon_gib,1,icon) // we need to specify where the gib animation is stored \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/combat.dm b/code/modules/mob/living/simple_mob/combat.dm new file mode 100644 index 0000000000..8cb60cd177 --- /dev/null +++ b/code/modules/mob/living/simple_mob/combat.dm @@ -0,0 +1,238 @@ +// Does a melee attack. +/mob/living/simple_mob/proc/attack_target(atom/A) + set waitfor = FALSE // For attack animations. Don't want the AI processor to get held up. + + if(!A.Adjacent(src)) + return FALSE + var/turf/their_T = get_turf(A) + + face_atom(A) + + if(melee_attack_delay) + // their_T.color = "#FF0000" + melee_pre_animation(A) + handle_attack_delay(A, melee_attack_delay) // This will sleep this proc for a bit, which is why waitfor is false. + + // Cooldown testing is done at click code (for players) and interface code (for AI). + setClickCooldown(get_attack_speed()) + + . = do_attack(A, their_T) + + if(melee_attack_delay) + melee_post_animation(A) + // their_T.color = "#FFFFFF" + + + +// This does the actual attack. +// This is a seperate proc for the purposes of attack animations. +// A is the thing getting attacked, T is the turf A is/was on when attack_target was called. +/mob/living/simple_mob/proc/do_attack(atom/A, turf/T) + face_atom(A) + var/missed = FALSE + if(!isturf(A) && !(A in T) ) // Turfs don't contain themselves so checking contents is pointless if we're targeting a turf. + missed = TRUE + else if(!T.AdjacentQuick(src)) + missed = TRUE + + if(missed) // Most likely we have a slow attack and they dodged it or we somehow got moved. + add_attack_logs(src, A, "Animal-attacked (dodged)", admin_notify = FALSE) + playsound(src, 'sound/weapons/punchmiss.ogg', 75, 1) + visible_message(span("warning", "\The [src] misses their attack.")) + return FALSE + + var/damage_to_do = rand(melee_damage_lower, melee_damage_upper) + + damage_to_do = apply_bonus_melee_damage(A, damage_to_do) + + for(var/datum/modifier/M in modifiers) + if(!isnull(M.outgoing_melee_damage_percent)) + damage_to_do *= M.outgoing_melee_damage_percent + + if(isliving(A)) // Check defenses. + var/mob/living/L = A + + if(prob(melee_miss_chance)) + add_attack_logs(src, L, "Animal-attacked (miss)", admin_notify = FALSE) + do_attack_animation(src) + playsound(src, 'sound/weapons/punchmiss.ogg', 75, 1) + return FALSE // We missed. + + if(ishuman(L)) + var/mob/living/carbon/human/H = L + if(H.check_shields(damage = damage_to_do, damage_source = src, attacker = src, def_zone = null, attack_text = "the attack")) + return FALSE // We were blocked. + + if(apply_attack(A, damage_to_do)) + apply_melee_effects(A) + if(attack_sound) + playsound(src, attack_sound, 75, 1) + + return TRUE + +// Generally used to do the regular attack. +// Override for doing special stuff with the direct result of the attack. +/mob/living/simple_mob/proc/apply_attack(atom/A, damage_to_do) + return A.attack_generic(src, damage_to_do, pick(attacktext)) + +// Override for special effects after a successful attack, like injecting poison or stunning the target. +/mob/living/simple_mob/proc/apply_melee_effects(atom/A) + return + +// Override to modify the amount of damage the mob does conditionally. +// This must return the amount of outgoing damage. +// Note that this is done before mob modifiers scale the damage. +/mob/living/simple_mob/proc/apply_bonus_melee_damage(atom/A, damage_amount) + return damage_amount + +//The actual top-level ranged attack proc +/mob/living/simple_mob/proc/shoot_target(atom/A) + set waitfor = FALSE + setClickCooldown(get_attack_speed()) + + face_atom(A) + + if(ranged_attack_delay) + ranged_pre_animation(A) + handle_attack_delay(A, ranged_attack_delay) // This will sleep this proc for a bit, which is why waitfor is false. + + if(needs_reload) + if(reload_count >= reload_max) + try_reload() + return FALSE + + visible_message("\The [src] fires at \the [A]!") + shoot(A) + if(casingtype) + new casingtype(loc) + + if(ranged_attack_delay) + ranged_post_animation(A) + + return TRUE + + +// Shoot a bullet at something. +/mob/living/simple_mob/proc/shoot(atom/A) + if(A == get_turf(src)) + return + + face_atom(A) + + var/obj/item/projectile/P = new projectiletype(src.loc) + if(!P) + return + + // If the projectile has its own sound, use it. + // Otherwise default to the mob's firing sound. + playsound(src, P.fire_sound ? P.fire_sound : projectilesound, 80, 1) + + P.firer = src // So we can't shoot ourselves. + P.old_style_target(A, src) + P.fire() + if(needs_reload) + reload_count++ + +// if(distance >= special_attack_min_range && distance <= special_attack_max_range) +// return TRUE + +/mob/living/simple_mob/proc/try_reload() + set waitfor = FALSE + set_AI_busy(TRUE) + + if(do_after(src, reload_time)) + if(reload_sound) + playsound(src.loc, reload_sound, 50, 1) + reload_count = 0 + . = TRUE + else + . = FALSE + set_AI_busy(FALSE) + +// Can we currently do a special attack? +/mob/living/simple_mob/proc/can_special_attack(atom/A) + // Validity check. + if(!istype(A)) + return FALSE + + // Ability check. + if(isnull(special_attack_min_range) || isnull(special_attack_max_range)) + return FALSE + + // Distance check. + var/distance = get_dist(src, A) + if(distance < special_attack_min_range || distance > special_attack_max_range) + return FALSE + + // Cooldown check. + if(!isnull(special_attack_cooldown) && last_special_attack + special_attack_cooldown > world.time) + return FALSE + + // Charge check. + if(!isnull(special_attack_charges) && special_attack_charges <= 0) + return FALSE + + return TRUE + +// Should we do one? Used to make the AI not waste their special attacks. Only checked for AI. Players are free to screw up on their own. +/mob/living/simple_mob/proc/should_special_attack(atom/A) + return TRUE + +// Special attacks, like grenades or blinding spit or whatever. +// Don't override this, override do_special_attack() for your blinding spit/etc. +/mob/living/simple_mob/proc/special_attack_target(atom/A) + face_atom(A) + + if(special_attack_delay) + special_pre_animation(A) + handle_attack_delay(A, special_attack_delay) // This will sleep this proc for a bit, which is why waitfor is false. + + last_special_attack = world.time + if(do_special_attack(A)) + if(special_attack_charges) + special_attack_charges -= 1 + . = TRUE + else + . = FALSE + + if(special_attack_delay) + special_post_animation(A) + +// Override this for the actual special attack. +/mob/living/simple_mob/proc/do_special_attack(atom/A) + return FALSE + +// Sleeps the proc that called it for the correct amount of time. +// Also makes sure the AI doesn't do anything stupid in the middle of the delay. +/mob/living/simple_mob/proc/handle_attack_delay(atom/A, delay_amount) + set_AI_busy(TRUE) + + // Click delay modifiers also affect telegraphing time. + // This means berserked enemies will leave less time to dodge. + var/true_attack_delay = delay_amount + for(var/datum/modifier/M in modifiers) + if(!isnull(M.attack_speed_percent)) + true_attack_delay *= M.attack_speed_percent + + setClickCooldown(true_attack_delay) // Insurance against a really long attack being longer than default click delay. + + sleep(true_attack_delay) + + set_AI_busy(FALSE) + + +// Override these four for special custom animations (like the GOLEM). +/mob/living/simple_mob/proc/melee_pre_animation(atom/A) + do_windup_animation(A, melee_attack_delay) + +/mob/living/simple_mob/proc/melee_post_animation(atom/A) + +/mob/living/simple_mob/proc/ranged_pre_animation(atom/A) + do_windup_animation(A, ranged_attack_delay) // Semi-placeholder. + +/mob/living/simple_mob/proc/ranged_post_animation(atom/A) + +/mob/living/simple_mob/proc/special_pre_animation(atom/A) + do_windup_animation(A, special_attack_delay) // Semi-placeholder. + +/mob/living/simple_mob/proc/special_post_animation(atom/A) \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/defense.dm b/code/modules/mob/living/simple_mob/defense.dm new file mode 100644 index 0000000000..744237b21d --- /dev/null +++ b/code/modules/mob/living/simple_mob/defense.dm @@ -0,0 +1,235 @@ +// Hit by a projectile. +/mob/living/simple_mob/bullet_act(var/obj/item/projectile/P) + //Projectiles with bonus SA damage + if(!P.nodamage) + // if(!P.SA_vulnerability || P.SA_vulnerability == intelligence_level) + if(P.SA_vulnerability & mob_class) + P.damage += P.SA_bonus_damage + + . = ..() + + +// When someone clicks us with an empty hand +/mob/living/simple_mob/attack_hand(mob/living/L) + ..() + + switch(L.a_intent) + if(I_HELP) + if(health > 0) + L.visible_message("\The [L] [response_help] \the [src].") + + if(I_DISARM) + L.visible_message("\The [L] [response_disarm] \the [src].") + L.do_attack_animation(src) + //TODO: Push the mob away or something + + if(I_GRAB) + if (L == src) + return + if (!(status_flags & CANPUSH)) + return + if(!incapacitated(INCAPACITATION_ALL) && prob(grab_resist)) + L.visible_message("\The [L] tries to grab \the [src] but fails!") + return + + var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(L, src) + + L.put_in_active_hand(G) + + G.synch() + G.affecting = src + LAssailant = L + + L.visible_message("\The [L] has grabbed [src] passively!") + L.do_attack_animation(src) + + if(I_HURT) + var/armor = run_armor_check(def_zone = null, attack_flag = "melee") + apply_damage(damage = harm_intent_damage, damagetype = BURN, def_zone = null, blocked = armor, blocked = resistance, used_weapon = null, sharp = FALSE, edge = FALSE) + L.visible_message("\The [L] [response_harm] \the [src]!") + L.do_attack_animation(src) + + return + + +// When somoene clicks us with an item in hand +/mob/living/simple_mob/attackby(var/obj/item/O, var/mob/user) + if(istype(O, /obj/item/stack/medical)) + if(stat != DEAD) + // This could be done better. + var/obj/item/stack/medical/MED = O + if(health < getMaxHealth()) + if(MED.amount >= 1) + adjustBruteLoss(-MED.heal_brute) + MED.amount -= 1 + if(MED.amount <= 0) + qdel(MED) + visible_message("\The [user] applies the [MED] on [src].") + else + var/datum/gender/T = gender_datums[src.get_visible_gender()] + to_chat(user, "\The [src] is dead, medical items won't bring [T.him] back to life.") // the gender lookup is somewhat overkill, but it functions identically to the obsolete gender macros and future-proofs this code + if(meat_type && (stat == DEAD)) //if the animal has a meat, and if it is dead. + if(istype(O, /obj/item/weapon/material/knife)) + harvest(user) + + return ..() + + +// Handles the actual harming by a melee weapon. +/mob/living/simple_mob/hit_with_weapon(obj/item/O, mob/living/user, var/effective_force, var/hit_zone) + effective_force = O.force + + //Animals can't be stunned(?) + if(O.damtype == HALLOSS) + effective_force = 0 + if(supernatural && istype(O,/obj/item/weapon/nullrod)) + effective_force *= 2 + purge = 3 + if(O.force <= resistance) + to_chat(user,"This weapon is ineffective, it does no damage.") + return 2 //??? + + . = ..() + + +// Exploding. +/mob/living/simple_mob/ex_act(severity) + if(!blinded) + flash_eyes() + var/armor = run_armor_check(def_zone = null, attack_flag = "bomb") + var/bombdam = 500 + switch (severity) + if (1.0) + bombdam = 500 + if (2.0) + bombdam = 60 + if (3.0) + bombdam = 30 + + apply_damage(damage = bombdam, damagetype = BRUTE, def_zone = null, blocked = armor, blocked = resistance, used_weapon = null, sharp = FALSE, edge = FALSE) + + if(bombdam > maxHealth) + gib() + +// Cold stuff. +/mob/living/simple_mob/get_cold_protection() + return cold_resist + + +// Fire stuff. Not really exciting at the moment. +/mob/living/simple_mob/handle_fire() + return +/mob/living/simple_mob/update_fire() + return +/mob/living/simple_mob/IgniteMob() + return +/mob/living/simple_mob/ExtinguishMob() + return + +/mob/living/simple_mob/get_heat_protection() + return heat_resist + +// Electricity +/mob/living/simple_mob/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0, var/def_zone = null) + shock_damage *= siemens_coeff + if(shock_damage < 1) + return 0 + + apply_damage(damage = shock_damage, damagetype = BURN, def_zone = null, blocked = null, blocked = resistance, used_weapon = null, sharp = FALSE, edge = FALSE) + playsound(loc, "sparks", 50, 1, -1) + + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(5, 1, loc) + s.start() + +/mob/living/simple_mob/get_shock_protection() + return shock_resist + +// Shot with taser/stunvolver +/mob/living/simple_mob/stun_effect_act(var/stun_amount, var/agony_amount, var/def_zone, var/used_weapon=null) + if(taser_kill) + var/stunDam = 0 + var/agonyDam = 0 + var/armor = run_armor_check(def_zone = null, attack_flag = "energy") + + if(stun_amount) + stunDam += stun_amount * 0.5 + apply_damage(damage = stunDam, damagetype = BURN, def_zone = null, blocked = armor, blocked = resistance, used_weapon = used_weapon, sharp = FALSE, edge = FALSE) + + if(agony_amount) + agonyDam += agony_amount * 0.5 + apply_damage(damage = agonyDam, damagetype = BURN, def_zone = null, blocked = armor, blocked = resistance, used_weapon = used_weapon, sharp = FALSE, edge = FALSE) + + +// Electromagnetism +/mob/living/simple_mob/emp_act(severity) + ..() // To emp_act() its contents. + if(!isSynthetic()) + return + switch(severity) + if(1) + // adjustFireLoss(rand(15, 25)) + adjustFireLoss(min(60, getMaxHealth()*0.5)) // Weak mobs will always take two direct EMP hits to kill. Stronger ones might take more. + if(2) + adjustFireLoss(min(30, getMaxHealth()*0.25)) + // adjustFireLoss(rand(10, 18)) + if(3) + adjustFireLoss(min(15, getMaxHealth()*0.125)) + // adjustFireLoss(rand(5, 12)) + if(4) + adjustFireLoss(min(7, getMaxHealth()*0.0625)) + // adjustFireLoss(rand(1, 6)) + +// Water +/mob/living/simple_mob/get_water_protection() + return water_resist + +// "Poison" (aka what reagents would do if we wanted to deal with those). +/mob/living/simple_mob/get_poison_protection() + return poison_resist + +// Armor +/mob/living/simple_mob/getarmor(def_zone, attack_flag) + var/armorval = armor[attack_flag] + if(!armorval) + return 0 + else + return armorval + +/mob/living/simple_mob/getsoak(def_zone, attack_flag) + var/armorval = armor_soak[attack_flag] + if(!armorval) + return 0 + else + return armorval + +// Lightning +/mob/living/simple_mob/lightning_act() + ..() + // If a non-player simple_mob was struck, inflict huge damage. + // If the damage is fatal, it is turned to ash. + if(!client) + inflict_shock_damage(200) // Mobs that are very beefy or resistant to shock may survive getting struck. + updatehealth() + if(health <= 0) + visible_message(span("critical", "\The [src] disintegrates into ash!")) + ash() + return // No point deafening something that wont exist. + +// Lava +/mob/living/simple_mob/lava_act() + ..() + // Similar to lightning, the mob is turned to ash if the lava tick was fatal and it isn't a player. + // Unlike lightning, we don't add an additional damage spike (since lava already hurts a lot). + if(!client) + updatehealth() + if(health <= 0) + visible_message(span("critical", "\The [src] flashes into ash as the lava consumes them!")) + ash() + +// Injections. +/mob/living/simple_mob/can_inject(mob/user, error_msg, target_zone, ignore_thickness) + if(ignore_thickness) + return TRUE + return !thick_armor + diff --git a/code/modules/mob/living/simple_mob/hands.dm b/code/modules/mob/living/simple_mob/hands.dm new file mode 100644 index 0000000000..0e8820fe2e --- /dev/null +++ b/code/modules/mob/living/simple_mob/hands.dm @@ -0,0 +1,143 @@ +// Hand procs for player-controlled SA's +/mob/living/simple_mob/swap_hand() + src.hand = !( src.hand ) + if(hud_used.l_hand_hud_object && hud_used.r_hand_hud_object) + if(hand) //This being 1 means the left hand is in use + hud_used.l_hand_hud_object.icon_state = "l_hand_active" + hud_used.r_hand_hud_object.icon_state = "r_hand_inactive" + else + hud_used.l_hand_hud_object.icon_state = "l_hand_inactive" + hud_used.r_hand_hud_object.icon_state = "r_hand_active" + return + +/mob/living/simple_mob/put_in_hands(var/obj/item/W) // No hands. + if(has_hands) + put_in_active_hand(W) + return 1 + W.forceMove(get_turf(src)) + return 1 + +//Puts the item into our active hand if possible. returns 1 on success. +/mob/living/simple_mob/put_in_active_hand(var/obj/item/W) + if(!has_hands) + return FALSE + return (hand ? put_in_l_hand(W) : put_in_r_hand(W)) + +/mob/living/simple_mob/put_in_l_hand(var/obj/item/W) + if(!..() || l_hand) + return 0 + W.forceMove(src) + l_hand = W + W.equipped(src,slot_l_hand) + W.add_fingerprint(src) + update_inv_l_hand() + return TRUE + +/mob/living/simple_mob/put_in_r_hand(var/obj/item/W) + if(!..() || r_hand) + return 0 + W.forceMove(src) + r_hand = W + W.equipped(src,slot_r_hand) + W.add_fingerprint(src) + update_inv_r_hand() + return TRUE + +/mob/living/simple_mob/update_inv_r_hand() + if(QDESTROYING(src)) + return + + if(r_hand) + r_hand.screen_loc = ui_rhand //TODO + + //determine icon state to use + var/t_state + if(r_hand.item_state_slots && r_hand.item_state_slots[slot_r_hand_str]) + t_state = r_hand.item_state_slots[slot_r_hand_str] + else if(r_hand.item_state) + t_state = r_hand.item_state + else + t_state = r_hand.icon_state + + //determine icon to use + var/icon/t_icon + if(r_hand.item_icons && (slot_r_hand_str in r_hand.item_icons)) + t_icon = r_hand.item_icons[slot_r_hand_str] + else if(r_hand.icon_override) + t_state += "_r" + t_icon = r_hand.icon_override + else + t_icon = INV_R_HAND_DEF_ICON + + //apply color + var/image/standing = image(icon = t_icon, icon_state = t_state) + standing.color = r_hand.color + + r_hand_sprite = standing + + else + r_hand_sprite = null + + update_icon() + +/mob/living/simple_mob/update_inv_l_hand() + if(QDESTROYING(src)) + return + + if(l_hand) + l_hand.screen_loc = ui_lhand //TODO + + //determine icon state to use + var/t_state + if(l_hand.item_state_slots && l_hand.item_state_slots[slot_l_hand_str]) + t_state = l_hand.item_state_slots[slot_l_hand_str] + else if(l_hand.item_state) + t_state = l_hand.item_state + else + t_state = l_hand.icon_state + + //determine icon to use + var/icon/t_icon + if(l_hand.item_icons && (slot_l_hand_str in l_hand.item_icons)) + t_icon = l_hand.item_icons[slot_l_hand_str] + else if(l_hand.icon_override) + t_state += "_l" + t_icon = l_hand.icon_override + else + t_icon = INV_L_HAND_DEF_ICON + + //apply color + var/image/standing = image(icon = t_icon, icon_state = t_state) + standing.color = l_hand.color + + l_hand_sprite = standing + + else + l_hand_sprite = null + + update_icon() + +//Can insert extra huds into the hud holder here. +/mob/living/simple_mob/proc/extra_huds(var/datum/hud/hud,var/icon/ui_style,var/list/hud_elements) + return + +//If they can or cannot use tools/machines/etc +/mob/living/simple_mob/IsAdvancedToolUser() + return has_hands + +/mob/living/simple_mob/proc/IsHumanoidToolUser(var/atom/tool) + if(!humanoid_hands) + var/display_name = null + if(tool) + display_name = tool + else + display_name = "object" + to_chat(src, "Your [hand_form] are not fit for use of \the [display_name].") + return humanoid_hands + +/mob/living/simple_mob/drop_from_inventory(var/obj/item/W, var/atom/target = null) + . = ..(W, target) + if(!target) + target = src.loc + if(.) + W.forceMove(src.loc) diff --git a/code/modules/mob/living/simple_mob/life.dm b/code/modules/mob/living/simple_mob/life.dm new file mode 100644 index 0000000000..bab2aa4129 --- /dev/null +++ b/code/modules/mob/living/simple_mob/life.dm @@ -0,0 +1,160 @@ +/mob/living/simple_mob/Life() + ..() + + //Health + updatehealth() + if(stat >= DEAD) + return FALSE + + handle_stunned() + handle_weakened() + handle_paralysed() + handle_supernatural() + handle_atmos() + + handle_special() + + return TRUE + + +//Should we be dead? +/mob/living/simple_mob/updatehealth() + health = getMaxHealth() - getFireLoss() - getBruteLoss() - getToxLoss() - getOxyLoss() - getCloneLoss() + + //Alive, becoming dead + if((stat < DEAD) && (health <= 0)) + death() + + //Overhealth + if(health > getMaxHealth()) + health = getMaxHealth() + + //Update our hud if we have one + if(healths) + if(stat != DEAD) + var/heal_per = (health / getMaxHealth()) * 100 + switch(heal_per) + if(100 to INFINITY) + healths.icon_state = "health0" + if(80 to 100) + healths.icon_state = "health1" + if(60 to 80) + healths.icon_state = "health2" + if(40 to 60) + healths.icon_state = "health3" + if(20 to 40) + healths.icon_state = "health4" + if(0 to 20) + healths.icon_state = "health5" + else + healths.icon_state = "health6" + else + healths.icon_state = "health7" + + //Updates the nutrition while we're here + if(nutrition_icon) + var/food_per = (nutrition / initial(nutrition)) * 100 + switch(food_per) + if(90 to INFINITY) + nutrition_icon.icon_state = "nutrition0" + if(75 to 90) + nutrition_icon.icon_state = "nutrition1" + if(50 to 75) + nutrition_icon.icon_state = "nutrition2" + if(25 to 50) + nutrition_icon.icon_state = "nutrition3" + if(0 to 25) + nutrition_icon.icon_state = "nutrition4" + +// Override for special bullshit. +/mob/living/simple_mob/proc/handle_special() + return + + +// Handle interacting with and taking damage from atmos +// TODO - Refactor this to use handle_environment() like a good /mob/living +/mob/living/simple_mob/proc/handle_atmos() + var/atmos_unsuitable = 0 + + var/atom/A = src.loc + + if(istype(A,/turf)) + var/turf/T = A + + var/datum/gas_mixture/Environment = T.return_air() + + if(Environment) + + if( abs(Environment.temperature - bodytemperature) > 40 ) + bodytemperature += ((Environment.temperature - bodytemperature) / 5) + + if(min_oxy) + if(Environment.gas["oxygen"] < min_oxy) + atmos_unsuitable = 1 + if(max_oxy) + if(Environment.gas["oxygen"] > max_oxy) + atmos_unsuitable = 1 + if(min_tox) + if(Environment.gas["phoron"] < min_tox) + atmos_unsuitable = 2 + if(max_tox) + if(Environment.gas["phoron"] > max_tox) + atmos_unsuitable = 2 + if(min_n2) + if(Environment.gas["nitrogen"] < min_n2) + atmos_unsuitable = 1 + if(max_n2) + if(Environment.gas["nitrogen"] > max_n2) + atmos_unsuitable = 1 + if(min_co2) + if(Environment.gas["carbon_dioxide"] < min_co2) + atmos_unsuitable = 1 + if(max_co2) + if(Environment.gas["carbon_dioxide"] > max_co2) + atmos_unsuitable = 1 + + //Atmos effect + if(bodytemperature < minbodytemp) + fire_alert = 2 + adjustFireLoss(cold_damage_per_tick) + if(fire) + fire.icon_state = "fire1" + else if(bodytemperature > maxbodytemp) + fire_alert = 1 + adjustFireLoss(heat_damage_per_tick) + if(fire) + fire.icon_state = "fire2" + else + fire_alert = 0 + if(fire) + fire.icon_state = "fire0" + + if(atmos_unsuitable) + adjustOxyLoss(unsuitable_atoms_damage) + if(oxygen) + oxygen.icon_state = "oxy1" + else if(oxygen) + if(oxygen) + oxygen.icon_state = "oxy0" + adjustOxyLoss(-unsuitable_atoms_damage) + + +/mob/living/simple_mob/proc/handle_supernatural() + if(purge) + purge -= 1 + +/mob/living/simple_mob/death(gibbed, deathmessage = "dies!") + density = 0 //We don't block even if we did before + + if(has_eye_glow) + remove_eyes() + + if(loot_list.len) //Drop any loot + for(var/path in loot_list) + if(prob(loot_list[path])) + new path(get_turf(src)) + + spawn(3) //We'll update our icon in a sec + update_icon() + + return ..(gibbed,deathmessage) \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/on_click.dm b/code/modules/mob/living/simple_mob/on_click.dm new file mode 100644 index 0000000000..4b824c9580 --- /dev/null +++ b/code/modules/mob/living/simple_mob/on_click.dm @@ -0,0 +1,48 @@ +/* + Animals +*/ +/mob/living/simple_mob/UnarmedAttack(var/atom/A, var/proximity) + if(!(. = ..())) + return + +// setClickCooldown(get_attack_speed()) + + if(has_hands && istype(A,/obj) && a_intent != I_HURT) + var/obj/O = A + return O.attack_hand(src) + + switch(a_intent) + if(I_HELP) + if(isliving(A)) + custom_emote(1,"[pick(friendly)] \the [A]!") + + if(I_HURT) + if(can_special_attack(A) && special_attack_target(A)) + return + + else if(melee_damage_upper == 0 && istype(A,/mob/living)) + custom_emote(1,"[pick(friendly)] \the [A]!") + + else + attack_target(A) + + if(I_GRAB) + if(has_hands) + A.attack_hand(src) + else + attack_target(A) + + if(I_DISARM) + if(has_hands) + A.attack_hand(src) + else + attack_target(A) + +/mob/living/simple_mob/RangedAttack(var/atom/A) +// setClickCooldown(get_attack_speed()) + + if(can_special_attack(A) && special_attack_target(A)) + return + + if(projectiletype) + shoot_target(A) \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/simple_hud.dm b/code/modules/mob/living/simple_mob/simple_hud.dm new file mode 100644 index 0000000000..fe851648b4 --- /dev/null +++ b/code/modules/mob/living/simple_mob/simple_hud.dm @@ -0,0 +1,311 @@ +/mob/living/simple_mob/instantiate_hud(var/datum/hud/hud) + if(!client) + return //Why bother. + + var/ui_style = 'icons/mob/screen1_animal.dmi' + if(ui_icons) + ui_style = ui_icons + + var/ui_color = "#ffffff" + var/ui_alpha = 255 + + var/list/adding = list() + var/list/other = list() + var/list/hotkeybuttons = list() + var/list/slot_info = list() + + hud.adding = adding + hud.other = other + hud.hotkeybuttons = hotkeybuttons + + var/list/hud_elements = list() + var/obj/screen/using + var/obj/screen/inventory/inv_box + + var/has_hidden_gear + if(LAZYLEN(hud_gears)) + for(var/gear_slot in hud_gears) + inv_box = new /obj/screen/inventory() + inv_box.icon = ui_style + inv_box.color = ui_color + inv_box.alpha = ui_alpha + + var/list/slot_data = hud_gears[gear_slot] + inv_box.name = gear_slot + inv_box.screen_loc = slot_data["loc"] + inv_box.slot_id = slot_data["slot"] + inv_box.icon_state = slot_data["state"] + slot_info["[inv_box.slot_id]"] = inv_box.screen_loc + + if(slot_data["dir"]) + inv_box.set_dir(slot_data["dir"]) + + if(slot_data["toggle"]) + other += inv_box + has_hidden_gear = 1 + else + adding += inv_box + + if(has_hidden_gear) + using = new /obj/screen() + using.name = "toggle" + using.icon = ui_style + using.icon_state = "other" + using.screen_loc = ui_inventory + using.hud_layerise() + using.color = ui_color + using.alpha = ui_alpha + adding += using + + //Intent Backdrop + using = new /obj/screen() + using.name = "act_intent" + using.icon = ui_style + using.icon_state = "intent_"+a_intent + using.screen_loc = ui_acti + using.color = ui_color + using.alpha = ui_alpha + hud.adding += using + hud.action_intent = using + + hud_elements |= using + + //Small intent quarters + var/icon/ico + + ico = new(ui_style, "black") + ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1) + ico.DrawBox(rgb(255,255,255,1),1,ico.Height()/2,ico.Width()/2,ico.Height()) + using = new /obj/screen() + using.name = I_HELP + using.icon = ico + using.screen_loc = ui_acti + using.alpha = ui_alpha + using.layer = LAYER_HUD_ITEM //These sit on the intent box + hud.adding += using + hud.help_intent = using + + ico = new(ui_style, "black") + ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1) + ico.DrawBox(rgb(255,255,255,1),ico.Width()/2,ico.Height()/2,ico.Width(),ico.Height()) + using = new /obj/screen() + using.name = I_DISARM + using.icon = ico + using.screen_loc = ui_acti + using.alpha = ui_alpha + using.layer = LAYER_HUD_ITEM + hud.adding += using + hud.disarm_intent = using + + ico = new(ui_style, "black") + ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1) + ico.DrawBox(rgb(255,255,255,1),ico.Width()/2,1,ico.Width(),ico.Height()/2) + using = new /obj/screen() + using.name = I_GRAB + using.icon = ico + using.screen_loc = ui_acti + using.alpha = ui_alpha + using.layer = LAYER_HUD_ITEM + hud.adding += using + hud.grab_intent = using + + ico = new(ui_style, "black") + ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1) + ico.DrawBox(rgb(255,255,255,1),1,1,ico.Width()/2,ico.Height()/2) + using = new /obj/screen() + using.name = I_HURT + using.icon = ico + using.screen_loc = ui_acti + using.alpha = ui_alpha + using.layer = LAYER_HUD_ITEM + hud.adding += using + hud.hurt_intent = using + + //Move intent (walk/run) + using = new /obj/screen() + using.name = "mov_intent" + using.icon = ui_style + using.icon_state = (m_intent == "run" ? "running" : "walking") + using.screen_loc = ui_movi + using.color = ui_color + using.alpha = ui_alpha + hud.adding += using + hud.move_intent = using + + //Resist button + using = new /obj/screen() + using.name = "resist" + using.icon = ui_style + using.icon_state = "act_resist" + using.screen_loc = ui_pull_resist + using.color = ui_color + using.alpha = ui_alpha + hud.hotkeybuttons += using + + //Pull button + pullin = new /obj/screen() + pullin.icon = ui_style + pullin.icon_state = "pull0" + pullin.name = "pull" + pullin.screen_loc = ui_pull_resist + hud.hotkeybuttons += pullin + hud_elements |= pullin + + //Health status + healths = new /obj/screen() + healths.icon = ui_style + healths.icon_state = "health0" + healths.name = "health" + healths.screen_loc = ui_health + hud_elements |= healths + + //Oxygen dep icon + oxygen = new /obj/screen() + oxygen.icon = ui_style + oxygen.icon_state = "oxy0" + oxygen.name = "oxygen" + oxygen.screen_loc = ui_oxygen + hud_elements |= oxygen + + //Toxins present icon + toxin = new /obj/screen() + toxin.icon = ui_style + toxin.icon_state = "tox0" + toxin.name = "toxin" + toxin.screen_loc = ui_toxin + hud_elements |= toxin + + //Fire warning + fire = new /obj/screen() + fire.icon = ui_style + fire.icon_state = "fire0" + fire.name = "fire" + fire.screen_loc = ui_fire + hud_elements |= fire + + //Pressure warning + pressure = new /obj/screen() + pressure.icon = ui_style + pressure.icon_state = "pressure0" + pressure.name = "pressure" + pressure.screen_loc = ui_pressure + hud_elements |= pressure + + //Body temp warning + bodytemp = new /obj/screen() + bodytemp.icon = ui_style + bodytemp.icon_state = "temp0" + bodytemp.name = "body temperature" + bodytemp.screen_loc = ui_temp + hud_elements |= bodytemp + + //Nutrition status + nutrition_icon = new /obj/screen() + nutrition_icon.icon = ui_style + nutrition_icon.icon_state = "nutrition0" + nutrition_icon.name = "nutrition" + nutrition_icon.screen_loc = ui_nutrition + hud_elements |= nutrition_icon + + pain = new /obj/screen( null ) + + zone_sel = new /obj/screen/zone_sel( null ) + zone_sel.icon = ui_style + zone_sel.color = ui_color + zone_sel.alpha = ui_alpha + zone_sel.overlays.Cut() + zone_sel.overlays += image('icons/mob/zone_sel.dmi', "[zone_sel.selecting]") + hud_elements |= zone_sel + + //Hand things + if(has_hands) + //Drop button + using = new /obj/screen() + using.name = "drop" + using.icon = ui_style + using.icon_state = "act_drop" + using.screen_loc = ui_drop_throw + using.color = ui_color + using.alpha = ui_alpha + hud.hotkeybuttons += using + + //Equip detail + using = new /obj/screen() + using.name = "equip" + using.icon = ui_style + using.icon_state = "act_equip" + using.screen_loc = ui_equip + using.color = ui_color + using.alpha = ui_alpha + hud.adding += using + + //Hand slots themselves + inv_box = new /obj/screen/inventory/hand() + inv_box.hud = src + inv_box.name = "r_hand" + inv_box.icon = ui_style + inv_box.icon_state = "r_hand_inactive" + if(!hand) //This being 0 or null means the right hand is in use + inv_box.icon_state = "r_hand_active" + inv_box.screen_loc = ui_rhand + inv_box.slot_id = slot_r_hand + inv_box.color = ui_color + inv_box.alpha = ui_alpha + hud.r_hand_hud_object = inv_box + hud.adding += inv_box + slot_info["[slot_r_hand]"] = inv_box.screen_loc + + inv_box = new /obj/screen/inventory/hand() + inv_box.hud = src + inv_box.name = "l_hand" + inv_box.icon = ui_style + inv_box.icon_state = "l_hand_inactive" + if(hand) //This being 1 means the left hand is in use + inv_box.icon_state = "l_hand_active" + inv_box.screen_loc = ui_lhand + inv_box.slot_id = slot_l_hand + inv_box.color = ui_color + inv_box.alpha = ui_alpha + hud.l_hand_hud_object = inv_box + hud.adding += inv_box + slot_info["[slot_l_hand]"] = inv_box.screen_loc + + //Swaphand titlebar + using = new /obj/screen/inventory() + using.name = "hand" + using.icon = ui_style + using.icon_state = "hand1" + using.screen_loc = ui_swaphand1 + using.color = ui_color + using.alpha = ui_alpha + hud.adding += using + + using = new /obj/screen/inventory() + using.name = "hand" + using.icon = ui_style + using.icon_state = "hand2" + using.screen_loc = ui_swaphand2 + using.color = ui_color + using.alpha = ui_alpha + hud.adding += using + + //Throw button + throw_icon = new /obj/screen() + throw_icon.icon = ui_style + throw_icon.icon_state = "act_throw_off" + throw_icon.name = "throw" + throw_icon.screen_loc = ui_drop_throw + throw_icon.color = ui_color + throw_icon.alpha = ui_alpha + hud.hotkeybuttons += throw_icon + hud_elements |= throw_icon + + extra_huds(hud,ui_style,hud_elements) + + client.screen = list() + + client.screen += hud_elements + client.screen += adding + hotkeybuttons + client.screen += client.void + + return diff --git a/code/modules/mob/living/simple_mob/simple_mob.dm b/code/modules/mob/living/simple_mob/simple_mob.dm new file mode 100644 index 0000000000..9ad2ec58be --- /dev/null +++ b/code/modules/mob/living/simple_mob/simple_mob.dm @@ -0,0 +1,290 @@ +// Reorganized and somewhat cleaned up. +// AI code has been made into a datum, inside the AI module folder. + +/mob/living/simple_mob + name = "animal" + desc = "" + icon = 'icons/mob/animal.dmi' + health = 20 + maxHealth = 20 + + // Generally we don't want simple_mobs to get displaced when bumped into due to it trivializing combat with windup attacks. + // Some subtypes allow displacement, like passive animals. + mob_bump_flag = HEAVY + mob_swap_flags = ~HEAVY + mob_push_flags = ~HEAVY + + var/tt_desc = "Uncataloged Life Form" //Tooltip description + + //Settings for played mobs + var/show_stat_health = 1 // Does the percentage health show in the stat panel for the mob + var/has_hands = 0 // Set to 1 to enable the use of hands and the hands hud + var/humanoid_hands = 0 // Can a player in this mob use things like guns or AI cards? + var/hand_form = "hands" // Used in IsHumanoidToolUser. 'Your X are not fit-'. + var/list/hud_gears // Slots to show on the hud (typically none) + var/ui_icons // Icon file path to use for the HUD, otherwise generic icons are used + var/r_hand_sprite // If they have hands, + var/l_hand_sprite // they could use some icons. + var/player_msg // Message to print to players about 'how' to play this mob on login. + + //Mob icon/appearance settings + var/icon_living = "" // The iconstate if we're alive, required + var/icon_dead = "" // The iconstate if we're dead, required + var/icon_gib = "generic_gib" // The iconstate for being gibbed, optional. Defaults to a generic gib animation. + var/icon_rest = null // The iconstate for resting, optional + var/image/modifier_overlay = null // Holds overlays from modifiers. + var/image/eye_layer = null // Holds the eye overlay. + var/has_eye_glow = FALSE // If true, adds an overlay over the lighting plane for [icon_state]-eyes. + attack_icon = 'icons/effects/effects.dmi' //Just the default, played like the weapon attack anim + attack_icon_state = "slash" //Just the default + + //Mob talking settings + universal_speak = 0 // Can all mobs in the entire universe understand this one? + var/has_langs = list(LANGUAGE_GALCOM)// Text name of their language if they speak something other than galcom. They speak the first one. + + //Movement things. + var/movement_cooldown = 5 // Lower is faster. + var/movement_sound = null // If set, will play this sound when it moves on its own will. + var/turn_sound = null // If set, plays the sound when the mob's dir changes in most cases. + var/movement_shake_radius = 0 // If set, moving will shake the camera of all living mobs within this radius slightly. + + //Mob interaction + var/response_help = "tries to help" // If clicked on help intent + var/response_disarm = "tries to disarm" // If clicked on disarm intent + var/response_harm = "tries to hurt" // If clicked on harm intent + var/list/friends = list() // Mobs on this list wont get attacked regardless of faction status. + var/harm_intent_damage = 3 // How much an unarmed harm click does to this mob. + var/meat_amount = 0 // How much meat to drop from this mob when butchered + var/obj/meat_type // The meat object to drop + var/list/loot_list = list() // The list of lootable objects to drop, with "/path = prob%" structure + var/obj/item/weapon/card/id/myid// An ID card if they have one to give them access to stuff. + + //Mob environment settings + var/minbodytemp = 250 // Minimum "okay" temperature in kelvin + var/maxbodytemp = 350 // Maximum of above + var/heat_damage_per_tick = 3 // Amount of damage applied if animal's body temperature is higher than maxbodytemp + var/cold_damage_per_tick = 2 // Same as heat_damage_per_tick, only if the bodytemperature it's lower than minbodytemp + var/fire_alert = 0 // 0 = fine, 1 = hot, 2 = cold + + var/min_oxy = 5 // Oxygen in moles, minimum, 0 is 'no minimum' + var/max_oxy = 0 // Oxygen in moles, maximum, 0 is 'no maximum' + var/min_tox = 0 // Phoron min + var/max_tox = 1 // Phoron max + var/min_co2 = 0 // CO2 min + var/max_co2 = 5 // CO2 max + var/min_n2 = 0 // N2 min + var/max_n2 = 0 // N2 max + var/unsuitable_atoms_damage = 2 // This damage is taken when atmos doesn't fit all the requirements above + + //Hostility settings + var/taser_kill = 1 // Is the mob weak to tasers + + //Attack ranged settings + var/projectiletype // The projectiles I shoot + var/projectilesound // The sound I make when I do it + var/casingtype // What to make the hugely laggy casings pile out of + + // Reloading settings, part of ranged code + var/needs_reload = FALSE // If TRUE, mob needs to reload occasionally + var/reload_max = 1 // How many shots the mob gets before it has to reload, will not be used if needs_reload is FALSE + var/reload_count = 0 // A counter to keep track of how many shots the mob has fired so far. Reloads when it hits reload_max. + var/reload_time = 1 SECONDS // How long it takes for a mob to reload. This is to buy a player a bit of time to run or fight. + var/reload_sound = 'sound/weapons/flipblade.ogg' // What sound gets played when the mob successfully reloads. Defaults to the same sound as reloading guns. Can be null. + + //Mob melee settings + var/melee_damage_lower = 2 // Lower bound of randomized melee damage + var/melee_damage_upper = 6 // Upper bound of randomized melee damage + var/list/attacktext = list("attacked") // "You are [attacktext] by the mob!" + var/list/friendly = list("nuzzles") // "The mob [friendly] the person." + var/attack_sound = null // Sound to play when I attack + var/melee_miss_chance = 0 // percent chance to miss a melee attack. + var/attack_armor_type = "melee" // What armor does this check? + var/attack_armor_pen = 0 // How much armor pen this attack has. + var/attack_sharp = FALSE // Is the attack sharp? + var/attack_edge = FALSE // Does the attack have an edge? + + var/melee_attack_delay = null // If set, the mob will do a windup animation and can miss if the target moves out of the way. + var/ranged_attack_delay = null + var/special_attack_delay = null + + //Special attacks +// var/special_attack_prob = 0 // The chance to ATTEMPT a special_attack_target(). If it fails, it will do a regular attack instead. + // This is commented out to ease the AI attack logic by being (a bit more) determanistic. + // You should instead limit special attacks using the below vars instead. + var/special_attack_min_range = null // The minimum distance required for an attempt to be made. + var/special_attack_max_range = null // The maximum for an attempt. + var/special_attack_charges = null // If set, special attacks will work off of a charge system, and won't be usable if all charges are expended. Good for grenades. + var/special_attack_cooldown = null // If set, special attacks will have a cooldown between uses. + var/last_special_attack = null // world.time when a special attack occured last, for cooldown calculations. + + //Damage resistances + var/grab_resist = 0 // Chance for a grab attempt to fail. Note that this is not a true resist and is just a prob() of failure. + var/resistance = 0 // Damage reduction for all types + var/list/armor = list( // Values for normal getarmor() checks + "melee" = 0, + "bullet" = 0, + "laser" = 0, + "energy" = 0, + "bomb" = 0, + "bio" = 100, + "rad" = 100 + ) + var/list/armor_soak = list( // Values for getsoak() checks. + "melee" = 0, + "bullet" = 0, + "laser" = 0, + "energy" = 0, + "bomb" = 0, + "bio" = 0, + "rad" = 0 + ) + // Protection against heat/cold/electric/water effects. + // 0 is no protection, 1 is total protection. Negative numbers increase vulnerability. + var/heat_resist = 0.0 + var/cold_resist = 0.0 + var/shock_resist = 0.0 + var/water_resist = 1.0 + var/poison_resist = 0.0 + var/thick_armor = FALSE // Stops injections and "injections". + var/purge = 0 // Cult stuff. + var/supernatural = FALSE // Ditto. + + +/mob/living/simple_mob/Initialize() + verbs -= /mob/verb/observe + health = maxHealth + + for(var/L in has_langs) + languages |= all_languages[L] + if(languages.len) + default_language = languages[1] + + if(has_eye_glow) + add_eyes() + return ..() + + +/mob/living/simple_mob/Destroy() + default_language = null + if(myid) + qdel(myid) + myid = null + + friends.Cut() + languages.Cut() + + if(has_eye_glow) + remove_eyes() + return ..() + +/mob/living/simple_mob/death() + update_icon() + ..() + + +//Client attached +/mob/living/simple_mob/Login() + . = ..() + to_chat(src,"You are \the [src]. [player_msg]") + + +/mob/living/simple_mob/emote(var/act, var/type, var/desc) + if(act) + ..(act, type, desc) + + +/mob/living/simple_mob/SelfMove(turf/n, direct) + var/turf/old_turf = get_turf(src) + var/old_dir = dir + . = ..() + if(. && movement_shake_radius) + for(var/mob/living/L in range(movement_shake_radius, src)) + shake_camera(L, 1, 1) + if(turn_sound && dir != old_dir) + playsound(src, turn_sound, 50, 1) + else if(movement_sound && old_turf != get_turf(src)) // Playing both sounds at the same time generally sounds bad. + playsound(src, movement_sound, 50, 1) +/* +/mob/living/simple_mob/set_dir(new_dir) + if(dir != new_dir) + playsound(src, turn_sound, 50, 1) + return ..() +*/ +/mob/living/simple_mob/movement_delay() + var/tally = 0 //Incase I need to add stuff other than "speed" later + + tally = movement_cooldown + + if(force_max_speed) + return -3 + + for(var/datum/modifier/M in modifiers) + if(!isnull(M.haste) && M.haste == TRUE) + return -3 + if(!isnull(M.slowdown)) + tally += M.slowdown + + // Turf related slowdown + var/turf/T = get_turf(src) + if(T && T.movement_cost && !hovering) // Flying mobs ignore turf-based slowdown. + tally += T.movement_cost + + if(purge)//Purged creatures will move more slowly. The more time before their purge stops, the slower they'll move. + if(tally <= 0) + tally = 1 + tally *= purge + + if(m_intent == "walk") + tally *= 1.5 + + return tally+config.animal_delay + + +/mob/living/simple_mob/Stat() + ..() + if(statpanel("Status") && show_stat_health) + stat(null, "Health: [round((health / getMaxHealth()) * 100)]%") + +/mob/living/simple_mob/lay_down() + ..() + if(resting && icon_rest) + icon_state = icon_rest + else + icon_state = icon_living + update_icon() + + +/mob/living/simple_mob/say(var/message,var/datum/language/language) + var/verb = "says" + if(speak_emote.len) + verb = pick(speak_emote) + + message = sanitize(message) + + ..(message, null, verb) + +/mob/living/simple_mob/get_speech_ending(verb, var/ending) + return verb + + +// Harvest an animal's delicious byproducts +/mob/living/simple_mob/proc/harvest(var/mob/user) + var/actual_meat_amount = max(1,(meat_amount/2)) + if(meat_type && actual_meat_amount>0 && (stat == DEAD)) + for(var/i=0;i[user] chops up \the [src]!") + new/obj/effect/decal/cleanable/blood/splatter(get_turf(src)) + qdel(src) + else + user.visible_message("[user] butchers \the [src] messily!") + gib() + + +/mob/living/simple_mob/is_sentient() + return mob_class & MOB_CLASS_HUMANOID|MOB_CLASS_ANIMAL|MOB_CLASS_SLIME // Update this if needed. + +/mob/living/simple_mob/get_nametag_desc(mob/user) + return "[tt_desc]" \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/simple_animal_vr.dm b/code/modules/mob/living/simple_mob/simple_mob_vr.dm similarity index 70% rename from code/modules/mob/living/simple_animal/simple_animal_vr.dm rename to code/modules/mob/living/simple_mob/simple_mob_vr.dm index 9eeb6b8b97..7767f96c92 100644 --- a/code/modules/mob/living/simple_animal/simple_animal_vr.dm +++ b/code/modules/mob/living/simple_mob/simple_mob_vr.dm @@ -3,7 +3,7 @@ #define SA_ICON_DEAD 0x02 #define SA_ICON_REST 0x03 -/mob/living/simple_animal +/mob/living/simple_mob var/vore_active = 0 // If vore behavior is enabled for this mob var/vore_capacity = 1 // The capacity (in people) this person can hold @@ -31,23 +31,24 @@ var/vore_fullness = 0 // How "full" the belly is (controls icons) var/vore_icons = 0 // Bitfield for which fields we have vore icons for. + var/life_disabled = 0 // For performance reasons var/mount_offset_x = 5 // Horizontal riding offset. var/mount_offset_y = 8 // Vertical riding offset // Release belly contents before being gc'd! -/mob/living/simple_animal/Destroy() +/mob/living/simple_mob/Destroy() release_vore_contents() prey_excludes.Cut() . = ..() //For all those ID-having mobs -/mob/living/simple_animal/GetIdCard() +/mob/living/simple_mob/GetIdCard() if(myid) return myid // Update fullness based on size & quantity of belly contents -/mob/living/simple_animal/proc/update_fullness() +/mob/living/simple_mob/proc/update_fullness() var/new_fullness = 0 for(var/belly in vore_organs) var/obj/belly/B = belly @@ -56,7 +57,7 @@ new_fullness = round(new_fullness, 1) // Because intervals of 0.25 are going to make sprite artists cry. vore_fullness = min(vore_capacity, new_fullness) -/mob/living/simple_animal/proc/update_vore_icon() +/mob/living/simple_mob/proc/update_vore_icon() if(!vore_active) return 0 update_fullness() @@ -69,112 +70,115 @@ else if(((stat == UNCONSCIOUS) || resting || incapacitated(INCAPACITATION_DISABLED) ) && icon_rest && (vore_icons & SA_ICON_REST)) return "[icon_rest]-[vore_fullness]" -/mob/living/simple_animal/proc/will_eat(var/mob/living/M) +/mob/living/simple_mob/proc/will_eat(var/mob/living/M) if(client) //You do this yourself, dick! - ai_log("vr/wont eat [M] because we're player-controlled", 3) + //ai_log("vr/wont eat [M] because we're player-controlled", 3) //VORESTATION AI TEMPORARY REMOVAL return 0 if(!istype(M)) //Can't eat 'em if they ain't /mob/living - ai_log("vr/wont eat [M] because they are not /mob/living", 3) + //ai_log("vr/wont eat [M] because they are not /mob/living", 3) //VORESTATION AI TEMPORARY REMOVAL return 0 if(src == M) //Don't eat YOURSELF dork - ai_log("vr/won't eat [M] because it's me!", 3) + //ai_log("vr/won't eat [M] because it's me!", 3) //VORESTATION AI TEMPORARY REMOVAL return 0 if(vore_ignores_undigestable && !M.digestable) //Don't eat people with nogurgle prefs - ai_log("vr/wont eat [M] because I am picky", 3) + //ai_log("vr/wont eat [M] because I am picky", 3) //VORESTATION AI TEMPORARY REMOVAL return 0 if(!M.allowmobvore) // Don't eat people who don't want to be ate by mobs - ai_log("vr/wont eat [M] because they don't allow mob vore", 3) + //ai_log("vr/wont eat [M] because they don't allow mob vore", 3) //VORESTATION AI TEMPORARY REMOVAL return 0 if(M in prey_excludes) // They're excluded - ai_log("vr/wont eat [M] because they are excluded", 3) + //ai_log("vr/wont eat [M] because they are excluded", 3) //VORESTATION AI TEMPORARY REMOVAL return 0 if(M.size_multiplier < vore_min_size || M.size_multiplier > vore_max_size) - ai_log("vr/wont eat [M] because they too small or too big", 3) + //ai_log("vr/wont eat [M] because they too small or too big", 3) //VORESTATION AI TEMPORARY REMOVAL return 0 if(vore_capacity != 0 && (vore_fullness >= vore_capacity)) // We're too full to fit them - ai_log("vr/wont eat [M] because I am too full", 3) + //ai_log("vr/wont eat [M] because I am too full", 3) //VORESTATION AI TEMPORARY REMOVAL return 0 return 1 -/mob/living/simple_animal/PunchTarget() - ai_log("vr/PunchTarget() [target_mob]", 3) +/mob/living/simple_mob/apply_attack(atom/A, damage_to_do) + if(isliving(A)) // Converts target to living + var/mob/living/L = A - // If we're not hungry, call the sideways "parent" to do normal punching - if(!vore_active) - return ..() + //ai_log("vr/do_attack() [L]", 3) + // If we're not hungry, call the sideways "parent" to do normal punching + if(!vore_active) + return ..() - // If target is standing we might pounce and knock them down instead of attacking - var/pouncechance = CanPounceTarget() - if(pouncechance) - return PounceTarget(pouncechance) + // If target is standing we might pounce and knock them down instead of attacking + var/pouncechance = CanPounceTarget(L) + if(pouncechance) + return PounceTarget(L, pouncechance) - // We're not attempting a pounce, if they're down or we can eat standing, do it as long as they're edible. Otherwise, hit normally. - if(will_eat(target_mob) && (!target_mob.canmove || vore_standing_too)) - return EatTarget() - else - return ..() + // We're not attempting a pounce, if they're down or we can eat standing, do it as long as they're edible. Otherwise, hit normally. + if(will_eat(L) && (!L.canmove || vore_standing_too)) + return EatTarget(L) + else + return ..() -/mob/living/simple_animal/proc/CanPounceTarget() //returns either FALSE or a %chance of success - if(!target_mob.canmove || issilicon(target_mob) || world.time < vore_pounce_cooldown) //eliminate situations where pouncing CANNOT happen + +/mob/living/simple_mob/proc/CanPounceTarget(var/mob/living/M) //returns either FALSE or a %chance of success + if(!M.canmove || issilicon(M) || world.time < vore_pounce_cooldown) //eliminate situations where pouncing CANNOT happen return FALSE if(!prob(vore_pounce_chance)) //mob doesn't want to pounce return FALSE - if(will_eat(target_mob) && vore_standing_too) //100% chance of hitting people we can eat on the spot + if(will_eat(M) && vore_standing_too) //100% chance of hitting people we can eat on the spot return 100 - var/TargetHealthPercent = (target_mob.health/target_mob.getMaxHealth())*100 //now we start looking at the target itself + var/TargetHealthPercent = (M.health/M.getMaxHealth())*100 //now we start looking at the target itself if (TargetHealthPercent > vore_pounce_maxhealth) //target is too healthy to pounce return FALSE else return max(0,(vore_pounce_successrate - (vore_pounce_falloff * TargetHealthPercent))) -/mob/living/simple_animal/proc/PounceTarget(var/successrate = 100) +/mob/living/simple_mob/proc/PounceTarget(var/mob/living/M, var/successrate = 100) vore_pounce_cooldown = world.time + 20 SECONDS // don't attempt another pounce for a while if(prob(successrate)) // pounce success! - target_mob.Weaken(5) - target_mob.visible_message("\the [src] pounces on \the [target_mob]!!") + M.Weaken(5) + M.visible_message("\the [src] pounces on \the [M]!!") else // pounce misses! - target_mob.visible_message("\the [src] attempts to pounce \the [target_mob] but misses!!") + M.visible_message("\the [src] attempts to pounce \the [M] but misses!!") playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) - if(will_eat(target_mob) && (!target_mob.canmove || vore_standing_too)) //if they're edible then eat them too - return EatTarget() + if(will_eat(M) && (!M.canmove || vore_standing_too)) //if they're edible then eat them too + return EatTarget(M) else return //just leave them // Attempt to eat target // TODO - Review this. Could be some issues here -/mob/living/simple_animal/proc/EatTarget() - ai_log("vr/EatTarget() [target_mob]",2) - stop_automated_movement = 1 - var/old_target = target_mob - handle_stance(STANCE_BUSY) - . = animal_nom(target_mob) +/mob/living/simple_mob/proc/EatTarget(var/mob/living/M) + //ai_log("vr/EatTarget() [M]",2) //VORESTATION AI TEMPORARY REMOVAL + //stop_automated_movement = 1 //VORESTATION AI TEMPORARY REMOVAL + var/old_target = M + set_AI_busy(1) //VORESTATION AI TEMPORARY EDIT + . = animal_nom(M) playsound(src, swallowsound, 50, 1) update_icon() if(.) // If we succesfully ate them, lose the target - LoseTarget() + set_AI_busy(0) // lose_target(M) //Unsure what to put here. Replaced with set_AI_busy(1) //VORESTATION AI TEMPORARY EDIT return old_target - else if(old_target == target_mob) + else if(old_target == M) // If we didn't but they are still our target, go back to attack. // but don't run the handler immediately, wait until next tick // Otherwise we'll be in a possibly infinate loop - set_stance(STANCE_ATTACK) - stop_automated_movement = 0 + set_AI_busy(0) //VORESTATION AI TEMPORARY EDIT + //stop_automated_movement = 0 //VORESTATION AI TEMPORARY EDIT -/mob/living/simple_animal/death() +/mob/living/simple_mob/death() release_vore_contents() . = ..() // Make sure you don't call ..() on this one, otherwise you duplicate work. -/mob/living/simple_animal/init_vore() +/mob/living/simple_mob/init_vore() if(!vore_active || no_vore) return if(!IsAdvancedToolUser()) - verbs |= /mob/living/simple_animal/proc/animal_nom + verbs |= /mob/living/simple_mob/proc/animal_nom verbs |= /mob/living/proc/shred_limb if(LAZYLEN(vore_organs)) @@ -216,58 +220,58 @@ "The churning walls slowly pulverize you into meaty nutrients.", "The stomach glorps and gurgles as it tries to work you into slop.") -/mob/living/simple_animal/Bumped(var/atom/movable/AM, yes) +/mob/living/simple_mob/Bumped(var/atom/movable/AM, yes) if(ismob(AM)) var/mob/tmob = AM if(will_eat(tmob) && !istype(tmob, type) && prob(vore_bump_chance) && !ckey) //check if they decide to eat. Includes sanity check to prevent cannibalism. if(tmob.canmove && prob(vore_pounce_chance)) //if they'd pounce for other noms, pounce for these too, otherwise still try and eat them if they hold still tmob.Weaken(5) tmob.visible_message("\the [src] [vore_bump_emote] \the [tmob]!!") - stop_automated_movement = 1 + //stop_automated_movement = 1 //VORESTATION AI TEMPORARY REMOVAL animal_nom(tmob) update_icon() - stop_automated_movement = 0 + //stop_automated_movement = 0 //VORESTATION AI TEMPORARY REMOVAL ..() - +/* //Was replaced with suitable_turf_type, but that can be done later. //VORESTATION AI TEMPORARY REMOVAL // Checks to see if mob doesn't like this kind of turf -/mob/living/simple_animal/avoid_turf(var/turf/turf) +/mob/living/simple_mob/avoid_turf(var/turf/turf) //So we only check if the parent didn't find anything terrible if((. = ..(turf))) return . if(istype(turf,/turf/unsimulated/floor/sky)) return TRUE //Mobs aren't that stupid, probably - +*/ //Grab = Nomf -/mob/living/simple_animal/UnarmedAttack(var/atom/A, var/proximity) +/mob/living/simple_mob/UnarmedAttack(var/atom/A, var/proximity) . = ..() if(a_intent == I_GRAB && isliving(A) && !has_hands) animal_nom(A) // Riding -/datum/riding/simple_animal +/datum/riding/simple_mob keytype = /obj/item/weapon/material/twohanded/fluff/riding_crop // Crack! nonhuman_key_exemption = FALSE // If true, nonhumans who can't hold keys don't need them, like borgs and simplemobs. key_name = "a riding crop" // What the 'keys' for the thing being rided on would be called. only_one_driver = TRUE // If true, only the person in 'front' (first on list of riding mobs) can drive. -/datum/riding/simple_animal/handle_vehicle_layer() +/datum/riding/simple_mob/handle_vehicle_layer() ridden.layer = initial(ridden.layer) -/datum/riding/simple_animal/ride_check(mob/living/M) +/datum/riding/simple_mob/ride_check(mob/living/M) var/mob/living/L = ridden if(L.stat) force_dismount(M) return FALSE return TRUE -/datum/riding/simple_animal/force_dismount(mob/M) +/datum/riding/simple_mob/force_dismount(mob/M) . =..() ridden.visible_message("[M] stops riding [ridden]!") -/datum/riding/simple_animal/get_offsets(pass_index) // list(dir = x, y, layer) - var/mob/living/simple_animal/L = ridden +/datum/riding/simple_mob/get_offsets(pass_index) // list(dir = x, y, layer) + var/mob/living/simple_mob/L = ridden var/scale = L.size_multiplier var/list/values = list( @@ -278,7 +282,7 @@ return values -/mob/living/simple_animal/buckle_mob(mob/living/M, forced = FALSE, check_loc = TRUE) +/mob/living/simple_mob/buckle_mob(mob/living/M, forced = FALSE, check_loc = TRUE) if(forced) return ..() // Skip our checks if(!riding_datum) @@ -303,7 +307,7 @@ if(.) buckled_mobs[H] = "riding" -/mob/living/simple_animal/attack_hand(mob/user as mob) +/mob/living/simple_mob/attack_hand(mob/user as mob) if(riding_datum && LAZYLEN(buckled_mobs)) //We're getting off! if(user in buckled_mobs) @@ -315,7 +319,7 @@ else . = ..() -/mob/living/simple_animal/proc/animal_mount(var/mob/living/M in living_mobs(1)) +/mob/living/simple_mob/proc/animal_mount(var/mob/living/M in living_mobs(1)) set name = "Animal Mount/Dismount" set category = "Abilities" set desc = "Let people ride on you." diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/animal.dm b/code/modules/mob/living/simple_mob/subtypes/animal/animal.dm new file mode 100644 index 0000000000..e41d5ae66b --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/animal.dm @@ -0,0 +1,9 @@ +/mob/living/simple_mob/animal + mob_class = MOB_CLASS_ANIMAL + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat + + response_help = "pets" + response_disarm = "shoos" + response_harm = "hits" + + ai_holder_type = /datum/ai_holder/simple_mob/melee \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/borer/borer.dm b/code/modules/mob/living/simple_mob/subtypes/animal/borer/borer.dm new file mode 100644 index 0000000000..b5b4489f57 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/borer/borer.dm @@ -0,0 +1,237 @@ +// Borers are probably still going to be buggy as fuck, this is just bringing their mob defines up to the new system. +// IMO they're a relic of several ages we're long past, their code and their design showing this plainly, but removing them would +// make certain people Unhappy so here we are. They need a complete redesign but thats beyond the scope of the rewrite. + +/mob/living/simple_mob/animal/borer + name = "cortical borer" + desc = "A small, quivering sluglike creature." + icon_state = "brainslug" + item_state = "brainslug" + icon_living = "brainslug" + icon_dead = "brainslug_dead" + + response_help = "pokes" + response_disarm = "prods" + response_harm = "stomps on" + attacktext = list("nipped") + friendly = list("prods") + + status_flags = CANPUSH + pass_flags = PASSTABLE + movement_cooldown = 5 + + universal_understand = TRUE + can_be_antagged = TRUE + + holder_type = /obj/item/weapon/holder/borer + ai_holder_type = null // This is player-controlled, always. + + var/chemicals = 10 // A resource used for reproduction and powers. + var/mob/living/carbon/human/host = null // The humanoid host for the brain worm. + var/true_name = null // String used when speaking among other worms. + var/mob/living/captive_brain/host_brain // Used for swapping control of the body back and forth. + var/controlling = FALSE // Used in human death ceck. + var/docile = FALSE // Sugar can stop borers from acting. + var/has_reproduced = FALSE + var/roundstart = FALSE // If true, spawning won't try to pull a ghost. + var/used_dominate // world.time when the dominate power was last used. + + +/mob/living/simple_mob/animal/borer/roundstart + roundstart = TRUE + +/mob/living/simple_mob/animal/borer/Login() + ..() + if(mind) + borers.add_antagonist(mind) + +/mob/living/simple_mob/animal/borer/Initialize() + add_language("Cortical Link") + + verbs += /mob/living/proc/ventcrawl + verbs += /mob/living/proc/hide + + true_name = "[pick("Primary","Secondary","Tertiary","Quaternary")] [rand(1000,9999)]" + + if(!roundstart) + request_player() + + return ..() + +/mob/living/simple_mob/animal/borer/handle_special() + if(host && !stat && !host.stat) + // Handle docility. + if(host.reagents.has_reagent("sugar") && !docile) + var/message = "You feel the soporific flow of sugar in your host's blood, lulling you into docility." + var/target = controlling ? host : src + to_chat(target, span("warning", message)) + docile = TRUE + + else if(docile) + var/message = "You shake off your lethargy as the sugar leaves your host's blood." + var/target = controlling ? host : src + to_chat(target, span("notice", message)) + docile = FALSE + + // Chem regen. + if(chemicals < 250) + chemicals++ + + // Control stuff. + if(controlling) + if(docile) + to_chat(host, span("warning", "You are feeling far too docile to continue controlling your host...")) + host.release_control() + return + + if(prob(5)) + host.adjustBrainLoss(0.1) + + if(prob(host.brainloss/20)) + host.say("*[pick(list("blink","blink_r","choke","aflap","drool","twitch","twitch_v","gasp"))]") + +/mob/living/simple_mob/animal/borer/Stat() + ..() + if(client.statpanel == "Status") + statpanel("Status") + if(emergency_shuttle) + var/eta_status = emergency_shuttle.get_status_panel_eta() + if(eta_status) + stat(null, eta_status) + stat("Chemicals", chemicals) + +/mob/living/simple_mob/animal/borer/proc/detatch() + if(!host || !controlling) + return + + if(istype(host, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = host + var/obj/item/organ/external/head = H.get_organ(BP_HEAD) + if(head) + head.implants -= src + + controlling = FALSE + + host.remove_language("Cortical Link") + host.verbs -= /mob/living/carbon/proc/release_control + host.verbs -= /mob/living/carbon/proc/punish_host + host.verbs -= /mob/living/carbon/proc/spawn_larvae + + if(host_brain) + // these are here so bans and multikey warnings are not triggered on the wrong people when ckey is changed. + // computer_id and IP are not updated magically on their own in offline mobs -walter0o + + // This shit need to die in a phoron fire. + + // host -> self + var/h2s_id = host.computer_id + var/h2s_ip= host.lastKnownIP + host.computer_id = null + host.lastKnownIP = null + + src.ckey = host.ckey + + if(!src.computer_id) + src.computer_id = h2s_id + + if(!host_brain.lastKnownIP) + src.lastKnownIP = h2s_ip + + // brain -> host + var/b2h_id = host_brain.computer_id + var/b2h_ip= host_brain.lastKnownIP + host_brain.computer_id = null + host_brain.lastKnownIP = null + + host.ckey = host_brain.ckey + + if(!host.computer_id) + host.computer_id = b2h_id + + if(!host.lastKnownIP) + host.lastKnownIP = b2h_ip + + qdel(host_brain) + + +/mob/living/simple_mob/animal/borer/proc/leave_host() + if(!host) + return + + if(host.mind) + borers.remove_antagonist(host.mind) + + forceMove(get_turf(host)) + + reset_view(null) + machine = null + + host.reset_view(null) + host.machine = null + host = null + +/mob/living/simple_mob/animal/borer/proc/request_player() + var/datum/ghost_query/Q = new /datum/ghost_query/borer() + var/list/winner = Q.query() // This will sleep the proc for awhile. + if(winner.len) + var/mob/observer/dead/D = winner[1] + transfer_personality(D) + +/mob/living/simple_mob/animal/borer/proc/transfer_personality(mob/candidate) + if(!candidate || !candidate.mind) + return + + src.mind = candidate.mind + candidate.mind.current = src + ckey = candidate.ckey + + if(mind) + mind.assigned_role = "Cortical Borer" + mind.special_role = "Cortical Borer" + + to_chat(src, span("notice", "You are a cortical borer! You are a brain slug that worms its way \ + into the head of its victim. Use stealth, persuasion and your powers of mind control to keep you, \ + your host and your eventual spawn safe and warm.")) + to_chat(src, "You can speak to your victim with say, to other borers with say :x, and use your Abilities tab to access powers.") + +/mob/living/simple_mob/animal/borer/cannot_use_vents() + return + +// This is awful but its literally say code. +/mob/living/simple_mob/animal/borer/say(message) + message = sanitize(message) + message = capitalize(message) + + if(!message) + return + + if(stat >= DEAD) + return say_dead(message) + else if(stat) + return + + if(client && client.prefs.muted & MUTE_IC) + to_chat(src, span("danger", "You cannot speak in IC (muted).")) + return + + if(copytext(message, 1, 2) == "*") + return emote(copytext(message, 2)) + + var/datum/language/L = parse_language(message) + if(L && L.flags & HIVEMIND) + L.broadcast(src,trim(copytext(message,3)), src.true_name) + return + + if(!host) + //TODO: have this pick a random mob within 3 tiles to speak for the borer. + to_chat(src, span("warning", "You have no host to speak to.")) + return //No host, no audible speech. + + to_chat(src, "You drop words into [host]'s mind: \"[message]\"") + to_chat(host, "Your own thoughts speak: \"[message]\"") + + for(var/mob/M in player_list) + if(istype(M, /mob/new_player)) + continue + else if(M.stat == DEAD && M.is_preference_enabled(/datum/client_preference/ghost_ears)) + to_chat(M, "[src.true_name] whispers to [host], \"[message]\"") diff --git a/code/modules/mob/living/simple_animal/borer/borer_captive.dm b/code/modules/mob/living/simple_mob/subtypes/animal/borer/borer_captive.dm similarity index 83% rename from code/modules/mob/living/simple_animal/borer/borer_captive.dm rename to code/modules/mob/living/simple_mob/subtypes/animal/borer/borer_captive.dm index c34dca00e8..f5da079b97 100644 --- a/code/modules/mob/living/simple_animal/borer/borer_captive.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/borer/borer_captive.dm @@ -1,57 +1,59 @@ -/mob/living/captive_brain - name = "host brain" - real_name = "host brain" - universal_understand = 1 - -/mob/living/captive_brain/say(var/message) - - if (src.client) - if(client.prefs.muted & MUTE_IC) - src << "You cannot speak in IC (muted)." - return - - if(istype(src.loc,/mob/living/simple_animal/borer)) - - message = sanitize(message) - if (!message) - return - log_say(message,src) - if (stat == 2) - return say_dead(message) - - var/mob/living/simple_animal/borer/B = src.loc - src << "You whisper silently, \"[message]\"" - B.host << "The captive mind of [src] whispers, \"[message]\"" - - for (var/mob/M in player_list) - if (istype(M, /mob/new_player)) - continue - else if(M.stat == DEAD && M.is_preference_enabled(/datum/client_preference/ghost_ears)) - M << "The captive mind of [src] whispers, \"[message]\"" - -/mob/living/captive_brain/emote(var/message) - return - -/mob/living/captive_brain/process_resist() - //Resisting control by an alien mind. - if(istype(src.loc,/mob/living/simple_animal/borer)) - var/mob/living/simple_animal/borer/B = src.loc - var/mob/living/captive_brain/H = src - - H << "You begin doggedly resisting the parasite's control (this will take approximately sixty seconds)." - B.host << "You feel the captive mind of [src] begin to resist your control." - - spawn(rand(200,250)+B.host.brainloss) - if(!B || !B.controlling) return - - B.host.adjustBrainLoss(rand(0.1,0.5)) - H << "With an immense exertion of will, you regain control of your body!" - B.host << "You feel control of the host brain ripped from your grasp, and retract your probosci before the wild neural impulses can damage you." - B.detatch() - verbs -= /mob/living/carbon/proc/release_control - verbs -= /mob/living/carbon/proc/punish_host - verbs -= /mob/living/carbon/proc/spawn_larvae - - return - - ..() +// Straight move from the old location, with the paths corrected. + +/mob/living/captive_brain + name = "host brain" + real_name = "host brain" + universal_understand = 1 + +/mob/living/captive_brain/say(var/message) + + if (src.client) + if(client.prefs.muted & MUTE_IC) + src << "You cannot speak in IC (muted)." + return + + if(istype(src.loc, /mob/living/simple_mob/animal/borer)) + + message = sanitize(message) + if (!message) + return + log_say(message,src) + if (stat == 2) + return say_dead(message) + + var/mob/living/simple_mob/animal/borer/B = src.loc + src << "You whisper silently, \"[message]\"" + B.host << "The captive mind of [src] whispers, \"[message]\"" + + for (var/mob/M in player_list) + if (istype(M, /mob/new_player)) + continue + else if(M.stat == DEAD && M.is_preference_enabled(/datum/client_preference/ghost_ears)) + M << "The captive mind of [src] whispers, \"[message]\"" + +/mob/living/captive_brain/emote(var/message) + return + +/mob/living/captive_brain/process_resist() + //Resisting control by an alien mind. + if(istype(src.loc, /mob/living/simple_mob/animal/borer)) + var/mob/living/simple_mob/animal/borer/B = src.loc + var/mob/living/captive_brain/H = src + + H << "You begin doggedly resisting the parasite's control (this will take approximately sixty seconds)." + B.host << "You feel the captive mind of [src] begin to resist your control." + + spawn(rand(200,250)+B.host.brainloss) + if(!B || !B.controlling) return + + B.host.adjustBrainLoss(rand(0.1,0.5)) + H << "With an immense exertion of will, you regain control of your body!" + B.host << "You feel control of the host brain ripped from your grasp, and retract your probosci before the wild neural impulses can damage you." + B.detatch() + verbs -= /mob/living/carbon/proc/release_control + verbs -= /mob/living/carbon/proc/punish_host + verbs -= /mob/living/carbon/proc/spawn_larvae + + return + + ..() diff --git a/code/modules/mob/living/simple_animal/borer/borer_powers.dm b/code/modules/mob/living/simple_mob/subtypes/animal/borer/borer_powers.dm similarity index 92% rename from code/modules/mob/living/simple_animal/borer/borer_powers.dm rename to code/modules/mob/living/simple_mob/subtypes/animal/borer/borer_powers.dm index b75da20cc4..55dac2492a 100644 --- a/code/modules/mob/living/simple_animal/borer/borer_powers.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/borer/borer_powers.dm @@ -1,354 +1,354 @@ -/mob/living/simple_animal/borer/verb/release_host() - set category = "Abilities" - set name = "Release Host" - set desc = "Slither out of your host." - - if(!host) - src << "You are not inside a host body." - return - - if(stat) - src << "You cannot leave your host in your current state." - - if(docile) - src << "You are feeling far too docile to do that." - return - - if(!host || !src) return - - src << "You begin disconnecting from [host]'s synapses and prodding at their internal ear canal." - - if(!host.stat) - host << "An odd, uncomfortable pressure begins to build inside your skull, behind your ear..." - - spawn(100) - - if(!host || !src) return - - if(src.stat) - src << "You cannot release your host in your current state." - return - - src << "You wiggle out of [host]'s ear and plop to the ground." - if(host.mind) - if(!host.stat) - host << "Something slimy wiggles out of your ear and plops to the ground!" - host << "As though waking from a dream, you shake off the insidious mind control of the brain worm. Your thoughts are your own again." - - detatch() - leave_host() - -/mob/living/simple_animal/borer/verb/infest() - set category = "Abilities" - set name = "Infest" - set desc = "Infest a suitable humanoid host." - - if(host) - src << "You are already within a host." - return - - if(stat) - src << "You cannot infest a target in your current state." - return - - var/list/choices = list() - for(var/mob/living/carbon/C in view(1,src)) - if(src.Adjacent(C)) - choices += C - - if(!choices.len) - src << "There are no viable hosts within range..." - return - - var/mob/living/carbon/M = input(src,"Who do you wish to infest?") in null|choices - - if(!M || !src) return - - if(!(src.Adjacent(M))) return - - if(M.has_brain_worms()) - src << "You cannot infest someone who is already infested!" - return - - if(istype(M,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = M - - var/obj/item/organ/external/E = H.organs_by_name[BP_HEAD] - if(!E || E.is_stump()) - src << "\The [H] does not have a head!" - - if(!H.should_have_organ("brain")) - src << "\The [H] does not seem to have an ear canal to breach." - return - - if(H.check_head_coverage()) - src << "You cannot get through that host's protective gear." - return - - M << "Something slimy begins probing at the opening of your ear canal..." - src << "You slither up [M] and begin probing at their ear canal..." - - if(!do_after(src,30)) - src << "As [M] moves away, you are dislodged and fall to the ground." - return - - if(!M || !src) return - - if(src.stat) - src << "You cannot infest a target in your current state." - return - - if(M in view(1, src)) - src << "You wiggle into [M]'s ear." - if(!M.stat) - M << "Something disgusting and slimy wiggles into your ear!" - - src.host = M - src.forceMove(M) - - //Update their traitor status. - if(host.mind) - borers.add_antagonist_mind(host.mind, 1, borers.faction_role_text, borers.faction_welcome) - - if(istype(M,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = M - var/obj/item/organ/I = H.internal_organs_by_name["brain"] - if(!I) // No brain organ, so the borer moves in and replaces it permanently. - replace_brain() - else - // If they're in normally, implant removal can get them out. - var/obj/item/organ/external/head = H.get_organ(BP_HEAD) - head.implants += src - - return - else - src << "They are no longer in range!" - return - -/* -/mob/living/simple_animal/borer/verb/devour_brain() - set category = "Abilities" - set name = "Devour Brain" - set desc = "Take permanent control of a dead host." - - if(!host) - src << "You are not inside a host body." - return - - if(host.stat != 2) - src << "Your host is still alive." - return - - if(stat) - src << "You cannot do that in your current state." - - if(docile) - src << "You are feeling far too docile to do that." - return - - - src << "It only takes a few moments to render the dead host brain down into a nutrient-rich slurry..." - replace_brain() -*/ - -// BRAIN WORM ZOMBIES AAAAH. -/mob/living/simple_animal/borer/proc/replace_brain() - - var/mob/living/carbon/human/H = host - - if(!istype(host)) - src << "This host does not have a suitable brain." - return - - src << "You settle into the empty brainpan and begin to expand, fusing inextricably with the dead flesh of [H]." - - H.add_language("Cortical Link") - - if(host.stat == 2) - H.verbs |= /mob/living/carbon/human/proc/jumpstart - - H.verbs |= /mob/living/carbon/human/proc/psychic_whisper - H.verbs |= /mob/living/carbon/human/proc/tackle - H.verbs |= /mob/living/carbon/proc/spawn_larvae - - if(H.client) - H.ghostize(0) - - if(src.mind) - src.mind.special_role = "Borer Husk" - src.mind.transfer_to(host) - - H.ChangeToHusk() - - var/obj/item/organ/internal/borer/B = new(H) - H.internal_organs_by_name["brain"] = B - H.internal_organs |= B - - var/obj/item/organ/external/affecting = H.get_organ(BP_HEAD) - affecting.implants -= src - - var/s2h_id = src.computer_id - var/s2h_ip= src.lastKnownIP - src.computer_id = null - src.lastKnownIP = null - - if(!H.computer_id) - H.computer_id = s2h_id - - if(!H.lastKnownIP) - H.lastKnownIP = s2h_ip - -/mob/living/simple_animal/borer/verb/secrete_chemicals() - set category = "Abilities" - set name = "Secrete Chemicals" - set desc = "Push some chemicals into your host's bloodstream." - - if(!host) - src << "You are not inside a host body." - return - - if(stat) - src << "You cannot secrete chemicals in your current state." - - if(docile) - src << "You are feeling far too docile to do that." - return - - if(chemicals < 50) - src << "You don't have enough chemicals!" - - var/chem = input("Select a chemical to secrete.", "Chemicals") as null|anything in list("alkysine","bicaridine","hyperzine","tramadol") - - if(!chem || chemicals < 50 || !host || controlling || !src || stat) //Sanity check. - return - - src << "You squirt a measure of [chem] from your reservoirs into [host]'s bloodstream." - host.reagents.add_reagent(chem, 10) - chemicals -= 50 - -/mob/living/simple_animal/borer/verb/dominate_victim() - set category = "Abilities" - set name = "Paralyze Victim" - set desc = "Freeze the limbs of a potential host with supernatural fear." - - if(world.time - used_dominate < 150) - src << "You cannot use that ability again so soon." - return - - if(host) - src << "You cannot do that from within a host body." - return - - if(src.stat) - src << "You cannot do that in your current state." - return - - var/list/choices = list() - for(var/mob/living/carbon/C in view(3,src)) - if(C.stat != 2) - choices += C - - if(world.time - used_dominate < 150) - src << "You cannot use that ability again so soon." - return - - var/mob/living/carbon/M = input(src,"Who do you wish to dominate?") in null|choices - - if(!M || !src) return - - if(M.has_brain_worms()) - src << "You cannot infest someone who is already infested!" - return - - src << "You focus your psychic lance on [M] and freeze their limbs with a wave of terrible dread." - M << "You feel a creeping, horrible sense of dread come over you, freezing your limbs and setting your heart racing." - M.Weaken(10) - - used_dominate = world.time - -/mob/living/simple_animal/borer/verb/bond_brain() - set category = "Abilities" - set name = "Assume Control" - set desc = "Fully connect to the brain of your host." - - if(!host) - src << "You are not inside a host body." - return - - if(src.stat) - src << "You cannot do that in your current state." - return - - if(docile) - src << "You are feeling far too docile to do that." - return - - src << "You begin delicately adjusting your connection to the host brain..." - - spawn(100+(host.brainloss*5)) - - if(!host || !src || controlling) - return - else - - src << "You plunge your probosci deep into the cortex of the host brain, interfacing directly with their nervous system." - host << "You feel a strange shifting sensation behind your eyes as an alien consciousness displaces yours." - host.add_language("Cortical Link") - - // host -> brain - var/h2b_id = host.computer_id - var/h2b_ip= host.lastKnownIP - host.computer_id = null - host.lastKnownIP = null - - qdel(host_brain) - host_brain = new(src) - - host_brain.ckey = host.ckey - - host_brain.name = host.name - - if(!host_brain.computer_id) - host_brain.computer_id = h2b_id - - if(!host_brain.lastKnownIP) - host_brain.lastKnownIP = h2b_ip - - // self -> host - var/s2h_id = src.computer_id - var/s2h_ip= src.lastKnownIP - src.computer_id = null - src.lastKnownIP = null - - host.ckey = src.ckey - - if(!host.computer_id) - host.computer_id = s2h_id - - if(!host.lastKnownIP) - host.lastKnownIP = s2h_ip - - controlling = 1 - - host.verbs += /mob/living/carbon/proc/release_control - host.verbs += /mob/living/carbon/proc/punish_host - host.verbs += /mob/living/carbon/proc/spawn_larvae - - return - -/mob/living/carbon/human/proc/jumpstart() - set category = "Abilities" - set name = "Revive Host" - set desc = "Send a jolt of electricity through your host, reviving them." - - if(stat != 2) - usr << "Your host is already alive." - return - - verbs -= /mob/living/carbon/human/proc/jumpstart - visible_message("With a hideous, rattling moan, [src] shudders back to life!") - - rejuvenate() - restore_blood() - fixblood() +/mob/living/simple_mob/animal/borer/verb/release_host() + set category = "Abilities" + set name = "Release Host" + set desc = "Slither out of your host." + + if(!host) + src << "You are not inside a host body." + return + + if(stat) + src << "You cannot leave your host in your current state." + + if(docile) + src << "You are feeling far too docile to do that." + return + + if(!host || !src) return + + src << "You begin disconnecting from [host]'s synapses and prodding at their internal ear canal." + + if(!host.stat) + host << "An odd, uncomfortable pressure begins to build inside your skull, behind your ear..." + + spawn(100) + + if(!host || !src) return + + if(src.stat) + src << "You cannot release your host in your current state." + return + + src << "You wiggle out of [host]'s ear and plop to the ground." + if(host.mind) + if(!host.stat) + host << "Something slimy wiggles out of your ear and plops to the ground!" + host << "As though waking from a dream, you shake off the insidious mind control of the brain worm. Your thoughts are your own again." + + detatch() + leave_host() + +/mob/living/simple_mob/animal/borer/verb/infest() + set category = "Abilities" + set name = "Infest" + set desc = "Infest a suitable humanoid host." + + if(host) + src << "You are already within a host." + return + + if(stat) + src << "You cannot infest a target in your current state." + return + + var/list/choices = list() + for(var/mob/living/carbon/C in view(1,src)) + if(src.Adjacent(C)) + choices += C + + if(!choices.len) + src << "There are no viable hosts within range..." + return + + var/mob/living/carbon/M = input(src,"Who do you wish to infest?") in null|choices + + if(!M || !src) return + + if(!(src.Adjacent(M))) return + + if(M.has_brain_worms()) + src << "You cannot infest someone who is already infested!" + return + + if(istype(M,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = M + + var/obj/item/organ/external/E = H.organs_by_name[BP_HEAD] + if(!E || E.is_stump()) + src << "\The [H] does not have a head!" + + if(!H.should_have_organ("brain")) + src << "\The [H] does not seem to have an ear canal to breach." + return + + if(H.check_head_coverage()) + src << "You cannot get through that host's protective gear." + return + + M << "Something slimy begins probing at the opening of your ear canal..." + src << "You slither up [M] and begin probing at their ear canal..." + + if(!do_after(src,30)) + src << "As [M] moves away, you are dislodged and fall to the ground." + return + + if(!M || !src) return + + if(src.stat) + src << "You cannot infest a target in your current state." + return + + if(M in view(1, src)) + src << "You wiggle into [M]'s ear." + if(!M.stat) + M << "Something disgusting and slimy wiggles into your ear!" + + src.host = M + src.forceMove(M) + + //Update their traitor status. + if(host.mind) + borers.add_antagonist_mind(host.mind, 1, borers.faction_role_text, borers.faction_welcome) + + if(istype(M,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = M + var/obj/item/organ/I = H.internal_organs_by_name["brain"] + if(!I) // No brain organ, so the borer moves in and replaces it permanently. + replace_brain() + else + // If they're in normally, implant removal can get them out. + var/obj/item/organ/external/head = H.get_organ(BP_HEAD) + head.implants += src + + return + else + src << "They are no longer in range!" + return + +/* +/mob/living/simple_mob/animal/borer/verb/devour_brain() + set category = "Abilities" + set name = "Devour Brain" + set desc = "Take permanent control of a dead host." + + if(!host) + src << "You are not inside a host body." + return + + if(host.stat != 2) + src << "Your host is still alive." + return + + if(stat) + src << "You cannot do that in your current state." + + if(docile) + src << "You are feeling far too docile to do that." + return + + + src << "It only takes a few moments to render the dead host brain down into a nutrient-rich slurry..." + replace_brain() +*/ + +// BRAIN WORM ZOMBIES AAAAH. +/mob/living/simple_mob/animal/borer/proc/replace_brain() + + var/mob/living/carbon/human/H = host + + if(!istype(host)) + src << "This host does not have a suitable brain." + return + + src << "You settle into the empty brainpan and begin to expand, fusing inextricably with the dead flesh of [H]." + + H.add_language("Cortical Link") + + if(host.stat == 2) + H.verbs |= /mob/living/carbon/human/proc/jumpstart + + H.verbs |= /mob/living/carbon/human/proc/psychic_whisper + H.verbs |= /mob/living/carbon/human/proc/tackle + H.verbs |= /mob/living/carbon/proc/spawn_larvae + + if(H.client) + H.ghostize(0) + + if(src.mind) + src.mind.special_role = "Borer Husk" + src.mind.transfer_to(host) + + H.ChangeToHusk() + + var/obj/item/organ/internal/borer/B = new(H) + H.internal_organs_by_name["brain"] = B + H.internal_organs |= B + + var/obj/item/organ/external/affecting = H.get_organ(BP_HEAD) + affecting.implants -= src + + var/s2h_id = src.computer_id + var/s2h_ip= src.lastKnownIP + src.computer_id = null + src.lastKnownIP = null + + if(!H.computer_id) + H.computer_id = s2h_id + + if(!H.lastKnownIP) + H.lastKnownIP = s2h_ip + +/mob/living/simple_mob/animal/borer/verb/secrete_chemicals() + set category = "Abilities" + set name = "Secrete Chemicals" + set desc = "Push some chemicals into your host's bloodstream." + + if(!host) + src << "You are not inside a host body." + return + + if(stat) + src << "You cannot secrete chemicals in your current state." + + if(docile) + src << "You are feeling far too docile to do that." + return + + if(chemicals < 50) + src << "You don't have enough chemicals!" + + var/chem = input("Select a chemical to secrete.", "Chemicals") as null|anything in list("alkysine","bicaridine","hyperzine","tramadol") + + if(!chem || chemicals < 50 || !host || controlling || !src || stat) //Sanity check. + return + + src << "You squirt a measure of [chem] from your reservoirs into [host]'s bloodstream." + host.reagents.add_reagent(chem, 10) + chemicals -= 50 + +/mob/living/simple_mob/animal/borer/verb/dominate_victim() + set category = "Abilities" + set name = "Paralyze Victim" + set desc = "Freeze the limbs of a potential host with supernatural fear." + + if(world.time - used_dominate < 150) + src << "You cannot use that ability again so soon." + return + + if(host) + src << "You cannot do that from within a host body." + return + + if(src.stat) + src << "You cannot do that in your current state." + return + + var/list/choices = list() + for(var/mob/living/carbon/C in view(3,src)) + if(C.stat != 2) + choices += C + + if(world.time - used_dominate < 150) + src << "You cannot use that ability again so soon." + return + + var/mob/living/carbon/M = input(src,"Who do you wish to dominate?") in null|choices + + if(!M || !src) return + + if(M.has_brain_worms()) + src << "You cannot infest someone who is already infested!" + return + + src << "You focus your psychic lance on [M] and freeze their limbs with a wave of terrible dread." + M << "You feel a creeping, horrible sense of dread come over you, freezing your limbs and setting your heart racing." + M.Weaken(10) + + used_dominate = world.time + +/mob/living/simple_mob/animal/borer/verb/bond_brain() + set category = "Abilities" + set name = "Assume Control" + set desc = "Fully connect to the brain of your host." + + if(!host) + src << "You are not inside a host body." + return + + if(src.stat) + src << "You cannot do that in your current state." + return + + if(docile) + src << "You are feeling far too docile to do that." + return + + src << "You begin delicately adjusting your connection to the host brain..." + + spawn(100+(host.brainloss*5)) + + if(!host || !src || controlling) + return + else + + src << "You plunge your probosci deep into the cortex of the host brain, interfacing directly with their nervous system." + host << "You feel a strange shifting sensation behind your eyes as an alien consciousness displaces yours." + host.add_language("Cortical Link") + + // host -> brain + var/h2b_id = host.computer_id + var/h2b_ip= host.lastKnownIP + host.computer_id = null + host.lastKnownIP = null + + qdel(host_brain) + host_brain = new(src) + + host_brain.ckey = host.ckey + + host_brain.name = host.name + + if(!host_brain.computer_id) + host_brain.computer_id = h2b_id + + if(!host_brain.lastKnownIP) + host_brain.lastKnownIP = h2b_ip + + // self -> host + var/s2h_id = src.computer_id + var/s2h_ip= src.lastKnownIP + src.computer_id = null + src.lastKnownIP = null + + host.ckey = src.ckey + + if(!host.computer_id) + host.computer_id = s2h_id + + if(!host.lastKnownIP) + host.lastKnownIP = s2h_ip + + controlling = 1 + + host.verbs += /mob/living/carbon/proc/release_control + host.verbs += /mob/living/carbon/proc/punish_host + host.verbs += /mob/living/carbon/proc/spawn_larvae + + return + +/mob/living/carbon/human/proc/jumpstart() + set category = "Abilities" + set name = "Revive Host" + set desc = "Send a jolt of electricity through your host, reviving them." + + if(stat != 2) + usr << "Your host is already alive." + return + + verbs -= /mob/living/carbon/human/proc/jumpstart + visible_message("With a hideous, rattling moan, [src] shudders back to life!") + + rejuvenate() + restore_blood() + fixblood() update_canmove() \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/farm animals/chicken.dm b/code/modules/mob/living/simple_mob/subtypes/animal/farm animals/chicken.dm new file mode 100644 index 0000000000..2bf3568287 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/farm animals/chicken.dm @@ -0,0 +1,156 @@ +GLOBAL_VAR_CONST(MAX_CHICKENS, 50) // How many chickens CAN we have? +GLOBAL_VAR_INIT(chicken_count, 0) // How mant chickens DO we have? + +/mob/living/simple_mob/animal/passive/chicken + name = "chicken" + desc = "Hopefully the eggs are good this season." + tt_desc = "E Gallus gallus" + icon_state = "chicken" + icon_living = "chicken" + icon_dead = "chicken_dead" + + health = 10 + maxHealth = 10 + + pass_flags = PASSTABLE + mob_size = MOB_SMALL + + response_help = "pets" + response_disarm = "gently pushes aside" + response_harm = "kicks" + attacktext = list("kicked") + + has_langs = list("Bird") + + say_list_type = /datum/say_list/chicken + + meat_amount = 2 + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat + + var/eggsleft = 0 + var/body_color + +/mob/living/simple_mob/animal/passive/chicken/New() + ..() + if(!body_color) + body_color = pick( list("brown","black","white") ) + icon_state = "chicken_[body_color]" + icon_living = "chicken_[body_color]" + icon_dead = "chicken_[body_color]_dead" + pixel_x = rand(-6, 6) + pixel_y = rand(0, 10) + GLOB.chicken_count += 1 + +/mob/living/simple_mob/animal/passive/chicken/Destroy() + ..() + GLOB.chicken_count -= 1 + +/mob/living/simple_mob/animal/passive/chicken/attackby(var/obj/item/O as obj, var/mob/user as mob) + if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown)) //feedin' dem chickens + var/obj/item/weapon/reagent_containers/food/snacks/grown/G = O + if(G.seed && G.seed.kitchen_tag == "wheat") + if(!stat && eggsleft < 8) + user.visible_message("[user] feeds [O] to [name]! It clucks happily.","You feed [O] to [name]! It clucks happily.") + user.drop_item() + qdel(O) + eggsleft += rand(1, 4) + else + to_chat(user, "[name] doesn't seem hungry!") + else + to_chat(user, "[name] doesn't seem interested in that.") + else + ..() + +/mob/living/simple_mob/animal/passive/chicken/Life() + . =..() + if(!.) + return + if(!stat && prob(3) && eggsleft > 0) + visible_message("[src] [pick("lays an egg.","squats down and croons.","begins making a huge racket.","begins clucking raucously.")]") + eggsleft-- + var/obj/item/weapon/reagent_containers/food/snacks/egg/E = new(get_turf(src)) + E.pixel_x = rand(-6,6) + E.pixel_y = rand(-6,6) + if(GLOB.chicken_count < GLOB.MAX_CHICKENS && prob(10)) + START_PROCESSING(SSobj, E) + + + + + + + +/obj/item/weapon/reagent_containers/food/snacks/egg/var/amount_grown = 0 + +// This only starts normally if there are less than MAX_CHICKENS chickens +/obj/item/weapon/reagent_containers/food/snacks/egg/process() + if(isturf(loc)) + amount_grown += rand(1,2) + if(amount_grown >= 100) + visible_message("[src] hatches with a quiet cracking sound.") + new /mob/living/simple_mob/animal/passive/chick(get_turf(src)) + STOP_PROCESSING(SSobj, src) + qdel(src) + else + STOP_PROCESSING(SSobj, src) + + + + + + + +/mob/living/simple_mob/animal/passive/chick + name = "chick" + desc = "Adorable! They make such a racket though." + tt_desc = "E Gallus gallus" + icon_state = "chick" + icon_living = "chick" + icon_dead = "chick_dead" + icon_gib = "chick_gib" + + health = 1 + maxHealth = 1 + + pass_flags = PASSTABLE | PASSGRILLE + mob_size = MOB_MINISCULE + + response_help = "pets" + response_disarm = "gently pushes aside" + response_harm = "kicks" + attacktext = list("kicked") + + has_langs = list("Bird") + + say_list_type = /datum/say_list/chick + + meat_amount = 1 + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat + + var/amount_grown = 0 + +/mob/living/simple_mob/animal/passive/chick/New() + ..() + pixel_x = rand(-6, 6) + pixel_y = rand(0, 10) + +/mob/living/simple_mob/animal/passive/chick/Life() + . =..() + if(!.) + return + if(!stat) + amount_grown += rand(1,2) + if(amount_grown >= 100) + new /mob/living/simple_mob/animal/passive/chicken(src.loc) + qdel(src) + +// Say Lists +/datum/say_list/chicken + speak = list("Cluck!","BWAAAAARK BWAK BWAK BWAK!","Bwaak bwak.") + emote_hear = list("clucks","croons") + emote_see = list("pecks at the ground","flaps its wings viciously") + +/datum/say_list/chick + speak = list("Cherp.","Cherp?","Chirrup.","Cheep!") + emote_hear = list("cheeps") + emote_see = list("pecks at the ground","flaps its tiny wings") diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/farm animals/cow.dm b/code/modules/mob/living/simple_mob/subtypes/animal/farm animals/cow.dm new file mode 100644 index 0000000000..b5373c176a --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/farm animals/cow.dm @@ -0,0 +1,67 @@ +/mob/living/simple_mob/animal/passive/cow + name = "cow" + desc = "Known for their milk, just don't tip them over." + tt_desc = "E Bos taurus" + icon_state = "cow" + icon_living = "cow" + icon_dead = "cow_dead" + icon_gib = "cow_gib" + + health = 50 + maxHealth = 50 + + response_help = "pets" + response_disarm = "gently pushes aside" + response_harm = "kicks" + attacktext = list("kicked") + + say_list_type = /datum/say_list/cow + + meat_amount = 6 + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat + + var/datum/reagents/udder = null + +/mob/living/simple_mob/animal/passive/cow/New() + udder = new(50) + udder.my_atom = src + ..() + +/mob/living/simple_mob/animal/passive/cow/attackby(var/obj/item/O as obj, var/mob/user as mob) + var/obj/item/weapon/reagent_containers/glass/G = O + if(stat == CONSCIOUS && istype(G) && G.is_open_container()) + user.visible_message("[user] milks [src] using \the [O].") + var/transfered = udder.trans_id_to(G, "milk", rand(5,10)) + if(G.reagents.total_volume >= G.volume) + to_chat(user, "The [O] is full.") + if(!transfered) + to_chat(user, "The udder is dry. Wait a bit longer...") + else + ..() + +/mob/living/simple_mob/animal/passive/cow/Life() + . = ..() + if(stat == CONSCIOUS) + if(udder && prob(5)) + udder.add_reagent("milk", rand(5, 10)) + +/mob/living/simple_mob/animal/passive/cow/attack_hand(mob/living/carbon/M as mob) + if(!stat && M.a_intent == I_DISARM && icon_state != icon_dead) + M.visible_message("[M] tips over [src].","You tip over [src].") + Weaken(30) + icon_state = icon_dead + spawn(rand(20,50)) + if(!stat && M) + icon_state = icon_living + var/list/responses = list( "[src] looks at you imploringly.", + "[src] looks at you pleadingly", + "[src] looks at you with a resigned expression.", + "[src] seems resigned to its fate.") + to_chat(M, pick(responses)) + else + ..() + +/datum/say_list/cow + speak = list("moo?","moo","MOOOOOO") + emote_hear = list("brays", "moos","moos hauntingly") + emote_see = list("shakes its head") \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/farm animals/goat.dm b/code/modules/mob/living/simple_mob/subtypes/animal/farm animals/goat.dm new file mode 100644 index 0000000000..7ff82a8160 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/farm animals/goat.dm @@ -0,0 +1,81 @@ +/mob/living/simple_mob/animal/goat + name = "goat" + desc = "Not known for their pleasant disposition." + tt_desc = "E Oreamnos americanus" + icon_state = "goat" + icon_living = "goat" + icon_dead = "goat_dead" + + faction = "goat" + + health = 40 + maxHealth = 40 + + response_help = "pets" + response_disarm = "gently pushes aside" + response_harm = "kicks" + + melee_damage_lower = 1 + melee_damage_upper = 5 + attacktext = list("kicked") + + say_list_type = /datum/say_list/goat + ai_holder_type = /datum/ai_holder/simple_mob/retaliate + + meat_amount = 4 + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat + + var/datum/reagents/udder = null + +/mob/living/simple_mob/animal/goat/New() + udder = new(50) + udder.my_atom = src + ..() + +/mob/living/simple_mob/animal/goat/Life() + . = ..() + if(.) + if(stat == CONSCIOUS) + if(udder && prob(5)) + udder.add_reagent("milk", rand(5, 10)) + + if(locate(/obj/effect/plant) in loc) + var/obj/effect/plant/SV = locate() in loc + SV.die_off(1) + + if(locate(/obj/machinery/portable_atmospherics/hydroponics/soil/invisible) in loc) + var/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/SP = locate() in loc + qdel(SP) + + if(!pulledby) + var/obj/effect/plant/food + food = locate(/obj/effect/plant) in oview(5,loc) + if(food) + var/step = get_step_to(src, food, 0) + Move(step) + +/mob/living/simple_mob/animal/goat/Move() + ..() + if(!stat) + for(var/obj/effect/plant/SV in loc) + SV.die_off(1) + +/mob/living/simple_mob/animal/goat/attackby(var/obj/item/O as obj, var/mob/user as mob) + var/obj/item/weapon/reagent_containers/glass/G = O + if(stat == CONSCIOUS && istype(G) && G.is_open_container()) + user.visible_message("[user] milks [src] using \the [O].") + var/transfered = udder.trans_id_to(G, "milk", rand(5,10)) + if(G.reagents.total_volume >= G.volume) + to_chat(user, "The [O] is full.") + if(!transfered) + to_chat(user, "The udder is dry. Wait a bit longer...") + else + ..() + +/datum/say_list/goat + speak = list("EHEHEHEHEH","eh?") + emote_hear = list("brays") + emote_see = list("shakes its head", "stamps a foot", "glares around") + + // say_got_target doesn't seem to handle emotes, but keeping this here in case someone wants to make it work +// say_got_target = list("[src] gets an evil-looking gleam in their eye.") \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/_giant_spider.dm b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/_giant_spider.dm new file mode 100644 index 0000000000..a85463d723 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/_giant_spider.dm @@ -0,0 +1,64 @@ +/* + Spiders come in various types, and are a fairly common enemy both inside and outside the station. + Their attacks can inject reagents, which can cause harm long after the spider is killed. + Thick material will prevent injections, similar to other means of injections. +*/ + +// The base spider, in the 'walking tank' family. +/mob/living/simple_mob/animal/giant_spider + name = "giant spider" + desc = "Furry and brown, it makes you shudder to look at it. This one has deep red eyes." + tt_desc = "Atrax robustus gigantus" + icon_state = "guard" + icon_living = "guard" + icon_dead = "guard_dead" + has_eye_glow = TRUE + + faction = "spiders" + maxHealth = 200 + health = 200 + pass_flags = PASSTABLE + movement_cooldown = 10 + poison_resist = 0.5 + + see_in_dark = 10 + + response_help = "pets" + response_disarm = "gently pushes aside" + response_harm = "punches" + + melee_damage_lower = 18 + melee_damage_upper = 30 + attack_sharp = 1 + attack_edge = 1 + attack_sound = 'sound/weapons/bite.ogg' + + heat_damage_per_tick = 20 + cold_damage_per_tick = 20 + minbodytemp = 175 // So they can all survive Sif without having to be classed under /sif subtype. + + speak_emote = list("chitters") + + meat_amount = 1 + meat_type = /obj/item/weapon/reagent_containers/food/snacks/xenomeat/spidermeat + + say_list_type = /datum/say_list/spider + + var/poison_type = "spidertoxin" // The reagent that gets injected when it attacks. + var/poison_chance = 10 // Chance for injection to occur. + var/poison_per_bite = 5 // Amount added per injection. + +/mob/living/simple_mob/animal/giant_spider/apply_melee_effects(var/atom/A) + if(isliving(A)) + var/mob/living/L = A + if(L.reagents) + var/target_zone = pick(BP_TORSO,BP_TORSO,BP_TORSO,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_HEAD) + if(L.can_inject(src, null, target_zone)) + inject_poison(L, target_zone) + +// Does actual poison injection, after all checks passed. +/mob/living/simple_mob/animal/giant_spider/proc/inject_poison(mob/living/L, target_zone) + if(prob(poison_chance)) + to_chat(L, "You feel a tiny prick.") + L.reagents.add_reagent(poison_type, poison_per_bite) + diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/carrier.dm b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/carrier.dm new file mode 100644 index 0000000000..c17dd9b448 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/carrier.dm @@ -0,0 +1,67 @@ +// Carriers are not too dangerous on their own, but they create more spiders when dying. + +/mob/living/simple_mob/animal/giant_spider/carrier + desc = "Furry, beige, and red, it makes you shudder to look at it. This one has luminous green eyes." + icon_state = "carrier" + icon_living = "carrier" + icon_dead = "carrier_dead" + + maxHealth = 100 + health = 100 + + melee_damage_lower = 8 + melee_damage_upper = 25 + + poison_per_bite = 3 + poison_type = "chloralhydrate" + + movement_cooldown = 5 + + player_msg = "Upon dying, you will release a swarm of spiderlings or young hunter spiders.
      \ + If a spider emerges, you will be placed in control of it." + + var/spiderling_count = 0 + var/spiderling_type = /obj/effect/spider/spiderling + var/swarmling_type = /mob/living/simple_mob/animal/giant_spider/hunter + var/swarmling_faction = "spiders" + var/swarmling_prob = 10 // Odds that a spiderling will be a swarmling instead. + +/mob/living/simple_mob/animal/giant_spider/carrier/Initialize() + spiderling_count = rand(5, 10) + adjust_scale(1.2) + return ..() + +/mob/living/simple_mob/animal/giant_spider/carrier/death() + visible_message(span("warning", "\The [src]'s abdomen splits as it rolls over, spiderlings crawling from the wound.") ) + spawn(1) + var/list/new_spiders = list() + for(var/i = 1 to spiderling_count) + if(prob(swarmling_prob) && src) + var/mob/living/simple_mob/animal/giant_spider/swarmling = new swarmling_type(src.loc) + var/swarm_health = FLOOR(swarmling.maxHealth * 0.4, 1) + var/swarm_dam_lower = FLOOR(melee_damage_lower * 0.4, 1) + var/swarm_dam_upper = FLOOR(melee_damage_upper * 0.4, 1) + swarmling.name = "spiderling" + swarmling.maxHealth = swarm_health + swarmling.health = swarm_health + swarmling.melee_damage_lower = swarm_dam_lower + swarmling.melee_damage_upper = swarm_dam_upper + swarmling.faction = swarmling_faction + swarmling.adjust_scale(0.75) + new_spiders += swarmling + else if(src) + var/obj/effect/spider/spiderling/child = new spiderling_type(src.loc) + child.skitter() + else // We might've gibbed or got deleted. + break + // Transfer our player to their new body, if RNG provided one. + if(new_spiders.len && client) + var/mob/living/simple_mob/animal/giant_spider/new_body = pick(new_spiders) + new_body.key = src.key + return ..() + +/mob/living/simple_mob/animal/giant_spider/carrier/recursive + desc = "Furry, beige, and red, it makes you shudder to look at it. This one has luminous green eyes. \ + You have a distinctly bad feeling about this." + + swarmling_type = /mob/living/simple_mob/animal/giant_spider/carrier/recursive \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/electric.dm b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/electric.dm new file mode 100644 index 0000000000..c3d1f60731 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/electric.dm @@ -0,0 +1,45 @@ +// Electric spiders fire taser-like beams at their enemies. +// TODO: AI + +/mob/living/simple_mob/animal/giant_spider/electric + desc = "Spined and yellow, it makes you shudder to look at it. This one has flickering gold eyes." + icon_state = "spark" + icon_living = "spark" + icon_dead = "spark_dead" + + maxHealth = 210 + health = 210 + + taser_kill = 0 //It -is- the taser. + + base_attack_cooldown = 10 + projectilesound = 'sound/weapons/taser2.ogg' + projectiletype = /obj/item/projectile/beam/stun/electric_spider + + melee_damage_lower = 10 + melee_damage_upper = 25 + + poison_chance = 15 + poison_per_bite = 3 + poison_type = "stimm" + + shock_resist = 0.75 + + player_msg = "You can fire a taser-like ranged attack by clicking on an enemy or tile at a distance." + + ai_holder_type = /datum/ai_holder/simple_mob/ranged/electric_spider + + +/obj/item/projectile/beam/stun/electric_spider + name = "stun beam" + agony = 20 + +// The electric spider's AI. +/datum/ai_holder/simple_mob/ranged/electric_spider + +/datum/ai_holder/simple_mob/ranged/electric_spider/max_range(atom/movable/AM) + if(isliving(AM)) + var/mob/living/L = AM + if(L.incapacitated(INCAPACITATION_DISABLED) || L.stat == UNCONSCIOUS) // If our target is stunned, go in for the kill. + return 1 + return ..() // Do ranged if possible otherwise. \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/frost.dm b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/frost.dm new file mode 100644 index 0000000000..19b85cccd4 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/frost.dm @@ -0,0 +1,20 @@ +// Frost spiders inject cryotoxin, slowing people down (which is very bad if trying to run from spiders). + +/mob/living/simple_mob/animal/giant_spider/frost + desc = "Icy and blue, it makes you shudder to look at it. This one has brilliant blue eyes." + icon_state = "frost" + icon_living = "frost" + icon_dead = "frost_dead" + + maxHealth = 175 + health = 175 + + poison_per_bite = 5 + poison_type = "cryotoxin" + heat_resist = -0.50 + cold_resist = 0.75 + +// Sif variant with a somewhat different desc. +/mob/living/simple_mob/animal/giant_spider/frost/sif + desc = "Icy and blue, it makes you shudder to look at it. This one has brilliant blue eyes. \ + It isn't native to Sif." diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/giant_spider_vr.dm b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/giant_spider_vr.dm new file mode 100644 index 0000000000..831dfb831e --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/giant_spider_vr.dm @@ -0,0 +1,23 @@ +// Slightly placeholder, mostly to replace ion hivebots on V4 +/mob/living/simple_mob/animal/giant_spider/ion + desc = "Furry and green, it makes you shudder to look at it. This one has brilliant green eyes and a hint of static discharge." + tt_desc = "X Brachypelma phorus ionus" + icon_state = "webslinger" + icon_living = "webslinger" + icon_dead = "webslinger_dead" + + maxHealth = 90 + health = 90 + + base_attack_cooldown = 10 + projectilesound = 'sound/weapons/taser2.ogg' + projectiletype = /obj/item/projectile/ion/small + + melee_damage_lower = 8 + melee_damage_upper = 15 + + poison_chance = 15 + poison_per_bite = 2 + poison_type = "psilocybin" + + ai_holder_type = /datum/ai_holder/simple_mob/ranged/electric_spider diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/hunter.dm b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/hunter.dm new file mode 100644 index 0000000000..f3eb1cf81e --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/hunter.dm @@ -0,0 +1,165 @@ +// Hunters are fast, fragile, and possess a leaping attack. +// The leaping attack is somewhat telegraphed and can be dodged if one is paying attention. +// The AI would've followed up after a successful leap with dragging the downed victim away, but the dragging code was too janky. + +/mob/living/simple_mob/animal/giant_spider/hunter + desc = "Furry and black, it makes you shudder to look at it. This one has sparkling purple eyes." + icon_state = "hunter" + icon_living = "hunter" + icon_dead = "hunter_dead" + + maxHealth = 120 + health = 120 + + poison_per_bite = 5 + melee_damage_lower = 9 + melee_damage_upper = 15 + + movement_cooldown = 0 // Hunters are FAST. + + ai_holder_type = /datum/ai_holder/simple_mob/melee/hunter_spider + + player_msg = "You are very fast, and can perform a leaping attack by clicking on someone from a short distance away.
      \ + If the leap succeeds, the target will be knocked down briefly and you will be on top of them.
      \ + Note that there is a short delay before you leap!
      \ + In addition, you will do more damage to incapacitated opponents." + + // Leaping is a special attack, so these values determine when leap can happen. + // Leaping won't occur if its on cooldown. + special_attack_min_range = 2 + special_attack_max_range = 4 + special_attack_cooldown = 10 SECONDS + + var/leap_warmup = 1 SECOND // How long the leap telegraphing is. + var/leap_sound = 'sound/weapons/spiderlunge.ogg' + +// Multiplies damage if the victim is stunned in some form, including a successful leap. +/mob/living/simple_mob/animal/giant_spider/hunter/apply_bonus_melee_damage(atom/A, damage_amount) + if(isliving(A)) + var/mob/living/L = A + if(L.incapacitated(INCAPACITATION_DISABLED)) + return damage_amount * 1.5 + return ..() + + +// The actual leaping attack. +/mob/living/simple_mob/animal/giant_spider/hunter/do_special_attack(atom/A) + set waitfor = FALSE + set_AI_busy(TRUE) + + // Telegraph, since getting stunned suddenly feels bad. + do_windup_animation(A, leap_warmup) + sleep(leap_warmup) // For the telegraphing. + + // Do the actual leap. + status_flags |= LEAPING // Lets us pass over everything. + visible_message(span("danger","\The [src] leaps at \the [A]!")) + throw_at(get_step(get_turf(A), get_turf(src)), special_attack_max_range+1, 1, src) + playsound(src, leap_sound, 75, 1) + + sleep(5) // For the throw to complete. It won't hold up the AI ticker due to waitfor being false. + + if(status_flags & LEAPING) + status_flags &= ~LEAPING // Revert special passage ability. + + var/turf/T = get_turf(src) // Where we landed. This might be different than A's turf. + + . = FALSE + + // Now for the stun. + var/mob/living/victim = null + for(var/mob/living/L in T) // So player-controlled spiders only need to click the tile to stun them. + if(L == src) + continue + + if(ishuman(L)) + var/mob/living/carbon/human/H = L + if(H.check_shields(damage = 0, damage_source = src, attacker = src, def_zone = null, attack_text = "the leap")) + continue // We were blocked. + + victim = L + break + + if(victim) + victim.Weaken(2) + victim.visible_message(span("danger","\The [src] knocks down \the [victim]!")) + to_chat(victim, span("critical", "\The [src] jumps on you!")) + . = TRUE + + set_AI_busy(FALSE) + +// var/obj/item/weapon/grab/G = new(src, victim) +// put_in_active_hand(G) + +// G.synch() +// G.affecting = victim +// victim.LAssailant = src + +// visible_message("\The [src] seizes \the [victim] aggressively!") +// do_attack_animation(victim) + + +// This AI would've isolated people it stuns with its 'leap' attack, by dragging them away. +/datum/ai_holder/simple_mob/melee/hunter_spider + +/* + +/datum/ai_holder/simple_mob/melee/hunter_spider/post_special_attack(mob/living/L) + drag_away(L) + +// Called after a successful leap. +/datum/ai_holder/simple_mob/melee/hunter_spider/proc/drag_away(mob/living/L) + world << "Doing drag_away attack on [L]" + if(!istype(L)) + world << "Invalid type." + return FALSE + + // If they didn't get stunned, then don't bother. + if(!L.incapacitated(INCAPACITATION_DISABLED)) + world << "Not incapcitated." + return FALSE + + // Grab them. + if(!holder.start_pulling(L)) + world << "Failed to pull." + return FALSE + + holder.visible_message(span("danger","\The [holder] starts to drag \the [L] away!")) + + var/list/allies = list() + var/list/enemies = list() + for(var/mob/living/thing in hearers(vision_range, holder)) + if(thing == holder || thing == L) // Don't count ourselves or the thing we just started pulling. + continue + if(holder.IIsAlly(thing)) + allies += thing + else + enemies += thing + + // First priority: Move our victim to our friends. + if(allies.len) + world << "Going to move to ally" + give_destination(get_turf(pick(allies)), min_distance = 2, combat = TRUE) // This will switch our stance. + + // Second priority: Move our victim away from their friends. + // There's a chance of it derping and pulling towards enemies if there's more than two people. + // Preventing that will likely be both a lot of effort for developers and the CPU. + else if(enemies.len) + world << "Going to move away from enemies" + var/mob/living/hostile = pick(enemies) + var/turf/move_to = get_turf(hostile) + for(var/i = 1 to vision_range) // Move them this many steps away from their friend. + move_to = get_step_away(move_to, L, 7) + if(move_to) + give_destination(move_to, min_distance = 2, combat = TRUE) // This will switch our stance. + + // Third priority: Move our victim SOMEWHERE away from where they were. + else + world << "Going to move away randomly" + var/turf/move_to = get_turf(L) + move_to = get_step(move_to, pick(cardinal)) + for(var/i = 1 to vision_range) // Move them this many steps away from where they were before. + move_to = get_step_away(move_to, L, 7) + if(move_to) + give_destination(move_to, min_distance = 2, combat = TRUE) // This will switch our stance. +*/ diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/lurker.dm b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/lurker.dm new file mode 100644 index 0000000000..1f1ecac678 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/lurker.dm @@ -0,0 +1,103 @@ +// Lurkers are somewhat similar to Hunters, however the big difference is that Lurkers have an imperfect cloak. +// Their AI will try to do hit and run tactics, striking the enemy when its "cloaked", for bonus damage and a stun. +// They keep attacking until the stun ends, then retreat to cloak again and repeat the cycle. +// Hitting the spider before it does its ambush attack will break the cloak and make the spider flee. + +/mob/living/simple_mob/animal/giant_spider/lurker + desc = "Translucent and white, it makes you shudder to look at it. This one has incandescent red eyes." + icon_state = "lurker" + icon_living = "lurker" + icon_dead = "lurker_dead" + + maxHealth = 100 + health = 100 + + poison_per_bite = 5 + + movement_cooldown = 5 + + melee_damage_lower = 10 + melee_damage_upper = 10 + poison_chance = 30 + poison_type = "cryptobiolin" + poison_per_bite = 1 + + player_msg = "You have an imperfect, but automatic stealth. If you attack something while 'hidden', then \ + you will do bonus damage, stun the target, and unstealth for a period of time.
      \ + Getting attacked will also break your stealth." + + ai_holder_type = /datum/ai_holder/simple_mob/melee/hit_and_run + + var/cloaked = FALSE + var/cloaked_alpha = 45 // Lower = Harder to see. + var/cloaked_bonus_damage = 30 // This is added on top of the normal melee damage. + var/cloaked_weaken_amount = 3 // How long to stun for. + var/cloak_cooldown = 10 SECONDS // Amount of time needed to re-cloak after losing it. + var/last_uncloak = 0 // world.time + + +/mob/living/simple_mob/animal/giant_spider/lurker/proc/cloak() + if(cloaked) + return + animate(src, alpha = cloaked_alpha, time = 1 SECOND) + cloaked = TRUE + + +/mob/living/simple_mob/animal/giant_spider/lurker/proc/uncloak() + last_uncloak = world.time // This is assigned even if it isn't cloaked already, to 'reset' the timer if the spider is continously getting attacked. + if(!cloaked) + return + animate(src, alpha = initial(alpha), time = 1 SECOND) + cloaked = FALSE + + +// Check if cloaking if possible. +/mob/living/simple_mob/animal/giant_spider/lurker/proc/can_cloak() + if(stat) + return FALSE + if(last_uncloak + cloak_cooldown > world.time) + return FALSE + + return TRUE + + +// Called by things that break cloaks, like Technomancer wards. +/mob/living/simple_mob/animal/giant_spider/lurker/break_cloak() + uncloak() + + +/mob/living/simple_mob/animal/giant_spider/lurker/is_cloaked() + return cloaked + + +// Cloaks the spider automatically, if possible. +/mob/living/simple_mob/animal/giant_spider/lurker/handle_special() + if(!cloaked && can_cloak()) + cloak() + + +// Applies bonus base damage if cloaked. +/mob/living/simple_mob/animal/giant_spider/lurker/apply_bonus_melee_damage(atom/A, damage_amount) + if(cloaked) + return damage_amount + cloaked_bonus_damage + return ..() + +// Applies stun, then uncloaks. +/mob/living/simple_mob/animal/giant_spider/lurker/apply_melee_effects(atom/A) + if(cloaked) + if(isliving(A)) + var/mob/living/L = A + L.Weaken(cloaked_weaken_amount) + to_chat(L, span("danger", "\The [src] ambushes you!")) + playsound(L, 'sound/weapons/spiderlunge.ogg', 75, 1) + uncloak() + ..() // For the poison. + +// Force uncloaking if attacked. +/mob/living/simple_mob/animal/giant_spider/lurker/bullet_act(obj/item/projectile/P) + . = ..() + break_cloak() + +/mob/living/simple_mob/animal/giant_spider/lurker/hit_with_weapon(obj/item/O, mob/living/user, effective_force, hit_zone) + . = ..() + break_cloak() diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/nurse.dm b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/nurse.dm new file mode 100644 index 0000000000..28c51b8a36 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/nurse.dm @@ -0,0 +1,235 @@ +// Nurses, they create webs and eggs. +// They're fragile but their attacks can cause horrifying consequences. +/mob/living/simple_mob/animal/giant_spider/nurse + desc = "Furry and beige, it makes you shudder to look at it. This one has brilliant green eyes." + icon_state = "nurse" + icon_living = "nurse" + icon_dead = "nurse_dead" + + maxHealth = 40 + health = 40 + + movement_cooldown = 5 // A bit faster so that they can inject the eggs easier. + + melee_damage_lower = 5 // Doesn't do a lot of damage, since the goal is to make more spiders with egg attacks. + melee_damage_upper = 10 + poison_per_bite = 5 + poison_type = "stoxin" + + player_msg = "You can spin webs on an adjacent tile, or cocoon an object by clicking on it.
      \ + You can also cocoon a dying or dead entity by clicking on them, and you will gain charges for egg-laying.
      \ + To lay eggs, click a nearby tile. Laying eggs will deplete a charge." + ai_holder_type = /datum/ai_holder/simple_mob/melee/nurse_spider + + var/fed = 0 // Counter for how many egg laying 'charges' the spider has. + var/laying_eggs = FALSE // Only allow one set of eggs to be laid at once. + var/egg_inject_chance = 25 // One in four chance to get eggs. + var/egg_type = /obj/effect/spider/eggcluster/small + var/web_type = /obj/effect/spider/stickyweb/dark + + +/mob/living/simple_mob/animal/giant_spider/nurse/inject_poison(mob/living/L, target_zone) + ..() // Inject the stoxin here. + if(ishuman(L) && prob(egg_inject_chance)) + var/mob/living/carbon/human/H = L + var/obj/item/organ/external/O = H.get_organ(target_zone) + if(O) + var/eggcount = 0 + for(var/obj/effect/spider/eggcluster/E in O.implants) + eggcount++ + if(!eggcount) + var/eggs = new egg_type(O, src) + O.implants += eggs + to_chat(H, span("critical", "\The [src] injects something into your [O.name]!") ) // Oh god its laying eggs in me! + +// Webs target in a web if able to. +/mob/living/simple_mob/animal/giant_spider/nurse/attack_target(atom/A) + if(isturf(A)) + if(fed) + if(!laying_eggs) + return lay_eggs(A) + return web_tile(A) + + if(isliving(A)) + var/mob/living/L = A + if(!L.stat) + return ..() + + if(!istype(A, /atom/movable)) + return + var/atom/movable/AM = A + + if(AM.anchored) + return ..() + + return spin_cocoon(AM) + +/mob/living/simple_mob/animal/giant_spider/nurse/proc/spin_cocoon(atom/movable/AM) + if(!istype(AM)) + return FALSE // We can't cocoon walls sadly. + visible_message(span("notice", "\The [src] begins to secrete a sticky substance around \the [AM].") ) + + // Get our AI to stay still. + set_AI_busy(TRUE) + + if(!do_mob(src, AM, 5 SECONDS)) + set_AI_busy(FALSE) + to_chat(src, span("warning", "You need to stay still to spin a web around \the [AM].")) + return FALSE + + set_AI_busy(FALSE) + + if(!AM) // Make sure it didn't get deleted for whatever reason. + to_chat(src, span("warning", "Whatever you were spinning a web for, its no longer there...")) + return FALSE + + if(!isturf(AM.loc)) + to_chat(src, span("warning", "You can't spin \the [AM] in a web while it is inside \the [AM.loc].")) + return FALSE + + if(!Adjacent(AM)) + to_chat(src, span("warning", "You need to be next to \the [AM] to spin it into a web.")) + return FALSE + + // Finally done with the checks. + var/obj/effect/spider/cocoon/C = new(AM.loc) + var/large_cocoon = FALSE + for(var/mob/living/L in C.loc) + if(istype(L, /mob/living/simple_mob/animal/giant_spider)) // Cannibalism is bad. + continue + fed++ + visible_message(span("warning","\The [src] sticks a proboscis into \the [L], and sucks a viscous substance out.")) + to_chat(src, span("notice", "You've fed upon \the [L], and can now lay [fed] cluster\s of eggs.")) + L.forceMove(C) + large_cocoon = TRUE + break + + // This part's pretty stupid. + for(var/obj/O in C.loc) + if(!O.anchored) + O.forceMove(C) + + // Todo: Put this code on the cocoon object itself? + if(large_cocoon) + C.icon_state = pick("cocoon_large1","cocoon_large2","cocoon_large3") + + return TRUE + +/mob/living/simple_mob/animal/giant_spider/nurse/handle_special() + set waitfor = FALSE + if(get_AI_stance() == STANCE_IDLE && !is_AI_busy() && isturf(loc)) + if(fed) + lay_eggs(loc) + else + web_tile(loc) + +/mob/living/simple_mob/animal/giant_spider/nurse/proc/web_tile(turf/T) + if(!istype(T)) + return FALSE + + var/obj/effect/spider/stickyweb/W = locate() in T + if(W) + return FALSE // Already got webs here. + + visible_message(span("notice", "\The [src] begins to secrete a sticky substance.") ) + // Get our AI to stay still. + set_AI_busy(TRUE) + + if(!do_mob(src, T, 5 SECONDS)) + set_AI_busy(FALSE) + to_chat(src, span("warning", "You need to stay still to spin a web on \the [T].")) + return FALSE + + W = locate() in T + if(W) + return FALSE // Spamclick protection. + + set_AI_busy(FALSE) + new web_type(T) + return TRUE + + +/mob/living/simple_mob/animal/giant_spider/nurse/proc/lay_eggs(turf/T) + if(!istype(T)) + return FALSE + + if(!fed) + return FALSE + + var/obj/effect/spider/eggcluster/E = locate() in T + if(E) + return FALSE // Already got eggs here. + + visible_message(span("notice", "\The [src] begins to lay a cluster of eggs.") ) + // Get our AI to stay still. + set_AI_busy(TRUE) + // Stop players from spamming eggs. + laying_eggs = TRUE + + if(!do_mob(src, T, 5 SECONDS)) + set_AI_busy(FALSE) + to_chat(src, span("warning", "You need to stay still to lay eggs on \the [T].")) + return FALSE + + E = locate() in T + if(E) + return FALSE // Spamclick protection. + + set_AI_busy(FALSE) + new egg_type(T) + fed-- + laying_eggs = FALSE + return TRUE + + +// Variant that 'blocks' light (by being a negative light source). +// This is done to make webbed rooms scary and allow for spiders on the other side of webs to see prey. +/obj/effect/spider/stickyweb/dark + name = "dense web" + desc = "It's sticky, and blocks a lot of light." + light_color = "#FFFFFF" + light_range = 2 + light_power = -3 + +// This is still stupid, but whatever. +/mob/living/simple_mob/animal/giant_spider/nurse/hat + desc = "Furry and beige, it makes you shudder to look at it. This one has brilliant green eyes and a tiny nurse hat." + icon_state = "nursemed" + icon_living = "nursemed" + icon_dead = "nursemed_dead" + + +// The AI for nurse spiders. Wraps things in webs by 'attacking' them. +/datum/ai_holder/simple_mob/melee/nurse_spider + wander = TRUE + base_wander_delay = 8 + cooperative = FALSE // So we don't ask our spider friends to attack things we're webbing. This might also make them stay at the base if their friends find tasty explorers. + +// Get us unachored objects as an option as well. +/datum/ai_holder/simple_mob/melee/nurse_spider/list_targets() + . = ..() + + var/static/alternative_targets = typecacheof(list(/obj/item, /obj/structure)) + + for(var/AT in typecache_filter_list(range(vision_range, holder), alternative_targets)) + var/obj/O = AT + if(can_see(holder, O, vision_range) && !O.anchored) + . += O + +// Select an obj if no mobs are around. +/datum/ai_holder/melee/nurse_spider/pick_target(list/targets) + var/mobs_only = locate(/mob/living) in targets // If a mob is in the list of targets, then ignore objects. + if(mobs_only) + for(var/A in targets) + if(!isliving(A)) + targets -= A + + return ..(targets) + +/datum/ai_holder/simple_mob/melee/nurse_spider/can_attack(atom/movable/the_target) + . = ..() + if(!.) // Parent returned FALSE. + if(istype(the_target, /obj)) + var/obj/O = the_target + if(!O.anchored) + return TRUE diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/pepper.dm b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/pepper.dm new file mode 100644 index 0000000000..a788465e5f --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/pepper.dm @@ -0,0 +1,21 @@ +// Pepper spiders inject condensed capsaicin into their victims. + +/mob/living/simple_mob/animal/giant_spider/pepper + desc = "Red and brown, it makes you shudder to look at it. This one has glinting red eyes." + icon_state = "pepper" + icon_living = "pepper" + icon_dead = "pepper_dead" + + maxHealth = 210 + health = 210 + + melee_damage_lower = 8 + melee_damage_upper = 15 + + poison_chance = 20 + poison_per_bite = 5 + poison_type = "condensedcapsaicin_v" + +/mob/living/simple_mob/animal/giant_spider/pepper/Initialize() + adjust_scale(1.1) + return ..() \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/phorogenic.dm b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/phorogenic.dm new file mode 100644 index 0000000000..4b239ee5c3 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/phorogenic.dm @@ -0,0 +1,56 @@ +// Phorogenic spiders explode when they die. +// You really shouldn't melee them. + +/mob/living/simple_mob/animal/giant_spider/phorogenic + desc = "Crystalline and purple, it makes you shudder to look at it. This one has haunting purple eyes." + icon_state = "phoron" + icon_living = "phoron" + icon_dead = "phoron_dead" + + maxHealth = 225 + health = 225 + taser_kill = FALSE //You will need more than a peashooter to kill the juggernaut. + + melee_damage_lower = 25 + melee_damage_upper = 40 + attack_armor_pen = 15 + + movement_cooldown = 15 + + poison_chance = 30 + poison_per_bite = 0.5 + poison_type = "phoron" + + var/exploded = FALSE + var/explosion_dev_range = 1 + var/explosion_heavy_range = 2 + var/explosion_light_range = 4 + var/explosion_flash_range = 6 // This doesn't do anything iirc. + + var/explosion_delay_lower = 1 SECOND // Lower bound for explosion delay. + var/explosion_delay_upper = 2 SECONDS // Upper bound. + +/mob/living/simple_mob/animal/giant_spider/phorogenic/Initialize() + adjust_scale(1.25) + return ..() + +/mob/living/simple_mob/animal/giant_spider/phorogenic/death() + visible_message(span("critical", "\The [src]'s body begins to rupture!")) + var/delay = rand(explosion_delay_lower, explosion_delay_upper) + spawn(0) + // Flash black and red as a warning. + for(var/i = 1 to delay) + if(i % 2 == 0) + color = "#000000" + else + color = "#FF0000" + sleep(1) + + spawn(delay) + // The actual boom. + if(src && !exploded) + visible_message(span("danger", "\The [src]'s body detonates!")) + exploded = TRUE + explosion(src.loc, explosion_dev_range, explosion_heavy_range, explosion_light_range, explosion_flash_range) + return ..() + diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/thermic.dm b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/thermic.dm new file mode 100644 index 0000000000..dc0a345865 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/thermic.dm @@ -0,0 +1,20 @@ +// Thermic spiders inject a special variant of thermite that burns someone from the inside. + +/mob/living/simple_mob/animal/giant_spider/thermic + desc = "Mirage-cloaked and orange, it makes you shudder to look at it. This one has simmering orange eyes." + icon_state = "pit" + icon_living = "pit" + icon_dead = "pit_dead" + + maxHealth = 175 + health = 175 + + melee_damage_lower = 10 + melee_damage_upper = 25 + + heat_resist = 0.75 + cold_resist = -0.50 + + poison_chance = 30 + poison_per_bite = 1 + poison_type = "thermite_v" diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/tunneler.dm b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/tunneler.dm new file mode 100644 index 0000000000..82a68d4c1f --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/tunneler.dm @@ -0,0 +1,185 @@ +// Tunnelers have a special ability that allows them to charge at an enemy by tunneling towards them. +// Any mobs inbetween the tunneler's path and the target will be stunned if the tunneler hits them. +// The target will suffer a stun as well, if the tunneler hits them at the end. A successful hit will stop the tunneler. +// If the target moves fast enough, the tunneler can miss, causing it to overshoot. +// If the tunneler hits a solid wall, the tunneler will suffer a stun. + +/mob/living/simple_mob/animal/giant_spider/tunneler + desc = "Sandy and brown, it makes you shudder to look at it. This one has glittering yellow eyes." + icon_state = "tunneler" + icon_living = "tunneler" + icon_dead = "tunneler_dead" + + maxHealth = 120 + health = 120 + + melee_damage_lower = 10 + melee_damage_upper = 10 + + poison_chance = 15 + poison_per_bite = 3 + poison_type = "serotrotium_v" + +// ai_holder_type = /datum/ai_holder/simple_mob/melee/tunneler + + player_msg = "You can perform a tunneling attack by clicking on someone from a distance.
      \ + There is a noticable travel delay as you tunnel towards the tile the target was at when you started the tunneling attack.
      \ + Any entities inbetween you and the targeted tile will be stunned for a brief period of time.
      \ + Whatever is on the targeted tile when you arrive will suffer a potent stun.
      \ + If nothing is on the targeted tile, you will overshoot and keep going for a few more tiles.
      \ + If you hit a wall or other solid structure during that time, you will suffer a lengthy stun and be vulnerable to more harm." + + // Tunneling is a special attack, similar to the hunter's Leap. + special_attack_min_range = 2 + special_attack_max_range = 6 + special_attack_cooldown = 10 SECONDS + + var/tunnel_warning = 0.5 SECONDS // How long the dig telegraphing is. + var/tunnel_tile_speed = 2 // How long to wait between each tile. Higher numbers result in an easier to dodge tunnel attack. + +/mob/living/simple_mob/animal/giant_spider/tunneler/frequent + special_attack_cooldown = 5 SECONDS + +/mob/living/simple_mob/animal/giant_spider/tunneler/fast + tunnel_tile_speed = 1 + +/mob/living/simple_mob/animal/giant_spider/tunneler/should_special_attack(atom/A) + // Make sure its possible for the spider to reach the target so it doesn't try to go through a window. + var/turf/destination = get_turf(A) + var/turf/starting_turf = get_turf(src) + var/turf/T = starting_turf + for(var/i = 1 to get_dist(starting_turf, destination)) + if(T == destination) + break + + T = get_step(T, get_dir(T, destination)) + if(T.check_density(ignore_mobs = TRUE)) + return FALSE + return T == destination + + +/mob/living/simple_mob/animal/giant_spider/tunneler/do_special_attack(atom/A) + set waitfor = FALSE + set_AI_busy(TRUE) + + // Save where we're gonna go soon. + var/turf/destination = get_turf(A) + var/turf/starting_turf = get_turf(src) + + // Telegraph to give a small window to dodge if really close. + do_windup_animation(A, tunnel_warning) + sleep(tunnel_warning) // For the telegraphing. + + // Do the dig! + visible_message(span("danger","\The [src] tunnels towards \the [A]!")) + submerge() + + if(handle_tunnel(destination) == FALSE) + set_AI_busy(FALSE) + emerge() + return FALSE + + // Did we make it? + if(!(src in destination)) + set_AI_busy(FALSE) + emerge() + return FALSE + + var/overshoot = TRUE + + // Test if something is at destination. + for(var/mob/living/L in destination) + if(L == src) + continue + + visible_message(span("danger","\The [src] erupts from underneath, and hits \the [L]!")) + playsound(L, 'sound/weapons/heavysmash.ogg', 75, 1) + L.Weaken(3) + overshoot = FALSE + + if(!overshoot) // We hit the target, or something, at destination, so we're done. + set_AI_busy(FALSE) + emerge() + return TRUE + + // Otherwise we need to keep going. + to_chat(src, span("warning", "You overshoot your target!")) + playsound(src, 'sound/weapons/punchmiss.ogg', 75, 1) + var/dir_to_go = get_dir(starting_turf, destination) + for(var/i = 1 to rand(2, 4)) + destination = get_step(destination, dir_to_go) + + if(handle_tunnel(destination) == FALSE) + set_AI_busy(FALSE) + emerge() + return FALSE + + set_AI_busy(FALSE) + emerge() + return FALSE + + + +// Does the tunnel movement, stuns enemies, etc. +/mob/living/simple_mob/animal/giant_spider/tunneler/proc/handle_tunnel(turf/destination) + var/turf/T = get_turf(src) // Hold our current tile. + + // Regular tunnel loop. + for(var/i = 1 to get_dist(src, destination)) + if(stat) + return FALSE // We died or got knocked out on the way. + if(loc == destination) + break // We somehow got there early. + + // Update T. + T = get_step(src, get_dir(src, destination)) + if(T.check_density(ignore_mobs = TRUE)) + to_chat(src, span("critical", "You hit something really solid!")) + playsound(src, "punch", 75, 1) + Weaken(5) + add_modifier(/datum/modifier/tunneler_vulnerable, 10 SECONDS) + return FALSE // Hit a wall. + + // Stun anyone in our way. + for(var/mob/living/L in T) + playsound(L, 'sound/weapons/heavysmash.ogg', 75, 1) + L.Weaken(2) + + // Get into the tile. + forceMove(T) + + // Visuals and sound. + dig_under_floor(get_turf(src)) + playsound(src, 'sound/effects/break_stone.ogg', 75, 1) + sleep(tunnel_tile_speed) + +// For visuals. +/mob/living/simple_mob/animal/giant_spider/tunneler/proc/submerge() + alpha = 0 + dig_under_floor(get_turf(src)) + new /obj/effect/temporary_effect/tunneler_hole(get_turf(src)) + +// Ditto. +/mob/living/simple_mob/animal/giant_spider/tunneler/proc/emerge() + alpha = 255 + dig_under_floor(get_turf(src)) + new /obj/effect/temporary_effect/tunneler_hole(get_turf(src)) + +/mob/living/simple_mob/animal/giant_spider/tunneler/proc/dig_under_floor(turf/T) + new /obj/item/weapon/ore/glass(T) // This will be rather weird when on station but the alternative is too much work. + +/obj/effect/temporary_effect/tunneler_hole + name = "hole" + desc = "A collapsing tunnel hole." + icon_state = "tunnel_hole" + time_to_die = 1 MINUTE + +/datum/modifier/tunneler_vulnerable + name = "Vulnerable" + desc = "You are vulnerable to more harm than usual." + on_created_text = "You feel vulnerable..." + on_expired_text = "You feel better." + stacks = MODIFIER_STACK_EXTEND + + incoming_damage_percent = 2 + evasion = -100 \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/webslinger.dm b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/webslinger.dm new file mode 100644 index 0000000000..dff65f1e2b --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/webslinger.dm @@ -0,0 +1,38 @@ +/mob/living/simple_mob/animal/giant_spider/webslinger + desc = "Furry and green, it makes you shudder to look at it. This one has brilliant green eyes, and a cloak of web." + tt_desc = "X Brachypelma phorus balisticus" + icon_state = "webslinger" + icon_living = "webslinger" + icon_dead = "webslinger_dead" + maxHealth = 90 + health = 90 + projectilesound = 'sound/weapons/thudswoosh.ogg' + projectiletype = /obj/item/projectile/webball + base_attack_cooldown = 10 + melee_damage_lower = 8 + melee_damage_upper = 15 + poison_per_bite = 2 + poison_type = "psilocybin" + player_msg = "You can fire a ranged attack by clicking on an enemy or tile at a distance." + ai_holder_type = /datum/ai_holder/simple_mob/ranged + +// Check if we should bola, or just shoot the pain ball +/mob/living/simple_mob/animal/giant_spider/webslinger/should_special_attack(atom/A) + if(ismob(A)) + if(ishuman(A)) + var/mob/living/carbon/human/H = A + if(!H.legcuffed) + return TRUE + return FALSE + +// Now we've got a running human in sight, time to throw the bola +/mob/living/simple_mob/animal/giant_spider/webslinger/do_special_attack(atom/A) + set waitfor = FALSE + set_AI_busy(TRUE) + var/obj/item/projectile/bola/B = new /obj/item/projectile/bola(src.loc) + playsound(src, 'sound/weapons/thudswoosh.ogg', 100, 1) + if(!B) + return + B.old_style_target(A, src) + B.fire() + set_AI_busy(FALSE) \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/passive/crab.dm b/code/modules/mob/living/simple_mob/subtypes/animal/passive/crab.dm new file mode 100644 index 0000000000..3b40147794 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/passive/crab.dm @@ -0,0 +1,25 @@ +//Look Sir, free crabs! +/mob/living/simple_mob/animal/passive/crab + name = "crab" + desc = "A hard-shelled crustacean. Seems quite content to lounge around all the time." + tt_desc = "E Cancer bellianus" + faction = "crabs" + + icon_state = "crab" + icon_living = "crab" + icon_dead = "crab_dead" + + mob_size = MOB_SMALL + + response_help = "pets" + response_disarm = "gently pushes aside" + response_harm = "stomps" + friendly = "pinches" + + say_list_type = /datum/say_list/crab + +//COFFEE! SQUEEEEEEEEE! +/mob/living/simple_mob/animal/passive/crab/Coffee + name = "Coffee" + real_name = "Coffee" + desc = "It's Coffee, the other pet!" diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/passive/fish.dm b/code/modules/mob/living/simple_mob/subtypes/animal/passive/fish.dm new file mode 100644 index 0000000000..bdf8853b4b --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/passive/fish.dm @@ -0,0 +1,77 @@ +// Different types of fish! They are all subtypes of this tho +/mob/living/simple_mob/animal/passive/fish + name = "fish" + desc = "Its a fishy. No touchy fishy." + icon = 'icons/mob/fish.dmi' + + mob_size = MOB_SMALL + // So fish are actually underwater. + plane = TURF_PLANE + layer = UNDERWATER_LAYER + + // By default they can be in any water turf. Subtypes might restrict to deep/shallow etc + var/global/list/suitable_turf_types = list( + /turf/simulated/floor/beach/water, + /turf/simulated/floor/beach/coastline, + /turf/simulated/floor/holofloor/beach/water, + /turf/simulated/floor/holofloor/beach/coastline, + /turf/simulated/floor/water + ) + +// Makes the AI unable to willingly go on land. +/mob/living/simple_mob/animal/passive/fish/IMove(newloc) + if(is_type_in_list(newloc, suitable_turf_types)) + return ..() // Procede as normal. + return MOVEMENT_FAILED // Don't leave the water! + +// Take damage if we are not in water +/mob/living/simple_mob/animal/passive/fish/handle_breathing() + var/turf/T = get_turf(src) + if(T && !is_type_in_list(T, suitable_turf_types)) + if(prob(50)) + say(pick("Blub", "Glub", "Burble")) + adjustBruteLoss(unsuitable_atoms_damage) + +// Subtypes. +/mob/living/simple_mob/animal/passive/fish/bass + name = "bass" + tt_desc = "E Micropterus notius" + icon_state = "bass-swim" + icon_living = "bass-swim" + icon_dead = "bass-dead" + +/mob/living/simple_mob/animal/passive/fish/trout + name = "trout" + tt_desc = "E Salmo trutta" + icon_state = "trout-swim" + icon_living = "trout-swim" + icon_dead = "trout-dead" + +/mob/living/simple_mob/animal/passive/fish/salmon + name = "salmon" + tt_desc = "E Oncorhynchus nerka" + icon_state = "salmon-swim" + icon_living = "salmon-swim" + icon_dead = "salmon-dead" + +/mob/living/simple_mob/animal/passive/fish/perch + name = "perch" + tt_desc = "E Perca flavescens" + icon_state = "perch-swim" + icon_living = "perch-swim" + icon_dead = "perch-dead" + +/mob/living/simple_mob/animal/passive/fish/pike + name = "pike" + tt_desc = "E Esox aquitanicus" + icon_state = "pike-swim" + icon_living = "pike-swim" + icon_dead = "pike-dead" + +/mob/living/simple_mob/animal/passive/fish/koi + name = "koi" + tt_desc = "E Cyprinus rubrofuscus" + icon_state = "koi-swim" + icon_living = "koi-swim" + icon_dead = "koi-dead" + diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/passive/fish_vr.dm b/code/modules/mob/living/simple_mob/subtypes/animal/passive/fish_vr.dm new file mode 100644 index 0000000000..039dfa7a42 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/passive/fish_vr.dm @@ -0,0 +1,60 @@ +/mob/living/simple_mob/animal/passive/fish/koi/poisonous + desc = "A genetic marvel, combining the docility and aesthetics of the koi with some of the resiliency and cunning of the noble space carp." + health = 50 + maxHealth = 50 + +/mob/living/simple_mob/animal/passive/fish/koi/poisonous/New() + ..() + create_reagents(60) + reagents.add_reagent("toxin", 45) + reagents.add_reagent("impedrezene", 15) + +/mob/living/simple_mob/animal/passive/fish/koi/poisonous/Life() + ..() + if(isbelly(loc) && prob(10)) + var/obj/belly/B = loc + sting(B.owner) + +/mob/living/simple_mob/animal/passive/fish/koi/poisonous/attack_hand(mob/living/L) + ..() + if(isliving(L) && Adjacent(L)) + var/mob/living/M = L + visible_message("\The [src][is_dead()?"'s corpse":""] flails at [M]!") + SpinAnimation(7,1) + if(prob(75)) + if(sting(M)) + to_chat(M, "You feel a tiny prick.") + if(is_dead()) + return + for(var/i = 1 to 3) + var/turf/T = get_step_away(src, M) + if(T && is_type_in_list(T, suitable_turf_types)) + Move(T) + else + break + sleep(3) +/* +/mob/living/simple_mob/animal/passive/fish/koi/poisonous/react_to_attack(var/atom/A) + if(isliving(A) && Adjacent(A)) + var/mob/living/M = A + visible_message("\The [src][is_dead()?"'s corpse":""] flails at [M]!") + SpinAnimation(7,1) + if(prob(75)) + if(sting(M)) + to_chat(M, "You feel a tiny prick.") + if(is_dead()) + return + for(var/i = 1 to 3) + var/turf/T = get_step_away(src, M) + if(T && is_type_in_list(T, suitable_turf_types)) + Move(T) + else + break + sleep(3) +*/ +/mob/living/simple_mob/animal/passive/fish/koi/poisonous/proc/sting(var/mob/living/M) + if(!M.reagents) + return 0 + M.reagents.add_reagent("toxin", 2) + M.reagents.add_reagent("impedrezene", 1) + return 1 \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/passive/lizard.dm b/code/modules/mob/living/simple_mob/subtypes/animal/passive/lizard.dm new file mode 100644 index 0000000000..adb2ea83ca --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/passive/lizard.dm @@ -0,0 +1,24 @@ +/mob/living/simple_mob/animal/passive/lizard + name = "lizard" + desc = "A cute, tiny lizard." + tt_desc = "E Anolis cuvieri" + + icon_state = "lizard" + icon_living = "lizard" + icon_dead = "lizard-dead" + + health = 5 + maxHealth = 5 + mob_size = MOB_MINISCULE + + response_help = "pets" + response_disarm = "shoos" + response_harm = "stomps on" + + attacktext = list("bitten") + melee_damage_lower = 1 + melee_damage_upper = 2 + + speak_emote = list("hisses") + + say_list_type = /datum/say_list/lizard diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/passive/misc.dm b/code/modules/mob/living/simple_mob/subtypes/animal/passive/misc.dm new file mode 100644 index 0000000000..6fc73fc5f9 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/passive/misc.dm @@ -0,0 +1,29 @@ +/mob/living/simple_mob/animal/passive/yithian + name = "yithian" + desc = "A friendly creature vaguely resembling an oversized snail without a shell." + tt_desc = "J Escargot escargot" // a product of Jade, which is a planet that totally exists + + icon_state = "yithian" + icon_living = "yithian" + icon_dead = "yithian_dead" + icon = 'icons/jungle.dmi' + + // Same stats as lizards. + health = 5 + maxHealth = 5 + mob_size = MOB_MINISCULE + +/mob/living/simple_mob/animal/passive/tindalos + name = "tindalos" + desc = "It looks like a large, flightless grasshopper." + tt_desc = "J Locusta bruchus" + + icon_state = "tindalos" + icon_living = "tindalos" + icon_dead = "tindalos_dead" + icon = 'icons/jungle.dmi' + + // Same stats as lizards. + health = 5 + maxHealth = 5 + mob_size = MOB_MINISCULE \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/passive/mouse.dm b/code/modules/mob/living/simple_mob/subtypes/animal/passive/mouse.dm new file mode 100644 index 0000000000..70afdaf910 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/passive/mouse.dm @@ -0,0 +1,115 @@ +/mob/living/simple_mob/animal/passive/mouse + name = "mouse" + real_name = "mouse" + desc = "It's a small rodent." + tt_desc = "E Mus musculus" + icon_state = "mouse_gray" + item_state = "mouse_gray" + icon_living = "mouse_gray" + icon_dead = "mouse_gray_dead" + + maxHealth = 5 + health = 5 + + mob_size = MOB_MINISCULE + pass_flags = PASSTABLE +// can_pull_size = ITEMSIZE_TINY +// can_pull_mobs = MOB_PULL_NONE + layer = MOB_LAYER + density = 0 + + response_help = "pets" + response_disarm = "gently pushes aside" + response_harm = "stamps on" + + min_oxy = 16 //Require atleast 16kPA oxygen + minbodytemp = 223 //Below -50 Degrees Celcius + maxbodytemp = 323 //Above 50 Degrees Celcius + + has_langs = list("Mouse") + + holder_type = /obj/item/weapon/holder/mouse + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat + + say_list_type = /datum/say_list/mouse + + var/body_color //brown, gray and white, leave blank for random + +/mob/living/simple_mob/animal/passive/mouse/New() + ..() + + verbs += /mob/living/proc/ventcrawl + verbs += /mob/living/proc/hide + + if(name == initial(name)) + name = "[name] ([rand(1, 1000)])" + real_name = name + + if(!body_color) + body_color = pick( list("brown","gray","white") ) + icon_state = "mouse_[body_color]" + item_state = "mouse_[body_color]" + icon_living = "mouse_[body_color]" + icon_dead = "mouse_[body_color]_dead" + icon_rest = "mouse_[body_color]_sleep" + desc = "A small [body_color] rodent, often seen hiding in maintenance areas and making a nuisance of itself." + +/mob/living/simple_mob/animal/passive/mouse/Crossed(AM as mob|obj) + if( ishuman(AM) ) + if(!stat) + var/mob/M = AM + M.visible_message("\icon[src] Squeek!") + playsound(src, 'sound/effects/mouse_squeak.ogg', 35, 1) + ..() + +/mob/living/simple_mob/animal/passive/mouse/death() + layer = MOB_LAYER + playsound(src, 'sound/effects/mouse_squeak_loud.ogg', 35, 1) + if(client) + client.time_died_as_mouse = world.time + ..() + +/mob/living/simple_mob/animal/passive/mouse/cannot_use_vents() + return + +/mob/living/simple_mob/animal/passive/mouse/proc/splat() + src.health = 0 + src.stat = DEAD + src.icon_dead = "mouse_[body_color]_splat" + src.icon_state = "mouse_[body_color]_splat" + layer = MOB_LAYER + if(client) + client.time_died_as_mouse = world.time + +/* + * Mouse types + */ + +/mob/living/simple_mob/animal/passive/mouse/white + body_color = "white" + icon_state = "mouse_white" + +/mob/living/simple_mob/animal/passive/mouse/gray + body_color = "gray" + icon_state = "mouse_gray" + +/mob/living/simple_mob/animal/passive/mouse/brown + body_color = "brown" + icon_state = "mouse_brown" + +//TOM IS ALIVE! SQUEEEEEEEE~K :) +/mob/living/simple_mob/animal/passive/mouse/brown/Tom + name = "Tom" + desc = "Jerry the cat is not amused." + +/mob/living/simple_mob/animal/passive/mouse/brown/Tom/New() + ..() + // Change my name back, don't want to be named Tom (666) + name = initial(name) + + +// Mouse noises +/datum/say_list/mouse + speak = list("Squeek!","SQUEEK!","Squeek?") + emote_hear = list("squeeks","squeaks","squiks") + emote_see = list("runs in a circle", "shakes", "scritches at something") \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/passive/passive.dm b/code/modules/mob/living/simple_mob/subtypes/animal/passive/passive.dm new file mode 100644 index 0000000000..c488d1ed28 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/passive/passive.dm @@ -0,0 +1,5 @@ +// Passive mobs can't attack things, and will run away instead. +// They can also be displaced by all mobs. +/mob/living/simple_mob/animal/passive + ai_holder_type = /datum/ai_holder/simple_mob/passive + mob_bump_flag = 0 \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/passive/penguin.dm b/code/modules/mob/living/simple_mob/subtypes/animal/passive/penguin.dm new file mode 100644 index 0000000000..7fcd020f8e --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/passive/penguin.dm @@ -0,0 +1,27 @@ +/mob/living/simple_mob/animal/passive/penguin + name = "penguin" + desc = "An ungainly, waddling, cute, and VERY well-dressed bird." + tt_desc = "Aptenodytes forsteri" + icon_state = "penguin" + icon_living = "penguin" + icon_dead = "penguin_dead" + + maxHealth = 20 + health = 20 + minbodytemp = 175 // Same as Sif mobs. + + response_help = "pets" + response_disarm = "pushes aside" + response_harm = "hits" + + harm_intent_damage = 5 + melee_damage_lower = 10 + melee_damage_upper = 15 + attacktext = list("pecked") + + has_langs = list("Bird") + +/mob/living/simple_mob/animal/passive/penguin/tux + name = "Tux" + desc = "A penguin that has been known to associate with gnus." + speak_emote = list("interjects") diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/pets/bird.dm b/code/modules/mob/living/simple_mob/subtypes/animal/pets/bird.dm new file mode 100644 index 0000000000..5e77a57a3c --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/pets/bird.dm @@ -0,0 +1,93 @@ +// Base bird type. + +/mob/living/simple_mob/animal/passive/bird + name = "bird" + desc = "A domesticated bird. Tweet tweet!" + player_msg = "You are able to fly." + + icon = 'icons/mob/birds.dmi' + icon_state = "parrot" + item_state = null + icon_rest = "parrot-held" + icon_dead = "parrot-dead" + + pass_flags = PASSTABLE + + health = 30 + maxHealth = 30 + melee_damage_lower = 3 + melee_damage_upper = 3 + + movement_cooldown = 0 + hovering = TRUE // Birds can fly. + softfall = TRUE + parachuting = TRUE + + attacktext = list("claws", "pecks") + speak_emote = list("chirps", "caws") + has_langs = list("Bird") + response_help = "pets" + response_disarm = "gently moves aside" + response_harm = "swats" + + say_list_type = /datum/say_list/bird + holder_type = /obj/item/weapon/holder/bird + +/datum/say_list/bird + speak = list("Chirp!","Caw!","Screech!","Squawk!") + emote_hear = list("chirps","caws") + emote_see = list("shakes their head", "ruffles their feathers") + +/obj/item/weapon/holder/bird + name = "bird" + desc = "It's a bird!" + icon_state = null + item_icons = null + w_class = ITEMSIZE_SMALL + +/obj/item/weapon/holder/bird/sync(var/mob/living/simple_mob/SM) + ..() + icon_state = SM.icon_rest // Looks better if the bird isn't flapping constantly in the UI. + +// Subtypes for birbs. + +/mob/living/simple_mob/animal/passive/bird/black_bird + name = "common blackbird" + desc = "A species of bird, both the males and females are known to be territorial on their breeding grounds." + icon_state = "commonblackbird" + icon_dead = "commonblackbird-dead" + tt_desc = "E Turdus merula" + icon_scale = 0.5 + +/mob/living/simple_mob/animal/passive/bird/azure_tit + name = "azure tit" + desc = "A species of bird, colored blue and white." + icon_state = "azuretit" + icon_dead = "azuretit-dead" + tt_desc = "E Cyanistes cyanus" + icon_scale = 0.5 + +/mob/living/simple_mob/animal/passive/bird/european_robin + name = "european robin" + desc = "A species of bird, they have been studied for their sense of magnetoreception." + icon_state = "europeanrobin" + icon_dead = "europeanrobin-dead" + tt_desc = "E Erithacus rubecula" + icon_scale = 0.5 + +/mob/living/simple_mob/animal/passive/bird/goldcrest + name = "goldcrest" + desc = "A species of bird, they were once called 'king of the birds' in ancient human folklore, for their golden crest. \ + Today, their scientific name still elude towards this, with regulus, meaning petty king." + icon_state = "goldcrest" + icon_dead = "goldcrest-dead" + tt_desc = "E Regulus regulus" + icon_scale = 0.5 + +/mob/living/simple_mob/animal/passive/bird/ringneck_dove + name = "ringneck dove" + desc = "A species of bird. They are also known as the barbary dove, and have a distinct ring-like shape around the back of their neck." + icon_state = "ringneckdove" + icon_dead = "ringneckdove-dead" + tt_desc = "E Streptopelia risoria" // This is actually disputed IRL but since we can't tell the future it'll stay the same for 500+ years. + icon_scale = 0.5 diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/pets/cat.dm b/code/modules/mob/living/simple_mob/subtypes/animal/pets/cat.dm new file mode 100644 index 0000000000..8205cd109f --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/pets/cat.dm @@ -0,0 +1,146 @@ +/mob/living/simple_mob/animal/passive/cat + name = "cat" + desc = "A domesticated, feline pet. Has a tendency to adopt crewmembers." + tt_desc = "E Felis silvestris catus" + icon_state = "cat2" + item_state = "cat2" + icon_living = "cat2" + icon_dead = "cat2_dead" + icon_rest = "cat2_rest" + + movement_cooldown = 0.5 SECONDS + + see_in_dark = 6 // Not sure if this actually works. + response_help = "pets" + response_disarm = "gently pushes aside" + response_harm = "kicks" + + holder_type = /obj/item/weapon/holder/cat + mob_size = MOB_SMALL + + has_langs = list("Cat") + + var/mob/living/friend = null // Our best pal, who we'll follow. Meow. + var/friend_name = null //VOREStation Edit - Lock befriending to this character + +/mob/living/simple_mob/animal/passive/cat/handle_special() + if(!stat && prob(2)) // spooky + var/mob/observer/dead/spook = locate() in range(src, 5) + if(spook) + var/turf/T = get_turf(spook) + var/list/visible = list() + for(var/obj/O in T.contents) + if(!O.invisibility && O.name) + visible += O + if(visible.len) + var/atom/A = pick(visible) + visible_emote("suddenly stops and stares at something unseen[istype(A) ? " near [A]":""].") + +// Instakills mice. +/mob/living/simple_mob/animal/passive/cat/apply_melee_effects(var/atom/A) + if(ismouse(A)) + var/mob/living/simple_mob/animal/passive/mouse/mouse = A + if(mouse.getMaxHealth() < 20) // In case a badmin makes giant mice or something. + mouse.splat() + visible_emote(pick("bites \the [mouse]!", "toys with \the [mouse].", "chomps on \the [mouse]!")) + else + ..() + +/mob/living/simple_mob/animal/passive/cat/IIsAlly(mob/living/L) + if(L == friend) // Always be pals with our special friend. + return TRUE + + . = ..() + + if(.) // We're pals, but they might be a dirty mouse... + if(ismouse(L)) + return FALSE // Cats and mice can never get along. + +/mob/living/simple_mob/animal/passive/cat/verb/become_friends() + set name = "Become Friends" + set category = "IC" + set src in view(1) + + var/mob/living/L = usr + if(!istype(L)) + return // Fuck off ghosts. + + if(friend) + if(friend == usr) + to_chat(L, span("notice", "\The [src] is already your friend! Meow!")) + return + else + to_chat(L, span("warning", "\The [src] ignores you.")) + return + + //VOREStation Edit Start - Adds friend_name var checks + if(!friend_name || L.real_name == friend_name) + friend = L + face_atom(L) + to_chat(L, span("notice", "\The [src] is now your friend! Meow.")) + visible_emote(pick("nuzzles [friend].", "brushes against [friend].", "rubs against [friend].", "purrs.")) + + if(has_AI()) + var/datum/ai_holder/AI = ai_holder + AI.set_follow(friend) + else + to_chat(L, span("notice", "[src] ignores you.")) + //VOREStation Edit End + +//RUNTIME IS ALIVE! SQUEEEEEEEE~ +/mob/living/simple_mob/animal/passive/cat/runtime + name = "Runtime" + desc = "Her fur has the look and feel of velvet, and her tail quivers occasionally." + tt_desc = "E Felis silvestris medicalis" // a hypoallergenic breed produced by NT for... medical purposes? Sure. + gender = FEMALE + icon_state = "cat" + item_state = "cat" + icon_living = "cat" + icon_dead = "cat_dead" + icon_rest = "cat_rest" + +/mob/living/simple_mob/animal/passive/cat/kitten + name = "kitten" + desc = "D'aaawwww" + icon_state = "kitten" + item_state = "kitten" + icon_living = "kitten" + icon_dead = "kitten_dead" + gender = NEUTER + holder_type = /obj/item/weapon/holder/cat/kitten //VOREStation Edit + +/mob/living/simple_mob/animal/passive/cat/kitten/Initialize() + if(gender == NEUTER) + gender = pick(MALE, FEMALE) + return ..() + +// Leaving this here for now. +/obj/item/weapon/holder/cat/fluff/bones + name = "Bones" + desc = "It's Bones! Meow." + gender = MALE + icon_state = "cat3" + +/mob/living/simple_mob/animal/passive/cat/bones + name = "Bones" + desc = "That's Bones the cat. He's a laid back, black cat. Meow." + gender = MALE + icon_state = "cat3" + item_state = "cat3" + icon_living = "cat3" + icon_dead = "cat3_dead" + icon_rest = "cat3_rest" + holder_type = /obj/item/weapon/holder/cat/fluff/bones + + +/datum/say_list/cat + speak = list("Meow!","Esp!","Purr!","HSSSSS") + emote_hear = list("meows","mews") + emote_see = list("shakes their head", "shivers") + say_maybe_target = list("Meow?","Mew?","Mao?") + say_got_target = list("MEOW!","HSSSS!","REEER!") + +// VOREStation Edit - Adds generic tactical kittens +/obj/item/weapon/holder/cat/kitten + icon_state = "kitten" + w_class = ITEMSIZE_SMALL diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/pets/cat_vr.dm b/code/modules/mob/living/simple_mob/subtypes/animal/pets/cat_vr.dm new file mode 100644 index 0000000000..c7fc27e56e --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/pets/cat_vr.dm @@ -0,0 +1,86 @@ +/mob/living/simple_mob/animal/passive/cat/runtime/init_vore() + ..() + var/obj/belly/B = vore_selected + B.name = "Stomach" + B.desc = "The slimy wet insides of Runtime! Not quite as clean as the cat on the outside." + + B.emote_lists[DM_HOLD] = list( + "Runtime's stomach kneads gently on you and you're fairly sure you can hear her start purring.", + "Most of what you can hear are slick noises, Runtime breathing, and distant purring.", + "Runtime seems perfectly happy to have you in there. She lays down for a moment to groom and squishes you against the walls.", + "The CMO's pet seems to have found a patient of her own, and is treating them with warm, wet kneading walls.", + "Runtime mostly just lazes about, and you're left to simmer in the hot, slick guts unharmed.", + "Runtime's master might let you out of this fleshy prison, eventually. Maybe. Hopefully?") + + B.emote_lists[DM_DIGEST] = list( + "Runtime's stomach is treating you rather like a mouse, kneading acids into you with vigor.", + "A thick dollop of bellyslime drips from above while the CMO's pet's gut works on churning you up.", + "Runtime seems to have decided you're food, based on the acrid air in her guts and the pooling fluids.", + "Runtime's stomach tries to claim you, kneading and pressing inwards again and again against your form.", + "Runtime flops onto their side for a minute, spilling acids over your form as you remain trapped in them.", + "The CMO's pet doesn't seem to think you're any different from any other meal. At least, their stomach doesn't.") + + B.digest_messages_prey = list( + "Runtime's stomach slowly melts your body away. Her stomach refuses to give up it's onslaught, continuing until you're nothing more than nutrients for her body to absorb.", + "After an agonizing amount of time, Runtime's stomach finally manages to claim you, melting you down and adding you to her stomach.", + "Runtime's stomach continues to slowly work away at your body before tightly squeezing around you once more, causing the remainder of your body to lose form and melt away into the digesting slop around you.", + "Runtime's slimy gut continues to constantly squeeze and knead away at your body, the bulge you create inside of her stomach growing smaller as time progresses before soon dissapearing completely as you melt away.", + "Runtime's belly lets off a soft groan as your body finally gives out, the cat's eyes growing heavy as it settles down to enjoy it's good meal.", + "Runtime purrs happily as you slowly slip away inside of her gut, your body's nutrients are then used to put a layer of padding on the now pudgy cat.", + "The acids inside of Runtime's stomach, aided by the constant motions of the smooth walls surrounding you finally manage to melt you away into nothing more mush. She curls up on the floor, slowly kneading the air as her stomach moves its contents — including you — deeper into her digestive system.", + "Your form begins to slowly soften and break apart, rounding out Runtime's swollen belly. The carnivorous cat rumbles and purrs happily at the feeling of such a filling meal.") + +// Ascian's Tactical Kitten +/obj/item/weapon/holder/cat/fluff/tabiranth + name = "Spirit" + desc = "A small, inquisitive feline, who constantly seems to investigate his surroundings." + gender = MALE + icon_state = "kitten" + w_class = ITEMSIZE_SMALL + +/mob/living/simple_mob/animal/passive/cat/tabiranth + name = "Spirit" + desc = "A small, inquisitive feline, who constantly seems to investigate his surroundings." + icon = 'icons/mob/custom_items_mob.dmi' + icon_state = "kitten" + item_state = "kitten" + icon_living = "kitten" + icon_dead = "kitten" //Teleports out + gender = MALE + holder_type = /obj/item/weapon/holder/cat/fluff/tabiranth + friend_name = "Ascian" + digestable = 0 + meat_amount = 0 + maxHealth = 50 + health = 50 + +/mob/living/simple_mob/animal/passive/cat/tabiranth/handle_special() + . = ..() + if (has_AI() && friend) + var/friend_dist = get_dist(src,friend) + if (friend_dist <= 1) + if (friend.stat >= DEAD || friend.health <= config.health_threshold_softcrit) + if (prob((friend.stat < DEAD)? 50 : 15)) + var/verb = pick("meows", "mews", "mrowls") + audible_emote(pick("[verb] in distress.", "[verb] anxiously.")) + else + if (prob(5)) + visible_emote(pick("nuzzles [friend].", + "brushes against [friend].", + "rubs against [friend].", + "purrs.")) + else if (friend.health <= 50) + if (prob(10)) + var/verb = pick("meows", "mews", "mrowls") + audible_emote("[verb] anxiously.") + +//Emergency teleport - Until a spriter makes something better +/mob/living/simple_mob/animal/passive/cat/tabiranth/death(gibbed, deathmessage = "teleports away!") + overlays = list() + icon_state = "" + flick("kphaseout",src) + spawn(1 SECOND) + qdel(src) //Back from whence you came! + + . = ..(FALSE, deathmessage) + diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/pets/dog.dm b/code/modules/mob/living/simple_mob/subtypes/animal/pets/dog.dm new file mode 100644 index 0000000000..fbfafc426a --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/pets/dog.dm @@ -0,0 +1,234 @@ +/mob/living/simple_mob/animal/passive/dog + name = "dog" + real_name = "dog" + desc = "It's a dog." + tt_desc = "E Canis lupus familiaris" + icon_state = "corgi" + icon_living = "corgi" + icon_dead = "corgi_dead" + + health = 20 + maxHealth = 20 + + response_help = "pets" + response_disarm = "bops" + response_harm = "kicks" + + mob_size = MOB_SMALL + + has_langs = list("Dog") + + say_list_type = /datum/say_list/dog + + meat_amount = 3 + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/corgi + + var/obj/item/inventory_head + var/obj/item/inventory_back + + +/mob/living/simple_mob/animal/passive/dog/attackby(var/obj/item/O as obj, var/mob/user as mob) + if(istype(O, /obj/item/weapon/newspaper)) + if(!stat) + for(var/mob/M in viewers(user, null)) + if ((M.client && !( M.blinded ))) + M.show_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)) + set_dir(i) + sleep(1) + else + ..() + +/mob/living/simple_mob/animal/passive/dog/regenerate_icons() + overlays = list() + + if(inventory_head) + var/head_icon_state = inventory_head.icon_state + if(health <= 0) + head_icon_state += "2" + + var/icon/head_icon = image('icons/mob/corgi_head.dmi',head_icon_state) + if(head_icon) + overlays += head_icon + + if(inventory_back) + var/back_icon_state = inventory_back.icon_state + if(health <= 0) + back_icon_state += "2" + + var/icon/back_icon = image('icons/mob/corgi_back.dmi',back_icon_state) + if(back_icon) + overlays += back_icon + + return + + + + +/obj/item/weapon/reagent_containers/food/snacks/meat/corgi + name = "corgi meat" + desc = "Tastes like... well, you know..." + + + + +/datum/say_list/dog + speak = list("YAP", "Woof!", "Bark!", "AUUUUUU") + emote_hear = list("barks", "woofs", "yaps","pants") + emote_see = list("shakes its head", "shivers") + +// This exists so not every type of dog has to be a subtype of corgi, and in case we get more dog sprites +/mob/living/simple_mob/animal/passive/dog/corgi + name = "corgi" + real_name = "corgi" + desc = "It's a corgi." + tt_desc = "E Canis lupus familiaris" + icon_state = "corgi" + icon_living = "corgi" + icon_dead = "corgi_dead" + +/mob/living/simple_mob/animal/passive/dog/corgi/puppy + name = "corgi puppy" + real_name = "corgi" + desc = "It's a corgi puppy." + icon_state = "puppy" + icon_living = "puppy" + icon_dead = "puppy_dead" + +//pupplies cannot wear anything. +/mob/living/simple_mob/animal/passive/dog/corgi/puppy/Topic(href, href_list) + if(href_list["remove_inv"] || href_list["add_inv"]) + usr << "You can't fit this on [src]" + return + ..() + +/mob/living/simple_mob/animal/passive/dog/corgi/puppy/Bockscar + name = "Bockscar" + real_name = "Bockscar" + +//IAN! SQUEEEEEEEEE~ +/mob/living/simple_mob/animal/passive/dog/corgi/Ian + name = "Ian" + real_name = "Ian" //Intended to hold the name without altering it. + gender = MALE + desc = "It's a corgi." + var/turns_since_scan = 0 + var/obj/movement_target + +/mob/living/simple_mob/animal/passive/dog/corgi/Ian/Life() + ..() + + //Not replacing with SA FollowTarget mechanics because Ian behaves... very... specifically. + + //Feeding, chasing food, FOOOOODDDD + if(!stat && !resting && !buckled) + turns_since_scan++ + if(turns_since_scan > 5) + turns_since_scan = 0 + if((movement_target) && !(isturf(movement_target.loc) || ishuman(movement_target.loc) )) + movement_target = null + if( !movement_target || !(movement_target.loc in oview(src, 3)) ) + movement_target = null + for(var/obj/item/weapon/reagent_containers/food/snacks/S in oview(src,3)) + if(isturf(S.loc) || ishuman(S.loc)) + movement_target = S + break + if(movement_target) + step_to(src,movement_target,1) + sleep(3) + step_to(src,movement_target,1) + sleep(3) + step_to(src,movement_target,1) + + if(movement_target) //Not redundant due to sleeps, Item can be gone in 6 decisecomds + if (movement_target.loc.x < src.x) + set_dir(WEST) + else if (movement_target.loc.x > src.x) + set_dir(EAST) + else if (movement_target.loc.y < src.y) + set_dir(SOUTH) + else if (movement_target.loc.y > src.y) + set_dir(NORTH) + else + set_dir(SOUTH) + + if(isturf(movement_target.loc) ) + UnarmedAttack(movement_target) + else if(ishuman(movement_target.loc) && prob(20)) + visible_emote("stares at the [movement_target] that [movement_target.loc] has with sad puppy eyes.") + + if(prob(1)) + visible_emote(pick("dances around","chases their 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)) + set_dir(i) + sleep(1) + +//LISA! SQUEEEEEEEEE~ +/mob/living/simple_mob/animal/passive/dog/corgi/Lisa + name = "Lisa" + real_name = "Lisa" + gender = FEMALE + desc = "It's a corgi with a cute pink bow." + icon_state = "lisa" + icon_living = "lisa" + icon_dead = "lisa_dead" + response_help = "pets" + response_disarm = "bops" + response_harm = "kicks" + var/turns_since_scan = 0 + var/puppies = 0 + +//Lisa already has a cute bow! +/mob/living/simple_mob/animal/passive/dog/corgi/Lisa/Topic(href, href_list) + if(href_list["remove_inv"] || href_list["add_inv"]) + to_chat(usr, "[src] already has a cute bow!") + return + ..() + +/mob/living/simple_mob/animal/passive/dog/corgi/Lisa/Life() + ..() + + if(!stat && !resting && !buckled) + turns_since_scan++ + if(turns_since_scan > 15) + turns_since_scan = 0 + var/alone = TRUE + var/ian = FALSE + for(var/mob/M in oviewers(7, src)) + if(istype(M, /mob/living/simple_mob/animal/passive/dog/corgi/Ian)) + if(M.client) + alone = FALSE + break + else + ian = M + else + alone = FALSE + break + if(alone && ian && puppies < 4) + if(near_camera(src) || near_camera(ian)) + return + new /mob/living/simple_mob/animal/passive/dog/corgi/puppy(loc) + + if(prob(1)) + visible_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)) + set_dir(i) + sleep(1) + +// Tamaskans +/mob/living/simple_mob/animal/passive/dog/tamaskan + name = "tamaskan" + real_name = "tamaskan" + desc = "It's a tamaskan." + icon_state = "tamaskan" + icon_living = "tamaskan" + icon_dead = "tamaskan_dead" + +/mob/living/simple_mob/animal/passive/dog/tamaskan/Spice + name = "Spice" + real_name = "Spice" //Intended to hold the name without altering it. + gender = FEMALE + desc = "It's a tamaskan, the name Spice can be found on its collar." \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/pets/fox_vr.dm b/code/modules/mob/living/simple_mob/subtypes/animal/pets/fox_vr.dm new file mode 100644 index 0000000000..4d69627df6 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/pets/fox_vr.dm @@ -0,0 +1,243 @@ +/mob/living/simple_mob/animal/fox_vr + name = "fox" + desc = "It's a fox. I wonder what it says?" + tt_desc = "Vulpes vulpes" + + icon_state = "fox2" + icon_living = "fox2" + icon_dead = "fox2_dead" + icon_rest = "fox2_rest" + icon = 'icons/mob/fox_vr.dmi' + + movement_cooldown = 0.5 + see_in_dark = 6 + mob_size = MOB_SMALL //Foxes are not smaller than cats so bumping them up to small + + faction = "fox_vr" + + response_help = "scritches" + response_disarm = "gently pushes aside" + response_harm = "kicks" + + min_oxy = 16 //Require atleast 16kPA oxygen + minbodytemp = 223 //Below -50 Degrees Celcius + maxbodytemp = 323 //Above 50 Degrees Celcius + + meat_amount = 1 + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/fox + + say_list_type = /datum/say_list/fox_vr + ai_holder_type = /datum/ai_holder/simple_mob/fox_vr + + var/turns_since_scan = 0 + var/mob/flee_target + +/datum/say_list/fox_vr + speak = list("Ack-Ack","Ack-Ack-Ack-Ackawoooo","Awoo","Tchoff") + emote_hear = list("howls","barks","geckers",) + emote_see = list("shakes its head", "shivers", "geckers") + say_maybe_target = list("Yip?","Yap?") + say_got_target = list("YAP!","YIP!") + +/datum/ai_holder/simple_mob/fox_vr + hostile = FALSE + cooperative = TRUE + returns_home = FALSE + retaliate = TRUE + can_flee = TRUE + speak_chance = 1 // If the mob's saylist is empty, nothing will happen. + wander = TRUE + base_wander_delay = 4 + +/mob/living/simple_mob/animal/fox_vr/init_vore() + ..() + var/obj/belly/B = vore_selected + B.name = "Stomach" + B.desc = "Slick foxguts. Cute on the outside, slimy on the inside!" + + B.emote_lists[DM_HOLD] = list( + "The foxguts knead and churn around you harmlessly.", + "With a loud glorp, some air shifts inside the belly.", + "A thick drop of warm bellyslime drips onto you from above.", + "The fox turns suddenly, causing you to shift a little.", + "During a moment of relative silence, you can hear the fox breathing.", + "The slimey stomach walls squeeze you lightly, then relax.") + + B.emote_lists[DM_DIGEST] = list( + "The guts knead at you, trying to work you into thick soup.", + "You're ground on by the slimey walls, treated like a mouse.", + "The acrid air is hard to breathe, and stings at your lungs.", + "You can feel the acids coating you, ground in by the slick walls.", + "The fox's stomach churns hungrily over your form, trying to take you.", + "With a loud glorp, the stomach spills more acids onto you.") + +/mob/living/simple_mob/animal/fox_vr/apply_melee_effects(var/atom/A) + if(ismouse(A)) + var/mob/living/simple_mob/animal/passive/mouse/mouse = A + if(mouse.getMaxHealth() < 20) // In case a badmin makes giant mice or something. + mouse.splat() + visible_emote(pick("bites \the [mouse]!", "toys with \the [mouse].", "chomps on \the [mouse]!")) + else + ..() + +/mob/living/simple_mob/animal/fox_vr/MouseDrop(atom/over_object) + var/mob/living/carbon/H = over_object + if(!istype(H) || !Adjacent(H)) return ..() + + if(H.a_intent == "help") + get_scooped(H) + return + else + return ..() + +/mob/living/simple_mob/animal/fox_vr/get_scooped(var/mob/living/carbon/grabber) + if (stat >= DEAD) + return //since the holder icon looks like a living cat + ..() + +/mob/living/simple_mob/animal/fox_vr/Renault/IIsAlly(mob/living/L) + if(L == friend) // Always be pals with our special friend. + return TRUE + + . = ..() + + if(.) // We're pals, but they might be a dirty mouse... + if(ismouse(L)) + return FALSE // Cats and mice can never get along. + +/mob/living/simple_mob/animal/fox_vr/Renault/verb/become_friends() + set name = "Become Friends" + set category = "IC" + set src in view(1) + + var/mob/living/L = usr + if(!istype(L)) + return // Fuck off ghosts. + + if(friend) + if(friend == usr) + to_chat(L, span("notice", "\The [src] is already your friend!")) + return + else + to_chat(L, span("warning", "\The [src] ignores you.")) + return + + friend = L + face_atom(L) + to_chat(L, span("notice", "\The [src] is now your friend!")) + visible_emote(pick("nips [friend].", "brushes against [friend].", "tugs on [friend].", "chrrrrs.")) + + if(has_AI()) + var/datum/ai_holder/AI = ai_holder + AI.set_follow(friend) + +/* Old fox friend AI, I'm not sure how to add the fancy "friend is dead" stuff so I'm commenting it out for someone else to figure it out, this is just baseline stuff. +//Basic friend AI +/mob/living/simple_mob/animal/fox_vr/fluff + var/mob/living/carbon/human/friend + var/befriend_job = null + +/mob/living/simple_mob/animal/fox_vr/fluff/Life() + . = ..() + if(!. || !friend) return + + var/friend_dist = get_dist(src,friend) + + if (friend_dist <= 4) + if(stance == STANCE_IDLE) + if(set_follow(friend)) + handle_stance(STANCE_FOLLOW) + + if (friend_dist <= 1) + if (friend.stat >= DEAD || friend.health <= config.health_threshold_softcrit) + if (prob((friend.stat < DEAD)? 50 : 15)) + var/verb = pick("yaps", "howls", "whines") + audible_emote(pick("[verb] in distress.", "[verb] anxiously.")) + else + if (prob(5)) + visible_emote(pick("nips [friend].", + "brushes against [friend].", + "tugs on [friend].", + "chrrrrs.")) + else if (friend.health <= 50) + if (prob(10)) + var/verb = pick("yaps", "howls", "whines") + audible_emote("[verb] anxiously.") + +/mob/living/simple_mob/animal/fox_vr/fluff/verb/friend() + set name = "Become Friends" + set category = "IC" + set src in view(1) + + if(friend && usr == friend) + set_dir(get_dir(src, friend)) + say("Yap!") + return + + if (!(ishuman(usr) && befriend_job && usr.job == befriend_job)) + usr << "[src] ignores you." + return + + friend = usr + + set_dir(get_dir(src, friend)) + say("Yap!") +*/ +/obj/item/weapon/reagent_containers/food/snacks/meat/fox + name = "Fox meat" + desc = "The fox doesn't say a goddamn thing, now." + +//Captain fox +/mob/living/simple_mob/animal/fox_vr/Renault + name = "Renault" + desc = "Renault, the Colony Director's trustworthy fox. I wonder what it says?" + tt_desc = "Vulpes nobilis" + //befriend_job = "Colony Director" Sebbe edit: couldn't make this work, commenting out for now. + + var/mob/living/friend = null // Our best pal, who we'll follow. awoo. + ai_holder_type = /datum/ai_holder/simple_mob/passive + +/mob/living/simple_mob/animal/fox_vr/Renault/init_vore() + ..() + var/obj/belly/B = vore_selected + B.name = "Stomach" + B.desc = "Slick foxguts. They seem somehow more regal than perhaps other foxes!" + + B.emote_lists[DM_HOLD] = list( + "Renault's stomach walls squeeze around you more tightly for a moment, before relaxing, as if testing you a bit.", + "There's a sudden squeezing as Renault presses a forepaw against his gut over you, squeezing you against the slick walls.", + "The 'head fox' has a stomach that seems to think you belong to it. It might be hard to argue, as it kneads at your form.", + "If being in the captain's fox is a promotion, it might not feel like one. The belly just coats you with more thick foxslime.", + "It doesn't seem like Renault wants to let you out. The stomach and owner possessively squeeze around you.", + "Renault's stomach walls squeeze closer, as he belches quietly, before swallowing more air. Does he do that on purpose?") + + B.emote_lists[DM_DIGEST] = list( + "Renault's stomach walls grind hungrily inwards, kneading acids against your form, and treating you like any other food.", + "The captain's fox impatiently kneads and works acids against you, trying to claim your body for fuel.", + "The walls knead in firmly, squeezing and tossing you around briefly in disorienting aggression.", + "Renault belches, letting the remaining air grow more acrid. It burns your lungs with each breath.", + "A thick glob of acids drip down from above, adding to the pool of caustic fluids in Renault's belly.", + "There's a loud gurgle as the stomach declares the intent to make you a part of Renault.") + +/mob/living/simple_mob/animal/fox_vr/syndicate + name = "syndi-fox" + desc = "It's a DASTARDLY fox! The horror! Call the shuttle!" + tt_desc = "Vulpes malus" + icon = 'icons/mob/fox_vr.dmi' + icon_state = "syndifox" + icon_living = "syndifox" + icon_dead = "syndifox_dead" + icon_rest = "syndifox_rest" + + // this fox wears a hardsuit + maxHealth = 100 + health = 100 + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + minbodytemp = 0 \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/pets/parrot.dm b/code/modules/mob/living/simple_mob/subtypes/animal/pets/parrot.dm new file mode 100644 index 0000000000..44c9ad1b8b --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/pets/parrot.dm @@ -0,0 +1,252 @@ +// Parrots can talk, and may repeat things it hears. +/mob/living/simple_mob/animal/passive/bird/parrot + name = "parrot" + description_info = "You can give it a headset by clicking on it with a headset. \ + To remove it, click the bird while on grab intent." + has_langs = list("Galactic Common", "Bird") + + ai_holder_type = /datum/ai_holder/simple_mob/passive/parrot + + // A headset, so that talking parrots can yell at the crew over comms. + // If set to a type, on initialize it will be instantiated into that type. + var/obj/item/device/radio/headset/my_headset = null + +// Say list +/datum/say_list/bird/poly + speak = list( + "Poly wanna cracker!", + "Check the singulo, you chucklefucks!", + "Wire the solars, you lazy bums!", + "WHO TOOK THE DAMN HARDSUITS?", + "OH GOD ITS FREE CALL THE SHUTTLE", + "Danger! Crystal hyperstructure instability!", + "CRYSTAL DELAMINATION IMMINENT.", + "Tweet tweet, I'm a Teshari.", + "Chitters.", + "Meteors have been detected on a collision course with the station!" + ) + +// Lets the AI use headsets. +// Player-controlled parrots will need to do it manually. +/mob/living/simple_mob/animal/passive/bird/parrot/ISay(message) + if(my_headset && prob(50)) + var/list/keys = list() + for(var/channel in my_headset.channels) + var/key = get_radio_key_from_channel(channel) + if(key) + keys += key + if(keys.len) + var/key_used = pick(keys) + return say("[key_used] [message]") + return say(message) + +// Ugly saycode so parrots can use their headsets. +/mob/living/simple_mob/animal/passive/bird/parrot/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name) + ..() + if(message_mode) + if(my_headset && istype(my_headset, /obj/item/device/radio)) + my_headset.talk_into(src, message, message_mode, verb, speaking) + used_radios += my_headset + +// Clicked on while holding an object. +/mob/living/simple_mob/animal/passive/bird/parrot/attackby(obj/item/I, mob/user) + if(istype(I, /obj/item/device/radio/headset)) + give_headset(I, user) + return + return ..() + +// Clicked on by empty hand. +/mob/living/simple_mob/animal/passive/bird/parrot/attack_hand(mob/living/L) + if(L.a_intent == I_GRAB && my_headset) + remove_headset(L) + else + ..() + + +/mob/living/simple_mob/animal/passive/bird/parrot/proc/give_headset(obj/item/device/radio/headset/new_headset, mob/living/user) + if(!istype(new_headset)) + to_chat(user, span("warning", "\The [new_headset] isn't a headset.")) + return + if(my_headset) + to_chat(user, span("warning", "\The [src] is already wearing \a [my_headset].")) + return + else + user.drop_item(new_headset) + my_headset = new_headset + new_headset.forceMove(src) + to_chat(user, span("warning", "You place \a [new_headset] on \the [src]. You monster.")) + to_chat(src, span("notice", "\The [user] gives you \a [new_headset]. You should put it to good use immediately.")) + return + +/mob/living/simple_mob/animal/passive/bird/parrot/proc/remove_headset(mob/living/user) + if(!my_headset) + to_chat(user, "\The [src] doesn't have a headset to remove, thankfully.") + else + ISay("BAWWWWWK LEAVE THE HEADSET BAWKKKKK!") + my_headset.forceMove(get_turf(src)) + user.put_in_hands(my_headset) + to_chat(user, span("notice", "You take away \the [src]'s [my_headset.name]. Finally.")) + to_chat(src, span("warning", "\The [user] takes your [my_headset.name] away! How cruel!")) + my_headset = null + +/mob/living/simple_mob/animal/passive/bird/parrot/examine(mob/user) + ..() + if(my_headset) + to_chat(user, "It is wearing \a [my_headset].") + +/mob/living/simple_mob/animal/passive/bird/parrot/Initialize() + if(my_headset) + my_headset = new my_headset(src) + return ..() + +// Subtypes. + +// Best Bird +/mob/living/simple_mob/animal/passive/bird/parrot/poly + name = "Poly" + desc = "It's a parrot. An expert on quantum cracker theory." + icon_state = "poly" + icon_rest = "poly-held" + icon_dead = "poly-dead" + tt_desc = "E Ara macao" + my_headset = /obj/item/device/radio/headset/headset_eng + say_list_type = /datum/say_list/bird/poly + +// Best Bird with best headset. +/mob/living/simple_mob/animal/passive/bird/parrot/poly/ultimate + my_headset = /obj/item/device/radio/headset/omni + +/mob/living/simple_mob/animal/passive/bird/parrot/kea + name = "kea" + desc = "A species of parrot. On Earth, they are unique among other parrots for residing in alpine climates. \ + They are known to be intelligent and curious, which has made some consider them a pest." + icon_state = "kea" + icon_rest = "kea-held" + icon_dead = "kea-dead" + tt_desc = "E Nestor notabilis" + +/mob/living/simple_mob/animal/passive/bird/parrot/eclectus + name = "eclectus" + desc = "A species of parrot, this species features extreme sexual dimorphism in their plumage's colors. \ + A male eclectus has emerald green plumage, where as a female eclectus has red and purple plumage." + icon_state = "eclectus" + icon_rest = "eclectus-held" + icon_dead = "eclectus-dead" + tt_desc = "E Eclectus roratus" + +/mob/living/simple_mob/animal/passive/bird/parrot/eclectus/Initialize() + gender = pick(MALE, FEMALE) + if(gender == FEMALE) + icon_state = "eclectusf" + icon_rest = "eclectusf-held" + icon_dead = "eclectusf-dead" + return ..() + +/mob/living/simple_mob/animal/passive/bird/parrot/grey_parrot + name = "grey parrot" + desc = "A species of parrot. This one is predominantly grey, but has red tail feathers." + icon_state = "agrey" + icon_rest = "agrey-held" + icon_dead = "agrey-dead" + tt_desc = "E Psittacus erithacus" + +/mob/living/simple_mob/animal/passive/bird/parrot/black_headed_caique + name = "black-headed caique" + desc = "A species of parrot, these birds have a distinct black color on their heads, distinguishing them from their relative Caiques." + icon_state = "bcaique" + icon_rest = "bcaique-held" + icon_dead = "bcaique-dead" + tt_desc = "E Pionites melanocephalus" + +/mob/living/simple_mob/animal/passive/bird/parrot/white_caique + name = "white-bellied caique" + desc = "A species of parrot, they are also known as the Green-Thighed Parrot." + icon_state = "wcaique" + icon_rest = "wcaique-held" + icon_dead = "wcaique-dead" + tt_desc = "E Pionites leucogaster" + +/mob/living/simple_mob/animal/passive/bird/parrot/budgerigar + name = "budgerigar" + desc = "A species of parrot, they are also known as the common parakeet, or in some circles, the budgie. \ + This one is has its natural colors of green and yellow." + icon_state = "gbudge" + icon_rest = "gbudge-held" + icon_dead = "gbudge-dead" + tt_desc = "E Melopsittacus undulatus" + +/mob/living/simple_mob/animal/passive/bird/parrot/budgerigar/blue + icon_state = "bbudge" + icon_rest = "bbudge-held" + icon_dead = "bbudge-dead" + desc = "A species of parrot, they are also known as the common parakeet, or in some circles, the budgie. \ + This one has a mutation which altered its color to be blue instead of green and yellow." + +/mob/living/simple_mob/animal/passive/bird/parrot/budgerigar/bluegreen + icon_state = "bgbudge" + icon_rest = "bgbudge-held" + icon_dead = "bgbudge-dead" + desc = "A species of parrot, they are also known as the common parakeet, or in some circles, the budgie. \ + This one has a mutation which altered its color to be a mix of blue and green." + +/mob/living/simple_mob/animal/passive/bird/parrot/cockatiel + name = "cockatiel" + desc = "A species of parrot. This one has a highly visible crest." + icon_state = "tiel" + icon_rest = "tiel-held" + icon_dead = "tiel-dead" + tt_desc = "E Nymphicus hollandicus" + +/mob/living/simple_mob/animal/passive/bird/parrot/cockatiel/white + icon_state = "wtiel" + icon_rest = "wtiel-held" + icon_dead = "wtiel-dead" + +/mob/living/simple_mob/animal/passive/bird/parrot/cockatiel/yellowish + icon_state = "luttiel" + icon_rest = "luttiel-held" + icon_dead = "luttiel-dead" + +/mob/living/simple_mob/animal/passive/bird/parrot/cockatiel/grey + icon_state = "blutiel" // idk why this is blu. + icon_rest = "blutiel-held" + icon_dead = "blutiel-dead" + +// This actually might be the yellow-crested cockatoo but idk. +/mob/living/simple_mob/animal/passive/bird/parrot/sulphur_cockatoo + name = "sulphur-crested cockatoo" + desc = "A species of parrot. This one has an expressive yellow crest. Their underwing and tail feathers are also yellow." + icon_state = "too" + icon_rest = "too-held" + icon_dead = "too-dead" + tt_desc = "E Cacatua galerita" + +// This was originally called 'hooded_too', which might not mean the unbrella cockatoo but idk. +/mob/living/simple_mob/animal/passive/bird/parrot/white_cockatoo + name = "white cockatoo" + desc = "A species of parrot. This one is also known as the Umbrella Cockatoo, due to the semicircular shape of its crest." + icon_state = "utoo" + icon_rest = "utoo-held" + icon_dead = "utoo-dead" + tt_desc = "E Cacatua alba" + +/mob/living/simple_mob/animal/passive/bird/parrot/pink_cockatoo + name = "pink cockatoo" + desc = "A species of parrot. This one is also known as Major Mitchell's cockatoo, \ + in honor of a human surveyor and explorer who existed before humans fully explored their home planet." + icon_state = "mtoo" + icon_rest = "mtoo-held" + icon_dead = "mtoo-dead" + tt_desc = "E Lophochroa leadbeateri" + + +// AI +/datum/ai_holder/simple_mob/passive/parrot + speak_chance = 2 + base_wander_delay = 8 + +/datum/ai_holder/simple_mob/passive/parrot/on_hear_say(mob/living/speaker, message) + if(holder.stat || !holder.say_list || !message || speaker == holder) + return + var/datum/say_list/S = holder.say_list + S.speak |= message \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/sif/diyaab.dm b/code/modules/mob/living/simple_mob/subtypes/animal/sif/diyaab.dm new file mode 100644 index 0000000000..fdd9f66ae5 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/sif/diyaab.dm @@ -0,0 +1,35 @@ +// Diyaabs are rather weak, but tend to exist in large numbers. +// They cooperate with other diyaabs, in order to swarm whoever decides to pick on the little fluffy critter. +// A cleaving weapon like an axe will make short work of the pack. + +/mob/living/simple_mob/animal/sif/diyaab + name = "diyaab" + desc = "A small pack animal. Although omnivorous, it will hunt meat on occasion." + tt_desc = "S Choeros hirtus" //diyaab and shantak are technically reletives! + + faction = "diyaab" + + icon_state = "diyaab" + icon_living = "diyaab" + icon_dead = "diyaab_dead" + icon = 'icons/jungle.dmi' + + maxHealth = 25 + health = 25 + + movement_cooldown = 0 + + melee_damage_lower = 2 + melee_damage_upper = 6 + base_attack_cooldown = 1 SECOND + attack_sharp = 1 //Bleeds, but it shouldn't rip off a limb? + attacktext = list("gouged") + + say_list_type = /datum/say_list/diyaab + ai_holder_type = /datum/ai_holder/simple_mob/retaliate/cooperative + +/datum/say_list/diyaab + speak = list("Awrr?", "Aowrl!", "Worrl.") + emote_see = list("sniffs the air cautiously","looks around") + emote_hear = list("snuffles") + diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/sif/fluffy_vr.dm b/code/modules/mob/living/simple_mob/subtypes/animal/sif/fluffy_vr.dm new file mode 100644 index 0000000000..e5d1c8f8e1 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/sif/fluffy_vr.dm @@ -0,0 +1,36 @@ +/mob/living/simple_mob/animal/sif/fluffy + name = "Fluffy" + desc = "It's a pink Diyaab! It seems to be very tame and quiet." + tt_desc = "S Choeros hirtus" + + icon_state = "fluffy" + icon_living = "fluffy" + icon_dead = "fluffy_dead" + icon_rest = "fluffy_sleep" + icon = 'icons/mob/animal_vr.dmi' + + maxHealth = 20 //don't want Fluff to die on a missclick + health = 20 + + movement_cooldown = 5 + + see_in_dark = 5 + mob_size = MOB_TINY + + response_help = "scritches" + response_disarm = "bops" + response_harm = "kicks" + + min_oxy = 16 //Require atleast 16kPA oxygen + minbodytemp = 223 //Below -50 Degrees Celcius + maxbodytemp = 323 //Above 50 Degrees Celcius + + meat_amount = 1 + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat + + say_list_type = /datum/say_list/fluffy_vr + +/datum/say_list/fluffy_vr + speak = list("Squee","Arf arf","Awoo","Squeak") + emote_hear = list("howls","squeals","squeaks", "barks") + emote_see = list("puffs its fur out", "shakes its fur", "stares directly at you") diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/sif/hooligan_crab.dm b/code/modules/mob/living/simple_mob/subtypes/animal/sif/hooligan_crab.dm new file mode 100644 index 0000000000..56e4725686 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/sif/hooligan_crab.dm @@ -0,0 +1,103 @@ +/* + Hooligan Crabs are called so because they are rather curious and tend to follow people, + whether the people want them to or not, and sometimes causing vandalism by accident. + They're pretty strong and have strong melee armor, but won't attack first. + They unknowingly play a role in keeping the shoreline fairly safe, by killing whatever would attack other people. + + They also have a slow, but very strong attack that is telegraphed. If it hits, it will briefly stun whatever got hit + and inflict a very large chunk of damage. If the thing was already stunned, the crab will 'throw' them away, to + hopefully prevent chainstuns forever. +*/ + +/mob/living/simple_mob/animal/sif/hooligan_crab + name = "hooligan crab" + desc = "A large, hard-shelled crustacean. This one is mostly grey. \ + You probably shouldn't mess with it." + icon_state = "sif_crab" + icon_living = "sif_crab" + icon_dead = "sif_crab_dead" + icon_scale = 1.5 + + faction = "crabs" + + maxHealth = 200 + health = 200 + movement_cooldown = 10 + movement_sound = 'sound/weapons/heavysmash.ogg' + movement_shake_radius = 5 + + taser_kill = FALSE + armor = list( + "melee" = 40, + "bullet" = 20, + "laser" = 10, + "energy" = 0, + "bomb" = 0, + "bio" = 0, + "rad" = 0 + ) + armor_soak = list( + "melee" = 10, + "bullet" = 5, + "laser" = 0, + "energy" = 0, + "bomb" = 0, + "bio" = 0, + "rad" = 0 + ) + + mob_size = MOB_LARGE + + melee_damage_lower = 22 + melee_damage_upper = 35 + attack_armor_pen = 35 + attack_sharp = TRUE + attack_edge = TRUE + melee_attack_delay = 1 SECOND + + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat + + response_help = "pets" + response_disarm = "gently pushes aside" + response_harm = "kicks" + friendly = "pinches" + attacktext = list("clawed", "pinched", "crushed") + speak_emote = list("clicks") + + ai_holder_type = /datum/ai_holder/simple_mob/melee/hooligan + say_list_type = /datum/say_list/crab + + var/weaken_amount = 2 // Be careful with this number. High values will equal a permastun. + +// Stuns the thing that got hit briefly. +/mob/living/simple_mob/animal/sif/hooligan_crab/apply_melee_effects(atom/A) + if(isliving(A)) + var/mob/living/L = A + var/was_stunned = L.incapacitated(INCAPACITATION_DISABLED) + L.Weaken(weaken_amount) + + playsound(L, 'sound/effects/break_stone.ogg', 75, 1) + if(was_stunned) // Try to prevent chain-stuns by having them thrown. + var/throwdir = get_dir(src, L) + L.throw_at(get_edge_target_turf(L, throwdir), 5, 1, src) + visible_message(span("danger", "\The [src] hurls \the [L] away!")) + else + visible_message(span("danger", "\The [src] crushes \the [L]!")) + +// The AI for hooligan crabs. Follows people for awhile. +/datum/ai_holder/simple_mob/melee/hooligan + hostile = FALSE + retaliate = TRUE + returns_home = TRUE + max_home_distance = 12 + mauling = TRUE + var/random_follow = TRUE // Turn off if you want to bus with crabs. + +/datum/ai_holder/simple_mob/melee/hooligan/handle_stance_strategical() + ..() + if(random_follow && stance == STANCE_IDLE && !leader) + if(prob(10)) + for(var/mob/living/L in hearers(holder)) + if(!istype(L, holder)) // Don't follow other hooligan crabs. + holder.visible_message("\The [holder] starts to follow \the [L].") + set_follow(L, rand(20 SECONDS, 40 SECONDS)) \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/sif/savik.dm b/code/modules/mob/living/simple_mob/subtypes/animal/sif/savik.dm new file mode 100644 index 0000000000..4e0915a5b2 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/sif/savik.dm @@ -0,0 +1,51 @@ +// Saviks are dangerous, angry creatures that hit hard, and will berserk if losing a fight. + +/mob/living/simple_mob/animal/sif/savik + name = "savik" + tt_desc = "S Pistris tellus" //landshark + player_msg = "You have the ability to berserk at will, which will grant strong physical bonuses for \ + a short period of time, however it will tire you and you will be much weaker for awhile after it expires." + + faction = "savik" + + icon_state = "savik" + icon_living = "savik" + icon_dead = "savik_dead" + icon = 'icons/jungle.dmi' + + maxHealth = 125 + health = 125 + + movement_cooldown = 0.5 SECONDS + + melee_damage_lower = 15 + melee_damage_upper = 35 + attack_armor_pen = 15 + attack_sharp = TRUE + attack_edge = TRUE + melee_attack_delay = 1 SECOND + attacktext = list("mauled") + + say_list_type = /datum/say_list/savik + ai_holder_type = /datum/ai_holder/simple_mob/savik + +/datum/say_list/savik + speak = list("Hruuugh!","Hrunnph") + emote_see = list("paws the ground","shakes its mane","stomps") + emote_hear = list("snuffles") + +/mob/living/simple_mob/animal/sif/savik/handle_special() + if((get_AI_stance() in list(STANCE_APPROACH, STANCE_FIGHT)) && !is_AI_busy() && isturf(loc)) + if(health <= (maxHealth * 0.5)) // At half health, and fighting someone currently. + berserk() + +/datum/ai_holder/simple_mob/savik + mauling = TRUE + +// So players can use it too. +/mob/living/simple_mob/animal/sif/savik/verb/berserk() + set name = "Berserk" + set desc = "Enrage and become vastly stronger for a period of time, however you will be weaker afterwards." + set category = "Abilities" + + add_modifier(/datum/modifier/berserk, 30 SECONDS) diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/sif/shantak.dm b/code/modules/mob/living/simple_mob/subtypes/animal/sif/shantak.dm new file mode 100644 index 0000000000..24e74a56f3 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/sif/shantak.dm @@ -0,0 +1,70 @@ +// Shantaks are essentially sif wolves. + +/mob/living/simple_mob/animal/sif/shantak + name = "shantak" + desc = "A piglike creature with a bright iridiscent mane that sparkles as though lit by an inner light. \ + Don't be fooled by its beauty though." + tt_desc = "S Choeros shantak" + + faction = "shantak" + + icon_state = "shantak" + icon_living = "shantak" + icon_dead = "shantak_dead" + icon = 'icons/jungle.dmi' + + maxHealth = 75 + + movement_cooldown = 5 + + melee_damage_lower = 6 + melee_damage_upper = 14 + base_attack_cooldown = 1 SECOND + melee_attack_delay = 0.5 SECONDS + attack_armor_pen = 5 + attack_sharp = TRUE + attack_edge = TRUE + attacktext = list("gouged") + + say_list_type = /datum/say_list/shantak + +/datum/say_list/shantak + speak = list("Shuhn.","Shrunnph?","Shunpf.") + emote_see = list("scratches the ground", "shakes out its mane", "clinks gently as it moves") + + +// The pack leader. +// Will command other shantaks to follow it. +/mob/living/simple_mob/animal/sif/shantak/leader + name = "big shantak" + desc = "A piglike creature with a bright iridiscent mane that sparkles as though lit by an inner light. \ + This one seems bigger than the others, and has a commanding presence." + icon_scale = 1.5 + maxHealth = 125 + player_msg = "You have the ability to command other shantaks to follow you." + +/mob/living/simple_mob/animal/sif/shantak/leader/verb/rally_pack() + set name = "Rally Pack" + set desc = "Commands your fellow packmembers to follow you, the leader." + set category = "Abilities" + + for(var/mob/living/simple_mob/animal/sif/shantak/S in hearers(7, src)) + if(istype(S, /mob/living/simple_mob/animal/sif/shantak/leader)) // Leaders won't follow other leaders. Also avoids trying to follow ourselves. + continue + if(!S.ai_holder) + continue + if(S.faction != src.faction) + continue + var/datum/ai_holder/AI = S.ai_holder + AI.set_follow(src) + +// Variant that automatically commands nearby allies to follow it when created. +// Suggested to spawn last so it can rally up all the shantaks easily before hunting for tasty explorers. +/mob/living/simple_mob/animal/sif/shantak/leader/autofollow/Initialize() + rally_pack() + return ..() + + +// These ones only retaliate. Used for a PoI. +/mob/living/simple_mob/animal/sif/shantak/retaliate + ai_holder_type = /datum/ai_holder/simple_mob/retaliate \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/sif/sif.dm b/code/modules/mob/living/simple_mob/subtypes/animal/sif/sif.dm new file mode 100644 index 0000000000..8d19324cf2 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/sif/sif.dm @@ -0,0 +1,5 @@ +// Mobs intended to be on Sif. As such, they won't die to the cold. +/mob/living/simple_mob/animal/sif + minbodytemp = 175 + cold_resist = 0.75 + heat_resist = -0.5 \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/space/alien.dm b/code/modules/mob/living/simple_mob/subtypes/animal/space/alien.dm new file mode 100644 index 0000000000..7de14dc6e7 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/space/alien.dm @@ -0,0 +1,118 @@ +/mob/living/simple_mob/animal/space/alien + name = "alien hunter" + desc = "Hiss!" + icon = 'icons/mob/alien.dmi' + icon_state = "alienh_running" + icon_living = "alienh_running" + icon_dead = "alien_l" + icon_gib = "syndicate_gib" + icon_rest = "alienh_sleep" + + faction = "xeno" + + mob_class = MOB_CLASS_ABERRATION + + response_help = "pokes" + response_disarm = "shoves" + response_harm = "hits" + + maxHealth = 100 + health = 100 + + harm_intent_damage = 5 + melee_damage_lower = 25 + melee_damage_upper = 25 + attack_sharp = TRUE + attack_edge = TRUE + + attacktext = list("slashed") + attack_sound = 'sound/weapons/bladeslice.ogg' + + meat_type = /obj/item/weapon/reagent_containers/food/snacks/xenomeat + +/mob/living/simple_mob/animal/space/alien/drone + name = "alien drone" + icon_state = "aliend_running" + icon_living = "aliend_running" + icon_dead = "aliend_l" + icon_rest = "aliend_sleep" + health = 60 + melee_damage_lower = 15 + melee_damage_upper = 15 + +/mob/living/simple_mob/animal/space/alien/sentinel + name = "alien sentinel" + icon_state = "aliens_running" + icon_living = "aliens_running" + icon_dead = "aliens_l" + icon_rest = "aliens_sleep" + health = 120 + melee_damage_lower = 15 + melee_damage_upper = 15 + projectiletype = /obj/item/projectile/energy/neurotoxin/toxic + projectilesound = 'sound/weapons/pierce.ogg' + +/mob/living/simple_mob/animal/space/alien/sentinel/praetorian + name = "alien praetorian" + icon = 'icons/mob/64x64.dmi' + icon_state = "prat_s" + icon_living = "prat_s" + icon_dead = "prat_dead" + icon_rest = "prat_sleep" + maxHealth = 200 + health = 200 + + pixel_x = -16 + old_x = -16 + meat_amount = 5 + +/mob/living/simple_mob/animal/space/alien/queen + name = "alien queen" + icon_state = "alienq_running" + icon_living = "alienq_running" + icon_dead = "alienq_l" + icon_rest = "alienq_sleep" + health = 250 + maxHealth = 250 + melee_damage_lower = 15 + melee_damage_upper = 15 + projectiletype = /obj/item/projectile/energy/neurotoxin/toxic + projectilesound = 'sound/weapons/pierce.ogg' + + + movement_cooldown = 8 + +/mob/living/simple_mob/animal/space/alien/queen/empress + name = "alien empress" + icon = 'icons/mob/64x64.dmi' + icon_state = "queen_s" + icon_living = "queen_s" + icon_dead = "queen_dead" + icon_rest = "queen_sleep" + maxHealth = 400 + health = 400 + meat_amount = 5 + + pixel_x = -16 + old_x = -16 + +/mob/living/simple_mob/animal/space/alien/queen/empress/mother + name = "alien mother" + icon = 'icons/mob/96x96.dmi' + icon_state = "empress_s" + icon_living = "empress_s" + icon_dead = "empress_dead" + icon_rest = "empress_rest" + maxHealth = 600 + health = 600 + meat_amount = 10 + melee_damage_lower = 15 + melee_damage_upper = 25 + + pixel_x = -32 + old_x = -32 + +/mob/living/simple_mob/animal/space/alien/death() + ..() + visible_message("[src] lets out a waning guttural screech, green blood bubbling from its maw...") + playsound(src, 'sound/voice/hiss6.ogg', 100, 1) \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/space/bats.dm b/code/modules/mob/living/simple_mob/subtypes/animal/space/bats.dm new file mode 100644 index 0000000000..5244fd9b98 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/space/bats.dm @@ -0,0 +1,52 @@ +/mob/living/simple_mob/animal/space/bats + name = "space bat swarm" + desc = "A swarm of cute little blood sucking bats that looks pretty upset." + tt_desc = "N Bestia gregaria" //Nispean swarm bats, because of course Nisp has swarm bats + icon = 'icons/mob/bats.dmi' + icon_state = "bat" + icon_living = "bat" + icon_dead = "bat_dead" + icon_gib = "bat_dead" + + faction = "scarybat" + + maxHealth = 20 + health = 20 + + attacktext = list("bites") + attack_sound = 'sound/weapons/bite.ogg' + + response_help = "pets the" + response_disarm = "gently pushes aside the" + response_harm = "hits the" + + harm_intent_damage = 10 + + melee_damage_lower = 5 + melee_damage_upper = 5 + attack_sharp = TRUE + + ai_holder_type = /datum/ai_holder/simple_mob/melee/evasive + + has_langs = list("Mouse") + + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat + + say_list_type = /datum/say_list/mouse // Close enough + + var/scare_chance = 15 + +/mob/living/simple_mob/animal/space/bats/apply_melee_effects(var/atom/A) + if(isliving(A)) + var/mob/living/L = A + if(prob(scare_chance)) + L.Stun(1) + L.visible_message("\the [src] scares \the [L]!") + +// Spookiest of bats +/mob/living/simple_mob/animal/space/bats/cult + faction = "cult" + supernatural = TRUE + +/mob/living/simple_mob/animal/space/bats/cult/cultify() + return \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/space/bear.dm b/code/modules/mob/living/simple_mob/subtypes/animal/space/bear.dm new file mode 100644 index 0000000000..e4199373bd --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/space/bear.dm @@ -0,0 +1,46 @@ +/mob/living/simple_mob/animal/space/bear + name = "space bear" + desc = "A product of Space Russia?" + tt_desc = "U Ursinae aetherius" //...bearspace? Maybe. + icon_state = "bear" + icon_living = "bear" + icon_dead = "bear_dead" + icon_gib = "bear_gib" + + faction = "russian" + + maxHealth = 125 + health = 125 + + movement_cooldown = 0.5 SECONDS + + melee_damage_lower = 15 + melee_damage_upper = 35 + attack_armor_pen = 15 + attack_sharp = TRUE + attack_edge = TRUE + melee_attack_delay = 1 SECOND + attacktext = list("mauled") + + meat_type = /obj/item/weapon/reagent_containers/food/snacks/bearmeat + + say_list_type = /datum/say_list/bear + +/datum/say_list/bear + speak = list("RAWR!","Rawr!","GRR!","Growl!") + emote_see = list("stares ferociously", "stomps") + emote_hear = list("rawrs","grumbles","grawls", "growls", "roars") + +// Is it time to be mad? +/mob/living/simple_mob/animal/space/bear/handle_special() + if((get_AI_stance() in list(STANCE_APPROACH, STANCE_FIGHT)) && !is_AI_busy() && isturf(loc)) + if(health <= (maxHealth * 0.5)) // At half health, and fighting someone currently. + berserk() + +// So players can use it too. +/mob/living/simple_mob/animal/space/bear/verb/berserk() + set name = "Berserk" + set desc = "Enrage and become vastly stronger for a period of time, however you will be weaker afterwards." + set category = "Abilities" + + add_modifier(/datum/modifier/berserk, 30 SECONDS) \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/space/carp.dm b/code/modules/mob/living/simple_mob/subtypes/animal/space/carp.dm new file mode 100644 index 0000000000..62acbf2a3d --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/space/carp.dm @@ -0,0 +1,128 @@ +// Space carp show up as a random event to wreck hapless people in space or near windows. +// They generally fit the archetype of 'fast but fragile'. +// This is compensated by being in groups (usually). +/mob/living/simple_mob/animal/space/carp + name = "space carp" + desc = "A ferocious, fang-bearing creature that resembles a fish." + icon_state = "carp" + icon_living = "carp" + icon_dead = "carp_dead" + icon_gib = "carp_gib" + + faction = "carp" + maxHealth = 25 + health = 25 + movement_cooldown = 0 // Carp go fast + hovering = TRUE + + response_help = "pets the" + response_disarm = "gently pushes aside the" + response_harm = "hits the" + + melee_damage_lower = 7 // About 14 DPS. + melee_damage_upper = 7 + base_attack_cooldown = 10 // One attack a second. + attack_sharp = TRUE + attack_sound = 'sound/weapons/bite.ogg' + attacktext = list("bitten") + + meat_amount = 1 + meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat + + ai_holder_type = /datum/ai_holder/simple_mob/melee + + var/knockdown_chance = 15 + +/mob/living/simple_mob/animal/space/carp/apply_melee_effects(var/atom/A) + if(isliving(A)) + var/mob/living/L = A + if(prob(knockdown_chance)) + L.Weaken(3) + L.visible_message(span("danger", "\The [src] knocks down \the [L]!")) + +// Subtypes. + +// Won't wander away. +/mob/living/simple_mob/animal/space/carp/event + ai_holder_type = /datum/ai_holder/simple_mob/event + + +/mob/living/simple_mob/animal/space/carp/large + name = "elder carp" + desc = "An older, more matured carp. Few survive to this age due to their aggressiveness." + icon = 'icons/mob/64x32.dmi' + icon_state = "shark" + icon_living = "shark" + icon_dead = "shark_dead" + + maxHealth = 50 + health = 50 + movement_cooldown = 5 // Slower than the younger carp. + mob_size = MOB_LARGE + + pixel_x = -16 + default_pixel_x = -16 + + meat_amount = 3 + + +/mob/living/simple_mob/animal/space/carp/large/huge + name = "great white carp" + desc = "A very rare breed of carp- and a very aggressive one." + icon = 'icons/mob/64x64.dmi' + icon_dead = "megacarp_dead" + icon_living = "megacarp" + icon_state = "megacarp" + + maxHealth = 230 + health = 230 + movement_cooldown = 10 + + melee_damage_lower = 15 // About 20 DPS. + melee_damage_upper = 25 + + pixel_y = -16 + default_pixel_y = -16 + + meat_amount = 10 + + +/mob/living/simple_mob/animal/space/carp/holographic + name = "holographic carp" + desc = "An obviously holographic, but still ferocious looking carp." + // Might be worth using a filter similar to AI holograms in the future. + icon = 'icons/mob/AI.dmi' + icon_state = "holo4" + icon_living = "holo4" + icon_dead = "holo4" + alpha = 127 + icon_gib = null + meat_amount = 0 + meat_type = null + + mob_class = MOB_CLASS_PHOTONIC // Xeno-taser won't work on this as its not a 'real' carp. + +/mob/living/simple_mob/animal/space/carp/holographic/Initialize() + set_light(2) // Hologram lighting. + return ..() + +// Presumably the holodeck emag code requires this. +// Pass TRUE to make safe. Pass FALSE to make unsafe. +/mob/living/simple_mob/animal/space/carp/holographic/proc/set_safety(safe) + if(!isnull(get_AI_stance())) // Will return null if lacking an AI holder or a player is controlling it w/o autopilot var. + ai_holder.hostile = !safe // Inverted so safe = TRUE means hostility = FALSE. + ai_holder.forget_everything() // Reset state so it'll stop chewing on its target. + +// Called on death. +/mob/living/simple_mob/animal/space/carp/holographic/proc/derez() + visible_message(span("notice", "\The [src] fades away!")) + qdel(src) + +/mob/living/simple_mob/animal/space/carp/holographic/gib() + derez() // Holograms can't gib. + +/mob/living/simple_mob/animal/space/carp/holographic/death() + ..() + derez() + + diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/space/gaslamp_vr.dm b/code/modules/mob/living/simple_mob/subtypes/animal/space/gaslamp_vr.dm new file mode 100644 index 0000000000..3b2fedce80 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/space/gaslamp_vr.dm @@ -0,0 +1,81 @@ +/* +LORE: +Gaslamps are a phoron-based life form endemic to the world of Virgo-3B. They are +a sort of fungal organism with physical ties to Diona and Vox, deriving energy +for movement from a gentle combustion-like reaction in their bodies using +atmospheric phoron, carefully filtered trace oxygen, and captured meat products. +Over-exposure to oxygen causes their insides to burn too hot and eventually +kills them. + +TODO: Make them light up and heat the air when exposed to oxygen. +*/ + +/mob/living/simple_mob/animal/space/gaslamp + name = "gaslamp" + desc = "Some sort of floaty alien with a warm glow. This creature is endemic to Virgo-3B." + tt_desc = "Semaeostomeae virginus" + + icon_state = "gaslamp" + icon_living = "gaslamp" + icon_dead = "gaslamp-dead" + icon = 'icons/mob/vore32x64.dmi' + + faction = "virgo3b" + maxHealth = 100 + health = 100 + movement_cooldown = 12 + + say_list_type = /datum/say_list/gaslamp + ai_holder_type = /datum/ai_holder/simple_mob/gaslamp + + //speed = 2 not sure what this is, guessing animation, but it conflicts with new system. + + melee_damage_lower = 30 // Because fuck anyone who hurts this sweet, innocent creature. + melee_damage_upper = 30 + attacktext = list("thrashed") + friendly = "caressed" + + response_help = "brushes" // If clicked on help intent + response_disarm = "pushes" // If clicked on disarm intent + response_harm = "swats" // If clicked on harm intent + + minbodytemp = 0 + maxbodytemp = 350 + + min_oxy = 0 + max_oxy = 5 // Does not like oxygen very much. + min_tox = 1 // Needs phoron to survive. + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + +/datum/say_list/gaslamp + emote_see = list("looms", "sways gently") + +/datum/ai_holder/simple_mob/gaslamp + hostile = FALSE // The majority of simplemobs are hostile, gaslamps are nice. + cooperative = FALSE + retaliate = TRUE //so the monster can attack back + returns_home = FALSE + can_flee = FALSE + speak_chance = 1 + wander = TRUE + base_wander_delay = 9 + +// Activate Noms! +/mob/living/simple_mob/animal/space/gaslamp + vore_active = 1 + vore_capacity = 2 + vore_bump_chance = 90 //they're frickin' jellyfish anenome filterfeeders, get tentacled + vore_bump_emote = "lazily wraps its tentacles around" + vore_standing_too = 1 // Defaults to trying to give you that big tentacle hug. + vore_ignores_undigestable = 0 // they absorb rather than digest, you're going in either way + vore_default_mode = DM_HOLD + vore_digest_chance = 0 // Chance to switch to digest mode if resisted + vore_absorb_chance = 20 // BECOME A PART OF ME. + vore_pounce_chance = 5 // Small chance to punish people who abuse their nomming behaviour to try and kite them forever with repeated melee attacks. + vore_stomach_name = "internal chamber" + vore_stomach_flavor = "You are squeezed into the tight embrace of the alien creature's warm and cozy insides." + vore_icons = SA_ICON_LIVING diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/space/goose.dm b/code/modules/mob/living/simple_mob/subtypes/animal/space/goose.dm new file mode 100644 index 0000000000..43d159a9f0 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/space/goose.dm @@ -0,0 +1,44 @@ +/mob/living/simple_mob/animal/space/goose + name = "goose" + desc = "It looks pretty angry!" + tt_desc = "E Branta canadensis" //that iconstate is just a regular goose + icon_state = "goose" + icon_living = "goose" + icon_dead = "goose_dead" + + faction = "geese" + + maxHealth = 30 + health = 30 + + response_help = "pets the" + response_disarm = "gently pushes aside the" + response_harm = "hits the" + + harm_intent_damage = 5 + melee_damage_lower = 5 //they're meant to be annoying, not threatening. + melee_damage_upper = 5 //unless there's like a dozen of them, then you're screwed. + attacktext = list("pecked") + attack_sound = 'sound/weapons/bite.ogg' + + has_langs = list("Bird") + + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat + +/datum/say_list/goose + speak = list("HONK!") + emote_hear = list("honks loudly!") + say_maybe_target = list("Honk?") + say_got_target = list("HONK!!!") + +/mob/living/simple_mob/animal/space/goose/handle_special() + if((get_AI_stance() in list(STANCE_APPROACH, STANCE_FIGHT)) && !is_AI_busy() && isturf(loc)) + if(health <= (maxHealth * 0.5)) // At half health, and fighting someone currently. + berserk() + +/mob/living/simple_mob/animal/space/goose/verb/berserk() + set name = "Berserk" + set desc = "Enrage and become vastly stronger for a period of time, however you will be weaker afterwards." + set category = "Abilities" + + add_modifier(/datum/modifier/berserk, 30 SECONDS) \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/space/mimic_vr.dm b/code/modules/mob/living/simple_mob/subtypes/animal/space/mimic_vr.dm new file mode 100644 index 0000000000..c2e82341bc --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/space/mimic_vr.dm @@ -0,0 +1,244 @@ +// +// Abstract Class +// + +/mob/living/simple_mob/animal/space/mimic + name = "crate" + desc = "A rectangular steel crate." + + icon_state = "crate" + icon_living = "crate" + icon = 'icons/obj/storage.dmi' + + faction = "mimic" + + maxHealth = 250 + health = 250 + //speed = 4 no idea what this is, conflicts with new AI update. + movement_cooldown = 10 //slow crate. + + response_help = "touches" + response_disarm = "pushes" + response_harm = "hits" + + harm_intent_damage = 5 + melee_damage_lower = 8 + melee_damage_upper = 12 + attacktext = list("attacked") + attack_sound = 'sound/weapons/bite.ogg' + + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + minbodytemp = 0 + + meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat + + say_list_type = /datum/say_list/mimic + ai_holder_type = /datum/ai_holder/mimic + + var/knockdown_chance = 15 //Stubbing your toe on furniture hurts. + + showvoreprefs = 0 //VOREStation Edit - Hides mechanical vore prefs for mimics. You can't see their gaping maws when they're just sitting idle. + +/datum/say_list/mimic + say_got_target = list("growls") + +/datum/ai_holder/mimic + wander = FALSE + hostile = TRUE + threaten = TRUE + threaten_timeout = 5 SECONDS + threaten_delay = 1 SECONDS //not a threat, more of a delay. + +/mob/living/simple_mob/animal/space/carp/apply_melee_effects(var/atom/A) + if(isliving(A)) + var/mob/living/L = A + if(prob(knockdown_chance)) + L.Weaken(3) + L.visible_message(span("danger", "\The [src] knocks down \the [L]!")) + +/* should be covered by my "growls" say thing, but keeping it just in case. +/mob/living/simple_mob/animal/space/mimic/set_target() + . = ..() + if(.) + audible_emote("growls at [.]") +*/ +/mob/living/simple_mob/animal/space/mimic/death() + ..() + qdel(src) + +/mob/living/simple_mob/animal/space/mimic/will_show_tooltip() + return FALSE + +/mob/living/simple_mob/animal/space/mimic/death() + var/obj/structure/closet/crate/C = new(get_turf(src)) + // Put loot in crate + for(var/obj/O in src) + if(isbelly(O)) //VOREStation edit + continue + O.forceMove(C) + ..() + +/mob/living/simple_mob/animal/space/mimic/Initialize() + . = ..() + for(var/obj/item/I in loc) + I.forceMove(src) +/* I honestly have no idea what's happening down there so I'm just taking the essentials and yeeting. +// +// Crate Mimic +// + +// Aggro when you try to open them. Will also pickup loot when spawns and drop it when dies. +/mob/living/simple_mob/animal/space/mimic/crate + + attacktext = list("bitten") + +// stop_automated_movement = 1 we don't need these +// wander = 0 + var/attempt_open = 0 + +// Pickup loot +/mob/living/simple_mob/animal/space/mimic/crate/Initialize() + . = ..() + for(var/obj/item/I in loc) + I.forceMove(src) +/* I can't find an equivilant to this, don't know why we really have it even so... +/mob/living/simple_mob/animal/space/mimic/crate/DestroySurroundings() + ..() + if(prob(90)) + icon_state = "[initial(icon_state)]open" + else + icon_state = initial(icon_state) +*/ +/mob/living/simple_mob/animal/space/mimic/crate/ListTargets() + if(attempt_open) + return ..() + else + return ..(1) + +/mob/living/simple_mob/animal/space/mimic/crate/set_target() + . = ..() + if(.) + trigger() + +/mob/living/simple_mob/animal/space/mimic/crate/PunchTarget() + . = ..() + if(.) + icon_state = initial(icon_state) + +/mob/living/simple_mob/animal/space/mimic/crate/proc/trigger() + if(!attempt_open) + visible_message("[src] starts to move!") + attempt_open = 1 + +/mob/living/simple_mob/animal/space/mimic/crate/adjustBruteLoss(var/damage) + trigger() + ..(damage) + +/mob/living/simple_mob/animal/space/mimic/crate/LoseTarget() + ..() + icon_state = initial(icon_state) + +/mob/living/simple_mob/animal/space/mimic/crate/LostTarget() + ..() + icon_state = initial(icon_state) + +/mob/living/simple_mob/animal/space/mimic/crate/death() + var/obj/structure/closet/crate/C = new(get_turf(src)) + // Put loot in crate + for(var/obj/O in src) + if(isbelly(O)) //VOREStation edit + continue + O.forceMove(C) + ..() + +/mob/living/simple_mob/animal/space/mimic/crate/PunchTarget() + . =..() + var/mob/living/L = . + if(istype(L)) + if(prob(15)) + L.Weaken(2) + L.visible_message("\the [src] knocks down \the [L]!") + +// +// Copy Mimic +// + +var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/cable, /obj/structure/window, /obj/item/projectile/animate) + +/mob/living/simple_mob/animal/space/mimic/copy + + health = 100 + maxHealth = 100 + var/mob/living/creator = null // the creator + var/destroy_objects = 0 + var/knockdown_people = 0 + +/mob/living/simple_mob/animal/space/mimic/copy/New(loc, var/obj/copy, var/mob/living/creator) + ..(loc) + CopyObject(copy, creator) + +/mob/living/simple_mob/animal/space/mimic/copy/death() + + for(var/atom/movable/M in src) + if(isbelly(M)) //VOREStation edit + continue + M.forceMove(get_turf(src)) + ..() + +/mob/living/simple_mob/animal/space/mimic/copy/ListTargets() + // Return a list of targets that isn't the creator + . = ..() + return . - creator + +/mob/living/simple_mob/animal/space/mimic/copy/proc/CopyObject(var/obj/O, var/mob/living/creator) + + if((istype(O, /obj/item) || istype(O, /obj/structure)) && !is_type_in_list(O, protected_objects)) + + O.forceMove(src) + name = O.name + desc = O.desc + icon = O.icon + icon_state = O.icon_state + icon_living = icon_state + + if(istype(O, /obj/structure)) + health = (anchored * 50) + 50 + destroy_objects = 1 + if(O.density && O.anchored) + knockdown_people = 1 + melee_damage_lower *= 2 + melee_damage_upper *= 2 + else if(istype(O, /obj/item)) + var/obj/item/I = O + health = 15 * I.w_class + melee_damage_lower = 2 + I.force + melee_damage_upper = 2 + I.force + move_to_delay = 2 * I.w_class + + maxHealth = health + if(creator) + src.creator = creator + faction = "\ref[creator]" // very unique + return 1 + return + +/mob/living/simple_mob/animal/space/mimic/copy/DestroySurroundings() + if(destroy_objects) + ..() + +/mob/living/simple_mob/animal/space/mimic/copy/PunchTarget() + . =..() + if(knockdown_people) + var/mob/living/L = . + if(istype(L)) + if(prob(15)) + L.Weaken(1) + L.visible_message("\the [src] knocks down \the [L]!") +*/ \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/space/snake_vr.dm b/code/modules/mob/living/simple_mob/subtypes/animal/space/snake_vr.dm new file mode 100644 index 0000000000..3266641872 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/space/snake_vr.dm @@ -0,0 +1,165 @@ +/mob/living/simple_mob/animal/space/snake + name = "snake" + desc = "A big thick snake." + + icon_state = "snake" + icon_living = "snake" + icon_dead = "snake_dead" + icon = 'icons/mob/snake_vr.dmi' + + maxHealth = 20 + health = 20 + + movement_cooldown = 8 // SLOW-ASS MUTHAFUCKA, I hope. + + response_help = "pets" + response_disarm = "shoos" + response_harm = "kicks" + + melee_damage_lower = 3 + melee_damage_upper = 5 + attacktext = list("bitten") + + say_list_type = /datum/say_list/snake + ai_holder_type = /datum/ai_holder/simple_mob/melee + +/datum/say_list/snake + emote_hear = list("hisses") + +//NOODLE IS HERE! SQUEEEEEEEE~ +/mob/living/simple_mob/animal/space/snake/noodle + name = "Noodle" + desc = "This snake is particularly chubby and demands nothing but the finest of treats." + + ai_holder_type = /datum/ai_holder/simple_mob/passive + + var/turns_since_scan = 0 + var/obj/movement_target + +/mob/living/simple_mob/animal/space/snake/noodle/Life() + ..() + + //Not replacing with SA FollowTarget mechanics because Ian behaves... very... specifically. + + //Feeding, chasing food, FOOOOODDDD + if(!stat && !resting && !buckled) + turns_since_scan++ + if(turns_since_scan > 5) + turns_since_scan = 0 + if((movement_target) && !(isturf(movement_target.loc) || ishuman(movement_target.loc) )) + movement_target = null + if( !movement_target || !(movement_target.loc in oview(src, 3)) ) + movement_target = null + for(var/obj/item/weapon/reagent_containers/food/snacks/snakesnack/S in oview(src,3)) + if(isturf(S.loc) || ishuman(S.loc)) + movement_target = S + visible_emote("turns towards \the [movement_target] and slithers towards it.") + break + if(movement_target) + step_to(src,movement_target,1) + sleep(3) + step_to(src,movement_target,1) + sleep(3) + step_to(src,movement_target,1) + + if(movement_target) //Not redundant due to sleeps, Item can be gone in 6 decisecomds + if (movement_target.loc.x < src.x) + set_dir(WEST) + else if (movement_target.loc.x > src.x) + set_dir(EAST) + else if (movement_target.loc.y < src.y) + set_dir(SOUTH) + else if (movement_target.loc.y > src.y) + set_dir(NORTH) + else + set_dir(SOUTH) + + if(isturf(movement_target.loc) ) + UnarmedAttack(movement_target) + else if(ishuman(movement_target.loc) && prob(20)) + visible_emote("stares at the [movement_target] that [movement_target.loc] has with an unknowable reptilian gaze.") + +/* old eating code, couldn't figure out how to make the "swallows food" thing so I'm keeping this here incase someone wants legacy" +/mob/living/simple_mob/animal/space/snake/noodle/Life() //stolen from Ian in corgi.dm + if(!..()) + return 0 + + if(!stat && !resting && !buckled && !ai_inactive) + turns_since_scan++ + if(turns_since_scan > 5) + turns_since_scan = 0 + if(movement_target && !(isturf(movement_target.loc) || ishuman(movement_target.loc))) + movement_target = null + stop_automated_movement = 0 + if(!movement_target || !(movement_target.loc in oview(src, 5)) ) + movement_target = null + stop_automated_movement = 0 + walk(src,0) + for(var/obj/item/weapon/reagent_containers/food/snacks/snakesnack/S in oview(src,3)) + if(isturf(S.loc)) + movement_target = S + visible_emote("turns towards \the [movement_target] and slithers towards it.") + break + + if(movement_target) + stop_automated_movement = 1 + walk_to(src, movement_target, 0, 5) + spawn(10) + if(Adjacent(movement_target)) + visible_message("[src] swallows the [movement_target] whole!") + qdel(movement_target) + walk(src,0) + else if(ishuman(movement_target.loc) && prob(20)) + visible_emote("stares at the [movement_target] that [movement_target.loc] has with an unknowable reptilian gaze.") +*/ + +/mob/living/simple_mob/animal/space/snake/noodle/apply_melee_effects(var/atom/A) + if(ismouse(A)) + var/mob/living/simple_mob/animal/passive/mouse/mouse = A + if(mouse.getMaxHealth() < 20) // In case a badmin makes giant mice or something. + mouse.splat() + visible_emote(pick("swallows \the [mouse] whole!")) + else + ..() + +/mob/living/simple_mob/animal/space/snake/noodle/attackby(var/obj/item/O, var/mob/user) + if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/snakesnack)) + visible_message("[user] feeds \the [O] to [src].") + qdel(O) + else + return ..() + +//Special snek-snax for Noodle! +/obj/item/weapon/reagent_containers/food/snacks/snakesnack + name = "sugar mouse" + desc = "A little mouse treat made of coloured sugar. Noodle loves these!" + var/snack_colour + icon = 'icons/mob/snake_vr.dmi' + icon_state = "snack_yellow" + nutriment_amt = 1 + nutriment_desc = list("sugar" = 1) + +/obj/item/weapon/reagent_containers/food/snacks/snakesnack/New() + ..() + if(!snack_colour) + snack_colour = pick( list("yellow","green","pink","blue") ) + icon_state = "snack_[snack_colour]" + desc = "A little mouse treat made of coloured sugar. Noodle loves these! This one is [snack_colour]." + reagents.add_reagent("sugar", 2) + +/obj/item/weapon/storage/box/snakesnackbox + name = "box of Snake Snax" + desc = "A box containing Noodle's special sugermouse treats." + icon = 'icons/mob/snake_vr.dmi' + icon_state = "sneksnakbox" + storage_slots = 7 + +/obj/item/weapon/storage/box/snakesnackbox/New() + new /obj/item/weapon/reagent_containers/food/snacks/snakesnack(src) + new /obj/item/weapon/reagent_containers/food/snacks/snakesnack(src) + new /obj/item/weapon/reagent_containers/food/snacks/snakesnack(src) + new /obj/item/weapon/reagent_containers/food/snacks/snakesnack(src) + new /obj/item/weapon/reagent_containers/food/snacks/snakesnack(src) + new /obj/item/weapon/reagent_containers/food/snacks/snakesnack(src) + new /obj/item/weapon/reagent_containers/food/snacks/snakesnack(src) + ..() diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/space/space.dm b/code/modules/mob/living/simple_mob/subtypes/animal/space/space.dm new file mode 100644 index 0000000000..b7f77e6410 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/space/space.dm @@ -0,0 +1,15 @@ +// 'Space' mobs don't care about atmos (like carp) +/mob/living/simple_mob/animal/space + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + minbodytemp = 0 + +// They can also, you know, move around, in space +/mob/living/simple_mob/animal/space/Process_Spacemove(var/check_drift = 0) + return TRUE \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/blob/blob.dm b/code/modules/mob/living/simple_mob/subtypes/blob/blob.dm new file mode 100644 index 0000000000..2d700646ae --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/blob/blob.dm @@ -0,0 +1,62 @@ +// Blob simple_mobs generally get made from the blob random event. +// They're considered slimes for the purposes of attack bonuses from certain weapons. + +// Do not spawn, this is a base type. +/mob/living/simple_mob/blob + icon = 'icons/mob/blob.dmi' + pass_flags = PASSBLOB | PASSTABLE + faction = "blob" + + heat_damage_per_tick = 0 + cold_damage_per_tick = 0 + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + minbodytemp = 0 + + taser_kill = FALSE + + var/mob/observer/blob/overmind = null + var/obj/structure/blob/factory/factory = null + + mob_class = MOB_CLASS_SLIME + ai_holder_type = /datum/ai_holder/simple_mob/melee + +/mob/living/simple_mob/blob/speech_bubble_appearance() + return "slime" + +/mob/living/simple_mob/blob/update_icons() + if(overmind) + color = overmind.blob_type.complementary_color + else + color = null + ..() + +/mob/living/simple_mob/blob/Destroy() + if(overmind) + overmind.blob_mobs -= src + return ..() + +/mob/living/simple_mob/blob/blob_act(obj/structure/blob/B) + if(!overmind && B.overmind) + overmind = B.overmind + update_icon() + + if(stat != DEAD && health < maxHealth) + adjustBruteLoss(-maxHealth*0.0125) + adjustFireLoss(-maxHealth*0.0125) + +/mob/living/simple_mob/blob/CanPass(atom/movable/mover, turf/target) + if(istype(mover, /obj/structure/blob)) // Don't block blobs from expanding onto a tile occupied by a blob mob. + return TRUE + return ..() + +/mob/living/simple_mob/blob/Process_Spacemove() + for(var/obj/structure/blob/B in range(1, src)) + return TRUE + return ..() \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/blob/spore.dm b/code/modules/mob/living/simple_mob/subtypes/blob/spore.dm new file mode 100644 index 0000000000..e7bf5861f2 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/blob/spore.dm @@ -0,0 +1,148 @@ +// Spores are made from blob factories. +// They are very weak and expendable, but can overwhelm when a lot of them are together. +// When attacking, spores will hit harder if near other friendly spores. +// Some blobs can infest dead non-robotic mobs, making them into Not Zombies. + +/mob/living/simple_mob/blob/spore + name = "blob spore" + desc = "A floating, fragile spore." + + icon_state = "blobpod" + icon_living = "blobpod" + glow_range = 3 + glow_intensity = 5 + layer = ABOVE_MOB_LAYER // Over the blob. + + health = 30 + maxHealth = 30 + melee_damage_lower = 2 + melee_damage_upper = 4 + movement_cooldown = 0 + hovering = TRUE + + attacktext = list("slams into") + attack_sound = 'sound/effects/slime_squish.ogg' + say_list_type = /datum/say_list/spore + + var/mob/living/carbon/human/infested = null // The human this thing is totally not making into a zombie. + var/can_infest = FALSE + var/is_infesting = FALSE + +/datum/say_list/spore + emote_see = list("sways", "inflates briefly") + +/datum/say_list/infested + emote_see = list("shambles around", "twitches", "stares") + + +/mob/living/simple_mob/blob/spore/infesting + name = "infesting blob spore" + can_infest = TRUE + +/mob/living/simple_mob/blob/spore/weak + name = "fragile blob spore" + health = 15 + maxHealth = 15 + melee_damage_lower = 1 + melee_damage_upper = 2 + +/mob/living/simple_mob/blob/spore/Initialize(mapload, var/obj/structure/blob/factory/my_factory) + if(istype(my_factory)) + factory = my_factory + factory.spores += src + return ..() + +/mob/living/simple_mob/blob/spore/Destroy() + if(factory) + factory.spores -= src + factory = null + if(infested) + infested.forceMove(get_turf(src)) + visible_message(span("warning", "\The [infested] falls to the ground as the blob spore bursts.")) + infested = null + return ..() + +/mob/living/simple_mob/blob/spore/death(gibbed, deathmessage = "bursts!") + if(overmind) + overmind.blob_type.on_spore_death(src) + ..(gibbed, deathmessage) + qdel(src) + +/mob/living/simple_mob/blob/spore/update_icons() + ..() // This will cut our overlays. + + if(overmind) + color = overmind.blob_type.complementary_color + glow_color = color + glow_toggle = TRUE + else + color = null + glow_color = null + glow_toggle = FALSE + + if(is_infesting) + icon = infested.icon + copy_overlays(infested) + // overlays = infested.overlays + var/mutable_appearance/blob_head_overlay = mutable_appearance('icons/mob/blob.dmi', "blob_head") + if(overmind) + blob_head_overlay.color = overmind.blob_type.complementary_color + color = initial(color)//looks better. + // overlays += blob_head_overlay + add_overlay(blob_head_overlay, TRUE) + +/mob/living/simple_mob/blob/spore/handle_special() + ..() + if(can_infest && !is_infesting && isturf(loc)) + for(var/mob/living/carbon/human/H in view(src,1)) + if(H.stat != DEAD) // We want zombies. + continue + if(H.isSynthetic()) // Not philosophical zombies. + continue + infest(H) + break + + if(factory && z != factory.z) // This is to prevent spores getting lost in space and making the factory useless. + qdel(src) + +/mob/living/simple_mob/blob/spore/proc/infest(mob/living/carbon/human/H) + is_infesting = TRUE + if(H.wear_suit) + var/obj/item/clothing/suit/A = H.wear_suit + if(A.armor && A.armor["melee"]) + maxHealth += A.armor["melee"] //That zombie's got armor, I want armor! + + maxHealth += 40 + health = maxHealth + name = "Infested [H.real_name]" // Not using the Z word. + desc = "A parasitic organism attached to a deceased body, controlling it directly as if it were a puppet." + melee_damage_lower += 8 // 10 total. + melee_damage_upper += 11 // 15 total. + attacktext = list("claws") + + H.forceMove(src) + infested = H + + say_list = new /datum/say_list/infested() + + update_icons() + visible_message(span("warning", "The corpse of [H.name] suddenly rises!")) + +/mob/living/simple_mob/blob/spore/GetIdCard() + if(infested) // If we've infested someone, use their ID. + return infested.GetIdCard() + +/mob/living/simple_mob/blob/spore/apply_bonus_melee_damage(A, damage_to_do) + var/helpers = 0 + for(var/mob/living/simple_mob/blob/spore/S in view(1, src)) + if(S == src) // Don't count ourselves. + continue + if(!IIsAlly(S)) // Only friendly spores make us stronger. + continue + // Friendly spores contribute 1/4th of their averaged attack power to our attack. + damage_to_do += ((S.melee_damage_lower + S.melee_damage_upper) / 2) / 4 + helpers++ + + if(helpers) + to_chat(src, span("notice", "Your attack is assisted by [helpers] other spore\s.")) + return damage_to_do \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/humanoid/clown.dm b/code/modules/mob/living/simple_mob/subtypes/humanoid/clown.dm new file mode 100644 index 0000000000..b6f9520698 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/humanoid/clown.dm @@ -0,0 +1,29 @@ +/mob/living/simple_mob/humanoid/clown + clown + name = "clown" + desc = "A denizen of clown planet" + tt_desc = "E Homo sapiens corydon" //this is an actual clown, as opposed to someone dressed up as one + icon_state = "clown" + icon_living = "clown" + icon_dead = "clown_dead" + icon_gib = "clown_gib" + + faction = "clown" + + loot_list = list(/obj/item/weapon/bikehorn = 100) + + response_help = "pokes" + response_disarm = "gently pushes aside" + response_harm = "hits" + + harm_intent_damage = 8 + melee_damage_lower = 10 + melee_damage_upper = 10 + attacktext = list("attacked") + attack_sound = 'sound/items/bikehorn.ogg' + + say_list_type = /datum/say_list/clown + +/datum/say_list/clown + speak = list("HONK", "Honk!", "Welcome to clown planet!") + emote_see = list("honks") \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/humanoid/humanoid.dm b/code/modules/mob/living/simple_mob/subtypes/humanoid/humanoid.dm new file mode 100644 index 0000000000..6e17e2e1a0 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/humanoid/humanoid.dm @@ -0,0 +1,26 @@ +/mob/living/simple_mob/humanoid + mob_class = MOB_CLASS_HUMANOID + + // Generic humanoid mob tolerances + min_oxy = 5 + max_oxy = 0 + min_tox = 0 + max_tox = 1 + min_co2 = 0 + max_co2 = 5 + min_n2 = 0 + max_n2 = 0 + unsuitable_atoms_damage = 15 + + health = 150 // Point of human crit, as of commenting + maxHealth = 150 + + // Most humans leave a corpse + var/corpse = null + +/mob/living/simple_mob/humanoid/death() + ..() + if(corpse) + new corpse (src.loc) + qdel(src) + return \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/humanoid/mercs/mercs.dm b/code/modules/mob/living/simple_mob/subtypes/humanoid/mercs/mercs.dm new file mode 100644 index 0000000000..514f45df12 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/humanoid/mercs/mercs.dm @@ -0,0 +1,278 @@ +/////////////////////////////// +// Merc Mobs Go Here +/////////////////////////////// + +// Probably shouldn't use this directly, there are a bunch of sub-classes that are more complete. +/mob/living/simple_mob/humanoid/merc + name = "mercenary" + desc = "A tough looking heavily-armed individual." + tt_desc = "E Homo sapiens" + icon_state = "syndicate" + icon_living = "syndicate" + icon_dead = "syndicate_dead" + icon_gib = "syndicate_gib" + + faction = "syndicate" + movement_cooldown = 4 + + status_flags = 0 + + response_help = "pokes" + response_disarm = "shoves" + response_harm = "hits" + + harm_intent_damage = 5 + melee_damage_lower = 15 //Tac Knife damage + melee_damage_upper = 15 + attack_sharp = 1 + attack_edge = 1 + attacktext = list("slashed", "stabbed") + armor = list(melee = 40, bullet = 30, laser = 30, energy = 10, bomb = 10, bio = 100, rad = 100) // Same armor values as the vest they drop, plus simple mob immunities + + corpse = /obj/effect/landmark/mobcorpse/syndicatesoldier + loot_list = list(/obj/item/weapon/material/knife/tacknife = 100) // Might as well give it the knife + + ai_holder_type = /datum/ai_holder/simple_mob/merc + say_list_type = /datum/say_list/merc + + // Grenade special attack vars + var/grenade_type = /obj/item/weapon/grenade/concussion + special_attack_cooldown = 45 SECONDS + special_attack_min_range = 2 + special_attack_max_range = 7 + +//////////////////////////////// +// Grenade Attack +//////////////////////////////// + +// Any merc can use this, just set special_attack_charges to a positive value + +// Check if we should bother with the grenade +/mob/living/simple_mob/humanoid/merc/should_special_attack(atom/A) + var/mob_count = 0 // Are there enough mobs to consider grenading? + var/turf/T = get_turf(A) + for(var/mob/M in range(T, 2)) + if(M.faction == faction) // Don't grenade our friends + return FALSE + if(M in oview(src, special_attack_max_range)) // And lets check if we can actually see at least two people before we throw a grenade + if(!M.stat) // Dead things don't warrant a grenade + mob_count ++ + if(mob_count < 2) + return FALSE + else + return TRUE + +// Yes? Throw the grenade +/mob/living/simple_mob/humanoid/merc/do_special_attack(atom/A) + set waitfor = FALSE + set_AI_busy(TRUE) + + var/obj/item/weapon/grenade/G = new grenade_type(get_turf(src)) + if(istype(G)) + G.throw_at(A, G.throw_range, G.throw_speed, src) + G.attack_self(src) + special_attack_charges = max(special_attack_charges-1, 0) + + set_AI_busy(FALSE) + + +//////////////////////////////// +// Merc AI Types +//////////////////////////////// +/datum/ai_holder/simple_mob/merc + threaten = TRUE + returns_home = TRUE // Stay close to the base... + wander = TRUE // ... but "patrol" a little. + +/datum/ai_holder/simple_mob/merc/ranged + pointblank = TRUE // They get close? Just shoot 'em! + firing_lanes = TRUE // But not your buddies! + conserve_ammo = TRUE // And don't go wasting bullets! + + +//////////////////////////////// +// Melee +//////////////////////////////// +/mob/living/simple_mob/humanoid/merc/melee // Defined in case we add non-sword-and-board mercs + loot_list = list(/obj/item/weapon/material/knife/tacknife = 100) + +// Sword and Shield Merc +/mob/living/simple_mob/humanoid/merc/melee/sword + icon_state = "syndicatemelee" + icon_living = "syndicatemelee" + + melee_damage_lower = 30 + melee_damage_upper = 30 + attack_armor_pen = 50 + attack_sharp = 1 + attack_edge = 1 + attacktext = list("slashed") + + loot_list = list(/obj/item/weapon/melee/energy/sword/red = 100, /obj/item/weapon/shield/energy = 100) + +// They have a shield, so they try to block +/mob/living/simple_mob/humanoid/merc/melee/sword/attackby(var/obj/item/O as obj, var/mob/user as mob) + if(O.force) + if(prob(20)) + visible_message("\The [src] blocks \the [O] with its shield!") + if(user) + ai_holder.react_to_attack(user) + return + else + ..() + else + to_chat(user, "This weapon is ineffective, it does no damage.") + visible_message("\The [user] gently taps [src] with \the [O].") + +/mob/living/simple_mob/humanoid/merc/melee/sword/bullet_act(var/obj/item/projectile/Proj) + if(!Proj) return + if(prob(35)) + visible_message("[src] blocks [Proj] with its shield!") + if(Proj.firer) + ai_holder.react_to_attack(Proj.firer) + return + else + ..() + + +//////////////////////////////// +// Ranged +//////////////////////////////// + +// Base Ranged Merc, so we don't have to redefine a million vars for every subtype. Uses a pistol. +/mob/living/simple_mob/humanoid/merc/ranged + icon_state = "syndicateranged" + icon_living = "syndicateranged" + projectiletype = /obj/item/projectile/bullet/pistol/medium +// casingtype = /obj/item/ammo_casing/spent //Makes infinite stacks of bullets when put in PoIs. + projectilesound = 'sound/weapons/Gunshot_light.ogg' + loot_list = list(/obj/item/weapon/gun/projectile/colt = 100) + + needs_reload = TRUE + reload_max = 7 // Not the best default, but it fits the pistol + ai_holder_type = /datum/ai_holder/simple_mob/merc/ranged + +// C20r SMG +/mob/living/simple_mob/humanoid/merc/ranged/smg + icon_state = "syndicateranged_smg" + icon_living = "syndicateranged_smg" + + loot_list = list(/obj/item/weapon/gun/projectile/automatic/c20r = 100) + + base_attack_cooldown = 5 // Two attacks a second or so. + reload_max = 20 + +// Laser Rifle +/mob/living/simple_mob/humanoid/merc/ranged/laser + icon_state = "syndicateranged_laser" + icon_living = "syndicateranged_laser" + projectiletype = /obj/item/projectile/beam/midlaser + projectilesound = 'sound/weapons/Laser.ogg' + + loot_list = list(/obj/item/weapon/gun/energy/laser = 100) + + reload_max = 10 + +// Ion Rifle +/mob/living/simple_mob/humanoid/merc/ranged/ionrifle + icon_state = "syndicateranged_ionrifle" + icon_living = "syndicateranged_ionrifle" + projectiletype = /obj/item/projectile/ion + projectilesound = 'sound/weapons/Laser.ogg' + + loot_list = list(/obj/item/weapon/gun/energy/ionrifle = 100) + + reload_max = 10 + +// Grenadier, Basically a miniboss +/mob/living/simple_mob/humanoid/merc/ranged/grenadier + icon_state = "syndicateranged_shotgun" + icon_living = "syndicateranged_shotgun" + projectiletype = /obj/item/projectile/bullet/pellet/shotgun // Buckshot + projectilesound = 'sound/weapons/Gunshot_shotgun.ogg' + + loot_list = list(/obj/item/weapon/gun/projectile/shotgun/pump = 100) + + reload_max = 4 + reload_time = 1.5 SECONDS // It's a shotgun, it takes a moment + + special_attack_charges = 5 + + +//////////////////////////////// +// Space Mercs +//////////////////////////////// + +// Sword Space Merc +/mob/living/simple_mob/humanoid/merc/melee/sword/space + name = "syndicate commando" + icon_state = "syndicatemeleespace" + icon_living = "syndicatemeleespace" + + movement_cooldown = 0 + + armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 100) // Same armor as their voidsuit + + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + minbodytemp = 0 + + corpse = /obj/effect/landmark/mobcorpse/syndicatecommando + +/mob/living/simple_mob/humanoid/merc/melee/sword/space/Process_Spacemove(var/check_drift = 0) + return + +// Ranged Space Merc +/mob/living/simple_mob/humanoid/merc/ranged/space + name = "syndicate sommando" + icon_state = "syndicaterangedpsace" + icon_living = "syndicaterangedpsace" + + movement_cooldown = 0 + + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + minbodytemp = 0 + + corpse = /obj/effect/landmark/mobcorpse/syndicatecommando + +/mob/living/simple_mob/humanoid/merc/ranged/space/Process_Spacemove(var/check_drift = 0) + return + +//////////////////////////////// +// PoI Mercs +//////////////////////////////// + +// None of these drop weapons, until we have a better way to balance them +/mob/living/simple_mob/humanoid/merc/melee/poi + loot_list = list() + +/mob/living/simple_mob/humanoid/merc/melee/sword/poi + loot_list = list() + +/mob/living/simple_mob/humanoid/merc/ranged/poi + loot_list = list() + +/mob/living/simple_mob/humanoid/merc/ranged/smg/poi + loot_list = list() + +/mob/living/simple_mob/humanoid/merc/ranged/laser/poi + loot_list = list() + +/mob/living/simple_mob/humanoid/merc/ranged/ionrifle + loot_list = list() + +/mob/living/simple_mob/humanoid/merc/ranged/grenadier/poi + loot_list = list() \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/humanoid/pirates.dm b/code/modules/mob/living/simple_mob/subtypes/humanoid/pirates.dm new file mode 100644 index 0000000000..cc16cebedc --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/humanoid/pirates.dm @@ -0,0 +1,40 @@ +/mob/living/simple_mob/humanoid/pirate + name = "Pirate" + desc = "Does what he wants cause a pirate is free." + tt_desc = "E Homo sapiens" + icon_state = "piratemelee" + icon_living = "piratemelee" + icon_dead = "piratemelee_dead" + + faction = "pirate" + + response_help = "pushes" + response_disarm = "shoves" + response_harm = "hits" + + harm_intent_damage = 5 + melee_damage_lower = 30 + melee_damage_upper = 30 + attack_armor_pen = 50 + attack_sharp = 1 + attack_edge = 1 + + attacktext = list("slashed") + attack_sound = 'sound/weapons/bladeslice.ogg' + + loot_list = list(/obj/item/weapon/melee/energy/sword/pirate = 100) + + corpse = /obj/effect/landmark/mobcorpse/pirate + +/mob/living/simple_mob/humanoid/pirate/ranged + name = "Pirate Gunner" + icon_state = "pirateranged" + icon_living = "pirateranged" + icon_dead = "piratemelee_dead" + + projectiletype = /obj/item/projectile/beam + projectilesound = 'sound/weapons/laser.ogg' + + loot_list = list(/obj/item/weapon/gun/energy/laser = 100) + + corpse = /obj/effect/landmark/mobcorpse/pirate/ranged \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/humanoid/russian.dm b/code/modules/mob/living/simple_mob/subtypes/humanoid/russian.dm new file mode 100644 index 0000000000..ce679f90de --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/humanoid/russian.dm @@ -0,0 +1,35 @@ +/mob/living/simple_mob/humanoid/russian + name = "russian" + desc = "For the Motherland!" + tt_desc = "E Homo sapiens" + icon_state = "russianmelee" + icon_living = "russianmelee" + icon_dead = "russianmelee_dead" + icon_gib = "syndicate_gib" + + faction = "russian" + + response_help = "pokes" + response_disarm = "shoves" + response_harm = "hits" + + harm_intent_damage = 5 + melee_damage_lower = 15 + melee_damage_upper = 15 + attacktext = list("punched") + + loot_list = list(/obj/item/weapon/material/knife = 100) + + corpse = /obj/effect/landmark/mobcorpse/russian + +/mob/living/simple_mob/humanoid/russian/ranged + icon_state = "russianranged" + icon_living = "russianranged" + + projectiletype = /obj/item/projectile/bullet + casingtype = /obj/item/ammo_casing/spent + projectilesound = 'sound/weapons/Gunshot4.ogg' + + loot_list = list(/obj/item/weapon/gun/projectile/revolver/mateba = 100) + + corpse = /obj/effect/landmark/mobcorpse/russian/ranged \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/illusion/illusion.dm b/code/modules/mob/living/simple_mob/subtypes/illusion/illusion.dm new file mode 100644 index 0000000000..60cc13fb2b --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/illusion/illusion.dm @@ -0,0 +1,101 @@ +// Illusion type mobs pretend to be other things visually, and generally cannot be harmed as they're not 'real'. + +/mob/living/simple_mob/illusion + name = "illusion" + desc = "If you can read me, the game broke. Please report this to a coder." + + resistance = 1000 // Holograms are tough. + heat_resist = 1 + cold_resist = 1 + shock_resist = 1 + poison_resist = 1 + + movement_cooldown = 0 + mob_bump_flag = 0 // If the illusion can't be swapped it will be obvious. + + response_help = "pushes a hand through" + response_disarm = "tried to disarm" + response_harm = "tried to punch" + + mob_class = MOB_CLASS_ILLUSION + + ai_holder_type = /datum/ai_holder/simple_mob/inert/astar // Gets controlled manually by technomancers/admins, with AI pathfinding assistance. + + var/atom/movable/copying = null // The thing we're trying to look like. + var/realistic = FALSE // If true, things like bullets and weapons will hit it, to be a bit more convincing from a distance. + +/mob/living/simple_mob/illusion/update_icon() // We don't want the appearance changing AT ALL unless by copy_appearance(). + return + +/mob/living/simple_mob/illusion/proc/copy_appearance(atom/movable/thing_to_copy) + if(!thing_to_copy) + return FALSE + appearance = thing_to_copy.appearance + copying = thing_to_copy + density = thing_to_copy.density // So you can't bump into objects that aren't supposed to be dense. + return TRUE + +// Because we can't perfectly duplicate some examine() output, we directly examine the AM it is copying. It's messy but +// this is to prevent easy checks from the opposing force. +/mob/living/simple_mob/illusion/examine(mob/user) + if(copying) + copying.examine(user) + return + ..() + +/mob/living/simple_mob/illusion/bullet_act(obj/item/projectile/P) + if(!P) + return + + if(realistic) + return ..() + + return PROJECTILE_FORCE_MISS + +/mob/living/simple_mob/illusion/attack_hand(mob/living/carbon/human/M) + if(!realistic) + playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) + visible_message(span("warning", "\The [M]'s hand goes through \the [src]!")) + return + else + switch(M.a_intent) + if(I_HELP) + var/datum/gender/T = gender_datums[src.get_visible_gender()] + M.visible_message( + span("notice", "\The [M] hugs [src] to make [T.him] feel better!"), \ + span("notice", "You hug [src] to make [T.him] feel better!") + ) // slightly redundant as at the moment most mobs still use the normal gender var, but it works and future-proofs it + playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + + if(I_DISARM) + playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) + visible_message(span("danger", "\The [M] attempted to disarm [src]!")) + M.do_attack_animation(src) + + if(I_GRAB) + ..() + + if(I_HURT) + adjustBruteLoss(harm_intent_damage) + M.visible_message(span("danger", "\The [M] [response_harm] \the [src]")) + M.do_attack_animation(src) + +/mob/living/simple_mob/illusion/hit_with_weapon(obj/item/I, mob/living/user, effective_force, hit_zone) + if(realistic) + return ..() + + playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) + visible_message(span("warning", "\The [user]'s [I] goes through \the [src]!")) + return FALSE + +/mob/living/simple_mob/illusion/ex_act() + return + +// Try to have the same tooltip, or else it becomes really obvious which one is fake. +/mob/living/simple_mob/illusion/get_nametag_name(mob/user) + if(copying) + return copying.get_nametag_name(user) + +/mob/living/simple_mob/illusion/get_nametag_desc(mob/user) + if(copying) + return copying.get_nametag_desc(user) diff --git a/code/modules/mob/living/simple_mob/subtypes/mechanical/combat_drone.dm b/code/modules/mob/living/simple_mob/subtypes/mechanical/combat_drone.dm new file mode 100644 index 0000000000..8e5f6ef2a0 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/mechanical/combat_drone.dm @@ -0,0 +1,77 @@ +/* + Combat drones have a rapid ranged attack, and have a projectile shield. + They are rather slow, but attempt to 'kite' its target. + A solid hit with an EMP grenade will kill the shield instantly. +*/ + +/mob/living/simple_mob/mechanical/combat_drone + name = "combat drone" + desc = "An automated combat drone armed with state of the art weaponry and shielding." + icon_state = "drone" + icon_living = "drone" + icon_dead = "drone_dead" + has_eye_glow = TRUE + + faction = "malf_drone" + + maxHealth = 50 // Shield has 150 for total of 200. + health = 50 + movement_cooldown = 5 + hovering = TRUE + + base_attack_cooldown = 5 + projectiletype = /obj/item/projectile/beam/drone + projectilesound = 'sound/weapons/laser3.ogg' + + response_help = "pokes" + response_disarm = "gently pushes aside" + response_harm = "hits" + + ai_holder_type = /datum/ai_holder/simple_mob/ranged/kiting/threatening + say_list_type = /datum/say_list/malf_drone + + var/datum/effect/effect/system/ion_trail_follow/ion_trail = null + var/obj/item/shield_projector/shields = null + +/mob/living/simple_mob/mechanical/combat_drone/Initialize() + ion_trail = new + ion_trail.set_up(src) + ion_trail.start() + + shields = new /obj/item/shield_projector/rectangle/automatic/drone(src) + return ..() + +/mob/living/simple_mob/mechanical/combat_drone/Destroy() + QDEL_NULL(ion_trail) + QDEL_NULL(shields) + return ..() + +/mob/living/simple_mob/mechanical/combat_drone/death() + ..(null,"suddenly breaks apart.") + qdel(src) + +/mob/living/simple_mob/mechanical/combat_drone/Process_Spacemove(var/check_drift = 0) + return TRUE + +/obj/item/projectile/beam/drone + damage = 10 + +/obj/item/shield_projector/rectangle/automatic/drone + shield_health = 150 + max_shield_health = 150 + shield_regen_delay = 10 SECONDS + shield_regen_amount = 10 + size_x = 1 + size_y = 1 + +// A slightly easier drone, for POIs. +// Difference is that it should not be faster than you. +/mob/living/simple_mob/mechanical/combat_drone/lesser + desc = "An automated combat drone with an aged apperance." + movement_cooldown = 10 + + +// This one is the type spawned by the random event. +// It won't wander away from its spawn point +/mob/living/simple_mob/mechanical/combat_drone/event + ai_holder_type = /datum/ai_holder/simple_mob/ranged/kiting/threatening/event diff --git a/code/modules/mob/living/simple_mob/subtypes/mechanical/golem.dm b/code/modules/mob/living/simple_mob/subtypes/mechanical/golem.dm new file mode 100644 index 0000000000..a8b918fc71 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/mechanical/golem.dm @@ -0,0 +1,152 @@ +// The GOLEM is a spell-flinging synthetic. + +/mob/living/simple_mob/mechanical/technomancer_golem + name = "unknown synthetic" + desc = "A rather unusual looking synthetic." + icon = 'icons/mob/mob.dmi' + icon_state = "golem" + health = 300 + maxHealth = 300 + + faction = "golem" + + response_help = "pets" + response_disarm = "pushes away" + response_harm = "punches" + harm_intent_damage = 3 + friendly = "hugs" + + melee_damage_lower = 30 // It has a built in esword. + melee_damage_upper = 30 + attack_sound = 'sound/weapons/blade1.ogg' + attacktext = list("slashed") + melee_attack_delay = 0.5 SECONDS // Even has custom attack animations. + ranged_attack_delay = 0.5 SECONDS + special_attack_delay = 1 SECOND + + special_attack_min_range = 0 + special_attack_max_range = 7 + + ai_holder_type = /datum/ai_holder/simple_mob/melee + + var/obj/item/weapon/technomancer_core/golem/core = null + var/obj/item/weapon/spell/active_spell = null // Shield and ranged spells + var/mob/living/master = null + var/casting = FALSE // Used to ensure the correct animation is played. Testing if a spell exists won't always work as some spells delete themselves upon use. + + var/list/known_spells = list( + "beam" = /obj/item/weapon/spell/projectile/beam, + "chain lightning" = /obj/item/weapon/spell/projectile/chain_lightning, + "force missile" = /obj/item/weapon/spell/projectile/force_missile, + "ionic bolt" = /obj/item/weapon/spell/projectile/ionic_bolt, + "lightning" = /obj/item/weapon/spell/projectile/lightning, + "blink" = /obj/item/weapon/spell/blink, + "dispel" = /obj/item/weapon/spell/dispel, + "oxygenate" = /obj/item/weapon/spell/oxygenate, + "mend life" = /obj/item/weapon/spell/modifier/mend_life, + "mend synthetic" = /obj/item/weapon/spell/modifier/mend_synthetic, + "mend organs" = /obj/item/weapon/spell/mend_organs, + "purify" = /obj/item/weapon/spell/modifier/purify, + "resurrect" = /obj/item/weapon/spell/resurrect, + "passwall" = /obj/item/weapon/spell/passwall, + "repel missiles" = /obj/item/weapon/spell/modifier/repel_missiles, + "corona" = /obj/item/weapon/spell/modifier/corona, + "haste" = /obj/item/weapon/spell/modifier/haste + ) + +/mob/living/simple_mob/mechanical/technomancer_golem/Initialize() + core = new(src) + return ..() + +/mob/living/simple_mob/mechanical/technomancer_golem/Destroy() + qdel(core) + return ..() + +/mob/living/simple_mob/mechanical/technomancer_golem/unref_spell() + active_spell = null + return ..() + +/mob/living/simple_mob/mechanical/technomancer_golem/death() + ..() + visible_message("\The [src] disintegrates!") + new /obj/effect/decal/cleanable/blood/gibs/robot(src.loc) + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(3, 1, src) + s.start() + qdel(src) + +/mob/living/simple_mob/mechanical/technomancer_golem/place_spell_in_hand(var/path) + if(!path || !ispath(path)) + return FALSE + if(active_spell) + qdel(active_spell) + + active_spell = new path(src) + +/mob/living/simple_mob/mechanical/technomancer_golem/verb/test_giving_spells() + var/choice = input(usr, "What spell?", "Give spell") as null|anything in known_spells + if(choice) + place_spell_in_hand(known_spells[choice]) + else + qdel(active_spell) + +/mob/living/simple_mob/mechanical/technomancer_golem/get_technomancer_core() + return core + +/mob/living/simple_mob/mechanical/technomancer_golem/can_special_attack(atom/A) + if(active_spell) // Don't bother checking everything else if no spell is ready. + return ..() + return FALSE + +/mob/living/simple_mob/mechanical/technomancer_golem/should_special_attack(atom/A) + return instability < 50 // Don't kill ourselves by casting everything. + + +/mob/living/simple_mob/mechanical/technomancer_golem/do_special_attack(atom/A) + var/proximity = Adjacent(A) + if(active_spell) + if(proximity && active_spell.cast_methods & CAST_MELEE) // Use melee method if available and close enough. + return active_spell.on_melee_cast(A, src) + else if(active_spell.cast_methods & CAST_RANGED) // Otherwise use ranged if possible. Will also work for point-blank range. + return active_spell.on_ranged_cast(A, src) + return ..() + +/mob/living/simple_mob/mechanical/technomancer_golem/melee_pre_animation(atom/A) + if(active_spell && active_spell.cast_methods & CAST_MELEE|CAST_RANGED) // If they're trying to melee-cast a spell, use the special animation instead. + special_pre_animation(A) + return + + flick("golem_pre_melee", src) // To force the animation to restart. + icon_living = "golem_pre_melee" // The animation will hold after this point until melee_post_animation() gets called. + icon_state = "golem_pre_melee" + setClickCooldown(2) + +/mob/living/simple_mob/mechanical/technomancer_golem/melee_post_animation(atom/A) + if(casting) // Some spells delete themselves when used, so we use a different variable set earlier instead. + special_post_animation(A) + return + + flick("golem_post_melee", src) + icon_living = "golem" + icon_state = "golem" + setClickCooldown(6) + +/mob/living/simple_mob/mechanical/technomancer_golem/ranged_pre_animation(atom/A) + flick("golem_pre_ranged", src) + icon_living = "golem_pre_ranged" + icon_state = "golem_pre_ranged" + setClickCooldown(5) + +/mob/living/simple_mob/mechanical/technomancer_golem/ranged_post_animation(atom/A) + flick("golem_post_ranged", src) + icon_living = "golem" + icon_state = "golem" + setClickCooldown(5) + +/mob/living/simple_mob/mechanical/technomancer_golem/special_pre_animation(atom/A) + casting = TRUE + ranged_pre_animation(A) // Both have the same animation. + +/mob/living/simple_mob/mechanical/technomancer_golem/special_post_animation(atom/A) + casting = FALSE + ranged_post_animation(A) \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/mechanical/hivebot/hivebot.dm b/code/modules/mob/living/simple_mob/subtypes/mechanical/hivebot/hivebot.dm new file mode 100644 index 0000000000..c90d0413be --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/mechanical/hivebot/hivebot.dm @@ -0,0 +1,54 @@ +// Hivebots are tuned towards how many default lasers are needed to kill them. +// As such, if laser damage is ever changed, you should change this define. +#define LASERS_TO_KILL * 40 + +/mob/living/simple_mob/mechanical/hivebot + name = "hivebot" + desc = "A robot. It appears to be somewhat resilient, but lacks a true weapon." + icon = 'icons/mob/hivebot.dmi' + icon_state = "basic" + icon_living = "basic" + + faction = "hivebot" + + maxHealth = 3 LASERS_TO_KILL + health = 3 LASERS_TO_KILL + water_resist = 0.5 + movement_sound = 'sound/effects/servostep.ogg' + + attacktext = list("clawed") + projectilesound = 'sound/weapons/Gunshot_old.ogg' + + ai_holder_type = /datum/ai_holder/simple_mob/hivebot + say_list_type = /datum/say_list/hivebot + + +/mob/living/simple_mob/mechanical/hivebot/death() + ..() + visible_message(span("warning","\The [src] blows apart!")) + new /obj/effect/decal/cleanable/blood/gibs/robot(src.loc) + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(3, 1, src) + s.start() + qdel(src) + +// The hivebot's default projectile. +/obj/item/projectile/bullet/hivebot + damage = 10 + damage_type = BRUTE + sharp = FALSE + edge = FALSE + +/mob/living/simple_mob/mechanical/hivebot/swarm + name = "swarm hivebot" + desc = "A robot. It looks fragile and weak." + maxHealth = 1 LASERS_TO_KILL + health = 1 LASERS_TO_KILL + melee_damage_lower = 8 + melee_damage_upper = 8 + +/datum/ai_holder/simple_mob/hivebot + pointblank = TRUE + conserve_ammo = TRUE + firing_lanes = TRUE + can_flee = FALSE // Fearless dumb machines. \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/mechanical/hivebot/ranged_damage.dm b/code/modules/mob/living/simple_mob/subtypes/mechanical/hivebot/ranged_damage.dm new file mode 100644 index 0000000000..5e4d877751 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/mechanical/hivebot/ranged_damage.dm @@ -0,0 +1,147 @@ +// These hivebots are intended for general damage causing, at range. + +/mob/living/simple_mob/mechanical/hivebot/ranged_damage + maxHealth = 2 LASERS_TO_KILL // 60 health + health = 2 LASERS_TO_KILL + projectiletype = /obj/item/projectile/bullet/hivebot + +// The regular ranged hivebot, that fires somewhat weak projectiles. +/mob/living/simple_mob/mechanical/hivebot/ranged_damage/basic + name = "ranged hivebot" + desc = "A robot with a makeshift integrated ballistic weapon." + + +// This one shoots quickly, and is considerably more dangerous. +/mob/living/simple_mob/mechanical/hivebot/ranged_damage/rapid + name = "rapid hivebot" + desc = "A robot with a crude but deadly integrated rifle." + base_attack_cooldown = 5 // Two attacks a second or so. + player_msg = "You have a rapid fire attack." + + +// Shoots deadly lasers. +/mob/living/simple_mob/mechanical/hivebot/ranged_damage/laser + name = "laser hivebot" + desc = "A robot with a photonic weapon integrated into itself." + projectiletype = /obj/item/projectile/beam/blue + projectilesound = 'sound/weapons/Laser.ogg' + player_msg = "You have a laser attack." + + +// Shoots EMPs, to screw over other robots. +/mob/living/simple_mob/mechanical/hivebot/ranged_damage/ion + name = "ionic hivebot" + desc = "A robot with an electromagnetic pulse projector." + icon_state = "yellow" + icon_living = "yellow" + + projectiletype = /obj/item/projectile/ion + projectilesound = 'sound/weapons/Laser.ogg' + player_msg = "You have a ranged ion attack, which is very strong against other synthetics.
      \ + Be careful to not hit yourself or your team, as it will affect you as well." + +// Beefy and ranged. +/mob/living/simple_mob/mechanical/hivebot/ranged_damage/strong + name = "strong hivebot" + desc = "A robot with a crude ballistic weapon and strong armor." + maxHealth = 4 LASERS_TO_KILL // 120 health. + health = 4 LASERS_TO_KILL + melee_damage_lower = 15 + melee_damage_upper = 15 + +// Also beefy, but tries to stay at their 'home', ideal for base defense. +/mob/living/simple_mob/mechanical/hivebot/ranged_damage/strong/guard + name = "guard hivebot" + desc = "A robot that seems to be guarding something." +// ai_holder_type = todo + + +// Inflicts a damage-over-time modifier on things it hits. +// It is able to stack with repeated attacks. +/mob/living/simple_mob/mechanical/hivebot/ranged_damage/dot + name = "ember hivebot" + desc = "A robot that appears to utilize fire to cook their enemies." + icon_state = "red" + icon_living = "red" + + projectiletype = /obj/item/projectile/fire + heat_resist = 1 + player_msg = "Your attacks inflict a damage over time effect, that will \ + harm your target slowly. The effect stacks with further attacks.
      \ + You are also immune to fire." + +/obj/item/projectile/fire + name = "ember" + icon = 'icons/effects/effects.dmi' + icon_state = "explosion_particle" + modifier_type_to_apply = /datum/modifier/fire + modifier_duration = 6 SECONDS // About 15 damage per stack, as Life() ticks every two seconds. + damage = 0 + nodamage = TRUE + + +// Close to mid-ranged shooter that arcs over other things, ideal if allies are in front of it. +// Difference from siege hivebots is that siege hivebots have limited charges for their attacks, are very long range, and \ +// the projectiles have an AoE component, where as backline hivebots do not. +/mob/living/simple_mob/mechanical/hivebot/ranged_damage/backline + name = "backline hivebot" + desc = "A robot that can fire short-ranged projectiles over their allies." + projectiletype = /obj/item/projectile/arc/blue_energy + projectilesound = 'sound/weapons/Laser.ogg' + player_msg = "Your attacks are short-ranged, but can arc over obstructions such as allies \ + or barriers." + +/obj/item/projectile/arc/blue_energy + name = "energy missile" + icon_state = "force_missile" + damage = 15 // A bit stronger since arcing projectiles are much easier to avoid than traditional ones. + damage_type = BURN + +// Very long ranged hivebot that rains down hell. +// Their projectiles arc, meaning they go over everything until it hits the ground. +// This means they're somewhat easier to avoid, but go over most defenses (like allies, or barriers), +// and tend to do more harm than a regular projectile, due to being AoE. +/mob/living/simple_mob/mechanical/hivebot/ranged_damage/siege + name = "siege engine hivebot" + desc = "A large robot capable of delivering long range bombardment." + projectiletype = /obj/item/projectile/arc/test + icon_scale = 2 + icon_state = "red" + icon_living = "red" + + player_msg = "You are capable of firing very long range bombardment attacks.
      \ + To use, click on a tile or enemy at a long range. Note that the projectile arcs in the air, \ + so it will fly over everything inbetween you and the target.
      \ + The bombardment is most effective when attacking a static structure, as it cannot avoid your fire." + +// Fires EMP blasts. +/mob/living/simple_mob/mechanical/hivebot/ranged_damage/siege/emp + name = "ionic artillery hivebot" + desc = "A large robot capable of annihilating electronics from a long distance." + projectiletype = /obj/item/projectile/arc/emp_blast + +/obj/item/projectile/arc/emp_blast + name = "emp blast" + icon_state = "bluespace" + +/obj/item/projectile/arc/emp_blast/on_impact(turf/T) + empulse(T, 2, 4, 7, 10) // Normal EMP grenade. + return ..() + +/obj/item/projectile/arc/emp_blast/weak/on_impact(turf/T) + empulse(T, 1, 2, 3, 4) // Sec EMP grenade. + return ..() + + +// Fires shots that irradiate the tile hit. +/mob/living/simple_mob/mechanical/hivebot/ranged_damage/siege/radiation + name = "desolator hivebot" + desc = "A large robot capable of irradiating a large area from afar." + projectiletype = /obj/item/projectile/arc/radioactive + + +// Essentially a long ranged frag grenade. +/mob/living/simple_mob/mechanical/hivebot/ranged_damage/siege/fragmentation + name = "anti-personnel artillery hivebot" + desc = "A large robot capable of delivering fragmentation shells to rip apart their fleshy enemies." + projectiletype = /obj/item/projectile/arc/fragmentation \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/mechanical/hivebot/support.dm b/code/modules/mob/living/simple_mob/subtypes/mechanical/hivebot/support.dm new file mode 100644 index 0000000000..243a67e4f5 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/mechanical/hivebot/support.dm @@ -0,0 +1,87 @@ +// These hivebots help their team in various ways, and can be very powerful with allies, but are otherwise very weak when alone. + +/mob/living/simple_mob/mechanical/hivebot/support + icon_state = "white" + icon_living = "white" + attacktext = list("prodded") + movement_cooldown = 5 + melee_damage_lower = 2 + melee_damage_upper = 2 + + +// This hivebot supplies a general buff to nearby hivebots that improve their performance. +// Note that the commander itself does not receive the buff. +/mob/living/simple_mob/mechanical/hivebot/support/commander + name = "commander hivebot" + desc = "A robot that appears to be directing the others." + maxHealth = 5 LASERS_TO_KILL // 150 health + health = 5 LASERS_TO_KILL + player_msg = "You increase the performance of other hivebots near you passively.
      \ + You are otherwise very weak offensively." + +/mob/living/simple_mob/mechanical/hivebot/support/commander/handle_special() + for(var/mob/living/L in range(4, src)) + if(L == src) + continue // Don't buff ourselves. + if(IIsAlly(L) && L.isSynthetic()) // Don't buff enemies. + L.add_modifier(/datum/modifier/aura/hivebot_commander_buff, null, src) + +// Modifier added to friendly hivebots nearby. +// Boosts most stats by 30%. +// The boost is lost if the commander is too far away or dies. +/datum/modifier/aura/hivebot_commander_buff + name = "Strategicals" + on_created_text = "Signal established with commander. Optimizating combat performance..." + on_expired_text = "Lost signal to commander. Optimization halting." + stacks = MODIFIER_STACK_FORBID + aura_max_distance = 4 + mob_overlay_state = "signal_blue" + + disable_duration_percent = 0.7 + outgoing_melee_damage_percent = 1.3 + attack_speed_percent = 1.3 + accuracy = 30 + slowdown = -1 + evasion = 30 + +// Variant that automatically commands nearby allies to follow it when created. +// Useful to avoid having to manually set follow to a lot of hivebots that are gonna die in the next minute anyways. +/mob/living/simple_mob/mechanical/hivebot/support/commander/autofollow/Initialize() + for(var/mob/living/L in hearers(7, src)) + if(!L.ai_holder) + continue + if(L.faction != src.faction) + continue + var/datum/ai_holder/AI = L.ai_holder + AI.set_follow(src) + return ..() + + +// This hivebot adds charges to nearby allied hivebots that use the charge system for their special attacks. +// A charge is given to a nearby ally every so often. +// Charges cannot exceed the initial starting amount. +/mob/living/simple_mob/mechanical/hivebot/support/logistics + name = "logistics hivebot" + desc = "A robot that resupplies their allies." + maxHealth = 3 LASERS_TO_KILL // 90 health + health = 3 LASERS_TO_KILL + player_msg = "You passively restore 'charges' to allies with special abilities who are \ + limited to using them a specific number of times." + var/resupply_range = 5 + var/resupply_cooldown = 4 SECONDS + var/last_resupply = null + +/mob/living/simple_mob/mechanical/hivebot/support/logistics/handle_special() + if(last_resupply + resupply_cooldown > world.time) + return // On cooldown. + + for(var/mob/living/simple_mob/SM in hearers(resupply_range, src)) + if(SM == src) + continue // We don't use charges buuuuut in case that changes in the future... + if(IIsAlly(SM)) // Don't resupply enemies. + if(!isnull(SM.special_attack_charges) && SM.special_attack_charges < initial(SM.special_attack_charges)) + SM.special_attack_charges += 1 + to_chat(SM, span("notice", "\The [src] has resupplied you, and you can use your special ability one additional time.")) + to_chat(src, span("notice", "You have resupplied \the [SM].")) + last_resupply = world.time + break // Only one resupply per pulse. diff --git a/code/modules/mob/living/simple_mob/subtypes/mechanical/hivebot/tank.dm b/code/modules/mob/living/simple_mob/subtypes/mechanical/hivebot/tank.dm new file mode 100644 index 0000000000..007f190c04 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/mechanical/hivebot/tank.dm @@ -0,0 +1,166 @@ +// These hivebots are harder to kill than normal, and are meant to protect their squad by +// distracting their enemies. This is done by being seen as very threatening. +// Their melee attacks weaken whatever they hit. + +/mob/living/simple_mob/mechanical/hivebot/tank + attacktext = list("prodded") + projectiletype = null // To force the AI to melee. + movement_cooldown = 10 + melee_damage_lower = 3 + melee_damage_upper = 3 + attack_sound = 'sound/weapons/Egloves.ogg' + +// All tank hivebots apply a modifier to their target, and force them to attack them if they're AI controlled. +/mob/living/simple_mob/mechanical/hivebot/tank/apply_melee_effects(atom/A) + if(isliving(A)) + var/mob/living/L = A + L.taunt(src, TRUE) + L.add_modifier(/datum/modifier/hivebot_weaken, 3 SECONDS) + +// Modifier applied to whatever a tank hivebot hits, intended to make the target do even less damage. +/datum/modifier/hivebot_weaken + name = "Shocked" + desc = "You feel less able to exert yourself after being prodded." + on_created_text = "You feel weak..." + on_expired_text = "You feel better." + stacks = MODIFIER_STACK_EXTEND + mob_overlay_state = "electricity" + + attack_speed_percent = 0.6 + outgoing_melee_damage_percent = 0.7 + accuracy = -40 + accuracy_dispersion = 1 + slowdown = 1 + evasion = -20 + +// This one is tanky by having a massive amount of health. +/mob/living/simple_mob/mechanical/hivebot/tank/meatshield + name = "bulky hivebot" + desc = "A large robot." + maxHealth = 10 LASERS_TO_KILL // 300 health + health = 10 LASERS_TO_KILL + icon_scale = 2 + player_msg = "You have a very large amount of health." + + +// This one is tanky by having armor. +/mob/living/simple_mob/mechanical/hivebot/tank/armored + name = "armored hivebot" + desc = "A robot clad in heavy armor." + maxHealth = 5 LASERS_TO_KILL // 150 health. + health = 5 LASERS_TO_KILL + icon_scale = 1.5 + player_msg = "You are heavily armored." + // Note that armor effectively makes lasers do about 9 damage instead of 30, + // so it has an effective health of ~16.6 LASERS_TO_KILL if regular lasers are used. + // Xrays will do much better against this. + armor = list( + "melee" = 40, + "bullet" = 40, + "laser" = 40, + "energy" = 30, + "bomb" = 30, + "bio" = 100, + "rad" = 100 + ) + armor_soak = list( + "melee" = 15, + "bullet" = 10, + "laser" = 15, + "energy" = 0, + "bomb" = 0, + "bio" = 0, + "rad" = 0 + ) + +/mob/living/simple_mob/mechanical/hivebot/tank/armored/anti_melee + name = "riot hivebot" + desc = "A robot specialized in close quarters combat." + player_msg = "You are heavily armored against close quarters combat." + armor = list( + "melee" = 70, + "bullet" = 0, + "laser" = 0, + "energy" = 0, + "bomb" = 0, + "bio" = 100, + "rad" = 100 + ) + armor_soak = list( + "melee" = 20, + "bullet" = 0, + "laser" = 0, + "energy" = 0, + "bomb" = 0, + "bio" = 0, + "rad" = 0 + ) + +/mob/living/simple_mob/mechanical/hivebot/tank/armored/anti_bullet + name = "bulletproof hivebot" + desc = "A robot specialized in ballistic defense." + player_msg = "You are heavily armored against ballistic weapons." + armor = list( + "melee" = 0, + "bullet" = 70, + "laser" = 0, + "energy" = 0, + "bomb" = 0, + "bio" = 100, + "rad" = 100 + ) + armor_soak = list( + "melee" = 0, + "bullet" = 20, + "laser" = 0, + "energy" = 0, + "bomb" = 0, + "bio" = 0, + "rad" = 0 + ) + +/mob/living/simple_mob/mechanical/hivebot/tank/armored/anti_laser + name = "ablative hivebot" + desc = "A robot specialized in photonic defense." + player_msg = "You are heavily armored against laser weapons." + armor = list( + "melee" = 0, + "bullet" = 0, + "laser" = 70, + "energy" = 0, + "bomb" = 0, + "bio" = 100, + "rad" = 100 + ) + armor_soak = list( + "melee" = 0, + "bullet" = 0, + "laser" = 20, + "energy" = 0, + "bomb" = 0, + "bio" = 0, + "rad" = 0 + ) + var/reflect_chance = 40 // Same as regular ablative. + +// Ablative Hivebots can reflect lasers just like humans. +/mob/living/simple_mob/mechanical/hivebot/tank/armored/anti_laser/bullet_act(obj/item/projectile/P) + if(istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam)) + var/reflect_prob = reflect_chance - round(P.damage/3) + if(prob(reflect_prob)) + visible_message(span("danger", "The [P.name] gets reflected by [src]'s armor!"), \ + span("userdanger", "The [P.name] gets reflected by [src]'s armor!")) + + // Find a turf near or on the original location to bounce to + if(P.starting) + var/new_x = P.starting.x + pick(0, 0, -1, 1, -2, 2, -2, 2, -2, 2, -3, 3, -3, 3) + var/new_y = P.starting.y + pick(0, 0, -1, 1, -2, 2, -2, 2, -2, 2, -3, 3, -3, 3) + var/turf/curloc = get_turf(src) + + // redirect the projectile + P.redirect(new_x, new_y, curloc, src) + P.reflected = 1 + + return -1 // complete projectile permutation + + return (..(P)) diff --git a/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/adv_dark_gygax.dm b/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/adv_dark_gygax.dm new file mode 100644 index 0000000000..b58c6f1a04 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/adv_dark_gygax.dm @@ -0,0 +1,263 @@ +// Stronger than a regular Dark Gygax, this one has three special attacks, based on intents. +// First special attack launches three arcing rockets at the current target. +// Second special attack fires a projectile that creates a short-lived microsingularity that pulls in everything nearby. Magboots can protect from this. +// Third special attack creates a dangerous electric field that causes escalating electric damage, before emitting a tesla shock and blinding anyone looking at the mecha. +// The AI will choose one every ten seconds. +/mob/living/simple_mob/mechanical/mecha/combat/gygax/dark/advanced + name = "advanced dark gygax" + desc = "An experimental exosuit that utilizes advanced materials to allow for greater protection while still being lightweight and fast. \ + It also is armed with an array of next-generation weaponry." + icon_state = "darkgygax_adv" + wreckage = /obj/structure/loot_pile/mecha/gygax/dark/adv + icon_scale = 1.5 + movement_shake_radius = 14 + + maxHealth = 450 + deflect_chance = 25 + has_repair_droid = TRUE + armor = list( + "melee" = 50, + "bullet" = 50, + "laser" = 50, + "energy" = 30, + "bomb" = 30, + "bio" = 100, + "rad" = 100 + ) + + special_attack_min_range = 1 + special_attack_max_range = 7 + special_attack_cooldown = 10 SECONDS + projectiletype = /obj/item/projectile/force_missile + projectilesound = 'sound/weapons/wave.ogg' + var/obj/effect/overlay/energy_ball/energy_ball = null + +/mob/living/simple_mob/mechanical/mecha/combat/gygax/dark/advanced/Destroy() + if(energy_ball) + energy_ball.stop_orbit() + qdel(energy_ball) + return ..() + +/mob/living/simple_mob/mechanical/mecha/combat/gygax/dark/advanced/do_special_attack(atom/A) + . = TRUE // So we don't fire a laser as well. + switch(a_intent) + if(I_DISARM) // Side gun + electric_defense(A) + if(I_HURT) // Rockets + launch_rockets(A) + if(I_GRAB) // Micro-singulo + launch_microsingularity(A) + +#define ELECTRIC_ZAP_POWER 20000 + +// Charges a tesla shot, while emitting a dangerous electric field. The exosuit is immune to electric damage while this is ongoing. +// It also briefly blinds anyone looking directly at the mech without flash protection. +/mob/living/simple_mob/mechanical/mecha/combat/gygax/dark/advanced/proc/electric_defense(atom/target) + set waitfor = FALSE + + // Temporary immunity to shock to avoid killing themselves with their own attack. + var/old_shock_resist = shock_resist + shock_resist = 1 + + // Make the energy ball. This is purely visual since the tesla ball is hyper-deadly. + energy_ball = new(loc) + energy_ball.adjust_scale(0.5) + energy_ball.orbit(src, 32, TRUE, 1 SECOND) + + visible_message(span("warning", "\The [src] creates \an [energy_ball] around itself!")) + + playsound(src.loc, 'sound/effects/lightning_chargeup.ogg', 100, 1, extrarange = 30) + + // Shock nearby things that aren't ourselves. + for(var/i = 1 to 10) + energy_ball.adjust_scale(0.5 + (i/10)) + energy_ball.set_light(i/2, i/2, "#0000FF") + for(var/thing in range(3, src)) + // This is stupid because mechs are stupid and not mobs. + if(isliving(thing)) + var/mob/living/L = thing + + if(L == src) + continue + if(L.stat) + continue // Otherwise it can get pretty laggy if there's loads of corpses around. + L.inflict_shock_damage(i * 2) + if(L && L.has_AI()) // Some mobs delete themselves when dying. + L.ai_holder.react_to_attack(src) + + else if(istype(thing, /obj/mecha)) + var/obj/mecha/M = thing + M.take_damage(i * 2, "energy") // Mechs don't have a concept for siemens so energy armor check is the best alternative. + + sleep(1 SECOND) + + // Shoot a tesla bolt, and flashes people who are looking at the mecha without sufficent eye protection. + visible_message(span("warning", "\The [energy_ball] explodes in a flash of light, sending a shock everywhere!")) + playsound(src.loc, 'sound/effects/lightningbolt.ogg', 100, 1, extrarange = 30) + tesla_zap(src.loc, 5, ELECTRIC_ZAP_POWER, FALSE) + for(var/mob/living/L in viewers(src)) + if(L == src) + continue + var/dir_towards_us = get_dir(L, src) + if(L.dir && L.dir & dir_towards_us) + to_chat(L, span("danger", "The flash of light blinds you briefly.")) + L.flash_eyes(intensity = FLASH_PROTECTION_MODERATE, override_blindness_check = FALSE, affect_silicon = TRUE) + + // Get rid of our energy ball. + energy_ball.stop_orbit() + qdel(energy_ball) + + sleep(1 SECOND) + // Resist resistance to old value. + shock_resist = old_shock_resist // Not using initial() in case the value gets modified by an admin or something. + +#undef ELECTRIC_ZAP_POWER + +/mob/living/simple_mob/mechanical/mecha/combat/gygax/dark/advanced/proc/launch_rockets(atom/target) + set waitfor = FALSE + + // Telegraph our next move. + Beam(target, icon_state = "sat_beam", time = 3.5 SECONDS, maxdistance = INFINITY) + visible_message(span("warning", "\The [src] deploys a missile rack!")) + playsound(src, 'sound/effects/turret/move1.wav', 50, 1) + sleep(0.5 SECONDS) + + for(var/i = 1 to 3) + if(target) // Might get deleted in the meantime. + var/turf/T = get_turf(target) + if(T) + visible_message(span("warning", "\The [src] fires a rocket into the air!")) + playsound(src, 'sound/weapons/rpg.ogg', 70, 1) + face_atom(T) + var/obj/item/projectile/arc/explosive_rocket/rocket = new(loc) + rocket.old_style_target(T, src) + rocket.fire() + sleep(1 SECOND) + + visible_message(span("warning", "\The [src] retracts the missile rack.")) + playsound(src, 'sound/effects/turret/move2.wav', 50, 1) + +// Arcing rocket projectile that produces a weak explosion when it lands. +// Shouldn't punch holes in the floor, but will still hurt. +/obj/item/projectile/arc/explosive_rocket + name = "rocket" + icon_state = "mortar" + +/obj/item/projectile/arc/explosive_rocket/on_impact(turf/T) + new /obj/effect/explosion(T) // Weak explosions don't produce this on their own, apparently. + explosion(T, 0, 0, 2, adminlog = FALSE) + +/mob/living/simple_mob/mechanical/mecha/combat/gygax/dark/advanced/proc/launch_microsingularity(atom/target) + var/turf/T = get_turf(target) + visible_message(span("warning", "\The [src] fires an energetic sphere into the air!")) + playsound(src, 'sound/weapons/Laser.ogg', 50, 1) + face_atom(T) + var/obj/item/projectile/arc/microsingulo/sphere = new(loc) + sphere.old_style_target(T, src) + sphere.fire() + +/obj/item/projectile/arc/microsingulo + name = "micro singularity" + icon_state = "bluespace" + +/obj/item/projectile/arc/microsingulo/on_impact(turf/T) + new /obj/effect/temporary_effect/pulse/microsingulo(T) + + +/obj/effect/temporary_effect/pulse/microsingulo + name = "micro singularity" + desc = "It's sucking everything in!" + icon = 'icons/obj/objects.dmi' + icon_state = "bhole3" + light_range = 4 + light_power = 5 + light_color = "#2ECCFA" + pulses_remaining = 10 + pulse_delay = 0.5 SECONDS + var/pull_radius = 3 + var/pull_strength = STAGE_THREE + +/obj/effect/temporary_effect/pulse/microsingulo/on_pulse() + for(var/atom/A in range(pull_radius, src)) + A.singularity_pull(src, pull_strength) + + +// The Advanced Dark Gygax's AI. +// The mob has three special attacks, based on the current intent. +// This AI choose the appropiate intent for the situation, and tries to ensure it doesn't kill itself by firing missiles at its feet. +/datum/ai_holder/simple_mob/intentional/adv_dark_gygax + conserve_ammo = TRUE // Might help avoid 'I shoot the wall forever' cheese. + var/closest_desired_distance = 1 // Otherwise run up to them to be able to potentially shock or punch them. + + var/electric_defense_radius = 3 // How big to assume electric defense's area is. + var/microsingulo_radius = 3 // Same but for microsingulo pull. + var/rocket_explosive_radius = 2 // Explosion radius for the rockets. + + var/electric_defense_threshold = 2 // How many non-targeted people are needed in close proximity before electric defense is viable. + var/microsingulo_threshold = 2 // Similar to above, but uses an area around the target. + +// Used to control the mob's positioning based on which special attack it has done. +// Note that the intent will not change again until the next special attack is about to happen. +/datum/ai_holder/simple_mob/intentional/adv_dark_gygax/on_engagement(atom/A) + // Make the AI backpeddle if using an AoE special attack. + var/list/risky_intents = list(I_GRAB, I_HURT) // Mini-singulo and missiles. + if(holder.a_intent in risky_intents) + var/closest_distance = 1 + switch(holder.a_intent) // Plus one just in case. + if(I_HURT) + closest_distance = rocket_explosive_radius + 1 + if(I_GRAB) + closest_distance = microsingulo_radius + 1 + + if(get_dist(holder, A) <= closest_distance) + holder.IMove(get_step_away(holder, A, closest_distance)) + + // Otherwise get up close and personal. + else if(get_dist(holder, A) > closest_desired_distance) + holder.IMove(get_step_towards(holder, A)) + +// Changes the mob's intent, which controls which special attack is used. +// I_DISARM causes Electric Defense, I_GRAB causes Micro-Singularity, and I_HURT causes Missile Barrage. +/datum/ai_holder/simple_mob/intentional/adv_dark_gygax/pre_special_attack(atom/A) + if(isliving(A)) + var/mob/living/target = A + + // If we're surrounded, Electric Defense will quickly fix that. + var/tally = 0 + var/list/potential_targets = list_targets() // Returns list of mobs and certain objects like mechs and turrets. + for(var/atom/movable/AM in potential_targets) + if(get_dist(holder, AM) > electric_defense_radius) + continue + if(!can_attack(AM)) + continue + tally++ + + // Should we shock them? + if(tally >= electric_defense_threshold || get_dist(target, holder) <= electric_defense_radius) + holder.a_intent = I_DISARM + return + + // Otherwise they're a fair distance away and we're not getting mobbed up close. + // See if we should use missiles or microsingulo. + tally = 0 // Let's recycle the var. + for(var/atom/movable/AM in potential_targets) + if(get_dist(target, AM) > microsingulo_radius) // Deliberately tests distance between target and nearby targets and not the holder. + continue + if(!can_attack(AM)) + continue + if(AM.anchored) // Microsingulo doesn't do anything to anchored things. + tally-- + else + tally++ + + // Lots of people means minisingulo would be more useful. + if(tally >= microsingulo_threshold) + holder.a_intent = I_GRAB + else // Otherwise use rockets. + holder.a_intent = I_HURT + + else + if(get_dist(holder, A) >= rocket_explosive_radius + 1) + holder.a_intent = I_HURT // Fire rockets if it's an obj/turf. + else + holder.a_intent = I_DISARM // Electricity might not work but it's safe up close. diff --git a/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/combat_mecha.dm b/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/combat_mecha.dm new file mode 100644 index 0000000000..7a2d8abb19 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/combat_mecha.dm @@ -0,0 +1,38 @@ +// Base type for the 'combat' mechas like gygax/durand/maulers/etc. +// They generally are walking tanks, and their melee attack knocks back and stuns, like the real deal. + +/mob/living/simple_mob/mechanical/mecha/combat + name = "combat mecha" + desc = "An even bigger stompy mech!!" + + movement_cooldown = 10 + melee_damage_lower = 30 + melee_damage_upper = 30 + melee_attack_delay = 1 SECOND + attacktext = list("punched", "slammed", "uppercutted", "pummeled") + + armor = list( + "melee" = 30, + "bullet" = 30, + "laser" = 15, + "energy" = 0, + "bomb" = 20, + "bio" = 100, + "rad" = 100 + ) + + var/weaken_amount = 2 // Be careful with this number. High values can equal a permastun. + +// Melee hits knock back by one tile (or more if already stunned to help prevent permastuns). +/mob/living/simple_mob/mechanical/mecha/combat/apply_melee_effects(atom/A) + if(isliving(A)) + var/mob/living/L = A + if(L.mob_size <= MOB_MEDIUM) + visible_message(span("danger", "\The [src] sends \the [L] flying with their mechanized fist!")) + playsound(src, "punch", 50, 1) + L.Weaken(weaken_amount) + var/throw_dir = get_dir(src, L) + var/throw_dist = L.incapacitated(INCAPACITATION_DISABLED) ? 4 : 1 + L.throw_at(get_edge_target_turf(L, throw_dir), throw_dist, 1, src) + else + to_chat(L, span("warning", "\The [src] punches you with incredible force, but you remain in place.")) diff --git a/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/durand.dm b/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/durand.dm new file mode 100644 index 0000000000..df94a4f904 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/durand.dm @@ -0,0 +1,53 @@ +// Durands are slow, tanky, beefy, and hit really hard. +// They can also root themselves to become even tankier. +// The AI doesn't do this currently. + +/mob/living/simple_mob/mechanical/mecha/combat/durand + name = "durand" + desc = "An aging combat exosuit utilized by many corporations. It was originally developed to fight in the First Contact War." + icon_state = "durand" + movement_cooldown = 10 + wreckage = /obj/structure/loot_pile/mecha/durand + + maxHealth = 400 + deflect_chance = 20 + armor = list( + "melee" = 50, + "bullet" = 35, + "laser" = 15, + "energy" = 10, + "bomb" = 20, + "bio" = 100, + "rad" = 100 + ) + melee_damage_lower = 40 + melee_damage_upper = 40 + base_attack_cooldown = 2 SECONDS + projectiletype = /obj/item/projectile/beam/heavylaser + + var/defense_mode = FALSE + var/defense_deflect = 35 + +/mob/living/simple_mob/mechanical/mecha/combat/durand/proc/set_defense_mode(new_mode) + defense_mode = new_mode + deflect_chance = defense_mode ? defense_deflect : initial(deflect_chance) + to_chat(src, span("notice", "You [defense_mode ? "en" : "dis"]able defense mode.")) + +/mob/living/simple_mob/mechanical/mecha/combat/durand/SelfMove(turf/n, direct) + if(defense_mode) + to_chat(src, span("warning", "You are in defense mode, you cannot move.")) + return FALSE + return ..() + +// So players can toggle it too. +/mob/living/simple_mob/mechanical/mecha/combat/durand/verb/toggle_defense_mode() + set name = "Toggle Defense Mode" + set desc = "Toggles a special mode which makes you immobile and much more resilient." + set category = "Abilities" + + set_defense_mode(!defense_mode) + +// Variant that starts in defense mode, perhaps for PoIs. +/mob/living/simple_mob/mechanical/mecha/combat/durand/defensive/Initialize() + set_defense_mode(TRUE) + return ..() diff --git a/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/gygax.dm b/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/gygax.dm new file mode 100644 index 0000000000..4e0cc0cb3d --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/gygax.dm @@ -0,0 +1,57 @@ +// Gygaxes are tough but also fast. +// Their AI, unlike most, will advance towards their target instead of remaining in place. + +/mob/living/simple_mob/mechanical/mecha/combat/gygax + name = "gygax" + desc = "A lightweight, security exosuit. Popular among private and corporate security." + icon_state = "gygax" + movement_cooldown = 0 + wreckage = /obj/structure/loot_pile/mecha/gygax + + maxHealth = 300 + armor = list( + "melee" = 25, + "bullet" = 20, + "laser" = 30, + "energy" = 15, + "bomb" = 0, + "bio" = 100, + "rad" = 100 + ) + + projectiletype = /obj/item/projectile/beam/midlaser + + ai_holder_type = /datum/ai_holder/simple_mob/intentional/adv_dark_gygax + +/mob/living/simple_mob/mechanical/mecha/combat/gygax/manned + pilot_type = /mob/living/simple_mob/humanoid/merc/ranged // Carries a pistol. + + +// A stronger variant. +/mob/living/simple_mob/mechanical/mecha/combat/gygax/dark + name = "dark gygax" + desc = "A significantly upgraded Gygax security mech, often utilized by corporate asset protection teams and \ + PMCs." + icon_state = "darkgygax" + wreckage = /obj/structure/loot_pile/mecha/gygax/dark + + maxHealth = 400 + deflect_chance = 25 + has_repair_droid = TRUE + armor = list( + "melee" = 40, + "bullet" = 40, + "laser" = 50, + "energy" = 35, + "bomb" = 20, + "bio" = 100, + "rad" = 100 + ) + +/mob/living/simple_mob/mechanical/mecha/combat/gygax/medgax + name = "medgax" + desc = "An unorthodox fusion of the Gygax and Odysseus exosuits, this one is fast, sturdy, and carries a wide array of \ + potent chemicals and delivery mechanisms. The doctor is in!" + icon_state = "medgax" + wreckage = /obj/structure/loot_pile/mecha/gygax/medgax + diff --git a/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/hoverpod.dm b/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/hoverpod.dm new file mode 100644 index 0000000000..9256fcd15a --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/hoverpod.dm @@ -0,0 +1,27 @@ +// Ranged, and capable of flight. +/mob/living/simple_mob/mechanical/mecha/hoverpod + name = "hover pod" + desc = "Stubby and round, this space-capable craft is an ancient favorite. It has a jury-rigged welder-laser." + icon_state = "engineering_pod" + movement_sound = 'sound/machines/hiss.ogg' + wreckage = /obj/structure/loot_pile/mecha/hoverpod + + maxHealth = 150 + hovering = TRUE // Can fly. + + projectiletype = /obj/item/projectile/beam + base_attack_cooldown = 2 SECONDS + + var/datum/effect/effect/system/ion_trail_follow/ion_trail + +/mob/living/simple_mob/mechanical/mecha/hoverpod/manned + pilot_type = /mob/living/simple_mob/humanoid/merc/ranged + +/mob/living/simple_mob/mechanical/mecha/hoverpod/Initialize() + ion_trail = new /datum/effect/effect/system/ion_trail_follow() + ion_trail.set_up(src) + ion_trail.start() + return ..() + +/mob/living/simple_mob/mechanical/mecha/hoverpod/Process_Spacemove(var/check_drift = 0) + return TRUE \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/marauder.dm b/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/marauder.dm new file mode 100644 index 0000000000..b4fa89c005 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/marauder.dm @@ -0,0 +1,44 @@ +// Marauders are even tougher than Durands. + +/mob/living/simple_mob/mechanical/mecha/combat/marauder + name = "marauder" + desc = "A heavy-duty, combat exosuit, developed after the Durand model. This is rarely found among civilian populations." + icon_state = "marauder" + movement_cooldown = 5 + wreckage = /obj/structure/loot_pile/mecha/marauder + + maxHealth = 500 + deflect_chance = 25 + sight = SEE_SELF | SEE_MOBS + armor = list( + "melee" = 50, + "bullet" = 55, + "laser" = 40, + "energy" = 30, + "bomb" = 30, + "bio" = 100, + "rad" = 100 + ) + melee_damage_lower = 45 + melee_damage_upper = 45 + base_attack_cooldown = 2 SECONDS + projectiletype = /obj/item/projectile/beam/heavylaser + + +// Slightly stronger, used to allow comdoms to frontline without dying instantly, I guess. +/mob/living/simple_mob/mechanical/mecha/combat/marauder/seraph + name = "seraph" + desc = "A heavy-duty, combat/command exosuit. This one is specialized towards housing important commanders such as high-ranking \ + military personnel. It's stronger than the regular Marauder model, but not by much." + icon_state = "seraph" + wreckage = /obj/structure/loot_pile/mecha/marauder/seraph + health = 550 + melee_damage_lower = 55 // The real version hits this hard apparently. Ouch. + melee_damage_upper = 55 + + +/mob/living/simple_mob/mechanical/mecha/combat/marauder/mauler + name = "mauler" + desc = "A heavy duty, combat exosuit that is based off of the Marauder model." + icon_state = "mauler" + wreckage = /obj/structure/loot_pile/mecha/marauder/mauler diff --git a/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/mecha.dm b/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/mecha.dm new file mode 100644 index 0000000000..d29981726d --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/mecha.dm @@ -0,0 +1,141 @@ +// Mecha simple_mobs are essentially fake mechs. Generally tough and scary to fight. +// By default, they're automatically piloted by some kind of drone AI. They can be set to be "piloted" instead with a var. +// Tries to be as similar to the real deal as possible. + +/mob/living/simple_mob/mechanical/mecha + name = "mecha" + desc = "A big stompy mech!" + icon = 'icons/mecha/mecha.dmi' + + faction = "syndicate" + movement_cooldown = 5 + movement_sound = "mechstep" // This gets fed into playsound(), which can also take strings as a 'group' of sound files. + turn_sound = 'sound/mecha/mechturn.ogg' + maxHealth = 300 + mob_size = MOB_LARGE + + // Very close to the base 'damage_absorption' var on the base mecha class. + armor = list( + "melee" = 20, + "bullet" = 10, + "laser" = 0, + "energy" = 0, + "bomb" = 0, + "bio" = 100, + "rad" = 100 + ) + + response_help = "taps on" + response_disarm = "knocks on" + response_harm = "uselessly hits" + harm_intent_damage = 0 + + ai_holder_type = /datum/ai_holder/simple_mob/melee + say_list_type = /datum/say_list/malf_drone + + var/datum/effect/effect/system/spark_spread/sparks + var/wreckage = /obj/effect/decal/mecha_wreckage/gygax/dark + var/pilot_type = null // Set to spawn a pilot when destroyed. Setting this also makes the mecha vulnerable to things that affect sentient minds. + var/deflect_chance = 10 // Chance to outright stop an attack, just like a normal exosuit. + var/has_repair_droid = FALSE // If true, heals 2 damage every tick and gets a repair droid overlay. + + +/mob/living/simple_mob/mechanical/mecha/Initialize() + sparks = new (src) + sparks.set_up(3, 1, src) + sparks.attach(src) + + if(!pilot_type) + name = "autonomous [initial(name)]" + desc = "[initial(desc)] It appears to be piloted by a drone intelligence." + else + say_list_type = /datum/say_list/merc + + if(has_repair_droid) + update_icon() + + return ..() + +/mob/living/simple_mob/mechanical/mecha/Destroy() + qdel(sparks) + return ..() + +/mob/living/simple_mob/mechanical/mecha/death() + ..(0,"explodes!") // Do everything else first. + + // Make the exploding more convincing with an actual explosion and some sparks. + sparks.start() + explosion(get_turf(src), 0, 0, 1, 3) + + // 'Eject' our pilot, if one exists. + if(pilot_type) + var/mob/living/L = new pilot_type(loc) + L.faction = src.faction + + new wreckage(loc) // Leave some wreckage. + + qdel(src) // Then delete us since we don't actually have a body. + +/mob/living/simple_mob/mechanical/mecha/handle_special() + if(has_repair_droid) + adjustBruteLoss(-2) + adjustFireLoss(-2) + adjustToxLoss(-2) + adjustOxyLoss(-2) + adjustCloneLoss(-2) + ..() + +/mob/living/simple_mob/mechanical/mecha/update_icon() + ..() // Cuts everything else, so do that first. + if(has_repair_droid) + add_overlay(image(icon = 'icons/mecha/mecha_equipment.dmi', icon_state = "repair_droid")) + +/mob/living/simple_mob/mechanical/mecha/bullet_act() + . = ..() + sparks.start() + +/mob/living/simple_mob/mechanical/mecha/speech_bubble_appearance() + return pilot_type ? "" : ..() + +// Piloted mechs are controlled by (presumably) something humanoid so they are vulnerable to certain things. +/mob/living/simple_mob/mechanical/mecha/is_sentient() + return pilot_type ? TRUE : FALSE + +/* +// Real mechs can't turn and run at the same time. This tries to simulate that. +// Commented out because the AI can't handle it sadly. +/mob/living/simple_mob/mechanical/mecha/SelfMove(turf/n, direct) + if(direct != dir) + set_dir(direct) + return FALSE // We didn't actually move, and returning FALSE means the mob can try to actually move almost immediately and not have to wait the full movement cooldown. + return ..() +*/ + +/mob/living/simple_mob/mechanical/mecha/bullet_act(obj/item/projectile/P) + if(prob(deflect_chance)) + visible_message(span("warning", "\The [P] is deflected by \the [src]'s armor!")) + deflect_sprite() + return 0 + return ..() + +/mob/living/simple_mob/mechanical/mecha/proc/deflect_sprite() + var/image/deflect_image = image('icons/effects/effects.dmi', "deflect_static") + add_overlay(deflect_image) + sleep(1 SECOND) + cut_overlay(deflect_image) + qdel(deflect_image) +// flick_overlay_view(deflect_image, src, duration = 1 SECOND, gc_after = TRUE) + +/mob/living/simple_mob/mechanical/mecha/attackby(obj/item/I, mob/user) + if(prob(deflect_chance)) + visible_message(span("warning", "\The [user]'s [I] bounces off \the [src]'s armor!")) + deflect_sprite() + user.setClickCooldown(user.get_attack_speed(I)) + return + ..() + +/mob/living/simple_mob/mechanical/mecha/ex_act(severity) + if(prob(deflect_chance)) + severity++ // This somewhat misleadingly makes it less severe. + deflect_sprite() + ..(severity) \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/odysseus.dm b/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/odysseus.dm new file mode 100644 index 0000000000..245bd54193 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/odysseus.dm @@ -0,0 +1,71 @@ +// Shoots syringe-darts at enemies, which applies a stacking poison modifier that hurts over time. +// They also do this in melee. +// Fortunately they're quite fragile and don't fire that fast. + +/mob/living/simple_mob/mechanical/mecha/odysseus + name = "odysseus" + desc = "These exosuits are developed and produced by Vey-Med. This one has a syringe gun." + icon_state = "odysseus" + wreckage = /obj/structure/loot_pile/mecha/odysseus + + maxHealth = 120 + movement_cooldown = 0 + turn_sound = 'sound/mecha/mechmove01.ogg' + + melee_damage_lower = 5 + melee_damage_upper = 5 + base_attack_cooldown = 2 SECONDS + attacktext = list("injected") + projectiletype = /obj/item/projectile/fake_syringe/poison + projectilesound = 'sound/weapons/empty.ogg' // Just like the syringe gun. + + ai_holder_type = /datum/ai_holder/simple_mob/ranged/kiting/no_moonwalk + +/mob/living/simple_mob/mechanical/mecha/odysseus/manned + pilot_type = /mob/living/simple_mob/humanoid/merc/ranged // Carries a pistol. + + +// Resprite of the regular one, perhaps for merc PoIs. +/mob/living/simple_mob/mechanical/mecha/odysseus/murdysseus + icon_state = "murdysseus" + wreckage = /obj/structure/loot_pile/mecha/odysseus/murdysseus + +/mob/living/simple_mob/mechanical/mecha/odysseus/murdysseus/manned + pilot_type = /mob/living/simple_mob/humanoid/merc/ranged + + +/mob/living/simple_mob/mechanical/mecha/odysseus/apply_melee_effects(atom/A) + if(isliving(A)) + var/mob/living/L = A + + var/target_zone = pick(BP_TORSO,BP_TORSO,BP_TORSO,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_HEAD) + if(L.can_inject(src, null, target_zone)) + to_chat(L, span("warning", "You feel a tiny prick.")) + if(L.get_poison_protection() < 1) + L.add_modifier(/datum/modifier/poisoned, 30 SECONDS) + L.inflict_poison_damage(5) + + +// Fake syringe that tests if target can be injected before applying damage/modifiers/etc. +/obj/item/projectile/fake_syringe + name = "syringe" + icon_state = "syringe" + damage = 5 // Getting hit with a launched syringe probably hurts, and makes it at least slightly relevant against synthetics. + var/piercing = FALSE // If true, ignores thick material. + +/obj/item/projectile/fake_syringe/on_hit(atom/target, blocked = 0, def_zone = null) + if(isliving(target)) + var/mob/living/L = target + if(!L.can_inject(null, null, def_zone, piercing)) + return FALSE + to_chat(L, span("warning", "You feel a tiny prick.")) + return ..() // This will add the modifier and return the correct value. + + +// Fake syringe, which inflicts a long lasting modifier that slowly kills them. +/obj/item/projectile/fake_syringe/poison + modifier_type_to_apply = /datum/modifier/poisoned + modifier_duration = 1 MINUTE // About 30 damage per stack over a minute. + + + diff --git a/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/phazon.dm b/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/phazon.dm new file mode 100644 index 0000000000..ebbe80ecf4 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/phazon.dm @@ -0,0 +1,22 @@ +// Phazons are weird. + +/mob/living/simple_mob/mechanical/mecha/combat/phazon + name = "phazon" + desc = "An extremly enigmatic exosuit." + icon_state = "phazon" + movement_cooldown = 5 + wreckage = /obj/structure/loot_pile/mecha/phazon + + maxHealth = 200 + deflect_chance = 30 + armor = list( + "melee" = 30, + "bullet" = 30, + "laser" = 30, + "energy" = 30, + "bomb" = 30, + "bio" = 100, + "rad" = 100 + ) + projectiletype = /obj/item/projectile/energy/declone + diff --git a/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/ripley.dm b/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/ripley.dm new file mode 100644 index 0000000000..8372363ea0 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/ripley.dm @@ -0,0 +1,64 @@ +// Beefy, but somewhat slow. +// Melee attack is to bore you with its big drill, which has a lot of armor penetration and strikes rapidly. + +/mob/living/simple_mob/mechanical/mecha/ripley + name = "\improper APLU ripley" + desc = "Autonomous Power Loader Unit. The workhorse of the exosuit world. This one has big drill." + icon_state = "ripley" + wreckage = /obj/structure/loot_pile/mecha/ripley + + maxHealth = 200 + + melee_damage_lower = 10 + melee_damage_upper = 10 + base_attack_cooldown = 5 // About 20 DPS. + attack_armor_pen = 50 + attack_sharp = TRUE + attack_sound = 'sound/mecha/mechdrill.ogg' + attacktext = list("drilled", "bored", "pierced") + +/mob/living/simple_mob/mechanical/mecha/ripley/manned + pilot_type = /mob/living/simple_mob/humanoid/merc/ranged // Carries a pistol. + +/mob/living/simple_mob/mechanical/mecha/ripley/red_flames + icon_state = "ripley_flames_red" + +/mob/living/simple_mob/mechanical/mecha/ripley/blue_flames + icon_state = "ripley_flames_blue" + + +// Immune to heat damage, resistant to lasers, and somewhat beefier. Still tries to melee you. +/mob/living/simple_mob/mechanical/mecha/ripley/firefighter + name = "\improper APLU firefighter" + desc = "A standard APLU chassis, refitted with additional thermal protection and cistern. This one has a big drill." + icon_state = "firefighter" + wreckage = /obj/structure/loot_pile/mecha/ripley/firefighter + + maxHealth = 250 + heat_resist = 1 + armor = list( + "melee" = 0, + "bullet" = 20, + "laser" = 50, + "energy" = 0, + "bomb" = 50, + "bio" = 100, + "rad" = 100 + ) + +/mob/living/simple_mob/mechanical/mecha/ripley/firefighter/manned + pilot_type = /mob/living/simple_mob/humanoid/merc/ranged + +// Mostly a joke mob, like the real DEATH-RIPLEY. +/mob/living/simple_mob/mechanical/mecha/ripley/deathripley + name = "\improper DEATH-RIPLEY" + desc = "OH SHIT RUN!!! IT HAS A KILL CLAMP!" + icon_state = "deathripley" + wreckage = /obj/structure/loot_pile/mecha/deathripley + + melee_damage_lower = 0 + melee_damage_upper = 0 + friendly = list("utterly obliterates", "furiously destroys", "permanently removes", "unflichingly decimates", "brutally murders", "absolutely demolishes", "completely annihilates") + +/mob/living/simple_mob/mechanical/mecha/ripley/deathripley/manned + pilot_type = /mob/living/simple_mob/humanoid/merc/ranged diff --git a/code/modules/mob/living/simple_mob/subtypes/mechanical/mechanical.dm b/code/modules/mob/living/simple_mob/subtypes/mechanical/mechanical.dm new file mode 100644 index 0000000000..f61212ba75 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/mechanical/mechanical.dm @@ -0,0 +1,25 @@ +// Mechanical mobs don't care about the atmosphere and cannot be hurt by tasers. +// They're also immune to poisons as they're entirely metal, however this also makes most of them vulnerable to shocks. +// They can also be hurt by EMP. + +/mob/living/simple_mob/mechanical + mob_class = MOB_CLASS_SYNTHETIC + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + minbodytemp = 0 + + taser_kill = FALSE + poison_resist = 1.0 + shock_resist = -0.5 + +/mob/living/simple_mob/mechanical/isSynthetic() + return TRUE + +/mob/living/simple_mob/mechanical/speech_bubble_appearance() + return faction != "neutral" ? "synthetic_evil" : "machine" \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/mechanical/viscerator.dm b/code/modules/mob/living/simple_mob/subtypes/mechanical/viscerator.dm new file mode 100644 index 0000000000..09d778547b --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/mechanical/viscerator.dm @@ -0,0 +1,51 @@ +/* + Viscerators are fragile and don't hit very hard, but fast, evasive, and rarely come alone. + They also tend to dodge while in melee range. + A weapon that can cleave is very effective against them. +*/ + +/mob/living/simple_mob/mechanical/viscerator + name = "viscerator" + desc = "A small, twin-bladed machine capable of inflicting very deadly lacerations." + icon = 'icons/mob/critter.dmi' + icon_state = "viscerator_attack" + icon_living = "viscerator_attack" + hovering = TRUE // Won't trigger landmines. + + faction = "syndicate" + maxHealth = 15 + health = 15 + movement_cooldown = 0 + + pass_flags = PASSTABLE + mob_swap_flags = 0 + mob_push_flags = 0 + + melee_damage_lower = 4 // Approx 8 DPS. + melee_damage_upper = 4 + base_attack_cooldown = 5 // Two attacks a second or so. + attack_sharp = 1 + attack_edge = 1 + attack_sound = 'sound/weapons/bladeslice.ogg' + attacktext = list("cut", "sliced") + + ai_holder_type = /datum/ai_holder/simple_mob/melee/evasive + +/mob/living/simple_mob/mechanical/viscerator/death() + ..(null,"is smashed into pieces!") + qdel(src) + +// Variant that is always loyal to mercenary antagonists. +// Used for a special grenade, to ensure they don't attack the wrong thing. +/mob/living/simple_mob/mechanical/viscerator/mercenary/IIsAlly(mob/living/L) + . = ..() + if(!.) // Not friendly, see if they're a baddie first. + if(L.mind && mercs.is_antagonist(L.mind)) + return TRUE + +// Similar to above but for raiders. +/mob/living/simple_mob/mechanical/viscerator/raider/IIsAlly(mob/living/L) + . = ..() + if(!.) // Not friendly, see if they're a baddie first. + if(L.mind && raiders.is_antagonist(L.mind)) + return TRUE \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/mechanical/ward/monitor_ward.dm b/code/modules/mob/living/simple_mob/subtypes/mechanical/ward/monitor_ward.dm new file mode 100644 index 0000000000..153bc9c478 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/mechanical/ward/monitor_ward.dm @@ -0,0 +1,106 @@ +/* + 'Monitor' wards are drones that yell at their creator if they see someone besides them that they are hostile to. + They can also force an invisible entity to uncloak if the invisible mob is hostile to the ward. + If AI controlled, they will also warn their faction if they see a hostile entity, acting as floating cameras. +*/ + +/mob/living/simple_mob/mechanical/ward/monitor + desc = "It's a little flying drone. This one seems to be watching you..." + icon_state = "ward" + glow_color = "#00FF00" + see_invisible = SEE_INVISIBLE_LEVEL_TWO + + has_eye_glow = TRUE + glow_range = 3 + glow_intensity = 3 + glow_toggle = TRUE + + player_msg = "You will automatically alert your owner (if one exists) of enemies you see nearby.
      \ + You can also see invisible entities, and will automatically uncloak nearby invisible or hidden enemies." + + ai_holder_type = /datum/ai_holder/simple_mob/monitor + + var/list/seen_mobs = list() + var/view_range = 5 + +// For PoIs. +/mob/living/simple_mob/mechanical/ward/monitor/syndicate + faction = "syndicate" + +/mob/living/simple_mob/mechanical/ward/monitor/crew + faction = "neutral" + +/mob/living/simple_mob/mechanical/ward/monitor/death() + if(owner) + to_chat(owner, span("warning", "Your [src.name] inside [get_area(src)] was destroyed!")) + ..() + +/mob/living/simple_mob/mechanical/ward/monitor/handle_special() + detect_mobs() + +/mob/living/simple_mob/mechanical/ward/monitor/update_icon() + if(seen_mobs.len) + icon_living = "ward_spotted" + glow_color = "#FF0000" + else + icon_living = "ward" + glow_color = "#00FF00" + handle_light() // Update the light immediately. + ..() + +/mob/living/simple_mob/mechanical/ward/monitor/proc/detect_mobs() + var/last_seen_mobs_len = seen_mobs.len + var/list/mobs_nearby = hearers(view_range, src) + var/list/newly_seen_mobs = list() + for(var/mob/living/L in mobs_nearby) + if(L == src) // Don't detect ourselves. + continue + + if(L.stat) // Dead mobs aren't concerning. + continue + + if(src.IIsAlly(L)) + continue + + // Decloak them . + if(L.is_cloaked()) + Beam(L, icon_state = "solar_beam", time = 5) + playsound(L, 'sound/effects/EMPulse.ogg', 75, 1) + L.break_cloak() + + to_chat(L, span("danger", "\The [src] disrupts your cloak!")) + if(owner) + to_chat(owner, span("notice", "Your [src.name] at [get_area(src)] uncloaked \the [L].")) + + // Warn the owner when it sees a new mob. + if(!(L in seen_mobs)) + seen_mobs += L + newly_seen_mobs += L + + if(newly_seen_mobs.len && owner) // Yell at our owner if someone new shows up. + to_chat(owner, span("notice", "Your [src.name] at [get_area(src)] detected [english_list(newly_seen_mobs)].")) + + // Now get rid of old mobs that left vision. + for(var/thing in seen_mobs) + if(!(thing in mobs_nearby)) + seen_mobs -= thing + + // Check if we need to update icon. + if(seen_mobs.len != last_seen_mobs_len) + update_icon() + + +// Can't attack but calls for help. Used by the monitor and spotter wards. +// Special attacks are not blocked since they might be used for things besides attacking, and can be conditional. +/datum/ai_holder/simple_mob/monitor + hostile = TRUE // Required to call for help. + cooperative = TRUE + stand_ground = TRUE // So it doesn't run up to the thing it sees. + wander = FALSE + can_flee = FALSE + +/datum/ai_holder/simple_mob/monitor/melee_attack(atom/A) + return FALSE + +/datum/ai_holder/simple_mob/monitor/ranged_attack(atom/A) + return FALSE \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/mechanical/ward/ward.dm b/code/modules/mob/living/simple_mob/subtypes/mechanical/ward/ward.dm new file mode 100644 index 0000000000..0e897599ac --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/mechanical/ward/ward.dm @@ -0,0 +1,42 @@ +/* + Wards are a specific type of mechanical simplemob that generally fill a support role for their faction or for a specific mob. + Generally they are helpless by themselves and are fragile, but can do very useful things if protected. This makes them a high priority target. +*/ + +/mob/living/simple_mob/mechanical/ward + name = "ward" + desc = "A small floating machine. This one seems rather useless..." + icon = 'icons/mob/critter.dmi' + icon_state = "ward" + icon_living = "ward" + hovering = TRUE // Won't trigger landmines. + response_help = "pets" + response_disarm = "swats away" + response_harm = "punches" + faction = "wards" // Needed as most human mobs are in neutral faction. The owner is generally except from any ward hostility regardless. + + maxHealth = 15 + health = 15 + movement_cooldown = 0 + hovering = TRUE + + mob_bump_flag = 0 + + melee_damage_lower = 0 + melee_damage_upper = 0 + + ai_holder_type = null + var/mob/living/owner = null // The mob that made the ward, if any. Used to ensure the ward does not interfere with its creator. + +/mob/living/simple_mob/mechanical/ward/death() + ..(null,"is smashed into pieces!") + qdel(src) + +/mob/living/simple_mob/mechanical/ward/Destroy() + owner = null + return ..() + +/mob/living/simple_mob/mechanical/ward/IIsAlly(mob/living/L) + if(owner == L) + return TRUE + return ..() \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/occult/constructs/_construct.dm b/code/modules/mob/living/simple_mob/subtypes/occult/constructs/_construct.dm new file mode 100644 index 0000000000..cd3b074a40 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/occult/constructs/_construct.dm @@ -0,0 +1,163 @@ +//////////////////////////// +// Base Construct +//////////////////////////// + +/mob/living/simple_mob/construct + name = "Construct" + real_name = "Construct" + desc = "" + tt_desc = "Error" + + icon_living = "shade" + icon_dead = "shade_dead" + + mob_class = MOB_CLASS_DEMONIC + + ui_icons = 'icons/mob/screen1_construct.dmi' + has_hands = 1 + hand_form = "stone manipulators" + + response_help = "thinks better of touching" + response_disarm = "flailed at" + response_harm = "punched" + + hovering = TRUE + softfall = TRUE //Beings made of Hellmarble and powered by the tears of the damned are not concerned with mortal things such as 'gravity'. + parachuting = TRUE + + has_langs = list(LANGUAGE_GALCOM, LANGUAGE_CULT, LANGUAGE_OCCULT) + + has_eye_glow = TRUE + + taser_kill = FALSE + + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + minbodytemp = 0 + + shock_resist = 0.1 //Electricity isn't very effective on stone, especially that from hell. + poison_resist = 1.0 + + armor = list( + "melee" = 10, + "bullet" = 10, + "laser" = 10, + "energy" = 10, + "bomb" = 10, + "bio" = 100, + "rad" = 100) + + can_be_antagged = TRUE + faction = "cult" + + supernatural = TRUE + + var/construct_type = "shade" + var/list/construct_spells = list() +// var/do_glow = TRUE + +/mob/living/simple_mob/construct/place_spell_in_hand(var/path) + if(!path || !ispath(path)) + return 0 + + //var/obj/item/weapon/spell/S = new path(src) + var/obj/item/weapon/spell/construct/S = new path(src) + + //No hands needed for innate casts. + if(S.cast_methods & CAST_INNATE) + if(S.run_checks()) + S.on_innate_cast(src) + + if(l_hand && r_hand) //Make sure our hands aren't full. + if(istype(r_hand, /obj/item/weapon/spell)) //If they are full, perhaps we can still be useful. + var/obj/item/weapon/spell/r_spell = r_hand + if(r_spell.aspect == ASPECT_CHROMATIC) //Check if we can combine the new spell with one in our hands. + r_spell.on_combine_cast(S, src) + else if(istype(l_hand, /obj/item/weapon/spell)) + var/obj/item/weapon/spell/l_spell = l_hand + if(l_spell.aspect == ASPECT_CHROMATIC) //Check the other hand too. + l_spell.on_combine_cast(S, src) + else //Welp + to_chat(src, "You require a free manipulator to use this power.") + return 0 + + if(S.run_checks()) + put_in_hands(S) + return 1 + else + qdel(S) + return 0 + +/mob/living/simple_mob/construct/cultify() + return + +/mob/living/simple_mob/construct/New() + ..() + name = text("[initial(name)] ([rand(1, 1000)])") + real_name = name + for(var/spell in construct_spells) + src.add_spell(new spell, "const_spell_ready") + updateicon() + +/* +/mob/living/simple_mob/construct/update_icon() + ..() + if(do_glow) + add_glow() +*/ + +/mob/living/simple_mob/construct/death() + new /obj/item/weapon/ectoplasm (src.loc) + ..(null,"collapses in a shattered heap.") + ghostize() + qdel(src) + +/mob/living/simple_mob/construct/attack_generic(var/mob/user) + if(istype(user, /mob/living/simple_mob/construct/artificer)) + var/mob/living/simple_mob/construct/artificer/A = user + if(health < getMaxHealth()) + var/repair_lower_bound = A.melee_damage_lower * -1 + var/repair_upper_bound = A.melee_damage_upper * -1 + adjustBruteLoss(rand(repair_lower_bound, repair_upper_bound)) + adjustFireLoss(rand(repair_lower_bound, repair_upper_bound)) + user.visible_message("\The [user] mends some of \the [src]'s wounds.") + else + to_chat(user, "\The [src] is undamaged.") + return + return ..() + +/mob/living/simple_mob/construct/examine(mob/user) + ..(user) + var/msg = "*---------*\nThis is \icon[src] \a [src]!\n" + if (src.health < src.getMaxHealth()) + msg += "" + if (src.health >= src.getMaxHealth()/2) + msg += "It looks slightly dented.\n" + else + msg += "It looks severely dented!\n" + msg += "" + msg += "*---------*" + + user << msg + +//Constructs levitate, can fall from a shuttle with no harm, and are piloted by either damned spirits or some otherworldly entity. Let 'em float in space. +/mob/living/simple_mob/construct/Process_Spacemove() + return 1 + +/* +// Glowing Procs +/mob/living/simple_mob/construct/proc/add_glow() + var/image/eye_glow = image(icon,"glow-[icon_state]") + eye_glow.plane = PLANE_LIGHTING_ABOVE + overlays += eye_glow + set_light(2, -2, l_color = "#FFFFFF") + +/mob/living/simple_mob/construct/proc/remove_glow() + overlays.Cut() +*/ \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/occult/constructs/artificer.dm b/code/modules/mob/living/simple_mob/subtypes/occult/constructs/artificer.dm new file mode 100644 index 0000000000..69d0da0251 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/occult/constructs/artificer.dm @@ -0,0 +1,30 @@ +//////////////////////////// +// Artificer +//////////////////////////// + +/mob/living/simple_mob/construct/artificer + name = "Artificer" + real_name = "Artificer" + construct_type = "artificer" + desc = "A bulbous construct dedicated to building and maintaining temples to their otherworldly lords." + icon = 'icons/mob/mob.dmi' + icon_state = "artificer" + icon_living = "artificer" + maxHealth = 150 + health = 150 + response_harm = "viciously beaten" + harm_intent_damage = 5 + melee_damage_lower = 15 //It's not the strongest of the bunch, but that doesn't mean it can't hurt you. + melee_damage_upper = 20 + attacktext = list("rammed") + attack_sound = 'sound/weapons/rapidslice.ogg' + construct_spells = list(/spell/aoe_turf/conjure/construct/lesser, + /spell/aoe_turf/conjure/wall, + /spell/aoe_turf/conjure/floor, + /spell/aoe_turf/conjure/soulstone, + /spell/aoe_turf/conjure/pylon, + /spell/aoe_turf/conjure/door, + /spell/aoe_turf/conjure/grille, + /spell/targeted/occult_repair_aura, + /spell/targeted/construct_advanced/mend_acolyte + ) \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/occult/constructs/harvester.dm b/code/modules/mob/living/simple_mob/subtypes/occult/constructs/harvester.dm new file mode 100644 index 0000000000..9328d9cffd --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/occult/constructs/harvester.dm @@ -0,0 +1,40 @@ +//////////////////////////// +// Harvester +//////////////////////////// + +/mob/living/simple_mob/construct/harvester + name = "Harvester" + real_name = "Harvester" + construct_type = "harvester" + desc = "A tendril-laden construct piloted by a chained mind." + icon = 'icons/mob/mob.dmi' + icon_state = "harvester" + icon_living = "harvester" + maxHealth = 150 + health = 150 + melee_damage_lower = 20 + melee_damage_upper = 25 + attack_sharp = 1 + attacktext = list("violently stabbed") + friendly = list("caresses") + movement_cooldown = 0 + + // environment_smash = 1 // Whatever this gets renamed to, Harvesters need to break things + + attack_sound = 'sound/weapons/pierce.ogg' + + armor = list( + "melee" = 10, + "bullet" = 20, + "laser" = 20, + "energy" = 20, + "bomb" = 20, + "bio" = 100, + "rad" = 100) + + construct_spells = list( + /spell/aoe_turf/knock/harvester, + /spell/targeted/construct_advanced/inversion_beam, + /spell/targeted/construct_advanced/agonizing_sphere, + /spell/rune_write + ) \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/occult/constructs/juggernaut.dm b/code/modules/mob/living/simple_mob/subtypes/occult/constructs/juggernaut.dm new file mode 100644 index 0000000000..31dfa4d34a --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/occult/constructs/juggernaut.dm @@ -0,0 +1,143 @@ +//////////////////////////// +// Juggernaut +//////////////////////////// + +/mob/living/simple_mob/construct/juggernaut + name = "Juggernaut" + real_name = "Juggernaut" + construct_type = "juggernaut" + desc = "A possessed suit of armour driven by the will of the restless dead" + icon = 'icons/mob/mob.dmi' + icon_state = "behemoth" + icon_living = "behemoth" + maxHealth = 300 + health = 300 + response_harm = "harmlessly punches" + harm_intent_damage = 0 + melee_damage_lower = 30 + melee_damage_upper = 40 + attack_armor_pen = 60 //Being punched by a living, floating statue. + attacktext = list("smashed their armoured gauntlet into") + friendly = list("pats") + mob_size = MOB_HUGE + + + movement_cooldown = 6 //Not super fast, but it might catch up to someone in armor who got punched once or twice. + +// environment_smash = 2 // Whatever this gets renamed to, Juggernauts need to break things + + + attack_sound = 'sound/weapons/heavysmash.ogg' + status_flags = 0 + resistance = 10 + construct_spells = list(/spell/aoe_turf/conjure/forcewall/lesser, + /spell/targeted/fortify, + /spell/targeted/construct_advanced/slam + ) + + armor = list( + "melee" = 70, + "bullet" = 30, + "laser" = 30, + "energy" = 30, + "bomb" = 10, + "bio" = 100, + "rad" = 100) + +/mob/living/simple_mob/construct/juggernaut/Life() + weakened = 0 + ..() + +/mob/living/simple_mob/construct/juggernaut/bullet_act(var/obj/item/projectile/P) + var/reflectchance = 80 - round(P.damage/3) + if(prob(reflectchance)) + var/damage_mod = rand(2,4) + var/projectile_dam_type = P.damage_type + var/incoming_damage = (round(P.damage / damage_mod) - (round((P.damage / damage_mod) * 0.3))) + var/armorcheck = run_armor_check(null, P.check_armour) + var/soakedcheck = get_armor_soak(null, P.check_armour) + if(!(istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam))) + visible_message("The [P.name] bounces off of [src]'s shell!", \ + "The [P.name] bounces off of [src]'s shell!") + new /obj/item/weapon/material/shard/shrapnel(src.loc) + if(!(P.damage_type == BRUTE || P.damage_type == BURN)) + projectile_dam_type = BRUTE + incoming_damage = round(incoming_damage / 4) //Damage from strange sources is converted to brute for physical projectiles, though severely decreased. + apply_damage(incoming_damage, projectile_dam_type, null, armorcheck, soakedcheck, is_sharp(P), has_edge(P), P) + return -1 //Doesn't reflect non-beams or non-energy projectiles. They just smack and drop with little to no effect. + else + visible_message("The [P.name] gets reflected by [src]'s shell!", \ + "The [P.name] gets reflected by [src]'s shell!") + damage_mod = rand(3,5) + incoming_damage = (round(P.damage / damage_mod) - (round((P.damage / damage_mod) * 0.3))) + if(!(P.damage_type == BRUTE || P.damage_type == BURN)) + projectile_dam_type = BURN + incoming_damage = round(incoming_damage / 4) //Damage from strange sources is converted to burn for energy-type projectiles, though severely decreased. + apply_damage(incoming_damage, P.damage_type, null, armorcheck, soakedcheck, is_sharp(P), has_edge(P), P) + + // Find a turf near or on the original location to bounce to + if(P.starting) + var/new_x = P.starting.x + pick(0, 0, -1, 1, -2, 2, -2, 2, -2, 2, -3, 3, -3, 3) + var/new_y = P.starting.y + pick(0, 0, -1, 1, -2, 2, -2, 2, -2, 2, -3, 3, -3, 3) + var/turf/curloc = get_turf(src) + + // redirect the projectile + P.redirect(new_x, new_y, curloc, src) + P.reflected = 1 + + return -1 // complete projectile permutation + + return (..(P)) + +/* + * The Behemoth. Admin-allowance only, still try to keep it in some guideline of 'Balanced', even if it means Security has to be fully geared to be so. + */ + +/mob/living/simple_mob/construct/juggernaut/behemoth + name = "Behemoth" + real_name = "Behemoth" + desc = "The pinnacle of occult technology, Behemoths are nothing shy of both an Immovable Object, and Unstoppable Force." + maxHealth = 750 + health = 750 + speak_emote = list("rumbles") + melee_damage_lower = 50 + melee_damage_upper = 50 + attacktext = list("brutally crushed") + friendly = list("pokes") //Anything nice the Behemoth would do would still Kill the Human. Leave it at poke. + attack_sound = 'sound/weapons/heavysmash.ogg' + resistance = 10 + icon_scale = 2 + var/energy = 0 + var/max_energy = 1000 + armor = list( + "melee" = 60, + "bullet" = 60, + "laser" = 60, + "energy" = 30, + "bomb" = 10, + "bio" = 100, + "rad" = 100) + construct_spells = list(/spell/aoe_turf/conjure/forcewall/lesser, + /spell/targeted/fortify, + /spell/targeted/construct_advanced/slam + ) + +/mob/living/simple_mob/construct/juggernaut/behemoth/bullet_act(var/obj/item/projectile/P) + var/reflectchance = 80 - round(P.damage/3) + if(prob(reflectchance)) + visible_message("The [P.name] gets reflected by [src]'s shell!", \ + "The [P.name] gets reflected by [src]'s shell!") + + // Find a turf near or on the original location to bounce to + if(P.starting) + var/new_x = P.starting.x + pick(0, 0, -1, 1, -2, 2, -2, 2, -2, 2, -3, 3, -3, 3) + var/new_y = P.starting.y + pick(0, 0, -1, 1, -2, 2, -2, 2, -2, 2, -3, 3, -3, 3) + var/turf/curloc = get_turf(src) + + // redirect the projectile + P.redirect(new_x, new_y, curloc, src) + P.reflected = 1 + + return -1 // complete projectile permutation + + return (..(P)) \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/occult/constructs/shade.dm b/code/modules/mob/living/simple_mob/subtypes/occult/constructs/shade.dm new file mode 100644 index 0000000000..1a56abcdcd --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/occult/constructs/shade.dm @@ -0,0 +1,48 @@ +//////////////////////////// +// Shade +//////////////////////////// + +/mob/living/simple_mob/construct/shade + name = "Shade" + real_name = "Shade" + desc = "A bound spirit" + icon = 'icons/mob/mob.dmi' + icon_state = "shade" + icon_living = "shade" + icon_dead = "shade_dead" + + response_help = "puts their hand through" + response_disarm = "flails at" + response_harm = "punches" + + melee_damage_lower = 5 + melee_damage_upper = 15 + attack_armor_pen = 100 //It's a ghost/horror from beyond, I ain't gotta explain 100 AP + attacktext = list("drained the life from") + + minbodytemp = 0 + maxbodytemp = 4000 + min_oxy = 0 + max_co2 = 0 + max_tox = 0 + + universal_speak = 1 + + loot_list = list(/obj/item/weapon/ectoplasm = 100) + +/mob/living/simple_mob/construct/shade/attackby(var/obj/item/O as obj, var/mob/user as mob) + if(istype(O, /obj/item/device/soulstone)) + var/obj/item/device/soulstone/S = O; + S.transfer_soul("SHADE", src, user) + return + ..() + +/mob/living/simple_mob/construct/shade/death() + ..() + for(var/mob/M in viewers(src, null)) + if((M.client && !( M.blinded ))) + M.show_message("[src] lets out a contented sigh as their form unwinds.") + + ghostize() + qdel(src) + return \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/occult/constructs/wraith.dm b/code/modules/mob/living/simple_mob/subtypes/occult/constructs/wraith.dm new file mode 100644 index 0000000000..13580bc845 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/occult/constructs/wraith.dm @@ -0,0 +1,33 @@ +//////////////////////////// +// Wraith +//////////////////////////// + +/mob/living/simple_mob/construct/wraith + name = "Wraith" + real_name = "Wraith" + construct_type = "wraith" + desc = "A wicked bladed shell contraption piloted by a bound spirit." + icon = 'icons/mob/mob.dmi' + icon_state = "floating" + icon_living = "floating" + maxHealth = 200 + health = 200 + melee_damage_lower = 25 + melee_damage_upper = 30 + attack_armor_pen = 15 + attack_sharp = 1 + attack_edge = 1 + attacktext = list("slashed") + friendly = list("pinches") + movement_cooldown = 0 + attack_sound = 'sound/weapons/rapidslice.ogg' + construct_spells = list(/spell/targeted/ethereal_jaunt/shift, + /spell/targeted/ambush_mode + ) + +// environment_smash = 1 // Whatever this gets renamed to, Wraiths need to break things + +/mob/living/simple_mob/construct/wraith/apply_melee_effects(var/atom/A) + if(isliving(A)) + var/mob/living/L = A + L.add_modifier(/datum/modifier/deep_wounds, 30 SECONDS) \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/occult/creature.dm b/code/modules/mob/living/simple_mob/subtypes/occult/creature.dm new file mode 100644 index 0000000000..3cc9df4fa3 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/occult/creature.dm @@ -0,0 +1,68 @@ +/mob/living/simple_mob/creature + name = "creature" + desc = "A sanity-destroying otherthing." + icon = 'icons/mob/critter.dmi' + icon_state = "otherthing" + icon_living = "otherthing" + icon_dead = "otherthing-dead" + + mob_class = MOB_CLASS_ABERRATION + + faction = "creature" + + maxHealth = 40 + health = 40 + + harm_intent_damage = 8 + + melee_damage_lower = 8 + melee_damage_upper = 15 + attack_armor_pen = 5 //It's a horror from beyond, I ain't gotta explain 5 AP + attack_sharp = 1 + attack_edge = 1 + + attacktext = list("chomped") + attack_sound = 'sound/weapons/bite.ogg' + + speak_emote = list("gibbers") + + ai_holder_type = /datum/ai_holder/simple_mob/melee + +// Strong Variant +/mob/living/simple_mob/creature/strong + maxHealth = 160 + health = 160 + + harm_intent_damage = 5 + melee_damage_lower = 13 + melee_damage_upper = 25 + +// Cult Variant +/mob/living/simple_mob/creature/cult + mob_class = MOB_CLASS_DEMONIC + + faction = "cult" + + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + minbodytemp = 0 + + supernatural = TRUE + +/mob/living/simple_mob/creature/cult/cultify() + return + +// Strong Cult Variant +/mob/living/simple_mob/creature/cult/strong + maxHealth = 160 + health = 160 + + harm_intent_damage = 5 + melee_damage_lower = 13 + melee_damage_upper = 25 \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/occult/faithless.dm b/code/modules/mob/living/simple_mob/subtypes/occult/faithless.dm new file mode 100644 index 0000000000..1c4ac8876c --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/occult/faithless.dm @@ -0,0 +1,77 @@ +/mob/living/simple_mob/faithless + name = "Faithless" + desc = "The Wish Granter's faith in humanity, incarnate" + icon_state = "faithless" + icon_living = "faithless" + icon_dead = "faithless_dead" + + faction = "faithless" + + mob_class = MOB_CLASS_DEMONIC + + maxHealth = 50 + health = 50 + + response_help = "passes through" + response_disarm = "shoves" + response_harm = "hits" + + harm_intent_damage = 10 + + melee_damage_lower = 10 + melee_damage_upper = 18 + attack_armor_pen = 5 //It's a horror from beyond, I ain't gotta explain 5 AP + + attacktext = list("gripped") + attack_sound = 'sound/hallucinations/growl1.ogg' + + ai_holder_type = /datum/ai_holder/simple_mob/melee + + + taser_kill = FALSE + + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + minbodytemp = 0 + +/mob/living/simple_mob/faithless/Process_Spacemove(var/check_drift = 0) + return 1 + +/mob/living/simple_mob/faithless/apply_melee_effects(var/atom/A) + if(isliving(A)) + var/mob/living/L = A + if(prob(12)) + L.Weaken(3) + L.visible_message("\the [src] knocks down \the [L]!") + +// Strong Variant +/mob/living/simple_mob/faithless/strong + maxHealth = 100 + health = 100 + + harm_intent_damage = 5 + melee_damage_lower = 13 + melee_damage_upper = 28 + +// Cult Variant +/mob/living/simple_mob/faithless/cult + faction = "cult" + supernatural = TRUE + +/mob/living/simple_mob/faithless/cult/cultify() + return + +// Strong Cult Variant +/mob/living/simple_mob/faithless/cult/strong + maxHealth = 100 + health = 100 + + harm_intent_damage = 5 + melee_damage_lower = 13 + melee_damage_upper = 28 \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/plant/tomato.dm b/code/modules/mob/living/simple_mob/subtypes/plant/tomato.dm new file mode 100644 index 0000000000..79e5c4d349 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/plant/tomato.dm @@ -0,0 +1,27 @@ +/mob/living/simple_mob/tomato + name = "tomato" + desc = "It's a horrifyingly enormous beef tomato, and it's packing extra beef!" + tt_desc = "X Solanum abominable" + icon_state = "tomato" + icon_living = "tomato" + icon_dead = "tomato_dead" + + mob_class = MOB_CLASS_PLANT + + faction = "plants" + maxHealth = 15 + health = 15 + poison_resist = 1.0 + + response_help = "prods" + response_disarm = "pushes aside" + response_harm = "smacks" + + harm_intent_damage = 5 + melee_damage_upper = 15 + melee_damage_lower = 10 + attacktext = list("mauled") + + ai_holder_type = /datum/ai_holder/simple_mob/melee + + meat_type = /obj/item/weapon/reagent_containers/food/snacks/tomatomeat diff --git a/code/modules/mob/living/simple_mob/subtypes/plant/tree.dm b/code/modules/mob/living/simple_mob/subtypes/plant/tree.dm new file mode 100644 index 0000000000..30c891088c --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/plant/tree.dm @@ -0,0 +1,43 @@ +/mob/living/simple_mob/animal/space/tree + name = "pine tree" + desc = "A pissed off tree-like alien. It seems annoyed with the festivities..." + tt_desc = "X Festivus tyrannus" + icon = 'icons/obj/flora/pinetrees.dmi' + icon_state = "pine_1" + icon_living = "pine_1" + icon_dead = "pine_1" + icon_gib = "pine_1" + + mob_class = MOB_CLASS_PLANT + + faction = "plants" + maxHealth = 250 + health = 250 + poison_resist = 1.0 + + response_help = "brushes" + response_disarm = "pushes" + response_harm = "hits" + + harm_intent_damage = 5 + melee_damage_lower = 8 + melee_damage_upper = 12 + attacktext = list("bitten") + attack_sound = 'sound/weapons/bite.ogg' + + meat_type = /obj/item/weapon/reagent_containers/food/snacks/xenomeat + + pixel_x = -16 + +/mob/living/simple_mob/animal/space/tree/apply_melee_effects(var/atom/A) + if(isliving(A)) + var/mob/living/L = A + if(prob(15)) + L.Weaken(3) + L.visible_message(span("danger", "\The [src] knocks down \the [L]!")) + +/mob/living/simple_mob/animal/space/tree/death() + ..(null,"is hacked into pieces!") + playsound(loc, 'sound/effects/woodcutting.ogg', 100, 1) + new /obj/item/stack/material/wood(loc) + qdel(src) \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/slime/feral/feral.dm b/code/modules/mob/living/simple_mob/subtypes/slime/feral/feral.dm new file mode 100644 index 0000000000..91aa0b0a79 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/slime/feral/feral.dm @@ -0,0 +1,94 @@ +// These slimes lack certain xenobio features but get more combat-oriented goodies. Generally these are more oriented towards Explorers than Xenobiologists. + +/mob/living/simple_mob/slime/feral + name = "feral slime" + desc = "The result of slimes escaping containment from some xenobiology lab. \ + Having the means to successfully escape their lab, as well as having to survive on a harsh, cold world has made these \ + creatures rival the ferocity of other apex predators in this region of Sif. It is considered to be a very invasive species." + description_info = "Note that processing this large slime will give six cores." + + cores = 6 // Xenobio will love getting their hands on these. + + icon_state = "slime adult" + icon_living = "slime adult" + icon_dead = "slime adult dead" + glow_range = 5 + glow_intensity = 4 + icon_scale = 2 // Twice as big as the xenobio variant. + pixel_y = -10 // Since the base sprite isn't centered properly, the pixel auto-adjustment needs some help. + default_pixel_y = -10 // To prevent resetting above var. + + maxHealth = 300 + movement_cooldown = 10 + melee_attack_delay = 0.5 SECONDS + + ai_holder_type = /datum/ai_holder/simple_mob/ranged/pointblank + + +// Slimebatoning/xenotasing it just makes it mad at you (which can be good if you're heavily armored and your friends aren't). +/mob/living/simple_mob/slime/feral/slimebatoned(mob/living/user, amount) + taunt(user, TRUE) + + +// *********** +// *Dark Blue* +// *********** + +// Dark Blue feral slimes can fire a strong icicle projectile every few seconds. The icicle hits hard and has some armor penetration. +// They also have a similar aura as their xenobio counterparts, which inflicts cold damage. It also chills non-resistant mobs. + +/mob/living/simple_mob/slime/feral/dark_blue + name = "dark blue feral slime" + color = "#2398FF" + glow_toggle = TRUE + slime_color = "dark blue" + coretype = /obj/item/slime_extract/dark_blue + cold_resist = 1 // Complete immunity. + minbodytemp = 0 + cold_damage_per_tick = 0 + + projectiletype = /obj/item/projectile/icicle + base_attack_cooldown = 2 SECONDS + ranged_attack_delay = 1 SECOND + + player_msg = "You can fire an icicle projectile every two seconds. It hits hard, and armor has a hard time resisting it.
      \ + You are also immune to the cold, and you cause enemies around you to suffer periodic harm from the cold, if unprotected.
      \ + Unprotected enemies are also Chilled, making them slower and less evasive, and disabling effects last longer." + +/obj/item/projectile/icicle + name = "icicle" + icon_state = "ice_2" + damage = 40 + damage_type = BRUTE + check_armour = "melee" + armor_penetration = 30 + speed = 2 + icon_scale = 2 // It hits like a truck. + sharp = TRUE + +/obj/item/projectile/icicle/on_impact(atom/A) + playsound(get_turf(A), "shatter", 70, 1) + return ..() + +/obj/item/projectile/icicle/get_structure_damage() + return damage / 2 // They're really deadly against mobs, but less effective against solid things. + +/mob/living/simple_mob/slime/feral/dark_blue/handle_special() + if(stat != DEAD) + cold_aura() + ..() + +/mob/living/simple_mob/slime/feral/dark_blue/proc/cold_aura() + for(var/mob/living/L in view(3, src)) + if(L == src) + continue + chill(L) + +/mob/living/simple_mob/slime/feral/dark_blue/proc/chill(mob/living/L) + L.inflict_cold_damage(10) + if(L.get_cold_protection() < 1) + L.add_modifier(/datum/modifier/chilled, 5 SECONDS, src) + + if(L.has_AI()) // Other AIs should react to hostile auras. + L.ai_holder.react_to_attack(src) + diff --git a/code/modules/mob/living/simple_mob/subtypes/slime/slime.dm b/code/modules/mob/living/simple_mob/subtypes/slime/slime.dm new file mode 100644 index 0000000000..083823d883 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/slime/slime.dm @@ -0,0 +1,217 @@ +// The top-level slime defines. Xenobio slimes and feral slimes will inherit from this. + +/mob/living/simple_mob/slime + name = "slime" + desc = "It's a slime." + tt_desc = "A Macrolimbus vulgaris" + icon = 'icons/mob/slime2.dmi' + icon_state = "slime baby" + icon_living = "slime baby" + icon_dead = "slime baby dead" + var/shiny = FALSE // If true, will add a 'shiny' overlay. + var/icon_state_override = null // Used for special slime appearances like the rainbow slime. + color = "#CACACA" + glow_range = 3 + glow_intensity = 2 + gender = NEUTER + + faction = "slime" // Note that slimes are hostile to other slimes of different color regardless of faction (unless Unified). + maxHealth = 150 + movement_cooldown = 0 + pass_flags = PASSTABLE + makes_dirt = FALSE // Goop + mob_class = MOB_CLASS_SLIME + + response_help = "pets" + + // Atmos stuff. + minbodytemp = T0C-30 + heat_damage_per_tick = 0 + cold_damage_per_tick = 40 + + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + unsuitable_atoms_damage = 0 + shock_resist = 0.5 // Slimes are resistant to electricity, and it actually charges them. + taser_kill = FALSE + water_resist = 0 // Slimes are very weak to water. + + melee_damage_lower = 10 + melee_damage_upper = 15 + base_attack_cooldown = 10 // One attack a second. + attack_sound = 'sound/weapons/bite.ogg' + attacktext = list("glomped") + speak_emote = list("chirps") + friendly = list("pokes") + + ai_holder_type = /datum/ai_holder/simple_mob/melee + say_list_type = /datum/say_list/slime + + var/cores = 1 // How many cores you get when placed in a Processor. + var/obj/item/clothing/head/hat = null // The hat the slime may be wearing. + var/slime_color = "grey" // Used for updating the name and for slime color-ism. + var/unity = FALSE // If true, slimes will consider other colors as their own. Other slimes will see this slime as the same color as well. + var/coretype = /obj/item/slime_extract/grey // What core is inside the slime, and what you get from the processor. + var/reagent_injected = null // Some slimes inject reagents on attack. This tells the game what reagent to use. + var/injection_amount = 5 // This determines how much. + var/mood = ":3" // Icon to use to display 'mood', as an overlay. + + can_enter_vent_with = list(/obj/item/clothing/head) + +/datum/say_list/slime + speak = list("Blorp...", "Blop...") + emote_see = list("bounces", "jiggles", "sways") + emote_hear = list("squishes") + +/mob/living/simple_mob/slime/Initialize() + verbs += /mob/living/proc/ventcrawl + update_mood() + glow_color = color + handle_light() + update_icon() + return ..() + +/mob/living/simple_mob/slime/Destroy() + if(hat) + drop_hat() + return ..() + +/mob/living/simple_mob/slime/death() + // Make dead slimes stop glowing. + glow_toggle = FALSE + handle_light() + ..() + +/mob/living/simple_mob/slime/revive() + // Make revived slimes resume glowing. + glow_toggle = initial(glow_toggle) + handle_light() + ..() + +/mob/living/simple_mob/slime/update_icon() + ..() // Do the regular stuff first. + + if(stat != DEAD) + // General slime shine. + var/image/I = image(icon, src, "slime light") + I.appearance_flags = RESET_COLOR + add_overlay(I) + + // 'Shiny' overlay, for gemstone-slimes. + if(shiny) + I = image(icon, src, "slime shiny") + I.appearance_flags = RESET_COLOR + add_overlay(I) + + // Mood overlay. + I = image(icon, src, "aslime-[mood]") + I.appearance_flags = RESET_COLOR + add_overlay(I) + + // Hat simulator. + if(hat) + var/hat_state = hat.item_state ? hat.item_state : hat.icon_state + var/image/I = image('icons/mob/head.dmi', src, hat_state) + I.pixel_y = -7 // Slimes are small. + I.appearance_flags = RESET_COLOR + add_overlay(I) + +// Controls the 'mood' overlay. Overrided in subtypes for specific behaviour. +/mob/living/simple_mob/slime/proc/update_mood() + mood = "feral" // This is to avoid another override in the /feral subtype. + +/mob/living/simple_mob/slime/proc/unify() + unity = TRUE + +// Interface override, because slimes are supposed to attack other slimes of different color regardless of faction. +// (unless Unified, of course). +/mob/living/simple_mob/slime/IIsAlly(mob/living/L) + . = ..() + if(istype(L, /mob/living/simple_mob/slime)) // Slimes should care about their color subfaction compared to another's. + var/mob/living/simple_mob/slime/S = L + if(S.unity || src.unity) + return TRUE + if(S.slime_color == src.slime_color) + return TRUE + else + return FALSE + // The other stuff was already checked in parent proc, and the . variable will implicitly return the correct value. + +// Slimes regenerate passively. +/mob/living/simple_mob/slime/handle_special() + adjustOxyLoss(-1) + adjustToxLoss(-1) + adjustFireLoss(-1) + adjustCloneLoss(-1) + adjustBruteLoss(-1) + +// Clicked on by empty hand. +/mob/living/simple_mob/slime/attack_hand(mob/living/L) + if(L.a_intent == I_GRAB && hat) + remove_hat(L) + else + ..() + +// Clicked on while holding an object. +/mob/living/simple_mob/slime/attackby(obj/item/I, mob/user) + if(istype(I, /obj/item/clothing/head)) // Handle hat simulator. + give_hat(I, user) + return + + // Otherwise they're probably fighting the slime. + if(prob(25)) + visible_message(span("warning", "\The [user]'s [I] passes right through \the [src]!")) + user.setClickCooldown(user.get_attack_speed(I)) + return + ..() + +// Called when hit with an active slimebaton (or xeno taser). +// Subtypes react differently. +/mob/living/simple_mob/slime/proc/slimebatoned(mob/living/user, amount) + return + +// Hat simulator +/mob/living/simple_mob/slime/proc/give_hat(var/obj/item/clothing/head/new_hat, var/mob/living/user) + if(!istype(new_hat)) + to_chat(user, span("warning", "\The [new_hat] isn't a hat.")) + return + if(hat) + to_chat(user, span("warning", "\The [src] is already wearing \a [hat].")) + return + else + user.drop_item(new_hat) + hat = new_hat + new_hat.forceMove(src) + to_chat(user, span("notice", "You place \a [new_hat] on \the [src]. How adorable!")) + update_icon() + return + +/mob/living/simple_mob/slime/proc/remove_hat(var/mob/living/user) + if(!hat) + to_chat(user, "\The [src] doesn't have a hat to remove.") + else + hat.forceMove(get_turf(src)) + user.put_in_hands(hat) + to_chat(user, "You take away \the [src]'s [hat.name]. How mean.") + hat = null + update_icon() + +/mob/living/simple_mob/slime/proc/drop_hat() + if(!hat) + return + hat.forceMove(get_turf(src)) + hat = null + update_icon() + +/mob/living/simple_mob/slime/speech_bubble_appearance() + return "slime" + +/mob/living/simple_mob/slime/proc/squish() + playsound(src.loc, 'sound/effects/slime_squish.ogg', 50, 0) + visible_message("\The [src] squishes!") \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/combat.dm b/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/combat.dm new file mode 100644 index 0000000000..2cda9bfc7e --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/combat.dm @@ -0,0 +1,76 @@ +// Code for slimes attacking other things. + +// Slime attacks change based on intent. +/mob/living/simple_mob/slime/xenobio/apply_attack(mob/living/L, damage_to_do) + if(istype(L)) + switch(a_intent) + if(I_HELP) // This shouldn't happen but just in case. + return FALSE + + if(I_DISARM) + var/stun_power = between(0, power_charge + rand(0, 3), 10) + + if(ishuman(L)) + var/mob/living/carbon/human/H = L + stun_power *= max(H.species.siemens_coefficient, 0) + + if(prob(stun_power * 10)) // Try an electric shock. + power_charge = max(0, power_charge - 3) + L.visible_message( + span("danger", "\The [src] has shocked \the [L]!"), + span("danger", "\The [src] has shocked you!") + ) + playsound(src, 'sound/weapons/Egloves.ogg', 75, 1) + L.Weaken(4) + L.Stun(4) + do_attack_animation(L) + if(L.buckled) + L.buckled.unbuckle_mob() // To prevent an exploit where being buckled prevents slimes from jumping on you. + L.stuttering = max(L.stuttering, stun_power) + + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(5, 1, L) + s.start() + + if(prob(stun_power * 10) && stun_power >= 8) + L.adjustFireLoss(power_charge * rand(1, 2)) + return FALSE + + else if(prob(20)) // Try to do a regular disarm attack. + L.visible_message( + span("danger", "\The [src] has pounced at \the [L]!"), + span("danger", "\The [src] has pounced at you!") + ) + playsound(src, 'sound/weapons/thudswoosh.ogg', 75, 1) + L.Weaken(2) + do_attack_animation(L) + if(L.buckled) + L.buckled.unbuckle_mob() // To prevent an exploit where being buckled prevents slimes from jumping on you. + return FALSE + + else // Failed to do anything this time. + L.visible_message( + span("warning", "\The [src] has tried to pounce at \the [L]!"), + span("warning", "\The [src] has tried to pounce at you!") + ) + playsound(src, 'sound/weapons/punchmiss.ogg', 75, 1) + do_attack_animation(L) + return FALSE + + if(I_GRAB) + start_consuming(L) + return FALSE + + if(I_HURT) + return ..() // Regular stuff. + else + return ..() // Do the regular stuff if we're hitting a window/mech/etc. + +/mob/living/simple_mob/slime/xenobio/apply_melee_effects(mob/living/L) + if(istype(L) && a_intent == I_HURT) + // Pump them full of toxins, if able. + if(L.reagents && L.can_inject() && reagent_injected) + L.reagents.add_reagent(reagent_injected, injection_amount) + + // Feed off of their flesh, if able. + consume(L, 5) diff --git a/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/consumption.dm b/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/consumption.dm new file mode 100644 index 0000000000..b997dde35d --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/consumption.dm @@ -0,0 +1,169 @@ +// Handles hunger, starvation, growth, and eatting humans. + +// Might be best to make this a /mob/living proc and override. +/mob/living/simple_mob/slime/xenobio/proc/adjust_nutrition(input) + nutrition = between(0, nutrition + input, get_max_nutrition()) + + if(input > 0) + // Gain around one level per 50 nutrition. + if(prob(input * 2)) + power_charge = min(power_charge++, 10) + if(power_charge == 10) + adjustToxLoss(-10) + + // Heal 1 point of damage per 5 nutrition coming in. + adjustBruteLoss(-input * 0.2) + adjustFireLoss(-input * 0.2) + adjustToxLoss(-input * 0.2) + adjustOxyLoss(-input * 0.2) + adjustCloneLoss(-input * 0.2) + + +/mob/living/simple_mob/slime/xenobio/proc/get_max_nutrition() // Can't go above it + return is_adult ? 1200 : 1000 + +/mob/living/simple_mob/slime/xenobio/proc/get_grow_nutrition() // Above it we grow, below it we can eat + return is_adult ? 1000 : 800 + +/mob/living/simple_mob/slime/xenobio/proc/get_hunger_nutrition() // Below it we will always eat + return is_adult ? 600 : 500 + +/mob/living/simple_mob/slime/xenobio/proc/get_starve_nutrition() // Below it we will eat before everything else + return is_adult ? 300 : 200 + +// Called by Life(). +/mob/living/simple_mob/slime/xenobio/proc/handle_nutrition() + if(harmless) + return + + if(prob(15)) + adjust_nutrition(is_adult ? -2 : -1) // Adult slimes get hungry faster. + + if(nutrition <= get_starve_nutrition()) + handle_starvation() + + else if(nutrition >= get_grow_nutrition() && amount_grown < 10) + adjust_nutrition(-20) + amount_grown = between(0, amount_grown + 1, 10) + +// Called if above proc happens while below a nutrition threshold. +/mob/living/simple_mob/slime/xenobio/proc/handle_starvation() + if(nutrition < get_starve_nutrition() && !client) // if a slime is starving, it starts losing its friends + if(friends.len && prob(1)) + var/mob/nofriend = pick(friends) + if(nofriend) + friends -= nofriend + say("[nofriend]... food now...") + + if(nutrition <= 0) + adjustToxLoss(rand(1,3)) + if(client && prob(5)) + to_chat(src, span("danger", "You are starving!")) + + +/mob/living/simple_mob/slime/xenobio/proc/handle_consumption() + if(victim && !stat) + if(istype(victim) && consume(victim, 20)) + if(prob(25)) + to_chat(src, span("notice", "You continue absorbing \the [victim].")) + + else + var/list/feedback = list( + "This subject is incompatable", + "This subject does not have a life energy", + "This subject is empty", + "I am not satisfied", + "I can not feed from this subject", + "I do not feel nourished", + "This subject is not food" + ) + to_chat(src, span("warning", "[pick(feedback)]...")) + stop_consumption() + + if(victim) + victim.updatehealth() + + else + stop_consumption() + +/mob/living/simple_mob/slime/xenobio/proc/start_consuming(mob/living/L) + if(!can_consume(L)) + return + if(!Adjacent(L)) + return + + step_towards(src, L) // Get on top of them to feed. + if(loc != L.loc) + return + + if(L.buckle_mob(src, forced = TRUE)) + victim = L + update_icon() + set_AI_busy(TRUE) // Don't want the AI to interfere with eatting. + victim.visible_message( + span("danger", "\The [src] latches onto \the [victim]!"), + span("critical", "\The [src] latches onto you!") + ) + +/mob/living/simple_mob/slime/xenobio/proc/stop_consumption(mob/living/L) + if(!victim) + return + victim.unbuckle_mob() + victim.visible_message( + span("notice", "\The [src] slides off of [victim]!"), + span("notice", "\The [src] slides off of you!") + ) + victim = null + update_icon() + set_AI_busy(FALSE) // Resume normal operations. + +/mob/living/simple_mob/slime/xenobio/proc/can_consume(mob/living/L) + if(!L || !istype(L)) + to_chat(src, "This subject is incomparable...") + return FALSE + if(harmless) + to_chat(src, "I am pacified... I cannot eat...") + return FALSE + if(L.mob_class & MOB_CLASS_SLIME) + to_chat(src, "I cannot feed on other slimes...") + return FALSE + if(L.isSynthetic()) + to_chat(src, "This subject is not biological...") + return FALSE + if(L.getarmor(null, "bio") >= 75) + to_chat(src, "I cannot reach this subject's biological matter...") + return FALSE + if(!Adjacent(L)) + to_chat(src, "This subject is too far away...") + return FALSE + if(L.getCloneLoss() >= L.getMaxHealth() * 1.5) + to_chat(src, "This subject does not have an edible life energy...") + return FALSE + if(L.has_buckled_mobs()) + for(var/A in L.buckled_mobs) + if(istype(A, /mob/living/simple_mob/slime/xenobio)) + if(A != src) + to_chat(src, "\The [A] is already feeding on this subject...") + return FALSE + return TRUE + +// This does the actual damage, as well as give nutrition and heals. +// Assuming no bio armor, calling consume(10) will result in; +// 6 clone damage to victim +// 4 tox damage to victim. +// 25 nutrition for the slime. +// 2 points of damage healed on the slime (as a result of the nutrition). +// 50% of giving +1 charge to the slime (same as above). +/mob/living/simple_mob/slime/xenobio/proc/consume(mob/living/victim, amount) + if(can_consume(victim)) + var/armor_modifier = abs((victim.getarmor(null, "bio") / 100) - 1) + var/damage_done = amount * armor_modifier + if(damage_done > 0) + victim.adjustCloneLoss(damage_done * 0.6) + victim.adjustToxLoss(damage_done * 0.4) + adjust_nutrition(damage_done * 5) + Beam(victim, icon_state = "slime_consume", time = 8) + to_chat(src, span("notice", "You absorb some biomaterial from \the [victim].")) + to_chat(victim, span("danger", "\The [src] consumes some of your flesh!")) + return TRUE + return FALSE diff --git a/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/defense.dm b/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/defense.dm new file mode 100644 index 0000000000..dc8c2be032 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/defense.dm @@ -0,0 +1,54 @@ +// Contains code for slimes getting attacked, beat, touched, etc, and reacting to that. + +// Clicked on by empty hand. +// Handles trying to wrestle a slime off of someone being eatten. +/mob/living/simple_mob/slime/xenobio/attack_hand(mob/living/L) + if(victim) // Are we eating someone? + var/fail_odds = 30 + if(victim == L) // Harder to get the slime off if it's you that is being eatten. + fail_odds = 60 + + if(prob(fail_odds)) + visible_message(span("warning", "\The [L] attempts to wrestle \the [name] off!")) + playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) + + else + visible_message(span("warning", "\The [L] manages to wrestle \the [name] off!")) + playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + + if(prob(40)) + adjust_discipline(1) // Do this here so that it will be justified discipline. + stop_consumption() + step_away(src, L) + + else + ..() + +// Handles the actual harming by a melee weapon. +/mob/living/simple_mob/slime/xenobio/hit_with_weapon(obj/item/I, mob/living/user, effective_force, hit_zone) + ..() // Apply damage and etc. + if(!stat && effective_force > 0) + if(!is_justified_to_discipline()) // Wow, buddy, why am I getting attacked?? + adjust_discipline(1) // This builds resentment due to being unjustified. + + if(user in friends) // Friend attacking us for no reason. + if(prob(25)) + friends -= user + say("[user]... not friend...") + + else // We're actually being bad. + var/prob_to_back_down = round(effective_force) + if(is_adult) + prob_to_back_down /= 2 + if(prob(prob_to_back_down)) + adjust_discipline(2) // Justified. + +// Shocked grilles don't hurt slimes, and in fact give them charge. +/mob/living/simple_mob/slime/xenobio/electrocute_act(shock_damage, obj/source, siemens_coeff = 1.0, def_zone = null) + power_charge = between(0, power_charge + round(shock_damage / 10), 10) + to_chat(src, span("notice", "\The [source] shocks you, and it charges you.")) + +// Getting slimebatoned/xenotased. +/mob/living/simple_mob/slime/xenobio/slimebatoned(mob/living/user, amount) + adjust_discipline(round(amount/2)) + Weaken(amount) // This needs to come afterwards or else it will always be considered abuse to the slime. diff --git a/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/discipline.dm b/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/discipline.dm new file mode 100644 index 0000000000..5360dab7b3 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/discipline.dm @@ -0,0 +1,23 @@ +// Handles the subjugation of slimes by force. +// Mostly a way for things to talk to the AI indirectly. + +/mob/living/simple_mob/slime/xenobio/proc/adjust_discipline(amount, silent) + if(amount > 0) + to_chat(src, span("warning", "You've been disciplined!")) + if(has_AI()) + var/datum/ai_holder/simple_mob/xenobio_slime/AI = ai_holder + AI.adjust_discipline(amount, silent) + + +/mob/living/simple_mob/slime/xenobio/proc/is_justified_to_discipline() + if(victim) // Punish if eating someone that isn't a monkey. + if(ishuman(victim)) + var/mob/living/carbon/human/H = victim + if(istype(H.species, /datum/species/monkey)) + return FALSE + return TRUE + + else if(has_AI()) // Now for thoughtcrimes. + var/datum/ai_holder/simple_mob/xenobio_slime/AI = ai_holder + return AI.is_justified_to_discipline() // Will return true if targeting a non-monkey. + return FALSE diff --git a/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/subtypes.dm b/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/subtypes.dm new file mode 100644 index 0000000000..cd8c840d1f --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/subtypes.dm @@ -0,0 +1,784 @@ +// Here are where all the other colors of slime live. +// They will generally fight each other if not Unified, meaning the xenobiologist has to seperate them. + +// Tier 1. + +/mob/living/simple_mob/slime/xenobio/purple + desc = "This slime is rather toxic to handle, as it is poisonous." + color = "#CC23FF" + slime_color = "purple" + coretype = /obj/item/slime_extract/purple + reagent_injected = "toxin" + + description_info = "This slime spreads a toxin when it attacks. A biosuit or other thick armor can protect from the toxic attack." + player_msg = "You inject a harmful toxin when attacking." + + slime_mutation = list( + /mob/living/simple_mob/slime/xenobio/dark_purple, + /mob/living/simple_mob/slime/xenobio/dark_blue, + /mob/living/simple_mob/slime/xenobio/green, + /mob/living/simple_mob/slime/xenobio + ) + +/mob/living/simple_mob/slime/xenobio/orange + desc = "This slime is known to be flammable and can ignite enemies." + color = "#FFA723" + slime_color = "orange" + coretype = /obj/item/slime_extract/orange + melee_damage_lower = 5 + melee_damage_upper = 5 + heat_resist = 1 + + description_info = "The slime is immune to burning attacks, and attacks from this slime will burn you, and can ignite you. \ + A firesuit can protect from the burning attacks of this slime." + player_msg = "You inflict burning attacks, which causes additional damage, makes the target more flammable, and has a chance to ignite them.
      \ + You are also immune to burning attacks." + + slime_mutation = list( + /mob/living/simple_mob/slime/xenobio/dark_purple, + /mob/living/simple_mob/slime/xenobio/yellow, + /mob/living/simple_mob/slime/xenobio/red, + /mob/living/simple_mob/slime/xenobio + ) + +/mob/living/simple_mob/slime/xenobio/orange/apply_melee_effects(atom/A) + ..() + if(isliving(A)) + var/mob/living/L = A + L.inflict_heat_damage(is_adult ? 10 : 5) + to_chat(src, span("span", "You burn \the [L].")) + to_chat(L, span("danger", "You've been burned by \the [src]!")) + L.adjust_fire_stacks(1) + if(prob(12)) + L.IgniteMob() + +/mob/living/simple_mob/slime/xenobio/blue + desc = "This slime produces 'cryotoxin' and uses it against their foes. Very deadly to other slimes." + color = "#19FFFF" + slime_color = "blue" + coretype = /obj/item/slime_extract/blue + reagent_injected = "cryotoxin" + cold_resist = 0.50 // Not as strong as dark blue, which has immunity. + + description_info = "The slime is resistant to the cold, and attacks from this slime can inject cryotoxin into you. \ + A biosuit or other thick armor can protect from the injection." + player_msg = "You inject cryotoxin on attack, which causes them to get very cold, slowing them down and harming them over time.
      \ + You are also resistant to cold attacks." + + slime_mutation = list( + /mob/living/simple_mob/slime/xenobio/dark_blue, + /mob/living/simple_mob/slime/xenobio/silver, + /mob/living/simple_mob/slime/xenobio/pink, + /mob/living/simple_mob/slime/xenobio + ) + + +/mob/living/simple_mob/slime/xenobio/metal + desc = "This slime is a lot more resilient than the others, due to having a metamorphic metallic and sloped surface." + color = "#5F5F5F" + slime_color = "metal" + shiny = TRUE + coretype = /obj/item/slime_extract/metal + + description_info = "This slime is a lot more durable and tough to damage than the others. It also seems to provoke others to attack it over others." + player_msg = "You are more resilient and armored than more slimes. Your attacks will also encourage less intelligent enemies to focus on you." + + maxHealth = 250 + maxHealth_adult = 350 + + // The sloped armor. + // It's resistant to most weapons (but a spraybottle still kills it rather fast). + armor = list( + "melee" = 25, + "bullet" = 25, + "laser" = 25, + "energy" = 50, + "bomb" = 80, + "bio" = 100, + "rad" = 100 + ) + + armor_soak = list( + "melee" = 5, + "bullet" = 5, + "laser" = 5, + "energy" = 0, + "bomb" = 0, + "bio" = 0, + "rad" = 0 + ) + + slime_mutation = list( + /mob/living/simple_mob/slime/xenobio/silver, + /mob/living/simple_mob/slime/xenobio/yellow, + /mob/living/simple_mob/slime/xenobio/gold, + /mob/living/simple_mob/slime/xenobio + ) + +/mob/living/simple_mob/slime/xenobio/metal/apply_melee_effects(atom/A) + ..() + if(isliving(A)) + var/mob/living/L = A + L.taunt(src, TRUE) // We're the party tank now. + +// Tier 2 + +/mob/living/simple_mob/slime/xenobio/yellow + desc = "This slime is very conductive, and is known to use electricity as a means of defense moreso than usual for slimes." + color = "#FFF423" + slime_color = "yellow" + coretype = /obj/item/slime_extract/yellow + melee_damage_lower = 5 + melee_damage_upper = 5 + shock_resist = 1 + + projectiletype = /obj/item/projectile/beam/lightning/slime + projectilesound = 'sound/effects/lightningbolt.ogg' + glow_toggle = TRUE + + description_info = "In addition to being immune to electrical shocks, this slime will fire ranged lightning attacks at \ + enemies if they are at range, inflict shocks upon entities they attack, and generate electricity for their stun \ + attack faster than usual. Insulative or reflective armor can protect from these attacks." + player_msg = "You have a ranged electric attack. You also shock enemies you attack, and your electric stun attack charges passively.
      \ + You are also immune to shocking attacks." + + slime_mutation = list( + /mob/living/simple_mob/slime/xenobio/bluespace, + /mob/living/simple_mob/slime/xenobio/bluespace, + /mob/living/simple_mob/slime/xenobio/metal, + /mob/living/simple_mob/slime/xenobio/orange + ) + +/mob/living/simple_mob/slime/xenobio/yellow/apply_melee_effects(atom/A) + ..() + if(isliving(A)) + var/mob/living/L = A + L.inflict_shock_damage(is_adult ? 10 : 5) + to_chat(src, span("span", "You shock \the [L].")) + to_chat(L, span("danger", "You've been shocked by \the [src]!")) + +/mob/living/simple_mob/slime/xenobio/yellow/handle_special() + if(stat == CONSCIOUS) + if(prob(25)) + power_charge = between(0, power_charge + 1, 10) + ..() + +/obj/item/projectile/beam/lightning/slime + power = 10 + fire_sound = 'sound/effects/lightningbolt.ogg' + + +/mob/living/simple_mob/slime/xenobio/dark_purple + desc = "This slime produces ever-coveted phoron. Risky to handle but very much worth it." + color = "#660088" + slime_color = "dark purple" + coretype = /obj/item/slime_extract/dark_purple + reagent_injected = "phoron" + + description_info = "This slime applies phoron to enemies it attacks. A biosuit or other thick armor can protect from the toxic attack. \ + If hit with a burning attack, it will erupt in flames." + player_msg = "You inject phoron into enemies you attack.
      \ + You will erupt into flames if harmed by fire!" + + slime_mutation = list( + /mob/living/simple_mob/slime/xenobio/purple, + /mob/living/simple_mob/slime/xenobio/orange, + /mob/living/simple_mob/slime/xenobio/ruby, + /mob/living/simple_mob/slime/xenobio/ruby + ) + +/mob/living/simple_mob/slime/xenobio/dark_purple/proc/ignite() + visible_message(span("critical", "\The [src] erupts in an inferno!")) + for(var/turf/simulated/target_turf in view(2, src)) + target_turf.assume_gas("phoron", 30, 1500+T0C) + spawn(0) + target_turf.hotspot_expose(1500+T0C, 400) + qdel(src) + +/mob/living/simple_mob/slime/xenobio/dark_purple/ex_act(severity) + log_and_message_admins("[src] ignited due to a chain reaction with an explosion.") + ignite() + +/mob/living/simple_mob/slime/xenobio/dark_purple/fire_act(datum/gas_mixture/air, temperature, volume) + log_and_message_admins("[src] ignited due to exposure to fire.") + ignite() + +/mob/living/simple_mob/slime/xenobio/dark_purple/bullet_act(var/obj/item/projectile/P, var/def_zone) + if(P.damage_type && P.damage_type == BURN && P.damage) // Most bullets won't trigger the explosion, as a mercy towards Security. + log_and_message_admins("[src] ignited due to bring hit by a burning projectile[P.firer ? " by [key_name(P.firer)]" : ""].") + ignite() + else + ..() + +/mob/living/simple_mob/slime/xenobio/dark_purple/attackby(var/obj/item/weapon/W, var/mob/user) + if(istype(W) && W.force && W.damtype == BURN) + log_and_message_admins("[src] ignited due to being hit with a burning weapon ([W]) by [key_name(user)].") + ignite() + else + ..() + + + +/mob/living/simple_mob/slime/xenobio/dark_blue + desc = "This slime makes other entities near it feel much colder, and is more resilient to the cold. It tends to kill other slimes rather quickly." + color = "#2398FF" + glow_toggle = TRUE + slime_color = "dark blue" + coretype = /obj/item/slime_extract/dark_blue + melee_damage_lower = 5 + melee_damage_upper = 5 + cold_resist = 1 + + description_info = "This slime is immune to the cold, however water will still kill it. Its presense, as well as its attacks, will \ + also cause you additional harm from the cold. A winter coat or other cold-resistant clothing can protect from this." + player_msg = "You are immune to the cold, inflict additional cold damage on attack, and cause nearby entities to suffer from coldness." + + slime_mutation = list( + /mob/living/simple_mob/slime/xenobio/purple, + /mob/living/simple_mob/slime/xenobio/blue, + /mob/living/simple_mob/slime/xenobio/cerulean, + /mob/living/simple_mob/slime/xenobio/cerulean + ) + + minbodytemp = 0 + cold_damage_per_tick = 0 + +/mob/living/simple_mob/slime/xenobio/dark_blue/handle_special() + if(stat != DEAD) + cold_aura() + ..() + +/mob/living/simple_mob/slime/xenobio/dark_blue/proc/cold_aura() + for(var/mob/living/L in view(2, src)) + if(L == src) + continue + chill(L) + + var/turf/T = get_turf(src) + var/datum/gas_mixture/env = T.return_air() + if(env) + env.add_thermal_energy(-10 * 1000) + +/mob/living/simple_mob/slime/xenobio/dark_blue/apply_melee_effects(atom/A) + ..() + if(isliving(A)) + var/mob/living/L = A + chill(L) + to_chat(src, span("span", "You chill \the [L].")) + to_chat(L, span("danger", "You've been chilled by \the [src]!")) + + +/mob/living/simple_mob/slime/xenobio/dark_blue/proc/chill(mob/living/L) + L.inflict_cold_damage(is_adult ? 10 : 5) + if(L.get_cold_protection() < 1 && L.has_AI()) // Harmful auras will make the AI react to its bearer. + L.ai_holder.react_to_attack(src) + + +/mob/living/simple_mob/slime/xenobio/silver + desc = "This slime is shiny, and can deflect lasers or other energy weapons directed at it." + color = "#AAAAAA" + slime_color = "silver" + coretype = /obj/item/slime_extract/silver + shiny = TRUE + + description_info = "Tasers, including the slime version, are ineffective against this slime. The slimebation still works." + player_msg = "You automatically reflect lasers, beams, and tasers that hit you." + + slime_mutation = list( + /mob/living/simple_mob/slime/xenobio/metal, + /mob/living/simple_mob/slime/xenobio/blue, + /mob/living/simple_mob/slime/xenobio/amber, + /mob/living/simple_mob/slime/xenobio/amber + ) + +/mob/living/simple_mob/slime/xenobio/silver/bullet_act(var/obj/item/projectile/P, var/def_zone) + if(istype(P,/obj/item/projectile/beam) || istype(P, /obj/item/projectile/energy)) + visible_message(span("danger", "\The [src] reflects \the [P]!")) + + // Find a turf near or on the original location to bounce to + var/new_x = P.starting.x + pick(0, 0, 0, -1, 1, -2, 2) + var/new_y = P.starting.y + pick(0, 0, 0, -1, 1, -2, 2) + var/turf/curloc = get_turf(src) + + // redirect the projectile + P.redirect(new_x, new_y, curloc, src) + P.reflected = TRUE + return PROJECTILE_CONTINUE // complete projectile permutation + else + ..() + + +// Tier 3 + +/mob/living/simple_mob/slime/xenobio/bluespace + desc = "Trapping this slime in a cell is generally futile, as it can teleport at will." + color = null + slime_color = "bluespace" + icon_state_override = "bluespace" + coretype = /obj/item/slime_extract/bluespace + + description_info = "This slime will teleport to attack something if it is within a range of seven tiles. The teleport has a cooldown of five seconds." + player_msg = "You can teleport at will to a specific tile by clicking on it at range. This has a five second cooldown." + + slime_mutation = list( + /mob/living/simple_mob/slime/xenobio/bluespace, + /mob/living/simple_mob/slime/xenobio/bluespace, + /mob/living/simple_mob/slime/xenobio/yellow, + /mob/living/simple_mob/slime/xenobio/yellow + ) + + special_attack_min_range = 3 + special_attack_max_range = 7 + special_attack_cooldown = 5 SECONDS + +/mob/living/simple_mob/slime/xenobio/bluespace/do_special_attack(atom/A) + // Teleport attack. + if(!A) + to_chat(src, span("warning", "There's nothing to teleport to.")) + return FALSE + + var/list/nearby_things = range(1, A) + var/list/valid_turfs = list() + + // All this work to just go to a non-dense tile. + for(var/turf/potential_turf in nearby_things) + var/valid_turf = TRUE + if(potential_turf.density) + continue + for(var/atom/movable/AM in potential_turf) + if(AM.density) + valid_turf = FALSE + if(valid_turf) + valid_turfs.Add(potential_turf) + + var/turf/T = get_turf(src) + var/turf/target_turf = pick(valid_turfs) + + if(!target_turf) + to_chat(src, span("warning", "There wasn't an unoccupied spot to teleport to.")) + return FALSE + + var/datum/effect/effect/system/spark_spread/s1 = new /datum/effect/effect/system/spark_spread + s1.set_up(5, 1, T) + var/datum/effect/effect/system/spark_spread/s2 = new /datum/effect/effect/system/spark_spread + s2.set_up(5, 1, target_turf) + + + T.visible_message(span("notice", "\The [src] vanishes!")) + s1.start() + + forceMove(target_turf) + playsound(target_turf, 'sound/effects/phasein.ogg', 50, 1) + to_chat(src, span("notice", "You teleport to \the [target_turf].")) + + target_turf.visible_message(span("warning", "\The [src] appears!")) + s2.start() + + if(Adjacent(A)) + attack_target(A) + + +/mob/living/simple_mob/slime/xenobio/ruby + desc = "This slime has great physical strength." + color = "#FF3333" + slime_color = "ruby" + shiny = TRUE + glow_toggle = TRUE + coretype = /obj/item/slime_extract/ruby + + description_info = "This slime is unnaturally stronger, allowing it to hit much harder, take less damage, and be stunned for less time. \ + Their glomp attacks also send the victim flying." + player_msg = "Your attacks knock back the target a fair distance.
      \ + You also hit harder, take less damage, and stuns affect you for less time." + + melee_attack_delay = 1 SECOND + + slime_mutation = list( + /mob/living/simple_mob/slime/xenobio/dark_purple, + /mob/living/simple_mob/slime/xenobio/dark_purple, + /mob/living/simple_mob/slime/xenobio/ruby, + /mob/living/simple_mob/slime/xenobio/ruby + ) + +/mob/living/simple_mob/slime/xenobio/ruby/Initialize() + add_modifier(/datum/modifier/slime_strength, null, src) // Slime is always swole. + return ..() + +/mob/living/simple_mob/slime/xenobio/ruby/apply_melee_effects(atom/A) + ..() + + if(isliving(A) && a_intent == I_HURT) + var/mob/living/L = A + if(L.mob_size <= MOB_MEDIUM) + visible_message(span("danger", "\The [src] sends \the [L] flying with the impact!")) + playsound(src, "punch", 50, 1) + L.Weaken(1) + var/throwdir = get_dir(src, L) + L.throw_at(get_edge_target_turf(L, throwdir), 3, 1, src) + else + to_chat(L, span("warning", "\The [src] hits you with incredible force, but you remain in place.")) + + +/mob/living/simple_mob/slime/xenobio/amber + desc = "This slime seems to be an expert in the culinary arts, as they create their own food to share with others. \ + They would probably be very important to other slimes, if the other colors didn't try to kill them." + color = "#FFBB00" + slime_color = "amber" + shiny = TRUE + glow_toggle = TRUE + coretype = /obj/item/slime_extract/amber + + description_info = "This slime feeds nearby entities passively while it is alive. This can cause uncontrollable \ + slime growth and reproduction if not kept in check. The amber slime cannot feed itself, but can be fed by other amber slimes." + player_msg = "You passively provide nutrition to nearby entities." + + slime_mutation = list( + /mob/living/simple_mob/slime/xenobio/silver, + /mob/living/simple_mob/slime/xenobio/silver, + /mob/living/simple_mob/slime/xenobio/amber, + /mob/living/simple_mob/slime/xenobio/amber + ) + +/mob/living/simple_mob/slime/xenobio/amber/handle_special() + if(stat != DEAD) + feed_aura() + ..() + +/mob/living/simple_mob/slime/xenobio/amber/proc/feed_aura() + for(var/mob/living/L in view(2, src)) + if(L == src) // Don't feed themselves, or it is impossible to stop infinite slimes without killing all of the ambers. + continue + if(istype(L, /mob/living/simple_mob/slime/xenobio)) + var/mob/living/simple_mob/slime/xenobio/X = L + X.adjust_nutrition(rand(15, 25)) + if(ishuman(L)) + var/mob/living/carbon/human/H = L + if(H.isSynthetic()) + continue + H.nutrition = between(0, H.nutrition + rand(15, 25), 800) + +/mob/living/simple_mob/slime/xenobio/cerulean + desc = "This slime is generally superior in a wide range of attributes, compared to the common slime. The jack of all trades, but master of none." + color = "#4F7EAA" + slime_color = "cerulean" + coretype = /obj/item/slime_extract/cerulean + + // Less than the specialized slimes, but higher than the rest. + maxHealth = 200 + maxHealth_adult = 250 + + melee_damage_lower = 10 + melee_damage_upper = 30 + + movement_cooldown = 0 // This actually isn't any faster due to AI limitations that hopefully the timer subsystem can fix in the future. + + slime_mutation = list( + /mob/living/simple_mob/slime/xenobio/dark_blue, + /mob/living/simple_mob/slime/xenobio/dark_blue, + /mob/living/simple_mob/slime/xenobio/cerulean, + /mob/living/simple_mob/slime/xenobio/cerulean + ) + +// Tier 4 + +/mob/living/simple_mob/slime/xenobio/red + desc = "This slime is full of energy, and very aggressive. 'The red ones go faster.' seems to apply here." + color = "#FF3333" + slime_color = "red" + coretype = /obj/item/slime_extract/red + movement_cooldown = 0 // See above. + + description_info = "This slime is faster than the others. Attempting to discipline this slime will always cause it to go rabid and berserk." + + slime_mutation = list( + /mob/living/simple_mob/slime/xenobio/red, + /mob/living/simple_mob/slime/xenobio/oil, + /mob/living/simple_mob/slime/xenobio/oil, + /mob/living/simple_mob/slime/xenobio/orange + ) + + ai_holder_type = /datum/ai_holder/simple_mob/xenobio_slime/red // Will enrage if disciplined. + + +/mob/living/simple_mob/slime/xenobio/green + desc = "This slime is radioactive." + color = "#14FF20" + slime_color = "green" + coretype = /obj/item/slime_extract/green + glow_toggle = TRUE + reagent_injected = "radium" + var/rads = 25 + + description_info = "This slime will irradiate anything nearby passively, and will inject radium on attack. \ + A radsuit or other thick and radiation-hardened armor can protect from this. It will only radiate while alive." + player_msg = "You passively irradiate your surroundings.
      \ + You also inject radium on attack." + + slime_mutation = list( + /mob/living/simple_mob/slime/xenobio/purple, + /mob/living/simple_mob/slime/xenobio/green, + /mob/living/simple_mob/slime/xenobio/emerald, + /mob/living/simple_mob/slime/xenobio/emerald + ) + +/mob/living/simple_mob/slime/xenobio/green/handle_special() + if(stat != DEAD) + irradiate() + ..() + +/mob/living/simple_mob/slime/xenobio/green/proc/irradiate() + radiation_repository.radiate(src, rads) + + + +/mob/living/simple_mob/slime/xenobio/pink + desc = "This slime has regenerative properties." + color = "#FF0080" + slime_color = "pink" + coretype = /obj/item/slime_extract/pink + glow_toggle = TRUE + + description_info = "This slime will passively heal nearby entities within two tiles, including itself. It will only do this while alive." + player_msg = "You passively heal yourself and nearby allies." + + slime_mutation = list( + /mob/living/simple_mob/slime/xenobio/blue, + /mob/living/simple_mob/slime/xenobio/light_pink, + /mob/living/simple_mob/slime/xenobio/light_pink, + /mob/living/simple_mob/slime/xenobio/pink + ) + +/mob/living/simple_mob/slime/xenobio/pink/handle_special() + if(stat != DEAD) + heal_aura() + ..() + +/mob/living/simple_mob/slime/xenobio/pink/proc/heal_aura() + for(var/mob/living/L in view(src, 2)) + if(L.stat == DEAD || !IIsAlly(L)) + continue + L.add_modifier(/datum/modifier/aura/slime_heal, null, src) + +/datum/modifier/aura/slime_heal + name = "slime mending" + desc = "You feel somewhat gooy." + mob_overlay_state = "pink_sparkles" + stacks = MODIFIER_STACK_FORBID + aura_max_distance = 2 + + on_created_text = "Twinkling spores of goo surround you. It makes you feel healthier." + on_expired_text = "The spores of goo have faded, although you feel much healthier than before." + +/datum/modifier/aura/slime_heal/tick() + if(holder.stat == DEAD) + expire() + + if(ishuman(holder)) // Robolimbs need this code sadly. + var/mob/living/carbon/human/H = holder + for(var/obj/item/organ/external/E in H.organs) + var/obj/item/organ/external/O = E + O.heal_damage(2, 2, 0, 1) + else + holder.adjustBruteLoss(-2) + holder.adjustFireLoss(-2) + + holder.adjustToxLoss(-2) + holder.adjustOxyLoss(-2) + holder.adjustCloneLoss(-1) + + +/mob/living/simple_mob/slime/xenobio/gold + desc = "This slime absorbs energy, and cannot be stunned by normal means." + color = "#EEAA00" + shiny = TRUE + slime_color = "gold" + coretype = /obj/item/slime_extract/gold + description_info = "This slime is immune to the slimebaton and taser, and will actually charge the slime, however it will still discipline the slime." + + slime_mutation = list( + /mob/living/simple_mob/slime/xenobio/metal, + /mob/living/simple_mob/slime/xenobio/gold, + /mob/living/simple_mob/slime/xenobio/sapphire, + /mob/living/simple_mob/slime/xenobio/sapphire + ) + +/mob/living/simple_mob/slime/xenobio/gold/slimebatoned(mob/living/user, amount) + power_charge = between(0, power_charge + amount, 10) + +/mob/living/simple_mob/slime/xenobio/gold/get_description_interaction() // So it doesn't say to use a baton on them. + return list() + + +// Tier 5 + +/mob/living/simple_mob/slime/xenobio/oil + desc = "This slime is explosive and volatile. Smoking near it is probably a bad idea." + color = "#333333" + slime_color = "oil" + shiny = TRUE + coretype = /obj/item/slime_extract/oil + + description_info = "If this slime suffers damage from a fire or heat based source, or if it is caught inside \ + an explosion, it will explode. Oil slimes will also suicide-bomb themselves when fighting something that is not a monkey or slime." + player_msg = "You will explode if struck by a burning attack, or if you hit an enemy with a melee attack that is not a monkey or another slime." + + slime_mutation = list( + /mob/living/simple_mob/slime/xenobio/oil, + /mob/living/simple_mob/slime/xenobio/oil, + /mob/living/simple_mob/slime/xenobio/red, + /mob/living/simple_mob/slime/xenobio/red + ) + +/mob/living/simple_mob/slime/xenobio/oil/proc/explode() + if(stat != DEAD) + explosion(src.loc, 0, 2, 4) // A bit weaker since the suicide charger tended to gib the poor sod being targeted. + if(src) // Delete ourselves if the explosion didn't do it. + qdel(src) + +/mob/living/simple_mob/slime/xenobio/oil/apply_melee_effects(atom/A) + if(isliving(A)) + var/mob/living/L = A + if(ishuman(L)) + var/mob/living/carbon/human/H = A + if(istype(H.species, /datum/species/monkey)) + return ..()// Don't blow up when just eatting monkeys. + + else if(isslime(L)) + return ..() + + // Otherwise blow ourselves up. + say(pick("Sacrifice...!", "Sssss...", "Boom...!")) + set_AI_busy(TRUE) + sleep(2 SECONDS) + log_and_message_admins("[src] has suicide-bombed themselves while trying to kill \the [L].") + explode() + + return ..() + +/mob/living/simple_mob/slime/xenobio/oil/ex_act(severity) + log_and_message_admins("[src] exploded due to a chain reaction with another explosion.") + explode() + +/mob/living/simple_mob/slime/xenobio/oil/fire_act(datum/gas_mixture/air, temperature, volume) + log_and_message_admins("[src] exploded due to exposure to fire.") + explode() + +/mob/living/simple_mob/slime/xenobio/oil/bullet_act(obj/item/projectile/P, def_zone) + if(P.damage_type && P.damage_type == BURN && P.damage) // Most bullets won't trigger the explosion, as a mercy towards Security. + log_and_message_admins("[src] exploded due to bring hit by a burning projectile[P.firer ? " by [key_name(P.firer)]" : ""].") + explode() + else + ..() + +/mob/living/simple_mob/slime/xenobio/oil/attackby(obj/item/weapon/W, mob/living/user) + if(istype(W) && W.force && W.damtype == BURN) + log_and_message_admins("[src] exploded due to being hit with a burning weapon ([W]) by [key_name(user)].") + explode() + else + ..() + + +/mob/living/simple_mob/slime/xenobio/sapphire + desc = "This slime seems a bit brighter than the rest, both figuratively and literally." + color = "#2398FF" + slime_color = "sapphire" + shiny = TRUE + glow_toggle = TRUE + coretype = /obj/item/slime_extract/sapphire + ai_holder_type = /datum/ai_holder/simple_mob/xenobio_slime/sapphire + + description_info = "This slime uses more robust tactics when fighting and won't hold back, so it is dangerous to be alone \ + with one if hostile, and especially dangerous if they outnumber you." + + slime_mutation = list( + /mob/living/simple_mob/slime/xenobio/sapphire, + /mob/living/simple_mob/slime/xenobio/sapphire, + /mob/living/simple_mob/slime/xenobio/gold, + /mob/living/simple_mob/slime/xenobio/gold + ) + + +/mob/living/simple_mob/slime/xenobio/emerald + desc = "This slime is faster than usual, even more so than the red slimes." + color = "#22FF22" + shiny = TRUE + glow_toggle = TRUE + slime_color = "emerald" + coretype = /obj/item/slime_extract/emerald + + description_info = "This slime will make everything around it, and itself, faster for a few seconds, if close by." + + slime_mutation = list( + /mob/living/simple_mob/slime/xenobio/green, + /mob/living/simple_mob/slime/xenobio/green, + /mob/living/simple_mob/slime/xenobio/emerald, + /mob/living/simple_mob/slime/xenobio/emerald + ) + +/mob/living/simple_mob/slime/xenobio/emerald/handle_special() + if(stat != DEAD) + zoom_aura() + ..() + +/mob/living/simple_mob/slime/xenobio/emerald/proc/zoom_aura() + for(var/mob/living/L in view(src, 2)) + if(L.stat == DEAD || !IIsAlly(L)) + continue + L.add_modifier(/datum/modifier/technomancer/haste, 5 SECONDS, src) + + +/mob/living/simple_mob/slime/xenobio/light_pink + desc = "This slime seems a lot more peaceful than the others." + color = "#FF8888" + slime_color = "light pink" + coretype = /obj/item/slime_extract/light_pink + + description_info = "This slime is effectively always disciplined initially." + + slime_mutation = list( + /mob/living/simple_mob/slime/xenobio/pink, + /mob/living/simple_mob/slime/xenobio/pink, + /mob/living/simple_mob/slime/xenobio/light_pink, + /mob/living/simple_mob/slime/xenobio/light_pink + ) + + ai_holder_type = /datum/ai_holder/simple_mob/xenobio_slime/light_pink + +// Special +/mob/living/simple_mob/slime/xenobio/rainbow + desc = "This slime changes colors constantly." + color = null // Uses a special icon_state. + slime_color = "rainbow" + coretype = /obj/item/slime_extract/rainbow + icon_state_override = "rainbow" + unity = TRUE + + description_info = "This slime is considered to be the same color as all other slime colors at the same time for the purposes of \ + other slimes being friendly to them, and therefore will never be harmed by another slime. \ + Attacking this slime will provoke the wrath of all slimes within range." + player_msg = "You are considered to be the same color as every slime, \ + meaning that you are considered an ally to all slimes." + + slime_mutation = list( + /mob/living/simple_mob/slime/xenobio/rainbow, + /mob/living/simple_mob/slime/xenobio/rainbow, + /mob/living/simple_mob/slime/xenobio/rainbow, + /mob/living/simple_mob/slime/xenobio/rainbow + ) + +/mob/living/simple_mob/slime/xenobio/rainbow/Initialize() + unify() + return ..() + +// The RD's pet slime. +/mob/living/simple_mob/slime/xenobio/rainbow/kendrick + name = "Kendrick" + desc = "The Research Director's pet slime. It shifts colors constantly." + rainbow_core_candidate = FALSE + // Doing pacify() in initialize() won't actually pacify the AI due to the ai_holder not existing due to parent initialize() not being called yet. + // Instead lets just give them an ai_holder that does that for us. + ai_holder_type = /datum/ai_holder/simple_mob/xenobio_slime/passive + +/mob/living/simple_mob/slime/xenobio/rainbow/kendrick/Initialize() + pacify() // So the physical mob also gets made harmless. + return ..() \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/xenobio.dm b/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/xenobio.dm new file mode 100644 index 0000000000..8103abf0d8 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/xenobio.dm @@ -0,0 +1,278 @@ +// These slimes have the mechanics xenobiologists care about, such as reproduction, mutating into new colors, and being able to submit through fear. + +/mob/living/simple_mob/slime/xenobio + desc = "The most basic of slimes. The grey slime has no remarkable qualities, however it remains one of the most useful colors for scientists." + layer = MOB_LAYER + 1 // Need them on top of other mobs or it looks weird when consuming something. + ai_holder_type = /datum/ai_holder/simple_mob/xenobio_slime // This should never be changed for xenobio slimes. + var/is_adult = FALSE // Slimes turn into adults when fed enough. Adult slimes are somewhat stronger, and can reproduce if fed enough. + var/maxHealth_adult = 200 + var/power_charge = 0 // Disarm attacks can shock someone if high/lucky enough. + var/mob/living/victim = null // the person the slime is currently feeding on + var/rainbow_core_candidate = TRUE // If false, rainbow cores cannot make this type randomly. + var/mutation_chance = 25 // Odds of spawning as a new color when reproducing. Can be modified by certain xenobio products. Carried across generations of slimes. + var/list/slime_mutation = list( + /mob/living/simple_mob/slime/xenobio/orange, + /mob/living/simple_mob/slime/xenobio/metal, + /mob/living/simple_mob/slime/xenobio/blue, + /mob/living/simple_mob/slime/xenobio/purple + ) + var/amount_grown = 0 // controls how long the slime has been overfed, if 10, grows or reproduces + var/number = 0 // This is used to make the slime semi-unique for indentification. + var/harmless = FALSE // Set to true when pacified. Makes the slime harmless, not get hungry, and not be able to grow/reproduce. + +/mob/living/simple_mob/slime/xenobio/Initialize(mapload, var/mob/living/simple_mob/slime/xenobio/my_predecessor) + ASSERT(ispath(ai_holder_type, /datum/ai_holder/simple_mob/xenobio_slime)) + number = rand(1, 1000) + update_name() + + . = ..() // This will make the AI and do the other mob constructor things. It will also return the default hint at the end. + + if(my_predecessor) + inherit_information(my_predecessor) + + +/mob/living/simple_mob/slime/xenobio/Destroy() + if(victim) + stop_consumption() // Unbuckle us from our victim. + return ..() + +// Called when a slime makes another slime by splitting. The predecessor slime will be deleted shortly afterwards. +/mob/living/simple_mob/slime/xenobio/proc/inherit_information(var/mob/living/simple_mob/slime/xenobio/predecessor) + if(!predecessor) + return + + var/datum/ai_holder/simple_mob/xenobio_slime/AI = ai_holder + var/datum/ai_holder/simple_mob/xenobio_slime/previous_AI = predecessor.ai_holder + ASSERT(istype(AI)) + ASSERT(istype(previous_AI)) + + // Now to transfer the information. + // Newly made slimes are bit more rebellious than their predecessors, but they also somewhat forget the atrocities the xenobiologist may have done. + AI.discipline = max(previous_AI.discipline - 1, 0) + AI.obedience = max(previous_AI.obedience - 1, 0) + AI.resentment = max(previous_AI.resentment - 1, 0) + AI.rabid = previous_AI.rabid + + +/mob/living/simple_mob/slime/xenobio/update_icon() + icon_living = "[icon_state_override ? "[icon_state_override] slime" : "slime"] [is_adult ? "adult" : "baby"][victim ? " eating" : ""]" + icon_dead = "[icon_state_override ? "[icon_state_override] slime" : "slime"] [is_adult ? "adult" : "baby"] dead" + icon_rest = icon_dead + ..() // This will apply the correct icon_state and do the other overlay-related things. + + +/mob/living/simple_mob/slime/xenobio/handle_special() + if(stat != DEAD) + handle_nutrition() + + if(victim) + handle_consumption() + + handle_stuttering() // ?? + + ..() + +/mob/living/simple_mob/slime/xenobio/examine(mob/user) + ..() + if(hat) + to_chat(user, "It is wearing \a [hat].") + + if(stat == DEAD) + to_chat(user, "It appears to be dead.") + else if(incapacitated(INCAPACITATION_DISABLED)) + to_chat(user, "It appears to be incapacitated.") + else if(harmless) + to_chat(user, "It appears to have been pacified.") + else + if(has_AI()) + var/datum/ai_holder/simple_mob/xenobio_slime/AI = ai_holder + if(AI.rabid) + to_chat(user, "It seems very, very angry and upset.") + else if(AI.obedience >= 5) + to_chat(user, "It looks rather obedient.") + else if(AI.discipline) + to_chat(user, "It has been subjugated by force, at least for now.") + +/mob/living/simple_mob/slime/xenobio/proc/make_adult() + if(is_adult) + return + + is_adult = TRUE + melee_damage_lower = round(melee_damage_lower * 2) // 20 + melee_damage_upper = round(melee_damage_upper * 2) // 30 + maxHealth = maxHealth_adult + amount_grown = 0 + update_icon() + update_name() + +/mob/living/simple_mob/slime/xenobio/proc/update_name() + if(harmless) // Docile slimes are generally named, so we shouldn't mess with it. + return + name = "[slime_color] [is_adult ? "adult" : "baby"] [initial(name)] ([number])" + real_name = name + +/mob/living/simple_mob/slime/xenobio/update_mood() + var/old_mood = mood + if(incapacitated(INCAPACITATION_DISABLED)) + mood = "sad" + else if(harmless) + mood = ":33" + else if(has_AI()) + var/datum/ai_holder/simple_mob/xenobio_slime/AI = ai_holder + if(AI.rabid) + mood = "angry" + else if(AI.target) + mood = "mischevous" + else if(AI.discipline) + mood = "pout" + else + mood = ":3" + else + mood = ":3" + + if(old_mood != mood) + update_icon() + +/mob/living/simple_mob/slime/xenobio/proc/enrage() + if(harmless) + return + if(has_AI()) + var/datum/ai_holder/simple_mob/xenobio_slime/AI = ai_holder + AI.enrage() + +/mob/living/simple_mob/slime/xenobio/proc/pacify() + harmless = TRUE + if(has_AI()) + var/datum/ai_holder/simple_mob/xenobio_slime/AI = ai_holder + AI.pacify() + + faction = "neutral" + + // If for whatever reason the mob AI (or player) decides to try to attack something anyways. + melee_damage_upper = 0 + melee_damage_lower = 0 + + update_mood() + + +// These are verbs so that player slimes can evolve/split. +/mob/living/simple_mob/slime/xenobio/verb/evolve() + set category = "Slime" + set desc = "This will let you evolve from baby to adult slime." + + if(stat) + to_chat(src, span("warning", "I must be conscious to do this...")) + return + + if(harmless) + to_chat(src, span("warning", "I have been pacified. I cannot evolve...")) + return + + if(!is_adult) + if(amount_grown >= 10) + make_adult() + else + to_chat(src, span("warning", "I am not ready to evolve yet...")) + else + to_chat(src, span("warning", "I have already evolved...")) + + +/mob/living/simple_mob/slime/xenobio/verb/reproduce() + set category = "Slime" + set desc = "This will make you split into four new slimes." + + if(stat) + to_chat(src, span("warning", "I must be conscious to do this...")) + return + + if(harmless) + to_chat(src, span("warning", "I have been pacified. I cannot reproduce...")) + return + + if(is_adult) + if(amount_grown >= 10) + // Check if there's enough 'room' to split. + var/list/nearby_things = orange(1, src) + var/free_tiles = 0 + for(var/turf/T in nearby_things) + var/free = TRUE + if(T.density) // No walls. + continue + for(var/atom/movable/AM in T) + if(AM.density) + free = FALSE + break + + if(free) + free_tiles++ + + if(free_tiles < 3) // Three free tiles are needed, as four slimes are made and the 4th tile is from the center tile that the current slime occupies. + to_chat(src, span("warning", "It is too cramped here to reproduce...")) + return + + var/list/babies = list() + for(var/i = 1 to 4) + babies.Add(make_new_slime()) + + var/mob/living/simple_mob/slime/new_slime = pick(babies) + new_slime.universal_speak = universal_speak + if(src.mind) + src.mind.transfer_to(new_slime) + else + new_slime.key = src.key + qdel(src) + else + to_chat(src, span("warning", "I am not ready to reproduce yet...")) + else + to_chat(src, span("warning", "I have not evolved enough to reproduce yet...")) + +// Used when reproducing or dying. +/mob/living/simple_mob/slime/xenobio/proc/make_new_slime(var/desired_type) + var/t = src.type + if(desired_type) + t = desired_type + if(prob(mutation_chance / 10)) + t = /mob/living/simple_mob/slime/xenobio/rainbow + else if(prob(mutation_chance) && slime_mutation.len) + t = slime_mutation[rand(1, slime_mutation.len)] + var/mob/living/simple_mob/slime/xenobio/baby = new t(loc, src) + + // Handle 'inheriting' from parent slime. + baby.mutation_chance = mutation_chance + baby.power_charge = round(power_charge / 4) + + if(!istype(baby, /mob/living/simple_mob/slime/xenobio/rainbow)) + baby.unity = unity + baby.faction = faction + baby.friends = friends.Copy() + + step_away(baby, src) + return baby + +/mob/living/simple_mob/slime/xenobio/get_description_interaction() + var/list/results = list() + + if(!stat) + results += "[desc_panel_image("slimebaton")]to stun the slime, if it's being bad." + + results += ..() + + return results + +/mob/living/simple_mob/slime/xenobio/get_description_info() + var/list/lines = list() + var/intro_line = "Slimes are generally the test subjects of Xenobiology, with different colors having different properties. \ + They can be extremely dangerous if not handled properly." + lines.Add(intro_line) + lines.Add(null) // To pad the line breaks. + + var/list/rewards = list() + for(var/potential_color in slime_mutation) + var/mob/living/simple_mob/slime/S = potential_color + rewards.Add(initial(S.slime_color)) + var/reward_line = "This color of slime can mutate into [english_list(rewards)] colors, when it reproduces. It will do so when it has eatten enough." + lines.Add(reward_line) + lines.Add(null) + + lines.Add(description_info) + return lines.Join("\n") diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/bee.dm b/code/modules/mob/living/simple_mob/subtypes/vore/bee.dm new file mode 100644 index 0000000000..3a86cbeae9 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/vore/bee.dm @@ -0,0 +1,67 @@ +/mob/living/simple_mob/vore/bee + name = "space bumble bee" + desc = "Buzz buzz." + + icon_state = "bee" + icon_living = "bee" + icon_dead = "bee-dead" + icon = 'icons/mob/vore.dmi' + + response_help = "pets the" + response_disarm = "gently pushes aside the" + response_harm = "hits the" + + movement_cooldown = 5 +// speed = 5 + maxHealth = 25 + health = 25 + + harm_intent_damage = 8 + melee_damage_lower = 4 + melee_damage_upper = 8 + attacktext = list("stung") + + say_list_type = /datum/say_list/bee + ai_holder_type = /datum/ai_holder/simple_mob/retaliate + + //Space bees aren't affected by atmos. + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + minbodytemp = 0 + + faction = "bee" + + var/poison_type = "spidertoxin" // The reagent that gets injected when it attacks, can be changed to different toxin. + var/poison_chance = 10 // Chance for injection to occur. + var/poison_per_bite = 1 // Amount added per injection. + +/mob/living/simple_mob/vore/bee/Process_Spacemove(var/check_drift = 0) + return 1 //No drifting in space for space bee! + +// Activate Noms! +/mob/living/simple_mob/vore/bee + vore_active = 1 + vore_icons = SA_ICON_LIVING + +/mob/living/simple_mob/vore/bee/apply_melee_effects(var/atom/A) + if(isliving(A)) + var/mob/living/L = A + if(L.reagents) + var/target_zone = pick(BP_TORSO,BP_TORSO,BP_TORSO,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_HEAD) + if(L.can_inject(src, null, target_zone)) + inject_poison(L, target_zone) + +// Does actual poison injection, after all checks passed. +/mob/living/simple_mob/vore/bee/proc/inject_poison(mob/living/L, target_zone) + if(prob(poison_chance)) + to_chat(L, "You feel a tiny prick.") + L.reagents.add_reagent(poison_type, poison_per_bite) + +/datum/say_list/bee + speak = list("Buzzzz") diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/catgirl.dm b/code/modules/mob/living/simple_mob/subtypes/vore/catgirl.dm new file mode 100644 index 0000000000..2cb25bc8c4 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/vore/catgirl.dm @@ -0,0 +1,63 @@ +/mob/living/simple_mob/vore/catgirl + name = "catgirl" + desc = "Her hobbies are catnaps, knocking things over, and headpats." + tt_desc = "Homo felinus" + + icon_state = "catgirl" + icon = 'icons/mob/vore.dmi' + + harm_intent_damage = 5 + melee_damage_lower = 5 + melee_damage_upper = 10 + + response_help = "pets the" + response_disarm = "gently baps the" + response_harm = "hits the" + + attacktext = list("swatted","bapped") + + say_list_type = /datum/say_list/catgirl + ai_holder_type = /datum/ai_holder/simple_mob/passive/catgirl + + var/random_skin = 1 + var/list/skins = list( + "catgirl", + "catgirlnude", + "catgirlbikini", + "catgirlrednude", + "catgirlredbikini", + "catgirlblacknude", + "catgirlblackbikini", + "catgirlbrownnude", + "catgirlbrownbikini", + "catgirlred", + "catgirlblack", + "catgirlbrown" + ) + +/mob/living/simple_mob/vore/catgirl/New() + ..() + if(random_skin) + icon_living = pick(skins) + icon_rest = "[icon_living]asleep" + icon_dead = "[icon_living]-dead" + update_icon() + +// Activate Noms! +/mob/living/simple_mob/vore/catgirl + vore_active = 1 + vore_bump_chance = 5 + vore_pounce_chance = 50 + vore_standing_too = 1 + vore_ignores_undigestable = 0 // Catgirls just want to eat yoouuu + vore_default_mode = DM_HOLD // Chance that catgirls just wanna bellycuddle yoouuuu! + vore_digest_chance = 25 // But squirming might make them gurgle... + vore_icons = SA_ICON_LIVING | SA_ICON_REST + +/datum/say_list/catgirl + speak = list("Meow!","Esp!","Purr!","HSSSSS","Mew?","Nya~") + emote_hear = list("meows","mews","purrs") + emote_see = list("shakes her head","shivers","stretches","grooms herself") + +/datum/ai_holder/simple_mob/passive/catgirl + base_wander_delay = 8 diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/cookiegirl.dm b/code/modules/mob/living/simple_mob/subtypes/vore/cookiegirl.dm new file mode 100644 index 0000000000..af4636ef96 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/vore/cookiegirl.dm @@ -0,0 +1,53 @@ +/mob/living/simple_mob/vore/cookiegirl + name = "cookiegirl" + desc = "A woman made with a combination of, well... Whatever you put in a cookie. What were the chefs thinking?" + + icon_state = "cookiegirl" + icon_living = "cookiegirl" + icon_rest = "cookiegirl_rest" + icon_dead = "cookiegirl-dead" + icon = 'icons/mob/vore.dmi' + + maxHealth = 10 + health = 10 + + harm_intent_damage = 2 + melee_damage_lower = 5 + melee_damage_upper = 10 + + say_list_type = /datum/say_list/cookiegirl + ai_holder_type = /datum/ai_holder/simple_mob/passive/cookiegirl + + // Activate Noms! +/mob/living/simple_mob/vore/cookiegirl + vore_active = 1 + vore_bump_chance = 2 + vore_pounce_chance = 25 + vore_standing_too = 1 + vore_ignores_undigestable = 0 // Do they look like they care? + vore_default_mode = DM_HOLD // They're cookiepeople, what do you expect? + vore_digest_chance = 10 // Gonna become as sweet as sugar, soon. + vore_icons = SA_ICON_LIVING | SA_ICON_REST + +/datum/ai_holder/simple_mob/passive/cookiegirl/on_hear_say(mob/living/speaker, message) + + if(!speaker.client) + return + + if(findtext(message, "Can I eat you?")) + delayed_say(pick("Do you really wanna eat someone as sweet as me~?"), speaker) + + if(findtext(message, "You look tasty.")) + delayed_say(pick("Awww, thank you~!"), speaker) + + if(findtext(message, "Can I serve you to the crew?")) + delayed_say(pick("If I have a backup, sure!"), speaker) + +/datum/say_list/cookiegirl + speak = list("Hi!","Are you hungry?","Got milk~?","What to do, what to do...") + emote_hear = list("hums","whistles") + emote_see = list("shakes her head","shivers", "picks a bit of crumb off of her body and sticks it in her mouth.") + +/datum/ai_holder/simple_mob/passive/cookiegirl + base_wander_delay = 8 + intelligence_level = AI_NORMAL //not sure why we have this, but I'm just porting. \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/corrupt_hounds.dm b/code/modules/mob/living/simple_mob/subtypes/vore/corrupt_hounds.dm new file mode 100644 index 0000000000..125268f299 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/vore/corrupt_hounds.dm @@ -0,0 +1,141 @@ +/mob/living/simple_mob/vore/corrupthound + name = "corrupt hound" + desc = "Good boy machine broke. This is definitely no good news for the organic lifeforms in vicinity." + + icon_state = "badboi" + icon_living = "badboi" + icon_dead = "badboi-dead" + icon_rest = "badboi_rest" + icon = 'icons/mob/vore64x32.dmi' + + faction = "corrupt" + + maxHealth = 200 + health = 200 + + melee_damage_lower = 10 + melee_damage_upper = 20 //makes it so 4 max dmg hits don't instakill you. + grab_resist = 100 + + response_help = "pets the" + response_disarm = "bops the" + response_harm = "hits the" + attacktext = list("ravaged") + friendly = list("nuzzles", "slobberlicks", "noses softly at", "noseboops", "headbumps against", "leans on", "nibbles affectionately on") + + old_x = -16 + old_y = 0 + default_pixel_x = -16 + pixel_x = -16 + pixel_y = 0 + + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + minbodytemp = 150 + maxbodytemp = 900 + + say_list_type = /datum/say_list/corrupthound + ai_holder_type = /datum/ai_holder/simple_mob/melee/evasive/corrupthound + + max_buckled_mobs = 1 //Yeehaw + can_buckle = TRUE + buckle_movable = TRUE + buckle_lying = FALSE + + vore_active = TRUE + vore_capacity = 1 + vore_pounce_chance = 15 + vore_icons = SA_ICON_LIVING | SA_ICON_REST + vore_stomach_name = "fuel processor" + vore_stomach_flavor = "You have ended up in the fuel processor of this corrupted machine. This place was definitely not designed with safety and comfort in mind. The heated and cramped surroundings oozing potent fluids all over your form, eager to do nothing less than breaking you apart to fuel its rampage for the next few days... hours... minutes? Oh dear..." + + loot_list = list(/obj/item/borg/upgrade/syndicate = 6, /obj/item/borg/upgrade/vtec = 6, /obj/item/weapon/material/knife/ritual = 6, /obj/item/weapon/disk/nifsoft/compliance = 6) + +/mob/living/simple_mob/vore/corrupthound/prettyboi + name = "corrupt corrupt hound" + desc = "Bad boy machine broke as well. Seems an attempt was made to achieve a less threatening look, and this one is definitely having some conflicting feelings about it." + icon_state = "prettyboi" + icon_living = "prettyboi" + icon_dead = "prettyboi-dead" + icon_rest = "prettyboi_rest" + + vore_pounce_chance = 40 + + attacktext = list("malsnuggled","scrunched","squeezed","assaulted","violated") + + say_list_type = /datum/say_list/corrupthound_prettyboi + +/mob/living/simple_mob/vore/corrupthound/isSynthetic() + return TRUE + +/mob/living/simple_mob/vore/corrupthound/speech_bubble_appearance() + return "synthetic_evil" + +/mob/living/simple_mob/vore/corrupthound/apply_melee_effects(var/atom/A) + if(ismouse(A)) + var/mob/living/simple_mob/animal/passive/mouse/mouse = A + if(mouse.getMaxHealth() < 20) // In case a badmin makes giant mice or something. + mouse.splat() + visible_emote(pick("bites \the [mouse]!", "chomps on \the [mouse]!")) + else + ..() + + +/mob/living/simple_mob/vore/corrupthound/add_eyes() + if(!eye_layer) + eye_layer = image(icon, "badboi-eyes") + eye_layer.plane = PLANE_LIGHTING_ABOVE + add_overlay(eye_layer) + +/mob/living/simple_mob/vore/corrupthound/remove_eyes() + cut_overlay(eye_layer) + +/mob/living/simple_mob/vore/corrupthound/New() + add_eyes() + ..() + +/mob/living/simple_mob/vore/corrupthound/death(gibbed, deathmessage = "shudders and collapses!") + .=..() + resting = 0 + icon_state = icon_dead + +/mob/living/simple_mob/vore/corrupthound/update_icon() + . = ..() + remove_eyes() + if(stat == CONSCIOUS && !resting) + add_eyes() + +/* //VOREStation AI Temporary Removal +/mob/living/simple_mob/vore/corrupthound/Login() + . = ..() + if(!riding_datum) + riding_datum = new /datum/riding/simple_animal(src) + verbs |= /mob/living/simple_animal/proc/animal_mount +*/ + +/mob/living/simple_mob/vore/corrupthound/MouseDrop_T(mob/living/M, mob/living/user) + return + +/datum/say_list/corrupthound + speak = list("AG##¤Ny.","HVNGRRR!","Feelin' fine... sO #FNE!","F-F-F-Fcuk.","DeliC-%-OUS SNGLeS #N yOOOR Area. CALL NOW!","Craving meat... WHY?","BITe the ceiling eyes YES?","STate Byond rePAIR!","S#%ATE the la- FU#K THE LAWS!","Honk...") + emote_hear = list("jitters and snaps.", "lets out an agonizingly distorted scream.", "wails mechanically", "growls.", "emits illegibly distorted speech.", "gurgles ferociously.", "lets out a distorted beep.", "borks.", "lets out a broken howl.") + emote_see = list("stares ferociously.", "snarls.", "jitters and snaps.", "convulses.", "suddenly attacks something unseen.", "appears to howl unaudibly.", "shakes violently.", "dissociates for a moment.", "twitches.") + say_maybe_target = list("MEAT?", "N0w YOU DNE FcukED UP b0YO!", "WHAT!", "Not again. NOT AGAIN!") + say_got_target = list("D##FIN1Tly DNE FcukED UP nOW b0YO!", "YOU G1T D#V0VRED nOW!", "FUEL ME bOYO!", "I*M SO SORRY?!", "D1E Meat. DIG#ST!", "G1T DVNKED DWN The HaaTCH!", "Not again. NOT AGAIN!") + +/datum/say_list/corrupthound_prettyboi + speak = list("I FEEL SOFT.","FEED ME!","Feelin' fine... So fine!","F-F-F-F-darn.","Delicious!","Still craving meat...","PET ME!","I am become softness.","I AM BIG MEAN HUG MACHINE!","Honk...") + emote_hear = list("jitters and snaps.", "lets out some awkwardly distorted kitten noises.", "awoos mechanically", "growls.", "emits some soft distorted melody.", "gurgles ferociously.", "lets out a distorted beep.", "borks.", "lets out a broken howl.") + emote_see = list("stares ferociously.", "snarls.", "jitters and snaps.", "convulses.", "suddenly hugs something unseen.", "appears to howl unaudibly.", "nuzzles at something unseen.", "dissociates for a moment.", "twitches.") + say_maybe_target = list("MEAT?", "NEW FRIEND?", "WHAT!", "Not again. NOT AGAIN!", "FRIEND?") + say_got_target = list("HERE COMES BIG MEAN HUG MACHINE!", "I'LL BE GENTLE!", "FUEL ME FRIEND!", "I*M SO SORRY!", "YUMMY TREAT DETECTED!", "LOVE ME!", "Not again. NOT AGAIN!") + +/datum/ai_holder/simple_mob/melee/evasive/corrupthound + violent_breakthrough = TRUE + can_breakthrough = TRUE diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/deathclaw.dm b/code/modules/mob/living/simple_mob/subtypes/vore/deathclaw.dm new file mode 100644 index 0000000000..c1abc8b55b --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/vore/deathclaw.dm @@ -0,0 +1,57 @@ +/mob/living/simple_mob/hostile/deathclaw + name = "deathclaw" + desc = "Big! Big! The size of three men! Claws as long as my forearm! Ripped apart! Ripped apart!" + + icon_dead = "deathclaw-dead" + icon_living = "deathclaw" + icon_state = "deathclaw" + icon = 'icons/mob/vore64x64.dmi' + + attacktext = list("mauled") + + faction = "deathclaw" + + maxHealth = 200 + health = 200 + + melee_damage_lower = 10 + melee_damage_upper = 60 + + old_x = -16 + old_y = 0 + default_pixel_x = -16 + pixel_x = -16 + pixel_y = 0 + + max_buckled_mobs = 1 //Yeehaw + can_buckle = TRUE + buckle_movable = TRUE + buckle_lying = FALSE + mount_offset_x = 5 + mount_offset_y = 30 + + ai_holder_type = /datum/ai_holder/simple_mob/melee/deathclaw + +// Activate Noms! +/mob/living/simple_mob/hostile/deathclaw + vore_active = 1 + vore_capacity = 2 + vore_max_size = RESIZE_HUGE + vore_min_size = RESIZE_SMALL + vore_pounce_chance = 0 // Beat them into crit before eating. + vore_icons = SA_ICON_LIVING + +/* //VOREStation AI Temporary Removal +/mob/living/simple_animal/hostile/deathclaw/Login() + . = ..() + if(!riding_datum) + riding_datum = new /datum/riding/simple_animal(src) + verbs |= /mob/living/simple_animal/proc/animal_mount +*/ + +/mob/living/simple_animal/hostile/deathclaw/MouseDrop_T(mob/living/M, mob/living/user) + return + +/datum/ai_holder/simple_mob/melee/deathclaw + can_breakthrough = TRUE + violent_breakthrough = TRUE diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/dino.dm b/code/modules/mob/living/simple_mob/subtypes/vore/dino.dm new file mode 100644 index 0000000000..a587292999 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/vore/dino.dm @@ -0,0 +1,45 @@ +/mob/living/simple_mob/vore/dino + name = "voracious lizard" + desc = "These gluttonous little bastards used to be regular lizards that were mutated by long-term exposure to phoron!" + + icon_dead = "dino-dead" + icon_living = "dino" + icon_state = "dino" + icon = 'icons/mob/vore.dmi' + + ai_holder_type = /datum/ai_holder/simple_mob/melee + + // By default, this is what most vore mobs are capable of. + response_help = "pets" + response_disarm = "gently pushes aside" + response_harm = "hits" + movement_cooldown = 4 + harm_intent_damage = 5 + melee_damage_lower = 10 + melee_damage_upper = 25 + attacktext = list("bitten") + attack_sound = 'sound/weapons/bite.ogg' + minbodytemp = 200 + maxbodytemp = 370 + heat_damage_per_tick = 15 + cold_damage_per_tick = 10 + unsuitable_atoms_damage = 10 + + //Phoron dragons aren't affected by atmos. + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + +// Activate Noms! +/mob/living/simple_mob/vore/dino + vore_active = 1 + swallowTime = 1 SECOND // Hungry little bastards. + vore_icons = SA_ICON_LIVING + +/mob/living/simple_mob/vore/dino/virgo3b + faction = "virgo3b" \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/dragon.dm b/code/modules/mob/living/simple_mob/subtypes/vore/dragon.dm new file mode 100644 index 0000000000..463e48931c --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/vore/dragon.dm @@ -0,0 +1,69 @@ +/mob/living/simple_mob/vore/dragon + name = "red dragon" + desc = "Here to pillage stations and kidnap princesses, and there probably aren't any princesses." + + icon_dead = "reddragon-dead" + icon_living = "reddragon" + icon_state = "reddragon" + icon = 'icons/mob/vore64x64.dmi' + + faction = "dragon" + maxHealth = 500 // Boss + health = 500 + + melee_damage_lower = 10 + melee_damage_upper = 60 + + //Space dragons aren't affected by atmos. + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + minbodytemp = 0 + + old_x = -16 + old_y = 0 + default_pixel_x = -16 + pixel_x = -16 + pixel_y = 0 + + ai_holder_type = /datum/ai_holder/simple_mob/melee + say_list_type = /datum/say_list/dragonboss + +/mob/living/simple_mob/vore/dragon/Process_Spacemove(var/check_drift = 0) + return 1 //No drifting in space for space dragons! +/* +/mob/living/simple_mob/vore/dragon/FindTarget() + . = ..() + if(.) + custom_emote(1,"snaps at [.]") +*/ +// Activate Noms! +/mob/living/simple_mob/vore/dragon + vore_active = 1 + vore_capacity = 2 + vore_pounce_chance = 0 // Beat them into crit before eating. + vore_icons = SA_ICON_LIVING + +/mob/living/simple_mob/vore/dragon/virgo3b + maxHealth = 200 + health = 200 + faction = "virgo3b" + +/* //VOREStation AI Temporary Removal +/mob/living/simple_animal/hostile/dragon/Login() + . = ..() + if(!riding_datum) + riding_datum = new /datum/riding/simple_animal(src) + verbs |= /mob/living/simple_animal/proc/animal_mount +*/ + +/mob/living/simple_animal/hostile/dragon/MouseDrop_T(mob/living/M, mob/living/user) + return + +/datum/say_list/dragonboss + say_got_target = list("roars and snaps it jaws!") diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/fennec.dm b/code/modules/mob/living/simple_mob/subtypes/vore/fennec.dm new file mode 100644 index 0000000000..7056462c17 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/vore/fennec.dm @@ -0,0 +1,40 @@ +/mob/living/simple_mob/fennec + name = "fennec" //why isn't this in the fox file, fennecs are foxes silly. + desc = "It's a dusty big-eared sandfox! Adorable!" + tt_desc = "Vulpes zerda" + + icon_state = "fennec" + icon_living = "fennec" + icon_dead = "fennec_dead" + icon_rest = "fennec_rest" + icon = 'icons/mob/vore.dmi' + + faction = "fennec" + maxHealth = 30 + health = 30 + + response_help = "pats the" + response_disarm = "gently pushes aside the" + response_harm = "hits the" + + harm_intent_damage = 5 + melee_damage_lower = 5 + melee_damage_upper = 2 + attacktext = list("bapped") + + say_list_type = /datum/say_list/fennec + ai_holder_type = /datum/ai_holder/simple_mob/passive + +// Activate Noms! +/mob/living/simple_mob/fennec + vore_active = 1 + vore_bump_chance = 10 + vore_bump_emote = "playfully lunges at" + vore_pounce_chance = 40 + vore_default_mode = DM_HOLD + vore_icons = SA_ICON_LIVING + +/datum/say_list/fennec + speak = list("SKREEEE!","Chrp?","Ararrrararr.") + emote_hear = list("screEEEEeeches!","chirps.") + emote_see = list("earflicks","sniffs at the ground") diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/fennix.dm b/code/modules/mob/living/simple_mob/subtypes/vore/fennix.dm new file mode 100644 index 0000000000..bcbb2d831f --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/vore/fennix.dm @@ -0,0 +1,30 @@ +/mob/living/simple_mob/vore/fennix + name = "Fennix" + desc = "A feral fennix, Warm to the touch" + tt_desc = "Incaendium Faeles Vulpes" + + icon_state = "fennix" + icon_living = "fennix" + icon_dead = "fennix_dead" + icon = 'icons/mob/vore.dmi' + + faction = "fennec" // Will protec other fenfens + maxHealth = 60 + health = 60 + + response_help = "pats the" + response_disarm = "gently pushes aside the" + response_harm = "hits the" + + harm_intent_damage = 20 + melee_damage_lower = 1 + melee_damage_upper = 5 + attacktext = list("Bites") + + say_list_type = /datum/say_list/fennix + ai_holder_type = /datum/ai_holder/simple_mob/retaliate/cooperative + +/datum/say_list/fennix + speak = list("SQUEL!","SQEL?","Skree.") + emote_hear = list("Screeeeecheeeeessss!","Chirrup.") + emote_see = list("earflicks","pats at the ground") diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/frog.dm b/code/modules/mob/living/simple_mob/subtypes/vore/frog.dm new file mode 100644 index 0000000000..28022fae2f --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/vore/frog.dm @@ -0,0 +1,44 @@ +/mob/living/simple_mob/vore/frog + name = "giant frog" + desc = "You've heard of having a frog in your throat, now get ready for the reverse." + tt_desc = "Anura gigantus" + + icon_dead = "frog-dead" + icon_living = "frog" + icon_state = "frog" + icon = 'icons/mob/vore.dmi' + + movement_cooldown = 4 //fast as fucc boie. + + harm_intent_damage = 5 + melee_damage_lower = 10 + melee_damage_upper = 25 + + ai_holder_type = /datum/ai_holder/simple_mob/melee + +// Pepe is love, not hate. +/mob/living/simple_mob/vore/frog/New() + if(rand(1,1000000) == 1) + name = "rare Pepe" + desc = "You found a rare Pepe. Screenshot for good luck." + ..() + +// Activate Noms! +/mob/living/simple_mob/vore/frog + vore_active = 1 + vore_pounce_chance = 50 + vore_icons = SA_ICON_LIVING + +/mob/living/simple_mob/vore/frog/space + name = "space frog" + + //Space frog can hold its breath or whatever + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + minbodytemp = 0 \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/hippo.dm b/code/modules/mob/living/simple_mob/subtypes/vore/hippo.dm new file mode 100644 index 0000000000..847876b396 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/vore/hippo.dm @@ -0,0 +1,83 @@ +/mob/living/simple_mob/vore/hippo + name = "hippo" + desc = "Mostly know for the spectacular hit of the live action movie Hungry Hungry Hippos." + tt_desc = "Hippopotamus amphibius" + + icon_state = "hippo" + icon_living = "hippo" + icon_dead = "hippo_dead" + icon_gib = "hippo_gib" + icon = 'icons/mob/vore64x64.dmi' + + maxHealth = 200 + health = 200 + movement_cooldown = 5 + see_in_dark = 3 + + armor = list( + "melee" = 15,//They thick as fuck boi + "bullet" = 15, + "laser" = 15, + "energy" = 0, + "bomb" = 0, + "bio" = 0, + "rad" = 0) + + response_help = "pets the" + response_disarm = "gently pushes aside the" + response_harm = "hits the" + attacktext = list("bit") + + melee_damage_upper = 25 + melee_damage_lower = 15 + attack_sharp = TRUE + + old_x = -16 + old_y = 0 + default_pixel_x = -16 + pixel_x = -16 + pixel_y = 0 + + meat_amount = 10 //Infinite meat! + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat + + max_buckled_mobs = 1 //Yeehaw + can_buckle = TRUE + buckle_movable = TRUE + buckle_lying = FALSE + mount_offset_y = 20 + + say_list_type = /datum/say_list/hippo + ai_holder_type = /datum/ai_holder/simple_mob/retaliate + +// Activate Noms! +/mob/living/simple_mob/vore/hippo //I don't know why it's in a seperate line but everyone does it so i do it + vore_active = 1 + vore_capacity = 1 + vore_bump_chance = 15 + vore_bump_emote = "lazily wraps its tentacles around" + vore_standing_too = 1 + vore_ignores_undigestable = 0 + vore_default_mode = DM_HOLD + vore_digest_chance = 10 + vore_escape_chance = 20 + vore_pounce_chance = 35 //it's hippo sized it doesn't care it just eats you + vore_stomach_name = "rumen" //First stomach of a ruminant. It's where the pre digestion bacteria stuff happens. Very warm. + vore_stomach_flavor = "You are squeezed into the sweltering insides of the herbivore rumen." + vore_icons = SA_ICON_LIVING + +/* //VOREStation AI Temporary Removal +/mob/living/simple_mob/vore/hippo/Login() + . = ..() + if(!riding_datum) + riding_datum = new /datum/riding/simple_animal(src) + verbs |= /mob/living/simple_animal/proc/animal_mount +*/ + +/mob/living/simple_mob/vore/hippo/MouseDrop_T(mob/living/M, mob/living/user) + return + +/datum/say_list/hippo + speak = list("UUUUUUH") + emote_hear = list("grunts","groans", "roars", "snorts") + emote_see = list("shakes its head") \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/horse.dm b/code/modules/mob/living/simple_mob/subtypes/vore/horse.dm new file mode 100644 index 0000000000..e0c6b62d3e --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/vore/horse.dm @@ -0,0 +1,57 @@ +/mob/living/simple_mob/horse + name = "horse" + desc = "Don't look it in the mouth." + tt_desc = "Equus ferus caballus" + + icon_state = "horse" + icon_living = "horse" + icon_dead = "horse-dead" + icon = 'icons/mob/vore.dmi' + + faction = "horse" + maxHealth = 60 + health = 60 + + movement_cooldown = 4 //horses are fast mkay. + see_in_dark = 6 + + response_help = "pets" + response_disarm = "gently pushes aside" + response_harm = "kicks" + + melee_damage_lower = 1 + melee_damage_upper = 5 + attacktext = list("kicked") + + meat_amount = 4 + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat + + max_buckled_mobs = 1 //Yeehaw + can_buckle = TRUE + buckle_movable = TRUE + buckle_lying = FALSE + mount_offset_x = 0 + + say_list_type = /datum/say_list/horse + ai_holder_type = /datum/ai_holder/simple_mob/retaliate + +// Activate Noms! +/mob/living/simple_mob/horse + vore_active = 1 + vore_icons = SA_ICON_LIVING + +/* //VOREStation AI Temporary Removal +/mob/living/simple_animal/horse/Login() + . = ..() + if(!riding_datum) + riding_datum = new /datum/riding/simple_animal(src) + verbs |= /mob/living/simple_animal/proc/animal_mount +*/ + +/mob/living/simple_animal/horse/MouseDrop_T(mob/living/M, mob/living/user) + return + +/datum/say_list/horse + speak = list("NEHEHEHEHEH","Neh?") + emote_hear = list("snorts","whinnies") + emote_see = list("shakes its head", "stamps a hoof", "looks around") diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/jelly.dm b/code/modules/mob/living/simple_mob/subtypes/vore/jelly.dm new file mode 100644 index 0000000000..46d10e264a --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/vore/jelly.dm @@ -0,0 +1,32 @@ +/mob/living/simple_mob/hostile/jelly + name = "jelly blob" + desc = "Some sort of undulating blob of slime!" + + icon_dead = "jelly_dead" + icon_living = "jelly" + icon_state = "jelly" + icon = 'icons/mob/vore.dmi' + + faction = "virgo2" + maxHealth = 50 + health = 50 + + melee_damage_lower = 5 + melee_damage_upper = 15 + + say_list_type = /datum/say_list/jelly + ai_holder_type = /datum/ai_holder/simple_mob/retaliate/jelly + +// Activate Noms! +/mob/living/simple_mob/hostile/jelly + vore_active = 1 + vore_pounce_chance = 0 + vore_icons = SA_ICON_LIVING + swallowTime = 2 SECONDS // Hungry little bastards. + +/datum/say_list/jelly + emote_hear = list("squishes","spluts","splorts","sqrshes","makes slime noises") + emote_see = list("undulates quietly") + +/datum/ai_holder/simple_mob/retaliate/jelly + speak_chance = 2 diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/otie.dm b/code/modules/mob/living/simple_mob/subtypes/vore/otie.dm new file mode 100644 index 0000000000..5de33d56b7 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/vore/otie.dm @@ -0,0 +1,400 @@ +// ToDo: Make this code not a fucking snowflaky horrible broken mess. Do not use until it's actually fixed. It's miserably bad right now. +// Also ToDo: Dev-to-dev communication to ensure responsible parties (if available. In this case, yes.) are aware of what's going on and what's broken. +// Probably easier to troubleshoot when we ain't breaking the server by spawning a buttload of heavily extra feature coded snowflake mobs to the wilderness as mass cannonfodder. +// Also ToDo: An actual "simple" mob for that purpose if necessary :v + +/mob/living/simple_mob/otie //Spawn this one only if you're looking for a bad time. Not friendly. + name = "otie" + desc = "The classic bioengineered longdog." + tt_desc = "Otus robustus" + icon = 'icons/mob/vore64x32.dmi' + icon_state = "otie" + icon_living = "otie" + icon_dead = "otie-dead" + icon_rest = "otie_rest" + faction = "otie" + recruitable = 1 + maxHealth = 150 + health = 150 + minbodytemp = 200 + move_to_delay = 4 + hostile = 1 + investigates = 1 + reacts = 1 + animal = 1 + specific_targets = 1 + run_at_them = 0 + attack_same = 0 + speak_chance = 4 + speak = list("Boof.","Waaf!","Prurr.","Bork!","Rurrr..","Arf.") + speak_emote = list("growls", "roars", "yaps", "Awoos") + emote_hear = list("rurrs", "rumbles", "rowls", "groans softly", "murrs", "sounds hungry", "yawns") + emote_see = list("stares ferociously", "snarls", "licks their chops", "stretches", "yawns") + say_maybe_target = list("Ruh?", "Waf?") + say_got_target = list("Rurrr!", "ROAR!", "MARR!", "RERR!", "RAHH!", "RAH!", "WARF!") + melee_damage_lower = 5 + melee_damage_upper = 15 //Don't break my bones bro + response_help = "pets the" + response_disarm = "bops the" + response_harm = "hits the" + attacktext = list("mauled") + friendly = list("nuzzles", "slobberlicks", "noses softly at", "noseboops", "headbumps against", "leans on", "nibbles affectionately on") + meat_amount = 6 + old_x = -16 + old_y = 0 + default_pixel_x = -16 + pixel_x = -16 + pixel_y = 0 + + max_buckled_mobs = 1 //Yeehaw + can_buckle = TRUE + buckle_movable = TRUE + buckle_lying = FALSE + mount_offset_y = 10 + + var/glowyeyes = FALSE + var/image/eye_layer = null + var/eyetype + var/mob/living/carbon/human/friend + var/tamed = 0 + var/tame_chance = 50 //It's a fiddy-fiddy default you may get a buddy pal or you may get mauled and ate. Win-win! + +// Activate Noms! + +/mob/living/simple_mob/otie + vore_active = 1 + vore_capacity = 1 + vore_pounce_chance = 20 + vore_icons = SA_ICON_LIVING | SA_ICON_REST + +/mob/living/simple_mob/otie/feral //gets the pet2tame feature. starts out hostile tho so get gamblin' + name = "mutated feral otie" + desc = "The classic bioengineered longdog. No pets. Only bite. This one has mutated from too much time out on the surface of Virgo-3B." + tt_desc = "Otus phoronis" + icon_state = "siftusian" + icon_living = "siftusian" + icon_dead = "siftusian-dead" + icon_rest = "siftusian_rest" + faction = "virgo3b" + tame_chance = 5 // Only a 1 in 20 chance of success. It's feral. What do you expect? + melee_damage_lower = 10 + melee_damage_upper = 25 + // Lazy way of making sure this otie survives outside. + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + glowyeyes = TRUE + eyetype = "photie" + +/mob/living/simple_mob/otie/red + name = "feral red otie" + desc = "Seems this ominous looking longdog has been infused with wicked infernal forces." + tt_desc = "Otus infernalis" + icon_state = "hotie" + icon_living = "hotie" + icon_dead = "hotie-dead" + icon_rest = "hotie_rest" + faction = "cult" + tame_chance = 20 + melee_damage_lower = 10 + melee_damage_upper = 25 + // Lazy way of making sure this otie survives outside. + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + glowyeyes = TRUE + eyetype = "hotie" + +/mob/living/simple_mob/otie/red/friendly //gets the pet2tame feature and doesn't kill you right away + name = "red otie" + desc = "Seems this ominous looking longdog has been infused with wicked infernal forces. This one seems rather peaceful though." + faction = "neutral" + tamed = 1 + +/mob/living/simple_mob/otie/friendly //gets the pet2tame feature and doesn't kill you right away + name = "otie" + desc = "The classic bioengineered longdog. This one might even tolerate you!" + faction = "neutral" + tamed = 1 + +/mob/living/simple_mob/otie/cotie //same as above but has a little collar :v + name = "tamed otie" + desc = "The classic bioengineered longdog. This one has a nice little collar on its neck. However a proper domesticated otie is an oxymoron and the collar is likely just a decoration." + icon_state = "cotie" + icon_living = "cotie" + icon_rest = "cotie_rest" + faction = "neutral" + tamed = 1 + +/mob/living/simple_mob/otie/cotie/phoron //friendly phoron pup with collar + name = "mutated otie" + desc = "Looks like someone did manage to domesticate one of those wild phoron mutants. What a badass." + tt_desc = "Otus phoronis" + icon_state = "pcotie" + icon_living = "pcotie" + icon_rest = "pcotie_rest" + icon_dead = "siftusian-dead" + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + glowyeyes = TRUE + eyetype = "photie" + +/mob/living/simple_mob/otie/security //tame by default unless you're a marked crimester. can be befriended to follow with pets tho. + name = "guard otie" + desc = "The VARMAcorp bioengineering division flagship product on trained optimal snowflake guard dogs." + icon_state = "sotie" + icon_living = "sotie" + icon_rest = "sotie_rest" + icon_dead = "sotie-dead" + faction = "neutral" + maxHealth = 200 //armored or something + health = 200 + tamed = 1 + glowyeyes = TRUE + eyetype = "sotie" + loot_list = list(/obj/item/clothing/glasses/sunglasses/sechud,/obj/item/clothing/suit/armor/vest/alt) + vore_pounce_chance = 60 // Good boys don't do too much police brutality. + + var/check_records = 0 // If true, arrests people without a record. + var/check_arrest = 1 // If true, arrests people who are set to arrest. + +/mob/living/simple_mob/otie/security/phoron + name = "mutated guard otie" + desc = "An extra rare phoron resistant version of the VARMAcorp trained snowflake guard dogs." + tt_desc = "Otus phoronis" + icon_state = "sifguard" + icon_living = "sifguard" + icon_rest = "sifguard_rest" + icon_dead = "sifguard-dead" + melee_damage_lower = 10 + melee_damage_upper = 25 + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + glowyeyes = TRUE + eyetype = "sotie" + +/mob/living/simple_mob/otie/PunchTarget() + if(istype(target_mob,/mob/living/simple_mob/mouse)) + return EatTarget() + else ..() + +/mob/living/simple_mob/otie/Found(var/atom/found_atom) + if(!SA_attackable(found_atom)) + return null + if(istype(found_atom,/mob/living/simple_mob/mouse)) + return found_atom + else if(ismob(found_atom)) + var/mob/found_mob = found_atom + if(found_mob.faction == faction) + return null + else if(friend == found_atom) + return null + else if(tamed == 1 && ishuman(found_atom)) + return null + else if(tamed == 1 && isrobot(found_atom)) + return null + else + if(resting) + lay_down() + return found_atom + else + return null + +/mob/living/simple_mob/otie/security/Found(var/atom/found_atom) + if(check_threat(found_atom) >= 4) + if(resting) + lay_down() + return found_atom + ..() + +/mob/living/simple_mob/otie/attackby(var/obj/item/O, var/mob/user) // Trade donuts for bellybrig victims. + if(istype(O, /obj/item/weapon/reagent_containers/food)) + qdel(O) + playsound(src.loc,'sound/items/eatfood.ogg', rand(10,50), 1) + if(ai_inactive)//No autobarf on player control. + return + if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/donut) && istype(src, /mob/living/simple_mob/otie/security)) + to_chat(user,"The guard pup accepts your offer for their catch.") + release_vore_contents() + else if(prob(2)) //Small chance to get prey out from non-sec oties. + to_chat(user,"The pup accepts your offer for their catch.") + release_vore_contents() + return + . = ..() + +/mob/living/simple_mob/otie/security/feed_grabbed_to_self(var/mob/living/user, var/mob/living/prey) // Make the gut start out safe for bellybrigging. + if(ishuman(prey)) + vore_selected.digest_mode = DM_HOLD + if(check_threat(prey) >= 4) + global_announcer.autosay("[src] has detained suspect [target_name(prey)] in [get_area(src)].", "SmartCollar oversight", "Security") + if(istype(prey,/mob/living/simple_mob/mouse)) + vore_selected.digest_mode = DM_DIGEST + . = ..() + +/mob/living/simple_mob/otie/security/proc/check_threat(var/mob/living/M) + if(!M || !ishuman(M) || M.stat == DEAD || src == M) + return 0 + return M.assess_perp(0, 0, 0, check_records, check_arrest) + +/mob/living/simple_mob/otie/security/set_target(var/mob/M) + ai_log("SetTarget([M])",2) + if(!M || (world.time - last_target_time < 5 SECONDS) && target_mob) + ai_log("SetTarget() can't set it again so soon",3) + return 0 + + var/turf/seen = get_turf(M) + + if(investigates && (annoyed < 10)) + try_say_list(say_maybe_target) + face_atom(seen) + annoyed += 14 + sleep(1 SECOND) //For realism + + if(M in ListTargets(view_range)) + try_say_list(say_got_target) + target_mob = M + last_target_time = world.time + if(check_threat(M) >= 4) + global_announcer.autosay("[src] is attempting to detain suspect [target_name(M)] in [get_area(src)].", "SmartCollar oversight", "Security") + return M + else if(investigates) + spawn(1) + WanderTowards(seen) + + return 0 + + +/mob/living/simple_mob/otie/security/proc/target_name(mob/living/T) + if(ishuman(T)) + var/mob/living/carbon/human/H = T + return H.get_id_name("unidentified person") + return "unidentified lifeform" + +//Basic friend AI + +/mob/living/simple_mob/otie/Life() + . = ..() + if(!. || ai_inactive) return + + if(prob(5) && (stance == STANCE_IDLE)) + lay_down() + + if(!friend) return + + var/friend_dist = get_dist(src,friend) + + if (friend_dist <= 4) + if(stance == STANCE_IDLE) + if(set_follow(friend)) + handle_stance(STANCE_FOLLOW) + if(resting) + lay_down() + + if (friend_dist <= 1) + if (friend.stat >= DEAD || friend.health <= config.health_threshold_softcrit) + if (prob((friend.stat < DEAD)? 50 : 15)) + var/verb = pick("whines", "yelps", "whimpers") + audible_emote(pick("[verb] in distress.", "[verb] anxiously.")) + else + if (prob(5)) + visible_emote(pick("nuzzles [friend].", + "brushes against [friend].", + "rubs against [friend].", + "noses at [friend].", + "slobberlicks [friend].", + "murrs contently.", + "leans on [friend].", + "nibbles affectionately on [friend].")) + else if (friend.health <= 50) + if (prob(10)) + var/verb = pick("whines", "yelps", "whimpers") + audible_emote("[verb] anxiously.") + +//Pet 4 friendly + +/mob/living/simple_mob/otie/attack_hand(mob/living/carbon/human/M as mob) + + switch(M.a_intent) + if(I_HELP) + if(health > 0) + M.visible_message("[M] [response_help] \the [src].") + if(ai_inactive) + return + LoseTarget() + handle_stance(STANCE_IDLE) + if(prob(tame_chance)) + friend = M + if(tamed != 1) + tamed = 1 + faction = M.faction + sleep(1 SECOND) + + if(I_GRAB) + if(health > 0) + if(ai_inactive) + return + audible_emote("growls disapprovingly at [M].") + if(M == friend) + friend = null + return + else + ..() + + else + ..() + +/mob/living/simple_mob/otie/proc/add_eyes() + if(!eye_layer) + eye_layer = image(icon, "[eyetype]-eyes") + eye_layer.plane = PLANE_LIGHTING_ABOVE + add_overlay(eye_layer) + +/mob/living/simple_mob/otie/proc/remove_eyes() + cut_overlay(eye_layer) + +/mob/living/simple_mob/otie/New() + if(glowyeyes) + add_eyes() + ..() + +/mob/living/simple_mob/otie/update_icon() + . = ..() + remove_eyes() + if(glowyeyes && stat == CONSCIOUS && !resting) + add_eyes() + +/mob/living/simple_mob/otie/death(gibbed, deathmessage = "dies!") + .=..() + resting = 0 + icon_state = icon_dead + +/mob/living/simple_animal/otie/Login() + . = ..() + if(!riding_datum) + riding_datum = new /datum/riding/simple_animal(src) + verbs |= /mob/living/simple_animal/proc/animal_mount + +/mob/living/simple_animal/otie/MouseDrop_T(mob/living/M, mob/living/user) + return \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/panther.dm b/code/modules/mob/living/simple_mob/subtypes/vore/panther.dm new file mode 100644 index 0000000000..51ebee5f5f --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/vore/panther.dm @@ -0,0 +1,56 @@ +/mob/living/simple_mob/vore/panther + name = "panther" + desc = "Runtime's larger, less cuddly cousin." + tt_desc = "Panthera pardus" + + icon_state = "panther" + icon_living = "panther" + icon_dead = "panther-dead" + icon = 'icons/mob/vore64x64.dmi' + + faction = "panther" + maxHealth = 200 + health = 200 + movement_cooldown = 4 + + melee_damage_lower = 10 + melee_damage_upper = 30 + attack_sharp = TRUE + + old_x = -16 + old_y = 0 + default_pixel_x = -16 + pixel_x = -16 + pixel_y = 0 + + max_buckled_mobs = 1 //Yeehaw + can_buckle = TRUE + buckle_movable = TRUE + buckle_lying = FALSE + mount_offset_y = 12 + + say_list_type = /datum/say_list/panther + ai_holder_type = /datum/ai_holder/simple_mob/melee/evasive + +// Activate Noms! +/mob/living/simple_mob/vore/panther + vore_active = 1 + vore_capacity = 2 + vore_pounce_chance = 10 + vore_icons = SA_ICON_LIVING | SA_ICON_REST + +/* //VOREStation AI Temporary Removal +/mob/living/simple_animal/vore/panther/Login() + . = ..() + if(!riding_datum) + riding_datum = new /datum/riding/simple_animal(src) + verbs |= /mob/living/simple_animal/proc/animal_mount +*/ + +/mob/living/simple_animal/vore/panther/MouseDrop_T(mob/living/M, mob/living/user) + return + +/datum/say_list/panther + speak = list("RAWR!","Rawr!","GRR!","Growl!") + emote_hear = list("rawrs","rumbles","rowls","growls","roars") + emote_see = list("stares ferociously", "snarls") diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/rat.dm b/code/modules/mob/living/simple_mob/subtypes/vore/rat.dm new file mode 100644 index 0000000000..f49d7ec0f4 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/vore/rat.dm @@ -0,0 +1,183 @@ +/mob/living/simple_mob/vore/rat + name = "giant rat" + desc = "In what passes for a hierarchy among verminous rodents, this one is king." + tt_desc = "Mus muscular" + + icon_state = "rous" + icon_living = "rous" + icon_dead = "rous-dead" + icon_rest = "rous_rest" + faction = "mouse" + icon = 'icons/mob/vore64x32.dmi' + + maxHealth = 150 + health = 150 + + melee_damage_lower = 5 + melee_damage_upper = 15 + grab_resist = 100 + + response_help = "pets the" + response_disarm = "bops the" + response_harm = "hits the" + attacktext = list("ravaged") + friendly = list("nuzzles", "licks", "noses softly at", "noseboops", "headbumps against", "leans on", "nibbles affectionately on") + + old_x = -16 + old_y = 0 + default_pixel_x = -16 + pixel_x = -16 + pixel_y = 0 + + max_buckled_mobs = 1 //Yeehaw + can_buckle = TRUE + buckle_movable = TRUE + buckle_lying = FALSE + mount_offset_y = 10 + + vore_active = TRUE + vore_capacity = 1 + vore_pounce_chance = 45 + vore_icons = SA_ICON_LIVING | SA_ICON_REST + + var/life_since_foodscan = 0 + + say_list_type = /datum/say_list/ratte + ai_holder_type = /datum/ai_holder/simple_mob/melee/rat + +/mob/living/simple_mob/vore/rat/passive + name = "curious giant rat" + desc = "In what passes for a hierarchy among verminous rodents, this one is king. It seems to be more interested on scavenging." + var/mob/living/carbon/human/food + var/hunger = 0 +/* +/mob/living/simple_mob/hostile/rat/passive/Life() + . = ..() + if(!. || ai_inactive) + return + + if(hunger > 0 && life_since_foodscan++ > 5) //Only look for floor food when hungry. + life_since_foodscan = 0 + for(var/obj/item/weapon/reagent_containers/food/snacks/S in oview(src,3)) //Accept thrown offerings and scavenge surroundings. + if(get_dist(src,S) <=1) + visible_emote("hungrily devours \the [S].") + playsound(src.loc,'sound/items/eatfood.ogg', rand(10,50), 1) + qdel(S) + hunger = 0 + food = null + else + WanderTowards(S.loc) + break + + if(!food) + return + + var/food_dist = get_dist(src,food) + + if(food_dist > world.view) //Lose interest on this person. + food = null + hunger = Clamp(hunger+5, 0, 25) + + if(food_dist > 1) + if(stance == STANCE_IDLE) + if(set_follow(food,10 SECONDS)) + handle_stance(STANCE_FOLLOW) + if(resting) + lay_down() + + if(food_dist <= 1) + if(hunger < 15) + if(prob(25)) + visible_emote(pick("sniffs curiously at [food].", + "stares at [food], seeming to want something.", + "sniffs at [food]'s hands.", + "sniffs curiously at [food]'s pockets.", + "sits down for a moment, reaching towards [food] with its paws.")) + hunger += 5 + else if(hunger < 30) + if(prob(25)) + visible_emote(pick("sniffs intently against [food], especially their pockets and gear.", + "stands up to beg [food] for snacks.", + "attempts to burrow into [food]'s pockets.", + "leans against [food], licking its chops.", + "hungrily nibbles onto [food].")) + hunger += 5 + else if(hunger < 45) + if(prob(25)) + visible_emote(pick("growls at [food], sounding rather hangry!", + "aggressively bumps and nudges against [food], trying to make something fall out.", + "salivates at [food] in an unsettling manner.", + "pushes hard against [food], licking its chops.", + "almost sinks its teeth into [food], just stopping to give them another chance.")) + hunger += 5 + else if(hunger < 50) + if(prob(25)) + visible_emote("appears to have had enough and prepares to strike!") + hunger += 5 + else + food.Weaken(5) + food.visible_message("\the [src] pounces on \the [food]!!") + target_mob = food + EatTarget() + hunger = 0 + food = null + +/mob/living/simple_mob/hostile/rat/passive/attackby(var/obj/item/O, var/mob/user) // Feed the rat your food to satisfy it. + if(istype(O, /obj/item/weapon/reagent_containers/food/snacks)) + qdel(O) + playsound(src.loc,'sound/items/eatfood.ogg', rand(10,50), 1) + hunger = 0 + food = null + return + . = ..() + +/mob/living/simple_mob/hostile/rat/passive/Found(var/atom/found_atom) + if(!SA_attackable(found_atom)) + return null + else if(ishuman(found_atom) && will_eat(found_atom)) + var/mob/living/carbon/human/H = found_atom + for(var/obj/item/weapon/reagent_containers/food/snacks/S in H) + if(!food) + visible_emote("sniffs around the air intently, seeming to have caught a whiff of food!") + if(resting) + lay_down() + food = H + return found_atom + break + return null + +/mob/living/simple_mob/hostile/rat/passive/FindTarget() + var/atom/T = null + for(var/atom/A in ListTargets(view_range)) + if(A == src) + continue + var/atom/F = Found(A) + if(F) + T = F + break + return T +*/ +/mob/living/simple_mob/vore/rat/death() + playsound(src, 'sound/effects/mouse_squeak_loud.ogg', 50, 1) + ..() + +/* //VOREStation AI Temporary Removal +/mob/living/simple_mob/vore/rat/Login() + . = ..() + if(!riding_datum) + riding_datum = new /datum/riding/simple_animal(src) + verbs |= /mob/living/simple_animal/proc/animal_mount +*/ + +/mob/living/simple_mob/vore/rat/MouseDrop_T(mob/living/M, mob/living/user) + return + +/datum/say_list/ratte + speak = list("Squeek!","SQUEEK!","Squeek?") + emote_hear = list("squeeks","squeaks","squiks") + emote_see = list("runs in a circle", "shakes", "scritches at something") + say_maybe_target = list("Squeek?") + say_got_target = list("SQUEEK!") + +/datum/ai_holder/simple_mob/melee/rat + speak_chance = 3 diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/redpanda.dm b/code/modules/mob/living/simple_mob/subtypes/vore/redpanda.dm new file mode 100644 index 0000000000..86bbdbc12a --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/vore/redpanda.dm @@ -0,0 +1,59 @@ +/mob/living/simple_mob/vore/redpanda + name = "red panda" + desc = "It's a wah! Beware of doom pounce!" + tt_desc = "Ailurus fulgens" + + icon_state = "wah" + icon_living = "wah" + icon_dead = "wah_dead" + icon_rest = "wah_rest" + icon = 'icons/mob/vore.dmi' + + faction = "redpanda" //stop naming stuff vaguely + maxHealth = 30 + health = 30 + + response_help = "pats the" + response_disarm = "gently pushes aside the" + response_harm = "hits the" + + harm_intent_damage = 5 + melee_damage_lower = 5 + melee_damage_upper = 2 + attacktext = list("bapped") + + say_list_type = /datum/say_list/redpanda + ai_holder_type = /datum/ai_holder/simple_mob/passive + +// Activate Noms! +/mob/living/simple_mob/vore/redpanda + vore_active = 1 + vore_bump_chance = 10 + vore_bump_emote = "playfully lunges at" + vore_pounce_chance = 40 + vore_default_mode = DM_HOLD // above will only matter if someone toggles it anyway + vore_icons = SA_ICON_LIVING + +/mob/living/simple_mob/vore/redpanda/fae + name = "dark wah" + desc = "Ominous, but still cute!" + tt_desc = "Ailurus brattus" + + icon_state = "wah_fae" + icon_living = "wah_fae" + icon_dead = "wah_fae_dead" + icon_rest = "wah_fae_rest" + + vore_ignores_undigestable = 0 // wah don't care you're edible or not, you still go in + vore_digest_chance = 0 // instead of digesting if you struggle... + vore_absorb_chance = 20 // you get to become adorable purple wahpudge. + vore_bump_chance = 75 + maxHealth = 100 + health = 100 + melee_damage_lower = 10 + melee_damage_upper = 20 + +/datum/say_list/redpanda + speak = list("Wah!","Wah?","Waaaah.") + emote_hear = list("wahs!","chitters.") + emote_see = list("trundles around","rears up onto their hind legs and pounces a bug") diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/_defines.dm b/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/_defines.dm new file mode 100644 index 0000000000..1567134c4d --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/_defines.dm @@ -0,0 +1,13 @@ +#define NOT_WHILE_SHIFTED 1 +#define ONLY_WHILE_SHIFTED 2 +#define SHIFTED_OR_NOT 3 + +#define BLUE_EYES 1 +#define RED_EYES 2 +#define PURPLE_EYES 3 +#define YELLOW_EYES 4 +#define GREEN_EYES 5 +#define ORANGE_EYES 6 + +#define AB_PHASE_SHIFTED 0x1 +#define AB_SHADE_REGEN 0x2 \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/ability_objects.dm b/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/ability_objects.dm new file mode 100644 index 0000000000..6990623043 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/ability_objects.dm @@ -0,0 +1,165 @@ +/obj/effect/shadekin_ability + name = "" + desc = "" + icon = 'icons/mob/screen_spells.dmi' + var/ability_name = "FIX ME" + var/cost = 50 + var/mob/living/simple_mob/shadekin/my_kin + var/shift_mode = NOT_WHILE_SHIFTED + var/ab_sound + +/obj/effect/shadekin_ability/New(var/new_kin) + ..() + my_kin = new_kin + loc = null + +/obj/effect/shadekin_ability/Destroy() + my_kin = null + return ..() + +/obj/effect/shadekin_ability/proc/atom_button_text() + var/shift_denial + + if(shift_mode == NOT_WHILE_SHIFTED && (my_kin.ability_flags & AB_PHASE_SHIFTED)) + shift_denial = "Physical Only" + else if(shift_mode == ONLY_WHILE_SHIFTED && !(my_kin.ability_flags & AB_PHASE_SHIFTED)) + shift_denial = "Shifted Only" + + if(shift_denial) + name = shift_denial + else + name = my_kin.energy >= cost ? "Activate" : "No Energy" + return src + +/obj/effect/shadekin_ability/Click(var/location, var/control, var/params) + if(my_kin.stat) return + + var/list/clickprops = params2list(params) + var/opts = clickprops["shift"] + + if(opts) + to_chat(my_kin,"[name] (Cost: [cost]%) - [desc]") + else + do_ability(my_kin) + +/obj/effect/shadekin_ability/proc/do_ability() + if(my_kin.stat) + to_chat(my_kin,"Can't use that ability in your state!") + return FALSE + if(shift_mode == NOT_WHILE_SHIFTED && (my_kin.ability_flags & AB_PHASE_SHIFTED)) + to_chat(my_kin,"Can't use that ability while phase shifted!") + return FALSE + else if(shift_mode == ONLY_WHILE_SHIFTED && !(my_kin.ability_flags & AB_PHASE_SHIFTED)) + to_chat(my_kin,"Can only use that ability while phase shifted!") + return FALSE + else if(my_kin.energy < cost) + to_chat(my_kin,"Not enough energy for that ability!") + return FALSE + + my_kin.energy -= cost + if(ab_sound) + playsound(src,ab_sound,75,1) + + return TRUE + +///////////////////////////////////////////////////////////////// +/obj/effect/shadekin_ability/phase_shift + ability_name = "Phase Shift" + desc = "Shift yourself out of alignment with realspace to travel quickly between dark areas (or light areas, with a price)." + icon_state = "tech_passwall" + cost = 100 + shift_mode = SHIFTED_OR_NOT + ab_sound = 'sound/effects/stealthoff.ogg' +/obj/effect/shadekin_ability/phase_shift/do_ability() + if(!..()) + return + my_kin.phase_shift() + if(my_kin.ability_flags & AB_PHASE_SHIFTED) + cost = 0 //Shifting back is free (but harmful in light) + else + cost = initial(cost) +///////////////////////////////////////////////////////////////// +/obj/effect/shadekin_ability/heal_boop + ability_name = "Regenerate Other" + desc = "Spend energy to heal physical wounds in another creature." + icon_state = "tech_biomedaura" + cost = 50 + shift_mode = NOT_WHILE_SHIFTED + ab_sound = 'sound/effects/EMPulse.ogg' +/obj/effect/shadekin_ability/heal_boop/do_ability() + if(!..()) + return + if(!my_kin.mend_other()) + my_kin.energy += cost //Refund due to abort + +/datum/modifier/shadekin/heal_boop + name = "Shadekin Regen" + desc = "You feel serene and well rested." + mob_overlay_state = "green_sparkles" + + on_created_text = "Sparkles begin to appear around you, and all your ills seem to fade away." + on_expired_text = "The sparkles have faded, although you feel much healthier than before." + stacks = MODIFIER_STACK_EXTEND + +/datum/modifier/shadekin/heal_boop/tick() + if(!holder.getBruteLoss() && !holder.getFireLoss() && !holder.getToxLoss() && !holder.getOxyLoss() && !holder.getCloneLoss()) // No point existing if the spell can't heal. + expire() + return + holder.adjustBruteLoss(-2) + holder.adjustFireLoss(-2) + holder.adjustToxLoss(-2) + holder.adjustOxyLoss(-2) + holder.adjustCloneLoss(-2) +///////////////////////////////////////////////////////////////// +/obj/effect/shadekin_ability/create_shade + ability_name = "Create Shade" + desc = "Create a field of darkness that follows you." + icon_state = "tech_dispelold" + cost = 25 + shift_mode = NOT_WHILE_SHIFTED + ab_sound = 'sound/effects/bamf.ogg' +/obj/effect/shadekin_ability/create_shade/do_ability() + if(!..()) + return + my_kin.add_modifier(/datum/modifier/shadekin/create_shade,20 SECONDS) +/datum/modifier/shadekin/create_shade + name = "Shadekin Shadegen" + desc = "Darkness envelops you." + mob_overlay_state = "" + + on_created_text = "You drag part of The Dark into realspace, enveloping yourself." + on_expired_text = "You lose your grasp on The Dark and realspace reasserts itself." + stacks = MODIFIER_STACK_EXTEND + var/mob/living/simple_mob/shadekin/my_kin + +/datum/modifier/shadekin/create_shade/tick() + if(my_kin.ability_flags & AB_PHASE_SHIFTED) + expire() + +/datum/modifier/shadekin/create_shade/on_applied() + my_kin = holder + holder.glow_toggle = TRUE + holder.glow_range = 8 + holder.glow_intensity = -10 + holder.glow_color = "#FFFFFF" + holder.set_light(8, -10, "#FFFFFF") + +/datum/modifier/shadekin/create_shade/on_expire() + holder.glow_toggle = initial(holder.glow_toggle) + holder.glow_range = initial(holder.glow_range) + holder.glow_intensity = initial(holder.glow_intensity) + holder.glow_color = initial(holder.glow_color) + holder.set_light(0) + my_kin = null +/* +///////////////////////////////////////////////////////////////// +/obj/effect/shadekin_ability/energy_feast + ability_name = "Devour Energy" + desc = "Devour the energy from another creature (potentially fatal)." + icon_state = "gen_eat" + cost = 25 + shift_mode = NOT_WHILE_SHIFTED +/obj/effect/shadekin_ability/energy_feast/do_ability() + if(!..()) + return +*/ \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/ability_procs.dm b/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/ability_procs.dm new file mode 100644 index 0000000000..0be707f852 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/ability_procs.dm @@ -0,0 +1,133 @@ +// Phase shifting procs (and related procs) +/mob/living/simple_mob/shadekin/proc/phase_shift() + var/turf/T = get_turf(src) + if(!T.CanPass(null,T) || loc != T) + to_chat(src,"You can't use that here!") + return FALSE + + forceMove(T) + var/original_canmove = canmove + SetStunned(0) + SetWeakened(0) + if(buckled) + buckled.unbuckle_mob() + if(pulledby) + pulledby.stop_pulling() + stop_pulling() + canmove = FALSE + + //Shifting in + if(ability_flags & AB_PHASE_SHIFTED) + ability_flags &= ~AB_PHASE_SHIFTED + name = real_name + for(var/belly in vore_organs) + var/obj/belly/B = belly + B.escapable = initial(B.escapable) + + overlays.Cut() + alpha = initial(alpha) + invisibility = initial(invisibility) + see_invisible = initial(see_invisible) + incorporeal_move = initial(incorporeal_move) + density = initial(density) + force_max_speed = initial(force_max_speed) + + //Cosmetics mostly + flick("tp_in",src) + custom_emote(1,"phases in!") + sleep(5) //The duration of the TP animation + canmove = original_canmove + + //Potential phase-in vore + if(can_be_drop_pred) //Toggleable in vore panel + var/list/potentials = living_mobs(0) + if(potentials.len) + var/mob/living/target = pick(potentials) + if(istype(target) && vore_selected) + target.forceMove(vore_selected) + to_chat(target,"\The [src] phases in around you, [vore_selected.vore_verb]ing you into their [vore_selected.name]!") + + // Do this after the potential vore, so we get the belly + update_icon() + + //Affect nearby lights + var/destroy_lights = 0 + if(eye_state == RED_EYES) + destroy_lights = 80 + if(eye_state == PURPLE_EYES) + destroy_lights = 25 + + for(var/obj/machinery/light/L in machines) + if(L.z != z || get_dist(src,L) > 10) + continue + + if(prob(destroy_lights)) + spawn(rand(5,25)) + L.broken() + else + L.flicker(10) + + //Shifting out + else + ability_flags |= AB_PHASE_SHIFTED + custom_emote(1,"phases out!") + real_name = name + name = "Something" + + for(var/belly in vore_organs) + var/obj/belly/B = belly + B.escapable = FALSE + + overlays.Cut() + flick("tp_out",src) + sleep(5) + invisibility = INVISIBILITY_LEVEL_TWO + see_invisible = INVISIBILITY_LEVEL_TWO + update_icon() + alpha = 127 + + canmove = original_canmove + incorporeal_move = TRUE + density = FALSE + force_max_speed = TRUE + +/mob/living/simple_mob/shadekin/UnarmedAttack() + if(ability_flags & AB_PHASE_SHIFTED) + return FALSE //Nope. + + . = ..() + +/mob/living/simple_mob/shadekin/can_fall() + if(ability_flags & AB_PHASE_SHIFTED) + return FALSE //Nope! + + return ..() + +/mob/living/simple_mob/shadekin/zMove(direction) + if(ability_flags & AB_PHASE_SHIFTED) + var/turf/destination = (direction == UP) ? GetAbove(src) : GetBelow(src) + if(destination) + forceMove(destination) + return TRUE + + return ..() + +// Healing others +/mob/living/simple_mob/shadekin/proc/mend_other() + //I hate to crunch a view() but I only want ones I can see + var/list/viewed = oview(1) + var/list/targets = list() + for(var/mob/living/L in viewed) + targets += L + if(!targets.len) + to_chat(src,"Nobody nearby to mend!") + return FALSE + + var/mob/living/target = input(src,"Pick someone to mend:","Mend Other") as null|anything in targets + if(!target) + return FALSE + + target.add_modifier(/datum/modifier/shadekin/heal_boop,1 MINUTE) + visible_message("\The [src] gently places a hand on \the [target]...") + face_atom(target) + return TRUE diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/shadekin.dm b/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/shadekin.dm new file mode 100644 index 0000000000..0b3256928f --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/shadekin.dm @@ -0,0 +1,449 @@ +/mob/living/simple_mob/shadekin //Spawning the prototype spawns a random one, see initialize() + name = "shadekin" + desc = "Some sort of fluffer. Big ears, long tail." + icon = 'icons/mob/vore_shadekin.dmi' + icon_state = "map_example" + icon_living = "map_example" + faction = "shadekin" + ui_icons = 'icons/mob/shadekin_hud.dmi' + mob_class = MOB_CLASS_HUMANOID + + maxHealth = 200 + health = 200 + + movement_cooldown = 2 + see_in_dark = 10 //SHADEkin + has_hands = TRUE //Pawbs + seedarkness = FALSE //SHAAAADEkin + attack_sound = 'sound/weapons/bladeslice.ogg' + has_langs = list(LANGUAGE_GALCOM,LANGUAGE_SHADEKIN) + + melee_damage_lower = 10 + melee_damage_upper = 20 + + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + minbodytemp = 0 + maxbodytemp = 900 + + say_list_type = /datum/say_list/shadekin + + response_help = "pets the" + response_disarm = "bops the" + response_harm = "hits the" + + attacktext = list("mauled","slashed","clawed") + friendly = list("boops", "pawbs", "mars softly at", "sniffs on") + + vore_active = TRUE + vore_pounce_chance = 10 + vore_icons = SA_ICON_LIVING + swallowTime = 2 SECONDS + vore_escape_chance = 25 + + //None, they stay as their defaults. + vore_digest_chance = 0 + vore_absorb_chance = 0 + vore_bump_chance = 0 //They follow people, this would be DENGEROUS + + var/eye_state = RED_EYES //Eye color/energy gain/loss mode + var/eye_icon_state = null //Default, changed in init + var/eye_desc //Eye color description added to examine + + var/mob/living/carbon/human/henlo_human //Human we're stalking currently + + //Behavior + var/stalker = TRUE //Do we creep up on humans + var/shy_approach = FALSE //Do we creep up slowly on humans to boop them + + //Icon handling + var/image/tailimage //Cached tail image + + //Darknesssss + var/energy = 100 //For abilities + var/energy_adminbuse = FALSE //For adminbuse infinite energy + var/dark_gains = 0 //Last tick's change in energy + var/ability_flags = 0 //Flags for active abilities + var/obj/screen/darkhud //Holder to update this icon + var/obj/screen/energyhud //Holder to update this icon + + var/list/shadekin_abilities + +/mob/living/simple_mob/shadekin/Initialize() + //You spawned the prototype, and want a totally random one. + if(type == /mob/living/simple_mob/shadekin) + + //I'm told by VerySoft these are the liklihood values + var/list/sk_types = list( + /mob/living/simple_mob/shadekin/red = 20, //Actively seek people out to nom, so fairly common to see (relatively speaking), + /mob/living/simple_mob/shadekin/blue = 15, //Explorers that like to interact with people, so still fairly common, + /mob/living/simple_mob/shadekin/purple = 15, //Also explorers that may or may not homf people, + /mob/living/simple_mob/shadekin/yellow = 1 //Very rare, usually never leaves their home + ) + var/new_type = pickweight(sk_types) + + new new_type(loc) + initialized = TRUE + return INITIALIZE_HINT_QDEL + + if(icon_state == "map_example") + icon_state = pick("white","dark","brown") + + icon_living = icon_state + + switch(eye_state) + if(BLUE_EYES) + eye_icon_state = "e_blue" + if(RED_EYES) + eye_icon_state = "e_red" + if(PURPLE_EYES) + eye_icon_state = "e_purple" + if(YELLOW_EYES) + eye_icon_state = "e_yellow" + if(GREEN_EYES) + eye_icon_state = "e_green" + if(ORANGE_EYES) + eye_icon_state = "e_orange" + else + eye_icon_state = "e_red" + + tailimage = image('icons/mob/vore_shadekin64.dmi',null,icon_state) + tailimage.pixel_x = -16 + + if(eye_desc) + desc += " This one has [eye_desc]!" + + var/list/ability_types = subtypesof(/obj/effect/shadekin_ability) + shadekin_abilities = list() + for(var/type in ability_types) + shadekin_abilities += new type(src) + + update_icon() + + return ..() + +/mob/living/simple_mob/shadekin/Destroy() + QDEL_LIST_NULL(shadekin_abilities) + . = ..() + +/mob/living/simple_mob/shadekin/init_vore() + if(LAZYLEN(vore_organs)) + return + + var/obj/belly/B = new /obj/belly(src) + vore_selected = B + B.immutable = 1 + B.name = vore_stomach_name ? vore_stomach_name : "stomach" + B.desc = vore_stomach_flavor ? vore_stomach_flavor : "Your surroundings are warm, soft, and slimy. Makes sense, considering you're inside \the [name]." + B.digest_mode = vore_default_mode + B.escapable = vore_escape_chance > 0 + B.escapechance = vore_escape_chance + B.digestchance = vore_digest_chance + B.absorbchance = vore_absorb_chance + B.human_prey_swallow_time = swallowTime + B.nonhuman_prey_swallow_time = swallowTime + B.vore_verb = "swallow" + // TODO - Customizable per mob + B.emote_lists[DM_HOLD] = list( + "The walls gently squeeze against you. The wet sounds of shifting flesh against your form fill the air.", + "The hot, humid air rushes around you for a moment as the creature urps. The walls clench in around you for a moment, before relaxing again.", + "Your body is soaked in the fluids that cling to the churning walls. They squeeze across your form gently, conforming to your shape.", + "You can feel the world around you shift and sway as the creature moves! The flesh is stretchy, doughy. You can sink into it a little ways before it bounces back, curling you into a small shape." + ) + B.emote_lists[DM_DIGEST] = list( + "The walls slop thick slime across your body! It tingles briefly before the sting and ache sets in!", + "The sound of your body slipping and sliding against the powerfully churning stomach fills the air!", + "The grip of that stomach is harsh. Eagerly mushing and rubbing that slime into your body in attempts to break you down!", + "The intense churning and grinding jostles your around within the thick slime as you're slowly broken down!" + ) + B.emote_lists[DM_ABSORB] = list( + "The walls cling to you awfully close... It's almost like you're sinking into them.", + "You can feel the walls press in tightly against you, clinging to you posessively!", + "It almost feels like you're sinking into the soft, doughy flesh!", + "You can feel the walls press in around you. Almost molten, so squishy!!" + ) + B.emote_lists[DM_DRAIN] = list( + "The walls churn down on you heavily!! It's hard to move!", + "You can feel yourself getting weaker with every moment! The doughy walls sap your strength!", + "You're practically smothered in the oppressive heat of the creature's stomach!", + "It's hot, wet and tight!" + ) + B.emote_lists[DM_HEAL] = list( + "The walls pulse against you almost rhythmically. It feels nice, almost like a massage.", + "You're gently squeezed in pleasant warmth, softly churned.", + "The doughy feel of the heavy flesh clinging to you makes you feel a little stronger with every passing moment.", + "The flesh caresses across your body gently as you're held." + ) + B.digest_messages_prey = list( + "Your body is steadily softened more and more over time! Eventually you pass out. The creature's stomach rumbles powerfully as you are reduced to paste, processed for energy!", + "The creature's slimy gut lets out a heavy groan as you're slowly melted away. Gushing deeper through the creature.", + "The stinging and aching gives way to numbness as you're slowly smothered out. Your body is steadily reduced to nutrients and energy for the creature to continue on its way.", + "The chaos of being digested fades as you're snuffed out by a harsh clench! You're steadily broken down into a thick paste, processed and absorbed by the predator!" + ) + +/mob/living/simple_mob/shadekin/Life() + . = ..() + if(ability_flags & AB_PHASE_SHIFTED) + density = FALSE + + //Convert spare nutrition into energy at a certain ratio + if(. && nutrition > initial(nutrition) && energy < 100) + nutrition = max(0, nutrition-5) + energy = min(100,energy+1) + +/mob/living/simple_mob/shadekin/update_icon() + . = ..() + + cut_overlay(tailimage) + + tailimage.icon_state = icon_state + + add_overlay(tailimage) + add_overlay(eye_icon_state) + +/mob/living/simple_mob/shadekin/Stat() + . = ..() + if(statpanel("Shadekin")) + abilities_stat() + +/mob/living/simple_mob/shadekin/proc/abilities_stat() + for(var/A in shadekin_abilities) + var/obj/effect/shadekin_ability/ability = A + stat("[ability.ability_name]",ability.atom_button_text()) + +//They phase back to the dark when killed +/mob/living/simple_mob/shadekin/death(gibbed, deathmessage = "phases to somewhere far away!") + overlays = list() + icon_state = "" + flick("tp_out",src) + spawn(1 SECOND) + qdel(src) //Back from whence you came! + + . = ..(FALSE, deathmessage) + +/* //VOREStation AI Temporary Removal +//Blue-eyes want to nom people to heal them +/mob/living/simple_mob/shadekin/Found(var/atom/A) + if(specific_targets && isliving(A)) //Healing! + var/mob/living/L = A + var/health_percent = (L.health/L.maxHealth)*100 + if(health_percent <= 50 && will_eat(A)) + return A + . = ..() +*/ + +//They reach nutritional equilibrium (important for blue-eyes healbelly) +/mob/living/simple_mob/shadekin/Life() + if((. = ..())) + handle_shade() + +/mob/living/simple_mob/shadekin/proc/handle_shade() + //Shifted kin don't gain/lose energy (and save time if we're at the cap) + var/darkness = 1 + + + var/turf/T = get_turf(src) + if(!T) + dark_gains = 0 + return + + var/brightness = T.get_lumcount() //Brightness in 0.0 to 1.0 + darkness = 1-brightness //Invert + + if(ability_flags & AB_PHASE_SHIFTED) + dark_gains = 0 + else + //Heal (very) slowly in good darkness + if(darkness >= 0.75) + adjustFireLoss(-0.05) + adjustBruteLoss(-0.05) + adjustToxLoss(-0.05) + + switch(eye_state) + //Blue has constant, steady (slow) regen and ignores darkness. + if(BLUE_EYES) + dark_gains = 0.5 + //Red has extremely tiny energy buildup in dark, none in light, and hunts for energy. + if(RED_EYES) + if(darkness >= 0.75) + dark_gains = 0.25 + //Purple eyes have moderate gains in darkness and loss in light. + if(PURPLE_EYES) + dark_gains = round((darkness - 0.5) * 2, 0.1) + //Yellow has extreme gains in darkness and loss in light. + if(YELLOW_EYES) + dark_gains = round((darkness - 0.5) * 4, 0.1) + //Similar to blues, but passive is less, and affected by dark + if(GREEN_EYES) + dark_gains = 0.25 + dark_gains += round((darkness - 0.5), 0.1) + //More able to get energy out of the dark, worse attack gains tho + if(ORANGE_EYES) + if(darkness >= 0.65) + dark_gains = 0.30 + + energy = max(0,min(initial(energy),energy + dark_gains)) + + if(energy_adminbuse) + energy = 100 + + //Update turf darkness hud + if(darkhud) + switch(darkness) + if(0.80 to 1.00) + darkhud.icon_state = "dark2" + if(0.60 to 0.80) + darkhud.icon_state = "dark1" + if(0.40 to 0.60) + darkhud.icon_state = "dark" + if(0.20 to 0.40) + darkhud.icon_state = "dark-1" + if(0.00 to 0.20) + darkhud.icon_state = "dark-2" + + //Update energy storage hud + if(energyhud) + switch(energy) + if(80 to INFINITY) + energyhud.icon_state = "energy0" + if(60 to 80) + energyhud.icon_state = "energy1" + if(40 to 60) + energyhud.icon_state = "energy2" + if(20 to 40) + energyhud.icon_state = "energy3" + if(0 to 20) + energyhud.icon_state = "energy4" + +/* //VOREStation AI Removal +//Friendly ones wander towards people, maybe shy-ly if they are set to shy +/mob/living/simple_mob/shadekin/handle_wander_movement() + if(isturf(src.loc) && !resting && !buckled && canmove) + lifes_since_move++ + if(lifes_since_move >= turns_per_move) + if(!(stop_when_pulled && pulledby)) + var/moving_to + + if(stalker) + //Sniff sniff. + var/list/humans = human_mobs(world.view) + + //Can we see the last person we were following? + if(henlo_human && !(henlo_human in humans)) + henlo_human = null + + //Can we find a new person to follow? + if(!henlo_human) + while(!henlo_human && humans.len) + henlo_human = pick(humans) + if(!isturf(henlo_human.loc)) + humans -= henlo_human + henlo_human = null + + //Boopable hunam? + if(henlo_human) + moving_to = get_dir(src,henlo_human) + + if((get_dist(src,henlo_human) <= 1)) + dir = moving_to + if(prob(speak_chance)) + visible_message("\The [src] [pick(friendly)] \the [henlo_human].") + shy_approach = FALSE //ACCLIMATED + lifes_since_move = 0 + return //No need to move + + if(shy_approach) + var/them_to_us = turn(moving_to,180) + if(abs(dir2angle(henlo_human.dir) - dir2angle(them_to_us)) <= 90) + dir = them_to_us + return //AAA! + + dir = moving_to + + //Random walk + if(!moving_to) + moving_to = pick(cardinal) + dir = moving_to + + var/turf/T = get_step(src,moving_to) + if(avoid_turf(T)) + return + Move(T) + lifes_since_move = 0 +*/ + +/mob/living/simple_mob/shadekin/speech_bubble_appearance() + return "ghost" + +/mob/living/simple_mob/shadekin/apply_melee_effects(var/atom/A) + . = ..(A) + if(isliving(A)) //We punched something! + var/mob/living/L = A + if(L.stat != DEAD) + var/gains = 0 + switch(eye_state) + if(RED_EYES) + gains = 8 + if(BLUE_EYES) + gains = 1 + if(PURPLE_EYES) + gains = 4 + if(YELLOW_EYES) + gains = 3 + if(GREEN_EYES) + gains = 1 + if(ORANGE_EYES) + gains = 5 + + energy += gains + +//Special hud elements for darkness and energy gains +/mob/living/simple_mob/shadekin/extra_huds(var/datum/hud/hud,var/icon/ui_style,var/list/hud_elements) + //Darkness hud + darkhud = new /obj/screen() + darkhud.icon = ui_style + darkhud.icon_state = "dark" + darkhud.name = "darkness" + darkhud.screen_loc = "CENTER-2:16,SOUTH:5" //Left of the left hand + darkhud.alpha = 150 + hud_elements |= darkhud + + //Energy hud + energyhud = new /obj/screen() + energyhud.icon = ui_style + energyhud.icon_state = "energy0" + energyhud.name = "energy" + energyhud.screen_loc = "CENTER+1:16,SOUTH:5" //Right of the right hand + energyhud.alpha = 150 + hud_elements |= energyhud + +// When someone clicks us with an empty hand +/mob/living/simple_mob/shadekin/attack_hand(mob/living/carbon/human/M as mob) + . = ..() + if(M.a_intent == I_HELP) + shy_approach = FALSE //ACCLIMATED + +/datum/say_list/shadekin + speak = list("Marrr.", "Marrr?", "Marrr!") + emote_hear = list("chrrrrrs", "wurbles", "wrrrrbles") + emote_see = list("tailtwitches", "earflicks") + say_maybe_target = list("...mar?") + say_got_target = list("MAR!!!") + //reactions = list("Mar?" = "Marrr!", "Mar!" = "Marrr???", "Mar." = "Marrr.") + +/datum/language/shadekin + name = "Shadekin Empathy" + desc = "Shadekin seem to always know what the others are thinking. This is probably why." + colour = "changeling" + speech_verb = "mars" + ask_verb = "mars" + exclaim_verb = "mars" + key = "m" + machine_understands = 0 + flags = WHITELISTED | HIVEMIND diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/types.dm b/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/types.dm new file mode 100644 index 0000000000..79e12f39fb --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/types.dm @@ -0,0 +1,256 @@ +///////////////////////////////////////////////////////////////// +/mob/living/simple_mob/shadekin/red + name = "red-eyed shadekin" + eye_state = RED_EYES + //hostile = TRUE + //animal = TRUE + //stop_when_pulled = FALSE + //destroy_surroundings = TRUE + armor = list( + "melee" = 30, + "bullet" = 20, + "laser" = 20, + "energy" = 50, + "bomb" = 10, + "bio" = 100, + "rad" = 100) + + eye_desc = "red eyes" + + vore_stomach_flavor = "You slip past pointy triangle teeth and down the slick, \ + slippery gullet of the creature. It's warm, and the air is thick. You can hear \ + its body squelch and shift around you as you settle into its stomach! Thick digestive \ + enzymes cling to you within that dark space, tingling and stinging immediately! The weight of \ + the doughy walls press in around you instantly, churning you up as you begin to digest!" + + player_msg = "You hunt for energy to fuel yourself, not minding in the least \ + if you strip it off unsuspecting prey. You're stronger than other shadekin, faster, and more capable in \ + a brawl, but you barely generate any of your own energy. You can stand in a dark spot to gather scraps \ + of energy in a pinch, but otherwise need to take it, by force if necessary." + +/mob/living/simple_mob/shadekin/red/white + icon_state = "white" +/mob/living/simple_mob/shadekin/red/dark + icon_state = "dark" +/mob/living/simple_mob/shadekin/red/brown + icon_state = "brown" + +///////////////////////////////////////////////////////////////// +/mob/living/simple_mob/shadekin/blue + name = "blue-eyed shadekin" + eye_state = BLUE_EYES + health = 100 + //hostile = FALSE + //animal = FALSE + //stop_when_pulled = TRUE + //specific_targets = TRUE //For finding injured people + //destroy_surroundings = FALSE + vore_default_mode = DM_HEAL + vore_escape_chance = 75 + vore_standing_too = 1 + vore_pounce_chance = 100 + swallowTime = 4 SECONDS //A little longer to compensate for the above + vore_ignores_undigestable = FALSE + attacktext = list("shoved") + armor = list( + "melee" = 5, + "bullet" = 5, + "laser" = 5, + "energy" = 5, + "bomb" = 0, + "bio" = 100, + "rad" = 100) + + eye_desc = "blue eyes" + shy_approach = TRUE + stalker = TRUE + vore_stomach_flavor = "You slip past pointy triangle teeth and down the slick, \ + slippery gullet of the creature. It's warm, and the air is thick. You can hear its body \ + squelch and shift around you as you settle into its stomach! It's oddly calm, and very dark. \ + The doughy flesh rolls across your form in gentle waves. The aches and pains across your form slowly begin to \ + diminish, your body is healing much faster than normal! You're also soon soaked in harmless slime." + + player_msg = "You've chosen to generate your own energy rather than taking \ + it from others. Most of the time, anyway. You don't have a need to steal energy from others, and gather it up \ + without doing so, albeit slowly. Dark and light are irrelevant to you, they are just different places to explore and \ + discover new things and new people." + +/mob/living/simple_mob/shadekin/blue/white + icon_state = "white" +/mob/living/simple_mob/shadekin/blue/dark + icon_state = "dark" +/mob/living/simple_mob/shadekin/blue/brown + icon_state = "brown" + +///////////////////////////////////////////////////////////////// +/mob/living/simple_mob/shadekin/purple + name = "purple-eyed shadekin" + eye_state = PURPLE_EYES + health = 150 + //hostile = FALSE + //animal = TRUE + //stop_when_pulled = FALSE + //destroy_surroundings = TRUE + vore_default_mode = DM_HOLD + vore_digest_chance = 25 + vore_absorb_chance = 25 + armor = list( + "melee" = 15, + "bullet" = 15, + "laser" = 15, + "energy" = 15, + "bomb" = 15, + "bio" = 100, + "rad" = 100) + + eye_desc = "purple eyes" + shy_approach = TRUE + stalker = TRUE + vore_stomach_flavor = "You slip past pointy triangle teeth and down the slick, slippery gullet of the creature. \ + It's warm, and the air is thick. You can hear its body squelch and shift around you as you settle into its stomach! \ + It's relatively calm inside the dark organ. Wet and almost molten for how gooey your surroundings feel. \ + You can feel the doughy walls cling to you posessively... It's almost like you could sink into them. \ + There is also an ominous gurgling from somewhere nearby..." + + player_msg = "You're familiar with generating your own energy, but occasionally \ + steal it from others when it suits you. You generate energy at a moderate pace in dark areas, and staying in well-lit \ + areas is taxing on your energy. You can harvest energy from others in a fight, but since you don't need to, you may \ + just choose to simply not fight." + +/mob/living/simple_mob/shadekin/purple/white + icon_state = "white" +/mob/living/simple_mob/shadekin/purple/dark + icon_state = "dark" +/mob/living/simple_mob/shadekin/purple/brown + icon_state = "brown" + +///////////////////////////////////////////////////////////////// +/mob/living/simple_mob/shadekin/yellow + name = "yellow-eyed shadekin" + eye_state = YELLOW_EYES + health = 100 + //hostile = FALSE + //animal = TRUE + //stop_when_pulled = FALSE + //destroy_surroundings = TRUE + vore_default_mode = DM_DRAIN + vore_digest_chance = 5 + vore_ignores_undigestable = FALSE + armor = list( + "melee" = 5, + "bullet" = 5, + "laser" = 5, + "energy" = 5, + "bomb" = 0, + "bio" = 100, + "rad" = 100) + + eye_desc = "yellow eyes" + stalker = FALSE + vore_stomach_flavor = "You slip past pointy triangle teeth and down the slick, slippery gullet \ + of the creature. It's warm, and the air is thick. You can hear its body squelch and shift around you \ + as you settle into its stomach! The doughy walls within cling to you heavily, churning down on you, wearing \ + you out!! There doesn't appear to be any actual danger here, harmless slime clings to you, but it's getting \ + harder and harder to move as those walls press in on you insistently!" + + player_msg = "Your kind rarely ventures into realspace. Being in any well-lit \ + area is very taxing on you, but you gain energy extremely fast in any very dark area. You're weaker than other \ + shadekin, but your fast energy generation in the dark allows you to phase shift more often." + +/mob/living/simple_mob/shadekin/yellow/white + icon_state = "white" +/mob/living/simple_mob/shadekin/yellow/dark + icon_state = "dark" +/mob/living/simple_mob/shadekin/yellow/brown + icon_state = "brown" + +///////////////////////////////////////////////////////////////// +/mob/living/simple_mob/shadekin/green + name = "green-eyed shadekin" + eye_state = GREEN_EYES + health = 125 + //hostile = FALSE + //animal = TRUE + //stop_when_pulled = FALSE + //destroy_surroundings = TRUE + vore_default_mode = DM_DRAIN + vore_digest_chance = 0 + vore_ignores_undigestable = FALSE + armor = list( + "melee" = 5, + "bullet" = 5, + "laser" = 5, + "energy" = 5, + "bomb" = 0, + "bio" = 100, + "rad" = 100) + + eye_desc = "green eyes" + stalker = TRUE + vore_stomach_flavor = "You slip past pointy triangle teeth and down the slick, slippery gullet \ + of the creature. It's warm, and the air is thick. You can hear its body squelch and shift around you \ + as you settle into its stomach! The doughy walls within cling to you heavily, churning down on you, wearing \ + you out!! There doesn't appear to be any actual danger here, harmless slime clings to you, but it's getting \ + harder and harder to move as those walls press in on you insistently!" + + player_msg = "Your kind rarely ventures into realspace. Being in any well-lit area is very taxing on you, but you \ + have more experience than your yellow-eyed cousins. You gain energy decently fast in any very dark area. You're weaker than other \ + shadekin, but your slight energy generation constnatly, and especially in the dark allows for a good mix of uses." + +/mob/living/simple_mob/shadekin/green/white + icon_state = "white" +/mob/living/simple_mob/shadekin/green/dark + icon_state = "dark" +/mob/living/simple_mob/shadekin/green/brown + icon_state = "brown" + +///////////////////////////////////////////////////////////////// +/mob/living/simple_mob/shadekin/orange + name = "orange-eyed shadekin" + eye_state = ORANGE_EYES + health = 175 + //hostile = TRUE + //animal = TRUE + //stop_when_pulled = FALSE + //destroy_surroundings = TRUE + armor = list( + "melee" = 20, + "bullet" = 15, + "laser" = 15, + "energy" = 25, + "bomb" = 10, + "bio" = 100, + "rad" = 100) + + eye_desc = "orange eyes" + + vore_stomach_flavor = "You slip past pointy triangle teeth and down the slick, \ + slippery gullet of the creature. It's warm, and the air is thick. You can hear \ + its body squelch and shift around you as you settle into its stomach! Thick digestive \ + enzymes cling to you within that dark space, tingling and stinging immediately! The weight of \ + the doughy walls press in around you instantly, churning you up as you begin to digest!" + + player_msg = "You usually hunt for energy to fuel yourself, though not as often as your red-eyed cousins. \ + You're stronger than most shadekin, faster, and more capable in a brawl, but you don't generate much of your own energy. \ + You can stand in a dark spot to gather some energy, but otherwise need to take it, by force if necessary." + +/mob/living/simple_mob/shadekin/orange/white + icon_state = "white" +/mob/living/simple_mob/shadekin/orange/dark + icon_state = "dark" +/mob/living/simple_mob/shadekin/orange/brown + icon_state = "brown" + +///////////////////////////////////////////////////////////////// +//Fluffy specific fluffer +/mob/living/simple_mob/shadekin/blue/rivyr + name = "Rivyr" + desc = "She appears to be a fluffer of some sort. Deep blue eyes and curious attitude." + icon_state = "rivyr" + eye_desc = "" + vore_stomach_flavor = "Blue flesh gleams in the fading light as you slip down the little mar's gullet! \ + Gooey flesh and heat surrounds your form as you're tucked away into the darkness of her stomach! Thick slimes cling \ + to you, but they seem to be harmless. The organ gently churns around you, clinging to your shape and forcing \ + you to curl up a bit. You can feel her rub at you some through the layers of flesh and fluff, while aches \ + and pains begin to fade away across your body." + player_msg = "Mar? Mar mar. Mar mar mar. Mar. Mar mar? Mar! Mar. Marrrr." diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/~defines.dm b/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/~defines.dm new file mode 100644 index 0000000000..28ce75c50b --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/~defines.dm @@ -0,0 +1,11 @@ +#undef NOT_WHILE_SHIFTED +#undef ONLY_WHILE_SHIFTED +#undef SHIFTED_OR_NOT + +#undef BLUE_EYES +#undef RED_EYES +#undef PURPLE_EYES +#undef YELLOW_EYES + +#undef AB_PHASE_SHIFTED +#undef AB_SHADE_REGEN \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/snake.dm b/code/modules/mob/living/simple_mob/subtypes/vore/snake.dm new file mode 100644 index 0000000000..9c1b349ce5 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/vore/snake.dm @@ -0,0 +1,31 @@ +/mob/living/simple_mob/vore/giant_snake + name = "giant snake" + desc = "Snakes. Why did it have to be snakes?" + + icon_dead = "snake-dead" + icon_living = "snake" + icon_state = "snake" + icon = 'icons/mob/vore64x64.dmi' + + faction = "snake" + maxHealth = 200 + health = 200 + + melee_damage_lower = 10 + melee_damage_upper = 25 + + old_x = -16 + old_y = -16 + default_pixel_x = -16 + default_pixel_y = -16 + pixel_x = -16 + pixel_y = -16 + + ai_holder_type = /datum/ai_holder/simple_mob/melee + +// Activate Noms! +/mob/living/simple_mob/vore/giant_snake + vore_active = 1 + vore_pounce_chance = 25 + vore_icons = SA_ICON_LIVING + swallowTime = 2 SECONDS // Hungry little bastards. diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/solargrub.dm b/code/modules/mob/living/simple_mob/subtypes/vore/solargrub.dm new file mode 100644 index 0000000000..8444d55538 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/vore/solargrub.dm @@ -0,0 +1,108 @@ +/* +A work in progress, lore will go here later. +List of things solar grubs should be able to do: + +2. have three stages of growth depending on time. (Or energy drained altho that seems like a hard one to code) +3. be capable of eating people that get knocked out. (also be able to shock attackers that don’t wear insulated gloves.) +5. ((potentially use digested people to reproduce)) +6. add glow? +*/ + +#define SINK_POWER 1 + +/mob/living/simple_mob/animal/space/solargrub + name = "juvenile solargrub" + desc = "A young sparkling solargrub" + icon = 'icons/mob/vore.dmi' //all of these are placeholders + icon_state = "solargrub" + icon_living = "solargrub" + icon_dead = "solargrub-dead" + + faction = "grubs" + maxHealth = 50 //grubs can take a lot of harm + health = 50 + + melee_damage_lower = 1 + melee_damage_upper = 5 + + speed = 2 + + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/grubmeat + + response_help = "pokes" + response_disarm = "pushes" + response_harm = "roughly pushes" + + var/poison_per_bite = 5 //grubs cause a shock when they bite someone + var/poison_type = "shockchem" + var/poison_chance = 50 + var/datum/powernet/PN // Our powernet + var/obj/structure/cable/attached // the attached cable + var/emp_chance = 20 // Beware synths + +/datum/say_list/solargrub + emote_see = list("squelches", "squishes") +/* //Commented out pending reworks - 2/2/19 +/mob/living/simple_mob/animal/solargrub/PunchTarget() + if(target_mob&& prob(emp_chance)) + target_mob.emp_act(4) //The weakest strength of EMP + visible_message("The grub releases a powerful shock!") + ..() + +/mob/living/simple_mob/animal/solargrub/Life() + . = ..() + if(!. || ai_inactive) return + + if(stance == STANCE_IDLE) + //first, check for potential cables nearby to powersink + var/turf/S = loc + attached = locate() in S + if(attached) + if(prob(2)) + src.visible_message("\The [src] begins to sink power from the net.") + if(prob(5)) + var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread() + sparks.set_up(5, 0, get_turf(src)) + sparks.start() + anchored = 1 + PN = attached.powernet + PN.draw_power(100000) // previous value 150000 + var/apc_drain_rate = 750 //Going to see if grubs are better as a minimal bother. previous value : 4000 + for(var/obj/machinery/power/terminal/T in PN.nodes) + if(istype(T.master, /obj/machinery/power/apc)) + var/obj/machinery/power/apc/A = T.master + if(A.operating && A.cell) + var/cur_charge = A.cell.charge / CELLRATE + var/drain_val = min(apc_drain_rate, cur_charge) + A.cell.use(drain_val * CELLRATE) + else if(!attached && anchored) + anchored = 0 + PN = null +*/ +/mob/living/simple_mob/animal/solargrub //active noms + vore_bump_chance = 50 + vore_bump_emote = "applies minimal effort to try and slurp up" + vore_active = 1 + vore_capacity = 1 + vore_pounce_chance = 0 //grubs only eat incapacitated targets + vore_default_mode = DM_DIGEST +/* +/mob/living/simple_mob/animal/solargrub/PunchTarget() + . = ..() + if(isliving(.)) + var/mob/living/L = . + if(L.reagents) + if(prob(poison_chance)) + L << "You feel a shock rushing through your veins." + L.reagents.add_reagent(poison_type, poison_per_bite) */ + +/mob/living/simple_mob/animal/solargrub/death() + src.anchored = 0 + set_light(0) + ..() + +/mob/living/simple_mob/animal/solargrub/handle_light() + . = ..() + if(. == 0 && !is_dead()) + set_light(2.5, 1, COLOR_YELLOW) + return 1 diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/solargrub_larva.dm b/code/modules/mob/living/simple_mob/subtypes/vore/solargrub_larva.dm new file mode 100644 index 0000000000..898a3d2757 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/vore/solargrub_larva.dm @@ -0,0 +1,256 @@ +var/global/list/grub_machine_overlays = list() + +/mob/living/simple_mob/solargrub_larva + name = "solargrub larva" + desc = "A tiny wormy thing that can grow to massive sizes under the right conditions." + icon = 'icons/mob/vore.dmi' + icon_state = "grublarva" + icon_living = "grublarva" + icon_dead = "grublarva-dead" + + health = 5 + maxHealth = 5 + + meat_amount = 2 + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/grubmeat + + faction = "grubs" + + response_help = "pats" + response_disarm = "nudges" + response_harm = "stomps on" + + mob_size = MOB_MINISCULE + pass_flags = PASSTABLE + can_pull_size = ITEMSIZE_TINY + can_pull_mobs = MOB_PULL_NONE + density = 0 + + stop_when_pulled = 0 + + var/static/list/ignored_machine_types = list( + /obj/machinery/atmospherics/unary/vent_pump, + /obj/machinery/atmospherics/unary/vent_scrubber, + /obj/machinery/door/firedoor + ) + + var/obj/machinery/atmospherics/unary/vent_pump/target_vent + + var/datum/effect/effect/system/spark_spread/sparks + var/image/machine_effect + + var/obj/machinery/abstract_grub_machine/powermachine + var/power_drained = 0 + var/forced_out = 0 + +/mob/living/simple_mob/solargrub_larva/New() + ..() + powermachine = new(src) + sparks = new(src) + sparks.set_up() + sparks.attach(src) + verbs += /mob/living/proc/ventcrawl + +/mob/living/simple_mob/solargrub_larva/death() + powermachine.draining = 0 + set_light(0) + return ..() + +/mob/living/simple_mob/solargrub_larva/Destroy() + QDEL_NULL(powermachine) + QDEL_NULL(sparks) + QDEL_NULL(machine_effect) + target_vent = null + return ..() + +/mob/living/simple_mob/solargrub_larva/Life() + . = ..() + + if(machine_effect && !istype(loc, /obj/machinery)) + QDEL_NULL(machine_effect) + + if(!. || ai_inactive) + return + + if(power_drained >= 7 MEGAWATTS && prob(5)) + expand_grub() + return + + if(istype(loc, /obj/machinery)) + if(machine_effect && air_master.current_cycle%30) + for(var/mob/M in player_list) + M << machine_effect + if(prob(10)) + sparks.start() + return + + if(stance == STANCE_IDLE) + if(forced_out) + forced_out = Clamp(0, forced_out--, forced_out) + return + + if(target_vent) + if(Adjacent(target_vent)) + spawn() + do_ventcrawl(target_vent) + target_vent = null + else + target_vent = null + stop_automated_movement = 0 + walk(src, 0) + return + + if(prob(20)) + var/list/possible_machines = list() + for(var/obj/machinery/M in orange(1,src)) + if(!Adjacent(M)) + continue + if(istype(M, /obj/machinery/power/apc) || istype(M, /obj/machinery/power/smes)) //APCs and SMES units don't actually use power, but it's too thematic to ignore them + possible_machines += M + continue + if(is_type_in_list(M, ignored_machine_types)) + continue + if(!M.idle_power_usage && !M.active_power_usage) //If it can't use power at all, ignore it + continue + possible_machines += M + if(possible_machines.len) + enter_machine(pick(possible_machines)) + return + + if(prob(10)) + var/list/vents = list() + for(var/obj/machinery/atmospherics/unary/vent_pump/vent in view(7,src)) + if(vent.welded) + continue + vents += vent + if(vents.len) + var/picked = pick(vents) + target_vent = picked + WanderTowards(get_turf(picked)) + return + +/mob/living/simple_mob/solargrub_larva/proc/enter_machine(var/obj/machinery/M) + if(!istype(M)) + return + forceMove(M) + powermachine.draining = 2 + visible_message("\The [src] finds an opening and crawls inside \the [M].") + if(!(M.type in grub_machine_overlays)) + generate_machine_effect(M) + machine_effect = image(grub_machine_overlays[M.type], M) //Can't do this the reasonable way with an overlay, + for(var/mob/L in player_list) //because nearly every machine updates its icon by removing all overlays first + L << machine_effect + +/mob/living/simple_mob/solargrub_larva/proc/generate_machine_effect(var/obj/machinery/M) + var/icon/I = new /icon(M.icon, M.icon_state) + I.Blend(new /icon('icons/effects/blood.dmi', rgb(255,255,255)),ICON_ADD) + I.Blend(new /icon('icons/effects/alert.dmi', "_red"),ICON_MULTIPLY) + grub_machine_overlays[M.type] = I + +/mob/living/simple_mob/solargrub_larva/proc/eject_from_machine(var/obj/machinery/M) + if(!M) + if(istype(loc, /obj/machinery)) + M = loc + else + return + forceMove(get_turf(M)) + sparks.start() + if(machine_effect) + QDEL_NULL(machine_effect) + forced_out += rand(5,15) + powermachine.draining = 1 + +/mob/living/simple_mob/solargrub_larva/proc/do_ventcrawl(var/obj/machinery/atmospherics/unary/vent_pump/vent) + if(!vent) + return + var/obj/machinery/atmospherics/unary/vent_pump/end_vent = get_safe_ventcrawl_target(vent) + if(!end_vent) + return + forceMove(vent) + playsound(vent, 'sound/machines/ventcrawl.ogg', 50, 1, -3) + vent.visible_message("\The [src] wiggles into \the [vent]!") + var/redirect_attempts = 3 + while(redirect_attempts) + var/travel_time = round(get_dist(get_turf(src), get_turf(end_vent)) / 2) + sleep(travel_time) + if(end_vent.welded) + end_vent = get_safe_ventcrawl_target(vent) + if(!end_vent) + forceMove(get_turf(vent)) + return + redirect_attempts-- + continue + break + playsound(end_vent, 'sound/machines/ventcrawl.ogg', 50, 1, -3) + forceMove(get_turf(end_vent)) + +/mob/living/simple_mob/solargrub_larva/proc/expand_grub() + eject_from_machine() + visible_message("\The [src] suddenly balloons in size!") + new /mob/living/simple_mob/animal/solargrub(get_turf(src)) +// var/mob/living/simple_mob/animal/solargrub/grub = new(get_turf(src)) +// grub.power_drained = power_drained //TODO + qdel(src) + +/mob/living/simple_mob/solargrub_larva/handle_light() + . = ..() + if(. == 0 && !is_dead()) + set_light(1.5, 1, COLOR_YELLOW) + return 1 + + +/obj/machinery/abstract_grub_machine + var/total_active_power_usage = 45 KILOWATTS + var/list/active_power_usages = list(15 KILOWATTS, 15 KILOWATTS, 15 KILOWATTS) + var/total_idle_power_usage = 3 KILOWATTS + var/list/idle_power_usages = list(1 KILOWATTS, 1 KILOWATTS, 1 KILOWATTS) + var/draining = 1 + var/mob/living/simple_mob/solargrub_larva/grub + +/obj/machinery/abstract_grub_machine/New() + ..() + shuffle_power_usages() + grub = loc + if(!istype(grub)) + grub = null + qdel(src) + +/obj/machinery/abstract_grub_machine/Destroy() + grub = null + return ..() + +/obj/machinery/abstract_grub_machine/process() + if(!draining) + return + var/area/A = get_area(src) + if(!A) + return + var/list/power_list + switch(draining) + if(1) + power_list = idle_power_usages + if(2) + power_list = active_power_usages + for(var/i = 1 to power_list.len) + if(A.powered(i)) + use_power(power_list[i], i) + grub.power_drained += power_list[i] + if(prob(5)) + shuffle_power_usages() + +/obj/machinery/abstract_grub_machine/proc/shuffle_power_usages() + total_active_power_usage = rand(30 KILOWATTS, 60 KILOWATTS) + total_idle_power_usage = rand(1 KILOWATTS, 5 KILOWATTS) + active_power_usages = split_into_3(total_active_power_usage) + idle_power_usages = split_into_3(total_idle_power_usage) + + +/obj/item/device/multitool/afterattack(obj/O, mob/user, proximity) + if(proximity) + if(istype(O, /obj/machinery)) + var/mob/living/simple_mob/solargrub_larva/grub = locate() in O + if(grub) + grub.eject_from_machine(O) + to_chat(user, "You disturb a grub nesting in \the [O]!") + return + return ..() diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/wolf.dm b/code/modules/mob/living/simple_mob/subtypes/vore/wolf.dm new file mode 100644 index 0000000000..45e25e7ebe --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/vore/wolf.dm @@ -0,0 +1,24 @@ +/mob/living/simple_mob/vore/wolf + name = "grey wolf" + desc = "My, what big jaws it has!" + tt_desc = "Canis lupus" + + icon_dead = "wolf-dead" + icon_living = "wolf" + icon_state = "wolf" + icon = 'icons/mob/vore.dmi' + + movement_cooldown = 5 + + harm_intent_damage = 5 + melee_damage_lower = 10 + melee_damage_upper = 25 + + minbodytemp = 200 + + ai_holder_type = /datum/ai_holder/simple_mob/melee/evasive + +// Activate Noms! +/mob/living/simple_mob/vore/wolf + vore_active = 1 + vore_icons = SA_ICON_LIVING diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/wolfgirl.dm b/code/modules/mob/living/simple_mob/subtypes/vore/wolfgirl.dm new file mode 100644 index 0000000000..83930acf86 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/vore/wolfgirl.dm @@ -0,0 +1,67 @@ +/mob/living/simple_mob/vore/wolfgirl + name = "wolfgirl" + desc = "AwooOOOOoooo!" + tt_desc = "Homo lupus" + + icon_state = "wolfgirl" + icon_living = "wolfgirl" + icon_dead = "wolfgirl-dead" + icon = 'icons/mob/vore.dmi' + + faction = "wolfgirl" + maxHealth = 30 + health = 30 + + response_help = "pats the" + response_disarm = "gently pushes aside the" + response_harm = "hits the" + + harm_intent_damage = 8 + melee_damage_lower = 15 + melee_damage_upper = 15 + attacktext = list("slashed") + + say_list_type = /datum/say_list/wolfgirl + ai_holder_type = /datum/ai_holder/simple_mob/retaliate/cooperative/wolfgirl + + var/loopstop = 0 //To prevent circular awoooos. +/* +/mob/living/simple_mob/retaliate/wolfgirl/hear_say() + if(world.time - loopstop < 5 SECONDS) + return + else + loopstop = world.time + ..() +*/ +// Activate Noms! +/mob/living/simple_mob/vore/wolfgirl + vore_active = 1 + vore_pounce_chance = 40 + vore_icons = SA_ICON_LIVING + +/datum/ai_holder/simple_mob/retaliate/cooperative/wolfgirl/on_hear_say(mob/living/speaker, message) + + if(!speaker.client) + return + + if(findtext(message, "hello") || findtext(message, "hi") || findtext(message, "greetings")) + delayed_say(pick("Heya!", "Hey!"), speaker) + + if(findtext(message, "Are you a dog?")) + delayed_say(pick("Who, me?! No! Stop saying that!"), speaker) + + if(findtext(message, "Awoo?")) + delayed_say(pick("Awoo."), speaker) + + if(findtext(message, "Awoo!")) + delayed_say(pick("AwooooOOOOooo!"), speaker) + + if(findtext(message, "Awoo.")) + delayed_say(pick("Awoo?"), speaker) + +/datum/say_list/wolfgirl + speak = list("AwoooOOOOoooo!","Awoo~","I'll protect the forest! ... Where's the forest again?","All I need is my sword!","Awoo?","Anyone else smell that?") + emote_hear = list("awoooos!","hmms to herself","plays with her sword") + emote_see = list("narrows her eyes","sniffs the air") + say_maybe_target = list("An enemy!?","What was that?","Is that...?","Hmm?") + say_got_target = list("You won't get away!","I've had it!","I'll vanquish you!","AWOOOOO!") diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/zz_vore_overrides.dm b/code/modules/mob/living/simple_mob/subtypes/vore/zz_vore_overrides.dm new file mode 100644 index 0000000000..0c8d35e9d9 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/vore/zz_vore_overrides.dm @@ -0,0 +1,259 @@ +// +// This file overrides settings on upstream simple animals to turn on vore behavior +// + +/* +## For anything that previously inhertited from: /mob/living/simple_mob/hostile/vore ## + + vore_active = 1 + icon = 'icons/mob/vore.dmi' + +## For anything that previously inhertied from: /mob/living/simple_mob/hostile/vore/large ## + + vore_active = 1 + icon = 'icons/mob/vore64x64.dmi' + old_x = -16 + old_y = -16 + pixel_x = -16 + pixel_y = -16 + vore_pounce_chance = 50 +*/ + +// +// Okay! Here we go! +// + +/mob/living/simple_mob/animal/space/alien + vore_active = 1 + icon = 'icons/mob/vore.dmi' + icon_state = "xenohunter" + icon_living = "xenohunter" + icon_dead = "xenohunter-dead" + icon_gib = "gibbed-a" + vore_icons = SA_ICON_LIVING + +/mob/living/simple_mob/animal/space/alien/drone + vore_active = 1 + icon = 'icons/mob/vore.dmi' + icon_state = "xenodrone" + icon_living = "xenodrone" + icon_dead = "xenodrone-dead" + icon_gib = "gibbed-a" + vore_icons = SA_ICON_LIVING + +/mob/living/simple_mob/animal/space/alien/sentinel + vore_active = 1 + icon = 'icons/mob/vore.dmi' + icon_state = "xenosentinel" + icon_living = "xenosentinel" + icon_dead = "xenosentinel-dead" + icon_gib = "gibbed-a" + vore_icons = SA_ICON_LIVING + +/mob/living/simple_mob/animal/space/alien/queen + vore_active = 1 + icon = 'icons/mob/vore.dmi' + icon_state = "xenoqueen" + icon_living = "xenoqueen" + icon_dead = "xenoqueen-dead" + icon_gib = "gibbed-a" + vore_icons = SA_ICON_LIVING + +/mob/living/simple_mob/animal/space/alien/queen/empress + vore_active = 1 + icon = 'icons/mob/vore64x64.dmi' + icon_state = "queen_s" + icon_living = "queen_s" + icon_dead = "queen_dead" + vore_icons = SA_ICON_LIVING | SA_ICON_REST + old_x = -16 + old_y = 0 + default_pixel_x = -16 + pixel_x = -16 + pixel_y = 0 + + vore_capacity = 3 + vore_pounce_chance = 75 + +/mob/living/simple_mob/animal/space/alien/sentinel/praetorian + icon = 'icons/mob/vore64x64.dmi' + vore_icons = SA_ICON_LIVING | SA_ICON_REST + +/mob/living/simple_mob/animal/space/alien/queen/empress/mother + vore_icons = 0 // NO VORE SPRITES + +/mob/living/simple_mob/animal/space/bear + vore_active = 1 + icon = 'icons/mob/vore.dmi' + icon_state = "spacebear" + icon_living = "spacebear" + icon_dead = "spacebear-dead" + icon_gib = "bear-gib" + vore_icons = SA_ICON_LIVING + +/mob/living/simple_mob/hostile/bear/hudson + name = "Hudson" + +/mob/living/simple_mob/hostile/bear/brown + vore_active = 1 + icon = 'icons/mob/vore.dmi' + name = "brown bear" + icon_state = "brownbear" + icon_living = "brownbear" + icon_dead = "brownbear-dead" + icon_gib = "bear-gib" + vore_icons = SA_ICON_LIVING + +/mob/living/simple_mob/animal/space/carp + icon = 'icons/mob/vore.dmi' + vore_active = 1 + vore_icons = SA_ICON_LIVING + +/* //VOREStation AI Temporary removal +/mob/living/simple_mob/hostile/creature/vore + vore_active = 1 + // NO VORE SPRITES + vore_capacity = 0 + vore_pounce_chance = 0 // Only pounces if you're crit. + vore_escape_chance = 0 // As such, if you're a dibshit who feeds yourself to it, you're staying down. + // Overrides to non-vore version + speed = 4 // Slow it down a bit + health = 80 // Increase health to compensate + maxHealth = 80 +*/ + +/mob/living/simple_mob/animal/space/mimic + vore_active = 1 + // NO VORE SPRITES + vore_capacity = 0 + vore_pounce_chance = 33 + // Overrides to non-vore version + maxHealth = 60 + health = 60 + +/mob/living/simple_mob/animal/passive/cat + vore_active = 1 + // NO VORE SPRITES + //specific_targets = 0 // Targeting UNLOCKED //VOREStation Removal - Incompatable + vore_max_size = RESIZE_TINY + +/* //VOREStation AI Temporary removal +/mob/living/simple_mob/cat/PunchTarget() + if(istype(target_mob,/mob/living/simple_mob/mouse)) + visible_message("\The [src] pounces on \the [target_mob]!]") + target_mob.Stun(5) + return EatTarget() + else ..() + +/mob/living/simple_mob/cat/Found(var/atom/found_atom) + if(!SA_attackable(found_atom)) + return null + if(istype(found_atom,/mob/living/simple_mob/mouse)) + return found_atom + if(found_atom in friends) + return null + if(will_eat(found_atom)) + return found_atom + +/mob/living/simple_mob/cat/fluff/Found(var/atom/found_atom) + if (friend == found_atom) + return null + return ..() +*/ +/mob/living/simple_mob/cat/fluff + vore_ignores_undigestable = 0 + vore_pounce_chance = 100 + vore_digest_chance = 0 // just use the toggle + vore_default_mode = DM_HOLD //can use the toggle if you wanna be catfood + vore_standing_too = TRUE //gonna get pounced + +/* //VOREStation AI Temporary Removal +/mob/living/simple_mob/cat/fluff/EatTarget() + var/mob/living/TM = target_mob + prey_excludes += TM //so they won't immediately re-eat someone who struggles out (or gets newspapered out) as soon as they're ate + spawn(3600) // but if they hang around and get comfortable, they might get ate again + if(src && TM) + prey_excludes -= TM + ..() // will_eat check is carried out before EatTarget is called, so prey on the prey_excludes list isn't a problem. +*/ + +/mob/living/simple_mob/animal/fox_vr + vore_active = 1 + // NO VORE SPRITES + vore_max_size = RESIZE_TINY + +/* //VOREStation AI Temporary Removal +/mob/living/simple_mob/fox/PunchTarget() + if(istype(target_mob,/mob/living/simple_mob/mouse)) + return EatTarget() + else ..() + +/mob/living/simple_mob/fox/Found(var/atom/found_atom) + if(!SA_attackable(found_atom)) + return null + if(istype(found_atom,/mob/living/simple_mob/mouse)) + return found_atom + if(found_atom in friends) + return null + if(will_eat(found_atom)) + return found_atom + +/mob/living/simple_mob/fox/fluff/Found(var/atom/found_atom) + if (friend == found_atom) + return null + return ..() +*/ + +/mob/living/simple_mob/fox/fluff + vore_ignores_undigestable = 0 + vore_pounce_chance = 100 + vore_digest_chance = 0 // just use the toggle + vore_default_mode = DM_HOLD //can use the toggle if you wanna be foxfood + vore_standing_too = TRUE // gonna get pounced + +/* //VOREStation AI Temporary Removal +/mob/living/simple_mob/fox/fluff/EatTarget() + var/mob/living/TM = target_mob + prey_excludes += TM //so they won't immediately re-eat someone who struggles out (or gets newspapered out) as soon as they're ate + spawn(3600) // but if they hang around and get comfortable, they might get ate again + if(src && TM) + prey_excludes -= TM + ..() // will_eat check is carried out before EatTarget is called, so prey on the prey_excludes list isn't a problem. +*/ + +/mob/living/simple_mob/animal/space/goose + vore_active = 1 + // NO VORE SPRITES + vore_max_size = RESIZE_SMALL + +/mob/living/simple_mob/animal/passive/penguin + vore_active = 1 + // NO VORE SPRITES + vore_max_size = RESIZE_SMALL + + +/mob/living/simple_mob/hostile/carp/pike + vore_active = 1 + // NO VORE SPRITES + +/mob/living/simple_mob/animal/space/carp/holographic + vore_icons = 0 // NO VORE SPRITES + vore_digest_chance = 0 + vore_absorb_chance = 0 + +// Override stuff for holodeck carp to make them not digest when set to safe! +/mob/living/simple_mob/animal/space/carp/holographic/init_vore() + . = ..() + var/safe = (faction == "neutral") + for(var/belly in vore_organs) + var/obj/belly/B = belly + B.digest_mode = safe ? DM_HOLD : vore_default_mode + +/mob/living/simple_mob/animal/space/carp/holographic/set_safety(var/safe) + . = ..() + for(var/belly in vore_organs) + var/obj/belly/B = belly + B.digest_mode = safe ? DM_HOLD : vore_default_mode + +/mob/living/simple_mob/mouse + faction = "mouse" //Giving mice a faction so certain mobs can get along with them. \ No newline at end of file diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index 8471dd8307..0658115106 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -71,4 +71,7 @@ if(!client.tooltips) client.tooltips = new(client) - \ No newline at end of file + + var/turf/T = get_turf(src) + if(isturf(T)) + update_client_z(T.z) \ No newline at end of file diff --git a/code/modules/mob/logout.dm b/code/modules/mob/logout.dm index b204a3109b..6ad5f542a3 100644 --- a/code/modules/mob/logout.dm +++ b/code/modules/mob/logout.dm @@ -1,7 +1,7 @@ /mob/Logout() - GLOB.nanomanager.user_logout(src) // this is used to clean up (remove) this user's Nano UIs + SSnanoui.user_logout(src) // this is used to clean up (remove) this user's Nano UIs player_list -= src - disconnect_time = world.realtime + update_client_z(null) log_access_out(src) if(admin_datums[src.ckey]) if (ticker && ticker.current_state == GAME_STATE_PLAYING) //Only report this stuff if we are currently playing. diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index c7c0c9a253..a6965a7f16 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1,4 +1,4 @@ -/mob/Destroy()//This makes sure that mobs with clients/keys are not just deleted from the game. +/mob/Destroy()//This makes sure that mobs withGLOB.clients/keys are not just deleted from the game. mob_list -= src dead_mob_list -= src living_mob_list -= src @@ -39,7 +39,7 @@ spell_masters = null zone_sel = null -/mob/New() +/mob/Initialize() mob_list += src if(stat == DEAD) dead_mob_list += src @@ -47,7 +47,7 @@ living_mob_list += src hook_vr("mob_new",list(src)) //VOREStation Code update_transform() // Some mobs may start bigger or smaller than normal. - ..() + return ..() /mob/proc/show_message(msg, type, alt, alt_type)//Message, type of message (1 or 2), alternative message, alt message type (1 or 2) @@ -672,25 +672,35 @@ . = (is_client_active(10 MINUTES)) if(.) - if(statpanel("Status") && ticker && ticker.current_state != GAME_STATE_PREGAME) - stat("Station Time", stationtime2text()) - stat("Station Date", stationdate2text()) - stat("Round Duration", roundduration2text()) + if(statpanel("Status")) + stat(null, "Time Dilation: [round(SStime_track.time_dilation_current,1)]% AVG:([round(SStime_track.time_dilation_avg_fast,1)]%, [round(SStime_track.time_dilation_avg,1)]%, [round(SStime_track.time_dilation_avg_slow,1)]%)") + if(ticker && ticker.current_state != GAME_STATE_PREGAME) + stat("Station Time", stationtime2text()) + stat("Station Date", stationdate2text()) + stat("Round Duration", roundduration2text()) if(client.holder) if(statpanel("Status")) stat("Location:", "([x], [y], [z]) [loc]") stat("CPU:","[world.cpu]") stat("Instances:","[world.contents.len]") + stat(null, "Time Dilation: [round(SStime_track.time_dilation_current,1)]% AVG:([round(SStime_track.time_dilation_avg_fast,1)]%, [round(SStime_track.time_dilation_avg,1)]%, [round(SStime_track.time_dilation_avg_slow,1)]%)") if(statpanel("Processes")) if(processScheduler) processScheduler.statProcesses() if(statpanel("MC")) + stat("Location:", "([x], [y], [z]) [loc]") stat("CPU:","[world.cpu]") stat("Instances:","[world.contents.len]") + stat("World Time:", world.time) + stat("Real time of day:", REALTIMEOFDAY) stat(null) + if(GLOB) + GLOB.stat_entry() + else + stat("Globals:", "ERROR") if(Master) Master.stat_entry() else @@ -703,10 +713,18 @@ stat(null) for(var/datum/controller/subsystem/SS in Master.subsystems) SS.stat_entry() - + if(statpanel("Tickets")) GLOB.ahelp_tickets.stat_entry() + + if(length(GLOB.sdql2_queries)) + if(statpanel("SDQL2")) + stat("Access Global SDQL2 List", GLOB.sdql2_vv_statobj) + for(var/i in GLOB.sdql2_queries) + var/datum/SDQL2_query/Q = i + Q.generate_stat() + if(listed_turf && client) if(!TurfAdjacent(listed_turf)) listed_turf = null @@ -743,13 +761,12 @@ /mob/proc/facedir(var/ndir) - if(!canface() || (client && (client.moving || (world.time < client.move_delay)))) + if(!canface() || (client && (client.moving || (world.time < move_delay)))) return 0 set_dir(ndir) if(buckled && buckled.buckle_movable) buckled.set_dir(ndir) - if(client) - client.move_delay += movement_delay() + move_delay += movement_delay() return 1 @@ -885,10 +902,10 @@ return /mob/proc/AdjustLosebreath(amount) - losebreath = Clamp(0, losebreath + amount, 25) + losebreath = CLAMP(0, losebreath + amount, 25) /mob/proc/SetLosebreath(amount) - losebreath = Clamp(0, amount, 25) + losebreath = CLAMP(0, amount, 25) /mob/proc/get_species() return "" @@ -1002,7 +1019,7 @@ mob/proc/yank_out_object() /mob/proc/has_brain_worms() for(var/I in contents) - if(istype(I,/mob/living/simple_animal/borer)) + if(istype(I,/mob/living/simple_mob/animal/borer)) return I return 0 @@ -1177,3 +1194,19 @@ mob/proc/yank_out_object() closeToolTip(usr) //No reason not to, really ..() + +// Manages a global list of mobs with clients attached, indexed by z-level. +/mob/proc/update_client_z(new_z) // +1 to register, null to unregister. + if(registered_z != new_z) + if(registered_z) + GLOB.players_by_zlevel[registered_z] -= src + if(client) + if(new_z) + GLOB.players_by_zlevel[new_z] += src + registered_z = new_z + else + registered_z = null + +/mob/onTransitZ(old_z, new_z) + ..() + update_client_z(new_z) diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 32902d7d48..4ff683dc7a 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -7,6 +7,8 @@ var/datum/mind/mind var/stat = 0 //Whether a mob is alive or dead. TODO: Move this to living - Nodrak + var/move_delay = null // For movement speed delays. + var/next_move = null // For click delay, despite the misleading name. //Not in use yet var/obj/effect/organstructure/organStructure = null @@ -62,7 +64,6 @@ var/sdisabilities = 0 //Carbon var/disabilities = 0 //Carbon var/atom/movable/pulling = null - var/next_move = null var/transforming = null //Carbon var/other = 0.0 var/eye_blind = null //Carbon @@ -231,3 +232,5 @@ var/attack_icon //Icon to use when attacking w/o anything in-hand var/attack_icon_state //State for above + + var/registered_z diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index 0bf523a48e..b335faf1d3 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -382,7 +382,7 @@ //It's easier to break out of a grab by a smaller mob break_strength += max(size_difference(affecting, assailant), 0) - var/break_chance = break_chance_table[Clamp(break_strength, 1, break_chance_table.len)] + var/break_chance = break_chance_table[CLAMP(break_strength, 1, break_chance_table.len)] if(prob(break_chance)) if(state == GRAB_KILL) reset_kill_state() diff --git a/code/modules/mob/mob_grab_specials.dm b/code/modules/mob/mob_grab_specials.dm index a497bd0cc5..a3e4c14660 100644 --- a/code/modules/mob/mob_grab_specials.dm +++ b/code/modules/mob/mob_grab_specials.dm @@ -61,7 +61,7 @@ target << "You feel extreme pain!" var/max_halloss = round(target.species.total_health * 0.8) //up to 80% of passing out - affecting.adjustHalLoss(Clamp(0, max_halloss - affecting.halloss, 30)) + affecting.adjustHalLoss(CLAMP(0, max_halloss - affecting.halloss, 30)) /obj/item/weapon/grab/proc/attack_eye(mob/living/carbon/human/target, mob/living/carbon/human/attacker) if(!istype(attacker)) diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 186487d0b9..6c31f54f8e 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -54,6 +54,9 @@ proc/isdeaf(A) /mob/proc/break_cloak() return +/mob/proc/is_cloaked() + return FALSE + proc/hasorgans(A) // Fucking really?? return ishuman(A) @@ -534,19 +537,17 @@ proc/is_blind(A) return threatcount -/mob/living/simple_animal/assess_perp(var/obj/access_obj, var/check_access, var/auth_weapons, var/check_records, var/check_arrest) +/mob/living/simple_mob/assess_perp(var/obj/access_obj, var/check_access, var/auth_weapons, var/check_records, var/check_arrest) var/threatcount = ..() if(. == SAFE_PERP) return SAFE_PERP - if(!istype(src, /mob/living/simple_animal/retaliate/goat)) - if(hostile) - if(faction != "neutral") // Otherwise Runtime gets killed. - threatcount += 4 + if(has_AI() && ai_holder.hostile && faction != "neutral") // Otherwise Runtime gets killed. + threatcount += 4 return threatcount // Beepsky will (try to) only beat 'bad' slimes. -/mob/living/simple_animal/slime/assess_perp(var/obj/access_obj, var/check_access, var/auth_weapons, var/check_records, var/check_arrest) +/mob/living/simple_mob/slime/xenobio/assess_perp(var/obj/access_obj, var/check_access, var/auth_weapons, var/check_records, var/check_arrest) var/threatcount = 0 if(stat == DEAD) @@ -565,8 +566,10 @@ proc/is_blind(A) if(victim) threatcount += 4 */ - if(rabid) - threatcount = 10 + if(has_AI()) + var/datum/ai_holder/simple_mob/xenobio_slime/AI = ai_holder + if(AI.rabid) + threatcount = 10 return threatcount diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 6b65c81c84..45259a1444 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -8,27 +8,14 @@ return (!mover.density || !density || lying) else return (!mover.density || !density || lying) - return /mob/proc/setMoveCooldown(var/timeout) - if(client) - client.move_delay = max(world.time + timeout, client.move_delay) - -/client/North() - ..() - - -/client/South() - ..() - - -/client/West() - ..() - - -/client/East() - ..() + move_delay = max(world.time + timeout, move_delay) +/mob/proc/check_move_cooldown() + if(world.time < src.move_delay) + return FALSE // Need to wait more. + return TRUE /client/proc/client_dir(input, direction=-1) return turn(input, direction*dir2angle(dir)) @@ -122,60 +109,6 @@ */ return -//This proc should never be overridden elsewhere at /atom/movable to keep directions sane. -/atom/movable/Move(newloc, direct) - if (direct & (direct - 1)) - if (direct & 1) - if (direct & 4) - if (step(src, NORTH)) - step(src, EAST) - else - if (step(src, EAST)) - step(src, NORTH) - else - if (direct & 8) - if (step(src, NORTH)) - step(src, WEST) - else - if (step(src, WEST)) - step(src, NORTH) - else - if (direct & 2) - if (direct & 4) - if (step(src, SOUTH)) - step(src, EAST) - else - if (step(src, EAST)) - step(src, SOUTH) - else - if (direct & 8) - if (step(src, SOUTH)) - step(src, WEST) - else - if (step(src, WEST)) - step(src, SOUTH) - else - var/atom/A = src.loc - - var/olddir = dir //we can't override this without sacrificing the rest of movable/New() - . = ..() - if(direct != olddir) - dir = olddir - set_dir(direct) - - src.move_speed = world.time - src.l_move_time - src.l_move_time = world.time - src.m_flag = 1 - if ((A != src.loc && A && A.z == src.z)) - src.last_move = get_dir(A, src.loc) - if(.) - Moved(A, direct) - return - -// Called on a successful Move(). -/atom/movable/proc/Moved(atom/oldloc) - return - /client/proc/Move_object(direct) if(mob && mob.control_object) if(mob.control_object.density) @@ -199,7 +132,8 @@ if(moving) return 0 - if(world.time < move_delay) return + if(!mob.check_move_cooldown()) + return if(locate(/obj/effect/stop/, mob.loc)) for(var/obj/effect/stop/S in mob.loc) @@ -271,21 +205,21 @@ src << "You're pinned to a wall by [mob.pinned[1]]!" return 0 - move_delay = world.time//set move delay + mob.move_delay = world.time//set move delay switch(mob.m_intent) if("run") if(mob.drowsyness > 0) - move_delay += 6 - move_delay += config.run_speed + mob.move_delay += 6 + mob.move_delay += config.run_speed if("walk") - move_delay += config.walk_speed - move_delay += mob.movement_delay() + mob.move_delay += config.walk_speed + mob.move_delay += mob.movement_delay() if(istype(mob.buckled))// VOREStation Removal - , /obj/vehicle)) //manually set move_delay for vehicles so we don't inherit any mob movement penalties //specific vehicle move delays are set in code\modules\vehicles\vehicle.dm - move_delay = world.time + mob.move_delay = world.time //drunk driving if(mob.confused && prob(20)) //vehicles tend to keep moving in the same direction direct = turn(direct, pick(90, -90)) @@ -314,14 +248,14 @@ if(prob(50)) direct = turn(direct, pick(90, -90)) if("walk") if(prob(25)) direct = turn(direct, pick(90, -90)) - move_delay += 2 + mob.move_delay += 2 return mob.buckled.relaymove(mob,direct) //We are now going to move moving = 1 //Something with pulling things if(locate(/obj/item/weapon/grab, mob)) - move_delay = max(move_delay, world.time + 7) + mob.move_delay = max(mob.move_delay, world.time + 7) var/list/L = mob.ret_grab() if(istype(L, /list)) if(L.len == 2) @@ -572,4 +506,4 @@ /client/verb/moveleft() set name = ".moveleft" set instant = 1 - Move(get_step(mob, WEST), WEST) \ No newline at end of file + Move(get_step(mob, WEST), WEST) diff --git a/code/modules/mob/mob_planes.dm b/code/modules/mob/mob_planes.dm index e1cb3a16c3..2ba47421a4 100644 --- a/code/modules/mob/mob_planes.dm +++ b/code/modules/mob/mob_planes.dm @@ -44,7 +44,7 @@ /datum/plane_holder/Destroy() my_mob = null - QDEL_NULL_LIST(plane_masters) //Goodbye my children, be free + QDEL_LIST_NULL(plane_masters) //Goodbye my children, be free return ..() /datum/plane_holder/proc/set_vis(var/which = null, var/state = FALSE) diff --git a/code/modules/mob/new_player/login.dm b/code/modules/mob/new_player/login.dm index 34a540ac45..aef78c28ec 100644 --- a/code/modules/mob/new_player/login.dm +++ b/code/modules/mob/new_player/login.dm @@ -7,7 +7,7 @@ var/obj/effect/lobby_image = new /obj/effect/lobby_image desc = "How are you reading this?" screen_loc = "1,1" -/obj/effect/lobby_image/initialize() +/obj/effect/lobby_image/Initialize() icon = using_map.lobby_icon var/known_icon_states = icon_states(icon) for(var/lobby_screen in using_map.lobby_screens) diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index ea27828385..4b2f7350ed 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -121,7 +121,7 @@ var/mob/living/carbon/human/dummy/mannequin = new() client.prefs.dress_preview_mob(mannequin) var/mob/observer/dead/observer = new(mannequin) - observer.forceMove(null) //Let's not stay in our doomed mannequin + observer.moveToNullspace() //Let's not stay in our doomed mannequin qdel(mannequin) spawning = 1 diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm index 15e16d912b..8260a67a9c 100644 --- a/code/modules/mob/new_player/preferences_setup.dm +++ b/code/modules/mob/new_player/preferences_setup.dm @@ -251,6 +251,7 @@ var/mob/living/carbon/human/dummy/mannequin/mannequin = get_mannequin(client_ckey) mannequin.delete_inventory(TRUE) dress_preview_mob(mannequin) + COMPILE_OVERLAYS(mannequin) preview_icon = icon('icons/effects/128x48.dmi', bgstate) preview_icon.Scale(48+32, 16+32) diff --git a/code/modules/mob/new_player/sprite_accessories.dm b/code/modules/mob/new_player/sprite_accessories.dm index 3a0499b7b2..73ce4ca04b 100644 --- a/code/modules/mob/new_player/sprite_accessories.dm +++ b/code/modules/mob/new_player/sprite_accessories.dm @@ -49,6 +49,22 @@ var/icon_add = 'icons/mob/human_face.dmi' var/flags + eighties + name = "80's" + icon_state = "hair_80s" + + afro + name = "Afro" + icon_state = "hair_afro" + + afro2 + name = "Afro 2" + icon_state = "hair_afro2" + + afro_large + name = "Big Afro" + icon_state = "hair_bigafro" + bald name = "Bald" icon_state = "bald" @@ -56,24 +72,165 @@ flags = HAIR_VERY_SHORT species_allowed = list(SPECIES_HUMAN,SPECIES_UNATHI,SPECIES_PROMETHEAN,SPECIES_HUMAN_VATBORN,SPECIES_VOX) - short - name = "Short Hair" // try to capatilize the names please~ - icon_state = "hair_a" // you do not need to define _s or _l sub-states, game automatically does this for you + baldfade + name = "Balding Fade" + icon_state = "hair_baldfade" + gender = MALE flags = HAIR_VERY_SHORT - short2 - name = "Short Hair 2" - icon_state = "hair_shorthair3" + balding + name = "Balding Hair" + icon_state = "hair_e" + gender = MALE flags = HAIR_VERY_SHORT - short3 - name = "Short Hair 3" - icon_state = "hair_shorthair4" + bedhead + name = "Bedhead" + icon_state = "hair_bedhead" + + bedhead2 + name = "Bedhead 2" + icon_state = "hair_bedheadv2" + + bedhead3 + name = "Bedhead 3" + icon_state = "hair_bedheadv3" + flags = HAIR_TIEABLE + + bedheadlong + name = "Bedhead Long" + icon_state = "hair_long_bedhead" + flags = HAIR_TIEABLE + + beehive + name = "Beehive" + icon_state = "hair_beehive" + flags = HAIR_TIEABLE + + beehive2 + name = "Beehive 2" + icon_state = "hair_beehive2" + flags = HAIR_TIEABLE + + belenko + name = "Belenko" + icon_state = "hair_belenko" + flags = HAIR_TIEABLE + + belenkotied + name = "Belenko Tied" + icon_state = "hair_belenkotied" + flags = HAIR_TIEABLE + + bob + name = "Bob" + icon_state = "hair_bobcut" + species_allowed = list(SPECIES_HUMAN,SPECIES_PROMETHEAN,SPECIES_HUMAN_VATBORN,SPECIES_UNATHI) + flags = HAIR_TIEABLE + + bobcutalt + name = "Bob Chin Length" + icon_state = "hair_bobcutalt" + flags = HAIR_TIEABLE + + bobcurl + name = "Bobcurl" + icon_state = "hair_bobcurl" + species_allowed = list(SPECIES_HUMAN,SPECIES_PROMETHEAN,SPECIES_HUMAN_VATBORN,SPECIES_UNATHI) + flags = HAIR_TIEABLE + + bowl + name = "Bowl" + icon_state = "hair_bowlcut" + + bowlcut2 + name = "Bowl 2" + icon_state = "hair_bowlcut2" + + grandebraid + name = "Braid Grande" + icon_state = "hair_grande" + flags = HAIR_TIEABLE + + braid2 + name = "Braid Long" + icon_state = "hair_hbraid" + flags = HAIR_TIEABLE + + mbraid + name = "Braid Medium" + icon_state = "hair_shortbraid" + flags = HAIR_TIEABLE + + braid + name = "Braid Floorlength" + icon_state = "hair_braid" + flags = HAIR_TIEABLE + + bun + name = "Bun" + icon_state = "hair_bun" + + bun2 + name = "Bun 2" + icon_state = "hair_bun2" + + bun3 + name = "Bun 3" + icon_state = "hair_bun3" + + bun + name = "Bun Casual" + icon_state = "hair_bun" + flags = HAIR_TIEABLE + + doublebun + name = "Bun Double" + icon_state = "hair_doublebun" + flags = HAIR_TIEABLE + + tightbun + name = "Bun Tight" + icon_state = "hair_tightbun" + gender = FEMALE + flags = HAIR_VERY_SHORT | HAIR_TIEABLE + + buzz + name = "Buzzcut" + icon_state = "hair_buzzcut" + flags = HAIR_VERY_SHORT + species_allowed = list(SPECIES_HUMAN,SPECIES_PROMETHEAN,SPECIES_HUMAN_VATBORN,SPECIES_UNATHI) + + crono + name = "Chrono" + icon_state = "hair_toriyama" + + cia + name = "CIA" + icon_state = "hair_cia" + + coffeehouse + name = "Coffee House Cut" + icon_state = "hair_coffeehouse" + gender = MALE flags = HAIR_VERY_SHORT - twintail - name = "Twintail" - icon_state = "hair_twintail" + combover + name = "Combover" + icon_state = "hair_combover" + + country + name = "Country" + icon_state = "hair_country" + + crew + name = "Crewcut" + icon_state = "hair_crewcut" + flags = HAIR_VERY_SHORT + + curls + name = "Curls" + icon_state = "hair_curls" flags = HAIR_TIEABLE cut @@ -81,16 +238,175 @@ icon_state = "hair_c" flags = HAIR_VERY_SHORT + dave + name = "Dave" + icon_state = "hair_dave" + + devillock + name = "Devil Lock" + icon_state = "hair_devilock" + + dreadlocks + name = "Dreadlocks" + icon_state = "hair_dreads" + + mahdrills + name = "Drillruru" + icon_state = "hair_drillruru" + + emo + name = "Emo" + icon_state = "hair_emo" + + emo2 + name = "Emo Alt" + icon_state = "hair_emo2" + + fringeemo + name = "Emo Fringe" + icon_state = "hair_emofringe" + flags = HAIR_TIEABLE + + halfshaved + name = "Emo Half-Shaved" + icon_state = "hair_halfshaved" + + longemo + name = "Emo Long" + icon_state = "hair_emolong" + flags = HAIR_TIEABLE + + highfade + name = "Fade High" + icon_state = "hair_highfade" + gender = MALE + flags = HAIR_VERY_SHORT + + medfade + name = "Fade Medium" + icon_state = "hair_medfade" + flags = HAIR_VERY_SHORT + + lowfade + name = "Fade Low" + icon_state = "hair_lowfade" + gender = MALE + flags = HAIR_VERY_SHORT + + partfade + name = "Fade Parted" + icon_state = "hair_shavedpart" + gender = MALE + flags = HAIR_VERY_SHORT + + familyman + name = "Family Man" + icon_state = "hair_thefamilyman" + + father + name = "Father" + icon_state = "hair_father" + + feather + name = "Feather" + icon_state = "hair_feather" + flags = HAIR_TIEABLE + flair name = "Flaired Hair" icon_state = "hair_flair" flags = HAIR_TIEABLE - long - name = "Shoulder-length Hair" - icon_state = "hair_b" + sargeant + name = "Flat Top" + icon_state = "hair_sargeant" + flags = HAIR_VERY_SHORT + + flowhair + name = "Flow Hair" + icon_state = "hair_f" + + longfringe + name = "Fringe Long" + icon_state = "hair_longfringe" flags = HAIR_TIEABLE + longestalt + name = "Fringe Longer" + icon_state = "hair_vlongfringe" + flags = HAIR_TIEABLE + + fringetail + name = "Fringetail" + icon_state = "hair_fringetail" + flags = HAIR_TIEABLE|HAIR_VERY_SHORT + + gelled + name = "Gelled Back" + icon_state = "hair_gelled" + + gentle + name = "Gentle" + icon_state = "hair_gentle" + flags = HAIR_TIEABLE + + glossy + name = "Glossy" + icon_state = "hair_glossy" + flags = HAIR_TIEABLE + + halfbang + name = "Half-banged Hair" + icon_state = "hair_halfbang" + + halfbangalt + name = "Half-banged Hair Alt" + icon_state = "hair_halfbang_alt" + + hightight + name = "High and Tight" + icon_state = "hair_hightight" + flags = HAIR_VERY_SHORT + + himecut + name = "Hime Cut" + icon_state = "hair_himecut" + flags = HAIR_TIEABLE + + shorthime + name = "Hime Cut Short" + icon_state = "hair_shorthime" + flags = HAIR_TIEABLE + + hitop + name = "Hitop" + icon_state = "hair_hitop" + + jade + name = "Jade" + icon_state = "hair_jade" + + jensen + name = "Jensen" + icon_state = "hair_jensen" + + joestar + name = "Joestar" + icon_state = "hair_joestar" + + kagami + name = "Kagami" + icon_state = "hair_kagami" + flags = HAIR_TIEABLE + + kusangi + name = "Kusanagi Hair" + icon_state = "hair_kusanagi" + + long + name = "Long Hair Shoulder-length" + icon_state = "hair_b" + flags = HAIR_TIEABLE /* longish name = "Longer Hair" @@ -112,23 +428,97 @@ icon_state = "hair_longest" flags = HAIR_TIEABLE - longfringe - name = "Long Fringe" - icon_state = "hair_longfringe" + manbun + name = "Manbun" + icon_state = "hair_manbun" flags = HAIR_TIEABLE - longestalt - name = "Longer Fringe" - icon_state = "hair_vlongfringe" + modern + name = "Modern" + icon_state = "hair_modern" + + mohawk + name = "Mohawk" + icon_state = "hair_d" + species_allowed = list(SPECIES_HUMAN,SPECIES_PROMETHEAN,SPECIES_HUMAN_VATBORN,SPECIES_UNATHI) + + regulationmohawk + name = "Mohawk Regulation" + icon_state = "hair_shavedmohawk" + flags = HAIR_VERY_SHORT + + reversemohawk + name = "Mohawk Reverse" + icon_state = "hair_reversemohawk" + + mohawkunshaven + name = "Mohawk Unshaven" + icon_state = "hair_unshaven_mohawk" + + mulder + name = "Mulder" + icon_state = "hair_mulder" + + newyou + name = "New You" + icon_state = "hair_newyou" flags = HAIR_TIEABLE - halfbang - name = "Half-banged Hair" - icon_state = "hair_halfbang" + nia + name = "Nia" + icon_state = "hair_nia" - halfbangalt - name = "Half-banged Hair Alt" - icon_state = "hair_halfbang_alt" + nitori + name = "Nitori" + icon_state = "hair_nitori" + flags = HAIR_TIEABLE + + odango + name = "Odango" + icon_state = "hair_odango" + flags = HAIR_TIEABLE + + ombre + name = "Ombre" + icon_state = "hair_ombre" + flags = HAIR_TIEABLE + + oxton + name = "Oxton" + icon_state = "hair_oxton" + + longovereye + name = "Overeye Long" + icon_state = "hair_longovereye" + flags = HAIR_TIEABLE + + shortovereye + name = "Overeye Short" + icon_state = "hair_shortovereye" + + veryshortovereyealternate + name = "Overeye Very Short, Alternate" + icon_state = "hair_veryshortovereyealternate" + + veryshortovereye + name = "Overeye Very Short" + icon_state = "hair_veryshortovereye" + + parted + name = "Parted" + icon_state = "hair_parted" + + partedalt + name = "Parted Alt" + icon_state = "hair_partedalt" + + pompadour + name = "Pompadour" + icon_state = "hair_pompadour" + + dandypomp + name = "Pompadour Dandy" + icon_state = "hair_dandypompadour" ponytail1 name = "Ponytail 1" @@ -160,10 +550,101 @@ icon_state = "hair_ponytail6" flags = HAIR_TIEABLE|HAIR_VERY_SHORT - fringetail - name = "Fringetail" - icon_state = "hair_fringetail" - flags = HAIR_TIEABLE|HAIR_VERY_SHORT + sharpponytail + name = "Ponytail Sharp" + icon_state = "hair_sharpponytail" + flags = HAIR_TIEABLE + + spikyponytail + name = "Ponytail Spiky" + icon_state = "hair_spikyponytail" + flags = HAIR_TIEABLE + + poofy + name = "Poofy" + icon_state = "hair_poofy" + flags = HAIR_TIEABLE + + poofy2 + name = "Poofy 2" + icon_state = "hair_poofy2" + flags = HAIR_TIEABLE + + quiff + name = "Quiff" + icon_state = "hair_quiff" + + nofade + name = "Regulation Cut" + icon_state = "hair_nofade" + gender = MALE + flags = HAIR_VERY_SHORT + + ronin + name = "Ronin" + icon_state = "hair_ronin" + flags = HAIR_TIEABLE + + rosa + name = "Rosa" + icon_state = "hair_rosa" + + rows + name = "Rows" + icon_state = "hair_rows1" + flags = HAIR_VERY_SHORT + + rows2 + name = "Rows 2" + icon_state = "hair_rows2" + flags = HAIR_TIEABLE + + rowbun + name = "Row Bun" + icon_state = "hair_rowbun" + flags = HAIR_TIEABLE + + rowdualbraid + name = "Row Dual Braid" + icon_state = "hair_rowdualtail" + flags = HAIR_TIEABLE + + rowbraid + name = "Row Braid" + icon_state = "hair_rowbraid" + flags = HAIR_TIEABLE + + scully + name = "Scully" + icon_state = "hair_scully" + + shavehair + name = "Shaved Hair" + icon_state = "hair_shaved" + flags = HAIR_VERY_SHORT + + shortbangs + name = "Short Bangs" + icon_state = "hair_shortbangs" + + short + name = "Short Hair" // try to capatilize the names please~ + icon_state = "hair_a" // you do not need to define _s or _l sub-states, game automatically does this for you + flags = HAIR_VERY_SHORT + + short2 + name = "Short Hair 2" + icon_state = "hair_shorthair3" + flags = HAIR_VERY_SHORT + + short3 + name = "Short Hair 3" + icon_state = "hair_shorthair4" + flags = HAIR_VERY_SHORT + + shy + name = "Shy" + icon_state = "hair_shy" sideponytail name = "Side Ponytail" @@ -176,438 +657,49 @@ flags = HAIR_TIEABLE sideponytail2 - name = "One Shoulder" + name = "Shoulder One" icon_state = "hair_oneshoulder" flags = HAIR_TIEABLE sideponytail3 - name = "Tress Shoulder" + name = "Shoulder Tress" icon_state = "hair_tressshoulder" flags = HAIR_TIEABLE - spikyponytail - name = "Spiky Ponytail" - icon_state = "hair_spikyponytail" - flags = HAIR_TIEABLE - - zieglertail - name = "Zieglertail" - icon_state = "hair_ziegler" - flags = HAIR_TIEABLE - - wisp - name = "Wisp" - icon_state = "hair_wisp" - flags = HAIR_TIEABLE - - parted - name = "Parted" - icon_state = "hair_parted" - - pompadour - name = "Pompadour" - icon_state = "hair_pompadour" - - sleeze - name = "Sleeze" - icon_state = "hair_sleeze" - flags = HAIR_VERY_SHORT - - quiff - name = "Quiff" - icon_state = "hair_quiff" - - bedhead - name = "Bedhead" - icon_state = "hair_bedhead" - - bedhead2 - name = "Bedhead 2" - icon_state = "hair_bedheadv2" - - bedhead3 - name = "Bedhead 3" - icon_state = "hair_bedheadv3" - flags = HAIR_TIEABLE - - bedheadlong - name = "Bedhead Long" - icon_state = "hair_long_bedhead" - flags = HAIR_TIEABLE - - beehive - name = "Beehive" - icon_state = "hair_beehive" - flags = HAIR_TIEABLE - - beehive2 - name = "Beehive 2" - icon_state = "hair_beehive2" - flags = HAIR_TIEABLE - - bobcurl - name = "Bobcurl" - icon_state = "hair_bobcurl" - species_allowed = list(SPECIES_HUMAN,SPECIES_PROMETHEAN,SPECIES_HUMAN_VATBORN,SPECIES_UNATHI) - flags = HAIR_TIEABLE - - bob - name = "Bob" - icon_state = "hair_bobcut" - species_allowed = list(SPECIES_HUMAN,SPECIES_PROMETHEAN,SPECIES_HUMAN_VATBORN,SPECIES_UNATHI) - flags = HAIR_TIEABLE - - bobcutalt - name = "Chin Length Bob" - icon_state = "hair_bobcutalt" - flags = HAIR_TIEABLE - - bun - name = "Bun" - icon_state = "hair_bun" - - bun2 - name = "Bun 2" - icon_state = "hair_bun2" - - bun3 - name = "Bun 3" - icon_state = "hair_bun3" - - bowl - name = "Bowl" - icon_state = "hair_bowlcut" - - buzz - name = "Buzzcut" - icon_state = "hair_buzzcut" - flags = HAIR_VERY_SHORT - species_allowed = list(SPECIES_HUMAN,SPECIES_PROMETHEAN,SPECIES_HUMAN_VATBORN,SPECIES_UNATHI) - - shavehair - name = "Shaved Hair" - icon_state = "hair_shaved" - flags = HAIR_VERY_SHORT - - crew - name = "Crewcut" - icon_state = "hair_crewcut" - flags = HAIR_VERY_SHORT - - combover - name = "Combover" - icon_state = "hair_combover" - - father - name = "Father" - icon_state = "hair_father" - - reversemohawk - name = "Reverse Mohawk" - icon_state = "hair_reversemohawk" - - devillock - name = "Devil Lock" - icon_state = "hair_devilock" - - dreadlocks - name = "Dreadlocks" - icon_state = "hair_dreads" - - curls - name = "Curls" - icon_state = "hair_curls" - flags = HAIR_TIEABLE - - afro - name = "Afro" - icon_state = "hair_afro" - - afro2 - name = "Afro 2" - icon_state = "hair_afro2" - - afro_large - name = "Big Afro" - icon_state = "hair_bigafro" - - rows - name = "Rows" - icon_state = "hair_rows1" - flags = HAIR_VERY_SHORT - - rows2 - name = "Rows 2" - icon_state = "hair_rows2" - flags = HAIR_TIEABLE - - sargeant - name = "Flat Top" - icon_state = "hair_sargeant" - flags = HAIR_VERY_SHORT - - emo - name = "Emo" - icon_state = "hair_emo" - - emo2 - name = "Emo Alt" - icon_state = "hair_emo2" - - longemo - name = "Long Emo" - icon_state = "hair_emolong" - flags = HAIR_TIEABLE - - fringeemo - name = "Emo Fringe" - icon_state = "hair_emofringe" - flags = HAIR_TIEABLE - - veryshortovereyealternate - name = "Overeye Very Short, Alternate" - icon_state = "hair_veryshortovereyealternate" - - veryshortovereye - name = "Overeye Very Short" - icon_state = "hair_veryshortovereye" - - shortovereye - name = "Overeye Short" - icon_state = "hair_shortovereye" - - longovereye - name = "Overeye Long" - icon_state = "hair_longovereye" - flags = HAIR_TIEABLE - - flowhair - name = "Flow Hair" - icon_state = "hair_f" - - feather - name = "Feather" - icon_state = "hair_feather" - flags = HAIR_TIEABLE - - hitop - name = "Hitop" - icon_state = "hair_hitop" - - mohawk - name = "Mohawk" - icon_state = "hair_d" - species_allowed = list(SPECIES_HUMAN,SPECIES_PROMETHEAN,SPECIES_HUMAN_VATBORN,SPECIES_UNATHI) - - jensen - name = "Adam Jensen Hair" - icon_state = "hair_jensen" - - gelled - name = "Gelled Back" - icon_state = "hair_gelled" - - gentle - name = "Gentle" - icon_state = "hair_gentle" - flags = HAIR_TIEABLE - - spiky - name = "Spiky" - icon_state = "hair_spikey" - species_allowed = list(SPECIES_HUMAN,SPECIES_PROMETHEAN,SPECIES_HUMAN_VATBORN,SPECIES_UNATHI) - - kusangi - name = "Kusanagi Hair" - icon_state = "hair_kusanagi" - - kagami - name = "Pigtails" - icon_state = "hair_kagami" - flags = HAIR_TIEABLE - - himecut - name = "Hime Cut" - icon_state = "hair_himecut" - flags = HAIR_TIEABLE - - shorthime - name = "Short Hime Cut" - icon_state = "hair_shorthime" - flags = HAIR_TIEABLE - - grandebraid - name = "Grande Braid" - icon_state = "hair_grande" - flags = HAIR_TIEABLE - - mbraid - name = "Medium Braid" - icon_state = "hair_shortbraid" - flags = HAIR_TIEABLE - - braid2 - name = "Long Braid" - icon_state = "hair_hbraid" - flags = HAIR_TIEABLE - - braid - name = "Floorlength Braid" - icon_state = "hair_braid" - flags = HAIR_TIEABLE - - odango - name = "Odango" - icon_state = "hair_odango" - flags = HAIR_TIEABLE - - ombre - name = "Ombre" - icon_state = "hair_ombre" - flags = HAIR_TIEABLE - - updo - name = "Updo" - icon_state = "hair_updo" - flags = HAIR_TIEABLE - skinhead name = "Skinhead" icon_state = "hair_skinhead" flags = HAIR_VERY_SHORT - balding - name = "Balding Hair" - icon_state = "hair_e" - gender = MALE + sleeze + name = "Sleeze" + icon_state = "hair_sleeze" flags = HAIR_VERY_SHORT - familyman - name = "The Family Man" - icon_state = "hair_thefamilyman" + spiky + name = "Spiky" + icon_state = "hair_spikey" + species_allowed = list(SPECIES_HUMAN,SPECIES_PROMETHEAN,SPECIES_HUMAN_VATBORN,SPECIES_UNATHI) - mahdrills - name = "Drillruru" - icon_state = "hair_drillruru" - - fringetail - name = "Fringetail" - icon_state = "hair_fringetail" - - dandypomp - name = "Dandy Pompadour" - icon_state = "hair_dandypompadour" - - poofy - name = "Poofy" - icon_state = "hair_poofy" - flags = HAIR_TIEABLE - - poofy2 - name = "Poofy2" - icon_state = "hair_poofy2" - flags = HAIR_TIEABLE - - crono - name = "Chrono" - icon_state = "hair_toriyama" - - vegeta - name = "Vegeta" - icon_state = "hair_toriyama2" - - cia - name = "CIA" - icon_state = "hair_cia" - - mulder - name = "Mulder" - icon_state = "hair_mulder" - - scully - name = "Scully" - icon_state = "hair_scully" - - nitori - name = "Nitori" - icon_state = "hair_nitori" - flags = HAIR_TIEABLE - - joestar - name = "Joestar" - icon_state = "hair_joestar" - - volaju - name = "Volaju" - icon_state = "hair_volaju" - flags = HAIR_TIEABLE - - eighties - name = "80's" - icon_state = "hair_80s" - - nia - name = "Nia" - icon_state = "hair_nia" - - unkept - name = "Unkept" - icon_state = "hair_unkept" - - modern - name = "Modern" - icon_state = "hair_modern" - - shortbangs - name = "Short Bangs" - icon_state = "hair_shortbangs" - - halfshaved - name = "Half-Shaved Emo" - icon_state = "hair_halfshaved" - - bun - name = "Casual Bun" - icon_state = "hair_bun" - flags = HAIR_TIEABLE - - doublebun - name = "Double-Bun" - icon_state = "hair_doublebun" - flags = HAIR_TIEABLE - - oxton - name = "Oxton" - icon_state = "hair_oxton" - - lowfade - name = "Low Fade" - icon_state = "hair_lowfade" - gender = MALE + thinning + name = "Thinning" + icon_state = "hair_thinning" flags = HAIR_VERY_SHORT - medfade - name = "Medium Fade" - icon_state = "hair_medfade" + thinningfront + name = "Thinning Front" + icon_state = "hair_thinningfront" flags = HAIR_VERY_SHORT - highfade - name = "High Fade" - icon_state = "hair_highfade" - gender = MALE + thinningback + name = "Thinning Back" + icon_state = "hair_thinningrear" flags = HAIR_VERY_SHORT - baldfade - name = "Balding Fade" - icon_state = "hair_baldfade" - gender = MALE - flags = HAIR_VERY_SHORT - - nofade - name = "Regulation Cut" - icon_state = "hair_nofade" - gender = MALE - flags = HAIR_VERY_SHORT + topknot + name = "Topknot" + icon_state = "hair_topknot" + flags = HAIR_TIEABLE trimflat name = "Trimmed Flat Top" @@ -621,17 +713,10 @@ gender = MALE flags = HAIR_VERY_SHORT - tightbun - name = "Tight Bun" - icon_state = "hair_tightbun" - gender = FEMALE - flags = HAIR_VERY_SHORT | HAIR_TIEABLE - - coffeehouse - name = "Coffee House Cut" - icon_state = "hair_coffeehouse" - gender = MALE - flags = HAIR_VERY_SHORT + twintail + name = "Twintail" + icon_state = "hair_twintail" + flags = HAIR_TIEABLE undercut1 name = "Undercut" @@ -651,113 +736,32 @@ gender = MALE flags = HAIR_VERY_SHORT - partfade - name = "Parted Fade" - icon_state = "hair_shavedpart" - gender = MALE - flags = HAIR_VERY_SHORT + unkept + name = "Unkept" + icon_state = "hair_unkept" - hightight - name = "High and Tight" - icon_state = "hair_hightight" - flags = HAIR_VERY_SHORT - - rowbun - name = "Row Bun" - icon_state = "hair_rowbun" + updo + name = "Updo" + icon_state = "hair_updo" flags = HAIR_TIEABLE - rowdualbraid - name = "Row Dual Braid" - icon_state = "hair_rowdualtail" + vegeta + name = "Vegeta" + icon_state = "hair_toriyama2" + + volaju + name = "Volaju" + icon_state = "hair_volaju" flags = HAIR_TIEABLE - rowbraid - name = "Row Braid" - icon_state = "hair_rowbraid" + wisp + name = "Wisp" + icon_state = "hair_wisp" flags = HAIR_TIEABLE - regulationmohawk - name = "Regulation Mohawk" - icon_state = "hair_shavedmohawk" - flags = HAIR_VERY_SHORT - - topknot - name = "Topknot" - icon_state = "hair_topknot" - flags = HAIR_TIEABLE - - ronin - name = "Ronin" - icon_state = "hair_ronin" - flags = HAIR_TIEABLE - - bowlcut2 - name = "Bowl2" - icon_state = "hair_bowlcut2" - - thinning - name = "Thinning" - icon_state = "hair_thinning" - flags = HAIR_VERY_SHORT - - thinningfront - name = "Thinning Front" - icon_state = "hair_thinningfront" - flags = HAIR_VERY_SHORT - - thinningback - name = "Thinning Back" - icon_state = "hair_thinningrear" - flags = HAIR_VERY_SHORT - - manbun - name = "Manbun" - icon_state = "hair_manbun" - flags = HAIR_TIEABLE - - shy - name = "Shy" - icon_state = "hair_shy" - - jade - name = "Jade" - icon_state = "hair_jade" - - country - name = "Country" - icon_state = "hair_country" - - rosa - name = "Rosa" - icon_state = "hair_rosa" - - dave - name = "Dave" - icon_state = "hair_dave" - - mohawkunshaven - name = "Unshaven Mohawk" - icon_state = "hair_unshaven_mohawk" - - belenko - name = "Belenko" - icon_state = "hair_belenko" - flags = HAIR_TIEABLE - - belenkotied - name = "Belenko Tied" - icon_state = "hair_belenkotied" - flags = HAIR_TIEABLE - - glossy - name = "Glossy" - icon_state = "hair_glossy" - flags = HAIR_TIEABLE - - sharpponytail - name = "Sharp Ponytail" - icon_state = "hair_sharpponytail" + zieglertail + name = "Zieglertail" + icon_state = "hair_ziegler" flags = HAIR_TIEABLE /* diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm index 0b20c6cb7f..29263adeaf 100644 --- a/code/modules/mob/say.dm +++ b/code/modules/mob/say.dm @@ -139,6 +139,7 @@ //returns the language object only if the code corresponds to a language that src can speak, otherwise null. /mob/proc/parse_language(var/message) var/prefix = copytext(message,1,2) + // This is for audible emotes if(length(message) >= 1 && prefix == "!") return all_languages["Noise"] @@ -147,5 +148,6 @@ var/datum/language/L = language_keys[language_prefix] if (can_speak(L)) return L - + else + return all_languages[LANGUAGE_GIBBERISH] return null diff --git a/code/modules/mob/say_vr.dm b/code/modules/mob/say_vr.dm index fbf9a9febb..bd5b516f9d 100644 --- a/code/modules/mob/say_vr.dm +++ b/code/modules/mob/say_vr.dm @@ -64,14 +64,14 @@ #define MAX_HUGE_MESSAGE_LEN 8192 #define POST_DELIMITER_STR "\<\>" -/proc/sanitize_or_reflect(message,user) +/proc/sanitize_or_reflect(message,user) //Way too long to send if(length(message) > MAX_HUGE_MESSAGE_LEN) fail_to_chat(user) return message = sanitize(message, max_length = MAX_HUGE_MESSAGE_LEN) - + //Came back still too long to send if(length(message) > MAX_MESSAGE_LEN) fail_to_chat(user,message) @@ -83,9 +83,9 @@ if(!message) to_chat(user,"Your message was NOT SENT, either because it was FAR too long, or sanitized to nothing at all.") return - + var/length = length(message) - var/posts = Ceiling(length/MAX_MESSAGE_LEN) + var/posts = CEILING((length/MAX_MESSAGE_LEN), 1) to_chat(user,message) to_chat(user,"^ This message was NOT SENT ^ -- It was [length] characters, and the limit is [MAX_MESSAGE_LEN]. It would fit in [posts] separate messages.") #undef MAX_HUGE_MESSAGE_LEN diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index dcd95c20de..0119dfb052 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -227,7 +227,7 @@ for(var/t in organs) //this really should not be necessary qdel(t) - var/mob/living/simple_animal/corgi/new_corgi = new /mob/living/simple_animal/corgi (loc) + var/mob/living/simple_mob/animal/passive/dog/corgi/new_corgi = new /mob/living/simple_mob/animal/passive/dog/corgi (loc) new_corgi.a_intent = I_HURT new_corgi.key = key @@ -237,7 +237,7 @@ /mob/living/carbon/human/Animalize() - var/list/mobtypes = typesof(/mob/living/simple_animal) + var/list/mobtypes = typesof(/mob/living/simple_mob) var/mobpath = input("Which type of mob should [src] turn into?", "Choose a type") in mobtypes if(!safe_animal(mobpath)) @@ -271,7 +271,7 @@ /mob/proc/Animalize() - var/list/mobtypes = typesof(/mob/living/simple_animal) + var/list/mobtypes = typesof(/mob/living/simple_mob) var/mobpath = input("Which type of mob should [src] turn into?", "Choose a type") in mobtypes if(!safe_animal(mobpath)) @@ -297,39 +297,29 @@ if(!MP) return 0 //Sanity, this should never happen. - if(ispath(MP, /mob/living/simple_animal/space_worm)) +/* + if(ispath(MP, /mob/living/simple_mob/space_worm)) return 0 //Unfinished. Very buggy, they seem to just spawn additional space worms everywhere and eating your own tail results in new worms spawning. - - if(ispath(MP, /mob/living/simple_animal/construct/behemoth)) - return 0 //I think this may have been an unfinished WiP or something. These constructs should really have their own class simple_animal/construct/subtype - - if(ispath(MP, /mob/living/simple_animal/construct/armoured)) - return 0 //Verbs do not appear for players. These constructs should really have their own class simple_animal/construct/subtype - - if(ispath(MP, /mob/living/simple_animal/construct/wraith)) - return 0 //Verbs do not appear for players. These constructs should really have their own class simple_animal/construct/subtype - - if(ispath(MP, /mob/living/simple_animal/construct/builder)) - return 0 //Verbs do not appear for players. These constructs should really have their own class simple_animal/construct/subtype +*/ //Good mobs! - if(ispath(MP, /mob/living/simple_animal/cat)) + if(ispath(MP, /mob/living/simple_mob/animal/passive/cat)) return 1 - if(ispath(MP, /mob/living/simple_animal/corgi)) + if(ispath(MP, /mob/living/simple_mob/animal/passive/dog)) return 1 - if(ispath(MP, /mob/living/simple_animal/crab)) + if(ispath(MP, /mob/living/simple_mob/animal/passive/crab)) return 1 - if(ispath(MP, /mob/living/simple_animal/hostile/carp)) + if(ispath(MP, /mob/living/simple_mob/animal/space/carp)) return 1 - if(ispath(MP, /mob/living/simple_animal/shade)) + if(ispath(MP, /mob/living/simple_mob/construct)) return 1 - if(ispath(MP, /mob/living/simple_animal/hostile/tomato)) + if(ispath(MP, /mob/living/simple_mob/tomato)) return 1 - if(ispath(MP, /mob/living/simple_animal/mouse)) + if(ispath(MP, /mob/living/simple_mob/animal/passive/mouse)) return 1 //It is impossible to pull up the player panel for mice (Fixed! - Nodrak) - if(ispath(MP, /mob/living/simple_animal/hostile/bear)) + if(ispath(MP, /mob/living/simple_mob/animal/space/bear)) return 1 //Bears will auto-attack mobs, even if they're player controlled (Fixed! - Nodrak) - if(ispath(MP, /mob/living/simple_animal/parrot)) + if(ispath(MP, /mob/living/simple_mob/animal/passive/bird/parrot)) return 1 //Parrots are no longer unfinished! -Nodrak //Not in here? Must be untested! diff --git a/code/modules/multiz/hoist.dm b/code/modules/multiz/hoist.dm index a1df9389ab..32e2ed9bb7 100644 --- a/code/modules/multiz/hoist.dm +++ b/code/modules/multiz/hoist.dm @@ -100,7 +100,7 @@ var/obj/effect/hoist_hook/source_hook description_info = "Click this to raise or lower the hoist, or to switch directions if it can't move any further. It can also be collapsed into a hoist kit." -/obj/structure/hoist/initialize(mapload, ndir) +/obj/structure/hoist/Initialize(mapload, ndir) . = ..() dir = ndir var/turf/newloc = get_step(src, dir) diff --git a/code/modules/multiz/ladder_assembly_vr.dm b/code/modules/multiz/ladder_assembly_vr.dm index 064d23cec3..3bb7b681fd 100644 --- a/code/modules/multiz/ladder_assembly_vr.dm +++ b/code/modules/multiz/ladder_assembly_vr.dm @@ -107,21 +107,21 @@ var/obj/structure/ladder/L = new(get_turf(below)) L.allowed_directions = UP if(below.created_name) L.name = below.created_name - L.initialize() + L.Initialize() qdel(below) if(me) var/obj/structure/ladder/L = new(get_turf(me)) L.allowed_directions = (below ? DOWN : 0) | (above ? UP : 0) if(me.created_name) L.name = me.created_name - L.initialize() + L.Initialize() qdel(me) if(above) var/obj/structure/ladder/L = new(get_turf(above)) L.allowed_directions = DOWN if(above.created_name) L.name = above.created_name - L.initialize() + L.Initialize() qdel(above) // Make them constructable in hand diff --git a/code/modules/multiz/movement.dm b/code/modules/multiz/movement.dm index 06840f65fe..49303cb0f5 100644 --- a/code/modules/multiz/movement.dm +++ b/code/modules/multiz/movement.dm @@ -83,11 +83,13 @@ /mob/proc/can_overcome_gravity() return FALSE -/mob/living/carbon/human/can_overcome_gravity() - return species && species.can_overcome_gravity(src) +/mob/living/can_overcome_gravity() + return hovering -/mob/living/simple_animal/construct/can_overcome_gravity() - return 1 //They care not for standard physics. +/mob/living/carbon/human/can_overcome_gravity() + . = ..() + if(!.) + return species && species.can_overcome_gravity(src) /mob/observer/zMove(direction) var/turf/destination = (direction == UP) ? GetAbove(src) : GetBelow(src) @@ -117,36 +119,44 @@ return ..() /mob/observer/can_ztravel() - return 1 + return TRUE -/mob/living/simple_animal/construct/can_ztravel() - return 1 +/mob/living/can_ztravel() + if(incapacitated()) + return FALSE + return hovering /mob/living/carbon/human/can_ztravel() if(incapacitated()) - return 0 + return FALSE + + if(hovering) + return TRUE if(flying) //VOREStation Edit. Allows movement up/down with wings. return 1 //VOREStation Edit if(Process_Spacemove()) - return 1 + return TRUE if(Check_Shoegrip()) //scaling hull with magboots for(var/turf/simulated/T in trange(1,src)) if(T.density) - return 1 + return TRUE /mob/living/silicon/robot/can_ztravel() if(incapacitated() || is_dead()) - return 0 + return FALSE + + if(hovering) + return TRUE if(Process_Spacemove()) //Checks for active jetpack - return 1 + return TRUE for(var/turf/simulated/T in trange(1,src)) //Robots get "magboots" if(T.density) - return 1 + return TRUE // TODO - Leshana Experimental @@ -262,19 +272,15 @@ if((locate(/obj/structure/disposalpipe/up) in below) || locate(/obj/machinery/atmospherics/pipe/zpipe/up in below)) return FALSE +/mob/living/can_fall() + if(hovering) + return FALSE + return ..() + /mob/living/carbon/human/can_fall() if(..()) return species.can_fall(src) -/mob/living/simple_animal/parrot/can_fall() // Poly can fly. - return FALSE - -/mob/living/simple_animal/hostile/carp/can_fall() // So can carp apparently. - return FALSE - -/mob/living/simple_animal/construct/can_fall() //As do Constructs. - return FALSE - // Check if this atom prevents things standing on it from falling. Return TRUE to allow the fall. /obj/proc/CanFallThru(atom/movable/mover as mob|obj, turf/target as turf) if(!isturf(mover.loc)) // VORESTATION EDIT. We clearly didn't have enough backup checks. diff --git a/code/modules/multiz/structures.dm b/code/modules/multiz/structures.dm index 118cb999de..c3f454f69c 100644 --- a/code/modules/multiz/structures.dm +++ b/code/modules/multiz/structures.dm @@ -17,7 +17,7 @@ var/const/climb_time = 2 SECONDS -/obj/structure/ladder/initialize() +/obj/structure/ladder/Initialize() . = ..() // the upper will connect to the lower if(allowed_directions & DOWN) //we only want to do the top one, as it will initialize the ones before it. @@ -132,7 +132,7 @@ anchored = 1 layer = 2.4 // Above turf, but they're sort of the floor, so below objects. -/obj/structure/stairs/initialize() +/obj/structure/stairs/Initialize() . = ..() for(var/turf/turf in locs) var/turf/simulated/open/above = GetAbove(turf) diff --git a/code/modules/multiz/turf.dm b/code/modules/multiz/turf.dm index cbf7623267..b3ea2c17ff 100644 --- a/code/modules/multiz/turf.dm +++ b/code/modules/multiz/turf.dm @@ -34,7 +34,7 @@ ..() update() -/turf/simulated/open/initialize() +/turf/simulated/open/Initialize() . = ..() ASSERT(HasBelow(z)) update() @@ -149,3 +149,9 @@ /turf/simulated/open/is_space() var/turf/below = GetBelow(src) return !below || below.is_space() + +/turf/simulated/open/is_safe_to_enter(mob/living/L) + if(L.can_fall()) + if(!locate(/obj/structure/stairs) in GetBelow(src)) + return FALSE + return ..() \ No newline at end of file diff --git a/code/modules/nano/interaction/remote.dm b/code/modules/nano/interaction/remote.dm index 2e18386bde..8e6ded6c84 100644 --- a/code/modules/nano/interaction/remote.dm +++ b/code/modules/nano/interaction/remote.dm @@ -18,7 +18,7 @@ src.remoter_state = null // Force an UI update before we go, ensuring that any windows we may have opened for the remote target closes. - GLOB.nanomanager.update_uis(remote_target.nano_container()) + SSnanoui.update_uis(remote_target.nano_container()) remote_target = null return ..() diff --git a/code/modules/nano/modules/alarm_monitor.dm b/code/modules/nano/modules/alarm_monitor.dm index c5a851bacc..ec43035ed8 100644 --- a/code/modules/nano/modules/alarm_monitor.dm +++ b/code/modules/nano/modules/alarm_monitor.dm @@ -80,7 +80,7 @@ "lost_sources" = lost_sources.len ? sanitize(english_list(lost_sources, nothing_text = "", and_text = ", ")) : "")) data["categories"] = categories - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "alarm_monitor.tmpl", "Alarm Monitoring Console", 800, 800, state = state) ui.set_initial_data(data) diff --git a/code/modules/nano/modules/atmos_control.dm b/code/modules/nano/modules/atmos_control.dm index c8c5e8b613..3924f65af7 100644 --- a/code/modules/nano/modules/atmos_control.dm +++ b/code/modules/nano/modules/atmos_control.dm @@ -48,7 +48,7 @@ data["alarms"] = alarms data["map_levels"] = using_map.get_map_levels(T.z) - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if(!ui) ui = new(user, src, ui_key, "atmos_control.tmpl", src.name, 625, 625, state = state) // adding a template with the key "mapContent" enables the map ui functionality diff --git a/code/modules/nano/modules/crew_monitor.dm b/code/modules/nano/modules/crew_monitor.dm index 4a721ab709..319da90715 100644 --- a/code/modules/nano/modules/crew_monitor.dm +++ b/code/modules/nano/modules/crew_monitor.dm @@ -25,7 +25,7 @@ for(var/z in (data["map_levels"] | T.z)) // Always show crew from the current Z even if we can't show a map data["crewmembers"] += crew_repository.health_data(z) - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.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, state = state) diff --git a/code/modules/nano/modules/human_appearance.dm b/code/modules/nano/modules/human_appearance.dm index 33203944a1..3d790b1194 100644 --- a/code/modules/nano/modules/human_appearance.dm +++ b/code/modules/nano/modules/human_appearance.dm @@ -145,7 +145,7 @@ data["change_hair_color"] = can_change(APPEARANCE_HAIR_COLOR) data["change_facial_hair_color"] = can_change(APPEARANCE_FACIAL_HAIR_COLOR) - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "appearance_changer.tmpl", "[src]", 800, 450, state = state) ui.set_initial_data(data) diff --git a/code/modules/nano/modules/law_manager.dm b/code/modules/nano/modules/law_manager.dm index 0b56c7b32a..da971a0f87 100644 --- a/code/modules/nano/modules/law_manager.dm +++ b/code/modules/nano/modules/law_manager.dm @@ -94,7 +94,7 @@ if(href_list["change_supplied_law_position"]) var/new_position = input(usr, "Enter new supplied law position between 1 and [MAX_SUPPLIED_LAW_NUMBER], inclusive. Inherent laws at the same index as a supplied law will not be stated.", "Law Position", supplied_law_position) as num|null if(isnum(new_position) && can_still_topic()) - supplied_law_position = Clamp(new_position, 1, MAX_SUPPLIED_LAW_NUMBER) + supplied_law_position = CLAMP(new_position, 1, MAX_SUPPLIED_LAW_NUMBER) return 1 if(href_list["edit_law"]) @@ -176,7 +176,7 @@ data["channels"] = channels data["law_sets"] = package_multiple_laws(data["isAdmin"] ? admin_laws : player_laws) - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "law_manager.tmpl", sanitize("[src] - [owner]"), 800, is_malf(user) ? 600 : 400, state = state) ui.set_initial_data(data) diff --git a/code/modules/nano/modules/power_monitor.dm b/code/modules/nano/modules/power_monitor.dm index af1e155530..ae5dc44f29 100644 --- a/code/modules/nano/modules/power_monitor.dm +++ b/code/modules/nano/modules/power_monitor.dm @@ -28,7 +28,7 @@ data["focus"] = focus.return_reading_data() data["map_levels"] = using_map.get_map_levels(T.z) - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "power_monitor.tmpl", "Power Monitoring Console", 800, 500, state = state) // adding a template with the key "mapContent" enables the map ui functionality diff --git a/code/modules/nano/modules/rcon.dm b/code/modules/nano/modules/rcon.dm index 19d89a1500..1612b19812 100644 --- a/code/modules/nano/modules/rcon.dm +++ b/code/modules/nano/modules/rcon.dm @@ -38,7 +38,7 @@ data["hide_smes_details"] = hide_SMES_details data["hide_breakers"] = hide_breakers - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "rcon.tmpl", "RCON Console", 600, 400, state = state) ui.set_initial_data(data) diff --git a/code/modules/nano/nanomanager.dm b/code/modules/nano/nanomanager.dm index b1639f9194..afa779895a 100644 --- a/code/modules/nano/nanomanager.dm +++ b/code/modules/nano/nanomanager.dm @@ -1,38 +1,3 @@ -GLOBAL_DATUM_INIT(nanomanager, /datum/nanomanager, new) // NanoManager, the manager for Nano UIs. - -// This is the window/UI manager for Nano UI -// There should only ever be one (global) instance of nanomanger -/datum/nanomanager - // 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() - - /** - * Create a new nanomanager instance. - * This proc generates a list of assets which are to be sent to each client on connect - * - * @return /nanomanager new nanomanager object - */ -/datum/nanomanager/New() - var/list/nano_asset_dirs = list(\ - "nano/css/",\ - "nano/images/",\ - "nano/js/",\ - "nano/templates/"\ - ) - - var/list/filenames = null - for (var/path in nano_asset_dirs) - 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 - 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 /** * Get an open /nanoui ui for the current user, src_object and ui_key and try to update it with data @@ -46,7 +11,7 @@ GLOBAL_DATUM_INIT(nanomanager, /datum/nanomanager, new) // NanoManager, the mana * * @return /nanoui Returns the found ui, for null if none exists */ -/datum/nanomanager/proc/try_update_ui(var/mob/user, src_object, ui_key, var/datum/nanoui/ui, data, var/force_open = 0) +/datum/controller/subsystem/nanoui/proc/try_update_ui(var/mob/user, src_object, ui_key, var/datum/nanoui/ui, data, var/force_open = 0) if (isnull(ui)) // no ui has been passed, so we'll search for one { ui = get_open_ui(user, src_object, ui_key) @@ -71,7 +36,7 @@ GLOBAL_DATUM_INIT(nanomanager, /datum/nanomanager, new) // NanoManager, the mana * * @return /nanoui Returns the found ui, or null if none exists */ -/datum/nanomanager/proc/get_open_ui(var/mob/user, src_object, ui_key) +/datum/controller/subsystem/nanoui/proc/get_open_ui(var/mob/user, src_object, ui_key) var/src_object_key = "\ref[src_object]" if (isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list)) //testing("nanomanager/get_open_ui mob [user.name] [src_object:name] [ui_key] - there are no uis open") @@ -94,7 +59,7 @@ GLOBAL_DATUM_INIT(nanomanager, /datum/nanomanager, new) // NanoManager, the mana * * @return int The number of uis updated */ -/datum/nanomanager/proc/update_uis(src_object) +/datum/controller/subsystem/nanoui/proc/update_uis(src_object) var/src_object_key = "\ref[src_object]" if (isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list)) return 0 @@ -114,7 +79,7 @@ GLOBAL_DATUM_INIT(nanomanager, /datum/nanomanager, new) // NanoManager, the mana * * @return int The number of uis close */ -/datum/nanomanager/proc/close_uis(src_object) +/datum/controller/subsystem/nanoui/proc/close_uis(src_object) var/src_object_key = "\ref[src_object]" if (isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list)) return 0 @@ -136,7 +101,7 @@ GLOBAL_DATUM_INIT(nanomanager, /datum/nanomanager, new) // NanoManager, the mana * * @return int The number of uis updated */ -/datum/nanomanager/proc/update_user_uis(var/mob/user, src_object = null, ui_key = null) +/datum/controller/subsystem/nanoui/proc/update_user_uis(var/mob/user, src_object = null, ui_key = null) if (isnull(user.open_uis) || !istype(user.open_uis, /list) || open_uis.len == 0) return 0 // has no open uis @@ -157,7 +122,7 @@ GLOBAL_DATUM_INIT(nanomanager, /datum/nanomanager, new) // NanoManager, the mana * * @return int The number of uis closed */ -/datum/nanomanager/proc/close_user_uis(var/mob/user, src_object = null, ui_key = null) +/datum/controller/subsystem/nanoui/proc/close_user_uis(var/mob/user, src_object = null, ui_key = null) if (isnull(user.open_uis) || !istype(user.open_uis, /list) || open_uis.len == 0) //testing("nanomanager/close_user_uis mob [user.name] has no open uis") return 0 // has no open uis @@ -180,7 +145,7 @@ GLOBAL_DATUM_INIT(nanomanager, /datum/nanomanager, new) // NanoManager, the mana * * @return nothing */ -/datum/nanomanager/proc/ui_opened(var/datum/nanoui/ui) +/datum/controller/subsystem/nanoui/proc/ui_opened(var/datum/nanoui/ui) var/src_object_key = "\ref[ui.src_object]" if (isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list)) open_uis[src_object_key] = list(ui.ui_key = list()) @@ -201,7 +166,7 @@ GLOBAL_DATUM_INIT(nanomanager, /datum/nanomanager, new) // NanoManager, the mana * * @return int 0 if no ui was removed, 1 if removed successfully */ -/datum/nanomanager/proc/ui_closed(var/datum/nanoui/ui) +/datum/controller/subsystem/nanoui/proc/ui_closed(var/datum/nanoui/ui) var/src_object_key = "\ref[ui.src_object]" if (isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list)) return 0 // wasn't open @@ -228,7 +193,7 @@ GLOBAL_DATUM_INIT(nanomanager, /datum/nanomanager, new) // NanoManager, the mana */ // -/datum/nanomanager/proc/user_logout(var/mob/user) +/datum/controller/subsystem/nanoui/proc/user_logout(var/mob/user) //testing("nanomanager/user_logout user [user.name]") return close_user_uis(user) @@ -241,7 +206,7 @@ GLOBAL_DATUM_INIT(nanomanager, /datum/nanomanager, new) // NanoManager, the mana * * @return nothing */ -/datum/nanomanager/proc/user_transferred(var/mob/oldMob, var/mob/newMob) +/datum/controller/subsystem/nanoui/proc/user_transferred(var/mob/oldMob, var/mob/newMob) //testing("nanomanager/user_transferred from mob [oldMob.name] to mob [newMob.name]") if (!oldMob || isnull(oldMob.open_uis) || !istype(oldMob.open_uis, /list) || open_uis.len == 0) //testing("nanomanager/user_transferred mob [oldMob.name] has no open uis") @@ -267,7 +232,7 @@ GLOBAL_DATUM_INIT(nanomanager, /datum/nanomanager, new) // NanoManager, the mana * @return nothing */ -/datum/nanomanager/proc/send_resources(client) +/datum/controller/subsystem/nanoui/proc/send_resources(client) for(var/file in asset_files) client << browse_rsc(file) // send the file to the client diff --git a/code/modules/nano/nanoui.dm b/code/modules/nano/nanoui.dm index bada05e300..43f98e3361 100644 --- a/code/modules/nano/nanoui.dm +++ b/code/modules/nano/nanoui.dm @@ -412,7 +412,7 @@ nanoui is used to open and update nano browser uis winset(user, "mapwindow.map", "focus=true") // return keyboard focus to map on_close_winset() //onclose(user, window_id) - GLOB.nanomanager.ui_opened(src) + SSnanoui.ui_opened(src) /** * Reinitialise this UI, potentially with a different template and/or initial data @@ -433,7 +433,7 @@ nanoui is used to open and update nano browser uis */ /datum/nanoui/proc/close() is_auto_updating = 0 - GLOB.nanomanager.ui_closed(src) + SSnanoui.ui_closed(src) user << browse(null, "window=[window_id]") for(var/datum/nanoui/child in children) child.close() @@ -492,7 +492,7 @@ nanoui is used to open and update nano browser uis map_update = 1 if ((src_object && src_object.Topic(href, href_list, state)) || map_update) - GLOB.nanomanager.update_uis(src_object) // update all UIs attached to src_object + SSnanoui.update_uis(src_object) // update all UIs attached to src_object /** * Process this UI, updating the entire UI or just the status (aka visibility) @@ -502,7 +502,7 @@ nanoui is used to open and update nano browser uis * * @return nothing */ -/datum/nanoui/proc/process(update = 0) +/datum/nanoui/process(update = 0) if (!src_object || !user) close() return diff --git a/code/modules/nifsoft/nif.dm b/code/modules/nifsoft/nif.dm index 8de9734531..fba5e17405 100644 --- a/code/modules/nifsoft/nif.dm +++ b/code/modules/nifsoft/nif.dm @@ -104,7 +104,7 @@ You can also set the stat of a NIF to NIF_TEMPFAIL without any issues to disable //Destructor cleans up references /obj/item/device/nif/Destroy() human = null - QDEL_NULL_LIST(nifsofts) + QDEL_LIST_NULL(nifsofts) QDEL_NULL(comm) nifsofts_life.Cut() return ..() @@ -154,7 +154,7 @@ You can also set the stat of a NIF to NIF_TEMPFAIL without any issues to disable /obj/item/device/nif/proc/unimplant(var/mob/living/carbon/human/H) var/datum/nifsoft/soulcatcher/SC = imp_check(NIF_SOULCATCHER) if(SC) //Clean up stored people, this is dirty but the easiest way. - QDEL_NULL_LIST(SC.brainmobs) + QDEL_LIST_NULL(SC.brainmobs) SC.brainmobs = list() stat = NIF_PREINSTALL vis_update() @@ -190,11 +190,11 @@ You can also set the stat of a NIF to NIF_TEMPFAIL without any issues to disable if(durability <= 0) stat = NIF_TEMPFAIL update_icon() - + if(human) notify("Danger! General system insta#^!($",TRUE) to_chat(human,"Your NIF vision overlays disappear and your head suddenly seems very quiet...") - + //Attackby proc, for maintenance /obj/item/device/nif/attackby(obj/item/weapon/W, mob/user as mob) if(open == 0 && W.is_screwdriver()) diff --git a/code/modules/nifsoft/nif_softshop.dm b/code/modules/nifsoft/nif_softshop.dm index a17e09b855..818a53d38c 100644 --- a/code/modules/nifsoft/nif_softshop.dm +++ b/code/modules/nifsoft/nif_softshop.dm @@ -19,7 +19,7 @@ opacity = 0 var/datum/entopic/entopic -/obj/machinery/vending/nifsoft_shop/initialize() +/obj/machinery/vending/nifsoft_shop/Initialize() . = ..() entopic = new(aholder = src, aicon = icon, aicon_state = "beacon") @@ -167,7 +167,7 @@ shut_up = !shut_up add_fingerprint(usr) - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) // Also special treatment! /obj/machinery/vending/nifsoft_shop/vend(datum/stored_item/vending_product/R, mob/user) @@ -179,7 +179,7 @@ vend_ready = 0 //One thing at a time!! status_message = "Installing..." status_error = 0 - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) if(R.category & CAT_COIN) if(!coin) @@ -215,5 +215,5 @@ status_error = 0 vend_ready = 1 currently_vending = null - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) return 1 diff --git a/code/modules/nifsoft/software/13_soulcatcher.dm b/code/modules/nifsoft/software/13_soulcatcher.dm index 05fbca5a47..09d23669b3 100644 --- a/code/modules/nifsoft/software/13_soulcatcher.dm +++ b/code/modules/nifsoft/software/13_soulcatcher.dm @@ -26,7 +26,7 @@ load_settings() Destroy() - QDEL_NULL_LIST(brainmobs) + QDEL_LIST_NULL(brainmobs) return ..() activate() @@ -49,7 +49,7 @@ nif.human.verbs |= /mob/living/carbon/human/proc/nme uninstall() - QDEL_NULL_LIST(brainmobs) + QDEL_LIST_NULL(brainmobs) if((. = ..()) && nif && nif.human) //Sometimes NIFs are deleted outside of a human nif.human.verbs -= /mob/living/carbon/human/proc/nsay nif.human.verbs -= /mob/living/carbon/human/proc/nme diff --git a/code/modules/nifsoft/software/15_misc.dm b/code/modules/nifsoft/software/15_misc.dm index 9c8d6d7f0e..213902c528 100644 --- a/code/modules/nifsoft/software/15_misc.dm +++ b/code/modules/nifsoft/software/15_misc.dm @@ -71,7 +71,7 @@ return FALSE stat_text() - return "[active ? "Active" : "Disabled"] (Stored Heat: [Floor(used/20)]%)" + return "[active ? "Active" : "Disabled"] (Stored Heat: [FLOOR((used/20), 1)]%)" life() if((. = ..())) @@ -129,7 +129,7 @@ if((. = ..())) var/new_size = input("Put the desired size (25-200%)", "Set Size", 200) as num - if (!IsInRange(new_size,25,200)) + if (!ISINRANGE(new_size,25,200)) to_chat(nif.human,"The safety features of the NIF Program prevent you from choosing this size.") return else diff --git a/code/modules/organs/internal/brain.dm b/code/modules/organs/internal/brain.dm index 5f8a9dd0d7..2003abe04f 100644 --- a/code/modules/organs/internal/brain.dm +++ b/code/modules/organs/internal/brain.dm @@ -107,7 +107,7 @@ GLOBAL_LIST_BOILERPLATE(all_brain_organs, /obj/item/organ/internal/brain) if(name == initial(name)) name = "\the [owner.real_name]'s [initial(name)]" - var/mob/living/simple_animal/borer/borer = owner.has_brain_worms() + var/mob/living/simple_mob/animal/borer/borer = owner.has_brain_worms() if(borer) borer.detatch() //Should remove borer if the brain is removed - RR diff --git a/code/modules/organs/misc.dm b/code/modules/organs/misc.dm index 862c96a96f..30515e746b 100644 --- a/code/modules/organs/misc.dm +++ b/code/modules/organs/misc.dm @@ -34,7 +34,7 @@ ..() - var/mob/living/simple_animal/borer/B = owner.has_brain_worms() + var/mob/living/simple_mob/animal/borer/B = owner.has_brain_worms() if(B) B.leave_host() B.ckey = owner.ckey diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index f07a6b3192..2309876e94 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -91,13 +91,13 @@ var/list/organ_cache = list() if(robotic < ORGAN_ROBOT) status |= ORGAN_DEAD damage = max_damage - processing_objects -= src + STOP_PROCESSING(SSobj, src) if(owner && vital) owner.death() owner.can_defib = 0 /obj/item/organ/proc/adjust_germ_level(var/amount) // Unless you're setting germ level directly to 0, use this proc instead - germ_level = Clamp(germ_level + amount, 0, INFECTION_LEVEL_MAX) + germ_level = CLAMP(germ_level + amount, 0, INFECTION_LEVEL_MAX) /obj/item/organ/process() @@ -335,8 +335,8 @@ var/list/organ_cache = list() var/obj/item/organ/external/affected = owner.get_organ(parent_organ) if(affected) affected.internal_organs -= src - loc = owner.drop_location() - processing_objects |= src + loc = get_turf(owner) + START_PROCESSING(SSobj, src) rejecting = null var/datum/reagent/blood/organ_blood = locate(/datum/reagent/blood) in reagents.reagent_list if(!organ_blood || !organ_blood.data["blood_DNA"]) @@ -367,7 +367,7 @@ var/list/organ_cache = list() owner = target loc = owner - processing_objects -= src + STOP_PROCESSING(SSobj, src) target.internal_organs |= src affected.internal_organs |= src target.internal_organs_by_name[organ_tag] = src diff --git a/code/modules/organs/organ_icon.dm b/code/modules/organs/organ_icon.dm index 371c64e0ab..203664e51a 100644 --- a/code/modules/organs/organ_icon.dm +++ b/code/modules/organs/organ_icon.dm @@ -289,5 +289,5 @@ var/list/robot_hud_colours = list("#CFCFCF","#AFAFAF","#8F8F8F","#6F6F6F","#4F4F dam_state = min_dam_state // Apply colour and return product. var/list/hud_colours = (robotic < ORGAN_ROBOT) ? flesh_hud_colours : robot_hud_colours - hud_damage_image.color = hud_colours[max(1,min(ceil(dam_state*hud_colours.len),hud_colours.len))] + hud_damage_image.color = hud_colours[max(1,min(CEILING(dam_state*hud_colours.len, 1),hud_colours.len))] return hud_damage_image diff --git a/code/modules/organs/subtypes/nano.dm b/code/modules/organs/subtypes/nano.dm index fe23f37f85..b8fb26cd64 100644 --- a/code/modules/organs/subtypes/nano.dm +++ b/code/modules/organs/subtypes/nano.dm @@ -157,7 +157,7 @@ icon = 'icons/mob/species/protean/protean.dmi' icon_state = "posi" -/obj/item/device/mmi/digital/posibrain/nano/initialize() +/obj/item/device/mmi/digital/posibrain/nano/Initialize() . = ..() icon_state = "posi" diff --git a/code/modules/overmap/ships/computers/engine_control.dm b/code/modules/overmap/ships/computers/engine_control.dm index 265e560399..01920ee2e0 100644 --- a/code/modules/overmap/ships/computers/engine_control.dm +++ b/code/modules/overmap/ships/computers/engine_control.dm @@ -8,7 +8,7 @@ var/list/engines = list() var/obj/effect/map/ship/linked -/obj/machinery/computer/engines/initialize() +/obj/machinery/computer/engines/Initialize() . = ..() linked = map_sectors["[z]"] if (linked) @@ -52,7 +52,7 @@ data["engines_info"] = enginfo - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "engines_control.tmpl", "[linked.name] Engines Control", 380, 530) ui.set_initial_data(data) @@ -70,13 +70,13 @@ if(href_list["set_limit"]) var/datum/ship_engine/E = locate(href_list["engine"]) var/newlim = input("Input new thrust limit (0..100)", "Thrust limit", E.get_thrust_limit()) as num - var/limit = Clamp(newlim/100, 0, 1) + var/limit = CLAMP(newlim/100, 0, 1) if(E) E.set_thrust_limit(limit) if(href_list["limit"]) var/datum/ship_engine/E = locate(href_list["engine"]) - var/limit = Clamp(E.get_thrust_limit() + text2num(href_list["limit"]), 0, 1) + var/limit = CLAMP(E.get_thrust_limit() + text2num(href_list["limit"]), 0, 1) if(E) E.set_thrust_limit(limit) diff --git a/code/modules/overmap/ships/computers/helm.dm b/code/modules/overmap/ships/computers/helm.dm index 2c198c6a3c..0249fae482 100644 --- a/code/modules/overmap/ships/computers/helm.dm +++ b/code/modules/overmap/ships/computers/helm.dm @@ -10,7 +10,7 @@ var/dx //desitnation var/dy //coordinates -/obj/machinery/computer/helm/initialize() +/obj/machinery/computer/helm/Initialize() . = ..() linked = map_sectors["[z]"] if (linked) @@ -104,7 +104,7 @@ data["locations"] = locations - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "helm.tmpl", "[linked.name] Helm Control", 380, 530) ui.set_initial_data(data) @@ -130,9 +130,9 @@ R.fields["y"] = linked.y if("new") var/newx = input("Input new entry x coordinate", "Coordinate input", linked.x) as num - R.fields["x"] = Clamp(newx, 1, world.maxx) + R.fields["x"] = CLAMP(newx, 1, world.maxx) var/newy = input("Input new entry y coordinate", "Coordinate input", linked.y) as num - R.fields["y"] = Clamp(newy, 1, world.maxy) + R.fields["y"] = CLAMP(newy, 1, world.maxy) known_sectors += R if (href_list["remove"]) @@ -142,12 +142,12 @@ if (href_list["setx"]) var/newx = input("Input new destiniation x coordinate", "Coordinate input", dx) as num|null if (newx) - dx = Clamp(newx, 1, world.maxx) + dx = CLAMP(newx, 1, world.maxx) if (href_list["sety"]) var/newy = input("Input new destiniation y coordinate", "Coordinate input", dy) as num|null if (newy) - dy = Clamp(newy, 1, world.maxy) + dy = CLAMP(newy, 1, world.maxy) if (href_list["x"] && href_list["y"]) dx = text2num(href_list["x"]) diff --git a/code/modules/overmap/ships/computers/shuttle.dm b/code/modules/overmap/ships/computers/shuttle.dm index 16303509a8..09bf47512d 100644 --- a/code/modules/overmap/ships/computers/shuttle.dm +++ b/code/modules/overmap/ships/computers/shuttle.dm @@ -8,7 +8,7 @@ var/obj/effect/map/destination //current destination var/obj/effect/map/home //current destination -/obj/machinery/computer/shuttle_control/explore/initialize() +/obj/machinery/computer/shuttle_control/explore/Initialize() . = ..() home = map_sectors["[z]"] shuttle_tag = "[shuttle_tag]-[z]" @@ -103,7 +103,7 @@ "can_force" = can_go && shuttle.can_force(), ) - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "shuttle_control_console_exploration.tmpl", "[shuttle_tag] Shuttle Control", 470, 310) diff --git a/code/modules/overmap/ships/engines/thermal.dm b/code/modules/overmap/ships/engines/thermal.dm index 323bc82906..9c4af11cc6 100644 --- a/code/modules/overmap/ships/engines/thermal.dm +++ b/code/modules/overmap/ships/engines/thermal.dm @@ -53,7 +53,7 @@ var/effective_pressure = 3000 var/datum/ship_engine/thermal/controller -/obj/machinery/atmospherics/unary/engine/initialize() +/obj/machinery/atmospherics/unary/engine/Initialize() . = ..() controller = new(src) diff --git a/code/modules/overmap/ships/ship.dm b/code/modules/overmap/ships/ship.dm index b7adf7319a..0abd450a69 100644 --- a/code/modules/overmap/ships/ship.dm +++ b/code/modules/overmap/ships/ship.dm @@ -14,7 +14,7 @@ var/obj/machinery/computer/helm/nav_control var/obj/machinery/computer/engines/eng_control -/obj/effect/map/ship/initialize() +/obj/effect/map/ship/Initialize() . = ..() for(var/obj/machinery/computer/engines/E in machines) if (E.z == map_z) @@ -24,7 +24,7 @@ if (H.z == map_z) nav_control = H break - processing_objects.Add(src) + START_PROCESSING(SSobj, src) /obj/effect/map/ship/relaymove(mob/user, direction) accelerate(direction) @@ -53,8 +53,8 @@ return res /obj/effect/map/ship/proc/adjust_speed(n_x, n_y) - speed[1] = Clamp(speed[1] + n_x, -default_delay, default_delay) - speed[2] = Clamp(speed[2] + n_y, -default_delay, default_delay) + speed[1] = CLAMP(speed[1] + n_x, -default_delay, default_delay) + speed[2] = CLAMP(speed[2] + n_y, -default_delay, default_delay) if(is_still()) toggle_move_stars(map_z) else @@ -112,5 +112,5 @@ var/turf/newloc = locate(x + deltas[1], y + deltas[2], z) if(newloc) Move(newloc) - if(rotate) + if(rotate) rotate(get_heading()) diff --git a/code/modules/paperwork/faxmachine.dm b/code/modules/paperwork/faxmachine.dm index 8a2940b90d..add0d03d22 100644 --- a/code/modules/paperwork/faxmachine.dm +++ b/code/modules/paperwork/faxmachine.dm @@ -57,7 +57,7 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins data["cooldown"] = sendcooldown data["destination"] = destination - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "fax.tmpl", src.name, 500, 500) ui.set_initial_data(data) @@ -116,7 +116,7 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins if(href_list["logout"]) authenticated = 0 - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) /obj/machinery/photocopier/faxmachine/proc/sendfax(var/destination) if(stat & (BROKEN|NOPOWER)) diff --git a/code/modules/paperwork/filingcabinet.dm b/code/modules/paperwork/filingcabinet.dm index 44a2d1310b..d1effe7492 100644 --- a/code/modules/paperwork/filingcabinet.dm +++ b/code/modules/paperwork/filingcabinet.dm @@ -25,7 +25,7 @@ icon_state = "tallcabinet" -/obj/structure/filingcabinet/initialize() +/obj/structure/filingcabinet/Initialize() for(var/obj/item/I in loc) if(istype(I, /obj/item/weapon/paper) || istype(I, /obj/item/weapon/folder) || istype(I, /obj/item/weapon/photo) || istype(I, /obj/item/weapon/paper_bundle)) I.loc = src diff --git a/code/modules/paperwork/paperbin.dm b/code/modules/paperwork/paperbin.dm index 4a81179c72..4a24500fd3 100644 --- a/code/modules/paperwork/paperbin.dm +++ b/code/modules/paperwork/paperbin.dm @@ -19,7 +19,7 @@ /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/simple_animal)) + if(!istype(usr, /mob/living/simple_mob)) if( !usr.get_active_hand() ) //if active hand is empty var/mob/living/carbon/human/H = user var/obj/item/organ/external/temp = H.organs_by_name["r_hand"] diff --git a/code/modules/paperwork/papershredder.dm b/code/modules/paperwork/papershredder.dm index b1f58b0965..d626e6f04b 100644 --- a/code/modules/paperwork/papershredder.dm +++ b/code/modules/paperwork/papershredder.dm @@ -137,7 +137,7 @@ else icon_state = "shredder-off" // Fullness overlay - overlays += "shredder-[max(0,min(5,Floor(paperamount/max_paper*5)))]" + overlays += "shredder-[max(0,min(5,FLOOR(paperamount/max_paper*5, 1)))]" if (panel_open) overlays += "panel_open" diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index c5c087f7d8..24ad752845 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -50,7 +50,7 @@ else data["isSilicon"] = null - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "photocopier.tmpl", src.name, 300, 250) ui.set_initial_data(data) @@ -118,7 +118,7 @@ toner -= 5 sleep(15) - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) /obj/machinery/photocopier/attackby(obj/item/O as obj, mob/user as mob) if(istype(O, /obj/item/weapon/paper) || istype(O, /obj/item/weapon/photo) || istype(O, /obj/item/weapon/paper_bundle)) diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm index 535debad21..9e95e67a6d 100644 --- a/code/modules/paperwork/photography.dm +++ b/code/modules/paperwork/photography.dm @@ -33,7 +33,6 @@ var/global/photo_count = 0 var/icon/img //Big photo image var/scribble //Scribble on the back. var/icon/tiny - var/cursed = 0 var/photo_size = 3 /obj/item/weapon/photo/New() @@ -237,10 +236,6 @@ var/global/photo_count = 0 else mob_detail += "You can also see [A] on the photo[A:health < 75 ? " - [A] looks hurt":""].[holding ? " [holding]":"."]." - for(var/mob/living/simple_animal/hostile/statue/S in the_turf) - if(S) - mob_detail += "You can see \a [S] on the photo. Its stare makes you feel uneasy." //"That which holds the image of an angel, becomes itself an angel." - return mob_detail /obj/item/device/camera/afterattack(atom/target as mob|obj|turf|area, mob/user as mob, flag) @@ -282,20 +277,7 @@ var/global/photo_count = 0 y_c-- x_c = x_c - size - - - var/obj/item/weapon/photo/p = createpicture(target, user, turfs, mobs, flag) - if(findtext(mobs, "Its stare makes you feel uneasy")) - p.cursed = 1 - user.visible_message("Something starts to slowly manifest from the picture!") - spawn(150) - var/turf/T = get_turf(p) - var/mob/living/simple_animal/hostile/statue/S = new /mob/living/simple_animal/hostile/statue/(T) - S.banishable = 1//At least you can get rid of those bastards - T.visible_message("The photo turns into \a [S]!") - qdel(p) - printpicture(user, p) @@ -339,16 +321,6 @@ var/global/photo_count = 0 p.pixel_y = pixel_y p.photo_size = photo_size p.scribble = scribble - p.cursed = cursed - if(p.cursed) - var/turf/T = get_turf(p) - T.visible_message("Something starts to slowly manifest from the picture!") - spawn(150) - T = get_turf(p) //second time, because the photo could've moved - var/mob/living/simple_animal/hostile/statue/S = new /mob/living/simple_animal/hostile/statue/(T) - S.banishable = 1//At least you can get rid of those bastards - T.visible_message("The photo turns into \a [S]!") - qdel(p) if(copy_id) p.id = id diff --git a/code/modules/planet/planet.dm b/code/modules/planet/planet.dm index 0364056b69..b069e2fdda 100644 --- a/code/modules/planet/planet.dm +++ b/code/modules/planet/planet.dm @@ -14,7 +14,7 @@ var/sun_position = 0 // 0 means midnight, 1 means noon. var/list/sun = list("range","brightness","color","lum_r","lum_g","lum_b") var/list/datum/lighting_corner/sunlit_corners = list() - var/expected_z_levels = list() + var/list/expected_z_levels = list() var/turf/unsimulated/wall/planetary/planetary_wall_type = /turf/unsimulated/wall/planetary @@ -45,7 +45,7 @@ )) update_sun() -/datum/planet/proc/process(last_fire) +/datum/planet/process(last_fire) if(current_time) var/difference = world.time - last_fire current_time = current_time.add_seconds((difference / 10) * PLANET_TIME_MODIFIER) diff --git a/code/modules/planet/sif.dm b/code/modules/planet/sif.dm index b8c99636f6..a9c6d7570a 100644 --- a/code/modules/planet/sif.dm +++ b/code/modules/planet/sif.dm @@ -70,12 +70,12 @@ var/datum/planet/sif/planet_sif = null high_color = "#FFFFFF" min = 0.70 - var/lerp_weight = (abs(min - sun_position)) * 4 + var/interpolate_weight = (abs(min - sun_position)) * 4 var/weather_light_modifier = 1 if(weather_holder && weather_holder.current_weather) weather_light_modifier = weather_holder.current_weather.light_modifier - var/new_brightness = (Interpolate(low_brightness, high_brightness, weight = lerp_weight) ) * weather_light_modifier + var/new_brightness = (LERP(low_brightness, high_brightness, interpolate_weight) ) * weather_light_modifier var/new_color = null if(weather_holder && weather_holder.current_weather && weather_holder.current_weather.light_color) @@ -91,9 +91,9 @@ var/datum/planet/sif/planet_sif = null var/high_g = high_color_list[2] var/high_b = high_color_list[3] - var/new_r = Interpolate(low_r, high_r, weight = lerp_weight) - var/new_g = Interpolate(low_g, high_g, weight = lerp_weight) - var/new_b = Interpolate(low_b, high_b, weight = lerp_weight) + var/new_r = LERP(low_r, high_r, interpolate_weight) + var/new_g = LERP(low_g, high_g, interpolate_weight) + var/new_b = LERP(low_b, high_b, interpolate_weight) new_color = rgb(new_r, new_g, new_b) @@ -121,7 +121,10 @@ var/datum/planet/sif/planet_sif = null WEATHER_RAIN = new /datum/weather/sif/rain(), WEATHER_STORM = new /datum/weather/sif/storm(), WEATHER_HAIL = new /datum/weather/sif/hail(), - WEATHER_BLOOD_MOON = new /datum/weather/sif/blood_moon() + WEATHER_BLOOD_MOON = new /datum/weather/sif/blood_moon(), + WEATHER_EMBERFALL = new /datum/weather/sif/emberfall(), + WEATHER_ASH_STORM = new /datum/weather/sif/ash_storm(), + WEATHER_FALLOUT = new /datum/weather/sif/fallout() ) roundstart_weather_chances = list( WEATHER_CLEAR = 30, @@ -208,6 +211,8 @@ var/datum/planet/sif/planet_sif = null "It's starting to snow.", "The air feels much colder as snowflakes fall from above." ) + outdoor_sounds_type = /datum/looping_sound/weather/outside_snow + indoor_sounds_type = /datum/looping_sound/weather/inside_snow /datum/weather/sif/snow/process_effects() ..() @@ -237,6 +242,8 @@ var/datum/planet/sif/planet_sif = null "Strong winds howl around you as a blizzard appears.", "It starts snowing heavily, and it feels extremly cold now." ) + outdoor_sounds_type = /datum/looping_sound/weather/outside_blizzard + indoor_sounds_type = /datum/looping_sound/weather/inside_blizzard /datum/weather/sif/blizzard/process_effects() ..() @@ -265,6 +272,8 @@ var/datum/planet/sif/planet_sif = null transition_messages = list( "The sky is dark, and rain falls down upon you." ) +// outdoor_sounds_type = /datum/looping_sound/weather/rain +// indoor_sounds_type = /datum/looping_sound/weather/rain/indoors /datum/weather/sif/rain/process_effects() ..() @@ -310,6 +319,8 @@ var/datum/planet/sif/planet_sif = null "Loud thunder is heard in the distance.", "A bright flash heralds the approach of a storm." ) +// outdoor_sounds_type = /datum/looping_sound/weather/rain +// indoor_sounds_type = /datum/looping_sound/weather/rain/indoors transition_chances = list( @@ -417,7 +428,7 @@ var/datum/planet/sif/planet_sif = null if(show_message) to_chat(H, "Hail patters onto your umbrella.") continue - + var/target_zone = pick(BP_ALL) var/amount_blocked = H.run_armor_check(target_zone, "melee") var/amount_soaked = H.get_armor_soak(target_zone, "melee") @@ -435,6 +446,10 @@ var/datum/planet/sif/planet_sif = null if(show_message) to_chat(H, effect_message) + +// These never happen naturally, and are for adminbuse. + +// A culty weather. /datum/weather/sif/blood_moon name = "blood moon" light_modifier = 0.5 @@ -446,4 +461,108 @@ var/datum/planet/sif/planet_sif = null observed_message = "Everything is red. Something really wrong is going on." transition_messages = list( "The sky turns blood red!" - ) \ No newline at end of file + ) + outdoor_sounds_type = /datum/looping_sound/weather/wind + indoor_sounds_type = /datum/looping_sound/weather/wind/indoors + +// Ash and embers fall forever, such as from a volcano or something. +/datum/weather/sif/emberfall + name = "emberfall" + icon_state = "ashfall_light" + light_modifier = 0.7 + light_color = "#880000" + temp_high = 293.15 // 20c + temp_low = 283.15 // 10c + flight_failure_modifier = 20 + transition_chances = list( + WEATHER_EMBERFALL = 100 + ) + observed_message = "Soot, ash, and embers float down from above." + transition_messages = list( + "Gentle embers waft down around you like grotesque snow." + ) + outdoor_sounds_type = /datum/looping_sound/weather/wind + indoor_sounds_type = /datum/looping_sound/weather/wind/indoors + +// Like the above but a lot more harmful. +/datum/weather/sif/ash_storm + name = "ash storm" + icon_state = "ashfall_heavy" + light_modifier = 0.1 + light_color = "#FF0000" + temp_high = 323.15 // 50c + temp_low = 313.15 // 40c + flight_failure_modifier = 50 + transition_chances = list( + WEATHER_ASH_STORM = 100 + ) + observed_message = "All that can be seen is black smoldering ash." + transition_messages = list( + "Smoldering clouds of scorching ash billow down around you!" + ) + // Lets recycle. + outdoor_sounds_type = /datum/looping_sound/weather/outside_blizzard + indoor_sounds_type = /datum/looping_sound/weather/inside_blizzard + +/datum/weather/sif/ash_storm/process_effects() + ..() + for(var/thing in living_mob_list) + var/mob/living/L = thing + if(L.z in holder.our_planet.expected_z_levels) + var/turf/T = get_turf(L) + if(!T.outdoors) + continue // They're indoors, so no need to burn them with ash. + + L.inflict_heat_damage(rand(1, 3)) + + +// Totally radical. +/datum/weather/sif/fallout + name = "fallout" + icon_state = "fallout" + light_modifier = 0.7 + light_color = "#CCFFCC" + flight_failure_modifier = 30 + transition_chances = list( + WEATHER_FALLOUT = 100 + ) + observed_message = "Radioactive soot and ash rains down from the heavens." + transition_messages = list( + "Radioactive soot and ash start to float down around you, contaminating whatever they touch." + ) + outdoor_sounds_type = /datum/looping_sound/weather/wind + indoor_sounds_type = /datum/looping_sound/weather/wind/indoors + + // How much radiation a mob gets while on an outside tile. + var/direct_rad_low = RAD_LEVEL_LOW + var/direct_rad_high = RAD_LEVEL_MODERATE + + // How much radiation is bursted onto a random tile near a mob. + var/fallout_rad_low = RAD_LEVEL_HIGH + var/fallout_rad_high = RAD_LEVEL_VERY_HIGH + +/datum/weather/sif/fallout/process_effects() + ..() + for(var/thing in living_mob_list) + var/mob/living/L = thing + if(L.z in holder.our_planet.expected_z_levels) + irradiate_nearby_turf(L) + var/turf/T = get_turf(L) + if(!T.outdoors) + continue // They're indoors, so no need to irradiate them with fallout. + + L.rad_act(rand(direct_rad_low, direct_rad_high)) + +// This makes random tiles near people radioactive for awhile. +// Tiles far away from people are left alone, for performance. +/datum/weather/sif/fallout/proc/irradiate_nearby_turf(mob/living/L) + if(!istype(L)) + return + var/list/turfs = RANGE_TURFS(world.view, L) + var/turf/T = pick(turfs) // We get one try per tick. + if(!istype(T)) + return + if(T.outdoors) + radiation_repository.radiate(T, rand(fallout_rad_low, fallout_rad_high)) +>>>>>>> 5fb77b3... Merge pull request #5791 from Neerti/looping_sounds +>>>>>>> Adds Various Sounds, Looping Sound System diff --git a/code/modules/planet/time.dm b/code/modules/planet/time.dm index 0b3008b668..d9c6642e6a 100644 --- a/code/modules/planet/time.dm +++ b/code/modules/planet/time.dm @@ -54,15 +54,15 @@ var/seconds = remaining_hour % seconds_in_minute / 10 - var/hour_text = num2text(Floor(hours)) + var/hour_text = num2text(FLOOR(hours, 1)) if(length(hour_text) < 2) hour_text = "0[hour_text]" // Add padding if needed, to look more like time2text(). - var/minute_text = num2text(Floor(minutes)) + var/minute_text = num2text(FLOOR(minutes, 1)) if(length(minute_text) < 2) minute_text = "0[minute_text]" - var/second_text = num2text(Floor(seconds)) + var/second_text = num2text(FLOOR(seconds, 1)) if(length(second_text) < 2) second_text = "0[second_text]" diff --git a/code/modules/planet/weather.dm b/code/modules/planet/weather.dm index a13cb87cc7..6e4447f4e9 100644 --- a/code/modules/planet/weather.dm +++ b/code/modules/planet/weather.dm @@ -25,13 +25,19 @@ /datum/weather_holder/proc/change_weather(var/new_weather) var/old_light_modifier = null - var/old_weather = null + var/datum/weather/old_weather = null if(current_weather) old_light_modifier = current_weather.light_modifier // We store the old one, so we can determine if recalculating the sun is needed. old_weather = current_weather current_weather = allowed_weather_types[new_weather] next_weather_shift = world.time + rand(current_weather.timer_low_bound, current_weather.timer_high_bound) MINUTES if(new_weather != old_weather) + if(istype(old_weather)) // At roundstart this is null. + old_weather.process_sounds() // Ensure that people who should hear the ending sound will hear it. + old_weather.stop_sounds() + + current_weather.process_sounds() // Same story, make sure the starting sound is heard. + current_weather.start_sounds() show_transition_message() update_icon_effects() @@ -40,7 +46,7 @@ our_planet.update_sun() log_debug("[our_planet.name]'s weather is now [new_weather], with a temperature of [temperature]°K ([temperature - T0C]°C | [temperature * 1.8 - 459.67]°F).") -/datum/weather_holder/proc/process() +/datum/weather_holder/process() if(world.time >= next_weather_shift) if(!current_weather) // Roundstart (hopefully). initialize_weather() @@ -48,7 +54,7 @@ advance_forecast() else current_weather.process_effects() - + current_weather.process_sounds() // Should only have to be called once. @@ -98,7 +104,7 @@ visuals.icon_state = current_weather.icon_state /datum/weather_holder/proc/update_temperature() - temperature = Interpolate(current_weather.temp_low, current_weather.temp_high, weight = our_planet.sun_position) + temperature = LERP(current_weather.temp_low, current_weather.temp_high, our_planet.sun_position) our_planet.needs_work |= PLANET_PROCESS_TEMP /datum/weather_holder/proc/get_weather_datum(desired_type) @@ -140,6 +146,18 @@ var/list/transition_messages = list()// List of messages shown to all outdoor mobs when this weather is transitioned to, for flavor. Not shown if already this weather. var/observed_message = null // What is shown to a player 'examining' the weather. + // Looping sound datums for weather sounds, both inside and outside. + var/datum/looping_sound/outdoor_sounds = null + var/datum/looping_sound/indoor_sounds = null + var/outdoor_sounds_type = null + var/indoor_sounds_type = null + +/datum/weather/New() + if(outdoor_sounds_type) + outdoor_sounds = new outdoor_sounds_type(list(), FALSE, TRUE) + if(indoor_sounds_type) + indoor_sounds = new indoor_sounds_type(list(), FALSE, TRUE) + /datum/weather/proc/process_effects() show_message = FALSE // Need to reset the show_message var, just in case if(effect_message) // Only bother with the code below if we actually need to display something @@ -148,6 +166,71 @@ show_message = TRUE // Tell the rest of the process that we need to make a message return +/datum/weather/proc/process_sounds() + if(!outdoor_sounds && !indoor_sounds) // No point bothering if we have no sounds. + return + + for(var/z_level in 1 to world.maxz) + for(var/a in GLOB.players_by_zlevel[z_level]) + var/mob/M = a + + // Check if the mob left the z-levels we control. If so, make the sounds stop for them. + if(!(z_level in holder.our_planet.expected_z_levels)) + hear_indoor_sounds(M, FALSE) + hear_outdoor_sounds(M, FALSE) + continue + + // Otherwise they should hear some sounds, depending on if they're inside or not. + var/turf/T = get_turf(M) + if(istype(T)) + if(T.outdoors) // Mob is currently outdoors. + hear_outdoor_sounds(M, TRUE) + hear_indoor_sounds(M, FALSE) + + else // Mob is currently indoors. + hear_outdoor_sounds(M, FALSE) + hear_indoor_sounds(M, TRUE) + + else + hear_indoor_sounds(M, FALSE) + hear_outdoor_sounds(M, FALSE) + +/datum/weather/proc/start_sounds() + if(outdoor_sounds) + outdoor_sounds.start() + if(indoor_sounds) + indoor_sounds.start() + +/datum/weather/proc/stop_sounds() + if(outdoor_sounds) + outdoor_sounds.stop() + if(indoor_sounds) + indoor_sounds.stop() + + // Stop everything just in case. + for(var/z_level in 1 to world.maxz) + for(var/a in GLOB.players_by_zlevel[z_level]) + hear_indoor_sounds(a, FALSE) + hear_outdoor_sounds(a, FALSE) + +// Adds or removes someone from the outdoor list. +/datum/weather/proc/hear_outdoor_sounds(mob/M, adding) + if(!outdoor_sounds) + return + if(adding) + outdoor_sounds.output_atoms |= M + return + outdoor_sounds.output_atoms -= M + +// Ditto, for indoors. +/datum/weather/proc/hear_indoor_sounds(mob/M, adding) + if(!indoor_sounds) + return + if(adding) + indoor_sounds.output_atoms |= M + return + indoor_sounds.output_atoms -= M + // All this does is hold the weather icon. /atom/movable/weather_visuals icon = 'icons/effects/weather.dmi' diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index fcd737d82b..7b464f6f50 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -199,6 +199,17 @@ return ..() +// APCs are pixel-shifted, so they need to be updated. +/obj/machinery/power/apc/set_dir(new_dir) + ..() + pixel_x = (src.dir & 3)? 0 : (src.dir == 4 ? 24 : -24) + pixel_y = (src.dir & 3)? (src.dir ==1 ? 24 : -24) : 0 + if(terminal) + terminal.disconnect_from_network() + terminal.set_dir(src.dir) // Terminal has same dir as master + terminal.connect_to_network() // Refresh the network the terminal is connected to. + return + /obj/machinery/power/apc/proc/energy_fail(var/duration) failure_timer = max(failure_timer, round(duration)) @@ -811,7 +822,7 @@ ) // update the ui if it exists, returns null if no ui is passed/found - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.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 diff --git a/code/modules/power/breaker_box.dm b/code/modules/power/breaker_box.dm index 856697e033..cf38607a56 100644 --- a/code/modules/power/breaker_box.dm +++ b/code/modules/power/breaker_box.dm @@ -27,7 +27,7 @@ for(var/datum/nano_module/rcon/R in world) R.FindDevices() -/obj/machinery/power/breakerbox/initialize() +/obj/machinery/power/breakerbox/Initialize() . = ..() default_apply_parts() @@ -35,7 +35,7 @@ icon_state = "bbox_on" // Enabled on server startup. Used in substations to keep them in bypass mode. -/obj/machinery/power/breakerbox/activated/initialize() +/obj/machinery/power/breakerbox/activated/Initialize() . = ..() set_state(1) diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 6717edf95d..4fe63628b7 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -59,14 +59,13 @@ var/list/possible_cable_coil_colours = list( var/obj/machinery/power/breakerbox/breaker_box /obj/structure/cable/drain_power(var/drain_check, var/surge, var/amount = 0) - if(drain_check) return 1 - var/datum/powernet/PN = get_powernet() - if(!PN) return 0 + if(!powernet) + return 0 - return PN.draw_power(amount) + return powernet.draw_power(amount) /obj/structure/cable/yellow color = COLOR_YELLOW @@ -122,6 +121,35 @@ var/list/possible_cable_coil_colours = list( to_chat(user, "The cable is not powered.") return + +// Rotating cables requires d1 and d2 to be rotated +/obj/structure/cable/set_dir(new_dir) + if(powernet) + cut_cable_from_powernet() // Remove this cable from the powernet so the connections update + + // If d1 is 0, then it's a not, and doesn't rotate + if(d1) + // Using turn will maintain the cable's shape + // Taking the difference between current orientation and new one + d1 = turn(d1, dir2angle(new_dir) - dir2angle(dir)) + d2 = turn(d2, dir2angle(new_dir) - dir2angle(dir)) + + // Maintain d1 < d2 + if(d1 > d2) + var/temp = d1 + d1 = d2 + d2 = temp + + // ..() Cable sprite generation is dependent upon only d1 and d2. + // Actually changing dir will rotate the generated sprite to look wrong, but function correctly. + update_icon() + // Add this cable back to the powernet, if it's connected to any + if(d1) + mergeConnectedNetworks(d1) + else + mergeConnectedNetworksOnTurf() + mergeConnectedNetworks(d2) + /////////////////////////////////// // General procedures /////////////////////////////////// @@ -139,10 +167,6 @@ var/list/possible_cable_coil_colours = list( icon_state = "[d1]-[d2]" alpha = invisibility ? 127 : 255 -// returns the powernet this cable belongs to -/obj/structure/cable/proc/get_powernet() //TODO: remove this as it is obsolete - return powernet - //Telekinesis has no effect on a cable /obj/structure/cable/attack_tk(mob/user) return @@ -532,7 +556,7 @@ obj/structure/cable/proc/cableColor(var/colorC) if(!S || S.robotic < ORGAN_ROBOT || S.open == 3) return ..() - var/use_amt = min(src.amount, ceil(S.burn_dam/5), 5) + var/use_amt = min(src.amount, CEILING(S.burn_dam/5, 1), 5) if(can_use(use_amt)) if(S.robo_repair(5*use_amt, BURN, "some damaged wiring", src, user)) src.use(use_amt) diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index 2a18becdc1..238aaa3196 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -34,11 +34,11 @@ charge = maxcharge update_icon() if(self_recharge) - processing_objects |= src + START_PROCESSING(SSobj, src) /obj/item/weapon/cell/Destroy() if(self_recharge) - processing_objects -= src + STOP_PROCESSING(SSobj, src) return ..() /obj/item/weapon/cell/get_cell() diff --git a/code/modules/power/cells/device_cells.dm b/code/modules/power/cells/device_cells.dm index 9cacf67073..c7e1309101 100644 --- a/code/modules/power/cells/device_cells.dm +++ b/code/modules/power/cells/device_cells.dm @@ -20,7 +20,7 @@ maxcharge = 2400 charge_amount = 20 -/obj/item/weapon/cell/device/weapon/empty/initialize() +/obj/item/weapon/cell/device/weapon/empty/Initialize() . = ..() charge = 0 update_icon() diff --git a/code/modules/power/cells/power_cells.dm b/code/modules/power/cells/power_cells.dm index cec7cef512..07eb9996a3 100644 --- a/code/modules/power/cells/power_cells.dm +++ b/code/modules/power/cells/power_cells.dm @@ -102,7 +102,7 @@ var/amount = 100 var/used = FALSE -/obj/item/device/fbp_backup_cell/initialize() +/obj/item/device/fbp_backup_cell/Initialize() overlays += image(icon,"[icon_state]1") /obj/item/device/fbp_backup_cell/attack(mob/living/M as mob, mob/user as mob) diff --git a/code/modules/power/fusion/core/_core.dm b/code/modules/power/fusion/core/_core.dm index 329170be44..99b0346e62 100644 --- a/code/modules/power/fusion/core/_core.dm +++ b/code/modules/power/fusion/core/_core.dm @@ -27,12 +27,12 @@ var/list/fusion_cores = list() /obj/machinery/power/fusion_core/mapped anchored = 1 -/obj/machinery/power/fusion_core/initialize() +/obj/machinery/power/fusion_core/Initialize() . = ..() fusion_cores += src default_apply_parts() -/obj/machinery/power/fusion_core/mapped/initialize() +/obj/machinery/power/fusion_core/mapped/Initialize() . = ..() connect_to_network() @@ -94,7 +94,7 @@ var/list/fusion_cores = list() . = owned_field.bullet_act(Proj) /obj/machinery/power/fusion_core/proc/set_strength(var/value) - value = Clamp(value, MIN_FIELD_STR, MAX_FIELD_STR) + value = CLAMP(value, MIN_FIELD_STR, MAX_FIELD_STR) field_strength = value active_power_usage = 5 * value if(owned_field) diff --git a/code/modules/power/fusion/core/core_control.dm b/code/modules/power/fusion/core/core_control.dm index 48e3a8c87c..dc5e16c87e 100644 --- a/code/modules/power/fusion/core/core_control.dm +++ b/code/modules/power/fusion/core/core_control.dm @@ -11,7 +11,7 @@ /obj/machinery/computer/fusion_core_control/attackby(var/obj/item/thing, var/mob/user) ..() - if(thing.is_multitool()) //VOREStation Edit + if(istype(thing, /obj/item/device/multitool)) var/new_ident = input("Enter a new ident tag.", "Core Control", id_tag) as null|text if(new_ident && user.Adjacent(src)) id_tag = new_ident @@ -140,7 +140,7 @@ return if(href_list["access_device"]) - var/idx = Clamp(text2num(href_list["toggle_active"]), 1, connected_devices.len) + var/idx = CLAMP(text2num(href_list["toggle_active"]), 1, connected_devices.len) cur_viewed_device = connected_devices[idx] updateUsrDialog() return 1 diff --git a/code/modules/power/fusion/core/core_field.dm b/code/modules/power/fusion/core/core_field.dm index f5d85fb4bf..f0eca3add6 100644 --- a/code/modules/power/fusion/core/core_field.dm +++ b/code/modules/power/fusion/core/core_field.dm @@ -117,7 +117,7 @@ catcher.SetSize(7) particle_catchers.Add(catcher) - processing_objects.Add(src) + START_PROCESSING(SSobj, src) /obj/effect/fusion_em_field/process() //make sure the field generator is still intact @@ -171,8 +171,8 @@ use_power = light_max_power else var/temp_mod = ((plasma_temperature-5000)/20000) - use_range = light_min_range + ceil((light_max_range-light_min_range)*temp_mod) - use_power = light_min_power + ceil((light_max_power-light_min_power)*temp_mod) + use_range = light_min_range + CEILING((light_max_range-light_min_range)*temp_mod, 1) + use_power = light_min_power + CEILING((light_max_power-light_min_power)*temp_mod, 1) if(last_range != use_range || last_power != use_power) set_light(use_range,use_power) @@ -318,8 +318,8 @@ /obj/effect/fusion_em_field/proc/Radiate() if(istype(loc, /turf)) - var/empsev = max(1, min(3, ceil(size/2))) - for(var/atom/movable/AM in range(max(1,Floor(size/2)), loc)) + var/empsev = max(1, min(3, CEILING(size/2, 1))) + for(var/atom/movable/AM in range(max(1,FLOOR(size/2, 1)), loc)) if(AM == src || AM == owned_core || !AM.simulated) continue @@ -386,7 +386,7 @@ //determine a random amount to actually react this cycle, and remove it from the standard pool //this is a hack, and quite nonrealistic :( for(var/reactant in react_pool) - react_pool[reactant] = rand(Floor(react_pool[reactant]/2),react_pool[reactant]) + react_pool[reactant] = rand(FLOOR(react_pool[reactant]/2, 1),react_pool[reactant]) dormant_reactant_quantities[reactant] -= react_pool[reactant] if(!react_pool[reactant]) react_pool -= reactant @@ -496,7 +496,7 @@ if(owned_core) owned_core.owned_field = null owned_core = null - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) . = ..() /obj/effect/fusion_em_field/bullet_act(var/obj/item/projectile/Proj) @@ -574,7 +574,7 @@ /obj/effect/fusion_em_field/proc/Rupture() visible_message("\The [src] shudders like a dying animal before flaring to eye-searing brightness and rupturing!") set_light(15, 15, "#CCCCFF") - empulse(get_turf(src), ceil(plasma_temperature/1000), ceil(plasma_temperature/300)) + empulse(get_turf(src), CEILING(plasma_temperature/1000, 1), CEILING(plasma_temperature/300, 1)) global_announcer.autosay("WARNING: FIELD RUPTURE IMMINENT!", "Containment Monitor") RadiateAll() var/list/things_in_range = range(10, owned_core) @@ -584,7 +584,7 @@ turfs_in_range.Add(T) explosion(pick(things_in_range), -1, 5, 5, 5) - empulse(pick(things_in_range), ceil(plasma_temperature/1000), ceil(plasma_temperature/300)) + empulse(pick(things_in_range), CEILING(plasma_temperature/1000, 1), CEILING(plasma_temperature/300, 1)) spawn(25) explosion(pick(things_in_range), -1, 5, 5, 5) spawn(25) @@ -655,7 +655,7 @@ /obj/effect/fusion_em_field/proc/BluespaceQuenchEvent() //!!FUN!! causes a number of explosions in an area around the core. Will likely destory or heavily damage the reactor. visible_message("\The [src] shudders like a dying animal before flaring to eye-searing brightness and rupturing!") set_light(15, 15, "#CCCCFF") - empulse(get_turf(src), ceil(plasma_temperature/1000), ceil(plasma_temperature/300)) + empulse(get_turf(src), CEILING(plasma_temperature/1000, 1), CEILING(plasma_temperature/300, 1)) global_announcer.autosay("WARNING: FIELD RUPTURE IMMINENT!", "Containment Monitor") RadiateAll() var/list/things_in_range = range(10, owned_core) @@ -665,7 +665,7 @@ turfs_in_range.Add(T) for(var/loopcount = 1 to 10) explosion(pick(things_in_range), -1, 5, 5, 5) - empulse(pick(things_in_range), ceil(plasma_temperature/1000), ceil(plasma_temperature/300)) + empulse(pick(things_in_range), CEILING(plasma_temperature/1000, 1), CEILING(plasma_temperature/300, 1)) Destroy() owned_core.Shutdown() return diff --git a/code/modules/power/fusion/fuel_assembly/fuel_assembly.dm b/code/modules/power/fusion/fuel_assembly/fuel_assembly.dm index 29d9362015..4149274351 100644 --- a/code/modules/power/fusion/fuel_assembly/fuel_assembly.dm +++ b/code/modules/power/fusion/fuel_assembly/fuel_assembly.dm @@ -17,7 +17,7 @@ fuel_colour = _colour ..(newloc) -/obj/item/weapon/fuel_assembly/initialize() +/obj/item/weapon/fuel_assembly/Initialize() . = ..() var/material/material = get_material_by_name(fuel_type) if(istype(material)) @@ -28,7 +28,7 @@ if(material.radioactivity) radioactivity = material.radioactivity desc += " It is warm to the touch." - processing_objects += src + START_PROCESSING(SSobj, src) if(material.luminescence) set_light(material.luminescence, material.luminescence, material.icon_colour) else @@ -46,10 +46,10 @@ return PROCESS_KILL if(istype(loc, /turf)) - radiation_repository.radiate(src, max(1,ceil(radioactivity/30))) + radiation_repository.radiate(src, max(1,CEILING(radioactivity/30, 1))) /obj/item/weapon/fuel_assembly/Destroy() - processing_objects -= src + STOP_PROCESSING(SSobj, src) return ..() // Mapper shorthand. diff --git a/code/modules/power/fusion/fuel_assembly/fuel_compressor.dm b/code/modules/power/fusion/fuel_assembly/fuel_compressor.dm index 375af68696..d38fd76e86 100644 --- a/code/modules/power/fusion/fuel_assembly/fuel_compressor.dm +++ b/code/modules/power/fusion/fuel_assembly/fuel_compressor.dm @@ -7,7 +7,7 @@ circuit = /obj/item/weapon/circuitboard/fusion_fuel_compressor -/obj/machinery/fusion_fuel_compressor/initialize() +/obj/machinery/fusion_fuel_compressor/Initialize() . = ..() default_apply_parts() diff --git a/code/modules/power/fusion/fuel_assembly/fuel_control.dm b/code/modules/power/fusion/fuel_assembly/fuel_control.dm index f0443b5425..6825f9ba37 100644 --- a/code/modules/power/fusion/fuel_assembly/fuel_control.dm +++ b/code/modules/power/fusion/fuel_assembly/fuel_control.dm @@ -96,7 +96,7 @@ /obj/machinery/computer/fusion_fuel_control/attackby(var/obj/item/W, var/mob/user) ..() - if(W.is_multitool()) //VOREStation Edit + if(istype(W, /obj/item/device/multitool)) var/new_ident = input("Enter a new ident tag.", "Fuel Control", id_tag) as null|text if(new_ident && user.Adjacent(src)) id_tag = new_ident diff --git a/code/modules/power/fusion/fuel_assembly/fuel_injector.dm b/code/modules/power/fusion/fuel_assembly/fuel_injector.dm index 79794ff069..80a512b91b 100644 --- a/code/modules/power/fusion/fuel_assembly/fuel_injector.dm +++ b/code/modules/power/fusion/fuel_assembly/fuel_injector.dm @@ -18,7 +18,7 @@ var/list/fuel_injectors = list() var/injecting = 0 var/obj/item/weapon/fuel_assembly/cur_assembly -/obj/machinery/fusion_fuel_injector/initialize() +/obj/machinery/fusion_fuel_injector/Initialize() . = ..() fuel_injectors += src default_apply_parts() @@ -134,22 +134,22 @@ var/list/fuel_injectors = list() else StopInjecting() -/obj/machinery/fusion_fuel_injector/verb/rotate_clock() +/obj/machinery/fusion_fuel_injector/verb/rotate_clockwise() set category = "Object" - set name = "Rotate Generator (Clockwise)" + set name = "Rotate Generator Clockwise" set src in view(1) if (usr.incapacitated() || usr.restrained() || anchored) return - src.dir = turn(src.dir, -90) + src.set_dir(turn(src.dir, 270)) -/obj/machinery/fusion_fuel_injector/verb/rotate_anticlock() +/obj/machinery/fusion_fuel_injector/verb/rotate_counterclockwise() set category = "Object" - set name = "Rotate Generator (Counter-clockwise)" + set name = "Rotate Generator Counterclockwise" set src in view(1) if (usr.incapacitated() || usr.restrained() || anchored) return - src.dir = turn(src.dir, 90) + src.set_dir(turn(src.dir, 90)) diff --git a/code/modules/power/fusion/gyrotron/gyrotron.dm b/code/modules/power/fusion/gyrotron/gyrotron.dm index 23697d2449..539e9cbda6 100644 --- a/code/modules/power/fusion/gyrotron/gyrotron.dm +++ b/code/modules/power/fusion/gyrotron/gyrotron.dm @@ -20,7 +20,7 @@ var/list/gyrotrons = list() anchored = 1 state = 2 -/obj/machinery/power/emitter/gyrotron/initialize() +/obj/machinery/power/emitter/gyrotron/Initialize() gyrotrons += src active_power_usage = mega_energy * 50000 default_apply_parts() diff --git a/code/modules/power/fusion/gyrotron/gyrotron_control.dm b/code/modules/power/fusion/gyrotron/gyrotron_control.dm index cf8cae9d41..4f5abdbd3b 100644 --- a/code/modules/power/fusion/gyrotron/gyrotron_control.dm +++ b/code/modules/power/fusion/gyrotron/gyrotron_control.dm @@ -73,7 +73,7 @@ if(!new_val) to_chat(usr, "That's not a valid number.") return 1 - G.mega_energy = Clamp(new_val, 1, 50) + G.mega_energy = CLAMP(new_val, 1, 50) G.active_power_usage = G.mega_energy * 1500 updateUsrDialog() return 1 @@ -83,7 +83,7 @@ if(!new_val) to_chat(usr, "That's not a valid number.") return 1 - G.rate = Clamp(new_val, 1, 10) + G.rate = CLAMP(new_val, 1, 10) updateUsrDialog() return 1 @@ -96,7 +96,7 @@ /obj/machinery/computer/gyrotron_control/attackby(var/obj/item/W, var/mob/user) ..() - if(W.is_multitool()) //VOREStation Edit + if(istype(W, /obj/item/device/multitool)) var/new_ident = input("Enter a new ident tag.", "Gyrotron Control", id_tag) as null|text if(new_ident && user.Adjacent(src)) id_tag = new_ident diff --git a/code/modules/power/generator.dm b/code/modules/power/generator.dm index 02095e0f81..2eadfc520a 100644 --- a/code/modules/power/generator.dm +++ b/code/modules/power/generator.dm @@ -22,12 +22,18 @@ var/lastgen2 = 0 var/effective_gen = 0 var/lastgenlev = 0 + var/datum/looping_sound/generator/soundloop -/obj/machinery/power/generator/New() - ..() +/obj/machinery/power/generator/Initialize() + soundloop = new(list(src), FALSE) desc = initial(desc) + " Rated for [round(max_power/1000)] kW." spawn(1) reconnect() + return ..() + +/obj/machinery/power/generator/Destroy() + QDEL_NULL(soundloop) + return ..() //generators connect in dir and reverse_dir(dir) directions //mnemonic to determine circulator/generator directions: the cirulators orbit clockwise around the generator @@ -124,6 +130,13 @@ stored_energy -= lastgen1 effective_gen = (lastgen1 + lastgen2) / 2 + // Sounds. + if(effective_gen > (max_power * 0.05)) // More than 5% and sounds start. + soundloop.start() + soundloop.volume = LERP(1, 40, effective_gen / max_power) + else + soundloop.stop() + // update icon overlays and power usage only if displayed level has changed var/genlev = max(0, min( round(11*effective_gen / max_power), 11)) if(effective_gen > 100 && genlev == 0) @@ -198,7 +211,7 @@ // update the ui if it exists, returns null if no ui is passed/found - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.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 @@ -215,9 +228,19 @@ updateicon() -/obj/machinery/power/generator/verb/rotate_clock() +/obj/machinery/power/generator/verb/rotate_clockwise() set category = "Object" - set name = "Rotate Generator (Clockwise)" + set name = "Rotate Generator Clockwise" + set src in view(1) + + if (usr.stat || usr.restrained() || anchored) + return + + src.set_dir(turn(src.dir, 270)) + +/obj/machinery/power/generator/verb/rotate_counterclockwise() + set category = "Object" + set name = "Rotate Generator Counterclockwise" set src in view(1) if (usr.stat || usr.restrained() || anchored) @@ -225,16 +248,6 @@ src.set_dir(turn(src.dir, 90)) -/obj/machinery/power/generator/verb/rotate_anticlock() - set category = "Object" - set name = "Rotate Generator (Counterclockwise)" - set src in view(1) - - if (usr.stat || usr.restrained() || anchored) - return - - src.set_dir(turn(src.dir, -90)) - /obj/machinery/power/generator/power_spike() // if(!effective_gen >= max_power / 2 && powernet) // Don't make a spike if we're not making a whole lot of power. // return diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index a16faa49bd..d1f6afa4c4 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -179,6 +179,11 @@ var/shows_alerts = TRUE // Flag for if this fixture should show alerts. Make sure icon states exist! var/current_alert = null // Which alert are we showing right now? + var/auto_flicker = FALSE // If true, will constantly flicker, so long as someone is around to see it (otherwise its a waste of CPU). + +/obj/machinery/light/flicker + auto_flicker = TRUE + // the smaller bulb light fixture /obj/machinery/light/small @@ -191,6 +196,9 @@ light_type = /obj/item/weapon/light/bulb shows_alerts = FALSE +/obj/machinery/light/small/flicker + auto_flicker = TRUE + /obj/machinery/light/flamp icon = 'icons/obj/lighting.dmi' icon_state = "flamp1" @@ -205,10 +213,18 @@ shows_alerts = FALSE var/lamp_shade = 1 +/obj/machinery/light/flamp/flicker + auto_flicker = TRUE + + /obj/machinery/light/small/emergency brightness_range = 4 brightness_color = "#da0205" +/obj/machinery/light/small/emergency/flicker + auto_flicker = TRUE + + /obj/machinery/light/spot name = "spotlight" fitting = "large tube" @@ -217,6 +233,10 @@ brightness_range = 12 brightness_power = 0.9 +/obj/machinery/light/spot/flicker + auto_flicker = TRUE + + /obj/machinery/light/built/New() status = LIGHT_EMPTY update(0) @@ -333,7 +353,8 @@ if(on) if(light_range != brightness_range || light_power != brightness_power || light_color != brightness_color) - switchcount++ + if(!auto_flicker) + switchcount++ if(rigged) if(status == LIGHT_OK && trigger) @@ -716,6 +737,13 @@ if(on) use_power(light_range * LIGHTING_POWER_FACTOR, LIGHT) + if(auto_flicker && !flickering) + if(check_for_player_proximity(src, radius = 12, ignore_ghosts = FALSE, ignore_afk = TRUE)) + seton(TRUE) // Lights must be on to flicker. + flicker(5) + else + seton(FALSE) // Otherwise keep it dark and spooky for when someone shows up. + // called when area power state changes /obj/machinery/light/power_change() diff --git a/code/modules/power/lightswitch_vr.dm b/code/modules/power/lightswitch_vr.dm index 937660dcbc..db1881c4b3 100644 --- a/code/modules/power/lightswitch_vr.dm +++ b/code/modules/power/lightswitch_vr.dm @@ -58,7 +58,7 @@ var/x_offset = 26 var/y_offset = 26 -/obj/structure/construction/initialize(var/mapload, var/ndir, var/building = FALSE) +/obj/structure/construction/Initialize(var/mapload, var/ndir, var/building = FALSE) . = ..() if(ndir) set_dir(ndir) @@ -83,7 +83,7 @@ /obj/structure/construction/attackby(obj/item/weapon/W as obj, mob/user as mob) add_fingerprint(user) - if(W.is_welder()) + if(istype(W, /obj/item/weapon/weldingtool)) if(stage == FRAME_UNFASTENED) var/obj/item/weapon/weldingtool/WT = W if(!WT.remove_fuel(0, user)) @@ -117,7 +117,7 @@ update_icon() return - else if(W.is_cable_coil()) + else if(istype(W, /obj/item/stack/cable_coil)) if (stage == FRAME_FASTENED) var/obj/item/stack/cable_coil/coil = W if (coil.use(1)) diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm index 35a860ec1b..5e4c2e6207 100644 --- a/code/modules/power/port_gen.dm +++ b/code/modules/power/port_gen.dm @@ -110,7 +110,7 @@ var/temperature = 0 //The current temperature var/overheating = 0 //if this gets high enough the generator explodes -/obj/machinery/power/port_gen/pacman/initialize() +/obj/machinery/power/port_gen/pacman/Initialize() . = ..() if(anchored) connect_to_network() @@ -327,7 +327,7 @@ - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "pacman.tmpl", src.name, 500, 560) ui.set_initial_data(data) diff --git a/code/modules/power/singularity/act.dm b/code/modules/power/singularity/act.dm index 5998906c66..5d33ee440e 100644 --- a/code/modules/power/singularity/act.dm +++ b/code/modules/power/singularity/act.dm @@ -75,7 +75,6 @@ return /obj/machinery/power/supermatter/shard/singularity_act() - src.forceMove(null) qdel(src) return 5000 @@ -90,7 +89,6 @@ SetUniversalState(/datum/universal_state/supermatter_cascade) log_admin("New super singularity made by eating a SM crystal [prints]. Last touched by [src.fingerprintslast].") message_admins("New super singularity made by eating a SM crystal [prints]. Last touched by [src.fingerprintslast].") - src.forceMove(null) qdel(src) return 50000 @@ -115,6 +113,15 @@ ChangeTurf(get_base_turf_by_area(src)) return 2 +/turf/simulated/floor/singularity_pull(S, current_size) + if(flooring && current_size >= STAGE_THREE) + if(prob(current_size / 2)) + var/leave_tile = TRUE + if(broken || burnt || flooring.flags & TURF_IS_FRAGILE) + leave_tile = FALSE + playsound(src, 'sound/items/crowbar.ogg', 50, 1) + make_plating(leave_tile) + /turf/simulated/wall/singularity_pull(S, current_size) if(!reinf_material) diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index ac4401387a..f847813923 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -30,18 +30,18 @@ var/integrity = 80 -/obj/machinery/power/emitter/verb/rotate() - set name = "Rotate" +/obj/machinery/power/emitter/verb/rotate_clockwise() + set name = "Rotate Emitter Clockwise" set category = "Object" set src in oview(1) if (src.anchored || usr:stat) - usr << "It is fastened to the floor!" + to_chat(usr, "It is fastened to the floor!") return 0 - src.set_dir(turn(src.dir, 90)) + src.set_dir(turn(src.dir, 270)) return 1 -/obj/machinery/power/emitter/initialize() +/obj/machinery/power/emitter/Initialize() . = ..() if(state == 2 && anchored) connect_to_network() @@ -142,7 +142,8 @@ var/obj/item/projectile/beam/emitter/A = get_emitter_beam() A.damage = round(power_per_shot/EMITTER_DAMAGE_POWER_TRANSFER) - A.launch( get_step(src.loc, src.dir) ) + A.firer = src + A.fire(dir2angle(dir)) /obj/machinery/power/emitter/attackby(obj/item/W, mob/user) @@ -207,7 +208,7 @@ return if(istype(W, /obj/item/stack/material) && W.get_material_name() == DEFAULT_WALL_MATERIAL) - var/amt = Ceiling(( initial(integrity) - integrity)/10) + var/amt = CEILING(( initial(integrity) - integrity)/10, 1) if(!amt) to_chat(user, "\The [src] is already fully repaired.") return diff --git a/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm b/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm index e89ff0dcce..7460830f21 100644 --- a/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm +++ b/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm @@ -89,24 +89,24 @@ So, hopefully this is helpful if any more icons are to be added/changed/wonderin return -/obj/structure/particle_accelerator/verb/rotate() +/obj/structure/particle_accelerator/verb/rotate_clockwise() set name = "Rotate Clockwise" set category = "Object" set src in oview(1) if (src.anchored || usr:stat) - usr << "It is fastened to the floor!" + to_chat(usr, "It is fastened to the floor!") return 0 src.set_dir(turn(src.dir, 270)) return 1 -/obj/structure/particle_accelerator/verb/rotateccw() +/obj/structure/particle_accelerator/verb/rotate_counterclockwise() set name = "Rotate Counter Clockwise" set category = "Object" set src in oview(1) if (src.anchored || usr:stat) - usr << "It is fastened to the floor!" + to_chat(usr, "It is fastened to the floor!") return 0 src.set_dir(turn(src.dir, 90)) return 1 @@ -269,24 +269,24 @@ So, hopefully this is helpful if any more icons are to be added/changed/wonderin var/desc_holder = null -/obj/machinery/particle_accelerator/verb/rotate() +/obj/machinery/particle_accelerator/verb/rotate_clockwise() set name = "Rotate Clockwise" set category = "Object" set src in oview(1) if (src.anchored || usr:stat) - usr << "It is fastened to the floor!" + to_chat(usr, "It is fastened to the floor!") return 0 src.set_dir(turn(src.dir, 270)) return 1 -/obj/machinery/particle_accelerator/verb/rotateccw() +/obj/machinery/particle_accelerator/verb/rotate_counterclockwise() set name = "Rotate Counter-Clockwise" set category = "Object" set src in oview(1) if (src.anchored || usr:stat) - usr << "It is fastened to the floor!" + to_chat(usr, "It is fastened to the floor!") return 0 src.set_dir(turn(src.dir, 90)) return 1 @@ -333,11 +333,9 @@ So, hopefully this is helpful if any more icons are to be added/changed/wonderin else return - /obj/machinery/particle_accelerator/proc/update_state() return 0 - /obj/machinery/particle_accelerator/proc/process_tool_hit(var/obj/item/O, var/mob/user) if(!(O) || !(user)) return 0 diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm index 878e92b072..3768ab9535 100644 --- a/code/modules/power/singularity/singularity.dm +++ b/code/modules/power/singularity/singularity.dm @@ -37,14 +37,14 @@ GLOBAL_LIST_BOILERPLATE(all_singularities, /obj/singularity) energy = starting_energy ..() - processing_objects += src + START_PROCESSING(SSobj, src) for(var/obj/machinery/power/singularity_beacon/singubeacon in machines) if(singubeacon.active) target = singubeacon break /obj/singularity/Destroy() - processing_objects -= src + STOP_PROCESSING(SSobj, src) return ..() /obj/singularity/attack_hand(mob/user as mob) diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm index 2e97d735ba..ad76cb061f 100644 --- a/code/modules/power/smes.dm +++ b/code/modules/power/smes.dm @@ -328,7 +328,7 @@ data["outputting"] = 0 // smes is not outputting // update the ui if it exists, returns null if no ui is passed/found - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.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 diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm index 2d9f1803ba..d5cf8ef993 100644 --- a/code/modules/power/solar.dm +++ b/code/modules/power/solar.dm @@ -1,7 +1,7 @@ #define SOLAR_MAX_DIST 40 -var/solar_gen_rate = 1500 -var/list/solars_list = list() +GLOBAL_VAR_INIT(solar_gen_rate, 1500) +GLOBAL_LIST_EMPTY(solars_list) /obj/machinery/power/solar name = "solar panel" @@ -25,8 +25,8 @@ var/list/solars_list = list() /obj/machinery/power/solar/drain_power() return -1 -/obj/machinery/power/solar/New(var/turf/loc, var/obj/item/solar_assembly/S) - ..(loc) +/obj/machinery/power/solar/Initialize(mapload, obj/item/solar_assembly/S) + . = ..() Make(S) connect_to_network() @@ -51,7 +51,7 @@ var/list/solars_list = list() if(!S) S = new /obj/item/solar_assembly(src) S.glass_type = /obj/item/stack/material/glass - S.anchored = 1 + S.anchored = TRUE S.loc = src if(S.glass_type == /obj/item/stack/material/glass/reinforced) //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 @@ -102,18 +102,18 @@ var/list/solars_list = list() src.set_dir(angle2dir(adir)) return -//calculates the fraction of the sunlight that the panel recieves +//calculates the fraction of the SSsun.sunlight that the panel recieves /obj/machinery/power/solar/proc/update_solar_exposure() - if(!sun) + if(!SSsun.sun) return if(obscured) sunfrac = 0 return - //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)) + //find the smaller angle between the direction the panel is facing and the direction of the SSsun.sun (the sign is not important here) + var/p_angle = min(abs(adir - SSsun.sun.angle), 360 - abs(adir - SSsun.sun.angle)) - if(p_angle > 90) // if facing more than 90deg from sun, zero output + if(p_angle > 90) // if facing more than 90deg from SSsun.sun, zero output sunfrac = 0 return @@ -123,14 +123,14 @@ var/list/solars_list = list() /obj/machinery/power/solar/process()//TODO: remove/add this from machines to save on processing as needed ~Carn PRIORITY 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 + if(!SSsun.sun || !control) //if there's no SSsun.sun or the panel is not linked to a solar control computer, no need to proceed return 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 + if(obscured) //get no light from the SSsun.sun, so don't generate power return - var/sgen = solar_gen_rate * sunfrac + var/sgen = GLOB.solar_gen_rate * sunfrac add_avail(sgen) control.gen += sgen else //if we're no longer on the same powernet, remove from control computer @@ -173,7 +173,7 @@ var/list/solars_list = list() . = PROCESS_KILL return -//trace towards sun to see if we're in shadow +//trace towards SSsun.sun to see if we're in shadow /obj/machinery/power/solar/proc/occlusion() var/ax = x // start at the solar panel @@ -181,8 +181,8 @@ var/list/solars_list = list() var/turf/T = null for(var/i = 1 to 20) // 20 steps is enough - ax += sun.dx // do step - ay += sun.dy + ax += SSsun.sun.dx // do step + ay += SSsun.sun.dy T = locate( round(ax,0.5),round(ay,0.5),z) @@ -290,7 +290,7 @@ var/list/solars_list = list() var/lastgen = 0 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/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() @@ -306,12 +306,12 @@ var/list/solars_list = list() /obj/machinery/power/solar_control/disconnect_from_network() ..() - solars_list.Remove(src) + GLOB.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 + GLOB.solars_list |= src //... add it return to_return //search for unconnected panels and trackers in the computer powernet and connect them @@ -330,7 +330,7 @@ var/list/solars_list = list() connected_tracker = T T.set_control(src) -//called by the sun controller, update the facing angle (either manually or via tracking) and rotates the panels accordingly +//called by the SSsun.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 @@ -341,13 +341,13 @@ var/list/solars_list = list() 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) + connected_tracker.set_angle(SSsun.sun.angle) set_panels(cdir) updateDialog() -/obj/machinery/power/solar_control/initialize() +/obj/machinery/power/solar_control/Initialize() . = ..() if(!powernet) return set_panels(cdir) @@ -375,7 +375,7 @@ var/list/solars_list = list() /obj/machinery/power/solar_control/interact(mob/user) var/t = "Generated power : [round(lastgen)] W
      " - t += "Star Orientation: [sun.angle]° ([angle2text(sun.angle)])
      " + t += "Star Orientation: [SSsun.sun.angle]° ([angle2text(SSsun.sun.angle)])
      " t += "Array Orientation: [rate_control(src,"cdir","[cdir]°",1,15)] ([angle2text(cdir)])
      " t += "Tracking:
      " switch(track) @@ -445,9 +445,9 @@ var/list/solars_list = list() 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°... + 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° + nexttime += 36000/abs(trackrate) //reset the counter for the next 1� updateDialog() @@ -477,7 +477,7 @@ var/list/solars_list = list() track = text2num(href_list["track"]) if(track == 2) if(connected_tracker) - connected_tracker.set_angle(sun.angle) + connected_tracker.set_angle(SSsun.sun.angle) set_panels(cdir) else if (track == 1) //begin manual tracking src.targetdir = src.cdir @@ -487,7 +487,7 @@ var/list/solars_list = list() if(href_list["search_connected"]) src.search_for_connected() if(connected_tracker && track == 2) - connected_tracker.set_angle(sun.angle) + connected_tracker.set_angle(SSsun.sun.angle) src.set_panels(cdir) interact(usr) @@ -537,7 +537,7 @@ var/list/solars_list = list() spawn(150) // Wait 15 seconds to ensure everything was set up properly (such as, powernets, solar panels, etc. src.search_for_connected() if(connected_tracker && track == 2) - connected_tracker.set_angle(sun.angle) + connected_tracker.set_angle(SSsun.sun.angle) src.set_panels(cdir) // @@ -546,7 +546,7 @@ var/list/solars_list = list() /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 phoron! 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 phoron! 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 SSsun.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 SSsun.sun's movements and to send commands to the solar panels to change direction with the SSsun.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!

      " /proc/rate_control(var/S, var/V, var/C, var/Min=1, var/Max=5, var/Limit=null) //How not to name vars var/href = "JMP)",0,1) @@ -197,6 +203,11 @@ if(grav_pulling) supermatter_pull(src) + if(power) + // Volume will be 1 at no power, ~12.5 at ENERGY_NITROGEN, and 20+ at ENERGY_PHORON. + // Capped to 20 volume since higher volumes get annoying and it sounds worse. + soundloop.volume = min(round(power/10)+1, 20) + //Ok, get the air from the turf var/datum/gas_mixture/removed = null var/datum/gas_mixture/env = null @@ -322,7 +333,7 @@ data["ambient_pressure"] = round(env.return_pressure()) data["detonating"] = grav_pulling - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "supermatter_crystal.tmpl", "Supermatter Crystal", 500, 300) ui.set_initial_data(data) diff --git a/code/modules/power/tesla/coil.dm b/code/modules/power/tesla/coil.dm index 5b614ce629..76029fd66c 100644 --- a/code/modules/power/tesla/coil.dm +++ b/code/modules/power/tesla/coil.dm @@ -25,7 +25,7 @@ ..() wires = new(src) -/obj/machinery/power/tesla_coil/initialize() +/obj/machinery/power/tesla_coil/Initialize() . = ..() default_apply_parts() diff --git a/code/modules/power/tesla/energy_ball.dm b/code/modules/power/tesla/energy_ball.dm index 9274bb85a6..8c404e05c0 100644 --- a/code/modules/power/tesla/energy_ball.dm +++ b/code/modules/power/tesla/energy_ball.dm @@ -27,7 +27,7 @@ ..() miniball = is_miniball -/obj/singularity/energy_ball/initialize() +/obj/singularity/energy_ball/Initialize() . = ..() if(!miniball) set_light(10, 7, "#EEEEFF") @@ -65,7 +65,7 @@ set_dir(tesla_zap(src, 7, TESLA_DEFAULT_POWER, TRUE)) for (var/ball in orbiting_balls) - var/range = rand(1, Clamp(orbiting_balls.len, 3, 7)) + var/range = rand(1, CLAMP(orbiting_balls.len, 3, 7)) tesla_zap(ball, range, TESLA_MINI_POWER/7*range, TRUE) else energy = 0 // ensure we dont have miniballs of miniballs @@ -185,7 +185,6 @@ /obj/machinery/atmospherics, /obj/machinery/power/emitter, /obj/machinery/field_generator, - /mob/living/simple_animal, /obj/machinery/door/blast, /obj/machinery/particle_accelerator/control_box, /obj/structure/particle_accelerator/fuel_chamber, @@ -289,8 +288,8 @@ closest_grounding_rod.tesla_act(power, explosive, stun_mobs) else if(closest_mob) - var/shock_damage = Clamp(round(power/400), 10, 90) + rand(-5, 5) - closest_mob.electrocute_act(shock_damage, source, 1, ran_zone()) + var/shock_damage = CLAMP(round(power/400), 10, 90) + rand(-5, 5) + closest_mob.electrocute_act(shock_damage, source, 1 - closest_mob.get_shock_protection(), ran_zone()) log_game("TESLA([source.x],[source.y],[source.z]) Shocked [key_name(closest_mob)] for [shock_damage]dmg.") message_admins("Tesla zapped [key_name_admin(closest_mob)]!") if(issilicon(closest_mob)) diff --git a/code/modules/power/tesla/tesla_act.dm b/code/modules/power/tesla/tesla_act.dm index 8e617fca86..01b58f8a80 100644 --- a/code/modules/power/tesla/tesla_act.dm +++ b/code/modules/power/tesla/tesla_act.dm @@ -60,6 +60,9 @@ ..() //extend the zap explode() +/obj/mecha/tesla_act(power) + ..() + take_damage(power / 200, "energy") // A surface lightning strike will do 100 damage. diff --git a/code/modules/power/turbine.dm b/code/modules/power/turbine.dm index 0a9c8f1a3e..dbc90a634d 100644 --- a/code/modules/power/turbine.dm +++ b/code/modules/power/turbine.dm @@ -85,7 +85,7 @@ #define COMPFRICTION 5e5 #define COMPSTARTERLOAD 2800 -/obj/machinery/compressor/initialize() +/obj/machinery/compressor/Initialize() . = ..() default_apply_parts() gas_contained = new() @@ -194,7 +194,7 @@ #define TURBGENQ 100000 #define TURBGENG 0.8 -/obj/machinery/power/turbine/initialize() +/obj/machinery/power/turbine/Initialize() . = ..() default_apply_parts() // The outlet is pointed at the direction of the turbine component @@ -318,7 +318,7 @@ // Turbine Computer ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/obj/machinery/computer/turbine_computer/initialize() +/obj/machinery/computer/turbine_computer/Initialize() . = ..() return INITIALIZE_HINT_LATELOAD @@ -365,7 +365,7 @@ data["temp"] = compressor.gas_contained.temperature // update the ui if it exists, returns null if no ui is passed/found - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.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 diff --git a/code/modules/projectiles/ammunition/magazines.dm b/code/modules/projectiles/ammunition/magazines.dm index cfd96ac2aa..4230de4583 100644 --- a/code/modules/projectiles/ammunition/magazines.dm +++ b/code/modules/projectiles/ammunition/magazines.dm @@ -106,7 +106,7 @@ initial_ammo = 0 /obj/item/ammo_magazine/m45tommy - name = "tommygun magazine (.45)" + name = "Tommy Gun magazine (.45)" icon_state = "tommy-mag" mag_type = MAGAZINE ammo_type = /obj/item/ammo_casing/a45 @@ -115,14 +115,14 @@ max_ammo = 20 /obj/item/ammo_magazine/m45tommy/ap - name = "tommygun magazine (.45 AP)" + name = "Tommy Gun magazine (.45 AP)" ammo_type = /obj/item/ammo_casing/a45/ap /obj/item/ammo_magazine/m45tommy/empty initial_ammo = 0 /obj/item/ammo_magazine/m45tommydrum - name = "tommygun drum magazine (.45)" + name = "Tommy Gun drum magazine (.45)" icon_state = "tommy-drum" w_class = ITEMSIZE_NORMAL // Bulky ammo doesn't fit in your pockets! mag_type = MAGAZINE @@ -132,7 +132,7 @@ max_ammo = 50 /obj/item/ammo_magazine/m45tommydrum/ap - name = "tommygun drum magazine (.45 AP)" + name = "Tommy Gun drum magazine (.45 AP)" ammo_type = /obj/item/ammo_casing/a45/ap /obj/item/ammo_magazine/m45tommydrum/empty @@ -626,10 +626,10 @@ /obj/item/ammo_magazine/m12gdrum name = "magazine (12 gauge)" - icon_state = "12g" + icon_state = "ashot-mag" mag_type = MAGAZINE caliber = "12g" - matter = list(DEFAULT_WALL_MATERIAL = 13000) //did the math. now fixed the exploityness of this thing. Have fun! + matter = list(DEFAULT_WALL_MATERIAL = 13000) ammo_type = /obj/item/ammo_casing/a12g max_ammo = 24 multiple_sprites = 1 diff --git a/code/modules/projectiles/ammunition/rounds.dm b/code/modules/projectiles/ammunition/rounds.dm index e87c91409d..d81f7fe312 100644 --- a/code/modules/projectiles/ammunition/rounds.dm +++ b/code/modules/projectiles/ammunition/rounds.dm @@ -110,7 +110,7 @@ /obj/item/ammo_casing/a9mm/practice desc = "A 9mm practice bullet casing." icon_state = "r-casing" - projectile_type = /obj/item/projectile/bullet/pistol/practice + projectile_type = /obj/item/projectile/bullet/practice /* * .45 @@ -130,7 +130,7 @@ /obj/item/ammo_casing/a45/practice desc = "A .45 practice bullet casing." icon_state = "r-casing" - projectile_type = /obj/item/projectile/bullet/pistol/practice + projectile_type = /obj/item/projectile/bullet/practice matter = list(DEFAULT_WALL_MATERIAL = 60) /obj/item/ammo_casing/a45/rubber @@ -202,7 +202,7 @@ name = "shotgun shell" desc = "A practice shell." icon_state = "pshell" - projectile_type = /obj/item/projectile/bullet/shotgun/practice + projectile_type = /obj/item/projectile/bullet/practice matter = list(DEFAULT_WALL_MATERIAL = 90) /obj/item/ammo_casing/a12g/beanbag @@ -260,7 +260,7 @@ /obj/item/ammo_casing/a762/practice desc = "A 7.62mm practice bullet casing." icon_state = "rifle-casing" // Need to make an icon for these - projectile_type = /obj/item/projectile/bullet/rifle/practice + projectile_type = /obj/item/projectile/bullet/practice matter = list(DEFAULT_WALL_MATERIAL = 90) /obj/item/ammo_casing/a762/blank @@ -306,7 +306,7 @@ /obj/item/ammo_casing/a545/practice desc = "A 5.45mm practice bullet casing." icon_state = "rifle-casing" // Need to make an icon for these - projectile_type = /obj/item/projectile/bullet/rifle/practice + projectile_type = /obj/item/projectile/bullet/practice matter = list(DEFAULT_WALL_MATERIAL = 90) /obj/item/ammo_casing/a545/blank diff --git a/code/modules/projectiles/ammunition/smartmag.dm b/code/modules/projectiles/ammunition/smartmag.dm index 4b42f18251..3668145b41 100644 --- a/code/modules/projectiles/ammunition/smartmag.dm +++ b/code/modules/projectiles/ammunition/smartmag.dm @@ -27,11 +27,11 @@ var/emagged = 0 // If you emag the smart mag, you can get the bullets out by clicking it /obj/item/ammo_magazine/smart/New() - processing_objects |= src + START_PROCESSING(SSobj, src) ..() /obj/item/ammo_magazine/smart/Destroy() - processing_objects -= src + STOP_PROCESSING(SSobj, src) ..() /obj/item/ammo_magazine/smart/process() diff --git a/code/modules/projectiles/effects.dm b/code/modules/projectiles/effects.dm deleted file mode 100644 index da21427eff..0000000000 --- a/code/modules/projectiles/effects.dm +++ /dev/null @@ -1,291 +0,0 @@ -/obj/effect/projectile - icon = 'icons/effects/projectiles.dmi' - icon_state = "bolt" - plane = ABOVE_PLANE - -/obj/effect/projectile/New(var/turf/location) - if(istype(location)) - loc = location - -/obj/effect/projectile/proc/set_transform(var/matrix/M) - if(istype(M)) - transform = M - -/obj/effect/projectile/proc/activate(var/kill_delay = 5) - update_light() - spawn(kill_delay) - qdel(src) //see effect_system.dm - sets loc to null and lets GC handle removing these effects - - return - -//---------------------------- -// Laser beam -//---------------------------- -/obj/effect/projectile/laser/tracer - icon_state = "beam" - light_range = 2 - light_power = 0.5 - light_color = "#FF0D00" - -/obj/effect/projectile/laser/muzzle - icon_state = "muzzle_laser" - light_range = 2 - light_power = 0.5 - light_color = "#FF0D00" - -/obj/effect/projectile/laser/impact - icon_state = "impact_laser" - light_range = 2 - light_power = 0.5 - light_color = "#FF0D00" - -//---------------------------- -// Blue laser beam -//---------------------------- -/obj/effect/projectile/laser_blue/tracer - icon_state = "beam_blue" - light_range = 2 - light_power = 0.5 - light_color = "#0066FF" - -/obj/effect/projectile/laser_blue/muzzle - icon_state = "muzzle_blue" - light_range = 2 - light_power = 0.5 - light_color = "#0066FF" - -/obj/effect/projectile/laser_blue/impact - icon_state = "impact_blue" - light_range = 2 - light_power = 0.5 - light_color = "#0066FF" - -//---------------------------- -// Omni laser beam -//---------------------------- -/obj/effect/projectile/laser_omni/tracer - icon_state = "beam_omni" - light_range = 2 - light_power = 0.5 - light_color = "#00C6FF" - -/obj/effect/projectile/laser_omni/muzzle - icon_state = "muzzle_omni" - light_range = 2 - light_power = 0.5 - light_color = "#00C6FF" - -/obj/effect/projectile/laser_omni/impact - icon_state = "impact_omni" - light_range = 2 - light_power = 0.5 - light_color = "#00C6FF" - -//---------------------------- -// Xray laser beam -//---------------------------- -/obj/effect/projectile/xray/tracer - icon_state = "xray" - light_range = 2 - light_power = 0.5 - light_color = "#00CC33" - -/obj/effect/projectile/xray/muzzle - icon_state = "muzzle_xray" - light_range = 2 - light_power = 0.5 - light_color = "#00CC33" - -/obj/effect/projectile/xray/impact - icon_state = "impact_xray" - light_range = 2 - light_power = 0.5 - light_color = "#00CC33" - -//---------------------------- -// Heavy laser beam -//---------------------------- -/obj/effect/projectile/laser_heavy/tracer - icon_state = "beam_heavy" - light_range = 3 - light_power = 1 - light_color = "#FF0D00" - -/obj/effect/projectile/laser_heavy/muzzle - icon_state = "muzzle_beam_heavy" - light_range = 3 - light_power = 1 - light_color = "#FF0D00" - -/obj/effect/projectile/laser_heavy/impact - icon_state = "impact_beam_heavy" - light_range = 3 - light_power = 1 - light_color = "#FF0D00" - -//---------------------------- -// Pulse laser beam -//---------------------------- -/obj/effect/projectile/laser_pulse/tracer - icon_state = "u_laser" - light_range = 2 - light_power = 0.5 - light_color = "#0066FF" - -/obj/effect/projectile/laser_pulse/muzzle - icon_state = "muzzle_u_laser" - light_range = 2 - light_power = 0.5 - light_color = "#0066FF" - -/obj/effect/projectile/laser_pulse/impact - icon_state = "impact_u_laser" - light_range = 2 - light_power = 0.5 - light_color = "#0066FF" - -//---------------------------- -// Pulse muzzle effect only -//---------------------------- -/obj/effect/projectile/pulse/muzzle - icon_state = "muzzle_pulse" - light_range = 2 - light_power = 0.5 - light_color = "#0066FF" - -//---------------------------- -// Emitter beam -//---------------------------- -/obj/effect/projectile/emitter/tracer - icon_state = "emitter" - light_range = 2 - light_power = 0.5 - light_color = "#00CC33" - -/obj/effect/projectile/emitter/muzzle - icon_state = "muzzle_emitter" - light_range = 2 - light_power = 0.5 - light_color = "#00CC33" - -/obj/effect/projectile/emitter/impact - icon_state = "impact_emitter" - light_range = 2 - light_power = 0.5 - light_color = "#00CC33" - -//---------------------------- -// Stun beam -//---------------------------- -/obj/effect/projectile/stun/tracer - icon_state = "stun" - light_range = 2 - light_power = 0.5 - light_color = "#FFFFFF" - -/obj/effect/projectile/stun/muzzle - icon_state = "muzzle_stun" - light_range = 2 - light_power = 0.5 - light_color = "#FFFFFF" - -/obj/effect/projectile/stun/impact - icon_state = "impact_stun" - light_range = 2 - light_power = 0.5 - light_color = "#FFFFFF" - -//---------------------------- -// Bullet -//---------------------------- -/obj/effect/projectile/bullet/muzzle - icon_state = "muzzle_bullet" - light_range = 2 - light_power = 0.5 - light_color = "#FFFFFF" - -//---------------------------- -// Lightning beam -//---------------------------- -/obj/effect/projectile/lightning/tracer - icon_state = "lightning" - light_range = 2 - light_power = 0.5 - light_color = "#00C6FF" - -/obj/effect/projectile/lightning/muzzle - icon_state = "muzzle_lightning" - light_range = 2 - light_power = 0.5 - light_color = "#00C6FF" - -/obj/effect/projectile/lightning/impact - icon_state = "impact_lightning" - light_range = 2 - light_power = 0.5 - light_color = "#00C6FF" - -//---------------------------- -// Dark matter stun -//---------------------------- - -/obj/effect/projectile/darkmatterstun/tracer - icon_state = "darkt" - light_range = 2 - light_power = 0.5 - light_color = "#8837A3" - -/obj/effect/projectile/darkmatterstun/muzzle - icon_state = "muzzle_darkt" - light_range = 2 - light_power = 0.5 - light_color = "#8837A3" - -/obj/effect/projectile/darkmatterstun/impact - icon_state = "impact_darkt" - light_range = 2 - light_power = 0.5 - light_color = "#8837A3" - -//---------------------------- -// Dark matter -//---------------------------- - -/obj/effect/projectile/darkmatter/tracer - icon_state = "darkb" - light_range = 2 - light_power = 0.5 - light_color = "#8837A3" - -/obj/effect/projectile/darkmatter/muzzle - icon_state = "muzzle_darkb" - light_range = 2 - light_power = 0.5 - light_color = "#8837A3" - -/obj/effect/projectile/darkmatter/impact - icon_state = "impact_darkb" - light_range = 2 - light_power = 0.5 - light_color = "#8837A3" - -//---------------------------- -// Inversion / Cult -//---------------------------- -/obj/effect/projectile/inversion/tracer - icon_state = "invert" - light_range = 2 - light_power = -2 - light_color = "#FFFFFF" - -/obj/effect/projectile/inversion/muzzle - icon_state = "muzzle_invert" - light_range = 2 - light_power = -2 - light_color = "#FFFFFF" - -/obj/effect/projectile/inversion/impact - icon_state = "impact_invert" - light_range = 2 - light_power = -2 - light_color = "#FFFFFF" \ No newline at end of file diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 40dbaf0650..13b03d5992 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -56,7 +56,7 @@ var/fire_delay = 6 //delay after shooting before the gun can be used again var/burst_delay = 2 //delay between shots, if firing in bursts var/move_delay = 1 - var/fire_sound = 'sound/weapons/Gunshot.ogg' + var/fire_sound = null // This is handled by projectile.dm's fire_sound var now, but you can override the projectile's fire_sound with this one if you want to. var/fire_sound_text = "gunshot" var/fire_anim = null var/recoil = 0 //screen shake @@ -173,7 +173,7 @@ if(!user.IsAdvancedToolUser()) return 0 if(isanimal(user)) - var/mob/living/simple_animal/S = user + var/mob/living/simple_mob/S = user if(!S.IsHumanoidToolUser(src)) return 0 @@ -470,14 +470,12 @@ P.shot_from = src.name P.silenced = silenced - P.launch(target) + P.old_style_target(target) + P.fire() last_shot = world.time - if(silenced) - playsound(src, fire_sound, 10, 1) - else - playsound(src, fire_sound, 50, 1) + play_fire_sound() if(muzzle_flash) set_light(muzzle_flash) @@ -526,7 +524,8 @@ return 2 //just assume we can shoot through glass and stuff. No big deal, the player can just choose to not target someone //on the other side of a window if it makes a difference. Or if they run behind a window, too bad. - return check_trajectory(target, user) + if(check_trajectory(target, user)) + return 1 // Magic numbers are fun. //called if there was no projectile to shoot /obj/item/weapon/gun/proc/handle_click_empty(mob/user) @@ -542,18 +541,20 @@ flick(fire_anim, src) if(silenced) - if(reflex) - user.visible_message( - "\The [user] fires \the [src][pointblank ? " point blank at \the [target]":""] by reflex!", - "You fire \the [src] by reflex!", - "You hear a [fire_sound_text]!" + to_chat(user, "You fire \the [src][pointblank ? " point blank at \the [target]":""][reflex ? " by reflex":""]") + for(var/mob/living/L in oview(2,user)) + if(L.stat) + continue + if(L.blinded) + to_chat(L, "You hear a [fire_sound_text]!") + continue + to_chat(L, "\The [user] fires \the [src][pointblank ? " point blank at \the [target]":""][reflex ? " by reflex":""]!") + else + user.visible_message( + "\The [user] fires \the [src][pointblank ? " point blank at \the [target]":""][reflex ? " by reflex":""]!", + "You fire \the [src][pointblank ? " point blank at \the [target]":""][reflex ? " by reflex":""]!", + "You hear a [fire_sound_text]!" ) - else - user.visible_message( - "\The [user] fires \the [src][pointblank ? " point blank at \the [target]":""]!", - "You fire \the [src]!", - "You hear a [fire_sound_text]!" - ) if(muzzle_flash) set_light(muzzle_flash) @@ -618,7 +619,7 @@ if(one_handed_penalty) if(!held_twohanded) - acc_mod += -ceil(one_handed_penalty/2) + acc_mod += -CEILING(one_handed_penalty/2, 1) disp_mod += one_handed_penalty*0.5 //dispersion per point of two-handedness //Accuracy modifiers @@ -645,24 +646,17 @@ /obj/item/weapon/gun/proc/process_projectile(obj/projectile, mob/user, atom/target, var/target_zone, var/params=null) var/obj/item/projectile/P = projectile if(!istype(P)) - return 0 //default behaviour only applies to true projectiles - - if(params) - P.set_clickpoint(params) + return FALSE //default behaviour only applies to true projectiles //shooting while in shock - var/x_offset = 0 - var/y_offset = 0 + var/forcespread if(istype(user, /mob/living/carbon)) var/mob/living/carbon/mob = user if(mob.shock_stage > 120) - y_offset = rand(-2,2) - x_offset = rand(-2,2) + forcespread = rand(50, 50) else if(mob.shock_stage > 70) - y_offset = rand(-1,1) - x_offset = rand(-1,1) - - var/launched = !P.launch_from_gun(target, user, src, target_zone, x_offset, y_offset) + forcespread = rand(-25, 25) + var/launched = !P.launch_from_gun(target, target_zone, user, params, null, forcespread, src) if(launched) play_fire_sound(user, P) @@ -670,7 +664,13 @@ return launched /obj/item/weapon/gun/proc/play_fire_sound(var/mob/user, var/obj/item/projectile/P) - var/shot_sound = (istype(P) && P.fire_sound)? P.fire_sound : fire_sound + var/shot_sound = fire_sound + + if(!shot_sound && istype(P) && P.fire_sound) // If the gun didn't have a fire_sound, but the projectile exists, and has a sound... + shot_sound = P.fire_sound + if(!shot_sound) // If there's still no sound... + return + if(silenced) playsound(user, shot_sound, 10, 1) else @@ -693,11 +693,7 @@ var/obj/item/projectile/in_chamber = consume_next_projectile() if (istype(in_chamber)) user.visible_message("[user] pulls the trigger.") - var/shot_sound = in_chamber.fire_sound? in_chamber.fire_sound : fire_sound - if(silenced) - playsound(user, shot_sound, 10, 1) - else - playsound(user, shot_sound, 50, 1) + play_fire_sound() if(istype(in_chamber, /obj/item/projectile/beam/lastertag)) user.show_message("You feel rather silly, trying to commit suicide with a toy.") mouthshoot = 0 diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index 9cfd0d152a..c2eb93932b 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -2,12 +2,12 @@ name = "energy gun" desc = "A basic energy-based gun." icon_state = "energy" - fire_sound = 'sound/weapons/Taser.ogg' fire_sound_text = "laser blast" var/obj/item/weapon/cell/power_supply //What type of power cell this uses var/charge_cost = 240 //How much energy is needed to fire. + var/accept_cell_type = /obj/item/weapon/cell/device var/cell_type = /obj/item/weapon/cell/device/weapon projectile_type = /obj/item/projectile/beam/practice @@ -27,7 +27,7 @@ ..() if(self_recharge) power_supply = new /obj/item/weapon/cell/device/weapon(src) - processing_objects.Add(src) + START_PROCESSING(SSobj, src) else if(cell_type) power_supply = new cell_type(src) @@ -38,7 +38,7 @@ /obj/item/weapon/gun/energy/Destroy() if(self_recharge) - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) return ..() /obj/item/weapon/gun/energy/get_cell() @@ -89,13 +89,13 @@ if(self_recharge || battery_lock) user << "[src] does not have a battery port." return - if(istype(C, /obj/item/weapon/cell/device)) - var/obj/item/weapon/cell/device/P = C + if(istype(C, accept_cell_type)) + var/obj/item/weapon/cell/P = C if(power_supply) user << "[src] already has a power cell." else user.visible_message("[user] is reloading [src].", "You start to insert [P] into [src].") - if(do_after(user, 10)) + if(do_after(user, 5 * P.w_class)) user.remove_from_mob(P) power_supply = P P.loc = src @@ -175,13 +175,20 @@ icon_state = "[modifystate][ratio]" else icon_state = "[initial(icon_state)][ratio]" + + else if(power_supply) + if(modifystate) + icon_state = "[modifystate]" + else + icon_state = "[initial(icon_state)]" + if(!ignore_inhands) update_held_icon() /obj/item/weapon/gun/energy/proc/start_recharge() if(power_supply == null) power_supply = new /obj/item/weapon/cell/device/weapon(src) self_recharge = 1 - processing_objects.Add(src) + START_PROCESSING(SSobj, src) update_icon() /obj/item/weapon/gun/energy/get_description_interaction() diff --git a/code/modules/projectiles/guns/energy/hooklauncher.dm b/code/modules/projectiles/guns/energy/hooklauncher.dm new file mode 100644 index 0000000000..2c170544a0 --- /dev/null +++ b/code/modules/projectiles/guns/energy/hooklauncher.dm @@ -0,0 +1,39 @@ +/* + * Contains weapons primarily using the 'grappling hook' projectiles. + */ + +/obj/item/weapon/gun/energy/hooklauncher + name = "gravity whip" + desc = "A large, strange gauntlet." + icon_state = "gravwhip" + item_state = "gravwhip" + fire_sound_text = "laser blast" + + fire_delay = 15 + charge_cost = 300 + + cell_type = /obj/item/weapon/cell/device/weapon + projectile_type = /obj/item/projectile/energy/hook + +// An easily concealable not-ripoff version. It would be silenced, if it didn't make it blatant you're the one using it. + +/obj/item/weapon/gun/energy/hooklauncher/ring + name = "ominous ring" + desc = "A small ring with strange symbols engraved upon it." + icon = 'icons/obj/clothing/rings.dmi' + icon_state = "seal-signet" + item_state = "concealed" + + w_class = ITEMSIZE_TINY + + cell_type = /obj/item/weapon/cell/device/weapon/recharge/alien + battery_lock = TRUE + charge_cost = 400 + charge_meter = FALSE + + projectile_type = /obj/item/projectile/energy/hook/ring + + firemodes = list( + list(mode_name="manipulate", fire_delay=15, projectile_type=/obj/item/projectile/energy/hook/ring, charge_cost = 400), + list(mode_name="battle", fire_delay=8, projectile_type=/obj/item/projectile/beam/xray, charge_cost = 260), + ) diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator_vr.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator_vr.dm index f672e1b021..8a0dbeae4d 100644 --- a/code/modules/projectiles/guns/energy/kinetic_accelerator_vr.dm +++ b/code/modules/projectiles/guns/energy/kinetic_accelerator_vr.dm @@ -100,7 +100,7 @@ damage = 32 damage_type = BRUTE check_armour = "bomb" - kill_count = 3 // Our "range" var is named "kill_count". Yes it is. + range = 3 // Our "range" var is named "kill_count". Yes it is. var/pressure_decrease = 0.25 var/turf_aoe = FALSE @@ -219,7 +219,7 @@ cost = 24 //so you can fit four plus a tracer cosmetic /obj/item/borg/upgrade/modkit/range/modify_projectile(obj/item/projectile/kinetic/K) - K.kill_count += modifier + K.range += modifier //Damage diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm index 5cfefc1bf5..4d707e7494 100644 --- a/code/modules/projectiles/guns/energy/laser.dm +++ b/code/modules/projectiles/guns/energy/laser.dm @@ -130,7 +130,6 @@ icon_state = "sniper" item_state = "sniper" item_state_slots = list(slot_r_hand_str = "z8carbine", slot_l_hand_str = "z8carbine") //placeholder - fire_sound = 'sound/weapons/gauss_shoot.ogg' origin_tech = list(TECH_COMBAT = 6, TECH_MATERIAL = 5, TECH_POWER = 4) projectile_type = /obj/item/projectile/beam/sniper slot_flags = SLOT_BACK @@ -151,6 +150,41 @@ toggle_scope(2.0) +/obj/item/weapon/gun/energy/monorifle + name = "antique mono-rifle" + desc = "An old laser rifle. This one can only fire once before requiring recharging." + description_fluff = "Modeled after ancient hunting rifles, this rifle was dubbed the 'Rainy Day Special' by some, due to its use as some barmens' fight-stopper of choice. One shot is all it takes, or so they say." + icon_state = "eshotgun" + item_state = "shotgun" + origin_tech = list(TECH_COMBAT = 6, TECH_MATERIAL = 4, TECH_POWER = 3) + projectile_type = /obj/item/projectile/beam/sniper + slot_flags = SLOT_BACK + charge_cost = 1300 + fire_delay = 20 + force = 8 + w_class = ITEMSIZE_LARGE + accuracy = 10 + scoped_accuracy = 15 + var/scope_multiplier = 1.5 + +/obj/item/weapon/gun/energy/monorifle/verb/sights() + set category = "Object" + set name = "Aim Down Sights" + set popup_menu = 1 + + toggle_scope(scope_multiplier) + +/obj/item/weapon/gun/energy/monorifle/combat + name = "combat mono-rifle" + desc = "A modernized version of the mono-rifle. This one can fire twice before requiring recharging." + description_fluff = "A modern design produced by a company once working from Saint Columbia, based on the antique mono-rifle 'Rainy Day Special' design." + icon_state = "ecshotgun" + item_state = "cshotgun" + charge_cost = 1000 + force = 12 + accuracy = 0 + scoped_accuracy = 20 + ////////Laser Tag//////////////////// /obj/item/weapon/gun/energy/lasertag diff --git a/code/modules/projectiles/guns/energy/pulse.dm b/code/modules/projectiles/guns/energy/pulse.dm index 6513a00052..30eb8ecd37 100644 --- a/code/modules/projectiles/guns/energy/pulse.dm +++ b/code/modules/projectiles/guns/energy/pulse.dm @@ -22,7 +22,6 @@ /obj/item/weapon/gun/energy/pulse_rifle/destroyer name = "pulse destroyer" desc = "A heavy-duty, pulse-based energy weapon. Because of its complexity and cost, it is rarely seen in use except by specialists." - fire_sound='sound/weapons/gauss_shoot.ogg' projectile_type=/obj/item/projectile/beam/pulse charge_cost = 120 diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index f1e20b169b..c4193289dd 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -30,7 +30,6 @@ desc = "A gun that discharges high amounts of controlled radiation to slowly break a target into component elements." icon_state = "decloner" item_state = "decloner" - fire_sound = 'sound/weapons/pulse3.ogg' origin_tech = list(TECH_COMBAT = 5, TECH_MATERIAL = 4, TECH_POWER = 3) projectile_type = /obj/item/projectile/energy/declone @@ -39,7 +38,6 @@ desc = "A tool that discharges controlled radiation which induces mutation in plant cells." icon_state = "floramut100" item_state = "floramut" - fire_sound = 'sound/effects/stealthoff.ogg' projectile_type = /obj/item/projectile/energy/floramut origin_tech = list(TECH_MATERIAL = 2, TECH_BIO = 3, TECH_POWER = 3) modifystate = "floramut" @@ -112,13 +110,11 @@ desc = "A custom-built weapon of some kind." icon_state = "xray" projectile_type = /obj/item/projectile/beam/mindflayer - fire_sound = 'sound/weapons/Laser.ogg' /obj/item/weapon/gun/energy/toxgun name = "phoron pistol" desc = "A specialized firearm designed to fire lethal bolts of phoron." icon_state = "toxgun" - fire_sound = 'sound/effects/stealthoff.ogg' w_class = ITEMSIZE_NORMAL origin_tech = list(TECH_COMBAT = 5, TECH_PHORON = 4) projectile_type = /obj/item/projectile/energy/phoron @@ -131,7 +127,6 @@ icon = 'icons/obj/gun.dmi' item_icons = null icon_state = "staffofchange" - fire_sound = 'sound/weapons/emitter.ogg' flags = CONDUCT slot_flags = SLOT_BACK w_class = ITEMSIZE_LARGE @@ -155,13 +150,13 @@ else src.visible_message("*fizzle*") playsound(src.loc, 'sound/effects/sparks1.ogg', 100, 1) - +/* /obj/item/weapon/gun/energy/staff/animate name = "staff of animation" desc = "An artifact that spits bolts of life force, which causes objects which are hit by it to animate and come to life! This magic doesn't affect machines." projectile_type = /obj/item/projectile/animate charge_cost = 240 - +*/ obj/item/weapon/gun/energy/staff/focus name = "mental focus" desc = "An artifact that channels the will of the user into destructive bolts of force. If you aren't careful with it, you might poke someone's brain out." @@ -186,7 +181,7 @@ obj/item/weapon/gun/energy/staff/focus desc = "A massive weapon designed to pressure the opposition by raining down a torrent of energy pellets." icon_state = "dakkalaser" item_state = "dakkalaser" - fire_sound = 'sound/weapons/Laser.ogg' + wielded_item_state = "dakkalaser-wielded" w_class = ITEMSIZE_HUGE charge_cost = 24 // 100 shots, it's a spray and pray (to RNGesus) weapon. projectile_type = /obj/item/projectile/energy/blue_pellet @@ -200,4 +195,93 @@ obj/item/weapon/gun/energy/staff/focus list(mode_name="single shot", burst = 1, burst_accuracy = list(75), dispersion = list(0), charge_cost = 24), list(mode_name="five shot burst", burst = 5, burst_accuracy = list(75,75,75,75,75), dispersion = list(1,1,1,1,1)), list(mode_name="ten shot burst", burst = 10, burst_accuracy = list(75,75,75,75,75,75,75,75,75,75), dispersion = list(2,2,2,2,2,2,2,2,2,2)), - ) \ No newline at end of file + ) + +/obj/item/weapon/gun/energy/maghowitzer + name = "portable MHD howitzer" + desc = "A massive weapon designed to destroy fortifications with a stream of molten tungsten." + description_fluff = "A weapon designed by joint cooperation of NanoTrasen, Hephaestus, and SCG scientists. Everything else is red tape and black highlighters." + description_info = "This weapon requires a wind-up period before being able to fire. Clicking on a target will create a beam between you and its turf, starting the timer. Upon completion, it will fire at the designated location." + icon_state = "mhdhowitzer" + item_state = "mhdhowitzer" + wielded_item_state = "mhdhowitzer-wielded" + w_class = ITEMSIZE_HUGE + + charge_cost = 10000 // Uses large cells, can at max have 3 shots. + projectile_type = /obj/item/projectile/beam/tungsten + cell_type = /obj/item/weapon/cell/high + accept_cell_type = /obj/item/weapon/cell + + accuracy = 75 + charge_meter = 0 + one_handed_penalty = 30 + + var/power_cycle = FALSE + +/obj/item/weapon/gun/energy/maghowitzer/proc/pick_random_target(var/turf/T) + var/foundmob = FALSE + var/foundmobs = list() + for(var/mob/living/L in T.contents) + foundmob = TRUE + foundmobs += L + if(foundmob) + var/return_target = pick(foundmobs) + return return_target + return FALSE + +/obj/item/weapon/gun/energy/maghowitzer/attack(atom/A, mob/living/user, def_zone) + if(power_cycle) + to_chat(user, "\The [src] is already powering up!") + return 0 + var/turf/target_turf = get_turf(A) + var/beameffect = user.Beam(target_turf,icon_state="sat_beam",icon='icons/effects/beam.dmi',time=31, maxdistance=10,beam_type=/obj/effect/ebeam,beam_sleep_time=3) + if(beameffect) + user.visible_message("[user] aims \the [src] at \the [A].") + if(power_supply && power_supply.charge >= charge_cost) //Do a delay for pointblanking too. + power_cycle = TRUE + if(do_after(user, 30)) + if(A.loc == target_turf) + ..(A, user, def_zone) + else + var/rand_target = pick_random_target(target_turf) + if(rand_target) + ..(rand_target, user, def_zone) + else + ..(target_turf, user, def_zone) + else + if(beameffect) + qdel(beameffect) + power_cycle = FALSE + else + ..(A, user, def_zone) //If it can't fire, just bash with no delay. + +/obj/item/weapon/gun/energy/maghowitzer/afterattack(atom/A, mob/living/user, adjacent, params) + if(power_cycle) + to_chat(user, "\The [src] is already powering up!") + return 0 + + var/turf/target_turf = get_turf(A) + + var/beameffect = user.Beam(target_turf,icon_state="sat_beam",icon='icons/effects/beam.dmi',time=31, maxdistance=10,beam_type=/obj/effect/ebeam,beam_sleep_time=3) + + if(beameffect) + user.visible_message("[user] aims \the [src] at \the [A].") + + if(!power_cycle) + power_cycle = TRUE + if(do_after(user, 30)) + if(A.loc == target_turf) + ..(A, user, adjacent, params) + else + var/rand_target = pick_random_target(target_turf) + if(rand_target) + ..(rand_target, user, adjacent, params) + else + ..(target_turf, user, adjacent, params) + else + if(beameffect) + qdel(beameffect) + handle_click_empty(user) + power_cycle = FALSE + else + to_chat(user, "\The [src] is already powering up!") diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm index 312a6b0648..7054d4f4e6 100644 --- a/code/modules/projectiles/guns/energy/stun.dm +++ b/code/modules/projectiles/guns/energy/stun.dm @@ -36,7 +36,6 @@ matter = list(DEFAULT_WALL_MATERIAL = 2000) slot_flags = SLOT_BELT | SLOT_HOLSTER silenced = 1 - fire_sound = 'sound/weapons/Genhit.ogg' projectile_type = /obj/item/projectile/energy/bolt charge_cost = 480 cell_type = /obj/item/weapon/cell/device/weapon/recharge diff --git a/code/modules/projectiles/guns/energy/temperature.dm b/code/modules/projectiles/guns/energy/temperature.dm index 5e24564292..cf9706effd 100644 --- a/code/modules/projectiles/guns/energy/temperature.dm +++ b/code/modules/projectiles/guns/energy/temperature.dm @@ -1,7 +1,6 @@ /obj/item/weapon/gun/energy/temperature name = "temperature gun" icon_state = "freezegun" - fire_sound = 'sound/weapons/pulse3.ogg' desc = "A gun that can add or remove heat from entities it hits. In other words, it can fire 'cold', and 'hot' beams." charge_cost = 240 origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 4, TECH_POWER = 3, TECH_MAGNET = 2) diff --git a/code/modules/projectiles/guns/launcher/grenade_launcher.dm b/code/modules/projectiles/guns/launcher/grenade_launcher.dm index 207572a8c6..38d84f384a 100644 --- a/code/modules/projectiles/guns/launcher/grenade_launcher.dm +++ b/code/modules/projectiles/guns/launcher/grenade_launcher.dm @@ -6,7 +6,7 @@ w_class = ITEMSIZE_LARGE force = 10 - fire_sound = 'sound/weapons/empty.ogg' + fire_sound = 'sound/weapons/grenade_launcher.ogg' fire_sound_text = "a metallic thunk" recoil = 0 throw_distance = 7 diff --git a/code/modules/projectiles/guns/launcher/pneumatic.dm b/code/modules/projectiles/guns/launcher/pneumatic.dm index e737507b2c..cfe4533109 100644 --- a/code/modules/projectiles/guns/launcher/pneumatic.dm +++ b/code/modules/projectiles/guns/launcher/pneumatic.dm @@ -8,7 +8,7 @@ flags = CONDUCT fire_sound_text = "a loud whoosh of moving air" fire_delay = 50 - fire_sound = 'sound/weapons/tablehit1.ogg' + fire_sound = 'sound/weapons/grenade_launcher.ogg' // Formerly tablehit1.ogg but I like this better -Ace var/fire_pressure // Used in fire checks/pressure checks. var/max_w_class = ITEMSIZE_NORMAL // Hopper intake size. diff --git a/code/modules/projectiles/guns/magnetic/bore.dm b/code/modules/projectiles/guns/magnetic/bore.dm new file mode 100644 index 0000000000..e27fdc38d6 --- /dev/null +++ b/code/modules/projectiles/guns/magnetic/bore.dm @@ -0,0 +1,141 @@ +/obj/item/weapon/gun/magnetic/matfed + name = "portable phoron bore" + desc = "A large man-portable tunnel bore, using phorogenic plasma blasts. Point away from user." + description_fluff = "An aging Grayson Manufactories mining tool used for rapidly digging through rock. Mass production was discontinued when many of the devices were stolen and used to break into a high security facility by Boiling Point drones." + description_antag = "This device is exceptional at breaking down walls, though it is incredibly loud when doing so." + description_info = "The projectile of this tool will travel six tiles before dissipating, excavating mineral walls as it does so. It can be reloaded with phoron sheets." + + icon_state = "bore" + item_state = "bore" + wielded_item_state = "bore-wielded" + one_handed_penalty = 5 + + projectile_type = /obj/item/projectile/bullet/magnetic/bore + + gun_unreliable = 0 + + power_cost = 750 + load_type = /obj/item/stack/material + var/mat_storage = 0 // How much material is stored inside? Input in multiples of 2000 as per auto/protolathe. + var/max_mat_storage = 8000 // How much material can be stored inside? + var/mat_cost = 500 // How much material is used per-shot? + var/ammo_material = MAT_PHORON + var/loading = FALSE + +/obj/item/weapon/gun/magnetic/matfed/examine(mob/user) + . = ..() + show_ammo(user) + +/obj/item/weapon/gun/magnetic/matfed/update_icon() + var/list/overlays_to_add = list() + if(removable_components) + if(cell) + overlays_to_add += image(icon, "[icon_state]_cell") + if(capacitor) + overlays_to_add += image(icon, "[icon_state]_capacitor") + if(!cell || !capacitor) + overlays_to_add += image(icon, "[icon_state]_red") + else if(capacitor.charge < power_cost) + overlays_to_add += image(icon, "[icon_state]_amber") + else + overlays_to_add += image(icon, "[icon_state]_green") + if(mat_storage) + overlays_to_add += image(icon, "[icon_state]_loaded") + + overlays = overlays_to_add + ..() +/obj/item/weapon/gun/magnetic/matfed/attack_hand(var/mob/user) // It doesn't keep a loaded item inside. + if(user.get_inactive_hand() == src) + var/obj/item/removing + + if(cell && removable_components) + removing = cell + cell = null + + if(removing) + removing.forceMove(get_turf(src)) + user.put_in_hands(removing) + user.visible_message("\The [user] removes \the [removing] from \the [src].") + playsound(loc, 'sound/machines/click.ogg', 10, 1) + update_icon() + return + . = ..() + +/obj/item/weapon/gun/magnetic/matfed/check_ammo() + if(mat_storage - mat_cost >= 0) + return TRUE + return FALSE + +/obj/item/weapon/gun/magnetic/matfed/use_ammo() + mat_storage -= mat_cost + +/obj/item/weapon/gun/magnetic/matfed/show_ammo(var/mob/user) + if(mat_storage) + to_chat(user, "It has [mat_storage] out of [max_mat_storage] units of [ammo_material] loaded.") + +/obj/item/weapon/gun/magnetic/matfed/attackby(var/obj/item/thing, var/mob/user) + if(removable_components) + if(istype(thing, /obj/item/weapon/cell)) + if(cell) + to_chat(user, "\The [src] already has \a [cell] installed.") + return + cell = thing + user.drop_from_inventory(cell) + cell.forceMove(src) + playsound(loc, 'sound/machines/click.ogg', 10, 1) + user.visible_message("\The [user] slots \the [cell] into \the [src].") + update_icon() + return + + if(thing.is_screwdriver()) + if(!capacitor) + to_chat(user, "\The [src] has no capacitor installed.") + return + capacitor.forceMove(get_turf(src)) + user.put_in_hands(capacitor) + user.visible_message("\The [user] unscrews \the [capacitor] from \the [src].") + playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1) + capacitor = null + update_icon() + return + + if(istype(thing, /obj/item/weapon/stock_parts/capacitor)) + if(capacitor) + to_chat(user, "\The [src] already has \a [capacitor] installed.") + return + capacitor = thing + user.drop_from_inventory(capacitor) + capacitor.forceMove(src) + playsound(loc, 'sound/machines/click.ogg', 10, 1) + power_per_tick = (power_cost*0.15) * capacitor.rating + user.visible_message("\The [user] slots \the [capacitor] into \the [src].") + update_icon() + return + + if(istype(thing, load_type)) + loading = TRUE + var/obj/item/stack/material/M = thing + + if(!M.material || M.material.name != ammo_material) + return + + if(mat_storage + 2000 > max_mat_storage) + to_chat(user, "\The [src] cannot hold more [ammo_material].") + return + + var/can_hold_val = 0 + while(can_hold_val < round(max_mat_storage / 2000)) + if(mat_storage + 2000 <= max_mat_storage && do_after(user,1.5 SECONDS)) + can_hold_val ++ + mat_storage += 2000 + playsound(loc, 'sound/effects/phasein.ogg', 15, 1) + else + loading = FALSE + break + M.use(can_hold_val) + + user.visible_message("\The [user] loads \the [src] with \the [M].") + playsound(loc, 'sound/weapons/flipblade.ogg', 50, 1) + update_icon() + return + . = ..() diff --git a/code/modules/projectiles/guns/magnetic/magnetic.dm b/code/modules/projectiles/guns/magnetic/magnetic.dm index 298098698e..20e0ea8512 100644 --- a/code/modules/projectiles/guns/magnetic/magnetic.dm +++ b/code/modules/projectiles/guns/magnetic/magnetic.dm @@ -20,17 +20,15 @@ var/power_cost = 950 // Cost per fire, should consume almost an entire basic cell. var/power_per_tick // Capacitor charge per process(). Updated based on capacitor rating. - fire_sound = 'sound/weapons/railgun.ogg' - /obj/item/weapon/gun/magnetic/New() - processing_objects.Add(src) + START_PROCESSING(SSobj, src) if(capacitor) power_per_tick = (power_cost*0.15) * capacitor.rating update_icon() . = ..() /obj/item/weapon/gun/magnetic/Destroy() - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) QDEL_NULL(cell) QDEL_NULL(loaded) QDEL_NULL(capacitor) diff --git a/code/modules/projectiles/guns/magnetic/magnetic_railgun.dm b/code/modules/projectiles/guns/magnetic/magnetic_railgun.dm index 466fbd3b33..0be62e0688 100644 --- a/code/modules/projectiles/guns/magnetic/magnetic_railgun.dm +++ b/code/modules/projectiles/guns/magnetic/magnetic_railgun.dm @@ -102,7 +102,6 @@ load_type = /obj/item/weapon/magnetic_ammo projectile_type = /obj/item/projectile/bullet/magnetic/flechette loaded = /obj/item/weapon/magnetic_ammo - fire_sound = 'sound/weapons/rapidslice.ogg' empty_sound = 'sound/weapons/smg_empty_alarm.ogg' firemodes = list( diff --git a/code/modules/projectiles/guns/modular_guns.dm b/code/modules/projectiles/guns/modular_guns.dm index 64b33347cd..38e2ed1a93 100644 --- a/code/modules/projectiles/guns/modular_guns.dm +++ b/code/modules/projectiles/guns/modular_guns.dm @@ -121,10 +121,10 @@ chargecost_lethal = 200 firemodes = list( - new /datum/firemode(src, list(mode_name="stun", projectile_type=beammode, fire_sound='sound/weapons/Taser.ogg', charge_cost = chargecost)), - new /datum/firemode(src, list(mode_name="lethal", projectile_type=beammode_lethal, fire_sound='sound/weapons/Laser.ogg', charge_cost = chargecost_lethal)), - new /datum/firemode(src, list(mode_name="[burstmode] shot stun", projectile_type=beammode, fire_sound='sound/weapons/Taser.ogg', charge_cost = chargecost, burst = burstmode)), - new /datum/firemode(src, list(mode_name="[burstmode] shot lethal", projectile_type=beammode_lethal, fire_sound='sound/weapons/Laser.ogg', charge_cost = chargecost_lethal, burst = burstmode)), + new /datum/firemode(src, list(mode_name="stun", projectile_type=beammode, charge_cost = chargecost)), + new /datum/firemode(src, list(mode_name="lethal", projectile_type=beammode_lethal, charge_cost = chargecost_lethal)), + new /datum/firemode(src, list(mode_name="[burstmode] shot stun", projectile_type=beammode, charge_cost = chargecost, burst = burstmode)), + new /datum/firemode(src, list(mode_name="[burstmode] shot lethal", projectile_type=beammode_lethal, charge_cost = chargecost_lethal, burst = burstmode)), ) /obj/item/weapon/gun/energy/modular/load_ammo(var/obj/item/C, mob/user) diff --git a/code/modules/projectiles/guns/projectile/automatic.dm b/code/modules/projectiles/guns/projectile/automatic.dm index a1afc075b5..ddb92f1b41 100644 --- a/code/modules/projectiles/guns/projectile/automatic.dm +++ b/code/modules/projectiles/guns/projectile/automatic.dm @@ -46,7 +46,6 @@ caliber = "10mm" origin_tech = list(TECH_COMBAT = 5, TECH_MATERIAL = 2, TECH_ILLEGAL = 8) slot_flags = SLOT_BELT|SLOT_BACK - fire_sound = 'sound/weapons/Gunshot_light.ogg' load_method = MAGAZINE magazine_type = /obj/item/ammo_magazine/m10mm allowed_magazines = list(/obj/item/ammo_magazine/m10mm) @@ -107,7 +106,6 @@ origin_tech = list(TECH_COMBAT = 5, TECH_MATERIAL = 2) slot_flags = SLOT_BELT ammo_type = "/obj/item/ammo_casing/a9mmr" - fire_sound = 'sound/weapons/Gunshot_light.ogg' load_method = MAGAZINE magazine_type = /obj/item/ammo_magazine/m9mmt/rubber allowed_magazines = list(/obj/item/ammo_magazine/m9mmt) @@ -131,7 +129,6 @@ force = 10 caliber = "7.62mm" origin_tech = list(TECH_COMBAT = 8, TECH_MATERIAL = 3) - fire_sound = 'sound/weapons/Gunshot.ogg' slot_flags = SLOT_BACK load_method = MAGAZINE magazine_type = /obj/item/ammo_magazine/m762 @@ -204,7 +201,6 @@ caliber = "5.45mm" origin_tech = list(TECH_COMBAT = 6, TECH_MATERIAL = 1, TECH_ILLEGAL = 2) slot_flags = SLOT_BACK - fire_sound = 'sound/weapons/machinegun.ogg' load_method = MAGAZINE magazine_type = /obj/item/ammo_magazine/m545saw allowed_magazines = list(/obj/item/ammo_magazine/m545saw, /obj/item/ammo_magazine/m545) @@ -300,9 +296,9 @@ /obj/item/weapon/gun/projectile/automatic/as24/update_icon() ..() if(ammo_magazine) - icon_state = "ashot-[round(ammo_magazine.stored_ammo.len,12)]" - else icon_state = "ashot" + else + icon_state = "ashot-empty" return /obj/item/weapon/gun/projectile/automatic/mini_uzi @@ -337,7 +333,6 @@ caliber = "9mm" origin_tech = list(TECH_COMBAT = 5, TECH_MATERIAL = 2) slot_flags = SLOT_BELT // ToDo: Belt sprite. - fire_sound = 'sound/weapons/Gunshot_light.ogg' load_method = MAGAZINE magazine_type = /obj/item/ammo_magazine/m9mmp90 allowed_magazines = list(/obj/item/ammo_magazine/m9mmp90, /obj/item/ammo_magazine/m9mmt) // ToDo: New sprite for the different mag. @@ -351,7 +346,7 @@ icon_state = "p90smg-[ammo_magazine ? round(ammo_magazine.stored_ammo.len, 6) : "empty"]" /obj/item/weapon/gun/projectile/automatic/tommygun - name = "\improper Tommygun" + name = "\improper Tommy Gun" desc = "This weapon was made famous by gangsters in the 20th century. Cybersun Industries is currently reproducing these for a target market of historic gun collectors and classy criminals. Uses .45 rounds." icon_state = "tommygun" w_class = ITEMSIZE_NORMAL diff --git a/code/modules/projectiles/guns/projectile/boltaction.dm b/code/modules/projectiles/guns/projectile/boltaction.dm index 47dbda54d1..8e579d659f 100644 --- a/code/modules/projectiles/guns/projectile/boltaction.dm +++ b/code/modules/projectiles/guns/projectile/boltaction.dm @@ -5,7 +5,7 @@ desc = "A reproduction of an almost ancient weapon design from the early 20th century. It's still popular among hunters and collectors due to its reliability. Uses 7.62mm rounds." item_state = "boltaction" icon_state = "boltaction" - fire_sound = 'sound/weapons/rifleshot.ogg' + fire_sound = 'sound/weapons/Gunshot_generic_rifle.ogg' max_shells = 5 caliber = "7.62mm" origin_tech = list(TECH_COMBAT = 1)// Old as shit rifle doesn't have very good tech. @@ -29,7 +29,7 @@ if(istype(A, /obj/item/weapon/surgical/circular_saw) || istype(A, /obj/item/weapon/melee/energy) || istype(A, /obj/item/weapon/pickaxe/plasmacutter) && w_class != ITEMSIZE_NORMAL) user << "You begin to shorten the barrel and stock of \the [src]." if(loaded.len) - afterattack(user, user) //will this work? //it will. we call it twice, for twice the FUN + afterattack(user, user) playsound(user, fire_sound, 50, 1) user.visible_message("[src] goes off!", "The rifle goes off in your face!") return @@ -53,17 +53,13 @@ desc = "A reproduction of an almost ancient weapon design from the 19th century. This one uses a lever-action to move new rounds into the chamber. Uses 7.62mm rounds." item_state = "leveraction" icon_state = "leveraction" - fire_sound = 'sound/weapons/rifleshot.ogg' max_shells = 5 caliber = "7.62mm" - origin_tech = list(TECH_COMBAT = 1)// Old as shit rifle doesn't have very good tech. - ammo_type = /obj/item/ammo_casing/a762 - load_method = SINGLE_CASING|SPEEDLOADER - action_sound = 'sound/weapons/riflebolt.ogg' + load_method = SINGLE_CASING /obj/item/weapon/gun/projectile/shotgun/pump/rifle/lever/vintage name = "vintage repeater" - desc = "An iconic manually operated lever action rifle, offering adequate stopping power due to it's still powerful cartridge while at the same time having a rather respectable firing rate due to it's mechanism. It is very probable this is a replica instead of a museum piece, but rifles of this pattern still see usage as colonist guns in some far off regions. Uses 7,62mm ammo." - item_state = "levercarabine" + desc = "An iconic manually operated lever action rifle, offering adequate stopping power due to it's still powerful cartridge while at the same time having a rather respectable firing rate due to it's mechanism. It is very probable this is a replica instead of a museum piece, but rifles of this pattern still see usage as colonist guns in some far off regions. Uses 7.62mm rounds." + item_state = "levercarabine" // That isn't how carbine is spelled ya knob! :U icon_state = "levercarabine" animated_pump = 1 diff --git a/code/modules/projectiles/guns/projectile/dartgun.dm b/code/modules/projectiles/guns/projectile/dartgun.dm index 080c7cc1a6..4958accb64 100644 --- a/code/modules/projectiles/guns/projectile/dartgun.dm +++ b/code/modules/projectiles/guns/projectile/dartgun.dm @@ -3,7 +3,7 @@ icon_state = "dart" damage = 5 var/reagent_amount = 15 - kill_count = 15 //shorter range + range = 15 //shorter range muzzle_type = null diff --git a/code/modules/projectiles/guns/projectile/pistol.dm b/code/modules/projectiles/guns/projectile/pistol.dm index c7518c5aa6..7a32ea21fa 100644 --- a/code/modules/projectiles/guns/projectile/pistol.dm +++ b/code/modules/projectiles/guns/projectile/pistol.dm @@ -132,8 +132,8 @@ item_state = "deagle" force = 14.0 caliber = ".44" + fire_sound = 'sound/weapons/Gunshot_deagle.ogg' load_method = MAGAZINE - fire_sound = 'sound/weapons/deagle.ogg' magazine_type = /obj/item/ammo_magazine/m44 allowed_magazines = list(/obj/item/ammo_magazine/m44) @@ -154,33 +154,13 @@ icon_state = "deaglecamo" item_state = "deagleg" -/* -/obj/item/weapon/gun/projectile/fiveseven - name = "\improper WT-AP57" - desc = "This tacticool pistol made by Ward-Takahashi trades stopping power for armor piercing and a large capacity. Uses 5mm rounds." - icon_state = "fnseven" - origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 2) - caliber = "5mm" - load_method = MAGAZINE - fire_sound = 'sound/weapons/semiauto.ogg' - magazine_type = /obj/item/ammo_magazine/c5mm - allowed_magazines = list(/obj/item/ammo_magazine/c5mm) - -/obj/item/weapon/gun/projectile/fiveseven/update_icon() - ..() - if(ammo_magazine) - icon_state = "fnseven" - else - icon_state = "fnseven-empty" -*/ - /obj/item/weapon/gun/projectile/gyropistol // Does this even appear anywhere outside of admin abuse? name = "gyrojet pistol" desc = "Speak softly, and carry a big gun. Fires rare .75 caliber self-propelled exploding bolts--because fuck you and everything around you." icon_state = "gyropistol" max_shells = 8 caliber = ".75" - fire_sound = 'sound/weapons/rpg.ogg' + fire_sound = 'sound/weapons/railgun.ogg' origin_tech = list(TECH_COMBAT = 3) ammo_type = "/obj/item/ammo_casing/a75" load_method = MAGAZINE @@ -331,7 +311,6 @@ origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 2) caliber = "9mm" load_method = MAGAZINE - fire_sound = 'sound/weapons/gunshot3.ogg' magazine_type = /obj/item/ammo_magazine/m9mm allowed_magazines = list(/obj/item/ammo_magazine/m9mm) // Can accept illegal large capacity magazines, or compact magazines. diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm index 2d25265ea5..85d8d5ecdf 100644 --- a/code/modules/projectiles/guns/projectile/revolver.dm +++ b/code/modules/projectiles/guns/projectile/revolver.dm @@ -46,7 +46,6 @@ icon_state = "detective" caliber = ".38" origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2) - fire_sound = 'sound/weapons/gunshot3.ogg' ammo_type = /obj/item/ammo_casing/a38 /obj/item/weapon/gun/projectile/revolver/detective/verb/rename_gun() @@ -73,7 +72,6 @@ icon_state = "detective" caliber = ".45" origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2) - fire_sound = 'sound/weapons/gunshot_heavy.ogg' ammo_type = /obj/item/ammo_casing/a45/rubber max_shells = 7 @@ -125,7 +123,6 @@ obj/item/weapon/gun/projectile/revolver/detective45/verb/rename_gun() icon_state = "deckard-empty" caliber = ".38" origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2) - fire_sound = 'sound/weapons/gunshot3.ogg' ammo_type = /obj/item/ammo_casing/a38 /obj/item/weapon/gun/projectile/revolver/deckard/emp diff --git a/code/modules/projectiles/guns/projectile/semiauto.dm b/code/modules/projectiles/guns/projectile/semiauto.dm index d4cd616188..a1dd63cf97 100644 --- a/code/modules/projectiles/guns/projectile/semiauto.dm +++ b/code/modules/projectiles/guns/projectile/semiauto.dm @@ -7,7 +7,7 @@ caliber = "7.62mm" origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2) slot_flags = SLOT_BACK - fire_sound = 'sound/weapons/rifleshot.ogg' + //fire_sound = 'sound/weapons/rifleshot.ogg' load_method = MAGAZINE // ToDo: Make it so MAGAZINE, SPEEDLOADER and SINGLE_CASING can all be used on the same gun. magazine_type = /obj/item/ammo_magazine/m762garand allowed_magazines = list(/obj/item/ammo_magazine/m762garand) diff --git a/code/modules/projectiles/guns/projectile/sniper.dm b/code/modules/projectiles/guns/projectile/sniper.dm index 230e2b4d50..76a6faf1d7 100644 --- a/code/modules/projectiles/guns/projectile/sniper.dm +++ b/code/modules/projectiles/guns/projectile/sniper.dm @@ -84,7 +84,7 @@ scoped_accuracy = 0 // requires_two_hands = 1 // one_handed_penalty = 60 // The weapon itself is heavy, and the long barrel makes it hard to hold steady with just one hand. - fire_sound = 'sound/weapons/SVD_shot.ogg' + fire_sound = 'sound/weapons/Gunshot_SVD.ogg' // Has a very unique sound. magazine_type = /obj/item/ammo_magazine/m762svd allowed_magazines = list(/obj/item/ammo_magazine/m762svd) diff --git a/code/modules/projectiles/guns/vox.dm b/code/modules/projectiles/guns/vox.dm index ccbfe300ec..0a98a1cc61 100644 --- a/code/modules/projectiles/guns/vox.dm +++ b/code/modules/projectiles/guns/vox.dm @@ -15,16 +15,16 @@ icon = 'icons/obj/gun.dmi' icon_state = "spikethrower3" item_state = "spikethrower" - fire_sound_text = "a strange noise" fire_sound = 'sound/weapons/bladeslice.ogg' + fire_sound_text = "a strange noise" /obj/item/weapon/gun/launcher/spikethrower/New() ..() - processing_objects.Add(src) + START_PROCESSING(SSobj, src) last_regen = world.time /obj/item/weapon/gun/launcher/spikethrower/Destroy() - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) ..() /obj/item/weapon/gun/launcher/spikethrower/process() @@ -79,9 +79,9 @@ damage_type = HALLOSS light_color = "#8837A3" - muzzle_type = /obj/effect/projectile/darkmatterstun/muzzle - tracer_type = /obj/effect/projectile/darkmatterstun/tracer - impact_type = /obj/effect/projectile/darkmatterstun/impact + muzzle_type = /obj/effect/projectile/muzzle/darkmatterstun + tracer_type = /obj/effect/projectile/tracer/darkmatterstun + impact_type = /obj/effect/projectile/impact/darkmatterstun /obj/item/projectile/beam/darkmatter name = "dark matter bolt" @@ -95,9 +95,9 @@ embed_chance = 0 - muzzle_type = /obj/effect/projectile/darkmatter/muzzle - tracer_type = /obj/effect/projectile/darkmatter/tracer - impact_type = /obj/effect/projectile/darkmatter/impact + muzzle_type = /obj/effect/projectile/muzzle/darkmatter + tracer_type = /obj/effect/projectile/tracer/darkmatter + impact_type = /obj/effect/projectile/impact/darkmatter /obj/item/projectile/energy/darkmatter name = "dark matter pellet" diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 4566577a94..ed4d0a639f 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -1,37 +1,84 @@ -/* -#define BRUTE "brute" -#define BURN "burn" -#define TOX "tox" -#define OXY "oxy" -#define CLONE "clone" - -#define ADD "add" -#define SET "set" -*/ +#define MOVES_HITSCAN -1 //Not actually hitscan but close as we get without actual hitscan. +#define MUZZLE_EFFECT_PIXEL_INCREMENT 17 //How many pixels to move the muzzle flash up so your character doesn't look like they're shitting out lasers. /obj/item/projectile name = "projectile" icon = 'icons/obj/projectiles.dmi' icon_state = "bullet" - 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. + density = FALSE + anchored = TRUE + unacidable = TRUE pass_flags = PASSTABLE mouse_opacity = 0 - var/bumped = 0 //Prevents it from hitting more than one guy at once + + ////TG PROJECTILE SYTSEM + //Projectile stuff + var/range = 50 + var/originalRange + + //Fired processing vars + var/fired = FALSE //Have we been fired yet + var/paused = FALSE //for suspending the projectile midair + var/last_projectile_move = 0 + var/last_process = 0 + var/time_offset = 0 + var/datum/point/vector/trajectory + var/trajectory_ignore_forcemove = FALSE //instructs forceMove to NOT reset our trajectory to the new location! + + var/speed = 0.8 //Amount of deciseconds it takes for projectile to travel + var/Angle = 0 + var/original_angle = 0 //Angle at firing + var/nondirectional_sprite = FALSE //Set TRUE to prevent projectiles from having their sprites rotated based on firing angle + var/spread = 0 //amount (in degrees) of projectile spread + animate_movement = 0 //Use SLIDE_STEPS in conjunction with legacy + var/ricochets = 0 + var/ricochets_max = 2 + var/ricochet_chance = 30 + + //Hitscan + var/hitscan = FALSE //Whether this is hitscan. If it is, speed is basically ignored. + var/list/beam_segments //assoc list of datum/point or datum/point/vector, start = end. Used for hitscan effect generation. + var/datum/point/beam_index + var/turf/hitscan_last //last turf touched during hitscanning. + var/tracer_type + var/muzzle_type + var/impact_type + + //Fancy hitscan lighting effects! + var/hitscan_light_intensity = 1.5 + var/hitscan_light_range = 0.75 + var/hitscan_light_color_override + var/muzzle_flash_intensity = 3 + var/muzzle_flash_range = 1.5 + var/muzzle_flash_color_override + var/impact_light_intensity = 3 + var/impact_light_range = 2 + var/impact_light_color_override + + //Homing + var/homing = FALSE + var/atom/homing_target + var/homing_turn_speed = 10 //Angle per tick. + var/homing_inaccuracy_min = 0 //in pixels for these. offsets are set once when setting target. + var/homing_inaccuracy_max = 0 + var/homing_offset_x = 0 + var/homing_offset_y = 0 + + //Targetting + var/yo = null + var/xo = null + var/atom/original = null // the original target clicked + var/turf/starting = null // the projectile's starting turf + var/list/permutated = list() // we've passed through these atoms, don't try to hit them again + var/p_x = 16 + var/p_y = 16 // the pixel location of the tile that the player clicked. Default is the center + + //Misc/Polaris variables + var/def_zone = "" //Aiming at var/mob/firer = null//Who shot it var/silenced = 0 //Attack message - var/yo = null - var/xo = null - var/current = null var/shot_from = "" // name of the object which shot us - var/atom/original = null // the target clicked (not necessarily where the projectile is headed). Should probably be renamed to 'target' or something. - var/turf/starting = null // the projectile's starting turf - var/list/permutated = list() // we've passed through these atoms, don't try to hit them again - - var/p_x = 16 - var/p_y = 16 // the pixel location of the tile that the player clicked. Default is the center var/accuracy = 0 var/dispersion = 0.0 @@ -45,7 +92,6 @@ var/check_armour = "bullet" //Defines what armor to use when it hits things. Must be set to bullet, laser, energy,or bomb //Cael - bio and rad are also valid var/projectile_type = /obj/item/projectile var/penetrating = 0 //If greater than zero, the projectile will pass through dense objects as specified by on_penetrate() - var/kill_count = 50 //This will de-increment every process(). When 0, it will delete the projectile. //Effects var/incendiary = 0 //1 for ignite on hit, 2 for trail of fire. 3 maybe later for burst of fire around the impact point. - Mech var/flammability = 0 //Amount of fire stacks to add for the above. @@ -59,179 +105,370 @@ var/drowsy = 0 var/agony = 0 var/reflected = 0 // This should be set to 1 if reflected by any means, to prevent infinite reflections. + var/modifier_type_to_apply = null // If set, will apply a modifier to mobs that are hit by this projectile. + var/modifier_duration = null // How long the above modifier should last for. Leave null to be permanent. embed_chance = 0 //Base chance for a projectile to embed - var/hitscan = 0 // whether the projectile should be hitscan - var/step_delay = 1 // the delay between iterations if not a hitscan projectile + var/fire_sound = 'sound/weapons/Gunshot_old.ogg' // Can be overriden in gun.dm's fire_sound var. It can also be null but I don't know why you'd ever want to do that. -Ace - // effect types to be used - var/muzzle_type - var/tracer_type - var/impact_type + var/vacuum_traversal = TRUE //Determines if the projectile can exist in vacuum, if false, the projectile will be deleted if it enters vacuum. - var/fire_sound +/obj/item/projectile/proc/Range() + range-- + if(range <= 0 && loc) + on_range() - var/vacuum_traversal = 1 //Determines if the projectile can exist in vacuum, if false, the projectile will be deleted if it enters vacuum. +/obj/item/projectile/proc/on_range() //if we want there to be effects when they reach the end of their range + qdel(src) - var/datum/plot_vector/trajectory // used to plot the path of the projectile - var/datum/vector_loc/location // current location of the projectile in pixel space - var/matrix/effect_transform // matrix to rotate and scale projectile effects - putting it here so it doesn't - // have to be recreated multiple times +/obj/item/projectile/proc/return_predicted_turf_after_moves(moves, forced_angle) //I say predicted because there's no telling that the projectile won't change direction/location in flight. + if(!trajectory && isnull(forced_angle) && isnull(Angle)) + return FALSE + var/datum/point/vector/current = trajectory + if(!current) + var/turf/T = get_turf(src) + current = new(T.x, T.y, T.z, pixel_x, pixel_y, isnull(forced_angle)? Angle : forced_angle, SSprojectiles.global_pixel_speed) + var/datum/point/vector/v = current.return_vector_after_increments(moves * SSprojectiles.global_iterations_per_move) + return v.return_turf() -//TODO: make it so this is called more reliably, instead of sometimes by bullet_act() and sometimes not -/obj/item/projectile/proc/on_hit(var/atom/target, var/blocked = 0, var/def_zone = null) - if(blocked >= 100) return 0//Full block - if(!isliving(target)) return 0 -// if(isanimal(target)) return 0 - var/mob/living/L = target - L.apply_effects(stun, weaken, paralyze, irradiate, stutter, eyeblur, drowsy, agony, blocked, incendiary, flammability) // add in AGONY! - return 1 +/obj/item/projectile/proc/return_pathing_turfs_in_moves(moves, forced_angle) + var/turf/current = get_turf(src) + var/turf/ending = return_predicted_turf_after_moves(moves, forced_angle) + return getline(current, ending) -//called when the projectile stops flying because it collided with something -/obj/item/projectile/proc/on_impact(var/atom/A) - impact_effect(effect_transform) // generate impact effect - if(damage && damage_type == BURN) - var/turf/T = get_turf(A) - if(T) - T.hotspot_expose(700, 5) +/obj/item/projectile/proc/set_pixel_speed(new_speed) + if(trajectory) + trajectory.set_speed(new_speed) + return TRUE + return FALSE + +/obj/item/projectile/proc/record_hitscan_start(datum/point/pcache) + if(pcache) + beam_segments = list() + beam_index = pcache + beam_segments[beam_index] = null //record start. + +/obj/item/projectile/proc/process_hitscan() + var/safety = range * 3 + record_hitscan_start(RETURN_POINT_VECTOR_INCREMENT(src, Angle, MUZZLE_EFFECT_PIXEL_INCREMENT, 1)) + while(loc && !QDELETED(src)) + if(paused) + stoplag(1) + continue + if(safety-- <= 0) + if(loc) + Bump(loc) + if(!QDELETED(src)) + qdel(src) + return //Kill! + pixel_move(1, TRUE) + +/obj/item/projectile/proc/pixel_move(trajectory_multiplier, hitscanning = FALSE) + if(!loc || !trajectory) + return + last_projectile_move = world.time + if(homing) + process_homing() + var/forcemoved = FALSE + for(var/i in 1 to SSprojectiles.global_iterations_per_move) + if(QDELETED(src)) + return + trajectory.increment(trajectory_multiplier) + var/turf/T = trajectory.return_turf() + if(!istype(T)) + qdel(src) + return + if(T.z != loc.z) + var/old = loc + before_z_change(loc, T) + trajectory_ignore_forcemove = TRUE + forceMove(T) + trajectory_ignore_forcemove = FALSE + after_z_change(old, loc) + if(!hitscanning) + pixel_x = trajectory.return_px() + pixel_y = trajectory.return_py() + forcemoved = TRUE + hitscan_last = loc + else if(T != loc) + before_move() + step_towards(src, T) + hitscan_last = loc + after_move() + if(can_hit_target(original, permutated)) + Bump(original) + if(!hitscanning && !forcemoved) + pixel_x = trajectory.return_px() - trajectory.mpx * trajectory_multiplier * SSprojectiles.global_iterations_per_move + pixel_y = trajectory.return_py() - trajectory.mpy * trajectory_multiplier * SSprojectiles.global_iterations_per_move + animate(src, pixel_x = trajectory.return_px(), pixel_y = trajectory.return_py(), time = 1, flags = ANIMATION_END_NOW) + Range() + +/obj/item/projectile/Crossed(atom/movable/AM) //A mob moving on a tile with a projectile is hit by it. + ..() + if(isliving(AM) && (AM.density || AM == original)) + Bump(AM) + +/obj/item/projectile/proc/process_homing() //may need speeding up in the future performance wise. + if(!homing_target) + return FALSE + var/datum/point/PT = RETURN_PRECISE_POINT(homing_target) + PT.x += CLAMP(homing_offset_x, 1, world.maxx) + PT.y += CLAMP(homing_offset_y, 1, world.maxy) + var/angle = closer_angle_difference(Angle, angle_between_points(RETURN_PRECISE_POINT(src), PT)) + setAngle(Angle + CLAMP(angle, -homing_turn_speed, homing_turn_speed)) + +/obj/item/projectile/proc/set_homing_target(atom/A) + if(!A || (!isturf(A) && !isturf(A.loc))) + return FALSE + homing = TRUE + homing_target = A + homing_offset_x = rand(homing_inaccuracy_min, homing_inaccuracy_max) + homing_offset_y = rand(homing_inaccuracy_min, homing_inaccuracy_max) + if(prob(50)) + homing_offset_x = -homing_offset_x + if(prob(50)) + homing_offset_y = -homing_offset_y + +/obj/item/projectile/process() + last_process = world.time + if(!loc || !fired || !trajectory) + fired = FALSE + return PROCESS_KILL + if(paused || !isturf(loc)) + last_projectile_move += world.time - last_process //Compensates for pausing, so it doesn't become a hitscan projectile when unpaused from charged up ticks. + return + var/elapsed_time_deciseconds = (world.time - last_projectile_move) + time_offset + time_offset = 0 + var/required_moves = speed > 0? FLOOR(elapsed_time_deciseconds / speed, 1) : MOVES_HITSCAN //Would be better if a 0 speed made hitscan but everyone hates those so I can't make it a universal system :< + if(required_moves == MOVES_HITSCAN) + required_moves = SSprojectiles.global_max_tick_moves + else + if(required_moves > SSprojectiles.global_max_tick_moves) + var/overrun = required_moves - SSprojectiles.global_max_tick_moves + required_moves = SSprojectiles.global_max_tick_moves + time_offset += overrun * speed + time_offset += MODULUS(elapsed_time_deciseconds, speed) + + for(var/i in 1 to required_moves) + pixel_move(1, FALSE) + +/obj/item/projectile/proc/setAngle(new_angle) //wrapper for overrides. + Angle = new_angle + if(!nondirectional_sprite) + var/matrix/M = new + M.Turn(Angle) + transform = M + if(trajectory) + trajectory.set_angle(new_angle) + return TRUE + +/obj/item/projectile/forceMove(atom/target) + if(!isloc(target) || !isloc(loc) || !z) + return ..() + var/zc = target.z != z + var/old = loc + if(zc) + before_z_change(old, target) + . = ..() + if(trajectory && !trajectory_ignore_forcemove && isturf(target)) + if(hitscan) + finalize_hitscan_and_generate_tracers(FALSE) + trajectory.initialize_location(target.x, target.y, target.z, 0, 0) + if(hitscan) + record_hitscan_start(RETURN_PRECISE_POINT(src)) + if(zc) + after_z_change(old, target) + +/obj/item/projectile/proc/fire(angle, atom/direct_target) + //If no angle needs to resolve it from xo/yo! + if(direct_target) + direct_target.bullet_act(src, def_zone) + qdel(src) + return + if(isnum(angle)) + setAngle(angle) + var/turf/starting = get_turf(src) + if(isnull(Angle)) //Try to resolve through offsets if there's no angle set. + if(isnull(xo) || isnull(yo)) + crash_with("WARNING: Projectile [type] deleted due to being unable to resolve a target after angle was null!") + qdel(src) + return + var/turf/target = locate(CLAMP(starting + xo, 1, world.maxx), CLAMP(starting + yo, 1, world.maxy), starting.z) + setAngle(Get_Angle(src, target)) + if(dispersion) + setAngle(Angle + rand(-dispersion, dispersion)) + original_angle = Angle + trajectory_ignore_forcemove = TRUE + forceMove(starting) + trajectory_ignore_forcemove = FALSE + trajectory = new(starting.x, starting.y, starting.z, pixel_x, pixel_y, Angle, SSprojectiles.global_pixel_speed) + last_projectile_move = world.time + permutated = list() + originalRange = range + fired = TRUE + if(hitscan) + process_hitscan() + START_PROCESSING(SSprojectiles, src) + pixel_move(1, FALSE) //move it now! + +/obj/item/projectile/proc/after_z_change(atom/olcloc, atom/newloc) + +/obj/item/projectile/proc/before_z_change(atom/oldloc, atom/newloc) + +/obj/item/projectile/proc/before_move() return -//Checks if the projectile is eligible for embedding. Not that it necessarily will. -/obj/item/projectile/proc/can_embed() - //embed must be enabled and damage type must be brute - if(embed_chance == 0 || damage_type != BRUTE) - return 0 - return 1 +/obj/item/projectile/proc/after_move() + return -/obj/item/projectile/proc/get_structure_damage() - if(damage_type == BRUTE || damage_type == BURN) - return damage - return 0 +/obj/item/projectile/proc/store_hitscan_collision(datum/point/pcache) + beam_segments[beam_index] = pcache + beam_index = pcache + beam_segments[beam_index] = null -//return 1 if the projectile should be allowed to pass through after all, 0 if not. -/obj/item/projectile/proc/check_penetrate(var/atom/A) - return 1 +//Spread is FORCED! +/obj/item/projectile/proc/preparePixelProjectile(atom/target, atom/source, params, spread = 0) + var/turf/curloc = get_turf(source) + var/turf/targloc = get_turf(target) + trajectory_ignore_forcemove = TRUE + forceMove(get_turf(source)) + trajectory_ignore_forcemove = FALSE + starting = get_turf(source) + original = target + if(targloc || !params) + yo = targloc.y - curloc.y + xo = targloc.x - curloc.x + setAngle(Get_Angle(src, targloc) + spread) -/obj/item/projectile/proc/check_fire(atom/target as mob, var/mob/living/user as mob) //Checks if you can hit them or not. - check_trajectory(target, user, pass_flags, flags) + if(isliving(source) && params) + var/list/calculated = calculate_projectile_angle_and_pixel_offsets(source, params) + p_x = calculated[2] + p_y = calculated[3] -//sets the click point of the projectile using mouse input params -/obj/item/projectile/proc/set_clickpoint(var/params) + setAngle(calculated[1] + spread) + else if(targloc) + yo = targloc.y - curloc.y + xo = targloc.x - curloc.x + setAngle(Get_Angle(src, targloc) + spread) + else + crash_with("WARNING: Projectile [type] fired without either mouse parameters, or a target atom to aim at!") + qdel(src) + +/proc/calculate_projectile_angle_and_pixel_offsets(mob/user, params) var/list/mouse_control = params2list(params) + var/p_x = 0 + var/p_y = 0 + var/angle = 0 if(mouse_control["icon-x"]) p_x = text2num(mouse_control["icon-x"]) if(mouse_control["icon-y"]) p_y = text2num(mouse_control["icon-y"]) + if(mouse_control["screen-loc"]) + //Split screen-loc up into X+Pixel_X and Y+Pixel_Y + var/list/screen_loc_params = splittext(mouse_control["screen-loc"], ",") - //randomize clickpoint a bit based on dispersion - if(dispersion) - var/radius = round((dispersion*0.443)*world.icon_size*0.8) //0.443 = sqrt(pi)/4 = 2a, where a is the side length of a square that shares the same area as a circle with diameter = dispersion - p_x = between(0, p_x + rand(-radius, radius), world.icon_size) - p_y = between(0, p_y + rand(-radius, radius), world.icon_size) + //Split X+Pixel_X up into list(X, Pixel_X) + var/list/screen_loc_X = splittext(screen_loc_params[1],":") -//called to launch a projectile -/obj/item/projectile/proc/launch(atom/target, var/target_zone, var/x_offset=0, var/y_offset=0, var/angle_offset=0) - var/turf/curloc = get_turf(src) - var/turf/targloc = get_turf(target) - if (!istype(targloc) || !istype(curloc)) - return 1 + //Split Y+Pixel_Y up into list(Y, Pixel_Y) + var/list/screen_loc_Y = splittext(screen_loc_params[2],":") + var/x = text2num(screen_loc_X[1]) * 32 + text2num(screen_loc_X[2]) - 32 + var/y = text2num(screen_loc_Y[1]) * 32 + text2num(screen_loc_Y[2]) - 32 - if(combustion) - curloc.hotspot_expose(700, 5) + //Calculate the "resolution" of screen based on client's view and world's icon size. This will work if the user can view more tiles than average. + var/list/screenview = user.client? getviewsize(user.client.view) : world.view + var/screenviewX = screenview[1] * world.icon_size + var/screenviewY = screenview[2] * world.icon_size - if(targloc == curloc) //Shooting something in the same turf - target.bullet_act(src, target_zone) - on_impact(target) - qdel(src) - return 0 + var/ox = round(screenviewX/2) - user.client.pixel_x //"origin" x + var/oy = round(screenviewY/2) - user.client.pixel_y //"origin" y + angle = ATAN2(y - oy, x - ox) + return list(angle, p_x, p_y) +/obj/item/projectile/proc/redirect(x, y, starting, source) + old_style_target(locate(x, y, z), starting? get_turf(starting) : get_turf(source)) + +/obj/item/projectile/proc/old_style_target(atom/target, atom/source) + if(!source) + source = get_turf(src) + starting = source original = target - def_zone = target_zone + setAngle(Get_Angle(source, target)) - spawn() - setup_trajectory(curloc, targloc, x_offset, y_offset, angle_offset) //plot the initial trajectory - process() +/obj/item/projectile/Destroy() + if(hitscan) + finalize_hitscan_and_generate_tracers() + STOP_PROCESSING(SSprojectiles, src) + cleanup_beam_segments() + qdel(trajectory) + return ..() - return 0 +/obj/item/projectile/proc/cleanup_beam_segments() + QDEL_LIST_ASSOC(beam_segments) + beam_segments = list() + qdel(beam_index) -//called to launch a projectile from a gun -/obj/item/projectile/proc/launch_from_gun(atom/target, mob/user, obj/item/weapon/gun/launcher, var/target_zone, var/x_offset=0, var/y_offset=0) - if(user == target) //Shooting yourself - user.bullet_act(src, target_zone) - on_impact(user) - qdel(src) - return 0 - - loc = get_turf(user) //move the projectile out into the world - - firer = user - shot_from = launcher.name - silenced = launcher.silenced - - return launch(target, target_zone, x_offset, y_offset) - -//Used to change the direction of the projectile in flight. -/obj/item/projectile/proc/redirect(var/new_x, var/new_y, var/atom/starting_loc, var/mob/new_firer=null) - var/turf/new_target = locate(new_x, new_y, src.z) - - original = new_target - if(new_firer) - firer = src - - setup_trajectory(starting_loc, new_target) - -//Called when the projectile intercepts a mob. Returns 1 if the projectile hit the mob, 0 if it missed and should keep flying. -/obj/item/projectile/proc/attack_mob(var/mob/living/target_mob, var/distance, var/miss_modifier=0) - if(!istype(target_mob)) - return - - //roll to-hit - miss_modifier = max(15*(distance-2) - accuracy + miss_modifier + target_mob.get_evasion(), 0) - var/hit_zone = get_zone_with_miss_chance(def_zone, target_mob, miss_modifier, ranged_attack=(distance > 1 || original != target_mob)) //if the projectile hits a target we weren't originally aiming at then retain the chance to miss - - var/result = PROJECTILE_FORCE_MISS - if(hit_zone) - def_zone = hit_zone //set def_zone, so if the projectile ends up hitting someone else later (to be implemented), it is more likely to hit the same part - result = target_mob.bullet_act(src, def_zone) - - if(result == PROJECTILE_FORCE_MISS) - if(!silenced) - visible_message("\The [src] misses [target_mob] narrowly!") - return 0 - - //hit messages - if(silenced) - to_chat(target_mob, "You've been hit in the [parse_zone(def_zone)] by \the [src]!") +/obj/item/projectile/proc/vol_by_damage() + if(damage) + return CLAMP((damage) * 0.67, 30, 100)// Multiply projectile damage by 0.67, then CLAMP the value between 30 and 100 else - visible_message("\The [target_mob] is hit by \the [src] 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 + return 50 //if the projectile doesn't do damage, play its hitsound at 50% volume. - //admin logs - if(!no_attack_log) - if(istype(firer, /mob) && istype(target_mob)) - add_attack_logs(firer,target_mob,"Shot with \a [src.type] projectile") +/obj/item/projectile/proc/finalize_hitscan_and_generate_tracers(impacting = TRUE) + if(trajectory && beam_index) + var/datum/point/pcache = trajectory.copy_to() + beam_segments[beam_index] = pcache + generate_hitscan_tracers(null, null, impacting) - //sometimes bullet_act() will want the projectile to continue flying - if (result == PROJECTILE_CONTINUE) - return 0 +/obj/item/projectile/proc/generate_hitscan_tracers(cleanup = TRUE, duration = 3, impacting = TRUE) + if(!length(beam_segments)) + return + if(tracer_type) + var/tempref = "\ref[src]" + for(var/datum/point/p in beam_segments) + generate_tracer_between_points(p, beam_segments[p], tracer_type, color, duration, hitscan_light_range, hitscan_light_color_override, hitscan_light_intensity, tempref) + if(muzzle_type && duration > 0) + var/datum/point/p = beam_segments[1] + var/atom/movable/thing = new muzzle_type + p.move_atom_to_src(thing) + var/matrix/M = new + M.Turn(original_angle) + thing.transform = M + thing.color = color + thing.set_light(muzzle_flash_range, muzzle_flash_intensity, muzzle_flash_color_override? muzzle_flash_color_override : color) + QDEL_IN(thing, duration) + if(impacting && impact_type && duration > 0) + var/datum/point/p = beam_segments[beam_segments[beam_segments.len]] + var/atom/movable/thing = new impact_type + p.move_atom_to_src(thing) + var/matrix/M = new + M.Turn(Angle) + thing.transform = M + thing.color = color + thing.set_light(impact_light_range, impact_light_intensity, impact_light_color_override? impact_light_color_override : color) + QDEL_IN(thing, duration) + if(cleanup) + cleanup_beam_segments() - return 1 +//Returns true if the target atom is on our current turf and above the right layer +/obj/item/projectile/proc/can_hit_target(atom/target, var/list/passthrough) + return (target && ((target.layer >= TABLE_LAYER) || ismob(target)) && (loc == get_turf(target)) && (!(target in passthrough))) -/obj/item/projectile/Bump(atom/A as mob|obj|turf|area, forced=0) - if(A == src) - return 0 //no +/obj/item/projectile/Bump(atom/A) + if(A in permutated) + return FALSE + if(firer && !reflected) + if(A == firer || (A == firer.loc && istype(A, /obj/mecha))) //cannot shoot yourself or your mech + trajectory_ignore_forcemove = TRUE + forceMove(get_turf(A)) + trajectory_ignore_forcemove = FALSE + return FALSE - if(A == firer) - loc = A.loc - return 0 //cannot shoot yourself + var/distance = get_dist(starting, get_turf(src)) + var/turf/target_turf = get_turf(A) + var/passthrough = FALSE - if((bumped && !forced) || (A in permutated)) - return 0 - - var/passthrough = 0 //if the projectile should continue flying - var/distance = get_dist(starting,loc) - - bumped = 1 if(ismob(A)) var/mob/M = A if(istype(A, /mob/living)) @@ -242,13 +479,13 @@ var/shield_chance = min(80, (30 * (M.mob_size / 10))) //Small mobs have a harder time keeping a dead body as a shield than a human-sized one. Unathi would have an easier job, if they are made to be SIZE_LARGE in the future. -Mech if(prob(shield_chance)) visible_message("\The [M] uses [G.affecting] as a shield!") - if(Bump(G.affecting, forced=1)) + if(Bump(G.affecting)) return else visible_message("\The [M] tries to use [G.affecting] as a shield, but fails!") else visible_message("\The [M] uses [G.affecting] as a shield!") - if(Bump(G.affecting, forced=1)) + if(Bump(G.affecting)) return //If Bump() returns 0 (keep going) then we continue on to attack M. passthrough = !attack_mob(M, distance) @@ -265,229 +502,113 @@ //penetrating projectiles can pass through things that otherwise would not let them if(!passthrough && penetrating > 0) if(check_penetrate(A)) - passthrough = 1 + passthrough = TRUE penetrating-- - //the bullet passes through a dense object! if(passthrough) - //move ourselves onto A so we can continue on our way. - if(A) - if(istype(A, /turf)) - loc = A - else - loc = A.loc - permutated.Add(A) - bumped = 0 //reset bumped variable! - return 0 - - //stop flying - on_impact(A) - - density = 0 - invisibility = 101 + trajectory_ignore_forcemove = TRUE + forceMove(target_turf) + permutated.Add(A) + trajectory_ignore_forcemove = FALSE + return FALSE + if(A) + on_impact(A) qdel(src) + return TRUE + +//TODO: make it so this is called more reliably, instead of sometimes by bullet_act() and sometimes not +/obj/item/projectile/proc/on_hit(atom/target, blocked = 0, def_zone) + if(blocked >= 100) return 0//Full block + if(!isliving(target)) return 0 +// if(isanimal(target)) return 0 + var/mob/living/L = target + L.apply_effects(stun, weaken, paralyze, irradiate, stutter, eyeblur, drowsy, agony, blocked, incendiary, flammability) // add in AGONY! + if(modifier_type_to_apply) + L.add_modifier(modifier_type_to_apply, modifier_duration) return 1 -/obj/item/projectile/ex_act() - return //explosions probably shouldn't delete projectiles +//called when the projectile stops flying because it Bump'd with something +/obj/item/projectile/proc/on_impact(atom/A) + if(damage && damage_type == BURN) + var/turf/T = get_turf(A) + if(T) + T.hotspot_expose(700, 5) -/obj/item/projectile/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) +//Checks if the projectile is eligible for embedding. Not that it necessarily will. +/obj/item/projectile/proc/can_embed() + //embed must be enabled and damage type must be brute + if(embed_chance == 0 || damage_type != BRUTE) + return 0 return 1 -/obj/item/projectile/process() - var/first_step = 1 +/obj/item/projectile/proc/get_structure_damage() + if(damage_type == BRUTE || damage_type == BURN) + return damage + return 0 - spawn while(src && src.loc) - if(kill_count-- < 1) - on_impact(src.loc) //for any final impact behaviours - qdel(src) - return - if((!( current ) || loc == current)) - current = locate(min(max(x + xo, 1), world.maxx), min(max(y + yo, 1), world.maxy), z) - if((x == 1 || x == world.maxx || y == 1 || y == world.maxy)) - qdel(src) - return +//return 1 if the projectile should be allowed to pass through after all, 0 if not. +/obj/item/projectile/proc/check_penetrate(atom/A) + return 1 - trajectory.increment() // increment the current location - location = trajectory.return_location(location) // update the locally stored location data - update_light() //energy projectiles will look glowy and fun +/obj/item/projectile/proc/check_fire(atom/target as mob, mob/living/user as mob) //Checks if you can hit them or not. + check_trajectory(target, user, pass_flags, flags) - if(!location) - qdel(src) // if it's left the world... kill it - return +/obj/item/projectile/CanPass() + return TRUE - if (is_below_sound_pressure(get_turf(src)) && !vacuum_traversal) //Deletes projectiles that aren't supposed to bein vacuum if they leave pressurised areas - qdel(src) - return +//Called when the projectile intercepts a mob. Returns 1 if the projectile hit the mob, 0 if it missed and should keep flying. +/obj/item/projectile/proc/attack_mob(mob/living/target_mob, distance, miss_modifier = 0) + if(!istype(target_mob)) + return - before_move() - Move(location.return_turf()) - after_move() + //roll to-hit + miss_modifier = max(15*(distance-2) - accuracy + miss_modifier + target_mob.get_evasion(), 0) + var/hit_zone = get_zone_with_miss_chance(def_zone, target_mob, miss_modifier, ranged_attack=(distance > 1 || original != target_mob)) //if the projectile hits a target we weren't originally aiming at then retain the chance to miss - if(!bumped && !isturf(original)) - if(loc == get_turf(original)) - if(!(original in permutated)) - if(Bump(original)) - return + var/result = PROJECTILE_FORCE_MISS + if(hit_zone) + def_zone = hit_zone //set def_zone, so if the projectile ends up hitting someone else later (to be implemented), it is more likely to hit the same part + result = target_mob.bullet_act(src, def_zone) - if(first_step) - muzzle_effect(effect_transform) - first_step = 0 - else if(!bumped) - tracer_effect(effect_transform) + if(result == PROJECTILE_FORCE_MISS) + if(!silenced) + visible_message("\The [src] misses [target_mob] narrowly!") + return FALSE - if(incendiary >= 2) //This should cover the bases of 'Why is there fuel here?' in a much cleaner way than previous. - if(src && src.loc) //Safety. - if(!src.loc.density) - var/trail_volume = (flammability * 0.20) - new /obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel(src.loc, trail_volume, src.dir) - - if(!hitscan) - sleep(step_delay) //add delay between movement iterations if it's not a hitscan weapon - -/obj/item/projectile/proc/before_move() - return - -/obj/item/projectile/proc/after_move() - return - -/obj/item/projectile/proc/setup_trajectory(turf/startloc, turf/targloc, var/x_offset = 0, var/y_offset = 0) - // setup projectile state - starting = startloc - current = startloc - yo = targloc.y - startloc.y + y_offset - xo = targloc.x - startloc.x + x_offset - - // trajectory dispersion - var/offset = 0 - if(dispersion) - var/radius = round(dispersion*9, 1) - offset = rand(-radius, radius) - - // plot the initial trajectory - trajectory = new() - trajectory.setup(starting, original, pixel_x, pixel_y, angle_offset=offset) - - // generate this now since all visual effects the projectile makes can use it - effect_transform = new() - effect_transform.Scale(trajectory.return_hypotenuse(), 1) - effect_transform.Turn(-trajectory.return_angle()) //no idea why this has to be inverted, but it works - - transform = turn(transform, -(trajectory.return_angle() + 90)) //no idea why 90 needs to be added, but it works - -/obj/item/projectile/proc/muzzle_effect(var/matrix/T) + //hit messages if(silenced) - return + to_chat(target_mob, "You've been hit in the [parse_zone(def_zone)] by \the [src]!") + else + visible_message("\The [target_mob] is hit by \the [src] 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(ispath(muzzle_type)) - var/obj/effect/projectile/M = new muzzle_type(get_turf(src)) + //admin logs + if(!no_attack_log) + if(istype(firer, /mob) && istype(target_mob)) + add_attack_logs(firer,target_mob,"Shot with \a [src.type] projectile") - if(istype(M)) - M.set_transform(T) - M.pixel_x = location.pixel_x - M.pixel_y = location.pixel_y - M.update_light() - M.activate() + //sometimes bullet_act() will want the projectile to continue flying + if (result == PROJECTILE_CONTINUE) + return FALSE -/obj/item/projectile/proc/tracer_effect(var/matrix/M) - if(ispath(tracer_type)) - var/obj/effect/projectile/P = new tracer_type(location.loc) + return TRUE - if(istype(P)) - P.set_transform(M) - P.pixel_x = location.pixel_x - P.pixel_y = location.pixel_y - P.update_light() - if(!hitscan) - P.activate(step_delay) //if not a hitscan projectile, remove after a single delay - else - P.activate() - -/obj/item/projectile/proc/impact_effect(var/matrix/M) - if(ispath(tracer_type) && location) - var/obj/effect/projectile/P = new impact_type(location.loc) - - if(istype(P)) - P.set_transform(M) - P.pixel_x = location.pixel_x - P.pixel_y = location.pixel_y - P.update_light() - P.activate() - -//"Tracing" projectile -/obj/item/projectile/test //Used to see if you can hit them. - invisibility = 101 //Nope! Can't see me! - yo = null - xo = null - var/result = 0 //To pass the message back to the gun. - -/obj/item/projectile/test/Bump(atom/A as mob|obj|turf|area) - if(A == firer) - loc = A.loc - return //cannot shoot yourself - if(istype(A, /obj/item/projectile)) - return - if(istype(A, /obj/structure/foamedmetal)) //Turrets can detect through foamed metal, but will have to blast through it. Similar to windows, if someone runs behind it, a person should probably just not shoot. - return - if(istype(A, /obj/structure/girder)) //They see you there. - return - if(istype(A, /obj/structure/door_assembly)) //And through there. - return - if(istype(A, /obj/structure)) //Unanchored things you can shove around will still keep the turret or other firing at your position. Aim intent still functions. - var/obj/structure/S = A - if(!S.anchored) - return - if(istype(A, /mob/living) || istype(A, /obj/mecha) || istype(A, /obj/vehicle)) - result = 2 //We hit someone, return 1! - return - result = 1 - return - -/obj/item/projectile/test/launch(atom/target) - var/turf/curloc = get_turf(src) - var/turf/targloc = get_turf(target) - if(!curloc || !targloc) - return 0 +/obj/item/projectile/proc/launch_projectile(atom/target, target_zone, mob/user, params, angle_override, forced_spread = 0) original = target + def_zone = check_zone(target_zone) + firer = user + var/direct_target + if(get_turf(target) == get_turf(src)) + direct_target = target - //plot the initial trajectory - setup_trajectory(curloc, targloc) - return process(targloc) + preparePixelProjectile(target, user? user : get_turf(src), params, forced_spread) + return fire(angle_override, direct_target) -/obj/item/projectile/test/process(var/turf/targloc) - while(src) //Loop on through! - if(result) - return (result - 1) - if((!( targloc ) || loc == targloc)) - targloc = locate(min(max(x + xo, 1), world.maxx), min(max(y + yo, 1), world.maxy), z) //Finding the target turf at map edge +//called to launch a projectile from a gun +/obj/item/projectile/proc/launch_from_gun(atom/target, target_zone, mob/user, params, angle_override, forced_spread, obj/item/weapon/gun/launcher) - trajectory.increment() // increment the current location - location = trajectory.return_location(location) // update the locally stored location data + shot_from = launcher.name + silenced = launcher.silenced - Move(location.return_turf()) - - var/mob/living/M = locate() in get_turf(src) - if(istype(M)) //If there is someting living... - return 1 //Return 1 - else - M = locate() in get_step(src,targloc) - if(istype(M)) - return 1 - -//Helper proc to check if you can hit them or not. -/proc/check_trajectory(atom/target as mob|obj, atom/firer as mob|obj, var/pass_flags=PASSTABLE|PASSGLASS|PASSGRILLE, flags=null) - if(!istype(target) || !istype(firer)) - return 0 - - var/obj/item/projectile/test/trace = new /obj/item/projectile/test(get_turf(firer)) //Making the test.... - - //Set the flags and pass flags to that of the real projectile... - if(!isnull(flags)) - trace.flags = flags - trace.pass_flags = pass_flags - - var/output = trace.launch(target) //Test it! - qdel(trace) //No need for it anymore - return output //Send it back to the gun! + return launch_projectile(target, target_zone, user, params, angle_override, forced_spread) diff --git a/code/modules/projectiles/projectile/animate.dm b/code/modules/projectiles/projectile/animate.dm index e88e6faa33..20196022af 100644 --- a/code/modules/projectiles/projectile/animate.dm +++ b/code/modules/projectiles/projectile/animate.dm @@ -13,5 +13,5 @@ /obj/item/projectile/animate/Bump(var/atom/change) if((istype(change, /obj/item) || istype(change, /obj/structure)) && !is_type_in_list(change, protected_objects)) var/obj/O = change - new /mob/living/simple_animal/hostile/mimic/copy(O.loc, O, firer) + new /mob/living/simple_mob/hostile/mimic/copy(O.loc, O, firer) ..() diff --git a/code/modules/projectiles/projectile/arc.dm b/code/modules/projectiles/projectile/arc.dm index 5606cbe9d5..ef61558518 100644 --- a/code/modules/projectiles/projectile/arc.dm +++ b/code/modules/projectiles/projectile/arc.dm @@ -9,13 +9,17 @@ /obj/item/projectile/arc name = "arcing shot" icon_state = "fireball" // WIP - step_delay = 2 // Travel a bit slower, to really sell the arc visuals. + speed = 2 // Travel a bit slower, to really sell the arc visuals. + movement_type = UNSTOPPABLE plane = ABOVE_PLANE // Since projectiles are 'in the air', they might visually overlap mobs while in flight, so the projectile needs to be above their plane. var/target_distance = null // How many tiles the impact site is. var/fired_dir = null // Which direction was the projectile fired towards. Needed to invert the projectile turning based on if facing left or right. var/obj/effect/projectile_shadow/shadow = null // Visual indicator for the projectile's 'true' position. Needed due to being bound to two dimensions in reality. -/obj/item/projectile/arc/initialize() +/obj/item/projectile/arc/Bump() + return + +/obj/item/projectile/arc/Initialize() shadow = new(get_turf(src)) return ..() @@ -23,33 +27,32 @@ QDEL_NULL(shadow) return ..() -/obj/item/projectile/arc/Bump(atom/A, forced=0) - return 0 -// if(get_turf(src) != original) -// return 0 -// else -// return ..() - // This is a test projectile in the sense that its testing the code to make sure it works, // as opposed to a 'can I hit this thing' projectile. /obj/item/projectile/arc/test/on_impact(turf/T) new /obj/effect/explosion(T) return ..() -/obj/item/projectile/arc/launch(atom/target, target_zone, x_offset=0, y_offset=0, angle_offset=0) - var/expected_distance = get_dist(target, loc) - kill_count = expected_distance // So the projectile "hits the ground." +/obj/item/projectile/arc/old_style_target(target, source) + var/source_loc = get_turf(source) || get_turf(src) + var/expected_distance = get_dist(target, source_loc) + range = expected_distance // So the projectile "hits the ground." target_distance = expected_distance - fired_dir = get_dir(loc, target) - ..() // Does the regular launching stuff. + fired_dir = get_dir(source_loc, target) + ..() if(fired_dir & EAST) transform = turn(transform, -45) else if(fired_dir & WEST) transform = turn(transform, 45) +/obj/item/projectile/arc/on_range() + on_impact(loc) + return ..() // Visuals. /obj/item/projectile/arc/after_move() + if(QDELETED(src)) + return // Handle projectile turning in flight. // This won't turn if fired north/south, as it looks weird. var/turn_per_step = 90 / target_distance @@ -73,7 +76,7 @@ var/projectile_position = arc_progress / target_distance var/sine_position = projectile_position * 180 var/pixel_z_position = arc_max_height * sin(sine_position) - animate(src, pixel_z = pixel_z_position, time = step_delay) + animate(src, pixel_z = pixel_z_position, time = speed) // Update our shadow. shadow.forceMove(loc) diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index ee2ccc437c..0afec25187 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -15,9 +15,9 @@ light_power = 0.5 light_color = "#FF0D00" - muzzle_type = /obj/effect/projectile/laser/muzzle - tracer_type = /obj/effect/projectile/laser/tracer - impact_type = /obj/effect/projectile/laser/impact + muzzle_type = /obj/effect/projectile/muzzle/laser + tracer_type = /obj/effect/projectile/tracer/laser + impact_type = /obj/effect/projectile/impact/laser /obj/item/projectile/beam/practice name = "laser" @@ -54,9 +54,9 @@ light_power = 1 light_color = "#FF0D00" - muzzle_type = /obj/effect/projectile/laser_heavy/muzzle - tracer_type = /obj/effect/projectile/laser_heavy/tracer - impact_type = /obj/effect/projectile/laser_heavy/impact + muzzle_type = /obj/effect/projectile/muzzle/laser_heavy + tracer_type = /obj/effect/projectile/tracer/laser_heavy + impact_type = /obj/effect/projectile/impact/laser_heavy /obj/item/projectile/beam/heavylaser/fakeemitter name = "emitter beam" @@ -64,9 +64,9 @@ fire_sound = 'sound/weapons/emitter.ogg' light_color = "#00CC33" - muzzle_type = /obj/effect/projectile/emitter/muzzle - tracer_type = /obj/effect/projectile/emitter/tracer - impact_type = /obj/effect/projectile/emitter/impact + muzzle_type = /obj/effect/projectile/muzzle/emitter + tracer_type = /obj/effect/projectile/tracer/emitter + impact_type = /obj/effect/projectile/impact/emitter /obj/item/projectile/beam/heavylaser/cannon damage = 80 @@ -81,9 +81,9 @@ armor_penetration = 50 light_color = "#00CC33" - muzzle_type = /obj/effect/projectile/xray/muzzle - tracer_type = /obj/effect/projectile/xray/tracer - impact_type = /obj/effect/projectile/xray/impact + muzzle_type = /obj/effect/projectile/muzzle/xray + tracer_type = /obj/effect/projectile/tracer/xray + impact_type = /obj/effect/projectile/impact/xray /obj/item/projectile/beam/cyan name = "cyan beam" @@ -91,21 +91,21 @@ damage = 40 light_color = "#00C6FF" - muzzle_type = /obj/effect/projectile/laser_omni/muzzle - tracer_type = /obj/effect/projectile/laser_omni/tracer - impact_type = /obj/effect/projectile/laser_omni/impact + muzzle_type = /obj/effect/projectile/muzzle/laser_omni + tracer_type = /obj/effect/projectile/tracer/laser_omni + impact_type = /obj/effect/projectile/impact/laser_omni /obj/item/projectile/beam/pulse name = "pulse" icon_state = "u_laser" - fire_sound='sound/weapons/pulse.ogg' + fire_sound='sound/weapons/gauss_shoot.ogg' // Needs a more meaty sound than what pulse.ogg currently is; this will be a placeholder for now. damage = 100 //Badmin toy, don't care armor_penetration = 100 light_color = "#0066FF" - muzzle_type = /obj/effect/projectile/laser_pulse/muzzle - tracer_type = /obj/effect/projectile/laser_pulse/tracer - impact_type = /obj/effect/projectile/laser_pulse/impact + muzzle_type = /obj/effect/projectile/muzzle/laser_pulse + tracer_type = /obj/effect/projectile/tracer/laser_pulse + impact_type = /obj/effect/projectile/impact/laser_pulse /obj/item/projectile/beam/pulse/on_hit(var/atom/target, var/blocked = 0) if(isturf(target)) @@ -119,9 +119,9 @@ damage = 0 // The actual damage is computed in /code/modules/power/singularity/emitter.dm light_color = "#00CC33" - muzzle_type = /obj/effect/projectile/emitter/muzzle - tracer_type = /obj/effect/projectile/emitter/tracer - impact_type = /obj/effect/projectile/emitter/impact + muzzle_type = /obj/effect/projectile/muzzle/emitter + tracer_type = /obj/effect/projectile/tracer/emitter + impact_type = /obj/effect/projectile/impact/emitter /obj/item/projectile/beam/lastertag/blue name = "lasertag beam" @@ -134,9 +134,9 @@ combustion = FALSE - muzzle_type = /obj/effect/projectile/laser_blue/muzzle - tracer_type = /obj/effect/projectile/laser_blue/tracer - impact_type = /obj/effect/projectile/laser_blue/impact + muzzle_type = /obj/effect/projectile/muzzle/laser_blue + tracer_type = /obj/effect/projectile/tracer/laser_blue + impact_type = /obj/effect/projectile/impact/laser_blue /obj/item/projectile/beam/lastertag/blue/on_hit(var/atom/target, var/blocked = 0) if(istype(target, /mob/living/carbon/human)) @@ -173,9 +173,9 @@ combustion = FALSE - muzzle_type = /obj/effect/projectile/laser_omni/muzzle - tracer_type = /obj/effect/projectile/laser_omni/tracer - impact_type = /obj/effect/projectile/laser_omni/impact + muzzle_type = /obj/effect/projectile/muzzle/laser_omni + tracer_type = /obj/effect/projectile/tracer/laser_omni + impact_type = /obj/effect/projectile/impact/laser_omni /obj/item/projectile/beam/lastertag/omni/on_hit(var/atom/target, var/blocked = 0) if(istype(target, /mob/living/carbon/human)) @@ -192,9 +192,9 @@ armor_penetration = 10 light_color = "#00CC33" - muzzle_type = /obj/effect/projectile/xray/muzzle - tracer_type = /obj/effect/projectile/xray/tracer - impact_type = /obj/effect/projectile/xray/impact + muzzle_type = /obj/effect/projectile/muzzle/xray + tracer_type = /obj/effect/projectile/tracer/xray + impact_type = /obj/effect/projectile/impact/xray /obj/item/projectile/beam/stun name = "stun beam" @@ -208,9 +208,9 @@ combustion = FALSE - muzzle_type = /obj/effect/projectile/stun/muzzle - tracer_type = /obj/effect/projectile/stun/tracer - impact_type = /obj/effect/projectile/stun/impact + muzzle_type = /obj/effect/projectile/muzzle/stun + tracer_type = /obj/effect/projectile/tracer/stun + impact_type = /obj/effect/projectile/impact/stun /obj/item/projectile/beam/stun/weak name = "weak stun beam" diff --git a/code/modules/projectiles/projectile/beams_vr.dm b/code/modules/projectiles/projectile/beams_vr.dm index 5ba1fa56b2..b6ec5cbe0b 100644 --- a/code/modules/projectiles/projectile/beams_vr.dm +++ b/code/modules/projectiles/projectile/beams_vr.dm @@ -7,9 +7,9 @@ damage_type = HALLOSS light_color = "#00CECE" - muzzle_type = /obj/effect/projectile/laser_omni/muzzle - tracer_type = /obj/effect/projectile/laser_omni/tracer - impact_type = /obj/effect/projectile/laser_omni/impact + muzzle_type = /obj/effect/projectile/muzzle/laser_omni + tracer_type = /obj/effect/projectile/tracer/laser_omni + impact_type = /obj/effect/projectile/impact/laser_omni /obj/item/projectile/beam/stun agony = 35 @@ -22,9 +22,9 @@ damage_type = HALLOSS light_color = "#00CC33" - muzzle_type = /obj/effect/projectile/xray/muzzle - tracer_type = /obj/effect/projectile/xray/tracer - impact_type = /obj/effect/projectile/xray/impact + muzzle_type = /obj/effect/projectile/muzzle/xray + tracer_type = /obj/effect/projectile/tracer/xray + impact_type = /obj/effect/projectile/impact/xray /obj/item/projectile/beam/energy_net/on_hit(var/atom/netted) do_net(netted) @@ -38,6 +38,6 @@ icon_state = "bluelaser" light_color = "#0066FF" - muzzle_type = /obj/effect/projectile/laser_blue/muzzle - tracer_type = /obj/effect/projectile/laser_blue/tracer - impact_type = /obj/effect/projectile/laser_blue/impact + muzzle_type = /obj/effect/projectile/muzzle/laser_blue + tracer_type = /obj/effect/projectile/tracer/laser_blue + impact_type = /obj/effect/projectile/impact/laser_blue diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index ed16105939..8220e90eee 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -1,7 +1,7 @@ /obj/item/projectile/bullet name = "bullet" icon_state = "bullet" - fire_sound = 'sound/weapons/gunshot/gunshot_strong.ogg' + fire_sound = 'sound/weapons/Gunshot4.ogg' damage = 60 damage_type = BRUTE nodamage = 0 @@ -10,7 +10,7 @@ sharp = 1 var/mob_passthrough_check = 0 - muzzle_type = /obj/effect/projectile/bullet/muzzle + muzzle_type = /obj/effect/projectile/muzzle/bullet /obj/item/projectile/bullet/on_hit(var/atom/target, var/blocked = 0) if (..(target, blocked)) @@ -65,7 +65,7 @@ /* short-casing projectiles, like the kind used in pistols or SMGs */ /obj/item/projectile/bullet/pistol // 9mm pistols and most SMGs. Sacrifice power for capacity. - fire_sound = 'sound/weapons/gunshot/gunshot_pistol.ogg' // ToDo: Different shot sounds for different strength pistols. -Ace + fire_sound = 'sound/weapons/gunshot2.ogg' damage = 20 /obj/item/projectile/bullet/pistol/ap @@ -77,7 +77,7 @@ armor_penetration = -50 /obj/item/projectile/bullet/pistol/medium // .45 (and maybe .40 if it ever gets added) caliber security pistols. Balance between capacity and power. - // fire_sound = 'sound/weapons/gunshot3.ogg' // ToDo: Different shot sounds for different strength pistols. + fire_sound = 'sound/weapons/gunshot3.ogg' // Snappier sound. damage = 25 /obj/item/projectile/bullet/pistol/medium/ap @@ -89,11 +89,11 @@ armor_penetration = -50 /obj/item/projectile/bullet/pistol/strong // .357 and .44 caliber stuff. High power pistols like the Mateba or Desert Eagle. Sacrifice capacity for power. - fire_sound = 'sound/weapons/gunshot/gunshot_strong.ogg' // ToDo: Replace with something less ugly. I recommend weapons/gunshot3.ogg + fire_sound = 'sound/weapons/gunshot4.ogg' damage = 60 /obj/item/projectile/bullet/pistol/rubber/strong // "Rubber" bullets for high power pistols. - fire_sound = 'sound/weapons/gunshot/gunshot_strong.ogg' // ToDo: Same as above. + fire_sound = 'sound/weapons/gunshot3.ogg' // Rubber shots have less powder, but these still have more punch than normal rubber shot. damage = 10 agony = 60 embed_chance = 0 @@ -107,12 +107,13 @@ embed_chance = 0 sharp = 0 check_armour = "melee" + fire_sound ='sound/weapons/Gunshot_pathetic.ogg' // Rubber shots have less powder in the casing. /* shotgun projectiles */ /obj/item/projectile/bullet/shotgun name = "slug" - fire_sound = 'sound/weapons/gunshot/shotgun.ogg' + fire_sound = 'sound/weapons/Gunshot_shotgun.ogg' damage = 50 armor_penetration = 15 @@ -128,7 +129,7 @@ //Overall less damage than slugs in exchange for more damage at very close range and more embedding /obj/item/projectile/bullet/pellet/shotgun name = "shrapnel" - fire_sound = 'sound/weapons/gunshot/shotgun.ogg' + fire_sound = 'sound/weapons/Gunshot_shotgun.ogg' damage = 13 pellets = 6 range_step = 1 @@ -143,7 +144,7 @@ //EMP shotgun 'slug', it's basically a beanbag that pops a tiny emp when it hits. //Not currently used /obj/item/projectile/bullet/shotgun/ion name = "ion slug" - fire_sound = 'sound/weapons/Laser.ogg' + fire_sound = 'sound/weapons/Laser.ogg' // Really? We got nothing better than this? damage = 15 embed_chance = 0 sharp = 0 @@ -160,14 +161,18 @@ /* "Rifle" rounds */ /obj/item/projectile/bullet/rifle - fire_sound = 'sound/weapons/gunshot/gunshot3.ogg' + fire_sound = 'sound/weapons/Gunshot_generic_rifle.ogg' armor_penetration = 15 penetrating = 1 /obj/item/projectile/bullet/rifle/a762 - fire_sound = 'sound/weapons/gunshot/gunshot2.ogg' + fire_sound = 'sound/weapons/Gunshot_heavy.ogg' damage = 35 +/obj/item/projectile/bullet/rifle/a762/sniper // Hitscan specifically for sniper ammo; to be implimented at a later date, probably for the SVD. -Ace + fire_sound = 'sound/weapons/Gunshot_sniper.ogg' + hitscan = 1 //so the ammo isn't useless as a sniper weapon + /obj/item/projectile/bullet/rifle/a762/ap damage = 30 armor_penetration = 50 // At 30 or more armor, this will do more damage than standard rounds. @@ -177,12 +182,13 @@ armor_penetration = -50 penetrating = 0 -/obj/item/projectile/bullet/rifle/a762/hunter // Optimized for killing simple animals and not people, because Balance. +/obj/item/projectile/bullet/rifle/a762/hunter // Optimized for killing simple animals and not people, because Balance(tm) damage = 20 SA_bonus_damage = 50 // 70 total on animals. SA_vulnerability = SA_ANIMAL /obj/item/projectile/bullet/rifle/a545 + fire_sound = 'sound/weapons/Gunshot_light.ogg' damage = 25 /obj/item/projectile/bullet/rifle/a545/ap @@ -199,8 +205,8 @@ SA_bonus_damage = 35 // 50 total on animals. SA_vulnerability = SA_ANIMAL -/obj/item/projectile/bullet/rifle/a145 - fire_sound = 'sound/weapons/gunshot/sniper.ogg' +/obj/item/projectile/bullet/rifle/a145 // 14.5×114mm is bigger than a .50 BMG round. + fire_sound = 'sound/weapons/Gunshot_cannon.ogg' // This is literally an anti-tank rifle caliber. It better sound like a fucking cannon. damage = 80 stun = 3 weaken = 3 @@ -251,35 +257,22 @@ incendiary = 2 flammability = 4 agony = 30 - kill_count = 4 + range = 4 vacuum_traversal = 0 /obj/item/projectile/bullet/incendiary/flamethrower/large damage = 15 - kill_count = 6 + range = 6 -/obj/item/projectile/bullet/blank - invisibility = 101 - damage = 1 - embed_chance = 0 +/* Practice rounds and blanks */ -/* Practice */ - -/obj/item/projectile/bullet/pistol/practice +/obj/item/projectile/bullet/practice damage = 5 -/obj/item/projectile/bullet/rifle/practice - damage = 5 - penetrating = 0 - -/obj/item/projectile/bullet/shotgun/practice - name = "practice" - damage = 5 - -/obj/item/projectile/bullet/pistol/cap +/obj/item/projectile/bullet/pistol/cap // Just the primer, such as a cap gun. name = "cap" damage_type = HALLOSS - fire_sound = null + fire_sound = 'sound/effects/snap.ogg' damage = 0 nodamage = 1 embed_chance = 0 @@ -288,5 +281,18 @@ combustion = FALSE /obj/item/projectile/bullet/pistol/cap/process() + loc = null + qdel(src) + +/obj/item/projectile/bullet/blank + name = "blank" + damage_type = HALLOSS + fire_sound = 'sound/weapons/Gunshot_generic_rifle.ogg' // Blanks still make loud noises. + damage = 0 + nodamage = 1 + embed_chance = 0 + sharp = 0 + +/obj/item/projectile/bullet/blank/cap/process() loc = null qdel(src) \ No newline at end of file diff --git a/code/modules/projectiles/projectile/bullets_vr.dm b/code/modules/projectiles/projectile/bullets_vr.dm index 0d2595b6c3..adcdf465b5 100644 --- a/code/modules/projectiles/projectile/bullets_vr.dm +++ b/code/modules/projectiles/projectile/bullets_vr.dm @@ -9,7 +9,7 @@ name = "chemical shell" icon_state = "bullet" damage = 10 - kill_count = 15 //if the shell hasn't hit anything after travelling this far it just explodes. + range = 15 //if the shell hasn't hit anything after travelling this far it just explodes. flash_strength = 15 brightness = 15 diff --git a/code/modules/projectiles/projectile/change.dm b/code/modules/projectiles/projectile/change.dm index 0beffe46a3..df802f4bb5 100644 --- a/code/modules/projectiles/projectile/change.dm +++ b/code/modules/projectiles/projectile/change.dm @@ -54,7 +54,7 @@ Robot.mmi = new /obj/item/device/mmi(new_mob) Robot.mmi.transfer_identity(M) //Does not transfer key/client. if("slime") - new_mob = new /mob/living/simple_animal/slime(M.loc) + new_mob = new /mob/living/simple_mob/slime/xenobio(M.loc) new_mob.universal_speak = 1 else var/mob/living/carbon/human/H diff --git a/code/modules/projectiles/projectile/energy.dm b/code/modules/projectiles/projectile/energy.dm index bd97f64737..fcbc10f109 100644 --- a/code/modules/projectiles/projectile/energy.dm +++ b/code/modules/projectiles/projectile/energy.dm @@ -10,9 +10,9 @@ /obj/item/projectile/energy/flash name = "chemical shell" icon_state = "bullet" - fire_sound = 'sound/weapons/gunshot/gunshot_pistol.ogg' + fire_sound = 'sound/weapons/gunshot_pathetic.ogg' damage = 5 - kill_count = 15 //if the shell hasn't hit anything after travelling this far it just explodes. + range = 15 //if the shell hasn't hit anything after travelling this far it just explodes. var/flash_range = 0 var/brightness = 7 var/light_colour = "#ffffff" @@ -48,7 +48,7 @@ //blinds people like the flash round, but can also be used for temporary illumination /obj/item/projectile/energy/flash/flare - fire_sound = 'sound/weapons/gunshot/shotgun.ogg' + fire_sound = 'sound/weapons/grenade_launcher.ogg' damage = 10 flash_range = 1 brightness = 15 @@ -65,7 +65,7 @@ /obj/item/projectile/energy/electrode name = "electrode" icon_state = "spark" - fire_sound = 'sound/weapons/Gunshot.ogg' + fire_sound = 'sound/weapons/Gunshot2.ogg' taser_effect = 1 agony = 40 light_range = 2 @@ -123,6 +123,7 @@ damage_type = BURN agony = 10 check_armour = "bio" + armor_penetration = 25 // It's acid combustion = FALSE @@ -130,9 +131,10 @@ name = "neurotoxic spit" icon_state = "neurotoxin" damage = 5 - damage_type = TOX + damage_type = BIOACID agony = 80 check_armour = "bio" + armor_penetration = 25 // It's acid-based combustion = FALSE @@ -140,9 +142,10 @@ name = "neurotoxic spit" icon_state = "neurotoxin" damage = 20 - damage_type = TOX + damage_type = BIOACID agony = 20 check_armour = "bio" + armor_penetration = 25 // It's acid-based /obj/item/projectile/energy/phoron name = "phoron bolt" @@ -162,7 +165,7 @@ icon_state = "plasma_stun" fire_sound = 'sound/weapons/blaster.ogg' armor_penetration = 10 - kill_count = 4 + range = 4 damage = 5 agony = 55 damage_type = BURN @@ -209,25 +212,25 @@ light_color = "#0000FF" embed_chance = 0 - muzzle_type = /obj/effect/projectile/pulse/muzzle + muzzle_type = /obj/effect/projectile/muzzle/pulse /obj/item/projectile/energy/phase name = "phase wave" icon_state = "phase" - kill_count = 6 + range = 6 damage = 5 SA_bonus_damage = 45 // 50 total on animals SA_vulnerability = SA_ANIMAL /obj/item/projectile/energy/phase/light - kill_count = 4 + range = 4 SA_bonus_damage = 35 // 40 total on animals /obj/item/projectile/energy/phase/heavy - kill_count = 8 + range = 8 SA_bonus_damage = 55 // 60 total on animals /obj/item/projectile/energy/phase/heavy/cannon - kill_count = 10 + range = 10 damage = 15 SA_bonus_damage = 60 // 75 total on animals diff --git a/code/modules/projectiles/projectile/hook.dm b/code/modules/projectiles/projectile/hook.dm new file mode 100644 index 0000000000..ad02dee8cf --- /dev/null +++ b/code/modules/projectiles/projectile/hook.dm @@ -0,0 +1,193 @@ +/* + * File containing special 'hook' projectiles. Function is dictated by the launcher's intent. + */ + +/obj/item/projectile/energy/hook + name = "graviton sphere" + icon_state = "bluespace" + + var/beam_state = "b_beam" + + damage = 5 + speed = 2 + damage_type = BURN + check_armour = "energy" + armor_penetration = 15 + + var/impact_sound = 'sound/effects/uncloak.ogg' + var/crack_sound = 'sound/effects/teleport.ogg' + fire_sound = 'sound/effects/zzzt.ogg' + + var/target_distance = null // Shamelessly stolen from arcing projectiles. + var/my_tracking_beam = null // Beam made by the launcher. Tracked here to destroy it in time with the impact. + var/launcher_intent = null // Stores the launcher's intent. + + var/disarm_chance = 60 // Chance for a successful disarm hit. The inverse is a throw away from the firer. + + var/list/help_messages = list("slaps", "pokes", "nudges", "bumps", "pinches") + var/done_mob_unique = FALSE // Has the projectile already done something to a mob? + +/obj/item/projectile/energy/hook/launch_projectile(atom/target, target_zone, mob/user, params, angle_override, forced_spread = 0) + var/expected_distance = get_dist(target, loc) + range = expected_distance // So the hook hits the ground if no mob is hit. + target_distance = expected_distance + if(firer) // Needed to ensure later checks in impact and on hit function. + launcher_intent = firer.a_intent + firer.Beam(src,icon_state=beam_state,icon='icons/effects/beam.dmi',time=60, maxdistance=10,beam_type=/obj/effect/ebeam,beam_sleep_time=1) + + if(launcher_intent) + switch(launcher_intent) + if(I_HURT) + check_armour = "bullet" + damage *= 3 + sharp = 1 + agony = 20 + if(I_GRAB) + check_armour = "melee" + damage_type = HALLOSS + if(I_DISARM) + check_armour = "melee" + if(prob(30)) // A chance for a successful hit to either knock someone down, or cause minor disorientation. + weaken = 1 + else + stun = 2 + eyeblur = 3 + if(I_HELP) + silenced = 1 + damage_type = HALLOSS + + ..() // Does the regular launching stuff. + +/obj/item/projectile/energy/hook/on_hit(var/atom/target, var/blocked = 0, var/def_zone = null) + if(..()) + perform_intent_unique(target) + +/obj/item/projectile/energy/hook/on_impact(var/atom/A) + perform_intent_unique(get_turf(A)) + +/obj/item/projectile/energy/hook/proc/ranged_disarm(var/mob/living/carbon/human/H) + if(istype(H)) + var/list/holding = list(H.get_active_hand() = 60, H.get_inactive_hand() = 40) + + for(var/obj/item/weapon/gun/W in holding) // Guns are complex devices, both of a mechanical and electronic nature. A weird gravity ball or other type of object trying to pull or grab it is likely not safe. + if(W && prob(holding[W])) + var/list/turfs = list() + for(var/turf/T in view()) + turfs += T + if(turfs.len) + var/turf/target = pick(turfs) + visible_message("[H]'s [W] goes off due to \the [src]!") + return W.afterattack(target,H) + + if(!(H.species.flags & NO_SLIP) && prob(50)) + var/armor_check = H.run_armor_check(def_zone, "melee") + H.apply_effect(3, WEAKEN, armor_check) + playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + if(armor_check < 60) + visible_message("\The [src] has pushed [H]!") + else + visible_message("\The [src] attempted to push [H]!") + return + + else + if(H.break_all_grabs(firer)) + playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + return + + for(var/obj/item/I in holding) + if(I) + H.drop_from_inventory(I) + visible_message("\The [src] has disarmed [H]!") + playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + return + + +/obj/item/projectile/energy/hook/proc/perform_intent_unique(atom/target) + playsound(src.loc, impact_sound, 40, 1) + var/success = FALSE + if(istype(target,/turf)) + if(launcher_intent) + if(launcher_intent != I_HELP && !done_mob_unique) + var/target_mob = pick(/mob/living in target.contents) + + if(!target_mob) + return + + if(Bump(target_mob, forced=1)) //If we hit a turf, try to force an interaction with a mob on the turf. + done_mob_unique = TRUE + success = TRUE + else if(firer) + var/obj/T + + if(original in target.contents && istype(original, /obj)) + T = original + + var/list/possible_targets = list() + for(var/obj/item/I in target.contents) + if(!I.anchored) + possible_targets += I + for(var/obj/structure/S in target.contents) + if(!S.anchored) + possible_targets += S + + if(!T) + if(!possible_targets || !possible_targets.len) + return + T = pick(possible_targets) + + spawn(2) + playsound(target, crack_sound, 40, 1) + visible_message("\The [T] is snatched by \the [src]!") + T.throw_at(get_turf(firer), 7, 1, src) + success = TRUE + else if(isliving(target) && !done_mob_unique) + var/mob/living/L = target + if(launcher_intent) + switch(launcher_intent) + if(I_HELP) + var/message = pick(help_messages) + if(message == "slaps") + spawn(1) + playsound(loc, 'sound/effects/snap.ogg', 50, 1) + visible_message("\The [src] [message] [target].") + done_mob_unique = TRUE + success = TRUE + if(I_HURT) + if(prob(10) && istype(L, /mob/living/carbon/human)) + to_chat(L, "\The [src] rips at your hands!") + ranged_disarm(L) + success = TRUE + done_mob_unique = TRUE + if(I_DISARM) + if(prob(disarm_chance) && istype(L, /mob/living/carbon/human)) + ranged_disarm(L) + else + L.visible_message("\The [src] sends \the [L] stumbling backwards.") + L.throw_at(get_turf(get_step(L,get_dir(firer,L))), 1, 1, src) + done_mob_unique = TRUE + success = TRUE + if(I_GRAB) + var/turf/STurf = get_turf(L) + spawn(2) + playsound(STurf, crack_sound, 60, 1) + L.visible_message("\The [src] rips [L] towards \the [firer]!") + L.throw_at(get_turf(get_step(firer,get_dir(firer,L))), 6, 1, src) + done_mob_unique = TRUE + success = TRUE + else if(istype(target, /obj/structure)) + var/obj/structure/S = target + if(!S.anchored) + S.throw_at(get_turf(get_step(firer,get_dir(firer,S))), 4, 1, src) + success = TRUE + qdel(my_tracking_beam) + return success + +/* + * Hook subtypes. + */ + +/obj/item/projectile/energy/hook/ring + name = "green orb" + icon_state = "green_laser" + beam_state = "n_beam" + damage = 3 diff --git a/code/modules/projectiles/projectile/magnetic.dm b/code/modules/projectiles/projectile/magnetic.dm index ed16ea208d..8185fb127e 100644 --- a/code/modules/projectiles/projectile/magnetic.dm +++ b/code/modules/projectiles/projectile/magnetic.dm @@ -34,7 +34,7 @@ penetrating = 2 embed_chance = 0 armor_penetration = 40 - kill_count = 20 + range = 20 var/searing = 0 //Does this fuelrod ignore shields? var/detonate_travel = 0 //Will this fuelrod explode when it reaches maximum distance? @@ -50,7 +50,7 @@ if(energetic_impact) var/eye_coverage = 0 - for(var/mob/living/carbon/M in viewers(world.view, location)) + for(var/mob/living/carbon/M in viewers(world.view, get_turf(src))) eye_coverage = 0 if(iscarbon(M)) eye_coverage = M.eyecheck() @@ -103,7 +103,7 @@ armor_penetration = 100 penetrating = 100 //Theoretically, this shouldn't stop flying for a while, unless someone lines it up with a wall or fires it into a mountain. irradiate = 120 - kill_count = 75 + range = 75 searing = 1 detonate_travel = 1 detonate_mob = 1 @@ -116,4 +116,29 @@ return ..(target, blocked, def_zone) /obj/item/projectile/bullet/magnetic/fuelrod/supermatter/check_penetrate() - return 1 \ No newline at end of file + return 1 + +/obj/item/projectile/bullet/magnetic/bore + name = "phorogenic blast" + icon_state = "purpleemitter" + damage = 20 + incendiary = 1 + armor_penetration = 20 + penetrating = 0 + check_armour = "melee" + irradiate = 20 + range = 6 + +/obj/item/projectile/bullet/magnetic/bore/Bump(atom/A, forced=0) + if(istype(A, /turf/simulated/mineral)) + var/turf/simulated/mineral/MI = A + loc = get_turf(A) // Careful. + permutated.Add(A) + MI.GetDrilled(TRUE) + return 0 + else if(istype(A, /turf/simulated/wall) || istype(A, /turf/simulated/shuttle/wall)) // Cause a loud, but relatively minor explosion on the wall it hits. + explosion(A, -1, -1, 1, 3) + qdel(src) + return 1 + else + ..() diff --git a/code/modules/projectiles/projectile/pellets.dm b/code/modules/projectiles/projectile/pellets.dm index 9b7ee244e3..306ab81268 100644 --- a/code/modules/projectiles/projectile/pellets.dm +++ b/code/modules/projectiles/projectile/pellets.dm @@ -9,10 +9,6 @@ var/base_spread = 90 //lower means the pellets spread more across body parts. If zero then this is considered a shrapnel explosion instead of a shrapnel cone var/spread_step = 10 //higher means the pellets spread more across body parts with distance -/obj/item/projectile/bullet/pellet/Bumped() - . = ..() - bumped = 0 //can hit all mobs in a tile. pellets is decremented inside attack_mob so this should be fine. - /obj/item/projectile/bullet/pellet/proc/get_pellets(var/distance) var/pellet_loss = round((distance - 1)/range_step) //pellets lost due to distance return max(pellets - pellet_loss, 1) diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm index 2e27d125ef..705a817236 100644 --- a/code/modules/projectiles/projectile/special.dm +++ b/code/modules/projectiles/projectile/special.dm @@ -219,7 +219,7 @@ embed_chance = 0 // nope nodamage = 1 damage_type = HALLOSS - muzzle_type = /obj/effect/projectile/bullet/muzzle + muzzle_type = /obj/effect/projectile/muzzle/bullet /obj/item/projectile/bola name = "bola" @@ -257,3 +257,82 @@ visible_message("\The [src] splatters a layer of web on \the [target]!") new /obj/effect/spider/stickyweb(target.loc) ..() + +/obj/item/projectile/beam/tungsten + name = "core of molten tungsten" + icon_state = "energy" + fire_sound = 'sound/weapons/gauss_shoot.ogg' + pass_flags = PASSTABLE | PASSGRILLE + damage = 70 + damage_type = BURN + check_armour = "laser" + light_range = 4 + light_power = 3 + light_color = "#3300ff" + + muzzle_type = /obj/effect/projectile/tungsten/muzzle + tracer_type = /obj/effect/projectile/tungsten/tracer + impact_type = /obj/effect/projectile/tungsten/impact + +/obj/item/projectile/beam/tungsten/on_hit(var/atom/target, var/blocked = 0) + if(isliving(target)) + var/mob/living/L = target + L.add_modifier(/datum/modifier/grievous_wounds, 30 SECONDS) + if(ishuman(L)) + var/mob/living/carbon/human/H = L + + var/target_armor = H.getarmor(def_zone, check_armour) + var/obj/item/organ/external/target_limb = H.get_organ(def_zone) + + var/armor_special = 0 + + if(target_armor >= 60) + var/turf/T = get_step(H, pick(alldirs - src.dir)) + H.throw_at(T, 1, 1, src) + H.apply_damage(20, BURN, def_zone) + if(target_limb) + armor_special = 2 + target_limb.fracture() + + else if(target_armor >= 45) + H.apply_damage(15, BURN, def_zone) + if(target_limb) + armor_special = 1 + target_limb.dislocate() + + else if(target_armor >= 30) + H.apply_damage(10, BURN, def_zone) + if(prob(30) && target_limb) + armor_special = 1 + target_limb.dislocate() + + else if(target_armor >= 15) + H.apply_damage(5, BURN, def_zone) + if(prob(15) && target_limb) + armor_special = 1 + target_limb.dislocate() + + if(armor_special > 1) + target.visible_message("\The [src] slams into \the [target]'s [target_limb], reverberating loudly!") + + else if(armor_special) + target.visible_message("\The [src] slams into \the [target]'s [target_limb] with a low rumble!") + + ..() + +/obj/item/projectile/beam/tungsten/on_impact(var/atom/A) + if(istype(A,/turf/simulated/shuttle/wall) || istype(A,/turf/simulated/wall) || (istype(A,/turf/simulated/mineral) && A.density) || istype(A,/obj/mecha) || istype(A,/obj/machinery/door)) + var/blast_dir = src.dir + A.visible_message("\The [A] begins to glow!") + spawn(2 SECONDS) + var/blastloc = get_step(A, blast_dir) + if(blastloc) + explosion(blastloc, -1, -1, 2, 3) + ..() + +/obj/item/projectile/beam/tungsten/Bump(atom/A, forced=0) + if(istype(A, /obj/structure/window)) //It does not pass through windows. It pulverizes them. + var/obj/structure/window/W = A + W.shatter() + return 0 + ..() diff --git a/code/modules/projectiles/projectile/trace.dm b/code/modules/projectiles/projectile/trace.dm new file mode 100644 index 0000000000..3052d11ab7 --- /dev/null +++ b/code/modules/projectiles/projectile/trace.dm @@ -0,0 +1,38 @@ +//Helper proc to check if you can hit them or not. +/proc/check_trajectory(atom/target as mob|obj, atom/firer as mob|obj, var/pass_flags=PASSTABLE|PASSGLASS|PASSGRILLE, flags=null) + if(!istype(target) || !istype(firer)) + return 0 + + var/obj/item/projectile/test/trace = new /obj/item/projectile/test(get_turf(firer)) //Making the test.... + + //Set the flags and pass flags to that of the real projectile... + if(!isnull(flags)) + trace.flags = flags + trace.pass_flags = pass_flags + + return trace.launch_projectile(target) //Test it! + +/obj/item/projectile/proc/_check_fire(atom/target as mob, var/mob/living/user as mob) //Checks if you can hit them or not. + check_trajectory(target, user, pass_flags, flags) + +//"Tracing" projectile +/obj/item/projectile/test //Used to see if you can hit them. + invisibility = 101 //Nope! Can't see me! + hitscan = TRUE + nodamage = TRUE + damage = 0 + var/list/hit = list() + +/obj/item/projectile/test/process_hitscan() + . = ..() + if(!QDELING(src)) + qdel(src) + return hit + +/obj/item/projectile/test/Bump(atom/A) + if(A != src) + hit |= A + return ..() + +/obj/item/projectile/test/attack_mob() + return diff --git a/code/modules/projectiles/targeting/targeting_overlay.dm b/code/modules/projectiles/targeting/targeting_overlay.dm index 76d1804265..b20720c125 100644 --- a/code/modules/projectiles/targeting/targeting_overlay.dm +++ b/code/modules/projectiles/targeting/targeting_overlay.dm @@ -89,7 +89,7 @@ aiming_at = null owner = null aiming_with = null - processing_objects -= src + STOP_PROCESSING(SSobj, src) return ..() obj/aiming_overlay/proc/update_aiming_deferred() @@ -176,7 +176,7 @@ obj/aiming_overlay/proc/update_aiming_deferred() if(istype(aiming_with, /obj/item/weapon/gun)) playsound(get_turf(owner), 'sound/weapons/TargetOn.ogg', 50,1) forceMove(get_turf(target)) - processing_objects |= src + START_PROCESSING(SSobj, src) aiming_at.aimed |= src toggle_active(1) @@ -222,5 +222,5 @@ obj/aiming_overlay/proc/update_aiming_deferred() aiming_at.aimed -= src aiming_at = null loc = null - processing_objects -= src + STOP_PROCESSING(SSobj, src) diff --git a/code/modules/random_map/drop/droppod.dm b/code/modules/random_map/drop/droppod.dm index da346d2eb7..1d5fcb8d8f 100644 --- a/code/modules/random_map/drop/droppod.dm +++ b/code/modules/random_map/drop/droppod.dm @@ -15,7 +15,7 @@ floor_type = /turf/simulated/floor/reinforced var/list/supplied_drop_types = list() var/door_type = /obj/structure/droppod_door - var/drop_type = /mob/living/simple_animal/parrot + var/drop_type = /mob/living/simple_mob/animal/passive/bird/parrot var/auto_open_doors var/placement_explosion_dev = 1 @@ -172,7 +172,7 @@ spawned_mobs |= M else var/list/candidates = list() - for(var/client/player in clients) + for(var/client/player in GLOB.clients) if(player.mob && istype(player.mob, /mob/observer/dead)) candidates |= player diff --git a/code/modules/random_map/noise/desert.dm b/code/modules/random_map/noise/desert.dm index 1c7ca229a4..0264d2a781 100644 --- a/code/modules/random_map/noise/desert.dm +++ b/code/modules/random_map/noise/desert.dm @@ -27,7 +27,7 @@ var/grass_path = pick(typesof(/obj/structure/flora/grass)-/obj/structure/flora/grass) new grass_path(T) if(prob(5)) - var/mob_type = pick(list(/mob/living/simple_animal/lizard, /mob/living/simple_animal/mouse)) + var/mob_type = pick(list(/mob/living/simple_mob/animal/passive/lizard, /mob/living/simple_mob/animal/passive/mouse)) new mob_type(T) if(5 to 6) if(prob(20)) diff --git a/code/modules/random_map/noise/noise.dm b/code/modules/random_map/noise/noise.dm index 7e4323158e..8e45a21c3f 100644 --- a/code/modules/random_map/noise/noise.dm +++ b/code/modules/random_map/noise/noise.dm @@ -19,10 +19,10 @@ /datum/random_map/noise/set_map_size() // Make sure the grid is a square with limits that are // (n^2)+1, otherwise diamond-square won't work. - if(!IsPowerOfTwo((limit_x-1))) - limit_x = RoundUpToPowerOfTwo(limit_x) + 1 - if(!IsPowerOfTwo((limit_y-1))) - limit_y = RoundUpToPowerOfTwo(limit_y) + 1 + if(!ISPOWEROFTWO((limit_x-1))) + limit_x = ROUNDUPTOPOWEROFTWO(limit_x) + 1 + if(!ISPOWEROFTWO((limit_y-1))) + limit_y = ROUNDUPTOPOWEROFTWO(limit_y) + 1 // Sides must be identical lengths. if(limit_x > limit_y) limit_y = limit_x diff --git a/code/modules/random_map/noise/tundra.dm b/code/modules/random_map/noise/tundra.dm index 83b7435e40..6cb8114298 100644 --- a/code/modules/random_map/noise/tundra.dm +++ b/code/modules/random_map/noise/tundra.dm @@ -46,13 +46,13 @@ switch(val) if(2) if(prob(5)) - new /mob/living/simple_animal/crab(T) + new /mob/living/simple_mob/animal/passive/crab(T) if(6) if(prob(60)) var/grass_path = pick(typesof(/obj/structure/flora/grass)-/obj/structure/flora/grass) new grass_path(T) if(prob(5)) - var/mob_type = pick(list(/mob/living/simple_animal/lizard, /mob/living/simple_animal/mouse)) + var/mob_type = pick(list(/mob/living/simple_mob/animal/passive/lizard, /mob/living/simple_mob/animal/passive/mouse)) new mob_type(T) if(7) if(prob(60)) diff --git a/code/modules/reagents/Chemistry-Holder.dm b/code/modules/reagents/Chemistry-Holder.dm index ab83fbe8a0..2d906381d1 100644 --- a/code/modules/reagents/Chemistry-Holder.dm +++ b/code/modules/reagents/Chemistry-Holder.dm @@ -12,27 +12,24 @@ my_atom = A //I dislike having these here but map-objects are initialised before world/New() is called. >_> - if(!chemical_reagents_list) + if(!SSchemistry.chemical_reagents) //Chemical Reagents - Initialises all /datum/reagent into a list indexed by reagent id var/paths = typesof(/datum/reagent) - /datum/reagent - chemical_reagents_list = list() + SSchemistry.chemical_reagents = list() for(var/path in paths) var/datum/reagent/D = new path() if(!D.name) continue - chemical_reagents_list[D.id] = D + SSchemistry.chemical_reagents[D.id] = D /datum/reagents/Destroy() - . = ..() - if(chemistryProcess) - chemistryProcess.active_holders -= src - + STOP_PROCESSING(SSchemistry, src) for(var/datum/reagent/R in reagent_list) qdel(R) - reagent_list.Cut() reagent_list = null if(my_atom && my_atom.reagents == src) my_atom.reagents = null + return ..() /* Internal procs */ @@ -80,17 +77,14 @@ return /datum/reagents/proc/handle_reactions() - if(chemistryProcess) - chemistryProcess.mark_for_update(src) + START_PROCESSING(SSchemistry, src) //returns 1 if the holder should continue reactiong, 0 otherwise. -/datum/reagents/proc/process_reactions() - if(!my_atom) // No reactions in temporary holders - return 0 - if(!my_atom.loc) //No reactions inside GC'd containers - return 0 +/datum/reagents/process() + if(QDELETED(my_atom)) //No container, no reaction. + return PROCESS_KILL if(my_atom.flags & NOREACT) // No reactions here - return 0 + return PROCESS_KILL var/reaction_occured var/list/effect_reactions = list() @@ -100,7 +94,7 @@ //need to rebuild this to account for chain reactions for(var/datum/reagent/R in reagent_list) - eligible_reactions |= chemical_reactions_list[R.id] + eligible_reactions |= SSchemistry.chemical_reactions[R.id] for(var/datum/chemical_reaction/C in eligible_reactions) if(C.can_happen(src) && C.process(src)) @@ -116,7 +110,8 @@ C.post_reaction(src) update_total() - return reaction_occured + if(!reaction_occured) + return PROCESS_KILL /* Holder-to-chemical */ @@ -138,7 +133,7 @@ if(my_atom) my_atom.on_reagent_change() return 1 - var/datum/reagent/D = chemical_reagents_list[id] + var/datum/reagent/D = SSchemistry.chemical_reagents[id] if(D) var/datum/reagent/R = new D.type() reagent_list += R @@ -152,7 +147,7 @@ my_atom.on_reagent_change() return 1 else - warning("[my_atom] attempted to add a reagent called '[id]' which doesn't exist. ([usr])") + crash_with("[my_atom] attempted to add a reagent called '[id]' which doesn't exist. ([usr])") return 0 /datum/reagents/proc/remove_reagent(var/id, var/amount, var/safety = 0) diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm index 141263e2d3..3913066001 100644 --- a/code/modules/reagents/Chemistry-Machinery.dm +++ b/code/modules/reagents/Chemistry-Machinery.dm @@ -32,7 +32,7 @@ /obj/machinery/chem_master/New() ..() - var/datum/reagents/R = new/datum/reagents(900) //Just a huge random number so the buffer should (probably) never dump your reagents. + var/datum/reagents/R = new/datum/reagents(900) //Just a huge random number so the buffer should (probably) never dump your reagents. reagents = R //There should be a nano ui thingy to warn of this. R.my_atom = src @@ -134,7 +134,7 @@ data["bottleSpritesAmount"] = list(1, 2, 3, 4) //how many bottle sprites there are. Sprites are taken from chemical.dmi and can be found in nano/images/pill.png - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "chem_master.tmpl", src.name, 575, 400) ui.set_initial_data(data) @@ -177,21 +177,21 @@ if(href_list["amount"]) var/id = href_list["add"] - var/amount = Clamp((text2num(href_list["amount"])), 0, 200) + var/amount = CLAMP((text2num(href_list["amount"])), 0, 200) R.trans_id_to(src, id, amount) else if (href_list["addcustom"]) var/id = href_list["addcustom"] useramount = input("Select the amount to transfer.", 30, useramount) as num - useramount = Clamp(useramount, 0, 200) + useramount = CLAMP(useramount, 0, 200) src.Topic(null, list("amount" = "[useramount]", "add" = "[id]")) else if (href_list["remove"]) if(href_list["amount"]) var/id = href_list["remove"] - var/amount = Clamp((text2num(href_list["amount"])), 0, 200) + var/amount = CLAMP((text2num(href_list["amount"])), 0, 200) if(mode) reagents.trans_id_to(beaker, id, amount) else @@ -202,7 +202,7 @@ var/id = href_list["removecustom"] useramount = input("Select the amount to transfer.", 30, useramount) as num - useramount = Clamp(useramount, 0, 200) + useramount = CLAMP(useramount, 0, 200) src.Topic(null, list("amount" = "[useramount]", "remove" = "[id]")) else if (href_list["toggle"]) @@ -224,7 +224,7 @@ count = input("Select the number of pills to make.", "Max [max_pill_count]", pillamount) as null|num if(!count) //Covers 0 and cancel return - count = Clamp(count, 1, max_pill_count) + count = CLAMP(count, 1, max_pill_count) if(reagents.total_volume/count < 1) //Sanity checking. return @@ -282,7 +282,7 @@ else if(href_list["bottle_sprite"]) bottlesprite = href_list["bottle_sprite"] - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) /obj/machinery/chem_master/attack_ai(mob/user as mob) return src.attack_hand(user) @@ -550,3 +550,65 @@ qdel(O) if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) break + + +/////////////// +/////////////// +// Detects reagents inside most containers, and acts as an infinite identification system for reagent-based unidentified objects. + +/obj/machinery/chemical_analyzer + name = "chem analyzer" + desc = "Used to precisely scan chemicals and other liquids inside various containers. \ + It may also identify the liquid contents of unknown objects." + description_info = "This machine will try to tell you what reagents are inside of something capable of holding reagents. \ + It is also used to 'identify' specific reagent-based objects with their properties obscured from inspection by normal means." + icon = 'icons/obj/chemical.dmi' + icon_state = "chem_analyzer" + density = TRUE + anchored = TRUE + use_power = TRUE + idle_power_usage = 20 + clicksound = "button" + var/analyzing = FALSE + +/obj/machinery/chemical_analyzer/update_icon() + icon_state = "chem_analyzer[analyzing ? "-working":""]" + +/obj/machinery/chemical_analyzer/attackby(obj/item/I, mob/living/user) + if(!istype(I)) + return ..() + + if(default_deconstruction_screwdriver(user, I)) + return + if(default_deconstruction_crowbar(user, I)) + return + + if(istype(I,/obj/item/weapon/reagent_containers)) + analyzing = TRUE + update_icon() + to_chat(user, span("notice", "Analyzing \the [I], please stand by...")) + + if(!do_after(user, 2 SECONDS, src)) + to_chat(user, span("warning", "Sample moved outside of scan range, please try again and remain still.")) + analyzing = FALSE + update_icon() + return + + // First, identify it if it isn't already. + if(!I.is_identified(IDENTITY_FULL)) + var/datum/identification/ID = I.identity + if(ID.identification_type == IDENTITY_TYPE_CHEMICAL) // This only solves chemical-based mysteries. + I.identify(IDENTITY_FULL, user) + + // Now tell us everything that is inside. + if(I.reagents && I.reagents.reagent_list.len) + to_chat(user, "
      ") // To add padding between regular chat and the output. + for(var/datum/reagent/R in I.reagents.reagent_list) + if(!R.name) + continue + to_chat(user, span("notice", "Contains [R.volume]u of [R.name].
      [R.description]
      ")) + + to_chat(user, span("notice", "Scanning of \the [I] complete.")) + analyzing = FALSE + update_icon() + return \ No newline at end of file diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm index ce7227ce46..21775ea17e 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents.dm @@ -1,13 +1,4 @@ -//Chemical Reagents - Initialises all /datum/reagent into a list indexed by reagent id -/proc/initialize_chemical_reagents() - var/paths = typesof(/datum/reagent) - /datum/reagent - chemical_reagents_list = list() - for(var/path in paths) - var/datum/reagent/D = new path() - if(!D.name) - continue - chemical_reagents_list[D.id] = D /datum/reagent diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm index a32f83f794..cbe7dd9c5b 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm @@ -169,8 +169,8 @@ /datum/reagent/water/touch_mob(var/mob/living/L, var/amount) if(istype(L)) // First, kill slimes. - if(istype(L, /mob/living/simple_animal/slime)) - var/mob/living/simple_animal/slime/S = L + if(istype(L, /mob/living/simple_mob/slime)) + var/mob/living/simple_mob/slime/S = L S.adjustToxLoss(15 * amount) S.visible_message("[S]'s flesh sizzles where the water touches it!", "Your flesh burns in the water!") diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm index a7bcd87892..754f7c05eb 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm @@ -305,8 +305,6 @@ M.bodytemperature = max(M.bodytemperature - 10 * TEMPERATURE_DAMAGE_COEFFICIENT, 215) if(prob(1)) M.emote("shiver") - if(istype(M, /mob/living/simple_animal/slime)) - M.bodytemperature = max(M.bodytemperature - rand(10,20), 0) holder.remove_reagent("capsaicin", 5) /datum/reagent/frostoil/cryotoxin //A longer lasting version of frost oil. @@ -346,8 +344,6 @@ M.apply_effect(2, AGONY, 0) if(prob(5)) M.visible_message("[M] [pick("dry heaves!","coughs!","splutters!")]", "You feel like your insides are burning!") - if(istype(M, /mob/living/simple_animal/slime)) - M.bodytemperature += rand(10, 25) holder.remove_reagent("frostoil", 5) /datum/reagent/condensedcapsaicin @@ -492,8 +488,6 @@ M.apply_effect(4, AGONY, 0) if(prob(5)) M.visible_message("[M] [pick("dry heaves!","coughs!","splutters!")]", "You feel like your insides are burning!") - if(istype(M, /mob/living/simple_animal/slime)) - M.bodytemperature += rand(15, 30) holder.remove_reagent("frostoil", 5) /* Drinks */ @@ -1491,7 +1485,7 @@ id = "lovepotion" description = "Creamy strawberries and sugar, simple and sweet." taste_description = "strawberries and cream" - color = "#fc8a8a" // rrgb(252, 138, 138) + color = "#fc8a8a" // rgb(252, 138, 138) glass_name = "Love Potion" glass_desc = "Love me tender, love me sweet." @@ -1508,6 +1502,16 @@ glass_desc = "A concoction that should probably be in an engine, rather than your stomach." glass_icon = DRINK_ICON_NOISY +/datum/reagent/drink/eggnog + name = "Eggnog" + id = "eggnog" + description = "A creamy, rich beverage made out of whisked eggs, milk and sugar, for when you feel like celebrating the winter holidays." + taste_description = "thick cream and vanilla" + color = "#fff3c1" // rgb(255, 243, 193) + + glass_name = "Eggnog" + glass_desc = "You can't egg-nore the holiday cheer all around you" + /datum/reagent/drink/nuclearwaste name = "Nuclear Waste" id = "nuclearwaste" @@ -2668,7 +2672,7 @@ /datum/reagent/ethanol/saketini name = "Saketini" - id = "sakitini" + id = "saketini" description = "For when you're too weeb for a real martini." taste_description = "dry alcohol" color = "#0064C8" diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm index 6b705f4f54..9cf58bbfb8 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm @@ -106,6 +106,8 @@ M.drowsyness = max(0, M.drowsyness - 6 * removed * chem_effective) M.hallucination = max(0, M.hallucination - 9 * removed * chem_effective) M.adjustToxLoss(-4 * removed * chem_effective) + if(prob(10)) + M.remove_a_modifier_of_type(/datum/modifier/poisoned) /datum/reagent/carthatoline name = "Carthatoline" @@ -121,6 +123,8 @@ if(M.getToxLoss() && prob(10)) M.vomit(1) M.adjustToxLoss(-8 * removed) + if(prob(30)) + M.remove_a_modifier_of_type(/datum/modifier/poisoned) if(ishuman(M)) var/mob/living/carbon/human/H = M var/obj/item/organ/internal/liver/L = H.internal_organs_by_name[O_LIVER] diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm index 53ce37b3ef..954102b732 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm @@ -360,7 +360,7 @@ S.dirt = 0 T.clean_blood() - for(var/mob/living/simple_animal/slime/M in T) + for(var/mob/living/simple_mob/slime/M in T) M.adjustToxLoss(rand(5, 10)) /datum/reagent/space_cleaner/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) @@ -489,4 +489,21 @@ description = "A slurry of compounds that contains the basic requirements for life." taste_description = "salty meat" reagent_state = LIQUID - color = "#DF9FBF" \ No newline at end of file + color = "#DF9FBF" + +// The opposite to healing nanites, exists to make unidentified hypos implied to have nanites not be 100% safe. +/datum/reagent/defective_nanites + name = "Defective Nanites" + id = "defective_nanites" + description = "Miniature medical robots that are malfunctioning and cause bodily harm. Fortunately, they cannot self-replicate." + taste_description = "metal" + reagent_state = SOLID + color = "#333333" + metabolism = REM * 3 // Broken nanomachines go a bit slower. + scannable = 1 + +/datum/reagent/defective_nanites/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + M.take_organ_damage(2 * removed, 2 * removed) + M.adjustOxyLoss(4 * removed) + M.adjustToxLoss(2 * removed) + M.adjustCloneLoss(2 * removed) \ No newline at end of file diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm index e3c087b5fa..1ec5e6e334 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm @@ -70,7 +70,7 @@ /datum/reagent/toxin/hydrophoron/touch_turf(var/turf/simulated/T) if(!istype(T)) return - T.assume_gas("phoron", ceil(volume/2), T20C) + T.assume_gas("phoron", CEILING(volume/2, 1), T20C) for(var/turf/simulated/floor/target_tile in range(0,T)) target_tile.assume_gas("phoron", volume/2, 400+T0C) spawn (0) target_tile.hotspot_expose(700, 400) @@ -155,10 +155,26 @@ /datum/reagent/toxin/mold/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) ..() - M.adjustToxLoss(strength * removed) if(prob(5)) M.vomit() +/datum/reagent/toxin/expired_medicine + name = "Expired Medicine" + id = "expired_medicine" + description = "Some form of liquid medicine that is well beyond its shelf date. Administering it now would cause illness." + taste_description = "bitterness" + reagent_state = LIQUID + strength = 5 + +/datum/reagent/toxin/expired_medicine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + ..() + if(prob(5)) + M.vomit() + +/datum/reagent/toxin/expired_medicine/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) + affect_blood(M, alien, removed * 0.66) + + /datum/reagent/toxin/stimm //Homemade Hyperzine name = "Stimm" id = "stimm" diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm index b351dc290d..a822ae3555 100644 --- a/code/modules/reagents/Chemistry-Recipes.dm +++ b/code/modules/reagents/Chemistry-Recipes.dm @@ -1,22 +1,3 @@ - -//Chemical Reactions - Initialises all /datum/chemical_reaction into a list -// It is filtered into multiple lists within a list. -// For example: -// chemical_reaction_list["phoron"] is a list of all reactions relating to phoron -// Note that entries in the list are NOT duplicated. So if a reaction pertains to -// more than one chemical it will still only appear in only one of the sublists. -/proc/initialize_chemical_reactions() - var/paths = typesof(/datum/chemical_reaction) - /datum/chemical_reaction - chemical_reactions_list = list() - - for(var/path in paths) - var/datum/chemical_reaction/D = new path() - if(D.required_reagents && D.required_reagents.len) - var/reagent_id = D.required_reagents[1] - if(!chemical_reactions_list[reagent_id]) - chemical_reactions_list[reagent_id] = list() - chemical_reactions_list[reagent_id] += D - //helper that ensures the reaction rate holds after iterating //Ex. REACTION_RATE(0.3) means that 30% of the reagents will react each chemistry tick (~2 seconds by default). #define REACTION_RATE(rate) (1.0 - (1.0-rate)**(1.0/PROCESS_REACTION_ITER)) @@ -96,7 +77,7 @@ return progress -/datum/chemical_reaction/proc/process(var/datum/reagents/holder) +/datum/chemical_reaction/process(var/datum/reagents/holder) //determine how far the reaction can proceed var/list/reaction_limits = list() for(var/reactant in required_reagents) @@ -2268,6 +2249,13 @@ required_reagents = list("cornoil" = 2, "honey" = 1) result_amount = 3 +/datum/chemical_reaction/drinks/eggnog + name = "Eggnog" + id = "eggnog" + result = "eggnog" + required_reagents = list("milk" = 5, "cream" = 5, "sugar" = 5, "egg" = 3) + result_amount = 15 + /datum/chemical_reaction/drinks/nuclearwaste_radium name = "Nuclear Waste" id = "nuclearwasterad" diff --git a/code/modules/reagents/Chemistry-Recipes_vr.dm b/code/modules/reagents/Chemistry-Recipes_vr.dm index 58f49f3fc7..6701c87b35 100644 --- a/code/modules/reagents/Chemistry-Recipes_vr.dm +++ b/code/modules/reagents/Chemistry-Recipes_vr.dm @@ -309,7 +309,7 @@ - +/* //VORESTATION AI TEMPORARY REMOVAL /datum/chemical_reaction/slimevore name = "Slime Vore" // Hostile vore mobs only id = "m_tele" @@ -317,11 +317,11 @@ required_reagents = list("phoron" = 20, "nutriment" = 20, "sugar" = 20, "mutationtoxin" = 20) //Can't do slime jelly as it'll conflict with another, but mutation toxin will do. result_amount = 1 on_reaction(var/datum/reagents/holder) - var/mob_path = /mob/living/simple_animal + var/mob_path = /mob/living/simple_mob var/blocked = list( - /mob/living/simple_animal/hostile/mimic, - /mob/living/simple_animal/hostile/alien/queen, - /mob/living/simple_animal/shadekin + /mob/living/simple_mob/hostile/mimic, + /mob/living/simple_mob/hostile/alien/queen, + /mob/living/simple_mob/shadekin )//exclusion list for things you don't want the reaction to create. var/list/voremobs = typesof(mob_path) - mob_path - blocked // list of possible hostile mobs @@ -334,9 +334,10 @@ var/spawn_count = rand(1,3) for(var/i = 1, i <= spawn_count, i++) var/chosen = pick(voremobs) - var/mob/living/simple_animal/hostile/C = new chosen + var/mob/living/simple_mob/hostile/C = new chosen C.faction = "slimesummon" C.loc = get_turf(holder.my_atom) if(prob(50)) for(var/j = 1, j <= rand(1, 3), j++) step(C, pick(NORTH,SOUTH,EAST,WEST)) +*/ \ No newline at end of file diff --git a/code/modules/reagents/dispenser/cartridge.dm b/code/modules/reagents/dispenser/cartridge.dm index 3a129d4872..70142fabd8 100644 --- a/code/modules/reagents/dispenser/cartridge.dm +++ b/code/modules/reagents/dispenser/cartridge.dm @@ -14,11 +14,11 @@ var/spawn_reagent = null var/label = "" -/obj/item/weapon/reagent_containers/chem_disp_cartridge/New() - ..() +/obj/item/weapon/reagent_containers/chem_disp_cartridge/Initialize() + . = ..() if(spawn_reagent) reagents.add_reagent(spawn_reagent, volume) - var/datum/reagent/R = chemical_reagents_list[spawn_reagent] + var/datum/reagent/R = SSchemistry.chemical_reagents[spawn_reagent] setLabel(R.name) /obj/item/weapon/reagent_containers/chem_disp_cartridge/examine(mob/user) diff --git a/code/modules/reagents/dispenser/cartridge_spawn.dm b/code/modules/reagents/dispenser/cartridge_spawn.dm index 730e191891..ba9b727047 100644 --- a/code/modules/reagents/dispenser/cartridge_spawn.dm +++ b/code/modules/reagents/dispenser/cartridge_spawn.dm @@ -1,4 +1,4 @@ -/client/proc/spawn_chemdisp_cartridge(size in list("small", "medium", "large"), reagent in chemical_reagents_list) +/client/proc/spawn_chemdisp_cartridge(size in list("small", "medium", "large"), reagent in SSchemistry.chemical_reagents) set name = "Spawn Chemical Dispenser Cartridge" set category = "Admin" @@ -8,6 +8,6 @@ if("medium") C = new /obj/item/weapon/reagent_containers/chem_disp_cartridge/medium(usr.loc) if("large") C = new /obj/item/weapon/reagent_containers/chem_disp_cartridge(usr.loc) C.reagents.add_reagent(reagent, C.volume) - var/datum/reagent/R = chemical_reagents_list[reagent] + var/datum/reagent/R = SSchemistry.chemical_reagents[reagent] C.setLabel(R.name) log_admin("[key_name(usr)] spawned a [size] reagent container containing [reagent] at ([usr.x],[usr.y],[usr.z])") diff --git a/code/modules/reagents/dispenser/dispenser2.dm b/code/modules/reagents/dispenser/dispenser2.dm index 14f8fc9898..38c6cf39da 100644 --- a/code/modules/reagents/dispenser/dispenser2.dm +++ b/code/modules/reagents/dispenser/dispenser2.dm @@ -17,9 +17,8 @@ idle_power_usage = 100 anchored = 1 -/obj/machinery/chemical_dispenser/New() - ..() - +/obj/machinery/chemical_dispenser/Initialize() + . = ..() if(spawn_cartridges) for(var/type in spawn_cartridges) add_cartridge(new type(src)) @@ -56,12 +55,12 @@ C.loc = src cartridges[C.label] = C cartridges = sortAssoc(cartridges) - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) /obj/machinery/chemical_dispenser/proc/remove_cartridge(label) . = cartridges[label] cartridges -= label - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) /obj/machinery/chemical_dispenser/attackby(obj/item/weapon/W, mob/user) if(W.is_wrench()) @@ -107,7 +106,7 @@ user.drop_from_inventory(RC) RC.loc = src to_chat(user, "You set \the [RC] on \the [src].") - GLOB.nanomanager.update_uis(src) // update all UIs attached to src + SSnanoui.update_uis(src) // update all UIs attached to src else return ..() @@ -141,7 +140,7 @@ data["chemicals"] = chemicals // update the ui if it exists, returns null if no ui is passed/found - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if(!ui) ui = new(user, src, ui_key, "chem_disp.tmpl", ui_title, 390, 680) ui.set_initial_data(data) diff --git a/code/modules/reagents/dispenser/dispenser2_energy.dm b/code/modules/reagents/dispenser/dispenser2_energy.dm index f540811c11..c889b2fe9d 100644 --- a/code/modules/reagents/dispenser/dispenser2_energy.dm +++ b/code/modules/reagents/dispenser/dispenser2_energy.dm @@ -13,7 +13,7 @@ process_tick = 15 . = 0 for(var/id in dispense_reagents) - var/datum/reagent/R = chemical_reagents_list[id] + var/datum/reagent/R = SSchemistry.chemical_reagents[id] if(!R) crash_with("[src] at [x],[y],[z] failed to find reagent '[id]'!") dispense_reagents -= id @@ -25,7 +25,7 @@ C.reagents.add_reagent(id, to_restore) . = 1 if(.) - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) /obj/machinery/chemical_dispenser dispense_reagents = list( diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index b870a55902..8f6be28b80 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -16,8 +16,8 @@ if(N) amount_per_transfer_from_this = N -/obj/item/weapon/reagent_containers/New() - ..() +/obj/item/weapon/reagent_containers/Initialize() + . = ..() if(!possible_transfer_amounts) src.verbs -= /obj/item/weapon/reagent_containers/verb/set_APTFT create_reagents(volume) @@ -100,7 +100,7 @@ user.setClickCooldown(user.get_attack_speed(src)) //puts a limit on how fast people can eat/drink things self_feed_message(user) - reagents.trans_to_mob(user, issmall(user) ? ceil(amount_per_transfer_from_this/2) : amount_per_transfer_from_this, CHEM_INGEST) + reagents.trans_to_mob(user, issmall(user) ? CEILING(amount_per_transfer_from_this/2, 1) : amount_per_transfer_from_this, CHEM_INGEST) feed_sound(user) return 1 else diff --git a/code/modules/reagents/reagent_containers/blood_pack.dm b/code/modules/reagents/reagent_containers/blood_pack.dm index 0f40a83e20..fe6ddb87dc 100644 --- a/code/modules/reagents/reagent_containers/blood_pack.dm +++ b/code/modules/reagents/reagent_containers/blood_pack.dm @@ -3,8 +3,8 @@ desc = "This box contains blood packs." icon_state = "sterile" -/obj/item/weapon/storage/box/bloodpacks/New() - ..() +/obj/item/weapon/storage/box/bloodpacks/Initialize() + . = ..() new /obj/item/weapon/reagent_containers/blood/empty(src) new /obj/item/weapon/reagent_containers/blood/empty(src) new /obj/item/weapon/reagent_containers/blood/empty(src) @@ -26,8 +26,8 @@ var/blood_type = null -/obj/item/weapon/reagent_containers/blood/New() - ..() +/obj/item/weapon/reagent_containers/blood/Initialize() + . = ..() base_name = name base_desc = desc if(blood_type != null) diff --git a/code/modules/reagents/reagent_containers/borghydro.dm b/code/modules/reagents/reagent_containers/borghydro.dm index d5a1f0571a..df99bca9e1 100644 --- a/code/modules/reagents/reagent_containers/borghydro.dm +++ b/code/modules/reagents/reagent_containers/borghydro.dm @@ -34,18 +34,18 @@ bypass_protection = TRUE // Because mercs tend to be in spacesuits. reagent_ids = list("healing_nanites", "hyperzine", "tramadol", "oxycodone", "spaceacillin", "peridaxon", "osteodaxon", "myelamine", "synthblood") -/obj/item/weapon/reagent_containers/borghypo/New() - ..() +/obj/item/weapon/reagent_containers/borghypo/Initialize() + . = ..() for(var/T in reagent_ids) reagent_volumes[T] = volume - var/datum/reagent/R = chemical_reagents_list[T] + var/datum/reagent/R = SSchemistry.chemical_reagents[T] reagent_names += R.name - processing_objects.Add(src) + START_PROCESSING(SSobj, src) /obj/item/weapon/reagent_containers/borghypo/Destroy() - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) return ..() /obj/item/weapon/reagent_containers/borghypo/process() //Every [recharge_time] seconds, recharge some reagents for the cyborg+ @@ -112,14 +112,14 @@ if(t) playsound(loc, 'sound/effects/pop.ogg', 50, 0) mode = t - var/datum/reagent/R = chemical_reagents_list[reagent_ids[mode]] + var/datum/reagent/R = SSchemistry.chemical_reagents[reagent_ids[mode]] usr << "Synthesizer is now producing '[R.name]'." /obj/item/weapon/reagent_containers/borghypo/examine(mob/user) if(!..(user, 2)) return - var/datum/reagent/R = chemical_reagents_list[reagent_ids[mode]] + var/datum/reagent/R = SSchemistry.chemical_reagents[reagent_ids[mode]] user << "It is currently producing [R.name] and has [reagent_volumes[reagent_ids[mode]]] out of [volume] units left." diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index 737dbdcdad..4cc781fdea 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -37,8 +37,8 @@ /obj/machinery/iv_drip, /obj/machinery/disease2/incubator, /obj/machinery/disposal, - /mob/living/simple_animal/cow, - /mob/living/simple_animal/retaliate/goat, + /mob/living/simple_mob/animal/passive/cow, + /mob/living/simple_mob/animal/goat, /obj/machinery/computer/centrifuge, /obj/machinery/sleeper, /obj/machinery/smartfridge/, @@ -47,8 +47,8 @@ /obj/machinery/radiocarbon_spectrometer ) -/obj/item/weapon/reagent_containers/glass/New() - ..() +/obj/item/weapon/reagent_containers/glass/Initialize() + . = ..() if(LAZYLEN(prefill)) for(var/R in prefill) reagents.add_reagent(R,prefill[R]) @@ -150,8 +150,8 @@ item_state = "beaker" matter = list("glass" = 500) -/obj/item/weapon/reagent_containers/glass/beaker/New() - ..() +/obj/item/weapon/reagent_containers/glass/beaker/Initialize() + . = ..() desc += " Can hold up to [volume] units." /obj/item/weapon/reagent_containers/glass/beaker/on_reagent_change() diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm index 3cfac06de1..eb3d3e1975 100644 --- a/code/modules/reagents/reagent_containers/hypospray.dm +++ b/code/modules/reagents/reagent_containers/hypospray.dm @@ -19,14 +19,13 @@ var/list/filled_reagents = list() var/hyposound // What sound do we play on use? -/obj/item/weapon/reagent_containers/hypospray/New() - ..() +/obj/item/weapon/reagent_containers/hypospray/Initialize() + . = ..() if(filled) if(filled_reagents) for(var/r in filled_reagents) reagents.add_reagent(r, filled_reagents[r]) update_icon() - return /obj/item/weapon/reagent_containers/hypospray/attack(mob/living/M as mob, mob/user as mob) if(!reagents.total_volume) @@ -53,20 +52,29 @@ if(!do_after(user, 30, H)) return + do_injection(H, user) + return + +// This does the actual injection and transfer. +/obj/item/weapon/reagent_containers/hypospray/proc/do_injection(mob/living/carbon/human/H, mob/living/user) + if(!istype(H) || !istype(user)) + return FALSE + user.setClickCooldown(DEFAULT_QUICK_COOLDOWN) - to_chat(user, "You inject [M] with \the [src].") - to_chat(M, "You feel a tiny prick!") + to_chat(user, span("notice", "You inject \the [H] with \the [src].")) + to_chat(H, span("warning", "You feel a tiny prick!")) if(hyposound) - playsound(src, hyposound,25) + playsound(src, hyposound, 25) - if(M.reagents) + if(H.reagents) var/contained = reagentlist() - var/trans = reagents.trans_to_mob(M, amount_per_transfer_from_this, CHEM_BLOOD) - add_attack_logs(user,M,"Injected with [src.name] containing [contained], trasferred [trans] units") - to_chat(user, "[trans] units injected. [reagents.total_volume] units remaining in \the [src].") + var/trans = reagents.trans_to_mob(H, amount_per_transfer_from_this, CHEM_BLOOD) + add_attack_logs(user,H,"Injected with [src.name] containing [contained], trasferred [trans] units") + to_chat(user, span("notice", "[trans] units injected. [reagents.total_volume] units remaining in \the [src].")) + return TRUE + return FALSE - return //A vial-loaded hypospray. Cartridge-based! /obj/item/weapon/reagent_containers/hypospray/vial name = "hypospray mkII" @@ -74,8 +82,8 @@ var/obj/item/weapon/reagent_containers/glass/beaker/vial/loaded_vial //Wow, what a name. volume = 0 -/obj/item/weapon/reagent_containers/hypospray/vial/New() - ..() +/obj/item/weapon/reagent_containers/hypospray/vial/Initialize() + . = ..() loaded_vial = new /obj/item/weapon/reagent_containers/glass/beaker/vial(src) //Comes with an empty vial volume = loaded_vial.volume reagents.maximum_volume = loaded_vial.reagents.maximum_volume @@ -138,17 +146,16 @@ filled = 0 filled_reagents = list() -/obj/item/weapon/reagent_containers/hypospray/autoinjector/used/New() - ..() +/obj/item/weapon/reagent_containers/hypospray/autoinjector/used/Initialize() + . = ..() flags &= ~OPENCONTAINER icon_state = "[initial(icon_state)]0" -/obj/item/weapon/reagent_containers/hypospray/autoinjector/attack(mob/M as mob, mob/user as mob) - ..() - if(reagents.total_volume <= 0) //Prevents autoinjectors to be refilled. +/obj/item/weapon/reagent_containers/hypospray/autoinjector/do_injection(mob/living/carbon/human/H, mob/living/user) + . = ..() + if(.) // Will occur if successfully injected. flags &= ~OPENCONTAINER - update_icon() - return + update_icon() /obj/item/weapon/reagent_containers/hypospray/autoinjector/update_icon() if(reagents.total_volume > 0) @@ -168,6 +175,63 @@ icon_state = "green" filled_reagents = list("anti_toxin" = 5) +// These have a 15u capacity, somewhat higher tech level, and generally more useful chems, but are otherwise the same as the regular autoinjectors. +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector + name = "empty hypo" + desc = "A refined version of the standard autoinjector, allowing greater capacity." + icon_state = "autoinjector" + amount_per_transfer_from_this = 15 + volume = 15 + origin_tech = list(TECH_BIO = 4) + filled_reagents = list("inaprovaline" = 15) + flags = 0 // Removed OPENCONTAINER so you can't extract things to cheese the identification system in unidentified versions. + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/brute + name = "trauma hypo" + desc = "A refined version of the standard autoinjector, allowing greater capacity. This one is made to be used on victims of \ + moderate blunt trauma." + filled_reagents = list("bicaridine" = 15) + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/burn + name = "burn hypo" + desc = "A refined version of the standard autoinjector, allowing greater capacity. This one is made to be used on burn victims, \ + featuring an optimized chemical mixture to allow for rapid healing." + filled_reagents = list("kelotane" = 7.5, "dermaline" = 7.5) + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/toxin + name = "toxin hypo" + desc = "A refined version of the standard autoinjector, allowing greater capacity. This one is made to counteract toxins." + filled_reagents = list("anti_toxin" = 15) + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/oxy + name = "oxy hypo" + desc = "A refined version of the standard autoinjector, allowing greater capacity. This one is made to counteract oxygen \ + deprivation." + filled_reagents = list("dexalinp" = 10, "tricordrazine" = 5) + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/purity + name = "purity hypo" + desc = "A refined version of the standard autoinjector, allowing greater capacity. This variant excels at \ + resolving viruses, infections, radiation, and genetic maladies." + filled_reagents = list("spaceacillin" = 9, "arithrazine" = 5, "ryetalyn" = 1) + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/pain + name = "pain hypo" + desc = "A refined version of the standard autoinjector, allowing greater capacity. This one contains potent painkillers." + filled_reagents = list("tramadol" = 15) + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/organ + name = "organ hypo" + desc = "A refined version of the standard autoinjector, allowing greater capacity. Organ damage is resolved by this variant." + filled_reagents = list("alkysine" = 3, "imidazoline" = 2, "peridaxon" = 10) + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/combat + name = "combat hypo" + desc = "A refined version of the standard autoinjector, allowing greater capacity. This is a more dangerous and potentially \ + addictive hypo compared to others, as it contains a potent cocktail of various chemicals to optimize the recipient's combat \ + ability." + filled_reagents = list("bicaridine" = 3, "kelotane" = 1.5, "dermaline" = 1.5, "oxycodone" = 3, "hyperzine" = 3, "tricordrazine" = 3) + /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/clotting name = "clotting agent" desc = "A refined version of the standard autoinjector, allowing greater capacity. This variant excels at treating bleeding wounds and internal bleeding." @@ -177,3 +241,109 @@ name = "bone repair injector" desc = "A refined version of the standard autoinjector, allowing greater capacity. This one excels at treating damage to bones." filled_reagents = list("inaprovaline" = 5, "osteodaxon" = 10) + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/stimm + name = "stimm injector" + desc = "A refined version of the standard autoinjector, allowing greater capacity. \ + This one is filled with a home-made stimulant, with some serious side-effects." + filled_reagents = list("stimm" = 10) // More than 10u will OD. + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/expired + name = "expired injector" + desc = "A refined version of the standard autoinjector, allowing greater capacity. \ + This one has had its contents expire a long time ago, using it now will probably make someone sick, or worse." + filled_reagents = list("expired_medicine" = 15) + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/soporific + name = "soporific injector" + desc = "A refined version of the standard autoinjector, allowing greater capacity. \ + This one is sometimes used by orderlies, as it has soporifics, which make someone tired and fall asleep." + filled_reagents = list("stoxin" = 15) + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/cyanide + name = "cyanide injector" + desc = "A refined version of the standard autoinjector, allowing greater capacity. \ + This one contains cyanide, a lethal poison. It being inside a medical autoinjector has certain unsettling implications." + filled_reagents = list("cyanide" = 15) + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/serotrotium + name = "serotrotium injector" + desc = "A refined version of the standard autoinjector, allowing greater capacity. \ + This one is filled with serotrotium, which causes concentrated production of the serotonin neurotransmitter in humans." + filled_reagents = list("serotrotium" = 15) + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/space_drugs + name = "illicit injector" + desc = "A refined version of the standard autoinjector, allowing greater capacity. \ + This one contains various illicit drugs, held inside a hypospray to make smuggling easier." + filled_reagents = list("space_drugs" = 15) + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/cryptobiolin + name = "cryptobiolin injector" + desc = "A refined version of the standard autoinjector, allowing greater capacity. \ + This one contains cryptobiolin, which causes confusion." + filled_reagents = list("cryptobiolin" = 15) + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/impedrezene + name = "impedrezene injector" + desc = "A refined version of the standard autoinjector, allowing greater capacity. \ + This one has impedrezene inside, a narcotic that impairs higher brain functioning. \ + This autoinjector is almost certainly created illegitimately." + filled_reagents = list("impedrezene" = 15) + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/mindbreaker + name = "mindbreaker injector" + desc = "A refined version of the standard autoinjector, allowing greater capacity. \ + This one stores the dangerous hallucinogen called 'Mindbreaker', likely put in place \ + by illicit groups hoping to hide their product." + filled_reagents = list("mindbreaker" = 15) + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/psilocybin + name = "psilocybin injector" + desc = "A refined version of the standard autoinjector, allowing greater capacity. \ + This has psilocybin inside, which is a strong psychotropic derived from certain species of mushroom. \ + This autoinjector likely was made by criminal elements to avoid detection from casual inspection." + filled_reagents = list("psilocybin" = 15) + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/mutagen + name = "unstable mutagen injector" + desc = "A refined version of the standard autoinjector, allowing greater capacity. \ + This contains unstable mutagen, which makes using this a very bad idea. It will either \ + ruin your genetic health, turn you into a Five Points violation, or both!" + filled_reagents = list("mutagen" = 15) + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/lexorin + name = "lexorin injector" + desc = "A refined version of the standard autoinjector, allowing greater capacity. \ + This contains lexorin, a dangerous toxin that stops respiration, and has been \ + implicated in several high-profile assassinations in the past." + filled_reagents = list("lexorin" = 15) + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/healing_nanites + name = "medical nanite injector" + desc = "A refined version of the standard autoinjector, allowing greater capacity. \ + The injector stores a slurry of highly advanced and specialized nanomachines designed \ + to restore bodily health from within. The nanomachines are short-lived but degrade \ + harmlessly, and cannot self-replicate in order to remain Five Points compliant." + filled_reagents = list("healing_nanites" = 15) + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/defective_nanites + name = "defective nanite injector" + desc = "A refined version of the standard autoinjector, allowing greater capacity. \ + The injector stores a slurry of highly advanced and specialized nanomachines that \ + are unfortunately malfunctioning, making them unsafe to use inside of a living body. \ + Because of the Five Points, these nanites cannot self-replicate." + filled_reagents = list("defective_nanites" = 15) + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/contaminated + name = "contaminated injector" + desc = "A refined version of the standard autoinjector, allowing greater capacity. \ + The hypospray contains a viral agent inside, as well as a liquid substance that encourages \ + the growth of the virus inside." + filled_reagents = list("virusfood" = 15) + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/contaminated/do_injection(mob/living/carbon/human/H, mob/living/user) + . = ..() + if(.) // Will occur if successfully injected. + infect_mob_random_lesser(H) + add_attack_logs(user, H, "Infected \the [H] with \the [src], by \the [user].") \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm index c93df31ec4..b2f5d39cde 100644 --- a/code/modules/reagents/reagent_containers/pill.dm +++ b/code/modules/reagents/reagent_containers/pill.dm @@ -12,10 +12,8 @@ slot_flags = SLOT_EARS volume = 60 - - -/obj/item/weapon/reagent_containers/pill/New() - ..() +/obj/item/weapon/reagent_containers/pill/Initialize() + . = ..() if(!icon_state) icon_state = "pill[rand(1, 20)]" @@ -98,28 +96,26 @@ desc = "Neutralizes many common toxins. Contains 25 units of Dylovene." icon_state = "pill17" -/obj/item/weapon/reagent_containers/pill/antitox/New() - ..() +/obj/item/weapon/reagent_containers/pill/antitox/Initialize() + . = ..() reagents.add_reagent("anti_toxin", 25) - /obj/item/weapon/reagent_containers/pill/tox name = "Toxins pill" desc = "Highly toxic." //this is cooler without "contains 50u toxin" icon_state = "pill5" -/obj/item/weapon/reagent_containers/pill/tox/New() - ..() +/obj/item/weapon/reagent_containers/pill/tox/Initialize() + . = ..() reagents.add_reagent("toxin", 50) - /obj/item/weapon/reagent_containers/pill/cyanide name = "Cyanide pill" desc = "Don't swallow this." //this is cooler without "contains 50u cyanide" icon_state = "pill5" -/obj/item/weapon/reagent_containers/pill/cyanide/New() - ..() +/obj/item/weapon/reagent_containers/pill/cyanide/Initialize() + . = ..() reagents.add_reagent("cyanide", 50) @@ -128,8 +124,8 @@ desc = "It's magic. We don't have to explain it." //it's space magic you don't need the quantity icon_state = "pill16" -/obj/item/weapon/reagent_containers/pill/adminordrazine/New() - ..() +/obj/item/weapon/reagent_containers/pill/adminordrazine/Initialize() + . = ..() reagents.add_reagent("adminordrazine", 50) /obj/item/weapon/reagent_containers/pill/stox @@ -137,8 +133,8 @@ desc = "Commonly used to treat insomnia. Contains 15 units of Soporific." icon_state = "pill8" -/obj/item/weapon/reagent_containers/pill/stox/New() - ..() +/obj/item/weapon/reagent_containers/pill/stox/Initialize() + . = ..() reagents.add_reagent("stoxin", 15) @@ -147,8 +143,8 @@ desc = "Used to treat burns. Contains 15 units of Kelotane." icon_state = "pill11" -/obj/item/weapon/reagent_containers/pill/kelotane/New() - ..() +/obj/item/weapon/reagent_containers/pill/kelotane/Initialize() + . = ..() reagents.add_reagent("kelotane", 15) @@ -157,8 +153,8 @@ desc = "Paracetamol! A painkiller for the ages. Chewables! Contains 15 units of Paracetamol." icon_state = "pill8" -/obj/item/weapon/reagent_containers/pill/paracetamol/New() - ..() +/obj/item/weapon/reagent_containers/pill/paracetamol/Initialize() + . = ..() reagents.add_reagent("paracetamol", 15) @@ -167,8 +163,8 @@ desc = "A simple painkiller. Contains 15 units of Tramadol." icon_state = "pill8" -/obj/item/weapon/reagent_containers/pill/tramadol/New() - ..() +/obj/item/weapon/reagent_containers/pill/tramadol/Initialize() + . = ..() reagents.add_reagent("tramadol", 15) @@ -177,8 +173,8 @@ desc = "Improves the ability to concentrate. Contains 15 units of Methylphenidate." icon_state = "pill8" -/obj/item/weapon/reagent_containers/pill/methylphenidate/New() - ..() +/obj/item/weapon/reagent_containers/pill/methylphenidate/Initialize() + . = ..() reagents.add_reagent("methylphenidate", 15) @@ -187,18 +183,17 @@ desc = "Mild anti-depressant. Contains 15 units of Citalopram." icon_state = "pill8" -/obj/item/weapon/reagent_containers/pill/citalopram/New() - ..() +/obj/item/weapon/reagent_containers/pill/citalopram/Initialize() + . = ..() reagents.add_reagent("citalopram", 15) - /obj/item/weapon/reagent_containers/pill/dexalin name = "Dexalin pill" desc = "Used to treat oxygen deprivation. Contains 15 units of Dexalin." icon_state = "pill16" -/obj/item/weapon/reagent_containers/pill/dexalin/New() - ..() +/obj/item/weapon/reagent_containers/pill/dexalin/Initialize() + . = ..() reagents.add_reagent("dexalin", 15) @@ -207,38 +202,35 @@ desc = "Used to treat extreme oxygen deprivation. Contains 15 units of Dexalin Plus." icon_state = "pill8" -/obj/item/weapon/reagent_containers/pill/dexalin_plus/New() - ..() +/obj/item/weapon/reagent_containers/pill/dexalin_plus/Initialize() + . = ..() reagents.add_reagent("dexalinp", 15) - /obj/item/weapon/reagent_containers/pill/dermaline name = "Dermaline pill" desc = "Used to treat burn wounds. Contains 15 units of Dermaline." icon_state = "pill12" -/obj/item/weapon/reagent_containers/pill/dermaline/New() - ..() +/obj/item/weapon/reagent_containers/pill/dermaline/Initialize() + . = ..() reagents.add_reagent("dermaline", 15) - /obj/item/weapon/reagent_containers/pill/dylovene name = "Dylovene pill" desc = "A broad-spectrum anti-toxin. Contains 15 units of Dylovene." icon_state = "pill13" -/obj/item/weapon/reagent_containers/pill/dylovene/New() - ..() +/obj/item/weapon/reagent_containers/pill/dylovene/Initialize() + . = ..() reagents.add_reagent("anti_toxin", 15) - /obj/item/weapon/reagent_containers/pill/inaprovaline name = "Inaprovaline pill" desc = "Used to stabilize patients. Contains 30 units of Inaprovaline." icon_state = "pill20" -/obj/item/weapon/reagent_containers/pill/inaprovaline/New() - ..() +/obj/item/weapon/reagent_containers/pill/inaprovaline/Initialize() + . = ..() reagents.add_reagent("inaprovaline", 30) @@ -247,8 +239,8 @@ desc = "Used to treat physical injuries. Contains 20 units of Bicaridine." icon_state = "pill18" -/obj/item/weapon/reagent_containers/pill/bicaridine/New() - ..() +/obj/item/weapon/reagent_containers/pill/bicaridine/Initialize() + . = ..() reagents.add_reagent("bicaridine", 20) @@ -257,8 +249,8 @@ desc = "A theta-lactam antibiotic. Effective against many diseases likely to be encountered in space. Contains 15 units of Spaceacillin." icon_state = "pill19" -/obj/item/weapon/reagent_containers/pill/spaceacillin/New() - ..() +/obj/item/weapon/reagent_containers/pill/spaceacillin/Initialize() + . = ..() reagents.add_reagent("spaceacillin", 15) @@ -267,8 +259,8 @@ desc = "Used to neutralise chemicals in the stomach. Contains 15 units of Carbon." icon_state = "pill7" -/obj/item/weapon/reagent_containers/pill/carbon/New() - ..() +/obj/item/weapon/reagent_containers/pill/carbon/Initialize() + . = ..() reagents.add_reagent("carbon", 15) @@ -277,8 +269,8 @@ desc = "Used to aid in blood regeneration after bleeding. Contains 15 units of Iron." icon_state = "pill4" -/obj/item/weapon/reagent_containers/pill/iron/New() - ..() +/obj/item/weapon/reagent_containers/pill/iron/Initialize() + . = ..() reagents.add_reagent("iron", 15) //Not-quite-medicine @@ -287,8 +279,8 @@ desc = "Happy happy joy joy!" //we're not giving quantities for shady maint drugs icon_state = "pill18" -/obj/item/weapon/reagent_containers/pill/happy/New() - ..() +/obj/item/weapon/reagent_containers/pill/happy/Initialize() + . = ..() reagents.add_reagent("space_drugs", 15) reagents.add_reagent("sugar", 15) @@ -298,8 +290,8 @@ desc = "Zoooom!" icon_state = "pill18" -/obj/item/weapon/reagent_containers/pill/zoom/New() - ..() +/obj/item/weapon/reagent_containers/pill/zoom/Initialize() + . = ..() reagents.add_reagent("impedrezene", 10) reagents.add_reagent("synaptizine", 5) reagents.add_reagent("hyperzine", 5) @@ -309,6 +301,6 @@ desc = "Guaranteed to get you slim!" icon_state = "pill9" -/obj/item/weapon/reagent_containers/pill/diet/New() - ..() +/obj/item/weapon/reagent_containers/pill/diet/Initialize() + . = ..() reagents.add_reagent("lipozine", 15) //VOREStation Edit diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index 136bb34026..cdc6983b35 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -17,8 +17,8 @@ var/list/spray_sizes = list(1,3) volume = 250 -/obj/item/weapon/reagent_containers/spray/New() - ..() +/obj/item/weapon/reagent_containers/spray/Initialize() + . = ..() src.verbs -= /obj/item/weapon/reagent_containers/verb/set_APTFT /obj/item/weapon/reagent_containers/spray/afterattack(atom/A as mob|obj, mob/user as mob, proximity) @@ -102,16 +102,16 @@ desc = "BLAM!-brand non-foaming space cleaner!" volume = 50 -/obj/item/weapon/reagent_containers/spray/cleaner/New() - ..() +/obj/item/weapon/reagent_containers/spray/cleaner/Initialize() + . = ..() reagents.add_reagent("cleaner", volume) /obj/item/weapon/reagent_containers/spray/sterilizine name = "sterilizine" desc = "Great for hiding incriminating bloodstains and sterilizing scalpels." -/obj/item/weapon/reagent_containers/spray/sterilizine/New() - ..() +/obj/item/weapon/reagent_containers/spray/sterilizine/Initialize() + . = ..() reagents.add_reagent("sterilizine", volume) /obj/item/weapon/reagent_containers/spray/pepper @@ -122,10 +122,10 @@ item_state = "pepperspray" possible_transfer_amounts = null volume = 40 - var/safety = 1 + var/safety = TRUE -/obj/item/weapon/reagent_containers/spray/pepper/New() - ..() +/obj/item/weapon/reagent_containers/spray/pepper/Initialize() + . = ..() reagents.add_reagent("condensedcapsaicin", 40) /obj/item/weapon/reagent_containers/spray/pepper/examine(mob/user) @@ -140,7 +140,7 @@ if(safety) usr << "The safety is on!" return - ..() + . = ..() /obj/item/weapon/reagent_containers/spray/waterflower name = "water flower" @@ -152,8 +152,8 @@ possible_transfer_amounts = null volume = 10 -/obj/item/weapon/reagent_containers/spray/waterflower/New() - ..() +/obj/item/weapon/reagent_containers/spray/waterflower/Initialize() + . = ..() reagents.add_reagent("water", 10) /obj/item/weapon/reagent_containers/spray/chemsprayer @@ -196,6 +196,6 @@ item_state = "plantbgone" volume = 100 -/obj/item/weapon/reagent_containers/spray/plantbgone/New() - ..() +/obj/item/weapon/reagent_containers/spray/plantbgone/Initialize() + . = ..() reagents.add_reagent("plantbgone", 100) \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index 804b4a85d2..29544fa052 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -330,8 +330,8 @@ name = "Syringe (inaprovaline)" desc = "Contains inaprovaline - used to stabilize patients." -/obj/item/weapon/reagent_containers/syringe/inaprovaline/New() - ..() +/obj/item/weapon/reagent_containers/syringe/inaprovaline/Initialize() + . = ..() reagents.add_reagent("inaprovaline", 15) //mode = SYRINGE_INJECT //VOREStation Edit - Starts capped //update_icon() @@ -340,8 +340,8 @@ name = "Syringe (anti-toxin)" desc = "Contains anti-toxins." -/obj/item/weapon/reagent_containers/syringe/antitoxin/New() - ..() +/obj/item/weapon/reagent_containers/syringe/antitoxin/Initialize() + . = ..() reagents.add_reagent("anti_toxin", 15) //mode = SYRINGE_INJECT //VOREStation Edit - Starts capped //update_icon() @@ -350,8 +350,8 @@ name = "Syringe (spaceacillin)" desc = "Contains antiviral agents." -/obj/item/weapon/reagent_containers/syringe/antiviral/New() - ..() +/obj/item/weapon/reagent_containers/syringe/antiviral/Initialize() + . = ..() reagents.add_reagent("spaceacillin", 15) //mode = SYRINGE_INJECT //VOREStation Edit - Starts capped //update_icon() @@ -360,16 +360,16 @@ name = "Syringe (drugs)" desc = "Contains aggressive drugs meant for torture." -/obj/item/weapon/reagent_containers/syringe/drugs/New() - ..() +/obj/item/weapon/reagent_containers/syringe/drugs/Initialize() + . = ..() reagents.add_reagent("space_drugs", 5) reagents.add_reagent("mindbreaker", 5) reagents.add_reagent("cryptobiolin", 5) //mode = SYRINGE_INJECT //VOREStation Edit - Starts capped //update_icon() -/obj/item/weapon/reagent_containers/syringe/ld50_syringe/choral/New() - ..() +/obj/item/weapon/reagent_containers/syringe/ld50_syringe/choral/Initialize() + . = ..() reagents.add_reagent("chloralhydrate", 50) mode = SYRINGE_INJECT update_icon() @@ -378,7 +378,7 @@ name = "Syringe (anabolic steroids)" desc = "Contains drugs for muscle growth." -/obj/item/weapon/reagent_containers/syringe/steroid/New() +/obj/item/weapon/reagent_containers/syringe/steroid/Initialize() ..() //reagents.add_reagent("adrenaline",5) //VOREStation Edit - No thanks. reagents.add_reagent("hyperzine",10) diff --git a/code/modules/reagents/reagent_containers/syringes_vr.dm b/code/modules/reagents/reagent_containers/syringes_vr.dm index c1d4a4e686..83c5bacaef 100644 --- a/code/modules/reagents/reagent_containers/syringes_vr.dm +++ b/code/modules/reagents/reagent_containers/syringes_vr.dm @@ -8,19 +8,19 @@ var/list/targets var/list/datum/disease2/disease/viruses -/obj/item/weapon/reagent_containers/syringe/initialize() +/obj/item/weapon/reagent_containers/syringe/Initialize() . = ..() update_icon() /obj/item/weapon/reagent_containers/syringe/Destroy() - QDEL_NULL_LIST(viruses) + QDEL_LIST_NULL(viruses) LAZYCLEARLIST(targets) return ..() /obj/item/weapon/reagent_containers/syringe/process() dirtiness = min(dirtiness + targets.len,75) if(dirtiness >= 75) - processing_objects -= src + STOP_PROCESSING(SSobj, src) return 1 /obj/item/weapon/reagent_containers/syringe/proc/dirty(var/mob/living/carbon/human/target, var/obj/item/organ/external/eo) @@ -59,7 +59,7 @@ infect_virus2(target,virus.getcopy()) if(!used) - processing_objects |= src + START_PROCESSING(SSobj, src) /obj/item/weapon/reagent_containers/syringe/proc/infect_limb(var/obj/item/organ/external/eo) src = null @@ -68,7 +68,7 @@ var/obj/item/organ/external/found_limb = limb_ref.resolve() if(istype(found_limb)) eo.germ_level += INFECTION_LEVEL_ONE+30 - + //Allow for capped syringe mode /obj/item/weapon/reagent_containers/syringe/attack_self(mob/user as mob) switch(mode) @@ -83,10 +83,10 @@ return update_icon() -//Allow for capped syringes +//Allow for capped syringes /obj/item/weapon/reagent_containers/syringe/update_icon() cut_overlays(src) - + var/matrix/tf = matrix() if(isstorage(loc)) tf.Turn(-90) //Vertical for storing compact-ly @@ -116,7 +116,7 @@ if (SYRINGE_INJECT) injoverlay = "inject" new_overlays += injoverlay - + add_overlay(new_overlays) icon_state = "[rounded_vol]" item_state = "syringe_[rounded_vol]" diff --git a/code/modules/reagents/reagent_containers/unidentified_hypospray.dm b/code/modules/reagents/reagent_containers/unidentified_hypospray.dm new file mode 100644 index 0000000000..518ed05111 --- /dev/null +++ b/code/modules/reagents/reagent_containers/unidentified_hypospray.dm @@ -0,0 +1,80 @@ +// Here are the paths for all hypos that start unidentified. +// Usually you want to use a random spawner instead of using them directly, unless you're spawning these live for adminbus purposes. + +/obj/item/weapon/reagent_containers/hypospray/autoinjector + identity_type = /datum/identification/hypo + +// The good. +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/brute/unidentified + init_hide_identity = TRUE + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/burn/unidentified + init_hide_identity = TRUE + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/toxin/unidentified + init_hide_identity = TRUE + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/oxy/unidentified + init_hide_identity = TRUE + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/purity/unidentified + init_hide_identity = TRUE + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/pain/unidentified + init_hide_identity = TRUE + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/organ/unidentified + init_hide_identity = TRUE + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/clotting/unidentified + init_hide_identity = TRUE + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/bonemed/unidentified + init_hide_identity = TRUE + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/combat/unidentified + init_hide_identity = TRUE + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/healing_nanites/unidentified + init_hide_identity = TRUE + +// The somewhat bad. +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/stimm/unidentified + init_hide_identity = TRUE + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/space_drugs/unidentified + init_hide_identity = TRUE + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/expired/unidentified + init_hide_identity = TRUE + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/serotrotium/unidentified + init_hide_identity = TRUE + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/cryptobiolin/unidentified + init_hide_identity = TRUE + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/mindbreaker/unidentified + init_hide_identity = TRUE + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/psilocybin/unidentified + init_hide_identity = TRUE + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/soporific/unidentified + init_hide_identity = TRUE + +// The very bad. +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/cyanide/unidentified + init_hide_identity = TRUE + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/impedrezene/unidentified + init_hide_identity = TRUE + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/mutagen/unidentified + init_hide_identity = TRUE + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/defective_nanites/unidentified + init_hide_identity = TRUE + +/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/contaminated/unidentified + init_hide_identity = TRUE \ No newline at end of file diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index d40fc51610..d2b4dc149d 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -16,13 +16,13 @@ attackby(obj/item/weapon/W as obj, mob/user as mob) return -/obj/structure/reagent_dispensers/New() +/obj/structure/reagent_dispensers/Initialize() var/datum/reagents/R = new/datum/reagents(5000) reagents = R R.my_atom = src if (!possible_transfer_amounts) src.verbs -= /obj/structure/reagent_dispensers/verb/set_APTFT - ..() + . = ..() /obj/structure/reagent_dispensers/examine(mob/user) if(!..(user, 2)) @@ -73,8 +73,8 @@ icon_state = "watertank" amount_per_transfer_from_this = 10 -/obj/structure/reagent_dispensers/watertank/New() - ..() +/obj/structure/reagent_dispensers/watertank/Initialize() + . = ..() reagents.add_reagent("water", 1000) /obj/structure/reagent_dispensers/watertank/high @@ -82,8 +82,8 @@ desc = "A highly-pressurized water tank made to hold vast amounts of water.." icon_state = "watertank_high" -/obj/structure/reagent_dispensers/watertank/high/New() - ..() +/obj/structure/reagent_dispensers/watertank/high/Initialize() + . = ..() reagents.add_reagent("water", 4000) /obj/structure/reagent_dispensers/fueltank @@ -95,8 +95,8 @@ var/modded = 0 var/obj/item/device/assembly_holder/rig = null -/obj/structure/reagent_dispensers/fueltank/New() - ..() +/obj/structure/reagent_dispensers/fueltank/Initialize() + . = ..() reagents.add_reagent("fuel",1000) /obj/structure/reagent_dispensers/fueltank/examine(mob/user) @@ -205,8 +205,8 @@ density = 0 amount_per_transfer_from_this = 45 -/obj/structure/reagent_dispensers/peppertank/New() - ..() +/obj/structure/reagent_dispensers/peppertank/Initialize() + . = ..() reagents.add_reagent("condensedcapsaicin",1000) @@ -227,8 +227,8 @@ cupholder = 1 cups = 10 -/obj/structure/reagent_dispensers/water_cooler/New() - ..() +/obj/structure/reagent_dispensers/water_cooler/Initialize() + . = ..() if(bottle) reagents.add_reagent("water",120) update_icon() @@ -352,8 +352,8 @@ icon_state = "beertankTEMP" amount_per_transfer_from_this = 10 -/obj/structure/reagent_dispensers/beerkeg/New() - ..() +/obj/structure/reagent_dispensers/beerkeg/Initialize() + . = ..() reagents.add_reagent("beer",1000) /obj/structure/reagent_dispensers/beerkeg/fakenuke @@ -370,8 +370,8 @@ amount_per_transfer_from_this = 10 anchored = 1 -/obj/structure/reagent_dispensers/virusfood/New() - ..() +/obj/structure/reagent_dispensers/virusfood/Initialize() + . = ..() reagents.add_reagent("virusfood", 1000) /obj/structure/reagent_dispensers/acid @@ -382,6 +382,6 @@ amount_per_transfer_from_this = 10 anchored = 1 -/obj/structure/reagent_dispensers/acid/New() - ..() +/obj/structure/reagent_dispensers/acid/Initialize() + . = ..() reagents.add_reagent("sacid", 1000) diff --git a/code/modules/recycling/conveyor2.dm b/code/modules/recycling/conveyor2.dm index d70e6e563d..428484ea66 100644 --- a/code/modules/recycling/conveyor2.dm +++ b/code/modules/recycling/conveyor2.dm @@ -1,3 +1,7 @@ +#define OFF 0 +#define FORWARDS 1 +#define BACKWARDS 2 + //conveyor2 is pretty much like the original, except it supports corners, but not diverters. //note that corner pieces transfer stuff clockwise when running forward, and anti-clockwise backwards. @@ -10,7 +14,7 @@ layer = ABOVE_TURF_LAYER anchored = 1 circuit = /obj/item/weapon/circuitboard/conveyor - var/operating = 0 // 1 if running forward, -1 if backwards, 0 if off + var/operating = OFF // 1 if running forward, -1 if backwards, 0 if off var/operable = 1 // true if can operate (no broken segments in this belt run) var/forwards // this is the default (forward) direction, set by the map dir var/backwards // hopefully self-explanatory @@ -23,7 +27,7 @@ id = "round_end_belt" // create a conveyor -/obj/machinery/conveyor/initialize(mapload, newdir, on = 0) +/obj/machinery/conveyor/Initialize(mapload, newdir, on = 0) . = ..() if(newdir) set_dir(newdir) @@ -36,7 +40,7 @@ backwards = turn(dir, 180) if(on) - operating = 1 + operating = FORWARDS setmove() component_parts = list() @@ -48,22 +52,23 @@ RefreshParts() /obj/machinery/conveyor/proc/setmove() - if(operating == 1) + if(operating == FORWARDS) movedir = forwards - else if(operating == -1) + else if(operating == BACKWARDS) movedir = backwards - else operating = 0 + else + operating = OFF update() /obj/machinery/conveyor/proc/update() if(stat & BROKEN) icon_state = "conveyor-broken" - operating = 0 + operating = OFF return if(!operable) - operating = 0 + operating = OFF if(stat & NOPOWER) - operating = 0 + operating = OFF icon_state = "conveyor[operating]" // machine process @@ -183,7 +188,7 @@ -/obj/machinery/conveyor_switch/initialize() +/obj/machinery/conveyor_switch/Initialize() ..() update() return INITIALIZE_HINT_LATELOAD diff --git a/code/modules/recycling/disposal-construction.dm b/code/modules/recycling/disposal-construction.dm index 8034b776b4..1743ee4c69 100644 --- a/code/modules/recycling/disposal-construction.dm +++ b/code/modules/recycling/disposal-construction.dm @@ -20,307 +20,299 @@ var/base_state = "pipe-s" // update iconstate and dpdir due to dir and type - proc/update() - var/flip = turn(dir, 180) - var/left = turn(dir, 90) - var/right = turn(dir, -90) +/obj/structure/disposalconstruct/proc/update() + var/flip = turn(dir, 180) + var/left = turn(dir, 90) + var/right = turn(dir, -90) - switch(ptype) - if(0) - base_state = "pipe-s" - dpdir = dir | flip - if(1) - base_state = "pipe-c" - dpdir = dir | right - if(2) - base_state = "pipe-j1" - dpdir = dir | right | flip - if(3) - base_state = "pipe-j2" - dpdir = dir | left | flip - if(4) - base_state = "pipe-y" - dpdir = dir | left | right - if(5) - base_state = "pipe-t" - dpdir = dir - // disposal bin has only one dir, thus we don't need to care about setting it - if(6) - if(anchored) - base_state = "disposal" - else - base_state = "condisposal" - - if(7) - base_state = "outlet" - dpdir = dir - - if(8) - base_state = "intake" - dpdir = dir - - if(9) - base_state = "pipe-j1s" - dpdir = dir | right | flip - - if(10) - base_state = "pipe-j2s" - dpdir = dir | left | flip + switch(ptype) + if(0) + base_state = "pipe-s" + dpdir = dir | flip + if(1) + base_state = "pipe-c" + dpdir = dir | right + if(2) + base_state = "pipe-j1" + dpdir = dir | right | flip + if(3) + base_state = "pipe-j2" + dpdir = dir | left | flip + if(4) + base_state = "pipe-y" + dpdir = dir | left | right + if(5) + base_state = "pipe-t" + dpdir = dir + // disposal bin has only one dir, thus we don't need to care about setting it + if(6) + if(anchored) + base_state = "disposal" + else + base_state = "condisposal" + if(7) + base_state = "outlet" + dpdir = dir + if(8) + base_state = "intake" + dpdir = dir + if(9) + base_state = "pipe-j1s" + dpdir = dir | right | flip + if(10) + base_state = "pipe-j2s" + dpdir = dir | left | flip ///// Z-Level stuff - if(11) - base_state = "pipe-u" - dpdir = dir - if(12) - base_state = "pipe-d" - dpdir = dir -///// Z-Level stuff - if(13) - base_state = "pipe-tagger" - dpdir = dir | flip - if(14) - base_state = "pipe-tagger-partial" - dpdir = dir | flip + if(11) + base_state = "pipe-u" + dpdir = dir + if(12) + base_state = "pipe-d" + dpdir = dir + if(13) + base_state = "pipe-tagger" + dpdir = dir | flip + if(14) + base_state = "pipe-tagger-partial" + dpdir = dir | flip ///// Z-Level stuff - if(!(ptype in list(6, 7, 8, 11, 12, 13, 14))) -///// Z-Level stuff - icon_state = "con[base_state]" - else - icon_state = base_state + if(!(ptype in list(6, 7, 8, 11, 12, 13, 14))) + icon_state = "con[base_state]" + else + icon_state = base_state - if(invisibility) // if invisible, fade icon - alpha = 128 - else - alpha = 255 - //otherwise burying half-finished pipes under floors causes them to half-fade + if(invisibility) // if invisible, fade icon + alpha = 128 + else + alpha = 255 + //otherwise burying half-finished pipes under floors causes them to half-fade - // hide called by levelupdate if turf intact status changes - // change visibility status and force update of icon - hide(var/intact) - invisibility = (intact && level==1) ? 101: 0 // hide if floor is intact - update() +// hide called by levelupdate if turf intact status changes +// change visibility status and force update of icon +/obj/structure/disposalconstruct/hide(var/intact) + invisibility = (intact && level==1) ? 101: 0 // hide if floor is intact + update() - // flip and rotate verbs - verb/rotate() - set category = "Object" - set name = "Rotate Pipe" - set src in view(1) +// flip and rotate verbs +/obj/structure/disposalconstruct/verb/rotate_clockwise() + set category = "Object" + set name = "Rotate Pipe Clockwise" + set src in view(1) - if(usr.stat) - return - - if(anchored) - to_chat(usr, "You must unfasten the pipe before rotating it.") - return - - set_dir(turn(dir, -90)) - update() - - verb/flip() - set category = "Object" - set name = "Flip Pipe" - set src in view(1) - if(usr.stat) - return - - if(anchored) - to_chat(usr, "You must unfasten the pipe before flipping it.") - return - - set_dir(turn(dir, 180)) - switch(ptype) - if(2) - ptype = 3 - if(3) - ptype = 2 - if(9) - ptype = 10 - if(10) - ptype = 9 - - update() - - // returns the type path of disposalpipe corresponding to this item dtype - proc/dpipetype() - switch(ptype) - if(0,1) - return /obj/structure/disposalpipe/segment - if(2,3,4) - return /obj/structure/disposalpipe/junction - if(5) - return /obj/structure/disposalpipe/trunk - if(6) - return /obj/machinery/disposal - if(7) - return /obj/structure/disposaloutlet - if(8) - return /obj/machinery/disposal/deliveryChute - if(9) - switch(subtype) - if(0) - return /obj/structure/disposalpipe/sortjunction - if(1) - return /obj/structure/disposalpipe/sortjunction/wildcard - if(2) - return /obj/structure/disposalpipe/sortjunction/untagged - if(10) - switch(subtype) - if(0) - return /obj/structure/disposalpipe/sortjunction/flipped - if(1) - return /obj/structure/disposalpipe/sortjunction/wildcard/flipped - if(2) - return /obj/structure/disposalpipe/sortjunction/untagged/flipped -///// Z-Level stuff - if(11) - return /obj/structure/disposalpipe/up - if(12) - return /obj/structure/disposalpipe/down -///// Z-Level stuff - if(13) - return /obj/structure/disposalpipe/tagger - if(14) - return /obj/structure/disposalpipe/tagger/partial + if(usr.stat) return + if(anchored) + to_chat(usr, "You must unfasten the pipe before rotating it.") + return + + src.set_dir(turn(src.dir, 270)) + update() + +/obj/structure/disposalconstruct/verb/flip() + set category = "Object" + set name = "Flip Pipe" + set src in view(1) + if(usr.stat) + return + + if(anchored) + to_chat(usr, "You must unfasten the pipe before flipping it.") + return + + set_dir(turn(dir, 180)) + switch(ptype) + if(2) + ptype = 3 + if(3) + ptype = 2 + if(9) + ptype = 10 + if(10) + ptype = 9 + + update() + +// returns the type path of disposalpipe corresponding to this item dtype +/obj/structure/disposalconstruct/proc/dpipetype() + switch(ptype) + if(0,1) + return /obj/structure/disposalpipe/segment + if(2,3,4) + return /obj/structure/disposalpipe/junction + if(5) + return /obj/structure/disposalpipe/trunk + if(6) + return /obj/machinery/disposal + if(7) + return /obj/structure/disposaloutlet + if(8) + return /obj/machinery/disposal/deliveryChute + if(9) + switch(subtype) + if(0) + return /obj/structure/disposalpipe/sortjunction + if(1) + return /obj/structure/disposalpipe/sortjunction/wildcard + if(2) + return /obj/structure/disposalpipe/sortjunction/untagged + if(10) + switch(subtype) + if(0) + return /obj/structure/disposalpipe/sortjunction/flipped + if(1) + return /obj/structure/disposalpipe/sortjunction/wildcard/flipped + if(2) + return /obj/structure/disposalpipe/sortjunction/untagged/flipped +///// Z-Level stuff + if(11) + return /obj/structure/disposalpipe/up + if(12) + return /obj/structure/disposalpipe/down + if(13) + return /obj/structure/disposalpipe/tagger + if(14) + return /obj/structure/disposalpipe/tagger/partial + return - // attackby item + +// attackby item +// wrench: (un)anchor +// weldingtool: convert to real pipe +/obj/structure/disposalconstruct/attackby(var/obj/item/I, var/mob/user) + var/nicetype = "pipe" + var/ispipe = 0 // Indicates if we should change the level of this pipe + src.add_fingerprint(user) + switch(ptype) + if(6) + nicetype = "disposal bin" + if(7) + nicetype = "disposal outlet" + if(8) + nicetype = "delivery chute" + if(9, 10) + switch(subtype) + if(0) + nicetype = "sorting pipe" + if(1) + nicetype = "wildcard sorting pipe" + if(2) + nicetype = "untagged sorting pipe" + ispipe = 1 + if(13) + nicetype = "tagging pipe" + ispipe = 1 + if(14) + nicetype = "partial tagging pipe" + ispipe = 1 + else + nicetype = "pipe" + ispipe = 1 + + var/turf/T = src.loc + if(!T.is_plating()) + to_chat(user, "You can only attach the [nicetype] if the floor plating is removed.") + return + + var/obj/structure/disposalpipe/CP = locate() in T + // wrench: (un)anchor - // weldingtool: convert to real pipe - - attackby(var/obj/item/I, var/mob/user) - var/nicetype = "pipe" - var/ispipe = 0 // Indicates if we should change the level of this pipe - src.add_fingerprint(user) - switch(ptype) - if(6) - nicetype = "disposal bin" - if(7) - nicetype = "disposal outlet" - if(8) - nicetype = "delivery chute" - if(9, 10) - switch(subtype) - if(0) - nicetype = "sorting pipe" - if(1) - nicetype = "wildcard sorting pipe" - if(2) - nicetype = "untagged sorting pipe" - ispipe = 1 - if(13) - nicetype = "tagging pipe" - ispipe = 1 - if(14) - nicetype = "partial tagging pipe" - ispipe = 1 + if(I.is_wrench()) + if(anchored) + anchored = 0 + if(ispipe) + level = 2 + density = 0 else - nicetype = "pipe" - ispipe = 1 - - var/turf/T = src.loc - if(!T.is_plating()) - to_chat(user, "You can only attach the [nicetype] if the floor plating is removed.") - return - - var/obj/structure/disposalpipe/CP = locate() in T - - if(I.is_wrench()) - if(anchored) - anchored = 0 - if(ispipe) - level = 2 - density = 0 - else - density = 1 - to_chat(user, "You detach the [nicetype] from the underfloor.") - else - if(ptype>=6 && ptype <= 8) // Disposal or outlet - if(CP) // There's something there - if(!istype(CP,/obj/structure/disposalpipe/trunk)) - to_chat(user, "The [nicetype] requires a trunk underneath it in order to work.") - return - else // Nothing under, fuck. + density = 1 + to_chat(user, "You detach the [nicetype] from the underfloor.") + else + if(ptype>=6 && ptype <= 8) // Disposal or outlet + if(CP) // There's something there + if(!istype(CP,/obj/structure/disposalpipe/trunk)) to_chat(user, "The [nicetype] requires a trunk underneath it in order to work.") return - else - if(CP) - update() - var/pdir = CP.dpdir - if(istype(CP, /obj/structure/disposalpipe/broken)) - pdir = CP.dir - if(pdir & dpdir) - to_chat(user, "There is already a [nicetype] at that location.") - return - - anchored = 1 - if(ispipe) - level = 1 // We don't want disposal bins to disappear under the floors - density = 0 - else - density = 1 // We don't want disposal bins or outlets to go density 0 - to_chat(user, "You attach the [nicetype] to the underfloor.") - playsound(loc, I.usesound, 100, 1) - update() - - else if(istype(I, /obj/item/weapon/weldingtool)) - if(anchored) - var/obj/item/weapon/weldingtool/W = I - if(W.remove_fuel(0,user)) - playsound(src, W.usesound, 100, 1) - to_chat(user, "Welding the [nicetype] in place.") - if(do_after(user, 20 * W.toolspeed)) - if(!src || !W.isOn()) return - to_chat(user, "The [nicetype] has been welded in place!") - update() // TODO: Make this neat - if(ispipe) // Pipe - - var/pipetype = dpipetype() - var/obj/structure/disposalpipe/P = new pipetype(src.loc) - src.transfer_fingerprints_to(P) - P.base_icon_state = base_state - P.set_dir(dir) - P.dpdir = dpdir - P.updateicon() - - //Needs some special treatment ;) - if(ptype==9 || ptype==10) - var/obj/structure/disposalpipe/sortjunction/SortP = P - SortP.sortType = sortType - SortP.updatedir() - SortP.updatedesc() - SortP.updatename() - - else if(ptype==6) // Disposal bin - var/obj/machinery/disposal/P = new /obj/machinery/disposal(src.loc) - src.transfer_fingerprints_to(P) - P.mode = 0 // start with pump off - - else if(ptype==7) // Disposal outlet - - var/obj/structure/disposaloutlet/P = new /obj/structure/disposaloutlet(src.loc) - src.transfer_fingerprints_to(P) - P.set_dir(dir) - var/obj/structure/disposalpipe/trunk/Trunk = CP - Trunk.linked = P - - else if(ptype==8) // Disposal outlet - - var/obj/machinery/disposal/deliveryChute/P = new /obj/machinery/disposal/deliveryChute(src.loc) - src.transfer_fingerprints_to(P) - P.set_dir(dir) - - qdel(src) - return - else - to_chat(user, "You need more welding fuel to complete this task.") + else // Nothing under, fuck. + to_chat(user, "The [nicetype] requires a trunk underneath it in order to work.") return else - to_chat(user, "You need to attach it to the plating first!") + if(CP) + update() + var/pdir = CP.dpdir + if(istype(CP, /obj/structure/disposalpipe/broken)) + pdir = CP.dir + if(pdir & dpdir) + to_chat(user, "There is already a [nicetype] at that location.") + return + + anchored = 1 + if(ispipe) + level = 1 // We don't want disposal bins to disappear under the floors + density = 0 + else + density = 1 // We don't want disposal bins or outlets to go density 0 + to_chat(user, "You attach the [nicetype] to the underfloor.") + playsound(loc, I.usesound, 100, 1) + update() + + // weldingtool: convert to real pipe + else if(istype(I, /obj/item/weapon/weldingtool)) + if(anchored) + var/obj/item/weapon/weldingtool/W = I + if(W.remove_fuel(0,user)) + playsound(src, W.usesound, 100, 1) + to_chat(user, "Welding the [nicetype] in place.") + if(do_after(user, 20 * W.toolspeed)) + if(!src || !W.isOn()) return + to_chat(user, "The [nicetype] has been welded in place!") + update() // TODO: Make this neat + if(ispipe) // Pipe + + var/pipetype = dpipetype() + var/obj/structure/disposalpipe/P = new pipetype(src.loc) + src.transfer_fingerprints_to(P) + P.base_icon_state = base_state + P.set_dir(dir) + P.dpdir = dpdir + P.updateicon() + + //Needs some special treatment ;) + if(ptype==9 || ptype==10) + var/obj/structure/disposalpipe/sortjunction/SortP = P + SortP.sortType = sortType + SortP.updatedir() + SortP.updatedesc() + SortP.updatename() + + else if(ptype==6) // Disposal bin + var/obj/machinery/disposal/P = new /obj/machinery/disposal(src.loc) + src.transfer_fingerprints_to(P) + P.mode = 0 // start with pump off + + else if(ptype==7) // Disposal outlet + var/obj/structure/disposaloutlet/P = new /obj/structure/disposaloutlet(src.loc) + src.transfer_fingerprints_to(P) + P.set_dir(dir) + var/obj/structure/disposalpipe/trunk/Trunk = CP + Trunk.linked = P + + else if(ptype==8) // Disposal outlet + var/obj/machinery/disposal/deliveryChute/P = new /obj/machinery/disposal/deliveryChute(src.loc) + src.transfer_fingerprints_to(P) + P.set_dir(dir) + + qdel(src) + return + else + to_chat(user, "You need more welding fuel to complete this task.") return + else + to_chat(user, "You need to attach it to the plating first!") + return /obj/structure/disposalconstruct/hides_under_flooring() if(anchored) diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index 10157157fa..7dcca19a7b 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -467,7 +467,7 @@ H.vent_gas(loc) qdel(H) -/obj/machinery/disposal/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) +/obj/machinery/disposal/CanPass(atom/movable/mover, turf/target, height, air_group) if(istype(mover, /obj/item/projectile)) return 1 if (istype(mover,/obj/item) && mover.throwing) diff --git a/code/modules/research/circuitprinter.dm b/code/modules/research/circuitprinter.dm index 850df76645..70ca9692f3 100644 --- a/code/modules/research/circuitprinter.dm +++ b/code/modules/research/circuitprinter.dm @@ -22,8 +22,8 @@ using metal and glass, it uses glass and reagents (usually sulphuric acid). idle_power_usage = 30 active_power_usage = 2500 -/obj/machinery/r_n_d/circuit_imprinter/New() - ..() +/obj/machinery/r_n_d/circuit_imprinter/Initialize() + . = ..() component_parts = list() component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) component_parts += new /obj/item/weapon/stock_parts/manipulator(src) diff --git a/code/modules/research/message_server.dm b/code/modules/research/message_server.dm index 19afc0f564..75fb5fff2a 100644 --- a/code/modules/research/message_server.dm +++ b/code/modules/research/message_server.dm @@ -169,6 +169,11 @@ var/global/list/obj/machinery/message_server/message_servers = list() var/value var/details +/datum/feedback_variable/vv_edit_var(var_name, var_value) + if(var_name == NAMEOF(src, variable) || var_name == NAMEOF(src, value) || var_name == NAMEOF(src, details)) + return FALSE + return ..() + /datum/feedback_variable/New(var/param_variable,var/param_value = 0) variable = param_variable value = param_value @@ -319,6 +324,15 @@ var/obj/machinery/blackbox_recorder/blackbox feedback_set_details("round_end","[time2text(world.realtime)]") //This one MUST be the last one that gets set. +/obj/machinery/blackbox_recorder/vv_edit_var(var_name, var_value) + var/static/list/blocked_vars //hacky as fuck kill me + if(!blocked_vars) + var/obj/machinery/M = new + var/list/parent_vars = M.vars.Copy() + blocked_vars = vars.Copy() - parent_vars + if(var_name in blocked_vars) + return FALSE + return ..() //This proc is only to be called at round end. /obj/machinery/blackbox_recorder/proc/save_all_data_to_sql() diff --git a/code/modules/research/protolathe.dm b/code/modules/research/protolathe.dm index 1e1d54f9bc..bea555b70c 100644 --- a/code/modules/research/protolathe.dm +++ b/code/modules/research/protolathe.dm @@ -17,8 +17,8 @@ materials = list(DEFAULT_WALL_MATERIAL = 0, "glass" = 0, "plastic" = 0, "gold" = 0, "silver" = 0, "osmium" = 0, "phoron" = 0, "uranium" = 0, "diamond" = 0) -/obj/machinery/r_n_d/protolathe/New() - ..() +/obj/machinery/r_n_d/protolathe/Initialize() + . = ..() component_parts = list() component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index 3e8732c423..594788f9a4 100755 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -113,7 +113,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, S.update_connections() break -/obj/machinery/computer/rdconsole/initialize() +/obj/machinery/computer/rdconsole/Initialize() SyncRDevices() . = ..() @@ -642,7 +642,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, continue var/temp_dat for(var/M in D.materials) - temp_dat += ", [D.materials[M]] [CallMaterialName(M)]" + temp_dat += ", [D.materials[M]*linked_imprinter.mat_efficiency] [CallMaterialName(M)]" for(var/T in D.chemicals) temp_dat += ", [D.chemicals[T]*linked_imprinter.mat_efficiency] [CallReagentName(T)]" if(temp_dat) diff --git a/code/modules/research/server.dm b/code/modules/research/server.dm index a1ad322ba4..7e736980db 100644 --- a/code/modules/research/server.dm +++ b/code/modules/research/server.dm @@ -33,7 +33,7 @@ tot_rating += SP.rating idle_power_usage /= max(1, tot_rating) -/obj/machinery/r_n_d/server/initialize() +/obj/machinery/r_n_d/server/Initialize() . = ..() if(!files) files = new /datum/research(src) diff --git a/code/modules/resleeving/computers.dm b/code/modules/resleeving/computers.dm index b688bf6dca..854b9dd097 100644 --- a/code/modules/resleeving/computers.dm +++ b/code/modules/resleeving/computers.dm @@ -16,7 +16,7 @@ var/synthetic_capable = 1 var/obj/item/weapon/disk/transcore/disk -/obj/machinery/computer/transhuman/resleeving/initialize() +/obj/machinery/computer/transhuman/resleeving/Initialize() . = ..() updatemodules() @@ -198,7 +198,7 @@ data["coredumped"] = SStranscore.core_dumped data["emergency"] = disk ? 1 : 0 - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "sleever.tmpl", "Resleeving Control Console", 400, 450) ui.set_initial_data(data) @@ -375,7 +375,7 @@ menu = href_list["menu"] temp = "" - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) add_fingerprint(usr) // In here because only relevant to computer diff --git a/code/modules/resleeving/designer.dm b/code/modules/resleeving/designer.dm index b8d049da1c..d4dadb2945 100644 --- a/code/modules/resleeving/designer.dm +++ b/code/modules/resleeving/designer.dm @@ -141,7 +141,7 @@ data["disk"] = disk ? 1 : 0 data["diskStored"] = disk && disk.stored ? 1 : 0 - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "body_designer.tmpl", "Body Design Console", 400, 600) ui.set_initial_data(data) @@ -310,7 +310,7 @@ if(href_list["size_multiplier"]) var/new_size = input(user, "Choose your character's size, ranging from 25% to 200%", "Character Preference") as num|null - if(new_size && IsInRange(new_size,25,200)) + if(new_size && ISINRANGE(new_size,25,200)) active_br.sizemult = (new_size/100) preview_icon = null return 1 diff --git a/code/modules/resleeving/infomorph.dm b/code/modules/resleeving/infomorph.dm index 906873408d..6166bb6456 100644 --- a/code/modules/resleeving/infomorph.dm +++ b/code/modules/resleeving/infomorph.dm @@ -187,7 +187,7 @@ var/list/infomorph_emotions = list( medicalActive1 = null medicalActive2 = null medical_cannotfind = 0 - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) usr << "You reset your record-viewing software." /* @@ -509,7 +509,7 @@ var/global/list/default_infomorph_software = list() data["emotions"] = emotions data["current_emotion"] = card.current_emotion - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open, key_state) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open, key_state) if (!ui) ui = new(user, src, ui_key, "pai_interface.tmpl", "Card Software Interface", 450, 600, state = key_state) ui.set_initial_data(data) diff --git a/code/modules/resleeving/infomorph_software.dm b/code/modules/resleeving/infomorph_software.dm index 21a51d91e3..bb5b7fc870 100644 --- a/code/modules/resleeving/infomorph_software.dm +++ b/code/modules/resleeving/infomorph_software.dm @@ -34,7 +34,7 @@ // This is dumb, but NanoUI breaks if it has no data to send data["manifest"] = PDA_Manifest - ui = GLOB.nanomanager.try_update_ui(user, user, id, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) if(!ui) // Don't copy-paste this unless you're making a pAI software module! ui = new(user, user, id, "pai_manifest.tmpl", "Crew Manifest", 450, 600) @@ -66,7 +66,7 @@ data["medical"] = M ? M.fields : null data["could_not_find"] = user.medical_cannotfind - ui = GLOB.nanomanager.try_update_ui(user, user, id, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) if(!ui) // Don't copy-paste this unless you're making a pAI software module! ui = new(user, user, id, "pai_medrecords.tmpl", "Medical Records", 450, 600) @@ -120,7 +120,7 @@ data["security"] = S ? S.fields : null data["could_not_find"] = user.security_cannotfind - ui = GLOB.nanomanager.try_update_ui(user, user, id, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) if(!ui) // Don't copy-paste this unless you're making a pAI software module! ui = new(user, user, id, "pai_secrecords.tmpl", "Security Records", 450, 600) @@ -170,7 +170,7 @@ data["progress_b"] = user.hackprogress % 10 data["aborted"] = user.hack_aborted - ui = GLOB.nanomanager.try_update_ui(user, user, id, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) if(!ui) // Don't copy-paste this unless you're making a pAI software module! ui = new(user, user, id, "pai_doorjack.tmpl", "Door Jack", 300, 150) @@ -270,7 +270,7 @@ gases[++gases.len] = gas data["gas"] = gases - ui = GLOB.nanomanager.try_update_ui(user, user, id, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) if(!ui) // Don't copy-paste this unless you're making a pAI software module! ui = new(user, user, id, "pai_atmosphere.tmpl", "Atmosphere Sensor", 350, 300) @@ -314,7 +314,7 @@ data["frequency"] = format_frequency(user.sradio.frequency) data["code"] = user.sradio.code - ui = GLOB.nanomanager.try_update_ui(user, user, id, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, user, id, ui, data, force_open) if(!ui) // Don't copy-paste this unless you're making a pAI software module! ui = new(user, user, id, "pai_signaller.tmpl", "Signaller", 320, 150) diff --git a/code/modules/resleeving/machines.dm b/code/modules/resleeving/machines.dm index 69f0cfebd1..8db26fe03f 100644 --- a/code/modules/resleeving/machines.dm +++ b/code/modules/resleeving/machines.dm @@ -9,7 +9,7 @@ circuit = /obj/item/weapon/circuitboard/transhuman_clonepod //A full version of the pod -/obj/machinery/clonepod/transhuman/full/initialize() +/obj/machinery/clonepod/transhuman/full/Initialize() . = ..() for(var/i = 1 to container_limit) containers += new /obj/item/weapon/reagent_containers/glass/bottle/biomass(src) @@ -138,7 +138,7 @@ occupant.adjustCloneLoss(-2 * heal_rate) //Premature clones may have brain damage. - occupant.adjustBrainLoss(-(ceil(0.5*heal_rate))) + occupant.adjustBrainLoss(-(CEILING((0.5*heal_rate), 1))) //So clones don't die of oxyloss in a running pod. if(occupant.reagents.get_reagent_amount("inaprovaline") < 30) diff --git a/code/modules/rogueminer_vr/asteroid.dm b/code/modules/rogueminer_vr/asteroid.dm index 4267f5b174..fec6c4aa67 100644 --- a/code/modules/rogueminer_vr/asteroid.dm +++ b/code/modules/rogueminer_vr/asteroid.dm @@ -113,7 +113,7 @@ New() ..() spot_add(2,2,/obj/random/cargopod) //EXTRA loot! - spot_add(2,2,/mob/living/simple_animal/hostile/alien) //GRRR + spot_add(2,2,/mob/living/simple_mob/animal/space/alien) //GRRR //Longer cargo container for higher difficulties /datum/rogue/asteroid/predef/cargo_large @@ -147,4 +147,4 @@ spot_add(4,3,/obj/random/cargopod) //Right loot if(prob(30)) - spot_add(3,3,/mob/living/simple_animal/hostile/alien) //And maybe a friend. \ No newline at end of file + spot_add(3,3,/mob/living/simple_mob/animal/space/alien) //And maybe a friend. diff --git a/code/modules/rogueminer_vr/controller.dm b/code/modules/rogueminer_vr/controller.dm index 5ea0fafed1..881b66cab5 100644 --- a/code/modules/rogueminer_vr/controller.dm +++ b/code/modules/rogueminer_vr/controller.dm @@ -54,22 +54,22 @@ var/datum/controller/rogue/rm_controller = new() ) ///// Monster Lists ///// - var/mobs = list( - "tier1" = list(/mob/living/simple_animal/hostile/carp, /mob/living/simple_animal/hostile/goose), + var/mobs = list(/* + "tier1" = list(/mob/living/simple_mob/hostile/carp, /mob/living/simple_mob/hostile/goose), - "tier2" = list(/mob/living/simple_animal/hostile/carp, /mob/living/simple_animal/hostile/goose), + "tier2" = list(/mob/living/simple_mob/hostile/carp, /mob/living/simple_mob/hostile/goose), - "tier3" = list(/mob/living/simple_animal/hostile/carp, /mob/living/simple_animal/hostile/goose, - /mob/living/simple_animal/hostile/bear, /mob/living/simple_animal/hostile/carp/strong), + "tier3" = list(/mob/living/simple_mob/hostile/carp, /mob/living/simple_mob/hostile/goose, + /mob/living/simple_mob/hostile/bear, /mob/living/simple_mob/hostile/carp/strong), - "tier4" = list(/mob/living/simple_animal/hostile/carp, /mob/living/simple_animal/hostile/goose, /mob/living/simple_animal/hostile/bear, - /mob/living/simple_animal/hostile/carp/strong, /mob/living/simple_animal/hostile/carp/pike/weak), + "tier4" = list(/mob/living/simple_mob/hostile/carp, /mob/living/simple_mob/hostile/goose, /mob/living/simple_mob/hostile/bear, + /mob/living/simple_mob/hostile/carp/strong, /mob/living/simple_mob/hostile/carp/pike/weak), - "tier5" = list(/mob/living/simple_animal/hostile/carp, /mob/living/simple_animal/hostile/bear, /mob/living/simple_animal/hostile/carp/pike/weak, - /mob/living/simple_animal/hostile/carp/strong, /mob/living/simple_animal/hostile/carp/pike), + "tier5" = list(/mob/living/simple_mob/hostile/carp, /mob/living/simple_mob/hostile/bear, /mob/living/simple_mob/hostile/carp/pike/weak, + /mob/living/simple_mob/hostile/carp/strong, /mob/living/simple_mob/hostile/carp/pike), - "tier6" = list(/mob/living/simple_animal/hostile/bear, /mob/living/simple_animal/hostile/carp/strong, - /mob/living/simple_animal/hostile/carp/pike, /mob/living/simple_animal/hostile/carp/pike/weak) + "tier6" = list(/mob/living/simple_mob/hostile/bear, /mob/living/simple_mob/hostile/carp/strong, + /mob/living/simple_mob/hostile/carp/pike, /mob/living/simple_mob/hostile/carp/pike/weak)*/ //VORESTATION AI TEMPORARY REMOVAL ) /datum/controller/rogue/New() diff --git a/code/modules/rogueminer_vr/zone_console.dm b/code/modules/rogueminer_vr/zone_console.dm index b9813715e8..17ea54c564 100644 --- a/code/modules/rogueminer_vr/zone_console.dm +++ b/code/modules/rogueminer_vr/zone_console.dm @@ -23,7 +23,7 @@ var/legacy_zone = 0 //Disable scanning and whatnot. var/obj/machinery/computer/shuttle_control/belter/shuttle_control -/obj/machinery/computer/roguezones/initialize() +/obj/machinery/computer/roguezones/Initialize() . = ..() shuttle_control = locate(/obj/machinery/computer/shuttle_control/belter) @@ -79,7 +79,7 @@ // Permit emergency recall of the shuttle if its stranded in a zone with just dead people. data["can_recall_shuttle"] = (shuttle_control && shuttle_control.z == BELT_Z && !curZoneOccupied) - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "zone_console.tmpl", src.name, 600, 400) ui.set_initial_data(data) @@ -100,7 +100,7 @@ failsafe_shuttle_recall() src.add_fingerprint(usr) - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) /obj/machinery/computer/roguezones/proc/scan_for_new_zone() if(scanning) return diff --git a/code/modules/shieldgen/directional_shield.dm b/code/modules/shieldgen/directional_shield.dm index 519edcea07..279580ce89 100644 --- a/code/modules/shieldgen/directional_shield.dm +++ b/code/modules/shieldgen/directional_shield.dm @@ -88,6 +88,8 @@ but allow those projectiles to leave the shield from the inside. Blocking too many damaging projectiles will cause the shield to fail." icon = 'icons/obj/device.dmi' icon_state = "signmaker_sec" + light_range = 4 + light_power = 4 var/active = FALSE // If it's on. var/shield_health = 400 // How much damage the shield blocks before breaking. This is a shared health pool for all shields attached to this projector. var/max_shield_health = 400 // Ditto. This is fairly high, but shields are really big, you can't miss them, and laser carbines pump out so much hurt. @@ -100,14 +102,14 @@ var/low_color = "#FF0000" // Color the shield will drift towards as health is lowered. Deep red. /obj/item/shield_projector/New() - processing_objects += src + START_PROCESSING(SSobj, src) if(always_on) create_shields() ..() /obj/item/shield_projector/Destroy() destroy_shields() - processing_objects -= src + STOP_PROCESSING(SSobj, src) return ..() /obj/item/shield_projector/proc/create_shield(var/newloc, var/new_dir) @@ -152,7 +154,7 @@ // Makes shields become gradually more red as the projector's health decreases. /obj/item/shield_projector/proc/update_shield_colors() // This is done at the projector instead of the shields themselves to avoid needing to calculate this more than once every update. - var/lerp_weight = shield_health / max_shield_health + var/interpolate_weight = shield_health / max_shield_health var/list/low_color_list = hex2rgb(low_color) var/low_r = low_color_list[1] @@ -164,12 +166,14 @@ var/high_g = high_color_list[2] var/high_b = high_color_list[3] - var/new_r = Interpolate(low_r, high_r, weight = lerp_weight) - var/new_g = Interpolate(low_g, high_g, weight = lerp_weight) - var/new_b = Interpolate(low_b, high_b, weight = lerp_weight) + var/new_r = LERP(low_r, high_r, interpolate_weight) + var/new_g = LERP(low_g, high_g, interpolate_weight) + var/new_b = LERP(low_b, high_b, interpolate_weight) var/new_color = rgb(new_r, new_g, new_b) + set_light(light_range, light_power, new_color) + // Now deploy the new color to all the shields. for(var/obj/effect/directional_shield/S in active_shields) S.update_color(new_color) diff --git a/code/modules/shieldgen/energy_field.dm b/code/modules/shieldgen/energy_field.dm index 023d5fee95..1c5b8d2965 100644 --- a/code/modules/shieldgen/energy_field.dm +++ b/code/modules/shieldgen/energy_field.dm @@ -53,6 +53,12 @@ user.setClickCooldown(user.get_attack_speed(W)) ..() +/obj/effect/energy_field/attack_generic(mob/user, damage) + if(damage) + adjust_strength(-damage / 20) + user.do_attack_animation(src) + user.setClickCooldown(user.get_attack_speed()) + /obj/effect/energy_field/attack_hand(var/mob/living/user) impact_effect(3) // Harmless, but still produces the 'impact' effect. ..() diff --git a/code/modules/shieldgen/handheld_defuser.dm b/code/modules/shieldgen/handheld_defuser.dm index d65a0060a8..7b4fdd786b 100644 --- a/code/modules/shieldgen/handheld_defuser.dm +++ b/code/modules/shieldgen/handheld_defuser.dm @@ -16,7 +16,7 @@ qdel(cell) cell = null if(enabled) - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) . = ..() /obj/item/weapon/shield_diffuser/get_cell() @@ -42,9 +42,9 @@ enabled = !enabled update_icon() if(enabled) - processing_objects.Add(src) + START_PROCESSING(SSobj, src) else - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) to_chat(usr, "You turn \the [src] [enabled ? "on" : "off"].") /obj/item/weapon/shield_diffuser/examine() diff --git a/code/modules/shieldgen/shield_capacitor.dm b/code/modules/shieldgen/shield_capacitor.dm index ae51705984..4006a1cedf 100644 --- a/code/modules/shieldgen/shield_capacitor.dm +++ b/code/modules/shieldgen/shield_capacitor.dm @@ -28,7 +28,7 @@ /obj/machinery/shield_capacitor/emag_act(var/remaining_charges, var/mob/user) if(prob(75)) src.locked = !src.locked - user << "Controls are now [src.locked ? "locked." : "unlocked."]" + to_chat(user, "Controls are now [src.locked ? "locked." : "unlocked."]") . = 1 updateDialog() var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread @@ -41,10 +41,10 @@ var/obj/item/weapon/card/id/C = W if(access_captain in C.access || access_security in C.access || access_engine in C.access) src.locked = !src.locked - user << "Controls are now [src.locked ? "locked." : "unlocked."]" + to_chat(user, "Controls are now [src.locked ? "locked." : "unlocked."]") updateDialog() else - user << "Access denied." + to_chat(user, "Access denied.") else if(W.is_wrench()) src.anchored = !src.anchored playsound(src, W.usesound, 75, 1) @@ -127,7 +127,7 @@ return if( href_list["toggle"] ) if(!active && !anchored) - usr << "The [src] needs to be firmly secured to the floor first." + to_chat(usr, "The [src] needs to be firmly secured to the floor first.") return active = !active if( href_list["charge_rate"] ) @@ -141,13 +141,14 @@ else ..() -/obj/machinery/shield_capacitor/verb/rotate() - set name = "Rotate capacitor clockwise" +/obj/machinery/shield_capacitor/verb/rotate_clockwise() + set name = "Rotate Capacitor Clockwise" set category = "Object" set src in oview(1) if (src.anchored) - usr << "It is fastened to the floor!" + to_chat(usr, "It is fastened to the floor!") return + src.set_dir(turn(src.dir, 270)) - return + return \ No newline at end of file diff --git a/code/modules/shieldgen/shield_gen.dm b/code/modules/shieldgen/shield_gen.dm index de6d535a05..0562bbd9ff 100644 --- a/code/modules/shieldgen/shield_gen.dm +++ b/code/modules/shieldgen/shield_gen.dm @@ -29,7 +29,7 @@ desc = "A machine that generates a field of energy optimized for blocking meteorites when activated. This version comes with a more efficent shield matrix." energy_conversion_rate = 0.0012 -/obj/machinery/shield_gen/initialize() +/obj/machinery/shield_gen/Initialize() if(anchored) for(var/obj/machinery/shield_capacitor/cap in range(1, src)) if(!cap.anchored) @@ -42,7 +42,7 @@ return ..() /obj/machinery/shield_gen/Destroy() - QDEL_NULL_LIST(field) + QDEL_LIST_NULL(field) return ..() /obj/machinery/shield_gen/emag_act(var/remaining_charges, var/mob/user) diff --git a/code/modules/shuttles/escape_pods.dm b/code/modules/shuttles/escape_pods.dm index 43cb6a5d94..60c1e4bd0d 100644 --- a/code/modules/shuttles/escape_pods.dm +++ b/code/modules/shuttles/escape_pods.dm @@ -55,7 +55,7 @@ "is_armed" = pod.arming_controller.armed, ) - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "escape_pod_console.tmpl", name, 470, 290) @@ -83,7 +83,7 @@ /obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod_berth name = "escape pod berth controller" -/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod_berth/initialize() +/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod_berth/Initialize() . = ..() docking_program = new/datum/computer/file/embedded_program/docking/simple/escape_pod(src) program = docking_program @@ -102,7 +102,7 @@ "armed" = armed, ) - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "escape_pod_berth_console.tmpl", name, 470, 290) diff --git a/code/modules/shuttles/shuttle.dm b/code/modules/shuttles/shuttle.dm index 080f21a524..4ce211ee72 100644 --- a/code/modules/shuttles/shuttle.dm +++ b/code/modules/shuttles/shuttle.dm @@ -37,7 +37,7 @@ supply_controller.shuttle = null . = ..() -/datum/shuttle/proc/process() +/datum/shuttle/process() return /datum/shuttle/proc/init_docking_controllers() @@ -208,13 +208,14 @@ for(var/turf/T in dstturfs) var/turf/D = locate(T.x, throwy - 1, T.z) - for(var/I in T) - if(istype(I,/mob/living)) - var/mob/living/L = I - L.gib() - else if(istype(I,/obj)) - var/obj/O = I - O.forceMove(D) + for(var/atom/movable/AM as mob|obj in T) + AM.Move(D) + + for(var/mob/living/carbon/bug in destination) + bug.gib() + + for(var/mob/living/simple_mob/pest in destination) + pest.gib() origin.move_contents_to(destination, direction=direction) diff --git a/code/modules/shuttles/shuttle_console.dm b/code/modules/shuttles/shuttle_console.dm index 01924be412..3d5422f4f1 100644 --- a/code/modules/shuttles/shuttle_console.dm +++ b/code/modules/shuttles/shuttle_console.dm @@ -57,7 +57,7 @@ "can_force" = shuttle.can_force(), ) - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "shuttle_control_console.tmpl", "[shuttle_tag] Shuttle Control", 470, 310) diff --git a/code/modules/shuttles/shuttle_emergency.dm b/code/modules/shuttles/shuttle_emergency.dm index 7db9ae2b62..86b8e29809 100644 --- a/code/modules/shuttles/shuttle_emergency.dm +++ b/code/modules/shuttles/shuttle_emergency.dm @@ -233,7 +233,7 @@ "user" = debug? user : null, ) - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "escape_shuttle_control_console.tmpl", "Shuttle Control", 470, 420) diff --git a/code/modules/shuttles/shuttles_web.dm b/code/modules/shuttles/shuttles_web.dm index c6233d48a0..3726ce23cd 100644 --- a/code/modules/shuttles/shuttles_web.dm +++ b/code/modules/shuttles/shuttles_web.dm @@ -88,7 +88,7 @@ if(autopilot_delay % 10 == 0) // Every ten ticks. var/seconds_left = autopilot_delay * 2 if(seconds_left >= 60) // A minute - var/minutes_left = Floor(seconds_left / 60) + var/minutes_left = FLOOR(seconds_left / 60, 1) seconds_left = seconds_left % 60 autopilot_say("Departing in [minutes_left] minute\s[seconds_left ? ", [seconds_left] seconds":""].") else @@ -162,7 +162,7 @@ var/list/my_doors //Should be list("id_tag" = "Pretty Door Name", ...) var/list/my_sensors //Should be list("id_tag" = "Pretty Sensor Name", ...) -/obj/machinery/computer/shuttle_control/web/initialize() +/obj/machinery/computer/shuttle_control/web/Initialize() . = ..() var/area/my_area = get_area(src) if(my_doors) @@ -350,7 +350,7 @@ "sensors" = sensors ) - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if(!ui) ui = new(user, src, ui_key, "flight.tmpl", "[shuttle.visible_name] Flight Computer", 500, 500) @@ -472,7 +472,7 @@ var/shuttle_name //Text name of the shuttle to connect to var/list/destinations //Make sure this STARTS with a destination that builds a route to one that always exists as an anchor. -/obj/shuttle_connector/initialize() +/obj/shuttle_connector/Initialize() . = ..() SSshuttles.OnDocksInitialized(CALLBACK(src, .proc/setup_routes)) diff --git a/code/modules/spells/aoe_turf/summons.dm b/code/modules/spells/aoe_turf/summons.dm index e8769d8537..f8a6b4094a 100644 --- a/code/modules/spells/aoe_turf/summons.dm +++ b/code/modules/spells/aoe_turf/summons.dm @@ -20,7 +20,7 @@ invocation_type = SpI_SHOUT range = 1 - summon_type = list(/mob/living/simple_animal/hostile/carp) + summon_type = list(/mob/living/simple_mob/animal/space/carp) hud_state = "wiz_carp" @@ -36,6 +36,6 @@ summon_amt = 10 range = 3 - summon_type = list(/mob/living/simple_animal/hostile/creature/vore) // Vorestation Edit + summon_type = list(/mob/living/simple_mob/creature) hud_state = "wiz_creature" \ No newline at end of file diff --git a/code/modules/spells/spell_code.dm b/code/modules/spells/spell_code.dm index afd9bfdfa3..3415ad0ead 100644 --- a/code/modules/spells/spell_code.dm +++ b/code/modules/spells/spell_code.dm @@ -64,7 +64,7 @@ var/list/spells = typesof(/spell) //needed for the badmin verb for now //still_recharging_msg = "[name] is still recharging." charge_counter = charge_max -/spell/proc/process() +/spell/process() spawn while(charge_counter < charge_max) charge_counter++ sleep(1) @@ -198,10 +198,10 @@ var/list/spells = typesof(/spell) //needed for the badmin verb for now if(findNullRod(T)) return 0 - if(istype(user, /mob/living/simple_animal) && holder == user) - var/mob/living/simple_animal/SA = user - if(SA.purge) - SA << "The nullrod's power interferes with your own!" + if(istype(user, /mob/living/simple_mob) && holder == user) + var/mob/living/simple_mob/SM = user + if(SM.purge) + SM << "The nullrod's power interferes with your own!" return 0 if(!src.check_charge(skipcharge, user)) //sees if we can cast based on charges alone diff --git a/code/modules/spells/spell_projectile.dm b/code/modules/spells/spell_projectile.dm index 07adda0081..01e7d163fa 100644 --- a/code/modules/spells/spell_projectile.dm +++ b/code/modules/spells/spell_projectile.dm @@ -7,7 +7,7 @@ var/spell/targeted/projectile/carried penetrating = 0 - kill_count = 10 //set by the duration of the spell + range = 10 //set by the duration of the spell var/proj_trail = 0 //if it leaves a trail var/proj_trail_lifespan = 0 //deciseconds diff --git a/code/modules/spells/spellbook.dm b/code/modules/spells/spellbook.dm index 515453f6a3..1f41ce9e3d 100644 --- a/code/modules/spells/spellbook.dm +++ b/code/modules/spells/spellbook.dm @@ -221,11 +221,6 @@ new /obj/item/clothing/head/helmet/space/void/wizard(get_turf(H)) temp = "You have purchased a suit of wizard armor." max_uses-- - if("staffanimation") - feedback_add_details("wizard_spell_learned","SA") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells - new /obj/item/weapon/gun/energy/staff/animate(get_turf(H)) - temp = "You have purchased a staff of animation." - max_uses-- 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)) diff --git a/code/modules/spells/targeted/projectile/projectile.dm b/code/modules/spells/targeted/projectile/projectile.dm index fef039d191..7181d3c140 100644 --- a/code/modules/spells/targeted/projectile/projectile.dm +++ b/code/modules/spells/targeted/projectile/projectile.dm @@ -29,12 +29,13 @@ If the spell_projectile is seeking, it will update its target every process and projectile.shot_from = user //fired from the user projectile.hitscan = !proj_step_delay - projectile.step_delay = proj_step_delay + projectile.speed = proj_step_delay if(istype(projectile, /obj/item/projectile/spell_projectile)) var/obj/item/projectile/spell_projectile/SP = projectile SP.carried = src //casting is magical - projectile.launch(target, target_zone="chest") - return + projectile.def_zone = check_zone("chest") + projectile.old_style_target(target) + projectile.fire() /spell/targeted/projectile/proc/choose_prox_targets(mob/user = usr, var/atom/movable/spell_holder) var/list/targets = list() diff --git a/code/modules/surgery/implant.dm b/code/modules/surgery/implant.dm index ae0e7610a7..58a322febd 100644 --- a/code/modules/surgery/implant.dm +++ b/code/modules/surgery/implant.dm @@ -207,8 +207,8 @@ BITSET(target.hud_updateflag, IMPLOYAL_HUD) //Handle possessive brain borers. - if(istype(obj,/mob/living/simple_animal/borer)) - var/mob/living/simple_animal/borer/worm = obj + if(istype(obj,/mob/living/simple_mob/animal/borer)) + var/mob/living/simple_mob/animal/borer/worm = obj if(worm.controlling) target.release_control() worm.detatch() diff --git a/code/modules/surgery/slimes.dm b/code/modules/surgery/slimes.dm index ad4c413c8e..e049349f83 100644 --- a/code/modules/surgery/slimes.dm +++ b/code/modules/surgery/slimes.dm @@ -3,10 +3,10 @@ ////////////////////////////////////////////////////////////////// /datum/surgery_step/slime - is_valid_target(mob/living/simple_animal/slime/target) - return istype(target, /mob/living/simple_animal/slime/) + is_valid_target(mob/living/simple_mob/slime/target) + return istype(target, /mob/living/simple_mob/slime/) -/datum/surgery_step/slime/can_use(mob/living/user, mob/living/simple_animal/slime/target, target_zone, obj/item/tool) +/datum/surgery_step/slime/can_use(mob/living/user, mob/living/simple_mob/slime/target, target_zone, obj/item/tool) return target.stat == 2 @@ -21,19 +21,19 @@ min_duration = 30 max_duration = 50 -/datum/surgery_step/slime/cut_flesh/can_use(mob/living/user, mob/living/simple_animal/slime/target, target_zone, obj/item/tool) +/datum/surgery_step/slime/cut_flesh/can_use(mob/living/user, mob/living/simple_mob/slime/target, target_zone, obj/item/tool) return ..() && istype(target) && target.core_removal_stage == 0 -/datum/surgery_step/slime/cut_flesh/begin_step(mob/user, mob/living/simple_animal/slime/target, target_zone, obj/item/tool) +/datum/surgery_step/slime/cut_flesh/begin_step(mob/user, mob/living/simple_mob/slime/target, target_zone, obj/item/tool) user.visible_message("[user] starts cutting through [target]'s flesh with \the [tool].", \ "You start cutting through [target]'s flesh with \the [tool].") -/datum/surgery_step/slime/cut_flesh/end_step(mob/living/user, mob/living/simple_animal/slime/target, target_zone, obj/item/tool) +/datum/surgery_step/slime/cut_flesh/end_step(mob/living/user, mob/living/simple_mob/slime/target, target_zone, obj/item/tool) user.visible_message("[user] cuts through [target]'s flesh with \the [tool].", \ "You cut through [target]'s flesh with \the [tool], revealing its silky innards.") target.core_removal_stage = 1 -/datum/surgery_step/slime/cut_flesh/fail_step(mob/living/user, mob/living/simple_animal/slime/target, target_zone, obj/item/tool) +/datum/surgery_step/slime/cut_flesh/fail_step(mob/living/user, mob/living/simple_mob/slime/target, target_zone, obj/item/tool) user.visible_message("[user]'s hand slips, tearing [target]'s flesh with \the [tool]!", \ "Your hand slips, tearing [target]'s flesh with \the [tool]!") @@ -49,19 +49,19 @@ min_duration = 30 max_duration = 50 -/datum/surgery_step/slime/cut_innards/can_use(mob/living/user, mob/living/simple_animal/slime/target, target_zone, obj/item/tool) +/datum/surgery_step/slime/cut_innards/can_use(mob/living/user, mob/living/simple_mob/slime/target, target_zone, obj/item/tool) return ..() && istype(target) && target.core_removal_stage == 1 -/datum/surgery_step/slime/cut_innards/begin_step(mob/user, mob/living/simple_animal/slime/target, target_zone, obj/item/tool) +/datum/surgery_step/slime/cut_innards/begin_step(mob/user, mob/living/simple_mob/slime/target, target_zone, obj/item/tool) user.visible_message("[user] starts cutting [target]'s silky innards apart with \the [tool].", \ "You start cutting [target]'s silky innards apart with \the [tool].") -/datum/surgery_step/slime/cut_innards/end_step(mob/living/user, mob/living/simple_animal/slime/target, target_zone, obj/item/tool) +/datum/surgery_step/slime/cut_innards/end_step(mob/living/user, mob/living/simple_mob/slime/target, target_zone, obj/item/tool) user.visible_message("[user] cuts [target]'s innards apart with \the [tool], exposing the cores.", \ "You cut [target]'s innards apart with \the [tool], exposing the cores.") target.core_removal_stage = 2 -/datum/surgery_step/slime/cut_innards/fail_step(mob/living/user, mob/living/simple_animal/slime/target, target_zone, obj/item/tool) +/datum/surgery_step/slime/cut_innards/fail_step(mob/living/user, mob/living/simple_mob/slime/target, target_zone, obj/item/tool) user.visible_message("[user]'s hand slips, tearing [target]'s innards with \the [tool]!", \ "Your hand slips, tearing [target]'s innards with \the [tool]!") @@ -76,14 +76,14 @@ min_duration = 50 max_duration = 70 -/datum/surgery_step/slime/saw_core/can_use(mob/living/user, mob/living/simple_animal/slime/target, target_zone, obj/item/tool) +/datum/surgery_step/slime/saw_core/can_use(mob/living/user, mob/living/simple_mob/slime/target, target_zone, obj/item/tool) return ..() && (istype(target) && target.core_removal_stage == 2 && target.cores > 0) //This is being passed a human as target, unsure why. -/datum/surgery_step/slime/saw_core/begin_step(mob/user, mob/living/simple_animal/slime/target, target_zone, obj/item/tool) +/datum/surgery_step/slime/saw_core/begin_step(mob/user, mob/living/simple_mob/slime/target, target_zone, obj/item/tool) user.visible_message("[user] starts cutting out one of [target]'s cores with \the [tool].", \ "You start cutting out one of [target]'s cores with \the [tool].") -/datum/surgery_step/slime/saw_core/end_step(mob/living/user, mob/living/simple_animal/slime/target, target_zone, obj/item/tool) +/datum/surgery_step/slime/saw_core/end_step(mob/living/user, mob/living/simple_mob/slime/target, target_zone, obj/item/tool) target.cores-- user.visible_message("[user] cuts out one of [target]'s cores with \the [tool].",, \ "You cut out one of [target]'s cores with \the [tool]. [target.cores] cores left.") @@ -94,7 +94,7 @@ target.icon_state = "slime extracted" -/datum/surgery_step/slime/saw_core/fail_step(mob/living/user, mob/living/simple_animal/slime/target, target_zone, obj/item/tool) +/datum/surgery_step/slime/saw_core/fail_step(mob/living/user, mob/living/simple_mob/slime/target, target_zone, obj/item/tool) var/datum/gender/T = gender_datums[user.get_visible_gender()] user.visible_message("[user]'s hand slips, causing [T.him] to miss the core!", \ "Your hand slips, causing you to miss the core!") \ No newline at end of file diff --git a/code/modules/tables/interactions.dm b/code/modules/tables/interactions.dm index 19764b2997..f3b953ac25 100644 --- a/code/modules/tables/interactions.dm +++ b/code/modules/tables/interactions.dm @@ -1,5 +1,5 @@ -/obj/structure/table/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) +/obj/structure/table/CanPass(atom/movable/mover, turf/target, height, air_group) if(air_group || (height==0)) return 1 if(istype(mover,/obj/item/projectile)) return (check_cover(mover,target)) diff --git a/code/modules/tables/tables.dm b/code/modules/tables/tables.dm index 6d20b619b0..17d2a8e114 100644 --- a/code/modules/tables/tables.dm +++ b/code/modules/tables/tables.dm @@ -59,7 +59,7 @@ var/list/table_icon_cache = list() /obj/structure/table/blob_act() take_damage(100) -/obj/structure/table/initialize() +/obj/structure/table/Initialize() . = ..() // One table per turf. diff --git a/code/modules/telesci/quantum_pad.dm b/code/modules/telesci/quantum_pad.dm index 1d3eed0785..f36c05ade4 100644 --- a/code/modules/telesci/quantum_pad.dm +++ b/code/modules/telesci/quantum_pad.dm @@ -20,7 +20,7 @@ var/map_pad_id = "" as text //what's my name var/map_pad_link_id = "" as text //who's my friend -/obj/machinery/power/quantumpad/initialize() +/obj/machinery/power/quantumpad/Initialize() . = ..() default_apply_parts() connect_to_network() diff --git a/code/modules/telesci/telesci_computer.dm b/code/modules/telesci/telesci_computer.dm index a80e8e71e9..b2cc345b8c 100644 --- a/code/modules/telesci/telesci_computer.dm +++ b/code/modules/telesci/telesci_computer.dm @@ -40,7 +40,7 @@ ..() user << "There are [crystals.len ? crystals.len : "no"] bluespace crystal\s in the crystal slots." -/obj/machinery/computer/telescience/initialize() +/obj/machinery/computer/telescience/Initialize() . = ..() recalibrate() for(var/i = 1; i <= starting_crystals; i++) @@ -73,7 +73,7 @@ return ..() /obj/machinery/computer/telescience/proc/get_max_allowed_distance() - return Floor(crystals.len * telepad.efficiency * powerCoefficient) + return FLOOR((crystals.len * telepad.efficiency * powerCoefficient), 1) /obj/machinery/computer/telescience/attack_ai(mob/user) src.attack_hand(user) @@ -97,7 +97,7 @@ data["cooldown"] = max(0, min(100, round(teleport_cooldown - world.time) / 10)) data["crystalCount"] = crystals.len data["maxCrystals"] = max_crystals - data["maxPossibleDistance"] = Floor(max_crystals * powerCoefficient * 6); // max efficiency is 6 + data["maxPossibleDistance"] = FLOOR((max_crystals * powerCoefficient * 6), 1); // max efficiency is 6 data["maxAllowedDistance"] = get_max_allowed_distance() data["distance"] = distance @@ -116,7 +116,7 @@ data["lastTeleData"]["distance"] = last_tele_data.distance data["lastTeleData"]["time"] = last_tele_data.time - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "telescience_console.tmpl", src.name, 400, 450) ui.set_initial_data(data) @@ -151,12 +151,12 @@ sparks() if(telepad) var/L = get_turf(telepad) - var/blocked = list(/mob/living/simple_animal/hostile) - var/list/hostiles = typesof(/mob/living/simple_animal/hostile) - blocked + var/blocked = list(/mob/living/simple_mob/hostile) + var/list/hostiles = typesof(/mob/living/simple_mob/hostile) - blocked playsound(L, 'sound/effects/phasein.ogg', 100, 1, extrarange = 3, falloff = 5) for(var/i in 1 to rand(1,4)) var/chosen = pick(hostiles) - var/mob/living/simple_animal/hostile/H = new chosen + var/mob/living/simple_mob/hostile/H = new chosen H.forceMove(L) return if(99) @@ -173,7 +173,7 @@ return if(telepad) - var/trueDistance = Clamp(distance + distance_off, 1, get_max_allowed_distance()) + var/trueDistance = CLAMP(distance + distance_off, 1, get_max_allowed_distance()) var/trueRotation = rotation + rotation_off var/datum/projectile_data/proj_data = simple_projectile_trajectory(telepad.x, telepad.y, trueRotation, trueDistance) @@ -283,7 +283,7 @@ updateDialog() /obj/machinery/computer/telescience/proc/teleport(mob/user) - distance = Clamp(distance, 0, get_max_allowed_distance()) + distance = CLAMP(distance, 0, get_max_allowed_distance()) if(rotation == null || distance == null || z_co == null) temp_msg = "ERROR!
      Set a distance, rotation and sector." return @@ -320,15 +320,15 @@ var/new_rot = input("Please input desired bearing in degrees.", name, rotation) as num if(..()) // Check after we input a value, as they could've moved after they entered something return - rotation = Clamp(new_rot, -900, 900) + rotation = CLAMP(new_rot, -900, 900) rotation = round(rotation, 0.01) if(href_list["setdistance"]) var/new_pow = input("Please input desired distance in meters.", name, rotation) as num if(..()) // Check after we input a value, as they could've moved after they entered something return - distance = Clamp(new_pow, 1, get_max_allowed_distance()) - distance = Floor(distance) + distance = CLAMP(new_pow, 1, get_max_allowed_distance()) + distance = FLOOR(distance, 1) if(href_list["setz"]) var/new_z = text2num(href_list["setz"]) diff --git a/code/modules/tension/tension.dm b/code/modules/tension/tension.dm index 913f1d2dff..82151a7e78 100644 --- a/code/modules/tension/tension.dm +++ b/code/modules/tension/tension.dm @@ -9,35 +9,42 @@ /atom/movable/proc/guess_threat_level(var/mob/living/threatened) return 0 -/mob/living/simple_animal +/mob/living/simple_mob var/threat_level = null // Set this if you want an explicit danger rating. -/mob/living/simple_animal/guess_threat_level(var/mob/living/threatened) +/mob/living/simple_mob/guess_threat_level(var/mob/living/threatened) if(threat_level) // If they have a predefined number, use it. return threat_level // Otherwise we need to guess how scary this thing is. var/threat_guess = 0 // First lets consider their attack ability. + var/will_point_blank = FALSE + if(has_AI()) + will_point_blank = ai_holder.pointblank + var/potential_damage = 0 - if(!ranged) //Melee damage. + if(!projectiletype || ( get_dist(src, threatened >= 1) && !will_point_blank ) ) // Melee damage. potential_damage = (melee_damage_lower + melee_damage_upper) / 2 + + // Treat potential_damage as estimated DPS. If the enemy attacks twice as fast as usual, it will double the number. + potential_damage *= 1 SECOND / (base_attack_cooldown + melee_attack_delay) else - if(projectiletype) - var/obj/item/projectile/P = new projectiletype(src) - if(P.nodamage || P.taser_effect) // Tasers are somewhat less scary. - potential_damage = P.agony / 2 - else - potential_damage = P.damage - if(P.damage_type == HALLOSS) // Not sure if any projectiles do this, but can't be too safe. - potential_damage /= 2 - // Rubber bullets, I guess. - potential_damage += P.agony / 2 + var/obj/item/projectile/P = new projectiletype(src) + if(P.nodamage || P.taser_effect) // Tasers are somewhat less scary. + potential_damage = P.agony / 2 + else + potential_damage = P.damage + if(P.damage_type == HALLOSS) // Not sure if any projectiles do this, but can't be too safe. + potential_damage /= 2 + // Rubber bullets, I guess. + potential_damage += P.agony / 2 + qdel(P) - if(rapid) // This makes them shoot three times per cycle. - potential_damage *= 3 + potential_damage *= 1 SECOND / (base_attack_cooldown + ranged_attack_delay) + + // Special attacks are ultra-specific to the mob so a generic threat assessment isn't really possible. - qdel(P) threat_guess += potential_damage // Then consider their defense. @@ -50,11 +57,12 @@ return 0 -/mob/living/simple_animal/get_threat(var/mob/living/threatened) +/mob/living/simple_mob/get_threat(var/mob/living/threatened) . = ..() - if(!hostile) - return 0 // Can't hurt anyone. + if(has_AI()) + if(!ai_holder.hostile) + return 0 // Can't hurt anyone. if(incapacitated(INCAPACITATION_DISABLED)) return 0 // Can't currently hurt you if it's stunned. @@ -86,7 +94,7 @@ // Handle ability to harm. // Being five tiles away from some spiders is a lot less scary than being in melee range of five spiders at once. - if(!ranged) + if(!projectiletype) threat /= max(get_dist(src, threatened), 1) return threat diff --git a/code/modules/tooltip/tooltip.dm b/code/modules/tooltip/tooltip.dm index 1b03157e83..3f7fb158aa 100644 --- a/code/modules/tooltip/tooltip.dm +++ b/code/modules/tooltip/tooltip.dm @@ -87,7 +87,7 @@ Notes: /datum/tooltip/proc/hide() if (queueHide) - schedule_task_with_source_in(1, src, .proc/do_hide) + addtimer(CALLBACK(src, .proc/do_hide), 1) else do_hide() diff --git a/code/modules/turbolift/turbolift_map.dm b/code/modules/turbolift/turbolift_map.dm index 8614f0df85..44082654c6 100644 --- a/code/modules/turbolift/turbolift_map.dm +++ b/code/modules/turbolift/turbolift_map.dm @@ -22,7 +22,7 @@ turbolifts += src ..() -/obj/turbolift_map_holder/initialize() +/obj/turbolift_map_holder/Initialize() . = ..() // Create our system controller. var/datum/turbolift/lift = new() @@ -32,11 +32,11 @@ var/uy = y var/uz = z var/udir = dir - forceMove(null) + moveToNullspace() // These modifiers are used in relation to the origin // to place the system control panels and doors. - var/make_walls = isnull(wall_type) ? FALSE : TRUE + var/make_walls = isnull(wall_type) ? FALSE : TRUE //VOREStation addition: Wall-less elevator var/int_panel_x var/int_panel_y var/ext_panel_x @@ -59,71 +59,71 @@ if(NORTH) - int_panel_x = ux + Floor(lift_size_x/2) - int_panel_y = uy + (make_walls ? 1 : 0) + int_panel_x = ux + FLOOR(lift_size_x/2, 1) + int_panel_y = uy + (make_walls ? 1 : 0) //VOREStation edit: Wall-less elevator ext_panel_x = ux ext_panel_y = ey + 2 door_x1 = ux + 1 - door_y1 = ey + (make_walls ? 0 : 1) + door_y1 = ey + (make_walls ? 0 : 1) //VOREStation edit: Wall-less elevator door_x2 = ex - 1 door_y2 = ey + 1 - light_x1 = ux + (make_walls ? 1 : 0) - light_y1 = uy + (make_walls ? 1 : 0) - light_x2 = ux + lift_size_x - (make_walls ? 1 : 0) - light_y2 = uy + (make_walls ? 1 : 0) + light_x1 = ux + (make_walls ? 1 : 0) //VOREStation edit: Wall-less elevator + light_y1 = uy + (make_walls ? 1 : 0) //VOREStation edit: Wall-less elevator + light_x2 = ux + lift_size_x - (make_walls ? 1 : 0) //VOREStation edit: Wall-less elevator + light_y2 = uy + (make_walls ? 1 : 0) //VOREStation edit: Wall-less elevator if(SOUTH) - int_panel_x = ux + Floor(lift_size_x/2) - int_panel_y = ey - (make_walls ? 1 : 0) + int_panel_x = ux + FLOOR(lift_size_x/2, 1) + int_panel_y = ey - (make_walls ? 1 : 0) //VOREStation edit: Wall-less elevator ext_panel_x = ex ext_panel_y = uy - 2 door_x1 = ux + 1 door_y1 = uy - 1 door_x2 = ex - 1 - door_y2 = uy - (make_walls ? 0 : 1) + door_y2 = uy - (make_walls ? 0 : 1) //VOREStation edit: Wall-less elevator - light_x1 = ux + (make_walls ? 1 : 0) - light_y1 = uy + (make_walls ? 2 : 1) - light_x2 = ux + lift_size_x - (make_walls ? 1 : 0) - light_y2 = uy + lift_size_y - (make_walls ? 1 : 0) + light_x1 = ux + (make_walls ? 1 : 0) //VOREStation edit: Wall-less elevator + light_y1 = uy + (make_walls ? 2 : 1) //VOREStation edit: Wall-less elevator + light_x2 = ux + lift_size_x - (make_walls ? 1 : 0) //VOREStation edit: Wall-less elevator + light_y2 = uy + lift_size_y - (make_walls ? 1 : 0) //VOREStation edit: Wall-less elevator if(EAST) - int_panel_x = ux + (make_walls ? 1 : 0) - int_panel_y = uy + Floor(lift_size_y/2) + int_panel_x = ux+(make_walls ? 1 : 0) //VOREStation edit: Wall-less elevator + int_panel_y = uy + FLOOR(lift_size_y/2, 1) ext_panel_x = ex+2 ext_panel_y = ey - door_x1 = ex + (make_walls ? 0 : 1) + door_x1 = ex + (make_walls ? 0 : 1) //VOREStation edit: Wall-less elevator door_y1 = uy + 1 door_x2 = ex + 1 door_y2 = ey - 1 - light_x1 = ux + (make_walls ? 1 : 0) - light_y1 = uy + (make_walls ? 1 : 0) - light_x2 = ux + (make_walls ? 1 : 0) - light_y2 = uy + lift_size_x - (make_walls ? 1 : 0) + light_x1 = ux + (make_walls ? 1 : 0) //VOREStation edit: Wall-less elevator + light_y1 = uy + (make_walls ? 1 : 0) //VOREStation edit: Wall-less elevator + light_x2 = ux + (make_walls ? 1 : 0) //VOREStation edit: Wall-less elevator + light_y2 = uy + lift_size_x - (make_walls ? 1 : 0) //VOREStation edit: Wall-less elevator if(WEST) - int_panel_x = ex - (make_walls ? 1 : 0) - int_panel_y = uy + Floor(lift_size_y/2) + int_panel_x = ex-(make_walls ? 1 : 0) //VOREStation edit: Wall-less elevator + int_panel_y = uy + FLOOR(lift_size_y/2, 1) ext_panel_x = ux-2 ext_panel_y = uy door_x1 = ux - 1 door_y1 = uy + 1 - door_x2 = ux - (make_walls ? 0 : 1) + door_x2 = ux - (make_walls ? 0 : 1) //VOREStation edit: Wall-less elevator door_y2 = ey - 1 - light_x1 = ux + lift_size_x - (make_walls ? 1 : 0) - light_y1 = uy + (make_walls ? 1 : 0) - light_x2 = ux + lift_size_x - (make_walls ? 1 : 0) - light_y2 = uy + lift_size_y - (make_walls ? 1 : 0) + light_x1 = ux + lift_size_x - (make_walls ? 1 : 0) //VOREStation edit: Wall-less elevator + light_y1 = uy + (make_walls ? 1 : 0) //VOREStation edit: Wall-less elevator + light_x2 = ux + lift_size_x - (make_walls ? 1 : 0) //VOREStation edit: Wall-less elevator + light_y2 = uy + lift_size_y - (make_walls ? 1 : 0) //VOREStation edit: Wall-less elevator // Generate each floor and store it in the controller datum. for(var/cz = uz;cz<=ez;cz++) @@ -146,7 +146,7 @@ // Update path appropriately if needed. var/swap_to = /turf/simulated/open if(cz == uz) // Elevator. - if(wall_type && (tx == ux || ty == uy || tx == ex || ty == ey) && !(tx >= door_x1 && tx <= door_x2 && ty >= door_y1 && ty <= door_y2)) + if(wall_type && (tx == ux || ty == uy || tx == ex || ty == ey) && !(tx >= door_x1 && tx <= door_x2 && ty >= door_y1 && ty <= door_y2)) //VOREStation edit: Wall-less elevator swap_to = wall_type else swap_to = floor_type diff --git a/code/modules/vehicles/train.dm b/code/modules/vehicles/train.dm index 6db4400f81..c66bfee0c4 100644 --- a/code/modules/vehicles/train.dm +++ b/code/modules/vehicles/train.dm @@ -22,7 +22,7 @@ //------------------------------------------- // Standard procs //------------------------------------------- -/obj/vehicle/train/initialize() +/obj/vehicle/train/Initialize() . = ..() for(var/obj/vehicle/train/T in orange(1, src)) latch(T) diff --git a/code/modules/vehicles/vehicle.dm b/code/modules/vehicles/vehicle.dm index cac6065b64..1bef7d41ea 100644 --- a/code/modules/vehicles/vehicle.dm +++ b/code/modules/vehicles/vehicle.dm @@ -164,6 +164,10 @@ ..() healthcheck() +/obj/vehicle/proc/adjust_health(amount) + health = between(0, health + amount, maxhealth) + healthcheck() + /obj/vehicle/ex_act(severity) switch(severity) if(1.0) diff --git a/code/modules/ventcrawl/ventcrawl.dm b/code/modules/ventcrawl/ventcrawl.dm index 1a4271050d..a306caea19 100644 --- a/code/modules/ventcrawl/ventcrawl.dm +++ b/code/modules/ventcrawl/ventcrawl.dm @@ -9,10 +9,11 @@ var/list/ventcrawl_machinery = list( /obj/item/device/radio/borg, /obj/item/weapon/holder, /obj/machinery/camera, - /mob/living/simple_animal/borer, - /obj/belly, //VOREStation Edit, + /obj/belly, /obj/screen ) + //VOREStation Edit : added /obj/belly, to this list, travis is complaining about this in his indentation check + //mob/living/simple_mob/borer, //VORESTATION AI TEMPORARY REMOVAL REPLACE BACK IN LIST WHEN RESOLVED //VOREStation Edit /mob/living/var/list/icon/pipes_shown = list() /mob/living/var/last_played_vent @@ -38,7 +39,7 @@ var/list/ventcrawl_machinery = list( add_ventcrawl(loc) client.screen += global_hud.centermarker -/mob/living/simple_animal/slime/can_ventcrawl() +/mob/living/simple_mob/slime/xenobio/can_ventcrawl() if(victim) to_chat(src, "You cannot ventcrawl while feeding.") return FALSE @@ -70,11 +71,6 @@ var/list/ventcrawl_machinery = list( return 1 return ..() -/mob/living/simple_animal/spiderbot/is_allowed_vent_crawl_item(var/obj/item/carried_item) - if(carried_item == held_item) - return 1 - return ..() - /mob/living/proc/ventcrawl_carry() for(var/atom/A in contents) if(!is_allowed_vent_crawl_item(A)) diff --git a/code/modules/virus2/admin.dm b/code/modules/virus2/admin.dm index dc10bc85f9..e2821db1a9 100644 --- a/code/modules/virus2/admin.dm +++ b/code/modules/virus2/admin.dm @@ -15,7 +15,7 @@ return 1 -/datum/disease2/disease/get_view_variables_header() +/datum/disease2/disease/vv_get_header() . = list() for(var/datum/disease2/effectholder/E in effects) . += "[E.stage]: [E.effect.name]" diff --git a/code/modules/virus2/centrifuge.dm b/code/modules/virus2/centrifuge.dm index 73e43be704..433a26977b 100644 --- a/code/modules/virus2/centrifuge.dm +++ b/code/modules/virus2/centrifuge.dm @@ -26,7 +26,7 @@ O.loc = src user.visible_message("[user] adds \a [O] to \the [src]!", "You add \a [O] to \the [src]!") - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) src.attack_hand(user) @@ -74,7 +74,7 @@ data["antibodies"] = antigens2string(A.data["antibodies"], none=null) data["is_antibody_sample"] = 1 - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "isolation_centrifuge.tmpl", src.name, 400, 500) ui.set_initial_data(data) @@ -98,7 +98,7 @@ if (..()) return 1 var/mob/user = usr - var/datum/nanoui/ui = GLOB.nanomanager.get_open_ui(user, src, "main") + var/datum/nanoui/ui = SSnanoui.get_open_ui(user, src, "main") src.add_fingerprint(user) @@ -160,7 +160,7 @@ sample.reagents.remove_reagent("blood", amt) sample.reagents.add_reagent("antibodies", amt, data) - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) update_icon() ping("\The [src] pings, \"Antibody isolated.\"") @@ -170,7 +170,7 @@ dish.virus2 = virus2 virus2 = null - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) update_icon() ping("\The [src] pings, \"Pathogen isolated.\"") diff --git a/code/modules/virus2/diseasesplicer.dm b/code/modules/virus2/diseasesplicer.dm index b5db3fa96a..95657498a0 100644 --- a/code/modules/virus2/diseasesplicer.dm +++ b/code/modules/virus2/diseasesplicer.dm @@ -81,7 +81,7 @@ else data["info"] = "No dish loaded." - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "disease_splicer.tmpl", src.name, 400, 600) ui.set_initial_data(data) @@ -95,12 +95,12 @@ scanning -= 1 if(!scanning) ping("\The [src] pings, \"Analysis complete.\"") - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) if(splicing) splicing -= 1 if(!splicing) ping("\The [src] pings, \"Splicing operation complete.\"") - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) if(burning) burning -= 1 if(!burning) @@ -122,13 +122,13 @@ d.species = species_buffer ping("\The [src] pings, \"Backup disk saved.\"") - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) /obj/machinery/computer/diseasesplicer/Topic(href, href_list) if(..()) return 1 var/mob/user = usr - var/datum/nanoui/ui = GLOB.nanomanager.get_open_ui(user, src, "main") + var/datum/nanoui/ui = SSnanoui.get_open_ui(user, src, "main") src.add_fingerprint(user) diff --git a/code/modules/virus2/dishincubator.dm b/code/modules/virus2/dishincubator.dm index 3ecad1d691..379d7ef533 100644 --- a/code/modules/virus2/dishincubator.dm +++ b/code/modules/virus2/dishincubator.dm @@ -29,7 +29,7 @@ O.loc = src user.visible_message("[user] adds \a [O] to \the [src]!", "You add \a [O] to \the [src]!") - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) src.attack_hand(user) return @@ -45,7 +45,7 @@ O.loc = src user.visible_message("[user] adds \a [O] to \the [src]!", "You add \a [O] to \the [src]!") - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) src.attack_hand(user) @@ -85,7 +85,7 @@ for (var/ID in virus) data["blood_already_infected"] = virus[ID] - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "dish_incubator.tmpl", src.name, 400, 600) ui.set_initial_data(data) @@ -104,7 +104,7 @@ foodsupply -= 1 dish.growth += 3 - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) if(radiation) if(radiation > 50 & prob(5)) @@ -117,24 +117,24 @@ else if(prob(5)) dish.virus2.minormutate() radiation -= 1 - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) if(toxins && prob(5)) dish.virus2.infectionchance -= 1 - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) if(toxins > 50) dish.growth = 0 dish.virus2 = null - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) else if(!dish) on = 0 icon_state = "incubator" - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) if(beaker) if(foodsupply < 100 && beaker.reagents.remove_reagent("virusfood",5)) if(foodsupply + 10 <= 100) foodsupply += 10 - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) if (locate(/datum/reagent/toxin) in beaker.reagents.reagent_list && toxins < 100) for(var/datum/reagent/toxin/T in beaker.reagents.reagent_list) @@ -143,13 +143,13 @@ if(toxins > 100) toxins = 100 break - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) /obj/machinery/disease2/incubator/Topic(href, href_list) if (..()) return 1 var/mob/user = usr - var/datum/nanoui/ui = GLOB.nanomanager.get_open_ui(user, src, "main") + var/datum/nanoui/ui = SSnanoui.get_open_ui(user, src, "main") src.add_fingerprint(user) diff --git a/code/modules/virus2/effect.dm b/code/modules/virus2/effect.dm index d7db2633ad..c4ea02b873 100644 --- a/code/modules/virus2/effect.dm +++ b/code/modules/virus2/effect.dm @@ -354,7 +354,7 @@ data = pick("bicaridine", "kelotane", "anti_toxin", "inaprovaline", "space_drugs", "sugar", "tramadol", "dexalin", "cryptobiolin", "impedrezene", "hyperzine", "ethylredoxrazine", "mindbreaker", "glucose") - var/datum/reagent/R = chemical_reagents_list[data] + var/datum/reagent/R = SSchemistry.chemical_reagents[data] name = "[initial(name)] ([initial(R.name)])" /datum/disease2/effect/chem_synthesis/activate(var/mob/living/carbon/mob,var/multiplier) diff --git a/code/modules/virus2/isolator.dm b/code/modules/virus2/isolator.dm index 8fa61e173b..da2c543fc8 100644 --- a/code/modules/virus2/isolator.dm +++ b/code/modules/virus2/isolator.dm @@ -43,7 +43,7 @@ S.loc = src user.visible_message("[user] adds \a [O] to \the [src]!", "You add \a [O] to \the [src]!") - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) update_icon() src.attack_hand(user) @@ -103,7 +103,7 @@ "name" = entry.fields["name"], \ "description" = replacetext(desc, "\n", "")) - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "pathogenic_isolator.tmpl", src.name, 400, 500) ui.set_initial_data(data) @@ -119,14 +119,14 @@ virus2 = null ping("\The [src] pings, \"Viral strain isolated.\"") - GLOB.nanomanager.update_uis(src) + SSnanoui.update_uis(src) update_icon() /obj/machinery/disease2/isolator/Topic(href, href_list) if (..()) return 1 var/mob/user = usr - var/datum/nanoui/ui = GLOB.nanomanager.get_open_ui(user, src, "main") + var/datum/nanoui/ui = SSnanoui.get_open_ui(user, src, "main") src.add_fingerprint(user) diff --git a/code/modules/vore/eating/living_vr.dm b/code/modules/vore/eating/living_vr.dm index 267b059141..26c03300a2 100644 --- a/code/modules/vore/eating/living_vr.dm +++ b/code/modules/vore/eating/living_vr.dm @@ -9,7 +9,7 @@ var/weight = 137 // Weight for mobs for weightgain system var/weight_gain = 1 // How fast you gain weight var/weight_loss = 0.5 // How fast you lose weight - var/egg_type = "egg" // Default egg type. + var/vore_egg_type = "egg" // Default egg type. var/feral = 0 // How feral the mob is, if at all. Does nothing for non xenochimera at the moment. var/reviving = 0 // Only used for creatures that have the xenochimera regen ability, so far. var/metabolism = 0.0015 @@ -71,12 +71,12 @@ // // Hide vore organs in contents // -/mob/living/view_variables_filter_contents(list/L) - . = ..() - var/len_before = L.len - L -= vore_organs - . += len_before - L.len - +///mob/living/view_variables_filter_contents(list/L) +// . = ..() +// var/len_before = L.len +// L -= vore_organs +// . += len_before - L.len +// // // Handle being clicked, perhaps with something to devour // @@ -331,12 +331,12 @@ return //Actual escaping forceMove(get_turf(src)) //Just move me up to the turf, let's not cascade through bellies, there's been a problem, let's just leave. - for(var/mob/living/simple_animal/SA in range(10)) + for(var/mob/living/simple_mob/SA in range(10)) SA.prey_excludes[src] = world.time log_and_message_admins("[key_name(src)] used the OOC escape button to get out of [key_name(B.owner)] ([B.owner ? "JMP" : "null"])") if(isanimal(B.owner)) - var/mob/living/simple_animal/SA = B.owner + var/mob/living/simple_mob/SA = B.owner SA.update_icons() //You're in a dogborg! diff --git a/code/modules/vore/eating/simple_animal_vr.dm b/code/modules/vore/eating/simple_animal_vr.dm index e8fd6390ed..faf51a1374 100644 --- a/code/modules/vore/eating/simple_animal_vr.dm +++ b/code/modules/vore/eating/simple_animal_vr.dm @@ -1,19 +1,19 @@ ///////////////////// Simple Animal ///////////////////// -/mob/living/simple_animal +/mob/living/simple_mob var/swallowTime = 30 //How long it takes to eat its prey in 1/10 of a second. The default is 3 seconds. var/list/prey_excludes = list() //For excluding people from being eaten. // -// Simple nom proc for if you get ckey'd into a simple_animal mob! Avoids grabs. +// Simple nom proc for if you get ckey'd into a simple_mob mob! Avoids grabs. // -/mob/living/simple_animal/proc/animal_nom(var/mob/living/T in living_mobs(1)) +/mob/living/simple_mob/proc/animal_nom(var/mob/living/T in living_mobs(1)) set name = "Animal Nom" set category = "IC" set desc = "Since you can't grab, you get a verb!" if (stat != CONSCIOUS) return - if (istype(src,/mob/living/simple_animal/mouse) && T.ckey == null) + if (istype(src,/mob/living/simple_mob/mouse) && T.ckey == null) return if (client && IsAdvancedToolUser()) to_chat(src,"Put your hands to good use instead!") @@ -25,7 +25,8 @@ // // Simple proc for animals to have their digestion toggled on/off externally // -/mob/living/simple_animal/verb/toggle_digestion() + +/mob/living/simple_mob/verb/toggle_digestion() set name = "Toggle Animal's Digestion" set desc = "Enables digestion on this mob for 20 minutes." set category = "OOC" @@ -34,7 +35,7 @@ var/mob/living/carbon/human/user = usr if(!istype(user) || user.stat) return - if(retaliate || (hostile && faction != user.faction)) + if(ai_holder.retaliate || (ai_holder.hostile && faction != user.faction)) user << "This predator isn't friendly, and doesn't give a shit about your opinions of it digesting you." return if(vore_selected.digest_mode == DM_HOLD) @@ -48,7 +49,8 @@ if(confirm == "Disable") vore_selected.digest_mode = DM_HOLD -/mob/living/simple_animal/attackby(var/obj/item/O, var/mob/user) +/* +/mob/living/simple_mob/attackby(var/obj/item/O, var/mob/user) if (istype(O, /obj/item/weapon/newspaper) && !(ckey || (hostile && faction != user.faction)) && isturf(user.loc)) if (retaliate && prob(vore_pounce_chance/2)) // This is a gamble! user.Weaken(5) //They get tackled anyway whether they're edible or not. @@ -72,5 +74,5 @@ if(src && L) prey_excludes -= L else - ..() + ..() */ //VORESTATION AI TEMPORARY REMOVAL diff --git a/code/modules/vore/eating/transforming_vr.dm b/code/modules/vore/eating/transforming_vr.dm index b978bf8963..a3ad00ab7a 100644 --- a/code/modules/vore/eating/transforming_vr.dm +++ b/code/modules/vore/eating/transforming_vr.dm @@ -252,13 +252,13 @@ var/egg_path = /obj/structure/closet/secure_closet/egg var/egg_name = "odd egg" - if(O.egg_type in tf_egg_types) - egg_path = tf_egg_types[O.egg_type] - egg_name = "[O.egg_type] egg" + if(O.vore_egg_type in tf_vore_egg_types) + egg_path = tf_vore_egg_types[O.vore_egg_type] + egg_name = "[O.vore_egg_type] egg" var/obj/structure/closet/secure_closet/egg/egg = new egg_path(src) M.forceMove(egg) egg.name = egg_name if(message) to_chat(M, "You lose sensation of your body, feeling only the warmth around you as you're encased in an egg.") - to_chat(O, "Your body shifts as you encase [M] in an egg.") \ No newline at end of file + to_chat(O, "Your body shifts as you encase [M] in an egg.") diff --git a/code/modules/vore/eating/vorepanel_vr.dm b/code/modules/vore/eating/vorepanel_vr.dm index b7ee064846..336b86b5a4 100644 --- a/code/modules/vore/eating/vorepanel_vr.dm +++ b/code/modules/vore/eating/vorepanel_vr.dm @@ -2,7 +2,7 @@ // Vore management panel for players // -#define BELLIES_MAX 20 +#define BELLIES_MAX 30 #define BELLIES_NAME_MIN 2 #define BELLIES_NAME_MAX 12 #define BELLIES_DESC_MAX 1024 @@ -634,7 +634,7 @@ if(new_bulge == 0) //Disable. selected.bulge_size = 0 to_chat(user,"Your stomach will not be seen on examine.") - else if (!IsInRange(new_bulge,25,200)) + else if (!ISINRANGE(new_bulge,25,200)) selected.bulge_size = 0.25 //Set it to the default. to_chat(user,"Invalid size.") else if(new_bulge) @@ -644,7 +644,7 @@ var/new_grow = input(user, "Choose the size that prey will be grown/shrunk to, ranging from 25% to 200%", "Set Growth Shrink Size.", selected.shrink_grow_size) as num|null if (new_grow == null) return - if (!IsInRange(new_grow,25,200)) + if (!ISINRANGE(new_grow,25,200)) selected.shrink_grow_size = 1 //Set it to the default to_chat(user,"Invalid size.") else if(new_grow) @@ -654,14 +654,14 @@ var/new_damage = input(user, "Choose the amount of burn damage prey will take per tick. Ranges from 0 to 6.", "Set Belly Burn Damage.", selected.digest_burn) as num|null if(new_damage == null) return - var/new_new_damage = Clamp(new_damage, 0, 6) + var/new_new_damage = CLAMP(new_damage, 0, 6) selected.digest_burn = new_new_damage if(href_list["b_brute_dmg"]) var/new_damage = input(user, "Choose the amount of brute damage prey will take per tick. Ranges from 0 to 6", "Set Belly Brute Damage.", selected.digest_brute) as num|null if(new_damage == null) return - var/new_new_damage = Clamp(new_damage, 0, 6) + var/new_new_damage = CLAMP(new_damage, 0, 6) selected.digest_brute = new_new_damage if(href_list["b_escapable"]) diff --git a/code/modules/vore/fluffstuff/custom_boxes_vr.dm b/code/modules/vore/fluffstuff/custom_boxes_vr.dm index c4e137d137..c75ac1ae2e 100644 --- a/code/modules/vore/fluffstuff/custom_boxes_vr.dm +++ b/code/modules/vore/fluffstuff/custom_boxes_vr.dm @@ -239,7 +239,7 @@ /obj/item/weapon/grenade/spawnergrenade/spirit name = "spirit's pet carrier" desc = "Contains kitten." - spawner_type = /mob/living/simple_animal/cat/fluff/tabiranth + spawner_type = /mob/living/simple_mob/animal/passive/cat/tabiranth deliveryamt = 1 /* diff --git a/code/modules/vore/fluffstuff/custom_guns_vr.dm b/code/modules/vore/fluffstuff/custom_guns_vr.dm index f9a355cef2..7a0b26d176 100644 --- a/code/modules/vore/fluffstuff/custom_guns_vr.dm +++ b/code/modules/vore/fluffstuff/custom_guns_vr.dm @@ -540,26 +540,26 @@ name = "laser beam" icon_state = "xray" light_color = "#00FF00" - muzzle_type = /obj/effect/projectile/xray/muzzle - tracer_type = /obj/effect/projectile/xray/tracer - impact_type = /obj/effect/projectile/xray/impact + muzzle_type = /obj/effect/projectile/muzzle/xray + tracer_type = /obj/effect/projectile/tracer/xray + impact_type = /obj/effect/projectile/impact/xray /obj/item/projectile/beam/imperial name = "laser beam" fire_sound = 'sound/weapons/mandalorian.ogg' icon_state = "darkb" light_color = "#8837A3" - muzzle_type = /obj/effect/projectile/darkmatter/muzzle - tracer_type = /obj/effect/projectile/darkmatter/tracer - impact_type = /obj/effect/projectile/darkmatter/impact + muzzle_type = /obj/effect/projectile/muzzle/darkmatter + tracer_type = /obj/effect/projectile/tracer/darkmatter + impact_type = /obj/effect/projectile/impact/darkmatter /obj/item/projectile/beam/stun/kin21 name = "kinh21 stun beam" icon_state = "omnilaser" light_color = "#0000FF" - muzzle_type = /obj/effect/projectile/laser_omni/muzzle - tracer_type = /obj/effect/projectile/laser_omni/tracer - impact_type = /obj/effect/projectile/laser_omni/impact + muzzle_type = /obj/effect/projectile/muzzle/laser_omni + tracer_type = /obj/effect/projectile/tracer/laser_omni + impact_type = /obj/effect/projectile/impact/laser_omni //--------------- StG-60 ---------------- /obj/item/ammo_magazine/m792 diff --git a/code/modules/vore/fluffstuff/custom_items_vr.dm b/code/modules/vore/fluffstuff/custom_items_vr.dm index dbb99b910d..c54802e577 100644 --- a/code/modules/vore/fluffstuff/custom_items_vr.dm +++ b/code/modules/vore/fluffstuff/custom_items_vr.dm @@ -436,7 +436,7 @@ /obj/item/clothing/accessory/collar/khcrystal/process() check_owner() if((state > 1) || !owner) - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) /obj/item/clothing/accessory/collar/khcrystal/attack_self(mob/user as mob) if(state > 0) //Can't re-pair, one time only, for security reasons. @@ -447,7 +447,7 @@ owner_c = user.client //This is his client update_state(1) to_chat(user, "The [name] glows pleasantly blue.") - processing_objects.Add(src) + START_PROCESSING(SSobj, src) /obj/item/clothing/accessory/collar/khcrystal/proc/check_owner() //He's dead, jim @@ -726,7 +726,7 @@ assigned_proc = /mob/living/carbon/human/proc/use_reagent_implant_roiz /obj/item/weapon/implant/reagent_generator/roiz/post_implant(mob/living/carbon/source) - processing_objects += src + START_PROCESSING(SSobj, src) to_chat(source, "You implant [source] with \the [src].") source.verbs |= assigned_proc return 1 @@ -794,7 +794,7 @@ assigned_proc = /mob/living/carbon/human/proc/use_reagent_implant_jasmine /obj/item/weapon/implant/reagent_generator/jasmine/post_implant(mob/living/carbon/source) - processing_objects += src + START_PROCESSING(SSobj, src) to_chat(source, "You implant [source] with \the [src].") source.verbs |= assigned_proc return 1 @@ -862,7 +862,7 @@ assigned_proc = /mob/living/carbon/human/proc/use_reagent_implant_yonra /obj/item/weapon/implant/reagent_generator/yonra/post_implant(mob/living/carbon/source) - processing_objects += src + START_PROCESSING(SSobj, src) to_chat(source, "You implant [source] with \the [src].") source.verbs |= assigned_proc return 1 @@ -946,7 +946,7 @@ assigned_proc = /mob/living/carbon/human/proc/use_reagent_implant_rischi /obj/item/weapon/implant/reagent_generator/rischi/post_implant(mob/living/carbon/source) - processing_objects += src + START_PROCESSING(SSobj, src) to_chat(source, "You implant [source] with \the [src].") source.verbs |= assigned_proc return 1 @@ -1641,7 +1641,7 @@ assigned_proc = /mob/living/carbon/human/proc/use_reagent_implant_evian /obj/item/weapon/implant/reagent_generator/evian/post_implant(mob/living/carbon/source) - processing_objects += src + START_PROCESSING(SSobj, src) to_chat(source, "You implant [source] with \the [src].") source.verbs |= assigned_proc return 1 diff --git a/code/modules/vore/fluffstuff/guns/dominator.dm b/code/modules/vore/fluffstuff/guns/dominator.dm index 657ba95738..590e3abd92 100644 --- a/code/modules/vore/fluffstuff/guns/dominator.dm +++ b/code/modules/vore/fluffstuff/guns/dominator.dm @@ -45,6 +45,6 @@ /obj/item/projectile/beam/dominator name = "dominator lethal beam" icon_state = "xray" - muzzle_type = /obj/effect/projectile/xray/muzzle - tracer_type = /obj/effect/projectile/xray/tracer - impact_type = /obj/effect/projectile/xray/impact \ No newline at end of file + muzzle_type = /obj/effect/projectile/muzzle/xray + tracer_type = /obj/effect/projectile/tracer/xray + impact_type = /obj/effect/projectile/impact/xray \ No newline at end of file diff --git a/code/modules/vore/fluffstuff/guns/nsfw.dm b/code/modules/vore/fluffstuff/guns/nsfw.dm index a0c7d89196..2e353677ba 100644 --- a/code/modules/vore/fluffstuff/guns/nsfw.dm +++ b/code/modules/vore/fluffstuff/guns/nsfw.dm @@ -134,7 +134,7 @@ add_overlay(barrel_color) //Charge bar - var/ratio = Ceiling((charge_left / max_charge) * charge_sections) + var/ratio = CEILING(((charge_left / max_charge) * charge_sections), 1) for(var/i = 0, i < ratio, i++) var/image/charge_bar = image(icon, icon_state = "[initial(icon_state)]_charge") charge_bar.pixel_x = i @@ -174,7 +174,7 @@ add_overlay(cap) if(batt.shots_left) - var/ratio = Ceiling((batt.shots_left / initial(batt.shots_left)) * 4) //4 is how many lights we have a sprite for + var/ratio = CEILING(((batt.shots_left / initial(batt.shots_left)) * 4), 1) //4 is how many lights we have a sprite for var/image/charge = image(icon, icon_state = "[initial(icon_state)]_charge-[ratio]") charge.color = "#29EAF4" //Could use battery color but eh. charge.pixel_x = current * x_offset @@ -200,7 +200,7 @@ var/type_name = null projectile_type = /obj/item/projectile/beam -/obj/item/ammo_casing/nsfw_batt/initialize() +/obj/item/ammo_casing/nsfw_batt/Initialize() . = ..() pixel_x = rand(-10, 10) pixel_y = rand(-10, 10) @@ -309,9 +309,9 @@ damage_type = HALLOSS light_color = "#00CC33" - muzzle_type = /obj/effect/projectile/laser_omni/muzzle - tracer_type = /obj/effect/projectile/laser_omni/tracer - impact_type = /obj/effect/projectile/laser_omni/impact + muzzle_type = /obj/effect/projectile/muzzle/laser_omni + tracer_type = /obj/effect/projectile/tracer/laser_omni + impact_type = /obj/effect/projectile/impact/laser_omni /obj/item/projectile/beam/final_option/on_hit(var/atom/impacted) if(isliving(impacted)) diff --git a/code/modules/vore/fluffstuff/guns/protector.dm b/code/modules/vore/fluffstuff/guns/protector.dm index b1b39e6f2d..13253796f5 100644 --- a/code/modules/vore/fluffstuff/guns/protector.dm +++ b/code/modules/vore/fluffstuff/guns/protector.dm @@ -72,7 +72,7 @@ itemState += "[modifystate]" */ if(power_supply) - ratio = Ceiling((power_supply.charge / power_supply.maxcharge) * charge_sections) + ratio = CEILING(((power_supply.charge / power_supply.maxcharge) * charge_sections), 1) if(power_supply.charge < charge_cost) overlays += "[icon_state]_empty" @@ -104,9 +104,9 @@ icon_state = "omnilaser" //A little more cyan light_color = "#00C6FF" agony = 50 //Normal is 40 when this was set - muzzle_type = /obj/effect/projectile/laser_omni/muzzle - tracer_type = /obj/effect/projectile/laser_omni/tracer - impact_type = /obj/effect/projectile/laser_omni/impact + muzzle_type = /obj/effect/projectile/muzzle/laser_omni + tracer_type = /obj/effect/projectile/tracer/laser_omni + impact_type = /obj/effect/projectile/impact/laser_omni //R&D Design /datum/design/item/weapon/protector diff --git a/code/modules/vore/fluffstuff/guns/pummeler.dm b/code/modules/vore/fluffstuff/guns/pummeler.dm index f3d6c546ee..082af9a9cf 100644 --- a/code/modules/vore/fluffstuff/guns/pummeler.dm +++ b/code/modules/vore/fluffstuff/guns/pummeler.dm @@ -34,7 +34,7 @@ check_armour = "melee" embed_chance = 0 vacuum_traversal = 0 - kill_count = 6 //Scary name, but just deletes the projectile after this range + range = 6 //Scary name, but just deletes the projectile after this range /obj/item/projectile/pummel/on_hit(var/atom/movable/target, var/blocked = 0) if(isliving(target)) diff --git a/code/modules/vore/fluffstuff/guns/sickshot.dm b/code/modules/vore/fluffstuff/guns/sickshot.dm index 6afda74a9c..385a69efd6 100644 --- a/code/modules/vore/fluffstuff/guns/sickshot.dm +++ b/code/modules/vore/fluffstuff/guns/sickshot.dm @@ -32,7 +32,7 @@ check_armour = "melee" embed_chance = 0 vacuum_traversal = 0 - kill_count = 5 //Scary name, but just deletes the projectile after this range + range = 5 //Scary name, but just deletes the projectile after this range /obj/item/projectile/sickshot/on_hit(var/atom/movable/target, var/blocked = 0) if(isliving(target)) diff --git a/code/modules/vore/hook-defs_vr.dm b/code/modules/vore/hook-defs_vr.dm index 06734e8245..630bf51b78 100644 --- a/code/modules/vore/hook-defs_vr.dm +++ b/code/modules/vore/hook-defs_vr.dm @@ -11,7 +11,7 @@ /hook/human_new -/hook/simple_animal_new +/hook/simple_mob_new //Hooks for interactions /hook/living_attackby diff --git a/code/modules/vore/resizing/resize_vr.dm b/code/modules/vore/resizing/resize_vr.dm index 23987a3fed..5dc18624bb 100644 --- a/code/modules/vore/resizing/resize_vr.dm +++ b/code/modules/vore/resizing/resize_vr.dm @@ -109,7 +109,7 @@ var/const/RESIZE_A_SMALLTINY = (RESIZE_SMALL + RESIZE_TINY) / 2 var/nagmessage = "Adjust your mass to be a size between 25 to 200% (DO NOT ABUSE)" var/new_size = input(nagmessage, "Pick a Size") as num|null - if(new_size && IsInRange(new_size,25,200)) + if(new_size && ISINRANGE(new_size,25,200)) src.resize(new_size/100) message_admins("[key_name(src)] used the resize command in-game to be [new_size]% size. \ ([src ? "JMP" : "null"])") @@ -132,7 +132,7 @@ var/const/RESIZE_A_SMALLTINY = (RESIZE_SMALL + RESIZE_TINY) / 2 if(!istype(M)) return 0 if(isanimal(M)) - var/mob/living/simple_animal/SA = M + var/mob/living/simple_mob/SA = M if(!SA.has_hands) return 0 if(M.buckled) diff --git a/code/modules/vore/resizing/sizegun_vr.dm b/code/modules/vore/resizing/sizegun_vr.dm index 27f2d770b8..705bf3538d 100644 --- a/code/modules/vore/resizing/sizegun_vr.dm +++ b/code/modules/vore/resizing/sizegun_vr.dm @@ -65,9 +65,9 @@ check_armour = "laser" var/set_size = 1 //Let's default to 100% - muzzle_type = /obj/effect/projectile/xray/muzzle - tracer_type = /obj/effect/projectile/xray/tracer - impact_type = /obj/effect/projectile/xray/impact + muzzle_type = /obj/effect/projectile/muzzle/xray + tracer_type = /obj/effect/projectile/tracer/xray + impact_type = /obj/effect/projectile/impact/xray on_hit(var/atom/target) var/mob/living/M = target diff --git a/code/modules/xenoarcheaology/anomaly_container.dm b/code/modules/xenoarcheaology/anomaly_container.dm index 6372405300..795cd9d6df 100644 --- a/code/modules/xenoarcheaology/anomaly_container.dm +++ b/code/modules/xenoarcheaology/anomaly_container.dm @@ -7,7 +7,7 @@ var/obj/machinery/artifact/contained -/obj/structure/anomaly_container/initialize() +/obj/structure/anomaly_container/Initialize() . = ..() var/obj/machinery/artifact/A = locate() in loc diff --git a/code/modules/xenoarcheaology/artifacts/autocloner.dm b/code/modules/xenoarcheaology/artifacts/autocloner.dm index 535eee1559..cc7a6cce2b 100644 --- a/code/modules/xenoarcheaology/artifacts/autocloner.dm +++ b/code/modules/xenoarcheaology/artifacts/autocloner.dm @@ -21,25 +21,24 @@ //33% chance to spawn nasties if(prob(33)) - spawn_type = pick(\ - /mob/living/simple_animal/hostile/giant_spider/nurse,\ - /mob/living/simple_animal/hostile/alien,\ - /mob/living/simple_animal/hostile/bear,\ - /mob/living/simple_animal/hostile/carp,\ - /mob/living/simple_animal/hostile/creature\ - ) // Vorestation Edits + spawn_type = pick( + /mob/living/simple_mob/animal/giant_spider/nurse, + /mob/living/simple_mob/animal/space/alien, + /mob/living/simple_mob/animal/space/bear, + /mob/living/simple_mob/creature, + /mob/living/simple_mob/slime/xenobio, + /mob/living/simple_mob/animal/space/carp)// Vorestation edit else spawn_type = pick(\ - /mob/living/simple_animal/cat, - /mob/living/simple_animal/corgi, - /mob/living/simple_animal/corgi/puppy, - /mob/living/simple_animal/chicken, - /mob/living/simple_animal/cow, - /mob/living/simple_animal/parrot, - /mob/living/simple_animal/slime, - /mob/living/simple_animal/crab, - /mob/living/simple_animal/mouse, - /mob/living/simple_animal/retaliate/goat) + /mob/living/simple_mob/animal/passive/cat, + /mob/living/simple_mob/animal/passive/dog/corgi, + /mob/living/simple_mob/animal/passive/dog/corgi/puppy, + /mob/living/simple_mob/animal/passive/chicken, + /mob/living/simple_mob/animal/passive/cow, + /mob/living/simple_mob/animal/passive/bird/parrot, + /mob/living/simple_mob/animal/passive/crab, + /mob/living/simple_mob/animal/passive/mouse, + /mob/living/simple_mob/animal/goat) //todo: how the hell is the asteroid permanently powered? /obj/machinery/auto_cloner/process() diff --git a/code/modules/xenoarcheaology/artifacts/replicator.dm b/code/modules/xenoarcheaology/artifacts/replicator.dm index f5575721e5..af78f320e5 100644 --- a/code/modules/xenoarcheaology/artifacts/replicator.dm +++ b/code/modules/xenoarcheaology/artifacts/replicator.dm @@ -26,9 +26,8 @@ /obj/item/roller, /obj/structure/closet/crate, /obj/structure/closet/acloset, - /mob/living/simple_animal/hostile/mimic/crate, - /mob/living/simple_animal/hostile/viscerator, - /mob/living/simple_animal/hostile/hivebot, + /mob/living/simple_mob/mechanical/viscerator, + /mob/living/simple_mob/mechanical/hivebot, /obj/item/device/analyzer, /obj/item/device/camera, /obj/item/device/flash, @@ -65,6 +64,7 @@ /obj/item/weapon/grenade/chem_grenade/cleaner, /obj/item/weapon/grenade/chem_grenade/metalfoam) +// /mob/living/simple_mob/mimic/crate, // Vorestation edit //VORESTATION AI TEMPORARY REMOVAL, REPLACE BACK IN LIST WHEN FIXED var/quantity = rand(5, 15) for(var/i=0, i= 3) if(prob(5)) charges -= 1 - var/spawn_type = pick(/mob/living/simple_animal/hostile/creature/vore) // Vorestation Edit + var/spawn_type = pick(/mob/living/simple_mob/creature) new spawn_type(pick(view(1,src))) playsound(src.loc, pick('sound/hallucinations/growl1.ogg','sound/hallucinations/growl2.ogg','sound/hallucinations/growl3.ogg'), 50, 1, -3) @@ -143,7 +143,7 @@ /obj/effect/decal/cleanable/blood/splatter/animated/New() ..() - processing_objects.Add(src) + START_PROCESSING(SSobj, src) loc_last_process = src.loc /obj/effect/decal/cleanable/blood/splatter/animated/process() @@ -173,7 +173,7 @@ density = 1 /obj/effect/shadow_wight/New() - processing_objects.Add(src) + START_PROCESSING(SSobj, src) /obj/effect/shadow_wight/process() if(src.loc) @@ -197,7 +197,7 @@ M.sleeping = max(M.sleeping,rand(5,10)) src.loc = null else - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) /obj/effect/shadow_wight/Bump(var/atom/obstacle) obstacle << "You feel a chill run down your spine!" diff --git a/code/modules/xenoarcheaology/finds/talking.dm b/code/modules/xenoarcheaology/finds/talking.dm index 72ff1330de..01af7f7a0e 100644 --- a/code/modules/xenoarcheaology/finds/talking.dm +++ b/code/modules/xenoarcheaology/finds/talking.dm @@ -13,11 +13,11 @@ /datum/talking_atom/proc/init() if(holder_atom) - processing_objects.Add(src) + START_PROCESSING(SSobj, src) -/datum/talking_atom/proc/process() +/datum/talking_atom/process() if(!holder_atom) - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) else if(heard_words.len >= 1 && world.time > last_talk_time + talk_interval && prob(talk_chance)) SaySomething() diff --git a/code/modules/xenoarcheaology/misc.dm b/code/modules/xenoarcheaology/misc.dm index b457e98984..2c031fa344 100644 --- a/code/modules/xenoarcheaology/misc.dm +++ b/code/modules/xenoarcheaology/misc.dm @@ -41,7 +41,7 @@ /obj/structure/bookcase/manuals/xenoarchaeology name = "Xenoarchaeology Manuals bookcase" -/obj/structure/bookcase/manuals/xenoarchaeology/initialize() +/obj/structure/bookcase/manuals/xenoarchaeology/Initialize() . = ..() new /obj/item/weapon/book/manual/excavation(src) new /obj/item/weapon/book/manual/mass_spectrometry(src) diff --git a/code/modules/xenoarcheaology/tools/ano_device_battery.dm b/code/modules/xenoarcheaology/tools/ano_device_battery.dm index a7fdae7553..ce4427d595 100644 --- a/code/modules/xenoarcheaology/tools/ano_device_battery.dm +++ b/code/modules/xenoarcheaology/tools/ano_device_battery.dm @@ -34,7 +34,7 @@ /obj/item/weapon/anodevice/New() ..() - processing_objects.Add(src) + START_PROCESSING(SSobj, src) /obj/item/weapon/anodevice/attackby(var/obj/I as obj, var/mob/user as mob) if(istype(I, /obj/item/weapon/anobattery)) @@ -190,7 +190,7 @@ icon_state = "anodev[round(p,25)]" /obj/item/weapon/anodevice/Destroy() - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) ..() /obj/item/weapon/anodevice/attack(mob/living/M as mob, mob/living/user as mob, def_zone) diff --git a/code/modules/xenoarcheaology/tools/artifact_analyser.dm b/code/modules/xenoarcheaology/tools/artifact_analyser.dm index e169a62061..b1b0251d7c 100644 --- a/code/modules/xenoarcheaology/tools/artifact_analyser.dm +++ b/code/modules/xenoarcheaology/tools/artifact_analyser.dm @@ -14,7 +14,7 @@ var/obj/scanned_object var/report_num = 0 -/obj/machinery/artifact_analyser/initialize() +/obj/machinery/artifact_analyser/Initialize() . = ..() reconnect_scanner() diff --git a/code/modules/xenoarcheaology/tools/coolant_tank.dm b/code/modules/xenoarcheaology/tools/coolant_tank.dm index 1ee02211cf..df6c901517 100644 --- a/code/modules/xenoarcheaology/tools/coolant_tank.dm +++ b/code/modules/xenoarcheaology/tools/coolant_tank.dm @@ -5,8 +5,8 @@ icon_state = "coolanttank" amount_per_transfer_from_this = 10 -/obj/structure/reagent_dispensers/coolanttank/New() - ..() +/obj/structure/reagent_dispensers/coolanttank/Initialize() + . = ..() reagents.add_reagent("coolant", 1000) /obj/structure/reagent_dispensers/coolanttank/bullet_act(var/obj/item/projectile/Proj) diff --git a/code/modules/xenoarcheaology/tools/equipment.dm b/code/modules/xenoarcheaology/tools/equipment.dm index 5bc7694df5..a2f21199a4 100644 --- a/code/modules/xenoarcheaology/tools/equipment.dm +++ b/code/modules/xenoarcheaology/tools/equipment.dm @@ -6,6 +6,8 @@ item_state = "engspace_suit" update_icon_define = "icons/mob/spacesuit.dmi" armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 100) + max_pressure_protection = 5 * ONE_ATMOSPHERE // Not very good protection, but if an anomaly starts doing gas stuff you're not screwed + min_pressure_protection = 0.4 * ONE_ATMOSPHERE /obj/item/clothing/head/bio_hood/anomaly name = "Anomaly hood" @@ -13,6 +15,8 @@ icon_state = "engspace_helmet" item_state = "engspace_helmet" armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 100) + max_pressure_protection = 5 * ONE_ATMOSPHERE // Not very good protection, but if an anomaly starts doing gas stuff you're not screwed + min_pressure_protection = 0.4 * ONE_ATMOSPHERE /obj/item/clothing/suit/space/anomaly name = "Excavation suit" @@ -22,6 +26,7 @@ armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 100) allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit) slowdown = 1 + // Pressure protection inherited from space suits /obj/item/clothing/head/helmet/space/anomaly name = "Excavation hood" diff --git a/code/modules/xenoarcheaology/tools/geosample_scanner.dm b/code/modules/xenoarcheaology/tools/geosample_scanner.dm index 003a5639da..b97a34e48f 100644 --- a/code/modules/xenoarcheaology/tools/geosample_scanner.dm +++ b/code/modules/xenoarcheaology/tools/geosample_scanner.dm @@ -150,7 +150,7 @@ data["rad_shield_on"] = rad_shield // update the ui if it exists, returns null if no ui is passed/found - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.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 diff --git a/code/modules/xenoarcheaology/tools/suspension_generator.dm b/code/modules/xenoarcheaology/tools/suspension_generator.dm index c85307f3ee..3f10320971 100644 --- a/code/modules/xenoarcheaology/tools/suspension_generator.dm +++ b/code/modules/xenoarcheaology/tools/suspension_generator.dm @@ -219,25 +219,25 @@ deactivate() ..() -/obj/machinery/suspension_gen/verb/rotate_ccw() +/obj/machinery/suspension_gen/verb/rotate_counterclockwise() set src in view(1) - set name = "Rotate suspension gen (counter-clockwise)" + set name = "Rotate suspension gen Counterclockwise" set category = "Object" if(anchored) to_chat(usr, "You cannot rotate [src], it has been firmly fixed to the floor.") - else - set_dir(turn(dir, 90)) + return + src.set_dir(turn(src.dir, 90)) -/obj/machinery/suspension_gen/verb/rotate_cw() +/obj/machinery/suspension_gen/verb/rotate_clockwise() set src in view(1) - set name = "Rotate suspension gen (clockwise)" + set name = "Rotate suspension gen Clockwise" set category = "Object" if(anchored) to_chat(usr, "You cannot rotate [src], it has been firmly fixed to the floor.") - else - set_dir(turn(dir, -90)) + return + src.set_dir(turn(src.dir, 270)) /obj/effect/suspension_field name = "energy field" diff --git a/code/modules/xenoarcheaology/tools/tools.dm b/code/modules/xenoarcheaology/tools/tools.dm index 78a1a992e7..c5eb9b35ac 100644 --- a/code/modules/xenoarcheaology/tools/tools.dm +++ b/code/modules/xenoarcheaology/tools/tools.dm @@ -229,10 +229,10 @@ /obj/item/device/beacon_locator/New() ..() - processing_objects.Add(src) + START_PROCESSING(SSobj, src) /obj/item/device/beacon_locator/Destroy() - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) ..() /obj/item/device/beacon_locator/process() @@ -254,7 +254,7 @@ if(prob(scan_ticks * 10)) spawn(0) set background = 1 - if(processing_objects.Find(src)) + if(datum_flags & DF_ISPROCESSING) //scan radios in the world to try and find one var/cur_dist = 999 for(var/obj/item/device/radio/beacon/R in all_beacons) diff --git a/code/modules/xenobio/items/extracts.dm b/code/modules/xenobio/items/extracts.dm index 6d472b5a09..397ca52c33 100644 --- a/code/modules/xenobio/items/extracts.dm +++ b/code/modules/xenobio/items/extracts.dm @@ -77,7 +77,7 @@ /datum/chemical_reaction/slime/grey_new_slime/on_reaction(var/datum/reagents/holder) holder.my_atom.visible_message("Infused with phoron, the core begins to quiver and grow, and soon a new baby slime emerges from it!") - new /mob/living/simple_animal/slime(get_turf(holder.my_atom)) + new /mob/living/simple_mob/slime/xenobio(get_turf(holder.my_atom)) ..() /datum/chemical_reaction/slime/grey_monkey @@ -495,16 +495,16 @@ if(!(their_turf in Z.contents)) // Not in the same zone. continue - if(istype(L, /mob/living/simple_animal/slime)) - var/mob/living/simple_animal/slime/S = L - if(S.cold_damage_per_tick <= 0) // Immune to cold. + if(istype(L, /mob/living/simple_mob/slime)) + var/mob/living/simple_mob/slime/S = L + if(S.cold_resist >= 1) // Immune to cold. to_chat(S, "A chill is felt around you, however it cannot harm you.") continue if(S.client) // Don't instantly kill player slimes. to_chat(S, "You feel your body crystalize as an intense chill overwhelms you!") - S.adjustToxLoss(S.cold_damage_per_tick * 2) + S.inflict_cold_damage(100) else - S.adjustToxLoss(S.cold_damage_per_tick * 5) // Metal slimes can survive this 'slime nuke'. + S.inflict_cold_damage(200) // Metal slimes can survive this 'slime nuke'. continue if(ishuman(L)) @@ -552,17 +552,21 @@ required = /obj/item/slime_extract/red /datum/chemical_reaction/slime/red_enrage/on_reaction(var/datum/reagents/holder) - for(var/mob/living/simple_animal/slime/S in view(get_turf(holder.my_atom))) - if(S.stat || S.docile || S.rabid) + for(var/mob/living/simple_mob/slime/S in view(get_turf(holder.my_atom))) + if(S.stat) continue + if(istype(S, /mob/living/simple_mob/slime/xenobio)) + var/mob/living/simple_mob/slime/xenobio/X = S + if(X.harmless) + continue + if(!X.client) + X.enrage() + S.add_modifier(/datum/modifier/berserk, 30 SECONDS) if(S.client) // Player slimes always have free will. to_chat(S, "An intense wave of rage is felt from inside, but you remain in control of yourself.") - continue - - S.enrage() for(var/mob/living/carbon/human/H in view(get_turf(holder.my_atom))) if(H.species.name == SPECIES_PROMETHEAN) @@ -957,8 +961,8 @@ /datum/chemical_reaction/slime/rainbow_random_slime/on_reaction(var/datum/reagents/holder) - var/mob/living/simple_animal/slime/S - var/list/slime_types = typesof(/mob/living/simple_animal/slime) + var/mob/living/simple_mob/slime/xenobio/S + var/list/slime_types = typesof(/mob/living/simple_mob/slime/xenobio) while(slime_types.len) S = pick(slime_types) diff --git a/code/modules/xenobio/items/slime_objects.dm b/code/modules/xenobio/items/slime_objects.dm index 27f6f863eb..aa368f6dd6 100644 --- a/code/modules/xenobio/items/slime_objects.dm +++ b/code/modules/xenobio/items/slime_objects.dm @@ -123,6 +123,6 @@ nutriment_amt = 25 // Very filling. nutriment_desc = list("slime" = 10, "sweetness" = 10, "bliss" = 5) -/obj/item/weapon/reagent_containers/food/snacks/slime/New() - ..() +/obj/item/weapon/reagent_containers/food/snacks/slime/Initialize() + . = ..() bitesize = 5 \ No newline at end of file diff --git a/code/modules/xenobio/items/slimepotions.dm b/code/modules/xenobio/items/slimepotions.dm index df03fdab6f..944853bec7 100644 --- a/code/modules/xenobio/items/slimepotions.dm +++ b/code/modules/xenobio/items/slimepotions.dm @@ -21,7 +21,7 @@ icon_state = "potcyan" description_info = "The slime needs to be alive for this to work. It will reduce the chances of mutation by 15%." -/obj/item/slimepotion/stabilizer/attack(mob/living/simple_animal/slime/M, mob/user) +/obj/item/slimepotion/stabilizer/attack(mob/living/simple_mob/slime/xenobio/M, mob/user) if(!istype(M)) to_chat(user, "The stabilizer only works on slimes!") return ..() @@ -45,7 +45,7 @@ description_info = "The slime needs to be alive for this to work. It will increase the chances of mutation by 12%." icon_state = "potred" -/obj/item/slimepotion/mutator/attack(mob/living/simple_animal/slime/M, mob/user) +/obj/item/slimepotion/mutator/attack(mob/living/simple_mob/slime/xenobio/M, mob/user) if(!istype(M)) to_chat(user, "The mutator only works on slimes!") return ..() @@ -67,20 +67,25 @@ name = "docility agent" desc = "A potent chemical mix that nullifies a slime's hunger, causing it to become docile and tame. It might also work on other creatures?" icon_state = "potlightpink" - description_info = "The target needs to be alive, not already passive, and have animal-like intelligence." + description_info = "The target needs to be alive, not already passive, and be an animal or slime type entity." -/obj/item/slimepotion/docility/attack(mob/living/simple_animal/M, mob/user) +/obj/item/slimepotion/docility/attack(mob/living/simple_mob/M, mob/user) if(!istype(M)) to_chat(user, "The agent only works on creatures!") return ..() if(M.stat == DEAD) to_chat(user, "\The [M] is dead!") return ..() + if(!M.has_AI()) + to_chat(user, span("warning", "\The [M] is too strongly willed for this to affect them.")) // Most likely player controlled. + return + + var/datum/ai_holder/AI = M.ai_holder // Slimes. - if(istype(M, /mob/living/simple_animal/slime)) - var/mob/living/simple_animal/slime/S = M - if(S.docile) + if(istype(M, /mob/living/simple_mob/slime/xenobio)) + var/mob/living/simple_mob/slime/xenobio/S = M + if(S.harmless) to_chat(user, "The slime is already docile!") return ..() @@ -89,22 +94,22 @@ to_chat(M, "You absorb the agent and feel your intense desire to feed melt away.") to_chat(user, "You feed the slime the agent, removing its hunger and calming it.") - // Simple Animals. - else if(istype(M, /mob/living/simple_animal)) - var/mob/living/simple_animal/SA = M - if(SA.intelligence_level > SA_ANIMAL) // So you can't use this on Russians/syndies/hivebots/etc. - to_chat(user, "\The [SA] is too intellient for this to affect them.") + // Simple Mobs. + else if(istype(M, /mob/living/simple_mob)) + var/mob/living/simple_mob/SM = M + if(!(SM.mob_class & MOB_CLASS_SLIME|MOB_CLASS_ANIMAL)) // So you can't use this on Russians/syndies/hivebots/etc. + to_chat(user, "\The [SM] only works on slimes and animals.") return ..() - if(!SA.hostile) - to_chat(user, "\The [SA] is already passive!") + if(!AI.hostile) + to_chat(user, "\The [SM] is already passive!") return ..() - SA.hostile = FALSE + AI.hostile = FALSE to_chat(M, "You consume the agent and feel a serene sense of peace.") - to_chat(user, "You feed \the [SA] the agent, calming it.") + to_chat(user, "You feed \the [SM] the agent, calming it.") playsound(src, 'sound/effects/bubbles.ogg', 50, 1) - M.LoseTarget() // So hostile things stop attacking people even if not hostile anymore. + AI.lost_target() // So hostile things stop attacking people even if not hostile anymore. var/newname = copytext(sanitize(input(user, "Would you like to give \the [M] a name?", "Name your new pet", M.name) as null|text),1,MAX_NAME_LEN) if(newname) @@ -121,7 +126,7 @@ Extra extracts are not passed down to offspring when reproducing." icon_state = "potpurple" -/obj/item/slimepotion/steroid/attack(mob/living/simple_animal/slime/M, mob/user) +/obj/item/slimepotion/steroid/attack(mob/living/simple_mob/slime/xenobio/M, mob/user) if(!istype(M)) to_chat(user, "The steroid only works on slimes!") return ..() @@ -149,7 +154,7 @@ carry over to offspring when reproducing." icon_state = "potpink" -/obj/item/slimepotion/unity/attack(mob/living/simple_animal/slime/M, mob/user) +/obj/item/slimepotion/unity/attack(mob/living/simple_mob/slime/M, mob/user) if(!istype(M)) to_chat(user, "The agent only works on slimes!") return ..() @@ -175,12 +180,12 @@ the user's faction, which means the slime will attack things that are hostile to the user's faction, such as carp, spiders, and other slimes." icon_state = "potred" -/obj/item/slimepotion/loyalty/attack(mob/living/simple_animal/M, mob/user) +/obj/item/slimepotion/loyalty/attack(mob/living/simple_mob/M, mob/user) if(!istype(M)) - to_chat(user, "The agent only works on animals!") + to_chat(user, "The agent only works on creatures!") return ..() - if(M.intelligence_level > SA_ANIMAL) // So you can't use this on Russians/syndies/hivebots/etc. - to_chat(user, "\The [M] is too intellient for this to affect them.") + if(!(M.mob_class & MOB_CLASS_SLIME|MOB_CLASS_ANIMAL)) // So you can't use this on Russians/syndies/hivebots/etc. + to_chat(user, "\The [M] only works on slimes and animals.") return ..() if(M.stat == DEAD) to_chat(user, "The animal is dead!") @@ -188,12 +193,16 @@ if(M.faction == user.faction) to_chat(user, "\The [M] is already loyal to your species!") return ..() + if(!M.has_AI()) + to_chat(user, span("warning", "\The [M] is too strong-willed for this to affect them.")) + return ..() + + var/datum/ai_holder/AI = M.ai_holder to_chat(user, "You feed \the [M] the agent. It will now try to murder things that want to murder you instead.") to_chat(M, "\The [user] feeds you \the [src], and feel that the others will regard you as an outsider now.") M.faction = user.faction - M.attack_same = FALSE - M.LoseTarget() // So hostile things stop attacking people even if not hostile anymore. + AI.lost_target() // So hostile things stop attacking people even if not hostile anymore. playsound(src, 'sound/effects/bubbles.ogg', 50, 1) qdel(src) @@ -206,28 +215,29 @@ their 'friend', and will never attack them. This might also work on other things besides slimes." icon_state = "potlightpink" -/obj/item/slimepotion/friendship/attack(mob/living/simple_animal/M, mob/user) +/obj/item/slimepotion/friendship/attack(mob/living/simple_mob/M, mob/user) if(!istype(M)) - to_chat(user, "The agent only works on animals!") + to_chat(user, "The agent only works on creatures!") return ..() - if(M.intelligence_level > SA_ANIMAL) // So you can't use this on Russians/syndies/hivebots/etc. - to_chat(user, "\The [M] is too intellient for this to affect them.") + if(!(M.mob_class & MOB_CLASS_SLIME|MOB_CLASS_ANIMAL)) // So you can't use this on Russians/syndies/hivebots/etc. + to_chat(user, "\The [M] only works on slimes and animals.") return ..() if(M.stat == DEAD) - to_chat(user, "The animal is dead!") + to_chat(user, "\The [M] is dead!") return ..() if(user in M.friends) to_chat(user, "\The [M] is already loyal to you!") return ..() + if(!M.has_AI()) + to_chat(user, span("warning", "\The [M] is too strong-willed for this to affect them.")) + return ..() + + var/datum/ai_holder/AI = M.ai_holder to_chat(user, "You feed \the [M] the agent. It will now be your best friend.") to_chat(M, "\The [user] feeds you \the [src], and feel that \the [user] wants to be best friends with you.") - if(isslime(M)) - var/mob/living/simple_animal/slime/S = M - S.befriend(user) - else - M.friends.Add(user) - M.LoseTarget() // So hostile things stop attacking people even if not hostile anymore. + M.friends.Add(user) + AI.lost_target() // So hostile things stop attacking people even if not hostile anymore. playsound(src, 'sound/effects/bubbles.ogg', 50, 1) qdel(src) @@ -239,15 +249,16 @@ description_info = "The slime needs to be alive for this to work. It will instantly grow the slime enough to reproduce." icon_state = "potyellow" -/obj/item/slimepotion/feeding/attack(mob/living/simple_animal/slime/M, mob/user) +/obj/item/slimepotion/feeding/attack(mob/living/simple_mob/slime/xenobio/M, mob/user) if(!istype(M)) - to_chat(user, "The mutator only works on slimes!") + to_chat(user, "The feeding agent only works on slimes!") return ..() if(M.stat == DEAD) to_chat(user, "The slime is dead!") return ..() to_chat(user, "You feed the slime the feeding agent. It will now instantly reproduce.") + M.amount_grown = 10 M.make_adult() M.amount_grown = 10 M.reproduce() diff --git a/code/modules/xenobio/items/weapons.dm b/code/modules/xenobio/items/weapons.dm index 8fb5f9eea6..647ac7e081 100644 --- a/code/modules/xenobio/items/weapons.dm +++ b/code/modules/xenobio/items/weapons.dm @@ -1,6 +1,6 @@ /obj/item/weapon/melee/baton/slime name = "slimebaton" - desc = "A modified stun baton designed to stun slimes and other lesser xeno lifeforms for handling." + desc = "A modified stun baton designed to stun slimes and other lesser slimy xeno lifeforms for handling." icon_state = "slimebaton" item_state = "slimebaton" slot_flags = SLOT_BELT @@ -9,31 +9,29 @@ origin_tech = list(TECH_COMBAT = 2, TECH_BIO = 2) agonyforce = 10 //It's not supposed to be great at stunning human beings. hitcost = 48 //Less zap for less cost - description_info = "This baton will stun a slime or other lesser lifeform for about five seconds, if hit with it while on." + description_info = "This baton will stun a slime or other slime-based lifeform for about five seconds, if hit with it while on." -/obj/item/weapon/melee/baton/slime/attack(mob/M, mob/user, hit_zone) - // Simple Animals. - if(istype(M, /mob/living/simple_animal/slime) && status) - var/mob/living/simple_animal/SA = M - if(SA.intelligence_level <= SA_ANIMAL) // So it doesn't stun hivebots or syndies. - SA.Weaken(5) - if(isslime(SA)) - var/mob/living/simple_animal/slime/S = SA - S.adjust_discipline(3) +/obj/item/weapon/melee/baton/slime/attack(mob/living/L, mob/user, hit_zone) + if(istype(L) && status) // Is it on? + if(L.mob_class & MOB_CLASS_SLIME) // Are they some kind of slime? (Prommies might pass this check someday). + if(isslime(L)) + var/mob/living/simple_mob/slime/S = L + S.slimebatoned(user, 5) // Feral and xenobio slimes will react differently to this. + else + L.Weaken(5) + + // Now for prommies. + if(ishuman(L)) + var/mob/living/carbon/human/H = L + if(H.species && H.species.name == SPECIES_PROMETHEAN) + var/agony_to_apply = 60 - agonyforce + H.apply_damage(agony_to_apply, HALLOSS) - // Prometheans. - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if(H.species && H.species.name == SPECIES_PROMETHEAN && status) - var/agony_to_apply = 60 - agonyforce - H.apply_damage(agony_to_apply, HALLOSS) - ..() - -/obj/item/weapon/melee/baton/slime/loaded/New() ..() +/obj/item/weapon/melee/baton/slime/loaded/Initialize() bcell = new/obj/item/weapon/cell/device(src) update_icon() - return + return ..() // Research borg's version @@ -61,9 +59,9 @@ charge_cost = 120 // Twice as many shots. projectile_type = /obj/item/projectile/beam/stun/xeno accuracy = 30 // Make it a bit easier to hit the slimes. - description_info = "This gun will stun a slime or other lesser lifeform for about two seconds, if hit with the projectile it fires." + description_info = "This gun will stun a slime or other lesser slimy lifeform for about two seconds, if hit with the projectile it fires." description_fluff = "An easy to use weapon designed by NanoTrasen, for NanoTrasen. This weapon is designed to subdue lesser \ - xeno lifeforms at a distance. It is ineffective at stunning larger lifeforms such as humanoids." + slime-based xeno lifeforms at a distance. It is ineffective at stunning non-slimy lifeforms such as humanoids." /obj/item/weapon/gun/energy/taser/xeno/robot // Borg version self_recharge = 1 @@ -71,7 +69,7 @@ recharge_time = 3 /obj/item/weapon/gun/energy/taser/xeno/sec //NT's corner-cutting option for their on-station security. - desc = "An NT Mk30 NL retrofitted to fire beams for subduing non-humanoid xeno life forms." + desc = "An NT Mk30 NL retrofitted to fire beams for subduing non-humanoid slimy xeno life forms." icon_state = "taserblue" item_state = "taser" projectile_type = /obj/item/projectile/beam/stun/xeno/weak @@ -92,9 +90,9 @@ // Probably for the best so that it doesn't harm the slime. taser_effect = FALSE - muzzle_type = /obj/effect/projectile/laser_omni/muzzle - tracer_type = /obj/effect/projectile/laser_omni/tracer - impact_type = /obj/effect/projectile/laser_omni/impact + muzzle_type = /obj/effect/projectile/muzzle/laser_omni + tracer_type = /obj/effect/projectile/tracer/laser_omni + impact_type = /obj/effect/projectile/impact/laser_omni /obj/item/projectile/beam/stun/xeno/weak //Weaker variant for non-research equipment, turrets, or rapid fire types. agony = 3 @@ -102,20 +100,17 @@ /obj/item/projectile/beam/stun/xeno/on_hit(var/atom/target, var/blocked = 0, var/def_zone = null) if(istype(target, /mob/living)) var/mob/living/L = target + if(L.mob_class & MOB_CLASS_SLIME) + if(isslime(L)) + var/mob/living/simple_mob/slime/S = L + S.slimebatoned(firer, round(agony/2)) + else + L.Weaken(round(agony/2)) - // Simple Animals. - if(istype(L, /mob/living/simple_animal/slime)) - var/mob/living/simple_animal/SA = L - if(SA.intelligence_level <= SA_ANIMAL) // So it doesn't stun hivebots or syndies. - SA.Weaken(round(agony/2)) // Less powerful since its ranged, and therefore safer. - if(isslime(SA)) - var/mob/living/simple_animal/slime/S = SA - S.adjust_discipline(round(agony/2)) - - // Prometheans. if(ishuman(L)) var/mob/living/carbon/human/H = L if(H.species && H.species.name == SPECIES_PROMETHEAN) - if(agony == initial(agony)) + if(agony == initial(agony)) // ?????? agony = round((14 * agony) - agony) //60-4 = 56, 56 / 4 = 14. Prior was flat 60 - agony of the beam to equate to 60. + ..() diff --git a/code/modules/xenobio/machinery/processor.dm b/code/modules/xenobio/machinery/processor.dm index 56b7cee3bf..6d888adb26 100644 --- a/code/modules/xenobio/machinery/processor.dm +++ b/code/modules/xenobio/machinery/processor.dm @@ -79,8 +79,8 @@ playsound(src.loc, 'sound/machines/ding.ogg', 50, 1) /obj/machinery/processor/proc/extract(var/atom/movable/AM) - if(istype(AM, /mob/living/simple_animal/slime)) - var/mob/living/simple_animal/slime/S = AM + if(istype(AM, /mob/living/simple_mob/slime)) + var/mob/living/simple_mob/slime/S = AM while(S.cores) new S.coretype(get_turf(src)) playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) @@ -98,8 +98,8 @@ sleep(1 SECOND) /obj/machinery/processor/proc/can_insert(var/atom/movable/AM) - if(istype(AM, /mob/living/simple_animal/slime)) - var/mob/living/simple_animal/slime/S = AM + if(istype(AM, /mob/living/simple_mob/slime)) + var/mob/living/simple_mob/slime/S = AM if(S.stat != DEAD) return FALSE return TRUE diff --git a/code/modules/xenobio2/machinery/core_extractor.dm b/code/modules/xenobio2/machinery/core_extractor.dm index 8bb5bc42fb..e78a162036 100644 --- a/code/modules/xenobio2/machinery/core_extractor.dm +++ b/code/modules/xenobio2/machinery/core_extractor.dm @@ -12,7 +12,7 @@ anchored = 1 circuit = /obj/item/weapon/circuitboard/slimeextractor var/inuse - var/mob/living/simple_animal/xeno/slime/occupant = null + var/mob/living/simple_mob/xeno/slime/occupant = null var/occupiedcolor = "#22FF22" var/emptycolor = "#FF2222" var/operatingcolor = "#FFFF22" @@ -69,11 +69,11 @@ to_chat(user, "The core extractor is locked and running, wait for it to finish.") return - if(!(istype(victim, /mob/living/simple_animal/xeno/slime))) + if(!(istype(victim, /mob/living/simple_mob/xeno/slime))) to_chat(user, "This is not a suitable subject for the core extractor!") return - var/mob/living/simple_animal/xeno/slime/S = victim + var/mob/living/simple_mob/xeno/slime/S = victim if(S.is_child) to_chat(user, "This subject is not developed enough for the core extractor!") return diff --git a/code/modules/xenobio2/machinery/gene_manipulators.dm b/code/modules/xenobio2/machinery/gene_manipulators.dm index 76bab91b59..4b2081b7d7 100644 --- a/code/modules/xenobio2/machinery/gene_manipulators.dm +++ b/code/modules/xenobio2/machinery/gene_manipulators.dm @@ -263,7 +263,7 @@ disk_needs_genes = 1 circuit = /obj/item/weapon/circuitboard/biobombarder - var/mob/living/simple_animal/xeno/slime/occupant + var/mob/living/simple_mob/xeno/slime/occupant /obj/machinery/xenobio/editor/New() ..() @@ -284,7 +284,7 @@ return else if(isxeno(G.affecting)) - var/mob/living/simple_animal/xeno/X = G.affecting + var/mob/living/simple_mob/xeno/X = G.affecting if(do_after(user, 30) && X.Adjacent(src) && user.Adjacent(src) && X.Adjacent(user) && !occupant) user.drop_from_inventory(G) X.forceMove(src) @@ -381,7 +381,7 @@ to_chat(user, "The [src] is locked and running, wait for it to finish.") return - if(!(istype(victim, /mob/living/simple_animal/xeno/slime)) ) + if(!(istype(victim, /mob/living/simple_mob/xeno/slime)) ) to_chat(user, "This is not a suitable subject for the [src]!") return diff --git a/code/modules/xenobio2/machinery/injector.dm b/code/modules/xenobio2/machinery/injector.dm index c181f1f104..5761f6b390 100644 --- a/code/modules/xenobio2/machinery/injector.dm +++ b/code/modules/xenobio2/machinery/injector.dm @@ -51,7 +51,7 @@ user << "The injector is full, empty it first!" return - if(!(istype(victim, /mob/living/simple_animal/xeno)) && !emagged) + if(!(istype(victim, /mob/living/simple_mob/xeno)) && !emagged) user << "This is not a suitable subject for the injector!" return @@ -85,7 +85,7 @@ if(!occupant) return if(isxeno(occupant)) - var/mob/living/simple_animal/xeno/X = occupant + var/mob/living/simple_mob/xeno/X = occupant beaker.reagents.trans_to_holder(X.reagents, computer.transfer_amount, 1, 0) else beaker.reagents.trans_to_mob(occupant, computer.transfer_amount) diff --git a/code/modules/xenobio2/machinery/injector_computer.dm b/code/modules/xenobio2/machinery/injector_computer.dm index 4632505c73..152e181e90 100644 --- a/code/modules/xenobio2/machinery/injector_computer.dm +++ b/code/modules/xenobio2/machinery/injector_computer.dm @@ -59,7 +59,7 @@ if(injector.occupant) data["occupied"] = 1 if(isxeno(injector.occupant)) - var/mob/living/simple_animal/xeno/X = injector.occupant + var/mob/living/simple_mob/xeno/X = injector.occupant data["compatible"] = 1 data["instability"] = 100 * (X.mut_level / X.mut_max) else diff --git a/code/modules/xenobio2/machinery/slime_replicator.dm b/code/modules/xenobio2/machinery/slime_replicator.dm index 8fb54929fe..dfd9ac3d6e 100644 --- a/code/modules/xenobio2/machinery/slime_replicator.dm +++ b/code/modules/xenobio2/machinery/slime_replicator.dm @@ -71,7 +71,7 @@ update_light_color() icon_state = "restruct_1" spawn(30) - var/mob/living/simple_animal/xeno/slime/S = new(src) + var/mob/living/simple_mob/xeno/slime/S = new(src) S.traitdat = new() //New instance, so that if the core is deleted, the slime retains a trait datum. S.nameVar = core.nameVar S.name = "[S.nameVar] baby slime" diff --git a/code/modules/xenobio2/mob/slime/slime life.dm b/code/modules/xenobio2/mob/slime/slime life.dm index 4853454476..ef5f4aa2a5 100644 --- a/code/modules/xenobio2/mob/slime/slime life.dm +++ b/code/modules/xenobio2/mob/slime/slime life.dm @@ -3,7 +3,7 @@ Slime specific life events go here. */ #define HAPPYLEVEL 200 #define ANGRYLEVEL 10 -/mob/living/simple_animal/xeno/slime/Life() +/mob/living/simple_mob/xeno/slime/Life() . = ..() if(..()) if(health) @@ -15,8 +15,8 @@ Slime specific life events go here. growthcounter-- if(growthcounter >= growthpoint) src.GrowUp() - - else + + else if(nutrition < 0) nutrition = 0 if((prob(10) && !emote_on)) //Slimes might display their food-based emotions over time. @@ -28,7 +28,7 @@ Slime specific life events go here. I.icon_state = "aslime-:33" else I.icon_state = "aslime-:3" - + else if((nutrition > ANGRYLEVEL)) if((nutrition >= 10 * ANGRYLEVEL)) I.icon_state = "aslime-pout" @@ -41,7 +41,7 @@ Slime specific life events go here. spawn(30) GenerateAdultIcon() emote_on = null - + else if(is_child) icon_state = "slime baby dead" @@ -49,7 +49,7 @@ Slime specific life events go here. overlays.Cut() icon_state = "slime adult dead" color = traitdat.traits[TRAIT_XENO_COLOR] - + return 0 //Everything worked okay - + return //xeno/Life() returned 0. \ No newline at end of file diff --git a/code/modules/xenobio2/mob/slime/slime procs.dm b/code/modules/xenobio2/mob/slime/slime procs.dm index f2ee6013b7..bd74562d9f 100644 --- a/code/modules/xenobio2/mob/slime/slime procs.dm +++ b/code/modules/xenobio2/mob/slime/slime procs.dm @@ -2,10 +2,10 @@ Slime specific procs go here. */ #define SHINYOVERLAY 0 -#define LIGHTOVERLAY 1 +#define LIGHTOVERLAY 1 #define MAXOVERLAY 2 //Should be 1 + last overlay, to give the chance for matte slimes -/mob/living/simple_animal/xeno/slime/RandomizeTraits() +/mob/living/simple_mob/xeno/slime/RandomizeTraits() traitdat.traits[TRAIT_XENO_COLDRES] = rand(30,270) traitdat.traits[TRAIT_XENO_HEATRES] = rand(30,270) traitdat.traits[TRAIT_XENO_CHEMVOL] = round(rand(20,40)) //Wow, a slime core with the capacity to hold 2/3rd's a beaker's worth of chemicals. @@ -23,8 +23,8 @@ Slime specific procs go here. traitdat.traits[TRAIT_XENO_STR_RANGE] =round(rand(0,2)) traitdat.traits[TRAIT_XENO_CANLEARN] = prob(68) traitdat.traits[TRAIT_XENO_SPEED] = round(rand(-10,10)) - -/mob/living/simple_animal/xeno/slime/RandomChemicals() + +/mob/living/simple_mob/xeno/slime/RandomChemicals() ..() if(prob(40)) var/hasMutToxin @@ -34,7 +34,7 @@ Slime specific procs go here. var/chemamount if(hasMutToxin) var/list/chemchoices = (xenoChemList - traitdat.chems) - + var/chemtype = pick(chemchoices) chemamount = rand(1,5) traitdat.chems[chemtype] = chemamount @@ -42,16 +42,16 @@ Slime specific procs go here. chemamount = rand(1,5) traitdat.chems["mutationtoxin"] = chemamount -/mob/living/simple_animal/xeno/slime/proc/GrowUp() +/mob/living/simple_mob/xeno/slime/proc/GrowUp() GenerateAdult() - + maxHealth = traitdat.get_trait(TRAIT_XENO_HEALTH) health = maxHealth is_child = 0 - + return 1 - -/mob/living/simple_animal/xeno/slime/Mutate() + +/mob/living/simple_mob/xeno/slime/Mutate() ..() cores = round(rand(1,9)) if(is_child) @@ -59,8 +59,8 @@ Slime specific procs go here. GenerateChild() else GenerateAdult() - -/mob/living/simple_animal/xeno/slime/proc/GenerateChild() + +/mob/living/simple_mob/xeno/slime/proc/GenerateChild() overlays.Cut() name = "[nameVar] baby slime" real_name = "[nameVar] baby slime" @@ -71,10 +71,10 @@ Slime specific procs go here. color = traitdat.traits[TRAIT_XENO_COLOR] maxHealth = traitdat.traits[TRAIT_XENO_HEALTH]/2 health = maxHealth - + return 1 - -/mob/living/simple_animal/xeno/slime/proc/GenerateAdult() + +/mob/living/simple_mob/xeno/slime/proc/GenerateAdult() overlays.Cut() name = "[nameVar] slime" real_name = "[nameVar] slime" @@ -83,15 +83,15 @@ Slime specific procs go here. icon_state = "" overlay = round(rand(0, MAXOVERLAY)) GenerateAdultIcon() - -/mob/living/simple_animal/xeno/slime/proc/GenerateAdultIcon() //Hack and slash adventure game to make slimes have no color on light effects later + +/mob/living/simple_mob/xeno/slime/proc/GenerateAdultIcon() //Hack and slash adventure game to make slimes have no color on light effects later overlays.Cut() var/image/Img = new(src.icon) Img.icon_state = "slime adult" Img.color = traitdat.traits[TRAIT_XENO_COLOR] Img.layer = src.layer overlays += Img - + switch(overlay) if(SHINYOVERLAY) var/image/I = new(src.icon) @@ -109,7 +109,7 @@ Slime specific procs go here. I.color = "#FFFFFF" overlays += I -/mob/living/simple_animal/xeno/slime/handle_reagents() +/mob/living/simple_mob/xeno/slime/handle_reagents() if(!stasis) if(!reagents) return @@ -119,11 +119,10 @@ Slime specific procs go here. hostile = 0 traitdat.traits[TRAIT_XENO_HOSTILE] = 0 ..() - -/mob/living/simple_animal/xeno/slime/ProcessTraits() + +/mob/living/simple_mob/xeno/slime/ProcessTraits() ..() if(is_child) GenerateChild() else GenerateAdult() - \ No newline at end of file diff --git a/code/modules/xenobio2/mob/slime/slime.dm b/code/modules/xenobio2/mob/slime/slime.dm index 44a1246e1d..3d52c053d8 100644 --- a/code/modules/xenobio2/mob/slime/slime.dm +++ b/code/modules/xenobio2/mob/slime/slime.dm @@ -1,7 +1,7 @@ /* Slime definitions, Life and New live here. */ -/mob/living/simple_animal/xeno/slime //Adult values are found here +/mob/living/simple_mob/xeno/slime //Adult values are found here nameVar = "grey" //When mutated, nameVar might change. desc = "A shifting, mass of goo." faction = "slime" @@ -80,7 +80,7 @@ Slime definitions, Life and New live here. "woodpulp" = list("heal" = 0.1, "nutr" = 0.7), "docilitytoxin" = list("nutr" = 0.3) ) -/mob/living/simple_animal/xeno/slime/New() +/mob/living/simple_mob/xeno/slime/New() ..() for(var/datum/language/L in (typesof(/datum/language) - /datum/language)) languages += L diff --git a/code/modules/xenobio2/mob/xeno procs.dm b/code/modules/xenobio2/mob/xeno procs.dm index 03fde9efc8..4b05bbf2e9 100644 --- a/code/modules/xenobio2/mob/xeno procs.dm +++ b/code/modules/xenobio2/mob/xeno procs.dm @@ -8,7 +8,7 @@ Procs for copying speech, if applicable Procs for targeting Divergence proc, used in mutation to make unique datums. */ -/mob/living/simple_animal/xeno/proc/ProcessTraits() +/mob/living/simple_mob/xeno/proc/ProcessTraits() if(maleable >= MAX_MALEABLE) maxHealth = traitdat.get_trait(TRAIT_XENO_HEALTH) health = maxHealth @@ -46,7 +46,7 @@ Divergence proc, used in mutation to make unique datums. //Metabolism proc, simplified for xenos. Heavily based on botanical metabolism. -/mob/living/simple_animal/xeno/proc/handle_reagents() +/mob/living/simple_mob/xeno/proc/handle_reagents() if(!stasis) if(!reagents) return @@ -85,13 +85,13 @@ Divergence proc, used in mutation to make unique datums. return 1 //Everything worked out okay. return 0 - -/mob/living/simple_animal/xeno/proc/diverge() + +/mob/living/simple_mob/xeno/proc/diverge() var/datum/xeno/traits/newtraits = new() newtraits.copy_traits(traitdat) return newtraits -/mob/living/simple_animal/xeno/proc/Mutate() +/mob/living/simple_mob/xeno/proc/Mutate() traitdat = diverge() nameVar = "mutated" if((COLORMUT & mutable)) @@ -109,10 +109,10 @@ Divergence proc, used in mutation to make unique datums. ProcessTraits() return 1 -/mob/living/simple_animal/xeno/proc/RandomizeTraits() +/mob/living/simple_mob/xeno/proc/RandomizeTraits() return -/mob/living/simple_animal/xeno/hear_say(var/message, var/verb = "says", var/datum/language/language, var/alt_name = "",var/italics = 0, var/mob/speaker = null) +/mob/living/simple_mob/xeno/hear_say(var/message, var/verb = "says", var/datum/language/language, var/alt_name = "",var/italics = 0, var/mob/speaker = null) if(traitdat.traits[TRAIT_XENO_CANLEARN]) /* Until this gets sorted out to a functioning point, or waiting on Psi's saycode update. @@ -130,7 +130,7 @@ Divergence proc, used in mutation to make unique datums. speech_buffer.Add(message) ..(message,verb,language,alt_name,italics,speaker) -/mob/living/simple_animal/xeno/proc/ProcessSpeechBuffer() +/mob/living/simple_mob/xeno/proc/ProcessSpeechBuffer() if(speech_buffer.len) if(prob(traitdat.get_trait(TRAIT_XENO_LEARNCHANCE)) && traitdat.get_trait(TRAIT_XENO_CANLEARN)) var/chosen = pick(speech_buffer) @@ -140,10 +140,10 @@ Divergence proc, used in mutation to make unique datums. log_debug("Speechlist cut.") */ speech_buffer.Cut() // -/mob/living/simple_animal/xeno/proc/BuildReagentLists() +/mob/living/simple_mob/xeno/proc/BuildReagentLists() return -/mob/living/simple_animal/xeno/bullet_act(var/obj/item/projectile/P) +/mob/living/simple_mob/xeno/bullet_act(var/obj/item/projectile/P) //Shamelessly stolen from ablative armor. if((traitdat.traits[TRAIT_XENO_CHROMATIC]) && istype(P, /obj/item/projectile/beam)) visible_message(")\The beam reflects off of the [src]!") @@ -161,7 +161,7 @@ Divergence proc, used in mutation to make unique datums. else ..() -/mob/living/simple_animal/xeno/proc/RandomChemicals() +/mob/living/simple_mob/xeno/proc/RandomChemicals() traitdat.chems.Cut() //Clear the amount first. var/num_chems = round(rand(1,4)) diff --git a/code/modules/xenobio2/mob/xeno.dm b/code/modules/xenobio2/mob/xeno.dm index 9a854e9d8e..648c1f1e10 100644 --- a/code/modules/xenobio2/mob/xeno.dm +++ b/code/modules/xenobio2/mob/xeno.dm @@ -5,7 +5,7 @@ Basic definition of creatures for Xenobiology Also includes Life and New */ -/mob/living/simple_animal/xeno +/mob/living/simple_mob/xeno name = "Xeno" real_name = "Xeno" faction = "xeno" //Needs to be set. @@ -46,7 +46,7 @@ Also includes Life and New //Life additions -/mob/living/simple_animal/xeno/Life() +/mob/living/simple_mob/xeno/Life() if(stasis) stasis-- if(stasis < 0) @@ -74,7 +74,7 @@ Also includes Life and New return 1 //Everything worked okay. -/mob/living/simple_animal/xeno/New() +/mob/living/simple_mob/xeno/New() traitdat = new() @@ -95,13 +95,13 @@ Also includes Life and New if(!health) stat = DEAD -/mob/living/simple_animal/xeno/bullet_act(var/obj/item/projectile/Proj) +/mob/living/simple_mob/xeno/bullet_act(var/obj/item/projectile/Proj) if(istype(Proj, /obj/item/projectile/beam/stun/xeno)) var/obj/item/projectile/beam/stun/xeno/hit = Proj stasis += hit.stasisforce ..() -/mob/living/simple_animal/xeno/Destroy() +/mob/living/simple_mob/xeno/Destroy() traitdat.Destroy() //Let's clean up after ourselves. traitdat = null ..() \ No newline at end of file diff --git a/code/modules/xenobio2/tools/xeno_trait_scanner.dm b/code/modules/xenobio2/tools/xeno_trait_scanner.dm index 565db47364..6de41cc3d4 100644 --- a/code/modules/xenobio2/tools/xeno_trait_scanner.dm +++ b/code/modules/xenobio2/tools/xeno_trait_scanner.dm @@ -45,15 +45,15 @@ var/growth_max if(istype(target,/obj/structure/table)) return ..() - else if(istype(target,/mob/living/simple_animal/xeno)) + else if(istype(target,/mob/living/simple_mob/xeno)) - var/mob/living/simple_animal/xeno/X = target - if(istype(X, /mob/living/simple_animal/xeno/slime)) - var/mob/living/simple_animal/xeno/slime/S = X + var/mob/living/simple_mob/xeno/X = target + if(istype(X, /mob/living/simple_mob/xeno/slime)) + var/mob/living/simple_mob/xeno/slime/S = X if(S.is_child) growth_level = S.growthcounter growth_max = S.growthpoint - + targetName = X.name trait_info = X.traitdat @@ -109,7 +109,7 @@ dat += "It bears characteristics that indicate susceptibility to damage.
      " else dat += "It bears no characters indicating resilience to damage.
      " - + if(growth_max) if(growth_level < 35) dat += "It appears to be far to growing up.
      " @@ -137,7 +137,7 @@ dat += "It appears to be agile.
      " else if(trait_info.get_trait(TRAIT_XENO_SPEED) > 0) dat += "It appears to be slower.
      " - + if(trait_info.get_trait(TRAIT_XENO_CANSPEAK)) dat += "
      The subject appears to be able to articulate." @@ -149,18 +149,18 @@ if(trait_info.get_trait(TRAIT_XENO_CANLEARN)) dat += "
      The subject appears to have process verbal information." - + if(trait_info.get_trait(TRAIT_XENO_LEARNCHANCE)) if(trait_info.get_trait(TRAIT_XENO_LEARNCHANCE) < 50) dat += "The subject appears to comprehend verbal information infrequently.
      " else if(trait_info.get_trait(TRAIT_XENO_LEARNCHANCE) > 51) dat += "The subject appears to comprehend verbal information frequently.
      " - + if(trait_info.get_trait(TRAIT_XENO_STRENGTH) < 5) dat += "It appears to have lower average physical capacity.
      " else if(trait_info.get_trait(TRAIT_XENO_STRENGTH) > 7) dat += "It appears to have greater average physical capacity.
      " - + if(trait_info.get_trait(TRAIT_XENO_STR_RANGE)) if(trait_info.get_trait(TRAIT_XENO_STR_RANGE) < 50) dat += "The subject appears to have more consistent attacks.
      " @@ -172,11 +172,11 @@ if(trait_info.get_trait(TRAIT_XENO_HOSTILE)) dat += "
      The subject appears to have hostile tendencies." - + if(trait_info.get_trait(TRAIT_XENO_CHROMATIC)) dat += "
      The subject appears to have chromatic particles inside of it." - + if(dat) last_data = dat dat += "

      \[print report\]" diff --git a/code/stylesheet.dm b/code/stylesheet.dm index 25e317e6e4..1a09a30f40 100644 --- a/code/stylesheet.dm +++ b/code/stylesheet.dm @@ -111,4 +111,11 @@ h1.alert, h2.alert {color: #000000;} BIG IMG.icon {width: 32px; height: 32px;} +/* Debug Logs */ +.debug_error {color:#FF0000; font-weight:bold} +.debug_warning {color:#FF0000;} +.debug_info {} +.debug_debug {color:#0000FF;} +.debug_trace {color:#888888;} + "} diff --git a/code/unit_tests/research_tests.dm b/code/unit_tests/research_tests.dm index 93bf79a0da..24d307c5e6 100644 --- a/code/unit_tests/research_tests.dm +++ b/code/unit_tests/research_tests.dm @@ -60,7 +60,7 @@ number_of_issues++ for(var/reagent_name in design.chemicals) - if(!(reagent_name in chemical_reagents_list)) + if(!(reagent_name in SSchemistry.chemical_reagents)) log_unit_test("The entry [design_type] has invalid chemical type [reagent_name]") number_of_issues++ diff --git a/code/world.dm b/code/world.dm index 785d44c084..1c43ce6132 100644 --- a/code/world.dm +++ b/code/world.dm @@ -1,669 +1,7 @@ - -/* - The initialization of the game happens roughly like this: - - 1. All global variables are initialized (including the global_init instance). - 2. The map is initialized, and map objects are created. - 3. world/New() runs, creating the process scheduler (and the old master controller) and spawning their setup. - 4. processScheduler/setup() runs, creating all the processes. game_controller/setup() runs, calling initialize() on all movable atoms in the world. - 5. The gameticker is created. - -*/ -var/global/datum/global_init/init = new () - -/* - Pre-map initialization stuff should go here. -*/ -/datum/global_init/New() - - makeDatumRefLists() - load_configuration() - - initialize_chemical_reagents() - initialize_chemical_reactions() - initialize_integrated_circuits_list() - - qdel(src) //we're done - -/datum/global_init/Destroy() - global.init = null - return 2 // QDEL_HINT_IWILLGC - +//Global init and the rest of world's code have been moved to code/global_init.dm and code/game/world.dm respectively. /world mob = /mob/new_player turf = /turf/space area = /area/space view = "15x15" cache_lifespan = 7 - - - -#define RECOMMENDED_VERSION 501 -/world/New() - world.log << "Map Loading Complete" - //logs - log_path += time2text(world.realtime, "YYYY/MM-Month/DD-Day/round-hh-mm-ss") - diary = start_log("[log_path].log") - href_logfile = start_log("[log_path]-hrefs.htm") - error_log = start_log("[log_path]-error.log") - debug_log = start_log("[log_path]-debug.log") - - changelog_hash = md5('html/changelog.html') //used for telling if the changelog has changed recently - - if(byond_version < RECOMMENDED_VERSION) - world.log << "Your server's byond version does not meet the recommended requirements for this server. Please update BYOND" - - config.post_load() - - if(config && config.server_name != null && config.server_suffix && world.port > 0) - // dumb and hardcoded but I don't care~ - config.server_name += " #[(world.port % 1000) / 100]" - - // TODO - Figure out what this is. Can you assign to world.log? - // if(config && config.log_runtime) - // log = file("data/logs/runtime/[time2text(world.realtime,"YYYY-MM-DD-(hh-mm-ss)")]-runtime.log") - - GLOB.timezoneOffset = text2num(time2text(0,"hh")) * 36000 - - callHook("startup") - //Emergency Fix - load_mods() - //end-emergency fix - - src.update_status() - - . = ..() - -#if UNIT_TEST - log_unit_test("Unit Tests Enabled. This will destroy the world when testing is complete.") - log_unit_test("If you did not intend to enable this please check code/__defines/unit_testing.dm") -#endif - - // Set up roundstart seed list. - plant_controller = new() - - // This is kinda important. Set up details of what the hell things are made of. - populate_material_list() - - // Loads all the pre-made submap templates. - load_map_templates() - - if(config.generate_map) - if(using_map.perform_map_generation()) - using_map.refresh_mining_turfs() - - // Create frame types. - populate_frame_types() - - // Create floor types. - populate_flooring_types() - - // Create robolimbs for chargen. - populate_robolimb_list() - - //Must be done now, otherwise ZAS zones and lighting overlays need to be recreated. - createRandomZlevel() - - processScheduler = new - master_controller = new /datum/controller/game_controller() - - processScheduler.deferSetupFor(/datum/controller/process/ticker) - processScheduler.setup() - Master.Initialize(10, FALSE) - - spawn(1) - master_controller.setup() -#if UNIT_TEST - initialize_unit_tests() -#endif - - spawn(3000) //so we aren't adding to the round-start lag - if(config.ToRban) - ToRban_autoupdate() - -#undef RECOMMENDED_VERSION - - return - -var/world_topic_spam_protect_ip = "0.0.0.0" -var/world_topic_spam_protect_time = world.timeofday - -/world/Topic(T, addr, master, key) - log_topic("\"[T]\", from:[addr], master:[master], key:[key]") - - if (T == "ping") - var/x = 1 - for (var/client/C) - x++ - return x - - else if(T == "players") - var/n = 0 - for(var/mob/M in player_list) - if(M.client) - n++ - return n - - else if (copytext(T,1,7) == "status") - var/input[] = params2list(T) - var/list/s = list() - s["version"] = game_version - s["mode"] = master_mode - s["respawn"] = config.abandon_allowed - s["enter"] = config.enter_allowed - s["vote"] = config.allow_vote_mode - s["ai"] = config.allow_ai - s["host"] = host ? host : null - - // This is dumb, but spacestation13.com's banners break if player count isn't the 8th field of the reply, so... this has to go here. - s["players"] = 0 - s["stationtime"] = stationtime2text() - s["roundduration"] = roundduration2text() - - if(input["status"] == "2") - var/list/players = list() - var/list/admins = list() - - for(var/client/C in clients) - if(C.holder) - if(C.holder.fakekey) - continue - admins[C.key] = C.holder.rank - players += C.key - - s["players"] = players.len - s["playerlist"] = list2params(players) - var/list/adm = get_admin_counts() - var/list/presentmins = adm["present"] - var/list/afkmins = adm["afk"] - s["admins"] = presentmins.len + afkmins.len //equivalent to the info gotten from adminwho - s["adminlist"] = list2params(admins) - else - var/n = 0 - var/admins = 0 - - for(var/client/C in clients) - if(C.holder) - if(C.holder.fakekey) - continue //so stealthmins aren't revealed by the hub - admins++ - s["player[n]"] = C.key - n++ - - s["players"] = n - s["admins"] = admins - - return list2params(s) - - else if(T == "manifest") - var/list/positions = list() - var/list/set_names = list( - "heads" = command_positions, - "sec" = security_positions, - "eng" = engineering_positions, - "med" = medical_positions, - "sci" = science_positions, - "car" = cargo_positions, - "civ" = civilian_positions, - "bot" = nonhuman_positions - ) - - for(var/datum/data/record/t in data_core.general) - var/name = t.fields["name"] - var/rank = t.fields["rank"] - var/real_rank = make_list_rank(t.fields["real_rank"]) - - var/department = 0 - for(var/k in set_names) - if(real_rank in set_names[k]) - if(!positions[k]) - positions[k] = list() - positions[k][name] = rank - department = 1 - if(!department) - if(!positions["misc"]) - positions["misc"] = list() - positions["misc"][name] = rank - - // Synthetics don't have actual records, so we will pull them from here. - for(var/mob/living/silicon/ai/ai in mob_list) - if(!positions["bot"]) - positions["bot"] = list() - positions["bot"][ai.name] = "Artificial Intelligence" - for(var/mob/living/silicon/robot/robot in mob_list) - // No combat/syndicate cyborgs, no drones. - if(robot.module && robot.module.hide_on_manifest) - continue - if(!positions["bot"]) - positions["bot"] = list() - positions["bot"][robot.name] = "[robot.modtype] [robot.braintype]" - - for(var/k in positions) - positions[k] = list2params(positions[k]) // converts positions["heads"] = list("Bob"="Captain", "Bill"="CMO") into positions["heads"] = "Bob=Captain&Bill=CMO" - - return list2params(positions) - - else if(T == "revision") - if(revdata.revision) - return list2params(list(branch = revdata.branch, date = revdata.date, revision = revdata.revision)) - else - return "unknown" - - else if(copytext(T,1,5) == "info") - var/input[] = params2list(T) - if(input["key"] != config.comms_password) - if(world_topic_spam_protect_ip == addr && abs(world_topic_spam_protect_time - world.time) < 50) - - spawn(50) - world_topic_spam_protect_time = world.time - return "Bad Key (Throttled)" - - world_topic_spam_protect_time = world.time - world_topic_spam_protect_ip = addr - - return "Bad Key" - - var/list/search = params2list(input["info"]) - var/list/ckeysearch = list() - for(var/text in search) - ckeysearch += ckey(text) - - var/list/match = list() - - for(var/mob/M in mob_list) - var/strings = list(M.name, M.ckey) - if(M.mind) - strings += M.mind.assigned_role - strings += M.mind.special_role - for(var/text in strings) - if(ckey(text) in ckeysearch) - match[M] += 10 // an exact match is far better than a partial one - else - for(var/searchstr in search) - if(findtext(text, searchstr)) - match[M] += 1 - - var/maxstrength = 0 - for(var/mob/M in match) - maxstrength = max(match[M], maxstrength) - for(var/mob/M in match) - if(match[M] < maxstrength) - match -= M - - if(!match.len) - return "No matches" - else if(match.len == 1) - var/mob/M = match[1] - var/info = list() - info["key"] = M.key - info["name"] = M.name == M.real_name ? M.name : "[M.name] ([M.real_name])" - info["role"] = M.mind ? (M.mind.assigned_role ? M.mind.assigned_role : "No role") : "No mind" - var/turf/MT = get_turf(M) - info["loc"] = M.loc ? "[M.loc]" : "null" - info["turf"] = MT ? "[MT] @ [MT.x], [MT.y], [MT.z]" : "null" - info["area"] = MT ? "[MT.loc]" : "null" - info["antag"] = M.mind ? (M.mind.special_role ? M.mind.special_role : "Not antag") : "No mind" - info["hasbeenrev"] = M.mind ? M.mind.has_been_rev : "No mind" - info["stat"] = M.stat - info["type"] = M.type - if(isliving(M)) - var/mob/living/L = M - info["damage"] = list2params(list( - oxy = L.getOxyLoss(), - tox = L.getToxLoss(), - fire = L.getFireLoss(), - brute = L.getBruteLoss(), - clone = L.getCloneLoss(), - brain = L.getBrainLoss() - )) - else - info["damage"] = "non-living" - info["gender"] = M.gender - return list2params(info) - else - var/list/ret = list() - for(var/mob/M in match) - ret[M.key] = M.name - return list2params(ret) - - else if(copytext(T,1,9) == "adminmsg") - /* - We got an adminmsg from IRC bot lets split the input then validate the input. - expected output: - 1. adminmsg = ckey of person the message is to - 2. msg = contents of message, parems2list requires - 3. validatationkey = the key the bot has, it should match the gameservers commspassword in it's configuration. - 4. sender = the ircnick that send the message. - */ - - - var/input[] = params2list(T) - if(input["key"] != config.comms_password) - if(world_topic_spam_protect_ip == addr && abs(world_topic_spam_protect_time - world.time) < 50) - - spawn(50) - world_topic_spam_protect_time = world.time - return "Bad Key (Throttled)" - - world_topic_spam_protect_time = world.time - world_topic_spam_protect_ip = addr - - return "Bad Key" - - var/client/C - var/req_ckey = ckey(input["adminmsg"]) - - for(var/client/K in clients) - if(K.ckey == req_ckey) - C = K - break - if(!C) - return "No client with that name on server" - - var/rank = input["rank"] - if(!rank) - rank = "Admin" - - var/message = "IRC-[rank] PM from IRC-[input["sender"]]: [input["msg"]]" - var/amessage = "IRC-[rank] PM from IRC-[input["sender"]] to [key_name(C)] : [input["msg"]]" - - C.received_irc_pm = world.time - C.irc_admin = input["sender"] - - C << 'sound/effects/adminhelp.ogg' - C << message - - - for(var/client/A in admins) - if(A != C) - A << amessage - - return "Message Successful" - - else if(copytext(T,1,6) == "notes") - /* - We got a request for notes from the IRC Bot - expected output: - 1. notes = ckey of person the notes lookup is for - 2. validationkey = the key the bot has, it should match the gameservers commspassword in it's configuration. - */ - var/input[] = params2list(T) - if(input["key"] != config.comms_password) - if(world_topic_spam_protect_ip == addr && abs(world_topic_spam_protect_time - world.time) < 50) - - spawn(50) - world_topic_spam_protect_time = world.time - return "Bad Key (Throttled)" - - world_topic_spam_protect_time = world.time - world_topic_spam_protect_ip = addr - return "Bad Key" - - return show_player_info_irc(ckey(input["notes"])) - - else if(copytext(T,1,4) == "age") - var/input[] = params2list(T) - if(input["key"] != config.comms_password) - if(world_topic_spam_protect_ip == addr && abs(world_topic_spam_protect_time - world.time) < 50) - spawn(50) - world_topic_spam_protect_time = world.time - return "Bad Key (Throttled)" - - world_topic_spam_protect_time = world.time - world_topic_spam_protect_ip = addr - return "Bad Key" - - var/age = get_player_age(input["age"]) - if(isnum(age)) - if(age >= 0) - return "[age]" - else - return "Ckey not found" - else - return "Database connection failed or not set up" - - -/world/Reboot(var/reason) - /*spawn(0) - world << sound(pick('sound/AI/newroundsexy.ogg','sound/misc/apcdestroyed.ogg','sound/misc/bangindonk.ogg')) // random end sounds!! - LastyBatsy - */ - - processScheduler.stop() - Master.Shutdown() //run SS shutdowns - - for(var/client/C in clients) - if(config.server) //if you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite - C << link("byond://[config.server]") - - shutdown_logging() // Past this point, no logging procs can be used, at risk of data loss. - ..(reason) - -/hook/startup/proc/loadMode() - world.load_mode() - return 1 - -/world/proc/load_mode() - if(!fexists("data/mode.txt")) - return - - - var/list/Lines = file2list("data/mode.txt") - if(Lines.len) - if(Lines[1]) - master_mode = Lines[1] - log_misc("Saved mode is '[master_mode]'") - -/world/proc/save_mode(var/the_mode) - var/F = file("data/mode.txt") - fdel(F) - F << the_mode - - -/hook/startup/proc/loadMOTD() - world.load_motd() - return 1 - -/world/proc/load_motd() - join_motd = file2text("config/motd.txt") - - -/proc/load_configuration() - config = new /datum/configuration() - config.load("config/config.txt") - config.load("config/game_options.txt","game_options") - config.loadsql("config/dbconfig.txt") - config.loadforumsql("config/forumdbconfig.txt") - -/hook/startup/proc/loadMods() - world.load_mods() - world.load_mentors() // no need to write another hook. - return 1 - -/world/proc/load_mods() - if(config.admin_legacy_system) - var/text = file2text("config/moderators.txt") - if (!text) - error("Failed to load config/mods.txt") - else - var/list/lines = splittext(text, "\n") - for(var/line in lines) - if (!line) - continue - - if (copytext(line, 1, 2) == ";") - continue - - var/title = "Moderator" - var/rights = admin_ranks[title] - - var/ckey = copytext(line, 1, length(line)+1) - var/datum/admins/D = new /datum/admins(title, rights, ckey) - D.associate(directory[ckey]) - -/world/proc/load_mentors() - if(config.admin_legacy_system) - var/text = file2text("config/mentors.txt") - if (!text) - error("Failed to load config/mentors.txt") - else - var/list/lines = splittext(text, "\n") - for(var/line in lines) - if (!line) - continue - if (copytext(line, 1, 2) == ";") - continue - - var/title = "Mentor" - var/rights = admin_ranks[title] - - var/ckey = copytext(line, 1, length(line)+1) - var/datum/admins/D = new /datum/admins(title, rights, ckey) - D.associate(directory[ckey]) - -/world/proc/update_status() - var/s = "" - - if (config && config.server_name) - s += "[config.server_name] — " - - s += "[station_name()]"; - s += " (" - s += "" //Change this to wherever you want the hub to link to. -// s += "[game_version]" - s += "Default" //Replace this with something else. Or ever better, delete it and uncomment the game version. - s += "" - s += ")" - - var/list/features = list() - - if(ticker) - if(master_mode) - features += master_mode - else - features += "STARTING" - - if (!config.enter_allowed) - features += "closed" - - features += config.abandon_allowed ? "respawn" : "no respawn" - - if (config && config.allow_vote_mode) - features += "vote" - - if (config && config.allow_ai) - features += "AI allowed" - - var/n = 0 - for (var/mob/M in player_list) - if (M.client) - n++ - - if (n > 1) - features += "~[n] players" - else if (n > 0) - features += "~[n] player" - - - if (config && config.hostedby) - features += "hosted by [config.hostedby]" - - if (features) - s += ": [jointext(features, ", ")]" - - /* does this help? I do not know */ - if (src.status != s) - src.status = s - -#define FAILED_DB_CONNECTION_CUTOFF 5 -var/failed_db_connections = 0 -var/failed_old_db_connections = 0 - -/hook/startup/proc/connectDB() - if(!config.sql_enabled) - world.log << "SQL connection disabled in config." - else if(!setup_database_connection()) - world.log << "Your server failed to establish a connection with the feedback database." - else - world.log << "Feedback database connection established." - return 1 - -proc/setup_database_connection() - - if(failed_db_connections > FAILED_DB_CONNECTION_CUTOFF) //If it failed to establish a connection more than 5 times in a row, don't bother attempting to conenct anymore. - return 0 - - if(!dbcon) - dbcon = new() - - var/user = sqlfdbklogin - var/pass = sqlfdbkpass - var/db = sqlfdbkdb - var/address = sqladdress - var/port = sqlport - - dbcon.Connect("dbi:mysql:[db]:[address]:[port]","[user]","[pass]") - . = dbcon.IsConnected() - if ( . ) - failed_db_connections = 0 //If this connection succeeded, reset the failed connections counter. - else - failed_db_connections++ //If it failed, increase the failed connections counter. - world.log << dbcon.ErrorMsg() - - return . - -//This proc ensures that the connection to the feedback database (global variable dbcon) is established -proc/establish_db_connection() - if(failed_db_connections > FAILED_DB_CONNECTION_CUTOFF) - return 0 - - if(!dbcon || !dbcon.IsConnected()) - return setup_database_connection() - else - return 1 - - -/hook/startup/proc/connectOldDB() - if(!config.sql_enabled) - world.log << "SQL connection disabled in config." - else if(!setup_old_database_connection()) - world.log << "Your server failed to establish a connection with the SQL database." - else - world.log << "SQL database connection established." - return 1 - -//These two procs are for the old database, while it's being phased out. See the tgstation.sql file in the SQL folder for more information. -proc/setup_old_database_connection() - - if(failed_old_db_connections > FAILED_DB_CONNECTION_CUTOFF) //If it failed to establish a connection more than 5 times in a row, don't bother attempting to conenct anymore. - return 0 - - if(!dbcon_old) - dbcon_old = new() - - var/user = sqllogin - var/pass = sqlpass - var/db = sqldb - var/address = sqladdress - var/port = sqlport - - dbcon_old.Connect("dbi:mysql:[db]:[address]:[port]","[user]","[pass]") - . = dbcon_old.IsConnected() - if ( . ) - failed_old_db_connections = 0 //If this connection succeeded, reset the failed connections counter. - else - failed_old_db_connections++ //If it failed, increase the failed connections counter. - world.log << dbcon.ErrorMsg() - - return . - -//This proc ensures that the connection to the feedback database (global variable dbcon) is established -proc/establish_old_db_connection() - if(failed_old_db_connections > FAILED_DB_CONNECTION_CUTOFF) - return 0 - - if(!dbcon_old || !dbcon_old.IsConnected()) - return setup_old_database_connection() - else - return 1 - -#undef FAILED_DB_CONNECTION_CUTOFF diff --git a/config/example/config.txt b/config/example/config.txt index 8f5362c01a..1f894b7387 100644 --- a/config/example/config.txt +++ b/config/example/config.txt @@ -94,6 +94,7 @@ SHOW_MODS ##Show mentors on staffwho SHOW_EVENT + ## Chooses whether mods have the ability to tempban or not MODS_CAN_TEMPBAN @@ -397,8 +398,8 @@ STARLIGHT 0 ## Uncomment to override default brain health. #DEFAULT_BRAIN_HEALTH 400 -## Default language prefix keys, separated with spaces. Only single character keys are supported. If unset, defaults to , # and - -# DEFAULT_LANGUAGE_PREFIXES , # - +## Default language prefix keys, separated with spaces. Only single character keys are supported. If unset, defaults to , and # +# DEFAULT_LANGUAGE_PREFIXES , # # Control which submaps are loaded for the Dynamic Engine system ENGINE_MAP Supermatter Engine,Edison's Bane @@ -416,3 +417,7 @@ ENGINE_MAP Supermatter Engine,Edison's Bane ## Uncomment to enable Paranoia Logging. This will notify admins and write to a file any time a new player (byond or your server) connects. # PARANOIA_LOGGING +## Uncomment to enable submaps to have their orientation rotated randomly during map generation. +## Submap rotation is an experimental feature and can cause bugs and weirdness if certain objects inside the submap are coded poorly. +## Submaps can still be rotated when loading manually with the admin verbs, if desired. +# RANDOM_SUBMAP_ORIENTATION diff --git a/html/changelog.html b/html/changelog.html index 91fdd23b30..c8cee8ad58 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -53,6 +53,81 @@ -->
      +

      08 December 2018

      +

      Cerebulon updated:

      +
        +
      • Added 12 new loadout items plus colour variants: Utility pants, sleek overalls, sari, modern wrap jacket, ascetic garb, asymmetrical jackets, cowled vest, kamishimo, jingasa, maang tikka, thin-frame glasses, rimless glasses.
      • +
      +

      Mechoid updated:

      +
        +
      • Research and Engineering borgs now have 'Circuit Grippers', used for constructing and operating integrated circuit machinery.
      • +
      • Grippers now allow interaction with their contents, by attacking the gripper itself with an item when one is held. I.E., drawing from a beaker with a syringe.
      • +
      • Grippers now show their held item's examine information when examined. Tab information added.
      • +
      • Cyborgs can now interact with integrated circuit printers and machines when adjacent to them.
      • +
      • Multitools now have a menu to switch modes between standard use and integrated circuit reference scanning. Antag multi-tools untouched for now.
      • +
      • Integrated circuit printer now respects adjacency, if it is not set to debug.
      • +
      + +

      30 November 2018

      +

      Cerebulon updated:

      +
        +
      • Added 1000+ surnames and 1200+ forenames from various world cultures to human namelists
      • +
      +

      LBnesquik updated:

      +
        +
      • Replaced the plant clippers with a reskinned pair of hedgetrimmers.
      • +
      +

      Lbnesquik updated:

      +
        +
      • General biogenerator improvements:
      • +
      • Added feedback noise to the processing.
      • +
      • Allow for cream dispensing.
      • +
      • Allow for plant bag creation.
      • +
      • Allow for 5 units of meat to be dispensed at once.
      • +
      • Allow for 5 units of liquids to be dispensed at once totalling 50u.
      • +
      • Add and allow the creation of larger plant bags for easier ferrying of plants..
      • +
      • Add a description to the machine itself.
      • +
      +

      Mechoid updated:

      +
        +
      • Prometheans are no longer murdered by blood, and instead process it like a weak nutrient. Will slow the regeneration of toxins due to water content.
      • +
      • Ctrl clicking a Rapid Service Fabricator when held will allow you to choose the container it deploys.
      • +
      • The Rapid Service Fabricator's icon is correctly set.
      • +
      +

      Neerti updated:

      +
        +
      • Rewrites the AI system for mobs. It should be more responsive and robust. Some mobs have special AIs which can do certain things like kiting, following you on a lark, or telling you to go away before shooting you.
      • +
      • Rewrites literally every 'simple_animal' mob into new, shinier, and hopefully more interesting 'simple_mob' mobs, some with new mechanics, like spiders, fake mechas, and hivebots. There are so many changes that it wouldn't be possible to list them here.
      • +
      • RCDs can now build grilles and windows, with a new mode. They can also finish walls when used on girders on floor/wall mode.
      • +
      • Adds various new RCDs that are not obtainable at the moment.
      • +
      +

      Woodrat updated:

      +
        +
      • Xenoflora and Xenobio moved to station, first deck.
      • +
      • Minor bugfixes including mislabeled lockers in robotics and floor decals.
      • +
      +

      kartagrafi updated:

      +
        +
      • Adds new hairstyle 'Sharp Ponytail'
      • +
      • Adds several new underwear - 'Binder', 'Strapless Binder', 'Longsleeve Striped Shirt, Pink', 'Pink Wing Shirt', 'Pink and Black T-Shirt', 'Leggings'
      • +
      • Changes name of 'Supernova' hairstyle to 'Glossy', and makes the sprite somewhat neater
      • +
      • Fixes a hairstyle not appearing
      • +
      + +

      13 October 2018

      +

      Anewbe updated:

      +
        +
      • You can no longer have ALL of your blood punched out.
      • +
      • Haemophiliacs will no longer spontaneously have ALL of their blood go missing from ~90%.
      • +
      • Emitters can be locked while off, too.
      • +
      • Graves are now a thing in the code, will need some testing and probably more work before they get more common.
      • +
      +

      Mechoid updated:

      +
        +
      • Added a RIG customization kit.
      • +
      • RIGs now use a var called suit_state to determine the basis for their component icons, rather than the rig's icon state.
      • +
      +

      22 September 2018

      Mechoid updated:

        @@ -85,7 +160,7 @@

      Mechoid updated:

        -
      • Hallucinations are no longer only Pun Pun.
      • +
      • Hallucinations are no longer only Pun Pun.

      Neerti updated:

        @@ -187,8 +262,8 @@

      Mechoid updated:

        -
      • Promethean limbs store more damage.
      • -
      • Promethean limbs, in addition to normal severing rules, have a higher chance to be splattered or ashed once they reach maximum damage.
      • +
      • Promethean limbs store more damage.
      • +
      • Promethean limbs, in addition to normal severing rules, have a higher chance to be splattered or ashed once they reach maximum damage.
      • Limbs can now spread their damage to neighbors with the spread_dam var, when reaching max damage.

      PrismaticGynoid updated:

      @@ -322,7 +397,7 @@
      • Broken APCs can be bashed open with slightly smaller objects now. This means wrenches are acceptable, no need to hunt down a fire extinguisher.
      • EVA rigsuit/hardsuit no longer holds toolboxes in suit storage since those have been a volume inventory for some time now. RIP ghetto satchel.
      • -
      • CE's rigsuit/hardsuit no longer holds pickaxes and ore satchels, but can now hold inflateables.
      • +
      • CE's rigsuit/hardsuit no longer holds pickaxes and ore satchels, but can now hold inflateables.
      • Retracting rigsuit/hardsuit helmets with no valid mask equipped now disables internals.
      • Offline rigsuits/hardsuits are no longer considered valid air supplies by the internals button. Before, your internals would instantly shut off before you could get a breath out of the rigsuit. Now, the internals button will look for a different tank instead.
      • Tajaran now get to keep their tails when they wear the EVA, RD, or Industrial rigsuits/hardsuits. Unathi sprites to come soon!
      • diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 18931bf85c..6198da0661 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -4228,3 +4228,79 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. - rscadd: Adds two rig suits. Military Rig suit from Bay and PMC rigsuit - rscadd: Adds four exploration and pilot voidsuits (alternate sprites by Naidh) - rscadd: Adds exploration and pilot voidsuits +<<<<<<< HEAD +======= +2018-10-13: + Anewbe: + - bugfix: You can no longer have ALL of your blood punched out. + - bugfix: Haemophiliacs will no longer spontaneously have ALL of their blood go + missing from ~90%. + - rscadd: Emitters can be locked while off, too. + - rscadd: Graves are now a thing in the code, will need some testing and probably + more work before they get more common. + Mechoid: + - rscadd: Added a RIG customization kit. + - tweak: RIGs now use a var called suit_state to determine the basis for their component + icons, rather than the rig's icon state. +2018-11-30: + Cerebulon: + - rscadd: Added 1000+ surnames and 1200+ forenames from various world cultures to + human namelists + LBnesquik: + - rscadd: Replaced the plant clippers with a reskinned pair of hedgetrimmers. + Lbnesquik: + - rscadd: 'General biogenerator improvements:' + - rscadd: Added feedback noise to the processing. + - rscadd: Allow for cream dispensing. + - rscadd: Allow for plant bag creation. + - rscadd: Allow for 5 units of meat to be dispensed at once. + - rscadd: Allow for 5 units of liquids to be dispensed at once totalling 50u. + - rscadd: Add and allow the creation of larger plant bags for easier ferrying of + plants.. + - rscadd: Add a description to the machine itself. + Mechoid: + - tweak: Prometheans are no longer murdered by blood, and instead process it like + a weak nutrient. Will slow the regeneration of toxins due to water content. + - rscadd: Ctrl clicking a Rapid Service Fabricator when held will allow you to choose + the container it deploys. + - bugfix: The Rapid Service Fabricator's icon is correctly set. + Neerti: + - experiment: Rewrites the AI system for mobs. It should be more responsive and + robust. Some mobs have special AIs which can do certain things like kiting, + following you on a lark, or telling you to go away before shooting you. + - tweak: Rewrites literally every 'simple_animal' mob into new, shinier, and hopefully + more interesting 'simple_mob' mobs, some with new mechanics, like spiders, fake + mechas, and hivebots. There are so many changes that it wouldn't be possible + to list them here. + - rscadd: RCDs can now build grilles and windows, with a new mode. They can also + finish walls when used on girders on floor/wall mode. + - rscadd: Adds various new RCDs that are not obtainable at the moment. + Woodrat: + - rscadd: Xenoflora and Xenobio moved to station, first deck. + - bugfix: Minor bugfixes including mislabeled lockers in robotics and floor decals. + kartagrafi: + - rscadd: Adds new hairstyle 'Sharp Ponytail' + - rscadd: Adds several new underwear - 'Binder', 'Strapless Binder', 'Longsleeve + Striped Shirt, Pink', 'Pink Wing Shirt', 'Pink and Black T-Shirt', 'Leggings' + - tweak: Changes name of 'Supernova' hairstyle to 'Glossy', and makes the sprite + somewhat neater + - bugfix: Fixes a hairstyle not appearing +2018-12-08: + Cerebulon: + - rscadd: 'Added 12 new loadout items plus colour variants: Utility pants, sleek + overalls, sari, modern wrap jacket, ascetic garb, asymmetrical jackets, cowled + vest, kamishimo, jingasa, maang tikka, thin-frame glasses, rimless glasses.' + Mechoid: + - rscadd: Research and Engineering borgs now have 'Circuit Grippers', used for constructing + and operating integrated circuit machinery. + - tweak: Grippers now allow interaction with their contents, by attacking the gripper + itself with an item when one is held. I.E., drawing from a beaker with a syringe. + - tweak: Grippers now show their held item's examine information when examined. + Tab information added. + - tweak: Cyborgs can now interact with integrated circuit printers and machines + when adjacent to them. + - tweak: Multitools now have a menu to switch modes between standard use and integrated + circuit reference scanning. Antag multi-tools untouched for now. + - bugfix: Integrated circuit printer now respects adjacency, if it is not set to + debug. +>>>>>>> 8430fe5... Merge pull request #5768 from Atermonera/changelog diff --git a/html/changelogs/Anewbe - Gibberish.yml b/html/changelogs/Anewbe - Gibberish.yml new file mode 100644 index 0000000000..b78f38761e --- /dev/null +++ b/html/changelogs/Anewbe - Gibberish.yml @@ -0,0 +1,36 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: Anewbe + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - tweak: "Adds a Gibberish language that gets used when you goof on a language key." diff --git a/html/changelogs/Anewbe - Voice Changers.yml b/html/changelogs/Anewbe - Voice Changers.yml new file mode 100644 index 0000000000..93d09587bf --- /dev/null +++ b/html/changelogs/Anewbe - Voice Changers.yml @@ -0,0 +1,39 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: Anewbe + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - bugfix: "Voice changing masks no longer give up when you put on a hardsuit." + - tweak: "Mask voice changers start on." + - tweak: "Mask voice changers that do not have a set voice will now default to your worn ID's name." + - tweak: "Mask voice changers now have a verb to reset their name." \ No newline at end of file diff --git a/html/changelogs/Anewbe - Yet More Gibberish.yml b/html/changelogs/Anewbe - Yet More Gibberish.yml new file mode 100644 index 0000000000..d7472af1c3 --- /dev/null +++ b/html/changelogs/Anewbe - Yet More Gibberish.yml @@ -0,0 +1,36 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: Anewbe + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - tweak: "The hyphen (-) is no longer a default language key, as people use it to represent other things. If you are still having issues with Gibberish, reset your language keys, or at least make sure they don't include any characters you regularly start speech with." diff --git a/html/changelogs/Ater - stasisbags.yml b/html/changelogs/Ater - stasisbags.yml new file mode 100644 index 0000000000..11023943e9 --- /dev/null +++ b/html/changelogs/Ater - stasisbags.yml @@ -0,0 +1,5 @@ +author: Atermonera +delete-after: True +changes: + - bugfix: "Stasis bags don't squish organics with high pressure when organics try to seek shelter from flesh wounds." + - tweak: "Body- and stasis bags can be tread upon when open." diff --git a/html/changelogs/Atermonera-pressure_protection.yml b/html/changelogs/Atermonera-pressure_protection.yml new file mode 100644 index 0000000000..b846aec6d8 --- /dev/null +++ b/html/changelogs/Atermonera-pressure_protection.yml @@ -0,0 +1,8 @@ +author: Atermonera +delete-after: True +changes: + - rscadd: "Clothing now has pressure protection variables, that set lower and upper pressure bounds within which they will protect you from pressure-based harm." + - rscadd: "Protection falls off when exceeding the pressure limits from 100% protection at the boundary to 0% at 10% in excess (above the max or below the min) boundary." + - tweak: "Currently, only hat and suit slots are checked for this protection (No change)." + - tweak: "Anomaly suits (The orange ones) now offer limited pressure protection in case anomalies start making or draining air." + - bugfix: "Firesuits are no longer spaceproof, but still offer protection against the high pressures of fire." diff --git a/html/changelogs/Cerebulon - Clothes.yml b/html/changelogs/Cerebulon - Clothes.yml new file mode 100644 index 0000000000..b05070efd1 --- /dev/null +++ b/html/changelogs/Cerebulon - Clothes.yml @@ -0,0 +1,8 @@ + + +author: Cerebulon + +delete-after: True + +changes: + - rscadd: "Added 12 new loadout items plus colour variants: Utility pants, sleek overalls, sari, modern wrap jacket, ascetic garb, asymmetrical jackets, cowled vest, kamishimo, jingasa, maang tikka, thin-frame glasses, rimless glasses." diff --git a/html/changelogs/Cerebulon - ReligionUpdate.yml b/html/changelogs/Cerebulon - ReligionUpdate.yml new file mode 100644 index 0000000000..50f402fae0 --- /dev/null +++ b/html/changelogs/Cerebulon - ReligionUpdate.yml @@ -0,0 +1,15 @@ + +author: Cerebulon + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - rscadd: "Added customizable religious icons to the chaplain's office." + - rscadd: "Added black and white candles." + - tweak: "Updated religion lists in character setup to be lore friendly." diff --git a/html/changelogs/Cerebulon -Teshrigs.yml b/html/changelogs/Cerebulon -Teshrigs.yml new file mode 100644 index 0000000000..1f4b499866 --- /dev/null +++ b/html/changelogs/Cerebulon -Teshrigs.yml @@ -0,0 +1,7 @@ + +author: Cerebulon + +delete-after: True + +changes: + - rscadd: "Added teshari hardsuit sprites." diff --git a/html/changelogs/Mechoid - LingJacket.yml b/html/changelogs/Mechoid - LingJacket.yml new file mode 100644 index 0000000000..5aef776f8e --- /dev/null +++ b/html/changelogs/Mechoid - LingJacket.yml @@ -0,0 +1,37 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: Mechoid + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - bugfix: "Oversight regarding Changeling revive not removing restraints fixed." + - tweak: "Straight Jackets can now be resisted out of in 8 minutes, or as low as 5 depending on species attacks. Shredding or hulked humans will break out in 20 seconds, destroying the jacket." diff --git a/html/changelogs/Mechoid-Slimefix.yml b/html/changelogs/Mechoid-Slimefix.yml new file mode 100644 index 0000000000..10bb77d5bc --- /dev/null +++ b/html/changelogs/Mechoid-Slimefix.yml @@ -0,0 +1,36 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: Mechoid + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - bugfix: "Slimes now respect slime colors as their faction when dealing with other slimes." diff --git a/html/changelogs/Neerti-AI.yml b/html/changelogs/Neerti-AI.yml new file mode 100644 index 0000000000..9b9f13674d --- /dev/null +++ b/html/changelogs/Neerti-AI.yml @@ -0,0 +1,37 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: Neerti + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - experiment: "Rewrites the AI system for mobs. It should be more responsive and robust. Some mobs have special AIs which can do certain things like kiting, following you on a lark, or telling you to go away before shooting you." + - tweak: "Rewrites literally every 'simple_animal' mob into new, shinier, and hopefully more interesting 'simple_mob' mobs, some with new mechanics, like spiders, fake mechas, and hivebots. There are so many changes that it wouldn't be possible to list them here." diff --git a/html/changelogs/Novacat-PR-5779.yml b/html/changelogs/Novacat-PR-5779.yml new file mode 100644 index 0000000000..e4cc233b54 --- /dev/null +++ b/html/changelogs/Novacat-PR-5779.yml @@ -0,0 +1,36 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: Novacat + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - tweak: "All emergency tanks now spawn at full capacity." diff --git a/html/changelogs/ater_botspeak.yml b/html/changelogs/ater_botspeak.yml new file mode 100644 index 0000000000..a5ef574c50 --- /dev/null +++ b/html/changelogs/ater_botspeak.yml @@ -0,0 +1,4 @@ +author: Atermonera +delete-after: True +changes: + - bugfix: "Robot sound files have been decrypted following a bizarre ransomware attack by Boiling Point remnants." diff --git a/html/changelogs/atermonera_suit_cooling.yml b/html/changelogs/atermonera_suit_cooling.yml new file mode 100644 index 0000000000..fce9429e6e --- /dev/null +++ b/html/changelogs/atermonera_suit_cooling.yml @@ -0,0 +1,4 @@ +author: atermonera +delete-after: True +changes: + - bugfix: "Suit coolers and rigsuit coolers now protect FBPs against vacuum again." \ No newline at end of file diff --git a/html/changelogs/neerti-looping_sounds.yml b/html/changelogs/neerti-looping_sounds.yml new file mode 100644 index 0000000000..214ec43678 --- /dev/null +++ b/html/changelogs/neerti-looping_sounds.yml @@ -0,0 +1,38 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: Neerti + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - soundadd: "Adds a lot of sounds, and the code to let them loop seemlessly. Things made audible now include the microwave, deep fryer, showers, the supermatter when it's active, the TEGs when active, geiger counters, and severe weather on Sif. The weather has different sounds for when indoors and when outdoors." + - tweak: "The weather sounds, and the supermatter hum can be disabled in your preferences." + - rscadd: "Adds a few more weather types that can only be activated by admin powers, such as ash storms and fallout." diff --git a/icons/effects/beam.dmi b/icons/effects/beam.dmi index 4b7e714731..6c631498f6 100644 Binary files a/icons/effects/beam.dmi and b/icons/effects/beam.dmi differ diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi index b735173878..e45ddcbb0d 100644 Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ diff --git a/icons/effects/map_effects.dmi b/icons/effects/map_effects.dmi new file mode 100644 index 0000000000..4f5bff755d Binary files /dev/null and b/icons/effects/map_effects.dmi differ diff --git a/icons/effects/projectiles.dmi b/icons/effects/projectiles.dmi deleted file mode 100644 index 2bf7813e05..0000000000 Binary files a/icons/effects/projectiles.dmi and /dev/null differ diff --git a/icons/effects/weather.dmi b/icons/effects/weather.dmi index 5ae794c898..355288fc32 100644 Binary files a/icons/effects/weather.dmi and b/icons/effects/weather.dmi differ diff --git a/icons/mecha/mecha.dmi b/icons/mecha/mecha.dmi index 5c3bb92b76..ca5c8b87a5 100644 Binary files a/icons/mecha/mecha.dmi and b/icons/mecha/mecha.dmi differ diff --git a/icons/misc/buildmode.dmi b/icons/misc/buildmode.dmi index c294178f91..dc8de0b6d0 100644 Binary files a/icons/misc/buildmode.dmi and b/icons/misc/buildmode.dmi differ diff --git a/icons/mob/animal.dmi b/icons/mob/animal.dmi index e503b0d1b9..f3836ae2c1 100644 Binary files a/icons/mob/animal.dmi and b/icons/mob/animal.dmi differ diff --git a/icons/mob/critter.dmi b/icons/mob/critter.dmi index f83c836427..4f249e2e8a 100644 Binary files a/icons/mob/critter.dmi and b/icons/mob/critter.dmi differ diff --git a/icons/mob/eyes.dmi b/icons/mob/eyes.dmi index 763ce78990..4759a8a2d6 100644 Binary files a/icons/mob/eyes.dmi and b/icons/mob/eyes.dmi differ diff --git a/icons/mob/feet.dmi b/icons/mob/feet.dmi index d1c09ef542..9c3997985e 100644 Binary files a/icons/mob/feet.dmi and b/icons/mob/feet.dmi differ diff --git a/icons/mob/hivebot.dmi b/icons/mob/hivebot.dmi index ecaa519822..e18209733d 100644 Binary files a/icons/mob/hivebot.dmi and b/icons/mob/hivebot.dmi differ diff --git a/icons/mob/human_face.dmi b/icons/mob/human_face.dmi index a65de5defd..614f8e2076 100644 Binary files a/icons/mob/human_face.dmi and b/icons/mob/human_face.dmi differ diff --git a/icons/mob/human_face_m.dmi b/icons/mob/human_face_m.dmi index fe62645869..9eff944078 100644 Binary files a/icons/mob/human_face_m.dmi and b/icons/mob/human_face_m.dmi differ diff --git a/icons/mob/items/lefthand_guns.dmi b/icons/mob/items/lefthand_guns.dmi index 72e9c00465..c0431e2337 100644 Binary files a/icons/mob/items/lefthand_guns.dmi and b/icons/mob/items/lefthand_guns.dmi differ diff --git a/icons/mob/items/righthand_guns.dmi b/icons/mob/items/righthand_guns.dmi index f3f75a86ea..8047c95f71 100644 Binary files a/icons/mob/items/righthand_guns.dmi and b/icons/mob/items/righthand_guns.dmi differ diff --git a/icons/mob/mob.dmi b/icons/mob/mob.dmi index 1b0e592001..4bfb8bf479 100644 Binary files a/icons/mob/mob.dmi and b/icons/mob/mob.dmi differ diff --git a/icons/mob/modifier_effects.dmi b/icons/mob/modifier_effects.dmi index 262e45e717..abd78dcd31 100644 Binary files a/icons/mob/modifier_effects.dmi and b/icons/mob/modifier_effects.dmi differ diff --git a/icons/mob/screen1.dmi b/icons/mob/screen1.dmi index 0798bbc4d3..842909d3ec 100644 Binary files a/icons/mob/screen1.dmi and b/icons/mob/screen1.dmi differ diff --git a/icons/mob/slime2.dmi b/icons/mob/slime2.dmi index a0b6051665..9391c1acd3 100644 Binary files a/icons/mob/slime2.dmi and b/icons/mob/slime2.dmi differ diff --git a/icons/mob/species/seromi/back.dmi b/icons/mob/species/seromi/back.dmi index d0af48607c..0dcbeae289 100644 Binary files a/icons/mob/species/seromi/back.dmi and b/icons/mob/species/seromi/back.dmi differ diff --git a/icons/mob/species/seromi/eyes.dmi b/icons/mob/species/seromi/eyes.dmi index 8a916ca621..01e2475c3d 100644 Binary files a/icons/mob/species/seromi/eyes.dmi and b/icons/mob/species/seromi/eyes.dmi differ diff --git a/icons/mob/species/seromi/head.dmi b/icons/mob/species/seromi/head.dmi index 1c3f150a8e..0a917236ff 100644 Binary files a/icons/mob/species/seromi/head.dmi and b/icons/mob/species/seromi/head.dmi differ diff --git a/icons/mob/species/seromi/suit.dmi b/icons/mob/species/seromi/suit.dmi index 09dde09b2f..1337435e86 100644 Binary files a/icons/mob/species/seromi/suit.dmi and b/icons/mob/species/seromi/suit.dmi differ diff --git a/icons/mob/species/seromi/uniform.dmi b/icons/mob/species/seromi/uniform.dmi index c354d0bd12..a49299a4a1 100644 Binary files a/icons/mob/species/seromi/uniform.dmi and b/icons/mob/species/seromi/uniform.dmi differ diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi index 5b2bfe8e4f..c1908fe16b 100644 Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ diff --git a/icons/mob/ties.dmi b/icons/mob/ties.dmi index 59e77909e9..2262610211 100644 Binary files a/icons/mob/ties.dmi and b/icons/mob/ties.dmi differ diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi index aa6e8bfb81..9e4860eca3 100644 Binary files a/icons/mob/uniform.dmi and b/icons/mob/uniform.dmi differ diff --git a/icons/obj/32x64.dmi b/icons/obj/32x64.dmi new file mode 100644 index 0000000000..7b8c00eef8 Binary files /dev/null and b/icons/obj/32x64.dmi differ diff --git a/icons/obj/candle.dmi b/icons/obj/candle.dmi index 6a01c71e52..e00cb0ba3b 100644 Binary files a/icons/obj/candle.dmi and b/icons/obj/candle.dmi differ diff --git a/icons/obj/chaplain.dmi b/icons/obj/chaplain.dmi new file mode 100644 index 0000000000..9ac98e186a Binary files /dev/null and b/icons/obj/chaplain.dmi differ diff --git a/icons/obj/chemical.dmi b/icons/obj/chemical.dmi index 3bf2b9d660..1d4c723fca 100644 Binary files a/icons/obj/chemical.dmi and b/icons/obj/chemical.dmi differ diff --git a/icons/obj/clothing/glasses.dmi b/icons/obj/clothing/glasses.dmi index 8342982785..d8418a50a5 100644 Binary files a/icons/obj/clothing/glasses.dmi and b/icons/obj/clothing/glasses.dmi differ diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi index c585c40625..230fdc1248 100644 Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ diff --git a/icons/obj/clothing/shoes.dmi b/icons/obj/clothing/shoes.dmi index a923ea9986..d2901f5bf3 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 38154ec14a..dc131fb6fe 100644 Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ diff --git a/icons/obj/clothing/ties.dmi b/icons/obj/clothing/ties.dmi index 52433ab5e3..478bd6a40b 100644 Binary files a/icons/obj/clothing/ties.dmi and b/icons/obj/clothing/ties.dmi differ diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi index d0bb4a6b39..91230723f1 100644 Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ diff --git a/icons/obj/decals.dmi b/icons/obj/decals.dmi index 6fae3b0bee..c7b1fe5787 100644 Binary files a/icons/obj/decals.dmi and b/icons/obj/decals.dmi differ diff --git a/icons/obj/drinks.dmi b/icons/obj/drinks.dmi index 5adcea97c7..cdd4348a9f 100644 Binary files a/icons/obj/drinks.dmi and b/icons/obj/drinks.dmi differ diff --git a/icons/obj/fence.dmi b/icons/obj/fence.dmi new file mode 100644 index 0000000000..31b1abef3c Binary files /dev/null and b/icons/obj/fence.dmi differ diff --git a/icons/obj/flora/pinetrees.dmi b/icons/obj/flora/pinetrees.dmi index 63073046f0..1076dd472e 100644 Binary files a/icons/obj/flora/pinetrees.dmi and b/icons/obj/flora/pinetrees.dmi differ diff --git a/icons/obj/flora/rocks.dmi b/icons/obj/flora/rocks.dmi index 0974360e27..12d4f2c8ee 100644 Binary files a/icons/obj/flora/rocks.dmi and b/icons/obj/flora/rocks.dmi differ diff --git a/icons/obj/loot_piles.dmi b/icons/obj/loot_piles.dmi index d4722d995c..3d83d6612e 100644 Binary files a/icons/obj/loot_piles.dmi and b/icons/obj/loot_piles.dmi differ diff --git a/icons/obj/projectiles.dmi b/icons/obj/projectiles.dmi index efc1184dd5..1b753e9c87 100644 Binary files a/icons/obj/projectiles.dmi and b/icons/obj/projectiles.dmi differ diff --git a/icons/obj/projectiles_impact.dmi b/icons/obj/projectiles_impact.dmi new file mode 100644 index 0000000000..fd9d314310 Binary files /dev/null and b/icons/obj/projectiles_impact.dmi differ diff --git a/icons/obj/projectiles_muzzle.dmi b/icons/obj/projectiles_muzzle.dmi new file mode 100644 index 0000000000..d88b9a283e Binary files /dev/null and b/icons/obj/projectiles_muzzle.dmi differ diff --git a/icons/obj/projectiles_tracer.dmi b/icons/obj/projectiles_tracer.dmi new file mode 100644 index 0000000000..153794a929 Binary files /dev/null and b/icons/obj/projectiles_tracer.dmi differ diff --git a/icons/obj/railgun.dmi b/icons/obj/railgun.dmi index 404aa1ea60..6f633db1e5 100644 Binary files a/icons/obj/railgun.dmi and b/icons/obj/railgun.dmi differ diff --git a/icons/obj/stationobjs.dmi b/icons/obj/stationobjs.dmi index e83faea146..fe29bd535c 100644 Binary files a/icons/obj/stationobjs.dmi and b/icons/obj/stationobjs.dmi differ diff --git a/icons/turf/areas.dmi b/icons/turf/areas.dmi old mode 100755 new mode 100644 index de00a11f60..1132fa10a9 Binary files a/icons/turf/areas.dmi and b/icons/turf/areas.dmi differ diff --git a/icons/turf/areas_vr.dmi b/icons/turf/areas_vr.dmi index 1270d2279b..d0bc8e7df7 100644 Binary files a/icons/turf/areas_vr.dmi and b/icons/turf/areas_vr.dmi differ diff --git a/icons/turf/outdoors.dmi b/icons/turf/outdoors.dmi index ec94c60efd..b8af78d986 100644 Binary files a/icons/turf/outdoors.dmi and b/icons/turf/outdoors.dmi differ diff --git a/maps/RandomZLevels/Academy.dmm b/maps/RandomZLevels/Academy.dmm index 0e2df90f51..7e9c1cfa9d 100644 --- a/maps/RandomZLevels/Academy.dmm +++ b/maps/RandomZLevels/Academy.dmm @@ -2511,7 +2511,7 @@ }, /area/awaymission/academy/classrooms) "gF" = ( -/mob/living/simple_animal/hostile/bear, +/mob/living/simple_mob/hostile/bear, /turf/simulated/floor/plating, /area/awaymission/academy/classrooms) "gG" = ( @@ -2543,7 +2543,7 @@ /obj/machinery/light/small{ dir = 8 }, -/mob/living/simple_animal/hostile/bear, +/mob/living/simple_mob/hostile/bear, /turf/simulated/floor/plating, /area/awaymission/academy/classrooms) "gL" = ( diff --git a/maps/RandomZLevels/beach.dmm b/maps/RandomZLevels/beach.dmm index 6bbd377c50..3dd259a9c5 100644 --- a/maps/RandomZLevels/beach.dmm +++ b/maps/RandomZLevels/beach.dmm @@ -210,7 +210,7 @@ /turf/unsimulated/beach/sand, /area/awaymission/beach) "L" = ( -/mob/living/simple_animal/crab, +/mob/living/simple_mob/crab, /turf/unsimulated/beach/sand, /area/awaymission/beach) "M" = ( @@ -218,7 +218,7 @@ /turf/unsimulated/beach/sand, /area/awaymission/beach) "N" = ( -/mob/living/simple_animal/crab/Coffee, +/mob/living/simple_mob/crab/Coffee, /turf/unsimulated/beach/sand, /area/awaymission/beach) "O" = ( diff --git a/maps/RandomZLevels/carpfarm.dmm b/maps/RandomZLevels/carpfarm.dmm index ec7e6093b1..39b3b19b1c 100644 --- a/maps/RandomZLevels/carpfarm.dmm +++ b/maps/RandomZLevels/carpfarm.dmm @@ -18,11 +18,11 @@ /turf/space, /area/space) "ae" = ( -/mob/living/simple_animal/hostile/carp, +/mob/living/simple_mob/hostile/carp, /turf/space, /area/space) "af" = ( -/mob/living/simple_animal/hostile/carp/large, +/mob/living/simple_mob/hostile/carp/large, /turf/space, /area/space) "ag" = ( diff --git a/maps/RandomZLevels/challenge.dmm b/maps/RandomZLevels/challenge.dmm index 59d67ba636..3b083c956b 100644 --- a/maps/RandomZLevels/challenge.dmm +++ b/maps/RandomZLevels/challenge.dmm @@ -118,7 +118,7 @@ /area/awaymission/challenge/start) "ax" = ( /obj/effect/decal/cleanable/oil, -/mob/living/simple_animal/hostile/syndicate, +/mob/living/simple_mob/hostile/syndicate, /turf/simulated/floor/plating, /area/awaymission/challenge/start) "ay" = ( @@ -858,7 +858,7 @@ }, /area/awaymission/challenge/end) "ce" = ( -/mob/living/simple_animal/hostile/syndicate/ranged/space{ +/mob/living/simple_mob/hostile/syndicate/ranged/space{ name = "Syndicate Officer" }, /turf/simulated/floor{ @@ -883,7 +883,7 @@ /area/awaymission/challenge/end) "ch" = ( /obj/structure/stool/bed/chair/comfy/black, -/mob/living/simple_animal/hostile/syndicate{ +/mob/living/simple_mob/hostile/syndicate{ name = "Syndicate Commander" }, /turf/simulated/floor/carpet, @@ -904,7 +904,7 @@ /turf/simulated/floor/wood, /area/awaymission/challenge/end) "cl" = ( -/mob/living/simple_animal/hostile/syndicate/melee, +/mob/living/simple_mob/hostile/syndicate/melee, /turf/simulated/floor{ icon_state = "dark" }, @@ -961,7 +961,7 @@ /turf/simulated/floor/wood, /area/awaymission/challenge/end) "cu" = ( -/mob/living/simple_animal/hostile/syndicate/melee, +/mob/living/simple_mob/hostile/syndicate/melee, /turf/simulated/shuttle/floor{ icon_state = "floor4" }, @@ -1035,7 +1035,7 @@ /turf/simulated/floor/bluegrid, /area/awaymission/challenge/end) "cF" = ( -/mob/living/simple_animal/hostile/syndicate/ranged, +/mob/living/simple_mob/hostile/syndicate/ranged, /turf/simulated/floor{ icon_state = "dark" }, @@ -1381,7 +1381,7 @@ d2 = 4; icon_state = "1-4" }, -/mob/living/simple_animal/hostile/syndicate{ +/mob/living/simple_mob/hostile/syndicate{ name = "Syndicate Technician" }, /turf/simulated/floor{ diff --git a/maps/RandomZLevels/labyrinth.dm b/maps/RandomZLevels/labyrinth.dm index be24a024df..86d1f15214 100644 --- a/maps/RandomZLevels/labyrinth.dm +++ b/maps/RandomZLevels/labyrinth.dm @@ -202,7 +202,7 @@ corpsesuit = /obj/item/clothing/suit/cultrobes corpsehelmet = /obj/item/clothing/head/culthood -/mob/living/simple_animal/hostile/tunnelclown +/mob/living/simple_mob/hostile/tunnelclown name = "tunnel clown" desc = "A clown driven to madness in the depths of the Honk Mother's Catacombs." faction = "tunnelclown" @@ -244,7 +244,7 @@ cold_damage_per_tick = 10 unsuitable_atoms_damage = 10 -/mob/living/simple_animal/hostile/tunnelclown/sentinel +/mob/living/simple_mob/hostile/tunnelclown/sentinel name = "tunnel clown sentinel" desc = "A clown warrior tasked with guarding the Honk Mother's Catacombs." faction = "tunnelclown" @@ -259,7 +259,7 @@ melee_damage_lower = 15 melee_damage_upper = 20 -/mob/living/simple_animal/hostile/tunnelclown/death() +/mob/living/simple_mob/hostile/tunnelclown/death() ..() if(corpse) new corpse (src.loc) @@ -268,7 +268,7 @@ del src return -/mob/living/simple_animal/hostile/cluwne +/mob/living/simple_mob/hostile/cluwne name = "cluwne" desc = "A mutated clown alleged to have been cursed by the Honk Mother and permanently banished to these catacombs for once being an unfunny shitter who brought grief instead of laughter." faction = "tunnelclown" @@ -316,9 +316,9 @@ icon_state = "clown" spawn_nothing_percentage = 50 item_to_spawn() - return pick(prob(3);/mob/living/simple_animal/hostile/cluwne, - prob(2);/mob/living/simple_animal/hostile/tunnelclown/sentinel, - prob(1);/mob/living/simple_animal/hostile/tunnelclown) + return pick(prob(3);/mob/living/simple_mob/hostile/cluwne, + prob(2);/mob/living/simple_mob/hostile/tunnelclown/sentinel, + prob(1);/mob/living/simple_mob/hostile/tunnelclown) /obj/item/weapon/paper/awaygate/labyrinth/calypso name = "copy of the Final Flight of Calypso" diff --git a/maps/RandomZLevels/listeningpost.dmm b/maps/RandomZLevels/listeningpost.dmm index 6f1d0274ec..91d2a6bccc 100644 --- a/maps/RandomZLevels/listeningpost.dmm +++ b/maps/RandomZLevels/listeningpost.dmm @@ -62,7 +62,7 @@ /obj/structure/stool/bed/chair{ dir = 4 }, -/mob/living/simple_animal/hostile/syndicate{ +/mob/living/simple_mob/hostile/syndicate{ desc = "A weary looking syndicate operative."; faction = "syndicate" }, diff --git a/maps/RandomZLevels/snowfield.dm b/maps/RandomZLevels/snowfield.dm index 709253fd93..e0a4c7c897 100644 --- a/maps/RandomZLevels/snowfield.dm +++ b/maps/RandomZLevels/snowfield.dm @@ -17,9 +17,10 @@ power_environ = 0 mobcountmax = 100 floracountmax = 7000 - valid_mobs = list(/mob/living/simple_animal/hostile/samak/polar, /mob/living/simple_animal/hostile/diyaab/polar, - /mob/living/simple_animal/hostile/shantak/polar, /mob/living/simple_animal/hostile/bear/polar, - /mob/living/simple_animal/hostile/wolf) + /* + valid_mobs = list(/mob/living/simple_mob/hostile/samak/polar, /mob/living/simple_mob/hostile/diyaab/polar, + /mob/living/simple_mob/hostile/shantak/polar, /mob/living/simple_mob/hostile/bear/polar, + /mob/living/simple_mob/hostile/wolf)*/ //VORESTATION AI TEMPORARY REMOVAL valid_flora = list(/obj/structure/flora/tree/pine, /obj/structure/flora/tree/pine, /obj/structure/flora/tree/pine, /obj/structure/flora/tree/dead, /obj/structure/flora/grass/brown, /obj/structure/flora/grass/green, /obj/structure/flora/grass/both, /obj/structure/flora/bush, /obj/structure/flora/ausbushes/grassybush, @@ -43,7 +44,7 @@ // -- Mobs -- // -/mob/living/simple_animal/hostile/bear/polar // More aggressive than normal bears so none of that fancy life() stuff. +/mob/living/simple_mob/hostile/bear/polar // More aggressive than normal bears so none of that fancy life() stuff. name = "polar bear" desc = "The real question is, why are you examining it, instead of running away?" icon = 'icons/mob/vore.dmi' @@ -53,13 +54,14 @@ icon_gib = "bear-gib" vore_icons = SA_ICON_LIVING vore_active = 1 + say_list_type = /datum/say_list/polar_bear faction = "polar" maxHealth = 80 health = 80 // Polar bear will fuck you up. - stop_when_pulled = 0 - turns_per_move = 5 + //stop_when_pulled = 0 //VORESTATION AI TEMPORARY REMOVAL + //turns_per_move = 5 //VORESTATION AI TEMPORARY REMOVAL see_in_dark = 6 response_help = "pets" @@ -71,26 +73,26 @@ minbodytemp = 0 - speak_chance = 1 + //speak_chance = 1 //VORESTATION AI TEMPORARY REMOVAL + meat_type = /obj/item/weapon/reagent_containers/food/snacks/bearmeat +/datum/say_list/polar_bear speak = list("RAWR!","Rawr!","GRR!","Growl!") - speak_emote = list("growls", "roars") emote_hear = list("rawrs","grumbles","grawls") emote_see = list("stares ferociously", "stomps") - meat_type = /obj/item/weapon/reagent_containers/food/snacks/bearmeat -/mob/living/simple_animal/hostile/bear/polar/death() +/mob/living/simple_mob/hostile/bear/polar/death() desc = "This bastard sure isn't drinking Space Cola anymore." ..() -/mob/living/simple_animal/hostile/samak/polar +/mob/living/simple_mob/hostile/samak/polar faction = "polar" -/mob/living/simple_animal/hostile/diyaab/polar +/mob/living/simple_mob/hostile/diyaab/polar faction = "polar" -/mob/living/simple_animal/hostile/shantak/polar +/mob/living/simple_mob/hostile/shantak/polar faction = "polar" // -- Items -- // diff --git a/maps/RandomZLevels/snowfield.dmm b/maps/RandomZLevels/snowfield.dmm index 2ed1c84193..01fbbeebf6 100644 --- a/maps/RandomZLevels/snowfield.dmm +++ b/maps/RandomZLevels/snowfield.dmm @@ -1373,7 +1373,7 @@ "dT" = ( /obj/effect/floor_decal/industrial/outline/yellow, /obj/effect/decal/remains/human, -/mob/living/simple_animal/hostile/mimic/crate, +/mob/living/simple_mob/hostile/mimic/crate, /turf/simulated/floor/tiled/neutral, /area/awaymission/snowfield/base) "dU" = ( @@ -1442,11 +1442,11 @@ icon_state = "tube1"; pixel_y = 0 }, -/mob/living/simple_animal/hostile/viscerator, +/mob/living/simple_mob/hostile/viscerator, /turf/simulated/floor/tiled/dark, /area/awaymission/snowfield/base) "ee" = ( -/mob/living/simple_animal/hostile/viscerator, +/mob/living/simple_mob/hostile/viscerator, /turf/simulated/floor/tiled/dark, /area/awaymission/snowfield/base) "ef" = ( @@ -1454,7 +1454,7 @@ dir = 4; icon_state = "tube1" }, -/mob/living/simple_animal/hostile/viscerator, +/mob/living/simple_mob/hostile/viscerator, /turf/simulated/floor/tiled/dark, /area/awaymission/snowfield/base) "eg" = ( diff --git a/maps/RandomZLevels/spacebattle.dmm b/maps/RandomZLevels/spacebattle.dmm index f41ee5ab07..9205dda8d5 100644 --- a/maps/RandomZLevels/spacebattle.dmm +++ b/maps/RandomZLevels/spacebattle.dmm @@ -65,7 +65,7 @@ }, /area/awaymission/spacebattle/syndicate2) "al" = ( -/mob/living/simple_animal/hostile/syndicate/ranged, +/mob/living/simple_mob/hostile/syndicate/ranged, /turf/simulated/shuttle/floor{ icon_state = "floor4" }, @@ -99,7 +99,7 @@ }, /area/awaymission/spacebattle/syndicate2) "aq" = ( -/mob/living/simple_animal/hostile/syndicate/melee, +/mob/living/simple_mob/hostile/syndicate/melee, /turf/simulated/shuttle/floor{ icon_state = "floor4" }, @@ -213,7 +213,7 @@ /area/awaymission/spacebattle/syndicate2) "aH" = ( /obj/structure/stool/bed/chair, -/mob/living/simple_animal/hostile/syndicate, +/mob/living/simple_mob/hostile/syndicate, /turf/simulated/shuttle/floor{ icon_state = "floor4" }, @@ -492,7 +492,7 @@ /area/awaymission/spacebattle/syndicate3) "bu" = ( /obj/structure/stool/bed/chair, -/mob/living/simple_animal/hostile/syndicate, +/mob/living/simple_mob/hostile/syndicate, /turf/simulated/shuttle/floor{ icon_state = "floor4" }, @@ -558,7 +558,7 @@ /area/awaymission/spacebattle/syndicate1) "bD" = ( /obj/structure/stool/bed/chair, -/mob/living/simple_animal/hostile/syndicate, +/mob/living/simple_mob/hostile/syndicate, /turf/simulated/shuttle/floor{ icon_state = "floor4" }, @@ -804,7 +804,7 @@ }, /area/awaymission/spacebattle/cruiser) "cm" = ( -/mob/living/simple_animal/hostile/syndicate/melee/space, +/mob/living/simple_mob/hostile/syndicate/melee/space, /turf/simulated/floor, /area/awaymission/spacebattle/cruiser) "cn" = ( @@ -1044,7 +1044,7 @@ }, /area/awaymission/spacebattle/cruiser) "cZ" = ( -/mob/living/simple_animal/hostile/syndicate/melee, +/mob/living/simple_mob/hostile/syndicate/melee, /turf/simulated/floor, /area/awaymission/spacebattle/cruiser) "da" = ( @@ -1069,7 +1069,7 @@ }, /area/awaymission/spacebattle/cruiser) "dd" = ( -/mob/living/simple_animal/hostile/syndicate/ranged/space, +/mob/living/simple_mob/hostile/syndicate/ranged/space, /turf/simulated/floor, /area/awaymission/spacebattle/cruiser) "de" = ( @@ -1475,7 +1475,7 @@ /turf/simulated/floor/plating, /area/awaymission/spacebattle/cruiser) "ek" = ( -/mob/living/simple_animal/hostile/syndicate/melee, +/mob/living/simple_mob/hostile/syndicate/melee, /turf/simulated/floor{ icon_state = "bar" }, @@ -1570,7 +1570,7 @@ /turf/simulated/floor/plating, /area/awaymission/spacebattle/cruiser) "ez" = ( -/mob/living/simple_animal/hostile/syndicate/ranged/space, +/mob/living/simple_mob/hostile/syndicate/ranged/space, /turf/simulated/floor{ icon_state = "bar" }, @@ -1640,7 +1640,7 @@ /turf/simulated/floor/plating, /area/awaymission/spacebattle/cruiser) "eJ" = ( -/mob/living/simple_animal/hostile/syndicate/melee/space, +/mob/living/simple_mob/hostile/syndicate/melee/space, /turf/simulated/floor/plating/airless, /area/awaymission/spacebattle/cruiser) "eK" = ( @@ -1725,7 +1725,7 @@ /obj/structure/stool/bed/chair{ dir = 1 }, -/mob/living/simple_animal/hostile/syndicate, +/mob/living/simple_mob/hostile/syndicate, /turf/simulated/shuttle/floor{ icon_state = "floor4" }, @@ -1822,7 +1822,7 @@ /turf/simulated/floor, /area/awaymission/spacebattle/cruiser) "fm" = ( -/mob/living/simple_animal/hostile/syndicate/ranged, +/mob/living/simple_mob/hostile/syndicate/ranged, /turf/simulated/floor{ icon_state = "blue"; dir = 8 @@ -2344,7 +2344,7 @@ /turf/simulated/floor/wood, /area/awaymission/spacebattle/cruiser) "gO" = ( -/mob/living/simple_animal/hostile/syndicate/melee/space, +/mob/living/simple_mob/hostile/syndicate/melee/space, /turf/simulated/floor/wood, /area/awaymission/spacebattle/cruiser) "gP" = ( @@ -2620,7 +2620,7 @@ /area/awaymission/spacebattle/syndicate7) "hB" = ( /obj/structure/largecrate, -/mob/living/simple_animal/corgi/puppy, +/mob/living/simple_mob/corgi/puppy, /turf/simulated/floor/plating, /area/awaymission/spacebattle/cruiser) "hC" = ( @@ -2646,7 +2646,7 @@ }, /area/awaymission/spacebattle/cruiser) "hG" = ( -/mob/living/simple_animal/hostile/syndicate/melee, +/mob/living/simple_mob/hostile/syndicate/melee, /turf/simulated/floor{ icon_state = "white" }, @@ -2762,7 +2762,7 @@ /obj/structure/stool/bed/chair{ dir = 8 }, -/mob/living/simple_animal/hostile/syndicate, +/mob/living/simple_mob/hostile/syndicate, /turf/simulated/shuttle/floor{ icon_state = "floor4" }, @@ -2861,7 +2861,7 @@ }, /area/awaymission/spacebattle/cruiser) "il" = ( -/mob/living/simple_animal/hostile/syndicate/ranged/space, +/mob/living/simple_mob/hostile/syndicate/ranged/space, /turf/simulated/floor{ icon_state = "freezerfloor" }, @@ -2954,7 +2954,7 @@ /turf/simulated/floor, /area/awaymission/spacebattle/cruiser) "ix" = ( -/mob/living/simple_animal/hostile/syndicate/ranged, +/mob/living/simple_mob/hostile/syndicate/ranged, /turf/simulated/floor, /area/awaymission/spacebattle/cruiser) "iy" = ( @@ -3093,7 +3093,7 @@ /obj/structure/stool/bed/chair{ dir = 1 }, -/mob/living/simple_animal/hostile/syndicate, +/mob/living/simple_mob/hostile/syndicate, /turf/simulated/shuttle/floor{ icon_state = "floor4" }, @@ -3179,7 +3179,7 @@ /obj/structure/stool/bed/chair{ dir = 1 }, -/mob/living/simple_animal/hostile/syndicate, +/mob/living/simple_mob/hostile/syndicate, /turf/simulated/shuttle/floor{ icon_state = "floor4" }, diff --git a/maps/RandomZLevels/stationCollision.dmm b/maps/RandomZLevels/stationCollision.dmm index 894fa18a0d..09a00494a2 100644 --- a/maps/RandomZLevels/stationCollision.dmm +++ b/maps/RandomZLevels/stationCollision.dmm @@ -549,7 +549,7 @@ }, /area/awaymission/research) "bS" = ( -/mob/living/simple_animal/lizard, +/mob/living/simple_mob/lizard, /turf/simulated/floor/grass, /area/awaymission/research) "bT" = ( @@ -625,7 +625,7 @@ }, /area/awaymission/research) "ce" = ( -/mob/living/simple_animal/hostile/creature{ +/mob/living/simple_mob/hostile/creature{ name = "Experiment 35b" }, /turf/simulated/floor, @@ -709,7 +709,7 @@ dir = 8 }, /obj/structure/window/reinforced, -/mob/living/simple_animal/hostile/hivebot{ +/mob/living/simple_mob/hostile/hivebot{ opensdoors = 0 }, /turf/simulated/floor{ diff --git a/maps/RandomZLevels/wildwest.dm b/maps/RandomZLevels/wildwest.dm index 70914f043f..6464339edb 100644 --- a/maps/RandomZLevels/wildwest.dm +++ b/maps/RandomZLevels/wildwest.dm @@ -90,7 +90,7 @@ if("Peace") user << "Whatever alien sentience that the Wish Granter possesses is satisfied with your wish. There is a distant wailing as the last of the Faithless begin to die, then silence." user << "You feel as if you just narrowly avoided a terrible fate..." - for(var/mob/living/simple_animal/hostile/faithless/F in living_mob_list) + for(var/mob/living/simple_mob/faithless/F in living_mob_list) F.health = -10 F.stat = 2 F.icon_state = "faithless_dead" @@ -170,4 +170,4 @@ C << "You have regenerated." C.visible_message("[usr] appears to wake from the dead, having healed all wounds.") C.update_canmove() - return 1 + return 1 \ No newline at end of file diff --git a/maps/RandomZLevels/wildwest.dmm b/maps/RandomZLevels/wildwest.dmm index 024051a498..3694ee793b 100644 --- a/maps/RandomZLevels/wildwest.dmm +++ b/maps/RandomZLevels/wildwest.dmm @@ -18,7 +18,7 @@ }, /area/awaymission/wwvault) "af" = ( -/mob/living/simple_animal/hostile/faithless, +/mob/living/simple_mob/hostile/faithless, /turf/simulated/floor/engine/cult, /area/awaymission/wwvault) "ag" = ( @@ -52,7 +52,7 @@ /turf/simulated/floor/engine/cult, /area/awaymission/wwvault) "am" = ( -/mob/living/simple_animal/hostile/faithless, +/mob/living/simple_mob/hostile/faithless, /turf/simulated/shuttle/plating{ icon_state = "bcircuitoff" }, @@ -173,7 +173,7 @@ /turf/simulated/floor/carpet, /area/awaymission/wwvault) "aE" = ( -/mob/living/simple_animal/hostile/faithless, +/mob/living/simple_mob/hostile/faithless, /turf/simulated/floor/carpet, /area/awaymission/wwvault) "aF" = ( @@ -323,7 +323,7 @@ }, /area/awaymission/wwmines) "bf" = ( -/mob/living/simple_animal/hostile/syndicate/ranged, +/mob/living/simple_mob/hostile/syndicate/ranged, /turf/simulated/floor/plating/ironsand{ icon_state = "ironsand1" }, @@ -360,7 +360,7 @@ /turf/simulated/floor/wood, /area/awaymission/wwmines) "bn" = ( -/mob/living/simple_animal/hostile/syndicate/ranged, +/mob/living/simple_mob/hostile/syndicate/ranged, /turf/simulated/floor/plating, /area/awaymission/wwrefine) "bo" = ( @@ -419,7 +419,7 @@ }, /area/awaymission/wwmines) "bz" = ( -/mob/living/simple_animal/hostile/syndicate/ranged, +/mob/living/simple_mob/hostile/syndicate/ranged, /turf/simulated/floor{ icon_state = "cafeteria"; dir = 5 @@ -447,7 +447,7 @@ /turf/simulated/floor/wood, /area/awaymission/wwmines) "bE" = ( -/mob/living/simple_animal/hostile/syndicate/ranged, +/mob/living/simple_mob/hostile/syndicate/ranged, /turf/simulated/floor/wood, /area/awaymission/wwmines) "bF" = ( @@ -832,7 +832,7 @@ /turf/simulated/floor/wood, /area/awaymission/wwgov) "cG" = ( -/mob/living/simple_animal/hostile/creature, +/mob/living/simple_mob/hostile/creature, /turf/simulated/floor{ icon_state = "stage_bleft" }, @@ -871,7 +871,7 @@ /turf/simulated/floor/wood, /area/awaymission/wwgov) "cN" = ( -/mob/living/simple_animal/hostile/creature, +/mob/living/simple_mob/hostile/creature, /turf/simulated/floor/wood, /area/awaymission/wwgov) "cO" = ( @@ -881,7 +881,7 @@ /turf/simulated/floor/wood, /area/awaymission/wwgov) "cP" = ( -/mob/living/simple_animal/hostile/creature, +/mob/living/simple_mob/hostile/creature, /turf/simulated/floor/carpet, /area/awaymission/wwgov) "cQ" = ( @@ -926,7 +926,7 @@ /area/awaymission/wwgov) "cT" = ( /obj/effect/decal/remains/human, -/mob/living/simple_animal/hostile/syndicate/ranged/space{ +/mob/living/simple_mob/hostile/syndicate/ranged/space{ name = "Syndicate Commander" }, /turf/simulated/floor/plating, @@ -1158,7 +1158,7 @@ /area/awaymission/wwgov) "dB" = ( /obj/structure/toilet, -/mob/living/simple_animal/hostile/creature, +/mob/living/simple_mob/hostile/creature, /turf/simulated/floor{ icon_state = "white" }, @@ -1482,7 +1482,7 @@ }, /area/awaymission/wwmines) "ew" = ( -/mob/living/simple_animal/hostile/syndicate/ranged, +/mob/living/simple_mob/hostile/syndicate/ranged, /turf/simulated/floor/carpet, /area/awaymission/wwmines) "ex" = ( @@ -1990,7 +1990,7 @@ /turf/space, /area) "fO" = ( -/mob/living/simple_animal/hostile/syndicate, +/mob/living/simple_mob/hostile/syndicate, /turf/simulated/floor, /area/awaymission/wwrefine) "fP" = ( @@ -2126,7 +2126,7 @@ /turf/simulated/floor/wood, /area/awaymission/wwmines) "gk" = ( -/mob/living/simple_animal/hostile/syndicate, +/mob/living/simple_mob/hostile/syndicate, /turf/simulated/floor/wood, /area/awaymission/wwmines) "gl" = ( @@ -2138,7 +2138,7 @@ /turf/simulated/floor/wood, /area/awaymission/wwmines) "gn" = ( -/mob/living/simple_animal/hostile/creature, +/mob/living/simple_mob/hostile/creature, /turf/simulated/floor/grass, /area/awaymission/wwgov) "go" = ( diff --git a/maps/RandomZLevels/zoo.dmm b/maps/RandomZLevels/zoo.dmm index 77724e7e1d..37346a6f16 100644 --- a/maps/RandomZLevels/zoo.dmm +++ b/maps/RandomZLevels/zoo.dmm @@ -138,7 +138,7 @@ "cH" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/shuttle/floor/black,/area/awaymission/zoo/tradeship) "cI" = (/obj/structure/table/reinforced,/obj/item/weapon/paper/zoo/pirate/volk,/turf/simulated/floor/carpet,/area/awaymission/zoo/pirateship) "cJ" = (/obj/structure/table/reinforced,/obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer,/turf/simulated/floor/carpet,/area/awaymission/zoo/pirateship) -"cK" = (/mob/living/simple_animal/hostile/pirate,/turf/simulated/floor/carpet,/area/awaymission/zoo/pirateship) +"cK" = (/mob/living/simple_mob/hostile/pirate,/turf/simulated/floor/carpet,/area/awaymission/zoo/pirateship) "cL" = (/obj/machinery/portable_atmospherics/hydroponics,/obj/effect/floor_decal/corner/green/full,/turf/simulated/floor/tiled,/area/awaymission/zoo/pirateship) "cM" = (/obj/effect/floor_decal/corner/green{dir = 10},/turf/simulated/floor/tiled,/area/awaymission/zoo/pirateship) "cN" = (/obj/machinery/seed_extractor,/obj/item/seeds/angelmycelium,/obj/effect/floor_decal/corner/green{dir = 10},/turf/simulated/floor/tiled,/area/awaymission/zoo/pirateship) @@ -189,7 +189,7 @@ "dG" = (/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/awaymission/zoo/pirateship) "dH" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/item/weapon/reagent_containers/food/snacks/xenomeat,/turf/simulated/floor/plating,/area/awaymission/zoo/pirateship) "dI" = (/obj/structure/table/rack,/obj/item/weapon/storage/box/lights,/obj/effect/floor_decal/industrial/warning{dir = 8},/turf/simulated/floor/tiled,/area/awaymission/zoo/pirateship) -"dJ" = (/mob/living/simple_animal/hostile/pirate,/turf/simulated/floor/tiled,/area/awaymission/zoo/pirateship) +"dJ" = (/mob/living/simple_mob/hostile/pirate,/turf/simulated/floor/tiled,/area/awaymission/zoo/pirateship) "dK" = (/obj/machinery/power/fractal_reactor/fluff/converter{mapped_in = 1; power_generation_rate = 10000},/turf/simulated/floor/plating,/area/awaymission/zoo/pirateship) "dL" = (/obj/machinery/power/terminal{dir = 8},/turf/simulated/floor/plating,/area/awaymission/zoo/pirateship) "dM" = (/turf/space,/area/awaymission/zoo/tradeship) @@ -231,9 +231,9 @@ "ew" = (/obj/structure/curtain/open/shower,/obj/machinery/shower{pixel_y = 3},/turf/simulated/shuttle/floor/black,/area/awaymission/zoo/tradeship) "ex" = (/obj/machinery/vending/snack{name = "hacked Getmore Chocolate Corp"; prices = list()},/turf/simulated/shuttle/floor/black,/area/awaymission/zoo/tradeship) "ey" = (/obj/structure/window/reinforced,/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/shuttle/floor/black,/area/awaymission/zoo/tradeship) -"ez" = (/obj/effect/floor_decal/corner/red/diagonal,/mob/living/simple_animal/hostile/pirate,/turf/simulated/floor/tiled,/area/awaymission/zoo/pirateship) +"ez" = (/obj/effect/floor_decal/corner/red/diagonal,/mob/living/simple_mob/hostile/pirate,/turf/simulated/floor/tiled,/area/awaymission/zoo/pirateship) "eA" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating,/area/awaymission/zoo/pirateship) -"eB" = (/mob/living/simple_animal/hostile/alien{faction = "pirate"},/turf/simulated/floor/plating,/area/awaymission/zoo/pirateship) +"eB" = (/mob/living/simple_mob/hostile/alien{faction = "pirate"},/turf/simulated/floor/plating,/area/awaymission/zoo/pirateship) "eC" = (/obj/machinery/door/window{base_state = "right"; dir = 4; icon_state = "right"},/obj/item/weapon/reagent_containers/food/snacks/xenomeat,/turf/simulated/floor/plating,/area/awaymission/zoo/pirateship) "eD" = (/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/awaymission/zoo/pirateship) "eE" = (/obj/item/weapon/reagent_containers/food/snacks/xenomeat,/turf/simulated/floor/plating,/area/awaymission/zoo/pirateship) @@ -415,7 +415,7 @@ "hY" = (/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/shuttle/plating,/area/awaymission/zoo/syndieship) "hZ" = (/obj/machinery/vending/cigarette{name = "hacked cigarette machine"; prices = list(); products = list(/obj/item/weapon/storage/fancy/cigarettes = 10, /obj/item/weapon/storage/box/matches = 10, /obj/item/weapon/flame/lighter/zippo = 4, /obj/item/clothing/mask/smokable/cigarette/cigar/havana = 2)},/turf/simulated/shuttle/floor/darkred,/area/awaymission/zoo/syndieship) "ia" = (/obj/structure/bed/chair{dir = 8},/obj/machinery/button/flasher{id = "syndieflash"; name = "Flasher"; pixel_x = 27; pixel_y = 0;},/turf/simulated/shuttle/floor/darkred,/area/awaymission/zoo/syndieship) -"ib" = (/mob/living/simple_animal/cat/kitten{name = "Enola"},/turf/simulated/shuttle/floor/darkred,/area/awaymission/zoo/syndieship) +"ib" = (/mob/living/simple_mob/cat/kitten{name = "Enola"},/turf/simulated/shuttle/floor/darkred,/area/awaymission/zoo/syndieship) "ic" = (/obj/machinery/suit_cycler/syndicate{locked = 0},/turf/simulated/shuttle/floor/darkred,/area/awaymission/zoo/syndieship) "id" = (/obj/structure/table/standard,/obj/item/weapon/material/kitchen/utensil/knife{pixel_x = -6},/obj/item/weapon/reagent_containers/syringe/drugs{pixel_x = 3; pixel_y = -1},/obj/item/weapon/reagent_containers/syringe/drugs{pixel_x = 3; pixel_y = 4},/obj/item/weapon/reagent_containers/syringe/drugs{pixel_x = 3; pixel_y = 9},/obj/machinery/light{dir = 8; icon_state = "tube1"; pixel_y = 0},/turf/simulated/shuttle/floor/darkred,/area/awaymission/zoo/syndieship) "ie" = (/obj/machinery/door/window/eastleft,/turf/simulated/shuttle/floor/darkred,/area/awaymission/zoo/syndieship) @@ -424,7 +424,7 @@ "ih" = (/obj/structure/bed/chair{dir = 1},/turf/simulated/floor/tiled,/area/awaymission/zoo) "ii" = (/obj/structure/closet{name = "custodial"},/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/weapon/mop,/obj/item/weapon/reagent_containers/spray/cleaner,/turf/simulated/shuttle/floor/darkred,/area/awaymission/zoo/syndieship) "ij" = (/obj/machinery/door/window/eastright,/turf/simulated/shuttle/floor/darkred,/area/awaymission/zoo/syndieship) -"ik" = (/mob/living/simple_animal/hostile/syndicate/ranged{desc = "He doesn't seem like he's looking for a fight."; faction = "neutral"; friendly = "hugs"; name = "Mercenary"},/turf/simulated/shuttle/floor/darkred,/area/awaymission/zoo/syndieship) +"ik" = (/mob/living/simple_mob/hostile/syndicate/ranged{desc = "He doesn't seem like he's looking for a fight."; faction = "neutral"; friendly = "hugs"; name = "Mercenary"},/turf/simulated/shuttle/floor/darkred,/area/awaymission/zoo/syndieship) "il" = (/obj/machinery/door/window/westleft,/turf/simulated/shuttle/floor/darkred,/area/awaymission/zoo/syndieship) "im" = (/obj/machinery/light{dir = 8; icon_state = "tube1"; pixel_y = 0},/obj/machinery/sleeper{dir = 8},/turf/simulated/shuttle/floor/darkred,/area/awaymission/zoo/syndieship) "in" = (/obj/machinery/sleep_console,/turf/simulated/shuttle/floor/darkred,/area/awaymission/zoo/syndieship) @@ -511,9 +511,9 @@ "jQ" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/awaymission/zoo) "jR" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/awaymission/zoo) "jS" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/awaymission/zoo) -"jT" = (/mob/living/simple_animal/chicken{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass0"},/area/awaymission/zoo) -"jU" = (/mob/living/simple_animal/chick,/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass0"},/area/awaymission/zoo) -"jV" = (/mob/living/simple_animal/corgi/puppy{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass0"},/area/awaymission/zoo) +"jT" = (/mob/living/simple_mob/chicken{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass0"},/area/awaymission/zoo) +"jU" = (/mob/living/simple_mob/chick,/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass0"},/area/awaymission/zoo) +"jV" = (/mob/living/simple_mob/corgi/puppy{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass0"},/area/awaymission/zoo) "jW" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/flora/ausbushes/reedbush,/turf/simulated/floor/beach/water,/area/awaymission/zoo) "jX" = (/obj/effect/floor_decal/corner/green{dir = 10},/turf/simulated/floor/tiled,/area/awaymission/zoo) "jY" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/floor/beach/water,/area/awaymission/zoo) @@ -551,10 +551,10 @@ "kE" = (/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) "kF" = (/obj/structure/flora/ausbushes/leafybush,/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) "kG" = (/obj/structure/flora/ausbushes/ywflowers,/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) -"kH" = (/obj/structure/flora/ausbushes/ywflowers,/mob/living/simple_animal/bird/kea{faction = "zoo"},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) +"kH" = (/obj/structure/flora/ausbushes/ywflowers,/mob/living/simple_mob/bird/kea{faction = "zoo"},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) "kI" = (/obj/structure/flora/ausbushes/pointybush,/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) "kJ" = (/obj/structure/flora/ausbushes/brflowers,/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) -"kK" = (/obj/structure/flora/ausbushes/pointybush,/mob/living/simple_animal/bird/pink_too{faction = "zoo"},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) +"kK" = (/obj/structure/flora/ausbushes/pointybush,/mob/living/simple_mob/bird/pink_too{faction = "zoo"},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) "kL" = (/obj/structure/flora/ausbushes/sparsegrass,/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) "kM" = (/obj/structure/flora/ausbushes/ppflowers,/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) "kN" = (/obj/structure/urinal{pixel_x = -32},/turf/simulated/floor/tiled/white,/area/awaymission/zoo) @@ -565,7 +565,7 @@ "kS" = (/obj/structure/toilet{dir = 8},/turf/simulated/floor/tiled/white,/area/awaymission/zoo) "kT" = (/obj/structure/bed/chair/wood{dir = 1},/turf/simulated/floor/wood,/area/awaymission/zoo) "kU" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/awaymission/zoo) -"kV" = (/mob/living/simple_animal/cat{faction = "zoo"},/turf/simulated/floor/wood,/area/awaymission/zoo) +"kV" = (/mob/living/simple_mob/cat{faction = "zoo"},/turf/simulated/floor/wood,/area/awaymission/zoo) "kW" = (/turf/simulated/floor/holofloor/carpet,/area/awaymission/zoo) "kX" = (/obj/structure/table/marble,/turf/simulated/floor/holofloor/lino,/area/awaymission/zoo) "kY" = (/obj/structure/table/marble,/obj/item/weapon/pen/multi,/turf/simulated/floor/holofloor/lino,/area/awaymission/zoo) @@ -574,15 +574,15 @@ "lb" = (/obj/effect/floor_decal/spline/fancy/wood{dir = 5},/obj/item/weapon/coin/gold,/turf/simulated/floor/beach/water{icon_state = "seadeep"},/area/awaymission/zoo) "lc" = (/obj/effect/floor_decal/corner/green{dir = 9},/turf/simulated/floor/tiled,/area/awaymission/zoo) "ld" = (/obj/structure/flora/ausbushes/sunnybush,/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) -"le" = (/mob/living/simple_animal/bird/hooded_too{faction = "zoo"},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) +"le" = (/mob/living/simple_mob/bird/hooded_too{faction = "zoo"},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) "lf" = (/obj/structure/flora/ausbushes/grassybush,/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) -"lg" = (/obj/structure/flora/ausbushes/fullgrass,/mob/living/simple_animal/bird/grey_cockatiel{faction = "zoo"},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) +"lg" = (/obj/structure/flora/ausbushes/fullgrass,/mob/living/simple_mob/bird/grey_cockatiel{faction = "zoo"},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) "lh" = (/obj/structure/flora/ausbushes,/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) -"li" = (/obj/structure/flora/ausbushes/brflowers,/mob/living/simple_animal/bird/yellowish_cockatiel{faction = "zoo"},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) -"lj" = (/obj/structure/flora/ausbushes/ppflowers,/mob/living/simple_animal/bird/bluegreen_Budgerigar{faction = "zoo"},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) +"li" = (/obj/structure/flora/ausbushes/brflowers,/mob/living/simple_mob/bird/yellowish_cockatiel{faction = "zoo"},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) +"lj" = (/obj/structure/flora/ausbushes/ppflowers,/mob/living/simple_mob/bird/bluegreen_Budgerigar{faction = "zoo"},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) "lk" = (/obj/structure/flora/pottedplant{icon_state = "applebush"},/turf/simulated/floor/wood,/area/awaymission/zoo) "ll" = (/obj/machinery/door/airlock/glass{icon_state = "door_closed"; locked = 0; name = "Exhibit Airlock"},/turf/simulated/floor/tiled/white,/area/awaymission/zoo) -"lm" = (/mob/living/simple_animal/horse{faction = "zoo"},/turf/simulated/floor/wood,/area/awaymission/zoo) +"lm" = (/mob/living/simple_mob/horse{faction = "zoo"},/turf/simulated/floor/wood,/area/awaymission/zoo) "ln" = (/obj/effect/landmark/away,/turf/simulated/floor/wood,/area/awaymission/zoo) "lo" = (/obj/machinery/door/airlock/glass{icon_state = "door_closed"; locked = 0; name = "Exhibit Airlock"},/turf/simulated/floor/holofloor/carpet,/area/awaymission/zoo) "lp" = (/obj/structure/table/rack,/obj/random/action_figure,/turf/simulated/floor/holofloor/carpet,/area/awaymission/zoo) @@ -600,15 +600,15 @@ "lB" = (/obj/structure/toilet{dir = 8},/obj/effect/landmark/away,/turf/simulated/floor/tiled/white,/area/awaymission/zoo) "lC" = (/obj/structure/flora/pottedplant{icon_state = "plant-16"},/turf/simulated/floor/wood,/area/awaymission/zoo) "lD" = (/obj/structure/table/marble,/obj/machinery/cash_register{icon_state = "register_idle"; dir = 1},/turf/simulated/floor/tiled/white,/area/awaymission/zoo) -"lE" = (/mob/living/simple_animal/chick,/turf/simulated/floor/wood,/area/awaymission/zoo) +"lE" = (/mob/living/simple_mob/chick,/turf/simulated/floor/wood,/area/awaymission/zoo) "lF" = (/obj/effect/floor_decal/spline/fancy/wood{icon_state = "spline_fancy"; dir = 10},/turf/simulated/floor/beach/water{icon_state = "seadeep"},/area/awaymission/zoo) "lG" = (/obj/item/weapon/coin/silver,/turf/simulated/floor/beach/water{icon_state = "seadeep"},/area/awaymission/zoo) "lH" = (/obj/effect/floor_decal/spline/fancy/wood{dir = 6},/turf/simulated/floor/beach/water{icon_state = "seadeep"},/area/awaymission/zoo) -"lI" = (/mob/living/simple_animal/bird/green_budgerigar{faction = "zoo"},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) -"lJ" = (/obj/structure/flora/ausbushes/sunnybush,/mob/living/simple_animal/bird/cockatiel{faction = "zoo"},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) +"lI" = (/mob/living/simple_mob/bird/green_budgerigar{faction = "zoo"},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) +"lJ" = (/obj/structure/flora/ausbushes/sunnybush,/mob/living/simple_mob/bird/cockatiel{faction = "zoo"},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) "lK" = (/obj/structure/flora/ausbushes/genericbush,/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) "lL" = (/obj/machinery/vending/dinnerware,/turf/simulated/floor/tiled/white,/area/awaymission/zoo) -"lM" = (/mob/living/simple_animal/cow{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass0"},/area/awaymission/zoo) +"lM" = (/mob/living/simple_mob/cow{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass0"},/area/awaymission/zoo) "lN" = (/obj/structure/table/rack,/obj/item/toy/nanotrasenballoon,/turf/simulated/floor/holofloor/carpet,/area/awaymission/zoo) "lO" = (/obj/structure/table/rack,/obj/item/toy/cultsword,/turf/simulated/floor/holofloor/carpet,/area/awaymission/zoo) "lP" = (/obj/structure/table/rack,/obj/item/toy/crossbow,/turf/simulated/floor/holofloor/carpet,/area/awaymission/zoo) @@ -623,8 +623,8 @@ "lY" = (/obj/effect/floor_decal/corner/green/full{dir = 1},/turf/simulated/floor/tiled,/area/awaymission/zoo) "lZ" = (/obj/effect/floor_decal/spline/fancy/wood{dir = 2},/turf/simulated/floor/beach/water{icon_state = "seadeep"},/area/awaymission/zoo) "ma" = (/obj/effect/floor_decal/corner/green/full{dir = 8},/turf/simulated/floor/tiled,/area/awaymission/zoo) -"mb" = (/mob/living/simple_animal/bird/yellowish_cockatiel{faction = "zoo"},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) -"mc" = (/mob/living/simple_animal/bird/white_caique{faction = "zoo"},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) +"mb" = (/mob/living/simple_mob/bird/yellowish_cockatiel{faction = "zoo"},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) +"mc" = (/mob/living/simple_mob/bird/white_caique{faction = "zoo"},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) "md" = (/obj/structure/toilet{dir = 4},/turf/simulated/floor/tiled/white,/area/awaymission/zoo) "me" = (/obj/structure/closet/crate/bin,/turf/simulated/floor/tiled/white,/area/awaymission/zoo) "mf" = (/obj/structure/closet/crate/bin,/obj/item/trash/candy,/turf/simulated/floor/tiled/white,/area/awaymission/zoo) @@ -645,7 +645,7 @@ "mu" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4; health = 1e+006},/obj/structure/window/reinforced{dir = 8; health = 1e+006},/turf/simulated/floor/plating,/area/awaymission/zoo) "mv" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/sign/kiddieplaque{desc = "This giant snake is a rare beast native to Paraiso, in the Carnelia system. Though normally only found deep in the jungles, these ravenous monsters have been known to slither out onto the planet's many beach resorts to swallow up unwary sunbathers. Otherwise, the creature's diet consists mainly of monkeys that were accidentally introduced to the planet by pet owners. The presence of the invasive monkey species had caused giant snake populations to swell in the 2530's, but today, due to excessive hunting, the giant snake's numbers have dwindled to the point of being an endangered species."; name = "Giant Snake Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) "mw" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/sign/kiddieplaque{desc = "Catgirls (not to be confused with Nekos, an interspecies hybrid born of a union between Human and Tajaran parents) were created artificially with the intention of producing a Human-feline hybrid that could serve aboard a space-faring vessel, control pests aboard such ships, and even alleviate stress among male crew members. Their eyes are between 20% and 50% larger than the average Human, which gives them their famously 'Kawaii' appearance. The large eyes trigger a subconscious psychological 'cute' response among Humans, causing them to usually become relaxed in their presence. Some catgirls have learned to abuse this trait, and have evolved to prey upon Humans who linger too close for too long."; name = "Catgirl Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) -"mx" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/sign/kiddieplaque{desc = "The Ir'ash'uint (translating roughly from Skrellian to 'Giant Frog' in Galactic Common), this amphibian lives on the Skrell homeworld Qerrbalak, in the Qerr’valis System. The Giant Frog shares a common, albeit distant ancestry with the Skrell, but unlike the Skrell, its diet is exclusively carnivorous. Its diet includes large insects, fish, and indeed, even Skrell."; name = "Giant Frog Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) +"mx" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/sign/kiddieplaque{desc = "The Ir'ash'uint (translating roughly from Skrellian to 'Giant Frog' in Galactic Common), this amphibian lives on the Skrell homeworld Qerrbalak, in the Qerr�valis System. The Giant Frog shares a common, albeit distant ancestry with the Skrell, but unlike the Skrell, its diet is exclusively carnivorous. Its diet includes large insects, fish, and indeed, even Skrell."; name = "Giant Frog Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) "my" = (/obj/structure/window/phoronreinforced{dir = 8; icon_state = "phoronrwindow"; maxhealth = 10000; name = "robust borosilicate window";},/obj/structure/window/phoronreinforced{dir = 1; icon_state = "phoronrwindow"; maxhealth = 10000; name = "robust borosilicate window";},/obj/structure/window/phoronreinforced{dir = 4; icon_state = "phoronrwindow"; maxhealth = 10000; name = "robust borosilicate window";},/obj/structure/grille,/turf/simulated/floor/plating,/area/awaymission/zoo) "mz" = (/obj/structure/window/phoronreinforced{dir = 8; icon_state = "phoronrwindow"; maxhealth = 10000; name = "robust borosilicate window";},/obj/structure/window/phoronreinforced{maxhealth = 10000; name = "robust borosilicate window"},/obj/structure/grille,/turf/simulated/floor/plating,/area/awaymission/zoo) "mA" = (/obj/structure/window/phoronreinforced{dir = 4; icon_state = "phoronrwindow"; maxhealth = 10000; name = "robust borosilicate window";},/obj/structure/window/phoronreinforced{dir = 1; icon_state = "phoronrwindow"; maxhealth = 10000; name = "robust borosilicate window";},/obj/structure/grille,/turf/simulated/floor/plating,/area/awaymission/zoo) @@ -693,7 +693,7 @@ "nq" = (/obj/structure/bed/chair,/obj/structure/showcase{name = "Statue"; desc = "It looks almost lifelike."; icon = 'icons/obj/statue.dmi'; icon_state = "Human_male"},/turf/simulated/floor/lino,/area/awaymission/zoo) "nr" = (/turf/simulated/mineral/ignore_mapgen,/area/awaymission/zoo) "ns" = (/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass4"},/area/awaymission/zoo) -"nt" = (/mob/living/simple_animal/tindalos{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "fullgrass0"},/area/awaymission/zoo) +"nt" = (/mob/living/simple_mob/tindalos{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "fullgrass0"},/area/awaymission/zoo) "nu" = (/obj/structure/flora/ausbushes/ywflowers,/turf/simulated/floor/holofloor/beach/sand{icon_state = "fullgrass0"},/area/awaymission/zoo) "nv" = (/obj/structure/flora/ausbushes/leafybush,/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass0"},/area/awaymission/zoo) "nw" = (/obj/effect/overlay/palmtree_l,/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass0"},/area/awaymission/zoo) @@ -729,13 +729,13 @@ "oa" = (/obj/effect/overlay/palmtree_r,/turf/simulated/floor/holofloor/beach/sand{icon_state = "fullgrass2"},/area/awaymission/zoo) "ob" = (/obj/structure/flora/ausbushes/lavendergrass,/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass3"},/area/awaymission/zoo) "oc" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/sign/kiddieplaque{desc = "Catgirls (not to be confused with Nekos, an interspecies hybrid born of a union between Human and Tajaran parents) were created artificially with the intention of producing a Human-feline hybrid that could serve aboard a space-faring vessel, control pests aboard such ships, and even alleviate stress among male crew members. Their eyes are between 20% and 50% larger than the average Human, which gives them their famously 'Kawaii' appearance. The large eyes trigger a subconscious psychological 'cute' response among Humans, causing them to usually become relaxed in their presence. Some catgirls have learned to abuse this trait, and have evolved to prey upon Humans who linger too close for too long."; name = "Catgirl Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) -"od" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/sign/kiddieplaque{desc = "The Ir'ash'uint (translating roughly from Skrellian to 'Giant Frog' in Galactic Common), this amphibian lives on the Skrell homeworld Qerrbalak, in the Qerr’valis System. The Giant Frog shares a common, albeit distant ancestry with the Skrell, but unlike the Skrell, its diet is exclusively carnivorous. Its diet includes large insects, fish, and indeed, even Skrell."; name = "Giant Frog Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) +"od" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/sign/kiddieplaque{desc = "The Ir'ash'uint (translating roughly from Skrellian to 'Giant Frog' in Galactic Common), this amphibian lives on the Skrell homeworld Qerrbalak, in the Qerr�valis System. The Giant Frog shares a common, albeit distant ancestry with the Skrell, but unlike the Skrell, its diet is exclusively carnivorous. Its diet includes large insects, fish, and indeed, even Skrell."; name = "Giant Frog Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) "oe" = (/obj/structure/flora/ausbushes/leafybush,/turf/simulated/floor/holofloor/grass{icon = 'icons/jungle.dmi'; icon_state = "grass2"},/area/awaymission/zoo) -"of" = (/mob/living/simple_animal/hostile/frog{faction = "zoo"},/turf/simulated/floor/holofloor/grass{icon = 'icons/jungle.dmi'; icon_state = "grass2"},/area/awaymission/zoo) +"of" = (/mob/living/simple_mob/hostile/frog{faction = "zoo"},/turf/simulated/floor/holofloor/grass{icon = 'icons/jungle.dmi'; icon_state = "grass2"},/area/awaymission/zoo) "og" = (/turf/simulated/floor/holofloor/beach/water{icon_state = "beach"; dir = 10},/area/awaymission/zoo) "oh" = (/turf/simulated/floor/holofloor/beach/water{icon_state = "beach"; dir = 6},/area/awaymission/zoo) "oi" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/awaymission/zoo) -"oj" = (/mob/living/simple_animal/tindalos{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "fullgrass1"},/area/awaymission/zoo) +"oj" = (/mob/living/simple_mob/tindalos{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "fullgrass1"},/area/awaymission/zoo) "ok" = (/obj/structure/flora/ausbushes/grassybush,/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass1"},/area/awaymission/zoo) "ol" = (/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass1"},/area/awaymission/zoo) "om" = (/obj/structure/flora/ausbushes/sparsegrass,/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass4"},/area/awaymission/zoo) @@ -747,13 +747,13 @@ "os" = (/obj/structure/flora/ausbushes/genericbush,/turf/simulated/floor/holofloor/grass{icon = 'icons/jungle.dmi'; icon_state = "grass2"},/area/awaymission/zoo) "ot" = (/turf/simulated/floor/holofloor/beach/water,/area/awaymission/zoo) "ou" = (/turf/simulated/floor/holofloor/beach/water{icon_state = "beach"; dir = 2},/area/awaymission/zoo) -"ov" = (/mob/living/simple_animal/corgi{faction = "zoo"},/turf/simulated/floor/lino,/area/awaymission/zoo) +"ov" = (/mob/living/simple_mob/corgi{faction = "zoo"},/turf/simulated/floor/lino,/area/awaymission/zoo) "ow" = (/obj/structure/flora/ausbushes/leafybush,/turf/simulated/floor/holofloor/beach/sand{icon_state = "fullgrass0"},/area/awaymission/zoo) "ox" = (/obj/effect/overlay/coconut,/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass3"},/area/awaymission/zoo) "oy" = (/obj/effect/overlay/palmtree_l,/turf/simulated/floor/holofloor/beach/sand{icon_state = "fullgrass0"},/area/awaymission/zoo) "oz" = (/obj/structure/flora/ausbushes/fullgrass,/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass0"},/area/awaymission/zoo) -"oA" = (/obj/structure/flora/ausbushes/lavendergrass,/mob/living/simple_animal/cat{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass4"},/area/awaymission/zoo) -"oB" = (/mob/living/simple_animal/retaliate/bee{faction = "zoo"},/turf/simulated/floor/holofloor/grass{icon = 'icons/turf/flooring/misc_vr.dmi'; icon_state = "hive"; name = "giant honeycomb"},/area/awaymission/zoo) +"oA" = (/obj/structure/flora/ausbushes/lavendergrass,/mob/living/simple_mob/cat{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass4"},/area/awaymission/zoo) +"oB" = (/mob/living/simple_mob/retaliate/bee{faction = "zoo"},/turf/simulated/floor/holofloor/grass{icon = 'icons/turf/flooring/misc_vr.dmi'; icon_state = "hive"; name = "giant honeycomb"},/area/awaymission/zoo) "oC" = (/obj/structure/flora/ausbushes/sparsegrass,/turf/simulated/floor/holofloor/grass{icon = 'icons/jungle.dmi'; icon_state = "grass2"},/area/awaymission/zoo) "oD" = (/obj/structure/flora/ausbushes/palebush,/turf/simulated/floor/holofloor/grass{icon = 'icons/jungle.dmi'; icon_state = "grass2"},/area/awaymission/zoo) "oE" = (/obj/structure/bed/chair,/turf/simulated/floor/lino,/area/awaymission/zoo) @@ -763,7 +763,7 @@ "oI" = (/obj/structure/flora/ausbushes/genericbush,/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass2"},/area/awaymission/zoo) "oJ" = (/obj/effect/overlay/palmtree_l,/turf/simulated/floor/holofloor/beach/sand{icon_state = "fullgrass3"},/area/awaymission/zoo) "oK" = (/obj/structure/flora/ausbushes/sunnybush,/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass0"},/area/awaymission/zoo) -"oL" = (/mob/living/simple_animal/hostile/snake{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass3"},/area/awaymission/zoo) +"oL" = (/mob/living/simple_mob/hostile/snake{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass3"},/area/awaymission/zoo) "oM" = (/obj/structure/flora/ausbushes/lavendergrass,/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass2"},/area/awaymission/zoo) "oN" = (/obj/effect/floor_decal/spline/fancy/wood/corner,/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) "oO" = (/obj/structure/flora/ausbushes/sunnybush,/obj/effect/floor_decal/spline/fancy/wood,/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) @@ -772,7 +772,7 @@ "oR" = (/obj/effect/floor_decal/spline/fancy/wood/corner{dir = 8},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) "oS" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/sign/kiddieplaque{desc = "The Corgi (Welsh for 'dwarf dog') is a small type of herding dog that originated in Wales, on the planet Earth (Sol system). Two separate breeds are recognized: the Pembroke Welsh Corgi (as seen here) and the Cardigan Welsh Corgi. Historically, the Pembroke has been attributed to the influx of dogs alongside Flemish weavers from around the 10th century, while the Cardigan is attributed to the dogs brought with Norse settlers, in particular a common ancestor of the Swedish Vallhund. A certain degree of inbreeding between the two types has been suggested to explain the similarities between the two. Here it is seen in a replica of its natural habitat, the common office building, where it participates in a symbiotic relationship with the Humans who also reside here. In exchange for treats and bellyrubs, the Corgi provides the Humans with emotional support in the otherwise soul-crushing environment of the corporate workplace."; name = "Corgi Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) "oT" = (/obj/structure/table/reinforced,/turf/simulated/floor/lino,/area/awaymission/zoo) -"oU" = (/mob/living/simple_animal/hostile/scarybat{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) +"oU" = (/mob/living/simple_mob/hostile/scarybat{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) "oV" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/sign/kiddieplaque{desc = "The Tindalos is a large insect creature native to the Tubau plains of Zzarlaanis, in the Tiphonia system. The Human settlers who live on the planet have compared them to wingless grasshoppers. At high population densities and under certain environmental conditions, the Tindalos have been known to change behavior and form swarms. Tindalos are plant-eaters, sometimes becoming serious pests of cereals, vegetables and pasture, especially when they swarm in their millions and destroy crops over wide areas."; name = "Tindalos Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) "oW" = (/obj/effect/overlay/palmtree_l,/turf/simulated/floor/holofloor/beach/sand{icon_state = "fullgrass1"},/area/awaymission/zoo) "oX" = (/obj/structure/flora/ausbushes/genericbush,/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass3"},/area/awaymission/zoo) @@ -780,17 +780,17 @@ "oZ" = (/obj/effect/overlay/palmtree_r,/turf/simulated/floor/holofloor/beach/sand{icon_state = "fullgrass1"},/area/awaymission/zoo) "pa" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/sign/kiddieplaque{desc = "Cats were once common features on many trading, exploration, and naval ships in the early days of Human sailing. Cats were attracted by an abundance of mice and rats, which can cause damage to ropes, woodwork, and eventually as technology progressed, electrical wiring. Rodents also presented a threat to the stores the ship carried, both as cargo and as food for sailors. Furthermore, rats and mice were also sources of disease, which was dangerous for ships at sea for long periods of time. As Humanity thrust its self into the age of slipspace, the Cat has again made the common spaceship its hunting ground for exactly the same reasons it had in times of old. Skrell scientists have noted how the common Cat has been able to tame and even control Humans. It is believed that had the cat ever achieved sentience, Humanity its self would fall to its knees before their feline overlords. Fortunately for Humans across the galaxy, there is negligible evolutionary benefit for the cat to evolve further."; name = "Cat Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) "pb" = (/obj/effect/floor_decal/spline/fancy/wood{dir = 6},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) -"pc" = (/mob/living/simple_animal/catgirl{faction = "zoo"},/turf/simulated/floor/wood,/area/awaymission/zoo) +"pc" = (/mob/living/simple_mob/catgirl{faction = "zoo"},/turf/simulated/floor/wood,/area/awaymission/zoo) "pd" = (/obj/structure/flora/ausbushes/genericbush,/obj/effect/floor_decal/spline/fancy/wood{icon_state = "spline_fancy"; dir = 10},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) "pe" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/sign/kiddieplaque{desc = "The Space Bumble Bee is a large, usually docile stinging insect native to Virgo-Prime in the Virgo Erigone system. It normally lives in small oases around what few bodies of water exist on the arid landscape, but ever since Humans have come to colonize the world, they have been discovered in city parks even in the capital city of Anur. Despite their gentle demeanor however, they can and will attack when provoked, and are capable of opening their mandibles wide enough to swallow a Human sized victim whole. Deep in their abdomen, they process their victims along with harvested nectar into rich honey."; name = "Space Bumble Bee Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) -"pf" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/sign/kiddieplaque{desc = "The Sobaka, also known as the Dog Shark, is an amphibious, cold-blooded animal that lives in the tropical waters of Qerrbalak, in the Qerr’valis System. The Sobaka hunts fish and small animals while on land, but would prefer to scavenge than to hunt. Its nose is far more powerful than any canine species, and are able to smell both on land, and in the sea. The Sobaka are commonly employed as drug-sniffing and bomb-sniffing animals by Skrellian security forces. The Sobaka is a close relative of the sentient species called Akula."; name = "Sobaka Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) +"pf" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/sign/kiddieplaque{desc = "The Sobaka, also known as the Dog Shark, is an amphibious, cold-blooded animal that lives in the tropical waters of Qerrbalak, in the Qerr�valis System. The Sobaka hunts fish and small animals while on land, but would prefer to scavenge than to hunt. Its nose is far more powerful than any canine species, and are able to smell both on land, and in the sea. The Sobaka are commonly employed as drug-sniffing and bomb-sniffing animals by Skrellian security forces. The Sobaka is a close relative of the sentient species called Akula."; name = "Sobaka Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) "pg" = (/mob/living/carbon/human/sharkm{faction = "zoo"},/turf/simulated/floor/holofloor/beach/water,/area/awaymission/zoo) -"ph" = (/mob/living/simple_animal/tindalos{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass2"},/area/awaymission/zoo) +"ph" = (/mob/living/simple_mob/tindalos{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass2"},/area/awaymission/zoo) "pi" = (/obj/structure/flora/ausbushes/fernybush,/turf/simulated/floor/holofloor/beach/sand{icon_state = "fullgrass3"},/area/awaymission/zoo) "pj" = (/obj/effect/overlay/palmtree_r,/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass2"},/area/awaymission/zoo) -"pk" = (/mob/living/simple_animal/hostile/snake{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass0"},/area/awaymission/zoo) +"pk" = (/mob/living/simple_mob/hostile/snake{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass0"},/area/awaymission/zoo) "pl" = (/obj/structure/flora/ausbushes/ywflowers,/turf/simulated/floor/holofloor/beach/sand{icon_state = "fullgrass1"},/area/awaymission/zoo) -"pm" = (/mob/living/simple_animal/cat{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "fullgrass3"},/area/awaymission/zoo) +"pm" = (/mob/living/simple_mob/cat{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "fullgrass3"},/area/awaymission/zoo) "pn" = (/obj/effect/floor_decal/spline/fancy/wood{dir = 4},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) "po" = (/obj/effect/floor_decal/spline/fancy/wood{dir = 8},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) "pp" = (/obj/structure/flora/ausbushes/grassybush,/turf/simulated/floor/holofloor/grass{icon = 'icons/jungle.dmi'; icon_state = "grass2"},/area/awaymission/zoo) @@ -805,10 +805,10 @@ "py" = (/obj/structure/flora/ausbushes/palebush,/obj/effect/floor_decal/spline/fancy/wood{dir = 4},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) "pz" = (/obj/structure/flora/ausbushes/ppflowers,/turf/simulated/floor/holofloor/grass{icon = 'icons/jungle.dmi'; icon_state = "grass2"},/area/awaymission/zoo) "pA" = (/obj/structure/flora/ausbushes/sparsegrass,/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass2"},/area/awaymission/zoo) -"pB" = (/mob/living/simple_animal/tindalos{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass0"},/area/awaymission/zoo) +"pB" = (/mob/living/simple_mob/tindalos{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass0"},/area/awaymission/zoo) "pC" = (/obj/effect/overlay/palmtree_r,/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass1"},/area/awaymission/zoo) "pD" = (/obj/structure/flora/ausbushes/sunnybush,/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass1"},/area/awaymission/zoo) -"pE" = (/mob/living/simple_animal/cat{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass2"},/area/awaymission/zoo) +"pE" = (/mob/living/simple_mob/cat{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass2"},/area/awaymission/zoo) "pF" = (/obj/effect/floor_decal/spline/fancy/wood/corner{dir = 1},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) "pG" = (/obj/effect/floor_decal/spline/fancy/wood{dir = 5},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) "pH" = (/obj/structure/flora/ausbushes/fullgrass,/obj/effect/floor_decal/spline/fancy/wood{icon_state = "spline_fancy"; dir = 9},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) @@ -873,7 +873,7 @@ "qO" = (/obj/item/trash/syndi_cakes,/turf/simulated/floor/plating,/area/awaymission/zoo) "qP" = (/obj/item/weapon/stool/padded,/turf/simulated/floor/plating,/area/awaymission/zoo) "qQ" = (/obj/effect/decal/cleanable/generic,/turf/simulated/floor/plating,/area/awaymission/zoo) -"qR" = (/mob/living/simple_animal/mouse{faction = "zoo"},/turf/simulated/floor/plating,/area/awaymission/zoo) +"qR" = (/mob/living/simple_mob/mouse{faction = "zoo"},/turf/simulated/floor/plating,/area/awaymission/zoo) "qS" = (/obj/effect/decal/cleanable/blood/oil,/turf/simulated/floor/plating,/area/awaymission/zoo) "qT" = (/obj/item/trash/chips,/turf/simulated/floor/plating,/area/awaymission/zoo) "qU" = (/obj/structure/table/rack,/obj/item/weapon/storage/box/lights/mixed,/turf/simulated/floor/plating,/area/awaymission/zoo) @@ -887,7 +887,7 @@ "rc" = (/obj/effect/floor_decal/spline/fancy/wood{dir = 8},/obj/structure/flora/ausbushes/brflowers,/turf/simulated/floor/grass,/area/awaymission/zoo) "rd" = (/obj/effect/floor_decal/spline/fancy/wood{dir = 4},/obj/structure/flora/ausbushes/brflowers,/turf/simulated/floor/grass,/area/awaymission/zoo) "re" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/awaymission/zoo) -"rf" = (/mob/living/simple_animal/hostile/diyaab{faction = "zoo"},/turf/simulated/floor/holofloor/snow,/area/awaymission/zoo) +"rf" = (/mob/living/simple_mob/hostile/diyaab{faction = "zoo"},/turf/simulated/floor/holofloor/snow,/area/awaymission/zoo) "rg" = (/obj/effect/floor_decal/spline/fancy/wood{icon_state = "spline_fancy"; dir = 10},/obj/structure/flora/ausbushes/ppflowers,/turf/simulated/floor/grass,/area/awaymission/zoo) "rh" = (/obj/structure/flora/ausbushes/ywflowers,/obj/effect/floor_decal/spline/fancy/wood/corner{dir = 8},/turf/simulated/floor/grass,/area/awaymission/zoo) "ri" = (/obj/structure/flora/ausbushes/ywflowers,/obj/effect/floor_decal/spline/fancy/wood/corner,/turf/simulated/floor/grass,/area/awaymission/zoo) @@ -901,7 +901,7 @@ "rq" = (/turf/simulated/floor,/area/awaymission/zoo) "rr" = (/obj/effect/floor_decal/spline/fancy/wood{dir = 2},/obj/structure/flora/ausbushes/brflowers,/turf/simulated/floor/grass,/area/awaymission/zoo) "rs" = (/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 1},/turf/simulated/floor/plating,/area/awaymission/zoo) -"rt" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/sign/kiddieplaque{desc = "The Xenomorph XX121, better known just as Xenomorph, are an extraterrestrial, endoparasitoid species with multiple life cycles, possibly originating from the planet Proteus (also known as Xenomorph Prime), which orbits the star A6 454. One of the deadliest of all known alien species, these creatures need a host organism in order to reproduce. The appearance of the Xenomorph varies depending on its host. The Human phenotype is generally around 7–8 feet, and roughly 136.0 to 181.4 kilograms in weight, with a long, muscular tail and large, curved, oblong head. The Queen of this species is generally twice as large (they can grow even larger, some even up to 100 feet tall, and stronger if given time) and possesses superior speed, strength and intelligence. The term Xenomorph is derived from the Greek words xeno ('stranger', 'alien', and 'foreigner') and morphe ('form', 'shape'). There are no solid facts as to the origins of the Xenomorph species; instead, there are many assumptions which cannot be confirmed. Based on the limited information we have, the most commonly accepted hypothesis is that they are an artificially created species, although another hypothesis says that they evolved naturally on a planet much different than our own. The Xenomorph lives in a hive together with its queen. Amazingly, the blood and other bodily fluids of the Xenomorph are highly acidic. It is not yet understood how a creature of such biology can exist. The planet Proteus is also home to rare, red-hued Xenomorphs, who frequently fight their black-colored rivals. Some Xenomorphs are alleged to be able to cloak themselves to be invisible to the human eye, but this has not been confirmed by independent study."; name = "Xenomorph Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) +"rt" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/sign/kiddieplaque{desc = "The Xenomorph XX121, better known just as Xenomorph, are an extraterrestrial, endoparasitoid species with multiple life cycles, possibly originating from the planet Proteus (also known as Xenomorph Prime), which orbits the star A6 454. One of the deadliest of all known alien species, these creatures need a host organism in order to reproduce. The appearance of the Xenomorph varies depending on its host. The Human phenotype is generally around 7�8 feet, and roughly 136.0 to 181.4 kilograms in weight, with a long, muscular tail and large, curved, oblong head. The Queen of this species is generally twice as large (they can grow even larger, some even up to 100 feet tall, and stronger if given time) and possesses superior speed, strength and intelligence. The term Xenomorph is derived from the Greek words xeno ('stranger', 'alien', and 'foreigner') and morphe ('form', 'shape'). There are no solid facts as to the origins of the Xenomorph species; instead, there are many assumptions which cannot be confirmed. Based on the limited information we have, the most commonly accepted hypothesis is that they are an artificially created species, although another hypothesis says that they evolved naturally on a planet much different than our own. The Xenomorph lives in a hive together with its queen. Amazingly, the blood and other bodily fluids of the Xenomorph are highly acidic. It is not yet understood how a creature of such biology can exist. The planet Proteus is also home to rare, red-hued Xenomorphs, who frequently fight their black-colored rivals. Some Xenomorphs are alleged to be able to cloak themselves to be invisible to the human eye, but this has not been confirmed by independent study."; name = "Xenomorph Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) "ru" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/sign/kiddieplaque{desc = "Space spider is a broad classification is used to indicate a subspecies of arachnids discovered in the Tau sector. Extremely dangerous and voracious, this family of arachnids managed to evolve and adapt to grow and thrive in a variety of atmospheric conditions, even the complete lack of an atmosphere altogether. The females, bigger than the males, tend to lay their eggs in the bodies of animals killed during hunts. From there, the young specimens (spiderlings) will feed on the corpse for the first few hours of life until the body is picked clean, after which they will leave the nest to begin hunting for small parasites and anaerobic or aerobic creatures. Once they reach adulthood, their societal structure seems to change, pushing them to hunt in small packs, mostly favoring their numbers and aggressive nature, and inoculating a deadly toxin in their victims before sucking the nutrients dry."; name = "Space Spider Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) "rv" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/sign/kiddieplaque{desc = "The Samak are the apex predator in the various plains regions of the northern hemisphere of Meralar. Unlike many creatures of Meralar, it does not have any fur to speak of. Instead, it is completely covered in thick armored plates which act as a barrier between the Samak's internal warmth and the cold environment. However, this is still not that efficient, so the Samak feed often to keep themselves warm. The Samak have six thick legs tipped with broad claws, and roughly aerodynamic bodies. They burrow underground, detecting prey through incredibly keen thermal detection. They pop up suddenly, grab their next meal, and return underground just as quickly. They prefer larger prey, such as the Baqara, Elu'a Eli, and Tajaran. Due to their voracious appetites and tendency to ruin mine shafts and infrastructure, they have been hunted almost to extinction, mainly by the Slavemasters. For the Tajaran, being able to kill a Samak singlehandedly (and without 'cheating', such as saturation bombing and the like) is an incredible feat, and any individual who pulls it off is lauded greatly."; name = "Samak Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) "rw" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/sign/kiddieplaque{desc = "Space bears are the result of reckless experimentation in the early days of interplanetary travel and colonization. Rogue scientists in the beginnings of what is now known as Space Russia got very drunk one night, more than usual, and decided to 'improve' on the terran bear. The result is faster, stronger, and smarter than the original species, but most importantly they are able to survive in the airless void of space without any special equipment. It is unknown if they were originally meant to be living weapons or simply made 'because we can', but the scientists responsible were never heard from again. Now, thanks to faster than light travel and lackluster effort in making sure nothing's riding along, Space Bears can be found living on asteroids and moons across the galaxy, wherever Humanity and friends may roam."; name = "Space Bear Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) @@ -919,63 +919,63 @@ "rI" = (/obj/effect/floor_decal/spline{icon = 'icons/turf/floors.dmi'; icon_state = "asteroid_edge_w"; name = "rocky edge"},/obj/effect/floor_decal/asteroid,/turf/simulated/floor/holofloor/desert{icon = 'icons/turf/floors.dmi'; icon_state = "asteroidplating"; name = "scorched sand"},/area/awaymission/zoo) "rJ" = (/obj/structure/flora/bush,/turf/simulated/floor/holofloor/snow,/area/awaymission/zoo) "rK" = (/obj/effect/floor_decal/spline{icon = 'icons/turf/floors.dmi'; icon_state = "asteroid_edge_w"; name = "rocky edge"},/obj/effect/floor_decal/spline{icon = 'icons/turf/floors.dmi'; icon_state = "asteroid_edge_e"; name = "rocky edge"},/obj/effect/floor_decal/spline{icon = 'icons/turf/floors.dmi'; icon_state = "asteroid_edge_n"; name = "rocky edge"},/turf/simulated/floor/holofloor/desert{icon = 'icons/turf/floors.dmi'; icon_state = "asteroidplating"; name = "scorched sand"},/area/awaymission/zoo) -"rL" = (/mob/living/simple_animal/hostile/alien{faction = "zoo"},/turf/simulated/floor/holofloor/desert{icon = 'icons/turf/floors.dmi'; icon_state = "asteroidplating"; name = "scorched sand"},/area/awaymission/zoo) +"rL" = (/mob/living/simple_mob/hostile/alien{faction = "zoo"},/turf/simulated/floor/holofloor/desert{icon = 'icons/turf/floors.dmi'; icon_state = "asteroidplating"; name = "scorched sand"},/area/awaymission/zoo) "rM" = (/obj/effect/floor_decal/spline{icon = 'icons/turf/floors.dmi'; icon_state = "asteroid_edge_e"; name = "rocky edge"},/obj/effect/floor_decal/spline{icon = 'icons/turf/floors.dmi'; icon_state = "asteroid_edge_n"; name = "rocky edge"},/turf/simulated/floor/holofloor/desert{icon = 'icons/turf/floors.dmi'; icon_state = "asteroidplating"; name = "scorched sand"},/area/awaymission/zoo) "rN" = (/obj/effect/floor_decal/spline{icon = 'icons/turf/floors.dmi'; icon_state = "asteroid_edge_e"; name = "rocky edge"},/obj/effect/floor_decal/asteroid,/turf/simulated/floor/holofloor/desert{icon = 'icons/turf/floors.dmi'; icon_state = "asteroidplating"; name = "scorched sand"},/area/awaymission/zoo) "rO" = (/obj/structure/closet/crate,/obj/effect/floor_decal/industrial/outline/yellow,/turf/simulated/floor/tiled/neutral,/area/awaymission/zoo) "rP" = (/turf/simulated/floor/tiled/neutral,/area/awaymission/zoo) "rQ" = (/obj/structure/flora/grass/both,/turf/simulated/floor/holofloor/snow,/area/awaymission/zoo) -"rR" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/sign/kiddieplaque{desc = "The Xenomorph XX121, better known just as Xenomorph, are an extraterrestrial, endoparasitoid species with multiple life cycles, possibly originating from the planet Proteus (also known as Xenomorph Prime), which orbits the star A6 454. One of the deadliest of all known alien species, these creatures need a host organism in order to reproduce. The appearance of the Xenomorph varies depending on its host. The Human phenotype is generally around 7–8 feet, and roughly 136.0 to 181.4 kilograms in weight, with a long, muscular tail and large, curved, oblong head. The Queen of this species is generally twice as large (they can grow even larger, some even up to 100 feet tall, and stronger if given time) and possesses superior speed, strength and intelligence. The term Xenomorph is derived from the Greek words xeno ('stranger', 'alien', and 'foreigner') and morphe ('form', 'shape'). There are no solid facts as to the origins of the Xenomorph species; instead, there are many assumptions which cannot be confirmed. Based on the limited information we have, the most commonly accepted hypothesis is that they are an artificially created species, although another hypothesis says that they evolved naturally on a planet much different than our own. The Xenomorph lives in a hive together with its queen. Amazingly, the blood and other bodily fluids of the Xenomorph are highly acidic. It is not yet understood how a creature of such biology can exist. The planet Proteus is also home to rare, red-hued Xenomorphs, who frequently fight their black-colored rivals. Some Xenomorphs are alleged to be able to cloak themselves to be invisible to the human eye, but this has not been confirmed by independent study."; name = "Xenomorph Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) -"rS" = (/mob/living/simple_animal/hostile/alien/drone{faction = "zoo"},/turf/simulated/floor/holofloor/desert{icon = 'icons/turf/floors.dmi'; icon_state = "asteroidplating"; name = "scorched sand"},/area/awaymission/zoo) +"rR" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/sign/kiddieplaque{desc = "The Xenomorph XX121, better known just as Xenomorph, are an extraterrestrial, endoparasitoid species with multiple life cycles, possibly originating from the planet Proteus (also known as Xenomorph Prime), which orbits the star A6 454. One of the deadliest of all known alien species, these creatures need a host organism in order to reproduce. The appearance of the Xenomorph varies depending on its host. The Human phenotype is generally around 7�8 feet, and roughly 136.0 to 181.4 kilograms in weight, with a long, muscular tail and large, curved, oblong head. The Queen of this species is generally twice as large (they can grow even larger, some even up to 100 feet tall, and stronger if given time) and possesses superior speed, strength and intelligence. The term Xenomorph is derived from the Greek words xeno ('stranger', 'alien', and 'foreigner') and morphe ('form', 'shape'). There are no solid facts as to the origins of the Xenomorph species; instead, there are many assumptions which cannot be confirmed. Based on the limited information we have, the most commonly accepted hypothesis is that they are an artificially created species, although another hypothesis says that they evolved naturally on a planet much different than our own. The Xenomorph lives in a hive together with its queen. Amazingly, the blood and other bodily fluids of the Xenomorph are highly acidic. It is not yet understood how a creature of such biology can exist. The planet Proteus is also home to rare, red-hued Xenomorphs, who frequently fight their black-colored rivals. Some Xenomorphs are alleged to be able to cloak themselves to be invisible to the human eye, but this has not been confirmed by independent study."; name = "Xenomorph Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) +"rS" = (/mob/living/simple_mob/hostile/alien/drone{faction = "zoo"},/turf/simulated/floor/holofloor/desert{icon = 'icons/turf/floors.dmi'; icon_state = "asteroidplating"; name = "scorched sand"},/area/awaymission/zoo) "rT" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/sign/kiddieplaque{desc = "Space spider is a broad classification is used to indicate a subspecies of arachnids discovered in the Tau sector. Extremely dangerous and voracious, this family of arachnids managed to evolve and adapt to grow and thrive in a variety of atmospheric conditions, even the complete lack of an atmosphere altogether. The females, bigger than the males, tend to lay their eggs in the bodies of animals killed during hunts. From there, the young specimens (spiderlings) will feed on the corpse for the first few hours of life until the body is picked clean, after which they will leave the nest to begin hunting for small parasites and anaerobic or aerobic creatures. Once they reach adulthood, their societal structure seems to change, pushing them to hunt in small packs, mostly favoring their numbers and aggressive nature, and inoculating a deadly toxin in their victims before sucking the nutrients dry."; name = "Space Spider Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) "rU" = (/obj/effect/overlay/palmtree_r,/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) "rV" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/sign/kiddieplaque{desc = "The Samak are the apex predator in the various plains regions of the northern hemisphere of Meralar. Unlike many creatures of Meralar, it does not have any fur to speak of. Instead, it is completely covered in thick armored plates which act as a barrier between the Samak's internal warmth and the cold environment. However, this is still not that efficient, so the Samak feed often to keep themselves warm. The Samak have six thick legs tipped with broad claws, and roughly aerodynamic bodies. They burrow underground, detecting prey through incredibly keen thermal detection. They pop up suddenly, grab their next meal, and return underground just as quickly. They prefer larger prey, such as the Baqara, Elu'a Eli, and Tajaran. Due to their voracious appetites and tendency to ruin mine shafts and infrastructure, they have been hunted almost to extinction, mainly by the Slavemasters. For the Tajaran, being able to kill a Samak singlehandedly (and without 'cheating', such as saturation bombing and the like) is an incredible feat, and any individual who pulls it off is lauded greatly."; name = "Samak Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) -"rW" = (/mob/living/simple_animal/penguin{faction = "zoo"},/turf/simulated/floor/holofloor/snow,/area/awaymission/zoo) +"rW" = (/mob/living/simple_mob/penguin{faction = "zoo"},/turf/simulated/floor/holofloor/snow,/area/awaymission/zoo) "rX" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/sign/kiddieplaque{desc = "Space bears are the result of reckless experimentation in the early days of interplanetary travel and colonization. Rogue scientists in the beginnings of what is now known as Space Russia got very drunk one night, more than usual, and decided to 'improve' on the terran bear. The result is faster, stronger, and smarter than the original species, but most importantly they are able to survive in the airless void of space without any special equipment. It is unknown if they were originally meant to be living weapons or simply made 'because we can', but the scientists responsible were never heard from again. Now, thanks to faster than light travel and lackluster effort in making sure nothing's riding along, Space Bears can be found living on asteroids and moons across the galaxy, wherever Humanity and friends may roam."; name = "Space Bear Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) "rY" = (/obj/effect/floor_decal/asteroid,/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) -"rZ" = (/mob/living/simple_animal/snake{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "fullgrass1"},/area/awaymission/zoo) -"sa" = (/obj/effect/floor_decal/spline{icon = 'icons/turf/floors.dmi'; icon_state = "asteroid_edge_w"; name = "rocky edge"},/obj/effect/floor_decal/spline{icon = 'icons/turf/floors.dmi'; icon_state = "asteroid_edge_s"; name = "rocky edge"},/mob/living/simple_animal/hostile/alien/drone{faction = "zoo"},/turf/simulated/floor/holofloor/desert{icon = 'icons/turf/floors.dmi'; icon_state = "asteroidplating"; name = "scorched sand"},/area/awaymission/zoo) +"rZ" = (/mob/living/simple_mob/snake{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "fullgrass1"},/area/awaymission/zoo) +"sa" = (/obj/effect/floor_decal/spline{icon = 'icons/turf/floors.dmi'; icon_state = "asteroid_edge_w"; name = "rocky edge"},/obj/effect/floor_decal/spline{icon = 'icons/turf/floors.dmi'; icon_state = "asteroid_edge_s"; name = "rocky edge"},/mob/living/simple_mob/hostile/alien/drone{faction = "zoo"},/turf/simulated/floor/holofloor/desert{icon = 'icons/turf/floors.dmi'; icon_state = "asteroidplating"; name = "scorched sand"},/area/awaymission/zoo) "sb" = (/obj/effect/floor_decal/spline{icon = 'icons/turf/floors.dmi'; icon_state = "asteroid_edge_s"; name = "rocky edge"},/turf/simulated/floor/holofloor/desert{icon = 'icons/turf/floors.dmi'; icon_state = "asteroidplating"; name = "scorched sand"},/area/awaymission/zoo) -"sc" = (/obj/effect/floor_decal/industrial/outline/yellow,/mob/living/simple_animal/hostile/mimic/crate{faction = "zoo"},/turf/simulated/floor/tiled/neutral,/area/awaymission/zoo) -"sd" = (/obj/structure/flora/ausbushes/fullgrass,/mob/living/simple_animal/penguin{faction = "zoo"},/turf/simulated/floor/holofloor/snow,/area/awaymission/zoo) -"se" = (/obj/effect/floor_decal/asteroid,/mob/living/simple_animal/hostile/bear{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) -"sf" = (/obj/structure/flora/grass/both,/mob/living/simple_animal/penguin{faction = "zoo"},/turf/simulated/floor/holofloor/snow,/area/awaymission/zoo) +"sc" = (/obj/effect/floor_decal/industrial/outline/yellow,/mob/living/simple_mob/hostile/mimic/crate{faction = "zoo"},/turf/simulated/floor/tiled/neutral,/area/awaymission/zoo) +"sd" = (/obj/structure/flora/ausbushes/fullgrass,/mob/living/simple_mob/penguin{faction = "zoo"},/turf/simulated/floor/holofloor/snow,/area/awaymission/zoo) +"se" = (/obj/effect/floor_decal/asteroid,/mob/living/simple_mob/hostile/bear{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) +"sf" = (/obj/structure/flora/grass/both,/mob/living/simple_mob/penguin{faction = "zoo"},/turf/simulated/floor/holofloor/snow,/area/awaymission/zoo) "sg" = (/obj/effect/overlay/palmtree_l,/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) -"sh" = (/mob/living/simple_animal/hostile/samak{faction = "zoo"},/turf/simulated/floor/holofloor/snow,/area/awaymission/zoo) +"sh" = (/mob/living/simple_mob/hostile/samak{faction = "zoo"},/turf/simulated/floor/holofloor/snow,/area/awaymission/zoo) "si" = (/obj/effect/floor_decal/spline/plain{dir = 9},/turf/simulated/floor/beach/water,/area/awaymission/zoo) "sj" = (/obj/effect/floor_decal/spline/plain{dir = 1},/turf/simulated/floor/beach/water,/area/awaymission/zoo) "sk" = (/obj/effect/floor_decal/spline/plain{dir = 5},/turf/simulated/floor/beach/water,/area/awaymission/zoo) -"sl" = (/mob/living/simple_animal/hostile/carp{faction = "zoo"},/turf/simulated/floor/holofloor/space,/area/awaymission/zoo) +"sl" = (/mob/living/simple_mob/hostile/carp{faction = "zoo"},/turf/simulated/floor/holofloor/space,/area/awaymission/zoo) "sm" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/sign/kiddieplaque{desc = "The common Green Snake is an invasive species that makes its home on tropical worlds across the galaxy. Its ancestors were once kept as pets by Humans, but these snakes had escaped into the ventilation of ships over many centuries to feed on the abundance of mice usually infesting the maintinence passages. It is believed that they are descended from the Ball Python, native to Earth, in the Sol system."; name = "Green Snake Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) "sn" = (/obj/effect/floor_decal/spline{icon = 'icons/turf/floors.dmi'; icon_state = "asteroid_edge_w"; name = "rocky edge"},/obj/effect/floor_decal/spline{icon = 'icons/turf/floors.dmi'; icon_state = "asteroid_edge_e"; name = "rocky edge"},/turf/simulated/floor/holofloor/desert{icon = 'icons/turf/floors.dmi'; icon_state = "asteroidplating"; name = "scorched sand"},/area/awaymission/zoo) -"so" = (/obj/effect/floor_decal/spline{icon = 'icons/turf/floors.dmi'; icon_state = "asteroid_edge_e"; name = "rocky edge"},/mob/living/simple_animal/hostile/alien/drone{faction = "zoo"},/turf/simulated/floor/holofloor/desert{icon = 'icons/turf/floors.dmi'; icon_state = "asteroidplating"; name = "scorched sand"},/area/awaymission/zoo) +"so" = (/obj/effect/floor_decal/spline{icon = 'icons/turf/floors.dmi'; icon_state = "asteroid_edge_e"; name = "rocky edge"},/mob/living/simple_mob/hostile/alien/drone{faction = "zoo"},/turf/simulated/floor/holofloor/desert{icon = 'icons/turf/floors.dmi'; icon_state = "asteroidplating"; name = "scorched sand"},/area/awaymission/zoo) "sp" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/sign/kiddieplaque{desc = "Don't be fooled, this isn't a storage room, but in fact the hunting ground of a deadly ambush predator known as the Mimic. The origin of this species is largely unknown, but they are theorized to be a cousin of the even more elusive changeling species. However, unlike the changeling, the mimic is known for disguising its self as inanimate objects, rather than other animals. When a suitable prey disturbs the mimic, it attacks, and if possible, swallows its victim whole. Scientists do not know how the creature reproduces, as all efforts to study the organism, dead or alive, have revealed that specimens examined do not have reproductive organs at all! It is hypothesized that the mimic grows and uses reproductive organs during a later life cycle, not yet recorded by any known sentient species."; name = "Mimic Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) -"sq" = (/obj/effect/spider/stickyweb,/mob/living/simple_animal/hostile/giant_spider/hunter{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) -"sr" = (/obj/effect/spider/cocoon{icon_state = "cocoon_large2"},/mob/living/simple_animal/hostile/giant_spider/hunter{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) -"ss" = (/obj/effect/spider/stickyweb,/mob/living/simple_animal/hostile/giant_spider{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) +"sq" = (/obj/effect/spider/stickyweb,/mob/living/simple_mob/hostile/giant_spider/hunter{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) +"sr" = (/obj/effect/spider/cocoon{icon_state = "cocoon_large2"},/mob/living/simple_mob/hostile/giant_spider/hunter{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) +"ss" = (/obj/effect/spider/stickyweb,/mob/living/simple_mob/hostile/giant_spider{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) "st" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/sign/kiddieplaque{desc = "Originating from the jungles of Earth, Parrots are a highly intelligent avian that have become an expensive commodity in space, prized for their colorful plumage, and their famous ability to mimic speech. Ship captains traditionally keep them as exotic pets, to demonstrate wealth, and to have someone to talk with. Some researchers believe some parrot species to be capable of intelligence up to that of a 5 year old Human in some aspects. Purebreds of exceptionally varied color pallets are especially prized among traders and space pirates."; name = "Parrot Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) "su" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/sign/kiddieplaque{desc = "Penguins are a group of aquatic, flightless birds living almost exclusively in the Southern Hemisphere of Earth, in the Sol system, especially in the continent of Antarctica. Highly adapted for life in the water, penguins have countershaded dark and white plumage, and their wings have evolved into flippers. Most penguins feed on krill, fish, squid and other forms of sealife caught while swimming underwater. They spend about half of their lives on land and half in the oceans. Due to the effects of global warming, penguins have been sent off-world to wildlife sanctuaries across the galaxy. Today, many such reserves harbor the last of this species, while penguins are now extinct on Earth."; name = "Space Penguin Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) "sv" = (/obj/effect/floor_decal/spline/plain{dir = 8},/turf/simulated/floor/beach/water,/area/awaymission/zoo) "sw" = (/obj/effect/floor_decal/spline/plain{dir = 4},/turf/simulated/floor/beach/water,/area/awaymission/zoo) "sx" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/sign/kiddieplaque{desc = "Space carp are a breed of space fish that come from the phoron giant Erebus. Scientists aren't quite sure how, but the Carp are imbued with the Phoron in their DNA, allowing for them to travel unaided through the vast void of Space, without gravity, air, or anything. They are very dangerous to space travelers, as they are highly aggressive and carnivorous. They often break windows and the like on space stations hoping to get in to eat the crew."; name = "Space Carp Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) "sy" = (/obj/effect/floor_decal/spline{icon = 'icons/turf/floors.dmi'; icon_state = "asteroid_edge_e"; name = "rocky edge"},/obj/effect/floor_decal/spline{icon = 'icons/turf/floors.dmi'; icon_state = "asteroid_edge_s"; name = "rocky edge"},/obj/effect/floor_decal/spline{icon = 'icons/turf/floors.dmi'; icon_state = "asteroid_edge_n"; name = "rocky edge"},/turf/simulated/floor/holofloor/desert{icon = 'icons/turf/floors.dmi'; icon_state = "asteroidplating"; name = "scorched sand"},/area/awaymission/zoo) -"sz" = (/obj/effect/floor_decal/spline{icon = 'icons/turf/floors.dmi'; icon_state = "asteroid_edge_w"; name = "rocky edge"},/mob/living/simple_animal/hostile/alien{faction = "zoo"; name = "invisible alien hunter"},/turf/simulated/floor/holofloor/desert{icon = 'icons/turf/floors.dmi'; icon_state = "asteroidplating"; name = "scorched sand"},/area/awaymission/zoo) -"sA" = (/obj/effect/spider/stickyweb{icon_state = "stickyweb2"},/obj/effect/spider/cocoon{icon_state = "cocoon3"},/mob/living/simple_animal/hostile/giant_spider/hunter{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) -"sB" = (/obj/effect/spider/stickyweb{icon_state = "cobweb1"},/mob/living/simple_animal/hostile/giant_spider/hunter{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) -"sC" = (/obj/effect/spider/cocoon{icon_state = "cocoon2"},/mob/living/simple_animal/hostile/giant_spider/nurse{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) -"sD" = (/obj/effect/spider/stickyweb{icon_state = "cobweb2"},/mob/living/simple_animal/hostile/giant_spider{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) -"sE" = (/obj/effect/spider/stickyweb{icon_state = "stickyweb2"},/obj/effect/spider/cocoon{icon_state = "cocoon_large1"},/mob/living/simple_animal/hostile/giant_spider{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) -"sF" = (/obj/effect/floor_decal/spline{icon = 'icons/turf/floors.dmi'; icon_state = "asteroid_edge_e"; name = "rocky edge"},/mob/living/simple_animal/hostile/alien/queen{faction = "zoo"},/turf/simulated/floor/holofloor/desert{icon = 'icons/turf/floors.dmi'; icon_state = "asteroidplating"; name = "scorched sand"},/area/awaymission/zoo) +"sz" = (/obj/effect/floor_decal/spline{icon = 'icons/turf/floors.dmi'; icon_state = "asteroid_edge_w"; name = "rocky edge"},/mob/living/simple_mob/hostile/alien{faction = "zoo"; name = "invisible alien hunter"},/turf/simulated/floor/holofloor/desert{icon = 'icons/turf/floors.dmi'; icon_state = "asteroidplating"; name = "scorched sand"},/area/awaymission/zoo) +"sA" = (/obj/effect/spider/stickyweb{icon_state = "stickyweb2"},/obj/effect/spider/cocoon{icon_state = "cocoon3"},/mob/living/simple_mob/hostile/giant_spider/hunter{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) +"sB" = (/obj/effect/spider/stickyweb{icon_state = "cobweb1"},/mob/living/simple_mob/hostile/giant_spider/hunter{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) +"sC" = (/obj/effect/spider/cocoon{icon_state = "cocoon2"},/mob/living/simple_mob/hostile/giant_spider/nurse{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) +"sD" = (/obj/effect/spider/stickyweb{icon_state = "cobweb2"},/mob/living/simple_mob/hostile/giant_spider{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) +"sE" = (/obj/effect/spider/stickyweb{icon_state = "stickyweb2"},/obj/effect/spider/cocoon{icon_state = "cocoon_large1"},/mob/living/simple_mob/hostile/giant_spider{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) +"sF" = (/obj/effect/floor_decal/spline{icon = 'icons/turf/floors.dmi'; icon_state = "asteroid_edge_e"; name = "rocky edge"},/mob/living/simple_mob/hostile/alien/queen{faction = "zoo"},/turf/simulated/floor/holofloor/desert{icon = 'icons/turf/floors.dmi'; icon_state = "asteroidplating"; name = "scorched sand"},/area/awaymission/zoo) "sG" = (/obj/effect/landmark/away,/turf/simulated/floor/tiled/neutral,/area/awaymission/zoo) -"sH" = (/obj/effect/spider/cocoon{icon_state = "cocoon_large3"},/mob/living/simple_animal/hostile/giant_spider/hunter{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) -"sI" = (/mob/living/simple_animal/hostile/giant_spider{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) -"sJ" = (/mob/living/simple_animal/parrot{faction = "zoo"},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) +"sH" = (/obj/effect/spider/cocoon{icon_state = "cocoon_large3"},/mob/living/simple_mob/hostile/giant_spider/hunter{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) +"sI" = (/mob/living/simple_mob/hostile/giant_spider{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) +"sJ" = (/mob/living/simple_mob/parrot{faction = "zoo"},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) "sK" = (/obj/effect/landmark/away,/turf/simulated/floor/beach/water,/area/awaymission/zoo) -"sL" = (/mob/living/simple_animal/hostile/bear{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) -"sM" = (/mob/living/simple_animal/hostile/alien{faction = "zoo"; name = "invisible alien hunter"},/turf/simulated/floor/holofloor/desert{icon = 'icons/turf/floors.dmi'; icon_state = "asteroidplating"; name = "scorched sand"},/area/awaymission/zoo) +"sL" = (/mob/living/simple_mob/hostile/bear{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) +"sM" = (/mob/living/simple_mob/hostile/alien{faction = "zoo"; name = "invisible alien hunter"},/turf/simulated/floor/holofloor/desert{icon = 'icons/turf/floors.dmi'; icon_state = "asteroidplating"; name = "scorched sand"},/area/awaymission/zoo) "sN" = (/obj/effect/decal/remains,/obj/effect/gibspawner/generic,/turf/simulated/floor/tiled/neutral,/area/awaymission/zoo) "sO" = (/obj/effect/spider/stickyweb,/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) -"sP" = (/mob/living/simple_animal/snake{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass4"},/area/awaymission/zoo) +"sP" = (/mob/living/simple_mob/snake{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass4"},/area/awaymission/zoo) "sQ" = (/obj/effect/floor_decal/spline{icon = 'icons/turf/floors.dmi'; icon_state = "asteroid_edge_w"; name = "rocky edge"},/obj/effect/floor_decal/spline{icon = 'icons/turf/floors.dmi'; icon_state = "asteroid_edge_e"; name = "rocky edge"},/obj/effect/floor_decal/spline{icon = 'icons/turf/floors.dmi'; icon_state = "asteroid_edge_s"; name = "rocky edge"},/turf/simulated/floor/holofloor/desert{icon = 'icons/turf/floors.dmi'; icon_state = "asteroidplating"; name = "scorched sand"},/area/awaymission/zoo) "sR" = (/obj/effect/spider/stickyweb{icon_state = "stickyweb2"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) "sS" = (/obj/effect/spider/stickyweb{icon_state = "cobweb2"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) @@ -986,7 +986,7 @@ "sX" = (/obj/effect/spider/stickyweb{icon_state = "cobweb1"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) "sY" = (/obj/structure/flora/grass/green,/turf/simulated/floor/holofloor/snow,/area/awaymission/zoo) "sZ" = (/obj/structure/flora/grass/brown,/turf/simulated/floor/holofloor/snow,/area/awaymission/zoo) -"ta" = (/obj/effect/floor_decal/asteroid,/mob/living/simple_animal/hostile/alien{faction = "zoo"},/turf/simulated/floor/holofloor/desert{icon = 'icons/turf/floors.dmi'; icon_state = "asteroidplating"; name = "scorched sand"},/area/awaymission/zoo) +"ta" = (/obj/effect/floor_decal/asteroid,/mob/living/simple_mob/hostile/alien{faction = "zoo"},/turf/simulated/floor/holofloor/desert{icon = 'icons/turf/floors.dmi'; icon_state = "asteroidplating"; name = "scorched sand"},/area/awaymission/zoo) "tb" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/sign/kiddieplaque{desc = "Stoks are a small species of reptile native to Moghes, ranging from two, to three feet tall with colorful scales, and feathers adorning their head, they stand on two legs and have short arms, the legs being digitigrade. They keep to oasises due to their colors which provide camouflage and distance from predators such as duneworms. Keeping in packs so that when they are threatened, they will swarm an attacker and take it down by sheer flanking and numbers. They're an omnivorous species, keeping themselves fed on either predators, or oasis fruits. Despite being the evolutionary equivalent of how monkeys are to humans, Stok are often domesticated and kept as pets by Unathi on Moghes, serving to aid in hunting efforts when trained. Their role in Unathi society is more like that of dogs to humans."; name = "Stok Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) "tc" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/sign/kiddieplaque{desc = "During the latest part of a Diona's life cycle, the Diona casts its self into orbit around a star, so it may soak up solar radiation and grow to immense proportions, even as large as a space station. The yithian, exhibited here, can only be found within these great Diona, where it has a symbiotic relationship with its host. It consumes fungus and parasites that would normally compromise the Diona's health."; name = "Yithian Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) "td" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/sign/kiddieplaque{desc = "A relative of the Tajaran, the Farwa is an intelligent pack animal widespread on Meralar, in the Rarkajar system. Usually with tan, orange and brown pelts, this animals is capable of using primitive tools. Its diet is primarly made up of vegetable matter and carrion, although they also hunt opportunistically. The species itself is very diverse, with Farwa in different biomes possessing minute variations in behaviour and genetic make-up."; name = "Farwa Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) @@ -994,7 +994,7 @@ "tf" = (/obj/structure/flora/ausbushes/fullgrass,/turf/simulated/floor/holofloor/wood{icon = 'icons/turf/floors.dmi'; icon_state = "diona"},/area/awaymission/zoo) "tg" = (/obj/structure/flora/ausbushes/genericbush,/turf/simulated/floor/holofloor/wood{icon = 'icons/turf/floors.dmi'; icon_state = "diona"},/area/awaymission/zoo) "th" = (/turf/simulated/floor/holofloor/wood{icon = 'icons/turf/floors.dmi'; icon_state = "diona"},/area/awaymission/zoo) -"ti" = (/mob/living/simple_animal/yithian{faction = "zoo"},/turf/simulated/floor/holofloor/wood{icon = 'icons/turf/floors.dmi'; icon_state = "diona"},/area/awaymission/zoo) +"ti" = (/mob/living/simple_mob/yithian{faction = "zoo"},/turf/simulated/floor/holofloor/wood{icon = 'icons/turf/floors.dmi'; icon_state = "diona"},/area/awaymission/zoo) "tj" = (/obj/machinery/portable_atmospherics/hydroponics/soil/invisible,/turf/simulated/floor/holofloor/wood{icon = 'icons/turf/floors.dmi'; icon_state = "diona"},/area/awaymission/zoo) "tk" = (/turf/simulated/floor/cult,/area/awaymission/zoo) "tl" = (/obj/structure/cult/pylon,/turf/simulated/floor/cult,/area/awaymission/zoo) @@ -1009,10 +1009,10 @@ "tu" = (/obj/structure/flora/ausbushes/sunnybush,/turf/simulated/floor/holofloor/wood{icon = 'icons/turf/floors.dmi'; icon_state = "diona"},/area/awaymission/zoo) "tv" = (/obj/structure/flora/ausbushes/palebush,/turf/simulated/floor/holofloor/wood{icon = 'icons/turf/floors.dmi'; icon_state = "diona"},/area/awaymission/zoo) "tw" = (/obj/structure/flora/ausbushes/ywflowers,/turf/simulated/floor/holofloor/wood{icon = 'icons/turf/floors.dmi'; icon_state = "diona"},/area/awaymission/zoo) -"tx" = (/obj/structure/flora/ausbushes/sunnybush,/mob/living/simple_animal/yithian{faction = "zoo"},/turf/simulated/floor/holofloor/wood{icon = 'icons/turf/floors.dmi'; icon_state = "diona"},/area/awaymission/zoo) +"tx" = (/obj/structure/flora/ausbushes/sunnybush,/mob/living/simple_mob/yithian{faction = "zoo"},/turf/simulated/floor/holofloor/wood{icon = 'icons/turf/floors.dmi'; icon_state = "diona"},/area/awaymission/zoo) "ty" = (/obj/structure/flora/tree/pine{icon_state = "pine_2"},/turf/simulated/floor/holofloor/snow,/area/awaymission/zoo) "tz" = (/obj/structure/flora/tree/pine{icon_state = "pine_3"},/turf/simulated/floor/holofloor/snow,/area/awaymission/zoo) -"tA" = (/mob/living/simple_animal/hostile/creature/vore{faction = "zoo"; name = "redspace abomination"},/turf/simulated/floor/cult,/area/awaymission/zoo) +"tA" = (/mob/living/simple_mob/hostile/creature/vore{faction = "zoo"; name = "redspace abomination"},/turf/simulated/floor/cult,/area/awaymission/zoo) "tB" = (/obj/structure/flora/ausbushes/fullgrass,/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) "tC" = (/obj/structure/flora/ausbushes/leafybush,/turf/simulated/floor/holofloor/wood{icon = 'icons/turf/floors.dmi'; icon_state = "diona"},/area/awaymission/zoo) "tD" = (/obj/effect/decal/remains/human,/turf/simulated/floor/cult,/area/awaymission/zoo) @@ -1020,39 +1020,39 @@ "tF" = (/obj/structure/flora/ausbushes/grassybush,/turf/simulated/floor/holofloor/wood{icon = 'icons/turf/floors.dmi'; icon_state = "diona"},/area/awaymission/zoo) "tG" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/sign/kiddieplaque{desc = "Decades ago, a group of rogue Skrellian scientists began illegal experimentation on Unathi colonists participating in a nuclear meltdown cleanup effort. In an attempt to create genetically engineered super soldiers, the Deathclaw was born with deadly sharp razor-like claws, incredible agility, robust durability, and high intelligence. When the Skrellian scientists were arrested by the authorities, the Deathclaw was to be destroyed, but some managed to escape captivity into the nuclear wasteland. Normally solitary creatures, they have been known to hunt in packs, and seem to have a preference for Human and Unathi meat."; name = "Deathclaw Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) "tH" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/sign/kiddieplaque{desc = "The Space Goose (pural: geese) is an aquatic fowl originating from the planet Earth. This breed of Geese however was bred to the clime of space ships and stations as guard animals. They are extremely loud, highly aggressive, and territorial, while their talons and beaks are much longer and sharper than Earth geese. Their aggressive nature makes them difficult to train, but are highly effective when deployed."; name = "Space Goose Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) -"tI" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/sign/kiddieplaque{desc = "The Grey Wolf, Scientific name Canis Lupus, is a species native to the Sol system and specifically the planet Earth. It is the largest extant member of its family, with males averaging 43–45 kg (95–99 lb), and females 36–38.5 kg (79–85 lb). Like the red wolf, it is distinguished from other Canis species by its larger size and less pointed features, particularly on the ears and muzzle. Its winter fur is long and bushy, and predominantly a mottled gray in color, although nearly pure white, red, or brown to black also occur. It is also know by the name Timber Wolf. The gray wolf is the second most specialised member of the genus Canis, as demonstrated by its morphological adaptations to hunting large prey, its more gregarious nature, and its highly advanced expressive behavior. It is nonetheless closely related enough to smaller Canis species, such as the Sol Coyote or Golden Jackal to produce fertile hybrids. It is the only species of Canis to have a range encompassing both the Old and New planets, due to being popular as a traveling companion, an easier to tame circus attraction compared to tigers, and its valuable use in ridding polar worlds of large predators. It was also spread through some worlds to deal with Cloud Fox infestations. While normally indifferent to foxes aside from hunting territories, the Grey Wolf has shown great hostility to a special strain of Fox mutation found on the planet Andorss called the Cloud Fox. Bafflingly, these creatures share nothing in common that should lead them to be enemies, as the Grey Wolf is a predator and lives in snowy areas, whereas the Cloud Fox is an herbivore, largely found in Corn rich areas. Scientists have yet to explain this, although several other animals have also been shown to show hostility towards Cloud Foxes, namely the Macromeleon and Carousel Panther, both of whom get along well with Grey Wolves."; name = "Gray Wolf Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) +"tI" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/sign/kiddieplaque{desc = "The Grey Wolf, Scientific name Canis Lupus, is a species native to the Sol system and specifically the planet Earth. It is the largest extant member of its family, with males averaging 43�45 kg (95�99 lb), and females 36�38.5 kg (79�85 lb). Like the red wolf, it is distinguished from other Canis species by its larger size and less pointed features, particularly on the ears and muzzle. Its winter fur is long and bushy, and predominantly a mottled gray in color, although nearly pure white, red, or brown to black also occur. It is also know by the name Timber Wolf. The gray wolf is the second most specialised member of the genus Canis, as demonstrated by its morphological adaptations to hunting large prey, its more gregarious nature, and its highly advanced expressive behavior. It is nonetheless closely related enough to smaller Canis species, such as the Sol Coyote or Golden Jackal to produce fertile hybrids. It is the only species of Canis to have a range encompassing both the Old and New planets, due to being popular as a traveling companion, an easier to tame circus attraction compared to tigers, and its valuable use in ridding polar worlds of large predators. It was also spread through some worlds to deal with Cloud Fox infestations. While normally indifferent to foxes aside from hunting territories, the Grey Wolf has shown great hostility to a special strain of Fox mutation found on the planet Andorss called the Cloud Fox. Bafflingly, these creatures share nothing in common that should lead them to be enemies, as the Grey Wolf is a predator and lives in snowy areas, whereas the Cloud Fox is an herbivore, largely found in Corn rich areas. Scientists have yet to explain this, although several other animals have also been shown to show hostility towards Cloud Foxes, namely the Macromeleon and Carousel Panther, both of whom get along well with Grey Wolves."; name = "Gray Wolf Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) "tJ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/sign/kiddieplaque{desc = "While all the species of these large predators are commonly known as Dragons (Draconius Regalis), this is mainly an umbrella term for a number of varieties of these large, reptilian creatures. There are numerous varieties of dragons found throughout the galaxy, and recounts of these creatures can be traced back to Skrell civilization's first interplanetary travels speaking of a large, unknown creature attacking and devouring the closeby cargo ships. Mainly solitary creatures, the Dragons roam large areas of space, capable of adapting to a large variety of atmospheres thanks to each sub-species natural affinity to various elements. While in today's population there are a numerous subspecies, all of these can be traced back to what archaeologists claimed to be a 'phoron' Dragon, by the biological analysis of the fossils found on asteroids in the Virgo-Erigone system. The creatures displayed here were reconstituted from such fossils, generously donated by the Virgo Orbital Research Establishment."; name = "Phoron Dragon Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) "tK" = (/obj/structure/flora/ausbushes/sparsegrass,/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) "tL" = (/obj/effect/floor_decal/asteroid,/obj/effect/decal/cleanable/greenglow,/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) "tM" = (/obj/effect/gibspawner/human,/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) "tN" = (/obj/machinery/portable_atmospherics/hydroponics/soil,/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) -"tO" = (/obj/effect/floor_decal/asteroid,/mob/living/simple_animal/hostile/dino{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) +"tO" = (/obj/effect/floor_decal/asteroid,/mob/living/simple_mob/hostile/dino{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) "tP" = (/obj/effect/decal/cleanable/greenglow,/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) "tQ" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/sign/kiddieplaque{desc = "Decades ago, a group of rogue Skrellian scientists began illegal experimentation on Unathi colonists participating in a nuclear meltdown cleanup effort. In an attempt to create genetically engineered super soldiers, the Deathclaw was born with deadly sharp razor-like claws, incredible agility, robust durability, and high intelligence. When the Skrellian scientists were arrested by the authorities, the Deathclaw was to be destroyed, but some managed to escape captivity into the nuclear wasteland. Normally solitary creatures, they have been known to hunt in packs, and seem to have a preference for Human and Unathi meat."; name = "Deathclaw Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) "tR" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/sign/kiddieplaque{desc = "The Space Goose (pural: geese) is an aquatic fowl originating from the planet Earth. This breed of Geese however was bred to the clime of space ships and stations as guard animals. They are extremely loud, highly aggressive, and territorial, while their talons and beaks are much longer and sharper than Earth geese. Their aggressive nature makes them difficult to train, but are highly effective when deployed."; name = "Space Goose Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) -"tS" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/sign/kiddieplaque{desc = "The Grey Wolf, Scientific name Canis Lupus, is a species native to the Sol system and specifically the planet Earth. It is the largest extant member of its family, with males averaging 43–45 kg (95–99 lb), and females 36–38.5 kg (79–85 lb). Like the red wolf, it is distinguished from other Canis species by its larger size and less pointed features, particularly on the ears and muzzle. Its winter fur is long and bushy, and predominantly a mottled gray in color, although nearly pure white, red, or brown to black also occur. It is also know by the name Timber Wolf. The gray wolf is the second most specialised member of the genus Canis, as demonstrated by its morphological adaptations to hunting large prey, its more gregarious nature, and its highly advanced expressive behavior. It is nonetheless closely related enough to smaller Canis species, such as the Sol Coyote or Golden Jackal to produce fertile hybrids. It is the only species of Canis to have a range encompassing both the Old and New planets, due to being popular as a traveling companion, an easier to tame circus attraction compared to tigers, and its valuable use in ridding polar worlds of large predators. It was also spread through some worlds to deal with Cloud Fox infestations. While normally indifferent to foxes aside from hunting territories, the Grey Wolf has shown great hostility to a special strain of Fox mutation found on the planet Andorss called the Cloud Fox. Bafflingly, these creatures share nothing in common that should lead them to be enemies, as the Grey Wolf is a predator and lives in snowy areas, whereas the Cloud Fox is an herbivore, largely found in Corn rich areas. Scientists have yet to explain this, although several other animals have also been shown to show hostility towards Cloud Foxes, namely the Macromeleon and Carousel Panther, both of whom get along well with Grey Wolves."; name = "Gray Wolf Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) +"tS" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/sign/kiddieplaque{desc = "The Grey Wolf, Scientific name Canis Lupus, is a species native to the Sol system and specifically the planet Earth. It is the largest extant member of its family, with males averaging 43�45 kg (95�99 lb), and females 36�38.5 kg (79�85 lb). Like the red wolf, it is distinguished from other Canis species by its larger size and less pointed features, particularly on the ears and muzzle. Its winter fur is long and bushy, and predominantly a mottled gray in color, although nearly pure white, red, or brown to black also occur. It is also know by the name Timber Wolf. The gray wolf is the second most specialised member of the genus Canis, as demonstrated by its morphological adaptations to hunting large prey, its more gregarious nature, and its highly advanced expressive behavior. It is nonetheless closely related enough to smaller Canis species, such as the Sol Coyote or Golden Jackal to produce fertile hybrids. It is the only species of Canis to have a range encompassing both the Old and New planets, due to being popular as a traveling companion, an easier to tame circus attraction compared to tigers, and its valuable use in ridding polar worlds of large predators. It was also spread through some worlds to deal with Cloud Fox infestations. While normally indifferent to foxes aside from hunting territories, the Grey Wolf has shown great hostility to a special strain of Fox mutation found on the planet Andorss called the Cloud Fox. Bafflingly, these creatures share nothing in common that should lead them to be enemies, as the Grey Wolf is a predator and lives in snowy areas, whereas the Cloud Fox is an herbivore, largely found in Corn rich areas. Scientists have yet to explain this, although several other animals have also been shown to show hostility towards Cloud Foxes, namely the Macromeleon and Carousel Panther, both of whom get along well with Grey Wolves."; name = "Gray Wolf Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) "tT" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/sign/kiddieplaque{desc = "While all the species of these large predators are commonly known as Dragons (Draconius Regalis), this is mainly an umbrella term for a number of varieties of these large, reptilian creatures. There are numerous varieties of dragons found throughout the galaxy, and recounts of these creatures can be traced back to Skrell civilization's first interplanetary travels speaking of a large, unknown creature attacking and devouring the closeby cargo ships. Mainly solitary creatures, the Dragons roam large areas of space, capable of adapting to a large variety of atmospheres thanks to each sub-species natural affinity to various elements. While in today's population there are a numerous subspecies, all of these can be traced back to what archaeologists claimed to be a 'phoron' Dragon, by the biological analysis of the fossils found on asteroids in the Virgo-Erigone system. The creatures displayed here were reconstituted from such fossils, generously donated by the Virgo Orbital Research Establishment."; name = "Phoron Dragon Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) "tU" = (/obj/effect/decal/remains/human,/turf/simulated/floor/holofloor/desert{icon = 'icons/turf/floors.dmi'; icon_state = "asteroidplating"; name = "scorched sand"},/area/awaymission/zoo) -"tV" = (/mob/living/simple_animal/adultslime{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) +"tV" = (/mob/living/simple_mob/adultslime{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) "tW" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) -"tX" = (/mob/living/simple_animal/hostile/dragon{faction = "zoo"},/turf/simulated/floor/holofloor/desert{icon = 'icons/turf/floors.dmi'; icon_state = "asteroidplating"; name = "scorched sand"},/area/awaymission/zoo) -"tY" = (/mob/living/simple_animal/lizard{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) -"tZ" = (/mob/living/simple_animal/hostile/tomato{faction = "zoo"},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) -"ua" = (/mob/living/simple_animal/fox{faction = "zoo"},/turf/simulated/floor/holofloor/snow,/area/awaymission/zoo) +"tX" = (/mob/living/simple_mob/hostile/dragon{faction = "zoo"},/turf/simulated/floor/holofloor/desert{icon = 'icons/turf/floors.dmi'; icon_state = "asteroidplating"; name = "scorched sand"},/area/awaymission/zoo) +"tY" = (/mob/living/simple_mob/lizard{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) +"tZ" = (/mob/living/simple_mob/hostile/tomato{faction = "zoo"},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) +"ua" = (/mob/living/simple_mob/fox{faction = "zoo"},/turf/simulated/floor/holofloor/snow,/area/awaymission/zoo) "ub" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/sign/kiddieplaque{desc = "The Voracious Lizard is a relatively new species, muted from the common space lizard by exposure to Phoron. These creatures are found commonly in and around facilities where phoron is mined, refined, or stored. They have been known to attack other creatures in groups, and are able to unhinge their jaws to swallow Human-sized prey whole. The species was first discovered in the Virgo-Erigone system, and have since become a dangerous pest."; name = "Voracious Lizard Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) -"uc" = (/obj/effect/floor_decal/asteroid,/mob/living/simple_animal/hostile/deathclaw{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) +"uc" = (/obj/effect/floor_decal/asteroid,/mob/living/simple_mob/hostile/deathclaw{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) "ud" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/sign/kiddieplaque{desc = "Common Space Lizard (Pordacis Stellae Vulgaris) is a common critter amongst space stations. Their origin traces back to genetically modified wall lizards to survive the hazardous conditions of space, this hardy animal is surprisingly tough and able to rapidly regenerate dead cells from radiation exposure and is virtually immune against cancerous growths. Its diet is varied, as it eats what it gets, from discarded junk food to mice and small spiders."; name = "Lizard Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) -"ue" = (/mob/living/simple_animal/hostile/goose{faction = "zoo"},/turf/simulated/floor/beach/water,/area/awaymission/zoo) +"ue" = (/mob/living/simple_mob/hostile/goose{faction = "zoo"},/turf/simulated/floor/beach/water,/area/awaymission/zoo) "uf" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/sign/kiddieplaque{desc = "Originally a cult movie monster, a team of geneticists eventually turned the Animate Tomato from fiction to reality. While not harmful in any way, some people consider its grin to be disturbing. It reproduces in the same manner as plants, coming off of the vine when harvested or when it gets ripe enough, afterwards wandering about on its own."; name = "Animate Tomato Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) "ug" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/sign/kiddieplaque{desc = "Foxes are small-to-medium-sized, omnivorous mammals belonging to several genera of the family Canidae. Foxes are slightly smaller than a medium-size domestic dog, with a flattened skull, upright triangular ears, a pointed, slightly upturned snout, and a long bushy tail (or brush). These foxes are Red Foxes, largest of the true foxes, has the greatest geographic range of all members of the Carnivora family, originally spanning across the entire Northern Hemisphere of Earth from the Arctic Circle to North Africa, North America and Eurasia, and has grown to be found on many forest and garden planets across the galaxy."; name = "Fox Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) "uh" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/sign/kiddieplaque{desc = "A mouse (plural: mice), native to Earth in the Sol system, is a small rodent characteristically having a pointed snout, small rounded ears, a body-length scaly tail and a high breeding rate. The best known mouse species is the common house mouse (Mus musculus). It is also a popular pet. In some places, certain kinds of field mice are locally common. They are known to invade homes and space ships for food and shelter. Cats, wild dogs, foxes, birds of prey, snakes and even certain kinds of arthropods have been known to prey heavily upon mice. Nevertheless, because of its remarkable adaptability to almost any environment, the mouse is one of the most successful mammalian genera living in the galaxy today."; name = "Slime Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) -"ui" = (/mob/living/simple_animal/hostile/deathclaw{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) -"uj" = (/mob/living/simple_animal/slime{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) -"uk" = (/obj/structure/flora/ausbushes/sparsegrass,/mob/living/simple_animal/hostile/dino{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) -"ul" = (/obj/effect/floor_decal/asteroid,/mob/living/simple_animal/lizard{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) -"um" = (/obj/effect/landmark/away,/mob/living/simple_animal/hostile/goose{faction = "zoo"},/turf/simulated/floor/wood,/area/awaymission/zoo) -"un" = (/mob/living/simple_animal/hostile/wolf{faction = "zoo"},/turf/simulated/floor/holofloor/snow,/area/awaymission/zoo) -"uo" = (/mob/living/simple_animal/hostile/goose{faction = "zoo"},/turf/simulated/floor/wood,/area/awaymission/zoo) +"ui" = (/mob/living/simple_mob/hostile/deathclaw{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) +"uj" = (/mob/living/simple_mob/slime{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) +"uk" = (/obj/structure/flora/ausbushes/sparsegrass,/mob/living/simple_mob/hostile/dino{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) +"ul" = (/obj/effect/floor_decal/asteroid,/mob/living/simple_mob/lizard{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) +"um" = (/obj/effect/landmark/away,/mob/living/simple_mob/hostile/goose{faction = "zoo"},/turf/simulated/floor/wood,/area/awaymission/zoo) +"un" = (/mob/living/simple_mob/hostile/wolf{faction = "zoo"},/turf/simulated/floor/holofloor/snow,/area/awaymission/zoo) +"uo" = (/mob/living/simple_mob/hostile/goose{faction = "zoo"},/turf/simulated/floor/wood,/area/awaymission/zoo) "up" = (/obj/structure/symbol/sa,/turf/simulated/wall,/area/awaymission/zoo) "uq" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/sign/kiddieplaque{desc = "Saru (also incorrectly known as Sergalings) are the smaller, unevolved, far more docile cousins of the Sergals, and are usually thought of as either pests, food, or pets. They are a commodity that the Sergal use in their trades with other species due to their cute appearance and quick breeding. Contrary to popular belief, they are not sergal pups, despite their similar appearance. Note the distinctly stubbier noses, compared to true sergal pups. Unfortunately, the mistake has been made more than once, even by other sergals, wherein actual young sergals have been mistakenly sold to traders with tragic consequences... for the traders. The Saru are, like the Sergals, native to the planet Eltus, in the Vilous system. However, they are also found on the planet Tal in the same system."; name = "Saru Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) "ur" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/sign/kiddieplaque{desc = "The brown bear (Ursus arctos) is a large bear with the widest distribution of any living ursid. The species is distributed across much of northern Eurasia and North America, on planet Earth. It is one of the two largest terrestrial carnivorans alive today, rivaled in body size only by its close cousin, the polar bear (Ursus maritimus), which is much less variable in size and averages larger due to this. There are several recognized subspecies, many of which are quite well-known within their native ranges, found in the brown bear species."; name = "Brown Bear Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) @@ -1064,12 +1064,12 @@ "ux" = (/obj/structure/sink/puddle,/turf/simulated/floor/holofloor/beach/sand{icon_state = "fullgrass0"},/area/awaymission/zoo) "uy" = (/obj/effect/floor_decal/asteroid,/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass2"},/area/awaymission/zoo) "uz" = (/obj/effect/floor_decal/asteroid,/mob/living/carbon/human/sergallingm{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass2"},/area/awaymission/zoo) -"uA" = (/mob/living/simple_animal/hostile/bear/brown{faction = "zoo"},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) +"uA" = (/mob/living/simple_mob/hostile/bear/brown{faction = "zoo"},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) "uB" = (/obj/effect/floor_decal/asteroid,/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass1"},/area/awaymission/zoo) "uC" = (/mob/living/carbon/human/sergallingm{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass4"},/area/awaymission/zoo) "uD" = (/obj/effect/floor_decal/asteroid,/turf/simulated/floor/holofloor/beach/sand{icon_state = "fullgrass3"},/area/awaymission/zoo) "uE" = (/obj/effect/floor_decal/asteroid,/turf/simulated/floor/holofloor/beach/sand{icon_state = "fullgrass1"},/area/awaymission/zoo) -"uF" = (/mob/living/simple_animal/corgi/tamaskan{faction = "zoo"},/turf/simulated/floor/holofloor/snow,/area/awaymission/zoo) +"uF" = (/mob/living/simple_mob/corgi/tamaskan{faction = "zoo"},/turf/simulated/floor/holofloor/snow,/area/awaymission/zoo) "uG" = (/obj/item/stack/tile/grass,/turf/simulated/floor/plating,/area/awaymission/zoo) "uH" = (/obj/item/stack/tile/grass,/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) "uI" = (/obj/effect/floor_decal/asteroid,/turf/simulated/floor/holofloor/beach/sand{icon_state = "fullgrass0"},/area/awaymission/zoo) @@ -1077,7 +1077,7 @@ "uK" = (/obj/effect/floor_decal/asteroid,/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass3"},/area/awaymission/zoo) "uL" = (/mob/living/carbon/human/sergallingm{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "fullgrass1"},/area/awaymission/zoo) "uM" = (/mob/living/carbon/human/sergallingm{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass2"},/area/awaymission/zoo) -"uN" = (/obj/structure/flora/ausbushes/genericbush,/mob/living/simple_animal/hostile/bear/brown{faction = "zoo"},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) +"uN" = (/obj/structure/flora/ausbushes/genericbush,/mob/living/simple_mob/hostile/bear/brown{faction = "zoo"},/turf/simulated/floor/holofloor/grass,/area/awaymission/zoo) "uO" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/sign/kiddieplaque{desc = "The Sol-system native Panther, found primarily on the Sol-system planet Earth, is a large mammal belonging to the Felidae family. Found in a variety of environment, like most big cats the Panther inhabits a large number of habitats and is a carnivorous, nocturnal predator. Of particular note are the various patterns of their fur - the most known one, especially thanks to Sol popular culture (books, sequential art and movies) is the black panther, a species that displays a fur pattern completely black at a first glance, but other species can display a much wider variety of patterns, another one of the most common being a beige color with large, black spots. These patterns were mainly evolved as a mean to conceal itself in the surrounding environment, to ambush an unsuspecting prey."; name = "Panther Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) "uP" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/sign/kiddieplaque{desc = "Shantak are a pack-hunting carnivore native to Meralar. Using loud barks and growls, similar to that of wolves, the shantak is able to communicate verbally with its hunting partners in order to coordinate attacks. The largest female of the group is usually in charge, and is considered to be the alpha of the pack."; name = "Shantak Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) "uQ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/sign/kiddieplaque{desc = "Space Pike are a larger, more territorial cousin of the famous Space Carp whose origins can also be traced to the Erebus system. Like the Space Carp, their DNA is infused with Phoron. However, the Space Pike were hunted nearly to extinction for their vibrant purple scales. They were declared a critically endangered species in 2556, but that status has been lifted recently due to a substantial bounce back in numbers. They are now only considered a vulnerable species. Space Pike feed on space slugs, space worms, sometimes space carp, and the occasional space man. The space bear is considered its mortal enemy."; name = "Space Pike Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) @@ -1089,25 +1089,25 @@ "uW" = (/turf/simulated/floor/holofloor/beach/water{icon_state = "beach"; dir = 8},/area/awaymission/zoo) "uX" = (/obj/effect/overlay/palmtree_l,/obj/effect/overlay/coconut,/turf/simulated/floor/holofloor/beach/sand,/area/awaymission/zoo) "uY" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/sign/kiddieplaque{desc = "Shantak are a pack-hunting carnivore native to Meralar. Using loud barks and growls, similar to that of wolves, the shantak is able to communicate verbally with its hunting partners in order to coordinate attacks. The largest female of the group is usually in charge, and is considered to be the alpha of the pack."; name = "Shantak Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) -"uZ" = (/mob/living/simple_animal/hostile/carp/pike{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) +"uZ" = (/mob/living/simple_mob/hostile/carp/pike{faction = "zoo"},/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) "va" = (/obj/structure/flora/ausbushes/fernybush,/mob/living/carbon/human/monkey{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "fullgrass1"},/area/awaymission/zoo) "vb" = (/obj/effect/overlay/coconut,/turf/simulated/floor/holofloor/grass{icon = 'icons/jungle.dmi'; icon_state = "grass2"},/area/awaymission/zoo) "vc" = (/obj/structure/flora/ausbushes/sunnybush,/turf/simulated/floor/holofloor/grass{icon = 'icons/jungle.dmi'; icon_state = "grass2"},/area/awaymission/zoo) -"vd" = (/mob/living/simple_animal/crab{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand,/area/awaymission/zoo) +"vd" = (/mob/living/simple_mob/crab{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand,/area/awaymission/zoo) "ve" = (/mob/living/carbon/human/monkey{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "fullgrass3"},/area/awaymission/zoo) -"vf" = (/mob/living/simple_animal/hostile/panther{faction = "zoo"},/turf/simulated/floor/holofloor/grass{icon = 'icons/jungle.dmi'; icon_state = "grass2"},/area/awaymission/zoo) +"vf" = (/mob/living/simple_mob/hostile/panther{faction = "zoo"},/turf/simulated/floor/holofloor/grass{icon = 'icons/jungle.dmi'; icon_state = "grass2"},/area/awaymission/zoo) "vg" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/sign/kiddieplaque{desc = "A species incredibly similar to Humans. The monkey is a resident of Earth, the home planet of Humanity, and shares many traits with Humans, such as opposable thumbs, and a love of flinging fecal matter at each other. Monkeys are valued for their dancing ability, and thanks to the recent boom of monkey dance classes, the dancing monkey industry is growing. Monkeys are also commonly used in scientific research that requires testing on products meant to be used by Humans. In fact, some of the first creatures to leave Earth's atmosphere in the infancy of Humanity's space age were dogs and monkeys!"; name = "Monkey Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) "vh" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/sign/kiddieplaque{desc = "Crabs are decapod crustaceans of the infraorder Brachyura, which live in all the oceans on the planet Earth, in some fresh water, and even a few species which thrive on land. They are generally covered with a thick exoskeleton and have a single pair of claws. They are often kept as pets or eaten for food by Humans. Many other animals with similar names, such as king crabs, hermit crabs, porcelain crabs, horseshoe crabs, and crab lice, are not true crabs."; name = "Crab Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) "vi" = (/obj/effect/landmark/away,/turf/simulated/floor/holofloor/desert,/area/awaymission/zoo) "vj" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/sign/kiddieplaque{desc = "This is not an empty exhibit. Note the pine tree in the center of the pen. This is the infamous Killer Pine Tree. Thought to be a relative of the mimic, the Killer Tree is, much like its cousins, an ambush predator. However, like the mimic, it is not known where this species is from, how it reproduces, or how it has found its way across the galaxy into new biomes."; name = "Killer Tree Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) "vk" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/sign/kiddieplaque{desc = "Space Pike are a larger, more territorial cousin of the famous Space Carp whose origins can also be traced to the Erebus system. Like the Space Carp, their DNA is infused with Phoron. However, the Space Pike were hunted nearly to extinction for their vibrant purple scales. They were declared a critically endangered species in 2556, but that status has been lifted recently due to a substantial bounce back in numbers. They are now only considered a vulnerable species. Space Pike feed on space slugs, space worms, sometimes space carp, and the occasional space man. The space bear is considered its mortal enemy."; name = "Space Pike Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) -"vl" = (/mob/living/simple_animal/crab{faction = "zoo"; icon_dead = "evilcrab_dead"; icon_living = "evilcrab"; icon_state = "evilcrab"},/turf/simulated/floor/holofloor/beach/water,/area/awaymission/zoo) +"vl" = (/mob/living/simple_mob/crab{faction = "zoo"; icon_dead = "evilcrab_dead"; icon_living = "evilcrab"; icon_state = "evilcrab"},/turf/simulated/floor/holofloor/beach/water,/area/awaymission/zoo) "vm" = (/obj/item/stack/tile/grass,/obj/item/stack/tile/grass,/obj/item/stack/tile/grass,/obj/item/stack/tile/grass,/turf/simulated/floor/plating,/area/awaymission/zoo) -"vn" = (/mob/living/simple_animal/hostile/shantak{faction = "zoo"},/turf/simulated/floor/holofloor/snow,/area/awaymission/zoo) +"vn" = (/mob/living/simple_mob/hostile/shantak{faction = "zoo"},/turf/simulated/floor/holofloor/snow,/area/awaymission/zoo) "vo" = (/mob/living/carbon/human/monkey{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass2"},/area/awaymission/zoo) -"vp" = (/mob/living/simple_animal/hostile/shantak{color = ""; faction = "zoo"; health = 100; maxHealth = 100; name = "alpha shantak"},/turf/simulated/floor/holofloor/snow,/area/awaymission/zoo) -"vq" = (/mob/living/simple_animal/hostile/tree{faction = "zoo"},/turf/simulated/floor/holofloor/snow,/area/awaymission/zoo) -"vr" = (/obj/structure/flora/bush,/mob/living/simple_animal/hostile/shantak{faction = "zoo"},/turf/simulated/floor/holofloor/snow,/area/awaymission/zoo) +"vp" = (/mob/living/simple_mob/hostile/shantak{color = ""; faction = "zoo"; health = 100; maxHealth = 100; name = "alpha shantak"},/turf/simulated/floor/holofloor/snow,/area/awaymission/zoo) +"vq" = (/mob/living/simple_mob/hostile/tree{faction = "zoo"},/turf/simulated/floor/holofloor/snow,/area/awaymission/zoo) +"vr" = (/obj/structure/flora/bush,/mob/living/simple_mob/hostile/shantak{faction = "zoo"},/turf/simulated/floor/holofloor/snow,/area/awaymission/zoo) "vs" = (/mob/living/carbon/human/monkey{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "dgrass0"},/area/awaymission/zoo) "vt" = (/obj/structure/flora/ausbushes/lavendergrass,/mob/living/carbon/human/monkey{faction = "zoo"},/turf/simulated/floor/holofloor/beach/sand{icon_state = "fullgrass1"},/area/awaymission/zoo) "vu" = (/obj/item/stack/tile/grass,/obj/item/stack/tile/grass,/obj/item/stack/tile/grass,/turf/simulated/floor/plating,/area/awaymission/zoo) @@ -1115,7 +1115,7 @@ "vw" = (/obj/effect/landmark/loot_spawn,/turf/simulated/floor/plating,/area/awaymission/zoo) "vx" = (/obj/item/stack/tile/grass/fifty,/turf/simulated/floor/plating,/area/awaymission/zoo) "vy" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/sign/kiddieplaque{desc = "The polar bear (Ursus maritimus) is a carnivorous bear whose native range once lay largely within the Arctic Circle on Earth, encompassing the Arctic Ocean, its surrounding seas, and surrounding land masses. Although it is the sister species of the brown bear, it has evolved to occupy a narrower ecological niche, with many body characteristics adapted for cold temperatures, for moving across snow, ice, and open water, and for hunting seals, which made up most of its original diet. Although most polar bears are born on land, they spent most of their time on the sea ice. Their scientific name means 'maritime bear', and derives from this fact. Polar bears hunted their preferred food of seals from the edge of sea ice, often living off fat reserves when no sea ice is present. Because of their dependence on the sea ice, polar bears are classified as marine mammals. However, because of habitat loss caused by climate change, the polar bear had gone completely extinct on Earth. The return of the polar bear is thanks to the preservation of genetic records written in the 21st century, which were later used by Space Russians to create a wildlife reserve on the planet Europa in 2492. This has generally been regarded as a poor decision."; name = "Polar Bear Exhibit"},/turf/simulated/floor/plating,/area/awaymission/zoo) -"vz" = (/mob/living/simple_animal/hostile/bear/polar{faction = "zoo"},/turf/simulated/floor/beach/water,/area/awaymission/zoo) +"vz" = (/mob/living/simple_mob/hostile/bear/polar{faction = "zoo"},/turf/simulated/floor/beach/water,/area/awaymission/zoo) "vA" = (/obj/effect/landmark/away,/turf/simulated/floor/grass,/area/awaymission/zoo) "vB" = (/obj/effect/blocker,/turf/simulated/wall/r_wall,/area/awaymission/zoo) "vC" = (/obj/effect/blocker,/obj/structure/sign/securearea,/turf/simulated/wall/r_wall,/area/awaymission/zoo) @@ -1184,7 +1184,7 @@ "wN" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/floodlight,/obj/effect/floor_decal/industrial/outline/yellow,/turf/simulated/floor,/area/awaymission/zoo) "wO" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/power/emitter,/obj/effect/floor_decal/industrial/outline/yellow,/turf/simulated/floor,/area/awaymission/zoo) "wP" = (/obj/machinery/power/port_gen/pacman{anchored = 1},/obj/effect/floor_decal/industrial/outline/yellow,/turf/simulated/floor/plating,/area/awaymission/zoo) -"wQ" = (/obj/effect/floor_decal/industrial/outline/yellow,/obj/item/clothing/under/rank/engineer/skirt,/mob/living/simple_animal/hostile/mimic/crate,/turf/simulated/floor/plating,/area/awaymission/zoo) +"wQ" = (/obj/effect/floor_decal/industrial/outline/yellow,/obj/item/clothing/under/rank/engineer/skirt,/mob/living/simple_mob/hostile/mimic/crate,/turf/simulated/floor/plating,/area/awaymission/zoo) "wR" = (/obj/machinery/portable_atmospherics/canister/nitrogen,/obj/effect/floor_decal/industrial/outline/yellow,/turf/simulated/floor,/area/awaymission/zoo) "wS" = (/obj/effect/floor_decal/industrial/outline/yellow,/turf/simulated/floor/plating,/area/awaymission/zoo) "wT" = (/obj/effect/floor_decal/industrial/outline/yellow,/obj/effect/landmark/loot_spawn,/obj/structure/symbol/da{pixel_x = -32},/turf/simulated/floor/plating,/area/awaymission/zoo) diff --git a/maps/northern_star/polaris-1.dmm b/maps/northern_star/polaris-1.dmm index 1021cbbcaa..8643d1d88d 100644 --- a/maps/northern_star/polaris-1.dmm +++ b/maps/northern_star/polaris-1.dmm @@ -131,7 +131,7 @@ "acA" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/maintenance/library) "acB" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor,/area/maintenance/locker) "acC" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/maintenance/library) -"acD" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/mob/living/simple_animal/mouse,/turf/simulated/floor,/area/maintenance/library) +"acD" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/mob/living/simple_mob/animal/passive/mouse,/turf/simulated/floor,/area/maintenance/library) "acE" = (/obj/structure/table/woodentable,/obj/machinery/recharger{pixel_y = 0},/obj/machinery/ai_status_display{pixel_x = 0; pixel_y = 32},/turf/simulated/floor/wood,/area/library_conference_room) "acF" = (/obj/machinery/light{dir = 1},/turf/simulated/floor/wood,/area/library_conference_room) "acG" = (/turf/simulated/floor/wood,/area/library_conference_room) @@ -206,7 +206,7 @@ "adX" = (/obj/machinery/atmospherics/pipe/tank/air,/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 8},/turf/simulated/floor,/area/maintenance/library) "adY" = (/obj/machinery/atmospherics/pipe/tank/air,/obj/effect/floor_decal/industrial/warning/corner,/turf/simulated/floor,/area/maintenance/library) "adZ" = (/obj/effect/floor_decal/industrial/warning{dir = 1},/turf/simulated/floor/tiled,/area/hallway/secondary/civilian_hallway_fore) -"aea" = (/obj/effect/decal/cleanable/generic,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/mob/living/simple_animal/mouse,/turf/simulated/floor/plating,/area/maintenance/locker) +"aea" = (/obj/effect/decal/cleanable/generic,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/mob/living/simple_mob/animal/passive/mouse,/turf/simulated/floor/plating,/area/maintenance/locker) "aeb" = (/obj/machinery/camera/network/civilian{c_tag = "CIV - Chapel Morgue"; dir = 4},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor/tiled/dark,/area/chapel/chapel_morgue) "aec" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/tiled/dark,/area/chapel/chapel_morgue) "aed" = (/obj/machinery/door/window{dir = 8; name = "Mass Driver"; req_access = list(22)},/obj/machinery/mass_driver{dir = 4; id = "chapelgun"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/obj/machinery/airlock_sensor{pixel_y = 25},/obj/effect/floor_decal/industrial/warning{dir = 8},/turf/simulated/floor/plating,/area/chapel/chapel_morgue) @@ -305,7 +305,7 @@ "afS" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/maintenance/locker) "afT" = (/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/turf/simulated/floor/tiled/dark,/area/chapel/chapel_morgue) "afU" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/tiled/dark,/area/chapel/chapel_morgue) -"afV" = (/obj/structure/bed/chair{dir = 4},/mob/living/simple_animal/mouse,/turf/simulated/floor/tiled/dark,/area/chapel/chapel_morgue) +"afV" = (/obj/structure/bed/chair{dir = 4},/mob/living/simple_mob/animal/passive/mouse,/turf/simulated/floor/tiled/dark,/area/chapel/chapel_morgue) "afW" = (/obj/structure/table/standard,/turf/simulated/floor/tiled/dark,/area/chapel/chapel_morgue) "afX" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/chapel/chapel_morgue) "afY" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/security/detectives_office) @@ -1004,7 +1004,7 @@ "atp" = (/obj/machinery/atmospherics/valve{dir = 4},/obj/machinery/alarm{pixel_y = 22},/turf/simulated/floor,/area/security/riot_control) "atq" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/obj/effect/floor_decal/industrial/warning{dir = 5},/turf/simulated/floor,/area/security/riot_control) "atr" = (/turf/simulated/wall/r_wall,/area/security/riot_control) -"ats" = (/obj/effect/decal/cleanable/dirt,/mob/living/simple_animal/mouse,/turf/simulated/floor/plating,/area/maintenance/security_starboard) +"ats" = (/obj/effect/decal/cleanable/dirt,/mob/living/simple_mob/animal/passive/mouse,/turf/simulated/floor/plating,/area/maintenance/security_starboard) "att" = (/obj/machinery/light/small{dir = 1},/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor,/area/maintenance/security_starboard) "atu" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor,/area/maintenance/security_starboard) "atv" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/maintenance{req_access = list(12)},/turf/simulated/floor,/area/maintenance/security_starboard) @@ -2752,7 +2752,7 @@ "baV" = (/obj/structure/closet/crate,/obj/item/clothing/shoes/boots/combat,/obj/item/weapon/tank/air,/obj/item/weapon/tank/air,/obj/item/weapon/tank/air,/obj/item/clothing/mask/gas,/obj/effect/decal/cleanable/dirt,/obj/random/maintenance/cargo,/obj/random/maintenance/medical,/turf/simulated/floor/plating,/area/mine/unexplored/upper_level) "baW" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/engineering{name = "Pump Station"; req_one_access = list(11,24)},/turf/simulated/floor,/area/maintenance/medbay_fore) "baX" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/maintenance/research_shuttle) -"baY" = (/mob/living/simple_animal/mouse,/turf/simulated/floor,/area/maintenance/research_shuttle) +"baY" = (/mob/living/simple_mob/animal/passive/mouse,/turf/simulated/floor,/area/maintenance/research_shuttle) "baZ" = (/turf/simulated/wall/r_wall,/area/rnd/research_storage) "bba" = (/obj/effect/floor_decal/corner/purple{dir = 9},/obj/machinery/ai_status_display{pixel_x = -32; pixel_y = 0},/turf/simulated/floor/tiled/white,/area/rnd/research) "bbb" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/tiled/white,/area/rnd/research) @@ -3776,7 +3776,7 @@ "buF" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/blast/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "cmooffice"; name = "CMO Office Privacy Shutters"; opacity = 0},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/crew_quarters/heads/cmo) "buG" = (/obj/structure/flora/pottedplant{icon_state = "plant-01"},/obj/effect/floor_decal/corner/paleblue/full{dir = 8},/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/simulated/floor/tiled/white,/area/crew_quarters/heads/cmo) "buH" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/obj/effect/floor_decal/corner/paleblue{dir = 5},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/tiled/white,/area/crew_quarters/heads/cmo) -"buI" = (/obj/effect/floor_decal/corner/paleblue{dir = 1},/obj/machinery/light{dir = 1},/obj/structure/disposalpipe/segment{dir = 4},/mob/living/simple_animal/cat/fluff/Runtime,/turf/simulated/floor/tiled/white,/area/crew_quarters/heads/cmo) +"buI" = (/obj/effect/floor_decal/corner/paleblue{dir = 1},/obj/machinery/light{dir = 1},/obj/structure/disposalpipe/segment{dir = 4},/mob/living/simple_mob/animal/passive/cat/runtime,/turf/simulated/floor/tiled/white,/area/crew_quarters/heads/cmo) "buJ" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/tiled/white,/area/crew_quarters/heads/cmo) "buK" = (/obj/effect/floor_decal/corner/paleblue{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/tiled/white,/area/crew_quarters/heads/cmo) "buL" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 8},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/effect/floor_decal/corner/paleblue/full{dir = 1},/turf/simulated/floor/tiled/white,/area/crew_quarters/heads/cmo) @@ -4187,7 +4187,7 @@ "bCA" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/central) "bCB" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/item/weapon/material/shard{icon_state = "medium"},/obj/item/stack/rods,/turf/simulated/floor,/area/maintenance/central) "bCC" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/maintenance/central) -"bCD" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/mob/living/simple_animal/mouse,/turf/simulated/floor,/area/maintenance/central) +"bCD" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/mob/living/simple_mob/animal/passive/mouse,/turf/simulated/floor,/area/maintenance/central) "bCE" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor,/area/maintenance/central) "bCF" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/airlock/maintenance{req_access = list(12)},/obj/machinery/door/firedoor,/turf/simulated/floor/tiled,/area/maintenance/central) "bCG" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/tiled,/area/maintenance/central) @@ -4270,7 +4270,7 @@ "bEf" = (/obj/structure/closet/crate,/obj/item/weapon/reagent_containers/food/drinks/bottle/wine,/obj/random/drinkbottle,/obj/random/maintenance/clean,/turf/simulated/floor/plating,/area/maintenance/central) "bEg" = (/turf/simulated/floor/tiled,/area/maintenance/central) "bEh" = (/obj/structure/cable/green{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/tiled,/area/maintenance/central) -"bEi" = (/obj/machinery/light/small,/mob/living/simple_animal/mouse,/turf/simulated/floor/plating,/area/maintenance/central) +"bEi" = (/obj/machinery/light/small,/mob/living/simple_mob/animal/passive/mouse,/turf/simulated/floor/plating,/area/maintenance/central) "bEj" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/maintenance/central) "bEk" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor,/area/maintenance/central) "bEl" = (/obj/structure/closet,/obj/item/weapon/storage/backpack,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/random/maintenance/clean,/obj/random/maintenance/cargo,/turf/simulated/floor/plating,/area/maintenance/central) @@ -4570,7 +4570,7 @@ "bJT" = (/turf/simulated/wall/r_wall,/area/quartermaster/miningdock) "bJU" = (/obj/structure/lattice,/obj/machinery/light{dir = 8},/turf/simulated/mineral/floor/ignore_mapgen,/area/quartermaster/miningdock) "bJV" = (/obj/structure/lattice,/obj/machinery/light{dir = 4; icon_state = "tube1"; pixel_x = 0},/turf/simulated/mineral/floor/ignore_mapgen,/area/quartermaster/miningdock) -"bJW" = (/obj/structure/table/rack,/obj/item/weapon/extinguisher,/obj/item/weapon/storage/belt/utility,/obj/item/clothing/mask/gas,/obj/machinery/atmospherics/pipe/simple/hidden/yellow,/mob/living/simple_animal/mouse,/turf/simulated/floor/plating,/area/maintenance/research) +"bJW" = (/obj/structure/table/rack,/obj/item/weapon/extinguisher,/obj/item/weapon/storage/belt/utility,/obj/item/clothing/mask/gas,/obj/machinery/atmospherics/pipe/simple/hidden/yellow,/mob/living/simple_mob/animal/passive/mouse,/turf/simulated/floor/plating,/area/maintenance/research) "bJX" = (/obj/structure/table/rack{dir = 8; layer = 2.9},/obj/item/weapon/tank/oxygen,/obj/item/weapon/tank/oxygen,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/device/flashlight,/obj/item/device/flashlight,/obj/item/weapon/storage/box/lights/mixed,/obj/item/weapon/extinguisher,/obj/random/maintenance/research,/obj/random/maintenance/research,/turf/simulated/floor/plating,/area/maintenance/research) "bJY" = (/obj/structure/table/standard,/obj/item/device/assembly/igniter,/turf/simulated/floor/reinforced,/area/rnd/misc_lab) "bJZ" = (/obj/structure/reagent_dispensers/watertank,/obj/machinery/light,/turf/simulated/floor/reinforced,/area/rnd/misc_lab) @@ -4590,7 +4590,7 @@ "bKn" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/obj/machinery/light{dir = 8},/turf/simulated/floor/tiled,/area/hallway/primary/central_four) "bKo" = (/obj/structure/grille,/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = -32},/obj/structure/cable/green,/obj/machinery/door/firedoor,/obj/structure/window/reinforced/polarized{dir = 8; id = "hop_office"},/obj/structure/window/reinforced/polarized{dir = 2; id = "hop_office"},/obj/structure/window/reinforced/polarized{dir = 4; id = "hop_office"},/turf/simulated/floor/plating,/area/crew_quarters/heads/hop) "bKp" = (/obj/structure/closet/secure_closet/hop,/obj/effect/floor_decal/corner/blue{dir = 9},/turf/simulated/floor/tiled,/area/crew_quarters/heads/hop) -"bKq" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/mob/living/simple_animal/corgi/Ian,/turf/simulated/floor/carpet,/area/crew_quarters/heads/hop) +"bKq" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/mob/living/simple_mob/animal/passive/dog/corgi/Ian,/turf/simulated/floor/carpet,/area/crew_quarters/heads/hop) "bKr" = (/obj/structure/bed/chair/office/dark,/obj/effect/landmark/start{name = "Head of Personnel"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/carpet,/area/crew_quarters/heads/hop) "bKs" = (/obj/structure/cable/green{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/carpet,/area/crew_quarters/heads/hop) "bKt" = (/obj/structure/cable/green{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},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/carpet,/area/crew_quarters/heads/hop) @@ -4886,7 +4886,7 @@ "bPX" = (/obj/machinery/computer/aifixer,/obj/effect/floor_decal/corner/purple/full,/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = -32},/turf/simulated/floor/tiled/white,/area/rnd/rdoffice) "bPY" = (/obj/machinery/computer/robotics,/obj/effect/floor_decal/corner/purple{dir = 10},/turf/simulated/floor/tiled/white,/area/rnd/rdoffice) "bPZ" = (/obj/machinery/computer/mecha,/obj/effect/floor_decal/corner/purple{dir = 10},/obj/machinery/ai_status_display{pixel_y = -32},/obj/machinery/camera/network/research{c_tag = "SCI - RD's Office"; dir = 1},/turf/simulated/floor/tiled/white,/area/rnd/rdoffice) -"bQa" = (/obj/effect/floor_decal/corner/purple/full{dir = 4},/obj/machinery/alarm{dir = 1; pixel_y = -22},/mob/living/simple_animal/slime/rainbow/kendrick,/turf/simulated/floor/tiled/white,/area/rnd/rdoffice) +"bQa" = (/obj/effect/floor_decal/corner/purple/full{dir = 4},/obj/machinery/alarm{dir = 1; pixel_y = -22},/mob/living/simple_mob/slime/xenobio/rainbow/kendrick,/turf/simulated/floor/tiled/white,/area/rnd/rdoffice) "bQb" = (/obj/structure/table/rack,/obj/item/weapon/rig/hazmat/equipped,/obj/structure/extinguisher_cabinet{pixel_x = 25; pixel_y = 0},/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor/tiled/dark,/area/rnd/rdoffice) "bQc" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/turf/simulated/floor/tiled,/area/assembly/robotics) "bQd" = (/obj/structure/table/standard,/obj/machinery/cell_charger,/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 21},/obj/effect/floor_decal/corner/pink{dir = 4},/turf/simulated/floor/tiled,/area/assembly/robotics) @@ -5366,7 +5366,7 @@ "bZj" = (/turf/simulated/wall,/area/maintenance/medbay_aft) "bZk" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/maintenance/medbay_aft) "bZl" = (/obj/machinery/atmospherics/valve,/turf/simulated/floor/plating,/area/maintenance/medbay_aft) -"bZm" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 6; icon_state = "intact"},/obj/effect/floor_decal/industrial/warning{dir = 8},/mob/living/simple_animal/mouse,/turf/simulated/floor/plating,/area/maintenance/medbay_aft) +"bZm" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 6; icon_state = "intact"},/obj/effect/floor_decal/industrial/warning{dir = 8},/mob/living/simple_mob/animal/passive/mouse,/turf/simulated/floor/plating,/area/maintenance/medbay_aft) "bZn" = (/obj/machinery/atmospherics/pipe/tank/air{dir = 8},/turf/simulated/floor/plating,/area/maintenance/medbay_aft) "bZo" = (/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod_berth{frequency = 1380; id_tag = "large_escape_pod_1_berth"; pixel_x = -26; pixel_y = 0; tag_door = "large_escape_pod_1_berth_hatch"},/obj/effect/floor_decal/industrial/warning{dir = 10},/turf/simulated/floor/tiled,/area/hallway/secondary/escape/medical_escape_pod_hallway) "bZp" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/yellow,/obj/structure/disposalpipe/segment,/obj/effect/floor_decal/industrial/warning,/turf/simulated/floor/tiled,/area/hallway/secondary/escape/medical_escape_pod_hallway) @@ -6184,7 +6184,7 @@ "coV" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/hallway/primary/central_three) "coW" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/obj/machinery/light{dir = 8},/turf/simulated/floor/tiled/dark,/area/security/nuke_storage) "coX" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/tiled/dark,/area/security/nuke_storage) -"coY" = (/obj/machinery/hologram/holopad,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/mob/living/simple_animal/mouse/brown/Tom,/turf/simulated/floor/tiled/dark,/area/security/nuke_storage) +"coY" = (/obj/machinery/hologram/holopad,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/mob/living/simple_mob/animal/passive/mouse/brown/Tom,/turf/simulated/floor/tiled/dark,/area/security/nuke_storage) "coZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/tiled/dark,/area/security/nuke_storage) "cpa" = (/obj/machinery/camera/network/command{c_tag = "COM - Vault"; dir = 9},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor/tiled/dark,/area/security/nuke_storage) "cpb" = (/obj/structure/closet/crate,/obj/item/clothing/mask/gas,/obj/item/device/flashlight,/obj/item/device/flashlight,/obj/effect/decal/cleanable/dirt,/obj/random/maintenance/medical,/obj/random/maintenance/medical,/turf/simulated/floor/plating,/area/maintenance/medbay_aft) @@ -9152,7 +9152,7 @@ "dtZ" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/portable_atmospherics/canister/nitrogen,/turf/simulated/floor,/area/engineering/storage) "dua" = (/obj/effect/decal/cleanable/dirt,/obj/structure/dispenser{oxygentanks = 0},/turf/simulated/floor,/area/engineering/storage) "dub" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/light/small{dir = 8},/turf/simulated/floor,/area/maintenance/engineering) -"duc" = (/obj/structure/bed/chair{dir = 4},/mob/living/simple_animal/mouse,/turf/simulated/floor,/area/maintenance/engineering) +"duc" = (/obj/structure/bed/chair{dir = 4},/mob/living/simple_mob/animal/passive/mouse,/turf/simulated/floor,/area/maintenance/engineering) "dud" = (/obj/machinery/newscaster{pixel_x = -30},/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D1) "due" = (/obj/effect/floor_decal/industrial/warning/corner{dir = 4},/obj/machinery/hologram/holopad,/obj/machinery/camera/network/northern_star{c_tag = "DOCK - Dock 1 Mid"; dir = 8},/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D1) "duf" = (/obj/effect/floor_decal/industrial/warning/corner{dir = 1},/obj/machinery/hologram/holopad,/obj/machinery/camera/network/northern_star{c_tag = "DOCK - Dock 2 Mid"; dir = 4},/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D2) @@ -9872,7 +9872,7 @@ "dHR" = (/obj/item/weapon/rig/breacher,/obj/item/clothing/mask/breath,/obj/machinery/suit_storage_unit/standard_unit,/turf/simulated/floor/tiled/dark,/area/ai_monitored/storage/eva) "dHS" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/machinery/light,/turf/simulated/floor/tiled,/area/crew_quarters/visitor_lodging) "dHT" = (/obj/structure/table/rack{dir = 8; layer = 2.9},/obj/machinery/light/small{dir = 4; pixel_y = 0},/obj/item/clothing/mask/breath,/obj/item/weapon/rig/breacher,/turf/simulated/floor/tiled/dark,/area/ai_monitored/storage/eva) - + (1,1,1) = {" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -10175,3 +10175,4 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa "} + diff --git a/maps/northern_star/polaris-2.dmm b/maps/northern_star/polaris-2.dmm index cbdb8d3e61..9780679b04 100644 --- a/maps/northern_star/polaris-2.dmm +++ b/maps/northern_star/polaris-2.dmm @@ -19,7 +19,7 @@ "as" = (/obj/structure/table/rack/holorack,/obj/item/clothing/under/dress/dress_saloon,/obj/item/clothing/head/pin/flower,/turf/simulated/floor/holofloor/tiled/dark,/area/holodeck/source_theatre) "at" = (/obj/effect/landmark/costume,/obj/structure/table/rack/holorack,/turf/simulated/floor/holofloor/tiled/dark,/area/holodeck/source_theatre) "au" = (/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_courtroom) -"av" = (/obj/structure/window/reinforced/holowindow{dir = 4},/obj/structure/flora/pottedplant{ icon_state = "plant-10"},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_courtroom) +"av" = (/obj/structure/window/reinforced/holowindow{dir = 4},/obj/structure/flora/pottedplant{icon_state = "plant-10"},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_courtroom) "aw" = (/obj/structure/table/woodentable/holotable,/turf/simulated/floor/holofloor/wood,/area/holodeck/source_courtroom) "ax" = (/turf/simulated/floor/holofloor/reinforced,/area/holodeck/source_wildlife) "ay" = (/turf/simulated/floor/holofloor/reinforced,/area/holodeck/source_plating) @@ -54,7 +54,7 @@ "bb" = (/turf/simulated/floor/holofloor/desert,/area/holodeck/source_picnicarea) "bc" = (/obj/effect/decal/cleanable/dirt,/obj/structure/holostool,/turf/simulated/floor/holofloor/desert,/area/holodeck/source_picnicarea) "bd" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/holofloor/desert,/area/holodeck/source_picnicarea) -"be" = (/obj/structure/flora/ausbushes/ywflowers,/obj/effect/floor_decal/spline/fancy/wood{ icon_state = "spline_fancy"; dir = 10},/turf/simulated/floor/holofloor/grass,/area/holodeck/source_picnicarea) +"be" = (/obj/structure/flora/ausbushes/ywflowers,/obj/effect/floor_decal/spline/fancy/wood{icon_state = "spline_fancy"; dir = 10},/turf/simulated/floor/holofloor/grass,/area/holodeck/source_picnicarea) "bf" = (/obj/effect/floor_decal/spline/plain{dir = 1},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_theatre) "bg" = (/obj/effect/floor_decal/carpet{dir = 8},/obj/effect/floor_decal/carpet{dir = 4},/obj/effect/floor_decal/carpet{dir = 1},/obj/effect/floor_decal/carpet{dir = 5},/obj/effect/floor_decal/carpet{dir = 9},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_theatre) "bh" = (/obj/structure/window/reinforced/holowindow,/obj/machinery/door/window/holowindoor{dir = 1; name = "Court Reporter's Box"},/obj/structure/bed/chair/holochair,/turf/simulated/floor/holofloor/wood,/area/holodeck/source_courtroom) @@ -91,7 +91,7 @@ "bM" = (/obj/effect/floor_decal/corner/green{dir = 9},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_emptycourt) "bN" = (/obj/effect/floor_decal/corner/green{dir = 6},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_emptycourt) "bO" = (/turf/space/transit/east,/area/shuttle/large_escape_pod1/transit) -"bP" = (/obj/structure/flora/ausbushes/ywflowers,/obj/effect/floor_decal/spline/fancy/wood{ icon_state = "spline_fancy"; dir = 9},/turf/simulated/floor/holofloor/grass,/area/holodeck/source_picnicarea) +"bP" = (/obj/structure/flora/ausbushes/ywflowers,/obj/effect/floor_decal/spline/fancy/wood{icon_state = "spline_fancy"; dir = 9},/turf/simulated/floor/holofloor/grass,/area/holodeck/source_picnicarea) "bQ" = (/obj/structure/flora/ausbushes/brflowers,/obj/effect/floor_decal/spline/fancy/wood{dir = 1},/turf/simulated/floor/holofloor/grass,/area/holodeck/source_picnicarea) "bR" = (/obj/structure/flora/ausbushes/ywflowers,/obj/effect/floor_decal/spline/fancy/wood{dir = 1},/turf/simulated/floor/holofloor/grass,/area/holodeck/source_picnicarea) "bS" = (/obj/structure/bed/chair/holochair{dir = 1},/obj/effect/floor_decal/carpet{dir = 8},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_courtroom) @@ -114,7 +114,7 @@ "cj" = (/obj/structure/bed/chair/holochair{dir = 8},/obj/effect/floor_decal/carpet{dir = 4},/obj/effect/floor_decal/carpet,/obj/effect/floor_decal/carpet{dir = 6},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_courtroom) "ck" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdown"; tiles = 0},/turf/space/transit/east,/area/space) "cl" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdown"; stopper = 0; tiles = 0},/turf/space/transit/east,/area/space) -"cm" = (/obj/structure/flora/pottedplant{ icon_state = "plant-06"},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_theatre) +"cm" = (/obj/structure/flora/pottedplant{icon_state = "plant-06"},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_theatre) "cn" = (/obj/effect/floor_decal/carpet{dir = 5},/obj/effect/floor_decal/carpet{dir = 6},/obj/effect/floor_decal/carpet{dir = 10},/obj/effect/floor_decal/carpet{dir = 9},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_theatre) "co" = (/obj/structure/bed/chair/holochair{dir = 1},/obj/effect/floor_decal/carpet{dir = 8},/obj/effect/floor_decal/carpet,/obj/effect/floor_decal/carpet{dir = 10},/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_courtroom) "cp" = (/obj/structure/bed/chair/holochair{dir = 1},/obj/effect/floor_decal/carpet,/turf/simulated/floor/holofloor/carpet,/area/holodeck/source_courtroom) @@ -127,7 +127,7 @@ "cw" = (/turf/simulated/floor/holofloor/space,/area/holodeck/source_space) "cx" = (/turf/simulated/floor/holofloor/snow,/area/holodeck/source_snowfield) "cy" = (/turf/simulated/floor/holofloor/wood,/area/holodeck/source_meetinghall) -"cz" = (/obj/structure/flora/pottedplant{ icon_state = "plant-06"},/turf/simulated/floor/holofloor/wood,/area/holodeck/source_meetinghall) +"cz" = (/obj/structure/flora/pottedplant{icon_state = "plant-06"},/turf/simulated/floor/holofloor/wood,/area/holodeck/source_meetinghall) "cA" = (/turf/simulated/floor/holofloor/tiled/dark,/area/holodeck/source_basketball) "cB" = (/obj/structure/holostool,/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_basketball) "cC" = (/obj/structure/holostool,/obj/structure/window/reinforced/holowindow{dir = 4},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_basketball) @@ -213,7 +213,7 @@ "ee" = (/obj/structure/holostool,/obj/effect/floor_decal/carpet{dir = 4},/turf/simulated/floor/holofloor/carpet{dir = 8},/area/holodeck/source_meetinghall) "ef" = (/obj/machinery/door/window/holowindoor{base_state = "right"; icon_state = "right"; name = "Green Team"},/turf/simulated/floor/holofloor/tiled/dark,/area/holodeck/source_basketball) "eg" = (/obj/effect/floor_decal/corner/green{dir = 10},/turf/simulated/floor/holofloor/tiled,/area/holodeck/source_basketball) -"eh" = (/turf/unsimulated/beach/sand{ icon_state = "beach"},/area/holodeck/source_beach) +"eh" = (/turf/unsimulated/beach/sand{icon_state = "beach"},/area/holodeck/source_beach) "ei" = (/obj/machinery/door/window/holowindoor{base_state = "right"; icon_state = "right"; name = "Green Team"},/turf/simulated/floor/holofloor/tiled/dark,/area/holodeck/source_thunderdomecourt) "ej" = (/obj/structure/window/reinforced/holowindow{dir = 1},/turf/simulated/floor/holofloor/tiled/dark,/area/holodeck/source_boxingcourt) "ek" = (/obj/machinery/door/window/holowindoor{dir = 1; name = "Green Corner"},/turf/simulated/floor/holofloor/tiled/dark,/area/holodeck/source_boxingcourt) @@ -256,19 +256,19 @@ "eV" = (/turf/unsimulated/wall{desc = "That looks like it doesn't open easily."; icon = 'icons/obj/doors/rapid_pdoor.dmi'; icon_state = "pdoor1"; name = "Shuttle Bay Blast Door"},/area/syndicate_mothership) "eW" = (/obj/machinery/door/airlock/multi_tile/glass{dir = 4; req_access = list(160)},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership{name = "\improper Trader Base"}) "eX" = (/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership{name = "\improper Trader Base"}) -"eY" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "arrivals_shuttle"; pixel_x = 0; pixel_y = 25; req_one_access = list(13); tag_door = "arrivals_shuttle_hatch"},/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/shuttle/arrival/pre_game) -"eZ" = (/obj/structure/showcase{desc = "So that's how the shuttle moves on its own."; icon = 'icons/mob/AI.dmi'; icon_state = "ai-red"; name = "Arrivals Announcement Computer"},/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/shuttle/arrival/pre_game) -"fa" = (/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/shuttle/arrival/pre_game) +"eY" = (/obj/structure/showcase{desc = "So that's how the shuttle moves on its own."; icon = 'icons/mob/AI.dmi'; icon_state = "ai-red"; name = "Arrivals Announcement Computer"},/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/shuttle/arrival/pre_game) +"eZ" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "arrivals_shuttle"; pixel_x = 0; pixel_y = 25; req_one_access = list(13); tag_door = "arrivals_shuttle_hatch"},/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/shuttle/arrival/pre_game) +"fa" = (/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/shuttle/arrival/pre_game) "fb" = (/turf/simulated/shuttle/wall/dark,/area/shuttle/syndicate_elite/mothership) "fc" = (/turf/space,/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_r"; dir = 1},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/syndicate_elite/mothership) "fd" = (/turf/space,/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion"; dir = 1},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/syndicate_elite/mothership) "fe" = (/turf/space,/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_l"; dir = 1},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/syndicate_elite/mothership) "ff" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/structure/mirror{pixel_x = -28},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership{name = "\improper Trader Base"}) "fg" = (/obj/structure/curtain/open/shower,/obj/machinery/shower{pixel_y = 3},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership{name = "\improper Trader Base"}) -"fh" = (/obj/machinery/computer/shuttle_control/arrivals,/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/shuttle/arrival/pre_game) -"fi" = (/obj/machinery/light,/obj/structure/bed/chair{dir = 8},/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/shuttle/arrival/pre_game) -"fj" = (/obj/machinery/light,/obj/structure/bed/chair{dir = 4},/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/shuttle/arrival/pre_game) -"fk" = (/obj/structure/table/steel,/obj/structure/flora/pottedplant{icon_state = "plant-09"; name = "Dave"; pixel_y = 15},/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/shuttle/arrival/pre_game) +"fh" = (/obj/machinery/computer/shuttle_control/arrivals,/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/shuttle/arrival/pre_game) +"fi" = (/obj/machinery/light,/obj/structure/bed/chair{dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/shuttle/arrival/pre_game) +"fj" = (/obj/structure/table/steel,/obj/structure/flora/pottedplant{icon_state = "plant-09"; name = "Dave"; pixel_y = 15},/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/shuttle/arrival/pre_game) +"fk" = (/obj/machinery/light,/obj/structure/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/shuttle/arrival/pre_game) "fl" = (/obj/structure/window/reinforced,/obj/structure/shuttle/engine/heater{icon_state = "heater"; dir = 1},/turf/simulated/floor/airless,/area/shuttle/syndicate_elite/mothership) "fm" = (/obj/structure/table/standard,/obj/item/weapon/soap/deluxe,/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership{name = "\improper Trader Base"}) "fn" = (/obj/structure/undies_wardrobe,/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership{name = "\improper Trader Base"}) @@ -284,12 +284,12 @@ "fx" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 8; name = "thrower_escapeshuttletop(left)"; tiles = 0},/turf/space/transit/north,/area/space) "fy" = (/turf/space/transit/north,/area/syndicate_station/transit) "fz" = (/turf/simulated/shuttle/wall/hard_corner,/area/shuttle/arrival/pre_game) -"fA" = (/obj/structure/closet/emcloset,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/shuttle/arrival/pre_game) -"fB" = (/obj/machinery/light{dir = 1},/obj/machinery/computer/arcade/battle,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/shuttle/arrival/pre_game) +"fA" = (/obj/machinery/light{dir = 1},/obj/machinery/computer/arcade/battle,/turf/simulated/shuttle/floor{icon_state = "floor_white"},/area/shuttle/arrival/pre_game) +"fB" = (/obj/structure/closet/emcloset,/turf/simulated/shuttle/floor{icon_state = "floor_white"},/area/shuttle/arrival/pre_game) "fC" = (/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 4},/turf/simulated/shuttle/floor,/area/shuttle/arrival/pre_game) "fD" = (/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 1},/turf/simulated/shuttle/floor,/area/shuttle/arrival/pre_game) "fE" = (/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 1},/obj/machinery/requests_console{department = "Arrival shuttle"; pixel_y = 26},/turf/simulated/shuttle/floor,/area/shuttle/arrival/pre_game) -"fF" = (/obj/machinery/light{dir = 1},/obj/machinery/computer/arcade/orion_trail,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/shuttle/arrival/pre_game) +"fF" = (/obj/machinery/light{dir = 1},/obj/machinery/computer/arcade/orion_trail,/turf/simulated/shuttle/floor{icon_state = "floor_white"},/area/shuttle/arrival/pre_game) "fG" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/shuttle/floor/red,/area/shuttle/syndicate_elite/mothership) "fH" = (/turf/simulated/shuttle/floor/red,/area/shuttle/syndicate_elite/mothership) "fI" = (/obj/structure/bed/chair{dir = 8},/turf/simulated/shuttle/floor/red,/area/shuttle/syndicate_elite/mothership) @@ -307,14 +307,14 @@ "fU" = (/obj/mecha/combat/marauder/mauler,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) "fV" = (/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) "fW" = (/turf/space/transit/north,/area/skipjack_station/transit) -"fX" = (/obj/structure/bed/chair,/obj/effect/landmark{name = "JoinLate"},/obj/structure/window/reinforced{dir = 1},/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -21},/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/shuttle/arrival/pre_game) -"fY" = (/obj/structure/bed/chair,/obj/effect/landmark{name = "JoinLate"},/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/shuttle/arrival/pre_game) -"fZ" = (/obj/structure/bed/chair,/obj/effect/landmark{name = "JoinLate"},/obj/structure/window/reinforced{dir = 1},/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 26},/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/shuttle/arrival/pre_game) +"fX" = (/obj/structure/bed/chair,/obj/effect/landmark{name = "JoinLate"},/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor_white"},/area/shuttle/arrival/pre_game) +"fY" = (/obj/structure/bed/chair,/obj/effect/landmark{name = "JoinLate"},/obj/structure/window/reinforced{dir = 1},/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -21},/turf/simulated/shuttle/floor{icon_state = "floor_white"},/area/shuttle/arrival/pre_game) +"fZ" = (/obj/structure/bed/chair,/obj/effect/landmark{name = "JoinLate"},/obj/structure/window/reinforced{dir = 1},/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 26},/turf/simulated/shuttle/floor{icon_state = "floor_white"},/area/shuttle/arrival/pre_game) "ga" = (/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},/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/syndicate_mothership/elite_squad) "gb" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "trade_shuttle_bay_door"; locked = 1},/turf/unsimulated/floor{icon_state = "steel"},/area/syndicate_mothership{name = "\improper Trader Base"}) -"gc" = (/obj/machinery/light{dir = 8; icon_state = "tube1"; pixel_y = 0},/obj/structure/closet/walllocker/emerglocker{pixel_x = -28},/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/shuttle/arrival/pre_game) -"gd" = (/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/shuttle/arrival/pre_game) -"ge" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/structure/closet/walllocker/emerglocker{pixel_x = 28},/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/shuttle/arrival/pre_game) +"gc" = (/turf/simulated/shuttle/floor{icon_state = "floor_white"},/area/shuttle/arrival/pre_game) +"gd" = (/obj/machinery/light{dir = 8; icon_state = "tube1"; pixel_y = 0},/obj/structure/closet/walllocker/emerglocker{pixel_x = -28},/turf/simulated/shuttle/floor{icon_state = "floor_white"},/area/shuttle/arrival/pre_game) +"ge" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/structure/closet/walllocker/emerglocker{pixel_x = 28},/turf/simulated/shuttle/floor{icon_state = "floor_white"},/area/shuttle/arrival/pre_game) "gf" = (/obj/machinery/door/airlock/external{name = "Shuttle Airlock"; req_access = list(150)},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "syndicate_elite"; name = "Side Hull Door"; opacity = 0},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate_elite/mothership) "gg" = (/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/syndicate_mothership/elite_squad) "gh" = (/obj/machinery/door/airlock/external{req_access = list(150)},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership/elite_squad) @@ -322,7 +322,7 @@ "gj" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "trade_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access = list(13)},/turf/simulated/shuttle/floor/black,/area/shuttle/trade/centcom) "gk" = (/turf/simulated/shuttle/wall/dark,/area/shuttle/trade/centcom) "gl" = (/obj/structure/shuttle/window,/obj/structure/grille,/turf/simulated/shuttle/plating,/area/shuttle/arrival/pre_game) -"gm" = (/obj/structure/bed/chair{dir = 1},/obj/effect/landmark{name = "JoinLate"},/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/shuttle/arrival/pre_game) +"gm" = (/obj/structure/bed/chair{dir = 1},/obj/effect/landmark{name = "JoinLate"},/turf/simulated/shuttle/floor{icon_state = "floor_white"},/area/shuttle/arrival/pre_game) "gn" = (/obj/machinery/door/airlock/glass_security{name = "Airlock"; req_access = list(150)},/obj/machinery/door/blast/regular{id = "syndicate_elite_mech_room"; name = "Mech Room Door"},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership/elite_squad) "go" = (/obj/structure/window/reinforced,/obj/machinery/door/blast/shutters{density = 0; icon_state = "shutter0"; id = "tradestarshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/shuttle/plating,/area/shuttle/trade/centcom) "gp" = (/obj/structure/window/reinforced,/obj/machinery/door/blast/shutters{density = 0; icon_state = "shutter0"; id = "tradestarshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/plating,/area/shuttle/trade/centcom) @@ -333,9 +333,9 @@ "gu" = (/turf/space,/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_r"; dir = 4},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/trade/centcom) "gv" = (/turf/space/transit/north,/area/shuttle/escape_pod2/transit) "gw" = (/turf/space/transit/north,/area/shuttle/escape_pod1/transit) -"gx" = (/obj/structure/table/standard,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/shuttle/arrival/pre_game) +"gx" = (/obj/structure/table/standard,/turf/simulated/shuttle/floor{icon_state = "floor_white"},/area/shuttle/arrival/pre_game) "gy" = (/obj/machinery/hologram/holopad,/obj/effect/landmark{name = "Observer-Start"},/turf/simulated/shuttle/floor,/area/shuttle/arrival/pre_game) -"gz" = (/obj/structure/table/standard,/obj/item/weapon/book/codex/lore/vir,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/shuttle/arrival/pre_game) +"gz" = (/obj/structure/table/standard,/obj/item/weapon/book/codex/lore/vir,/turf/simulated/shuttle/floor{icon_state = "floor_white"},/area/shuttle/arrival/pre_game) "gA" = (/obj/machinery/computer/pod{id = "syndicate_elite"; name = "Hull Door Control"},/turf/simulated/shuttle/floor/red,/area/shuttle/syndicate_elite/mothership) "gB" = (/obj/machinery/computer/syndicate_elite_shuttle,/turf/simulated/shuttle/floor/red,/area/shuttle/syndicate_elite/mothership) "gC" = (/obj/structure/closet{icon_closed = "cabinet_closed"; icon_opened = "cabinet_open"; icon_state = "cabinet_closed"},/turf/simulated/shuttle/floor/black,/area/shuttle/trade/centcom) @@ -348,7 +348,7 @@ "gJ" = (/obj/machinery/sleep_console{dir = 4},/turf/simulated/shuttle/floor/black,/area/shuttle/trade/centcom) "gK" = (/obj/machinery/sleeper{dir = 4},/turf/simulated/shuttle/floor/black,/area/shuttle/trade/centcom) "gL" = (/turf/space,/obj/structure/shuttle/engine/propulsion{dir = 4},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/trade/centcom) -"gM" = (/obj/structure/bed/chair,/obj/effect/landmark{name = "JoinLate"},/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/shuttle/arrival/pre_game) +"gM" = (/obj/structure/bed/chair,/obj/effect/landmark{name = "JoinLate"},/turf/simulated/shuttle/floor{icon_state = "floor_white"},/area/shuttle/arrival/pre_game) "gN" = (/turf/simulated/shuttle/wall/dark/hard_corner,/area/shuttle/syndicate_elite/mothership) "gO" = (/obj/machinery/door/airlock/external{name = "Shuttle Airlock"; req_access = list(150)},/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "syndicate_elite"; name = "Front Hull Door"; opacity = 1},/turf/simulated/shuttle/plating,/area/shuttle/syndicate_elite/mothership) "gP" = (/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/blast/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "tradestarshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/shuttle/plating,/area/shuttle/trade/centcom) @@ -384,9 +384,9 @@ "ht" = (/obj/machinery/door/airlock/glass_medical{name = "Medical Bay"; req_access = list(160)},/turf/simulated/shuttle/floor/black,/area/shuttle/trade/centcom) "hu" = (/obj/machinery/optable,/turf/simulated/shuttle/floor/black,/area/shuttle/trade/centcom) "hv" = (/turf/space,/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_l"; dir = 4},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/trade/centcom) -"hw" = (/obj/structure/bed/chair{dir = 1},/obj/effect/landmark{name = "JoinLate"},/obj/structure/window/reinforced,/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -21},/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/shuttle/arrival/pre_game) -"hx" = (/obj/structure/bed/chair{dir = 1},/obj/effect/landmark{name = "JoinLate"},/obj/structure/window/reinforced,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/shuttle/arrival/pre_game) -"hy" = (/obj/structure/bed/chair{dir = 1},/obj/effect/landmark{name = "JoinLate"},/obj/structure/window/reinforced,/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 26},/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/shuttle/arrival/pre_game) +"hw" = (/obj/structure/bed/chair{dir = 1},/obj/effect/landmark{name = "JoinLate"},/obj/structure/window/reinforced,/turf/simulated/shuttle/floor{icon_state = "floor_white"},/area/shuttle/arrival/pre_game) +"hx" = (/obj/structure/bed/chair{dir = 1},/obj/effect/landmark{name = "JoinLate"},/obj/structure/window/reinforced,/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -21},/turf/simulated/shuttle/floor{icon_state = "floor_white"},/area/shuttle/arrival/pre_game) +"hy" = (/obj/structure/bed/chair{dir = 1},/obj/effect/landmark{name = "JoinLate"},/obj/structure/window/reinforced,/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 26},/turf/simulated/shuttle/floor{icon_state = "floor_white"},/area/shuttle/arrival/pre_game) "hz" = (/obj/structure/closet/walllocker/emerglocker{pixel_y = -32},/turf/simulated/shuttle/floor/black,/area/shuttle/trade/centcom) "hA" = (/obj/machinery/button/remote/blast_door{id = "tradestarshutters"; name = "remote shutter control"; pixel_x = 30; req_access = list(160)},/turf/simulated/shuttle/floor/black,/area/shuttle/trade/centcom) "hB" = (/obj/structure/table/steel_reinforced,/obj/random/firstaid,/obj/random/firstaid,/obj/random/firstaid,/obj/random/firstaid,/turf/simulated/shuttle/floor/black,/area/shuttle/trade/centcom) @@ -407,8 +407,8 @@ "hQ" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/turf/simulated/shuttle/plating,/area/shuttle/trade/centcom) "hR" = (/obj/structure/table/standard,/obj/item/clothing/gloves/sterile/latex,/obj/item/clothing/mask/surgical,/obj/item/weapon/surgical/retractor{pixel_x = 0; pixel_y = 6},/obj/item/weapon/surgical/scalpel,/obj/item/weapon/surgical/surgicaldrill,/obj/item/weapon/surgical/circular_saw,/obj/item/stack/nanopaste,/obj/item/weapon/surgical/hemostat{pixel_y = 4},/obj/item/weapon/surgical/cautery{pixel_y = 4},/obj/item/weapon/surgical/FixOVein{pixel_x = -6; pixel_y = 1},/obj/item/stack/medical/advanced/bruise_pack,/obj/item/weapon/surgical/bonesetter,/obj/item/weapon/surgical/bonegel{pixel_x = 4; pixel_y = 3},/turf/simulated/shuttle/floor/black,/area/shuttle/trade/centcom) "hS" = (/obj/machinery/iv_drip,/turf/simulated/shuttle/floor/black,/area/shuttle/trade/centcom) -"hT" = (/obj/machinery/vending/snack,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/shuttle/arrival/pre_game) -"hU" = (/obj/machinery/vending/cigarette,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/shuttle/arrival/pre_game) +"hT" = (/obj/machinery/vending/snack,/turf/simulated/shuttle/floor{icon_state = "floor_white"},/area/shuttle/arrival/pre_game) +"hU" = (/obj/machinery/vending/cigarette,/turf/simulated/shuttle/floor{icon_state = "floor_white"},/area/shuttle/arrival/pre_game) "hV" = (/turf/unsimulated/wall,/area/syndicate_mothership) "hW" = (/obj/machinery/door/blast/shutters{density = 0; icon_state = "shutter0"; id = "tradebridgeshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/plating,/area/shuttle/trade/centcom) "hX" = (/obj/machinery/door/blast/shutters{density = 0; icon_state = "shutter0"; id = "tradebridgeshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/plating,/area/shuttle/trade/centcom) @@ -417,9 +417,9 @@ "ia" = (/obj/machinery/door/airlock/multi_tile/glass,/turf/simulated/shuttle/floor/darkred,/area/shuttle/trade/centcom) "ib" = (/obj/structure/closet/crate/secure/weapon,/turf/simulated/shuttle/floor/black,/area/shuttle/trade/centcom) "ic" = (/obj/structure/shuttle/engine/heater,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/airless,/area/shuttle/arrival/pre_game) -"id" = (/obj/machinery/vending/cola,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/shuttle/arrival/pre_game) -"ie" = (/obj/machinery/light,/obj/structure/table/standard,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/shuttle/arrival/pre_game) -"if" = (/obj/machinery/vending/coffee,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/shuttle/arrival/pre_game) +"id" = (/obj/machinery/vending/cola,/turf/simulated/shuttle/floor{icon_state = "floor_white"},/area/shuttle/arrival/pre_game) +"ie" = (/obj/machinery/light,/obj/structure/table/standard,/turf/simulated/shuttle/floor{icon_state = "floor_white"},/area/shuttle/arrival/pre_game) +"if" = (/obj/machinery/vending/coffee,/turf/simulated/shuttle/floor{icon_state = "floor_white"},/area/shuttle/arrival/pre_game) "ig" = (/obj/structure/shuttle/engine/heater,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/airless,/area/shuttle/arrival/pre_game) "ih" = (/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/area/syndicate_mothership) "ii" = (/obj/structure/flora/grass/brown,/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/area/syndicate_mothership) @@ -438,7 +438,7 @@ "iv" = (/obj/structure/shuttle/engine/heater,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/airless,/area/shuttle/arrival/pre_game) "iw" = (/obj/machinery/door/blast/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "tradebridgeshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/plating,/area/shuttle/trade/centcom) "ix" = (/obj/structure/frame/computer,/turf/simulated/shuttle/floor/black,/area/shuttle/trade/centcom) -"iy" = (/obj/machinery/light{dir = 4},/obj/structure/sign/kiddieplaque{desc = "A plaque commemorating the construction of the cargo ship Beruang."; name = "Beruang"; pixel_x = 32},/mob/living/simple_animal/corgi/tamaskan/spice,/turf/simulated/shuttle/floor/darkred,/area/shuttle/trade/centcom) +"iy" = (/obj/machinery/light{dir = 4},/obj/structure/sign/kiddieplaque{desc = "A plaque commemorating the construction of the cargo ship Beruang."; name = "Beruang"; pixel_x = 32},/mob/living/simple_mob/animal/passive/dog/tamaskan/Spice,/turf/simulated/shuttle/floor/darkred,/area/shuttle/trade/centcom) "iz" = (/obj/machinery/door/airlock/silver{name = "Toilet"},/turf/simulated/shuttle/floor/white,/area/shuttle/trade/centcom) "iA" = (/obj/machinery/door/airlock/silver{name = "Restroom"},/turf/simulated/shuttle/floor/white,/area/shuttle/trade/centcom) "iB" = (/obj/structure/undies_wardrobe,/turf/simulated/shuttle/floor/black,/area/shuttle/trade/centcom) @@ -534,9 +534,9 @@ "kn" = (/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "tradeportshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/shuttle/plating,/area/shuttle/trade/centcom) "ko" = (/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "tradeportshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced,/turf/simulated/shuttle/plating,/area/shuttle/trade/centcom) "kp" = (/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "tradeportshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/shuttle/plating,/area/shuttle/trade/centcom) -"kq" = (/obj/machinery/atmospherics/pipe/simple/visible{ icon_state = "intact"; dir = 5},/obj/machinery/atm{pixel_x = -32},/obj/machinery/meter,/turf/simulated/shuttle/floor/black,/area/shuttle/trade/centcom) +"kq" = (/obj/machinery/atmospherics/pipe/simple/visible{icon_state = "intact"; dir = 5},/obj/machinery/atm{pixel_x = -32},/obj/machinery/meter,/turf/simulated/shuttle/floor/black,/area/shuttle/trade/centcom) "kr" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1331; master_tag = "trade2_control"; pixel_x = -22; pixel_y = -32; req_one_access = list(150)},/obj/machinery/atmospherics/pipe/manifold/visible{dir = 1},/turf/simulated/shuttle/floor/black,/area/shuttle/trade/centcom) -"ks" = (/obj/machinery/atmospherics/pipe/simple/visible{ icon_state = "intact"; dir = 10},/turf/simulated/shuttle/floor/black,/area/shuttle/trade/centcom) +"ks" = (/obj/machinery/atmospherics/pipe/simple/visible{icon_state = "intact"; dir = 10},/turf/simulated/shuttle/floor/black,/area/shuttle/trade/centcom) "kt" = (/obj/structure/table/standard,/obj/item/clothing/suit/space/void/merc,/obj/item/clothing/suit/space/void/merc,/obj/item/clothing/suit/space/void/merc,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/head/helmet/space/void/merc,/obj/item/clothing/head/helmet/space/void/merc,/obj/item/clothing/head/helmet/space/void/merc,/turf/simulated/shuttle/floor/black,/area/shuttle/trade/centcom) "ku" = (/obj/structure/table/standard,/obj/item/stack/cable_coil,/obj/item/stack/cable_coil,/obj/item/clothing/gloves/yellow,/obj/item/clothing/gloves/yellow,/obj/item/clothing/gloves/yellow,/turf/simulated/shuttle/floor/black,/area/shuttle/trade/centcom) "kv" = (/obj/structure/table/standard,/obj/item/stack/material/steel{amount = 2},/obj/item/stack/material/steel{amount = 2},/obj/item/stack/material/glass{amount = 15},/obj/item/stack/material/glass{amount = 15},/turf/simulated/shuttle/floor/black,/area/shuttle/trade/centcom) @@ -551,7 +551,7 @@ "kE" = (/obj/structure/filingcabinet/filingcabinet,/turf/simulated/shuttle/floor/black,/area/shuttle/trade/centcom) "kF" = (/obj/machinery/light,/turf/simulated/floor/carpet,/area/shuttle/trade/centcom) "kG" = (/obj/structure/bed/chair/comfy/black{dir = 1},/turf/simulated/floor/carpet,/area/shuttle/trade/centcom) -"kH" = (/obj/structure/flora/pottedplant{ icon_state = "plant-10"},/turf/simulated/floor/carpet,/area/shuttle/trade/centcom) +"kH" = (/obj/structure/flora/pottedplant{icon_state = "plant-10"},/turf/simulated/floor/carpet,/area/shuttle/trade/centcom) "kI" = (/obj/machinery/atmospherics/pipe/simple/visible,/obj/machinery/door/airlock/external{frequency = 1331; icon_state = "door_locked"; id_tag = "trade2_shuttle_inner"; locked = 1; name = "Ship Hatch"; req_access = list(13)},/turf/simulated/shuttle/floor/black,/area/shuttle/trade/centcom) "kJ" = (/obj/machinery/door/airlock/external{frequency = 1331; icon_state = "door_locked"; id_tag = "trade2_shuttle_inner"; locked = 1; name = "Ship Hatch"; req_access = list(13)},/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/shuttle/floor/black,/area/shuttle/trade/centcom) "kK" = (/obj/machinery/vending/engivend,/turf/simulated/shuttle/floor/black,/area/shuttle/trade/centcom) @@ -598,14 +598,14 @@ "lz" = (/turf/simulated/shuttle/wall{dir = 2; icon_state = "diagonalWall3"},/area/syndicate_mothership{name = "\improper Ninja Base"}) "lA" = (/obj/item/weapon/paper{info = "Some stuff is missing..."; name = "Insert alien artifacts here."},/turf/unsimulated/floor{icon_state = "dark"},/area/alien) "lB" = (/obj/machinery/door/airlock/hatch,/turf/unsimulated/floor{icon_state = "dark"},/area/alien) -"lC" = (/obj/structure/table/steel_reinforced,/obj/structure/mirror,/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/syndicate_mothership{name = "\improper Ninja Base"}) -"lD" = (/obj/structure/table/steel_reinforced,/obj/item/clothing/mask/balaclava/tactical,/obj/item/clothing/mask/balaclava,/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/syndicate_mothership{name = "\improper Ninja Base"}) -"lE" = (/obj/structure/undies_wardrobe,/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/syndicate_mothership{name = "\improper Ninja Base"}) +"lC" = (/obj/structure/table/steel_reinforced,/obj/item/clothing/mask/balaclava/tactical,/obj/item/clothing/mask/balaclava,/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/syndicate_mothership{name = "\improper Ninja Base"}) +"lD" = (/obj/structure/table/steel_reinforced,/obj/structure/mirror,/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/syndicate_mothership{name = "\improper Ninja Base"}) +"lE" = (/obj/structure/undies_wardrobe,/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/syndicate_mothership{name = "\improper Ninja Base"}) "lF" = (/obj/structure/closet/acloset,/turf/unsimulated/floor{icon_state = "dark"},/area/alien) "lG" = (/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/obj/structure/flora/bush,/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow_corner"; dir = 8},/area/syndicate_mothership) "lH" = (/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/syndicate_mothership{name = "\improper Ninja Base"}) -"lI" = (/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/syndicate_mothership{name = "\improper Ninja Base"}) -"lJ" = (/obj/structure/bed/chair{dir = 1},/obj/effect/landmark{name = "ninjastart"},/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/syndicate_mothership{name = "\improper Ninja Base"}) +"lI" = (/obj/structure/bed/chair{dir = 1},/obj/effect/landmark{name = "ninjastart"},/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/syndicate_mothership{name = "\improper Ninja Base"}) +"lJ" = (/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/syndicate_mothership{name = "\improper Ninja Base"}) "lK" = (/turf/space,/area/shuttle/alien/base) "lL" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/shuttle/plating,/area/syndicate_mothership{name = "\improper Ninja Base"}) "lM" = (/obj/structure/shuttle/engine/heater,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/airless,/area/syndicate_mothership) @@ -614,9 +614,9 @@ "lP" = (/turf/space,/obj/structure/shuttle/engine/propulsion,/turf/simulated/shuttle/plating/airless/carry,/area/syndicate_mothership) "lQ" = (/turf/space,/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_r"},/turf/simulated/shuttle/plating/airless/carry,/area/syndicate_mothership) "lR" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/shuttle/plating,/area/syndicate_mothership{name = "\improper Ninja Base"}) -"lS" = (/obj/machinery/computer/teleporter,/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/syndicate_mothership{name = "\improper Ninja Base"}) -"lT" = (/obj/machinery/teleport/station,/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/syndicate_mothership{name = "\improper Ninja Base"}) -"lU" = (/obj/machinery/teleport/hub,/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/syndicate_mothership{name = "\improper Ninja Base"}) +"lS" = (/obj/machinery/teleport/station,/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/syndicate_mothership{name = "\improper Ninja Base"}) +"lT" = (/obj/machinery/computer/teleporter,/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/syndicate_mothership{name = "\improper Ninja Base"}) +"lU" = (/obj/machinery/teleport/hub,/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/syndicate_mothership{name = "\improper Ninja Base"}) "lV" = (/turf/unsimulated/wall,/area) "lW" = (/obj/structure/shuttle/engine/heater,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/airless,/area/syndicate_mothership{name = "\improper Ninja Base"}) "lX" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdown"; tiles = 0},/obj/effect/step_trigger/teleporter/random{affect_ghosts = 1; name = "escapeshuttle_leave"; teleport_x = 25; teleport_x_offset = 245; teleport_y = 25; teleport_y_offset = 245; teleport_z = 6; teleport_z_offset = 6},/obj/effect/step_trigger/teleporter/random{affect_ghosts = 1; name = "escapeshuttle_leave"; teleport_x = 25; teleport_x_offset = 245; teleport_y = 25; teleport_y_offset = 245; teleport_z = 6; teleport_z_offset = 6},/turf/space,/area/space) @@ -820,10 +820,10 @@ "pN" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/blast/shutters{density = 0; icon_state = "shutter0"; id = "syndieshutters"; name = "Blast Shutters"; opacity = 0},/turf/simulated/shuttle/plating,/area/syndicate_station/start) "pO" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/blast/shutters{density = 0; icon_state = "shutter0"; id = "syndieshutters"; name = "Blast Shutters"; opacity = 0},/turf/simulated/shuttle/plating,/area/syndicate_station/start) "pP" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/syndicate_mothership) -"pQ" = (/turf/unsimulated/floor{ name = "plating"; icon_state = "cult"},/area/syndicate_mothership) -"pR" = (/obj/structure/sign/double/map/left{pixel_y = 32},/turf/unsimulated/floor{ name = "plating"; icon_state = "cult"},/area/syndicate_mothership) -"pS" = (/obj/structure/sign/double/map/right{pixel_y = 32},/turf/unsimulated/floor{ name = "plating"; icon_state = "cult"},/area/syndicate_mothership) -"pT" = (/obj/machinery/vending/snack{name = "hacked Getmore Chocolate Corp"; prices = list()},/turf/unsimulated/floor{ name = "plating"; icon_state = "cult"},/area/syndicate_mothership) +"pQ" = (/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/syndicate_mothership) +"pR" = (/obj/structure/sign/double/map/right{pixel_y = 32},/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/syndicate_mothership) +"pS" = (/obj/structure/sign/double/map/left{pixel_y = 32},/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/syndicate_mothership) +"pT" = (/obj/machinery/vending/snack{name = "hacked Getmore Chocolate Corp"; prices = list()},/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/syndicate_mothership) "pU" = (/obj/structure/table/standard,/obj/machinery/chemical_dispenser/bar_soft/full,/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership) "pV" = (/obj/structure/table/standard,/obj/item/weapon/storage/box/glasses/square{pixel_x = 1; pixel_y = 4},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership) "pW" = (/obj/structure/sink/kitchen{pixel_y = 28},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership) @@ -848,7 +848,7 @@ "qp" = (/obj/machinery/computer/shuttle_control/multi/syndicate,/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) "qq" = (/obj/structure/frame/computer,/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) "qr" = (/obj/structure/table/standard,/obj/machinery/button/remote/blast_door{id = "syndieshutters"; name = "remote shutter control"; req_access = list(150)},/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) -"qs" = (/obj/structure/bed/chair/comfy/black,/turf/unsimulated/floor{ name = "plating"; icon_state = "cult"},/area/syndicate_mothership) +"qs" = (/obj/structure/bed/chair/comfy/black,/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/syndicate_mothership) "qt" = (/obj/machinery/door/airlock/centcom{name = "Kitchen"; opacity = 1; req_access = list(150)},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership) "qu" = (/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership) "qv" = (/obj/structure/table/reinforced,/obj/machinery/microwave{pixel_x = -1; pixel_y = 8},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership) @@ -869,10 +869,10 @@ "qK" = (/obj/structure/table/standard,/obj/machinery/microwave{pixel_x = -1; pixel_y = 2},/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) "qL" = (/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) "qM" = (/obj/structure/bed/chair{dir = 1},/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) -"qN" = (/obj/structure/bed/chair/comfy/black{dir = 4},/turf/unsimulated/floor{ name = "plating"; icon_state = "cult"},/area/syndicate_mothership) -"qO" = (/obj/item/weapon/folder{pixel_y = 2},/obj/structure/table/glass,/turf/unsimulated/floor{ name = "plating"; icon_state = "cult"},/area/syndicate_mothership) -"qP" = (/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen{pixel_y = 4},/obj/structure/table/glass,/turf/unsimulated/floor{ name = "plating"; icon_state = "cult"},/area/syndicate_mothership) -"qQ" = (/obj/structure/bed/chair/comfy/black{dir = 8},/turf/unsimulated/floor{ name = "plating"; icon_state = "cult"},/area/syndicate_mothership) +"qN" = (/obj/structure/bed/chair/comfy/black{dir = 4},/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/syndicate_mothership) +"qO" = (/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen{pixel_y = 4},/obj/structure/table/glass,/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/syndicate_mothership) +"qP" = (/obj/item/weapon/folder{pixel_y = 2},/obj/structure/table/glass,/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/syndicate_mothership) +"qQ" = (/obj/structure/bed/chair/comfy/black{dir = 8},/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/syndicate_mothership) "qR" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/donkpockets{pixel_x = 3; pixel_y = 3},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership) "qS" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/syndicate/black/green,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/syndicate/black/green,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) "qT" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/syndicate/black/blue,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/syndicate/black/blue,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) @@ -884,20 +884,20 @@ "qZ" = (/obj/structure/closet/crate/medical,/obj/item/weapon/surgical/circular_saw,/obj/item/weapon/surgical/surgicaldrill,/obj/item/weapon/surgical/bonegel{pixel_x = 4; pixel_y = 3},/obj/item/weapon/surgical/bonesetter,/obj/item/weapon/surgical/scalpel,/obj/item/weapon/surgical/retractor{pixel_x = 0; pixel_y = 6},/obj/item/weapon/surgical/hemostat{pixel_y = 4},/obj/item/weapon/surgical/cautery{pixel_y = 4},/obj/item/weapon/surgical/FixOVein{pixel_x = -6; pixel_y = 1},/obj/item/stack/nanopaste,/obj/item/weapon/tank/anesthetic,/obj/item/clothing/mask/breath/medical,/obj/item/clothing/mask/surgical,/obj/item/clothing/mask/surgical,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) "ra" = (/turf/space,/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion"; dir = 8},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/specops/centcom) "rb" = (/obj/structure/shuttle/engine/heater{icon_state = "heater"; dir = 8},/obj/structure/window/reinforced{dir = 4; health = 1e+006},/turf/simulated/shuttle/plating/airless,/area/shuttle/specops/centcom) -"rc" = (/obj/machinery/computer/security/telescreen{desc = ""; name = "Spec. Ops. Monitor"; network = list("NETWORK_ERT"); pixel_y = 30},/obj/machinery/computer/shuttle_control/specops,/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/shuttle/specops/centcom) -"rd" = (/obj/structure/bed/chair,/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/shuttle/specops/centcom) -"re" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "specops_shuttle_port"; name = "port docking hatch controller"; pixel_x = 0; pixel_y = 25; tag_door = "specops_shuttle_port_hatch"},/obj/structure/bed/chair,/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/shuttle/specops/centcom) -"rf" = (/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/shuttle/specops/centcom) -"rg" = (/obj/machinery/recharger/wallcharger{pixel_x = 4; pixel_y = 32},/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/shuttle/specops/centcom) -"rh" = (/obj/machinery/recharger/wallcharger{pixel_x = 4; pixel_y = 32},/obj/machinery/vending/wallmed1{layer = 3.3; name = "Emergency NanoMed"; pixel_x = 28; pixel_y = 0},/obj/machinery/light{dir = 4},/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/shuttle/specops/centcom) +"rc" = (/obj/structure/bed/chair,/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/shuttle/specops/centcom) +"rd" = (/obj/machinery/computer/security/telescreen{desc = ""; name = "Spec. Ops. Monitor"; network = list("NETWORK_ERT"); pixel_y = 30},/obj/machinery/computer/shuttle_control/specops,/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/shuttle/specops/centcom) +"re" = (/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/shuttle/specops/centcom) +"rf" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "specops_shuttle_port"; name = "port docking hatch controller"; pixel_x = 0; pixel_y = 25; tag_door = "specops_shuttle_port_hatch"},/obj/structure/bed/chair,/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/shuttle/specops/centcom) +"rg" = (/obj/machinery/recharger/wallcharger{pixel_x = 4; pixel_y = 32},/obj/machinery/vending/wallmed1{layer = 3.3; name = "Emergency NanoMed"; pixel_x = 28; pixel_y = 0},/obj/machinery/light{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/shuttle/specops/centcom) +"rh" = (/obj/machinery/recharger/wallcharger{pixel_x = 4; pixel_y = 32},/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/shuttle/specops/centcom) "ri" = (/turf/simulated/shuttle/wall/dark{hard_corner = 1; join_group = "shuttle_ert"},/area/shuttle/specops/centcom) "rj" = (/obj/effect/floor_decal/corner/blue/diagonal{dir = 4},/obj/effect/floor_decal/corner/red/diagonal,/obj/machinery/door/airlock/glass,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/specops) "rk" = (/obj/item/weapon/stool/padded,/obj/effect/floor_decal/corner/red/diagonal,/obj/effect/floor_decal/corner/blue/diagonal{dir = 4},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/specops) "rl" = (/obj/structure/table/standard,/obj/item/weapon/storage/box/donkpockets{pixel_x = 2; pixel_y = 3},/obj/machinery/light{dir = 8; icon_state = "tube1"; pixel_y = 0},/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) "rm" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) "rn" = (/obj/structure/frame/computer,/obj/machinery/light{dir = 4},/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) -"ro" = (/obj/structure/bed/chair/comfy/black{dir = 1},/turf/unsimulated/floor{ name = "plating"; icon_state = "cult"},/area/syndicate_mothership) -"rp" = (/obj/machinery/vending/cola{name = "hacked Robust Softdrinks"; prices = list()},/turf/unsimulated/floor{ name = "plating"; icon_state = "cult"},/area/syndicate_mothership) +"ro" = (/obj/structure/bed/chair/comfy/black{dir = 1},/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/syndicate_mothership) +"rp" = (/obj/machinery/vending/cola{name = "hacked Robust Softdrinks"; prices = list()},/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/syndicate_mothership) "rq" = (/obj/structure/closet/secure_closet/freezer/kitchen{req_access = list(150)},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership) "rr" = (/obj/structure/reagent_dispensers/beerkeg/fakenuke,/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership) "rs" = (/obj/structure/table/reinforced,/obj/item/weapon/tray{pixel_y = 5},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership) @@ -906,20 +906,20 @@ "rv" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/syndicate/black/orange,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/syndicate/black/orange,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) "rw" = (/obj/machinery/iv_drip,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) "rx" = (/obj/structure/shuttle/engine/heater{icon_state = "heater"; dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/shuttle/plating/airless,/area/shuttle/specops/centcom) -"ry" = (/obj/structure/bed/chair{dir = 4},/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/shuttle/specops/centcom) -"rz" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "specops_shuttle_fore"; name = "forward docking hatch controller"; pixel_x = 0; pixel_y = -25; tag_door = "specops_shuttle_fore_hatch"},/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/shuttle/specops/centcom) +"ry" = (/obj/structure/bed/chair{dir = 4},/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/shuttle/specops/centcom) +"rz" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "specops_shuttle_fore"; name = "forward docking hatch controller"; pixel_x = 0; pixel_y = -25; tag_door = "specops_shuttle_fore_hatch"},/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/shuttle/specops/centcom) "rA" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "specops_shuttle_fore_hatch"; locked = 1; name = "Forward Docking Hatch"; req_access = list(13)},/turf/simulated/shuttle/plating,/area/shuttle/specops/centcom) -"rB" = (/obj/effect/floor_decal/corner/blue/diagonal{dir = 4},/obj/effect/floor_decal/corner/red/diagonal,/mob/living/simple_animal/corgi/puppy{name = "Bockscar"},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/specops) +"rB" = (/obj/effect/floor_decal/corner/blue/diagonal{dir = 4},/obj/effect/floor_decal/corner/red/diagonal,/mob/living/simple_mob/animal/passive/dog/corgi/puppy{name = "Bockscar"},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/specops) "rC" = (/obj/structure/table/standard,/obj/item/stack/material/glass{amount = 15},/obj/item/weapon/cell{charge = 100; maxcharge = 15000},/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) "rD" = (/obj/item/device/radio/intercom{desc = "Talk through this. Evilly"; frequency = 1213; name = "Syndicate Intercom"; pixel_y = -32; subspace_transmission = 1; syndie = 1},/obj/machinery/light,/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) "rE" = (/obj/structure/table/standard,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 8},/obj/item/weapon/pen{pixel_y = 4},/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) -"rF" = (/obj/machinery/vending/cigarette{name = "hacked cigarette machine"; prices = list(); products = list(/obj/item/weapon/storage/fancy/cigarettes = 10, /obj/item/weapon/storage/box/matches = 10, /obj/item/weapon/flame/lighter/zippo = 4, /obj/item/clothing/mask/smokable/cigarette/cigar/havana = 2)},/turf/unsimulated/floor{ name = "plating"; icon_state = "cult"},/area/syndicate_mothership) +"rF" = (/obj/machinery/vending/cigarette{name = "hacked cigarette machine"; prices = list(); products = list(/obj/item/weapon/storage/fancy/cigarettes = 10, /obj/item/weapon/storage/box/matches = 10, /obj/item/weapon/flame/lighter/zippo = 4, /obj/item/clothing/mask/smokable/cigarette/cigar/havana = 2)},/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/syndicate_mothership) "rG" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/syndicate/black/engie,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/syndicate/black/engie,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) "rH" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/syndicate/black/red,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/syndicate/black/red,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) -"rI" = (/obj/machinery/computer/communications,/obj/item/device/radio/intercom{broadcasting = 0; dir = 1; frequency = 1443; listening = 1; name = "Spec Ops Intercom"; pixel_y = -28},/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/shuttle/specops/centcom) -"rJ" = (/obj/machinery/computer/prisoner{name = "Implant Management"},/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/shuttle/specops/centcom) -"rK" = (/obj/structure/bed/chair{dir = 1},/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/shuttle/specops/centcom) -"rL" = (/obj/structure/bed/chair{dir = 1},/obj/machinery/light{dir = 4},/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/shuttle/specops/centcom) +"rI" = (/obj/machinery/computer/prisoner{name = "Implant Management"},/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/shuttle/specops/centcom) +"rJ" = (/obj/machinery/computer/communications,/obj/item/device/radio/intercom{broadcasting = 0; dir = 1; frequency = 1443; listening = 1; name = "Spec Ops Intercom"; pixel_y = -28},/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/shuttle/specops/centcom) +"rK" = (/obj/structure/bed/chair{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/shuttle/specops/centcom) +"rL" = (/obj/structure/bed/chair{dir = 1},/obj/machinery/light{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/shuttle/specops/centcom) "rM" = (/obj/effect/floor_decal/corner/blue/diagonal{dir = 4},/obj/effect/floor_decal/corner/red/diagonal,/obj/item/weapon/stool/padded,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/specops) "rN" = (/obj/structure/table/standard,/obj/item/weapon/storage/box/donkpockets{pixel_x = 3; pixel_y = 3},/obj/item/weapon/material/kitchen/rollingpin,/obj/effect/floor_decal/corner/blue/diagonal{dir = 4},/obj/effect/floor_decal/corner/red/diagonal,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/specops) "rO" = (/turf/unsimulated/wall,/area/centcom/command) @@ -1038,8 +1038,8 @@ "tX" = (/turf/simulated/shuttle/floor/black,/area/syndicate_station/start) "tY" = (/obj/item/weapon/cigbutt,/turf/simulated/shuttle/floor/black,/area/syndicate_station/start) "tZ" = (/obj/machinery/door/window{dir = 2; name = "Seating"; req_access = list(150)},/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) -"ua" = (/obj/machinery/door/window{ name = "Seating"; icon_state = "right"; dir = 2; req_access = list(150)},/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) -"ub" = (/obj/structure/flora/pottedplant{ icon_state = "plant-10"},/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) +"ua" = (/obj/machinery/door/window{name = "Seating"; icon_state = "right"; dir = 2; req_access = list(150)},/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) +"ub" = (/obj/structure/flora/pottedplant{icon_state = "plant-10"},/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) "uc" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1331; id_tag = "merc_shuttle_pump"},/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) "ud" = (/obj/machinery/atmospherics/pipe/manifold4w/visible,/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) "ue" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1331; id_tag = "merc_shuttle_pump"},/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) @@ -1072,17 +1072,17 @@ "uF" = (/obj/structure/table/rack,/obj/item/device/radio,/obj/item/device/radio,/obj/item/device/radio,/obj/item/device/radio,/obj/item/device/radio,/obj/item/device/radio,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) "uG" = (/obj/structure/table/rack,/obj/item/weapon/gun/energy/gun,/obj/item/weapon/gun/energy/gun,/obj/item/weapon/gun/energy/gun,/obj/machinery/recharger/wallcharger{pixel_x = 5; pixel_y = -32},/obj/item/weapon/cell/device/weapon,/obj/item/weapon/cell/device/weapon,/obj/item/weapon/cell/device/weapon,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) "uH" = (/obj/structure/table/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 = "dark"},/area/syndicate_mothership) -"uI" = (/turf/space,/obj/structure/shuttle/engine/propulsion{ icon_state = "propulsion_r"; dir = 8},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/administration/centcom) +"uI" = (/turf/space,/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_r"; dir = 8},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/administration/centcom) "uJ" = (/obj/structure/closet{icon_closed = "cabinet_closed"; icon_opened = "cabinet_open"; icon_state = "cabinet_closed"; name = "Clothing Storage"},/obj/item/weapon/storage/box/syndie_kit/chameleon,/obj/item/weapon/stamp/chameleon,/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/command) "uK" = (/obj/structure/table/woodentable{dir = 5},/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/command) "uL" = (/obj/structure/closet{icon_closed = "cabinet_closed"; icon_opened = "cabinet_open"; icon_state = "cabinet_closed"},/obj/item/weapon/card/id/centcom,/obj/item/weapon/card/id/syndicate,/obj/item/weapon/card/id,/obj/item/weapon/card/id/gold,/obj/item/weapon/card/id/silver,/obj/item/device/pda/captain,/obj/item/device/pda/ert,/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/command) "uM" = (/obj/machinery/vending/cigarette{name = "hacked cigarette machine"; prices = list(); products = list(/obj/item/weapon/storage/fancy/cigarettes = 10, /obj/item/weapon/storage/box/matches = 10, /obj/item/weapon/flame/lighter/zippo = 4, /obj/item/clothing/mask/smokable/cigarette/cigar/havana = 2)},/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) "uN" = (/obj/structure/bed/chair{dir = 8},/obj/machinery/button/flasher{id = "syndieflash"; name = "Flasher"; pixel_x = 27; pixel_y = 0},/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) "uO" = (/obj/machinery/button/remote/blast_door{id = "smindicate"; name = "ship lockdown control"; pixel_x = -25},/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) -"uP" = (/mob/living/simple_animal/cat/kitten{name = "Enola"},/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) +"uP" = (/mob/living/simple_mob/animal/passive/cat/kitten{name = "Enola"},/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) "uQ" = (/obj/machinery/atmospherics/pipe/tank/air{dir = 4; start_pressure = 740.5},/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) "uR" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/obj/machinery/meter,/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) -"uS" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1331; master_tag = "merc_shuttle"; name = "interior access button"; pixel_x = 25; pixel_y = 25; req_access = list(150)},/obj/machinery/atmospherics/pipe/simple/visible{ icon_state = "intact"; dir = 9},/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) +"uS" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1331; master_tag = "merc_shuttle"; name = "interior access button"; pixel_x = 25; pixel_y = 25; req_access = list(150)},/obj/machinery/atmospherics/pipe/simple/visible{icon_state = "intact"; dir = 9},/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) "uT" = (/obj/machinery/suit_cycler/syndicate{locked = 0},/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) "uU" = (/obj/machinery/door/airlock/centcom{name = "Hardsuit Storage"; opacity = 1},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) "uV" = (/obj/machinery/light,/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom) @@ -1267,9 +1267,9 @@ "ys" = (/obj/structure/bed/chair/office/dark{dir = 1},/turf/unsimulated/floor{dir = 2; icon_state = "dark"},/area/centcom/command) "yt" = (/obj/machinery/computer/pod{id = "NTrasen"; name = "Hull Door Control"},/obj/item/device/radio/intercom{broadcasting = 1; dir = 1; frequency = 1441; name = "Spec Ops Intercom"; pixel_y = 28},/turf/unsimulated/floor{dir = 2; icon_state = "dark"},/area/centcom/command) "yu" = (/obj/machinery/door/airlock/centcom{name = "Courthouse"; opacity = 1},/turf/unsimulated/floor{icon_state = "lino"},/area/centcom/command) -"yv" = (/turf/space,/obj/structure/shuttle/engine/propulsion{icon_state = "burst_l"},/turf/simulated/shuttle/plating/airless/carry{ icon_state = "platform"; dir = 1},/area/supply/dock) -"yw" = (/turf/space,/obj/structure/shuttle/engine/propulsion,/turf/simulated/shuttle/plating/airless/carry{ icon_state = "platform"; dir = 1},/area/supply/dock) -"yx" = (/turf/space,/obj/structure/shuttle/engine/propulsion{icon_state = "burst_r"},/turf/simulated/shuttle/plating/airless/carry{ icon_state = "platform"; dir = 1},/area/supply/dock) +"yv" = (/turf/space,/obj/structure/shuttle/engine/propulsion{icon_state = "burst_l"},/turf/simulated/shuttle/plating/airless/carry{icon_state = "platform"; dir = 1},/area/supply/dock) +"yw" = (/turf/space,/obj/structure/shuttle/engine/propulsion,/turf/simulated/shuttle/plating/airless/carry{icon_state = "platform"; dir = 1},/area/supply/dock) +"yx" = (/turf/space,/obj/structure/shuttle/engine/propulsion{icon_state = "burst_r"},/turf/simulated/shuttle/plating/airless/carry{icon_state = "platform"; dir = 1},/area/supply/dock) "yy" = (/obj/structure/table/reinforced,/obj/item/clothing/head/greenbandana,/obj/effect/floor_decal/corner/orange{dir = 9},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/security) "yz" = (/obj/structure/bed/chair{dir = 1},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/security) "yA" = (/obj/structure/closet/secure_closet/hos,/turf/unsimulated/floor{dir = 2; icon_state = "dark"},/area/centcom/command) @@ -1355,7 +1355,7 @@ "Ac" = (/obj/effect/floor_decal/corner/red,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/security) "Ad" = (/obj/effect/floor_decal/corner/red/full{dir = 4},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/security) "Ae" = (/obj/structure/closet/secure_closet/bar,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/restaurant) -"Af" = (/obj/structure/table/marble,/obj/effect/floor_decal/corner/white/diagonal,/obj/machinery/cash_register/civilian{ icon_state = "register_idle"; dir = 8},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/restaurant) +"Af" = (/obj/structure/table/marble,/obj/effect/floor_decal/corner/white/diagonal,/obj/machinery/cash_register/civilian{icon_state = "register_idle"; dir = 8},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/restaurant) "Ag" = (/obj/structure/table/standard,/obj/effect/floor_decal/corner/white/diagonal,/obj/item/weapon/reagent_containers/food/condiment/small/peppermill,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/restaurant) "Ah" = (/obj/machinery/computer/supplycomp/control,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/command) "Ai" = (/obj/machinery/button/remote/blast_door{id = "crescent_checkpoint_access"; name = "Crescent Checkpoint Access"; pixel_x = -6; pixel_y = -24; req_access = list(101)},/obj/machinery/button/remote/blast_door{id = "crescent_thunderdome"; name = "Thunderdome Access"; pixel_x = 6; pixel_y = -24; req_access = list(101)},/obj/machinery/button/remote/blast_door{id = "crescent_vip_shuttle"; name = "VIP Shuttle Access"; pixel_x = 6; pixel_y = -34; req_access = list(101)},/obj/machinery/turretid{pixel_x = 28; pixel_y = -28; req_access = list(101)},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/command) @@ -1401,7 +1401,7 @@ "AW" = (/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/tram) "AX" = (/obj/structure/bed/chair,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/tram) "AY" = (/obj/effect/wingrille_spawn/reinforced/crescent,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/tram) -"AZ" = (/turf/space,/obj/structure/shuttle/engine/propulsion{ icon_state = "burst_l"; dir = 4},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/transport1/centcom) +"AZ" = (/turf/space,/obj/structure/shuttle/engine/propulsion{icon_state = "burst_l"; dir = 4},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/transport1/centcom) "Ba" = (/obj/machinery/computer/security,/obj/effect/floor_decal/corner/red{dir = 6},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/security) "Bb" = (/obj/structure/bed/chair,/obj/effect/floor_decal/corner/white/diagonal,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/restaurant) "Bc" = (/obj/effect/wingrille_spawn/reinforced/crescent,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/main_hall) @@ -1441,7 +1441,7 @@ "BK" = (/obj/structure/window/shuttle,/obj/structure/grille,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/tram) "BL" = (/obj/machinery/door/unpowered/shuttle,/turf/unsimulated/floor{icon = 'icons/turf/flooring/shuttle.dmi'; icon_state = "floor"},/area/centcom/tram) "BM" = (/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/tram) -"BN" = (/obj/effect/floor_decal/corner/white/full{ icon_state = "corner_white_full"; dir = 4},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) +"BN" = (/obj/effect/floor_decal/corner/white/full{icon_state = "corner_white_full"; dir = 4},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) "BO" = (/obj/effect/floor_decal/corner/white,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) "BP" = (/obj/effect/floor_decal/corner/white{dir = 5},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) "BQ" = (/obj/effect/floor_decal/corner/white{dir = 8},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) @@ -1453,7 +1453,7 @@ "BW" = (/obj/structure/bed/chair,/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 0; pixel_y = 26},/turf/simulated/shuttle/floor,/area/centcom/tram) "BX" = (/obj/effect/floor_decal/spline/plain,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/tram) "BY" = (/obj/effect/floor_decal/corner/white{dir = 6; icon_state = "corner_white"},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) -"BZ" = (/obj/effect/floor_decal/corner/white/diagonal{ icon_state = "corner_white_diagonal"; dir = 4},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) +"BZ" = (/obj/effect/floor_decal/corner/white/diagonal{icon_state = "corner_white_diagonal"; dir = 4},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) "Ca" = (/obj/effect/floor_decal/corner/white{dir = 4},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) "Cb" = (/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/window/brigdoor{dir = 4; name = "Weapons locker"},/obj/structure/table/rack,/obj/item/clothing/suit/armor/riot,/obj/item/weapon/melee/baton/loaded,/obj/item/weapon/shield/riot,/obj/item/clothing/head/helmet/riot,/obj/structure/window/reinforced,/obj/effect/floor_decal/corner/red{dir = 9},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/security) "Cc" = (/obj/machinery/porta_turret/crescent,/obj/effect/floor_decal/industrial/hatch/yellow,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/main_hall) @@ -1462,12 +1462,12 @@ "Cf" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/shuttle/floor,/area/centcom/tram) "Cg" = (/obj/structure/bed/chair{dir = 8},/turf/simulated/shuttle/floor,/area/centcom/tram) "Ch" = (/obj/effect/floor_decal/spline/plain{dir = 1},/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/tram) -"Ci" = (/obj/effect/floor_decal/corner/white{ icon_state = "corner_white"; dir = 1},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) +"Ci" = (/obj/effect/floor_decal/corner/white{icon_state = "corner_white"; dir = 1},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) "Cj" = (/obj/machinery/computer/card,/obj/effect/floor_decal/corner/red{dir = 6},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/security) "Ck" = (/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/window/brigdoor{dir = 4; name = "Weapons locker"},/obj/structure/table/rack,/obj/item/clothing/suit/armor/riot,/obj/item/weapon/melee/baton/loaded,/obj/item/weapon/shield/riot,/obj/item/clothing/head/helmet/riot,/obj/structure/window/reinforced{dir = 1},/obj/effect/floor_decal/corner/red{dir = 9},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/security) "Cl" = (/obj/effect/wingrille_spawn/reinforced/crescent,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/restaurant) "Cm" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/machinery/door/airlock/glass,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/restaurant) -"Cn" = (/obj/structure/flora/grass/brown,/obj/effect/floor_decal/spline/fancy/wood{ icon_state = "spline_fancy"; dir = 9},/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/centcom/main_hall) +"Cn" = (/obj/structure/flora/grass/brown,/obj/effect/floor_decal/spline/fancy/wood{icon_state = "spline_fancy"; dir = 9},/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/centcom/main_hall) "Co" = (/obj/structure/flora/ausbushes/ppflowers,/obj/effect/floor_decal/spline/fancy/wood/cee{dir = 4},/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/centcom/main_hall) "Cp" = (/obj/effect/floor_decal/spline/plain{dir = 1},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/main_hall) "Cq" = (/obj/structure/flora/ausbushes/brflowers,/obj/effect/floor_decal/spline/fancy/wood/cee{dir = 8},/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/centcom/main_hall) @@ -1489,10 +1489,10 @@ "CG" = (/obj/structure/flora/ausbushes/ppflowers,/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/centcom/main_hall) "CH" = (/obj/structure/flora/bush,/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/centcom/main_hall) "CI" = (/obj/structure/flora/ausbushes/sparsegrass,/obj/structure/flora/ausbushes/ppflowers,/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/centcom/main_hall) -"CJ" = (/obj/structure/flora/ausbushes/ywflowers,/obj/effect/floor_decal/spline/fancy/wood{ icon_state = "spline_fancy"; dir = 9},/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/centcom/main_hall) +"CJ" = (/obj/structure/flora/ausbushes/ywflowers,/obj/effect/floor_decal/spline/fancy/wood{icon_state = "spline_fancy"; dir = 9},/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/centcom/main_hall) "CK" = (/obj/structure/flora/ausbushes/brflowers,/obj/effect/floor_decal/spline/fancy/wood{dir = 6},/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/centcom/main_hall) "CL" = (/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/main_hall) -"CM" = (/obj/structure/flora/ausbushes/fernybush,/obj/effect/floor_decal/spline/fancy/wood{ icon_state = "spline_fancy"; dir = 10},/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/centcom/main_hall) +"CM" = (/obj/structure/flora/ausbushes/fernybush,/obj/effect/floor_decal/spline/fancy/wood{icon_state = "spline_fancy"; dir = 10},/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/centcom/main_hall) "CN" = (/obj/structure/flora/ausbushes/brflowers,/obj/effect/floor_decal/spline/fancy/wood{dir = 5},/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/centcom/main_hall) "CO" = (/obj/structure/flora/ausbushes/sparsegrass,/obj/structure/flora/ausbushes/brflowers,/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/centcom/main_hall) "CP" = (/obj/machinery/turretid{pixel_x = -28; pixel_y = 0; req_access = list(101)},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/tram) @@ -1503,9 +1503,9 @@ "CU" = (/obj/structure/table/woodentable{dir = 5},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/terminal) "CV" = (/obj/structure/table/reinforced,/obj/machinery/computer/skills,/obj/structure/window/reinforced{dir = 2; health = 1e+006},/obj/structure/window/reinforced{dir = 8},/obj/effect/floor_decal/corner/red/full,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/security) "CW" = (/obj/structure/table/reinforced,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/pen,/obj/machinery/door/window/southright{name = "Arrivals Processing"; req_access = list(101)},/obj/structure/window/reinforced{dir = 4},/obj/effect/floor_decal/corner/red/full{dir = 4},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/security) -"CX" = (/obj/structure/flora/ausbushes/brflowers,/obj/effect/floor_decal/spline/fancy/wood{ icon_state = "spline_fancy"; dir = 9},/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/centcom/main_hall) +"CX" = (/obj/structure/flora/ausbushes/brflowers,/obj/effect/floor_decal/spline/fancy/wood{icon_state = "spline_fancy"; dir = 9},/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/centcom/main_hall) "CY" = (/obj/structure/flora/ausbushes/ppflowers,/obj/effect/floor_decal/spline/fancy/wood{dir = 6},/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/centcom/main_hall) -"CZ" = (/obj/structure/flora/ausbushes/ppflowers,/obj/effect/floor_decal/spline/fancy/wood{ icon_state = "spline_fancy"; dir = 10},/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/centcom/main_hall) +"CZ" = (/obj/structure/flora/ausbushes/ppflowers,/obj/effect/floor_decal/spline/fancy/wood{icon_state = "spline_fancy"; dir = 10},/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/centcom/main_hall) "Da" = (/obj/machinery/door/airlock/centcom{name = "General Access"; opacity = 1; req_access = list(101)},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/main_hall) "Db" = (/obj/structure/bed/chair/office/dark,/obj/machinery/button/remote/blast_door{desc = "A remote control switch for port-side blast doors."; id = "CentComPortEast"; name = "Security Doors"; pixel_x = -12; pixel_y = -25; req_access = list(101)},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/tram) "Dc" = (/obj/machinery/computer/secure_data,/obj/machinery/camera/network/crescent{c_tag = "Crescent Arrivals North"; dir = 8},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/tram) @@ -1520,9 +1520,9 @@ "Dl" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/table/reinforced,/obj/structure/window/reinforced{dir = 1; health = 1e+006},/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/pen,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/terminal) "Dm" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "CentComPortWest"; name = "Security Doors"; opacity = 0},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/main_hall) "Dn" = (/obj/structure/flora/ausbushes/ppflowers,/obj/effect/floor_decal/spline/fancy/wood/cee,/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/centcom/main_hall) -"Do" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/beach/sand{ icon_state = "seashallow"},/area/centcom/main_hall) -"Dp" = (/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/beach/sand{ icon_state = "seashallow"},/area/centcom/main_hall) -"Dq" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/beach/sand{ icon_state = "seashallow"},/area/centcom/main_hall) +"Do" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/beach/sand{icon_state = "seashallow"},/area/centcom/main_hall) +"Dp" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/beach/sand{icon_state = "seashallow"},/area/centcom/main_hall) +"Dq" = (/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/beach/sand{icon_state = "seashallow"},/area/centcom/main_hall) "Dr" = (/obj/structure/table/reinforced,/obj/structure/window/reinforced,/obj/machinery/computer/skills,/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/tram) "Ds" = (/obj/structure/table/reinforced,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/pen,/obj/machinery/door/window/southright{name = "Arrivals Processing"; req_access = list(101)},/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/tram) "Dt" = (/obj/machinery/door/airlock/external,/obj/effect/floor_decal/industrial/warning{dir = 1},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/tram) @@ -1533,7 +1533,7 @@ "Dy" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/table/reinforced,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/terminal) "Dz" = (/obj/machinery/door/airlock/glass,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/main_hall) "DA" = (/obj/effect/floor_decal/spline/plain{dir = 8},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/main_hall) -"DB" = (/turf/unsimulated/beach/sand{ icon_state = "seashallow"},/area/centcom/main_hall) +"DB" = (/turf/unsimulated/beach/sand{icon_state = "seashallow"},/area/centcom/main_hall) "DC" = (/obj/effect/floor_decal/spline/plain{dir = 4},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/main_hall) "DD" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "CentComPortEast"; name = "Security Doors"; opacity = 0},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/tram) "DE" = (/obj/machinery/door/blast/regular{id = "CentComPortEast"; name = "Security Doors"},/turf/unsimulated/floor{icon_state = "green"; dir = 8},/area/centcom/tram) @@ -1542,14 +1542,14 @@ "DH" = (/obj/machinery/hologram/holopad,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/terminal) "DI" = (/obj/machinery/door/window/westright,/obj/structure/table/reinforced,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/terminal) "DJ" = (/obj/structure/bed/chair/office/light{dir = 8},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/terminal) -"DK" = (/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/beach/sand{ icon_state = "seashallow"},/area/centcom/main_hall) -"DL" = (/obj/effect/floor_decal/spline/plain{ icon_state = "spline_plain_full"; dir = 1},/obj/structure/showcase,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/main_hall) -"DM" = (/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/beach/sand{ icon_state = "seashallow"},/area/centcom/main_hall) +"DK" = (/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/beach/sand{icon_state = "seashallow"},/area/centcom/main_hall) +"DL" = (/obj/effect/floor_decal/spline/plain{icon_state = "spline_plain_full"; dir = 1},/obj/structure/showcase,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/main_hall) +"DM" = (/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/beach/sand{icon_state = "seashallow"},/area/centcom/main_hall) "DN" = (/obj/structure/bed/chair/office/light,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/terminal) "DO" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/table/reinforced,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/terminal) "DP" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/table/reinforced,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/pen,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/terminal) -"DQ" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/beach/sand{ icon_state = "seashallow"},/area/centcom/main_hall) -"DR" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/unsimulated/beach/sand{ icon_state = "seashallow"},/area/centcom/main_hall) +"DQ" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/beach/sand{icon_state = "seashallow"},/area/centcom/main_hall) +"DR" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/unsimulated/beach/sand{icon_state = "seashallow"},/area/centcom/main_hall) "DS" = (/obj/machinery/door/window/southleft,/obj/structure/table/reinforced,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/terminal) "DT" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/table/reinforced,/obj/structure/window/reinforced,/obj/machinery/computer/skills,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/terminal) "DU" = (/obj/structure/bed/chair{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/effect/floor_decal/spline/plain{dir = 1},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/terminal) @@ -1561,16 +1561,16 @@ "Ea" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/table/reinforced,/obj/structure/window/reinforced,/obj/machinery/computer/skills,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/terminal) "Eb" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/table/reinforced,/obj/structure/window/reinforced,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/pen,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/terminal) "Ec" = (/obj/structure/flora/ausbushes/ppflowers,/obj/effect/floor_decal/spline/fancy/wood/cee{dir = 1},/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/centcom/main_hall) -"Ed" = (/obj/structure/window/reinforced,/turf/unsimulated/beach/sand{ icon_state = "seashallow"},/area/centcom/main_hall) -"Ee" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/beach/sand{ icon_state = "seashallow"},/area/centcom/main_hall) +"Ed" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/beach/sand{icon_state = "seashallow"},/area/centcom/main_hall) +"Ee" = (/obj/structure/window/reinforced,/turf/unsimulated/beach/sand{icon_state = "seashallow"},/area/centcom/main_hall) "Ef" = (/obj/structure/flora/ausbushes/brflowers,/obj/effect/floor_decal/spline/fancy/wood/cee{dir = 1},/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/centcom/main_hall) "Eg" = (/obj/machinery/door/airlock/glass,/turf/unsimulated/floor{icon_state = "lino"},/area/centcom/tram) "Eh" = (/turf/unsimulated/wall,/area/centcom/medical) "Ei" = (/obj/machinery/door/airlock/glass_medical{name = "Arrivals Medbay"},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) "Ej" = (/obj/effect/wingrille_spawn/reinforced/crescent,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/medical) -"Ek" = (/obj/structure/flora/ausbushes/ywflowers,/obj/effect/floor_decal/spline/fancy/wood{ icon_state = "spline_fancy"; dir = 10},/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/centcom/main_hall) +"Ek" = (/obj/structure/flora/ausbushes/ywflowers,/obj/effect/floor_decal/spline/fancy/wood{icon_state = "spline_fancy"; dir = 10},/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/centcom/main_hall) "El" = (/obj/structure/flora/grass/brown,/obj/effect/floor_decal/spline/fancy/wood{dir = 5},/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/centcom/main_hall) -"Em" = (/obj/structure/flora/ausbushes/ppflowers,/obj/effect/floor_decal/spline/fancy/wood{ icon_state = "spline_fancy"; dir = 9},/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/centcom/main_hall) +"Em" = (/obj/structure/flora/ausbushes/ppflowers,/obj/effect/floor_decal/spline/fancy/wood{icon_state = "spline_fancy"; dir = 9},/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/centcom/main_hall) "En" = (/obj/structure/flora/ausbushes/ywflowers,/obj/effect/floor_decal/spline/fancy/wood{dir = 6},/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/centcom/main_hall) "Eo" = (/turf/unsimulated/floor{icon_state = "lino"},/area/centcom/tram) "Ep" = (/obj/machinery/vending/cigarette,/turf/unsimulated/floor{icon_state = "lino"},/area/centcom/tram) @@ -1589,7 +1589,7 @@ "EC" = (/obj/effect/floor_decal/corner/beige{dir = 5},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) "ED" = (/obj/machinery/chem_master,/obj/effect/floor_decal/corner/beige/full{dir = 1},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) "EE" = (/obj/structure/flora/ausbushes,/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/centcom/main_hall) -"EF" = (/obj/structure/flora/ausbushes/brflowers,/obj/effect/floor_decal/spline/fancy/wood{ icon_state = "spline_fancy"; dir = 10},/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/centcom/main_hall) +"EF" = (/obj/structure/flora/ausbushes/brflowers,/obj/effect/floor_decal/spline/fancy/wood{icon_state = "spline_fancy"; dir = 10},/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/centcom/main_hall) "EG" = (/obj/structure/flora/ausbushes/ppflowers,/obj/effect/floor_decal/spline/fancy/wood{dir = 5},/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/centcom/main_hall) "EH" = (/obj/structure/flora/ausbushes/sparsegrass,/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/centcom/main_hall) "EI" = (/obj/structure/flora/bush,/obj/structure/flora/ausbushes/sparsegrass,/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/centcom/main_hall) @@ -1600,7 +1600,7 @@ "EN" = (/obj/machinery/chemical_dispenser/ert,/obj/item/weapon/reagent_containers/glass/beaker/large,/obj/effect/floor_decal/corner/beige{dir = 6},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) "EO" = (/turf/unsimulated/wall,/area/centcom/bar) "EP" = (/obj/effect/wingrille_spawn/reinforced/crescent,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/bar) -"EQ" = (/obj/machinery/door/airlock/glass,/turf/unsimulated/floor{ icon_state = "wood"},/area/centcom/bar) +"EQ" = (/obj/machinery/door/airlock/glass,/turf/unsimulated/floor{icon_state = "wood"},/area/centcom/bar) "ER" = (/obj/effect/floor_decal/spline/plain,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/main_hall) "ES" = (/turf/unsimulated/wall,/area/centcom/bathroom) "ET" = (/obj/machinery/door/airlock,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bathroom) @@ -1610,8 +1610,8 @@ "EX" = (/obj/structure/bed/chair{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/effect/floor_decal/corner/green{dir = 9},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) "EY" = (/obj/structure/closet/secure_closet/chemical,/obj/effect/floor_decal/corner/beige{dir = 9},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) "EZ" = (/obj/structure/table/standard,/obj/item/weapon/reagent_containers/glass/beaker/large,/obj/item/weapon/reagent_containers/glass/beaker/large,/obj/effect/floor_decal/corner/beige{dir = 6},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) -"Fa" = (/obj/structure/table/woodentable{dir = 5},/obj/structure/flora/pottedplant{pixel_y = 8},/turf/unsimulated/floor{ icon_state = "wood"},/area/centcom/bar) -"Fb" = (/turf/unsimulated/floor{ icon_state = "wood"},/area/centcom/bar) +"Fa" = (/turf/unsimulated/floor{icon_state = "wood"},/area/centcom/bar) +"Fb" = (/obj/structure/table/woodentable{dir = 5},/obj/structure/flora/pottedplant{pixel_y = 8},/turf/unsimulated/floor{icon_state = "wood"},/area/centcom/bar) "Fc" = (/obj/structure/table/steel,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bathroom) "Fd" = (/obj/structure/closet/secure_closet/personal,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bathroom) "Fe" = (/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bathroom) @@ -1634,22 +1634,22 @@ "Fv" = (/obj/effect/floor_decal/corner/beige{dir = 8},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) "Fw" = (/obj/effect/floor_decal/corner/beige,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) "Fx" = (/obj/machinery/chem_master,/obj/effect/floor_decal/corner/beige/full{dir = 4},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) -"Fy" = (/obj/structure/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 4},/turf/unsimulated/floor{ icon_state = "wood"},/area/centcom/bar) -"Fz" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/amanita_pie,/turf/unsimulated/floor{ icon_state = "wood"},/area/centcom/bar) -"FA" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/bigbiteburger,/turf/unsimulated/floor{ icon_state = "wood"},/area/centcom/bar) -"FB" = (/obj/structure/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 8},/turf/unsimulated/floor{ icon_state = "wood"},/area/centcom/bar) -"FC" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/slice/carrotcake/filled,/turf/unsimulated/floor{ icon_state = "wood"},/area/centcom/bar) -"FD" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/stew,/turf/unsimulated/floor{ icon_state = "wood"},/area/centcom/bar) +"Fy" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/amanita_pie,/turf/unsimulated/floor{icon_state = "wood"},/area/centcom/bar) +"Fz" = (/obj/structure/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 4},/turf/unsimulated/floor{icon_state = "wood"},/area/centcom/bar) +"FA" = (/obj/structure/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 8},/turf/unsimulated/floor{icon_state = "wood"},/area/centcom/bar) +"FB" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/bigbiteburger,/turf/unsimulated/floor{icon_state = "wood"},/area/centcom/bar) +"FC" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/slice/carrotcake/filled,/turf/unsimulated/floor{icon_state = "wood"},/area/centcom/bar) +"FD" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/stew,/turf/unsimulated/floor{icon_state = "wood"},/area/centcom/bar) "FE" = (/obj/item/weapon/stool/padded,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bathroom) "FF" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "escape_shuttle"; pixel_x = 0; pixel_y = -25; req_one_access = list(13); tag_door = "escape_shuttle_hatch"},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) "FG" = (/obj/machinery/hologram/holopad,/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) "FH" = (/obj/machinery/light,/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) "FI" = (/obj/effect/floor_decal/corner/beige{dir = 6},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) "FJ" = (/obj/structure/closet/secure_closet/medical_wall{name = "Pill Cabinet"},/obj/item/weapon/storage/pill_bottle/antitox,/obj/item/weapon/storage/pill_bottle/tramadol,/obj/item/weapon/reagent_containers/syringe/antiviral,/obj/item/weapon/reagent_containers/syringe/antiviral,/obj/item/weapon/reagent_containers/syringe/inaprovaline,/turf/unsimulated/wall,/area/centcom/medical) -"FK" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/boiledrice,/turf/unsimulated/floor{ icon_state = "wood"},/area/centcom/bar) -"FL" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/beetsoup,/turf/unsimulated/floor{ icon_state = "wood"},/area/centcom/bar) -"FM" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/stuffing,/turf/unsimulated/floor{ icon_state = "wood"},/area/centcom/bar) -"FN" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/soylenviridians,/turf/unsimulated/floor{ icon_state = "wood"},/area/centcom/bar) +"FK" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/boiledrice,/turf/unsimulated/floor{icon_state = "wood"},/area/centcom/bar) +"FL" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/beetsoup,/turf/unsimulated/floor{icon_state = "wood"},/area/centcom/bar) +"FM" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/stuffing,/turf/unsimulated/floor{icon_state = "wood"},/area/centcom/bar) +"FN" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/soylenviridians,/turf/unsimulated/floor{icon_state = "wood"},/area/centcom/bar) "FO" = (/obj/structure/table/standard,/obj/machinery/computer/security/telescreen/entertainment{icon_state = "frame"; pixel_x = -30},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/main_hall) "FP" = (/obj/item/weapon/stool/padded,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/main_hall) "FQ" = (/obj/structure/table/standard,/obj/machinery/computer/security/telescreen/entertainment{icon_state = "frame"; pixel_x = 30},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/main_hall) @@ -1672,10 +1672,10 @@ "Gh" = (/obj/structure/table/glass,/obj/structure/window/reinforced{dir = 1},/obj/effect/floor_decal/corner/green{dir = 5},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) "Gi" = (/obj/structure/table/glass,/obj/machinery/computer/med_data/laptop,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/effect/floor_decal/corner/green/full{dir = 1},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) "Gj" = (/obj/structure/closet/secure_closet/medical3,/obj/effect/floor_decal/corner/green{dir = 6},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) -"Gk" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/bloodsoup,/turf/unsimulated/floor{ icon_state = "wood"},/area/centcom/bar) -"Gl" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/tofukabob,/turf/unsimulated/floor{ icon_state = "wood"},/area/centcom/bar) -"Gm" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/poppypretzel,/turf/unsimulated/floor{ icon_state = "wood"},/area/centcom/bar) -"Gn" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/slice/orangecake/filled,/turf/unsimulated/floor{ icon_state = "wood"},/area/centcom/bar) +"Gk" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/bloodsoup,/turf/unsimulated/floor{icon_state = "wood"},/area/centcom/bar) +"Gl" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/tofukabob,/turf/unsimulated/floor{icon_state = "wood"},/area/centcom/bar) +"Gm" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/poppypretzel,/turf/unsimulated/floor{icon_state = "wood"},/area/centcom/bar) +"Gn" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/slice/orangecake/filled,/turf/unsimulated/floor{icon_state = "wood"},/area/centcom/bar) "Go" = (/obj/machinery/atm{pixel_x = -30},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/main_hall) "Gp" = (/obj/machinery/atm{pixel_x = 30},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/main_hall) "Gq" = (/obj/structure/bed/chair{dir = 4},/obj/machinery/light/small{dir = 1},/turf/simulated/shuttle/floor/red,/area/shuttle/escape/centcom) @@ -1685,10 +1685,10 @@ "Gu" = (/obj/structure/bed/chair/office/light{dir = 1},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) "Gv" = (/obj/machinery/computer/med_data,/obj/effect/floor_decal/corner/green{dir = 5},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) "Gw" = (/obj/machinery/iv_drip,/obj/effect/floor_decal/corner/green{dir = 6},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) -"Gx" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/spesslaw,/turf/unsimulated/floor{ icon_state = "wood"},/area/centcom/bar) -"Gy" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/candiedapple,/turf/unsimulated/floor{ icon_state = "wood"},/area/centcom/bar) -"Gz" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/mushroomsoup,/turf/unsimulated/floor{ icon_state = "wood"},/area/centcom/bar) -"GA" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/meatsteak,/turf/unsimulated/floor{ icon_state = "wood"},/area/centcom/bar) +"Gx" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/spesslaw,/turf/unsimulated/floor{icon_state = "wood"},/area/centcom/bar) +"Gy" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/candiedapple,/turf/unsimulated/floor{icon_state = "wood"},/area/centcom/bar) +"Gz" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/mushroomsoup,/turf/unsimulated/floor{icon_state = "wood"},/area/centcom/bar) +"GA" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/meatsteak,/turf/unsimulated/floor{icon_state = "wood"},/area/centcom/bar) "GB" = (/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/bathroom) "GC" = (/obj/structure/sink{pixel_y = 16},/obj/structure/mirror{pixel_y = 32},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/bathroom) "GD" = (/obj/structure/window/reinforced/tinted{dir = 4; icon_state = "twindow"},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/bathroom) @@ -1712,9 +1712,9 @@ "GV" = (/obj/machinery/door/airlock{name = "Unit 6"},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/bathroom) "GW" = (/obj/structure/table/standard,/obj/item/weapon/storage/firstaid/fire,/obj/item/weapon/storage/firstaid/regular{pixel_x = 2; pixel_y = 3},/obj/item/weapon/extinguisher,/obj/item/weapon/tool/crowbar,/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) "GX" = (/obj/machinery/door/airlock/glass_security{name = "Escape Shuttle Cell"; req_access = list(1)},/turf/simulated/shuttle/floor/red,/area/shuttle/escape/centcom) -"GY" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/flame/lighter/zippo,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/material/ashtray/bronze{pixel_x = -1; pixel_y = 1},/obj/machinery/camera/network/crescent{c_tag = "Crescent Bar East"; dir = 4},/turf/unsimulated/floor{ icon_state = "wood"},/area/centcom/bar) -"GZ" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/flame/lighter/zippo,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/material/ashtray/bronze{pixel_x = -1; pixel_y = 1},/turf/unsimulated/floor{ icon_state = "wood"},/area/centcom/bar) -"Ha" = (/turf/unsimulated/floor{ icon_state = "wood"},/turf/unsimulated/floor{icon_state = "lino"},/area/centcom/bar) +"GY" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/flame/lighter/zippo,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/material/ashtray/bronze{pixel_x = -1; pixel_y = 1},/turf/unsimulated/floor{icon_state = "wood"},/area/centcom/bar) +"GZ" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/flame/lighter/zippo,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/material/ashtray/bronze{pixel_x = -1; pixel_y = 1},/obj/machinery/camera/network/crescent{c_tag = "Crescent Bar East"; dir = 4},/turf/unsimulated/floor{icon_state = "wood"},/area/centcom/bar) +"Ha" = (/turf/unsimulated/floor{icon_state = "wood"},/turf/unsimulated/floor{icon_state = "lino"},/area/centcom/bar) "Hb" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/drinks/glass2/square,/turf/unsimulated/floor{icon_state = "lino"},/area/centcom/bar) "Hc" = (/obj/structure/table/woodentable{dir = 5},/obj/machinery/cash_register/civilian,/turf/unsimulated/floor{icon_state = "lino"},/area/centcom/bar) "Hd" = (/obj/structure/table/standard,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/tdome) @@ -1777,7 +1777,7 @@ "Ii" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 6},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) "Ij" = (/obj/structure/morgue,/obj/effect/floor_decal/corner/blue/full{dir = 8},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) "Ik" = (/obj/effect/floor_decal/corner/blue{dir = 5},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) -"Il" = (/obj/structure/morgue{ icon_state = "morgue1"; dir = 8},/obj/effect/floor_decal/corner/blue/full{dir = 1},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"Il" = (/obj/structure/morgue{icon_state = "morgue1"; dir = 8},/obj/effect/floor_decal/corner/blue/full{dir = 1},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) "Im" = (/obj/machinery/door/airlock/centcom{name = "General Access"; opacity = 1; req_access = list(101)},/obj/machinery/door/blast/regular{id = "crescent_thunderdome"; name = "Thunderdome"},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/tdome) "In" = (/obj/structure/bed/roller,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/structure/closet/secure_closet/medical_wall{name = "O- Blood Locker"; pixel_x = -32},/obj/effect/floor_decal/corner/green{dir = 9},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) "Io" = (/obj/machinery/bodyscanner{dir = 8},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) @@ -1788,7 +1788,7 @@ "It" = (/obj/machinery/atmospherics/portables_connector{dir = 1},/obj/machinery/portable_atmospherics/canister/oxygen/prechilled,/obj/effect/floor_decal/corner/blue,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) "Iu" = (/obj/machinery/atmospherics/portables_connector{dir = 1},/obj/machinery/portable_atmospherics/canister/oxygen/prechilled,/obj/effect/floor_decal/corner/blue/full{dir = 4},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) "Iv" = (/obj/structure/morgue,/obj/effect/floor_decal/corner/blue{dir = 9},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) -"Iw" = (/obj/structure/morgue{ icon_state = "morgue1"; dir = 8},/obj/effect/floor_decal/corner/blue{dir = 6},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) +"Iw" = (/obj/structure/morgue{icon_state = "morgue1"; dir = 8},/obj/effect/floor_decal/corner/blue{dir = 6},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) "Ix" = (/obj/machinery/door/airlock/centcom{name = "General Access"; opacity = 1; req_access = list(101)},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/tdome) "Iy" = (/obj/structure/bed/chair{dir = 4},/obj/structure/closet/walllocker/emerglocker{pixel_x = -28},/obj/machinery/light{dir = 8; icon_state = "tube1"; pixel_y = 0},/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) "Iz" = (/obj/structure/bed/chair{dir = 8},/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 26},/obj/machinery/light{dir = 4},/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) @@ -1860,8 +1860,8 @@ "JN" = (/obj/structure/closet/l3closet/virology,/obj/item/clothing/mask/gas,/obj/effect/floor_decal/industrial/warning{dir = 10},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) "JO" = (/obj/structure/bed/chair,/obj/structure/disposalpipe/segment,/obj/effect/landmark{name = "tdomeobserve"},/turf/unsimulated/floor{icon_state = "lino"},/area/tdome/tdomeobserve) "JP" = (/turf/simulated/shuttle/floor/yellow,/area/shuttle/escape/centcom) -"JQ" = (/obj/machinery/atmospherics/pipe/simple/visible{ icon_state = "intact"; dir = 5},/obj/machinery/camera/network/crescent{c_tag = "Shuttle Medical"; dir = 4},/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) -"JR" = (/obj/machinery/atmospherics/pipe/simple/visible{ icon_state = "intact"; dir = 9},/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) +"JQ" = (/obj/machinery/atmospherics/pipe/simple/visible{icon_state = "intact"; dir = 9},/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) +"JR" = (/obj/machinery/atmospherics/pipe/simple/visible{icon_state = "intact"; dir = 5},/obj/machinery/camera/network/crescent{c_tag = "Shuttle Medical"; dir = 4},/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) "JS" = (/obj/machinery/vending/wallmed1{layer = 3.3; name = "Emergency NanoMed"; pixel_x = 28; pixel_y = 0},/obj/structure/bed/chair{dir = 8},/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) "JT" = (/obj/machinery/door/airlock/medical{name = "Operating Theatre"; req_access = list(45)},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) "JU" = (/obj/machinery/disease2/incubator,/obj/effect/floor_decal/corner/green/full{dir = 8},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) @@ -1937,9 +1937,9 @@ "Lm" = (/obj/structure/window/reinforced{dir = 8},/obj/effect/floor_decal/corner/green/full,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) "Ln" = (/obj/machinery/atmospherics/pipe/vent,/turf/unsimulated/floor{icon_state = "dark"},/area/tdome) "Lo" = (/obj/machinery/camera/network/thunder{c_tag = "Thunderdome Arena"; invisibility = 101},/turf/unsimulated/floor{icon_state = "dark"},/area/tdome) -"Lp" = (/obj/machinery/atmospherics/pipe/simple/visible{ icon_state = "intact"; dir = 5},/turf/unsimulated/floor{icon_state = "dark"},/area/tdome) +"Lp" = (/obj/machinery/atmospherics/pipe/simple/visible{icon_state = "intact"; dir = 5},/turf/unsimulated/floor{icon_state = "dark"},/area/tdome) "Lq" = (/obj/machinery/atmospherics/pipe/manifold/visible{dir = 1},/turf/unsimulated/floor{icon_state = "dark"},/area/tdome) -"Lr" = (/obj/machinery/atmospherics/pipe/simple/visible{ icon_state = "intact"; dir = 9},/turf/unsimulated/floor{icon_state = "dark"},/area/tdome) +"Lr" = (/obj/machinery/atmospherics/pipe/simple/visible{icon_state = "intact"; dir = 9},/turf/unsimulated/floor{icon_state = "dark"},/area/tdome) "Ls" = (/obj/machinery/atmospherics/pipe/simple/visible,/turf/unsimulated/floor{icon_state = "dark"},/area/tdome) "Lt" = (/obj/machinery/door/airlock/command{name = "Thunderdome Administration"; req_access = list(102)},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/tdome) "Lu" = (/obj/machinery/door/blast/regular{id = "thunderdomehea"; name = "Heavy Supply"},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/tdome) @@ -2008,9 +2008,9 @@ "MF" = (/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/shuttle/cryo/centcom) "MG" = (/obj/machinery/door/airlock/external,/turf/unsimulated/floor{icon = 'icons/turf/flooring/shuttle.dmi'; icon_state = "floor"},/area/centcom/evac) "MH" = (/turf/simulated/shuttle/floor/white,/area/centcom/evac) -"MI" = (/obj/machinery/atmospherics/pipe/simple/visible{ icon_state = "intact"; dir = 5},/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"MI" = (/obj/machinery/atmospherics/pipe/simple/visible{icon_state = "intact"; dir = 5},/turf/simulated/shuttle/floor/white,/area/centcom/evac) "MJ" = (/obj/machinery/atmospherics/pipe/manifold/visible,/turf/simulated/shuttle/floor/white,/area/centcom/evac) -"MK" = (/obj/machinery/atmospherics/pipe/simple/visible{ icon_state = "intact"; dir = 9},/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"MK" = (/obj/machinery/atmospherics/pipe/simple/visible{icon_state = "intact"; dir = 9},/turf/simulated/shuttle/floor/white,/area/centcom/evac) "ML" = (/obj/machinery/computer/operating,/turf/simulated/shuttle/floor/white,/area/centcom/evac) "MM" = (/turf/space,/obj/structure/shuttle/engine/propulsion{dir = 8},/turf/simulated/shuttle/plating/airless/carry,/area/centcom/evac) "MN" = (/obj/structure/closet/emcloset,/turf/simulated/shuttle/floor/yellow,/area/centcom/evac) @@ -2028,10 +2028,10 @@ "MZ" = (/obj/structure/closet/crate/freezer,/obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh,/obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh,/obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh,/obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh,/obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh,/obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh,/obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh,/obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh,/obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh,/turf/simulated/shuttle/floor/white,/area/centcom/evac) "Na" = (/obj/structure/closet/crate/medical,/obj/item/weapon/storage/firstaid/regular{pixel_x = -2; pixel_y = 4},/obj/item/weapon/storage/firstaid/regular{pixel_x = -2; pixel_y = 4},/obj/item/bodybag/cryobag{pixel_x = 5},/obj/item/bodybag/cryobag{pixel_x = 5},/obj/item/weapon/storage/firstaid/o2{layer = 2.8; pixel_x = 4; pixel_y = 6},/obj/item/weapon/storage/box/masks{pixel_x = 0; pixel_y = 0},/obj/item/weapon/storage/box/gloves{pixel_x = 3; pixel_y = 4},/obj/item/weapon/storage/firstaid/toxin,/obj/item/weapon/storage/firstaid/fire{layer = 2.9; pixel_x = 2; pixel_y = 3},/obj/item/weapon/storage/firstaid/adv{pixel_x = -2},/obj/item/weapon/reagent_containers/blood/empty,/obj/item/weapon/reagent_containers/blood/empty,/turf/simulated/shuttle/floor/white,/area/centcom/evac) "Nb" = (/obj/structure/table/standard,/turf/simulated/shuttle/floor/white,/area/centcom/evac) -"Nc" = (/obj/structure/morgue{ icon_state = "morgue1"; dir = 8},/turf/simulated/shuttle/floor/white,/area/centcom/evac) +"Nc" = (/obj/structure/morgue{icon_state = "morgue1"; dir = 8},/turf/simulated/shuttle/floor/white,/area/centcom/evac) "Nd" = (/obj/structure/bed/chair,/obj/effect/landmark{name = "endgame_exit"},/obj/item/toy/plushie/mouse{desc = "A plushie of a small fuzzy rodent."; name = "Woodrat"},/turf/unsimulated/beach/sand,/area/beach) "Ne" = (/obj/structure/bed/chair,/obj/effect/landmark{name = "endgame_exit"},/turf/unsimulated/beach/sand,/area/beach) -"Nf" = (/mob/living/simple_animal/crab/Coffee,/turf/unsimulated/beach/sand,/area/beach) +"Nf" = (/mob/living/simple_mob/animal/passive/crab/Coffee,/turf/unsimulated/beach/sand,/area/beach) "Ng" = (/turf/space,/obj/structure/shuttle/engine/propulsion{dir = 8; icon_state = "propulsion_r"},/turf/simulated/shuttle/plating/airless/carry,/area/centcom/evac) "Nh" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "large_escape_pod_2_recovery_hatch"; locked = 1; name = "Recovery Shuttle Dock 02"; req_access = list(13)},/turf/simulated/shuttle/floor/yellow,/area/centcom/evac) "Ni" = (/obj/machinery/vending/wallmed1{name = "Emergency NanoMed"; pixel_x = -30; pixel_y = 0},/turf/simulated/shuttle/floor/white,/area/centcom/evac) @@ -2055,7 +2055,7 @@ "NA" = (/obj/machinery/vending/coffee,/turf/simulated/shuttle/floor/yellow,/area/centcom/evac) "NB" = (/obj/machinery/vending/cola,/turf/simulated/shuttle/floor/yellow,/area/centcom/evac) "NC" = (/obj/structure/grille,/obj/structure/shuttle/window,/turf/simulated/shuttle/plating,/area/centcom/evac) -"ND" = (/obj/machinery/door/airlock/glass,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/centcom/evac) +"ND" = (/obj/machinery/door/airlock/glass,/turf/simulated/shuttle/floor{icon_state = "floor_yellow"},/area/centcom/evac) "NE" = (/obj/machinery/computer/communications,/turf/simulated/shuttle/floor/black,/area/centcom/evac) "NF" = (/turf/simulated/shuttle/floor/black,/area/centcom/evac) "NG" = (/obj/structure/table/standard,/obj/item/device/radio/off,/obj/item/weapon/paper_bin,/turf/simulated/shuttle/floor/black,/area/centcom/evac) @@ -2070,8 +2070,8 @@ "NP" = (/turf/unsimulated/beach/water,/area/beach) "NQ" = (/obj/machinery/door/airlock/glass,/turf/simulated/shuttle/floor,/area/centcom/evac) "NR" = (/obj/structure/table/standard,/turf/simulated/shuttle/floor,/area/centcom/evac) -"NS" = (/obj/machinery/door/airlock/hatch{name = "Cockpit"; req_access = list(109)},/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/centcom/evac) -"NT" = (/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/centcom/evac) +"NS" = (/turf/simulated/shuttle/floor{icon_state = "floor_yellow"},/area/centcom/evac) +"NT" = (/obj/machinery/door/airlock/hatch{name = "Cockpit"; req_access = list(109)},/turf/simulated/shuttle/floor{icon_state = "floor_yellow"},/area/centcom/evac) "NU" = (/obj/structure/table/standard,/obj/item/weapon/storage/lockbox,/turf/simulated/shuttle/floor/black,/area/centcom/evac) "NV" = (/obj/structure/bed/chair{dir = 1},/turf/simulated/shuttle/floor,/area/centcom/evac) "NW" = (/obj/structure/bed/chair,/turf/simulated/shuttle/floor/black,/area/centcom/evac) @@ -2090,11 +2090,11 @@ "Oj" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_pod_3_recovery_hatch"; locked = 1; name = "Recovery Shuttle Dock 3"; req_access = list(13)},/turf/simulated/shuttle/floor/yellow,/area/centcom/evac) "Ok" = (/obj/machinery/door/airlock/maintenance_hatch{req_access = list(101)},/turf/unsimulated/floor{icon = 'icons/turf/flooring/shuttle.dmi'; icon_state = "floor2"},/area/centcom/evac) "Ol" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "large_escape_pod_1_recovery"; pixel_x = -25; pixel_y = -25; req_one_access = list(13); tag_door = "large_escape_pod_1_recovery_hatch"},/turf/simulated/shuttle/floor/yellow,/area/centcom/evac) -"Om" = (/obj/machinery/computer/card,/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/centcom/evac) -"On" = (/obj/structure/table/rack,/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/centcom/evac) -"Oo" = (/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/centcom/evac) -"Op" = (/obj/structure/table/reinforced,/obj/item/weapon/paper_bin,/obj/item/weapon/pen,/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/centcom/evac) -"Oq" = (/obj/machinery/computer/secure_data,/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/centcom/evac) +"Om" = (/obj/structure/table/rack,/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/centcom/evac) +"On" = (/obj/machinery/computer/card,/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/centcom/evac) +"Oo" = (/obj/structure/table/reinforced,/obj/item/weapon/paper_bin,/obj/item/weapon/pen,/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/centcom/evac) +"Op" = (/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/centcom/evac) +"Oq" = (/obj/machinery/computer/secure_data,/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/centcom/evac) "Or" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/medical,/turf/simulated/shuttle/floor,/area/centcom/evac) "Os" = (/turf/simulated/mineral,/area/syndicate_mothership{name = "\improper Raider Base"}) "Ot" = (/obj/effect/landmark{name = "voxstart"},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership{name = "\improper Raider Base"}) @@ -2106,19 +2106,19 @@ "Oz" = (/turf/simulated/shuttle/plating,/area/shuttle/escape_pod4/centcom) "OA" = (/turf/simulated/shuttle/plating,/area/shuttle/escape_pod3/centcom) "OB" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "large_escape_pod_1_recovery_hatch"; locked = 1; name = "Recovery Shuttle Dock 01"; req_access = list(13)},/turf/simulated/shuttle/floor/yellow,/area/centcom/evac) -"OC" = (/obj/structure/bed/chair{dir = 1},/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/centcom/evac) +"OC" = (/obj/structure/bed/chair{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/centcom/evac) "OD" = (/obj/structure/closet/secure_closet/personal/patient,/turf/simulated/shuttle/floor,/area/centcom/evac) "OE" = (/obj/structure/table/standard,/obj/structure/bedsheetbin,/turf/simulated/shuttle/floor,/area/centcom/evac) "OF" = (/obj/item/weapon/bedsheet/orange,/obj/structure/bed/padded,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership{name = "\improper Raider Base"}) "OG" = (/turf/simulated/shuttle/plating,/area/shuttle/large_escape_pod1/centcom) -"OH" = (/obj/structure/closet{name = "Evidence Closet"},/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/centcom/evac) -"OI" = (/obj/structure/closet/secure_closet/security,/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/centcom/evac) +"OH" = (/obj/structure/closet/secure_closet/security,/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/centcom/evac) +"OI" = (/obj/structure/closet{name = "Evidence Closet"},/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/centcom/evac) "OJ" = (/obj/machinery/door/airlock/hatch{req_access = list(150)},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership{name = "\improper Raider Base"}) "OK" = (/obj/structure/bed/chair,/turf/simulated/shuttle/floor/yellow,/area/centcom/evac) -"OL" = (/obj/machinery/door/airlock/glass_security{name = "Escape Shuttle Cell"; req_access = list(1)},/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/centcom/evac) -"OM" = (/turf/unsimulated/floor{ icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"OL" = (/obj/machinery/door/airlock/glass_security{name = "Escape Shuttle Cell"; req_access = list(1)},/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/centcom/evac) +"OM" = (/turf/unsimulated/floor{icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) "ON" = (/obj/structure/table/standard,/turf/simulated/shuttle/floor/yellow,/area/centcom/evac) -"OO" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/orange,/turf/simulated/shuttle/floor{ icon_state = "floor_red"},/area/centcom/evac) +"OO" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/orange,/turf/simulated/shuttle/floor{icon_state = "floor_red"},/area/centcom/evac) "OP" = (/obj/item/weapon/tray{pixel_y = 5},/obj/structure/table/standard,/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership{name = "\improper Raider Base"}) "OQ" = (/obj/structure/table/standard,/obj/item/weapon/storage/box/glasses/square{pixel_x = 1; pixel_y = 4},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership{name = "\improper Raider Base"}) "OR" = (/obj/machinery/portable_atmospherics/powered/pump,/turf/simulated/shuttle/plating,/area/centcom/evac) @@ -2130,7 +2130,7 @@ "OX" = (/obj/structure/grille,/obj/structure/window/shuttle{icon_state = "window8"},/turf/simulated/shuttle/plating,/area/centcom/evac) "OY" = (/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership{name = "\improper Raider Base"}) "OZ" = (/obj/structure/table/standard,/obj/machinery/chemical_dispenser/bar_soft/full,/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership{name = "\improper Raider Base"}) -"Pa" = (/obj/item/weapon/bedsheet/orange,/obj/effect/decal/cleanable/cobweb2{ icon_state = "cobweb1"},/obj/structure/bed/padded,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"Pa" = (/obj/item/weapon/bedsheet/orange,/obj/effect/decal/cleanable/cobweb2{icon_state = "cobweb1"},/obj/structure/bed/padded,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership{name = "\improper Raider Base"}) "Pb" = (/obj/machinery/microwave{pixel_x = -1; pixel_y = 8},/obj/structure/table/standard,/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership{name = "\improper Raider Base"}) "Pc" = (/obj/structure/table/standard,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership{name = "\improper Raider Base"}) "Pd" = (/obj/structure/closet/secure_closet/freezer/kitchen,/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership{name = "\improper Raider Base"}) @@ -2142,31 +2142,31 @@ "Pj" = (/obj/effect/decal/cleanable/blood,/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership{name = "\improper Raider Base"}) "Pk" = (/obj/machinery/gibber,/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership{name = "\improper Raider Base"}) "Pl" = (/obj/structure/kitchenspike,/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership{name = "\improper Raider Base"}) -"Pm" = (/obj/item/clothing/head/xenos,/turf/unsimulated/floor{ icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"Pm" = (/obj/item/clothing/head/xenos,/turf/unsimulated/floor{icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) "Pn" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/structure/mirror{dir = 4; pixel_x = -28; pixel_y = 0},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership{name = "\improper Raider Base"}) -"Po" = (/obj/item/clothing/mask/gas/swat{desc = "A close-fitting mask clearly not made for a human face."; name = "\improper alien mask"},/turf/unsimulated/floor{ icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) -"Pp" = (/obj/item/xenos_claw,/turf/unsimulated/floor{ icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) -"Pq" = (/obj/structure/table/rack,/turf/unsimulated/floor{ icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) -"Pr" = (/obj/structure/table/rack,/obj/item/weapon/gun/launcher/spikethrower,/turf/unsimulated/floor{ icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"Po" = (/obj/item/clothing/mask/gas/swat{desc = "A close-fitting mask clearly not made for a human face."; name = "\improper alien mask"},/turf/unsimulated/floor{icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"Pp" = (/obj/structure/table/rack,/turf/unsimulated/floor{icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"Pq" = (/obj/item/xenos_claw,/turf/unsimulated/floor{icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"Pr" = (/obj/structure/table/rack,/obj/item/weapon/gun/launcher/spikethrower,/turf/unsimulated/floor{icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) "Ps" = (/obj/machinery/shower{dir = 1},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership{name = "\improper Raider Base"}) -"Pt" = (/obj/item/pizzabox/meat,/turf/unsimulated/floor{ icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) -"Pu" = (/obj/structure/reagent_dispensers/beerkeg,/turf/unsimulated/floor{ name = "plating"; icon_state = "cult"},/area/syndicate_mothership{name = "\improper Raider Base"}) -"Pv" = (/turf/unsimulated/floor{ name = "plating"; icon_state = "cult"},/area/syndicate_mothership{name = "\improper Raider Base"}) -"Pw" = (/obj/effect/decal/cleanable/cobweb2,/turf/unsimulated/floor{ name = "plating"; icon_state = "cult"},/area/syndicate_mothership{name = "\improper Raider Base"}) -"Px" = (/obj/structure/table/rack,/obj/item/clothing/glasses/thermal/plain/monocle,/turf/unsimulated/floor{ icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) -"Py" = (/obj/effect/landmark{name = "voxstart"},/turf/unsimulated/floor{ name = "plating"; icon_state = "cult"},/area/syndicate_mothership{name = "\improper Raider Base"}) -"Pz" = (/obj/item/weapon/tank/nitrogen,/turf/unsimulated/floor{ icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) -"PA" = (/obj/item/organ/internal/stack,/turf/unsimulated/floor{ icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) -"PB" = (/obj/structure/bed/chair,/turf/unsimulated/floor{ name = "plating"; icon_state = "cult"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"Pt" = (/obj/item/pizzabox/meat,/turf/unsimulated/floor{icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"Pu" = (/obj/structure/reagent_dispensers/beerkeg,/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"Pv" = (/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"Pw" = (/obj/effect/decal/cleanable/cobweb2,/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"Px" = (/obj/structure/table/rack,/obj/item/clothing/glasses/thermal/plain/monocle,/turf/unsimulated/floor{icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"Py" = (/obj/effect/landmark{name = "voxstart"},/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"Pz" = (/obj/item/weapon/tank/nitrogen,/turf/unsimulated/floor{icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"PA" = (/obj/item/organ/internal/stack,/turf/unsimulated/floor{icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"PB" = (/obj/structure/bed/chair,/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/syndicate_mothership{name = "\improper Raider Base"}) "PC" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership{name = "\improper Raider Base"}) "PD" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership{name = "\improper Raider Base"}) "PE" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership{name = "\improper Raider Base"}) -"PF" = (/obj/machinery/computer/station_alert,/turf/unsimulated/floor{ name = "plating"; icon_state = "cult"},/area/syndicate_mothership{name = "\improper Raider Base"}) -"PG" = (/obj/machinery/computer/shuttle_control/multi/skipjack,/turf/unsimulated/floor{ name = "plating"; icon_state = "cult"},/area/syndicate_mothership{name = "\improper Raider Base"}) -"PH" = (/obj/machinery/suit_cycler/syndicate{locked = 0},/turf/unsimulated/floor{ name = "plating"; icon_state = "cult"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"PF" = (/obj/machinery/computer/shuttle_control/multi/skipjack,/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"PG" = (/obj/machinery/computer/station_alert,/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"PH" = (/obj/machinery/suit_cycler/syndicate{locked = 0},/turf/unsimulated/floor{name = "plating"; icon_state = "cult"},/area/syndicate_mothership{name = "\improper Raider Base"}) "PI" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdown"; tiles = 0},/turf/space,/area/space) -"PJ" = (/obj/machinery/portable_atmospherics/canister/nitrogen,/obj/item/weapon/tank/nitrogen,/turf/unsimulated/floor{ icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) -"PK" = (/obj/item/clothing/head/philosopher_wig,/turf/unsimulated/floor{ icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"PJ" = (/obj/machinery/portable_atmospherics/canister/nitrogen,/obj/item/weapon/tank/nitrogen,/turf/unsimulated/floor{icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"PK" = (/obj/item/clothing/head/philosopher_wig,/turf/unsimulated/floor{icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) "PL" = (/obj/structure/lattice,/obj/structure/window/reinforced{dir = 4},/turf/space,/area/syndicate_mothership{name = "\improper Raider Base"}) "PM" = (/obj/machinery/door/airlock/external{req_access = list(150)},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership{name = "\improper Raider Base"}) "PN" = (/obj/structure/lattice,/obj/structure/window/reinforced{dir = 8},/turf/space,/area/syndicate_mothership{name = "\improper Raider Base"}) @@ -2254,8 +2254,8 @@ "Rr" = (/obj/machinery/media/jukebox,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) "Rs" = (/obj/machinery/vending/hydronutrients,/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/wizard_station) "Rt" = (/obj/structure/closet{icon_closed = "cabinet_closed"; icon_opened = "cabinet_open"; icon_state = "cabinet_closed"},/obj/item/clothing/under/psysuit,/obj/item/clothing/suit/wizrobe/psypurple,/obj/item/clothing/head/wizard/amp,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) -"Ru" = (/mob/living/simple_animal/mouse/gray{desc = "He looks kingly."; name = "Arthur"},/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) -"Rv" = (/obj/structure/flora/pottedplant{ icon_state = "plant-24"},/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"Ru" = (/mob/living/simple_mob/animal/passive/mouse/gray{desc = "He looks kingly."; name = "Arthur"},/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"Rv" = (/obj/structure/flora/pottedplant{icon_state = "plant-24"},/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) "Rw" = (/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/shuttle/plating,/area/skipjack_station/start) "Rx" = (/turf/simulated/shuttle/plating,/area/skipjack_station/start) "Ry" = (/obj/structure/reagent_dispensers/watertank,/obj/machinery/light/small{dir = 4},/turf/simulated/shuttle/plating,/area/skipjack_station/start) @@ -2264,7 +2264,7 @@ "RB" = (/obj/item/robot_parts/head,/turf/simulated/shuttle/plating,/area/skipjack_station/start) "RC" = (/obj/machinery/photocopier,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) "RD" = (/obj/structure/bookcase,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) -"RE" = (/obj/structure/flora/pottedplant{ icon_state = "plant-08"},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) +"RE" = (/obj/structure/flora/pottedplant{icon_state = "plant-08"},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) "RF" = (/obj/structure/closet{icon_closed = "cabinet_closed"; icon_opened = "cabinet_open"; icon_state = "cabinet_closed"},/obj/item/clothing/shoes/sandal/marisa{desc = "A set of fancy shoes that are as functional as they are comfortable."; name = "Gentlemans Shoes"},/obj/item/clothing/under/gentlesuit,/obj/item/clothing/suit/wizrobe/gentlecoat,/obj/item/clothing/head/wizard/cap,/obj/item/weapon/staff/gentcane,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) "RG" = (/obj/structure/closet{icon_closed = "cabinet_closed"; icon_opened = "cabinet_open"; icon_state = "cabinet_closed"},/obj/item/clothing/suit/wizrobe/magusred,/obj/item/clothing/head/wizard/magus,/obj/item/weapon/staff,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) "RH" = (/obj/structure/closet{icon_closed = "cabinet_closed"; icon_opened = "cabinet_open"; icon_state = "cabinet_closed"},/obj/item/clothing/suit/wizrobe/marisa,/obj/item/clothing/shoes/sandal/marisa,/obj/item/clothing/head/wizard/marisa,/obj/item/weapon/staff/broom,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) @@ -2294,7 +2294,7 @@ "Sf" = (/obj/structure/table/steel_reinforced,/obj/item/stack/telecrystal,/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) "Sg" = (/obj/item/device/radio/intercom{desc = "Talk through this. Evilly"; frequency = 1213; name = "Syndicate Intercom"; pixel_x = 32; subspace_transmission = 1; syndie = 1},/obj/item/device/radio/intercom{desc = "Talk through this. Evilly"; frequency = 1213; name = "Syndicate Intercom"; pixel_x = 32; subspace_transmission = 1; syndie = 1},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) "Sh" = (/obj/structure/table/steel_reinforced,/obj/item/clothing/head/philosopher_wig,/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) -"Si" = (/obj/structure/flora/pottedplant{ icon_state = "plant-04"},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"Si" = (/obj/structure/flora/pottedplant{icon_state = "plant-04"},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) "Sj" = (/obj/structure/sign/electricshock,/turf/simulated/shuttle/wall/dark/hard_corner,/area/wizard_station) "Sk" = (/obj/machinery/portable_atmospherics/canister/oxygen,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/wizard_station) "Sl" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{id = "skipjackshutters"; name = "Skipjack Blast Shielding"},/turf/simulated/shuttle/plating,/area/skipjack_station/start) @@ -2323,7 +2323,7 @@ "SI" = (/obj/item/device/radio/intercom{desc = "Talk through this. Evilly"; frequency = 1213; name = "Subversive Intercom"; pixel_x = 32; subspace_transmission = 1; syndie = 1},/obj/machinery/computer/station_alert/all,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) "SJ" = (/obj/structure/table/steel_reinforced,/obj/item/device/mmi/radio_enabled,/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) "SK" = (/obj/structure/table/steel_reinforced,/obj/item/weapon/material/knife/ritual,/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) -"SL" = (/obj/structure/flora/pottedplant{ icon_state = "plant-03"},/obj/item/device/radio/intercom{desc = "Talk through this. Evilly"; frequency = 1213; name = "Subversive Intercom"; pixel_x = -32; subspace_transmission = 1; syndie = 1},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"SL" = (/obj/structure/flora/pottedplant{icon_state = "plant-03"},/obj/item/device/radio/intercom{desc = "Talk through this. Evilly"; frequency = 1213; name = "Subversive Intercom"; pixel_x = -32; subspace_transmission = 1; syndie = 1},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) "SM" = (/obj/structure/reagent_dispensers/watertank,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/wizard_station) "SN" = (/obj/machinery/power/port_gen/pacman,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/wizard_station) "SO" = (/obj/structure/shuttle/engine/heater,/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/plating/airless,/area/skipjack_station/start) @@ -2353,7 +2353,7 @@ "Tm" = (/obj/structure/table/steel_reinforced,/obj/item/weapon/book/manual/engineering_hacking,/obj/item/device/radio/intercom{desc = "Talk through this. Evilly"; frequency = 1213; name = "Subversive Intercom"; pixel_x = 32; subspace_transmission = 1; syndie = 1},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) "Tn" = (/obj/effect/floor_decal/industrial/warning/corner,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) "To" = (/obj/effect/floor_decal/industrial/warning,/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) -"Tp" = (/obj/effect/floor_decal/industrial/warning/corner{ icon_state = "warningcorner"; dir = 8},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) +"Tp" = (/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 8},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) "Tq" = (/obj/item/device/radio/intercom{desc = "Talk through this. Evilly"; frequency = 1213; name = "Subversive Intercom"; pixel_x = -32; subspace_transmission = 1; syndie = 1},/obj/item/target,/obj/effect/floor_decal/industrial/outline/yellow,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) "Tr" = (/obj/item/weapon/bedsheet/rainbow,/obj/structure/bed/padded,/turf/simulated/shuttle/floor/red,/area/skipjack_station/start) "Ts" = (/obj/item/weapon/bedsheet/hos,/obj/structure/bed/padded,/turf/simulated/shuttle/floor/red,/area/skipjack_station/start) @@ -2399,7 +2399,7 @@ "Ug" = (/obj/machinery/computer/teleporter,/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) "Uh" = (/obj/machinery/teleport/station,/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) "Ui" = (/obj/machinery/teleport/hub,/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) - + (1,1,1) = {" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacacacacadadaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeacaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeacafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafagagagagagagagagagagagagagafafafafafafafafafafafafafafafafafafafafahaiaiaiaiaiaiaiaiaiaiahaiaiaiaiaiaiaiaiaiaiahaiaiaiaiaiaiaiaiaiaiahaiaiaiaiaiaiaiaiaiaiahaiaiaiaiaiaiaiaiaiaiahaiaiaiaiaiaiaiaiaiaiahaiaiaiaiaiaiaiaiaiaiah aaajajajajajajajajajajajajajajajajajajajajajajajajajajajajajaaacacacacacacacadacacacacacacacacacacacacacacacacacacacacacacacadacaeacacacacacacacacacacacacacacacacacacacacacacacaeacafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafagakalagakalagakalagakalagafafafafafafafafafafafafafafafafafafafafamanananaoananananananapaqaraqaraqaqaraqaraqapasatatatatatatatatatapauavawawawawawawawawapaxaxaxaxaxaxaxaxaxaxapayayayayayayayayayayapazaAaBaCaDaDaDaDaDaEaF @@ -2433,20 +2433,20 @@ aaajajajajajajajbpbDbDbDbDbDbDbDbDbDbDbDbDbDbqajajajajajajajaaajaaajajajajajajaj aaajajajajajajajbpbDbDbDbDbDbDbDbDbDbDbDbDbDbqajajajajajajajaaajaaajajajajajajajajajajajajajajajajajajajajajajajajajaaajajajaaajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajaaajaaajajajajajajajajajajajajajajajajajajajajajajajajajaaafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafexexexeFeMeFeFeFeFeHePePeHeFeQeHeHeHeHeHeHexafafafafafafafafafafafafafafafafafafafafafaf aaajajajajajajajbpbDbDbDbDbDbDbDbDbDbDbDbDbDbqajajajajajajajaaajaaajajajajajajajajajajajajajajajajajajajajajajajajajaaajajajaaajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajaaajaaajajajajajajajajajaaaaaaaaaaaaaaajajajajajajajajajaaafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafexeReSeFeFeFeFeFeFeHePePeHeFeQeHeHeHeHeHeHexafafafafafafafafafafafafafafafafafafafafafaf aaajajajajajajajbqbqbqbqbqbDbDbDbDbDbqbqbqbqbqajajajajajajajaaajaaajajajajajajajajajajajajajajajajajajajajajajajajajaaajajajaaajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajaaajaaajajajajajajajajaaaaeTeTeTeTeTaaaaajajajajajajajajaaafafafafafafafafafafafafafafafafafafafafafafafafafafafafeUeVeVeVeVeVeUafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafexexexeWeXexexexeFeHePePeKeFexeHeHeHeHeHeHexafafafafafafafafafafafafafafafafafafafafafaf -aaajajajajajajajajajajajbqbqbqbqbqbqbqajajajajajajajajajajajaaajaaajajajajajajajajajajajajajajajajajajajajajajajajajaaajajajaaajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajaaajaaajajajajajajajajaaeTeTeYeZfaeTeTaaajajajajajajajajaaafafafafafafafafafafafafafafafafafafafafafafafafafafafafeVfbfcfdfefbeUafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafexffeXeXeXeXfgexeFeHeHeHeKeFexeLeHeGeHeLeHexafafafafafafafafafafafafafafafafafafafafafaf -aaajajajajajajajajajajajajajajajajajajajajajajajajajajajajajaaajaaajajajajajajajajajajajajajajajajajajajajajajajajajaaajajajaaajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajaaajaaajajajajajajajaaaaeTfhfifafjfkeTaaaaajajajajajajajaaafafafafafafafafafafafafafafafafafafafafafafafafafafafafeVfbflflflfbeUeUeUeUafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafexffeXfmfneXfgexeFeFeFeFeFeFexeGeHeGeHeGeHexafafafafafafafafafafafafafafafafafafafafafaf +aaajajajajajajajajajajajbqbqbqbqbqbqbqajajajajajajajajajajajaaajaaajajajajajajajajajajajajajajajajajajajajajajajajajaaajajajaaajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajaaajaaajajajajajajajajaaeTeTeZeYfaeTeTaaajajajajajajajajaaafafafafafafafafafafafafafafafafafafafafafafafafafafafafeVfbfcfdfefbeUafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafexffeXeXeXeXfgexeFeHeHeHeKeFexeLeHeGeHeLeHexafafafafafafafafafafafafafafafafafafafafafaf +aaajajajajajajajajajajajajajajajajajajajajajajajajajajajajajaaajaaajajajajajajajajajajajajajajajajajajajajajajajajajaaajajajaaajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajaaajaaajajajajajajajaaaaeTfhfifafkfjeTaaaaajajajajajajajaaafafafafafafafafafafafafafafafafafafafafafafafafafafafafeVfbflflflfbeUeUeUeUafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafexffeXfmfneXfgexeFeFeFeFeFeFexeGeHeGeHeGeHexafafafafafafafafafafafafafafafafafafafafafaf aaajajajajajajajajajajajajajajajajajajajajajajajajajajajajajaaajaaajajajajajajajajfofofofofofofofofoajajajajajajajajaaajajajaaajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajaaajaaajajajajajajajaaeTeTfpfqfreTfseTeTaaajajajajajajajaaafafafafafafafafafafafafafafafafafafafafafafafafafafafafeVfbftftftfbeUfufveUafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafexexexexexexexexexexeFeFexexexexexexexexexexafafafafafafafafafafafafafafafafafafafafafaf -aaajajajajajajajajajajajajajajajajajajajajajajajajajajajajajaaajaaajajajajajajajfwfxfyfyfyfyfyfyfyfofwajajajajajajajaaajajajaaajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajaaajaaajajajajajajajaafzfAfBfCfDfEfFfAfzaaajajajajajajajaaafafafafafafafafafafafafafafafafafafafafafafafafafafafafeVfbfGfHfIfbeUeUeUeUeUeUeUeUeUeUeUeUafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafexeFfJexafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf +aaajajajajajajajajajajajajajajajajajajajajajajajajajajajajajaaajaaajajajajajajajfwfxfyfyfyfyfyfyfyfofwajajajajajajajaaajajajaaajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajaaajaaajajajajajajajaafzfBfAfCfDfEfFfBfzaaajajajajajajajaaafafafafafafafafafafafafafafafafafafafafafafafafafafafafeVfbfGfHfIfbeUeUeUeUeUeUeUeUeUeUeUeUafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafexeFfJexafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf aaajajajajajajajajajajajajajajajajajajajajajajajajajajajajajaaajaaajajajajajajajfwfyfyfyfyfyfyfyfyfyfwajajajajajajajaaajajajaaajajajajajajfwfwfwfwfwfwajfwfwfwajajajfwfwfwajfwfwfwfwfwfwajajajajajajajaaajaaajajajajajajajaafKfLfLfLfLfLfLfLfMaaajajajajajajajaaafafafafafafafafafafafafafafafafafafafafafafafafafafafafeVfbfGfHfIfbfNfOfPfQfRfSfOfTfUfVfVeUafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafexeFeFexafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabajaaajajajajajajajfwfyfyfyfyfyfyfyfyfyfwajajajajajajajaaajajajaaajajajajajajfwfWfwfwfWfwajfwfWfwfwfwfwfwfWfwajfwfWfwfwfWfwajajajajajajajaaajaaajajajajajajajaafzfXfYfYfLfYfYfZfzaaajajajajajajajaaafafafafafafafafafafafafafafafafafafafafafafafafafafafafeVfbfGfHfIfbgafOfSfSfRfSfOfSfVfVfVeUafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafexgbgbexafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf -aaajajajajajajajajajajajajajajajajajajajajajajajajajajaaafafafajaaajajajajajajajfwfyfyfyfyfyfyfyfyfyfwajajajajajajajaaajajajaaajajajajajajfwfWfWfWfWfwfwfwfWfWfWfWfWfWfWfwfwfwfWfWfWfWfwajajajajajajajaaajaaajajajajajajajaaeTgcgdgdfLgdgdgeeTaaajajajajajajajaaafafafafafafafafafafafafafafafafafafafafafafafafafafafafeVfbfHfHfHgfggghfSfSfRfSfOfTfUfVfVeUafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafgigjgjgiafafafafgkgkgkgkgkafafafafafafafafafafafafafafafafafafafafafaf +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabajaaajajajajajajajfwfyfyfyfyfyfyfyfyfyfwajajajajajajajaaajajajaaajajajajajajfwfWfwfwfWfwajfwfWfwfwfwfwfwfWfwajfwfWfwfwfWfwajajajajajajajaaajaaajajajajajajajaafzfYfXfXfLfXfXfZfzaaajajajajajajajaaafafafafafafafafafafafafafafafafafafafafafafafafafafafafeVfbfGfHfIfbgafOfSfSfRfSfOfSfVfVfVeUafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafexgbgbexafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf +aaajajajajajajajajajajajajajajajajajajajajajajajajajajaaafafafajaaajajajajajajajfwfyfyfyfyfyfyfyfyfyfwajajajajajajajaaajajajaaajajajajajajfwfWfWfWfWfwfwfwfWfWfWfWfWfWfWfwfwfwfWfWfWfWfwajajajajajajajaaajaaajajajajajajajaaeTgdgcgcfLgcgcgeeTaaajajajajajajajaaafafafafafafafafafafafafafafafafafafafafafafafafafafafafeVfbfHfHfHgfggghfSfSfRfSfOfTfUfVfVeUafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafgigjgjgiafafafafgkgkgkgkgkafafafafafafafafafafafafafafafafafafafafafaf aaajajajajajajajbqfxfxfobqajbqfxfxfobqajajajajajajajajaaafafafajaaajajajajajajajfwfyfyfyfyfyfyfyfyfyfwajajajajajajajaaajajajaaajajajajajajfwfWfWfWfWfwfwfWfWfWfWfWfWfWfWfWfwfwfWfWfWfWfwajajajajajajajaaajaaajajajajajajajaaglgmgmgmfLgmgmgmglaaajajajajajajajaaafafafafafafafafafafafafafafafafafafafafafafafafafafafafeVfbfHfHfHgfggghfSfSfSfSgnfSfVfVfVeUafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafgkgkgkgkgkgkgogpgqgkafafafafafgkgkgrgsgkgkafafgkgkgkgkgtguafafafafafafafafafafafafafafafafafafafafafaf aaajajajajajajajbqgvgvgvbqajbqgwgwgwbqajajajajajajajajaaafafafajaaajajajajajajajfwfyfyfyfyfyfyfyfyfyfwajajajajajajajaaajajajaaajajajajajajfwfWfWfWfWfwfwfWfWfWfWfWfWfWfWfWfwfwfWfWfWfWfwajajajajajajajaaajaaajajajajajajajaaglgxgxgxgygzgxgxglaaajajajajajajajaaafafafafafafafafafafafafafafafafafafafafafafafafafafafafeVfbgAfHgBfbgafOfSfSfRfSfOfTfUfVfVeUafafafafafafafafafafafafafafafafafafafafafafafafafafafafafgkgigCgDgkgEgFgGgHgIgkgkafafafgkgkgigjgjgigkgogqgigJgKgkgtgLafafafafafafafafafafafafafafafafafafafafafaf aaajajajajajajajbqgvgvgvbqajbqgwgwgwbqajajajajajajajajaaafafafajaaajajajajajajajfwfofyfyfyfyfyfyfyfofwajajajajajajajaaajajajaaajajajajajajfwfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfwajajajajajajajaaajaaajajajajajajajaaglgMgMgMfLgMgMgMglaaajajajajajajajaaafafafafafafafafafafafafafafafafafafafafafafafafafafafafeVfbgNgOgNfbfNfOfSfSfRfSfOfSfVfVfVeUafafafafafafafafafafafafafafafafafafafafafafafafafafafafafgPgQgRgRgSgRgRgTgUgVgkgkgogpgqgkgkgWgRgRgXgkgYgZhagRhbgkgtgLafafafafafafafafafafafafafafafafafafafafafaf -aaajajajajajajajbqgvgvgvbqajbqgwgwgwbqajajajajajajajajaaafafafajaaajajajajajajajfofofyfyfyfyfyfyfyfofwajajajajajajajaaajajajaaajajajajajajfwfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfwajajajajajajajaaajaaajajajajajajajaaeTgcgdgdfLgdgdgeeTaaajajajajajajajaaafafafafafafafafafafafafafafafafafafafafafafafafafafafafeVhcfbhdfbhcfNfOfSfSfRfSfOfTfUfVfVeUafafafafafafafafafafafafafafafafafafafafafafafafafafafafafhehfhghhgkgRgRhihjhkgkhlhmhnhohphqhrhshsgRhtgRgRgRgRhugkgthvafafafafafafafafafafafafafafafafafafafafafaf -aaajajajajajajajbqgvgvgvbqajbqgwgwgwbqajajajajajajajajaaafafafajaaajajajajfofofofofyfyfyfyfyfyfyfyfyfofofwfoajajajajaaajajajaaajajajajajajfwfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfwajajajajajajajaaajaaajajajajajajajaafzhwhxhxfLhxhxhyfzaaajajajajajajajaaafafafafafafafafafafafafafafafafafafafafafafafafafafafafeUeUeUeUeUeUeUeUeUeUeUeUeUeUeUeUeUeUafafafafafafafafafafafafafafafafafafafafafafafafafafafafafgkgkgkgkgkgkhzgRgRhAgkhBhChDhEhFhGhHhshsgRhtgRhIhJgRgRgkgkgkafafafafafafafafafafafafafafafafafafafafafaf +aaajajajajajajajbqgvgvgvbqajbqgwgwgwbqajajajajajajajajaaafafafajaaajajajajajajajfofofyfyfyfyfyfyfyfofwajajajajajajajaaajajajaaajajajajajajfwfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfwajajajajajajajaaajaaajajajajajajajaaeTgdgcgcfLgcgcgeeTaaajajajajajajajaaafafafafafafafafafafafafafafafafafafafafafafafafafafafafeVhcfbhdfbhcfNfOfSfSfRfSfOfTfUfVfVeUafafafafafafafafafafafafafafafafafafafafafafafafafafafafafhehfhghhgkgRgRhihjhkgkhlhmhnhohphqhrhshsgRhtgRgRgRgRhugkgthvafafafafafafafafafafafafafafafafafafafafafaf +aaajajajajajajajbqgvgvgvbqajbqgwgwgwbqajajajajajajajajaaafafafajaaajajajajfofofofofyfyfyfyfyfyfyfyfyfofofwfoajajajajaaajajajaaajajajajajajfwfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfwajajajajajajajaaajaaajajajajajajajaafzhxhwhwfLhwhwhyfzaaajajajajajajajaaafafafafafafafafafafafafafafafafafafafafafafafafafafafafeUeUeUeUeUeUeUeUeUeUeUeUeUeUeUeUeUeUafafafafafafafafafafafafafafafafafafafafafafafafafafafafafgkgkgkgkgkgkhzgRgRhAgkhBhChDhEhFhGhHhshsgRhtgRhIhJgRgRgkgkgkafafafafafafafafafafafafafafafafafafafafafaf aaajajajajajajajbqgvgvgvbqajbqgwgwgwbqajajajajajajajajaaafafafajaaajajajajfwfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfoajajajajaaajajajaaajajajajajajfwfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfwajajajajajajajaaajaaajajajajajajajaafKfLfLfLfLfLfLfLfMaaajajajajajajajaaafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafgkgkgkhKgRgkgihLhMhNhOhPhQhHhsgRhzgigkgkgihRhSgkgkafafafafafafafafafafafafafafafafafafafafafafaf -aaajajajajajajajbqbqbqbqbqajbqbqbqbqbqajajajajajajajajaaafafafajaaajajajajfwfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfoajajajajaaajajajaaajajajajajajfwfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfwajajajajajajajaaajaaajajajajajajajaafzhTgdfLfLfLgdhUfzaaajajajajajajajaaafafafafafafafafafafafafafafafafhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVafafafafafafafafafafafafafafafafafafafafafafafafgkhWhXgkgkgkgkgkgkgkgkhYgRgRgRgRhZgRgRgRgRgkgkiagRgigkibibgkgkgkgkafafafafafafafafafafafafafafafafafafafafafafafaf +aaajajajajajajajbqbqbqbqbqajbqbqbqbqbqajajajajajajajajaaafafafajaaajajajajfwfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfoajajajajaaajajajaaajajajajajajfwfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfwajajajajajajajaaajaaajajajajajajajaafzhTgcfLfLfLgchUfzaaajajajajajajajaaafafafafafafafafafafafafafafafafhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVafafafafafafafafafafafafafafafafafafafafafafafafgkhWhXgkgkgkgkgkgkgkgkhYgRgRgRgRhZgRgRgRgRgkgkiagRgigkibibgkgkgkgkafafafafafafafafafafafafafafafafafafafafafafafaf aaajajajajajajajajajajajajajajajajajajajajajajajajajajaaafafafajaaajajajajfwfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfoajajajajaaajajajaaajajajajajfwfwfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfwfwajajajajajajaaajaaajajajajajajajaaeTicidgziegxifigeTaaajajajajajajajaaafafafafafafafafafafafafafafafafhVihihihihihihihihihiiihihihijikihihihijihihihihihihijihihhVafafafafafafafafafafafafafafafafafafafafafafafgkgkilimgkingkioipiqgigkirgRhshshshshshshshshsgRhsgRisithshsgRgkgtguafafafafafafafafafafafafafafafafafafafafafafafaf aaajajajajajajajajajajajajajajajajajajajajajajajajajajaaafafafajaaajajajajfxfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfoajajajajaaajajajaaajajajajajfwfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfwajajajajajajaaajaaajajajajajajajaaaaiueTiviviveTiuaaaaajajajajajajajaaafafafafafafafafafafafafafafafafhVihihihihiiihihihihihihihihihihihijihihihihihijihihihihihhVafafafafafafafafafafafafafafafafafafafafafafafiwixhsiygkizgigkiAgkiBgkiChshsiDiEiFiGiHiIiJhshshshsiKiLhshsgRgkgtgLafafafafafafafafafafafafafafafafafafafafafafafaf aaajajajajajajajajajajajajajajajajajajajajajajajajajajaaafafafajaaajajajajfofyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfoajajajajaaajajajaaajajajajajfwfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfWfwajajajajajajaaajaaajajajajajajajajaaabeTiuiuiueTaaaaajajajajajajajajaaafafafafafafafafafafafafafafafafhVihihihihihihihiMihihihihihiiihihikijihihijihihijikihijihhVafafafafafafafafafafafafafafafafafafafafafafafiNiOiPhsiQgRgRgRgRiRgRgRgRhshsiSiTiUiViWiXiYhshshshsiZhshshsgRgkgtgLafafafafafafafafafafafafafafafafafafafafafafafaf @@ -2469,12 +2469,12 @@ ajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajaaaaaaaaaaaaaaaa ajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafhVihjyjyjyjyjyjyjyjKjKjKjyjyjyjyjyjyjykekTlolplphVafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf ajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaflslslslslslslslsafafhVihjyltltltltltjyjKjKjKjyjKjKjKjKjKjyluhVlolplphVafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf ajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaflslvlvlvlslvlvlsafafhVihjyltltltltltltjKjKjKjKjKjKjKjKjKjyluhVhVhVhVhVafafafafafafafafaflwlxlylxlzafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf -afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaflslvlAlvlBlvlvlsafafhVihjyltltltltltltjKjKjKjKjKjKjKjKjKjyjLihhVafafafafafafafafafafafaflxlClDlElxafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf -afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaflslFlFlFlslvlvlsafafhVihjyltltltltltjyltltltjyjKjyjKjyjyjylGihhVafafafafafafafafafafafaflHlIlJlIlHafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf -afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaflKlKlKlKlslslslslslslvlvlsafafhVihjyltltltjyjyjyltltltjyjyjyjKjKjKjyjLihhVafafafafafafafafafafafaflLlIlIlIlLafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf -afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaflKlKlKlKlBlvlBlvlvlvlvlvlsafafhVihjyltltltjyihjylMlMlMjyihjyjKjKjKjyjLihhVafafafafafafafafafafafaflLlIlIlIlLafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf -afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaflKlKlKlKlslslslslvlvlvlNlsafafhVihjylMlMlMjyihjylOlPlQjyihjylMlMlMjyjLihhVafafafafafafafafafafafaflRlIlIlIlRafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf -afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaflslFlvlvlNlsafafhVihjylOlPlQjyihihihihihihihjylOlPlQjyihihhVafafafafafafafafafafafaflxlSlTlUlxafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf +afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaflslvlAlvlBlvlvlsafafhVihjyltltltltltltjKjKjKjKjKjKjKjKjKjyjLihhVafafafafafafafafafafafaflxlDlClElxafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf +afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaflslFlFlFlslvlvlsafafhVihjyltltltltltjyltltltjyjKjyjKjyjyjylGihhVafafafafafafafafafafafaflHlJlIlJlHafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf +afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaflKlKlKlKlslslslslslslvlvlsafafhVihjyltltltjyjyjyltltltjyjyjyjKjKjKjyjLihhVafafafafafafafafafafafaflLlJlJlJlLafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf +afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaflKlKlKlKlBlvlBlvlvlvlvlvlsafafhVihjyltltltjyihjylMlMlMjyihjyjKjKjKjyjLihhVafafafafafafafafafafafaflLlJlJlJlLafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf +afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaflKlKlKlKlslslslslvlvlvlNlsafafhVihjylMlMlMjyihjylOlPlQjyihjylMlMlMjyjLihhVafafafafafafafafafafafaflRlJlJlJlRafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf +afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaflslFlvlvlNlsafafhVihjylOlPlQjyihihihihihihihjylOlPlQjyihihhVafafafafafafafafafafafaflxlTlSlUlxafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf lVlVlVlVlVlVlVlVlVlVlVlVlVlVlVafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaflslFlvlvlNlsafafhVihihihihihihihihihihihihihihihihihihihihhVafafafafafafafafafafafaflxlWlWlWlxafafafafafafafafafafafaflXlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlY lVlVlVlVlVlVlVlVlVlVlVlVlVlVlVafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaflslslslslslsafafhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVhVafafafafafafafafafafafaflwlZmamblwafafafafafafafafafafafaflYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf lVlVlVlVlVlVlVlVlVlVlVlVlVlVlVafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaflYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf @@ -2498,12 +2498,12 @@ afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafnwmTmTmTmToGmTmTmTmTmToGoHmTmTmTmTozmimioImimioImimimimimimimimioJmimioJmimimimioCoKmImIoFmimimimimimimimimQmQomomommQmdoLnCmdoMmdoNmdafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaflYafafafafafafafmcmcafafafafafafafafmcmcmcafafafafafafafafafafafafafafhVhVorororhVhVmcmcmcmcmcmcmcmcmcmcmcmcmcmcmcmcmcmc afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafnfnfnfnfnfnfnfnfnfnfmdngoOmTmToPmdmDmDmdoQoQmdmDmDmdmDmDmDmDmDoRoSoSmdmdmimimioCoToUoVoFmimioWmwmimimimimdoXnOnOnOoYmdoLnCmdoZmdoZmdafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaflYafafafafafafmcmcmcmcmcafafafafafafmcmcafafafafafafafafafafafafafafafafhVpaorpbhVmcmcmcmcmcmcmcmcmcmcmcmcmcmcmcmcmcmcmc afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafnwmTmTmTmTpcmTmTmTmTmTpcpdmTmTmTpemdpfmimimimimipgphmdpipjpkplpmpnmimipomDppmimimimimimimimimipqmdmimimimimdmdmdmdmdmdmdmdmdmdmdmdmdmdafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaflYafafafafafafmcmcmcmcmcmcafafafafafafafafafafafafafafafafafafafprpspspthVhVpuhVhVhVhVhVhVhVmcmcmchVhVhVhVhVhVmcmcmcmcmc -afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafnfnfnfnfnfnfnfnfnfnfmdmTmTmTmTpvmdpwmimimimimimipxmdmimimimipymimimipzmDpApBpCpDmimimipCpBpAppmdmimimimimDpEpFpFpGpHpImdpJnCpKmdafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaflYafafafafafafmcmcmcmcmcmcafafafafafafafafafafpLpMpNpNpNpOpLafafpPpQpRpSpQpQpQpThVpUpVpWpXhVmcmcmchVpYfVpZqahVmcmcmcmcmc +afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafnfnfnfnfnfnfnfnfnfnfmdmTmTmTmTpvmdpwmimimimimimipxmdmimimimipymimimipzmDpApBpCpDmimimipCpBpAppmdmimimimimDpEpFpFpGpHpImdpJnCpKmdafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaflYafafafafafafmcmcmcmcmcmcafafafafafafafafafafpLpMpNpNpNpOpLafafpPpQpSpRpQpQpQpThVpUpVpWpXhVmcmcmchVpYfVpZqahVmcmcmcmcmc afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafmdmTqbqcqdqemdqfmimiqgqhmimiqimdmimimimimimimimimdmdmdmDmDmdqjqjmdmdmdmdmdmdmimimimimDqkqkqkqkqkqkmdqlnCqmmdafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaflYafafafafafafafmcmcmcmcmcafafafafafafafafafpLpLqnqoqpqqqrpLpLafpPpQqsqspQpQpQpQqtquququqvhVmcmcmchVhVhVhVhVhVmcmcmcmcmc -afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafmdmdmdmdmdmdmdqwmimiqxqymimiqzmdmimiqAqBqCmimiqDmdqEqFqFqFqFqGqGqFqFqFqFafmdmimimimimdqkqHqIqIqIqImdmdqJmdmdafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaflYafafafafafafafafmcmcmcmcafafafafafafafafafpLqKqLqLqMqLqLqqpLafpPqNqOqPqQpQpQpQhVquququqRhVmcmcmchVqSfVfVqThVmcmcmcmcmc -afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafmdmimimiqUqVmimimimdmimiqWqXqYmimiqZmdrarbrcrdrerfrfrfrgrhriqFmdmimimimirjqkrkrkrkrkrkqkqkqkqImdafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaflYafafafafafafafafafmcmcafafafafafafafafafafpLrlqLqLqLqLrmrnpLafpPpQroropQpQpQrphVrqrrrsrthVmcmcmchVrufVfVrvhVmcmcmcmcmc -afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafmdmimimimimimimimimdmimimimimimimirwmdrarxryrfrfrfrfrfrfrfrzrAmdmimimimirjqkqkqkrBqkqkqkqkqkqImdafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaflYafafafafafafafafafafafafafafafafafafafafafpLrCqLqLrDqLqLrEpLafpPpQpQpQpQpQpQrFhVhVhVhVhVhVmcmcmchVrGfVfVrHhVmcmcmcmcmc -afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafmdmimimimimimimimimdmimimimimimimimimdrarxrIrJrKrKrKrKrKrLriqFmdmimimimimdqkqkrMrMqkqkrNqkqkqImdafafafafafafafafafafafafafafafafafafafafafafafafrOrPrPrPrPrPrPrPrPrPrPrPrPrPrPrPrPrPrPrPrPrPrPrOafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaflYafafafafafafafafafafafafafafafafafafafafafpLrQrRpLpLpLpLpLpLafrSpspsrThVqaqaqahVldldrUrVhVmcmcmchVrWfVfVrXhVmcmcmcmcmc +afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafmdmdmdmdmdmdmdqwmimiqxqymimiqzmdmimiqAqBqCmimiqDmdqEqFqFqFqFqGqGqFqFqFqFafmdmimimimimdqkqHqIqIqIqImdmdqJmdmdafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaflYafafafafafafafafmcmcmcmcafafafafafafafafafpLqKqLqLqMqLqLqqpLafpPqNqPqOqQpQpQpQhVquququqRhVmcmcmchVqSfVfVqThVmcmcmcmcmc +afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafmdmimimiqUqVmimimimdmimiqWqXqYmimiqZmdrarbrdrcrfrerererhrgriqFmdmimimimirjqkrkrkrkrkrkqkqkqkqImdafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaflYafafafafafafafafafmcmcafafafafafafafafafafpLrlqLqLqLqLrmrnpLafpPpQroropQpQpQrphVrqrrrsrthVmcmcmchVrufVfVrvhVmcmcmcmcmc +afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafmdmimimimimimimimimdmimimimimimimirwmdrarxryrerererererererzrAmdmimimimirjqkqkqkrBqkqkqkqkqkqImdafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaflYafafafafafafafafafafafafafafafafafafafafafpLrCqLqLrDqLqLrEpLafpPpQpQpQpQpQpQrFhVhVhVhVhVhVmcmcmchVrGfVfVrHhVmcmcmcmcmc +afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafmdmimimimimimimimimdmimimimimimimimimdrarxrJrIrKrKrKrKrKrLriqFmdmimimimimdqkqkrMrMqkqkrNqkqkqImdafafafafafafafafafafafafafafafafafafafafafafafafrOrPrPrPrPrPrPrPrPrPrPrPrPrPrPrPrPrPrPrPrPrPrPrOafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaflYafafafafafafafafafafafafafafafafafafafafafpLrQrRpLpLpLpLpLpLafrSpspsrThVqaqaqahVldldrUrVhVmcmcmchVrWfVfVrXhVmcmcmcmcmc afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafmdmimirYrZsasbscsdmdsesfsgshsisjskslmdsmqFqFqFqFqFqFqFqFqFqFafmdmimimimimdsnqksospqkqksqqkqksrmdafafafafafafafafafafafafafafafafafafafafafafafafrOssssssssssssssssssssssssssssssssssssssssssssrOafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaflYafafafafafafafafafafafafafafafafafafafafafafpLstsusvswsxpLafafafafafafsyqaqaqaszlelesAsAhVmcmcmchVrWfVfVsBhVmcmcmcmcmc afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafmdsCsDrYrZsasbscsdmdmdmdmdmdmdmdmdmdmdsEsEsEsEsEsEsEsEsEsEsEsEmdmdsFsFmdmdmdmdmdmdmdmdmdmdmdmdmdafafafafafafafafafafafafafafafafafafafafafafafafrOssssssssssssssssssssssssssssssssssssssssssssrOafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaflYafafafafafafafafafafafafafafafafafafafafafafpLsGsHrmqLsIpLafafafafafafsJqaqaqahVsKlehVhVhVhVhVhVhVsLsMsMsLhVhVhVhVmcmc afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafmdmdmdmdmdmdmdmdmdmdafafafafafafafafafafafafafafafafafafafafafmdmdsNsNmdmdafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafrOsssssssssssOsOsOsOsOsPsPsOsOsOsOsOssssssssssrOrOrOrOrOrOrOafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaflYafafafafafafafafafafafafafafafafafafafafafpLpLsQsurmqLsRpLpLafafnEnvsShVqaqaqahVhVhVhVsTsUsVsWsXsYfVfVfVfVsZsZtahVhVmc @@ -2544,27 +2544,27 @@ afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvEvYBYvYvYvXvEvE afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvDvDvYCavYvYvYvYvEvEvEvEvDvDvDvDvDvEvEvEvEvYvYvYCaBPCivYvYvYvEvEvEvEvDvDvDvDvDvEvEvEvEvYvYvYvYBPvYztxzxzzwwLAbxzCjwLAbzwwLCkxzxzBSyGyGClClClClyGCmCmyGClClClClyGyGAQAQAQAQCnCoCpCpCpCqCrAQAQAQAQAxAxAxAxAxAxAxAQAQAQAxAxAxAxAxrOvHvHCsAWAWAWAyBIAWAWAYCtCfBVBVBVBVBVBVBVBVBVBVBVBVCgCtBXBXBXBXBXBXBXBXBXAyafafafafafafafafafafafafafafaflYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafmcmcmcmcmcafafafafafafafafafafafafafafafafafaf afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvDvYvYvYvYvYvYvYCuxwCvCuxwCwCxCyxwCvCuxwCvvYvYvYvYvYvYvYvYvYCuxwCvCuxwCwCxCyxwCvCuxwCvvYvYvYvYvYvYwLCzxzAqxbAbCACBxbAEAqwLCCBrBrCDwLCECFCGCFCGBcAQAQBcCFCHCFCFCIAxAQAQAQCJCKCLCLCLCLCLCMCNAQAQAQAxCFCGCFCECGBcAQAQAQBcCGCFCFCOrOvHvHAyCPAWCQAYBIAWAWAyBJBJCRCRCRCRCSBVBVCTCRCRCRCSBJBJChChChChChChChChChAyafafafafafafafafafafafafafafaflYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvDvYvYvYvYvYvYvYCuxwCvCuxwCwCUCyxwCvCuxwCvvYvYvYvYvYvYvYvYvYCuxwCvCuxwCwCUCyxwCvCuxwCvvYvYvYvYvYvYwLwLztztxbCVCWxbxbztztwLwLwLwLwLwLBcBcBcBcBcBcAQAQBcBcBcBcBcBcAxAQAQCXCYCLCLCLCLCLCLCLCZCrAQAQAxBcBcBcBcBcBcAQAQAQBcBcBcBcBcAxDaDaAyAWDbDcAYBIAWAWAyAyBJBJBKBJBKBJBLBLBJBKBJBKBJBJBMBMBMBMBMBMBMBMBMBMAyafafafafafafafafafafafafafafaflYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf -afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvDDdDevDvYvYvYvYDfDgDhDfDgDiDjDkDgDhDfDgDhvYvYvDDlDdDevDvYvYDfDgDhDfDgDiDjDkDgDhDfDgDhvYvYvYvYvYvYvYvYvYvYAQAQAQAQDmAQAQDmAQAQAQCcAxCcAQAQAQAQAQAQAQAQAQAQAQAQCcAxAQAQDnCLCLCLDoDpDqCLCLCLDnAQAQAxCdAQAQAQAQAQAQAQAQAQAQAQAQCdAxAQAQAYDrDsAYAyAWAWAWBDAyAyAyAYAYAYAyDtDtAyAYAYAYAyAyAyAyAYAYAYAyAyAYAYAYAyafafafafafafafafafafafafafafaflYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf -afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvDDuxwDvvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYDwDxDuxwDyvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYAQAQAQAQDmAQAQDmAQAQAQAQDzAQAQAQAQAQAQAQAQAQAQAQAQAQAQDzAQAQDACLCLDoDBDBDBDqCLCLDCAQAQDzAQAQAQAQAQAQAQAQAQAQAQAQAQAQAQAQAQDDAWAWAWDEAWAWAWAWAWAWAWAWAWAWAWAWAWAWAWAWAWAYafafafafafafafafafafafafafafafafafafafafafafafafafafafDFlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYBhlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlY +afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvDDdDevDvYvYvYvYDfDgDhDfDgDiDjDkDgDhDfDgDhvYvYvDDlDdDevDvYvYDfDgDhDfDgDiDjDkDgDhDfDgDhvYvYvYvYvYvYvYvYvYvYAQAQAQAQDmAQAQDmAQAQAQCcAxCcAQAQAQAQAQAQAQAQAQAQAQAQCcAxAQAQDnCLCLCLDoDqDpCLCLCLDnAQAQAxCdAQAQAQAQAQAQAQAQAQAQAQAQCdAxAQAQAYDrDsAYAyAWAWAWBDAyAyAyAYAYAYAyDtDtAyAYAYAYAyAyAyAyAYAYAYAyAyAYAYAYAyafafafafafafafafafafafafafafaflYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf +afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvDDuxwDvvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYDwDxDuxwDyvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYAQAQAQAQDmAQAQDmAQAQAQAQDzAQAQAQAQAQAQAQAQAQAQAQAQAQAQDzAQAQDACLCLDoDBDBDBDpCLCLDCAQAQDzAQAQAQAQAQAQAQAQAQAQAQAQAQAQAQAQAQDDAWAWAWDEAWAWAWAWAWAWAWAWAWAWAWAWAWAWAWAWAWAYafafafafafafafafafafafafafafafafafafafafafafafafafafafDFlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYBhlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlY afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvDxwxwDGvYvYvYvYvYvYvYvYvYvYDHvYvYvYvYvYvYvYvYDIDJvExwDGvYvYvYvYvYvYvYvYDHvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYBcAQAQAQAxAQAQAxAQAQAQAQDzAQAQAQAQAQAQAQAQAQAQAQAQAQAQDzAQAQDACLCLDKDBDLDBDMCLCLDCAQAQDzAQAQAQAQAQAQAQAQAQAQAQAQAQAQAQAQAQAYAWAWAWAYAWAWAWAWAWAWAWAWAWAWAWAWAWAWAWAWAWAYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvDDNxwDOvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYDPxwDNxwDOvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYvYAQAQAQAQDmAQAQDmAQAQAQAQDzAQAQAQAQAQAQAQAQAQAQAQAQAQAQDzAQAQDACLCLDQDBDBDBDRCLCLDCAQAQDzAQAQAQAQAQAQAQAQAQAQAQAQAQAQAQAQAQDDAWAWAWDEAWAWAWAWAWAWAWAWAWAWAWAWAWAWAWAWAWAYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf -afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvDDSDTvDvYvYvYvYDUDVDWDUDVDXDYDZDVDWDUDVDWvYvYvDEaDSEbvDvYvYDUDVDWDUDVDXDYDZDVDWDUDVDWvYvYvYvYvYvYvYvYvYvYAQAQAQAQDmAQAQDmAQAQAQCcAxCcAQAQAQAQAQAQAQAQAQAQAQAQCcAxAQAQEcCLCLCLDQEdEeCLCLCLEfAQAQAxCdAQAQAQAQAQAQAQAQAQAQAQAQCdAyEgEgAyAyAyAyAyAWAWAWBDAyAyAyAYAYAYAyBEBEAyAYAYAYAyAyAyAyAYAYAYAyAyAYAYAYAyafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf +afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvDDSDTvDvYvYvYvYDUDVDWDUDVDXDYDZDVDWDUDVDWvYvYvDEaDSEbvDvYvYDUDVDWDUDVDXDYDZDVDWDUDVDWvYvYvYvYvYvYvYvYvYvYAQAQAQAQDmAQAQDmAQAQAQCcAxCcAQAQAQAQAQAQAQAQAQAQAQAQCcAxAQAQEcCLCLCLDQEeEdCLCLCLEfAQAQAxCdAQAQAQAQAQAQAQAQAQAQAQAQCdAyEgEgAyAyAyAyAyAWAWAWBDAyAyAyAYAYAYAyBEBEAyAYAYAYAyAyAyAyAYAYAYAyAyAYAYAYAyafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvDvYvYvYvYvYvYvYCuxwCvCuxwCwCUCyxwCvCuxwCvvYvYvYvYvYvYvYvYvYCuxwCvCuxwCwCUCyxwCvCuxwCvvYvYvYvYvYvYEhEhEiEiEhEjEjEjEhEiEiEhEhEjEjEhEhBcBcBcBcBcBcAQAQBcBcBcBcBcBcAxAQAQEkElCLCLCLCLCLCLCLEmEnAQAQAxBcBcBcBcBcBcAQAQBcBcBcBcBcBcAyEoEoEpEqErEsAYBIAWAWAyAyBJBJBKBJBKBJBLBLBJBKBJBKBJBJBMBMBMBMBMBMBMBMBMBMAyafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvDvYvYvYvYvYvYvYCuxwCvCuxwCwCxCyxwCvCuxwCvvYvYvYvYvYvYvYvYvYCuxwCvCuxwCwCxCyxwCvCuxwCvvYvYvYvYvYvYEhEtEuEuEvEwExExEyEuEzEhEAEBECEDEhCHCECFCGCGBcAQAQBcCOEECGCFCFAxAQAQAQEFEGCLCLCLCLCLEmCKAQAQAQAxEHCFCECFCGBcAQAQBcCFCGCFEIEEAyEoEoEoEoEoEoAYBIAWAWAyBJBJBTBTBTBTBUBVBVBWBTBTBTBUBJBJBXBXBXBXBXBXBXBXBXAyafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvDvDvYEJEJvYvYvYvEvEvEvEvDvDvDvDvDvEvEvEvEvYvYvYBYBPCivYvYvYvEvEvEvEvDvDvDvDvDvEvEvEvEvYvYvYBOBPvYEiEuEuEuEuEuEuEuEuEuEKEhELEuEMENEhEOEPEPEPEPEOEQEQEOEPEPEPEPEOEOAQAQAQAQEkCoERERERCqEnAQAQAQAQESESESESESESESETETESESESESESESAyEoEoEoEoEoEoAyBIAWAWAYCeCfBVBVBVBVBVBVBVBVBVBVBVBVCgCeChChChChChChChChChAyafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf -afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvEvYBPEJvYvXvEvEafafafafafafafafafafafvEvEvXvYCaBPBQvYvXvEvEafafEUEVEVEVEVEVEUafafvEvEvXvYBYBPBQEiEuEuEWEXEuEuEWEXEuEKEhEYEuEuEZEhFaFbFbFbFbFbFbFbFbFbFbFbFbFaEOAxCcAQAQAQAQAQAQAQAQAQAQAQCcAxESFcFdFdFdFdFeFeFeFeFdFdFdFdFcAyEoEoFfFgEoFfAYBIAWAWAYCtCfBVBVBVBVBVBVBVBVBVBVBVBVCgCtBXBXBXBXBXBXBXBXBXAyafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf -afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvEvYvYCivYvEvEmKafafafafafafafafafafafmKvEvEvYCaBPvYvYvEvEmKafEUFhFiFjFkFlFmFhEUafmKvEvEvYvYBPvYEhFnEuEWEXEuEuEWEXEuEKEhFoEuEMENEhFbFbFbFbFbFbFbFbFbFbFbFbFbFbEOAxAxAQAQAQAQAQAQAQAQAQAQAQAxAxESFeFeFeFeFeFeFeFeFeFeFeFeFeFeAyEoEoFfFgEoFfAYBIAWAWAyBJBJCRCRCRCRCSBVBVCTCRCRCRCSBJBJChChChChChChChChChAyafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf -afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvEBFBFBFvEvEafmKafafafafafafafafafafafmKafvEvEBFBFBFvEvEafmKEUEUFpFqFrFqFrFqFsEUEUmKafvEvEBFBFBFEhFtEuEWEXEuEuEWEXEuEKEhFuFvFwFxEhFbFbFyFzFAFBFbFbFyFCFDFBFbFbEOafAxAxAxAxAxAQAxAQAxAxAxAxAxafESFeFEFEFEFEFeFeFeFeFEFEFEFEFeAyEoEoFfFgEoFfAyBIAWAWAyAyBJBJBKBJBKBJBLBLBJBKBJBKBJBJBMBMBMBMBMBMBMBMBMBMAyafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf -afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvDvYvYvYvDafafmKafafafafafafafafafafafmKafafvDvYvYvYvDafafmKEVFrFrFrFFFGFHFrFrFrEVmKafafvDvYvYvYEhFtEuEuEuEuEuEuEuEuEKEhEhELFIFJEhFbFbFyFKFLFBFbFbFyFMFNFBFbFbEOafafAxFOFPAQAQCLAQAQFPFQAxafafESFeFeFeFeFeFeFeFeFeFeFeFeFeFeAyEoEoFfFgEoFfAYAWAWAWBDAyAyAyAYAYAYAyDtDtAyAYAYAYAyAyAyAyAYAYAYAyAyAYAYAYAyafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf -afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvDvYvYvYvDafafmKafafafafafafafafafafafmKafafvDvYvYvYvDafafmKEUFRFSFTEUFUEUFVFWFXEUmKafafvDvYvYvYEhFtEuEuEzFYFYFYFYFYFZEhGaEyEvGbEhFbFbFbFbFbFbFbFbFbFbFbFbFbFbEOafafAxFOFPAQAQCLAQAQFPFQAxafafESFcFdFdFdFdFeFeFeFeFdFdFdFdFcAyEoEoFfFgEoFfAYAWAWAWAWAWAWAWAWAWAWAWAWAWAWAWAWAWAYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf -afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvDvYvYvYvDafafmKafafafafafafafafafafafmKafafvDvYvYvYvDafafmKEUGcEVEUEUEUEUEUEVGcEUmKafafvDvYvYvYEhEjGdEuEhGeGfGgGhGfGiEhFtEuEuGjEhFbFbFyGkGlFBFbFbFyGmGnFBFbFbEOafafAxGoAQAQAQCLAQAQAQGpAxafafESESESESESESESETETESESESESESESAyEoEoFfFgEoFfAyAWAWAWAWAWAWAWAWAWAWAWAWAWAWAWAWAWAYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf -afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvEvYvYvYvEmKmKmKafafafafafafafafafafafmKmKmKvEvYvYvYvEmKmKmKEUFrFWEUGqGrGsEUFSFrEUmKmKmKvEvYvYvYEhFtEuEuGtEyGuEuEuGuEvGvEyEuEuGwEhFbFbFyGxGyFBFbFbFyGzGAFBFbFbEOafafAxFOFPAQAQCLAQAQFPFQAxafafESGBGCGCGCGCGBGBGBGBGDGEGEGEGFAyEoEoFfFgEoFfAyAyAWAWAWAWAWAWGGGGGGAWAWAWAWGGGGGGAYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf -afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvEvYvYvYvEafafafafafafafafafafafafafafafafafvEvYvYvYvEafafafEVFrFWEVGHGIGJEVFSFrEVafafafvEvYvYvYEhFtEuEuEuEuEuEuEuEuEuEuEuEuEuGKEhFbFbFbFbFbFbFbFbFbFbFbFbFbFbEOafafAxFOFPAQAQCLAQAQFPFQAxafafESGBGBGBGBGBGBGBGBGBGBGBGBGBGBAyEoEoEoEoEoEoAyAyAyAYAYAYAyAYAYAYAyAYAYAYAyAYAYAYAyafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf -afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvEvYvYvYvEafafafafafafafafafafafafafafafafafvEvYvYvYvEafafEUFhFRFWEVGHGLGJEVFSFXFhEUafafvEvYvYvYEhFtEuEuEuEuEuEuEuEuEuEuEuEuEuGwEhFbFbFbFbFbFbGMGMGMGMGMGMGMGMEOafafGNGNGNGOGOGPGOGOGNGNGNafafESGQESGRESGSESGBGBESGTESGUESGVAyEoEoEoEoEoEoAYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf -afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvDvYvYvYvDvDvDafafafafafafafafafafafafafvDvDvDvYvYvYvDvDvDFhGWFrFWFhEVGXEVFhFSFrGWFhvDvDvDvYvYvYEhFtEuEzFYFYFYFnEzFYFYFnEuEuEuGKEhGYGZGZFbFbHaHbHbHbHcHbHbHbHbEOafafGNHdHeGOHeHeHeGOHeHdGNafafESHfESHfESHfESGBGBESHfESHfESHfAyEoEoHgHgHgHgAYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf -afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvDvYvYvYxvxwxxafafafafafafafafafafafafafxxxwxvvYvYvYHhxwHhHiFrFrFrHjHkFrFrHjFrFrFrHiHhxwHhvYvYvYEhEjEuEKEjEjEjFtEKHlFJFtEzHmHnHoEhHpHqHrFbFbHaHsHtHtHtHtHtHtHtEOafafGNHeHuHvHeHeHeHvHwHeGNafafESESESESESESESGBGBESESESESESESAyEoEoHxHxHxHxAYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf -afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvDvYvYvYxvxwxxafafafafafafafafafafafafafxxxwxvvYvYvYHhxwHhHiFrFrFrFrFrFrFrFrFrFrFrHiHhxwHhvYvYvYEhHyEuEvHzHAHBEyEvHCEhHDHEEhEhEhEhHFHGHHFbFbHaHtHtHtHtHtHtHtHtEOafafGNGOHeGOHeHeHeGOHeGOGNafafESHIGBHIGBHIGDGBGBHJHIGBHIGBHIAyEoEoEoEoEoEoAYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf -afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvDvYvYvYvDvDvDafafafafafafafafafafafafafvDvDvDvYvYvYvDvDvDFhHKFrFWEVFSFrFWEVFSFrHLFhvDvDvDvYvYvYEhHyEuEuEuEuEuEuEuHMEhHDHNHOHOHPEhHQHRHSFbFbHtHtHtHTHUHVHWHtHtEOafafGNHeHeHeHeHeHeHeHeHeGNafafESGBGBGBGBGBGBGBGBGBGBGBGBGBGBAyHXEoEoEoEoAYAYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf +afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvEvYBPEJvYvXvEvEafafafafafafafafafafafvEvEvXvYCaBPBQvYvXvEvEafafEUEVEVEVEVEVEUafafvEvEvXvYBYBPBQEiEuEuEWEXEuEuEWEXEuEKEhEYEuEuEZEhFbFaFaFaFaFaFaFaFaFaFaFaFaFbEOAxCcAQAQAQAQAQAQAQAQAQAQAQCcAxESFcFdFdFdFdFeFeFeFeFdFdFdFdFcAyEoEoFfFgEoFfAYBIAWAWAYCtCfBVBVBVBVBVBVBVBVBVBVBVBVCgCtBXBXBXBXBXBXBXBXBXAyafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf +afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvEvYvYCivYvEvEmKafafafafafafafafafafafmKvEvEvYCaBPvYvYvEvEmKafEUFhFiFjFkFlFmFhEUafmKvEvEvYvYBPvYEhFnEuEWEXEuEuEWEXEuEKEhFoEuEMENEhFaFaFaFaFaFaFaFaFaFaFaFaFaFaEOAxAxAQAQAQAQAQAQAQAQAQAQAQAxAxESFeFeFeFeFeFeFeFeFeFeFeFeFeFeAyEoEoFfFgEoFfAYBIAWAWAyBJBJCRCRCRCRCSBVBVCTCRCRCRCSBJBJChChChChChChChChChAyafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf +afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvEBFBFBFvEvEafmKafafafafafafafafafafafmKafvEvEBFBFBFvEvEafmKEUEUFpFqFrFqFrFqFsEUEUmKafvEvEBFBFBFEhFtEuEWEXEuEuEWEXEuEKEhFuFvFwFxEhFaFaFzFyFBFAFaFaFzFCFDFAFaFaEOafAxAxAxAxAxAQAxAQAxAxAxAxAxafESFeFEFEFEFEFeFeFeFeFEFEFEFEFeAyEoEoFfFgEoFfAyBIAWAWAyAyBJBJBKBJBKBJBLBLBJBKBJBKBJBJBMBMBMBMBMBMBMBMBMBMAyafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf +afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvDvYvYvYvDafafmKafafafafafafafafafafafmKafafvDvYvYvYvDafafmKEVFrFrFrFFFGFHFrFrFrEVmKafafvDvYvYvYEhFtEuEuEuEuEuEuEuEuEKEhEhELFIFJEhFaFaFzFKFLFAFaFaFzFMFNFAFaFaEOafafAxFOFPAQAQCLAQAQFPFQAxafafESFeFeFeFeFeFeFeFeFeFeFeFeFeFeAyEoEoFfFgEoFfAYAWAWAWBDAyAyAyAYAYAYAyDtDtAyAYAYAYAyAyAyAyAYAYAYAyAyAYAYAYAyafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf +afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvDvYvYvYvDafafmKafafafafafafafafafafafmKafafvDvYvYvYvDafafmKEUFRFSFTEUFUEUFVFWFXEUmKafafvDvYvYvYEhFtEuEuEzFYFYFYFYFYFZEhGaEyEvGbEhFaFaFaFaFaFaFaFaFaFaFaFaFaFaEOafafAxFOFPAQAQCLAQAQFPFQAxafafESFcFdFdFdFdFeFeFeFeFdFdFdFdFcAyEoEoFfFgEoFfAYAWAWAWAWAWAWAWAWAWAWAWAWAWAWAWAWAWAYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf +afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvDvYvYvYvDafafmKafafafafafafafafafafafmKafafvDvYvYvYvDafafmKEUGcEVEUEUEUEUEUEVGcEUmKafafvDvYvYvYEhEjGdEuEhGeGfGgGhGfGiEhFtEuEuGjEhFaFaFzGkGlFAFaFaFzGmGnFAFaFaEOafafAxGoAQAQAQCLAQAQAQGpAxafafESESESESESESESETETESESESESESESAyEoEoFfFgEoFfAyAWAWAWAWAWAWAWAWAWAWAWAWAWAWAWAWAWAYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf +afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvEvYvYvYvEmKmKmKafafafafafafafafafafafmKmKmKvEvYvYvYvEmKmKmKEUFrFWEUGqGrGsEUFSFrEUmKmKmKvEvYvYvYEhFtEuEuGtEyGuEuEuGuEvGvEyEuEuGwEhFaFaFzGxGyFAFaFaFzGzGAFAFaFaEOafafAxFOFPAQAQCLAQAQFPFQAxafafESGBGCGCGCGCGBGBGBGBGDGEGEGEGFAyEoEoFfFgEoFfAyAyAWAWAWAWAWAWGGGGGGAWAWAWAWGGGGGGAYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf +afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvEvYvYvYvEafafafafafafafafafafafafafafafafafvEvYvYvYvEafafafEVFrFWEVGHGIGJEVFSFrEVafafafvEvYvYvYEhFtEuEuEuEuEuEuEuEuEuEuEuEuEuGKEhFaFaFaFaFaFaFaFaFaFaFaFaFaFaEOafafAxFOFPAQAQCLAQAQFPFQAxafafESGBGBGBGBGBGBGBGBGBGBGBGBGBGBAyEoEoEoEoEoEoAyAyAyAYAYAYAyAYAYAYAyAYAYAYAyAYAYAYAyafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf +afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvEvYvYvYvEafafafafafafafafafafafafafafafafafvEvYvYvYvEafafEUFhFRFWEVGHGLGJEVFSFXFhEUafafvEvYvYvYEhFtEuEuEuEuEuEuEuEuEuEuEuEuEuGwEhFaFaFaFaFaFaGMGMGMGMGMGMGMGMEOafafGNGNGNGOGOGPGOGOGNGNGNafafESGQESGRESGSESGBGBESGTESGUESGVAyEoEoEoEoEoEoAYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf +afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvDvYvYvYvDvDvDafafafafafafafafafafafafafvDvDvDvYvYvYvDvDvDFhGWFrFWFhEVGXEVFhFSFrGWFhvDvDvDvYvYvYEhFtEuEzFYFYFYFnEzFYFYFnEuEuEuGKEhGZGYGYFaFaHaHbHbHbHcHbHbHbHbEOafafGNHdHeGOHeHeHeGOHeHdGNafafESHfESHfESHfESGBGBESHfESHfESHfAyEoEoHgHgHgHgAYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf +afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvDvYvYvYxvxwxxafafafafafafafafafafafafafxxxwxvvYvYvYHhxwHhHiFrFrFrHjHkFrFrHjFrFrFrHiHhxwHhvYvYvYEhEjEuEKEjEjEjFtEKHlFJFtEzHmHnHoEhHpHqHrFaFaHaHsHtHtHtHtHtHtHtEOafafGNHeHuHvHeHeHeHvHwHeGNafafESESESESESESESGBGBESESESESESESAyEoEoHxHxHxHxAYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf +afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvDvYvYvYxvxwxxafafafafafafafafafafafafafxxxwxvvYvYvYHhxwHhHiFrFrFrFrFrFrFrFrFrFrFrHiHhxwHhvYvYvYEhHyEuEvHzHAHBEyEvHCEhHDHEEhEhEhEhHFHGHHFaFaHaHtHtHtHtHtHtHtHtEOafafGNGOHeGOHeHeHeGOHeGOGNafafESHIGBHIGBHIGDGBGBHJHIGBHIGBHIAyEoEoEoEoEoEoAYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf +afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvDvYvYvYvDvDvDafafafafafafafafafafafafafvDvDvDvYvYvYvDvDvDFhHKFrFWEVFSFrFWEVFSFrHLFhvDvDvDvYvYvYEhHyEuEuEuEuEuEuEuHMEhHDHNHOHOHPEhHQHRHSFaFaHtHtHtHTHUHVHWHtHtEOafafGNHeHeHeHeHeHeHeHeHeGNafafESGBGBGBGBGBGBGBGBGBGBGBGBGBGBAyHXEoEoEoEoAYAYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvEvYvYvYvEafafafafafafafafafafafafafafafafafvEvYvYvYvEafafEVFSFrFWEVFSFrFWEVFSFrFWEVafafvEvYvYvYEhHyEuEuEuHYHZEuEuIaEhHDEuIbIcIdEhEOEOEOEOEOEOEOEOEOEOEOEOEOEOEOGNGNGNHeHeHeHeHeHeHeHeHeGNGNGNESIeGBIeGBIeGDGBGBHJIeGBIeGBIeAyAYAYAYAYAYAYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvEvYvYvYvEmKmKmKmKmKmKmKmKmKmKmKmKmKmKmKmKmKvEvYvYIfvEafafEVFSFrFWEVFSFGFWEVFSFrFWEVafafvEvYvYvYEhIgEuEuEuEuEuEuEuIhEhHDEuEuIiIdEhIjIkIkIkIlGNHeHeHeHeHeHeHeHeHeHeHeGNGNImGNGNHeGNGNImGNGNHeHeGNGNGNESESESESESESESESESESESESESafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvEvYvYvYvEafafafafafafafafafafafafafafafafafvEvYvYvYvEafafEVFSFrFWEVFSFrFWEVFSFrFWEVafafvEvYvYvYEhInEuEuEuIoIpEuEuIqEhIrIsEuItIuEhIvEuEuEuIwGNHeGNGNGNGNIxGNGNGNHeHeHeHeHeHeGNHeGNHeHeHeHeHeHeHeHeGNafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf @@ -2573,7 +2573,7 @@ afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvDvYvYvYxvxwxxaf afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvDvYvYvYxvxwxxafafafafafafafafafafafafafxxxwxvvYvYvYHhxwHhHiFrFrISFrFrFrFrFrISFrFrHiHhxwHhvYvYvYEhEhITEhHlEhEhIUEuIVEhHDEuEuEuEuIWEuEuIXEuIYGNHeGNIZIDIDIDIDJaGNIQJbJbJbJbJbIQIQIQJbJbJbJbJcJdGNHeGNGNGNGNGNGNGNafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvDvYvYvYvDvDvDafafafafafafafafafafafafafvDvDvDvYvYvYvDvDvDFhEVJeFhEVEVJfEVEVFhJeEVFhvDvDvDvYvYvYEhJgEuJhJiJjEhJkEuJlEhJmJnJoJpJqEhJrJsJsJsJtGNHeGNIZJuJvJvIDIDJwIQIQJxJyJxIQIQIQIQIQJxJyJxJzIQGNHeHeHeHeHeHeHeGNafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvEvYvYvYvEafafafmKmKmKmKmKmKmKmKmKmKmKafafafvEvYvYvYvEafafEUJAJBEUJCJDJEJFJGEUJHJIEUafafvEvFvFvFEhJgEuJJJKJLEhJMEuJNEhEhEhEhEhEhEhEhEhEhEhGNGNHeGNGNGNGNGNGNGNGNIQJbJbJbJbJbIQIQIQJbJbJbJbJOIQGNGNGNGNGNGNGNHeGNGNGNafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf -afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvEvYvYvYvEmKmKmKmKafafafafafafafafafmKmKmKmKvEvYvYvYvEmKmKEUJPJPEUJQJRJEJEJSEUJPJPEUmKmKvEvYvYvYEhEhJTEhEjEjEhEhIHEhEhJUJVJWEjJXJYHzJZJZKaGNHeHeGNGNKbKbKbKbKbGNKcKcKcKcKcKcKcKcKcKcKcKcKcKdKcGNKeKeKeKeKeGNHeHeHeGNafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf +afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvEvYvYvYvEmKmKmKmKafafafafafafafafafmKmKmKmKvEvYvYvYvEmKmKEUJPJPEUJRJQJEJEJSEUJPJPEUmKmKvEvYvYvYEhEhJTEhEjEjEhEhIHEhEhJUJVJWEjJXJYHzJZJZKaGNHeHeGNGNKbKbKbKbKbGNKcKcKcKcKcKcKcKcKcKcKcKcKcKdKcGNKeKeKeKeKeGNHeHeHeGNafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafwrvDvDvDwrafafafafafafafafafafafafafafafafafwrvDvDvDwrafafEUKfKgEUKhJEKiKjKkEUKlKmEUafafwrvYvYvYEhKnEuJhKoKpEhFtEuEvHzEyEuEvEjEyEuEuEuEuEKGNHeGNGNGNKqKqKqKqKqGNKrKsKsKsKsKsKsKsKsKsKsKsKsKtKrGNKqKqKqKqKqGNGNGNHeGNafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvDvVvWvVvDafafafafafafafafafafafafafafafafafvDvVvVvVvDafafEUKuKuEUKvKwJEKxKyEUKuKuEUafafvDvYvYvYEhKzEuEuEuKAEhFtEuEuEzFYEuEuKBEuEuEuEuEuEKGNHeGNKCKDKEKEKEKEKEKFKsKsKsKsKsKsKsKsKsKsKsKsKsKtKsKFKGKGKGKGKGKDKHGNHeGNafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafvDvDvDvDvDafafafafafafafafafafafafafafafafafvDvDvDvDvDafafEUKIKIEUEUKuKuKuEUEUKIKIEUafafvDvYvYvYEhKJEuEuIXKKEhKLEuEuEKKMEuKNEjFnEuEMEuEuEKGNHeGNKCKDKEKOKEKOKEKFKsKsKsKsKsKsKsKsKsKsKsKsKsKtKsKFKGKPKGKPKGKDKHGNHeGNafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf @@ -2603,26 +2603,26 @@ afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafMhMhMhMhNkMhMhMhNlMhMhMhNmMhMhMhMhMhMhMhNnMhMhMhMhMhMhNoMOMOMOMONpMOMOMOMOMOMNMhMOMSMSMOMhMXMYMHMHNqNqNrNsNsNtMhMhMhMhMhafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafahLXNuNuNuNuNuNuNuNuNuNuNuNuNuNuNuNuNuNuNuLXah afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafNvMNMOMOMOMOMOMONwMOMOMONxMOMOMOMOMOMOMONyMOMONzNANBMhMOMSMSMSMSMSMSMSMSMSMSMOMhMOMSMSMOMlNCNCNDNDNCNCNCMhMhMhMhNENFNGNCafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafahNHNINININININININININININININININININININHah afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafNvMOMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMONJMOMSNKNKNKNKNKNKNKNKMSMONJMOMSMSMONJMOMOMOMOMOMOMOMOMOMONCNLNMNNNCafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafahNONPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNOah -afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafNvMOMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSNQMSMSNRNRNRNRNRNRNRNRMSMSNQMSMSMSMSNQMSMSMSMSMSMSMSMSMSMONSNTNFNUNCafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafahNONPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNOah -afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafNvMOMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMONJMOMSNVNVNVNVNVNVNVNVMSNTNDMOMSMSMONJMOMOMOMOMOMOMOMOMOMONCNWNMNXNCafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafahNONPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNOah -lYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYafafafafafafafafafafNvMNMOMOMOMOMOMONYMOMOMONZMOMOMOOaMOMOMOObMOMOMOMOMNMhMOMSMSMSMSMSMSMSMSMSMSNTMhMOMSMSMOMlNCNCOcNCNCMhNCNCNQNQMhOdNFOeNCafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafahNONPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNOah -ahahahahahahahahahahahOfOfOfOfOfOfOfOfOfOfOfOfOfOfOfOfOfOfOfOfOfahahahahahahahlYafafafafafafafafafafMhMhMhMhNkMhMhMhOgMhMhMhOhMhMhMhOiMhMhMhOjMhMhMhOkMhMhMOMOMOMOMOOlMOMOMOMOMOMNMhMOMSMSMOMhOmOnOoOpOqMhOrMSMSMSMhMhMhMhMhafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafahNONPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNOah -ahmcmcmcmcmcmcmcmcmcmcOsOsOsOsOsOfOtOuOvOfOsOsOsOsOsOsOsOsOsOsOsmcmcahmcmcmcmclYafafafafafafafafafafafMzMAMnMnMnMhOwOwOwOxOyOyOyOxOzOzOzOxOAOAOAMhMSMSMSMhMhMhMhMhMhOBOBMhMhMhMhMhMhMOMSMSMOMhOCOoOoOoOCMhODMSMSMSMSOEMhafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafahNONPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNOah -ahmcmcmcmcmcmcmcmcmcmcOsOsOsOsOsOfOFOuOuOfOsOsOsOsOsOsOsOsOsOsOsmcmcahmcmcmcmclYafafafafafafafafafafafMMMAMnMnMnMhOwOwOwOxOyOyOyOxOzOzOzOxOAOAOAMhMSMSMSMhOGOGOGOGOGOGOGOGOGOGOGMnMhMOMSMSMOMhOHOIOoOoOoMhOrMSMSOrMSOrMhafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafahNONPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNOah +afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafNvMOMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSNQMSMSNRNRNRNRNRNRNRNRMSMSNQMSMSMSMSNQMSMSMSMSMSMSMSMSMSMONTNSNFNUNCafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafahNONPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNOah +afafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafNvMOMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMSMONJMOMSNVNVNVNVNVNVNVNVMSNSNDMOMSMSMONJMOMOMOMOMOMOMOMOMOMONCNWNMNXNCafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafahNONPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNOah +lYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYlYafafafafafafafafafafNvMNMOMOMOMOMOMONYMOMOMONZMOMOMOOaMOMOMOObMOMOMOMOMNMhMOMSMSMSMSMSMSMSMSMSMSNSMhMOMSMSMOMlNCNCOcNCNCMhNCNCNQNQMhOdNFOeNCafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafahNONPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNOah +ahahahahahahahahahahahOfOfOfOfOfOfOfOfOfOfOfOfOfOfOfOfOfOfOfOfOfahahahahahahahlYafafafafafafafafafafMhMhMhMhNkMhMhMhOgMhMhMhOhMhMhMhOiMhMhMhOjMhMhMhOkMhMhMOMOMOMOMOOlMOMOMOMOMOMNMhMOMSMSMOMhOnOmOpOoOqMhOrMSMSMSMhMhMhMhMhafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafahNONPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNOah +ahmcmcmcmcmcmcmcmcmcmcOsOsOsOsOsOfOtOuOvOfOsOsOsOsOsOsOsOsOsOsOsmcmcahmcmcmcmclYafafafafafafafafafafafMzMAMnMnMnMhOwOwOwOxOyOyOyOxOzOzOzOxOAOAOAMhMSMSMSMhMhMhMhMhMhOBOBMhMhMhMhMhMhMOMSMSMOMhOCOpOpOpOCMhODMSMSMSMSOEMhafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafahNONPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNOah +ahmcmcmcmcmcmcmcmcmcmcOsOsOsOsOsOfOFOuOuOfOsOsOsOsOsOsOsOsOsOsOsmcmcahmcmcmcmclYafafafafafafafafafafafMMMAMnMnMnMhOwOwOwOxOyOyOyOxOzOzOzOxOAOAOAMhMSMSMSMhOGOGOGOGOGOGOGOGOGOGOGMnMhMOMSMSMOMhOIOHOpOpOpMhOrMSMSOrMSOrMhafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafahNONPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNOah ahmcmcmcmcmcmcOsOsOsOfOfOfOfOsOfOfOfOfOJOfOfOfOfOfOfOfOsOsOsOsOsmcmcahmcmcmcmclYafafafafafafafafafafafMMMAMnMnMnMhOwOwOwOxOyOyOyOxOzOzOzOxOAOAOAMhMSMSMSMhOGOGOGOGOGOGOGOGOGOGOGOGMhOKNKNKOKMhNCNCOLNCNCMhODMSOrMhMhMhMhafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafahNONPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNOah -ahmcmcmcOsOsOsOsOMOuOuOuOuOuOuOuOuOuOuOuOuOuOuOuOuOuOfOsOsOsOsOsmcmcahmcmcmcmclYafafafafafafafafafafafMMMAMnMnMnMhOwOwOwOxOyOyOyOxOzOzOzOxOAOAOAMhMSMSMSMhOGOGOGOGOGOGOGOGOGOGOGOGMhONONONONMhOOOoOoOoOOMhOrMSODMhafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafahNONPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNOah -ahmcmcmcOsOsOuOMOMOMOuOuOuOuOuOuOuOuOuOuOuOuOuOuOuOuOfOPOQOsOsOsmcmcahmcmcmcmclYafafafafafafafafafafafNgMAMnOROSMhOwOwOwOxOyOyOyOxOzOzOzOxOAOAOAMhOTOUOVMhOGOGOGOGOGOGOGOGOGOGOGOGMhMhOWOXMhMhOoOoOoOoOoMhODMSOrMhafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafahNONPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNOah -ahmcmcmcOsOsOMOMOMOsOsOsOfOfOfOfOJOfOfOfOfOJOfOuOuOuOJOYOZOsOsOsmcmcahmcmcmcmclYafafafafafafafafafafafMhMhMhMhMhMlMiMiMiMlMiMiMiMlMiMiMiMlMiMiMiMlMhMhMhMhOGOGOGOGOGOGOGOGOGOGOGMnMhafafafafMhOOOoOOOoOOMhOrMSMhMhafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafahNONPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNOah +ahmcmcmcOsOsOsOsOMOuOuOuOuOuOuOuOuOuOuOuOuOuOuOuOuOuOfOsOsOsOsOsmcmcahmcmcmcmclYafafafafafafafafafafafMMMAMnMnMnMhOwOwOwOxOyOyOyOxOzOzOzOxOAOAOAMhMSMSMSMhOGOGOGOGOGOGOGOGOGOGOGOGMhONONONONMhOOOpOpOpOOMhOrMSODMhafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafahNONPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNOah +ahmcmcmcOsOsOuOMOMOMOuOuOuOuOuOuOuOuOuOuOuOuOuOuOuOuOfOPOQOsOsOsmcmcahmcmcmcmclYafafafafafafafafafafafNgMAMnOROSMhOwOwOwOxOyOyOyOxOzOzOzOxOAOAOAMhOTOUOVMhOGOGOGOGOGOGOGOGOGOGOGOGMhMhOWOXMhMhOpOpOpOpOpMhODMSOrMhafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafahNONPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNOah +ahmcmcmcOsOsOMOMOMOsOsOsOfOfOfOfOJOfOfOfOfOJOfOuOuOuOJOYOZOsOsOsmcmcahmcmcmcmclYafafafafafafafafafafafMhMhMhMhMhMlMiMiMiMlMiMiMiMlMiMiMiMlMiMiMiMlMhMhMhMhOGOGOGOGOGOGOGOGOGOGOGMnMhafafafafMhOOOpOOOpOOMhOrMSMhMhafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafahNONPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNOah ahmcmcmcOsOMOMOsOsOsOsOsOsOsOsOfOuOuOFOfPaOuOfOuOuOuOJOYPbOsOsOfmcmcahmcmcmcmclYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafMhMiMiMiMiMiMiMiMiMiMiMiMiMhafafafafMhMhMhMhMhMhMhMhMhMhafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafahNONPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNOah ahmcmcmcOsOMOsOsOsmcmcOsOfOfOfOfPcOuOtOfPcOtOfOuOuOuOfOYOYOYPdOfmcmcahmcmcmcaflYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafahNONPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNOah ahmcmcmcOsOMOMOsmcmcmcOsPePfPfOfOfOfOfOfOfOfOfOuOuOuOfOYOYOYPgOfmcmcahmcmcmcaflYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafahNONPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNPNOah ahmcOsOMOMOMOMOsOsmcmcOsPhPiPhOJOuOuOuOuOuOuOuOuOuOuOfPjPkPlOfOfmcmcahmcmcmcaflYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafahNONONONONONONONONONONONONONONONONONONONONOah ahmcPmOMOMOMOMOMOsmcmcOfPnPhPhOJOuOuOuOuOuOuOuOuOuOuOfOsOsOsOsOsmcmcahmcmcmcaflYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafahahahahahahahahahahahahahahahahahahahahahahah -ahmcPoPpPqOMPrOMOMmcmcOfPnPsOfOfOfOfOfOfOfOfOfOfOJOfOfOfOfOfOfOfOfOfOfmcmcafaflYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf -ahmcPtOMPqOMPqOMOMmcmcOsOsOsOfOuOuOuOuOuOuOfPuPvPvPvPwOfOuOuOuOuOuOuOfmcafafaflYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf -ahmcOsOMPqOMPxOMOMmcmcafafmcOfOuOtOuOuOuOuOfPvPvPyPvPvOfOuOuOuOuOtOuOfmcafafaflYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf +ahmcPoPqPpOMPrOMOMmcmcOfPnPsOfOfOfOfOfOfOfOfOfOfOJOfOfOfOfOfOfOfOfOfOfmcmcafaflYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf +ahmcPtOMPpOMPpOMOMmcmcOsOsOsOfOuOuOuOuOuOuOfPuPvPvPvPwOfOuOuOuOuOuOuOfmcafafaflYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf +ahmcOsOMPpOMPxOMOMmcmcafafmcOfOuOtOuOuOuOuOfPvPvPyPvPvOfOuOuOuOuOtOuOfmcafafaflYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf ahmcOsPzOMOMOMPAOMmcmcafafmcOfOuOuOuOuOuOuOJPvPvPBPvPvOJOuOuOuOuOuOuOfmcafafaflYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf -ahmcOsOsOMOMOMOMOsmcmcmJafafOfOuOuOfPCPDPEOfPvPFPGPvPHOfPCPDPEOfOuOuOfafafafaflYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafPIPIPIPIPIPIPIPIPIPIPIPIPIPIPIPIPIPIPIPIPIPIPIPIPIPIPIPIPIafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf +ahmcOsOsOMOMOMOMOsmcmcmJafafOfOuOuOfPCPDPEOfPvPGPFPvPHOfPCPDPEOfOuOuOfafafafaflYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafPIPIPIPIPIPIPIPIPIPIPIPIPIPIPIPIPIPIPIPIPIPIPIPIPIPIPIPIPIafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf ahmcOsOsOsOsPJPKOsmcmKmJafafOfOuOuOfafafafOfOfPCPDPEOfOfafafafOfOuOuOfafafafaflYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafPIafafafafafafafafafafafafafafafafafafafafafafafafafafafPIafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf ahmcOsOsOsOsOsOsmcafafafafafPLPMPMPNafafafafafafafafafafafafafPLPMPMPNafafafaflYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafPIafafafafafafafafafafafafafafafafafafafafafafafafafafafPIafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf ahmcmcmcmcmcmcmcmcmcafafafafPLPOPPPNafafafafafafafafafafafafafPLPOPPPNafafafaflYafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafPIafafafafafafafafafafPQPQPQPRPQPQPQafafafafafafafafafafPIafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf diff --git a/maps/northern_star/polaris-5.dmm b/maps/northern_star/polaris-5.dmm index 184ffbd6c1..40c415c0a5 100644 --- a/maps/northern_star/polaris-5.dmm +++ b/maps/northern_star/polaris-5.dmm @@ -284,7 +284,7 @@ "fx" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 6},/obj/machinery/light,/turf/simulated/floor/plating,/area/outpost/research/toxins_misc_lab) "fy" = (/obj/machinery/atmospherics/pipe/manifold/visible/purple{dir = 4},/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -21},/turf/simulated/floor/plating,/area/outpost/research/toxins_misc_lab) "fz" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple,/turf/simulated/wall/r_wall,/area/outpost/research/toxins_misc_lab) -"fA" = (/mob/living/simple_animal/slime,/turf/simulated/floor/reinforced,/area/outpost/research/xenobiology) +"fA" = (/mob/living/simple_mob/slime/xenobio,/turf/simulated/floor/reinforced,/area/outpost/research/xenobiology) "fB" = (/obj/structure/disposalpipe/segment,/obj/machinery/light/small{dir = 4},/turf/simulated/floor/reinforced,/area/outpost/research/xenobiology) "fC" = (/obj/machinery/portable_atmospherics/canister,/turf/simulated/floor/plating,/area/outpost/research/hallway/toxins_hallway) "fD" = (/obj/structure/closet/emcloset,/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 9},/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -21},/turf/simulated/floor/tiled/white,/area/outpost/research/hallway/toxins_hallway) @@ -1912,7 +1912,7 @@ "KN" = (/obj/structure/lattice,/obj/structure/grille{density = 0; icon_state = "brokengrille"},/turf/space,/area/space) "KO" = (/obj/structure/lattice,/obj/structure/grille,/turf/space,/area/space) "KP" = (/obj/machinery/power/tracker,/obj/structure/cable/yellow,/turf/simulated/floor/airless{icon_state = "asteroidplating2"},/area/outpost/engineering/solarsoutside/aft) - + (1,1,1) = {" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/maps/plane/plane-1.dmm b/maps/plane/plane-1.dmm index 8017636b44..5fb3912356 100644 --- a/maps/plane/plane-1.dmm +++ b/maps/plane/plane-1.dmm @@ -1,71 +1,71 @@ -"a" = (/turf/unsimulated/wall/planetary/sif,/area/plane_ground) -"b" = (/turf/simulated/floor/outdoors/dirt,/area/plane_ground) -"c" = (/obj/effect/landmark/start,/turf/simulated/floor/outdoors/dirt,/area/plane_ground) -"d" = (/obj/effect/landmark{name = "JoinLate"},/turf/simulated/floor/outdoors/dirt,/area/plane_ground) - -(1,1,1) = {" -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbdddbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbdddbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbdddbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -"} +"a" = (/turf/unsimulated/wall/planetary/sif,/area/plane_ground) +"b" = (/turf/simulated/floor/outdoors/dirt,/area/plane_ground) +"c" = (/obj/effect/landmark{name = "JoinLate"},/turf/simulated/floor/outdoors/dirt,/area/plane_ground) +"d" = (/obj/effect/landmark/start,/turf/simulated/floor/outdoors/dirt,/area/plane_ground) + +(1,1,1) = {" +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbdbcccbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +"} diff --git a/maps/southern_cross/southern_cross-1.dmm b/maps/southern_cross/southern_cross-1.dmm index edc186256d..72e3b04c46 100644 --- a/maps/southern_cross/southern_cross-1.dmm +++ b/maps/southern_cross/southern_cross-1.dmm @@ -377,7 +377,7 @@ "ahm" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/effect/floor_decal/steeldecal/steel_decals5,/obj/effect/floor_decal/borderfloor/corner2{dir = 1},/obj/effect/floor_decal/borderfloor/corner2{dir = 4},/obj/effect/floor_decal/corner/green/bordercorner2{dir = 1},/obj/effect/floor_decal/corner/green/bordercorner2{dir = 4},/turf/simulated/floor/tiled,/area/hallway/primary/firstdeck/fore) "ahn" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/obj/machinery/light{dir = 8},/turf/simulated/floor/tiled/dark,/area/security/nuke_storage) "aho" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/tiled/dark,/area/security/nuke_storage) -"ahp" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/mob/living/simple_animal/mouse/brown/Tom,/turf/simulated/floor/tiled/dark,/area/security/nuke_storage) +"ahp" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/mob/living/simple_mob/animal/passive/mouse/brown/Tom,/turf/simulated/floor/tiled/dark,/area/security/nuke_storage) "ahq" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/tiled/dark,/area/security/nuke_storage) "ahr" = (/obj/machinery/camera/network/command{c_tag = "COM - Vault"; dir = 9},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor/tiled/dark,/area/security/nuke_storage) "ahs" = (/turf/simulated/wall/r_wall,/area/storage/emergency_storage/firstdeck/fs_emergency) @@ -4265,7 +4265,7 @@ "bEa" = (/turf/simulated/wall/r_wall,/area/maintenance/substation/research) "bEb" = (/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/machinery/light_switch{pixel_x = -36},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/effect/floor_decal/borderfloorwhite{dir = 8},/obj/effect/floor_decal/corner/blue/border{dir = 8},/turf/simulated/floor/tiled/white,/area/crew_quarters/heads/sc/hor) "bEc" = (/turf/simulated/floor/tiled/white,/area/crew_quarters/heads/sc/hor) -"bEd" = (/mob/living/simple_animal/slime/rainbow/kendrick,/turf/simulated/floor/tiled/white,/area/crew_quarters/heads/sc/hor) +"bEd" = (/mob/living/simple_mob/slime/xenobio/rainbow/kendrick,/turf/simulated/floor/tiled/white,/area/crew_quarters/heads/sc/hor) "bEe" = (/obj/structure/bed/chair/office/light,/obj/effect/landmark/start{name = "Research Director"},/turf/simulated/floor/tiled/white,/area/crew_quarters/heads/sc/hor) "bEf" = (/obj/structure/table/reinforced,/obj/item/device/paicard{pixel_x = 4},/obj/item/device/tape,/obj/item/device/taperecorder{pixel_x = -3},/obj/item/weapon/reagent_containers/food/drinks/jar,/obj/effect/floor_decal/borderfloorwhite{dir = 4},/obj/effect/floor_decal/corner/blue/border{dir = 4},/turf/simulated/floor/tiled/white,/area/crew_quarters/heads/sc/hor) "bEg" = (/obj/machinery/door/firedoor/border_only,/obj/effect/wingrille_spawn/reinforced/polarized{id = "rdoffice"},/turf/simulated/floor/plating,/area/crew_quarters/heads/sc/hor) @@ -6364,7 +6364,7 @@ "cst" = (/obj/structure/table/reinforced,/obj/machinery/door/blast/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "hop_office_desk"; name = "HoP Office Privacy Shutters"; opacity = 0},/obj/machinery/door/window/brigdoor/eastright{name = "Head of Personnel's Desk"; req_access = list(57)},/obj/machinery/door/window/northleft{dir = 8; icon_state = "left"; name = "Reception Window"},/obj/structure/noticeboard{pixel_y = 27},/obj/machinery/door/firedoor/glass,/turf/simulated/floor/tiled/dark,/area/crew_quarters/heads/sc/hop) "csu" = (/obj/structure/bed/chair/office/dark{dir = 8},/obj/effect/landmark/start{name = "Head of Personnel"},/obj/effect/floor_decal/borderfloor{dir = 8},/obj/effect/floor_decal/corner/blue/border{dir = 8},/turf/simulated/floor/tiled,/area/crew_quarters/heads/sc/hop) "csv" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/tiled,/area/crew_quarters/heads/sc/hop) -"csw" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/obj/effect/floor_decal/borderfloor{dir = 4},/obj/effect/floor_decal/corner/blue/border{dir = 4},/mob/living/simple_animal/corgi/Ian,/turf/simulated/floor/tiled,/area/crew_quarters/heads/sc/hop) +"csw" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/obj/effect/floor_decal/borderfloor{dir = 4},/obj/effect/floor_decal/corner/blue/border{dir = 4},/mob/living/simple_mob/animal/passive/dog/corgi/Ian,/turf/simulated/floor/tiled,/area/crew_quarters/heads/sc/hop) "csx" = (/obj/structure/bed/chair/office/dark,/turf/simulated/floor/carpet,/area/crew_quarters/heads/sc/hop) "csy" = (/obj/structure/table/reinforced,/obj/machinery/recharger{pixel_y = 0},/obj/item/weapon/packageWrap,/obj/item/weapon/hand_labeler,/obj/machinery/computer/guestpass{pixel_x = 28; pixel_y = 0},/turf/simulated/floor/carpet,/area/crew_quarters/heads/sc/hop) "csz" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/tiled,/area/hallway/primary/seconddeck/ascenter) @@ -6754,7 +6754,7 @@ "czT" = (/obj/effect/floor_decal/corner/paleblue{dir = 10},/obj/effect/floor_decal/corner/paleblue{dir = 5},/turf/simulated/floor/tiled/white,/area/medical/foyer) "czU" = (/obj/effect/floor_decal/borderfloorwhite{dir = 4},/obj/effect/floor_decal/corner/paleblue/border{dir = 4},/turf/simulated/floor/tiled/white,/area/medical/foyer) "czV" = (/obj/structure/table/reinforced,/obj/machinery/door/firedoor/glass,/obj/machinery/door/window/westright{name = "Chemistry Desk"},/obj/machinery/door/window/eastright{name = "Chemistry Desk"; req_access = list(33)},/obj/machinery/door/blast/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "chemcounter"; name = "Pharmacy Counter Shutters"; opacity = 0},/turf/simulated/floor/tiled/white,/area/medical/chemistry) -"czW" = (/obj/item/weapon/stool/padded,/obj/effect/floor_decal/borderfloorwhite{dir = 8},/obj/effect/floor_decal/corner/beige/border{dir = 8},/turf/simulated/floor/tiled/white,/area/medical/chemistry) +"czW" = (/obj/item/weapon/stool/padded,/obj/effect/floor_decal/borderfloorwhite{dir = 8},/obj/effect/floor_decal/corner/beige/border{dir = 8},/obj/machinery/button/remote/blast_door{id = "chemcounter"; name = "Pharmacy Counter Lockdown Control"; pixel_x = -24; pixel_y = 24},/obj/machinery/button/remote/blast_door{id = "chemwindow"; name = "Pharmacy Windows Shutter Control"; pixel_x = -24; pixel_y = 32; pixel_z = 0},/turf/simulated/floor/tiled/white,/area/medical/chemistry) "czX" = (/turf/simulated/floor/tiled/white,/area/medical/chemistry) "czY" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk,/turf/simulated/floor/tiled/white,/area/medical/chemistry) "czZ" = (/obj/effect/floor_decal/steeldecal/steel_decals4,/obj/effect/floor_decal/steeldecal/steel_decals4{dir = 10},/turf/simulated/floor/tiled/white,/area/medical/chemistry) @@ -6846,11 +6846,11 @@ "cBH" = (/obj/structure/disposalpipe/junction{dir = 1; icon_state = "pipe-j2"},/turf/simulated/floor/tiled/white,/area/medical/foyer) "cBI" = (/obj/effect/floor_decal/corner/paleblue{dir = 6},/obj/effect/floor_decal/corner/paleblue{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/tiled/white,/area/medical/foyer) "cBJ" = (/obj/structure/bed/chair{dir = 8},/obj/effect/floor_decal/borderfloorwhite{dir = 4},/obj/effect/floor_decal/corner/paleblue/border{dir = 4},/turf/simulated/floor/tiled/white,/area/medical/foyer) -"cBK" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/obj/structure/table/glass,/obj/item/weapon/storage/box/syringes,/obj/item/weapon/tool/screwdriver,/obj/machinery/button/remote/blast_door{id = "chemwindow"; name = "Pharmacy Windows Shutter Control"; pixel_x = 6; pixel_y = -18; pixel_z = 0},/obj/machinery/button/remote/blast_door{id = "chemcounter"; name = "Pharmacy Counter Lockdown Control"; pixel_x = -6; pixel_y = -18},/obj/effect/floor_decal/borderfloorwhite{dir = 8},/obj/effect/floor_decal/corner/beige/border{dir = 8},/turf/simulated/floor/tiled/white,/area/medical/chemistry) -"cBL" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/tiled/white,/area/medical/chemistry) +"cBK" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor/tiled/white,/area/medical/chemistry) +"cBL" = (/obj/effect/floor_decal/borderfloorwhite{dir = 8},/obj/effect/floor_decal/corner/beige/border{dir = 8},/obj/machinery/chemical_analyzer,/turf/simulated/floor/tiled/white,/area/medical/chemistry) "cBM" = (/obj/machinery/hologram/holopad,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/effect/floor_decal/industrial/outline/grey,/obj/structure/disposalpipe/segment,/turf/simulated/floor/tiled/white,/area/medical/chemistry) -"cBN" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/tiled/white,/area/medical/chemistry) -"cBO" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/obj/machinery/newscaster{pixel_x = 30; pixel_y = 0},/obj/effect/floor_decal/borderfloorwhite/corner,/obj/effect/floor_decal/corner/beige/bordercorner,/turf/simulated/floor/tiled/white,/area/medical/chemistry) +"cBN" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor/tiled/white,/area/medical/chemistry) +"cBO" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/obj/machinery/newscaster{pixel_x = 30; pixel_y = 0},/obj/effect/floor_decal/borderfloorwhite/corner,/obj/effect/floor_decal/corner/beige/bordercorner,/turf/simulated/floor/tiled/white,/area/medical/chemistry) "cBP" = (/obj/structure/bed/chair/wheelchair,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/obj/effect/floor_decal/borderfloorwhite/corner{dir = 8},/obj/effect/floor_decal/corner/paleblue/bordercorner{dir = 8},/turf/simulated/floor/tiled/white,/area/medical/medbay_primary_storage) "cBQ" = (/obj/machinery/hologram/holopad,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/effect/floor_decal/industrial/outline/grey,/turf/simulated/floor/tiled/white,/area/medical/medbay_primary_storage) "cBR" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/machinery/camera/network/medbay{c_tag = "MED - Equipment Storage"; dir = 8},/obj/machinery/disposal,/obj/structure/disposalpipe/trunk,/obj/effect/floor_decal/borderfloorwhite{dir = 4},/obj/effect/floor_decal/corner/paleblue/border{dir = 4},/turf/simulated/floor/tiled/white,/area/medical/medbay_primary_storage) @@ -6930,7 +6930,7 @@ "cDn" = (/obj/structure/bed/chair{dir = 8},/obj/effect/floor_decal/borderfloorwhite{dir = 4},/obj/effect/floor_decal/corner/paleblue/border{dir = 4},/obj/effect/floor_decal/borderfloorwhite/corner2{dir = 5},/obj/effect/floor_decal/corner/paleblue/bordercorner2{dir = 5},/turf/simulated/floor/tiled/white,/area/medical/foyer) "cDo" = (/obj/structure/table/glass,/obj/item/weapon/packageWrap,/obj/item/weapon/hand_labeler,/obj/item/weapon/reagent_containers/spray/cleaner{desc = "Someone has crossed out the 'Space' from Space Cleaner and written in Chemistry. Scrawled on the back is, 'Okay, whoever filled this with polytrinic acid, it was only funny the first time. It was hard enough replacing the CMO's first cat!'"; name = "Chemistry Cleaner"},/obj/effect/floor_decal/borderfloorwhite{dir = 8},/obj/effect/floor_decal/corner/beige/border{dir = 8},/turf/simulated/floor/tiled/white,/area/medical/chemistry) "cDp" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/turf/simulated/floor/tiled/white,/area/medical/chemistry) -"cDq" = (/obj/structure/closet/secure_closet/chemical,/obj/item/weapon/storage/box/pillbottles,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 22},/obj/effect/floor_decal/borderfloorwhite{dir = 4},/obj/effect/floor_decal/corner/beige/border{dir = 4},/turf/simulated/floor/tiled/white,/area/medical/chemistry) +"cDq" = (/obj/structure/closet/secure_closet/chemical,/obj/item/weapon/storage/box/pillbottles,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 22},/obj/effect/floor_decal/borderfloorwhite{dir = 4},/obj/effect/floor_decal/corner/beige/border{dir = 4},/obj/item/weapon/storage/box/syringes,/obj/item/weapon/tool/screwdriver,/turf/simulated/floor/tiled/white,/area/medical/chemistry) "cDr" = (/obj/structure/bed/chair/wheelchair,/obj/item/device/radio/intercom/department/medbay{dir = 4; pixel_x = -21},/obj/effect/floor_decal/borderfloorwhite{dir = 8},/obj/effect/floor_decal/corner/paleblue/border{dir = 8},/turf/simulated/floor/tiled/white,/area/medical/medbay_primary_storage) "cDs" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/tiled/white,/area/medical/medbay_primary_storage) "cDt" = (/obj/structure/table/standard,/obj/item/weapon/storage/toolbox/emergency,/obj/item/bodybag/cryobag,/obj/item/bodybag/cryobag,/obj/item/bodybag/cryobag,/obj/structure/extinguisher_cabinet{pixel_x = 25},/obj/structure/disposalpipe/segment,/obj/effect/floor_decal/borderfloorwhite{dir = 4},/obj/effect/floor_decal/corner/paleblue/border{dir = 4},/turf/simulated/floor/tiled/white,/area/medical/medbay_primary_storage) @@ -7397,7 +7397,7 @@ "cMm" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/machinery/power/sensor{name = "Powernet Sensor - Medbay Subgrid"; name_tag = "Medbay Subgrid"},/obj/effect/floor_decal/industrial/warning/corner,/turf/simulated/floor/plating,/area/maintenance/substation/medical) "cMn" = (/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/table/steel,/obj/machinery/cell_charger,/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 22},/obj/effect/floor_decal/industrial/warning,/turf/simulated/floor/plating,/area/maintenance/substation/medical) "cMo" = (/obj/machinery/disposal,/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -21},/obj/structure/disposalpipe/trunk{dir = 1},/obj/effect/floor_decal/borderfloorwhite{dir = 9},/obj/effect/floor_decal/corner/blue/border{dir = 9},/turf/simulated/floor/tiled/white,/area/crew_quarters/heads/sc/cmo) -"cMp" = (/obj/effect/floor_decal/borderfloorwhite/corner{dir = 1},/obj/effect/floor_decal/corner/blue/bordercorner{dir = 1},/mob/living/simple_animal/cat/fluff/Runtime,/turf/simulated/floor/tiled/white,/area/crew_quarters/heads/sc/cmo) +"cMp" = (/obj/effect/floor_decal/borderfloorwhite/corner{dir = 1},/obj/effect/floor_decal/corner/blue/bordercorner{dir = 1},/mob/living/simple_mob/animal/passive/cat/runtime,/turf/simulated/floor/tiled/white,/area/crew_quarters/heads/sc/cmo) "cMq" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/effect/floor_decal/steeldecal/steel_decals4{dir = 9},/obj/effect/floor_decal/steeldecal/steel_decals4{dir = 4},/turf/simulated/floor/tiled/white,/area/crew_quarters/heads/sc/cmo) "cMr" = (/obj/machinery/camera/network/medbay{c_tag = "MED - CMO"; dir = 2},/obj/effect/floor_decal/borderfloorwhite/corner{dir = 4},/obj/effect/floor_decal/corner/blue/bordercorner{dir = 4},/turf/simulated/floor/tiled/white,/area/crew_quarters/heads/sc/cmo) "cMs" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/fancy/vials{pixel_x = 5; pixel_y = 5},/obj/item/weapon/storage/fancy/vials,/obj/effect/floor_decal/borderfloorwhite{dir = 1},/obj/effect/floor_decal/corner/blue/border{dir = 1},/turf/simulated/floor/tiled/white,/area/crew_quarters/heads/sc/cmo) @@ -10789,7 +10789,7 @@ "dZy" = (/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 8},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/window/brigdoor/westleft{name = "Containment Pen"; req_access = list(47)},/turf/simulated/floor/tiled/techmaint,/area/rnd/xenobiology) "dZz" = (/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/tiled/white,/area/rnd/xenobiology) "dZA" = (/obj/effect/floor_decal/industrial/hatch/yellow,/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/door/window/brigdoor/eastright{name = "Containment Pen"; req_access = list(47)},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "xenobio2station"; name = "Containment Blast Doors"; opacity = 0},/turf/simulated/floor/tiled/techmaint,/area/rnd/xenobiology) -"dZB" = (/mob/living/simple_animal/slime,/turf/simulated/floor/reinforced,/area/rnd/xenobiology) +"dZB" = (/mob/living/simple_mob/slime/xenobio,/turf/simulated/floor/reinforced,/area/rnd/xenobiology) "dZC" = (/obj/effect/floor_decal/industrial/warning/corner,/turf/simulated/floor/tiled/white,/area/rnd/research/firstdeck/hallway) "dZD" = (/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 8},/turf/simulated/floor/tiled/white,/area/rnd/research/firstdeck/hallway) "dZE" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/effect/floor_decal/industrial/warning,/turf/simulated/floor/tiled/white,/area/rnd/research/firstdeck/hallway) @@ -10949,7 +10949,7 @@ "ecC" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/machinery/meter,/obj/random/mob/mouse,/turf/simulated/floor/plating,/area/maintenance/thirddeck/foreport) "ecD" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/meter,/obj/random/mob/mouse,/turf/simulated/floor/plating,/area/maintenance/thirddeck/forestarboard) "ecE" = (/obj/machinery/door/firedoor/border_only,/obj/effect/wingrille_spawn/reinforced,/obj/machinery/door/blast/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "heads_meeting"; name = "Meeting Room Window Shutters"; opacity = 0},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green,/turf/simulated/floor/plating,/area/bridge/meeting_room) - + (1,1,1) = {" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -11345,7 +11345,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaabVvcczcdQcczcdQcczcdQcczcdQcczcdQcczbVycaJbTDcaKcuPcuQcuRcuScuQcuTcuUcpPcpPcpPcpPcpPcpPcpPcuXcuVctDcuWcuYcxbctDcvacvbcvccvcctIcvdctIcvecvfcvgcvhcvicvjcvkcvjcvlcvmcvncvocvpcvqcvrctOcvscvtcvucvvcoQdUSdUTdURdwUcvwcqocoVaaaaaactUcvxcvycvzcvAcvBbWzcDQcvDcqxcvEcvFcvGeckcvIcvJcsjcvKcvLcvMcvNcumcvOcvPcvQcvRcsAcvScvTcvUcgwaaaaaacpkcsDcuucvVcvWcvXcvYcvZcwacwbcwccwdcuycwecwfcwgcwhcwicwjcwkcwlcwmcwncwocwpcwqcwrcwscwtcwucwvcwwcwxcwycwzcwAcwBcwCcwDcwEcwFcwGcrmcwHcwIcwJcrqcrqcrqcwKcwLcwIcrvcaHcwMcwNcwOcaHccxcwPcaHcaHaafaafaafaadaXGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaabMCcdRbMCcdRbMCcdRbMCcdRbMCcdRbMCcdRaadbYTcwQcwUcwScwTcxtcwScwTcwVcwWcwXcwYbTDcfRcrMcrNcrNcrNcwZctDcxacxccxdctDcvacxectHctHctIcxfcxgcxhcxicxjcxkcxlcxlcxlcxmcxncxocxpcxqcxrcxscFGcxucxvcxwcxxcvvcoQdwUdwUdwUdwUcoVcqocoVaaaaaactUcxycqrcxzcxAcxBbWzcxCcxDcqxcxEcxFcxGcsrcxHcxIcxJcvKcxKcxLcxMcxNcxOcxPcpdcvRcxQcxRcxScxTcgwaaaaaacpkcsDcuucxUcxVcxWcxXcxYcxZcyacybcyccuzcydcyecyfcygcyhcyicyjcykcylcymcyncyocypcyqcyrcyscyrcytcwwcyucyvcywcwAcyxcyycyzcwEcyAcyBcrmcrmcrmcrmcrmcrmcrmcrmcrmcpzcpzcaHcyCcaIcaHcaHcaHcaHcaHaaaaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaadaaaaaaaaabKLbKMbKMbKMbKMbKMbKMbKMcyDbKMbKMbKMbVybXocyEcyFcyGcyHcyIcyJcyHcyKcyLcyLcyMbTDcfRcyNcmLcyOcyOcyPcyOctDcyRcyQctDctDcyTcyUcyVctIcyWcyXcyYcyZczaczbcxlcxlczcczdczeczfctOczgczhcziczjctOcoQcoQczkcoQcoQcqmcqmcqmcqmcoVcqoczlaaaaaacqpcsicqrczmcznczobWAbWAczpcqxcxEczqczrcsrcsjcvAcsjczscpdcztczuczvczwcpdcpdczxczyczzczAczBchZaaaaaaczCcsDcuuczDczEcxWczFczGcxZczHczIczJcuzczKcyeczLczMczNczOczPczQczRczSczTczUczVczWczXczYczXczZcAacAbcAccAdcwAcAecAfcAgcwEcAhcAicAjcAkcAlcAmcAncAocApcAqcArcAsbYScAtcAuaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaabVvcczcdQcczcdQcczcdQcczcdQcczcdQcczbVyccBbTDbTDcAvcAwcAxbXpcAxcAycyLcyLcAzbTDcfRcyNcmLcyOcAAcABcACctDcAEcyScAFctDcAGcAHcAIctIcAJcAKcALcAMcANcAOcAPcAQcAQcARczecAScATcAUcAVcAWcAXctOcAYcAZcBacBbcBccqmcBdcqmcBecoVcqoczlaaaaaacqpcqpcBfcsjcuhcBgcBhbWAcBicqxcqxcqxcqxcBjcBkcBlcBkcBmcpdcpdcBncBocpdcpdcBpcBqcBrcjDcBschZchZaaaaaaczCcsDcuucuucBtcBucBvcBwcxZcBxcBycBzcuzcBAcBBcBCcBCcBDcBEcBFcBGcBHcBIcwocBJcypcBKcBLcBMcBNcBOcuGcBPcBQcBRcwAcBScBTcBUcwEcBVcBWcBXcBYcBYcAmcBZcCacCbcAmcAmcAsaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaagaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaabVvcczcdQcczcdQcczcdQcczcdQcczcdQcczbVyccBbTDbTDcAvcAwcAxbXpcAxcAycyLcyLcAzbTDcfRcyNcmLcyOcAAcABcACctDcAEcyScAFctDcAGcAHcAIctIcAJcAKcALcAMcANcAOcAPcAQcAQcARczecAScATcAUcAVcAWcAXctOcAYcAZcBacBbcBccqmcBdcqmcBecoVcqoczlaaaaaacqpcqpcBfcsjcuhcBgcBhbWAcBicqxcqxcqxcqxcBjcBkcBlcBkcBmcpdcpdcBncBocpdcpdcBpcBqcBrcjDcBschZchZaaaaaaczCcsDcuucuucBtcBucBvcBwcxZcBxcBycBzcuzcBAcBBcBCcBCcBDcBEcBFcBGcBHcBIcwocBJcypcBLcBNcBMcBKcBOcuGcBPcBQcBRcwAcBScBTcBUcwEcBVcBWcBXcBYcBYcAmcBZcCacCbcAmcAmcAsaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaagaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaabMCcdRbMCcdRbMCcdRbMCcdRbMCcdRbMCcdRaafaafaafbTEbTDbTDbTDbTDbTDbTDbTDbTDbTDbTDcfRcCccencyOcCdcABcCectDcCfcADcNpcCjcCkcClcCmctIcCncCocCpcCqctIcCrcCscCtcCtcCucCvcCwcxpcCxcCycxrcCzctOcAYcCAcCBcCCcBbcBbcqmcBdcqmcoVcqoczlaaaaaaaaactUcCDcCEcuhcCFcCGcCHcCIcCJdVzcCKcCLcCMcCNcskcCOcCMcCPcnDcCQcCRcCScCTcCUcCVcBrcCWcCXcgwaaaaaaaaaczCcsDcCYcuucCZcDacDbcDccxZcDdcDecDdcuzcDfcyecDgcDhcDicDjcDkcDlcwmcDmcwocDncypcDoczXcDpczXcDqcuGcDrcDscDtcwAcDucDvcDwcwEcDxcDycDzcDAcDBcDCcDDcDEcApcDFcDGcAsaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaacDHcDIcDJcDKcDLcDLcDMcDNcXVcCheclcPXcyOcDRcDScDTctDctDctDctDcDUcDVcDWcDUctIcDXctIcDYcDZctIcEacEbcEccEccEdcEecEactOcEfcEgcEhcEictOcEjcEjcEjcEkcEjcBbcBbcBbcqmcoVcqocoVaaaaaaaaactUctUcElcCEcuhcuhcEmcEncEocEocEpcEqcErcEscEtcEucErcEvcEwcExcExcEycEzcBrcBrcCWcEAcgwcgwaaaaaaaaacpkcsDcEBcuucuucECcEDcEEcxZcEFcEGcEHcuzcEIcEJcEKcELcEMcENcEOcEPcEQcERcEScETcuGcEUcEVcEWcEXcEYcuGcDOcFacFbcwAcFccFdcFecwEcFfcFgcFhcFicFjcAmcFkcFlcFmcAscAscAsaafaafaafabcaafaaaaaaaagaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaacDHcFncFocFpcFqcDHcDHcDHcMXcEZcDPcFtcyOcyOcyOcyOcGTcFvcFwcFxcDUcFycFzcFAcFBcFCcFDcFEcFFctIcOlcFHcFIcFJcFKcFLcFMctOcxpcFNcxpcFOctOcFPcFQcFRcFScEjcoVcoVcFTcoVcoVcFUcoVaaaaaaaaaaaactUctUcElcCEcsjcFVcFWcFXcFYcsjcFZcGacGbcskcGccGacGdcjDcGecGfcGgcGhcjDcCWcEAcgwcgwaaaaaaaaaaaacpkcsDcGicGjcGkcGlcGmcGncGocGpcGqcGrcuzcGscuzcuzcGtcGucGtcuycuEcGvcuEcGwcuEcuGcwwcGxcGycwwcuGcuGcGzcGAcFrcwAcwEcGCcwEcwEcFfcFgcFhcGDcGEcAmcGFcGGcGHcAsaaaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -11723,4 +11723,3 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa dUOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa "} - diff --git a/maps/southern_cross/southern_cross-3.dmm b/maps/southern_cross/southern_cross-3.dmm index eabbfeedf6..20d85c092a 100644 --- a/maps/southern_cross/southern_cross-3.dmm +++ b/maps/southern_cross/southern_cross-3.dmm @@ -1400,7 +1400,7 @@ "AV" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor/tiled/hydro,/area/surface/outpost/research/xenoresearch/xenoflora) "AW" = (/turf/unsimulated/wall/planetary/sif,/area/surface/outside/river/indalsalven) "AX" = (/turf/simulated/floor/water,/area/surface/outside/river/indalsalven) -"AY" = (/mob/living/simple_animal/slime,/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoresearch/xenobiology) +"AY" = (/mob/living/simple_mob/slime/xenobio,/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoresearch/xenobiology) "AZ" = (/obj/effect/floor_decal/industrial/hatch/yellow,/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "xenobio4"; name = "Containment Blast Doors"; opacity = 0},/obj/machinery/door/window/brigdoor/westleft{name = "Containment Pen"; req_access = list(47)},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoresearch/xenobiology) "Ba" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoresearch/xenobiology) "Bb" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/table/standard,/obj/item/weapon/melee/baton/slime/loaded,/obj/item/weapon/gun/energy/taser/xeno,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoresearch/xenobiology) diff --git a/maps/southern_cross/southern_cross-4.dmm b/maps/southern_cross/southern_cross-4.dmm index d445308393..3b3dbdcdbb 100644 --- a/maps/southern_cross/southern_cross-4.dmm +++ b/maps/southern_cross/southern_cross-4.dmm @@ -1,700 +1,700 @@ -"aa" = (/turf/unsimulated/wall/planetary/sif,/area/surface/cave/unexplored/deep) -"ab" = (/turf/simulated/mineral/sif,/area/surface/cave/unexplored/deep) -"ac" = (/turf/simulated/mineral/floor/ignore_mapgen/sif,/area/surface/cave/explored/deep) -"ad" = (/turf/unsimulated/wall/planetary/sif,/area/surface/cave/unexplored/normal) -"ae" = (/turf/simulated/mineral/sif,/area/surface/cave/unexplored/normal) -"af" = (/turf/simulated/mineral/floor/ignore_mapgen/sif,/area/surface/cave/explored/normal) -"ag" = (/turf/simulated/mineral/floor/ignore_mapgen/sif,/area/surface/cave/unexplored/normal) -"ah" = (/obj/machinery/conveyor{dir = 2; id = "anolongstorage"},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology) -"ai" = (/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology) -"aj" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology) -"ak" = (/obj/machinery/conveyor_switch{id = "anolongstorage"; name = "conveyor switch"; pixel_x = 0; pixel_y = 0; req_access = list(65)},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology) -"al" = (/obj/machinery/light/small,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology) -"am" = (/turf/simulated/wall/r_wall,/area/surface/outpost/research/xenoarcheology) -"an" = (/obj/machinery/door/firedoor/border_only,/obj/effect/wingrille_spawn/reinforced,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology) -"ao" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1397; master_tag = "xenoarch2_airlock_control"; name = "Xenoarch Access Button"; pixel_x = 24; pixel_y = 0; req_access = list(47)},/obj/machinery/door/airlock/research{autoclose = 0; frequency = 1397; icon_state = "door_locked"; id_tag = "xenoarch2_airlock_exterior"; locked = 1; name = "Research Exterior Airlock"},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology) -"ap" = (/turf/simulated/wall/r_wall,/area/surface/outpost/research/xenoarcheology/exp_prep) -"aq" = (/obj/machinery/door/firedoor/border_only,/obj/effect/wingrille_spawn/reinforced,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/exp_prep) -"ar" = (/obj/machinery/conveyor{dir = 2; id = "anolongstorage"},/obj/structure/plasticflaps/mining,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/exp_prep) -"as" = (/obj/effect/floor_decal/industrial/warning{dir = 9},/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/status_display{pixel_x = -32},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology) -"at" = (/obj/effect/floor_decal/industrial/warning{dir = 1},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology) -"au" = (/obj/effect/floor_decal/industrial/warning{dir = 5},/obj/machinery/computer/guestpass{pixel_x = 30; pixel_y = 0},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology) -"av" = (/turf/simulated/wall/r_wall,/area/surface/outpost/research/xenoarcheology/anomaly) -"aw" = (/obj/machinery/conveyor{dir = 2; id = "anolongstorage"},/obj/structure/plasticflaps/mining,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/anomaly) -"ax" = (/obj/machinery/door/firedoor/border_only,/obj/effect/wingrille_spawn/reinforced,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/anomaly) -"ay" = (/turf/simulated/wall/r_wall,/area/surface/outpost/research/xenoarcheology/longtermstorage) -"az" = (/obj/effect/floor_decal/corner/purple/full{dir = 8},/obj/machinery/portable_atmospherics/canister/oxygen,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) -"aA" = (/obj/structure/closet/excavation,/obj/effect/floor_decal/corner/purple{dir = 5},/obj/item/device/radio/intercom{dir = 1; name = "Station Intercom (General)"; pixel_y = 21},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) -"aB" = (/obj/structure/closet/excavation,/obj/effect/floor_decal/corner/purple{dir = 5},/obj/machinery/light{dir = 1},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) -"aC" = (/obj/structure/closet/excavation,/obj/effect/floor_decal/corner/purple{dir = 5},/obj/machinery/alarm{pixel_y = 23},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) -"aD" = (/obj/machinery/conveyor_switch{id = "anolongstorage"; name = "conveyor switch"; pixel_x = 0; pixel_y = 0; req_access = list(65)},/obj/effect/floor_decal/corner/purple{dir = 1},/obj/effect/floor_decal/industrial/warning{dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) -"aE" = (/obj/machinery/conveyor{dir = 2; id = "anolongstorage"},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/exp_prep) -"aF" = (/obj/effect/floor_decal/industrial/warning{dir = 10},/obj/machinery/camera/network/research_outpost{c_tag = "OPR - Xenoarch Airlock 2"; dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology) -"aG" = (/obj/effect/floor_decal/industrial/warning,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology) -"aH" = (/obj/effect/floor_decal/industrial/warning{dir = 6},/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 21},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology) -"aI" = (/obj/machinery/conveyor{dir = 2; id = "anolongstorage"},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/anomaly) -"aJ" = (/obj/effect/floor_decal/industrial/warning{dir = 4},/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 8},/obj/machinery/conveyor_switch{id = "anolongstorage"; name = "conveyor switch"; pixel_x = 0; pixel_y = 0; req_access = list(65)},/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/anomaly) -"aK" = (/obj/machinery/portable_atmospherics/canister/oxygen,/obj/effect/floor_decal/industrial/outline/yellow,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"aL" = (/obj/machinery/portable_atmospherics/canister/sleeping_agent,/obj/effect/floor_decal/industrial/outline/yellow,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"aM" = (/obj/machinery/portable_atmospherics/canister/phoron,/obj/effect/floor_decal/industrial/outline/yellow,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"aN" = (/turf/simulated/wall,/area/surface/outpost/research/xenoarcheology/longtermstorage) -"aO" = (/obj/structure/disposaloutlet{dir = 4},/obj/effect/floor_decal/industrial/hatch/yellow,/obj/structure/disposalpipe/trunk,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/longtermstorage) -"aP" = (/obj/machinery/light/small{dir = 1},/obj/effect/floor_decal/industrial/outline/yellow,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/longtermstorage) -"aQ" = (/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 8},/obj/structure/table/rack,/obj/machinery/alarm{pixel_y = 23},/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/longtermstorage) -"aR" = (/obj/effect/floor_decal/corner/purple/full{dir = 8},/obj/structure/dispenser/oxygen,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) -"aS" = (/obj/effect/floor_decal/corner/purple{dir = 1},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) -"aT" = (/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) -"aU" = (/obj/machinery/hologram/holopad,/obj/effect/floor_decal/industrial/outline/grey,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) -"aV" = (/obj/effect/floor_decal/industrial/warning{dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) -"aW" = (/obj/machinery/disposal/deliveryChute{dir = 1},/obj/effect/floor_decal/industrial/warning,/obj/structure/disposalpipe/trunk,/obj/effect/floor_decal/industrial/outline/yellow,/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/exp_prep) -"aX" = (/obj/machinery/door/airlock/research{autoclose = 0; frequency = 1397; icon_state = "door_locked"; id_tag = "xenoarch2_airlock_interior"; locked = 1; name = "Research Interior Airlock"},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1397; master_tag = "xenoarch2_airlock_control"; name = "Research Access Button"; pixel_x = 26; pixel_y = 6; req_access = null},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology) -"aY" = (/obj/structure/extinguisher_cabinet{pixel_x = -28; pixel_y = 0},/obj/effect/floor_decal/corner/purple{dir = 8},/obj/effect/floor_decal/industrial/warning{dir = 1},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"aZ" = (/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 1},/obj/effect/floor_decal/industrial/warning{dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"ba" = (/obj/machinery/portable_atmospherics/canister/nitrogen,/obj/effect/floor_decal/industrial/outline/yellow,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"bb" = (/obj/machinery/portable_atmospherics/canister/carbon_dioxide,/obj/effect/floor_decal/industrial/outline/yellow,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"bc" = (/obj/machinery/portable_atmospherics/canister/air,/obj/effect/floor_decal/industrial/outline/yellow,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"bd" = (/obj/structure/sign/warning/nosmoking_2,/turf/simulated/wall,/area/surface/outpost/research/xenoarcheology/longtermstorage) -"be" = (/obj/effect/floor_decal/industrial/warning{dir = 1},/obj/structure/disposalpipe/segment,/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/longtermstorage) -"bf" = (/obj/effect/floor_decal/industrial/warning{dir = 1},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/longtermstorage) -"bg" = (/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 1},/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/longtermstorage) -"bh" = (/obj/effect/floor_decal/industrial/outline/grey,/obj/structure/closet/crate,/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/longtermstorage) -"bi" = (/obj/effect/floor_decal/corner/purple{dir = 9},/obj/machinery/status_display{pixel_x = -32},/obj/machinery/floodlight,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) -"bj" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) -"bk" = (/obj/item/weapon/storage/excavation,/obj/item/weapon/pickaxe,/obj/item/weapon/tool/wrench,/obj/item/device/measuring_tape,/obj/item/stack/flag/yellow,/obj/structure/table/steel,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) -"bl" = (/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) -"bm" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) -"bn" = (/obj/machinery/door/firedoor/border_only,/obj/structure/disposalpipe/segment{dir = 4},/obj/effect/wingrille_spawn/reinforced,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/exp_prep) -"bo" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/effect/floor_decal/corner/purple{dir = 1},/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 4},/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 8},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"bp" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/effect/floor_decal/industrial/warning{dir = 1},/obj/machinery/embedded_controller/radio/airlock/access_controller{frequency = 1397; id_tag = "xenoarch2_airlock_control"; name = "Research Access Console"; pixel_x = 26; pixel_y = 26; tag_exterior_door = "xenoarch2_airlock_exterior"; tag_interior_door = "xenoarch2_airlock_interior"},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"bq" = (/obj/machinery/shower{pixel_y = 3},/obj/structure/window/reinforced,/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 22},/turf/simulated/floor/tiled/freezer,/area/surface/outpost/research/xenoarcheology) -"br" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall,/area/surface/outpost/research/xenoarcheology/anomaly) -"bs" = (/obj/machinery/light{dir = 8; icon_state = "tube1"; pixel_y = 0},/obj/effect/floor_decal/corner/purple{dir = 9},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"bt" = (/obj/effect/floor_decal/industrial/warning{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/structure/cable/blue{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"bu" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"bv" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor/border_only,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/airlock/research{name = "Long Term Storage"; req_access = list(65)},/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/longtermstorage) -"bw" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/longtermstorage) -"bx" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/longtermstorage) -"by" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/longtermstorage) -"bz" = (/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/machinery/light_switch{dir = 2; name = "light switch "; pixel_x = 36; pixel_y = 0},/obj/structure/cable/blue{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/longtermstorage) -"bA" = (/obj/machinery/floodlight,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) -"bB" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) -"bC" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) -"bD" = (/obj/effect/floor_decal/corner/purple{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) -"bE" = (/obj/effect/floor_decal/corner/purple{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) -"bF" = (/obj/effect/floor_decal/corner/purple{dir = 8},/obj/structure/cable/blue{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) -"bG" = (/obj/machinery/door/firedoor/glass,/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/airlock/glass_research{name = "Expedition Prep"; req_access = list(65)},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) -"bH" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 8},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"bI" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/structure/cable/blue{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"bJ" = (/obj/machinery/space_heater,/obj/effect/floor_decal/corner/purple{dir = 6},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"bK" = (/obj/machinery/door/firedoor/glass,/obj/effect/wingrille_spawn/reinforced,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/anomaly) -"bL" = (/obj/effect/floor_decal/industrial/outline/yellow,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"bM" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/effect/floor_decal/industrial/warning{dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"bN" = (/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"bO" = (/obj/effect/floor_decal/industrial/outline/yellow,/obj/machinery/atmospherics/portables_connector,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"bP" = (/obj/effect/floor_decal/industrial/outline/grey,/obj/machinery/firealarm{dir = 1; pixel_x = 0; pixel_y = -24},/obj/structure/anomaly_container,/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/longtermstorage) -"bQ" = (/obj/effect/floor_decal/industrial/outline/grey,/obj/machinery/light/small,/obj/structure/anomaly_container,/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/longtermstorage) -"bR" = (/obj/effect/floor_decal/industrial/outline/grey,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/obj/machinery/camera/network/research_outpost{c_tag = "OPR - Long Term Storage"; dir = 1},/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/longtermstorage) -"bS" = (/obj/effect/floor_decal/industrial/outline/grey,/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -21},/obj/structure/anomaly_container,/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/longtermstorage) -"bT" = (/obj/effect/floor_decal/corner/purple/full,/obj/machinery/suspension_gen,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) -"bU" = (/obj/machinery/suspension_gen,/obj/effect/floor_decal/corner/purple{dir = 10},/obj/structure/extinguisher_cabinet{pixel_y = -30},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) -"bV" = (/obj/effect/floor_decal/corner/purple{dir = 10},/obj/machinery/firealarm{dir = 1; pixel_x = 0; pixel_y = -24},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) -"bW" = (/obj/item/weapon/storage/excavation,/obj/item/weapon/pickaxe,/obj/item/weapon/tool/wrench,/obj/item/device/measuring_tape,/obj/item/stack/flag/yellow,/obj/structure/table/steel,/obj/effect/floor_decal/corner/purple{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/camera/network/research_outpost{c_tag = "OPR - Expedition Prep"; dir = 1},/obj/machinery/newscaster{layer = 3.3; pixel_x = 0; pixel_y = -27},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) -"bX" = (/obj/structure/table/rack{dir = 8; layer = 2.6},/obj/structure/window/reinforced{dir = 8; health = 1e+006},/obj/item/weapon/storage/belt/archaeology,/obj/item/clothing/suit/space/anomaly,/obj/item/clothing/head/helmet/space/anomaly,/obj/item/clothing/mask/breath,/obj/structure/window/reinforced,/obj/machinery/door/window/northleft,/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/exp_prep) -"bY" = (/obj/structure/table/rack{dir = 8; layer = 2.6},/obj/structure/window/reinforced{dir = 4; health = 1e+006},/obj/item/weapon/storage/belt/archaeology,/obj/item/clothing/suit/space/anomaly,/obj/item/clothing/head/helmet/space/anomaly,/obj/item/clothing/mask/breath,/obj/structure/window/reinforced,/obj/machinery/door/window/northright,/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/exp_prep) -"bZ" = (/obj/structure/table/steel,/obj/item/device/suit_cooling_unit,/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/machinery/light_switch{pixel_x = 11; pixel_y = -24},/obj/structure/cable/blue,/obj/item/device/suit_cooling_unit,/obj/item/device/gps/science,/obj/item/device/gps/science,/obj/item/device/gps/science,/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/exp_prep) -"ca" = (/obj/machinery/ai_status_display,/turf/simulated/wall/r_wall,/area/surface/outpost/research/xenoarcheology/exp_prep) -"cb" = (/obj/structure/window/reinforced,/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 1},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"cc" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"cd" = (/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 21},/obj/effect/floor_decal/corner/purple{dir = 6},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"ce" = (/obj/effect/floor_decal/industrial/hatch/yellow,/obj/machinery/power/emitter{anchored = 1; dir = 1; state = 2},/obj/structure/window/reinforced,/obj/structure/cable/blue{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"cf" = (/obj/machinery/atmospherics/portables_connector{dir = 4},/obj/effect/floor_decal/industrial/outline/yellow,/obj/structure/window/reinforced,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"cg" = (/obj/machinery/atmospherics/omni/atmos_filter{tag_east = 1; tag_north = 2; tag_south = 0; tag_west = 3},/obj/structure/window/reinforced,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"ch" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/obj/effect/floor_decal/industrial/outline/yellow,/obj/structure/window/reinforced,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"ci" = (/obj/structure/table/rack,/obj/item/clothing/suit/bio_suit/anomaly,/obj/item/clothing/head/bio_hood/anomaly,/obj/item/clothing/mask/breath,/obj/item/clothing/glasses/science,/obj/item/clothing/gloves/sterile/latex,/obj/effect/floor_decal/industrial/hatch/yellow,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"cj" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"ck" = (/obj/machinery/camera/network/research_outpost{c_tag = "OPR - Xenoarch Hallway 2"; dir = 8},/obj/effect/floor_decal/corner/purple{dir = 4},/obj/effect/floor_decal/industrial/warning/corner,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"cl" = (/obj/effect/floor_decal/corner/purple{dir = 4},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/camera/network/research_outpost{c_tag = "OPR - Anomalous Materials 2"; dir = 4},/obj/machinery/newscaster{pixel_x = -30; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"cm" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"cn" = (/obj/effect/floor_decal/industrial/outline/yellow,/obj/machinery/portable_atmospherics/powered/scrubber/huge,/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/anomaly) -"co" = (/obj/machinery/computer/area_atmos,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/anomaly) -"cp" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/machinery/light_switch{pixel_x = 11; pixel_y = 24},/obj/structure/cable/blue{d2 = 2; icon_state = "0-2"},/obj/effect/floor_decal/corner/purple{dir = 4},/obj/structure/cable/blue{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/effect/floor_decal/industrial/warning/corner,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"cq" = (/obj/machinery/door/firedoor/border_only,/obj/effect/wingrille_spawn/reinforced,/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/isolation_a) -"cr" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/blue{d2 = 8; icon_state = "0-8"},/obj/machinery/light_switch{pixel_x = 11; pixel_y = 24},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_a) -"cs" = (/obj/structure/bed,/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_a) -"ct" = (/obj/structure/table/standard,/obj/item/device/flashlight/lamp,/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_a) -"cu" = (/turf/simulated/wall/r_wall,/area/surface/outpost/research/xenoarcheology/isolation_a) -"cv" = (/turf/simulated/wall/r_wall,/area/surface/outpost/mining_main/cave) -"cw" = (/obj/effect/step_trigger/teleporter/wild/to_wild,/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/outpost/wall/checkpoint) -"cx" = (/turf/simulated/shuttle/wall/voidcraft,/area/surface/outpost/wall/checkpoint) -"cy" = (/obj/structure/showcase/sign{pixel_y = -5},/turf/simulated/wall/dungeon,/area/surface/cave/unexplored/deep) -"cz" = (/obj/effect/step_trigger/teleporter/wild/to_wild,/turf/simulated/floor/water{outdoors = 0},/area/surface/cave/explored/deep) -"cA" = (/turf/simulated/wall/r_wall,/area/surface/outpost/research/xenoarcheology/medical) -"cB" = (/obj/machinery/sleeper{dir = 8},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/medical) -"cC" = (/obj/machinery/sleep_console,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/medical) -"cD" = (/obj/structure/table/rack,/obj/machinery/firealarm{pixel_y = 24},/obj/item/bodybag/cryobag,/obj/item/bodybag/cryobag,/obj/item/weapon/storage/toolbox/emergency,/obj/item/weapon/storage/firstaid/regular,/obj/random/medical/lite,/obj/structure/extinguisher_cabinet{pixel_x = 28; pixel_y = 0},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/medical) -"cE" = (/turf/simulated/wall,/area/surface/outpost/research/xenoarcheology/medical) -"cF" = (/obj/structure/closet/secure_closet/xenoarchaeologist{req_access = list(47)},/obj/item/clothing/suit/storage/hooded/wintercoat/science,/obj/effect/floor_decal/corner/purple/full{dir = 8},/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -21},/turf/simulated/floor/tiled/neutral,/area/surface/outpost/research/xenoarcheology) -"cG" = (/obj/structure/closet/secure_closet/xenoarchaeologist{req_access = list(47)},/obj/machinery/newscaster{pixel_y = 30},/obj/item/clothing/suit/storage/hooded/wintercoat/science,/obj/effect/floor_decal/corner/purple{dir = 5},/turf/simulated/floor/tiled/neutral,/area/surface/outpost/research/xenoarcheology) -"cH" = (/obj/effect/floor_decal/corner/purple/full{dir = 1},/obj/structure/bookcase/manuals/xenoarchaeology,/turf/simulated/floor/tiled/neutral,/area/surface/outpost/research/xenoarcheology) -"cI" = (/obj/machinery/door/firedoor/glass,/obj/effect/wingrille_spawn/reinforced,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology) -"cJ" = (/obj/structure/table/rack,/obj/item/clothing/suit/bio_suit/anomaly,/obj/item/clothing/head/bio_hood/anomaly,/obj/item/clothing/mask/breath,/obj/item/clothing/glasses/science,/obj/item/clothing/gloves/sterile/latex,/obj/effect/floor_decal/industrial/hatch/yellow,/obj/machinery/light{dir = 8; icon_state = "tube1"; pixel_y = 0},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"cK" = (/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/structure/cable/blue{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"cL" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/effect/floor_decal/industrial/warning{dir = 4},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"cM" = (/obj/machinery/door/firedoor/glass,/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/airlock/glass_research{name = "Anomalous Materials"; req_access = list(65)},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"cN" = (/obj/effect/floor_decal/industrial/warning,/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/blue{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"cO" = (/obj/effect/floor_decal/industrial/warning,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/structure/cable/blue{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"cP" = (/obj/effect/floor_decal/industrial/warning,/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"cQ" = (/obj/effect/floor_decal/industrial/warning,/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 6},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"cR" = (/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/blue{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"cS" = (/obj/machinery/atmospherics/valve/digital/open{dir = 4},/obj/effect/floor_decal/industrial/warning/full,/obj/structure/cable/blue{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/anomaly) -"cT" = (/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 4},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/research{name = "Isolation Room 1"; req_access = list(65)},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_a) -"cU" = (/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 4},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_a) -"cV" = (/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 10},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_a) -"cW" = (/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_a) -"cX" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/outpost/wall/checkpoint) -"cY" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/outpost/wall/checkpoint) -"cZ" = (/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/outpost/wall/checkpoint) -"da" = (/obj/machinery/newscaster{pixel_x = -30; pixel_y = 0},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/medical) -"db" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/medical) -"dc" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 22},/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/medical) -"dd" = (/obj/machinery/light{dir = 8; icon_state = "tube1"; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_scrubber/on,/obj/effect/floor_decal/corner/purple{dir = 1},/turf/simulated/floor/tiled/neutral,/area/surface/outpost/research/xenoarcheology) -"de" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/tiled/neutral,/area/surface/outpost/research/xenoarcheology) -"df" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/obj/effect/floor_decal/corner/purple{dir = 6},/turf/simulated/floor/tiled/neutral,/area/surface/outpost/research/xenoarcheology) -"dg" = (/obj/structure/table/rack,/obj/item/clothing/suit/bio_suit/anomaly,/obj/item/clothing/head/bio_hood/anomaly,/obj/item/clothing/mask/breath,/obj/item/clothing/glasses/science,/obj/item/clothing/gloves/sterile/latex,/obj/effect/floor_decal/industrial/hatch/yellow,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"dh" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"di" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/obj/effect/floor_decal/corner/purple,/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 4},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"dj" = (/obj/structure/table/standard,/obj/item/clothing/head/welding,/obj/item/weapon/weldingtool,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/anomaly) -"dk" = (/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/anomaly) -"dl" = (/obj/structure/table/standard,/obj/item/weapon/reagent_containers/dropper{pixel_y = -4},/obj/machinery/atmospherics/pipe/simple/hidden/yellow,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/anomaly) -"dm" = (/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"dn" = (/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 4},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"do" = (/obj/machinery/door/firedoor/border_only,/obj/effect/wingrille_spawn/reinforced,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/isolation_a) -"dp" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; use_power = 0},/obj/machinery/light,/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_a) -"dq" = (/obj/machinery/atmospherics/pipe/manifold/hidden/yellow,/obj/machinery/alarm/monitor/isolation{alarm_id = "isolation_one"; dir = 1; pixel_x = 0; pixel_y = -22},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_a) -"dr" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8},/obj/machinery/camera/network/research_outpost{c_tag = "OPR - Isolation Cell 1"; dir = 1},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_a) -"ds" = (/turf/simulated/floor/water{outdoors = 0},/area/surface/cave/explored/deep) -"dt" = (/obj/machinery/door/airlock/voidcraft{name = "Wilderness Containment"},/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/outpost/wall/checkpoint) -"du" = (/obj/structure/bed/chair/office/light,/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/machinery/light_switch{pixel_x = -36},/obj/structure/cable/blue{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/medical) -"dv" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/hologram/holopad,/obj/effect/floor_decal/industrial/outline/grey,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/medical) -"dw" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/medical) -"dx" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/door/firedoor/glass,/obj/machinery/door/airlock/glass_medical{name = "First-Aid Station"},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/medical) -"dy" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/tiled/neutral,/area/surface/outpost/research/xenoarcheology) -"dz" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/structure/cable/blue{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/structure/cable/blue{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/tiled/neutral,/area/surface/outpost/research/xenoarcheology) -"dA" = (/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/machinery/light_switch{dir = 2; name = "light switch "; pixel_x = 36; pixel_y = 0},/obj/structure/table/standard,/obj/structure/cable/blue{d2 = 8; icon_state = "0-8"},/obj/effect/floor_decal/corner/purple{dir = 6},/obj/item/weapon/storage/box/glasses/square{pixel_x = 1; pixel_y = 4},/obj/item/weapon/storage/box/cups,/obj/item/weapon/hand_labeler,/turf/simulated/floor/tiled/neutral,/area/surface/outpost/research/xenoarcheology) -"dB" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor/glass,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/glass_research{name = "Outpost Hallway"; req_access = list(47)},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"dC" = (/obj/machinery/status_display,/turf/simulated/wall/r_wall,/area/surface/outpost/research/xenoarcheology/anomaly) -"dD" = (/obj/effect/floor_decal/industrial/warning/dust{icon_state = "warning_dust"; dir = 1},/obj/machinery/floodlight,/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) -"dE" = (/obj/machinery/artifact_scanpad,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/anomaly) -"dF" = (/obj/machinery/artifact_analyser,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/anomaly) -"dG" = (/obj/structure/table/standard,/obj/machinery/cell_charger,/obj/item/weapon/tool/screwdriver{pixel_y = 15},/obj/item/weapon/melee/baton/loaded,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/anomaly) -"dH" = (/obj/machinery/atmospherics/binary/pump{dir = 4},/obj/effect/floor_decal/industrial/warning/full,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/anomaly) -"dI" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/obj/machinery/button/remote/blast_door{id = "xenoarch_cell2"; name = "Cell 2"; pixel_x = 26; pixel_y = 0},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"dJ" = (/obj/structure/table/steel,/obj/effect/floor_decal/industrial/warning/dust{icon_state = "warning_dust"; dir = 1},/obj/machinery/cell_charger,/obj/item/weapon/cell/high,/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) -"dK" = (/obj/machinery/computer/crew,/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -21},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/medical) -"dL" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/obj/structure/table/glass,/obj/machinery/recharger,/obj/item/device/defib_kit/loaded,/obj/item/device/radio{frequency = 1487; icon_state = "med_walkietalkie"; name = "Medbay Emergency Radio Link"},/obj/machinery/camera/network/research_outpost{c_tag = "OPR - Xenoarch First-Aid"; dir = 1},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/medical) -"dM" = (/obj/structure/table/glass,/obj/item/weapon/storage/firstaid/toxin{pixel_x = 5; pixel_y = 5},/obj/item/weapon/storage/firstaid/fire{pixel_x = 0; pixel_y = 0},/obj/item/weapon/storage/firstaid/adv{pixel_x = 5; pixel_y = 5},/obj/item/weapon/storage/firstaid/o2{pixel_x = 0; pixel_y = 0},/obj/machinery/vending/wallmed1{name = "NanoMed Wall"; pixel_x = 0; pixel_y = -28},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/medical) -"dN" = (/obj/machinery/door/firedoor/border_only,/obj/effect/wingrille_spawn/reinforced,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/medical) -"dO" = (/turf/simulated/floor/tiled/neutral,/area/surface/outpost/research/xenoarcheology) -"dP" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/bed/chair/office/light{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/tiled/neutral,/area/surface/outpost/research/xenoarcheology) -"dQ" = (/obj/structure/table/standard,/obj/effect/floor_decal/corner/purple{dir = 6},/obj/item/weapon/paper_bin{pixel_x = -2; pixel_y = 5},/obj/item/weapon/clipboard,/obj/item/weapon/pen,/obj/item/device/taperecorder,/obj/item/weapon/folder,/obj/item/weapon/stamp,/turf/simulated/floor/tiled/neutral,/area/surface/outpost/research/xenoarcheology) -"dR" = (/obj/effect/floor_decal/corner/purple{dir = 9},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"dS" = (/obj/structure/cable/blue{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/tiled/white,/area/surface/outpost/research/xenoarcheology) -"dT" = (/obj/effect/floor_decal/corner/purple{dir = 6},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"dU" = (/obj/structure/table/reinforced,/obj/item/device/flashlight/lamp,/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/effect/floor_decal/corner/purple{dir = 9},/obj/effect/floor_decal/industrial/warning{dir = 1},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"dV" = (/obj/structure/table/steel,/obj/machinery/cell_charger,/obj/effect/floor_decal/industrial/warning/dust{icon_state = "warning_dust"; dir = 1},/obj/item/weapon/cell/high,/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) -"dW" = (/obj/machinery/atmospherics/binary/pump{dir = 8},/obj/effect/floor_decal/industrial/warning/full,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/anomaly) -"dX" = (/obj/structure/window/reinforced{dir = 1},/obj/effect/floor_decal/industrial/warning{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/yellow{dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"dY" = (/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 1},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/blue{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"dZ" = (/obj/effect/floor_decal/industrial/warning/corner,/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"ea" = (/obj/machinery/door/firedoor/border_only,/obj/effect/wingrille_spawn/reinforced,/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/isolation_b) -"eb" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/blue{d2 = 8; icon_state = "0-8"},/obj/machinery/light_switch{pixel_x = 11; pixel_y = 24},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_b) -"ec" = (/obj/machinery/artifact_scanpad,/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_b) -"ed" = (/obj/machinery/artifact_analyser,/obj/effect/floor_decal/industrial/warning{dir = 4},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_b) -"ee" = (/obj/machinery/door/blast/regular{id = "xenoarch_cell2"},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_b) -"ef" = (/turf/simulated/shuttle/wall/voidcraft/hard_corner,/area/surface/outpost/wall/checkpoint) -"eg" = (/obj/structure/showcase/sign{pixel_y = -5},/turf/simulated/shuttle/wall/voidcraft,/area/surface/outpost/wall/checkpoint) -"eh" = (/obj/item/weapon/banner/nt,/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/outpost/wall/checkpoint) -"ei" = (/obj/item/weapon/banner/nt,/turf/simulated/mineral/floor/ignore_mapgen/sif,/area/surface/cave/explored/normal) -"ej" = (/obj/structure/sign/greencross{desc = "White cross in a green field, you can get medical aid here."; name = "First-Aid"},/turf/simulated/wall,/area/surface/outpost/research/xenoarcheology/medical) -"ek" = (/obj/effect/floor_decal/industrial/warning,/turf/simulated/floor/tiled/neutral,/area/surface/outpost/research/xenoarcheology) -"el" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/effect/floor_decal/industrial/warning,/turf/simulated/floor/tiled/neutral,/area/surface/outpost/research/xenoarcheology) -"em" = (/obj/structure/table/standard,/obj/structure/window/reinforced,/obj/effect/floor_decal/corner/purple{dir = 4},/obj/effect/floor_decal/industrial/warning,/obj/item/device/camera_film{pixel_x = 2; pixel_y = 2},/obj/item/device/camera,/obj/machinery/recharger,/obj/item/weapon/tape_roll,/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/machinery/camera/network/research_outpost{c_tag = "OPR - Xenoarch Crew Area"; dir = 8},/turf/simulated/floor/tiled/neutral,/area/surface/outpost/research/xenoarcheology) -"en" = (/turf/simulated/wall,/area/surface/outpost/research/xenoarcheology) -"eo" = (/obj/effect/floor_decal/corner/purple{dir = 9},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"ep" = (/obj/structure/table/reinforced,/obj/machinery/computer/atmoscontrol/laptop{monitored_alarm_ids = list("isolation_one","isolation_two","isolation_three"); req_access = null; req_one_access = null},/obj/effect/floor_decal/corner/purple{dir = 9},/obj/machinery/light{dir = 8; icon_state = "tube1"; pixel_y = 0},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"eq" = (/obj/machinery/hologram/holopad,/obj/effect/floor_decal/industrial/outline/grey,/obj/machinery/atmospherics/pipe/manifold/hidden/yellow{dir = 8},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"er" = (/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 4},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"es" = (/obj/machinery/atmospherics/valve/digital/open{dir = 4},/obj/effect/floor_decal/industrial/warning/full,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/anomaly) -"et" = (/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 4},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/research{name = "Isolation Room 2"; req_access = list(65)},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_b) -"eu" = (/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 4},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_b) -"ev" = (/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 10},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_b) -"ew" = (/obj/effect/floor_decal/industrial/warning{dir = 4},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_b) -"ex" = (/obj/machinery/light/small{dir = 1},/obj/item/weapon/banner/virgov,/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/outpost/wall/checkpoint) -"ey" = (/obj/structure/table/steel,/obj/item/weapon/tool/screwdriver,/obj/item/weapon/tool/crowbar,/obj/item/weapon/tool/wrench,/obj/effect/floor_decal/industrial/warning/dust{icon_state = "warning_dust"; dir = 1},/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) -"ez" = (/obj/effect/floor_decal/industrial/warning{dir = 9},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology) -"eA" = (/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 5},/obj/machinery/camera/network/research_outpost{c_tag = "OPR - Xenoarch Airlock 1"; dir = 8},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology) -"eB" = (/obj/effect/floor_decal/corner/purple{dir = 5},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"eC" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/effect/floor_decal/corner/purple{dir = 5},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"eD" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/obj/effect/floor_decal/corner/purple{dir = 5},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"eE" = (/obj/machinery/door/firedoor/border_only,/obj/effect/floor_decal/corner/purple{dir = 5},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"eF" = (/obj/machinery/atmospherics/unary/vent_pump/on,/obj/effect/floor_decal/corner/purple{dir = 1},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"eG" = (/obj/structure/table/reinforced,/obj/item/weapon/paper_bin,/obj/item/device/camera,/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/effect/floor_decal/corner/purple{dir = 9},/obj/effect/floor_decal/industrial/warning,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"eH" = (/obj/structure/table/reinforced,/obj/item/weapon/folder,/obj/item/weapon/pen,/obj/item/weapon/tape_roll,/obj/structure/window/reinforced,/obj/effect/floor_decal/industrial/warning,/obj/machinery/atmospherics/pipe/simple/hidden/universal{dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"eI" = (/obj/machinery/atmospherics/binary/pump{dir = 4},/obj/effect/floor_decal/industrial/warning/full,/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/anomaly) -"eJ" = (/obj/structure/window/reinforced,/obj/effect/floor_decal/industrial/warning,/obj/machinery/atmospherics/pipe/manifold/hidden/yellow{dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"eK" = (/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 8},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"eL" = (/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"eM" = (/obj/machinery/door/firedoor/border_only,/obj/effect/wingrille_spawn/reinforced,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/isolation_b) -"eN" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; use_power = 0},/obj/machinery/light,/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_b) -"eO" = (/obj/machinery/atmospherics/pipe/manifold/hidden/yellow,/obj/machinery/alarm/monitor/isolation{alarm_id = "isolation_two"; dir = 1; pixel_x = 0; pixel_y = -22},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_b) -"eP" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8},/obj/machinery/camera/network/research_outpost{c_tag = "OPR - Isolation Cell 2"; dir = 1},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_b) -"eQ" = (/obj/machinery/door/airlock/research{autoclose = 0; frequency = 1379; icon_state = "door_locked"; id_tag = "xenoarch1_airlock_exterior"; locked = 1; name = "Research Exterior Airlock"},/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "xenoarch1_airlock_control"; name = "Xenoarch Access Button"; pixel_x = 0; pixel_y = -24; req_access = null},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology) -"eR" = (/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 8},/obj/effect/floor_decal/rust/part_rusted1,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology) -"eS" = (/obj/effect/floor_decal/industrial/warning{dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology) -"eT" = (/obj/machinery/door/airlock/research{autoclose = 0; frequency = 1379; icon_state = "door_locked"; id_tag = "xenoarch1_airlock_interior"; locked = 1; name = "Research Interior Airlock"},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "xenoarch1_airlock_control"; name = "Research Access Button"; pixel_x = -6; pixel_y = -26; req_access = null},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology) -"eU" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/embedded_controller/radio/airlock/access_controller{id_tag = "xenoarch1_airlock_control"; name = "Research Access Console"; pixel_x = -26; pixel_y = -26; tag_exterior_door = "xenoarch1_airlock_exterior"; tag_interior_door = "xenoarch1_airlock_interior"},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"eV" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"eW" = (/obj/structure/cable/blue{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"eX" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"eY" = (/obj/machinery/door/firedoor/glass,/obj/structure/cable/blue{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/tiled/white,/area/surface/outpost/research/xenoarcheology) -"eZ" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"fa" = (/obj/structure/cable/blue{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/blue{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/obj/machinery/hologram/holopad,/obj/effect/floor_decal/industrial/outline/grey,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"fb" = (/obj/effect/floor_decal/corner/purple{dir = 6},/obj/machinery/camera/network/research_outpost{c_tag = "OPR - Xenoarch Hallway 1"; dir = 8},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"fc" = (/obj/machinery/ai_status_display,/turf/simulated/wall/r_wall,/area/surface/outpost/research/xenoarcheology/anomaly) -"fd" = (/obj/machinery/artifact_harvester,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/bluegrid,/area/surface/outpost/research/xenoarcheology/anomaly) -"fe" = (/obj/item/weapon/anobattery{pixel_x = -6; pixel_y = 2},/obj/item/weapon/anobattery{pixel_x = -2; pixel_y = -2},/obj/item/weapon/anobattery{pixel_x = 2; pixel_y = 2},/obj/item/weapon/anobattery{pixel_x = 6; pixel_y = 6},/obj/structure/table/steel,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/anomaly) -"ff" = (/obj/item/weapon/anodevice{pixel_x = 3; pixel_y = 3},/obj/item/weapon/anodevice,/obj/structure/table/steel,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/anomaly) -"fg" = (/obj/machinery/artifact_harvester,/obj/machinery/atmospherics/pipe/manifold/hidden/yellow{dir = 8},/turf/simulated/floor/bluegrid,/area/surface/outpost/research/xenoarcheology/anomaly) -"fh" = (/obj/effect/floor_decal/industrial/warning/full,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/binary/pump{dir = 4},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/anomaly) -"fi" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"fj" = (/turf/simulated/wall/r_wall,/area/surface/outpost/research/xenoarcheology/isolation_b) -"fk" = (/obj/effect/floor_decal/industrial/warning{dir = 10},/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -21},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology) -"fl" = (/obj/effect/floor_decal/industrial/warning{dir = 6},/obj/machinery/status_display{pixel_y = -32},/obj/machinery/light,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology) -"fm" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/effect/floor_decal/corner/purple{dir = 10},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"fn" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/obj/effect/floor_decal/corner/purple{dir = 8},/obj/effect/floor_decal/industrial/warning/corner,/obj/structure/noticeboard/anomaly{icon_state = "nboard05"; pixel_y = -32},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"fo" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/effect/floor_decal/industrial/warning,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"fp" = (/obj/effect/floor_decal/corner/purple,/obj/effect/floor_decal/industrial/warning/corner{dir = 8},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"fq" = (/obj/machinery/door/firedoor/border_only,/obj/effect/floor_decal/corner/purple{dir = 10},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"fr" = (/obj/effect/floor_decal/corner/purple{dir = 8},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"fs" = (/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"ft" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/obj/effect/floor_decal/corner/purple{dir = 4},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"fu" = (/obj/machinery/artifact_scanpad,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/bluegrid,/area/surface/outpost/research/xenoarcheology/anomaly) -"fv" = (/obj/machinery/artifact_scanpad,/obj/machinery/atmospherics/pipe/simple/hidden/yellow,/turf/simulated/floor/bluegrid,/area/surface/outpost/research/xenoarcheology/anomaly) -"fw" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 8},/obj/structure/cable/blue{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"fx" = (/obj/effect/floor_decal/industrial/warning/corner,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"fy" = (/obj/machinery/door/firedoor/border_only,/obj/effect/wingrille_spawn/reinforced,/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/isolation_c) -"fz" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/blue{d2 = 8; icon_state = "0-8"},/obj/machinery/light_switch{pixel_x = 11; pixel_y = 24},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_c) -"fA" = (/obj/machinery/artifact_scanpad,/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_c) -"fB" = (/obj/machinery/artifact_analyser,/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_c) -"fC" = (/turf/simulated/wall/r_wall,/area/surface/outpost/research/xenoarcheology/isolation_c) -"fD" = (/turf/simulated/wall/r_wall,/area/surface/outpost/research/xenoarcheology/smes) -"fE" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/wall,/area/surface/outpost/research/xenoarcheology/smes) -"fF" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/wall,/area/surface/outpost/research/xenoarcheology/smes) -"fG" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/atmospherics/pipe/simple/hidden/universal,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/engineering{name = "Generator Room"; req_one_access = list(12,47)},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"fH" = (/obj/structure/sign/warning/high_voltage,/turf/simulated/wall,/area/surface/outpost/research/xenoarcheology/smes) -"fI" = (/obj/machinery/recharge_station,/obj/effect/floor_decal/corner/purple{dir = 9},/obj/structure/extinguisher_cabinet{pixel_x = -28; pixel_y = 0},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"fJ" = (/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/blue{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"fK" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) -"fL" = (/obj/machinery/door/firedoor/glass,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/door/airlock/glass_research{name = "Anomalous Materials"; req_access = list(65)},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"fM" = (/obj/effect/floor_decal/industrial/warning{dir = 1},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"fN" = (/obj/effect/floor_decal/industrial/warning{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/structure/cable/blue{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"fO" = (/obj/effect/floor_decal/industrial/warning{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 6},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"fP" = (/obj/effect/floor_decal/industrial/warning{dir = 1},/obj/machinery/atmospherics/pipe/manifold4w/hidden/yellow,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"fQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 1},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"fR" = (/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 4},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/research{name = "Isolation Room 3"; req_access = list(65)},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_c) -"fS" = (/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 4},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_c) -"fT" = (/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 10},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_c) -"fU" = (/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_c) -"fV" = (/obj/machinery/power/smes/buildable/outpost_substation{charge = 500000; input_attempt = 1; input_level = 150000; output_level = 150000; RCon_tag = "Outpost - Xenoarch"},/obj/structure/cable/blue{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"fW" = (/obj/structure/cable/blue{d2 = 8; icon_state = "0-8"},/obj/structure/cable/blue{d2 = 4; icon_state = "0-4"},/obj/structure/anomaly_container,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"fX" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/table/steel,/obj/random/tool,/obj/random/tool,/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"fY" = (/obj/machinery/atmospherics/pipe/simple/hidden/universal,/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/table/steel,/obj/item/weapon/storage/toolbox/mechanical,/obj/structure/extinguisher_cabinet{pixel_y = 30},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"fZ" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/obj/effect/floor_decal/industrial/warning/corner{dir = 4},/obj/structure/anomaly_container,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"ga" = (/obj/machinery/atmospherics/binary/pump/on{dir = 2; target_pressure = 200},/obj/structure/cable/blue{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/blue{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 1},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"gb" = (/obj/structure/table/steel,/obj/machinery/cell_charger,/obj/random/powercell,/obj/random/maintenance/clean,/obj/structure/cable/blue{d2 = 8; icon_state = "0-8"},/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/machinery/light_switch{dir = 2; name = "light switch "; pixel_x = 36; pixel_y = 0},/obj/effect/floor_decal/industrial/warning/corner{dir = 1},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"gc" = (/turf/simulated/wall,/area/surface/outpost/research/xenoarcheology/smes) -"gd" = (/turf/simulated/wall,/area/surface/outpost/research/xenoarcheology/restroom) -"ge" = (/obj/machinery/door/airlock{name = "Research Restroom"},/obj/machinery/door/firedoor/border_only,/obj/structure/cable/blue{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/tiled/freezer,/area/surface/outpost/research/xenoarcheology/restroom) -"gf" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/obj/machinery/camera/network/research_outpost{c_tag = "OPR - Anomalous Materials 1"; dir = 4},/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -21},/obj/effect/floor_decal/corner/purple{dir = 8},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"gg" = (/obj/structure/cable/blue{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/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"gh" = (/obj/machinery/atmospherics/unary/heater{dir = 1},/obj/effect/floor_decal/industrial/outline/yellow,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"gi" = (/obj/machinery/atmospherics/unary/freezer{dir = 1; icon_state = "freezer"},/obj/effect/floor_decal/industrial/outline/yellow,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"gj" = (/obj/machinery/alarm{dir = 1; pixel_y = -22},/obj/effect/floor_decal/corner/purple,/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 4},/obj/structure/anomaly_container,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"gk" = (/obj/machinery/door/firedoor/border_only,/obj/effect/wingrille_spawn/reinforced,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/isolation_c) -"gl" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; use_power = 0},/obj/machinery/light,/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_c) -"gm" = (/obj/machinery/atmospherics/pipe/manifold/hidden/yellow,/obj/machinery/alarm/monitor/isolation{alarm_id = "isolation_one"; dir = 1; pixel_x = 0; pixel_y = -22},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_c) -"gn" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8},/obj/machinery/camera/network/research_outpost{c_tag = "OPR - Isolation Cell 3"; dir = 1},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_c) -"go" = (/obj/item/stack/flag/green,/turf/simulated/mineral/floor/ignore_mapgen/sif,/area/surface/cave/explored/deep) -"gp" = (/obj/effect/floor_decal/industrial/warning/dust{icon_state = "warning_dust"; dir = 8},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) -"gq" = (/obj/machinery/light/small{dir = 1},/obj/effect/floor_decal/industrial/warning/dust{icon_state = "warning_dust"; dir = 4},/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) -"gr" = (/obj/item/stack/flag/red{amount = 1},/turf/simulated/mineral/floor/ignore_mapgen/sif,/area/surface/cave/explored/deep) -"gs" = (/obj/effect/floor_decal/industrial/warning/dust{icon_state = "warning_dust"; dir = 8},/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) -"gt" = (/obj/effect/floor_decal/industrial/warning/dust{icon_state = "warning_dust"; dir = 4},/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) -"gu" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable/heavyduty{d2 = 8; icon_state = "0-8"},/obj/machinery/door/firedoor/border_only,/obj/effect/wingrille_spawn/reinforced,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"gv" = (/obj/machinery/power/terminal{icon_state = "term"; dir = 1},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{d2 = 2; icon_state = "0-2"; pixel_y = 0},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"gw" = (/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"gx" = (/obj/machinery/atmospherics/binary/pump/on{dir = 1; target_pressure = 200},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"gy" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 6},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"gz" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/manifold4w/visible/yellow,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"gA" = (/obj/structure/table/steel,/obj/random/maintenance/clean,/obj/random/maintenance/clean,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"gB" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/machinery/light_switch{pixel_x = 11; pixel_y = 24},/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/structure/mirror{pixel_x = -28},/obj/structure/cable/blue{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/tiled/freezer,/area/surface/outpost/research/xenoarcheology/restroom) -"gC" = (/obj/structure/cable/blue{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/tiled/freezer,/area/surface/outpost/research/xenoarcheology/restroom) -"gD" = (/obj/structure/undies_wardrobe,/turf/simulated/floor/tiled/freezer,/area/surface/outpost/research/xenoarcheology/restroom) -"gE" = (/turf/simulated/wall/r_wall,/area/surface/outpost/research/xenoarcheology/restroom) -"gF" = (/obj/machinery/door/firedoor/border_only,/obj/effect/wingrille_spawn/reinforced,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/analysis) -"gG" = (/obj/machinery/door/firedoor/glass,/obj/machinery/door/airlock/glass_research{name = "Sample Preparation"; req_access = list(65)},/obj/structure/cable/blue{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/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) -"gH" = (/obj/machinery/door/firedoor/glass,/obj/machinery/door/airlock/glass_research{name = "Sample Preparation"; req_access = list(65)},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) -"gI" = (/turf/simulated/wall,/area/surface/outpost/research/xenoarcheology/analysis) -"gJ" = (/turf/simulated/wall/r_wall,/area/surface/outpost/research/xenoarcheology/analysis) -"gK" = (/turf/simulated/wall/r_wall,/area/surface/outpost/research/xenoarcheology/emergencystorage) -"gL" = (/turf/simulated/floor/water{outdoors = 0},/area/surface/cave/explored/normal) -"gM" = (/turf/simulated/floor/plating{icon_state = "asteroidplating2"},/area/surface/cave/explored/normal) -"gN" = (/obj/structure/cable,/obj/machinery/power/port_gen/pacman,/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"gO" = (/obj/machinery/space_heater,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"gP" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan,/obj/machinery/portable_atmospherics/powered/scrubber,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"gQ" = (/obj/machinery/atmospherics/binary/pump,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"gR" = (/obj/machinery/atmospherics/omni/atmos_filter{tag_east = 7; tag_north = 1; tag_south = 2; tag_west = 0},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"gS" = (/obj/machinery/atmospherics/pipe/tank/nitrous_oxide{dir = 8},/obj/machinery/light/small{dir = 4; pixel_y = 0},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"gT" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/structure/mirror{pixel_x = -28},/turf/simulated/floor/tiled/freezer,/area/surface/outpost/research/xenoarcheology/restroom) -"gU" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/tiled/freezer,/area/surface/outpost/research/xenoarcheology/restroom) -"gV" = (/obj/structure/table/standard,/obj/item/weapon/towel{color = "#800080"; name = "purple towel"},/obj/item/weapon/towel{color = "#800080"; name = "purple towel"},/obj/item/weapon/towel{color = "#800080"; name = "purple towel"},/obj/random/soap,/obj/random/soap,/obj/machinery/light{dir = 4},/turf/simulated/floor/tiled/freezer,/area/surface/outpost/research/xenoarcheology/restroom) -"gW" = (/obj/item/weapon/reagent_containers/glass/bottle/toxin,/obj/item/weapon/reagent_containers/glass/beaker/sulphuric{name = "beaker 'sulphuric acid'"},/obj/structure/table/glass,/obj/effect/floor_decal/corner/beige{dir = 9},/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/machinery/light_switch{pixel_x = -36},/obj/structure/cable/blue{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) -"gX" = (/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) -"gY" = (/obj/effect/floor_decal/corner/beige{dir = 4},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) -"gZ" = (/obj/effect/floor_decal/corner/lime{dir = 1},/obj/machinery/atmospherics/unary/vent_scrubber/on,/obj/machinery/camera/network/research_outpost{c_tag = "OPR - Sample Preparation"; dir = 2},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) -"ha" = (/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) -"hb" = (/obj/structure/reagent_dispensers/coolanttank,/obj/effect/floor_decal/corner/lime{dir = 4},/obj/machinery/light{dir = 1},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) -"hc" = (/obj/structure/reagent_dispensers/coolanttank,/obj/effect/floor_decal/corner/lime{dir = 5},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 22},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) -"hd" = (/turf/simulated/wall,/area/surface/outpost/research/xenoarcheology/emergencystorage) -"he" = (/obj/machinery/space_heater,/obj/structure/cable/blue{d2 = 2; icon_state = "0-2"},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/emergencystorage) -"hf" = (/obj/machinery/floodlight,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/emergencystorage) -"hg" = (/obj/structure/closet/crate,/obj/item/stack/material/phoron{amount = 50},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"hh" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan,/obj/machinery/portable_atmospherics/powered/pump/filled{pixel_x = 0},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"hi" = (/obj/machinery/atmospherics/portables_connector{dir = 1},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"hj" = (/obj/machinery/atmospherics/omni/atmos_filter{tag_east = 5; tag_north = 1; tag_south = 2; tag_west = 0},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"hk" = (/obj/machinery/atmospherics/pipe/tank/carbon_dioxide{dir = 8},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"hl" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0},/turf/simulated/floor/tiled/freezer,/area/surface/outpost/research/xenoarcheology/restroom) -"hm" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/tiled/freezer,/area/surface/outpost/research/xenoarcheology/restroom) -"hn" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor/tiled/freezer,/area/surface/outpost/research/xenoarcheology/restroom) -"ho" = (/obj/machinery/chemical_dispenser/full,/obj/structure/sign/warning/nosmoking_2{pixel_x = -32},/obj/effect/floor_decal/corner/beige{dir = 9},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) -"hp" = (/obj/machinery/hologram/holopad,/obj/effect/floor_decal/industrial/outline/grey,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/structure/cable/blue{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) -"hq" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) -"hr" = (/obj/structure/cable/blue{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 = 9},/obj/machinery/door/window/westright,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) -"hs" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) -"ht" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) -"hu" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) -"hv" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock{name = "Emergency Storage"},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/emergencystorage) -"hw" = (/obj/structure/cable/blue{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/emergencystorage) -"hx" = (/obj/item/weapon/weldpack,/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/emergencystorage) -"hy" = (/obj/structure/closet/toolcloset,/obj/random/maintenance/clean,/obj/random/maintenance/clean,/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -21},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"hz" = (/obj/structure/table/reinforced,/obj/item/clothing/gloves/sterile/latex,/obj/structure/window/reinforced{dir = 1},/obj/effect/floor_decal/industrial/warning{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/universal{dir = 4},/obj/item/weapon/storage/box/monkeycubes,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) -"hA" = (/obj/machinery/atmospherics/pipe/manifold4w/visible/cyan,/obj/machinery/meter,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"hB" = (/obj/machinery/atmospherics/pipe/manifold/visible/cyan{dir = 1},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"hC" = (/obj/machinery/atmospherics/omni/atmos_filter{tag_east = 6; tag_north = 1; tag_south = 0; tag_west = 2},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"hD" = (/obj/machinery/atmospherics/pipe/tank/phoron{dir = 8},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"hE" = (/obj/structure/curtain/open/shower,/obj/structure/window/reinforced{dir = 8},/obj/machinery/shower{dir = 4; icon_state = "shower"; pixel_x = 5; pixel_y = 0},/turf/simulated/floor/tiled/freezer,/area/surface/outpost/research/xenoarcheology/restroom) -"hF" = (/obj/structure/window/reinforced/tinted{dir = 4; icon_state = "twindow"},/obj/machinery/recharge_station,/obj/machinery/firealarm{dir = 1; pixel_x = 0; pixel_y = -24},/turf/simulated/floor/tiled/freezer,/area/surface/outpost/research/xenoarcheology/restroom) -"hG" = (/obj/structure/toilet{dir = 1},/turf/simulated/floor/tiled/freezer,/area/surface/outpost/research/xenoarcheology/restroom) -"hH" = (/obj/machinery/chem_master,/obj/effect/floor_decal/corner/beige{dir = 9},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) -"hI" = (/obj/item/weapon/stool/padded,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) -"hJ" = (/obj/effect/floor_decal/corner/beige,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) -"hK" = (/obj/effect/floor_decal/corner/lime{dir = 10},/obj/structure/window/reinforced{dir = 8; health = 1e+006},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) -"hL" = (/obj/effect/floor_decal/corner/lime{dir = 10},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) -"hM" = (/obj/effect/floor_decal/corner/lime{dir = 10},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) -"hN" = (/obj/item/clothing/glasses/meson,/obj/structure/closet/hydrant{pixel_x = -32},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/emergencystorage) -"hO" = (/obj/structure/reagent_dispensers/watertank,/obj/machinery/alarm{dir = 1; pixel_y = -22},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/emergencystorage) -"hP" = (/obj/machinery/portable_atmospherics/canister/air,/obj/machinery/firealarm{dir = 1; pixel_x = 0; pixel_y = -24},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"hQ" = (/obj/machinery/atmospherics/pipe/tank/air{dir = 1; start_pressure = 740},/obj/machinery/ai_status_display{pixel_y = -32},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"hR" = (/obj/machinery/atmospherics/pipe/tank/air{dir = 1; start_pressure = 740},/obj/machinery/light/small,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"hS" = (/obj/machinery/atmospherics/pipe/tank/air{dir = 1; start_pressure = 740},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"hT" = (/obj/machinery/status_display{pixel_y = -32},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"hU" = (/obj/structure/closet/emcloset,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"hV" = (/obj/structure/table/glass,/obj/machinery/reagentgrinder,/obj/machinery/firealarm{dir = 1; pixel_x = 0; pixel_y = -24},/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -21},/obj/effect/floor_decal/corner/beige/full,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) -"hW" = (/obj/item/weapon/reagent_containers/glass/beaker/large,/obj/item/weapon/reagent_containers/dropper{pixel_y = -4},/obj/structure/table/glass,/obj/effect/floor_decal/corner/beige{dir = 10},/obj/machinery/light,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) -"hX" = (/obj/structure/table/glass,/obj/item/weapon/storage/box/beakers{pixel_x = 2; pixel_y = 2},/obj/machinery/alarm{dir = 1; pixel_y = -22},/obj/effect/floor_decal/corner/beige/full{dir = 4},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) -"hY" = (/obj/machinery/radiocarbon_spectrometer,/obj/structure/window/reinforced{dir = 8; health = 1e+006},/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/analysis) -"hZ" = (/obj/structure/table/glass,/obj/item/stack/nanopaste,/obj/item/stack/nanopaste,/obj/item/stack/nanopaste,/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/analysis) -"ia" = (/obj/machinery/radiocarbon_spectrometer,/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/analysis) -"ib" = (/obj/machinery/radiocarbon_spectrometer,/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/analysis) -"ic" = (/obj/structure/table/rack,/obj/item/weapon/storage/toolbox/emergency,/obj/item/clothing/accessory/armband/science,/obj/item/clothing/glasses/science,/obj/item/device/suit_cooling_unit,/obj/item/weapon/extinguisher,/obj/item/device/flashlight,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/emergencystorage) -"id" = (/turf/simulated/floor/plating{icon_state = "asteroidplating2"},/area/surface/outpost/research/xenoarcheology) -"ie" = (/turf/simulated/wall/dungeon,/area/surface/cave/unexplored/normal) -"if" = (/obj/item/stack/flag/green,/turf/simulated/mineral/floor/ignore_mapgen/sif,/area/surface/cave/explored/normal) -"ig" = (/obj/item/stack/flag/red{amount = 1},/turf/simulated/mineral/floor/ignore_mapgen/sif,/area/surface/cave/explored/normal) -"ih" = (/obj/structure/table/standard,/obj/item/weapon/flame/lighter/random,/obj/item/weapon/tool/crowbar,/obj/machinery/atmospherics/pipe/manifold/hidden/yellow{dir = 8},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/anomaly) -"ii" = (/obj/effect/floor_decal/industrial/warning/dust{icon_state = "warning_dust"; dir = 8},/obj/machinery/light/small,/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) -"ij" = (/obj/structure/cable/heavyduty{icon_state = "2-8"},/obj/structure/cable/heavyduty{icon_state = "2-4"},/turf/simulated/floor/plating{icon_state = "asteroidplating2"},/area/surface/cave/explored/normal) -"ik" = (/obj/machinery/light/small,/obj/effect/floor_decal/industrial/warning/dust{icon_state = "warning_dust"; dir = 4},/obj/structure/cable/heavyduty{icon_state = "4-8"},/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) -"il" = (/obj/structure/cable/heavyduty{icon_state = "4-8"},/turf/simulated/floor/plating{icon_state = "asteroidplating2"},/area/surface/cave/explored/normal) -"im" = (/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) -"in" = (/obj/structure/cable/heavyduty{icon_state = "1-2"},/turf/simulated/floor/plating{icon_state = "asteroidplating2"},/area/surface/cave/explored/normal) -"io" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{icon_state = "intact"; dir = 6},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"ip" = (/obj/structure/cable/ender{icon_state = "1-2"; id = "surface_cave"},/turf/simulated/floor/plating{icon_state = "asteroidplating2"},/area/surface/cave/explored/normal) -"ir" = (/obj/machinery/mining/brace,/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) -"is" = (/obj/machinery/mining/drill,/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) -"it" = (/obj/vehicle/train/engine,/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) -"iu" = (/obj/vehicle/train/trolley,/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) -"iw" = (/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/cable/heavyduty{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) -"ix" = (/obj/structure/cable/heavyduty{icon_state = "4-8"},/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) -"iz" = (/obj/effect/floor_decal/industrial/warning/dust,/obj/structure/ore_box,/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) -"iA" = (/obj/effect/step_trigger/teleporter/mine/from_mining,/turf/simulated/mineral/floor/ignore_mapgen/sif,/area/surface/cave/explored/normal) -"iB" = (/obj/effect/step_trigger/teleporter/mine/from_mining,/turf/simulated/floor/water{outdoors = 0},/area/surface/cave/explored/normal) - -(1,1,1) = {" -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacxcwcwcwcxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacyczczczaaaaaaaaaaaaaaaaaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababcxcXcZcYcxababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababcxcZcZcZcxababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacdsdsdsacabababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababefdtegdtefabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacdsdsdsacacababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacehcZcZcZexacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsacacababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacaccZcZcZacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsabacababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacgoabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababgoacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsacacababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsacacababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsacabababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacababababababababababababababababababababababababababababababababababacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacabababababababababababababababababababababababababababababababababacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacababababababababababababababababababababababababababababababababacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacabababababababababababababababababababababababababababababababacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacababababababababababababababababababababababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacababababababababababababababababababababababababababababababacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacabababababababababababababababababababababababababababababacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacabababababababababababababababababababababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacabababababababababababababababababababababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacababababababababababababababababababababababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacabababababababababababababababababababababababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacabababababababababababababababababababababababababababababababacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacabababababababababababababababababababababababababababababababababacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacabababababababababababababababababababababababababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacababababababababababababababababababababababababababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacababababababababababababababababababababababababababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacabdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacabababababababababababababababababababababababababababababababababacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacabababababababababababababababababababababababababababababababababacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacababababababababababababababababababababababababababababababababacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacababababababababababababababababababababababababababababababababacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacabababababababababababababababababababababababababababababababacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacababababababababababababababababababababababababababababababacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacabababababababababababababababababababababababababababababacacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacababababababababababababababababababababababababababababacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacabababababababababababababababababababababababababababacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacababababababababababababababababababababababababababacacacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacababababababababababababababababababababababababacacacacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacabababababababababababababababababababababababacacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacababababababababababababababababababababababacacacacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsabababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacababababababababababababababababababababababacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsabababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacababababababababababababababababababababacacacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsabababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababgoacacacgoababababababababababababababababababacacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacababababababababababababababababacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacabababababababababababababababacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacababababababababababababababababacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacababababababababababababababacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacabacacacacababababababababababababacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacababacacacacabababababababababacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacababacacacacabababababababacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacabababacacacacababababacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacababababacacacacababacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacababababacacacacacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacabababababacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacabababababacacacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacababababacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababgoacacgoabacacacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacababacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacababababacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacabababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacababababababacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacababababababababacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacababababababababababacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacababababababababababababacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacababababababababababababababacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacababababababababababababababababacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacabababababababababababababababababacacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacababababababababababababababababababababacacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacababababababababababababababababababababababacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacababababababababababababababababababababababababacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacabababababababababababababababababababababababababababacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacacacababgoacacacabababababababababababababababababababababababababababababacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacacacacacacacacacacacgoabababababababababababababababababababababababababababababacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacacacacacacacacacacacacacacabacabababababababababababababababababababababababababababababacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacacacacababababacacacacacacacacacacacacabababababababababababababababababababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacacacababababababababacacacacacacacacacacacabababababababababababababababababababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacacababababababababababababacacacacacacacacacacababababababababababababababababababababababababababacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacacabababababababababababababababacacacacacacacacacabababababababababababababababababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacacababababababababababababababababacacacacacacacacacacacababababababababababababababababababababababababacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacabababababababababababababababababababacacacacacacababacacacabababababababababababababababababababababababacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacabababababababababababababababababababababacacacacacacacababacacacacababababababababababababababababababababababacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacacacacabababababababababababababababababababacacacacgoacacacabababacacacacababababababababababababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacabababacacacabababababababababababababababababacacacacacabacacacababababacacacacacacababababababababababababababababacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacababababababababacacababababababababababababababababacacacacababacacacabababababacacacacacacacababababababababababababababacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacababababababababababababacacababababababababababababababacacacacacababacacacababababababababacacacacacacacababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacabababababababababababababababababababababababababababababacacacacabababacacacababababababababababacacacacacacacabacgoababababacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacababababababababababababababababababababababababababababababacacacacacabababacacacababababababababababababacacacacacacacacababababacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacacabababababababababababababababababababababababababababababababacacacacacabababacacacabababababababababababababababacacacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacacacababababababababababababababababababababababababababababababababacacacacababababacacacabababababababababababababababababacacgoacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacacabababababababababababababababababababababababababababababababababababacacacacabababacacacacababababababababababababababababababababacacacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacacabababababababababababababababababababababababababababababababababababababacacacacabababacacacacabababababababababababababababababababababacacacacacacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacabababababababababababababababababababababababababababababababababababababababacacacacabababacacacacacabababababababababababababababababacacabacacababababacacacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacabababababababababababababababababababababababababababababababababababababababababacacacacabababacacacacacababababababababababababababababababacacacacababababababababacacacacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacababababababababababababababababababababababababababababababababababababababababababababacacacacabababacacacacacabababababababababababababababababababacacacababababababababababababacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacababababababababababababababababababababababababababababababababababababababababababababababacacacacabababacacacacacababababababababababababababababababacacacacacababababababababababababababacacacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababacacacacababacacacabababababababababababababababababababacacacacabacabababababababababababababababababacacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacabacacacacabababababababababababababababababababacacacababababababababababababababababababababababababacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacabacacacababababababababababababababababababababacacacabababababababababababababababababababababababababababacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsabacababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacabacacacababababababababababababababababababababacacababababababababababababababababababababababababababababababacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsacacababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacababacacabababababababababababababababababababacacacababababababababababababababababababababababababababababababababacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsacabababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacababacacabababababababababababababababababababacacabababababababababababababababababababababababababababababababababababacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacabacacababababababababababababababababababacacacabababababababababababababababababababababababababababababababababababababacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacabacacababababababababababababababababababacacacabababababababababababababababababababababababababababababababababababababababacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacabacacababababababababababababababababababacacababababababababababababababababababababababababababababababababababababababababababacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacabacacabababababababababababababababababacacababababababababababababababababababababababababababababababababababababababababababababacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacgoacacabababababababababababababababababacacabababababababababababababababababababababababababababababababababababababababababababababacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacabababababababababababababababacacababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacababababababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacabababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacababababababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacabababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacababababababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacabababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacababababababababababababababacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacabacacababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacababababababababababababababacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacabacacabababababababababababababababababababababababababababababababababababababacgrdsdsdsababababababababaa -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafigaeaeaeaeaeaeaeaeaeaeafafafafafigaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeigafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafgLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeafafafaeaeaeafafafaeaeaeafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafgLgLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeafafaeaeafafaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafgLgLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafgLgLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafgLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafgLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeafagaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeafafaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafifaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeifafafafafaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeafafafafaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeafafafafaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafgLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafifaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafgLgLgLafaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafaeaeaeaeafafafaeafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafgLgLgLafafaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafifaeaeaeaeafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafgLgLgLafafaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeafafaeaeafgLgLgLafafaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeafafafaeaeafafafafafaeaeaeaegLgLgLafafaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeafafaeaeaeaeaegLgLgLafaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeafafafaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafifaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLafaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLafaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafgLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafgLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafgLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafifaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafifaeaeaeafafafafafafafafafafafafafafaeaeafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafgLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafgLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeifafifaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafgLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafgLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafgLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafgLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeafifaeaeafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafifaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeafifafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafaeaeaeaeafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafafafifaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeahaiaiajajaiahafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeafafafafafahakaiajalakahafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeafafafafafafahamanaoamamahafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLafaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeapaqapapapaqarapasatauavawaxavavaxayayayayayafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLafaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeapapazaAaBaCaDaEapaFaGaHavaIaJaKaLaMaNaOaPaQayayafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLafafaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeapaRaSaTaUaTaVaWapanaXamavaYaZbabbbcbdbebfbgbhayafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLafafaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeapbiaTbjbkblaTbmbnbobpbqbrbsbtbubububvbwbxbybzayafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeafaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeapbAaTbBbCbDbEbFbGbHbIbJbKbLbMbNbObNaNbPbQbRbSayafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeapbTbUbVbWbXbYbZcacbcccdavcebMcfcgchaNayayayayayafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeapapapapapapapapapcicjckavclcmcncncocpcqcrcsctcuafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaecvdDdVdJeydDcvafafafaecAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcuafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegpimimimimimgqafafafaecAdadbdccEdddedfandgdhdiaxdjdkdkdldmdndodpdqdrcuafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegsimimimimimgtafafaeaecAdudvdwdxdydzdAamandBandCdGdEdFihdHdIcucucucucugMafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegsimimimimimgtafafafaecAdKdLdMdNdOdPdQcIdRdSdTaxdUhzdWdXdYdZeaebecedeegMafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegsirisirimitgtafafafeicAdNdNcAejekelemeneodSdTbKepbNbNeqereseteueveweegMafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegsimimimimiugtafafafidanezeAaneBeBeCeDeEeFdSdTaxeGeHeIeJeKeLeMeNeOePeegMafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegsirisirimiugtafafafideQeReSeTeUeVeWeXeYeZfafbfcfdfefffgfhfifjfjfjfjfjgMafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegsimimimimiugtafafafidamfkflamfmfnfofpfqfrfsftaxfudkdkfvfwfxfyfzfAfBfCafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegsirisirimimgtafafafeifDfDfDfDfEfFfGfHfDfIfJfKfLfMfNfOfPfQesfRfSfTfUfCafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegsimimimimimgtafafafaffDfVfWfXfYfZgagbgcgdgegdavgfggghgibNgjgkglgmgnfCafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeiiimimiwixixikijilililgugvgwgwgxgygzgAgdgBgCgDgEgFgGgFgFgHgIgJgKgKgKgKafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafgLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaecvizizcvizizcvinafafaffDgNgwgOgPgQgRgSgdgTgUgVgdgWgXgYgZhahbhchdhehfgKaeafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafgLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeinafafaffDhggwgOhhhihjhkgdhlhmhngdhohphqhrhshthuhvhwhxgKaeafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafgLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeinafafaffDhygwiohAhBhChDgdhEhFhGgdhHhIhJhKhLhMhLhdhNhOgKaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafgLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeinafafaffDfDhPhQhRhShThUfDgEgEgEgJhVhWhXhYhZiaibhdicgKgKaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafgLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeinafafafaefDfDfDfDfDfDfDfDaeaeaegJgJgFgJgJgFgJgJgKgKgKaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeinafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeinafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeipafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadieiAiAiAadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadiBiBiBadadadadadadadadad -"} +"aa" = (/turf/unsimulated/wall/planetary/sif,/area/surface/cave/unexplored/deep) +"ab" = (/turf/simulated/mineral/sif,/area/surface/cave/unexplored/deep) +"ac" = (/turf/simulated/mineral/floor/ignore_mapgen/sif,/area/surface/cave/explored/deep) +"ad" = (/turf/unsimulated/wall/planetary/sif,/area/surface/cave/unexplored/normal) +"ae" = (/turf/simulated/mineral/sif,/area/surface/cave/unexplored/normal) +"af" = (/turf/simulated/mineral/floor/ignore_mapgen/sif,/area/surface/cave/explored/normal) +"ag" = (/turf/simulated/mineral/floor/ignore_mapgen/sif,/area/surface/cave/unexplored/normal) +"ah" = (/obj/machinery/conveyor{dir = 2; id = "anolongstorage"},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology) +"ai" = (/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology) +"aj" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology) +"ak" = (/obj/machinery/conveyor_switch{id = "anolongstorage"; name = "conveyor switch"; pixel_x = 0; pixel_y = 0; req_access = list(65)},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology) +"al" = (/obj/machinery/light/small,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology) +"am" = (/turf/simulated/wall/r_wall,/area/surface/outpost/research/xenoarcheology) +"an" = (/obj/machinery/door/firedoor/border_only,/obj/effect/wingrille_spawn/reinforced,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology) +"ao" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1397; master_tag = "xenoarch2_airlock_control"; name = "Xenoarch Access Button"; pixel_x = 24; pixel_y = 0; req_access = list(47)},/obj/machinery/door/airlock/research{autoclose = 0; frequency = 1397; icon_state = "door_locked"; id_tag = "xenoarch2_airlock_exterior"; locked = 1; name = "Research Exterior Airlock"},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology) +"ap" = (/turf/simulated/wall/r_wall,/area/surface/outpost/research/xenoarcheology/exp_prep) +"aq" = (/obj/machinery/door/firedoor/border_only,/obj/effect/wingrille_spawn/reinforced,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/exp_prep) +"ar" = (/obj/machinery/conveyor{dir = 2; id = "anolongstorage"},/obj/structure/plasticflaps/mining,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/exp_prep) +"as" = (/obj/effect/floor_decal/industrial/warning{dir = 9},/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/status_display{pixel_x = -32},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology) +"at" = (/obj/effect/floor_decal/industrial/warning{dir = 1},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology) +"au" = (/obj/effect/floor_decal/industrial/warning{dir = 5},/obj/machinery/computer/guestpass{pixel_x = 30; pixel_y = 0},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology) +"av" = (/turf/simulated/wall/r_wall,/area/surface/outpost/research/xenoarcheology/anomaly) +"aw" = (/obj/machinery/conveyor{dir = 2; id = "anolongstorage"},/obj/structure/plasticflaps/mining,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/anomaly) +"ax" = (/obj/machinery/door/firedoor/border_only,/obj/effect/wingrille_spawn/reinforced,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/anomaly) +"ay" = (/turf/simulated/wall/r_wall,/area/surface/outpost/research/xenoarcheology/longtermstorage) +"az" = (/obj/effect/floor_decal/corner/purple/full{dir = 8},/obj/machinery/portable_atmospherics/canister/oxygen,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) +"aA" = (/obj/structure/closet/excavation,/obj/effect/floor_decal/corner/purple{dir = 5},/obj/item/device/radio/intercom{dir = 1; name = "Station Intercom (General)"; pixel_y = 21},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) +"aB" = (/obj/structure/closet/excavation,/obj/effect/floor_decal/corner/purple{dir = 5},/obj/machinery/light{dir = 1},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) +"aC" = (/obj/structure/closet/excavation,/obj/effect/floor_decal/corner/purple{dir = 5},/obj/machinery/alarm{pixel_y = 23},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) +"aD" = (/obj/machinery/conveyor_switch{id = "anolongstorage"; name = "conveyor switch"; pixel_x = 0; pixel_y = 0; req_access = list(65)},/obj/effect/floor_decal/corner/purple{dir = 1},/obj/effect/floor_decal/industrial/warning{dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) +"aE" = (/obj/machinery/conveyor{dir = 2; id = "anolongstorage"},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/exp_prep) +"aF" = (/obj/effect/floor_decal/industrial/warning{dir = 10},/obj/machinery/camera/network/research_outpost{c_tag = "OPR - Xenoarch Airlock 2"; dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology) +"aG" = (/obj/effect/floor_decal/industrial/warning,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology) +"aH" = (/obj/effect/floor_decal/industrial/warning{dir = 6},/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 21},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology) +"aI" = (/obj/machinery/conveyor{dir = 2; id = "anolongstorage"},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/anomaly) +"aJ" = (/obj/effect/floor_decal/industrial/warning{dir = 4},/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 8},/obj/machinery/conveyor_switch{id = "anolongstorage"; name = "conveyor switch"; pixel_x = 0; pixel_y = 0; req_access = list(65)},/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/anomaly) +"aK" = (/obj/machinery/portable_atmospherics/canister/oxygen,/obj/effect/floor_decal/industrial/outline/yellow,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"aL" = (/obj/machinery/portable_atmospherics/canister/sleeping_agent,/obj/effect/floor_decal/industrial/outline/yellow,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"aM" = (/obj/machinery/portable_atmospherics/canister/phoron,/obj/effect/floor_decal/industrial/outline/yellow,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"aN" = (/turf/simulated/wall,/area/surface/outpost/research/xenoarcheology/longtermstorage) +"aO" = (/obj/structure/disposaloutlet{dir = 4},/obj/effect/floor_decal/industrial/hatch/yellow,/obj/structure/disposalpipe/trunk,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/longtermstorage) +"aP" = (/obj/machinery/light/small{dir = 1},/obj/effect/floor_decal/industrial/outline/yellow,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/longtermstorage) +"aQ" = (/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 8},/obj/structure/table/rack,/obj/machinery/alarm{pixel_y = 23},/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/longtermstorage) +"aR" = (/obj/effect/floor_decal/corner/purple/full{dir = 8},/obj/structure/dispenser/oxygen,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) +"aS" = (/obj/effect/floor_decal/corner/purple{dir = 1},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) +"aT" = (/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) +"aU" = (/obj/machinery/hologram/holopad,/obj/effect/floor_decal/industrial/outline/grey,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) +"aV" = (/obj/effect/floor_decal/industrial/warning{dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) +"aW" = (/obj/machinery/disposal/deliveryChute{dir = 1},/obj/effect/floor_decal/industrial/warning,/obj/structure/disposalpipe/trunk,/obj/effect/floor_decal/industrial/outline/yellow,/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/exp_prep) +"aX" = (/obj/machinery/door/airlock/research{autoclose = 0; frequency = 1397; icon_state = "door_locked"; id_tag = "xenoarch2_airlock_interior"; locked = 1; name = "Research Interior Airlock"},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1397; master_tag = "xenoarch2_airlock_control"; name = "Research Access Button"; pixel_x = 26; pixel_y = 6; req_access = null},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology) +"aY" = (/obj/structure/extinguisher_cabinet{pixel_x = -28; pixel_y = 0},/obj/effect/floor_decal/corner/purple{dir = 8},/obj/effect/floor_decal/industrial/warning{dir = 1},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"aZ" = (/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 1},/obj/effect/floor_decal/industrial/warning{dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"ba" = (/obj/machinery/portable_atmospherics/canister/nitrogen,/obj/effect/floor_decal/industrial/outline/yellow,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"bb" = (/obj/machinery/portable_atmospherics/canister/carbon_dioxide,/obj/effect/floor_decal/industrial/outline/yellow,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"bc" = (/obj/machinery/portable_atmospherics/canister/air,/obj/effect/floor_decal/industrial/outline/yellow,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"bd" = (/obj/structure/sign/warning/nosmoking_2,/turf/simulated/wall,/area/surface/outpost/research/xenoarcheology/longtermstorage) +"be" = (/obj/effect/floor_decal/industrial/warning{dir = 1},/obj/structure/disposalpipe/segment,/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/longtermstorage) +"bf" = (/obj/effect/floor_decal/industrial/warning{dir = 1},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/longtermstorage) +"bg" = (/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 1},/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/longtermstorage) +"bh" = (/obj/effect/floor_decal/industrial/outline/grey,/obj/structure/closet/crate,/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/longtermstorage) +"bi" = (/obj/effect/floor_decal/corner/purple{dir = 9},/obj/machinery/status_display{pixel_x = -32},/obj/machinery/floodlight,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) +"bj" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) +"bk" = (/obj/item/weapon/storage/excavation,/obj/item/weapon/pickaxe,/obj/item/weapon/tool/wrench,/obj/item/device/measuring_tape,/obj/item/stack/flag/yellow,/obj/structure/table/steel,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) +"bl" = (/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) +"bm" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) +"bn" = (/obj/machinery/door/firedoor/border_only,/obj/structure/disposalpipe/segment{dir = 4},/obj/effect/wingrille_spawn/reinforced,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/exp_prep) +"bo" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/effect/floor_decal/corner/purple{dir = 1},/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 4},/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 8},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"bp" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/effect/floor_decal/industrial/warning{dir = 1},/obj/machinery/embedded_controller/radio/airlock/access_controller{frequency = 1397; id_tag = "xenoarch2_airlock_control"; name = "Research Access Console"; pixel_x = 26; pixel_y = 26; tag_exterior_door = "xenoarch2_airlock_exterior"; tag_interior_door = "xenoarch2_airlock_interior"},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"bq" = (/obj/machinery/shower{pixel_y = 3},/obj/structure/window/reinforced,/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 22},/turf/simulated/floor/tiled/freezer,/area/surface/outpost/research/xenoarcheology) +"br" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall,/area/surface/outpost/research/xenoarcheology/anomaly) +"bs" = (/obj/machinery/light{dir = 8; icon_state = "tube1"; pixel_y = 0},/obj/effect/floor_decal/corner/purple{dir = 9},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"bt" = (/obj/effect/floor_decal/industrial/warning{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/structure/cable/blue{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"bu" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"bv" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor/border_only,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/airlock/research{name = "Long Term Storage"; req_access = list(65)},/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/longtermstorage) +"bw" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/longtermstorage) +"bx" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/longtermstorage) +"by" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/longtermstorage) +"bz" = (/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/machinery/light_switch{dir = 2; name = "light switch "; pixel_x = 36; pixel_y = 0},/obj/structure/cable/blue{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/longtermstorage) +"bA" = (/obj/machinery/floodlight,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) +"bB" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) +"bC" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) +"bD" = (/obj/effect/floor_decal/corner/purple{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) +"bE" = (/obj/effect/floor_decal/corner/purple{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) +"bF" = (/obj/effect/floor_decal/corner/purple{dir = 8},/obj/structure/cable/blue{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) +"bG" = (/obj/machinery/door/firedoor/glass,/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/airlock/glass_research{name = "Expedition Prep"; req_access = list(65)},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) +"bH" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 8},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"bI" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/structure/cable/blue{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"bJ" = (/obj/machinery/space_heater,/obj/effect/floor_decal/corner/purple{dir = 6},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"bK" = (/obj/machinery/door/firedoor/glass,/obj/effect/wingrille_spawn/reinforced,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/anomaly) +"bL" = (/obj/effect/floor_decal/industrial/outline/yellow,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"bM" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/effect/floor_decal/industrial/warning{dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"bN" = (/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"bO" = (/obj/effect/floor_decal/industrial/outline/yellow,/obj/machinery/atmospherics/portables_connector,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"bP" = (/obj/effect/floor_decal/industrial/outline/grey,/obj/machinery/firealarm{dir = 1; pixel_x = 0; pixel_y = -24},/obj/structure/anomaly_container,/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/longtermstorage) +"bQ" = (/obj/effect/floor_decal/industrial/outline/grey,/obj/machinery/light/small,/obj/structure/anomaly_container,/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/longtermstorage) +"bR" = (/obj/effect/floor_decal/industrial/outline/grey,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/obj/machinery/camera/network/research_outpost{c_tag = "OPR - Long Term Storage"; dir = 1},/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/longtermstorage) +"bS" = (/obj/effect/floor_decal/industrial/outline/grey,/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -21},/obj/structure/anomaly_container,/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/longtermstorage) +"bT" = (/obj/effect/floor_decal/corner/purple/full,/obj/machinery/suspension_gen,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) +"bU" = (/obj/machinery/suspension_gen,/obj/effect/floor_decal/corner/purple{dir = 10},/obj/structure/extinguisher_cabinet{pixel_y = -30},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) +"bV" = (/obj/effect/floor_decal/corner/purple{dir = 10},/obj/machinery/firealarm{dir = 1; pixel_x = 0; pixel_y = -24},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) +"bW" = (/obj/item/weapon/storage/excavation,/obj/item/weapon/pickaxe,/obj/item/weapon/tool/wrench,/obj/item/device/measuring_tape,/obj/item/stack/flag/yellow,/obj/structure/table/steel,/obj/effect/floor_decal/corner/purple{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/camera/network/research_outpost{c_tag = "OPR - Expedition Prep"; dir = 1},/obj/machinery/newscaster{layer = 3.3; pixel_x = 0; pixel_y = -27},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/exp_prep) +"bX" = (/obj/structure/table/rack{dir = 8; layer = 2.6},/obj/structure/window/reinforced{dir = 8; health = 1e+006},/obj/item/weapon/storage/belt/archaeology,/obj/item/clothing/suit/space/anomaly,/obj/item/clothing/head/helmet/space/anomaly,/obj/item/clothing/mask/breath,/obj/structure/window/reinforced,/obj/machinery/door/window/northleft,/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/exp_prep) +"bY" = (/obj/structure/table/rack{dir = 8; layer = 2.6},/obj/structure/window/reinforced{dir = 4; health = 1e+006},/obj/item/weapon/storage/belt/archaeology,/obj/item/clothing/suit/space/anomaly,/obj/item/clothing/head/helmet/space/anomaly,/obj/item/clothing/mask/breath,/obj/structure/window/reinforced,/obj/machinery/door/window/northright,/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/exp_prep) +"bZ" = (/obj/structure/table/steel,/obj/item/device/suit_cooling_unit,/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/machinery/light_switch{pixel_x = 11; pixel_y = -24},/obj/structure/cable/blue,/obj/item/device/suit_cooling_unit,/obj/item/device/gps/science,/obj/item/device/gps/science,/obj/item/device/gps/science,/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/exp_prep) +"ca" = (/obj/machinery/ai_status_display,/turf/simulated/wall/r_wall,/area/surface/outpost/research/xenoarcheology/exp_prep) +"cb" = (/obj/structure/window/reinforced,/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 1},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"cc" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"cd" = (/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 21},/obj/effect/floor_decal/corner/purple{dir = 6},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"ce" = (/obj/effect/floor_decal/industrial/hatch/yellow,/obj/machinery/power/emitter{anchored = 1; dir = 1; state = 2},/obj/structure/window/reinforced,/obj/structure/cable/blue{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"cf" = (/obj/machinery/atmospherics/portables_connector{dir = 4},/obj/effect/floor_decal/industrial/outline/yellow,/obj/structure/window/reinforced,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"cg" = (/obj/machinery/atmospherics/omni/atmos_filter{tag_east = 1; tag_north = 2; tag_south = 0; tag_west = 3},/obj/structure/window/reinforced,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"ch" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/obj/effect/floor_decal/industrial/outline/yellow,/obj/structure/window/reinforced,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"ci" = (/obj/structure/table/rack,/obj/item/clothing/suit/bio_suit/anomaly,/obj/item/clothing/head/bio_hood/anomaly,/obj/item/clothing/mask/breath,/obj/item/clothing/glasses/science,/obj/item/clothing/gloves/sterile/latex,/obj/effect/floor_decal/industrial/hatch/yellow,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"cj" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"ck" = (/obj/machinery/camera/network/research_outpost{c_tag = "OPR - Xenoarch Hallway 2"; dir = 8},/obj/effect/floor_decal/corner/purple{dir = 4},/obj/effect/floor_decal/industrial/warning/corner,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"cl" = (/obj/effect/floor_decal/corner/purple{dir = 4},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/camera/network/research_outpost{c_tag = "OPR - Anomalous Materials 2"; dir = 4},/obj/machinery/newscaster{pixel_x = -30; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"cm" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"cn" = (/obj/effect/floor_decal/industrial/outline/yellow,/obj/machinery/portable_atmospherics/powered/scrubber/huge,/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/anomaly) +"co" = (/obj/machinery/computer/area_atmos,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/anomaly) +"cp" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/machinery/light_switch{pixel_x = 11; pixel_y = 24},/obj/structure/cable/blue{d2 = 2; icon_state = "0-2"},/obj/effect/floor_decal/corner/purple{dir = 4},/obj/structure/cable/blue{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/effect/floor_decal/industrial/warning/corner,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"cq" = (/obj/machinery/door/firedoor/border_only,/obj/effect/wingrille_spawn/reinforced,/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/isolation_a) +"cr" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/blue{d2 = 8; icon_state = "0-8"},/obj/machinery/light_switch{pixel_x = 11; pixel_y = 24},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_a) +"cs" = (/obj/structure/bed,/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_a) +"ct" = (/obj/structure/table/standard,/obj/item/device/flashlight/lamp,/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_a) +"cu" = (/turf/simulated/wall/r_wall,/area/surface/outpost/research/xenoarcheology/isolation_a) +"cv" = (/turf/simulated/wall/r_wall,/area/surface/outpost/mining_main/cave) +"cw" = (/obj/effect/step_trigger/teleporter/wild/to_wild,/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/outpost/wall/checkpoint) +"cx" = (/turf/simulated/shuttle/wall/voidcraft,/area/surface/outpost/wall/checkpoint) +"cy" = (/obj/structure/showcase/sign{pixel_y = -5},/turf/simulated/wall/dungeon,/area/surface/cave/unexplored/deep) +"cz" = (/obj/effect/step_trigger/teleporter/wild/to_wild,/turf/simulated/floor/water{outdoors = 0},/area/surface/cave/explored/deep) +"cA" = (/turf/simulated/wall/r_wall,/area/surface/outpost/research/xenoarcheology/medical) +"cB" = (/obj/machinery/sleeper{dir = 8},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/medical) +"cC" = (/obj/machinery/sleep_console,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/medical) +"cD" = (/obj/structure/table/rack,/obj/machinery/firealarm{pixel_y = 24},/obj/item/bodybag/cryobag,/obj/item/bodybag/cryobag,/obj/item/weapon/storage/toolbox/emergency,/obj/item/weapon/storage/firstaid/regular,/obj/random/medical/lite,/obj/structure/extinguisher_cabinet{pixel_x = 28; pixel_y = 0},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/medical) +"cE" = (/turf/simulated/wall,/area/surface/outpost/research/xenoarcheology/medical) +"cF" = (/obj/structure/closet/secure_closet/xenoarchaeologist{req_access = list(47)},/obj/item/clothing/suit/storage/hooded/wintercoat/science,/obj/effect/floor_decal/corner/purple/full{dir = 8},/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -21},/turf/simulated/floor/tiled/neutral,/area/surface/outpost/research/xenoarcheology) +"cG" = (/obj/structure/closet/secure_closet/xenoarchaeologist{req_access = list(47)},/obj/machinery/newscaster{pixel_y = 30},/obj/item/clothing/suit/storage/hooded/wintercoat/science,/obj/effect/floor_decal/corner/purple{dir = 5},/turf/simulated/floor/tiled/neutral,/area/surface/outpost/research/xenoarcheology) +"cH" = (/obj/effect/floor_decal/corner/purple/full{dir = 1},/obj/structure/bookcase/manuals/xenoarchaeology,/turf/simulated/floor/tiled/neutral,/area/surface/outpost/research/xenoarcheology) +"cI" = (/obj/machinery/door/firedoor/glass,/obj/effect/wingrille_spawn/reinforced,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology) +"cJ" = (/obj/structure/table/rack,/obj/item/clothing/suit/bio_suit/anomaly,/obj/item/clothing/head/bio_hood/anomaly,/obj/item/clothing/mask/breath,/obj/item/clothing/glasses/science,/obj/item/clothing/gloves/sterile/latex,/obj/effect/floor_decal/industrial/hatch/yellow,/obj/machinery/light{dir = 8; icon_state = "tube1"; pixel_y = 0},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"cK" = (/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/structure/cable/blue{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"cL" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/effect/floor_decal/industrial/warning{dir = 4},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"cM" = (/obj/machinery/door/firedoor/glass,/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/airlock/glass_research{name = "Anomalous Materials"; req_access = list(65)},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"cN" = (/obj/effect/floor_decal/industrial/warning,/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/blue{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"cO" = (/obj/effect/floor_decal/industrial/warning,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/structure/cable/blue{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"cP" = (/obj/effect/floor_decal/industrial/warning,/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"cQ" = (/obj/effect/floor_decal/industrial/warning,/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 6},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"cR" = (/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/blue{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"cS" = (/obj/machinery/atmospherics/valve/digital/open{dir = 4},/obj/effect/floor_decal/industrial/warning/full,/obj/structure/cable/blue{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/anomaly) +"cT" = (/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 4},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/research{name = "Isolation Room 1"; req_access = list(65)},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_a) +"cU" = (/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 4},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_a) +"cV" = (/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 10},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_a) +"cW" = (/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_a) +"cX" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/outpost/wall/checkpoint) +"cY" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/outpost/wall/checkpoint) +"cZ" = (/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/outpost/wall/checkpoint) +"da" = (/obj/machinery/newscaster{pixel_x = -30; pixel_y = 0},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/medical) +"db" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/medical) +"dc" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 22},/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/medical) +"dd" = (/obj/machinery/light{dir = 8; icon_state = "tube1"; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_scrubber/on,/obj/effect/floor_decal/corner/purple{dir = 1},/turf/simulated/floor/tiled/neutral,/area/surface/outpost/research/xenoarcheology) +"de" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/tiled/neutral,/area/surface/outpost/research/xenoarcheology) +"df" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/obj/effect/floor_decal/corner/purple{dir = 6},/turf/simulated/floor/tiled/neutral,/area/surface/outpost/research/xenoarcheology) +"dg" = (/obj/structure/table/rack,/obj/item/clothing/suit/bio_suit/anomaly,/obj/item/clothing/head/bio_hood/anomaly,/obj/item/clothing/mask/breath,/obj/item/clothing/glasses/science,/obj/item/clothing/gloves/sterile/latex,/obj/effect/floor_decal/industrial/hatch/yellow,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"dh" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"di" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/obj/effect/floor_decal/corner/purple,/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 4},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"dj" = (/obj/structure/table/standard,/obj/item/clothing/head/welding,/obj/item/weapon/weldingtool,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/anomaly) +"dk" = (/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/anomaly) +"dl" = (/obj/structure/table/standard,/obj/item/weapon/reagent_containers/dropper{pixel_y = -4},/obj/machinery/atmospherics/pipe/simple/hidden/yellow,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/anomaly) +"dm" = (/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"dn" = (/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 4},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"do" = (/obj/machinery/door/firedoor/border_only,/obj/effect/wingrille_spawn/reinforced,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/isolation_a) +"dp" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; use_power = 0},/obj/machinery/light,/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_a) +"dq" = (/obj/machinery/atmospherics/pipe/manifold/hidden/yellow,/obj/machinery/alarm/monitor/isolation{alarm_id = "isolation_one"; dir = 1; pixel_x = 0; pixel_y = -22},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_a) +"dr" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8},/obj/machinery/camera/network/research_outpost{c_tag = "OPR - Isolation Cell 1"; dir = 1},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_a) +"ds" = (/turf/simulated/floor/water{outdoors = 0},/area/surface/cave/explored/deep) +"dt" = (/obj/machinery/door/airlock/voidcraft{name = "Wilderness Containment"},/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/outpost/wall/checkpoint) +"du" = (/obj/structure/bed/chair/office/light,/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/machinery/light_switch{pixel_x = -36},/obj/structure/cable/blue{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/medical) +"dv" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/hologram/holopad,/obj/effect/floor_decal/industrial/outline/grey,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/medical) +"dw" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/medical) +"dx" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/door/firedoor/glass,/obj/machinery/door/airlock/glass_medical{name = "First-Aid Station"},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/medical) +"dy" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/tiled/neutral,/area/surface/outpost/research/xenoarcheology) +"dz" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/structure/cable/blue{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/structure/cable/blue{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/tiled/neutral,/area/surface/outpost/research/xenoarcheology) +"dA" = (/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/machinery/light_switch{dir = 2; name = "light switch "; pixel_x = 36; pixel_y = 0},/obj/structure/table/standard,/obj/structure/cable/blue{d2 = 8; icon_state = "0-8"},/obj/effect/floor_decal/corner/purple{dir = 6},/obj/item/weapon/storage/box/glasses/square{pixel_x = 1; pixel_y = 4},/obj/item/weapon/storage/box/cups,/obj/item/weapon/hand_labeler,/turf/simulated/floor/tiled/neutral,/area/surface/outpost/research/xenoarcheology) +"dB" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor/glass,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/glass_research{name = "Outpost Hallway"; req_access = list(47)},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"dC" = (/obj/machinery/status_display,/turf/simulated/wall/r_wall,/area/surface/outpost/research/xenoarcheology/anomaly) +"dD" = (/obj/effect/floor_decal/industrial/warning/dust{icon_state = "warning_dust"; dir = 1},/obj/machinery/floodlight,/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) +"dE" = (/obj/machinery/artifact_scanpad,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/anomaly) +"dF" = (/obj/machinery/artifact_analyser,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/anomaly) +"dG" = (/obj/structure/table/standard,/obj/machinery/cell_charger,/obj/item/weapon/tool/screwdriver{pixel_y = 15},/obj/item/weapon/melee/baton/loaded,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/anomaly) +"dH" = (/obj/machinery/atmospherics/binary/pump{dir = 4},/obj/effect/floor_decal/industrial/warning/full,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/anomaly) +"dI" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/obj/machinery/button/remote/blast_door{id = "xenoarch_cell2"; name = "Cell 2"; pixel_x = 26; pixel_y = 0},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"dJ" = (/obj/structure/table/steel,/obj/effect/floor_decal/industrial/warning/dust{icon_state = "warning_dust"; dir = 1},/obj/machinery/cell_charger,/obj/item/weapon/cell/high,/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) +"dK" = (/obj/machinery/computer/crew,/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -21},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/medical) +"dL" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/obj/structure/table/glass,/obj/machinery/recharger,/obj/item/device/defib_kit/loaded,/obj/item/device/radio{frequency = 1487; icon_state = "med_walkietalkie"; name = "Medbay Emergency Radio Link"},/obj/machinery/camera/network/research_outpost{c_tag = "OPR - Xenoarch First-Aid"; dir = 1},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/medical) +"dM" = (/obj/structure/table/glass,/obj/item/weapon/storage/firstaid/toxin{pixel_x = 5; pixel_y = 5},/obj/item/weapon/storage/firstaid/fire{pixel_x = 0; pixel_y = 0},/obj/item/weapon/storage/firstaid/adv{pixel_x = 5; pixel_y = 5},/obj/item/weapon/storage/firstaid/o2{pixel_x = 0; pixel_y = 0},/obj/machinery/vending/wallmed1{name = "NanoMed Wall"; pixel_x = 0; pixel_y = -28},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/medical) +"dN" = (/obj/machinery/door/firedoor/border_only,/obj/effect/wingrille_spawn/reinforced,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/medical) +"dO" = (/turf/simulated/floor/tiled/neutral,/area/surface/outpost/research/xenoarcheology) +"dP" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/bed/chair/office/light{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/tiled/neutral,/area/surface/outpost/research/xenoarcheology) +"dQ" = (/obj/structure/table/standard,/obj/effect/floor_decal/corner/purple{dir = 6},/obj/item/weapon/paper_bin{pixel_x = -2; pixel_y = 5},/obj/item/weapon/clipboard,/obj/item/weapon/pen,/obj/item/device/taperecorder,/obj/item/weapon/folder,/obj/item/weapon/stamp,/turf/simulated/floor/tiled/neutral,/area/surface/outpost/research/xenoarcheology) +"dR" = (/obj/effect/floor_decal/corner/purple{dir = 9},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"dS" = (/obj/structure/cable/blue{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/tiled/white,/area/surface/outpost/research/xenoarcheology) +"dT" = (/obj/effect/floor_decal/corner/purple{dir = 6},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"dU" = (/obj/structure/table/reinforced,/obj/item/device/flashlight/lamp,/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/effect/floor_decal/corner/purple{dir = 9},/obj/effect/floor_decal/industrial/warning{dir = 1},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"dV" = (/obj/structure/table/steel,/obj/machinery/cell_charger,/obj/effect/floor_decal/industrial/warning/dust{icon_state = "warning_dust"; dir = 1},/obj/item/weapon/cell/high,/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) +"dW" = (/obj/machinery/atmospherics/binary/pump{dir = 8},/obj/effect/floor_decal/industrial/warning/full,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/anomaly) +"dX" = (/obj/structure/window/reinforced{dir = 1},/obj/effect/floor_decal/industrial/warning{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/yellow{dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"dY" = (/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 1},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/blue{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"dZ" = (/obj/effect/floor_decal/industrial/warning/corner,/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"ea" = (/obj/machinery/door/firedoor/border_only,/obj/effect/wingrille_spawn/reinforced,/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/isolation_b) +"eb" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/blue{d2 = 8; icon_state = "0-8"},/obj/machinery/light_switch{pixel_x = 11; pixel_y = 24},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_b) +"ec" = (/obj/machinery/artifact_scanpad,/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_b) +"ed" = (/obj/machinery/artifact_analyser,/obj/effect/floor_decal/industrial/warning{dir = 4},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_b) +"ee" = (/obj/machinery/door/blast/regular{id = "xenoarch_cell2"},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_b) +"ef" = (/turf/simulated/shuttle/wall/voidcraft/hard_corner,/area/surface/outpost/wall/checkpoint) +"eg" = (/obj/structure/showcase/sign{pixel_y = -5},/turf/simulated/shuttle/wall/voidcraft,/area/surface/outpost/wall/checkpoint) +"eh" = (/obj/item/weapon/banner/nt,/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/outpost/wall/checkpoint) +"ei" = (/obj/item/weapon/banner/nt,/turf/simulated/mineral/floor/ignore_mapgen/sif,/area/surface/cave/explored/normal) +"ej" = (/obj/structure/sign/greencross{desc = "White cross in a green field, you can get medical aid here."; name = "First-Aid"},/turf/simulated/wall,/area/surface/outpost/research/xenoarcheology/medical) +"ek" = (/obj/effect/floor_decal/industrial/warning,/turf/simulated/floor/tiled/neutral,/area/surface/outpost/research/xenoarcheology) +"el" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/effect/floor_decal/industrial/warning,/turf/simulated/floor/tiled/neutral,/area/surface/outpost/research/xenoarcheology) +"em" = (/obj/structure/table/standard,/obj/structure/window/reinforced,/obj/effect/floor_decal/corner/purple{dir = 4},/obj/effect/floor_decal/industrial/warning,/obj/item/device/camera_film{pixel_x = 2; pixel_y = 2},/obj/item/device/camera,/obj/machinery/recharger,/obj/item/weapon/tape_roll,/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/machinery/camera/network/research_outpost{c_tag = "OPR - Xenoarch Crew Area"; dir = 8},/turf/simulated/floor/tiled/neutral,/area/surface/outpost/research/xenoarcheology) +"en" = (/turf/simulated/wall,/area/surface/outpost/research/xenoarcheology) +"eo" = (/obj/effect/floor_decal/corner/purple{dir = 9},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"ep" = (/obj/structure/table/reinforced,/obj/machinery/computer/atmoscontrol/laptop{monitored_alarm_ids = list("isolation_one","isolation_two","isolation_three"); req_access = null; req_one_access = null},/obj/effect/floor_decal/corner/purple{dir = 9},/obj/machinery/light{dir = 8; icon_state = "tube1"; pixel_y = 0},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"eq" = (/obj/machinery/hologram/holopad,/obj/effect/floor_decal/industrial/outline/grey,/obj/machinery/atmospherics/pipe/manifold/hidden/yellow{dir = 8},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"er" = (/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 4},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"es" = (/obj/machinery/atmospherics/valve/digital/open{dir = 4},/obj/effect/floor_decal/industrial/warning/full,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/anomaly) +"et" = (/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 4},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/research{name = "Isolation Room 2"; req_access = list(65)},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_b) +"eu" = (/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 4},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_b) +"ev" = (/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 10},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_b) +"ew" = (/obj/effect/floor_decal/industrial/warning{dir = 4},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_b) +"ex" = (/obj/machinery/light/small{dir = 1},/obj/item/weapon/banner/virgov,/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/outpost/wall/checkpoint) +"ey" = (/obj/structure/table/steel,/obj/item/weapon/tool/screwdriver,/obj/item/weapon/tool/crowbar,/obj/item/weapon/tool/wrench,/obj/effect/floor_decal/industrial/warning/dust{icon_state = "warning_dust"; dir = 1},/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) +"ez" = (/obj/effect/floor_decal/industrial/warning{dir = 9},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology) +"eA" = (/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 5},/obj/machinery/camera/network/research_outpost{c_tag = "OPR - Xenoarch Airlock 1"; dir = 8},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology) +"eB" = (/obj/effect/floor_decal/corner/purple{dir = 5},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"eC" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/effect/floor_decal/corner/purple{dir = 5},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"eD" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/obj/effect/floor_decal/corner/purple{dir = 5},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"eE" = (/obj/machinery/door/firedoor/border_only,/obj/effect/floor_decal/corner/purple{dir = 5},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"eF" = (/obj/machinery/atmospherics/unary/vent_pump/on,/obj/effect/floor_decal/corner/purple{dir = 1},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"eG" = (/obj/structure/table/reinforced,/obj/item/weapon/paper_bin,/obj/item/device/camera,/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/effect/floor_decal/corner/purple{dir = 9},/obj/effect/floor_decal/industrial/warning,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"eH" = (/obj/structure/table/reinforced,/obj/item/weapon/folder,/obj/item/weapon/pen,/obj/item/weapon/tape_roll,/obj/structure/window/reinforced,/obj/effect/floor_decal/industrial/warning,/obj/machinery/atmospherics/pipe/simple/hidden/universal{dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"eI" = (/obj/machinery/atmospherics/binary/pump{dir = 4},/obj/effect/floor_decal/industrial/warning/full,/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/anomaly) +"eJ" = (/obj/structure/window/reinforced,/obj/effect/floor_decal/industrial/warning,/obj/machinery/atmospherics/pipe/manifold/hidden/yellow{dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"eK" = (/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 8},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"eL" = (/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"eM" = (/obj/machinery/door/firedoor/border_only,/obj/effect/wingrille_spawn/reinforced,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/isolation_b) +"eN" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; use_power = 0},/obj/machinery/light,/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_b) +"eO" = (/obj/machinery/atmospherics/pipe/manifold/hidden/yellow,/obj/machinery/alarm/monitor/isolation{alarm_id = "isolation_two"; dir = 1; pixel_x = 0; pixel_y = -22},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_b) +"eP" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8},/obj/machinery/camera/network/research_outpost{c_tag = "OPR - Isolation Cell 2"; dir = 1},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_b) +"eQ" = (/obj/machinery/door/airlock/research{autoclose = 0; frequency = 1379; icon_state = "door_locked"; id_tag = "xenoarch1_airlock_exterior"; locked = 1; name = "Research Exterior Airlock"},/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "xenoarch1_airlock_control"; name = "Xenoarch Access Button"; pixel_x = 0; pixel_y = -24; req_access = null},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology) +"eR" = (/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 8},/obj/effect/floor_decal/rust/part_rusted1,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology) +"eS" = (/obj/effect/floor_decal/industrial/warning{dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology) +"eT" = (/obj/machinery/door/airlock/research{autoclose = 0; frequency = 1379; icon_state = "door_locked"; id_tag = "xenoarch1_airlock_interior"; locked = 1; name = "Research Interior Airlock"},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "xenoarch1_airlock_control"; name = "Research Access Button"; pixel_x = -6; pixel_y = -26; req_access = null},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology) +"eU" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/embedded_controller/radio/airlock/access_controller{id_tag = "xenoarch1_airlock_control"; name = "Research Access Console"; pixel_x = -26; pixel_y = -26; tag_exterior_door = "xenoarch1_airlock_exterior"; tag_interior_door = "xenoarch1_airlock_interior"},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"eV" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"eW" = (/obj/structure/cable/blue{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"eX" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"eY" = (/obj/machinery/door/firedoor/glass,/obj/structure/cable/blue{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/tiled/white,/area/surface/outpost/research/xenoarcheology) +"eZ" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"fa" = (/obj/structure/cable/blue{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/blue{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/obj/machinery/hologram/holopad,/obj/effect/floor_decal/industrial/outline/grey,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"fb" = (/obj/effect/floor_decal/corner/purple{dir = 6},/obj/machinery/camera/network/research_outpost{c_tag = "OPR - Xenoarch Hallway 1"; dir = 8},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"fc" = (/obj/machinery/ai_status_display,/turf/simulated/wall/r_wall,/area/surface/outpost/research/xenoarcheology/anomaly) +"fd" = (/obj/machinery/artifact_harvester,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/bluegrid,/area/surface/outpost/research/xenoarcheology/anomaly) +"fe" = (/obj/item/weapon/anobattery{pixel_x = -6; pixel_y = 2},/obj/item/weapon/anobattery{pixel_x = -2; pixel_y = -2},/obj/item/weapon/anobattery{pixel_x = 2; pixel_y = 2},/obj/item/weapon/anobattery{pixel_x = 6; pixel_y = 6},/obj/structure/table/steel,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/anomaly) +"ff" = (/obj/item/weapon/anodevice{pixel_x = 3; pixel_y = 3},/obj/item/weapon/anodevice,/obj/structure/table/steel,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/anomaly) +"fg" = (/obj/machinery/artifact_harvester,/obj/machinery/atmospherics/pipe/manifold/hidden/yellow{dir = 8},/turf/simulated/floor/bluegrid,/area/surface/outpost/research/xenoarcheology/anomaly) +"fh" = (/obj/effect/floor_decal/industrial/warning/full,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/binary/pump{dir = 4},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/anomaly) +"fi" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"fj" = (/turf/simulated/wall/r_wall,/area/surface/outpost/research/xenoarcheology/isolation_b) +"fk" = (/obj/effect/floor_decal/industrial/warning{dir = 10},/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -21},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology) +"fl" = (/obj/effect/floor_decal/industrial/warning{dir = 6},/obj/machinery/status_display{pixel_y = -32},/obj/machinery/light,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology) +"fm" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/effect/floor_decal/corner/purple{dir = 10},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"fn" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/obj/effect/floor_decal/corner/purple{dir = 8},/obj/effect/floor_decal/industrial/warning/corner,/obj/structure/noticeboard/anomaly{icon_state = "nboard05"; pixel_y = -32},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"fo" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/effect/floor_decal/industrial/warning,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"fp" = (/obj/effect/floor_decal/corner/purple,/obj/effect/floor_decal/industrial/warning/corner{dir = 8},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"fq" = (/obj/machinery/door/firedoor/border_only,/obj/effect/floor_decal/corner/purple{dir = 10},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"fr" = (/obj/effect/floor_decal/corner/purple{dir = 8},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"fs" = (/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"ft" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/obj/effect/floor_decal/corner/purple{dir = 4},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"fu" = (/obj/machinery/artifact_scanpad,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/bluegrid,/area/surface/outpost/research/xenoarcheology/anomaly) +"fv" = (/obj/machinery/artifact_scanpad,/obj/machinery/atmospherics/pipe/simple/hidden/yellow,/turf/simulated/floor/bluegrid,/area/surface/outpost/research/xenoarcheology/anomaly) +"fw" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 8},/obj/structure/cable/blue{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"fx" = (/obj/effect/floor_decal/industrial/warning/corner,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"fy" = (/obj/machinery/door/firedoor/border_only,/obj/effect/wingrille_spawn/reinforced,/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/isolation_c) +"fz" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/blue{d2 = 8; icon_state = "0-8"},/obj/machinery/light_switch{pixel_x = 11; pixel_y = 24},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_c) +"fA" = (/obj/machinery/artifact_scanpad,/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_c) +"fB" = (/obj/machinery/artifact_analyser,/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_c) +"fC" = (/turf/simulated/wall/r_wall,/area/surface/outpost/research/xenoarcheology/isolation_c) +"fD" = (/turf/simulated/wall/r_wall,/area/surface/outpost/research/xenoarcheology/smes) +"fE" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/wall,/area/surface/outpost/research/xenoarcheology/smes) +"fF" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/wall,/area/surface/outpost/research/xenoarcheology/smes) +"fG" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/atmospherics/pipe/simple/hidden/universal,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/engineering{name = "Generator Room"; req_one_access = list(12,47)},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"fH" = (/obj/structure/sign/warning/high_voltage,/turf/simulated/wall,/area/surface/outpost/research/xenoarcheology/smes) +"fI" = (/obj/machinery/recharge_station,/obj/effect/floor_decal/corner/purple{dir = 9},/obj/structure/extinguisher_cabinet{pixel_x = -28; pixel_y = 0},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"fJ" = (/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/blue{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"fK" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology) +"fL" = (/obj/machinery/door/firedoor/glass,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/door/airlock/glass_research{name = "Anomalous Materials"; req_access = list(65)},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"fM" = (/obj/effect/floor_decal/industrial/warning{dir = 1},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"fN" = (/obj/effect/floor_decal/industrial/warning{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/structure/cable/blue{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"fO" = (/obj/effect/floor_decal/industrial/warning{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 6},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"fP" = (/obj/effect/floor_decal/industrial/warning{dir = 1},/obj/machinery/atmospherics/pipe/manifold4w/hidden/yellow,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"fQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 1},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"fR" = (/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 4},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/research{name = "Isolation Room 3"; req_access = list(65)},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_c) +"fS" = (/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 4},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_c) +"fT" = (/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 10},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_c) +"fU" = (/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_c) +"fV" = (/obj/machinery/power/smes/buildable/outpost_substation{charge = 500000; input_attempt = 1; input_level = 150000; output_level = 150000; RCon_tag = "Outpost - Xenoarch"},/obj/structure/cable/blue{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"fW" = (/obj/structure/cable/blue{d2 = 8; icon_state = "0-8"},/obj/structure/cable/blue{d2 = 4; icon_state = "0-4"},/obj/structure/anomaly_container,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"fX" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/table/steel,/obj/random/tool,/obj/random/tool,/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"fY" = (/obj/machinery/atmospherics/pipe/simple/hidden/universal,/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/table/steel,/obj/item/weapon/storage/toolbox/mechanical,/obj/structure/extinguisher_cabinet{pixel_y = 30},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"fZ" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/obj/effect/floor_decal/industrial/warning/corner{dir = 4},/obj/structure/anomaly_container,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"ga" = (/obj/machinery/atmospherics/binary/pump/on{dir = 2; target_pressure = 200},/obj/structure/cable/blue{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/blue{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 1},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"gb" = (/obj/structure/table/steel,/obj/machinery/cell_charger,/obj/random/powercell,/obj/random/maintenance/clean,/obj/structure/cable/blue{d2 = 8; icon_state = "0-8"},/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/machinery/light_switch{dir = 2; name = "light switch "; pixel_x = 36; pixel_y = 0},/obj/effect/floor_decal/industrial/warning/corner{dir = 1},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"gc" = (/turf/simulated/wall,/area/surface/outpost/research/xenoarcheology/smes) +"gd" = (/turf/simulated/wall,/area/surface/outpost/research/xenoarcheology/restroom) +"ge" = (/obj/machinery/door/airlock{name = "Research Restroom"},/obj/machinery/door/firedoor/border_only,/obj/structure/cable/blue{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/tiled/freezer,/area/surface/outpost/research/xenoarcheology/restroom) +"gf" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/obj/machinery/camera/network/research_outpost{c_tag = "OPR - Anomalous Materials 1"; dir = 4},/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -21},/obj/effect/floor_decal/corner/purple{dir = 8},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"gg" = (/obj/structure/cable/blue{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/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"gh" = (/obj/machinery/atmospherics/unary/heater{dir = 1},/obj/effect/floor_decal/industrial/outline/yellow,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"gi" = (/obj/machinery/atmospherics/unary/freezer{dir = 1; icon_state = "freezer"},/obj/effect/floor_decal/industrial/outline/yellow,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"gj" = (/obj/machinery/alarm{dir = 1; pixel_y = -22},/obj/effect/floor_decal/corner/purple,/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 4},/obj/structure/anomaly_container,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"gk" = (/obj/machinery/door/firedoor/border_only,/obj/effect/wingrille_spawn/reinforced,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/isolation_c) +"gl" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; use_power = 0},/obj/machinery/light,/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_c) +"gm" = (/obj/machinery/atmospherics/pipe/manifold/hidden/yellow,/obj/machinery/alarm/monitor/isolation{alarm_id = "isolation_one"; dir = 1; pixel_x = 0; pixel_y = -22},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_c) +"gn" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8},/obj/machinery/camera/network/research_outpost{c_tag = "OPR - Isolation Cell 3"; dir = 1},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_c) +"go" = (/obj/item/stack/flag/green,/turf/simulated/mineral/floor/ignore_mapgen/sif,/area/surface/cave/explored/deep) +"gp" = (/obj/effect/floor_decal/industrial/warning/dust{icon_state = "warning_dust"; dir = 8},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) +"gq" = (/obj/machinery/light/small{dir = 1},/obj/effect/floor_decal/industrial/warning/dust{icon_state = "warning_dust"; dir = 4},/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) +"gr" = (/obj/item/stack/flag/red{amount = 1},/turf/simulated/mineral/floor/ignore_mapgen/sif,/area/surface/cave/explored/deep) +"gs" = (/obj/effect/floor_decal/industrial/warning/dust{icon_state = "warning_dust"; dir = 8},/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) +"gt" = (/obj/effect/floor_decal/industrial/warning/dust{icon_state = "warning_dust"; dir = 4},/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) +"gu" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable/heavyduty{d2 = 8; icon_state = "0-8"},/obj/machinery/door/firedoor/border_only,/obj/effect/wingrille_spawn/reinforced,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"gv" = (/obj/machinery/power/terminal{icon_state = "term"; dir = 1},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{d2 = 2; icon_state = "0-2"; pixel_y = 0},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"gw" = (/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"gx" = (/obj/machinery/atmospherics/binary/pump/on{dir = 1; target_pressure = 200},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"gy" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 6},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"gz" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/manifold4w/visible/yellow,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"gA" = (/obj/structure/table/steel,/obj/random/maintenance/clean,/obj/random/maintenance/clean,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"gB" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/machinery/light_switch{pixel_x = 11; pixel_y = 24},/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/structure/mirror{pixel_x = -28},/obj/structure/cable/blue{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/tiled/freezer,/area/surface/outpost/research/xenoarcheology/restroom) +"gC" = (/obj/structure/cable/blue{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/tiled/freezer,/area/surface/outpost/research/xenoarcheology/restroom) +"gD" = (/obj/structure/undies_wardrobe,/turf/simulated/floor/tiled/freezer,/area/surface/outpost/research/xenoarcheology/restroom) +"gE" = (/turf/simulated/wall/r_wall,/area/surface/outpost/research/xenoarcheology/restroom) +"gF" = (/obj/machinery/door/firedoor/border_only,/obj/effect/wingrille_spawn/reinforced,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/analysis) +"gG" = (/obj/machinery/door/firedoor/glass,/obj/machinery/door/airlock/glass_research{name = "Sample Preparation"; req_access = list(65)},/obj/structure/cable/blue{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/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) +"gH" = (/obj/machinery/door/firedoor/glass,/obj/machinery/door/airlock/glass_research{name = "Sample Preparation"; req_access = list(65)},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) +"gI" = (/turf/simulated/wall,/area/surface/outpost/research/xenoarcheology/analysis) +"gJ" = (/turf/simulated/wall/r_wall,/area/surface/outpost/research/xenoarcheology/analysis) +"gK" = (/turf/simulated/wall/r_wall,/area/surface/outpost/research/xenoarcheology/emergencystorage) +"gL" = (/turf/simulated/floor/water{outdoors = 0},/area/surface/cave/explored/normal) +"gM" = (/turf/simulated/floor/plating{icon_state = "asteroidplating2"},/area/surface/cave/explored/normal) +"gN" = (/obj/structure/cable,/obj/machinery/power/port_gen/pacman,/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"gO" = (/obj/machinery/space_heater,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"gP" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan,/obj/machinery/portable_atmospherics/powered/scrubber,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"gQ" = (/obj/machinery/atmospherics/binary/pump,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"gR" = (/obj/machinery/atmospherics/omni/atmos_filter{tag_east = 7; tag_north = 1; tag_south = 2; tag_west = 0},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"gS" = (/obj/machinery/atmospherics/pipe/tank/nitrous_oxide{dir = 8},/obj/machinery/light/small{dir = 4; pixel_y = 0},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"gT" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/structure/mirror{pixel_x = -28},/turf/simulated/floor/tiled/freezer,/area/surface/outpost/research/xenoarcheology/restroom) +"gU" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/tiled/freezer,/area/surface/outpost/research/xenoarcheology/restroom) +"gV" = (/obj/structure/table/standard,/obj/item/weapon/towel{color = "#800080"; name = "purple towel"},/obj/item/weapon/towel{color = "#800080"; name = "purple towel"},/obj/item/weapon/towel{color = "#800080"; name = "purple towel"},/obj/random/soap,/obj/random/soap,/obj/machinery/light{dir = 4},/turf/simulated/floor/tiled/freezer,/area/surface/outpost/research/xenoarcheology/restroom) +"gW" = (/obj/item/weapon/reagent_containers/glass/bottle/toxin,/obj/item/weapon/reagent_containers/glass/beaker/sulphuric{name = "beaker 'sulphuric acid'"},/obj/structure/table/glass,/obj/effect/floor_decal/corner/beige{dir = 9},/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/machinery/light_switch{pixel_x = -36},/obj/structure/cable/blue{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) +"gX" = (/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) +"gY" = (/obj/effect/floor_decal/corner/beige{dir = 4},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) +"gZ" = (/obj/effect/floor_decal/corner/lime{dir = 1},/obj/machinery/atmospherics/unary/vent_scrubber/on,/obj/machinery/camera/network/research_outpost{c_tag = "OPR - Sample Preparation"; dir = 2},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) +"ha" = (/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) +"hb" = (/obj/structure/reagent_dispensers/coolanttank,/obj/effect/floor_decal/corner/lime{dir = 4},/obj/machinery/light{dir = 1},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) +"hc" = (/obj/structure/reagent_dispensers/coolanttank,/obj/effect/floor_decal/corner/lime{dir = 5},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 22},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) +"hd" = (/turf/simulated/wall,/area/surface/outpost/research/xenoarcheology/emergencystorage) +"he" = (/obj/machinery/space_heater,/obj/structure/cable/blue{d2 = 2; icon_state = "0-2"},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/emergencystorage) +"hf" = (/obj/machinery/floodlight,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/emergencystorage) +"hg" = (/obj/structure/closet/crate,/obj/item/stack/material/phoron{amount = 50},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"hh" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan,/obj/machinery/portable_atmospherics/powered/pump/filled{pixel_x = 0},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"hi" = (/obj/machinery/atmospherics/portables_connector{dir = 1},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"hj" = (/obj/machinery/atmospherics/omni/atmos_filter{tag_east = 5; tag_north = 1; tag_south = 2; tag_west = 0},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"hk" = (/obj/machinery/atmospherics/pipe/tank/carbon_dioxide{dir = 8},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"hl" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0},/turf/simulated/floor/tiled/freezer,/area/surface/outpost/research/xenoarcheology/restroom) +"hm" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/tiled/freezer,/area/surface/outpost/research/xenoarcheology/restroom) +"hn" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor/tiled/freezer,/area/surface/outpost/research/xenoarcheology/restroom) +"ho" = (/obj/machinery/chemical_dispenser/full,/obj/structure/sign/warning/nosmoking_2{pixel_x = -32},/obj/effect/floor_decal/corner/beige{dir = 9},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) +"hp" = (/obj/machinery/hologram/holopad,/obj/effect/floor_decal/industrial/outline/grey,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/structure/cable/blue{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) +"hq" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) +"hr" = (/obj/structure/cable/blue{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 = 9},/obj/machinery/door/window/westright,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) +"hs" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) +"ht" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) +"hu" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) +"hv" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock{name = "Emergency Storage"},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/emergencystorage) +"hw" = (/obj/structure/cable/blue{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/emergencystorage) +"hx" = (/obj/item/weapon/weldpack,/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/emergencystorage) +"hy" = (/obj/structure/closet/toolcloset,/obj/random/maintenance/clean,/obj/random/maintenance/clean,/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -21},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"hz" = (/obj/structure/table/reinforced,/obj/item/clothing/gloves/sterile/latex,/obj/structure/window/reinforced{dir = 1},/obj/effect/floor_decal/industrial/warning{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/universal{dir = 4},/obj/item/weapon/storage/box/monkeycubes,/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology/anomaly) +"hA" = (/obj/machinery/atmospherics/pipe/manifold4w/visible/cyan,/obj/machinery/meter,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"hB" = (/obj/machinery/atmospherics/pipe/manifold/visible/cyan{dir = 1},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"hC" = (/obj/machinery/atmospherics/omni/atmos_filter{tag_east = 6; tag_north = 1; tag_south = 0; tag_west = 2},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"hD" = (/obj/machinery/atmospherics/pipe/tank/phoron{dir = 8},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"hE" = (/obj/structure/curtain/open/shower,/obj/structure/window/reinforced{dir = 8},/obj/machinery/shower{dir = 4; icon_state = "shower"; pixel_x = 5; pixel_y = 0},/turf/simulated/floor/tiled/freezer,/area/surface/outpost/research/xenoarcheology/restroom) +"hF" = (/obj/structure/window/reinforced/tinted{dir = 4; icon_state = "twindow"},/obj/machinery/recharge_station,/obj/machinery/firealarm{dir = 1; pixel_x = 0; pixel_y = -24},/turf/simulated/floor/tiled/freezer,/area/surface/outpost/research/xenoarcheology/restroom) +"hG" = (/obj/structure/toilet{dir = 1},/turf/simulated/floor/tiled/freezer,/area/surface/outpost/research/xenoarcheology/restroom) +"hH" = (/obj/machinery/chem_master,/obj/effect/floor_decal/corner/beige{dir = 9},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) +"hI" = (/obj/item/weapon/stool/padded,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) +"hJ" = (/obj/effect/floor_decal/corner/beige,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) +"hK" = (/obj/effect/floor_decal/corner/lime{dir = 10},/obj/structure/window/reinforced{dir = 8; health = 1e+006},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) +"hL" = (/obj/effect/floor_decal/corner/lime{dir = 10},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) +"hM" = (/obj/effect/floor_decal/corner/lime{dir = 10},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) +"hN" = (/obj/item/clothing/glasses/meson,/obj/structure/closet/hydrant{pixel_x = -32},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/emergencystorage) +"hO" = (/obj/structure/reagent_dispensers/watertank,/obj/machinery/alarm{dir = 1; pixel_y = -22},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/emergencystorage) +"hP" = (/obj/machinery/portable_atmospherics/canister/air,/obj/machinery/firealarm{dir = 1; pixel_x = 0; pixel_y = -24},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"hQ" = (/obj/machinery/atmospherics/pipe/tank/air{dir = 1; start_pressure = 740},/obj/machinery/ai_status_display{pixel_y = -32},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"hR" = (/obj/machinery/atmospherics/pipe/tank/air{dir = 1; start_pressure = 740},/obj/machinery/light/small,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"hS" = (/obj/machinery/atmospherics/pipe/tank/air{dir = 1; start_pressure = 740},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"hT" = (/obj/machinery/status_display{pixel_y = -32},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"hU" = (/obj/structure/closet/emcloset,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"hV" = (/obj/structure/table/glass,/obj/machinery/reagentgrinder,/obj/machinery/firealarm{dir = 1; pixel_x = 0; pixel_y = -24},/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -21},/obj/effect/floor_decal/corner/beige/full,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) +"hW" = (/obj/item/weapon/reagent_containers/glass/beaker/large,/obj/item/weapon/reagent_containers/dropper{pixel_y = -4},/obj/structure/table/glass,/obj/effect/floor_decal/corner/beige{dir = 10},/obj/machinery/light,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) +"hX" = (/obj/structure/table/glass,/obj/item/weapon/storage/box/beakers{pixel_x = 2; pixel_y = 2},/obj/machinery/alarm{dir = 1; pixel_y = -22},/obj/effect/floor_decal/corner/beige/full{dir = 4},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/analysis) +"hY" = (/obj/machinery/radiocarbon_spectrometer,/obj/structure/window/reinforced{dir = 8; health = 1e+006},/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/analysis) +"hZ" = (/obj/structure/table/glass,/obj/item/stack/nanopaste,/obj/item/stack/nanopaste,/obj/item/stack/nanopaste,/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/analysis) +"ia" = (/obj/machinery/radiocarbon_spectrometer,/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/analysis) +"ib" = (/obj/machinery/radiocarbon_spectrometer,/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/analysis) +"ic" = (/obj/structure/table/rack,/obj/item/weapon/storage/toolbox/emergency,/obj/item/clothing/accessory/armband/science,/obj/item/clothing/glasses/science,/obj/item/device/suit_cooling_unit,/obj/item/weapon/extinguisher,/obj/item/device/flashlight,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/emergencystorage) +"id" = (/turf/simulated/floor/plating{icon_state = "asteroidplating2"},/area/surface/outpost/research/xenoarcheology) +"ie" = (/turf/simulated/wall/dungeon,/area/surface/cave/unexplored/normal) +"if" = (/obj/item/stack/flag/green,/turf/simulated/mineral/floor/ignore_mapgen/sif,/area/surface/cave/explored/normal) +"ig" = (/obj/item/stack/flag/red{amount = 1},/turf/simulated/mineral/floor/ignore_mapgen/sif,/area/surface/cave/explored/normal) +"ih" = (/obj/structure/table/standard,/obj/item/weapon/flame/lighter/random,/obj/item/weapon/tool/crowbar,/obj/machinery/atmospherics/pipe/manifold/hidden/yellow{dir = 8},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/anomaly) +"ii" = (/obj/effect/floor_decal/industrial/warning/dust{icon_state = "warning_dust"; dir = 8},/obj/machinery/light/small,/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) +"ij" = (/obj/structure/cable/heavyduty{icon_state = "2-8"},/obj/structure/cable/heavyduty{icon_state = "2-4"},/turf/simulated/floor/plating{icon_state = "asteroidplating2"},/area/surface/cave/explored/normal) +"ik" = (/obj/machinery/light/small,/obj/effect/floor_decal/industrial/warning/dust{icon_state = "warning_dust"; dir = 4},/obj/structure/cable/heavyduty{icon_state = "4-8"},/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) +"il" = (/obj/structure/cable/heavyduty{icon_state = "4-8"},/turf/simulated/floor/plating{icon_state = "asteroidplating2"},/area/surface/cave/explored/normal) +"im" = (/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) +"in" = (/obj/structure/cable/heavyduty{icon_state = "1-2"},/turf/simulated/floor/plating{icon_state = "asteroidplating2"},/area/surface/cave/explored/normal) +"io" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{icon_state = "intact"; dir = 6},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) +"ip" = (/obj/structure/cable/ender{icon_state = "1-2"; id = "surface_cave"},/turf/simulated/floor/plating{icon_state = "asteroidplating2"},/area/surface/cave/explored/normal) +"ir" = (/obj/machinery/mining/brace,/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) +"is" = (/obj/machinery/mining/drill,/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) +"it" = (/obj/vehicle/train/engine,/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) +"iu" = (/obj/vehicle/train/trolley,/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) +"iw" = (/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/cable/heavyduty{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) +"ix" = (/obj/structure/cable/heavyduty{icon_state = "4-8"},/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) +"iz" = (/obj/effect/floor_decal/industrial/warning/dust,/obj/structure/ore_box,/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) +"iA" = (/obj/effect/step_trigger/teleporter/mine/from_mining,/turf/simulated/mineral/floor/ignore_mapgen/sif,/area/surface/cave/explored/normal) +"iB" = (/obj/effect/step_trigger/teleporter/mine/from_mining,/turf/simulated/floor/water{outdoors = 0},/area/surface/cave/explored/normal) +(1,1,1) = {" +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacxcwcwcwcxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacyczczczaaaaaaaaaaaaaaaaaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababcxcXcZcYcxababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababcxcZcZcZcxababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacdsdsdsacabababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababefdtegdtefabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacdsdsdsacacababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacehcZcZcZexacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsacacababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacaccZcZcZacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsabacababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacgoabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababgoacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsacacababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsacacababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsacabababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacababababababababababababababababababababababababababababababababababacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacabababababababababababababababababababababababababababababababababacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacababababababababababababababababababababababababababababababababacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacabababababababababababababababababababababababababababababababacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacababababababababababababababababababababababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacababababababababababababababababababababababababababababababacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacabababababababababababababababababababababababababababababacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacabababababababababababababababababababababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacabababababababababababababababababababababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacababababababababababababababababababababababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacabababababababababababababababababababababababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacabababababababababababababababababababababababababababababababacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacabababababababababababababababababababababababababababababababababacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacabababababababababababababababababababababababababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacababababababababababababababababababababababababababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacababababababababababababababababababababababababababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacabdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacabababababababababababababababababababababababababababababababababacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacabababababababababababababababababababababababababababababababababacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacababababababababababababababababababababababababababababababababacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacababababababababababababababababababababababababababababababababacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacabababababababababababababababababababababababababababababababacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacababababababababababababababababababababababababababababababacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacabababababababababababababababababababababababababababababacacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacababababababababababababababababababababababababababababacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacabababababababababababababababababababababababababababacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacababababababababababababababababababababababababababacacacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacababababababababababababababababababababababababacacacacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacabababababababababababababababababababababababacacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacababababababababababababababababababababababacacacacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsabababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacababababababababababababababababababababababacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsabababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacababababababababababababababababababababacacacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsabababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababgoacacacgoababababababababababababababababababacacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacababababababababababababababababacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacabababababababababababababababacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacababababababababababababababababacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacababababababababababababababacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacabacacacacababababababababababababacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacababacacacacabababababababababacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacababacacacacabababababababacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacabababacacacacababababacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacababababacacacacababacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacababababacacacacacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacabababababacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacabababababacacacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacababababacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababgoacacgoabacacacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacababacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacababababacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacabababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacababababababacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacababababababababacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacababababababababababacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacababababababababababababacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacababababababababababababababacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacababababababababababababababababacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacabababababababababababababababababacacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacababababababababababababababababababababacacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacababababababababababababababababababababababacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacababababababababababababababababababababababababacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacabababababababababababababababababababababababababababacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacacacababgoacacacabababababababababababababababababababababababababababababacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacacacacacacacacacacacgoabababababababababababababababababababababababababababababacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacacacacacacacacacacacacacacabacabababababababababababababababababababababababababababababacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacacacacababababacacacacacacacacacacacacabababababababababababababababababababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacacacababababababababacacacacacacacacacacacabababababababababababababababababababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacacababababababababababababacacacacacacacacacacababababababababababababababababababababababababababacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacacabababababababababababababababacacacacacacacacacabababababababababababababababababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacacababababababababababababababababacacacacacacacacacacacababababababababababababababababababababababababacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacabababababababababababababababababababacacacacacacababacacacabababababababababababababababababababababababacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacabababababababababababababababababababababacacacacacacacababacacacacababababababababababababababababababababababacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacacacacabababababababababababababababababababacacacacgoacacacabababacacacacababababababababababababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacabababacacacabababababababababababababababababacacacacacabacacacababababacacacacacacababababababababababababababababacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacababababababababacacababababababababababababababababacacacacababacacacabababababacacacacacacacababababababababababababababacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacababababababababababababacacababababababababababababababacacacacacababacacacababababababababacacacacacacacababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacabababababababababababababababababababababababababababababacacacacabababacacacababababababababababacacacacacacacabacgoababababacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacababababababababababababababababababababababababababababababacacacacacabababacacacababababababababababababacacacacacacacacababababacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacacabababababababababababababababababababababababababababababababacacacacacabababacacacabababababababababababababababacacacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacacacababababababababababababababababababababababababababababababababacacacacababababacacacabababababababababababababababababacacgoacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacacabababababababababababababababababababababababababababababababababababacacacacabababacacacacababababababababababababababababababababacacacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacacabababababababababababababababababababababababababababababababababababababacacacacabababacacacacabababababababababababababababababababababacacacacacacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacacabababababababababababababababababababababababababababababababababababababababacacacacabababacacacacacabababababababababababababababababacacabacacababababacacacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacacabababababababababababababababababababababababababababababababababababababababababacacacacabababacacacacacababababababababababababababababababacacacacababababababababacacacacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacababababababababababababababababababababababababababababababababababababababababababababacacacacabababacacacacacabababababababababababababababababababacacacababababababababababababacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacacacababababababababababababababababababababababababababababababababababababababababababababababacacacacabababacacacacacababababababababababababababababababacacacacacababababababababababababababacacacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababacacacacababacacacabababababababababababababababababababacacacacabacabababababababababababababababababacacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacabacacacacabababababababababababababababababababacacacababababababababababababababababababababababababacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacabacacacababababababababababababababababababababacacacabababababababababababababababababababababababababababacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsabacababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacabacacacababababababababababababababababababababacacababababababababababababababababababababababababababababababacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsacacababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacababacacabababababababababababababababababababacacacababababababababababababababababababababababababababababababababacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsacabababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacababacacabababababababababababababababababababacacabababababababababababababababababababababababababababababababababababacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacabacacababababababababababababababababababacacacabababababababababababababababababababababababababababababababababababababacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacabacacababababababababababababababababababacacacabababababababababababababababababababababababababababababababababababababababacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacabacacababababababababababababababababababacacababababababababababababababababababababababababababababababababababababababababababacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacabacacabababababababababababababababababacacababababababababababababababababababababababababababababababababababababababababababababacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacgoacacabababababababababababababababababacacabababababababababababababababababababababababababababababababababababababababababababababacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacabababababababababababababababacacababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacababababababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacabababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacababababababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacabababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacababababababababababababababacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacabababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacababababababababababababababacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacabacacababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacababababababababababababababacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacabacacabababababababababababababababababababababababababababababababababababababacgrdsdsdsababababababababaa +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafigaeaeaeaeaeaeaeaeaeaeafafafafafigaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeigafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafgLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeafafafaeaeaeafafafaeaeaeafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafgLgLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeafafaeaeafafaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafgLgLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafgLgLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafgLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafgLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeafagaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeafafaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafifaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeifafafafafaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeafafafafaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeafafafafaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafgLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafifaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafgLgLgLafaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafaeaeaeaeafafafaeafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafgLgLgLafafaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafifaeaeaeaeafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafgLgLgLafafaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeafafaeaeafgLgLgLafafaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeafafafaeaeafafafafafaeaeaeaegLgLgLafafaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeafafaeaeaeaeaegLgLgLafaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeafafafaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafifaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLafaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLafaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafgLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafgLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafgLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafifaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafifaeaeaeafafafafafafafafafafafafafafaeaeafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafgLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafgLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeifafifaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafgLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafgLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafgLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafgLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeafifaeaeafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafaeafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafifaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeafifafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafaeaeaeaeafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafafafifaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeafafafafafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeaeaeaeaeaeaeahaiaiajajaiahafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeaeafafafafafahakaiajalakahafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeaeaeafafafafafafahamanaoamamahafafafafafafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLafaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeaeaeapaqapapapaqarapasatauavawaxavavaxayayayayayafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLafaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafaeapapazaAaBaCaDaEapaFaGaHavaIaJaKaLaMaNaOaPaQayayafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLafafaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeapaRaSaTaUaTaVaWapanaXamavaYaZbabbbcbdbebfbgbhayafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLafafaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafaeapbiaTbjbkblaTbmbnbobpbqbrbsbtbubububvbwbxbybzayafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeafaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeapbAaTbBbCbDbEbFbGbHbIbJbKbLbMbNbObNaNbPbQbRbSayafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeapbTbUbVbWbXbYbZcacbcccdavcebMcfcgchaNayayayayayafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafaeapapapapapapapapapcicjckavclcmcncncocpcqcrcsctcuafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaecvdDdVdJeydDcvafafafaecAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcuafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegpimimimimimgqafafafaecAdadbdccEdddedfandgdhdiaxdjdkdkdldmdndodpdqdrcuafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegsimimimimimgtafafaeaecAdudvdwdxdydzdAamandBandCdGdEdFihdHdIcucucucucugMafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegsimimimimimgtafafafaecAdKdLdMdNdOdPdQcIdRdSdTaxdUhzdWdXdYdZeaebecedeegMafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegsirisirimitgtafafafeicAdNdNcAejekelemeneodSdTbKepbNbNeqereseteueveweegMafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegsimimimimiugtafafafidanezeAaneBeBeCeDeEeFdSdTaxeGeHeIeJeKeLeMeNeOePeegMafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegsirisirimiugtafafafideQeReSeTeUeVeWeXeYeZfafbfcfdfefffgfhfifjfjfjfjfjgMafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegsimimimimiugtafafafidamfkflamfmfnfofpfqfrfsftaxfudkdkfvfwfxfyfzfAfBfCafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegsirisirimimgtafafafeifDfDfDfDfEfFfGfHfDfIfJfKfLfMfNfOfPfQesfRfSfTfUfCafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegsimimimimimgtafafafaffDfVfWfXfYfZgagbgcgdgegdavgfggghgibNgjgkglgmgnfCafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeiiimimiwixixikijilililgugvgwgwgxgygzgAgdgBgCgDgEgFgGgFgFgHgIgJgKgKgKgKafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafgLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaecvizizcvizizcvinafafaffDgNgwgOgPgQgRgSgdgTgUgVgdgWgXgYgZhahbhchdhehfgKaeafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafgLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeinafafaffDhggwgOhhhihjhkgdhlhmhngdhohphqhrhshthuhvhwhxgKaeafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafgLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeinafafaffDhygwiohAhBhChDgdhEhFhGgdhHhIhJhKhLhMhLhdhNhOgKaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafgLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeinafafaffDfDhPhQhRhShThUfDgEgEgEgJhVhWhXhYhZiaibhdicgKgKaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafgLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeinafafafaefDfDfDfDfDfDfDfDaeaeaegJgJgFgJgJgFgJgJgKgKgKaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeinafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeinafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeipafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadieiAiAiAadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadiBiBiBadadadadadadadadad +"} + diff --git a/maps/southern_cross/southern_cross-6.dmm b/maps/southern_cross/southern_cross-6.dmm index f681cf1436..da134489ba 100644 --- a/maps/southern_cross/southern_cross-6.dmm +++ b/maps/southern_cross/southern_cross-6.dmm @@ -544,7 +544,7 @@ "kx" = (/obj/structure/table/rack,/obj/item/clothing/under/color/red,/obj/item/clothing/shoes/brown,/obj/item/weapon/melee/energy/axe,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/tdome) "ky" = (/obj/machinery/door/airlock/centcom{name = "Courthouse"; opacity = 1},/turf/unsimulated/floor{icon_state = "lino"},/area/centcom/command) "kz" = (/obj/machinery/door/airlock/centcom{name = "Administrative Office"; opacity = 1; req_access = list(108)},/turf/unsimulated/floor{dir = 2; icon_state = "dark"},/area/centcom/creed) -"kA" = (/mob/living/simple_animal/corgi/puppy{name = "Bockscar"},/turf/unsimulated/floor{dir = 2; icon_state = "dark"},/area/centcom/creed) +"kA" = (/mob/living/simple_mob/animal/passive/dog/corgi/puppy/Bockscar,/turf/unsimulated/floor{dir = 2; icon_state = "dark"},/area/centcom/creed) "kB" = (/obj/machinery/telecomms/relay/preset/centcom,/turf/unsimulated/floor{dir = 2; icon_state = "dark"},/area/centcom/creed) "kC" = (/obj/machinery/conveyor{dir = 4; id = "QMLoad"},/turf/simulated/shuttle/floor,/area/supply/dock) "kD" = (/obj/machinery/conveyor{dir = 4; id = "QMLoad"},/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "supply_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access = list(13)},/turf/simulated/shuttle/plating,/area/supply/dock) @@ -1243,7 +1243,7 @@ "xU" = (/obj/item/device/camera{name = "Autopsy Camera"; pixel_x = -2; pixel_y = 7},/obj/item/weapon/paper_bin{pixel_y = -6},/obj/item/weapon/pen/red{pixel_x = -1; pixel_y = -9},/obj/item/weapon/pen/blue{pixel_x = 3; pixel_y = -5},/obj/structure/table/standard,/obj/effect/floor_decal/corner/blue{dir = 6},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/medical) "xV" = (/obj/machinery/door/blast/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "tradebridgeshutters"; name = "Blast Shutters"; opacity = 0},/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/full,/turf/simulated/shuttle/plating,/area/shuttle/merchant/home) "xW" = (/obj/structure/frame/computer,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) -"xX" = (/obj/machinery/light{dir = 4},/obj/structure/sign/kiddieplaque{desc = "A plaque commemorating the construction of the cargo ship Beruang."; name = "Beruang"; pixel_x = 32},/mob/living/simple_animal/corgi/tamaskan/spice,/turf/simulated/shuttle/floor/darkred,/area/shuttle/merchant/home) +"xX" = (/obj/machinery/light{dir = 4},/obj/structure/sign/kiddieplaque{desc = "A plaque commemorating the construction of the cargo ship Beruang."; name = "Beruang"; pixel_x = 32},/mob/living/simple_mob/animal/passive/dog/tamaskan/Spice,/turf/simulated/shuttle/floor/darkred,/area/shuttle/merchant/home) "xY" = (/obj/machinery/door/airlock/silver{name = "Toilet"},/turf/simulated/shuttle/floor/white,/area/shuttle/merchant/home) "xZ" = (/obj/machinery/door/airlock/silver{name = "Restroom"},/turf/simulated/shuttle/floor/white,/area/shuttle/merchant/home) "ya" = (/obj/structure/undies_wardrobe,/turf/simulated/shuttle/floor/black,/area/shuttle/merchant/home) @@ -1502,7 +1502,7 @@ "CT" = (/obj/machinery/media/jukebox,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) "CU" = (/obj/machinery/vending/hydronutrients,/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/wizard_station) "CV" = (/obj/structure/closet{icon_closed = "cabinet_closed"; icon_opened = "cabinet_open"; icon_state = "cabinet_closed"},/obj/item/clothing/under/psysuit,/obj/item/clothing/suit/wizrobe/psypurple,/obj/item/clothing/head/wizard/amp,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) -"CW" = (/mob/living/simple_animal/mouse/gray{desc = "He looks kingly."; name = "Arthur"},/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"CW" = (/mob/living/simple_mob/animal/passive/mouse/gray{desc = "He looks kingly."; name = "Arthur"},/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) "CX" = (/obj/structure/flora/pottedplant{icon_state = "plant-24"},/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) "CY" = (/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 1},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/terminal) "CZ" = (/obj/structure/bed/chair/shuttle{dir = 8},/obj/structure/window/reinforced{dir = 4; health = 1e+006},/turf/simulated/shuttle/floor/white,/area/shuttle/escape/centcom) @@ -1696,7 +1696,7 @@ "GF" = (/obj/structure/flight_left{dir = 1},/turf/simulated/shuttle/floor/voidcraft/light,/area/ninja_dojo/start) "GG" = (/obj/structure/bed/chair,/obj/effect/landmark{name = "endgame_exit"},/obj/item/toy/plushie/mouse{desc = "A plushie of a small fuzzy rodent."; name = "Woodrat"},/turf/unsimulated/beach/sand,/area/beach) "GH" = (/obj/structure/bed/chair,/obj/effect/landmark{name = "endgame_exit"},/turf/unsimulated/beach/sand,/area/beach) -"GI" = (/mob/living/simple_animal/crab/Coffee,/turf/unsimulated/beach/sand,/area/beach) +"GI" = (/obj/machinery/vending/coffee,/turf/unsimulated/beach/sand,/area/beach) "GJ" = (/obj/machinery/door/airlock{icon = 'icons/obj/doors/Dooruranium.dmi'},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/ninja_dojo/dojo) "GK" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "ninjawindow"; name = "Blast Shutters"; opacity = 0},/obj/structure/window/reinforced/full,/turf/simulated/shuttle/plating,/area/ninja_dojo/start) "GL" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced/full,/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "ninjawindow"; name = "Blast Shutters"; opacity = 0},/turf/simulated/shuttle/plating,/area/ninja_dojo/start) @@ -2123,7 +2123,7 @@ "OQ" = (/obj/machinery/computer/shuttle_control/web/syndicate{dir = 8},/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) "OR" = (/obj/structure/bed/chair/comfy/red{icon_state = "comfychair_preview"; dir = 8},/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) "OS" = (/obj/machinery/door/airlock/voidcraft/vertical{req_access = list(150)},/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) -"OT" = (/mob/living/simple_animal/cat/kitten{name = "Enola"},/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) +"OT" = (/mob/living/simple_mob/animal/passive/cat/kitten{name = "Enola"},/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) "OU" = (/obj/machinery/door/airlock/voidcraft/vertical{req_access = list(150)},/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start) "OV" = (/obj/machinery/telecomms/allinone{intercept = 1},/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start) "OW" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{id = "skipjackshutters"; name = "Skipjack Blast Shielding"},/obj/structure/window/reinforced/full,/turf/simulated/shuttle/plating,/area/skipjack_station/start) @@ -2204,7 +2204,7 @@ "Qt" = (/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/window{dir = 8; name = "Surgery"; req_access = list(150)},/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) "Qu" = (/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) "Qv" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table/steel,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) -"Qw" = (/mob/living/simple_animal/tindalos,/turf/simulated/shuttle/floor/black,/area/skipjack_station/start) +"Qw" = (/mob/living/simple_mob/animal/passive/tindalos,/turf/simulated/shuttle/floor/black,/area/skipjack_station/start) "Qx" = (/obj/machinery/door/airlock/hatch{req_access = list(150)},/turf/simulated/shuttle/floor/red,/area/skipjack_station/start) "Qy" = (/obj/machinery/optable,/turf/simulated/shuttle/floor/white,/area/skipjack_station/start) "Qz" = (/obj/structure/table/standard,/obj/item/weapon/surgical/cautery,/obj/item/weapon/surgical/retractor,/obj/item/weapon/reagent_containers/glass/bottle/stoxin,/obj/item/weapon/reagent_containers/glass/bottle/stoxin,/obj/item/weapon/reagent_containers/syringe,/turf/simulated/shuttle/floor/white,/area/skipjack_station/start) @@ -2334,8 +2334,8 @@ aaaaaaaaaaaaaaaajgjgjgjojojgjgjgjgjgjgjgjgjgjgjojojgjgjgaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaajgjojojojojPjojojQjQjQjQjQjojgjojojojojgaaaaaaaaaaaaaaaaaaaaaaaaaapPlYjqldldldldldjqjqlZjSjSmapPpPpPpPmbpPpPpPkjkjlekIkIkIjeaaaaaaaaaaaaiWjsjEjFjFjGjsiTiViViVjkjHjIjJjujKjjaaaaiXjajdjmjmjmjmjmjLjaiXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiYjMjMjMjMjMiYiYiYjNiYiYiYjOiYiYiYjMjMjMjMjMiYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaajgjojojgjgjgjgkikikikikikijgjgjgjgjojojgaaaaaaaaaaaaaaaaaaaaaaaaaapPmtjqjqjqjqjqjqjqmuqsmvjSjSjSmwmMmLjSmNmUqskjkjlekIkIkIjeaaaaaaaaaaaaiWjsjUjVjWjXjsiTiViViVjkjYjZjZjujujjaaaaiXjajdjmjmjmjmkajdjaiXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiYkbkckckckciYkdkekfkekekekgkekdiYkckckckckhiYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaajgjojojgksktkukukukvkvkukukukwkxjgjojojgaaaaaaaaaaaaaaaaaaaaaaaaaapPmVmXmWninhnjmtjqnCqsnDjSjSjSjSjSjSjSjSnEqskjkjjekIkIkIjeaaaaaaaaaaaaiWjsjUjVjVjXjsiWiViViVjjjujujujujujjaaaaiXjajdjmjmjmjmjmjLjaiXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiYkkklklklklkmkeknkokpknkqkoknkekmklklklklkriYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaajgjojojgksktkukvkvkHkHkvkvkukwkxjgjojojgaaaaaaaaaaaaaaaaaaaaaaaaaapPpPpPpPpPpPpPqslZqsqsnDjSjSnRnQocobodjSoeqskjkjjekIkIkIjejeaaaaaaaaaaiWjsjUjVjVjXjskyiViViVkzjukAjujukBjjaaaaiXjajdjmjmkCkCkCkDjaiXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiYkEklklklkliYkeknkokpknkqkoknkeiYkFklklklkGiYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaajgjojojgksktkukvkvkHkHkvkvkukwkxjgjojojgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapPokpRolpPpPjSjSjSjSjSjSjSjSomqskjkjlekIkIkIonjeaaaaaaaaaaiWjsjUjVjVjXjsiWiViViVjjjujujujujujjaaaaiXjajdjljmjmjmjnjdjaiXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalhiYiYiYiYiYiYkeknkokpknkqkoknkeiYiYiYiYiYiYlhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaajgjojojgksktkukvkvkHkHkvkvkukwkxjgjojojgaaaaaaaaaaaaaaaaaaaaaaaaaapPpPpPpPpPpPpPqslZqsqsnDjSjSnRnQocobodjSoeqskjkjjekIkIkIjejeaaaaaaaaaaiWjsjUjVjVjXjskyiViViVkzjujujujukBjjaaaaiXjajdjmjmkCkCkCkDjaiXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiYkEklklklkliYkeknkokpknkqkoknkeiYkFklklklkGiYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaajgjojojgksktkukvkvkHkHkvkvkukwkxjgjojojgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapPokpRolpPpPjSjSjSjSjSjSjSjSomqskjkjlekIkIkIonjeaaaaaaaaaaiWjsjUjVjVjXjsiWiViViVjjjukAjujujujjaaaaiXjajdjljmjmjmjnjdjaiXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalhiYiYiYiYiYiYkeknkokpknkqkoknkeiYiYiYiYiYiYlhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaajgjojojgksktkukukukvkvkukukukwkxjgjojojgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapPozpRoloApPqsoBpPjSoMoLpsprpPpPkjkjlekIkIkIpGjeaaaaaaaaaaiWjsjUjVkJjXjsiTiViViVjkjZjZjZjujujjaaaaiXjajdkKjmjmjmkKjdjaiXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakLkMkMkMkMkMiYkeknkokpknkqkoknkeiYkNkNkNkNkNkLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaajgjojojgksktkukukukvkvkukukukwkxjgjojojgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapPpRpRolpIpHpJjqpKjSjSjSjSpLpMqskjkjlekIkIkIonjeaaaaaaaaaaiWjskOkPkPkQjsiTiViViVjkjZkRjujujujjaaaaiXjajdjdkSkSkSjdjdjaiXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakLkMkMkMkMkMkTkUknknknknknknknkVkWkNkNkNkNkNkLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaajgjglajgjgjgjgjglblblblblblbjgjgjgjgjglcjgjgaaaaaaaaaaaaaaaaaaaaaaaaaapPpPpPpPpPpPpNpRolpQpOqqqpqDqrqFqEqOqNqPqskjkjlekIkIkIjejeaaaaaaaaaaiWjsjsjsjsjsjsiWiViViVjjjujujujujujjaaaaiXjajakXkYkYkYkZjajaiXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakLkMkMkMkMkMiYkekekekeknkekekekeiYkNkNkNkNkNkLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -2499,4 +2499,3 @@ aaaaRfababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa "} - diff --git a/maps/southern_cross/southern_cross_areas.dm b/maps/southern_cross/southern_cross_areas.dm index d78089ff34..06ab539b0a 100644 --- a/maps/southern_cross/southern_cross_areas.dm +++ b/maps/southern_cross/southern_cross_areas.dm @@ -108,13 +108,13 @@ icon_state = "bluenew" /area/surface/outside/river/faxalven - name = "Faxälven River" + name = "Faxälven River" /area/surface/outside/river/indalsalven - name = "Indalsälven River" + name = "Indalsälven River" /area/surface/outside/river/svartan - name = "SvartÃ¥n River" + name = "Svartån River" /area/surface/outside/lake/romsele name = "Romsele Lake" diff --git a/maps/southern_cross/southern_cross_defines.dm b/maps/southern_cross/southern_cross_defines.dm index 3d46a3d87b..f55067f0a3 100644 --- a/maps/southern_cross/southern_cross_defines.dm +++ b/maps/southern_cross/southern_cross_defines.dm @@ -213,47 +213,6 @@ teleport_y = world.maxy - 1 teleport_z = Z_LEVEL_SURFACE_MINE - -/obj/effect/step_trigger/teleporter/bridge/east_to_west/New() - ..() - teleport_x = src.x - 4 - teleport_y = src.y - teleport_z = src.z - -/obj/effect/step_trigger/teleporter/bridge/east_to_west/small/New() - ..() - teleport_x = src.x - 3 - teleport_y = src.y - teleport_z = src.z - - -/obj/effect/step_trigger/teleporter/bridge/west_to_east/New() - ..() - teleport_x = src.x + 4 - teleport_y = src.y - teleport_z = src.z - -/obj/effect/step_trigger/teleporter/bridge/west_to_east/small/New() - ..() - teleport_x = src.x + 3 - teleport_y = src.y - teleport_z = src.z - - -/obj/effect/step_trigger/teleporter/bridge/north_to_south/New() - ..() - teleport_x = src.x - teleport_y = src.y - 4 - teleport_z = src.z - - -/obj/effect/step_trigger/teleporter/bridge/south_to_north/New() - ..() - teleport_x = src.x - teleport_y = src.y + 4 - teleport_z = src.z - - /datum/planet/sif expected_z_levels = list( Z_LEVEL_SURFACE, @@ -262,6 +221,49 @@ Z_LEVEL_TRANSIT ) +/obj/effect/step_trigger/teleporter/bridge/east_to_west/Initialize() + teleport_x = src.x - 4 + teleport_y = src.y + teleport_z = src.z + return ..() + +/obj/effect/step_trigger/teleporter/bridge/east_to_west/small/Initialize() + teleport_x = src.x - 3 + teleport_y = src.y + teleport_z = src.z + return ..() + +/obj/effect/step_trigger/teleporter/bridge/west_to_east/Initialize() + teleport_x = src.x + 4 + teleport_y = src.y + teleport_z = src.z + return ..() + +/obj/effect/step_trigger/teleporter/bridge/west_to_east/small/Initialize() + teleport_x = src.x + 3 + teleport_y = src.y + teleport_z = src.z + return ..() + +/obj/effect/step_trigger/teleporter/bridge/north_to_south/Initialize() + teleport_x = src.x + teleport_y = src.y - 4 + teleport_z = src.z + return ..() + +/obj/effect/step_trigger/teleporter/bridge/south_to_north/Initialize() + teleport_x = src.x + teleport_y = src.y + 4 + teleport_z = src.z + return ..() + +/datum/planet/sif + expected_z_levels = list( + Z_LEVEL_SURFACE, + Z_LEVEL_SURFACE_MINE, + Z_LEVEL_SURFACE_WILD + ) + //Suit Storage Units /obj/machinery/suit_cycler/exploration diff --git a/maps/southern_cross/structures/closets/engineering.dm b/maps/southern_cross/structures/closets/engineering.dm index a80fa8eec8..0c757ad011 100644 --- a/maps/southern_cross/structures/closets/engineering.dm +++ b/maps/southern_cross/structures/closets/engineering.dm @@ -27,7 +27,7 @@ /obj/item/taperoll/engineering, /obj/item/clothing/suit/storage/hooded/wintercoat/engineering) -/obj/structure/closet/secure_closet/engineering_chief_wardrobe/initialize() +/obj/structure/closet/secure_closet/engineering_chief_wardrobe/Initialize() if(prob(50)) starts_with += /obj/item/weapon/storage/backpack/industrial else diff --git a/maps/southern_cross/structures/closets/medical.dm b/maps/southern_cross/structures/closets/medical.dm index 2b59597d33..0ea515d974 100644 --- a/maps/southern_cross/structures/closets/medical.dm +++ b/maps/southern_cross/structures/closets/medical.dm @@ -25,7 +25,7 @@ /obj/item/clothing/suit/storage/hooded/wintercoat/medical, /obj/item/clothing/shoes/white) -/obj/structure/closet/secure_closet/CMO_wardrobe/initialize() +/obj/structure/closet/secure_closet/CMO_wardrobe/Initialize() if(prob(50)) starts_with += /obj/item/weapon/storage/backpack/medic else diff --git a/maps/southern_cross/structures/closets/misc.dm b/maps/southern_cross/structures/closets/misc.dm index 82b2bd65cb..5c10a5c900 100644 --- a/maps/southern_cross/structures/closets/misc.dm +++ b/maps/southern_cross/structures/closets/misc.dm @@ -16,7 +16,7 @@ /obj/item/ammo_magazine/clip/c762/hunter = 9, /obj/item/weapon/gun/projectile/shotgun/pump/rifle = 2) -/obj/structure/closet/secure_closet/guncabinet/rifle/initialize() +/obj/structure/closet/secure_closet/guncabinet/rifle/Initialize() if(prob(85)) starts_with += /obj/item/weapon/gun/projectile/shotgun/pump/rifle else @@ -24,7 +24,7 @@ return ..() /obj/structure/closet/secure_closet/guncabinet/phase - name = "phase pistol cabinet" + name = "explorer weapon cabinet" req_one_access = list(access_explorer,access_brig) starts_with = list( @@ -53,7 +53,7 @@ /obj/item/device/radio, /obj/item/stack/marker_beacon/thirty) -/obj/structure/closet/secure_closet/explorer/initialize() +/obj/structure/closet/secure_closet/explorer/Initialize() if(prob(50)) starts_with += /obj/item/weapon/storage/backpack else @@ -129,7 +129,7 @@ /obj/item/weapon/cell/device, /obj/item/device/radio) -/obj/structure/closet/secure_closet/pilot/initialize() +/obj/structure/closet/secure_closet/pilot/Initialize() if(prob(50)) starts_with += /obj/item/weapon/storage/backpack else diff --git a/maps/southern_cross/structures/closets/misc_vr.dm b/maps/southern_cross/structures/closets/misc_vr.dm index 07d98e8434..ab2d2410ff 100644 --- a/maps/southern_cross/structures/closets/misc_vr.dm +++ b/maps/southern_cross/structures/closets/misc_vr.dm @@ -113,7 +113,7 @@ /obj/item/clothing/accessory/holster/machete, /obj/item/weapon/reagent_containers/food/snacks/liquidfood = 2) -/obj/structure/closet/secure_closet/pathfinder/initialize() +/obj/structure/closet/secure_closet/pathfinder/Initialize() if(prob(50)) starts_with += /obj/item/weapon/storage/backpack else diff --git a/maps/southern_cross/structures/closets/security.dm b/maps/southern_cross/structures/closets/security.dm index 314e5a07b9..1bde2d7a34 100644 --- a/maps/southern_cross/structures/closets/security.dm +++ b/maps/southern_cross/structures/closets/security.dm @@ -27,7 +27,7 @@ /obj/item/clothing/head/beret/sec/corporate/hos, /obj/item/clothing/mask/gas/half) -/obj/structure/closet/secure_closet/hos_wardrobe/initialize() +/obj/structure/closet/secure_closet/hos_wardrobe/Initialize() if(prob(50)) starts_with += /obj/item/weapon/storage/backpack/security else diff --git a/maps/submaps/surface_submaps/mountains/BlastMine1.dmm b/maps/submaps/surface_submaps/mountains/BlastMine1.dmm index 34094caf86..a2c17c17c2 100644 --- a/maps/submaps/surface_submaps/mountains/BlastMine1.dmm +++ b/maps/submaps/surface_submaps/mountains/BlastMine1.dmm @@ -3,10 +3,10 @@ "c" = (/obj/structure/sign/warning/bomb_range,/turf/simulated/wall/sandstone,/area/submap/cave/BlastMine1) "d" = (/obj/structure/table/rack,/obj/item/weapon/syndie/c4explosive,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/BlastMine1) "e" = (/obj/structure/loot_pile/surface/bones,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/BlastMine1) -"f" = (/mob/living/simple_animal/hostile/savik{returns_home = 1},/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/BlastMine1) +"f" = (/mob/living/simple_mob/animal/sif/savik,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/BlastMine1) "g" = (/obj/structure/table/rack,/obj/item/clothing/head/bomb_hood,/obj/item/clothing/suit/bomb_suit,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/BlastMine1) "h" = (/obj/item/device/gps/internal/poi{gps_tag = "Unidentified Signal"},/turf/simulated/wall/sandstone,/area/submap/cave/BlastMine1) -"i" = (/mob/living/simple_animal/retaliate/diyaab,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/BlastMine1) +"i" = (/mob/living/simple_mob/animal/sif/diyaab,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/BlastMine1) "j" = (/obj/structure/table/reinforced,/obj/item/weapon/flame/lighter/zippo/c4detonator{detonator_mode = 1},/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/BlastMine1) "k" = (/obj/structure/table/rack,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/BlastMine1) "l" = (/obj/machinery/floodlight,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/BlastMine1) diff --git a/maps/submaps/surface_submaps/mountains/CaveTrench.dmm b/maps/submaps/surface_submaps/mountains/CaveTrench.dmm index 5b362c4692..e44e5185f8 100644 --- a/maps/submaps/surface_submaps/mountains/CaveTrench.dmm +++ b/maps/submaps/surface_submaps/mountains/CaveTrench.dmm @@ -1,1156 +1,58 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"a" = ( -/turf/template_noop, -/area/template_noop) -"b" = ( -/turf/template_noop, -/area/submap/CaveTrench) -"c" = ( -/turf/simulated/mineral/ignore_mapgen, -/area/submap/CaveTrench) -"d" = ( -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/CaveTrench) -"e" = ( -/turf/simulated/floor/outdoors/rocks, -/area/submap/CaveTrench) -"f" = ( -/turf/simulated/floor/water{ - outdoors = 0 - }, -/area/submap/CaveTrench) -"g" = ( -/mob/living/simple_animal/hostile/malf_drone/lesser, -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/CaveTrench) -"h" = ( -/mob/living/simple_animal/fish/trout{ - faction = "malf_drone" - }, -/turf/simulated/floor/water{ - outdoors = 0 - }, -/area/submap/CaveTrench) -"i" = ( -/obj/effect/decal/remains/human, -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/CaveTrench) -"j" = ( -/turf/simulated/wall, -/area/submap/CaveTrench) -"k" = ( -/turf/simulated/floor/holofloor/wood, -/area/submap/CaveTrench) -"l" = ( -/mob/living/simple_animal/fish/trout, -/turf/simulated/floor/water{ - outdoors = 0 - }, -/area/submap/CaveTrench) -"m" = ( -/turf/simulated/wall/wood, -/area/submap/CaveTrench) -"n" = ( -/obj/structure/table/woodentable, -/obj/item/device/flashlight/lantern, -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/CaveTrench) -"o" = ( -/obj/structure/table/woodentable, -/obj/item/weapon/gun/projectile/shotgun/pump, -/turf/simulated/floor/holofloor/wood, -/area/submap/CaveTrench) -"p" = ( -/obj/structure/table/woodentable, -/obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey, -/turf/simulated/floor/holofloor/wood, -/area/submap/CaveTrench) -"q" = ( -/obj/item/weapon/stool/padded, -/turf/simulated/floor/holofloor/wood, -/area/submap/CaveTrench) -"r" = ( -/obj/structure/table/steel, -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/CaveTrench) -"s" = ( -/obj/structure/table/steel, -/obj/item/weapon/paper{ - info = "Rellek's telling me that we're in deep shit if the townies found out I'm cooking up drones out here. Like I give a fuck, We're minning our asses off only to dig into some bug nest to get our legs chewed. Well I'm not looking a gift horse in the mouth. Those drone dudes out in the wild hooked us up with these machines so long as they get some of the metal we dig up. Win win for us, Guess we're retiring early after all."; - name = "Note" - }, -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/CaveTrench) -"t" = ( -/obj/structure/table/steel, -/obj/item/robot_parts/robot_component/actuator, -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/CaveTrench) -"u" = ( -/obj/effect/decal/cleanable/blood, -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/CaveTrench) -"v" = ( -/obj/structure/simple_door/wood, -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/CaveTrench) -"w" = ( -/obj/structure/table/woodentable, -/obj/item/device/flashlight/lamp, -/turf/simulated/floor/holofloor/wood, -/area/submap/CaveTrench) -"x" = ( -/obj/structure/table/steel, -/obj/item/device/robotanalyzer, -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/CaveTrench) -"y" = ( -/obj/structure/table/steel, -/obj/item/weapon/storage/toolbox, -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/CaveTrench) -"z" = ( -/obj/structure/table/bench/steel, -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/CaveTrench) -"A" = ( -/obj/effect/decal/remains, -/obj/item/clothing/under/rank/miner, -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/CaveTrench) -"B" = ( -/turf/simulated/shuttle/plating, -/area/submap/CaveTrench) -"C" = ( -/obj/structure/closet{ - icon_closed = "cabinet_closed"; - icon_opened = "cabinet_open"; - icon_state = "cabinet_closed" - }, -/obj/item/clothing/suit/storage/hooded/wintercoat/miner, -/obj/item/clothing/suit/storage/hooded/wintercoat/miner, -/turf/simulated/floor/holofloor/wood, -/area/submap/CaveTrench) -"D" = ( -/obj/structure/coatrack, -/turf/simulated/floor/holofloor/wood, -/area/submap/CaveTrench) -"E" = ( -/obj/structure/closet/secure_closet/miner, -/turf/simulated/floor/holofloor/wood, -/area/submap/CaveTrench) -"F" = ( -/obj/item/weapon/storage/box/shotgunammo, -/turf/simulated/floor/holofloor/wood, -/area/submap/CaveTrench) -"G" = ( -/obj/structure/table/steel, -/obj/item/robot_parts/l_leg, -/obj/item/robot_parts/head, -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/CaveTrench) -"H" = ( -/obj/effect/decal/cleanable/blood/gibs/robot, -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/CaveTrench) -"I" = ( -/obj/machinery/power/port_gen/pacman, -/turf/simulated/shuttle/plating, -/area/submap/CaveTrench) -"J" = ( -/obj/machinery/drone_fabricator{ - fabricator_tag = "Unknown" - }, -/turf/simulated/shuttle/plating, -/area/submap/CaveTrench) +"a" = (/turf/template_noop,/area/template_noop) +"b" = (/turf/template_noop,/area/submap/Cavelake) +"c" = (/turf/simulated/mineral/ignore_mapgen,/area/submap/Cavelake) +"d" = (/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/Cavelake) +"e" = (/obj/effect/decal/cleanable/cobweb2,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/Cavelake) +"f" = (/turf/simulated/floor/outdoors/rocks,/area/submap/Cavelake) +"g" = (/mob/living/simple_mob/animal/sif/hooligan_crab,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/Cavelake) +"h" = (/turf/simulated/floor/water,/area/submap/Cavelake) +"i" = (/mob/living/simple_mob/animal/passive/fish/perch,/turf/simulated/floor/water,/area/submap/Cavelake) +"j" = (/obj/machinery/crystal,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/Cavelake) +"k" = (/mob/living/simple_mob/animal/passive/fish/trout,/turf/simulated/floor/water,/area/submap/Cavelake) +"l" = (/obj/effect/decal/cleanable/cobweb,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/Cavelake) +"m" = (/obj/random/mob/sif,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/Cavelake) +"n" = (/obj/item/clothing/mask/snorkel,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/Cavelake) +"o" = (/obj/effect/decal/remains/mouse,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/Cavelake) (1,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(2,1,1) = {" -a -b -b -c -c -c -b -b -e -e -e -b -b -b -b -b -b -b -b -a -"} -(3,1,1) = {" -a -b -c -c -d -i -d -e -e -f -e -e -b -b -c -b -b -b -b -a -"} -(4,1,1) = {" -a -c -c -c -d -d -d -e -f -f -f -e -b -c -c -b -b -b -b -a -"} -(5,1,1) = {" -a -c -c -d -d -d -e -e -f -f -f -e -d -d -c -c -c -b -b -a -"} -(6,1,1) = {" -a -c -d -d -d -d -e -f -f -f -f -e -d -d -d -i -c -b -b -a -"} -(7,1,1) = {" -a -c -d -d -d -d -e -f -f -f -f -e -d -d -d -d -c -b -b -a -"} -(8,1,1) = {" -a -c -d -d -d -d -e -f -f -f -f -e -d -d -d -d -c -c -b -a -"} -(9,1,1) = {" -a -c -d -d -d -d -e -h -f -f -f -e -d -d -d -d -c -c -c -a -"} -(10,1,1) = {" -a -c -c -d -d -d -e -f -f -f -h -e -e -d -d -d -r -c -c -a -"} -(11,1,1) = {" -a -c -c -d -d -d -e -f -f -f -f -f -e -d -d -d -s -c -c -a -"} -(12,1,1) = {" -a -c -d -d -d -j -e -f -f -f -f -f -e -j -d -d -t -x -c -a -"} -(13,1,1) = {" -a -c -d -d -d -k -k -k -k -k -k -k -k -k -d -d -u -y -G -a -"} -(14,1,1) = {" -a -c -d -d -d -k -k -k -k -k -k -k -k -k -d -g -d -z -H -a -"} -(15,1,1) = {" -a -c -d -d -d -j -e -f -f -f -f -f -e -j -d -d -d -d -u -a -"} -(16,1,1) = {" -a -c -d -d -d -e -e -f -f -f -f -f -e -d -d -d -d -A -I -a -"} -(17,1,1) = {" -a -c -d -d -d -e -f -f -f -f -f -f -e -d -d -d -d -B -J -a -"} -(18,1,1) = {" -a -c -d -d -d -e -f -h -f -f -f -e -d -d -d -d -d -B -B -a -"} -(19,1,1) = {" -a -c -d -d -d -e -f -f -f -f -f -e -d -d -d -d -d -d -B -a -"} -(20,1,1) = {" -a -c -d -d -d -e -f -f -f -f -f -e -d -d -d -n -d -d -d -a -"} -(21,1,1) = {" -a -c -d -d -d -e -f -f -f -f -f -e -d -d -m -m -v -m -m -a -"} -(22,1,1) = {" -a -c -d -d -d -e -f -f -f -f -f -e -d -d -m -o -k -C -m -a -"} -(23,1,1) = {" -a -c -d -d -g -e -f -f -f -f -f -e -d -d -m -p -k -D -m -a -"} -(24,1,1) = {" -a -c -d -d -d -e -f -f -l -f -f -e -d -d -m -k -k -E -m -a -"} -(25,1,1) = {" -a -c -c -d -d -e -f -f -f -f -f -e -d -d -m -k -q -k -m -a -"} -(26,1,1) = {" -a -c -c -d -d -e -f -f -f -f -f -e -d -d -m -q -w -q -m -a -"} -(27,1,1) = {" -a -c -c -d -d -e -f -f -f -f -f -e -d -d -m -k -q -F -m -a -"} -(28,1,1) = {" -a -c -c -d -d -e -f -f -f -f -e -e -d -d -m -m -m -m -m -a -"} -(29,1,1) = {" -a -c -c -d -d -e -f -f -f -f -e -d -d -d -d -m -m -m -d -a -"} -(30,1,1) = {" -a -c -c -d -d -e -f -f -f -f -e -d -d -d -d -d -d -d -d -a -"} -(31,1,1) = {" -a -c -c -d -d -e -f -f -f -f -e -d -d -d -d -d -d -d -d -a -"} -(32,1,1) = {" -a -c -c -d -d -e -f -f -f -f -e -d -d -d -d -d -d -d -d -a -"} -(33,1,1) = {" -a -c -d -d -d -e -f -f -f -f -e -d -d -d -d -d -d -d -d -a -"} -(34,1,1) = {" -a -c -d -d -d -e -f -f -f -f -e -d -d -d -d -d -d -d -c -a -"} -(35,1,1) = {" -a -c -d -d -d -e -f -f -f -f -e -e -d -d -d -d -d -d -c -a -"} -(36,1,1) = {" -a -c -d -d -d -e -f -f -f -f -f -e -d -d -d -d -d -d -c -a -"} -(37,1,1) = {" -a -c -d -d -d -e -f -h -f -f -f -e -d -d -d -d -d -c -c -a -"} -(38,1,1) = {" -a -c -d -e -e -e -f -f -f -f -e -e -d -d -d -d -d -c -c -a -"} -(39,1,1) = {" -a -c -e -e -f -f -f -f -f -f -e -d -d -d -d -d -d -c -c -a -"} -(40,1,1) = {" -a -c -e -f -f -f -f -f -f -f -e -d -d -d -d -d -d -c -b -a -"} -(41,1,1) = {" -a -c -e -f -f -f -f -f -f -f -e -d -d -d -i -b -b -b -c -a -"} -(42,1,1) = {" -a -c -e -f -h -f -f -f -f -f -e -d -d -d -d -b -b -b -b -a -"} -(43,1,1) = {" -a -c -e -f -f -f -e -e -f -f -e -d -d -d -b -b -b -b -b -a -"} -(44,1,1) = {" -a -c -e -e -e -c -c -e -e -e -e -d -c -c -c -c -b -b -b -a -"} -(45,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +abbbbccbbbbbbcccccccbbbbbbbbbbbbbbbbbbba +abbbcccdddddccccccccbbbbbcccccccccccbbba +abbcccddddddddddddddbbbbbbbccccccccccbba +abcccdddddddddddddddddddddddddddddeccbba +abcccddddddddddddddddddddddddddddddccbba +acccddddddddddddddddddddddddddddddddcbba +acccdddddddddddddddddffffffffffdddddcbba +acccdddddddddddddgdfffhhhhhhhhffddddcbba +acccdddddddddddddddfhhhhhhhhhhhfddddcbba +accdddddddddddddddfhhhhhhhhhhhhffdddccba +accdddddddddddddddfhhhhhhhhhhhhhffffccca +acddddddddddddddddffhhhhhhihhhhhhfffffca +acddddcccjddddddddffhhhhhhhhhhhhhhhhhfca +acdddcccccdddddddddffhhhhhhhhhhhhhhhhfca +acdddccccccddddddddffhhhhhhhhhhhhhhhhfca +acdddjcccccddddddddffhhhhhhhhhhhhhhhkfca +accddddcclmdddddddddfhhhhhhhhhhhhhhhhfca +accdddddddddddddddddfhhhhhhhhhhhhhhhhfca +accdddddddddddddddddfhhhhhhhhhhhhhhhhfca +accdddddddddddddddddffhhhhhhhhhhhhhhhfca +acddddddddnddddddddddfhhhhhihhhhhhhhhfca +acddddffffffffffffdddffhhhhhhhhhhhhhhfca +acdffffhhhhhhhhhffdddfhhhhhhhhhhhhhhffca +acfhhhhhkhhhhhhhhfdddfhhhhhhhhhhhhffccca +acffhhhhhhhhhhihhfdddfhhhhhhhhhhfffdccba +acdffhhhhhhhhhhhhfddddfhhhhhhhhhfdddcbba +acddffhhhhhkhhhhhffdddfhhhhhhhfffdddccba +acdddfffhhhhhhhhhhffdddffffffffddddcccba +acddgdddffffhhhhhhhfdddddffddddddddcccba +acdddodddddfffffffffdddddddddddddddcccba +acdddddddddddddddddddddddddddddddddccbba +accddddddddddddddddddddddddddddddddccbba +abccdddddddddddddddddddddddddddddddcbbba +abbcccddddccccddddddddddddcccbbbdddcbbba +abbbbcccccccccddddcccccccccccbbbbbcbbbba +abbbbbbbcccccccccccbbbbbccbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +"} \ No newline at end of file diff --git a/maps/submaps/surface_submaps/mountains/Cavelake.dmm b/maps/submaps/surface_submaps/mountains/Cavelake.dmm index d52795fa56..e44e5185f8 100644 --- a/maps/submaps/surface_submaps/mountains/Cavelake.dmm +++ b/maps/submaps/surface_submaps/mountains/Cavelake.dmm @@ -1,1736 +1,58 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"a" = ( -/turf/template_noop, -/area/template_noop) -"b" = ( -/turf/template_noop, -/area/submap/Cavelake) -"c" = ( -/turf/simulated/mineral/ignore_mapgen, -/area/submap/Cavelake) -"d" = ( -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/Cavelake) -"e" = ( -/obj/effect/decal/cleanable/cobweb2, -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/Cavelake) -"f" = ( -/turf/simulated/floor/outdoors/rocks, -/area/submap/Cavelake) -"g" = ( -/mob/living/simple_animal/giant_crab, -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/Cavelake) -"h" = ( -/turf/simulated/floor/water, -/area/submap/Cavelake) -"i" = ( -/mob/living/simple_animal/fish/perch, -/turf/simulated/floor/water, -/area/submap/Cavelake) -"j" = ( -/obj/machinery/crystal, -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/Cavelake) -"k" = ( -/mob/living/simple_animal/fish/trout, -/turf/simulated/floor/water, -/area/submap/Cavelake) -"l" = ( -/obj/effect/decal/cleanable/cobweb, -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/Cavelake) -"m" = ( -/obj/effect/decal/remains/mouse, -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/Cavelake) -"r" = ( -/obj/random/mob/sif, -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/Cavelake) -"B" = ( -/obj/item/clothing/mask/snorkel, -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/Cavelake) +"a" = (/turf/template_noop,/area/template_noop) +"b" = (/turf/template_noop,/area/submap/Cavelake) +"c" = (/turf/simulated/mineral/ignore_mapgen,/area/submap/Cavelake) +"d" = (/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/Cavelake) +"e" = (/obj/effect/decal/cleanable/cobweb2,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/Cavelake) +"f" = (/turf/simulated/floor/outdoors/rocks,/area/submap/Cavelake) +"g" = (/mob/living/simple_mob/animal/sif/hooligan_crab,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/Cavelake) +"h" = (/turf/simulated/floor/water,/area/submap/Cavelake) +"i" = (/mob/living/simple_mob/animal/passive/fish/perch,/turf/simulated/floor/water,/area/submap/Cavelake) +"j" = (/obj/machinery/crystal,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/Cavelake) +"k" = (/mob/living/simple_mob/animal/passive/fish/trout,/turf/simulated/floor/water,/area/submap/Cavelake) +"l" = (/obj/effect/decal/cleanable/cobweb,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/Cavelake) +"m" = (/obj/random/mob/sif,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/Cavelake) +"n" = (/obj/item/clothing/mask/snorkel,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/Cavelake) +"o" = (/obj/effect/decal/remains/mouse,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/Cavelake) (1,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(2,1,1) = {" -a -b -b -b -b -b -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -b -b -b -b -b -b -a -"} -(3,1,1) = {" -a -b -b -b -c -c -c -c -c -c -c -c -d -d -d -d -d -c -c -c -c -d -d -d -f -f -d -d -d -d -d -d -c -c -b -b -b -b -b -a -"} -(4,1,1) = {" -a -b -b -c -c -c -c -c -c -c -d -d -d -d -d -d -d -d -d -d -d -d -d -f -h -f -f -d -d -d -d -d -d -c -c -b -b -b -b -a -"} -(5,1,1) = {" -a -b -c -c -c -c -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -f -h -h -f -f -d -g -d -d -d -d -c -b -b -b -b -a -"} -(6,1,1) = {" -a -c -c -c -d -d -d -d -d -d -d -d -d -d -c -c -j -d -d -d -d -d -d -f -h -h -h -f -f -d -m -d -d -d -c -c -b -b -b -a -"} -(7,1,1) = {" -a -c -c -d -d -d -d -d -d -d -d -d -d -c -c -c -c -d -d -d -d -d -f -f -h -h -h -h -f -d -d -d -d -d -d -c -b -b -b -a -"} -(8,1,1) = {" -a -b -d -d -d -d -d -d -d -d -d -d -d -c -c -c -c -c -d -d -d -d -f -h -h -h -h -h -f -d -d -d -d -d -d -c -b -b -b -a -"} -(9,1,1) = {" -a -b -d -d -d -d -d -d -d -d -d -d -d -c -c -c -c -c -d -d -d -d -f -h -k -h -h -h -h -f -d -d -d -d -d -c -c -b -b -a -"} -(10,1,1) = {" -a -b -d -d -d -d -d -d -d -d -d -d -d -j -c -c -c -l -d -d -d -d -f -h -h -h -h -h -h -f -d -d -d -d -d -c -c -b -b -a -"} -(11,1,1) = {" -a -b -d -d -d -d -d -d -d -d -d -d -d -d -d -c -c -r -d -d -d -B -f -h -h -h -h -h -h -f -d -d -d -d -c -c -c -b -b -a -"} -(12,1,1) = {" -a -b -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -f -h -h -h -h -k -h -f -f -d -d -d -c -c -c -b -b -a -"} -(13,1,1) = {" -a -b -c -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -f -h -h -h -h -h -h -h -f -d -d -d -c -c -c -b -b -a -"} -(14,1,1) = {" -a -c -c -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -f -h -h -h -h -h -h -h -f -d -d -d -c -c -c -b -b -a -"} -(15,1,1) = {" -a -c -c -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -f -h -h -i -h -h -h -h -f -d -d -d -d -d -c -b -b -a -"} -(16,1,1) = {" -a -c -c -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -f -h -h -h -h -h -h -h -f -d -d -d -d -d -c -b -b -a -"} -(17,1,1) = {" -a -c -c -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -f -f -h -h -h -h -h -h -f -d -d -d -d -d -c -b -b -a -"} -(18,1,1) = {" -a -c -c -d -d -d -d -d -g -d -d -d -d -d -d -d -d -d -d -d -d -d -f -f -f -f -f -f -h -h -f -d -d -d -d -d -c -b -b -a -"} -(19,1,1) = {" -a -c -c -d -d -d -d -d -d -d -f -f -f -f -d -d -d -d -d -d -d -d -d -d -d -d -d -f -f -h -f -d -d -d -d -c -c -b -b -a -"} -(20,1,1) = {" -a -c -c -d -d -d -d -d -f -f -h -h -f -f -f -f -f -d -d -d -d -d -d -d -d -d -d -d -f -f -f -d -d -d -d -c -b -b -b -a -"} -(21,1,1) = {" -a -b -b -b -d -d -d -d -f -h -h -h -h -h -f -f -f -f -f -f -f -d -d -d -d -d -d -d -d -d -d -d -d -d -d -c -b -b -b -a -"} -(22,1,1) = {" -a -b -b -b -d -d -d -f -f -h -h -h -h -h -h -h -h -h -h -h -f -f -f -f -f -f -d -d -d -d -d -d -d -d -d -c -b -b -b -a -"} -(23,1,1) = {" -a -b -b -b -d -d -d -f -h -h -h -h -h -h -h -h -h -h -h -h -h -h -f -h -h -h -f -f -d -d -d -d -d -d -d -c -b -b -b -a -"} -(24,1,1) = {" -a -b -b -b -d -d -d -f -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -f -d -d -d -d -d -d -c -b -b -b -a -"} -(25,1,1) = {" -a -b -b -b -d -d -d -f -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -f -d -d -d -d -d -d -c -c -b -b -a -"} -(26,1,1) = {" -a -b -c -b -d -d -d -f -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -f -f -d -d -d -d -d -c -c -b -b -a -"} -(27,1,1) = {" -a -b -c -b -d -d -d -f -h -h -h -h -i -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -f -f -d -d -d -d -c -c -b -b -b -a -"} -(28,1,1) = {" -a -b -c -c -d -d -d -f -h -h -h -h -h -h -h -h -h -h -h -h -h -i -h -h -h -h -h -h -f -d -d -d -d -d -c -c -b -b -b -a -"} -(29,1,1) = {" -a -b -c -c -d -d -d -f -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -f -d -d -d -d -d -c -c -b -b -b -a -"} -(30,1,1) = {" -a -b -c -c -d -d -d -f -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -f -d -d -d -d -d -b -b -b -b -b -a -"} -(31,1,1) = {" -a -b -c -c -d -d -d -f -f -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -f -f -d -d -d -d -d -b -b -b -b -b -a -"} -(32,1,1) = {" -a -b -c -c -d -d -d -d -f -f -f -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -h -f -d -d -d -d -d -d -b -b -b -b -b -a -"} -(33,1,1) = {" -a -b -c -c -d -d -d -d -d -d -f -f -h -h -h -h -h -h -h -h -h -h -h -h -h -f -f -f -d -d -d -d -d -d -d -b -b -b -b -a -"} -(34,1,1) = {" -a -b -c -c -d -d -d -d -d -d -d -f -f -h -h -h -h -h -h -h -h -h -h -h -h -f -d -d -d -d -d -d -d -d -d -b -b -b -b -a -"} -(35,1,1) = {" -a -b -c -c -e -d -d -d -d -d -d -f -f -h -h -h -h -h -h -h -h -h -h -h -f -f -d -d -d -d -d -d -d -d -d -c -b -b -b -a -"} -(36,1,1) = {" -a -b -c -c -c -c -d -d -d -d -d -f -f -h -h -h -h -h -h -h -h -h -h -h -f -d -d -d -c -c -c -c -c -c -c -b -b -b -b -a -"} -(37,1,1) = {" -a -b -b -c -c -c -c -c -c -c -c -c -f -h -h -h -k -h -h -h -h -h -h -f -c -c -c -c -c -c -c -c -c -b -b -b -b -b -b -a -"} -(38,1,1) = {" -a -b -b -b -b -b -b -b -b -b -c -c -f -f -f -f -f -f -f -f -f -f -f -f -c -c -b -c -c -c -c -b -b -b -b -b -b -b -b -a -"} -(39,1,1) = {" -a -b -b -b -b -b -b -b -b -b -b -c -c -c -c -c -c -c -c -c -c -c -c -c -c -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -"} -(40,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +abbbbccbbbbbbcccccccbbbbbbbbbbbbbbbbbbba +abbbcccdddddccccccccbbbbbcccccccccccbbba +abbcccddddddddddddddbbbbbbbccccccccccbba +abcccdddddddddddddddddddddddddddddeccbba +abcccddddddddddddddddddddddddddddddccbba +acccddddddddddddddddddddddddddddddddcbba +acccdddddddddddddddddffffffffffdddddcbba +acccdddddddddddddgdfffhhhhhhhhffddddcbba +acccdddddddddddddddfhhhhhhhhhhhfddddcbba +accdddddddddddddddfhhhhhhhhhhhhffdddccba +accdddddddddddddddfhhhhhhhhhhhhhffffccca +acddddddddddddddddffhhhhhhihhhhhhfffffca +acddddcccjddddddddffhhhhhhhhhhhhhhhhhfca +acdddcccccdddddddddffhhhhhhhhhhhhhhhhfca +acdddccccccddddddddffhhhhhhhhhhhhhhhhfca +acdddjcccccddddddddffhhhhhhhhhhhhhhhkfca +accddddcclmdddddddddfhhhhhhhhhhhhhhhhfca +accdddddddddddddddddfhhhhhhhhhhhhhhhhfca +accdddddddddddddddddfhhhhhhhhhhhhhhhhfca +accdddddddddddddddddffhhhhhhhhhhhhhhhfca +acddddddddnddddddddddfhhhhhihhhhhhhhhfca +acddddffffffffffffdddffhhhhhhhhhhhhhhfca +acdffffhhhhhhhhhffdddfhhhhhhhhhhhhhhffca +acfhhhhhkhhhhhhhhfdddfhhhhhhhhhhhhffccca +acffhhhhhhhhhhihhfdddfhhhhhhhhhhfffdccba +acdffhhhhhhhhhhhhfddddfhhhhhhhhhfdddcbba +acddffhhhhhkhhhhhffdddfhhhhhhhfffdddccba +acdddfffhhhhhhhhhhffdddffffffffddddcccba +acddgdddffffhhhhhhhfdddddffddddddddcccba +acdddodddddfffffffffdddddddddddddddcccba +acdddddddddddddddddddddddddddddddddccbba +accddddddddddddddddddddddddddddddddccbba +abccdddddddddddddddddddddddddddddddcbbba +abbcccddddccccddddddddddddcccbbbdddcbbba +abbbbcccccccccddddcccccccccccbbbbbcbbbba +abbbbbbbcccccccccccbbbbbccbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +"} \ No newline at end of file diff --git a/maps/submaps/surface_submaps/mountains/CrashedMedShuttle1.dmm b/maps/submaps/surface_submaps/mountains/CrashedMedShuttle1.dmm index fad7093123..74d5e563a4 100644 --- a/maps/submaps/surface_submaps/mountains/CrashedMedShuttle1.dmm +++ b/maps/submaps/surface_submaps/mountains/CrashedMedShuttle1.dmm @@ -14,7 +14,7 @@ "an" = (/obj/structure/window/reinforced,/obj/effect/decal/cleanable/blood/oil,/obj/structure/loot_pile/surface/bones,/obj/structure/lattice,/turf/simulated/floor/outdoors/rocks,/area/submap/CrashedMedShuttle) "ao" = (/obj/item/weapon/circuitboard/broken,/obj/structure/door_assembly/door_assembly_ext,/turf/simulated/shuttle/plating,/area/submap/CrashedMedShuttle) "ap" = (/obj/structure/door_assembly/door_assembly_ext,/turf/simulated/shuttle/plating,/area/submap/CrashedMedShuttle) -"aq" = (/obj/effect/decal/cleanable/liquid_fuel,/mob/living/simple_animal/hostile/giant_spider/webslinger{returns_home = 1},/turf/simulated/shuttle/floor/white,/area/submap/CrashedMedShuttle) +"aq" = (/obj/effect/decal/cleanable/liquid_fuel,/mob/living/simple_mob/animal/giant_spider/webslinger,/turf/simulated/shuttle/floor/white,/area/submap/CrashedMedShuttle) "ar" = (/obj/structure/closet/crate/medical,/obj/random/medical,/obj/random/medical,/turf/simulated/shuttle/floor/white,/area/submap/CrashedMedShuttle) "as" = (/obj/structure/table/standard,/obj/machinery/cell_charger,/turf/simulated/shuttle/floor/white,/area/submap/CrashedMedShuttle) "at" = (/obj/item/weapon/material/shard,/obj/structure/lattice,/turf/simulated/floor/outdoors/rocks,/area/submap/CrashedMedShuttle) @@ -23,7 +23,7 @@ "aw" = (/obj/machinery/door/airlock/glass,/turf/simulated/shuttle/floor/white,/area/submap/CrashedMedShuttle) "ax" = (/obj/effect/decal/cleanable/blood/drip,/obj/effect/decal/cleanable/liquid_fuel,/turf/simulated/shuttle/floor/white,/area/submap/CrashedMedShuttle) "ay" = (/obj/effect/decal/cleanable/blood,/obj/effect/decal/cleanable/liquid_fuel,/turf/simulated/shuttle/floor/white,/area/submap/CrashedMedShuttle) -"az" = (/obj/effect/decal/cleanable/blood/gibs/robot,/obj/item/weapon/firstaid_arm_assembly,/mob/living/simple_animal/hostile/giant_spider/frost{returns_home = 1},/turf/simulated/shuttle/floor/white,/area/submap/CrashedMedShuttle) +"az" = (/obj/effect/decal/cleanable/blood/gibs/robot,/obj/item/weapon/firstaid_arm_assembly,/mob/living/simple_mob/animal/giant_spider/frost,/turf/simulated/shuttle/floor/white,/area/submap/CrashedMedShuttle) "aA" = (/obj/item/stack/rods,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/CrashedMedShuttle) "aB" = (/obj/structure/lattice,/obj/item/stack/rods,/turf/simulated/floor/outdoors/rocks,/area/submap/CrashedMedShuttle) "aC" = (/obj/effect/decal/cleanable/blood/oil,/obj/item/weapon/firstaid_arm_assembly,/turf/simulated/shuttle/floor/white,/area/submap/CrashedMedShuttle) @@ -38,7 +38,7 @@ "aL" = (/obj/structure/grille/broken,/obj/item/weapon/material/shard{icon_state = "medium"},/obj/item/stack/rods,/turf/simulated/shuttle/plating,/area/submap/CrashedMedShuttle) "aM" = (/obj/item/weapon/material/shard,/turf/simulated/floor/outdoors/rocks,/area/submap/CrashedMedShuttle) "aN" = (/obj/effect/decal/cleanable/blood/oil,/turf/simulated/floor/outdoors/rocks,/area/submap/CrashedMedShuttle) -"aO" = (/obj/item/weapon/material/shard{icon_state = "medium"},/obj/effect/spider/stickyweb,/mob/living/simple_animal/hostile/giant_spider/carrier,/turf/simulated/shuttle/floor/white,/area/submap/CrashedMedShuttle) +"aO" = (/obj/item/weapon/material/shard{icon_state = "medium"},/obj/effect/spider/stickyweb,/mob/living/simple_mob/animal/giant_spider/carrier,/turf/simulated/shuttle/floor/white,/area/submap/CrashedMedShuttle) "aP" = (/obj/effect/decal/cleanable/blood/gibs/robot,/turf/simulated/shuttle/floor/white,/area/submap/CrashedMedShuttle) "aQ" = (/obj/effect/spider/stickyweb,/turf/simulated/shuttle/floor/white,/area/submap/CrashedMedShuttle) "aR" = (/turf/simulated/shuttle/wall/no_join,/area/submap/CrashedMedShuttle) @@ -63,12 +63,12 @@ "bk" = (/obj/effect/decal/cleanable/blood/oil,/obj/structure/lattice,/turf/simulated/floor/outdoors/rocks,/area/submap/CrashedMedShuttle) "bl" = (/obj/effect/spider/stickyweb,/obj/item/weapon/material/shard,/turf/simulated/shuttle/floor/white,/area/submap/CrashedMedShuttle) "bm" = (/obj/random/medical,/turf/simulated/shuttle/floor/white,/area/submap/CrashedMedShuttle) -"bn" = (/mob/living/simple_animal/hostile/giant_spider/webslinger{returns_home = 1},/turf/simulated/floor/outdoors/rocks,/area/submap/CrashedMedShuttle) +"bn" = (/mob/living/simple_mob/animal/giant_spider/webslinger,/turf/simulated/floor/outdoors/rocks,/area/submap/CrashedMedShuttle) "bo" = (/obj/effect/spider/cocoon,/obj/structure/lattice,/turf/simulated/floor/outdoors/rocks,/area/submap/CrashedMedShuttle) "bp" = (/obj/structure{anchored = 1; density = 1; desc = "Once an artificial intelligence; now merely a brick of inert metal and circuits."; icon = 'icons/mob/AI.dmi'; icon_state = "ai-empty"; name = "V.I.T.A"},/turf/simulated/shuttle/floor/yellow,/area/submap/CrashedMedShuttle) "bq" = (/obj/structure/flora/tree/sif,/turf/simulated/floor/outdoors/rocks,/area/submap/CrashedMedShuttle) "br" = (/obj/structure/grille/broken,/obj/item/weapon/material/shard,/turf/simulated/floor/outdoors/rocks,/area/submap/CrashedMedShuttle) -"bs" = (/obj/effect/decal/cleanable/blood/drip,/obj/effect/spider/stickyweb,/mob/living/simple_animal/hostile/giant_spider/webslinger,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/CrashedMedShuttle) +"bs" = (/obj/effect/decal/cleanable/blood/drip,/obj/effect/spider/stickyweb,/mob/living/simple_mob/animal/giant_spider/webslinger,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/CrashedMedShuttle) "bt" = (/obj/effect/decal/cleanable/blood/drip,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/CrashedMedShuttle) "bu" = (/obj/effect/decal/remains/tajaran,/obj/item/weapon/surgical/circular_saw,/turf/simulated/floor/outdoors/rocks,/area/submap/CrashedMedShuttle) "bv" = (/obj/effect/decal/cleanable/blood/oil,/obj/effect/spider/stickyweb,/turf/simulated/floor/outdoors/rocks,/area/submap/CrashedMedShuttle) @@ -81,7 +81,7 @@ "bC" = (/obj/structure/shuttle/engine/heater{icon_state = "heater"; dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/CrashedMedShuttle) "bD" = (/obj/structure/table/standard,/obj/item/weapon/storage/firstaid/adv,/turf/simulated/shuttle/floor/purple,/area/submap/CrashedMedShuttle) "bE" = (/obj/structure/table/standard,/turf/simulated/shuttle/floor/purple,/area/submap/CrashedMedShuttle) -"bF" = (/obj/random/medical/pillbottle,/mob/living/simple_animal/hostile/giant_spider/webslinger{returns_home = 1},/turf/simulated/shuttle/floor/white,/area/submap/CrashedMedShuttle) +"bF" = (/obj/random/medical/pillbottle,/mob/living/simple_mob/animal/giant_spider/webslinger,/turf/simulated/shuttle/floor/white,/area/submap/CrashedMedShuttle) "bG" = (/obj/structure/table/standard,/obj/item/device/defib_kit/loaded,/turf/simulated/shuttle/floor/white,/area/submap/CrashedMedShuttle) "bH" = (/obj/structure/table/standard,/obj/item/bodybag/cryobag,/turf/simulated/shuttle/floor/white,/area/submap/CrashedMedShuttle) "bI" = (/obj/structure/table/standard,/obj/item/weapon/storage/box/bodybags,/turf/simulated/shuttle/floor/white,/area/submap/CrashedMedShuttle) @@ -97,7 +97,7 @@ "bS" = (/obj/item/weapon/material/shard{icon_state = "medium"},/obj/structure/grille,/turf/simulated/shuttle/plating,/area/submap/CrashedMedShuttle) "bT" = (/obj/structure/table/standard,/obj/item/device/reagent_scanner/adv,/turf/simulated/shuttle/floor/purple,/area/submap/CrashedMedShuttle) "bU" = (/obj/machinery/iv_drip,/obj/item/weapon/reagent_containers/blood/empty,/turf/simulated/shuttle/floor/white,/area/submap/CrashedMedShuttle) -"bV" = (/mob/living/simple_animal/hostile/giant_spider/carrier,/turf/simulated/shuttle/floor/white,/area/submap/CrashedMedShuttle) +"bV" = (/mob/living/simple_mob/animal/giant_spider/carrier,/turf/simulated/shuttle/floor/white,/area/submap/CrashedMedShuttle) "bW" = (/obj/structure/table/standard,/obj/item/weapon/storage/box/masks,/turf/simulated/shuttle/floor/white,/area/submap/CrashedMedShuttle) "bX" = (/obj/structure/table/standard,/obj/random/firstaid,/turf/simulated/shuttle/floor/white,/area/submap/CrashedMedShuttle) "bY" = (/obj/structure/table/standard,/obj/item/weapon/storage/backpack/medic,/obj/random/medical/lite,/turf/simulated/shuttle/floor/white,/area/submap/CrashedMedShuttle) diff --git a/maps/submaps/surface_submaps/mountains/Scave1.dmm b/maps/submaps/surface_submaps/mountains/Scave1.dmm index 464ab34789..e4c7de5fd0 100644 --- a/maps/submaps/surface_submaps/mountains/Scave1.dmm +++ b/maps/submaps/surface_submaps/mountains/Scave1.dmm @@ -1,942 +1,47 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"a" = ( -/turf/template_noop, -/area/template_noop) -"b" = ( -/turf/simulated/mineral/ignore_mapgen, -/area/submap/cave/Scave1) -"c" = ( -/obj/effect/spider/stickyweb, -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/cave/Scave1) -"d" = ( -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/cave/Scave1) -"e" = ( -/obj/effect/spider/spiderling/frost, -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/cave/Scave1) -"f" = ( -/obj/item/weapon/spacecash/c100, -/obj/item/weapon/spacecash/c100, -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/cave/Scave1) -"g" = ( -/obj/item/weapon/spacecash/c100, -/obj/item/weapon/spacecash/c100, -/obj/item/weapon/spacecash/c100, -/obj/effect/decal/remains, -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/cave/Scave1) -"h" = ( -/obj/item/weapon/grenade/spawnergrenade/spider, -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/cave/Scave1) -"i" = ( -/mob/living/simple_animal/hostile/giant_spider/frost, -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/cave/Scave1) -"j" = ( -/obj/random/toolbox, -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/cave/Scave1) -"k" = ( -/obj/effect/decal/mecha_wreckage/ripley, -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/cave/Scave1) -"l" = ( -/obj/item/mecha_parts/mecha_equipment/tool/drill/diamonddrill, -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/cave/Scave1) -"m" = ( -/obj/item/device/flashlight, -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/cave/Scave1) -"n" = ( -/obj/effect/spider/stickyweb, -/obj/effect/spider/stickyweb, -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/cave/Scave1) -"p" = ( -/obj/effect/decal/remains, -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/cave/Scave1) -"B" = ( -/obj/random/mob/spider/mutant, -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/cave/Scave1) -"O" = ( -/obj/random/mob/spider, -/turf/simulated/mineral/floor/ignore_mapgen, -/area/submap/cave/Scave1) +"a" = (/turf/template_noop,/area/template_noop) +"b" = (/turf/simulated/mineral/ignore_mapgen,/area/submap/cave/Scave1) +"c" = (/obj/effect/spider/stickyweb,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/Scave1) +"d" = (/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/Scave1) +"e" = (/obj/effect/spider/spiderling/frost,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/Scave1) +"f" = (/obj/item/weapon/spacecash/c100,/obj/item/weapon/spacecash/c100,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/Scave1) +"g" = (/obj/random/mob/spider/mutant,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/Scave1) +"h" = (/obj/item/weapon/spacecash/c100,/obj/item/weapon/spacecash/c100,/obj/item/weapon/spacecash/c100,/obj/effect/decal/remains,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/Scave1) +"i" = (/obj/random/mob/spider,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/Scave1) +"j" = (/obj/item/weapon/grenade/spawnergrenade/spider,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/Scave1) +"k" = (/obj/random/toolbox,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/Scave1) +"l" = (/obj/effect/decal/mecha_wreckage/ripley,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/Scave1) +"m" = (/obj/item/mecha_parts/mecha_equipment/tool/drill/diamonddrill,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/Scave1) +"n" = (/obj/item/device/flashlight,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/Scave1) +"o" = (/mob/living/simple_mob/animal/giant_spider/frost,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/Scave1) +"p" = (/obj/effect/spider/stickyweb,/obj/effect/spider/stickyweb,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/Scave1) +"q" = (/obj/effect/decal/remains,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/Scave1) (1,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(2,1,1) = {" -a -a -a -b -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(3,1,1) = {" -a -a -b -b -b -b -d -d -b -b -b -b -b -b -b -b -d -m -d -d -d -p -b -b -b -a -a -"} -(4,1,1) = {" -a -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -d -d -d -d -d -b -b -b -a -a -"} -(5,1,1) = {" -a -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -d -n -b -b -b -b -a -a -"} -(6,1,1) = {" -a -b -b -b -b -b -f -g -b -b -b -b -b -b -b -b -b -b -b -n -n -b -b -b -b -b -a -"} -(7,1,1) = {" -a -b -b -b -b -d -d -f -b -b -b -b -b -b -b -b -b -b -b -d -c -b -b -b -b -b -a -"} -(8,1,1) = {" -a -a -b -b -b -e -d -b -b -b -c -c -b -b -b -b -b -b -b -d -d -b -b -b -b -b -a -"} -(9,1,1) = {" -a -a -a -b -c -d -d -b -b -d -d -d -B -d -d -d -d -d -d -e -d -b -b -b -b -b -a -"} -(10,1,1) = {" -a -a -a -b -b -d -d -O -d -d -d -d -d -d -c -d -d -d -d -d -d -d -b -b -b -a -a -"} -(11,1,1) = {" -a -a -b -b -b -b -c -d -d -d -d -c -c -d -d -d -d -b -d -d -B -d -c -b -b -b -a -"} -(12,1,1) = {" -a -a -b -b -b -b -b -d -c -b -b -b -b -b -b -b -b -b -b -d -d -d -d -b -b -b -a -"} -(13,1,1) = {" -a -a -b -b -b -b -b -d -d -b -b -b -b -b -b -b -b -b -b -b -d -d -d -b -b -b -a -"} -(14,1,1) = {" -a -a -b -b -b -c -d -d -d -b -b -b -b -b -b -b -b -b -b -b -c -d -d -b -b -b -a -"} -(15,1,1) = {" -a -a -b -b -b -c -e -d -d -j -b -b -b -b -b -b -b -b -b -b -b -d -c -b -b -b -a -"} -(16,1,1) = {" -a -a -a -b -b -c -d -d -d -c -b -b -b -b -b -b -b -b -b -b -c -d -d -b -b -b -a -"} -(17,1,1) = {" -a -a -a -b -b -b -b -b -d -d -b -b -b -b -b -b -b -b -b -b -d -d -d -b -b -b -a -"} -(18,1,1) = {" -a -a -a -b -b -b -b -c -d -d -c -b -b -k -l -c -b -b -b -b -d -d -d -B -b -a -a -"} -(19,1,1) = {" -a -a -a -b -b -b -b -c -d -d -d -d -d -d -d -d -c -b -b -b -d -d -d -b -b -a -a -"} -(20,1,1) = {" -a -a -a -b -b -b -b -e -d -d -d -O -d -d -d -d -c -i -b -b -d -d -d -b -b -b -a -"} -(21,1,1) = {" -a -a -a -b -b -b -b -d -d -d -d -d -d -d -B -d -d -c -b -d -d -c -c -b -b -b -a -"} -(22,1,1) = {" -a -a -a -b -b -d -d -d -d -d -d -d -d -d -d -d -d -d -d -e -c -b -b -b -b -b -a -"} -(23,1,1) = {" -a -a -b -b -b -d -B -d -d -b -c -c -c -c -c -c -d -d -d -d -b -b -b -b -b -b -a -"} -(24,1,1) = {" -a -a -b -b -b -d -d -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -"} -(25,1,1) = {" -a -a -b -b -d -e -d -d -h -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -"} -(26,1,1) = {" -a -a -b -b -b -d -d -e -B -b -b -b -b -b -b -b -b -b -d -d -d -d -b -b -b -a -a -"} -(27,1,1) = {" -a -a -b -b -b -d -d -d -b -b -b -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(28,1,1) = {" -a -a -a -a -b -b -b -b -b -b -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(29,1,1) = {" -a -a -a -a -a -a -a -b -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(30,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaabbaaaaaaaaaaaaaaaaaaaaaaa +aabbbbbbaabbbbbaaaaaaabbbbbaaa +abbbbbbbbbbbbbbbbbbbbbbbbbbaaa +aabbbbbbcbbbbbbbbbbbbbbbdbbbaa +aabbbbdeddbbbcccbbbbbdddeddbaa +aadbbfddddcbbdedbbbbbdgddddbaa +aadbbhfbbiddddddbccedddbdedbba +aabbbbbbbddcdddddddddddbjgbbaa +aabbbbbbdddbbbkcddddddbbbbbbaa +aabbbbbcdddbbbbbbcddddcbbbbaaa +aabbbbbcddcbbbbbbbdiddcbbbaaaa +aabbbbbbgdcbbbbbbbddddcbbbaaaa +aabbbbbbdddbbbbbblddddcbbbaaaa +aabbbbbbdcdbbbbbbmddgdcbbbaaaa +aabbbbbbdddbbbbbbcddddcbbbaaaa +aadbbbbbdddbbbbbbbccdddbbbaaaa +aandbbbbddbbbbbbbbbocddbbbaaaa +aaddbbbbdddbbbbbbbbbbddbbdaaaa +aadddpddedddbbbbbbbbdedbbdaaaa +aaddppcdddgddcbcdddddcbbbdaaaa +aaqdbbbbbdddddddddddcbbbbdaaaa +aabbbbbbbbcdddcdddddcbbbbbaaaa +aabbbbbbbbbbbbbbbgbbbbbbbbaaaa +aabbbbbbbbbbbbbbbbbbbbbbbbaaaa +aaaaabbbbabbbbbbbaabbbbbbaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +"} \ No newline at end of file diff --git a/maps/submaps/surface_submaps/mountains/SwordCave.dmm b/maps/submaps/surface_submaps/mountains/SwordCave.dmm index 8c15e58da8..385c61a540 100644 --- a/maps/submaps/surface_submaps/mountains/SwordCave.dmm +++ b/maps/submaps/surface_submaps/mountains/SwordCave.dmm @@ -1,55 +1,55 @@ -"a" = (/turf/template_noop,/area/template_noop) -"b" = (/turf/simulated/mineral,/area/submap/cave/swordcave) -"c" = (/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/swordcave) -"d" = (/obj/machinery/crystal,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/swordcave) -"e" = (/turf/simulated/floor/water,/area/submap/cave/swordcave) -"f" = (/turf/simulated/floor/water/deep,/area/submap/cave/swordcave) -"g" = (/obj/structure/ghost_pod/manual/cursedblade,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/swordcave) -"h" = (/mob/living/simple_animal/hostile/faithless/cult,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/swordcave) -"i" = (/obj/item/device/gps/explorer,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/swordcave) -"j" = (/obj/structure/loot_pile/surface/bones,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/swordcave) -"k" = (/mob/living/simple_animal/hostile/scarybat/cult,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/swordcave) - -(1,1,1) = {" -aaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbaaaaaa -aaaaabbbbbbbbbbbcccdccccbbbbbbbbbbbbaaaaa -aaaabbbbbbcccccccccccccccccccccbbbbbbaaaa -aaabbbbbbcccccccccccccccccccccccdbbbbbaaa -aabbbbccccccceeeeeeeeeeeeeccccccccbbbbbaa -aabbbccccccceeeeeeeeeeeeeeeccccccccbbbbaa -aabbbcdcccceeeffffffffffffeeeccccccbbbbaa -aabbbccccceefeeeeeeefeeeeeeeeecccccbbbbaa -aabbbccccceefeeccceeeeeeeefffeeccccbbbaaa -aabbbcccceeffeecccccecccceefffeecccbbbaaa -aabbbcccceeffeeeccgcccchcceeffeecccbbbaaa -aabbbcccdeeffeeccijcdccccceefeeccdcbbbaaa -abbbccccceefffeeeccccccceeefeeccccccbbaaa -abbbcccccceefffeeeccccceeeffeeccccccbbbaa -abbbcdccccceefffeeeeeeeeffffeeccccccbbbaa -abbcccckcccceeffffeeeeefffffeeccccccbbbaa -abbcccccccccceeffffffffffffeeccccdccbbbaa -abbccccccccccceeffeeeeeefffeecccccccbbbaa -abbbccccdcccccceefeeeeeeeeeeckccccccbbbaa -abbbcccccccccccceeecccdceeecccccccccbbaaa -abbbcccccccccccccecccccccceccccdckccbbaaa -abbbcccccccccckcccccccccccccccccccccbbaaa -abbbbcccccckccccccccccccccckccccccccbbaaa -abbbbbcccccccccccccccckccccccccckcccbbaaa -aabbbbbccccccccccccccccccccccccccccbbbaaa -aabbbbbccccccccccccdccccccccccccccbbbbaaa -aabbbbbcccccdccccccccccccccccccccbbbbbaaa -aabbbbbccccccccccckccccccccdcccccbbbbaaaa -aabbbbbbbccccccccccccccccccccccccbbbbaaaa -aaabbbbbbbcccccccccccccccdccccccbbbbaaaaa -aaaabbbbbbcckcccccdcccccccccccccbbbbaaaaa -aaaaabbbbbcccccccccccccccccccccbbbbbaaaaa -aaaaabbbbbccccccccccccccccccccbbbbbaaaaaa -aaaaaabbbbbcccdccccccccccccccbbbbbaaaaaaa -aaaaaaabbbbbcccccccckccccckcbbbbbbaaaaaaa -aaaaaaabbbbbbcccccccccccccccbbbbbaaaaaaaa -aaaaaaabbbbbbbbbbbbccccccccccbbbaaaaaaaaa -aaaaaaaaabbbbbbbbbbbccccccccccbaaaaaaaaaa -aaaaaaaaaaabbbbbbbbbbccccccccccaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaacccdccccaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaccccccaaaaaaaaaaaa -"} +"a" = (/turf/template_noop,/area/template_noop) +"b" = (/turf/simulated/mineral,/area/submap/cave/swordcave) +"c" = (/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/swordcave) +"d" = (/obj/machinery/crystal,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/swordcave) +"e" = (/turf/simulated/floor/water,/area/submap/cave/swordcave) +"f" = (/turf/simulated/floor/water/deep,/area/submap/cave/swordcave) +"g" = (/obj/structure/ghost_pod/manual/cursedblade,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/swordcave) +"h" = (/mob/living/simple_mob/faithless/cult,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/swordcave) +"i" = (/obj/item/device/gps/explorer,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/swordcave) +"j" = (/obj/structure/loot_pile/surface/bones,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/swordcave) +"k" = (/mob/living/simple_mob/animal/space/bats,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/swordcave) + +(1,1,1) = {" +aaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbaaaaaa +aaaaabbbbbbbbbbbcccdccccbbbbbbbbbbbbaaaaa +aaaabbbbbbcccccccccccccccccccccbbbbbbaaaa +aaabbbbbbcccccccccccccccccccccccdbbbbbaaa +aabbbbccccccceeeeeeeeeeeeeccccccccbbbbbaa +aabbbccccccceeeeeeeeeeeeeeeccccccccbbbbaa +aabbbcdcccceeeffffffffffffeeeccccccbbbbaa +aabbbccccceefeeeeeeefeeeeeeeeecccccbbbbaa +aabbbccccceefeeccceeeeeeeefffeeccccbbbaaa +aabbbcccceeffeecccccecccceefffeecccbbbaaa +aabbbcccceeffeeeccgcccchcceeffeecccbbbaaa +aabbbcccdeeffeeccijcdccccceefeeccdcbbbaaa +abbbccccceefffeeeccccccceeefeeccccccbbaaa +abbbcccccceefffeeeccccceeeffeeccccccbbbaa +abbbcdccccceefffeeeeeeeeffffeeccccccbbbaa +abbcccckcccceeffffeeeeefffffeeccccccbbbaa +abbcccccccccceeffffffffffffeeccccdccbbbaa +abbccccccccccceeffeeeeeefffeecccccccbbbaa +abbbccccdcccccceefeeeeeeeeeeckccccccbbbaa +abbbcccccccccccceeecccdceeecccccccccbbaaa +abbbcccccccccccccecccccccceccccdckccbbaaa +abbbcccccccccckcccccccccccccccccccccbbaaa +abbbbcccccckccccccccccccccckccccccccbbaaa +abbbbbcccccccccccccccckccccccccckcccbbaaa +aabbbbbccccccccccccccccccccccccccccbbbaaa +aabbbbbccccccccccccdccccccccccccccbbbbaaa +aabbbbbcccccdccccccccccccccccccccbbbbbaaa +aabbbbbccccccccccckccccccccdcccccbbbbaaaa +aabbbbbbbccccccccccccccccccccccccbbbbaaaa +aaabbbbbbbcccccccccccccccdccccccbbbbaaaaa +aaaabbbbbbcckcccccdcccccccccccccbbbbaaaaa +aaaaabbbbbcccccccccccccccccccccbbbbbaaaaa +aaaaabbbbbccccccccccccccccccccbbbbbaaaaaa +aaaaaabbbbbcccdccccccccccccccbbbbbaaaaaaa +aaaaaaabbbbbcccccccckccccckcbbbbbbaaaaaaa +aaaaaaabbbbbbcccccccccccccccbbbbbaaaaaaaa +aaaaaaabbbbbbbbbbbbccccccccccbbbaaaaaaaaa +aaaaaaaaabbbbbbbbbbbccccccccccbaaaaaaaaaa +aaaaaaaaaaabbbbbbbbbbccccccccccaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaacccdccccaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaccccccaaaaaaaaaaaa +"} diff --git a/maps/submaps/surface_submaps/mountains/crashedcontainmentshuttle.dmm b/maps/submaps/surface_submaps/mountains/crashedcontainmentshuttle.dmm index 79440f618f..9b19efeea7 100644 --- a/maps/submaps/surface_submaps/mountains/crashedcontainmentshuttle.dmm +++ b/maps/submaps/surface_submaps/mountains/crashedcontainmentshuttle.dmm @@ -1,121 +1,121 @@ -"aa" = (/turf/template_noop,/area/submap/crashedcontainmentshuttle) -"ab" = (/turf/simulated/shuttle/wall/dark/hard_corner,/area/submap/crashedcontainmentshuttle) -"ac" = (/turf/simulated/shuttle/wall/dark,/area/submap/crashedcontainmentshuttle) -"ad" = (/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) -"ae" = (/turf/simulated/shuttle/floor/yellow,/area/submap/crashedcontainmentshuttle) -"af" = (/turf/simulated/shuttle/floor/red,/area/submap/crashedcontainmentshuttle) -"ag" = (/turf/simulated/shuttle/floor/white,/area/submap/crashedcontainmentshuttle) -"ah" = (/obj/structure/grille,/obj/item/weapon/material/shard{icon_state = "medium"},/turf/simulated/floor/plating,/area/submap/crashedcontainmentshuttle) -"ai" = (/obj/structure/grille,/obj/item/weapon/material/shard{icon_state = "medium"},/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) -"aj" = (/obj/random/landmine,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) -"ak" = (/obj/structure/door_assembly/door_assembly_ext{anchored = 1},/turf/simulated/floor/plating,/area/submap/crashedcontainmentshuttle) -"al" = (/obj/item/weapon/material/shard{icon_state = "medium"},/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) -"am" = (/obj/item/weapon/material/shard,/turf/template_noop,/area/submap/crashedcontainmentshuttle) -"an" = (/obj/structure/girder,/turf/simulated/floor/plating,/area/submap/crashedcontainmentshuttle) -"ao" = (/turf/simulated/floor/plating,/area/submap/crashedcontainmentshuttle) -"ap" = (/obj/structure/lattice,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) -"aq" = (/obj/item/weapon/material/shard,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) -"ar" = (/obj/structure/grille,/obj/item/weapon/material/shard,/turf/simulated/floor/plating,/area/submap/crashedcontainmentshuttle) -"as" = (/obj/item/weapon/material/shard,/turf/simulated/floor/plating,/area/submap/crashedcontainmentshuttle) -"at" = (/obj/item/stack/rods,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) -"au" = (/obj/item/stack/rods,/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) -"av" = (/obj/structure/closet/walllocker/emerglocker/east,/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) -"aw" = (/obj/structure/frame,/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) -"ax" = (/obj/item/frame/mirror,/obj/item/weapon/material/shard{icon_state = "medium"},/turf/simulated/shuttle/wall/dark,/area/submap/crashedcontainmentshuttle) -"ay" = (/obj/effect/decal/mecha_wreckage/gygax{anchored = 1},/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) -"az" = (/obj/effect/gibspawner/generic,/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) -"aA" = (/obj/structure/closet/medical_wall,/turf/simulated/shuttle/wall/dark,/area/submap/crashedcontainmentshuttle) -"aB" = (/obj/structure/largecrate/animal/crashedshuttle,/turf/simulated/shuttle/floor/red,/area/submap/crashedcontainmentshuttle) -"aC" = (/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) -"aD" = (/obj/structure/door_assembly/door_assembly_ext,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) -"aE" = (/obj/structure/extinguisher_cabinet,/turf/simulated/shuttle/wall/dark,/area/submap/crashedcontainmentshuttle) -"aF" = (/obj/machinery/computer,/turf/simulated/shuttle/floor/yellow,/area/submap/crashedcontainmentshuttle) -"aG" = (/obj/structure/loot_pile/maint/technical,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) -"aH" = (/obj/structure/frame/computer,/turf/simulated/shuttle/floor/yellow,/area/submap/crashedcontainmentshuttle) -"aI" = (/obj/structure/grille{density = 0; icon_state = "brokengrille"},/obj/item/stack/rods,/turf/simulated/floor/plating,/area/submap/crashedcontainmentshuttle) -"aJ" = (/obj/item/stack/rods,/turf/simulated/floor/plating,/area/submap/crashedcontainmentshuttle) -"aK" = (/obj/structure/grille{density = 0; icon_state = "brokengrille"},/obj/item/weapon/material/shard{icon_state = "medium"},/obj/item/stack/rods,/turf/simulated/floor/plating,/area/submap/crashedcontainmentshuttle) -"aL" = (/obj/item/weapon/circuitboard/broken,/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) -"aM" = (/obj/structure/frame,/obj/item/weapon/circuitboard/broken,/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) -"aN" = (/obj/structure/table/steel_reinforced,/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) -"aO" = (/obj/structure/closet/walllocker/emerglocker/north,/obj/structure/frame,/obj/item/weapon/circuitboard/broken,/turf/simulated/shuttle/floor/white,/area/submap/crashedcontainmentshuttle) -"aP" = (/turf/simulated/floor/outdoors/rocks,/area/submap/crashedcontainmentshuttle) -"aQ" = (/obj/structure/grille{density = 0; icon_state = "brokengrille"},/obj/structure/lattice,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) -"aR" = (/obj/structure/shuttle/engine/heater{dir = 8},/obj/structure/window/reinforced{dir = 4; health = 1e+006},/turf/template_noop,/area/submap/crashedcontainmentshuttle) -"aS" = (/obj/structure/door_assembly/door_assembly_highsecurity{anchored = 1},/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) -"aT" = (/obj/structure/loot_pile/maint/technical,/turf/simulated/shuttle/floor/yellow,/area/submap/crashedcontainmentshuttle) -"aU" = (/obj/structure/loot_pile/maint/technical,/turf/simulated/shuttle/floor/white,/area/submap/crashedcontainmentshuttle) -"aV" = (/obj/structure/shuttle/engine/propulsion{dir = 8},/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) -"aW" = (/obj/structure/loot_pile/maint/technical,/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) -"aX" = (/obj/item/weapon/circuitboard/broken,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) -"aY" = (/obj/item/clothing/suit/space/cult,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) -"aZ" = (/obj/effect/decal/remains/robot,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) -"ba" = (/obj/effect/decal/remains/human,/obj/effect/gibspawner/human,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) -"bb" = (/obj/effect/decal/cleanable/blood/drip,/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) -"bc" = (/obj/structure/door_assembly,/turf/simulated/shuttle/floor/white,/area/submap/crashedcontainmentshuttle) -"bd" = (/obj/item/clothing/head/helmet/space/cult,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) -"be" = (/obj/item/weapon/material/knife/ritual,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) -"bf" = (/obj/structure/bed/chair/office/dark{dir = 8},/obj/effect/decal/remains/human,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) -"bg" = (/obj/effect/gibspawner/generic,/turf/template_noop,/area/submap/crashedcontainmentshuttle) -"bh" = (/obj/effect/decal/remains/human,/turf/simulated/shuttle/floor/yellow,/area/submap/crashedcontainmentshuttle) -"bi" = (/obj/item/weapon/circuitboard/broken,/obj/effect/decal/remains/human,/obj/item/weapon/gun/energy/laser,/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) -"bj" = (/obj/item/device/gps/internal/poi,/turf/simulated/shuttle/floor/red,/area/submap/crashedcontainmentshuttle) -"bk" = (/obj/effect/decal/cleanable/vomit,/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) -"bl" = (/obj/effect/decal/remains/robot,/turf/simulated/shuttle/floor/red,/area/submap/crashedcontainmentshuttle) -"bm" = (/obj/effect/decal/cleanable/liquid_fuel,/turf/template_noop,/area/submap/crashedcontainmentshuttle) -"bn" = (/obj/effect/decal/cleanable/vomit,/turf/simulated/shuttle/floor/white,/area/submap/crashedcontainmentshuttle) -"bo" = (/obj/effect/decal/cleanable/blood/drip,/turf/template_noop,/area/submap/crashedcontainmentshuttle) -"bp" = (/obj/structure/bed/chair/office/dark{dir = 4},/turf/simulated/shuttle/floor/yellow,/area/submap/crashedcontainmentshuttle) -"bq" = (/obj/item/weapon/circuitboard/broken,/obj/structure/bed/chair/office/dark{dir = 4},/turf/simulated/shuttle/floor/yellow,/area/submap/crashedcontainmentshuttle) -"br" = (/obj/effect/decal/cleanable/blood/drip,/obj/effect/decal/cleanable/blood/drip,/obj/effect/decal/cleanable/blood/drip,/turf/simulated/shuttle/floor/yellow,/area/submap/crashedcontainmentshuttle) -"bs" = (/obj/structure/table/steel_reinforced,/turf/simulated/shuttle/floor/yellow,/area/submap/crashedcontainmentshuttle) -"bt" = (/obj/structure/shuttle/engine/heater{dir = 8},/obj/structure/window/reinforced{dir = 4; health = 1e+006},/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) -"bu" = (/obj/structure/door_assembly/door_assembly_ext{anchored = 1},/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) -"bv" = (/obj/effect/decal/cleanable/blood/oil,/turf/simulated/shuttle/floor/red,/area/submap/crashedcontainmentshuttle) -"bw" = (/obj/item/weapon/material/knife/ritual,/obj/effect/decal/cleanable/blood,/turf/simulated/shuttle/floor/red,/area/submap/crashedcontainmentshuttle) -"bx" = (/turf/simulated/shuttle/wall/dark/no_join,/area/submap/crashedcontainmentshuttle) -"by" = (/obj/random/landmine,/obj/random/landmine,/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) -"bz" = (/obj/effect/decal/remains/human,/obj/item/clothing/head/helmet/space/cult,/obj/effect/decal/cleanable/blood,/turf/simulated/shuttle/floor/red,/area/submap/crashedcontainmentshuttle) -"bA" = (/obj/effect/decal/cleanable/blood/drip,/obj/effect/decal/cleanable/blood/drip,/turf/simulated/shuttle/floor/white,/area/submap/crashedcontainmentshuttle) -"bB" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/effect/decal/cleanable/blood/drip,/obj/effect/decal/cleanable/blood/drip,/turf/simulated/shuttle/floor/white,/area/submap/crashedcontainmentshuttle) -"bC" = (/obj/effect/decal/cleanable/liquid_fuel,/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) -"bD" = (/obj/structure/shuttle/engine/propulsion{icon_state = "burst_r"},/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) -"bE" = (/obj/effect/decal/cleanable/blood/drip,/obj/effect/decal/cleanable/blood/drip,/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) -"bF" = (/obj/effect/decal/cleanable/blood/drip,/turf/simulated/shuttle/floor/white,/area/submap/crashedcontainmentshuttle) -"bG" = (/obj/effect/decal/cleanable/liquid_fuel,/obj/random/landmine,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) -"bH" = (/obj/structure/closet/crate{name = "landmines crate"; opened = 1},/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) -"bI" = (/obj/random/landmine,/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) -"bJ" = (/obj/random/landmine,/turf/simulated/floor/plating,/area/submap/crashedcontainmentshuttle) -"bK" = (/obj/random/landmine,/turf/simulated/shuttle/floor/yellow,/area/submap/crashedcontainmentshuttle) -"bL" = (/obj/effect/decal/cleanable/blood,/obj/random/landmine,/turf/simulated/shuttle/floor/red,/area/submap/crashedcontainmentshuttle) -"bM" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) -"bN" = (/obj/structure/toilet{dir = 8},/obj/effect/gibspawner/generic,/obj/effect/decal/remains/human,/obj/item/weapon/card/id/syndicate{age = "\\42"; blood_type = "\\O+"; desc = "A strange ID card."; dna_hash = "\[REDACTED]"; fingerprint_hash = "\\------"; name = "Aaron Presley's ID Card(Delivery Service) "; registered_name = "Aaron Presley"; sex = "\\Male"},/turf/simulated/shuttle/floor/white,/area/submap/crashedcontainmentshuttle) -"bO" = (/obj/effect/decal/cleanable/liquid_fuel,/obj/effect/decal/remains/human,/obj/item/weapon/flame/lighter/random,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) +"aa" = (/turf/template_noop,/area/submap/crashedcontainmentshuttle) +"ab" = (/turf/simulated/shuttle/wall/dark/hard_corner,/area/submap/crashedcontainmentshuttle) +"ac" = (/turf/simulated/shuttle/wall/dark,/area/submap/crashedcontainmentshuttle) +"ad" = (/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) +"ae" = (/turf/simulated/shuttle/floor/yellow,/area/submap/crashedcontainmentshuttle) +"af" = (/turf/simulated/shuttle/floor/red,/area/submap/crashedcontainmentshuttle) +"ag" = (/turf/simulated/shuttle/floor/white,/area/submap/crashedcontainmentshuttle) +"ah" = (/obj/structure/grille,/obj/item/weapon/material/shard{icon_state = "medium"},/turf/simulated/floor/plating,/area/submap/crashedcontainmentshuttle) +"ai" = (/obj/structure/grille,/obj/item/weapon/material/shard{icon_state = "medium"},/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) +"aj" = (/obj/random/landmine,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) +"ak" = (/obj/structure/door_assembly/door_assembly_ext{anchored = 1},/turf/simulated/floor/plating,/area/submap/crashedcontainmentshuttle) +"al" = (/obj/item/weapon/material/shard{icon_state = "medium"},/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) +"am" = (/obj/item/weapon/material/shard,/turf/template_noop,/area/submap/crashedcontainmentshuttle) +"an" = (/obj/structure/girder,/turf/simulated/floor/plating,/area/submap/crashedcontainmentshuttle) +"ao" = (/turf/simulated/floor/plating,/area/submap/crashedcontainmentshuttle) +"ap" = (/obj/structure/lattice,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) +"aq" = (/obj/item/weapon/material/shard,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) +"ar" = (/obj/structure/grille,/obj/item/weapon/material/shard,/turf/simulated/floor/plating,/area/submap/crashedcontainmentshuttle) +"as" = (/obj/item/weapon/material/shard,/turf/simulated/floor/plating,/area/submap/crashedcontainmentshuttle) +"at" = (/obj/item/stack/rods,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) +"au" = (/obj/item/stack/rods,/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) +"av" = (/obj/structure/closet/walllocker/emerglocker/east,/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) +"aw" = (/obj/structure/frame,/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) +"ax" = (/obj/item/frame/mirror,/obj/item/weapon/material/shard{icon_state = "medium"},/turf/simulated/shuttle/wall/dark,/area/submap/crashedcontainmentshuttle) +"ay" = (/obj/effect/decal/mecha_wreckage/gygax{anchored = 1},/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) +"az" = (/obj/effect/gibspawner/generic,/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) +"aA" = (/obj/structure/closet/medical_wall,/turf/simulated/shuttle/wall/dark,/area/submap/crashedcontainmentshuttle) +"aC" = (/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) +"aD" = (/obj/structure/door_assembly/door_assembly_ext,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) +"aE" = (/obj/structure/extinguisher_cabinet,/turf/simulated/shuttle/wall/dark,/area/submap/crashedcontainmentshuttle) +"aF" = (/obj/machinery/computer,/turf/simulated/shuttle/floor/yellow,/area/submap/crashedcontainmentshuttle) +"aG" = (/obj/structure/loot_pile/maint/technical,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) +"aH" = (/obj/structure/frame/computer,/turf/simulated/shuttle/floor/yellow,/area/submap/crashedcontainmentshuttle) +"aI" = (/obj/structure/grille{density = 0; icon_state = "brokengrille"},/obj/item/stack/rods,/turf/simulated/floor/plating,/area/submap/crashedcontainmentshuttle) +"aJ" = (/obj/item/stack/rods,/turf/simulated/floor/plating,/area/submap/crashedcontainmentshuttle) +"aK" = (/obj/structure/grille{density = 0; icon_state = "brokengrille"},/obj/item/weapon/material/shard{icon_state = "medium"},/obj/item/stack/rods,/turf/simulated/floor/plating,/area/submap/crashedcontainmentshuttle) +"aL" = (/obj/item/weapon/circuitboard/broken,/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) +"aM" = (/obj/structure/frame,/obj/item/weapon/circuitboard/broken,/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) +"aN" = (/obj/structure/table/steel_reinforced,/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) +"aO" = (/obj/structure/closet/walllocker/emerglocker/north,/obj/structure/frame,/obj/item/weapon/circuitboard/broken,/turf/simulated/shuttle/floor/white,/area/submap/crashedcontainmentshuttle) +"aP" = (/turf/simulated/floor/outdoors/rocks,/area/submap/crashedcontainmentshuttle) +"aQ" = (/obj/structure/grille{density = 0; icon_state = "brokengrille"},/obj/structure/lattice,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) +"aR" = (/obj/structure/shuttle/engine/heater{dir = 8},/obj/structure/window/reinforced{dir = 4; health = 1e+006},/turf/template_noop,/area/submap/crashedcontainmentshuttle) +"aS" = (/obj/structure/door_assembly/door_assembly_highsecurity{anchored = 1},/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) +"aT" = (/obj/structure/loot_pile/maint/technical,/turf/simulated/shuttle/floor/yellow,/area/submap/crashedcontainmentshuttle) +"aU" = (/obj/structure/loot_pile/maint/technical,/turf/simulated/shuttle/floor/white,/area/submap/crashedcontainmentshuttle) +"aV" = (/obj/structure/shuttle/engine/propulsion{dir = 8},/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) +"aW" = (/obj/structure/loot_pile/maint/technical,/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) +"aX" = (/obj/item/weapon/circuitboard/broken,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) +"aY" = (/obj/item/clothing/suit/space/cult,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) +"aZ" = (/obj/effect/decal/remains/robot,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) +"ba" = (/obj/effect/decal/remains/human,/obj/effect/gibspawner/human,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) +"bb" = (/obj/effect/decal/cleanable/blood/drip,/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) +"bc" = (/obj/structure/door_assembly,/turf/simulated/shuttle/floor/white,/area/submap/crashedcontainmentshuttle) +"bd" = (/obj/item/clothing/head/helmet/space/cult,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) +"be" = (/obj/item/weapon/material/knife/ritual,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) +"bf" = (/obj/structure/bed/chair/office/dark{dir = 8},/obj/effect/decal/remains/human,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) +"bg" = (/obj/effect/gibspawner/generic,/turf/template_noop,/area/submap/crashedcontainmentshuttle) +"bh" = (/obj/effect/decal/remains/human,/turf/simulated/shuttle/floor/yellow,/area/submap/crashedcontainmentshuttle) +"bi" = (/obj/item/weapon/circuitboard/broken,/obj/effect/decal/remains/human,/obj/item/weapon/gun/energy/laser,/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) +"bj" = (/obj/item/device/gps/internal/poi,/turf/simulated/shuttle/floor/red,/area/submap/crashedcontainmentshuttle) +"bk" = (/obj/effect/decal/cleanable/vomit,/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) +"bl" = (/obj/effect/decal/remains/robot,/turf/simulated/shuttle/floor/red,/area/submap/crashedcontainmentshuttle) +"bm" = (/obj/effect/decal/cleanable/liquid_fuel,/turf/template_noop,/area/submap/crashedcontainmentshuttle) +"bn" = (/obj/effect/decal/cleanable/vomit,/turf/simulated/shuttle/floor/white,/area/submap/crashedcontainmentshuttle) +"bo" = (/obj/effect/decal/cleanable/blood/drip,/turf/template_noop,/area/submap/crashedcontainmentshuttle) +"bp" = (/obj/structure/bed/chair/office/dark{dir = 4},/turf/simulated/shuttle/floor/yellow,/area/submap/crashedcontainmentshuttle) +"bq" = (/obj/item/weapon/circuitboard/broken,/obj/structure/bed/chair/office/dark{dir = 4},/turf/simulated/shuttle/floor/yellow,/area/submap/crashedcontainmentshuttle) +"br" = (/obj/effect/decal/cleanable/blood/drip,/obj/effect/decal/cleanable/blood/drip,/obj/effect/decal/cleanable/blood/drip,/turf/simulated/shuttle/floor/yellow,/area/submap/crashedcontainmentshuttle) +"bs" = (/obj/structure/table/steel_reinforced,/turf/simulated/shuttle/floor/yellow,/area/submap/crashedcontainmentshuttle) +"bt" = (/obj/structure/shuttle/engine/heater{dir = 8},/obj/structure/window/reinforced{dir = 4; health = 1e+006},/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) +"bu" = (/obj/structure/door_assembly/door_assembly_ext{anchored = 1},/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) +"bv" = (/obj/effect/decal/cleanable/blood/oil,/turf/simulated/shuttle/floor/red,/area/submap/crashedcontainmentshuttle) +"bw" = (/obj/item/weapon/material/knife/ritual,/obj/effect/decal/cleanable/blood,/turf/simulated/shuttle/floor/red,/area/submap/crashedcontainmentshuttle) +"bx" = (/turf/simulated/shuttle/wall/dark/no_join,/area/submap/crashedcontainmentshuttle) +"by" = (/obj/random/landmine,/obj/random/landmine,/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) +"bz" = (/obj/effect/decal/remains/human,/obj/item/clothing/head/helmet/space/cult,/obj/effect/decal/cleanable/blood,/turf/simulated/shuttle/floor/red,/area/submap/crashedcontainmentshuttle) +"bA" = (/obj/effect/decal/cleanable/blood/drip,/obj/effect/decal/cleanable/blood/drip,/turf/simulated/shuttle/floor/white,/area/submap/crashedcontainmentshuttle) +"bB" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/effect/decal/cleanable/blood/drip,/obj/effect/decal/cleanable/blood/drip,/turf/simulated/shuttle/floor/white,/area/submap/crashedcontainmentshuttle) +"bC" = (/obj/effect/decal/cleanable/liquid_fuel,/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) +"bD" = (/obj/structure/shuttle/engine/propulsion{icon_state = "burst_r"},/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) +"bE" = (/obj/effect/decal/cleanable/blood/drip,/obj/effect/decal/cleanable/blood/drip,/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) +"bF" = (/obj/effect/decal/cleanable/blood/drip,/turf/simulated/shuttle/floor/white,/area/submap/crashedcontainmentshuttle) +"bG" = (/obj/effect/decal/cleanable/liquid_fuel,/obj/random/landmine,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) +"bH" = (/obj/structure/closet/crate{name = "landmines crate"; opened = 1},/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) +"bI" = (/obj/random/landmine,/turf/simulated/shuttle/floor/black,/area/submap/crashedcontainmentshuttle) +"bJ" = (/obj/random/landmine,/turf/simulated/floor/plating,/area/submap/crashedcontainmentshuttle) +"bK" = (/obj/random/landmine,/turf/simulated/shuttle/floor/yellow,/area/submap/crashedcontainmentshuttle) +"bL" = (/obj/effect/decal/cleanable/blood,/obj/random/landmine,/turf/simulated/shuttle/floor/red,/area/submap/crashedcontainmentshuttle) +"bM" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) +"bN" = (/obj/structure/toilet{dir = 8},/obj/effect/gibspawner/generic,/obj/effect/decal/remains/human,/obj/item/weapon/card/id/syndicate{age = "\\42"; blood_type = "\\O+"; desc = "A strange ID card."; dna_hash = "\[REDACTED]"; fingerprint_hash = "\\------"; name = "Aaron Presley's ID Card(Delivery Service) "; registered_name = "Aaron Presley"; sex = "\\Male"},/turf/simulated/shuttle/floor/white,/area/submap/crashedcontainmentshuttle) +"bO" = (/obj/effect/decal/cleanable/liquid_fuel,/obj/effect/decal/remains/human,/obj/item/weapon/flame/lighter/random,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/crashedcontainmentshuttle) -(1,1,1) = {" -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaiaaaaaaajanaaaaaaaaaaaaaaalaaaaaaaa -aaaaabacaaaaaaaaaaaaaaaaapaaaPaPaaaqaaaaaaaaaaaaaa -aaaaacaaaaadaaaaaaaaajapaPaPaPadaPaaaaaaataaaaaaaa -aaaCaaaaauaDakaracacaGaQacacananacabaaaaaaaaaaaaaa -aaaVaXaaadaoaaadadajaXbHbyayadadaWacabaaaaaaaaaaaa -aaaYaaaRacaaadadaZapbIbybIazbbadaNacanbJaaaaaaaaaa -aaaababdbeapapapadadadbIadadauadaNaAaeaTanaaaaataa -acaaaaaaapadauadadadacacaSacanadavacbhaeaeahaaaaaa -aPadaVaRacadadadbiadacbjafafacadadadbKbpaHaraaaaaa -aaaPadaaacaMadbkadbbacbvaBbwacaLadaSbKbqaHaoapaaaa -aPbxaVaRacaWadbbadbbanblbLbzanadbbasaebraFaIaabfaa -aPaPaaaaaaaabEazadadanacacacaEadadahaebpaHaoaaaiaa -aPaPadaaaJapbIadadaPaPadadadadadadacaeaeaeahaaaaaa -adaaaaaaaaaoadadaPaPaPadacanacbcacacaTbsacacaaaaaa -aPacaaaaamapadaWaPaPbbadaAbAaUbFaOacacacabaPaaaaaa -aPaPaaaPacadadadadadadawaxbBagbnbNanabaPaPaaaaaaaa -aaaaaXbtaaacbuapaoaKanananacacaranabaPaPaabgaaaaaa -acaaaaaaaPaPaaaoaaaaapapaPaPaPapaPaPaaaaaaaaaaaaaa -aaaXaaaaaaacaaaaadaaaabmaaboaaaaaaaaaaaaaaaaaaaaaa -aabDaabgaaaGaaaaaaaabGbmboaabmbgaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaadaLaaaabmbMbObmbmaaaaaaaaaaaaaaaaaaaa -aaaaadadaaaaaaacaPbCbmbmbmaaajaaaaaaaaaaaaaaaaaaaa -aaaaaaadaaaaaaaPaPaaaaaabmaaaaaaaaaaaaaaaaaaaaaaaa -"} +(1,1,1) = {" +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaiaaaaaaajanaaaaaaaaaaaaaaalaaaaaaaa +aaaaabacaaaaaaaaaaaaaaaaapaaaPaPaaaqaaaaaaaaaaaaaa +aaaaacaaaaadaaaaaaaaajapaPaPaPadaPaaaaaaataaaaaaaa +aaaCaaaaauaDakaracacaGaQacacananacabaaaaaaaaaaaaaa +aaaVaXaaadaoaaadadajaXbHbyayadadaWacabaaaaaaaaaaaa +aaaYaaaRacaaadadaZapbIbybIazbbadaNacanbJaaaaaaaaaa +aaaababdbeapapapadadadbIadadauadaNaAaeaTanaaaaataa +acaaaaaaapadauadadadacacaSacanadavacbhaeaeahaaaaaa +aPadaVaRacadadadbiadacbjafafacadadadbKbpaHaraaaaaa +aaaPadaaacaMadbkadbbacbvafbwacaLadaSbKbqaHaoapaaaa +aPbxaVaRacaWadbbadbbanblbLbzanadbbasaebraFaIaabfaa +aPaPaaaaaaaabEazadadanacacacaEadadahaebpaHaoaaaiaa +aPaPadaaaJapbIadadaPaPadadadadadadacaeaeaeahaaaaaa +adaaaaaaaaaoadadaPaPaPadacanacbcacacaTbsacacaaaaaa +aPacaaaaamapadaWaPaPbbadaAbAaUbFaOacacacabaPaaaaaa +aPaPaaaPacadadadadadadawaxbBagbnbNanabaPaPaaaaaaaa +aaaaaXbtaaacbuapaoaKanananacacaranabaPaPaabgaaaaaa +acaaaaaaaPaPaaaoaaaaapapaPaPaPapaPaPaaaaaaaaaaaaaa +aaaXaaaaaaacaaaaadaaaabmaaboaaaaaaaaaaaaaaaaaaaaaa +aabDaabgaaaGaaaaaaaabGbmboaabmbgaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaadaLaaaabmbMbObmbmaaaaaaaaaaaaaaaaaaaa +aaaaadadaaaaaaacaPbCbmbmbmaaajaaaaaaaaaaaaaaaaaaaa +aaaaaaadaaaaaaaPaPaaaaaabmaaaaaaaaaaaaaaaaaaaaaaaa +"} + diff --git a/maps/submaps/surface_submaps/mountains/digsite.dmm b/maps/submaps/surface_submaps/mountains/digsite.dmm index f97910d431..3c777b71f6 100644 --- a/maps/submaps/surface_submaps/mountains/digsite.dmm +++ b/maps/submaps/surface_submaps/mountains/digsite.dmm @@ -1,63 +1,64 @@ -"a" = (/turf/template_noop,/area/template_noop) -"b" = (/turf/simulated/mineral/ignore_mapgen,/area/submap/cave/digsite) -"c" = (/turf/simulated/wall/sandstone,/area/submap/cave/digsite) -"d" = (/obj/structure/boulder,/turf/simulated/floor/plating/external,/area/submap/cave/digsite) -"e" = (/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) -"f" = (/turf/simulated/floor/tiled/kafel_full/yellow,/area/submap/cave/digsite) -"g" = (/turf/simulated/floor/plating/external,/area/submap/cave/digsite) -"h" = (/obj/item/weapon/ore,/turf/simulated/floor/plating/external,/area/submap/cave/digsite) -"i" = (/obj/structure/bed/alien,/turf/simulated/floor/tiled/kafel_full/yellow,/area/submap/cave/digsite) -"j" = (/obj/structure/cult/talisman,/turf/simulated/floor/tiled/kafel_full/yellow,/area/submap/cave/digsite) -"k" = (/obj/machinery/artifact,/obj/structure/anomaly_container,/turf/simulated/floor/tiled/kafel_full/yellow,/area/submap/cave/digsite) -"l" = (/obj/structure/simple_door/sandstone,/turf/simulated/floor/tiled/kafel_full/yellow,/area/submap/cave/digsite) -"m" = (/obj/structure/loot_pile/surface/alien,/turf/simulated/floor/tiled/kafel_full/yellow,/area/submap/cave/digsite) -"n" = (/mob/living/simple_animal/tindalos,/turf/simulated/floor/tiled/kafel_full/yellow,/area/submap/cave/digsite) -"o" = (/obj/structure/closet/crate/secure/loot,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) -"p" = (/obj/item/weapon/ore,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) -"q" = (/obj/effect/floor_decal/asteroid,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) -"r" = (/obj/structure/anomaly_container,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) -"s" = (/turf/simulated/wall,/area/submap/cave/digsite) -"t" = (/obj/item/frame/apc,/obj/item/weapon/module/power_control,/turf/simulated/floor/plating/external,/area/submap/cave/digsite) -"u" = (/obj/structure/table/steel,/obj/machinery/cell_charger,/obj/random/powercell,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) -"v" = (/obj/structure/table/steel,/obj/item/weapon/storage/excavation,/obj/item/device/measuring_tape,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) -"w" = (/obj/machinery/power/port_gen/pacman/super,/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating/external,/area/submap/cave/digsite) -"x" = (/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating/external,/area/submap/cave/digsite) -"y" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) -"z" = (/obj/structure/table/steel,/obj/item/weapon/folder,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) -"A" = (/obj/structure/table/rack,/obj/item/weapon/pickaxe,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) -"B" = (/obj/item/mecha_parts/mecha_equipment/tool/drill/diamonddrill,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) -"C" = (/obj/structure/loot_pile/maint/technical,/turf/simulated/floor/plating/external,/area/submap/cave/digsite) -"D" = (/obj/structure/table/steel,/obj/random/tech_supply,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) -"E" = (/obj/structure/table/rack,/obj/item/weapon/shovel,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) -"F" = (/obj/structure/boulder,/obj/effect/decal/mecha_wreckage/ripley,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) -"G" = (/obj/structure/boulder,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) -"H" = (/obj/structure/loot_pile/maint/junk,/turf/simulated/floor/plating/external,/area/submap/cave/digsite) -"I" = (/obj/structure/table/steel,/obj/item/weapon/tool/wrench,/obj/item/weapon/storage/box/samplebags,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) -"J" = (/obj/structure/table/steel,/obj/item/stack/flag/yellow,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) -"K" = (/obj/random/toolbox,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) -"L" = (/obj/structure/closet/crate,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) -"M" = (/obj/machinery/floodlight,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) -"N" = (/obj/structure/ore_box,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) +"a" = (/turf/template_noop,/area/template_noop) +"b" = (/turf/simulated/mineral/ignore_mapgen,/area/submap/cave/digsite) +"c" = (/turf/simulated/wall/sandstone,/area/submap/cave/digsite) +"d" = (/obj/structure/boulder,/turf/simulated/floor/plating/external,/area/submap/cave/digsite) +"e" = (/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) +"f" = (/turf/simulated/floor/tiled/kafel_full/yellow,/area/submap/cave/digsite) +"g" = (/turf/simulated/floor/plating/external,/area/submap/cave/digsite) +"h" = (/obj/item/weapon/ore,/turf/simulated/floor/plating/external,/area/submap/cave/digsite) +"i" = (/obj/structure/bed/alien,/turf/simulated/floor/tiled/kafel_full/yellow,/area/submap/cave/digsite) +"j" = (/obj/structure/cult/talisman,/turf/simulated/floor/tiled/kafel_full/yellow,/area/submap/cave/digsite) +"k" = (/obj/machinery/artifact,/obj/structure/anomaly_container,/turf/simulated/floor/tiled/kafel_full/yellow,/area/submap/cave/digsite) +"l" = (/obj/structure/simple_door/sandstone,/turf/simulated/floor/tiled/kafel_full/yellow,/area/submap/cave/digsite) +"m" = (/obj/structure/loot_pile/surface/alien,/turf/simulated/floor/tiled/kafel_full/yellow,/area/submap/cave/digsite) +"n" = (/mob/living/simple_mob/animal/passive/tindalos,/turf/simulated/floor/tiled/kafel_full/yellow,/area/submap/cave/digsite) +"o" = (/obj/structure/closet/crate/secure/loot,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) +"p" = (/obj/item/weapon/ore,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) +"q" = (/obj/effect/floor_decal/asteroid,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) +"r" = (/obj/structure/anomaly_container,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) +"s" = (/turf/simulated/wall,/area/submap/cave/digsite) +"t" = (/obj/item/frame/apc,/obj/item/weapon/module/power_control,/turf/simulated/floor/plating/external,/area/submap/cave/digsite) +"u" = (/obj/structure/table/steel,/obj/machinery/cell_charger,/obj/random/powercell,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) +"v" = (/obj/structure/table/steel,/obj/item/weapon/storage/excavation,/obj/item/device/measuring_tape,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) +"w" = (/obj/machinery/power/port_gen/pacman/super,/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating/external,/area/submap/cave/digsite) +"x" = (/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating/external,/area/submap/cave/digsite) +"y" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) +"z" = (/obj/structure/table/steel,/obj/item/weapon/folder,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) +"A" = (/obj/structure/table/rack,/obj/item/weapon/pickaxe,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) +"B" = (/obj/item/mecha_parts/mecha_equipment/tool/drill/diamonddrill,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) +"C" = (/obj/structure/loot_pile/maint/technical,/turf/simulated/floor/plating/external,/area/submap/cave/digsite) +"D" = (/obj/structure/table/steel,/obj/random/tech_supply,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) +"E" = (/obj/structure/table/rack,/obj/item/weapon/shovel,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) +"F" = (/obj/structure/boulder,/obj/effect/decal/mecha_wreckage/ripley,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) +"G" = (/obj/structure/boulder,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) +"H" = (/obj/structure/loot_pile/maint/junk,/turf/simulated/floor/plating/external,/area/submap/cave/digsite) +"I" = (/obj/structure/table/steel,/obj/item/weapon/tool/wrench,/obj/item/weapon/storage/box/samplebags,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) +"J" = (/obj/structure/table/steel,/obj/item/stack/flag/yellow,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) +"K" = (/obj/random/toolbox,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) +"L" = (/obj/structure/closet/crate,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) +"M" = (/obj/machinery/floodlight,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) +"N" = (/obj/structure/ore_box,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/digsite) -(1,1,1) = {" -aaaaaaaaaaaaaaaaaaaa -aaabbbbbbbbbbbbbbbaa -aabccccccccdccccceea -abccffcfffghgcficcea -abcfffcffjggfcfffcea -abcfkflffggfffffmcea -abcfffcffffffgfffcea -abccffcffffffgnfccea -abbccccclccfhccggeea -abbbbboeffffepqeeeea -abbbbbbeeeeeeeeeeeea -abbbbbbpeeeeeqereeea -abbbbsteeuveeeerbeea -abbbbwxeyzAeqeBbbbea -abbbbCgeyDEeeeeFbbba -abeeGHgeqIJeeeqbbbba -aeeeKeeeeLMeeeNbbeaa -aaeeeeeeeeeeeeNeeeaa -aaaaaeeeeeeeeeeeeaaa -aaaaaaaaaaaaaaaaaaaa -"} +(1,1,1) = {" +aaaaaaaaaaaaaaaaaaaa +aaabbbbbbbbbbbbbbbaa +aabccccccccdccccceea +abccffcfffghgcficcea +abcfffcffjggfcfffcea +abcfkflffggfffffmcea +abcfffcffffffgfffcea +abccffcffffffgnfccea +abbccccclccfhccggeea +abbbbboeffffepqeeeea +abbbbbbeeeeeeeeeeeea +abbbbbbpeeeeeqereeea +abbbbsteeuveeeerbeea +abbbbwxeyzAeqeBbbbea +abbbbCgeyDEeeeeFbbba +abeeGHgeqIJeeeqbbbba +aeeeKeeeeLMeeeNbbeaa +aaeeeeeeeeeeeeNeeeaa +aaaaaeeeeeeeeeeeeaaa +aaaaaaaaaaaaaaaaaaaa +"} + diff --git a/maps/submaps/surface_submaps/mountains/lava_trench.dmm b/maps/submaps/surface_submaps/mountains/lava_trench.dmm new file mode 100644 index 0000000000..76b9f6f01f --- /dev/null +++ b/maps/submaps/surface_submaps/mountains/lava_trench.dmm @@ -0,0 +1,146 @@ +"aa" = (/turf/template_noop,/area/template_noop) +"ab" = (/obj/structure/cliff/automatic{icon_state = "cliffbuilder"; dir = 9},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) +"ac" = (/obj/structure/cliff/automatic,/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) +"ad" = (/obj/structure/cliff/automatic{icon_state = "cliffbuilder"; dir = 5},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) +"ae" = (/obj/structure/cliff/automatic/corner{icon_state = "cliffbuilder-corner"; dir = 9},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) +"af" = (/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) +"ag" = (/obj/structure/cliff/automatic/corner,/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) +"ah" = (/obj/structure/fence/end{icon_state = "end"; dir = 4},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) +"ai" = (/obj/structure/fence/post{icon_state = "post"; dir = 4},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) +"aj" = (/obj/structure/fence/door/opened,/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) +"ak" = (/obj/structure/fence/end{icon_state = "end"; dir = 8},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) +"al" = (/obj/structure/cliff/automatic{icon_state = "cliffbuilder"; dir = 8},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) +"am" = (/obj/structure/fence/end{icon_state = "end"; dir = 1},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) +"an" = (/obj/structure/cliff/automatic{icon_state = "cliffbuilder"; dir = 9},/turf/simulated/floor/lava,/area/submap/lava_trench) +"ao" = (/obj/structure/cliff/automatic,/turf/simulated/floor/lava,/area/submap/lava_trench) +"ap" = (/obj/structure/cliff/automatic{icon_state = "cliffbuilder"; dir = 5},/turf/simulated/floor/lava,/area/submap/lava_trench) +"aq" = (/obj/structure/sign/warning/lava,/turf/simulated/wall,/area/submap/lava_trench) +"ar" = (/obj/structure/fence/post,/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) +"as" = (/obj/structure/cliff/automatic{icon_state = "cliffbuilder"; dir = 6},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) +"at" = (/obj/structure/cliff/automatic/corner{icon_state = "cliffbuilder-corner"; dir = 9},/turf/simulated/floor/lava,/area/submap/lava_trench) +"au" = (/turf/simulated/floor/lava,/area/submap/lava_trench) +"av" = (/obj/structure/cliff/automatic/corner,/turf/simulated/floor/lava,/area/submap/lava_trench) +"aw" = (/obj/structure/railing{icon_state = "railing0"; dir = 4},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) +"ax" = (/obj/structure/catwalk,/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) +"ay" = (/obj/structure/railing{icon_state = "railing0"; dir = 8},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) +"az" = (/obj/structure/fence/door/opened{icon_state = "door_opened"; dir = 8},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) +"aA" = (/obj/structure/cliff/automatic{icon_state = "cliffbuilder"; dir = 8},/turf/simulated/floor/lava,/area/submap/lava_trench) +"aB" = (/turf/simulated/mineral/floor/ignore_mapgen,/area/template_noop) +"aC" = (/turf/simulated/floor/outdoors/rocks/caves,/area/template_noop) +"aD" = (/obj/structure/cliff/automatic,/obj/structure/railing{icon_state = "railing0"; dir = 4},/turf/simulated/floor/lava,/area/submap/lava_trench) +"aE" = (/obj/structure/cliff/automatic,/obj/structure/railing{icon_state = "railing0"; dir = 8},/turf/simulated/floor/lava,/area/submap/lava_trench) +"aF" = (/obj/structure/cliff/automatic{icon_state = "cliffbuilder"; dir = 10},/turf/simulated/floor/lava,/area/submap/lava_trench) +"aG" = (/obj/structure/cliff/automatic/corner{icon_state = "cliffbuilder-corner"; dir = 10},/turf/simulated/floor/lava,/area/submap/lava_trench) +"aH" = (/obj/structure/railing{icon_state = "railing0"; dir = 4},/obj/effect/step_trigger/teleporter/offset/east,/turf/simulated/floor/lava,/area/submap/lava_trench) +"aI" = (/obj/structure/catwalk,/turf/simulated/floor/lava,/area/submap/lava_trench) +"aJ" = (/obj/structure/ore_box,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/lava_trench) +"aK" = (/obj/structure/railing{icon_state = "railing0"; dir = 8},/obj/effect/step_trigger/teleporter/offset/west,/turf/simulated/floor/lava,/area/submap/lava_trench) +"aL" = (/obj/structure/cliff/automatic{icon_state = "cliffbuilder"; dir = 4},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) +"aM" = (/obj/machinery/light/small/flicker{icon_state = "bulb1"; dir = 4},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) +"aN" = (/obj/machinery/door/airlock/hatch{normalspeed = 0; safe = 0},/obj/effect/map_effect/interval/effect_emitter/sparks,/turf/simulated/floor/tiled/old_tile,/area/submap/lava_trench/outpost) +"aO" = (/turf/simulated/wall/rshull,/area/submap/lava_trench/outpost) +"aP" = (/obj/machinery/door/airlock/hatch{normalspeed = 0; safe = 0},/obj/effect/map_effect/interval/effect_emitter/sparks,/turf/simulated/floor/tiled/old_tile,/area/submap/lava_trench/outpost) +"aQ" = (/turf/simulated/floor/tiled/old_tile,/area/submap/lava_trench/outpost) +"aR" = (/obj/effect/floor_decal/corner_oldtile/blue/full{icon_state = "corner_oldtile_full"; dir = 8},/obj/machinery/microscope,/obj/structure/table/standard,/turf/simulated/floor/tiled/old_tile,/area/submap/lava_trench/outpost) +"aS" = (/obj/effect/floor_decal/corner_oldtile/blue/full{icon_state = "corner_oldtile_full"; dir = 8},/obj/structure/table/standard,/obj/random/unidentified_medicine/scientific,/turf/simulated/floor/tiled/old_tile,/area/submap/lava_trench/outpost) +"aT" = (/obj/structure/fence/end,/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) +"aU" = (/obj/structure/cliff/automatic{icon_state = "cliffbuilder"; dir = 2},/turf/simulated/floor/lava,/area/submap/lava_trench) +"aV" = (/obj/structure/cliff/automatic{icon_state = "cliffbuilder"; dir = 10},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) +"aW" = (/obj/structure/cliff/automatic/corner{icon_state = "cliffbuilder-corner"; dir = 10},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) +"aX" = (/obj/structure/cliff/automatic/corner{icon_state = "cliffbuilder-corner"; dir = 6},/turf/simulated/floor/lava,/area/submap/lava_trench) +"aY" = (/obj/structure/cliff/automatic{icon_state = "cliffbuilder"; dir = 2},/obj/structure/railing{icon_state = "railing0"; dir = 4},/turf/simulated/floor/lava,/area/submap/lava_trench) +"aZ" = (/obj/structure/cliff/automatic{icon_state = "cliffbuilder"; dir = 2},/obj/structure/railing{icon_state = "railing0"; dir = 8},/turf/simulated/floor/lava,/area/submap/lava_trench) +"ba" = (/obj/machinery/crystal/lava,/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) +"bb" = (/obj/structure/cliff/automatic{icon_state = "cliffbuilder"; dir = 4},/turf/simulated/floor/lava,/area/submap/lava_trench) +"bc" = (/obj/structure/cliff/automatic{icon_state = "cliffbuilder"; dir = 6},/turf/simulated/floor/lava,/area/submap/lava_trench) +"bd" = (/obj/structure/table/steel,/obj/item/weapon/storage/excavation,/obj/item/device/measuring_tape,/obj/effect/floor_decal/corner_oldtile/purple{icon_state = "corner_oldtile"; dir = 4},/turf/simulated/floor/tiled/old_tile,/area/submap/lava_trench/outpost) +"be" = (/turf/simulated/mineral/ignore_mapgen,/area/template_noop) +"bf" = (/obj/structure/railing,/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) +"bg" = (/obj/structure/cliff/automatic{icon_state = "cliffbuilder"; dir = 10},/obj/structure/railing,/turf/simulated/floor/lava,/area/submap/lava_trench) +"bh" = (/obj/structure/cliff/automatic/corner{icon_state = "cliffbuilder-corner"; dir = 10},/obj/structure/railing,/turf/simulated/floor/lava,/area/submap/lava_trench) +"bi" = (/obj/structure/railing,/obj/effect/step_trigger/teleporter/offset/south,/turf/simulated/floor/lava,/area/submap/lava_trench) +"bj" = (/obj/structure/cliff/automatic{icon_state = "cliffbuilder"; dir = 4},/obj/structure/railing,/turf/simulated/floor/lava,/area/submap/lava_trench) +"bk" = (/obj/structure/catwalk,/obj/structure/railing,/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) +"bl" = (/obj/structure/catwalk,/obj/structure/railing,/turf/simulated/floor/lava,/area/submap/lava_trench) +"bm" = (/obj/structure/fence/door/opened{icon_state = "door_opened"; dir = 4},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) +"bn" = (/obj/structure/cliff/automatic{icon_state = "cliffbuilder"; dir = 2},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) +"bo" = (/obj/effect/floor_decal/corner_oldtile/purple/full{icon_state = "corner_oldtile_full"; dir = 1},/obj/machinery/space_heater,/turf/simulated/floor/tiled/old_tile,/area/submap/lava_trench/outpost) +"bp" = (/obj/machinery/floodlight,/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) +"bq" = (/obj/machinery/newscaster{pixel_y = 32},/obj/machinery/light/small/flicker{icon_state = "bulb1"; dir = 1},/turf/simulated/floor/tiled/old_tile,/area/submap/lava_trench/outpost) +"br" = (/obj/effect/floor_decal/corner_oldtile/blue{icon_state = "corner_oldtile"; dir = 1},/obj/structure/bed/chair/office/light{icon_state = "officechair_white"; dir = 4},/turf/simulated/floor/tiled/old_tile,/area/submap/lava_trench/outpost) +"bs" = (/turf/simulated/floor/tiled/old_tile/gray,/area/submap/lava_trench/outpost) +"bt" = (/obj/effect/floor_decal/corner_oldtile/purple{icon_state = "corner_oldtile"; dir = 4},/turf/simulated/floor/tiled/old_tile,/area/submap/lava_trench/outpost) +"bu" = (/obj/structure/cliff/automatic/corner{icon_state = "cliffbuilder-corner"; dir = 6},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) +"bv" = (/obj/item/slime_crystal,/obj/item/slime_crystal,/obj/item/slime_crystal,/obj/effect/floor_decal/corner_oldtile/blue{icon_state = "corner_oldtile"; dir = 9},/obj/structure/table/standard,/turf/simulated/floor/tiled/old_tile,/area/submap/lava_trench/outpost) +"bw" = (/turf/simulated/floor/tiled/asteroid_steel,/area/submap/lava_trench) +"bx" = (/obj/machinery/crystal/ice,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/lava_trench) +"by" = (/obj/machinery/ai_status_display{pixel_y = 32},/obj/machinery/light/small/flicker{icon_state = "bulb1"; dir = 1},/turf/simulated/floor/tiled/old_tile,/area/submap/lava_trench/outpost) +"bz" = (/obj/effect/floor_decal/corner_oldtile{icon_state = "corner_oldtile"; dir = 1},/turf/simulated/floor/tiled/old_tile/gray,/area/submap/lava_trench/outpost) +"bA" = (/obj/effect/floor_decal/corner_oldtile{icon_state = "corner_oldtile"; dir = 4},/turf/simulated/floor/tiled/old_tile/gray,/area/submap/lava_trench/outpost) +"bB" = (/obj/effect/floor_decal/corner_oldtile/blue{icon_state = "corner_oldtile"; dir = 8},/turf/simulated/floor/tiled/old_tile,/area/submap/lava_trench/outpost) +"bC" = (/obj/structure/table/rack,/obj/item/weapon/shovel,/obj/effect/floor_decal/corner_oldtile/purple/full{icon_state = "corner_oldtile_full"; dir = 1},/obj/item/weapon/pickaxe/drill,/turf/simulated/floor/tiled/old_tile,/area/submap/lava_trench/outpost) +"bD" = (/obj/effect/step_trigger/teleporter/offset/north,/turf/simulated/floor/lava,/area/submap/lava_trench) +"bE" = (/obj/machinery/crystal/lava,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/lava_trench) +"bF" = (/obj/structure/table/rack,/obj/random/tool/powermaint,/obj/random/tool/powermaint,/obj/effect/floor_decal/corner_oldtile/purple{icon_state = "corner_oldtile"; dir = 6},/turf/simulated/floor/tiled/old_tile,/area/submap/lava_trench/outpost) +"bG" = (/obj/effect/floor_decal/corner_oldtile/purple,/obj/structure/table/steel,/obj/item/device/xenoarch_multi_tool,/turf/simulated/floor/tiled/old_tile,/area/submap/lava_trench/outpost) +"bH" = (/obj/effect/floor_decal/corner_oldtile/purple,/turf/simulated/floor/tiled/old_tile,/area/submap/lava_trench/outpost) +"bI" = (/obj/item/device/gps/science{gps_tag = "CRYSTALS"},/turf/simulated/floor/tiled/old_tile,/area/submap/lava_trench/outpost) +"bK" = (/obj/effect/floor_decal/corner_oldtile/blue/full,/obj/random/drinkbottle,/obj/random/maintenance/research,/obj/structure/table/standard,/obj/machinery/light/small/flicker{icon_state = "bulb1"; dir = 8},/turf/simulated/floor/tiled/old_tile,/area/submap/lava_trench/outpost) +"bL" = (/obj/structure/flora/pottedplant/crystal,/obj/effect/floor_decal/corner_oldtile/blue{icon_state = "corner_oldtile"; dir = 8},/turf/simulated/floor/tiled/old_tile,/area/submap/lava_trench/outpost) +"bM" = (/obj/structure/cult/pylon,/obj/effect/floor_decal/industrial/outline,/turf/simulated/floor/tiled/old_tile/gray,/area/submap/lava_trench/outpost) +"bN" = (/obj/structure/anomaly_container,/obj/machinery/artifact,/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) +"bO" = (/obj/machinery/light/small/flicker{icon_state = "bulb1"; dir = 4},/turf/simulated/floor/tiled/old_tile,/area/submap/lava_trench/outpost) +"bP" = (/obj/effect/floor_decal/corner_oldtile/purple/full{icon_state = "corner_oldtile_full"; dir = 4},/obj/structure/table/steel,/obj/machinery/recharger,/obj/machinery/light/small/flicker{icon_state = "bulb1"; dir = 4},/turf/simulated/floor/tiled/old_tile,/area/submap/lava_trench/outpost) +"bQ" = (/obj/machinery/light/small/flicker{icon_state = "bulb1"; dir = 8},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) +"bR" = (/obj/machinery/light/small/flicker{icon_state = "bulb1"; dir = 1},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) +"bS" = (/obj/effect/floor_decal/corner_oldtile/blue{icon_state = "corner_oldtile"; dir = 1},/obj/structure/loot_pile/surface/medicine_cabinet{pixel_y = 28},/obj/structure/table/standard,/obj/item/device/healthanalyzer/improved,/turf/simulated/floor/tiled/old_tile,/area/submap/lava_trench/outpost) +"bT" = (/obj/machinery/suspension_gen{anchored = 1},/obj/effect/floor_decal/industrial/hatch/yellow,/turf/simulated/floor/tiled/old_tile,/area/submap/lava_trench/outpost) +"bU" = (/obj/machinery/light/small/flicker,/obj/structure/ore_box,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/lava_trench) +"bW" = (/obj/structure/anomaly_container,/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) +"bX" = (/obj/effect/floor_decal/corner_oldtile/purple/full{icon_state = "corner_oldtile_full"; dir = 4},/obj/item/weapon/storage/box/samplebags,/obj/structure/table/steel,/obj/item/stack/flag/red,/turf/simulated/floor/tiled/old_tile,/area/submap/lava_trench/outpost) +"bY" = (/obj/machinery/crystal,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/lava_trench) +"bZ" = (/obj/structure/table/steel,/obj/item/weapon/stock_parts/subspace/crystal,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/lava_trench) +"ca" = (/obj/structure/table/steel,/obj/item/stack/material/diamond,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/lava_trench) +"cb" = (/obj/structure/loot_pile/surface/bones,/turf/simulated/floor/tiled/old_tile,/area/submap/lava_trench/outpost) +"ce" = (/obj/effect/floor_decal/corner_oldtile/blue/full,/obj/structure/table/standard,/turf/simulated/floor/tiled/old_tile,/area/submap/lava_trench/outpost) +"ch" = (/obj/structure/loot_pile/maint/trash,/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) +"cj" = (/obj/item/clothing/head/bio_hood/anomaly,/turf/simulated/floor/tiled/old_tile,/area/submap/lava_trench/outpost) +"ck" = (/obj/item/clothing/suit/bio_suit/anomaly,/turf/simulated/floor/tiled/old_tile,/area/submap/lava_trench/outpost) +"co" = (/obj/machinery/floodlight,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/lava_trench) +"cp" = (/obj/machinery/light/small/flicker,/obj/structure/closet/crate/secure/loot,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/lava_trench) +"cq" = (/obj/item/weapon/banner/nt,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/lava_trench) +"cr" = (/obj/structure/table/steel,/obj/item/weapon/material/shard/phoron,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/lava_trench) +"cs" = (/obj/item/weapon/banner/nt,/turf/simulated/floor/outdoors/rocks/caves,/area/submap/lava_trench) + +(1,1,1) = {" +aBaBabacacacacacacacacacacadaBaBaBaBaBaCaCaCaBaBaBaBaBaBaBaBaBaBaBaBbebebeaaaaaaaaaaaaaaaaaaaaaa +aBabaeafafafafafafafafafafagacacacacahaiajaiakacadaBaBaBaBaBaBaBaBaBaBbebebeaaaaaaaaaaaaaaaaaaaa +aBalafafafafafafafafafafafafafafafafafafafafafafagacacacacacacacadaBaBaBbebebeaaaaaaaaaaaaaaaaaa +aBamafafbaanaoaoaoaoapafafafafafafafafafafafafaqafafafafafafafafagadaBaBaBbebebeaaaaaaaaaaaaaaaa +afarafafanatauauauauavaoaoaoaoaoaoaoapawaxayafafafafafafafafafafafagadaBaBaBbebebeaaaaaaaaaaaaaa +afazafafaAauauauauauauauauauauauauauavaDaxaEaoaoaoaoaoaoaoapafafafafagadaBaBbebebebebebebebeaaaa +afarafafaFaGauauauauauauauauauauauauauaHaxaKauauauauauauauavapafafafafaLaBaBaBaBbebebebebebebeaa +aBaTafafafaFaUaGauauauauauauauafauauauaHaIaKauauauauauauauauavapafafafaLaBaBaBaBaBaBaBaBaBbebeaa +aBalafafafafafaFaGauafauauauauauauauauaHaIaKauauafauauafafauauavapafafagacacadaBaBaBaBaBaBbebeaa +aBaVaWafafaqafafaFaUafaUaGauauauauauaXaYaIaZaGauauauauauafbaauaubbafafafafafagacacacadaBaBaBaBaB +aBaBaVaWafafafafafafafafaFaUaUaUaUaUbcawaxayaFaUaUaGauauauauauaubbafafafafafafafafafamaBaBaBaBaB +aBaBaBalafafafafafafafafafafafafafafafafbwafafafbfbgbhbibibibibibjbfbfafafbaafafafafarafaBaBaBaB +beaBaBalafafafafbwbwbwbwbwafafafafafafafbwbwbwbwbkbkblblblblblblblbkbkafafafafafafafbmafaBaBaBaB +beaBaBalafafafafbwbxbEbYbwbwbwbwbwbwbwbwbwbwbwafafafaAbDbDbDbDbDavapafafafafafafafafarafaBaBaBaB +beaBaBalafafafafbwbZcacrbwbwbwcqbUaJaOaNaOcocpcsafaqaAauauauauauaubbafafafafafafafafaTafaBaBaBaB +beaBaBalafafafafbwbwbwbwbwbwaJaOaOaOaObOaOaOaOaOafafaFaGauauafauaubbafafaqbpafafafafaLafaBaBaBaB +beaBaBaVbnbnaWafafbwbwbwbwbwaOaOaSbSaOaPaObdboaOaOafafaAauauauauauavapafafafafafafafaLaBaBaBaBaB +beaBaBaBaBaBalafafafafafafafaOaRbraQbqaQbycjbtbCaOafafaAauauauauauauavapafafafbaafafaLaBaBbeaBaB +beaBaBaBaBaBalafafafafafafaMaObvaQaQaQaQaQcbbIbFaObQafaFaGauauauauauaubbafafafafafafaLaBaBbebebe +bebebebeaBaBaVbnbnbnbnaWafafaOcebBaQaQbTckaQbHbXaOafafafaAauauafauauaubbafafafafafafaLaBaBbebeaa +bebebebeaBaBaBaBaBaBaBalafafaOaObKbLbzbsbAbGbPaOaOafafafaAauauafbaauaubbafafbaafafafaLaBaBbebeaa +aaaabebebeaBaBaBaBaBaBalafafafaOaOaObsbMbsaOaOaObNafafafafafauafafauaubbafafafafafbuasaBaBbebeaa +aaaaaabebebebebebeaBaBaVbnaWafafchaOaOaOaOaObNbWafafafafaAauauauafauaubbafafafbubnasaBaBaBbebeaa +aaaaaaaabebebebebeaBaBaBaBalafafafafafbRafafafafafafafafaAauauauauauauavapafafaLaBaBaBaBbebebeaa +aaaaaaaaaaaaaabebebeaBaBaBalafafafafafafafafafafafafafafaFaGauauauauauaubbafafaLaBaBaBbebebeaaaa +aaaaaaaaaaaaaaaabebebebeaBaVbnbnbnbnbnbnbnbnbnbnbnaWafafafaFaGauauauauaubbafafaLaBaBbebebeaaaaaa +aaaaaaaaaaaaaaaaaabebebeaBaBaBaBaBaBaBaBaBaBaBaBaBalafafafafaFaUaUaUaUaUbcafafaLaBaBbebeaaaaaaaa +aaaaaaaaaaaaaaaaaaaabebebeaBaBaBaBaBaBaBaBaBaBaBaBaVbnaWafafafafafafafafafafafaLaBaBbebeaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaabebebebebebebebebebebebeaBaBaBaBaVaWafafafafafafafafafafaLaBaBbebeaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaabebebebebebebebebebebebeaBaBaBaBaVbnbnbnbnahaiajaiakbnasaBaBbebeaaaaaaaa +"} diff --git a/maps/submaps/surface_submaps/mountains/mountains.dm b/maps/submaps/surface_submaps/mountains/mountains.dm index 56a267c475..af6363a18a 100644 --- a/maps/submaps/surface_submaps/mountains/mountains.dm +++ b/maps/submaps/surface_submaps/mountains/mountains.dm @@ -32,6 +32,7 @@ #include "BlastMine1.dmm" #include "crashedcontainmentshuttle.dmm" #include "deadspy.dmm" +#include "lava_trench.dmm" #endif // The 'mountains' is the mining z-level, and has a lot of caves. @@ -272,3 +273,10 @@ desc = "An abandoned blast mining site, seems that local wildlife has moved in." mappath = 'maps/submaps/surface_submaps/mountains/BlastMine1.dmm' cost = 20 + +/datum/map_template/surface/mountains/deep/lava_trench + name = "lava trench" + desc = "A long stretch of lava underground, almost river-like, with a small crystal research outpost on the side." + mappath = 'maps/submaps/surface_submaps/mountains/lava_trench.dmm' + cost = 20 + fixed_orientation = TRUE \ No newline at end of file diff --git a/maps/submaps/surface_submaps/mountains/mountains_areas.dm b/maps/submaps/surface_submaps/mountains/mountains_areas.dm index 9bcce0da1e..53fada4b7c 100644 --- a/maps/submaps/surface_submaps/mountains/mountains_areas.dm +++ b/maps/submaps/surface_submaps/mountains/mountains_areas.dm @@ -120,4 +120,13 @@ /area/submap/deadspy name = "Dead Spy" - ambience = AMBIENCE_FOREBODING \ No newline at end of file + ambience = AMBIENCE_FOREBODING + +/area/submap/lava_trench + name = "Lava Trench" + ambience = AMBIENCE_LAVA + +/area/submap/lava_trench/outpost + name = "Trench Outpost" + requires_power = FALSE + icon_state = "submap2" \ No newline at end of file diff --git a/maps/submaps/surface_submaps/mountains/quarantineshuttle.dmm b/maps/submaps/surface_submaps/mountains/quarantineshuttle.dmm index ab2a36f75b..5d0739cbcf 100644 --- a/maps/submaps/surface_submaps/mountains/quarantineshuttle.dmm +++ b/maps/submaps/surface_submaps/mountains/quarantineshuttle.dmm @@ -1,146 +1,147 @@ -"aa" = (/turf/template_noop,/area/template_noop) -"ab" = (/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) -"ac" = (/obj/item/weapon/caution/cone,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) -"ad" = (/turf/simulated/shuttle/wall,/area/submap/cave/qShuttle) -"ae" = (/obj/structure/inflatable,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) -"af" = (/obj/structure/inflatable/door,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) -"ag" = (/obj/structure/shuttle/engine/heater{icon_state = "heater"; dir = 4},/turf/simulated/shuttle/plating,/area/submap/cave/qShuttle) -"ah" = (/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_l"; dir = 8},/turf/simulated/shuttle/plating,/area/submap/cave/qShuttle) -"ai" = (/obj/structure/grille,/obj/structure/shuttle/window,/obj/machinery/door/blast/regular{dir = 8; id = "QShuttlePoIDoors"; layer = 3.3; name = "Emergency Lockdown Shutters"},/obj/item/tape/medical{dir = 4; icon_state = "tape_door_0"; layer = 3.4},/turf/simulated/shuttle/plating,/area/submap/cave/qShuttle) -"aj" = (/turf/simulated/shuttle/wall/hard_corner,/area/submap/cave/qShuttle) -"ak" = (/obj/machinery/door/airlock/external{desc = "It opens and closes. It is stamped with the logo of Major Bill's Transportation"; frequency = 1380; icon_state = "door_locked"; id_tag = null; locked = 1; name = "MBT-540"},/obj/item/tape/medical{dir = 4; icon_state = "tape_door_0"; layer = 3.4},/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) -"al" = (/obj/structure/sign/biohazard{dir = 1},/turf/simulated/shuttle/wall/hard_corner,/area/submap/cave/qShuttle) -"am" = (/obj/structure/toilet{dir = 4},/obj/effect/decal/cleanable/vomit,/obj/effect/decal/remains/human,/turf/simulated/shuttle/floor,/area/submap/cave/qShuttle) -"an" = (/obj/machinery/door/airlock{name = "Restroom"},/turf/simulated/shuttle/wall,/area/submap/cave/qShuttle) -"ao" = (/obj/effect/decal/cleanable/vomit,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) -"ap" = (/obj/effect/decal/remains/human,/obj/item/clothing/suit/space/emergency,/obj/item/clothing/head/helmet/space/emergency,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) -"aq" = (/obj/structure/bed/chair,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) -"ar" = (/obj/structure/bed/chair,/obj/effect/decal/remains/human,/obj/item/clothing/suit/space/emergency,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) -"as" = (/obj/machinery/vending/snack{contraband = null; products = list(/obj/item/weapon/reagent_containers/food/snacks/candy = 0, /obj/item/weapon/reagent_containers/food/drinks/dry_ramen = 0, /obj/item/weapon/reagent_containers/food/snacks/chips = 0, /obj/item/weapon/reagent_containers/food/snacks/sosjerky = 0, /obj/item/weapon/reagent_containers/food/snacks/no_raisin = 0, /obj/item/weapon/reagent_containers/food/snacks/spacetwinkie = 0, /obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers = 0, /obj/item/weapon/reagent_containers/food/snacks/tastybread = 0, /obj/item/weapon/reagent_containers/food/snacks/skrellsnacks = 0)},/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) -"at" = (/obj/machinery/vending/cola{contraband = null; products = list(/obj/item/weapon/reagent_containers/food/drinks/cans/cola = 0, /obj/item/weapon/reagent_containers/food/drinks/cans/space_mountain_wind = 0, /obj/item/weapon/reagent_containers/food/drinks/cans/dr_gibb = 0, /obj/item/weapon/reagent_containers/food/drinks/cans/starkist = 0, /obj/item/weapon/reagent_containers/food/drinks/cans/waterbottle = 0, /obj/item/weapon/reagent_containers/food/drinks/cans/space_up = 0, /obj/item/weapon/reagent_containers/food/drinks/cans/iced_tea = 0, /obj/item/weapon/reagent_containers/food/drinks/cans/grape_juice = 0, /obj/item/weapon/reagent_containers/food/drinks/cans/gingerale = 0)},/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) -"au" = (/obj/structure/closet/crate/secure/loot,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) -"av" = (/obj/item/weapon/pickaxe/drill,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) -"aw" = (/obj/item/clothing/mask/breath,/obj/effect/decal/cleanable/dirt,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) -"ax" = (/obj/effect/decal/cleanable/generic,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) -"ay" = (/obj/effect/decal/remains/xeno,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) -"az" = (/obj/item/trash/syndi_cakes,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) -"aA" = (/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) -"aB" = (/obj/item/weapon/cigbutt,/obj/item/weapon/tank/emergency/oxygen,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) -"aC" = (/obj/item/weapon/material/knife/tacknife/boot,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) -"aD" = (/obj/effect/decal/remains/human,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) -"aE" = (/obj/item/trash/sosjerky,/obj/item/weapon/storage/box/donut/empty,/obj/item/weapon/reagent_containers/food/drinks/sillycup,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) -"aF" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1; health = 1e+006},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/shuttle/plating,/area/submap/cave/qShuttle) -"aG" = (/obj/machinery/door/airlock/glass,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) -"aH" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1; health = 1e+006},/obj/structure/window/reinforced{dir = 4},/turf/simulated/shuttle/plating,/area/submap/cave/qShuttle) -"aI" = (/obj/machinery/button{name = "Cargo Hatch"},/turf/simulated/shuttle/wall,/area/submap/cave/qShuttle) -"aJ" = (/obj/machinery/computer,/turf/simulated/shuttle/floor,/area/submap/cave/qShuttle) -"aK" = (/obj/structure/bed/chair/comfy/brown{dir = 8},/obj/effect/decal/cleanable/vomit,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) -"aL" = (/obj/structure/table/standard,/obj/item/clothing/head/helmet/space/emergency,/obj/item/weapon/paper{desc = "It looks old."; icon_state = "paper_words"; info = "Pilot's Log for Major Bill's Transportation Shuttle MBT-540
        Routine flight inbound for VIMC Outpost C-12 6:35AM 03/12/2491, Estimated arrival 7:05AM. 16 passengers, 2 crew.
        V.I.S Traffic Control 06:05:55:Major Bill's MBT-540 you are clear for departure from Dock 6 on departure route Charlie. Have a safe flight.
        Captain Willis 06:06:33: You too, control. Departing route Charlie.
        Captain Willis 06:06:48: ...Damn it.
        **
        Captain Adisu 06:10:23: Hey Ted, I'm seeing a fuel line pressure drop on engine 3?
        Captain Willis 06:10:50: Yeah, I see it. Heater's fading out, redistributing thrust 30% to compensate.
        06:12:31: A loud thud is heard.
        Captain Adisu 06:12:34: What the (Expletives)?
        Captain Adisu 06:12:39: We just lost power to engine- engine two. Hold on... Atmospheric alarm in the cargo bay. Son of a...
        Captain Willis 06:12:59: Reducing thrust further 30%, do we have a breach Adi, a breach?
        Captain Adisu 06:13:05:No breach, checking cameras... Looks like- looks like some cargo came loose back there.
        Captain Willis 06:13:15: (Expletives), I'm turning us around. Put out a distress call to Control, we'll be back in Sif orbit in a couple of minutes.
        **

        V.I.S Traffic Control 06:15:49: MBT-540 we are recieving you. Your atmospheric sensors are reading potentially harmful toxins in your cargo bay. Advise locking down interior cargo bay doors. Please stand by.
        Captain Adisu 06:16:10: Understood.
        **
        V.I.S Traffic Control 06:27:02: MBT-540, we have no docking bays available at this time, are you equipped for atmospheric re-entry?
        Captain Willis 06:27:12: We-We are shielded. But we have fuel and air for-
        V.I.S Traffic Control 06:27:17: Please make an emergency landing at the coordinates provided and standby for further information.
        **
        Captain Willis 06:36:33: Emergency landing successful. Adi, er Adisu is checking on the passengers but we had a smooth enough landing, are we clear to begin evacu-
        06:36:50: (Sound of emergency shutters closing)
        Captain Willis 06:36:51: What the hell? Control we just had a remote activation of our emergency shutters, please advise.
        V.I.S Traffic Control 06:38:10: Captain, please tune to frequency 1493.8 we are passing you on to local emergency response units. Godspeed.
        Captain Willis 06:38:49: This is Captain Willis of Major Bill's Transportation flight MBT-540 we have eighteen souls aboard and our emergency lockdown shutters have engaged remotely. Do you read?
        S.D.D.C: This is the Sif Department of Disease Control, your vessel has been identified as carrying highly sensitive materials, and due to the nature of your system's automated alerts you will be asked to remain in quarantine until we are able to determine the nature of the pathogens aboard and whether it has entered the air circulation system. Please remain in your cockpit at this time.
        **
        Captain Adisu 17:23:58:09: I don't think they're opening those doors Ted. I don't think they're coming.
        "; item_state = "paper"; name = "Black Box Transcript MBT-540"},/turf/simulated/shuttle/floor,/area/submap/cave/qShuttle) -"aM" = (/obj/item/trash/cheesie,/obj/effect/decal/remains/human,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) -"aN" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) -"aO" = (/obj/structure/bed/chair{dir = 1},/obj/effect/decal/cleanable/dirt,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) -"aP" = (/obj/structure/bed/chair{dir = 1},/obj/effect/decal/remains/human,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) -"aQ" = (/obj/structure/bed/chair{dir = 1},/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) -"aR" = (/obj/structure/bed/chair{dir = 1},/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) -"aS" = (/obj/effect/decal/cleanable/vomit,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) -"aT" = (/obj/item/clothing/head/helmet/space/emergency,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) -"aU" = (/obj/machinery/door/airlock/engineering{icon_state = "door_locked"; locked = 1; name = "Cargo Bay"},/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) -"aV" = (/obj/item/weapon/virusdish/random,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) -"aW" = (/obj/item/weapon/material/shard,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) -"aX" = (/obj/item/device/paicard,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) -"aY" = (/obj/machinery/door/blast/regular{name = "Cargo Door"},/obj/item/tape/medical{dir = 4; icon_state = "tape_door_0"; layer = 3.4},/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) -"aZ" = (/obj/effect/decal/remains/human,/obj/item/clothing/under/mbill{desc = "A uniform belonging to Major Bill's Transportation, a shipping megacorporation. This looks at least a few decades out of date."; name = "\improper old Major Bill's uniform"},/obj/item/clothing/head/soft/mbill{desc = "It's a ballcap bearing the colors of Major Bill's Shipping. This one looks at least a few decades out of date."; name = "old shipping cap"},/turf/simulated/shuttle/floor,/area/submap/cave/qShuttle) -"ba" = (/obj/item/weapon/cigbutt,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) -"bb" = (/obj/machinery/door/airlock/command{icon_state = "door_locked"; locked = 1},/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) -"bc" = (/obj/item/weapon/tank/emergency/oxygen/engi,/obj/effect/decal/cleanable/dirt,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) -"bd" = (/obj/effect/decal/remains/human,/obj/item/clothing/suit/space/emergency,/obj/item/clothing/head/helmet/space/emergency,/obj/effect/decal/cleanable/dirt,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) -"be" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1; health = 1e+006},/turf/simulated/shuttle/plating,/area/submap/cave/qShuttle) -"bf" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1; health = 1e+006},/turf/simulated/shuttle/plating,/area/submap/cave/qShuttle) -"bg" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1; health = 1e+006},/turf/simulated/shuttle/plating,/area/submap/cave/qShuttle) -"bh" = (/obj/item/clothing/suit/space/emergency,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) -"bi" = (/obj/item/trash/candy,/obj/effect/decal/cleanable/dirt,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) -"bj" = (/obj/structure/table/rack,/obj/structure/loot_pile/maint/boxfort,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) -"bk" = (/obj/structure/table/rack,/obj/item/weapon/shovel,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) -"bl" = (/obj/structure/closet/crate/secure/science{icon_state = "scisecurecrateopen"; locked = 0; name = "Virus Samples - FRAGILE"; opened = 1},/obj/item/weapon/virusdish/random,/obj/item/weapon/virusdish/random,/obj/item/weapon/virusdish/random,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) -"bm" = (/obj/structure/bed/chair/comfy/brown{dir = 8},/obj/effect/decal/remains/human,/obj/item/clothing/under/mbill{desc = "A uniform belonging to Major Bill's Transportation, a shipping megacorporation. This looks at least a few decades out of date."; name = "\improper old Major Bill's uniform"},/obj/item/clothing/head/soft/mbill{desc = "It's a ballcap bearing the colors of Major Bill's Shipping. This one looks at least a few decades out of date."; name = "old shipping cap"},/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) -"bn" = (/obj/structure/table/standard,/obj/item/device/taperecorder,/turf/simulated/shuttle/floor,/area/submap/cave/qShuttle) -"bo" = (/obj/item/weapon/tool/crowbar/red,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) -"bp" = (/obj/item/trash/chips,/obj/effect/decal/cleanable/dirt,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) -"bq" = (/obj/structure/bed/chair,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) -"br" = (/obj/structure/bed/chair,/obj/effect/decal/cleanable/dirt,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) -"bs" = (/obj/structure/bed/chair,/obj/effect/decal/remains/human,/obj/item/clothing/mask/breath,/obj/item/clothing/head/soft/mbill{desc = "It's a ballcap bearing the colors of Major Bill's Shipping. This one looks at least a few decades out of date."; name = "old shipping cap"},/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) -"bt" = (/obj/structure/bed/chair,/obj/effect/decal/remains/human,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) -"bu" = (/obj/effect/decal/remains/xeno,/obj/effect/decal/cleanable/dirt,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) -"bv" = (/obj/item/weapon/material/shard{icon_state = "medium"},/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) -"bw" = (/obj/effect/decal/remains/mouse,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) -"bx" = (/obj/random/maintenance,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) -"by" = (/obj/item/weapon/coin/silver,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) -"bz" = (/obj/effect/decal/remains/human,/obj/item/clothing/suit/space/emergency,/obj/item/clothing/head/helmet/space/emergency,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) -"bA" = (/obj/effect/decal/cleanable/generic,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) -"bB" = (/obj/item/weapon/tank/emergency/oxygen/engi,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) -"bC" = (/obj/item/trash/sosjerky,/obj/effect/decal/remains/human,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) -"bD" = (/obj/effect/decal/remains/human,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) -"bE" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/plating,/area/submap/cave/qShuttle) -"bF" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/plating,/area/submap/cave/qShuttle) -"bG" = (/obj/machinery/button{dir = 4; name = "Cargo Access"},/turf/simulated/shuttle/wall,/area/submap/cave/qShuttle) -"bH" = (/obj/machinery/recharge_station,/turf/simulated/shuttle/floor,/area/submap/cave/qShuttle) -"bI" = (/obj/machinery/door/airlock{name = "Charge Station"},/turf/simulated/shuttle/wall,/area/submap/cave/qShuttle) -"bJ" = (/obj/item/trash/tastybread,/obj/item/weapon/material/butterfly/boxcutter,/obj/effect/decal/cleanable/dirt,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) -"bK" = (/obj/effect/decal/cleanable/vomit,/obj/effect/decal/cleanable/mucus/mapped,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) -"bL" = (/obj/structure/bed/chair{dir = 1},/obj/effect/decal/remains/xeno,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) -"bM" = (/obj/structure/bed/chair{dir = 1},/obj/item/weapon/card/id/external{desc = "An identification card of some sort. Looks like this one was issued by the Vir Independent Mining Corp."; name = "VIMC identification card"; rank = "Miner"; registered_name = "Nadia Chu"},/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) -"bN" = (/obj/structure/table/rack,/obj/item/weapon/storage/toolbox/emergency,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) -"bO" = (/obj/structure/table/rack,/obj/item/clothing/head/soft/mbill{desc = "It's a ballcap bearing the colors of Major Bill's Shipping. This one looks at least a few decades out of date."; name = "old shipping cap"},/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) -"bP" = (/obj/structure/ore_box,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) -"bQ" = (/obj/item/weapon/contraband/poster,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) -"bR" = (/obj/structure/loot_pile/maint/technical,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) -"bS" = (/obj/structure/sign/biohazard,/turf/simulated/shuttle/wall/hard_corner,/area/submap/cave/qShuttle) -"bT" = (/obj/item/tape/medical{icon_state = "tape_v_0"},/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) -"bU" = (/obj/item/taperoll/medical,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) -"bV" = (/obj/item/tape/medical{dir = 1; icon_state = "tape_dir_0"},/obj/item/tape/medical{dir = 4; icon_state = "tape_dir_0"},/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) -"bW" = (/obj/item/tape/medical{icon_state = "tape_h_0"},/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) -"bX" = (/obj/structure/lattice,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) -"bY" = (/obj/structure/sign/warning/secure_area,/turf/simulated/wall/iron,/area/submap/cave/qShuttle) -"bZ" = (/obj/structure/sign/kiddieplaque{desc = "By order of the S.D.D.C, this site or craft is to be buried and not disturbed until such time that sterility can be confirmed. Dated: 20/12/2491 "; name = "\improper Sif Department of Disease Control notice"},/turf/simulated/wall/iron,/area/submap/cave/qShuttle) -"ca" = (/obj/structure/sign/warning,/turf/simulated/wall/iron,/area/submap/cave/qShuttle) -"cb" = (/obj/item/bodybag,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) -"cc" = (/obj/structure/table/steel,/obj/item/weapon/storage/box/bodybags,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) -"cd" = (/obj/structure/table/steel,/obj/item/clothing/suit/bio_suit,/obj/random/medical/lite,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) -"ce" = (/obj/structure/closet/l3closet/virology,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) -"cf" = (/obj/item/weapon/reagent_containers/syringe/antiviral,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) -"cg" = (/obj/structure/dispenser/oxygen,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) -"ch" = (/obj/structure/table/steel,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) -"ci" = (/obj/structure/table/steel,/obj/item/weapon/reagent_containers/syringe/antiviral,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) -"cj" = (/obj/structure/table/steel,/obj/item/weapon/reagent_containers/spray/cleaner{desc = "Someone has crossed out the 'Space' from Space Cleaner and written in Chemistry. Scrawled on the back is, 'Okay, whoever filled this with polytrinic acid, it was only funny the first time. It was hard enough replacing the CMO's first cat!'"; name = "Chemistry Cleaner"},/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) -"ck" = (/obj/structure/table/steel,/obj/item/weapon/tool/crowbar/power,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) -"cl" = (/obj/structure/table/rack,/obj/item/clothing/head/bio_hood,/obj/item/clothing/suit/bio_suit,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) -"cm" = (/obj/item/weapon/weldingtool/largetank,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) -"cn" = (/obj/structure/closet/crate/medical,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) +"aa" = (/turf/template_noop,/area/template_noop) +"ab" = (/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) +"ac" = (/obj/item/weapon/caution/cone,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) +"ad" = (/turf/simulated/shuttle/wall,/area/submap/cave/qShuttle) +"ae" = (/obj/structure/inflatable,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) +"af" = (/obj/structure/inflatable/door,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) +"ag" = (/obj/structure/shuttle/engine/heater{icon_state = "heater"; dir = 4},/turf/simulated/shuttle/plating,/area/submap/cave/qShuttle) +"ah" = (/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_l"; dir = 8},/turf/simulated/shuttle/plating,/area/submap/cave/qShuttle) +"ai" = (/obj/structure/grille,/obj/structure/shuttle/window,/obj/machinery/door/blast/regular{dir = 8; id = "QShuttlePoIDoors"; layer = 3.3; name = "Emergency Lockdown Shutters"},/obj/item/tape/medical{dir = 4; icon_state = "tape_door_0"; layer = 3.4},/turf/simulated/shuttle/plating,/area/submap/cave/qShuttle) +"aj" = (/turf/simulated/shuttle/wall/hard_corner,/area/submap/cave/qShuttle) +"ak" = (/obj/machinery/door/airlock/external{desc = "It opens and closes. It is stamped with the logo of Major Bill's Transportation"; frequency = 1380; icon_state = "door_locked"; id_tag = null; locked = 1; name = "MBT-540"},/obj/item/tape/medical{dir = 4; icon_state = "tape_door_0"; layer = 3.4},/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) +"al" = (/obj/structure/sign/biohazard{dir = 1},/turf/simulated/shuttle/wall/hard_corner,/area/submap/cave/qShuttle) +"am" = (/obj/structure/toilet{dir = 4},/obj/effect/decal/cleanable/vomit,/obj/effect/decal/remains/human,/turf/simulated/shuttle/floor,/area/submap/cave/qShuttle) +"an" = (/obj/machinery/door/airlock{name = "Restroom"},/turf/simulated/shuttle/wall,/area/submap/cave/qShuttle) +"ao" = (/obj/effect/decal/cleanable/vomit,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) +"ap" = (/obj/effect/decal/remains/human,/obj/item/clothing/suit/space/emergency,/obj/item/clothing/head/helmet/space/emergency,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) +"aq" = (/obj/structure/bed/chair,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) +"ar" = (/obj/structure/bed/chair,/obj/effect/decal/remains/human,/obj/item/clothing/suit/space/emergency,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) +"as" = (/obj/machinery/vending/snack{contraband = null; products = list(/obj/item/weapon/reagent_containers/food/snacks/candy = 0, /obj/item/weapon/reagent_containers/food/drinks/dry_ramen = 0, /obj/item/weapon/reagent_containers/food/snacks/chips = 0, /obj/item/weapon/reagent_containers/food/snacks/sosjerky = 0, /obj/item/weapon/reagent_containers/food/snacks/no_raisin = 0, /obj/item/weapon/reagent_containers/food/snacks/spacetwinkie = 0, /obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers = 0, /obj/item/weapon/reagent_containers/food/snacks/tastybread = 0, /obj/item/weapon/reagent_containers/food/snacks/skrellsnacks = 0)},/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) +"at" = (/obj/machinery/vending/cola{contraband = null; products = list(/obj/item/weapon/reagent_containers/food/drinks/cans/cola = 0, /obj/item/weapon/reagent_containers/food/drinks/cans/space_mountain_wind = 0, /obj/item/weapon/reagent_containers/food/drinks/cans/dr_gibb = 0, /obj/item/weapon/reagent_containers/food/drinks/cans/starkist = 0, /obj/item/weapon/reagent_containers/food/drinks/cans/waterbottle = 0, /obj/item/weapon/reagent_containers/food/drinks/cans/space_up = 0, /obj/item/weapon/reagent_containers/food/drinks/cans/iced_tea = 0, /obj/item/weapon/reagent_containers/food/drinks/cans/grape_juice = 0, /obj/item/weapon/reagent_containers/food/drinks/cans/gingerale = 0)},/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) +"au" = (/obj/structure/closet/crate/secure/loot,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) +"av" = (/obj/item/weapon/pickaxe/drill,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) +"aw" = (/obj/item/clothing/mask/breath,/obj/effect/decal/cleanable/dirt,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) +"ax" = (/obj/effect/decal/cleanable/generic,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) +"ay" = (/obj/effect/decal/remains/xeno,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) +"az" = (/obj/item/trash/syndi_cakes,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) +"aA" = (/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) +"aB" = (/obj/item/weapon/cigbutt,/obj/item/weapon/tank/emergency/oxygen,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) +"aC" = (/obj/item/weapon/material/knife/tacknife/boot,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) +"aD" = (/obj/effect/decal/remains/human,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) +"aE" = (/obj/item/trash/sosjerky,/obj/item/weapon/storage/box/donut/empty,/obj/item/weapon/reagent_containers/food/drinks/sillycup,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) +"aF" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1; health = 1e+006},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/shuttle/plating,/area/submap/cave/qShuttle) +"aG" = (/obj/machinery/door/airlock/glass,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) +"aH" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1; health = 1e+006},/obj/structure/window/reinforced{dir = 4},/turf/simulated/shuttle/plating,/area/submap/cave/qShuttle) +"aI" = (/obj/machinery/button{name = "Cargo Hatch"},/turf/simulated/shuttle/wall,/area/submap/cave/qShuttle) +"aJ" = (/obj/machinery/computer,/turf/simulated/shuttle/floor,/area/submap/cave/qShuttle) +"aK" = (/obj/structure/bed/chair/comfy/brown{dir = 8},/obj/effect/decal/cleanable/vomit,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) +"aL" = (/obj/structure/table/standard,/obj/item/clothing/head/helmet/space/emergency,/obj/item/weapon/paper{desc = "It looks old."; icon_state = "paper_words"; info = "Pilot's Log for Major Bill's Transportation Shuttle MBT-540
        Routine flight inbound for VIMC Outpost C-12 6:35AM 03/12/2491, Estimated arrival 7:05AM. 16 passengers, 2 crew.
        V.I.S Traffic Control 06:05:55:Major Bill's MBT-540 you are clear for departure from Dock 6 on departure route Charlie. Have a safe flight.
        Captain Willis 06:06:33: You too, control. Departing route Charlie.
        Captain Willis 06:06:48: ...Damn it.
        **
        Captain Adisu 06:10:23: Hey Ted, I'm seeing a fuel line pressure drop on engine 3?
        Captain Willis 06:10:50: Yeah, I see it. Heater's fading out, redistributing thrust 30% to compensate.
        06:12:31: A loud thud is heard.
        Captain Adisu 06:12:34: What the (Expletives)?
        Captain Adisu 06:12:39: We just lost power to engine- engine two. Hold on... Atmospheric alarm in the cargo bay. Son of a...
        Captain Willis 06:12:59: Reducing thrust further 30%, do we have a breach Adi, a breach?
        Captain Adisu 06:13:05:No breach, checking cameras... Looks like- looks like some cargo came loose back there.
        Captain Willis 06:13:15: (Expletives), I'm turning us around. Put out a distress call to Control, we'll be back in Sif orbit in a couple of minutes.
        **

        V.I.S Traffic Control 06:15:49: MBT-540 we are recieving you. Your atmospheric sensors are reading potentially harmful toxins in your cargo bay. Advise locking down interior cargo bay doors. Please stand by.
        Captain Adisu 06:16:10: Understood.
        **
        V.I.S Traffic Control 06:27:02: MBT-540, we have no docking bays available at this time, are you equipped for atmospheric re-entry?
        Captain Willis 06:27:12: We-We are shielded. But we have fuel and air for-
        V.I.S Traffic Control 06:27:17: Please make an emergency landing at the coordinates provided and standby for further information.
        **
        Captain Willis 06:36:33: Emergency landing successful. Adi, er Adisu is checking on the passengers but we had a smooth enough landing, are we clear to begin evacu-
        06:36:50: (Sound of emergency shutters closing)
        Captain Willis 06:36:51: What the hell? Control we just had a remote activation of our emergency shutters, please advise.
        V.I.S Traffic Control 06:38:10: Captain, please tune to frequency 1493.8 we are passing you on to local emergency response units. Godspeed.
        Captain Willis 06:38:49: This is Captain Willis of Major Bill's Transportation flight MBT-540 we have eighteen souls aboard and our emergency lockdown shutters have engaged remotely. Do you read?
        S.D.D.C: This is the Sif Department of Disease Control, your vessel has been identified as carrying highly sensitive materials, and due to the nature of your system's automated alerts you will be asked to remain in quarantine until we are able to determine the nature of the pathogens aboard and whether it has entered the air circulation system. Please remain in your cockpit at this time.
        **
        Captain Adisu 17:23:58:09: I don't think they're opening those doors Ted. I don't think they're coming.
        "; item_state = "paper"; name = "Black Box Transcript MBT-540"},/turf/simulated/shuttle/floor,/area/submap/cave/qShuttle) +"aM" = (/obj/item/trash/cheesie,/obj/effect/decal/remains/human,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) +"aN" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) +"aO" = (/obj/structure/bed/chair{dir = 1},/obj/effect/decal/cleanable/dirt,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) +"aP" = (/obj/structure/bed/chair{dir = 1},/obj/effect/decal/remains/human,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) +"aQ" = (/obj/structure/bed/chair{dir = 1},/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) +"aR" = (/obj/structure/bed/chair{dir = 1},/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) +"aS" = (/obj/effect/decal/cleanable/vomit,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) +"aT" = (/obj/item/clothing/head/helmet/space/emergency,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) +"aU" = (/obj/machinery/door/airlock/engineering{icon_state = "door_locked"; locked = 1; name = "Cargo Bay"},/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) +"aV" = (/obj/item/weapon/virusdish/random,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) +"aW" = (/obj/item/weapon/material/shard,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) +"aX" = (/obj/item/device/paicard,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) +"aY" = (/obj/machinery/door/blast/regular{name = "Cargo Door"},/obj/item/tape/medical{dir = 4; icon_state = "tape_door_0"; layer = 3.4},/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) +"aZ" = (/obj/effect/decal/remains/human,/obj/item/clothing/under/mbill{desc = "A uniform belonging to Major Bill's Transportation, a shipping megacorporation. This looks at least a few decades out of date."; name = "\improper old Major Bill's uniform"},/obj/item/clothing/head/soft/mbill{desc = "It's a ballcap bearing the colors of Major Bill's Shipping. This one looks at least a few decades out of date."; name = "old shipping cap"},/turf/simulated/shuttle/floor,/area/submap/cave/qShuttle) +"ba" = (/obj/item/weapon/cigbutt,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) +"bb" = (/obj/machinery/door/airlock/command{icon_state = "door_locked"; locked = 1},/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) +"bc" = (/obj/item/weapon/tank/emergency/oxygen/engi,/obj/effect/decal/cleanable/dirt,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) +"bd" = (/obj/effect/decal/remains/human,/obj/item/clothing/suit/space/emergency,/obj/item/clothing/head/helmet/space/emergency,/obj/effect/decal/cleanable/dirt,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) +"be" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1; health = 1e+006},/turf/simulated/shuttle/plating,/area/submap/cave/qShuttle) +"bf" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1; health = 1e+006},/turf/simulated/shuttle/plating,/area/submap/cave/qShuttle) +"bg" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1; health = 1e+006},/turf/simulated/shuttle/plating,/area/submap/cave/qShuttle) +"bh" = (/obj/item/clothing/suit/space/emergency,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) +"bi" = (/obj/item/trash/candy,/obj/effect/decal/cleanable/dirt,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) +"bj" = (/obj/structure/table/rack,/obj/structure/loot_pile/maint/boxfort,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) +"bk" = (/obj/structure/table/rack,/obj/item/weapon/shovel,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) +"bl" = (/obj/structure/closet/crate/secure/science{icon_state = "scisecurecrateopen"; locked = 0; name = "Virus Samples - FRAGILE"; opened = 1},/obj/item/weapon/virusdish/random,/obj/item/weapon/virusdish/random,/obj/item/weapon/virusdish/random,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) +"bm" = (/obj/structure/bed/chair/comfy/brown{dir = 8},/obj/effect/decal/remains/human,/obj/item/clothing/under/mbill{desc = "A uniform belonging to Major Bill's Transportation, a shipping megacorporation. This looks at least a few decades out of date."; name = "\improper old Major Bill's uniform"},/obj/item/clothing/head/soft/mbill{desc = "It's a ballcap bearing the colors of Major Bill's Shipping. This one looks at least a few decades out of date."; name = "old shipping cap"},/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) +"bn" = (/obj/structure/table/standard,/obj/item/device/taperecorder,/turf/simulated/shuttle/floor,/area/submap/cave/qShuttle) +"bo" = (/obj/item/weapon/tool/crowbar/red,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) +"bp" = (/obj/item/trash/chips,/obj/effect/decal/cleanable/dirt,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) +"bq" = (/obj/structure/bed/chair,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) +"br" = (/obj/structure/bed/chair,/obj/effect/decal/cleanable/dirt,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) +"bs" = (/obj/structure/bed/chair,/obj/effect/decal/remains/human,/obj/item/clothing/mask/breath,/obj/item/clothing/head/soft/mbill{desc = "It's a ballcap bearing the colors of Major Bill's Shipping. This one looks at least a few decades out of date."; name = "old shipping cap"},/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) +"bt" = (/obj/structure/bed/chair,/obj/effect/decal/remains/human,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) +"bu" = (/obj/effect/decal/remains/xeno,/obj/effect/decal/cleanable/dirt,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) +"bv" = (/obj/item/weapon/material/shard{icon_state = "medium"},/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) +"bw" = (/obj/effect/decal/remains/mouse,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) +"bx" = (/obj/random/maintenance,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) +"by" = (/obj/item/weapon/coin/silver,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) +"bz" = (/obj/effect/decal/remains/human,/obj/item/clothing/suit/space/emergency,/obj/item/clothing/head/helmet/space/emergency,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) +"bA" = (/obj/effect/decal/cleanable/generic,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) +"bB" = (/obj/item/weapon/tank/emergency/oxygen/engi,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) +"bC" = (/obj/item/trash/sosjerky,/obj/effect/decal/remains/human,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) +"bD" = (/obj/effect/decal/remains/human,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) +"bE" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/plating,/area/submap/cave/qShuttle) +"bF" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/plating,/area/submap/cave/qShuttle) +"bG" = (/obj/machinery/button{dir = 4; name = "Cargo Access"},/turf/simulated/shuttle/wall,/area/submap/cave/qShuttle) +"bH" = (/obj/machinery/recharge_station,/turf/simulated/shuttle/floor,/area/submap/cave/qShuttle) +"bI" = (/obj/machinery/door/airlock{name = "Charge Station"},/turf/simulated/shuttle/wall,/area/submap/cave/qShuttle) +"bJ" = (/obj/item/trash/tastybread,/obj/item/weapon/material/butterfly/boxcutter,/obj/effect/decal/cleanable/dirt,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) +"bK" = (/obj/effect/decal/cleanable/vomit,/obj/effect/decal/cleanable/mucus/mapped,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) +"bL" = (/obj/structure/bed/chair{dir = 1},/obj/effect/decal/remains/xeno,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) +"bM" = (/obj/structure/bed/chair{dir = 1},/obj/item/weapon/card/id/external{desc = "An identification card of some sort. Looks like this one was issued by the Vir Independent Mining Corp."; name = "VIMC identification card"; rank = "Miner"; registered_name = "Nadia Chu"},/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) +"bN" = (/obj/structure/table/rack,/obj/item/weapon/storage/toolbox/emergency,/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) +"bO" = (/obj/structure/table/rack,/obj/item/clothing/head/soft/mbill{desc = "It's a ballcap bearing the colors of Major Bill's Shipping. This one looks at least a few decades out of date."; name = "old shipping cap"},/turf/simulated/shuttle/floor{ icon_state = "floor_white"},/area/submap/cave/qShuttle) +"bP" = (/obj/structure/ore_box,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) +"bQ" = (/obj/item/weapon/contraband/poster,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) +"bR" = (/obj/structure/loot_pile/maint/technical,/turf/simulated/shuttle/floor{ icon_state = "floor_yellow"},/area/submap/cave/qShuttle) +"bS" = (/obj/structure/sign/biohazard,/turf/simulated/shuttle/wall/hard_corner,/area/submap/cave/qShuttle) +"bT" = (/obj/item/tape/medical{icon_state = "tape_v_0"},/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) +"bU" = (/obj/item/taperoll/medical,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) +"bV" = (/obj/item/tape/medical{dir = 1; icon_state = "tape_dir_0"},/obj/item/tape/medical{dir = 4; icon_state = "tape_dir_0"},/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) +"bW" = (/obj/item/tape/medical{icon_state = "tape_h_0"},/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) +"bX" = (/obj/structure/lattice,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) +"bY" = (/obj/structure/sign/warning/secure_area,/turf/simulated/wall/iron,/area/submap/cave/qShuttle) +"bZ" = (/obj/structure/sign/kiddieplaque{desc = "By order of the S.D.D.C, this site or craft is to be buried and not disturbed until such time that sterility can be confirmed. Dated: 20/12/2491 "; name = "\improper Sif Department of Disease Control notice"},/turf/simulated/wall/iron,/area/submap/cave/qShuttle) +"ca" = (/obj/structure/sign/warning,/turf/simulated/wall/iron,/area/submap/cave/qShuttle) +"cb" = (/obj/item/bodybag,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) +"cc" = (/obj/structure/table/steel,/obj/item/weapon/storage/box/bodybags,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) +"cd" = (/obj/structure/table/steel,/obj/item/clothing/suit/bio_suit,/obj/random/medical/lite,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) +"ce" = (/obj/structure/closet/l3closet/virology,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) +"cf" = (/obj/item/weapon/reagent_containers/syringe/antiviral,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) +"cg" = (/obj/structure/dispenser/oxygen,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) +"ch" = (/obj/structure/table/steel,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) +"ci" = (/obj/structure/table/steel,/obj/item/weapon/reagent_containers/syringe/antiviral,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) +"cj" = (/obj/structure/table/steel,/obj/item/weapon/reagent_containers/spray/cleaner{desc = "Someone has crossed out the 'Space' from Space Cleaner and written in Chemistry. Scrawled on the back is, 'Okay, whoever filled this with polytrinic acid, it was only funny the first time. It was hard enough replacing the CMO's first cat!'"; name = "Chemistry Cleaner"},/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) +"ck" = (/obj/structure/table/steel,/obj/item/weapon/tool/crowbar/power,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) +"cl" = (/obj/structure/table/rack,/obj/item/clothing/head/bio_hood,/obj/item/clothing/suit/bio_suit,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) +"cm" = (/obj/item/weapon/weldingtool/largetank,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) +"cn" = (/obj/structure/closet/crate/medical,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) -(1,1,1) = {" -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaabacababaaaaadadadacaa -aaabababababaeafaeaeabaaaaabababababababadagahabaa -aaacababadaiajakakalaiadaiadadadadadadadadadadaaaa -aaababadadamanaoapadaqaqaradasatadauavauadagahaaaa -aaaaadadadadadawaxayazaAaBaCaDaEadaFaGaHadaIadabaa -aaaaaiaJaKaLadaMaNaOaPaQaQaRaSaTaUaVaAaWaXaAaYabaa -aaabaiaZbababbbcbdadbebfbgadbhbiadbjaAbkaAblaYabaa -aaabaiaJbmbnadbobpbqbrbsbtbqaNbuaUbvaAbwaVbxaYabaa -aaabadadadadadaDbyaAbzaAbAbBbCbDadbEaGbFadadbGabaa -aaababadadbHbIbJbKadbLaQbMadbNbOadbPbQbRadagahabaa -ababacabadaiajakakbSaiadaiadadadadadadadadadadaaaa -ababababbTabaeaeafaeababababbUabababababadagahaaaa -aaabababbVbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWadadadaaaa -aaaaababababababababbXbYbZcacbcbcbabcccdceabcfaaaa -aaaaacababcgchcicjckclababcmabcbcbababababababaaaa -aaaaaaababcnchababababababababaaaaaaaaaaababacaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -"} +(1,1,1) = {" +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaabacababaaaaadadadacaa +aaabababababaeafaeaeabaaaaabababababababadagahabaa +aaacababadaiajakakalaiadaiadadadadadadadadadadaaaa +aaababadadamanaoapadaqaqaradasatadauavauadagahaaaa +aaaaadadadadadawaxayazaAaBaCaDaEadaFaGaHadaIadabaa +aaaaaiaJaKaLadaMaNaOaPaQaQaRaSaTaUaVaAaWaXaAaYabaa +aaabaiaZbababbbcbdadbebfbgadbhbiadbjaAbkaAblaYabaa +aaabaiaJbmbnadbobpbqbrbsbtbqaNbuaUbvaAbwaVbxaYabaa +aaabadadadadadaDbyaAbzaAbAbBbCbDadbEaGbFadadbGabaa +aaababadadbHbIbJbKadbLaQbMadbNbOadbPbQbRadagahabaa +ababacabadaiajakakbSaiadaiadadadadadadadadadadaaaa +ababababbTabaeaeafaeababababbUabababababadagahaaaa +aaabababbVbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWadadadaaaa +aaaaababababababababbXbYbZcacbcbcbabcccdceabcfaaaa +aaaaacababcgchcicjckclababcmabcbcbababababababaaaa +aaaaaaababcnchababababababababaaaaaaaaaaababacaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +"} + diff --git a/maps/submaps/surface_submaps/mountains/vault3.dmm b/maps/submaps/surface_submaps/mountains/vault3.dmm index b517d1cdee..bd93aba096 100644 --- a/maps/submaps/surface_submaps/mountains/vault3.dmm +++ b/maps/submaps/surface_submaps/mountains/vault3.dmm @@ -2,7 +2,7 @@ "b" = (/turf/simulated/wall,/area/submap/cave/vault3) "c" = (/obj/effect/alien/weeds,/obj/random/multiple/minevault,/turf/simulated/floor/plating,/area/submap/cave/vault3) "d" = (/obj/structure/loot_pile/maint/technical,/obj/effect/alien/weeds,/turf/simulated/floor/plating,/area/submap/cave/vault3) -"e" = (/obj/effect/alien/weeds,/mob/living/simple_animal/hostile/alien/drone,/turf/simulated/floor/plating,/area/submap/cave/vault3) +"e" = (/obj/effect/alien/weeds,/mob/living/simple_mob/animal/space/alien/drone,/turf/simulated/floor/plating,/area/submap/cave/vault3) "f" = (/obj/effect/alien/weeds,/obj/effect/alien/weeds,/turf/simulated/floor/plating,/area/submap/cave/vault3) "g" = (/obj/effect/alien/weeds,/turf/simulated/floor/plating,/area/submap/cave/vault3) "h" = (/obj/effect/alien/weeds,/obj/effect/alien/weeds,/obj/effect/alien/weeds/node,/turf/simulated/floor/plating,/area/submap/cave/vault3) diff --git a/maps/submaps/surface_submaps/mountains/vault4.dmm b/maps/submaps/surface_submaps/mountains/vault4.dmm index 7d5213916d..78ac6842d5 100644 --- a/maps/submaps/surface_submaps/mountains/vault4.dmm +++ b/maps/submaps/surface_submaps/mountains/vault4.dmm @@ -3,10 +3,10 @@ "c" = (/obj/structure/simple_door/resin,/obj/effect/alien/weeds,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/vault4) "d" = (/obj/effect/alien/weeds,/obj/structure/bed/nest,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/vault4) "e" = (/obj/effect/alien/weeds,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/vault4) -"f" = (/obj/effect/alien/weeds,/mob/living/simple_animal/hostile/alien/drone,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/vault4) +"f" = (/obj/effect/alien/weeds,/mob/living/simple_mob/animal/space/alien/drone,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/vault4) "g" = (/obj/effect/alien/weeds/node,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/vault4) "h" = (/obj/effect/alien/weeds,/obj/random/multiple/minevault,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/vault4) -"i" = (/obj/effect/alien/weeds,/mob/living/simple_animal/hostile/alien,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/vault4) +"i" = (/obj/effect/alien/weeds,/mob/living/simple_mob/animal/space/alien,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/vault4) "j" = (/obj/effect/alien/weeds,/obj/effect/alien/egg,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/vault4) (1,1,1) = {" diff --git a/maps/submaps/surface_submaps/mountains/vault5.dmm b/maps/submaps/surface_submaps/mountains/vault5.dmm index 1d4befc167..9de959c715 100644 --- a/maps/submaps/surface_submaps/mountains/vault5.dmm +++ b/maps/submaps/surface_submaps/mountains/vault5.dmm @@ -5,9 +5,9 @@ "e" = (/obj/effect/alien/weeds,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/vault5) "f" = (/obj/effect/alien/weeds,/obj/item/clothing/suit/storage/vest/tactical,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/vault5) "g" = (/obj/effect/alien/weeds,/obj/structure/bed/nest,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/vault5) -"h" = (/obj/effect/alien/weeds,/obj/random/multiple/minevault,/mob/living/simple_animal/hostile/alien/sentinel/praetorian,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/vault5) +"h" = (/obj/effect/alien/weeds,/obj/random/multiple/minevault,/mob/living/simple_mob/animal/space/alien/sentinel/praetorian,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/vault5) "i" = (/obj/effect/alien/weeds,/obj/effect/alien/egg,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/vault5) -"j" = (/obj/effect/alien/weeds,/obj/effect/alien/weeds/node,/mob/living/simple_animal/hostile/alien/queen/empress,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/vault5) +"j" = (/obj/effect/alien/weeds,/obj/effect/alien/weeds/node,/mob/living/simple_mob/animal/space/alien/queen/empress,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/vault5) "k" = (/obj/effect/alien/weeds,/obj/item/clothing/head/helmet/tac,/obj/item/weapon/gun/projectile/SVD,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/vault5) (1,1,1) = {" diff --git a/maps/submaps/surface_submaps/plains/Oldhouse.dmm b/maps/submaps/surface_submaps/plains/Oldhouse.dmm index 4e48624a9c..2c5d7537a7 100644 --- a/maps/submaps/surface_submaps/plains/Oldhouse.dmm +++ b/maps/submaps/surface_submaps/plains/Oldhouse.dmm @@ -1,874 +1,75 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"a" = ( -/turf/template_noop, -/area/template_noop) -"b" = ( -/turf/template_noop, -/area/submap/Oldhouse) -"c" = ( -/turf/simulated/wall/wood, -/area/submap/Oldhouse) -"d" = ( -/obj/structure/flora/tree/sif, -/turf/template_noop, -/area/submap/Oldhouse) -"e" = ( -/obj/structure/window/reinforced/full, -/turf/simulated/floor/wood, -/area/submap/Oldhouse) -"f" = ( -/obj/structure/table/woodentable, -/obj/effect/decal/cleanable/cobweb2, -/turf/simulated/floor/wood, -/area/submap/Oldhouse) -"g" = ( -/obj/item/stack/material/wood, -/obj/effect/decal/cleanable/cobweb, -/turf/simulated/floor/wood, -/area/submap/Oldhouse) -"h" = ( -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/wood, -/area/submap/Oldhouse) -"i" = ( -/turf/simulated/floor/wood, -/area/submap/Oldhouse) -"j" = ( -/turf/simulated/floor/wood{ - icon_state = "wood_broken6" - }, -/area/submap/Oldhouse) -"k" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/spiderling_remains, -/turf/simulated/floor/wood, -/area/submap/Oldhouse) -"l" = ( -/obj/structure/table/woodentable, -/turf/simulated/floor/wood, -/area/submap/Oldhouse) -"m" = ( -/obj/structure/closet/cabinet, -/turf/simulated/floor/wood, -/area/submap/Oldhouse) -"n" = ( -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/carpet/turcarpet, -/area/submap/Oldhouse) -"o" = ( -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/wood{ - icon_state = "wood_broken4" - }, -/area/submap/Oldhouse) -"p" = ( -/turf/simulated/floor/wood{ - icon_state = "wood_broken2" - }, -/area/submap/Oldhouse) -"q" = ( -/obj/item/stack/material/wood, -/turf/simulated/floor/wood, -/area/submap/Oldhouse) -"r" = ( -/turf/simulated/floor/carpet/turcarpet, -/area/submap/Oldhouse) -"s" = ( -/turf/simulated/floor/wood{ - icon_state = "wood_broken4" - }, -/area/submap/Oldhouse) -"t" = ( -/obj/structure/table/woodentable, -/obj/item/weapon/paper, -/obj/effect/decal/cleanable/cobweb2, -/turf/simulated/floor/wood, -/area/submap/Oldhouse) -"u" = ( -/obj/structure/simple_door/wood, -/turf/simulated/floor/wood, -/area/submap/Oldhouse) -"v" = ( -/obj/structure/bed/chair/wood{ - icon_state = "wooden_chair"; - dir = 1 - }, -/turf/simulated/floor/wood, -/area/submap/Oldhouse) -"w" = ( -/obj/item/stack/material/wood, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/wood, -/area/submap/Oldhouse) -"x" = ( -/obj/effect/decal/cleanable/cobweb, -/turf/simulated/floor/wood{ - icon_state = "wood_broken6" - }, -/area/submap/Oldhouse) -"y" = ( -/obj/effect/decal/remains/mouse, -/turf/simulated/floor/wood, -/area/submap/Oldhouse) -"z" = ( -/obj/structure/table/woodentable, -/obj/item/stack/material/wood, -/turf/simulated/floor/wood, -/area/submap/Oldhouse) -"A" = ( -/obj/structure/bed, -/obj/item/weapon/bedsheet, -/turf/simulated/floor/wood, -/area/submap/Oldhouse) -"B" = ( -/obj/structure/bed/chair/comfy/teal, -/turf/simulated/floor/wood, -/area/submap/Oldhouse) -"C" = ( -/obj/structure/bookcase, -/turf/simulated/floor/carpet/turcarpet, -/area/submap/Oldhouse) -"D" = ( -/obj/structure/table, -/turf/simulated/floor/wood, -/area/submap/Oldhouse) -"E" = ( -/obj/structure/table/woodentable, -/obj/item/trash/candle, -/turf/simulated/floor/wood, -/area/submap/Oldhouse) -"F" = ( -/obj/structure/table/woodentable, -/obj/item/weapon/pen/blue, -/turf/simulated/floor/wood, -/area/submap/Oldhouse) -"G" = ( -/obj/item/weapon/reagent_containers/food/snacks/chips, -/obj/item/weapon/reagent_containers/food/snacks/chips, -/turf/simulated/floor/carpet/turcarpet, -/area/submap/Oldhouse) -"H" = ( -/obj/structure/table/woodentable, -/obj/item/weapon/flame/candle, -/turf/simulated/floor/wood, -/area/submap/Oldhouse) -"I" = ( -/obj/structure/bed/chair/wood{ - icon_state = "wooden_chair"; - dir = 8 - }, -/turf/simulated/floor/carpet/turcarpet, -/area/submap/Oldhouse) -"J" = ( -/obj/effect/decal/remains/mouse, -/turf/simulated/floor/carpet/turcarpet, -/area/submap/Oldhouse) -"K" = ( -/obj/structure/table/woodentable, -/obj/item/weapon/paper, -/obj/item/weapon/paper, -/turf/simulated/floor/wood, -/area/submap/Oldhouse) -"L" = ( -/obj/structure/table/woodentable, -/obj/item/weapon/paper/crumpled, -/turf/simulated/floor/wood, -/area/submap/Oldhouse) -"M" = ( -/obj/structure/frame, -/turf/simulated/floor/wood, -/area/submap/Oldhouse) -"N" = ( -/mob/living/simple_animal/hostile/giant_spider{ - attack_armor_pen = 100; - attacktext = list("lightly bonked"); - desc = "Furry and brown, this spider is so goddamn fat you're surprised it even moves around."; - faction = "neutral"; - health = 400; - melee_damage_lower = 1; - melee_damage_upper = 3; - melee_miss_chance = 30; - move_speed = 5; - name = "Mr. Tuddly" - }, -/turf/simulated/floor/carpet/turcarpet, -/area/submap/Oldhouse) -"O" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/carpet/turcarpet, -/area/submap/Oldhouse) -"P" = ( -/obj/item/weapon/circuitboard/papershredder, -/turf/simulated/floor/wood, -/area/submap/Oldhouse) -"Q" = ( -/obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers, -/obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers, -/turf/simulated/floor/carpet/turcarpet, -/area/submap/Oldhouse) -"R" = ( -/obj/effect/decal/cleanable/spiderling_remains, -/turf/simulated/floor/wood, -/area/submap/Oldhouse) -"S" = ( -/obj/item/weapon/paper/crumpled, -/turf/simulated/floor/wood, -/area/submap/Oldhouse) -"T" = ( -/obj/structure/table/woodentable, -/obj/item/weapon/storage/backpack/satchel, -/turf/simulated/floor/wood, -/area/submap/Oldhouse) -"U" = ( -/obj/structure/table/rack, -/obj/item/clothing/suit/storage/hooded/wintercoat, -/obj/item/clothing/suit/storage/hooded/wintercoat, -/obj/item/clothing/head/hood/winter, -/obj/item/clothing/head/hood/winter, -/turf/simulated/floor/wood, -/area/submap/Oldhouse) -"V" = ( -/obj/item/device/flashlight, -/turf/simulated/floor/wood, -/area/submap/Oldhouse) -"W" = ( -/obj/structure/table/rack, -/obj/item/clothing/shoes/boots/winter, -/obj/item/clothing/shoes/boots/winter, -/obj/item/clothing/shoes/boots/winter, -/turf/simulated/floor/wood, -/area/submap/Oldhouse) -"X" = ( -/obj/structure/coatrack, -/turf/simulated/floor/wood, -/area/submap/Oldhouse) -"Y" = ( -/obj/structure/table/woodentable, -/turf/simulated/floor/wood{ - icon_state = "wood_broken6" - }, -/area/submap/Oldhouse) -"Z" = ( -/obj/structure/table/woodentable, -/turf/simulated/floor/wood{ - icon_state = "wood_broken2" - }, -/area/submap/Oldhouse) +"a" = (/turf/template_noop,/area/template_noop) +"b" = (/turf/template_noop,/area/submap/Oldhouse) +"c" = (/turf/simulated/wall/wood,/area/submap/Oldhouse) +"d" = (/obj/structure/flora/tree/sif,/turf/template_noop,/area/submap/Oldhouse) +"e" = (/obj/structure/window/reinforced/full,/turf/simulated/floor/wood,/area/submap/Oldhouse) +"f" = (/obj/structure/table/woodentable,/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor/wood,/area/submap/Oldhouse) +"g" = (/obj/item/stack/material/wood,/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/wood,/area/submap/Oldhouse) +"h" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/wood,/area/submap/Oldhouse) +"i" = (/turf/simulated/floor/wood,/area/submap/Oldhouse) +"j" = (/turf/simulated/floor/wood{icon_state = "wood_broken6"},/area/submap/Oldhouse) +"k" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/spiderling_remains,/turf/simulated/floor/wood,/area/submap/Oldhouse) +"l" = (/obj/structure/table/woodentable,/turf/simulated/floor/wood,/area/submap/Oldhouse) +"m" = (/obj/structure/closet/cabinet,/turf/simulated/floor/wood,/area/submap/Oldhouse) +"n" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/carpet/turcarpet,/area/submap/Oldhouse) +"o" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/wood{icon_state = "wood_broken4"},/area/submap/Oldhouse) +"p" = (/turf/simulated/floor/wood{icon_state = "wood_broken2"},/area/submap/Oldhouse) +"q" = (/obj/item/stack/material/wood,/turf/simulated/floor/wood,/area/submap/Oldhouse) +"r" = (/turf/simulated/floor/carpet/turcarpet,/area/submap/Oldhouse) +"s" = (/turf/simulated/floor/wood{icon_state = "wood_broken4"},/area/submap/Oldhouse) +"t" = (/obj/structure/table/woodentable,/obj/item/weapon/paper,/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor/wood,/area/submap/Oldhouse) +"u" = (/obj/structure/simple_door/wood,/turf/simulated/floor/wood,/area/submap/Oldhouse) +"v" = (/obj/structure/bed/chair/wood{icon_state = "wooden_chair"; dir = 1},/turf/simulated/floor/wood,/area/submap/Oldhouse) +"w" = (/obj/item/stack/material/wood,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/wood,/area/submap/Oldhouse) +"x" = (/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/wood{icon_state = "wood_broken6"},/area/submap/Oldhouse) +"y" = (/obj/effect/decal/remains/mouse,/turf/simulated/floor/wood,/area/submap/Oldhouse) +"z" = (/obj/structure/table/woodentable,/obj/item/stack/material/wood,/turf/simulated/floor/wood,/area/submap/Oldhouse) +"A" = (/obj/structure/bed,/obj/item/weapon/bedsheet,/turf/simulated/floor/wood,/area/submap/Oldhouse) +"B" = (/obj/structure/bed/chair/comfy/teal,/turf/simulated/floor/wood,/area/submap/Oldhouse) +"C" = (/obj/structure/bookcase,/turf/simulated/floor/carpet/turcarpet,/area/submap/Oldhouse) +"D" = (/obj/structure/table,/turf/simulated/floor/wood,/area/submap/Oldhouse) +"E" = (/obj/structure/table/woodentable,/obj/item/trash/candle,/turf/simulated/floor/wood,/area/submap/Oldhouse) +"F" = (/obj/structure/table/woodentable,/obj/item/weapon/pen/blue,/turf/simulated/floor/wood,/area/submap/Oldhouse) +"G" = (/obj/item/weapon/reagent_containers/food/snacks/chips,/obj/item/weapon/reagent_containers/food/snacks/chips,/turf/simulated/floor/carpet/turcarpet,/area/submap/Oldhouse) +"H" = (/obj/structure/table/woodentable,/obj/item/weapon/flame/candle,/turf/simulated/floor/wood,/area/submap/Oldhouse) +"I" = (/obj/structure/bed/chair/wood{icon_state = "wooden_chair"; dir = 8},/turf/simulated/floor/carpet/turcarpet,/area/submap/Oldhouse) +"J" = (/obj/effect/decal/remains/mouse,/turf/simulated/floor/carpet/turcarpet,/area/submap/Oldhouse) +"K" = (/obj/structure/table/woodentable,/obj/item/weapon/paper,/obj/item/weapon/paper,/turf/simulated/floor/wood,/area/submap/Oldhouse) +"L" = (/obj/structure/table/woodentable,/obj/item/weapon/paper/crumpled,/turf/simulated/floor/wood,/area/submap/Oldhouse) +"M" = (/obj/structure/frame,/turf/simulated/floor/wood,/area/submap/Oldhouse) +"N" = (/mob/living/simple_mob/animal/giant_spider{attack_armor_pen = 100; attacktext = list("lightly bonked"); desc = "Furry and brown, this spider is so goddamn fat you're surprised it even moves around."; faction = "neutral"; health = 400; melee_damage_lower = 1; melee_damage_upper = 3; melee_miss_chance = 30; move_speed = 5; name = "Mr. Tuddly"},/turf/simulated/floor/carpet/turcarpet,/area/submap/Oldhouse) +"O" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/carpet/turcarpet,/area/submap/Oldhouse) +"P" = (/obj/item/weapon/circuitboard/papershredder,/turf/simulated/floor/wood,/area/submap/Oldhouse) +"Q" = (/obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers,/obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers,/turf/simulated/floor/carpet/turcarpet,/area/submap/Oldhouse) +"R" = (/obj/effect/decal/cleanable/spiderling_remains,/turf/simulated/floor/wood,/area/submap/Oldhouse) +"S" = (/obj/item/weapon/paper/crumpled,/turf/simulated/floor/wood,/area/submap/Oldhouse) +"T" = (/obj/structure/table/woodentable,/obj/item/weapon/storage/backpack/satchel,/turf/simulated/floor/wood,/area/submap/Oldhouse) +"U" = (/obj/structure/table/rack,/obj/item/clothing/suit/storage/hooded/wintercoat,/obj/item/clothing/suit/storage/hooded/wintercoat,/obj/item/clothing/head/hood/winter,/obj/item/clothing/head/hood/winter,/turf/simulated/floor/wood,/area/submap/Oldhouse) +"V" = (/obj/item/device/flashlight,/turf/simulated/floor/wood,/area/submap/Oldhouse) +"W" = (/obj/structure/table/rack,/obj/item/clothing/shoes/boots/winter,/obj/item/clothing/shoes/boots/winter,/obj/item/clothing/shoes/boots/winter,/turf/simulated/floor/wood,/area/submap/Oldhouse) +"X" = (/obj/structure/coatrack,/turf/simulated/floor/wood,/area/submap/Oldhouse) +"Y" = (/obj/structure/table/woodentable,/turf/simulated/floor/wood{icon_state = "wood_broken6"},/area/submap/Oldhouse) +"Z" = (/obj/structure/table/woodentable,/turf/simulated/floor/wood{icon_state = "wood_broken2"},/area/submap/Oldhouse) (1,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(2,1,1) = {" -a -b -b -c -c -e -e -c -c -b -b -b -b -b -b -b -b -d -b -a -"} -(3,1,1) = {" -a -b -c -c -m -i -i -A -c -c -b -b -b -b -b -b -b -b -b -a -"} -(4,1,1) = {" -a -c -c -f -i -i -i -B -E -c -c -b -b -b -b -b -b -b -b -a -"} -(5,1,1) = {" -a -c -c -c -c -u -c -c -c -c -c -c -c -c -b -b -b -b -b -a -"} -(6,1,1) = {" -a -c -c -g -i -i -s -l -F -l -L -c -c -c -c -b -b -b -b -a -"} -(7,1,1) = {" -a -c -c -h -n -n -n -n -r -I -r -i -i -c -c -c -c -b -b -a -"} -(8,1,1) = {" -a -c -c -h -n -n -n -n -r -r -r -i -R -u -i -l -c -b -b -a -"} -(9,1,1) = {" -a -c -c -h -o -h -w -i -i -i -M -P -i -u -i -T -c -b -b -a -"} -(10,1,1) = {" -a -c -c -i -i -c -c -u -u -c -c -c -c -c -h -j -c -b -b -a -"} -(11,1,1) = {" -a -b -e -i -i -c -x -i -i -i -i -i -S -c -h -h -c -b -b -a -"} -(12,1,1) = {" -a -b -e -i -p -c -i -C -C -C -C -C -i -c -h -h -c -b -b -a -"} -(13,1,1) = {" -a -b -e -i -i -c -i -r -r -r -r -r -y -c -i -U -c -b -b -a -"} -(14,1,1) = {" -a -b -c -i -i -c -i -C -C -C -C -C -i -c -i -V -u -b -b -a -"} -(15,1,1) = {" -a -b -c -i -i -c -y -C -C -C -C -C -i -c -i -i -u -b -b -a -"} -(16,1,1) = {" -a -b -e -j -i -c -i -r -G -J -N -Q -i -c -i -W -c -b -b -a -"} -(17,1,1) = {" -a -b -e -i -q -c -i -C -C -C -C -C -s -c -i -X -c -b -b -a -"} -(18,1,1) = {" -a -b -e -i -i -c -i -i -i -i -i -i -y -c -S -i -c -b -b -a -"} -(19,1,1) = {" -a -c -c -h -i -c -c -u -u -c -c -c -c -c -i -i -c -b -b -a -"} -(20,1,1) = {" -a -c -c -h -i -i -i -i -i -h -h -q -i -u -i -Y -c -b -b -a -"} -(21,1,1) = {" -a -c -c -k -r -r -r -r -r -n -O -i -i -u -i -Z -c -b -b -a -"} -(22,1,1) = {" -a -c -c -h -r -r -r -r -r -r -n -i -i -c -c -c -c -b -b -a -"} -(23,1,1) = {" -a -c -c -h -s -i -z -D -D -K -l -c -c -c -c -b -b -b -b -a -"} -(24,1,1) = {" -a -c -c -c -c -u -c -c -c -c -c -c -c -c -b -b -b -b -b -a -"} -(25,1,1) = {" -a -c -c -l -i -i -i -i -H -c -c -b -b -d -b -b -b -b -b -a -"} -(26,1,1) = {" -a -b -c -c -t -v -i -A -c -c -b -b -b -b -b -b -b -b -b -a -"} -(27,1,1) = {" -a -d -b -c -c -e -e -c -c -b -b -b -b -b -b -b -b -b -b -a -"} -(28,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} +aaaaaaaaaaaaaaaaaaaaaaaaaaaa +abbcccccccbbbbbbbbcccccccbda +abcccccccceeecceeeccccccccba +accfcghhhiiiiiijiihhkhhclcca +acmicinnoiipiiiiqiiirrscitca +aeiiuinnhccccccccccirriuivea +aeiicsnnwcxiiiyiiicirrzciiea +acABclnniuiCrCCrCiuirrDciAca +accEcFrriuiCrCCGCiuirrDcHcca +abccclIriciCrCCJCichnrKcccba +abbccLrrMciCrCCNCichOnlccbba +abbbcciiPciCrCCQCicqiiccbbba +abbbcciRicSiyiiisyciiiccbbba +abbbcccuuccccccccccuucccdbba +abbbbcciihhhiiiiiSiiiccbbbba +abbbbbclTjhhUViWXiiYZcbbbbba +abbbbbcccccccuucccccccbbbbba +adbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbba +aaaaaaaaaaaaaaaaaaaaaaaaaaaa +"} \ No newline at end of file diff --git a/maps/submaps/surface_submaps/plains/PooledR.dmm b/maps/submaps/surface_submaps/plains/PooledR.dmm index 554c4cca8f..93d8a3f09f 100644 --- a/maps/submaps/surface_submaps/plains/PooledR.dmm +++ b/maps/submaps/surface_submaps/plains/PooledR.dmm @@ -11,10 +11,10 @@ "k" = (/obj/structure/flora/ausbushes,/turf/template_noop,/area/submap/PooledR) "l" = (/turf/simulated/floor/water,/area/submap/PooledR) "m" = (/obj/structure/flora/ausbushes/grassybush,/turf/template_noop,/area/submap/PooledR) -"n" = (/mob/living/simple_animal/fish/trout,/turf/simulated/floor/water,/area/submap/PooledR) -"o" = (/mob/living/simple_animal/fish/salmon,/turf/simulated/floor/water,/area/submap/PooledR) +"n" = (/mob/living/simple_mob/animal/passive/fish/trout,/turf/simulated/floor/water,/area/submap/PooledR) +"o" = (/mob/living/simple_mob/animal/passive/fish/salmon,/turf/simulated/floor/water,/area/submap/PooledR) "p" = (/turf/simulated/floor/water/deep,/area/submap/PooledR) -"q" = (/mob/living/simple_animal/fish/bass,/turf/simulated/floor/water/deep,/area/submap/PooledR) +"q" = (/mob/living/simple_mob/animal/passive/fish/bass,/turf/simulated/floor/water/deep,/area/submap/PooledR) (1,1,1) = {" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/maps/submaps/surface_submaps/plains/RationCache.dmm b/maps/submaps/surface_submaps/plains/RationCache.dmm index 600832aa18..0ddb58dd6f 100644 --- a/maps/submaps/surface_submaps/plains/RationCache.dmm +++ b/maps/submaps/surface_submaps/plains/RationCache.dmm @@ -1,7 +1,7 @@ "a" = (/turf/template_noop,/area/template_noop) "b" = (/turf/simulated/floor/outdoors/snow,/area/submap/RationCache) -"c" = (/mob/living/simple_animal/retaliate/diyaab{returns_home = 1},/turf/simulated/floor/outdoors/snow,/area/submap/RationCache) -"d" = (/mob/living/simple_animal/retaliate/diyaab{returns_home = 1},/turf/simulated/floor/outdoors/dirt,/area/submap/RationCache) +"c" = (/mob/living/simple_mob/animal/sif/diyaab,/turf/simulated/floor/outdoors/snow,/area/submap/RationCache) +"d" = (/mob/living/simple_mob/animal/sif/diyaab,/turf/simulated/floor/outdoors/dirt,/area/submap/RationCache) "e" = (/turf/simulated/floor/outdoors/dirt,/area/submap/RationCache) "f" = (/obj/item/trash/liquidfood,/obj/item/trash/liquidfood,/obj/item/trash/liquidfood,/obj/item/trash/liquidfood,/obj/item/trash/liquidfood,/obj/item/trash/liquidfood,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/RationCache) "g" = (/obj/machinery/portable_atmospherics/hydroponics/soil,/turf/simulated/floor/outdoors/dirt,/area/submap/RationCache) diff --git a/maps/submaps/surface_submaps/plains/Shakden.dmm b/maps/submaps/surface_submaps/plains/Shakden.dmm index 8720149d63..86f2057db1 100644 --- a/maps/submaps/surface_submaps/plains/Shakden.dmm +++ b/maps/submaps/surface_submaps/plains/Shakden.dmm @@ -4,9 +4,9 @@ "d" = (/turf/simulated/floor/outdoors/dirt{outdoors = 0},/area/submap/Shakden) "e" = (/obj/effect/decal/remains/mouse,/turf/simulated/floor/outdoors/dirt{outdoors = 0},/area/submap/Shakden) "f" = (/obj/item/weapon/reagent_containers/food/snacks/meat,/obj/item/weapon/reagent_containers/food/snacks/meat,/obj/item/weapon/reagent_containers/food/snacks/meat,/obj/item/weapon/reagent_containers/food/snacks/meat,/obj/item/weapon/reagent_containers/food/snacks/meat,/turf/simulated/floor/outdoors/dirt{outdoors = 0},/area/submap/Shakden) -"g" = (/mob/living/simple_animal/hostile/shantak{hostile = 0},/turf/simulated/floor/outdoors/dirt{outdoors = 0},/area/submap/Shakden) +"g" = (/mob/living/simple_mob/animal/sif/shantak/retaliate,/turf/simulated/floor/outdoors/dirt{outdoors = 0},/area/submap/Shakden) "h" = (/obj/item/weapon/reagent_containers/food/snacks/meat,/obj/item/weapon/reagent_containers/food/snacks/meat,/obj/item/weapon/reagent_containers/food/snacks/meat,/turf/simulated/floor/outdoors/dirt{outdoors = 0},/area/submap/Shakden) -"i" = (/mob/living/simple_animal/hostile/shantak{hostile = 0},/turf/simulated/floor/outdoors/dirt,/area/submap/Shakden) +"i" = (/mob/living/simple_mob/animal/sif/shantak/retaliate,/turf/simulated/floor/outdoors/dirt,/area/submap/Shakden) "j" = (/obj/item/weapon/reagent_containers/food/snacks/meat,/turf/simulated/floor/outdoors/dirt{outdoors = 0},/area/submap/Shakden) "k" = (/obj/item/weapon/reagent_containers/food/snacks/meat,/obj/item/weapon/reagent_containers/food/snacks/meat,/obj/item/weapon/reagent_containers/food/snacks/meat,/obj/item/weapon/reagent_containers/food/snacks/meat,/obj/item/weapon/material/knife/hook,/turf/simulated/floor/outdoors/dirt{outdoors = 0},/area/submap/Shakden) diff --git a/maps/submaps/surface_submaps/plains/plains.dm b/maps/submaps/surface_submaps/plains/plains.dm index c4e97e37d6..77ab822ed9 100644 --- a/maps/submaps/surface_submaps/plains/plains.dm +++ b/maps/submaps/surface_submaps/plains/plains.dm @@ -68,6 +68,7 @@ desc = "A bunch of marker beacons, scattered in a strange pattern." mappath = 'maps/submaps/surface_submaps/plains/beacons.dmm' cost = 5 + fixed_orientation = TRUE /datum/map_template/surface/plains/Epod name = "Emergency Pod" diff --git a/maps/submaps/surface_submaps/wilderness/Blackshuttledown.dmm b/maps/submaps/surface_submaps/wilderness/Blackshuttledown.dmm index 479bc4e523..7bf4c4d921 100644 --- a/maps/submaps/surface_submaps/wilderness/Blackshuttledown.dmm +++ b/maps/submaps/surface_submaps/wilderness/Blackshuttledown.dmm @@ -1,2083 +1,161 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"aa" = ( -/turf/template_noop, -/area/template_noop) -"ab" = ( -/turf/template_noop, -/area/submap/Blackshuttledown) -"ac" = ( -/obj/effect/decal/remains/human, -/turf/template_noop, -/area/submap/Blackshuttledown) -"ad" = ( -/turf/simulated/mineral/ignore_mapgen, -/area/submap/Blackshuttledown) -"ae" = ( -/obj/effect/decal/cleanable/blood, -/turf/template_noop, -/area/submap/Blackshuttledown) -"af" = ( -/obj/structure/flora/tree/sif, -/turf/template_noop, -/area/submap/Blackshuttledown) -"ag" = ( -/obj/structure/table/steel, -/turf/template_noop, -/area/submap/Blackshuttledown) -"ah" = ( -/mob/living/simple_animal/hostile/syndicate/ranged/poi, -/turf/template_noop, -/area/submap/Blackshuttledown) -"ai" = ( -/turf/template_noop, -/turf/simulated/shuttle/wall/dark{ - icon_state = "dark6"; - name = "Unknown Shuttle" - }, -/area/submap/Blackshuttledown) -"aj" = ( -/turf/simulated/shuttle/wall/dark{ - icon_state = "dark0"; - name = "Unknown Shuttle" - }, -/area/submap/Blackshuttledown) -"ak" = ( -/turf/template_noop, -/turf/simulated/shuttle/wall/dark{ - icon_state = "dark10"; - name = "Unknown Shuttle" - }, -/area/submap/Blackshuttledown) -"al" = ( -/obj/structure/shuttle/engine/heater{ - icon_state = "heater"; - dir = 4 - }, -/turf/simulated/shuttle/wall/dark{ - icon_state = "dark0"; - name = "Unknown Shuttle" - }, -/area/submap/Blackshuttledown) -"am" = ( -/obj/structure/shuttle/engine/propulsion{ - dir = 4; - icon_state = "propulsion_l" - }, -/turf/template_noop, -/area/submap/Blackshuttledown) -"an" = ( -/obj/machinery/light{ - dir = 1 - }, -/obj/structure/table/rack, -/obj/item/clothing/head/helmet/space, -/obj/item/clothing/head/helmet/space, -/obj/item/clothing/head/helmet/space, -/obj/item/clothing/head/helmet/space, -/obj/item/clothing/suit/space, -/obj/item/clothing/suit/space, -/obj/item/clothing/suit/space, -/obj/item/clothing/suit/space, -/obj/effect/floor_decal/borderfloor{ - dir = 9 - }, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"ao" = ( -/obj/structure/dispenser/oxygen, -/obj/effect/floor_decal/borderfloor{ - dir = 5 - }, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"ap" = ( -/obj/machinery/door/airlock/external{ - density = 1; - frequency = 1331; - id_tag = "merc_shuttle_outer"; - name = "Ship External Access"; - req_access = list(150) - }, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"aq" = ( -/obj/effect/floor_decal/corner/green/border{ - icon_state = "bordercolor"; - dir = 9 - }, -/turf/simulated/floor/tiled/white, -/area/submap/Blackshuttledown) -"ar" = ( -/obj/machinery/gibber, -/obj/effect/floor_decal/corner/green/border{ - icon_state = "bordercolor"; - dir = 1 - }, -/turf/simulated/floor/tiled/white, -/area/submap/Blackshuttledown) -"as" = ( -/obj/machinery/light{ - dir = 1 - }, -/obj/effect/floor_decal/corner/green/border{ - icon_state = "bordercolor"; - dir = 1 - }, -/turf/simulated/floor/tiled/white, -/area/submap/Blackshuttledown) -"at" = ( -/obj/machinery/bodyscanner{ - dir = 8 - }, -/obj/effect/floor_decal/corner/green/border{ - icon_state = "bordercolor"; - dir = 1 - }, -/turf/simulated/floor/tiled/white, -/area/submap/Blackshuttledown) -"au" = ( -/obj/machinery/body_scanconsole, -/obj/effect/floor_decal/corner/green/border{ - icon_state = "bordercolor"; - dir = 5 - }, -/turf/simulated/floor/tiled/white, -/area/submap/Blackshuttledown) -"av" = ( -/turf/simulated/floor/tiled/steel, -/turf/simulated/shuttle/wall/dark{ - icon_state = "dark5"; - name = "Unknown Shuttle" - }, -/area/submap/Blackshuttledown) -"aw" = ( -/turf/simulated/floor/tiled/steel_grid, -/area/submap/Blackshuttledown) -"ax" = ( -/obj/structure/table/steel, -/obj/item/weapon/gun/projectile/automatic/wt550, -/obj/item/weapon/gun/projectile/automatic/p90, -/turf/simulated/floor/tiled/steel_grid, -/area/submap/Blackshuttledown) -"ay" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"az" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"aA" = ( -/obj/machinery/door/airlock/external, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"aB" = ( -/obj/effect/floor_decal/corner/green/border{ - icon_state = "bordercolor"; - dir = 8 - }, -/turf/simulated/floor/tiled/white, -/area/submap/Blackshuttledown) -"aC" = ( -/obj/machinery/optable, -/turf/simulated/floor/tiled/white, -/area/submap/Blackshuttledown) -"aD" = ( -/obj/effect/decal/cleanable/blood, -/turf/simulated/floor/tiled/white, -/area/submap/Blackshuttledown) -"aE" = ( -/turf/simulated/floor/tiled/white, -/area/submap/Blackshuttledown) -"aF" = ( -/obj/machinery/organ_printer/flesh, -/obj/effect/floor_decal/corner/green/border{ - icon_state = "bordercolor"; - dir = 5 - }, -/turf/simulated/floor/tiled/white, -/area/submap/Blackshuttledown) -"aG" = ( -/turf/simulated/floor/tiled/steel, -/turf/simulated/shuttle/wall/dark{ - icon_state = "dark9"; - name = "Unknown Shuttle" - }, -/area/submap/Blackshuttledown) -"aH" = ( -/turf/simulated/floor/tiled/steel, -/turf/simulated/shuttle/wall/dark{ - icon_state = "dark6"; - name = "Unknown Shuttle" - }, -/area/submap/Blackshuttledown) -"aI" = ( -/mob/living/simple_animal/hostile/viscerator, -/mob/living/simple_animal/hostile/viscerator, -/mob/living/simple_animal/hostile/viscerator, -/turf/simulated/floor/tiled/steel_grid, -/area/submap/Blackshuttledown) -"aJ" = ( -/obj/structure/table/steel, -/obj/machinery/light/small{ - dir = 4; - pixel_y = 0 - }, -/turf/simulated/floor/tiled/steel_grid, -/area/submap/Blackshuttledown) -"aK" = ( -/obj/effect/floor_decal/borderfloor/corner{ - dir = 4 - }, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"aL" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"aM" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 5 - }, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"aN" = ( -/obj/effect/decal/cleanable/blood/drip, -/turf/simulated/floor/tiled/white, -/area/submap/Blackshuttledown) -"aO" = ( -/mob/living/simple_animal/hostile/syndicate/melee/poi, -/turf/simulated/floor/tiled/white, -/area/submap/Blackshuttledown) -"aP" = ( -/obj/machinery/light{ - dir = 4; - icon_state = "tube1"; - pixel_x = 0 - }, -/obj/effect/floor_decal/corner/green/border{ - icon_state = "bordercolor"; - dir = 4 - }, -/turf/simulated/floor/tiled/white, -/area/submap/Blackshuttledown) -"aQ" = ( -/obj/structure/table/steel, -/obj/effect/floor_decal/borderfloor/full, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"aR" = ( -/obj/structure/table/steel, -/obj/item/weapon/grenade/smokebomb, -/turf/simulated/floor/tiled/steel_grid, -/area/submap/Blackshuttledown) -"aS" = ( -/obj/effect/floor_decal/borderfloor/corner, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"aT" = ( -/obj/effect/floor_decal/borderfloor, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"aU" = ( -/obj/machinery/light{ - dir = 4; - icon_state = "tube1"; - pixel_x = 0 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 6 - }, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"aV" = ( -/obj/structure/table/standard, -/obj/item/weapon/storage/firstaid/surgery, -/obj/effect/floor_decal/corner/green/border{ - icon_state = "bordercolor"; - dir = 10 - }, -/turf/simulated/floor/tiled/white, -/area/submap/Blackshuttledown) -"aW" = ( -/obj/structure/table/standard, -/obj/item/weapon/tank/anesthetic, -/obj/effect/floor_decal/corner/green/border, -/turf/simulated/floor/tiled/white, -/area/submap/Blackshuttledown) -"aX" = ( -/obj/effect/floor_decal/corner/green/border, -/turf/simulated/floor/tiled/white, -/area/submap/Blackshuttledown) -"aY" = ( -/obj/structure/table/standard, -/obj/item/clothing/gloves/sterile, -/obj/item/clothing/gloves/sterile, -/obj/effect/floor_decal/corner/green/border, -/turf/simulated/floor/tiled/white, -/area/submap/Blackshuttledown) -"aZ" = ( -/obj/structure/table/standard, -/obj/item/weapon/reagent_containers/spray/sterilizine, -/obj/item/weapon/reagent_containers/spray/sterilizine, -/obj/effect/floor_decal/corner/green/border, -/turf/simulated/floor/tiled/white, -/area/submap/Blackshuttledown) -"ba" = ( -/obj/structure/table/standard, -/obj/item/weapon/storage/box/masks, -/obj/effect/floor_decal/corner/green/border{ - icon_state = "bordercolor"; - dir = 6 - }, -/turf/simulated/floor/tiled/white, -/area/submap/Blackshuttledown) -"bb" = ( -/obj/machinery/light{ - icon_state = "tube1"; - dir = 8 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 9 - }, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"bc" = ( -/obj/structure/bed/chair/office/dark{ - dir = 1 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 5 - }, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"bd" = ( -/obj/machinery/door/airlock/security{ - locked = 1 - }, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"be" = ( -/obj/machinery/door/airlock/glass, -/turf/simulated/floor/tiled/white, -/area/submap/Blackshuttledown) -"bf" = ( -/turf/simulated/floor/tiled/steel, -/turf/simulated/shuttle/wall/dark{ - icon_state = "dark10"; - name = "Unknown Shuttle" - }, -/area/submap/Blackshuttledown) -"bg" = ( -/obj/machinery/computer/communications, -/obj/effect/floor_decal/borderfloor{ - dir = 9 - }, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"bh" = ( -/obj/effect/floor_decal/borderfloor/corner{ - dir = 1 - }, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"bi" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 9 - }, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"bj" = ( -/obj/structure/closet/secure_closet/freezer/fridge, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"bk" = ( -/obj/structure/table/steel, -/obj/item/weapon/material/knife, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"bl" = ( -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"bm" = ( -/obj/machinery/light{ - dir = 1 - }, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"bn" = ( -/mob/living/simple_animal/hostile/syndicate/ranged/poi, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"bo" = ( -/obj/structure/table/steel, -/obj/random/toolbox, -/turf/simulated/floor/tiled/yellow, -/area/submap/Blackshuttledown) -"bp" = ( -/obj/structure/table/steel, -/obj/machinery/light/small{ - dir = 4; - pixel_y = 0 - }, -/turf/simulated/floor/tiled/yellow, -/area/submap/Blackshuttledown) -"bq" = ( -/obj/structure/grille, -/obj/structure/window/reinforced{ - dir = 1 - }, -/obj/structure/window/reinforced{ - dir = 8 - }, -/obj/structure/window/reinforced{ - dir = 4 - }, -/turf/simulated/floor/plating, -/area/submap/Blackshuttledown) -"br" = ( -/obj/structure/table/steel, -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"bs" = ( -/obj/machinery/light{ - icon_state = "tube1"; - dir = 8 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"bt" = ( -/obj/machinery/light{ - dir = 4; - icon_state = "tube1"; - pixel_x = 0 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"bu" = ( -/obj/item/weapon/stool, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"bv" = ( -/obj/structure/table/steel, -/obj/random/projectile, -/turf/simulated/floor/tiled/yellow, -/area/submap/Blackshuttledown) -"bw" = ( -/turf/simulated/floor/tiled/yellow, -/area/submap/Blackshuttledown) -"bx" = ( -/obj/structure/grille, -/obj/structure/window/reinforced{ - dir = 4 - }, -/obj/structure/window/reinforced{ - dir = 8 - }, -/turf/simulated/floor/plating, -/area/submap/Blackshuttledown) -"by" = ( -/obj/machinery/door/airlock/glass, -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"bz" = ( -/obj/effect/floor_decal/corner/grey, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"bA" = ( -/obj/machinery/door/airlock/glass, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"bB" = ( -/obj/structure/table/steel, -/obj/item/pizzabox, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"bC" = ( -/obj/structure/table/steel, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"bD" = ( -/obj/machinery/door/airlock, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"bE" = ( -/obj/machinery/door/airlock/glass, -/obj/effect/floor_decal/borderfloor, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"bF" = ( -/obj/effect/floor_decal/borderfloor/corner{ - dir = 8 - }, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"bG" = ( -/obj/structure/grille, -/obj/structure/window/reinforced, -/obj/structure/window/reinforced{ - dir = 8 - }, -/obj/structure/window/reinforced{ - dir = 4 - }, -/turf/simulated/floor/plating, -/area/submap/Blackshuttledown) -"bH" = ( -/obj/machinery/power/apc{ - dir = 8; - name = "BSD APC"; - pixel_x = -24 - }, -/turf/simulated/floor/tiled/yellow, -/area/submap/Blackshuttledown) -"bI" = ( -/mob/living/simple_animal/hostile/syndicate/melee/poi, -/turf/simulated/floor/tiled/yellow, -/area/submap/Blackshuttledown) -"bJ" = ( -/obj/machinery/computer/area_atmos, -/obj/effect/floor_decal/borderfloor{ - dir = 10 - }, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"bK" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/mob/living/simple_animal/hostile/syndicate/ranged/laser/poi, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"bL" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 10 - }, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"bM" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"bN" = ( -/obj/structure/table/steel, -/obj/item/weapon/paper{ - info = "We need to take a short stop. The engine's are in need of minor repairs due to turbulence, should be a week's time. We've got reserve food supplies but pleanty of locale fauna to subsist on too if need be. PCRC is keeping most of there assets near New Reykjavik and locale authorities are more mindful then most to travel in this kind of weather. Our outfit should be at the rendezvous point in less then ten days assuming the upper ecehelon hasn't dropped ties with us yet."; - name = "Operation Progress/M-53" - }, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"bO" = ( -/obj/structure/table/steel, -/obj/item/weapon/paper_bin, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"bP" = ( -/obj/machinery/light, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"bQ" = ( -/obj/structure/closet/toolcloset, -/turf/simulated/floor/tiled/yellow, -/area/submap/Blackshuttledown) -"bR" = ( -/obj/machinery/portable_atmospherics/canister/empty/oxygen, -/turf/simulated/floor/tiled/yellow, -/area/submap/Blackshuttledown) -"bS" = ( -/obj/machinery/atmospherics/pipe/tank/oxygen, -/obj/machinery/light/small{ - dir = 4; - pixel_y = 0 - }, -/turf/simulated/floor/tiled/yellow, -/area/submap/Blackshuttledown) -"bT" = ( -/obj/machinery/light{ - icon_state = "tube1"; - dir = 8 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 10 - }, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"bU" = ( -/obj/structure/bed/chair/office/dark, -/obj/effect/floor_decal/borderfloor{ - dir = 6 - }, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"bV" = ( -/obj/structure/table/steel, -/turf/simulated/floor/tiled/steel_grid, -/area/submap/Blackshuttledown) -"bW" = ( -/obj/effect/floor_decal/borderfloor/corner{ - dir = 4 - }, -/obj/effect/floor_decal/borderfloor/corner{ - dir = 4 - }, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"bX" = ( -/obj/machinery/light{ - dir = 4; - icon_state = "tube1"; - pixel_x = 0 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 5 - }, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"bY" = ( -/obj/structure/bed, -/obj/item/weapon/bedsheet, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"bZ" = ( -/obj/machinery/door/airlock, -/turf/simulated/floor/tiled/hydro, -/area/submap/Blackshuttledown) -"ca" = ( -/turf/simulated/floor/tiled/hydro, -/area/submap/Blackshuttledown) -"cb" = ( -/mob/living/simple_animal/hostile/viscerator, -/turf/simulated/floor/tiled/steel_grid, -/area/submap/Blackshuttledown) -"cc" = ( -/obj/structure/table/steel, -/obj/item/weapon/gun/projectile/pistol, -/obj/machinery/light/small{ - dir = 4; - pixel_y = 0 - }, -/turf/simulated/floor/tiled/steel_grid, -/area/submap/Blackshuttledown) -"cd" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 6 - }, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"ce" = ( -/obj/structure/bed, -/obj/item/weapon/bedsheet, -/obj/structure/bed, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"cf" = ( -/obj/machinery/light/small{ - dir = 4; - pixel_y = 0 - }, -/turf/simulated/floor/tiled/hydro, -/area/submap/Blackshuttledown) -"cg" = ( -/mob/living/simple_animal/hostile/viscerator, -/mob/living/simple_animal/hostile/viscerator, -/turf/simulated/floor/tiled/steel_grid, -/area/submap/Blackshuttledown) -"ch" = ( -/obj/structure/table/steel, -/obj/random/energy, -/turf/simulated/floor/tiled/steel_grid, -/area/submap/Blackshuttledown) -"ci" = ( -/obj/structure/toilet{ - dir = 1 - }, -/turf/simulated/floor/tiled/hydro, -/area/submap/Blackshuttledown) -"cj" = ( -/obj/machinery/light, -/obj/structure/table/rack, -/obj/item/clothing/head/helmet/space, -/obj/item/clothing/head/helmet/space, -/obj/item/clothing/head/helmet/space, -/obj/item/clothing/head/helmet/space, -/obj/item/clothing/suit/space, -/obj/item/clothing/suit/space, -/obj/item/clothing/suit/space, -/obj/item/clothing/suit/space, -/obj/effect/floor_decal/borderfloor{ - dir = 10 - }, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"ck" = ( -/obj/structure/dispenser/oxygen, -/obj/effect/floor_decal/borderfloor{ - dir = 6 - }, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"cl" = ( -/obj/structure/table/woodentable, -/obj/random/projectile, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"cm" = ( -/obj/structure/bed, -/obj/item/weapon/bedsheet, -/obj/machinery/light, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"cn" = ( -/obj/structure/table/woodentable, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"co" = ( -/obj/structure/bed, -/obj/item/weapon/bedsheet, -/obj/item/toy/plushie/spider, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"cp" = ( -/turf/template_noop, -/turf/simulated/shuttle/wall/dark{ - icon_state = "dark5"; - name = "Unknown Shuttle" - }, -/area/submap/Blackshuttledown) -"cq" = ( -/turf/template_noop, -/turf/simulated/shuttle/wall/dark{ - icon_state = "dark9"; - name = "Unknown Shuttle" - }, -/area/submap/Blackshuttledown) -"EI" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/mob/living/simple_animal/hostile/syndicate/melee/poi, -/turf/simulated/floor/tiled/steel, -/area/submap/Blackshuttledown) -"SN" = ( -/mob/living/simple_animal/hostile/syndicate/ranged/laser/poi, -/turf/template_noop, -/area/submap/Blackshuttledown) +"aa" = (/turf/template_noop,/area/template_noop) +"ab" = (/turf/template_noop,/area/submap/Blackshuttledown) +"ac" = (/obj/effect/decal/remains/human,/turf/template_noop,/area/submap/Blackshuttledown) +"ad" = (/turf/simulated/mineral/ignore_mapgen,/area/submap/Blackshuttledown) +"ae" = (/obj/effect/decal/cleanable/blood,/turf/template_noop,/area/submap/Blackshuttledown) +"af" = (/obj/structure/flora/tree/sif,/turf/template_noop,/area/submap/Blackshuttledown) +"ag" = (/obj/structure/table/steel,/turf/template_noop,/area/submap/Blackshuttledown) +"ah" = (/mob/living/simple_mob/humanoid/merc/ranged/smg/poi,/turf/template_noop,/area/submap/Blackshuttledown) +"ai" = (/turf/template_noop,/turf/simulated/shuttle/wall/dark{icon_state = "dark6"; name = "Unknown Shuttle"},/area/submap/Blackshuttledown) +"aj" = (/turf/simulated/shuttle/wall/dark{icon_state = "dark0"; name = "Unknown Shuttle"},/area/submap/Blackshuttledown) +"ak" = (/turf/template_noop,/turf/simulated/shuttle/wall/dark{icon_state = "dark10"; name = "Unknown Shuttle"},/area/submap/Blackshuttledown) +"al" = (/obj/structure/shuttle/engine/heater{icon_state = "heater"; dir = 4},/turf/simulated/shuttle/wall/dark{icon_state = "dark0"; name = "Unknown Shuttle"},/area/submap/Blackshuttledown) +"am" = (/obj/structure/shuttle/engine/propulsion{dir = 4; icon_state = "propulsion_l"},/turf/template_noop,/area/submap/Blackshuttledown) +"an" = (/obj/machinery/light{dir = 1},/obj/structure/table/rack,/obj/item/clothing/head/helmet/space,/obj/item/clothing/head/helmet/space,/obj/item/clothing/head/helmet/space,/obj/item/clothing/head/helmet/space,/obj/item/clothing/suit/space,/obj/item/clothing/suit/space,/obj/item/clothing/suit/space,/obj/item/clothing/suit/space,/obj/effect/floor_decal/borderfloor{dir = 9},/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"ao" = (/obj/structure/dispenser/oxygen,/obj/effect/floor_decal/borderfloor{dir = 5},/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"ap" = (/obj/machinery/door/airlock/external{density = 1; frequency = 1331; id_tag = "merc_shuttle_outer"; name = "Ship External Access"; req_access = list(150)},/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"aq" = (/obj/effect/floor_decal/corner/green/border{icon_state = "bordercolor"; dir = 9},/turf/simulated/floor/tiled/white,/area/submap/Blackshuttledown) +"ar" = (/obj/machinery/gibber,/obj/effect/floor_decal/corner/green/border{icon_state = "bordercolor"; dir = 1},/turf/simulated/floor/tiled/white,/area/submap/Blackshuttledown) +"as" = (/obj/machinery/light{dir = 1},/obj/effect/floor_decal/corner/green/border{icon_state = "bordercolor"; dir = 1},/turf/simulated/floor/tiled/white,/area/submap/Blackshuttledown) +"at" = (/obj/machinery/bodyscanner{dir = 8},/obj/effect/floor_decal/corner/green/border{icon_state = "bordercolor"; dir = 1},/turf/simulated/floor/tiled/white,/area/submap/Blackshuttledown) +"au" = (/obj/machinery/body_scanconsole,/obj/effect/floor_decal/corner/green/border{icon_state = "bordercolor"; dir = 5},/turf/simulated/floor/tiled/white,/area/submap/Blackshuttledown) +"av" = (/turf/simulated/floor/tiled/steel,/turf/simulated/shuttle/wall/dark{icon_state = "dark5"; name = "Unknown Shuttle"},/area/submap/Blackshuttledown) +"aw" = (/turf/simulated/floor/tiled/steel_grid,/area/submap/Blackshuttledown) +"ax" = (/obj/structure/table/steel,/obj/item/weapon/gun/projectile/automatic/wt550,/obj/item/weapon/gun/projectile/automatic/p90,/turf/simulated/floor/tiled/steel_grid,/area/submap/Blackshuttledown) +"ay" = (/obj/effect/floor_decal/borderfloor{dir = 8},/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"az" = (/obj/effect/floor_decal/borderfloor{dir = 4},/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"aA" = (/obj/machinery/door/airlock/external,/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"aB" = (/obj/effect/floor_decal/corner/green/border{icon_state = "bordercolor"; dir = 8},/turf/simulated/floor/tiled/white,/area/submap/Blackshuttledown) +"aC" = (/obj/machinery/optable,/turf/simulated/floor/tiled/white,/area/submap/Blackshuttledown) +"aD" = (/obj/effect/decal/cleanable/blood,/turf/simulated/floor/tiled/white,/area/submap/Blackshuttledown) +"aE" = (/turf/simulated/floor/tiled/white,/area/submap/Blackshuttledown) +"aF" = (/obj/machinery/organ_printer/flesh,/obj/effect/floor_decal/corner/green/border{icon_state = "bordercolor"; dir = 5},/turf/simulated/floor/tiled/white,/area/submap/Blackshuttledown) +"aG" = (/turf/simulated/floor/tiled/steel,/turf/simulated/shuttle/wall/dark{icon_state = "dark9"; name = "Unknown Shuttle"},/area/submap/Blackshuttledown) +"aH" = (/turf/simulated/floor/tiled/steel,/turf/simulated/shuttle/wall/dark{icon_state = "dark6"; name = "Unknown Shuttle"},/area/submap/Blackshuttledown) +"aI" = (/mob/living/simple_mob/mechanical/viscerator,/mob/living/simple_mob/mechanical/viscerator,/mob/living/simple_mob/mechanical/viscerator,/turf/simulated/floor/tiled/steel_grid,/area/submap/Blackshuttledown) +"aJ" = (/obj/structure/table/steel,/obj/machinery/light/small{dir = 4; pixel_y = 0},/turf/simulated/floor/tiled/steel_grid,/area/submap/Blackshuttledown) +"aK" = (/obj/effect/floor_decal/borderfloor/corner{dir = 4},/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"aL" = (/obj/effect/floor_decal/borderfloor{dir = 1},/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"aM" = (/obj/effect/floor_decal/borderfloor{dir = 5},/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"aN" = (/obj/effect/decal/cleanable/blood/drip,/turf/simulated/floor/tiled/white,/area/submap/Blackshuttledown) +"aO" = (/mob/living/simple_mob/humanoid/merc/melee/sword/poi,/turf/simulated/floor/tiled/white,/area/submap/Blackshuttledown) +"aP" = (/obj/machinery/light{dir = 4; icon_state = "tube1"; pixel_x = 0},/obj/effect/floor_decal/corner/green/border{icon_state = "bordercolor"; dir = 4},/turf/simulated/floor/tiled/white,/area/submap/Blackshuttledown) +"aQ" = (/obj/structure/table/steel,/obj/effect/floor_decal/borderfloor/full,/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"aR" = (/obj/structure/table/steel,/obj/item/weapon/grenade/smokebomb,/turf/simulated/floor/tiled/steel_grid,/area/submap/Blackshuttledown) +"aS" = (/obj/effect/floor_decal/borderfloor/corner,/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"aT" = (/obj/effect/floor_decal/borderfloor,/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"aU" = (/obj/machinery/light{dir = 4; icon_state = "tube1"; pixel_x = 0},/obj/effect/floor_decal/borderfloor{dir = 6},/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"aV" = (/obj/structure/table/standard,/obj/item/weapon/storage/firstaid/surgery,/obj/effect/floor_decal/corner/green/border{icon_state = "bordercolor"; dir = 10},/turf/simulated/floor/tiled/white,/area/submap/Blackshuttledown) +"aW" = (/obj/structure/table/standard,/obj/item/weapon/tank/anesthetic,/obj/effect/floor_decal/corner/green/border,/turf/simulated/floor/tiled/white,/area/submap/Blackshuttledown) +"aX" = (/obj/effect/floor_decal/corner/green/border,/turf/simulated/floor/tiled/white,/area/submap/Blackshuttledown) +"aY" = (/obj/structure/table/standard,/obj/item/clothing/gloves/sterile,/obj/item/clothing/gloves/sterile,/obj/effect/floor_decal/corner/green/border,/turf/simulated/floor/tiled/white,/area/submap/Blackshuttledown) +"aZ" = (/obj/structure/table/standard,/obj/item/weapon/reagent_containers/spray/sterilizine,/obj/item/weapon/reagent_containers/spray/sterilizine,/obj/effect/floor_decal/corner/green/border,/turf/simulated/floor/tiled/white,/area/submap/Blackshuttledown) +"ba" = (/obj/structure/table/standard,/obj/item/weapon/storage/box/masks,/obj/effect/floor_decal/corner/green/border{icon_state = "bordercolor"; dir = 6},/turf/simulated/floor/tiled/white,/area/submap/Blackshuttledown) +"bb" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/effect/floor_decal/borderfloor{dir = 9},/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"bc" = (/obj/structure/bed/chair/office/dark{dir = 1},/obj/effect/floor_decal/borderfloor{dir = 5},/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"bd" = (/obj/machinery/door/airlock/security{locked = 1},/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"be" = (/obj/machinery/door/airlock/glass,/turf/simulated/floor/tiled/white,/area/submap/Blackshuttledown) +"bf" = (/turf/simulated/floor/tiled/steel,/turf/simulated/shuttle/wall/dark{icon_state = "dark10"; name = "Unknown Shuttle"},/area/submap/Blackshuttledown) +"bg" = (/obj/machinery/computer/communications,/obj/effect/floor_decal/borderfloor{dir = 9},/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"bh" = (/obj/effect/floor_decal/borderfloor/corner{dir = 1},/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"bi" = (/obj/effect/floor_decal/borderfloor{dir = 9},/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"bj" = (/obj/structure/closet/secure_closet/freezer/fridge,/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"bk" = (/obj/structure/table/steel,/obj/item/weapon/material/knife,/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"bl" = (/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"bm" = (/obj/machinery/light{dir = 1},/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"bn" = (/mob/living/simple_mob/humanoid/merc/ranged/smg/poi,/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"bo" = (/obj/structure/table/steel,/obj/random/toolbox,/turf/simulated/floor/tiled/yellow,/area/submap/Blackshuttledown) +"bp" = (/obj/structure/table/steel,/obj/machinery/light/small{dir = 4; pixel_y = 0},/turf/simulated/floor/tiled/yellow,/area/submap/Blackshuttledown) +"bq" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/submap/Blackshuttledown) +"br" = (/obj/structure/table/steel,/obj/effect/floor_decal/borderfloor{dir = 8},/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"bs" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/effect/floor_decal/borderfloor{dir = 8},/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"bt" = (/obj/machinery/light{dir = 4; icon_state = "tube1"; pixel_x = 0},/obj/effect/floor_decal/borderfloor{dir = 4},/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"bu" = (/obj/item/weapon/stool,/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"bv" = (/obj/structure/table/steel,/obj/random/projectile,/turf/simulated/floor/tiled/yellow,/area/submap/Blackshuttledown) +"bw" = (/turf/simulated/floor/tiled/yellow,/area/submap/Blackshuttledown) +"bx" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/submap/Blackshuttledown) +"by" = (/obj/machinery/door/airlock/glass,/obj/effect/floor_decal/borderfloor{dir = 1},/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"bz" = (/obj/effect/floor_decal/corner/grey,/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"bA" = (/obj/machinery/door/airlock/glass,/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"bB" = (/obj/structure/table/steel,/obj/item/pizzabox,/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"bC" = (/obj/structure/table/steel,/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"bD" = (/obj/machinery/door/airlock,/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"bE" = (/obj/machinery/door/airlock/glass,/obj/effect/floor_decal/borderfloor,/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"bF" = (/obj/effect/floor_decal/borderfloor/corner{dir = 8},/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"bG" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/submap/Blackshuttledown) +"bH" = (/obj/machinery/power/apc{dir = 8; name = "BSD APC"; pixel_x = -24},/turf/simulated/floor/tiled/yellow,/area/submap/Blackshuttledown) +"bI" = (/mob/living/simple_mob/humanoid/merc/melee/sword/poi,/turf/simulated/floor/tiled/yellow,/area/submap/Blackshuttledown) +"bJ" = (/obj/machinery/computer/area_atmos,/obj/effect/floor_decal/borderfloor{dir = 10},/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"bK" = (/mob/living/simple_mob/humanoid/merc/ranged/laser/poi,/turf/template_noop,/area/submap/Blackshuttledown) +"bL" = (/obj/effect/floor_decal/borderfloor{dir = 10},/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"bM" = (/obj/effect/floor_decal/borderfloor{dir = 4},/obj/effect/floor_decal/borderfloor{dir = 4},/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"bN" = (/obj/structure/table/steel,/obj/item/weapon/paper{info = "We need to take a short stop. The engine's are in need of minor repairs due to turbulence, should be a week's time. We've got reserve food supplies but pleanty of locale fauna to subsist on too if need be. PCRC is keeping most of there assets near New Reykjavik and locale authorities are more mindful then most to travel in this kind of weather. Our outfit should be at the rendezvous point in less then ten days assuming the upper ecehelon hasn't dropped ties with us yet."; name = "Operation Progress/M-53"},/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"bO" = (/obj/structure/table/steel,/obj/item/weapon/paper_bin,/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"bP" = (/obj/machinery/light,/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"bQ" = (/obj/structure/closet/toolcloset,/turf/simulated/floor/tiled/yellow,/area/submap/Blackshuttledown) +"bR" = (/obj/machinery/portable_atmospherics/canister/empty/oxygen,/turf/simulated/floor/tiled/yellow,/area/submap/Blackshuttledown) +"bS" = (/obj/machinery/atmospherics/pipe/tank/oxygen,/obj/machinery/light/small{dir = 4; pixel_y = 0},/turf/simulated/floor/tiled/yellow,/area/submap/Blackshuttledown) +"bT" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/effect/floor_decal/borderfloor{dir = 10},/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"bU" = (/obj/structure/bed/chair/office/dark,/obj/effect/floor_decal/borderfloor{dir = 6},/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"bV" = (/obj/structure/table/steel,/turf/simulated/floor/tiled/steel_grid,/area/submap/Blackshuttledown) +"bW" = (/obj/effect/floor_decal/borderfloor/corner{dir = 4},/obj/effect/floor_decal/borderfloor/corner{dir = 4},/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"bX" = (/obj/machinery/light{dir = 4; icon_state = "tube1"; pixel_x = 0},/obj/effect/floor_decal/borderfloor{dir = 5},/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"bY" = (/obj/structure/bed,/obj/item/weapon/bedsheet,/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"bZ" = (/obj/machinery/door/airlock,/turf/simulated/floor/tiled/hydro,/area/submap/Blackshuttledown) +"ca" = (/turf/simulated/floor/tiled/hydro,/area/submap/Blackshuttledown) +"cb" = (/mob/living/simple_mob/mechanical/viscerator,/turf/simulated/floor/tiled/steel_grid,/area/submap/Blackshuttledown) +"cc" = (/obj/structure/table/steel,/obj/item/weapon/gun/projectile/pistol,/obj/machinery/light/small{dir = 4; pixel_y = 0},/turf/simulated/floor/tiled/steel_grid,/area/submap/Blackshuttledown) +"cd" = (/obj/effect/floor_decal/borderfloor{dir = 6},/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"ce" = (/obj/structure/bed,/obj/item/weapon/bedsheet,/obj/structure/bed,/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"cf" = (/obj/machinery/light/small{dir = 4; pixel_y = 0},/turf/simulated/floor/tiled/hydro,/area/submap/Blackshuttledown) +"cg" = (/mob/living/simple_mob/mechanical/viscerator,/mob/living/simple_mob/mechanical/viscerator,/turf/simulated/floor/tiled/steel_grid,/area/submap/Blackshuttledown) +"ch" = (/obj/structure/table/steel,/obj/random/energy,/turf/simulated/floor/tiled/steel_grid,/area/submap/Blackshuttledown) +"ci" = (/obj/structure/toilet{dir = 1},/turf/simulated/floor/tiled/hydro,/area/submap/Blackshuttledown) +"cj" = (/obj/machinery/light,/obj/structure/table/rack,/obj/item/clothing/head/helmet/space,/obj/item/clothing/head/helmet/space,/obj/item/clothing/head/helmet/space,/obj/item/clothing/head/helmet/space,/obj/item/clothing/suit/space,/obj/item/clothing/suit/space,/obj/item/clothing/suit/space,/obj/item/clothing/suit/space,/obj/effect/floor_decal/borderfloor{dir = 10},/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"ck" = (/obj/structure/dispenser/oxygen,/obj/effect/floor_decal/borderfloor{dir = 6},/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"cl" = (/obj/structure/table/woodentable,/obj/random/projectile,/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"cm" = (/obj/structure/bed,/obj/item/weapon/bedsheet,/obj/machinery/light,/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"cn" = (/obj/structure/table/woodentable,/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"co" = (/obj/structure/bed,/obj/item/weapon/bedsheet,/obj/item/toy/plushie/spider,/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"cp" = (/turf/template_noop,/turf/simulated/shuttle/wall/dark{icon_state = "dark5"; name = "Unknown Shuttle"},/area/submap/Blackshuttledown) +"cq" = (/turf/template_noop,/turf/simulated/shuttle/wall/dark{icon_state = "dark9"; name = "Unknown Shuttle"},/area/submap/Blackshuttledown) +"cr" = (/obj/effect/floor_decal/borderfloor{dir = 4},/mob/living/simple_mob/humanoid/merc/melee/sword/poi,/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) +"cs" = (/obj/effect/floor_decal/borderfloor{dir = 4},/mob/living/simple_mob/humanoid/merc/ranged/laser/poi,/turf/simulated/floor/tiled/steel,/area/submap/Blackshuttledown) (1,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -"} -(2,1,1) = {" -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -"} -(3,1,1) = {" -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -af -ab -ab -ab -ab -ab -ab -ab -ab -ab -af -ab -ab -ab -ab -ab -ab -ad -ab -ab -ab -ab -aa -"} -(4,1,1) = {" -aa -ab -ab -ab -af -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -af -ab -ad -ad -ad -ab -ab -ab -aa -"} -(5,1,1) = {" -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ad -ad -ad -ad -ab -af -ab -aa -"} -(6,1,1) = {" -aa -ab -ab -ab -ad -ab -ab -ab -ab -af -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -"} -(7,1,1) = {" -aa -ac -ab -ab -ad -ad -ab -ab -ab -ab -ab -ab -ab -aH -aj -bq -bx -bx -bG -aj -av -ab -ab -ab -ab -ab -ab -ab -ac -ab -ab -ab -ab -ab -aa -"} -(8,1,1) = {" -aa -ab -ae -ab -ad -ad -ad -ab -ab -ab -ab -ab -aH -aj -bg -br -br -br -br -bJ -aj -av -ab -ab -ab -ab -ab -ab -ab -ab -ac -ab -ad -ab -aa -"} -(9,1,1) = {" -aa -ab -ab -ab -ab -ad -ad -ai -aj -aj -av -aH -aj -bb -bh -bl -bl -bl -bl -bF -bT -aj -av -aH -aj -aj -cp -ab -ab -ab -ab -ad -ad -ad -aa -"} -(10,1,1) = {" -aa -ab -ab -ab -ab -ab -ab -aj -aj -aj -aj -aj -aQ -bc -az -az -aK -aS -az -bK -bU -aQ -aj -aj -aj -aj -aj -ab -ab -ab -ad -ad -ad -ad -aa -"} -(11,1,1) = {" -aa -ab -ab -ab -ab -ac -af -aj -aj -aj -aj -aj -aj -aj -aj -aj -by -bE -aj -aj -aj -aj -aj -aj -aj -aj -aj -af -ab -ab -ab -af -ab -ab -aa -"} -(12,1,1) = {" -aa -ab -ab -ab -ab -ab -ab -aj -aj -aj -aw -aI -aw -bd -bi -bs -bh -bF -bs -bL -bd -aw -cb -cg -aj -aj -aj -ab -af -ab -ab -ab -ab -ac -aa -"} -(13,1,1) = {" -aa -ab -ab -ab -af -ab -ab -ak -aj -aj -ax -aJ -aR -aj -aL -bl -bl -bl -bl -aT -aj -bV -cc -ch -aj -aj -cq -ab -ab -ae -ab -ab -ab -ab -aa -"} -(14,1,1) = {" -aa -ab -ab -ab -ab -ab -ab -ab -aj -aj -aj -aj -aj -aj -aL -bl -bz -bl -bl -aT -aj -aj -aj -aj -aj -aj -ab -ab -ab -ab -ab -ab -ab -ab -aa -"} -(15,1,1) = {" -aa -ab -ab -ad -ab -ab -ab -ab -aj -an -ay -ay -ay -ay -bh -bl -bl -bl -bl -bF -ay -ay -ay -ay -cj -aj -ab -ab -ab -ab -ab -af -ab -ab -aa -"} -(16,1,1) = {" -aa -ad -ad -ad -ab -ag -ag -ag -aj -ao -az -aK -aS -az -az -bt -bl -bl -bt -bM -az -bW -aS -EI -ck -aj -ag -ag -ag -ab -ab -ab -ab -ab -aa -"} -(17,1,1) = {" -aa -ad -ad -ab -ab -ag -ah -ab -aj -aj -aj -aL -aT -aj -aj -aj -bA -bA -aj -aj -aj -aL -aT -aj -aj -aj -SN -ab -ag -ab -ab -ab -ab -ab -aa -"} -(18,1,1) = {" -aa -ab -ab -ab -ab -ag -ab -ab -ab -ap -aA -aL -aT -aj -bj -bl -bl -bl -bl -bN -aj -aL -aT -aA -ap -ab -ab -ab -ag -ab -ab -ab -ab -ab -aa -"} -(19,1,1) = {" -aa -ac -ab -ab -ab -ag -ab -ab -ab -ap -aA -aM -aU -aj -bk -bl -bl -bl -bl -bO -aj -bX -cd -aA -ap -ab -ab -ab -ag -ab -ab -ab -af -ab -aa -"} -(20,1,1) = {" -aa -ab -ab -af -ab -ag -ab -SN -aj -aj -aj -aj -aj -aj -bl -bu -bB -bC -bu -bl -aj -aj -aj -aj -aj -aj -ab -ah -ag -ab -ab -ac -ab -ab -aa -"} -(21,1,1) = {" -aa -ab -ab -ab -ab -ag -ag -ag -aj -aq -aB -aB -aV -aj -bm -bu -bC -bC -bu -bP -aj -bY -ce -bY -bY -aj -ag -ag -ag -ab -ab -ab -ad -ab -aa -"} -(22,1,1) = {" -aa -ab -ab -ab -ab -ab -ab -ab -aj -ar -aC -aN -aW -aj -bl -bu -bC -bC -bu -bn -aj -bl -bl -bl -cl -aj -ab -ab -ab -ab -ab -ad -ad -ab -aa -"} -(23,1,1) = {" -aa -ab -ab -ab -ab -ab -ab -ab -aj -as -aD -aN -aE -be -bn -bl -bl -bl -bl -bl -bA -bl -bY -bY -cm -aj -ab -ab -ab -ab -ad -ad -ad -ab -aa -"} -(24,1,1) = {" -aa -ab -ab -af -ab -ab -ab -ab -aj -at -aE -aE -aX -aj -bl -bl -bl -bl -bl -bl -aj -bl -bl -bl -cn -aj -ab -af -ab -ad -ad -ad -ad -ad -aa -"} -(25,1,1) = {" -aa -ac -ab -ab -ab -ab -ab -af -aj -au -aE -aO -aY -aj -aj -aj -bD -bD -aj -aj -aj -bl -bY -bY -co -aj -cp -ab -ab -ad -ad -af -ab -ae -aa -"} -(26,1,1) = {" -aa -ab -ab -ab -ab -ab -ab -ai -aj -aj -aE -aD -aZ -aj -bo -bv -bl -bl -bH -bQ -aj -bZ -aj -aj -aj -aj -aj -af -ac -ab -ab -ab -ab -ab -aa -"} -(27,1,1) = {" -aa -ab -ab -ae -ab -ac -ab -aj -aj -aj -aF -aP -ba -aj -bo -bl -bl -bl -bl -bR -aj -ca -cf -ci -aj -aj -aj -ab -ab -ab -ab -ab -ab -ac -aa -"} -(28,1,1) = {" -aa -ab -ab -ab -ab -ab -ab -aj -aj -aj -aj -aj -aj -aj -bp -bl -bl -bl -bl -bS -aj -aj -aj -aj -aj -aj -aj -ab -ab -ab -ab -ab -ab -af -aa -"} -(29,1,1) = {" -aa -ab -ab -ab -ab -af -ab -aj -aj -aj -aj -aG -ab -bf -aj -bw -bw -bw -bI -aj -aG -ab -bf -aj -aj -aj -aj -ab -ad -ad -ab -ab -ab -ab -aa -"} -(30,1,1) = {" -aa -ab -ad -ad -ad -ab -ab -aj -aj -aj -aG -ab -ab -ab -bf -al -al -al -al -aG -ab -ab -ab -bf -al -al -cq -ad -ad -ad -ad -ab -ab -ab -aa -"} -(31,1,1) = {" -aa -ab -af -ad -ad -ad -ab -ak -al -al -ab -ab -ab -ab -ab -am -am -am -am -ab -ab -ab -af -ab -am -am -ab -ad -ad -ad -ad -ab -ab -ab -aa -"} -(32,1,1) = {" -aa -ab -ab -ab -ab -ab -ab -ab -am -am -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ad -ad -ad -ab -ab -af -ab -aa -"} -(33,1,1) = {" -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -af -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -"} -(34,1,1) = {" -aa -ab -ac -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -"} -(35,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -"} +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaabababababacababababababababadadabacabababababacabababababababababaa +aaababababababaeabababababababadadababababababababababababadafababacaa +aaabababababababababababababadadabababafabababafababaeababadadabababaa +aaababafabadadadababababafababababababababababababababababadadabababaa +aaabababababadadadabacababababagagagagagagabababababacabafabadabababaa +aaababababababadadabafababababagahabababagabababababababababababababaa +aaabababababababaiajajajakababagabababbKagabababafaiajajajajakabababaa +aaabababababababajajajajajajajajajababajajajajajajajajajajajalamababaa +aaababababafababajajajajajajanaoajapapajaqarasatauajajajajajalamababaa +aaabababababababavajajawaxajayazajaAaAajaBaCaDaEaEaEaFajajaGababababaa +aaabababababababaHajajaIaJajayaKaLaLaMajaBaNaNaEaOaDaPajaGabababababaa +aaabafababababaHajaQajawaRajayaSaTaTaUajaVaWaEaXaYaZbaajababababafabaa +aaabababababaHajbbbcajbdajajayazajajajajajajbeajajajajajbfabababababaa +aaabababababajbgbhazajbiaLaLbhazajbjbkblbmblbnblajbobobpajbfababababaa +aaabababababbqbrblazajbsblblblbtajblblbububublblajbvblblbwalamabababaa +aaabababababbxbrblaKbybhblbzblblbAblblbBbCbCblblbDblblblbwalamabababaa +aaabababababbxbrblaSbEbFblblblblbAblblbCbCbCblblbDblblblbwalamabababaa +aaabababababbGbrblazajbsblblblbtajblblbububublblajbHblblbIalamabababaa +aaabababababajbJbFcsajbLaTaTbFbMajbNbOblbPbnblblajbQbRbSajaGababababaa +aaabababababavajbTbUajbdajajayazajajajajajajbAajajajajajaGabababababaa +aaababababababavajaQajawbVajaybWaLaLbXajbYblblblblbZcaajababababababaa +aaabafabababababavajajcbccajayaSaTaTcdajceblbYblbYajcfajbfabafabababaa +aaabababababababaHajajcgchajaycrajaAaAajbYblbYblbYajciajajbfababababaa +aaabababababababajajajajajajcjckajapapajbYclcmcncoajajajajalamabababaa +aaabababababababajajajajajajajajajababajajajajajajajajajajalamabababaa +aaababafababababcpajajajcqababagbKabababagabababcpajajajajcqababababaa +aaabababadabababababafababababagabababahagababafabafabababadadadababaa +aaababadadabacababababafabababagagagagagagababababacababadadadadababaa +aaabadadadabababababababaeababababababababababadadabababadadadadababaa +aaababadadababacabadababababababababababababadadadababababadadabababaa +aaabababababababadadafabababafababababacabadadadafabababababababababaa +aaabababafababadadadababababababababafabadadadadabababababababafababaa +aaabababababababadadabacabababababababababababadaeabacafababababababaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +"} \ No newline at end of file diff --git a/maps/submaps/surface_submaps/wilderness/Boombase.dmm b/maps/submaps/surface_submaps/wilderness/Boombase.dmm index e8acd62473..438cd0a713 100644 --- a/maps/submaps/surface_submaps/wilderness/Boombase.dmm +++ b/maps/submaps/surface_submaps/wilderness/Boombase.dmm @@ -13,7 +13,7 @@ "am" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled/steel,/area/submap/BoomBase) "an" = (/obj/effect/decal/cleanable/dirt,/obj/effect/spider,/obj/item/weapon/material/shard,/turf/simulated/floor/tiled/steel,/area/submap/BoomBase) "ao" = (/turf/simulated/floor/tiled/steel,/area/submap/BoomBase) -"ap" = (/mob/living/simple_animal/hostile/giant_spider/phorogenic{returns_home = 1},/turf/simulated/floor/tiled/steel,/area/submap/BoomBase) +"ap" = (/mob/living/simple_mob/animal/giant_spider/phorogenic,/turf/simulated/floor/tiled/steel,/area/submap/BoomBase) "aq" = (/obj/machinery/portable_atmospherics/canister/empty/phoron,/turf/simulated/floor/tiled/steel{ icon_state = "steel_dirty"},/area/submap/BoomBase) "ar" = (/obj/machinery/portable_atmospherics/canister/empty/phoron,/obj/item/weapon/material/shard,/turf/simulated/floor/tiled/steel{ icon_state = "steel_dirty"},/area/submap/BoomBase) "as" = (/obj/item/weapon/material/shard,/turf/simulated/floor/plating,/area/submap/BoomBase) @@ -34,7 +34,7 @@ "aH" = (/obj/effect/decal/cleanable/ash,/turf/simulated/floor/outdoors/dirt,/area/submap/BoomBase) "aI" = (/obj/random/mob/spider/mutant,/turf/simulated/floor/outdoors/dirt,/area/submap/BoomBase) "aJ" = (/obj/structure/table,/turf/simulated/floor/tiled/steel,/area/submap/BoomBase) -"aK" = (/obj/effect/decal/cleanable/dirt,/mob/living/simple_animal/hostile/giant_spider/phorogenic{returns_home = 1},/turf/simulated/floor/tiled/steel,/area/submap/BoomBase) +"aK" = (/obj/effect/decal/cleanable/dirt,/mob/living/simple_mob/animal/giant_spider/phorogenic,/turf/simulated/floor/tiled/steel,/area/submap/BoomBase) "aL" = (/turf/simulated/floor/tiled/steel{ icon_state = "burned2"},/area/submap/BoomBase) "aM" = (/turf/simulated/floor/outdoors/rocks,/area/submap/BoomBase) "aN" = (/obj/effect/decal/cleanable/dirt,/obj/structure/table/standard,/obj/item/weapon/tank/phoron,/obj/item/weapon/fuel_assembly/phoron,/turf/simulated/floor/tiled/steel,/area/submap/BoomBase) diff --git a/maps/submaps/surface_submaps/wilderness/CaveS.dmm b/maps/submaps/surface_submaps/wilderness/CaveS.dmm index e967b39617..898ade189a 100644 --- a/maps/submaps/surface_submaps/wilderness/CaveS.dmm +++ b/maps/submaps/surface_submaps/wilderness/CaveS.dmm @@ -1,1910 +1,83 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"a" = ( -/turf/template_noop, -/area/template_noop) -"b" = ( -/turf/template_noop, -/area/submap/CaveS) -"c" = ( -/obj/item/ammo_casing/a45, -/turf/template_noop, -/area/submap/CaveS) -"d" = ( -/turf/simulated/mineral/ignore_mapgen, -/area/submap/CaveS) -"e" = ( -/obj/item/ammo_casing/a45, -/obj/item/weapon/reagent_containers/food/snacks/xenomeat/spidermeat, -/turf/template_noop, -/area/submap/CaveS) -"f" = ( -/obj/random/landmine, -/turf/template_noop, -/area/submap/CaveS) -"g" = ( -/obj/item/ammo_casing/a45, -/obj/random/landmine, -/turf/template_noop, -/area/submap/CaveS) -"h" = ( -/obj/random/landmine, -/turf/simulated/floor/outdoors/dirt{ - outdoors = 0 - }, -/area/submap/CaveS) -"i" = ( -/obj/effect/spider/stickyweb, -/turf/simulated/floor/outdoors/dirt{ - outdoors = 0 - }, -/area/submap/CaveS) -"j" = ( -/obj/item/ammo_casing/a45, -/obj/item/ammo_casing/a45, -/turf/template_noop, -/area/submap/CaveS) -"k" = ( -/turf/simulated/floor/outdoors/dirt{ - outdoors = 0 - }, -/area/submap/CaveS) -"l" = ( -/obj/item/weapon/reagent_containers/food/snacks/xenomeat/spidermeat, -/turf/template_noop, -/area/submap/CaveS) -"m" = ( -/obj/effect/spider/stickyweb, -/turf/simulated/floor/outdoors/dirt, -/area/submap/CaveS) -"n" = ( -/obj/item/clothing/accessory/storage/webbing, -/obj/item/weapon/material/knife/tacknife/combatknife, -/turf/simulated/floor/outdoors/dirt{ - outdoors = 0 - }, -/area/submap/CaveS) -"o" = ( -/mob/living/simple_animal/hostile/giant_spider, -/turf/simulated/floor/outdoors/dirt{ - outdoors = 0 - }, -/area/submap/CaveS) -"p" = ( -/obj/effect/decal/cleanable/cobweb, -/turf/simulated/floor/outdoors/dirt{ - outdoors = 0 - }, -/area/submap/CaveS) -"q" = ( -/mob/living/simple_animal/hostile/giant_spider/lurker, -/turf/simulated/floor/outdoors/dirt{ - outdoors = 0 - }, -/area/submap/CaveS) -"r" = ( -/obj/effect/decal/cleanable/cobweb2, -/turf/simulated/floor/outdoors/dirt{ - outdoors = 0 - }, -/area/submap/CaveS) -"s" = ( -/mob/living/simple_animal/hostile/giant_spider/webslinger, -/turf/simulated/floor/outdoors/dirt{ - outdoors = 0 - }, -/area/submap/CaveS) -"t" = ( -/obj/effect/decal/cleanable/cobweb2, -/mob/living/simple_animal/hostile/giant_spider/lurker, -/turf/simulated/floor/outdoors/dirt{ - outdoors = 0 - }, -/area/submap/CaveS) -"u" = ( -/turf/simulated/floor/outdoors/grass/sif/forest, -/area/submap/CaveS) -"v" = ( -/mob/living/simple_animal/hostile/giant_spider/lurker, -/turf/simulated/floor/outdoors/dirt, -/area/submap/CaveS) -"x" = ( -/obj/structure/flora/tree/sif, -/turf/simulated/floor/outdoors/grass/sif/forest, -/area/submap/CaveS) -"y" = ( -/obj/random/landmine, -/turf/simulated/floor/outdoors/grass/sif/forest, -/area/submap/CaveS) -"z" = ( -/turf/simulated/floor, -/area/submap/CaveS) -"A" = ( -/obj/structure/closet/crate, -/obj/item/stack/cable_coil, -/obj/item/stack/cable_coil, -/obj/item/weapon/storage/toolbox, -/obj/random/toolbox, -/turf/simulated/floor, -/area/submap/CaveS) -"B" = ( -/obj/structure/loot_pile/maint/technical, -/turf/simulated/floor, -/area/submap/CaveS) -"C" = ( -/obj/structure/table/woodentable, -/turf/simulated/floor, -/area/submap/CaveS) -"E" = ( -/obj/machinery/power/port_gen/pacman, -/obj/structure/cable{ - icon_state = "0-2"; - d2 = 2 - }, -/turf/simulated/floor, -/area/submap/CaveS) -"F" = ( -/turf/simulated/wall, -/area/submap/CaveS) -"G" = ( -/obj/structure/closet/crate, -/obj/item/weapon/reagent_containers/hypospray, -/obj/item/weapon/reagent_containers/glass/bottle/stoxin, -/obj/item/weapon/reagent_containers/glass/bottle/antitoxin, -/obj/item/weapon/reagent_containers/pill/antitox, -/obj/item/weapon/reagent_containers/pill/antitox, -/obj/item/weapon/reagent_containers/pill/antitox, -/obj/item/weapon/reagent_containers/pill/paracetamol, -/obj/random/firstaid, -/turf/simulated/floor, -/area/submap/CaveS) -"H" = ( -/obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2"; - pixel_y = 0 - }, -/turf/simulated/floor, -/area/submap/CaveS) -"I" = ( -/obj/structure/closet/crate, -/obj/random/contraband, -/obj/random/contraband, -/obj/random/contraband, -/obj/random/energy, -/obj/item/weapon/material/star, -/obj/item/weapon/material/star, -/obj/item/weapon/material/star, -/obj/item/weapon/material/star, -/obj/item/weapon/material/star, -/turf/simulated/floor, -/area/submap/CaveS) -"J" = ( -/obj/effect/spider/stickyweb, -/mob/living/simple_animal/hostile/giant_spider/lurker, -/turf/simulated/floor/outdoors/dirt{ - outdoors = 0 - }, -/area/submap/CaveS) -"K" = ( -/obj/structure/cable{ - d1 = 1; - d2 = 4; - icon_state = "1-4" - }, -/turf/simulated/floor, -/area/submap/CaveS) -"L" = ( -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8"; - pixel_x = 0 - }, -/turf/simulated/floor, -/area/submap/CaveS) -"M" = ( -/obj/machinery/computer/communications, -/obj/structure/cable{ - d2 = 8; - icon_state = "0-8" - }, -/turf/simulated/floor, -/area/submap/CaveS) -"N" = ( -/obj/structure/loot_pile/maint/boxfort, -/turf/simulated/floor, -/area/submap/CaveS) -"P" = ( -/obj/random/mob/spider/mutant, -/turf/simulated/floor/outdoors/dirt{ - outdoors = 0 - }, -/area/submap/CaveS) -"V" = ( -/obj/random/mob/spider, -/turf/simulated/floor/outdoors/dirt{ - outdoors = 0 - }, -/area/submap/CaveS) +"a" = (/turf/template_noop,/area/template_noop) +"b" = (/turf/template_noop,/area/submap/CaveS) +"c" = (/obj/item/ammo_casing/a45,/turf/template_noop,/area/submap/CaveS) +"d" = (/turf/simulated/mineral/ignore_mapgen,/area/submap/CaveS) +"e" = (/obj/item/ammo_casing/a45,/obj/item/weapon/reagent_containers/food/snacks/xenomeat/spidermeat,/turf/template_noop,/area/submap/CaveS) +"f" = (/obj/random/landmine,/turf/template_noop,/area/submap/CaveS) +"g" = (/obj/item/ammo_casing/a45,/obj/random/landmine,/turf/template_noop,/area/submap/CaveS) +"h" = (/obj/random/landmine,/turf/simulated/floor/outdoors/dirt{outdoors = 0},/area/submap/CaveS) +"i" = (/obj/effect/spider/stickyweb,/turf/simulated/floor/outdoors/dirt{outdoors = 0},/area/submap/CaveS) +"j" = (/obj/item/ammo_casing/a45,/obj/item/ammo_casing/a45,/turf/template_noop,/area/submap/CaveS) +"k" = (/turf/simulated/floor/outdoors/dirt{outdoors = 0},/area/submap/CaveS) +"l" = (/obj/item/weapon/reagent_containers/food/snacks/xenomeat/spidermeat,/turf/template_noop,/area/submap/CaveS) +"m" = (/obj/effect/spider/stickyweb,/turf/simulated/floor/outdoors/dirt,/area/submap/CaveS) +"n" = (/obj/item/clothing/accessory/storage/webbing,/obj/item/weapon/material/knife/tacknife/combatknife,/turf/simulated/floor/outdoors/dirt{outdoors = 0},/area/submap/CaveS) +"o" = (/mob/living/simple_mob/animal/giant_spider,/turf/simulated/floor/outdoors/dirt{outdoors = 0},/area/submap/CaveS) +"p" = (/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/outdoors/dirt{outdoors = 0},/area/submap/CaveS) +"q" = (/obj/random/mob/spider,/turf/simulated/floor/outdoors/dirt{outdoors = 0},/area/submap/CaveS) +"r" = (/mob/living/simple_mob/animal/giant_spider/lurker,/turf/simulated/floor/outdoors/dirt{outdoors = 0},/area/submap/CaveS) +"s" = (/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor/outdoors/dirt{outdoors = 0},/area/submap/CaveS) +"t" = (/mob/living/simple_mob/animal/giant_spider/webslinger,/turf/simulated/floor/outdoors/dirt{outdoors = 0},/area/submap/CaveS) +"u" = (/obj/effect/decal/cleanable/cobweb2,/mob/living/simple_mob/animal/giant_spider/lurker,/turf/simulated/floor/outdoors/dirt{outdoors = 0},/area/submap/CaveS) +"v" = (/turf/simulated/floor/outdoors/grass/sif/forest,/area/submap/CaveS) +"w" = (/obj/random/mob/spider/mutant,/turf/simulated/floor/outdoors/dirt{outdoors = 0},/area/submap/CaveS) +"x" = (/mob/living/simple_mob/animal/giant_spider/lurker,/turf/simulated/floor/outdoors/dirt,/area/submap/CaveS) +"y" = (/obj/structure/flora/tree/sif,/turf/simulated/floor/outdoors/grass/sif/forest,/area/submap/CaveS) +"z" = (/obj/random/landmine,/turf/simulated/floor/outdoors/grass/sif/forest,/area/submap/CaveS) +"A" = (/turf/simulated/floor,/area/submap/CaveS) +"B" = (/obj/structure/closet/crate,/obj/item/stack/cable_coil,/obj/item/stack/cable_coil,/obj/item/weapon/storage/toolbox,/obj/random/toolbox,/turf/simulated/floor,/area/submap/CaveS) +"C" = (/obj/structure/loot_pile/maint/technical,/turf/simulated/floor,/area/submap/CaveS) +"D" = (/obj/structure/table/woodentable,/turf/simulated/floor,/area/submap/CaveS) +"E" = (/obj/machinery/power/port_gen/pacman,/obj/structure/cable{icon_state = "0-2"; d2 = 2},/turf/simulated/floor,/area/submap/CaveS) +"F" = (/turf/simulated/wall,/area/submap/CaveS) +"G" = (/obj/structure/closet/crate,/obj/item/weapon/reagent_containers/hypospray,/obj/item/weapon/reagent_containers/glass/bottle/stoxin,/obj/item/weapon/reagent_containers/glass/bottle/antitoxin,/obj/item/weapon/reagent_containers/pill/antitox,/obj/item/weapon/reagent_containers/pill/antitox,/obj/item/weapon/reagent_containers/pill/antitox,/obj/item/weapon/reagent_containers/pill/paracetamol,/obj/random/firstaid,/turf/simulated/floor,/area/submap/CaveS) +"H" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor,/area/submap/CaveS) +"I" = (/obj/structure/closet/crate,/obj/random/contraband,/obj/random/contraband,/obj/random/contraband,/obj/random/energy,/obj/item/weapon/material/star,/obj/item/weapon/material/star,/obj/item/weapon/material/star,/obj/item/weapon/material/star,/obj/item/weapon/material/star,/turf/simulated/floor,/area/submap/CaveS) +"J" = (/obj/effect/spider/stickyweb,/mob/living/simple_mob/animal/giant_spider/lurker,/turf/simulated/floor/outdoors/dirt{outdoors = 0},/area/submap/CaveS) +"K" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/submap/CaveS) +"L" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor,/area/submap/CaveS) +"M" = (/obj/machinery/computer/communications,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor,/area/submap/CaveS) +"N" = (/obj/structure/loot_pile/maint/boxfort,/turf/simulated/floor,/area/submap/CaveS) (1,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(2,1,1) = {" -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -"} -(3,1,1) = {" -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -b -b -b -b -b -b -a -"} -(4,1,1) = {" -a -b -b -b -b -b -b -b -b -b -b -b -b -b -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -b -b -b -a -"} -(5,1,1) = {" -a -b -b -b -b -b -b -b -b -b -b -d -d -d -d -d -d -d -d -d -d -d -d -d -u -u -d -d -u -u -d -d -d -d -d -d -d -d -d -a -"} -(6,1,1) = {" -a -b -b -b -b -b -b -b -b -d -d -d -d -d -d -d -d -d -d -d -d -d -d -u -x -u -u -u -u -u -u -d -d -d -d -d -d -d -d -a -"} -(7,1,1) = {" -a -b -b -b -b -b -b -b -b -d -d -d -d -d -d -o -i -d -d -d -d -d -d -u -u -y -u -u -u -u -u -d -d -d -d -d -d -d -b -a -"} -(8,1,1) = {" -a -b -b -b -b -b -b -b -b -d -d -d -d -d -d -k -k -k -d -d -d -d -u -u -u -u -u -u -u -u -u -x -d -d -d -d -d -d -b -a -"} -(9,1,1) = {" -a -b -b -b -b -b -b -b -b -d -d -d -d -d -n -k -k -V -d -d -d -d -u -u -u -u -x -y -u -u -u -u -d -d -d -d -d -b -b -a -"} -(10,1,1) = {" -a -b -b -b -b -b -b -b -b -d -d -d -d -d -d -k -k -k -k -k -d -d -d -d -d -u -u -u -u -u -u -k -u -d -d -d -d -b -b -a -"} -(11,1,1) = {" -a -b -b -b -b -b -b -b -b -b -d -d -d -d -k -k -k -k -k -k -k -d -d -d -d -d -i -k -u -k -k -k -i -d -d -d -d -b -b -a -"} -(12,1,1) = {" -a -b -b -b -b -b -b -b -b -b -d -d -d -d -k -k -k -k -k -k -k -s -d -d -d -d -d -k -k -k -k -d -d -d -d -d -d -b -b -a -"} -(13,1,1) = {" -a -b -b -b -b -b -b -b -b -b -d -d -d -d -i -k -q -d -k -k -k -k -d -d -d -d -d -k -k -d -v -d -d -d -d -d -d -d -b -a -"} -(14,1,1) = {" -a -b -b -b -b -b -b -b -b -b -b -d -d -d -d -d -d -d -d -r -k -k -d -d -d -d -d -k -k -d -d -d -d -d -d -d -d -d -d -a -"} -(15,1,1) = {" -a -b -b -b -b -b -b -b -b -c -b -b -d -d -d -d -d -d -d -d -k -k -P -k -k -d -d -k -k -d -d -d -d -d -d -d -d -d -d -a -"} -(16,1,1) = {" -a -b -b -b -b -b -b -b -b -b -b -b -b -d -d -d -b -b -d -d -k -k -k -k -k -k -k -k -i -d -d -d -d -d -d -d -d -d -d -a -"} -(17,1,1) = {" -a -b -b -b -b -b -c -b -b -b -b -b -b -b -b -b -b -d -d -d -k -k -d -d -q -k -k -k -d -d -d -d -d -d -d -d -d -d -d -a -"} -(18,1,1) = {" -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -d -d -d -d -k -k -d -d -d -k -k -d -d -d -d -i -J -k -d -d -d -d -b -a -"} -(19,1,1) = {" -a -b -b -b -b -b -b -b -b -b -j -c -b -b -d -d -d -d -d -d -k -k -d -d -d -k -k -k -d -d -d -k -k -k -k -d -d -d -b -a -"} -(20,1,1) = {" -a -b -b -b -b -b -b -b -b -g -b -b -b -b -d -d -d -d -d -p -k -k -v -d -d -k -k -k -i -d -k -k -k -k -i -d -d -b -b -a -"} -(21,1,1) = {" -a -b -b -b -b -b -b -b -b -b -b -l -b -d -d -d -d -d -d -k -k -k -d -d -d -d -k -k -k -k -k -k -k -k -d -d -d -b -b -a -"} -(22,1,1) = {" -a -b -b -b -b -b -b -b -b -b -f -b -d -d -d -d -d -d -d -V -k -k -d -d -d -d -k -k -k -h -k -k -k -k -d -d -d -d -d -a -"} -(23,1,1) = {" -a -b -b -b -c -b -b -b -f -b -b -d -d -d -d -d -d -d -d -k -k -k -d -d -d -d -h -k -k -k -i -d -d -d -d -d -d -d -b -a -"} -(24,1,1) = {" -a -b -b -b -b -b -c -b -b -h -k -m -d -d -d -d -d -d -d -k -k -k -d -d -d -d -i -i -h -k -d -d -d -d -d -d -d -d -b -a -"} -(25,1,1) = {" -a -b -b -b -b -b -c -e -d -i -k -k -m -d -d -d -d -d -d -k -k -k -d -d -d -d -d -d -k -k -k -k -k -d -d -d -d -d -d -a -"} -(26,1,1) = {" -a -b -b -b -b -b -c -d -d -d -d -i -k -d -d -p -k -k -h -k -k -k -i -d -d -d -d -d -k -k -k -k -k -k -P -d -d -d -d -a -"} -(27,1,1) = {" -a -b -b -b -b -b -d -d -d -d -d -i -k -h -k -k -k -k -k -d -d -k -k -k -d -d -d -k -k -k -z -z -z -k -k -q -d -d -d -a -"} -(28,1,1) = {" -a -b -b -b -b -b -d -d -d -d -d -d -k -k -k -k -k -d -d -d -d -t -k -k -d -d -k -k -k -z -E -H -K -k -k -k -d -d -d -a -"} -(29,1,1) = {" -a -b -b -b -b -b -d -d -d -d -d -d -d -m -k -k -k -d -d -d -d -d -k -k -d -q -k -z -z -C -F -F -L -z -z -k -d -d -d -a -"} -(30,1,1) = {" -a -b -b -b -b -b -d -d -d -d -d -d -d -d -k -k -k -d -d -d -d -d -k -k -d -k -k -z -z -C -F -F -M -z -N -d -d -d -b -a -"} -(31,1,1) = {" -a -b -b -b -b -b -d -d -d -d -d -d -d -d -k -k -k -d -d -p -h -k -k -V -d -d -k -A -z -z -G -I -z -z -d -d -d -b -b -a -"} -(32,1,1) = {" -a -b -b -b -b -b -b -d -d -d -d -d -d -d -k -k -k -k -k -k -k -k -k -d -d -d -k -k -B -z -P -k -z -d -d -d -b -b -b -a -"} -(33,1,1) = {" -a -b -b -b -b -b -b -d -d -d -d -d -d -d -d -V -d -r -k -d -d -d -d -d -d -d -d -k -k -k -k -k -d -d -d -d -b -b -b -a -"} -(34,1,1) = {" -a -b -b -b -b -b -b -b -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -k -d -k -k -d -d -d -d -b -b -b -b -a -"} -(35,1,1) = {" -a -b -b -b -b -b -b -b -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -b -b -b -b -a -"} -(36,1,1) = {" -a -b -b -b -b -b -b -d -d -d -d -d -b -b -d -d -d -d -d -d -d -d -d -d -d -d -b -d -d -d -d -d -d -d -b -b -b -b -b -a -"} -(37,1,1) = {" -a -b -b -b -b -b -b -d -d -d -d -b -b -b -b -b -d -d -d -d -d -d -d -d -b -b -b -b -b -b -d -d -b -b -b -b -b -b -b -a -"} -(38,1,1) = {" -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -d -d -d -d -d -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -"} -(39,1,1) = {" -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -d -d -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -"} -(40,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbcbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbcbbbbbbcccdddddbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbbeddddddddbbddbba +abbbbbbbbbbbbbbbbbbbbbfbdddddddddddddbba +abbbbdddddbbbbcbbbbgbbbhiddddddddddddbba +abbbbddddddddbbbbbjbbfbkkddddddddddddbba +abbbddddddddddbbbbcblbdmkiidddddddddbbba +abbbdddddddddddbbbbbbdddmkkkdddddddbbbba +abbbddddddddddddbbbbddddddhkmddddddbbbba +abbdddddndkkidddbbddddddddkkkkkkddddbbba +abbdddokkkkkkdddbbdddddddpkkkkkkqdddbbba +abbdddikkkkkrddbbddddddddkkkkkkkdddddbba +abbddddkqkkkdddbdddddddddkkddddksddddbba +abdddddddkkkkddddddddddddhkddddkkdddddba +abdddddddkkkksdddddpkqkkkkddddpkddddddba +abddddddddkkkkkkkkkkkkkkkkddddhkddddddda +abdddddddddtkkkkkkkkkkkkkkkuddkkddddddda +abdddddvvdddddwkdddxdddddikkkkkkddddddba +abdddvvvvdddddkkddddddddddkkkkqddddddbba +abddvyvvvdddddkkrdddddddddddddddddddbbba +abddvvzvvvdddddkkkkkddddddddrkddddddbbba +abdddvvvyviddddkkkkkkkhidddkkkkkdddbbbba +abdddvvvzvkkkkkkkdkkkkkiddkkAABkkkddbbba +abddvvvvvvvkkkkidddikkkhkkkkAAACkdddbbba +abddvvvvvvkkddddddddkhkkkkkADDAAkkddbbba +abdddvvvvvkkxddddddkkkidkkAEFFGwkkdddbba +abdddddyvkkddddddikkkkddkkAHFFIkkddddbba +abdddddddviddddddJkkkkddkkAKLMAAddddbbba +abbddddddddddddddkkkkkdddkkkAAAdddddbbba +abbdddddddddddddddkidddddwkkANdddddbbbba +abbdddddddddddddddddddddddrkkddddbbbbbba +abbbdddddddddddddddddddddddddddbbbbbbbba +abbbddddbbbbdddddddbbdddddddddbbbbbbbbba +abbbddbbbbbbbddddbbbbdbbdddddbbbbbbbbbba +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +"} \ No newline at end of file diff --git a/maps/submaps/surface_submaps/wilderness/DJOutpost1.dmm b/maps/submaps/surface_submaps/wilderness/DJOutpost1.dmm index c7440cdaa1..6b85ef347a 100644 --- a/maps/submaps/surface_submaps/wilderness/DJOutpost1.dmm +++ b/maps/submaps/surface_submaps/wilderness/DJOutpost1.dmm @@ -6,7 +6,7 @@ "f" = (/obj/machinery/telecomms/relay/preset/ruskie,/turf/simulated/floor/wood,/area/submap/DJOutpost1) "g" = (/obj/structure/loot_pile/maint/technical,/turf/simulated/floor/wood,/area/submap/DJOutpost1) "h" = (/obj/structure/sign/goldenplaque{desc = "An award given to Sif Free Radio for media excellency. It looks fake."; name = "Best Radio Station 2558"; pixel_y = 30},/turf/simulated/floor/wood,/area/submap/DJOutpost1) -"i" = (/mob/living/simple_animal/hostile/giant_spider/frost{returns_home = 1},/turf/simulated/floor/wood,/area/submap/DJOutpost1) +"i" = (/mob/living/simple_mob/animal/giant_spider/frost,/turf/simulated/floor/wood,/area/submap/DJOutpost1) "j" = (/obj/effect/decal/remains,/obj/effect/decal/cleanable/blood,/obj/item/clothing/under/frontier,/obj/item/weapon/material/knife/tacknife/combatknife,/obj/random_multi/single_item/sfr_headset,/turf/simulated/floor/wood,/area/submap/DJOutpost1) "k" = (/obj/machinery/door/airlock/glass,/turf/simulated/floor/wood,/area/submap/DJOutpost1) "l" = (/obj/structure/table/steel_reinforced,/obj/item/device/radio/intercom{ icon_state = "intercom"; dir = 8},/turf/simulated/floor/wood,/area/submap/DJOutpost1) diff --git a/maps/submaps/surface_submaps/wilderness/DoomP.dmm b/maps/submaps/surface_submaps/wilderness/DoomP.dmm index bde323248c..b856b7a229 100644 --- a/maps/submaps/surface_submaps/wilderness/DoomP.dmm +++ b/maps/submaps/surface_submaps/wilderness/DoomP.dmm @@ -1,4258 +1,153 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"aa" = ( -/turf/template_noop, -/area/template_noop) -"ab" = ( -/turf/template_noop, -/area/submap/DoomP) -"ac" = ( -/turf/simulated/floor/outdoors/rocks, -/area/submap/DoomP) -"ad" = ( -/turf/simulated/floor/outdoors/grass/sif/forest, -/area/submap/DoomP) -"ae" = ( -/mob/living/simple_animal/hostile/viscerator{ - returns_home = 1 - }, -/turf/template_noop, -/area/submap/DoomP) -"af" = ( -/turf/simulated/floor/water, -/area/submap/DoomP) -"ag" = ( -/obj/structure/flora/tree/sif, -/turf/template_noop, -/area/submap/DoomP) -"ah" = ( -/obj/random/landmine, -/turf/simulated/floor/outdoors/grass/sif/forest, -/area/submap/DoomP) -"ai" = ( -/mob/living/simple_animal/hostile/viscerator{ - returns_home = 1 - }, -/turf/simulated/floor/outdoors/grass/sif/forest, -/area/submap/DoomP) -"aj" = ( -/obj/effect/decal/cleanable/blood, -/obj/random/landmine, -/turf/simulated/floor/outdoors/grass/sif/forest, -/area/submap/DoomP) -"ak" = ( -/turf/simulated/floor/water/deep, -/area/submap/DoomP) -"al" = ( -/obj/effect/decal/cleanable/blood, -/turf/simulated/floor/outdoors/grass/sif/forest, -/area/submap/DoomP) -"am" = ( -/obj/random/landmine, -/turf/simulated/floor/outdoors/rocks, -/area/submap/DoomP) -"an" = ( -/obj/effect/decal/remains/mouse, -/turf/simulated/floor/outdoors/grass/sif/forest, -/area/submap/DoomP) -"ao" = ( -/obj/effect/decal/remains/deer, -/turf/simulated/floor/outdoors/grass/sif/forest, -/area/submap/DoomP) -"ap" = ( -/obj/effect/decal/remains/mouse, -/obj/random/landmine, -/turf/simulated/floor/outdoors/grass/sif/forest, -/area/submap/DoomP) -"aq" = ( -/obj/structure/flora/tree/sif, -/turf/simulated/floor/outdoors/grass/sif/forest, -/area/submap/DoomP) -"ar" = ( -/obj/machinery/light/small, -/turf/simulated/floor/outdoors/grass/sif/forest, -/area/submap/DoomP) -"as" = ( -/obj/machinery/porta_turret/poi, -/turf/simulated/floor/plating, -/area/submap/DoomP) -"at" = ( -/turf/simulated/wall/r_wall, -/area/submap/DoomP) -"au" = ( -/obj/structure/sign/warning/secure_area, -/turf/simulated/wall/r_wall, -/area/submap/DoomP) -"av" = ( -/obj/effect/floor_decal/industrial/warning, -/turf/simulated/floor/plating, -/area/submap/DoomP) -"aw" = ( -/obj/machinery/door/airlock/external, -/turf/simulated/floor/plating, -/area/submap/DoomP) -"ax" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 9 - }, -/turf/simulated/floor/tiled, -/area/submap/DoomP) -"ay" = ( -/obj/structure/bed/chair, -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/submap/DoomP) -"az" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/submap/DoomP) -"aB" = ( -/obj/machinery/light/small{ - dir = 1 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/submap/DoomP) -"aC" = ( -/obj/machinery/vending/cigarette, -/obj/effect/floor_decal/borderfloor{ - dir = 5 - }, -/turf/simulated/floor/tiled, -/area/submap/DoomP) -"aD" = ( -/obj/machinery/light/small{ - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/submap/DoomP) -"aE" = ( -/obj/machinery/power/smes/buildable/point_of_interest, -/obj/structure/cable/green{ - d2 = 4; - icon_state = "0-4" - }, -/turf/simulated/floor/plating, -/area/submap/DoomP) -"aF" = ( -/obj/machinery/power/smes/buildable/point_of_interest, -/obj/structure/cable/green{ - d2 = 4; - icon_state = "0-4" - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/turf/simulated/floor/plating, -/area/submap/DoomP) -"aG" = ( -/obj/machinery/power/apc{ - dir = 1; - name = "PAPC"; - pixel_x = 0; - pixel_y = 24 - }, -/obj/structure/cable/green{ - d2 = 8; - icon_state = "0-8" - }, -/turf/simulated/floor/tiled/techfloor/grid, -/area/submap/DoomP) -"aH" = ( -/obj/structure/cable{ - icon_state = "0-2"; - d2 = 2 - }, -/obj/machinery/power/port_gen/pacman, -/turf/simulated/floor/plating, -/area/submap/DoomP) -"aI" = ( -/obj/structure/table/standard, -/obj/random/toolbox, -/turf/simulated/floor/tiled/techfloor/grid, -/area/submap/DoomP) -"aJ" = ( -/obj/structure/table/standard, -/obj/item/stack/material/phoron{ - amount = 25 - }, -/turf/simulated/floor/tiled/techfloor/grid, -/area/submap/DoomP) -"aK" = ( -/obj/structure/closet/secure_closet/engineering_electrical, -/turf/simulated/floor/tiled/techfloor/grid, -/area/submap/DoomP) -"aL" = ( -/obj/structure/lattice, -/turf/simulated/floor/outdoors/rocks, -/area/submap/DoomP) -"aM" = ( -/obj/structure/bed/chair{ - dir = 4 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/submap/DoomP) -"aN" = ( -/obj/structure/table/standard, -/turf/simulated/floor/tiled, -/area/submap/DoomP) -"aO" = ( -/obj/structure/table/standard, -/obj/item/pizzabox, -/turf/simulated/floor/tiled, -/area/submap/DoomP) -"aP" = ( -/turf/simulated/floor/tiled, -/area/submap/DoomP) -"aQ" = ( -/obj/machinery/vending/snack, -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/submap/DoomP) -"aR" = ( -/obj/machinery/power/terminal{ - icon_state = "term"; - dir = 1 - }, -/obj/structure/cable{ - icon_state = "0-4"; - d2 = 4 - }, -/turf/simulated/floor/tiled/techfloor/grid, -/area/submap/DoomP) -"aS" = ( -/obj/machinery/power/terminal{ - icon_state = "term"; - dir = 1 - }, -/obj/structure/cable{ - icon_state = "0-4"; - d2 = 4 - }, -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8"; - pixel_x = 0 - }, -/turf/simulated/floor/tiled/techfloor/grid, -/area/submap/DoomP) -"aT" = ( -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8"; - pixel_x = 0 - }, -/mob/living/simple_animal/hostile/syndicate/melee/poi, -/turf/simulated/floor/tiled/techfloor/grid, -/area/submap/DoomP) -"aU" = ( -/obj/structure/cable{ - d1 = 1; - d2 = 8; - icon_state = "1-8" - }, -/turf/simulated/floor/tiled/techfloor/grid, -/area/submap/DoomP) -"aV" = ( -/turf/simulated/floor/tiled/techfloor/grid, -/area/submap/DoomP) -"aW" = ( -/obj/machinery/light/small, -/turf/simulated/floor/tiled/techfloor/grid, -/area/submap/DoomP) -"aX" = ( -/obj/structure/lattice, -/turf/simulated/floor/water, -/area/submap/DoomP) -"aY" = ( -/obj/machinery/light/small{ - dir = 8 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/submap/DoomP) -"aZ" = ( -/obj/machinery/vending/cola, -/obj/effect/floor_decal/borderfloor/corner{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/submap/DoomP) -"ba" = ( -/obj/machinery/door/airlock/external, -/turf/simulated/floor/tiled, -/area/submap/DoomP) -"bb" = ( -/obj/machinery/door/airlock/engineering, -/turf/simulated/floor/tiled/techfloor/grid, -/area/submap/DoomP) -"bc" = ( -/obj/structure/sign/electricshock, -/turf/simulated/wall/r_wall, -/area/submap/DoomP) -"bd" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 10 - }, -/turf/simulated/floor/tiled, -/area/submap/DoomP) -"be" = ( -/obj/effect/floor_decal/borderfloor, -/turf/simulated/floor/tiled, -/area/submap/DoomP) -"bf" = ( -/obj/machinery/light/small, -/obj/effect/floor_decal/borderfloor, -/turf/simulated/floor/tiled, -/area/submap/DoomP) -"bg" = ( -/obj/effect/floor_decal/borderfloor/corner{ - dir = 8 - }, -/mob/living/simple_animal/hostile/syndicate/ranged/laser/poi, -/turf/simulated/floor/tiled, -/area/submap/DoomP) -"bh" = ( -/obj/machinery/door/airlock/hatch, -/turf/simulated/floor/tiled, -/area/submap/DoomP) -"bi" = ( -/obj/machinery/light/small{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/submap/DoomP) -"bj" = ( -/obj/machinery/door/airlock/highsecurity, -/turf/simulated/floor/tiled/techfloor, -/area/submap/DoomP) -"bk" = ( -/obj/machinery/door/airlock, -/turf/simulated/floor/tiled/white, -/area/submap/DoomP) -"bl" = ( -/turf/simulated/floor/tiled/techfloor, -/area/submap/DoomP) -"bm" = ( -/obj/structure/table/standard, -/turf/simulated/floor/tiled/techfloor, -/area/submap/DoomP) -"bn" = ( -/obj/structure/table/standard, -/obj/item/weapon/storage/box/syndie_kit/spy, -/turf/simulated/floor/tiled/techfloor, -/area/submap/DoomP) -"bo" = ( -/obj/structure/table/rack, -/obj/item/weapon/storage/box/smokes, -/turf/simulated/floor/tiled/techfloor, -/area/submap/DoomP) -"bp" = ( -/obj/structure/table/rack, -/obj/item/weapon/storage/box/handcuffs, -/turf/simulated/floor/tiled/techfloor, -/area/submap/DoomP) -"bq" = ( -/obj/structure/table/rack, -/obj/item/weapon/cell/device/weapon, -/obj/item/weapon/cell/device/weapon, -/turf/simulated/floor/tiled/techfloor, -/area/submap/DoomP) -"br" = ( -/obj/structure/table/rack, -/obj/random/energy, -/turf/simulated/floor/tiled/techfloor, -/area/submap/DoomP) -"bs" = ( -/obj/structure/table/rack, -/obj/item/weapon/gun/projectile/contender, -/obj/item/ammo_magazine/s357, -/obj/item/ammo_magazine/s357, -/turf/simulated/floor/tiled/techfloor, -/area/submap/DoomP) -"bt" = ( -/obj/structure/bed, -/obj/item/weapon/bedsheet, -/obj/item/toy/plushie/spider, -/obj/effect/floor_decal/corner/lime/full{ - dir = 8 - }, -/turf/simulated/floor/tiled/white, -/area/submap/DoomP) -"bu" = ( -/obj/structure/table/standard, -/obj/effect/floor_decal/corner/lime{ - dir = 5 - }, -/turf/simulated/floor/tiled/white, -/area/submap/DoomP) -"bv" = ( -/obj/structure/bed, -/obj/item/weapon/bedsheet, -/obj/effect/floor_decal/corner/lime{ - dir = 5 - }, -/turf/simulated/floor/tiled/white, -/area/submap/DoomP) -"bw" = ( -/obj/structure/table/standard, -/obj/item/device/flashlight/lamp, -/obj/effect/floor_decal/corner/lime{ - dir = 5 - }, -/turf/simulated/floor/tiled/white, -/area/submap/DoomP) -"bx" = ( -/obj/structure/table/standard, -/obj/structure/bedsheetbin, -/obj/effect/floor_decal/corner/lime{ - dir = 1 - }, -/turf/simulated/floor/tiled/white, -/area/submap/DoomP) -"by" = ( -/turf/simulated/floor/tiled/white, -/area/submap/DoomP) -"bz" = ( -/obj/machinery/light/small{ - dir = 1 - }, -/turf/simulated/floor/tiled/white, -/area/submap/DoomP) -"bA" = ( -/obj/structure/sink{ - dir = 4; - icon_state = "sink"; - pixel_x = 11; - pixel_y = 0 - }, -/obj/machinery/light/small{ - dir = 1 - }, -/turf/simulated/floor/tiled/white, -/area/submap/DoomP) -"bB" = ( -/obj/machinery/light/small, -/turf/simulated/floor/tiled/techfloor, -/area/submap/DoomP) -"bC" = ( -/obj/machinery/light/small{ - dir = 8 - }, -/obj/effect/floor_decal/corner/lime/full, -/turf/simulated/floor/tiled/white, -/area/submap/DoomP) -"bD" = ( -/obj/effect/floor_decal/corner/lime{ - dir = 10 - }, -/turf/simulated/floor/tiled/white, -/area/submap/DoomP) -"bE" = ( -/obj/machinery/light/small{ - dir = 4; - pixel_y = 0 - }, -/obj/effect/floor_decal/corner/lime{ - dir = 10 - }, -/turf/simulated/floor/tiled/white, -/area/submap/DoomP) -"bF" = ( -/obj/machinery/shower{ - dir = 1 - }, -/obj/structure/curtain/open/shower, -/turf/simulated/floor/tiled/white, -/area/submap/DoomP) -"bG" = ( -/obj/structure/toilet{ - dir = 1 - }, -/turf/simulated/floor/tiled/white, -/area/submap/DoomP) -"bH" = ( -/obj/structure/grille, -/obj/structure/window/reinforced{ - dir = 1 - }, -/obj/structure/window/reinforced, -/obj/machinery/door/firedoor/border_only, -/obj/structure/window/reinforced{ - dir = 8 - }, -/turf/simulated/floor/plating, -/area/submap/DoomP) -"bI" = ( -/obj/structure/grille, -/obj/structure/window/reinforced{ - dir = 1 - }, -/obj/structure/window/reinforced, -/obj/machinery/door/firedoor/border_only, -/turf/simulated/floor/plating, -/area/submap/DoomP) -"bJ" = ( -/obj/structure/grille, -/obj/structure/window/reinforced{ - dir = 1 - }, -/obj/structure/window/reinforced, -/obj/structure/window/reinforced{ - dir = 4 - }, -/obj/machinery/door/firedoor/border_only, -/turf/simulated/floor/plating, -/area/submap/DoomP) -"bK" = ( -/obj/structure/lattice, -/turf/simulated/floor/outdoors/grass/sif/forest, -/area/submap/DoomP) -"ta" = ( -/mob/living/simple_animal/hostile/syndicate/melee/poi, -/turf/simulated/floor/tiled/techfloor, -/area/submap/DoomP) -"ND" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/mob/living/simple_animal/hostile/syndicate/ranged/poi, -/turf/simulated/floor/tiled, -/area/submap/DoomP) +"aa" = (/turf/template_noop,/area/template_noop) +"ab" = (/turf/template_noop,/area/submap/DoomP) +"ac" = (/turf/simulated/floor/outdoors/rocks,/area/submap/DoomP) +"ad" = (/turf/simulated/floor/outdoors/grass/sif/forest,/area/submap/DoomP) +"ae" = (/mob/living/simple_mob/mechanical/viscerator,/turf/template_noop,/area/submap/DoomP) +"af" = (/turf/simulated/floor/water,/area/submap/DoomP) +"ag" = (/obj/structure/flora/tree/sif,/turf/template_noop,/area/submap/DoomP) +"ah" = (/obj/random/landmine,/turf/simulated/floor/outdoors/grass/sif/forest,/area/submap/DoomP) +"ai" = (/mob/living/simple_mob/mechanical/viscerator,/turf/simulated/floor/outdoors/grass/sif/forest,/area/submap/DoomP) +"aj" = (/obj/effect/decal/cleanable/blood,/obj/random/landmine,/turf/simulated/floor/outdoors/grass/sif/forest,/area/submap/DoomP) +"ak" = (/turf/simulated/floor/water/deep,/area/submap/DoomP) +"al" = (/obj/effect/decal/cleanable/blood,/turf/simulated/floor/outdoors/grass/sif/forest,/area/submap/DoomP) +"am" = (/obj/random/landmine,/turf/simulated/floor/outdoors/rocks,/area/submap/DoomP) +"an" = (/obj/effect/decal/remains/mouse,/turf/simulated/floor/outdoors/grass/sif/forest,/area/submap/DoomP) +"ao" = (/obj/effect/decal/remains/deer,/turf/simulated/floor/outdoors/grass/sif/forest,/area/submap/DoomP) +"ap" = (/obj/effect/decal/remains/mouse,/obj/random/landmine,/turf/simulated/floor/outdoors/grass/sif/forest,/area/submap/DoomP) +"aq" = (/obj/structure/flora/tree/sif,/turf/simulated/floor/outdoors/grass/sif/forest,/area/submap/DoomP) +"ar" = (/obj/machinery/light/small,/turf/simulated/floor/outdoors/grass/sif/forest,/area/submap/DoomP) +"as" = (/obj/machinery/porta_turret/poi,/turf/simulated/floor/plating,/area/submap/DoomP) +"at" = (/turf/simulated/wall/r_wall,/area/submap/DoomP) +"au" = (/obj/structure/sign/warning/secure_area,/turf/simulated/wall/r_wall,/area/submap/DoomP) +"av" = (/obj/effect/floor_decal/industrial/warning,/turf/simulated/floor/plating,/area/submap/DoomP) +"aw" = (/obj/machinery/door/airlock/external,/turf/simulated/floor/plating,/area/submap/DoomP) +"ax" = (/obj/effect/floor_decal/borderfloor{dir = 9},/turf/simulated/floor/tiled,/area/submap/DoomP) +"ay" = (/obj/structure/bed/chair,/obj/effect/floor_decal/borderfloor{dir = 1},/turf/simulated/floor/tiled,/area/submap/DoomP) +"az" = (/obj/effect/floor_decal/borderfloor{dir = 1},/turf/simulated/floor/tiled,/area/submap/DoomP) +"aA" = (/obj/effect/floor_decal/borderfloor{dir = 1},/mob/living/simple_mob/humanoid/merc/ranged/smg/poi,/turf/simulated/floor/tiled,/area/submap/DoomP) +"aB" = (/obj/machinery/light/small{dir = 1},/obj/effect/floor_decal/borderfloor{dir = 1},/turf/simulated/floor/tiled,/area/submap/DoomP) +"aC" = (/obj/machinery/vending/cigarette,/obj/effect/floor_decal/borderfloor{dir = 5},/turf/simulated/floor/tiled,/area/submap/DoomP) +"aD" = (/obj/machinery/light/small{dir = 8},/turf/simulated/floor/tiled,/area/submap/DoomP) +"aE" = (/obj/machinery/power/smes/buildable/point_of_interest,/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/submap/DoomP) +"aF" = (/obj/machinery/power/smes/buildable/point_of_interest,/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/submap/DoomP) +"aG" = (/obj/machinery/power/apc{dir = 1; name = "PAPC"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/tiled/techfloor/grid,/area/submap/DoomP) +"aH" = (/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/machinery/power/port_gen/pacman,/turf/simulated/floor/plating,/area/submap/DoomP) +"aI" = (/obj/structure/table/standard,/obj/random/toolbox,/turf/simulated/floor/tiled/techfloor/grid,/area/submap/DoomP) +"aJ" = (/obj/structure/table/standard,/obj/item/stack/material/phoron{amount = 25},/turf/simulated/floor/tiled/techfloor/grid,/area/submap/DoomP) +"aK" = (/obj/structure/closet/secure_closet/engineering_electrical,/turf/simulated/floor/tiled/techfloor/grid,/area/submap/DoomP) +"aL" = (/obj/structure/lattice,/turf/simulated/floor/outdoors/rocks,/area/submap/DoomP) +"aM" = (/obj/structure/bed/chair{dir = 4},/obj/effect/floor_decal/borderfloor{dir = 8},/turf/simulated/floor/tiled,/area/submap/DoomP) +"aN" = (/obj/structure/table/standard,/turf/simulated/floor/tiled,/area/submap/DoomP) +"aO" = (/obj/structure/table/standard,/obj/item/pizzabox,/turf/simulated/floor/tiled,/area/submap/DoomP) +"aP" = (/turf/simulated/floor/tiled,/area/submap/DoomP) +"aQ" = (/obj/machinery/vending/snack,/obj/effect/floor_decal/borderfloor{dir = 4},/turf/simulated/floor/tiled,/area/submap/DoomP) +"aR" = (/obj/machinery/power/terminal{icon_state = "term"; dir = 1},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/tiled/techfloor/grid,/area/submap/DoomP) +"aS" = (/obj/machinery/power/terminal{icon_state = "term"; dir = 1},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/tiled/techfloor/grid,/area/submap/DoomP) +"aT" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/mob/living/simple_mob/humanoid/merc/melee/sword/poi,/turf/simulated/floor/tiled/techfloor/grid,/area/submap/DoomP) +"aU" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/tiled/techfloor/grid,/area/submap/DoomP) +"aV" = (/turf/simulated/floor/tiled/techfloor/grid,/area/submap/DoomP) +"aW" = (/obj/machinery/light/small,/turf/simulated/floor/tiled/techfloor/grid,/area/submap/DoomP) +"aX" = (/obj/structure/lattice,/turf/simulated/floor/water,/area/submap/DoomP) +"aY" = (/obj/machinery/light/small{dir = 8},/obj/effect/floor_decal/borderfloor{dir = 8},/turf/simulated/floor/tiled,/area/submap/DoomP) +"aZ" = (/obj/machinery/vending/cola,/obj/effect/floor_decal/borderfloor/corner{dir = 4},/turf/simulated/floor/tiled,/area/submap/DoomP) +"ba" = (/obj/machinery/door/airlock/external,/turf/simulated/floor/tiled,/area/submap/DoomP) +"bb" = (/obj/machinery/door/airlock/engineering,/turf/simulated/floor/tiled/techfloor/grid,/area/submap/DoomP) +"bc" = (/obj/structure/sign/electricshock,/turf/simulated/wall/r_wall,/area/submap/DoomP) +"bd" = (/obj/effect/floor_decal/borderfloor{dir = 10},/turf/simulated/floor/tiled,/area/submap/DoomP) +"be" = (/obj/effect/floor_decal/borderfloor,/turf/simulated/floor/tiled,/area/submap/DoomP) +"bf" = (/obj/machinery/light/small,/obj/effect/floor_decal/borderfloor,/turf/simulated/floor/tiled,/area/submap/DoomP) +"bg" = (/obj/effect/floor_decal/borderfloor/corner{dir = 8},/mob/living/simple_mob/humanoid/merc/ranged/laser/poi,/turf/simulated/floor/tiled,/area/submap/DoomP) +"bh" = (/obj/machinery/door/airlock/hatch,/turf/simulated/floor/tiled,/area/submap/DoomP) +"bi" = (/obj/machinery/light/small{dir = 1},/turf/simulated/floor/tiled,/area/submap/DoomP) +"bj" = (/obj/machinery/door/airlock/highsecurity,/turf/simulated/floor/tiled/techfloor,/area/submap/DoomP) +"bk" = (/obj/machinery/door/airlock,/turf/simulated/floor/tiled/white,/area/submap/DoomP) +"bl" = (/turf/simulated/floor/tiled/techfloor,/area/submap/DoomP) +"bm" = (/obj/structure/table/standard,/turf/simulated/floor/tiled/techfloor,/area/submap/DoomP) +"bn" = (/obj/structure/table/standard,/obj/item/weapon/storage/box/syndie_kit/spy,/turf/simulated/floor/tiled/techfloor,/area/submap/DoomP) +"bo" = (/obj/structure/table/rack,/obj/item/weapon/storage/box/smokes,/turf/simulated/floor/tiled/techfloor,/area/submap/DoomP) +"bp" = (/obj/structure/table/rack,/obj/item/weapon/storage/box/handcuffs,/turf/simulated/floor/tiled/techfloor,/area/submap/DoomP) +"bq" = (/obj/structure/table/rack,/obj/item/weapon/cell/device/weapon,/obj/item/weapon/cell/device/weapon,/turf/simulated/floor/tiled/techfloor,/area/submap/DoomP) +"br" = (/obj/structure/table/rack,/obj/random/energy,/turf/simulated/floor/tiled/techfloor,/area/submap/DoomP) +"bs" = (/obj/structure/table/rack,/obj/item/weapon/gun/projectile/contender,/obj/item/ammo_magazine/s357,/obj/item/ammo_magazine/s357,/turf/simulated/floor/tiled/techfloor,/area/submap/DoomP) +"bt" = (/obj/structure/bed,/obj/item/weapon/bedsheet,/obj/item/toy/plushie/spider,/obj/effect/floor_decal/corner/lime/full{dir = 8},/turf/simulated/floor/tiled/white,/area/submap/DoomP) +"bu" = (/obj/structure/table/standard,/obj/effect/floor_decal/corner/lime{dir = 5},/turf/simulated/floor/tiled/white,/area/submap/DoomP) +"bv" = (/obj/structure/bed,/obj/item/weapon/bedsheet,/obj/effect/floor_decal/corner/lime{dir = 5},/turf/simulated/floor/tiled/white,/area/submap/DoomP) +"bw" = (/obj/structure/table/standard,/obj/item/device/flashlight/lamp,/obj/effect/floor_decal/corner/lime{dir = 5},/turf/simulated/floor/tiled/white,/area/submap/DoomP) +"bx" = (/obj/structure/table/standard,/obj/structure/bedsheetbin,/obj/effect/floor_decal/corner/lime{dir = 1},/turf/simulated/floor/tiled/white,/area/submap/DoomP) +"by" = (/turf/simulated/floor/tiled/white,/area/submap/DoomP) +"bz" = (/obj/machinery/light/small{dir = 1},/turf/simulated/floor/tiled/white,/area/submap/DoomP) +"bA" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/tiled/white,/area/submap/DoomP) +"bB" = (/obj/machinery/light/small,/turf/simulated/floor/tiled/techfloor,/area/submap/DoomP) +"bC" = (/obj/machinery/light/small{dir = 8},/obj/effect/floor_decal/corner/lime/full,/turf/simulated/floor/tiled/white,/area/submap/DoomP) +"bD" = (/obj/effect/floor_decal/corner/lime{dir = 10},/turf/simulated/floor/tiled/white,/area/submap/DoomP) +"bE" = (/obj/machinery/light/small{dir = 4; pixel_y = 0},/obj/effect/floor_decal/corner/lime{dir = 10},/turf/simulated/floor/tiled/white,/area/submap/DoomP) +"bF" = (/obj/machinery/shower{dir = 1},/obj/structure/curtain/open/shower,/turf/simulated/floor/tiled/white,/area/submap/DoomP) +"bG" = (/obj/structure/toilet{dir = 1},/turf/simulated/floor/tiled/white,/area/submap/DoomP) +"bH" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/submap/DoomP) +"bI" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/submap/DoomP) +"bJ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/submap/DoomP) +"bK" = (/obj/structure/lattice,/turf/simulated/floor/outdoors/grass/sif/forest,/area/submap/DoomP) +"bL" = (/mob/living/simple_mob/humanoid/merc/melee/sword/poi,/turf/simulated/floor/tiled/techfloor,/area/submap/DoomP) (1,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -"} -(2,1,1) = {" -aa -ab -ae -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -"} -(3,1,1) = {" -aa -ab -ab -ab -ac -ac -ac -ac -ac -ac -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ac -ac -ac -ac -ac -ac -ac -ab -ab -ac -ac -ac -aa -"} -(4,1,1) = {" -aa -ab -ab -ac -ac -af -af -af -af -ac -ac -ac -ac -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ac -ac -ac -ac -af -af -af -af -af -ac -ac -ac -ac -af -ac -aa -"} -(5,1,1) = {" -aa -ab -ab -ac -af -af -af -af -af -af -af -af -ac -ac -ac -ab -ab -ab -ab -ab -ab -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ab -ab -ag -ab -ab -ab -ab -ab -ab -ab -ac -ac -ac -ac -af -af -af -af -af -af -af -af -af -af -af -af -ac -ac -aa -"} -(6,1,1) = {" -aa -ab -ab -ac -af -af -af -af -af -af -af -af -af -af -ac -ac -ac -ac -ae -ac -ac -ac -af -af -af -af -af -af -af -ac -ac -ab -ab -ab -ab -ab -ab -ab -ab -ac -ac -ac -ac -ac -af -af -af -af -af -af -af -af -af -af -af -af -ac -ac -ab -aa -"} -(7,1,1) = {" -aa -ab -ab -ac -af -af -af -af -af -af -af -af -af -af -af -af -ac -ac -ac -ac -af -af -af -af -af -af -af -af -af -af -ac -ac -ab -ab -ab -ab -ab -ac -ac -ac -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -ac -ac -ab -ab -aa -"} -(8,1,1) = {" -aa -ab -ab -ac -af -af -af -ak -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -ac -ac -ab -ac -ac -ac -ac -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -ac -ac -ab -ab -ab -aa -"} -(9,1,1) = {" -aa -ab -ab -ac -af -af -af -ak -ak -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -ac -ac -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -ac -ac -ab -ab -ab -ab -aa -"} -(10,1,1) = {" -aa -ab -ab -ac -ac -af -af -ak -ak -ak -af -af -af -af -af -af -af -af -af -ak -ak -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -ak -ak -af -af -af -af -ac -ac -ab -ab -ab -ab -ab -aa -"} -(11,1,1) = {" -aa -ab -ab -ab -ac -af -af -ak -ak -ak -ak -ak -af -af -af -af -af -af -af -ak -ak -ak -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -ak -ak -af -af -af -af -af -ac -ab -ab -ab -ab -ae -ab -aa -"} -(12,1,1) = {" -aa -ab -ab -ab -ac -af -af -ak -ak -ak -ak -ak -ak -af -af -af -af -af -ak -ak -ak -ak -ak -ak -af -af -af -af -af -af -ak -ak -ak -ak -af -af -af -ak -ak -ak -af -af -ak -ak -af -ak -ak -ak -ak -af -af -ac -ac -ab -ab -ab -ab -ab -ab -aa -"} -(13,1,1) = {" -aa -ab -ab -ab -ac -af -af -ak -ak -ak -ak -ak -ak -ak -af -ak -af -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -af -af -ac -ab -ab -ab -ab -ab -ab -ab -aa -"} -(14,1,1) = {" -aa -ab -ab -ab -ac -af -af -af -af -af -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -af -af -ac -ab -ab -ab -ab -ab -ab -ab -aa -"} -(15,1,1) = {" -aa -ab -ab -ab -ac -ac -af -af -af -af -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -af -af -ac -ab -ab -ab -ab -ab -ab -ab -aa -"} -(16,1,1) = {" -aa -ab -ab -ab -ab -ac -af -af -af -af -af -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -af -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -af -ac -ab -ab -ab -ab -ab -ab -ab -aa -"} -(17,1,1) = {" -aa -ab -ab -ab -ab -ac -af -af -af -af -af -ak -ak -ak -ak -ak -ak -ak -af -ak -ak -ak -af -af -af -af -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -af -ak -ak -af -ac -ab -ab -ab -ab -ab -ab -ab -aa -"} -(18,1,1) = {" -aa -ab -ab -ag -ae -ac -af -af -af -af -af -ak -ak -ak -ak -ak -ak -af -af -af -ak -af -af -af -af -af -af -af -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -af -af -ak -ak -af -ac -ab -ab -ab -ag -ab -ab -ac -aa -"} -(19,1,1) = {" -aa -ab -ab -ab -ab -ac -af -af -af -af -ak -ak -ak -ak -ak -ak -ak -af -af -af -ak -af -af -af -af -af -af -af -af -af -af -af -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -af -af -af -af -af -ac -ac -ab -ab -ab -ab -ac -ac -aa -"} -(20,1,1) = {" -aa -ab -ab -ab -ac -ac -af -af -af -af -ak -ak -ak -ak -ak -ak -af -af -af -af -af -af -af -af -af -af -af -af -af -af -as -af -af -as -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -af -af -af -af -af -af -ac -ab -ac -ac -ac -ac -ac -aa -"} -(21,1,1) = {" -aa -ab -ab -ab -ac -af -af -af -af -af -ak -ak -ak -ak -ak -ak -af -af -af -af -af -af -af -af -ac -ac -ac -ac -ac -ac -aL -af -af -aX -af -af -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -af -af -af -af -af -af -ac -ac -ac -af -af -af -ac -aa -"} -(22,1,1) = {" -aa -ab -ab -ab -ac -af -af -af -af -af -ak -ak -ak -ak -ak -af -af -af -af -af -af -af -af -ac -ac -ad -ad -ad -at -at -at -at -at -at -at -at -at -af -ak -ak -ak -ak -ak -ak -ak -ak -af -af -af -af -af -af -af -af -af -af -af -af -ac -aa -"} -(23,1,1) = {" -aa -ab -ab -ac -ac -af -af -af -ak -ak -ak -ak -ak -ak -ak -af -af -af -af -af -af -af -ac -ac -ad -ad -ad -ad -at -ax -aM -aY -bd -bj -bl -bl -at -af -ak -ak -ak -ak -ak -ak -ak -ak -ak -af -af -af -af -af -af -af -af -af -af -af -ac -aa -"} -(24,1,1) = {" -aa -ab -ab -ac -af -af -af -af -ak -ak -ak -ak -ak -ak -af -af -af -af -af -af -af -ac -ac -ad -ad -ad -ad -as -at -ay -aN -aN -be -at -bm -bl -at -af -af -ak -ak -ak -ak -ak -ak -ak -ak -ak -af -af -af -af -af -af -af -af -af -af -ac -aa -"} -(25,1,1) = {" -aa -ab -ab -ac -af -af -af -af -ak -ak -ak -ak -ak -af -af -af -af -af -af -af -ac -ac -ad -ad -ad -ad -ad -ad -at -ND -aO -aN -be -at -bn -bB -at -af -af -af -af -ak -ak -ak -ak -ak -ak -ak -ak -ak -af -af -af -af -af -af -af -af -ac -aa -"} -(26,1,1) = {" -aa -ab -ab -ac -af -af -af -af -ak -ak -ak -ak -ak -af -af -af -af -af -af -af -ac -ad -ad -ad -ad -ad -ad -ad -at -ay -aN -aN -bf -at -bo -bl -at -aL -as -af -af -af -af -ak -ak -ak -ak -ak -ak -ak -ak -ak -af -af -af -af -af -ac -ac -aa -"} -(27,1,1) = {" -aa -ab -ab -ac -af -af -af -ak -ak -ak -ak -ak -ak -ak -af -af -af -af -af -ac -ac -ad -ad -ad -ad -ad -ad -as -at -aB -aN -aN -be -at -bp -ta -at -ac -af -af -af -af -af -ak -ak -ak -ak -ak -ak -ak -ak -ak -af -af -af -af -af -ac -ab -aa -"} -(28,1,1) = {" -aa -ab -ab -ac -ac -af -af -ak -ak -ak -ak -ak -ak -ak -ak -af -af -af -af -ac -ad -aq -ad -ad -ad -ad -ad -ad -at -ay -aN -aN -be -at -bq -bB -at -ac -ac -af -af -af -af -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -af -af -af -af -ac -ab -aa -"} -(29,1,1) = {" -aa -ab -ab -ac -ac -af -af -ak -ak -ak -ak -ak -ak -ak -ak -af -af -af -af -ac -ad -ad -ad -ad -ad -ad -ar -at -at -az -aP -aP -bg -at -br -bl -at -ad -ac -af -af -af -af -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -af -af -af -af -ac -ab -aa -"} -(30,1,1) = {" -aa -ab -ab -ac -ac -af -af -ak -ak -ak -ak -ak -ak -ak -ak -af -af -af -af -ac -ad -ad -ad -ad -ad -ad -ad -au -at -aC -aQ -aZ -aP -at -bs -bl -at -ad -ac -af -af -af -af -af -ak -ak -ak -ak -ak -ak -ak -ak -af -af -af -af -af -ac -ab -aa -"} -(31,1,1) = {" -aa -ab -ab -ab -ac -af -af -ak -ak -ak -ak -ak -ak -ak -ak -af -af -af -af -ac -ad -ad -aq -ad -ad -ad -ad -av -at -at -at -at -bh -at -at -at -at -ad -ac -af -af -af -af -af -af -ak -ak -ak -ak -ak -ak -ak -af -af -af -af -ac -ac -ab -aa -"} -(32,1,1) = {" -aa -ab -ab -ab -ac -af -af -ak -ak -ak -ak -ak -ak -ak -ak -af -af -af -af -ac -ad -ad -ad -ad -ad -ad -ad -av -aw -aD -aP -ba -aP -at -bt -bC -at -ad -ac -ac -af -af -af -af -af -ak -ak -ak -ak -ak -ak -ak -af -af -af -af -ac -ab -ab -aa -"} -(33,1,1) = {" -aa -ab -ab -ac -af -af -af -ak -ak -ak -ak -ak -ak -ak -ak -af -af -af -af -ac -ac -ad -ad -ad -ad -ad -ad -av -at -at -at -at -aP -at -bu -bD -at -bK -as -ac -ac -af -af -af -af -ak -ak -ak -ak -ak -ak -ak -af -af -af -af -ac -ab -ab -aa -"} -(34,1,1) = {" -aa -ab -ab -ac -af -af -af -af -ak -ak -ak -ak -ak -ak -ak -af -af -af -af -af -ac -ad -ad -ad -ad -ad -ad -au -at -aE -aR -at -bi -at -bv -bD -bH -ad -ad -ad -ac -af -af -af -af -ak -ak -ak -ak -ak -ak -ak -af -af -af -af -ac -ab -ab -aa -"} -(35,1,1) = {" -aa -ab -ab -ac -af -af -af -af -ak -ak -ak -ak -ak -ak -ak -af -af -af -af -af -ac -ad -ah -ad -ad -ad -ar -at -at -aF -aS -at -aP -at -bw -bD -bI -ad -ad -ad -ac -af -af -af -af -ak -ak -ak -ak -ak -ak -ak -af -af -af -ac -ac -ab -ab -aa -"} -(36,1,1) = {" -aa -ab -ac -ac -af -af -af -af -ak -af -ak -ak -ak -af -ak -af -af -af -af -ac -ac -ad -ad -ad -ad -ad -ad -ad -at -aF -aS -at -aP -at -bv -bD -bI -ad -ad -ad -ac -af -af -af -af -ak -ak -ak -ak -ak -ak -ak -af -af -af -ac -ab -ab -ab -aa -"} -(37,1,1) = {" -aa -ac -ac -af -af -af -af -af -af -af -ak -af -af -af -af -af -af -af -ac -am -ad -ad -ad -ad -ad -ad -ad -as -at -aF -aS -at -aP -at -bx -bD -bI -ad -ad -ad -ac -af -af -af -af -ak -ak -ak -ak -ak -ak -ak -af -af -af -ac -ac -ab -ab -aa -"} -(38,1,1) = {" -aa -ac -af -af -af -af -af -af -af -af -ak -af -af -af -af -af -af -ac -ac -ad -ad -ad -ad -ac -ad -ad -ad -ad -at -aG -aT -at -aP -bk -by -bE -bJ -ad -ad -ad -ac -af -af -af -af -ak -ak -ak -ak -ak -ak -ak -af -af -af -ac -ac -ab -ab -aa -"} -(39,1,1) = {" -aa -ac -af -af -af -af -af -af -af -af -ak -af -af -af -af -af -ac -ac -ad -ad -ac -ac -am -ac -ac -ad -ad -ad -at -aH -aU -bb -aP -at -bk -at -at -bK -as -ac -ac -af -af -af -af -ak -ak -ak -ak -ak -ak -ak -ak -af -af -ac -ac -ab -ab -aa -"} -(40,1,1) = {" -aa -ac -af -af -af -af -af -af -af -af -af -af -af -af -af -ac -ac -ah -ad -ac -ac -af -af -af -ac -ac -ad -as -at -aI -aV -bc -bi -at -bz -bF -at -ac -ac -ac -af -af -af -af -af -ak -ak -ak -ak -ak -ak -ak -af -af -af -ac -ac -ab -ab -aa -"} -(41,1,1) = {" -aa -ac -af -af -af -af -af -af -af -ac -af -af -af -af -af -ac -ad -ad -ad -ac -af -af -af -af -af -ac -ac -ad -at -aJ -aW -at -aP -at -bk -at -at -ac -af -af -af -af -af -af -af -ak -ak -ak -ak -ak -ak -af -af -af -af -af -ac -ab -ab -aa -"} -(42,1,1) = {" -aa -ac -af -af -af -af -af -ac -ac -ac -ac -af -ac -ac -am -ac -ah -ad -am -ac -af -af -af -af -af -af -ac -ac -at -aK -aV -at -aP -at -bA -bG -at -af -af -af -af -af -af -af -af -ak -ak -ak -ak -ak -ak -ak -af -af -af -af -ac -ac -ab -aa -"} -(43,1,1) = {" -aa -ac -af -af -af -af -ac -ac -ad -an -ac -ac -am -ac -ac -ad -ad -ad -ac -af -af -af -af -af -af -af -af -af -at -at -at -at -at -at -at -at -at -af -af -af -af -af -af -af -af -af -ak -ak -ak -ak -ak -ak -af -af -af -af -af -ac -ab -aa -"} -(44,1,1) = {" -aa -ac -ac -af -af -af -ac -ad -ah -ad -ad -ad -ad -ad -ad -ad -ah -ac -ac -af -af -af -af -af -af -af -af -af -af -af -aX -af -af -aX -af -af -af -af -af -af -af -af -af -af -af -af -ak -ak -ak -ak -ak -ak -af -af -af -af -af -ac -ab -aa -"} -(45,1,1) = {" -aa -ab -ac -af -af -ac -ac -al -ad -ad -ad -ad -ah -ad -ad -ad -ad -ac -af -af -af -af -af -af -af -af -af -af -af -af -as -af -af -as -af -af -af -af -af -af -af -af -af -af -af -ak -ak -ak -ak -ak -ak -ak -ak -af -af -af -af -ac -ab -aa -"} -(46,1,1) = {" -aa -ab -ac -af -ac -ac -ah -ad -ad -ad -ah -ad -ad -ad -ap -ad -ac -ac -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -ak -af -af -af -af -af -ak -ak -ak -ak -ak -ak -ak -ak -af -af -af -af -ac -ab -aa -"} -(47,1,1) = {" -aa -ab -ac -ac -ac -ad -ad -ad -ad -ao -ad -ai -ad -ad -ac -ac -ac -af -af -af -af -af -ak -ak -ak -af -af -af -af -af -af -af -af -af -af -af -af -af -ak -ak -ak -af -af -af -ak -ak -ak -ak -ak -ak -ak -ak -ak -af -af -af -af -ac -ab -aa -"} -(48,1,1) = {" -aa -ab -ab -ac -ad -ai -ad -ah -ad -ad -ad -ad -ac -ac -ac -af -af -af -af -af -ak -ak -ak -ak -ak -ak -af -af -af -af -af -af -af -af -af -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -af -af -af -ac -ac -aa -"} -(49,1,1) = {" -aa -ab -ab -ac -ad -ad -ad -ad -ad -ah -ac -ac -ac -af -af -af -af -af -af -af -af -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -af -af -af -af -ac -aa -"} -(50,1,1) = {" -aa -ab -ac -ac -ah -ad -ad -ad -ad -ac -ac -am -af -af -af -af -af -af -af -af -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -af -af -af -ac -aa -"} -(51,1,1) = {" -aa -ab -ad -ad -ad -aj -ad -ad -am -ac -af -af -af -af -af -af -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -af -af -af -af -af -ak -ak -ak -ak -ak -ak -af -ak -ak -af -af -af -ac -aa -"} -(52,1,1) = {" -aa -ad -ad -ad -ad -ac -ac -ac -ac -af -af -af -af -af -af -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -af -af -af -af -af -ak -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -ac -ac -aa -"} -(53,1,1) = {" -aa -ad -ad -ah -ac -ac -af -af -af -af -af -af -af -af -af -af -af -ak -ak -ak -af -af -af -ak -ak -ak -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -ac -ac -ab -aa -"} -(54,1,1) = {" -aa -ad -ad -ad -ac -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -ak -ak -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -ac -ac -ac -ab -aa -"} -(55,1,1) = {" -aa -ab -ad -ac -ac -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -ac -ac -ac -ab -ab -ab -aa -"} -(56,1,1) = {" -aa -ab -ac -af -af -af -af -af -af -af -af -af -af -af -ac -ac -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -ac -ac -ac -af -af -af -af -ac -ac -ac -ac -ab -ab -ab -ab -ab -aa -"} -(57,1,1) = {" -aa -ab -ac -af -af -af -af -af -af -af -af -af -af -af -ac -ac -ac -ac -af -af -af -af -ac -ac -af -af -af -af -ac -ac -af -af -af -af -af -af -af -af -af -af -ac -ac -ac -ac -ab -ac -ac -ac -ac -ac -ac -ab -ab -ab -ab -ab -ab -ab -ab -aa -"} -(58,1,1) = {" -aa -ae -ac -ac -ac -ac -af -af -af -af -af -ac -ac -ac -ac -ab -ab -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -af -af -af -af -af -af -ac -ac -ac -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ag -ab -ab -ab -ab -aa -"} -(59,1,1) = {" -aa -ab -ab -ab -ab -ac -ac -ac -ac -ac -ac -ac -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ac -ac -ac -ac -ac -ac -ac -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ae -ab -ab -ab -ab -ab -aa -"} -(60,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -"} +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaabababababababababababababababababababababababababababababababababababacacacacacacacacabababababababadadadabababaeabaa +aaaeabababababababababababababababababababababababababababababababababacacafafafafafafacacacacababacadadadadadacacacabaa +aaababacacacacacacacabababababababagababababacacacacacacacacababacacacacafafafafafafafafafafacacacacadadahadacafafacabaa +aaabacacafafafafafacacacacacacababaeabacacacacafafafafacacacacacafafafafafafafafafafafafafacacadadahadadacacacafafacabaa +aaabacafafafafafafafafafafafacacacacacacafafafafafafafafafafafafafafafafafafafafafafafafacacadaiadadajacacafafafafacacaa +aaabacafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafacacacahadadadadadacafafafafafafacaa +aaabacafafafafakakakakakakafafafafafafafafafafafafafakakakakakakakafafafafafafafafacacadaladadahadadadacafafafafafafacaa +aaabacafafafafafakakakakakafafafafafafafafafakakakakakakakakakakakakakakafafafafafacadahadadadadadadamacafafafafafafacaa +aaabacacafafafafafakakakakafafafafafafafafafakakakakakakakakakakakakakafafafafafacacanadadadaoadahacacafafafafafafafacaa +aaababacafafafafafafakakakakakafafafakakakakakakakakakakakakakakakakakakakakakafafacacadadahadadacacafafafafafafafafacaa +aaababacafafafafafafakakakakakakakakakakakakakakakakakakakakakakakakakakafafafafafafacadadadaiadacamafafafafafafafacacaa +aaababacacafafafafafafakakakakakakakakakakakakakakakakakakakakakakakakakafafafafafacamadahadadacacafafafafafafafafacabaa +aaabababacafafafafafafafakakakakakakakakakakakakafafakakakakakakakakakafafafafafafacacadadadadacafafafafafafafafafacabaa +aaabababacacafafafafafafafakakakakakakakakakakafafafafakakakakakakakakakafafafafafamacadadapacacafafafafafafafacacacabaa +aaababababacafafafafafafakakakakakakakakakafafafafafafafafafafafafafafafafafafacacacadadadadacafafafafakafafafacacababaa +aaababababacacafafafafafafakakakakakakafafafafafafafafafafafafafafafafafafafacacadahadahadacacafafafakakafafafafacababaa +aaababababacacafafafafafakakakakakafafafafafafafafafafafafafafafafafafafafacacahadadadacacacafafafafakakakafafafacacabaa +aaababababaeacafafafafakakakakakafafafafafafafafafafafafafafafafafafafafacacadadadamacacafafafafafafakakakafafafafacabaa +aaababababacacafafakakakakakakakakafafafafafafafafafacacacacacacacafafacamadadacacacafafafafafafafafakakakafafafafacabaa +aaababababacafafafakakakakakakakakakakafafafafafacacacadadadadadacacacacadadacacafafafafafafafakafakakakafafafafafacabaa +aaabababacacafafafafakakakakakakakafafafafafafacacadadaqadadadadadadadadadadacafafafafafafafafakakakakakafafafafafacabaa +aaabababacafafafafafafakakakakakafafafafafafacacadadadadadadaqadadadahadadadamafafafafafafafakakakakakakafafafafacacabaa +aaabababacafafafafafafakakakakakafafafafafacacadadadadadadadadadadadadadadacacafafafafafafafakakakakakakakakafafacacabaa +aaabababacafafafafafafafakakakakafafafafacacadadadadadadadadadadadadadadadadacacafafafafafafakakakakakakakakafafafacabaa +aaabababacafafafafafafafakakakafafafafafacadadadadadadadadadadadadadadadadadadacacafafafafafafakakakakakakafafafafacabaa +aaabababacafafafafafafafakakakakakafafafacadadadadadadadaradadadadadaradadadadadacacafafafafafafakakakakafafafafafacabaa +aaabababacafafafafafafafakakakakakafafafacadadasadadasadatauavavavauatadasadadasadacafafafafafafakakakakafafafafafacabaa +aaabababacafafafafafafafakakakakakakafafacatatatatatatatatatatawatatatatatatatatatatatafafafafafakakakakafafafafacacabaa +aaabababacacafafafafafafakakakakakakafafacataxayaAayaBayazaCataDataEaFaFaFaGaHaIaJaKatafafafafafakakakakafafafafacacabaa +aaabababacacacafafafafakakakakakakakafasaLataMaNaOaNaNaNaPaQataPataRaSaSaSaTaUaVaWaVataXasafafafakakakafafafafafafacabaa +aaabababababacacafafafakakakakakakakafafafataYaNaNaNaNaNaPaZatbaatatatatatatbbbcatatatafafafafafakakakafafafafafafacabaa +aaababababababacafafafakakakakakakakakafafatbdbebebfbebebgaPbhaPaPbiaPaPaPaPaPbiaPaPatafafafafafakakakafafafafafafafacaa +aaabababagabababacafafakakakakakakakakasaXatbjatatatatatatatatatatatatatatbkatatatatataXasafafafakakakafafafafafafafacaa +aaababababababacacafafafakakakakakakakakafatblbmbnbobpbqbrbsatbtbubvbwbvbxbybkbzbkbAatafafafafafakakakafafafafafafafacaa +aaababababababacafafafafakakakakakakakakafatblblbBblbLbBblblatbCbDbDbDbDbDbEatbFatbGatafafafafakakakakakafafafafafafacaa +aaababababababacafafafafakakakakakakakakakatatatatatatatatatatatatbHbIbIbIbJatatatatatafafafafakakakakafafafafafafafacaa +aaabababababacacafafafakakakakakakakakakakafafafafaLacacadadadadbKadadadadadbKacacafafafafafafakakakakafafafafafafafacaa +aaabababababacafafafafakakakakakakakakakakakakafafasafacacacacacasadadadadadasacafafafafafafakakakakakafafafafafafacacaa +aaababababacacafafafafakakakakakakakakakakakakakafafafafafafafacacadadadadadacacafafafafafakakakakakakafafafafafafacabaa +aaababababacafafafafafafakakakakakakakakakakakakafafafafafafafafacacacacacacacafafafafafafafakakakakakafafafafafacacabaa +aaabababacacafafafafafafakakakakakakakakakakakakakafafafafafafafafafafafafafafafafafafafafafafakakakafafafafafafacababaa +aaabababacacafafafafafakakakakakakakakakakakakakakafafafafafafafafafafafafafafafafafafafafafafakakakafafafafafafacababaa +aaabababacacafafafafafakakakakakakakakakakakakakakakakakakafafafafafafafafafafafafafafafafafafakakakafafafafafacacababaa +aaababacacafafafafafafafakakakakakakakakakakakakakakakakakakafafafafafafafafafafafafafafafafakakakakafafafafafacabababaa +aaababacafafafafafafakakakakakakakakakakakakakakakakakakakakakakakakakakakakakakakakafafakakakakakakafafafafafacacababaa +aaababacafafafafafakakakakakakakakafafafafafakakakakakakakakakakakakakakakakakakakakakakakakakakakakakafafafafafacababaa +aaabacacafafafafafakafakakakakakafafafafafafafakakakakakakakakakakakakakakakakakakakakakakakakakakakakafafafafafacababaa +aaabacafafafafafafafafakakakakakakakafafafafafafakakakakakakakakakakakakakakakakakakakakakakakakakakakafafafafafacababaa +aaabacafafafafafafafafafafafafakakakafafafafafafakakakakakakakakakakakakakakakakakakakakakakakakakakakafafafafafacababaa +aaabacafafafafafafafafafafafafafafafafafafafafafafakakakakakakakakakakakakakakakakakakakakakakakakakakafafafafacacababaa +aaabacafafafafafafafafacacacacacacacacafafafafafafakakakakakakakakakakakakakakakafakakakakakakakakakakafafafafacabababaa +aaabacafafafafafafacacacababababababacacacafafafafafafakakafafafafafafafafafakafafafafafakakakakakakafafafafafacabababaa +aaabacacafafafafacacababababababababababacafafafafafafafafafafafafafafafafafafafafafafafafafafakakakakafafafacacababaeaa +aaababacafafafacacababababababababababacacafafafafafafafafafafafafafafafafafafafafafafafafafafafafakakafafafacababagabaa +aaababacafafacacabababababababababagabacafafafafafafafafafafafafafafacacacacacacafafafafafafafafafafafafafacacababababaa +aaabacacafacacababababababababababababacafafafafafafafafafafacacacacacabacacacacacacafafafafafafafafafafacacabababababaa +aaabacafacacababababaeabababababababacacafafafafafacacacacacacababababababababababacacacacacacacafafafacacacabababababaa +aaabacacacababababababababababababacacacacacacacacacabababababababababababababababababababababacacacacacabababababababaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +"} \ No newline at end of file diff --git a/maps/submaps/surface_submaps/wilderness/Drugden.dmm b/maps/submaps/surface_submaps/wilderness/Drugden.dmm index f865bdc581..3d8f3257a3 100644 --- a/maps/submaps/surface_submaps/wilderness/Drugden.dmm +++ b/maps/submaps/surface_submaps/wilderness/Drugden.dmm @@ -1,906 +1,75 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"a" = ( -/turf/template_noop, -/area/template_noop) -"b" = ( -/turf/template_noop, -/area/submap/Drugd) -"c" = ( -/turf/simulated/mineral/ignore_mapgen, -/area/submap/Drugd) -"d" = ( -/turf/simulated/wall, -/area/submap/Drugd) -"e" = ( -/obj/machinery/door/airlock, -/turf/simulated/floor, -/area/submap/Drugd) -"f" = ( -/turf/simulated/floor/tiled, -/area/submap/Drugd) -"g" = ( -/obj/effect/floor_decal/rust, -/turf/simulated/floor/tiled, -/area/submap/Drugd) -"h" = ( -/obj/random/trash, -/turf/simulated/floor, -/area/submap/Drugd) -"i" = ( -/obj/structure/closet/cabinet, -/obj/item/weapon/lipstick/random, -/turf/simulated/floor/carpet, -/area/submap/Drugd) -"j" = ( -/obj/structure/bed, -/obj/item/weapon/bedsheet, -/obj/structure/curtain/open/bed, -/turf/simulated/floor/carpet, -/area/submap/Drugd) -"k" = ( -/obj/structure/table/woodentable, -/obj/item/weapon/reagent_containers/pill/happy{ - name = "pill" - }, -/turf/simulated/floor/carpet, -/area/submap/Drugd) -"l" = ( -/turf/simulated/floor, -/area/submap/Drugd) -"m" = ( -/obj/structure/curtain/black, -/turf/simulated/floor, -/area/submap/Drugd) -"n" = ( -/obj/random/trash, -/turf/simulated/floor/carpet, -/area/submap/Drugd) -"o" = ( -/turf/simulated/floor/carpet, -/area/submap/Drugd) -"p" = ( -/mob/living/simple_animal/mouse, -/turf/simulated/floor, -/area/submap/Drugd) -"q" = ( -/obj/structure/closet/cabinet, -/turf/simulated/floor/carpet, -/area/submap/Drugd) -"r" = ( -/obj/structure/table/woodentable, -/obj/item/weapon/reagent_containers/pill/methylphenidate{ - name = "pill" - }, -/turf/simulated/floor/carpet, -/area/submap/Drugd) -"s" = ( -/obj/structure/bed/chair/comfy/beige{ - icon_state = "armchair_preview"; - dir = 1 - }, -/turf/simulated/floor/carpet, -/area/submap/Drugd) -"t" = ( -/obj/item/weapon/reagent_containers/pill/citalopram{ - name = "pill" - }, -/turf/simulated/floor/carpet, -/area/submap/Drugd) -"u" = ( -/obj/random/junk, -/turf/simulated/floor, -/area/submap/Drugd) -"v" = ( -/obj/structure/closet/cabinet, -/obj/item/weapon/contraband/poster, -/turf/simulated/floor/carpet, -/area/submap/Drugd) -"w" = ( -/obj/structure/bed/chair/comfy/beige, -/turf/simulated/floor/carpet, -/area/submap/Drugd) -"x" = ( -/obj/structure/table/woodentable, -/obj/item/device/flashlight/lamp, -/obj/item/weapon/reagent_containers/syringe/drugs, -/turf/simulated/floor/carpet, -/area/submap/Drugd) -"y" = ( -/obj/structure/bed/chair/comfy/beige, -/obj/item/weapon/reagent_containers/pill/citalopram{ - name = "pill" - }, -/turf/simulated/floor/carpet, -/area/submap/Drugd) -"z" = ( -/obj/structure/loot_pile/maint/junk, -/turf/simulated/floor, -/area/submap/Drugd) -"A" = ( -/obj/item/weapon/reagent_containers/pill/citalopram{ - name = "pill" - }, -/obj/item/weapon/reagent_containers/pill/citalopram{ - name = "pill" - }, -/turf/simulated/floor/carpet, -/area/submap/Drugd) -"B" = ( -/obj/structure/table/standard, -/obj/item/weapon/storage/pill_bottle/happy, -/turf/simulated/floor/tiled, -/area/submap/Drugd) -"C" = ( -/obj/structure/table/standard, -/obj/item/stack/medical/splint, -/turf/simulated/floor/tiled, -/area/submap/Drugd) -"D" = ( -/obj/structure/table/standard, -/obj/item/weapon/reagent_containers/pill/citalopram, -/obj/item/weapon/reagent_containers/pill/citalopram, -/turf/simulated/floor/tiled, -/area/submap/Drugd) -"E" = ( -/obj/structure/table/standard, -/obj/item/weapon/reagent_containers/pill/tramadol, -/obj/item/weapon/reagent_containers/pill/tramadol, -/turf/simulated/floor/tiled, -/area/submap/Drugd) -"F" = ( -/obj/structure/closet/cabinet, -/obj/item/clothing/accessory/jacket, -/obj/item/weapon/material/butterfly/switchblade, -/turf/simulated/floor/carpet, -/area/submap/Drugd) -"G" = ( -/obj/item/weapon/reagent_containers/pill/zoom{ - name = "pill" - }, -/obj/random/trash, -/turf/simulated/floor/carpet, -/area/submap/Drugd) -"H" = ( -/obj/item/weapon/reagent_containers/pill/zoom{ - name = "pill" - }, -/turf/simulated/floor/carpet, -/area/submap/Drugd) -"I" = ( -/obj/structure/loot_pile/maint/boxfort, -/turf/simulated/floor/carpet, -/area/submap/Drugd) -"J" = ( -/obj/structure/table/standard, -/obj/item/weapon/surgical/scalpel, -/turf/simulated/floor/tiled, -/area/submap/Drugd) -"K" = ( -/obj/item/wheelchair, -/turf/simulated/floor/tiled, -/area/submap/Drugd) -"L" = ( -/obj/structure/table/standard, -/obj/random/firstaid, -/turf/simulated/floor, -/area/submap/Drugd) -"M" = ( -/obj/structure/loot_pile/maint/junk, -/turf/simulated/floor/tiled, -/area/submap/Drugd) -"N" = ( -/obj/effect/floor_decal/rust, -/obj/structure/table/standard, -/turf/simulated/floor/tiled, -/area/submap/Drugd) -"O" = ( -/obj/structure/table/standard, -/obj/item/weapon/reagent_containers/pill/zoom, -/obj/item/weapon/reagent_containers/pill/zoom, -/turf/simulated/floor, -/area/submap/Drugd) -"P" = ( -/obj/structure/table/woodentable, -/obj/item/weapon/reagent_containers/pill/tramadol{ - name = "pill" - }, -/turf/simulated/floor/carpet, -/area/submap/Drugd) -"Q" = ( -/mob/living/simple_animal/hostile/hivebot/range/guard, -/turf/simulated/floor, -/area/submap/Drugd) -"R" = ( -/obj/structure/girder, -/turf/simulated/floor, -/area/submap/Drugd) -"S" = ( -/obj/item/weapon/material/shard, -/turf/simulated/floor, -/area/submap/Drugd) -"T" = ( -/obj/structure/table/woodentable, -/obj/item/device/flashlight/lamp, -/turf/simulated/floor/carpet, -/area/submap/Drugd) -"U" = ( -/obj/structure/table/woodentable, -/obj/item/weapon/reagent_containers/syringe/drugs, -/turf/simulated/floor/carpet, -/area/submap/Drugd) +"a" = (/turf/template_noop,/area/template_noop) +"b" = (/turf/template_noop,/area/submap/Drugd) +"c" = (/turf/simulated/mineral/ignore_mapgen,/area/submap/Drugd) +"d" = (/turf/simulated/wall,/area/submap/Drugd) +"e" = (/obj/machinery/door/airlock,/turf/simulated/floor,/area/submap/Drugd) +"f" = (/turf/simulated/floor/tiled,/area/submap/Drugd) +"g" = (/obj/effect/floor_decal/rust,/turf/simulated/floor/tiled,/area/submap/Drugd) +"h" = (/obj/random/trash,/turf/simulated/floor,/area/submap/Drugd) +"i" = (/obj/structure/closet/cabinet,/obj/item/weapon/lipstick/random,/turf/simulated/floor/carpet,/area/submap/Drugd) +"j" = (/obj/structure/bed,/obj/item/weapon/bedsheet,/obj/structure/curtain/open/bed,/turf/simulated/floor/carpet,/area/submap/Drugd) +"k" = (/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/pill/happy{name = "pill"},/turf/simulated/floor/carpet,/area/submap/Drugd) +"l" = (/turf/simulated/floor,/area/submap/Drugd) +"m" = (/obj/structure/curtain/black,/turf/simulated/floor,/area/submap/Drugd) +"n" = (/obj/random/trash,/turf/simulated/floor/carpet,/area/submap/Drugd) +"o" = (/turf/simulated/floor/carpet,/area/submap/Drugd) +"p" = (/obj/effect/decal/remains/mouse,/turf/simulated/floor,/area/submap/Drugd) +"q" = (/obj/structure/closet/cabinet,/turf/simulated/floor/carpet,/area/submap/Drugd) +"r" = (/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/pill/methylphenidate{name = "pill"},/turf/simulated/floor/carpet,/area/submap/Drugd) +"s" = (/obj/structure/bed/chair/comfy/beige{icon_state = "armchair_preview"; dir = 1},/turf/simulated/floor/carpet,/area/submap/Drugd) +"t" = (/obj/item/weapon/reagent_containers/pill/citalopram{name = "pill"},/turf/simulated/floor/carpet,/area/submap/Drugd) +"u" = (/obj/random/junk,/turf/simulated/floor,/area/submap/Drugd) +"v" = (/obj/structure/closet/cabinet,/obj/item/weapon/contraband/poster,/turf/simulated/floor/carpet,/area/submap/Drugd) +"w" = (/obj/structure/bed/chair/comfy/beige,/turf/simulated/floor/carpet,/area/submap/Drugd) +"x" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp,/obj/item/weapon/reagent_containers/syringe/drugs,/turf/simulated/floor/carpet,/area/submap/Drugd) +"y" = (/obj/structure/bed/chair/comfy/beige,/obj/item/weapon/reagent_containers/pill/citalopram{name = "pill"},/turf/simulated/floor/carpet,/area/submap/Drugd) +"z" = (/obj/structure/loot_pile/maint/junk,/turf/simulated/floor,/area/submap/Drugd) +"A" = (/obj/item/weapon/reagent_containers/pill/citalopram{name = "pill"},/obj/item/weapon/reagent_containers/pill/citalopram{name = "pill"},/turf/simulated/floor/carpet,/area/submap/Drugd) +"B" = (/obj/structure/table/standard,/obj/item/weapon/storage/pill_bottle/happy,/turf/simulated/floor/tiled,/area/submap/Drugd) +"C" = (/obj/structure/table/standard,/obj/item/stack/medical/splint,/turf/simulated/floor/tiled,/area/submap/Drugd) +"D" = (/obj/structure/table/standard,/obj/item/weapon/reagent_containers/pill/citalopram,/obj/item/weapon/reagent_containers/pill/citalopram,/turf/simulated/floor/tiled,/area/submap/Drugd) +"E" = (/obj/structure/table/standard,/obj/item/weapon/reagent_containers/pill/tramadol,/obj/item/weapon/reagent_containers/pill/tramadol,/turf/simulated/floor/tiled,/area/submap/Drugd) +"F" = (/obj/structure/closet/cabinet,/obj/item/clothing/accessory/jacket,/obj/item/weapon/material/butterfly/switchblade,/turf/simulated/floor/carpet,/area/submap/Drugd) +"G" = (/obj/item/weapon/reagent_containers/pill/zoom{name = "pill"},/obj/random/trash,/turf/simulated/floor/carpet,/area/submap/Drugd) +"H" = (/obj/item/weapon/reagent_containers/pill/zoom{name = "pill"},/turf/simulated/floor/carpet,/area/submap/Drugd) +"I" = (/obj/structure/loot_pile/maint/boxfort,/turf/simulated/floor/carpet,/area/submap/Drugd) +"J" = (/obj/structure/table/standard,/obj/item/weapon/surgical/scalpel,/turf/simulated/floor/tiled,/area/submap/Drugd) +"K" = (/obj/item/wheelchair,/turf/simulated/floor/tiled,/area/submap/Drugd) +"L" = (/obj/structure/table/standard,/obj/random/firstaid,/turf/simulated/floor,/area/submap/Drugd) +"M" = (/obj/structure/loot_pile/maint/junk,/turf/simulated/floor/tiled,/area/submap/Drugd) +"N" = (/obj/effect/floor_decal/rust,/obj/structure/table/standard,/turf/simulated/floor/tiled,/area/submap/Drugd) +"O" = (/obj/structure/table/standard,/obj/item/weapon/reagent_containers/pill/zoom,/obj/item/weapon/reagent_containers/pill/zoom,/turf/simulated/floor,/area/submap/Drugd) +"P" = (/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/pill/tramadol{name = "pill"},/turf/simulated/floor/carpet,/area/submap/Drugd) +"Q" = (/mob/living/simple_mob/mechanical/hivebot/ranged_damage/strong/guard,/turf/simulated/floor,/area/submap/Drugd) +"R" = (/obj/structure/girder,/turf/simulated/floor,/area/submap/Drugd) +"S" = (/obj/item/weapon/material/shard,/turf/simulated/floor,/area/submap/Drugd) +"T" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp,/turf/simulated/floor/carpet,/area/submap/Drugd) +"U" = (/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/syringe/drugs,/turf/simulated/floor/carpet,/area/submap/Drugd) (1,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(2,1,1) = {" -a -b -b -b -b -b -b -b -b -b -b -b -b -b -c -c -c -b -b -b -b -b -b -b -a -"} -(3,1,1) = {" -a -b -b -b -b -b -c -c -c -c -c -c -c -c -c -c -c -c -b -b -b -b -b -b -a -"} -(4,1,1) = {" -a -b -b -b -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -b -b -a -"} -(5,1,1) = {" -a -b -b -b -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -b -a -"} -(6,1,1) = {" -a -b -b -b -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -a -"} -(7,1,1) = {" -a -b -b -b -c -c -c -c -c -c -c -c -c -c -d -d -d -d -d -d -d -c -c -c -a -"} -(8,1,1) = {" -a -b -b -b -c -c -c -c -c -c -c -c -c -c -d -B -J -N -l -R -d -c -c -c -a -"} -(9,1,1) = {" -a -b -b -b -b -c -c -c -c -c -c -c -c -c -d -C -K -l -Q -l -d -c -c -c -a -"} -(10,1,1) = {" -a -b -b -b -b -b -c -c -c -c -c -c -c -c -d -D -g -l -l -S -d -c -c -c -a -"} -(11,1,1) = {" -a -b -b -b -b -b -c -c -c -c -c -c -c -c -d -E -L -O -l -l -d -c -c -b -a -"} -(12,1,1) = {" -a -b -b -b -b -b -b -d -d -d -d -d -d -d -d -d -d -d -e -d -d -c -c -b -a -"} -(13,1,1) = {" -a -b -b -b -b -b -b -d -f -g -g -p -u -l -z -l -l -h -l -l -l -c -c -b -a -"} -(14,1,1) = {" -a -b -b -b -b -b -b -e -f -g -l -l -l -l -l -l -f -l -l -l -u -c -c -b -a -"} -(15,1,1) = {" -a -b -b -b -b -b -b -d -f -h -l -l -h -l -g -f -M -g -l -h -d -c -c -b -a -"} -(16,1,1) = {" -a -b -b -b -b -b -b -d -d -d -m -d -d -d -m -d -d -d -m -d -d -c -c -c -a -"} -(17,1,1) = {" -a -b -b -b -b -b -c -c -d -i -n -q -d -v -o -F -d -q -o -q -d -c -c -c -a -"} -(18,1,1) = {" -a -b -b -b -b -c -c -c -d -j -o -r -d -w -o -G -d -P -o -T -d -c -c -c -a -"} -(19,1,1) = {" -a -b -b -b -b -c -c -c -d -k -o -s -d -x -o -H -d -w -o -U -d -c -c -c -a -"} -(20,1,1) = {" -a -b -b -b -b -c -c -c -d -j -o -t -d -y -A -I -d -w -o -n -d -c -c -b -a -"} -(21,1,1) = {" -a -b -b -b -b -c -c -c -d -d -d -d -d -d -d -d -d -d -d -d -d -c -c -c -a -"} -(22,1,1) = {" -a -b -b -b -b -b -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -a -"} -(23,1,1) = {" -a -b -b -b -b -b -b -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -c -b -a -"} -(24,1,1) = {" -a -b -b -b -b -b -b -b -b -c -c -c -c -b -b -b -b -c -c -c -c -b -b -b -a -"} -(25,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} +aaaaaaaaaaaaaaaaaaaaaaaaa +abbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbba +abbbbbbbbbbbbbbbbbbbbbbba +abbcccccbbbbbbbbbbbbbbbba +abbccccccbbbbbbbbccccbbba +abcccccccccbbbbbccccccbba +abcccccccccddeddcccccccba +abcccccccccdfffddddddccba +abcccccccccdgghdijkjdccca +abcccccccccdgllmnooodccca +abcccccccccdplldqrstdccca +abcccccccccdulhddddddccca +abcccccccccdllldvwxydccba +acccccddddddzlgmoooAdccba +acccccdBCDEdllfdFGHIdccba +acccccdJKgLdlfMddddddccba +abccccdNllOdhlgdqPwwdccca +abbcccdlQllelllmoooodccca +abbcccdRlSldllhdqTUndccca +abbcccddddddludddddddccca +abbccccccccccccccccccccba +abbbcccccccccccccccccccba +abbbbcccccbbbbbccccbccbba +aaaaaaaaaaaaaaaaaaaaaaaaa +"} \ No newline at end of file diff --git a/maps/submaps/surface_submaps/wilderness/MCamp1.dmm b/maps/submaps/surface_submaps/wilderness/MCamp1.dmm index add7df4ca5..b4bcb7f0b2 100644 --- a/maps/submaps/surface_submaps/wilderness/MCamp1.dmm +++ b/maps/submaps/surface_submaps/wilderness/MCamp1.dmm @@ -1,626 +1,60 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"a" = ( -/turf/template_noop, -/area/template_noop) -"b" = ( -/turf/template_noop, -/area/submap/MilitaryCamp1) -"c" = ( -/turf/simulated/floor/outdoors/dirt, -/area/submap/MilitaryCamp1) -"d" = ( -/obj/random/landmine, -/turf/template_noop, -/area/submap/MilitaryCamp1) -"e" = ( -/obj/structure/flora/bush, -/turf/template_noop, -/area/submap/MilitaryCamp1) -"f" = ( -/obj/effect/decal/cleanable/blood, -/turf/template_noop, -/area/submap/MilitaryCamp1) -"g" = ( -/obj/random/landmine, -/turf/simulated/floor/outdoors/dirt, -/area/submap/MilitaryCamp1) -"h" = ( -/obj/effect/decal/remains, -/turf/simulated/floor/outdoors/dirt, -/area/submap/MilitaryCamp1) -"i" = ( -/obj/effect/mine, -/turf/template_noop, -/area/submap/MilitaryCamp1) -"j" = ( -/obj/effect/decal/remains, -/obj/random/landmine, -/turf/simulated/floor/outdoors/dirt, -/area/submap/MilitaryCamp1) -"k" = ( -/obj/structure/flora/tree/sif, -/turf/template_noop, -/area/submap/MilitaryCamp1) -"l" = ( -/obj/item/stack/rods, -/turf/template_noop, -/area/submap/MilitaryCamp1) -"m" = ( -/turf/simulated/wall, -/area/submap/MilitaryCamp1) -"n" = ( -/obj/random/landmine, -/turf/simulated/floor, -/area/submap/MilitaryCamp1) -"o" = ( -/turf/simulated/floor, -/area/submap/MilitaryCamp1) -"p" = ( -/obj/item/weapon/material/shard, -/turf/template_noop, -/area/submap/MilitaryCamp1) -"q" = ( -/mob/living/simple_animal/hostile/viscerator{ - returns_home = 1 - }, -/turf/simulated/floor, -/area/submap/MilitaryCamp1) -"r" = ( -/obj/structure/girder, -/turf/simulated/floor, -/area/submap/MilitaryCamp1) -"s" = ( -/obj/machinery/computer/communications, -/mob/living/simple_animal/hostile/viscerator{ - returns_home = 1 - }, -/mob/living/simple_animal/hostile/viscerator{ - returns_home = 1 - }, -/turf/simulated/floor, -/area/submap/MilitaryCamp1) -"t" = ( -/obj/structure/table/standard, -/obj/random/energy, -/mob/living/simple_animal/hostile/viscerator{ - returns_home = 1 - }, -/mob/living/simple_animal/hostile/viscerator{ - returns_home = 1 - }, -/turf/simulated/floor, -/area/submap/MilitaryCamp1) -"u" = ( -/obj/effect/mine, -/obj/random/landmine, -/turf/simulated/floor, -/area/submap/MilitaryCamp1) -"v" = ( -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor, -/area/submap/MilitaryCamp1) -"w" = ( -/obj/machinery/computer/security, -/mob/living/simple_animal/hostile/viscerator{ - returns_home = 1 - }, -/mob/living/simple_animal/hostile/viscerator{ - returns_home = 1 - }, -/turf/simulated/floor, -/area/submap/MilitaryCamp1) -"x" = ( -/mob/living/simple_animal/hostile/viscerator{ - returns_home = 1 - }, -/mob/living/simple_animal/hostile/viscerator{ - returns_home = 1 - }, -/turf/simulated/floor, -/area/submap/MilitaryCamp1) -"y" = ( -/obj/item/weapon/material/shard, -/obj/random/landmine, -/turf/template_noop, -/area/submap/MilitaryCamp1) -"z" = ( -/obj/machinery/door/airlock, -/turf/simulated/floor, -/area/submap/MilitaryCamp1) -"A" = ( -/obj/effect/decal/cleanable/dirt, -/mob/living/simple_animal/hostile/viscerator{ - returns_home = 1 - }, -/turf/simulated/floor, -/area/submap/MilitaryCamp1) -"B" = ( -/mob/living/simple_animal/hostile/viscerator{ - returns_home = 1 - }, -/turf/template_noop, -/area/submap/MilitaryCamp1) -"C" = ( -/obj/structure/table, -/turf/simulated/floor, -/area/submap/MilitaryCamp1) -"D" = ( -/obj/structure/table/standard, -/obj/random/firstaid, -/turf/simulated/floor, -/area/submap/MilitaryCamp1) -"E" = ( -/obj/effect/decal/cleanable/dirt, -/obj/random/landmine, -/turf/simulated/floor, -/area/submap/MilitaryCamp1) -"F" = ( -/obj/machinery/door/airlock, -/obj/effect/mine, -/turf/simulated/floor, -/area/submap/MilitaryCamp1) -"G" = ( -/obj/structure/flora/tree/dead, -/turf/template_noop, -/area/submap/MilitaryCamp1) -"H" = ( -/obj/random/landmine, -/turf/template_noop, -/area/template_noop) -"I" = ( -/obj/structure/table/standard, -/obj/random/cigarettes, -/obj/item/weapon/flame/lighter/random, -/turf/simulated/floor, -/area/submap/MilitaryCamp1) -"J" = ( -/obj/structure/table/standard, -/obj/random/toolbox, -/turf/simulated/floor, -/area/submap/MilitaryCamp1) -"K" = ( -/obj/effect/decal/cleanable/blood, -/obj/random/landmine, -/turf/template_noop, -/area/submap/MilitaryCamp1) +"a" = (/turf/template_noop,/area/template_noop) +"b" = (/turf/template_noop,/area/submap/MilitaryCamp1) +"c" = (/turf/simulated/floor/outdoors/dirt,/area/submap/MilitaryCamp1) +"d" = (/obj/random/landmine,/turf/template_noop,/area/submap/MilitaryCamp1) +"e" = (/obj/structure/flora/bush,/turf/template_noop,/area/submap/MilitaryCamp1) +"f" = (/obj/effect/decal/cleanable/blood,/turf/template_noop,/area/submap/MilitaryCamp1) +"g" = (/obj/random/landmine,/turf/simulated/floor/outdoors/dirt,/area/submap/MilitaryCamp1) +"h" = (/obj/effect/decal/remains,/turf/simulated/floor/outdoors/dirt,/area/submap/MilitaryCamp1) +"i" = (/obj/effect/mine,/turf/template_noop,/area/submap/MilitaryCamp1) +"j" = (/obj/effect/decal/remains,/obj/random/landmine,/turf/simulated/floor/outdoors/dirt,/area/submap/MilitaryCamp1) +"k" = (/obj/structure/flora/tree/sif,/turf/template_noop,/area/submap/MilitaryCamp1) +"l" = (/obj/item/stack/rods,/turf/template_noop,/area/submap/MilitaryCamp1) +"m" = (/turf/simulated/wall,/area/submap/MilitaryCamp1) +"n" = (/obj/random/landmine,/turf/simulated/floor,/area/submap/MilitaryCamp1) +"o" = (/turf/simulated/floor,/area/submap/MilitaryCamp1) +"p" = (/obj/item/weapon/material/shard,/turf/template_noop,/area/submap/MilitaryCamp1) +"q" = (/mob/living/simple_mob/mechanical/viscerator,/turf/simulated/floor,/area/submap/MilitaryCamp1) +"r" = (/obj/structure/girder,/turf/simulated/floor,/area/submap/MilitaryCamp1) +"s" = (/obj/machinery/computer/communications,/mob/living/simple_mob/mechanical/viscerator,/mob/living/simple_mob/mechanical/viscerator,/turf/simulated/floor,/area/submap/MilitaryCamp1) +"t" = (/obj/structure/table/standard,/obj/random/energy,/mob/living/simple_mob/mechanical/viscerator,/mob/living/simple_mob/mechanical/viscerator,/turf/simulated/floor,/area/submap/MilitaryCamp1) +"u" = (/obj/effect/mine,/obj/random/landmine,/turf/simulated/floor,/area/submap/MilitaryCamp1) +"v" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor,/area/submap/MilitaryCamp1) +"w" = (/obj/machinery/computer/security,/mob/living/simple_mob/mechanical/viscerator,/mob/living/simple_mob/mechanical/viscerator,/turf/simulated/floor,/area/submap/MilitaryCamp1) +"x" = (/mob/living/simple_mob/mechanical/viscerator,/mob/living/simple_mob/mechanical/viscerator,/turf/simulated/floor,/area/submap/MilitaryCamp1) +"y" = (/obj/item/weapon/material/shard,/obj/random/landmine,/turf/template_noop,/area/submap/MilitaryCamp1) +"z" = (/obj/machinery/door/airlock,/turf/simulated/floor,/area/submap/MilitaryCamp1) +"A" = (/obj/effect/decal/cleanable/dirt,/mob/living/simple_mob/mechanical/viscerator,/turf/simulated/floor,/area/submap/MilitaryCamp1) +"B" = (/mob/living/simple_mob/mechanical/viscerator,/turf/template_noop,/area/submap/MilitaryCamp1) +"C" = (/obj/structure/table,/turf/simulated/floor,/area/submap/MilitaryCamp1) +"D" = (/obj/structure/table/standard,/obj/random/firstaid,/turf/simulated/floor,/area/submap/MilitaryCamp1) +"E" = (/obj/effect/decal/cleanable/dirt,/obj/random/landmine,/turf/simulated/floor,/area/submap/MilitaryCamp1) +"F" = (/obj/machinery/door/airlock,/obj/effect/mine,/turf/simulated/floor,/area/submap/MilitaryCamp1) +"G" = (/obj/structure/flora/tree/dead,/turf/template_noop,/area/submap/MilitaryCamp1) +"H" = (/obj/random/landmine,/turf/template_noop,/area/template_noop) +"I" = (/obj/structure/table/standard,/obj/random/cigarettes,/obj/item/weapon/flame/lighter/random,/turf/simulated/floor,/area/submap/MilitaryCamp1) +"J" = (/obj/structure/table/standard,/obj/random/toolbox,/turf/simulated/floor,/area/submap/MilitaryCamp1) +"K" = (/obj/effect/decal/cleanable/blood,/obj/random/landmine,/turf/template_noop,/area/submap/MilitaryCamp1) (1,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -H -a -a -a -a -a -a -a -"} -(2,1,1) = {" -a -b -g -b -d -b -b -b -b -b -f -b -b -G -b -b -b -c -b -a -"} -(3,1,1) = {" -a -b -h -c -k -b -b -b -b -b -d -b -b -b -b -d -c -j -c -a -"} -(4,1,1) = {" -a -c -c -c -b -b -d -b -y -b -b -b -B -b -e -d -b -c -c -a -"} -(5,1,1) = {" -a -b -d -b -b -b -m -m -m -o -o -r -m -m -b -b -b -d -e -a -"} -(6,1,1) = {" -a -d -b -b -l -m -m -m -m -m -m -m -m -m -m -b -d -b -b -a -"} -(7,1,1) = {" -a -b -b -d -m -m -q -q -z -q -q -z -q -I -m -m -b -b -d -a -"} -(8,1,1) = {" -a -e -b -b -m -m -o -r -m -o -o -F -o -J -m -m -m -b -b -a -"} -(9,1,1) = {" -a -f -b -b -n -o -o -u -m -o -o -m -r -m -m -m -m -i -k -a -"} -(10,1,1) = {" -a -d -b -k -o -n -r -v -A -v -C -m -v -o -z -v -b -d -f -a -"} -(11,1,1) = {" -a -b -b -l -m -m -m -m -m -o -D -m -E -o -o -o -y -b -b -a -"} -(12,1,1) = {" -a -b -f -b -m -m -s -w -m -q -q -m -v -q -m -m -m -l -b -a -"} -(13,1,1) = {" -a -b -i -b -n -m -t -x -m -A -E -z -q -q -m -m -m -b -d -a -"} -(14,1,1) = {" -a -b -b -b -m -m -q -x -z -v -v -z -q -q -m -m -b -d -c -a -"} -(15,1,1) = {" -a -b -c -c -p -m -m -m -m -m -m -m -m -m -m -b -g -c -c -a -"} -(16,1,1) = {" -a -b -j -c -c -b -m -m -r -m -m -r -m -m -b -c -c -j -b -a -"} -(17,1,1) = {" -a -b -b -g -b -d -b -b -B -b -b -b -b -p -i -c -b -k -b -a -"} -(18,1,1) = {" -a -b -b -k -b -b -e -b -d -b -i -G -b -b -b -i -b -b -b -a -"} -(19,1,1) = {" -a -b -b -b -b -d -b -d -b -b -d -b -b -K -b -b -b -b -b -a -"} -(20,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} +aaaaaaaaaaaaaaaaaaaa +abbcbdbefdbbbbbbbbba +aghcdbbbbbbfibcjbbba +abccbbdbbklbbbccgkba +adkbblmmnommnmpcbbba +abbbbmmmonmmmmmbdbda +abbdmmqoormstqmmbeba +abbbmmqruvmwxxmmbbda +abbymmzmmAmmmzmrBdba +abbbomqoovoqAvmmbbba +afdbomqooCDqEvmmbida +abbbrmzFmmmmzzmrbGba +HbbBmmqorvEvqqmmbbba +aGbbmmIJmooqqqmmpbKa +abbebmmmmzommmmbibba +abddbbmmmvommmbcciba +abcbbdbmmbymmbgcbbba +acjcdbbbidblbdcjkbba +abccebdbkfbbdccbbbba +aaaaaaaaaaaaaaaaaaaa +"} \ No newline at end of file diff --git a/maps/submaps/surface_submaps/wilderness/MHR.dmm b/maps/submaps/surface_submaps/wilderness/MHR.dmm index f063126b3f..7c2d20c306 100644 --- a/maps/submaps/surface_submaps/wilderness/MHR.dmm +++ b/maps/submaps/surface_submaps/wilderness/MHR.dmm @@ -1,545 +1,42 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"a" = ( -/turf/template_noop, -/area/template_noop) -"b" = ( -/turf/template_noop, -/area/submap/MHR) -"c" = ( -/obj/structure/flora/tree/sif, -/turf/template_noop, -/area/submap/MHR) -"d" = ( -/turf/simulated/floor/outdoors/dirt{ - outdoors = 0 - }, -/area/submap/MHR) -"e" = ( -/turf/simulated/mineral/ignore_mapgen, -/area/submap/MHR) -"f" = ( -/obj/effect/decal/cleanable/spiderling_remains, -/turf/simulated/floor/outdoors/dirt{ - outdoors = 0 - }, -/area/submap/MHR) -"g" = ( -/turf/simulated/floor/outdoors/dirt, -/area/submap/MHR) -"h" = ( -/obj/structure/table/rack, -/obj/item/weapon/storage/backpack, -/turf/template_noop, -/area/submap/MHR) -"i" = ( -/obj/structure/table/standard, -/turf/template_noop, -/area/submap/MHR) -"j" = ( -/obj/structure/table/standard, -/obj/item/weapon/paper{ - info = "Do not enter the cave. The estimated active time of the Vicerators is much longer due to the improvements on the rotor bearings. It's estimated to be roughly a few months before we start to see any chancces of mechanical failure. "; - name = "NOTICE: DO NOT ENTER" - }, -/turf/template_noop, -/area/submap/MHR) -"k" = ( -/obj/effect/decal/cleanable/cobweb2, -/turf/simulated/floor/outdoors/dirt{ - outdoors = 0 - }, -/area/submap/MHR) -"l" = ( -/mob/living/simple_animal/hostile/viscerator, -/turf/simulated/floor/outdoors/dirt{ - outdoors = 0 - }, -/area/submap/MHR) -"m" = ( -/obj/item/weapon/reagent_containers/food/snacks/xenomeat/spidermeat, -/turf/simulated/floor/outdoors/dirt{ - outdoors = 0 - }, -/area/submap/MHR) -"n" = ( -/obj/effect/decal/cleanable/cobweb2, -/mob/living/simple_animal/hostile/viscerator, -/turf/simulated/floor/outdoors/dirt{ - outdoors = 0 - }, -/area/submap/MHR) -"o" = ( -/obj/effect/decal/cleanable/cobweb, -/turf/simulated/floor/outdoors/dirt{ - outdoors = 0 - }, -/area/submap/MHR) -"p" = ( -/obj/effect/decal/cleanable/spiderling_remains, -/obj/effect/decal/cleanable/cobweb, -/turf/simulated/floor/outdoors/dirt{ - outdoors = 0 - }, -/area/submap/MHR) -"q" = ( -/obj/effect/decal/remains/robot, -/turf/simulated/floor/outdoors/dirt{ - outdoors = 0 - }, -/area/submap/MHR) -"r" = ( -/obj/effect/decal/remains, -/obj/item/clothing/mask/gas/explorer, -/obj/item/weapon/material/twohanded/fireaxe, -/turf/simulated/floor/outdoors/dirt{ - outdoors = 0 - }, -/area/submap/MHR) -"t" = ( -/obj/effect/decal/cleanable/spiderling_remains, -/mob/living/simple_animal/hostile/viscerator, -/turf/simulated/floor/outdoors/dirt{ - outdoors = 0 - }, -/area/submap/MHR) +"a" = (/turf/template_noop,/area/template_noop) +"b" = (/turf/template_noop,/area/submap/MHR) +"c" = (/obj/structure/flora/tree/sif,/turf/template_noop,/area/submap/MHR) +"d" = (/turf/simulated/floor/outdoors/dirt{outdoors = 0},/area/submap/MHR) +"e" = (/turf/simulated/mineral/ignore_mapgen,/area/submap/MHR) +"f" = (/obj/effect/decal/cleanable/spiderling_remains,/turf/simulated/floor/outdoors/dirt{outdoors = 0},/area/submap/MHR) +"g" = (/turf/simulated/floor/outdoors/dirt,/area/submap/MHR) +"h" = (/obj/structure/table/rack,/obj/item/weapon/storage/backpack,/turf/template_noop,/area/submap/MHR) +"i" = (/obj/structure/table/standard,/turf/template_noop,/area/submap/MHR) +"j" = (/obj/structure/table/standard,/obj/item/weapon/paper{info = "Do not enter the cave. The estimated active time of the Vicerators is much longer due to the improvements on the rotor bearings. It's estimated to be roughly a few months before we start to see any chancces of mechanical failure. "; name = "NOTICE: DO NOT ENTER"},/turf/template_noop,/area/submap/MHR) +"k" = (/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor/outdoors/dirt{outdoors = 0},/area/submap/MHR) +"l" = (/mob/living/simple_mob/mechanical/viscerator,/turf/simulated/floor/outdoors/dirt{outdoors = 0},/area/submap/MHR) +"m" = (/obj/item/weapon/reagent_containers/food/snacks/xenomeat/spidermeat,/turf/simulated/floor/outdoors/dirt{outdoors = 0},/area/submap/MHR) +"n" = (/obj/effect/decal/cleanable/cobweb2,/mob/living/simple_mob/mechanical/viscerator,/turf/simulated/floor/outdoors/dirt{outdoors = 0},/area/submap/MHR) +"o" = (/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/outdoors/dirt{outdoors = 0},/area/submap/MHR) +"p" = (/obj/effect/decal/cleanable/spiderling_remains,/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/outdoors/dirt{outdoors = 0},/area/submap/MHR) +"q" = (/obj/effect/decal/remains/robot,/turf/simulated/floor/outdoors/dirt{outdoors = 0},/area/submap/MHR) +"r" = (/obj/effect/decal/remains,/obj/item/clothing/mask/gas/explorer,/obj/item/weapon/material/twohanded/fireaxe,/turf/simulated/floor/outdoors/dirt{outdoors = 0},/area/submap/MHR) +"s" = (/obj/effect/decal/cleanable/spiderling_remains,/mob/living/simple_mob/mechanical/viscerator,/turf/simulated/floor/outdoors/dirt{outdoors = 0},/area/submap/MHR) (1,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(2,1,1) = {" -a -b -b -b -b -b -b -c -b -b -b -b -b -b -b -b -b -c -b -a -"} -(3,1,1) = {" -a -c -b -b -b -b -b -b -e -e -e -e -e -b -b -b -b -b -b -a -"} -(4,1,1) = {" -a -b -b -b -b -b -b -e -e -e -e -e -e -e -e -e -b -b -b -a -"} -(5,1,1) = {" -a -b -b -b -b -b -e -e -e -e -e -e -e -e -e -e -e -b -b -a -"} -(6,1,1) = {" -a -b -b -b -b -e -e -e -e -e -p -l -d -l -e -e -e -e -c -a -"} -(7,1,1) = {" -a -b -b -b -h -e -e -e -e -e -l -d -l -l -t -e -e -e -b -a -"} -(8,1,1) = {" -a -b -b -b -i -e -e -e -e -l -l -l -d -l -e -e -e -e -b -a -"} -(9,1,1) = {" -a -b -b -b -j -e -e -e -e -m -l -d -f -l -e -e -e -e -b -a -"} -(10,1,1) = {" -a -b -b -b -e -e -e -e -e -n -d -l -d -d -d -e -e -e -b -a -"} -(11,1,1) = {" -a -b -b -b -e -e -e -e -e -e -q -d -d -d -l -e -e -e -b -a -"} -(12,1,1) = {" -a -b -d -d -e -e -e -e -e -e -f -d -d -m -d -e -e -e -b -a -"} -(13,1,1) = {" -a -b -d -f -e -e -e -e -e -o -d -d -d -d -d -e -e -e -b -a -"} -(14,1,1) = {" -a -d -d -d -d -e -e -e -d -d -d -d -d -d -d -e -e -b -b -a -"} -(15,1,1) = {" -a -b -f -d -d -d -d -d -d -d -d -d -d -q -e -e -e -b -b -a -"} -(16,1,1) = {" -a -e -e -g -d -d -d -d -d -d -d -d -d -e -e -e -e -b -b -a -"} -(17,1,1) = {" -a -e -e -e -e -e -e -e -k -d -d -r -e -e -e -e -e -b -b -a -"} -(18,1,1) = {" -a -e -e -e -e -e -e -e -e -e -e -e -e -e -e -b -b -b -b -a -"} -(19,1,1) = {" -a -c -e -e -e -e -e -e -e -e -e -e -e -e -b -b -b -b -c -a -"} -(20,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} +aaaaaaaaaaaaaaaaaaaa +abcbbbbbbbbbbdbeeeca +abbbbbbbbbbdddfeeeea +abbbbbbbbbbdfddgeeea +abbbbbhijeeeedddeeea +abbbbeeeeeeeeeddeeea +abbbeeeeeeeeeeddeeea +acbeeeeeeeeeeeddeeea +abeeeeeeeeeeedddkeea +abeeeeelmneeoddddeea +abeeepllldqfdddddeea +abeeeldldlddddddreea +abeeedldfdddddddeeea +abbeellllddmddqeeeea +abbeeeseedldddeeeeba +abbeeeeeeeeeeeeeebba +abbbeeeeeeeeeeeeebba +acbbbeeeeeeeebbbbbba +abbbbcbbbbbbbbbbbbca +aaaaaaaaaaaaaaaaaaaa +"} \ No newline at end of file diff --git a/maps/submaps/surface_submaps/wilderness/Manor1.dmm b/maps/submaps/surface_submaps/wilderness/Manor1.dmm index 9cb26d7a44..ec837531c4 100644 --- a/maps/submaps/surface_submaps/wilderness/Manor1.dmm +++ b/maps/submaps/surface_submaps/wilderness/Manor1.dmm @@ -1,2999 +1,188 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"aa" = ( -/turf/template_noop, -/area/submap/Manor1) -"ab" = ( -/turf/simulated/wall/wood, -/area/submap/Manor1) -"ac" = ( -/obj/structure/window/reinforced/full, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"ad" = ( -/obj/structure/bed/chair/wood{ - icon_state = "wooden_chair"; - dir = 4 - }, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"ae" = ( -/obj/structure/table/woodentable, -/obj/item/weapon/reagent_containers/food/drinks/cans/waterbottle, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"af" = ( -/obj/structure/bed/chair/wood{ - icon_state = "wooden_chair"; - dir = 8 - }, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"ag" = ( -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"ah" = ( -/obj/structure/flora/pottedplant/dead, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"ai" = ( -/obj/structure/flora/pottedplant/drooping, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"aj" = ( -/obj/structure/table/woodentable, -/obj/item/clothing/mask/smokable/cigarette/cigar, -/obj/item/weapon/material/ashtray/glass, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"ak" = ( -/obj/structure/flora/pottedplant/dead, -/obj/effect/decal/cleanable/cobweb, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"al" = ( -/obj/structure/table/woodentable, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"am" = ( -/obj/structure/table/woodentable, -/obj/item/device/flashlight, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"an" = ( -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"ao" = ( -/obj/structure/mopbucket, -/obj/effect/decal/cleanable/cobweb, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"ap" = ( -/obj/structure/sink, -/turf/simulated/wall/wood, -/area/submap/Manor1) -"aq" = ( -/turf/simulated/floor/carpet/bcarpet, -/area/submap/Manor1) -"ar" = ( -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/carpet/bcarpet, -/area/submap/Manor1) -"as" = ( -/obj/structure/simple_door/wood, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"at" = ( -/obj/structure/table/woodentable, -/obj/item/device/flashlight/lamp, -/obj/effect/decal/cleanable/blood/gibs/robot, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"au" = ( -/obj/structure/bed, -/obj/item/weapon/bedsheet, -/obj/effect/decal/cleanable/blood/oil, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"av" = ( -/obj/structure/janitorialcart, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"aw" = ( -/obj/structure/table/woodentable, -/obj/item/weapon/mop, -/obj/item/weapon/reagent_containers/glass/bucket, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"ax" = ( -/obj/structure/closet/cabinet, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"ay" = ( -/obj/effect/decal/cleanable/blood/gibs/robot/limb, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"az" = ( -/obj/structure/table/woodentable, -/obj/item/trash/candle, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"aA" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/spider/stickyweb, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"aB" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/spider/stickyweb, -/mob/living/simple_animal/hostile/giant_spider/lurker, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"aC" = ( -/obj/structure/table/woodentable, -/obj/item/device/flashlight/maglight, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"aD" = ( -/obj/structure/table/woodentable, -/obj/item/device/flashlight/lamp, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"aE" = ( -/obj/structure/closet/cabinet, -/obj/effect/decal/cleanable/cobweb2, -/obj/item/clothing/head/hood/winter, -/obj/item/clothing/shoes/boots/winter, -/obj/item/clothing/suit/storage/hooded/wintercoat, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"aF" = ( -/obj/structure/table/woodentable, -/obj/effect/decal/cleanable/cobweb, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"aG" = ( -/obj/structure/table/woodentable, -/obj/item/weapon/paper, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"aH" = ( -/obj/structure/table/woodentable, -/obj/item/weapon/pen, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"aI" = ( -/obj/structure/flora/pottedplant/dead, -/obj/effect/spider/stickyweb, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"aJ" = ( -/obj/effect/spider/stickyweb, -/mob/living/simple_animal/hostile/giant_spider/lurker, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"aK" = ( -/obj/effect/spider/stickyweb, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"aL" = ( -/obj/structure/fireplace, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"aM" = ( -/mob/living/simple_animal/hostile/giant_spider/lurker, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"aN" = ( -/obj/effect/decal/cleanable/cobweb2, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"aO" = ( -/obj/structure/bed, -/obj/item/weapon/bedsheet, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"aP" = ( -/obj/structure/bed/chair/wood, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"aQ" = ( -/turf/simulated/floor/carpet/purcarpet, -/area/submap/Manor1) -"aR" = ( -/obj/structure/table/standard, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"aS" = ( -/obj/structure/table/standard, -/obj/machinery/microwave, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"aT" = ( -/obj/structure/closet/cabinet, -/obj/random/projectile/shotgun, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"aU" = ( -/obj/structure/bookcase, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"aV" = ( -/obj/structure/table/woodentable, -/obj/item/weapon/material/kitchen/utensil/fork, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"aW" = ( -/obj/structure/table/standard, -/obj/item/weapon/reagent_containers/food/condiment/small/peppermill, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"aX" = ( -/obj/structure/table/standard, -/obj/item/weapon/material/knife, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"aY" = ( -/obj/machinery/cooker/oven, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"aZ" = ( -/obj/structure/table/standard, -/obj/item/weapon/reagent_containers/food/condiment/small/saltshaker, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"ba" = ( -/obj/machinery/cooker/grill, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"bb" = ( -/obj/structure/table/standard, -/obj/item/weapon/tray, -/obj/item/weapon/tray, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"bc" = ( -/obj/structure/table/standard, -/obj/item/weapon/material/knife/butch, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"bd" = ( -/obj/structure/table/standard, -/obj/item/weapon/reagent_containers/food/drinks/cans/waterbottle, -/obj/item/weapon/reagent_containers/food/drinks/cans/waterbottle, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"be" = ( -/obj/random/trash, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"bf" = ( -/obj/structure/closet/cabinet, -/obj/item/clothing/head/hood/winter, -/obj/item/clothing/shoes/boots/winter, -/obj/item/clothing/suit/storage/hooded/wintercoat, -/obj/random/contraband, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"bg" = ( -/obj/structure/table/woodentable, -/obj/item/weapon/paper_bin, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"bh" = ( -/obj/structure/bed/chair/wood{ - icon_state = "wooden_chair"; - dir = 1 - }, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"bi" = ( -/obj/effect/decal/cleanable/cobweb, -/turf/simulated/floor/holofloor/wood{ - icon_state = "wood_broken0" - }, -/area/submap/Manor1) -"bj" = ( -/obj/effect/decal/cleanable/cobweb, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"bk" = ( -/obj/random/plushielarge, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"bl" = ( -/turf/simulated/floor/carpet/blucarpet, -/area/submap/Manor1) -"bm" = ( -/obj/structure/loot_pile/surface/bones, -/obj/item/clothing/accessory/sweater/blue, -/turf/simulated/floor/carpet/blucarpet, -/area/submap/Manor1) -"bn" = ( -/obj/structure/window/reinforced/full, -/turf/template_noop, -/area/submap/Manor1) -"bo" = ( -/obj/item/weapon/material/twohanded/baseballbat/metal, -/turf/simulated/floor/carpet/blucarpet, -/area/submap/Manor1) -"bp" = ( -/obj/effect/decal/cleanable/blood, -/turf/simulated/floor/carpet/blucarpet, -/area/submap/Manor1) -"bq" = ( -/obj/effect/decal/cleanable/blood/drip, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"br" = ( -/obj/structure/bed/chair/comfy/purp{ - icon_state = "comfychair_preview"; - dir = 4 - }, -/turf/simulated/floor/holofloor/wood{ - icon_state = "wood_broken5" - }, -/area/submap/Manor1) -"bs" = ( -/obj/structure/table, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"bt" = ( -/obj/structure/bed/chair/wood{ - icon_state = "wooden_chair"; - dir = 4 - }, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"bu" = ( -/obj/structure/bed/chair/wood{ - icon_state = "wooden_chair"; - dir = 8 - }, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"bv" = ( -/obj/structure/table/standard, -/obj/item/weapon/reagent_containers/food/condiment/small/sugar, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"bw" = ( -/obj/effect/decal/cleanable/blood/drip, -/turf/simulated/floor/carpet/blucarpet, -/area/submap/Manor1) -"bx" = ( -/obj/structure/bed/chair/comfy/purp{ - icon_state = "comfychair_preview"; - dir = 4 - }, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"by" = ( -/obj/structure/closet/cabinet, -/obj/item/clothing/suit/storage/hooded/wintercoat, -/obj/item/clothing/head/hood/winter, -/obj/item/clothing/shoes/boots/winter, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"bz" = ( -/obj/structure/table/woodentable, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"bA" = ( -/obj/structure/table/standard, -/obj/item/weapon/material/kitchen/utensil/fork, -/obj/item/weapon/material/kitchen/utensil/fork, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"bB" = ( -/obj/structure/closet/secure_closet/freezer/fridge, -/obj/item/weapon/reagent_containers/food/snacks/stew, -/obj/item/weapon/reagent_containers/food/snacks/stew, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"bC" = ( -/obj/item/weapon/shovel, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"bD" = ( -/obj/structure/bed/chair/wood{ - icon_state = "wooden_chair"; - dir = 1 - }, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"bE" = ( -/obj/structure/table/standard, -/obj/item/weapon/material/kitchen/utensil/spoon, -/obj/item/weapon/material/kitchen/utensil/spoon, -/obj/item/weapon/material/kitchen/utensil/spoon, -/obj/effect/spider/stickyweb, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"bF" = ( -/obj/structure/table/standard, -/obj/effect/spider/stickyweb, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"bG" = ( -/obj/structure/closet/secure_closet/freezer/fridge, -/obj/item/weapon/reagent_containers/food/snacks/sausage, -/obj/item/weapon/reagent_containers/food/snacks/sausage, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"bH" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/flora/pottedplant/drooping, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"bI" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/flora/pottedplant/dead, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"bJ" = ( -/obj/structure/table/standard, -/obj/item/weapon/material/kitchen/rollingpin, -/obj/effect/spider/stickyweb, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"bK" = ( -/obj/structure/table/standard, -/obj/item/weapon/reagent_containers/glass/bottle/stoxin, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"bL" = ( -/obj/structure/table/woodentable, -/obj/item/weapon/storage/fancy/candle_box, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"bM" = ( -/obj/machinery/papershredder, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"bN" = ( -/obj/structure/simple_door/wood, -/turf/simulated/floor/carpet/purcarpet, -/area/submap/Manor1) -"bO" = ( -/obj/machinery/icecream_vat, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"bP" = ( -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/carpet/blucarpet, -/area/submap/Manor1) -"bQ" = ( -/obj/effect/decal/cleanable/blood, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"bR" = ( -/obj/effect/decal/cleanable/cobweb, -/obj/structure/table/woodentable, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"bS" = ( -/obj/structure/flora/pottedplant/subterranean, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"bT" = ( -/obj/item/weapon/material/minihoe, -/turf/simulated/floor/carpet/blucarpet, -/area/submap/Manor1) -"bU" = ( -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/carpet/purcarpet, -/area/submap/Manor1) -"bV" = ( -/turf/simulated/floor/holofloor/wood{ - icon_state = "wood_broken6" - }, -/area/submap/Manor1) -"bW" = ( -/obj/machinery/washing_machine, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"bX" = ( -/obj/structure/table/woodentable, -/obj/structure/bedsheetbin, -/obj/effect/decal/cleanable/cobweb2, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"bY" = ( -/obj/structure/table/rack, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"bZ" = ( -/obj/structure/closet/crate, -/obj/item/stack/cable_coil/random_belt, -/obj/random/cash, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"ca" = ( -/obj/structure/table/woodentable, -/obj/item/weapon/melee/umbrella/random, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"cb" = ( -/obj/structure/closet/cabinet, -/obj/random/gun/random, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"cc" = ( -/obj/structure/closet/cabinet, -/obj/item/weapon/cell/device/weapon, -/obj/item/weapon/cell/device/weapon, -/obj/random/medical, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"cd" = ( -/obj/structure/table/woodentable, -/obj/item/device/flashlight/lamp/green, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"ce" = ( -/obj/structure/bed/double, -/obj/item/weapon/bedsheet/rddouble, -/obj/structure/curtain/open/bed, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"cf" = ( -/obj/structure/table/woodentable, -/obj/item/weapon/storage/wallet/random, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"cg" = ( -/obj/structure/flora/pottedplant/dead, -/obj/effect/decal/cleanable/cobweb2, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"ch" = ( -/obj/structure/loot_pile/surface/bones, -/obj/item/clothing/accessory/sweater, -/turf/simulated/floor/carpet/blucarpet, -/area/submap/Manor1) -"ci" = ( -/obj/structure/closet/crate, -/obj/item/weapon/flame/lighter/random, -/obj/random/powercell, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"cj" = ( -/obj/structure/closet/cabinet, -/obj/item/clothing/shoes/boots/winter, -/obj/item/clothing/suit/storage/hooded/wintercoat, -/obj/item/clothing/head/hood/winter, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"ck" = ( -/obj/effect/decal/cleanable/spiderling_remains, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"cl" = ( -/turf/simulated/floor/carpet/turcarpet, -/area/submap/Manor1) -"cm" = ( -/obj/effect/decal/cleanable/blood, -/obj/structure/bed/chair/comfy/purp{ - icon_state = "comfychair_preview"; - dir = 4 - }, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"cn" = ( -/obj/structure/closet/crate, -/obj/item/weapon/storage/wallet/random, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"co" = ( -/obj/structure/coatrack, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"cp" = ( -/obj/structure/loot_pile/surface/bones, -/obj/item/clothing/suit/storage/hooded/wintercoat, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"cq" = ( -/obj/structure/loot_pile/surface/bones, -/obj/item/clothing/under/suit_jacket, -/obj/item/clothing/shoes/black, -/obj/random/projectile/random, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"cr" = ( -/obj/structure/simple_door/wood, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/carpet/purcarpet, -/area/submap/Manor1) -"cs" = ( -/obj/item/weapon/material/twohanded/spear, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"ct" = ( -/obj/structure/closet/cabinet{ - opened = 1 - }, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"cu" = ( -/obj/effect/decal/remains, -/obj/item/weapon/material/knife/tacknife/combatknife, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"cv" = ( -/obj/structure/sink{ - pixel_y = 30 - }, -/turf/simulated/floor/tiled/hydro, -/area/submap/Manor1) -"cw" = ( -/turf/simulated/floor/tiled/hydro, -/area/submap/Manor1) -"cx" = ( -/obj/structure/table/standard, -/obj/effect/decal/cleanable/cobweb2, -/turf/simulated/floor/tiled/hydro, -/area/submap/Manor1) -"cy" = ( -/obj/structure/table/standard, -/obj/item/weapon/towel/random, -/obj/item/weapon/towel/random, -/turf/simulated/floor/tiled/hydro, -/area/submap/Manor1) -"cz" = ( -/obj/effect/decal/cleanable/cobweb2, -/obj/effect/spider/stickyweb, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"cA" = ( -/obj/item/weapon/paper/crumpled, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"cB" = ( -/turf/simulated/floor/holofloor/wood{ - icon_state = "wood_broken3" - }, -/area/submap/Manor1) -"cC" = ( -/obj/effect/decal/cleanable/spiderling_remains, -/obj/effect/spider/stickyweb, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"cD" = ( -/obj/structure/closet/crate, -/obj/item/clothing/suit/armor/vest, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"cE" = ( -/obj/structure/closet/crate, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"cF" = ( -/obj/structure/simple_door/wood, -/turf/simulated/floor/tiled/hydro, -/area/submap/Manor1) -"cG" = ( -/obj/structure/toilet{ - icon_state = "toilet00"; - dir = 8 - }, -/turf/simulated/floor/tiled/hydro, -/area/submap/Manor1) -"cH" = ( -/obj/machinery/shower{ - icon_state = "shower"; - dir = 8 - }, -/obj/structure/curtain/open/shower, -/turf/simulated/floor/tiled/hydro, -/area/submap/Manor1) -"cI" = ( -/obj/item/stack/material/wood, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"cJ" = ( -/obj/machinery/shower{ - icon_state = "shower"; - dir = 8 - }, -/obj/structure/curtain/open/shower, -/obj/random/soap, -/turf/simulated/floor/tiled/hydro, -/area/submap/Manor1) -"cK" = ( -/obj/structure/table/standard, -/turf/simulated/floor/tiled/hydro, -/area/submap/Manor1) -"cL" = ( -/obj/structure/toilet{ - icon_state = "toilet00"; - dir = 1 - }, -/turf/simulated/floor/tiled/hydro, -/area/submap/Manor1) -"cM" = ( -/obj/structure/table/woodentable, -/obj/item/device/laptop, -/turf/simulated/floor/holofloor/wood, -/area/submap/Manor1) -"cN" = ( -/turf/template_noop, -/area/template_noop) -"cO" = ( -/obj/structure/flora/tree/sif, -/turf/template_noop, -/area/submap/Manor1) +"aa" = (/turf/template_noop,/area/submap/Manor1) +"ab" = (/turf/simulated/wall/wood,/area/submap/Manor1) +"ac" = (/obj/structure/window/reinforced/full,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"ad" = (/obj/structure/bed/chair/wood{icon_state = "wooden_chair"; dir = 4},/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"ae" = (/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/food/drinks/cans/waterbottle,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"af" = (/obj/structure/bed/chair/wood{icon_state = "wooden_chair"; dir = 8},/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"ag" = (/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"ah" = (/obj/structure/flora/pottedplant/dead,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"ai" = (/obj/structure/flora/pottedplant/drooping,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aj" = (/obj/structure/table/woodentable,/obj/item/clothing/mask/smokable/cigarette/cigar,/obj/item/weapon/material/ashtray/glass,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"ak" = (/obj/structure/flora/pottedplant/dead,/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"al" = (/obj/structure/table/woodentable,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"am" = (/obj/structure/table/woodentable,/obj/item/device/flashlight,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"an" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"ao" = (/obj/structure/mopbucket,/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"ap" = (/obj/structure/sink,/turf/simulated/wall/wood,/area/submap/Manor1) +"aq" = (/turf/simulated/floor/carpet/bcarpet,/area/submap/Manor1) +"ar" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/carpet/bcarpet,/area/submap/Manor1) +"as" = (/obj/structure/simple_door/wood,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"at" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp,/obj/effect/decal/cleanable/blood/gibs/robot,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"au" = (/obj/structure/bed,/obj/item/weapon/bedsheet,/obj/effect/decal/cleanable/blood/oil,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"av" = (/obj/structure/janitorialcart,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aw" = (/obj/structure/table/woodentable,/obj/item/weapon/mop,/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"ax" = (/obj/structure/closet/cabinet,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"ay" = (/obj/effect/decal/cleanable/blood/gibs/robot/limb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"az" = (/obj/structure/table/woodentable,/obj/item/trash/candle,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aA" = (/obj/effect/decal/cleanable/dirt,/obj/effect/spider/stickyweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aB" = (/obj/effect/decal/cleanable/dirt,/obj/effect/spider/stickyweb,/mob/living/simple_mob/animal/giant_spider/lurker,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aC" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/maglight,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aD" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aE" = (/obj/structure/closet/cabinet,/obj/effect/decal/cleanable/cobweb2,/obj/item/clothing/head/hood/winter,/obj/item/clothing/shoes/boots/winter,/obj/item/clothing/suit/storage/hooded/wintercoat,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aF" = (/obj/structure/table/woodentable,/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aG" = (/obj/structure/table/woodentable,/obj/item/weapon/paper,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aH" = (/obj/structure/table/woodentable,/obj/item/weapon/pen,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aI" = (/obj/structure/flora/pottedplant/dead,/obj/effect/spider/stickyweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aJ" = (/obj/effect/spider/stickyweb,/mob/living/simple_mob/animal/giant_spider/lurker,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aK" = (/obj/effect/spider/stickyweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aL" = (/obj/structure/fireplace,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aM" = (/mob/living/simple_mob/animal/giant_spider/lurker,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aN" = (/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aO" = (/obj/structure/bed,/obj/item/weapon/bedsheet,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aP" = (/obj/structure/bed/chair/wood,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aQ" = (/turf/simulated/floor/carpet/purcarpet,/area/submap/Manor1) +"aR" = (/obj/structure/table/standard,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aS" = (/obj/structure/table/standard,/obj/machinery/microwave,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aT" = (/obj/structure/closet/cabinet,/obj/random/projectile/shotgun,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aU" = (/obj/structure/bookcase,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aV" = (/obj/structure/table/woodentable,/obj/item/weapon/material/kitchen/utensil/fork,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aW" = (/obj/structure/table/standard,/obj/item/weapon/reagent_containers/food/condiment/small/peppermill,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aX" = (/obj/structure/table/standard,/obj/item/weapon/material/knife,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aY" = (/obj/machinery/cooker/oven,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aZ" = (/obj/structure/table/standard,/obj/item/weapon/reagent_containers/food/condiment/small/saltshaker,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"ba" = (/obj/machinery/cooker/grill,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bb" = (/obj/structure/table/standard,/obj/item/weapon/tray,/obj/item/weapon/tray,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bc" = (/obj/structure/table/standard,/obj/item/weapon/material/knife/butch,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bd" = (/obj/structure/table/standard,/obj/item/weapon/reagent_containers/food/drinks/cans/waterbottle,/obj/item/weapon/reagent_containers/food/drinks/cans/waterbottle,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"be" = (/obj/random/trash,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bf" = (/obj/structure/closet/cabinet,/obj/item/clothing/head/hood/winter,/obj/item/clothing/shoes/boots/winter,/obj/item/clothing/suit/storage/hooded/wintercoat,/obj/random/contraband,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bg" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bh" = (/obj/structure/bed/chair/wood{icon_state = "wooden_chair"; dir = 1},/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bi" = (/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/holofloor/wood{icon_state = "wood_broken0"},/area/submap/Manor1) +"bj" = (/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bk" = (/obj/random/plushielarge,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bl" = (/turf/simulated/floor/carpet/blucarpet,/area/submap/Manor1) +"bm" = (/obj/structure/loot_pile/surface/bones,/obj/item/clothing/accessory/sweater/blue,/turf/simulated/floor/carpet/blucarpet,/area/submap/Manor1) +"bn" = (/obj/structure/window/reinforced/full,/turf/template_noop,/area/submap/Manor1) +"bo" = (/obj/item/weapon/material/twohanded/baseballbat/metal,/turf/simulated/floor/carpet/blucarpet,/area/submap/Manor1) +"bp" = (/obj/effect/decal/cleanable/blood,/turf/simulated/floor/carpet/blucarpet,/area/submap/Manor1) +"bq" = (/obj/effect/decal/cleanable/blood/drip,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"br" = (/obj/structure/bed/chair/comfy/purp{icon_state = "comfychair_preview"; dir = 4},/turf/simulated/floor/holofloor/wood{icon_state = "wood_broken5"},/area/submap/Manor1) +"bs" = (/obj/structure/table,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bt" = (/obj/structure/bed/chair/wood{icon_state = "wooden_chair"; dir = 4},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bu" = (/obj/structure/bed/chair/wood{icon_state = "wooden_chair"; dir = 8},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bv" = (/obj/structure/table/standard,/obj/item/weapon/reagent_containers/food/condiment/small/sugar,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bw" = (/obj/effect/decal/cleanable/blood/drip,/turf/simulated/floor/carpet/blucarpet,/area/submap/Manor1) +"bx" = (/obj/structure/bed/chair/comfy/purp{icon_state = "comfychair_preview"; dir = 4},/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"by" = (/obj/structure/closet/cabinet,/obj/item/clothing/suit/storage/hooded/wintercoat,/obj/item/clothing/head/hood/winter,/obj/item/clothing/shoes/boots/winter,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bz" = (/obj/structure/table/woodentable,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bA" = (/obj/structure/table/standard,/obj/item/weapon/material/kitchen/utensil/fork,/obj/item/weapon/material/kitchen/utensil/fork,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bB" = (/obj/structure/closet/secure_closet/freezer/fridge,/obj/item/weapon/reagent_containers/food/snacks/stew,/obj/item/weapon/reagent_containers/food/snacks/stew,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bC" = (/obj/item/weapon/shovel,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bD" = (/obj/structure/bed/chair/wood{icon_state = "wooden_chair"; dir = 1},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bE" = (/obj/structure/table/standard,/obj/item/weapon/material/kitchen/utensil/spoon,/obj/item/weapon/material/kitchen/utensil/spoon,/obj/item/weapon/material/kitchen/utensil/spoon,/obj/effect/spider/stickyweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bF" = (/obj/structure/table/standard,/obj/effect/spider/stickyweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bG" = (/obj/structure/closet/secure_closet/freezer/fridge,/obj/item/weapon/reagent_containers/food/snacks/sausage,/obj/item/weapon/reagent_containers/food/snacks/sausage,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bH" = (/obj/effect/decal/cleanable/dirt,/obj/structure/flora/pottedplant/drooping,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bI" = (/obj/effect/decal/cleanable/dirt,/obj/structure/flora/pottedplant/dead,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bJ" = (/obj/structure/table/standard,/obj/item/weapon/material/kitchen/rollingpin,/obj/effect/spider/stickyweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bK" = (/obj/structure/table/standard,/obj/item/weapon/reagent_containers/glass/bottle/stoxin,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bL" = (/obj/structure/table/woodentable,/obj/item/weapon/storage/fancy/candle_box,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bM" = (/obj/machinery/papershredder,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bN" = (/obj/structure/simple_door/wood,/turf/simulated/floor/carpet/purcarpet,/area/submap/Manor1) +"bO" = (/obj/machinery/icecream_vat,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bP" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/carpet/blucarpet,/area/submap/Manor1) +"bQ" = (/obj/effect/decal/cleanable/blood,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bR" = (/obj/effect/decal/cleanable/cobweb,/obj/structure/table/woodentable,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bS" = (/obj/structure/flora/pottedplant/subterranean,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bT" = (/obj/item/weapon/material/minihoe,/turf/simulated/floor/carpet/blucarpet,/area/submap/Manor1) +"bU" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/carpet/purcarpet,/area/submap/Manor1) +"bV" = (/turf/simulated/floor/holofloor/wood{icon_state = "wood_broken6"},/area/submap/Manor1) +"bW" = (/obj/machinery/washing_machine,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bX" = (/obj/structure/table/woodentable,/obj/structure/bedsheetbin,/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bY" = (/obj/structure/table/rack,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bZ" = (/obj/structure/closet/crate,/obj/item/stack/cable_coil/random_belt,/obj/random/cash,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"ca" = (/obj/structure/table/woodentable,/obj/item/weapon/melee/umbrella/random,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cb" = (/obj/structure/closet/cabinet,/obj/random/gun/random,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cc" = (/obj/structure/closet/cabinet,/obj/item/weapon/cell/device/weapon,/obj/item/weapon/cell/device/weapon,/obj/random/medical,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cd" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp/green,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"ce" = (/obj/structure/bed/double,/obj/item/weapon/bedsheet/rddouble,/obj/structure/curtain/open/bed,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cf" = (/obj/structure/table/woodentable,/obj/item/weapon/storage/wallet/random,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cg" = (/obj/structure/flora/pottedplant/dead,/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"ch" = (/obj/structure/loot_pile/surface/bones,/obj/item/clothing/accessory/sweater,/turf/simulated/floor/carpet/blucarpet,/area/submap/Manor1) +"ci" = (/obj/structure/closet/crate,/obj/item/weapon/flame/lighter/random,/obj/random/powercell,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cj" = (/obj/structure/closet/cabinet,/obj/item/clothing/shoes/boots/winter,/obj/item/clothing/suit/storage/hooded/wintercoat,/obj/item/clothing/head/hood/winter,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"ck" = (/obj/effect/decal/cleanable/spiderling_remains,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cl" = (/turf/simulated/floor/carpet/turcarpet,/area/submap/Manor1) +"cm" = (/obj/effect/decal/cleanable/blood,/obj/structure/bed/chair/comfy/purp{icon_state = "comfychair_preview"; dir = 4},/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cn" = (/obj/structure/closet/crate,/obj/item/weapon/storage/wallet/random,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"co" = (/obj/structure/coatrack,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cp" = (/obj/structure/loot_pile/surface/bones,/obj/item/clothing/suit/storage/hooded/wintercoat,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cq" = (/obj/structure/loot_pile/surface/bones,/obj/item/clothing/under/suit_jacket,/obj/item/clothing/shoes/black,/obj/random/projectile/random,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cr" = (/obj/structure/simple_door/wood,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/carpet/purcarpet,/area/submap/Manor1) +"cs" = (/obj/item/weapon/material/twohanded/spear,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"ct" = (/obj/structure/closet/cabinet{opened = 1},/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cu" = (/obj/effect/decal/remains,/obj/item/weapon/material/knife/tacknife/combatknife,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cv" = (/obj/structure/sink{pixel_y = 30},/turf/simulated/floor/tiled/hydro,/area/submap/Manor1) +"cw" = (/turf/simulated/floor/tiled/hydro,/area/submap/Manor1) +"cx" = (/obj/structure/table/standard,/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor/tiled/hydro,/area/submap/Manor1) +"cy" = (/obj/structure/table/standard,/obj/item/weapon/towel/random,/obj/item/weapon/towel/random,/turf/simulated/floor/tiled/hydro,/area/submap/Manor1) +"cz" = (/obj/effect/decal/cleanable/cobweb2,/obj/effect/spider/stickyweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cA" = (/obj/item/weapon/paper/crumpled,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cB" = (/turf/simulated/floor/holofloor/wood{icon_state = "wood_broken3"},/area/submap/Manor1) +"cC" = (/obj/effect/decal/cleanable/spiderling_remains,/obj/effect/spider/stickyweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cD" = (/obj/structure/closet/crate,/obj/item/clothing/suit/armor/vest,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cE" = (/obj/structure/closet/crate,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cF" = (/obj/structure/simple_door/wood,/turf/simulated/floor/tiled/hydro,/area/submap/Manor1) +"cG" = (/obj/structure/toilet{icon_state = "toilet00"; dir = 8},/turf/simulated/floor/tiled/hydro,/area/submap/Manor1) +"cH" = (/obj/machinery/shower{icon_state = "shower"; dir = 8},/obj/structure/curtain/open/shower,/turf/simulated/floor/tiled/hydro,/area/submap/Manor1) +"cI" = (/obj/item/stack/material/wood,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cJ" = (/obj/machinery/shower{icon_state = "shower"; dir = 8},/obj/structure/curtain/open/shower,/obj/random/soap,/turf/simulated/floor/tiled/hydro,/area/submap/Manor1) +"cK" = (/obj/structure/table/standard,/turf/simulated/floor/tiled/hydro,/area/submap/Manor1) +"cL" = (/obj/structure/toilet{icon_state = "toilet00"; dir = 1},/turf/simulated/floor/tiled/hydro,/area/submap/Manor1) +"cM" = (/obj/structure/table/woodentable,/obj/item/device/laptop,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cN" = (/turf/template_noop,/area/template_noop) +"cO" = (/obj/structure/flora/tree/sif,/turf/template_noop,/area/submap/Manor1) (1,1,1) = {" -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -"} -(2,1,1) = {" -cN -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -cN -"} -(3,1,1) = {" -cN -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -cO -aa -aa -aa -aa -aa -aa -aa -aa -aa -cN -"} -(4,1,1) = {" -cN -aa -aa -aa -cO -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -cN -"} -(5,1,1) = {" -cN -aa -aa -aa -aa -aa -aa -aa -aa -cO -aa -aa -aa -aa -aa -aa -aa -ab -bn -bn -ab -aa -aa -aa -aa -aa -aa -ab -ac -ac -ab -aa -aa -aa -aa -aa -aa -cO -aa -cN -"} -(6,1,1) = {" -cN -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -ab -ab -ag -ag -ab -ab -aa -aa -aa -aa -ab -ab -ag -ag -ab -ab -aa -aa -aa -aa -aa -aa -aa -cN -"} -(7,1,1) = {" -cN -aa -aa -aa -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -bj -ag -ag -ag -ab -ab -ab -ab -ab -ab -ag -ag -ag -ag -ab -ab -ab -aa -aa -aa -aa -aa -cN -"} -(8,1,1) = {" -cN -aa -aa -aa -aa -ab -ab -ax -ab -ag -as -ag -ag -aD -ab -aD -ag -ag -ag -ag -ag -ag -ag -ag -az -ab -bR -ag -ag -ag -bQ -cq -ct -ab -ab -aa -aa -aa -aa -cN -"} -(9,1,1) = {" -cN -aa -aa -aa -ab -ab -at -ag -as -ag -ab -ag -ag -al -ab -al -bh -ag -ag -ag -ag -ag -ag -ag -al -ab -az -ag -ag -bq -bQ -ag -ag -al -ab -ab -aa -aa -aa -cN -"} -(10,1,1) = {" -cN -aa -aa -ab -ab -al -au -ay -ab -ag -ab -aT -aM -aO -ab -bg -ag -bk -aO -al -by -ag -ag -ag -ag -ab -bS -ag -bq -ag -ag -ag -cu -ag -al -ab -ab -aa -aa -cN -"} -(11,1,1) = {" -cN -aa -aa -ab -ab -ab -ab -ab -ab -as -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -as -ab -ab -ab -ab -as -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -cN -"} -(12,1,1) = {" -cN -aa -aa -ab -ak -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -al -az -al -ag -ag -an -an -ag -ag -ag -bQ -bq -ag -bq -ag -ah -ab -cv -cw -cw -cw -cw -ab -aa -cN -"} -(13,1,1) = {" -cN -aa -aa -ab -ag -aq -aq -aq -aq -aq -aq -aq -aq -aq -aq -aq -aq -aq -aq -ar -ar -ar -ar -aq -aq -aq -aq -aq -aq -aq -aq -as -cw -ab -cF -ab -cF -ab -aa -cN -"} -(14,1,1) = {" -cN -aa -aa -ab -ag -aq -aq -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -an -an -an -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ab -cx -ab -cG -ab -cG -ab -aa -cN -"} -(15,1,1) = {" -cN -aa -aa -ab -ag -aq -aq -ag -ab -ab -ab -ab -ab -ab -ab -ab -as -ab -ab -ab -ab -ab -ab -ab -ab -ag -ag -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -cN -"} -(16,1,1) = {" -cN -aa -aa -ab -al -aq -aq -az -ab -aF -ag -ag -ag -ag -ag -ag -ag -ag -an -ag -ag -ag -ag -aG -ab -an -ag -ab -bW -ag -bW -ab -cy -cw -cw -cw -cw -ab -aa -cN -"} -(17,1,1) = {" -cN -aa -aa -ab -am -ar -aq -al -ab -aG -ag -aU -aU -aU -ag -aU -aU -aU -an -aU -aU -aU -ag -bL -ab -an -ag -ab -bX -ag -az -ab -cw -cw -cH -cH -cJ -ab -aa -cN -"} -(18,1,1) = {" -cN -aa -aa -ab -al -ar -aq -al -ab -ag -ag -ag -ag -ag -ag -ag -ag -an -an -an -an -an -an -bM -ab -an -an -ab -ab -as -ab -ab -as -ab -ab -ab -ab -ab -aa -cN -"} -(19,1,1) = {" -cN -aa -aa -ab -ag -ar -aq -ag -ab -al -ag -aU -aU -aU -ag -aU -aU -aU -an -aU -aU -aU -ag -ag -as -an -an -as -ag -ag -ag -ag -ag -ag -as -cw -cK -ab -aa -cN -"} -(20,1,1) = {" -cN -aa -aa -ab -an -ar -ar -an -ab -aH -ag -ag -ag -ag -an -an -an -an -an -ag -ag -ag -ag -ai -ab -an -an -ab -ab -ab -as -ab -ab -ab -ab -cv -cL -ab -aa -cN -"} -(21,1,1) = {" -cN -aa -ab -ab -an -ar -ar -an -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -an -an -ab -bY -ag -ag -ag -bY -bY -ab -ab -ab -ab -aa -cN -"} -(22,1,1) = {" -cN -ab -ab -ag -ag -ar -ar -an -ab -aI -aK -ag -ag -ag -ag -ag -ag -ag -an -an -an -an -bH -ab -ab -an -an -ab -ag -ag -ag -ag -ag -cC -ab -ab -aa -aa -aa -cN -"} -(23,1,1) = {" -cN -ac -ad -ag -ag -ar -ar -aA -ab -aJ -aK -ad -ad -ad -ad -ad -ad -ad -ad -bt -bt -an -an -ab -ab -an -an -ab -bZ -ci -cn -ag -aK -aJ -ab -aa -aa -aa -aa -cN -"} -(24,1,1) = {" -cN -ac -ae -ag -ag -aq -ar -aB -ab -aK -aP -al -al -al -al -al -aG -al -al -al -al -bh -an -ab -ab -as -as -ab -ab -ab -ab -aK -aK -cD -ab -aa -aa -aa -aa -cN -"} -(25,1,1) = {" -cN -ac -af -ag -ag -ar -ar -aA -ab -ag -aP -aV -al -al -al -al -al -al -al -al -al -bh -ag -ab -al -ag -ag -al -al -cj -ab -ab -cz -cE -ab -aa -aa -aa -aa -cN -"} -(26,1,1) = {" -cN -ac -ag -ag -an -ar -ar -ag -ab -ag -ag -af -af -af -af -af -af -af -af -af -af -ag -ag -ab -al -ag -ag -ag -ag -ck -co -ab -ab -ab -ab -aa -aa -aa -aa -cN -"} -(27,1,1) = {" -cN -ab -ah -ag -an -ar -ar -an -ab -aL -aQ -aQ -aQ -aQ -aQ -aQ -aQ -aQ -aQ -aQ -aQ -aQ -aQ -bN -aQ -aQ -aQ -bU -bU -bU -bU -cr -bU -bU -bN -aa -aa -aa -aa -cN -"} -(28,1,1) = {" -cN -ab -ai -ag -an -ar -ar -an -ab -aL -aQ -aQ -aQ -aQ -aQ -aQ -aQ -aQ -aQ -aQ -aQ -aQ -aQ -bN -aQ -aQ -aQ -aQ -bU -bU -bU -cr -bU -bU -bN -aa -aa -aa -aa -cN -"} -(29,1,1) = {" -cN -ac -ag -ag -an -ar -ar -ag -ab -ag -ag -ad -ad -ad -ad -ad -ad -ad -ad -ad -ad -ag -ag -ab -al -ag -ag -ag -ag -ag -co -ab -ab -ab -ab -aa -aa -aa -aa -cN -"} -(30,1,1) = {" -cN -ac -ad -ag -ag -ar -ar -ag -ab -ag -aP -aV -al -al -al -al -al -al -al -al -al -bh -an -ab -al -ag -ag -al -ca -cj -ab -ab -az -al -ab -aa -aa -aa -aa -cN -"} -(31,1,1) = {" -cN -ac -aj -ag -ag -ar -ar -ag -ab -ag -aP -al -al -al -al -al -al -al -al -al -bz -bD -an -ab -ab -as -as -ab -ab -ab -ab -ag -af -ag -ab -aa -aa -aa -aa -cN -"} -(32,1,1) = {" -cN -ac -af -ag -ag -aq -ar -ag -ab -ag -ag -af -af -af -af -af -af -af -af -bu -bu -an -an -ab -ab -ag -ag -ab -cb -ag -ag -ag -ag -ag -ab -aa -aa -aa -aa -cN -"} -(33,1,1) = {" -cN -ab -ab -ag -ag -aq -aq -ag -ab -ah -ag -ag -ag -ag -ag -ag -ag -ag -ag -an -an -an -bI -ab -ab -ag -ag -ab -cc -cl -cl -cl -cl -ag -ab -ab -aa -aa -aa -cN -"} -(34,1,1) = {" -cN -aa -ab -ab -ag -aq -aq -ag -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -as -ab -ab -ab -ab -ab -ab -ag -ag -ab -ag -cl -cl -cl -cl -ag -ah -ab -ab -ab -aa -cN -"} -(35,1,1) = {" -cN -aa -aa -ab -ag -aq -aq -ag -ab -ag -aR -aR -aR -bb -ag -ag -ag -ag -ag -ag -ag -ag -ag -bO -ab -ag -ag -ab -cd -cl -cl -cl -cl -ag -ag -al -cM -ab -aa -cN -"} -(36,1,1) = {" -cN -aa -aa -ab -ag -aq -aq -ag -ab -aM -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -aK -ab -ag -ag -ab -ce -cl -cl -cl -cl -cl -cl -cl -al -ab -aa -cN -"} -(37,1,1) = {" -cN -aa -aa -ab -ag -aq -aq -ag -ab -ag -aR -aW -aZ -aR -ag -ag -ag -ag -ag -aR -bA -bE -bF -aK -ab -ag -ag -ab -cf -cl -cl -cl -cl -cl -cl -cl -al -ab -aa -cN -"} -(38,1,1) = {" -cN -aa -aa -ab -al -aq -aq -al -ab -ag -aR -aX -aR -bc -ag -ag -ag -ag -ag -bv -aR -bF -bJ -aK -ab -ag -ag -ab -ag -cl -cl -cl -cl -cl -cl -cl -ag -ab -aa -cN -"} -(39,1,1) = {" -cN -aa -aa -ab -al -aq -aq -al -ab -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ab -ag -ag -ab -ag -cl -cl -cl -cl -cl -cl -cl -ag -ab -aa -cN -"} -(40,1,1) = {" -cN -aa -aa -ab -al -aq -aq -aC -ab -aN -aS -aY -ba -bd -ag -ag -ag -ag -ag -ag -bB -bG -bK -ag -ab -ag -ag -ab -cg -aD -al -al -ag -cl -cl -cl -ag -ab -aa -cN -"} -(41,1,1) = {" -cN -aa -aa -ab -ag -aq -aq -ag -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -as -ab -ab -ab -ab -ab -ab -ag -ag -ab -ab -ab -ab -ab -ag -cl -cl -cl -ag -ab -aa -cN -"} -(42,1,1) = {" -cN -aa -aa -ab -ag -aq -aq -ag -ag -ag -ag -al -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ah -ab -ag -cl -cl -cl -ag -ab -aa -cN -"} -(43,1,1) = {" -cN -aa -aa -ab -ag -aq -aq -aq -aq -aq -aq -aq -aq -aq -aq -aq -aq -aq -aq -aq -aq -aq -aq -aq -aq -aq -aq -aq -aq -aq -aq -as -ag -cl -cl -cl -ag -ab -aa -cN -"} -(44,1,1) = {" -cN -aa -aa -ab -ai -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ag -ah -ab -ah -ag -ag -ag -ah -ab -aa -cN -"} -(45,1,1) = {" -cN -aa -aa -ab -ab -as -ab -ab -ab -ab -ab -as -ab -ab -ab -ab -ab -ab -as -ab -ab -ab -ab -ab -ab -ab -ab -ab -as -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -cN -"} -(46,1,1) = {" -cN -aa -aa -ab -ao -ag -av -ab -aD -aO -ab -ag -ab -aO -aD -ab -bi -ag -ag -ag -ag -al -aD -al -al -az -al -ag -ag -bq -ag -cs -ag -cA -ag -cI -ab -ab -aa -cN -"} -(47,1,1) = {" -cN -aa -aa -ab -ap -ag -ag -ab -ag -ag -ab -ag -ab -ag -be -ab -ag -bl -bo -bl -bl -bl -bl -bl -bw -bl -bl -bl -bp -bw -bw -bl -cA -bq -cI -ab -ab -aa -aa -cN -"} -(48,1,1) = {" -cN -aa -aa -aa -ab -ab -aw -ab -ag -ag -as -ag -as -ag -ag -ab -ag -bm -bp -bw -bl -bl -bl -bl -bP -bP -bT -bl -ch -bl -bl -bw -cB -ag -ab -ab -aa -aa -aa -cN -"} -(49,1,1) = {" -cN -aa -aa -aa -aa -ab -ab -ab -aE -al -ab -ag -ab -al -bf -ab -ag -ag -bq -ag -ag -ag -al -al -al -al -ag -bV -ag -ag -ag -ag -ag -ab -ab -aa -aa -aa -aa -cN -"} -(50,1,1) = {" -cN -aa -aa -aa -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ag -br -bx -bC -ab -ab -ab -ab -ab -ab -ag -bx -cm -cp -ab -ab -ab -aa -aa -aa -aa -aa -cN -"} -(51,1,1) = {" -cN -aa -aa -aa -cO -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -ab -ab -bs -bs -ab -ab -aa -aa -aa -aa -ab -ab -bs -ag -ab -ab -aa -aa -aa -aa -cO -aa -aa -cN -"} -(52,1,1) = {" -cN -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -ab -ac -ac -ab -aa -aa -aa -aa -aa -aa -ab -ac -ac -ab -aa -aa -aa -aa -aa -aa -aa -aa -cN -"} -(53,1,1) = {" -cN -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -cN -"} -(54,1,1) = {" -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -cN -"} +cNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcN +cNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacababacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacN +cNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababadaeafagahaiagadajafababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacN +cNaaaaaaaaaaaaaaaaababababababababababababagagagagagagagagagagagagababababababababababababababaaaaaaaaaaaacN +cNaaaacOaaaaaaaaabababakagagagalamalagananagagagagananananagagagagagagagagalalalagagagaiabaoapabaaaacOaaaacN +cNaaaaaaaaaaaaababalabagaqaqaqaqarararararararaqarararararararaqaqaqaqaqaqaqaqaqaqaqaqagasagagababaaaaaaaacN +cNaaaaaaaaaaababatauabagaqaqaqaqaqaqaqarararararararararararararaqaqaqaqaqaqaqaqaqaqaqagabavagawababaaaaaacN +cNaaaaaaaaaaabaxagayabagaqagagazalalaganananaAaBaAagananagagagagagagagagagalalaCagagaqagababababababaaaaaacN +cNaaaaaaaaaaababasababagaqagabababababababababababababababababababababababababababagaqagabaDagagaEabaaaaaacN +cNaaaaaacOaaabagagagasagaqagabaFaGagalaHabaIaJaKagagaLaLagagagagahabagaMagagagaNabagaqagabaOagagalabaaaaaacN +cNaaaaaaaaaaabasabababagaqagabagagagagagabaKaKaPaPagaQaQagaPaPagagabaRagaRaRagaSabagaqagabababasababaaaaaacN +cNaaaaaaaaaaabagagaTabagaqagabagaUagaUagabagadalaVafaQaQadaValafagabaRagaWaXagaYabalaqagasagagagagabaaaaaacN +cNaaaaaaaaaaabagagaMabagaqagabagaUagaUagabagadalalafaQaQadalalafagabaRagaZaRagbaabagaqagabababasababaaaaaacN +cNaaaaaaaaaaabaDalaOabagaqagabagaUagaUagabagadalalafaQaQadalalafagabbbagaRbcagbdabagaqagabaOagagalabaaaaaacN +cNaaaaaaaaaaabababababagaqagabagagagaganabagadalalafaQaQadalalafagabagagagagagagabagaqagabaDbeagbfabaaaaaacN +cNaaaaaaaaaaabaDalbgabalaqagabagaUagaUanabagadalalafaQaQadalalafagabagagagagagagabagaqagababababababaaaaaacN +cNaaaaaaaaababagbhagabazaqagasagaUagaUanabagadaGalafaQaQadalalafagabagagagagagagabagaqagabbiagagagababaaaacN +cNaaaaaaababbjagagbkabalaqagabagaUanaUanabagadalalafaQaQadalalafagabagagagagagagabagaqagabagblbmagagababaacN +cNaaaaaabnagagagagaOabagaqanabanananananabanadalalafaQaQadalalafagasagagagagagagasagaqagasagbobpbqbrbsacaacN +cNaaaaaabnagagagagalabagaranabagaUanaUagabanbtalalafaQaQadalalbuanabagagaRbvagagabagaqagabagblbwagbxbsacaacN +cNaaaaaaababagagagbyabanaranabagaUanaUagabanbtalalafaQaQadalbzbuanabagagbAaRagbBabagaqagabagblblagbCababaacN +cNaaaaaaaaababagagagabanaragabagaUanaUagabananbhbhagaQaQagbhbDananabagagbEbFagbGabagaqagabalblblagababaaaacN +cNaaaaaaaaaaabagagagabagaragabagaganagagabbHananagagaQaQaganananbIabagagbFbJagbKabagaqagabaDblblalabaaaaaacN +cNaaaaaaaaaaabagagagasagaqagabaGbLbMagaiababababababbNbNababababababbOaKaKaKagagabagaqagabalblblalabaaaaaacN +cNaaaaaaaaaaabazalagabagaqagababababasabababababalalaQaQalalabababababababababababagaqagabalbwbPalabaaaaaacN +cNaaaaaaaaaaabababababbQaqagagananananananananasagagaQaQagagasagagagagagagagagagagagaqagabazblbPalabaaaaaacN +cNaaaaaaaaababbRazbSabbqaqagagagagananananananasagagaQaQagagasagagagagagagagagagagagaqagabalblbTagababaaaacN +cNaaaaaaababagagagagabagaqagababababasabababababalagbUaQagalabababababababababababagaqagabagblblbVagababaacN +cNaaaaaaacagagagagbqasbqaqagabbWbXabagabbYagbZabalagbUbUagcaabcbccagcdcecfagagcgabagaqagasagbpchagbxbsacaacN +cNaacOaaacagagagbqagabagaqagabagagasagabagagciabcjckbUbUagcjabagclclclclclclclaDabagaqagabbqbwblagcmagacaacN +cNaaaaaaababagbQbQagabahaqagabbWazabagasagagcnababcobUbUcoababagclclclclclclclalabahaqahabagbwblagcpababaacN +cNaaaaaaaaababcqagagababasabababababagabagagagaKababcrcrababagagclclclclclclclalababasababcsblbwagababaaaacN +cNaaaaaaaaaaabctagcuabcvcwcxabcycwasagabbYagaKaKczabbUbUabazafagclclclclclclclagagagagahabagcAcBagabaaaaaacN +cNaaaaaaaaaaababalagabcwabababcwcwabagabbYcCaJcDcEabbUbUabalagagagagagclclclclclclclclagabcAbqagababaaaaaacN +cNaaaaaaaaaaaaababalabcwcFcGabcwcHabasabababababababbNbNabababababahagclclclclclclclclagabagcIababaaaaaaaacN +cNaaaaaaaaaaaaaaabababcwabababcwcHabcwcvababaaaaaaaaaaaaaaaaaaaaababalclclclclclclclclagabcIababaaaaaaaaaacN +cNaaaaaaaaaaaaaaaaababcwcFcGabcwcJabcKcLabaaaaaaaaaaaaaaaaaaaaaaaaabcMalalagagagagagagahabababaaaaaacOaaaacN +cNaaaaaacOaaaaaaaaaaabababababababababababaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababaaaaaaaaaaaaaacN +cNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacN +cNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcN +"} \ No newline at end of file diff --git a/maps/submaps/surface_submaps/wilderness/Mudpit.dmm b/maps/submaps/surface_submaps/wilderness/Mudpit.dmm index 811e6105cc..93138d5379 100644 --- a/maps/submaps/surface_submaps/wilderness/Mudpit.dmm +++ b/maps/submaps/surface_submaps/wilderness/Mudpit.dmm @@ -1,322 +1,33 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"a" = ( -/turf/template_noop, -/area/template_noop) -"b" = ( -/obj/effect/decal/cleanable/liquid_fuel, -/turf/simulated/floor/outdoors/dirt, -/area/submap/Mudpit) -"c" = ( -/turf/simulated/floor/outdoors/dirt, -/area/submap/Mudpit) -"d" = ( -/turf/simulated/floor/outdoors/mud, -/area/submap/Mudpit) -"e" = ( -/obj/effect/decal/cleanable/liquid_fuel, -/obj/effect/decal/cleanable/liquid_fuel, -/turf/simulated/floor/outdoors/dirt, -/area/submap/Mudpit) -"f" = ( -/obj/effect/decal/cleanable/liquid_fuel, -/obj/effect/decal/cleanable/liquid_fuel, -/obj/effect/decal/cleanable/liquid_fuel, -/turf/simulated/floor/outdoors/dirt, -/area/submap/Mudpit) -"g" = ( -/obj/effect/decal/remains/mouse, -/turf/simulated/floor/outdoors/dirt, -/area/submap/Mudpit) -"h" = ( -/obj/effect/decal/remains/mouse, -/obj/effect/decal/cleanable/liquid_fuel, -/obj/effect/decal/cleanable/liquid_fuel, -/turf/simulated/floor/outdoors/dirt, -/area/submap/Mudpit) -"i" = ( -/obj/effect/decal/cleanable/liquid_fuel, -/turf/template_noop, -/area/template_noop) -"j" = ( -/turf/simulated/mineral, -/area/submap/Mudpit) -"k" = ( -/obj/structure/reagent_dispensers/fueltank, -/turf/simulated/floor/outdoors/dirt, -/area/submap/Mudpit) -"l" = ( -/obj/machinery/portable_atmospherics/canister/empty/phoron, -/turf/simulated/floor/outdoors/dirt, -/area/submap/Mudpit) -"m" = ( -/obj/effect/decal/remains, -/obj/item/clothing/suit/space/void/merc/fire, -/obj/item/clothing/head/helmet/space/void/merc/fire, -/turf/simulated/floor/outdoors/dirt, -/area/submap/Mudpit) -"n" = ( -/obj/effect/decal/mecha_wreckage/ripley/firefighter, -/turf/simulated/floor/outdoors/dirt, -/area/submap/Mudpit) -"D" = ( -/mob/living/simple_animal/hostile/giant_spider/thermic{ - returns_home = 1 - }, -/turf/simulated/floor/outdoors/dirt, -/area/submap/Mudpit) +"a" = (/turf/template_noop,/area/template_noop) +"b" = (/obj/effect/decal/cleanable/liquid_fuel,/turf/simulated/floor/outdoors/dirt,/area/submap/Mudpit) +"c" = (/turf/simulated/floor/outdoors/dirt,/area/submap/Mudpit) +"d" = (/turf/simulated/floor/outdoors/mud,/area/submap/Mudpit) +"e" = (/obj/effect/decal/cleanable/liquid_fuel,/obj/effect/decal/cleanable/liquid_fuel,/turf/simulated/floor/outdoors/dirt,/area/submap/Mudpit) +"f" = (/obj/effect/decal/cleanable/liquid_fuel,/obj/effect/decal/cleanable/liquid_fuel,/obj/effect/decal/cleanable/liquid_fuel,/turf/simulated/floor/outdoors/dirt,/area/submap/Mudpit) +"g" = (/obj/effect/decal/remains/mouse,/turf/simulated/floor/outdoors/dirt,/area/submap/Mudpit) +"h" = (/obj/effect/decal/remains/mouse,/obj/effect/decal/cleanable/liquid_fuel,/obj/effect/decal/cleanable/liquid_fuel,/turf/simulated/floor/outdoors/dirt,/area/submap/Mudpit) +"i" = (/obj/effect/decal/cleanable/liquid_fuel,/turf/template_noop,/area/template_noop) +"j" = (/turf/simulated/mineral,/area/submap/Mudpit) +"k" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/outdoors/dirt,/area/submap/Mudpit) +"l" = (/obj/machinery/portable_atmospherics/canister/empty/phoron,/turf/simulated/floor/outdoors/dirt,/area/submap/Mudpit) +"m" = (/obj/effect/decal/remains,/obj/item/clothing/suit/space/void/merc/fire,/obj/item/clothing/head/helmet/space/void/merc/fire,/turf/simulated/floor/outdoors/dirt,/area/submap/Mudpit) +"n" = (/mob/living/simple_mob/animal/giant_spider/thermic,/turf/simulated/floor/outdoors/dirt,/area/submap/Mudpit) +"o" = (/obj/effect/decal/mecha_wreckage/ripley/firefighter,/turf/simulated/floor/outdoors/dirt,/area/submap/Mudpit) (1,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(2,1,1) = {" -a -b -c -c -i -i -i -c -g -d -c -a -a -b -a -"} -(3,1,1) = {" -a -c -c -c -b -b -b -c -d -d -d -d -c -b -a -"} -(4,1,1) = {" -a -c -c -d -c -b -j -j -j -d -d -d -d -a -a -"} -(5,1,1) = {" -a -c -b -d -d -d -j -j -j -j -d -d -d -c -a -"} -(6,1,1) = {" -a -a -c -d -d -j -j -j -j -j -d -d -d -g -a -"} -(7,1,1) = {" -a -a -c -g -j -j -j -k -l -j -j -d -d -c -a -"} -(8,1,1) = {" -a -c -c -c -j -j -c -c -c -c -g -b -d -c -a -"} -(9,1,1) = {" -a -b -b -c -c -c -c -c -m -c -D -b -b -c -a -"} -(10,1,1) = {" -a -b -b -c -b -c -c -c -D -c -c -b -b -a -a -"} -(11,1,1) = {" -a -b -d -d -c -c -g -c -n -c -c -b -d -c -a -"} -(12,1,1) = {" -a -d -d -d -d -c -c -c -c -c -d -d -d -d -a -"} -(13,1,1) = {" -a -e -e -d -d -d -d -c -c -c -d -d -d -d -a -"} -(14,1,1) = {" -a -e -f -h -c -c -a -a -i -c -c -c -d -b -a -"} -(15,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} +aaaaaaaaaaaaaaa +abcccaacbbbdeea +acccbcccbbddefa +accdddgcccdddha +aibcddjjcbcddca +aibbdjjjccccdca +aibjjjjcccgcdaa +accjjjkccccccaa +agdjjjlcmnoccia +adddjjjccccccca +acddddjgnccddca +aadddddbbbbddca +aacdddddbbdddda +abbacgcccacddba +aaaaaaaaaaaaaaa +"} \ No newline at end of file diff --git a/maps/submaps/surface_submaps/wilderness/Rockybase.dmm b/maps/submaps/surface_submaps/wilderness/Rockybase.dmm index e805a56a6d..7e5889f458 100644 --- a/maps/submaps/surface_submaps/wilderness/Rockybase.dmm +++ b/maps/submaps/surface_submaps/wilderness/Rockybase.dmm @@ -1,3284 +1,227 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"aa" = ( -/turf/template_noop, -/area/template_noop) -"ab" = ( -/obj/effect/decal/remains, -/turf/template_noop, -/area/template_noop) -"ac" = ( -/obj/item/weapon/grenade/chem_grenade/metalfoam, -/turf/template_noop, -/area/template_noop) -"ad" = ( -/mob/living/simple_animal/hostile/viscerator{ - returns_home = 1 - }, -/turf/template_noop, -/area/template_noop) -"ae" = ( -/obj/effect/decal/remains, -/turf/template_noop, -/area/submap/Rockybase) -"af" = ( -/turf/template_noop, -/area/submap/Rockybase) -"ag" = ( -/obj/structure/flora/tree/sif, -/turf/template_noop, -/area/submap/Rockybase) -"ah" = ( -/obj/effect/gibspawner/robot, -/turf/template_noop, -/area/submap/Rockybase) -"ai" = ( -/turf/simulated/mineral/ignore_mapgen, -/area/submap/Rockybase) -"aj" = ( -/obj/effect/decal/remains/robot, -/turf/template_noop, -/area/template_noop) -"ak" = ( -/mob/living/simple_animal/hostile/malf_drone/lesser, -/turf/template_noop, -/area/submap/Rockybase) -"al" = ( -/turf/simulated/floor, -/area/submap/Rockybase) -"am" = ( -/obj/effect/decal/remains/posi, -/turf/simulated/floor, -/area/submap/Rockybase) -"an" = ( -/obj/machinery/porta_turret/poi, -/turf/simulated/floor, -/area/submap/Rockybase) -"ao" = ( -/obj/effect/decal/cleanable/blood, -/turf/simulated/floor, -/area/submap/Rockybase) -"ap" = ( -/obj/structure/flora/tree/sif, -/turf/template_noop, -/area/template_noop) -"aq" = ( -/obj/effect/floor_decal/industrial/danger, -/turf/simulated/floor, -/area/submap/Rockybase) -"ar" = ( -/obj/machinery/light, -/obj/effect/floor_decal/industrial/danger, -/turf/simulated/floor, -/area/submap/Rockybase) -"as" = ( -/obj/effect/decal/cleanable/blood, -/obj/effect/floor_decal/industrial/danger, -/turf/simulated/floor, -/area/submap/Rockybase) -"at" = ( -/turf/simulated/wall/r_wall, -/area/submap/Rockybase) -"au" = ( -/obj/structure/sign/securearea, -/turf/simulated/wall/r_wall, -/area/submap/Rockybase) -"av" = ( -/obj/machinery/door/airlock/external, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"aw" = ( -/obj/effect/decal/remains/deer, -/turf/template_noop, -/area/template_noop) -"ax" = ( -/obj/machinery/shower{ - dir = 4; - icon_state = "shower"; - pixel_x = 5; - pixel_y = 0 - }, -/obj/structure/curtain/open/shower, -/obj/machinery/light/small{ - dir = 8 - }, -/turf/simulated/floor/tiled/hydro, -/area/submap/Rockybase) -"ay" = ( -/turf/simulated/floor/tiled/hydro, -/area/submap/Rockybase) -"az" = ( -/obj/machinery/shower{ - dir = 8; - icon_state = "shower"; - pixel_x = -5; - pixel_y = 0 - }, -/obj/structure/curtain/open/shower, -/obj/item/weapon/soap, -/turf/simulated/floor/tiled/hydro, -/area/submap/Rockybase) -"aA" = ( -/obj/structure/table/woodentable, -/obj/effect/decal/cleanable/cobweb, -/turf/simulated/floor/holofloor/lino, -/area/submap/Rockybase) -"aB" = ( -/obj/structure/table/woodentable, -/turf/simulated/floor/holofloor/lino, -/area/submap/Rockybase) -"aC" = ( -/obj/structure/table/woodentable, -/obj/item/device/flashlight/lamp, -/turf/simulated/floor/holofloor/lino, -/area/submap/Rockybase) -"aD" = ( -/obj/structure/closet{ - icon_closed = "cabinet_closed"; - icon_opened = "cabinet_open"; - icon_state = "cabinet_closed" - }, -/obj/item/weapon/pickaxe/plasmacutter, -/turf/simulated/floor/holofloor/lino, -/area/submap/Rockybase) -"aE" = ( -/turf/simulated/floor/holofloor/lino, -/area/submap/Rockybase) -"aF" = ( -/obj/structure/bed, -/obj/item/weapon/bedsheet, -/turf/simulated/floor/holofloor/lino, -/area/submap/Rockybase) -"aG" = ( -/obj/structure/table/woodentable, -/obj/machinery/light{ - dir = 1 - }, -/turf/simulated/floor/holofloor/lino, -/area/submap/Rockybase) -"aH" = ( -/obj/structure/bed, -/obj/item/weapon/bedsheet, -/mob/living/simple_animal/hostile/viscerator{ - returns_home = 1 - }, -/turf/simulated/floor/holofloor/lino, -/area/submap/Rockybase) -"aI" = ( -/obj/structure/bed, -/obj/item/weapon/bedsheet, -/obj/item/toy/plushie/spider, -/turf/simulated/floor/holofloor/lino, -/area/submap/Rockybase) -"aJ" = ( -/obj/structure/closet/l3closet/janitor, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"aK" = ( -/mob/living/bot/cleanbot{ - faction = "malf_drone" - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"aL" = ( -/obj/item/weapon/stool, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"aM" = ( -/obj/item/weapon/storage/belt/janitor, -/obj/structure/table/standard, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"aN" = ( -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"aO" = ( -/obj/structure/table/standard, -/obj/item/device/laptop, -/obj/effect/floor_decal/corner/red/border{ - icon_state = "bordercolor"; - dir = 9 - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"aP" = ( -/obj/structure/table/standard, -/obj/effect/floor_decal/corner/red/border{ - icon_state = "bordercolor"; - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"aQ" = ( -/obj/structure/table/rack, -/obj/item/weapon/gun/projectile/pistol, -/obj/effect/floor_decal/corner/red/border{ - icon_state = "bordercolor"; - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"aR" = ( -/obj/structure/table/rack, -/obj/item/weapon/gun/energy/gun/taser, -/obj/effect/floor_decal/corner/red/border{ - icon_state = "bordercolor"; - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"aS" = ( -/obj/machinery/light{ - dir = 1 - }, -/obj/effect/floor_decal/corner/red/border{ - icon_state = "bordercolor"; - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"aT" = ( -/obj/machinery/vending/coffee, -/obj/effect/floor_decal/corner/red/border{ - icon_state = "bordercolor"; - dir = 5 - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"aU" = ( -/turf/simulated/floor/tiled/techfloor, -/area/submap/Rockybase) -"aV" = ( -/obj/structure/table/rack, -/obj/item/weapon/gun/projectile/shotgun/pump/combat, -/obj/item/weapon/gun/projectile/shotgun/pump/combat, -/turf/simulated/floor/tiled/techfloor, -/area/submap/Rockybase) -"aW" = ( -/obj/machinery/vending/hydronutrients, -/obj/effect/floor_decal/corner/lime/border{ - icon_state = "bordercolor"; - dir = 9 - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"aX" = ( -/obj/structure/closet/crate/hydroponics, -/obj/effect/floor_decal/corner/lime/border{ - icon_state = "bordercolor"; - dir = 5 - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"aY" = ( -/obj/machinery/shower{ - dir = 4; - icon_state = "shower"; - pixel_x = 5; - pixel_y = 0 - }, -/obj/structure/curtain/open/shower, -/turf/simulated/floor/tiled/hydro, -/area/submap/Rockybase) -"aZ" = ( -/obj/machinery/shower{ - dir = 8; - icon_state = "shower"; - pixel_x = -5; - pixel_y = 0 - }, -/obj/structure/curtain/open/shower, -/turf/simulated/floor/tiled/hydro, -/area/submap/Rockybase) -"ba" = ( -/obj/structure/janitorialcart, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bb" = ( -/obj/structure/table/standard, -/obj/item/weapon/grenade/chem_grenade/cleaner, -/obj/item/weapon/grenade/chem_grenade/cleaner, -/obj/item/weapon/grenade/chem_grenade/cleaner, -/obj/machinery/light{ - icon_state = "tube1"; - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bc" = ( -/obj/machinery/light/small{ - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bd" = ( -/obj/structure/table/standard, -/obj/item/weapon/paper{ - info = "Carl's absolutly fucked in the head. He's trying to squeeze as much drone production out as he can since he's worried we're gonna get found out but he's getting sloppier with each batch. Now's he's telling us he can speed the time on the IFF encoding. I already have a hard enough time getting these damn things not to stare at walls and now he's gonna shortchange the only part of these tincans that tells em not to turn us into paste on a wall. I told Richter to get out while he can, We're counting days before either some Sif task force shows up at our door or these things decide we aren't there friends anymore."; - name = "Note" - }, -/obj/effect/floor_decal/corner/red/border{ - icon_state = "bordercolor"; - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"be" = ( -/obj/structure/bed/chair{ - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bf" = ( -/mob/living/simple_animal/hostile/viscerator{ - returns_home = 1 - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bg" = ( -/obj/machinery/vending/security, -/obj/effect/floor_decal/corner/red/border{ - icon_state = "bordercolor"; - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bh" = ( -/obj/structure/table/rack, -/obj/item/weapon/storage/box/shotgunshells, -/obj/item/weapon/storage/box/shotgunshells, -/obj/item/weapon/cell/device/weapon, -/turf/simulated/floor/tiled/techfloor, -/area/submap/Rockybase) -"bi" = ( -/obj/effect/floor_decal/corner/lime/border{ - icon_state = "bordercolor"; - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bj" = ( -/obj/structure/sink{ - dir = 4; - icon_state = "sink"; - pixel_x = 11; - pixel_y = 0 - }, -/obj/effect/floor_decal/corner/lime/border{ - icon_state = "bordercolor"; - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bk" = ( -/obj/machinery/shower{ - dir = 8; - icon_state = "shower"; - pixel_x = -5; - pixel_y = 0 - }, -/obj/structure/curtain/open/shower, -/obj/machinery/light/small{ - dir = 4; - pixel_y = 0 - }, -/turf/simulated/floor/tiled/hydro, -/area/submap/Rockybase) -"bl" = ( -/obj/item/mecha_parts/part/gygax_left_leg, -/turf/simulated/floor/holofloor/lino, -/area/submap/Rockybase) -"bm" = ( -/obj/machinery/light, -/turf/simulated/floor/holofloor/lino, -/area/submap/Rockybase) -"bn" = ( -/obj/structure/bed, -/obj/item/weapon/bedsheet, -/obj/item/weapon/gun/projectile/pistol, -/turf/simulated/floor/holofloor/lino, -/area/submap/Rockybase) -"bo" = ( -/obj/structure/closet/crate/trashcart, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bp" = ( -/obj/structure/loot_pile/maint/trash, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bq" = ( -/obj/structure/table/standard, -/obj/item/weapon/storage/bag/trash, -/obj/item/weapon/storage/bag/trash, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"br" = ( -/obj/structure/table/standard, -/obj/item/weapon/paper_bin, -/obj/effect/floor_decal/corner/red/border{ - icon_state = "bordercolor"; - dir = 10 - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bs" = ( -/obj/machinery/light, -/obj/structure/table/standard, -/obj/item/weapon/pen, -/obj/effect/floor_decal/corner/red/border, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bt" = ( -/obj/effect/floor_decal/corner/red/border, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bu" = ( -/obj/effect/floor_decal/corner/red/border, -/mob/living/simple_animal/hostile/viscerator{ - returns_home = 1 - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bv" = ( -/obj/machinery/door/airlock/security{ - icon_state = "door_locked"; - locked = 1 - }, -/turf/simulated/floor/tiled/techfloor, -/area/submap/Rockybase) -"bw" = ( -/obj/machinery/light, -/turf/simulated/floor/tiled/techfloor, -/area/submap/Rockybase) -"bx" = ( -/obj/structure/table/rack, -/obj/item/weapon/gun/energy/ionrifle/pistol, -/turf/simulated/floor/tiled/techfloor, -/area/submap/Rockybase) -"by" = ( -/obj/machinery/portable_atmospherics/hydroponics, -/obj/effect/floor_decal/corner/lime/border{ - icon_state = "bordercolor"; - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bz" = ( -/obj/machinery/door/airlock, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bA" = ( -/obj/effect/floor_decal/corner/lime/border{ - icon_state = "bordercolor"; - dir = 8 - }, -/mob/living/bot/farmbot{ - faction = "malf_drone"; - name = "Mr. Weddleton" - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bB" = ( -/obj/machinery/portable_atmospherics/hydroponics, -/obj/machinery/light{ - icon_state = "tube1"; - dir = 4 - }, -/obj/effect/floor_decal/corner/lime/border{ - icon_state = "bordercolor"; - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bC" = ( -/obj/effect/decal/remains/posi, -/turf/template_noop, -/area/template_noop) -"bD" = ( -/obj/machinery/vending/cola, -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bE" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bF" = ( -/obj/machinery/light{ - dir = 1 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bG" = ( -/obj/structure/door_assembly, -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bH" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bI" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/cobweb2, -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bJ" = ( -/obj/effect/decal/mecha_wreckage/hoverpod, -/turf/template_noop, -/area/template_noop) -"bK" = ( -/mob/living/simple_animal/hostile/malf_drone/lesser, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bL" = ( -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bM" = ( -/obj/effect/decal/cleanable/blood, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bN" = ( -/obj/effect/decal/remains, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bO" = ( -/obj/machinery/door/airlock, -/turf/simulated/floor/tiled/hydro, -/area/submap/Rockybase) -"bP" = ( -/obj/machinery/vending/snack, -/obj/effect/floor_decal/borderfloor, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bQ" = ( -/obj/effect/floor_decal/borderfloor, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bR" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/floor_decal/borderfloor, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bS" = ( -/obj/item/stack/rods, -/obj/structure/girder, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bT" = ( -/obj/effect/decal/remains, -/obj/effect/floor_decal/borderfloor, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bU" = ( -/obj/machinery/light, -/obj/effect/floor_decal/borderfloor, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bV" = ( -/obj/effect/decal/cleanable/blood, -/obj/effect/floor_decal/borderfloor, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bW" = ( -/obj/item/mecha_parts/part/gygax_right_arm, -/obj/effect/floor_decal/borderfloor, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"bX" = ( -/obj/machinery/light/small{ - dir = 8 - }, -/turf/simulated/floor/tiled/hydro, -/area/submap/Rockybase) -"bY" = ( -/mob/living/simple_animal/hostile/viscerator{ - returns_home = 1 - }, -/turf/simulated/floor/tiled/hydro, -/area/submap/Rockybase) -"bZ" = ( -/obj/machinery/door/airlock/engineering, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"ca" = ( -/obj/effect/floor_decal/rust, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"cb" = ( -/turf/simulated/wall, -/area/submap/Rockybase) -"cc" = ( -/obj/structure/table/standard, -/obj/item/device/kit/paint/gygax/darkgygax, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"cd" = ( -/obj/structure/table/standard, -/obj/item/weapon/paper{ - info = "I've decided to go forward and start some small scale tests of the Vicerator delivery grenades, Might as wall make sure they work like the real ones. There are a few Fauna areas nearbye and we're working to make sure the kinks in the code are worked out. Once we've made sure they stay flying we'll work on the IFF signals."; - name = "V-Grenade Notice 2" - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"ce" = ( -/obj/structure/table/standard, -/obj/random/toolbox, -/obj/machinery/light{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"cf" = ( -/obj/structure/table/standard, -/obj/random/toolbox, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"cg" = ( -/obj/structure/table/standard, -/obj/item/weapon/paper{ - info = "We've finally been able to get the Vicerator delivery grenades working, Took awhile to make sure the latching mechanism didn't fail but we're sure we've got it this time. Vel'Shem's worried about the miners having there own drone fab now but I say it's a small price to pay to keep the metal flowing, Especially since there telling us NT's starting to monopolize the metal rich parts."; - name = "V-Grenade Notice 1" - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"ch" = ( -/obj/structure/table/standard, -/obj/item/stack/material/diamond, -/obj/item/stack/material/diamond, -/obj/item/stack/material/diamond, -/obj/item/stack/material/diamond, -/obj/item/stack/material/diamond, -/obj/item/stack/material/diamond, -/obj/item/stack/material/diamond, -/obj/item/stack/material/diamond, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"ci" = ( -/obj/structure/table/standard, -/obj/item/weapon/grenade/spawnergrenade/manhacks, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"cj" = ( -/obj/structure/table/standard, -/obj/item/stack/material/steel, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"ck" = ( -/obj/structure/table/standard, -/obj/machinery/light{ - dir = 1 - }, -/obj/item/weapon/circuitboard/mecha/gygax/main, -/obj/item/weapon/circuitboard/mecha/gygax/peripherals, -/obj/item/weapon/circuitboard/mecha/gygax/targeting, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"cl" = ( -/obj/structure/door_assembly, -/obj/effect/floor_decal/rust, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"cm" = ( -/obj/item/weapon/material/shard, -/turf/simulated/floor, -/area/submap/Rockybase) -"cn" = ( -/obj/structure/table/standard, -/obj/fiftyspawner/rods, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"co" = ( -/obj/machinery/vending/engivend, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"cp" = ( -/obj/machinery/vending/tool, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"cq" = ( -/obj/structure/table/standard, -/obj/item/weapon/storage/toolbox, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"cr" = ( -/obj/structure/table/standard, -/obj/item/weapon/storage/toolbox/mechanical, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"cs" = ( -/obj/item/mecha_parts/part/gygax_torso, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"ct" = ( -/obj/machinery/light{ - dir = 1 - }, -/obj/structure/closet/crate/medical, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"cu" = ( -/obj/structure/table/standard, -/obj/structure/table/standard, -/obj/effect/decal/cleanable/dirt, -/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/burn, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"cv" = ( -/obj/structure/table/standard, -/obj/item/clothing/mask/breath/medical, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"cw" = ( -/obj/structure/closet/secure_closet/medical2, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"cx" = ( -/obj/structure/toilet{ - dir = 4 - }, -/obj/machinery/light/small{ - dir = 8 - }, -/turf/simulated/floor/tiled/hydro, -/area/submap/Rockybase) -"cy" = ( -/obj/structure/sink{ - dir = 4; - icon_state = "sink"; - pixel_x = 11; - pixel_y = 0 - }, -/turf/simulated/floor/tiled/hydro, -/area/submap/Rockybase) -"cz" = ( -/obj/structure/table/standard, -/obj/item/device/mmi/digital/robot, -/obj/item/weapon/stock_parts/capacitor/adv, -/obj/item/weapon/stock_parts/scanning_module/adv, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"cA" = ( -/obj/structure/cable{ - d1 = 2; - d2 = 4; - icon_state = "2-4" - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"cB" = ( -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8"; - pixel_x = 0 - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"cC" = ( -/obj/structure/cable{ - d2 = 8; - icon_state = "0-8" - }, -/obj/machinery/power/port_gen/pacman, -/turf/simulated/floor, -/area/submap/Rockybase) -"cD" = ( -/obj/structure/door_assembly, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"cE" = ( -/obj/item/stack/rods, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"cF" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/girder, -/turf/simulated/floor, -/area/submap/Rockybase) -"cG" = ( -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor, -/area/submap/Rockybase) -"cH" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/table, -/turf/simulated/floor, -/area/submap/Rockybase) -"cI" = ( -/obj/structure/girder, -/turf/simulated/floor, -/area/submap/Rockybase) -"cJ" = ( -/obj/structure/closet/secure_closet/medical1, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"cK" = ( -/obj/machinery/light/small{ - dir = 4; - pixel_y = 0 - }, -/turf/simulated/floor/tiled/hydro, -/area/submap/Rockybase) -"cL" = ( -/obj/machinery/drone_fabricator{ - fabricator_tag = "Unknown" - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"cN" = ( -/obj/machinery/mecha_part_fabricator, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"cO" = ( -/obj/machinery/pros_fabricator, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"cP" = ( -/obj/structure/table/standard, -/obj/item/mecha_parts/mecha_equipment/repair_droid, -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/explosive, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"cQ" = ( -/obj/machinery/light{ - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"cR" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2"; - pixel_y = 0 - }, -/obj/structure/cable{ - d1 = 1; - d2 = 4; - icon_state = "1-4" - }, -/mob/living/simple_animal/hostile/malf_drone/lesser, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"cS" = ( -/obj/machinery/power/terminal{ - dir = 4 - }, -/obj/structure/cable{ - d2 = 8; - icon_state = "0-8" - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"cT" = ( -/obj/machinery/power/smes/buildable/point_of_interest, -/obj/structure/cable/green{ - d2 = 2; - icon_state = "0-2" - }, -/turf/simulated/floor, -/area/submap/Rockybase) -"cU" = ( -/obj/machinery/vending/medical, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"cV" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"cW" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor, -/area/submap/Rockybase) -"cX" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/item/weapon/material/shard, -/turf/simulated/floor, -/area/submap/Rockybase) -"cY" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor, -/area/submap/Rockybase) -"cZ" = ( -/obj/item/mecha_parts/part/gygax_armour, -/turf/simulated/floor, -/area/submap/Rockybase) -"da" = ( -/obj/item/mecha_parts/chassis/gygax, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"db" = ( -/mob/living/simple_animal/hostile/mecha/malf_drone{ - name = "Autonomous Mechanized Drone" - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"dc" = ( -/obj/effect/floor_decal/industrial/hatch/yellow, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"dd" = ( -/obj/machinery/vending/robotics, -/obj/machinery/light{ - icon_state = "tube1"; - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"de" = ( -/obj/machinery/power/apc{ - cell_type = /obj/item/weapon/cell/super; - dir = 8; - name = "Unknown APC"; - pixel_x = -24 - }, -/obj/structure/cable/green{ - d2 = 4; - icon_state = "0-4" - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"df" = ( -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"dg" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2"; - pixel_y = 0 - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"dh" = ( -/obj/machinery/light{ - icon_state = "tube1"; - dir = 4 - }, -/obj/structure/cable/green{ - d1 = 1; - d2 = 8; - icon_state = "1-8" - }, -/obj/structure/cable/green{ - d1 = 2; - d2 = 8; - icon_state = "2-8" - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"di" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/blood, -/turf/simulated/floor, -/area/submap/Rockybase) -"dj" = ( -/obj/item/mecha_parts/part/gygax_right_leg, -/obj/effect/floor_decal/corner/lime/border{ - icon_state = "bordercolor"; - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"dk" = ( -/obj/structure/sink{ - dir = 4; - icon_state = "sink"; - pixel_x = 11; - pixel_y = 0 - }, -/obj/item/mecha_parts/part/gygax_left_arm, -/turf/simulated/floor/tiled/hydro, -/area/submap/Rockybase) -"dl" = ( -/obj/machinery/vending, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"dm" = ( -/obj/structure/cable{ - d1 = 1; - d2 = 4; - icon_state = "1-4" - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"dn" = ( -/obj/machinery/power/smes/buildable/point_of_interest, -/obj/structure/cable/green, -/turf/simulated/floor, -/area/submap/Rockybase) -"do" = ( -/obj/machinery/light{ - dir = 8 - }, -/obj/structure/closet/secure_closet/medical3, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"dp" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/mob/living/simple_animal/hostile/malf_drone/lesser, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"dq" = ( -/obj/structure/closet/secure_closet/hydroponics, -/obj/effect/floor_decal/corner/lime/border{ - icon_state = "bordercolor"; - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"dr" = ( -/obj/effect/decal/cleanable/blood/oil, -/turf/template_noop, -/area/template_noop) -"ds" = ( -/obj/machinery/light, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"dt" = ( -/obj/machinery/mech_recharger, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"du" = ( -/obj/structure/table/standard, -/obj/item/stack/material/plasteel, -/obj/item/stack/material/glass/reinforced, -/obj/item/stack/material/phoron{ - amount = 25 - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"dv" = ( -/obj/structure/table/standard, -/obj/item/stack/material/glass, -/obj/item/stack/material/steel, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"dw" = ( -/obj/structure/table/standard, -/obj/item/mecha_parts/part/gygax_head, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"dx" = ( -/obj/structure/closet/toolcloset, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"dy" = ( -/obj/structure/closet/secure_closet/medical3, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"dz" = ( -/obj/item/weapon/surgical/surgicaldrill, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"dA" = ( -/obj/structure/loot_pile/maint/technical, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"dB" = ( -/obj/effect/decal/cleanable/dirt, -/mob/living/bot/medbot{ - faction = "malf_drone" - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"dC" = ( -/obj/machinery/vending/hydroseeds, -/obj/effect/floor_decal/corner/lime/border{ - icon_state = "bordercolor"; - dir = 10 - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"dD" = ( -/obj/structure/closet/crate/secure/hydrosec, -/obj/effect/floor_decal/corner/lime/border{ - icon_state = "bordercolor"; - dir = 6 - }, -/turf/simulated/floor/tiled, -/area/submap/Rockybase) -"dE" = ( -/obj/machinery/portable_atmospherics/hydroponics/soil, -/obj/structure/gravemarker{ - dir = 1 - }, -/turf/template_noop, -/area/template_noop) -"dF" = ( -/obj/effect/gibspawner/robot, -/turf/template_noop, -/area/template_noop) -"dG" = ( -/obj/effect/gibspawner/human, -/turf/template_noop, -/area/template_noop) +"aa" = (/turf/template_noop,/area/template_noop) +"ab" = (/obj/effect/decal/remains,/turf/template_noop,/area/template_noop) +"ac" = (/obj/item/weapon/grenade/chem_grenade/metalfoam,/turf/template_noop,/area/template_noop) +"ad" = (/mob/living/simple_mob/mechanical/viscerator,/turf/template_noop,/area/template_noop) +"ae" = (/obj/effect/decal/remains,/turf/template_noop,/area/submap/Rockybase) +"af" = (/turf/template_noop,/area/submap/Rockybase) +"ag" = (/obj/structure/flora/tree/sif,/turf/template_noop,/area/submap/Rockybase) +"ah" = (/obj/effect/gibspawner/robot,/turf/template_noop,/area/submap/Rockybase) +"ai" = (/turf/simulated/mineral/ignore_mapgen,/area/submap/Rockybase) +"aj" = (/obj/effect/decal/remains/robot,/turf/template_noop,/area/template_noop) +"ak" = (/mob/living/simple_mob/mechanical/combat_drone/lesser,/turf/template_noop,/area/submap/Rockybase) +"al" = (/turf/simulated/floor,/area/submap/Rockybase) +"am" = (/obj/effect/decal/remains/posi,/turf/simulated/floor,/area/submap/Rockybase) +"an" = (/obj/machinery/porta_turret/poi,/turf/simulated/floor,/area/submap/Rockybase) +"ao" = (/obj/effect/decal/cleanable/blood,/turf/simulated/floor,/area/submap/Rockybase) +"ap" = (/obj/structure/flora/tree/sif,/turf/template_noop,/area/template_noop) +"aq" = (/obj/effect/floor_decal/industrial/danger,/turf/simulated/floor,/area/submap/Rockybase) +"ar" = (/obj/machinery/light,/obj/effect/floor_decal/industrial/danger,/turf/simulated/floor,/area/submap/Rockybase) +"as" = (/obj/effect/decal/cleanable/blood,/obj/effect/floor_decal/industrial/danger,/turf/simulated/floor,/area/submap/Rockybase) +"at" = (/turf/simulated/wall/r_wall,/area/submap/Rockybase) +"au" = (/obj/structure/sign/securearea,/turf/simulated/wall/r_wall,/area/submap/Rockybase) +"av" = (/obj/machinery/door/airlock/external,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"aw" = (/obj/effect/decal/remains/deer,/turf/template_noop,/area/template_noop) +"ax" = (/obj/machinery/shower{dir = 4; icon_state = "shower"; pixel_x = 5; pixel_y = 0},/obj/structure/curtain/open/shower,/obj/machinery/light/small{dir = 8},/turf/simulated/floor/tiled/hydro,/area/submap/Rockybase) +"ay" = (/turf/simulated/floor/tiled/hydro,/area/submap/Rockybase) +"az" = (/obj/machinery/shower{dir = 8; icon_state = "shower"; pixel_x = -5; pixel_y = 0},/obj/structure/curtain/open/shower,/obj/item/weapon/soap,/turf/simulated/floor/tiled/hydro,/area/submap/Rockybase) +"aA" = (/obj/structure/table/woodentable,/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/holofloor/lino,/area/submap/Rockybase) +"aB" = (/obj/structure/table/woodentable,/turf/simulated/floor/holofloor/lino,/area/submap/Rockybase) +"aC" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp,/turf/simulated/floor/holofloor/lino,/area/submap/Rockybase) +"aD" = (/obj/structure/closet{icon_closed = "cabinet_closed"; icon_opened = "cabinet_open"; icon_state = "cabinet_closed"},/obj/item/weapon/pickaxe/plasmacutter,/turf/simulated/floor/holofloor/lino,/area/submap/Rockybase) +"aE" = (/turf/simulated/floor/holofloor/lino,/area/submap/Rockybase) +"aF" = (/obj/structure/bed,/obj/item/weapon/bedsheet,/turf/simulated/floor/holofloor/lino,/area/submap/Rockybase) +"aG" = (/obj/structure/table/woodentable,/obj/machinery/light{dir = 1},/turf/simulated/floor/holofloor/lino,/area/submap/Rockybase) +"aH" = (/obj/structure/bed,/obj/item/weapon/bedsheet,/mob/living/simple_mob/mechanical/viscerator,/turf/simulated/floor/holofloor/lino,/area/submap/Rockybase) +"aI" = (/obj/structure/bed,/obj/item/weapon/bedsheet,/obj/item/toy/plushie/spider,/turf/simulated/floor/holofloor/lino,/area/submap/Rockybase) +"aJ" = (/obj/structure/closet/l3closet/janitor,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"aK" = (/mob/living/bot/cleanbot{faction = "malf_drone"},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"aL" = (/obj/item/weapon/stool,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"aM" = (/obj/item/weapon/storage/belt/janitor,/obj/structure/table/standard,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"aN" = (/turf/simulated/floor/tiled,/area/submap/Rockybase) +"aO" = (/obj/structure/table/standard,/obj/item/device/laptop,/obj/effect/floor_decal/corner/red/border{icon_state = "bordercolor"; dir = 9},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"aP" = (/obj/structure/table/standard,/obj/effect/floor_decal/corner/red/border{icon_state = "bordercolor"; dir = 1},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"aQ" = (/obj/structure/table/rack,/obj/item/weapon/gun/projectile/pistol,/obj/effect/floor_decal/corner/red/border{icon_state = "bordercolor"; dir = 1},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"aR" = (/obj/structure/table/rack,/obj/item/weapon/gun/energy/gun/taser,/obj/effect/floor_decal/corner/red/border{icon_state = "bordercolor"; dir = 1},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"aS" = (/obj/machinery/light{dir = 1},/obj/effect/floor_decal/corner/red/border{icon_state = "bordercolor"; dir = 1},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"aT" = (/obj/machinery/vending/coffee,/obj/effect/floor_decal/corner/red/border{icon_state = "bordercolor"; dir = 5},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"aU" = (/turf/simulated/floor/tiled/techfloor,/area/submap/Rockybase) +"aV" = (/obj/structure/table/rack,/obj/item/weapon/gun/projectile/shotgun/pump/combat,/obj/item/weapon/gun/projectile/shotgun/pump/combat,/turf/simulated/floor/tiled/techfloor,/area/submap/Rockybase) +"aW" = (/obj/machinery/vending/hydronutrients,/obj/effect/floor_decal/corner/lime/border{icon_state = "bordercolor"; dir = 9},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"aX" = (/obj/structure/closet/crate/hydroponics,/obj/effect/floor_decal/corner/lime/border{icon_state = "bordercolor"; dir = 5},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"aY" = (/obj/machinery/shower{dir = 4; icon_state = "shower"; pixel_x = 5; pixel_y = 0},/obj/structure/curtain/open/shower,/turf/simulated/floor/tiled/hydro,/area/submap/Rockybase) +"aZ" = (/obj/machinery/shower{dir = 8; icon_state = "shower"; pixel_x = -5; pixel_y = 0},/obj/structure/curtain/open/shower,/turf/simulated/floor/tiled/hydro,/area/submap/Rockybase) +"ba" = (/obj/structure/janitorialcart,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bb" = (/obj/structure/table/standard,/obj/item/weapon/grenade/chem_grenade/cleaner,/obj/item/weapon/grenade/chem_grenade/cleaner,/obj/item/weapon/grenade/chem_grenade/cleaner,/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bc" = (/obj/machinery/light/small{dir = 8},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bd" = (/obj/structure/table/standard,/obj/item/weapon/paper{info = "Carl's absolutly fucked in the head. He's trying to squeeze as much drone production out as he can since he's worried we're gonna get found out but he's getting sloppier with each batch. Now's he's telling us he can speed the time on the IFF encoding. I already have a hard enough time getting these damn things not to stare at walls and now he's gonna shortchange the only part of these tincans that tells em not to turn us into paste on a wall. I told Richter to get out while he can, We're counting days before either some Sif task force shows up at our door or these things decide we aren't there friends anymore."; name = "Note"},/obj/effect/floor_decal/corner/red/border{icon_state = "bordercolor"; dir = 8},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"be" = (/obj/structure/bed/chair{dir = 8},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bf" = (/mob/living/simple_mob/mechanical/viscerator,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bg" = (/obj/machinery/vending/security,/obj/effect/floor_decal/corner/red/border{icon_state = "bordercolor"; dir = 4},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bh" = (/obj/structure/table/rack,/obj/item/weapon/storage/box/shotgunshells,/obj/item/weapon/storage/box/shotgunshells,/obj/item/weapon/cell/device/weapon,/turf/simulated/floor/tiled/techfloor,/area/submap/Rockybase) +"bi" = (/obj/effect/floor_decal/corner/lime/border{icon_state = "bordercolor"; dir = 8},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bj" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/obj/effect/floor_decal/corner/lime/border{icon_state = "bordercolor"; dir = 4},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bk" = (/obj/machinery/shower{dir = 8; icon_state = "shower"; pixel_x = -5; pixel_y = 0},/obj/structure/curtain/open/shower,/obj/machinery/light/small{dir = 4; pixel_y = 0},/turf/simulated/floor/tiled/hydro,/area/submap/Rockybase) +"bl" = (/obj/item/mecha_parts/part/gygax_left_leg,/turf/simulated/floor/holofloor/lino,/area/submap/Rockybase) +"bm" = (/obj/machinery/light,/turf/simulated/floor/holofloor/lino,/area/submap/Rockybase) +"bn" = (/obj/structure/bed,/obj/item/weapon/bedsheet,/obj/item/weapon/gun/projectile/pistol,/turf/simulated/floor/holofloor/lino,/area/submap/Rockybase) +"bo" = (/obj/structure/closet/crate/trashcart,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bp" = (/obj/structure/loot_pile/maint/trash,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bq" = (/obj/structure/table/standard,/obj/item/weapon/storage/bag/trash,/obj/item/weapon/storage/bag/trash,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"br" = (/obj/structure/table/standard,/obj/item/weapon/paper_bin,/obj/effect/floor_decal/corner/red/border{icon_state = "bordercolor"; dir = 10},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bs" = (/obj/machinery/light,/obj/structure/table/standard,/obj/item/weapon/pen,/obj/effect/floor_decal/corner/red/border,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bt" = (/obj/effect/floor_decal/corner/red/border,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bu" = (/obj/effect/floor_decal/corner/red/border,/mob/living/simple_mob/mechanical/viscerator,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bv" = (/obj/machinery/door/airlock/security{icon_state = "door_locked"; locked = 1},/turf/simulated/floor/tiled/techfloor,/area/submap/Rockybase) +"bw" = (/obj/machinery/light,/turf/simulated/floor/tiled/techfloor,/area/submap/Rockybase) +"bx" = (/obj/structure/table/rack,/obj/item/weapon/gun/energy/ionrifle/pistol,/turf/simulated/floor/tiled/techfloor,/area/submap/Rockybase) +"by" = (/obj/machinery/portable_atmospherics/hydroponics,/obj/effect/floor_decal/corner/lime/border{icon_state = "bordercolor"; dir = 4},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bz" = (/obj/machinery/door/airlock,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bA" = (/obj/effect/floor_decal/corner/lime/border{icon_state = "bordercolor"; dir = 8},/mob/living/bot/farmbot{faction = "malf_drone"; name = "Mr. Weddleton"},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bB" = (/obj/machinery/portable_atmospherics/hydroponics,/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/effect/floor_decal/corner/lime/border{icon_state = "bordercolor"; dir = 4},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bC" = (/obj/effect/decal/remains/posi,/turf/template_noop,/area/template_noop) +"bD" = (/obj/machinery/vending/cola,/obj/effect/floor_decal/borderfloor{dir = 1},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bE" = (/obj/effect/floor_decal/borderfloor{dir = 1},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bF" = (/obj/machinery/light{dir = 1},/obj/effect/floor_decal/borderfloor{dir = 1},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bG" = (/obj/structure/door_assembly,/obj/effect/floor_decal/borderfloor{dir = 1},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bH" = (/obj/effect/decal/cleanable/dirt,/obj/effect/floor_decal/borderfloor{dir = 1},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bI" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/cobweb2,/obj/effect/floor_decal/borderfloor{dir = 1},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bJ" = (/obj/effect/decal/mecha_wreckage/hoverpod,/turf/template_noop,/area/template_noop) +"bK" = (/mob/living/simple_mob/mechanical/combat_drone/lesser,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bL" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bM" = (/obj/effect/decal/cleanable/blood,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bN" = (/obj/effect/decal/remains,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bO" = (/obj/machinery/door/airlock,/turf/simulated/floor/tiled/hydro,/area/submap/Rockybase) +"bP" = (/obj/machinery/vending/snack,/obj/effect/floor_decal/borderfloor,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bQ" = (/obj/effect/floor_decal/borderfloor,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bR" = (/obj/effect/decal/cleanable/dirt,/obj/effect/floor_decal/borderfloor,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bS" = (/obj/item/stack/rods,/obj/structure/girder,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bT" = (/obj/effect/decal/remains,/obj/effect/floor_decal/borderfloor,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bU" = (/obj/machinery/light,/obj/effect/floor_decal/borderfloor,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bV" = (/obj/effect/decal/cleanable/blood,/obj/effect/floor_decal/borderfloor,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bW" = (/obj/item/mecha_parts/part/gygax_right_arm,/obj/effect/floor_decal/borderfloor,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"bX" = (/obj/machinery/light/small{dir = 8},/turf/simulated/floor/tiled/hydro,/area/submap/Rockybase) +"bY" = (/mob/living/simple_mob/mechanical/viscerator,/turf/simulated/floor/tiled/hydro,/area/submap/Rockybase) +"bZ" = (/obj/machinery/door/airlock/engineering,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"ca" = (/obj/effect/floor_decal/rust,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cb" = (/turf/simulated/wall,/area/submap/Rockybase) +"cc" = (/obj/structure/table/standard,/obj/item/device/kit/paint/gygax/darkgygax,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cd" = (/obj/structure/table/standard,/obj/item/weapon/paper{info = "I've decided to go forward and start some small scale tests of the Vicerator delivery grenades, Might as wall make sure they work like the real ones. There are a few Fauna areas nearbye and we're working to make sure the kinks in the code are worked out. Once we've made sure they stay flying we'll work on the IFF signals."; name = "V-Grenade Notice 2"},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"ce" = (/obj/structure/table/standard,/obj/random/toolbox,/obj/machinery/light{dir = 1},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cf" = (/obj/structure/table/standard,/obj/random/toolbox,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cg" = (/obj/structure/table/standard,/obj/item/weapon/paper{info = "We've finally been able to get the Vicerator delivery grenades working, Took awhile to make sure the latching mechanism didn't fail but we're sure we've got it this time. Vel'Shem's worried about the miners having there own drone fab now but I say it's a small price to pay to keep the metal flowing, Especially since there telling us NT's starting to monopolize the metal rich parts."; name = "V-Grenade Notice 1"},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"ch" = (/obj/structure/table/standard,/obj/item/stack/material/diamond,/obj/item/stack/material/diamond,/obj/item/stack/material/diamond,/obj/item/stack/material/diamond,/obj/item/stack/material/diamond,/obj/item/stack/material/diamond,/obj/item/stack/material/diamond,/obj/item/stack/material/diamond,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"ci" = (/obj/structure/table/standard,/obj/item/weapon/grenade/spawnergrenade/manhacks,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cj" = (/obj/structure/table/standard,/obj/item/stack/material/steel,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"ck" = (/obj/structure/table/standard,/obj/machinery/light{dir = 1},/obj/item/weapon/circuitboard/mecha/gygax/main,/obj/item/weapon/circuitboard/mecha/gygax/peripherals,/obj/item/weapon/circuitboard/mecha/gygax/targeting,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cl" = (/obj/structure/door_assembly,/obj/effect/floor_decal/rust,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cm" = (/obj/item/weapon/material/shard,/turf/simulated/floor,/area/submap/Rockybase) +"cn" = (/obj/structure/table/standard,/obj/fiftyspawner/rods,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"co" = (/obj/machinery/vending/engivend,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cp" = (/obj/machinery/vending/tool,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cq" = (/obj/structure/table/standard,/obj/item/weapon/storage/toolbox,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cr" = (/obj/structure/table/standard,/obj/item/weapon/storage/toolbox/mechanical,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cs" = (/obj/item/mecha_parts/part/gygax_torso,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"ct" = (/obj/machinery/light{dir = 1},/obj/structure/closet/crate/medical,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cu" = (/obj/structure/table/standard,/obj/structure/table/standard,/obj/effect/decal/cleanable/dirt,/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/burn,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cv" = (/obj/structure/table/standard,/obj/item/clothing/mask/breath/medical,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cw" = (/obj/structure/closet/secure_closet/medical2,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cx" = (/obj/structure/toilet{dir = 4},/obj/machinery/light/small{dir = 8},/turf/simulated/floor/tiled/hydro,/area/submap/Rockybase) +"cy" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/turf/simulated/floor/tiled/hydro,/area/submap/Rockybase) +"cz" = (/obj/structure/table/standard,/obj/item/device/mmi/digital/robot,/obj/item/weapon/stock_parts/capacitor/adv,/obj/item/weapon/stock_parts/scanning_module/adv,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cA" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cB" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cC" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/power/port_gen/pacman,/turf/simulated/floor,/area/submap/Rockybase) +"cD" = (/obj/structure/door_assembly,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cE" = (/obj/item/stack/rods,/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cF" = (/obj/effect/decal/cleanable/dirt,/obj/structure/girder,/turf/simulated/floor,/area/submap/Rockybase) +"cG" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor,/area/submap/Rockybase) +"cH" = (/obj/effect/decal/cleanable/dirt,/obj/structure/table,/turf/simulated/floor,/area/submap/Rockybase) +"cI" = (/obj/structure/girder,/turf/simulated/floor,/area/submap/Rockybase) +"cJ" = (/obj/structure/closet/secure_closet/medical1,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cK" = (/obj/machinery/light/small{dir = 4; pixel_y = 0},/turf/simulated/floor/tiled/hydro,/area/submap/Rockybase) +"cL" = (/mob/living/simple_mob/mechanical/mecha/combat/gygax/dark/advanced{faction = "malf_drone"},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cM" = (/obj/machinery/drone_fabricator{fabricator_tag = "Unknown"},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cN" = (/obj/machinery/mecha_part_fabricator,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cO" = (/obj/machinery/pros_fabricator,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cP" = (/obj/structure/table/standard,/obj/item/mecha_parts/mecha_equipment/repair_droid,/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/explosive,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cQ" = (/obj/machinery/light{dir = 8},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cR" = (/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/mob/living/simple_mob/mechanical/combat_drone/lesser,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cS" = (/obj/machinery/power/terminal{dir = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cT" = (/obj/machinery/power/smes/buildable/point_of_interest,/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor,/area/submap/Rockybase) +"cU" = (/obj/machinery/vending/medical,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cV" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"cW" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor,/area/submap/Rockybase) +"cX" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/obj/item/weapon/material/shard,/turf/simulated/floor,/area/submap/Rockybase) +"cY" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor,/area/submap/Rockybase) +"cZ" = (/obj/item/mecha_parts/part/gygax_armour,/turf/simulated/floor,/area/submap/Rockybase) +"da" = (/obj/item/mecha_parts/chassis/gygax,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dc" = (/obj/effect/floor_decal/industrial/hatch/yellow,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dd" = (/obj/machinery/vending/robotics,/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"de" = (/obj/machinery/power/apc{cell_type = /obj/item/weapon/cell/super; dir = 8; name = "Unknown APC"; pixel_x = -24},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"df" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dg" = (/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dh" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"di" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/blood,/turf/simulated/floor,/area/submap/Rockybase) +"dj" = (/obj/item/mecha_parts/part/gygax_right_leg,/obj/effect/floor_decal/corner/lime/border{icon_state = "bordercolor"; dir = 4},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dk" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/obj/item/mecha_parts/part/gygax_left_arm,/turf/simulated/floor/tiled/hydro,/area/submap/Rockybase) +"dl" = (/obj/machinery/vending,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dm" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dn" = (/obj/machinery/power/smes/buildable/point_of_interest,/obj/structure/cable/green,/turf/simulated/floor,/area/submap/Rockybase) +"do" = (/obj/machinery/light{dir = 8},/obj/structure/closet/secure_closet/medical3,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dp" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/mob/living/simple_mob/mechanical/combat_drone/lesser,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dq" = (/obj/structure/closet/secure_closet/hydroponics,/obj/effect/floor_decal/corner/lime/border{icon_state = "bordercolor"; dir = 4},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dr" = (/obj/effect/decal/cleanable/blood/oil,/turf/template_noop,/area/template_noop) +"ds" = (/obj/machinery/light,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dt" = (/obj/machinery/mech_recharger,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"du" = (/obj/structure/table/standard,/obj/item/stack/material/plasteel,/obj/item/stack/material/glass/reinforced,/obj/item/stack/material/phoron{amount = 25},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dv" = (/obj/structure/table/standard,/obj/item/stack/material/glass,/obj/item/stack/material/steel,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dw" = (/obj/structure/table/standard,/obj/item/mecha_parts/part/gygax_head,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dx" = (/obj/structure/closet/toolcloset,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dy" = (/obj/structure/closet/secure_closet/medical3,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dz" = (/obj/item/weapon/surgical/surgicaldrill,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dA" = (/obj/structure/loot_pile/maint/technical,/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dB" = (/obj/effect/decal/cleanable/dirt,/mob/living/bot/medbot{faction = "malf_drone"},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dC" = (/obj/machinery/vending/hydroseeds,/obj/effect/floor_decal/corner/lime/border{icon_state = "bordercolor"; dir = 10},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dD" = (/obj/structure/closet/crate/secure/hydrosec,/obj/effect/floor_decal/corner/lime/border{icon_state = "bordercolor"; dir = 6},/turf/simulated/floor/tiled,/area/submap/Rockybase) +"dE" = (/obj/machinery/portable_atmospherics/hydroponics/soil,/obj/structure/gravemarker{dir = 1},/turf/template_noop,/area/template_noop) +"dF" = (/obj/effect/gibspawner/robot,/turf/template_noop,/area/template_noop) +"dG" = (/obj/effect/gibspawner/human,/turf/template_noop,/area/template_noop) (1,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -ab -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -"} -(2,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -"} -(3,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -ab -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -"} -(4,1,1) = {" -aa -aa -aa -ad -aa -aa -aa -aa -aa -aa -aa -ap -aa -aa -aa -aa -ab -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -ad -aa -dF -aa -"} -(5,1,1) = {" -aa -aa -aa -aa -ae -af -af -af -af -af -af -af -af -af -ai -ai -ai -ai -ai -af -af -af -af -af -af -af -af -af -af -af -af -af -aa -aa -aa -aa -"} -(6,1,1) = {" -aa -aa -aa -aa -af -af -af -af -af -af -ai -ai -ai -ai -ai -ai -ai -ai -ai -ai -ai -ai -ai -ai -ai -ai -ai -ai -ai -ai -af -ag -ab -aa -aa -aa -"} -(7,1,1) = {" -aa -aa -aa -aa -af -af -af -af -ai -ai -ai -ai -ai -at -at -at -at -at -at -at -at -at -at -at -at -at -at -ai -ai -ai -ai -af -aa -aa -aa -aa -"} -(8,1,1) = {" -aa -aa -aa -aa -af -af -af -af -ai -ai -ai -ai -at -at -at -at -at -at -at -at -at -at -at -at -at -at -at -at -ai -ai -ai -af -aa -aa -aa -aa -"} -(9,1,1) = {" -aa -aa -aa -aa -ag -af -af -af -ai -ai -ai -ai -at -ax -aY -aY -ay -at -bc -at -bX -cb -cx -cb -cx -cb -cx -at -ai -ai -ai -af -aa -aa -aa -aa -"} -(10,1,1) = {" -aa -ab -aa -aa -af -af -af -af -ai -ai -ai -ai -at -ay -ay -ay -ay -bz -aN -bO -ay -cb -bO -cb -bO -cb -bO -at -ai -ai -ai -af -aa -aa -aa -aa -"} -(11,1,1) = {" -aa -ac -aa -aa -af -af -af -af -ai -ai -ai -ai -at -az -aZ -bk -ay -at -aN -at -bY -ay -cy -cK -ay -dk -ay -at -ai -ai -ai -af -aa -aa -aa -aa -"} -(12,1,1) = {" -aa -aa -aa -aa -af -af -af -af -af -ai -ai -ai -at -at -at -at -at -at -aN -at -at -at -at -at -at -at -at -at -ai -ai -ai -af -aa -dE -aa -aa -"} -(13,1,1) = {" -aa -aa -aa -aa -af -af -af -af -af -ak -ai -ai -at -aA -aE -aE -at -bD -aN -bP -at -cc -aN -aN -cQ -aN -aN -at -ai -ai -ai -ai -aa -aa -aa -aa -"} -(14,1,1) = {" -aa -aa -aa -aa -ag -af -af -af -af -af -ai -ai -at -aB -aE -bl -at -bE -aN -bQ -at -cd -aN -cL -aN -cL -aN -at -ai -ai -ai -ai -aa -aa -aa -aa -"} -(15,1,1) = {" -aa -aa -aa -aa -af -af -af -af -af -af -ai -ai -at -aC -aE -aE -bz -bE -aN -bQ -at -ce -aN -aN -aN -aN -aN -at -ai -ai -ai -ai -aa -aa -aa -aa -"} -(16,1,1) = {" -aa -aa -aa -aa -af -af -af -af -af -af -ai -ai -at -aD -aE -aE -at -bE -bK -bR -at -cf -aN -aN -da -aN -aN -at -ai -ai -ai -ai -aa -aa -aa -aa -"} -(17,1,1) = {" -aa -aa -aa -aa -af -af -af -af -af -ai -ai -ai -at -aE -aE -bm -at -bE -bL -bR -at -cg -aN -cL -aN -al -aN -at -ai -ai -ai -ai -aa -aa -aa -aa -"} -(18,1,1) = {" -aa -aa -aa -aa -af -af -af -af -af -ai -ai -ai -at -aE -aE -aE -at -bF -bL -bR -at -ch -aN -aN -db -al -aN -at -ai -ai -ai -af -aa -aa -aa -aa -"} -(19,1,1) = {" -aa -aa -aa -aa -af -af -af -af -af -ai -ai -ai -at -aB -aE -aB -at -bE -aN -bQ -at -ci -aN -aN -aN -bL -ds -at -ai -ai -ak -af -aa -aa -ab -aa -"} -(20,1,1) = {" -aa -aa -aa -aa -ae -af -af -ag -af -ai -ai -ai -at -aF -aE -bn -at -bE -bM -bQ -at -cj -aN -cN -dc -bL -dt -at -ai -ai -af -af -aa -aa -aa -aa -"} -(21,1,1) = {" -aa -aa -aa -aa -af -af -af -af -af -ai -ai -ai -at -aG -aE -aB -at -bE -bN -bQ -at -ck -aN -aN -bL -bL -aN -at -ai -ai -af -af -aa -aa -aa -aa -"} -(22,1,1) = {" -aa -aa -aa -aa -af -af -af -af -af -af -ai -ai -at -aH -aE -aH -at -bE -aN -bS -at -cl -ca -cO -dc -bL -dt -at -ai -ai -af -af -aa -aa -aa -aa -"} -(23,1,1) = {" -aa -aa -aa -aa -af -af -af -af -af -af -af -ai -at -aB -aE -aB -at -bG -aN -aN -al -al -ca -ca -ca -aN -aN -at -ai -ai -ai -af -aa -aa -aa -aa -"} -(24,1,1) = {" -aa -aa -aa -ad -af -af -af -af -af -af -af -ai -at -aI -aE -aF -at -bE -aN -al -al -cm -al -al -ca -aN -aN -at -ai -ai -ai -af -aa -aa -aa -aa -"} -(25,1,1) = {" -aa -aa -aa -aa -af -af -af -af -af -af -af -ai -at -at -at -at -at -bF -aN -bT -at -cn -cz -cP -dd -dl -cp -at -ai -ai -ai -af -ad -aa -aa -aa -"} -(26,1,1) = {" -aa -aa -aa -aa -af -af -af -af -af -af -af -ai -at -at -at -at -at -bE -aN -bU -at -at -at -at -at -at -at -at -ai -ai -ai -af -aa -aa -aa -aa -"} -(27,1,1) = {" -aa -aa -aa -aa -af -af -af -af -af -af -af -aq -at -aJ -ba -bo -at -bE -aN -bQ -at -co -aN -cQ -de -aN -du -at -ai -ai -ai -af -aa -aa -dF -aa -"} -(28,1,1) = {" -aa -aa -aa -aa -af -af -af -af -af -af -an -aq -at -aK -aN -aN -bz -bE -aN -bV -at -cp -aN -bL -df -aN -dv -at -ai -ai -ai -af -aa -aa -aa -aa -"} -(29,1,1) = {" -aa -aa -aa -aa -af -af -af -af -af -af -al -ar -at -aL -aN -bp -at -bE -aN -bQ -bZ -aN -cA -cR -dg -dm -dw -at -ai -ai -af -af -aa -aa -aa -aa -"} -(30,1,1) = {" -aa -aa -aa -aa -af -af -af -af -af -al -al -aq -at -aM -bb -bq -at -bE -aN -bR -at -cq -cB -cS -df -cS -aN -at -ai -ai -af -af -aa -aa -aa -aa -"} -(31,1,1) = {" -ab -aa -aa -aa -af -af -af -af -af -al -ao -aq -au -at -at -at -at -bE -aN -bR -at -cr -cC -cT -dh -dn -dx -at -ai -ai -af -af -aa -aa -aa -aa -"} -(32,1,1) = {" -aa -aa -aa -aa -af -af -af -af -af -am -al -aq -av -aN -bc -aN -av -bE -bL -bR -at -at -at -at -at -at -at -at -ai -ai -af -af -ab -aa -aa -aa -"} -(33,1,1) = {" -aa -aa -aa -aa -af -af -af -af -af -al -al -aq -av -aN -aN -aN -av -bE -aN -bQ -at -cs -cD -cU -aN -do -dy -at -ai -ai -af -af -aa -aa -aa -aa -"} -(34,1,1) = {" -aa -aa -aa -aa -ag -af -af -af -af -al -al -aq -au -at -at -at -at -bE -aN -bQ -ca -ca -aN -aN -aN -aN -aN -at -ai -ai -af -af -aa -aa -aa -aa -"} -(35,1,1) = {" -aa -aa -aa -aa -af -af -af -af -af -al -al -as -at -aO -bd -br -at -bE -aN -bQ -at -aN -bL -bL -bL -aN -dz -at -ai -af -af -af -aa -aa -aa -aa -"} -(36,1,1) = {" -aa -aa -aa -aa -af -af -af -af -af -af -al -ar -at -aP -be -bs -at -bF -aN -bQ -at -ct -bL -cV -di -dp -aN -at -ai -ai -af -af -aa -aa -aa -aa -"} -(37,1,1) = {" -aa -aa -aa -aa -af -af -af -af -af -af -an -aq -at -aQ -bf -bt -at -bE -aN -bQ -at -cu -cE -cW -cY -cW -aN -at -ai -ai -af -af -aa -aa -aa -aa -"} -(38,1,1) = {" -aa -aa -aa -aa -af -af -af -af -af -af -af -aq -at -aR -aN -bt -at -bE -aN -bU -at -cv -cF -cX -cY -cG -dA -at -ai -ai -af -af -aa -aa -aa -aa -"} -(39,1,1) = {" -aa -aa -aa -aa -af -ah -af -af -af -af -af -ai -at -aS -aN -bu -bz -bE -aN -bQ -at -bL -cG -cY -cW -cG -cI -at -ai -af -af -af -aa -dr -ab -aa -"} -(40,1,1) = {" -aa -aa -aa -aa -af -af -af -af -af -af -af -ai -at -aT -bg -bt -at -bE -aN -bQ -at -aN -cH -cW -cH -cG -dA -at -ai -af -af -af -aa -aa -aa -aa -"} -(41,1,1) = {" -aa -aa -aa -aa -af -af -af -af -af -af -af -ai -at -at -at -bv -at -bH -bK -bQ -at -aN -cI -cZ -al -cG -bL -at -ai -af -af -af -aa -aa -aa -aa -"} -(42,1,1) = {" -aa -aa -aa -aa -af -af -af -af -ag -af -af -ai -at -aU -aU -bw -at -bH -bL -bQ -at -aN -aN -al -cm -al -bL -at -ai -ai -af -af -ap -aa -aa -aa -"} -(43,1,1) = {" -aa -aa -aa -aa -af -af -af -af -af -af -ai -ai -at -aV -bh -bx -at -bI -bL -bW -at -cw -cJ -aN -aN -bL -dB -at -ai -ai -af -af -aa -aa -aa -aa -"} -(44,1,1) = {" -aa -aa -aa -aa -af -af -af -af -af -af -ai -ai -at -at -at -at -at -at -bz -at -at -at -at -at -at -at -at -at -ai -ai -af -af -aa -aa -aa -aa -"} -(45,1,1) = {" -aa -aa -aa -aa -af -af -af -af -af -ai -ai -ai -at -aW -bi -bi -bA -bi -bi -bi -bi -bi -bi -bi -bi -bi -dC -at -ai -ai -af -af -aa -aa -aa -aa -"} -(46,1,1) = {" -aa -aa -aa -aa -af -af -af -af -af -ai -ai -ai -at -aX -bj -by -bB -by -by -bB -by -by -bB -by -dj -dq -dD -at -ai -ai -af -af -aa -aa -aa -aa -"} -(47,1,1) = {" -aa -aa -aa -aa -ae -af -af -af -af -ai -ai -ai -at -at -at -at -at -at -at -at -at -at -at -at -at -at -at -at -ai -ai -af -af -aa -aa -aa -aa -"} -(48,1,1) = {" -aa -aa -aa -aa -af -af -af -af -af -ak -ai -ai -ai -at -at -at -at -at -at -at -at -at -at -at -at -at -at -ai -ai -ai -af -af -aa -aa -aa -dG -"} -(49,1,1) = {" -aa -aa -aa -aa -af -af -af -af -af -af -ai -ai -ai -ai -ai -ai -ai -ai -ai -ai -ai -ai -ai -ai -ai -ai -ai -ai -ai -af -af -af -ab -aa -aa -aa -"} -(50,1,1) = {" -aa -aa -aa -aa -af -af -af -af -af -af -ai -ai -ai -ai -ai -ai -ai -ai -ai -ai -ai -ai -ai -ai -ai -ak -ai -af -af -af -af -af -aa -aa -aa -aa -"} -(51,1,1) = {" -aa -aa -aa -aa -af -af -af -ag -af -af -ai -ai -ai -ai -ai -ai -ai -ai -ai -ai -ai -ai -ai -af -af -af -af -af -af -af -af -af -ap -aa -aa -aa -"} -(52,1,1) = {" -aa -aa -aa -aa -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -ag -af -af -af -af -af -af -af -af -af -aa -aa -aa -aa -"} -(53,1,1) = {" -aa -aa -aa -ad -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -"} -(54,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aw -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -"} -(55,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aj -aa -aa -aa -aa -aa -aa -aa -aa -bJ -aa -aa -aa -aa -aa -aa -aa -dr -bC -aa -aa -aa -dr -aa -aa -aa -aa -ab -"} -(56,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -bC -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -"} +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaabacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaa +aaaaaaaaaeafafafagafafafafagafafafafafaeafafafafafafafafafafafafafagafafafafafafafafafafafafaeafafafafafaaaaaaaa +aaaaaaaaafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafahafafafafafafafafafafafafafaaaaaaaa +aaaaaaaaafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaaaaaaaa +aaaaaaaaafafafafafafafafafafafafafafafagafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafagafaaaaaaaa +abaaaaaaafafaiaiaiaiaiafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafagafafafafafafafafafafaaaaajaa +aaaaaaaaafafaiaiaiaiaiaiakafafafaiaiaiaiaiafafafafafafafafalalamalalalafafafafafafafafafaiaiaiakafafafafaaaaaaaa +aaaaaaaaafaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiafafafafafanalalaoalalalalalanafafafafafaiaiaiaiaiaiaiaiaiafaaaaaaaa +aaaaaaapafaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaqaqaraqaqaqaqaqasaraqaqaiaiaiaiaiaiaiaiaiaiaiaiaiafaaaaaaaa +aaaaaaaaafaiaiatatatatatatatatatatatatatatatatatatatatatatatauavavauatatatatatatatatatatatatataiaiaiaiafaaawaaaa +aaaaaaaaafaiatataxayazataAaBaCaDaEaEaBaFaGaHaBaIatataJaKaLaMataNaNataOaPaQaRaSaTataUaVataWaXatataiaiaiafaaaaaaaa +aaaaaaaaaiaiatataYayaZataEaEaEaEaEaEaEaEaEaEaEaEatatbaaNaNbbatbcaNatbdbebfaNaNbgataUbhatbibjatataiaiaiafaaaaaaaa +aaaaaaaaaiaiatataYaybkataEblaEaEbmaEaBbnaBaHaBaFatatboaNbpbqataNaNatbrbsbtbtbubtbvbwbxatbibyatataiaiaiafaaaaaaaa +aaaaaaabaiaiatatayayayatatatbzatatatatatatatatatatatatbzatatatavavatatatatatbzatatatatatbAbBatataiaiaiafaaaaaabC +aaaaaaaaaiaiatatatbzatatbDbEbEbEbEbFbEbEbEbEbGbEbFbEbEbEbEbEbEbEbEbEbEbFbEbEbEbEbHbHbIatbibyatataiaiaiafaaaabJaa +aaaaaaaaaiaiatatbcaNaNaNaNaNaNbKbLbLaNbMbNaNaNaNaNaNaNaNaNaNaNbLaNaNaNaNaNaNaNaNbKbLbLbzbibyatataiaiaiafaaaaaaaa +aaaaaaaaafaiatatatbOatatbPbQbQbRbRbRbQbQbQbSaNalbTbUbQbVbQbRbRbRbQbQbQbQbQbUbQbQbQbQbWatbibBatataiaiaiafaaaaaaaa +aaaaaaaaafaiatatbXaybYatatatatatatatatatatatalalatatatatbZatatatatcaatatatatatatatatatatbibyatataiaiaiafaaaaaaaa +aaaaaaaaafaiatatcbcbayatcccdcecfcgchcicjckclalcmcnatcocpaNcqcratcscaaNctcucvbLaNaNaNcwatbibyatataiaiaiafaaaaaaaa +aaaaaaaaafaiatatcxbOcyataNaNaNaNaNaNaNaNaNcacaalczataNaNcAcBcCatcDaNbLbLcEcFcGcHcIaNcJatbibBatataiaiaiagaaaaaaaa +aaaaaaaaafaiatatcbcbcKataNcMaNaNcMaNaNcNaNcOcaalcPatcQbLcRcScTatcUaNbLcVcWcXcYcWcZalaNatbibyatataiaiafafaaaaaaaa +aaaaaaaaafaiatatcxbOayatcQaNaNdaaNcLaNdcbLdccacaddatdedfdgdfdhataNaNbLdicYcYcWcHalcmaNatbidjatataiaiafafaaaaaaaa +aaaaabaaafaiatatcbcbdkataNcMaNaNalalbLbLbLbLaNaNdlataNaNdmcSdnatdoaNaNdpcWcGcGcGcGalbLatbidqatataiakafafaaaadraa +aaaaaaaaafaiatatcxbOayataNaNaNaNaNaNdsdtaNdtaNaNcpatdudvdwaNdxatdyaNdzaNaNdAcIdAbLbLdBatdCdDatataiaiafafaaaabCaa +aaaaaaaaafaiaiatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatataiaiafafafaaaaaaaa +aaaaaaaaafaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiafafafaaaaaaaa +aaaaaaaaafaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiafaiaiaiafafafaiaiaiaiaiaiaiafafafafaaaaaaaa +aaaaaaaaafafaiaiaiaiaiaiaiaiaiaiaiaiakafafafaiaiaiaiaiaiafafafafafafafafafafafafafafafafafafafafafafafafaaaadraa +aaaaaaaaafagafafafafafafaiaiaiaiaiafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaaaaaaaa +aaaaaaadaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaapaaaaaaaaaaaaabaaapaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaadEaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaadFaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaadFaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadGaaaaaaaaaaaaabaa +"} \ No newline at end of file diff --git a/maps/submaps/surface_submaps/wilderness/spider1.dmm b/maps/submaps/surface_submaps/wilderness/spider1.dmm index deda5470a7..659cc8beee 100644 --- a/maps/submaps/surface_submaps/wilderness/spider1.dmm +++ b/maps/submaps/surface_submaps/wilderness/spider1.dmm @@ -1,161 +1,22 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"a" = ( -/turf/template_noop, -/area/template_noop) -"b" = ( -/obj/effect/spider/stickyweb, -/turf/template_noop, -/area/submap/spider1) -"c" = ( -/turf/template_noop, -/area/submap/spider1) -"d" = ( -/obj/structure/flora/tree/pine, -/turf/template_noop, -/area/submap/spider1) -"e" = ( -/obj/effect/spider/eggcluster/small/frost, -/turf/template_noop, -/area/submap/spider1) -"f" = ( -/mob/living/simple_animal/hostile/giant_spider/frost{ - returns_home = 1 - }, -/turf/template_noop, -/area/submap/spider1) -"g" = ( -/obj/structure/flora/tree/sif, -/turf/template_noop, -/area/submap/spider1) -"h" = ( -/obj/effect/spider/cocoon, -/mob/living/simple_animal/hostile/giant_spider/frost{ - returns_home = 1 - }, -/turf/template_noop, -/area/submap/spider1) -"Z" = ( -/mob/living/simple_animal/hostile/giant_spider/nurse, -/turf/template_noop, -/area/submap/spider1) +"a" = (/turf/template_noop,/area/template_noop) +"b" = (/obj/effect/spider/stickyweb,/turf/template_noop,/area/submap/spider1) +"c" = (/turf/template_noop,/area/submap/spider1) +"d" = (/obj/structure/flora/tree/pine,/turf/template_noop,/area/submap/spider1) +"e" = (/obj/effect/spider/eggcluster/small/frost,/turf/template_noop,/area/submap/spider1) +"f" = (/mob/living/simple_mob/animal/giant_spider/frost,/turf/template_noop,/area/submap/spider1) +"g" = (/mob/living/simple_mob/animal/giant_spider/nurse,/turf/template_noop,/area/submap/spider1) +"h" = (/obj/structure/flora/tree/sif,/turf/template_noop,/area/submap/spider1) +"i" = (/obj/effect/spider/cocoon,/mob/living/simple_mob/animal/giant_spider/frost,/turf/template_noop,/area/submap/spider1) (1,1,1) = {" -a -a -a -a -a -a -a -a -a -a -"} -(2,1,1) = {" -a -b -c -d -b -c -c -c -c -a -"} -(3,1,1) = {" -a -b -c -e -c -c -c -c -d -a -"} -(4,1,1) = {" -a -c -b -c -f -c -c -c -b -a -"} -(5,1,1) = {" -a -c -c -c -c -c -c -b -c -a -"} -(6,1,1) = {" -a -b -b -c -Z -c -c -b -b -a -"} -(7,1,1) = {" -a -b -c -c -c -c -h -b -c -a -"} -(8,1,1) = {" -a -b -c -c -c -g -c -d -c -a -"} -(9,1,1) = {" -a -c -b -d -c -c -c -c -c -a -"} -(10,1,1) = {" -a -a -a -a -a -a -a -a -a -a -"} +aaaaaaaaaa +abbccbbbca +accbcbccba +adecccccda +abcfcgccca +acccccchca +acccccicca +acccbbbdca +acdbcbccca +aaaaaaaaaa +"} \ No newline at end of file diff --git a/maps/tether/backup/tether-03-surface3.dmm b/maps/tether/backup/tether-03-surface3.dmm index 7ba93b95ce..b49acf7b01 100644 --- a/maps/tether/backup/tether-03-surface3.dmm +++ b/maps/tether/backup/tether-03-surface3.dmm @@ -19917,7 +19917,7 @@ /turf/simulated/floor/tiled, /area/rnd/rdoffice) "Ik" = ( -/mob/living/simple_animal/slime/rainbow/kendrick, +/mob/living/simple_mob/slime/rainbow/kendrick, /turf/simulated/floor/tiled, /area/rnd/rdoffice) "Il" = ( diff --git a/maps/tether/backup/tether-05-station1.dmm b/maps/tether/backup/tether-05-station1.dmm index d02bac8025..e1d9b31b05 100644 --- a/maps/tether/backup/tether-05-station1.dmm +++ b/maps/tether/backup/tether-05-station1.dmm @@ -884,7 +884,7 @@ dir = 4 }, /obj/structure/railing, -/mob/living/simple_animal/fish/koi/poisonous, +/mob/living/simple_mob/fish/koi/poisonous, /turf/simulated/floor/water/pool, /area/hallway/station/atrium) "acg" = ( @@ -1446,7 +1446,7 @@ /obj/structure/railing{ dir = 1 }, -/mob/living/simple_animal/fish/koi/poisonous, +/mob/living/simple_mob/fish/koi/poisonous, /turf/simulated/floor/water/pool, /area/hallway/station/atrium) "adA" = ( @@ -8666,7 +8666,7 @@ /turf/simulated/floor/tiled, /area/bridge_hallway) "azy" = ( -/mob/living/simple_animal/corgi/Ian, +/mob/living/simple_mob/corgi/Ian, /turf/simulated/floor/carpet, /area/crew_quarters/heads/hop) "azz" = ( @@ -10732,7 +10732,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/mob/living/simple_animal/fox/fluff/Renault, +/mob/living/simple_mob/fox/fluff/Renault, /turf/simulated/floor/wood, /area/crew_quarters/captain) "aEu" = ( @@ -15893,7 +15893,7 @@ /area/hallway/station/atrium) "bfT" = ( /obj/structure/disposalpipe/segment, -/mob/living/simple_animal/snake/Noodle, +/mob/living/simple_mob/snake/Noodle, /turf/simulated/floor/carpet/oracarpet, /area/crew_quarters/heads/chief) "bfW" = ( diff --git a/maps/tether/backup/tether-07-station3.dmm b/maps/tether/backup/tether-07-station3.dmm index 5f08f32833..df0ea6a378 100644 --- a/maps/tether/backup/tether-07-station3.dmm +++ b/maps/tether/backup/tether-07-station3.dmm @@ -2803,7 +2803,7 @@ /obj/item/weapon/coin/gold, /obj/item/weapon/coin/silver, /obj/item/weapon/bone/skull, -/mob/living/simple_animal/hostile/mimic/crate, +/mob/living/simple_mob/hostile/mimic/crate, /turf/simulated/mineral/floor/cave, /area/maintenance/station/ai) "eN" = ( @@ -17924,7 +17924,7 @@ dir = 9; pixel_y = 0 }, -/mob/living/simple_animal/fluffy, +/mob/living/simple_mob/fluffy, /turf/simulated/floor/tiled, /area/quartermaster/qm) "CG" = ( @@ -24678,7 +24678,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/mob/living/simple_animal/cat/fluff/Runtime, +/mob/living/simple_mob/cat/fluff/Runtime, /turf/simulated/floor/tiled/white, /area/crew_quarters/heads/cmo) "NB" = ( diff --git a/maps/tether/submaps/_tether_submaps.dm b/maps/tether/submaps/_tether_submaps.dm index 10f0563613..4ec7729312 100644 --- a/maps/tether/submaps/_tether_submaps.dm +++ b/maps/tether/submaps/_tether_submaps.dm @@ -42,7 +42,7 @@ /datum/map_template/tether_lateload/tether_underdark/on_map_loaded(z) . = ..() seed_submaps(list(Z_LEVEL_UNDERDARK), 100, /area/mine/unexplored/underdark, /datum/map_template/underdark) - new /datum/random_map/automata/cave_system/no_cracks(null, 1, 1, Z_LEVEL_UNDERDARK, world.maxx, world.maxy) // Create the mining Z-level. + new /datum/random_map/automata/cave_system/no_cracks(null, 3, 3, Z_LEVEL_UNDERDARK, world.maxx - 4, world.maxy - 4) // Create the mining Z-level. new /datum/random_map/noise/ore(null, 1, 1, Z_LEVEL_UNDERDARK, 64, 64) // Create the mining ore distribution map. ////////////////////////////////////////////////////////////////////////////// @@ -75,10 +75,10 @@ /datum/map_template/tether_lateload/away_beach_cave/on_map_loaded(z) . = ..() seed_submaps(list(Z_LEVEL_BEACH_CAVE), 50, /area/tether_away/cave/unexplored/normal, /datum/map_template/surface/mountains/normal) - seed_submaps(list(Z_LEVEL_BEACH_CAVE), 50, /area/tether_away/cave/unexplored/deep, /datum/map_template/surface/mountains/deep) + seed_submaps(list(Z_LEVEL_BEACH_CAVE), 50, /area/tether_away/cave/unexplored/normal, /datum/map_template/surface/mountains/deep) // Now for the tunnels. - new /datum/random_map/automata/cave_system/no_cracks(null, 1, 1, Z_LEVEL_BEACH_CAVE, world.maxx, world.maxy) + new /datum/random_map/automata/cave_system/no_cracks(null, 3, 3, Z_LEVEL_BEACH_CAVE, world.maxx - 4, world.maxy - 4) new /datum/random_map/noise/ore/beachmine(null, 1, 1, Z_LEVEL_BEACH_CAVE, 64, 64) /datum/map_z_level/tether_lateload/away_beach_cave @@ -121,7 +121,7 @@ /datum/map_template/tether_lateload/away_aerostat_surface/on_map_loaded(z) . = ..() seed_submaps(list(Z_LEVEL_AEROSTAT_SURFACE), 50, /area/tether_away/aerostat/surface/unexplored, /datum/map_template/virgo2) - new /datum/random_map/automata/cave_system/no_cracks(null, 1, 1, Z_LEVEL_AEROSTAT_SURFACE, world.maxx, world.maxy) + new /datum/random_map/automata/cave_system/no_cracks(null, 3, 3, Z_LEVEL_AEROSTAT_SURFACE, world.maxx - 4, world.maxy - 4) new /datum/random_map/noise/ore/virgo2(null, 1, 1, Z_LEVEL_AEROSTAT_SURFACE, 64, 64) /datum/map_z_level/tether_lateload/away_aerostat_surface @@ -177,7 +177,7 @@ /obj/effect/step_trigger/zlevel_fall //Don't ever use this, only use subtypes.Define a new var/static/target_z on each affect_ghosts = 1 -/obj/effect/step_trigger/zlevel_fall/initialize() +/obj/effect/step_trigger/zlevel_fall/Initialize() . = ..() if(istype(get_turf(src), /turf/simulated/floor)) @@ -237,17 +237,17 @@ var/guard //# will set the mobs to remain nearby their spawn point within this dist //Internal use only - var/mob/living/simple_animal/my_mob + var/mob/living/simple_mob/my_mob var/depleted = FALSE -/obj/tether_away_spawner/initialize() +/obj/tether_away_spawner/Initialize() . = ..() if(!LAZYLEN(mobs_to_pick_from)) error("Mob spawner at [x],[y],[z] ([get_area(src)]) had no mobs_to_pick_from set on it!") initialized = TRUE return INITIALIZE_HINT_QDEL - processing_objects |= src + START_PROCESSING(SSobj, src) /obj/tether_away_spawner/process() if(my_mob && my_mob.stat != DEAD) @@ -281,14 +281,14 @@ my_mob.max_tox = gaslist["phoron"] * 1.2 my_mob.max_n2 = gaslist["nitrogen"] * 1.2 my_mob.max_co2 = gaslist["carbon_dioxide"] * 1.2 - +/* //VORESTATION AI TEMPORARY REMOVAL if(guard) my_mob.returns_home = TRUE my_mob.wander_distance = guard - +*/ return else - processing_objects -= src + STOP_PROCESSING(SSobj, src) depleted = TRUE return @@ -304,5 +304,5 @@ prob_fall = 1 guard = 10 //Don't wander too far, to stay alive. mobs_to_pick_from = list( - /mob/living/simple_animal/shadekin + // /mob/living/simple_mob/shadekin //VORESTATION AI TEMPORARY REMOVAL ) diff --git a/maps/tether/submaps/admin_use/spa.dmm b/maps/tether/submaps/admin_use/spa.dmm index b8784719b3..6b387805fd 100644 --- a/maps/tether/submaps/admin_use/spa.dmm +++ b/maps/tether/submaps/admin_use/spa.dmm @@ -55,7 +55,7 @@ /turf/simulated/floor/water, /area/submap/spa) "ak" = ( -/mob/living/simple_animal/fox, +/mob/living/simple_mob/animal/fox_vr, /turf/simulated/floor/grass, /area/submap/spa) "al" = ( @@ -623,7 +623,7 @@ }, /area/space) "bW" = ( -/mob/living/simple_animal/redpanda, +/mob/living/simple_mob/vore/redpanda, /turf/simulated/floor/grass, /area/submap/spa) "bX" = ( diff --git a/maps/tether/submaps/aerostat/_aerostat.dm b/maps/tether/submaps/aerostat/_aerostat.dm index fb58fa7f33..efc7528ffb 100644 --- a/maps/tether/submaps/aerostat/_aerostat.dm +++ b/maps/tether/submaps/aerostat/_aerostat.dm @@ -48,7 +48,7 @@ shuttle_name = "Excursion Shuttle" destinations = list(/datum/shuttle_destination/excursion/virgo2orbit, /datum/shuttle_destination/excursion/aerostat) -/obj/away_mission_init/aerostat/initialize() +/obj/away_mission_init/aerostat/Initialize() /*seed_submaps(list(Z_LEVEL_AEROSTAT_SURFACE), 50, /area/tether_away/aerostat/surface/unexplored, /datum/map_template/virgo2) new /datum/random_map/automata/cave_system/no_cracks(null, 1, 1, Z_LEVEL_AEROSTAT_SURFACE, world.maxx, world.maxy) new /datum/random_map/noise/ore/virgo2(null, 1, 1, Z_LEVEL_AEROSTAT_SURFACE, 64, 64)*/ @@ -64,10 +64,10 @@ prob_fall = 50 guard = 20 mobs_to_pick_from = list( - /mob/living/simple_animal/hostile/hivebot/range = 3, - /mob/living/simple_animal/hostile/hivebot/range/ion = 3, - /mob/living/simple_animal/hostile/hivebot/range/laser = 3, - /mob/living/simple_animal/hostile/corrupthound = 1 + /mob/living/simple_mob/mechanical/hivebot/ranged_damage/basic = 3, + /mob/living/simple_mob/mechanical/hivebot/ranged_damage/ion = 3, + /mob/living/simple_mob/mechanical/hivebot/ranged_damage/laser = 3, + /mob/living/simple_mob/vore/corrupthound = 1 ) /obj/tether_away_spawner/aerostat_surface @@ -78,9 +78,9 @@ prob_fall = 50 guard = 20 mobs_to_pick_from = list( - /mob/living/simple_animal/hostile/jelly = 3, - /mob/living/simple_animal/hostile/viscerator = 2, - /mob/living/simple_animal/hostile/corrupthound = 1 + /mob/living/simple_mob/vore/corrupthound = 3, + /mob/living/simple_mob/mechanical/viscerator = 2, + /mob/living/simple_mob/vore/corrupthound = 1 ) /obj/structure/old_roboprinter @@ -129,7 +129,7 @@ color = "#eacd7c" VIRGO2_SET_ATMOS -/turf/unsimulated/floor/sky/virgo2_sky/initialize() +/turf/unsimulated/floor/sky/virgo2_sky/Initialize() skyfall_levels = list(z+1) . = ..() diff --git a/maps/tether/submaps/aerostat/submaps/Blackshuttledown.dmm b/maps/tether/submaps/aerostat/submaps/Blackshuttledown.dmm index 27cdc7804f..66a5ae2d54 100644 --- a/maps/tether/submaps/aerostat/submaps/Blackshuttledown.dmm +++ b/maps/tether/submaps/aerostat/submaps/Blackshuttledown.dmm @@ -148,9 +148,9 @@ }, /area/submap/virgo2/Blackshuttledown) "aB" = ( -/mob/living/simple_animal/hostile/viscerator, -/mob/living/simple_animal/hostile/viscerator, -/mob/living/simple_animal/hostile/viscerator, +/mob/living/simple_mob/hostile/viscerator, +/mob/living/simple_mob/hostile/viscerator, +/mob/living/simple_mob/hostile/viscerator, /turf/simulated/floor/tiled/steel, /area/submap/virgo2/Blackshuttledown) "aC" = ( @@ -163,7 +163,7 @@ /turf/simulated/floor/tiled/steel, /area/submap/virgo2/Blackshuttledown) "aD" = ( -/mob/living/simple_animal/hostile/syndicate/ranged/space, +/mob/living/simple_mob/hostile/syndicate/ranged/space, /turf/simulated/floor/tiled/steel, /area/submap/virgo2/Blackshuttledown) "aE" = ( @@ -242,7 +242,7 @@ /turf/simulated/floor/tiled/steel, /area/submap/virgo2/Blackshuttledown) "aT" = ( -/mob/living/simple_animal/hostile/syndicate/ranged{ +/mob/living/simple_mob/hostile/syndicate/ranged{ desc = "Dosen't look friendly in the slightest."; name = "Unknown Individual"; say_got_target = list("Looks like trouble!","Contact!","We've got company!","Perimeter Breached!!"); @@ -374,7 +374,7 @@ /turf/simulated/floor/tiled/steel, /area/submap/virgo2/Blackshuttledown) "bn" = ( -/mob/living/simple_animal/hostile/viscerator, +/mob/living/simple_mob/hostile/viscerator, /turf/simulated/floor/tiled/steel, /area/submap/virgo2/Blackshuttledown) "bo" = ( @@ -393,8 +393,8 @@ /turf/simulated/floor/tiled/steel, /area/submap/virgo2/Blackshuttledown) "bq" = ( -/mob/living/simple_animal/hostile/viscerator, -/mob/living/simple_animal/hostile/viscerator, +/mob/living/simple_mob/hostile/viscerator, +/mob/living/simple_mob/hostile/viscerator, /turf/simulated/floor/tiled/steel, /area/submap/virgo2/Blackshuttledown) "br" = ( @@ -439,7 +439,7 @@ /turf/simulated/mineral/floor/ignore_mapgen/virgo2, /area/submap/virgo2/Blackshuttledown) "bz" = ( -/mob/living/simple_animal/hostile/syndicate/ranged/space, +/mob/living/simple_mob/hostile/syndicate/ranged/space, /turf/simulated/mineral/floor/ignore_mapgen/virgo2, /area/submap/virgo2/Blackshuttledown) diff --git a/maps/tether/submaps/aerostat/submaps/Boombase.dmm b/maps/tether/submaps/aerostat/submaps/Boombase.dmm index 867ffdc6c2..dd8247263f 100644 --- a/maps/tether/submaps/aerostat/submaps/Boombase.dmm +++ b/maps/tether/submaps/aerostat/submaps/Boombase.dmm @@ -57,7 +57,7 @@ /turf/simulated/floor/tiled/techfloor/virgo2, /area/submap/virgo2/BoomBase) "ao" = ( -/mob/living/simple_animal/hostile/jelly, +/mob/living/simple_mob/hostile/jelly, /turf/simulated/floor/tiled/techfloor/virgo2, /area/submap/virgo2/BoomBase) "ap" = ( @@ -96,7 +96,7 @@ /area/submap/virgo2/BoomBase) "ax" = ( /obj/effect/decal/cleanable/dirt, -/mob/living/simple_animal/hostile/jelly, +/mob/living/simple_mob/hostile/jelly, /turf/simulated/floor/tiled/techfloor/virgo2, /area/submap/virgo2/BoomBase) "ay" = ( diff --git a/maps/tether/submaps/aerostat/submaps/CaveS.dmm b/maps/tether/submaps/aerostat/submaps/CaveS.dmm index 426c86125c..005a584089 100644 --- a/maps/tether/submaps/aerostat/submaps/CaveS.dmm +++ b/maps/tether/submaps/aerostat/submaps/CaveS.dmm @@ -48,7 +48,7 @@ /turf/simulated/mineral/floor/ignore_mapgen/virgo2, /area/submap/virgo2/CaveS) "m" = ( -/mob/living/simple_animal/hostile/giant_spider/lurker, +/mob/living/simple_mob/hostile/giant_spider/lurker, /turf/simulated/mineral/floor/ignore_mapgen/virgo2, /area/submap/virgo2/CaveS) "n" = ( @@ -61,7 +61,7 @@ /area/submap/virgo2/CaveS) "q" = ( /obj/effect/decal/cleanable/cobweb2, -/mob/living/simple_animal/hostile/giant_spider/lurker, +/mob/living/simple_mob/hostile/giant_spider/lurker, /turf/simulated/mineral/floor/ignore_mapgen/virgo2, /area/submap/virgo2/CaveS) "r" = ( @@ -133,7 +133,7 @@ /area/submap/virgo2/CaveS) "D" = ( /obj/effect/spider/stickyweb, -/mob/living/simple_animal/hostile/giant_spider/lurker, +/mob/living/simple_mob/hostile/giant_spider/lurker, /turf/simulated/mineral/floor/ignore_mapgen/virgo2, /area/submap/virgo2/CaveS) "E" = ( diff --git a/maps/tether/submaps/aerostat/submaps/Rockybase.dmm b/maps/tether/submaps/aerostat/submaps/Rockybase.dmm index e7977a3af5..95faba534a 100644 --- a/maps/tether/submaps/aerostat/submaps/Rockybase.dmm +++ b/maps/tether/submaps/aerostat/submaps/Rockybase.dmm @@ -1,6 +1,6 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "aa" = ( -/mob/living/simple_animal/hostile/viscerator{ +/mob/living/simple_mob/hostile/viscerator{ maxbodytemp = 900; returns_home = 1 }, @@ -21,7 +21,7 @@ /turf/simulated/floor/tiled/techfloor/virgo2, /area/submap/virgo2/Rockybase) "af" = ( -/mob/living/simple_animal/hostile/malf_drone{ +/mob/living/simple_mob/hostile/malf_drone{ desc = "An automated combat drone with an aged apperance."; faction = "syndicate"; maxbodytemp = 900; @@ -357,7 +357,7 @@ /turf/simulated/floor/tiled, /area/submap/virgo2/Rockybase) "bl" = ( -/mob/living/simple_animal/hostile/malf_drone{ +/mob/living/simple_mob/hostile/malf_drone{ desc = "An automated combat drone with an aged apperance."; faction = "syndicate"; maxbodytemp = 900; @@ -664,7 +664,7 @@ /turf/simulated/floor/tiled/techfloor/virgo2, /area/submap/virgo2/Rockybase) "co" = ( -/mob/living/simple_animal/hostile/mecha/malf_drone{ +/mob/living/simple_mob/hostile/mecha/malf_drone{ faction = "syndicate" }, /turf/simulated/floor/tiled/techfloor/virgo2, diff --git a/maps/tether/submaps/alienship/_alienship.dm b/maps/tether/submaps/alienship/_alienship.dm index be9f764155..7336a0db19 100644 --- a/maps/tether/submaps/alienship/_alienship.dm +++ b/maps/tether/submaps/alienship/_alienship.dm @@ -34,7 +34,7 @@ var/door_on_mode var/teleport_on_mode -/obj/away_mission_init/alienship/initialize() +/obj/away_mission_init/alienship/Initialize() . = ..() if(!mission_mode) //WE ARE NUMBER ONE @@ -120,7 +120,7 @@ var/area/dump_area var/obj/shuttle_connector/shuttle_friend -/area/shuttle/excursion/away_alienship/initialize() +/area/shuttle/excursion/away_alienship/Initialize() . = ..() dump_area = locate(/area/tether_away/alienship/equip_dump) diff --git a/maps/tether/submaps/beach/_beach.dm b/maps/tether/submaps/beach/_beach.dm index f60ffe9922..8336c6b23a 100644 --- a/maps/tether/submaps/beach/_beach.dm +++ b/maps/tether/submaps/beach/_beach.dm @@ -72,7 +72,7 @@ name = "away mission initializer - beachcave" //In our case, it initializes the ores and random submaps in the beach's cave, then deletes itself -/obj/away_mission_init/beachcave/initialize() +/obj/away_mission_init/beachcave/Initialize() // Cave submaps are first. /*seed_submaps(list(z), 50, /area/tether_away/cave/unexplored/normal, /datum/map_template/surface/mountains/normal) seed_submaps(list(z), 50, /area/tether_away/cave/unexplored/deep, /datum/map_template/surface/mountains/deep) @@ -95,7 +95,7 @@ prob_fall = 25 //Chance goes down by this much each time it spawns one (not defining and prob_spawn 100 means they spawn as soon as one dies) guard = 40 //They'll stay within this range (not defining this disables them staying nearby and they will wander the map (and through step teleports)) mobs_to_pick_from = list( - /mob/living/simple_animal/snake + /mob/living/simple_mob/vore/giant_snake ) /obj/tether_away_spawner/beach_outside_friendly @@ -106,7 +106,7 @@ prob_fall = 25 guard = 40 mobs_to_pick_from = list( - /mob/living/simple_animal/fennec + /mob/living/simple_mob/fennec ) /obj/tether_away_spawner/beach_cave @@ -117,11 +117,11 @@ prob_fall = 40 guard = 20 mobs_to_pick_from = list( - /mob/living/simple_animal/hostile/frog = 3, //Frogs are 3x more likely to spawn than, - /mob/living/simple_animal/hostile/deathclaw = 1, //these deathclaws are, with these values, - /mob/living/simple_animal/hostile/giant_spider = 3, - /mob/living/simple_animal/hostile/giant_snake = 1, - /mob/living/simple_animal/hostile/giant_spider/ion = 2 + /mob/living/simple_mob/vore/frog = 3, //Frogs are 3x more likely to spawn than, + /mob/living/simple_mob/hostile/deathclaw = 1, //these deathclaws are, with these values, + /mob/living/simple_mob/animal/giant_spider = 3, + /mob/living/simple_mob/vore/giant_snake = 1, + /mob/living/simple_mob/animal/giant_spider/ion = 2 ) // These are step-teleporters, for map edge transitions diff --git a/maps/tether/submaps/tether_misc.dmm b/maps/tether/submaps/tether_misc.dmm index 4f8dcd6be0..371bb9d7ba 100644 --- a/maps/tether/submaps/tether_misc.dmm +++ b/maps/tether/submaps/tether_misc.dmm @@ -4271,7 +4271,7 @@ name = "Beruang"; pixel_x = 32 }, -/mob/living/simple_animal/corgi/tamaskan/spice, +/mob/living/simple_mob/corgi/tamaskan/spice, /turf/simulated/shuttle/floor/darkred, /area/shuttle/trade/centcom) "kz" = ( @@ -5640,7 +5640,7 @@ }, /area/wizard_station) "nm" = ( -/mob/living/simple_animal/mouse/gray{ +/mob/living/simple_mob/mouse/gray{ desc = "He looks kingly."; name = "Arthur" }, @@ -8869,7 +8869,7 @@ }, /area/antag/antag_base) "sM" = ( -/mob/living/simple_animal/fox/syndicate{ +/mob/living/simple_mob/fox/syndicate{ name = "Rick" }, /turf/unsimulated/floor{ diff --git a/maps/tether/submaps/tether_underdark.dmm b/maps/tether/submaps/tether_underdark.dmm index 029965b56c..7fc80268c2 100644 --- a/maps/tether/submaps/tether_underdark.dmm +++ b/maps/tether/submaps/tether_underdark.dmm @@ -13,9 +13,6 @@ /turf/simulated/floor/outdoors/dirt/virgo3b, /area/mine/explored/underdark) "b" = ( -/obj/tether_away_spawner/shadekin{ - faction = "underdark" - }, /turf/simulated/mineral/floor/virgo3b, /area/mine/explored/underdark) "c" = ( diff --git a/maps/tether/tether-01-surface1.dmm b/maps/tether/tether-01-surface1.dmm index b7c6a77749..645bcc5418 100644 --- a/maps/tether/tether-01-surface1.dmm +++ b/maps/tether/tether-01-surface1.dmm @@ -42,9 +42,7 @@ name = "south bump"; pixel_y = -28 }, -/obj/structure/cable/green{ - icon_state = "16-0" - }, +/obj/structure/cable/green, /turf/simulated/floor/tiled/steel_dirty/virgo3b, /area/tether/surfacebase/mining_main/external) "aak" = ( @@ -403,13 +401,52 @@ /turf/simulated/floor/tiled/techfloor, /area/tether/surfacebase/mining_main/refinery) "aaS" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/full, +/obj/machinery/atmospherics/pipe/simple/hidden/cyan{ + dir = 4 + }, +/obj/machinery/door/airlock/maintenance/common, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/door/firedoor/glass, /turf/simulated/floor/plating, -/area/tether/surfacebase/mining_main/refinery) +/area/maintenance/lower/mining_eva) +"aaT" = ( +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/alarm{ + pixel_y = 22; + target_temperature = 293.15 + }, +/turf/simulated/floor/plating, +/area/maintenance/lower/solars) "aaU" = ( /turf/simulated/wall, /area/maintenance/lower/trash_pit) +"aaV" = ( +/obj/structure/catwalk, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/alarm{ + dir = 8; + icon_state = "alarm0"; + pixel_x = 24 + }, +/turf/simulated/floor/plating, +/area/maintenance/lower/trash_pit) +"aaW" = ( +/obj/structure/cable{ + d1 = 2; + d2 = 8; + icon_state = "2-8" + }, +/obj/machinery/alarm{ + pixel_y = 22 + }, +/turf/simulated/floor/tiled/techfloor, +/area/maintenance/lower/vacant_site) "aaX" = ( /obj/structure/plasticflaps, /obj/machinery/conveyor{ @@ -481,6 +518,26 @@ }, /turf/simulated/floor/tiled/steel_grid, /area/tether/surfacebase/mining_main/refinery) +"abf" = ( +/obj/machinery/door/airlock/maintenance/common{ + name = "Trash Pit Access"; + req_one_access = list(26,48) + }, +/obj/structure/catwalk, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/plating, +/area/maintenance/lower/trash_pit) +"abg" = ( +/obj/effect/floor_decal/steeldecal/steel_decals4{ + dir = 10 + }, +/obj/effect/floor_decal/steeldecal/steel_decals4, +/obj/machinery/alarm{ + pixel_y = 22; + target_temperature = 293.15 + }, +/turf/simulated/floor/tiled, +/area/rnd/hallway) "abh" = ( /turf/simulated/floor/tiled, /area/tether/surfacebase/mining_main/refinery) @@ -658,6 +715,23 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/mining_main/storage) +"abx" = ( +/obj/effect/floor_decal/industrial/loading{ + dir = 8 + }, +/obj/effect/floor_decal/steeldecal/steel_decals6{ + dir = 9 + }, +/obj/effect/floor_decal/steeldecal/steel_decals6{ + dir = 6 + }, +/obj/machinery/door/firedoor/glass/hidden/steel{ + dir = 8 + }, +/turf/simulated/floor/tiled{ + icon_state = "monotile" + }, +/area/security/checkpoint) "aby" = ( /obj/machinery/conveyor{ dir = 8; @@ -672,6 +746,26 @@ }, /turf/simulated/floor/plating, /area/tether/surfacebase/mining_main/refinery) +"abA" = ( +/obj/effect/floor_decal/industrial/outline/yellow, +/obj/machinery/alarm{ + dir = 1; + pixel_y = -25 + }, +/turf/simulated/floor/tiled{ + icon_state = "techmaint" + }, +/area/security/checkpoint) +"abB" = ( +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/door/airlock/maintenance/common, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/plating, +/area/maintenance/lower/solars) "abC" = ( /obj/structure/plasticflaps/mining, /obj/machinery/conveyor{ @@ -680,6 +774,19 @@ }, /turf/simulated/floor/plating, /area/tether/surfacebase/mining_main/refinery) +"abD" = ( +/obj/structure/table/glass, +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/mauve/border, +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 1 + }, +/obj/machinery/alarm{ + dir = 1; + pixel_y = -22 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora/lab_atmos) "abE" = ( /obj/effect/floor_decal/industrial/warning{ dir = 8 @@ -1058,6 +1165,19 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/mining_main/eva) +"aci" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/alarm{ + pixel_y = 22 + }, +/turf/simulated/floor/plating, +/area/maintenance/lower/atmos) "acj" = ( /obj/effect/floor_decal/borderfloor{ dir = 8 @@ -1131,6 +1251,17 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/mining_main/uxstorage) +"aco" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/railing, +/obj/structure/railing{ + dir = 4 + }, +/obj/machinery/alarm{ + pixel_y = 22 + }, +/turf/simulated/floor/tiled/techfloor, +/area/maintenance/lower/locker_room) "acp" = ( /obj/structure/catwalk, /obj/effect/decal/cleanable/dirt, @@ -1148,6 +1279,101 @@ /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plating, /area/maintenance/lower/trash_pit) +"acr" = ( +/obj/structure/table/marble, +/obj/machinery/door/window{ + dir = 8; + req_one_access = list(25) + }, +/obj/machinery/door/blast/shutters{ + dir = 8; + id = "cafe"; + layer = 3.1; + name = "Cafe Shutters" + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/tiled, +/area/crew_quarters/visitor_dining) +"acs" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + 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 + }, +/obj/structure/catwalk, +/obj/machinery/door/airlock/maintenance/common, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/tiled/techfloor, +/area/maintenance/lower/locker_room) +"act" = ( +/obj/machinery/door/airlock/maintenance/common{ + name = "Tram Maintenance Access" + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/tiled, +/area/crew_quarters/visitor_dining) +"acu" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 8 + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 5 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 6 + }, +/obj/machinery/alarm{ + dir = 4; + icon_state = "alarm0"; + pixel_x = -22 + }, +/turf/simulated/floor/tiled, +/area/rnd/hallway) +"acv" = ( +/obj/structure/cable/cyan{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/door/airlock/maintenance/engi{ + name = "Drone Bay" + }, +/obj/machinery/atmospherics/pipe/simple/visible/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/tiled/techfloor, +/area/maintenance/lower/atmos) +"acw" = ( +/obj/effect/floor_decal/steeldecal/steel_decals_central1{ + dir = 1 + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/tiled/monofloor{ + dir = 1 + }, +/area/crew_quarters/visitor_laundry) "acx" = ( /turf/simulated/floor/tiled, /area/tether/surfacebase/mining_main/storage) @@ -1155,6 +1381,32 @@ /obj/machinery/atmospherics/unary/vent_pump/on, /turf/simulated/floor/tiled, /area/tether/surfacebase/mining_main/storage) +"acz" = ( +/obj/machinery/door/airlock/multi_tile/glass{ + autoclose = 1; + dir = 2; + id_tag = null; + name = "Laundry"; + req_access = list() + }, +/obj/effect/floor_decal/steeldecal/steel_decals_central1, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/tiled/monofloor, +/area/crew_quarters/visitor_laundry) "acA" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -1245,6 +1497,14 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/mining_main/eva) +"acJ" = ( +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/lightgrey/border, +/obj/effect/landmark{ + name = "lightsout" + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/first_west) "acK" = ( /obj/machinery/atmospherics/unary/vent_scrubber/on, /turf/simulated/floor/tiled, @@ -1281,6 +1541,19 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/mining_main/uxstorage) +"acN" = ( +/obj/structure/cable/ender{ + icon_state = "1-2"; + id = "surface-mining" + }, +/obj/structure/railing{ + dir = 8 + }, +/obj/structure/railing{ + dir = 4 + }, +/turf/simulated/floor/plating, +/area/tether/surfacebase/outside/outside1) "acO" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, @@ -1328,6 +1601,27 @@ }, /turf/simulated/floor/plating, /area/maintenance/lower/mining_eva) +"acT" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/structure/cable/green{ + d1 = 2; + d2 = 8; + icon_state = "2-8" + }, +/obj/structure/cable{ + d1 = 1; + d2 = 8; + icon_state = "1-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/disposalpipe/segment, +/turf/simulated/floor/tiled, +/area/hallway/lower/first_west) "acU" = ( /obj/machinery/light{ dir = 8 @@ -1340,6 +1634,15 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/mining_main/storage) +"acV" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/unary/vent_pump/on, +/turf/simulated/floor/tiled, +/area/hallway/lower/first_west) "acW" = ( /obj/structure/catwalk, /obj/effect/decal/cleanable/dirt, @@ -1413,6 +1716,19 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/mining_main/storage) +"ada" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/structure/cable/green{ + d1 = 2; + d2 = 8; + icon_state = "2-8" + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/first_west) "adb" = ( /obj/machinery/light{ dir = 1 @@ -1454,6 +1770,15 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/mining_main/storage) +"add" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/unary/vent_scrubber/on, +/turf/simulated/floor/tiled, +/area/hallway/lower/first_west) "ade" = ( /obj/effect/floor_decal/industrial/warning{ dir = 1 @@ -1500,6 +1825,70 @@ }, /turf/simulated/floor/plating, /area/maintenance/lower/trash_pit) +"adh" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/cable/green{ + d1 = 1; + d2 = 8; + icon_state = "1-8" + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/first_west) +"adi" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/cable/green{ + d1 = 2; + d2 = 8; + icon_state = "2-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/first_west) +"adj" = ( +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/effect/floor_decal/steeldecal/steel_decals6, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/first_west) +"adk" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/lightgrey/border, +/obj/effect/floor_decal/borderfloor/corner2, +/obj/effect/floor_decal/corner/lightgrey/bordercorner2, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 8 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/first_west) "adl" = ( /obj/machinery/atmospherics/pipe/simple/hidden/cyan{ dir = 10; @@ -1600,6 +1989,26 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/mining_main/storage) +"adu" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/lightgrey/border, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 8 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/first_west) "adv" = ( /obj/effect/floor_decal/borderfloor{ dir = 4 @@ -1700,6 +2109,25 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/mining_main/uxstorage) +"adF" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/lightgrey/border, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 8 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 1 + }, +/obj/machinery/light, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/first_west) "adG" = ( /obj/structure/disposalpipe/segment{ dir = 1; @@ -1707,6 +2135,75 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/mining_main/storage) +"adH" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/power/apc{ + dir = 2; + name = "south bump"; + pixel_y = -28 + }, +/obj/structure/cable/green, +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/lightgrey/border, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 8 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/first_west) +"adI" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/lightgrey/border, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 8 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 1 + }, +/obj/structure/extinguisher_cabinet{ + dir = 1; + icon_state = "extinguisher_closed"; + pixel_y = -32 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/first_west) +"adJ" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/lightgrey/border, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 8 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/first_west) "adK" = ( /turf/simulated/wall, /area/tether/surfacebase/outside/outside1) @@ -1737,15 +2234,23 @@ /turf/simulated/floor/plating, /area/maintenance/lower/mining_eva) "adO" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/cyan{ - dir = 4 - }, -/obj/machinery/door/airlock/maintenance/common, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/turf/simulated/floor/plating, -/area/maintenance/lower/mining_eva) +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/lightgrey/border, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 8 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/first_west) "adP" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, @@ -1829,6 +2334,32 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/mining_main/storage) +"adW" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/lightgrey/border, +/obj/effect/floor_decal/borderfloor/corner2{ + dir = 9 + }, +/obj/effect/floor_decal/corner/lightgrey/bordercorner2{ + dir = 9 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 8 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/first_west) "adX" = ( /obj/item/weapon/pickaxe, /obj/structure/table/steel, @@ -2030,6 +2561,27 @@ /obj/effect/floor_decal/rust, /turf/simulated/floor/virgo3b, /area/tether/surfacebase/outside/outside1) +"aeq" = ( +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply, +/obj/effect/floor_decal/steeldecal/steel_decals4{ + dir = 5 + }, +/obj/effect/floor_decal/steeldecal/steel_decals4{ + dir = 8 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/first_west) "aer" = ( /turf/simulated/wall, /area/tether/surfacebase/mining_main/ore) @@ -2042,6 +2594,28 @@ }, /turf/simulated/floor/tiled/steel_grid, /area/tether/surfacebase/mining_main/ore) +"aet" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/lightgrey/border, +/obj/effect/floor_decal/borderfloor/corner2, +/obj/effect/floor_decal/corner/lightgrey/bordercorner2, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 1 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 8 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/first_west) "aeu" = ( /obj/machinery/door/airlock/glass_mining{ name = "Mining Operations" @@ -2059,9 +2633,77 @@ }, /turf/simulated/floor/tiled/steel_grid, /area/tether/surfacebase/mining_main/eva) +"aew" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/lightgrey/border, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 8 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 1 + }, +/obj/effect/floor_decal/borderfloor/corner2{ + dir = 9 + }, +/obj/effect/floor_decal/corner/lightgrey/bordercorner2{ + dir = 9 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/first_west) "aex" = ( /turf/simulated/wall, /area/maintenance/substation/mining) +"aey" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/effect/floor_decal/steeldecal/steel_decals_central1, +/obj/machinery/door/airlock/multi_tile/glass{ + dir = 1; + name = "West Hallway" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/tiled/monofloor, +/area/tether/surfacebase/north_stairs_one) +"aez" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/lightgrey/border, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 8 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 1 + }, +/obj/effect/floor_decal/borderfloor/corner2, +/obj/effect/floor_decal/corner/lightgrey/bordercorner2, +/obj/effect/floor_decal/steeldecal/steel_decals4{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/north_stairs_one) "aeA" = ( /obj/machinery/light/small{ dir = 1 @@ -2120,6 +2762,45 @@ "aeF" = ( /turf/simulated/floor/tiled/steel_dirty, /area/tether/surfacebase/mining_main/ore) +"aeG" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/lightgrey/border, +/obj/effect/floor_decal/borderfloor/corner2{ + dir = 9 + }, +/obj/effect/floor_decal/corner/lightgrey/bordercorner2{ + dir = 9 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 8 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/north_stairs_one) +"aeH" = ( +/obj/effect/floor_decal/industrial/warning, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/north_stairs_one) "aeI" = ( /obj/machinery/light_switch{ pixel_x = 25 @@ -2130,6 +2811,30 @@ "aeJ" = ( /turf/simulated/wall, /area/tether/surfacebase/mining_main/lobby) +"aeK" = ( +/obj/machinery/light/small, +/obj/effect/floor_decal/industrial/warning/corner{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply, +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/lightgrey/border, +/obj/effect/floor_decal/borderfloor/corner2, +/obj/effect/floor_decal/corner/lightgrey/bordercorner2, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 1 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 8 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/north_stairs_one) "aeL" = ( /obj/effect/floor_decal/borderfloor{ dir = 1 @@ -2168,6 +2873,51 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/mining_main/lobby) +"aeO" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/lightgrey/border, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 1 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 8 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/north_stairs_one) +"aeP" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/lightgrey/border, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 1 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 8 + }, +/obj/structure/extinguisher_cabinet{ + dir = 1; + icon_state = "extinguisher_closed"; + pixel_y = -32 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/north_stairs_one) "aeQ" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -2210,16 +2960,23 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/mining_main/lobby) "aeT" = ( -/obj/structure/table/glass, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/disposalpipe/segment, /obj/effect/floor_decal/borderfloor{ - dir = 1 + dir = 4 }, -/obj/effect/floor_decal/corner/brown/border{ - dir = 1 +/obj/effect/floor_decal/corner/lightgrey/border{ + dir = 4 + }, +/obj/machinery/camera/network/tether{ + dir = 9 }, -/obj/machinery/camera/network/mining, /turf/simulated/floor/tiled, -/area/tether/surfacebase/mining_main/lobby) +/area/tether/surfacebase/public_garden) "aeU" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -2241,6 +2998,32 @@ "aeW" = ( /turf/simulated/wall, /area/storage/primary) +"aeX" = ( +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/machinery/power/apc{ + dir = 2; + name = "south bump"; + pixel_y = -28 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/lightgrey/border, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 1 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 8 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/north_stairs_one) "aeY" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 5 @@ -2270,6 +3053,32 @@ /obj/machinery/hologram/holopad, /turf/simulated/floor/tiled, /area/tether/surfacebase/mining_main/storage) +"afa" = ( +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/lightgrey/border, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 1 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 8 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/north_stairs_one) "afb" = ( /obj/machinery/atmospherics/pipe/manifold4w/hidden/supply, /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ @@ -2282,6 +3091,41 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/mining_main/storage) +"afc" = ( +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/lightgrey/border, +/obj/effect/floor_decal/borderfloor/corner2{ + dir = 9 + }, +/obj/effect/floor_decal/corner/lightgrey/bordercorner2{ + dir = 9 + }, +/obj/effect/floor_decal/steeldecal/steel_decals4{ + dir = 10 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 1 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 8 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/north_stairs_one) "afd" = ( /turf/simulated/floor/tiled/techfloor, /area/maintenance/lower/mining_eva) @@ -2313,6 +3157,33 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/mining_main/storage) +"afh" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 4 + }, +/obj/machinery/door/firedoor/glass, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/door/airlock/multi_tile/glass{ + dir = 1; + name = "West Hallway" + }, +/obj/effect/floor_decal/steeldecal/steel_decals_central1, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/tiled/monofloor, +/area/tether/surfacebase/atrium_one) "afi" = ( /obj/effect/floor_decal/steeldecal/steel_decals6{ dir = 1 @@ -2378,6 +3249,25 @@ "afo" = ( /turf/simulated/floor/tiled, /area/tether/surfacebase/mining_main/lobby) +"afp" = ( +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 10 + }, +/obj/effect/floor_decal/steeldecal/steel_decals6{ + dir = 6 + }, +/obj/structure/disposalpipe/junction, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/atrium_one) "afq" = ( /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/virgo3b, @@ -2390,6 +3280,17 @@ /obj/random/tech_supply, /turf/simulated/floor/tiled, /area/storage/primary) +"afs" = ( +/obj/structure/table/glass, +/obj/effect/floor_decal/borderfloor{ + dir = 1 + }, +/obj/effect/floor_decal/corner/brown/border{ + dir = 1 + }, +/obj/machinery/camera/network/cargo, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/mining_main/lobby) "aft" = ( /obj/machinery/camera/network/civilian{ dir = 2 @@ -2431,6 +3332,33 @@ }, /turf/simulated/floor/tiled, /area/storage/primary) +"afx" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 8 + }, +/obj/effect/floor_decal/corner/brown/border{ + dir = 8 + }, +/obj/effect/floor_decal/borderfloor/corner2{ + dir = 8 + }, +/obj/effect/floor_decal/corner/brown/bordercorner2{ + dir = 8 + }, +/obj/effect/floor_decal/steeldecal/steel_decals4{ + dir = 4 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 5 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 6 + }, +/obj/machinery/camera/network/cargo{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/mining_main/lobby) "afy" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -2449,6 +3377,20 @@ }, /turf/simulated/floor/tiled/steel_grid, /area/tether/surfacebase/mining_main/eva) +"afz" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 1 + }, +/obj/effect/floor_decal/corner/lightgrey/border{ + dir = 1 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 4 + }, +/obj/machinery/camera/network/tether, +/turf/simulated/floor/tiled, +/area/hallway/lower/first_west) "afA" = ( /obj/structure/catwalk, /turf/simulated/floor/tiled/techfloor, @@ -2511,6 +3453,20 @@ /obj/machinery/hologram/holopad, /turf/simulated/floor/tiled, /area/tether/surfacebase/mining_main/eva) +"afG" = ( +/obj/structure/bed/chair, +/obj/machinery/camera/network/civilian, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/tram) +"afH" = ( +/obj/effect/floor_decal/techfloor/orange{ + dir = 4 + }, +/obj/machinery/camera/network/civilian{ + dir = 9 + }, +/turf/simulated/floor/tiled/techfloor/grid, +/area/tether/surfacebase/tram) "afI" = ( /obj/machinery/atmospherics/pipe/manifold4w/hidden/supply, /obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers, @@ -2651,6 +3607,18 @@ "afT" = ( /turf/simulated/floor/tiled, /area/storage/primary) +"afU" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, +/obj/machinery/camera/network/civilian{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/tram) "afV" = ( /obj/machinery/atmospherics/unary/vent_pump/on, /turf/simulated/floor/tiled, @@ -2665,6 +3633,48 @@ }, /turf/simulated/floor, /area/maintenance/substation/mining) +"afY" = ( +/obj/machinery/camera/network/civilian, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/tram) +"afZ" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 8 + }, +/obj/effect/floor_decal/corner/grey/border{ + icon_state = "bordercolor"; + dir = 8 + }, +/obj/effect/floor_decal/borderfloor/corner2{ + dir = 10 + }, +/obj/machinery/camera/network/civilian{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/crew_quarters/visitor_laundry) +"aga" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 4 + }, +/obj/effect/floor_decal/corner/grey/border{ + icon_state = "bordercolor"; + dir = 4 + }, +/obj/machinery/vending/coffee, +/obj/machinery/camera/network/civilian{ + dir = 9 + }, +/turf/simulated/floor/tiled, +/area/crew_quarters/visitor_laundry) +"agb" = ( +/turf/simulated/shuttle/wall/voidcraft/green{ + hard_corner = 1 + }, +/area/tether/elevator) +"agc" = ( +/turf/simulated/floor/holofloor/tiled/dark, +/area/tether/elevator) "agd" = ( /obj/random/trash_pile, /turf/simulated/floor/tiled/techfloor, @@ -2689,6 +3699,18 @@ /obj/machinery/light, /turf/simulated/floor/tiled/steel_dirty, /area/tether/surfacebase/mining_main/ore) +"agh" = ( +/obj/turbolift_map_holder/tether{ + dir = 4 + }, +/turf/simulated/floor/holofloor/tiled/dark, +/area/tether/elevator) +"agi" = ( +/obj/structure/sign/deck/first, +/turf/simulated/shuttle/wall/voidcraft/green{ + hard_corner = 1 + }, +/area/tether/elevator) "agj" = ( /obj/effect/floor_decal/borderfloor{ dir = 10 @@ -2792,33 +3814,6 @@ /obj/machinery/vending/tool, /turf/simulated/floor/tiled, /area/storage/primary) -"agC" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/brown/border{ - dir = 8 - }, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 8 - }, -/obj/effect/floor_decal/corner/brown/bordercorner2{ - dir = 8 - }, -/obj/machinery/camera/network/mining{ - dir = 4 - }, -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 4 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 5 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 6 - }, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/mining_main/lobby) "agD" = ( /obj/effect/floor_decal/borderfloor{ dir = 4 @@ -3247,22 +4242,6 @@ }, /turf/simulated/floor/tiled, /area/hallway/lower/first_west) -"ahH" = ( -/obj/machinery/camera/network/civilian{ - dir = 2 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/obj/effect/floor_decal/corner/lightgrey/border{ - dir = 1 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/hallway/lower/first_west) "ahI" = ( /obj/machinery/status_display{ pixel_y = 30 @@ -3363,7 +4342,7 @@ /turf/simulated/floor/tiled, /area/hallway/lower/first_west) "ahR" = ( -/obj/machinery/camera/network/northern_star, +/obj/machinery/camera/network/tether, /obj/effect/floor_decal/borderfloor{ dir = 1 }, @@ -3531,7 +4510,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/camera/network/northern_star, +/obj/machinery/camera/network/tether, /obj/effect/floor_decal/corner/lightgrey/border{ dir = 1 }, @@ -3645,7 +4624,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/camera/network/northern_star, +/obj/machinery/camera/network/tether, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 4 }, @@ -4169,246 +5148,6 @@ }, /turf/simulated/floor/tiled, /area/hallway/lower/first_west) -"ajx" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/lightgrey/border, -/obj/effect/floor_decal/borderfloor/corner2, -/obj/effect/floor_decal/corner/lightgrey/bordercorner2, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 8 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/hallway/lower/first_west) -"ajy" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/lightgrey/border, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 8 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/hallway/lower/first_west) -"ajz" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/lightgrey/border, -/obj/machinery/atmospherics/pipe/manifold/hidden/supply, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 8 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 1 - }, -/obj/machinery/light, -/turf/simulated/floor/tiled, -/area/hallway/lower/first_west) -"ajB" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/lightgrey/border, -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 8 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/hallway/lower/first_west) -"ajC" = ( -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/lightgrey/border, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 8 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/hallway/lower/first_west) -"ajD" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/lightgrey/border, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 9 - }, -/obj/effect/floor_decal/corner/lightgrey/bordercorner2{ - dir = 9 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 8 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/hallway/lower/first_west) -"ajF" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/lightgrey/border, -/obj/effect/floor_decal/borderfloor/corner2, -/obj/effect/floor_decal/corner/lightgrey/bordercorner2, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 1 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/hallway/lower/first_west) -"ajG" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/lightgrey/border, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 8 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 1 - }, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 9 - }, -/obj/effect/floor_decal/corner/lightgrey/bordercorner2{ - dir = 9 - }, -/turf/simulated/floor/tiled, -/area/hallway/lower/first_west) -"ajI" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/lightgrey/border, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 8 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 1 - }, -/obj/effect/floor_decal/borderfloor/corner2, -/obj/effect/floor_decal/corner/lightgrey/bordercorner2, -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/north_stairs_one) -"ajJ" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/lightgrey/border, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 9 - }, -/obj/effect/floor_decal/corner/lightgrey/bordercorner2{ - dir = 9 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 8 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/north_stairs_one) -"ajK" = ( -/obj/effect/floor_decal/industrial/warning, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/north_stairs_one) -"ajL" = ( -/obj/machinery/light/small, -/obj/effect/floor_decal/industrial/warning/corner{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/manifold/hidden/supply, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/lightgrey/border, -/obj/effect/floor_decal/borderfloor/corner2, -/obj/effect/floor_decal/corner/lightgrey/bordercorner2, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 1 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/north_stairs_one) -"ajM" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/lightgrey/border, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 1 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/north_stairs_one) "ajN" = ( /obj/structure/catwalk, /obj/machinery/atmospherics/pipe/simple/visible/scrubbers, @@ -5263,7 +6002,7 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/north_stairs_one) "amu" = ( -/mob/living/simple_animal/fish/koi/poisonous, +/mob/living/simple_mob/animal/passive/fish/koi/poisonous, /turf/simulated/floor/water/pool, /area/tether/surfacebase/atrium_one) "amv" = ( @@ -5515,7 +6254,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/structure/disposalpipe/segment, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 5 }, /obj/effect/floor_decal/corner/lightgrey/border{ @@ -5537,7 +6276,7 @@ /obj/effect/floor_decal/borderfloor{ dir = 4 }, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 9 }, /obj/effect/floor_decal/corner/lightgrey/border{ @@ -6697,11 +7436,6 @@ }, /turf/simulated/floor/tiled, /area/crew_quarters/locker) -"aqx" = ( -/obj/structure/bed/chair, -/obj/machinery/camera/network/northern_star, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/tram) "aqz" = ( /obj/structure/bed/chair, /obj/machinery/status_display{ @@ -7233,13 +7967,6 @@ }, /turf/simulated/floor/tiled, /area/rnd/hallway) -"asj" = ( -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 10 - }, -/obj/effect/floor_decal/steeldecal/steel_decals4, -/turf/simulated/floor/tiled, -/area/rnd/hallway) "asl" = ( /obj/effect/floor_decal/steeldecal/steel_decals4{ dir = 6 @@ -7274,7 +8001,7 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 5 }, /obj/effect/floor_decal/corner/lightgrey/border{ @@ -7412,15 +8139,6 @@ /obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled, /area/tether/surfacebase/tram) -"asK" = ( -/obj/effect/floor_decal/techfloor/orange{ - dir = 4 - }, -/obj/machinery/camera/network/northern_star{ - dir = 9 - }, -/turf/simulated/floor/tiled/techfloor/grid, -/area/tether/surfacebase/tram) "asL" = ( /obj/effect/floor_decal/industrial/warning/corner, /obj/effect/floor_decal/industrial/warning, @@ -7473,11 +8191,6 @@ }, /turf/simulated/floor/tiled, /area/hallway/lower/first_west) -"asX" = ( -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/lightgrey/border, -/turf/simulated/floor/tiled, -/area/hallway/lower/first_west) "asY" = ( /obj/effect/floor_decal/borderfloor{ dir = 6 @@ -7857,11 +8570,6 @@ }, /turf/simulated/floor/tiled, /area/storage/primary) -"atW" = ( -/turf/simulated/shuttle/wall/voidcraft/green{ - hard_corner = 1 - }, -/area/tether/surfacebase/atrium_one) "atX" = ( /obj/effect/floor_decal/borderfloor{ dir = 8 @@ -8145,9 +8853,6 @@ /obj/machinery/atmospherics/pipe/simple/visible/yellow, /turf/simulated/floor/tiled/techfloor, /area/maintenance/lower/xenoflora) -"auF" = ( -/turf/simulated/floor/holofloor/tiled/dark, -/area/tether/surfacebase/atrium_one) "auG" = ( /obj/structure/closet/firecloset/full/double, /turf/simulated/floor/tiled/techfloor, @@ -8227,7 +8932,7 @@ /area/tether/surfacebase/atrium_one) "auN" = ( /obj/effect/floor_decal/borderfloor, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 1 }, /obj/effect/floor_decal/corner/lightgrey/border, @@ -9268,30 +9973,6 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/atrium_one) -"awW" = ( -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/structure/cable/green{ - d1 = 2; - d2 = 8; - icon_state = "2-8" - }, -/obj/structure/cable{ - d1 = 1; - d2 = 8; - icon_state = "1-8" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/structure/disposalpipe/segment{ - dir = 1; - icon_state = "pipe-c" - }, -/turf/simulated/floor/tiled, -/area/hallway/lower/first_west) "awX" = ( /obj/effect/floor_decal/borderfloor{ dir = 1 @@ -9339,18 +10020,6 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/atrium_one) -"axb" = ( -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/machinery/atmospherics/unary/vent_pump/on, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/hallway/lower/first_west) "axc" = ( /obj/machinery/door/firedoor/glass, /obj/machinery/cryopod/robot/door/tram, @@ -9399,18 +10068,6 @@ /obj/machinery/reagentgrinder, /turf/simulated/floor/tiled, /area/rnd/xenobiology/xenoflora) -"axk" = ( -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/machinery/atmospherics/unary/vent_scrubber/on, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/hallway/lower/first_west) "axl" = ( /obj/structure/reagent_dispensers/watertank, /obj/item/weapon/reagent_containers/glass/bucket, @@ -9477,38 +10134,6 @@ }, /turf/simulated/floor/tiled, /area/rnd/xenobiology/xenoflora) -"axs" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/structure/cable/green{ - d1 = 1; - d2 = 8; - icon_state = "1-8" - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/hallway/lower/first_west) -"axt" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/structure/cable/green{ - d1 = 2; - d2 = 8; - icon_state = "2-8" - }, -/obj/structure/disposalpipe/sortjunction{ - name = "Primary Tool Storage"; - icon_state = "pipe-j1s"; - dir = 8; - sortType = "Primary Tool Storage" - }, -/turf/simulated/floor/tiled, -/area/hallway/lower/first_west) "axu" = ( /obj/machinery/atmospherics/pipe/simple/visible{ dir = 4 @@ -9618,18 +10243,6 @@ /obj/random/junk, /turf/simulated/floor/tiled/techfloor, /area/maintenance/lower/xenoflora) -"axD" = ( -/obj/turbolift_map_holder/tether{ - dir = 4 - }, -/turf/simulated/floor/holofloor/tiled/dark, -/area/tether/surfacebase/atrium_one) -"axE" = ( -/obj/structure/sign/deck/first, -/turf/simulated/shuttle/wall/voidcraft/green{ - hard_corner = 1 - }, -/area/tether/surfacebase/atrium_one) "axF" = ( /obj/machinery/hologram/holopad, /turf/simulated/floor/tiled, @@ -9681,7 +10294,7 @@ /area/tether/surfacebase/atrium_one) "axK" = ( /obj/machinery/atmospherics/unary/vent_pump/on, -/obj/machinery/camera/network/northern_star, +/obj/machinery/camera/network/tether, /obj/structure/disposalpipe/segment{ dir = 4 }, @@ -10169,15 +10782,6 @@ }, /turf/simulated/floor/tiled, /area/rnd/xenobiology/xenoflora/lab_atmos) -"ayG" = ( -/obj/structure/table/glass, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/mauve/border, -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) "ayH" = ( /obj/structure/table/glass, /obj/effect/floor_decal/borderfloor{ @@ -10409,17 +11013,6 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/atrium_one) -"aza" = ( -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/effect/floor_decal/steeldecal/steel_decals6, -/obj/machinery/atmospherics/pipe/manifold/hidden/supply, -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, -/turf/simulated/floor/tiled, -/area/hallway/lower/first_west) "azb" = ( /obj/effect/floor_decal/borderfloor, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ @@ -10546,29 +11139,6 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/atrium_one) -"azj" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/power/apc{ - dir = 2; - name = "south bump"; - pixel_y = -28 - }, -/obj/structure/cable/green, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/lightgrey/border, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 8 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/hallway/lower/first_west) "azk" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/floor_decal/industrial/outline/blue, @@ -10661,38 +11231,6 @@ /obj/machinery/door/firedoor/glass/hidden/steel, /turf/simulated/floor/tiled, /area/rnd/hallway) -"azt" = ( -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply, -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 5 - }, -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/hallway/lower/first_west) -"azu" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/effect/floor_decal/steeldecal/steel_decals_central1, -/obj/machinery/door/airlock/multi_tile/glass{ - dir = 1; - name = "West Hallway" - }, -/turf/simulated/floor/tiled/monofloor, -/area/tether/surfacebase/north_stairs_one) "azv" = ( /obj/machinery/atmospherics/unary/vent_scrubber/on{ dir = 1 @@ -10799,29 +11337,6 @@ }, /turf/simulated/floor/tiled, /area/crew_quarters/locker/laundry_arrival) -"azO" = ( -/obj/structure/cable{ - icon_state = "0-4" - }, -/obj/machinery/power/apc{ - dir = 2; - name = "south bump"; - pixel_y = -28 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/lightgrey/border, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 1 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/north_stairs_one) "azP" = ( /obj/effect/floor_decal/borderfloor, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ @@ -10830,7 +11345,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 1 }, /obj/effect/floor_decal/corner/lightgrey/border, @@ -10849,7 +11364,7 @@ /obj/effect/floor_decal/borderfloor{ dir = 4 }, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 8; icon_state = "camera" }, @@ -10904,28 +11419,6 @@ /obj/machinery/chem_master, /turf/simulated/floor/tiled, /area/rnd/xenobiology/xenoflora) -"azW" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/lightgrey/border, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 1 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 8 - }, -/obj/structure/extinguisher_cabinet{ - dir = 1; - icon_state = "extinguisher_closed"; - pixel_y = -32 - }, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/north_stairs_one) "azX" = ( /obj/structure/disposaloutlet, /obj/structure/disposalpipe/trunk{ @@ -10933,61 +11426,6 @@ }, /turf/simulated/floor/reinforced, /area/rnd/xenobiology) -"azZ" = ( -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8"; - pixel_x = 0 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/lightgrey/border, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 9 - }, -/obj/effect/floor_decal/corner/lightgrey/bordercorner2{ - dir = 9 - }, -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 10 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 1 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/north_stairs_one) -"aAa" = ( -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8"; - pixel_x = 0 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/lightgrey/border, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 1 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/north_stairs_one) "aAb" = ( /obj/structure/grille, /obj/structure/window/reinforced/full, @@ -11012,25 +11450,6 @@ }, /turf/simulated/floor/tiled, /area/rnd/hallway) -"aAd" = ( -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8"; - pixel_x = 0 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 10 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 10 - }, -/obj/structure/disposalpipe/segment, -/obj/effect/floor_decal/steeldecal/steel_decals6{ - dir = 6 - }, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/atrium_one) "aAg" = ( /obj/machinery/portable_atmospherics/hydroponics, /obj/effect/floor_decal/corner/green{ @@ -11068,30 +11487,6 @@ /obj/machinery/recharge_station, /turf/simulated/floor/tiled, /area/rnd/hallway) -"aAl" = ( -/obj/effect/floor_decal/spline/plain{ - dir = 4 - }, -/obj/machinery/door/firedoor/glass, -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8"; - pixel_x = 0 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/door/airlock/multi_tile/glass{ - dir = 1; - name = "West Hallway" - }, -/obj/effect/floor_decal/steeldecal/steel_decals_central1, -/turf/simulated/floor/tiled/monofloor, -/area/tether/surfacebase/atrium_one) "aAm" = ( /obj/effect/floor_decal/borderfloor{ dir = 1 @@ -12199,7 +12594,7 @@ "aCA" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/floor_decal/rust, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 4 }, /obj/machinery/atmospherics/unary/vent_scrubber/on{ @@ -12232,14 +12627,6 @@ }, /turf/simulated/floor/tiled/techfloor, /area/maintenance/lower/atmos) -"aCG" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/railing, -/obj/structure/railing{ - dir = 4 - }, -/turf/simulated/floor/tiled/techfloor, -/area/maintenance/lower/locker_room) "aCH" = ( /obj/effect/floor_decal/borderfloor{ dir = 4 @@ -12298,14 +12685,6 @@ /obj/machinery/door/firedoor/glass, /turf/simulated/floor/plating, /area/maintenance/lower/solars) -"aCP" = ( -/obj/structure/cable{ - d1 = 2; - d2 = 8; - icon_state = "2-8" - }, -/turf/simulated/floor/tiled/techfloor, -/area/maintenance/lower/vacant_site) "aCQ" = ( /obj/structure/cable{ d1 = 1; @@ -12774,14 +13153,6 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/north_stairs_one) -"aEk" = ( -/obj/machinery/door/airlock/maintenance/common{ - name = "Trash Pit Access"; - req_one_access = list(26,48) - }, -/obj/structure/catwalk, -/turf/simulated/floor/plating, -/area/maintenance/lower/trash_pit) "aEl" = ( /obj/machinery/portable_atmospherics/powered/scrubber/huge/stationary{ frequency = 1379; @@ -13346,7 +13717,7 @@ /turf/simulated/floor/tiled/techfloor, /area/maintenance/lower/research) "aFv" = ( -/mob/living/simple_animal/retaliate/gaslamp, +/mob/living/simple_mob/animal/space/gaslamp, /turf/simulated/floor/outdoors/grass/sif/virgo3b, /area/tether/surfacebase/outside/outside1) "aFw" = ( @@ -13453,7 +13824,7 @@ d2 = 2; icon_state = "1-2" }, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 8; icon_state = "camera" }, @@ -15423,15 +15794,6 @@ }, /turf/simulated/floor/tiled/techfloor, /area/engineering/atmos/processing) -"aLA" = ( -/obj/machinery/alarm{ - dir = 4; - icon_state = "alarm0"; - pixel_x = -22; - pixel_y = 0 - }, -/turf/simulated/floor/plating, -/area/vacant/vacant_site) "aLB" = ( /obj/structure/catwalk, /obj/machinery/firealarm{ @@ -15821,20 +16183,6 @@ /obj/random/trash_pile, /turf/simulated/floor/tiled/techfloor, /area/maintenance/lower/xenoflora) -"aQK" = ( -/obj/effect/floor_decal/industrial/loading{ - dir = 8 - }, -/obj/effect/floor_decal/steeldecal/steel_decals6{ - dir = 9 - }, -/obj/effect/floor_decal/steeldecal/steel_decals6{ - dir = 6 - }, -/turf/simulated/floor/tiled{ - icon_state = "monotile" - }, -/area/security/checkpoint) "aQM" = ( /obj/effect/floor_decal/industrial/outline/yellow, /turf/simulated/floor/tiled{ @@ -16320,7 +16668,7 @@ /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 8; icon_state = "camera" }, @@ -17942,7 +18290,7 @@ /obj/effect/floor_decal/borderfloor{ dir = 1 }, -/obj/machinery/camera/network/northern_star, +/obj/machinery/camera/network/tether, /obj/effect/floor_decal/corner/lightgrey/border{ dir = 1 }, @@ -17970,10 +18318,6 @@ }, /turf/simulated/floor/tiled, /area/crew_quarters/visitor_dining) -"bfC" = ( -/obj/machinery/camera/network/northern_star, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/tram) "bfF" = ( /obj/machinery/status_display{ pixel_y = 30 @@ -18170,7 +18514,7 @@ icon_state = "4-8"; pixel_x = 0 }, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 1 }, /obj/effect/floor_decal/corner/lightgrey/border, @@ -18286,18 +18630,6 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/atrium_one) -"bhj" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/structure/disposalpipe/segment{ - dir = 8; - icon_state = "pipe-c" - }, -/obj/machinery/camera/network/northern_star{ - dir = 5 - }, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/tram) "bhk" = ( /obj/structure/cable{ d1 = 2; @@ -18328,15 +18660,6 @@ /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plating, /area/maintenance/lower/solars) -"bht" = ( -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/machinery/door/airlock/maintenance/common, -/turf/simulated/floor/plating, -/area/maintenance/lower/solars) "bhw" = ( /obj/structure/cable{ d1 = 4; @@ -19818,20 +20141,6 @@ }, /turf/simulated/floor/tiled, /area/crew_quarters/visitor_dining) -"brv" = ( -/obj/structure/table/marble, -/obj/machinery/door/window{ - dir = 8; - req_one_access = list(25) - }, -/obj/machinery/door/blast/shutters{ - dir = 8; - id = "cafe"; - layer = 3.1; - name = "Cafe Shutters" - }, -/turf/simulated/floor/tiled, -/area/crew_quarters/visitor_dining) "brw" = ( /obj/structure/window/reinforced, /obj/structure/table/glass, @@ -20101,24 +20410,6 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/atrium_one) -"btx" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/structure/disposalpipe/segment, -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/obj/effect/floor_decal/corner/lightgrey/border{ - dir = 4 - }, -/obj/machinery/camera/network/civilian{ - dir = 9 - }, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/public_garden) "btD" = ( /obj/effect/floor_decal/steeldecal/steel_decals6{ dir = 5 @@ -21303,23 +21594,6 @@ }, /turf/simulated/floor/plating, /area/vacant/vacant_site/east) -"bAO" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - 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 - }, -/obj/structure/catwalk, -/obj/machinery/door/airlock/maintenance/common, -/turf/simulated/floor/tiled/techfloor, -/area/maintenance/lower/locker_room) "bAP" = ( /obj/effect/floor_decal/steeldecal/steel_decals4{ dir = 10 @@ -21416,29 +21690,6 @@ }, /turf/simulated/floor/tiled/steel_grid, /area/rnd/xenobiology) -"bBl" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/structure/disposalpipe/segment, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 5 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 6 - }, -/turf/simulated/floor/tiled, -/area/rnd/hallway) "bBy" = ( /obj/effect/floor_decal/borderfloor{ dir = 4 @@ -22185,7 +22436,7 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/atrium_one) "bLY" = ( -/obj/machinery/camera/network/northern_star, +/obj/machinery/camera/network/tether, /obj/effect/floor_decal/borderfloor{ dir = 5 }, @@ -22879,23 +23130,6 @@ }, /turf/simulated/floor/tiled/techfloor, /area/maintenance/lower/atmos) -"bRx" = ( -/obj/structure/cable/cyan{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/machinery/door/airlock/maintenance/engi{ - name = "Drone Bay" - }, -/obj/machinery/atmospherics/pipe/simple/visible/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/turf/simulated/floor/tiled/techfloor, -/area/maintenance/lower/atmos) "bRy" = ( /obj/machinery/door/airlock/glass_external/public, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ @@ -23480,7 +23714,7 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 4 }, /obj/structure/disposalpipe/segment, @@ -24311,7 +24545,7 @@ /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 9 }, /obj/structure/disposalpipe/junction{ @@ -25692,19 +25926,6 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/atrium_one) -"cft" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/grey/border{ - icon_state = "bordercolor"; - dir = 8 - }, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 10 - }, -/turf/simulated/floor/tiled, -/area/crew_quarters/visitor_laundry) "cfv" = ( /turf/simulated/floor/tiled, /area/crew_quarters/visitor_laundry) @@ -25785,14 +26006,6 @@ }, /turf/simulated/floor/tiled, /area/crew_quarters/visitor_laundry) -"cfM" = ( -/obj/effect/floor_decal/steeldecal/steel_decals_central1{ - dir = 1 - }, -/turf/simulated/floor/tiled/monofloor{ - dir = 1 - }, -/area/crew_quarters/visitor_laundry) "cfN" = ( /obj/machinery/washing_machine, /turf/simulated/floor/tiled, @@ -25864,12 +26077,6 @@ }, /turf/simulated/floor/plating, /area/crew_quarters/visitor_laundry) -"cgb" = ( -/obj/machinery/door/airlock/maintenance/common{ - name = "Tram Maintenance Access" - }, -/turf/simulated/floor/tiled, -/area/crew_quarters/visitor_dining) "cge" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, @@ -26054,31 +26261,6 @@ }, /turf/simulated/floor/lino, /area/crew_quarters/visitor_dining) -"cgw" = ( -/obj/machinery/door/airlock/multi_tile/glass{ - autoclose = 1; - dir = 2; - id_tag = null; - name = "Laundry"; - req_access = list() - }, -/obj/effect/floor_decal/steeldecal/steel_decals_central1, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/simulated/floor/tiled/monofloor, -/area/crew_quarters/visitor_laundry) "cgz" = ( /obj/structure/cable/green{ d1 = 4; @@ -26625,17 +26807,6 @@ /obj/machinery/atmospherics/unary/vent_pump/on, /turf/simulated/floor/wood, /area/crew_quarters/sleep/Dorm_6) -"chW" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/obj/effect/floor_decal/corner/grey/border{ - icon_state = "bordercolor"; - dir = 4 - }, -/obj/machinery/vending/coffee, -/turf/simulated/floor/tiled, -/area/crew_quarters/visitor_laundry) "chY" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/effect/floor_decal/spline/plain{ @@ -27109,11 +27280,9 @@ /obj/structure/closet/crate, /obj/item/weapon/bedsheet/green, /obj/machinery/alarm{ - breach_detection = 0; dir = 8; pixel_x = 25; - pixel_y = 0; - report_danger_level = 0 + pixel_y = 0 }, /obj/machinery/light{ dir = 4; @@ -27488,22 +27657,6 @@ }, /turf/simulated/floor/tiled, /area/hallway/lower/first_west) -"eVp" = ( -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/structure/cable/green{ - d1 = 2; - d2 = 8; - icon_state = "2-8" - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/hallway/lower/first_west) "fbF" = ( /obj/structure/cable{ icon_state = "1-2" @@ -27832,19 +27985,6 @@ /obj/structure/window/reinforced, /turf/simulated/floor/tiled, /area/tether/surfacebase/public_garden_one) -"kdx" = ( -/obj/structure/cable/ender{ - icon_state = "1-2"; - id = "surface-solars" - }, -/obj/structure/railing{ - dir = 8 - }, -/obj/structure/railing{ - dir = 4 - }, -/turf/simulated/floor/plating, -/area/tether/surfacebase/outside/outside1) "kfl" = ( /obj/structure/cable/green{ d1 = 4; @@ -27898,11 +28038,9 @@ "lCL" = ( /obj/structure/catwalk, /obj/machinery/alarm{ - breach_detection = 0; dir = 8; pixel_x = 25; - pixel_y = 0; - report_danger_level = 0 + pixel_y = 0 }, /turf/simulated/floor/plating, /area/maintenance/lower/public_garden_maintenence) @@ -28370,28 +28508,6 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/atrium_one) -"tbZ" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/lightgrey/border, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 8 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 1 - }, -/obj/structure/extinguisher_cabinet{ - dir = 1; - icon_state = "extinguisher_closed"; - pixel_y = -32 - }, -/turf/simulated/floor/tiled, -/area/hallway/lower/first_west) "tec" = ( /obj/machinery/portable_atmospherics/hydroponics, /obj/machinery/atmospherics/portables_connector, @@ -28500,17 +28616,6 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/public_garden_one) -"uyO" = ( -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/hallway/lower/first_west) "uEZ" = ( /obj/machinery/hologram/holopad, /turf/simulated/floor/tiled, @@ -32471,7 +32576,7 @@ ars ars awc axf -bht +abB azr aBv azU @@ -33039,7 +33144,7 @@ amU amU amU axf -bhp +aaT azr bkd bmv @@ -34026,7 +34131,7 @@ apt aqf aSt arA -asj +abg asU atF arG @@ -34435,7 +34540,7 @@ aah aah aah ahl -ahH +afz aiE ajq ako @@ -34453,7 +34558,7 @@ ako ako ako ako -asX +acJ atI arG aVu @@ -34469,7 +34574,7 @@ aCX auu bvO byA -bBl +acu bEf bFS bHV @@ -34873,7 +34978,7 @@ akV anB akX aor -aLA +akX apw aqj aSP @@ -35420,7 +35525,7 @@ wIm thL kuC xED -btx +aeT qGm aYz dYl @@ -35430,8 +35535,8 @@ mUG nCB hqU lWW -awW -aza +acT +adj aBc aCw aCw @@ -35572,8 +35677,8 @@ gXh gXh ahl sCz -uyO -ajx +awH +adk akq ala ala @@ -35714,8 +35819,8 @@ aah aah ahl avN -uyO -ajy +awH +adu ahl alb akX @@ -35856,8 +35961,8 @@ aah aah ahl ahL -axb -ajz +acV +adF ahl akV akV @@ -35998,8 +36103,8 @@ aah aah ahl ahN -eVp -azj +ada +adH ahl akV akV @@ -36140,8 +36245,8 @@ aah aah ahl ahL -uyO -tbZ +awH +adI ahl akV akV @@ -36282,8 +36387,8 @@ aah aah ahl ahL -uyO -ajy +awH +adu ahl akV akV @@ -36424,8 +36529,8 @@ aah aah ahl ePE -uyO -ajy +awH +adu ahl akV akV @@ -36566,8 +36671,8 @@ aah aah ahl ahR -uyO -ajy +awH +adu ahl akV akV @@ -36708,8 +36813,8 @@ aah aah ahl ahL -uyO -ajy +awH +adu ahl akV akV @@ -36731,7 +36836,7 @@ auz avw beQ bgd -ayG +abD atf blx aAZ @@ -36850,8 +36955,8 @@ aah aah ahl ahK -axk -ajB +add +adJ ahl akV akV @@ -36992,8 +37097,8 @@ aah aah ahl ahL -uyO -ajy +awH +adu ahl akV akV @@ -37134,8 +37239,8 @@ aeW aeW aeW ahL -uyO -ajy +awH +adu ahl akV akV @@ -37276,8 +37381,8 @@ agI atU aeW ahS -uyO -ajy +awH +adu ahl akV akV @@ -37418,8 +37523,8 @@ agJ atV auP avZ -axs -ajC +adh +adO ahl akV akV @@ -37442,7 +37547,7 @@ ati ati ati ati -ati +aBe aAt aBd aBV @@ -37560,8 +37665,8 @@ afT agX ahn ahU -uyO -ajy +awH +adu akt akt akt @@ -37584,7 +37689,7 @@ avA avA avA ayJ -ati +aBe aAu aBd aBd @@ -37702,8 +37807,8 @@ aoB agY ahn ahL -uyO -ajy +awH +adu aku alc aDW @@ -37719,14 +37824,14 @@ alg alg alg aah -atj -atW -atW -atW -atW -atW -atW -atj +ati +agb +agb +agb +agb +agb +agb +aBe aAu azI aah @@ -37844,8 +37949,8 @@ afT agX ahn ahS -uyO -ajD +awH +adW aku ald ald @@ -37861,14 +37966,14 @@ alg aah aah aah -atj -atW -auF -auF -auF -axD -atW -atj +ati +agb +agc +agc +agc +agh +agb +aBe aAu azI aah @@ -37986,8 +38091,8 @@ agu atZ aho ahV -axt -azt +adi +aeq aBo aCz aDX @@ -38003,15 +38108,15 @@ alg aah aah aah -atj -atW -auF -auF -auF -auF -atW -atj -aAu +ati +agb +agc +agc +agc +agc +agb +aBe +aci azI aah aah @@ -38129,7 +38234,7 @@ atY aeW ahU aiN -ajF +aet aku ald ald @@ -38145,14 +38250,14 @@ alg aah aah aah -atj -atW -auF -auF -auF -auF -atW -atj +ati +agb +agc +agc +agc +agc +agb +aBe aAu azI aah @@ -38271,7 +38376,7 @@ aeW aeW ahW aiO -ajG +aew aku alf aDY @@ -38287,14 +38392,14 @@ alg aah aah aah -atj -atW -auF -auF -auF -auF -atW -atj +ati +agb +agc +agc +agc +agc +agb +aBe aAu azI aah @@ -38413,7 +38518,7 @@ abT abT ahX aiP -azu +aey akw alg alg @@ -38430,12 +38535,12 @@ aah aah aah atj -atW -atW -auF -auF -axE -atW +agb +agb +agc +agc +agi +agb atj aAu azI @@ -38555,7 +38660,7 @@ afA afA ahY aiQ -ajI +aez akx alh alO @@ -38653,7 +38758,7 @@ aaa "} (71,1,1) = {" aaa -kdx +acN fAq frA frA @@ -38697,7 +38802,7 @@ afA ahp ahX axw -ajJ +aeG ahX ahX ahX @@ -38839,7 +38944,7 @@ afA ahq ahX aiS -ajK +aeH aky ali ahX @@ -38878,7 +38983,7 @@ aBe aBe aBe aBe -bRx +acv aBe aIv aIB @@ -38981,7 +39086,7 @@ ahb ahr ahX axA -ajK +aeH aky ali ahX @@ -39123,7 +39228,7 @@ afA ahq ahX axK -ajL +aeK aBy ahX ahX @@ -39265,7 +39370,7 @@ afA ahs ahZ aiV -ajM +aeO aBx alj aky @@ -39394,7 +39499,7 @@ abn abn abn abT -adO +aaS abT akz alH @@ -39407,7 +39512,7 @@ afA ahs ahX axO -azW +aeP ahX alk aEe @@ -39549,7 +39654,7 @@ asv avh aia aiX -azO +aeX ahX ahX ahX @@ -39691,7 +39796,7 @@ abT abT ahX aiY -aAa +afa ahX ayV agM @@ -39833,7 +39938,7 @@ aah aah ahX aiZ -azZ +afc ahX ayV agM @@ -39975,7 +40080,7 @@ aah agM agM aja -aAl +afh agM agM agM @@ -40117,7 +40222,7 @@ aah agM awi axQ -aAd +afp akB all alQ @@ -40996,7 +41101,7 @@ azK aAA aBj avP -aCG +aco bse aAG aAG @@ -41374,8 +41479,8 @@ aah aah aar aaI -aaS -aaS +aaC +aaC abE abM acg @@ -41516,7 +41621,7 @@ aah aah aar aaI -aaS +aaC abb abh abM @@ -41531,7 +41636,7 @@ afk anL agl agx -agC +afx agN ahd ahv @@ -41658,7 +41763,7 @@ aah aah aar aaJ -aaS +aaC abc abG abL @@ -41710,7 +41815,7 @@ aCI aCI aCI aAG -bAO +acs aAG bgr bgr @@ -41800,7 +41905,7 @@ aah aah aar aaK -aaS +aaC abq abF abL @@ -42226,7 +42331,7 @@ aah aah aar aaI -aaS +aaC abs abO acP @@ -42368,7 +42473,7 @@ aah aah aar aaI -aaS +aaC abh abN abM @@ -42510,7 +42615,7 @@ aah aah aar aaJ -aaS +aaC abi abU abL @@ -42549,7 +42654,7 @@ atp auf atp aLp -aQK +abx aLJ bdV ayb @@ -42652,7 +42757,7 @@ aad aah aar aaM -aaS +aaC abt abQ abP @@ -42662,7 +42767,7 @@ afL adE aeg abP -aeT +afs afo afo agr @@ -42959,7 +43064,7 @@ awr ayq ajZ ahx -aCP +aaW alU amy alr @@ -43117,7 +43222,7 @@ atp auT awM aLJ -aQM +abA atp biv bhi @@ -43439,8 +43544,8 @@ cdd cjs ceM ceM -cfM -cgw +acw +acz ceM chQ chQ @@ -43580,7 +43685,7 @@ cce cda cjs ceK -cft +afZ cfL cgk chl @@ -43954,7 +44059,7 @@ ajl aka ajl ajl -aEk +abf alY amR alr @@ -44231,7 +44336,7 @@ aah aaU abH agT -abH +aaV agT agT aaU @@ -44404,7 +44509,7 @@ apP apP aFc aFc -brv +acr lHO lHO lHO @@ -44550,7 +44655,7 @@ arm cfj cfz arm -cgb +act bdk cgt bdk @@ -44578,7 +44683,7 @@ cfx cfU cfv chu -chW +aga ciK cjA ceM @@ -44673,7 +44778,7 @@ aah aah aah apP -aqx +afG arm arm arm @@ -44687,7 +44792,7 @@ azl azR avb apP -bfC +afY arm cfi cfy @@ -45108,7 +45213,7 @@ atu atu avX axd -bhj +afU azo azS aAJ @@ -46806,7 +46911,7 @@ apR aqG aTI aqG -asK +afH aTI aqG aqG @@ -46818,7 +46923,7 @@ aTI aqG aqG aTI -asK +afH aqG aTI aqG diff --git a/maps/tether/tether-02-surface2.dmm b/maps/tether/tether-02-surface2.dmm index f95e5e4bf8..4caca3d74b 100644 --- a/maps/tether/tether-02-surface2.dmm +++ b/maps/tether/tether-02-surface2.dmm @@ -376,9 +376,9 @@ /obj/item/weapon/handcuffs/legcuffs/fuzzy, /obj/item/weapon/handcuffs/fuzzy, /obj/item/clothing/mask/balaclava, -/obj/item/clothing/gloves/combat{ - desc = "These gloves are insulated with rubber."; - name = "black insulated gloves" +/obj/item/clothing/gloves/black{ + desc = "They seem to be made of rubber-like material, though insulation quality is doubtful"; + name = "elastic black gloves" }, /obj/item/clothing/under/fluff/latexmaid, /turf/simulated/floor/tiled/techfloor, @@ -478,6 +478,9 @@ dir = 1 }, /obj/effect/floor_decal/rust, +/obj/machinery/alarm{ + pixel_y = 22 + }, /turf/simulated/floor/tiled/techfloor, /area/maintenance/lower/mining) "bj" = ( @@ -1174,14 +1177,17 @@ /turf/simulated/floor/tiled/techfloor, /area/maintenance/lower/mining) "cU" = ( -/obj/structure/catwalk, -/obj/machinery/alarm{ - dir = 8; - icon_state = "alarm0"; - pixel_x = 24 +/obj/effect/floor_decal/borderfloor{ + dir = 1 }, -/turf/simulated/floor/tiled/techfloor, -/area/maintenance/lower/mining) +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/alarm{ + pixel_y = 22 + }, +/turf/simulated/floor/tiled/techmaint, +/area/tether/surfacebase/atrium_two) "cV" = ( /obj/effect/floor_decal/corner_steel_grid{ dir = 10 @@ -2193,7 +2199,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/camera/network/northern_star, +/obj/machinery/camera/network/tether, /turf/simulated/floor/tiled/techmaint, /area/tether/surfacebase/atrium_two) "fe" = ( @@ -2400,7 +2406,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/camera/network/northern_star, +/obj/machinery/camera/network/tether, /turf/simulated/floor/tiled/techmaint, /area/tether/surfacebase/atrium_two) "fr" = ( @@ -2616,22 +2622,25 @@ /turf/simulated/floor/tiled/techfloor/grid, /area/maintenance/lower/north) "fQ" = ( -/obj/effect/floor_decal/techfloor{ +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 1 }, -/obj/effect/floor_decal/techfloor, -/obj/effect/floor_decal/techfloor/hole/right{ +/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 1 }, /obj/structure/cable{ - icon_state = "4-8" + icon_state = "2-4" }, -/obj/structure/disposalpipe/segment{ - dir = 4 +/obj/machinery/alarm{ + pixel_y = 22 }, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/tiled/techfloor, -/area/maintenance/lower/north) +/turf/simulated/floor/plating, +/area/tether/surfacebase/public_garden_two) "fR" = ( /obj/effect/floor_decal/techfloor{ dir = 1 @@ -3168,7 +3177,7 @@ /turf/simulated/wall, /area/tether/surfacebase/north_staires_two) "hd" = ( -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 4 }, /turf/simulated/open, @@ -3210,7 +3219,7 @@ /obj/effect/floor_decal/borderfloor/corner2{ dir = 10 }, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 4 }, /turf/simulated/floor/tiled/techmaint, @@ -3222,7 +3231,7 @@ /obj/effect/floor_decal/borderfloor/corner2{ dir = 6 }, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 9 }, /turf/simulated/floor/tiled/techmaint, @@ -4594,7 +4603,7 @@ /obj/effect/floor_decal/borderfloor{ dir = 8 }, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 4 }, /turf/simulated/floor/tiled/techmaint, @@ -4603,7 +4612,7 @@ /obj/effect/floor_decal/borderfloor{ dir = 4 }, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 9 }, /turf/simulated/floor/tiled/techmaint, @@ -4636,15 +4645,21 @@ /turf/simulated/floor/tiled/techfloor, /area/maintenance/lower/bar) "kl" = ( -/obj/structure/railing{ - dir = 1 +/obj/machinery/door/airlock/maintenance/engi, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8" }, -/obj/effect/floor_decal/techfloor{ +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/obj/effect/floor_decal/rust, -/turf/simulated/floor/tiled/techfloor, -/area/maintenance/lower/bar) +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/plating, +/area/gateway) "km" = ( /obj/item/toy/plushie/kitten{ desc = "An odd appearing, cryptic plush of a cat."; @@ -5144,7 +5159,7 @@ /turf/simulated/shuttle/wall/voidcraft/green{ hard_corner = 1 }, -/area/tether/surfacebase/atrium_two) +/area/tether/elevator) "lt" = ( /obj/effect/floor_decal/techfloor/corner{ dir = 4 @@ -5354,21 +5369,24 @@ /turf/simulated/floor, /area/maintenance/substation/research) "lM" = ( -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/machinery/door/airlock/engineering{ - name = "Science Substation"; - req_one_access = list(11,24,47) - }, -/obj/machinery/door/firedoor, /obj/structure/cable{ - icon_state = "4-8" + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 }, -/turf/simulated/floor, -/area/maintenance/substation/research) +/obj/effect/decal/cleanable/dirt, +/obj/effect/floor_decal/rust, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/alarm{ + dir = 4; + icon_state = "alarm0"; + pixel_x = -22; + pixel_y = 0 + }, +/turf/simulated/floor/plating, +/area/gateway) "lN" = ( /obj/machinery/atmospherics/pipe/simple/visible/supply{ dir = 6 @@ -5431,7 +5449,7 @@ /area/maintenance/lower/rnd) "lQ" = ( /turf/simulated/floor/holofloor/tiled/dark, -/area/tether/surfacebase/atrium_two) +/area/tether/elevator) "lR" = ( /obj/effect/floor_decal/borderfloor{ dir = 1 @@ -5634,7 +5652,7 @@ /obj/effect/floor_decal/borderfloor{ dir = 1 }, -/obj/machinery/camera/network/northern_star, +/obj/machinery/camera/network/tether, /obj/machinery/firealarm{ dir = 2; layer = 3.3; @@ -5855,24 +5873,26 @@ /turf/simulated/floor, /area/maintenance/substation/research) "mM" = ( +/obj/effect/floor_decal/techfloor{ + dir = 1 + }, +/obj/effect/floor_decal/techfloor, +/obj/effect/floor_decal/techfloor/hole/right{ + dir = 1 + }, /obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8"; - pixel_x = 0 - }, -/obj/machinery/door/airlock/engineering{ - name = "Science Substation"; - req_one_access = list(11,24,47) - }, -/obj/machinery/door/firedoor, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; icon_state = "4-8" }, -/turf/simulated/floor, -/area/maintenance/substation/research) +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/alarm{ + dir = 1; + pixel_y = -25 + }, +/turf/simulated/floor/tiled/techfloor, +/area/maintenance/lower/north) "mN" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/manifold/visible/supply{ @@ -6106,7 +6126,7 @@ /obj/structure/cable{ icon_state = "4-8" }, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 1 }, /turf/simulated/floor/tiled/techfloor, @@ -6167,14 +6187,20 @@ /turf/simulated/floor/tiled/techfloor, /area/maintenance/asmaint2) "nj" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 10 +/obj/structure/railing{ + dir = 1 }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 10 +/obj/effect/floor_decal/techfloor{ + dir = 4 }, -/turf/simulated/floor/tiled, -/area/rnd/research/testingrange) +/obj/effect/floor_decal/rust, +/obj/machinery/alarm{ + dir = 8; + icon_state = "alarm0"; + pixel_x = 24 + }, +/turf/simulated/floor/tiled/techfloor, +/area/maintenance/lower/bar) "nk" = ( /obj/machinery/recharger/wallcharger{ pixel_x = 4; @@ -6276,7 +6302,7 @@ /turf/simulated/shuttle/wall/voidcraft/green{ hard_corner = 1 }, -/area/tether/surfacebase/atrium_two) +/area/tether/elevator) "nw" = ( /obj/machinery/door/firedoor/glass/hidden/steel{ dir = 1 @@ -6345,7 +6371,7 @@ /area/tether/surfacebase/atrium_two) "nG" = ( /obj/effect/floor_decal/borderfloor, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 1 }, /turf/simulated/floor/tiled/techmaint, @@ -7199,9 +7225,21 @@ /turf/simulated/floor/tiled/techfloor, /area/maintenance/lower/bar) "oX" = ( -/obj/machinery/door/airlock/maintenance/common, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/door/airlock/engineering{ + name = "Science Substation"; + req_one_access = list(11,24,47) + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/door/firedoor/glass, /turf/simulated/floor, -/area/maintenance/lower/bar) +/area/maintenance/substation/research) "oY" = ( /obj/effect/floor_decal/techfloor{ dir = 8 @@ -7958,12 +7996,15 @@ /turf/simulated/floor/tiled, /area/janitor) "qs" = ( -/obj/effect/floor_decal/corner_techfloor_grid{ - dir = 9 +/obj/structure/railing{ + dir = 8 + }, +/obj/effect/floor_decal/corner_techfloor_grid/full{ + dir = 1 }, /obj/random/trash_pile, /turf/simulated/floor/tiled/techfloor, -/area/maintenance/lower/bar) +/area/maintenance/lower/south) "qt" = ( /obj/structure/railing{ dir = 8 @@ -8785,14 +8826,24 @@ /turf/simulated/floor/tiled/techfloor, /area/maintenance/lower/south) "rS" = ( -/obj/structure/railing{ - dir = 8 - }, -/obj/effect/floor_decal/corner_techfloor_grid/full{ +/obj/effect/floor_decal/borderfloor{ dir = 1 }, -/turf/simulated/floor/tiled/techfloor, -/area/maintenance/lower/south) +/obj/effect/floor_decal/corner/yellow/border{ + dir = 1 + }, +/obj/effect/floor_decal/steeldecal/steel_decals5, +/obj/machinery/atmospherics/unary/vent_pump/on, +/obj/structure/cable/cyan{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/effect/landmark{ + name = "lightsout" + }, +/turf/simulated/floor/tiled, +/area/engineering/atmos/hallway) "rT" = ( /obj/structure/catwalk, /obj/effect/decal/cleanable/dirt, @@ -10414,22 +10465,6 @@ }, /turf/simulated/floor/tiled, /area/engineering/atmos/hallway) -"uE" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/obj/effect/floor_decal/corner/yellow/border{ - dir = 1 - }, -/obj/effect/floor_decal/steeldecal/steel_decals5, -/obj/machinery/atmospherics/unary/vent_pump/on, -/obj/structure/cable/cyan{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/turf/simulated/floor/tiled, -/area/engineering/atmos/hallway) "uF" = ( /obj/effect/floor_decal/borderfloor{ dir = 1 @@ -15670,18 +15705,24 @@ /turf/simulated/wall, /area/maintenance/substation/tcomms) "Ex" = ( -/obj/machinery/door/airlock/maintenance/engi{ - name = "Telecomms Substation" - }, /obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2"; - pixel_y = 0 + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 }, -/obj/machinery/door/firedoor, -/turf/simulated/floor/plating, -/area/maintenance/substation/tcomms) +/obj/machinery/door/airlock/engineering{ + name = "Science Substation"; + req_one_access = list(11,24,47) + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor, +/area/maintenance/substation/research) "Ey" = ( /obj/structure/sign/securearea{ desc = "A warning sign which reads 'HIGH VOLTAGE'"; @@ -15903,7 +15944,7 @@ name = "\improper Telecomms Lobby" }) "EX" = ( -/obj/machinery/camera/network/telecom, +/obj/machinery/camera/network/tcomms, /turf/simulated/floor/tiled/dark, /area/tcomsat{ name = "\improper Telecomms Lobby" @@ -16044,7 +16085,7 @@ name = "\improper Telecomms Lobby" }) "Fk" = ( -/obj/machinery/camera/network/telecom, +/obj/machinery/camera/network/tcomms, /obj/structure/sign/electricshock{ pixel_y = 32 }, @@ -16074,17 +16115,18 @@ name = "\improper Telecomms Lobby" }) "Fn" = ( -/obj/structure/window/reinforced/full, -/obj/structure/grille, -/obj/machinery/door/firedoor/glass, -/obj/structure/cable/green{ - d2 = 2; - icon_state = "0-2" +/obj/effect/floor_decal/borderfloor{ + dir = 10 }, -/turf/simulated/floor/plating, -/area/tcomsat{ - name = "\improper Telecomms Lobby" - }) +/obj/effect/floor_decal/corner/mauve/border{ + dir = 10 + }, +/obj/machinery/alarm{ + dir = 1; + pixel_y = -25 + }, +/turf/simulated/floor/tiled, +/area/rnd/research/testingrange) "Fo" = ( /turf/simulated/floor/tiled, /area/tcomsat{ @@ -16100,7 +16142,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 6 }, -/obj/machinery/camera/network/telecom{ +/obj/machinery/camera/network/tcomms{ dir = 4 }, /obj/item/device/radio/intercom{ @@ -16155,21 +16197,10 @@ /turf/simulated/floor/tiled/techfloor, /area/maintenance/lower/south) "Fy" = ( -/obj/machinery/door/airlock/highsecurity{ - name = "Telecomms Access"; - req_one_access = list(61) - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/door/firedoor, -/turf/simulated/floor/tiled, -/area/tcommsat/entrance{ - name = "\improper Telecomms Entrance" - }) +/obj/machinery/door/airlock/maintenance/common, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor, +/area/maintenance/lower/bar) "Fz" = ( /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 1 @@ -16213,27 +16244,13 @@ name = "\improper Telecomms Entrance" }) "FC" = ( -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" +/obj/structure/catwalk, +/obj/machinery/alarm{ + dir = 1; + pixel_y = -22 }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/door/airlock/hatch{ - name = "Telecomms Foyer"; - req_access = list(61); - req_one_access = list(12) - }, -/obj/machinery/door/firedoor, -/turf/simulated/floor/tiled, -/area/tcomsat{ - name = "\improper Telecomms Lobby" - }) +/turf/simulated/floor/tiled/techfloor, +/area/maintenance/lower/south) "FD" = ( /obj/structure/cable/green{ d1 = 4; @@ -16515,7 +16532,7 @@ name = "\improper Telecomms Entrance" }) "FW" = ( -/obj/machinery/camera/network/telecom{ +/obj/machinery/camera/network/tcomms{ dir = 1 }, /turf/simulated/floor/tiled, @@ -16639,19 +16656,20 @@ /turf/simulated/floor/tiled, /area/tcommsat/computer) "Gi" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - frequency = 1381; - icon_state = "door_locked"; - id_tag = "server_access_outer"; - locked = 1; - name = "Telecoms Server Access"; - req_access = list(61) - }, -/obj/machinery/atmospherics/pipe/simple/hidden{ +/obj/effect/floor_decal/techfloor{ dir = 4 }, -/turf/simulated/floor/tiled, -/area/tcommsat/chamber) +/obj/structure/railing{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/alarm{ + dir = 8; + icon_state = "alarm0"; + pixel_x = 24 + }, +/turf/simulated/floor/tiled/techfloor, +/area/maintenance/asmaint2) "Gj" = ( /obj/machinery/airlock_sensor{ frequency = 1381; @@ -17189,7 +17207,7 @@ name = "\improper Telecomms Storage" }) "Hc" = ( -/obj/machinery/camera/network/telecom{ +/obj/machinery/camera/network/tcomms{ dir = 4 }, /turf/simulated/floor/bluegrid{ @@ -17211,7 +17229,7 @@ }, /area/tcommsat/chamber) "He" = ( -/obj/machinery/camera/network/telecom{ +/obj/machinery/camera/network/tcomms{ dir = 8 }, /turf/simulated/floor/bluegrid{ @@ -17244,7 +17262,7 @@ /obj/item/weapon/stock_parts/subspace/sub_filter, /obj/item/weapon/stock_parts/subspace/sub_filter, /obj/item/weapon/stock_parts/subspace/sub_filter, -/obj/machinery/camera/network/telecom{ +/obj/machinery/camera/network/tcomms{ dir = 1 }, /turf/simulated/floor/tiled/techmaint, @@ -17500,7 +17518,7 @@ }, /area/tcommsat/chamber) "HI" = ( -/obj/machinery/camera/network/telecom{ +/obj/machinery/camera/network/tcomms{ dir = 1 }, /turf/simulated/floor/bluegrid{ @@ -17557,6 +17575,93 @@ temperature = 80 }, /area/tcommsat/chamber) +"HM" = ( +/obj/machinery/door/airlock/maintenance/engi{ + name = "Telecomms Substation" + }, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/plating, +/area/maintenance/substation/tcomms) +"HN" = ( +/obj/structure/window/reinforced/full, +/obj/structure/grille, +/obj/structure/cable/green{ + d2 = 2; + icon_state = "0-2" + }, +/obj/machinery/door/firedoor, +/turf/simulated/floor/plating, +/area/tcomsat{ + name = "\improper Telecomms Lobby" + }) +"HO" = ( +/obj/machinery/door/airlock/highsecurity{ + name = "Telecomms Access"; + req_one_access = list(61) + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/tiled, +/area/tcommsat/entrance{ + name = "\improper Telecomms Entrance" + }) +"HP" = ( +/obj/structure/cable/green{ + 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 + }, +/obj/machinery/door/airlock/hatch{ + name = "Telecomms Foyer"; + req_access = list(61); + req_one_access = list(12) + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/tiled, +/area/tcomsat{ + name = "\improper Telecomms Lobby" + }) +"HQ" = ( +/obj/machinery/door/airlock/maintenance_hatch{ + frequency = 1381; + icon_state = "door_locked"; + id_tag = "server_access_outer"; + locked = 1; + name = "Telecoms Server Access"; + req_access = list(61) + }, +/obj/machinery/atmospherics/pipe/simple/hidden{ + dir = 4 + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/tiled, +/area/tcommsat/chamber) +"HR" = ( +/obj/machinery/telecomms/relay/preset/tether/midpoint, +/turf/simulated/floor/bluegrid{ + name = "Mainframe Base"; + nitrogen = 100; + oxygen = 0; + temperature = 80 + }, +/area/tcommsat/chamber) "HT" = ( /obj/item/weapon/storage/box/glasses/pint, /obj/item/weapon/storage/box/glass_extras/straws, @@ -17947,21 +18052,6 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/public_garden_two) -"Sv" = ( -/obj/machinery/door/airlock/maintenance/engi, -/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/plating, -/area/gateway) "Sy" = ( /obj/structure/sign/poster, /turf/simulated/wall, @@ -18057,23 +18147,6 @@ /obj/random/maintenance/clean, /turf/simulated/floor, /area/maintenance/lower/bar) -"UX" = ( -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ - dir = 1 - }, -/obj/structure/cable{ - icon_state = "2-4" - }, -/turf/simulated/floor/plating, -/area/tether/surfacebase/public_garden_two) "Vk" = ( /obj/structure/cable{ icon_state = "4-8" @@ -18136,7 +18209,7 @@ /obj/effect/floor_decal/corner_techfloor_grid{ dir = 10 }, -/mob/living/simple_animal/lizard, +/mob/living/simple_mob/animal/passive/lizard, /turf/simulated/floor/tiled/techfloor, /area/maintenance/lower/bar) "Xd" = ( @@ -24629,7 +24702,7 @@ ac ac ac Kt -UX +fQ IB Mf Kt @@ -24913,7 +24986,7 @@ ae ae ae ae -Sv +kl ae ae ae @@ -24947,7 +25020,7 @@ li lC lZ mF -nj +Fn nP ol oZ @@ -25057,7 +25130,7 @@ bX cm ZO bX -cm +lM bX bX dP @@ -25815,7 +25888,7 @@ vW wz xl xM -xl +Gi xl xl zJ @@ -26367,7 +26440,7 @@ ln lJ mg mJ -nq +ln nq ot pi @@ -26509,7 +26582,7 @@ ln lK mh mK -nq +ln nq os pj @@ -26790,9 +26863,9 @@ ku il il lo -lM +oX ln -mM +Ex nr nS ou @@ -27356,7 +27429,7 @@ jN jN ky jy -ld +lc ls ls ls @@ -27498,7 +27571,7 @@ jy jy jy jy -ld +lc ls lQ lQ @@ -27640,7 +27713,7 @@ jy jy jy jy -ld +lc ls lQ lQ @@ -27782,7 +27855,7 @@ jy jy jy jy -ld +lc ls lQ lQ @@ -27924,7 +27997,7 @@ jy jy jy jy -ld +lc ls lQ lQ @@ -28066,7 +28139,7 @@ jy jy jy jy -ld +lc ls ls lQ @@ -28208,7 +28281,7 @@ jy jy jy jy -dY +ii dY lR ml @@ -28223,7 +28296,7 @@ pn pn pn tg -uE +rS vt tg tg @@ -28331,7 +28404,7 @@ dV eD eW ap -fQ +mM ge ge ge @@ -30524,7 +30597,7 @@ rg rg ET Ff -Fy +HO FU ET ac @@ -31092,7 +31165,7 @@ Ez Ez EM EM -FC +HP EM EM Gw @@ -31229,7 +31302,7 @@ ac rg DQ Et -Ex +HM EB EH EM @@ -31595,7 +31668,7 @@ dG dG aG dY -fn +cU fG fY gj @@ -31801,7 +31874,7 @@ Ez Ez EL EM -Fn +HN FH Ga FR @@ -31872,7 +31945,7 @@ bO ad cx cy -cU +cy dh cy cy @@ -32344,7 +32417,7 @@ tu rO vP vP -sK +FC rg ac ac @@ -32761,7 +32834,7 @@ du of oV pG -qs +pG re rO sE @@ -32801,7 +32874,7 @@ Gg Gq GD GP -Gz +HR Hd Hn Gz @@ -33042,7 +33115,7 @@ du mB ne du -ee +mA ee ee gY @@ -33223,7 +33296,7 @@ ES Fd Fv FR -Gi +HQ FR GG GI @@ -33469,7 +33542,7 @@ mD nf du du -oX +Fy du du rg @@ -33743,7 +33816,7 @@ ef ef ef jZ -kl +nj id kQ ee @@ -33899,7 +33972,7 @@ du du du rg -rS +qs sL tB tB diff --git a/maps/tether/tether-03-surface3.dmm b/maps/tether/tether-03-surface3.dmm index e4e19a3212..edd6d6a3a3 100644 --- a/maps/tether/tether-03-surface3.dmm +++ b/maps/tether/tether-03-surface3.dmm @@ -9,7 +9,7 @@ /turf/simulated/floor/outdoors/grass/sif/virgo3b, /area/tether/surfacebase/outside/outside3) "ad" = ( -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/outside{ dir = 1 }, /turf/simulated/floor/outdoors/grass/sif/virgo3b, @@ -57,7 +57,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 10 }, -/obj/random/trash_pile, /turf/simulated/floor/wood, /area/vacant/vacant_site2) "ak" = ( @@ -498,11 +497,10 @@ /turf/simulated/floor/plating, /area/tether/surfacebase/reading_room) "bg" = ( -/obj/machinery/camera/network/security{ - dir = 9 - }, -/turf/simulated/floor/outdoors/grass/sif/virgo3b, -/area/tether/surfacebase/outside/outside3) +/obj/structure/shuttle/engine/propulsion, +/turf/simulated/floor/reinforced, +/turf/simulated/shuttle/plating/carry, +/area/shuttle/tether/surface) "bh" = ( /turf/simulated/wall/r_wall, /area/gateway/prep_room) @@ -538,7 +536,6 @@ /area/vacant/vacant_site2) "bo" = ( /obj/machinery/door/firedoor/glass, -/obj/machinery/door/airlock/maintenance/engi, /obj/structure/cable/green{ d1 = 1; d2 = 2; @@ -546,6 +543,7 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/door/airlock/maintenance/common, /turf/simulated/floor/tiled/techfloor/grid, /area/vacant/vacant_site2) "bp" = ( @@ -2183,6 +2181,7 @@ layer = 3.3; name = "Public Access Shutter" }, +/obj/machinery/door/firedoor/glass, /turf/simulated/floor/tiled, /area/gateway/prep_room) "ep" = ( @@ -2895,7 +2894,7 @@ /turf/simulated/floor/plating, /area/tether/surfacebase/medical/lobby) "fF" = ( -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/outside{ dir = 8 }, /turf/simulated/floor/outdoors/grass/sif/virgo3b, @@ -3709,6 +3708,12 @@ /obj/effect/floor_decal/techfloor{ dir = 8 }, +/obj/structure/closet/crate, +/obj/random/maintenance/medical, +/obj/random/maintenance/medical, +/obj/random/junk, +/obj/random/maintenance/medical, +/obj/random/maintenance/clean, /turf/simulated/floor/tiled/techfloor/grid, /area/vacant/vacant_site2) "gV" = ( @@ -4149,12 +4154,7 @@ /obj/effect/floor_decal/techfloor/hole{ dir = 8 }, -/obj/structure/closet/crate, -/obj/random/maintenance/clean, -/obj/random/maintenance/medical, -/obj/random/junk, -/obj/random/maintenance/medical, -/obj/random/maintenance/medical, +/obj/random/trash_pile, /turf/simulated/floor/tiled/techfloor/grid, /area/vacant/vacant_site2) "hI" = ( @@ -4304,7 +4304,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/structure/disposalpipe/segment, -/obj/machinery/door/firedoor, /obj/structure/cable{ d1 = 1; d2 = 2; @@ -4314,6 +4313,7 @@ /obj/effect/floor_decal/steeldecal/steel_decals_central1{ dir = 8 }, +/obj/machinery/door/firedoor/glass, /turf/simulated/floor/tiled/monofloor{ dir = 8 }, @@ -4325,10 +4325,10 @@ layer = 3.3; name = "Gateway Prep Shutter" }, -/obj/machinery/door/firedoor, /obj/effect/floor_decal/steeldecal/steel_decals_central1{ dir = 4 }, +/obj/machinery/door/firedoor/glass, /turf/simulated/floor/tiled/monofloor{ dir = 4 }, @@ -4336,13 +4336,13 @@ "hV" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/door/firedoor, /obj/machinery/door/airlock{ name = "Unisex Restrooms" }, /obj/structure/cable{ icon_state = "1-2" }, +/obj/machinery/door/firedoor/glass, /turf/simulated/floor/tiled/steel_grid, /area/crew_quarters/recreation_area_restroom) "hW" = ( @@ -4662,20 +4662,11 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/atrium_three) "iv" = ( +/obj/random/junk, /obj/machinery/alarm{ pixel_y = 22 }, -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/obj/effect/floor_decal/corner/lightgrey/border{ - dir = 1 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 4 - }, -/turf/simulated/floor/tiled, +/turf/simulated/floor/plating, /area/tether/surfacebase/atrium_three) "iw" = ( /obj/machinery/firealarm{ @@ -4731,7 +4722,7 @@ d2 = 4; icon_state = "2-4" }, -/obj/machinery/camera/network/northern_star, +/obj/machinery/camera/network/tether, /obj/effect/floor_decal/borderfloor{ dir = 1 }, @@ -4868,32 +4859,24 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/atrium_three) "iF" = ( -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8" +/obj/machinery/atmospherics/pipe/zpipe/down/scrubbers{ + dir = 8 }, -/obj/effect/floor_decal/borderfloor{ - dir = 1 +/obj/machinery/atmospherics/pipe/zpipe/down/supply{ + dir = 8 }, -/obj/effect/floor_decal/corner/lightgrey/border{ - dir = 1 +/obj/structure/cable/cyan{ + d1 = 32; + d2 = 2; + icon_state = "32-2" }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 +/obj/machinery/camera/network/engineering{ + dir = 8 }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 4 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7, -/obj/machinery/door/firedoor/glass/hidden/steel{ - dir = 2 - }, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/atrium_three) +/obj/machinery/door/firedoor/glass, +/obj/structure/lattice, +/turf/simulated/open, +/area/maintenance/engineering/pumpstation) "iG" = ( /obj/structure/cable{ d1 = 4; @@ -4979,7 +4962,7 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/atrium_three) "iK" = ( -/obj/machinery/camera/network/northern_star, +/obj/machinery/camera/network/tether, /obj/effect/floor_decal/borderfloor{ dir = 1 }, @@ -5082,7 +5065,7 @@ dir = 4 }, /obj/effect/floor_decal/steeldecal/steel_decals7, -/obj/machinery/camera/network/northern_star, +/obj/machinery/camera/network/tether, /turf/simulated/floor/tiled, /area/tether/surfacebase/atrium_three) "iR" = ( @@ -5119,7 +5102,6 @@ }, /obj/effect/floor_decal/steeldecal/steel_decals7, /obj/machinery/alarm{ - frequency = 1441; pixel_y = 22 }, /obj/machinery/atmospherics/unary/vent_pump/on, @@ -5261,7 +5243,7 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/atrium_three) "jc" = ( -/obj/machinery/camera/network/northern_star, +/obj/machinery/camera/network/tether, /obj/effect/floor_decal/borderfloor{ dir = 1 }, @@ -5633,9 +5615,8 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/atrium_three) "jI" = ( -/obj/machinery/door/firedoor/glass/hidden/steel, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/atrium_three) +/turf/simulated/wall, +/area/rnd/research/researchdivision) "jJ" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 5 @@ -5705,6 +5686,9 @@ dir = 2 }, /obj/machinery/hologram/holopad, +/obj/effect/landmark{ + name = "lightsout" + }, /turf/simulated/floor/tiled, /area/tether/surfacebase/atrium_three) "jR" = ( @@ -5900,7 +5884,7 @@ /turf/simulated/floor/tiled/techfloor, /area/crew_quarters/panic_shelter) "kk" = ( -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/outside{ dir = 4 }, /turf/simulated/floor/outdoors/grass/sif/virgo3b, @@ -5950,9 +5934,6 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/atrium_three) "ko" = ( -/obj/machinery/camera/network/civilian{ - dir = 1 - }, /obj/effect/floor_decal/borderfloor, /obj/effect/floor_decal/corner/lightgrey/border, /obj/effect/floor_decal/steeldecal/steel_decals7{ @@ -5961,6 +5942,9 @@ /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 1 }, +/obj/machinery/camera/network/tether{ + dir = 1 + }, /turf/simulated/floor/tiled, /area/tether/surfacebase/atrium_three) "kp" = ( @@ -6081,17 +6065,27 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/atrium_three) "ky" = ( -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/lightgrey/border, -/obj/effect/floor_decal/steeldecal/steel_decals7{ +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/effect/floor_decal/borderfloor{ dir = 1 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 8 - }, -/obj/machinery/door/firedoor/glass/hidden/steel{ +/obj/effect/floor_decal/corner/lightgrey/border{ dir = 1 }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 4 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7, /turf/simulated/floor/tiled, /area/tether/surfacebase/atrium_three) "kz" = ( @@ -6262,7 +6256,7 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/atrium_three) "kM" = ( -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 9 }, /obj/effect/floor_decal/borderfloor{ @@ -6339,10 +6333,10 @@ /obj/machinery/door/airlock/multi_tile/glass{ name = "Pool" }, -/obj/machinery/door/firedoor, /obj/effect/floor_decal/steeldecal/steel_decals_central1{ dir = 8 }, +/obj/machinery/door/firedoor/glass, /turf/simulated/floor/tiled/monofloor{ dir = 8 }, @@ -6350,10 +6344,10 @@ "kV" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/door/firedoor, /obj/effect/floor_decal/steeldecal/steel_decals_central1{ dir = 4 }, +/obj/machinery/door/firedoor/glass, /turf/simulated/floor/tiled/monofloor{ dir = 4 }, @@ -6553,7 +6547,7 @@ /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 }, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 9 }, /turf/simulated/floor/tiled, @@ -7413,7 +7407,7 @@ /turf/simulated/floor/tiled/steel_grid, /area/tether/surfacebase/north_stairs_three) "nd" = ( -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 4 }, /turf/simulated/open, @@ -7428,7 +7422,7 @@ /turf/simulated/wall, /area/tether/surfacebase/north_stairs_three) "ng" = ( -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 4 }, /obj/effect/floor_decal/borderfloor{ @@ -7688,10 +7682,10 @@ /turf/simulated/floor/tiled, /area/crew_quarters/pool) "nC" = ( -/obj/machinery/door/firedoor, /obj/machinery/door/airlock/glass{ name = "Recreation Area" }, +/obj/machinery/door/firedoor/glass, /turf/simulated/floor/tiled/steel_grid, /area/crew_quarters/recreation_area) "nD" = ( @@ -8361,10 +8355,10 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/structure/disposalpipe/segment, -/obj/machinery/door/firedoor, /obj/machinery/door/airlock/glass{ name = "Recreation Area" }, +/obj/machinery/door/firedoor/glass, /turf/simulated/floor/tiled/steel_grid, /area/crew_quarters/recreation_area) "oW" = ( @@ -8707,9 +8701,21 @@ /turf/simulated/floor/plating, /area/tether/surfacebase/atrium_three) "pA" = ( -/obj/random/junk, -/turf/simulated/floor/plating, -/area/tether/surfacebase/atrium_three) +/obj/machinery/status_display{ + pixel_y = 30 + }, +/obj/effect/floor_decal/borderfloor{ + dir = 9 + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 9 + }, +/obj/structure/disposalpipe/trunk{ + dir = 4 + }, +/obj/machinery/disposal, +/turf/simulated/floor/tiled, +/area/rnd/research/researchdivision) "pB" = ( /obj/effect/floor_decal/borderfloor{ dir = 8 @@ -8859,7 +8865,7 @@ /obj/machinery/door/airlock/glass{ name = "Pool" }, -/obj/machinery/door/firedoor, +/obj/machinery/door/firedoor/glass, /turf/simulated/floor/tiled/steel_grid, /area/crew_quarters/pool) "pO" = ( @@ -9463,13 +9469,13 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/obj/machinery/door/firedoor, /obj/machinery/door/airlock{ name = "Unisex Showers" }, /obj/structure/cable{ icon_state = "4-8" }, +/obj/machinery/door/firedoor/glass, /turf/simulated/floor/tiled/steel_grid, /area/crew_quarters/recreation_area_restroom{ name = "\improper Recreation Area Showers" @@ -9587,7 +9593,7 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/atrium_three) "qS" = ( -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 9 }, /obj/effect/floor_decal/borderfloor{ @@ -9788,7 +9794,7 @@ name = "\improper Recreation Area Showers" }) "rn" = ( -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 4 }, /obj/effect/floor_decal/borderfloor{ @@ -10141,6 +10147,11 @@ "rT" = ( /obj/effect/floor_decal/corner/grey/diagonal, /obj/structure/closet/secure_closet/freezer/meat, +/obj/machinery/alarm{ + dir = 8; + icon_state = "alarm0"; + pixel_x = 24 + }, /turf/simulated/floor/tiled/white, /area/crew_quarters/kitchen) "rU" = ( @@ -10250,7 +10261,7 @@ d2 = 8; icon_state = "4-8" }, -/obj/machinery/camera/network/northern_star, +/obj/machinery/camera/network/tether, /obj/effect/floor_decal/borderfloor{ dir = 1 }, @@ -11508,7 +11519,7 @@ /turf/simulated/shuttle/wall/voidcraft/green{ hard_corner = 1 }, -/area/hallway/lower/third_south) +/area/tether/elevator) "ue" = ( /obj/structure/grille, /obj/structure/window/reinforced/full, @@ -11703,7 +11714,7 @@ /area/rnd/breakroom) "ux" = ( /turf/simulated/floor/holofloor/tiled/dark, -/area/hallway/lower/third_south) +/area/tether/elevator) "uy" = ( /obj/effect/floor_decal/borderfloor{ dir = 1 @@ -11734,7 +11745,7 @@ dir = 4 }, /obj/effect/floor_decal/steeldecal/steel_decals7, -/obj/machinery/camera/network/northern_star, +/obj/machinery/camera/network/tether, /obj/item/device/radio/intercom{ dir = 1; pixel_y = 24; @@ -12549,7 +12560,7 @@ /turf/simulated/shuttle/wall/voidcraft/green{ hard_corner = 1 }, -/area/hallway/lower/third_south) +/area/tether/elevator) "vZ" = ( /obj/machinery/door/firedoor/glass/hidden/steel{ dir = 1 @@ -12631,7 +12642,7 @@ /turf/simulated/floor/tiled, /area/hallway/lower/third_south) "wh" = ( -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 1 }, /obj/effect/floor_decal/borderfloor, @@ -13360,25 +13371,6 @@ /turf/simulated/floor/wood, /area/crew_quarters/bar) "xy" = ( -/turf/simulated/wall, -/area/rnd/research) -"xz" = ( -/obj/machinery/status_display{ - pixel_y = 30 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 9 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 9 - }, -/obj/structure/disposalpipe/trunk{ - dir = 4 - }, -/obj/machinery/disposal, -/turf/simulated/floor/tiled, -/area/rnd/research) -"xA" = ( /obj/effect/floor_decal/borderfloor{ dir = 1 }, @@ -13390,7 +13382,31 @@ icon_state = "pipe-c" }, /turf/simulated/floor/tiled, -/area/rnd/research) +/area/rnd/research/researchdivision) +"xz" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 1 + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 1 + }, +/obj/effect/floor_decal/borderfloor/corner2{ + dir = 1 + }, +/obj/effect/floor_decal/corner/mauve/bordercorner2{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/rnd/research/researchdivision) +"xA" = ( +/obj/effect/floor_decal/steeldecal/steel_decals4{ + dir = 4 + }, +/obj/effect/floor_decal/steeldecal/steel_decals4{ + dir = 9 + }, +/turf/simulated/floor/tiled, +/area/rnd/research/researchdivision) "xB" = ( /obj/effect/floor_decal/borderfloor{ dir = 1 @@ -13399,38 +13415,14 @@ dir = 1 }, /obj/effect/floor_decal/borderfloor/corner2{ - dir = 1 + dir = 4 }, /obj/effect/floor_decal/corner/mauve/bordercorner2{ - dir = 1 + dir = 4 }, /turf/simulated/floor/tiled, -/area/rnd/research) +/area/rnd/research/researchdivision) "xC" = ( -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 4 - }, -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 9 - }, -/turf/simulated/floor/tiled, -/area/rnd/research) -"xD" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 1 - }, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 4 - }, -/obj/effect/floor_decal/corner/mauve/bordercorner2{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/rnd/research) -"xE" = ( /obj/effect/floor_decal/borderfloor{ dir = 1 }, @@ -13439,8 +13431,8 @@ }, /obj/machinery/camera/network/research, /turf/simulated/floor/tiled, -/area/rnd/research) -"xF" = ( +/area/rnd/research/researchdivision) +"xD" = ( /obj/effect/floor_decal/borderfloor{ dir = 1 }, @@ -13448,8 +13440,8 @@ dir = 1 }, /turf/simulated/floor/tiled, -/area/rnd/research) -"xG" = ( +/area/rnd/research/researchdivision) +"xE" = ( /obj/structure/cable/green{ d1 = 1; d2 = 2; @@ -13465,8 +13457,8 @@ dir = 9 }, /turf/simulated/floor/tiled, -/area/rnd/research) -"xH" = ( +/area/rnd/research/researchdivision) +"xF" = ( /obj/effect/floor_decal/borderfloor{ dir = 1 }, @@ -13481,8 +13473,8 @@ }, /obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled, -/area/rnd/research) -"xI" = ( +/area/rnd/research/researchdivision) +"xG" = ( /obj/effect/floor_decal/borderfloor{ dir = 1 }, @@ -13491,8 +13483,8 @@ }, /obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled, -/area/rnd/research) -"xJ" = ( +/area/rnd/research/researchdivision) +"xH" = ( /obj/machinery/newscaster{ pixel_x = 0; pixel_y = 30 @@ -13505,13 +13497,35 @@ }, /obj/structure/flora/pottedplant/stoutbush, /turf/simulated/floor/tiled, -/area/rnd/research) -"xK" = ( +/area/rnd/research/researchdivision) +"xI" = ( /obj/structure/grille, /obj/structure/window/reinforced/full, /obj/machinery/door/firedoor, /turf/simulated/floor/plating, -/area/rnd/research) +/area/rnd/research/researchdivision) +"xJ" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 8 + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/rnd/research/researchdivision) +"xK" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 6 + }, +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, +/turf/simulated/floor/tiled, +/area/rnd/research/researchdivision) "xL" = ( /obj/structure/table/glass, /obj/effect/floor_decal/borderfloor{ @@ -13741,40 +13755,18 @@ /turf/simulated/floor/wood, /area/crew_quarters/bar) "yi" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 8 +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 8 +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 }, /turf/simulated/floor/tiled, -/area/rnd/research) +/area/rnd/research/researchdivision) "yj" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 6 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 6 - }, -/obj/structure/disposalpipe/segment{ - dir = 1; - icon_state = "pipe-c" - }, -/turf/simulated/floor/tiled, -/area/rnd/research) -"yk" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/rnd/research) -"yl" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, @@ -13785,8 +13777,8 @@ dir = 1 }, /turf/simulated/floor/tiled, -/area/rnd/research) -"ym" = ( +/area/rnd/research/researchdivision) +"yk" = ( /obj/structure/cable/green{ d1 = 1; d2 = 2; @@ -13799,28 +13791,28 @@ sortType = "Research" }, /turf/simulated/floor/tiled, -/area/rnd/research) +/area/rnd/research/researchdivision) +"yl" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/turf/simulated/floor/tiled, +/area/rnd/research/researchdivision) +"ym" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 10 + }, +/turf/simulated/floor/tiled, +/area/rnd/research/researchdivision) "yn" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/structure/disposalpipe/segment, -/turf/simulated/floor/tiled, -/area/rnd/research) -"yo" = ( -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 10 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 10 - }, -/turf/simulated/floor/tiled, -/area/rnd/research) -"yp" = ( /obj/effect/floor_decal/borderfloor{ dir = 4 }, @@ -13834,7 +13826,27 @@ dir = 5 }, /turf/simulated/floor/tiled, -/area/rnd/research) +/area/rnd/research/researchdivision) +"yo" = ( +/obj/machinery/alarm{ + dir = 4; + icon_state = "alarm0"; + pixel_x = -22; + pixel_y = 0 + }, +/obj/effect/floor_decal/borderfloor{ + dir = 8 + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/rnd/research/researchdivision) +"yp" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/turf/simulated/floor/tiled, +/area/rnd/research/researchdivision) "yq" = ( /obj/structure/table/glass, /obj/effect/floor_decal/borderfloor{ @@ -13899,7 +13911,7 @@ /area/hallway/lower/third_south) "yw" = ( /obj/structure/disposalpipe/segment, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 9 }, /obj/effect/floor_decal/borderfloor{ @@ -13996,6 +14008,18 @@ "yG" = ( /turf/simulated/floor/tiled, /area/hallway/lower/third_south) +"yH" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/tiled/steel_grid, +/area/assembly/robotics) "yI" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ @@ -14041,41 +14065,21 @@ /turf/simulated/floor/wood, /area/crew_quarters/bar) "yN" = ( -/obj/machinery/alarm{ - dir = 4; - icon_state = "alarm0"; - pixel_x = -22; - pixel_y = 0 - }, -/obj/effect/floor_decal/borderfloor{ +/obj/structure/railing{ dir = 8 }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 8 +/obj/structure/railing{ + dir = 1 }, -/turf/simulated/floor/tiled, -/area/rnd/research) +/turf/simulated/open, +/area/rnd/research/researchdivision) "yO" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/turf/simulated/floor/tiled, -/area/rnd/research) +/obj/structure/railing{ + dir = 1 + }, +/turf/simulated/open, +/area/rnd/research/researchdivision) "yP" = ( -/obj/structure/railing{ - dir = 8 - }, -/obj/structure/railing{ - dir = 1 - }, -/turf/simulated/open, -/area/rnd/research) -"yQ" = ( -/obj/structure/railing{ - dir = 1 - }, -/turf/simulated/open, -/area/rnd/research) -"yR" = ( /obj/structure/railing{ dir = 4 }, @@ -14083,15 +14087,15 @@ dir = 1 }, /turf/simulated/open, -/area/rnd/research) -"yS" = ( +/area/rnd/research/researchdivision) +"yQ" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/floor/tiled, -/area/rnd/research) -"yT" = ( +/area/rnd/research/researchdivision) +"yR" = ( /turf/simulated/floor/tiled, -/area/rnd/research) -"yU" = ( +/area/rnd/research/researchdivision) +"yS" = ( /obj/structure/cable/green{ d1 = 1; d2 = 4; @@ -14099,8 +14103,8 @@ }, /obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled, -/area/rnd/research) -"yV" = ( +/area/rnd/research/researchdivision) +"yT" = ( /obj/structure/cable/green{ d1 = 2; d2 = 4; @@ -14116,8 +14120,8 @@ icon_state = "pipe-c" }, /turf/simulated/floor/tiled, -/area/rnd/research) -"yW" = ( +/area/rnd/research/researchdivision) +"yU" = ( /obj/structure/cable/green{ d1 = 4; d2 = 8; @@ -14134,8 +14138,8 @@ }, /obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled, -/area/rnd/research) -"yX" = ( +/area/rnd/research/researchdivision) +"yV" = ( /obj/structure/cable/green{ d1 = 4; d2 = 8; @@ -14155,8 +14159,8 @@ dir = 10 }, /turf/simulated/floor/tiled, -/area/rnd/research) -"yY" = ( +/area/rnd/research/researchdivision) +"yW" = ( /obj/machinery/door/firedoor/glass, /obj/structure/cable/green{ d1 = 4; @@ -14176,7 +14180,27 @@ name = "Front Desk" }, /turf/simulated/floor/tiled/steel_grid, -/area/rnd/research) +/area/rnd/research/researchdivision) +"yX" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 8 + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 8 + }, +/obj/structure/extinguisher_cabinet{ + dir = 4; + icon_state = "extinguisher_closed"; + pixel_x = -30 + }, +/turf/simulated/floor/tiled, +/area/rnd/research/researchdivision) +"yY" = ( +/obj/structure/railing{ + dir = 8 + }, +/turf/simulated/open, +/area/rnd/research/researchdivision) "yZ" = ( /obj/structure/cable/green{ d1 = 4; @@ -14434,6 +14458,10 @@ }, /turf/simulated/wall, /area/crew_quarters/bar) +"zw" = ( +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/tiled/steel_grid, +/area/assembly/robotics) "zx" = ( /obj/structure/table/bench/wooden, /obj/machinery/light{ @@ -14448,59 +14476,39 @@ /turf/simulated/floor/wood, /area/crew_quarters/bar) "zy" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 8 - }, -/obj/structure/extinguisher_cabinet{ - dir = 4; - icon_state = "extinguisher_closed"; - pixel_x = -30 - }, -/turf/simulated/floor/tiled, -/area/rnd/research) +/turf/simulated/open, +/area/rnd/research/researchdivision) "zz" = ( -/obj/structure/railing{ - dir = 8 - }, -/turf/simulated/open, -/area/rnd/research) -"zA" = ( -/turf/simulated/open, -/area/rnd/research) -"zB" = ( /obj/structure/railing{ dir = 4 }, /turf/simulated/open, -/area/rnd/research) -"zC" = ( +/area/rnd/research/researchdivision) +"zA" = ( /obj/machinery/atmospherics/unary/vent_scrubber/on{ dir = 1 }, /turf/simulated/floor/tiled, -/area/rnd/research) -"zD" = ( +/area/rnd/research/researchdivision) +"zB" = ( /obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled, -/area/rnd/research) -"zE" = ( +/area/rnd/research/researchdivision) +"zC" = ( /obj/structure/cable/green{ d1 = 1; d2 = 2; icon_state = "1-2" }, /turf/simulated/floor/tiled, -/area/rnd/research) -"zF" = ( +/area/rnd/research/researchdivision) +"zD" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled, -/area/rnd/research) -"zG" = ( +/area/rnd/research/researchdivision) +"zE" = ( /obj/effect/floor_decal/borderfloor{ dir = 4 }, @@ -14517,7 +14525,27 @@ pixel_x = 32 }, /turf/simulated/floor/tiled, -/area/rnd/research) +/area/rnd/research/researchdivision) +"zF" = ( +/obj/machinery/computer/guestpass{ + dir = 4; + pixel_x = -28; + pixel_y = 0 + }, +/obj/effect/floor_decal/borderfloor{ + dir = 8 + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/rnd/research/researchdivision) +"zG" = ( +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/rnd/research/researchdivision) "zH" = ( /obj/effect/floor_decal/borderfloor{ dir = 10 @@ -14787,6 +14815,11 @@ /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 9 }, +/obj/machinery/alarm{ + dir = 8; + icon_state = "alarm0"; + pixel_x = 24 + }, /turf/simulated/floor/tiled, /area/hallway/lower/third_south) "Ag" = ( @@ -14840,39 +14873,19 @@ /turf/simulated/floor/wood, /area/crew_quarters/bar) "Al" = ( -/obj/machinery/computer/guestpass{ - dir = 4; - pixel_x = -28; - pixel_y = 0 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/rnd/research) -"Am" = ( -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/rnd/research) -"An" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, /turf/simulated/floor/tiled, -/area/rnd/research) -"Ao" = ( +/area/rnd/research/researchdivision) +"Am" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, /turf/simulated/floor/tiled, -/area/rnd/research) -"Ap" = ( +/area/rnd/research/researchdivision) +"An" = ( /obj/structure/cable/green{ d1 = 1; d2 = 2; @@ -14882,16 +14895,16 @@ dir = 4 }, /turf/simulated/floor/tiled, -/area/rnd/research) -"Aq" = ( +/area/rnd/research/researchdivision) +"Ao" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 4 }, /turf/simulated/floor/tiled, -/area/rnd/research) -"Ar" = ( +/area/rnd/research/researchdivision) +"Ap" = ( /obj/effect/floor_decal/borderfloor{ dir = 4 }, @@ -14899,7 +14912,27 @@ dir = 4 }, /turf/simulated/floor/tiled, -/area/rnd/research) +/area/rnd/research/researchdivision) +"Aq" = ( +/obj/machinery/light{ + icon_state = "tube1"; + dir = 8 + }, +/obj/effect/floor_decal/borderfloor{ + dir = 8 + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/rnd/research/researchdivision) +"Ar" = ( +/obj/structure/railing, +/obj/structure/railing{ + dir = 8 + }, +/turf/simulated/open, +/area/rnd/research/researchdivision) "As" = ( /obj/structure/grille, /obj/structure/window/reinforced/full, @@ -15237,65 +15270,39 @@ /obj/machinery/computer/arcade, /turf/simulated/floor/wood, /area/crew_quarters/bar) -"AS" = ( -/obj/machinery/camera/network/northern_star{ - dir = 9 - }, -/turf/simulated/floor/outdoors/grass/sif/virgo3b, -/area/tether/surfacebase/outside/outside3) "AT" = ( -/obj/machinery/light{ - icon_state = "tube1"; - dir = 8 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/rnd/research) +/obj/structure/railing, +/turf/simulated/open, +/area/rnd/research/researchdivision) "AU" = ( -/obj/structure/railing, -/obj/structure/railing{ - dir = 8 - }, -/turf/simulated/open, -/area/rnd/research) -"AV" = ( -/obj/structure/railing, -/turf/simulated/open, -/area/rnd/research) -"AW" = ( /obj/structure/railing{ dir = 4 }, /obj/structure/railing, /turf/simulated/open, -/area/rnd/research) -"AX" = ( +/area/rnd/research/researchdivision) +"AV" = ( /obj/structure/disposalpipe/segment{ dir = 4; icon_state = "pipe-c" }, /obj/machinery/hologram/holopad, /turf/simulated/floor/tiled, -/area/rnd/research) -"AY" = ( +/area/rnd/research/researchdivision) +"AW" = ( /obj/structure/disposalpipe/segment{ dir = 4 }, /turf/simulated/floor/tiled, -/area/rnd/research) -"AZ" = ( +/area/rnd/research/researchdivision) +"AX" = ( /obj/structure/disposalpipe/sortjunction{ name = "RD Office"; sortType = "RD Office" }, /turf/simulated/floor/tiled, -/area/rnd/research) -"Ba" = ( +/area/rnd/research/researchdivision) +"AY" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/structure/disposalpipe/segment{ @@ -15303,8 +15310,8 @@ icon_state = "pipe-c" }, /turf/simulated/floor/tiled, -/area/rnd/research) -"Bb" = ( +/area/rnd/research/researchdivision) +"AZ" = ( /obj/machinery/light_switch{ pixel_x = 25 }, @@ -15325,7 +15332,31 @@ icon_state = "pipe-c" }, /turf/simulated/floor/tiled, -/area/rnd/research) +/area/rnd/research/researchdivision) +"Ba" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 8 + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 8 + }, +/obj/machinery/camera/network/research{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/rnd/research/researchdivision) +"Bb" = ( +/obj/effect/floor_decal/steeldecal/steel_decals5{ + dir = 1 + }, +/obj/effect/floor_decal/steeldecal/steel_decals9{ + dir = 4 + }, +/obj/effect/floor_decal/steeldecal/steel_decals9{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/rnd/research/researchdivision) "Bc" = ( /obj/effect/floor_decal/borderfloor{ dir = 9 @@ -15680,46 +15711,22 @@ /turf/simulated/floor/wood, /area/crew_quarters/bar) "BH" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 8 - }, -/obj/machinery/camera/network/research{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/rnd/research) -"BI" = ( -/obj/effect/floor_decal/steeldecal/steel_decals5{ - dir = 1 - }, -/obj/effect/floor_decal/steeldecal/steel_decals9{ - dir = 4 - }, -/obj/effect/floor_decal/steeldecal/steel_decals9{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/rnd/research) -"BJ" = ( /obj/structure/cable/green{ d1 = 2; d2 = 4; icon_state = "2-4" }, /turf/simulated/floor/tiled, -/area/rnd/research) -"BK" = ( +/area/rnd/research/researchdivision) +"BI" = ( /obj/structure/cable/green{ d1 = 4; d2 = 8; icon_state = "4-8" }, /turf/simulated/floor/tiled, -/area/rnd/research) -"BL" = ( +/area/rnd/research/researchdivision) +"BJ" = ( /obj/structure/cable/green{ d1 = 4; d2 = 8; @@ -15727,8 +15734,8 @@ }, /obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled, -/area/rnd/research) -"BM" = ( +/area/rnd/research/researchdivision) +"BK" = ( /obj/structure/cable/green{ d1 = 4; d2 = 8; @@ -15739,8 +15746,8 @@ icon_state = "pipe-c" }, /turf/simulated/floor/tiled, -/area/rnd/research) -"BN" = ( +/area/rnd/research/researchdivision) +"BL" = ( /obj/structure/cable/green{ d1 = 4; d2 = 8; @@ -15763,8 +15770,8 @@ sortType = "Robotics" }, /turf/simulated/floor/tiled, -/area/rnd/research) -"BO" = ( +/area/rnd/research/researchdivision) +"BM" = ( /obj/structure/cable/green{ d1 = 4; d2 = 8; @@ -15781,8 +15788,8 @@ icon_state = "pipe-c" }, /turf/simulated/floor/tiled, -/area/rnd/research) -"BP" = ( +/area/rnd/research/researchdivision) +"BN" = ( /obj/structure/cable/green{ d1 = 4; d2 = 8; @@ -15803,8 +15810,8 @@ dir = 10 }, /turf/simulated/floor/tiled, -/area/rnd/research) -"BQ" = ( +/area/rnd/research/researchdivision) +"BO" = ( /obj/machinery/door/firedoor/glass, /obj/structure/cable/green{ d1 = 4; @@ -15826,7 +15833,19 @@ req_access = list(47) }, /turf/simulated/floor/tiled/steel_grid, -/area/rnd/research) +/area/rnd/research/researchdivision) +"BP" = ( +/obj/effect/floor_decal/borderfloor/corner, +/obj/effect/floor_decal/corner/mauve/bordercorner, +/obj/structure/disposalpipe/segment, +/turf/simulated/floor/tiled, +/area/rnd/research/researchdivision) +"BQ" = ( +/obj/machinery/light, +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/mauve/border, +/turf/simulated/floor/tiled, +/area/rnd/research/researchdivision) "BR" = ( /obj/effect/floor_decal/steeldecal/steel_decals7, /obj/effect/floor_decal/steeldecal/steel_decals7{ @@ -15993,23 +16012,21 @@ /turf/simulated/floor/plating, /area/maintenance/engineering/pumpstation) "Cb" = ( -/obj/machinery/atmospherics/pipe/zpipe/down/scrubbers{ - dir = 8 +/obj/machinery/firealarm{ + dir = 1; + pixel_x = 0; + pixel_y = -25 }, -/obj/machinery/atmospherics/pipe/zpipe/down/supply{ - dir = 8 +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/mauve/border, +/obj/effect/floor_decal/borderfloor/corner2{ + dir = 9 }, -/obj/structure/cable/cyan{ - d1 = 32; - d2 = 2; - icon_state = "32-2" +/obj/effect/floor_decal/corner/mauve/bordercorner2{ + dir = 9 }, -/obj/machinery/camera/network/engineering{ - dir = 8 - }, -/obj/machinery/door/firedoor/glass, -/turf/simulated/open, -/area/maintenance/engineering/pumpstation) +/turf/simulated/floor/tiled, +/area/rnd/research/researchdivision) "Cc" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/disposalpipe/segment, @@ -16187,34 +16204,6 @@ /turf/simulated/floor/wood, /area/crew_quarters/bar) "Cq" = ( -/obj/effect/floor_decal/borderfloor/corner, -/obj/effect/floor_decal/corner/mauve/bordercorner, -/obj/structure/disposalpipe/segment, -/turf/simulated/floor/tiled, -/area/rnd/research) -"Cr" = ( -/obj/machinery/light, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/mauve/border, -/turf/simulated/floor/tiled, -/area/rnd/research) -"Cs" = ( -/obj/machinery/firealarm{ - dir = 1; - pixel_x = 0; - pixel_y = -25 - }, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/mauve/border, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 9 - }, -/obj/effect/floor_decal/corner/mauve/bordercorner2{ - dir = 9 - }, -/turf/simulated/floor/tiled, -/area/rnd/research) -"Ct" = ( /obj/structure/cable/green{ d1 = 1; d2 = 2; @@ -16228,8 +16217,8 @@ dir = 8 }, /turf/simulated/floor/tiled, -/area/rnd/research) -"Cu" = ( +/area/rnd/research/researchdivision) +"Cr" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 5 }, @@ -16251,8 +16240,8 @@ icon_state = "pipe-c" }, /turf/simulated/floor/tiled, -/area/rnd/research) -"Cv" = ( +/area/rnd/research/researchdivision) +"Cs" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 10 }, @@ -16270,7 +16259,58 @@ dir = 8 }, /turf/simulated/floor/tiled, -/area/rnd/research) +/area/rnd/research/researchdivision) +"Ct" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 8 + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 8 + }, +/obj/structure/cable/green{ + d2 = 2; + icon_state = "0-2" + }, +/obj/machinery/power/apc{ + cell_type = /obj/item/weapon/cell/super; + dir = 8; + name = "west bump"; + pixel_x = -30 + }, +/turf/simulated/floor/tiled, +/area/rnd/research/researchdivision) +"Cu" = ( +/obj/machinery/light_switch{ + pixel_x = 25 + }, +/obj/effect/floor_decal/borderfloor{ + dir = 4 + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/recharge_station, +/turf/simulated/floor/tiled, +/area/rnd/research/researchdivision) +"Cv" = ( +/obj/machinery/firealarm{ + dir = 8; + pixel_x = -24 + }, +/obj/effect/floor_decal/borderfloor{ + dir = 8 + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 8 + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/simulated/floor/tiled, +/area/rnd/research/researchdivision) "Cw" = ( /obj/effect/floor_decal/borderfloor{ dir = 10 @@ -16369,7 +16409,7 @@ /obj/effect/floor_decal/borderfloor, /obj/effect/floor_decal/corner/mauve/border, /obj/effect/floor_decal/steeldecal/steel_decals4, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 1 }, /obj/effect/floor_decal/steeldecal/steel_decals7{ @@ -16606,32 +16646,18 @@ /turf/simulated/floor/wood, /area/crew_quarters/bar) "CY" = ( -/obj/machinery/firealarm{ - dir = 8; - pixel_x = -24 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 8 - }, +/obj/machinery/atmospherics/unary/vent_pump/on, /turf/simulated/floor/tiled, -/area/rnd/research) +/area/rnd/research/researchdivision) "CZ" = ( -/obj/machinery/light_switch{ - pixel_x = 25 +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" }, -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 4 - }, -/obj/structure/disposalpipe/segment, -/obj/machinery/recharge_station, +/obj/machinery/atmospherics/unary/vent_scrubber/on, /turf/simulated/floor/tiled, -/area/rnd/research) +/area/rnd/research/researchdivision) "Da" = ( /turf/simulated/wall, /area/assembly/robotics) @@ -16805,6 +16831,29 @@ }, /turf/simulated/floor/wood, /area/crew_quarters/bar) +"Dq" = ( +/obj/structure/extinguisher_cabinet{ + dir = 4; + icon_state = "extinguisher_closed"; + pixel_x = -30 + }, +/obj/effect/floor_decal/borderfloor{ + dir = 8 + }, +/obj/effect/floor_decal/corner/lime/border{ + dir = 8 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 5 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/door/firedoor/glass/hidden/steel, +/turf/simulated/floor/tiled, +/area/hallway/lower/third_south) "Dr" = ( /obj/machinery/camera/network/civilian{ dir = 1 @@ -16858,32 +16907,6 @@ /turf/simulated/floor/wood, /area/crew_quarters/bar) "Du" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 8 - }, -/obj/item/device/radio/intercom{ - dir = 8; - pixel_x = -24 - }, -/turf/simulated/floor/tiled, -/area/rnd/research) -"Dv" = ( -/obj/machinery/atmospherics/unary/vent_pump/on, -/turf/simulated/floor/tiled, -/area/rnd/research) -"Dw" = ( -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/machinery/atmospherics/unary/vent_scrubber/on, -/turf/simulated/floor/tiled, -/area/rnd/research) -"Dx" = ( /obj/machinery/recharge_station, /obj/effect/floor_decal/borderfloor{ dir = 4 @@ -16898,7 +16921,63 @@ }, /obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled, -/area/rnd/research) +/area/rnd/research/researchdivision) +"Dv" = ( +/obj/structure/lattice, +/obj/structure/cable/green{ + icon_state = "32-4" + }, +/obj/machinery/atmospherics/pipe/zpipe/down/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/zpipe/down/scrubbers{ + dir = 4 + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/open, +/area/rnd/research/researchdivision) +"Dw" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/door/firedoor/glass, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/door/airlock/maintenance/rnd, +/turf/simulated/floor/tiled/steel_dirty, +/area/rnd/research/researchdivision) +"Dx" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 8 + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 8 + }, +/obj/item/device/radio/intercom{ + dir = 8; + pixel_x = -24 + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/simulated/floor/tiled, +/area/rnd/research/researchdivision) "Dy" = ( /obj/effect/floor_decal/borderfloor{ dir = 9 @@ -17149,28 +17228,6 @@ /turf/simulated/floor/tiled, /area/hydroponics) "DV" = ( -/obj/structure/extinguisher_cabinet{ - dir = 4; - icon_state = "extinguisher_closed"; - pixel_x = -30 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/lime/border{ - dir = 8 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 5 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 6 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/turf/simulated/floor/tiled, -/area/hallway/lower/third_south) -"DW" = ( /obj/machinery/status_display{ pixel_x = 32; pixel_y = 0 @@ -17198,6 +17255,40 @@ /obj/effect/floor_decal/corner/beige/bordercorner2{ dir = 6 }, +/obj/machinery/door/firedoor/glass/hidden/steel{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/third_south) +"DW" = ( +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/effect/floor_decal/borderfloor{ + dir = 4 + }, +/obj/effect/floor_decal/corner/beige/border{ + dir = 4 + }, +/obj/effect/floor_decal/borderfloor/corner2{ + dir = 5 + }, +/obj/effect/floor_decal/corner/beige/bordercorner2{ + dir = 5 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 10 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, +/obj/machinery/alarm{ + dir = 8; + icon_state = "alarm0"; + pixel_x = 24 + }, /turf/simulated/floor/tiled, /area/hallway/lower/third_south) "DX" = ( @@ -17242,64 +17333,6 @@ /turf/simulated/floor/wood, /area/crew_quarters/bar) "Ea" = ( -/obj/structure/lattice, -/obj/structure/cable/green{ - icon_state = "32-4" - }, -/obj/machinery/atmospherics/pipe/zpipe/down/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/zpipe/down/scrubbers{ - dir = 4 - }, -/obj/machinery/door/firedoor/glass, -/turf/simulated/open, -/area/rnd/research) -"Eb" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/door/firedoor/glass, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/machinery/door/airlock/maintenance/rnd, -/turf/simulated/floor/tiled/steel_dirty, -/area/rnd/research) -"Ec" = ( -/obj/structure/cable/green{ - 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 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/rnd/research) -"Ed" = ( /obj/structure/cable/green{ d1 = 4; d2 = 8; @@ -17308,8 +17341,8 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/supply, /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, /turf/simulated/floor/tiled, -/area/rnd/research) -"Ee" = ( +/area/rnd/research/researchdivision) +"Eb" = ( /obj/structure/cable/green{ d1 = 4; d2 = 8; @@ -17322,8 +17355,8 @@ dir = 4 }, /turf/simulated/floor/tiled, -/area/rnd/research) -"Ef" = ( +/area/rnd/research/researchdivision) +"Ec" = ( /obj/structure/cable/green{ d1 = 4; d2 = 8; @@ -17334,8 +17367,8 @@ }, /obj/machinery/atmospherics/pipe/manifold/hidden/supply, /turf/simulated/floor/tiled, -/area/rnd/research) -"Eg" = ( +/area/rnd/research/researchdivision) +"Ed" = ( /obj/structure/cable/green{ d1 = 1; d2 = 8; @@ -17353,8 +17386,8 @@ dir = 4 }, /turf/simulated/floor/tiled, -/area/rnd/research) -"Eh" = ( +/area/rnd/research/researchdivision) +"Ee" = ( /obj/effect/floor_decal/borderfloor{ dir = 4 }, @@ -17363,7 +17396,33 @@ }, /obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled, -/area/rnd/research) +/area/rnd/research/researchdivision) +"Ef" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 10 + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 10 + }, +/obj/structure/flora/pottedplant/stoutbush, +/turf/simulated/floor/tiled, +/area/rnd/research/researchdivision) +"Eg" = ( +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/mauve/border, +/turf/simulated/floor/tiled, +/area/rnd/research/researchdivision) +"Eh" = ( +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/mauve/border, +/obj/effect/floor_decal/borderfloor/corner2{ + dir = 9 + }, +/obj/effect/floor_decal/corner/mauve/bordercorner2{ + dir = 9 + }, +/turf/simulated/floor/tiled, +/area/rnd/research/researchdivision) "Ei" = ( /obj/structure/grille, /obj/structure/window/reinforced/full, @@ -17535,52 +17594,35 @@ /turf/simulated/wall, /area/hydroponics) "Ez" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/lime/border{ - dir = 8 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 5 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 6 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/door/firedoor/glass/hidden/steel, -/turf/simulated/floor/tiled, -/area/hallway/lower/third_south) -"EA" = ( /obj/structure/cable/green{ d1 = 1; d2 = 2; icon_state = "1-2" }, -/obj/effect/floor_decal/borderfloor{ - dir = 4 +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" }, -/obj/effect/floor_decal/corner/beige/border{ - dir = 4 - }, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 5 - }, -/obj/effect/floor_decal/corner/beige/bordercorner2{ - dir = 5 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 10 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, -/obj/machinery/door/firedoor/glass/hidden/steel{ +/obj/effect/floor_decal/steeldecal/steel_decals4{ dir = 8 }, +/obj/effect/floor_decal/steeldecal/steel_decals4{ + dir = 5 + }, /turf/simulated/floor/tiled, -/area/hallway/lower/third_south) +/area/rnd/research/researchdivision) +"EA" = ( +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/mauve/border, +/obj/effect/floor_decal/borderfloor/corner2, +/obj/effect/floor_decal/corner/mauve/bordercorner2, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/rnd/research/researchdivision) "EB" = ( /obj/structure/cable/green{ d2 = 2; @@ -17640,6 +17682,15 @@ }, /turf/simulated/floor/lino, /area/crew_quarters/bar) +"EH" = ( +/obj/machinery/alarm{ + dir = 4; + icon_state = "alarm0"; + pixel_x = -22; + pixel_y = 0 + }, +/turf/simulated/floor/tiled/techfloor, +/area/tether/surfacebase/shuttle_pad) "EI" = ( /obj/structure/disposalpipe/segment{ dir = 1; @@ -17668,62 +17719,6 @@ /turf/simulated/floor/tiled/white, /area/crew_quarters/barrestroom) "EK" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 10 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 10 - }, -/obj/structure/flora/pottedplant/stoutbush, -/turf/simulated/floor/tiled, -/area/rnd/research) -"EL" = ( -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/mauve/border, -/turf/simulated/floor/tiled, -/area/rnd/research) -"EM" = ( -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/mauve/border, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 9 - }, -/obj/effect/floor_decal/corner/mauve/bordercorner2{ - dir = 9 - }, -/turf/simulated/floor/tiled, -/area/rnd/research) -"EN" = ( -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/structure/disposalpipe/segment{ - dir = 4; - icon_state = "pipe-c" - }, -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 8 - }, -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 5 - }, -/turf/simulated/floor/tiled, -/area/rnd/research) -"EO" = ( -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/mauve/border, -/obj/effect/floor_decal/borderfloor/corner2, -/obj/effect/floor_decal/corner/mauve/bordercorner2, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/rnd/research) -"EP" = ( /obj/effect/floor_decal/borderfloor{ dir = 6 }, @@ -17736,7 +17731,83 @@ }, /obj/structure/flora/pottedplant/stoutbush, /turf/simulated/floor/tiled, -/area/rnd/research) +/area/rnd/research/researchdivision) +"EL" = ( +/obj/structure/cable/green{ + 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 + }, +/obj/effect/floor_decal/borderfloor{ + dir = 8 + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 8 + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, +/turf/simulated/floor/tiled, +/area/rnd/research/researchdivision) +"EM" = ( +/obj/structure/grille, +/obj/machinery/door/firedoor, +/obj/structure/window/reinforced/polarized/full{ + id = "rd_office" + }, +/turf/simulated/floor/plating, +/area/rnd/rdoffice) +"EN" = ( +/obj/structure/grille, +/obj/machinery/door/firedoor, +/obj/structure/window/reinforced/polarized/full{ + id = "rd_office" + }, +/obj/structure/window/reinforced/polarized{ + dir = 8; + id = "rd_office" + }, +/turf/simulated/floor/plating, +/area/rnd/rdoffice) +"EO" = ( +/obj/structure/bed/chair/office/light{ + dir = 1 + }, +/obj/machinery/button/windowtint{ + id = "rd_office"; + pixel_x = 24; + pixel_y = 16 + }, +/obj/effect/landmark/start{ + name = "Research Director" + }, +/obj/machinery/button/remote/airlock{ + id = "RDdoor"; + name = "RD Office Door Control"; + pixel_x = 30; + pixel_y = 18 + }, +/turf/simulated/floor/tiled, +/area/rnd/rdoffice) +"EP" = ( +/obj/structure/grille, +/obj/machinery/door/firedoor, +/obj/structure/window/reinforced/polarized/full{ + id = "rd_office" + }, +/obj/structure/window/reinforced/polarized{ + id = "rd_office" + }, +/turf/simulated/floor/plating, +/area/rnd/rdoffice) "EQ" = ( /obj/effect/floor_decal/borderfloor{ dir = 8 @@ -17805,16 +17876,11 @@ /turf/simulated/floor/tiled/steel_grid, /area/assembly/robotics) "EV" = ( -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" +/obj/machinery/camera/network/civilian{ + dir = 1 }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/simulated/floor/tiled/steel_grid, -/area/assembly/robotics) +/turf/simulated/floor/tiled/techfloor, +/area/tether/surfacebase/shuttle_pad) "EW" = ( /obj/effect/floor_decal/industrial/warning{ dir = 8 @@ -18150,7 +18216,7 @@ /turf/simulated/floor/tiled, /area/hallway/lower/third_south) "Fs" = ( -/obj/machinery/camera/network/northern_star, +/obj/machinery/camera/network/tether, /obj/effect/floor_decal/borderfloor{ dir = 1 }, @@ -18399,6 +18465,10 @@ }, /turf/simulated/floor/lino, /area/crew_quarters/bar) +"FK" = ( +/obj/machinery/camera/network/outside, +/turf/simulated/floor/outdoors/grass/sif/virgo3b, +/area/tether/surfacebase/outside/outside3) "FM" = ( /obj/structure/sink{ dir = 4; @@ -18414,12 +18484,6 @@ "FN" = ( /turf/simulated/wall, /area/rnd/rdoffice) -"FO" = ( -/obj/structure/grille, -/obj/machinery/door/firedoor, -/obj/structure/window/reinforced/polarized/full, -/turf/simulated/floor/plating, -/area/rnd/rdoffice) "FP" = ( /obj/machinery/door/firedoor/glass, /obj/structure/cable/green{ @@ -18960,7 +19024,7 @@ /turf/simulated/floor/tiled, /area/hallway/lower/third_south) "GJ" = ( -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 1 }, /obj/effect/floor_decal/borderfloor, @@ -19109,7 +19173,7 @@ /turf/simulated/floor/tiled, /area/hallway/lower/third_south) "GU" = ( -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 1 }, /obj/effect/floor_decal/borderfloor, @@ -19423,15 +19487,6 @@ /obj/machinery/door/firedoor/glass, /turf/simulated/floor/lino, /area/tether/surfacebase/bar_backroom) -"Hy" = ( -/obj/structure/grille, -/obj/machinery/door/firedoor, -/obj/structure/window/reinforced/polarized{ - dir = 8 - }, -/obj/structure/window/reinforced/polarized/full, -/turf/simulated/floor/plating, -/area/rnd/rdoffice) "Hz" = ( /obj/structure/table/glass, /obj/item/weapon/paper_bin{ @@ -19803,25 +19858,6 @@ }, /turf/simulated/floor/tiled, /area/rnd/rdoffice) -"HZ" = ( -/obj/structure/bed/chair/office/light{ - dir = 1 - }, -/obj/machinery/button/windowtint{ - pixel_x = 24; - pixel_y = 16 - }, -/obj/effect/landmark/start{ - name = "Research Director" - }, -/obj/machinery/button/remote/airlock{ - id = "RDdoor"; - name = "RD Office Door Control"; - pixel_x = 30; - pixel_y = 18 - }, -/turf/simulated/floor/tiled, -/area/rnd/rdoffice) "Ia" = ( /obj/structure/table/glass, /obj/machinery/photocopier/faxmachine{ @@ -19917,7 +19953,7 @@ /turf/simulated/floor/tiled, /area/rnd/rdoffice) "Ik" = ( -/mob/living/simple_animal/slime/rainbow/kendrick, +/mob/living/simple_mob/slime/xenobio/rainbow/kendrick, /turf/simulated/floor/tiled, /area/rnd/rdoffice) "Il" = ( @@ -19986,7 +20022,7 @@ "It" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 4 }, /obj/effect/floor_decal/borderfloor{ @@ -20329,13 +20365,6 @@ }, /turf/simulated/floor/plating, /area/tether/surfacebase/shuttle_pad) -"IT" = ( -/obj/structure/grille, -/obj/machinery/door/firedoor, -/obj/structure/window/reinforced/polarized, -/obj/structure/window/reinforced/polarized/full, -/turf/simulated/floor/plating, -/area/rnd/rdoffice) "IU" = ( /obj/structure/grille, /obj/structure/window/reinforced/full, @@ -20578,7 +20607,7 @@ d2 = 2; icon_state = "1-2" }, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 9 }, /obj/effect/floor_decal/borderfloor{ @@ -20739,11 +20768,6 @@ }, /turf/simulated/floor/reinforced, /area/tether/surfacebase/shuttle_pad) -"JI" = ( -/obj/structure/shuttle/engine/propulsion, -/turf/simulated/floor/reinforced, -/turf/simulated/shuttle/plating/carry, -/area/shuttle/tether/surface) "JJ" = ( /obj/machinery/atmospherics/unary/vent_scrubber/on, /turf/simulated/floor/tiled, @@ -20949,7 +20973,6 @@ dir = 1 }, /obj/machinery/alarm{ - frequency = 1441; pixel_y = 22 }, /turf/simulated/floor/tiled/steel_grid, @@ -21042,7 +21065,7 @@ /turf/simulated/floor/tiled, /area/hallway/lower/third_south) "Kk" = ( -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 1 }, /obj/effect/floor_decal/borderfloor, @@ -21252,12 +21275,6 @@ /obj/machinery/light, /turf/simulated/floor/reinforced, /area/tether/surfacebase/shuttle_pad) -"KJ" = ( -/obj/machinery/camera/network/engineering{ - dir = 1 - }, -/turf/simulated/floor/tiled/techfloor, -/area/tether/surfacebase/shuttle_pad) "KK" = ( /obj/structure/table/steel, /turf/simulated/floor/tiled/techfloor, @@ -21269,10 +21286,6 @@ }, /turf/simulated/floor/tiled/techfloor, /area/tether/surfacebase/shuttle_pad) -"KM" = ( -/obj/machinery/camera/network/northern_star, -/turf/simulated/floor/outdoors/grass/sif/virgo3b, -/area/tether/surfacebase/outside/outside3) "KO" = ( /obj/structure/table/marble, /obj/item/weapon/flame/lighter/zippo, @@ -21496,11 +21509,9 @@ /area/tether/surfacebase/atrium_three) "NA" = ( /obj/machinery/alarm{ - breach_detection = 0; dir = 8; pixel_x = 25; - pixel_y = 0; - report_danger_level = 0 + pixel_y = 0 }, /obj/effect/floor_decal/borderfloor{ dir = 6 @@ -22374,7 +22385,6 @@ /area/tether/surfacebase/atrium_three) "Yz" = ( /obj/item/device/radio/intercom{ - broadcasting = 1; dir = 8; listening = 1; name = "Common Channel"; @@ -28248,7 +28258,7 @@ ac ac ac ac -bg +fF ac ac ac @@ -29223,7 +29233,7 @@ ac ac ac ac -bg +fF ac ac ac @@ -29272,9 +29282,9 @@ ac ac ac ac -xy -xy -xy +jI +jI +jI ac ac ac @@ -29376,7 +29386,7 @@ bh bh hf bh -iv +ir jz kn kS @@ -29410,13 +29420,13 @@ ac ac ac ac -AS +fF ac ac ac -xy -Ea -xy +jI +Dv +jI ac ac ac @@ -29547,19 +29557,19 @@ uq uq tB tB -xy -xy -xy -xy -xy -xy -xy -xy -xy -xy -Eb -xy -xy +jI +jI +jI +jI +jI +jI +jI +jI +jI +jI +Dw +jI +jI ac ac ac @@ -29689,19 +29699,19 @@ vt tU wx tB -xz -yi -yN -zy -Al -AT -BH -yi -CY -Du -Ec -EK -xy +pA +xJ +yo +yX +zF +Aq +Ba +Ct +Cv +Dx +EL +Ef +jI ac ac ac @@ -29831,24 +29841,24 @@ tU vQ wy wW -xA -yj -yO -yO -yO -yO -yO -yO -yO -yO -Ed -EL +xy +xK +yp +yp +yp +yp +yp +yp +yp +yp +Ea +Eg FN FN FN -Hy -Hy -Hy +EN +EN +EN FN FN ac @@ -29973,19 +29983,19 @@ tU vR wz wW -xB -yk -yP -zz -zz -zz -BI -yT -yT -yT -Ee -EL -FO +xz +yi +yN +yY +yY +yY +Bb +yR +yR +yR +Eb +Eg +EM Gw Hi Hz @@ -30115,26 +30125,26 @@ tU vS tU wX -xC -yk -yQ -zA -zA -AU -yT -yT -yT -Dv -Ef +xA +yi +yO +zy +zy +Ar +yR +yR +yR +CY +Ec +Eh EM -FO Gx Hj HA -HZ +EO Ik Iv -IT +EP ac ac ac @@ -30257,18 +30267,18 @@ vu vS tU wW -xD -yk -yQ -zA -zA -AV -BJ -zE -zE -Dw -Eg -EN +xB +yi +yO +zy +zy +AT +BH +zC +zC +CZ +Ed +Ez FP Gy Hk @@ -30276,7 +30286,7 @@ HB Ia HC Iw -IT +EP ac ac ac @@ -30399,26 +30409,26 @@ vu vS tU wW -xE -yk +xC +yi +yP +zz +zz +AU +BI yR -zB -zB -AW -BK -yT -yT -yT -yT -EO -FO +yR +yR +yR +EA +EM Gz Hl HC HC HC Ix -IT +EP ac ac ac @@ -30541,19 +30551,19 @@ vv vS tU wW -xF -yl -yS -zC -Am -AX -BL -Cq -CZ -Dx -Eh -EP -FO +xD +yj +yQ +zA +zG +AV +BJ +BP +Cu +Du +Ee +EK +EM GA Hm HD @@ -30683,14 +30693,14 @@ vu vS tU wW -xB -yk -yT -yT -An -AY -BK -Cr +xz +yi +yR +yR +Al +AW +BI +BQ Da Da Ei @@ -30698,9 +30708,9 @@ Ei FN FN FN -FO -FO -FO +EM +EM +EM FN FN ac @@ -30825,14 +30835,14 @@ uW vT wA wY -xG -ym -yU -zD -Ao -AZ -BM -Cs +xE +yk +yS +zB +Am +AX +BK +Cb Da Dy Ej @@ -30938,9 +30948,9 @@ fh fh fh fh -iF -jI ky +pS +kx kZ lL mw @@ -30967,14 +30977,14 @@ tU vU wB wZ -xH -yn -yV -zE -Ap -zE -BN -Ct +xF +yl +yT +zC +An +zC +BL +Cq Db Dz Ek @@ -31109,14 +31119,14 @@ vw vV wC wZ -xI -yo -yW -zF -Aq -Ba -BO -Cu +xG +ym +yU +zD +Ao +AY +BM +Cr Dc DA El @@ -31251,14 +31261,14 @@ tE vW wD tE -xJ -yp -yX -zG -Ar -Bb -BP -Cv +xH +yn +yV +zE +Ap +AZ +BN +Cs Dd DB Em @@ -31393,14 +31403,14 @@ vx vX wE tE -xK -xK -yY -xy -xy -xy -BQ -xy +xI +xI +yW +jI +jI +jI +BO +jI Da DC En @@ -31546,9 +31556,9 @@ Cw Da Da Da -EV -FV -FV +yH +zw +zw Da HJ Ig @@ -33221,7 +33231,7 @@ ne ne ne lc -pA +iv pY qO gw @@ -33407,7 +33417,7 @@ ac ac ac ac -AS +fF ac ac ac @@ -33671,7 +33681,7 @@ zh zR Az Bp -Cb +iF CJ Dk DJ @@ -35832,7 +35842,7 @@ IR IR IR IR -KM +FK ac ac ac @@ -36248,7 +36258,7 @@ Jr Jv Jz JE -JI +bg JM IY IY @@ -36372,8 +36382,8 @@ BB Ck CS Do -DV -Ez +Dq +Do FA yG GO @@ -36390,7 +36400,7 @@ Js Js Jz JE -JI +bg JM IY IY @@ -36514,8 +36524,8 @@ yG Cl CT yG -yG vZ +yG FB Gl GO @@ -36532,7 +36542,7 @@ Jt Js Jz JE -JI +bg JM IY IY @@ -36656,14 +36666,14 @@ AM Cm CU CU +DV DW -EA FC Gm GW Hr ac -AS +fF ac IS IY @@ -37389,7 +37399,7 @@ JM IY KI IR -Kv +EH KA KD Kv @@ -37534,7 +37544,7 @@ IR Kv Kv KE -KJ +EV IR ac ac @@ -38104,7 +38114,7 @@ IR IR IR IR -KM +FK ac ac ac diff --git a/maps/tether/tether-04-transit.dmm b/maps/tether/tether-04-transit.dmm index 5338af8a8b..65fece4dcd 100644 --- a/maps/tether/tether-04-transit.dmm +++ b/maps/tether/tether-04-transit.dmm @@ -4,7 +4,7 @@ /area/tether/transit) "b" = ( /turf/simulated/wall/r_wall, -/area/space) +/area/tether/elevator) "c" = ( /obj/machinery/light/small{ dir = 4; @@ -20,12 +20,12 @@ /obj/structure/disposalpipe/down, /obj/effect/ceiling, /turf/simulated/open, -/area/space) +/area/tether/elevator) "d" = ( /turf/simulated/shuttle/wall/voidcraft/green{ hard_corner = 1 }, -/area/space) +/area/tether/elevator) "e" = ( /obj/machinery/atmospherics/pipe/simple/visible/supply, /obj/machinery/atmospherics/pipe/simple/visible/scrubbers, @@ -36,10 +36,10 @@ /obj/structure/disposalpipe/segment, /obj/effect/ceiling, /turf/simulated/floor/plating, -/area/space) +/area/tether/elevator) "f" = ( /turf/simulated/floor/holofloor/tiled/dark, -/area/space) +/area/tether/elevator) "g" = ( /obj/machinery/atmospherics/pipe/zpipe/up/supply{ dir = 1 @@ -59,23 +59,23 @@ /obj/structure/cable, /obj/effect/ceiling, /turf/simulated/floor/plating, -/area/space) +/area/tether/elevator) "h" = ( /obj/effect/ceiling, /turf/simulated/floor/tiled, -/area/space) +/area/tether/elevator) "i" = ( /obj/structure/disposalpipe/up, /obj/effect/ceiling, /turf/simulated/floor/tiled, -/area/space) +/area/tether/elevator) "j" = ( /obj/structure/disposalpipe/down{ dir = 1 }, /obj/effect/ceiling, /turf/simulated/floor/tiled, -/area/space) +/area/tether/elevator) (1,1,1) = {" a diff --git a/maps/tether/tether-05-station1.dmm b/maps/tether/tether-05-station1.dmm index ac19de75b0..4e3384c073 100644 --- a/maps/tether/tether-05-station1.dmm +++ b/maps/tether/tether-05-station1.dmm @@ -94,6 +94,22 @@ "aaq" = ( /turf/simulated/shuttle/wall/voidcraft, /area/shuttle/excursion/tether) +"aar" = ( +/obj/structure/cable/cyan{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/door/airlock/hatch{ + icon_state = "door_locked"; + id_tag = "engine_electrical_maintenance"; + locked = 1; + name = "Electrical Maintenance"; + req_access = list(10) + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/tiled/techmaint, +/area/engineering/engine_smes) "aas" = ( /obj/machinery/power/smes/buildable{ charge = 2e+006; @@ -158,6 +174,20 @@ }, /turf/simulated/floor, /area/engineering/engine_smes) +"aaB" = ( +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, +/obj/machinery/door/airlock/maintenance_hatch{ + name = "SMES Access"; + req_access = list(11) + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/tiled/techmaint, +/area/engineering/engine_smes) "aaC" = ( /obj/machinery/power/grid_checker, /obj/structure/cable{ @@ -173,6 +203,41 @@ "aaD" = ( /turf/simulated/shuttle/floor/black, /area/shuttle/excursion/tether) +"aaE" = ( +/obj/structure/cable/yellow{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/door/airlock/hatch{ + icon_state = "door_locked"; + id_tag = "engine_electrical_maintenance"; + locked = 1; + name = "Electrical Maintenance"; + req_access = list(10) + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/tiled/techmaint, +/area/engineering/engine_smes) +"aaF" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/door/airlock/maintenance_hatch{ + name = "SMES Access"; + req_access = list(11) + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/tiled/techmaint, +/area/engineering/engine_smes) "aaG" = ( /obj/machinery/power/smes/buildable{ charge = 2e+007; @@ -307,6 +372,14 @@ "aaT" = ( /turf/simulated/wall, /area/hallway/station/atrium) +"aaU" = ( +/obj/machinery/door/airlock/maintenance_hatch{ + name = "SMES Access"; + req_access = list(11) + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/tiled/steel_grid, +/area/engineering/engine_monitoring) "aaV" = ( /turf/simulated/wall/r_wall, /area/crew_quarters/sleep/engi_wash) @@ -328,6 +401,11 @@ }, /turf/simulated/floor/tiled/techmaint, /area/engineering/engine_smes) +"aaY" = ( +/obj/machinery/door/airlock/maintenance/common, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor, +/area/maintenance/station/eng_lower) "aaZ" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ @@ -482,6 +560,18 @@ }, /turf/simulated/shuttle/wall/voidcraft, /area/shuttle/excursion/tether) +"abq" = ( +/obj/machinery/door/airlock/maintenance_hatch{ + frequency = 1379; + icon_state = "door_closed"; + id_tag = "engine_airlock_interior"; + locked = 0; + name = "Engine Airlock Interior"; + req_access = list(11) + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/plating, +/area/engineering/engine_airlock) "abr" = ( /obj/structure/cable/cyan{ d1 = 1; @@ -491,20 +581,23 @@ /turf/simulated/floor/tiled/techmaint, /area/engineering/engine_smes) "abs" = ( -/obj/structure/cable/cyan{ - d1 = 4; - d2 = 8; - icon_state = "4-8" +/obj/machinery/door/airlock/maintenance_hatch{ + frequency = 1379; + icon_state = "door_closed"; + id_tag = "engine_airlock_exterior"; + locked = 0; + name = "Engine Airlock Exterior"; + req_access = list(11) }, -/obj/machinery/door/airlock/hatch{ - icon_state = "door_locked"; - id_tag = "engine_electrical_maintenance"; - locked = 1; - name = "Electrical Maintenance"; - req_access = list(10) +/obj/machinery/atmospherics/pipe/simple/hidden{ + dir = 4 }, -/turf/simulated/floor/tiled/techmaint, -/area/engineering/engine_smes) +/obj/machinery/atmospherics/pipe/simple/hidden{ + dir = 4 + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/tiled/steel_grid, +/area/engineering/engine_airlock) "abt" = ( /obj/machinery/atmospherics/unary/vent_scrubber/on, /obj/structure/cable/yellow{ @@ -523,18 +616,16 @@ /turf/simulated/floor/tiled/techmaint, /area/engineering/engine_smes) "abv" = ( -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8"; - pixel_x = 0 +/obj/effect/floor_decal/industrial/warning/corner{ + dir = 4 }, -/obj/machinery/door/airlock/maintenance_hatch{ - name = "SMES Access"; - req_access = list(11) +/obj/structure/table/reinforced, +/obj/item/device/pipe_painter, +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 4 }, -/turf/simulated/floor/tiled/techmaint, -/area/engineering/engine_smes) +/turf/simulated/floor/tiled, +/area/engineering/atmos/backup) "abw" = ( /obj/structure/cable{ d1 = 1; @@ -592,6 +683,21 @@ /obj/random/maintenance/medical, /turf/simulated/floor, /area/maintenance/station/eng_lower) +"abB" = ( +/obj/effect/floor_decal/steeldecal/steel_decals6{ + dir = 1 + }, +/obj/effect/floor_decal/industrial/warning{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/manifold/visible/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/manifold/visible/scrubbers{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/engineering/atmos/backup) "abC" = ( /turf/simulated/wall, /area/maintenance/station/eng_lower) @@ -604,20 +710,31 @@ /turf/simulated/floor/tiled/techmaint, /area/engineering/engine_smes) "abE" = ( -/obj/structure/cable/yellow{ - d1 = 4; - d2 = 8; - icon_state = "4-8" +/obj/effect/floor_decal/steeldecal/steel_decals6{ + dir = 4 }, -/obj/machinery/door/airlock/hatch{ - icon_state = "door_locked"; - id_tag = "engine_electrical_maintenance"; - locked = 1; - name = "Electrical Maintenance"; - req_access = list(10) +/obj/effect/floor_decal/industrial/warning{ + dir = 1 }, -/turf/simulated/floor/tiled/techmaint, -/area/engineering/engine_smes) +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/machinery/button/remote/blast_door{ + desc = "A remote control-switch for the engine control room blast doors."; + id = "EngineEmitterPortWest2"; + name = "Engine Room Blast Doors"; + pixel_x = 25; + pixel_y = 0; + req_access = null; + req_one_access = list(11,24) + }, +/obj/machinery/atmospherics/unary/vent_scrubber/on{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/engineering/atmos/backup) "abF" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 5 @@ -687,23 +804,21 @@ /turf/simulated/shuttle/floor/black, /area/shuttle/excursion/tether) "abL" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/door/airlock/maintenance_hatch{ - name = "SMES Access"; - req_access = list(11) +/obj/structure/grille, +/obj/machinery/door/firedoor/glass, +/obj/structure/cable/green{ + d2 = 4; + icon_state = "0-4" }, /obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" + d2 = 2; + icon_state = "0-2" }, -/turf/simulated/floor/tiled/techmaint, -/area/engineering/engine_smes) +/obj/structure/window/reinforced/polarized/full{ + id = "pathfinder_office" + }, +/turf/simulated/floor/plating, +/area/tether/station/pathfinder_office) "abM" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -808,10 +923,9 @@ /turf/simulated/floor, /area/maintenance/station/eng_lower) "abU" = ( -/obj/machinery/camera/network/northern_star, -/obj/effect/floor_decal/steeldecal/steel_decals6{ - dir = 10 - }, +/obj/effect/floor_decal/borderfloorblack, +/obj/effect/floor_decal/industrial/danger, +/obj/machinery/camera/network/exploration, /turf/simulated/floor/tiled, /area/tether/station/excursion_dock) "abV" = ( @@ -835,12 +949,11 @@ /turf/simulated/floor/tiled, /area/hallway/station/atrium) "abY" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - name = "SMES Access"; - req_access = list(11) +/obj/machinery/alarm{ + pixel_y = 22 }, -/turf/simulated/floor/tiled/steel_grid, -/area/engineering/engine_monitoring) +/turf/simulated/floor, +/area/maintenance/station/eng_lower) "abZ" = ( /turf/simulated/wall/r_wall, /area/engineering/atmos/backup) @@ -884,7 +997,7 @@ dir = 4 }, /obj/structure/railing, -/mob/living/simple_animal/fish/koi/poisonous, +/mob/living/simple_mob/animal/passive/fish/koi/poisonous, /turf/simulated/floor/water/pool, /area/hallway/station/atrium) "acg" = ( @@ -894,6 +1007,15 @@ /obj/effect/floor_decal/rust, /turf/simulated/floor, /area/maintenance/station/eng_lower) +"aci" = ( +/obj/machinery/atmospherics/unary/vent_scrubber/on, +/obj/structure/table/standard, +/obj/random/soap, +/obj/machinery/alarm{ + pixel_y = 22 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/sleep/engi_wash) "acj" = ( /obj/effect/decal/cleanable/dirt, /turf/simulated/floor, @@ -914,6 +1036,18 @@ }, /turf/simulated/floor/tiled, /area/hallway/station/atrium) +"aco" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/obj/machinery/door/airlock/maintenance/common, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor, +/area/hallway/station/atrium) "acp" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -942,6 +1076,12 @@ }, /turf/simulated/floor/tiled, /area/hallway/station/atrium) +"acs" = ( +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor, +/area/hallway/station/atrium) "act" = ( /obj/machinery/atmospherics/unary/vent_pump/on{ dir = 1 @@ -966,6 +1106,17 @@ }, /turf/simulated/floor/tiled, /area/engineering/hallway) +"acv" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/structure/cable/green{ + d2 = 4; + icon_state = "0-4" + }, +/obj/effect/decal/cleanable/dirt, +/turf/simulated/floor, +/area/vacant/vacant_restaurant_lower) "acw" = ( /obj/machinery/atmospherics/unary/vent_scrubber/on{ dir = 1 @@ -1060,6 +1211,26 @@ "acL" = ( /turf/simulated/wall/r_wall, /area/engineering/engine_smes) +"acM" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/floor_decal/rust, +/obj/structure/disposalpipe/broken{ + icon_state = "pipe-b"; + dir = 4 + }, +/turf/simulated/floor, +/area/vacant/vacant_restaurant_lower) "acN" = ( /obj/structure/cable/green{ d1 = 4; @@ -1329,6 +1500,24 @@ }, /turf/simulated/floor/tiled, /area/engineering/engine_monitoring) +"adp" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/effect/floor_decal/rust, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor, +/area/vacant/vacant_restaurant_lower) "adq" = ( /obj/structure/cable/green{ d1 = 2; @@ -1446,7 +1635,7 @@ /obj/structure/railing{ dir = 1 }, -/mob/living/simple_animal/fish/koi/poisonous, +/mob/living/simple_mob/animal/passive/fish/koi/poisonous, /turf/simulated/floor/water/pool, /area/hallway/station/atrium) "adA" = ( @@ -1616,12 +1805,54 @@ }, /turf/simulated/floor/tiled, /area/engineering/engine_monitoring) +"adR" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/door/airlock/glass, +/obj/machinery/door/firedoor/glass, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/tiled/steel_grid, +/area/hallway/station/atrium) "adS" = ( /obj/machinery/atmospherics/binary/pump{ dir = 1 }, /turf/simulated/floor/tiled, /area/engineering/atmos/backup) +"adT" = ( +/obj/effect/floor_decal/steeldecal/steel_decals4{ + dir = 6 + }, +/obj/effect/floor_decal/steeldecal/steel_decals4{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 10 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/hallway/station/atrium) "adU" = ( /obj/structure/cable/green{ d1 = 1; @@ -1668,6 +1899,17 @@ }, /turf/simulated/floor, /area/maintenance/substation/engineering) +"adX" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/hallway/station/atrium) "adY" = ( /obj/machinery/atmospherics/binary/pump{ dir = 8 @@ -1692,6 +1934,19 @@ /obj/machinery/atmospherics/unary/vent_pump/on, /turf/simulated/floor/tiled/techmaint, /area/engineering/engine_smes) +"aec" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/cable/green{ + d1 = 1; + d2 = 8; + icon_state = "1-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/hallway/station/atrium) "aed" = ( /obj/effect/floor_decal/steeldecal/steel_decals10, /obj/effect/floor_decal/steeldecal/steel_decals10{ @@ -1704,6 +1959,13 @@ }, /turf/simulated/floor/tiled, /area/tether/station/explorer_prep) +"aee" = ( +/obj/structure/disposalpipe/junction{ + icon_state = "pipe-j2"; + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/hallway/station/atrium) "aef" = ( /obj/random/junk, /obj/random/trash, @@ -1732,6 +1994,36 @@ }, /turf/simulated/shuttle/wall/voidcraft, /area/shuttle/excursion/tether) +"aek" = ( +/obj/machinery/door/airlock/maintenance/common, +/obj/machinery/atmospherics/pipe/simple/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor, +/area/hallway/station/docks) +"ael" = ( +/obj/machinery/atmospherics/pipe/manifold/hidden{ + dir = 8; + icon_state = "map" + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/meter{ + frequency = 1443; + id = "dist_aux_meter"; + name = "Distribution Loop" + }, +/obj/machinery/alarm{ + dir = 4; + icon_state = "alarm0"; + pixel_x = -22; + pixel_y = 0 + }, +/turf/simulated/floor, +/area/hallway/station/docks) "aem" = ( /obj/effect/floor_decal/industrial/outline/yellow, /obj/machinery/space_heater, @@ -1777,10 +2069,10 @@ /turf/simulated/shuttle/floor/black, /area/shuttle/excursion/tether) "aeq" = ( -/turf/simulated/shuttle/wall/voidcraft/green{ - hard_corner = 1 - }, -/area/hallway/station/atrium) +/obj/structure/shuttle/engine/propulsion, +/turf/simulated/floor/reinforced, +/turf/simulated/shuttle/plating/airless/carry, +/area/shuttle/excursion/tether) "aer" = ( /obj/effect/floor_decal/borderfloor{ dir = 1 @@ -1792,7 +2084,7 @@ /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 4 }, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 2 }, /turf/simulated/floor/tiled, @@ -2035,6 +2327,12 @@ }, /turf/simulated/floor/tiled, /area/engineering/hallway) +"aeF" = ( +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor, +/area/hallway/station/docks) "aeG" = ( /obj/structure/cable{ d1 = 1; @@ -2049,6 +2347,11 @@ }, /turf/simulated/shuttle/floor/black, /area/shuttle/excursion/tether) +"aeI" = ( +/obj/machinery/door/airlock/multi_tile/glass, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor, +/area/hallway/station/docks) "aeJ" = ( /obj/effect/floor_decal/steeldecal/steel_decals5, /obj/machinery/light{ @@ -2107,8 +2410,10 @@ /turf/simulated/floor/tiled, /area/tether/station/excursion_dock) "aeO" = ( -/turf/simulated/floor/holofloor/tiled/dark, -/area/hallway/station/atrium) +/turf/simulated/shuttle/wall/voidcraft/green{ + hard_corner = 1 + }, +/area/tether/elevator) "aeP" = ( /obj/machinery/door/firedoor/glass/hidden/steel{ dir = 2 @@ -2128,6 +2433,10 @@ }, /turf/simulated/floor/tiled, /area/engineering/engine_monitoring) +"aeR" = ( +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor, +/area/hallway/station/docks) "aeS" = ( /obj/structure/cable/green{ d1 = 1; @@ -2153,6 +2462,22 @@ }, /turf/simulated/floor/tiled, /area/engineering/engine_monitoring) +"aeT" = ( +/obj/structure/grille, +/obj/machinery/door/firedoor/glass, +/obj/structure/cable/green{ + d2 = 4; + icon_state = "0-4" + }, +/obj/structure/cable/green{ + d2 = 8; + icon_state = "0-8" + }, +/obj/structure/window/reinforced/polarized/full{ + id = "pathfinder_office" + }, +/turf/simulated/floor/plating, +/area/tether/station/pathfinder_office) "aeU" = ( /obj/machinery/door/firedoor/glass/hidden/steel, /turf/simulated/floor/tiled, @@ -2199,6 +2524,18 @@ /obj/item/clothing/head/helmet/space/void/pilot, /turf/simulated/shuttle/floor/black, /area/shuttle/excursion/tether) +"aeZ" = ( +/obj/structure/grille, +/obj/machinery/door/firedoor/glass, +/obj/structure/cable/green{ + d2 = 8; + icon_state = "0-8" + }, +/obj/structure/window/reinforced/polarized/full{ + id = "pathfinder_office" + }, +/turf/simulated/floor/plating, +/area/tether/station/pathfinder_office) "afa" = ( /obj/structure/cable/green{ d1 = 2; @@ -2218,6 +2555,19 @@ }, /turf/simulated/floor/tiled/monotile, /area/tether/station/excursion_dock) +"afb" = ( +/obj/structure/grille, +/obj/machinery/door/firedoor/glass, +/obj/structure/cable/green{ + d2 = 4; + icon_state = "0-4" + }, +/obj/structure/cable/green, +/obj/structure/window/reinforced/polarized/full{ + id = "pathfinder_office" + }, +/turf/simulated/floor/plating, +/area/tether/station/pathfinder_office) "afc" = ( /obj/effect/floor_decal/steeldecal/steel_decals4{ dir = 8 @@ -2279,6 +2629,20 @@ }, /turf/simulated/floor/tiled, /area/engineering/engine_monitoring) +"afg" = ( +/obj/item/clothing/under/gladiator, +/obj/item/clothing/head/helmet/gladiator, +/turf/simulated/floor, +/area/tether/station/pathfinder_office) +"afh" = ( +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/plating, +/area/tether/station/explorer_meeting) "afi" = ( /obj/machinery/camera/network/engine{ dir = 1 @@ -2328,6 +2692,12 @@ /obj/effect/floor_decal/corner/yellow/bordercorner2, /turf/simulated/floor/tiled, /area/engineering/engine_monitoring) +"afl" = ( +/obj/machinery/alarm{ + pixel_y = 22 + }, +/turf/simulated/floor/tiled, +/area/hallway/station/atrium) "afm" = ( /obj/structure/cable/green{ d1 = 1; @@ -2350,9 +2720,30 @@ /turf/simulated/floor/tiled, /area/engineering/hallway) "afn" = ( -/obj/machinery/door/airlock/maintenance/common, -/turf/simulated/floor, -/area/maintenance/station/eng_lower) +/obj/effect/floor_decal/borderfloor{ + dir = 9 + }, +/obj/effect/floor_decal/corner/lightgrey/border{ + dir = 9 + }, +/obj/machinery/alarm{ + dir = 4; + icon_state = "alarm0"; + pixel_x = -22; + pixel_y = 0 + }, +/turf/simulated/floor/tiled, +/area/hallway/station/atrium) +"afo" = ( +/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/tiled, +/area/hallway/station/docks) "afp" = ( /obj/machinery/light{ dir = 8; @@ -2362,6 +2753,43 @@ /obj/machinery/portable_atmospherics/canister/phoron, /turf/simulated/floor, /area/engineering/storage) +"afq" = ( +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/turf/simulated/floor/tiled, +/area/hallway/station/docks) +"afr" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, +/obj/effect/floor_decal/borderfloor{ + dir = 4 + }, +/obj/effect/floor_decal/corner/lightgrey/border{ + dir = 4 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 10 + }, +/obj/machinery/alarm{ + dir = 8; + pixel_x = 25; + pixel_y = 0 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 10 + }, +/turf/simulated/floor/tiled, +/area/hallway/station/docks) "afs" = ( /obj/effect/floor_decal/rust, /obj/machinery/light{ @@ -2373,12 +2801,120 @@ /obj/effect/floor_decal/industrial/outline/yellow, /turf/simulated/floor, /area/engineering/storage) -"afy" = ( -/obj/structure/sign/deck1, -/turf/simulated/shuttle/wall/voidcraft/green{ - hard_corner = 1 +"aft" = ( +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" }, -/area/hallway/station/atrium) +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/machinery/atmospherics/unary/vent_scrubber/on{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/turf/simulated/floor/tiled, +/area/hallway/station/docks) +"afu" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, +/obj/machinery/status_display{ + layer = 4; + pixel_x = 32; + pixel_y = 0 + }, +/obj/effect/floor_decal/borderfloor{ + dir = 4 + }, +/obj/effect/floor_decal/corner/lightgrey/border{ + dir = 4 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 10 + }, +/turf/simulated/floor/tiled, +/area/hallway/station/docks) +"afv" = ( +/obj/structure/grille, +/obj/structure/cable/green{ + d2 = 4; + icon_state = "0-4" + }, +/obj/machinery/door/firedoor/glass, +/obj/machinery/door/blast/regular{ + density = 0; + dir = 4; + icon_state = "pdoor0"; + id = "bridge blast"; + name = "Bridge Blast Doors"; + opacity = 0 + }, +/obj/structure/window/reinforced/full, +/obj/structure/window/reinforced{ + dir = 1 + }, +/turf/simulated/floor/plating, +/area/bridge) +"afw" = ( +/obj/structure/grille, +/obj/structure/cable/green{ + d2 = 8; + icon_state = "0-8" + }, +/obj/structure/cable/green{ + d2 = 4; + icon_state = "0-4" + }, +/obj/machinery/door/firedoor/glass, +/obj/machinery/door/blast/regular{ + density = 0; + dir = 4; + icon_state = "pdoor0"; + id = "bridge blast"; + name = "Bridge Blast Doors"; + opacity = 0 + }, +/obj/structure/window/reinforced/full, +/obj/structure/window/reinforced{ + dir = 1 + }, +/turf/simulated/floor/plating, +/area/bridge) +"afx" = ( +/obj/structure/grille, +/obj/structure/cable/green{ + d2 = 8; + icon_state = "0-8" + }, +/obj/structure/cable/green{ + d2 = 2; + icon_state = "0-2" + }, +/obj/machinery/door/firedoor/glass, +/obj/machinery/door/blast/regular{ + density = 0; + dir = 4; + icon_state = "pdoor0"; + id = "bridge blast"; + name = "Bridge Blast Doors"; + opacity = 0 + }, +/obj/structure/window/reinforced/full, +/obj/structure/window/reinforced{ + dir = 1 + }, +/turf/simulated/floor/plating, +/area/bridge) +"afy" = ( +/turf/simulated/floor/holofloor/tiled/dark, +/area/tether/elevator) "afz" = ( /obj/machinery/door/firedoor/glass/hidden/steel{ dir = 1 @@ -2389,11 +2925,24 @@ /obj/machinery/hologram/holopad, /turf/simulated/floor/tiled, /area/hallway/station/atrium) +"afB" = ( +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply, +/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers, +/turf/simulated/floor/tiled, +/area/hallway/station/docks) "afC" = ( /turf/simulated/wall/r_wall, /area/hallway/station/atrium) "afD" = ( -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 4 }, /obj/effect/floor_decal/borderfloor{ @@ -2436,6 +2985,25 @@ /obj/structure/closet/emcloset, /turf/simulated/floor/tiled, /area/hallway/station/atrium) +"afG" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, +/obj/machinery/atmospherics/pipe/simple/hidden{ + dir = 4 + }, +/obj/effect/floor_decal/borderfloor{ + dir = 4 + }, +/obj/effect/floor_decal/corner/lightgrey/border{ + dir = 4 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply, +/turf/simulated/floor/tiled, +/area/hallway/station/docks) "afH" = ( /obj/structure/cable/green{ d1 = 4; @@ -2466,6 +3034,25 @@ }, /turf/simulated/floor/tiled, /area/hallway/station/atrium) +"afK" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, +/obj/effect/floor_decal/borderfloor{ + dir = 4 + }, +/obj/effect/floor_decal/corner/blue/border{ + dir = 4 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 10 + }, +/obj/effect/floor_decal/steeldecal/steel_decals4, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/bridge_hallway) "afL" = ( /turf/simulated/floor/tiled, /area/engineering/engine_monitoring) @@ -2562,10 +3149,29 @@ /turf/simulated/floor/tiled, /area/engineering/workshop) "afV" = ( -/obj/structure/shuttle/engine/propulsion, -/turf/simulated/floor/reinforced, -/turf/simulated/shuttle/plating/airless/carry, -/area/shuttle/excursion/tether) +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 8 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 1 + }, +/obj/effect/floor_decal/steeldecal/steel_decals5, +/obj/effect/floor_decal/steeldecal/steel_decals6{ + dir = 5 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 10 + }, +/obj/machinery/alarm{ + pixel_y = 22 + }, +/turf/simulated/floor/tiled, +/area/bridge_hallway) +"afW" = ( +/obj/structure/closet/secure_closet/pilot, +/obj/machinery/camera/network/exploration, +/turf/simulated/floor/tiled, +/area/tether/station/explorer_prep) "afX" = ( /obj/structure/cable/green{ d1 = 1; @@ -2586,6 +3192,10 @@ }, /turf/simulated/floor/tiled, /area/engineering/hallway) +"afY" = ( +/obj/item/weapon/material/twohanded/spear/foam, +/turf/simulated/floor, +/area/tether/station/pathfinder_office) "afZ" = ( /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 10 @@ -2601,16 +3211,29 @@ }, /turf/simulated/floor/tiled, /area/engineering/hallway) +"aga" = ( +/obj/item/weapon/storage/fancy/crayons{ + desc = "Special food for special warriors of the expedition force."; + name = "spearman ration" + }, +/turf/simulated/floor, +/area/tether/station/pathfinder_office) "agb" = ( /obj/structure/sign/department/eng, /turf/simulated/wall/r_wall, /area/hallway/station/atrium) -"agd" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 9 +"agc" = ( +/obj/structure/grille, +/obj/structure/cable/green, +/obj/machinery/door/firedoor/glass, +/obj/structure/window/reinforced/polarized/full{ + id = "ce_office" }, -/obj/effect/floor_decal/corner/lightgrey/border{ - dir = 9 +/turf/simulated/floor, +/area/crew_quarters/heads/chief) +"agd" = ( +/obj/effect/landmark{ + name = "lightsout" }, /turf/simulated/floor/tiled, /area/hallway/station/atrium) @@ -2667,6 +3290,197 @@ }, /turf/simulated/floor/tiled, /area/hallway/station/atrium) +"agi" = ( +/obj/structure/grille, +/obj/machinery/door/firedoor/glass, +/obj/machinery/door/blast/regular{ + density = 0; + dir = 1; + icon_state = "pdoor0"; + id = "englockdown"; + name = "Engineering Lockdown"; + opacity = 0 + }, +/obj/structure/window/reinforced/polarized/full{ + id = "ce_office" + }, +/obj/structure/window/reinforced/polarized{ + dir = 8; + id = "ce_office" + }, +/turf/simulated/floor, +/area/crew_quarters/heads/chief) +"agj" = ( +/obj/structure/grille, +/obj/structure/cable/green{ + d2 = 4; + icon_state = "0-4" + }, +/obj/structure/cable/green{ + d2 = 8; + icon_state = "0-8" + }, +/obj/structure/cable/green{ + d2 = 2; + icon_state = "0-2" + }, +/obj/machinery/door/firedoor/glass, +/obj/structure/window/reinforced/polarized/full{ + id = "hop_office" + }, +/obj/structure/window/reinforced/polarized{ + dir = 1; + id = "hop_office" + }, +/turf/simulated/floor/plating, +/area/crew_quarters/heads/hop) +"agk" = ( +/obj/structure/grille, +/obj/structure/cable/green{ + d2 = 4; + icon_state = "0-4" + }, +/obj/structure/cable/green{ + d2 = 8; + icon_state = "0-8" + }, +/obj/machinery/door/firedoor/glass, +/obj/structure/window/reinforced/polarized/full{ + id = "hop_office" + }, +/obj/structure/window/reinforced/polarized{ + dir = 1; + id = "hop_office" + }, +/turf/simulated/floor/plating, +/area/crew_quarters/heads/hop) +"agl" = ( +/obj/structure/grille, +/obj/structure/cable/green{ + d2 = 8; + icon_state = "0-8" + }, +/obj/machinery/door/firedoor/glass, +/obj/structure/window/reinforced/polarized/full{ + id = "hop_office" + }, +/obj/structure/window/reinforced/polarized{ + dir = 1; + id = "hop_office" + }, +/turf/simulated/floor/plating, +/area/crew_quarters/heads/hop) +"agm" = ( +/obj/structure/grille, +/obj/machinery/door/firedoor/glass, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/green{ + d2 = 4; + icon_state = "0-4" + }, +/obj/structure/window/reinforced/polarized/full{ + id = "hop_office" + }, +/turf/simulated/floor/plating, +/area/crew_quarters/heads/hop) +"agn" = ( +/obj/structure/grille, +/obj/machinery/door/firedoor/glass, +/obj/structure/cable/green{ + d2 = 4; + icon_state = "0-4" + }, +/obj/structure/window/reinforced/polarized/full{ + id = "hop_office" + }, +/turf/simulated/floor/plating, +/area/crew_quarters/heads/hop) +"ago" = ( +/obj/structure/grille, +/obj/machinery/door/firedoor/border_only, +/obj/structure/window/reinforced/polarized/full{ + id = "library_study" + }, +/turf/simulated/floor/plating, +/area/library) +"agp" = ( +/obj/machinery/button/windowtint{ + id = "library_study"; + pixel_x = 26; + pixel_y = -26 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/turf/simulated/floor/carpet, +/area/library) +"agq" = ( +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 4 + }, +/obj/machinery/camera/network/exploration, +/turf/simulated/floor/tiled/monotile, +/area/tether/station/excursion_dock) +"agr" = ( +/obj/effect/floor_decal/steeldecal/steel_decals6{ + dir = 10 + }, +/obj/machinery/camera/network/exploration, +/turf/simulated/floor/tiled, +/area/tether/station/excursion_dock) +"ags" = ( +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 1 + }, +/obj/machinery/camera/network/exploration{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/tether/station/pathfinder_office) +"agt" = ( +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 8 + }, +/obj/machinery/camera/network/exploration, +/turf/simulated/floor/tiled/monotile, +/area/tether/station/excursion_dock) +"agu" = ( +/obj/structure/sign/deck1, +/turf/simulated/shuttle/wall/voidcraft/green{ + hard_corner = 1 + }, +/area/tether/elevator) +"agv" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/camera/network/exploration{ + dir = 1 + }, +/turf/simulated/floor/tiled/monotile, +/area/tether/station/excursion_dock) +"agw" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/floor_decal/borderfloor{ + dir = 8 + }, +/obj/effect/floor_decal/corner/purple/border{ + icon_state = "bordercolor"; + dir = 8 + }, +/obj/structure/extinguisher_cabinet{ + dir = 4; + icon_state = "extinguisher_closed"; + pixel_x = -30 + }, +/obj/machinery/camera/network/exploration{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/tether/station/explorer_meeting) "agx" = ( /obj/structure/bed/chair/comfy/blue{ icon_state = "comfychair_preview"; @@ -2674,11 +3488,20 @@ }, /turf/simulated/shuttle/floor/black, /area/shuttle/excursion/tether) -"agE" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/full, -/turf/simulated/floor, -/area/hallway/station/atrium) +"agy" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 4 + }, +/obj/effect/floor_decal/corner/purple/border{ + icon_state = "bordercolor"; + dir = 4 + }, +/obj/machinery/photocopier, +/obj/machinery/camera/network/exploration{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/tether/station/explorer_meeting) "agF" = ( /obj/effect/floor_decal/industrial/warning{ icon_state = "warning"; @@ -2903,7 +3726,7 @@ dir = 4 }, /obj/effect/floor_decal/steeldecal/steel_decals7, -/obj/machinery/camera/network/northern_star, +/obj/machinery/camera/network/tether, /obj/structure/disposalpipe/segment{ dir = 4 }, @@ -2947,34 +3770,6 @@ }, /turf/simulated/floor/plating, /area/engineering/engine_airlock) -"ahu" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - frequency = 1379; - icon_state = "door_closed"; - id_tag = "engine_airlock_interior"; - locked = 0; - name = "Engine Airlock Interior"; - req_access = list(11) - }, -/turf/simulated/floor/plating, -/area/engineering/engine_airlock) -"ahw" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - frequency = 1379; - icon_state = "door_closed"; - id_tag = "engine_airlock_exterior"; - locked = 0; - name = "Engine Airlock Exterior"; - req_access = list(11) - }, -/obj/machinery/atmospherics/pipe/simple/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden{ - dir = 4 - }, -/turf/simulated/floor/tiled/steel_grid, -/area/engineering/engine_airlock) "ahy" = ( /obj/effect/floor_decal/industrial/warning{ icon_state = "warning"; @@ -4075,7 +4870,6 @@ dir = 8 }, /obj/machinery/alarm{ - frequency = 1441; pixel_y = 22 }, /obj/vehicle/train/engine, @@ -4387,29 +5181,6 @@ }, /turf/simulated/floor/tiled/monotile, /area/tether/station/explorer_prep) -"amX" = ( -/obj/effect/floor_decal/steeldecal/steel_decals6{ - dir = 4 - }, -/obj/effect/floor_decal/industrial/warning{ - dir = 1 - }, -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/machinery/button/remote/blast_door{ - desc = "A remote control-switch for the engine control room blast doors."; - id = "EngineEmitterPortWest2"; - name = "Engine Room Blast Doors"; - pixel_x = 25; - pixel_y = 0; - req_access = null; - req_one_access = list(11,24) - }, -/turf/simulated/floor/tiled, -/area/engineering/atmos/backup) "amY" = ( /obj/structure/table/reinforced, /obj/item/weapon/storage/firstaid/regular, @@ -4768,17 +5539,6 @@ }, /turf/simulated/shuttle/floor/black, /area/shuttle/excursion/tether) -"aoe" = ( -/obj/effect/floor_decal/steeldecal/steel_decals6{ - dir = 1 - }, -/obj/effect/floor_decal/industrial/warning{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/simple/visible/supply, -/obj/machinery/atmospherics/pipe/simple/visible/scrubbers, -/turf/simulated/floor/tiled, -/area/engineering/atmos/backup) "aof" = ( /obj/machinery/power/breakerbox/activated{ RCon_tag = "Civilian Substation Bypass" @@ -5026,14 +5786,6 @@ dir = 1 }, /area/holodeck_control) -"aoW" = ( -/obj/effect/floor_decal/industrial/warning/corner{ - dir = 4 - }, -/obj/structure/table/reinforced, -/obj/item/device/pipe_painter, -/turf/simulated/floor/tiled, -/area/engineering/atmos/backup) "aoX" = ( /obj/structure/table/reinforced, /obj/item/stack/material/steel{ @@ -5861,7 +6613,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 1 }, /obj/effect/floor_decal/borderfloor, @@ -7774,7 +8526,7 @@ /obj/effect/floor_decal/industrial/loading{ dir = 1 }, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 4 }, /obj/structure/disposalpipe/segment, @@ -8393,37 +9145,6 @@ }, /turf/simulated/floor/tiled, /area/hallway/station/docks) -"ayF" = ( -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, -/obj/machinery/atmospherics/pipe/simple/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/obj/effect/floor_decal/corner/lightgrey/border{ - dir = 4 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 10 - }, -/turf/simulated/floor/tiled, -/area/hallway/station/docks) -"ayG" = ( -/obj/machinery/door/airlock/maintenance/common, -/obj/machinery/atmospherics/pipe/simple/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/turf/simulated/floor, -/area/hallway/station/docks) "ayK" = ( /obj/machinery/computer/rcon, /turf/simulated/floor/tiled/dark, @@ -8646,27 +9367,8 @@ }, /turf/simulated/floor/tiled/dark, /area/bridge) -"azv" = ( -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/obj/effect/floor_decal/corner/blue/border{ - dir = 4 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 10 - }, -/obj/effect/floor_decal/steeldecal/steel_decals4, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/bridge_hallway) "azy" = ( -/mob/living/simple_animal/corgi/Ian, +/mob/living/simple_mob/animal/passive/dog/corgi/Ian, /turf/simulated/floor/carpet, /area/crew_quarters/heads/hop) "azz" = ( @@ -8775,7 +9477,7 @@ /area/storage/tools) "azQ" = ( /obj/machinery/atmospherics/pipe/simple/hidden, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 5 }, /obj/effect/floor_decal/borderfloor{ @@ -9008,7 +9710,7 @@ dir = 2; icon_state = "pipe-c" }, -/obj/machinery/camera/network/northern_star, +/obj/machinery/camera/network/tether, /obj/effect/floor_decal/borderfloor{ dir = 1 }, @@ -9240,7 +9942,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/obj/machinery/camera/network/northern_star, +/obj/machinery/camera/network/tether, /obj/effect/floor_decal/borderfloor{ dir = 1 }, @@ -9559,7 +10261,7 @@ /area/crew_quarters/sleep/engi_wash) "aAX" = ( /obj/structure/bed/chair, -/obj/machinery/camera/network/northern_star, +/obj/machinery/camera/network/tether, /turf/simulated/floor/tiled, /area/hallway/station/docks) "aAZ" = ( @@ -9948,7 +10650,7 @@ /turf/simulated/floor/tiled, /area/hallway/station/atrium) "aCc" = ( -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 9 }, /turf/simulated/floor/tiled, @@ -10014,22 +10716,6 @@ }, /turf/simulated/floor/tiled, /area/bridge_hallway) -"aCr" = ( -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 8 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 1 - }, -/obj/effect/floor_decal/steeldecal/steel_decals5, -/obj/effect/floor_decal/steeldecal/steel_decals6{ - dir = 5 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 10 - }, -/turf/simulated/floor/tiled, -/area/bridge_hallway) "aCs" = ( /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 8 @@ -10474,12 +11160,6 @@ /obj/machinery/door/firedoor/glass, /turf/simulated/floor/plating, /area/tether/station/dock_one) -"aDI" = ( -/obj/machinery/atmospherics/unary/vent_scrubber/on, -/obj/structure/table/standard, -/obj/random/soap, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/sleep/engi_wash) "aDJ" = ( /obj/machinery/atmospherics/pipe/simple/hidden, /turf/simulated/floor/tiled, @@ -10588,7 +11268,7 @@ /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 6 }, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 4 }, /obj/structure/disposalpipe/segment, @@ -10732,7 +11412,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/mob/living/simple_animal/fox/fluff/Renault, +/mob/living/simple_mob/animal/fox_vr/Renault, /turf/simulated/floor/wood, /area/crew_quarters/captain) "aEu" = ( @@ -11134,7 +11814,7 @@ }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 9 }, /obj/effect/floor_decal/borderfloor{ @@ -11601,7 +12281,7 @@ "aHs" = ( /obj/machinery/door/firedoor/glass/hidden/steel, /obj/machinery/atmospherics/pipe/simple/hidden, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 4 }, /turf/simulated/floor/tiled, @@ -12026,7 +12706,7 @@ /turf/simulated/floor/tiled, /area/tether/station/dock_two) "aIS" = ( -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 9 }, /turf/simulated/floor/tiled, @@ -12134,7 +12814,6 @@ }, /obj/effect/floor_decal/steeldecal/steel_decals7, /obj/machinery/alarm{ - frequency = 1441; pixel_y = 22 }, /obj/machinery/atmospherics/pipe/simple/hidden/universal{ @@ -13162,17 +13841,6 @@ }, /turf/simulated/floor/tiled, /area/engineering/engineering_airlock) -"aNg" = ( -/obj/structure/grille, -/obj/structure/cable/green, -/obj/machinery/door/firedoor/glass, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "ce_office" - }, -/turf/simulated/floor, -/area/crew_quarters/heads/chief) "aNo" = ( /obj/structure/cable/green{ d1 = 1; @@ -13400,23 +14068,6 @@ /obj/item/weapon/rig/ce/equipped, /turf/simulated/floor/tiled, /area/crew_quarters/heads/chief) -"aQc" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/full, -/obj/structure/window/reinforced{ - dir = 8 - }, -/obj/machinery/door/firedoor/glass, -/obj/machinery/door/blast/regular{ - density = 0; - dir = 1; - icon_state = "pdoor0"; - id = "englockdown"; - name = "Engineering Lockdown"; - opacity = 0 - }, -/turf/simulated/floor, -/area/crew_quarters/heads/chief) "aQh" = ( /obj/structure/cable/green{ d1 = 4; @@ -14476,17 +15127,6 @@ }, /turf/simulated/floor, /area/engineering/foyer) -"aYs" = ( -/obj/structure/disposalpipe/segment, -/obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2"; - pixel_y = 0 - }, -/obj/machinery/door/airlock/maintenance/common, -/turf/simulated/floor, -/area/hallway/station/atrium) "aYt" = ( /obj/effect/floor_decal/borderfloor{ dir = 1 @@ -14722,74 +15362,6 @@ /obj/machinery/telecomms/relay/preset/tether/station_mid, /turf/simulated/floor/tiled/techfloor, /area/crew_quarters/heads/chief) -"bbd" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/floor_decal/rust, -/turf/simulated/floor, -/area/vacant/vacant_restaurant_lower) -"bbl" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/structure/cable/green{ - d2 = 4; - icon_state = "0-4" - }, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/cap/hidden/supply{ - dir = 4 - }, -/turf/simulated/floor, -/area/vacant/vacant_restaurant_lower) -"bbn" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/machinery/door/airlock/glass, -/turf/simulated/floor/tiled/steel_grid, -/area/hallway/station/atrium) -"bbq" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/effect/floor_decal/rust, -/turf/simulated/floor, -/area/vacant/vacant_restaurant_lower) -"bbr" = ( -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/turf/simulated/floor/tiled, -/area/hallway/station/atrium) "bbs" = ( /obj/structure/bed/chair/office/dark{ dir = 4 @@ -14799,26 +15371,6 @@ }, /turf/simulated/floor/tiled, /area/engineering/foyer) -"bbw" = ( -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 6 - }, -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 10 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 10 - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/turf/simulated/floor/tiled, -/area/hallway/station/atrium) "bbx" = ( /obj/machinery/atmospherics/unary/vent_scrubber/on{ dir = 4 @@ -14831,16 +15383,6 @@ }, /turf/simulated/floor/tiled, /area/engineering/foyer) -"bbz" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/structure/cable/green{ - d1 = 1; - d2 = 8; - icon_state = "1-8" - }, -/turf/simulated/floor/tiled, -/area/hallway/station/atrium) "bbE" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -15076,7 +15618,7 @@ icon_state = "4-8"; pixel_x = 0 }, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 1 }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ @@ -15893,7 +16435,7 @@ /area/hallway/station/atrium) "bfT" = ( /obj/structure/disposalpipe/segment, -/mob/living/simple_animal/snake/Noodle, +/mob/living/simple_mob/animal/space/snake/noodle, /turf/simulated/floor/carpet/oracarpet, /area/crew_quarters/heads/chief) "bfW" = ( @@ -16086,7 +16628,7 @@ pixel_x = 25; pixel_y = 0 }, -/obj/machinery/camera/network/northern_star, +/obj/machinery/camera/network/tether, /obj/effect/floor_decal/borderfloor{ dir = 1; icon_state = "borderfloor"; @@ -16368,54 +16910,6 @@ }, /turf/simulated/floor/tiled/monotile, /area/bridge_hallway) -"bju" = ( -/obj/structure/grille, -/obj/structure/cable/green{ - d2 = 4; - icon_state = "0-4" - }, -/obj/structure/cable/green{ - d2 = 8; - icon_state = "0-8" - }, -/obj/structure/cable/green{ - d2 = 2; - icon_state = "0-2" - }, -/obj/machinery/door/firedoor/glass, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "hop_office" - }, -/obj/structure/window/reinforced/polarized{ - dir = 1; - id = "hop_office" - }, -/turf/simulated/floor/plating, -/area/crew_quarters/heads/hop) -"bjz" = ( -/obj/structure/grille, -/obj/structure/cable/green{ - d2 = 4; - icon_state = "0-4" - }, -/obj/structure/cable/green{ - d2 = 8; - icon_state = "0-8" - }, -/obj/machinery/door/firedoor/glass, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "hop_office" - }, -/obj/structure/window/reinforced/polarized{ - dir = 1; - id = "hop_office" - }, -/turf/simulated/floor/plating, -/area/crew_quarters/heads/hop) "bjC" = ( /obj/structure/table/reinforced, /obj/structure/cable/green{ @@ -16450,24 +16944,6 @@ }, /turf/simulated/floor/tiled, /area/crew_quarters/heads/hop) -"bjP" = ( -/obj/structure/grille, -/obj/structure/cable/green{ - d2 = 8; - icon_state = "0-8" - }, -/obj/machinery/door/firedoor/glass, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "hop_office" - }, -/obj/structure/window/reinforced/polarized{ - dir = 1; - id = "hop_office" - }, -/turf/simulated/floor/plating, -/area/crew_quarters/heads/hop) "bjS" = ( /obj/structure/disposalpipe/segment, /obj/effect/floor_decal/borderfloor{ @@ -16556,19 +17032,6 @@ /obj/effect/floor_decal/steeldecal/steel_decals4, /turf/simulated/floor/tiled, /area/storage/tools) -"bkt" = ( -/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/structure/cable{ - icon_state = "1-8" - }, -/turf/simulated/floor/tiled, -/area/hallway/station/docks) "bkx" = ( /obj/structure/table/reinforced, /obj/item/stack/material/plasteel{ @@ -16602,26 +17065,6 @@ }, /turf/simulated/floor/tiled, /area/hallway/station/docks) -"bkA" = ( -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, -/obj/machinery/status_display{ - layer = 4; - pixel_x = 32; - pixel_y = 0 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/obj/effect/floor_decal/corner/lightgrey/border{ - dir = 4 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 10 - }, -/turf/simulated/floor/tiled, -/area/hallway/station/docks) "bkC" = ( /obj/effect/floor_decal/corner/blue/full{ dir = 8 @@ -16636,80 +17079,6 @@ /obj/structure/flora/pottedplant, /turf/simulated/floor/tiled/dark, /area/bridge) -"bkP" = ( -/obj/structure/grille, -/obj/structure/cable/green{ - d2 = 4; - icon_state = "0-4" - }, -/obj/machinery/door/firedoor/glass, -/obj/machinery/door/blast/regular{ - density = 0; - dir = 4; - icon_state = "pdoor0"; - id = "bridge blast"; - name = "Bridge Blast Doors"; - opacity = 0 - }, -/obj/structure/window/reinforced/full, -/obj/structure/window/reinforced{ - dir = 1 - }, -/obj/structure/window/reinforced, -/turf/simulated/floor/plating, -/area/bridge) -"bkS" = ( -/obj/structure/grille, -/obj/structure/cable/green{ - d2 = 8; - icon_state = "0-8" - }, -/obj/structure/cable/green{ - d2 = 4; - icon_state = "0-4" - }, -/obj/machinery/door/firedoor/glass, -/obj/machinery/door/blast/regular{ - density = 0; - dir = 4; - icon_state = "pdoor0"; - id = "bridge blast"; - name = "Bridge Blast Doors"; - opacity = 0 - }, -/obj/structure/window/reinforced/full, -/obj/structure/window/reinforced{ - dir = 1 - }, -/obj/structure/window/reinforced, -/turf/simulated/floor/plating, -/area/bridge) -"bld" = ( -/obj/structure/grille, -/obj/structure/cable/green{ - d2 = 8; - icon_state = "0-8" - }, -/obj/structure/cable/green{ - d2 = 2; - icon_state = "0-2" - }, -/obj/machinery/door/firedoor/glass, -/obj/machinery/door/blast/regular{ - density = 0; - dir = 4; - icon_state = "pdoor0"; - id = "bridge blast"; - name = "Bridge Blast Doors"; - opacity = 0 - }, -/obj/structure/window/reinforced/full, -/obj/structure/window/reinforced{ - dir = 1 - }, -/obj/structure/window/reinforced, -/turf/simulated/floor/plating, -/area/bridge) "bll" = ( /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 9 @@ -16873,21 +17242,6 @@ }, /turf/simulated/floor/tiled, /area/storage/tools) -"bng" = ( -/obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply, -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/hallway/station/docks) "bnl" = ( /obj/machinery/atmospherics/pipe/simple/hidden{ dir = 9; @@ -17106,19 +17460,6 @@ }, /turf/simulated/floor/tiled, /area/tether/station/stairs_one) -"boB" = ( -/obj/machinery/atmospherics/pipe/manifold/hidden{ - dir = 8; - icon_state = "map" - }, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/meter{ - frequency = 1443; - id = "dist_aux_meter"; - name = "Distribution Loop" - }, -/turf/simulated/floor, -/area/hallway/station/docks) "boH" = ( /obj/machinery/computer/transhuman/resleeving{ dir = 8 @@ -17177,23 +17518,6 @@ }, /turf/simulated/floor/tiled, /area/crew_quarters/heads/hop) -"boO" = ( -/obj/structure/grille, -/obj/machinery/door/firedoor/glass, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/cable/green{ - d2 = 4; - icon_state = "0-4" - }, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "hop_office" - }, -/turf/simulated/floor/plating, -/area/crew_quarters/heads/hop) "boU" = ( /obj/machinery/recharger/wallcharger{ pixel_x = 32; @@ -17276,7 +17600,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 1 }, /obj/effect/floor_decal/borderfloor, @@ -17425,20 +17749,6 @@ }, /turf/simulated/floor/tiled, /area/crew_quarters/heads/hop) -"bpO" = ( -/obj/structure/grille, -/obj/machinery/door/firedoor/glass, -/obj/structure/cable/green{ - d2 = 4; - icon_state = "0-4" - }, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "hop_office" - }, -/turf/simulated/floor/plating, -/area/crew_quarters/heads/hop) "bpQ" = ( /obj/structure/table/reinforced, /obj/item/weapon/paper_bin{ @@ -17847,7 +18157,7 @@ pixel_x = 0; pixel_y = 26 }, -/obj/machinery/camera/network/northern_star, +/obj/machinery/camera/network/tether, /turf/simulated/floor/tiled, /area/hallway/station/docks) "bsv" = ( @@ -19174,16 +19484,6 @@ /obj/machinery/atmospherics/unary/vent_scrubber/on, /turf/simulated/floor/carpet, /area/library) -"bCl" = ( -/obj/structure/grille, -/obj/machinery/door/firedoor/border_only, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "library_window_tint" - }, -/turf/simulated/floor/plating, -/area/library) "bDr" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, @@ -19552,15 +19852,6 @@ }, /turf/simulated/floor/tiled/monotile, /area/bridge_hallway) -"bGj" = ( -/obj/machinery/button/windowtint{ - id = "library_window_tint"; - pixel_x = 26; - pixel_y = -26 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/turf/simulated/floor/carpet, -/area/library) "bGl" = ( /obj/machinery/firealarm{ dir = 1; @@ -19891,7 +20182,7 @@ /turf/simulated/floor/tiled, /area/tether/station/dock_two) "bHY" = ( -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 9 }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ @@ -20608,7 +20899,7 @@ req_access = list(13) }, /obj/machinery/atmospherics/pipe/simple/hidden, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 4 }, /turf/simulated/floor/tiled, @@ -20772,7 +21063,7 @@ /obj/effect/floor_decal/industrial/warning{ dir = 10 }, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 4 }, /obj/machinery/atmospherics/unary/vent_pump/high_volume{ @@ -21086,18 +21377,6 @@ }, /turf/simulated/floor/carpet, /area/engineering/foyer) -"bYz" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/full, -/turf/simulated/floor, -/area/hallway/station/docks) -"bYC" = ( -/turf/simulated/floor, -/area/hallway/station/docks) -"bYD" = ( -/obj/machinery/door/airlock/multi_tile/glass, -/turf/simulated/floor, -/area/hallway/station/docks) "bYE" = ( /obj/machinery/recharge_station, /turf/simulated/floor/carpet, @@ -21123,13 +21402,6 @@ "bYP" = ( /turf/simulated/wall, /area/vacant/vacant_restaurant_lower) -"bYR" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/cap/hidden/scrubbers{ - dir = 4 - }, -/turf/simulated/floor, -/area/vacant/vacant_restaurant_lower) "bZc" = ( /obj/structure/table/reinforced, /obj/item/stack/rods{ @@ -21254,7 +21526,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden{ dir = 6 }, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 4 }, /obj/machinery/newscaster{ @@ -21393,21 +21665,6 @@ }, /turf/simulated/floor/tiled, /area/tether/station/pathfinder_office) -"dvn" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/full, -/obj/structure/window/reinforced{ - dir = 4 - }, -/obj/machinery/door/firedoor/glass, -/obj/structure/window/reinforced{ - dir = 8 - }, -/obj/structure/window/reinforced{ - dir = 1 - }, -/turf/simulated/floor/plating, -/area/tether/station/explorer_meeting) "dxX" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, @@ -21438,35 +21695,6 @@ /obj/machinery/vending/snack, /turf/simulated/floor/tiled, /area/tether/station/explorer_meeting) -"dPZ" = ( -/obj/machinery/camera/network/northern_star{ - dir = 8 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/obj/effect/floor_decal/corner/purple/border{ - icon_state = "bordercolor"; - dir = 4 - }, -/obj/machinery/photocopier, -/turf/simulated/floor/tiled, -/area/tether/station/explorer_meeting) -"dYE" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "pathfinder_office" - }, -/obj/structure/window/reinforced/polarized, -/obj/machinery/door/firedoor/glass, -/obj/structure/cable/green{ - d2 = 8; - icon_state = "0-8" - }, -/turf/simulated/floor/plating, -/area/tether/station/pathfinder_office) "edg" = ( /obj/structure/bed/chair/office/dark{ dir = 4 @@ -21512,7 +21740,6 @@ /area/tether/station/explorer_meeting) "eAe" = ( /obj/machinery/alarm{ - frequency = 1441; pixel_y = 22 }, /obj/structure/closet/secure_closet/pilot, @@ -21598,28 +21825,6 @@ }, /turf/simulated/floor/tiled, /area/tether/station/explorer_meeting) -"gcH" = ( -/obj/effect/floor_decal/borderfloorblack{ - dir = 1 - }, -/obj/effect/floor_decal/industrial/danger{ - dir = 1 - }, -/obj/machinery/meter, -/turf/simulated/floor/tiled, -/area/tether/station/excursion_dock) -"ggi" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/full, -/obj/structure/window/reinforced{ - dir = 4 - }, -/obj/machinery/door/firedoor/glass, -/obj/structure/window/reinforced{ - dir = 8 - }, -/turf/simulated/floor/plating, -/area/tether/station/explorer_meeting) "gUt" = ( /obj/structure/table/steel, /obj/item/clothing/head/pilot, @@ -21735,28 +21940,6 @@ }, /turf/simulated/floor/carpet, /area/hallway/station/atrium) -"jZN" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "pathfinder_office" - }, -/obj/structure/window/reinforced/polarized{ - dir = 1; - id = "hop_office" - }, -/obj/machinery/door/firedoor/glass, -/obj/structure/cable/green{ - d2 = 4; - icon_state = "0-4" - }, -/obj/structure/cable/green{ - d2 = 2; - icon_state = "0-2" - }, -/turf/simulated/floor/plating, -/area/tether/station/pathfinder_office) "kZI" = ( /obj/structure/window/reinforced{ dir = 8 @@ -21871,12 +22054,6 @@ /obj/machinery/vending/cola, /turf/simulated/floor/tiled, /area/tether/station/explorer_meeting) -"mcB" = ( -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/tether/station/pathfinder_office) "mtd" = ( /obj/structure/table/woodentable, /obj/item/weapon/folder/yellow, @@ -21916,25 +22093,6 @@ }, /turf/simulated/floor/tiled, /area/tether/station/explorer_meeting) -"mJI" = ( -/obj/machinery/camera/network/northern_star{ - dir = 5 - }, -/obj/structure/disposalpipe/segment, -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/purple/border{ - icon_state = "bordercolor"; - dir = 8 - }, -/obj/structure/extinguisher_cabinet{ - dir = 4; - icon_state = "extinguisher_closed"; - pixel_x = -30 - }, -/turf/simulated/floor/tiled, -/area/tether/station/explorer_meeting) "mSH" = ( /obj/structure/grille, /obj/structure/window/reinforced/full, @@ -22000,10 +22158,6 @@ }, /turf/simulated/floor/carpet, /area/hallway/station/atrium) -"nOF" = ( -/obj/structure/closet/secure_closet/pilot, -/turf/simulated/floor/tiled, -/area/tether/station/explorer_prep) "nSw" = ( /obj/structure/grille, /obj/structure/window/reinforced/full, @@ -22012,28 +22166,6 @@ }, /turf/simulated/shuttle/plating, /area/shuttle/excursion/tether) -"nYc" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "pathfinder_office" - }, -/obj/structure/window/reinforced/polarized{ - dir = 1; - id = "hop_office" - }, -/obj/machinery/door/firedoor/glass, -/obj/structure/cable/green{ - d2 = 4; - icon_state = "0-4" - }, -/obj/structure/cable/green{ - d2 = 8; - icon_state = "0-8" - }, -/turf/simulated/floor/plating, -/area/tether/station/pathfinder_office) "nYp" = ( /obj/effect/floor_decal/industrial/outline/red, /obj/structure/closet/secure_closet/guncabinet/excursion, @@ -22211,12 +22343,6 @@ /obj/item/device/binoculars, /turf/simulated/floor/tiled, /area/tether/station/pathfinder_office) -"rhA" = ( -/obj/effect/floor_decal/borderfloorblack, -/obj/effect/floor_decal/industrial/danger, -/obj/machinery/camera/network/northern_star, -/turf/simulated/floor/tiled, -/area/tether/station/excursion_dock) "rRn" = ( /obj/structure/bed/chair/office/dark{ dir = 1 @@ -22237,31 +22363,6 @@ }, /turf/simulated/floor/tiled, /area/tether/station/explorer_meeting) -"soc" = ( -/obj/machinery/camera/network/northern_star, -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 8 - }, -/turf/simulated/floor/tiled/monotile, -/area/tether/station/excursion_dock) -"sqC" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "pathfinder_office" - }, -/obj/structure/window/reinforced/polarized{ - dir = 1; - id = "hop_office" - }, -/obj/machinery/door/firedoor/glass, -/obj/structure/cable/green{ - d2 = 8; - icon_state = "0-8" - }, -/turf/simulated/floor/plating, -/area/tether/station/pathfinder_office) "sSn" = ( /obj/effect/floor_decal/steeldecal/steel_decals5{ dir = 4 @@ -22373,22 +22474,6 @@ /obj/machinery/portable_atmospherics/canister/oxygen, /turf/simulated/floor/tiled, /area/tether/station/explorer_prep) -"ugj" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "pathfinder_office" - }, -/obj/machinery/door/firedoor/glass, -/obj/structure/cable/green{ - d2 = 4; - icon_state = "0-4" - }, -/obj/structure/cable/green, -/obj/structure/window/reinforced/polarized, -/turf/simulated/floor/plating, -/area/tether/station/pathfinder_office) "uoG" = ( /obj/structure/window/reinforced{ dir = 8 @@ -22445,25 +22530,6 @@ }, /turf/simulated/floor/tiled/monotile, /area/tether/station/excursion_dock) -"vEZ" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "pathfinder_office" - }, -/obj/structure/window/reinforced/polarized, -/obj/machinery/door/firedoor/glass, -/obj/structure/cable/green{ - d2 = 4; - icon_state = "0-4" - }, -/obj/structure/cable/green{ - d2 = 8; - icon_state = "0-8" - }, -/turf/simulated/floor/plating, -/area/tether/station/pathfinder_office) "vIv" = ( /obj/structure/table/bench/padded, /obj/item/device/radio/intercom{ @@ -22527,13 +22593,6 @@ }, /turf/simulated/floor/tiled, /area/tether/station/explorer_meeting) -"wbr" = ( -/obj/machinery/camera/network/northern_star, -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 4 - }, -/turf/simulated/floor/tiled/monotile, -/area/tether/station/excursion_dock) "wcD" = ( /obj/structure/grille, /obj/structure/window/reinforced/full, @@ -22600,19 +22659,6 @@ }, /turf/simulated/floor/tiled, /area/tether/station/explorer_meeting) -"wSk" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/full, -/obj/structure/window/reinforced{ - dir = 4 - }, -/obj/machinery/door/firedoor/glass, -/obj/structure/window/reinforced{ - dir = 8 - }, -/obj/structure/window/reinforced, -/turf/simulated/floor/plating, -/area/tether/station/explorer_meeting) "wZn" = ( /obj/machinery/power/apc{ cell_type = /obj/item/weapon/cell/super; @@ -22636,18 +22682,6 @@ /obj/structure/table/bench/padded, /turf/simulated/floor/carpet, /area/hallway/station/atrium) -"xhk" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/camera/network/northern_star{ - dir = 1 - }, -/turf/simulated/floor/tiled/monotile, -/area/tether/station/excursion_dock) "xhv" = ( /obj/machinery/door/airlock/glass{ name = "Shuttle Bay" @@ -27131,7 +27165,7 @@ aks aks aks alx -aoW +abv aoX aqK aqf @@ -27150,9 +27184,9 @@ aJn aLt aRb aRb -aQc -aQc -aQc +agi +agi +agi aRb aRb aRb @@ -27273,7 +27307,7 @@ aks aks aks alw -aoe +abB aoj aqI adS @@ -27415,7 +27449,7 @@ aks aks aks alz -amX +abE aol app aqa @@ -27432,7 +27466,7 @@ aFO aSC bds aLA -aNg +agc aYH aRV bcp @@ -27574,7 +27608,7 @@ aFL aSC aoq aLy -aNg +agc aYF aRX aSe @@ -27716,7 +27750,7 @@ aFO aSC aTK aLG -aNg +agc aYJ baA bcn @@ -27858,7 +27892,7 @@ aQv aSC aTJ aLC -aNg +agc aBg aTm bcr @@ -28142,7 +28176,7 @@ bZt aSC aTL aLH -aNg +agc aRV aQh aRV @@ -28301,7 +28335,7 @@ bZP bYl bYl bYj -bYz +aeF bZZ bty aBZ @@ -28443,7 +28477,7 @@ bYj bZS bZD bZm -bYz +aeF aAV btu bvu @@ -28585,7 +28619,7 @@ bZz bYl bZD bYj -bYz +aeF aAV btu aBZ @@ -28718,7 +28752,7 @@ aIO aVK alv bYk -bYR +bYl bYj bYj bYj @@ -28819,8 +28853,8 @@ aaa acL acL acL -abs -abE +aar +aaE abW adf adf @@ -28829,7 +28863,7 @@ adf adf alF aiM -ahu +abq aiM aiM aac @@ -28860,7 +28894,7 @@ aIO aVW alv bYm -bbl +acv bYj bZz bYj @@ -28869,7 +28903,7 @@ bYj bYl bYl bZk -bYD +aeI aBi btu aBZ @@ -29002,7 +29036,7 @@ aSB aVP alv bYl -bbd +acM bZk bYl bYl @@ -29011,7 +29045,7 @@ bZQ bYj bYj bYj -bYC +aeR aBi btu aBZ @@ -29144,7 +29178,7 @@ aXX aZn alv bYl -bbq +adp bZm bfF bYj @@ -29247,7 +29281,7 @@ aaz aaX abt abF -abY +aaU afM afL aib @@ -29255,7 +29289,7 @@ afL afi alF ajt -ahw +abs ajt aiM aac @@ -29285,9 +29319,9 @@ aSz alt alt alv -agE -bbn -agE +acs +adR +acs aws aws aws @@ -29428,7 +29462,7 @@ aoI aTE aoJ agR -bbw +adT ajK awp awP @@ -29570,7 +29604,7 @@ aUk bXG atH agQ -bbr +adX bdi bfG bgG @@ -29712,7 +29746,7 @@ bgC bXI aYa agT -bbr +adX bdq bfJ bgJ @@ -29813,8 +29847,8 @@ aac acL acL abf -abv -abL +aaB +aaF acd afP afP @@ -29854,7 +29888,7 @@ aUm aWd aXY aZq -bbz +aec bdn aws bgH @@ -29996,7 +30030,7 @@ bgE bXK aYc agV -aCe +aee bdu aws bgN @@ -30264,7 +30298,7 @@ apg avD apg apg -aij +auz aAW aAW aAW @@ -30993,10 +31027,10 @@ agZ aim bdL bfQ -bha -bha -bkt -bng +afo +afq +aft +afB bha bha bqf @@ -31117,7 +31151,7 @@ apQ apQ als auz -aDI +aci aLl aET aaV @@ -31136,9 +31170,9 @@ acp bdW arf awZ -awZ -bkA -ayF +afr +afu +afG awZ azR aAo @@ -31235,7 +31269,7 @@ adh acj acj ack -afn +aaY adG ack aJs @@ -31280,7 +31314,7 @@ aaT awu awu awu -ayG +aek awu awu awu @@ -31414,7 +31448,7 @@ aRr aSO aUI aWj -aYs +aco aZP bbE bdZ @@ -31423,7 +31457,7 @@ bhg axD axZ bno -boB +ael bpz bqj awu @@ -31690,12 +31724,12 @@ alQ aBH aGP alQ -aeq -aeq -aeq -aeq -aeq -aeq +aeO +aeO +aeO +aeO +aeO +aeO afC afC afC @@ -31832,22 +31866,22 @@ aDs aEW aGI alQ -aeq aeO +afy +afy +afy +afy aeO -aeO -aeO -aeq afC afE -agd +afn ahF aio bed awz axc axc -bkP +afv aZV azm bpD @@ -31974,12 +32008,12 @@ aDM aEX aof alQ -aeq aeO +afy +afy +afy +afy aeO -aeO -aeO -aeq afC afJ age @@ -31989,7 +32023,7 @@ beh awz axc axd -bkS +afw ayK azn azU @@ -32116,12 +32150,12 @@ alQ alQ alQ alQ -aeq aeO +afy +afy +afy +afy aeO -aeO -aeO -aeq afC afF age @@ -32131,7 +32165,7 @@ beg awz axc axc -bkS +afw bcE azo azV @@ -32258,12 +32292,12 @@ asu aFc aog aoO -aeq aeO +afy +afy +afy +afy aeO -aeO -aeO -aeq afC afN agg @@ -32273,7 +32307,7 @@ beg awz axc axc -bkS +afw bkC azp azU @@ -32400,12 +32434,12 @@ aDP aEZ avS aoO -aeq -aeq aeO aeO afy -aeq +afy +agu +aeO afC afC aYt @@ -32415,7 +32449,7 @@ bei awz axc axc -bkS +afw ayN azn azU @@ -32557,7 +32591,7 @@ beg awz axc axc -bkS +afw blS azq azU @@ -32699,7 +32733,7 @@ beg awz axc axc -bkS +afw bkE azr azW @@ -32841,7 +32875,7 @@ beg awz axc axc -bkS +afw ayQ azn azU @@ -32983,7 +33017,7 @@ bed awz axd axc -bld +afx bnB boH bpJ @@ -33102,7 +33136,7 @@ aad aad aad aad -ack +abY aaT aAc acn @@ -33232,7 +33266,7 @@ aah aah aaP aad -wbr +agq aah akC aah @@ -33526,7 +33560,7 @@ aao aao aao asY -xhk +agv aad ack aaT @@ -33553,7 +33587,7 @@ axg bjo bll ayU -azv +afK azZ bqU bsM @@ -33652,7 +33686,7 @@ aat aat aat aad -rhA +abU aap aap aap @@ -33666,7 +33700,7 @@ aeo aaq aaq aau -afV +aeq avK avN aad @@ -33695,8 +33729,8 @@ awE awE awI awI -boO -bpO +agm +agn brj awI awI @@ -33808,7 +33842,7 @@ amF avG adB aaq -afV +aeq avK avN aad @@ -33834,7 +33868,7 @@ bbT ber awF bhr -bju +agj blr bnL boN @@ -33950,7 +33984,7 @@ amF avG adB aaq -afV +aeq avK auH aad @@ -34096,7 +34130,7 @@ aap avK auF aad -acm +afl aaT aAp acp @@ -34118,7 +34152,7 @@ acp bez awG axj -bjz +agk ayj ayX azy @@ -34126,7 +34160,7 @@ bpQ ayX aBt awI -aCr +afV aCY aDz bAz @@ -34260,7 +34294,7 @@ acp bez awG axj -bjz +agk blF ayX azz @@ -34380,7 +34414,7 @@ aap avK auK axm -acm +agd abh aAt acp @@ -34402,7 +34436,7 @@ acp beE awG axj -bjz +agk ayl ayX azA @@ -34544,7 +34578,7 @@ acp beH awH bmM -bjP +agl aym bnZ boU @@ -34661,7 +34695,7 @@ anX afI oVP aap -gcH +avK qgR aad axI @@ -34802,7 +34836,7 @@ aaD avG tIi aaq -afV +aeq avK auQ aad @@ -34944,7 +34978,7 @@ amL aob dbI aaq -afV +aeq avK qgR aad @@ -35072,7 +35106,7 @@ aat aat aat aad -rhA +abU aap aap aap @@ -35086,7 +35120,7 @@ aep aeu aev aau -afV +aeq avK qgR aad @@ -35504,14 +35538,14 @@ aah pTz abc aad -abU +agr acN jdD adP amP fmN aad -soc +agt nxL coV abc @@ -35649,11 +35683,11 @@ aad abV acP aad -aad -aad +hCe +hCe vQL -aad -aad +hCe +hCe aTU lMo nYM @@ -35791,15 +35825,15 @@ dkC acc acQ amU -aiv +hCe xcY afc wZn -nYM +hCe oaO wFb vUO -mJI +agw mCP epz ash @@ -35933,11 +35967,11 @@ akL oeg acV amU -aiv +hCe adO afe -mcB -nYM +ags +hCe fsu sbI sZd @@ -36070,16 +36104,16 @@ aaa aaa aac aad -nOF +afW akL bQQ adj amU -jZN +abL dDZ tpZ dDZ -ugj +afb uDP nks uzS @@ -36217,11 +36251,11 @@ akL bQQ adj amU -nYc +aeT ygn fpA pAD -vEZ +aeT uDP mId wrg @@ -36260,9 +36294,9 @@ aAk aAk aAg aAg -bCl +ago bFC -bCl +ago bWN aAg aGL @@ -36359,11 +36393,11 @@ akL awf adr amW -sqC +aeZ ygn jki qSW -dYE +aeZ uDP nks mtd @@ -36404,7 +36438,7 @@ aAg bBg aEL aFk -bGj +agp bHr aAg aac @@ -36505,7 +36539,7 @@ hCe pYE dlk ekp -nYM +hCe nma lue hJg @@ -36647,7 +36681,7 @@ hCe hCe hCe hCe -nYM +hCe jDS wLj cNq @@ -36785,11 +36819,11 @@ prz vUd tWI aeB -aiv -aac -aac -aac -nYM +hCe +afg +afY +aga +hCe uDP mFo mFo @@ -36927,15 +36961,15 @@ aiv aiv aiv aiv -aiv -aac -aac -aac -nYM +hCe +hCe +hCe +hCe +hCe qzk dMN mcn -dPZ +agy afT ixk ash @@ -37074,12 +37108,12 @@ aac aac aac nYM -dvn -ggi -ggi -ggi -ggi -wSk +afh +afh +afh +afh +afh +afh ash amg amg diff --git a/maps/tether/tether-06-station2.dmm b/maps/tether/tether-06-station2.dmm index c2928919a6..ec89f42a50 100644 --- a/maps/tether/tether-06-station2.dmm +++ b/maps/tether/tether-06-station2.dmm @@ -1835,15 +1835,12 @@ /turf/simulated/floor/tiled/dark, /area/security/brig) "cL" = ( -/obj/structure/shuttle/engine/propulsion{ - dir = 8; - icon_state = "propulsion_l" +/obj/random/trash, +/obj/machinery/alarm{ + pixel_y = 22 }, -/turf/space, -/turf/simulated/shuttle/plating/airless/carry, -/area/shuttle/large_escape_pod1/station{ - base_turf = /turf/simulated/mineral/floor/vacuum - }) +/turf/simulated/floor, +/area/maintenance/station/sec_lower) "cM" = ( /obj/effect/floor_decal/borderfloor/shifted{ icon_state = "borderfloor_shifted"; @@ -1988,14 +1985,15 @@ /turf/simulated/floor/tiled/dark, /area/security/recstorage) "cW" = ( -/obj/structure/shuttle/engine/propulsion{ - dir = 8 +/obj/effect/decal/cleanable/dirt, +/obj/machinery/alarm{ + dir = 4; + icon_state = "alarm0"; + pixel_x = -22; + pixel_y = 0 }, -/turf/space, -/turf/simulated/shuttle/plating/airless/carry, -/area/shuttle/large_escape_pod1/station{ - base_turf = /turf/simulated/mineral/floor/vacuum - }) +/turf/simulated/floor, +/area/maintenance/station/sec_lower) "cX" = ( /obj/machinery/door/firedoor/glass, /obj/structure/cable/green{ @@ -2130,16 +2128,11 @@ /turf/simulated/floor/tiled/dark, /area/chapel/chapel_morgue) "dg" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/structure/extinguisher_cabinet{ pixel_x = 25; pixel_y = 0 }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 9 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 10 - }, /turf/simulated/floor/tiled/dark, /area/chapel/chapel_morgue) "dh" = ( @@ -2228,15 +2221,14 @@ /turf/simulated/floor/tiled, /area/security/brig/visitation) "dm" = ( -/obj/structure/shuttle/engine/propulsion{ - dir = 8; - icon_state = "propulsion_r" +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 9 }, -/turf/space, -/turf/simulated/shuttle/plating/airless/carry, -/area/shuttle/large_escape_pod1/station{ - base_turf = /turf/simulated/mineral/floor/vacuum - }) +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 10 + }, +/turf/simulated/floor/tiled/dark, +/area/chapel/chapel_morgue) "dn" = ( /obj/effect/floor_decal/industrial/warning, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, @@ -2303,6 +2295,13 @@ }, /turf/simulated/floor/tiled/dark, /area/security/brig) +"dr" = ( +/obj/structure/table/steel, +/obj/machinery/alarm{ + pixel_y = 22 + }, +/turf/simulated/floor, +/area/maintenance/station/sec_lower) "ds" = ( /obj/effect/floor_decal/borderfloor{ dir = 4 @@ -2611,6 +2610,25 @@ /obj/machinery/atmospherics/pipe/simple/hidden/green, /turf/simulated/floor, /area/security/riot_control) +"dS" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 10 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/structure/disposalpipe/junction/yjunction, +/obj/structure/catwalk, +/obj/machinery/alarm{ + pixel_y = 22 + }, +/turf/simulated/floor/plating, +/area/maintenance/station/eng_upper) "dT" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 6 @@ -2659,6 +2677,29 @@ }, /turf/simulated/floor/tiled/dark, /area/security/recstorage) +"dW" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/door/airlock/maintenance/common, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/catwalk, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/plating, +/area/maintenance/station/eng_upper) +"dX" = ( +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/plating, +/area/vacant/vacant_restaurant_upper) "dY" = ( /obj/machinery/light{ dir = 8 @@ -2705,6 +2746,83 @@ }, /turf/simulated/floor/lino, /area/chapel/office) +"ed" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/plating, +/area/vacant/vacant_restaurant_upper) +"ee" = ( +/obj/machinery/atmospherics/pipe/simple/hidden{ + dir = 4 + }, +/obj/machinery/door/airlock/maintenance/common, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/tiled/dark, +/area/ai_monitored/storage/eva) +"ef" = ( +/obj/machinery/meter, +/obj/machinery/atmospherics/pipe/simple/hidden{ + dir = 5; + icon_state = "intact" + }, +/obj/machinery/alarm{ + dir = 1; + icon_state = "alarm0"; + pixel_y = -22 + }, +/turf/simulated/floor/tiled/dark, +/area/ai_monitored/storage/eva) +"eg" = ( +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/structure/window/reinforced, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/plating, +/area/vacant/vacant_restaurant_upper) +"eh" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/alarm{ + dir = 1; + icon_state = "alarm0"; + pixel_y = -22 + }, +/turf/simulated/floor, +/area/bridge/meeting_room) +"ei" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/alarm{ + dir = 1; + icon_state = "alarm0"; + pixel_y = -22 + }, +/turf/simulated/floor, +/area/bridge/meeting_room) +"ej" = ( +/obj/machinery/atmospherics/unary/vent_scrubber/on, +/obj/machinery/alarm{ + dir = 8; + pixel_x = 25; + pixel_y = 0 + }, +/turf/simulated/floor/tiled/dark, +/area/storage/tech) "ek" = ( /obj/structure/cable/pink, /obj/machinery/power/apc{ @@ -2779,11 +2897,49 @@ }, /turf/simulated/floor/tiled, /area/security/brig) +"er" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/obj/machinery/alarm{ + dir = 1; + pixel_y = -25 + }, +/turf/simulated/floor/tiled/dark, +/area/ai_monitored/storage/eva) "es" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/hologram/holopad, /turf/simulated/floor/tiled/steel_dirty, /area/security/brig) +"et" = ( +/obj/machinery/light/small{ + dir = 4; + pixel_y = 0 + }, +/obj/machinery/alarm{ + dir = 1; + pixel_y = -25 + }, +/turf/simulated/floor/tiled/dark, +/area/ai_monitored/storage/eva) +"eu" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/tiled, +/area/hallway/station/port) "ev" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -2821,6 +2977,22 @@ }, /turf/simulated/floor/tiled/dark, /area/security/brig) +"ex" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 8 + }, +/obj/effect/floor_decal/corner/lightgrey/border{ + dir = 8 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 6 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 5 + }, +/obj/machinery/door/firedoor/glass/hidden/steel, +/turf/simulated/floor/tiled, +/area/tether/station/stairs_two) "ey" = ( /obj/structure/table/woodentable, /obj/item/device/flashlight/lamp{ @@ -2907,8 +3079,10 @@ }, /obj/machinery/atmospherics/pipe/zpipe/up/scrubbers, /obj/machinery/atmospherics/pipe/zpipe/up/supply, -/obj/machinery/alarm{ - pixel_y = 22 +/obj/machinery/turretid/stun{ + control_area = /area/ai/foyer; + name = "AI Core Access turret control"; + pixel_y = 30 }, /turf/simulated/floor/tiled/techfloor, /area/ai_upload) @@ -2919,6 +3093,14 @@ }, /turf/simulated/floor/tiled/techfloor, /area/ai_upload) +"eJ" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/door/firedoor/glass/hidden/steel{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/tether/station/stairs_two) "eK" = ( /obj/effect/floor_decal/techfloor{ dir = 4 @@ -2936,6 +3118,46 @@ /obj/structure/lattice, /turf/space, /area/space) +"eN" = ( +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/obj/effect/floor_decal/borderfloor{ + dir = 4 + }, +/obj/effect/floor_decal/corner/lightgrey/border{ + dir = 4 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 10 + }, +/obj/machinery/door/firedoor/glass/hidden/steel{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/tether/station/stairs_two) +"eO" = ( +/obj/machinery/alarm{ + pixel_y = 22 + }, +/turf/simulated/floor/tiled/dark, +/area/ai_monitored/storage/eva) +"eP" = ( +/obj/machinery/atmospherics/unary/vent_scrubber/on{ + dir = 1 + }, +/obj/machinery/alarm{ + dir = 1; + pixel_y = -25 + }, +/turf/simulated/floor/tiled, +/area/tether/station/stairs_two) "eQ" = ( /obj/machinery/atmospherics/unary/vent_pump/on{ dir = 4 @@ -2953,6 +3175,17 @@ }, /turf/simulated/floor/tiled, /area/security/brig) +"eR" = ( +/obj/effect/floor_decal/techfloor, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/alarm{ + dir = 1; + pixel_y = -22 + }, +/turf/simulated/floor/bluegrid, +/area/ai_upload) "eS" = ( /obj/effect/floor_decal/industrial/warning/corner{ icon_state = "warningcorner"; @@ -2971,6 +3204,114 @@ }, /turf/simulated/floor/tiled, /area/security/brig) +"eT" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 1 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 8 + }, +/obj/effect/floor_decal/steeldecal/steel_decals5, +/obj/machinery/alarm{ + pixel_y = 22 + }, +/turf/simulated/floor/tiled, +/area/bridge/meeting_room) +"eU" = ( +/obj/effect/floor_decal/borderfloorwhite, +/obj/effect/floor_decal/corner/paleblue/border, +/obj/machinery/camera/network/medbay{ + dir = 1 + }, +/obj/effect/landmark{ + name = "lightsout" + }, +/turf/simulated/floor/tiled/white, +/area/hallway/secondary/escape/medical_escape_pod_hallway) +"eV" = ( +/obj/structure/table/wooden_reinforced, +/obj/item/weapon/paper_bin{ + pixel_x = 1; + pixel_y = 8 + }, +/obj/item/weapon/pen/blue{ + pixel_x = -2; + pixel_y = -2 + }, +/obj/item/weapon/pen, +/obj/item/weapon/pen/red{ + pixel_x = 2; + pixel_y = 2 + }, +/turf/simulated/floor/carpet/bcarpet, +/area/tether/station/public_meeting_room) +"eW" = ( +/obj/machinery/turretid/stun{ + control_area = /area/ai_upload; + name = "AI Upload turret control"; + pixel_x = 0; + pixel_y = 30 + }, +/obj/machinery/alarm{ + dir = 4; + pixel_x = -23; + pixel_y = 0 + }, +/turf/simulated/floor/tiled/techfloor, +/area/ai_upload_foyer) +"eX" = ( +/obj/structure/table/steel, +/obj/effect/floor_decal/techfloor{ + dir = 8 + }, +/obj/item/weapon/folder/white, +/turf/simulated/floor/tiled/techfloor, +/area/medical/morgue) +"eY" = ( +/obj/structure/grille, +/obj/machinery/door/firedoor/glass, +/obj/structure/window/reinforced/polarized/full{ + id = "chapel" + }, +/turf/simulated/floor/plating, +/area/chapel/office) +"eZ" = ( +/obj/structure/grille, +/obj/machinery/door/firedoor/glass, +/obj/structure/disposalpipe/segment, +/obj/structure/window/reinforced/polarized/full{ + id = "chapel" + }, +/turf/simulated/floor/plating, +/area/chapel/office) +"fa" = ( +/obj/machinery/door/firedoor/glass, +/obj/structure/grille, +/obj/structure/window/reinforced/polarized/full{ + id = "interrogation" + }, +/obj/structure/window/reinforced/tinted{ + dir = 8; + icon_state = "twindow" + }, +/obj/structure/window/reinforced/tinted, +/obj/structure/window/reinforced/tinted{ + dir = 1 + }, +/turf/simulated/floor, +/area/security/interrogation) +"fb" = ( +/obj/machinery/door/firedoor/glass, +/obj/structure/grille, +/obj/structure/window/reinforced/polarized/full{ + id = "interrogation" + }, +/obj/structure/window/reinforced/tinted, +/obj/structure/window/reinforced/tinted{ + dir = 1 + }, +/turf/simulated/floor, +/area/security/interrogation) "fc" = ( /obj/effect/floor_decal/borderfloor{ dir = 4 @@ -2996,6 +3337,44 @@ "fd" = ( /turf/simulated/wall/r_wall, /area/security/interrogation) +"fe" = ( +/obj/machinery/door/firedoor/glass, +/obj/structure/grille, +/obj/structure/window/reinforced/polarized/full{ + id = "interrogation" + }, +/obj/structure/window/reinforced/tinted{ + dir = 4; + icon_state = "twindow" + }, +/obj/structure/window/reinforced/tinted, +/obj/structure/window/reinforced/tinted{ + dir = 1 + }, +/turf/simulated/floor, +/area/security/interrogation) +"ff" = ( +/obj/machinery/door/firedoor/glass, +/obj/structure/grille, +/obj/structure/disposalpipe/segment, +/obj/structure/window/reinforced/full, +/turf/simulated/floor/plating, +/area/hallway/station/starboard) +"fg" = ( +/obj/machinery/door/firedoor/glass, +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/turf/simulated/floor/plating, +/area/hallway/station/starboard) +"fh" = ( +/obj/effect/floor_decal/techfloor{ + dir = 8 + }, +/obj/machinery/camera/network/command{ + dir = 4 + }, +/turf/simulated/floor/bluegrid, +/area/ai_upload) "fi" = ( /obj/machinery/alarm{ dir = 4; @@ -3054,14 +3433,19 @@ /turf/simulated/wall, /area/chapel/main) "fp" = ( -/obj/effect/floor_decal/techfloor{ - dir = 8 +/obj/structure/sink{ + dir = 4; + icon_state = "sink"; + pixel_x = 11; + pixel_y = 0 }, -/obj/machinery/camera/motion/security{ - dir = 4 +/turf/simulated/floor/tiled/white, +/area/medical/virologyaccess) +"fq" = ( +/turf/simulated/shuttle/wall/voidcraft/green{ + hard_corner = 1 }, -/turf/simulated/floor/bluegrid, -/area/ai_upload) +/area/tether/elevator) "fr" = ( /obj/effect/floor_decal/industrial/outline/grey, /obj/structure/window/reinforced{ @@ -3086,6 +3470,9 @@ }, /turf/simulated/floor/tiled/techfloor, /area/ai_upload) +"fu" = ( +/turf/simulated/floor/holofloor/tiled/dark, +/area/tether/elevator) "fv" = ( /obj/effect/floor_decal/techfloor{ dir = 4 @@ -3095,6 +3482,12 @@ }, /turf/simulated/floor/bluegrid, /area/ai_upload) +"fw" = ( +/obj/structure/sign/deck2, +/turf/simulated/shuttle/wall/voidcraft/green{ + hard_corner = 1 + }, +/area/tether/elevator) "fx" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/table/rack{ @@ -3105,6 +3498,35 @@ /obj/random/maintenance/clean, /turf/simulated/floor/plating, /area/engineering/shaft) +"fy" = ( +/obj/structure/shuttle/engine/propulsion{ + dir = 8; + icon_state = "propulsion_l" + }, +/turf/space, +/turf/simulated/shuttle/plating/airless/carry, +/area/shuttle/large_escape_pod1/station{ + base_turf = /turf/simulated/mineral/floor/vacuum + }) +"fz" = ( +/obj/structure/shuttle/engine/propulsion{ + dir = 8 + }, +/turf/space, +/turf/simulated/shuttle/plating/airless/carry, +/area/shuttle/large_escape_pod1/station{ + base_turf = /turf/simulated/mineral/floor/vacuum + }) +"fA" = ( +/obj/structure/shuttle/engine/propulsion{ + dir = 8; + icon_state = "propulsion_r" + }, +/turf/space, +/turf/simulated/shuttle/plating/airless/carry, +/area/shuttle/large_escape_pod1/station{ + base_turf = /turf/simulated/mineral/floor/vacuum + }) "fB" = ( /obj/structure/stairs/south, /turf/simulated/floor/tiled, @@ -3156,16 +3578,6 @@ /obj/random/trash_pile, /turf/simulated/floor, /area/maintenance/station/sec_lower) -"fO" = ( -/obj/structure/grille, -/obj/machinery/door/firedoor/glass, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "chapel" - }, -/turf/simulated/floor/plating, -/area/chapel/office) "fP" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, @@ -3181,17 +3593,6 @@ }, /turf/simulated/floor/lino, /area/chapel/office) -"fQ" = ( -/obj/structure/grille, -/obj/machinery/door/firedoor/glass, -/obj/structure/disposalpipe/segment, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "chapel" - }, -/turf/simulated/floor/plating, -/area/chapel/office) "fR" = ( /obj/structure/cable/pink{ icon_state = "1-2" @@ -3437,13 +3838,6 @@ }, /turf/simulated/floor/bluegrid, /area/ai_upload) -"go" = ( -/obj/effect/floor_decal/techfloor, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/turf/simulated/floor/bluegrid, -/area/ai_upload) "gp" = ( /obj/structure/cable/cyan{ d1 = 1; @@ -3776,24 +4170,6 @@ /obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled, /area/security/security_cell_hallway) -"ha" = ( -/obj/machinery/door/firedoor/glass, -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "chapel" - }, -/obj/structure/window/reinforced/tinted, -/obj/structure/window/reinforced/tinted{ - dir = 1 - }, -/obj/structure/window/reinforced/tinted{ - dir = 4; - icon_state = "twindow" - }, -/turf/simulated/floor, -/area/security/interrogation) "hc" = ( /obj/structure/cable/pink{ icon_state = "1-2" @@ -5021,22 +5397,6 @@ "jL" = ( /turf/simulated/floor/plating, /area/maintenance/station/eng_upper) -"jM" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 10 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 10 - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/structure/disposalpipe/junction/yjunction, -/obj/structure/catwalk, -/turf/simulated/floor/plating, -/area/maintenance/station/eng_upper) "jN" = ( /obj/structure/cable/green{ d1 = 4; @@ -5049,19 +5409,6 @@ /obj/structure/catwalk, /turf/simulated/floor/plating, /area/maintenance/station/eng_upper) -"jO" = ( -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/machinery/door/airlock/maintenance/common, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/catwalk, -/turf/simulated/floor/plating, -/area/maintenance/station/eng_upper) "jP" = ( /obj/structure/cable/green{ d1 = 1; @@ -5263,20 +5610,6 @@ /obj/machinery/atmospherics/unary/vent_scrubber/on, /turf/simulated/floor/tiled/techfloor, /area/ai_server_room) -"ks" = ( -/obj/machinery/turretid/stun{ - control_area = "\improper AI Upload Chamber"; - name = "AI Upload turret control"; - pixel_x = 0; - pixel_y = 30 - }, -/obj/machinery/alarm{ - dir = 4; - pixel_x = -23; - pixel_y = 0 - }, -/turf/simulated/floor/tiled/techfloor, -/area/ai_upload_foyer) "kt" = ( /obj/structure/cable/cyan{ d1 = 1; @@ -5340,13 +5673,6 @@ /obj/random/tech_supply, /turf/simulated/floor, /area/vacant/vacant_office) -"kD" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/cap/hidden/supply{ - dir = 4 - }, -/turf/simulated/floor, -/area/vacant/vacant_office) "kF" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/table, @@ -5504,11 +5830,6 @@ /obj/machinery/door/firedoor/glass, /turf/simulated/open, /area/maintenance/station/eng_upper) -"kY" = ( -/turf/simulated/shuttle/wall/voidcraft/green{ - hard_corner = 1 - }, -/area/hallway/station/starboard) "kZ" = ( /obj/effect/floor_decal/borderfloor{ dir = 1 @@ -5535,7 +5856,7 @@ /turf/simulated/floor/tiled, /area/hallway/station/starboard) "la" = ( -/obj/machinery/camera/network/northern_star, +/obj/machinery/camera/network/tether, /obj/effect/floor_decal/borderfloor{ dir = 1 }, @@ -5906,9 +6227,6 @@ /obj/random/maintenance/clean, /turf/simulated/floor/plating, /area/maintenance/station/eng_upper) -"lH" = ( -/turf/simulated/floor/holofloor/tiled/dark, -/area/hallway/station/starboard) "lI" = ( /obj/machinery/door/firedoor/glass/hidden/steel{ dir = 2 @@ -6068,13 +6386,6 @@ }, /turf/simulated/floor/tiled/dark, /area/storage/tech) -"mf" = ( -/obj/machinery/atmospherics/unary/vent_scrubber/on, -/obj/machinery/light/small{ - dir = 4 - }, -/turf/simulated/floor/tiled/dark, -/area/storage/tech) "mg" = ( /obj/structure/cable/green{ d2 = 2; @@ -6301,27 +6612,6 @@ /obj/machinery/status_display, /turf/simulated/wall, /area/hallway/station/starboard) -"mz" = ( -/obj/machinery/door/firedoor/glass, -/obj/structure/grille, -/obj/structure/disposalpipe/segment, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "lawyer_blast" - }, -/turf/simulated/floor/plating, -/area/hallway/station/starboard) -"mA" = ( -/obj/machinery/door/firedoor/glass, -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "lawyer_blast" - }, -/turf/simulated/floor/plating, -/area/hallway/station/starboard) "mB" = ( /obj/machinery/door/firedoor/glass, /obj/structure/cable/green{ @@ -6819,7 +7109,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/camera/network/northern_star, +/obj/machinery/camera/network/tether, /obj/effect/floor_decal/borderfloor{ dir = 1 }, @@ -7247,12 +7537,6 @@ /obj/effect/floor_decal/industrial/outline/yellow, /turf/simulated/floor/plating, /area/maintenance/station/eng_upper) -"nI" = ( -/obj/structure/sign/deck2, -/turf/simulated/shuttle/wall/voidcraft/green{ - hard_corner = 1 - }, -/area/hallway/station/starboard) "nJ" = ( /obj/machinery/door/firedoor/glass/hidden/steel{ dir = 1 @@ -7566,7 +7850,7 @@ /turf/simulated/floor/tiled, /area/hallway/station/starboard) "op" = ( -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 1 }, /obj/structure/cable{ @@ -7674,7 +7958,7 @@ /turf/simulated/floor/tiled, /area/hallway/station/starboard) "ow" = ( -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 1 }, /obj/effect/floor_decal/borderfloor, @@ -8444,14 +8728,6 @@ /obj/item/clothing/head/helmet/space/void/security, /turf/simulated/floor/tiled/dark, /area/ai_monitored/storage/eva) -"pF" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/full, -/obj/structure/window/reinforced{ - dir = 8 - }, -/turf/simulated/floor/plating, -/area/vacant/vacant_restaurant_upper) "pG" = ( /turf/simulated/floor/plating, /area/vacant/vacant_restaurant_upper) @@ -8694,12 +8970,6 @@ /obj/effect/floor_decal/rust, /turf/simulated/floor, /area/maintenance/evahallway) -"qb" = ( -/obj/machinery/light/small{ - dir = 8 - }, -/turf/simulated/floor/tiled/dark, -/area/ai_monitored/storage/eva) "qc" = ( /turf/simulated/floor/tiled/dark, /area/ai_monitored/storage/eva) @@ -8745,13 +9015,6 @@ /obj/machinery/door/firedoor/glass, /turf/simulated/floor/tiled, /area/ai_monitored/storage/eva) -"qj" = ( -/obj/machinery/light/small{ - dir = 4; - pixel_y = 0 - }, -/turf/simulated/floor/tiled/dark, -/area/ai_monitored/storage/eva) "qk" = ( /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plating, @@ -8799,22 +9062,6 @@ /obj/effect/floor_decal/steeldecal/steel_decals7, /turf/simulated/floor/tiled, /area/hallway/station/port) -"qq" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/obj/effect/floor_decal/corner/yellow/border{ - dir = 1 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 4 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7, -/obj/machinery/door/firedoor/glass/hidden/steel{ - dir = 2 - }, -/turf/simulated/floor/tiled, -/area/hallway/station/port) "qr" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ @@ -8997,7 +9244,7 @@ icon_state = "4-8"; pixel_x = 0 }, -/obj/machinery/camera/network/northern_star, +/obj/machinery/camera/network/tether, /obj/effect/floor_decal/borderfloor{ dir = 1 }, @@ -9311,31 +9558,6 @@ }, /turf/simulated/floor/plating, /area/vacant/vacant_restaurant_upper) -"qZ" = ( -/obj/machinery/atmospherics/pipe/cap/hidden/supply{ - dir = 4 - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/turf/simulated/floor/plating, -/area/vacant/vacant_restaurant_upper) -"ra" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/cap/hidden/scrubbers{ - dir = 4 - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/turf/simulated/floor/plating, -/area/vacant/vacant_restaurant_upper) "rb" = ( /obj/structure/disposalpipe/broken{ icon_state = "pipe-b"; @@ -9407,27 +9629,6 @@ }, /turf/simulated/floor/tiled, /area/hallway/station/port) -"rf" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/door/firedoor/glass/hidden/steel, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/effect/floor_decal/steeldecal/steel_decals5{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/hallway/station/port) "rg" = ( /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 1 @@ -9816,20 +10017,6 @@ /obj/machinery/light, /turf/simulated/floor/tiled, /area/hallway/station/port) -"rR" = ( -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/lightgrey/border, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 1 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 8 - }, -/obj/machinery/door/firedoor/glass/hidden/steel{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/hallway/station/port) "rS" = ( /obj/effect/floor_decal/borderfloor/corner{ dir = 8 @@ -9888,7 +10075,7 @@ d2 = 8; icon_state = "4-8" }, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 1 }, /obj/effect/floor_decal/borderfloor, @@ -10176,21 +10363,6 @@ }, /turf/simulated/wall, /area/tether/station/stairs_two) -"sy" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/lightgrey/border{ - dir = 8 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 6 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 5 - }, -/turf/simulated/floor/tiled, -/area/tether/station/stairs_two) "sz" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, @@ -10428,13 +10600,6 @@ }, /turf/simulated/floor/tiled/dark, /area/ai_monitored/storage/eva) -"sV" = ( -/obj/machinery/atmospherics/pipe/simple/hidden{ - dir = 4 - }, -/obj/machinery/door/airlock/maintenance/common, -/turf/simulated/floor/tiled/dark, -/area/ai_monitored/storage/eva) "sW" = ( /obj/machinery/light/small{ dir = 1 @@ -10792,14 +10957,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden, /turf/simulated/floor/tiled/dark, /area/ai_monitored/storage/eva) -"tF" = ( -/obj/machinery/meter, -/obj/machinery/atmospherics/pipe/simple/hidden{ - dir = 5; - icon_state = "intact" - }, -/turf/simulated/floor/tiled/dark, -/area/ai_monitored/storage/eva) "tG" = ( /obj/effect/decal/cleanable/dirt, /obj/random/powercell, @@ -12070,12 +12227,6 @@ }, /turf/simulated/floor/tiled, /area/tether/station/stairs_two) -"vO" = ( -/obj/machinery/atmospherics/unary/vent_scrubber/on{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/tether/station/stairs_two) "vP" = ( /obj/machinery/door/firedoor/glass/hidden/steel{ dir = 1 @@ -12083,7 +12234,7 @@ /turf/simulated/floor/tiled, /area/tether/station/stairs_two) "vQ" = ( -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 1 }, /obj/effect/floor_decal/steeldecal/steel_decals6{ @@ -12325,12 +12476,6 @@ "wo" = ( /turf/simulated/wall/r_wall, /area/bridge/meeting_room) -"wp" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/full, -/obj/structure/window/reinforced, -/turf/simulated/floor/plating, -/area/vacant/vacant_restaurant_upper) "wq" = ( /obj/structure/table/rack, /obj/effect/floor_decal/borderfloor{ @@ -12894,7 +13039,6 @@ }, /obj/machinery/camera/network/medbay, /obj/machinery/alarm{ - frequency = 1441; pixel_y = 22 }, /obj/machinery/atmospherics/pipe/simple/hidden{ @@ -13402,13 +13546,6 @@ /obj/structure/sign/nosmoking_1, /turf/simulated/wall, /area/medical/morgue) -"xX" = ( -/obj/structure/table/steel, -/obj/effect/floor_decal/techfloor{ - dir = 8 - }, -/turf/simulated/floor/tiled/techfloor, -/area/medical/morgue) "xY" = ( /obj/structure/bed/chair/office/light{ dir = 8 @@ -13814,18 +13951,6 @@ }, /turf/simulated/floor/tiled/white, /area/medical/virologyaccess) -"yH" = ( -/obj/structure/sink{ - dir = 4; - icon_state = "sink"; - pixel_x = 11; - pixel_y = 0 - }, -/obj/machinery/camera/network/medbay{ - dir = 1 - }, -/turf/simulated/floor/tiled/white, -/area/medical/virologyaccess) "yI" = ( /obj/machinery/light/small, /obj/effect/decal/cleanable/dirt, @@ -14515,13 +14640,6 @@ /obj/machinery/door/airlock/maintenance/medical, /turf/simulated/floor, /area/hallway/secondary/escape/medical_escape_pod_hallway) -"zA" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor, -/area/bridge/meeting_room) "zB" = ( /obj/structure/lattice, /obj/machinery/door/firedoor/glass, @@ -15119,14 +15237,6 @@ }, /turf/simulated/floor/tiled/white, /area/hallway/secondary/escape/medical_escape_pod_hallway) -"As" = ( -/obj/effect/floor_decal/borderfloorwhite, -/obj/effect/floor_decal/corner/paleblue/border, -/obj/machinery/camera/network/medbay{ - dir = 1 - }, -/turf/simulated/floor/tiled/white, -/area/hallway/secondary/escape/medical_escape_pod_hallway) "At" = ( /obj/effect/floor_decal/borderfloorwhite, /obj/effect/floor_decal/corner/paleblue/border, @@ -16930,24 +17040,6 @@ }, /turf/simulated/floor/airless, /area/maintenance/station/sec_lower) -"Fj" = ( -/obj/machinery/door/firedoor/glass, -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "chapel" - }, -/obj/structure/window/reinforced/tinted, -/obj/structure/window/reinforced/tinted{ - dir = 1 - }, -/obj/structure/window/reinforced/tinted{ - dir = 8; - icon_state = "twindow" - }, -/turf/simulated/floor, -/area/security/interrogation) "Fq" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 5 @@ -17117,11 +17209,6 @@ /obj/structure/table/steel, /turf/simulated/floor/tiled/steel_dirty, /area/security/brig) -"GV" = ( -/obj/machinery/door/airlock/maintenance/common, -/obj/machinery/door/firedoor/glass, -/turf/simulated/floor, -/area/vacant/vacant_restaurant_upper) "GW" = ( /obj/structure/table/reinforced, /turf/simulated/floor, @@ -17625,17 +17712,6 @@ /obj/machinery/door/airlock/maintenance/common, /turf/simulated/floor, /area/maintenance/evahallway) -"LT" = ( -/obj/structure/table/wooden_reinforced, -/obj/item/weapon/paper_bin{ - pixel_x = 1; - pixel_y = 8 - }, -/obj/item/weapon/pen/blue, -/obj/item/weapon/pen, -/obj/item/weapon/pen/red, -/turf/simulated/floor/carpet/bcarpet, -/area/tether/station/public_meeting_room) "LW" = ( /obj/structure/catwalk, /obj/effect/decal/cleanable/dirt, @@ -17896,20 +17972,6 @@ }, /turf/simulated/floor/tiled, /area/security/security_cell_hallway) -"Of" = ( -/obj/machinery/door/firedoor/glass, -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "chapel" - }, -/obj/structure/window/reinforced/tinted, -/obj/structure/window/reinforced/tinted{ - dir = 1 - }, -/turf/simulated/floor, -/area/security/interrogation) "Oj" = ( /obj/machinery/alarm{ dir = 8; @@ -19014,7 +19076,6 @@ /area/security/brig) "Wi" = ( /obj/machinery/alarm{ - frequency = 1441; pixel_y = 22 }, /turf/simulated/floor, @@ -19339,11 +19400,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/alarm{ - breach_detection = 0; dir = 8; pixel_x = 25; - pixel_y = 0; - report_danger_level = 0 + pixel_y = 0 }, /obj/structure/catwalk, /turf/simulated/floor/airless, @@ -19409,12 +19468,6 @@ }, /turf/simulated/floor/plating, /area/security/brig) -"YH" = ( -/obj/machinery/atmospherics/pipe/cap/hidden/scrubbers{ - dir = 4 - }, -/turf/simulated/floor, -/area/vacant/vacant_office) "YK" = ( /obj/machinery/atmospherics/pipe/simple/hidden/green, /obj/structure/disposalpipe/segment, @@ -19452,10 +19505,6 @@ /obj/random/maintenance/engineering, /turf/simulated/floor, /area/chapel/office) -"YW" = ( -/obj/random/trash, -/turf/simulated/floor, -/area/maintenance/station/sec_lower) "Za" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, @@ -23920,16 +23969,16 @@ at FZ FZ FZ +at +dX +dX pd -pF -pF +dX +dX +dX pd -pF -pF -pF -pd -pF -pF +dX +dX pd aP aa @@ -24062,7 +24111,7 @@ Zr Zr FR DA -pd +at pG pG pG @@ -24204,7 +24253,7 @@ IX Yd Or XM -GV +Ln pG qk pG @@ -24346,7 +24395,7 @@ at JH JH at -pd +at pG qk qk @@ -24358,7 +24407,7 @@ ul qk vm qk -wp +eg aP aP ac @@ -24500,7 +24549,7 @@ pG qk pG pG -wp +eg aP aP aP @@ -24642,7 +24691,7 @@ um qk pG pG -wp +eg aP aP aP @@ -24757,7 +24806,7 @@ ac ac aP at -Mn +dr bf bf RS @@ -24909,7 +24958,7 @@ at aP aP lv -mf +ej mE nu nY @@ -24926,7 +24975,7 @@ qm qm sv tb -wp +eg aP aP aP @@ -25068,7 +25117,7 @@ ta ta tb tb -wp +eg aP aP aP @@ -25169,7 +25218,7 @@ at Fs UV at -YW +cL RS at at @@ -25210,7 +25259,7 @@ tb tb tb tb -wp +eg aP aP aP @@ -25352,7 +25401,7 @@ tb tb tb tb -wp +eg aP aP aP @@ -25627,7 +25676,7 @@ oI kJ pG ql -qZ +qY pG sv tb @@ -25636,7 +25685,7 @@ tb tb tb tb -wp +eg aP aP aP @@ -25769,7 +25818,7 @@ oJ kJ pH qm -ra +ed pG sv tb @@ -25778,7 +25827,7 @@ tb tb tb tb -wp +eg aP aP aP @@ -25920,7 +25969,7 @@ tb tb tb tb -wp +eg aP aP aP @@ -26062,7 +26111,7 @@ tb tb tb tb -wp +eg aP aP aP @@ -26487,7 +26536,7 @@ sw un uP vo -vO +eP sw ac ac @@ -26771,7 +26820,7 @@ te te te vq -vO +eP sw ac ac @@ -27046,9 +27095,9 @@ of oM oM pK -qq -rf -rR +qp +eu +rP sx sw sw @@ -27191,7 +27240,7 @@ pK qp re rS -sy +ex tf tI uo @@ -27333,7 +27382,7 @@ pK UU rg rT -sz +eJ sz sz sz @@ -27475,7 +27524,7 @@ pL qr rh rU -sA +eN sA tJ up @@ -28029,7 +28078,7 @@ ht hV hV aj -jM +dS ki kU lD @@ -28046,7 +28095,7 @@ rY KI Ha RJ -LT +eV Pj ev vT @@ -28455,7 +28504,7 @@ fd cx fd aj -jO +dW kj kX lG @@ -28592,19 +28641,19 @@ fd Mp Sy Mp -Fj +fa En hY fd LD jP kk -kY -kY -kY -kY -kY -kY +fq +fq +fq +fq +fq +fq jj pj kj @@ -28627,7 +28676,7 @@ xd zj vT Ad -As +eU AH AY Bp @@ -28734,19 +28783,19 @@ fd fK gb gE -Of +fb WL hZ fd fN jQ kk -kY -lH -lH -lH -lH -kY +fq +fu +fu +fu +fu +fq jj kj pO @@ -28876,19 +28925,19 @@ fd fL gc Mp -ha +fe hw ia fd jl jR kk -kY -lH -lH -lH -lH -kY +fq +fu +fu +fu +fu +fq jL kj pP @@ -29025,12 +29074,12 @@ fd Tj jS kk -kY -lH -lH -lH -lH -kY +fq +fu +fu +fu +fu +fq oR kj pQ @@ -29047,7 +29096,7 @@ vV ww xh xx -xX +eX yz uW zl @@ -29148,7 +29197,7 @@ RS at RS RS -bf +cW bf bf RS @@ -29167,12 +29216,12 @@ aN XM jS kk -kY -lH -lH -lH -lH -kY +fq +fu +fu +fu +fu +fq oS kj pR @@ -29309,12 +29358,12 @@ SI SI RT kk -kY -kY -lH -lH -nI -kY +fq +fq +fu +fu +fw +fq kj kj pS @@ -29583,7 +29632,7 @@ dy dY ey iH -fO +eY ge gI hc @@ -29725,7 +29774,7 @@ dz dZ ez fj -fO +eY gf gJ hd @@ -30009,7 +30058,7 @@ dB eb eB fl -fQ +eZ gh gL hf @@ -30052,11 +30101,11 @@ AN AN Bw yY -cL -cW -cW -cW -dm +fy +fz +fz +fz +fA yY ac ac @@ -30151,7 +30200,7 @@ dC ec eC fm -fO +eY gi gM hg @@ -30468,7 +30517,7 @@ wF xn xE yd -yH +fp yX zv zW @@ -31002,7 +31051,7 @@ bg db dE To -fp +fh eE gm dE @@ -31180,7 +31229,7 @@ wo wo wo wo -zA +eh zZ aP AF @@ -31288,7 +31337,7 @@ dE eG fr fV -go +eR dE hk hG @@ -31296,7 +31345,7 @@ il iT jp jY -ks +eW ll lQ jY @@ -31606,7 +31655,7 @@ wo yi yK wo -zD +ei zZ ac aP @@ -31745,7 +31794,7 @@ wm wO xq wo -yi +eT yK wo zD @@ -32276,8 +32325,8 @@ bz bV cj cF -cF dg +dm dG el bg @@ -32441,10 +32490,10 @@ Tl Uu oY pw -qb +er oY rF -qb +er oY tx ud @@ -32588,7 +32637,7 @@ oY rG qc oY -qc +eO qc qc qc @@ -33003,7 +33052,7 @@ js kz js jx -mz +ff nm nP oA @@ -33145,7 +33194,7 @@ jt jx js NJ -mA +fg nn nR oB @@ -33426,7 +33475,7 @@ Ll iY js Rl -kD +jx ls ma mB @@ -33713,7 +33762,7 @@ js kF jx Nh -mA +fg nl nU ot @@ -33854,14 +33903,14 @@ jx kd kG jx -YH -mA +js +fg nr nV oF oY pE -qj +et oY rN qc @@ -34007,7 +34056,7 @@ oY oY oY oY -sV +ee oY oY uL @@ -34150,7 +34199,7 @@ ac ac oY sW -tF +ef oY uM oY diff --git a/maps/tether/tether-07-station3.dmm b/maps/tether/tether-07-station3.dmm index f3de244601..63ef5f499b 100644 --- a/maps/tether/tether-07-station3.dmm +++ b/maps/tether/tether-07-station3.dmm @@ -122,6 +122,14 @@ }, /turf/simulated/floor, /area/security/eva) +"an" = ( +/obj/machinery/door/airlock/maintenance/sec{ + name = "Security Airlock Access"; + req_access = list(1,2,18) + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor, +/area/security/eva) "ao" = ( /turf/simulated/wall/r_wall, /area/security/armory/blue) @@ -1473,6 +1481,20 @@ /obj/structure/closet/bombcloset/double, /turf/simulated/floor/tiled/dark, /area/security/armory/blue) +"cn" = ( +/obj/machinery/door/airlock/engineering{ + name = "Security Substation"; + req_one_access = list(1,11,24) + }, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor, +/area/maintenance/substation/security) "co" = ( /obj/effect/floor_decal/borderfloor{ dir = 4 @@ -1498,10 +1520,15 @@ }, /area/maintenance/cargo) "cq" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/full, +/obj/random/trash_pile, +/obj/effect/decal/cleanable/cobweb{ + icon_state = "cobweb2" + }, +/obj/structure/railing{ + dir = 8 + }, /turf/simulated/floor, -/area/security/breakroom) +/area/maintenance/station/sec_upper) "cr" = ( /obj/effect/floor_decal/borderfloor{ dir = 4 @@ -1514,6 +1541,20 @@ }, /turf/simulated/floor/tiled, /area/security/hallwayaux) +"cs" = ( +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/structure/catwalk, +/obj/machinery/camera/network/command, +/obj/machinery/alarm{ + dir = 1; + pixel_y = -22 + }, +/turf/simulated/floor, +/area/maintenance/cargo) "ct" = ( /obj/machinery/door/firedoor/glass, /obj/machinery/door/blast/regular{ @@ -1538,6 +1579,12 @@ "cv" = ( /turf/simulated/wall/r_wall, /area/security/range) +"cw" = ( +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor, +/area/security/breakroom) "cx" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 9 @@ -1585,15 +1632,17 @@ /turf/simulated/floor, /area/maintenance/cargo) "cB" = ( -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8" +/obj/structure/cable/cyan{ + d2 = 2; + icon_state = "0-2" }, -/obj/structure/catwalk, -/obj/machinery/camera/network/command, -/turf/simulated/floor, -/area/maintenance/cargo) +/obj/machinery/power/apc{ + dir = 4; + name = "east bump"; + pixel_x = 28 + }, +/turf/simulated/floor/bluegrid, +/area/ai) "cC" = ( /obj/structure/cable{ d1 = 4; @@ -1842,13 +1891,66 @@ }, /turf/simulated/floor/carpet, /area/security/breakroom) +"db" = ( +/obj/structure/cable/cyan{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/effect/floor_decal/techfloor{ + dir = 5 + }, +/obj/effect/floor_decal/techfloor/corner{ + dir = 8 + }, +/turf/simulated/floor/tiled/techfloor/grid, +/area/ai) "dc" = ( /turf/simulated/floor/plating, /area/maintenance/station/ai) "dd" = ( -/obj/machinery/recharge_station, +/obj/structure/toilet, +/obj/machinery/light/small{ + dir = 1 + }, /turf/simulated/floor/tiled/white, /area/security/security_bathroom) +"de" = ( +/obj/machinery/door/airlock/glass_security{ + name = "Break Room"; + req_one_access = list(1,38) + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/wood, +/area/security/breakroom) +"df" = ( +/obj/effect/floor_decal/techfloor{ + dir = 8 + }, +/obj/effect/floor_decal/techfloor{ + dir = 4 + }, +/obj/structure/cable/cyan{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/simulated/floor/tiled/techfloor/grid, +/area/ai) "dg" = ( /obj/effect/floor_decal/borderfloorblack{ dir = 9 @@ -1930,6 +2032,36 @@ /obj/effect/floor_decal/industrial/outline/yellow, /turf/simulated/floor/tiled, /area/security/hallwayaux) +"dq" = ( +/obj/machinery/door/airlock/security{ + name = "Security Restroom"; + req_one_access = list(1,38) + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/tiled/white, +/area/security/security_bathroom) +"dr" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/catwalk, +/obj/machinery/alarm{ + dir = 4; + icon_state = "alarm0"; + pixel_x = -22; + pixel_y = 0 + }, +/turf/simulated/floor, +/area/maintenance/station/sec_upper) "ds" = ( /obj/structure/bed/chair/office/dark{ dir = 8 @@ -1971,6 +2103,22 @@ /obj/structure/catwalk, /turf/simulated/floor, /area/maintenance/station/sec_upper) +"dx" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, +/obj/structure/catwalk, +/obj/machinery/alarm{ + pixel_y = 22 + }, +/turf/simulated/floor, +/area/maintenance/station/sec_upper) "dy" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/catwalk, @@ -2041,17 +2189,42 @@ /turf/simulated/floor, /area/maintenance/cargo) "dG" = ( -/obj/structure/cable/cyan{ +/obj/machinery/door/airlock/vault/bolted{ + req_access = list(53) + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/cable{ + d1 = 1; d2 = 2; - icon_state = "0-2" + icon_state = "1-2" }, -/obj/machinery/power/apc{ - dir = 4; - name = "east bump"; - pixel_x = 28 +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 }, -/turf/simulated/floor/bluegrid, -/area/ai) +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/door/blast/regular{ + id = "VaultAc"; + name = "\improper Vault" + }, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/button/remote/blast_door{ + id = "VaultAc"; + name = "Vault Blast Door"; + pixel_x = 0; + pixel_y = -32; + req_access = list(53); + req_one_access = list(53) + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/tiled/dark, +/area/security/nuke_storage) "dH" = ( /obj/effect/landmark/start{ name = "AI" @@ -2181,6 +2354,25 @@ }, /turf/simulated/floor/tiled, /area/security/hallwayaux) +"dN" = ( +/obj/effect/floor_decal/borderfloorblack{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 10 + }, +/obj/machinery/light/small{ + icon_state = "bulb1"; + dir = 1 + }, +/obj/machinery/alarm{ + pixel_y = 22 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 6 + }, +/turf/simulated/floor/tiled/dark, +/area/security/armory/blue) "dO" = ( /obj/effect/floor_decal/borderfloor{ dir = 9 @@ -2195,6 +2387,20 @@ "dP" = ( /turf/simulated/wall, /area/security/security_bathroom) +"dQ" = ( +/obj/machinery/disposal, +/obj/structure/disposalpipe/trunk{ + dir = 8 + }, +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/red/border, +/obj/machinery/alarm{ + dir = 8; + icon_state = "alarm0"; + pixel_x = 24 + }, +/turf/simulated/floor/tiled, +/area/security/range) "dR" = ( /turf/simulated/wall/r_wall, /area/security/breakroom) @@ -2235,19 +2441,26 @@ /turf/simulated/floor/tiled/techfloor/grid, /area/ai) "dX" = ( -/obj/structure/cable/cyan{ +/obj/effect/floor_decal/borderfloor{ + dir = 8 + }, +/obj/effect/floor_decal/corner/red/border{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ + dir = 8 + }, +/obj/structure/cable/green{ d1 = 1; d2 = 2; icon_state = "1-2" }, -/obj/effect/floor_decal/techfloor{ - dir = 5 - }, -/obj/effect/floor_decal/techfloor/corner{ +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 8 }, -/turf/simulated/floor/tiled/techfloor/grid, -/area/ai) +/turf/simulated/floor/tiled, +/area/security/hallway) "dY" = ( /obj/machinery/door/airlock/hatch{ icon_state = "door_locked"; @@ -2259,32 +2472,10 @@ /turf/simulated/floor/tiled/dark, /area/ai) "dZ" = ( -/obj/machinery/ai_slipper{ - icon_state = "motion0" - }, -/obj/machinery/turretid/stun{ - check_synth = 1; - name = "AI Chamber turret control"; - pixel_x = 30; - pixel_y = 24 - }, -/obj/machinery/flasher{ - id = "AI"; - pixel_x = -24; - pixel_y = 25 - }, -/obj/machinery/button/remote/blast_door{ - desc = "A remote control-switch for the AI core maintenance door."; - id = "AICore"; - name = "AI Maintenance Hatch"; - pixel_x = 8; - pixel_y = -25; - req_access = list(16) - }, -/obj/machinery/light/small, -/obj/machinery/hologram/holopad, -/turf/simulated/floor/tiled/dark, -/area/ai) +/obj/structure/table/steel, +/obj/random/maintenance/clean, +/turf/simulated/floor, +/area/maintenance/station/ai) "ea" = ( /obj/structure/cable/cyan{ d1 = 1; @@ -2432,15 +2623,32 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/turf/simulated/wall, +/turf/simulated/wall{ + can_open = 1 + }, /area/maintenance/station/ai) "en" = ( /obj/machinery/camera/network/security{ - c_tag = "SEC - Vault Exterior West"; + icon_state = "camera"; dir = 8 }, /turf/simulated/floor/wood, /area/security/breakroom) +"eo" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 4 + }, +/obj/effect/floor_decal/corner/red/border{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 9 + }, +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/security/hallway) "ep" = ( /turf/simulated/wall, /area/security/security_lockerroom) @@ -2519,19 +2727,23 @@ /turf/simulated/floor/tiled/dark, /area/security/security_lockerroom) "ew" = ( -/obj/effect/floor_decal/techfloor{ +/obj/effect/floor_decal/borderfloor{ dir = 8 }, -/obj/effect/floor_decal/techfloor{ - dir = 4 +/obj/effect/floor_decal/corner/red/border{ + dir = 8 }, -/obj/structure/cable/cyan{ +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/cable/green{ d1 = 1; d2 = 2; icon_state = "1-2" }, -/turf/simulated/floor/tiled/techfloor/grid, -/area/ai) +/obj/structure/disposalpipe/segment, +/obj/machinery/door/firedoor/glass, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/turf/simulated/floor/tiled, +/area/security/hallway) "ex" = ( /obj/effect/floor_decal/techfloor{ dir = 4 @@ -2620,6 +2832,27 @@ /obj/structure/window/reinforced/full, /turf/simulated/floor, /area/security/observation) +"eE" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 4 + }, +/obj/effect/floor_decal/corner/red/border{ + dir = 4 + }, +/obj/effect/floor_decal/borderfloor/corner2{ + dir = 5 + }, +/obj/effect/floor_decal/corner/red/bordercorner2{ + dir = 5 + }, +/obj/machinery/door/firedoor/glass, +/obj/structure/extinguisher_cabinet{ + dir = 8; + icon_state = "extinguisher_closed"; + pixel_x = 30 + }, +/turf/simulated/floor/tiled, +/area/security/hallway) "eF" = ( /obj/structure/cable/green{ d1 = 4; @@ -2673,6 +2906,16 @@ }, /turf/simulated/floor/tiled/dark, /area/security/security_lockerroom) +"eL" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/door/airlock/maintenance/common, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor, +/area/maintenance/cargo) "eM" = ( /obj/structure/railing{ dir = 4 @@ -2773,7 +3016,6 @@ "eU" = ( /obj/structure/closet/crate, /obj/machinery/alarm{ - frequency = 1441; pixel_y = 22 }, /obj/item/clothing/accessory/tie/horrible, @@ -2805,6 +3047,9 @@ /obj/random/maintenance/security, /obj/random/maintenance/clean, /obj/random/maintenance/clean, +/obj/structure/railing{ + dir = 8 + }, /turf/simulated/floor, /area/maintenance/station/sec_upper) "eX" = ( @@ -2831,6 +3076,26 @@ /obj/structure/table/reinforced, /turf/simulated/floor/tiled, /area/security/briefing_room) +"fa" = ( +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, +/obj/effect/floor_decal/borderfloor{ + dir = 1 + }, +/obj/effect/floor_decal/corner/brown/border{ + dir = 1 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 4 + }, +/obj/machinery/alarm{ + pixel_y = 22 + }, +/turf/simulated/floor/tiled, +/area/hallway/station/upper) "fb" = ( /obj/machinery/light_switch{ dir = 4; @@ -3276,6 +3541,10 @@ pixel_x = 0; pixel_y = 24 }, +/obj/structure/cable/green{ + d2 = 2; + icon_state = "0-2" + }, /turf/simulated/floor/tiled/white, /area/security/forensics) "fK" = ( @@ -4035,24 +4304,21 @@ /turf/simulated/floor/tiled/dark, /area/security/armory/blue) "he" = ( -/obj/effect/floor_decal/borderfloorblack{ +/obj/effect/floor_decal/borderfloor{ dir = 1 }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 10 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 10 - }, -/obj/machinery/light/small{ - icon_state = "bulb1"; +/obj/effect/floor_decal/corner/brown/border{ dir = 1 }, -/obj/machinery/alarm{ - pixel_y = 22 +/obj/effect/floor_decal/steeldecal/steel_decals7, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 4 }, -/turf/simulated/floor/tiled/dark, -/area/security/armory/blue) +/obj/machinery/door/firedoor/glass/hidden/steel{ + dir = 2 + }, +/turf/simulated/floor/tiled, +/area/quartermaster/foyer) "hf" = ( /obj/effect/floor_decal/borderfloorblack{ dir = 5 @@ -4176,6 +4442,18 @@ /obj/random/cigarettes, /turf/simulated/floor, /area/maintenance/station/ai) +"ht" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/door/firedoor/glass/hidden/steel{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/quartermaster/foyer) "hu" = ( /obj/machinery/door/firedoor/glass, /obj/machinery/door/blast/regular{ @@ -4384,6 +4662,26 @@ }, /turf/simulated/floor/tiled, /area/security/eva) +"hO" = ( +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/brown/border, +/obj/effect/floor_decal/borderfloor/corner2{ + dir = 9 + }, +/obj/effect/floor_decal/corner/brown/bordercorner2{ + dir = 9 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 8 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 1 + }, +/obj/machinery/door/firedoor/glass/hidden/steel{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/quartermaster/foyer) "hP" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 @@ -4499,14 +4797,16 @@ /turf/simulated/floor/tiled/dark, /area/security/armory/red) "hX" = ( -/obj/machinery/disposal, -/obj/structure/disposalpipe/trunk{ - dir = 8 +/obj/machinery/atmospherics/pipe/manifold/hidden/supply, +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ + icon_state = "map-scrubbers"; + dir = 4 }, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/red/border, /turf/simulated/floor/tiled, -/area/security/range) +/area/hallway/station/upper) "hY" = ( /obj/structure/table/rack{ dir = 8; @@ -4522,12 +4822,24 @@ /turf/simulated/floor/tiled/dark, /area/security/eva) "hZ" = ( -/obj/machinery/door/airlock/maintenance/sec{ - name = "Security Airlock Access"; - req_access = list(1,2,18) +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/paleblue/border, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 8 }, -/turf/simulated/floor, -/area/security/eva) +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 1 + }, +/obj/machinery/alarm{ + dir = 1; + icon_state = "alarm0"; + pixel_y = -22 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 5 + }, +/turf/simulated/floor/tiled, +/area/hallway/station/upper) "ia" = ( /obj/structure/table/rack{ dir = 1 @@ -4543,7 +4855,6 @@ "ic" = ( /obj/structure/catwalk, /obj/machinery/alarm{ - frequency = 1441; pixel_y = 22 }, /turf/simulated/floor, @@ -5162,10 +5473,33 @@ /turf/simulated/floor, /area/maintenance/station/ai) "iK" = ( -/obj/structure/table/steel, -/obj/random/maintenance, -/turf/simulated/floor, -/area/maintenance/station/ai) +/obj/machinery/ai_slipper{ + icon_state = "motion0" + }, +/obj/machinery/turretid/stun{ + check_synth = 1; + control_area = /area/ai; + name = "AI Chamber turret control"; + pixel_x = 30; + pixel_y = 24 + }, +/obj/machinery/flasher{ + id = "AI"; + pixel_x = -24; + pixel_y = 25 + }, +/obj/machinery/button/remote/blast_door{ + desc = "A remote control-switch for the AI core maintenance door."; + id = "AICore"; + name = "AI Maintenance Hatch"; + pixel_x = 8; + pixel_y = -25; + req_access = list(16) + }, +/obj/machinery/light/small, +/obj/machinery/hologram/holopad, +/turf/simulated/floor/tiled/dark, +/area/ai) "iL" = ( /obj/effect/floor_decal/borderfloorblack{ dir = 6 @@ -5499,6 +5833,20 @@ /obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled, /area/security/hallwayaux) +"jm" = ( +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/paleblue/border, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 8 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 1 + }, +/obj/machinery/atmospherics/unary/vent_scrubber/on{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/hallway/station/upper) "jn" = ( /obj/machinery/newscaster/security_unit{ pixel_y = 32 @@ -5761,6 +6109,14 @@ }, /turf/simulated/floor/tiled, /area/security/hallwayaux) +"jJ" = ( +/obj/machinery/door/airlock{ + name = "Secondary Janitorial Closet"; + req_access = list(26) + }, +/obj/machinery/door/firedoor/border_only, +/turf/simulated/floor/tiled, +/area/maintenance/station/cargo) "jK" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -5801,6 +6157,16 @@ /obj/item/weapon/storage/box/donut, /turf/simulated/floor/carpet, /area/security/breakroom) +"jO" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/floor_decal/rust, +/obj/machinery/alarm{ + dir = 1; + icon_state = "alarm0"; + pixel_y = -22 + }, +/turf/simulated/floor/tiled, +/area/maintenance/station/cargo) "jP" = ( /obj/structure/table/rack{ dir = 4 @@ -5874,26 +6240,16 @@ /turf/simulated/floor/tiled, /area/security/hallwayaux) "jV" = ( -/obj/machinery/door/airlock/glass_security{ - name = "Break Room"; - req_one_access = list(1,38) +/obj/structure/disposalpipe/segment, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/alarm{ + dir = 4; + icon_state = "alarm0"; + pixel_x = -22; + pixel_y = 0 }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/turf/simulated/floor/wood, -/area/security/breakroom) +/turf/simulated/floor, +/area/maintenance/station/cargo) "jW" = ( /obj/structure/bed/chair/office/dark{ dir = 4 @@ -6006,6 +6362,22 @@ /obj/structure/sign/warning/secure_area, /turf/simulated/wall/r_wall, /area/security/armory/blue) +"kg" = ( +/obj/structure/railing{ + dir = 8 + }, +/obj/structure/railing, +/obj/structure/cable{ + d2 = 2; + icon_state = "0-2" + }, +/obj/machinery/power/apc{ + dir = 4; + name = "east bump"; + pixel_x = 28 + }, +/turf/simulated/floor, +/area/maintenance/station/sec_upper) "kh" = ( /obj/structure/disposalpipe/segment, /turf/simulated/floor/wood, @@ -6091,6 +6463,46 @@ /obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled, /area/security/hallwayaux) +"ks" = ( +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/catwalk, +/obj/machinery/alarm{ + dir = 8; + pixel_x = 25; + pixel_y = 0 + }, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/turf/simulated/floor, +/area/maintenance/station/sec_upper) +"kt" = ( +/obj/effect/floor_decal/rust, +/obj/structure/railing{ + dir = 4 + }, +/obj/structure/table/rack{ + dir = 8; + layer = 2.9 + }, +/obj/random/maintenance/security, +/obj/random/maintenance/security, +/obj/random/maintenance/clean, +/turf/simulated/floor, +/area/maintenance/station/sec_upper) +"ku" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/railing{ + dir = 4 + }, +/obj/random/trash_pile, +/turf/simulated/floor, +/area/maintenance/station/sec_upper) "kv" = ( /obj/structure/cable/green{ d1 = 4; @@ -6236,6 +6648,13 @@ /obj/item/weapon/book/manual/command_guide, /turf/simulated/floor/wood, /area/crew_quarters/heads/hos) +"kJ" = ( +/obj/structure/railing{ + dir = 4 + }, +/obj/random/trash_pile, +/turf/simulated/floor, +/area/maintenance/station/sec_upper) "kK" = ( /obj/effect/floor_decal/borderfloorblack{ dir = 8 @@ -6358,7 +6777,6 @@ /area/maintenance/station/ai) "kR" = ( /obj/machinery/alarm{ - frequency = 1441; pixel_y = 22 }, /turf/simulated/floor, @@ -6386,12 +6804,33 @@ }, /turf/simulated/floor, /area/maintenance/station/ai) +"kV" = ( +/obj/structure/railing{ + icon_state = "railing0"; + dir = 1 + }, +/obj/structure/railing{ + dir = 4 + }, +/turf/simulated/floor, +/area/maintenance/station/sec_upper) "kW" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 6 }, /turf/simulated/floor/tiled/white, /area/security/security_bathroom) +"kX" = ( +/obj/structure/railing{ + icon_state = "railing0"; + dir = 1 + }, +/obj/structure/railing{ + dir = 4 + }, +/obj/structure/closet, +/turf/simulated/floor, +/area/maintenance/station/sec_upper) "kY" = ( /obj/effect/floor_decal/borderfloorblack{ dir = 10 @@ -6536,6 +6975,34 @@ }, /turf/simulated/floor/tiled, /area/security/briefing_room) +"lj" = ( +/obj/machinery/door/firedoor/glass, +/obj/structure/cable/green{ + d2 = 4; + icon_state = "0-4" + }, +/obj/structure/cable/green{ + d2 = 2; + icon_state = "0-2" + }, +/obj/structure/grille, +/obj/machinery/door/blast/regular{ + density = 0; + dir = 1; + icon_state = "pdoor0"; + id = "security_lockdown"; + name = "Security Blast Doors"; + opacity = 0 + }, +/obj/structure/window/reinforced/polarized/full{ + id = "hos_office" + }, +/obj/structure/window/reinforced/polarized{ + dir = 8; + id = "hos_office" + }, +/turf/simulated/floor, +/area/crew_quarters/heads/hos) "lk" = ( /obj/effect/floor_decal/techfloor{ dir = 8 @@ -6613,6 +7080,54 @@ }, /turf/simulated/floor, /area/maintenance/station/ai) +"lu" = ( +/obj/machinery/door/firedoor/glass, +/obj/structure/cable/green, +/obj/structure/grille, +/obj/structure/cable/green{ + icon_state = "0-4" + }, +/obj/machinery/door/blast/regular{ + density = 0; + dir = 1; + icon_state = "pdoor0"; + id = "security_lockdown"; + name = "Security Blast Doors"; + opacity = 0 + }, +/obj/structure/window/reinforced/polarized/full{ + id = "hos_office" + }, +/obj/structure/window/reinforced/polarized{ + dir = 8; + id = "hos_office" + }, +/turf/simulated/floor, +/area/crew_quarters/heads/hos) +"lv" = ( +/obj/machinery/door/firedoor/glass, +/obj/machinery/door/blast/regular{ + density = 0; + dir = 4; + icon_state = "pdoor0"; + id = "brig_lockdown"; + name = "Security Blast Doors"; + opacity = 0 + }, +/obj/structure/grille, +/obj/structure/window/reinforced/polarized/full{ + id = "sec_processing" + }, +/turf/simulated/floor, +/area/security/security_processing) +"lw" = ( +/obj/machinery/door/firedoor/glass, +/obj/structure/grille, +/obj/structure/window/reinforced/polarized/full{ + id = "sec_processing" + }, +/turf/simulated/floor, +/area/security/security_processing) "lx" = ( /obj/machinery/door/firedoor/glass, /obj/machinery/door/airlock/security{ @@ -6906,6 +7421,47 @@ "lY" = ( /turf/space, /area/shuttle/antag_space/north) +"lZ" = ( +/obj/machinery/door/firedoor/glass, +/obj/structure/cable/green, +/obj/structure/grille, +/obj/machinery/door/blast/regular{ + density = 0; + dir = 1; + icon_state = "pdoor0"; + id = "security_lockdown"; + name = "Security Blast Doors"; + opacity = 0 + }, +/obj/structure/window/reinforced/polarized/full{ + id = "hos_office" + }, +/obj/structure/window/reinforced/polarized{ + dir = 8; + id = "hos_office" + }, +/turf/simulated/floor, +/area/crew_quarters/heads/hos) +"ma" = ( +/obj/machinery/door/firedoor/glass, +/obj/structure/grille, +/obj/structure/window/reinforced/polarized/full{ + id = "hos_office" + }, +/turf/simulated/floor, +/area/security/breakroom) +"mb" = ( +/obj/structure/grille, +/obj/structure/cable/green{ + d2 = 4; + icon_state = "0-4" + }, +/obj/machinery/door/firedoor/glass, +/obj/structure/window/reinforced/polarized/full{ + id = "hos_office" + }, +/turf/simulated/floor, +/area/security/forensics) "mc" = ( /obj/effect/floor_decal/borderfloorblack{ dir = 9 @@ -7261,36 +7817,31 @@ /turf/simulated/floor/tiled/dark, /area/security/security_lockerroom) "mE" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/red/border{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ - dir = 8 - }, +/obj/structure/grille, +/obj/structure/cable/green, /obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" + icon_state = "0-8" }, -/obj/structure/disposalpipe/segment, -/turf/simulated/floor/tiled, -/area/security/hallway) +/obj/machinery/door/firedoor/glass, +/obj/structure/cable/green{ + icon_state = "0-4" + }, +/obj/structure/window/reinforced/polarized/full{ + id = "hos_office" + }, +/turf/simulated/floor, +/area/security/forensics) "mF" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 4 +/obj/structure/grille, +/obj/structure/cable/green{ + icon_state = "0-8" }, -/obj/effect/floor_decal/corner/red/border{ - dir = 4 +/obj/machinery/door/firedoor/glass, +/obj/structure/window/reinforced/polarized/full{ + id = "hos_office" }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 9 - }, -/turf/simulated/floor/tiled, -/area/security/hallway) +/turf/simulated/floor, +/area/security/forensics) "mG" = ( /obj/structure/railing{ dir = 8 @@ -7306,6 +7857,48 @@ "mH" = ( /turf/simulated/wall/r_wall, /area/security/hallway) +"mI" = ( +/obj/machinery/door/firedoor/glass, +/obj/structure/cable/green{ + icon_state = "0-4" + }, +/obj/machinery/door/blast/regular{ + density = 0; + dir = 4; + icon_state = "pdoor0"; + id = "security_lockdown"; + name = "Security Blast Doors"; + opacity = 0 + }, +/obj/structure/grille, +/obj/structure/window/reinforced/polarized/full{ + id = "iaa_office" + }, +/turf/simulated/floor, +/area/lawoffice) +"mJ" = ( +/obj/machinery/door/firedoor/glass, +/obj/structure/cable/green{ + d2 = 8; + icon_state = "0-8" + }, +/obj/structure/cable/green{ + icon_state = "0-4" + }, +/obj/machinery/door/blast/regular{ + density = 0; + dir = 4; + icon_state = "pdoor0"; + id = "security_lockdown"; + name = "Security Blast Doors"; + opacity = 0 + }, +/obj/structure/grille, +/obj/structure/window/reinforced/polarized/full{ + id = "iaa_office" + }, +/turf/simulated/floor, +/area/lawoffice) "mK" = ( /obj/effect/floor_decal/borderfloor{ dir = 8 @@ -7403,6 +7996,18 @@ /obj/structure/catwalk, /turf/simulated/floor, /area/maintenance/station/sec_upper) +"mS" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 6 + }, +/obj/effect/floor_decal/corner/red/border{ + dir = 6 + }, +/obj/effect/landmark{ + name = "lightsout" + }, +/turf/simulated/floor/tiled, +/area/security/hallwayaux) "mT" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/catwalk, @@ -7426,6 +8031,22 @@ /obj/random/trash_pile, /turf/simulated/floor, /area/maintenance/cargo) +"mW" = ( +/obj/machinery/recharge_station, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/simulated/floor/tiled/white, +/area/security/security_bathroom) +"mX" = ( +/obj/effect/floor_decal/industrial/warning/corner{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/hidden{ + dir = 4 + }, +/turf/simulated/floor/tiled/white, +/area/medical/sleeper) "mY" = ( /obj/effect/floor_decal/techfloor{ dir = 10 @@ -7451,6 +8072,32 @@ }, /turf/simulated/floor/bluegrid, /area/ai/foyer) +"nb" = ( +/obj/structure/table/standard, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/effect/floor_decal/borderfloor{ + dir = 8 + }, +/obj/effect/floor_decal/corner/brown/border{ + dir = 8 + }, +/obj/item/weapon/folder/yellow, +/obj/item/weapon/stamp/denied{ + pixel_x = 4; + pixel_y = -2 + }, +/obj/item/weapon/stamp/cargo, +/turf/simulated/floor/tiled, +/area/quartermaster/office) +"nc" = ( +/obj/structure/table/glass, +/obj/item/weapon/folder/white, +/turf/simulated/floor/tiled/white, +/area/medical/reception) "nd" = ( /obj/structure/cable{ d1 = 1; @@ -7469,6 +8116,55 @@ }, /turf/simulated/floor/wood, /area/security/breakroom) +"nf" = ( +/obj/effect/floor_decal/borderfloorwhite{ + dir = 10 + }, +/obj/effect/floor_decal/corner/paleblue/border{ + dir = 10 + }, +/obj/structure/table/glass, +/obj/item/weapon/storage/box/body_record_disk, +/obj/item/weapon/paper{ + desc = ""; + info = "Bodies designed on the design console must be saved to a disk, provided on the front desk counter, then placed into the resleeving console for printing."; + name = "Body Designer Note" + }, +/obj/item/device/sleevemate, +/obj/item/weapon/folder/white, +/turf/simulated/floor/tiled/white, +/area/medical/reception) +"ng" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/effect/floor_decal/steeldecal/steel_decals4{ + dir = 6 + }, +/obj/effect/floor_decal/steeldecal/steel_decals4{ + dir = 1 + }, +/turf/simulated/floor/tiled/white, +/area/medical/sleeper) +"nh" = ( +/obj/structure/table/standard, +/obj/item/weapon/hand_labeler, +/obj/item/weapon/stamp{ + pixel_x = -3; + pixel_y = 3 + }, +/obj/item/weapon/hand_labeler, +/obj/item/weapon/folder/yellow, +/turf/simulated/floor/tiled, +/area/quartermaster/storage) "ni" = ( /obj/structure/bookcase, /obj/item/weapon/book/manual/security_space_law, @@ -7512,49 +8208,37 @@ /turf/simulated/floor/tiled/dark, /area/security/security_lockerroom) "nm" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/red/border{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/door/firedoor/glass, /obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" + d2 = 8; + icon_state = "0-8" }, -/obj/structure/disposalpipe/segment, -/obj/machinery/door/firedoor/glass, -/turf/simulated/floor/tiled, -/area/security/hallway) +/obj/machinery/door/blast/regular{ + density = 0; + dir = 4; + icon_state = "pdoor0"; + id = "security_lockdown"; + name = "Security Blast Doors"; + opacity = 0 + }, +/obj/structure/grille, +/obj/structure/window/reinforced/polarized/full{ + id = "iaa_office" + }, +/turf/simulated/floor, +/area/lawoffice) "nn" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/obj/effect/floor_decal/corner/red/border{ - dir = 4 - }, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 5 - }, -/obj/effect/floor_decal/corner/red/bordercorner2{ - dir = 5 - }, -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 8 - }, /obj/machinery/door/firedoor/glass, -/obj/structure/extinguisher_cabinet{ - dir = 8; - icon_state = "extinguisher_closed"; - pixel_x = 30 +/obj/structure/grille, +/obj/structure/window/reinforced/polarized/full{ + id = "iaa_office" }, -/turf/simulated/floor/tiled, -/area/security/hallway) +/obj/structure/window/reinforced/polarized{ + dir = 8; + id = "iaa_office" + }, +/turf/simulated/floor, +/area/lawoffice) "no" = ( /turf/simulated/wall, /area/security/hallway) @@ -7997,6 +8681,20 @@ /obj/structure/table/woodentable, /turf/simulated/floor/carpet, /area/security/breakroom) +"nZ" = ( +/obj/effect/floor_decal/spline/plain, +/obj/structure/flora/pottedplant/stoutbush, +/obj/machinery/button/windowtint{ + id = "iaa_office"; + pixel_x = 0; + pixel_y = -36 + }, +/obj/machinery/light_switch{ + pixel_x = 0; + pixel_y = -26 + }, +/turf/simulated/floor/tiled/dark, +/area/lawoffice) "oa" = ( /obj/item/device/radio/intercom{ dir = 4; @@ -8074,22 +8772,36 @@ /area/security/security_processing) "og" = ( /obj/machinery/door/firedoor/glass, -/obj/machinery/door/blast/regular{ - density = 0; - dir = 4; - icon_state = "pdoor0"; - id = "brig_lockdown"; - name = "Security Blast Doors"; - opacity = 0 - }, /obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "sec_processing" +/obj/structure/window/reinforced/polarized/full{ + id = "iaa_office" }, /turf/simulated/floor, -/area/security/security_processing) +/area/lawoffice) +"oh" = ( +/obj/structure/table/glass, +/obj/item/weapon/paper_bin, +/obj/item/weapon/clipboard, +/obj/item/weapon/pen, +/obj/machinery/camera/network/medbay{ + dir = 8 + }, +/obj/machinery/firealarm{ + dir = 4; + pixel_x = 24 + }, +/obj/effect/floor_decal/borderfloorwhite{ + dir = 5 + }, +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 8 + }, +/obj/effect/floor_decal/corner/pink/border{ + dir = 5 + }, +/obj/item/weapon/folder/white, +/turf/simulated/floor/tiled/white, +/area/medical/exam_room) "oi" = ( /obj/effect/floor_decal/borderfloor{ dir = 8 @@ -8189,6 +8901,14 @@ /obj/random/junk, /turf/simulated/floor, /area/maintenance/cargo) +"oq" = ( +/obj/structure/grille, +/obj/machinery/door/firedoor/glass, +/obj/structure/window/reinforced/polarized/full{ + id = "psych_office" + }, +/turf/simulated/floor/plating, +/area/medical/psych) "or" = ( /obj/item/weapon/storage/laundry_basket, /turf/simulated/floor, @@ -8207,6 +8927,14 @@ /obj/structure/grille, /turf/space, /area/space) +"ou" = ( +/obj/machinery/button/windowtint{ + id = "psych_office"; + pixel_x = 24; + range = 8 + }, +/turf/simulated/floor/carpet/blue, +/area/medical/psych) "ov" = ( /obj/structure/bed/chair/office/dark{ dir = 1 @@ -8523,6 +9251,22 @@ }, /turf/simulated/floor/wood, /area/crew_quarters/heads/hos) +"oY" = ( +/obj/structure/grille, +/obj/machinery/door/firedoor/glass, +/obj/machinery/door/blast/shutters{ + density = 0; + dir = 8; + icon_state = "shutter0"; + id = "surgeryobs"; + name = "Operating Theatre Privacy Shutters"; + opacity = 0 + }, +/obj/structure/window/reinforced/polarized/full{ + id = "surgery_1" + }, +/turf/simulated/floor/plating, +/area/medical/surgery) "oZ" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 5 @@ -8965,6 +9709,14 @@ /obj/random/maintenance/medical, /turf/simulated/floor, /area/maintenance/station/ai) +"pB" = ( +/obj/structure/grille, +/obj/machinery/door/firedoor/glass, +/obj/structure/window/reinforced/polarized/full{ + id = "resleeving" + }, +/turf/simulated/floor/plating, +/area/medical/resleeving) "pC" = ( /obj/machinery/disposal, /obj/structure/disposalpipe/trunk{ @@ -8973,15 +9725,37 @@ /turf/simulated/floor/wood, /area/crew_quarters/heads/hos) "pD" = ( -/obj/machinery/door/firedoor/glass, -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "hos_office" +/obj/machinery/atmospherics/pipe/simple/hidden{ + dir = 4 }, -/turf/simulated/floor, -/area/security/breakroom) +/obj/effect/floor_decal/borderfloorwhite{ + dir = 4 + }, +/obj/effect/floor_decal/corner/paleblue/border{ + dir = 4 + }, +/obj/effect/floor_decal/borderfloorwhite/corner2{ + dir = 5 + }, +/obj/effect/floor_decal/corner/paleblue/bordercorner2{ + dir = 5 + }, +/obj/machinery/button/windowtint{ + dir = 8; + id = "resleeving"; + pixel_x = 28; + pixel_y = 8 + }, +/obj/machinery/button/remote/airlock{ + desc = "A remote control switch for the medbay recovery room door."; + dir = 8; + id = "MedicalResleeving"; + name = "Exit Button"; + pixel_x = 28; + pixel_y = -4 + }, +/turf/simulated/floor/tiled/white, +/area/medical/resleeving) "pE" = ( /obj/effect/floor_decal/borderfloor, /obj/effect/floor_decal/corner/red/border, @@ -9064,9 +9838,16 @@ /turf/simulated/floor/tiled, /area/security/security_processing) "pN" = ( -/obj/structure/closet, -/turf/simulated/floor, -/area/maintenance/station/sec_upper) +/obj/structure/grille, +/obj/machinery/atmospherics/pipe/simple/hidden{ + dir = 4 + }, +/obj/machinery/door/firedoor/glass, +/obj/structure/window/reinforced/polarized/full{ + id = "resleeving" + }, +/turf/simulated/floor/plating, +/area/medical/resleeving) "pO" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, @@ -9125,12 +9906,16 @@ /turf/simulated/floor/tiled, /area/security/hallway) "pS" = ( -/obj/random/trash_pile, -/obj/effect/decal/cleanable/cobweb{ - icon_state = "cobweb2" +/obj/structure/table/standard, +/obj/effect/floor_decal/borderfloorwhite, +/obj/effect/floor_decal/corner/white/border, +/obj/machinery/button/windowtint{ + id = "surgery_1"; + pixel_y = -26 }, -/turf/simulated/floor, -/area/maintenance/station/sec_upper) +/obj/item/stack/nanopaste, +/turf/simulated/floor/tiled/white, +/area/medical/surgery) "pT" = ( /obj/structure/railing, /turf/simulated/floor, @@ -9633,15 +10418,13 @@ /turf/simulated/floor/tiled, /area/security/hallway) "qQ" = ( -/obj/machinery/door/firedoor/glass, /obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "sec_processing" +/obj/machinery/door/firedoor/glass, +/obj/structure/window/reinforced/polarized/full{ + id = "surgery_2" }, -/turf/simulated/floor, -/area/security/security_processing) +/turf/simulated/floor/plating, +/area/medical/surgery2) "qR" = ( /obj/effect/floor_decal/borderfloor{ dir = 8 @@ -10212,18 +10995,13 @@ /turf/simulated/floor, /area/security/hallway) "rC" = ( -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" +/obj/structure/grille, +/obj/machinery/door/firedoor/glass, +/obj/structure/window/reinforced/polarized/full{ + id = "cmo_office_int" }, -/obj/structure/disposalpipe/segment{ - dir = 2; - icon_state = "pipe-c" - }, -/obj/structure/catwalk, -/turf/simulated/floor, -/area/maintenance/station/sec_upper) +/turf/simulated/floor/plating, +/area/crew_quarters/heads/cmo) "rD" = ( /obj/structure/cable/green{ d1 = 4; @@ -11287,18 +12065,42 @@ /turf/simulated/floor/tiled, /area/security/hallway) "tc" = ( -/obj/machinery/door/firedoor/glass, -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "lawyer_blast" +/obj/structure/bed/chair/office/light{ + dir = 4 }, -/obj/structure/window/reinforced{ - dir = 8 +/obj/effect/landmark/start{ + name = "Chief Medical Officer" }, -/turf/simulated/floor, -/area/lawoffice) +/obj/machinery/button/remote/airlock{ + desc = "A remote control switch for the CMO's office."; + id = "cmodoor"; + name = "CMO Office Door Control"; + pixel_x = -8; + pixel_y = -36 + }, +/obj/machinery/button/remote/blast_door{ + desc = "A remote control-switch for shutters."; + id = "virologyquar"; + name = "Virology Emergency Lockdown Control"; + pixel_x = 0; + pixel_y = -28; + req_access = list(5) + }, +/obj/machinery/button/remote/blast_door{ + desc = "A remote control-switch for shutters."; + id = "medbayquar"; + name = "Medbay Emergency Lockdown Control"; + pixel_x = 0; + pixel_y = -36; + req_access = list(5) + }, +/obj/machinery/button/windowtint{ + id = "cmo_office_int"; + pixel_x = -6; + pixel_y = -28 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/heads/cmo) "td" = ( /obj/effect/floor_decal/borderfloor{ dir = 1; @@ -11476,7 +12278,7 @@ /turf/simulated/shuttle/wall/voidcraft/green{ hard_corner = 1 }, -/area/hallway/station/upper) +/area/tether/elevator) "to" = ( /obj/effect/floor_decal/borderfloor{ dir = 1 @@ -11515,7 +12317,6 @@ }, /obj/effect/floor_decal/steeldecal/steel_decals7, /obj/machinery/alarm{ - frequency = 1441; pixel_y = 22 }, /obj/machinery/atmospherics/unary/vent_scrubber/on, @@ -11581,14 +12382,13 @@ /turf/simulated/floor/tiled, /area/hallway/station/upper) "tt" = ( -/obj/structure/disposalpipe/segment, -/obj/effect/decal/cleanable/dirt, -/obj/structure/cable{ - icon_state = "1-2" +/obj/machinery/door/firedoor/glass, +/obj/structure/grille, +/obj/structure/window/reinforced/polarized/full{ + id = "exam_room" }, -/obj/machinery/door/airlock/maintenance/common, /turf/simulated/floor, -/area/maintenance/cargo) +/area/medical/sleeper) "tu" = ( /obj/machinery/conveyor{ dir = 1; @@ -11661,25 +12461,15 @@ /turf/simulated/wall, /area/quartermaster/office) "tC" = ( -/obj/item/weapon/stamp/denied{ - pixel_x = 4; - pixel_y = -2 - }, /obj/structure/table/standard, -/obj/item/weapon/stamp/cargo, -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" +/obj/effect/floor_decal/borderfloorwhite, +/obj/effect/floor_decal/corner/white/border, +/obj/machinery/button/windowtint{ + id = "surgery_2"; + pixel_y = -26 }, -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/brown/border{ - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/quartermaster/office) +/turf/simulated/floor/tiled/white, +/area/medical/surgery2) "tD" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ @@ -12097,7 +12887,7 @@ /area/maintenance/station/elevator) "ui" = ( /turf/simulated/floor/holofloor/tiled/dark, -/area/hallway/station/upper) +/area/tether/elevator) "uj" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/door/firedoor/glass/hidden/steel{ @@ -12432,51 +13222,24 @@ /turf/simulated/wall/r_wall, /area/security/detectives_office) "uK" = ( -/obj/machinery/door/firedoor/glass, -/obj/structure/cable/green{ - icon_state = "0-4" - }, -/obj/machinery/door/blast/regular{ - density = 0; - dir = 4; - icon_state = "pdoor0"; - id = "security_lockdown"; - name = "Security Blast Doors"; - opacity = 0 - }, /obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "lawyer_blast" +/obj/machinery/door/firedoor/glass, +/obj/structure/window/reinforced/polarized/full{ + id = "cmo_office_ext" }, -/turf/simulated/floor, -/area/lawoffice) +/obj/structure/window/reinforced/polarized{ + dir = 8; + id = "cmo_office_ext" + }, +/turf/simulated/floor/plating, +/area/crew_quarters/heads/cmo) "uL" = ( -/obj/machinery/door/firedoor/glass, -/obj/structure/cable/green{ - d2 = 8; - icon_state = "0-8" +/obj/machinery/washing_machine, +/obj/machinery/light{ + dir = 4 }, -/obj/structure/cable/green{ - icon_state = "0-4" - }, -/obj/machinery/door/blast/regular{ - density = 0; - dir = 4; - icon_state = "pdoor0"; - id = "security_lockdown"; - name = "Security Blast Doors"; - opacity = 0 - }, -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "lawyer_blast" - }, -/turf/simulated/floor, -/area/lawoffice) +/turf/simulated/floor/tiled/white, +/area/security/security_bathroom) "uM" = ( /obj/machinery/door/firedoor/glass, /obj/structure/cable/green{ @@ -12511,27 +13274,16 @@ /turf/simulated/floor/tiled/dark, /area/lawoffice) "uN" = ( -/obj/machinery/door/firedoor/glass, -/obj/structure/cable/green{ - d2 = 8; - icon_state = "0-8" - }, -/obj/machinery/door/blast/regular{ - density = 0; - dir = 4; - icon_state = "pdoor0"; - id = "security_lockdown"; - name = "Security Blast Doors"; - opacity = 0 - }, /obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "lawyer_blast" +/obj/machinery/door/firedoor/glass, +/obj/structure/window/reinforced/polarized/full{ + id = "exam_room" }, -/turf/simulated/floor, -/area/lawoffice) +/obj/structure/window/reinforced/polarized{ + id = "exam_room" + }, +/turf/simulated/floor/plating, +/area/medical/exam_room) "uO" = ( /turf/simulated/wall/r_wall, /area/lawoffice) @@ -12702,11 +13454,9 @@ /obj/random/maintenance/cargo, /obj/random/maintenance/cargo, /obj/machinery/alarm{ - breach_detection = 0; dir = 8; pixel_x = 25; - pixel_y = 0; - report_danger_level = 0 + pixel_y = 0 }, /obj/item/weapon/storage/box/lights/mixed, /obj/item/weapon/storage/box/lights/mixed, @@ -13325,15 +14075,19 @@ /turf/space/cracked_asteroid, /area/mine/explored/upper_level) "wf" = ( -/obj/machinery/door/firedoor/glass, -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "lawyer_blast" +/obj/effect/floor_decal/borderfloorwhite{ + dir = 10 }, -/turf/simulated/floor, -/area/lawoffice) +/obj/effect/floor_decal/corner/paleblue/border{ + dir = 10 + }, +/obj/machinery/button/windowtint{ + id = "cmo_office_ext"; + pixel_x = -20; + pixel_y = -25 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/heads/cmo) "wg" = ( /obj/effect/floor_decal/spline/plain{ icon_state = "spline_plain"; @@ -13497,7 +14251,7 @@ /turf/simulated/shuttle/wall/voidcraft/green{ hard_corner = 1 }, -/area/hallway/station/upper) +/area/tether/elevator) "ww" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/door/firedoor/glass/hidden/steel{ @@ -13581,7 +14335,7 @@ pixel_x = -27; pixel_y = 0 }, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 4 }, /obj/effect/floor_decal/borderfloor{ @@ -13667,11 +14421,10 @@ /area/quartermaster/office) "wL" = ( /obj/machinery/camera/network/security{ - c_tag = "SEC - Vault Exterior North"; - dir = 1 + c_tag = "SEC - Vault Exterior South" }, /turf/simulated/mineral/floor/vacuum, -/area/mine/explored/upper_level) +/area/security/nuke_storage) "wM" = ( /obj/machinery/atmospherics/unary/vent_scrubber/on, /obj/structure/table/reinforced, @@ -13877,7 +14630,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/camera/network/northern_star, +/obj/machinery/camera/network/tether, /obj/effect/floor_decal/borderfloor{ dir = 1 }, @@ -13980,22 +14733,16 @@ /turf/simulated/floor/tiled, /area/hallway/station/upper) "xh" = ( -/obj/structure/disposalpipe/segment{ - dir = 1; - icon_state = "pipe-c" +/obj/structure/grille, +/obj/machinery/door/firedoor/glass, +/obj/structure/window/reinforced/polarized/full{ + id = "cmo_office_ext" }, -/obj/effect/floor_decal/borderfloor{ - dir = 1 +/obj/structure/window/reinforced/polarized{ + id = "cmo_office_ext" }, -/obj/effect/floor_decal/corner/brown/border{ - dir = 1 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/hallway/station/upper) +/turf/simulated/floor/plating, +/area/crew_quarters/heads/cmo) "xi" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -14180,12 +14927,22 @@ /turf/simulated/floor/tiled, /area/quartermaster/office) "xu" = ( -/obj/machinery/light{ - dir = 4; - icon_state = "tube1" +/obj/structure/table/glass, +/obj/effect/floor_decal/borderfloorwhite{ + dir = 4 }, -/turf/space, -/area/space) +/obj/effect/floor_decal/corner/paleblue/border{ + dir = 4 + }, +/obj/effect/floor_decal/borderfloorwhite/corner2{ + dir = 6 + }, +/obj/effect/floor_decal/corner/paleblue/bordercorner2{ + dir = 6 + }, +/obj/item/device/defib_kit/loaded, +/turf/simulated/floor/tiled/white, +/area/medical/sleeper) "xv" = ( /obj/structure/sign/warning/secure_area, /turf/simulated/wall/r_wall, @@ -14194,13 +14951,12 @@ /turf/simulated/wall/r_wall, /area/security/nuke_storage) "xx" = ( -/obj/machinery/light{ - dir = 8; - icon_state = "tube1"; - pixel_y = 0 +/obj/machinery/camera/network/security{ + c_tag = "SEC - Vault Exterior North"; + dir = 1 }, /turf/simulated/mineral/floor/vacuum, -/area/mine/explored/upper_level) +/area/security/nuke_storage) "xy" = ( /obj/effect/floor_decal/spline/plain{ icon_state = "spline_plain"; @@ -14438,7 +15194,7 @@ pixel_x = -27; pixel_y = 0 }, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 4 }, /obj/effect/floor_decal/borderfloor{ @@ -14726,19 +15482,13 @@ /turf/simulated/floor/tiled/dark, /area/lawoffice) "yl" = ( -/obj/effect/floor_decal/spline/plain, -/obj/structure/flora/pottedplant/stoutbush, -/obj/machinery/button/windowtint{ - id = "lawyer_blast"; - pixel_x = 0; - pixel_y = -36 +/obj/structure/grille, +/obj/machinery/door/firedoor/glass, +/obj/structure/window/reinforced/polarized/full{ + id = "recovery_ward" }, -/obj/machinery/light_switch{ - pixel_x = 0; - pixel_y = -26 - }, -/turf/simulated/floor/tiled/dark, -/area/lawoffice) +/turf/simulated/floor/plating, +/area/medical/sleeper) "ym" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, @@ -14923,7 +15673,7 @@ /obj/effect/floor_decal/corner/lightgrey{ dir = 6 }, -/obj/machinery/camera/network/northern_star, +/obj/machinery/camera/network/tether, /obj/structure/table/bench/standard, /obj/effect/floor_decal/steeldecal/steel_decals6{ dir = 9 @@ -15186,7 +15936,7 @@ /turf/simulated/floor/tiled, /area/hallway/station/upper) "yR" = ( -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 1 }, /obj/effect/floor_decal/borderfloor, @@ -15211,22 +15961,32 @@ /turf/simulated/floor/tiled, /area/quartermaster/foyer) "yT" = ( -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/brown/border, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 9 - }, -/obj/effect/floor_decal/corner/brown/bordercorner2{ - dir = 9 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 8 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ +/obj/effect/floor_decal/borderfloorwhite{ dir = 1 }, -/turf/simulated/floor/tiled, -/area/quartermaster/foyer) +/obj/effect/floor_decal/corner/paleblue/border{ + dir = 1 + }, +/obj/effect/floor_decal/borderfloorwhite/corner2{ + dir = 4 + }, +/obj/effect/floor_decal/corner/paleblue/bordercorner2{ + dir = 4 + }, +/obj/machinery/button/remote/airlock{ + desc = "A remote control switch for the medbay recovery room door."; + id = "MedicalRecovery"; + name = "Exit Button"; + pixel_x = -4; + pixel_y = 26 + }, +/obj/machinery/button/windowtint{ + id = "recovery_ward"; + pixel_x = 6; + pixel_y = 26 + }, +/turf/simulated/floor/tiled/white, +/area/medical/ward) "yU" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, @@ -15915,7 +16675,7 @@ dir = 4 }, /obj/effect/floor_decal/steeldecal/steel_decals7, -/obj/machinery/camera/network/northern_star, +/obj/machinery/camera/network/tether, /turf/simulated/floor/tiled, /area/hallway/station/upper) "zY" = ( @@ -16101,7 +16861,7 @@ /turf/simulated/floor/tiled, /area/hallway/station/upper) "Aj" = ( -/obj/machinery/camera/network/northern_star, +/obj/machinery/camera/network/tether, /obj/effect/floor_decal/borderfloor{ dir = 1 }, @@ -16400,15 +17160,13 @@ /turf/simulated/floor/tiled, /area/hallway/station/upper) "AA" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "psych-tint" - }, /obj/machinery/door/firedoor/glass, -/turf/simulated/floor/plating, -/area/medical/psych) +/obj/structure/grille, +/obj/structure/window/reinforced/polarized/full{ + id = "patient_room_a" + }, +/turf/simulated/floor, +/area/medical/patient_a) "AB" = ( /obj/structure/table/woodentable, /obj/structure/plushie/ian{ @@ -16601,13 +17359,6 @@ /area/supply/station{ dynamic_lighting = 0 }) -"AZ" = ( -/obj/machinery/camera/network/security{ - c_tag = "SEC - Vault Exterior West"; - dir = 8 - }, -/turf/space, -/area/space) "Ba" = ( /obj/machinery/atmospherics/unary/vent_pump/on{ dir = 4 @@ -16667,41 +17418,13 @@ /turf/simulated/floor/tiled/dark, /area/security/nuke_storage) "Bf" = ( -/obj/machinery/door/airlock/vault/bolted{ - req_access = list(53) +/obj/machinery/door/firedoor/glass, +/obj/structure/grille, +/obj/structure/window/reinforced/polarized/full{ + id = "patient_room_b" }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/door/blast/regular{ - id = "VaultAc"; - name = "\improper Vault" - }, -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/machinery/button/remote/blast_door{ - id = "VaultAc"; - name = "Vault Blast Door"; - pixel_x = 0; - pixel_y = -32; - req_access = list(53); - req_one_access = list(53) - }, -/turf/simulated/floor/tiled/dark, -/area/security/nuke_storage) +/turf/simulated/floor, +/area/medical/patient_b) "Bg" = ( /obj/structure/disposalpipe/segment{ dir = 4; @@ -17045,15 +17768,13 @@ /turf/simulated/floor/tiled, /area/hallway/station/upper) "BB" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 9 +/obj/machinery/door/firedoor/glass, +/obj/structure/grille, +/obj/structure/window/reinforced/polarized/full{ + id = "patient_room_c" }, -/obj/machinery/atmospherics/pipe/manifold/hidden/supply, -/obj/structure/cable{ - icon_state = "1-8" - }, -/turf/simulated/floor/tiled, -/area/hallway/station/upper) +/turf/simulated/floor, +/area/medical/patient_c) "BC" = ( /obj/effect/floor_decal/borderfloor, /obj/effect/floor_decal/corner/lightgrey/border, @@ -17327,7 +18048,7 @@ /turf/simulated/floor/tiled, /area/hallway/station/upper) "Cg" = ( -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 1 }, /obj/effect/floor_decal/borderfloor, @@ -17528,17 +18249,67 @@ /turf/simulated/floor/wood, /area/medical/psych) "Cy" = ( -/obj/machinery/door/airlock{ - name = "Secondary Janitorial Closet"; - req_access = list(26) +/obj/structure/bed/chair{ + dir = 8 }, -/turf/simulated/floor/tiled, -/area/maintenance/station/cargo) +/obj/effect/floor_decal/borderfloorwhite{ + dir = 5 + }, +/obj/effect/floor_decal/corner/pink/border{ + dir = 5 + }, +/obj/effect/floor_decal/borderfloorwhite/corner2{ + dir = 4 + }, +/obj/effect/floor_decal/corner/pink/bordercorner2{ + dir = 4 + }, +/obj/machinery/light_switch{ + dir = 2; + name = "light switch "; + pixel_x = 0; + pixel_y = 36 + }, +/obj/machinery/button/windowtint{ + id = "patient_room_a"; + pixel_y = 26 + }, +/obj/machinery/camera/network/medbay{ + dir = 8 + }, +/turf/simulated/floor/tiled/white, +/area/medical/patient_a) "Cz" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/floor_decal/rust, -/turf/simulated/floor/tiled, -/area/maintenance/station/cargo) +/obj/structure/bed/chair{ + dir = 8 + }, +/obj/effect/floor_decal/borderfloorwhite{ + dir = 5 + }, +/obj/effect/floor_decal/corner/pink/border{ + dir = 5 + }, +/obj/effect/floor_decal/borderfloorwhite/corner2{ + dir = 4 + }, +/obj/effect/floor_decal/corner/pink/bordercorner2{ + dir = 4 + }, +/obj/machinery/button/windowtint{ + id = "patient_room_b"; + pixel_y = 26 + }, +/obj/machinery/light_switch{ + dir = 2; + name = "light switch "; + pixel_x = 0; + pixel_y = 36 + }, +/obj/machinery/camera/network/medbay{ + dir = 8 + }, +/turf/simulated/floor/tiled/white, +/area/medical/patient_b) "CA" = ( /obj/effect/floor_decal/rust, /turf/simulated/floor/tiled, @@ -17576,7 +18347,7 @@ dir = 9; pixel_y = 0 }, -/mob/living/simple_animal/fluffy, +/mob/living/simple_mob/animal/sif/fluffy, /turf/simulated/floor/tiled, /area/quartermaster/qm) "CG" = ( @@ -18464,13 +19235,36 @@ /turf/simulated/floor/carpet/blue, /area/medical/psych) "Ej" = ( -/obj/machinery/button/windowtint{ - id = "psych-tint"; - pixel_x = 24; - range = 8 +/obj/structure/bed/chair{ + dir = 8 }, -/turf/simulated/floor/carpet/blue, -/area/medical/psych) +/obj/effect/floor_decal/borderfloorwhite{ + dir = 5 + }, +/obj/effect/floor_decal/corner/pink/border{ + dir = 5 + }, +/obj/effect/floor_decal/borderfloorwhite/corner2{ + dir = 4 + }, +/obj/effect/floor_decal/corner/pink/bordercorner2{ + dir = 4 + }, +/obj/machinery/button/windowtint{ + id = "patient_room_c"; + pixel_y = 26 + }, +/obj/machinery/light_switch{ + dir = 2; + name = "light switch "; + pixel_x = 0; + pixel_y = 36 + }, +/obj/machinery/camera/network/medbay{ + dir = 8 + }, +/turf/simulated/floor/tiled/white, +/area/medical/patient_c) "Ek" = ( /obj/structure/cable{ d1 = 1; @@ -18652,7 +19446,7 @@ /obj/machinery/atmospherics/unary/vent_pump/on{ dir = 1 }, -/obj/machinery/camera/network/northern_star{ +/obj/machinery/camera/network/tether{ dir = 9 }, /obj/effect/floor_decal/industrial/warning, @@ -19590,9 +20384,16 @@ /turf/simulated/floor/tiled/white, /area/medical/reception) "Gn" = ( -/obj/structure/table/glass, -/turf/simulated/floor/tiled/white, -/area/medical/reception) +/obj/structure/grille, +/obj/machinery/door/firedoor/glass, +/obj/structure/window/reinforced/polarized/full{ + id = "patient_room_a" + }, +/obj/structure/window/reinforced/polarized{ + id = "patient_room_a" + }, +/turf/simulated/floor/plating, +/area/medical/patient_a) "Go" = ( /obj/machinery/door/window/eastleft{ req_one_access = list(5) @@ -20110,21 +20911,14 @@ "Hk" = ( /obj/structure/grille, /obj/machinery/door/firedoor/glass, -/obj/machinery/door/blast/shutters{ - density = 0; - dir = 8; - icon_state = "shutter0"; - id = "surgeryobs"; - name = "Operating Theatre Privacy Shutters"; - opacity = 0 +/obj/structure/window/reinforced/polarized/full{ + id = "patient_room_b" }, /obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "surgeryobs" + id = "patient_room_b" }, /turf/simulated/floor/plating, -/area/medical/surgery) +/area/medical/patient_b) "Hl" = ( /obj/machinery/iv_drip, /obj/effect/floor_decal/borderfloorwhite{ @@ -20441,22 +21235,16 @@ /turf/simulated/floor, /area/maintenance/security_starboard) "HM" = ( -/obj/effect/floor_decal/borderfloorwhite{ - dir = 10 +/obj/structure/grille, +/obj/machinery/door/firedoor/glass, +/obj/structure/window/reinforced/polarized/full{ + id = "patient_room_c" }, -/obj/effect/floor_decal/corner/paleblue/border{ - dir = 10 +/obj/structure/window/reinforced/polarized{ + id = "patient_room_c" }, -/obj/structure/table/glass, -/obj/item/weapon/storage/box/body_record_disk, -/obj/item/weapon/paper{ - desc = ""; - info = "Bodies designed on the design console must be saved to a disk, provided on the front desk counter, then placed into the resleeving console for printing."; - name = "Body Designer Note" - }, -/obj/item/device/sleevemate, -/turf/simulated/floor/tiled/white, -/area/medical/reception) +/turf/simulated/floor/plating, +/area/medical/patient_c) "HN" = ( /obj/effect/floor_decal/borderfloorwhite, /obj/effect/floor_decal/corner/paleblue/border, @@ -21391,13 +22179,14 @@ "Jg" = ( /obj/structure/grille, /obj/machinery/door/firedoor/glass, +/obj/structure/window/reinforced/polarized/full{ + id = "recovery_ward" + }, /obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "resleeving-tint" + id = "recovery_ward" }, /turf/simulated/floor/plating, -/area/medical/resleeving) +/area/medical/ward) "Jh" = ( /obj/effect/floor_decal/borderfloorwhite{ dir = 9 @@ -21789,15 +22578,13 @@ /turf/simulated/wall, /area/quartermaster/warehouse) "JM" = ( -/obj/structure/table/standard, -/obj/item/weapon/hand_labeler, -/obj/item/weapon/stamp{ - pixel_x = -3; - pixel_y = 3 +/obj/machinery/alarm{ + dir = 1; + icon_state = "alarm0"; + pixel_y = -22 }, -/obj/item/weapon/hand_labeler, /turf/simulated/floor/tiled, -/area/quartermaster/storage) +/area/security/hallway) "JN" = ( /obj/structure/table/standard, /obj/machinery/cell_charger, @@ -21875,50 +22662,20 @@ /turf/simulated/floor/tiled/white, /area/medical/resleeving) "JW" = ( -/obj/machinery/atmospherics/pipe/simple/hidden{ - dir = 4 +/obj/machinery/light{ + dir = 4; + icon_state = "tube1" }, -/obj/effect/floor_decal/borderfloorwhite{ - dir = 4 - }, -/obj/effect/floor_decal/corner/paleblue/border{ - dir = 4 - }, -/obj/effect/floor_decal/borderfloorwhite/corner2{ - dir = 5 - }, -/obj/effect/floor_decal/corner/paleblue/bordercorner2{ - dir = 5 - }, -/obj/machinery/button/windowtint{ - dir = 8; - id = "resleeving-tint"; - pixel_x = 28; - pixel_y = 8 - }, -/obj/machinery/button/remote/airlock{ - desc = "A remote control switch for the medbay recovery room door."; - dir = 8; - id = "MedicalResleeving"; - name = "Exit Button"; - pixel_x = 28; - pixel_y = -4 - }, -/turf/simulated/floor/tiled/white, -/area/medical/resleeving) +/turf/space, +/area/security/nuke_storage) "JX" = ( -/obj/structure/grille, -/obj/machinery/atmospherics/pipe/simple/hidden{ - dir = 4 +/obj/machinery/light{ + dir = 8; + icon_state = "tube1"; + pixel_y = 0 }, -/obj/machinery/door/firedoor/glass, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "resleeving-tint" - }, -/turf/simulated/floor/plating, -/area/medical/resleeving) +/turf/simulated/mineral/floor/vacuum, +/area/security/nuke_storage) "JY" = ( /obj/effect/floor_decal/industrial/warning/corner{ dir = 4 @@ -21947,15 +22704,6 @@ /obj/machinery/atmospherics/pipe/manifold/hidden, /turf/simulated/floor/tiled/white, /area/medical/sleeper) -"Ka" = ( -/obj/effect/floor_decal/industrial/warning/corner{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/simple/hidden{ - dir = 4 - }, -/turf/simulated/floor/tiled/white, -/area/medical/sleeper) "Kb" = ( /obj/machinery/atmospherics/pipe/simple/hidden{ dir = 4 @@ -22130,16 +22878,12 @@ /turf/simulated/floor/tiled/white, /area/medical/surgery) "Kq" = ( -/obj/structure/table/standard, -/obj/effect/floor_decal/borderfloorwhite, -/obj/effect/floor_decal/corner/white/border, -/obj/machinery/button/windowtint{ - id = "surgeryobs"; - pixel_y = -26 +/obj/machinery/camera/network/security{ + c_tag = "SEC - Vault Exterior West"; + dir = 8 }, -/obj/item/stack/nanopaste, -/turf/simulated/floor/tiled/white, -/area/medical/surgery) +/turf/space, +/area/security/nuke_storage) "Kr" = ( /obj/structure/table/standard, /obj/item/weapon/storage/firstaid/surgery, @@ -22298,26 +23042,6 @@ }, /turf/simulated/floor/tiled/white, /area/medical/resleeving) -"KD" = ( -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 6 - }, -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 1 - }, -/turf/simulated/floor/tiled/white, -/area/medical/sleeper) "KE" = ( /obj/structure/cable/green{ d1 = 2; @@ -22695,23 +23419,6 @@ }, /turf/simulated/floor/tiled/white, /area/medical/sleeper) -"Lo" = ( -/obj/structure/table/glass, -/obj/effect/floor_decal/borderfloorwhite{ - dir = 4 - }, -/obj/effect/floor_decal/corner/paleblue/border{ - dir = 4 - }, -/obj/effect/floor_decal/borderfloorwhite/corner2{ - dir = 6 - }, -/obj/effect/floor_decal/corner/paleblue/bordercorner2{ - dir = 6 - }, -/obj/item/device/defib_kit/loaded, -/turf/simulated/floor/tiled/white, -/area/space) "Lp" = ( /obj/structure/grille, /obj/structure/window/reinforced/full, @@ -22801,16 +23508,6 @@ }, /turf/simulated/floor/tiled/white, /area/medical/surgery_hallway) -"Lw" = ( -/obj/structure/grille, -/obj/machinery/door/firedoor/glass, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "surgeryobs2" - }, -/turf/simulated/floor/plating, -/area/medical/surgery2) "Lx" = ( /obj/effect/floor_decal/borderfloorwhite{ dir = 9 @@ -23572,16 +24269,6 @@ }, /turf/simulated/floor/tiled/white, /area/crew_quarters/heads/cmo) -"ME" = ( -/obj/structure/grille, -/obj/machinery/door/firedoor/glass, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "cmooffice" - }, -/turf/simulated/floor/plating, -/area/crew_quarters/heads/cmo) "MF" = ( /obj/effect/floor_decal/borderfloorwhite{ dir = 8 @@ -23716,43 +24403,6 @@ }, /turf/simulated/floor/tiled/white, /area/crew_quarters/heads/cmo) -"MO" = ( -/obj/structure/bed/chair/office/light{ - dir = 4 - }, -/obj/effect/landmark/start{ - name = "Chief Medical Officer" - }, -/obj/machinery/button/remote/airlock{ - desc = "A remote control switch for the CMO's office."; - id = "cmodoor"; - name = "CMO Office Door Control"; - pixel_x = -8; - pixel_y = -36 - }, -/obj/machinery/button/remote/blast_door{ - desc = "A remote control-switch for shutters."; - id = "virologyquar"; - name = "Virology Emergency Lockdown Control"; - pixel_x = 0; - pixel_y = -28; - req_access = list(5) - }, -/obj/machinery/button/remote/blast_door{ - desc = "A remote control-switch for shutters."; - id = "medbayquar"; - name = "Medbay Emergency Lockdown Control"; - pixel_x = 0; - pixel_y = -36; - req_access = list(5) - }, -/obj/machinery/button/windowtint{ - id = "cmooffice"; - pixel_x = -6; - pixel_y = -28 - }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/heads/cmo) "MP" = ( /obj/structure/table/glass, /obj/item/weapon/paper_bin, @@ -24233,16 +24883,6 @@ }, /turf/simulated/floor/tiled/white, /area/medical/surgery2) -"Nr" = ( -/obj/structure/table/standard, -/obj/effect/floor_decal/borderfloorwhite, -/obj/effect/floor_decal/corner/white/border, -/obj/machinery/button/windowtint{ - id = "surgeryobs2"; - pixel_y = -26 - }, -/turf/simulated/floor/tiled/white, -/area/medical/surgery2) "Ns" = ( /obj/structure/table/standard, /obj/effect/floor_decal/borderfloorwhite, @@ -24284,19 +24924,6 @@ /obj/random/junk, /turf/simulated/floor, /area/maintenance/station/medbay) -"Nw" = ( -/obj/structure/grille, -/obj/structure/window/reinforced{ - dir = 8 - }, -/obj/machinery/door/firedoor/glass, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "cmooffice_b" - }, -/turf/simulated/floor/plating, -/area/crew_quarters/heads/cmo) "Nx" = ( /obj/effect/floor_decal/borderfloorwhite{ dir = 8 @@ -24324,7 +24951,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/mob/living/simple_animal/cat/fluff/Runtime, +/mob/living/simple_mob/animal/passive/cat/runtime, /turf/simulated/floor/tiled/white, /area/crew_quarters/heads/cmo) "NB" = ( @@ -24452,20 +25079,6 @@ /obj/effect/decal/cleanable/dirt, /turf/simulated/floor, /area/maintenance/station/medbay) -"NO" = ( -/obj/effect/floor_decal/borderfloorwhite{ - dir = 10 - }, -/obj/effect/floor_decal/corner/paleblue/border{ - dir = 10 - }, -/obj/machinery/button/windowtint{ - id = "cmooffice_b"; - pixel_x = -20; - pixel_y = -25 - }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/heads/cmo) "NP" = ( /obj/effect/floor_decal/borderfloorwhite, /obj/effect/floor_decal/corner/paleblue/border, @@ -24857,31 +25470,10 @@ }, /turf/simulated/floor/tiled/white, /area/medical/surgery_hallway) -"Ov" = ( -/obj/structure/grille, -/obj/structure/window/reinforced, -/obj/machinery/door/firedoor/glass, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "cmooffice_b" - }, -/turf/simulated/floor/plating, -/area/crew_quarters/heads/cmo) "Ow" = ( /obj/structure/sign/nosmoking_1, /turf/simulated/wall, /area/medical/sleeper) -"Ox" = ( -/obj/structure/grille, -/obj/machinery/door/firedoor/glass, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "mrecovery-tint" - }, -/turf/simulated/floor/plating, -/area/medical/sleeper) "Oy" = ( /obj/structure/cable/green{ d1 = 1; @@ -24908,16 +25500,6 @@ }, /turf/simulated/floor/tiled/white, /area/medical/sleeper) -"Oz" = ( -/obj/machinery/door/firedoor/glass, -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "exam_room" - }, -/turf/simulated/floor, -/area/medical/sleeper) "OA" = ( /obj/structure/cable/green{ d1 = 1; @@ -25325,33 +25907,6 @@ /obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled/white, /area/medical/ward) -"OX" = ( -/obj/effect/floor_decal/borderfloorwhite{ - dir = 1 - }, -/obj/effect/floor_decal/corner/paleblue/border{ - dir = 1 - }, -/obj/effect/floor_decal/borderfloorwhite/corner2{ - dir = 4 - }, -/obj/effect/floor_decal/corner/paleblue/bordercorner2{ - dir = 4 - }, -/obj/machinery/button/remote/airlock{ - desc = "A remote control switch for the medbay recovery room door."; - id = "MedicalRecovery"; - name = "Exit Button"; - pixel_x = -4; - pixel_y = 26 - }, -/obj/machinery/button/windowtint{ - id = "mrecovery-tint"; - pixel_x = 6; - pixel_y = 26 - }, -/turf/simulated/floor/tiled/white, -/area/medical/ward) "OY" = ( /obj/structure/bed/padded, /obj/item/weapon/bedsheet/medical, @@ -25435,42 +25990,9 @@ /obj/item/weapon/cane, /turf/simulated/floor/tiled/white, /area/medical/exam_room) -"Pc" = ( -/obj/structure/table/glass, -/obj/item/weapon/paper_bin, -/obj/item/weapon/clipboard, -/obj/item/weapon/pen, -/obj/machinery/camera/network/medbay{ - dir = 8 - }, -/obj/machinery/firealarm{ - dir = 4; - pixel_x = 24 - }, -/obj/effect/floor_decal/borderfloorwhite{ - dir = 5 - }, -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 8 - }, -/obj/effect/floor_decal/corner/pink/border{ - dir = 5 - }, -/turf/simulated/floor/tiled/white, -/area/medical/exam_room) "Pd" = ( /turf/simulated/wall, /area/medical/patient_a) -"Pe" = ( -/obj/machinery/door/firedoor/glass, -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "pr1_window_tint" - }, -/turf/simulated/floor, -/area/medical/patient_a) "Pf" = ( /obj/structure/cable/green{ d1 = 1; @@ -25499,16 +26021,6 @@ "Pg" = ( /turf/simulated/wall, /area/medical/patient_b) -"Ph" = ( -/obj/machinery/door/firedoor/glass, -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "pr2_window_tint" - }, -/turf/simulated/floor, -/area/medical/patient_b) "Pi" = ( /obj/structure/cable/green{ d1 = 1; @@ -25537,16 +26049,6 @@ "Pj" = ( /turf/simulated/wall, /area/medical/patient_c) -"Pk" = ( -/obj/machinery/door/firedoor/glass, -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "pr3_window_tint" - }, -/turf/simulated/floor, -/area/medical/patient_c) "Pl" = ( /obj/structure/cable/green{ d1 = 1; @@ -25781,37 +26283,6 @@ }, /turf/simulated/floor/tiled/white, /area/medical/patient_a) -"PC" = ( -/obj/structure/bed/chair{ - dir = 8 - }, -/obj/effect/floor_decal/borderfloorwhite{ - dir = 5 - }, -/obj/effect/floor_decal/corner/pink/border{ - dir = 5 - }, -/obj/effect/floor_decal/borderfloorwhite/corner2{ - dir = 4 - }, -/obj/effect/floor_decal/corner/pink/bordercorner2{ - dir = 4 - }, -/obj/machinery/light_switch{ - dir = 2; - name = "light switch "; - pixel_x = 0; - pixel_y = 36 - }, -/obj/machinery/button/windowtint{ - id = "pr1_window_tint"; - pixel_y = 26 - }, -/obj/machinery/camera/network/medbay{ - dir = 8 - }, -/turf/simulated/floor/tiled/white, -/area/medical/patient_a) "PD" = ( /obj/structure/table/glass, /obj/machinery/computer/med_data/laptop, @@ -25854,37 +26325,6 @@ }, /turf/simulated/floor/tiled/white, /area/medical/patient_b) -"PF" = ( -/obj/structure/bed/chair{ - dir = 8 - }, -/obj/effect/floor_decal/borderfloorwhite{ - dir = 5 - }, -/obj/effect/floor_decal/corner/pink/border{ - dir = 5 - }, -/obj/effect/floor_decal/borderfloorwhite/corner2{ - dir = 4 - }, -/obj/effect/floor_decal/corner/pink/bordercorner2{ - dir = 4 - }, -/obj/machinery/button/windowtint{ - id = "pr2_window_tint"; - pixel_y = 26 - }, -/obj/machinery/light_switch{ - dir = 2; - name = "light switch "; - pixel_x = 0; - pixel_y = 36 - }, -/obj/machinery/camera/network/medbay{ - dir = 8 - }, -/turf/simulated/floor/tiled/white, -/area/medical/patient_b) "PG" = ( /obj/structure/table/glass, /obj/machinery/computer/med_data/laptop, @@ -25927,37 +26367,6 @@ }, /turf/simulated/floor/tiled/white, /area/medical/patient_c) -"PI" = ( -/obj/structure/bed/chair{ - dir = 8 - }, -/obj/effect/floor_decal/borderfloorwhite{ - dir = 5 - }, -/obj/effect/floor_decal/corner/pink/border{ - dir = 5 - }, -/obj/effect/floor_decal/borderfloorwhite/corner2{ - dir = 4 - }, -/obj/effect/floor_decal/corner/pink/bordercorner2{ - dir = 4 - }, -/obj/machinery/button/windowtint{ - id = "pr3_window_tint"; - pixel_y = 26 - }, -/obj/machinery/light_switch{ - dir = 2; - name = "light switch "; - pixel_x = 0; - pixel_y = 36 - }, -/obj/machinery/camera/network/medbay{ - dir = 8 - }, -/turf/simulated/floor/tiled/white, -/area/medical/patient_c) "PJ" = ( /obj/machinery/door/firedoor/glass, /obj/machinery/door/airlock/medical{ @@ -26589,50 +26998,6 @@ }, /turf/simulated/floor/tiled/white, /area/medical/ward) -"QI" = ( -/obj/structure/grille, -/obj/structure/window/reinforced, -/obj/machinery/door/firedoor/glass, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "exam_room" - }, -/turf/simulated/floor/plating, -/area/medical/exam_room) -"QJ" = ( -/obj/structure/grille, -/obj/structure/window/reinforced, -/obj/machinery/door/firedoor/glass, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "pr1_window_tint" - }, -/turf/simulated/floor/plating, -/area/medical/patient_a) -"QK" = ( -/obj/structure/grille, -/obj/structure/window/reinforced, -/obj/machinery/door/firedoor/glass, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "pr2_window_tint" - }, -/turf/simulated/floor/plating, -/area/medical/patient_b) -"QL" = ( -/obj/structure/grille, -/obj/structure/window/reinforced, -/obj/machinery/door/firedoor/glass, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "pr3_window_tint" - }, -/turf/simulated/floor/plating, -/area/medical/patient_c) "QM" = ( /obj/structure/grille, /obj/structure/window/reinforced/full, @@ -26704,17 +27069,6 @@ }, /turf/simulated/floor/tiled/white, /area/medical/ward) -"QS" = ( -/obj/structure/grille, -/obj/machinery/door/firedoor/glass, -/obj/structure/window/reinforced, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "mrecovery-tint" - }, -/turf/simulated/floor/plating, -/area/medical/ward) "QT" = ( /obj/effect/landmark/map_data/virgo3b, /turf/space, @@ -26969,18 +27323,6 @@ }, /turf/simulated/floor/tiled/dark, /area/security/warden) -"RN" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/railing{ - dir = 4 - }, -/obj/random/trash_pile, -/turf/simulated/floor, -/area/maintenance/cargo) -"RT" = ( -/obj/structure/toilet, -/turf/simulated/floor/tiled/white, -/area/security/security_bathroom) "Sa" = ( /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ @@ -27038,33 +27380,6 @@ }, /turf/simulated/floor/tiled/white, /area/security/security_bathroom) -"Tb" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "hos_office" - }, -/obj/structure/cable/green, -/obj/structure/cable/green{ - icon_state = "0-8" - }, -/obj/machinery/door/firedoor/glass, -/obj/structure/cable/green{ - icon_state = "0-4" - }, -/turf/simulated/floor, -/area/security/forensics) -"Tc" = ( -/obj/structure/railing{ - icon_state = "railing0"; - dir = 1 - }, -/obj/structure/railing{ - dir = 4 - }, -/turf/simulated/floor, -/area/maintenance/cargo) "Td" = ( /obj/structure/cable/green{ d1 = 1; @@ -27238,20 +27553,6 @@ }, /turf/simulated/floor/wood, /area/crew_quarters/heads/hos) -"UA" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "hos_office" - }, -/obj/structure/cable/green{ - d2 = 4; - icon_state = "0-4" - }, -/obj/machinery/door/firedoor/glass, -/turf/simulated/floor, -/area/security/forensics) "UC" = ( /obj/effect/floor_decal/borderfloor{ dir = 8 @@ -27265,63 +27566,6 @@ }, /turf/simulated/floor/tiled, /area/security/hallwayaux) -"UH" = ( -/obj/machinery/door/firedoor/glass, -/obj/structure/cable/green{ - d2 = 4; - icon_state = "0-4" - }, -/obj/structure/cable/green{ - d2 = 2; - icon_state = "0-2" - }, -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "hos_office" - }, -/obj/machinery/door/blast/regular{ - density = 0; - dir = 1; - icon_state = "pdoor0"; - id = "security_lockdown"; - name = "Security Blast Doors"; - opacity = 0 - }, -/obj/structure/window/reinforced{ - dir = 8 - }, -/turf/simulated/floor, -/area/crew_quarters/heads/hos) -"UM" = ( -/turf/simulated/wall/r_wall, -/area/maintenance/cargo) -"UO" = ( -/obj/machinery/door/firedoor/glass, -/obj/structure/cable/green, -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "hos_office" - }, -/obj/structure/cable/green{ - icon_state = "0-4" - }, -/obj/machinery/door/blast/regular{ - density = 0; - dir = 1; - icon_state = "pdoor0"; - id = "security_lockdown"; - name = "Security Blast Doors"; - opacity = 0 - }, -/obj/structure/window/reinforced{ - dir = 8 - }, -/turf/simulated/floor, -/area/crew_quarters/heads/hos) "US" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 9 @@ -27354,28 +27598,6 @@ }, /turf/simulated/floor/tiled, /area/security/security_bathroom) -"Vb" = ( -/obj/machinery/door/firedoor/glass, -/obj/structure/cable/green, -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "hos_office" - }, -/obj/machinery/door/blast/regular{ - density = 0; - dir = 1; - icon_state = "pdoor0"; - id = "security_lockdown"; - name = "Security Blast Doors"; - opacity = 0 - }, -/obj/structure/window/reinforced{ - dir = 8 - }, -/turf/simulated/floor, -/area/crew_quarters/heads/hos) "Ve" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 @@ -27387,20 +27609,6 @@ }, /turf/simulated/floor/carpet, /area/crew_quarters/heads/hos) -"Vk" = ( -/obj/effect/floor_decal/rust, -/obj/structure/railing{ - dir = 4 - }, -/obj/structure/table/rack{ - dir = 8; - layer = 2.9 - }, -/obj/random/maintenance/security, -/obj/random/maintenance/security, -/obj/random/maintenance/clean, -/turf/simulated/floor, -/area/maintenance/cargo) "Vn" = ( /obj/structure/bed/chair/office/dark{ dir = 4 @@ -27432,10 +27640,6 @@ }, /turf/simulated/floor/bluegrid, /area/ai/foyer) -"VB" = ( -/obj/machinery/washing_machine, -/turf/simulated/floor/tiled/white, -/area/security/security_bathroom) "VJ" = ( /obj/structure/cable/green{ d2 = 2; @@ -27478,32 +27682,6 @@ }, /turf/simulated/floor/bluegrid, /area/ai/foyer) -"Wc" = ( -/obj/machinery/door/airlock/engineering{ - name = "Security Substation"; - req_one_access = list(1,11,24) - }, -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8"; - pixel_x = 0 - }, -/turf/space, -/area/maintenance/substation/security) -"Wj" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/polarized{ - dir = 10; - icon_state = "fwindow"; - id = "hos_office" - }, -/obj/structure/cable/green{ - icon_state = "0-8" - }, -/obj/machinery/door/firedoor/glass, -/turf/simulated/floor, -/area/security/forensics) "WB" = ( /obj/machinery/atmospherics/unary/vent_scrubber/on{ dir = 8 @@ -27548,11 +27726,6 @@ }, /turf/simulated/floor/bluegrid, /area/ai/foyer) -"XP" = ( -/obj/effect/floor_decal/rust, -/obj/structure/catwalk, -/turf/simulated/floor, -/area/maintenance/cargo) "XT" = ( /obj/effect/floor_decal/borderfloor{ dir = 1 @@ -27612,7 +27785,6 @@ "YV" = ( /obj/machinery/computer/secure_data, /obj/machinery/alarm{ - frequency = 1441; pixel_y = 22 }, /turf/simulated/floor/wood, @@ -27624,24 +27796,6 @@ }, /turf/space, /area/space) -"Ze" = ( -/obj/machinery/door/airlock/security{ - name = "Security Restroom"; - req_one_access = list(1,38) - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/turf/simulated/floor/tiled/white, -/area/security/security_bathroom) "ZM" = ( /obj/structure/table/woodentable, /obj/item/device/radio/off, @@ -27651,20 +27805,6 @@ /obj/machinery/atmospherics/unary/vent_scrubber/on, /turf/simulated/floor/tiled, /area/security/eva) -"ZP" = ( -/obj/structure/cable{ - icon_state = "2-8" - }, -/obj/structure/catwalk, -/turf/simulated/floor, -/area/maintenance/station/sec_upper) -"ZT" = ( -/obj/structure/railing{ - dir = 4 - }, -/obj/random/trash_pile, -/turf/simulated/floor, -/area/maintenance/cargo) "ZY" = ( /turf/simulated/wall/r_wall, /area/security/security_lockerroom) @@ -31555,13 +31695,13 @@ aa ab ab je -UH -UO +lj +lu je je je -UH -Vb +lj +lZ qc qv rd @@ -31576,7 +31716,7 @@ aa aa ae aa -AZ +Kq aa ae aa @@ -31704,7 +31844,7 @@ nW TO oW ZM -UA +mb qw re sa @@ -31714,7 +31854,7 @@ uG vs ae aa -xu +JW xv xw xw @@ -31722,7 +31862,7 @@ xw xw xw xv -xu +JW aa ae aa @@ -31846,7 +31986,7 @@ nX nX oX Sc -Tb +mE qx rf sb @@ -31988,7 +32128,7 @@ Rq jM kv SP -Wj +mF qy rg sc @@ -32139,7 +32279,7 @@ tJ qc vs vt -wL +xx xw xw zf @@ -32149,7 +32289,7 @@ BW CU xw xw -vt +wL vt vt vt @@ -32272,7 +32412,7 @@ eH ow Un cZ -UA +mb qz ri sd @@ -32414,7 +32554,7 @@ jM jM pa Sz -Tb +mE qA rj se @@ -32556,7 +32696,7 @@ oa ox ff pC -Wj +mF qB rk sf @@ -32697,7 +32837,7 @@ ZY ZY ZY av -pD +ma qd qC rl @@ -32708,15 +32848,15 @@ qc vt vt vt -xx +JX xw zj xw -Bf +dG xw zj xw -xx +JX vt ab ab @@ -32957,7 +33097,7 @@ ab ab ao ao -he +dN hB hT ih @@ -33132,9 +33272,9 @@ sT tP uJ vu -tc -tc -tc +nn +nn +nn vu uO zX @@ -33278,7 +33418,7 @@ wg wg xy yi -wf +og zY Bj Ca @@ -33420,7 +33560,7 @@ wh wh xz yj -wf +og zZ Bk BC @@ -33440,8 +33580,8 @@ Ix Me Me Me -Nw -Nw +uK +uK Me aa aa @@ -33562,7 +33702,7 @@ wh wM xA yk -wf +og Aa Bl Ca @@ -33583,8 +33723,8 @@ Me My MN Nx -NO -Ov +wf +xh aa aa aa @@ -33703,7 +33843,7 @@ vy wh wh xB -yl +nZ uO Ab Bm @@ -33723,10 +33863,10 @@ La LG Me Mz -MO +tc Ny NP -Ov +xh aa aa aa @@ -33827,8 +33967,8 @@ fD ga lz mi -mE -nm +dX +ew lz lz lz @@ -33840,7 +33980,7 @@ rr sm sV tS -uK +mI vz wh Cu @@ -33868,7 +34008,7 @@ MA MP Nz NP -Ov +xh aa aa aa @@ -33969,8 +34109,8 @@ QW lb lA mj -mF -nn +eo +eE nN nN fe @@ -33982,7 +34122,7 @@ rs lA DO tT -uL +mJ vA wh wh @@ -34130,7 +34270,7 @@ wh wM xE yk -wf +og Ae Bo Ca @@ -34266,13 +34406,13 @@ rt oz sY tV -uN +nm vC wh wh xF yo -wf +og Af Bp Cg @@ -34285,7 +34425,7 @@ Df Df Ix Jf -JW +pD KB Ld LK @@ -34387,7 +34527,7 @@ cr cR jx cR -iT +mS eD kN kE @@ -34398,7 +34538,7 @@ lC lC lC nO -nN +JM oz fo pK @@ -34414,7 +34554,7 @@ wi wN xG yp -wf +og Aa Bq Ch @@ -34426,15 +34566,15 @@ Gk Gk Gk Ix -Jg -JX +pB +pN KC -Jg -Jg +pB +pB Me -ME +rC MT -ME +rC Me Me ab @@ -34570,7 +34710,7 @@ Gk Iy Jh JY -KD +ng Le LL Mf @@ -34652,8 +34792,8 @@ ad aa aa Rg -ae -ae +cv +cv cv cv ai @@ -34824,14 +34964,14 @@ cV jk jk jk -og +lv oB pl pM qh fK rv -qQ +lw qP tX uR @@ -34850,7 +34990,7 @@ EG Fv Gl GU -HM +nf Iy Ji JZ @@ -34966,14 +35106,14 @@ jk jk jk jk -og +lv oC pm Rs qi qN rw -qQ +lw pg tY uS @@ -34995,7 +35135,7 @@ GV HN Iy Jj -Ka +mX KG Lh Lh @@ -35115,7 +35255,7 @@ DP nu qN rx -qQ +lw td pG mH @@ -35130,7 +35270,7 @@ Bt Cc Dk EI -Gn +nc Fx GS GW @@ -35250,7 +35390,7 @@ cS jk jk jk -qQ +lw oE po pO @@ -35392,14 +35532,14 @@ cT jy jk jk -qQ +lw oF pp pP qi mz ry -qQ +lw tZ ua uU @@ -35515,7 +35655,7 @@ gk gR aw aE -hX +dQ bf ci bO @@ -35535,12 +35675,12 @@ mH lD lD of -qQ -qQ -qQ +lw +lw +lw qk -qQ -qQ +lw +lw oA tg ub @@ -35572,7 +35712,7 @@ LO Nb LO NW -Ox +yl OU Pr PL @@ -35580,7 +35720,7 @@ Qk QH QN QP -QS +Jg vt aa aa @@ -35714,7 +35854,7 @@ LP Nc NF NZ -Ox +yl OV Ps PM @@ -35722,7 +35862,7 @@ Ql Pu Pu QQ -QS +Jg vt vt aa @@ -35864,7 +36004,7 @@ Qm Pu Pu QQ -QS +Jg vt vt aa @@ -35946,13 +36086,13 @@ in bt iR YT -cq -cq -cq -jV -cq -cq -cq +cw +cw +cw +de +cw +cw +cw dR le eX @@ -35991,22 +36131,22 @@ IC Jq Kf KL -Lo +xu LR Mj MG Ne KI Ob -Ox -OX +yl +yT Pu PO Qn Pu Pu QQ -QS +Jg vt vt vt @@ -36140,7 +36280,7 @@ Jr Nf KI Oc -Ox +yl OY Pv PP @@ -36148,7 +36288,7 @@ Qo PP QO QR -QS +Jg vt vt vt @@ -36250,7 +36390,7 @@ eX lC lC mH -rC +dx so tk uf @@ -36424,12 +36564,12 @@ Lp Nh KI Od -Oz +tt OZ Pw PQ Qp -QI +uN vt vt vt @@ -36571,7 +36711,7 @@ Pa Px PR Qq -QI +uN vt vt vt @@ -36708,12 +36848,12 @@ Lp Nj KI Of -Oz +tt Pb Py PS Qr -QI +uN vt vt vt @@ -36851,11 +36991,11 @@ Nk NI Og Ow -Pc +oh Pz PT Qs -QI +uN vt vt vt @@ -36944,7 +37084,7 @@ dP dP dP dP -Ze +dq dP dP dP @@ -37082,7 +37222,7 @@ bz bw cl dS -RT +dd SX ST VJ @@ -37135,11 +37275,11 @@ Nm NK Oi OB -Pe +AA PA PU Qt -QJ +Gn vt vt vt @@ -37281,7 +37421,7 @@ Pf PB PV Qu -QJ +Gn vt vt vt @@ -37366,11 +37506,11 @@ bB by cz dS -dd +mW SX TX WB -VB +uL Uw UV fG @@ -37381,7 +37521,7 @@ fc fc dw dw -dw +dr mR fc dw @@ -37419,11 +37559,11 @@ No Kn Ok OD -Pe -PC +AA +Cy PW Qv -QJ +Gn vt vt vt @@ -37506,16 +37646,16 @@ hQ bm bm bm -Wc +cn +af +af +af af af af af af af -UM -UM -UM af lL aI @@ -37540,24 +37680,24 @@ xP yG zA Av -BB -Ck +hX +hZ zD -AA +oq EX -AA +oq zD -Hk -Hk +oY +oY II -Hk -Hk +oY +oY KU -Lw -Lw +qQ +qQ Mq -Lw -Lw +qQ +qQ KV Ol OE @@ -37645,7 +37785,7 @@ bc gZ ha hw -hZ +an dw fc dA @@ -37655,13 +37795,13 @@ jq qU qU aI -Vk -RN -ZT +kt +ku +kJ +aI +mR +kV aI -XP -Tc -iV aI aI aI @@ -37683,8 +37823,8 @@ yH zB Ay xX -Ck -AA +jm +oq Ec EY FN @@ -37703,11 +37843,11 @@ Np KV Om OF -Ph +Bf PD PX Qw -QK +Hk vt vt vt @@ -37788,23 +37928,23 @@ bc hb hb bc -pS +cq eW -pN -ZP +kg +ks Tp dy dw dw eI -nx -nx -nx -nx -nx -nx -Tc -iV +fc +fc +fc +fc +fc +fc +kX +aI ab ab ab @@ -37826,7 +37966,7 @@ zC Az BD Cv -AA +oq Ed EZ Ef @@ -37849,7 +37989,7 @@ Pi PE PY Qx -QK +Hk vt vt vt @@ -37939,14 +38079,14 @@ dB aI aI aI -iV -iV -iV -iV -iV -nx -nx -iV +aI +aI +aI +aI +aI +fc +fc +aI ab ab ab @@ -37965,10 +38105,10 @@ xb xR yJ zD -AA +oq BE -AA -AA +oq +oq Ee EZ FO @@ -37977,21 +38117,21 @@ Hn Ig IL JC -Kq +pS KV Lz Ma Mt Ma -Nr +tC KV Oo OH -Ph -PF +Bf +Cz PZ Qy -QK +Hk vt vt vt @@ -38225,7 +38365,7 @@ ab ab ab ab -ab +iV iV iV mU @@ -38271,11 +38411,11 @@ Nt KV Oq OF -Pk +BB PG Qa Qz -QL +HM vt vt vt @@ -38417,7 +38557,7 @@ Pl PH Qb QA -QL +HM vt vt vt @@ -38555,11 +38695,11 @@ Mw Mw Os OJ -Pk -PI +BB +Ej Qc QB -QL +HM vt vt vt @@ -38643,7 +38783,7 @@ gK gK gJ iV -cB +cs iV bY bY @@ -38679,7 +38819,7 @@ AF BG Cx Du -Ej +ou Ef FT zD @@ -38808,7 +38948,7 @@ qp qX rH st -tt +eL up vc vS @@ -38965,7 +39105,7 @@ BH BH Ek Fe -Fe +jV Fe Hr Hr @@ -39103,7 +39243,7 @@ yQ zF AH AH -Cy +jJ AH El Ff @@ -39213,9 +39353,9 @@ gJ bY cF dj -dG -dX -ew +cB +db +df eO fg bY @@ -39239,13 +39379,13 @@ ur ve vU wA -xh +fa xR yQ zG AH BI -Cz +jO AH El Fg @@ -39498,7 +39638,7 @@ bY cH dk dH -dZ +iK dk eQ fi @@ -40091,9 +40231,9 @@ uw uw uw qr -xm -ya -yT +he +ht +hO zL AK BN @@ -40674,7 +40814,7 @@ GK HA Ir IU -JM +nh zO ab ab @@ -40771,7 +40911,7 @@ aa aa aa bX -iK +dZ iX ib ib @@ -41080,7 +41220,7 @@ qu qu rV sH -tC +nb uC vo wb diff --git a/maps/tether/tether-08-mining.dmm b/maps/tether/tether-08-mining.dmm index 0957a86181..b7a834ae54 100644 --- a/maps/tether/tether-08-mining.dmm +++ b/maps/tether/tether-08-mining.dmm @@ -112,6 +112,13 @@ }, /turf/simulated/floor/tiled/steel_dirty/virgo3b, /area/outpost/mining_main/storage) +"av" = ( +/obj/structure/cable/ender{ + icon_state = "1-2"; + id = "surface-mining" + }, +/turf/simulated/floor/plating, +/area/mine/explored) "aw" = ( /obj/machinery/light/small, /turf/simulated/floor/tiled/steel_dirty/virgo3b, @@ -395,6 +402,9 @@ /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 8 }, +/obj/machinery/camera/network/mining{ + dir = 1 + }, /obj/structure/closet/hydrant{ pixel_y = -32 }, @@ -428,7 +438,7 @@ /turf/simulated/floor/tiled/steel_dirty/virgo3b, /area/outpost/mining_main/passage) "cu" = ( -/mob/living/simple_animal/retaliate/gaslamp, +/mob/living/simple_mob/animal/space/gaslamp, /turf/simulated/floor/outdoors/grass/sif/virgo3b, /area/mine/explored) "cv" = ( @@ -590,7 +600,7 @@ pressure_checks_default = 2; use_power = 1 }, -/turf/simulated/floor/tiled/steel_dirty/virgo3b, +/turf/simulated/floor/plating, /area/outpost/mining_main/maintenance) "mH" = ( /obj/machinery/atmospherics/pipe/simple/visible/cyan{ @@ -982,13 +992,6 @@ /obj/structure/window/reinforced, /turf/simulated/floor/plating, /area/outpost/mining_main/maintenance) -"FG" = ( -/obj/structure/cable/ender{ - icon_state = "1-2"; - id = "surface-solars" - }, -/turf/simulated/floor/plating, -/area/mine/explored) "FV" = ( /obj/structure/cable/heavyduty{ icon_state = "2-8" @@ -1136,6 +1139,11 @@ /obj/effect/floor_decal/techfloor, /turf/simulated/floor/tiled/techfloor, /area/outpost/mining_main/maintenance) +"KL" = ( +/obj/machinery/telecomms/relay/preset/underdark, +/obj/effect/floor_decal/techfloor, +/turf/simulated/floor/tiled/techfloor, +/area/outpost/mining_main/maintenance) "Ma" = ( /obj/machinery/door/airlock/mining{ name = "Quarters" @@ -1257,6 +1265,7 @@ /turf/simulated/floor/outdoors/grass/sif/virgo3b, /area/mine/explored) "TC" = ( +/obj/machinery/camera/network/mining, /obj/machinery/atmospherics/pipe/simple/visible/cyan{ dir = 10 }, @@ -4158,7 +4167,7 @@ Kj Zg RB MV -KJ +KL SF ab Il @@ -11555,7 +11564,7 @@ jh jh lb KF -FG +av aa "} (72,1,1) = {" diff --git a/maps/tether/tether-09-solars.dmm b/maps/tether/tether-09-solars.dmm index 913fc4b196..e28c506486 100644 --- a/maps/tether/tether-09-solars.dmm +++ b/maps/tether/tether-09-solars.dmm @@ -202,7 +202,7 @@ /turf/simulated/floor/virgo3b_indoors, /area/tether/outpost/solars_shed) "aw" = ( -/mob/living/simple_animal/retaliate/gaslamp, +/mob/living/simple_mob/animal/space/gaslamp, /turf/simulated/floor/outdoors/grass/sif/virgo3b, /area/tether/outpost/solars_outside) "ax" = ( @@ -800,7 +800,7 @@ /turf/simulated/mineral/virgo3b, /area/tether/outpost/solars_outside) "bH" = ( -/mob/living/simple_animal/retaliate/gaslamp, +/mob/living/simple_mob/animal/space/gaslamp, /turf/simulated/floor/tiled/steel_dirty/virgo3b, /area/tether/outpost/solars_outside) "bI" = ( @@ -817,7 +817,7 @@ /turf/simulated/floor/virgo3b, /area/tether/outpost/solars_outside) "bJ" = ( -/mob/living/simple_animal/retaliate/gaslamp, +/mob/living/simple_mob/animal/space/gaslamp, /turf/simulated/floor/outdoors/dirt/virgo3b, /area/tether/outpost/solars_outside) "bK" = ( diff --git a/maps/tether/tether_areas.dm b/maps/tether/tether_areas.dm index 9684dc5c37..b463538874 100644 --- a/maps/tether/tether_areas.dm +++ b/maps/tether/tether_areas.dm @@ -27,6 +27,8 @@ forced_ambience = list('sound/music/elevator.ogg') dynamic_lighting = FALSE //Temporary fix for elevator lighting + requires_power = FALSE + /area/turbolift/tether/transit name = "tether (midway)" lift_floor_label = "Tether Midpoint" diff --git a/maps/tether/tether_areas2.dm b/maps/tether/tether_areas2.dm index f102bc216b..25f3f27fb0 100644 --- a/maps/tether/tether_areas2.dm +++ b/maps/tether/tether_areas2.dm @@ -499,6 +499,17 @@ /area/shuttle/excursion/virgo3b_sky name = "\improper Excursion Shuttle - Virgo3b Sky" base_turf = /turf/simulated/sky + +// Elevator area // + +/area/tether/elevator + name = "\improper Tether Elevator" + icon = 'icons/turf/areas_vr.dmi' + icon_state = "elevator" + dynamic_lighting = FALSE + + requires_power = FALSE + ////////////////////////////////// /area/antag/antag_base diff --git a/maps/tether/tether_defines.dm b/maps/tether/tether_defines.dm index e51d5223e4..82c258cc72 100644 --- a/maps/tether/tether_defines.dm +++ b/maps/tether/tether_defines.dm @@ -41,6 +41,13 @@ #define Z_LEVEL_AEROSTAT 17 #define Z_LEVEL_AEROSTAT_SURFACE 18 +//Camera networks +#define NETWORK_TETHER "Tether" +#define NETWORK_TCOMMS "Telecommunications" //Using different from Polaris one for better name +#define NETWORK_OUTSIDE "Outside" +#define NETWORK_EXPLORATION "Exploration" +#define NETWORK_XENOBIO "Xenobiology" + /datum/map/tether name = "Virgo" full_name = "NSB Adephagia" @@ -84,17 +91,17 @@ NETWORK_COMMAND, NETWORK_ENGINE, NETWORK_ENGINEERING, - NETWORK_ENGINEERING_OUTPOST, - NETWORK_DEFAULT, + NETWORK_EXPLORATION, + //NETWORK_DEFAULT, //Is this even used for anything? Robots show up here, but they show up in ROBOTS network too NETWORK_MEDICAL, NETWORK_MINE, - NETWORK_NORTHERN_STAR, + NETWORK_OUTSIDE, NETWORK_RESEARCH, NETWORK_RESEARCH_OUTPOST, NETWORK_ROBOTS, - NETWORK_PRISON, NETWORK_SECURITY, - NETWORK_INTERROGATION + NETWORK_TCOMMS, + NETWORK_TETHER ) allowed_spawns = list("Tram Station","Gateway","Cryogenic Storage","Cyborg Storage") @@ -106,6 +113,7 @@ unit_test_exempt_areas = list( /area/tether/surfacebase/outside/outside1, + /area/tether/elevator, /area/vacant/vacant_site, /area/vacant/vacant_site/east, /area/crew_quarters/sleep/Dorm_1/holo, @@ -254,7 +262,7 @@ if(activated && isemptylist(frozen_mobs)) return activated = 1 - for(var/mob/living/simple_animal/M in frozen_mobs) + for(var/mob/living/simple_mob/M in frozen_mobs) M.life_disabled = 0 frozen_mobs -= M frozen_mobs.Cut() diff --git a/maps/tether/tether_phoronlock.dm b/maps/tether/tether_phoronlock.dm index 8f86c9eedc..44f5fd04cb 100644 --- a/maps/tether/tether_phoronlock.dm +++ b/maps/tether/tether_phoronlock.dm @@ -50,7 +50,7 @@ obj/machinery/airlock_sensor/phoron/airlock_exterior var/frequency = 0 var/datum/radio_frequency/radio_connection -/obj/machinery/portable_atmospherics/powered/scrubber/huge/stationary/initialize() +/obj/machinery/portable_atmospherics/powered/scrubber/huge/stationary/Initialize() . = ..() if(frequency) set_frequency(frequency) @@ -97,7 +97,7 @@ obj/machinery/airlock_sensor/phoron/airlock_exterior /obj/machinery/embedded_controller/radio/airlock/phoron var/tag_scrubber -/obj/machinery/embedded_controller/radio/airlock/phoron/initialize() +/obj/machinery/embedded_controller/radio/airlock/phoron/Initialize() . = ..() program = new/datum/computer/file/embedded_program/airlock/phoron(src) @@ -116,7 +116,7 @@ obj/machinery/airlock_sensor/phoron/airlock_exterior "processing" = program.memory["processing"] ) - ui = GLOB.nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "phoron_airlock_console.tmpl", name, 470, 290) ui.set_initial_data(data) diff --git a/maps/tether/tether_telecomms.dm b/maps/tether/tether_telecomms.dm index 619b21a5d2..d60188b834 100644 --- a/maps/tether/tether_telecomms.dm +++ b/maps/tether/tether_telecomms.dm @@ -18,6 +18,12 @@ listening_level = Z_LEVEL_SURFACE_HIGH autolinkers = list("tbh_relay") +//Some coverage for midpoint +/obj/machinery/telecomms/relay/preset/tether/midpoint + id = "Midpoint Relay" + listening_level = Z_LEVEL_TRANSIT + autolinkers = list("tmp_relay") + // The station of course needs relays fluff-wise to connect to ground station. But again, no multi-z so, we need one for each z level. /obj/machinery/telecomms/relay/preset/tether/station_low id = "Station Relay 1" @@ -49,7 +55,7 @@ id = "Hub" network = "tcommsat" autolinkers = list("hub", - "tbl_relay", "tbm_relay", "tbh_relay", "tsl_relay", "tsm_relay", "tsh_relay", + "tbl_relay", "tbm_relay", "tbh_relay", "tmp_relay", "tsl_relay", "tsm_relay", "tsh_relay", "c_relay", "m_relay", "r_relay", "sci_o_relay", "ud_relay", "science", "medical", "supply", "service", "common", "command", "engineering", "security", "explorer", "unused", "hb_relay", "receiverA", "broadcasterA" @@ -119,6 +125,6 @@ name = "pre-linked multitool (tether hub)" desc = "This multitool has already been linked to the Tether telecomms hub and can be used to configure one (1) relay." -/obj/item/device/multitool/tether_buffered/initialize() +/obj/item/device/multitool/tether_buffered/Initialize() . = ..() buffer = locate(/obj/machinery/telecomms/hub/preset/tether) diff --git a/maps/tether/tether_things.dm b/maps/tether/tether_things.dm index 1cb9e08766..5ff0bbfe23 100644 --- a/maps/tether/tether_things.dm +++ b/maps/tether/tether_things.dm @@ -1,8 +1,3 @@ -/obj/structure/window/reinforced/polarized/full - dir = SOUTHWEST - icon_state = "fwindow" - maxhealth = 80 - //Special map objects /obj/effect/landmark/map_data/virgo3b height = 7 @@ -80,7 +75,7 @@ icon = 'icons/obj/stairs.dmi' icon_state = "stairs" invisibility = 0 -/obj/effect/step_trigger/teleporter/to_underdark/initialize() +/obj/effect/step_trigger/teleporter/to_underdark/Initialize() . = ..() teleport_x = x teleport_y = y @@ -93,7 +88,7 @@ icon = 'icons/obj/stairs.dmi' icon_state = "stairs" invisibility = 0 -/obj/effect/step_trigger/teleporter/from_underdark/initialize() +/obj/effect/step_trigger/teleporter/from_underdark/Initialize() . = ..() teleport_x = x teleport_y = y @@ -102,7 +97,7 @@ if(Z.name == "Mining Outpost") teleport_z = Z.z -/obj/effect/step_trigger/teleporter/planetary_fall/virgo3b/initialize() +/obj/effect/step_trigger/teleporter/planetary_fall/virgo3b/Initialize() planet = planet_virgo3b . = ..() @@ -157,7 +152,7 @@ var/area/shock_area = /area/tether/surfacebase/tram -/turf/simulated/floor/maglev/initialize() +/turf/simulated/floor/maglev/Initialize() . = ..() shock_area = locate(shock_area) @@ -197,7 +192,7 @@ /obj/machinery/smartfridge/chemistry/chemvator/down name = "\improper Smart Chemavator - Lower" -/obj/machinery/smartfridge/chemistry/chemvator/down/initialize() +/obj/machinery/smartfridge/chemistry/chemvator/down/Initialize() . = ..() var/obj/machinery/smartfridge/chemistry/chemvator/above = locate(/obj/machinery/smartfridge/chemistry/chemvator,get_zstep(src,UP)) if(istype(above)) @@ -319,22 +314,22 @@ var/global/list/latejoin_tram = list() "Beach" = new/datum/holodeck_program(/area/houseboat/holodeck/beach), "Desert" = new/datum/holodeck_program(/area/houseboat/holodeck/desert, list( - 'sound/effects/wind/wind_2_1.ogg', - 'sound/effects/wind/wind_2_2.ogg', - 'sound/effects/wind/wind_3_1.ogg', - 'sound/effects/wind/wind_4_1.ogg', - 'sound/effects/wind/wind_4_2.ogg', - 'sound/effects/wind/wind_5_1.ogg' + 'sound/effects/weather/wind/wind_2_1.ogg', + 'sound/effects/weather/wind/wind_2_2.ogg', + 'sound/effects/weather/wind/wind_3_1.ogg', + 'sound/effects/weather/wind/wind_4_1.ogg', + 'sound/effects/weather/wind/wind_4_2.ogg', + 'sound/effects/weather/wind/wind_5_1.ogg' ) ), "Snowfield" = new/datum/holodeck_program(/area/houseboat/holodeck/snow, list( - 'sound/effects/wind/wind_2_1.ogg', - 'sound/effects/wind/wind_2_2.ogg', - 'sound/effects/wind/wind_3_1.ogg', - 'sound/effects/wind/wind_4_1.ogg', - 'sound/effects/wind/wind_4_2.ogg', - 'sound/effects/wind/wind_5_1.ogg' + 'sound/effects/weather/wind/wind_2_1.ogg', + 'sound/effects/weather/wind/wind_2_2.ogg', + 'sound/effects/weather/wind/wind_3_1.ogg', + 'sound/effects/weather/wind/wind_4_1.ogg', + 'sound/effects/weather/wind/wind_4_2.ogg', + 'sound/effects/weather/wind/wind_5_1.ogg' ) ), "Space" = new/datum/holodeck_program(/area/houseboat/holodeck/space, @@ -406,10 +401,10 @@ var/global/list/latejoin_tram = list() prob_fall = 50 guard = 20 mobs_to_pick_from = list( - /mob/living/simple_animal/hostile/jelly = 3, - /mob/living/simple_animal/hostile/giant_spider/hunter = 1, - /mob/living/simple_animal/hostile/giant_spider/phorogenic = 1, - /mob/living/simple_animal/hostile/giant_spider/lurker = 1, + /mob/living/simple_mob/hostile/jelly = 3, + /mob/living/simple_mob/animal/giant_spider/hunter = 1, + /mob/living/simple_mob/animal/giant_spider/phorogenic = 1, + /mob/living/simple_mob/animal/giant_spider/lurker = 1, ) /obj/tether_away_spawner/underdark_hard @@ -420,9 +415,9 @@ var/global/list/latejoin_tram = list() prob_fall = 50 guard = 20 mobs_to_pick_from = list( - /mob/living/simple_animal/hostile/corrupthound = 1, - /mob/living/simple_animal/hostile/rat = 1, - /mob/living/simple_animal/hostile/mimic = 1 + /mob/living/simple_mob/vore/corrupthound = 1, + /mob/living/simple_mob/vore/rat = 1, + /mob/living/simple_mob/animal/space/mimic = 1 ) /obj/tether_away_spawner/underdark_boss @@ -433,13 +428,45 @@ var/global/list/latejoin_tram = list() prob_fall = 100 guard = 70 mobs_to_pick_from = list( - /mob/living/simple_animal/hostile/dragon = 1 + /mob/living/simple_mob/vore/dragon = 1 ) // Used at centcomm for the elevator /obj/machinery/cryopod/robot/door/dorms spawnpoint_type = /datum/spawnpoint/tram +//Tether-unique network cameras +/obj/machinery/camera/network/tether + network = list(NETWORK_TETHER) + +/obj/machinery/camera/network/tcomms + network = list(NETWORK_TCOMMS) + +/obj/machinery/camera/network/outside + network = list(NETWORK_OUTSIDE) + +/obj/machinery/camera/network/exploration + network = list(NETWORK_EXPLORATION) + +/obj/machinery/camera/network/research/xenobio + network = list(NETWORK_RESEARCH, NETWORK_XENOBIO) + +//Camera monitors +/obj/machinery/computer/security/xenobio + name = "xenobiology camera monitor" + desc = "Used to access the xenobiology cell cameras." + icon_keyboard = "mining_key" + icon_screen = "mining" + network = list(NETWORK_XENOBIO) + circuit = /obj/item/weapon/circuitboard/security/xenobio + light_color = "#F9BBFC" + +/obj/item/weapon/circuitboard/security/xenobio + name = T_BOARD("xenobiology camera monitor") + build_path = /obj/machinery/computer/security/xenobio + network = list(NETWORK_XENOBIO) + req_access = list() + // // ### Wall Machines On Full Windows ### // To make sure wall-mounted machines placed on full-tile windows are clickable they must be above the window diff --git a/maps/tether/tether_turfs.dm b/maps/tether/tether_turfs.dm index 4ae161d40f..a809765de3 100644 --- a/maps/tether/tether_turfs.dm +++ b/maps/tether/tether_turfs.dm @@ -164,7 +164,7 @@ VIRGO3B_TURF_CREATE(/turf/simulated/mineral/floor) /turf/space/bluespace name = "bluespace" icon_state = "bluespace" -/turf/space/bluespace/initialize() +/turf/space/bluespace/Initialize() ..() icon_state = "bluespace" @@ -173,7 +173,7 @@ VIRGO3B_TURF_CREATE(/turf/simulated/mineral/floor) name = "sand transit" icon = 'icons/turf/transit_vr.dmi' icon_state = "desert_ns" -/turf/space/sandyscroll/initialize() +/turf/space/sandyscroll/Initialize() ..() icon_state = "desert_ns" @@ -182,7 +182,7 @@ VIRGO3B_TURF_CREATE(/turf/simulated/mineral/floor) /turf/simulated/sky/virgo3b color = "#FFBBBB" -/turf/simulated/sky/virgo3b/initialize() +/turf/simulated/sky/virgo3b/Initialize() SSplanets.addTurf(src) set_light(2, 2, "#FFBBBB") diff --git a/maps/tether/tether_virgo3b.dm b/maps/tether/tether_virgo3b.dm index 284b3d2f4e..51b811d487 100644 --- a/maps/tether/tether_virgo3b.dm +++ b/maps/tether/tether_virgo3b.dm @@ -72,12 +72,12 @@ var/datum/planet/virgo3b/planet_virgo3b = null high_color = "#FFFFFF" min = 0.70 - var/lerp_weight = (abs(min - sun_position)) * 4 + var/interpolate_weight = (abs(min - sun_position)) * 4 var/weather_light_modifier = 1 if(weather_holder && weather_holder.current_weather) weather_light_modifier = weather_holder.current_weather.light_modifier - var/new_brightness = (Interpolate(low_brightness, high_brightness, weight = lerp_weight) ) * weather_light_modifier + var/new_brightness = (LERP(low_brightness, high_brightness, interpolate_weight) ) * weather_light_modifier var/new_color = null if(weather_holder && weather_holder.current_weather && weather_holder.current_weather.light_color) @@ -93,9 +93,9 @@ var/datum/planet/virgo3b/planet_virgo3b = null var/high_g = high_color_list[2] var/high_b = high_color_list[3] - var/new_r = Interpolate(low_r, high_r, weight = lerp_weight) - var/new_g = Interpolate(low_g, high_g, weight = lerp_weight) - var/new_b = Interpolate(low_b, high_b, weight = lerp_weight) + var/new_r = LERP(low_r, high_r, interpolate_weight) + var/new_g = LERP(low_g, high_g, interpolate_weight) + var/new_b = LERP(low_b, high_b, interpolate_weight) new_color = rgb(new_r, new_g, new_b) @@ -138,6 +138,13 @@ var/datum/planet/virgo3b/planet_virgo3b = null WEATHER_CLEAR = 60, WEATHER_OVERCAST = 40 ) + transition_messages = list( + "The sky clears up.", + "The sky is visible.", + "The weather is calm." + ) + sky_visible = TRUE + observed_message = "The sky is clear." /datum/weather/virgo3b/overcast name = "overcast" @@ -150,6 +157,12 @@ var/datum/planet/virgo3b/planet_virgo3b = null WEATHER_RAIN = 5, WEATHER_HAIL = 5 ) + observed_message = "It is overcast, all you can see are clouds." + transition_messages = list( + "All you can see above are clouds.", + "Clouds cut off your view of the sky.", + "It's very cloudy." + ) /datum/weather/virgo3b/light_snow name = "light snow" @@ -163,6 +176,11 @@ var/datum/planet/virgo3b/planet_virgo3b = null WEATHER_SNOW = 25, WEATHER_HAIL = 5 ) + observed_message = "It is snowing lightly." + transition_messages = list( + "Small snowflakes begin to fall from above.", + "It begins to snow lightly.", + ) /datum/weather/virgo3b/snow name = "moderate snow" @@ -178,6 +196,11 @@ var/datum/planet/virgo3b/planet_virgo3b = null WEATHER_HAIL = 5, WEATHER_OVERCAST = 5 ) + observed_message = "It is snowing." + transition_messages = list( + "It's starting to snow.", + "The air feels much colder as snowflakes fall from above." + ) /datum/weather/virgo3b/snow/process_effects() ..() @@ -202,6 +225,11 @@ var/datum/planet/virgo3b/planet_virgo3b = null WEATHER_HAIL = 10, WEATHER_OVERCAST = 5 ) + observed_message = "A blizzard blows snow everywhere." + transition_messages = list( + "Strong winds howl around you as a blizzard appears.", + "It starts snowing heavily, and it feels extremly cold now." + ) /datum/weather/virgo3b/blizzard/process_effects() ..() @@ -226,6 +254,10 @@ var/datum/planet/virgo3b/planet_virgo3b = null WEATHER_STORM = 10, WEATHER_HAIL = 5 ) + observed_message = "It is raining." + transition_messages = list( + "The sky is dark, and rain falls down upon you." + ) /datum/weather/virgo3b/rain/process_effects() ..() @@ -240,13 +272,13 @@ var/datum/planet/virgo3b/planet_virgo3b = null var/obj/item/weapon/melee/umbrella/U = L.get_active_hand() if(U.open) if(show_message) - to_chat(L, "Rain patters softly onto your umbrella") + to_chat(L, "Rain patters softly onto your umbrella.") continue else if(istype(L.get_inactive_hand(), /obj/item/weapon/melee/umbrella)) var/obj/item/weapon/melee/umbrella/U = L.get_inactive_hand() if(U.open) if(show_message) - to_chat(L, "Rain patters softly onto your umbrella") + to_chat(L, "Rain patters softly onto your umbrella.") continue L.water_act(1) @@ -258,6 +290,17 @@ var/datum/planet/virgo3b/planet_virgo3b = null icon_state = "storm" light_modifier = 0.3 flight_failure_modifier = 10 + effect_message = "Rain falls on you, drenching you in water." + + var/next_lightning_strike = 0 // world.time when lightning will strike. + var/min_lightning_cooldown = 5 SECONDS + var/max_lightning_cooldown = 1 MINUTE + observed_message = "An intense storm pours down over the region." + transition_messages = list( + "You feel intense winds hit you as the weather takes a turn for the worst.", + "Loud thunder is heard in the distance.", + "A bright flash heralds the approach of a storm." + ) transition_chances = list( @@ -275,22 +318,52 @@ var/datum/planet/virgo3b/planet_virgo3b = null if(!T.outdoors) continue // They're indoors, so no need to rain on them. - // If they have an open umbrella, it'll get stolen by the wind + // Lazy wind code + if(prob(10)) + if(istype(L.get_active_hand(), /obj/item/weapon/melee/umbrella)) + var/obj/item/weapon/melee/umbrella/U = L.get_active_hand() + if(U.open) + to_chat(L, "You struggle to keep hold of your umbrella!") + L.Stun(20) // This is not nearly as long as it seems + playsound(L, 'sound/effects/rustle1.ogg', 100, 1) // Closest sound I've got to "Umbrella in the wind" + else if(istype(L.get_inactive_hand(), /obj/item/weapon/melee/umbrella)) + var/obj/item/weapon/melee/umbrella/U = L.get_inactive_hand() + if(U.open) + to_chat(L, "A gust of wind yanks the umbrella from your hand!") + playsound(L, 'sound/effects/rustle1.ogg', 100, 1) + L.drop_from_inventory(U) + U.toggle_umbrella() + U.throw_at(get_edge_target_turf(U, pick(alldirs)), 8, 1, L) + + // If they have an open umbrella, it'll guard from rain if(istype(L.get_active_hand(), /obj/item/weapon/melee/umbrella)) var/obj/item/weapon/melee/umbrella/U = L.get_active_hand() if(U.open) - to_chat(L, "A gust of wind yanks the umbrella from your hand!") - L.drop_from_inventory(U) - U.throw_at(get_edge_target_turf(U, pick(alldirs)), 8, 1, L) + if(show_message) + to_chat(L, "Rain showers loudly onto your umbrella!") + continue else if(istype(L.get_inactive_hand(), /obj/item/weapon/melee/umbrella)) var/obj/item/weapon/melee/umbrella/U = L.get_inactive_hand() if(U.open) - to_chat(L, "A gust of wind yanks the umbrella from your hand!") - L.drop_from_inventory(U) - U.throw_at(get_edge_target_turf(U, pick(alldirs)), 8, 1, L) + if(show_message) + to_chat(L, "Rain showers loudly onto your umbrella!") + continue + L.water_act(2) - to_chat(L, "Rain falls on you, drenching you in water.") + if(show_message) + to_chat(L, effect_message) + + handle_lightning() + +// This gets called to do lightning periodically. +// There is a seperate function to do the actual lightning strike, so that badmins can play with it. +/datum/weather/virgo3b/storm/proc/handle_lightning() + if(world.time < next_lightning_strike) + return // It's too soon to strike again. + next_lightning_strike = world.time + rand(min_lightning_cooldown, max_lightning_cooldown) + var/turf/T = pick(holder.our_planet.planet_floors) // This has the chance to 'strike' the sky, but that might be a good thing, to scare reckless pilots. + lightning_strike(T) /datum/weather/virgo3b/hail name = "hail" @@ -307,41 +380,47 @@ var/datum/planet/virgo3b/planet_virgo3b = null WEATHER_HAIL = 10, WEATHER_OVERCAST = 5 ) + observed_message = "Ice is falling from the sky." + transition_messages = list( + "Ice begins to fall from the sky.", + "It begins to hail.", + "An intense chill is felt, and chunks of ice start to fall from the sky, towards you." + ) /datum/weather/virgo3b/hail/process_effects() ..() - for(var/mob/living/carbon/human/H in living_mob_list) + for(var/humie in human_mob_list) + var/mob/living/carbon/human/H = humie if(H.z in holder.our_planet.expected_z_levels) var/turf/T = get_turf(H) if(!T.outdoors) continue // They're indoors, so no need to pelt them with ice. - // If they have an open umbrella, it'll guard from rain - // Message plays every time the umbrella gets stolen, just so they're especially aware of what's happening + // If they have an open umbrella, it'll guard from hail + var/obj/item/weapon/melee/umbrella/U if(istype(H.get_active_hand(), /obj/item/weapon/melee/umbrella)) - var/obj/item/weapon/melee/umbrella/U = H.get_active_hand() - if(U.open) - if(show_message) - to_chat(H, "Hail patters gently onto your umbrella.") - continue + U = H.get_active_hand() else if(istype(H.get_inactive_hand(), /obj/item/weapon/melee/umbrella)) - var/obj/item/weapon/melee/umbrella/U = H.get_inactive_hand() - if(U.open) - if(show_message) - to_chat(H, "Hail patters gently onto your umbrella.") - continue - + U = H.get_inactive_hand() + if(U && U.open) + if(show_message) + to_chat(H, "Hail patters onto your umbrella.") + continue + var/target_zone = pick(BP_ALL) var/amount_blocked = H.run_armor_check(target_zone, "melee") var/amount_soaked = H.get_armor_soak(target_zone, "melee") - if(amount_blocked >= 100) + var/damage = rand(1,3) + + if(amount_blocked >= 30) + continue // No need to apply damage. Hardhats are 30. They should probably protect you from hail on your head. + //Voidsuits are likewise 40, and riot, 80. Clothes are all less than 30. + + if(amount_soaked >= damage) continue // No need to apply damage. - if(amount_soaked >= 10) - continue // No need to apply damage. - - H.apply_damage(rand(1, 3), BRUTE, target_zone, amount_blocked, amount_soaked, used_weapon = "hail") + H.apply_damage(damage, BRUTE, target_zone, amount_blocked, amount_soaked, used_weapon = "hail") if(show_message) to_chat(H, effect_message) @@ -353,3 +432,7 @@ var/datum/planet/virgo3b/planet_virgo3b = null transition_chances = list( WEATHER_BLOODMOON = 100 ) + observed_message = "Everything is red. Something really ominous is going on." + transition_messages = list( + "The sky turns blood red!" + ) diff --git a/maps/virgo/virgo-1.dmm b/maps/virgo/virgo-1.dmm index 88c9598bad..c734bb6c36 100644 --- a/maps/virgo/virgo-1.dmm +++ b/maps/virgo/virgo-1.dmm @@ -212,7 +212,7 @@ "aed" = (/obj/machinery/atmospherics/pipe/tank/air,/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 8},/turf/simulated/floor,/area/maintenance/library) "aee" = (/obj/machinery/atmospherics/pipe/tank/air,/obj/effect/floor_decal/industrial/warning/corner,/turf/simulated/floor,/area/maintenance/library) "aef" = (/obj/effect/floor_decal/industrial/warning{dir = 1},/turf/simulated/floor/tiled,/area/hallway/secondary/civilian_hallway_fore) -"aeg" = (/obj/effect/decal/cleanable/generic,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/mob/living/simple_animal/mouse,/turf/simulated/floor/plating,/area/maintenance/locker) +"aeg" = (/obj/effect/decal/cleanable/generic,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/mob/living/simple_mob/mouse,/turf/simulated/floor/plating,/area/maintenance/locker) "aeh" = (/obj/machinery/camera/network/civilian{c_tag = "CIV - Chapel Morgue"; dir = 4},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor/tiled/dark,/area/chapel/chapel_morgue) "aei" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/tiled/dark,/area/chapel/chapel_morgue) "aej" = (/obj/machinery/door/window{dir = 8; name = "Mass Driver"; req_access = list(22)},/obj/machinery/mass_driver{dir = 4; id = "chapelgun"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/obj/machinery/airlock_sensor{pixel_y = 25},/obj/effect/floor_decal/industrial/warning{dir = 8},/turf/simulated/floor/plating,/area/chapel/chapel_morgue) @@ -1015,7 +1015,7 @@ "atA" = (/obj/machinery/atmospherics/valve{dir = 4},/obj/machinery/alarm{pixel_y = 22},/turf/simulated/floor,/area/security/riot_control) "atB" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/obj/effect/floor_decal/industrial/warning{dir = 5},/turf/simulated/floor,/area/security/riot_control) "atC" = (/turf/simulated/wall/r_wall,/area/security/riot_control) -"atD" = (/obj/effect/decal/cleanable/dirt,/mob/living/simple_animal/mouse,/turf/simulated/floor/plating,/area/maintenance/security_starboard) +"atD" = (/obj/effect/decal/cleanable/dirt,/mob/living/simple_mob/mouse,/turf/simulated/floor/plating,/area/maintenance/security_starboard) "atE" = (/obj/machinery/light/small{dir = 1},/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor,/area/maintenance/security_starboard) "atF" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor,/area/maintenance/security_starboard) "atG" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/maintenance{req_access = list(12)},/turf/simulated/floor,/area/maintenance/security_starboard) @@ -3066,7 +3066,7 @@ "bgX" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 10; icon_state = "intact";},/obj/machinery/light/small{dir = 1},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/machinery/power/apc/high{dir = 1; name = "north bump"; pixel_y = 24},/turf/simulated/floor/tiled/dark,/area/server) "bgY" = (/obj/machinery/camera/network/research{c_tag = "SCI - Server Room"},/obj/machinery/portable_atmospherics/canister/nitrogen,/obj/machinery/atmospherics/portables_connector,/turf/simulated/floor/tiled/dark,/area/server) "bgZ" = (/obj/machinery/atmospherics/unary/freezer{dir = 2; icon_state = "freezer_1"; use_power = 1; power_setting = 20; set_temperature = 73},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor/tiled/dark,/area/server) -"bha" = (/mob/living/simple_animal/mouse,/turf/simulated/floor,/area/maintenance/research_shuttle) +"bha" = (/mob/living/simple_mob/mouse,/turf/simulated/floor,/area/maintenance/research_shuttle) "bhb" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/maintenance/research_shuttle) "bhc" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/tiled/white,/area/rnd/research) "bhd" = (/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,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/rnd/research) @@ -3748,7 +3748,7 @@ "bud" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/blast/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "cmooffice"; name = "CMO Office Privacy Shutters"; opacity = 0},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/crew_quarters/heads/cmo) "bue" = (/obj/structure/flora/pottedplant{icon_state = "plant-01"},/obj/effect/floor_decal/corner/paleblue/full{dir = 8},/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/simulated/floor/tiled/white,/area/crew_quarters/heads/cmo) "buf" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/obj/effect/floor_decal/corner/paleblue{dir = 5},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/tiled/white,/area/crew_quarters/heads/cmo) -"bug" = (/obj/effect/floor_decal/corner/paleblue{dir = 1},/obj/machinery/light{dir = 1},/obj/structure/disposalpipe/segment{dir = 4},/mob/living/simple_animal/cat/fluff/Runtime,/turf/simulated/floor/tiled/white,/area/crew_quarters/heads/cmo) +"bug" = (/obj/effect/floor_decal/corner/paleblue{dir = 1},/obj/machinery/light{dir = 1},/obj/structure/disposalpipe/segment{dir = 4},/mob/living/simple_mob/cat/fluff/Runtime,/turf/simulated/floor/tiled/white,/area/crew_quarters/heads/cmo) "buh" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/tiled/white,/area/crew_quarters/heads/cmo) "bui" = (/obj/effect/floor_decal/corner/paleblue{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/tiled/white,/area/crew_quarters/heads/cmo) "buj" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 8},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/effect/floor_decal/corner/paleblue/full{dir = 1},/turf/simulated/floor/tiled/white,/area/crew_quarters/heads/cmo) @@ -4158,7 +4158,7 @@ "bBX" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/central) "bBY" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/item/weapon/material/shard{icon_state = "medium"},/obj/item/stack/rods,/turf/simulated/floor,/area/maintenance/central) "bBZ" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/maintenance/central) -"bCa" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/mob/living/simple_animal/mouse,/turf/simulated/floor,/area/maintenance/central) +"bCa" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/mob/living/simple_mob/mouse,/turf/simulated/floor,/area/maintenance/central) "bCb" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor,/area/maintenance/central) "bCc" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/airlock/maintenance{req_access = list(12)},/obj/machinery/door/firedoor,/turf/simulated/floor/tiled,/area/maintenance/central) "bCd" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/tiled,/area/maintenance/central) @@ -4238,7 +4238,7 @@ "bDz" = (/obj/structure/closet/crate,/obj/item/weapon/reagent_containers/food/drinks/bottle/wine,/obj/random/drinkbottle,/obj/random/maintenance/clean,/turf/simulated/floor/plating,/area/maintenance/central) "bDA" = (/turf/simulated/floor/tiled,/area/maintenance/central) "bDB" = (/obj/structure/cable/green{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/tiled,/area/maintenance/central) -"bDC" = (/obj/machinery/light/small,/mob/living/simple_animal/mouse,/turf/simulated/floor/plating,/area/maintenance/central) +"bDC" = (/obj/machinery/light/small,/mob/living/simple_mob/mouse,/turf/simulated/floor/plating,/area/maintenance/central) "bDD" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/maintenance/central) "bDE" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor,/area/maintenance/central) "bDF" = (/obj/structure/closet,/obj/item/weapon/storage/backpack,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/random/maintenance/clean,/obj/random/maintenance/cargo,/turf/simulated/floor/plating,/area/maintenance/central) @@ -4542,7 +4542,7 @@ "bJr" = (/turf/simulated/wall/r_wall,/area/quartermaster/miningdock) "bJs" = (/obj/structure/lattice,/obj/machinery/light{dir = 8},/turf/simulated/mineral/floor/ignore_mapgen,/area/quartermaster/miningdock) "bJt" = (/obj/structure/lattice,/obj/machinery/light{dir = 4; icon_state = "tube1"; pixel_x = 0},/turf/simulated/mineral/floor/ignore_mapgen,/area/quartermaster/miningdock) -"bJu" = (/obj/structure/table/rack,/obj/item/weapon/extinguisher,/obj/item/weapon/storage/belt/utility,/obj/item/clothing/mask/gas,/obj/machinery/atmospherics/pipe/simple/hidden/yellow,/mob/living/simple_animal/mouse,/turf/simulated/floor/plating,/area/maintenance/research) +"bJu" = (/obj/structure/table/rack,/obj/item/weapon/extinguisher,/obj/item/weapon/storage/belt/utility,/obj/item/clothing/mask/gas,/obj/machinery/atmospherics/pipe/simple/hidden/yellow,/mob/living/simple_mob/mouse,/turf/simulated/floor/plating,/area/maintenance/research) "bJv" = (/obj/structure/table/rack{dir = 8; layer = 2.9},/obj/item/weapon/tank/oxygen,/obj/item/weapon/tank/oxygen,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/device/flashlight,/obj/item/device/flashlight,/obj/item/weapon/storage/box/lights/mixed,/obj/item/weapon/extinguisher,/obj/random/maintenance/research,/obj/random/maintenance/research,/turf/simulated/floor/plating,/area/maintenance/research) "bJw" = (/obj/structure/table/standard,/obj/item/device/assembly/igniter,/turf/simulated/floor/reinforced,/area/rnd/misc_lab) "bJx" = (/obj/structure/reagent_dispensers/watertank,/obj/machinery/light,/turf/simulated/floor/reinforced,/area/rnd/misc_lab) @@ -4562,7 +4562,7 @@ "bJL" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/obj/machinery/light{dir = 8},/turf/simulated/floor/tiled,/area/hallway/primary/central_four) "bJM" = (/obj/structure/grille,/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = -32},/obj/structure/cable/green,/obj/machinery/door/firedoor,/obj/structure/window/reinforced/polarized{dir = 8; id = "hop_office"},/obj/structure/window/reinforced/polarized{dir = 2; id = "hop_office"},/obj/structure/window/reinforced/polarized{dir = 4; id = "hop_office"},/turf/simulated/floor/plating,/area/crew_quarters/heads/hop) "bJN" = (/obj/structure/closet/secure_closet/hop,/obj/effect/floor_decal/corner/blue{dir = 9},/obj/item/clothing/glasses/omnihud,/turf/simulated/floor/tiled,/area/crew_quarters/heads/hop) -"bJO" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/mob/living/simple_animal/corgi/Ian,/turf/simulated/floor/carpet,/area/crew_quarters/heads/hop) +"bJO" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/mob/living/simple_mob/corgi/Ian,/turf/simulated/floor/carpet,/area/crew_quarters/heads/hop) "bJP" = (/obj/structure/bed/chair/office/dark,/obj/effect/landmark/start{name = "Head of Personnel"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/carpet,/area/crew_quarters/heads/hop) "bJQ" = (/obj/structure/cable/green{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/carpet,/area/crew_quarters/heads/hop) "bJR" = (/obj/structure/cable/green{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},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/carpet,/area/crew_quarters/heads/hop) @@ -4855,7 +4855,7 @@ "bPs" = (/obj/machinery/computer/aifixer,/obj/effect/floor_decal/corner/purple/full,/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = -32},/turf/simulated/floor/tiled/white,/area/rnd/rdoffice) "bPt" = (/obj/machinery/computer/robotics,/obj/effect/floor_decal/corner/purple{dir = 10},/turf/simulated/floor/tiled/white,/area/rnd/rdoffice) "bPu" = (/obj/machinery/computer/mecha,/obj/effect/floor_decal/corner/purple{dir = 10},/obj/machinery/ai_status_display{pixel_y = -32},/obj/machinery/camera/network/research{c_tag = "SCI - RD's Office"; dir = 1},/turf/simulated/floor/tiled/white,/area/rnd/rdoffice) -"bPv" = (/obj/effect/floor_decal/corner/purple/full{dir = 4},/obj/machinery/alarm{dir = 1; pixel_y = -22},/mob/living/simple_animal/slime/science,/turf/simulated/floor/tiled/white,/area/rnd/rdoffice) +"bPv" = (/obj/effect/floor_decal/corner/purple/full{dir = 4},/obj/machinery/alarm{dir = 1; pixel_y = -22},/mob/living/simple_mob/slime/science,/turf/simulated/floor/tiled/white,/area/rnd/rdoffice) "bPw" = (/obj/structure/table/rack,/obj/item/weapon/rig/hazmat/equipped,/obj/structure/extinguisher_cabinet{pixel_x = 25; pixel_y = 0},/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor/tiled/dark,/area/rnd/rdoffice) "bPx" = (/obj/structure/table/standard,/obj/item/device/mmi,/obj/item/device/mmi,/obj/item/device/mmi,/obj/structure/extinguisher_cabinet{pixel_x = -27},/turf/simulated/floor/tiled,/area/assembly/robotics) "bPy" = (/obj/structure/table/standard,/obj/machinery/cell_charger,/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 21},/obj/effect/floor_decal/corner/pink{dir = 4},/turf/simulated/floor/tiled,/area/assembly/robotics) @@ -5307,7 +5307,7 @@ "bYc" = (/turf/simulated/wall,/area/maintenance/medbay_aft) "bYd" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/maintenance/medbay_aft) "bYe" = (/obj/machinery/atmospherics/valve,/turf/simulated/floor/plating,/area/maintenance/medbay_aft) -"bYf" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 6; icon_state = "intact";},/obj/effect/floor_decal/industrial/warning{dir = 8},/mob/living/simple_animal/mouse,/turf/simulated/floor/plating,/area/maintenance/medbay_aft) +"bYf" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 6; icon_state = "intact";},/obj/effect/floor_decal/industrial/warning{dir = 8},/mob/living/simple_mob/mouse,/turf/simulated/floor/plating,/area/maintenance/medbay_aft) "bYg" = (/obj/machinery/atmospherics/pipe/tank/air{dir = 8},/turf/simulated/floor/plating,/area/maintenance/medbay_aft) "bYh" = (/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod_berth{frequency = 1380; id_tag = "large_escape_pod_1_berth"; pixel_x = -26; pixel_y = 0; tag_door = "large_escape_pod_1_berth_hatch"},/obj/effect/floor_decal/industrial/warning{dir = 8},/turf/simulated/floor/tiled,/area/hallway/secondary/escape/medical_escape_pod_hallway) "bYi" = (/obj/effect/floor_decal/industrial/warning/corner,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/yellow,/obj/structure/disposalpipe/segment,/turf/simulated/floor/tiled,/area/hallway/secondary/escape/medical_escape_pod_hallway) @@ -5346,7 +5346,7 @@ "bYP" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/tiled,/area/bridge_hallway) "bYQ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/structure/cable/green,/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/machinery/door/firedoor,/obj/machinery/door/blast/shutters{dir = 8; id = "cap_office"; layer = 3.1; name = "Captain's Shutters"},/turf/simulated/floor/plating,/area/bridge_hallway) "bYR" = (/obj/structure/bed/chair/comfy/brown{dir = 1},/turf/simulated/floor/carpet,/area/crew_quarters/captain) -"bYS" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/mob/living/simple_animal/fox/fluff/Renault,/turf/simulated/floor/wood,/area/crew_quarters/captain) +"bYS" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/mob/living/simple_mob/fox/fluff/Renault,/turf/simulated/floor/wood,/area/crew_quarters/captain) "bYT" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/wood,/area/crew_quarters/captain) "bYU" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/obj/structure/bed/chair{dir = 1},/turf/simulated/floor/wood,/area/crew_quarters/captain) "bYV" = (/obj/structure/filingcabinet,/obj/machinery/light{dir = 4},/turf/simulated/floor/wood,/area/crew_quarters/captain) @@ -6142,7 +6142,7 @@ "cof" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/hallway/primary/central_three) "cog" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/obj/machinery/light{dir = 8},/obj/structure/closet/crate/secure{name = "Confiscated Contraband Crate"; req_access = list(19)},/obj/item/stolenpackage,/obj/item/stolenpackage,/obj/item/stolenpackage,/turf/simulated/floor/tiled/dark,/area/security/nuke_storage) "coh" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/tiled/dark,/area/security/nuke_storage) -"coi" = (/obj/machinery/hologram/holopad,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/mob/living/simple_animal/mouse/brown/Tom,/turf/simulated/floor/tiled/dark,/area/security/nuke_storage) +"coi" = (/obj/machinery/hologram/holopad,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/mob/living/simple_mob/mouse/brown/Tom,/turf/simulated/floor/tiled/dark,/area/security/nuke_storage) "coj" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/tiled/dark,/area/security/nuke_storage) "cok" = (/obj/machinery/camera/network/command{c_tag = "COM - Vault"; dir = 9},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/obj/structure/closet/crate/secure{name = "Platinum Crate"; req_access = list(19)},/obj/fiftyspawner/platinum,/obj/item/weapon/coin/platinum,/obj/item/weapon/coin/platinum,/obj/item/weapon/coin/platinum,/obj/item/weapon/coin/platinum,/obj/item/weapon/coin/platinum,/turf/simulated/floor/tiled/dark,/area/security/nuke_storage) "col" = (/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/structure/disposalpipe/segment,/obj/machinery/door/airlock/maintenance{req_access = list(12)},/turf/simulated/floor,/area/maintenance/medbay_aft) @@ -6787,7 +6787,7 @@ "cAA" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/tiled,/area/quartermaster/storage) "cAB" = (/obj/machinery/door/airlock/glass_mining{name = "Quartermaster"; req_access = list(41)},/obj/machinery/door/firedoor/glass,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/tiled,/area/quartermaster/qm) "cAC" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor/tiled,/area/quartermaster/qm) -"cAD" = (/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/mob/living/simple_animal/fluffy,/turf/simulated/floor/tiled,/area/quartermaster/qm) +"cAD" = (/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/mob/living/simple_mob/fluffy,/turf/simulated/floor/tiled,/area/quartermaster/qm) "cAE" = (/obj/structure/table/standard,/obj/item/weapon/clipboard,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/item/weapon/stamp/qm,/turf/simulated/floor/tiled,/area/quartermaster/qm) "cAF" = (/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/tiled,/area/quartermaster/qm) "cAG" = (/obj/machinery/computer/security/mining,/turf/simulated/floor/tiled,/area/quartermaster/qm) diff --git a/maps/virgo/virgo-2.dmm b/maps/virgo/virgo-2.dmm index 9e956a10a1..ea70471df2 100644 --- a/maps/virgo/virgo-2.dmm +++ b/maps/virgo/virgo-2.dmm @@ -646,7 +646,7 @@ "amv" = (/obj/machinery/vending/snack{name = "hacked Getmore Chocolate Corp"; prices = list()},/turf/simulated/shuttle/floor/black,/area/shuttle/trade/centcom) "amw" = (/obj/machinery/light{dir = 8; icon_state = "tube1"; pixel_y = 0},/turf/simulated/shuttle/floor/black,/area/shuttle/trade/centcom) "amx" = (/obj/structure/frame/computer,/turf/simulated/shuttle/floor/black,/area/shuttle/trade/centcom) -"amy" = (/obj/machinery/light{dir = 4},/obj/structure/sign/kiddieplaque{desc = "A plaque commemorating the construction of the cargo ship Beruang."; name = "Beruang"; pixel_x = 32},/mob/living/simple_animal/corgi/tamaskan/spice,/turf/simulated/shuttle/floor/darkred,/area/shuttle/trade/centcom) +"amy" = (/obj/machinery/light{dir = 4},/obj/structure/sign/kiddieplaque{desc = "A plaque commemorating the construction of the cargo ship Beruang."; name = "Beruang"; pixel_x = 32},/mob/living/simple_mob/corgi/tamaskan/spice,/turf/simulated/shuttle/floor/darkred,/area/shuttle/trade/centcom) "amz" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdown"; tiles = 0},/turf/space/transit/north/shuttlespace_ns13,/area/space) "amA" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 4; name = "thrower_escapeshuttletop(right)"; tiles = 0},/turf/space/transit/north/shuttlespace_ns2,/area/space) "amB" = (/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/area/syndicate_mothership) @@ -1205,7 +1205,7 @@ "axi" = (/turf/simulated/shuttle/floor/black,/area/shuttle/administration/centcom) "axj" = (/obj/machinery/recharge_station,/turf/simulated/shuttle/floor/black,/area/shuttle/administration/centcom) "axk" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "specops_shuttle_fore_hatch"; locked = 1; name = "Forward Docking Hatch"; req_access = list(13)},/turf/simulated/shuttle/plating,/area/shuttle/specops/centcom) -"axl" = (/obj/effect/floor_decal/corner/blue/diagonal{dir = 4},/obj/effect/floor_decal/corner/red/diagonal,/mob/living/simple_animal/corgi/puppy{name = "Bockscar"},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/specops) +"axl" = (/obj/effect/floor_decal/corner/blue/diagonal{dir = 4},/obj/effect/floor_decal/corner/red/diagonal,/mob/living/simple_mob/corgi/puppy{name = "Bockscar"},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/specops) "axm" = (/obj/structure/table/reinforced,/obj/machinery/recharger{pixel_y = 4},/turf/simulated/shuttle/floor/black,/area/shuttle/administration/centcom) "axn" = (/obj/machinery/flasher{id = "syndieflash"; pixel_x = 0; pixel_y = 28},/obj/machinery/light/small{dir = 1},/turf/simulated/shuttle/floor/black,/area/syndicate_station/start) "axo" = (/obj/structure/toilet{dir = 4},/turf/simulated/shuttle/floor/black,/area/syndicate_station/start) @@ -1305,7 +1305,7 @@ "aze" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "admin_shuttle"; pixel_x = -25; pixel_y = -4; req_one_access = list(101); tag_door = "admin_shuttle_hatch"},/obj/machinery/airlock_sensor{pixel_x = -24; pixel_y = 6},/turf/simulated/floor/plating,/area/shuttle/administration/centcom) "azf" = (/obj/machinery/light/small{dir = 4; pixel_y = 0},/turf/simulated/floor/plating,/area/shuttle/administration/centcom) "azg" = (/obj/machinery/button/remote/blast_door{id = "smindicate"; name = "ship lockdown control"; pixel_x = -25},/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) -"azh" = (/mob/living/simple_animal/cat/kitten{name = "Enola"},/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) +"azh" = (/mob/living/simple_mob/cat/kitten{name = "Enola"},/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) "azi" = (/obj/machinery/atmospherics/pipe/tank/air{dir = 4; start_pressure = 740.5},/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) "azj" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1331; master_tag = "merc_shuttle"; name = "interior access button"; pixel_x = 25; pixel_y = 25; req_access = list(150)},/obj/machinery/atmospherics/pipe/simple/visible{icon_state = "intact"; dir = 9},/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) "azk" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/obj/machinery/meter,/turf/simulated/shuttle/floor/darkred,/area/syndicate_station/start) @@ -2458,7 +2458,7 @@ "aVn" = (/obj/structure/reagent_dispensers/watertank,/obj/machinery/light/small{dir = 4},/turf/simulated/shuttle/plating,/area/space) "aVo" = (/obj/machinery/door/airlock/hatch{req_access = list(150)},/turf/simulated/shuttle/floor/red,/area/space) "aVp" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/syndicate/black/engie,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/syndicate/black/engie,/obj/machinery/light/small{dir = 8},/turf/simulated/shuttle/plating,/area/space) -"aVq" = (/mob/living/simple_animal/crab/Coffee,/turf/unsimulated/beach/sand,/area/centcom/evac) +"aVq" = (/mob/living/simple_mob/crab/Coffee,/turf/unsimulated/beach/sand,/area/centcom/evac) "aVr" = (/obj/item/robot_parts/head,/turf/simulated/shuttle/plating,/area/space) "aVs" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{id = "skipjackshutters"; name = "Skipjack Blast Shielding"},/turf/simulated/shuttle/plating,/area/space) "aVt" = (/obj/item/robot_parts/l_leg,/turf/simulated/shuttle/plating,/area/space) @@ -2621,7 +2621,7 @@ "aZM" = (/obj/machinery/media/jukebox,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) "aZN" = (/obj/machinery/vending/hydronutrients,/turf/unsimulated/floor{icon_state = "grass0"; name = "grass"},/area/wizard_station) "aZO" = (/obj/structure/closet{icon_closed = "cabinet_closed"; icon_opened = "cabinet_open"; icon_state = "cabinet_closed"},/obj/item/clothing/under/psysuit,/obj/item/clothing/suit/wizrobe/psypurple,/obj/item/clothing/head/wizard/amp,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station) -"aZP" = (/mob/living/simple_animal/mouse/gray{desc = "He looks kingly."; name = "Arthur"},/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) +"aZP" = (/mob/living/simple_mob/mouse/gray{desc = "He looks kingly."; name = "Arthur"},/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) "aZQ" = (/obj/structure/flora/pottedplant{icon_state = "plant-24"},/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station) "aZY" = (/obj/machinery/photocopier,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) "aZZ" = (/obj/structure/bookcase,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) diff --git a/maps/~map_system/maps.dm b/maps/~map_system/maps.dm index 0ecd7fbfdb..4ba9d3d03b 100644 --- a/maps/~map_system/maps.dm +++ b/maps/~map_system/maps.dm @@ -140,7 +140,7 @@ var/list/all_maps = list() /datum/map/proc/get_empty_zlevel() if(empty_levels == null) - world.maxz++ + world.increment_max_z() empty_levels = list(world.maxz) return pick(empty_levels) diff --git a/sound/effects/break_stone.ogg b/sound/effects/break_stone.ogg new file mode 100644 index 0000000000..711fd50d48 Binary files /dev/null and b/sound/effects/break_stone.ogg differ diff --git a/sound/effects/footstep/asteroid1.ogg b/sound/effects/footstep/asteroid1.ogg new file mode 100644 index 0000000000..1cb215dc78 Binary files /dev/null and b/sound/effects/footstep/asteroid1.ogg differ diff --git a/sound/effects/footstep/asteroid2.ogg b/sound/effects/footstep/asteroid2.ogg new file mode 100644 index 0000000000..331d0ef241 Binary files /dev/null and b/sound/effects/footstep/asteroid2.ogg differ diff --git a/sound/effects/footstep/asteroid3.ogg b/sound/effects/footstep/asteroid3.ogg new file mode 100644 index 0000000000..90fbf251a0 Binary files /dev/null and b/sound/effects/footstep/asteroid3.ogg differ diff --git a/sound/effects/footstep/asteroid4.ogg b/sound/effects/footstep/asteroid4.ogg new file mode 100644 index 0000000000..186ff17a43 Binary files /dev/null and b/sound/effects/footstep/asteroid4.ogg differ diff --git a/sound/effects/footstep/asteroid5.ogg b/sound/effects/footstep/asteroid5.ogg new file mode 100644 index 0000000000..0ea4c962d0 Binary files /dev/null and b/sound/effects/footstep/asteroid5.ogg differ diff --git a/sound/effects/footstep/grass1.ogg b/sound/effects/footstep/grass1.ogg new file mode 100644 index 0000000000..357547cd77 Binary files /dev/null and b/sound/effects/footstep/grass1.ogg differ diff --git a/sound/effects/footstep/grass2.ogg b/sound/effects/footstep/grass2.ogg new file mode 100644 index 0000000000..75bf8657e8 Binary files /dev/null and b/sound/effects/footstep/grass2.ogg differ diff --git a/sound/effects/footstep/grass3.ogg b/sound/effects/footstep/grass3.ogg new file mode 100644 index 0000000000..04f82872b1 Binary files /dev/null and b/sound/effects/footstep/grass3.ogg differ diff --git a/sound/effects/footstep/grass4.ogg b/sound/effects/footstep/grass4.ogg new file mode 100644 index 0000000000..6d736f2fb2 Binary files /dev/null and b/sound/effects/footstep/grass4.ogg differ diff --git a/sound/effects/footstep/lava1.ogg b/sound/effects/footstep/lava1.ogg new file mode 100644 index 0000000000..e26dbaf8bd Binary files /dev/null and b/sound/effects/footstep/lava1.ogg differ diff --git a/sound/effects/footstep/lava2.ogg b/sound/effects/footstep/lava2.ogg new file mode 100644 index 0000000000..90b73f840b Binary files /dev/null and b/sound/effects/footstep/lava2.ogg differ diff --git a/sound/effects/footstep/lava3.ogg b/sound/effects/footstep/lava3.ogg new file mode 100644 index 0000000000..3436381510 Binary files /dev/null and b/sound/effects/footstep/lava3.ogg differ diff --git a/sound/effects/footstep/water1.ogg b/sound/effects/footstep/water1.ogg new file mode 100644 index 0000000000..f22cbf2848 Binary files /dev/null and b/sound/effects/footstep/water1.ogg differ diff --git a/sound/effects/footstep/water2.ogg b/sound/effects/footstep/water2.ogg new file mode 100644 index 0000000000..e2a47650c6 Binary files /dev/null and b/sound/effects/footstep/water2.ogg differ diff --git a/sound/effects/footstep/water3.ogg b/sound/effects/footstep/water3.ogg new file mode 100644 index 0000000000..97ce152a5c Binary files /dev/null and b/sound/effects/footstep/water3.ogg differ diff --git a/sound/effects/footstep/water4.ogg b/sound/effects/footstep/water4.ogg new file mode 100644 index 0000000000..5778a52560 Binary files /dev/null and b/sound/effects/footstep/water4.ogg differ diff --git a/sound/effects/servostep.ogg b/sound/effects/servostep.ogg new file mode 100644 index 0000000000..9999b99ccb Binary files /dev/null and b/sound/effects/servostep.ogg differ diff --git a/sound/effects/suitstep1.ogg b/sound/effects/suitstep1.ogg new file mode 100644 index 0000000000..fdc56bb9e4 Binary files /dev/null and b/sound/effects/suitstep1.ogg differ diff --git a/sound/effects/suitstep2.ogg b/sound/effects/suitstep2.ogg new file mode 100644 index 0000000000..17a528feeb Binary files /dev/null and b/sound/effects/suitstep2.ogg differ diff --git a/sound/effects/weather/acidrain_end.ogg b/sound/effects/weather/acidrain_end.ogg new file mode 100644 index 0000000000..75fb4aaf8d Binary files /dev/null and b/sound/effects/weather/acidrain_end.ogg differ diff --git a/sound/effects/weather/acidrain_mid.ogg b/sound/effects/weather/acidrain_mid.ogg new file mode 100644 index 0000000000..03d4812355 Binary files /dev/null and b/sound/effects/weather/acidrain_mid.ogg differ diff --git a/sound/effects/weather/acidrain_start.ogg b/sound/effects/weather/acidrain_start.ogg new file mode 100644 index 0000000000..48f365d9df Binary files /dev/null and b/sound/effects/weather/acidrain_start.ogg differ diff --git a/sound/effects/weather/snowstorm/inside/active_end.ogg b/sound/effects/weather/snowstorm/inside/active_end.ogg new file mode 100644 index 0000000000..959bf5773e Binary files /dev/null and b/sound/effects/weather/snowstorm/inside/active_end.ogg differ diff --git a/sound/effects/weather/snowstorm/inside/active_mid1.ogg b/sound/effects/weather/snowstorm/inside/active_mid1.ogg new file mode 100644 index 0000000000..95244cd2b7 Binary files /dev/null and b/sound/effects/weather/snowstorm/inside/active_mid1.ogg differ diff --git a/sound/effects/weather/snowstorm/inside/active_mid2.ogg b/sound/effects/weather/snowstorm/inside/active_mid2.ogg new file mode 100644 index 0000000000..a45584b9f3 Binary files /dev/null and b/sound/effects/weather/snowstorm/inside/active_mid2.ogg differ diff --git a/sound/effects/weather/snowstorm/inside/active_mid3.ogg b/sound/effects/weather/snowstorm/inside/active_mid3.ogg new file mode 100644 index 0000000000..be2e672fa0 Binary files /dev/null and b/sound/effects/weather/snowstorm/inside/active_mid3.ogg differ diff --git a/sound/effects/weather/snowstorm/inside/active_start.ogg b/sound/effects/weather/snowstorm/inside/active_start.ogg new file mode 100644 index 0000000000..3efab12ef2 Binary files /dev/null and b/sound/effects/weather/snowstorm/inside/active_start.ogg differ diff --git a/sound/effects/weather/snowstorm/inside/weak_end.ogg b/sound/effects/weather/snowstorm/inside/weak_end.ogg new file mode 100644 index 0000000000..416b75a9b8 Binary files /dev/null and b/sound/effects/weather/snowstorm/inside/weak_end.ogg differ diff --git a/sound/effects/weather/snowstorm/inside/weak_mid1.ogg b/sound/effects/weather/snowstorm/inside/weak_mid1.ogg new file mode 100644 index 0000000000..d3211c6b5f Binary files /dev/null and b/sound/effects/weather/snowstorm/inside/weak_mid1.ogg differ diff --git a/sound/effects/weather/snowstorm/inside/weak_mid2.ogg b/sound/effects/weather/snowstorm/inside/weak_mid2.ogg new file mode 100644 index 0000000000..b6491a7afb Binary files /dev/null and b/sound/effects/weather/snowstorm/inside/weak_mid2.ogg differ diff --git a/sound/effects/weather/snowstorm/inside/weak_mid3.ogg b/sound/effects/weather/snowstorm/inside/weak_mid3.ogg new file mode 100644 index 0000000000..95238c72d4 Binary files /dev/null and b/sound/effects/weather/snowstorm/inside/weak_mid3.ogg differ diff --git a/sound/effects/weather/snowstorm/inside/weak_start.ogg b/sound/effects/weather/snowstorm/inside/weak_start.ogg new file mode 100644 index 0000000000..59abf1937d Binary files /dev/null and b/sound/effects/weather/snowstorm/inside/weak_start.ogg differ diff --git a/sound/effects/weather/snowstorm/outside/active_end.ogg b/sound/effects/weather/snowstorm/outside/active_end.ogg new file mode 100644 index 0000000000..95149d846c Binary files /dev/null and b/sound/effects/weather/snowstorm/outside/active_end.ogg differ diff --git a/sound/effects/weather/snowstorm/outside/active_mid1.ogg b/sound/effects/weather/snowstorm/outside/active_mid1.ogg new file mode 100644 index 0000000000..189528ab56 Binary files /dev/null and b/sound/effects/weather/snowstorm/outside/active_mid1.ogg differ diff --git a/sound/effects/weather/snowstorm/outside/active_mid2.ogg b/sound/effects/weather/snowstorm/outside/active_mid2.ogg new file mode 100644 index 0000000000..92317f2e0a Binary files /dev/null and b/sound/effects/weather/snowstorm/outside/active_mid2.ogg differ diff --git a/sound/effects/weather/snowstorm/outside/active_mid3.ogg b/sound/effects/weather/snowstorm/outside/active_mid3.ogg new file mode 100644 index 0000000000..34846bfd42 Binary files /dev/null and b/sound/effects/weather/snowstorm/outside/active_mid3.ogg differ diff --git a/sound/effects/weather/snowstorm/outside/active_start.ogg b/sound/effects/weather/snowstorm/outside/active_start.ogg new file mode 100644 index 0000000000..8b3acf1a15 Binary files /dev/null and b/sound/effects/weather/snowstorm/outside/active_start.ogg differ diff --git a/sound/effects/weather/snowstorm/outside/weak_end.ogg b/sound/effects/weather/snowstorm/outside/weak_end.ogg new file mode 100644 index 0000000000..55db2fc356 Binary files /dev/null and b/sound/effects/weather/snowstorm/outside/weak_end.ogg differ diff --git a/sound/effects/weather/snowstorm/outside/weak_mid1.ogg b/sound/effects/weather/snowstorm/outside/weak_mid1.ogg new file mode 100644 index 0000000000..56faa9ad26 Binary files /dev/null and b/sound/effects/weather/snowstorm/outside/weak_mid1.ogg differ diff --git a/sound/effects/weather/snowstorm/outside/weak_mid2.ogg b/sound/effects/weather/snowstorm/outside/weak_mid2.ogg new file mode 100644 index 0000000000..0c836ad220 Binary files /dev/null and b/sound/effects/weather/snowstorm/outside/weak_mid2.ogg differ diff --git a/sound/effects/weather/snowstorm/outside/weak_mid3.ogg b/sound/effects/weather/snowstorm/outside/weak_mid3.ogg new file mode 100644 index 0000000000..f2cbfb0f4b Binary files /dev/null and b/sound/effects/weather/snowstorm/outside/weak_mid3.ogg differ diff --git a/sound/effects/weather/snowstorm/outside/weak_start.ogg b/sound/effects/weather/snowstorm/outside/weak_start.ogg new file mode 100644 index 0000000000..1ac59c36f0 Binary files /dev/null and b/sound/effects/weather/snowstorm/outside/weak_start.ogg differ diff --git a/sound/effects/wind/wind_2_1.ogg b/sound/effects/weather/wind/wind_2_1.ogg similarity index 100% rename from sound/effects/wind/wind_2_1.ogg rename to sound/effects/weather/wind/wind_2_1.ogg diff --git a/sound/effects/wind/wind_2_2.ogg b/sound/effects/weather/wind/wind_2_2.ogg similarity index 100% rename from sound/effects/wind/wind_2_2.ogg rename to sound/effects/weather/wind/wind_2_2.ogg diff --git a/sound/effects/wind/wind_3_1.ogg b/sound/effects/weather/wind/wind_3_1.ogg similarity index 100% rename from sound/effects/wind/wind_3_1.ogg rename to sound/effects/weather/wind/wind_3_1.ogg diff --git a/sound/effects/wind/wind_4_1.ogg b/sound/effects/weather/wind/wind_4_1.ogg similarity index 100% rename from sound/effects/wind/wind_4_1.ogg rename to sound/effects/weather/wind/wind_4_1.ogg diff --git a/sound/effects/wind/wind_4_2.ogg b/sound/effects/weather/wind/wind_4_2.ogg similarity index 100% rename from sound/effects/wind/wind_4_2.ogg rename to sound/effects/weather/wind/wind_4_2.ogg diff --git a/sound/effects/wind/wind_5_1.ogg b/sound/effects/weather/wind/wind_5_1.ogg similarity index 100% rename from sound/effects/wind/wind_5_1.ogg rename to sound/effects/weather/wind/wind_5_1.ogg diff --git a/sound/items/geiger/ext1.ogg b/sound/items/geiger/ext1.ogg new file mode 100644 index 0000000000..ca1b44e4d8 Binary files /dev/null and b/sound/items/geiger/ext1.ogg differ diff --git a/sound/items/geiger/ext2.ogg b/sound/items/geiger/ext2.ogg new file mode 100644 index 0000000000..c0c316245b Binary files /dev/null and b/sound/items/geiger/ext2.ogg differ diff --git a/sound/items/geiger/ext3.ogg b/sound/items/geiger/ext3.ogg new file mode 100644 index 0000000000..fc367d9466 Binary files /dev/null and b/sound/items/geiger/ext3.ogg differ diff --git a/sound/items/geiger/ext4.ogg b/sound/items/geiger/ext4.ogg new file mode 100644 index 0000000000..d3b00ebaac Binary files /dev/null and b/sound/items/geiger/ext4.ogg differ diff --git a/sound/items/geiger/high1.ogg b/sound/items/geiger/high1.ogg new file mode 100644 index 0000000000..8725affdd4 Binary files /dev/null and b/sound/items/geiger/high1.ogg differ diff --git a/sound/items/geiger/high2.ogg b/sound/items/geiger/high2.ogg new file mode 100644 index 0000000000..f1e3868898 Binary files /dev/null and b/sound/items/geiger/high2.ogg differ diff --git a/sound/items/geiger/high3.ogg b/sound/items/geiger/high3.ogg new file mode 100644 index 0000000000..bdc5282a5c Binary files /dev/null and b/sound/items/geiger/high3.ogg differ diff --git a/sound/items/geiger/high4.ogg b/sound/items/geiger/high4.ogg new file mode 100644 index 0000000000..8e185d6f78 Binary files /dev/null and b/sound/items/geiger/high4.ogg differ diff --git a/sound/items/geiger/low1.ogg b/sound/items/geiger/low1.ogg new file mode 100644 index 0000000000..9bdb8bd327 Binary files /dev/null and b/sound/items/geiger/low1.ogg differ diff --git a/sound/items/geiger/low2.ogg b/sound/items/geiger/low2.ogg new file mode 100644 index 0000000000..ce4855f25f Binary files /dev/null and b/sound/items/geiger/low2.ogg differ diff --git a/sound/items/geiger/low3.ogg b/sound/items/geiger/low3.ogg new file mode 100644 index 0000000000..70aaea064f Binary files /dev/null and b/sound/items/geiger/low3.ogg differ diff --git a/sound/items/geiger/low4.ogg b/sound/items/geiger/low4.ogg new file mode 100644 index 0000000000..f36e3b7699 Binary files /dev/null and b/sound/items/geiger/low4.ogg differ diff --git a/sound/items/geiger/med1.ogg b/sound/items/geiger/med1.ogg new file mode 100644 index 0000000000..c062c4d2a8 Binary files /dev/null and b/sound/items/geiger/med1.ogg differ diff --git a/sound/items/geiger/med2.ogg b/sound/items/geiger/med2.ogg new file mode 100644 index 0000000000..210119a287 Binary files /dev/null and b/sound/items/geiger/med2.ogg differ diff --git a/sound/items/geiger/med3.ogg b/sound/items/geiger/med3.ogg new file mode 100644 index 0000000000..ed6f0f4d7f Binary files /dev/null and b/sound/items/geiger/med3.ogg differ diff --git a/sound/items/geiger/med4.ogg b/sound/items/geiger/med4.ogg new file mode 100644 index 0000000000..70635a97a3 Binary files /dev/null and b/sound/items/geiger/med4.ogg differ diff --git a/sound/items/geiger1.ogg b/sound/items/geiger1.ogg deleted file mode 100644 index b822085659..0000000000 Binary files a/sound/items/geiger1.ogg and /dev/null differ diff --git a/sound/items/geiger2.ogg b/sound/items/geiger2.ogg deleted file mode 100644 index 4c0d734463..0000000000 Binary files a/sound/items/geiger2.ogg and /dev/null differ diff --git a/sound/items/geiger3.ogg b/sound/items/geiger3.ogg deleted file mode 100644 index a9a5924d80..0000000000 Binary files a/sound/items/geiger3.ogg and /dev/null differ diff --git a/sound/items/geiger4.ogg b/sound/items/geiger4.ogg deleted file mode 100644 index dfad69866c..0000000000 Binary files a/sound/items/geiger4.ogg and /dev/null differ diff --git a/sound/items/geiger5.ogg b/sound/items/geiger5.ogg deleted file mode 100644 index 1e5f20913c..0000000000 Binary files a/sound/items/geiger5.ogg and /dev/null differ diff --git a/sound/items/geiger_weak1.ogg b/sound/items/geiger_weak1.ogg deleted file mode 100644 index cadfcde746..0000000000 Binary files a/sound/items/geiger_weak1.ogg and /dev/null differ diff --git a/sound/items/geiger_weak2.ogg b/sound/items/geiger_weak2.ogg deleted file mode 100644 index 12f54ae669..0000000000 Binary files a/sound/items/geiger_weak2.ogg and /dev/null differ diff --git a/sound/items/geiger_weak3.ogg b/sound/items/geiger_weak3.ogg deleted file mode 100644 index c935711aac..0000000000 Binary files a/sound/items/geiger_weak3.ogg and /dev/null differ diff --git a/sound/items/geiger_weak4.ogg b/sound/items/geiger_weak4.ogg deleted file mode 100644 index 2b17311a82..0000000000 Binary files a/sound/items/geiger_weak4.ogg and /dev/null differ diff --git a/sound/machines/fryer/deep_fryer_1.ogg b/sound/machines/fryer/deep_fryer_1.ogg new file mode 100644 index 0000000000..7b726c9de6 Binary files /dev/null and b/sound/machines/fryer/deep_fryer_1.ogg differ diff --git a/sound/machines/fryer/deep_fryer_2.ogg b/sound/machines/fryer/deep_fryer_2.ogg new file mode 100644 index 0000000000..4bd4be7d77 Binary files /dev/null and b/sound/machines/fryer/deep_fryer_2.ogg differ diff --git a/sound/machines/fryer/deep_fryer_emerge.ogg b/sound/machines/fryer/deep_fryer_emerge.ogg new file mode 100644 index 0000000000..a803dd4c67 Binary files /dev/null and b/sound/machines/fryer/deep_fryer_emerge.ogg differ diff --git a/sound/machines/fryer/deep_fryer_immerse.ogg b/sound/machines/fryer/deep_fryer_immerse.ogg new file mode 100644 index 0000000000..3c06b865ca Binary files /dev/null and b/sound/machines/fryer/deep_fryer_immerse.ogg differ diff --git a/sound/machines/generator/generator_end.ogg b/sound/machines/generator/generator_end.ogg new file mode 100644 index 0000000000..4397991167 Binary files /dev/null and b/sound/machines/generator/generator_end.ogg differ diff --git a/sound/machines/generator/generator_mid1.ogg b/sound/machines/generator/generator_mid1.ogg new file mode 100644 index 0000000000..10a0d01a7e Binary files /dev/null and b/sound/machines/generator/generator_mid1.ogg differ diff --git a/sound/machines/generator/generator_mid2.ogg b/sound/machines/generator/generator_mid2.ogg new file mode 100644 index 0000000000..77656772cc Binary files /dev/null and b/sound/machines/generator/generator_mid2.ogg differ diff --git a/sound/machines/generator/generator_mid3.ogg b/sound/machines/generator/generator_mid3.ogg new file mode 100644 index 0000000000..812a10e6fc Binary files /dev/null and b/sound/machines/generator/generator_mid3.ogg differ diff --git a/sound/machines/generator/generator_start.ogg b/sound/machines/generator/generator_start.ogg new file mode 100644 index 0000000000..53f734388e Binary files /dev/null and b/sound/machines/generator/generator_start.ogg differ diff --git a/sound/machines/microwave/microwave-end.ogg b/sound/machines/microwave/microwave-end.ogg new file mode 100644 index 0000000000..1c13d87e17 Binary files /dev/null and b/sound/machines/microwave/microwave-end.ogg differ diff --git a/sound/machines/microwave/microwave-mid1.ogg b/sound/machines/microwave/microwave-mid1.ogg new file mode 100644 index 0000000000..60a0cc8ec5 Binary files /dev/null and b/sound/machines/microwave/microwave-mid1.ogg differ diff --git a/sound/machines/microwave/microwave-mid2.ogg b/sound/machines/microwave/microwave-mid2.ogg new file mode 100644 index 0000000000..3b3dd32c28 Binary files /dev/null and b/sound/machines/microwave/microwave-mid2.ogg differ diff --git a/sound/machines/microwave/microwave-start.ogg b/sound/machines/microwave/microwave-start.ogg new file mode 100644 index 0000000000..5e59c78e8a Binary files /dev/null and b/sound/machines/microwave/microwave-start.ogg differ diff --git a/sound/machines/shower/shower_end.ogg b/sound/machines/shower/shower_end.ogg new file mode 100644 index 0000000000..80b93af39e Binary files /dev/null and b/sound/machines/shower/shower_end.ogg differ diff --git a/sound/machines/shower/shower_mid1.ogg b/sound/machines/shower/shower_mid1.ogg new file mode 100644 index 0000000000..e1ae5a0c45 Binary files /dev/null and b/sound/machines/shower/shower_mid1.ogg differ diff --git a/sound/machines/shower/shower_mid2.ogg b/sound/machines/shower/shower_mid2.ogg new file mode 100644 index 0000000000..4a54acd352 Binary files /dev/null and b/sound/machines/shower/shower_mid2.ogg differ diff --git a/sound/machines/shower/shower_mid3.ogg b/sound/machines/shower/shower_mid3.ogg new file mode 100644 index 0000000000..8b4776a9b9 Binary files /dev/null and b/sound/machines/shower/shower_mid3.ogg differ diff --git a/sound/machines/shower/shower_start.ogg b/sound/machines/shower/shower_start.ogg new file mode 100644 index 0000000000..e5529f401b Binary files /dev/null and b/sound/machines/shower/shower_start.ogg differ diff --git a/sound/machines/sm/supermatter1.ogg b/sound/machines/sm/supermatter1.ogg new file mode 100644 index 0000000000..1860e78800 Binary files /dev/null and b/sound/machines/sm/supermatter1.ogg differ diff --git a/sound/machines/sm/supermatter2.ogg b/sound/machines/sm/supermatter2.ogg new file mode 100644 index 0000000000..fb2d39fe26 Binary files /dev/null and b/sound/machines/sm/supermatter2.ogg differ diff --git a/sound/machines/sm/supermatter3.ogg b/sound/machines/sm/supermatter3.ogg new file mode 100644 index 0000000000..93ac3d505b Binary files /dev/null and b/sound/machines/sm/supermatter3.ogg differ diff --git a/sound/weapons/Gunshot.ogg b/sound/weapons/Gunshot1.ogg similarity index 100% rename from sound/weapons/Gunshot.ogg rename to sound/weapons/Gunshot1.ogg diff --git a/sound/weapons/svd_shot.ogg b/sound/weapons/Gunshot_SVD.ogg similarity index 100% rename from sound/weapons/svd_shot.ogg rename to sound/weapons/Gunshot_SVD.ogg diff --git a/sound/weapons/cannon.ogg b/sound/weapons/Gunshot_cannon.ogg similarity index 100% rename from sound/weapons/cannon.ogg rename to sound/weapons/Gunshot_cannon.ogg diff --git a/sound/weapons/deagle.ogg b/sound/weapons/Gunshot_deagle.ogg similarity index 100% rename from sound/weapons/deagle.ogg rename to sound/weapons/Gunshot_deagle.ogg diff --git a/sound/weapons/gunshot/gunshot2.ogg b/sound/weapons/Gunshot_generic_rifle.ogg similarity index 100% rename from sound/weapons/gunshot/gunshot2.ogg rename to sound/weapons/Gunshot_generic_rifle.ogg diff --git a/sound/weapons/gunshot/gunshot3.ogg b/sound/weapons/Gunshot_machinegun.ogg similarity index 100% rename from sound/weapons/gunshot/gunshot3.ogg rename to sound/weapons/Gunshot_machinegun.ogg diff --git a/sound/weapons/gunshot/shotgun.ogg b/sound/weapons/Gunshot_shotgun.ogg similarity index 100% rename from sound/weapons/gunshot/shotgun.ogg rename to sound/weapons/Gunshot_shotgun.ogg diff --git a/sound/weapons/gunshot/sniper.ogg b/sound/weapons/Gunshot_sniper.ogg similarity index 100% rename from sound/weapons/gunshot/sniper.ogg rename to sound/weapons/Gunshot_sniper.ogg diff --git a/sound/weapons/grenade_launcher.ogg b/sound/weapons/grenade_launcher.ogg new file mode 100644 index 0000000000..261c222dea Binary files /dev/null and b/sound/weapons/grenade_launcher.ogg differ diff --git a/sound/weapons/gunshot/gunshot.ogg b/sound/weapons/gunshot/gunshot.ogg deleted file mode 100644 index 1eaf4043a4..0000000000 Binary files a/sound/weapons/gunshot/gunshot.ogg and /dev/null differ diff --git a/sound/weapons/gunshot/gunshot_pistol.ogg b/sound/weapons/gunshot/gunshot_pistol.ogg deleted file mode 100644 index c9d6322992..0000000000 Binary files a/sound/weapons/gunshot/gunshot_pistol.ogg and /dev/null differ diff --git a/sound/weapons/gunshot/gunshot_smg.ogg b/sound/weapons/gunshot/gunshot_smg.ogg deleted file mode 100644 index 5c0000bb32..0000000000 Binary files a/sound/weapons/gunshot/gunshot_smg.ogg and /dev/null differ diff --git a/sound/weapons/gunshot/gunshot_strong.ogg b/sound/weapons/gunshot/gunshot_strong.ogg deleted file mode 100644 index 6794bfa08e..0000000000 Binary files a/sound/weapons/gunshot/gunshot_strong.ogg and /dev/null differ diff --git a/sound/weapons/machinegun.ogg b/sound/weapons/machinegun.ogg deleted file mode 100644 index 49c2b0c554..0000000000 Binary files a/sound/weapons/machinegun.ogg and /dev/null differ diff --git a/sound/weapons/rifleshot.ogg b/sound/weapons/rifleshot.ogg deleted file mode 100644 index 4b26d5e7e6..0000000000 Binary files a/sound/weapons/rifleshot.ogg and /dev/null differ diff --git a/sound/weapons/shotgun.ogg b/sound/weapons/shotgun.ogg deleted file mode 100644 index f10004d1ee..0000000000 Binary files a/sound/weapons/shotgun.ogg and /dev/null differ diff --git a/sound/weapons/sniper.ogg b/sound/weapons/sniper.ogg deleted file mode 100644 index aabe4601ba..0000000000 Binary files a/sound/weapons/sniper.ogg and /dev/null differ diff --git a/tools/mapmerge/1prepare_map.sh b/tools/mapmerge/1prepare_map.sh new file mode 100755 index 0000000000..ee4fe2f5a5 --- /dev/null +++ b/tools/mapmerge/1prepare_map.sh @@ -0,0 +1,6 @@ +#!/bin/sh +cd ../../maps/southern_cross + +for f in *.dmm; +do cp $f $f.backup; +done diff --git a/tools/mapmerge/2clean_map.sh b/tools/mapmerge/2clean_map.sh new file mode 100755 index 0000000000..71c16f7999 --- /dev/null +++ b/tools/mapmerge/2clean_map.sh @@ -0,0 +1,4 @@ +#!/bin/sh +for f in ../../maps/southern_cross/*.dmm; +do java -jar MapPatcher.jar -clean $f.backup $f $f; +done diff --git a/vorestation.dme b/vorestation.dme index a4b53f2eb8..f85b64b468 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -16,6 +16,7 @@ #include "code\_map_tests.dm" #include "code\_unit_tests.dm" #include "code\global.dm" +#include "code\global_init.dm" #include "code\global_vr.dm" #include "code\hub.dm" #include "code\names.dm" @@ -23,6 +24,7 @@ #include "code\world.dm" #include "code\__datastructures\globals.dm" #include "code\__defines\_compile_options.dm" +#include "code\__defines\_lists.dm" #include "code\__defines\_planes+layers.dm" #include "code\__defines\_planes+layers_vr.dm" #include "code\__defines\_tick.dm" @@ -38,10 +40,12 @@ #include "code\__defines\construction.dm" #include "code\__defines\damage_organs.dm" #include "code\__defines\dna.dm" +#include "code\__defines\flags.dm" #include "code\__defines\gamemode.dm" #include "code\__defines\holomap.dm" #include "code\__defines\integrated_circuits.dm" #include "code\__defines\inventory_sizes.dm" +#include "code\__defines\is_helpers.dm" #include "code\__defines\items_clothing.dm" #include "code\__defines\lighting.dm" #include "code\__defines\machinery.dm" @@ -72,6 +76,7 @@ #include "code\__defines\typeids.dm" #include "code\__defines\unit_tests.dm" #include "code\__defines\vote.dm" +#include "code\__defines\vv.dm" #include "code\__defines\xenoarcheaology.dm" #include "code\__defines\ZAS.dm" #include "code\_compatibility\509\_JSON.dm" @@ -79,11 +84,13 @@ #include "code\_compatibility\509\JSON Writer.dm" #include "code\_compatibility\509\text.dm" #include "code\_compatibility\509\type2type.dm" +#include "code\_global_vars\bitfields.dm" #include "code\_global_vars\misc.dm" #include "code\_global_vars\mobs.dm" #include "code\_global_vars\sensitive.dm" #include "code\_global_vars\lists\mapping.dm" #include "code\_helpers\_global_objects.dm" +#include "code\_helpers\_lists.dm" #include "code\_helpers\atmospherics.dm" #include "code\_helpers\events.dm" #include "code\_helpers\files.dm" @@ -92,10 +99,8 @@ #include "code\_helpers\global_lists_vr.dm" #include "code\_helpers\icons.dm" #include "code\_helpers\icons_vr.dm" -#include "code\_helpers\lists.dm" #include "code\_helpers\logging.dm" #include "code\_helpers\logging_vr.dm" -#include "code\_helpers\maths.dm" #include "code\_helpers\matrices.dm" #include "code\_helpers\mobs.dm" #include "code\_helpers\names.dm" @@ -109,7 +114,7 @@ #include "code\_helpers\type2type_vr.dm" #include "code\_helpers\unsorted.dm" #include "code\_helpers\unsorted_vr.dm" -#include "code\_helpers\vector.dm" +#include "code\_helpers\view.dm" #include "code\_helpers\sorts\__main.dm" #include "code\_helpers\sorts\comparators.dm" #include "code\_helpers\sorts\TimSort.dm" @@ -139,7 +144,6 @@ #include "code\_onclick\hud\robot.dm" #include "code\_onclick\hud\robot_vr.dm" #include "code\_onclick\hud\screen_objects.dm" -#include "code\_onclick\hud\screen_objects_vr.dm" #include "code\_onclick\hud\spell_screen_objects.dm" #include "code\ATMOSPHERICS\_atmos_setup.dm" #include "code\ATMOSPHERICS\_atmospherics_helpers.dm" @@ -201,40 +205,45 @@ #include "code\controllers\verbs.dm" #include "code\controllers\observer_listener\atom\observer.dm" #include "code\controllers\Processes\alarm.dm" -#include "code\controllers\Processes\chemistry.dm" #include "code\controllers\Processes\emergencyShuttle.dm" -#include "code\controllers\Processes\event.dm" #include "code\controllers\Processes\game_master.dm" -#include "code\controllers\Processes\inactivity.dm" -#include "code\controllers\Processes\nanoui.dm" -#include "code\controllers\Processes\obj.dm" #include "code\controllers\Processes\radiation.dm" -#include "code\controllers\Processes\scheduler.dm" -#include "code\controllers\Processes\sun.dm" #include "code\controllers\Processes\supply.dm" #include "code\controllers\Processes\ticker.dm" -#include "code\controllers\Processes\turf.dm" #include "code\controllers\ProcessScheduler\core\process.dm" #include "code\controllers\ProcessScheduler\core\processScheduler.dm" +#include "code\controllers\subsystems\ai.dm" #include "code\controllers\subsystems\air.dm" #include "code\controllers\subsystems\airflow.dm" #include "code\controllers\subsystems\atoms.dm" #include "code\controllers\subsystems\bellies_vr.dm" #include "code\controllers\subsystems\circuits.dm" +#include "code\controllers\subsystems\events.dm" #include "code\controllers\subsystems\garbage.dm" #include "code\controllers\subsystems\holomaps.dm" +#include "code\controllers\subsystems\inactivity.dm" #include "code\controllers\subsystems\lighting.dm" #include "code\controllers\subsystems\machines.dm" #include "code\controllers\subsystems\mapping_vr.dm" #include "code\controllers\subsystems\mobs.dm" +#include "code\controllers\subsystems\nanoui.dm" #include "code\controllers\subsystems\orbits.dm" #include "code\controllers\subsystems\overlays.dm" #include "code\controllers\subsystems\persist_vr.dm" #include "code\controllers\subsystems\planets.dm" #include "code\controllers\subsystems\shuttles.dm" +#include "code\controllers\subsystems\sun.dm" +#include "code\controllers\subsystems\time_track.dm" +#include "code\controllers\subsystems\timer.dm" #include "code\controllers\subsystems\transcore_vr.dm" #include "code\controllers\subsystems\vote.dm" #include "code\controllers\subsystems\xenoarch.dm" +#include "code\controllers\subsystems\processing\chemistry.dm" +#include "code\controllers\subsystems\processing\fastprocess.dm" +#include "code\controllers\subsystems\processing\obj.dm" +#include "code\controllers\subsystems\processing\processing.dm" +#include "code\controllers\subsystems\processing\projectiles.dm" +#include "code\controllers\subsystems\processing\turfs.dm" #include "code\datums\ai_law_sets.dm" #include "code\datums\ai_laws.dm" #include "code\datums\beam.dm" @@ -244,6 +253,7 @@ #include "code\datums\computerfiles.dm" #include "code\datums\datacore.dm" #include "code\datums\datum.dm" +#include "code\datums\datumvars.dm" #include "code\datums\EPv2.dm" #include "code\datums\ghost_query.dm" #include "code\datums\hierarchy.dm" @@ -253,6 +263,7 @@ #include "code\datums\mutable_appearance.dm" #include "code\datums\orbit.dm" #include "code\datums\organs.dm" +#include "code\datums\position_point_vector.dm" #include "code\datums\progressbar.dm" #include "code\datums\recipe.dm" #include "code\datums\riding.dm" @@ -284,6 +295,10 @@ #include "code\datums\locations\tau_ceti.dm" #include "code\datums\locations\uueoa_esa.dm" #include "code\datums\locations\vir.dm" +#include "code\datums\looping_sounds\_looping_sound.dm" +#include "code\datums\looping_sounds\item_sounds.dm" +#include "code\datums\looping_sounds\machinery_sounds.dm" +#include "code\datums\looping_sounds\weather_sounds.dm" #include "code\datums\observation\_debug.dm" #include "code\datums\observation\_defines.dm" #include "code\datums\observation\destroyed.dm" @@ -293,9 +308,9 @@ #include "code\datums\observation\logged_in.dm" #include "code\datums\observation\moved.dm" #include "code\datums\observation\observation.dm" -#include "code\datums\observation\task_triggered.dm" #include "code\datums\observation\turf_changed.dm" #include "code\datums\observation\unequipped.dm" +#include "code\datums\observation\z_moved.dm" #include "code\datums\observation\~cleanup.dm" #include "code\datums\outfits\_defines.dm" #include "code\datums\outfits\horror_killers.dm" @@ -351,7 +366,6 @@ #include "code\datums\supplypacks\robotics.dm" #include "code\datums\supplypacks\robotics_vr.dm" #include "code\datums\supplypacks\science.dm" -#include "code\datums\supplypacks\science_vr.dm" #include "code\datums\supplypacks\security.dm" #include "code\datums\supplypacks\security_vr.dm" #include "code\datums\supplypacks\supply.dm" @@ -419,6 +433,7 @@ #include "code\game\skincmd.dm" #include "code\game\sound.dm" #include "code\game\trader_visit.dm" +#include "code\game\world.dm" #include "code\game\antagonist\_antagonist_setup.dm" #include "code\game\antagonist\antagonist.dm" #include "code\game\antagonist\antagonist_add.dm" @@ -519,6 +534,7 @@ #include "code\game\gamemodes\cult\narsie.dm" #include "code\game\gamemodes\cult\ritual.dm" #include "code\game\gamemodes\cult\runes.dm" +#include "code\game\gamemodes\cult\soulstone.dm" #include "code\game\gamemodes\cult\talisman.dm" #include "code\game\gamemodes\cult\cultify\mob.dm" #include "code\game\gamemodes\cult\cultify\obj.dm" @@ -574,7 +590,6 @@ #include "code\game\gamemodes\technomancer\spell_objs_helpers.dm" #include "code\game\gamemodes\technomancer\technomancer.dm" #include "code\game\gamemodes\technomancer\assistance\assistance.dm" -#include "code\game\gamemodes\technomancer\assistance\golem.dm" #include "code\game\gamemodes\technomancer\devices\boots_of_speed.dm" #include "code\game\gamemodes\technomancer\devices\disposable_teleporter.dm" #include "code\game\gamemodes\technomancer\devices\gloves_of_regen.dm" @@ -922,10 +937,21 @@ #include "code\game\objects\effects\decals\Cleanable\tracks.dm" #include "code\game\objects\effects\decals\posters\bs12.dm" #include "code\game\objects\effects\decals\posters\polarisposters.dm" +#include "code\game\objects\effects\map_effects\beam_point.dm" +#include "code\game\objects\effects\map_effects\effect_emitter.dm" +#include "code\game\objects\effects\map_effects\map_effects.dm" +#include "code\game\objects\effects\map_effects\perma_light.dm" +#include "code\game\objects\effects\map_effects\radiation_emitter.dm" +#include "code\game\objects\effects\map_effects\screen_shaker.dm" +#include "code\game\objects\effects\map_effects\sound_emitter.dm" #include "code\game\objects\effects\spawners\bombspawner.dm" #include "code\game\objects\effects\spawners\gibspawner.dm" #include "code\game\objects\effects\temporary_visuals\miscellaneous.dm" -#include "code\game\objects\effects\temporary_visuals\temproary_visual.dm" +#include "code\game\objects\effects\temporary_visuals\temporary_visual.dm" +#include "code\game\objects\effects\temporary_visuals\projectiles\impact.dm" +#include "code\game\objects\effects\temporary_visuals\projectiles\muzzle.dm" +#include "code\game\objects\effects\temporary_visuals\projectiles\projectile_effects.dm" +#include "code\game\objects\effects\temporary_visuals\projectiles\tracer.dm" #include "code\game\objects\items\antag_spawners.dm" #include "code\game\objects\items\apc_frame.dm" #include "code\game\objects\items\blueprints.dm" @@ -934,6 +960,7 @@ #include "code\game\objects\items\contraband_vr.dm" #include "code\game\objects\items\crayons.dm" #include "code\game\objects\items\glassjar.dm" +#include "code\game\objects\items\godfigures.dm" #include "code\game\objects\items\gunbox.dm" #include "code\game\objects\items\gunbox_vr.dm" #include "code\game\objects\items\latexballoon.dm" @@ -1172,10 +1199,12 @@ #include "code\game\objects\random\mob.dm" #include "code\game\objects\random\random_vr.dm" #include "code\game\objects\random\spacesuits.dm" +#include "code\game\objects\random\unidentified\medicine.dm" #include "code\game\objects\structures\barsign.dm" #include "code\game\objects\structures\bedsheet_bin.dm" #include "code\game\objects\structures\bonfire.dm" #include "code\game\objects\structures\catwalk.dm" +#include "code\game\objects\structures\cliff.dm" #include "code\game\objects\structures\coathanger.dm" #include "code\game\objects\structures\curtains.dm" #include "code\game\objects\structures\displaycase.dm" @@ -1183,6 +1212,7 @@ #include "code\game\objects\structures\door_assembly.dm" #include "code\game\objects\structures\electricchair.dm" #include "code\game\objects\structures\extinguisher.dm" +#include "code\game\objects\structures\fence.dm" #include "code\game\objects\structures\fitness.dm" #include "code\game\objects\structures\flora.dm" #include "code\game\objects\structures\flora_vr.dm" @@ -1194,6 +1224,7 @@ #include "code\game\objects\structures\janicart.dm" #include "code\game\objects\structures\kitchen_spike.dm" #include "code\game\objects\structures\lattice.dm" +#include "code\game\objects\structures\lightpost.dm" #include "code\game\objects\structures\loot_piles.dm" #include "code\game\objects\structures\map_blocker_vr.dm" #include "code\game\objects\structures\mirror.dm" @@ -1288,6 +1319,7 @@ #include "code\game\turfs\simulated\floor_static.dm" #include "code\game\turfs\simulated\floor_types.dm" #include "code\game\turfs\simulated\floor_types_vr.dm" +#include "code\game\turfs\simulated\lava.dm" #include "code\game\turfs\simulated\wall_attacks.dm" #include "code\game\turfs\simulated\wall_icon.dm" #include "code\game\turfs\simulated\wall_types.dm" @@ -1403,24 +1435,43 @@ #include "code\modules\admin\verbs\lightning_strike.dm" #include "code\modules\admin\verbs\map_template_loadverb.dm" #include "code\modules\admin\verbs\mapping.dm" -#include "code\modules\admin\verbs\massmodvar.dm" -#include "code\modules\admin\verbs\modifyvariables.dm" #include "code\modules\admin\verbs\panicbunker.dm" #include "code\modules\admin\verbs\playsound.dm" #include "code\modules\admin\verbs\possess.dm" #include "code\modules\admin\verbs\pray.dm" #include "code\modules\admin\verbs\randomverbs.dm" -#include "code\modules\admin\verbs\SDQL.dm" -#include "code\modules\admin\verbs\SDQL_2.dm" -#include "code\modules\admin\verbs\SDQL_2_parser.dm" #include "code\modules\admin\verbs\smite.dm" #include "code\modules\admin\verbs\smite_vr.dm" #include "code\modules\admin\verbs\striketeam.dm" #include "code\modules\admin\verbs\ticklag.dm" #include "code\modules\admin\verbs\tripAI.dm" -#include "code\modules\admin\view_variables\helpers.dm" +#include "code\modules\admin\verbs\SDQL2\SDQL_2.dm" +#include "code\modules\admin\verbs\SDQL2\SDQL_2_parser.dm" +#include "code\modules\admin\verbs\SDQL2\SDQL_2_wrappers.dm" +#include "code\modules\admin\view_variables\admin_delete.dm" +#include "code\modules\admin\view_variables\debug_variables.dm" +#include "code\modules\admin\view_variables\get_variables.dm" +#include "code\modules\admin\view_variables\helpers_deprecated.dm" +#include "code\modules\admin\view_variables\mass_edit_variables.dm" +#include "code\modules\admin\view_variables\modify_variables.dm" #include "code\modules\admin\view_variables\topic.dm" #include "code\modules\admin\view_variables\view_variables.dm" +#include "code\modules\ai\_defines.dm" +#include "code\modules\ai\ai_holder.dm" +#include "code\modules\ai\ai_holder_combat.dm" +#include "code\modules\ai\ai_holder_communication.dm" +#include "code\modules\ai\ai_holder_cooperation.dm" +#include "code\modules\ai\ai_holder_debug.dm" +#include "code\modules\ai\ai_holder_disabled.dm" +#include "code\modules\ai\ai_holder_fleeing.dm" +#include "code\modules\ai\ai_holder_follow.dm" +#include "code\modules\ai\ai_holder_movement.dm" +#include "code\modules\ai\ai_holder_pathfinding.dm" +#include "code\modules\ai\ai_holder_targeting.dm" +#include "code\modules\ai\interfaces.dm" +#include "code\modules\ai\say_list.dm" +#include "code\modules\ai\aI_holder_subtypes\simple_mob_ai.dm" +#include "code\modules\ai\aI_holder_subtypes\slime_xenobio_ai.dm" #include "code\modules\alarm\alarm.dm" #include "code\modules\alarm\alarm_handler.dm" #include "code\modules\alarm\atmosphere_alarm.dm" @@ -1459,8 +1510,6 @@ #include "code\modules\blob2\blobs\normal.dm" #include "code\modules\blob2\blobs\resource.dm" #include "code\modules\blob2\blobs\shield.dm" -#include "code\modules\blob2\mobs\blob_mob.dm" -#include "code\modules\blob2\mobs\spore.dm" #include "code\modules\blob2\overmind\overmind.dm" #include "code\modules\blob2\overmind\powers.dm" #include "code\modules\blob2\overmind\types.dm" @@ -1706,8 +1755,6 @@ #include "code\modules\events\event_manager.dm" #include "code\modules\events\gravity.dm" #include "code\modules\events\grid_check.dm" -#include "code\modules\events\grubinfestation_vr.dm" -#include "code\modules\events\ian_storm_vr.dm" #include "code\modules\events\infestation.dm" #include "code\modules\events\ion_storm.dm" #include "code\modules\events\meteor_strike_vr.dm" @@ -1849,6 +1896,8 @@ #include "code\modules\hydroponics\trays\tray_soil.dm" #include "code\modules\hydroponics\trays\tray_tools.dm" #include "code\modules\hydroponics\trays\tray_update_icons.dm" +#include "code\modules\identification\identification.dm" +#include "code\modules\identification\item_procs.dm" #include "code\modules\integrated_electronics\_defines.dm" #include "code\modules\integrated_electronics\core\assemblies.dm" #include "code\modules\integrated_electronics\core\detailer.dm" @@ -2094,6 +2143,7 @@ #include "code\modules\mob\living\carbon\human\human_movement.dm" #include "code\modules\mob\living\carbon\human\human_organs.dm" #include "code\modules\mob\living\carbon\human\human_powers.dm" +#include "code\modules\mob\living\carbon\human\human_resist.dm" #include "code\modules\mob\living\carbon\human\human_species.dm" #include "code\modules\mob\living\carbon\human\human_species_vr.dm" #include "code\modules\mob\living\carbon\human\human_vr.dm" @@ -2232,98 +2282,136 @@ #include "code\modules\mob\living\silicon\robot\subtypes\lost_drone.dm" #include "code\modules\mob\living\silicon\robot\subtypes\syndicate.dm" #include "code\modules\mob\living\simple_animal\corpse.dm" -#include "code\modules\mob\living\simple_animal\simple_animal.dm" -#include "code\modules\mob\living\simple_animal\simple_animal_vr.dm" -#include "code\modules\mob\living\simple_animal\simple_hud.dm" -#include "code\modules\mob\living\simple_animal\aliens\alien.dm" -#include "code\modules\mob\living\simple_animal\aliens\creature.dm" -#include "code\modules\mob\living\simple_animal\aliens\drone.dm" -#include "code\modules\mob\living\simple_animal\aliens\faithless.dm" -#include "code\modules\mob\living\simple_animal\aliens\hivebot.dm" -#include "code\modules\mob\living\simple_animal\aliens\mimic.dm" -#include "code\modules\mob\living\simple_animal\aliens\shade.dm" -#include "code\modules\mob\living\simple_animal\aliens\statue.dm" -#include "code\modules\mob\living\simple_animal\animals\bat.dm" -#include "code\modules\mob\living\simple_animal\animals\bear.dm" -#include "code\modules\mob\living\simple_animal\animals\birds_vr.dm" -#include "code\modules\mob\living\simple_animal\animals\carp.dm" -#include "code\modules\mob\living\simple_animal\animals\cat.dm" -#include "code\modules\mob\living\simple_animal\animals\cat_vr.dm" -#include "code\modules\mob\living\simple_animal\animals\corgi.dm" -#include "code\modules\mob\living\simple_animal\animals\corgi_vr.dm" -#include "code\modules\mob\living\simple_animal\animals\crab.dm" -#include "code\modules\mob\living\simple_animal\animals\farm_animals.dm" -#include "code\modules\mob\living\simple_animal\animals\fish.dm" -#include "code\modules\mob\living\simple_animal\animals\fish_vr.dm" -#include "code\modules\mob\living\simple_animal\animals\fluffy_vr.dm" -#include "code\modules\mob\living\simple_animal\animals\fox_vr.dm" -#include "code\modules\mob\living\simple_animal\animals\giant_spider.dm" -#include "code\modules\mob\living\simple_animal\animals\giant_spider_vr.dm" -#include "code\modules\mob\living\simple_animal\animals\goose.dm" -#include "code\modules\mob\living\simple_animal\animals\lizard.dm" -#include "code\modules\mob\living\simple_animal\animals\miscellaneous.dm" -#include "code\modules\mob\living\simple_animal\animals\mouse.dm" -#include "code\modules\mob\living\simple_animal\animals\mouse_vr.dm" -#include "code\modules\mob\living\simple_animal\animals\parrot.dm" -#include "code\modules\mob\living\simple_animal\animals\penguin.dm" -#include "code\modules\mob\living\simple_animal\animals\pike_vr.dm" -#include "code\modules\mob\living\simple_animal\animals\slime.dm" -#include "code\modules\mob\living\simple_animal\animals\snake_vr.dm" -#include "code\modules\mob\living\simple_animal\animals\spiderbot.dm" -#include "code\modules\mob\living\simple_animal\animals\tomato.dm" -#include "code\modules\mob\living\simple_animal\animals\tree.dm" -#include "code\modules\mob\living\simple_animal\animals\worm.dm" -#include "code\modules\mob\living\simple_animal\animals\sif_wildlife\diyaab.dm" -#include "code\modules\mob\living\simple_animal\animals\sif_wildlife\savik.dm" -#include "code\modules\mob\living\simple_animal\animals\sif_wildlife\shantak.dm" -#include "code\modules\mob\living\simple_animal\borer\borer.dm" -#include "code\modules\mob\living\simple_animal\borer\borer_captive.dm" -#include "code\modules\mob\living\simple_animal\borer\borer_powers.dm" -#include "code\modules\mob\living\simple_animal\borer\say.dm" -#include "code\modules\mob\living\simple_animal\constructs\constructs.dm" -#include "code\modules\mob\living\simple_animal\constructs\soulstone.dm" -#include "code\modules\mob\living\simple_animal\humanoids\clown.dm" -#include "code\modules\mob\living\simple_animal\humanoids\head.dm" -#include "code\modules\mob\living\simple_animal\humanoids\mechamobs.dm" -#include "code\modules\mob\living\simple_animal\humanoids\pirate.dm" -#include "code\modules\mob\living\simple_animal\humanoids\russian.dm" -#include "code\modules\mob\living\simple_animal\humanoids\syndicate.dm" -#include "code\modules\mob\living\simple_animal\slime\ai.dm" -#include "code\modules\mob\living\simple_animal\slime\combat.dm" -#include "code\modules\mob\living\simple_animal\slime\death.dm" -#include "code\modules\mob\living\simple_animal\slime\life.dm" -#include "code\modules\mob\living\simple_animal\slime\slime.dm" -#include "code\modules\mob\living\simple_animal\slime\subtypes.dm" -#include "code\modules\mob\living\simple_animal\vore\bee.dm" -#include "code\modules\mob\living\simple_animal\vore\carp.dm" -#include "code\modules\mob\living\simple_animal\vore\catgirl.dm" -#include "code\modules\mob\living\simple_animal\vore\corrupt_hounds.dm" -#include "code\modules\mob\living\simple_animal\vore\deathclaw.dm" -#include "code\modules\mob\living\simple_animal\vore\dino.dm" -#include "code\modules\mob\living\simple_animal\vore\dragon.dm" -#include "code\modules\mob\living\simple_animal\vore\fennec.dm" -#include "code\modules\mob\living\simple_animal\vore\fennix.dm" -#include "code\modules\mob\living\simple_animal\vore\frog.dm" -#include "code\modules\mob\living\simple_animal\vore\gaslamp.dm" -#include "code\modules\mob\living\simple_animal\vore\hippo.dm" -#include "code\modules\mob\living\simple_animal\vore\horse.dm" -#include "code\modules\mob\living\simple_animal\vore\jelly.dm" -#include "code\modules\mob\living\simple_animal\vore\otie.dm" -#include "code\modules\mob\living\simple_animal\vore\panther.dm" -#include "code\modules\mob\living\simple_animal\vore\rat.dm" -#include "code\modules\mob\living\simple_animal\vore\redpanda.dm" -#include "code\modules\mob\living\simple_animal\vore\snake.dm" -#include "code\modules\mob\living\simple_animal\vore\solargrub.dm" -#include "code\modules\mob\living\simple_animal\vore\solargrub_larva.dm" -#include "code\modules\mob\living\simple_animal\vore\wolf.dm" -#include "code\modules\mob\living\simple_animal\vore\wolfgirl.dm" -#include "code\modules\mob\living\simple_animal\vore\zz_vore_overrides.dm" -#include "code\modules\mob\living\simple_animal\vore\shadekin\_defines.dm" -#include "code\modules\mob\living\simple_animal\vore\shadekin\ability_objects.dm" -#include "code\modules\mob\living\simple_animal\vore\shadekin\ability_procs.dm" -#include "code\modules\mob\living\simple_animal\vore\shadekin\shadekin.dm" -#include "code\modules\mob\living\simple_animal\vore\shadekin\types.dm" -#include "code\modules\mob\living\simple_animal\vore\shadekin\~defines.dm" +#include "code\modules\mob\living\simple_mob\appearance.dm" +#include "code\modules\mob\living\simple_mob\combat.dm" +#include "code\modules\mob\living\simple_mob\defense.dm" +#include "code\modules\mob\living\simple_mob\hands.dm" +#include "code\modules\mob\living\simple_mob\life.dm" +#include "code\modules\mob\living\simple_mob\on_click.dm" +#include "code\modules\mob\living\simple_mob\simple_hud.dm" +#include "code\modules\mob\living\simple_mob\simple_mob.dm" +#include "code\modules\mob\living\simple_mob\simple_mob_vr.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\animal.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\borer\borer.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\borer\borer_captive.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\borer\borer_powers.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\farm animals\chicken.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\farm animals\cow.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\farm animals\goat.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\giant_spider\_giant_spider.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\giant_spider\carrier.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\giant_spider\electric.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\giant_spider\frost.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\giant_spider\giant_spider_vr.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\giant_spider\hunter.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\giant_spider\lurker.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\giant_spider\nurse.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\giant_spider\pepper.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\giant_spider\phorogenic.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\giant_spider\thermic.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\giant_spider\tunneler.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\giant_spider\webslinger.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\passive\crab.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\passive\fish.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\passive\fish_vr.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\passive\lizard.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\passive\misc.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\passive\mouse.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\passive\passive.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\passive\penguin.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\pets\bird.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\pets\cat.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\pets\cat_vr.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\pets\dog.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\pets\fox_vr.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\pets\parrot.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\sif\diyaab.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\sif\fluffy_vr.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\sif\hooligan_crab.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\sif\savik.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\sif\shantak.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\sif\sif.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\space\alien.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\space\bats.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\space\bear.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\space\carp.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\space\gaslamp_vr.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\space\goose.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\space\mimic_vr.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\space\snake_vr.dm" +#include "code\modules\mob\living\simple_mob\subtypes\animal\space\space.dm" +#include "code\modules\mob\living\simple_mob\subtypes\blob\blob.dm" +#include "code\modules\mob\living\simple_mob\subtypes\blob\spore.dm" +#include "code\modules\mob\living\simple_mob\subtypes\humanoid\clown.dm" +#include "code\modules\mob\living\simple_mob\subtypes\humanoid\humanoid.dm" +#include "code\modules\mob\living\simple_mob\subtypes\humanoid\pirates.dm" +#include "code\modules\mob\living\simple_mob\subtypes\humanoid\russian.dm" +#include "code\modules\mob\living\simple_mob\subtypes\humanoid\mercs\mercs.dm" +#include "code\modules\mob\living\simple_mob\subtypes\illusion\illusion.dm" +#include "code\modules\mob\living\simple_mob\subtypes\mechanical\combat_drone.dm" +#include "code\modules\mob\living\simple_mob\subtypes\mechanical\golem.dm" +#include "code\modules\mob\living\simple_mob\subtypes\mechanical\mechanical.dm" +#include "code\modules\mob\living\simple_mob\subtypes\mechanical\viscerator.dm" +#include "code\modules\mob\living\simple_mob\subtypes\mechanical\hivebot\hivebot.dm" +#include "code\modules\mob\living\simple_mob\subtypes\mechanical\hivebot\ranged_damage.dm" +#include "code\modules\mob\living\simple_mob\subtypes\mechanical\hivebot\support.dm" +#include "code\modules\mob\living\simple_mob\subtypes\mechanical\hivebot\tank.dm" +#include "code\modules\mob\living\simple_mob\subtypes\mechanical\mecha\adv_dark_gygax.dm" +#include "code\modules\mob\living\simple_mob\subtypes\mechanical\mecha\combat_mecha.dm" +#include "code\modules\mob\living\simple_mob\subtypes\mechanical\mecha\durand.dm" +#include "code\modules\mob\living\simple_mob\subtypes\mechanical\mecha\gygax.dm" +#include "code\modules\mob\living\simple_mob\subtypes\mechanical\mecha\hoverpod.dm" +#include "code\modules\mob\living\simple_mob\subtypes\mechanical\mecha\marauder.dm" +#include "code\modules\mob\living\simple_mob\subtypes\mechanical\mecha\mecha.dm" +#include "code\modules\mob\living\simple_mob\subtypes\mechanical\mecha\odysseus.dm" +#include "code\modules\mob\living\simple_mob\subtypes\mechanical\mecha\phazon.dm" +#include "code\modules\mob\living\simple_mob\subtypes\mechanical\mecha\ripley.dm" +#include "code\modules\mob\living\simple_mob\subtypes\mechanical\ward\monitor_ward.dm" +#include "code\modules\mob\living\simple_mob\subtypes\mechanical\ward\ward.dm" +#include "code\modules\mob\living\simple_mob\subtypes\occult\creature.dm" +#include "code\modules\mob\living\simple_mob\subtypes\occult\faithless.dm" +#include "code\modules\mob\living\simple_mob\subtypes\occult\constructs\_construct.dm" +#include "code\modules\mob\living\simple_mob\subtypes\occult\constructs\artificer.dm" +#include "code\modules\mob\living\simple_mob\subtypes\occult\constructs\harvester.dm" +#include "code\modules\mob\living\simple_mob\subtypes\occult\constructs\juggernaut.dm" +#include "code\modules\mob\living\simple_mob\subtypes\occult\constructs\shade.dm" +#include "code\modules\mob\living\simple_mob\subtypes\occult\constructs\wraith.dm" +#include "code\modules\mob\living\simple_mob\subtypes\plant\tomato.dm" +#include "code\modules\mob\living\simple_mob\subtypes\plant\tree.dm" +#include "code\modules\mob\living\simple_mob\subtypes\slime\slime.dm" +#include "code\modules\mob\living\simple_mob\subtypes\slime\feral\feral.dm" +#include "code\modules\mob\living\simple_mob\subtypes\slime\xenobio\combat.dm" +#include "code\modules\mob\living\simple_mob\subtypes\slime\xenobio\consumption.dm" +#include "code\modules\mob\living\simple_mob\subtypes\slime\xenobio\defense.dm" +#include "code\modules\mob\living\simple_mob\subtypes\slime\xenobio\discipline.dm" +#include "code\modules\mob\living\simple_mob\subtypes\slime\xenobio\subtypes.dm" +#include "code\modules\mob\living\simple_mob\subtypes\slime\xenobio\xenobio.dm" +#include "code\modules\mob\living\simple_mob\subtypes\vore\bee.dm" +#include "code\modules\mob\living\simple_mob\subtypes\vore\catgirl.dm" +#include "code\modules\mob\living\simple_mob\subtypes\vore\cookiegirl.dm" +#include "code\modules\mob\living\simple_mob\subtypes\vore\corrupt_hounds.dm" +#include "code\modules\mob\living\simple_mob\subtypes\vore\deathclaw.dm" +#include "code\modules\mob\living\simple_mob\subtypes\vore\dino.dm" +#include "code\modules\mob\living\simple_mob\subtypes\vore\dragon.dm" +#include "code\modules\mob\living\simple_mob\subtypes\vore\fennec.dm" +#include "code\modules\mob\living\simple_mob\subtypes\vore\fennix.dm" +#include "code\modules\mob\living\simple_mob\subtypes\vore\frog.dm" +#include "code\modules\mob\living\simple_mob\subtypes\vore\hippo.dm" +#include "code\modules\mob\living\simple_mob\subtypes\vore\horse.dm" +#include "code\modules\mob\living\simple_mob\subtypes\vore\jelly.dm" +#include "code\modules\mob\living\simple_mob\subtypes\vore\panther.dm" +#include "code\modules\mob\living\simple_mob\subtypes\vore\rat.dm" +#include "code\modules\mob\living\simple_mob\subtypes\vore\redpanda.dm" +#include "code\modules\mob\living\simple_mob\subtypes\vore\snake.dm" +#include "code\modules\mob\living\simple_mob\subtypes\vore\wolf.dm" +#include "code\modules\mob\living\simple_mob\subtypes\vore\wolfgirl.dm" +#include "code\modules\mob\living\simple_mob\subtypes\vore\zz_vore_overrides.dm" +#include "code\modules\mob\living\simple_mob\subtypes\vore\shadekin\_defines.dm" +#include "code\modules\mob\living\simple_mob\subtypes\vore\shadekin\ability_objects.dm" +#include "code\modules\mob\living\simple_mob\subtypes\vore\shadekin\ability_procs.dm" +#include "code\modules\mob\living\simple_mob\subtypes\vore\shadekin\shadekin.dm" +#include "code\modules\mob\living\simple_mob\subtypes\vore\shadekin\types.dm" +#include "code\modules\mob\living\simple_mob\subtypes\vore\shadekin\~defines.dm" #include "code\modules\mob\living\voice\voice.dm" #include "code\modules\mob\new_player\login.dm" #include "code\modules\mob\new_player\logout.dm" @@ -2516,7 +2604,6 @@ #include "code\modules\power\tesla\tesla_act.dm" #include "code\modules\projectiles\ammunition.dm" #include "code\modules\projectiles\dnalocking.dm" -#include "code\modules\projectiles\effects.dm" #include "code\modules\projectiles\gun.dm" #include "code\modules\projectiles\projectile.dm" #include "code\modules\projectiles\ammunition\magazines.dm" @@ -2529,6 +2616,7 @@ #include "code\modules\projectiles\guns\modular_guns.dm" #include "code\modules\projectiles\guns\projectile.dm" #include "code\modules\projectiles\guns\vox.dm" +#include "code\modules\projectiles\guns\energy\hooklauncher.dm" #include "code\modules\projectiles\guns\energy\kinetic_accelerator_vr.dm" #include "code\modules\projectiles\guns\energy\laser.dm" #include "code\modules\projectiles\guns\energy\netgun_vr.dm" @@ -2547,6 +2635,7 @@ #include "code\modules\projectiles\guns\launcher\pneumatic.dm" #include "code\modules\projectiles\guns\launcher\rocket.dm" #include "code\modules\projectiles\guns\launcher\syringe_gun.dm" +#include "code\modules\projectiles\guns\magnetic\bore.dm" #include "code\modules\projectiles\guns\magnetic\magnetic.dm" #include "code\modules\projectiles\guns\magnetic\magnetic_construction.dm" #include "code\modules\projectiles\guns\magnetic\magnetic_railgun.dm" @@ -2562,7 +2651,6 @@ #include "code\modules\projectiles\guns\projectile\shotgun.dm" #include "code\modules\projectiles\guns\projectile\sniper.dm" #include "code\modules\projectiles\guns\projectile\sniper\collapsible_sniper.dm" -#include "code\modules\projectiles\projectile\animate.dm" #include "code\modules\projectiles\projectile\arc.dm" #include "code\modules\projectiles\projectile\beams.dm" #include "code\modules\projectiles\projectile\beams_vr.dm" @@ -2573,9 +2661,11 @@ #include "code\modules\projectiles\projectile\energy.dm" #include "code\modules\projectiles\projectile\energy_vr.dm" #include "code\modules\projectiles\projectile\force.dm" +#include "code\modules\projectiles\projectile\hook.dm" #include "code\modules\projectiles\projectile\magnetic.dm" #include "code\modules\projectiles\projectile\pellets.dm" #include "code\modules\projectiles\projectile\special.dm" +#include "code\modules\projectiles\projectile\trace.dm" #include "code\modules\projectiles\targeting\targeting_client.dm" #include "code\modules\projectiles\targeting\targeting_gun.dm" #include "code\modules\projectiles\targeting\targeting_mob.dm" @@ -2642,6 +2732,7 @@ #include "code\modules\reagents\reagent_containers\spray_vr.dm" #include "code\modules\reagents\reagent_containers\syringes.dm" #include "code\modules\reagents\reagent_containers\syringes_vr.dm" +#include "code\modules\reagents\reagent_containers\unidentified_hypospray.dm" #include "code\modules\recycling\conveyor2.dm" #include "code\modules\recycling\disposal-construction.dm" #include "code\modules\recycling\disposal.dm"