Basically ripped over /tg/'s powernet and cable code into our own codebase.

Keeps Z-level code as it was.
Modifies/restores powernet procs as necessary to match our own implementation changes.
This commit is contained in:
PsiOmega
2014-10-13 16:47:56 +02:00
parent ef9cc80603
commit a1ee4e766b
24 changed files with 1393 additions and 1183 deletions

View File

@@ -164,6 +164,8 @@
#include "code\datums\spells\trigger.dm"
#include "code\datums\spells\turf_teleport.dm"
#include "code\datums\spells\wizard.dm"
#include "code\datums\wires\apc.dm"
#include "code\datums\wires\wires.dm"
#include "code\defines\obj.dm"
#include "code\defines\obj\weapon.dm"
#include "code\defines\procs\admin.dm"
@@ -1136,7 +1138,6 @@
#include "code\modules\power\breaker_box.dm"
#include "code\modules\power\cable.dm"
#include "code\modules\power\cable_heavyduty.dm"
#include "code\modules\power\cable_logic.dm"
#include "code\modules\power\cell.dm"
#include "code\modules\power\engine.dm"
#include "code\modules\power\fractal_reactor.dm"

View File

@@ -61,7 +61,6 @@ max volume of phoron storeable by the field = the total volume of a number of ti
idle_power_usage = 50
active_power_usage = 500 //multiplied by field strength
var/cached_power_avail = 0
directwired = 1
anchored = 0
var/state = 0
@@ -120,7 +119,6 @@ max volume of phoron storeable by the field = the total volume of a number of ti
state = 2
user << "You weld the [src] to the floor."
connect_to_network()
src.directwired = 1
else
user << "\red You need more welding fuel to complete this task."
if(2)
@@ -134,7 +132,6 @@ max volume of phoron storeable by the field = the total volume of a number of ti
state = 1
user << "You cut the [src] free from the floor."
disconnect_from_network()
src.directwired = 0
else
user << "\red You need more welding fuel to complete this task."
return

View File

@@ -19,7 +19,6 @@
use_power = 1
idle_power_usage = 10
active_power_usage = 500
directwired = 0
var/remote_access_enabled = 1
var/cached_power_avail = 0
var/emergency_insert_ready = 0

View File

@@ -363,7 +363,7 @@ datum/controller/game_controller/proc/process_powernets()
while(i<=powernets.len)
var/datum/powernet/Powernet = powernets[i]
if(Powernet)
Powernet.process()
Powernet.reset()
i++
continue
powernets.Cut(i,i+1)

78
code/datums/wires/apc.dm Normal file
View File

@@ -0,0 +1,78 @@
/datum/wires/apc
holder_type = /obj/machinery/power/apc
wire_count = 4
var/const/APC_WIRE_IDSCAN = 1
var/const/APC_WIRE_MAIN_POWER1 = 2
var/const/APC_WIRE_MAIN_POWER2 = 4
var/const/APC_WIRE_AI_CONTROL = 8
/datum/wires/apc/GetInteractWindow()
var/obj/machinery/power/apc/A = holder
. += ..()
. += text("<br>\n[(A.locked ? "The APC is locked." : "The APC is unlocked.")]<br>\n[(A.shorted ? "The APCs power has been shorted." : "The APC is working properly!")]<br>\n[(A.aidisabled ? "The 'AI control allowed' light is off." : "The 'AI control allowed' light is on.")]")
/datum/wires/apc/CanUse(var/mob/living/L)
var/obj/machinery/power/apc/A = holder
if(A.wiresexposed)
return 1
return 0
/datum/wires/apc/UpdatePulsed(var/index)
var/obj/machinery/power/apc/A = holder
switch(index)
if(APC_WIRE_IDSCAN)
A.locked = 0
spawn(300)
if(A)
A.locked = 1
A.updateDialog()
if (APC_WIRE_MAIN_POWER1, APC_WIRE_MAIN_POWER2)
if(A.shorted == 0)
A.shorted = 1
spawn(1200)
if(A && !IsIndexCut(APC_WIRE_MAIN_POWER1) && !IsIndexCut(APC_WIRE_MAIN_POWER2))
A.shorted = 0
A.updateDialog()
if (APC_WIRE_AI_CONTROL)
if (A.aidisabled == 0)
A.aidisabled = 1
spawn(10)
if(A && !IsIndexCut(APC_WIRE_AI_CONTROL))
A.aidisabled = 0
A.updateDialog()
A.updateDialog()
/datum/wires/apc/UpdateCut(var/index, var/mended)
var/obj/machinery/power/apc/A = holder
switch(index)
if(APC_WIRE_MAIN_POWER1, APC_WIRE_MAIN_POWER2)
if(!mended)
A.shock(usr, 50)
A.shorted = 1
else if(!IsIndexCut(APC_WIRE_MAIN_POWER1) && !IsIndexCut(APC_WIRE_MAIN_POWER2))
A.shorted = 0
A.shock(usr, 50)
if(APC_WIRE_AI_CONTROL)
if(!mended)
if (A.aidisabled == 0)
A.aidisabled = 1
else
if (A.aidisabled == 1)
A.aidisabled = 0
A.updateDialog()

293
code/datums/wires/wires.dm Normal file
View File

@@ -0,0 +1,293 @@
// Wire datums. Created by Giacomand.
// Was created to replace a horrible case of copy and pasted code with no care for maintability.
// Goodbye Door wires, Cyborg wires, Vending Machine wires, Autolathe wires
// Protolathe wires, APC wires and Camera wires!
#define MAX_FLAG 65535
var/list/same_wires = list()
// 12 colours, if you're adding more than 12 wires then add more colours here
var/list/wireColours = list("red", "blue", "green", "black", "orange", "brown", "gold", "gray", "cyan", "navy", "purple", "pink")
/datum/wires
var/random = 0 // Will the wires be different for every single instance.
var/atom/holder = null // The holder
var/holder_type = null // The holder type; used to make sure that the holder is the correct type.
var/wire_count = 0 // Max is 16
var/wires_status = 0 // BITFLAG OF WIRES
var/list/wires = list()
var/list/signallers = list()
var/table_options = " align='center'"
var/row_options1 = " width='80px'"
var/row_options2 = " width='260px'"
var/window_x = 370
var/window_y = 470
/datum/wires/New(var/atom/holder)
..()
src.holder = holder
if(!istype(holder, holder_type))
CRASH("Our holder is null/the wrong type!")
return
// Generate new wires
if(random)
GenerateWires()
// Get the same wires
else
// We don't have any wires to copy yet, generate some and then copy it.
if(!same_wires[holder_type])
GenerateWires()
same_wires[holder_type] = src.wires.Copy()
else
var/list/wires = same_wires[holder_type]
src.wires = wires // Reference the wires list.
/datum/wires/proc/GenerateWires()
var/list/colours_to_pick = wireColours.Copy() // Get a copy, not a reference.
var/list/indexes_to_pick = list()
//Generate our indexes
for(var/i = 1; i < MAX_FLAG && i < (1 << wire_count); i += i)
indexes_to_pick += i
colours_to_pick.len = wire_count // Downsize it to our specifications.
while(colours_to_pick.len && indexes_to_pick.len)
// Pick and remove a colour
var/colour = pick_n_take(colours_to_pick)
// Pick and remove an index
var/index = pick_n_take(indexes_to_pick)
src.wires[colour] = index
//wires = shuffle(wires)
/datum/wires/proc/Interact(var/mob/living/user)
var/html = null
if(holder && CanUse(user))
html = GetInteractWindow()
if(html)
user.set_machine(holder)
else
user.unset_machine()
// No content means no window.
user << browse(null, "window=wires")
return
var/datum/browser/popup = new(user, "wires", holder.name, window_x, window_y)
popup.set_content(html)
popup.set_title_image(user.browse_rsc_icon(holder.icon, holder.icon_state))
popup.open()
/datum/wires/proc/GetInteractWindow()
var/html = "<div class='block'>"
html += "<h3>Exposed Wires</h3>"
html += "<table[table_options]>"
for(var/colour in wires)
html += "<tr>"
html += "<td[row_options1]><font color='[colour]'>[capitalize(colour)]</font></td>"
html += "<td[row_options2]>"
html += "<A href='?src=\ref[src];action=1;cut=[colour]'>[IsColourCut(colour) ? "Mend" : "Cut"]</A>"
html += " <A href='?src=\ref[src];action=1;pulse=[colour]'>Pulse</A>"
html += " <A href='?src=\ref[src];action=1;attach=[colour]'>[IsAttached(colour) ? "Detach" : "Attach"] Signaller</A></td></tr>"
html += "</table>"
html += "</div>"
return html
/datum/wires/Topic(href, href_list)
..()
if(in_range(holder, usr) && isliving(usr))
var/mob/living/L = usr
if(CanUse(L) && href_list["action"])
var/obj/item/I = L.get_active_hand()
holder.add_hiddenprint(L)
if(href_list["cut"]) // Toggles the cut/mend status
if(istype(I, /obj/item/weapon/wirecutters))
var/colour = href_list["cut"]
CutWireColour(colour)
else
L << "<span class='error'>You need wirecutters!</span>"
else if(href_list["pulse"])
if(istype(I, /obj/item/device/multitool))
var/colour = href_list["pulse"]
PulseColour(colour)
else
L << "<span class='error'>You need a multitool!</span>"
else if(href_list["attach"])
var/colour = href_list["attach"]
// Detach
if(IsAttached(colour))
var/obj/item/O = Detach(colour)
if(O)
L.put_in_hands(O)
// Attach
else
if(istype(I, /obj/item/device/assembly/signaler))
L.drop_item()
Attach(colour, I)
else
L << "<span class='error'>You need a remote signaller!</span>"
// Update Window
Interact(usr)
if(href_list["close"])
usr << browse(null, "window=wires")
usr.unset_machine(holder)
//
// Overridable Procs
//
// Called when wires cut/mended.
/datum/wires/proc/UpdateCut(var/index, var/mended)
return
// Called when wire pulsed. Add code here.
/datum/wires/proc/UpdatePulsed(var/index)
return
/datum/wires/proc/CanUse(var/mob/living/L)
return 1
// Example of use:
/*
var/const/BOLTED= 1
var/const/SHOCKED = 2
var/const/SAFETY = 4
var/const/POWER = 8
/datum/wires/door/UpdateCut(var/index, var/mended)
var/obj/machinery/door/airlock/A = holder
switch(index)
if(BOLTED)
if(!mended)
A.bolt()
if(SHOCKED)
A.shock()
if(SAFETY )
A.safety()
*/
//
// Helper Procs
//
/datum/wires/proc/PulseColour(var/colour)
PulseIndex(GetIndex(colour))
/datum/wires/proc/PulseIndex(var/index)
if(IsIndexCut(index))
return
UpdatePulsed(index)
/datum/wires/proc/GetIndex(var/colour)
if(wires[colour])
var/index = wires[colour]
return index
else
CRASH("[colour] is not a key in wires.")
//
// Is Index/Colour Cut procs
//
/datum/wires/proc/IsColourCut(var/colour)
var/index = GetIndex(colour)
return IsIndexCut(index)
/datum/wires/proc/IsIndexCut(var/index)
return (index & wires_status)
//
// Signaller Procs
//
/datum/wires/proc/IsAttached(var/colour)
if(signallers[colour])
return 1
return 0
/datum/wires/proc/GetAttached(var/colour)
if(signallers[colour])
return signallers[colour]
return null
/datum/wires/proc/Attach(var/colour, var/obj/item/device/assembly/signaler/S)
if(colour && S)
if(!IsAttached(colour))
signallers[colour] = S
S.loc = holder
S.connected = src
return S
/datum/wires/proc/Detach(var/colour)
if(colour)
var/obj/item/device/assembly/signaler/S = GetAttached(colour)
if(S)
signallers -= colour
S.connected = null
S.loc = holder.loc
return S
/datum/wires/proc/Pulse(var/obj/item/device/assembly/signaler/S)
for(var/colour in signallers)
if(S == signallers[colour])
PulseColour(colour)
break
//
// Cut Wire Colour/Index procs
//
/datum/wires/proc/CutWireColour(var/colour)
var/index = GetIndex(colour)
CutWireIndex(index)
/datum/wires/proc/CutWireIndex(var/index)
if(IsIndexCut(index))
wires_status &= ~index
UpdateCut(index, 1)
else
wires_status |= index
UpdateCut(index, 0)
/datum/wires/proc/RandomCut()
var/r = rand(1, wires.len)
CutWireIndex(r)
/datum/wires/proc/CutAll()
for(var/i = 1; i < MAX_FLAG && i < (1 << wire_count); i += i)
CutWireIndex(i)
/datum/wires/proc/IsAllCut()
if(wires_status == (1 << wire_count) - 1)
return 1
return 0
//
//Shuffle and Mend
//
/datum/wires/proc/Shuffle()
wires_status = 0
GenerateWires()

