BROADCASTER REWORK AHOY (also powernet things)

- Added: /datum/power_connection components, allows machinery to have cable connections without being /obj/machinery/power + more flexibility
- Bugfix: Broadcaster doesn't use area power anymore, requires a direct cable connection to grid.
- Bugfix: Broadcaster can be unwrenched again
- Bugfix: Broadcaster cannot be on while unanchored

NOTE: Didn't fuck around with adding cables to the broadcaster's lair on the maps.  Mappers will need to fix that.

Tested locally, eradicated some related funtimes.
This commit is contained in:
Rob Nelson
2015-08-04 17:48:18 -07:00
parent 7ad99d0bd4
commit e9715e3749
6 changed files with 454 additions and 36 deletions

View File

@@ -12,38 +12,72 @@ var/global/list/power_machines = list()
for(var/i = 1 to power_machines.len)
if(i > power_machines.len)
break
var/obj/machinery/M = power_machines[i]
if(istype(M) && !M.gcDestroyed)
if(istype(power_machines[i], /obj/machinery))
var/obj/machinery/M = power_machines[i]
if(!M.gcDestroyed)
#ifdef PROFILE_MACHINES
var/time_start = world.timeofday
#endif
if(M.check_rebuild()) //Checks to make sure the powernet doesn't need to be rebuilt, rebuilds it if it does
scheck()
if(M.process() == PROCESS_KILL)
M.inMachineList = 0
power_machines.Remove(M)
continue
if(M && M.use_power)
M.auto_use_power()
if(istype(M))
#ifdef PROFILE_MACHINES
var/time_end = world.timeofday
if(!(M.type in power_machinery_profiling))
power_machinery_profiling[M.type] = 0
power_machinery_profiling[M.type] += (time_end - time_start)
#endif
else
if(!power_machines.Remove(M))
power_machines.Cut(i,i+1)
else
if(M)
M.inMachineList = 0
if(!power_machines.Remove(M))
power_machines.Cut(i,i+1)
if(istype(power_machines[i], /datum/power_connection))
var/datum/power_connection/C = power_machines[i]
#ifdef PROFILE_MACHINES
var/time_start = world.timeofday
#endif
if(M.check_rebuild()) //Checks to make sure the powernet doesn't need to be rebuilt, rebuilds it if it does
if(C.check_rebuild()) //Checks to make sure the powernet doesn't need to be rebuilt, rebuilds it if it does
scheck()
if(M.process() == PROCESS_KILL)
M.inMachineList = 0
power_machines.Remove(M)
if(C.process() == PROCESS_KILL)
C.inMachineList = 0
power_machines.Remove(C)
continue
if(M && M.use_power)
M.auto_use_power()
if(istype(M))
//if(C && C.use_power)
// C.auto_use_power()
if(istype(C))
#ifdef PROFILE_MACHINES
var/time_end = world.timeofday
if(!(M.type in power_machinery_profiling))
power_machinery_profiling[M.type] = 0
if(!(C.type in power_machinery_profiling))
power_machinery_profiling[C.type] = 0
power_machinery_profiling[M.type] += (time_end - time_start)
power_machinery_profiling[C.type] += (time_end - time_start)
#endif
else
if(!power_machines.Remove(M))
if(!power_machines.Remove(C))
power_machines.Cut(i,i+1)
else
if(M)
M.inMachineList = 0
if(!power_machines.Remove(M))
power_machines.Cut(i,i+1)
scheck()
scheck()

View File

