mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 18:53:06 +00:00
Merge branch 'dev' of https://github.com/Baystation12/Baystation12 into dev
This commit is contained in:
@@ -164,6 +164,11 @@
|
||||
#include "code\datums\spells\trigger.dm"
|
||||
#include "code\datums\spells\turf_teleport.dm"
|
||||
#include "code\datums\spells\wizard.dm"
|
||||
#include "code\datums\wires\apc.dm"
|
||||
#include "code\datums\wires\smartfridge.dm"
|
||||
#include "code\datums\wires\suit_storage_unit.dm"
|
||||
#include "code\datums\wires\vending.dm"
|
||||
#include "code\datums\wires\wires.dm"
|
||||
#include "code\defines\obj.dm"
|
||||
#include "code\defines\obj\weapon.dm"
|
||||
#include "code\defines\procs\admin.dm"
|
||||
@@ -433,9 +438,9 @@
|
||||
#include "code\game\mecha\equipment\tools\medical_tools.dm"
|
||||
#include "code\game\mecha\equipment\tools\tools.dm"
|
||||
#include "code\game\mecha\equipment\weapons\weapons.dm"
|
||||
#include "code\game\mecha\hoverpod\hoverpod.dm"
|
||||
#include "code\game\mecha\medical\medical.dm"
|
||||
#include "code\game\mecha\medical\odysseus.dm"
|
||||
#include "code\game\mecha\working\hoverpod.dm"
|
||||
#include "code\game\mecha\working\ripley.dm"
|
||||
#include "code\game\mecha\working\working.dm"
|
||||
#include "code\game\objects\empulse.dm"
|
||||
@@ -1137,7 +1142,6 @@
|
||||
#include "code\modules\power\breaker_box.dm"
|
||||
#include "code\modules\power\cable.dm"
|
||||
#include "code\modules\power\cable_heavyduty.dm"
|
||||
#include "code\modules\power\cable_logic.dm"
|
||||
#include "code\modules\power\cell.dm"
|
||||
#include "code\modules\power\engine.dm"
|
||||
#include "code\modules\power\fractal_reactor.dm"
|
||||
|
||||
@@ -61,7 +61,6 @@ max volume of phoron storeable by the field = the total volume of a number of ti
|
||||
idle_power_usage = 50
|
||||
active_power_usage = 500 //multiplied by field strength
|
||||
var/cached_power_avail = 0
|
||||
directwired = 1
|
||||
anchored = 0
|
||||
|
||||
var/state = 0
|
||||
@@ -120,7 +119,6 @@ max volume of phoron storeable by the field = the total volume of a number of ti
|
||||
state = 2
|
||||
user << "You weld the [src] to the floor."
|
||||
connect_to_network()
|
||||
src.directwired = 1
|
||||
else
|
||||
user << "\red You need more welding fuel to complete this task."
|
||||
if(2)
|
||||
@@ -134,7 +132,6 @@ max volume of phoron storeable by the field = the total volume of a number of ti
|
||||
state = 1
|
||||
user << "You cut the [src] free from the floor."
|
||||
disconnect_from_network()
|
||||
src.directwired = 0
|
||||
else
|
||||
user << "\red You need more welding fuel to complete this task."
|
||||
return
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
use_power = 1
|
||||
idle_power_usage = 10
|
||||
active_power_usage = 500
|
||||
directwired = 0
|
||||
var/remote_access_enabled = 1
|
||||
var/cached_power_avail = 0
|
||||
var/emergency_insert_ready = 0
|
||||
|
||||
@@ -400,6 +400,37 @@ proc/listclearnulls(list/list)
|
||||
//world.log << " output: [out.len]"
|
||||
return reverselist(out)
|
||||
|
||||
/proc/dd_sortedObjectList(var/list/L, var/cache=list())
|
||||
if(L.len < 2)
|
||||
return L
|
||||
var/middle = L.len / 2 + 1 // Copy is first,second-1
|
||||
return dd_mergeObjectList(dd_sortedObjectList(L.Copy(0,middle), cache), dd_sortedObjectList(L.Copy(middle), cache), cache) //second parameter null = to end of list
|
||||
|
||||
/proc/dd_mergeObjectList(var/list/L, var/list/R, var/list/cache)
|
||||
var/Li=1
|
||||
var/Ri=1
|
||||
var/list/result = new()
|
||||
while(Li <= L.len && Ri <= R.len)
|
||||
var/LLi = L[Li]
|
||||
var/RRi = R[Ri]
|
||||
var/LLiV = cache[LLi]
|
||||
var/RRiV = cache[RRi]
|
||||
if(!LLiV)
|
||||
LLiV = LLi:dd_SortValue()
|
||||
cache[LLi] = LLiV
|
||||
if(!RRiV)
|
||||
RRiV = RRi:dd_SortValue()
|
||||
cache[RRi] = RRiV
|
||||
if(LLiV < RRiV)
|
||||
result += L[Li++]
|
||||
else
|
||||
result += R[Ri++]
|
||||
|
||||
if(Li <= L.len)
|
||||
return (result + L.Copy(Li, 0))
|
||||
return (result + R.Copy(Ri, 0))
|
||||
|
||||
/*
|
||||
proc/dd_sortedObjectList(list/incoming)
|
||||
/*
|
||||
Use binary search to order by dd_SortValue().
|
||||
@@ -456,7 +487,7 @@ proc/dd_sortedObjectList(list/incoming)
|
||||
sorted_list += current_sort_object
|
||||
sorted_list += list_bottom
|
||||
return sorted_list
|
||||
|
||||
*/
|
||||
|
||||
proc/dd_sortedtextlist(list/incoming, case_sensitive = 0)
|
||||
// Returns a new list with the text values sorted.
|
||||
|
||||
@@ -351,16 +351,10 @@ datum/controller/game_controller/proc/process_pipenets()
|
||||
continue
|
||||
pipe_networks.Cut(i,i+1)
|
||||
|
||||
datum/controller/game_controller/proc/process_powernets()
|
||||
/datum/controller/game_controller/proc/process_powernets()
|
||||
last_thing_processed = /datum/powernet
|
||||
var/i = 1
|
||||
while(i<=powernets.len)
|
||||
var/datum/powernet/Powernet = powernets[i]
|
||||
if(Powernet)
|
||||
Powernet.process()
|
||||
i++
|
||||
continue
|
||||
powernets.Cut(i,i+1)
|
||||
for(var/datum/powernet/Powernet in powernets)
|
||||
Powernet.reset()
|
||||
|
||||
datum/controller/game_controller/proc/process_nano()
|
||||
var/i = 1
|
||||
|
||||
@@ -450,6 +450,15 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
containertype = /obj/structure/closet/crate
|
||||
containername = "Wooden planks crate"
|
||||
group = "Engineering"
|
||||
|
||||
/datum/supply_packs/plastic50
|
||||
name = "50 plastic sheets"
|
||||
contains = list(/obj/item/stack/sheet/mineral/plastic)
|
||||
amount = 50
|
||||
cost = 10
|
||||
containertype = /obj/structure/closet/crate
|
||||
containername = "Plastic sheets crate"
|
||||
group = "Engineering"
|
||||
|
||||
/datum/supply_packs/smescoil
|
||||
name = "Superconducting Magnetic Coil"
|
||||
|
||||
78
code/datums/wires/apc.dm
Normal file
78
code/datums/wires/apc.dm
Normal file
@@ -0,0 +1,78 @@
|
||||
/datum/wires/apc
|
||||
holder_type = /obj/machinery/power/apc
|
||||
wire_count = 4
|
||||
|
||||
var/const/APC_WIRE_IDSCAN = 1
|
||||
var/const/APC_WIRE_MAIN_POWER1 = 2
|
||||
var/const/APC_WIRE_MAIN_POWER2 = 4
|
||||
var/const/APC_WIRE_AI_CONTROL = 8
|
||||
|
||||
/datum/wires/apc/GetInteractWindow()
|
||||
var/obj/machinery/power/apc/A = holder
|
||||
. += ..()
|
||||
. += text("<br>\n[(A.locked ? "The APC is locked." : "The APC is unlocked.")]<br>\n[(A.shorted ? "The APCs power has been shorted." : "The APC is working properly!")]<br>\n[(A.aidisabled ? "The 'AI control allowed' light is off." : "The 'AI control allowed' light is on.")]")
|
||||
|
||||
|
||||
/datum/wires/apc/CanUse(var/mob/living/L)
|
||||
var/obj/machinery/power/apc/A = holder
|
||||
if(A.wiresexposed)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/wires/apc/UpdatePulsed(var/index)
|
||||
|
||||
var/obj/machinery/power/apc/A = holder
|
||||
|
||||
switch(index)
|
||||
|
||||
if(APC_WIRE_IDSCAN)
|
||||
A.locked = 0
|
||||
|
||||
spawn(300)
|
||||
if(A)
|
||||
A.locked = 1
|
||||
A.updateDialog()
|
||||
|
||||
if (APC_WIRE_MAIN_POWER1, APC_WIRE_MAIN_POWER2)
|
||||
if(A.shorted == 0)
|
||||
A.shorted = 1
|
||||
|
||||
spawn(1200)
|
||||
if(A && !IsIndexCut(APC_WIRE_MAIN_POWER1) && !IsIndexCut(APC_WIRE_MAIN_POWER2))
|
||||
A.shorted = 0
|
||||
A.updateDialog()
|
||||
|
||||
if (APC_WIRE_AI_CONTROL)
|
||||
if (A.aidisabled == 0)
|
||||
A.aidisabled = 1
|
||||
|
||||
spawn(10)
|
||||
if(A && !IsIndexCut(APC_WIRE_AI_CONTROL))
|
||||
A.aidisabled = 0
|
||||
A.updateDialog()
|
||||
|
||||
A.updateDialog()
|
||||
|
||||
/datum/wires/apc/UpdateCut(var/index, var/mended)
|
||||
var/obj/machinery/power/apc/A = holder
|
||||
|
||||
switch(index)
|
||||
if(APC_WIRE_MAIN_POWER1, APC_WIRE_MAIN_POWER2)
|
||||
|
||||
if(!mended)
|
||||
A.shock(usr, 50)
|
||||
A.shorted = 1
|
||||
|
||||
else if(!IsIndexCut(APC_WIRE_MAIN_POWER1) && !IsIndexCut(APC_WIRE_MAIN_POWER2))
|
||||
A.shorted = 0
|
||||
A.shock(usr, 50)
|
||||
|
||||
if(APC_WIRE_AI_CONTROL)
|
||||
|
||||
if(!mended)
|
||||
if (A.aidisabled == 0)
|
||||
A.aidisabled = 1
|
||||
else
|
||||
if (A.aidisabled == 1)
|
||||
A.aidisabled = 0
|
||||
A.updateDialog()
|
||||
52
code/datums/wires/smartfridge.dm
Normal file
52
code/datums/wires/smartfridge.dm
Normal file
@@ -0,0 +1,52 @@
|
||||
/datum/wires/smartfridge
|
||||
holder_type = /obj/machinery/smartfridge
|
||||
wire_count = 3
|
||||
|
||||
var/const/SMARTFRIDGE_WIRE_ELECTRIFY = 1
|
||||
var/const/SMARTFRIDGE_WIRE_THROW = 2
|
||||
var/const/SMARTFRIDGE_WIRE_IDSCAN = 4
|
||||
|
||||
/datum/wires/smartfridge/CanUse(var/mob/living/L)
|
||||
var/obj/machinery/smartfridge/S = holder
|
||||
if(!istype(L, /mob/living/silicon))
|
||||
if(S.seconds_electrified)
|
||||
if(S.shock(L, 100))
|
||||
return 0
|
||||
if(S.panel_open)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/wires/smartfridge/Interact(var/mob/living/user)
|
||||
if(CanUse(user))
|
||||
var/obj/machinery/smartfridge/S = holder
|
||||
S.attack_hand(user)
|
||||
|
||||
/datum/wires/smartfridge/GetInteractWindow()
|
||||
var/obj/machinery/smartfridge/S = holder
|
||||
. += ..()
|
||||
. += "<BR>The orange light is [S.seconds_electrified ? "off" : "on"].<BR>"
|
||||
. += "The red light is [S.shoot_inventory ? "off" : "blinking"].<BR>"
|
||||
. += "A [S.scan_id ? "purple" : "yellow"] light is on.<BR>"
|
||||
|
||||
/datum/wires/smartfridge/UpdatePulsed(var/index)
|
||||
var/obj/machinery/smartfridge/S = holder
|
||||
switch(index)
|
||||
if(SMARTFRIDGE_WIRE_THROW)
|
||||
S.shoot_inventory = !S.shoot_inventory
|
||||
if(SMARTFRIDGE_WIRE_ELECTRIFY)
|
||||
S.seconds_electrified = 30
|
||||
if(SMARTFRIDGE_WIRE_IDSCAN)
|
||||
S.scan_id = !S.scan_id
|
||||
|
||||
/datum/wires/smartfridge/UpdateCut(var/index, var/mended)
|
||||
var/obj/machinery/smartfridge/S = holder
|
||||
switch(index)
|
||||
if(SMARTFRIDGE_WIRE_THROW)
|
||||
S.shoot_inventory = !mended
|
||||
if(SMARTFRIDGE_WIRE_ELECTRIFY)
|
||||
if(mended)
|
||||
S.seconds_electrified = 0
|
||||
else
|
||||
S.seconds_electrified = -1
|
||||
if(SMARTFRIDGE_WIRE_IDSCAN)
|
||||
S.scan_id = 1
|
||||
52
code/datums/wires/suit_storage_unit.dm
Normal file
52
code/datums/wires/suit_storage_unit.dm
Normal file
@@ -0,0 +1,52 @@
|
||||
/datum/wires/suit_storage_unit
|
||||
holder_type = /obj/machinery/suit_cycler
|
||||
wire_count = 3
|
||||
|
||||
var/const/SUIT_STORAGE_WIRE_ELECTRIFY = 1
|
||||
var/const/SUIT_STORAGE_WIRE_SAFETY = 2
|
||||
var/const/SUIT_STORAGE_WIRE_LOCKED = 4
|
||||
|
||||
/datum/wires/suit_storage_unit/CanUse(var/mob/living/L)
|
||||
var/obj/machinery/suit_cycler/S = holder
|
||||
if(!istype(L, /mob/living/silicon))
|
||||
if(S.electrified)
|
||||
if(S.shock(L, 100))
|
||||
return 0
|
||||
if(S.panel_open)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/wires/suit_storage_unit/Interact(var/mob/living/user)
|
||||
if(CanUse(user))
|
||||
var/obj/machinery/suit_cycler/S = holder
|
||||
S.attack_hand(user)
|
||||
|
||||
/datum/wires/suit_storage_unit/GetInteractWindow()
|
||||
var/obj/machinery/suit_cycler/S = holder
|
||||
. += ..()
|
||||
. += "<BR>The orange light is [S.electrified ? "off" : "on"].<BR>"
|
||||
. += "The red light is [S.safeties ? "off" : "blinking"].<BR>"
|
||||
. += "The yellow light is [S.locked ? "on" : "off"].<BR>"
|
||||
|
||||
/datum/wires/suit_storage_unit/UpdatePulsed(var/index)
|
||||
var/obj/machinery/suit_cycler/S = holder
|
||||
switch(index)
|
||||
if(SUIT_STORAGE_WIRE_SAFETY)
|
||||
S.safeties = !S.safeties
|
||||
if(SUIT_STORAGE_WIRE_ELECTRIFY)
|
||||
S.electrified = 30
|
||||
if(SUIT_STORAGE_WIRE_LOCKED)
|
||||
S.locked = !S.locked
|
||||
|
||||
/datum/wires/suit_storage_unit/UpdateCut(var/index, var/mended)
|
||||
var/obj/machinery/suit_cycler/S = holder
|
||||
switch(index)
|
||||
if(SUIT_STORAGE_WIRE_SAFETY)
|
||||
S.safeties = mended
|
||||
if(SUIT_STORAGE_WIRE_LOCKED)
|
||||
S.locked = mended
|
||||
if(SUIT_STORAGE_WIRE_ELECTRIFY)
|
||||
if(mended)
|
||||
S.electrified = 0
|
||||
else
|
||||
S.electrified = -1
|
||||
58
code/datums/wires/vending.dm
Normal file
58
code/datums/wires/vending.dm
Normal file
@@ -0,0 +1,58 @@
|
||||
/datum/wires/vending
|
||||
holder_type = /obj/machinery/vending
|
||||
wire_count = 4
|
||||
|
||||
var/const/VENDING_WIRE_THROW = 1
|
||||
var/const/VENDING_WIRE_CONTRABAND = 2
|
||||
var/const/VENDING_WIRE_ELECTRIFY = 4
|
||||
var/const/VENDING_WIRE_IDSCAN = 8
|
||||
|
||||
/datum/wires/vending/CanUse(var/mob/living/L)
|
||||
var/obj/machinery/vending/V = holder
|
||||
if(!istype(L, /mob/living/silicon))
|
||||
if(V.seconds_electrified)
|
||||
if(V.shock(L, 100))
|
||||
return 0
|
||||
if(V.panel_open)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/wires/vending/Interact(var/mob/living/user)
|
||||
if(CanUse(user))
|
||||
var/obj/machinery/vending/V = holder
|
||||
V.attack_hand(user)
|
||||
|
||||
/datum/wires/vending/GetInteractWindow()
|
||||
var/obj/machinery/vending/V = holder
|
||||
. += ..()
|
||||
. += "<BR>The orange light is [V.seconds_electrified ? "off" : "on"].<BR>"
|
||||
. += "The red light is [V.shoot_inventory ? "off" : "blinking"].<BR>"
|
||||
. += "The green light is [V.extended_inventory ? "on" : "off"].<BR>"
|
||||
. += "The [V.scan_id ? "purple" : "yellow"] light is on.<BR>"
|
||||
|
||||
/datum/wires/vending/UpdatePulsed(var/index)
|
||||
var/obj/machinery/vending/V = holder
|
||||
switch(index)
|
||||
if(VENDING_WIRE_THROW)
|
||||
V.shoot_inventory = !V.shoot_inventory
|
||||
if(VENDING_WIRE_CONTRABAND)
|
||||
V.extended_inventory = !V.extended_inventory
|
||||
if(VENDING_WIRE_ELECTRIFY)
|
||||
V.seconds_electrified = 30
|
||||
if(VENDING_WIRE_IDSCAN)
|
||||
V.scan_id = !V.scan_id
|
||||
|
||||
/datum/wires/vending/UpdateCut(var/index, var/mended)
|
||||
var/obj/machinery/vending/V = holder
|
||||
switch(index)
|
||||
if(VENDING_WIRE_THROW)
|
||||
V.shoot_inventory = !mended
|
||||
if(VENDING_WIRE_CONTRABAND)
|
||||
V.extended_inventory = 0
|
||||
if(VENDING_WIRE_ELECTRIFY)
|
||||
if(mended)
|
||||
V.seconds_electrified = 0
|
||||
else
|
||||
V.seconds_electrified = -1
|
||||
if(VENDING_WIRE_IDSCAN)
|
||||
V.scan_id = 1
|
||||
293
code/datums/wires/wires.dm
Normal file
293
code/datums/wires/wires.dm
Normal file
@@ -0,0 +1,293 @@
|
||||
// Wire datums. Created by Giacomand.
|
||||
// Was created to replace a horrible case of copy and pasted code with no care for maintability.
|
||||
// Goodbye Door wires, Cyborg wires, Vending Machine wires, Autolathe wires
|
||||
// Protolathe wires, APC wires and Camera wires!
|
||||
|
||||
#define MAX_FLAG 65535
|
||||
|
||||
var/list/same_wires = list()
|
||||
// 12 colours, if you're adding more than 12 wires then add more colours here
|
||||
var/list/wireColours = list("red", "blue", "green", "black", "orange", "brown", "gold", "gray", "cyan", "navy", "purple", "pink")
|
||||
|
||||
/datum/wires
|
||||
|
||||
var/random = 0 // Will the wires be different for every single instance.
|
||||
var/atom/holder = null // The holder
|
||||
var/holder_type = null // The holder type; used to make sure that the holder is the correct type.
|
||||
var/wire_count = 0 // Max is 16
|
||||
var/wires_status = 0 // BITFLAG OF WIRES
|
||||
|
||||
var/list/wires = list()
|
||||
var/list/signallers = list()
|
||||
|
||||
var/table_options = " align='center'"
|
||||
var/row_options1 = " width='80px'"
|
||||
var/row_options2 = " width='260px'"
|
||||
var/window_x = 370
|
||||
var/window_y = 470
|
||||
|
||||
/datum/wires/New(var/atom/holder)
|
||||
..()
|
||||
src.holder = holder
|
||||
if(!istype(holder, holder_type))
|
||||
CRASH("Our holder is null/the wrong type!")
|
||||
return
|
||||
|
||||
// Generate new wires
|
||||
if(random)
|
||||
GenerateWires()
|
||||
// Get the same wires
|
||||
else
|
||||
// We don't have any wires to copy yet, generate some and then copy it.
|
||||
if(!same_wires[holder_type])
|
||||
GenerateWires()
|
||||
same_wires[holder_type] = src.wires.Copy()
|
||||
else
|
||||
var/list/wires = same_wires[holder_type]
|
||||
src.wires = wires // Reference the wires list.
|
||||
|
||||
/datum/wires/proc/GenerateWires()
|
||||
var/list/colours_to_pick = wireColours.Copy() // Get a copy, not a reference.
|
||||
var/list/indexes_to_pick = list()
|
||||
//Generate our indexes
|
||||
for(var/i = 1; i < MAX_FLAG && i < (1 << wire_count); i += i)
|
||||
indexes_to_pick += i
|
||||
colours_to_pick.len = wire_count // Downsize it to our specifications.
|
||||
|
||||
while(colours_to_pick.len && indexes_to_pick.len)
|
||||
// Pick and remove a colour
|
||||
var/colour = pick_n_take(colours_to_pick)
|
||||
|
||||
// Pick and remove an index
|
||||
var/index = pick_n_take(indexes_to_pick)
|
||||
|
||||
src.wires[colour] = index
|
||||
//wires = shuffle(wires)
|
||||
|
||||
|
||||
/datum/wires/proc/Interact(var/mob/living/user)
|
||||
|
||||
var/html = null
|
||||
if(holder && CanUse(user))
|
||||
html = GetInteractWindow()
|
||||
if(html)
|
||||
user.set_machine(holder)
|
||||
else
|
||||
user.unset_machine()
|
||||
// No content means no window.
|
||||
user << browse(null, "window=wires")
|
||||
return
|
||||
|
||||
var/datum/browser/popup = new(user, "wires", holder.name, window_x, window_y)
|
||||
popup.set_content(html)
|
||||
popup.set_title_image(user.browse_rsc_icon(holder.icon, holder.icon_state))
|
||||
popup.open()
|
||||
|
||||
/datum/wires/proc/GetInteractWindow()
|
||||
var/html = "<div class='block'>"
|
||||
html += "<h3>Exposed Wires</h3>"
|
||||
html += "<table[table_options]>"
|
||||
|
||||
for(var/colour in wires)
|
||||
html += "<tr>"
|
||||
html += "<td[row_options1]><font color='[colour]'>[capitalize(colour)]</font></td>"
|
||||
html += "<td[row_options2]>"
|
||||
html += "<A href='?src=\ref[src];action=1;cut=[colour]'>[IsColourCut(colour) ? "Mend" : "Cut"]</A>"
|
||||
html += " <A href='?src=\ref[src];action=1;pulse=[colour]'>Pulse</A>"
|
||||
html += " <A href='?src=\ref[src];action=1;attach=[colour]'>[IsAttached(colour) ? "Detach" : "Attach"] Signaller</A></td></tr>"
|
||||
html += "</table>"
|
||||
html += "</div>"
|
||||
|
||||
return html
|
||||
|
||||
/datum/wires/Topic(href, href_list)
|
||||
..()
|
||||
if(in_range(holder, usr) && isliving(usr))
|
||||
|
||||
var/mob/living/L = usr
|
||||
if(CanUse(L) && href_list["action"])
|
||||
var/obj/item/I = L.get_active_hand()
|
||||
holder.add_hiddenprint(L)
|
||||
if(href_list["cut"]) // Toggles the cut/mend status
|
||||
if(istype(I, /obj/item/weapon/wirecutters))
|
||||
var/colour = href_list["cut"]
|
||||
CutWireColour(colour)
|
||||
else
|
||||
L << "<span class='error'>You need wirecutters!</span>"
|
||||
|
||||
else if(href_list["pulse"])
|
||||
if(istype(I, /obj/item/device/multitool))
|
||||
var/colour = href_list["pulse"]
|
||||
PulseColour(colour)
|
||||
else
|
||||
L << "<span class='error'>You need a multitool!</span>"
|
||||
|
||||
else if(href_list["attach"])
|
||||
var/colour = href_list["attach"]
|
||||
// Detach
|
||||
if(IsAttached(colour))
|
||||
var/obj/item/O = Detach(colour)
|
||||
if(O)
|
||||
L.put_in_hands(O)
|
||||
|
||||
// Attach
|
||||
else
|
||||
if(istype(I, /obj/item/device/assembly/signaler))
|
||||
L.drop_item()
|
||||
Attach(colour, I)
|
||||
else
|
||||
L << "<span class='error'>You need a remote signaller!</span>"
|
||||
|
||||
|
||||
|
||||
|
||||
// Update Window
|
||||
Interact(usr)
|
||||
|
||||
if(href_list["close"])
|
||||
usr << browse(null, "window=wires")
|
||||
usr.unset_machine(holder)
|
||||
|
||||
//
|
||||
// Overridable Procs
|
||||
//
|
||||
|
||||
// Called when wires cut/mended.
|
||||
/datum/wires/proc/UpdateCut(var/index, var/mended)
|
||||
return
|
||||
|
||||
// Called when wire pulsed. Add code here.
|
||||
/datum/wires/proc/UpdatePulsed(var/index)
|
||||
return
|
||||
|
||||
/datum/wires/proc/CanUse(var/mob/living/L)
|
||||
return 1
|
||||
|
||||
// Example of use:
|
||||
/*
|
||||
|
||||
var/const/BOLTED= 1
|
||||
var/const/SHOCKED = 2
|
||||
var/const/SAFETY = 4
|
||||
var/const/POWER = 8
|
||||
|
||||
/datum/wires/door/UpdateCut(var/index, var/mended)
|
||||
var/obj/machinery/door/airlock/A = holder
|
||||
switch(index)
|
||||
if(BOLTED)
|
||||
if(!mended)
|
||||
A.bolt()
|
||||
if(SHOCKED)
|
||||
A.shock()
|
||||
if(SAFETY )
|
||||
A.safety()
|
||||
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// Helper Procs
|
||||
//
|
||||
|
||||
/datum/wires/proc/PulseColour(var/colour)
|
||||
PulseIndex(GetIndex(colour))
|
||||
|
||||
/datum/wires/proc/PulseIndex(var/index)
|
||||
if(IsIndexCut(index))
|
||||
return
|
||||
UpdatePulsed(index)
|
||||
|
||||
/datum/wires/proc/GetIndex(var/colour)
|
||||
if(wires[colour])
|
||||
var/index = wires[colour]
|
||||
return index
|
||||
else
|
||||
CRASH("[colour] is not a key in wires.")
|
||||
|
||||
//
|
||||
// Is Index/Colour Cut procs
|
||||
//
|
||||
|
||||
/datum/wires/proc/IsColourCut(var/colour)
|
||||
var/index = GetIndex(colour)
|
||||
return IsIndexCut(index)
|
||||
|
||||
/datum/wires/proc/IsIndexCut(var/index)
|
||||
return (index & wires_status)
|
||||
|
||||
//
|
||||
// Signaller Procs
|
||||
//
|
||||
|
||||
/datum/wires/proc/IsAttached(var/colour)
|
||||
if(signallers[colour])
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/wires/proc/GetAttached(var/colour)
|
||||
if(signallers[colour])
|
||||
return signallers[colour]
|
||||
return null
|
||||
|
||||
/datum/wires/proc/Attach(var/colour, var/obj/item/device/assembly/signaler/S)
|
||||
if(colour && S)
|
||||
if(!IsAttached(colour))
|
||||
signallers[colour] = S
|
||||
S.loc = holder
|
||||
S.connected = src
|
||||
return S
|
||||
|
||||
/datum/wires/proc/Detach(var/colour)
|
||||
if(colour)
|
||||
var/obj/item/device/assembly/signaler/S = GetAttached(colour)
|
||||
if(S)
|
||||
signallers -= colour
|
||||
S.connected = null
|
||||
S.loc = holder.loc
|
||||
return S
|
||||
|
||||
|
||||
/datum/wires/proc/Pulse(var/obj/item/device/assembly/signaler/S)
|
||||
|
||||
for(var/colour in signallers)
|
||||
if(S == signallers[colour])
|
||||
PulseColour(colour)
|
||||
break
|
||||
|
||||
|
||||
//
|
||||
// Cut Wire Colour/Index procs
|
||||
//
|
||||
|
||||
/datum/wires/proc/CutWireColour(var/colour)
|
||||
var/index = GetIndex(colour)
|
||||
CutWireIndex(index)
|
||||
|
||||
/datum/wires/proc/CutWireIndex(var/index)
|
||||
if(IsIndexCut(index))
|
||||
wires_status &= ~index
|
||||
UpdateCut(index, 1)
|
||||
else
|
||||
wires_status |= index
|
||||
UpdateCut(index, 0)
|
||||
|
||||
/datum/wires/proc/RandomCut()
|
||||
var/r = rand(1, wires.len)
|
||||
CutWireIndex(r)
|
||||
|
||||
/datum/wires/proc/CutAll()
|
||||
for(var/i = 1; i < MAX_FLAG && i < (1 << wire_count); i += i)
|
||||
CutWireIndex(i)
|
||||
|
||||
/datum/wires/proc/IsAllCut()
|
||||
if(wires_status == (1 << wire_count) - 1)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
//
|
||||
//Shuffle and Mend
|
||||
//
|
||||
|
||||
/datum/wires/proc/Shuffle()
|
||||
wires_status = 0
|
||||
GenerateWires()
|
||||
@@ -884,18 +884,10 @@ var/list/ghostteleportlocs = list()
|
||||
name = "\improper Dormitories"
|
||||
icon_state = "Sleep"
|
||||
|
||||
/area/crew_quarters/sleep/engi
|
||||
name = "\improper Engineering Dormitories"
|
||||
icon_state = "Sleep"
|
||||
|
||||
/area/crew_quarters/sleep/engi_wash
|
||||
name = "\improper Engineering Washroom"
|
||||
icon_state = "toilet"
|
||||
|
||||
/area/crew_quarters/sleep/sec
|
||||
name = "\improper Security Dormitories"
|
||||
icon_state = "Sleep"
|
||||
|
||||
/area/crew_quarters/sleep/bedrooms
|
||||
name = "\improper Dormitory Bedroom"
|
||||
icon_state = "Sleep"
|
||||
@@ -1080,6 +1072,10 @@ var/list/ghostteleportlocs = list()
|
||||
name = "\improper Engineering Foyer"
|
||||
icon_state = "engine"
|
||||
|
||||
engineering_supply
|
||||
name = "Engineering Supply"
|
||||
icon_state = "engine_supply"
|
||||
|
||||
break_room
|
||||
name = "\improper Engineering Break Room"
|
||||
icon_state = "engine"
|
||||
|
||||
@@ -206,7 +206,7 @@
|
||||
return
|
||||
|
||||
/area/proc/updateicon()
|
||||
if ((fire || eject || party) && ((!requires_power)?(!requires_power):power_environ))//If it doesn't require power, can still activate this proc.
|
||||
if ((fire || eject || party) && (!requires_power||power_environ) && !lighting_space)//If it doesn't require power, can still activate this proc.
|
||||
if(fire && !eject && !party)
|
||||
icon_state = "blue"
|
||||
/*else if(atmosalm && !fire && !eject && !party)
|
||||
@@ -234,6 +234,8 @@
|
||||
return 1
|
||||
if(master.always_unpowered)
|
||||
return 0
|
||||
if(src.lighting_space)
|
||||
return 0 // Nope sorry
|
||||
switch(chan)
|
||||
if(EQUIP)
|
||||
return master.power_equip
|
||||
@@ -245,12 +247,10 @@
|
||||
return 0
|
||||
|
||||
// called when power status changes
|
||||
|
||||
/area/proc/power_change()
|
||||
master.powerupdate = 2
|
||||
for(var/area/RA in related)
|
||||
for(var/obj/machinery/M in RA) // for each machine in the area
|
||||
M.power_change() // reverify power status (to update icons etc.)
|
||||
M.power_change() // reverify power status (to update icons etc.)
|
||||
if (fire || eject || party)
|
||||
RA.updateicon()
|
||||
|
||||
@@ -265,7 +265,6 @@
|
||||
used += master.used_environ
|
||||
if(TOTAL)
|
||||
used += master.used_light + master.used_equip + master.used_environ
|
||||
|
||||
return used
|
||||
|
||||
/area/proc/clear_usage()
|
||||
@@ -274,7 +273,6 @@
|
||||
master.used_environ = 0
|
||||
|
||||
/area/proc/use_power(var/amount, var/chan)
|
||||
|
||||
switch(chan)
|
||||
if(EQUIP)
|
||||
master.used_equip += amount
|
||||
|
||||
@@ -22,11 +22,14 @@
|
||||
var/shoot_inventory = 0
|
||||
var/locked = 0
|
||||
var/panel_open = 0 //Hacking a smartfridge
|
||||
var/wires = 7
|
||||
var/const/WIRE_SHOCK = 1
|
||||
var/const/WIRE_SHOOTINV = 2
|
||||
var/const/WIRE_SCANID = 3 //Only used by the secure smartfridge, but required by the cut, mend and pulse procs.
|
||||
var/scan_id = 1
|
||||
var/datum/wires/smartfridge/wires = null
|
||||
|
||||
/obj/machinery/smartfridge/New()
|
||||
wires = new(src)
|
||||
|
||||
/obj/machinery/smartfridge/Del()
|
||||
del(wires) // qdel
|
||||
|
||||
/obj/machinery/smartfridge/proc/accept_check(var/obj/item/O as obj)
|
||||
if(istype(O,/obj/item/weapon/reagent_containers/food/snacks/grown/) || istype(O,/obj/item/seeds/))
|
||||
@@ -217,6 +220,8 @@
|
||||
if(seconds_electrified != 0)
|
||||
if(shock(user, 100))
|
||||
return
|
||||
if(panel_open)
|
||||
wires.Interact(user)
|
||||
|
||||
ui_interact(user)
|
||||
|
||||
@@ -248,26 +253,6 @@
|
||||
if (items.len > 0)
|
||||
data["contents"] = items
|
||||
|
||||
var/list/vendwires = null
|
||||
if (is_secure)
|
||||
vendwires = list(
|
||||
"Violet" = 1,
|
||||
"Orange" = 2,
|
||||
"Green" = 3)
|
||||
else
|
||||
vendwires = list(
|
||||
"Blue" = 1,
|
||||
"Red" = 2,
|
||||
"Black" = 3)
|
||||
|
||||
var/list/vendor_wires[0]
|
||||
for (var/wire in vendwires)
|
||||
var is_uncut = wires & APCWireColorToFlag[vendwires[wire]]
|
||||
vendor_wires.Add(list(list("wire" = wire, "cut" = !is_uncut, "index" = vendwires[wire])))
|
||||
|
||||
if (vendor_wires.len > 0)
|
||||
data["wires"] = vendor_wires
|
||||
|
||||
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "smartfridge.tmpl", src.name, 400, 500)
|
||||
@@ -306,82 +291,8 @@
|
||||
return 1
|
||||
|
||||
return 1
|
||||
|
||||
if (panel_open)
|
||||
if (href_list["cutwire"])
|
||||
if (!( istype(usr.get_active_hand(), /obj/item/weapon/wirecutters) ))
|
||||
user << "You need wirecutters!"
|
||||
return 1
|
||||
|
||||
var/wire_index = text2num(href_list["cutwire"])
|
||||
if (isWireColorCut(wire_index))
|
||||
mend(wire_index)
|
||||
else
|
||||
cut(wire_index)
|
||||
return 1
|
||||
|
||||
if (href_list["pulsewire"])
|
||||
if (!istype(usr.get_active_hand(), /obj/item/device/multitool))
|
||||
usr << "You need a multitool!"
|
||||
return 1
|
||||
|
||||
var/wire_index = text2num(href_list["pulsewire"])
|
||||
if (isWireColorCut(wire_index))
|
||||
usr << "You can't pulse a cut wire."
|
||||
return 1
|
||||
|
||||
pulse(wire_index)
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
/*************
|
||||
* Hacking
|
||||
**************/
|
||||
|
||||
/obj/machinery/smartfridge/proc/cut(var/wireColor)
|
||||
var/wireFlag = APCWireColorToFlag[wireColor]
|
||||
var/wireIndex = APCWireColorToIndex[wireColor]
|
||||
src.wires &= ~wireFlag
|
||||
switch(wireIndex)
|
||||
if(WIRE_SHOCK)
|
||||
src.seconds_electrified = -1
|
||||
if (WIRE_SHOOTINV)
|
||||
if(!src.shoot_inventory)
|
||||
src.shoot_inventory = 1
|
||||
if(WIRE_SCANID)
|
||||
src.locked = 1
|
||||
|
||||
/obj/machinery/smartfridge/proc/mend(var/wireColor)
|
||||
var/wireFlag = APCWireColorToFlag[wireColor]
|
||||
var/wireIndex = APCWireColorToIndex[wireColor]
|
||||
src.wires |= wireFlag
|
||||
switch(wireIndex)
|
||||
if(WIRE_SHOCK)
|
||||
src.seconds_electrified = 0
|
||||
if (WIRE_SHOOTINV)
|
||||
src.shoot_inventory = 0
|
||||
if(WIRE_SCANID)
|
||||
src.locked = 0
|
||||
|
||||
/obj/machinery/smartfridge/proc/pulse(var/wireColor)
|
||||
var/wireIndex = APCWireColorToIndex[wireColor]
|
||||
switch(wireIndex)
|
||||
if(WIRE_SHOCK)
|
||||
src.seconds_electrified = 30
|
||||
if(WIRE_SHOOTINV)
|
||||
src.shoot_inventory = !src.shoot_inventory
|
||||
if(WIRE_SCANID)
|
||||
src.locked = -1
|
||||
|
||||
/obj/machinery/smartfridge/proc/isWireColorCut(var/wireColor)
|
||||
var/wireFlag = APCWireColorToFlag[wireColor]
|
||||
return ((src.wires & wireFlag) == 0)
|
||||
|
||||
/obj/machinery/smartfridge/proc/isWireCut(var/wireIndex)
|
||||
var/wireFlag = APCIndexToFlag[wireIndex]
|
||||
return ((src.wires & wireFlag) == 0)
|
||||
|
||||
/obj/machinery/smartfridge/proc/throw_item()
|
||||
var/obj/throw_item = null
|
||||
var/mob/living/target = locate() in view(7,src)
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
var/safetieson = 1
|
||||
var/cycletime_left = 0
|
||||
|
||||
|
||||
//The units themselves/////////////////
|
||||
|
||||
/obj/machinery/suit_storage_unit/standard_unit
|
||||
@@ -591,13 +590,7 @@
|
||||
var/locked = 1 // If locked, nothing can be taken from or added to the cycler.
|
||||
var/panel_open = 0 // Hacking!
|
||||
var/can_repair // If set, the cycler can repair hardsuits.
|
||||
|
||||
// Wiring bollocks.
|
||||
var/wires = 15
|
||||
var/electrified = 0
|
||||
var/const/WIRE_EXTEND = 1 // Safeties
|
||||
var/const/WIRE_SCANID = 2 // Locked status
|
||||
var/const/WIRE_SHOCK = 3 // What it says on the tin.
|
||||
|
||||
//Departments that the cycler can paint suits to look like.
|
||||
var/list/departments = list("Engineering","Mining","Medical","Security","Atmos")
|
||||
@@ -611,12 +604,20 @@
|
||||
var/obj/item/clothing/suit/space/rig/suit = null
|
||||
var/obj/item/clothing/head/helmet/space/helmet = null
|
||||
|
||||
var/datum/wires/suit_storage_unit/wires = null
|
||||
|
||||
/obj/machinery/suit_cycler/New()
|
||||
..()
|
||||
|
||||
wires = new(src)
|
||||
target_department = departments[1]
|
||||
target_species = species[1]
|
||||
if(!target_department || !target_species) del(src)
|
||||
|
||||
/obj/machinery/suit_cycler/Del()
|
||||
del(wires) // qdel
|
||||
wires = null
|
||||
|
||||
/obj/machinery/suit_cycler/engineering
|
||||
name = "Engineering suit cycler"
|
||||
model_text = "Engineering"
|
||||
@@ -820,31 +821,15 @@
|
||||
dat += "<A href='?src=\ref[src];apply_paintjob=1'><br>\[apply customisation routine\]</a><br><hr>"
|
||||
|
||||
if(panel_open)
|
||||
var/list/vendwires = list(
|
||||
"Violet" = 1,
|
||||
"Orange" = 2,
|
||||
"Goldenrod" = 3,
|
||||
)
|
||||
dat += "<h2><B>Access Panel</B></h2>"
|
||||
for(var/wiredesc in vendwires)
|
||||
var/is_uncut = src.wires & APCWireColorToFlag[vendwires[wiredesc]]
|
||||
dat += "[wiredesc] wire: "
|
||||
if(!is_uncut)
|
||||
dat += "<a href='?src=\ref[src];cutwire=[vendwires[wiredesc]]'>Mend</a>"
|
||||
else
|
||||
dat += "<a href='?src=\ref[src];cutwire=[vendwires[wiredesc]]'>Cut</a> "
|
||||
dat += "<a href='?src=\ref[src];pulsewire=[vendwires[wiredesc]]'>Pulse</a> "
|
||||
dat += "<br>"
|
||||
|
||||
dat += "<br>"
|
||||
dat += "The orange light is [(electrified == 0) ? "off" : "on"].<BR>"
|
||||
dat += "The red light is [safeties ? "blinking" : "off"].<BR>"
|
||||
dat += "The yellow light is [locked ? "on" : "off"].<BR>"
|
||||
dat += wires()
|
||||
|
||||
user << browse(dat, "window=suit_cycler")
|
||||
onclose(user, "suit_cycler")
|
||||
return
|
||||
|
||||
/obj/machinery/suit_cycler/proc/wires()
|
||||
return wires.GetInteractWindow()
|
||||
|
||||
/obj/machinery/suit_cycler/Topic(href, href_list)
|
||||
if(href_list["eject_suit"])
|
||||
if(!suit) return
|
||||
@@ -916,27 +901,6 @@
|
||||
if(radiation_level > 1)
|
||||
suit.clean_blood()
|
||||
|
||||
else if ((href_list["cutwire"]) && (src.panel_open))
|
||||
var/twire = text2num(href_list["cutwire"])
|
||||
if (!( istype(usr.get_active_hand(), /obj/item/weapon/wirecutters) ))
|
||||
usr << "You need wirecutters!"
|
||||
return
|
||||
if (src.isWireColorCut(twire))
|
||||
src.mend(twire)
|
||||
else
|
||||
src.cut(twire)
|
||||
|
||||
else if ((href_list["pulsewire"]) && (src.panel_open))
|
||||
var/twire = text2num(href_list["pulsewire"])
|
||||
if (!istype(usr.get_active_hand(), /obj/item/device/multitool))
|
||||
usr << "You need a multitool!"
|
||||
return
|
||||
if (src.isWireColorCut(twire))
|
||||
usr << "You can't pulse a cut wire."
|
||||
return
|
||||
else
|
||||
src.pulse(twire)
|
||||
|
||||
src.updateUsrDialog()
|
||||
return
|
||||
|
||||
@@ -1017,46 +981,6 @@
|
||||
|
||||
return
|
||||
|
||||
//HACKING PROCS, MOSTLY COPIED FROM VENDING MACHINES
|
||||
/obj/machinery/suit_cycler/proc/isWireColorCut(var/wireColor)
|
||||
var/wireFlag = APCWireColorToFlag[wireColor]
|
||||
return ((src.wires & wireFlag) == 0)
|
||||
|
||||
/obj/machinery/suit_cycler/proc/isWireCut(var/wireIndex)
|
||||
var/wireFlag = APCIndexToFlag[wireIndex]
|
||||
return ((src.wires & wireFlag) == 0)
|
||||
|
||||
/obj/machinery/suit_cycler/proc/cut(var/wireColor)
|
||||
var/wireFlag = APCWireColorToFlag[wireColor]
|
||||
var/wireIndex = APCWireColorToIndex[wireColor]
|
||||
src.wires &= ~wireFlag
|
||||
switch(wireIndex)
|
||||
|
||||
if(WIRE_EXTEND)
|
||||
safeties = 0
|
||||
if(WIRE_SHOCK)
|
||||
electrified = -1
|
||||
if (WIRE_SCANID)
|
||||
locked = 0
|
||||
|
||||
/obj/machinery/suit_cycler/proc/mend(var/wireColor)
|
||||
var/wireFlag = APCWireColorToFlag[wireColor]
|
||||
var/wireIndex = APCWireColorToIndex[wireColor] //not used in this function
|
||||
src.wires |= wireFlag
|
||||
switch(wireIndex)
|
||||
if(WIRE_SHOCK)
|
||||
src.electrified = 0
|
||||
|
||||
/obj/machinery/suit_cycler/proc/pulse(var/wireColor)
|
||||
var/wireIndex = APCWireColorToIndex[wireColor]
|
||||
switch(wireIndex)
|
||||
if(WIRE_EXTEND)
|
||||
safeties = !locked
|
||||
if(WIRE_SHOCK)
|
||||
electrified = 30
|
||||
if (WIRE_SCANID)
|
||||
locked = !locked
|
||||
|
||||
//There HAS to be a less bloated way to do this. TODO: some kind of table/icon name coding? ~Z
|
||||
/obj/machinery/suit_cycler/proc/apply_paintjob()
|
||||
|
||||
|
||||
@@ -56,12 +56,9 @@
|
||||
var/shut_up = 1 //Stop spouting those godawful pitches!
|
||||
var/extended_inventory = 0 //can we access the hidden inventory?
|
||||
var/panel_open = 0 //Hacking that vending machine. Gonna get a free candy bar.
|
||||
var/wires = 15
|
||||
var/scan_id = 1
|
||||
var/obj/item/weapon/coin/coin
|
||||
var/const/WIRE_EXTEND = 1
|
||||
var/const/WIRE_SCANID = 2
|
||||
var/const/WIRE_SHOCK = 3
|
||||
var/const/WIRE_SHOOTINV = 4
|
||||
var/datum/wires/vending/wires = null
|
||||
|
||||
var/check_accounts = 0 // 1 = requires PIN and checks accounts. 0 = You slide an ID, it vends, SPACE COMMUNISM!
|
||||
var/obj/item/weapon/spacecash/ewallet/ewallet
|
||||
@@ -69,6 +66,7 @@
|
||||
|
||||
/obj/machinery/vending/New()
|
||||
..()
|
||||
wires = new(src)
|
||||
spawn(4)
|
||||
src.slogan_list = text2list(src.product_slogans, ";")
|
||||
|
||||
@@ -87,6 +85,14 @@
|
||||
|
||||
return
|
||||
|
||||
/obj/machinery/vending/Del()
|
||||
del(wires) // qdel
|
||||
wires = null
|
||||
if(coin)
|
||||
del(coin) // qdel
|
||||
coin = null
|
||||
..()
|
||||
|
||||
/obj/machinery/vending/ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
@@ -354,36 +360,19 @@
|
||||
dat += "</TT>"
|
||||
|
||||
if(panel_open)
|
||||
var/list/vendwires = list(
|
||||
"Violet" = 1,
|
||||
"Orange" = 2,
|
||||
"Goldenrod" = 3,
|
||||
"Green" = 4,
|
||||
)
|
||||
dat += "<br><hr><br><B>Access Panel</B><br>"
|
||||
for(var/wiredesc in vendwires)
|
||||
var/is_uncut = src.wires & APCWireColorToFlag[vendwires[wiredesc]]
|
||||
dat += "[wiredesc] wire: "
|
||||
if(!is_uncut)
|
||||
dat += "<a href='?src=\ref[src];cutwire=[vendwires[wiredesc]]'>Mend</a>"
|
||||
else
|
||||
dat += "<a href='?src=\ref[src];cutwire=[vendwires[wiredesc]]'>Cut</a> "
|
||||
dat += "<a href='?src=\ref[src];pulsewire=[vendwires[wiredesc]]'>Pulse</a> "
|
||||
dat += "<br>"
|
||||
dat += wires()
|
||||
|
||||
dat += "<br>"
|
||||
dat += "The orange light is [(src.seconds_electrified == 0) ? "off" : "on"].<BR>"
|
||||
dat += "The red light is [src.shoot_inventory ? "off" : "blinking"].<BR>"
|
||||
dat += "The green light is [src.extended_inventory ? "on" : "off"].<BR>"
|
||||
dat += "The [(src.wires & WIRE_SCANID) ? "purple" : "yellow"] light is on.<BR>"
|
||||
|
||||
if (product_slogans != "")
|
||||
dat += "The speaker switch is [src.shut_up ? "off" : "on"]. <a href='?src=\ref[src];togglevoice=[1]'>Toggle</a>"
|
||||
if(product_slogans != "")
|
||||
dat += "The speaker switch is [shut_up ? "off" : "on"]. <a href='?src=\ref[src];togglevoice=[1]'>Toggle</a>"
|
||||
|
||||
user << browse(dat, "window=vending")
|
||||
onclose(user, "")
|
||||
return
|
||||
|
||||
// returns the wire panel text
|
||||
/obj/machinery/vending/proc/wires()
|
||||
return wires.GetInteractWindow()
|
||||
|
||||
/obj/machinery/vending/Topic(href, href_list)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
@@ -425,9 +414,9 @@
|
||||
usr << "\red The vending machine refuses to interface with you, as you are not in its target demographic!"
|
||||
return
|
||||
|
||||
if ((!src.allowed(usr)) && (!src.emagged) && (src.wires & WIRE_SCANID)) //For SECURE VENDING MACHINES YEAH
|
||||
usr << "\red Access denied." //Unless emagged of course
|
||||
flick(src.icon_deny,src)
|
||||
if((!allowed(usr)) && !emagged && scan_id) //For SECURE VENDING MACHINES YEAH
|
||||
usr << "<span class='warning'>Access denied.</span>" //Unless emagged of course
|
||||
flick(icon_deny,src)
|
||||
return
|
||||
|
||||
var/idx=text2num(href_list["vend"])
|
||||
@@ -458,27 +447,6 @@
|
||||
src.updateUsrDialog()
|
||||
return
|
||||
|
||||
else if ((href_list["cutwire"]) && (src.panel_open))
|
||||
var/twire = text2num(href_list["cutwire"])
|
||||
if (!( istype(usr.get_active_hand(), /obj/item/weapon/wirecutters) ))
|
||||
usr << "You need wirecutters!"
|
||||
return
|
||||
if (src.isWireColorCut(twire))
|
||||
src.mend(twire)
|
||||
else
|
||||
src.cut(twire)
|
||||
|
||||
else if ((href_list["pulsewire"]) && (src.panel_open))
|
||||
var/twire = text2num(href_list["pulsewire"])
|
||||
if (!istype(usr.get_active_hand(), /obj/item/device/multitool))
|
||||
usr << "You need a multitool!"
|
||||
return
|
||||
if (src.isWireColorCut(twire))
|
||||
usr << "You can't pulse a cut wire."
|
||||
return
|
||||
else
|
||||
src.pulse(twire)
|
||||
|
||||
else if ((href_list["togglevoice"]) && (src.panel_open))
|
||||
src.shut_up = !src.shut_up
|
||||
|
||||
@@ -490,8 +458,8 @@
|
||||
return
|
||||
|
||||
/obj/machinery/vending/proc/vend(datum/data/vending_product/R, mob/user)
|
||||
if ((!src.allowed(user)) && (!src.emagged) && (src.wires & WIRE_SCANID)) //For SECURE VENDING MACHINES YEAH
|
||||
user << "\red Access denied." //Unless emagged of course
|
||||
if((!allowed(usr)) && !emagged && scan_id) //For SECURE VENDING MACHINES YEAH
|
||||
usr << "<span class='warning'>Access denied.</span>" //Unless emagged of course
|
||||
flick(src.icon_deny,src)
|
||||
return
|
||||
src.vend_ready = 0 //One thing at a time!!
|
||||
@@ -618,51 +586,6 @@
|
||||
src.visible_message("\red <b>[src] launches [throw_item.name] at [target.name]!</b>")
|
||||
return 1
|
||||
|
||||
/obj/machinery/vending/proc/isWireColorCut(var/wireColor)
|
||||
var/wireFlag = APCWireColorToFlag[wireColor]
|
||||
return ((src.wires & wireFlag) == 0)
|
||||
|
||||
/obj/machinery/vending/proc/isWireCut(var/wireIndex)
|
||||
var/wireFlag = APCIndexToFlag[wireIndex]
|
||||
return ((src.wires & wireFlag) == 0)
|
||||
|
||||
/obj/machinery/vending/proc/cut(var/wireColor)
|
||||
var/wireFlag = APCWireColorToFlag[wireColor]
|
||||
var/wireIndex = APCWireColorToIndex[wireColor]
|
||||
src.wires &= ~wireFlag
|
||||
switch(wireIndex)
|
||||
if(WIRE_EXTEND)
|
||||
src.extended_inventory = 0
|
||||
if(WIRE_SHOCK)
|
||||
src.seconds_electrified = -1
|
||||
if (WIRE_SHOOTINV)
|
||||
if(!src.shoot_inventory)
|
||||
src.shoot_inventory = 1
|
||||
|
||||
|
||||
/obj/machinery/vending/proc/mend(var/wireColor)
|
||||
var/wireFlag = APCWireColorToFlag[wireColor]
|
||||
var/wireIndex = APCWireColorToIndex[wireColor] //not used in this function
|
||||
src.wires |= wireFlag
|
||||
switch(wireIndex)
|
||||
// if(WIRE_SCANID)
|
||||
if(WIRE_SHOCK)
|
||||
src.seconds_electrified = 0
|
||||
if (WIRE_SHOOTINV)
|
||||
src.shoot_inventory = 0
|
||||
|
||||
/obj/machinery/vending/proc/pulse(var/wireColor)
|
||||
var/wireIndex = APCWireColorToIndex[wireColor]
|
||||
switch(wireIndex)
|
||||
if(WIRE_EXTEND)
|
||||
src.extended_inventory = !src.extended_inventory
|
||||
// if (WIRE_SCANID)
|
||||
if (WIRE_SHOCK)
|
||||
src.seconds_electrified = 30
|
||||
if (WIRE_SHOOTINV)
|
||||
src.shoot_inventory = !src.shoot_inventory
|
||||
|
||||
|
||||
/*
|
||||
* Vending machine types
|
||||
*/
|
||||
|
||||
@@ -95,6 +95,9 @@
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/can_attach(obj/mecha/M as obj)
|
||||
if(M.equipment.len >= M.max_equip)
|
||||
return 0
|
||||
|
||||
if (ispath(required_type))
|
||||
return istype(M, required_type)
|
||||
|
||||
|
||||
@@ -365,9 +365,7 @@
|
||||
|
||||
if(!PN)
|
||||
PN = new()
|
||||
powernets += PN
|
||||
NC.powernet = PN
|
||||
PN.cables += NC
|
||||
PN.add_cable(NC)
|
||||
NC.mergeConnectedNetworks(NC.d2)
|
||||
|
||||
//NC.mergeConnectedNetworksOnTurf()
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
energy_drain = 10
|
||||
var/dam_force = 20
|
||||
var/obj/mecha/working/ripley/cargo_holder
|
||||
required_type = /obj/mecha/working
|
||||
required_type = list(/obj/mecha/working, /obj/mecha/hoverpod) //so that hoverpods are a bit more useful as space transportation
|
||||
|
||||
attach(obj/mecha/M as obj)
|
||||
..()
|
||||
@@ -1163,6 +1163,10 @@
|
||||
if (!usr.Adjacent(src))
|
||||
return
|
||||
|
||||
if (!isturf(usr.loc))
|
||||
usr << "\red You can't reach the passenger compartment from here."
|
||||
return
|
||||
|
||||
if(iscarbon(usr))
|
||||
var/mob/living/carbon/C = usr
|
||||
if(C.handcuffed)
|
||||
|
||||
@@ -1,96 +1,69 @@
|
||||
/obj/mecha/working/hoverpod
|
||||
/obj/mecha/hoverpod
|
||||
desc = "Stubby and round, this space-capable craft is an ancient favorite."
|
||||
name = "Hover Pod"
|
||||
icon_state = "engineering_pod"
|
||||
initial_icon = "engineering_pod"
|
||||
internal_damage_threshold = 80
|
||||
step_in = 4
|
||||
step_energy_drain = 5
|
||||
step_energy_drain = 10
|
||||
max_temperature = 20000
|
||||
health = 150
|
||||
infra_luminosity = 6
|
||||
wreckage = /obj/effect/decal/mecha_wreckage/hoverpod
|
||||
var/list/cargo = new
|
||||
var/cargo_capacity = 3
|
||||
max_equip = 3
|
||||
max_equip = 2
|
||||
var/datum/effect/effect/system/ion_trail_follow/ion_trail
|
||||
|
||||
//duplicate of parent proc, but without space drifting
|
||||
/obj/mecha/working/hoverpod/dyndomove(direction)
|
||||
if(!can_move)
|
||||
return 0
|
||||
if(src.pr_inertial_movement.active())
|
||||
return 0
|
||||
if(!has_charge(step_energy_drain))
|
||||
return 0
|
||||
var/move_result = 0
|
||||
if(hasInternalDamage(MECHA_INT_CONTROL_LOST))
|
||||
move_result = mechsteprand()
|
||||
else if(src.dir!=direction)
|
||||
move_result = mechturn(direction)
|
||||
else
|
||||
move_result = mechstep(direction)
|
||||
if(move_result)
|
||||
can_move = 0
|
||||
use_power(step_energy_drain)
|
||||
/*if(istype(src.loc, /turf/space))
|
||||
if(!src.check_for_support())
|
||||
src.pr_inertial_movement.start(list(src,direction))
|
||||
src.log_message("Movement control lost. Inertial movement started.")*/
|
||||
if(do_after(step_in))
|
||||
can_move = 1
|
||||
/obj/mecha/hoverpod/New()
|
||||
..()
|
||||
var/turf/T = get_turf(src)
|
||||
if(T.z != 2)
|
||||
new /obj/item/mecha_parts/mecha_tracking(src)
|
||||
|
||||
ion_trail = new /datum/effect/effect/system/ion_trail_follow()
|
||||
ion_trail.set_up(src)
|
||||
ion_trail.start()
|
||||
|
||||
/obj/mecha/hoverpod/range_action(atom/target as obj|mob|turf)
|
||||
return
|
||||
|
||||
//No space drifting
|
||||
/obj/mecha/hoverpod/check_for_support()
|
||||
//does the hoverpod have enough charge left to stabilize itself?
|
||||
if (has_charge(step_energy_drain))
|
||||
if (!ion_trail.on)
|
||||
ion_trail.start()
|
||||
return 1
|
||||
return 0
|
||||
|
||||
ion_trail.stop()
|
||||
return ..()
|
||||
|
||||
//these three procs overriden to play different sounds
|
||||
/obj/mecha/working/hoverpod/mechturn(direction)
|
||||
/obj/mecha/hoverpod/mechturn(direction)
|
||||
dir = direction
|
||||
//playsound(src,'sound/machines/hiss.ogg',40,1)
|
||||
return 1
|
||||
|
||||
/obj/mecha/working/hoverpod/mechstep(direction)
|
||||
/obj/mecha/hoverpod/mechstep(direction)
|
||||
var/result = step(src,direction)
|
||||
if(result)
|
||||
playsound(src,'sound/machines/hiss.ogg',40,1)
|
||||
return result
|
||||
|
||||
|
||||
/obj/mecha/working/hoverpod/mechsteprand()
|
||||
/obj/mecha/hoverpod/mechsteprand()
|
||||
var/result = step_rand(src)
|
||||
if(result)
|
||||
playsound(src,'sound/machines/hiss.ogg',40,1)
|
||||
return result
|
||||
|
||||
/*
|
||||
/obj/mecha/working/hoverpod/New()
|
||||
..()
|
||||
return
|
||||
*/
|
||||
|
||||
/obj/mecha/working/hoverpod/combatpod
|
||||
desc = "An ancient, ghetto fighter." // Ideally would have a seperate icon.
|
||||
name = "Combat Hoverpod"
|
||||
|
||||
/obj/mecha/working/hoverpod/combatpod/New()
|
||||
..()
|
||||
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/explosive
|
||||
ME.attach(src)
|
||||
|
||||
/obj/mecha/working/hoverpod/shuttlepod
|
||||
desc = "Who knew a tiny ball could fit three people?"
|
||||
/obj/mecha/working/hoverpod/shuttlepod/New()
|
||||
..()
|
||||
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/tool/passenger
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/tool/passenger
|
||||
ME.attach(src)
|
||||
|
||||
/obj/mecha/working/hoverpod/Exit(atom/movable/O)
|
||||
/obj/mecha/hoverpod/Exit(atom/movable/O)
|
||||
if(O in cargo)
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/obj/mecha/working/hoverpod/Topic(href, href_list)
|
||||
/obj/mecha/hoverpod/Topic(href, href_list)
|
||||
..()
|
||||
if(href_list["drop_from_cargo"])
|
||||
var/obj/O = locate(href_list["drop_from_cargo"])
|
||||
@@ -105,7 +78,7 @@
|
||||
return
|
||||
|
||||
|
||||
/obj/mecha/working/hoverpod/get_stats_part()
|
||||
/obj/mecha/hoverpod/get_stats_part()
|
||||
var/output = ..()
|
||||
output += "<b>Cargo Compartment Contents:</b><div style=\"margin-left: 15px;\">"
|
||||
if(src.cargo.len)
|
||||
@@ -116,7 +89,7 @@
|
||||
output += "</div>"
|
||||
return output
|
||||
|
||||
/obj/mecha/working/hoverpod/Del()
|
||||
/obj/mecha/hoverpod/Del()
|
||||
for(var/mob/M in src)
|
||||
if(M==src.occupant)
|
||||
continue
|
||||
@@ -130,4 +103,32 @@
|
||||
T.Entered(A)
|
||||
step_rand(A)
|
||||
..()
|
||||
return
|
||||
return
|
||||
|
||||
//Hoverpod variants
|
||||
|
||||
/* Commented out the combatpod as they can't reattach their equipment if it ever gets dropped,
|
||||
* and making a special exception for them seems lame.
|
||||
/obj/mecha/hoverpod/combatpod
|
||||
desc = "An ancient, run-down combat spacecraft." // Ideally would have a seperate icon.
|
||||
name = "Combat Hoverpod"
|
||||
health = 200
|
||||
internal_damage_threshold = 35
|
||||
|
||||
/obj/mecha/hoverpod/combatpod/New()
|
||||
..()
|
||||
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/explosive
|
||||
ME.attach(src)
|
||||
*/
|
||||
|
||||
/obj/mecha/hoverpod/shuttlepod
|
||||
desc = "Who knew a tiny ball could fit three people?"
|
||||
|
||||
/obj/mecha/hoverpod/shuttlepod/New()
|
||||
..()
|
||||
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/tool/passenger
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/tool/passenger
|
||||
ME.attach(src)
|
||||
@@ -97,10 +97,7 @@
|
||||
SetLuminosity(12)
|
||||
|
||||
// found a powernet, so drain up to max power from it
|
||||
|
||||
var/drained = min ( drain_rate, PN.avail )
|
||||
PN.newload += drained
|
||||
power_drained += drained
|
||||
var/drained = PN.draw_power(drain_rate)
|
||||
|
||||
// if tried to drain more than available on powernet
|
||||
// now look for APCs and drain their cells
|
||||
|
||||
@@ -70,5 +70,5 @@
|
||||
|
||||
/obj/structure/largecrate/hoverpod/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(istype(W, /obj/item/weapon/crowbar))
|
||||
new /obj/mecha/working/hoverpod(loc)
|
||||
new /obj/mecha/hoverpod(loc)
|
||||
..()
|
||||
@@ -186,10 +186,6 @@ var/list/globalAirlockWireColorToFlag = RandomAirlockWires()
|
||||
var/list/globalAirlockIndexToFlag
|
||||
var/list/globalAirlockIndexToWireColor
|
||||
var/list/globalAirlockWireColorToIndex
|
||||
var/list/APCWireColorToFlag = RandomAPCWires()
|
||||
var/list/APCIndexToFlag
|
||||
var/list/APCIndexToWireColor
|
||||
var/list/APCWireColorToIndex
|
||||
var/list/BorgWireColorToFlag = RandomBorgWires()
|
||||
var/list/BorgIndexToFlag
|
||||
var/list/BorgIndexToWireColor
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
var/frequency = 1457
|
||||
var/delay = 0
|
||||
var/airlock_wire = null
|
||||
var/datum/wires/connected = null
|
||||
var/datum/radio_frequency/radio_connection
|
||||
var/deadman = 0
|
||||
|
||||
@@ -118,7 +119,9 @@
|
||||
|
||||
|
||||
pulse(var/radio = 0)
|
||||
if(istype(src.loc, /obj/machinery/door/airlock) && src.airlock_wire && src.wires)
|
||||
if(src.connected && src.wires)
|
||||
connected.Pulse(src)
|
||||
else if(istype(src.loc, /obj/machinery/door/airlock) && src.airlock_wire && src.wires)
|
||||
var/obj/machinery/door/airlock/A = src.loc
|
||||
A.pulse(src.airlock_wire)
|
||||
else if(holder)
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
|
||||
var/obj/item/stack/cable_coil/CC = new/obj/item/stack/cable_coil(user.loc)
|
||||
CC.amount = 1
|
||||
CC.updateicon()
|
||||
CC.update_icon()
|
||||
overlays = list()
|
||||
string_attached = null
|
||||
user << "\blue You detach the string from the coin."
|
||||
|
||||
@@ -95,4 +95,12 @@
|
||||
O.loc = src.loc
|
||||
usr << "\blue You empty the ore box"
|
||||
|
||||
return
|
||||
return
|
||||
|
||||
/obj/structure/ore_box/ex_act(severity)
|
||||
if(severity == 1.0 || (severity < 3.0 && prob(50)))
|
||||
for (var/obj/item/weapon/ore/O in contents)
|
||||
O.loc = src.loc
|
||||
O.ex_act(severity++)
|
||||
del(src)
|
||||
return
|
||||
File diff suppressed because it is too large
Load Diff
@@ -239,21 +239,15 @@
|
||||
var/last_overcharge = overcharge_percent
|
||||
|
||||
if(terminal)
|
||||
var/excess = terminal.surplus()
|
||||
if(chargemode)
|
||||
var/target_load = min((capacity-charge)/SMESRATE, chargelevel) // 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
|
||||
var/load = min((capacity * 1.5 - charge)/SMESRATE, chargelevel) // charge at set rate, limited to spare capacity
|
||||
load = add_load(load) // add the load to the terminal side network
|
||||
charge += load * SMESRATE // increase the charge
|
||||
|
||||
|
||||
else // if not enough capacity
|
||||
charging = 0 // stop charging
|
||||
|
||||
else
|
||||
if (chargemode && excess > 0 && excess >= chargelevel)
|
||||
if (actual_load >= target_load) // did the powernet have enough power available for us?
|
||||
charging = 1
|
||||
else
|
||||
charging = 0
|
||||
|
||||
if(online) // if outputting
|
||||
lastout = min( charge/SMESRATE, output) //limit output to that stored
|
||||
|
||||
@@ -80,13 +80,14 @@
|
||||
C.breaker_box = src
|
||||
|
||||
var/datum/powernet/PN = new()
|
||||
PN.number = powernets.len + 1
|
||||
powernets += PN
|
||||
PN.cables += C
|
||||
PN.add_cable(C)
|
||||
|
||||
C.mergeConnectedNetworks(C.d2)
|
||||
C.mergeConnectedNetworksOnTurf()
|
||||
|
||||
if(C.d2 & (C.d2 - 1))// if the cable is layed diagonally, check the others 2 possible directions
|
||||
C.mergeDiagonalsNetworks(C.d2)
|
||||
|
||||
else
|
||||
icon_state = icon_state_off
|
||||
for(var/obj/structure/cable/C in src.loc)
|
||||
|
||||
@@ -1,29 +1,27 @@
|
||||
// attach a wire to a power machine - leads from the turf you are standing on
|
||||
///////////////////////////////
|
||||
//CABLE STRUCTURE
|
||||
///////////////////////////////
|
||||
|
||||
/obj/machinery/power/attackby(obj/item/weapon/W, mob/user)
|
||||
|
||||
if(istype(W, /obj/item/stack/cable_coil))
|
||||
////////////////////////////////
|
||||
// Definitions
|
||||
////////////////////////////////
|
||||
|
||||
var/obj/item/stack/cable_coil/coil = W
|
||||
/* Cable directions (d1 and d2)
|
||||
|
||||
var/turf/T = user.loc
|
||||
|
||||
if(T.intact || !istype(T, /turf/simulated/floor))
|
||||
return
|
||||
9 1 5
|
||||
\ | /
|
||||
8 - 0 - 4
|
||||
/ | \
|
||||
10 2 6
|
||||
|
||||
if(get_dist(src, user) > 1)
|
||||
return
|
||||
If d1 = 0 and d2 = 0, there's no cable
|
||||
If d1 = 0 and d2 = dir, it's a O-X cable, getting from the center of the tile to dir (knot cable)
|
||||
If d1 = dir1 and d2 = dir2, it's a full X-X cable, getting from dir1 to dir2
|
||||
By design, d1 is the smallest direction and d2 is the highest
|
||||
*/
|
||||
|
||||
if(!directwired) // only for attaching to directwired machines
|
||||
return
|
||||
|
||||
coil.turf_place(T, user)
|
||||
return
|
||||
else
|
||||
..()
|
||||
return
|
||||
|
||||
// the power cable object
|
||||
/obj/structure/cable
|
||||
level = 1
|
||||
anchored =1
|
||||
@@ -74,17 +72,20 @@
|
||||
var/turf/T = src.loc // hide if turf is not intact
|
||||
|
||||
if(level==1) hide(T.intact)
|
||||
cable_list += src
|
||||
update_icon()
|
||||
cable_list += src //add it to the global cable list
|
||||
|
||||
|
||||
/obj/structure/cable/Del() // called when a cable is deleted
|
||||
if(!defer_powernet_rebuild) // set if network will be rebuilt manually
|
||||
if(powernet)
|
||||
powernet.cut_cable(src) // update the powernets
|
||||
cable_list -= src
|
||||
..() // then go ahead and delete the cable
|
||||
/obj/structure/cable/Del() // called when a cable is deleted
|
||||
if(powernet)
|
||||
cut_cable_from_powernet() // update the powernets
|
||||
cable_list -= src //remove it from global cable list
|
||||
..() // then go ahead and delete the cable
|
||||
|
||||
///////////////////////////////////
|
||||
// General procedures
|
||||
///////////////////////////////////
|
||||
|
||||
//If underfloor, hide the cable
|
||||
/obj/structure/cable/hide(var/i)
|
||||
|
||||
if(level == 1 && istype(loc, /turf))
|
||||
@@ -92,17 +93,25 @@
|
||||
updateicon()
|
||||
|
||||
/obj/structure/cable/proc/updateicon()
|
||||
icon_state = "[d1]-[d2]"
|
||||
alpha = invisibility ? 127 : 255
|
||||
if(invisibility)
|
||||
icon_state = "[d1]-[d2]-f"
|
||||
else
|
||||
icon_state = "[d1]-[d2]"
|
||||
|
||||
|
||||
// returns the powernet this cable belongs to
|
||||
/obj/structure/cable/proc/get_powernet() //TODO: remove this as it is obsolete
|
||||
return powernet
|
||||
|
||||
//Telekinesis has no effect on a cable
|
||||
/obj/structure/cable/attack_tk(mob/user)
|
||||
return
|
||||
|
||||
// Items usable on a cable :
|
||||
// - Wirecutters : cut it duh !
|
||||
// - Cable coil : merge cables
|
||||
// - Multitool : get the power currently passing through the cable
|
||||
//
|
||||
/obj/structure/cable/attackby(obj/item/W, mob/user)
|
||||
|
||||
var/turf/T = src.loc
|
||||
@@ -110,13 +119,11 @@
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/weapon/wirecutters))
|
||||
|
||||
///// Z-Level Stuff
|
||||
if(src.d1 == 12 || src.d2 == 12)
|
||||
user << "<span class='warning'>You must cut this cable from above.</span>"
|
||||
return
|
||||
///// Z-Level Stuff
|
||||
|
||||
if(breaker_box)
|
||||
user << "\red This cable is connected to nearby breaker box. Use breaker box to interact with it."
|
||||
return
|
||||
@@ -142,22 +149,23 @@
|
||||
if(c.d1 == 12 || c.d2 == 12)
|
||||
c.Del()
|
||||
///// Z-Level Stuff
|
||||
investigate_log("was cut by [key_name(usr, usr.client)] in [user.loc.loc]","wires")
|
||||
|
||||
del(src)
|
||||
|
||||
return // not needed, but for clarity
|
||||
del(src) // qdel
|
||||
return
|
||||
|
||||
|
||||
else if(istype(W, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/coil = W
|
||||
if (coil.get_amount() < 1)
|
||||
user << "Not enough cable"
|
||||
return
|
||||
coil.cable_join(src, user)
|
||||
|
||||
else if(istype(W, /obj/item/device/multitool))
|
||||
|
||||
var/datum/powernet/PN = get_powernet() // find the powernet
|
||||
|
||||
if(PN && (PN.avail > 0)) // is it powered?
|
||||
user << "<span class='warning'>[PN.avail]W in power network.</span>"
|
||||
if(powernet && (powernet.avail > 0)) // is it powered?
|
||||
user << "<span class='warning'>[powernet.avail]W in power network.</span>"
|
||||
|
||||
else
|
||||
user << "<span class='warning'>The cable is not powered.</span>"
|
||||
@@ -171,7 +179,6 @@
|
||||
src.add_fingerprint(user)
|
||||
|
||||
// shock the user with probability prb
|
||||
|
||||
/obj/structure/cable/proc/shock(mob/user, prb, var/siemens_coeff = 1.0)
|
||||
if(!prob(prb))
|
||||
return 0
|
||||
@@ -183,24 +190,296 @@
|
||||
else
|
||||
return 0
|
||||
|
||||
//explosion handling
|
||||
/obj/structure/cable/ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
del(src)
|
||||
del(src) // qdel
|
||||
if(2.0)
|
||||
if (prob(50))
|
||||
new/obj/item/stack/cable_coil(src.loc, src.d1 ? 2 : 1, color)
|
||||
del(src)
|
||||
del(src) // qdel
|
||||
|
||||
if(3.0)
|
||||
if (prob(25))
|
||||
new/obj/item/stack/cable_coil(src.loc, src.d1 ? 2 : 1, color)
|
||||
del(src)
|
||||
del(src) // qdel
|
||||
return
|
||||
|
||||
// the cable coil object, used for laying cable
|
||||
obj/structure/cable/proc/cableColor(var/colorC)
|
||||
var/color_n = "#DD0000"
|
||||
if(colorC)
|
||||
color_n = colorC
|
||||
color = color_n
|
||||
|
||||
////////////////////////////////////////////
|
||||
// Power related
|
||||
///////////////////////////////////////////
|
||||
|
||||
obj/structure/cable/proc/add_avail(var/amount)
|
||||
if(powernet)
|
||||
powernet.newavail += amount
|
||||
|
||||
obj/structure/cable/proc/add_load(var/amount)
|
||||
if(powernet)
|
||||
powernet.load += amount
|
||||
|
||||
obj/structure/cable/proc/surplus()
|
||||
if(powernet)
|
||||
return powernet.avail-powernet.load
|
||||
else
|
||||
return 0
|
||||
|
||||
obj/structure/cable/proc/avail()
|
||||
if(powernet)
|
||||
return powernet.avail
|
||||
else
|
||||
return 0
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// Cable laying helpers
|
||||
////////////////////////////////////////////////
|
||||
|
||||
//handles merging diagonally matching cables
|
||||
//for info : direction^3 is flipping horizontally, direction^12 is flipping vertically
|
||||
/obj/structure/cable/proc/mergeDiagonalsNetworks(var/direction)
|
||||
|
||||
//search for and merge diagonally matching cables from the first direction component (north/south)
|
||||
var/turf/T = get_step(src, direction&3)//go north/south
|
||||
|
||||
for(var/obj/structure/cable/C in T)
|
||||
|
||||
if(!C)
|
||||
continue
|
||||
|
||||
if(src == C)
|
||||
continue
|
||||
|
||||
if(C.d1 == (direction^3) || C.d2 == (direction^3)) //we've got a diagonally matching cable
|
||||
if(!C.powernet) //if the matching cable somehow got no powernet, make him one (should not happen for cables)
|
||||
var/datum/powernet/newPN = new()
|
||||
newPN.add_cable(C)
|
||||
|
||||
if(powernet) //if we already have a powernet, then merge the two powernets
|
||||
merge_powernets(powernet,C.powernet)
|
||||
else
|
||||
C.powernet.add_cable(src) //else, we simply connect to the matching cable powernet
|
||||
|
||||
//the same from the second direction component (east/west)
|
||||
T = get_step(src, direction&12)//go east/west
|
||||
|
||||
for(var/obj/structure/cable/C in T)
|
||||
|
||||
if(!C)
|
||||
continue
|
||||
|
||||
if(src == C)
|
||||
continue
|
||||
if(C.d1 == (direction^12) || C.d2 == (direction^12)) //we've got a diagonally matching cable
|
||||
if(!C.powernet) //if the matching cable somehow got no powernet, make him one (should not happen for cables)
|
||||
var/datum/powernet/newPN = new()
|
||||
newPN.add_cable(C)
|
||||
|
||||
if(powernet) //if we already have a powernet, then merge the two powernets
|
||||
merge_powernets(powernet,C.powernet)
|
||||
else
|
||||
C.powernet.add_cable(src) //else, we simply connect to the matching cable powernet
|
||||
|
||||
// merge with the powernets of power objects in the given direction
|
||||
/obj/structure/cable/proc/mergeConnectedNetworks(var/direction)
|
||||
|
||||
var/fdir = (!direction)? 0 : turn(direction, 180) //flip the direction, to match with the source position on its turf
|
||||
|
||||
if(!(d1 == direction || d2 == direction)) //if the cable is not pointed in this direction, do nothing
|
||||
return
|
||||
|
||||
var/turf/TB = get_step(src, direction)
|
||||
|
||||
for(var/obj/structure/cable/C in TB)
|
||||
|
||||
if(!C)
|
||||
continue
|
||||
|
||||
if(src == C)
|
||||
continue
|
||||
|
||||
if(C.d1 == fdir || C.d2 == fdir) //we've got a matching cable in the neighbor turf
|
||||
if(!C.powernet) //if the matching cable somehow got no powernet, make him one (should not happen for cables)
|
||||
var/datum/powernet/newPN = new()
|
||||
newPN.add_cable(C)
|
||||
|
||||
if(powernet) //if we already have a powernet, then merge the two powernets
|
||||
merge_powernets(powernet,C.powernet)
|
||||
else
|
||||
C.powernet.add_cable(src) //else, we simply connect to the matching cable powernet
|
||||
|
||||
// merge with the powernets of power objects in the source turf
|
||||
/obj/structure/cable/proc/mergeConnectedNetworksOnTurf()
|
||||
var/list/to_connect = list()
|
||||
|
||||
if(!powernet) //if we somehow have no powernet, make one (should not happen for cables)
|
||||
var/datum/powernet/newPN = new()
|
||||
newPN.add_cable(src)
|
||||
|
||||
//first let's add turf cables to our powernet
|
||||
//then we'll connect machines on turf with a node cable is present
|
||||
for(var/AM in loc)
|
||||
if(istype(AM,/obj/structure/cable))
|
||||
var/obj/structure/cable/C = AM
|
||||
if(C.d1 == d1 || C.d2 == d1 || C.d1 == d2 || C.d2 == d2) //only connected if they have a common direction
|
||||
if(C.powernet == powernet) continue
|
||||
if(C.powernet)
|
||||
merge_powernets(powernet, C.powernet)
|
||||
else
|
||||
powernet.add_cable(C) //the cable was powernetless, let's just add it to our powernet
|
||||
|
||||
else if(istype(AM,/obj/machinery/power/apc))
|
||||
var/obj/machinery/power/apc/N = AM
|
||||
if(!N.terminal) continue // APC are connected through their terminal
|
||||
|
||||
if(N.terminal.powernet == powernet)
|
||||
continue
|
||||
|
||||
to_connect += N.terminal //we'll connect the machines after all cables are merged
|
||||
|
||||
else if(istype(AM,/obj/machinery/power)) //other power machines
|
||||
var/obj/machinery/power/M = AM
|
||||
|
||||
if(M.powernet == powernet)
|
||||
continue
|
||||
|
||||
to_connect += M //we'll connect the machines after all cables are merged
|
||||
|
||||
//now that cables are done, let's connect found machines
|
||||
for(var/obj/machinery/power/PM in to_connect)
|
||||
if(!PM.connect_to_network())
|
||||
PM.disconnect_from_network() //if we somehow can't connect the machine to the new powernet, remove it from the old nonetheless
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// Powernets handling helpers
|
||||
//////////////////////////////////////////////
|
||||
|
||||
//if powernetless_only = 1, will only get connections without powernet
|
||||
/obj/structure/cable/proc/get_connections(var/powernetless_only = 0)
|
||||
. = list() // this will be a list of all connected power objects
|
||||
var/turf/T
|
||||
|
||||
///// Z-Level Stuff
|
||||
if (d1 == 11 || d1 == 12)
|
||||
var/turf/controllerlocation = locate(1, 1, z)
|
||||
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
|
||||
if(controller.up && d1 == 12)
|
||||
T = locate(src.x, src.y, controller.up_target)
|
||||
if(T)
|
||||
. += power_list(T, src, 11, 1)
|
||||
if(controller.down && d1 == 11)
|
||||
T = locate(src.x, src.y, controller.down_target)
|
||||
if(T)
|
||||
. += power_list(T, src, 12, 1)
|
||||
///// Z-Level Stuff
|
||||
//get matching cables from the first direction
|
||||
else if(d1) //if not a node cable
|
||||
T = get_step(src, d1)
|
||||
if(T)
|
||||
. += power_list(T, src, turn(d1, 180), powernetless_only) //get adjacents matching cables
|
||||
|
||||
if(d1&(d1-1)) //diagonal direction, must check the 4 possibles adjacents tiles
|
||||
T = get_step(src,d1&3) // go north/south
|
||||
if(T)
|
||||
. += power_list(T, src, d1 ^ 3, powernetless_only) //get diagonally matching cables
|
||||
T = get_step(src,d1&12) // go east/west
|
||||
if(T)
|
||||
. += power_list(T, src, d1 ^ 12, powernetless_only) //get diagonally matching cables
|
||||
|
||||
. += power_list(loc, src, d1, powernetless_only) //get on turf matching cables
|
||||
|
||||
///// Z-Level Stuff
|
||||
if(d2 == 11 || d2 == 12)
|
||||
var/turf/controllerlocation = locate(1, 1, z)
|
||||
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
|
||||
if(controller.up && d2 == 12)
|
||||
T = locate(src.x, src.y, controller.up_target)
|
||||
if(T)
|
||||
. += power_list(T, src, 11, 1)
|
||||
if(controller.down && d2 == 11)
|
||||
T = locate(src.x, src.y, controller.down_target)
|
||||
if(T)
|
||||
. += power_list(T, src, 12, 1)
|
||||
///// Z-Level Stuff
|
||||
else
|
||||
//do the same on the second direction (which can't be 0)
|
||||
T = get_step(src, d2)
|
||||
if(T)
|
||||
. += power_list(T, src, turn(d2, 180), powernetless_only) //get adjacents matching cables
|
||||
|
||||
if(d2&(d2-1)) //diagonal direction, must check the 4 possibles adjacents tiles
|
||||
T = get_step(src,d2&3) // go north/south
|
||||
if(T)
|
||||
. += power_list(T, src, d2 ^ 3, powernetless_only) //get diagonally matching cables
|
||||
T = get_step(src,d2&12) // go east/west
|
||||
if(T)
|
||||
. += power_list(T, src, d2 ^ 12, powernetless_only) //get diagonally matching cables
|
||||
. += power_list(loc, src, d2, powernetless_only) //get on turf matching cables
|
||||
|
||||
return .
|
||||
|
||||
//should be called after placing a cable which extends another cable, creating a "smooth" cable that no longer terminates in the centre of a turf.
|
||||
//needed as this can, unlike other placements, disconnect cables
|
||||
/obj/structure/cable/proc/denode()
|
||||
var/turf/T1 = loc
|
||||
if(!T1) return
|
||||
|
||||
var/list/powerlist = power_list(T1,src,0,0) //find the other cables that ended in the centre of the turf, with or without a powernet
|
||||
if(powerlist.len>0)
|
||||
var/datum/powernet/PN = new()
|
||||
propagate_network(powerlist[1],PN) //propagates the new powernet beginning at the source cable
|
||||
|
||||
if(PN.is_empty()) //can happen with machines made nodeless when smoothing cables
|
||||
del(PN) // qdel
|
||||
|
||||
// cut the cable's powernet at this cable and updates the powergrid
|
||||
/obj/structure/cable/proc/cut_cable_from_powernet()
|
||||
var/turf/T1 = loc
|
||||
var/list/P_list
|
||||
if(!T1) return
|
||||
if(d1)
|
||||
T1 = get_step(T1, d1)
|
||||
P_list = power_list(T1, src, turn(d1,180),0,cable_only = 1) // what adjacently joins on to cut cable...
|
||||
|
||||
P_list += power_list(loc, src, d1, 0, cable_only = 1)//... and on turf
|
||||
|
||||
|
||||
if(P_list.len == 0)//if nothing in both list, then the cable was a lone cable, just delete it and its powernet
|
||||
powernet.remove_cable(src)
|
||||
|
||||
for(var/obj/machinery/power/P in T1)//check if it was powering a machine
|
||||
if(!P.connect_to_network()) //can't find a node cable on a the turf to connect to
|
||||
P.disconnect_from_network() //remove from current network (and delete powernet)
|
||||
return
|
||||
|
||||
// remove the cut cable from its turf and powernet, so that it doesn't get count in propagate_network worklist
|
||||
loc = null
|
||||
powernet.remove_cable(src) //remove the cut cable from its powernet
|
||||
|
||||
var/datum/powernet/newPN = new()// creates a new powernet...
|
||||
propagate_network(P_list[1], newPN)//... and propagates it to the other side of the cable
|
||||
|
||||
// Disconnect machines connected to nodes
|
||||
if(d1 == 0) // if we cut a node (O-X) cable
|
||||
for(var/obj/machinery/power/P in T1)
|
||||
if(!P.connect_to_network()) //can't find a node cable on a the turf to connect to
|
||||
P.disconnect_from_network() //remove from current network
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// The cable coil object, used for laying cable
|
||||
///////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////
|
||||
// Definitions
|
||||
////////////////////////////////
|
||||
|
||||
#define MAXCOIL 30
|
||||
|
||||
/obj/item/stack/cable_coil
|
||||
name = "cable coil"
|
||||
icon = 'icons/obj/power.dmi'
|
||||
@@ -219,10 +498,12 @@
|
||||
item_state = "coil"
|
||||
attack_verb = list("whipped", "lashed", "disciplined", "flogged")
|
||||
|
||||
suicide_act(mob/user)
|
||||
viewers(user) << "<span class='warning'><b>[user] is strangling \himself with the [src.name]! It looks like \he's trying to commit suicide.</b></span>"
|
||||
return(OXYLOSS)
|
||||
|
||||
/obj/item/stack/cable_coil/suicide_act(mob/user)
|
||||
if(locate(/obj/structure/stool) in user.loc)
|
||||
user.visible_message("<span class='suicide'>[user] is making a noose with the [src.name]! It looks like \he's trying to commit suicide.</span>")
|
||||
else
|
||||
user.visible_message("<span class='suicide'>[user] is strangling \himself with the [src.name]! It looks like \he's trying to commit suicide.</span>")
|
||||
return(OXYLOSS)
|
||||
|
||||
/obj/item/stack/cable_coil/New(loc, length = MAXCOIL, var/param_color = null)
|
||||
..()
|
||||
@@ -233,10 +514,38 @@
|
||||
color = item_color
|
||||
pixel_x = rand(-2,2)
|
||||
pixel_y = rand(-2,2)
|
||||
updateicon()
|
||||
update_icon()
|
||||
update_wclass()
|
||||
|
||||
/obj/item/stack/cable_coil/proc/updateicon()
|
||||
///////////////////////////////////
|
||||
// General procedures
|
||||
///////////////////////////////////
|
||||
|
||||
//you can use wires to heal robotics
|
||||
/obj/item/stack/cable_coil/attack(mob/M as mob, mob/user as mob)
|
||||
if(istype(M,/mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/datum/organ/external/S = H.get_organ(user.zone_sel.selecting)
|
||||
if(!(S.status & ORGAN_ROBOT) || user.a_intent != "help")
|
||||
return ..()
|
||||
|
||||
if(H.species.flags & IS_SYNTHETIC)
|
||||
if(M == user)
|
||||
user << "\red You can't repair damage to your own body - it's against OH&S."
|
||||
return
|
||||
|
||||
if(S.burn_dam > 0 && use(1))
|
||||
S.heal_damage(0,15,0,1)
|
||||
user.visible_message("\red \The [user] repairs some burn damage on \the [M]'s [S.display_name] with \the [src].")
|
||||
return
|
||||
else
|
||||
user << "Nothing to fix!"
|
||||
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/item/stack/cable_coil/update_icon()
|
||||
if (!color)
|
||||
color = pick(COLOR_RED, COLOR_BLUE, COLOR_GREEN, COLOR_ORANGE, COLOR_WHITE, COLOR_PINK, COLOR_YELLOW, COLOR_CYAN)
|
||||
item_color = color
|
||||
@@ -259,12 +568,13 @@
|
||||
/obj/item/stack/cable_coil/examine()
|
||||
set src in view(1)
|
||||
|
||||
if(amount == 1)
|
||||
if(get_amount() == 1)
|
||||
usr << "A short piece of power cable."
|
||||
else if(amount == 2)
|
||||
else if(get_amount() == 2)
|
||||
usr << "A piece of power cable."
|
||||
else
|
||||
usr << "A coil of power cable. There are [amount] lengths of cable in the coil."
|
||||
usr << "A coil of power cable. There are [get_amount()] lengths of cable in the coil."
|
||||
|
||||
|
||||
/obj/item/stack/cable_coil/verb/make_restraint()
|
||||
set name = "Make Cable Restraints"
|
||||
@@ -274,26 +584,28 @@
|
||||
if(ishuman(M) && !M.restrained() && !M.stat && !M.paralysis && ! M.stunned)
|
||||
if(!istype(usr.loc,/turf)) return
|
||||
if(src.amount <= 14)
|
||||
usr << "<span class='warning'>You need at least 15 lengths to make restraints!</span>"
|
||||
usr << "\red You need at least 15 lengths to make restraints!"
|
||||
return
|
||||
var/obj/item/weapon/handcuffs/cable/B = new /obj/item/weapon/handcuffs/cable(usr.loc)
|
||||
B.color = item_color
|
||||
usr << "<span class='notice'>You wind some cable together to make some restraints.</span>"
|
||||
B.icon_state = "cuff_[item_color]"
|
||||
usr << "\blue You wind some cable together to make some restraints."
|
||||
src.use(15)
|
||||
else
|
||||
usr << "<span class='notice'>\blue You cannot do that.</span>"
|
||||
usr << "\blue You cannot do that."
|
||||
..()
|
||||
|
||||
// Items usable on a cable coil :
|
||||
// - Wirecutters : cut them duh !
|
||||
// - Cable coil : merge cables
|
||||
/obj/item/stack/cable_coil/attackby(obj/item/weapon/W, mob/user)
|
||||
..()
|
||||
if( istype(W, /obj/item/weapon/wirecutters) && src.amount > 1)
|
||||
src.amount--
|
||||
new/obj/item/stack/cable_coil(user.loc, 1,item_color)
|
||||
user << "<span class='notice'>You cut a piece off the cable coil.</span>"
|
||||
src.updateicon()
|
||||
src.update_wclass()
|
||||
user << "You cut a piece off the cable coil."
|
||||
src.update_icon()
|
||||
return
|
||||
|
||||
else if( istype(W, /obj/item/stack/cable_coil) )
|
||||
else if(istype(W, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/C = W
|
||||
if(C.amount >= MAXCOIL)
|
||||
user << "The coil is too long, you cannot add any more cable to it."
|
||||
@@ -301,54 +613,65 @@
|
||||
|
||||
if( (C.amount + src.amount <= MAXCOIL) )
|
||||
user << "You join the cable coils together."
|
||||
C.add(src.amount) // give it cable
|
||||
C.give(src.amount) // give it cable
|
||||
src.use(src.amount) // make sure this one cleans up right
|
||||
return
|
||||
|
||||
else
|
||||
var/amt = MAXCOIL - C.amount
|
||||
user << "You transfer [amt] length\s of cable from one coil to the other."
|
||||
C.add(amt)
|
||||
C.give(amt)
|
||||
src.use(amt)
|
||||
return
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/item/stack/cable_coil/attack_hand(mob/user as mob)
|
||||
if (user.get_inactive_hand() == src)
|
||||
var/obj/item/stack/cable_coil/F = new /obj/item/stack/cable_coil(user, 1, color)
|
||||
F.copy_evidences(src)
|
||||
user.put_in_hands(F)
|
||||
src.add_fingerprint(user)
|
||||
F.add_fingerprint(user)
|
||||
use(1)
|
||||
//remove cables from the stack
|
||||
/* This is probably reduntant
|
||||
/obj/item/stack/cable_coil/use(var/used)
|
||||
if(src.amount < used)
|
||||
return 0
|
||||
else if (src.amount == used)
|
||||
if(ismob(loc)) //handle mob icon update
|
||||
var/mob/M = loc
|
||||
M.unEquip(src)
|
||||
qdel(src)
|
||||
return 1
|
||||
else
|
||||
..()
|
||||
return
|
||||
|
||||
amount -= used
|
||||
update_icon()
|
||||
return 1
|
||||
*/
|
||||
/obj/item/stack/cable_coil/use(var/used)
|
||||
. = ..()
|
||||
updateicon()
|
||||
update_wclass()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/item/stack/cable_coil/add(var/extra)
|
||||
. = ..()
|
||||
updateicon()
|
||||
update_wclass()
|
||||
return
|
||||
//add cables to the stack
|
||||
/obj/item/stack/cable_coil/proc/give(var/extra)
|
||||
if(amount + extra > MAXCOIL)
|
||||
amount = MAXCOIL
|
||||
else
|
||||
amount += extra
|
||||
update_icon()
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// Cable laying procedures
|
||||
//////////////////////////////////////////////
|
||||
|
||||
// called when cable_coil is clicked on a turf/simulated/floor
|
||||
|
||||
/obj/item/stack/cable_coil/proc/turf_place(turf/simulated/floor/F, mob/user)
|
||||
|
||||
if(!isturf(user.loc))
|
||||
return
|
||||
|
||||
if(get_dist(F,user) > 1)
|
||||
user << "<span class='warning'>You can't lay cable at a place that far away.</span>"
|
||||
if(get_amount() < 1) // Out of cable
|
||||
user << "There is no cable left."
|
||||
return
|
||||
|
||||
if(F.intact) // if floor is intact, complain
|
||||
user << "<span class='warning'>You can't lay cable there unless the floor tiles are removed.</span>"
|
||||
if(get_dist(F,user) > 1) // Too far
|
||||
user << "You can't lay cable at a place that far away."
|
||||
return
|
||||
|
||||
if(F.intact) // Ff floor is intact, complain
|
||||
user << "You can't lay cable there unless the floor tiles are removed."
|
||||
return
|
||||
|
||||
else
|
||||
@@ -382,9 +705,8 @@
|
||||
C.add_fingerprint(user)
|
||||
C.updateicon()
|
||||
|
||||
C.powernet = new()
|
||||
powernets += C.powernet
|
||||
C.powernet.cables += C
|
||||
var/datum/powernet/PN = new()
|
||||
PN.add_cable(C)
|
||||
|
||||
C.mergeConnectedNetworks(C.d2)
|
||||
C.mergeConnectedNetworksOnTurf()
|
||||
@@ -396,15 +718,12 @@
|
||||
D.add_fingerprint(user)
|
||||
D.updateicon()
|
||||
|
||||
D.powernet = C.powernet
|
||||
D.powernet.cables += D
|
||||
|
||||
PN.add_cable(D)
|
||||
D.mergeConnectedNetworksOnTurf()
|
||||
|
||||
// do the normal stuff
|
||||
else
|
||||
///// Z-Level Stuff
|
||||
|
||||
for(var/obj/structure/cable/LC in F)
|
||||
if((LC.d1 == dirn && LC.d2 == 0 ) || ( LC.d2 == dirn && LC.d1 == 0))
|
||||
user << "There's already a cable at that position."
|
||||
@@ -414,32 +733,32 @@
|
||||
|
||||
C.cableColor(item_color)
|
||||
|
||||
C.d1 = 0
|
||||
//set up the new cable
|
||||
C.d1 = 0 //it's a O-X node cable
|
||||
C.d2 = dirn
|
||||
C.add_fingerprint(user)
|
||||
C.updateicon()
|
||||
|
||||
C.powernet = new()
|
||||
powernets += C.powernet
|
||||
C.powernet.cables += C
|
||||
//create a new powernet with the cable, if needed it will be merged later
|
||||
var/datum/powernet/PN = new()
|
||||
PN.add_cable(C)
|
||||
|
||||
C.mergeConnectedNetworks(C.d2)
|
||||
C.mergeConnectedNetworksOnTurf()
|
||||
C.mergeConnectedNetworks(C.d2) //merge the powernet with adjacents powernets
|
||||
C.mergeConnectedNetworksOnTurf() //merge the powernet with on turf powernets
|
||||
|
||||
if(C.d2 & (C.d2 - 1))// if the cable is layed diagonally, check the others 2 possible directions
|
||||
C.mergeDiagonalsNetworks(C.d2)
|
||||
|
||||
|
||||
use(1)
|
||||
if (C.shock(user, 50))
|
||||
if (prob(50)) //fail
|
||||
new/obj/item/stack/cable_coil(C.loc, 1, C.color)
|
||||
del(C)
|
||||
//src.laying = 1
|
||||
//last = C
|
||||
|
||||
del(C) // qdel
|
||||
|
||||
// called when cable_coil is click on an installed obj/cable
|
||||
|
||||
// or click on a turf that already contains a "node" cable
|
||||
/obj/item/stack/cable_coil/proc/cable_join(obj/structure/cable/C, mob/user)
|
||||
|
||||
var/turf/U = user.loc
|
||||
if(!isturf(U))
|
||||
return
|
||||
@@ -450,18 +769,20 @@
|
||||
return
|
||||
|
||||
if(get_dist(C, user) > 1) // make sure it's close enough
|
||||
user << "<span class='warning'>You can't lay cable at a place that far away.</span>"
|
||||
user << "You can't lay cable at a place that far away."
|
||||
return
|
||||
|
||||
|
||||
if(U == T) // do nothing if we clicked a cable we're standing on
|
||||
return // may change later if can think of something logical to do
|
||||
if(U == T) //if clicked on the turf we're standing on, try to put a cable in the direction we're facing
|
||||
turf_place(T,user)
|
||||
return
|
||||
|
||||
var/dirn = get_dir(C, user)
|
||||
|
||||
if(C.d1 == dirn || C.d2 == dirn) // one end of the clicked cable is pointing towards us
|
||||
// one end of the clicked cable is pointing towards us
|
||||
if(C.d1 == dirn || C.d2 == dirn)
|
||||
if(U.intact) // can't place a cable if the floor is complete
|
||||
user << "<span class='warning'>You can't lay cable there unless the floor tiles are removed.</span>"
|
||||
user << "You can't lay cable there unless the floor tiles are removed."
|
||||
return
|
||||
else
|
||||
// cable is pointing at us, we're standing on an open tile
|
||||
@@ -471,7 +792,7 @@
|
||||
|
||||
for(var/obj/structure/cable/LC in U) // check to make sure there's not a cable there already
|
||||
if(LC.d1 == fdirn || LC.d2 == fdirn)
|
||||
user << "<span class='warning'>There's already a cable at that position.</span>"
|
||||
user << "There's already a cable at that position."
|
||||
return
|
||||
|
||||
var/obj/structure/cable/NC = new(U)
|
||||
@@ -482,19 +803,27 @@
|
||||
NC.add_fingerprint()
|
||||
NC.updateicon()
|
||||
|
||||
if(C.powernet)
|
||||
NC.powernet = C.powernet
|
||||
NC.powernet.cables += NC
|
||||
NC.mergeConnectedNetworks(NC.d2)
|
||||
NC.mergeConnectedNetworksOnTurf()
|
||||
//create a new powernet with the cable, if needed it will be merged later
|
||||
var/datum/powernet/newPN = new()
|
||||
newPN.add_cable(NC)
|
||||
|
||||
NC.mergeConnectedNetworks(NC.d2) //merge the powernet with adjacents powernets
|
||||
NC.mergeConnectedNetworksOnTurf() //merge the powernet with on turf powernets
|
||||
|
||||
if(NC.d2 & (NC.d2 - 1))// if the cable is layed diagonally, check the others 2 possible directions
|
||||
NC.mergeDiagonalsNetworks(NC.d2)
|
||||
|
||||
use(1)
|
||||
|
||||
if (NC.shock(user, 50))
|
||||
if (prob(50)) //fail
|
||||
new/obj/item/stack/cable_coil(NC.loc, 1, NC.color)
|
||||
del(NC)
|
||||
del(NC) // qdel
|
||||
|
||||
return
|
||||
else if(C.d1 == 0) // exisiting cable doesn't point at our position, so see if it's a stub
|
||||
|
||||
// exisiting cable doesn't point at our position, so see if it's a stub
|
||||
else if(C.d1 == 0)
|
||||
// if so, make it a full cable pointing from it's old direction to our dirn
|
||||
var/nd1 = C.d2 // these will be the new directions
|
||||
var/nd2 = dirn
|
||||
@@ -509,7 +838,7 @@
|
||||
if(LC == C) // skip the cable we're interacting with
|
||||
continue
|
||||
if((LC.d1 == nd1 && LC.d2 == nd2) || (LC.d1 == nd2 && LC.d2 == nd1) ) // make sure no cable matches either direction
|
||||
user << "<span class='warning'>There's already a cable at that position.</span>"
|
||||
user << "There's already a cable at that position."
|
||||
return
|
||||
|
||||
|
||||
@@ -522,90 +851,30 @@
|
||||
C.updateicon()
|
||||
|
||||
|
||||
C.mergeConnectedNetworks(C.d1)
|
||||
C.mergeConnectedNetworks(C.d2)
|
||||
C.mergeConnectedNetworks(C.d1) //merge the powernets...
|
||||
C.mergeConnectedNetworks(C.d2) //...in the two new cable directions
|
||||
C.mergeConnectedNetworksOnTurf()
|
||||
|
||||
if(C.d1 & (C.d1 - 1))// if the cable is layed diagonally, check the others 2 possible directions
|
||||
C.mergeDiagonalsNetworks(C.d1)
|
||||
|
||||
if(C.d2 & (C.d2 - 1))// if the cable is layed diagonally, check the others 2 possible directions
|
||||
C.mergeDiagonalsNetworks(C.d2)
|
||||
|
||||
use(1)
|
||||
|
||||
if (C.shock(user, 50))
|
||||
if (prob(50)) //fail
|
||||
new/obj/item/stack/cable_coil(C.loc, 2, C.color)
|
||||
del(C)
|
||||
del(C) // qdel
|
||||
return
|
||||
|
||||
C.denode()// this call may have disconnected some cables that terminated on the centre of the turf, if so split the powernets.
|
||||
return
|
||||
|
||||
/obj/structure/cable/proc/mergeConnectedNetworks(var/direction)
|
||||
var/turf/TB
|
||||
if(!(d1 == direction || d2 == direction))
|
||||
return
|
||||
TB = get_step(src, direction)
|
||||
|
||||
for(var/obj/structure/cable/TC in TB)
|
||||
|
||||
if(!TC)
|
||||
continue
|
||||
|
||||
if(src == TC)
|
||||
continue
|
||||
|
||||
var/fdir = (!direction)? 0 : turn(direction, 180)
|
||||
|
||||
if(TC.d1 == fdir || TC.d2 == fdir)
|
||||
|
||||
if(!TC.powernet)
|
||||
TC.powernet = new()
|
||||
powernets += TC.powernet
|
||||
TC.powernet.cables += TC
|
||||
|
||||
if(powernet)
|
||||
merge_powernets(powernet,TC.powernet)
|
||||
else
|
||||
powernet = TC.powernet
|
||||
powernet.cables += src
|
||||
|
||||
|
||||
|
||||
|
||||
/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
|
||||
|
||||
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] = 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] = M
|
||||
|
||||
|
||||
obj/structure/cable/proc/cableColor(var/colorC)
|
||||
var/color_n = "#DD0000"
|
||||
if(colorC)
|
||||
color_n = colorC
|
||||
color = color_n
|
||||
//////////////////////////////
|
||||
// Misc.
|
||||
/////////////////////////////
|
||||
|
||||
/obj/item/stack/cable_coil/cut
|
||||
item_state = "coil2"
|
||||
@@ -615,7 +884,7 @@ obj/structure/cable/proc/cableColor(var/colorC)
|
||||
src.amount = rand(1,2)
|
||||
pixel_x = rand(-2,2)
|
||||
pixel_y = rand(-2,2)
|
||||
updateicon()
|
||||
update_icon()
|
||||
update_wclass()
|
||||
|
||||
/obj/item/stack/cable_coil/yellow
|
||||
@@ -642,27 +911,3 @@ obj/structure/cable/proc/cableColor(var/colorC)
|
||||
/obj/item/stack/cable_coil/random/New()
|
||||
item_color = pick(COLOR_RED, COLOR_BLUE, COLOR_GREEN, COLOR_WHITE, COLOR_PINK, COLOR_YELLOW, COLOR_CYAN)
|
||||
..()
|
||||
|
||||
/obj/item/stack/cable_coil/attack(mob/M as mob, mob/user as mob)
|
||||
if(hasorgans(M))
|
||||
|
||||
var/datum/organ/external/S = M:get_organ(user.zone_sel.selecting)
|
||||
if(!(S.status & ORGAN_ROBOT) || user.a_intent != "help")
|
||||
return ..()
|
||||
|
||||
if(istype(M,/mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.species.flags & IS_SYNTHETIC)
|
||||
if(M == user)
|
||||
user << "\red You can't repair damage to your own body - it's against OH&S."
|
||||
return
|
||||
|
||||
if(S.burn_dam > 0 && use(1))
|
||||
S.heal_damage(0,15,0,1)
|
||||
user.visible_message("\red \The [user] repairs some burn damage on \the [M]'s [S.display_name] with \the [src].")
|
||||
return
|
||||
else
|
||||
user << "Nothing to fix!"
|
||||
|
||||
else
|
||||
return ..()
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
icon_state = "tracker" //ICON stolen from solar tracker. There is no need to make new texture for debug item
|
||||
anchored = 1
|
||||
density = 1
|
||||
directwired = 1
|
||||
var/power_generation_rate = 2000000 //Defaults to 2MW of power. Should be enough to run SMES charging on full 2 times.
|
||||
var/powernet_connection_failed = 0
|
||||
|
||||
|
||||
@@ -48,7 +48,6 @@ display round(lastgen) and phorontank amount
|
||||
icon_state = "portgen0"
|
||||
density = 1
|
||||
anchored = 0
|
||||
directwired = 0
|
||||
use_power = 0
|
||||
|
||||
var/active = 0
|
||||
|
||||
@@ -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,19 +19,23 @@
|
||||
disconnect_from_network()
|
||||
..()
|
||||
|
||||
///////////////////////////////
|
||||
// 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)
|
||||
return powernet.draw_power(amount)
|
||||
return 0
|
||||
|
||||
/obj/machinery/power/proc/surplus()
|
||||
if(powernet)
|
||||
return powernet.surplus()
|
||||
return powernet.avail-powernet.load
|
||||
else
|
||||
return 0
|
||||
|
||||
@@ -35,18 +45,18 @@
|
||||
else
|
||||
return 0
|
||||
|
||||
/obj/machinery/power/proc/disconnect_terminal() // machines without a terminal will just return, no harm no fowl.
|
||||
return
|
||||
|
||||
// returns true if the area has power on given channel (or doesn't require power).
|
||||
// defaults to power_channel
|
||||
|
||||
/obj/machinery/proc/powered(var/chan = -1)
|
||||
/obj/machinery/proc/powered(var/chan = -1) // defaults to power_channel
|
||||
|
||||
if(!src.loc)
|
||||
return 0
|
||||
|
||||
//This is bad. This makes machines which are switched off not update their stat flag correctly when power_change() is called.
|
||||
//If use_power is 0, then you probably shouldn't be checking power to begin with.
|
||||
//if(!use_power)
|
||||
// return 1
|
||||
if(!use_power)
|
||||
return 1
|
||||
|
||||
var/area/A = src.loc.loc // make sure it's in an area
|
||||
if(!A || !isarea(A) || !A.master)
|
||||
@@ -56,75 +66,127 @@
|
||||
return A.master.powered(chan) // return power status of the area
|
||||
|
||||
// increment the power usage stats for an area
|
||||
|
||||
/obj/machinery/proc/use_power(var/amount, var/chan = -1, var/autocalled = 0) // defaults to power_channel
|
||||
var/area/A = src.loc.loc // make sure it's in an area
|
||||
/obj/machinery/proc/use_power(var/amount, var/chan = -1) // defaults to power_channel
|
||||
var/area/A = get_area(src) // make sure it's in an area
|
||||
if(!A || !isarea(A) || !A.master)
|
||||
return
|
||||
if(chan == -1)
|
||||
chan = power_channel
|
||||
A.master.use_power(amount, chan)
|
||||
if(!autocalled)
|
||||
log_power_update_request(A.master, src)
|
||||
A.master.powerupdate = 2 // Decremented by 2 each GC tick, since it's not auto power change we're going to update power twice.
|
||||
return 1
|
||||
|
||||
//The master_area optional argument can be used to save on a lot of processing if the master area is already known. This is mainly intended for when this proc is called by the master controller.
|
||||
/obj/machinery/proc/power_change(var/area/master_area = null) // called whenever the power settings of the containing area change
|
||||
/obj/machinery/proc/power_change() // called whenever the power settings of the containing area change
|
||||
// by default, check equipment channel & set flag
|
||||
// can override if needed
|
||||
var/has_power
|
||||
if (master_area)
|
||||
has_power = master_area.powered(power_channel)
|
||||
else
|
||||
has_power = powered(power_channel)
|
||||
|
||||
if(has_power)
|
||||
if(powered(power_channel))
|
||||
stat &= ~NOPOWER
|
||||
else
|
||||
|
||||
stat |= NOPOWER
|
||||
return
|
||||
|
||||
// the powernet datum
|
||||
// each contiguous network of cables & nodes
|
||||
// connect the machine to a powernet if a node cable is present on the turf
|
||||
/obj/machinery/power/proc/connect_to_network()
|
||||
var/turf/T = src.loc
|
||||
if(!T || !istype(T))
|
||||
return 0
|
||||
|
||||
var/obj/structure/cable/C = T.get_cable_node() //check if we have a node cable on the machine turf, the first found is picked
|
||||
if(!C || !C.powernet)
|
||||
return 0
|
||||
|
||||
// rebuild all power networks from scratch
|
||||
|
||||
/hook/startup/proc/buildPowernets()
|
||||
return makepowernets()
|
||||
|
||||
/proc/makepowernets()
|
||||
for(var/datum/powernet/PN in powernets)
|
||||
del(PN)
|
||||
powernets.Cut()
|
||||
|
||||
for(var/obj/structure/cable/PC in cable_list)
|
||||
if(!PC.powernet)
|
||||
PC.powernet = new()
|
||||
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
|
||||
|
||||
C.powernet.add_machine(src)
|
||||
return 1
|
||||
|
||||
// remove and disconnect the machine from its current powernet
|
||||
/obj/machinery/power/proc/disconnect_from_network()
|
||||
if(!powernet)
|
||||
return 0
|
||||
powernet.remove_machine(src)
|
||||
return 1
|
||||
|
||||
// attach a wire to a power machine - leads from the turf you are standing on
|
||||
//almost never called, overwritten by all power machines but terminal and generator
|
||||
/obj/machinery/power/attackby(obj/item/weapon/W, mob/user)
|
||||
|
||||
if(istype(W, /obj/item/stack/cable_coil))
|
||||
|
||||
var/obj/item/stack/cable_coil/coil = W
|
||||
|
||||
var/turf/T = user.loc
|
||||
|
||||
if(T.intact || !istype(T, /turf/simulated/floor))
|
||||
return
|
||||
|
||||
if(get_dist(src, user) > 1)
|
||||
return
|
||||
|
||||
coil.turf_place(T, user)
|
||||
return
|
||||
else
|
||||
..()
|
||||
return
|
||||
|
||||
///////////////////////////////////////////
|
||||
// Powernet handling helpers
|
||||
//////////////////////////////////////////
|
||||
|
||||
//returns all the cables WITHOUT a powernet in neighbors turfs,
|
||||
//pointing towards the turf the machine is located at
|
||||
/obj/machinery/power/proc/get_connections()
|
||||
|
||||
. = list()
|
||||
|
||||
var/cdir
|
||||
var/turf/T
|
||||
|
||||
for(var/card in cardinal)
|
||||
T = get_step(loc,card)
|
||||
cdir = get_dir(T,loc)
|
||||
|
||||
for(var/obj/structure/cable/C in T)
|
||||
if(C.powernet) continue
|
||||
if(C.d1 == cdir || C.d2 == cdir)
|
||||
. += C
|
||||
return .
|
||||
|
||||
//returns all the cables in neighbors turfs,
|
||||
//pointing towards the turf the machine is located at
|
||||
/obj/machinery/power/proc/get_marked_connections()
|
||||
|
||||
. = list()
|
||||
|
||||
var/cdir
|
||||
var/turf/T
|
||||
|
||||
for(var/card in cardinal)
|
||||
T = get_step(loc,card)
|
||||
cdir = get_dir(T,loc)
|
||||
|
||||
for(var/obj/structure/cable/C in T)
|
||||
if(C.d1 == cdir || C.d2 == cdir)
|
||||
. += C
|
||||
return .
|
||||
|
||||
//returns all the NODES (O-X) cables WITHOUT a powernet in the turf the machine is located at
|
||||
/obj/machinery/power/proc/get_indirect_connections()
|
||||
. = list()
|
||||
for(var/obj/structure/cable/C in loc)
|
||||
if(C.powernet) continue
|
||||
if(C.d1 == 0) // the cable is a node cable
|
||||
. += C
|
||||
return .
|
||||
|
||||
///////////////////////////////////////////
|
||||
// GLOBAL PROCS for powernets handling
|
||||
//////////////////////////////////////////
|
||||
|
||||
|
||||
// returns a list of all power-related objects (nodes, cable, junctions) in turf,
|
||||
// excluding source, that match the direction d
|
||||
// if unmarked==1, only return those with no powernet
|
||||
/proc/power_list(var/turf/T, var/source, var/d, var/unmarked=0)
|
||||
/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)
|
||||
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)
|
||||
@@ -134,16 +196,15 @@
|
||||
else
|
||||
Zdir = 999
|
||||
///// Z-Level Stuff
|
||||
// world.log << "d=[d] fdir=[fdir]"
|
||||
for(var/AM in T)
|
||||
if(AM == source) continue //we don't want to return source
|
||||
|
||||
if(istype(AM,/obj/machinery/power))
|
||||
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(P.directwired || (d == 0))
|
||||
if(d == 0)
|
||||
. += P
|
||||
|
||||
else if(istype(AM,/obj/structure/cable))
|
||||
@@ -154,115 +215,82 @@
|
||||
if(C.d1 == fdir || C.d2 == fdir || C.d1 == Zdir || C.d2 == Zdir)
|
||||
///// Z-Level Stuff
|
||||
. += C
|
||||
else if(C.d1 == turn(C.d2, 180))
|
||||
else if(C.d1 == d || C.d2 == d)
|
||||
. += C
|
||||
return .
|
||||
|
||||
/hook/startup/proc/buildPowernets()
|
||||
return makepowernets()
|
||||
|
||||
/obj/structure/cable/proc/get_connections()
|
||||
. = list() // this will be a list of all connected power objects
|
||||
var/turf/T = loc
|
||||
// rebuild all power networks from scratch - only called at world creation or by the admin verb
|
||||
/proc/makepowernets()
|
||||
for(var/datum/powernet/PN in powernets)
|
||||
del(PN)
|
||||
powernets.Cut()
|
||||
|
||||
///// Z-Level Stuff
|
||||
if(d1)
|
||||
if(d1 <= 10)
|
||||
T = get_step(src, d1)
|
||||
if(T)
|
||||
. += power_list(T, src, d1, 1)
|
||||
else if (d1 == 11 || d1 == 12)
|
||||
var/turf/controllerlocation = locate(1, 1, z)
|
||||
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
|
||||
if(controller.up && d1 == 12)
|
||||
T = locate(src.x, src.y, controller.up_target)
|
||||
if(T)
|
||||
. += power_list(T, src, 11, 1)
|
||||
if(controller.down && d1 == 11)
|
||||
T = locate(src.x, src.y, controller.down_target)
|
||||
if(T)
|
||||
. += power_list(T, src, 12, 1)
|
||||
else if(!d1)
|
||||
if(T)
|
||||
. += power_list(T, src, d1, 1)
|
||||
|
||||
if(d2 == 11 || d2 == 12)
|
||||
var/turf/controllerlocation = locate(1, 1, z)
|
||||
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
|
||||
if(controller.up && d2 == 12)
|
||||
T = locate(src.x, src.y, controller.up_target)
|
||||
if(T)
|
||||
. += power_list(T, src, 11, 1)
|
||||
if(controller.down && d2 == 11)
|
||||
T = locate(src.x, src.y, controller.down_target)
|
||||
if(T)
|
||||
. += power_list(T, src, 12, 1)
|
||||
else
|
||||
T = get_step(src, d2)
|
||||
if(T)
|
||||
. += power_list(T, src, d2, 1)
|
||||
///// Z-Level Stuff
|
||||
|
||||
return .
|
||||
|
||||
|
||||
/obj/machinery/power/proc/get_connections()
|
||||
|
||||
. = list()
|
||||
|
||||
if(!directwired)
|
||||
return get_indirect_connections()
|
||||
|
||||
var/cdir
|
||||
|
||||
for(var/card in cardinal)
|
||||
var/turf/T = get_step(loc,card)
|
||||
cdir = get_dir(T,loc)
|
||||
|
||||
for(var/obj/structure/cable/C in T)
|
||||
if(C.powernet) continue
|
||||
if(C.d1 == cdir || C.d2 == cdir)
|
||||
. += C
|
||||
return .
|
||||
|
||||
/obj/machinery/power/proc/get_indirect_connections()
|
||||
. = list()
|
||||
for(var/obj/structure/cable/C in loc)
|
||||
if(C.powernet) continue
|
||||
if(C.d1 == 0)
|
||||
. += C
|
||||
return .
|
||||
|
||||
/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
|
||||
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
|
||||
|
||||
/obj/machinery/power/proc/disconnect_from_network()
|
||||
if(!powernet)
|
||||
//world << " no powernet"
|
||||
return 0
|
||||
powernet.nodes -= src
|
||||
powernet = null
|
||||
//world << "powernet null"
|
||||
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
|
||||
|
||||
/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
|
||||
worklist+=O //start propagating from the passed object
|
||||
|
||||
/area/proc/get_apc()
|
||||
for(var/area/RA in src.related)
|
||||
var/obj/machinery/power/apc/FINDME = locate() in RA
|
||||
if (FINDME)
|
||||
return FINDME
|
||||
while(index<=worklist.len) //until we've exhausted all power objects
|
||||
P = worklist[index] //get the next power object found
|
||||
index++
|
||||
|
||||
if( istype(P,/obj/structure/cable))
|
||||
var/obj/structure/cable/C = P
|
||||
if(C.powernet != PN) //add it to the powernet, if it isn't already there
|
||||
PN.add_cable(C)
|
||||
worklist |= C.get_connections() //get adjacents power objects, with or without a powernet
|
||||
|
||||
else if(P.anchored && istype(P,/obj/machinery/power))
|
||||
var/obj/machinery/power/M = P
|
||||
found_machines |= M //we wait until the powernet is fully propagates to connect the machines
|
||||
|
||||
else
|
||||
continue
|
||||
|
||||
//now that the powernet is set, connect found machines to it
|
||||
for(var/obj/machinery/power/PM in found_machines)
|
||||
if(!PM.connect_to_network()) //couldn't find a node on its turf...
|
||||
PM.disconnect_from_network() //... so disconnect if already on a powernet
|
||||
|
||||
|
||||
//Merge two powernets, the bigger (in cable length term) absorbing the other
|
||||
/proc/merge_powernets(var/datum/powernet/net1, var/datum/powernet/net2)
|
||||
if(!net1 || !net2) //if one of the powernet doesn't exist, return
|
||||
return
|
||||
|
||||
if(net1 == net2) //don't merge same powernets
|
||||
return
|
||||
|
||||
//We assume net1 is larger. If net2 is in fact larger we are just going to make them switch places to reduce on code.
|
||||
if(net1.cables.len < net2.cables.len) //net2 is larger than net1. Let's switch them around
|
||||
var/temp = net1
|
||||
net1 = net2
|
||||
net2 = temp
|
||||
|
||||
//merge net2 into net1
|
||||
for(var/obj/structure/cable/Cable in net2.cables) //merge cables
|
||||
net1.add_cable(Cable)
|
||||
|
||||
for(var/obj/machinery/power/Node in net2.nodes) //merge power machines
|
||||
if(!Node.connect_to_network())
|
||||
Node.disconnect_from_network() //if somehow we can't connect the machine to the new powernet, disconnect it from the old nonetheless
|
||||
|
||||
return net1
|
||||
|
||||
//Determines how strong could be shock, deals damage to mob, uses power.
|
||||
//M is a mob who touched wire/whatever
|
||||
@@ -271,17 +299,11 @@
|
||||
//No animations will be performed by this proc.
|
||||
/proc/electrocute_mob(mob/living/carbon/M as mob, var/power_source, var/obj/source, var/siemens_coeff = 1.0)
|
||||
if(istype(M.loc,/obj/mecha)) return 0 //feckin mechs are dumb
|
||||
|
||||
//This is for performance optimization only.
|
||||
//DO NOT modify siemens_coeff here. That is checked in human/electrocute_act()
|
||||
if(istype(M,/mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.species.insulated)
|
||||
return 0
|
||||
else if(H.gloves)
|
||||
if(H.gloves)
|
||||
var/obj/item/clothing/gloves/G = H.gloves
|
||||
if(G.siemens_coefficient == 0)
|
||||
return 0 //to avoid spamming with insulated glvoes on
|
||||
if(G.siemens_coefficient == 0) return 0 //to avoid spamming with insulated glvoes on
|
||||
|
||||
var/area/source_area
|
||||
if(istype(power_source,/area))
|
||||
@@ -327,11 +349,10 @@
|
||||
var/drained_energy = drained_hp*20
|
||||
|
||||
if (source_area)
|
||||
source_area.use_power(drained_energy)
|
||||
source_area.use_power(drained_energy/CELLRATE)
|
||||
else if (istype(power_source,/datum/powernet))
|
||||
//var/drained_power = drained_energy/CELLRATE //convert from "joules" to "watts" <<< NO. THIS IS WRONG. CELLRATE DOES NOT CONVERT TO OR FROM JOULES.
|
||||
PN.draw_power(drained_energy)
|
||||
var/drained_power = drained_energy/CELLRATE //convert from "joules" to "watts"
|
||||
PN.load+=drained_power
|
||||
else if (istype(power_source, /obj/item/weapon/cell))
|
||||
cell.use(drained_energy*CELLRATE) //convert to units of charge.
|
||||
cell.use(drained_energy)
|
||||
return drained_energy
|
||||
|
||||
|
||||
@@ -1,29 +1,80 @@
|
||||
/datum/powernet
|
||||
var/list/cables = list() // all cables & junctions
|
||||
var/list/nodes = list() // all APCs & sources
|
||||
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/newload = 0
|
||||
var/load = 0
|
||||
var/newavail = 0
|
||||
var/avail = 0
|
||||
var/viewload = 0
|
||||
var/number = 0
|
||||
|
||||
var/perapc = 0 // per-apc avilability
|
||||
var/perapc_excess = 0
|
||||
var/netexcess = 0
|
||||
var/netexcess = 0 // excess power on the powernet (typically avail-load)
|
||||
|
||||
/datum/powernet/proc/process()
|
||||
load = newload
|
||||
newload = 0
|
||||
avail = newavail
|
||||
newavail = 0
|
||||
/datum/powernet/New()
|
||||
powernets += src
|
||||
|
||||
/datum/powernet/Del()
|
||||
powernets -= src
|
||||
|
||||
//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
|
||||
|
||||
|
||||
viewload = 0.8*viewload + 0.2*load
|
||||
|
||||
viewload = round(viewload)
|
||||
//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
|
||||
|
||||
//handles the power changes in the powernet
|
||||
//called every ticks by the powernet controller
|
||||
/datum/powernet/proc/reset()
|
||||
var/numapc = 0
|
||||
|
||||
if(nodes && nodes.len) // Added to fix a bad list bug -- TLE
|
||||
@@ -41,165 +92,24 @@
|
||||
perapc_excess += min(netexcess/numapc, (avail - perapc) - perapc_excess)
|
||||
else
|
||||
perapc_excess = 0
|
||||
|
||||
|
||||
perapc = avail/numapc + perapc_excess
|
||||
|
||||
if( netexcess > 100) // if there was excess power last cycle
|
||||
if(nodes && nodes.len)
|
||||
for(var/obj/machinery/power/smes/S in nodes) // find the SMESes in the network
|
||||
if(S.powernet == src)
|
||||
S.restore() // and restore some of the power that was used
|
||||
else
|
||||
error("[S.name] (\ref[S]) had a [S.powernet ? "different (\ref[S.powernet])" : "null"] powernet to our powernet (\ref[src]).")
|
||||
nodes.Remove(S)
|
||||
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)
|
||||
|
||||
|
||||
|
||||
//Returns the amount of available power
|
||||
/datum/powernet/proc/surplus()
|
||||
return max(avail - newload, 0)
|
||||
|
||||
//Returns the amount of excess power (before refunding to SMESs) from last tick.
|
||||
//This is for machines that might adjust their power consumption using this data.
|
||||
/datum/powernet/proc/last_surplus()
|
||||
return max(avail - load, 0)
|
||||
|
||||
//Attempts to draw power from a powernet. Returns the actual amount of power drawn
|
||||
/datum/powernet/proc/draw_power(var/requested_amount)
|
||||
var/surplus = max(avail - newload, 0)
|
||||
var/actual_draw = min(requested_amount, surplus)
|
||||
newload += actual_draw
|
||||
|
||||
return actual_draw
|
||||
|
||||
// cut a powernet at this cable object
|
||||
/datum/powernet/proc/cut_cable(var/obj/structure/cable/C)
|
||||
var/turf/T1 = C.loc
|
||||
if(!T1) return
|
||||
var/node = 0
|
||||
if(C.d1 == 0)
|
||||
node = 1
|
||||
|
||||
var/turf/T2
|
||||
if(C.d2) T2 = get_step(T1, C.d2)
|
||||
if(C.d1) T1 = get_step(T1, C.d1)
|
||||
|
||||
|
||||
var/list/P1 = power_list(T1, C, C.d1) // what joins on to cut cable in dir1
|
||||
var/list/P2 = power_list(T2, C, C.d2) // what joins on to cut cable in dir2
|
||||
|
||||
// if(Debug)
|
||||
// for(var/obj/O in P1)
|
||||
// world.log << "P1: [O] at [O.x] [O.y] : [istype(O, /obj/structure/cable) ? "[O:d1]/[O:d2]" : null] "
|
||||
// for(var/obj/O in P2)
|
||||
// world.log << "P2: [O] at [O.x] [O.y] : [istype(O, /obj/structure/cable) ? "[O:d1]/[O:d2]" : null] "
|
||||
|
||||
|
||||
if(P1.len == 0 || P2.len == 0)//if nothing in either list, then the cable was an endpoint no need to rebuild the powernet,
|
||||
cables -= C //just remove cut cable from the list
|
||||
// if(Debug) world.log << "Was end of cable"
|
||||
return
|
||||
|
||||
//null the powernet reference of all cables & nodes in this powernet
|
||||
var/i=1
|
||||
while(i<=cables.len)
|
||||
var/obj/structure/cable/Cable = cables[i]
|
||||
if(Cable)
|
||||
Cable.powernet = null
|
||||
if(Cable == C)
|
||||
cables.Cut(i,i+1)
|
||||
continue
|
||||
i++
|
||||
i=1
|
||||
while(i<=nodes.len)
|
||||
var/obj/machinery/power/Node = nodes[i]
|
||||
if(Node)
|
||||
Node.powernet = null
|
||||
i++
|
||||
|
||||
// remove the cut cable from the network
|
||||
// C.netnum = -1
|
||||
|
||||
C.loc = null
|
||||
|
||||
powernet_nextlink(P1[1], src) // propagate network from 1st side of cable, using current netnum //TODO?
|
||||
|
||||
// now test to see if propagation reached to the other side
|
||||
// if so, then there's a loop in the network
|
||||
var/notlooped = 0
|
||||
for(var/O in P2)
|
||||
if( istype(O, /obj/machinery/power) )
|
||||
var/obj/machinery/power/Machine = O
|
||||
if(Machine.powernet != src)
|
||||
notlooped = 1
|
||||
break
|
||||
else if( istype(O, /obj/structure/cable) )
|
||||
var/obj/structure/cable/Cable = O
|
||||
if(Cable.powernet != src)
|
||||
notlooped = 1
|
||||
break
|
||||
|
||||
if(notlooped)
|
||||
// not looped, so make a new powernet
|
||||
var/datum/powernet/PN = new()
|
||||
powernets += PN
|
||||
|
||||
// if(Debug) world.log << "Was not looped: spliting PN#[number] ([cables.len];[nodes.len])"
|
||||
|
||||
i=1
|
||||
while(i<=cables.len)
|
||||
var/obj/structure/cable/Cable = cables[i]
|
||||
if(Cable && !Cable.powernet) // non-connected cables will have powernet=null, since they weren't reached by propagation
|
||||
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
|
||||
//reset the powernet
|
||||
load = 0
|
||||
avail = newavail
|
||||
newavail = 0
|
||||
|
||||
/datum/powernet/proc/get_electrocute_damage()
|
||||
switch(avail)/*
|
||||
if (1300000 to INFINITY)
|
||||
return min(rand(70,150),rand(70,150))
|
||||
if (750000 to 1300000)
|
||||
return min(rand(50,115),rand(50,115))
|
||||
if (100000 to 750000-1)
|
||||
return min(rand(35,101),rand(35,101))
|
||||
if (75000 to 100000-1)
|
||||
return min(rand(30,95),rand(30,95))
|
||||
if (50000 to 75000-1)
|
||||
return min(rand(25,80),rand(25,80))
|
||||
if (25000 to 50000-1)
|
||||
return min(rand(20,70),rand(20,70))
|
||||
if (10000 to 25000-1)
|
||||
return min(rand(20,65),rand(20,65))
|
||||
if (1000 to 10000-1)
|
||||
return min(rand(10,20),rand(10,20))*/
|
||||
switch(avail)
|
||||
if (1000000 to INFINITY)
|
||||
return min(rand(50,160),rand(50,160))
|
||||
if (200000 to 1000000)
|
||||
@@ -213,53 +123,23 @@
|
||||
else
|
||||
return 0
|
||||
|
||||
/proc/powernet_nextlink(var/obj/O, var/datum/powernet/PN)
|
||||
var/list/P
|
||||
////////////////////////////////////////////////
|
||||
// Misc.
|
||||
///////////////////////////////////////////////
|
||||
|
||||
while(1)
|
||||
if( istype(O,/obj/structure/cable) )
|
||||
var/obj/structure/cable/C = O
|
||||
C.powernet = PN
|
||||
P = C.get_connections()
|
||||
|
||||
else if(O.anchored && istype(O,/obj/machinery/power))
|
||||
var/obj/machinery/power/M = O
|
||||
M.powernet = PN
|
||||
P = M.get_connections()
|
||||
// return a knot cable (O-X) if one is present in the turf
|
||||
// null if there's none
|
||||
/turf/proc/get_cable_node()
|
||||
if(!istype(src, /turf/simulated/floor))
|
||||
return null
|
||||
for(var/obj/structure/cable/C in src)
|
||||
if(C.d1 == 0)
|
||||
return C
|
||||
return null
|
||||
|
||||
else
|
||||
return
|
||||
|
||||
if(P.len == 0) return
|
||||
|
||||
O = P[1]
|
||||
|
||||
for(var/L = 2 to P.len)
|
||||
powernet_nextlink(P[L], PN)
|
||||
|
||||
//The powernet that calls this proc will consume the other powernet - Rockdtben
|
||||
//TODO: rewrite so the larger net absorbs the smaller net
|
||||
/proc/merge_powernets(var/datum/powernet/net1, var/datum/powernet/net2)
|
||||
if(!net1 || !net2) return
|
||||
if(net1 == net2) return
|
||||
|
||||
//We assume net1 is larger. If net2 is in fact larger we are just going to make them switch places to reduce on code.
|
||||
if(net1.cables.len < net2.cables.len) //net2 is larger than net1. Let's switch them around
|
||||
var/temp = net1
|
||||
net1 = net2
|
||||
net2 = temp
|
||||
|
||||
for(var/i=1,i<=net2.nodes.len,i++) //merge net2 into net1
|
||||
var/obj/machinery/power/Node = net2.nodes[i]
|
||||
if(Node)
|
||||
Node.powernet = net1
|
||||
net1.nodes[Node] = Node
|
||||
|
||||
for(var/i=1,i<=net2.cables.len,i++)
|
||||
var/obj/structure/cable/Cable = net2.cables[i]
|
||||
if(Cable)
|
||||
Cable.powernet = net1
|
||||
net1.cables += Cable
|
||||
|
||||
del(net2)
|
||||
return net1
|
||||
/area/proc/get_apc()
|
||||
for(var/area/RA in src.related)
|
||||
var/obj/machinery/power/apc/FINDME = locate() in RA
|
||||
if (FINDME)
|
||||
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/phoron/P = null
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
..()
|
||||
if(state == 2 && anchored)
|
||||
connect_to_network()
|
||||
src.directwired = 1
|
||||
|
||||
/obj/machinery/power/emitter/Del()
|
||||
message_admins("Emitter deleted at ([x],[y],[z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)",0,1)
|
||||
@@ -106,7 +105,8 @@
|
||||
return
|
||||
if(((src.last_shot + src.fire_delay) <= world.time) && (src.active == 1))
|
||||
|
||||
if(surplus() >= active_power_usage && add_load(active_power_usage) >= active_power_usage) //does the laser have enough power to shoot?
|
||||
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()
|
||||
@@ -125,13 +125,13 @@
|
||||
else
|
||||
src.fire_delay = rand(min_burst_delay, max_burst_delay)
|
||||
src.shot_number = 0
|
||||
|
||||
|
||||
//need to calculate the power per shot as the emitter doesn't fire continuously.
|
||||
var/burst_time = (min_burst_delay + max_burst_delay)/2 + 2*(burst_shots-1)
|
||||
var/power_per_shot = active_power_usage * (burst_time/10) / burst_shots
|
||||
var/obj/item/projectile/beam/emitter/A = new /obj/item/projectile/beam/emitter( src.loc )
|
||||
A.damage = round(power_per_shot/EMITTER_DAMAGE_POWER_TRANSFER)
|
||||
|
||||
|
||||
playsound(src.loc, 'sound/weapons/emitter.ogg', 25, 1)
|
||||
if(prob(35))
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
@@ -198,7 +198,6 @@
|
||||
state = 2
|
||||
user << "You weld the [src] to the floor."
|
||||
connect_to_network()
|
||||
src.directwired = 1
|
||||
else
|
||||
user << "\red You need more welding fuel to complete this task."
|
||||
if(2)
|
||||
@@ -212,7 +211,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
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
//TODO: Add a meter to tell players how much charge we are actually getting, and only set charging to 0 when we are unable to get any charge at all.
|
||||
if(chargemode)
|
||||
var/target_load = min((capacity-charge)/SMESRATE, chargelevel) // charge at set rate, limited to spare capacity
|
||||
var/actual_load = add_load(target_load) // add the load to the terminal side network
|
||||
var/actual_load = draw_power(target_load) // add the load to the terminal side network
|
||||
charge += actual_load * SMESRATE // increase the charge
|
||||
|
||||
if (actual_load >= target_load) // did the powernet have enough power available for us?
|
||||
@@ -174,7 +174,7 @@
|
||||
return 1
|
||||
|
||||
|
||||
/obj/machinery/power/smes/add_load(var/amount)
|
||||
/obj/machinery/power/smes/draw_power(var/amount)
|
||||
if(terminal && terminal.powernet)
|
||||
return terminal.powernet.draw_power(amount)
|
||||
return 0
|
||||
@@ -385,11 +385,4 @@
|
||||
charge = 5000000
|
||||
..()
|
||||
|
||||
/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
|
||||
|
||||
|
||||
#undef SMESRATE
|
||||
|
||||
@@ -1,20 +1,8 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33
|
||||
|
||||
#define SOLAR_MAX_DIST 40
|
||||
#define SOLARGENRATE 1500
|
||||
|
||||
var/list/solars_list = list()
|
||||
|
||||
// This will choose whether to get the solar list from the powernet or the powernet nodes,
|
||||
// depending on the size of the nodes.
|
||||
/obj/machinery/power/proc/get_solars_powernet()
|
||||
if(!powernet)
|
||||
return list()
|
||||
if(solars_list.len < powernet.nodes)
|
||||
return solars_list
|
||||
else
|
||||
return powernet.nodes
|
||||
|
||||
/obj/machinery/power/solar
|
||||
name = "solar panel"
|
||||
desc = "A solar electrical generator."
|
||||
@@ -22,7 +10,6 @@ var/list/solars_list = list()
|
||||
icon_state = "sp_base"
|
||||
anchored = 1
|
||||
density = 1
|
||||
directwired = 1
|
||||
use_power = 0
|
||||
idle_power_usage = 0
|
||||
active_power_usage = 0
|
||||
@@ -30,26 +17,32 @@ var/list/solars_list = list()
|
||||
var/health = 10
|
||||
var/obscured = 0
|
||||
var/sunfrac = 0
|
||||
var/adir = SOUTH
|
||||
var/ndir = SOUTH
|
||||
var/adir = SOUTH // actual dir
|
||||
var/ndir = SOUTH // target dir
|
||||
var/turn_angle = 0
|
||||
var/obj/machinery/power/solar_control/control = null
|
||||
|
||||
/obj/machinery/power/solar/New(var/turf/loc, var/obj/item/solar_assembly/S, var/process = 1)
|
||||
/obj/machinery/power/solar/New(var/turf/loc, var/obj/item/solar_assembly/S)
|
||||
..(loc)
|
||||
Make(S)
|
||||
connect_to_network(process)
|
||||
connect_to_network()
|
||||
|
||||
|
||||
/obj/machinery/power/solar/disconnect_from_network()
|
||||
/obj/machinery/power/solar/Del()
|
||||
unset_control() //remove from control computer
|
||||
..()
|
||||
solars_list.Remove(src)
|
||||
|
||||
/obj/machinery/power/solar/connect_to_network(var/process)
|
||||
..()
|
||||
if(process)
|
||||
solars_list.Add(src)
|
||||
//set the control of the panel to a given computer if closer than SOLAR_MAX_DIST
|
||||
/obj/machinery/power/solar/proc/set_control(var/obj/machinery/power/solar_control/SC)
|
||||
if(SC && (get_dist(src, SC) > SOLAR_MAX_DIST))
|
||||
return 0
|
||||
control = SC
|
||||
return 1
|
||||
|
||||
//set the control of the panel to null and removes it from the control list of the previous control computer if needed
|
||||
/obj/machinery/power/solar/proc/unset_control()
|
||||
if(control)
|
||||
control.connected_panels.Remove(src)
|
||||
control = null
|
||||
|
||||
/obj/machinery/power/solar/proc/Make(var/obj/item/solar_assembly/S)
|
||||
if(!S)
|
||||
@@ -57,14 +50,17 @@ var/list/solars_list = list()
|
||||
S.glass_type = /obj/item/stack/sheet/glass
|
||||
S.anchored = 1
|
||||
S.loc = src
|
||||
if(S.glass_type == /obj/item/stack/sheet/rglass) //if the panel is in reinforced glass
|
||||
health *= 2 //this need to be placed here, because panels already on the map don't have an assembly linked to
|
||||
update_icon()
|
||||
|
||||
|
||||
|
||||
/obj/machinery/power/solar/attackby(obj/item/weapon/W, mob/user)
|
||||
|
||||
if(iscrowbar(W))
|
||||
if(istype(W, /obj/item/weapon/crowbar))
|
||||
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
|
||||
user.visible_message("<span class='notice'>[user] begins to take the glass off the solar panel.</span>")
|
||||
if(do_after(user, 50))
|
||||
var/obj/item/solar_assembly/S = locate() in src
|
||||
if(S)
|
||||
@@ -72,7 +68,7 @@ var/list/solars_list = list()
|
||||
S.give_glass()
|
||||
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
user.visible_message("<span class='notice'>[user] takes the glass off the solar panel.</span>")
|
||||
del(src)
|
||||
del(src) // qdel
|
||||
return
|
||||
else if (W)
|
||||
src.add_fingerprint(user)
|
||||
@@ -94,7 +90,7 @@ var/list/solars_list = list()
|
||||
else
|
||||
new /obj/item/weapon/shard(src.loc)
|
||||
new /obj/item/weapon/shard(src.loc)
|
||||
del(src)
|
||||
del(src) // qdel
|
||||
return
|
||||
return
|
||||
|
||||
@@ -109,65 +105,64 @@ var/list/solars_list = list()
|
||||
src.dir = angle2dir(adir)
|
||||
return
|
||||
|
||||
|
||||
//calculates the fraction of the sunlight that the panel recieves
|
||||
/obj/machinery/power/solar/proc/update_solar_exposure()
|
||||
if(!sun)
|
||||
return
|
||||
if(obscured)
|
||||
sunfrac = 0
|
||||
return
|
||||
var/p_angle = abs((360+adir)%360 - (360+sun.angle)%360)
|
||||
|
||||
//find the smaller angle between the direction the panel is facing and the direction of the sun (the sign is not important here)
|
||||
var/p_angle = min(abs(adir - sun.angle), 360 - abs(adir - sun.angle))
|
||||
|
||||
if(p_angle > 90) // if facing more than 90deg from sun, zero output
|
||||
sunfrac = 0
|
||||
return
|
||||
sunfrac = cos(p_angle) ** 2
|
||||
|
||||
sunfrac = cos(p_angle) ** 2
|
||||
//isn't the power recieved from the incoming light proportionnal to cos(p_angle) (Lambert's cosine law) rather than cos(p_angle)^2 ?
|
||||
|
||||
/obj/machinery/power/solar/process()//TODO: remove/add this from machines to save on processing as needed ~Carn PRIORITY
|
||||
if(stat & BROKEN) return
|
||||
if(!control) return
|
||||
if(stat & BROKEN)
|
||||
return
|
||||
if(!sun || !control) //if there's no sun or the panel is not linked to a solar control computer, no need to proceed
|
||||
return
|
||||
|
||||
if(adir != ndir)
|
||||
adir = (360+adir+dd_range(-10,10,ndir-adir))%360
|
||||
update_icon()
|
||||
update_solar_exposure()
|
||||
|
||||
if(obscured) return
|
||||
|
||||
var/sgen = SOLARGENRATE * sunfrac
|
||||
add_avail(sgen)
|
||||
if(powernet && control)
|
||||
if(powernet.nodes[control])
|
||||
if(powernet)
|
||||
if(powernet == control.powernet)//check if the panel is still connected to the computer
|
||||
if(obscured) //get no light from the sun, so don't generate power
|
||||
return
|
||||
var/sgen = SOLARGENRATE * sunfrac
|
||||
add_avail(sgen)
|
||||
control.gen += sgen
|
||||
|
||||
else //if we're no longer on the same powernet, remove from control computer
|
||||
unset_control()
|
||||
|
||||
/obj/machinery/power/solar/proc/broken()
|
||||
stat |= BROKEN
|
||||
unset_control()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/power/solar/meteorhit()
|
||||
if(stat & !BROKEN)
|
||||
broken()
|
||||
else
|
||||
del(src)
|
||||
|
||||
|
||||
/obj/machinery/power/solar/ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
del(src)
|
||||
if(prob(15))
|
||||
new /obj/item/weapon/shard( src.loc )
|
||||
del(src) // qdel
|
||||
return
|
||||
|
||||
if(2.0)
|
||||
if (prob(25))
|
||||
new /obj/item/weapon/shard( src.loc )
|
||||
del(src)
|
||||
del(src) // qdel
|
||||
return
|
||||
|
||||
if (prob(50))
|
||||
broken()
|
||||
|
||||
if(3.0)
|
||||
if (prob(25))
|
||||
broken()
|
||||
@@ -187,6 +182,29 @@ var/list/solars_list = list()
|
||||
. = PROCESS_KILL
|
||||
return
|
||||
|
||||
//trace towards sun to see if we're in shadow
|
||||
/obj/machinery/power/solar/proc/occlusion()
|
||||
|
||||
var/ax = x // start at the solar panel
|
||||
var/ay = y
|
||||
var/turf/T = null
|
||||
|
||||
for(var/i = 1 to 20) // 20 steps is enough
|
||||
ax += sun.dx // do step
|
||||
ay += sun.dy
|
||||
|
||||
T = locate( round(ax,0.5),round(ay,0.5),z)
|
||||
|
||||
if(T.x == 1 || T.x==world.maxx || T.y==1 || T.y==world.maxy) // not obscured if we reach the edge
|
||||
break
|
||||
|
||||
if(T.density) // if we hit a solid turf, panel is obscured
|
||||
obscured = 1
|
||||
return
|
||||
|
||||
obscured = 0 // if hit the edge or stepped 20 times, not obscured
|
||||
update_solar_exposure()
|
||||
|
||||
|
||||
//
|
||||
// Solar Assembly - For construction of solar arrays.
|
||||
@@ -218,13 +236,13 @@ var/list/solars_list = list()
|
||||
/obj/item/solar_assembly/attackby(var/obj/item/weapon/W, var/mob/user)
|
||||
|
||||
if(!anchored && isturf(loc))
|
||||
if(iswrench(W))
|
||||
if(istype(W, /obj/item/weapon/wrench))
|
||||
anchored = 1
|
||||
user.visible_message("<span class='notice'>[user] wrenches the solar assembly into place.</span>")
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1)
|
||||
return 1
|
||||
else
|
||||
if(iswrench(W))
|
||||
if(istype(W, /obj/item/weapon/wrench))
|
||||
anchored = 0
|
||||
user.visible_message("<span class='notice'>[user] unwrenches the solar assembly from it's place.</span>")
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1)
|
||||
@@ -241,18 +259,19 @@ var/list/solars_list = list()
|
||||
else
|
||||
new /obj/machinery/power/solar(get_turf(src), src)
|
||||
else
|
||||
user << "<span class='warning'>You need two sheets of glass to put them on the solar assembly.</span>"
|
||||
user << "<span class='warning'>You need two sheets of glass to put them into a solar panel.</span>"
|
||||
return
|
||||
return 1
|
||||
|
||||
if(!tracker)
|
||||
if(istype(W, /obj/item/weapon/tracker_electronics))
|
||||
tracker = 1
|
||||
user.drop_item()
|
||||
del(W)
|
||||
del(W) // qdel
|
||||
user.visible_message("<span class='notice'>[user] inserts the electronics into the solar assembly.</span>")
|
||||
return 1
|
||||
else
|
||||
if(iscrowbar(W))
|
||||
if(istype(W, /obj/item/weapon/crowbar))
|
||||
new /obj/item/weapon/tracker_electronics(src.loc)
|
||||
tracker = 0
|
||||
user.visible_message("<span class='notice'>[user] takes out the electronics from the solar assembly.</span>")
|
||||
@@ -270,18 +289,18 @@ var/list/solars_list = list()
|
||||
icon_state = "solar"
|
||||
anchored = 1
|
||||
density = 1
|
||||
directwired = 1
|
||||
use_power = 1
|
||||
idle_power_usage = 5
|
||||
active_power_usage = 20
|
||||
idle_power_usage = 250
|
||||
var/id = 0
|
||||
var/cdir = 0
|
||||
var/targetdir = 0 // target angle in manual tracking (since it updates every game minute)
|
||||
var/gen = 0
|
||||
var/lastgen = 0
|
||||
var/track = 0 // 0=off 1=manual 2=automatic
|
||||
var/trackrate = 60 // Measured in tenths of degree per minute (i.e. defaults to 6.0 deg/min)
|
||||
var/trackdir = 1 // -1=CCW, 1=CW
|
||||
var/nexttime = 0 // Next clock time that manual tracking will move the array
|
||||
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/obj/machinery/power/tracker/connected_tracker = null
|
||||
var/list/connected_panels = list()
|
||||
|
||||
|
||||
/obj/machinery/power/solar_control/New()
|
||||
@@ -290,14 +309,55 @@ var/list/solars_list = list()
|
||||
initialize()
|
||||
connect_to_network()
|
||||
|
||||
/obj/machinery/power/solar_control/Del()
|
||||
for(var/obj/machinery/power/solar/M in connected_panels)
|
||||
M.unset_control()
|
||||
if(connected_tracker)
|
||||
connected_tracker.unset_control()
|
||||
..()
|
||||
|
||||
/obj/machinery/power/solar_control/disconnect_from_network()
|
||||
..()
|
||||
solars_list.Remove(src)
|
||||
|
||||
/obj/machinery/power/solar_control/connect_to_network()
|
||||
..()
|
||||
var/to_return = ..()
|
||||
if(powernet) //if connected and not already in solar_list...
|
||||
solars_list |= src //... add it
|
||||
return to_return
|
||||
|
||||
//search for unconnected panels and trackers in the computer powernet and connect them
|
||||
/obj/machinery/power/solar_control/proc/search_for_connected()
|
||||
if(powernet)
|
||||
solars_list.Add(src)
|
||||
for(var/obj/machinery/power/M in powernet.nodes)
|
||||
if(istype(M, /obj/machinery/power/solar))
|
||||
var/obj/machinery/power/solar/S = M
|
||||
if(!S.control) //i.e unconnected
|
||||
S.set_control(src)
|
||||
connected_panels |= S
|
||||
else if(istype(M, /obj/machinery/power/tracker))
|
||||
if(!connected_tracker) //if there's already a tracker connected to the computer don't add another
|
||||
var/obj/machinery/power/tracker/T = M
|
||||
if(!T.control) //i.e unconnected
|
||||
connected_tracker = T
|
||||
T.set_control(src)
|
||||
|
||||
//called by the sun controller, update the facing angle (either manually or via tracking) and rotates the panels accordingly
|
||||
/obj/machinery/power/solar_control/proc/update()
|
||||
if(stat & (NOPOWER | BROKEN))
|
||||
return
|
||||
|
||||
switch(track)
|
||||
if(1)
|
||||
if(trackrate) //we're manual tracking. If we set a rotation speed...
|
||||
cdir = targetdir //...the current direction is the targetted one (and rotates panels to it)
|
||||
if(2) // auto-tracking
|
||||
if(connected_tracker)
|
||||
connected_tracker.set_angle(sun.angle)
|
||||
|
||||
set_panels(cdir)
|
||||
updateDialog()
|
||||
|
||||
|
||||
/obj/machinery/power/solar_control/initialize()
|
||||
..()
|
||||
@@ -315,22 +375,42 @@ var/list/solars_list = list()
|
||||
return
|
||||
icon_state = "solar"
|
||||
overlays.Cut()
|
||||
if(cdir > 0)
|
||||
if(cdir > -1)
|
||||
overlays += image('icons/obj/computer.dmi', "solcon-o", FLY_LAYER, angle2dir(cdir))
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/power/solar_control/attack_ai(mob/user)
|
||||
add_fingerprint(user)
|
||||
if(stat & (BROKEN | NOPOWER)) return
|
||||
interact(user)
|
||||
|
||||
|
||||
/obj/machinery/power/solar_control/attack_hand(mob/user)
|
||||
add_fingerprint(user)
|
||||
if(stat & (BROKEN | NOPOWER)) return
|
||||
interact(user)
|
||||
if(!..())
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/power/solar_control/interact(mob/user)
|
||||
|
||||
var/t = "<B><span class='highlight'>Generated power</span></B> : [round(lastgen)] W<BR>"
|
||||
t += "<B><span class='highlight'>Orientation</span></B>: [rate_control(src,"cdir","[cdir]°",1,15)] ([angle2text(cdir)])<BR>"
|
||||
t += "<B><span class='highlight'>Tracking:</B><div class='statusDisplay'>"
|
||||
switch(track)
|
||||
if(0)
|
||||
t += "<span class='linkOn'>Off</span> <A href='?src=\ref[src];track=1'>Timed</A> <A href='?src=\ref[src];track=2'>Auto</A><BR>"
|
||||
if(1)
|
||||
t += "<A href='?src=\ref[src];track=0'>Off</A> <span class='linkOn'>Timed</span> <A href='?src=\ref[src];track=2'>Auto</A><BR>"
|
||||
if(2)
|
||||
t += "<A href='?src=\ref[src];track=0'>Off</A> <A href='?src=\ref[src];track=1'>Timed</A> <span class='linkOn'>Auto</span><BR>"
|
||||
|
||||
t += "Tracking Rate: [rate_control(src,"tdir","[trackrate] deg/h ([trackrate<0 ? "CCW" : "CW"])",1,30,180)]</div><BR>"
|
||||
|
||||
t += "<B><span class='highlight'>Connected devices:</span></B><div class='statusDisplay'>"
|
||||
|
||||
t += "<A href='?src=\ref[src];search_connected=1'>Search for devices</A><BR>"
|
||||
t += "Solar panels : [connected_panels.len] connected<BR>"
|
||||
t += "Solar tracker : [connected_tracker ? "<span class='good'>Found</span>" : "<span class='bad'>Not found</span>"]</div><BR>"
|
||||
|
||||
t += "<A href='?src=\ref[src];close=1'>Close</A>"
|
||||
|
||||
var/datum/browser/popup = new(user, "solar", name)
|
||||
popup.set_content(t)
|
||||
popup.open()
|
||||
|
||||
return
|
||||
|
||||
/obj/machinery/power/solar_control/attackby(I as obj, user as mob)
|
||||
if(istype(I, /obj/item/weapon/screwdriver))
|
||||
@@ -347,7 +427,7 @@ var/list/solars_list = list()
|
||||
A.state = 3
|
||||
A.icon_state = "3"
|
||||
A.anchored = 1
|
||||
del(src)
|
||||
del(src) // qdel
|
||||
else
|
||||
user << "\blue You disconnect the monitor."
|
||||
var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
|
||||
@@ -358,12 +438,11 @@ var/list/solars_list = list()
|
||||
A.state = 4
|
||||
A.icon_state = "4"
|
||||
A.anchored = 1
|
||||
del(src)
|
||||
del(src) // qdel
|
||||
else
|
||||
src.attack_hand(user)
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/power/solar_control/process()
|
||||
lastgen = gen
|
||||
gen = 0
|
||||
@@ -371,130 +450,73 @@ var/list/solars_list = list()
|
||||
if(stat & (NOPOWER | BROKEN))
|
||||
return
|
||||
|
||||
//use_power(250)
|
||||
if(track==1 && nexttime < world.time && trackdir*trackrate)
|
||||
// Increments nexttime using itself and not world.time to prevent drift
|
||||
nexttime = nexttime + 6000/trackrate
|
||||
// Nudges array 1 degree in desired direction
|
||||
cdir = (cdir+trackdir+360)%360
|
||||
set_panels(cdir)
|
||||
update_icon()
|
||||
if(connected_tracker) //NOTE : handled here so that we don't add trackers to the processing list
|
||||
if(connected_tracker.powernet != powernet)
|
||||
connected_tracker.unset_control()
|
||||
|
||||
src.updateDialog()
|
||||
|
||||
|
||||
// called by solar tracker when sun position changes
|
||||
/obj/machinery/power/solar_control/proc/tracker_update(var/angle)
|
||||
if(track != 2 || stat & (NOPOWER | BROKEN))
|
||||
return
|
||||
cdir = angle
|
||||
set_panels(cdir)
|
||||
update_icon()
|
||||
src.updateDialog()
|
||||
|
||||
|
||||
/obj/machinery/power/solar_control/interact(mob/user)
|
||||
if(stat & (BROKEN | NOPOWER)) return
|
||||
if ( (get_dist(src, user) > 1 ))
|
||||
if (!istype(user, /mob/living/silicon))
|
||||
user.unset_machine()
|
||||
user << browse(null, "window=solcon")
|
||||
return
|
||||
|
||||
add_fingerprint(user)
|
||||
user.set_machine(src)
|
||||
|
||||
var/t = "<TT><B>Solar Generator Control</B><HR><PRE>"
|
||||
t += "<B>Generated power</B> : [round(lastgen)] W<BR>"
|
||||
t += "Station Rotational Period: [60/abs(sun.rate)] minutes<BR>"
|
||||
t += "Station Rotational Direction: [sun.rate<0 ? "CCW" : "CW"]<BR>"
|
||||
t += "Star Orientation: [sun.angle]° ([angle2text(sun.angle)])<BR>"
|
||||
t += "Array Orientation: [rate_control(src,"cdir","[cdir]°",1,10,60)] ([angle2text(cdir)])<BR>"
|
||||
t += "<BR><HR><BR>"
|
||||
t += "Tracking: "
|
||||
switch(track)
|
||||
if(0)
|
||||
t += "<B>Off</B> <A href='?src=\ref[src];track=1'>Manual</A> <A href='?src=\ref[src];track=2'>Automatic</A><BR>"
|
||||
if(1)
|
||||
t += "<A href='?src=\ref[src];track=0'>Off</A> <B>Manual</B> <A href='?src=\ref[src];track=2'>Automatic</A><BR>"
|
||||
if(2)
|
||||
t += "<A href='?src=\ref[src];track=0'>Off</A> <A href='?src=\ref[src];track=1'>Manual</A> <B>Automatic</B><BR>"
|
||||
|
||||
t += "Manual Tracking Rate: [rate_control(src,"tdir","[trackrate/10]°/min ([trackdir<0 ? "CCW" : "CW"])",1,10)]<BR>"
|
||||
t += "Manual Tracking Direction: "
|
||||
switch(trackdir)
|
||||
if(-1)
|
||||
t += "<A href='?src=\ref[src];trackdir=1'>CW</A> <B>CCW</B><BR>"
|
||||
if(1)
|
||||
t += "<B>CW</B> <A href='?src=\ref[src];trackdir=-1'>CCW</A><BR>"
|
||||
t += "<A href='?src=\ref[src];close=1'>Close</A></TT>"
|
||||
user << browse(t, "window=solcon")
|
||||
onclose(user, "solcon")
|
||||
return
|
||||
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<>...
|
||||
targetdir = (targetdir + trackrate/abs(trackrate) + 360) % 360 //... do it
|
||||
nexttime += 36000/abs(trackrate) //reset the counter for the next 1<>
|
||||
|
||||
updateDialog()
|
||||
|
||||
/obj/machinery/power/solar_control/Topic(href, href_list)
|
||||
if(..())
|
||||
usr << browse(null, "window=solcon")
|
||||
usr.unset_machine()
|
||||
return
|
||||
return 0
|
||||
if(href_list["close"] )
|
||||
usr << browse(null, "window=solcon")
|
||||
usr.unset_machine()
|
||||
return
|
||||
|
||||
if(href_list["dir"])
|
||||
cdir = text2num(href_list["dir"])
|
||||
set_panels(cdir)
|
||||
update_icon()
|
||||
return 0
|
||||
|
||||
if(href_list["rate control"])
|
||||
if(href_list["cdir"])
|
||||
src.cdir = dd_range(0,359,(360+src.cdir+text2num(href_list["cdir"]))%360)
|
||||
src.targetdir = src.cdir
|
||||
if(track == 2) //manual update, so losing auto-tracking
|
||||
track = 0
|
||||
spawn(1)
|
||||
set_panels(cdir)
|
||||
update_icon()
|
||||
if(href_list["tdir"])
|
||||
src.trackrate = dd_range(0,360,src.trackrate+text2num(href_list["tdir"]))
|
||||
if(src.trackrate) nexttime = world.time + 6000/trackrate
|
||||
src.trackrate = dd_range(-7200,7200,src.trackrate+text2num(href_list["tdir"]))
|
||||
if(src.trackrate) nexttime = world.time + 36000/abs(trackrate)
|
||||
|
||||
if(href_list["track"])
|
||||
if(src.trackrate) nexttime = world.time + 6000/trackrate
|
||||
track = text2num(href_list["track"])
|
||||
if(powernet && (track == 2))
|
||||
if(!solars_list.Find(src,1,0))
|
||||
solars_list.Add(src)
|
||||
for(var/obj/machinery/power/tracker/T in get_solars_powernet())
|
||||
if(powernet.nodes[T])
|
||||
cdir = T.sun_angle
|
||||
break
|
||||
if(track == 2)
|
||||
if(connected_tracker)
|
||||
connected_tracker.set_angle(sun.angle)
|
||||
set_panels(cdir)
|
||||
else if (track == 1) //begin manual tracking
|
||||
src.targetdir = src.cdir
|
||||
if(src.trackrate) nexttime = world.time + 36000/abs(trackrate)
|
||||
set_panels(targetdir)
|
||||
|
||||
if(href_list["trackdir"])
|
||||
trackdir = text2num(href_list["trackdir"])
|
||||
|
||||
set_panels(cdir)
|
||||
update_icon()
|
||||
src.updateUsrDialog()
|
||||
return
|
||||
if(href_list["search_connected"])
|
||||
src.search_for_connected()
|
||||
if(connected_tracker && track == 2)
|
||||
connected_tracker.set_angle(sun.angle)
|
||||
src.set_panels(cdir)
|
||||
|
||||
interact(usr)
|
||||
return 1
|
||||
|
||||
//rotates the panel to the passed angle
|
||||
/obj/machinery/power/solar_control/proc/set_panels(var/cdir)
|
||||
if(!powernet) return
|
||||
for(var/obj/machinery/power/solar/S in get_solars_powernet())
|
||||
if(powernet.nodes[S])
|
||||
if(get_dist(S, src) < SOLAR_MAX_DIST)
|
||||
if(!S.control)
|
||||
S.control = src
|
||||
S.ndir = cdir
|
||||
|
||||
for(var/obj/machinery/power/solar/S in connected_panels)
|
||||
S.adir = cdir //instantly rotates the panel
|
||||
S.occlusion()//and
|
||||
S.update_icon() //update it
|
||||
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/machinery/power/solar_control/power_change()
|
||||
..()
|
||||
if(!(stat & NOPOWER))
|
||||
update_icon()
|
||||
else
|
||||
spawn(rand(0, 15))
|
||||
update_icon()
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/machinery/power/solar_control/proc/broken()
|
||||
@@ -502,16 +524,11 @@ var/list/solars_list = list()
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/machinery/power/solar_control/meteorhit()
|
||||
broken()
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/power/solar_control/ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
//SN src = null
|
||||
del(src)
|
||||
del(src) // qdel
|
||||
return
|
||||
if(2.0)
|
||||
if (prob(50))
|
||||
@@ -535,3 +552,9 @@ var/list/solars_list = list()
|
||||
/obj/item/weapon/paper/solar
|
||||
name = "paper- 'Going green! Setup your own solar array instructions.'"
|
||||
info = "<h1>Welcome</h1><p>At greencorps we love the environment, and space. With this package you are able to help mother nature and produce energy without any usage of fossil fuel or phoron! Singularity energy is dangerous while solar energy is safe, which is why it's better. Now here is how you setup your own solar array.</p><p>You can make a solar panel by wrenching the solar assembly onto a cable node. Adding a glass panel, reinforced or regular glass will do, will finish the construction of your solar panel. It is that easy!</p><p>Now after setting up 19 more of these solar panels you will want to create a solar tracker to keep track of our mother nature's gift, the sun. These are the same steps as before except you insert the tracker equipment circuit into the assembly before performing the final step of adding the glass. You now have a tracker! Now the last step is to add a computer to calculate the sun's movements and to send commands to the solar panels to change direction with the sun. Setting up the solar computer is the same as setting up any computer, so you should have no trouble in doing that. You do need to put a wire node under the computer, and the wire needs to be connected to the tracker.</p><p>Congratulations, you should have a working solar array. If you are having trouble, here are some tips. Make sure all solar equipment are on a cable node, even the computer. You can always deconstruct your creations if you make a mistake.</p><p>That's all to it, be safe, be green!</p>"
|
||||
|
||||
/proc/rate_control(var/S, var/V, var/C, var/Min=1, var/Max=5, var/Limit=null) //How not to name vars
|
||||
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
|
||||
@@ -11,7 +11,6 @@
|
||||
layer = TURF_LAYER
|
||||
var/obj/machinery/power/master = null
|
||||
anchored = 1
|
||||
directwired = 0 // must have a cable on same turf connecting to terminal
|
||||
layer = 2.6 // a bit above wires
|
||||
|
||||
|
||||
@@ -21,6 +20,10 @@
|
||||
if(level==1) hide(T.intact)
|
||||
return
|
||||
|
||||
/obj/machinery/power/terminal/Del()
|
||||
if(master)
|
||||
master.disconnect_terminal()
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/terminal/hide(var/i)
|
||||
if(i)
|
||||
|
||||
@@ -10,55 +10,58 @@
|
||||
icon_state = "tracker"
|
||||
anchored = 1
|
||||
density = 1
|
||||
directwired = 1
|
||||
use_power = 0 // doesn't use APC power
|
||||
var/power_usage = 500 //W
|
||||
use_power = 0
|
||||
|
||||
var/id = 0
|
||||
var/sun_angle = 0 // sun angle as set by sun datum
|
||||
var/obj/machinery/power/solar_control/control = null
|
||||
|
||||
/obj/machinery/power/tracker/New(var/turf/loc, var/obj/item/solar_assembly/S)
|
||||
..(loc)
|
||||
Make(S)
|
||||
connect_to_network()
|
||||
|
||||
/obj/machinery/power/tracker/Del()
|
||||
unset_control() //remove from control computer
|
||||
..()
|
||||
|
||||
//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))
|
||||
return 0
|
||||
control = SC
|
||||
return 1
|
||||
|
||||
//set the control of the tracker to null and removes it from the previous control computer if needed
|
||||
/obj/machinery/power/tracker/proc/unset_control()
|
||||
if(control)
|
||||
control.connected_tracker = null
|
||||
control = null
|
||||
|
||||
/obj/machinery/power/tracker/proc/Make(var/obj/item/solar_assembly/S)
|
||||
if(!S)
|
||||
S = new /obj/item/solar_assembly(src)
|
||||
S.glass_type = /obj/item/stack/sheet/glass
|
||||
S.tracker = 1
|
||||
S.anchored = 1
|
||||
S.loc = src
|
||||
connect_to_network()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/power/tracker/disconnect_from_network()
|
||||
..()
|
||||
solars_list.Remove(src)
|
||||
|
||||
/obj/machinery/power/tracker/connect_to_network()
|
||||
..()
|
||||
solars_list.Add(src)
|
||||
|
||||
// called by datum/sun/calc_position() as sun's angle changes
|
||||
//updates the tracker icon and the facing angle for the control computer
|
||||
/obj/machinery/power/tracker/proc/set_angle(var/angle)
|
||||
sun_angle = angle
|
||||
|
||||
//set icon dir to show sun illumination
|
||||
dir = turn(NORTH, -angle - 22.5) // 22.5 deg bias ensures, e.g. 67.5-112.5 is EAST
|
||||
|
||||
// check we can draw power
|
||||
if(stat & NOPOWER)
|
||||
return
|
||||
|
||||
// find all solar controls and update them
|
||||
// currently, just update all controllers in world
|
||||
// ***TODO: better communication system using network
|
||||
if(powernet)
|
||||
for(var/obj/machinery/power/solar_control/C in get_solars_powernet())
|
||||
if(powernet.nodes[C])
|
||||
if(get_dist(C, src) < SOLAR_MAX_DIST)
|
||||
C.tracker_update(angle)
|
||||
|
||||
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)
|
||||
|
||||
if(iscrowbar(W))
|
||||
if(istype(W, /obj/item/weapon/crowbar))
|
||||
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
|
||||
user.visible_message("<span class='notice'>[user] begins to take the glass off the solar tracker.</span>")
|
||||
if(do_after(user, 50))
|
||||
var/obj/item/solar_assembly/S = locate() in src
|
||||
if(S)
|
||||
@@ -66,20 +69,10 @@
|
||||
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>")
|
||||
del(src)
|
||||
del(src) // qdel
|
||||
return
|
||||
..()
|
||||
|
||||
// timed process
|
||||
// make sure we can draw power from the powernet
|
||||
/obj/machinery/power/tracker/process()
|
||||
|
||||
if(surplus() >= power_usage && add_load(power_usage) >= power_usage)
|
||||
stat &= ~NOPOWER
|
||||
else
|
||||
stat |= NOPOWER
|
||||
|
||||
|
||||
// Tracker Electronic
|
||||
|
||||
/obj/item/weapon/tracker_electronics
|
||||
@@ -87,4 +80,4 @@
|
||||
name = "tracker electronics"
|
||||
icon = 'icons/obj/doors/door_assembly.dmi'
|
||||
icon_state = "door_electronics"
|
||||
w_class = 2.0
|
||||
w_class = 2.0
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
anchored = 1
|
||||
density = 1
|
||||
var/obj/machinery/compressor/compressor
|
||||
directwired = 1
|
||||
var/turf/simulated/outturf
|
||||
var/lastgen
|
||||
|
||||
@@ -30,7 +29,7 @@
|
||||
name = "Gas turbine control computer"
|
||||
desc = "A computer to remotely control a gas turbine"
|
||||
icon = 'icons/obj/computer.dmi'
|
||||
icon_state = "airtunnel0e"
|
||||
icon_state = "turbinecomp"
|
||||
circuit = /obj/item/weapon/circuitboard/turbine_control
|
||||
anchored = 1
|
||||
density = 1
|
||||
|
||||
@@ -70,12 +70,12 @@
|
||||
var/shieldload = between(500, max_stored_power - storedpower, power_draw) //what we try to draw
|
||||
shieldload = PN.draw_power(shieldload) //what we actually get
|
||||
storedpower += shieldload
|
||||
|
||||
|
||||
//If we're still in the red, then there must not be enough available power to cover our load.
|
||||
if(storedpower <= 0)
|
||||
power = 0
|
||||
return 0
|
||||
|
||||
|
||||
power = 1 // IVE GOT THE POWER!
|
||||
return 1
|
||||
|
||||
|
||||
@@ -107,14 +107,14 @@
|
||||
/obj/machinery/shield_capacitor/process()
|
||||
if (!anchored)
|
||||
active = 0
|
||||
|
||||
|
||||
//see if we can connect to a power net.
|
||||
var/datum/powernet/PN
|
||||
var/turf/T = src.loc
|
||||
var/obj/structure/cable/C = T.get_cable_node()
|
||||
if (C)
|
||||
PN = C.powernet
|
||||
|
||||
|
||||
if (PN)
|
||||
var/power_draw = between(0, max_charge - stored_charge, charge_rate) //what we are trying to draw
|
||||
power_draw = PN.draw_power(power_draw) //what we actually get
|
||||
@@ -138,7 +138,7 @@
|
||||
active = !active
|
||||
if( href_list["charge_rate"] )
|
||||
charge_rate = between(10000, charge_rate + text2num(href_list["charge_rate"]), max_charge_rate)
|
||||
|
||||
|
||||
updateDialog()
|
||||
|
||||
/obj/machinery/shield_capacitor/power_change()
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@ Used In File(s): \code\game\machinery\computer\crew.dm
|
||||
-->
|
||||
{{for data.crewmembers}}
|
||||
{{if value.sensor_type == 3}}
|
||||
<div class="mapIcon mapIcon16 rank-{{:value.rank.ckey()}} {{:value.dead ? 'dead' : 'alive'}}" style="left: {{:(value.x)}}px; bottom: {{:(value.y)}}px;" unselectable="on">
|
||||
<div class="mapIcon mapIcon16 rank-{{:value.rank.ckey()}} {{:value.dead ? 'dead' : 'alive'}}" style="left: {{:(value.x)}}px; bottom: {{:(value.y - 1)}}px;" unselectable="on">
|
||||
<div class="tooltip hidden">
|
||||
{{:value.name}} ({{:value.dead ? "<span class='bad'>Deceased</span>" : "<span class='good'>Living</span>"}}) (<span class="oxyloss">{{:value.oxy}}</span>/<span class="toxin">{{:value.tox}}</span>/<span class="burn">{{:value.fire}}</span>/<span class="brute">{{:value.brute}}</span>) ({{:value.area}}: {{:value.x}}, {{:value.y}})
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user