SM, Tesla, and general engineering adjustments [MDB IGNORE] [IDB IGNORE] (#19339)

* Update supermatter.dm

* fix

* clamps these

* gwah

* Stops tesla from zapping unwrenched coils

* tesla upgrade

* unglobals this

* fix these

* Update coil.dm

* Update coil.dm

* Descriptions

* Update coil.dm

* Update coil.dm

* Update coil.dm

* Update coil.dm

* Update coil.dm

* ranges

* UGH

* Update vorestation.dme

* meth

* monster math

* Update coil.dm

* Update coil.dm

* Update coil.dm

* THEY DID THE MATH

* the monster math

* egwah

* desc

* Update coil.dm

* Returns

* Update coil.dm

* Lowers amount gained

* this

* im dumb

* tesy

* Update coil.dm

* Update coil.dm

* fixes initial density on blast doors

* dot

* fixes these

* Mapper Tools

* icon

* these

* Fixes the sound following people

* recursive geigers

* Make this a proc

* Update supermatter.dm

* less ear destroying

* these

* makes canisters not get softlocked

* Hotkeys

* proper return

* Makes shield gen useful. Gets rid of a harddel

Adds hydromagnetic trap

* math

* Makes buttons more clear.

* lol

* Fixes ancient runtime

* Adds craftable mass driver buttons

* button

* fixes this

* Makes misclicks not destroy solar panels

* Update solar.dm

* fix this

* make them both numbers

* upports reflectors

* Update reflector.dm

* Update reflectors.dm

* solar panel and climbable

* Gets rid of 'as X'

* Adds account console

* Update vorestation.dme

* Craftable message server

* Update message_server.dm

* These

* con struct

* Update smartfridge.dm

* whoop

* edits
This commit is contained in:
Cameron Lennox
2026-03-26 22:20:06 -04:00
committed by GitHub
parent f17bc7576c
commit 453080616b
76 changed files with 1316 additions and 244 deletions
+3 -3
View File
@@ -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.
+1 -1
View File
@@ -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
@@ -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
+5
View File
@@ -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 ..()
@@ -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)
. = ..()
@@ -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
@@ -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))
@@ -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))
@@ -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
@@ -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)
@@ -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)
. = ..()
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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))
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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",
+4 -4
View File
@@ -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()
@@ -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()
@@ -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()
@@ -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()
@@ -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()
@@ -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()
@@ -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()
@@ -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()
@@ -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()
+7 -5
View File
@@ -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()
..()
+9 -10
View File
@@ -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
+225 -56
View File
@@ -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
+16 -11
View File
@@ -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))
+4 -1
View File
@@ -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
+10 -10
View File
@@ -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.
+1 -1
View File
@@ -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)
+9 -2
View File
@@ -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)
@@ -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
@@ -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
@@ -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."
@@ -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"
@@ -117,7 +117,7 @@
"gps_exp",
// "automated_announcement",
"bankmachine",
// "account_console",
"account_console",
"idcard",
"idrestore_console",
"guestpass",
+68 -37
View File
@@ -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
..()
+1 -1
View File
@@ -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(
+1 -1
View File
@@ -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
+6 -4
View File
@@ -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))
+3 -3
View File
@@ -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