diff --git a/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm b/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm index b12b1cfb2b..19a62d9a2f 100644 --- a/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm +++ b/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm @@ -227,6 +227,8 @@ turbine = null if(src.loc && anchored) turbine = locate(/obj/machinery/atmospherics/pipeturbine) in get_step(src,dir) + if(!turbine) + return if (turbine.stat & (BROKEN) || !turbine.anchored || turn(turbine.dir,180) != dir) turbine = null diff --git a/code/ATMOSPHERICS/components/binary_devices/pump.dm b/code/ATMOSPHERICS/components/binary_devices/pump.dm index b731b2c3e5..3b1a28e2dc 100644 --- a/code/ATMOSPHERICS/components/binary_devices/pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/pump.dm @@ -255,6 +255,31 @@ Thus, the two variables affect pump operation are set in New(): "You hear ratchet.") deconstruct() +/obj/machinery/atmospherics/binary/pump/click_alt(mob/user) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) + if(!allowed(user)) + to_chat(user, span_warning("Access denied.")) + return CLICK_ACTION_BLOCKING + + to_chat(user, span_notice("You set the [name] to max output")) + target_pressure = max_pressure_setting + add_fingerprint(user) + return CLICK_ACTION_SUCCESS + + +/obj/machinery/atmospherics/binary/pump/click_ctrl(mob/user) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) + if(!allowed(user)) + to_chat(user, span_warning("Access denied.")) + return CLICK_ACTION_BLOCKING + + update_use_power(!use_power) + update_icon() + add_fingerprint(user) + to_chat(user, span_notice("You toggle the [name] [use_power ? "on" : "off"].")) + + return CLICK_ACTION_SUCCESS + /obj/machinery/atmospherics/binary/pump/high_power icon = 'icons/atmos/volume_pump.dmi' icon_state = "map_off" diff --git a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm index e0cd6f58f2..c138cfcdbc 100644 --- a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm @@ -303,5 +303,29 @@ Thus, the two variables affect pump operation are set in New(): to_chat(user, span_notice("The pump quiets down as you turn its limiters back on.")) update_icon() +/obj/machinery/atmospherics/binary/volume_pump/click_alt(mob/user) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) + if(!allowed(user)) + to_chat(user, span_warning("Access denied.")) + return CLICK_ACTION_BLOCKING + + to_chat(user, span_notice("You set the [name] to max output")) + transfer_rate = max_transfer_rate + add_fingerprint(user) + return CLICK_ACTION_SUCCESS + + +/obj/machinery/atmospherics/binary/volume_pump/click_ctrl(mob/user) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) + if(!allowed(user)) + to_chat(user, span_warning("Access denied.")) + return CLICK_ACTION_BLOCKING + + update_use_power(!use_power) + update_icon() + add_fingerprint(user) + to_chat(user, span_notice("You toggle the [name] [use_power ? "on" : "off"].")) + return CLICK_ACTION_SUCCESS + #undef VOLUME_PUMP_MAX_OUTPUT_PRESSURE #undef VOLUME_PUMP_LEAK_AMOUNT diff --git a/code/__defines/power.dm b/code/__defines/power.dm index ea32aa1470..98ae2ffbef 100644 --- a/code/__defines/power.dm +++ b/code/__defines/power.dm @@ -1,2 +1,3 @@ #define I_SINGULO "singulo" #define EMITTER_DAMAGE_POWER_TRANSFER 450 //used to transfer power to containment field generators +#define MAXIMUM_TESLA_JUMPS 20 diff --git a/code/__defines/research/techweb_nodes.dm b/code/__defines/research/techweb_nodes.dm index 7988bc3926..31f2217e80 100644 --- a/code/__defines/research/techweb_nodes.dm +++ b/code/__defines/research/techweb_nodes.dm @@ -161,3 +161,4 @@ #define TECHWEB_NODE_CONFETTI "confetti" #define TECHWEB_NODE_RSF "rapid_service_fab" #define TECHWEB_NODE_MATERIALSHEETS "material_sheets" +#define TECHWEB_NODE_SMARTFRIDGES "smartfridges" diff --git a/code/controllers/subsystems/radiation.dm b/code/controllers/subsystems/radiation.dm index 7c7af986e7..928bc4103e 100644 --- a/code/controllers/subsystems/radiation.dm +++ b/code/controllers/subsystems/radiation.dm @@ -42,24 +42,13 @@ SUBSYSTEM_DEF(radiation) continue for(var/obj/item/geiger/geiger_counter in turf_to_irradiate) - var/current_insulation = 1 - for(var/turf/turf_in_between in get_line(source, geiger_counter) - get_turf(source)) - var/insulation = cached_rad_insulations[turf_in_between] - if(isnull(insulation)) - insulation = turf_in_between.rad_insulation - for (var/atom/on_turf as anything in turf_in_between.contents) - insulation *= on_turf.rad_insulation - cached_rad_insulations[turf_in_between] = insulation - - current_insulation *= insulation - - if(current_insulation <= pulse_information.threshold) - continue - - SEND_SIGNAL(geiger_counter, COMSIG_IN_RANGE_OF_IRRADIATION, pulse_information, current_insulation) - + geiger_check(source, pulse_information, geiger_counter, geiger_counter) for(var/mob/living/target in turf_to_irradiate) + var/list/contents_to_check = target.get_all_contents_type(/obj/item/geiger) + for(var/obj/item/geiger/geiger_counter in contents_to_check) + geiger_check(source, pulse_information, geiger_counter, target) + if(!can_irradiate_basic(target)) continue @@ -184,3 +173,25 @@ SUBSYSTEM_DEF(radiation) break return (protected_limbs/limb_count) + +///Proc for when geiger counter is checked. This is called twice: Once when the geiger counter is in range of a pulse itself and once when a geiger counter is on a mob that is in range of a pulse. +/datum/controller/subsystem/radiation/proc/geiger_check(atom/source, datum/radiation_pulse_information/pulse_information, obj/item/geiger/geiger_counter, atom/target) + if(!target) + target = geiger_counter + + var/current_insulation = 1 + var/list/cached_rad_insulations = list() + for(var/turf/turf_in_between in get_line(source, target) - get_turf(source)) + var/insulation = cached_rad_insulations[turf_in_between] + if(isnull(insulation)) + insulation = turf_in_between.rad_insulation + for (var/atom/on_turf as anything in turf_in_between.contents) + insulation *= on_turf.rad_insulation + cached_rad_insulations[turf_in_between] = insulation + + current_insulation *= insulation + + if(current_insulation <= pulse_information.threshold) + continue + + SEND_SIGNAL(geiger_counter, COMSIG_IN_RANGE_OF_IRRADIATION, pulse_information, current_insulation) diff --git a/code/controllers/subsystems/reflector.dm b/code/controllers/subsystems/reflector.dm new file mode 100644 index 0000000000..3e691c6310 --- /dev/null +++ b/code/controllers/subsystems/reflector.dm @@ -0,0 +1,45 @@ +#define FIRE_PRIORITY_REFLECTOR 20 + +SUBSYSTEM_DEF(reflector) + name = "Reflectors" + priority = FIRE_PRIORITY_REFLECTOR + flags = SS_BACKGROUND | SS_NO_INIT + wait = 5 + + var/stat_tag = "R" //Used for logging + var/list/processing = list() + var/list/currentrun = list() + var/obj/structure/reflector/current_thing + +/datum/controller/subsystem/reflector/Recover() + log_runtime("[name] subsystem Recover().") + if(SSreflector.current_thing) + log_runtime("current_thing was: (\ref[SSreflector.current_thing])[SSreflector.current_thing]([SSreflector.current_thing.type]) - currentrun: [SSreflector.currentrun.len] vs total: [length(SSreflector.processing)]") + var/list/old_processing = SSreflector.processing.Copy() + for(var/datum/D in old_processing) + if(CHECK_BITFIELD(D.datum_flags, DF_ISPROCESSING)) + processing |= D + +/datum/controller/subsystem/reflector/stat_entry(msg) + msg = "[stat_tag]:[processing.len]" + return ..() + +/datum/controller/subsystem/reflector/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) + current_thing = current_run[current_run.len] + current_run.len-- + if(QDELETED(current_thing)) + processing -= current_thing + current_thing.Fire() + if (MC_TICK_CHECK) + current_thing = null + return + + current_thing = null + +#undef FIRE_PRIORITY_REFLECTOR diff --git a/code/datums/components/geiger_sound.dm b/code/datums/components/geiger_sound.dm index 7bfa16d0cc..bc6c885044 100644 --- a/code/datums/components/geiger_sound.dm +++ b/code/datums/components/geiger_sound.dm @@ -52,15 +52,16 @@ register_to_loc(source.loc) /datum/component/geiger_sound/proc/register_to_loc(new_loc) - if (last_parent == new_loc) + if(last_parent == new_loc) return - if (!isnull(last_parent)) + if(!isnull(last_parent)) + sound.stop(last_parent) UnregisterSignal(last_parent, COMSIG_IN_RANGE_OF_IRRADIATION) last_parent = new_loc - if (!isnull(new_loc)) + if(!isnull(new_loc)) RegisterSignal(new_loc, COMSIG_IN_RANGE_OF_IRRADIATION, PROC_REF(on_pre_potential_irradiation)) /datum/looping_sound/geiger @@ -80,11 +81,17 @@ last_radiation_pulse = null return ..() -/datum/looping_sound/geiger/get_sound() +/datum/looping_sound/geiger/get_sound(starttime, _mid_sounds) if (isnull(last_radiation_pulse)) return null + var/danger = get_perceived_radiation_danger(last_radiation_pulse, last_insulation_to_target) + if(danger >= PERCEIVED_RADIATION_DANGER_HIGH) + chance = 100 + else + chance = danger * 15 + volume = (danger * 5) - return ..(mid_sounds[get_perceived_radiation_danger(last_radiation_pulse, last_insulation_to_target)]) + return ..(starttime, mid_sounds[danger]) /datum/looping_sound/geiger/stop(null_parent = FALSE) . = ..() diff --git a/code/datums/components/traits/radiation_effects.dm b/code/datums/components/traits/radiation_effects.dm index 87bc413dc0..73327d206c 100644 --- a/code/datums/components/traits/radiation_effects.dm +++ b/code/datums/components/traits/radiation_effects.dm @@ -171,9 +171,9 @@ /datum/component/radiation_effects/proc/process_component() SIGNAL_HANDLER var/mob/living/living_guy = parent - if((living_guy.radiation > RADIATION_CAP || living_guy.radiation < 0) || (living_guy.accumulated_rads > RADIATION_CAP || living_guy.accumulated_rads < 0)) - living_guy.radiation = CLAMP(living_guy.radiation,0,RADIATION_CAP) - living_guy.accumulated_rads = CLAMP(living_guy.accumulated_rads,0,RADIATION_CAP) + if(living_guy.radiation > RADIATION_CAP || living_guy.radiation < 0 || living_guy.accumulated_rads > RADIATION_CAP || living_guy.accumulated_rads < 0) + living_guy.radiation = CLAMP(living_guy.radiation, 0, RADIATION_CAP) + living_guy.accumulated_rads = CLAMP(living_guy.accumulated_rads, 0, RADIATION_CAP) if(QDELETED(parent)) return @@ -231,6 +231,8 @@ living_guy.radiation -= rads_to_utilize living_guy.accumulated_rads -= rads_to_utilize + living_guy.radiation = CLAMP(living_guy.radiation, 0, RADIATION_CAP) + living_guy.accumulated_rads = CLAMP(living_guy.accumulated_rads, 0, RADIATION_CAP) return COMPONENT_BLOCK_LIVING_RADIATION if(custom_damage) @@ -243,6 +245,8 @@ living_guy.apply_damage(rads_to_utilize * damage_multiplier, damage_type) + living_guy.radiation = CLAMP(living_guy.radiation, 0, RADIATION_CAP) + living_guy.accumulated_rads = CLAMP(living_guy.accumulated_rads, 0, RADIATION_CAP) return COMPONENT_BLOCK_LIVING_RADIATION /datum/component/radiation_effects/proc/handle_irradiate_effect(var/mob/living/living_guy, var/effect, var/effecttype, var/blocked, var/check_protection, var/rad_protection) @@ -266,6 +270,7 @@ //If we linger in one place for a prolonged period, the area around us will become irradiated and give us a small bit of radiation back. (only got ~1 rad per tick when we were offputting 60 rads for example) //However, we'll lose our rads faster than we accumulate. living_guy.radiation += max((radiation_to_apply * rad_protection), 0) + living_guy.radiation = CLAMP(living_guy.radiation, 0, RADIATION_CAP) return COMPONENT_BLOCK_IRRADIATION ///TGUI below here diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index 2a916319eb..b517d249ce 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -266,6 +266,8 @@ update_flag if(!src || !WT.isOn()) return to_chat(user, span_notice("You deconstruct the [src].")) new /obj/item/stack/material/steel( src.loc, 10) + if(connected_port) + disconnect() qdel(src) return //Voreend diff --git a/code/game/machinery/atmoalter/pump.dm b/code/game/machinery/atmoalter/pump.dm index 60f0525d71..b1719b7ef7 100644 --- a/code/game/machinery/atmoalter/pump.dm +++ b/code/game/machinery/atmoalter/pump.dm @@ -11,7 +11,7 @@ var/target_pressure = ONE_ATMOSPHERE var/pressuremin = 0 - var/pressuremax = 10 * ONE_ATMOSPHERE + var/pressuremax = 39.45 * ONE_ATMOSPHERE //The safest level you can get WITHOUT the tank exploding. volume = 1000 diff --git a/code/game/machinery/atmoalter/pump_vr.dm b/code/game/machinery/atmoalter/pump_vr.dm index bc8404e1f5..79af88761f 100644 --- a/code/game/machinery/atmoalter/pump_vr.dm +++ b/code/game/machinery/atmoalter/pump_vr.dm @@ -10,7 +10,7 @@ active_power_usage = 1000 // Blowers running power_rating = 100000 //100 kW ~ 135 HP - var/global/gid = 1 + var/static/gid = 1 var/id = 0 /obj/machinery/portable_atmospherics/powered/pump/huge/Initialize(mapload) diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index 598a0ee2e0..7b656b34af 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -96,7 +96,7 @@ /obj/machinery/autolathe/crowbar_act(mob/living/user, obj/item/tool) . = NONE - if(default_deconstruction_crowbar(tool)) + if(default_deconstruction_crowbar(user, tool)) return ITEM_INTERACT_SUCCESS /obj/machinery/autolathe/screwdriver_act(mob/living/user, obj/item/tool) diff --git a/code/game/machinery/computer/computer.dm b/code/game/machinery/computer/computer.dm index d0321ab0ed..4794d320d3 100644 --- a/code/game/machinery/computer/computer.dm +++ b/code/game/machinery/computer/computer.dm @@ -115,12 +115,12 @@ text = replacetext(text, "\n", "
") return text -/obj/machinery/computer/attackby(I as obj, user as mob) - if(computer_deconstruction_screwdriver(user, I)) +/obj/machinery/computer/attackby(obj/item/W, mob/user) + if(computer_deconstruction_screwdriver(user, W)) return else - if(istype(I,/obj/item/gripper)) //Behold, Grippers and their horribleness. If ..() is called by any computers' attackby() now or in the future, this should let grippers work with them appropriately. - var/obj/item/gripper/B = I //B, for Borg. + if(istype(W,/obj/item/gripper)) //Behold, Grippers and their horribleness. If ..() is called by any computers' attackby() now or in the future, this should let grippers work with them appropriately. + var/obj/item/gripper/B = W //B, for Borg. var/obj/item/wrapped = B.get_wrapped_item() if(!wrapped) to_chat(user, "\The [B] is not holding anything.") diff --git a/code/game/machinery/door_control.dm b/code/game/machinery/door_control.dm index ddac48b7d2..7f5c3013b0 100644 --- a/code/game/machinery/door_control.dm +++ b/code/game/machinery/door_control.dm @@ -164,6 +164,7 @@ desc = "A remote control switch for a mass driver." icon = 'icons/obj/objects.dmi' icon_state = "launcherbtt" + circuit = /obj/item/circuitboard/mass_driver_button /obj/machinery/button/remote/driver/trigger(mob/user) if(active) @@ -193,6 +194,18 @@ active = FALSE update_icon() +/obj/machinery/button/remote/driver/attackby(obj/item/I, mob/user) + //Swiping ID on the access button + if (istype(I, /obj/item/card/id) || istype(I, /obj/item/pda)) + attack_hand(user) + return + if(I.has_tool_quality(TOOL_MULTITOOL)) + var/new_id = tgui_input_number(user, "[src] has an id of \"[id]\". What would you like it to be?", "[src] ID]", id, 9999) + if(!Adjacent(user)) //walked away + to_chat(user, span_warning(span_warning("You need to be adjacent to the remote to change its id."))) + return + if(new_id) + id = new_id /obj/machinery/button/remote/driver/update_icon() if(!active || (stat & NOPOWER)) diff --git a/code/game/machinery/doors/airlock_control.dm b/code/game/machinery/doors/airlock_control.dm index f6b8b99a1f..dcab1057e0 100644 --- a/code/game/machinery/doors/airlock_control.dm +++ b/code/game/machinery/doors/airlock_control.dm @@ -343,7 +343,7 @@ new_frequency = sanitize_frequency(new_frequency, RADIO_LOW_FREQ, RADIO_HIGH_FREQ) set_frequency(new_frequency) if("Command") - var/new_command = tgui_input_text(user, "[src] has a command of \"[command]\". Valid options include: cycle, cycle_interior, cycle_exterior", "[src] command", command, encode = TRUE) + var/new_command = tgui_input_text(user, "[src] has a command of \"[command]\". Valid options include: 'open', 'close', 'unlock', 'lock', 'secure_open', 'secure_close', and 'update', without the '. Additionally, some airlocks support 'cycle', 'cycle_interion', and 'cycle_exterior' '", "[src] command", command, encode = TRUE) if(new_command) command = new_command diff --git a/code/game/machinery/doors/blast_door.dm b/code/game/machinery/doors/blast_door.dm index 86c7a691aa..e8c7b68c5c 100644 --- a/code/game/machinery/doors/blast_door.dm +++ b/code/game/machinery/doors/blast_door.dm @@ -43,6 +43,10 @@ /obj/machinery/door/blast/Initialize(mapload) . = ..() implicit_material = get_material_by_name(MAT_PLASTEEL) + if(density) + rad_insulation = RAD_EXTREME_INSULATION + else + rad_insulation = RAD_NO_INSULATION /obj/machinery/door/blast/get_material() return implicit_material diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index e8f6cdba4f..44a96fd19a 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -373,14 +373,14 @@ Class Procs: update_icon() return TRUE -/obj/machinery/proc/default_deconstruction_crowbar(var/mob/user, var/obj/item/C) +/obj/machinery/proc/default_deconstruction_crowbar(mob/user, obj/item/C) if(!C.has_tool_quality(TOOL_CROWBAR)) return 0 if(!panel_open) return 0 . = dismantle() -/obj/machinery/proc/default_deconstruction_screwdriver(var/mob/user, var/obj/item/S) +/obj/machinery/proc/default_deconstruction_screwdriver(mob/user, obj/item/S) if(!S.has_tool_quality(TOOL_SCREWDRIVER)) return 0 playsound(src, S.usesound, 50, 1) @@ -389,7 +389,7 @@ Class Procs: update_icon() return 1 -/obj/machinery/proc/computer_deconstruction_screwdriver(var/mob/user, var/obj/item/S) +/obj/machinery/proc/computer_deconstruction_screwdriver(mob/user, obj/item/S) if(!S.has_tool_quality(TOOL_SCREWDRIVER)) return 0 if(!circuit) diff --git a/code/game/machinery/mass_driver.dm b/code/game/machinery/mass_driver.dm index 605333fde5..27fe4cb0be 100644 --- a/code/game/machinery/mass_driver.dm +++ b/code/game/machinery/mass_driver.dm @@ -13,7 +13,7 @@ var/power = 1.0 var/code = 1.0 - var/id = 1.0 + var/id = null var/drive_range = 50 //this is mostly irrelevant since current mass drivers throw into space, but you could make a lower-range mass driver for interstation transport or something I guess. /obj/machinery/mass_driver/Initialize(mapload) @@ -28,7 +28,7 @@ if(istype(I, /obj/item/multitool)) if(panel_open) - var/input = tgui_input_text(user, "What id would you like to give this conveyor?", "Multitool-Conveyor interface", id, MAX_KEYPAD_INPUT_LEN) + var/input = tgui_input_number(user, "[src] has an id of \"[id]\". What would you like it to be?", "[src] ID]", id, 9999) if(!input) to_chat(user, "No input found please hang up and try your call again.") return diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm index ab0e7b86ac..1e2d63a4b9 100644 --- a/code/game/machinery/spaceheater.dm +++ b/code/game/machinery/spaceheater.dm @@ -101,7 +101,7 @@ if(istype(C)) user.drop_item() cell = C - C.loc = src + C.forceMove(src) C.add_fingerprint(user) user.visible_message(span_notice("[user] inserts a power cell into [src]."), span_notice("You insert the power cell into [src].")) diff --git a/code/game/objects/effects/anomalies/anomalies_flux.dm b/code/game/objects/effects/anomalies/anomalies_flux.dm index fc9a63c417..7eac67e4e9 100644 --- a/code/game/objects/effects/anomalies/anomalies_flux.dm +++ b/code/game/objects/effects/anomalies/anomalies_flux.dm @@ -71,14 +71,14 @@ sparks.set_up(3, 1, src) sparks.start() if(16 to 33) - tesla_zap(src, 2, 1000, FALSE, FALSE) + tesla_zap(src, 2, 1000, FALSE, FALSE, current_jumps = 1) //Can't chain jumps. if(34 to 65) - tesla_zap(src, 3, 1000, FALSE, FALSE) + tesla_zap(src, 3, 1000, FALSE, FALSE, current_jumps = 1) addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(tesla_zap), src, 3, 1500, FALSE, FALSE), 3 SECONDS) else - tesla_zap(src, 4, 1000, FALSE, TRUE) + tesla_zap(src, 4, 1000, FALSE, TRUE, current_jumps = 1) addtimer(CALLBACK(src, PROC_REF(highSevPulse)), 3 SECONDS) -/obj/effect/anomaly/flux/proc/highSevPulse() - tesla_zap(src, 4, 1250, FALSE, FALSE) +/obj/effect/anomaly/flux/proc/highSevPulse(power, explosive, current_jumps) + tesla_zap(src, 4, 1250, FALSE, FALSE, current_jumps = 1) addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(tesla_zap), src, 4, 1500, FALSE, FALSE), 3 SECONDS) diff --git a/code/game/objects/items/devices/geiger.dm b/code/game/objects/items/devices/geiger.dm index 3c667f61b6..1e2a2ee884 100644 --- a/code/game/objects/items/devices/geiger.dm +++ b/code/game/objects/items/devices/geiger.dm @@ -31,15 +31,15 @@ . += span_info("Alt-click it to clear stored radiation levels.") switch(last_perceived_radiation_danger) if(null) - . += span_notice("Ambient radiation level count reports that all is well.") + . += span_notice("Ambient radiation level count reports that all is well. It is ") + span_green("safe ") + span_notice("here.") if(PERCEIVED_RADIATION_DANGER_LOW) - . += span_alert("Ambient radiation levels slightly above average.") + . += span_notice("Ambient radiation levels slightly above average. It is ") + span_green("safe ") + span_notice("here.") if(PERCEIVED_RADIATION_DANGER_MEDIUM) - . += span_warning("Ambient radiation levels above average.") + . += span_notice("Ambient radiation levels above average. It is ") + span_green("safe ") + span_notice("here.") if(PERCEIVED_RADIATION_DANGER_HIGH) - . += span_danger("Ambient radiation levels highly above average.") + . += span_suicide("Ambient radiation levels highly above average. It is ") + span_warning("unsafe ") + span_suicide("here.") if(PERCEIVED_RADIATION_DANGER_EXTREME) - . += span_suicide("Ambient radiation levels reaching critical level!") + . += span_suicide("Ambient radiation levels reaching critical levels! It is ") + span_warning("extremely unsafe ") + span_suicide("here.") /obj/item/geiger/update_icon() if(!scanning) diff --git a/code/game/objects/items/weapons/circuitboards/computer/command.dm b/code/game/objects/items/weapons/circuitboards/computer/command.dm new file mode 100644 index 0000000000..ffc4e75783 --- /dev/null +++ b/code/game/objects/items/weapons/circuitboards/computer/command.dm @@ -0,0 +1,5 @@ +/obj/item/circuitboard/account_console + name = T_BOARD("account database console") + build_path = /obj/machinery/account_database + board_type = new /datum/frame/frame_types/computer + req_one_access = list(ACCESS_HOP, ACCESS_CAPTAIN, ACCESS_CENT_CAPTAIN) diff --git a/code/game/objects/items/weapons/circuitboards/computer/telecomms.dm b/code/game/objects/items/weapons/circuitboards/computer/telecomms.dm index 92fabccedf..071bcfebba 100644 --- a/code/game/objects/items/weapons/circuitboards/computer/telecomms.dm +++ b/code/game/objects/items/weapons/circuitboards/computer/telecomms.dm @@ -16,3 +16,9 @@ name = T_BOARD("telecommunications traffic control console") build_path = /obj/machinery/computer/telecomms/traffic origin_tech = list(TECH_DATA = 3) + +/obj/item/circuitboard/message_server + name = T_BOARD("message server") + build_path = /obj/machinery/message_server + origin_tech = list(TECH_DATA = 3) + board_type = new /datum/frame/frame_types/machine diff --git a/code/game/objects/items/weapons/circuitboards/frame.dm b/code/game/objects/items/weapons/circuitboards/frame.dm index 19f439df05..f09434fcab 100644 --- a/code/game/objects/items/weapons/circuitboards/frame.dm +++ b/code/game/objects/items/weapons/circuitboards/frame.dm @@ -74,6 +74,11 @@ build_path = /obj/machinery/button/windowtint board_type = new /datum/frame/frame_types/button +/obj/item/circuitboard/mass_driver_button + name = T_BOARD("mass driver button") + build_path = /obj/machinery/button/remote/driver + board_type = new /datum/frame/frame_types/button + //Computer /obj/item/circuitboard/holopad diff --git a/code/game/objects/items/weapons/circuitboards/machinery/power.dm b/code/game/objects/items/weapons/circuitboards/machinery/power.dm index 083124f478..05a555815b 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/power.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/power.dm @@ -36,3 +36,12 @@ /obj/item/stock_parts/spring = 1, /obj/item/stock_parts/manipulator = 1, /obj/item/stack/cable_coil = 10) + +/obj/item/circuitboard/hydromagnetic_trap + name = T_BOARD("hydromagnetic trap") + build_path = /obj/machinery/power/hydromagnetic_trap + board_type = new /datum/frame/frame_types/machine + req_components = list( + /obj/item/stock_parts/spring = 1, + /obj/item/stock_parts/motor = 2, + /obj/item/stack/cable_coil = 10) diff --git a/code/game/objects/items/weapons/circuitboards/machinery/smartfridges.dm b/code/game/objects/items/weapons/circuitboards/machinery/smartfridges.dm new file mode 100644 index 0000000000..b8ccabad6c --- /dev/null +++ b/code/game/objects/items/weapons/circuitboards/machinery/smartfridges.dm @@ -0,0 +1,78 @@ +#ifndef T_BOARD +#error T_BOARD macro is not defined but we need it! +#endif + +/obj/item/circuitboard/smartfridge + name = T_BOARD("smartfridge") + build_path = /obj/machinery/smartfridge + board_type = new /datum/frame/frame_types/machine + hidden = TRUE + req_components = list( + /obj/item/stock_parts/motor = 1, + /obj/item/stock_parts/gear = 2) + +/obj/item/circuitboard/smartfridge/drying + name = T_BOARD("smartfridge - drying rack") + build_path = /obj/machinery/smartfridge/drying_rack + hidden = FALSE + +/obj/item/circuitboard/smartfridge/sheets + name = T_BOARD("smartfridge - industrial sheet storage") + build_path = /obj/machinery/smartfridge/sheets + hidden = FALSE + +/obj/item/circuitboard/smartfridge/sheets/mining + name = T_BOARD("smartfridge - mining sheet storage") + build_path = /obj/machinery/smartfridge/sheets/mining + hidden = FALSE + +/obj/item/circuitboard/smartfridge/medbay + name = T_BOARD("smartfridge - refrigerated medicine storage") + build_path = /obj/machinery/smartfridge/medbay + hidden = FALSE + +/obj/item/circuitboard/smartfridge/medbay/secure + name = T_BOARD("smartfridge - secure refrigerated medicine storage") + build_path = /obj/machinery/smartfridge/secure/medbay + hidden = FALSE + +/obj/item/circuitboard/smartfridge/science + name = T_BOARD("smartfridge - biological sample storage") + build_path = /obj/machinery/smartfridge/secure/extract + hidden = FALSE + +/obj/item/circuitboard/smartfridge/kitchen + name = T_BOARD("smartfridge - food storage") + build_path = /obj/machinery/smartfridge/chef + hidden = FALSE + +/obj/item/circuitboard/smartfridge/drinks + name = T_BOARD("smartfridge - drink storage") + build_path = /obj/machinery/smartfridge/drinks + hidden = FALSE + +/obj/item/circuitboard/smartfridge/drinks/showcase + name = T_BOARD("smartfridge - drink showcase") + build_path = /obj/machinery/smartfridge/drinks/showcase + hidden = FALSE + +/obj/item/circuitboard/smartfridge/produce + name = T_BOARD("smartfridge - smart produce storage") + build_path = /obj/machinery/smartfridge/produce + hidden = FALSE + +/obj/item/circuitboard/smartfridge/seeds + name = T_BOARD("smartfridge - megaSeed servitor") + build_path = /obj/machinery/smartfridge/seeds + hidden = FALSE + +//these 2 are weird af +/obj/item/circuitboard/smartfridge/chemvator + name = T_BOARD("smartfridge - smart chemavator - upper") + build_path = /obj/machinery/smartfridge/chemistry/chemvator + hidden = FALSE + +/obj/item/circuitboard/smartfridge/chemvator/down + name = T_BOARD("smartfridge - smart chemavator - lower") + build_path = /obj/machinery/smartfridge/chemistry/chemvator/down + hidden = FALSE diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 0e647d87fd..6dcfb46196 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -13,7 +13,6 @@ var/show_examine = TRUE // Does this pop up on a mob when the mob is examined? var/redgate_allowed = TRUE //can we be taken through the redgate, in either direction? - var/rad_resistance = 0 // Allow overriding rad resistance var/being_shocked = FALSE var/micro_accepted_scale = 0.5 var/micro_target = FALSE diff --git a/code/game/objects/structures/flora/trees.dm b/code/game/objects/structures/flora/trees.dm index 9bc9117ac4..181c72abc4 100644 --- a/code/game/objects/structures/flora/trees.dm +++ b/code/game/objects/structures/flora/trees.dm @@ -124,7 +124,7 @@ if(Proj.get_structure_damage()) adjust_health(-Proj.get_structure_damage(), TRUE) -/obj/structure/flora/tree/tesla_act(power, explosive) +/obj/structure/flora/tree/tesla_act(power, explosive, current_jumps) adjust_health(-power / 100, TRUE) // Kills most trees in one lightning strike. ..() diff --git a/code/game/objects/structures/reflectors.dm b/code/game/objects/structures/reflectors.dm new file mode 100644 index 0000000000..0ab6b10245 --- /dev/null +++ b/code/game/objects/structures/reflectors.dm @@ -0,0 +1,323 @@ +/obj/structure/reflector + name = "reflector base" + icon = 'icons/obj/structures/tgs_structures.dmi' + icon_state = "reflector_map" + desc = "A base for reflector assemblies." + anchored = FALSE + density = FALSE + var/deflector_icon_state + var/image/deflector_overlay + var/finished = FALSE + var/admin = FALSE //Can't be rotated or deconstructed + var/can_rotate = TRUE + var/framebuildstacktype = /obj/item/stack/material//metal + var/framebuildstackamount = 5 + var/buildstacktype = /obj/item/stack/material//metal + var/buildstackamount = 0 + var/fires_projectile = /obj/item/projectile/beam/emitter + var/fires_accuracy = 10000 + var/fires_dispersion = 0 + var/list/allowed_projectile_typecache = list(/obj/item/projectile/beam) + var/rotation_angle = -1 + var/can_decon = TRUE + var/list/has_projectiles = list() + var/bullet_act_in_progress = FALSE + +/obj/structure/reflector/Initialize(mapload) + . = ..() + icon_state = "reflector_base" + allowed_projectile_typecache = typecacheof(allowed_projectile_typecache) + if(deflector_icon_state) + deflector_overlay = image(icon, deflector_icon_state) + add_overlay(deflector_overlay) + + if(rotation_angle == -1) + setAngle(dir2angle(dir)) + else + setAngle(rotation_angle) + + if(admin) + can_rotate = FALSE + + SSreflector.processing += src + +/obj/structure/reflector/examine(mob/user) + . = ..() + if(finished) + . += "It is set to [rotation_angle] degrees, and the rotation is [can_rotate ? "unlocked" : "locked"]." + if(!admin) + if(can_rotate) + . += span_notice("Alt-click to adjust its direction.") + else + . += span_notice("Use screwdriver to unlock the rotation.") + +/obj/structure/reflector/proc/Fire() + UNTIL(!bullet_act_in_progress) + var/list/angles = list() + for(var/obj/item/projectile/P in has_projectiles) + angles[num2text(has_projectiles[P])] += P.damage + for(var/angle in angles) + var/obj/item/projectile/P = new fires_projectile(src) + P.firer = src + P.damage = angles[angle] + P.accuracy = 350 + P.dispersion = 0 + P.fire(text2num(angle)) + has_projectiles = list() + +/obj/structure/reflector/proc/setAngle(new_angle) + if(can_rotate) + rotation_angle = new_angle + if(deflector_overlay) + cut_overlay(deflector_overlay) + deflector_overlay.transform = turn(matrix(), new_angle) + add_overlay(deflector_overlay) + +/obj/structure/reflector/proc/redirect_projectile(obj/item/projectile/P,pangle) + has_projectiles[P] = pangle + qdel(P) + +/obj/structure/reflector/set_dir(new_dir) + return ..(NORTH) + +/obj/structure/reflector/Crossed(atom/movable/AM) //Ok so this is my solution to garbage projectile code. Please god let this work. + if(istype(AM,/obj/item/projectile)) + AM.Bump(src) + +/obj/structure/reflector/bullet_act(obj/item/projectile/P) + bullet_act_in_progress = TRUE + var/pdir = P.dir + var/pangle = P.Angle + var/ploc = get_turf(P) + if(!finished || !allowed_projectile_typecache[P.type] || !(P.dir in GLOB.cardinal)) + return ..() + if(auto_reflect(P, pdir, ploc, pangle) != 2) + return ..() + bullet_act_in_progress = FALSE + +/obj/structure/reflector/proc/auto_reflect(obj/item/projectile/P, pdir, turf/ploc, pangle) + P.ignore_source_check = TRUE + return 2 + +/obj/structure/reflector/attackby(obj/item/W, mob/user, params) + if(admin) + return + + if(W.is_screwdriver()) + can_rotate = !can_rotate + to_chat(user, span_notice("You [can_rotate ? "unlock" : "lock"] [src]'s rotation.")) + playsound(W, W.usesound, 50, 1) + return + + if(W.is_wrench() && can_decon) + if(anchored) + to_chat(user, span_warning("Unweld [src] from the floor first!")) + return + user.visible_message(span_notice("[user] starts to dismantle [src]."), span_notice("You start to dismantle [src]...")) + + if(do_after(user, 2 SECONDS, target = src)) + user.visible_message(span_notice("[user] dismantles [src]."), span_notice("You dismantle [src]...")) + new framebuildstacktype(drop_location(), framebuildstackamount) + if(buildstackamount) + new buildstacktype(drop_location(), buildstackamount) + qdel(src) + else if(istype(W, /obj/item/weldingtool)) + var/obj/item/weldingtool/I = W + if(!anchored) + if(!I.get_fuel()) + to_chat(user, span_warning("You require fuel to weld the [src]!")) + return + + user.visible_message(span_notice("[user] starts to weld [src] to the floor."), + span_notice("You start to weld [src] to the floor..."), + span_hear("You hear welding.")) + + if(do_after(user, 2 SECONDS, target = src)) + if(!I.remove_fuel(1,user)) + to_chat(user, span_warning("You require fuel to weld the [src]!")) + return + anchored = TRUE + user.visible_message(span_notice("[user] welds [src] to the floor."), + span_notice("You weld [src] to the floor..."), + span_hear("You hear welding.")) + else + if(!I.remove_fuel(1,user)) + return + + user.visible_message(span_notice("[user] starts to cut [src] free from the floor."), + span_notice("You start to cut [src] free from the floor..."), + span_hear("You hear welding.")) + anchored = FALSE + to_chat(user, span_notice("You cut [src] free from the floor.")) + + //Finishing the frame + else if(istype(W, /obj/item/stack/material)) + if(finished) + return + var/obj/item/stack/material/S = W + if(istype(S, /obj/item/stack/material/glass)) + if(S.use(5)) + new /obj/structure/reflector/single(drop_location()) + qdel(src) + else + to_chat(user, span_warning("You need five sheets of glass to create a reflector!")) + return + if(istype(S, /obj/item/stack/material/glass/reinforced)) + if(S.use(10)) + new /obj/structure/reflector/double(drop_location()) + qdel(src) + else + to_chat(user, span_warning("You need ten sheets of reinforced glass to create a double reflector!")) + return + if(istype(S, /obj/item/stack/material/diamond)) + if(S.use(1)) + new /obj/structure/reflector/box(drop_location()) + qdel(src) + else + return ..() + +/obj/structure/reflector/proc/rotate(mob/user) + if (!can_rotate || admin) + to_chat(user, span_warning("The rotation is locked!")) + return FALSE + var/new_angle = tgui_input_number(user, "Input a new angle for primary reflection face.", "Reflector Angle", rotation_angle, 360, -360) + if(!CanUseTopic(user)) + return + if(!isnull(new_angle)) + setAngle(SIMPLIFY_DEGREES(new_angle)) + return TRUE + +/obj/structure/reflector/click_alt(mob/user) + if(!CanUseTopic(user)) + return + else if(finished) + rotate(user) + + +//TYPES OF REFLECTORS, SINGLE, DOUBLE, BOX + +//SINGLE + +/obj/structure/reflector/single + name = "reflector" + deflector_icon_state = "reflector" + desc = "An angled mirror for reflecting laser beams." + density = TRUE + finished = TRUE + buildstacktype = /obj/item/stack/material//glass + buildstackamount = 5 + +/obj/structure/reflector/single/anchored + anchored = TRUE + +/obj/structure/reflector/single/mapping + admin = TRUE + anchored = TRUE + +/obj/structure/reflector/single/auto_reflect(obj/item/projectile/P, pdir, turf/ploc, pangle) + var/incidence = GET_ANGLE_OF_INCIDENCE(rotation_angle, (P.Angle + 180)) + if(abs(incidence) > 90 && abs(incidence) < 270) + return FALSE + var/new_angle = SIMPLIFY_DEGREES(rotation_angle + incidence) + redirect_projectile(P,new_angle) + return ..() + +//DOUBLE + +/obj/structure/reflector/double + name = "double sided reflector" + deflector_icon_state = "reflector_double" + desc = "A double sided angled mirror for reflecting laser beams." + density = TRUE + finished = TRUE + buildstacktype = /obj/item/stack/material/glass/reinforced + buildstackamount = 10 + +/obj/structure/reflector/double/anchored + anchored = TRUE + +/obj/structure/reflector/double/mapping + admin = TRUE + anchored = TRUE + +/obj/structure/reflector/double/auto_reflect(obj/item/projectile/P, pdir, turf/ploc, pangle) + var/incidence = GET_ANGLE_OF_INCIDENCE(rotation_angle, (P.Angle + 180)) + var/new_angle = SIMPLIFY_DEGREES(rotation_angle + incidence) + redirect_projectile(P,new_angle) + return ..() + +//BOX + +/obj/structure/reflector/box + name = "reflector box" + deflector_icon_state = "reflector_box" + desc = "A box with an internal set of mirrors that reflects all laser beams in a single direction." + density = TRUE + finished = TRUE + buildstacktype = /obj/item/stack/material/diamond + buildstackamount = 1 + +/obj/structure/reflector/box/Fire() //Since they all end up at the same angle, this should save a tad bit of processing power and memory <3 + UNTIL(!bullet_act_in_progress) + var/total_damage = 0 + for(var/obj/item/projectile/P in has_projectiles) + total_damage += P.damage + if(total_damage) + var/obj/item/projectile/P = new fires_projectile(src) + P.firer = src + P.damage = total_damage + P.accuracy = 350 + P.dispersion = 0 + P.fire(rotation_angle) + has_projectiles = list() + +/obj/structure/reflector/box/anchored + anchored = TRUE + +/obj/structure/reflector/box/mapping + admin = TRUE + anchored = TRUE + +/obj/structure/reflector/box/auto_reflect(obj/item/projectile/P) + redirect_projectile(P,rotation_angle) + return ..() + +/obj/structure/reflector/ex_act() + if(admin) + return + else + return ..() + +/obj/structure/reflector/singularity_act() + if(admin) + return + else + return ..() + +/obj/structure/reflector/box/orderable + name = "NanoTrasen reflector box" + desc = "A box with an internal set of mirrors that reflects all laser beams in a single direction. This one is marked with NanoTrasen's logo." + can_decon = FALSE + +/datum/material/steel/generate_recipes() + ..() + recipes += new/datum/stack_recipe("reflector frame", /obj/structure/reflector, 5, time = 25, one_per_turf = TRUE, on_floor = TRUE) + +/datum/supply_pack/eng/reflector + name = "Reflector crate" + cost = 35 + containername = "Reflector crate" + containertype = /obj/structure/closet/crate/secure/einstein + contains = list(/obj/structure/reflector/box/orderable = 3) + +//Below is mostly mapping stuff for the spicy storage I added to house these new reflectors ;p + +/area/engineering/secret_storage + name = "Engineering Secret Storage" + +/obj/machinery/portable_atmospherics/canister + var/dont_burst = FALSE + +/obj/machinery/portable_atmospherics/canister/phoron/cold/Initialize(mapload) + . = ..() + src.air_contents.temperature = 2.72 diff --git a/code/modules/admin/verbs/lightning_strike.dm b/code/modules/admin/verbs/lightning_strike.dm index 0092d513fd..ceeee5f7bf 100644 --- a/code/modules/admin/verbs/lightning_strike.dm +++ b/code/modules/admin/verbs/lightning_strike.dm @@ -66,14 +66,14 @@ ADMIN_VERB(admin_lightning_strike, R_FUN, "Lightning Strike", "Causes lightning return if(ground) // All is well. - ground.tesla_act(LIGHTNING_POWER, FALSE) + ground.tesla_act(LIGHTNING_POWER, FALSE, current_jumps = 1) return else if(coil) // Otherwise lets bounce off the tesla coil. - coil.tesla_act(LIGHTNING_POWER, TRUE) + coil.tesla_act(LIGHTNING_POWER, TRUE, current_jumps = 1) else // Striking the turf directly. - tesla_zap(T, zap_range = LIGHTNING_ZAP_RANGE, power = LIGHTNING_POWER, explosive = FALSE, stun_mobs = TRUE) + tesla_zap(T, zap_range = LIGHTNING_ZAP_RANGE, power = LIGHTNING_POWER, explosive = FALSE, stun_mobs = TRUE, current_jumps = 1) // Some extra effects. // Some apply to those within zap range, others if they were a bit farther away. diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index cc236e5f01..8f05b052bc 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -777,7 +777,7 @@ // I_HELP: No painful description, messages only sent to prey. Similar to inshoe steppies from before. // I_DISARM: Painful yet harmless descriptions, weaken on walk. Attack logs on weaken. // I_GRAB: Grabby/Squishing descriptions, weaken on walk. Attack logs on weaken. - // I_HARM: Rand .5-1.5 multiplied by .25 min or 1.75 max, multiplied by 3.5 on walk. Ranges from .125 min to 9.1875 max damage to each limb + // I_HURT: Rand .5-1.5 multiplied by .25 min or 1.75 max, multiplied by 3.5 on walk. Ranges from .125 min to 9.1875 max damage to each limb var/message_pred = null var/message_prey = null diff --git a/code/modules/clothing/suits/reactive_armour.dm b/code/modules/clothing/suits/reactive_armour.dm index 01dc11ea18..6f61048726 100644 --- a/code/modules/clothing/suits/reactive_armour.dm +++ b/code/modules/clothing/suits/reactive_armour.dm @@ -176,7 +176,7 @@ /obj/item/clothing/suit/armor/reactive/tesla/reactive_activation(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", damage = 0) owner.visible_message(span_danger("[src] blocks [attack_text], sending out arcs of lightning!")) - tesla_zap(owner, zap_range, zap_power) + tesla_zap(owner, zap_range, zap_power, current_jumps = 1) reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration return TRUE diff --git a/code/modules/economy/Accounts_DB.dm b/code/modules/economy/Accounts_DB.dm index 76d2272503..d2192b4aaf 100644 --- a/code/modules/economy/Accounts_DB.dm +++ b/code/modules/economy/Accounts_DB.dm @@ -13,6 +13,7 @@ var/datum/money_account/detailed_account_view var/creating_new_account = 0 var/const/fund_cap = 1000000 + circuit = /obj/item/circuitboard/account_console /obj/machinery/account_database/proc/get_access_level() if(!held_card) @@ -43,8 +44,12 @@ /obj/machinery/account_database/Initialize(mapload) machine_id = "[station_name()] Acc. DB #[GLOB.num_financial_terminals++]" . = ..() + AddElement(/datum/element/climbable) /obj/machinery/account_database/attackby(obj/O, mob/user) + if(computer_deconstruction_screwdriver(user, O)) + return + if(!istype(O, /obj/item/card/id)) return ..() diff --git a/code/modules/food/kitchen/smartfridge/drying_rack.dm b/code/modules/food/kitchen/smartfridge/drying_rack.dm index 03263883a0..a7e61ee9e2 100644 --- a/code/modules/food/kitchen/smartfridge/drying_rack.dm +++ b/code/modules/food/kitchen/smartfridge/drying_rack.dm @@ -4,6 +4,7 @@ wrenchable = 1 icon_state = "drying_rack" icon_base = "drying_rack" + circuit = /obj/item/circuitboard/smartfridge/drying /obj/machinery/smartfridge/drying_rack/Initialize(mapload) . = ..() diff --git a/code/modules/food/kitchen/smartfridge/engineering.dm b/code/modules/food/kitchen/smartfridge/engineering.dm index ed370ef3fd..57b186a420 100644 --- a/code/modules/food/kitchen/smartfridge/engineering.dm +++ b/code/modules/food/kitchen/smartfridge/engineering.dm @@ -8,6 +8,7 @@ icon_base = "industrial" icon_contents = "sheet" stored_datum_type = /datum/stored_item/stack + circuit = /obj/item/circuitboard/smartfridge/sheets /obj/machinery/smartfridge/sheets/persistent persistent = /datum/persistent/storage/smartfridge/sheet_storage @@ -44,6 +45,7 @@ icon_state = "base_mining" icon_base = "mining" icon_contents = "sheet" + circuit = /obj/item/circuitboard/smartfridge/sheets/mining /obj/machinery/smartfridge/sheets/mining/persistent persistent = /datum/persistent/storage/smartfridge/sheet_storage diff --git a/code/modules/food/kitchen/smartfridge/medical.dm b/code/modules/food/kitchen/smartfridge/medical.dm index 8aaf3eba94..ae7b79929c 100644 --- a/code/modules/food/kitchen/smartfridge/medical.dm +++ b/code/modules/food/kitchen/smartfridge/medical.dm @@ -5,6 +5,7 @@ name = "\improper Refrigerated Medicine Storage" desc = "A refrigerated storage unit for securely storing medicine and chemicals." icon_contents = "chem" + circuit = /obj/item/circuitboard/smartfridge/medbay /obj/machinery/smartfridge/medbay/accept_check(var/obj/item/O as obj) if(istype(O, /obj/item/reagent_containers/borghypo)) @@ -18,6 +19,7 @@ desc = "A refrigerated storage unit for storing medicine and chemicals." icon_contents = "chem" req_one_access = list(ACCESS_MEDICAL,ACCESS_CHEMISTRY) + circuit = /obj/item/circuitboard/smartfridge/medbay/secure /obj/machinery/smartfridge/secure/medbay/accept_check(var/obj/item/O as obj) if(istype(O, /obj/item/reagent_containers/borghypo)) diff --git a/code/modules/food/kitchen/smartfridge/research.dm b/code/modules/food/kitchen/smartfridge/research.dm index 2c2bf201f4..0fac80fe68 100644 --- a/code/modules/food/kitchen/smartfridge/research.dm +++ b/code/modules/food/kitchen/smartfridge/research.dm @@ -6,6 +6,7 @@ desc = "A refrigerated storage unit for xenobiological samples." icon_contents = "slime" req_access = list(ACCESS_RESEARCH) + circuit = /obj/item/circuitboard/smartfridge/science /obj/machinery/smartfridge/secure/extract/accept_check(var/obj/item/O as obj) if(istype(O, /obj/item/slime_extract) || istype(O, /obj/item/slimepotion)) diff --git a/code/modules/food/kitchen/smartfridge/service.dm b/code/modules/food/kitchen/smartfridge/service.dm index 7bececc0a6..49138c9682 100644 --- a/code/modules/food/kitchen/smartfridge/service.dm +++ b/code/modules/food/kitchen/smartfridge/service.dm @@ -3,8 +3,9 @@ */ /obj/machinery/smartfridge/chef desc = "For storing all sorts of delicious foods!" + circuit = /obj/item/circuitboard/smartfridge/kitchen -/obj/machinery/smartfridge/chef/accept_check(var/obj/item/O as obj) +/obj/machinery/smartfridge/chef/accept_check(obj/item/O) if(istype(O,/obj/item/reagent_containers/food/snacks)) return TRUE return FALSE @@ -16,8 +17,9 @@ name = "\improper Smart Drink Storage" desc = "A refrigerated storage unit for tasty tasty alcohol." icon_contents = "drinks" + circuit = /obj/item/circuitboard/smartfridge/drinks -/obj/machinery/smartfridge/drinks/accept_check(var/obj/item/O as obj) +/obj/machinery/smartfridge/drinks/accept_check(obj/item/O) if(istype(O,/obj/item/reagent_containers/glass) || istype(O,/obj/item/reagent_containers/food/drinks) || istype(O,/obj/item/reagent_containers/food/condiment)) return TRUE return FALSE @@ -26,6 +28,7 @@ name = "\improper Drink Showcase" icon_state = "base_showcase" icon_base = "showcase" + circuit = /obj/item/circuitboard/smartfridge/drinks/showcase //Showcase needs a special icon update /obj/machinery/smartfridge/drinks/showcase/update_icon() @@ -54,6 +57,7 @@ name = "\improper Smart Produce Storage" desc = "For storing all sorts of perishable produce!" icon_contents = "plants" + circuit = /obj/item/circuitboard/smartfridge/produce /obj/machinery/smartfridge/produce/persistent persistent = /datum/persistent/storage/smartfridge/produce @@ -61,7 +65,7 @@ /obj/machinery/smartfridge/produce/persistent_lossy persistent = /datum/persistent/storage/smartfridge/produce/lossy -/obj/machinery/smartfridge/produce/accept_check(var/obj/item/O as obj) +/obj/machinery/smartfridge/produce/accept_check(obj/item/O) if(istype(O,/obj/item/reagent_containers/food/snacks/grown/) || istype(O,/obj/item/seeds/)) return TRUE return FALSE @@ -71,7 +75,7 @@ desc = "When you need seeds fast!" icon_contents = "petri" //There's no seed base in the current batch -/obj/machinery/smartfridge/seeds/accept_check(var/obj/item/O as obj) - if(istype(O,/obj/item/seeds/)) +/obj/machinery/smartfridge/seeds/accept_check(obj/item/O) + if(istype(O,/obj/item/seeds)) return TRUE return FALSE diff --git a/code/modules/food/kitchen/smartfridge/smartfridge.dm b/code/modules/food/kitchen/smartfridge/smartfridge.dm index 6a50d11de8..978b36114f 100644 --- a/code/modules/food/kitchen/smartfridge/smartfridge.dm +++ b/code/modules/food/kitchen/smartfridge/smartfridge.dm @@ -23,6 +23,7 @@ var/wrenchable = 0 var/datum/wires/smartfridge/wires = null var/persistent = null // Path of persistence datum used to track contents + circuit = /obj/item/circuitboard/smartfridge //This one is meant to be uncraftable, however. /obj/machinery/smartfridge/secure is_secure = 1 @@ -36,6 +37,7 @@ else wires = new/datum/wires/smartfridge(src) update_icon() + default_apply_parts() /obj/machinery/smartfridge/Destroy() qdel(wires) @@ -46,7 +48,7 @@ SSpersistence.forget_value(src, persistent) return ..() -/obj/machinery/smartfridge/proc/accept_check(var/obj/item/O as obj) +/obj/machinery/smartfridge/proc/accept_check(obj/item/O) return FALSE /obj/machinery/smartfridge/process() @@ -95,7 +97,7 @@ if(6 to INFINITY) add_overlay("[icon_base]-[icon_contents]3") -/obj/machinery/smartfridge/attackby(var/obj/item/O as obj, var/mob/user as mob) +/obj/machinery/smartfridge/attackby(obj/item/O, mob/user) if(O.has_tool_quality(TOOL_SCREWDRIVER)) panel_open = !panel_open user.visible_message(span_filter_notice("[user] [panel_open ? "opens" : "closes"] the maintenance panel of \the [src]."), span_filter_notice("You [panel_open ? "open" : "close"] the maintenance panel of \the [src].")) @@ -106,6 +108,13 @@ if(wrenchable && default_unfasten_wrench(user, O, 20)) return + if(O.has_tool_quality(TOOL_CROWBAR)) + if(allowed(user)) + default_deconstruction_crowbar(user, O) + else + to_chat(user, span_warning("\The [src] smartly denies you access to deconstruct it.")) + return + if(istype(O, /obj/item/multitool) || O.has_tool_quality(TOOL_WIRECUTTER)) if(panel_open) attack_hand(user) diff --git a/code/modules/food/kitchen/smartfridge/smartfridge_vr.dm b/code/modules/food/kitchen/smartfridge/smartfridge_vr.dm index d9416d4ae5..c37268f527 100644 --- a/code/modules/food/kitchen/smartfridge/smartfridge_vr.dm +++ b/code/modules/food/kitchen/smartfridge/smartfridge_vr.dm @@ -45,6 +45,7 @@ desc = "A refrigerated storage unit for medicine and chemical storage. Now sporting a fancy system of pulleys to lift bottles up and down." expert_job = JOB_CHEMIST var/obj/machinery/smartfridge/chemistry/chemvator/attached + circuit = /obj/item/circuitboard/smartfridge/chemvator /obj/machinery/smartfridge/chemistry/chemvator/accept_check(var/obj/item/O as obj) if(istype(O,/obj/item/storage/pill_bottle) || istype(O,/obj/item/reagent_containers) || istype(O,/obj/item/reagent_containers/glass/)) @@ -57,6 +58,7 @@ /obj/machinery/smartfridge/chemistry/chemvator/down name = "\improper Smart Chemavator - Lower" + circuit = /obj/item/circuitboard/smartfridge/chemvator/down /obj/machinery/smartfridge/chemistry/chemvator/down/Initialize(mapload) . = ..() 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 index d9e56fcca1..b4fc04fbe9 100644 --- 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 @@ -180,7 +180,7 @@ // 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, 'sound/effects/lightningbolt.ogg', 100, 1, extrarange = 30) - tesla_zap(src.loc, 5, ELECTRIC_ZAP_POWER, FALSE) + tesla_zap(src.loc, 5, ELECTRIC_ZAP_POWER, FALSE, current_jumps = 1) for(var/mob/living/L in viewers(src)) if(L == src) continue diff --git a/code/modules/power/cells/power_cells.dm b/code/modules/power/cells/power_cells.dm index 18c704d9c9..93be6c5f51 100644 --- a/code/modules/power/cells/power_cells.dm +++ b/code/modules/power/cells/power_cells.dm @@ -149,6 +149,7 @@ maxcharge = 30000 //determines how badly mobs get shocked matter = list(MAT_STEEL = 700, MAT_GLASS = 80) robot_durability = 200 + emp_proof = TRUE /obj/item/cell/infinite/check_charge() return 1 diff --git a/code/modules/power/fusion/magpower.dm b/code/modules/power/fusion/magpower.dm index 9d5f9bb649..c36ad77e87 100644 --- a/code/modules/power/fusion/magpower.dm +++ b/code/modules/power/fusion/magpower.dm @@ -12,6 +12,7 @@ var/list/active_field = list()//Our active field. var/active = 0 //are we even on? var/id_tag //needed for !!rasins!! + circuit = /obj/item/circuitboard/hydromagnetic_trap /obj/machinery/power/hydromagnetic_trap/attackby(var/obj/item/W, var/mob/user) if(default_unfasten_wrench(user, W)) diff --git a/code/modules/power/gravitygenerator_vr.dm b/code/modules/power/gravitygenerator_vr.dm index 1f7f706067..0d62ff83f0 100644 --- a/code/modules/power/gravitygenerator_vr.dm +++ b/code/modules/power/gravitygenerator_vr.dm @@ -38,7 +38,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) if(prob(20)) set_broken() -/obj/machinery/gravity_generator/tesla_act(power, tesla_flags) +/obj/machinery/gravity_generator/tesla_act(power, explosive, current_jumps) ..() qdel(src)//like the singulo, tesla deletes it. stops it from exploding over and over diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index a465fa7ec7..0a29fdfa1b 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -1108,7 +1108,7 @@ GLOBAL_LIST_EMPTY(light_type_cache) if(isrobot(user)) I = user.get_active_hand() - if(istype(I,/obj/item/multitool)) + if(I?.has_tool_quality(TOOL_MULTITOOL)) var/list/menu_list = list( "Normal Range", "Normal Brightness", diff --git a/code/modules/power/port_gen_vr.dm b/code/modules/power/port_gen_vr.dm index 2ceae99e38..a80db0fa5d 100644 --- a/code/modules/power/port_gen_vr.dm +++ b/code/modules/power/port_gen_vr.dm @@ -236,7 +236,7 @@ visible_message(span_danger("\The [src] lets out an shower of sparks as it starts to lose stability!"),\ span_warningplain("You hear a loud electrical crack!")) playsound(src, 'sound/effects/lightningshock.ogg', 100, 1, extrarange = 5) - tesla_zap(src, 5, power_gen * 0.05) + tesla_zap(src, 5, power_gen * 0.05, current_jumps = 1) addtimer(CALLBACK(GLOBAL_PROC, PROC_REF(explosion), get_turf(src), 2, 3, 4, 8), 100) // Not a normal explosion. /obj/machinery/power/rtg/abductor/bullet_act(obj/item/projectile/Proj) @@ -297,7 +297,7 @@ /obj/machinery/power/rtg/abductor/fire_act(exposed_temperature, exposed_volume) asplod() -/obj/machinery/power/rtg/abductor/tesla_act() +/obj/machinery/power/rtg/abductor/tesla_act(power, explosive, current_jumps) ..() //extend the zap asplod() @@ -355,7 +355,7 @@ /obj/machinery/power/rtg/kugelblitz/fire_act(exposed_temperature, exposed_volume) asplod() -/obj/machinery/power/rtg/kugelblitz/tesla_act() +/obj/machinery/power/rtg/kugelblitz/tesla_act(power, explosive, current_jumps) ..() //extend the zap asplod() @@ -620,7 +620,7 @@ /obj/machinery/power/rtg/antimatter_core/fire_act(exposed_temperature, exposed_volume) return -/obj/machinery/power/rtg/antimatter_core/tesla_act() +/obj/machinery/power/rtg/antimatter_core/tesla_act(power, explosive, current_jumps) ..() //extend the zap asplod() diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index 9ed93e31d3..7d2c9f0641 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -307,3 +307,12 @@ projectile.particle_type = particle return projectile return new /obj/item/projectile/beam/emitter(get_turf(src)) + +/obj/machinery/power/emitter/pre_mapped + anchored = TRUE + state = 2 + +/obj/machinery/power/emitter/pre_mapped/Initialize(mapload) + . = ..() + connect_to_network() + update_icon() diff --git a/code/modules/power/singularity/emitter_vr.dm b/code/modules/power/singularity/emitter_vr.dm index be4d73e7b0..c3c765b486 100644 --- a/code/modules/power/singularity/emitter_vr.dm +++ b/code/modules/power/singularity/emitter_vr.dm @@ -35,3 +35,12 @@ icon_state = "emitter_+a" else icon_state = "emitter" + +/obj/machinery/power/emitter/antique/pre_mapped + anchored = TRUE + state = 2 + +/obj/machinery/power/emitter/antique/pre_mapped/Initialize(mapload) + . = ..() + connect_to_network() + update_icon() diff --git a/code/modules/power/singularity/field_generator.dm b/code/modules/power/singularity/field_generator.dm index 358dfc7738..1ef3d7e469 100644 --- a/code/modules/power/singularity/field_generator.dm +++ b/code/modules/power/singularity/field_generator.dm @@ -357,3 +357,12 @@ investigate_log("has " + span_red("failed") + " whilst a singulo exists.","singulo") log_game("FIELDGEN([x],[y],[z]) Containment failed while singulo/tesla exists.") O.last_warning = world.time + +/obj/machinery/field_generator/pre_mapped + state = 2 //Start welded. + anchored = TRUE + + +/obj/machinery/field_generator/pre_mapped/Initialize(mapload) + . = ..() + update_icon() diff --git a/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm b/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm index c49a864b7d..711a212d84 100644 --- a/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm +++ b/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm @@ -346,3 +346,12 @@ So, hopefully this is helpful if any more icons are to be added/changed/wonderin update_use_power(USE_POWER_IDLE) update_icon() return 1 + +/obj/structure/particle_accelerator/end_cap/pre_mapped + construction_state = 3 + anchored = TRUE + +/obj/structure/particle_accelerator/end_cap/pre_mapped/Initialize(mapload) + . = ..() + update_state() + update_icon() diff --git a/code/modules/power/singularity/particle_accelerator/particle_chamber.dm b/code/modules/power/singularity/particle_accelerator/particle_chamber.dm index 4d666e12c3..8d65e6979a 100644 --- a/code/modules/power/singularity/particle_accelerator/particle_chamber.dm +++ b/code/modules/power/singularity/particle_accelerator/particle_chamber.dm @@ -4,3 +4,11 @@ icon = 'icons/obj/machines/particle_accelerator2.dmi' icon_state = "fuel_chamber" reference = "fuel_chamber" + +/obj/structure/particle_accelerator/fuel_chamber/pre_mapped + construction_state = 3 + anchored = TRUE + +/obj/structure/particle_accelerator/fuel_chamber/pre_mapped/Initialize(mapload) + . = ..() + update_icon() diff --git a/code/modules/power/singularity/particle_accelerator/particle_control.dm b/code/modules/power/singularity/particle_accelerator/particle_control.dm index 8cdbe0eb08..e95f4cca1f 100644 --- a/code/modules/power/singularity/particle_accelerator/particle_control.dm +++ b/code/modules/power/singularity/particle_accelerator/particle_control.dm @@ -252,3 +252,11 @@ . = TRUE update_icon() + +/obj/machinery/particle_accelerator/control_box/pre_mapped + construction_state = 3 + assembled = TRUE + +/obj/machinery/particle_accelerator/control_box/pre_mapped/Initialize(mapload) + . = ..() + update_icon() diff --git a/code/modules/power/singularity/particle_accelerator/particle_emitter.dm b/code/modules/power/singularity/particle_accelerator/particle_emitter.dm index b3a7c52917..354ef21753 100644 --- a/code/modules/power/singularity/particle_accelerator/particle_emitter.dm +++ b/code/modules/power/singularity/particle_accelerator/particle_emitter.dm @@ -45,3 +45,28 @@ A.set_dir(src.dir) return 1 return 0 + +/obj/structure/particle_accelerator/particle_emitter/center/pre_mapped + construction_state = 3 + anchored = TRUE + +/obj/structure/particle_accelerator/particle_emitter/center/pre_mapped/Initialize(mapload) + . = ..() + update_icon() + + +/obj/structure/particle_accelerator/particle_emitter/right/pre_mapped + construction_state = 3 + anchored = TRUE + +/obj/structure/particle_accelerator/particle_emitter/right/pre_mapped/Initialize(mapload) + . = ..() + update_icon() + +/obj/structure/particle_accelerator/particle_emitter/left/pre_mapped + construction_state = 3 + anchored = TRUE + +/obj/structure/particle_accelerator/particle_emitter/left/pre_mapped/Initialize(mapload) + . = ..() + update_icon() diff --git a/code/modules/power/singularity/particle_accelerator/particle_power.dm b/code/modules/power/singularity/particle_accelerator/particle_power.dm index 07de6e3b60..3de313d796 100644 --- a/code/modules/power/singularity/particle_accelerator/particle_power.dm +++ b/code/modules/power/singularity/particle_accelerator/particle_power.dm @@ -4,3 +4,11 @@ icon = 'icons/obj/machines/particle_accelerator2.dmi' icon_state = "power_box" reference = "power_box" + +/obj/structure/particle_accelerator/power_box/pre_mapped + construction_state = 3 + anchored = TRUE + +/obj/structure/particle_accelerator/power_box/pre_mapped/Initialize(mapload) + . = ..() + update_icon() diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm index 2541b2307a..382a746b56 100644 --- a/code/modules/power/solar.dm +++ b/code/modules/power/solar.dm @@ -62,7 +62,7 @@ GLOBAL_LIST_EMPTY(solars_list) if(W.has_tool_quality(TOOL_CROWBAR)) playsound(src, 'sound/machines/click.ogg', 50, 1) user.visible_message(span_notice("[user] begins to take the glass off the solar panel.")) - if(do_after(user, 5 SECONDS, target = src)) + if(do_after(user, 2 SECONDS * W.toolspeed, target = src)) var/obj/item/solar_assembly/S = new(loc) S.anchored = TRUE new glass_type(loc, 2) @@ -70,10 +70,12 @@ GLOBAL_LIST_EMPTY(solars_list) user.visible_message(span_notice("[user] takes the glass off the solar panel.")) qdel(src) return - else if (W) - src.add_fingerprint(user) - src.health -= W.force - src.healthcheck() + else if(W && user.a_intent == I_HURT) + user.visible_message(span_warning("[user] strikes the solar panel with [W].")) + user.setClickCooldown(user.get_attack_speed(W)) + add_fingerprint(user) + health -= W.force + healthcheck() ..() diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index e0e5a363d8..785ac1e596 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -413,16 +413,15 @@ if(!istype(l.glasses, /obj/item/clothing/glasses/meson) || l.is_incorporeal()) //Only mesons can protect you! OR if they're not in the same plane of existence l.hallucination = max(0, min(200, l.hallucination + power * config_hallucination_power * sqrt( 1 / max(1,get_dist(l, src)) ) ) ) - if(power) - // At a power mult of 0.025 for range, this means a 1000power SM (about normal) will reach 25 tiles and be putting off rad pulses of 500. With 0 protection, you have a 10% chance of getting hit. - radiation_pulse( - src, - max_range = CLAMP(round(power * 0.025), 5, 50), - threshold = CLAMP(RAD_HEAVY_INSULATION - (power * 0.00025), 0.1, RAD_MEDIUM_INSULATION), - chance = max(round(power * 0.01), DEFAULT_RADIATION_CHANCE), - minimum_exposure_time = URANIUM_RADIATION_MINIMUM_EXPOSURE_TIME, - strength = max(round(power * 0.5), 50) - ) + // At a power mult of 0.025 for range, this means a 1000power SM (about normal) will reach 25 tiles and be putting off rad pulses of 500. With 0 protection, you have a 10% chance of getting hit. + radiation_pulse( + src, + max_range = CLAMP(round(power * 0.025), 5, 50), + threshold = CLAMP(RAD_MEDIUM_INSULATION - (power * 0.00025), 0.1, RAD_MEDIUM_INSULATION), + chance = max(round(power * 0.01), DEFAULT_RADIATION_CHANCE), + minimum_exposure_time = URANIUM_RADIATION_MINIMUM_EXPOSURE_TIME, + strength = max(round(power * 0.5), 50) + ) power -= (power/DECAY_FACTOR)**3 //energy losses due to radiation diff --git a/code/modules/power/tesla/coil.dm b/code/modules/power/tesla/coil.dm index 66034e2599..1fc16efea2 100644 --- a/code/modules/power/tesla/coil.dm +++ b/code/modules/power/tesla/coil.dm @@ -1,3 +1,5 @@ +#define AMPLIFIER_STRENGTH 0.2 //Each tier of capacitor increases the amplifier's strength by this much. At 5 rating, 100% increase per relay. + /obj/machinery/power/tesla_coil name = "tesla coil" desc = "Balanced power generation and zapping." @@ -15,20 +17,37 @@ var/power_loss = 2 var/input_power_multiplier = 1 - var/zap_cooldown = 100 + var/zap_cooldown = 10 var/last_zap = 0 var/datum/wires/tesla_coil/wires = null + var/zap_range = 5 + var/lossy_transfer = TRUE //If true, we lose power upon shooting the next beam by our power_loss var. Only comes to play if power_loss is > 1 -/obj/machinery/power/tesla_coil/pre_mapped - anchored = TRUE - -/obj/machinery/power/tesla_coil/examine() +/obj/machinery/power/tesla_coil/examine(mob/user) . = ..() if(anchored) . += span_notice("It has been securely bolted down and is ready for operation.") else . += span_warning("It is not secured!") + if(Adjacent(user)) + + var/power_calculated = FALSE + if(input_power_multiplier != 1) //Greater than 1 or less than 1. + if(power_loss != 1) + . += span_info("This tesla coil will increase any power it produces by [((input_power_multiplier/power_loss) - 1) * 100]%.") + power_calculated = TRUE + else + . += span_info("This tesla coil will increase any power it produces by [(input_power_multiplier - 1) * 100]%.") + if(!power_calculated || lossy_transfer) + if(power_loss != 1) //If set to 1, we don't lose power upon shooting the next. + . += span_warning("This tesla coil will relay power with a [(1/power_loss) * 100]% loss.") + + if(zap_range) + . += span_info("This tesla coil produces bolts that will reach out [zap_range] tiles.") + else + . += span_warning("This tesla coil does not produce bolts!") + /obj/machinery/power/tesla_coil/Initialize(mapload) . = ..() wires = new(src) @@ -42,13 +61,11 @@ return ..() /obj/machinery/power/tesla_coil/RefreshParts() - var/power_multiplier = 0 - zap_cooldown = 100 + input_power_multiplier = 0 + zap_cooldown = 10 for(var/obj/item/stock_parts/capacitor/C in component_parts) - power_multiplier += C.rating - zap_cooldown -= (C.rating * 20) - input_power_multiplier = power_multiplier - + input_power_multiplier += C.rating + zap_cooldown -= (C.rating - 1) /obj/machinery/power/tesla_coil/update_icon() if(panel_open) @@ -57,7 +74,7 @@ icon_state = "[icontype][anchored]" /obj/machinery/power/tesla_coil/attackby(obj/item/W, mob/user, params) - src.add_fingerprint(user) + add_fingerprint(user) //if(default_deconstruction_screwdriver(user, "coil_open[anchored]", "coil[anchored]", W)) if(default_deconstruction_screwdriver(user, W)) @@ -68,8 +85,67 @@ return if(default_deconstruction_crowbar(user, W)) return + + if(panel_open && W?.has_tool_quality(TOOL_MULTITOOL)) + var/list/menu_list = list( + "Normal", + "Relay", + "Splitter", + "Amplifier", + "Recaster", + "Collector", + ) + + var/modification_decision = tgui_input_list(user, "Which tesla do you wish to change it into?", "Tesla Selection", menu_list) + if(!modification_decision) + return //They didn't select anything! + if(QDELETED(src) || QDELETED(W) || QDELETED(user) || get_dist(user, src) > W.reach) + return + + var/turf = get_turf(src) + if(!turf) + return + var/obj/machinery/power/tesla_coil/new_coil + switch(modification_decision) + if("Normal") + new_coil = new(turf) + if("Relay") + new_coil = new /obj/machinery/power/tesla_coil/relay(turf) + if("Splitter") + new_coil = new /obj/machinery/power/tesla_coil/splitter(turf) + if("Amplifier") + new_coil = new /obj/machinery/power/tesla_coil/amplifier(turf) + if("Recaster") + new_coil = new /obj/machinery/power/tesla_coil/recaster(turf) + if("Collector") + new_coil = new /obj/machinery/power/tesla_coil/collector(turf) + else //Should never happen. + return + + //Get rid of the stock parts that get added by init. + for(var/obj/item/stock_parts/C in new_coil.component_parts) + new_coil.component_parts -= C + qdel(C) + + //Move the stock parts from the old coil to the new one. + for(var/obj/item/stock_parts/C in component_parts) + C.forceMove(new_coil) + component_parts -= C + new_coil.component_parts += C + new_coil.RefreshParts() + + new_coil.anchored = anchored + new_coil.update_icon() + + to_chat(user, span_notice("You modify \the [src]. It is now a [lowertext(modification_decision)]! You close the access panel.")) + qdel(src) + return + + /* //Tesla wires do literally nothing. if(is_wire_tool(W)) return wires.Interact(user) + */ + return ..() /obj/machinery/power/tesla_coil/attack_hand(mob/user) @@ -77,58 +153,72 @@ return ..() -/obj/machinery/power/tesla_coil/tesla_act(var/power) +/obj/machinery/power/tesla_coil/tesla_act(power, explosive, current_jumps) if(anchored && !panel_open) being_shocked = TRUE - coil_act(power) + coil_act(power, explosive, current_jumps) //addtimer(CALLBACK(src, PROC_REF(reset_shocked)), 10) - spawn(10) reset_shocked() + spawn(zap_cooldown) reset_shocked() + else if(anchored && panel_open) //Doing maintenance. Just act like a grounding rod. + being_shocked = TRUE + spawn(zap_cooldown) reset_shocked() else ..() -/obj/machinery/power/tesla_coil/proc/coil_act(var/power) +/obj/machinery/power/tesla_coil/proc/coil_act(power, explosive, current_jumps) var/power_produced = power / power_loss add_avail(power_produced*input_power_multiplier) flick("[icontype]hit", src) playsound(src, 'sound/effects/lightningshock.ogg', 100, 1, extrarange = 5) - tesla_zap(src, 5, power_produced) + tesla_zap(src, zap_range, power_produced, current_jumps = current_jumps) -/obj/machinery/power/tesla_coil/proc/zap() +//Unused. +/obj/machinery/power/tesla_coil/proc/zap(power, explosive, current_jumps) if((last_zap + zap_cooldown) > world.time || !powernet) return FALSE last_zap = world.time var/coeff = (20 - ((input_power_multiplier - 1) * 3)) coeff = max(coeff, 10) - var/power = (powernet.avail/2) + power = (powernet.avail/2) draw_power(power) playsound(src, 'sound/effects/lightningshock.ogg', 100, 1, extrarange = 5) - tesla_zap(src, 10, power/(coeff/2)) + tesla_zap(src, zap_range, power/(coeff/2), current_jumps = current_jumps) /obj/machinery/power/tesla_coil/relay name = "tesla relay coil" - desc = "Designed to move power around rather than just consuming it." + desc = "Designed to move power around rather. Creates no power on its own." icon_state = "relay0" icontype = "relay" circuit = /obj/item/circuitboard/tesla_coil power_loss = 1 - input_power_multiplier = 0 var/relay_efficiency = 0.9 /obj/machinery/power/tesla_coil/relay/RefreshParts() ..() - var/relay_multiplier + input_power_multiplier = 1 //So we don't show the examine text further above. + relay_efficiency = 0.85 for(var/obj/item/stock_parts/capacitor/C in component_parts) - relay_multiplier += C.rating - relay_efficiency = 0.85 + (0.05 * relay_multiplier) + relay_efficiency += C.rating * 0.05 -/obj/machinery/power/tesla_coil/relay/coil_act(var/power) - var/power_relayed = power * relay_efficiency +/obj/machinery/power/tesla_coil/relay/coil_act(power, explosive, current_jumps) + var/diminishing_returns = 1 + ((current_jumps * 0.1)-0.1) //The more jumps, the less effective the amplifier is. At 10 jumps, it's only 1/2 as effective. + var/power_relayed = ((power * relay_efficiency) / diminishing_returns) + if(power_relayed < power && relay_efficiency >= 1) + power_relayed = power flick("[icontype]hit", src) playsound(src, 'sound/effects/lightningshock.ogg', 100, 1, extrarange = 5) - tesla_zap(src, 5, power_relayed) + tesla_zap(src, zap_range, power_relayed, current_jumps = current_jumps) + +/obj/machinery/power/tesla_coil/relay/examine(mob/user) + . = ..() + if(Adjacent(user)) + if(relay_efficiency == 1) + . += span_info("This tesla coil will transfer power through it with no loss.") + else + . += span_info("This tesla coil will [relay_efficiency > 1 ? "amplify" : "reduce"] power transferring through it by [ abs(relay_efficiency - 1) * 100]%.") /obj/machinery/power/tesla_coil/splitter name = "tesla prism coil" @@ -138,6 +228,9 @@ circuit = /obj/item/circuitboard/tesla_coil + power_loss = 2 + lossy_transfer = FALSE + var/split_count = 1 /obj/machinery/power/tesla_coil/splitter/RefreshParts() @@ -146,38 +239,56 @@ for(var/obj/item/stock_parts/capacitor/C in component_parts) split_count += C.rating -/obj/machinery/power/tesla_coil/splitter/coil_act(var/power) +/obj/machinery/power/tesla_coil/splitter/coil_act(power, explosive, current_jumps) var/power_per_bolt = power / (split_count + 1) var/power_produced = power_per_bolt / power_loss - add_avail(power_produced*input_power_multiplier) + add_avail(power_produced * input_power_multiplier) flick("[icontype]hit", src) playsound(src, 'sound/effects/lightningshock.ogg', 100, 1, extrarange = 5) for(var/i = 0, i < split_count, i++) - tesla_zap(src, 5, power_per_bolt) + tesla_zap(src, zap_range, power_per_bolt, current_jumps = current_jumps) + +/obj/machinery/power/tesla_coil/splitter/examine(mob/user) + . = ..() + if(Adjacent(user)) + . += span_info("This tesla coil will create [split_count + 1] bolts, with each containing [round(((1 / (split_count+1)) * 100), 0.1)]% of the original power.") /obj/machinery/power/tesla_coil/amplifier name = "tesla amplifier coil" - desc = "Designed to amplify power moving through it rather than collecting it." + desc = "Designed to amplify power moving through it rather than collecting it. Has diminishing returns the more relays the tesla bolt has passed through." icon_state = "amp0" icontype = "amp" circuit = /obj/item/circuitboard/tesla_coil - var/amp_eff = 2 + var/amp_eff = 1.075 + power_loss = 1 /obj/machinery/power/tesla_coil/amplifier/RefreshParts() ..() - var/amp_eff = 1 + amp_eff = 1.075 for(var/obj/item/stock_parts/capacitor/C in component_parts) - amp_eff += C.rating + amp_eff += ((C.rating * AMPLIFIER_STRENGTH) - AMPLIFIER_STRENGTH) + input_power_multiplier = 1 //no mult for you -/obj/machinery/power/tesla_coil/amplifier/coil_act(var/power) - var/power_produced = power / power_loss - add_avail(power_produced*input_power_multiplier) +/obj/machinery/power/tesla_coil/amplifier/coil_act(power, explosive, current_jumps) + var/diminishing_returns = 1 + ((current_jumps * 0.1)-0.1) //The more jumps, the less effective the amplifier is. At 10 jumps, it stops increasing power. Use something else! + var/power_produced = ((power * amp_eff) / diminishing_returns) + if(power_produced < power) + power_produced = power //Don't let it reduce power. If the amp is worse than the original, just give them the original power. flick("[icontype]hit", src) playsound(src, 'sound/effects/lightningshock.ogg', 100, 1, extrarange = 5) - tesla_zap(src, 5, power_produced) + tesla_zap(src, zap_range, power_produced, current_jumps = current_jumps) +/obj/machinery/power/tesla_coil/amplifier/examine(mob/user) + . = ..() + if(Adjacent(user)) + . += span_info("This tesla coil will amplify any power it receives by [round((((amp_eff) * 100) - 100), 0.1)]% of the original power when relaying it.") + . += span_info("Every jump the tesla makes reduces the effectiveness of the amplifier by 10%, meaning at 10 jumps, it stops increasing power.") + . += span_danger("This tesla coil will NOT produce produce energy.") + + +///BE WARNED, THIS THING CAN CAUSE MASSIVE LAG IF THE RANGE IS TOO HIGH /obj/machinery/power/tesla_coil/recaster name = "tesla recaster coil" desc = "Extends the reach of the bolts." @@ -186,21 +297,21 @@ circuit = /obj/item/circuitboard/tesla_coil - var/zap_range = 6 + zap_range = 6 /obj/machinery/power/tesla_coil/recaster/RefreshParts() ..() - var/zap_range = 5 + zap_range = 5 for(var/obj/item/stock_parts/capacitor/C in component_parts) - zap_range += C.rating + zap_range += C.rating * 1 -/obj/machinery/power/tesla_coil/recaster/coil_act(var/power) +/obj/machinery/power/tesla_coil/recaster/coil_act(power, explosive, current_jumps) var/power_relayed = power / power_loss var/power_produced = power / (power_loss * 2) add_avail(power_produced*input_power_multiplier) flick("[icontype]hit", src) playsound(src, 'sound/effects/lightningshock.ogg', 100, 1, extrarange = zap_range) - tesla_zap(src, zap_range, power_relayed) + tesla_zap(src, zap_range, power_relayed, current_jumps = current_jumps) /obj/machinery/power/tesla_coil/collector name = "tesla collector coil" @@ -210,18 +321,20 @@ circuit = /obj/item/circuitboard/tesla_coil - var/collect_eff = 0.8 + power_loss = 1 //Doesn't lose power. Instead it uses collect_eff + + zap_range = 0 /obj/machinery/power/tesla_coil/collector/RefreshParts() ..() - var/collect_mod = 0 + input_power_multiplier = 0 for(var/obj/item/stock_parts/capacitor/C in component_parts) - collect_mod += C.rating - collect_eff = 0.75 + collect_mod*0.05 + input_power_multiplier += C.rating * C.rating //T1 = 200% T2 = 400% T3 = 900% T4 = 1600% T5 = 2500% + if(input_power_multiplier == 1) + input_power_multiplier = 2 -/obj/machinery/power/tesla_coil/collector/coil_act(var/power) - var/power_produced = power * collect_eff - add_avail(power_produced*input_power_multiplier) +/obj/machinery/power/tesla_coil/collector/coil_act(power, explosive, current_jumps) + add_avail(power*input_power_multiplier) flick("[icontype]hit", src) playsound(src, 'sound/effects/lightningshock.ogg', 100, 1, extrarange = 5) @@ -241,16 +354,13 @@ . = ..() AddElement(/datum/element/climbable) -/obj/machinery/power/grounding_rod/examine() +/obj/machinery/power/grounding_rod/examine(user) . = ..() if(anchored) . += span_notice("It has been securely bolted down and is ready for operation.") else . += span_warning("It is not secured!") -/obj/machinery/power/grounding_rod/pre_mapped - anchored = TRUE - /obj/machinery/power/grounding_rod/update_icon() if(panel_open) icon_state = "grounding_rod_open[anchored]" @@ -274,8 +384,67 @@ return ..() -/obj/machinery/power/grounding_rod/tesla_act(var/power) +/obj/machinery/power/grounding_rod/tesla_act(power, explosive, current_jumps) if(anchored && !panel_open) flick("grounding_rodhit", src) else ..() + +//Mapspawn variants of each. +/obj/machinery/power/tesla_coil/pre_mapped + anchored = TRUE + +/obj/machinery/power/tesla_coil/pre_mapped/Initialize(mapload) + . = ..() + connect_to_network() + update_icon() + +/obj/machinery/power/tesla_coil/relay/pre_mapped + anchored = TRUE + +/obj/machinery/power/tesla_coil/relay/pre_mapped/Initialize(mapload) + . = ..() + connect_to_network() + update_icon() + +/obj/machinery/power/tesla_coil/splitter/pre_mapped + anchored = TRUE + +/obj/machinery/power/tesla_coil/splitter/pre_mapped/Initialize(mapload) + . = ..() + connect_to_network() + update_icon() + +/obj/machinery/power/tesla_coil/amplifier/pre_mapped + anchored = TRUE + +/obj/machinery/power/tesla_coil/amplifier/pre_mapped/Initialize(mapload) + . = ..() + connect_to_network() + update_icon() + +/obj/machinery/power/tesla_coil/recaster/pre_mapped + anchored = TRUE + +/obj/machinery/power/tesla_coil/recaster/pre_mapped/Initialize(mapload) + . = ..() + connect_to_network() + update_icon() + +/obj/machinery/power/tesla_coil/collector/pre_mapped + anchored = TRUE + +/obj/machinery/power/tesla_coil/collector/pre_mapped/Initialize(mapload) + . = ..() + connect_to_network() + update_icon() + +/obj/machinery/power/grounding_rod/pre_mapped + anchored = TRUE + +/obj/machinery/power/grounding_rod/pre_mapped/Initialize(mapload) + . = ..() + connect_to_network() + update_icon() + +#undef AMPLIFIER_STRENGTH diff --git a/code/modules/power/tesla/energy_ball.dm b/code/modules/power/tesla/energy_ball.dm index e2130406f1..fff31bb094 100644 --- a/code/modules/power/tesla/energy_ball.dm +++ b/code/modules/power/tesla/energy_ball.dm @@ -58,11 +58,11 @@ playsound(src, 'sound/effects/lightningbolt.ogg', 100, 1, extrarange = 30) - set_dir(tesla_zap(src, 7, TESLA_DEFAULT_POWER, TRUE)) + set_dir(tesla_zap(src, 7, TESLA_DEFAULT_POWER, TRUE, current_jumps = 1)) for (var/ball in orbiting_balls) var/range = rand(1, CLAMP(orbiting_balls.len, 3, 7)) - tesla_zap(ball, range, TESLA_MINI_POWER/7*range, TRUE) + tesla_zap(ball, range, TESLA_MINI_POWER/7*range, TRUE, current_jumps = 1) else energy = 0 // ensure we dont have miniballs of miniballs @@ -158,12 +158,15 @@ // L.dust() - Changing to do fatal elecrocution instead L.electrocute_act(500, src, def_zone = BP_TORSO) -/proc/tesla_zap(atom/source, zap_range = 3, power, explosive = FALSE, stun_mobs = TRUE) +/proc/tesla_zap(atom/source, zap_range = 3, power, explosive = FALSE, stun_mobs = TRUE, current_jumps) if(!source) // Some mobs and maybe some objects delete themselves when they die. return . = source.dir if(power < 1000) return + if(current_jumps >= MAXIMUM_TESLA_JUMPS) + return + current_jumps++ var/closest_dist = 0 var/closest_atom @@ -194,10 +197,12 @@ /obj/structure/grille, /obj/machinery/the_singularitygen/tesla)) - for(var/A in typecache_filter_multi_list_exclusion(oview(source, zap_range+2), things_to_shock, blacklisted_tesla_types)) + for(var/A in typecache_filter_multi_list_exclusion(oview(zap_range+2, source), things_to_shock, blacklisted_tesla_types)) if(istype(A, /obj/machinery/power/tesla_coil)) var/dist = get_dist(source, A) var/obj/machinery/power/tesla_coil/C = A + if(!C.anchored) + continue if(dist <= zap_range && (dist < closest_dist || !closest_tesla_coil) && !C.being_shocked) closest_dist = dist @@ -277,10 +282,10 @@ //per type stuff: if(closest_tesla_coil) - closest_tesla_coil.tesla_act(power, explosive, stun_mobs) + closest_tesla_coil.tesla_act(power, explosive, stun_mobs, current_jumps = current_jumps) else if(closest_grounding_rod) - closest_grounding_rod.tesla_act(power, explosive, stun_mobs) + closest_grounding_rod.tesla_act(power, explosive, stun_mobs, current_jumps = current_jumps) else if(closest_mob) var/shock_damage = CLAMP(round(power/400), 10, 90) + rand(-5, 5) @@ -291,21 +296,21 @@ var/mob/living/silicon/S = closest_mob if(stun_mobs) S.emp_act(3 /*EMP_LIGHT*/) - tesla_zap(closest_mob, 7, power / 1.5, explosive, stun_mobs) // metallic folks bounce it further + tesla_zap(closest_mob, 7, power / 1.5, explosive, stun_mobs, current_jumps = current_jumps) // metallic folks bounce it further else - tesla_zap(closest_mob, 5, power / 1.5, explosive, stun_mobs) + tesla_zap(closest_mob, 5, power / 1.5, explosive, stun_mobs, current_jumps = current_jumps) else if(closest_machine) drain_energy = TRUE // VOREStation Edit - Safety First! Drain Tesla fast when its loose - closest_machine.tesla_act(power, explosive, stun_mobs) + closest_machine.tesla_act(power, explosive, stun_mobs, current_jumps = current_jumps) else if(closest_blob) drain_energy = TRUE // VOREStation Edit - Safety First! Drain Tesla fast when its loose - closest_blob.tesla_act(power, explosive, stun_mobs) + closest_blob.tesla_act(power, explosive, stun_mobs, current_jumps = current_jumps) else if(closest_structure) drain_energy = TRUE // VOREStation Edit - Safety First! Drain Tesla fast when its loose - closest_structure.tesla_act(power, explosive, stun_mobs) + closest_structure.tesla_act(power, explosive, stun_mobs, current_jumps = current_jumps) // VOREStation Edit Start - Safety First! Drain Tesla fast when its loose if(drain_energy && istype(source, /obj/singularity/energy_ball)) diff --git a/code/modules/power/tesla/generator.dm b/code/modules/power/tesla/generator.dm index 63bce099fa..2ec8768ede 100644 --- a/code/modules/power/tesla/generator.dm +++ b/code/modules/power/tesla/generator.dm @@ -5,6 +5,9 @@ icon_state = "TheSingGen" creation_type = /obj/singularity/energy_ball -/obj/machinery/the_singularitygen/tesla/tesla_act(power, explosive = FALSE) +/obj/machinery/the_singularitygen/tesla/tesla_act(power, explosive = FALSE, current_jumps) if(explosive) energy += power + +/obj/machinery/the_singularitygen/tesla/pre_mapped + anchored = TRUE diff --git a/code/modules/power/tesla/tesla_act.dm b/code/modules/power/tesla/tesla_act.dm index 16a5669ac2..96c56cbe8f 100644 --- a/code/modules/power/tesla/tesla_act.dm +++ b/code/modules/power/tesla/tesla_act.dm @@ -2,10 +2,10 @@ // Vars and Default tesla_act behavior //////////////////////////////////////// -/obj/proc/tesla_act(var/power) +/obj/proc/tesla_act(power, explosive = FALSE, current_jumps) being_shocked = TRUE var/power_bounced = power / 2 - tesla_zap(src, 3, power_bounced) + tesla_zap(src, 3, power_bounced, current_jumps) //addtimer(CALLBACK(src, PROC_REF(reset_shocked)), 10) //schedule_task_with_source_in(10, src, PROC_REF(reset_shocked)) spawn(10) reset_shocked() @@ -15,16 +15,16 @@ // Overrides for behavior on specific types -/obj/structure/blob/tesla_act(power) +/obj/structure/blob/tesla_act(power, explosive, current_jumps) ..() adjust_integrity(-power/400) -/obj/machinery/nuclearbomb/tesla_act(power, explosive) +/obj/machinery/nuclearbomb/tesla_act(power, explosive, current_jumps) ..() if(explosive) qdel(src)//like the singulo, tesla deletes it. stops it from exploding over and over -/obj/machinery/tesla_act(power, explosive = FALSE) +/obj/machinery/tesla_act(power, explosive, current_jumps) ..() if(prob(85) && explosive) explosion(loc, 0, 2, 4, /*flame_range = 2,*/ adminlog = FALSE/*, smoke = FALSE*/) // VOREStation Edit - No devastation range @@ -33,13 +33,13 @@ else ex_act(2) -/obj/machinery/camera/tesla_act(var/power)//EMP proof upgrade also makes it tesla immune +/obj/machinery/camera/tesla_act(power, explosive, current_jumps)//EMP proof upgrade also makes it tesla immune if(isEmpProof()) return ..() qdel(src) //to prevent bomb testing camera from exploding over and over forever -/obj/machinery/light/tesla_act(power, explosive = FALSE) +/obj/machinery/light/tesla_act(power, explosive, current_jumps) if(explosive) explosion(loc, 0, 0, 0/*, flame_range = 5*/, adminlog = FALSE) qdel(src) @@ -47,16 +47,16 @@ on = TRUE broken() -/obj/structure/closet/tesla_act(var/power) +/obj/structure/closet/tesla_act(power, explosive, current_jumps) ..() //extend the zap visible_message(span_danger("[src] is blown apart by the bolt of electricity!"), span_danger("You hear a metallic screeching sound.")) dump_contents() qdel(src) -/obj/structure/reagent_dispensers/fueltank/tesla_act() +/obj/structure/reagent_dispensers/fueltank/tesla_act(power, explosive, current_jumps) ..() //extend the zap explode() -/obj/mecha/tesla_act(power) +/obj/mecha/tesla_act(power, explosive = FALSE, current_jumps) ..() 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 ffd2303f31..2396bc04b0 100644 --- a/code/modules/power/turbine.dm +++ b/code/modules/power/turbine.dm @@ -330,7 +330,7 @@ compressor = C LAZYINITLIST(doors) for(var/obj/machinery/door/blast/P in GLOB.machines) - if(P.id == id) + if(P.id == id) //This will never work because the ID on the blast doors is a number while the ID on the turbine (if set mid-round) is a string. doors += P /obj/machinery/computer/turbine_computer/attackby(obj/item/W, mob/user) diff --git a/code/modules/research/message_server.dm b/code/modules/research/message_server.dm index f803a3ad32..e969bbd9f7 100644 --- a/code/modules/research/message_server.dm +++ b/code/modules/research/message_server.dm @@ -56,6 +56,7 @@ use_power = USE_POWER_IDLE idle_power_usage = 10 active_power_usage = 100 + circuit = /obj/item/circuitboard/message_server var/list/datum/data_pda_msg/pda_msgs = list() var/list/datum/data_rc_msg/rc_msgs = list() @@ -137,7 +138,7 @@ Console.set_light(2) -/obj/machinery/message_server/attack_hand(user as mob) +/obj/machinery/message_server/attack_hand(mob/living/user) // to_chat(user, span_blue("There seem to be some parts missing from this server. They should arrive on the station in a few days, give or take a few CentCom delays.")) to_chat(user, span_filter_notice("You toggle PDA message passing from [active ? "On" : "Off"] to [active ? "Off" : "On"].")) active = !active @@ -145,7 +146,13 @@ return -/obj/machinery/message_server/attackby(obj/item/O as obj, mob/living/user as mob) +/obj/machinery/message_server/attackby(obj/item/O, mob/living/user) + if(default_deconstruction_screwdriver(user, O)) + return + + if(default_deconstruction_crowbar(user, O)) + return + if (active && !(stat & (BROKEN|NOPOWER)) && (spamfilter_limit < MESSAGE_SERVER_DEFAULT_SPAM_LIMIT*2) && \ istype(O,/obj/item/circuitboard/message_monitor)) spamfilter_limit += round(MESSAGE_SERVER_DEFAULT_SPAM_LIMIT / 2) diff --git a/code/modules/research/tg/designs/boards/engineering.dm b/code/modules/research/tg/designs/boards/engineering.dm index 8a70f92bcd..9d87e5565c 100644 --- a/code/modules/research/tg/designs/boards/engineering.dm +++ b/code/modules/research/tg/designs/boards/engineering.dm @@ -116,6 +116,16 @@ ) departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING | DEPARTMENT_BITFLAG_SCIENCE +/datum/design_techweb/board/hydromagnetic_trap + SET_CIRCUIT_DESIGN_NAMEDESC("hydromagnetic trap") + id = "hydromagnetic_trap" + // req_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 3) + build_path = /obj/item/circuitboard/hydromagnetic_trap + category = list( + RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_ENGINEERING + ) + departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING | DEPARTMENT_BITFLAG_SCIENCE + /datum/design_techweb/board/secure_airlock name = "secure airlock electronics circuit" desc = "Allows for the construction of a tamper-resistant airlock electronics." @@ -360,6 +370,15 @@ ) departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING | DEPARTMENT_BITFLAG_SCIENCE +/datum/design_techweb/board/mass_driver_button + SET_CIRCUIT_DESIGN_NAMEDESC("mass driver button") + id = "mass_driver_button" + build_path = /obj/item/circuitboard/mass_driver_button + category = list( + RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_ENGINEERING + ) + departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING | DEPARTMENT_BITFLAG_SCIENCE + /datum/design_techweb/board/automatic_pipe_layer SET_CIRCUIT_DESIGN_NAMEDESC("automatic pipe layer") id = "automatic_pipe_layer" @@ -404,3 +423,125 @@ RND_CATEGORY_COMPUTER + RND_SUBCATEGORY_MACHINE_ENGINEERING ) departmental_flags = DEPARTMENT_BITFLAG_SCIENCE | DEPARTMENT_BITFLAG_ENGINEERING + +//Smartfridges + +/datum/design_techweb/board/drying_rack + SET_CIRCUIT_DESIGN_NAMEDESC("drying rack") + id = "drying_rack_circuit" + build_path = /obj/item/circuitboard/smartfridge/drying + category = list( + RND_CATEGORY_COMPUTER + RND_SUBCATEGORY_MACHINE_ENGINEERING + ) + departmental_flags = DEPARTMENT_BITFLAG_SCIENCE | DEPARTMENT_BITFLAG_ENGINEERING + +/datum/design_techweb/board/industrial_sheet_storage + SET_CIRCUIT_DESIGN_NAMEDESC("smartfridge industrial sheet storage") + id = "industrial_sheet_storage_circuit" + build_path = /obj/item/circuitboard/smartfridge/sheets + category = list( + RND_CATEGORY_COMPUTER + RND_SUBCATEGORY_MACHINE_ENGINEERING + ) + departmental_flags = DEPARTMENT_BITFLAG_SCIENCE | DEPARTMENT_BITFLAG_ENGINEERING + +/datum/design_techweb/board/mining_sheet_storage + SET_CIRCUIT_DESIGN_NAMEDESC("smartfridge mining sheet storage") + id = "mining_sheet_storage_circuit" + build_path = /obj/item/circuitboard/smartfridge/sheets/mining + category = list( + RND_CATEGORY_COMPUTER + RND_SUBCATEGORY_MACHINE_ENGINEERING + ) + departmental_flags = DEPARTMENT_BITFLAG_SCIENCE | DEPARTMENT_BITFLAG_ENGINEERING + +/datum/design_techweb/board/refrigerated_medicine_storage + SET_CIRCUIT_DESIGN_NAMEDESC("smartfridge refrigerated medicine storage") + id = "refrigerated_medicine_storage_circuit" + build_path = /obj/item/circuitboard/smartfridge/medbay + category = list( + RND_CATEGORY_COMPUTER + RND_SUBCATEGORY_MACHINE_ENGINEERING + ) + departmental_flags = DEPARTMENT_BITFLAG_SCIENCE | DEPARTMENT_BITFLAG_ENGINEERING + +/datum/design_techweb/board/secure_refrigerated_medicine_storage + SET_CIRCUIT_DESIGN_NAMEDESC("smartfridge secure refrigerated medicine storage") + id = "secure_refrigerated_medicine_storage_circuit" + build_path = /obj/item/circuitboard/smartfridge/medbay/secure + category = list( + RND_CATEGORY_COMPUTER + RND_SUBCATEGORY_MACHINE_ENGINEERING + ) + departmental_flags = DEPARTMENT_BITFLAG_SCIENCE | DEPARTMENT_BITFLAG_ENGINEERING + +/datum/design_techweb/board/biological_sample_storage + SET_CIRCUIT_DESIGN_NAMEDESC("smartfridge biological sample storage") + id = "biological_sample_storage_circuit" + build_path = /obj/item/circuitboard/smartfridge/science + category = list( + RND_CATEGORY_COMPUTER + RND_SUBCATEGORY_MACHINE_ENGINEERING + ) + departmental_flags = DEPARTMENT_BITFLAG_SCIENCE | DEPARTMENT_BITFLAG_ENGINEERING + +/datum/design_techweb/board/food_storage + SET_CIRCUIT_DESIGN_NAMEDESC("smartfridge food storage") + id = "food_storage_circuit" + build_path = /obj/item/circuitboard/smartfridge/kitchen + category = list( + RND_CATEGORY_COMPUTER + RND_SUBCATEGORY_MACHINE_ENGINEERING + ) + departmental_flags = DEPARTMENT_BITFLAG_SCIENCE | DEPARTMENT_BITFLAG_ENGINEERING + +/datum/design_techweb/board/drink_storage + SET_CIRCUIT_DESIGN_NAMEDESC("smartfridge drink storage") + id = "drink_storage_circuit" + build_path = /obj/item/circuitboard/smartfridge/drinks + category = list( + RND_CATEGORY_COMPUTER + RND_SUBCATEGORY_MACHINE_ENGINEERING + ) + departmental_flags = DEPARTMENT_BITFLAG_SCIENCE | DEPARTMENT_BITFLAG_ENGINEERING + +/datum/design_techweb/board/drink_showcase + SET_CIRCUIT_DESIGN_NAMEDESC("smartfridge drink showcase") + id = "drink_showcase_circuit" + build_path = /obj/item/circuitboard/smartfridge/drinks/showcase + category = list( + RND_CATEGORY_COMPUTER + RND_SUBCATEGORY_MACHINE_ENGINEERING + ) + departmental_flags = DEPARTMENT_BITFLAG_SCIENCE | DEPARTMENT_BITFLAG_ENGINEERING + +/datum/design_techweb/board/produce_showcase + SET_CIRCUIT_DESIGN_NAMEDESC("smartfridge produce storage") + id = "produce_storage_circuit" + build_path = /obj/item/circuitboard/smartfridge/produce + category = list( + RND_CATEGORY_COMPUTER + RND_SUBCATEGORY_MACHINE_ENGINEERING + ) + departmental_flags = DEPARTMENT_BITFLAG_SCIENCE | DEPARTMENT_BITFLAG_ENGINEERING + +/datum/design_techweb/board/seed_storage + SET_CIRCUIT_DESIGN_NAMEDESC("smartfridge seed storage") + id = "seed_storage_circuit" + build_path = /obj/item/circuitboard/smartfridge/seeds + + category = list( + RND_CATEGORY_COMPUTER + RND_SUBCATEGORY_MACHINE_ENGINEERING + ) + departmental_flags = DEPARTMENT_BITFLAG_SCIENCE | DEPARTMENT_BITFLAG_ENGINEERING + +/datum/design_techweb/board/chemavator_storage_upper + SET_CIRCUIT_DESIGN_NAMEDESC("smartfridge smart chemavator - upper") + id = "chemavator_storage_upper_circuit" + build_path = /obj/item/circuitboard/smartfridge/chemvator + + category = list( + RND_CATEGORY_COMPUTER + RND_SUBCATEGORY_MACHINE_ENGINEERING + ) + departmental_flags = DEPARTMENT_BITFLAG_SCIENCE | DEPARTMENT_BITFLAG_ENGINEERING + +/datum/design_techweb/board/chemavator_storage_lower + SET_CIRCUIT_DESIGN_NAMEDESC("smartfridge smart chemavator - lower") + id = "chemavator_storage_lower_circuit" + build_path = /obj/item/circuitboard/smartfridge/chemvator/down + + category = list( + RND_CATEGORY_COMPUTER + RND_SUBCATEGORY_MACHINE_ENGINEERING + ) + departmental_flags = DEPARTMENT_BITFLAG_SCIENCE | DEPARTMENT_BITFLAG_ENGINEERING diff --git a/code/modules/research/tg/designs/boards/misc.dm b/code/modules/research/tg/designs/boards/misc.dm index 1ac2da3260..e624943428 100644 --- a/code/modules/research/tg/designs/boards/misc.dm +++ b/code/modules/research/tg/designs/boards/misc.dm @@ -325,3 +325,14 @@ RND_CATEGORY_COMPUTER + RND_SUBCATEGORY_MACHINE_SERVICE ) departmental_flags = DEPARTMENT_BITFLAG_SCIENCE | DEPARTMENT_BITFLAG_SERVICE + + +/datum/design_techweb/board/account_console + SET_CIRCUIT_DESIGN_NAMEDESC("account database console") + id = "account_console" + build_type = AUTOLATHE | IMPRINTER // Simple circuit + build_path = /obj/item/circuitboard/account_console + category = list( + RND_CATEGORY_COMPUTER + RND_SUBCATEGORY_MACHINE_SERVICE + ) + departmental_flags = DEPARTMENT_BITFLAG_SCIENCE | DEPARTMENT_BITFLAG_COMMAND diff --git a/code/modules/research/tg/designs/boards/telecomms.dm b/code/modules/research/tg/designs/boards/telecomms.dm index 738fb6b59e..7c57f5dea7 100644 --- a/code/modules/research/tg/designs/boards/telecomms.dm +++ b/code/modules/research/tg/designs/boards/telecomms.dm @@ -74,6 +74,11 @@ id = "comm_traffic" build_path = /obj/item/circuitboard/comm_traffic +/datum/design_techweb/board/tcom/message_server + SET_CIRCUIT_DESIGN_NAMEDESC("message server") + id = "message_server" + build_path = /obj/item/circuitboard/message_server + // Telecomm parts /datum/design_techweb/subspace desc = "Complex components used to construct and repair telecomms machinery." diff --git a/code/modules/research/tg/techwebs/nodes/engi_nodes.dm b/code/modules/research/tg/techwebs/nodes/engi_nodes.dm index 98c2678b18..8583b6c72b 100644 --- a/code/modules/research/tg/techwebs/nodes/engi_nodes.dm +++ b/code/modules/research/tg/techwebs/nodes/engi_nodes.dm @@ -107,6 +107,7 @@ "tcom-receiver", "tcom-exonet_node", "message_monitor", + "message_server", "comm_monitor", "comm_server", "ntnet_relay", @@ -200,6 +201,7 @@ "large_light_tube", "floor_light", "electrochromic", + "mass_driver_button", // "crossing_signal", // "guideway_sensor", // "manuunloader", @@ -236,6 +238,7 @@ "smes_cell", "grid_checker", "breakerbox", + "hydromagnetic_trap", "tesla_coil", "rtg", // "apc_control", @@ -377,6 +380,30 @@ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) announce_channels = list(CHANNEL_ENGINEERING,CHANNEL_MEDICAL) + +/datum/techweb_node/smartfridges + id = TECHWEB_NODE_SMARTFRIDGES + display_name = "Smart Fridges" + description = "Is it the space that makes the fridge smart, or the fridge that makes the space smart?" + prereq_ids = list(TECHWEB_NODE_PARTS_UPG) + design_ids = list( + "drying_rack_circuit", + "industrial_sheet_storage_circuit", + "mining_sheet_storage_circuit", + "refrigerated_medicine_storage_circuit", + "secure_refrigerated_medicine_storage_circuit", + "biological_sample_storage_circuit", + "food_storage_circuit", + "drink_storage_circuit", + "drink_showcase_circuit", + "produce_storage_circuit", + "seed_storage_circuit", + "chemavator_storage_upper_circuit", + "chemavator_storage_lower_circuit", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + announce_channels = list(CHANNEL_ENGINEERING) + /datum/techweb_node/cells_empproof id = TECHWEB_NODE_PARTS_EMP_PROOF display_name = "EMP-Proof Parts" diff --git a/code/modules/research/tg/techwebs/nodes/service_nodes.dm b/code/modules/research/tg/techwebs/nodes/service_nodes.dm index 1535e72af1..465339da46 100644 --- a/code/modules/research/tg/techwebs/nodes/service_nodes.dm +++ b/code/modules/research/tg/techwebs/nodes/service_nodes.dm @@ -117,7 +117,7 @@ "gps_exp", // "automated_announcement", "bankmachine", - // "account_console", + "account_console", "idcard", "idrestore_console", "guestpass", diff --git a/code/modules/shieldgen/emergency_shield.dm b/code/modules/shieldgen/emergency_shield.dm index f6fdcf6823..0391c351c3 100644 --- a/code/modules/shieldgen/emergency_shield.dm +++ b/code/modules/shieldgen/emergency_shield.dm @@ -12,6 +12,7 @@ var/health = max_health //The shield can only take so much beating (prevents perma-prisons) var/shield_generate_power = 7500 //how much power we use when regenerating var/shield_idle_power = 1500 //how much power we use when just being sustained. + var/datum/weakref/our_owner /obj/machinery/shield/malfai name = "emergency forcefield" @@ -37,6 +38,9 @@ opacity = 0 density = FALSE update_nearby_tiles() + var/obj/machinery/shieldgen/SG = our_owner.resolve() + if(SG) + SG.deployed_shields -= src . = ..() /obj/machinery/shield/attackby(obj/item/W as obj, mob/user as mob) @@ -131,6 +135,8 @@ pressure_resistance = 2*ONE_ATMOSPHERE req_access = list(ACCESS_ENGINE) var/const/max_health = 100 + var/obj/item/cell/cell + var/cell_type = /obj/item/cell/high var/health = max_health var/active = 0 var/malfunction = 0 //Malfunction causes parts of the shield to slowly dissapate @@ -139,21 +145,39 @@ var/is_open = 0 //Whether or not the wires are exposed var/locked = 0 var/check_delay = 60 //periodically recheck if we need to rebuild a shield + var/power_efficiency = 1 //Inverse. The lower, the more power efficient we are. use_power = USE_POWER_OFF idle_power_usage = 0 /obj/machinery/shieldgen/Initialize(mapload) . = ..() + if(cell_type) + cell = new cell_type(src) AddElement(/datum/element/climbable) /obj/machinery/shieldgen/Destroy() collapse_shields() + if(cell) + QDEL_NULL(cell) + if(LAZYLEN(deployed_shields)) + QDEL_NULL_LIST(deployed_shields) + . = ..() + +/obj/machinery/shieldgen/examine(mob/user) + . = ..() + . += "The generator is [active ? "on" : "off"] and the hatch is [is_open ? "open" : "closed"]." + if(panel_open) + . += "The power cell is [cell ? "installed" : "missing"]." + else + . += "The charge meter reads [cell ? round(cell.percent(),1) : 0]%" + /obj/machinery/shieldgen/proc/shields_up() if(active) return 0 //If it's already turned on, how did this get called? - src.active = 1 + active = TRUE + START_MACHINE_PROCESSING(src) update_icon() create_shields() @@ -161,66 +185,55 @@ var/new_power_usage = 0 for(var/obj/machinery/shield/shield_tile in deployed_shields) new_power_usage += shield_tile.shield_idle_power - update_idle_power_usage(new_power_usage) - update_use_power(USE_POWER_IDLE) /obj/machinery/shieldgen/proc/shields_down() if(!active) return 0 //If it's already off, how did this get called? - src.active = 0 + active = FALSE + STOP_MACHINE_PROCESSING(src) update_icon() collapse_shields() - update_use_power(USE_POWER_OFF) - /obj/machinery/shieldgen/proc/create_shields() for(var/turf/target_tile in range(2, src)) if (is_type_in_list(target_tile,GLOB.shieldgen_blockedturfs) && !(locate(/obj/machinery/shield) in target_tile)) if (malfunction && prob(33) || !malfunction) var/obj/machinery/shield/S = new/obj/machinery/shield(target_tile) deployed_shields += S + S.our_owner = WEAKREF(src) //So it knows to remove itself from our list when it gets qdel'd use_power(S.shield_generate_power) /obj/machinery/shieldgen/proc/collapse_shields() for(var/obj/machinery/shield/shield_tile in deployed_shields) qdel(shield_tile) -/obj/machinery/shieldgen/power_change() - ..() - if(!active) return - if (stat & NOPOWER) - collapse_shields() - else - create_shields() - update_icon() - /obj/machinery/shieldgen/process() - if (!active || (stat & NOPOWER)) - return + if(!active) //This shouldn't happen + shields_down() + update_icon() + + if(cell && cell.charge) + var/power_usage = 0 + for(var/obj/machinery/shield/shield_tile in deployed_shields) + power_usage += shield_tile.shield_idle_power + cell.use(power_usage*CELLRATE) + if(check_delay <= 0) + create_shields() + check_delay = 60 + else + check_delay-- + else + shields_down() + update_icon() if(malfunction) if(deployed_shields.len && prob(5)) qdel(pick(deployed_shields)) - else - if (check_delay <= 0) - create_shields() - - var/new_power_usage = 0 - for(var/obj/machinery/shield/shield_tile in deployed_shields) - new_power_usage += shield_tile.shield_idle_power - - if (new_power_usage != idle_power_usage) - update_idle_power_usage(new_power_usage) - use_power(0) - - check_delay = 60 - else - check_delay-- /obj/machinery/shieldgen/proc/checkhp() if(health <= 30) - src.malfunction = 1 + malfunction = TRUE if(health <= 0) spawn(0) explosion(get_turf(src.loc), 0, 0, 1, 0, 0, 0) @@ -280,7 +293,7 @@ /obj/machinery/shieldgen/emag_act(var/remaining_charges, var/mob/user) if(!malfunction) - malfunction = 1 + malfunction = TRUE update_icon() return 1 @@ -289,10 +302,10 @@ playsound(src, W.usesound, 100, 1) if(is_open) to_chat(user, span_blue("You close the panel.")) - is_open = 0 + is_open = FALSE else to_chat(user, span_blue("You open the panel and expose the wiring.")) - is_open = 1 + is_open = TRUE else if(istype(W, /obj/item/stack/cable_coil) && malfunction && is_open) var/obj/item/stack/cable_coil/coil = W @@ -325,11 +338,29 @@ else if(istype(W, /obj/item/card/id) || istype(W, /obj/item/pda)) if(src.allowed(user)) - src.locked = !src.locked + locked = !locked to_chat(user, "The controls are now [src.locked ? "locked." : "unlocked."]") else to_chat(user, span_red("Access denied.")) + else if(istype(W, /obj/item/cell)) + if(is_open) + if(cell) + to_chat(user, "There is already a power cell inside.") + return + // insert cell + var/obj/item/cell/C = user.get_active_hand() + if(istype(C)) + user.drop_item() + cell = C + C.forceMove(src) + C.add_fingerprint(user) + + user.visible_message(span_notice("[user] inserts a power cell into [src]."), span_notice("You insert the power cell into [src].")) + power_change() + else + to_chat(user, "The hatch must be open to insert a power cell.") + return else ..() diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm index 4ecf5320ce..51d4ece474 100644 --- a/code/modules/surgery/organs_internal.dm +++ b/code/modules/surgery/organs_internal.dm @@ -198,7 +198,7 @@ // Organ Detaching Surgery /////////////////////////////////////////////////////////////// -/datum/surgery_step/internal/detatch_organ/ +/datum/surgery_step/internal/detatch_organ surgery_name = "Detach Organ" allowed_tools = list( diff --git a/code/modules/surgery/robotics.dm b/code/modules/surgery/robotics.dm index 3b224290f9..3c4d80d640 100644 --- a/code/modules/surgery/robotics.dm +++ b/code/modules/surgery/robotics.dm @@ -583,7 +583,7 @@ var/okay = tgui_alert(target,"New name will be '[clean_name]', ok?", "Confirmation",list("Cancel","Ok")) if(okay == "Ok") new_name = clean_name - break //ChompEDIT infinite rename bug + break new_name = sanitizeName(new_name, allow_numbers = TRUE) target.name = new_name diff --git a/code/modules/vehicles/cargo_train.dm b/code/modules/vehicles/cargo_train.dm index 19a3e60c58..632055d5b2 100644 --- a/code/modules/vehicles/cargo_train.dm +++ b/code/modules/vehicles/cargo_train.dm @@ -209,10 +209,12 @@ if(Adjacent(user)) if(on) stop_engine() - else - start_engine() - else - return ..() + return CLICK_ACTION_SUCCESS + + start_engine() + return CLICK_ACTION_SUCCESS + + return ..() /obj/vehicle/train/engine/click_alt(var/mob/user) if(Adjacent(user)) diff --git a/code/modules/vore/resizing/resize_vr.dm b/code/modules/vore/resizing/resize_vr.dm index c877d4e5ce..3c7c394c5b 100644 --- a/code/modules/vore/resizing/resize_vr.dm +++ b/code/modules/vore/resizing/resize_vr.dm @@ -350,13 +350,13 @@ tmob.Weaken(1) var/size_damage_multiplier = size_multiplier - tmob.size_multiplier - // This technically means that I_GRAB will set this value to the same as I_HARM, but + // This technically means that I_GRAB will set this value to the same as I_HURT, but // I_GRAB won't ever trigger the damage-giving code, so it doesn't matter. - // I_HARM: Rand 1-3 multiplied by 1 min or 1.75 max. 1 min 5.25 max damage to each limb. + // I_HURT: Rand 1-3 multiplied by 1 min or 1.75 max. 1 min 5.25 max damage to each limb. // I_DISARM: Perform some HALLOSS damage to the smaller. // Since stunned is broken, let's do this. Rand 15-30 multiplied by 1 min or 1.75 max. 15 holo to 52.5 holo, depending on RNG and size differnece. var/damage = (a_intent == I_DISARM) ? (rand(15, 30) * size_damage_multiplier) : (rand(1, 3) * size_damage_multiplier) - // I_HARM only + // I_HURT only var/calculated_damage = damage / 2 //This will sting, but not kill. Does .5 to 2.625 damage, randomly, to each limb. var/message_pred = null diff --git a/icons/obj/structures/tgs_structures.dmi b/icons/obj/structures/tgs_structures.dmi new file mode 100644 index 0000000000..b70485d5d5 Binary files /dev/null and b/icons/obj/structures/tgs_structures.dmi differ diff --git a/maps/virgo_minitest/virgo_minitest-1.dmm b/maps/virgo_minitest/virgo_minitest-1.dmm index 67d210bad4..284343463a 100644 --- a/maps/virgo_minitest/virgo_minitest-1.dmm +++ b/maps/virgo_minitest/virgo_minitest-1.dmm @@ -3669,10 +3669,10 @@ /area/bridge) "jC" = ( /obj/structure/cable/yellow, -/obj/machinery/power/tesla_coil, /obj/structure/cable/yellow{ icon_state = "0-2" }, +/obj/machinery/power/tesla_coil/pre_mapped, /turf/simulated/floor/airless, /area/space) "jQ" = ( @@ -3854,8 +3854,8 @@ /obj/structure/cable/yellow{ icon_state = "0-2" }, -/obj/machinery/power/tesla_coil, /obj/structure/cable/yellow, +/obj/machinery/power/tesla_coil/pre_mapped, /turf/simulated/floor/airless, /area/space) "lZ" = ( @@ -4433,11 +4433,7 @@ /area/engineering/engine_room) "rY" = ( /obj/structure/cable/cyan, -/obj/machinery/power/emitter{ - anchored = 1; - icon_state = "emitter1"; - state = 1 - }, +/obj/machinery/power/emitter/pre_mapped, /turf/simulated/floor/airless, /area/space) "sf" = ( @@ -4540,7 +4536,7 @@ /obj/effect/floor_decal/techfloor/orange{ dir = 1 }, -/obj/structure/particle_accelerator/particle_emitter/right{ +/obj/structure/particle_accelerator/particle_emitter/right/pre_mapped{ dir = 8 }, /turf/simulated/floor/tiled/techfloor, @@ -5243,10 +5239,10 @@ /turf/simulated/wall/r_wall, /area/submap/pa_room) "AE" = ( -/obj/machinery/particle_accelerator/control_box, /obj/effect/floor_decal/techfloor/orange{ dir = 1 }, +/obj/machinery/particle_accelerator/control_box/pre_mapped, /turf/simulated/floor/tiled/techfloor, /area/submap/pa_room) "AI" = ( @@ -5367,10 +5363,7 @@ /turf/simulated/floor/tiled/techmaint, /area/engineering/engine_monitoring) "BO" = ( -/obj/machinery/field_generator{ - anchored = 1; - state = 1 - }, +/obj/machinery/field_generator/pre_mapped, /turf/simulated/floor/airless, /area/space) "BU" = ( @@ -5399,13 +5392,13 @@ /turf/simulated/floor, /area/submap/pa_room) "BX" = ( -/obj/machinery/power/tesla_coil, /obj/structure/cable/yellow{ icon_state = "0-4" }, /obj/structure/cable/yellow{ icon_state = "0-8" }, +/obj/machinery/power/tesla_coil/pre_mapped, /turf/simulated/floor/airless, /area/space) "Cd" = ( @@ -5541,7 +5534,7 @@ /turf/simulated/floor/tiled, /area/engineering/engine_room) "DZ" = ( -/obj/structure/particle_accelerator/particle_emitter/center{ +/obj/structure/particle_accelerator/particle_emitter/center/pre_mapped{ dir = 8 }, /turf/simulated/floor/tiled/techfloor, @@ -5960,8 +5953,8 @@ /turf/simulated/floor/tiled/techmaint, /area/engineering/engine_monitoring) "Ke" = ( -/obj/machinery/power/tesla_coil, /obj/structure/cable/yellow, +/obj/machinery/power/tesla_coil/pre_mapped, /turf/simulated/floor/airless, /area/space) "Ki" = ( @@ -6218,7 +6211,7 @@ /area/engineering/engine_monitoring) "MW" = ( /obj/effect/floor_decal/techfloor/orange, -/obj/structure/particle_accelerator/particle_emitter/left{ +/obj/structure/particle_accelerator/particle_emitter/left/pre_mapped{ dir = 8 }, /turf/simulated/floor/tiled/techfloor, @@ -6282,11 +6275,8 @@ /obj/structure/cable/cyan{ icon_state = "0-2" }, -/obj/machinery/power/emitter{ - anchored = 1; - dir = 1; - icon_state = "emitter1"; - state = 1 +/obj/machinery/power/emitter/pre_mapped{ + dir = 1 }, /turf/simulated/floor/airless, /area/space) @@ -6432,10 +6422,10 @@ /turf/simulated/floor/tiled, /area/engineering/engine_room) "OI" = ( -/obj/machinery/power/tesla_coil, /obj/structure/cable/yellow{ icon_state = "0-2" }, +/obj/machinery/power/tesla_coil/pre_mapped, /turf/simulated/floor/airless, /area/space) "OL" = ( @@ -6873,9 +6863,7 @@ /turf/simulated/floor/tiled/techfloor/grid, /area/submap/pa_room) "TI" = ( -/obj/machinery/the_singularitygen/tesla{ - anchored = 1 - }, +/obj/machinery/the_singularitygen/tesla/pre_mapped, /turf/simulated/floor/airless, /area/space) "TL" = ( @@ -7019,7 +7007,7 @@ /turf/space, /area/space) "Vk" = ( -/obj/machinery/power/grounding_rod, +/obj/machinery/power/grounding_rod/pre_mapped, /turf/simulated/floor/airless, /area/space) "Vp" = ( @@ -7103,7 +7091,7 @@ /turf/simulated/floor, /area/submap/pa_room) "WR" = ( -/obj/structure/particle_accelerator/fuel_chamber{ +/obj/structure/particle_accelerator/fuel_chamber/pre_mapped{ dir = 8 }, /turf/simulated/floor/tiled/techfloor, @@ -7165,15 +7153,15 @@ /turf/simulated/floor, /area/engineering/engine_room) "XH" = ( -/obj/structure/particle_accelerator/end_cap{ - dir = 8 - }, /obj/effect/floor_decal/techfloor/orange{ dir = 4 }, /obj/effect/floor_decal/techfloor/hole{ dir = 4 }, +/obj/structure/particle_accelerator/end_cap/pre_mapped{ + dir = 8 + }, /turf/simulated/floor/tiled/techfloor, /area/submap/pa_room) "XI" = ( @@ -7319,7 +7307,7 @@ /turf/simulated/floor, /area/engineering/workshop) "Zi" = ( -/obj/structure/particle_accelerator/power_box{ +/obj/structure/particle_accelerator/power_box/pre_mapped{ dir = 8 }, /turf/simulated/floor/tiled/techfloor, diff --git a/vorestation.dme b/vorestation.dme index e43d7c82f6..50fb469552 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -604,6 +604,7 @@ #include "code\controllers\subsystems\pois.dm" #include "code\controllers\subsystems\profiler.dm" #include "code\controllers\subsystems\radiation.dm" +#include "code\controllers\subsystems\reflector.dm" #include "code\controllers\subsystems\research.dm" #include "code\controllers\subsystems\robot_sprites.dm" #include "code\controllers\subsystems\runechat.dm" @@ -1818,6 +1819,7 @@ #include "code\game\objects\items\weapons\circuitboards\other.dm" #include "code\game\objects\items\weapons\circuitboards\computer\air_management.dm" #include "code\game\objects\items\weapons\circuitboards\computer\camera_monitor.dm" +#include "code\game\objects\items\weapons\circuitboards\computer\command.dm" #include "code\game\objects\items\weapons\circuitboards\computer\computer.dm" #include "code\game\objects\items\weapons\circuitboards\computer\research.dm" #include "code\game\objects\items\weapons\circuitboards\computer\shuttle.dm" @@ -1842,6 +1844,7 @@ #include "code\game\objects\items\weapons\circuitboards\machinery\research.dm" #include "code\game\objects\items\weapons\circuitboards\machinery\shieldgen.dm" #include "code\game\objects\items\weapons\circuitboards\machinery\ships.dm" +#include "code\game\objects\items\weapons\circuitboards\machinery\smartfridges.dm" #include "code\game\objects\items\weapons\circuitboards\machinery\telecomms.dm" #include "code\game\objects\items\weapons\circuitboards\machinery\unary_atmos.dm" #include "code\game\objects\items\weapons\grenades\anti_photon_grenade.dm" @@ -2001,6 +2004,7 @@ #include "code\game\objects\structures\pillows.dm" #include "code\game\objects\structures\plasticflaps.dm" #include "code\game\objects\structures\railing.dm" +#include "code\game\objects\structures\reflectors.dm" #include "code\game\objects\structures\safe.dm" #include "code\game\objects\structures\salvageable.dm" #include "code\game\objects\structures\signs.dm"