@@ -5,8 +5,9 @@
icon = 'icons/obj/machines/broadcast.dmi'
icon_state = "broadcaster"
light_color = LIGHT_COLOR_BLUE
use_power = 1
use_power = 0 // We use power_connection for this.
density = 1
anchored = 1 // May need map updates idfk
idle_power_usage = 50
active_power_usage = 1000
@@ -17,23 +18,38 @@
var/list/autolink = null
var/datum/wires/transmitter/wires = null
var/datum/power_connection/consumer/cable/power_connection = null
var/const/RADS_PER_TICK=150
var/const/MAX_TEMP=70 // Celsius
machine_flags = MULTITOOL_MENU | SCREWTOGGLE
machine_flags = MULTITOOL_MENU | SCREWTOGGLE | WRENCHMOVE | FIXED2WORK
/obj/machinery/media/transmitter/broadcast/New()
..()
wires = new(src)
power_connection=new(src,LIGHT)
power_connection.idle_usage=idle_power_usage
power_connection.active_usage=active_power_usage
/obj/machinery/media/transmitter/broadcast/Destroy()
if(wires)
wires.Destroy()
wires = null
if(power_connection)
power_connection.Destroy()
power_connection = null
..()
/obj/machinery/media/transmitter/broadcast/proc/cable_power_change(var/list/args)
if(power_connection.powered())
stat &= ~NOPOWER
else
stat |= NOPOWER
update_icon()
/obj/machinery/media/transmitter/broadcast/initialize()
testing("[type]/initialize() called!")
//testing("[type]/initialize() called!")
if(autolink && autolink.len)
for(var/obj/machinery/media/source in orange(20, src))
if(source.id_tag in autolink)
@@ -42,8 +58,21 @@
hook_media_sources()
if(on)
update_on()
power_connection.power_changed.Add(src,"cable_power_change")
power_connection.connect()
update_icon()
/obj/machinery/media/transmitter/broadcast/wrenchAnchor(mob/user)
if(..())
if(anchored) // We are now anchored
power_connection.connect() // Connect to the powernet
else // We are now NOT anchored
power_connection.disconnect() // Ditch powernet.
on=0
update_on()
return 1
return
/obj/machinery/media/transmitter/broadcast/proc/hook_media_sources()
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/obj/machinery/media/transmitter/broadcast/proc/hook_media_sources() called tick#: [world.time]")
if(!sources.len)
@@ -122,20 +151,11 @@
return screen
/obj/machinery/light_switch/power_change()
if(powered(LIGHT))
stat &= ~NOPOWER
else
stat |= NOPOWER
updateicon()
/obj/machinery/light_switch/emp_act(severity)
/obj/machinery/media/transmitter/broadcast/emp_act(severity)
if(stat & (BROKEN|NOPOWER))
..(severity)
return
power_change()
cable_power_change()
..(severity)
/obj/machinery/media/transmitter/broadcast/update_icon()
@@ -169,6 +189,11 @@
return
if("power" in href_list)
if(!power_connection.powernet)
power_connection.connect()
if(!power_connection.powered())
usr << "<span class='warning'>This machine needs to be hooked up to a powered cable.</span>"
return
on = !on
update_on()
return
@@ -194,13 +219,14 @@
/obj/machinery/media/transmitter/broadcast/process()
if(stat & (NOPOWER|BROKEN) || wires.IsIndexCut(TRANS_POWER))
return
if(on)
if(on && anchored)
if(integrity<=0 || count_rad_wires()==0) //Shut down if too damaged OR if no rad wires
on=0
update_on()
// Radiation
for(var/mob/living/carbon/M in view(src,3))
// TODO: Standardize radiation damage. Currently does not check for armor. (handle in apply_effect?)
var/rads = RADS_PER_TICK * sqrt( 1 / (get_dist(M, src) + 1) )
if(istype(M,/mob/living/carbon/human))
M.apply_effect((rads*count_rad_wires()),IRRADIATE)

View File

