Merge branch 'master' of https://github.com/ParadiseSS13/Paradise into alarms

Conflicts:
	_maps/map_files/RandomZLevels/moonoutpost19.dmm
	_maps/map_files/cyberiad/cyberiad.dmm
	code/controllers/master_controller.dm
	code/game/machinery/alarm.dm
	code/modules/power/apc.dm
This commit is contained in:
Markolie
2015-08-03 00:04:24 +02:00
78 changed files with 1812 additions and 1450 deletions
+1 -1
View File
@@ -1139,7 +1139,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
for(var/obj/machinery/power/smes/SMES in world)
if(SMES.anchored)
SMES.chargemode = 1
SMES.input_attempt = 1
/client/proc/cmd_debug_mob_lists()
set category = "Debug"
+1 -1
View File
@@ -18,7 +18,7 @@
var/delay = 0
var/datum/radio_frequency/radio_connection
var/airlock_wire = null
New()
..()
if(!radio_controller)
+4 -4
View File
@@ -130,16 +130,16 @@
#if LIGHTING_FALLOFF == 1 //circular
#define LUM_DISTANCE(swapvar, O, T) swapvar = (O.x - T.x)**2 + (O.y - T.y)**2 + LIGHTING_HEIGHT
#if LIGHTING_LAMBERTIAN == 1
#define LUM_ATTENUATION(swapvar) swapvar = CLAMP01((1 - CLAMP01(sqrt(swapvar) / light_range)) * (1 / sqrt(swapvar + 1)))
#define LUM_ATTENUATION(swapvar) swapvar = CLAMP01((1 - CLAMP01(sqrt(swapvar) / max(1,light_range))) * (1 / sqrt(swapvar + 1)))
#else
#define LUM_ATTENUATION(swapvar) swapvar = 1 - CLAMP01(sqrt(swapvar) / light_range)
#define LUM_ATTENUATION(swapvar) swapvar = 1 - CLAMP01(sqrt(swapvar) / max(1,light_range))
#endif
#elif LIGHTING_FALLOFF == 2 //square
#define LUM_DISTANCE(swapvar, O, T) swapvar = abs(O.x - T.x) + abs(O.y - T.y) + LIGHTING_HEIGHT
#if LIGHTING_LAMBERTIAN == 1
#define LUM_ATTENUATION(swapvar) swapvar = CLAMP01((1 - CLAMP01(swapvar / light_range)) * (1 / sqrt(swapvar**2 + 1)))
#define LUM_ATTENUATION(swapvar) swapvar = CLAMP01((1 - CLAMP01(swapvar / max(1,light_range))) * (1 / sqrt(swapvar**2 + 1)))
#else
#define LUM_ATTENUATION(swapvar) swapvar = CLAMP01(swapvar / light_range)
#define LUM_ATTENUATION(swapvar) swapvar = CLAMP01(swapvar / max(1,light_range))
#endif
#endif
@@ -45,7 +45,7 @@
icon_state = "alien[caste]_leap"
pixel_x = -32
pixel_y = -32
else if(icon == 'icons/mob/alienleap.dmi' && icon_state == "alien[caste]_leap" && pixel_x == -32 && pixel_y == -32)
else if(icon == 'icons/mob/alienleap.dmi' && pixel_x == -32 && pixel_y == -32)
icon = initial(icon)// ^ this looks odd, but in theory it will prevent the icon and pixel_xy from being reset unless it needs to be
pixel_x = initial(pixel_x)
pixel_y = initial(pixel_y)
@@ -65,11 +65,11 @@
return 1
// if(M.health < -75) return 0
if((M.head && (M.head.flags & HEADCOVERSMOUTH)) || (M.wear_mask && (M.wear_mask.flags & MASKCOVERSMOUTH)))
M << "\blue <B>Remove your mask!</B>"
if((M.head && (M.head.flags & HEADCOVERSMOUTH)) || (M.wear_mask && (M.wear_mask.flags & MASKCOVERSMOUTH) && !M.wear_mask.mask_adjusted))
M << "<span class='boldnotice'>Remove your mask!</span>"
return 0
if((head && (head.flags & HEADCOVERSMOUTH)) || (wear_mask && (wear_mask.flags & MASKCOVERSMOUTH)))
M << "\blue <B>Remove his mask!</B>"
if((head && (head.flags & HEADCOVERSMOUTH)) || (wear_mask && (wear_mask.flags & MASKCOVERSMOUTH) && !wear_mask.mask_adjusted))
M << "<span class='boldnotice'>Remove his mask!</span>"
return 0
var/obj/effect/equip_e/human/O = new /obj/effect/equip_e/human()
File diff suppressed because it is too large Load Diff
+174 -299
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,14 +19,19 @@
disconnect_from_network()
return ..()
///////////////////////////////
// General procedures
//////////////////////////////
// common helper procs for all power machines
/obj/machinery/power/proc/add_avail(var/amount)
if(powernet)
powernet.newavail += amount
/obj/machinery/power/proc/add_load(var/amount)
/obj/machinery/power/proc/draw_power(var/amount)
if(powernet)
powernet.load += amount
return powernet.draw_power(amount)
return 0
/obj/machinery/power/proc/surplus()
if(powernet)
@@ -34,17 +45,16 @@
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
if(!use_power)
return 1
var/area/A = src.loc.loc // make sure it's in an area
if(!A || !isarea(A))
return 0 // if not, then not powered
@@ -71,94 +81,63 @@
stat |= NOPOWER
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
// 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)
qdel(PN)
powernets.Cut()
for(var/obj/structure/cable/PC in cable_list)
if(!PC.powernet)
PC.powernet = new()
powernets += PC.powernet
// 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
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
// 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)
// world.log << "d=[d] fdir=[fdir]"
for(var/AM in T)
if(AM == source) continue //we don't want to return source
// 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)
if(istype(AM,/obj/machinery/power))
var/obj/machinery/power/P = AM
if(P.powernet == 0) continue // exclude APCs which have powernet=0
if(istype(W, /obj/item/stack/cable_coil))
if(!unmarked || !P.powernet) //if unmarked=1 we only return things with no powernet
if(P.directwired || (d == 0))
. += P
var/obj/item/stack/cable_coil/coil = W
else if(istype(AM,/obj/structure/cable))
var/obj/structure/cable/C = AM
var/turf/T = user.loc
if(!unmarked || !C.powernet)
if(C.d1 == fdir || C.d2 == fdir)
. += C
else if(C.d1 == turn(C.d2, 180))
. += C
return .
if(T.intact || !istype(T, /turf/simulated/floor))
return
if(get_dist(src, user) > 1)
return
/obj/structure/cable/proc/get_connections()
. = list() // this will be a list of all connected power objects
var/turf/T = loc
if(d1) T = get_step(src, d1)
if(T) . += power_list(T, src, d1, 1)
T = get_step(src, d2)
if(T) . += power_list(T, src, d2, 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()
if(!directwired)
return get_indirect_connections()
var/cdir
var/turf/T
for(var/card in cardinal)
var/turf/T = get_step(loc,card)
T = get_step(loc,card)
cdir = get_dir(T,loc)
for(var/obj/structure/cable/C in T)
@@ -167,193 +146,132 @@
. += 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)
if(C.d1 == 0) // the cable is a node cable
. += C
return .
///////////////////////////////////////////
// GLOBAL PROCS for powernets handling
//////////////////////////////////////////
/proc/powernet_nextlink(var/obj/O, var/datum/powernet/PN)
var/list/P
while(1)
if( istype(O,/obj/structure/cable) )
var/obj/structure/cable/C = O
C.powernet = PN
P = C.get_connections()
// 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
else if(O.anchored && istype(O,/obj/machinery/power))
var/obj/machinery/power/M = O
M.powernet = PN
P = M.get_connections()
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)
qdel(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
return
continue
if(P.len == 0) return
O = P[1]
for(var/L = 2 to P.len)
powernet_nextlink(P[L], PN)
//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
// 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"
//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
//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
Cable.powernet = PN
cables.Cut(i,i+1) // remove from old network & add to new one
PN.cables += 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/reset()
//see if there's a surplus of power remaining in the powernet and stores unused power in the SMES
netexcess = avail - load
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
/datum/powernet/proc/get_electrocute_damage()
switch(avail)
if (5000000 to INFINITY)
return min(rand(200,300),rand(200,300))
if (4000000 to 5000000)
return min(rand(80,180),rand(80,180))
if (1000000 to 4000000)
return min(rand(50,160),rand(50,160))
if (200000 to 1000000)
return min(rand(25,80),rand(25,80))
if (100000 to 200000)//Ave powernet
return min(rand(20,60),rand(20,60))
if (50000 to 100000)
return min(rand(15,40),rand(15,40))
if (1000 to 50000)
return min(rand(10,20),rand(10,20))
else
return 0
//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
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
@@ -361,57 +279,18 @@
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
//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/i=1,i<=net2.cables.len,i++)
var/obj/structure/cable/Cable = net2.cables[i]
if(Cable)
Cable.powernet = net1
net1.cables += 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
qdel(net2)
return net1
/obj/machinery/power/proc/connect_to_network()
var/turf/T = src.loc
var/obj/structure/cable/C = T.get_cable_node()
if(!C || !C.powernet) return 0
// makepowernets() //TODO: find fast way //EWWWW what are you doing!?
powernet = C.powernet
powernet.nodes[src] = src
return 1
/obj/machinery/power/proc/disconnect_from_network()
if(!powernet)
//world << " no powernet"
return 0
powernet.nodes -= src
powernet = null
//world << "powernet null"
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
/area/proc/get_apc()
// This was a simple locate() in src, but an unresolved BYOND bug causes trying to locate() in an
// area to take an inconceivably long time, especially for large areas.
// See: http://www.byond.com/forum/?post=1860571
var/obj/machinery/power/apc/FINDME
for(FINDME in src)
return FINDME
//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
@@ -419,9 +298,6 @@
//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.gloves)
@@ -475,8 +351,7 @@
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"
PN.load+=drained_power
drained_power = PN.draw_power(drained_power)
else if (istype(power_source, /obj/item/weapon/stock_parts/cell))
cell.use(drained_energy)
return drained_energy
+162
View File
@@ -0,0 +1,162 @@
/datum/powernet
var/list/cables = list() // all cables & junctions
var/list/nodes = list() // all connected machines
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/perapc = 0 // per-apc avilability
var/perapc_excess = 0
var/netexcess = 0 // excess power on the powernet (typically avail-load)
var/problem = 0 // If either of these is set to 1 there is some sort of issue at the powernet.
/datum/powernet/New()
powernets += src
..()
/datum/powernet/Destroy()
powernets -= src
return ..()
//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)
/datum/powernet/proc/draw_power(var/amount)
var/draw = between(0, amount, avail - load)
load += draw
return draw
/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
/datum/powernet/proc/remove_machine(var/obj/machinery/power/M)
nodes -=M
M.powernet = null
if(is_empty())//the powernet is now empty...
del(src)///... delete it - qdel
//add a power machine to the current powernet
//Warning : this proc DON'T check if the machine exists
/datum/powernet/proc/add_machine(var/obj/machinery/power/M)
if(M.powernet)// if M already has a powernet...
if(M.powernet == src)
return
else
M.disconnect_from_network()//..remove it
M.powernet = src
nodes[M] = M
// Triggers warning for certain amount of ticks
/datum/powernet/proc/trigger_warning(var/duration_ticks = 20)
problem = max(duration_ticks, problem)
//handles the power changes in the powernet
//called every ticks by the powernet controller
/datum/powernet/proc/reset()
var/numapc = 0
if(problem > 0)
problem = max(problem - 1, 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 && 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 = round(load)
//reset the powernet
load = 0
avail = newavail
newavail = 0
/datum/powernet/proc/get_electrocute_damage()
switch(avail)
if (5000000 to INFINITY)
return min(rand(200,300),rand(200,300))
if (4000000 to 5000000)
return min(rand(80,180),rand(80,180))
if (1000000 to 4000000)
return min(rand(50,160),rand(50,160))
if (200000 to 1000000)
return min(rand(25,80),rand(25,80))
if (100000 to 200000)//Ave powernet
return min(rand(20,60),rand(20,60))
if (50000 to 100000)
return min(rand(15,40),rand(15,40))
if (1000 to 50000)
return min(rand(10,20),rand(10,20))
else
return 0
////////////////////////////////////////////////
// Misc.
///////////////////////////////////////////////
// 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
/area/proc/get_apc()
// This was a simple locate() in src, but an unresolved BYOND bug causes trying to locate() in an
// area to take an inconceivably long time, especially for large areas.
// See: http://www.byond.com/forum/?post=1860571
var/obj/machinery/power/apc/FINDME
for(FINDME in src)
return FINDME
@@ -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/plasma/P = null
@@ -46,57 +46,23 @@
return 1
return 0
/obj/machinery/containment_field/proc/shock(mob/living/user as mob)
/obj/machinery/containment_field/shock(mob/living/user as mob)
if(hasShocked)
return 0
if(!FG1 || !FG2)
qdel(src)
return 0
if(iscarbon(user))
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, user.loc)
s.start()
if(isliving(user))
hasShocked = 1
var/shock_damage = min(rand(30,40),rand(30,40))
user.burn_skin(shock_damage)
user.updatehealth()
user.visible_message("\red [user.name] was shocked by the [src.name]!", \
"\red <B>You feel a powerful shock course through your body sending you flying!</B>", \
"\red You hear a heavy electrical crack")
user.electrocute_act(shock_damage, src)
var/stun = min(shock_damage, 15)
user.Stun(stun)
user.Weaken(10)
user.updatehealth()
var/atom/target = get_edge_target_turf(user, get_dir(src, get_step_away(user, src)))
user.throw_at(target, 200, 4)
sleep(20)
hasShocked = 0
return
else if(issilicon(user))
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, user.loc)
s.start()
hasShocked = 1
var/shock_damage = rand(15,30)
user.take_overall_damage(0,shock_damage)
user.visible_message("\red [user.name] was shocked by the [src.name]!", \
"\red <B>Energy pulse detected, system damaged!</B>", \
"\red You hear an electrical crack")
if(prob(20))
user.Stun(2)
sleep(20)
hasShocked = 0
return
return
/obj/machinery/containment_field/proc/set_master(var/master1,var/master2)
+4 -10
View File
@@ -48,7 +48,6 @@
..()
if(state == 2 && anchored)
connect_to_network()
src.directwired = 1
if(frequency)
set_frequency(frequency)
/obj/machinery/power/emitter/multitool_menu(var/mob/user,var/obj/item/device/multitool/P)
@@ -145,8 +144,8 @@
return
if(((src.last_shot + src.fire_delay) <= world.time) && (src.active == 1))
if(!active_power_usage || avail(active_power_usage))
add_load(active_power_usage)
var/actual_load = draw_power(active_power_usage)
if(actual_load >= active_power_usage) //does the laser have enough power to shoot?
if(!powered)
powered = 1
update_icon()
@@ -238,7 +237,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)
@@ -252,7 +250,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
@@ -275,11 +272,8 @@
..()
return
/obj/machinery/power/emitter/emag_act(user as mob)
/obj/machinery/power/emitter/emag_act(var/mob/living/user as mob)
if(!emagged)
if(!ishuman(user))
return
var/mob/living/carbon/human/H = user
locked = 0
emagged = 1
H.visible_message("[H.name] emags the [src.name].","\red You short out the lock.")
user.visible_message("[user.name] emags the [src.name].","\red You short out the lock.")
+185 -200
View File
@@ -13,22 +13,32 @@
icon_state = "smes"
density = 1
anchored = 1
use_power = 0
var/output = 50000
var/lastout = 0
var/loaddemand = 0
var/capacity = 5e6
var/charge = 0
var/charging = 0
var/chargemode = 0
var/chargecount = 0
var/chargelevel = 50000
var/input_level_max = 200000 // cap on input_level
var/output_level_max = 200000 // cap on output_level
var/online = 1
var/capacity = 5e6 // maximum charge
var/charge = 0 // actual charge
var/input_attempt = 0 // 1 = attempting to charge, 0 = not attempting to charge
var/inputting = 0 // 1 = actually inputting, 0 = not inputting
var/input_level = 50000 // amount of power the SMES attempts to charge by
var/input_level_max = 200000 // cap on input_level
var/input_available = 0 // amount of charge available from input last tick
var/output_attempt = 1 // 1 = attempting to output, 0 = not attempting to output
var/outputting = 1 // 1 = actually outputting, 0 = not outputting
var/output_level = 50000 // amount of power the SMES attempts to output
var/output_level_max = 200000 // cap on output_level
var/output_used = 0 // amount of power actually outputted. may be less than output_level if the powernet returns excess power
//Holders for powerout event.
var/last_output_attempt = 0
var/last_input_attempt = 0
var/last_charge = 0
var/open_hatch = 0
var/name_tag = null
var/building_terminal = 0 //Suggestions about how to avoid clickspam building several terminals accepted!
var/obj/machinery/power/terminal/terminal = null
var/list/overlay_images
/obj/machinery/power/smes/New()
..()
@@ -42,35 +52,7 @@
component_parts += new /obj/item/weapon/stock_parts/capacitor(null)
component_parts += new /obj/item/stack/cable_coil(null, 5)
RefreshParts()
setup()
return
/obj/machinery/power/smes/upgraded/New()
..()
component_parts = list()
component_parts += new /obj/item/weapon/circuitboard/smes(null)
component_parts += new /obj/item/weapon/stock_parts/cell/hyper(null)
component_parts += new /obj/item/weapon/stock_parts/cell/hyper(null)
component_parts += new /obj/item/weapon/stock_parts/cell/hyper(null)
component_parts += new /obj/item/weapon/stock_parts/cell/hyper(null)
component_parts += new /obj/item/weapon/stock_parts/cell/hyper(null)
component_parts += new /obj/item/weapon/stock_parts/capacitor/super(null)
component_parts += new /obj/item/stack/cable_coil(null, 5)
RefreshParts()
return
/obj/machinery/power/smes/RefreshParts()
var/IO = 0
var/C = 0
for(var/obj/item/weapon/stock_parts/capacitor/CP in component_parts)
IO += CP.rating
input_level_max = 200000 * IO
output_level_max = 200000 * IO
for(var/obj/item/weapon/stock_parts/cell/PC in component_parts)
C += PC.maxcharge
capacity = C / (15000) * 1e6
/obj/machinery/power/smes/proc/setup()
spawn(5)
if(!powernet)
connect_to_network()
@@ -88,43 +70,52 @@
terminal.master = src
if(!terminal.powernet)
terminal.connect_to_network()
updateicon()
update_icon()
return
/obj/machinery/power/smes/proc/updateicon()
/obj/machinery/power/smes/upgraded/New()
..()
component_parts = list()
component_parts += new /obj/item/weapon/circuitboard/smes(null)
component_parts += new /obj/item/weapon/stock_parts/cell/hyper(null)
component_parts += new /obj/item/weapon/stock_parts/cell/hyper(null)
component_parts += new /obj/item/weapon/stock_parts/cell/hyper(null)
component_parts += new /obj/item/weapon/stock_parts/cell/hyper(null)
component_parts += new /obj/item/weapon/stock_parts/cell/hyper(null)
component_parts += new /obj/item/weapon/stock_parts/capacitor/super(null)
component_parts += new /obj/item/stack/cable_coil(null, 5)
RefreshParts()
/obj/machinery/power/smes/RefreshParts()
var/IO = 0
var/C = 0
for(var/obj/item/weapon/stock_parts/capacitor/CP in component_parts)
IO += CP.rating
input_level_max = 200000 * IO
output_level_max = 200000 * IO
for(var/obj/item/weapon/stock_parts/cell/PC in component_parts)
C += PC.maxcharge
capacity = C / (15000) * 1e6
/obj/machinery/power/smes/update_icon()
overlays.Cut()
if(stat & BROKEN) return
if(isnull(src.overlay_images))
src.overlay_images = new
src.overlay_images.len = 3
overlays += image('icons/obj/power.dmi', "smes-op[outputting]")
src.overlay_images[1] = image('icons/obj/power.dmi', "smes-op[online]")
src.overlay_images[2] = image('icons/obj/power.dmi', "smes-oc0")
src.overlay_images[3] = image('icons/obj/power.dmi', "smes-og1")
var/image/buffer
buffer = src.overlay_images[1]
buffer.icon_state = "smes-op[online]"
overlays += src.overlay_images[1]
if(!charging && chargemode)
buffer = src.overlay_images[2]
buffer.icon_state = "smes-oc0"
overlays += src.overlay_images[2]
if(inputting == 2)
overlays += image('icons/obj/power.dmi', "smes-oc2")
else if (inputting == 1)
overlays += image('icons/obj/power.dmi', "smes-oc1")
else
buffer = src.overlay_images[2]
buffer.icon_state = "smes-oc1"
overlays += src.overlay_images[2]
if(input_attempt)
overlays += image('icons/obj/power.dmi', "smes-oc0")
var/clevel = chargedisplay()
if(clevel > 0)
buffer = src.overlay_images[3]
buffer.icon_state = "smes-og[clevel]"
overlays += src.overlay_images[3]
if(clevel>0)
overlays += image('icons/obj/power.dmi', "smes-og[clevel]")
return
/obj/machinery/power/smes/attackby(obj/item/I, mob/user, params)
//opening using screwdriver
if(default_deconstruction_screwdriver(user, "[initial(icon_state)]-o", initial(icon_state), I))
@@ -220,7 +211,7 @@
user.visible_message(\
"<span class='alert'>[user.name] cuts the cables and dismantles the power terminal.</span>",\
"You cut the cables and dismantle the power terminal.")
charging = 0 //stop inputting, since we have don't have a terminal anymore
inputting = 0 //stop inputting, since we have don't have a terminal anymore
qdel(terminal)
return
@@ -238,92 +229,70 @@
disconnect_terminal()
return ..()
// create a terminal object pointing towards the SMES
// wires will attach to this
/obj/machinery/power/smes/proc/make_terminal(var/turf/T)
terminal = new/obj/machinery/power/terminal(T)
terminal.dir = get_dir(T,src)
terminal.master = src
/obj/machinery/power/smes/proc/disconnect_terminal()
if(terminal)
terminal.master = null
terminal = null
return round(5.5*charge/(capacity ? capacity : 5e6))
/obj/machinery/power/smes/proc/chargedisplay()
return round(5.5*charge/capacity)
return round(5.5*charge/(capacity ? capacity : 5e6))
#define SMESRATE 0.05
/obj/machinery/power/smes/process()
if(stat & BROKEN)
return
if(stat & BROKEN) return
//store machine state to see if we need to update the icon overlays
var/last_disp = chargedisplay()
var/last_chrg = charging
var/last_onln = online
var/last_chrg = inputting
var/last_onln = outputting
if(terminal)
var/excess = terminal.surplus()
//inputting
if(input_attempt)
var/target_load = min((capacity-charge)/SMESRATE, input_level) // charge at set rate, limited to spare capacity
var/actual_load = draw_power(target_load) // add the load to the terminal side network
charge += actual_load * SMESRATE // increase the charge
if(charging)
if(excess >= 0) // if there's power available, try to charge
if (actual_load >= target_load) // Did we charge at full rate?
inputting = 2
else if (actual_load) // If not, did we charge at least partially?
inputting = 1
else // Or not at all?
inputting = 0
var/load = min((capacity-charge)/SMESRATE, chargelevel) // charge at set rate, limited to spare capacity
//outputting
if(outputting)
output_used = min( charge/SMESRATE, output_level) //limit output to that stored
charge += load * SMESRATE // increase the charge
charge -= output_used*SMESRATE // reduce the storage (may be recovered in /restore() if excessive)
add_load(load) // add the load to the terminal side network
add_avail(output_used) // add output to powernet (smes side)
else // if not enough capcity
charging = 0 // stop charging
chargecount = 0
else
if(chargemode)
if(chargecount > rand(3,6))
charging = 1
chargecount = 0
if(excess > chargelevel)
chargecount++
else
chargecount = 0
else
chargecount = 0
if(online) // if outputting
lastout = min( charge/SMESRATE, output) //limit output to that stored
charge -= lastout*SMESRATE // reduce the storage (may be recovered in /restore() if excessive)
add_avail(lastout) // add output to powernet (smes side)
if(charge < 0.0001)
online = 0 // stop output if charge falls to zero
if(output_used < 0.0001) // either from no charge or set to 0
outputting = 0
investigate_log("lost power and turned <font color='red'>off</font>","singulo")
else if(output_attempt && charge > output_level && output_level > 0)
outputting = 1
else
output_used = 0
// only update icon if state changed
if(last_disp != chargedisplay() || last_chrg != charging || last_onln != online)
updateicon()
if(last_disp != chargedisplay() || last_chrg != inputting || last_onln != outputting)
update_icon()
return
// called after all power processes are finished
// restores charge level to smes if there was excess this ptick
/obj/machinery/power/smes/proc/restore()
if(stat & BROKEN)
return
if(!online)
loaddemand = 0
if(!outputting)
output_used = 0
return
var/excess = powernet.netexcess // this was how much wasn't used on the network last ptick, minus any removed by other SMESes
excess = min(lastout, excess) // clamp it to how much was actually output by this SMES last ptick
excess = min(output_used, excess) // clamp it to how much was actually output by this SMES last ptick
excess = min((capacity-charge)/SMESRATE, excess) // for safety, also limit recharge by space capacity of SMES (shouldn't happen)
@@ -331,23 +300,51 @@
var/clev = chargedisplay()
charge += excess * SMESRATE
charge += excess * SMESRATE // restore unused power
powernet.netexcess -= excess // remove the excess from the powernet, so later SMESes don't try to use it
loaddemand = lastout-excess
output_used -= excess
if(clev != chargedisplay() )
updateicon()
if(clev != chargedisplay() ) //if needed updates the icons overlay
update_icon()
return
//Will return 1 on failure
/obj/machinery/power/smes/proc/make_terminal(const/mob/user)
if (user.loc == loc)
user << "<span class='warning'>You must not be on the same tile as the [src].</span>"
return 1
/obj/machinery/power/smes/add_load(var/amount)
//Direction the terminal will face to
var/tempDir = get_dir(user, src)
switch(tempDir)
if (NORTHEAST, SOUTHEAST)
tempDir = EAST
if (NORTHWEST, SOUTHWEST)
tempDir = WEST
var/turf/tempLoc = get_step(src, reverse_direction(tempDir))
if (istype(tempLoc, /turf/space))
user << "<span class='warning'>You can't build a terminal on space.</span>"
return 1
else if (istype(tempLoc))
if(tempLoc.intact)
user << "<span class='warning'>You must remove the floor plating first.</span>"
return 1
user << "<span class='notice'>You start adding cable to the [src].</span>"
if(do_after(user, 50))
terminal = new /obj/machinery/power/terminal(tempLoc)
terminal.dir = tempDir
terminal.master = src
return 0
return 1
/obj/machinery/power/smes/draw_power(var/amount)
if(terminal && terminal.powernet)
terminal.powernet.load += amount
return terminal.powernet.draw_power(amount)
return 0
/obj/machinery/power/smes/attack_ai(mob/user)
add_fingerprint(user)
add_hiddenprint(user)
ui_interact(user)
/obj/machinery/power/smes/attack_ghost(mob/user)
@@ -361,7 +358,6 @@
return
/obj/machinery/power/smes/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
if(stat & BROKEN)
return
@@ -369,14 +365,21 @@
var/data[0]
data["nameTag"] = name_tag
data["storedCapacity"] = round(100.0*charge/capacity, 0.1)
data["charging"] = charging
data["chargeMode"] = chargemode
data["chargeLevel"] = chargelevel
data["charging"] = inputting
data["chargeMode"] = input_attempt
data["chargeLevel"] = input_level
data["chargeMax"] = input_level_max
data["outputOnline"] = online
data["outputLevel"] = output
data["outputOnline"] = output_attempt
data["outputLevel"] = output_level
data["outputMax"] = output_level_max
data["outputLoad"] = round(loaddemand)
data["outputLoad"] = round(output_used)
if(outputting)
data["outputting"] = 2 // smes is outputting
else if(!outputting && output_attempt)
data["outputting"] = 1 // smes is online but not outputting because it's charge level is too low
else
data["outputting"] = 0 // smes is not outputting
// update the ui if it exists, returns null if no ui is passed/found
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
@@ -391,60 +394,45 @@
// auto update every Master Controller tick
ui.set_auto_update(1)
/obj/machinery/power/smes/Topic(href, href_list)
..()
if (usr.stat || usr.restrained() )
return
if (!(istype(usr, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
if(!istype(usr, /mob/living/silicon/ai))
usr << "\red You don't have the dexterity to do this!"
return
//world << "[href] ; [href_list[href]]"
if (!istype(src.loc, /turf) && !istype(usr, /mob/living/silicon/))
return 0 // Do not update ui
if(..())
return 1
if( href_list["cmode"] )
chargemode = !chargemode
if(!chargemode)
charging = 0
updateicon()
inputting(!input_attempt)
update_icon()
else if( href_list["online"] )
online = !online
updateicon()
outputting(!output_attempt)
update_icon()
else if( href_list["input"] )
switch( href_list["input"] )
if("min")
chargelevel = 0
input_level = 0
if("max")
chargelevel = input_level_max //30000
input_level = input_level_max
if("set")
chargelevel = input(usr, "Enter new input level (0-[input_level_max])", "SMES Input Power Control", chargelevel) as num
chargelevel = max(0, min(input_level_max, chargelevel)) // clamp to range
input_level = input(usr, "Enter new input level (0-[input_level_max])", "SMES Input Power Control", input_level) as num
input_level = max(0, min(input_level_max, input_level)) // clamp to range
else if( href_list["output"] )
switch( href_list["output"] )
if("min")
output = 0
output_level = 0
if("max")
output = output_level_max //30000
output_level = output_level_max
if("set")
output = input(usr, "Enter new output level (0-[output_level_max])", "SMES Output Power Control", output) as num
output = max(0, min(output_level_max, output)) // clamp to range
output_level = input(usr, "Enter new output level (0-[output_level_max])", "SMES Output Power Control", output_level) as num
output_level = max(0, min(output_level_max, output_level)) // clamp to range
investigate_log("input/output; [chargelevel>output?"<font color='green'>":"<font color='red'>"][chargelevel]/[output]</font> | Output-mode: [online?"<font color='green'>on</font>":"<font color='red'>off</font>"] | Input-mode: [chargemode?"<font color='green'>auto</font>":"<font color='red'>off</font>"] by [usr.key]","singulo")
investigate_log("input/output; [input_level>output_level?"<font color='green'>":"<font color='red'>"][input_level]/[output_level]</font> | Output-mode: [output_attempt?"<font color='green'>on</font>":"<font color='red'>off</font>"] | Input-mode: [input_attempt?"<font color='green'>auto</font>":"<font color='red'>off</font>"] by [usr.key]","singulo")
return 1
/obj/machinery/power/smes/proc/ion_act()
if((src.z in config.station_levels))
if(src.z in config.station_levels)
if(prob(1)) //explosion
world << "\red SMES explosion in [src.loc.loc]"
for(var/mob/M in viewers(src))
M.show_message("\red The [src.name] is making strange noises!", 3, "\red You hear sizzling electronics.", 2)
sleep(10*pick(4,5,6,7,10,14))
@@ -452,11 +440,10 @@
smoke.set_up(3, 0, src.loc)
smoke.attach(src)
smoke.start()
explosion(src.loc, -1, 0, 1, 3, 0)
explosion(src.loc, -1, 0, 1, 3, 1, 0)
qdel(src)
return
if(prob(15)) //Power drain
world << "\red SMES power drain in [src.loc.loc]"
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
@@ -465,45 +452,43 @@
else
emp_act(2)
if(prob(5)) //smoke only
world << "\red SMES smoke in [src.loc.loc]"
var/datum/effect/effect/system/harmless_smoke_spread/smoke = new /datum/effect/effect/system/harmless_smoke_spread()
smoke.set_up(3, 0, src.loc)
smoke.attach(src)
smoke.start()
/obj/machinery/power/smes/proc/inputting(var/do_input)
input_attempt = do_input
if(!input_attempt)
inputting = 0
/obj/machinery/power/smes/proc/outputting(var/do_output)
output_attempt = do_output
if(!output_attempt)
outputting = 0
/obj/machinery/power/smes/emp_act(severity)
online = 0
charging = 0
output = 0
inputting(rand(0,1))
outputting(rand(0,1))
output_level = rand(0, output_level_max)
input_level = rand(0, input_level_max)
charge -= 1e6/severity
if (charge < 0)
charge = 0
spawn(100)
output = initial(output)
charging = initial(charging)
online = initial(online)
update_icon()
..()
/obj/machinery/power/smes/engineering
charge = 1e6 // Engineering starts with some charge for singulo
charge = 1e6 // Engineering starts with some charge for singulo
/obj/machinery/power/smes/magical
name = "magical power storage unit"
desc = "A high-capacity superconducting magnetic energy storage (SMES) unit. Magically produces power."
process()
capacity = INFINITY
charge = INFINITY
..()
capacity = 9000000
output_level = 250000
/proc/rate_control(var/S, var/V, var/C, var/Min=1, var/Max=5, var/Limit=null)
var/href = "<A href='?src=\ref[S];rate control=1;[V]"
var/rate = "[href]=-[Max]'>-</A>[href]=-[Min]'>-</A> [(C?C : 0)] [href]=[Min]'>+</A>[href]=[Max]'>+</A>"
if(Limit) return "[href]=-[Limit]'>-</A>"+rate+"[href]=[Limit]'>+</A>"
return rate
/obj/machinery/power/smes/magical/process()
charge = 5000000
..()
#undef SMESRATE
#undef SMESRATE
+34 -19
View File
@@ -289,16 +289,25 @@
var/lastgen = 0
var/track = 0 // 0= off 1=timed 2=auto (tracker)
var/trackrate = 600 // 300-900 seconds
var/nexttime = 0 // time for a panel to rotate of 1° in manual tracking
var/nexttime = 0 // time for a panel to rotate of 1? in manual tracking
var/autostart = 0 // Automatically search for connected devices
var/obj/machinery/power/tracker/connected_tracker = null
var/list/connected_panels = list()
// Used for mapping in solar array which automatically starts itself (telecomms, for example)
/obj/machinery/power/solar_control/autostart
track = 2 // Auto tracking mode
autostart = 1 // Automatically start
/obj/machinery/power/solar_control/New()
/obj/machinery/power/solar_control/initialize()
..()
if(ticker)
initialize()
connect_to_network()
if(!powernet)
return
if(autostart)
src.search_for_connected()
if(connected_tracker && track == 2)
connected_tracker.set_angle(sun.angle)
set_panels(cdir)
/obj/machinery/power/solar_control/Destroy()
for(var/obj/machinery/power/solar/M in connected_panels)
@@ -309,11 +318,12 @@
/obj/machinery/power/solar_control/disconnect_from_network()
..()
sun.solars.Remove(src)
if(sun)
sun.solars.Remove(src)
/obj/machinery/power/solar_control/connect_to_network()
var/to_return = ..()
if(powernet) //if connected and not already in solar list...
if(powernet && sun) //if connected and not already in solar list...
sun.solars |= src //... add it
return to_return
@@ -347,12 +357,6 @@
set_panels(cdir)
updateDialog()
/obj/machinery/power/solar_control/initialize()
..()
if(!powernet) return
set_panels(cdir)
/obj/machinery/power/solar_control/update_icon()
overlays.Cut()
if(stat & NOPOWER)
@@ -366,9 +370,21 @@
if(cdir > -1)
overlays += image('icons/obj/computer.dmi', "solcon-o", FLY_LAYER, angle2dir(cdir))
/obj/machinery/power/solar_control/attack_ai(mob/user as mob)
src.add_hiddenprint(user)
ui_interact(user)
/obj/machinery/power/solar_control/attack_ghost(mob/user as mob)
ui_interact(user)
/obj/machinery/power/solar_control/attack_hand(mob/user)
if(!..())
ui_interact(user)
if(..(user))
return 1
if(stat & BROKEN)
return
ui_interact(user)
/obj/machinery/power/solar_control/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
@@ -438,9 +454,9 @@
connected_tracker.unset_control()
if(track==1 && trackrate) //manual tracking and set a rotation speed
if(nexttime <= world.time) //every time we need to increase/decrease the angle by 1°...
if(nexttime <= world.time) //every time we need to increase/decrease the angle by 1?...
targetdir = (targetdir + trackrate/abs(trackrate) + 360) % 360 //... do it
nexttime += 36000/abs(trackrate) //reset the counter for the next 1°
nexttime += 36000/abs(trackrate) //reset the counter for the next 1?
/obj/machinery/power/solar_control/Topic(href, href_list)
if(..())
@@ -514,7 +530,6 @@
broken()
src.density = 0
//
// MISC
//
+5 -1
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
@@ -20,6 +19,11 @@
var/turf/T = src.loc
if(level==1) hide(T.intact)
return
/obj/machinery/power/terminal/Destroy()
if(master)
master.disconnect_terminal()
return ..()
/obj/machinery/power/terminal/hide(var/i)
+4 -4
View File
@@ -27,7 +27,7 @@
//set the control of the tracker to a given computer if closer than SOLAR_MAX_DIST
/obj/machinery/power/tracker/proc/set_control(var/obj/machinery/power/solar_control/SC)
if(!SC || (get_dist(src, SC) > SOLAR_MAX_DIST))
if(SC && (get_dist(src, SC) > SOLAR_MAX_DIST))
return 0
control = SC
SC.connected_tracker = src
@@ -58,7 +58,7 @@
if(powernet && (powernet == control.powernet)) //update if we're still in the same powernet
control.cdir = angle
/obj/machinery/power/tracker/attackby(var/obj/item/weapon/W, var/mob/user, params)
/obj/machinery/power/tracker/attackby(var/obj/item/weapon/W, var/mob/user)
if(istype(W, /obj/item/weapon/crowbar))
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
@@ -70,7 +70,7 @@
S.give_glass()
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
user.visible_message("<span class='notice'>[user] takes the glass off the tracker.</span>")
qdel(src)
qdel(src) // qdel
return
..()
@@ -81,4 +81,4 @@
name = "tracker electronics"
icon = 'icons/obj/doors/door_assembly.dmi'
icon_state = "door_electronics"
w_class = 2.0
w_class = 2.0
-1
View File
@@ -22,7 +22,6 @@
anchored = 1
density = 1
var/obj/machinery/compressor/compressor
directwired = 1
var/turf/simulated/outturf
var/lastgen
@@ -176,7 +176,7 @@
reagents.add_reagent("methamphetamine", 5)
/obj/item/weapon/reagent_containers/pill/charcoal
name = "Chacoal pill"
name = "Charcoal pill"
desc = "Neutralizes many common toxins."
icon_state = "pill17"
New()
-14
View File
@@ -35,20 +35,6 @@
src.disable_wire = pick(w)
w -= src.disable_wire
/obj/machinery/r_n_d/proc/
shock(mob/user, prb)
if(stat & (BROKEN|NOPOWER)) // unpowered, no shock
return 0
if(!prob(prb))
return 0
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
if (electrocute_mob(user, get_area(src), src, 0.7))
return 1
else
return 0
/obj/machinery/r_n_d/attack_hand(mob/user as mob)
if (shocked)
shock(user,50)