View File

@@ -97,10 +97,7 @@
SetLuminosity(12)
// found a powernet, so drain up to max power from it
var/drained = min ( drain_rate, PN.avail )
PN.newload += drained
power_drained += drained
var/drained = PN.draw_power(drain_rate)
// if tried to drain more than available on powernet
// now look for APCs and drain their cells

View File

@@ -262,3 +262,24 @@ var/DBConnection/dbcon_old = new() //Tgstation database (Old database) - See the
//added for Xenoarchaeology, might be useful for other stuff
var/global/list/alphabet_uppercase = list("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z")
// TODO: Replace
/proc/RandomAPCWires()
//to make this not randomize the wires, just set index to 1 and increment it in the flag for loop (after doing everything else).
var/list/apcwires = list(0, 0, 0, 0)
APCIndexToFlag = list(0, 0, 0, 0)
APCIndexToWireColor = list(0, 0, 0, 0)
APCWireColorToIndex = list(0, 0, 0, 0)
var/flagIndex = 1
for (var/flag=1, flag<16, flag+=flag)
var/valid = 0
while (!valid)
var/colorIndex = rand(1, 4)
if (apcwires[colorIndex]==0)
valid = 1
apcwires[colorIndex] = flag
APCIndexToFlag[flagIndex] = flag
APCIndexToWireColor[flagIndex] = colorIndex
APCWireColorToIndex[colorIndex] = flagIndex
flagIndex+=1
return apcwires

View File

@@ -13,6 +13,7 @@
var/frequency = 1457
var/delay = 0
var/airlock_wire = null
var/datum/wires/connected = null
var/datum/radio_frequency/radio_connection
var/deadman = 0
@@ -118,7 +119,9 @@
pulse(var/radio = 0)
if(istype(src.loc, /obj/machinery/door/airlock) && src.airlock_wire && src.wires)
if(src.connected && src.wires)
connected.Pulse(src)
else if(istype(src.loc, /obj/machinery/door/airlock) && src.airlock_wire && src.wires)
var/obj/machinery/door/airlock/A = src.loc
A.pulse(src.airlock_wire)
else if(holder)

View File

@@ -63,7 +63,7 @@
var/obj/item/stack/cable_coil/CC = new/obj/item/stack/cable_coil(user.loc)
CC.amount = 1
CC.updateicon()
CC.update_icon()
overlays = list()
string_attached = null
user << "\blue You detach the string from the coin."

File diff suppressed because it is too large Load Diff

View File