@@ -0,0 +1,319 @@
/**
* A desperate attempt at component-izing power transmission shit.
*
* The idea being that objects that aren't /obj/machinery/power can hook into power systems.
*/
/datum/power_connection
var/obj/parent=null
//For powernet rebuilding
var/channel = EQUIP // EQUIP, ENVIRON or LIGHT.
var/build_status = 0 //1 means it needs rebuilding during the next tick or on usage
var/connected = 0
var/datum/powernet/powernet = null
var/machine_flags = 0 // Emulate machinery flags.
var/inMachineList = 0
/datum/power_connection/New(var/obj/parent)
src.parent = parent
power_machines |= src
/datum/power_connection/Destroy()
disconnect()
power_machines -= parent
..()
/datum/power_connection/proc/excess(var/netexcess)
return
/datum/power_connection/proc/process()
return // auto_use_power() :^)
// common helper procs for all power machines
/datum/power_connection/proc/add_avail(var/amount)
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/power_connection/proc/add_avail() called tick#: [world.time]")
if(get_powernet())
powernet.newavail += amount
/datum/power_connection/proc/add_load(var/amount)
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/power_connection/proc/add_load() called tick#: [world.time]")
if(get_powernet())
powernet.load += amount
/datum/power_connection/proc/get_surplus()
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/power_connection/proc/surplus() called tick#: [world.time]")
if(get_powernet())
return powernet.avail-powernet.load
else
return 0
/datum/power_connection/proc/get_avail()
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/power_connection/proc/avail() called tick#: [world.time]")
if(get_powernet())
return powernet.avail
else
return 0
/datum/power_connection/proc/get_powernet()
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/power_connection/proc/get_powernet() called tick#: [world.time]")
check_rebuild()
return powernet
/datum/power_connection/proc/check_rebuild()
if(!build_status)
return 0
for(var/obj/structure/cable/C in parent.loc)
if(C.check_rebuild())
return 1
/datum/power_connection/proc/getPowernetNodes()
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/power_connection/proc/getPowernetNodes() called tick#: [world.time]")
if(!get_powernet())
return list()
return powernet.nodes
// returns true if the area has power on given channel (or doesn't require power)
// defaults to power_channel
/datum/power_connection/proc/powered(chan = channel)
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/power_connection/proc/powered() called tick#: [world.time]")
if(!parent || !parent.loc)
return 0
// If you're using a consumer, you need power.
//if(!use_power)
// return 1
if(isnull(parent.areaMaster) || !parent.areaMaster)
return 0 // if not, then not powered.
if((machine_flags & FIXED2WORK) && !parent.anchored)
return 0
return parent.areaMaster.powered(chan) // return power status of the area.
// increment the power usage stats for an area
// defaults to power_channel
/datum/power_connection/proc/use_power(amount, chan = channel)
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/power_connection/proc/use_power() called tick#: [world.time]")
if(isnull(parent.areaMaster) || !parent.areaMaster)
return 0 // if not, then not powered.
if(!powered(chan)) //no point in trying if we don't have power
return 0
parent.areaMaster.use_power(amount, chan)
// called whenever the power settings of the containing area change
// by default, check equipment channel & set flag
// can override if needed
/datum/power_connection/proc/power_change()
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/power_connection/proc/power_change() called tick#: [world.time]")
//parent.power_change()
return
// connect the machine to a powernet if a node cable is present on the turf
/datum/power_connection/proc/connect()
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/power_connection/proc/connect() called tick#: [world.time]")
var/turf/T = get_turf(parent)
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.get_powernet())
return 0
C.powernet.add_component(src)
connected=1
return 1
// remove and disconnect the machine from its current powernet
/datum/power_connection/proc/disconnect()
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/power_connection/proc/disconnect() called tick#: [world.time]")
connected=0
if(!get_powernet())
build_status = 0
return 0
powernet.remove_component(src)
return 1
// returns all the cables WITHOUT a powernet in neighbors turfs,
// pointing towards the turf the machine is located at
/datum/power_connection/proc/get_connections()
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/power_connection/proc/get_connections() called tick#: [world.time]")
. = list()
var/cdir
var/turf/T
for(var/card in cardinal)
T = get_step(parent.loc, card)
cdir = get_dir(T, parent.loc)
for(var/obj/structure/cable/C in T)
if(C.get_powernet())
continue
if(C.d1 == cdir || C.d2 == cdir)
. += C
// returns all the cables in neighbors turfs,
// pointing towards the turf the machine is located at
/datum/power_connection/proc/get_marked_connections()
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/power_connection/proc/get_marked_connections() called tick#: [world.time]")
. = list()
var/cdir
var/turf/T
for(var/card in cardinal)
T = get_step(parent.loc, card)
cdir = get_dir(T, parent.loc)
for(var/obj/structure/cable/C in T)
if(C.d1 == cdir || C.d2 == cdir)
. += C
// returns all the NODES (O-X) cables WITHOUT a powernet in the turf the machine is located at
/datum/power_connection/proc/get_indirect_connections()
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/power_connection/proc/get_indirect_connections() called tick#: [world.time]")
. = list()
for(var/obj/structure/cable/C in parent.loc)
if(C.get_powernet())
continue
if(C.d1 == 0) // the cable is a node cable
. += C
////////////////////////////////////////////////
// Misc.
///////////////////////////////////////////////
/datum/power_connection/proc/addStaticPower(value, powerchannel)
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/power_connection/proc/addStaticPower() called tick#: [world.time]")
if(!parent.areaMaster)
return
parent.areaMaster.addStaticPower(value, powerchannel)
/datum/power_connection/proc/removeStaticPower(value, powerchannel)
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/power_connection/proc/removeStaticPower() called tick#: [world.time]")
addStaticPower(-value, powerchannel)
///////////////////////////
// POWER CONSUMERS
///////////////////////////
/datum/power_connection/consumer
var/enabled=0
var/use=0 // 1=idle, 2=active
var/idle_usage=1 // watts
var/active_usage=2
var/event/power_changed = null
/datum/power_connection/consumer/New(var/loc,var/obj/parent)
..(loc,parent)
power_changed = new ("owner"=src)
/datum/power_connection/consumer/power_change()
INVOKE_EVENT(power_changed,list("consumer"=src))
/datum/power_connection/consumer/process()
if(use)
auto_use_power()
/datum/power_connection/consumer/proc/auto_use_power()
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/power_connection/consumer/proc/auto_use_power() called tick#: [world.time]")
if(!powered(channel))
return 0
switch (use)
if (1)
use_power(idle_usage, channel)
if (2)
use_power(active_usage, channel)
return 1
/datum/power_connection/consumer/proc/set_enabled(var/value)
enabled=value
power_change()
//////////////////////
/// TERMINAL RECEIVER
//////////////////////
/datum/power_connection/consumer/terminal
var/obj/machinery/power/terminal/terminal=null
/datum/power_connection/consumer/terminal/use_power(var/watts, var/_channel_NOT_USED)
add_load(watts)
/datum/power_connection/consumer/terminal/connect()
..()
for(var/d in cardinal)
var/turf/T = get_step(parent, d)
for(var/obj/machinery/power/terminal/term in T)
if(term && term.dir == turn(d, 180))
terminal = term
break
if(terminal)
break
if(terminal)
terminal.master = parent
//parent.update_icon()
/datum/power_connection/consumer/terminal/Destroy()
if (terminal)
terminal.master = null
terminal = null
..()
////////////////////////////////
/// DIRECT CONNECTION RECEIVER
////////////////////////////////
/datum/power_connection/consumer/cable
var/obj/structure/cable/cable=null
/datum/power_connection/consumer/cable/use_power(var/watts, var/_channel_NOT_USED)
add_load(watts)
// connect the machine to a powernet if a node cable is present on the turf
/datum/power_connection/consumer/cable/connect()
// OVERRIDES!
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/power_connection/proc/connect() called tick#: [world.time]")
var/turf/T = get_turf(parent)
cable = T.get_cable_node() // check if we have a node cable on the machine turf, the first found is picked
if(!cable || !cable.get_powernet())
return 0
cable.powernet.add_component(src)
connected=1
return 1
// returns true if the area has power on given channel (or doesn't require power)
// defaults to power_channel
/datum/power_connection/consumer/cable/powered(chan = channel)
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/power_connection/proc/powered() called tick#: [world.time]")
if(!parent || !parent.loc)
return 0
// If you're using a consumer, you need power.
//if(!use_power)
// return 1
if(isnull(powernet) || !powernet || !cable)
return 0 // if not, then not powered.
if((machine_flags & FIXED2WORK) && !parent.anchored)
return 0
return 1 // We have a powernet and a cable, so we're okay.

