From c81c70bd863f5d72c98166676e25d41b94d08436 Mon Sep 17 00:00:00 2001 From: "elly1989@rocketmail.com" Date: Wed, 5 Sep 2012 16:14:24 +0000 Subject: [PATCH] Replaced var/netnum for cables and powered machines with a direct reference to their powernet. The bug which was causing cutting and merging powernets to fail was due to my attempts to fix the powernets slowly becoming filled with null entries. Removing those null entries messed up the indexes and essentially jumbled up the powernets. :( sorry Fixed the failsafe misreporting how long the MC has been dead. Lighting initialization no longer 'interrupts' the master_controller setup(). Added updated powernet debugging tools. They're in my WIP folder. They are sexy c: It draws the powernet onto the map so you can see what's going on during debugging. Added tachyon-doppler arrays. They're gonna be something for scientists to measure their bombs with rather than praying for the figures. Nothing spectacular. Commented out switches, they aren't used and I've been fixing/testing powernets all day. Sorry. If you need them back just PM me and I'll fix them. Known issues: the merging procs behave silly at intersections. I really tried to fix it but I think I'll make more progress just working on some powernet improvements. git-svn-id: http://tgstation13.googlecode.com/svn/trunk@4623 316c924e-a436-60f5-8080-3fe189b3f50e --- code/WorkInProgress/carn/debug_powernets.dm | 96 +---- code/controllers/master_controller.dm | 2 +- code/defines/obj.dm | 2 +- code/game/cellautomata.dm | 11 +- code/game/machinery/doppler_array.dm | 53 +++ code/game/machinery/shieldgen.dm | 12 +- .../mecha/equipment/tools/medical_tools.dm | 14 +- code/game/objects/explosion.dm | 9 +- code/global.dm | 2 +- code/modules/power/apc.dm | 2 +- code/modules/power/cable.dm | 174 +++----- code/modules/power/power.dm | 379 ++++++++---------- code/modules/power/switch.dm | 5 +- 13 files changed, 324 insertions(+), 437 deletions(-) create mode 100644 code/game/machinery/doppler_array.dm diff --git a/code/WorkInProgress/carn/debug_powernets.dm b/code/WorkInProgress/carn/debug_powernets.dm index 600b0315507..04d2fc929ec 100644 --- a/code/WorkInProgress/carn/debug_powernets.dm +++ b/code/WorkInProgress/carn/debug_powernets.dm @@ -1,86 +1,14 @@ -//Inefficient as hell so don't copypasta this anywhere! It's only here as a tool for debugging -//prints a map of the powernetworks on z-level 1 -/client/verb/print_powernets() - set name = "print powernets" +/* +client/verb/powernets_debug() + if(!holder) return + var/ref_holder = "\ref[holder]" + for(var/i=1,i<=powernets.len,i++) + src << "[copytext("\ref[powernets[i]]",8,12)]" - var/file = file("powernets_map.html") - var/list/grid[255][255] - - var/list/checklist = list() - for(var/obj/structure/cable/C in world) - if(C.z != 1) continue - if(C.x < 1 || C.x > 255) continue - if(C.y < 1 || C.y > 255) continue - grid[C.x][C.y] = C.netnum - checklist |= C.netnum - - sleep(1) - file << "" - for(var/netnum in checklist) - file << "[netnum]
" - - for(var/j=255, j>=1, j--) - var/line = "
" - for(var/i=1, i<=255, i++) - switch(grid[i][j]) - if(null) line += " " - if(0 to 9) line += "[grid[i][j]]" - if(10) line += "a" - if(11) line += "b" - if(12) line += "c" - if(13) line += "d" - if(14) line += "e" - if(15) line += "f" - if(16) line += "g" - if(17) line += "h" - if(18) line += "i" - if(19) line += "j" - if(20) line += "k" - if(21) line += "l" - if(22) line += "m" - if(23) line += "n" - if(24) line += "o" - if(25) line += "p" - if(26) line += "q" - if(27) line += "r" - if(28) line += "s" - if(29) line += "t" - if(30) line += "u" - if(31) line += "v" - if(32) line += "w" - if(33) line += "x" - if(34) line += "y" - if(35) line += "z" - if(36) line += "A" - if(37) line += "B" - if(38) line += "C" - if(39) line += "D" - if(40) line += "E" - if(41) line += "F" - if(42) line += "G" - if(43) line += "H" - if(44) line += "I" - if(45) line += "J" - if(46) line += "K" - if(47) line += "L" - if(48) line += "M" - if(49) line += "N" - if(50) line += "O" - if(51) line += "P" - if(52) line += "Q" - if(53) line += "R" - if(54) line += "S" - if(55) line += "T" - if(56) line += "U" - if(57) line += "V" - if(58) line += "W" - if(59) line += "X" - if(60) line += "Y" - if(61) line += "Z" - else line += "#" - - file << line - file << "
" - src << "printed to powernets_map.html" - src << browse(file) \ No newline at end of file +client/verb/powernet_overlays() + for(var/obj/structure/cable/C in cable_list) + C.maptext = "[copytext("\ref[C.powernet]",8,12)]" + for(var/obj/machinery/power/M in machines) + M.maptext = "[copytext("\ref[M.powernet]",8,12)]" +*/ diff --git a/code/controllers/master_controller.dm b/code/controllers/master_controller.dm index 248c760c4df..51d6873154f 100644 --- a/code/controllers/master_controller.dm +++ b/code/controllers/master_controller.dm @@ -273,10 +273,10 @@ datum/controller/game_controller/proc/Recover() //Mostly a placeholder for now. if(0 to 3) defcon++ if(4) - defcon = 5 for(var/client/C in admin_list) if(C.holder) C << "Warning. The Master Controller has not fired in the last [defcon*ticks_per_spin] ticks. Automatic restart in [ticks_per_spin] ticks." + defcon = 5 if(5) for(var/client/C in admin_list) if(C.holder) diff --git a/code/defines/obj.dm b/code/defines/obj.dm index 0f09c88fc9a..7207a27247d 100644 --- a/code/defines/obj.dm +++ b/code/defines/obj.dm @@ -95,7 +95,7 @@ /obj/structure/cable level = 1 anchored =1 - var/netnum = 0 + var/datum/powernet/powernet name = "power cable" desc = "A flexible superconducting cable for heavy-duty power transfer" icon = 'icons/obj/power_cond_red.dmi' diff --git a/code/game/cellautomata.dm b/code/game/cellautomata.dm index a2262008c14..820d5adf398 100644 --- a/code/game/cellautomata.dm +++ b/code/game/cellautomata.dm @@ -83,15 +83,9 @@ makepowernets() sun = new /datum/sun() - vote = new /datum/vote() - -// coffinhandler = new /datum/coffinhandler() - radio_controller = new /datum/controller/radio() - //main_hud1 = new /obj/hud() data_core = new /obj/effect/datacore() - paiController = new /datum/paiController() ..() @@ -113,8 +107,9 @@ src.update_status() master_controller = new /datum/controller/game_controller() - spawn(-1) master_controller.setup() - lighting_controller.Initialize() + spawn(-1) + master_controller.setup() + lighting_controller.Initialize() return //Crispy fullban diff --git a/code/game/machinery/doppler_array.dm b/code/game/machinery/doppler_array.dm new file mode 100644 index 00000000000..658375b9eea --- /dev/null +++ b/code/game/machinery/doppler_array.dm @@ -0,0 +1,53 @@ +var/list/doppler_arrays = list() + +/obj/machinery/doppler_array + name = "tachyon-doppler array" + desc = "A highly precise directional sensor array which measures the release of quants from decaying tachyons. The doppler shifting of the mirror-image formed by these quants can reveal the size, location and temporal affects of energetic disturbances within a large radius ahead of the array." + + +/obj/machinery/doppler_array/New() + doppler_arrays += src + +/obj/machinery/doppler_array/Del() + doppler_arrays -= src + +/obj/machinery/doppler_array/process() + return PROCESS_KILL + +/obj/machinery/doppler_array/proc/sense_explosion(var/x0,var/y0,var/z0,var/devastation_range,var/heavy_impact_range,var/light_impact_range,var/took) + if(stat & NOPOWER) return + if(z != z0) return + + var/dx = abs(x0-x) + var/dy = abs(y0-y) + var/distance + var/direct + + if(dx > dy) + distance = dx + if(x0 > x) direct = EAST + else direct = WEST + else + distance = dy + if(y0 > y) direct = NORTH + else direct = SOUTH + + if(distance > 100) return + if(!(direct & dir)) return + + var/message = "Explosive disturbance detected - Epicenter at: grid ([x0],[y0]). Epicenter radius: [devastation_range]. Outer radius: [heavy_impact_range]. Shockwave radius: [light_impact_range]. Temporal displacement of tachyons: [took]seconds." + + for(var/mob/O in hearers(src, null)) + O.show_message("[src] states coldly, \"[message]\"",2) + + +/obj/machinery/doppler_array/power_change() + if(stat & BROKEN) + icon_state = "[initial(icon_state)]-broken" + else + if( powered() ) + icon_state = initial(icon_state) + stat &= ~NOPOWER + else + icon_state = "[initial(icon_state)]-off" + stat |= NOPOWER \ No newline at end of file diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm index faef446796b..0615b73be65 100644 --- a/code/game/machinery/shieldgen.dm +++ b/code/game/machinery/shieldgen.dm @@ -385,19 +385,15 @@ power = 0 return 0 var/turf/T = src.loc - var/obj/structure/cable/C = T.get_cable_node() - var/net - if (C) - net = C.netnum // find the powernet of the connected cable - if(!net) - power = 0 - return 0 - var/datum/powernet/PN = powernets[net] // find the powernet. Magic code, voodoo code. + var/obj/structure/cable/C = T.get_cable_node() + var/datum/powernet/PN + if(C) PN = C.powernet // find the powernet of the connected cable if(!PN) power = 0 return 0 + var/surplus = max(PN.avail-PN.load, 0) var/shieldload = min(rand(50,200), surplus) if(shieldload==0 && !storedpower) // no cable or no power, and no power stored diff --git a/code/game/mecha/equipment/tools/medical_tools.dm b/code/game/mecha/equipment/tools/medical_tools.dm index 1a292b6706f..c68ca2d5af9 100644 --- a/code/game/mecha/equipment/tools/medical_tools.dm +++ b/code/game/mecha/equipment/tools/medical_tools.dm @@ -365,23 +365,21 @@ NC.d1 = 0 NC.d2 = fdirn NC.updateicon() - var/netnum + var/datum/powernet/PN if(last_piece && last_piece.d2 != chassis.dir) last_piece.d1 = min(last_piece.d2, chassis.dir) last_piece.d2 = max(last_piece.d2, chassis.dir) last_piece.updateicon() - netnum = last_piece.netnum - if(netnum) - NC.netnum = netnum - PN = powernets[netnum] - else + PN = last_piece.powernet + + if(!PN) PN = new() - PN.number = powernets.len + 1 powernets += PN - NC.netnum = PN.number + NC.powernet = PN PN.cables += NC NC.mergeConnectedNetworks(NC.d2) + //NC.mergeConnectedNetworksOnTurf() last_piece = NC return 1 diff --git a/code/game/objects/explosion.dm b/code/game/objects/explosion.dm index ce3c7c4940b..c5197265f91 100644 --- a/code/game/objects/explosion.dm +++ b/code/game/objects/explosion.dm @@ -51,8 +51,15 @@ proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impa var/atom/movable/AM = atom_movable AM.ex_act(dist) + var/took = (world.timeofday-start)/10 //You need to press the DebugGame verb to see these now....they were getting annoying and we've collected a fair bit of data. Just -test- changes to explosion code using this please so we can compare - if(Debug2) world.log << "## DEBUG: Explosion([x0],[y0],[z0])(d[devastation_range],h[heavy_impact_range],l[light_impact_range]): Took [(world.timeofday-start)/10] seconds." + if(Debug2) world.log << "## DEBUG: Explosion([x0],[y0],[z0])(d[devastation_range],h[heavy_impact_range],l[light_impact_range]): Took [took] seconds." + + //Machines which report explosions. + for(var/i,i<=doppler_arrays.len,i++) + var/obj/machinery/doppler_array/Array = doppler_arrays[i] + if(Array) + Array.sense_explosion(x0,y0,z0,devastation_range,heavy_impact_range,light_impact_range,took) sleep(8) diff --git a/code/global.dm b/code/global.dm index 3ea951884fa..dd4d340ae9b 100644 --- a/code/global.dm +++ b/code/global.dm @@ -120,7 +120,7 @@ var/list/OOClog = list() var/list/adminlog = list() -var/list/powernets = null +var/list/powernets = list() var/Debug = 0 // global debug switch var/Debug2 = 0 diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 63410f53301..267e64480fc 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -46,7 +46,7 @@ var/main_status = 0 var/wiresexposed = 0 var/apcwires = 15 - netnum = -1 // set so that APCs aren't found as powernet nodes + powernet = 0 // set so that APCs aren't found as powernet nodes //Hackish, Horrible, was like this before I changed it :( var/malfhack = 0 //New var for my changes to AI malf. --NeoFite var/mob/living/silicon/ai/malfai = null //See above --NeoFite // luminosity = 1 diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 970827f7737..55973a5e91b 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -35,21 +35,13 @@ NC.mergeConnectedNetworks(NC.d2) NC.mergeConnectedNetworksOnTurf() - if(netnum == 0 && NC.netnum == 0) - var/datum/powernet/PN = new() - - PN.number = powernets.len + 1 - powernets += PN - NC.netnum = PN.number - netnum = PN.number - PN.cables += NC - PN.nodes += src - powernet = PN - else if(netnum == 0) - netnum = NC.netnum - var/datum/powernet/PN = powernets[netnum] - powernet = PN - PN.nodes += src + if(powernet==null) + if(NC.powernet == null) + NC.powernet = new() + powernets += NC.powernet + NC.powernet.cables += NC + powernet = NC.powernet + NC.powernet.nodes += src NC.mergeConnectedNetworksOnTurf() coil.use(1) @@ -82,15 +74,11 @@ cable_list += src -/obj/structure/cable/Del() // called when a cable is deleted - - if(!defer_powernet_rebuild) // set if network will be rebuilt manually - if(netnum && powernets && (powernets.len >= netnum) && (netnum >= 1) ) // make sure cable & powernet data is valid - var/datum/powernet/PN = powernets[netnum] - PN.cut_cable(src) // updated the powernets +/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 -// else -// if(Debug) diary << "Defered cable deletion at [x],[y]: #[netnum]" ..() // then go ahead and delete the cable /obj/structure/cable/hide(var/i) @@ -107,11 +95,8 @@ // returns the powernet this cable belongs to -/obj/structure/cable/proc/get_powernet() - var/datum/powernet/PN // find the powernet - if(netnum && powernets && powernets.len >= netnum) - PN = powernets[netnum] - return PN +/obj/structure/cable/proc/get_powernet() //TODO: remove this as it is obsolete + return powernet /obj/structure/cable/attack_hand(mob/user) if(ishuman(user)) @@ -127,9 +112,9 @@ if(istype(W, /obj/item/weapon/wirecutters)) - if(power_switch) - user << "\red This piece of cable is tied to a power switch. Flip the switch to remove it." - return +// if(power_switch) +// user << "\red This piece of cable is tied to a power switch. Flip the switch to remove it." +// return if (shock(user, 50)) return @@ -174,7 +159,7 @@ /obj/structure/cable/proc/shock(mob/user, prb, var/siemens_coeff = 1.0) if(!prob(prb)) return 0 - if (electrocute_mob(user, powernets[src.netnum], src, siemens_coeff)) + if (electrocute_mob(user, powernet, src, siemens_coeff)) var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(5, 1, src) s.start() @@ -334,11 +319,9 @@ C.add_fingerprint(user) C.updateicon() - var/datum/powernet/PN = new() - PN.number = powernets.len + 1 - powernets += PN - C.netnum = PN.number - PN.cables += C + C.powernet = new() + powernets += C.powernet + C.powernet.cables += C C.mergeConnectedNetworks(C.d2) C.mergeConnectedNetworksOnTurf() @@ -399,11 +382,11 @@ NC.add_fingerprint() NC.updateicon() - NC.netnum = C.netnum - var/datum/powernet/PN = powernets[C.netnum] - PN.cables += NC - NC.mergeConnectedNetworks(NC.d2) - NC.mergeConnectedNetworksOnTurf() + if(C.powernet) + NC.powernet = C.powernet + NC.powernet.cables += NC + NC.mergeConnectedNetworks(NC.d2) + NC.mergeConnectedNetworksOnTurf() use(1) if (NC.shock(user, 50)) if (prob(50)) //fail @@ -453,7 +436,7 @@ /obj/structure/cable/proc/mergeConnectedNetworks(var/direction) var/turf/TB - if((d1 == direction || d2 == direction) != 1) + if(!(d1 == direction || d2 == direction)) return TB = get_step(src, direction) @@ -469,79 +452,54 @@ if(TC.d1 == fdir || TC.d2 == fdir) - if(!netnum) - var/datum/powernet/PN = powernets[TC.netnum] - netnum = TC.netnum - PN = powernets[netnum] - PN.cables += src - continue + if(!TC.powernet) + TC.powernet = new() + powernets += TC.powernet + TC.powernet.cables += TC + + if(powernet) + merge_powernets(powernet,TC.powernet) + else + powernet = TC.powernet + powernet.cables += src + - if(TC.netnum != netnum) - var/datum/powernet/PN = powernets[netnum] - var/datum/powernet/TPN = powernets[TC.netnum] - PN.merge_powernets(TPN) /obj/structure/cable/proc/mergeConnectedNetworksOnTurf() + if(!powernet) + powernet = new() + powernets += powernet + powernet.cables += src + for(var/AM in loc) + if(istype(AM,/obj/structure/cable)) + var/obj/structure/cable/C = AM + if(C.powernet == powernet) continue + if(C.powernet) + merge_powernets(powernet, C.powernet) + else + C.powernet = powernet + powernet.cables += C - for(var/obj/structure/cable/C in loc) + else if(istype(AM,/obj/machinery/power/apc)) + var/obj/machinery/power/apc/N = AM + if(!N.terminal) continue + if(N.terminal.powernet) + merge_powernets(powernet, N.terminal.powernet) + else + N.terminal.powernet = powernet + powernet.nodes += N.terminal + else if(istype(AM,/obj/machinery/power)) + var/obj/machinery/power/M = AM + if(M.powernet == powernet) continue + if(M.powernet) + merge_powernets(powernet, M.powernet) + else + M.powernet = powernet + powernet.nodes += M - if(!C) - continue - - if(C == src) - continue - if(netnum == 0) - var/datum/powernet/PN = powernets[C.netnum] - netnum = C.netnum - PN.cables += src - continue - - var/datum/powernet/PN = powernets[netnum] - var/datum/powernet/TPN = powernets[C.netnum] - - PN.merge_powernets(TPN) - - for(var/obj/machinery/power/M in loc) - - if(!M) - continue - - if(!M.netnum) - var/datum/powernet/PN = powernets[netnum] - PN.nodes += M - M.netnum = netnum - M.powernet = powernets[M.netnum] - - if(M.netnum < 0) - continue - - var/datum/powernet/PN = powernets[netnum] - var/datum/powernet/TPN = powernets[M.netnum] - - PN.merge_powernets(TPN) - - for(var/obj/machinery/power/apc/N in loc) - if(!N) continue - - var/obj/machinery/power/M - M = N.terminal - if(!M) continue - - if(!M.netnum) - if(!netnum)continue - var/datum/powernet/PN = powernets[netnum] - PN.nodes += M - M.netnum = netnum - M.powernet = powernets[M.netnum] - continue - - var/datum/powernet/PN = powernets[netnum] - var/datum/powernet/TPN = powernets[M.netnum] - - PN.merge_powernets(TPN) obj/structure/cable/proc/cableColor(var/colorC) var/color_n = "red" diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm index 4d0ebdc2154..0c7b7744cc2 100644 --- a/code/modules/power/power.dm +++ b/code/modules/power/power.dm @@ -3,7 +3,6 @@ icon = 'icons/obj/power.dmi' anchored = 1.0 var/datum/powernet/powernet = null - var/netnum = 0 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 @@ -72,265 +71,213 @@ // rebuild all power networks from scratch /proc/makepowernets() - - var/netcount = 0 - powernets = list() + for(var/datum/powernet/PN in powernets) + del(PN) + powernets.Cut() for(var/obj/structure/cable/PC in cable_list) - PC.netnum = 0 - for(var/obj/machinery/power/M in machines) - if(M.netnum >=0) - M.netnum = 0 - - - for(var/obj/structure/cable/PC in cable_list) - if(!PC.netnum) - PC.netnum = ++netcount - - if(Debug) world.log << "Starting mpn at [PC.x],[PC.y] ([PC.d1]/[PC.d2]) #[netcount]" - powernet_nextlink(PC, PC.netnum) - - if(Debug) world.log << "[netcount] powernets found" - - for(var/L = 1 to netcount) - var/datum/powernet/PN = new() - //PN.tag = "powernet #[L]" - powernets += PN - PN.number = L + 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) - var/datum/powernet/PN = powernets[C.netnum] - PN.cables += C + if(!C.powernet) continue + C.powernet.cables += C for(var/obj/machinery/power/M in machines) - if(M.netnum<=0) // APCs have netnum=-1 so they don't count as network nodes directly - continue - - M.powernet = powernets[M.netnum] + if(!M.powernet) continue // APCs have powernet=0 so they don't count as network nodes directly M.powernet.nodes += M // 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 netnum==0 - +// if unmarked==1, only return those with no powernet /proc/power_list(var/turf/T, var/source, var/d, var/unmarked=0) - var/list/result = list() - var/fdir = (!d)? 0 : turn(d, 180) // the opposite direction to d (or 0 if d==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 - for(var/obj/machinery/power/P in T) - if(P.netnum < 0) // exclude APCs - continue + if(istype(AM,/obj/machinery/power)) + var/obj/machinery/power/P = AM + if(P.powernet == 0) continue // exclude APCs which have powernet=0 - if(P.directwired) // true if this machine covers the whole turf (so can be joined to a cable on neighbour turf) - if(!unmarked || !P.netnum) - result += P - else if(d == 0) // otherwise, need a 0-X cable on same turf to connect - if(!unmarked || !P.netnum) - result += P + 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 - for(var/obj/structure/cable/C in T) - if(C.d1 == fdir || C.d2 == fdir) - if(!unmarked || !C.netnum) - result += C - - result -= source - - return result + if(!unmarked || !C.powernet) + if(C.d1 == fdir || C.d2 == fdir) + . += C + return . /obj/structure/cable/proc/get_connections() + . = list() // this will be a list of all connected power objects + var/turf/T = loc - var/list/res = list() // this will be a list of all connected power objects - - var/turf/T - if(!d1) - T = src.loc // if d1=0, same turf as src - else - T = get_step(src, d1) - - res += power_list(T, src , d1, 1) + 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) - res += power_list(T, src, d2, 1) - - return res + return . /obj/machinery/power/proc/get_connections() + if(!directwired) return get_indirect_connections() - if(!directwired) - return get_indirect_connections() - - var/list/res = list() + . = list() var/cdir - for(var/turf/T in orange(1, src)) - - cdir = get_dir(T, src) + 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.netnum) - continue - + if(C.powernet) continue if(C.d1 == cdir || C.d2 == cdir) - res += C - - return res + . += C + return . /obj/machinery/power/proc/get_indirect_connections() - - var/list/res = list() - - for(var/obj/structure/cable/C in src.loc) - - if(C.netnum) - continue - + . = list() + for(var/obj/structure/cable/C in loc) + if(C.powernet) continue if(C.d1 == 0) - res += C - - return res + . += C + return . -/proc/powernet_nextlink(var/obj/O, var/num) - +/proc/powernet_nextlink(var/obj/O, var/datum/powernet/PN) var/list/P - //world.log << "start: [O] at [O.x].[O.y]" - - while(1) - - if( istype(O, /obj/structure/cable) ) + if( istype(O,/obj/structure/cable) ) var/obj/structure/cable/C = O - - C.netnum = num + C.powernet = PN P = C.get_connections() - else if( istype(O, /obj/machinery/power) ) - + else if( istype(O,/obj/machinery/power) ) var/obj/machinery/power/M = O - - M.netnum = num + M.powernet = PN P = M.get_connections() - if(P.len == 0) - //world.log << "end1" - return + if(P.len == 0) return O = P[1] - for(var/L = 2 to P.len) - - powernet_nextlink(P[L], num) - - //world.log << "next: [O] at [O.x].[O.y]" + powernet_nextlink(P[L], PN) // cut a powernet at this cable object - /datum/powernet/proc/cut_cable(var/obj/structure/cable/C) - var/turf/T1 = C.loc - if(C.d1) - T1 = get_step(C, C.d1) + if(!T1) return + + var/turf/T2 + if(C.d2) T2 = get_step(T1, C.d2) + if(C.d1) T1 = get_step(T1, C.d1) - var/turf/T2 = get_step(C, C.d2) 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(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, just remove cut cable from the list - cables -= C - if(Debug) world.log << "Was end of cable" + 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 - // zero the netnum of all cables & nodes in this powernet - - for(var/obj/structure/cable/OC in cables) - OC.netnum = 0 - for(var/obj/machinery/power/OM in nodes) - OM.netnum = 0 - + //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.netnum = -1 C.loc = null - cables -= C - - - powernet_nextlink(P1[1], number) // propagate network from 1st side of cable, using current netnum + 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/obj/O in P2) + for(var/O in P2) if( istype(O, /obj/machinery/power) ) - var/obj/machinery/power/OM = O - if(OM.netnum != number) + var/obj/machinery/power/Machine = O + if(Machine.powernet != src) notlooped = 1 break else if( istype(O, /obj/structure/cable) ) - var/obj/structure/cable/OC = O - if(OC.netnum != number) + 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() - //PN.tag = "powernet #[L]" powernets += PN - PN.number = powernets.len - if(Debug) world.log << "Was not looped: spliting PN#[number] ([cables.len];[nodes.len])" +// if(Debug) world.log << "Was not looped: spliting PN#[number] ([cables.len];[nodes.len])" - for(var/obj/structure/cable/OC in cables) + 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++ - if(!OC.netnum) // non-connected cables will have netnum==0, since they weren't reached by propagation + 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 + continue + i++ - OC.netnum = PN.number - cables -= OC - PN.cables += OC // remove from old network & add to new one - - for(var/obj/machinery/power/OM in nodes) - if(!OM.netnum) - OM.netnum = PN.number - OM.powernet = PN - nodes -= OM - PN.nodes += OM // same for power machines - - 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 - - return +// 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 @@ -381,52 +328,57 @@ return min(rand(10,20),rand(10,20))*/ if (1000000 to INFINITY) return min(rand(50,160),rand(50,160)) - if (200000 to 1000000-1) + if (200000 to 1000000) return min(rand(25,80),rand(25,80)) - if (100000 to 200000-1)//Ave powernet + if (100000 to 200000)//Ave powernet return min(rand(20,60),rand(20,60)) - if (50000 to 100000-1) + if (50000 to 100000) return min(rand(15,40),rand(15,40)) - if (1000 to 50000-1) + if (1000 to 50000) return min(rand(10,20),rand(10,20)) else return 0 -/datum/powernet/proc/merge_powernets(var/datum/powernet/P) -// The powernet that calls this proc will consume the other powernet - Rockdtben +//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(src == P) - 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 - if(nodes.len >= P.nodes.len) - nodes += P.nodes - else - P.nodes += nodes - nodes = P.nodes - for(var/obj/machinery/power/M in nodes) - M.netnum = number - M.powernet = powernets[M.netnum] // Thanks to Derp__ + 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 + 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 + + del(net2) + return net1 - if(cables.len >= P.cables.len) - cables += P.cables - else - P.cables += cables - cables = P.cables - for(var/obj/structure/cable/C in cables) - C.netnum = number - del P /obj/machinery/power/proc/connect_to_network() var/turf/T = src.loc var/obj/structure/cable/C = T.get_cable_node() - if (!C || !C.netnum) - return - makepowernets() //TODO: find fast way + if(!C || !C.powernet) return +// makepowernets() //TODO: find fast way //EWWWW what are you doing!? + powernet = C.powernet + powernet.nodes += src /obj/machinery/power/proc/disconnect_from_network() - //TODO: dunno how to do that - return + if(!powernet) return + powernet.nodes -= src + powernet = null /turf/proc/get_cable_node() if(!istype(src, /turf/simulated/floor)) @@ -449,31 +401,29 @@ //source is an object caused electrocuting (airlock, grille, etc) //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 + if(istype(M.loc,/obj/mecha)) return 0 //feckin mechs are dumb if(istype(M,/mob/living/carbon/human)) var/mob/living/carbon/human/H = M if(H.gloves) var/obj/item/clothing/gloves/G = H.gloves - var/siem_coef = G.siemens_coefficient - if(siem_coef == 0) //to avoid spamming with insulated glvoes on - return 0 + if(G.siemens_coefficient == 0) return 0 //to avoid spamming with insulated glvoes on + var/area/source_area - if (istype(power_source,/area)) + if(istype(power_source,/area)) source_area = power_source power_source = source_area.get_apc() - if (istype(power_source,/obj/structure/cable)) - var/obj/structure/cable/tmp = power_source - power_source = powernets[tmp.netnum] + if(istype(power_source,/obj/structure/cable)) + var/obj/structure/cable/Cable = power_source + power_source = Cable.powernet var/datum/powernet/PN var/obj/item/weapon/cell/cell - if (istype(power_source,/datum/powernet)) + if(istype(power_source,/datum/powernet)) PN = power_source - else if (istype(power_source,/obj/item/weapon/cell)) + else if(istype(power_source,/obj/item/weapon/cell)) cell = power_source - else if (istype(power_source,/obj/machinery/power/apc)) + else if(istype(power_source,/obj/machinery/power/apc)) var/obj/machinery/power/apc/apc = power_source cell = apc.cell if (apc.terminal) @@ -508,4 +458,5 @@ PN.newload+=drained_power else if (istype(power_source, /obj/item/weapon/cell)) cell.use(drained_energy) - return drained_energy \ No newline at end of file + return drained_energy + diff --git a/code/modules/power/switch.dm b/code/modules/power/switch.dm index 30b16f2f2e6..efdce94f440 100644 --- a/code/modules/power/switch.dm +++ b/code/modules/power/switch.dm @@ -2,7 +2,7 @@ //After it knows this it creates the number of cables from the center to each of the cables attempting to conenct. These cables cannot be removed //with wirecutters. When the switch is turned off it removes all the cables on the tile it's on. //The switch uses a 5s delay to prevent powernet change spamming. - +/* /obj/structure/powerswitch name = "power switch" desc = "A switch that controls power." @@ -81,4 +81,5 @@ else icon_state = icon_state_off for(var/obj/structure/cable/C in src.loc) - del(C) \ No newline at end of file + del(C) +*/ \ No newline at end of file