@@ -1,29 +1,27 @@
// attach a wire to a power machine - leads from the turf you are standing on
///////////////////////////////
//CABLE STRUCTURE
///////////////////////////////
/obj/machinery/power/attackby(obj/item/weapon/W, mob/user)
if(istype(W, /obj/item/stack/cable_coil))
////////////////////////////////
// Definitions
////////////////////////////////
var/obj/item/stack/cable_coil/coil = W
/* Cable directions (d1 and d2)
var/turf/T = user.loc
if(T.intact || !istype(T, /turf/simulated/floor))
return
9 1 5
\ | /
8 - 0 - 4
/ | \
10 2 6
if(get_dist(src, user) > 1)
return
If d1 = 0 and d2 = 0, there's no cable
If d1 = 0 and d2 = dir, it's a O-X cable, getting from the center of the tile to dir (knot cable)
If d1 = dir1 and d2 = dir2, it's a full X-X cable, getting from dir1 to dir2
By design, d1 is the smallest direction and d2 is the highest
*/
if(!directwired) // only for attaching to directwired machines
return
coil.turf_place(T, user)
return
else
..()
return
// the power cable object
/obj/structure/cable
level = 1
anchored =1
@@ -74,17 +72,20 @@
var/turf/T = src.loc // hide if turf is not intact
if(level==1) hide(T.intact)
cable_list += src
update_icon()
cable_list += src //add it to the global cable list
/obj/structure/cable/Del() // called when a cable is deleted
if(!defer_powernet_rebuild) // set if network will be rebuilt manually
if(powernet)
powernet.cut_cable(src) // update the powernets
cable_list -= src
..() // then go ahead and delete the cable
/obj/structure/cable/Del() // called when a cable is deleted
if(powernet)
cut_cable_from_powernet() // update the powernets
cable_list -= src //remove it from global cable list
..() // then go ahead and delete the cable
///////////////////////////////////
// General procedures
///////////////////////////////////
//If underfloor, hide the cable
/obj/structure/cable/hide(var/i)
if(level == 1 && istype(loc, /turf))
@@ -92,17 +93,25 @@
updateicon()
/obj/structure/cable/proc/updateicon()
icon_state = "[d1]-[d2]"
alpha = invisibility ? 127 : 255
if(invisibility)
icon_state = "[d1]-[d2]-f"
else
icon_state = "[d1]-[d2]"
// returns the powernet this cable belongs to
/obj/structure/cable/proc/get_powernet() //TODO: remove this as it is obsolete
return powernet
//Telekinesis has no effect on a cable
/obj/structure/cable/attack_tk(mob/user)
return
// Items usable on a cable :
// - Wirecutters : cut it duh !
// - Cable coil : merge cables
// - Multitool : get the power currently passing through the cable
//
/obj/structure/cable/attackby(obj/item/W, mob/user)
var/turf/T = src.loc
@@ -110,13 +119,11 @@
return
if(istype(W, /obj/item/weapon/wirecutters))
///// Z-Level Stuff
if(src.d1 == 12 || src.d2 == 12)
user << "<span class='warning'>You must cut this cable from above.</span>"
return
///// Z-Level Stuff
if(breaker_box)
user << "\red This cable is connected to nearby breaker box. Use breaker box to interact with it."
return
@@ -142,22 +149,23 @@
if(c.d1 == 12 || c.d2 == 12)
c.Del()
///// Z-Level Stuff
investigate_log("was cut by [key_name(usr, usr.client)] in [user.loc.loc]","wires")
del(src)
return // not needed, but for clarity
del(src) // qdel
return
else if(istype(W, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/coil = W
if (coil.get_amount() < 1)
user << "Not enough cable"
return
coil.cable_join(src, user)
else if(istype(W, /obj/item/device/multitool))
var/datum/powernet/PN = get_powernet() // find the powernet
if(PN && (PN.avail > 0)) // is it powered?
user << "<span class='warning'>[PN.avail]W in power network.</span>"
if(powernet && (powernet.avail > 0)) // is it powered?
user << "<span class='warning'>[powernet.avail]W in power network.</span>"
else
user << "<span class='warning'>The cable is not powered.</span>"
@@ -171,7 +179,6 @@
src.add_fingerprint(user)
// shock the user with probability prb
/obj/structure/cable/proc/shock(mob/user, prb, var/siemens_coeff = 1.0)
if(!prob(prb))
return 0
@@ -183,24 +190,296 @@
else
return 0
//explosion handling
/obj/structure/cable/ex_act(severity)
switch(severity)
if(1.0)
del(src)
del(src) // qdel
if(2.0)
if (prob(50))
new/obj/item/stack/cable_coil(src.loc, src.d1 ? 2 : 1, color)
del(src)
del(src) // qdel
if(3.0)
if (prob(25))
new/obj/item/stack/cable_coil(src.loc, src.d1 ? 2 : 1, color)
del(src)
del(src) // qdel
return
// the cable coil object, used for laying cable
obj/structure/cable/proc/cableColor(var/colorC)
var/color_n = "#DD0000"
if(colorC)
color_n = colorC
color = color_n
////////////////////////////////////////////
// Power related
///////////////////////////////////////////
obj/structure/cable/proc/add_avail(var/amount)
if(powernet)
powernet.newavail += amount
obj/structure/cable/proc/add_load(var/amount)
if(powernet)
powernet.load += amount
obj/structure/cable/proc/surplus()
if(powernet)
return powernet.avail-powernet.load
else
return 0
obj/structure/cable/proc/avail()
if(powernet)
return powernet.avail
else
return 0
/////////////////////////////////////////////////
// Cable laying helpers
////////////////////////////////////////////////
//handles merging diagonally matching cables
//for info : direction^3 is flipping horizontally, direction^12 is flipping vertically
/obj/structure/cable/proc/mergeDiagonalsNetworks(var/direction)
//search for and merge diagonally matching cables from the first direction component (north/south)
var/turf/T = get_step(src, direction&3)//go north/south
for(var/obj/structure/cable/C in T)
if(!C)
continue
if(src == C)
continue
if(C.d1 == (direction^3) || C.d2 == (direction^3)) //we've got a diagonally matching cable
if(!C.powernet) //if the matching cable somehow got no powernet, make him one (should not happen for cables)
var/datum/powernet/newPN = new()
newPN.add_cable(C)
if(powernet) //if we already have a powernet, then merge the two powernets
merge_powernets(powernet,C.powernet)
else
C.powernet.add_cable(src) //else, we simply connect to the matching cable powernet
//the same from the second direction component (east/west)
T = get_step(src, direction&12)//go east/west
for(var/obj/structure/cable/C in T)
if(!C)
continue
if(src == C)
continue
if(C.d1 == (direction^12) || C.d2 == (direction^12)) //we've got a diagonally matching cable
if(!C.powernet) //if the matching cable somehow got no powernet, make him one (should not happen for cables)
var/datum/powernet/newPN = new()
newPN.add_cable(C)
if(powernet) //if we already have a powernet, then merge the two powernets
merge_powernets(powernet,C.powernet)
else
C.powernet.add_cable(src) //else, we simply connect to the matching cable powernet
// merge with the powernets of power objects in the given direction
/obj/structure/cable/proc/mergeConnectedNetworks(var/direction)
var/fdir = (!direction)? 0 : turn(direction, 180) //flip the direction, to match with the source position on its turf
if(!(d1 == direction || d2 == direction)) //if the cable is not pointed in this direction, do nothing
return
var/turf/TB = get_step(src, direction)
for(var/obj/structure/cable/C in TB)
if(!C)
continue
if(src == C)
continue
if(C.d1 == fdir || C.d2 == fdir) //we've got a matching cable in the neighbor turf
if(!C.powernet) //if the matching cable somehow got no powernet, make him one (should not happen for cables)
var/datum/powernet/newPN = new()
newPN.add_cable(C)
if(powernet) //if we already have a powernet, then merge the two powernets
merge_powernets(powernet,C.powernet)
else
C.powernet.add_cable(src) //else, we simply connect to the matching cable powernet
// merge with the powernets of power objects in the source turf
/obj/structure/cable/proc/mergeConnectedNetworksOnTurf()
var/list/to_connect = list()
if(!powernet) //if we somehow have no powernet, make one (should not happen for cables)
var/datum/powernet/newPN = new()
newPN.add_cable(src)
//first let's add turf cables to our powernet
//then we'll connect machines on turf with a node cable is present
for(var/AM in loc)
if(istype(AM,/obj/structure/cable))
var/obj/structure/cable/C = AM
if(C.d1 == d1 || C.d2 == d1 || C.d1 == d2 || C.d2 == d2) //only connected if they have a common direction
if(C.powernet == powernet) continue
if(C.powernet)
merge_powernets(powernet, C.powernet)
else
powernet.add_cable(C) //the cable was powernetless, let's just add it to our powernet
else if(istype(AM,/obj/machinery/power/apc))
var/obj/machinery/power/apc/N = AM
if(!N.terminal) continue // APC are connected through their terminal
if(N.terminal.powernet == powernet)
continue
to_connect += N.terminal //we'll connect the machines after all cables are merged
else if(istype(AM,/obj/machinery/power)) //other power machines
var/obj/machinery/power/M = AM
if(M.powernet == powernet)
continue
to_connect += M //we'll connect the machines after all cables are merged
//now that cables are done, let's connect found machines
for(var/obj/machinery/power/PM in to_connect)
if(!PM.connect_to_network())
PM.disconnect_from_network() //if we somehow can't connect the machine to the new powernet, remove it from the old nonetheless
//////////////////////////////////////////////
// Powernets handling helpers
//////////////////////////////////////////////
//if powernetless_only = 1, will only get connections without powernet
/obj/structure/cable/proc/get_connections(var/powernetless_only = 0)
. = list() // this will be a list of all connected power objects
var/turf/T
///// Z-Level Stuff
if (d1 == 11 || d1 == 12)
var/turf/controllerlocation = locate(1, 1, z)
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
if(controller.up && d1 == 12)
T = locate(src.x, src.y, controller.up_target)
if(T)
. += power_list(T, src, 11, 1)
if(controller.down && d1 == 11)
T = locate(src.x, src.y, controller.down_target)
if(T)
. += power_list(T, src, 12, 1)
///// Z-Level Stuff
//get matching cables from the first direction
else if(d1) //if not a node cable
T = get_step(src, d1)
if(T)
. += power_list(T, src, turn(d1, 180), powernetless_only) //get adjacents matching cables
if(d1&(d1-1)) //diagonal direction, must check the 4 possibles adjacents tiles
T = get_step(src,d1&3) // go north/south
if(T)
. += power_list(T, src, d1 ^ 3, powernetless_only) //get diagonally matching cables
T = get_step(src,d1&12) // go east/west
if(T)
. += power_list(T, src, d1 ^ 12, powernetless_only) //get diagonally matching cables
. += power_list(loc, src, d1, powernetless_only) //get on turf matching cables
///// Z-Level Stuff
if(d2 == 11 || d2 == 12)
var/turf/controllerlocation = locate(1, 1, z)
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
if(controller.up && d2 == 12)
T = locate(src.x, src.y, controller.up_target)
if(T)
. += power_list(T, src, 11, 1)
if(controller.down && d2 == 11)
T = locate(src.x, src.y, controller.down_target)
if(T)
. += power_list(T, src, 12, 1)
///// Z-Level Stuff
else
//do the same on the second direction (which can't be 0)
T = get_step(src, d2)
if(T)
. += power_list(T, src, turn(d2, 180), powernetless_only) //get adjacents matching cables
if(d2&(d2-1)) //diagonal direction, must check the 4 possibles adjacents tiles
T = get_step(src,d2&3) // go north/south
if(T)
. += power_list(T, src, d2 ^ 3, powernetless_only) //get diagonally matching cables
T = get_step(src,d2&12) // go east/west
if(T)
. += power_list(T, src, d2 ^ 12, powernetless_only) //get diagonally matching cables
. += power_list(loc, src, d2, powernetless_only) //get on turf matching cables
return .
//should be called after placing a cable which extends another cable, creating a "smooth" cable that no longer terminates in the centre of a turf.
//needed as this can, unlike other placements, disconnect cables
/obj/structure/cable/proc/denode()
var/turf/T1 = loc
if(!T1) return
var/list/powerlist = power_list(T1,src,0,0) //find the other cables that ended in the centre of the turf, with or without a powernet
if(powerlist.len>0)
var/datum/powernet/PN = new()
propagate_network(powerlist[1],PN) //propagates the new powernet beginning at the source cable
if(PN.is_empty()) //can happen with machines made nodeless when smoothing cables
del(PN) // qdel
// cut the cable's powernet at this cable and updates the powergrid
/obj/structure/cable/proc/cut_cable_from_powernet()
var/turf/T1 = loc
var/list/P_list
if(!T1) return
if(d1)
T1 = get_step(T1, d1)
P_list = power_list(T1, src, turn(d1,180),0,cable_only = 1) // what adjacently joins on to cut cable...
P_list += power_list(loc, src, d1, 0, cable_only = 1)//... and on turf
if(P_list.len == 0)//if nothing in both list, then the cable was a lone cable, just delete it and its powernet
powernet.remove_cable(src)
for(var/obj/machinery/power/P in T1)//check if it was powering a machine
if(!P.connect_to_network()) //can't find a node cable on a the turf to connect to
P.disconnect_from_network() //remove from current network (and delete powernet)
return
// remove the cut cable from its turf and powernet, so that it doesn't get count in propagate_network worklist
loc = null
powernet.remove_cable(src) //remove the cut cable from its powernet
var/datum/powernet/newPN = new()// creates a new powernet...
propagate_network(P_list[1], newPN)//... and propagates it to the other side of the cable
// Disconnect machines connected to nodes
if(d1 == 0) // if we cut a node (O-X) cable
for(var/obj/machinery/power/P in T1)
if(!P.connect_to_network()) //can't find a node cable on a the turf to connect to
P.disconnect_from_network() //remove from current network
///////////////////////////////////////////////
// The cable coil object, used for laying cable
///////////////////////////////////////////////
////////////////////////////////
// Definitions
////////////////////////////////
#define MAXCOIL 30
/obj/item/stack/cable_coil
name = "cable coil"
icon = 'icons/obj/power.dmi'
@@ -219,10 +498,12 @@
item_state = "coil"
attack_verb = list("whipped", "lashed", "disciplined", "flogged")
suicide_act(mob/user)
viewers(user) << "<span class='warning'><b>[user] is strangling \himself with the [src.name]! It looks like \he's trying to commit suicide.</b></span>"
return(OXYLOSS)
/obj/item/stack/cable_coil/suicide_act(mob/user)
if(locate(/obj/structure/stool) in user.loc)
user.visible_message("<span class='suicide'>[user] is making a noose with the [src.name]! It looks like \he's trying to commit suicide.</span>")
else
user.visible_message("<span class='suicide'>[user] is strangling \himself with the [src.name]! It looks like \he's trying to commit suicide.</span>")
return(OXYLOSS)
/obj/item/stack/cable_coil/New(loc, length = MAXCOIL, var/param_color = null)
..()
@@ -233,10 +514,38 @@
color = item_color
pixel_x = rand(-2,2)
pixel_y = rand(-2,2)
updateicon()
update_icon()
update_wclass()
/obj/item/stack/cable_coil/proc/updateicon()
///////////////////////////////////
// General procedures
///////////////////////////////////
//you can use wires to heal robotics
/obj/item/stack/cable_coil/attack(mob/M as mob, mob/user as mob)
if(istype(M,/mob/living/carbon/human))
var/mob/living/carbon/human/H = M
var/datum/organ/external/S = H.get_organ(user.zone_sel.selecting)
if(!(S.status & ORGAN_ROBOT) || user.a_intent != "help")
return ..()
if(H.species.flags & IS_SYNTHETIC)
if(M == user)
user << "\red You can't repair damage to your own body - it's against OH&S."
return
if(S.burn_dam > 0 && use(1))
S.heal_damage(0,15,0,1)
user.visible_message("\red \The [user] repairs some burn damage on \the [M]'s [S.display_name] with \the [src].")
return
else
user << "Nothing to fix!"
else
return ..()
/obj/item/stack/cable_coil/update_icon()
if (!color)
color = pick(COLOR_RED, COLOR_BLUE, COLOR_GREEN, COLOR_ORANGE, COLOR_WHITE, COLOR_PINK, COLOR_YELLOW, COLOR_CYAN)
item_color = color
@@ -259,12 +568,13 @@
/obj/item/stack/cable_coil/examine()
set src in view(1)
if(amount == 1)
if(get_amount() == 1)
usr << "A short piece of power cable."
else if(amount == 2)
else if(get_amount() == 2)
usr << "A piece of power cable."
else
usr << "A coil of power cable. There are [amount] lengths of cable in the coil."
usr << "A coil of power cable. There are [get_amount()] lengths of cable in the coil."
/obj/item/stack/cable_coil/verb/make_restraint()
set name = "Make Cable Restraints"
@@ -274,26 +584,28 @@
if(ishuman(M) && !M.restrained() && !M.stat && !M.paralysis && ! M.stunned)
if(!istype(usr.loc,/turf)) return
if(src.amount <= 14)
usr << "<span class='warning'>You need at least 15 lengths to make restraints!</span>"
usr << "\red You need at least 15 lengths to make restraints!"
return
var/obj/item/weapon/handcuffs/cable/B = new /obj/item/weapon/handcuffs/cable(usr.loc)
B.color = item_color
usr << "<span class='notice'>You wind some cable together to make some restraints.</span>"
B.icon_state = "cuff_[item_color]"
usr << "\blue You wind some cable together to make some restraints."
src.use(15)
else
usr << "<span class='notice'>\blue You cannot do that.</span>"
usr << "\blue You cannot do that."
..()
// Items usable on a cable coil :
// - Wirecutters : cut them duh !
// - Cable coil : merge cables
/obj/item/stack/cable_coil/attackby(obj/item/weapon/W, mob/user)
..()
if( istype(W, /obj/item/weapon/wirecutters) && src.amount > 1)
src.amount--
new/obj/item/stack/cable_coil(user.loc, 1,item_color)
user << "<span class='notice'>You cut a piece off the cable coil.</span>"
src.updateicon()
src.update_wclass()
user << "You cut a piece off the cable coil."
src.update_icon()
return
else if( istype(W, /obj/item/stack/cable_coil) )
else if(istype(W, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/C = W
if(C.amount >= MAXCOIL)
user << "The coil is too long, you cannot add any more cable to it."
@@ -301,54 +613,65 @@
if( (C.amount + src.amount <= MAXCOIL) )
user << "You join the cable coils together."
C.add(src.amount) // give it cable
C.give(src.amount) // give it cable
src.use(src.amount) // make sure this one cleans up right
return
else
var/amt = MAXCOIL - C.amount
user << "You transfer [amt] length\s of cable from one coil to the other."
C.add(amt)
C.give(amt)
src.use(amt)
return
..()
return
/obj/item/stack/cable_coil/attack_hand(mob/user as mob)
if (user.get_inactive_hand() == src)
var/obj/item/stack/cable_coil/F = new /obj/item/stack/cable_coil(user, 1, color)
F.copy_evidences(src)
user.put_in_hands(F)
src.add_fingerprint(user)
F.add_fingerprint(user)
use(1)
//remove cables from the stack
/* This is probably reduntant
/obj/item/stack/cable_coil/use(var/used)
if(src.amount < used)
return 0
else if (src.amount == used)
if(ismob(loc)) //handle mob icon update
var/mob/M = loc
M.unEquip(src)
qdel(src)
return 1
else
..()
return
amount -= used
update_icon()
return 1
*/
/obj/item/stack/cable_coil/use(var/used)
. = ..()
updateicon()
update_wclass()
update_icon()
return
/obj/item/stack/cable_coil/add(var/extra)
. = ..()
updateicon()
update_wclass()
return
//add cables to the stack
/obj/item/stack/cable_coil/proc/give(var/extra)
if(amount + extra > MAXCOIL)
amount = MAXCOIL
else
amount += extra
update_icon()
///////////////////////////////////////////////
// Cable laying procedures
//////////////////////////////////////////////
// called when cable_coil is clicked on a turf/simulated/floor
/obj/item/stack/cable_coil/proc/turf_place(turf/simulated/floor/F, mob/user)
if(!isturf(user.loc))
return
if(get_dist(F,user) > 1)
user << "<span class='warning'>You can't lay cable at a place that far away.</span>"
if(get_amount() < 1) // Out of cable
user << "There is no cable left."
return
if(F.intact) // if floor is intact, complain
user << "<span class='warning'>You can't lay cable there unless the floor tiles are removed.</span>"
if(get_dist(F,user) > 1) // Too far
user << "You can't lay cable at a place that far away."
return
if(F.intact) // Ff floor is intact, complain
user << "You can't lay cable there unless the floor tiles are removed."
return
else
@@ -396,49 +719,47 @@
D.updateicon()
PN.add_cable(D)
D.mergeConnectedNetworksOnTurf()
// do the normal stuff
else
///// Z-Level Stuff
for(var/obj/structure/cable/LC in F)
if((LC.d1 == dirn && LC.d2 == 0 ) || ( LC.d2 == dirn && LC.d1 == 0))
user << "There's already a cable at that position."
return
var/obj/structure/cable/C = new(F)
var/obj/structure/cable/C = new(F)
C.cableColor(item_color)
C.cableColor(item_color)
C.d1 = 0
C.d2 = dirn
C.add_fingerprint(user)
C.updateicon()
//set up the new cable
C.d1 = 0 //it's a O-X node cable
C.d2 = dirn
C.add_fingerprint(user)
C.updateicon()
var/datum/powernet/PN = new()
PN.add_cable(C)
//create a new powernet with the cable, if needed it will be merged later
var/datum/powernet/PN = new()
PN.add_cable(C)
C.mergeConnectedNetworks(C.d2)
C.mergeConnectedNetworksOnTurf()
C.mergeConnectedNetworks(C.d2) //merge the powernet with adjacents powernets
C.mergeConnectedNetworksOnTurf() //merge the powernet with on turf powernets
if(C.d2 & (C.d2 - 1))// if the cable is layed diagonally, check the others 2 possible directions
C.mergeDiagonalsNetworks(C.d2)
if(C.d2 & (C.d2 - 1))// if the cable is layed diagonally, check the others 2 possible directions
C.mergeDiagonalsNetworks(C.d2)
use(1)
if (C.shock(user, 50))
if (prob(50)) //fail
new/obj/item/stack/cable_coil(C.loc, 1, C.color)
del(C)
//src.laying = 1
//last = C
use(1)
if (C.shock(user, 50))
if (prob(50)) //fail
new/obj/item/stack/cable_coil(C.loc, 1, C.color)
del(C) // qdel
// called when cable_coil is click on an installed obj/cable
// or click on a turf that already contains a "node" cable
/obj/item/stack/cable_coil/proc/cable_join(obj/structure/cable/C, mob/user)
var/turf/U = user.loc
if(!isturf(U))
return
@@ -449,7 +770,7 @@
return
if(get_dist(C, user) > 1) // make sure it's close enough
user << "<span class='warning'>You can't lay cable at a place that far away.</span>"
user << "You can't lay cable at a place that far away."
return
@@ -459,9 +780,10 @@
var/dirn = get_dir(C, user)
if(C.d1 == dirn || C.d2 == dirn) // one end of the clicked cable is pointing towards us
// one end of the clicked cable is pointing towards us
if(C.d1 == dirn || C.d2 == dirn)
if(U.intact) // can't place a cable if the floor is complete
user << "<span class='warning'>You can't lay cable there unless the floor tiles are removed.</span>"
user << "You can't lay cable there unless the floor tiles are removed."
return
else
// cable is pointing at us, we're standing on an open tile
@@ -471,7 +793,7 @@
for(var/obj/structure/cable/LC in U) // check to make sure there's not a cable there already
if(LC.d1 == fdirn || LC.d2 == fdirn)
user << "<span class='warning'>There's already a cable at that position.</span>"
user << "There's already a cable at that position."
return
var/obj/structure/cable/NC = new(U)
@@ -493,13 +815,16 @@
NC.mergeDiagonalsNetworks(NC.d2)
use(1)
if (NC.shock(user, 50))
if (prob(50)) //fail
new/obj/item/stack/cable_coil(NC.loc, 1, NC.color)
del(NC)
del(NC) // qdel
return
else if(C.d1 == 0) // exisiting cable doesn't point at our position, so see if it's a stub
// exisiting cable doesn't point at our position, so see if it's a stub
else if(C.d1 == 0)
// if so, make it a full cable pointing from it's old direction to our dirn
var/nd1 = C.d2 // these will be the new directions
var/nd2 = dirn
@@ -514,7 +839,7 @@
if(LC == C) // skip the cable we're interacting with
continue
if((LC.d1 == nd1 && LC.d2 == nd2) || (LC.d1 == nd2 && LC.d2 == nd1) ) // make sure no cable matches either direction
user << "<span class='warning'>There's already a cable at that position.</span>"
user << "There's already a cable at that position."
return
@@ -527,8 +852,8 @@
C.updateicon()
C.mergeConnectedNetworks(C.d1)
C.mergeConnectedNetworks(C.d2)
C.mergeConnectedNetworks(C.d1) //merge the powernets...
C.mergeConnectedNetworks(C.d2) //...in the two new cable directions
C.mergeConnectedNetworksOnTurf()
if(C.d1 & (C.d1 - 1))// if the cable is layed diagonally, check the others 2 possible directions
@@ -538,148 +863,19 @@
C.mergeDiagonalsNetworks(C.d2)
use(1)
if (C.shock(user, 50))
if (prob(50)) //fail
new/obj/item/stack/cable_coil(C.loc, 2, C.color)
del(C)
del(C) // qdel
return
C.denode()// this call may have disconnected some cables that terminated on the centre of the turf, if so split the powernets.
return
//handles merging diagonally matching cables
//for info : direction^3 is flipping horizontally, direction^12 is flipping vertically
/obj/structure/cable/proc/mergeDiagonalsNetworks(var/direction)
//search for and merge diagonally matching cables from the first direction component (north/south)
var/turf/T = get_step(src, direction&3)//go north/south
for(var/obj/structure/cable/C in T)
if(!C)
continue
if(src == C)
continue
if(C.d1 == (direction^3) || C.d2 == (direction^3)) //we've got a diagonally matching cable
if(!C.powernet) //if the matching cable somehow got no powernet, make him one (should not happen for cables)
var/datum/powernet/newPN = new()
newPN.add_cable(C)
if(powernet) //if we already have a powernet, then merge the two powernets
merge_powernets(powernet,C.powernet)
else
C.powernet.add_cable(src) //else, we simply connect to the matching cable powernet
//the same from the second direction component (east/west)
T = get_step(src, direction&12)//go east/west
for(var/obj/structure/cable/C in T)
if(!C)
continue
if(src == C)
continue
if(C.d1 == (direction^12) || C.d2 == (direction^12)) //we've got a diagonally matching cable
if(!C.powernet) //if the matching cable somehow got no powernet, make him one (should not happen for cables)
var/datum/powernet/newPN = new()
newPN.add_cable(C)
if(powernet) //if we already have a powernet, then merge the two powernets
merge_powernets(powernet,C.powernet)
else
C.powernet.add_cable(src) //else, we simply connect to the matching cable powernet
/obj/structure/cable/proc/mergeConnectedNetworks(var/direction)
var/turf/TB
if(!(d1 == direction || d2 == direction))
return
TB = get_step(src, direction)
for(var/obj/structure/cable/TC in TB)
if(!TC)
continue
if(src == TC)
continue
var/fdir = (!direction)? 0 : turn(direction, 180)
if(TC.d1 == fdir || TC.d2 == fdir)
if(!TC.powernet)
var/datum/powernet/PN = new()
PN.add_cable(TC)
if(powernet)
merge_powernets(powernet,TC.powernet)
else
TC.powernet.add_cable(src)
// merge with the powernets of power objects in the source turf
/obj/structure/cable/proc/mergeConnectedNetworksOnTurf()
var/list/to_connect = list()
if(!powernet) //if we somehow have no powernet, make one (should not happen for cables)
var/datum/powernet/newPN = new()
newPN.add_cable(src)
//first let's add turf cables to our powernet
//then we'll connect machines on turf with a node cable is present
for(var/AM in loc)
if(istype(AM,/obj/structure/cable))
var/obj/structure/cable/C = AM
if(C.d1 == d1 || C.d2 == d1 || C.d1 == d2 || C.d2 == d2) //only connected if they have a common direction
if(C.powernet == powernet) continue
if(C.powernet)
merge_powernets(powernet, C.powernet)
else
powernet.add_cable(C) //the cable was powernetless, let's just add it to our powernet
else if(istype(AM,/obj/machinery/power/apc))
var/obj/machinery/power/apc/N = AM
if(!N.terminal) continue // APC are connected through their terminal
if(N.terminal.powernet == powernet)
continue
to_connect += N.terminal //we'll connect the machines after all cables are merged
else if(istype(AM,/obj/machinery/power)) //other power machines
var/obj/machinery/power/M = AM
if(M.powernet == powernet)
continue
to_connect += M //we'll connect the machines after all cables are merged
//now that cables are done, let's connect found machines
for(var/obj/machinery/power/PM in to_connect)
if(!PM.connect_to_network())
PM.disconnect_from_network() //if we somehow can't connect the machine to the new powernet, remove it from the old nonetheless
//should be called after placing a cable which extends another cable, creating a "smooth" cable that no longer terminates in the centre of a turf.
//needed as this can, unlike other placements, disconnect cables
/obj/structure/cable/proc/denode()
var/turf/T1 = loc
if(!T1) return
var/list/powerlist = power_list(T1,src,0,0) //find the other cables that ended in the centre of the turf, with or without a powernet
if(powerlist.len>0)
var/datum/powernet/PN = new()
propagate_network(powerlist[1],PN) //propagates the new powernet beginning at the source cable
if(PN.is_empty()) //can happen with machines made nodeless when smoothing cables
del(PN)
obj/structure/cable/proc/cableColor(var/colorC)
var/color_n = "#DD0000"
if(colorC)
color_n = colorC
color = color_n
//////////////////////////////
// Misc.
/////////////////////////////
/obj/item/stack/cable_coil/cut
item_state = "coil2"
@@ -689,7 +885,7 @@ obj/structure/cable/proc/cableColor(var/colorC)
src.amount = rand(1,2)
pixel_x = rand(-2,2)
pixel_y = rand(-2,2)
updateicon()
update_icon()
update_wclass()
/obj/item/stack/cable_coil/yellow
@@ -716,27 +912,3 @@ obj/structure/cable/proc/cableColor(var/colorC)
/obj/item/stack/cable_coil/random/New()
item_color = pick(COLOR_RED, COLOR_BLUE, COLOR_GREEN, COLOR_WHITE, COLOR_PINK, COLOR_YELLOW, COLOR_CYAN)
..()
/obj/item/stack/cable_coil/attack(mob/M as mob, mob/user as mob)
if(hasorgans(M))
var/datum/organ/external/S = M:get_organ(user.zone_sel.selecting)
if(!(S.status & ORGAN_ROBOT) || user.a_intent != "help")
return ..()
if(istype(M,/mob/living/carbon/human))
var/mob/living/carbon/human/H = M
if(H.species.flags & IS_SYNTHETIC)
if(M == user)
user << "\red You can't repair damage to your own body - it's against OH&S."
return
if(S.burn_dam > 0 && use(1))
S.heal_damage(0,15,0,1)
user.visible_message("\red \The [user] repairs some burn damage on \the [M]'s [S.display_name] with \the [src].")
return
else
user << "Nothing to fix!"
else
return ..()

View File

@@ -10,7 +10,6 @@
icon_state = "tracker" //ICON stolen from solar tracker. There is no need to make new texture for debug item
anchored = 1
density = 1
directwired = 1
var/power_generation_rate = 2000000 //Defaults to 2MW of power. Should be enough to run SMES charging on full 2 times.
var/powernet_connection_failed = 0

View File

@@ -48,7 +48,6 @@ display round(lastgen) and phorontank amount
icon_state = "portgen0"
density = 1
anchored = 0
directwired = 0
use_power = 0
var/active = 0

View File

@@ -1,10 +1,16 @@
//////////////////////////////
// POWER MACHINERY BASE CLASS
//////////////////////////////
/////////////////////////////
// Definitions
/////////////////////////////
/obj/machinery/power
name = null
icon = 'icons/obj/power.dmi'
anchored = 1.0
var/datum/powernet/powernet = null
var/directwired = 1 // by default, power machines are connected by a cable in a neighbouring turf
// if set to 0, requires a 0-X cable on this turf
use_power = 0
idle_power_usage = 0
active_power_usage = 0
@@ -13,6 +19,10 @@
disconnect_from_network()
..()
///////////////////////////////
// General procedures
//////////////////////////////
// common helper procs for all power machines
/obj/machinery/power/proc/add_avail(var/amount)
if(powernet)
@@ -25,7 +35,7 @@
/obj/machinery/power/proc/surplus()
if(powernet)
return powernet.surplus()
return powernet.avail-powernet.load
else
return 0
@@ -35,18 +45,18 @@
else
return 0
/obj/machinery/power/proc/disconnect_terminal() // machines without a terminal will just return, no harm no fowl.
return
// returns true if the area has power on given channel (or doesn't require power).
// defaults to power_channel
/obj/machinery/proc/powered(var/chan = -1)
/obj/machinery/proc/powered(var/chan = -1) // defaults to power_channel
if(!src.loc)
return 0
//This is bad. This makes machines which are switched off not update their stat flag correctly when power_change() is called.
//If use_power is 0, then you probably shouldn't be checking power to begin with.
//if(!use_power)
// return 1
if(!use_power)
return 1
var/area/A = src.loc.loc // make sure it's in an area
if(!A || !isarea(A) || !A.master)
@@ -56,179 +66,23 @@
return A.master.powered(chan) // return power status of the area
// increment the power usage stats for an area
/obj/machinery/proc/use_power(var/amount, var/chan = -1, var/autocalled = 0) // defaults to power_channel
var/area/A = src.loc.loc // make sure it's in an area
/obj/machinery/proc/use_power(var/amount, var/chan = -1) // defaults to power_channel
var/area/A = get_area(src) // make sure it's in an area
if(!A || !isarea(A) || !A.master)
return
if(chan == -1)
chan = power_channel
A.master.use_power(amount, chan)
if(!autocalled)
log_power_update_request(A.master, src)
A.master.powerupdate = 2 // Decremented by 2 each GC tick, since it's not auto power change we're going to update power twice.
return 1
//The master_area optional argument can be used to save on a lot of processing if the master area is already known. This is mainly intended for when this proc is called by the master controller.
/obj/machinery/proc/power_change(var/area/master_area = null) // called whenever the power settings of the containing area change
/obj/machinery/proc/power_change() // called whenever the power settings of the containing area change
// by default, check equipment channel & set flag
// can override if needed
var/has_power
if (master_area)
has_power = master_area.powered(power_channel)
else
has_power = powered(power_channel)
if(has_power)
if(powered(power_channel))
stat &= ~NOPOWER
else
stat |= NOPOWER
// the powernet datum
// each contiguous network of cables & nodes
// rebuild all power networks from scratch
/hook/startup/proc/buildPowernets()
return makepowernets()
/proc/makepowernets()
for(var/datum/powernet/PN in powernets)
del(PN)
powernets.Cut()
for(var/obj/structure/cable/PC in cable_list)
if(!PC.powernet)
PC.powernet = new()
// if(Debug) world.log << "Starting mpn at [PC.x],[PC.y] ([PC.d1]/[PC.d2])"
powernet_nextlink(PC,PC.powernet)
// if(Debug) world.log << "[powernets.len] powernets found"
for(var/obj/structure/cable/C in cable_list)
if(!C.powernet) continue
C.powernet.cables += C
for(var/obj/machinery/power/M in machines)
if(!M.powernet) continue // APCs have powernet=0 so they don't count as network nodes directly
M.powernet.nodes[M] = M
return 1
// 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)
. = list()
var/fdir = (!d)? 0 : turn(d, 180)
// the opposite direction to d (or 0 if d==0)
///// Z-Level Stuff
var/Zdir
if(d==11)
Zdir = 11
else if (d==12)
Zdir = 12
else
Zdir = 999
///// Z-Level Stuff
// world.log << "d=[d] fdir=[fdir]"
for(var/AM in T)
if(AM == source) continue //we don't want to return source
if(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(P.directwired || (d == 0))
. += P
else if(istype(AM,/obj/structure/cable))
var/obj/structure/cable/C = AM
if(!unmarked || !C.powernet)
///// Z-Level Stuff
if(C.d1 == fdir || C.d2 == fdir || C.d1 == Zdir || C.d2 == Zdir)
///// Z-Level Stuff
. += C
else if(C.d1 == turn(C.d2, 180))
. += C
return .
/obj/structure/cable/proc/get_connections()
. = list() // this will be a list of all connected power objects
var/turf/T = loc
///// Z-Level Stuff
if(d1)
if(d1 <= 10)
T = get_step(src, d1)
if(T)
. += power_list(T, src, d1, 1)
else if (d1 == 11 || d1 == 12)
var/turf/controllerlocation = locate(1, 1, z)
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
if(controller.up && d1 == 12)
T = locate(src.x, src.y, controller.up_target)
if(T)
. += power_list(T, src, 11, 1)
if(controller.down && d1 == 11)
T = locate(src.x, src.y, controller.down_target)
if(T)
. += power_list(T, src, 12, 1)
else if(!d1)
if(T)
. += power_list(T, src, d1, 1)
if(d2 == 11 || d2 == 12)
var/turf/controllerlocation = locate(1, 1, z)
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
if(controller.up && d2 == 12)
T = locate(src.x, src.y, controller.up_target)
if(T)
. += power_list(T, src, 11, 1)
if(controller.down && d2 == 11)
T = locate(src.x, src.y, controller.down_target)
if(T)
. += power_list(T, src, 12, 1)
else
T = get_step(src, d2)
if(T)
. += power_list(T, src, d2, 1)
///// Z-Level Stuff
return .
/obj/machinery/power/proc/get_connections()
. = list()
if(!directwired)
return get_indirect_connections()
var/cdir
for(var/card in cardinal)
var/turf/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 .
/obj/machinery/power/proc/get_indirect_connections()
. = list()
for(var/obj/structure/cable/C in loc)
if(C.powernet) continue
if(C.d1 == 0)
. += C
return .
return
// connect the machine to a powernet if a node cable is present on the turf
/obj/machinery/power/proc/connect_to_network()
@@ -250,20 +104,193 @@
powernet.remove_machine(src)
return 1
/turf/proc/get_cable_node()
if(!istype(src, /turf/simulated/floor))
return null
for(var/obj/structure/cable/C in src)
if(C.d1 == 0)
return C
return null
// 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/weapon/W, mob/user)
/area/proc/get_apc()
for(var/area/RA in src.related)
var/obj/machinery/power/apc/FINDME = locate() in RA
if (FINDME)
return FINDME
if(istype(W, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/coil = W
var/turf/T = user.loc
if(T.intact || !istype(T, /turf/simulated/floor))
return
if(get_dist(src, user) > 1)
return
coil.turf_place(T, user)
return
else
..()
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 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 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/fdir = (!d)? 0 : turn(d, 180) // the opposite direction to d (or 0 if d==0)
///// Z-Level Stuff
var/Zdir
if(d==11)
Zdir = 11
else if (d==12)
Zdir = 12
else
Zdir = 999
///// Z-Level Stuff
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)
///// Z-Level Stuff
if(C.d1 == fdir || C.d2 == fdir || C.d1 == Zdir || C.d2 == Zdir)
///// Z-Level Stuff
. += C
else if(C.d1 == d || C.d2 == d)
. += C
return .
/hook/startup/proc/buildPowernets()
return makepowernets()
// rebuild all power networks from scratch - only called at world creation or by the admin verb
/proc/makepowernets()
for(var/datum/powernet/PN in powernets)
del(PN)
powernets.Cut()
for(var/obj/structure/cable/PC in cable_list)
if(!PC.powernet)
var/datum/powernet/NewPN = new()
NewPN.add_cable(PC)
propagate_network(PC,PC.powernet)
return 1
//remove the old powernet and replace it with a new one throughout the network.
/proc/propagate_network(var/obj/O, var/datum/powernet/PN)
//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)
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
@@ -272,17 +299,11 @@
//No animations will be performed by this proc.
/proc/electrocute_mob(mob/living/carbon/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
//This is for performance optimization only.
//DO NOT modify siemens_coeff here. That is checked in human/electrocute_act()
if(istype(M,/mob/living/carbon/human))
var/mob/living/carbon/human/H = M
if(H.species.insulated)
return 0
else if(H.gloves)
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
if(G.siemens_coefficient == 0) return 0 //to avoid spamming with insulated glvoes on
var/area/source_area
if(istype(power_source,/area))
@@ -328,11 +349,10 @@
var/drained_energy = drained_hp*20
if (source_area)
source_area.use_power(drained_energy)
source_area.use_power(drained_energy/CELLRATE)
else if (istype(power_source,/datum/powernet))
//var/drained_power = drained_energy/CELLRATE //convert from "joules" to "watts" <<< NO. THIS IS WRONG. CELLRATE DOES NOT CONVERT TO OR FROM JOULES.
PN.draw_power(drained_energy)
var/drained_power = drained_energy/CELLRATE //convert from "joules" to "watts"
PN.load+=drained_power
else if (istype(power_source, /obj/item/weapon/cell))
cell.use(drained_energy*CELLRATE) //convert to units of charge.
cell.use(drained_energy)
return drained_energy

View File

@@ -1,17 +1,13 @@
/datum/powernet
var/list/cables = list() // all cables & junctions
var/list/nodes = list() // all APCs & sources
var/list/nodes = list() // all connected machines
var/newload = 0
var/load = 0
var/newavail = 0
var/avail = 0
var/viewload = 0
var/number = 0
var/perapc = 0 // per-apc avilability
var/perapc_excess = 0
var/netexcess = 0
var/load = 0 // the current load on the powernet, increased by each machine at processing
var/newavail = 0 // what available power was gathered last tick, then becomes...
var/avail = 0 //...the current available power in the powernet
var/viewload = 0 // the load as it appears on the power console (gradually updated)
var/number = 0 // Unused //TODEL
var/netexcess = 0 // excess power on the powernet (typically avail-load)
/datum/powernet/New()
powernets += src
@@ -19,9 +15,34 @@
/datum/powernet/Del()
powernets -= src
/datum/powernet/proc/draw_power(var/amount)
var/drained = min(amount, avail)
load += drained
return drained
/datum/powernet/proc/is_empty()
return !cables.len && !nodes.len
//remove a cable from the current powernet
//if the powernet is then empty, delete it
//Warning : this proc DON'T check if the cable exists
/datum/powernet/proc/remove_cable(var/obj/structure/cable/C)
cables -= C
C.powernet = null
if(is_empty())//the powernet is now empty...
del(src)///... delete it - qdel
//add a cable to the current powernet
//Warning : this proc DON'T check if the cable exists
/datum/powernet/proc/add_cable(var/obj/structure/cable/C)
if(C.powernet)// if C already has a powernet...
if(C.powernet == src)
return
else
C.powernet.remove_cable(C) //..remove it
C.powernet = src
cables +=C
//remove a power machine from the current powernet
//if the powernet is then empty, delete it
//Warning : this proc DON'T check if the machine exists
@@ -43,211 +64,28 @@
M.powernet = src
nodes[M] = M
//remove a cable from the current powernet
//if the powernet is then empty, delete it
//Warning : this proc DON'T check if the cable exists
/datum/powernet/proc/remove_cable(var/obj/structure/cable/C)
cables -= C
C.powernet = null
if(is_empty())//the powernet is now empty...
del(src)///... delete it - qdel
//handles the power changes in the powernet
//called every ticks by the powernet controller
/datum/powernet/proc/reset()
//add a cable to the current powernet
//Warning : this proc DON'T check if the cable exists
/datum/powernet/proc/add_cable(var/obj/structure/cable/C)
if(C.powernet)// if C already has a powernet...
if(C.powernet == src)
return
else
C.powernet.remove_cable(C) //..remove it
C.powernet = src
cables +=C
//see if there's a surplus of power remaining in the powernet and stores unused power in the SMES
netexcess = avail - load
/datum/powernet/proc/process()
load = newload
newload = 0
if(netexcess > 100 && nodes && nodes.len) // if there was excess power last cycle
for(var/obj/machinery/power/smes/S in nodes) // find the SMESes in the network
S.restore() // and restore some of the power that was used
//updates the viewed load (as seen on power computers)
viewload = 0.8*viewload + 0.2*load
viewload = round(viewload)
//reset the powernet
load = 0
avail = newavail
newavail = 0
viewload = 0.8*viewload + 0.2*load
viewload = round(viewload)
var/numapc = 0
if(nodes && nodes.len) // Added to fix a bad list bug -- TLE
for(var/obj/machinery/power/terminal/term in nodes)
if( istype( term.master, /obj/machinery/power/apc ) )
numapc++
netexcess = avail - load
if(numapc)
//very simple load balancing. If there was a net excess this tick then it must have been that some APCs used less than perapc, since perapc*numapc = avail
//Therefore we can raise the amount of power rationed out to APCs on the assumption that those APCs that used less than perapc will continue to do so.
//If that assumption fails, then some APCs will miss out on power next tick, however it will be rebalanced for the tick after.
if (netexcess >= 0)
perapc_excess += min(netexcess/numapc, (avail - perapc) - perapc_excess)
else
perapc_excess = 0
perapc = avail/numapc + perapc_excess
if( netexcess > 100) // if there was excess power last cycle
if(nodes && nodes.len)
for(var/obj/machinery/power/smes/S in nodes) // find the SMESes in the network
if(S.powernet == src)
S.restore() // and restore some of the power that was used
else
error("[S.name] (\ref[S]) had a [S.powernet ? "different (\ref[S.powernet])" : "null"] powernet to our powernet (\ref[src]).")
nodes.Remove(S)
//Returns the amount of available power
/datum/powernet/proc/surplus()
return max(avail - newload, 0)
//Returns the amount of excess power (before refunding to SMESs) from last tick.
//This is for machines that might adjust their power consumption using this data.
/datum/powernet/proc/last_surplus()
return max(avail - load, 0)
//Attempts to draw power from a powernet. Returns the actual amount of power drawn
/datum/powernet/proc/draw_power(var/requested_amount)
var/surplus = max(avail - newload, 0)
var/actual_draw = min(requested_amount, surplus)
newload += actual_draw
return actual_draw
// cut a powernet at this cable object
/datum/powernet/proc/cut_cable(var/obj/structure/cable/C)
var/turf/T1 = C.loc
if(!T1) return
var/node = 0
if(C.d1 == 0)
node = 1
var/turf/T2
if(C.d2) T2 = get_step(T1, C.d2)
if(C.d1) T1 = get_step(T1, C.d1)
var/list/P1 = power_list(T1, C, C.d1) // what joins on to cut cable in dir1
var/list/P2 = power_list(T2, C, C.d2) // what joins on to cut cable in dir2
// if(Debug)
// for(var/obj/O in P1)
// world.log << "P1: [O] at [O.x] [O.y] : [istype(O, /obj/structure/cable) ? "[O:d1]/[O:d2]" : null] "
// for(var/obj/O in P2)
// world.log << "P2: [O] at [O.x] [O.y] : [istype(O, /obj/structure/cable) ? "[O:d1]/[O:d2]" : null] "
if(P1.len == 0 || P2.len == 0)//if nothing in either list, then the cable was an endpoint no need to rebuild the powernet,
cables -= C //just remove cut cable from the list
// if(Debug) world.log << "Was end of cable"
return
//null the powernet reference of all cables & nodes in this powernet
var/i=1
while(i<=cables.len)
var/obj/structure/cable/Cable = cables[i]
if(Cable)
Cable.powernet = null
if(Cable == C)
cables.Cut(i,i+1)
continue
i++
i=1
while(i<=nodes.len)
var/obj/machinery/power/Node = nodes[i]
if(Node)
Node.powernet = null
i++
// remove the cut cable from the network
// C.netnum = -1
C.loc = null
powernet_nextlink(P1[1], src) // propagate network from 1st side of cable, using current netnum //TODO?
// now test to see if propagation reached to the other side
// if so, then there's a loop in the network
var/notlooped = 0
for(var/O in P2)
if( istype(O, /obj/machinery/power) )
var/obj/machinery/power/Machine = O
if(Machine.powernet != src)
notlooped = 1
break
else if( istype(O, /obj/structure/cable) )
var/obj/structure/cable/Cable = O
if(Cable.powernet != src)
notlooped = 1
break
if(notlooped)
// not looped, so make a new powernet
var/datum/powernet/PN = new()
powernets += PN
// if(Debug) world.log << "Was not looped: spliting PN#[number] ([cables.len];[nodes.len])"
i=1
while(i<=cables.len)
var/obj/structure/cable/Cable = cables[i]
if(Cable && !Cable.powernet) // non-connected cables will have powernet=null, since they weren't reached by propagation
PN.add_cable(Cable)
continue
i++
i=1
while(i<=nodes.len)
var/obj/machinery/power/Node = nodes[i]
if(Node && !Node.powernet)
Node.powernet = PN
nodes.Cut(i,i+1)
PN.nodes[Node] = Node
continue
i++
// Disconnect machines connected to nodes
if(node)
for(var/obj/machinery/power/P in T1)
if(P.powernet && !P.powernet.nodes[src])
P.disconnect_from_network()
// if(Debug)
// world.log << "Old PN#[number] : ([cables.len];[nodes.len])"
// world.log << "New PN#[PN.number] : ([PN.cables.len];[PN.nodes.len])"
//
// else
// if(Debug)
// world.log << "Was looped."
// //there is a loop, so nothing to be done
// return
/datum/powernet/proc/get_electrocute_damage()
switch(avail)/*
if (1300000 to INFINITY)
return min(rand(70,150),rand(70,150))
if (750000 to 1300000)
return min(rand(50,115),rand(50,115))
if (100000 to 750000-1)
return min(rand(35,101),rand(35,101))
if (75000 to 100000-1)
return min(rand(30,95),rand(30,95))
if (50000 to 75000-1)
return min(rand(25,80),rand(25,80))
if (25000 to 50000-1)
return min(rand(20,70),rand(20,70))
if (10000 to 25000-1)
return min(rand(20,65),rand(20,65))
if (1000 to 10000-1)
return min(rand(10,20),rand(10,20))*/
switch(avail)
if (1000000 to INFINITY)
return min(rand(50,160),rand(50,160))
if (200000 to 1000000)
@@ -261,84 +99,23 @@
else
return 0
/proc/powernet_nextlink(var/obj/O, var/datum/powernet/PN)
var/list/P
////////////////////////////////////////////////
// Misc.
///////////////////////////////////////////////
while(1)
if( istype(O,/obj/structure/cable) )
var/obj/structure/cable/C = O
C.powernet = PN
P = C.get_connections()
else if(O.anchored && istype(O,/obj/machinery/power))
var/obj/machinery/power/M = O
M.powernet = PN
P = M.get_connections()
// return a knot cable (O-X) if one is present in the turf
// null if there's none
/turf/proc/get_cable_node()
if(!istype(src, /turf/simulated/floor))
return null
for(var/obj/structure/cable/C in src)
if(C.d1 == 0)
return C
return null
else
return
if(P.len == 0) return
O = P[1]
for(var/L = 2 to P.len)
powernet_nextlink(P[L], PN)
//The powernet that calls this proc will consume the other powernet - Rockdtben
//TODO: rewrite so the larger net absorbs the smaller net
/proc/merge_powernets(var/datum/powernet/net1, var/datum/powernet/net2)
if(!net1 || !net2) return
if(net1 == net2) 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
for(var/i=1,i<=net2.nodes.len,i++) //merge net2 into net1
var/obj/machinery/power/Node = net2.nodes[i]
if(Node)
Node.powernet = net1
net1.nodes[Node] = Node
for(var/i=1,i<=net2.cables.len,i++)
var/obj/structure/cable/Cable = net2.cables[i]
if(Cable)
net1.add_cable(Cable)
del(net2)
return net1
//remove the old powernet and replace it with a new one throughout the network.
/proc/propagate_network(var/obj/O, var/datum/powernet/PN)
//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
/area/proc/get_apc()
for(var/area/RA in src.related)
var/obj/machinery/power/apc/FINDME = locate() in RA
if (FINDME)
return FINDME

View File

@@ -8,7 +8,6 @@ var/global/list/rad_collectors = list()
icon_state = "ca"
anchored = 0
density = 1
directwired = 1
req_access = list(access_engine_equip)
// use_power = 0
var/obj/item/weapon/tank/phoron/P = null
@@ -30,7 +29,7 @@ var/global/list/rad_collectors = list()
//so that we don't zero out the meter if the SM is processed first.
last_power = last_power_new
last_power_new = 0
if(P)
if(P.air_contents.gas["phoron"] == 0)

View File

@@ -40,7 +40,6 @@
..()
if(state == 2 && anchored)
connect_to_network()
src.directwired = 1
/obj/machinery/power/emitter/Del()
message_admins("Emitter deleted at ([x],[y],[z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)",0,1)
@@ -125,13 +124,13 @@
else
src.fire_delay = rand(min_burst_delay, max_burst_delay)
src.shot_number = 0
//need to calculate the power per shot as the emitter doesn't fire continuously.
var/burst_time = (min_burst_delay + max_burst_delay)/2 + 2*(burst_shots-1)
var/power_per_shot = active_power_usage * (burst_time/10) / burst_shots
var/obj/item/projectile/beam/emitter/A = new /obj/item/projectile/beam/emitter( src.loc )
A.damage = round(power_per_shot/EMITTER_DAMAGE_POWER_TRANSFER)
playsound(src.loc, 'sound/weapons/emitter.ogg', 25, 1)
if(prob(35))
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
@@ -198,7 +197,6 @@
state = 2
user << "You weld the [src] to the floor."
connect_to_network()
src.directwired = 1
else
user << "\red You need more welding fuel to complete this task."
if(2)
@@ -212,7 +210,6 @@
state = 1
user << "You cut the [src] free from the floor."
disconnect_from_network()
src.directwired = 0
else
user << "\red You need more welding fuel to complete this task."
return

View File

@@ -22,7 +22,6 @@ var/list/solars_list = list()
icon_state = "sp_base"
anchored = 1
density = 1
directwired = 1
use_power = 0
idle_power_usage = 0
active_power_usage = 0
@@ -270,8 +269,6 @@ var/list/solars_list = list()
icon_state = "solar"
anchored = 1
density = 1
directwired = 1
use_power = 1
idle_power_usage = 5
active_power_usage = 20
var/id = 0

View File

@@ -11,7 +11,6 @@
layer = TURF_LAYER
var/obj/machinery/power/master = null
anchored = 1
directwired = 0 // must have a cable on same turf connecting to terminal
layer = 2.6 // a bit above wires
@@ -21,6 +20,10 @@
if(level==1) hide(T.intact)
return
/obj/machinery/power/terminal/Del()
if(master)
master.disconnect_terminal()
return ..()
/obj/machinery/power/terminal/hide(var/i)
if(i)

View File

@@ -10,7 +10,6 @@
icon_state = "tracker"
anchored = 1
density = 1
directwired = 1
use_power = 0 // doesn't use APC power
var/power_usage = 500 //W

View File

@@ -22,7 +22,6 @@
anchored = 1
density = 1
var/obj/machinery/compressor/compressor
directwired = 1
var/turf/simulated/outturf
var/lastgen

View File

@@ -70,12 +70,12 @@
var/shieldload = between(500, max_stored_power - storedpower, power_draw) //what we try to draw
shieldload = PN.draw_power(shieldload) //what we actually get
storedpower += shieldload
//If we're still in the red, then there must not be enough available power to cover our load.
if(storedpower <= 0)
power = 0
return 0
power = 1 // IVE GOT THE POWER!
return 1

View File

@@ -107,14 +107,14 @@
/obj/machinery/shield_capacitor/process()
if (!anchored)
active = 0
//see if we can connect to a power net.
var/datum/powernet/PN
var/turf/T = src.loc
var/obj/structure/cable/C = T.get_cable_node()
if (C)
PN = C.powernet
if (PN)
var/power_draw = between(0, max_charge - stored_charge, charge_rate) //what we are trying to draw
power_draw = PN.draw_power(power_draw) //what we actually get
@@ -138,7 +138,7 @@
active = !active
if( href_list["charge_rate"] )
charge_rate = between(10000, charge_rate + text2num(href_list["charge_rate"]), max_charge_rate)
updateDialog()
/obj/machinery/shield_capacitor/power_change()