View File

@@ -2,6 +2,7 @@
/datum/powernet
var/list/obj/structure/cable/cables = list() // all cables & junctions
var/list/obj/machinery/power/nodes = list() // all connected machines
var/list/datum/power_connection/components = list() // all connected components
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
@@ -50,17 +51,22 @@ Powernet procs :
C.powernet = null
for(var/obj/machinery/power/P in nodes)
P.powernet = null
// Power components
for(var/datum/power_connection/C in components)
C.powernet = null
cables = null
nodes = null
components = null
/datum/powernet/resetVariables()
..("cables","nodes")
cables = list()
nodes = list()
components = list()
/datum/powernet/proc/is_empty()
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/powernet/proc/is_empty() called tick#: [world.time]")
return !cables.len && !nodes.len
return !cables.len && !nodes.len && !components.len
// helper proc for removing cables from the current powernet
// warning : this proc doesn't check if the cable exists, but don't worry a runtime should tell you if it doesn't
@@ -80,6 +86,15 @@ Powernet procs :
if(is_empty())
returnToDPool(src)
// helper proc for removing a power machine from the current powernet
// warning : this proc doesn't check if the machine exists, but don't worry a runtime should tell you if it doesn't
/datum/powernet/proc/remove_component(var/datum/power_connection/C)
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/powernet/proc/remove_component() called tick#: [world.time]")
components -= C
C.powernet = null
if(is_empty())
returnToDPool(src)
// add a cable to the current powernet
/datum/powernet/proc/add_cable(obj/structure/cable/C)
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/powernet/proc/add_cable() called tick#: [world.time]")
@@ -93,7 +108,7 @@ Powernet procs :
cables += C
// add a power machine to the current powernet
/datum/powernet/proc/add_machine(obj/machinery/power/M)
/datum/powernet/proc/add_machine(var/obj/machinery/power/M)
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/powernet/proc/add_machine() called tick#: [world.time]")
if(M.powernet) // if M already has a powernet...
if(M.powernet == src)
@@ -104,6 +119,17 @@ Powernet procs :
M.powernet = src
nodes += M
/datum/powernet/proc/add_component(var/datum/power_connection/C)
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/powernet/proc/add_component() called tick#: [world.time]")
if(C.powernet) // if M already has a powernet...
if(C.powernet == src)
return
else
C.disconnect() // ..remove it
C.build_status = 0 //Resetting build status because it has been added to a powernet
C.powernet = src
components += C
// handles the power changes in the powernet
// called every ticks by the powernet controller
// all powernets will have been rebuilt by the time this is called
@@ -118,6 +144,9 @@ Powernet procs :
for(var/obj/machinery/power/battery_port/BP in nodes) //Since portable batteries aren't in our nodes, we pass ourselves to restore them via their connectors
if(BP.connected)
BP.connected.restore()
if(netexcess > 100 && components && components.len) // Same deal as above, but with components.
for(var/datum/power_connection/C in components)
C.excess(netexcess)
// updates the viewed load (as seen on power computers)
viewload = 0.8 * viewload + 0.2 * load
@@ -144,6 +173,8 @@ Powernet procs :
C.oldnewavail = newavail
for(var/obj/machinery/power/P in nodes)
P.build_status = 1
for(var/datum/power_connection/C in components)
C.build_status = 1
returnToDPool(src)
//Hopefully this will never ever have to be used
@@ -166,6 +197,8 @@ var/global/powernets_broke = 0
C.build_status = 0
for(var/obj/machinery/power/P in NewPN.nodes)
P.build_status = 0
for(var/datum/power_connection/C in NewPN.components)
C.build_status = 0
return 1
return 0