mirror of
https://github.com/Citadel-Station-13/Citadel-Station-13-RP.git
synced 2025-12-10 12:11:19 +00:00
* Tetherport * sigh * more fixes * shields * more * woo * compile * e * a * Tether, compilable and running not playable tho * Tether, compilable and running not playable tho * Automatic changelog generation for PR #3200 [ci skip] * why * EOL * nukes edited areas. if you had something important in here, you didn't deserve to. * another folder down * one more folder * the refacotring continues * change those * okay * dynamic zlevels * move stufF * reorganize that too * get rid of unneded archives * move talon too and rename that * meh * woop * fixes * move those * fixes * fix * Submap Repathing/Reconciliation * Attempts to fix Gecko invalid variable bug. * Alright. Let's actually fix every bugged instance. * Another round of updates. That same turf issue exists. * Should fix the last of those weird varedits. * One snuck by? * Another round of fixes. * I want to know who put all these var edits in. * Another batch down. * Yet another batch. * A map at a time, at this rate. * I hope these are the last four, but probably not. * Hopefully the last, but probably not. * ANOTHER stealth var_edit that snuck through. * Manually checked the rest of the map files I found. These were updated. * Did the same for bad var_edits. Caught these. * Updates the 140x140. * Sorts Talon and partially adds Point Defense. Too complex for me. * tether_turfs * I think this is it. The last variable bug. * Telenetwork Delenda Est * linterS * fix * extraneous files * woo * mmm * add that in until reagents hardsync * woo * sync * updates * t * weather * i want to rewrite telecomms * test * shift those * woo * move that * FUCK * Fix * fix * or null * shuffle * Fixes * Fixes * Fix * fixes * woo * that * facility safety * that too * move that out * fixes * woops / * rename those * those * woo * test * fixes * woo * exploration map edits changes oxygen tanks to o2 jetpacks, co2 jetpack to an o2, adds pathfinder voidsuit, suit cycler for medical, and fixes access restrictions on the PF's office and locker * mh * Update fueldepot.dmm * woo * woo * woo * fix * utterly fuck you * Automatic changelog generation for PR #3225 [ci skip] * test code * w * that * fieldgens * better * singulo * fixes * fix * fix * adds mirrortools, removes backup implants * why * Prevents falling through catwalks and lattice, stolen from Silicons * Lots of stuff! * Update talon2.dmm * Automatic changelog generation for PR #3226 [ci skip] * Removes Mining Stacker * Slight remap changes to Deck 3, pending more. * Automatic changelog generation for PR #3228 [ci skip] * fix that * that * R&D remap. * Lighting fix and correcting a talon vault issue? * Conflict clean-up. * Multi-floor modifications. Chem change. R&D revert. Etc. * Adds a few extra timeclocks. * Missed the bioregens. Hooray. * Re re readjusts R&D to a lobby design. Adds Space Spice. Maybe fixes Captain spawner. * woo * fix * not that * Xenobotany and Trash Pit adjustments. * proper * De-militarizes Talon. Will Trader-ify them when I wake up. * fix * fix * ashet pls * ashet pls v2 * cleaner * cleaner Co-authored-by: nevimer <77420409+nevimer@users.noreply.github.com> Co-authored-by: CitadelStationBot <citadelstationcommunity@gmail.com> Co-authored-by: Captain277 <agentraven16@gmail.com> Co-authored-by: Mag <86886852+MonaraMir@users.noreply.github.com> Co-authored-by: nik707 <38332985+nik707@users.noreply.github.com> Co-authored-by: TheLordME <58342752+TheLordME@users.noreply.github.com>
344 lines
9.8 KiB
Plaintext
344 lines
9.8 KiB
Plaintext
//////////////////////////////
|
|
// POWER MACHINERY BASE CLASS
|
|
//////////////////////////////
|
|
|
|
/////////////////////////////
|
|
// Definitions
|
|
/////////////////////////////
|
|
|
|
/obj/machinery/power
|
|
name = null
|
|
icon = 'icons/obj/power.dmi'
|
|
anchored = 1.0
|
|
var/datum/powernet/powernet = null
|
|
use_power = USE_POWER_OFF
|
|
idle_power_usage = 0
|
|
active_power_usage = 0
|
|
|
|
/obj/machinery/power/Destroy()
|
|
disconnect_from_network()
|
|
disconnect_terminal()
|
|
|
|
return ..()
|
|
|
|
///////////////////////////////
|
|
// General procedures
|
|
//////////////////////////////
|
|
|
|
// common helper procs for all power machines
|
|
/obj/machinery/power/drain_power(var/drain_check, var/surge, var/amount = 0)
|
|
if(drain_check)
|
|
return 1
|
|
|
|
if(powernet && powernet.avail)
|
|
powernet.trigger_warning()
|
|
return powernet.draw_power(amount)
|
|
|
|
/obj/machinery/power/proc/add_avail(var/amount)
|
|
if(powernet)
|
|
powernet.newavail += amount
|
|
|
|
/obj/machinery/power/proc/draw_power(var/amount)
|
|
if(powernet)
|
|
return powernet.draw_power(amount)
|
|
return 0
|
|
|
|
/obj/machinery/power/proc/surplus()
|
|
if(powernet)
|
|
return powernet.avail-powernet.load
|
|
else
|
|
return 0
|
|
|
|
/obj/machinery/power/proc/avail()
|
|
if(powernet)
|
|
return powernet.avail
|
|
else
|
|
return 0
|
|
|
|
/obj/machinery/power/proc/viewload()
|
|
if(powernet)
|
|
return powernet.viewload
|
|
else
|
|
return 0
|
|
|
|
/obj/machinery/power/proc/disconnect_terminal() // machines without a terminal will just return, no harm no fowl.
|
|
return
|
|
|
|
// connect the machine to a powernet if a node cable is present on the turf
|
|
/obj/machinery/power/proc/connect_to_network()
|
|
var/turf/T = src.loc
|
|
if(!T || !istype(T))
|
|
return 0
|
|
|
|
var/obj/structure/cable/C = T.get_cable_node() //check if we have a node cable on the machine turf, the first found is picked
|
|
if(!C || !C.powernet)
|
|
return 0
|
|
|
|
C.powernet.add_machine(src)
|
|
return 1
|
|
|
|
// remove and disconnect the machine from its current powernet
|
|
/obj/machinery/power/proc/disconnect_from_network()
|
|
if(!powernet)
|
|
return 0
|
|
powernet.remove_machine(src)
|
|
return 1
|
|
|
|
// attach a wire to a power machine - leads from the turf you are standing on
|
|
//almost never called, overwritten by all power machines but terminal and generator
|
|
/obj/machinery/power/attackby(obj/item/W, mob/user)
|
|
|
|
if(istype(W, /obj/item/stack/cable_coil))
|
|
|
|
var/obj/item/stack/cable_coil/coil = W
|
|
|
|
var/turf/T = user.loc
|
|
|
|
if(!T.is_plating() || !istype(T, /turf/simulated/floor))
|
|
return
|
|
|
|
if(get_dist(src, user) > 1)
|
|
return
|
|
|
|
coil.turf_place(T, user)
|
|
return
|
|
else
|
|
..()
|
|
return
|
|
|
|
// Power machinery should also connect/disconnect from the network.
|
|
/obj/machinery/power/default_unfasten_wrench(var/mob/user, var/obj/item/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
|
|
|
|
// Used by the grid checker upon receiving a power spike.
|
|
/obj/machinery/power/proc/do_grid_check()
|
|
return
|
|
|
|
/obj/machinery/power/proc/power_spike()
|
|
return
|
|
|
|
///////////////////////////////////////////
|
|
// Powernet handling helpers
|
|
//////////////////////////////////////////
|
|
|
|
//returns all the cables WITHOUT a powernet in neighbors turfs,
|
|
//pointing towards the turf the machine is located at
|
|
/obj/machinery/power/proc/get_connections()
|
|
|
|
. = list()
|
|
|
|
var/cdir
|
|
var/turf/T
|
|
|
|
for(var/card in GLOB.cardinal)
|
|
T = get_step(loc,card)
|
|
cdir = get_dir(T,loc)
|
|
|
|
for(var/obj/structure/cable/C in T)
|
|
if(C.powernet) continue
|
|
if(C.d1 == cdir || C.d2 == cdir)
|
|
. += C
|
|
return .
|
|
|
|
//returns all the cables in neighbors turfs,
|
|
//pointing towards the turf the machine is located at
|
|
/obj/machinery/power/proc/get_marked_connections()
|
|
|
|
. = list()
|
|
|
|
var/cdir
|
|
var/turf/T
|
|
|
|
for(var/card in GLOB.cardinal)
|
|
T = get_step(loc,card)
|
|
cdir = get_dir(T,loc)
|
|
|
|
for(var/obj/structure/cable/C in T)
|
|
if(C.d1 == cdir || C.d2 == cdir)
|
|
. += C
|
|
return .
|
|
|
|
//returns all the NODES (O-X) cables WITHOUT a powernet in the turf the machine is located at
|
|
/obj/machinery/power/proc/get_indirect_connections()
|
|
. = list()
|
|
for(var/obj/structure/cable/C in loc)
|
|
if(C.powernet) continue
|
|
if(C.d1 == 0) // the cable is a node cable
|
|
. += C
|
|
return .
|
|
|
|
///////////////////////////////////////////
|
|
// GLOBAL PROCS for powernets handling
|
|
//////////////////////////////////////////
|
|
|
|
|
|
// returns a list of all power-related objects (nodes, cable, junctions) in turf,
|
|
// excluding source, that match the direction d
|
|
// if unmarked==1, only return those with no powernet
|
|
/proc/power_list(var/turf/T, var/source, var/d, var/unmarked=0, var/cable_only = 0)
|
|
. = list()
|
|
|
|
var/reverse = d ? GLOB.reverse_dir[d] : 0
|
|
for(var/AM in T)
|
|
if(AM == source) continue //we don't want to return source
|
|
|
|
if(!cable_only && istype(AM,/obj/machinery/power))
|
|
var/obj/machinery/power/P = AM
|
|
if(P.powernet == 0) continue // exclude APCs which have powernet=0
|
|
|
|
if(!unmarked || !P.powernet) //if unmarked=1 we only return things with no powernet
|
|
if(d == 0)
|
|
. += P
|
|
|
|
else if(istype(AM,/obj/structure/cable))
|
|
var/obj/structure/cable/C = AM
|
|
|
|
if(!unmarked || !C.powernet)
|
|
if(C.d1 == d || C.d2 == d || C.d1 == reverse || C.d2 == reverse )
|
|
. += C
|
|
return .
|
|
|
|
//remove the old powernet and replace it with a new one throughout the network.
|
|
/proc/propagate_network(var/obj/O, var/datum/powernet/PN)
|
|
//to_chat(world.log, "propagating new network")
|
|
var/list/worklist = list()
|
|
var/list/found_machines = list()
|
|
var/index = 1
|
|
var/obj/P = null
|
|
|
|
worklist+=O //start propagating from the passed object
|
|
|
|
while(index<=worklist.len) //until we've exhausted all power objects
|
|
P = worklist[index] //get the next power object found
|
|
index++
|
|
|
|
if( istype(P,/obj/structure/cable))
|
|
var/obj/structure/cable/C = P
|
|
if(C.powernet != PN) //add it to the powernet, if it isn't already there
|
|
PN.add_cable(C)
|
|
worklist |= C.get_connections() //get adjacents power objects, with or without a powernet
|
|
|
|
else if(P.anchored && istype(P,/obj/machinery/power))
|
|
var/obj/machinery/power/M = P
|
|
found_machines |= M //we wait until the powernet is fully propagates to connect the machines
|
|
|
|
else
|
|
continue
|
|
|
|
//now that the powernet is set, connect found machines to it
|
|
for(var/obj/machinery/power/PM in found_machines)
|
|
if(!PM.connect_to_network()) //couldn't find a node on its turf...
|
|
PM.disconnect_from_network() //... so disconnect if already on a powernet
|
|
|
|
|
|
//Merge two powernets, the bigger (in cable length term) absorbing the other
|
|
/proc/merge_powernets(var/datum/powernet/net1, var/datum/powernet/net2)
|
|
if(!net1 || !net2) //if one of the powernet doesn't exist, return
|
|
return
|
|
|
|
if(net1 == net2) //don't merge same powernets
|
|
return
|
|
|
|
//We assume net1 is larger. If net2 is in fact larger we are just going to make them switch places to reduce on code.
|
|
if(net1.cables.len < net2.cables.len) //net2 is larger than net1. Let's switch them around
|
|
var/temp = net1
|
|
net1 = net2
|
|
net2 = temp
|
|
|
|
//merge net2 into net1
|
|
for(var/obj/structure/cable/Cable in net2.cables) //merge cables
|
|
net1.add_cable(Cable)
|
|
|
|
if(!net2) return net1
|
|
|
|
for(var/obj/machinery/power/Node in net2.nodes) //merge power machines
|
|
if(!Node.connect_to_network())
|
|
Node.disconnect_from_network() //if somehow we can't connect the machine to the new powernet, disconnect it from the old nonetheless
|
|
|
|
return net1
|
|
|
|
//Determines how strong could be shock, deals damage to mob, uses power.
|
|
//M is a mob who touched wire/whatever
|
|
//power_source is a source of electricity, can be powercell, area, apc, cable, powernet or null
|
|
//source is an object caused electrocuting (airlock, grille, etc)
|
|
//No animations will be performed by this proc.
|
|
/proc/electrocute_mob(mob/living/M as mob, var/power_source, var/obj/source, var/siemens_coeff = 1.0)
|
|
if(istype(M.loc,/obj/mecha)) return 0 //feckin mechs are dumb
|
|
if(issilicon(M)) return 0 //No more robot shocks from machinery
|
|
var/area/source_area
|
|
if(istype(power_source,/area))
|
|
source_area = power_source
|
|
power_source = source_area.get_apc()
|
|
if(istype(power_source,/obj/structure/cable))
|
|
var/obj/structure/cable/Cable = power_source
|
|
power_source = Cable.powernet
|
|
|
|
var/datum/powernet/PN
|
|
var/obj/item/cell/cell
|
|
|
|
if(istype(power_source,/datum/powernet))
|
|
PN = power_source
|
|
else if(istype(power_source,/obj/item/cell))
|
|
cell = power_source
|
|
else if(istype(power_source,/obj/machinery/power/apc))
|
|
var/obj/machinery/power/apc/apc = power_source
|
|
cell = apc.cell
|
|
if (apc.terminal)
|
|
PN = apc.terminal.powernet
|
|
else if (!power_source)
|
|
return 0
|
|
else
|
|
log_admin("ERROR: /proc/electrocute_mob([M], [power_source], [source]): wrong power_source")
|
|
return 0
|
|
//Triggers powernet warning, but only for 5 ticks (if applicable)
|
|
//If following checks determine user is protected we won't alarm for long.
|
|
if(PN)
|
|
PN.trigger_warning(5)
|
|
if(istype(M,/mob/living/carbon/human))
|
|
var/mob/living/carbon/human/H = M
|
|
if(H.species.siemens_coefficient <= 0)
|
|
return
|
|
if(H.gloves)
|
|
var/obj/item/clothing/gloves/G = H.gloves
|
|
if(G.siemens_coefficient == 0) return 0 //to avoid spamming with insulated glvoes on
|
|
|
|
//Checks again. If we are still here subject will be shocked, trigger standard 20 tick warning
|
|
//Since this one is longer it will override the original one.
|
|
if(PN)
|
|
PN.trigger_warning()
|
|
|
|
if (!cell && !PN)
|
|
return 0
|
|
var/PN_damage = 0
|
|
var/cell_damage = 0
|
|
if (PN)
|
|
PN_damage = PN.get_electrocute_damage()
|
|
if (cell)
|
|
cell_damage = cell.get_electrocute_damage()
|
|
var/shock_damage = 0
|
|
if (PN_damage>=cell_damage)
|
|
power_source = PN
|
|
shock_damage = PN_damage
|
|
else
|
|
power_source = cell
|
|
shock_damage = cell_damage
|
|
var/drained_hp = M.electrocute_act(shock_damage, source, siemens_coeff) //zzzzzzap!
|
|
var/drained_energy = drained_hp*20
|
|
|
|
if (source_area)
|
|
source_area.use_power_oneoff(drained_energy/CELLRATE)
|
|
else if (istype(power_source,/datum/powernet))
|
|
var/drained_power = drained_energy/CELLRATE
|
|
drained_power = PN.draw_power(drained_power)
|
|
else if (istype(power_source, /obj/item/cell))
|
|
cell.use(drained_energy)
|
|
return drained_energy
|