mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2026-01-03 22:13:50 +00:00
Implements the Tesla engine and supporting features (#4539)
* Adds "typecache" utility functions. A fast way to filter lists by type. Ported from TG * Ports the "orbit" feature and subsystem from TG * Adds a feature that allows mobs and objs to "orbit" around some atom. They literally are moved around in circles. See the `orbit` proc in orbit.dm. * Adds a subsystem that processes the actual movement of orbiting items. * Adds utility methods for common machinery behavior. * Adds default_unfasten_wrench which handles the standard anchor/unanchor behavior of wrenches being used on machines. Together with the other default_x_tool machinery procs we can eliminate having that code duplicated in dozens of places! * Adds is_wire_tool proc to easily detect when a machine is hit with a tool that should open its wires UI (if it has one). Based on ideas from Paradise, with improvements for us. * Implements the Tesla Engine Ported from a mixture of TG and Paradise code and assets: Edison's Bane Includes the tesla energy ball itself, the generator that makes it, tesla coils, grounding rods, the circuits and frames to build them. * Switch dusting to zapping on impact and spin better Ported /tg SpinAnimation which supports more than triangles.
This commit is contained in:
@@ -517,11 +517,15 @@
|
||||
E.state = 2
|
||||
E.connect_to_network()
|
||||
E.active = TRUE
|
||||
|
||||
for(var/obj/machinery/field_generator/F in world)
|
||||
if(istype(get_area(F), /area/space))
|
||||
F.Varedit_start = 1
|
||||
|
||||
for(var/obj/machinery/power/grounding_rod/GR in world)
|
||||
GR.anchored = TRUE
|
||||
GR.update_icon()
|
||||
for(var/obj/machinery/power/tesla_coil/TC in world)
|
||||
TC.anchored = TRUE
|
||||
TC.update_icon()
|
||||
for(var/obj/structure/particle_accelerator/PA in world)
|
||||
PA.anchored = TRUE
|
||||
PA.construction_state = 3
|
||||
@@ -531,25 +535,6 @@
|
||||
PA.construction_state = 3
|
||||
PA.update_icon()
|
||||
|
||||
spawn(30)
|
||||
for(var/obj/machinery/the_singularitygen/G in world)
|
||||
if(G.anchored)
|
||||
var/obj/singularity/S = new /obj/singularity(get_turf(G), 50)
|
||||
spawn(0)
|
||||
qdel(G)
|
||||
S.energy = 1750
|
||||
S.current_size = 7
|
||||
S.icon = 'icons/effects/224x224.dmi'
|
||||
S.icon_state = "singularity_s7"
|
||||
S.pixel_x = -96
|
||||
S.pixel_y = -96
|
||||
S.grav_pull = 0
|
||||
//S.consume_range = 3
|
||||
S.dissipate = 0
|
||||
//S.dissipate_delay = 10
|
||||
//S.dissipate_track = 0
|
||||
//S.dissipate_strength = 10
|
||||
|
||||
for(var/obj/machinery/power/rad_collector/Rad in world)
|
||||
if(Rad.anchored)
|
||||
if(!Rad.P)
|
||||
|
||||
@@ -138,6 +138,14 @@
|
||||
..()
|
||||
return
|
||||
|
||||
// Power machinery should also connect/disconnect from the network.
|
||||
/obj/machinery/power/default_unfasten_wrench(var/mob/user, var/obj/item/weapon/wrench/W, var/time = 20)
|
||||
if((. = ..()))
|
||||
if(anchored)
|
||||
connect_to_network()
|
||||
else
|
||||
disconnect_from_network()
|
||||
|
||||
// Used for power spikes by the engine, has specific effects on different machines.
|
||||
/obj/machinery/power/proc/overload(var/obj/machinery/power/source)
|
||||
return
|
||||
|
||||
@@ -8,11 +8,12 @@
|
||||
density = 1
|
||||
use_power = 0
|
||||
var/energy = 0
|
||||
var/creation_type = /obj/singularity
|
||||
|
||||
/obj/machinery/the_singularitygen/process()
|
||||
var/turf/T = get_turf(src)
|
||||
if(src.energy >= 200)
|
||||
new /obj/singularity/(T, 50)
|
||||
new creation_type(T, 50)
|
||||
if(src) qdel(src)
|
||||
|
||||
/obj/machinery/the_singularitygen/attackby(obj/item/W, mob/user)
|
||||
|
||||
@@ -29,15 +29,11 @@
|
||||
|
||||
var/chained = 0//Adminbus chain-grab
|
||||
|
||||
/obj/singularity/New(loc, var/starting_energy = 50, var/temp = 0)
|
||||
/obj/singularity/New(loc, var/starting_energy = 50)
|
||||
//CARN: admin-alert for chuckle-fuckery.
|
||||
admin_investigate_setup()
|
||||
energy = starting_energy
|
||||
|
||||
if (temp)
|
||||
spawn (temp)
|
||||
qdel(src)
|
||||
|
||||
..()
|
||||
processing_objects += src
|
||||
for(var/obj/machinery/power/singularity_beacon/singubeacon in machines)
|
||||
|
||||
133
code/modules/power/tesla/coil.dm
Normal file
133
code/modules/power/tesla/coil.dm
Normal file
@@ -0,0 +1,133 @@
|
||||
/obj/machinery/power/tesla_coil
|
||||
name = "tesla coil"
|
||||
desc = "For the union!"
|
||||
icon = 'icons/obj/tesla_engine/tesla_coil.dmi'
|
||||
icon_state = "coil0"
|
||||
anchored = FALSE
|
||||
density = TRUE
|
||||
|
||||
// Executing a traitor caught releasing tesla was never this fun!
|
||||
can_buckle = TRUE
|
||||
buckle_lying = FALSE
|
||||
|
||||
circuit = /obj/item/weapon/circuitboard/tesla_coil
|
||||
|
||||
var/power_loss = 2
|
||||
var/input_power_multiplier = 1
|
||||
var/zap_cooldown = 100
|
||||
var/last_zap = 0
|
||||
var/datum/wires/tesla_coil/wires = null
|
||||
|
||||
/obj/machinery/power/tesla_coil/New()
|
||||
..()
|
||||
wires = new(src)
|
||||
|
||||
/obj/machinery/power/tesla_coil/initialize()
|
||||
. = ..()
|
||||
default_apply_parts()
|
||||
|
||||
/obj/machinery/power/tesla_coil/Destroy()
|
||||
qdel_null(wires)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/tesla_coil/RefreshParts()
|
||||
var/power_multiplier = 0
|
||||
zap_cooldown = 100
|
||||
for(var/obj/item/weapon/stock_parts/capacitor/C in component_parts)
|
||||
power_multiplier += C.rating
|
||||
zap_cooldown -= (C.rating * 20)
|
||||
input_power_multiplier = power_multiplier
|
||||
|
||||
|
||||
/obj/machinery/power/tesla_coil/update_icon()
|
||||
if(panel_open)
|
||||
icon_state = "coil_open[anchored]"
|
||||
else
|
||||
icon_state = "coil[anchored]"
|
||||
|
||||
/obj/machinery/power/tesla_coil/attackby(obj/item/W, mob/user, params)
|
||||
src.add_fingerprint(user)
|
||||
|
||||
//if(default_deconstruction_screwdriver(user, "coil_open[anchored]", "coil[anchored]", W))
|
||||
if(default_deconstruction_screwdriver(user, W))
|
||||
return
|
||||
if(default_part_replacement(user, W))
|
||||
return
|
||||
if(default_unfasten_wrench(user, W))
|
||||
return
|
||||
if(default_deconstruction_crowbar(user, W))
|
||||
return
|
||||
if(is_wire_tool(W))
|
||||
return wires.Interact(user)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/tesla_coil/attack_hand(mob/user)
|
||||
if(user.a_intent == I_GRAB && user_buckle_mob(user.pulling, user))
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/machinery/power/tesla_coil/tesla_act(var/power)
|
||||
if(anchored && !panel_open)
|
||||
being_shocked = TRUE
|
||||
//don't lose arc power when it's not connected to anything
|
||||
//please place tesla coils all around the station to maximize effectiveness
|
||||
var/power_produced = powernet ? power / power_loss : power
|
||||
add_avail(power_produced*input_power_multiplier)
|
||||
flick("coilhit", src)
|
||||
playsound(src.loc, 'sound/effects/lightningshock.ogg', 100, 1, extrarange = 5)
|
||||
tesla_zap(src, 5, power_produced)
|
||||
//addtimer(CALLBACK(src, .proc/reset_shocked), 10)
|
||||
spawn(10) reset_shocked()
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/machinery/power/tesla_coil/proc/zap()
|
||||
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)
|
||||
draw_power(power)
|
||||
playsound(src.loc, 'sound/effects/lightningshock.ogg', 100, 1, extrarange = 5)
|
||||
tesla_zap(src, 10, power/(coeff/2))
|
||||
|
||||
/obj/machinery/power/grounding_rod
|
||||
name = "grounding rod"
|
||||
desc = "Keep an area from being fried from Edison's Bane."
|
||||
icon = 'icons/obj/tesla_engine/tesla_coil.dmi'
|
||||
icon_state = "grounding_rod0"
|
||||
anchored = FALSE
|
||||
density = TRUE
|
||||
|
||||
can_buckle = TRUE
|
||||
buckle_lying = FALSE
|
||||
|
||||
/obj/machinery/power/grounding_rod/update_icon()
|
||||
if(panel_open)
|
||||
icon_state = "grounding_rod_open[anchored]"
|
||||
else
|
||||
icon_state = "grounding_rod[anchored]"
|
||||
|
||||
/obj/machinery/power/grounding_rod/attackby(obj/item/W, mob/user, params)
|
||||
//if(default_deconstruction_screwdriver(user, "grounding_rod_open[anchored]", "grounding_rod[anchored]", W))
|
||||
if(default_deconstruction_screwdriver(user, W))
|
||||
return
|
||||
if(default_part_replacement(user, W))
|
||||
return
|
||||
if(default_unfasten_wrench(user, W))
|
||||
return
|
||||
if(default_deconstruction_crowbar(user, W))
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/grounding_rod/attack_hand(mob/user)
|
||||
if(user.a_intent == I_GRAB && user_buckle_mob(user.pulling, user))
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/machinery/power/grounding_rod/tesla_act(var/power)
|
||||
if(anchored && !panel_open)
|
||||
flick("grounding_rodhit", src)
|
||||
else
|
||||
..()
|
||||
298
code/modules/power/tesla/energy_ball.dm
Normal file
298
code/modules/power/tesla/energy_ball.dm
Normal file
@@ -0,0 +1,298 @@
|
||||
#define TESLA_DEFAULT_POWER 1738260
|
||||
#define TESLA_MINI_POWER 869130
|
||||
|
||||
/obj/singularity/energy_ball
|
||||
name = "energy ball"
|
||||
desc = "An energy ball."
|
||||
icon = 'icons/obj/tesla_engine/energy_ball.dmi'
|
||||
icon_state = "energy_ball"
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
current_size = STAGE_TWO
|
||||
move_self = 1
|
||||
grav_pull = 0
|
||||
contained = 0
|
||||
density = TRUE
|
||||
energy = 0
|
||||
dissipate = 1
|
||||
dissipate_delay = 5
|
||||
dissipate_strength = 1
|
||||
var/list/orbiting_balls = list()
|
||||
var/miniball = FALSE
|
||||
var/produced_power
|
||||
var/energy_to_raise = 32
|
||||
var/energy_to_lower = -20
|
||||
|
||||
/obj/singularity/energy_ball/New(loc, starting_energy = 50, is_miniball = FALSE)
|
||||
..()
|
||||
miniball = is_miniball
|
||||
|
||||
/obj/singularity/energy_ball/initialize()
|
||||
. = ..()
|
||||
if(!miniball)
|
||||
set_light(10, 7, "#EEEEFF")
|
||||
|
||||
/obj/singularity/energy_ball/ex_act(severity, target)
|
||||
return
|
||||
|
||||
/obj/singularity/energy_ball/Destroy()
|
||||
if(orbiting && istype(orbiting.orbiting, /obj/singularity/energy_ball))
|
||||
var/obj/singularity/energy_ball/EB = orbiting.orbiting
|
||||
EB.orbiting_balls -= src
|
||||
|
||||
for(var/ball in orbiting_balls)
|
||||
var/obj/singularity/energy_ball/EB = ball
|
||||
qdel(EB)
|
||||
|
||||
. = ..()
|
||||
|
||||
/obj/singularity/energy_ball/admin_investigate_setup()
|
||||
if(miniball)
|
||||
return //don't annnounce miniballs
|
||||
..()
|
||||
|
||||
|
||||
/obj/singularity/energy_ball/process(var/wait = 20)
|
||||
set waitfor = FALSE
|
||||
if(!orbiting)
|
||||
handle_energy()
|
||||
|
||||
move_the_basket_ball(max(wait - 5, 4 + orbiting_balls.len * 1.5))
|
||||
|
||||
playsound(src.loc, 'sound/effects/lightningbolt.ogg', 100, 1, extrarange = 30)
|
||||
|
||||
set_dir(tesla_zap(src.loc, 7, TESLA_DEFAULT_POWER, TRUE))
|
||||
|
||||
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)
|
||||
else
|
||||
energy = 0 // ensure we dont have miniballs of miniballs
|
||||
|
||||
/obj/singularity/energy_ball/examine(mob/user)
|
||||
..()
|
||||
if(orbiting_balls.len)
|
||||
to_chat(user, "The amount of orbiting mini-balls is [orbiting_balls.len].")
|
||||
|
||||
|
||||
/obj/singularity/energy_ball/proc/move_the_basket_ball(var/move_amount)
|
||||
//we face the last thing we zapped, so this lets us favor that direction a bit
|
||||
var/move_bias = dir
|
||||
for(var/i in 0 to move_amount)
|
||||
var/move_dir = pick(global.alldirs + move_bias) //ensures large-ball teslas don't just sit around
|
||||
if(target && prob(10))
|
||||
move_dir = get_dir(src,target)
|
||||
var/turf/T = get_step(src, move_dir)
|
||||
if(can_move(T))
|
||||
forceMove(T)
|
||||
set_dir(move_dir)
|
||||
for(var/mob/living/carbon/C in loc)
|
||||
dust_mobs(C)
|
||||
sleep(1) // So movement is smooth
|
||||
|
||||
/obj/singularity/energy_ball/proc/handle_energy()
|
||||
if(energy >= energy_to_raise)
|
||||
energy_to_lower = energy_to_raise - 20
|
||||
energy_to_raise = energy_to_raise * 1.25
|
||||
|
||||
playsound(src.loc, 'sound/effects/lightning_chargeup.ogg', 100, 1, extrarange = 30)
|
||||
//addtimer(CALLBACK(src, .proc/new_mini_ball), 100)
|
||||
spawn(100) new_mini_ball()
|
||||
|
||||
else if(energy < energy_to_lower && orbiting_balls.len)
|
||||
energy_to_raise = energy_to_raise / 1.25
|
||||
energy_to_lower = (energy_to_raise / 1.25) - 20
|
||||
|
||||
var/Orchiectomy_target = pick(orbiting_balls)
|
||||
qdel(Orchiectomy_target)
|
||||
|
||||
else if(orbiting_balls.len)
|
||||
dissipate() //sing code has a much better system.
|
||||
|
||||
/obj/singularity/energy_ball/proc/new_mini_ball()
|
||||
if(!loc)
|
||||
return
|
||||
var/obj/singularity/energy_ball/EB = new(loc, 0, TRUE)
|
||||
|
||||
EB.transform *= pick(0.3, 0.4, 0.5, 0.6, 0.7)
|
||||
var/icon/I = icon(icon,icon_state,dir)
|
||||
|
||||
var/orbitsize = (I.Width() + I.Height()) * pick(0.4, 0.5, 0.6, 0.7, 0.8)
|
||||
orbitsize -= (orbitsize / world.icon_size) * (world.icon_size * 0.25)
|
||||
|
||||
EB.orbit(src, orbitsize, pick(FALSE, TRUE), rand(10, 25), pick(3, 4, 5, 6, 36))
|
||||
|
||||
|
||||
/obj/singularity/energy_ball/Bump(atom/A)
|
||||
dust_mobs(A)
|
||||
|
||||
/obj/singularity/energy_ball/Bumped(atom/movable/AM)
|
||||
dust_mobs(AM)
|
||||
|
||||
/obj/singularity/energy_ball/orbit(obj/singularity/energy_ball/target)
|
||||
if (istype(target))
|
||||
target.orbiting_balls += src
|
||||
//TODO-LESH-DEL global.poi_list -= src
|
||||
target.dissipate_strength = target.orbiting_balls.len
|
||||
|
||||
. = ..()
|
||||
/obj/singularity/energy_ball/stop_orbit()
|
||||
if (orbiting && istype(orbiting.orbiting, /obj/singularity/energy_ball))
|
||||
var/obj/singularity/energy_ball/orbitingball = orbiting.orbiting
|
||||
orbitingball.orbiting_balls -= src
|
||||
orbitingball.dissipate_strength = orbitingball.orbiting_balls.len
|
||||
..()
|
||||
if (!loc && !QDELETED(src))
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/singularity/energy_ball/proc/dust_mobs(atom/A)
|
||||
if(isliving(A))
|
||||
var/mob/living/L = A
|
||||
if(L.incorporeal_move)
|
||||
return
|
||||
if(!iscarbon(A))
|
||||
return
|
||||
for(var/obj/machinery/power/grounding_rod/GR in orange(src, 2))
|
||||
if(GR.anchored)
|
||||
return
|
||||
var/mob/living/carbon/C = A
|
||||
// C.dust() - Changing to do fatal elecrocution instead
|
||||
C.electrocute_act(500, src, def_zone = BP_TORSO)
|
||||
|
||||
/proc/tesla_zap(atom/source, zap_range = 3, power, explosive = FALSE, stun_mobs = TRUE)
|
||||
. = source.dir
|
||||
if(power < 1000)
|
||||
return
|
||||
|
||||
var/closest_dist = 0
|
||||
var/closest_atom
|
||||
var/obj/machinery/power/tesla_coil/closest_tesla_coil
|
||||
var/obj/machinery/power/grounding_rod/closest_grounding_rod
|
||||
var/mob/living/closest_mob
|
||||
var/obj/machinery/closest_machine
|
||||
var/obj/structure/closest_structure
|
||||
var/obj/structure/blob/closest_blob
|
||||
var/static/things_to_shock = typecacheof(list(/obj/machinery, /mob/living, /obj/structure))
|
||||
var/static/blacklisted_tesla_types = typecacheof(list(
|
||||
/obj/machinery/atmospherics,
|
||||
/obj/machinery/power/emitter,
|
||||
/obj/machinery/field_generator,
|
||||
/mob/living/simple_animal,
|
||||
/obj/machinery/door/blast,
|
||||
/obj/machinery/particle_accelerator/control_box,
|
||||
/obj/structure/particle_accelerator/fuel_chamber,
|
||||
/obj/structure/particle_accelerator/particle_emitter/center,
|
||||
/obj/structure/particle_accelerator/particle_emitter/left,
|
||||
/obj/structure/particle_accelerator/particle_emitter/right,
|
||||
/obj/structure/particle_accelerator/power_box,
|
||||
/obj/structure/particle_accelerator/end_cap,
|
||||
/obj/machinery/containment_field,
|
||||
/obj/structure/disposalpipe,
|
||||
/obj/structure/sign,
|
||||
/obj/machinery/gateway,
|
||||
/obj/structure/lattice,
|
||||
/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))
|
||||
if(istype(A, /obj/machinery/power/tesla_coil))
|
||||
var/dist = get_dist(source, A)
|
||||
var/obj/machinery/power/tesla_coil/C = A
|
||||
if(dist <= zap_range && (dist < closest_dist || !closest_tesla_coil) && !C.being_shocked)
|
||||
closest_dist = dist
|
||||
|
||||
//we use both of these to save on istype and typecasting overhead later on
|
||||
//while still allowing common code to run before hand
|
||||
closest_tesla_coil = C
|
||||
closest_atom = C
|
||||
|
||||
|
||||
else if(closest_tesla_coil)
|
||||
continue //no need checking these other things
|
||||
|
||||
else if(istype(A, /obj/machinery/power/grounding_rod))
|
||||
var/dist = get_dist(source, A)-2
|
||||
if(dist <= zap_range && (dist < closest_dist || !closest_grounding_rod))
|
||||
closest_grounding_rod = A
|
||||
closest_atom = A
|
||||
closest_dist = dist
|
||||
|
||||
else if(closest_grounding_rod)
|
||||
continue
|
||||
|
||||
else if(isliving(A))
|
||||
var/dist = get_dist(source, A)
|
||||
var/mob/living/L = A
|
||||
if(dist <= zap_range && (dist < closest_dist || !closest_mob) && L.stat != DEAD && !(L.status_flags & GODMODE))
|
||||
closest_mob = L
|
||||
closest_atom = A
|
||||
closest_dist = dist
|
||||
|
||||
else if(closest_mob)
|
||||
continue
|
||||
|
||||
else if(istype(A, /obj/machinery))
|
||||
var/obj/machinery/M = A
|
||||
var/dist = get_dist(source, A)
|
||||
if(dist <= zap_range && (dist < closest_dist || !closest_machine) && !M.being_shocked)
|
||||
closest_machine = M
|
||||
closest_atom = A
|
||||
closest_dist = dist
|
||||
|
||||
else if(closest_mob)
|
||||
continue
|
||||
|
||||
else if(istype(A, /obj/structure/blob))
|
||||
var/obj/structure/blob/B = A
|
||||
var/dist = get_dist(source, A)
|
||||
if(dist <= zap_range && (dist < closest_dist || !closest_tesla_coil) && !B.being_shocked)
|
||||
closest_blob = B
|
||||
closest_atom = A
|
||||
closest_dist = dist
|
||||
|
||||
else if(closest_blob)
|
||||
continue
|
||||
|
||||
else if(istype(A, /obj/structure))
|
||||
var/obj/structure/S = A
|
||||
var/dist = get_dist(source, A)
|
||||
if(dist <= zap_range && (dist < closest_dist || !closest_tesla_coil) && !S.being_shocked)
|
||||
closest_structure = S
|
||||
closest_atom = A
|
||||
closest_dist = dist
|
||||
|
||||
//Alright, we've done our loop, now lets see if was anything interesting in range
|
||||
if(closest_atom)
|
||||
//common stuff
|
||||
source.Beam(closest_atom, icon_state="lightning[rand(1,12)]", time=5, maxdistance = INFINITY)
|
||||
var/zapdir = get_dir(source, closest_atom)
|
||||
if(zapdir)
|
||||
. = zapdir
|
||||
|
||||
//per type stuff:
|
||||
if(closest_tesla_coil)
|
||||
closest_tesla_coil.tesla_act(power, explosive, stun_mobs)
|
||||
|
||||
else if(closest_grounding_rod)
|
||||
closest_grounding_rod.tesla_act(power, explosive, stun_mobs)
|
||||
|
||||
else if(closest_mob)
|
||||
var/shock_damage = Clamp(round(power/400), 10, 90) + rand(-5, 5)
|
||||
closest_mob.electrocute_act(shock_damage, source, 1/*, tesla_shock = 1, stun = stun_mobs*/)
|
||||
if(issilicon(closest_mob))
|
||||
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
|
||||
else
|
||||
tesla_zap(closest_mob, 5, power / 1.5, explosive, stun_mobs)
|
||||
|
||||
else if(closest_machine)
|
||||
closest_machine.tesla_act(power, explosive, stun_mobs)
|
||||
|
||||
else if(closest_blob)
|
||||
closest_blob.tesla_act(power, explosive, stun_mobs)
|
||||
|
||||
else if(closest_structure)
|
||||
closest_structure.tesla_act(power, explosive, stun_mobs)
|
||||
10
code/modules/power/tesla/generator.dm
Normal file
10
code/modules/power/tesla/generator.dm
Normal file
@@ -0,0 +1,10 @@
|
||||
/obj/machinery/the_singularitygen/tesla
|
||||
name = "energy ball generator"
|
||||
desc = "Makes the wardenclyffe look like a child's plaything when shot with a particle accelerator."
|
||||
icon = 'icons/obj/tesla_engine/tesla_generator.dmi'
|
||||
icon_state = "TheSingGen"
|
||||
creation_type = /obj/singularity/energy_ball
|
||||
|
||||
/obj/machinery/the_singularitygen/tesla/tesla_act(power, explosive = FALSE)
|
||||
if(explosive)
|
||||
energy += power
|
||||
31
code/modules/power/tesla/telsa_construction.dm
Normal file
31
code/modules/power/tesla/telsa_construction.dm
Normal file
@@ -0,0 +1,31 @@
|
||||
//////////////////////////
|
||||
// Circuits and Research
|
||||
//////////////////////////
|
||||
|
||||
// Tesla coils are built as machines using a circuit researchable in RnD
|
||||
/obj/item/weapon/circuitboard/tesla_coil
|
||||
name = T_BOARD("tesla coil")
|
||||
build_path = /obj/machinery/power/tesla_coil
|
||||
board_type = new /datum/frame/frame_types/machine
|
||||
origin_tech = list(TECH_MAGNET = 2, TECH_POWER = 4)
|
||||
req_components = list(/obj/item/weapon/stock_parts/capacitor = 1)
|
||||
|
||||
/datum/design/circuit/tesla_coil
|
||||
name = "Machine Design (Tesla Coil Board)"
|
||||
desc = "The circuit board for a tesla coil."
|
||||
id = "tesla_coil"
|
||||
build_path = /obj/item/weapon/circuitboard/tesla_coil
|
||||
req_tech = list(TECH_MAGNET = 2, TECH_POWER = 4)
|
||||
sort_string = "MAAAC"
|
||||
|
||||
// Grounding rods can be built as machines using a circuit made in an autolathe.
|
||||
/obj/item/weapon/circuitboard/grounding_rod
|
||||
name = T_BOARD("grounding rod")
|
||||
build_path = /obj/machinery/power/grounding_rod
|
||||
board_type = new /datum/frame/frame_types/machine
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
|
||||
req_components = list()
|
||||
|
||||
/datum/category_item/autolathe/engineering/grounding_rod
|
||||
name = "grounding rod electronics"
|
||||
path = /obj/item/weapon/circuitboard/grounding_rod
|
||||
68
code/modules/power/tesla/tesla_act.dm
Normal file
68
code/modules/power/tesla/tesla_act.dm
Normal file
@@ -0,0 +1,68 @@
|
||||
////////////////////////////////////////
|
||||
// Vars and Default tesla_act behavior
|
||||
////////////////////////////////////////
|
||||
|
||||
/obj
|
||||
var/being_shocked = FALSE
|
||||
|
||||
/obj/proc/tesla_act(var/power)
|
||||
being_shocked = TRUE
|
||||
var/power_bounced = power / 2
|
||||
tesla_zap(src, 3, power_bounced)
|
||||
//addtimer(CALLBACK(src, .proc/reset_shocked), 10)
|
||||
//schedule_task_with_source_in(10, src, .proc/reset_shocked)
|
||||
spawn(10) reset_shocked()
|
||||
|
||||
/obj/proc/reset_shocked()
|
||||
being_shocked = FALSE
|
||||
|
||||
// Overrides for behavior on specific types
|
||||
|
||||
/obj/structure/blob/tesla_act(power)
|
||||
..()
|
||||
adjust_integrity(-power/400)
|
||||
|
||||
/obj/machinery/nuclearbomb/tesla_act(power, explosive)
|
||||
..()
|
||||
if(explosive)
|
||||
qdel(src)//like the singulo, tesla deletes it. stops it from exploding over and over
|
||||
|
||||
/obj/machinery/tesla_act(power, explosive = FALSE)
|
||||
..()
|
||||
if(prob(85) && explosive)
|
||||
explosion(loc, 1, 2, 4, /*flame_range = 2,*/ adminlog = FALSE/*, smoke = FALSE*/)
|
||||
else if(prob(50))
|
||||
emp_act(2)
|
||||
else
|
||||
ex_act(2)
|
||||
|
||||
/obj/machinery/camera/tesla_act(var/power)//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)
|
||||
if(explosive)
|
||||
explosion(loc, 0, 0, 0/*, flame_range = 5*/, adminlog = FALSE)
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/closet/tesla_act(var/power)
|
||||
..() //extend the zap
|
||||
visible_message("<span class='danger'>[src] is blown apart by the bolt of electricity!</span>", "<span class='danger'>You hear a metallic screeching sound.</span>")
|
||||
dump_contents()
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/reagent_dispensers/fueltank/tesla_act()
|
||||
..() //extend the zap
|
||||
explode()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user