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

Conflicts:
	_maps/map_files/RandomZLevels/moonoutpost19.dmm
	_maps/map_files/cyberiad/cyberiad.dmm
	code/controllers/master_controller.dm
	code/game/machinery/alarm.dm
	code/modules/power/apc.dm
This commit is contained in:
Markolie
2015-08-03 00:04:24 +02:00
78 changed files with 1812 additions and 1450 deletions
+3
View File
@@ -10,6 +10,9 @@ Pipelines + Other Objects -> Pipe network
*/
/obj/machinery/atmospherics
auto_init = 0
anchored = 1
idle_power_usage = 0
active_power_usage = 0
@@ -30,12 +30,6 @@ Filter types:
if(frequency)
radio_connection = radio_controller.add_object(src, frequency, RADIO_ATMOSIA)
/* I don't know why this is here, but it's ugly, so I'm disabling it
/obj/machinery/atmospherics/trinary/filter/New()
..()
if(radio_controller)
initialize()
*/
/obj/machinery/atmospherics/trinary/filter/update_icon()
if(istype(src, /obj/machinery/atmospherics/trinary/filter/m_filter))
icon_state = "m"
@@ -64,9 +64,6 @@
if (!id_tag)
assign_uid()
id_tag = num2text(uid)
if(ticker && ticker.current_state == 3)//if the game is running
src.initialize()
src.broadcast_status()
..()
/obj/machinery/atmospherics/unary/vent_pump/high_volume
@@ -227,11 +224,12 @@
/obj/machinery/atmospherics/unary/vent_pump/initialize()
..()
//some vents work his own spesial way
//some vents work his own special way
radio_filter_in = frequency==1439?(RADIO_FROM_AIRALARM):null
radio_filter_out = frequency==1439?(RADIO_TO_AIRALARM):null
if(frequency)
set_frequency(frequency)
src.broadcast_status()
/obj/machinery/atmospherics/unary/vent_pump/receive_signal(datum/signal/signal)
if(stat & (NOPOWER|BROKEN))
@@ -42,9 +42,6 @@
if (!id_tag)
assign_uid()
id_tag = num2text(uid)
if(ticker && ticker.current_state == 3)//if the game is running
src.initialize()
src.broadcast_status()
..()
/obj/machinery/atmospherics/unary/vent_scrubber/update_icon(var/safety = 0)
@@ -131,6 +128,7 @@
radio_filter_out = frequency==initial(frequency)?(RADIO_TO_AIRALARM):null
if(frequency)
set_frequency(frequency)
src.broadcast_status()
/obj/machinery/atmospherics/unary/vent_scrubber/process()
..()
+4
View File
@@ -0,0 +1,4 @@
#define GAME_STATE_PREGAME 1
#define GAME_STATE_SETTING_UP 2
#define GAME_STATE_PLAYING 3
#define GAME_STATE_FINISHED 4
+4 -1
View File
@@ -50,6 +50,9 @@
#define INFECTION_LEVEL_TWO 500
#define INFECTION_LEVEL_THREE 1000
// Damage above this value must be repaired with surgery.
#define ROBOLIMB_SELF_REPAIR_CAP 30
//metal, glass, rod stacks
#define MAX_STACK_AMOUNT_METAL 50
#define MAX_STACK_AMOUNT_GLASS 50
@@ -143,4 +146,4 @@
dview_mob.loc = center; \
dview_mob.see_invisible = invis_flags; \
for(type in view(range, dview_mob))
#define END_FOR_DVIEW dview_mob.loc = null
#define END_FOR_DVIEW dview_mob.loc = null
+1 -1
View File
@@ -15,8 +15,8 @@ var/global/list/singularities = list() //list of all singularities
var/global/list/aibots = list() // AI controlled bots
var/global/list/table_recipes = list() //list of all table craft recipes
var/global/list/active_areas = list()
var/global/list/all_areas = list()
var/global/list/machines = list()
var/global/list/processing_power_items = list()
//items that ask to be called every cycle
+10 -2
View File
@@ -7,6 +7,7 @@
/datum/controller/process/machinery/doWork()
process_sort()
process_power()
process_power_drain()
process_machines()
/datum/controller/process/machinery/proc/process_sort()
@@ -48,5 +49,12 @@
powerNetwork.reset()
scheck()
continue
else
powernets -= powerNetwork
powernets.Remove(powerNetwork)
/datum/controller/process/machinery/proc/process_power_drain()
// Currently only used by powersinks. These items get priority processed before machinery
for(var/obj/item/I in processing_power_items)
if(!I.pwr_drain()) // 0 = Process Kill, remove from processing list.
processing_power_items.Remove(I)
scheck()
-15
View File
@@ -28,20 +28,5 @@
name = "text"
var/data = null
/datum/powernet
var/list/cables = list() // all cables & junctions
var/list/nodes = list() // all connected machines
var/load = 0 // the current load on the powernet, increased by each machine at processing
var/newavail = 0 // what available power was gathered last tick, then becomes...
var/avail = 0 //...the current available power in the powernet
var/viewload = 0 // the load as it appears on the power console (gradually updated)
var/number = 0 // Unused //TODEL
var/netexcess = 0 // excess power on the powernet (typically avail-load)
/datum/debug
var/list/debuglist
+1 -1
View File
@@ -743,7 +743,7 @@ var/list/uplink_items = list()
name = "Energy Shield"
desc = "An incredibly useful personal shield projector, capable of reflecting energy projectiles and defending against other attacks."
item = /obj/item/weapon/shield/energy
reference = "ES"
reference = "ESD"
cost = 16
gamemodes = list("nuclear emergency")
surplus = 20
+51
View File
@@ -0,0 +1,51 @@
/datum/wires/smartfridge
holder_type = /obj/machinery/smartfridge
wire_count = 3
/datum/wires/smartfridge/secure
random = 1
wire_count = 4
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/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
-1
View File
@@ -35,7 +35,6 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
var/eject = null
var/debug = 0
var/powerupdate = 10 //We give everything 10 ticks to settle out it's power usage.
var/requires_power = 1
var/always_unpowered = 0 //this gets overriden to 1 for space in area/New()
+2 -4
View File
@@ -16,7 +16,6 @@
icon_state = ""
layer = 10
uid = ++global_uid
active_areas += src
all_areas += src
if(type == /area) // override defaults for space. TODO: make space areas of type /area/space rather than /area
@@ -157,7 +156,7 @@
if(radalert) // always show the radiation alert, regardless of power
icon_state = "radiation"
blend_mode = BLEND_MULTIPLY
else if ((fire || eject || party) && ((!requires_power)?(!requires_power):power_environ))//If it doesn't require power, can still activate this proc.
else if ((fire || eject || party) && (!requires_power||power_environ))//If it doesn't require power, can still activate this proc.
if(fire && !radalert && !eject && !party)
icon_state = "red"
blend_mode = BLEND_MULTIPLY
@@ -209,9 +208,8 @@
// called when power status changes
/area/proc/power_change()
powerupdate = 2
for(var/obj/machinery/M in src) // 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)
updateicon()
+7 -1
View File
@@ -16,11 +16,14 @@
var/mob/pulledby = null
var/area/areaMaster
var/auto_init = 1
/atom/movable/New()
. = ..()
areaMaster = get_area_master(src)
if(auto_init && ticker && ticker.current_state == GAME_STATE_PLAYING)
initialize()
/atom/movable/Destroy()
for(var/atom/movable/AM in contents)
@@ -32,6 +35,9 @@
pulledby = null
..()
return QDEL_HINT_QUEUE
/atom/movable/proc/initialize()
return
// Used in shuttle movement and AI eye stuff.
// Primarily used to notify objects being moved by a shuttle/bluespace fuckup.
+14 -10
View File
@@ -10,10 +10,13 @@
var/area/current_area = get_area(S)
if(current_area.type in skipped_areas || !(S.z in config.station_levels))
continue
S.last_charge = S.charge
S.last_output_attempt = S.output_attempt
S.last_input_attempt = S.input_attempt
S.charge = 0
S.output = 0
S.online = 0
S.updateicon()
S.inputting(0)
S.outputting(0)
S.update_icon()
S.power_change()
@@ -40,10 +43,10 @@
var/area/current_area = get_area(S)
if(current_area.type in skipped_areas || !(S.z in config.station_levels))
continue
S.charge = S.capacity
S.output = 200000
S.online = 1
S.updateicon()
S.charge = S.last_charge
S.output_attempt = S.last_output_attempt
S.input_attempt = S.last_input_attempt
S.update_icon()
S.power_change()
/proc/power_restore_quick(var/announce = 1)
@@ -54,7 +57,8 @@
if(S.z != 1)
continue
S.charge = S.capacity
S.output = 200000
S.online = 1
S.updateicon()
S.output_level = S.output_level_max
S.output_attempt = 1
S.input_attempt = 1
S.update_icon()
S.power_change()
-6
View File
@@ -1,11 +1,5 @@
var/global/datum/controller/gameticker/ticker
#define GAME_STATE_PREGAME 1
#define GAME_STATE_SETTING_UP 2
#define GAME_STATE_PLAYING 3
#define GAME_STATE_FINISHED 4
/datum/controller/gameticker
var/const/restart_timeout = 600
var/current_state = GAME_STATE_PREGAME
-12
View File
@@ -591,18 +591,6 @@
E.open()
continue
/obj/machinery/alarm/proc/shock(mob/user, prb)
if((stat & (NOPOWER))) // unpowered, no shock
return 0
if(!prob(prb))
return 0 //you lucked out, no shock for you
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src)
s.start() //sparks always.
if (electrocute_mob(user, get_area(src), src))
return 1
else
return 0
///////////////
//END HACKING//
///////////////
+4 -6
View File
@@ -87,6 +87,8 @@ obj/machinery/air_sensor
process()
if(on)
if(!radio_connection)
return
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.data["tag"] = id_tag
@@ -128,12 +130,6 @@ obj/machinery/air_sensor
initialize()
set_frequency(frequency)
New()
..()
if(radio_controller)
set_frequency(frequency)
Destroy()
if(radio_controller)
radio_controller.remove_object(src,frequency)
@@ -533,6 +529,8 @@ legend {
send_signal(list("tag"=device, "status"))
proc/send_signal(var/list/data)
if(!radio_connection)
return
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.source = src
-13
View File
@@ -500,19 +500,6 @@
dat += "[D.materials["$glass"] / coeff] glass"
return dat
/obj/machinery/autolathe/proc/shock(mob/user, prb)
if(stat & (BROKEN|NOPOWER)) // unpowered, no shock
return 0
if(!prob(prb))
return 0
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
if (electrocute_mob(user, get_area(src), src, 0.7))
return 1
else
return 0
/obj/machinery/autolathe/proc/adjust_hacked(var/hack)
hacked = hack
-5
View File
@@ -113,11 +113,6 @@
src.view_range = num
cameranet.updateVisibility(src, 0)
/obj/machinery/camera/proc/shock(var/mob/living/user)
if(!istype(user))
return
user.electrocute_act(10, src)
/obj/machinery/camera/attackby(W as obj, mob/living/user as mob, params)
invalidateCameraCache()
var/msg = "<span class='notice'>You attach [W] into the assembly inner circuits.</span>"
-5
View File
@@ -14,11 +14,6 @@
var/light_range_on = 2
var/light_power_on = 1
/obj/machinery/computer/New()
..()
if(ticker)
initialize()
/obj/machinery/computer/initialize()
power_change()
update_icon()
+5 -11
View File
@@ -450,25 +450,19 @@ About the new airlock wires panel:
// shock user with probability prb (if all connections & power are working)
// returns 1 if shocked, 0 otherwise
// The preceding comment was borrowed from the grille's shock script
/obj/machinery/door/airlock/proc/shock(mob/user, prb)
if((stat & (NOPOWER)) || !src.arePowerSystemsOn()) // unpowered, no shock
/obj/machinery/door/airlock/shock(mob/user, prb)
if(!arePowerSystemsOn())
return 0
if(hasShocked)
return 0 //Already shocked someone recently?
if(!prob(prb))
return 0 //you lucked out, no shock for you
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src)
s.start() //sparks always.
if(electrocute_mob(user, get_area(src), src))
if(..())
hasShocked = 1
spawn(10)
hasShocked = 0
sleep(10)
hasShocked = 0
return 1
else
return 0
/obj/machinery/door/airlock/update_icon()
if(overlays) overlays.Cut()
overlays = list()
+3 -1
View File
@@ -31,13 +31,15 @@
set_light(0)
src.visible_message("<span class='warning'>[src] shuts down due to lack of power!</span>")
return
/obj/machinery/floodlight/attack_ai(mob/user as mob)
return
/obj/machinery/floodlight/attack_hand(mob/user as mob)
if(open && cell)
if(ishuman(user))
if(!user.get_active_hand())
user.put_in_hands(cell)
cell.loc = user.loc
else
cell.loc = loc
+187 -54
View File
@@ -14,9 +14,28 @@
var/global/max_n_of_items = 999 // Sorry but the BYOND infinite loop detector doesn't look things over 1000.
var/icon_on = "smartfridge"
var/icon_off = "smartfridge-off"
var/icon_panel = "smartfridge-panel"
var/item_quants = list()
var/ispowered = 1 //starts powered
var/isbroken = 0
var/seconds_electrified = 0;
var/shoot_inventory = 0
var/locked = 0
var/scan_id = 1
var/is_secure = 0
var/datum/wires/smartfridge/wires = null
/obj/machinery/smartfridge/secure
is_secure = 1
/obj/machinery/smartfridge/New()
..()
if(is_secure)
wires = new/datum/wires/smartfridge/secure(src)
else
wires = new/datum/wires/smartfridge(src)
/obj/machinery/smartfridge/Destroy()
qdel(wires)
return ..()
/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/))
@@ -36,49 +55,129 @@
return 1
return 0
/obj/machinery/smartfridge/extract
/obj/machinery/smartfridge/medbay
name = "\improper Refrigerated Medicine Storage"
desc = "A refrigerated storage unit for storing medicine and chemicals."
icon_state = "smartfridge" //To fix the icon in the map editor.
icon_on = "smartfridge_chem"
/obj/machinery/smartfridge/medbay/accept_check(var/obj/item/O as obj)
if(istype(O,/obj/item/weapon/reagent_containers/glass/))
return 1
if(istype(O,/obj/item/weapon/storage/pill_bottle/))
return 1
if(istype(O,/obj/item/weapon/reagent_containers/pill/))
return 1
return 0
/obj/machinery/smartfridge/secure/extract
name = "\improper Slime Extract Storage"
desc = "A refrigerated storage unit for slime extracts"
req_access_txt = "47"
/obj/machinery/smartfridge/extract/accept_check(var/obj/item/O as obj)
/obj/machinery/smartfridge/secure/extract/accept_check(var/obj/item/O as obj)
if(istype(O,/obj/item/slime_extract))
return 1
if(istype(O,/obj/item/device/slime_scanner))
return 1
return 0
/obj/machinery/smartfridge/medbay
name = "\improper Medical Fridge"
desc = "Am refridgerated storage unit for medicine."
icon = 'icons/obj/vending.dmi'
/obj/machinery/smartfridge/secure/medbay
name = "\improper Secure Refrigerated Medicine Storage"
desc = "A refrigerated storage unit for storing medicine and chemicals."
icon_state = "smartfridge" //To fix the icon in the map editor.
icon_on = "smartfridge_chem"
req_one_access_txt = "5;33"
/obj/machinery/smartfridge/medbay/accept_check(var/obj/item/O as obj)
if(istype(O,/obj/item/weapon/reagent_containers/) || istype(O,/obj/item/weapon/storage/pill_bottle))
/obj/machinery/smartfridge/secure/medbay/accept_check(var/obj/item/O as obj)
if(istype(O,/obj/item/weapon/reagent_containers/glass/))
return 1
if(istype(O,/obj/item/weapon/storage/pill_bottle/))
return 1
if(istype(O,/obj/item/weapon/reagent_containers/pill/))
return 1
return 0
/obj/machinery/smartfridge/secure/virology
name = "\improper Refrigerated Virus Storage"
desc = "A refrigerated storage unit for storing viral material."
req_access_txt = "39"
icon_state = "smartfridge_virology"
icon_on = "smartfridge_virology"
icon_off = "smartfridge_virology-off"
/obj/machinery/smartfridge/secure/virology/accept_check(var/obj/item/O as obj)
if(istype(O,/obj/item/weapon/reagent_containers/glass/beaker/vial/))
return 1
if(istype(O,/obj/item/weapon/virusdish/))
return 1
return 0
/obj/machinery/smartfridge/secure/chemistry
name = "\improper Smart Chemical Storage"
desc = "A refrigerated storage unit for medicine and chemical storage."
icon_state = "smartfridge" //To fix the icon in the map editor.
icon_on = "smartfridge_chem"
req_access_txt = "33"
/obj/machinery/smartfridge/chemistry/accept_check(var/obj/item/O as obj)
if(istype(O,/obj/item/weapon/storage/pill_bottle) || istype(O,/obj/item/weapon/reagent_containers))
return 1
return 0
/obj/machinery/smartfridge/secure/chemistry/virology
name = "\improper Smart Virus Storage"
desc = "A refrigerated storage unit for volatile sample storage."
req_access_txt = "39"
/obj/machinery/smartfridge/drinks
name = "\improper Drink Showcase"
desc = "A refrigerated storage unit for tasty tasty alcohol."
/obj/machinery/smartfridge/drinks/accept_check(var/obj/item/O as obj)
if(istype(O,/obj/item/weapon/reagent_containers/glass) || istype(O,/obj/item/weapon/reagent_containers/food/drinks) || istype(O,/obj/item/weapon/reagent_containers/food/condiment))
return 1
/obj/machinery/smartfridge/process()
if(stat & (BROKEN|NOPOWER))
return
if(src.seconds_electrified > 0)
src.seconds_electrified--
if(src.shoot_inventory && prob(2))
src.throw_item()
/obj/machinery/smartfridge/power_change()
if( powered() )
src.ispowered = 1
stat &= ~NOPOWER
if(!isbroken)
icon_state = icon_on
var/old_stat = stat
..()
if(old_stat != stat)
update_icon()
/obj/machinery/smartfridge/update_icon()
if(stat & (BROKEN|NOPOWER))
icon_state = icon_off
else
spawn(rand(0, 15))
src.ispowered = 0
stat |= NOPOWER
if(!isbroken)
icon_state = icon_off
icon_state = icon_on
/*******************
* Item Adding
********************/
/obj/machinery/smartfridge/attackby(var/obj/item/O as obj, var/mob/user as mob, params)
if(!src.ispowered)
/obj/machinery/smartfridge/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(istype(O, /obj/item/weapon/screwdriver))
playsound(user, 'sound/items/Screwdriver.ogg', 50, 1)
panel_open = !panel_open
user.visible_message("[user] [panel_open ? "opens" : "closes"] the maintenance panel of \the [src].", "You [panel_open ? "open" : "close"] the maintenance panel of \the [src].")
overlays.Cut()
if(panel_open)
overlays += image(icon, icon_panel)
nanomanager.update_uis(src)
return
if(istype(O, /obj/item/device/multitool)||istype(O, /obj/item/weapon/wirecutters))
if(panel_open)
attack_hand(user)
return
if(stat & NOPOWER)
user << "<span class='notice'>\The [src] is unpowered and useless.</span>"
return
@@ -87,21 +186,18 @@
user << "<span class='notice'>\The [src] is full.</span>"
return 1
else
if(!user.unEquip(O))
usr << "<span class='notice'>\the [O] is stuck to your hand, you cannot put it in \the [src]</span>"
return
user.remove_from_mob(O)
O.loc = src
if(item_quants[O.name])
item_quants[O.name]++
else
item_quants[O.name] = 1
user.visible_message("<span class='notice'>[user] has added \the [O] to \the [src].", \
"<span class='notice'>You add \the [O] to \the [src].")
user.visible_message("<span class='notice'>[user] has added \the [O] to \the [src].</span>", "<span class='notice'>You add \the [O] to \the [src].</span>")
nanomanager.update_uis(src)
else if(istype(O, /obj/item/weapon/storage/bag/plants) || istype(O, /obj/item/weapon/storage/belt/medical))
var/obj/item/weapon/storage/bag/plants/P = O
else if(istype(O, /obj/item/weapon/storage/bag))
var/obj/item/weapon/storage/bag/P = O
var/plants_loaded = 0
for(var/obj/G in P.contents)
if(accept_check(G))
@@ -117,27 +213,23 @@
plants_loaded++
if(plants_loaded)
user.visible_message( \
"<span class='notice'>[user] loads \the [src] with \the [P].</span>", \
"<span class='notice'>You load \the [src] with \the [P].</span>")
user.visible_message("<span class='notice'>[user] loads \the [src] with \the [P].</span>", "<span class='notice'>You load \the [src] with \the [P].</span>")
if(P.contents.len > 0)
user << "<span class='notice'>Some items are refused.</span>"
nanomanager.update_uis(src)
else
user << "<span class='notice'>\The [src] smartly refuses [O].</span>"
return 1
updateUsrDialog()
/obj/machinery/smartfridge/attack_ai(mob/user as mob)
return 0
/obj/machinery/smartfridge/attack_hand(mob/user as mob)
if(stat & (NOPOWER|BROKEN))
return
wires.Interact(user)
ui_interact(user)
//Drag pill bottle to fridge to empty it into the fridge
@@ -145,7 +237,7 @@
if(!istype(over_object, /obj/item/weapon/storage/pill_bottle)) //Only pill bottles, please
return
if(!src.ispowered)
if(stat & NOPOWER)
user << "<span class='notice'>\The [src] is unpowered and useless.</span>"
return
@@ -170,9 +262,12 @@
if(P.contents.len > 0)
user << "<span class='notice'>Some items are refused.</span>"
nanomanager.update_uis(src)
updateUsrDialog()
/obj/machinery/smartfridge/secure/emag_act(user as mob)
emagged = 1
locked = -1
user << "You short out the product lock on [src]."
/*******************
* SmartFridge Menu
********************/
@@ -182,38 +277,41 @@
var/data[0]
data["contents"] = null
data["electrified"] = seconds_electrified > 0
data["shoot_inventory"] = shoot_inventory
data["locked"] = locked
data["secure"] = is_secure
var/list/items[0]
for (var/i=1 to length(item_quants))
var/K = item_quants[i]
var/count = item_quants[K]
if (count > 0)
if(count > 0)
items.Add(list(list("display_name" = html_encode(capitalize(K)), "vend" = i, "quantity" = count)))
if (items.len > 0)
if(items.len > 0)
data["contents"] = items
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
if(!ui)
ui = new(user, src, ui_key, "smartfridge.tmpl", src.name, 400, 500)
ui.set_initial_data(data)
ui.open()
/obj/machinery/smartfridge/Topic(href, href_list)
if (..()) return 0
if(..()) return 0
var/mob/user = usr
var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, "main")
src.add_fingerprint(user)
if (href_list["close"])
if(href_list["close"])
user.unset_machine()
ui.close()
return 0
if (href_list["vend"])
if(href_list["vend"])
var/index = text2num(href_list["vend"])
var/amount = text2num(href_list["amount"])
var/K = item_quants[index]
@@ -225,14 +323,49 @@
var/i = amount
for(var/obj/O in contents)
if (O.name == K)
if(O.name == K)
O.loc = loc
i--
if (i <= 0)
if(i <= 0)
return 1
return 1
return 0
/obj/machinery/smartfridge/proc/throw_item()
var/obj/throw_item = null
var/mob/living/target = locate() in view(7,src)
if(!target)
return 0
for (var/O in item_quants)
if(item_quants[O] <= 0) //Try to use a record that actually has something to dump.
continue
item_quants[O]--
for(var/obj/T in contents)
if(T.name == O)
T.loc = src.loc
throw_item = T
break
break
if(!throw_item)
return 0
spawn(0)
throw_item.throw_at(target,16,3,src)
src.visible_message("<span class='warning'>[src] launches [throw_item.name] at [target.name]!</span>")
return 1
/************************
* Secure SmartFridges
*************************/
/obj/machinery/smartfridge/secure/Topic(href, href_list)
if(stat & (NOPOWER|BROKEN))
return 0
if(usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf)))
if(!allowed(usr) && !emagged && locked != -1 && href_list["vend"])
usr << "<span class='warning'>Access denied.</span>"
nanomanager.update_uis(src)
return 0
return ..()
+14 -3
View File
@@ -354,9 +354,6 @@ Class Procs:
src.add_fingerprint(user)
var/area/A = get_area(src)
A.powerupdate = 1
return 0
/obj/machinery/CheckParts()
@@ -525,3 +522,17 @@ Class Procs:
threatcount += 4
return threatcount
/obj/machinery/proc/shock(mob/user, prb)
if(inoperable())
return 0
if(!prob(prb))
return 0
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
if (electrocute_mob(user, get_area(src), src, 0.7))
if(user.stunned)
return 1
return 0
-12
View File
@@ -1016,18 +1016,6 @@
if (WIRE_SCANID)
locked = !locked
*/
/obj/machinery/suit_cycler/proc/shock(mob/user, prb)
if(stat & (BROKEN|NOPOWER)) // unpowered, no shock
return 0
if(!prob(prb))
return 0
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
if (electrocute_mob(user, get_area(src), src, 0.7))
return 1
else
return 0
//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()
+1 -1
View File
@@ -192,7 +192,7 @@
return PROCESS_KILL
else
if(surplus() > 1500)
add_load(1500)
draw_power(1500)
else
Deactivate()
+8 -2
View File
@@ -23,6 +23,12 @@
hide = 1
toggled = 0
autolinkers = list("r_relay")
/obj/machinery/telecomms/relay/preset/engioutpost
id = "Engineering Outpost"
hide = 1
toggled = 0
autolinkers = list("e_relay")
/obj/machinery/telecomms/relay/preset/centcom
id = "Centcom Relay"
@@ -39,7 +45,7 @@
/obj/machinery/telecomms/hub/preset
id = "Hub"
network = "tcommsat"
autolinkers = list("hub", "relay", "c_relay", "s_relay", "m_relay", "r_relay", "science", "medical",
autolinkers = list("hub", "relay", "c_relay", "s_relay", "m_relay", "r_relay", "e_relay", "science", "medical",
"supply", "service", "common", "command", "engineering", "security",
"receiverA", "receiverB", "broadcasterA", "broadcasterB")
@@ -47,7 +53,7 @@
id = "CentComm Hub"
network = "tcommsat"
use_power = 0
autolinkers = list("hub_cent", "c_relay", "s_relay", "m_relay", "r_relay",
autolinkers = list("hub_cent", "c_relay", "s_relay", "m_relay", "r_relay", "e_relay",
"centcomm", "receiverCent", "broadcasterCent")
//Receivers
+1 -15
View File
@@ -416,7 +416,7 @@
var/list/data = list()
if(currently_vending)
data["mode"] = 1
data["product"] = currently_vending.product_name
data["product"] = sanitize(currently_vending.product_name)
data["price"] = currently_vending.price
data["message_err"] = 0
data["message"] = src.status_message
@@ -677,20 +677,6 @@
src.visible_message("\red <b>[src] launches [throw_item.name] at [target.name]!</b>")
return 1
/obj/machinery/vending/proc/shock(mob/user, prb)
if(stat & (BROKEN|NOPOWER)) // unpowered, no shock
return 0
if(!prob(prb))
return 0
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
if(electrocute_mob(user, get_area(src), src, 0.7))
return 1
else
return 0
/*
* Vending machine types
*/
@@ -372,9 +372,7 @@
if(!PN)
PN = new()
powernets += PN
NC.powernet = PN
PN.cables += NC
PN.add_cable(NC)
NC.mergeConnectedNetworks(NC.d2)
//NC.mergeConnectedNetworksOnTurf()
+4 -1
View File
@@ -701,4 +701,7 @@
spawn(0) //this is needed or multiple items will be thrown sequentially and not simultaneously
if(current_size >= STAGE_FOUR)
throw_at(S,14,3)
else ..()
else ..()
/obj/item/proc/pwr_drain()
return 0 // Process Kill
+38 -45
View File
@@ -59,10 +59,9 @@
icon_state = "cart-s"
access_security = 1
/obj/item/weapon/cartridge/security/New()
/obj/item/weapon/cartridge/security/initialize()
radio = new /obj/item/radio/integrated/beepsky(src)
..()
spawn(5)
radio = new /obj/item/radio/integrated/beepsky(src)
/obj/item/weapon/cartridge/detective
name = "D.E.T.E.C.T. Cartridge"
@@ -111,12 +110,9 @@
access_reagent_scanner = 1
access_atmos = 1
/obj/item/weapon/cartridge/signal/New()
/obj/item/weapon/cartridge/signal/initialize()
radio = new /obj/item/radio/integrated/signal(src)
..()
spawn(5)
radio = new /obj/item/radio/integrated/signal(src)
/obj/item/weapon/cartridge/quartermaster
name = "Space Parts & Space Vendors Cartridge"
@@ -124,10 +120,9 @@
icon_state = "cart-q"
access_quartermaster = 1
/obj/item/weapon/cartridge/quartermaster/New()
/obj/item/weapon/cartridge/quartermaster/initialize()
radio = new /obj/item/radio/integrated/mule(src)
..()
spawn(5)
radio = new /obj/item/radio/integrated/mule(src)
/obj/item/weapon/cartridge/head
name = "Easy-Record DELUXE"
@@ -142,10 +137,9 @@
access_janitor = 1
access_security = 1
/obj/item/weapon/cartridge/hop/New()
/obj/item/weapon/cartridge/hop/initialize()
radio = new /obj/item/radio/integrated/mule(src)
..()
spawn(5)
radio = new /obj/item/radio/integrated/mule(src)
/obj/item/weapon/cartridge/hos
name = "R.O.B.U.S.T. DELUXE"
@@ -153,10 +147,9 @@
access_status_display = 1
access_security = 1
/obj/item/weapon/cartridge/hos/New()
/obj/item/weapon/cartridge/hos/initialize()
radio = new /obj/item/radio/integrated/beepsky(src)
..()
spawn(5)
radio = new /obj/item/radio/integrated/beepsky(src)
/obj/item/weapon/cartridge/ce
name = "Power-On DELUXE"
@@ -179,10 +172,9 @@
access_reagent_scanner = 1
access_atmos = 1
/obj/item/weapon/cartridge/rd/New()
..()
spawn(5)
radio = new /obj/item/radio/integrated/signal(src)
/obj/item/weapon/cartridge/rd/initialize()
radio = new /obj/item/radio/integrated/signal(src)
..()
/obj/item/weapon/cartridge/captain
name = "Value-PAK Cartridge"
@@ -197,10 +189,9 @@
access_status_display = 1
access_atmos = 1
/obj/item/weapon/cartridge/captain/New()
..()
spawn(5)
radio = new /obj/item/radio/integrated/beepsky(src)
/obj/item/weapon/cartridge/captain/initialize()
radio = new /obj/item/radio/integrated/beepsky(src)
..()
/obj/item/weapon/cartridge/supervisor
name = "Easy-Record DELUXE"
@@ -221,10 +212,9 @@
access_status_display = 1
access_atmos = 1
/obj/item/weapon/cartridge/centcom/New()
/obj/item/weapon/cartridge/centcom/initialize()
radio = new /obj/item/radio/integrated/beepsky(src)
..()
spawn(5)
radio = new /obj/item/radio/integrated/beepsky(src)
/obj/item/weapon/cartridge/syndicate
name = "Detomatix Cartridge"
@@ -294,29 +284,32 @@
/* Power Monitor (Mode: 43 / 433) */
if(mode==43 || mode==433)
var/pMonData[0]
var/apcData[0]
for(var/obj/machinery/computer/monitor/pMon in world)
if(!(pMon.stat & (NOPOWER|BROKEN)) )
pMonData[++pMonData.len] = list ("Name" = pMon.name, "ref" = "\ref[pMon]")
if(isnull(powmonitor)) powmonitor = pMon
if(isnull(powmonitor)) powmonitor = pMon
values["powermonitors"] = pMonData
values["poweravail"] = powmonitor.powernet.avail
values["powerload"] = num2text(powmonitor.powernet.viewload,10)
if (!isnull(powmonitor.powernet))
values["powerconnected"] = 1
values["poweravail"] = powmonitor.powernet.avail
values["powerload"] = num2text(powmonitor.powernet.viewload,10)
var/list/L = list()
for(var/obj/machinery/power/terminal/term in powmonitor.powernet.nodes)
if(istype(term.master, /obj/machinery/power/apc))
var/obj/machinery/power/apc/A = term.master
L += A
var/list/L = list()
for(var/obj/machinery/power/terminal/term in powmonitor.powernet.nodes)
if(istype(term.master, /obj/machinery/power/apc))
var/obj/machinery/power/apc/A = term.master
L += A
var/list/Status = list(0,0,1,1) // Status: off, auto-off, on, auto-on
var/list/chg = list(0,1,1) // Charging: nope, charging, full
var/apcData[0]
for(var/obj/machinery/power/apc/A in L)
apcData[++apcData.len] = list("Name" = html_encode(A.area.name), "Equipment" = Status[A.equipment+1], "Lights" = Status[A.lighting+1], "Environment" = Status[A.environ+1], "CellPct" = A.cell ? round(A.cell.percent(),1) : -1, "CellStatus" = A.cell ? chg[A.charging+1] : 0)
values["apcs"] = apcData
var/list/Status = list(0,0,1,1) // Status: off, auto-off, on, auto-on
var/list/chg = list(0,1,1) // Charging: nope, charging, full
for(var/obj/machinery/power/apc/A in L)
apcData[++apcData.len] = list("Name" = html_encode(A.area.name), "Equipment" = Status[A.equipment+1], "Lights" = Status[A.lighting+1], "Environment" = Status[A.environ+1], "CellPct" = A.cell ? round(A.cell.percent(),1) : -1, "CellStatus" = A.cell ? chg[A.charging+1] : 0)
values["apcs"] = apcData
else
values["powerconnected"] = 0
+2 -5
View File
@@ -229,17 +229,14 @@
var/last_transmission
var/datum/radio_frequency/radio_connection
/obj/item/radio/integrated/signal/New()
..()
if(radio_controller)
initialize()
/obj/item/radio/integrated/signal/Destroy()
if(radio_controller)
radio_controller.remove_object(src, frequency)
return ..()
/obj/item/radio/integrated/signal/initialize()
if(!radio_controller)
return
if (src.frequency < 1441 || src.frequency > 1489)
src.frequency = sanitize_frequency(src.frequency)
@@ -115,9 +115,11 @@
M << "<span class='danger'>Your chameleon-projector deactivates.</span>"
master.disrupt()
/obj/effect/dummy/chameleon/ex_act() //ok now THATS some serious protection against explosions right here
/obj/effect/dummy/chameleon/ex_act(var/severity) //no longer bomb-proof
for(var/mob/M in src)
M << "<span class='danger'>Your chameleon-projector deactivates.</span>"
spawn()
M.ex_act(severity)
master.disrupt()
/obj/effect/dummy/chameleon/bullet_act()
+104 -99
View File
@@ -1,8 +1,8 @@
// Powersink - used to drain station power
/obj/item/device/powersink
desc = "A nulling power sink which drains energy from electrical systems."
name = "power sink"
desc = "A nulling power sink which drains energy from electrical systems."
icon_state = "powersink0"
item_state = "electronic"
w_class = 4.0
@@ -13,114 +13,119 @@
m_amt = 750
w_amt = 750
origin_tech = "powerstorage=3;syndicate=5"
var/drain_rate = 600000 // amount of power to drain per tick
var/power_drained = 0 // has drained this much power
var/max_power = 1e8 // maximum power that can be drained before exploding
var/mode = 0 // 0 = off, 1=clamped (off), 2=operating
var/drain_rate = 1500000 // amount of power to drain per tick
var/apc_drain_rate = 5000 // Max. amount drained from single APC. In Watts.
var/dissipation_rate = 20000 // Passive dissipation of drained power. In Watts.
var/power_drained = 0 // Amount of power drained.
var/max_power = 5e9 // Detonation point.
var/mode = 0 // 0 = off, 1=clamped (off), 2=operating
var/drained_this_tick = 0 // This is unfortunately necessary to ensure we process powersinks BEFORE other machinery such as APCs.
var/datum/powernet/PN // Our powernet
var/obj/structure/cable/attached // the attached cable
attackby(var/obj/item/I, var/mob/user, params)
if(istype(I, /obj/item/weapon/screwdriver))
if(mode == 0)
var/turf/T = loc
if(isturf(T) && !T.intact)
attached = locate() in T
if(!attached)
user << "No exposed cable here to attach to."
return
else
// attached.attached = src
anchored = 1
mode = 1
user << "You attach the device to the cable."
for(var/mob/M in viewers(user))
if(M == user) continue
M << "[user] attaches the power sink to the cable."
return
/obj/item/device/powersink/Destroy()
processing_objects.Remove(src)
processing_power_items.Remove(src)
return ..()
/obj/item/device/powersink/attackby(var/obj/item/I, var/mob/user)
if(istype(I, /obj/item/weapon/screwdriver))
if(mode == 0)
var/turf/T = loc
if(isturf(T) && !T.intact)
attached = locate() in T
if(!attached)
user << "No exposed cable here to attach to."
return
else
user << "Device must be placed over an exposed cable to attach to it."
anchored = 1
mode = 1
src.visible_message("<span class='notice'>[user] attaches [src] to the cable!</span>")
return
else
if (mode == 2)
processing_objects.Remove(src) // Now the power sink actually stops draining the station's power if you unhook it. --NeoFite
anchored = 0
mode = 0
user << "You detach the device from the cable."
// attached.attached = null
attached = null
for(var/mob/M in viewers(user))
if(M == user) continue
M << "[user] detaches the power sink from the cable."
set_light(0)
icon_state = "powersink0"
user << "Device must be placed over an exposed cable to attach to it."
return
else
if (mode == 2)
processing_objects.Remove(src) // Now the power sink actually stops draining the station's power if you unhook it. --NeoFite
processing_power_items.Remove(src)
anchored = 0
mode = 0
src.visible_message("<span class='notice'>[user] detaches [src] from the cable!</span>")
set_light(0)
icon_state = "powersink0"
return
else
..()
/obj/item/device/powersink/attack_ai()
return
/obj/item/device/powersink/attack_hand(var/mob/user)
switch(mode)
if(0)
..()
if(1)
src.visible_message("<span class='notice'>[user] activates [src]!</span>")
mode = 2
icon_state = "powersink1"
processing_objects.Add(src)
processing_power_items.Add(src)
if(2) //This switch option wasn't originally included. It exists now. --NeoFite
src.visible_message("<span class='notice'>[user] deactivates [src]!</span>")
mode = 1
set_light(0)
icon_state = "powersink0"
processing_objects.Remove(src)
processing_power_items.Remove(src)
Destroy()
set_light(0)
processing_objects.Remove(src)
// attached.attached = null
attached = null
return ..()
/obj/item/device/powersink/pwr_drain()
if(!attached)
return 0
if(drained_this_tick)
return 1
drained_this_tick = 1
var/drained = 0
if(!PN)
return 1
set_light(12)
PN.trigger_warning()
// found a powernet, so drain up to max power from it
drained = PN.draw_power(drain_rate)
// if tried to drain more than available on powernet
// now look for APCs and drain their cells
if(drained < drain_rate)
for(var/obj/machinery/power/terminal/T in PN.nodes)
// Enough power drained this tick, no need to torture more APCs
if(drained >= drain_rate)
break
if(istype(T.master, /obj/machinery/power/apc))
var/obj/machinery/power/apc/A = T.master
if(A.operating && A.cell)
var/cur_charge = A.cell.charge / CELLRATE
var/drain_val = min(apc_drain_rate, cur_charge)
A.cell.use(drain_val * CELLRATE)
drained += drain_val
power_drained += drained
return 1
attack_ai()
/obj/item/device/powersink/process()
drained_this_tick = 0
power_drained -= min(dissipation_rate, power_drained)
if(power_drained > max_power * 0.95)
playsound(src, 'sound/effects/screech.ogg', 100, 1, 1)
if(power_drained >= max_power)
explosion(src.loc, 3,6,9,12)
qdel(src)
return
attack_hand(var/mob/user)
switch(mode)
if(0)
..()
if(1)
user << "You activate the device!"
for(var/mob/M in viewers(user))
if(M == user) continue
M << "[user] activates the power sink!"
mode = 2
icon_state = "powersink1"
processing_objects.Add(src)
if(2) //This switch option wasn't originally included. It exists now. --NeoFite
user << "You deactivate the device!"
for(var/mob/M in viewers(user))
if(M == user) continue
M << "[user] deactivates the power sink!"
mode = 1
set_light(0)
icon_state = "powersink0"
processing_objects.Remove(src)
process()
if(attached)
var/datum/powernet/PN = attached.powernet
if(PN)
set_light(12)
// found a powernet, so drain up to max power from it
var/drained = min ( drain_rate, PN.avail )
PN.load += drained
power_drained += drained
// if tried to drain more than available on powernet
// now look for APCs and drain their cells
if(drained < drain_rate)
for(var/obj/machinery/power/terminal/T in PN.nodes)
if(istype(T.master, /obj/machinery/power/apc))
var/obj/machinery/power/apc/A = T.master
if(A.operating && A.cell)
A.cell.charge = max(0, A.cell.charge - 50)
power_drained += 50
if(power_drained > max_power * 0.95)
playsound(src, 'sound/effects/screech.ogg', 100, 1, 1)
if(power_drained >= max_power)
processing_objects.Remove(src)
explosion(src.loc, 3,6,9,12)
qdel(src)
if(attached && attached.powernet)
PN = attached.powernet
else
PN = null
+3
View File
@@ -191,6 +191,9 @@
/obj/item/stack/proc/get_amount()
return amount
/obj/item/stack/proc/get_max_amount()
return max_amount
/obj/item/stack/attack_hand(mob/user as mob)
if (user.get_inactive_hand() == src)
-3
View File
@@ -83,9 +83,6 @@
else
return null
/atom/movable/proc/initialize()
return
/obj/proc/updateUsrDialog()
if(in_use)
var/is_in_use = 0
+1 -1
View File
@@ -1139,7 +1139,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
for(var/obj/machinery/power/smes/SMES in world)
if(SMES.anchored)
SMES.chargemode = 1
SMES.input_attempt = 1
/client/proc/cmd_debug_mob_lists()
set category = "Debug"
+1 -1
View File
@@ -18,7 +18,7 @@
var/delay = 0
var/datum/radio_frequency/radio_connection
var/airlock_wire = null
New()
..()
if(!radio_controller)
+4 -4
View File
@@ -130,16 +130,16 @@
#if LIGHTING_FALLOFF == 1 //circular
#define LUM_DISTANCE(swapvar, O, T) swapvar = (O.x - T.x)**2 + (O.y - T.y)**2 + LIGHTING_HEIGHT
#if LIGHTING_LAMBERTIAN == 1
#define LUM_ATTENUATION(swapvar) swapvar = CLAMP01((1 - CLAMP01(sqrt(swapvar) / light_range)) * (1 / sqrt(swapvar + 1)))
#define LUM_ATTENUATION(swapvar) swapvar = CLAMP01((1 - CLAMP01(sqrt(swapvar) / max(1,light_range))) * (1 / sqrt(swapvar + 1)))
#else
#define LUM_ATTENUATION(swapvar) swapvar = 1 - CLAMP01(sqrt(swapvar) / light_range)
#define LUM_ATTENUATION(swapvar) swapvar = 1 - CLAMP01(sqrt(swapvar) / max(1,light_range))
#endif
#elif LIGHTING_FALLOFF == 2 //square
#define LUM_DISTANCE(swapvar, O, T) swapvar = abs(O.x - T.x) + abs(O.y - T.y) + LIGHTING_HEIGHT
#if LIGHTING_LAMBERTIAN == 1
#define LUM_ATTENUATION(swapvar) swapvar = CLAMP01((1 - CLAMP01(swapvar / light_range)) * (1 / sqrt(swapvar**2 + 1)))
#define LUM_ATTENUATION(swapvar) swapvar = CLAMP01((1 - CLAMP01(swapvar / max(1,light_range))) * (1 / sqrt(swapvar**2 + 1)))
#else
#define LUM_ATTENUATION(swapvar) swapvar = CLAMP01(swapvar / light_range)
#define LUM_ATTENUATION(swapvar) swapvar = CLAMP01(swapvar / max(1,light_range))
#endif
#endif
@@ -45,7 +45,7 @@
icon_state = "alien[caste]_leap"
pixel_x = -32
pixel_y = -32
else if(icon == 'icons/mob/alienleap.dmi' && icon_state == "alien[caste]_leap" && pixel_x == -32 && pixel_y == -32)
else if(icon == 'icons/mob/alienleap.dmi' && pixel_x == -32 && pixel_y == -32)
icon = initial(icon)// ^ this looks odd, but in theory it will prevent the icon and pixel_xy from being reset unless it needs to be
pixel_x = initial(pixel_x)
pixel_y = initial(pixel_y)
@@ -65,11 +65,11 @@
return 1
// if(M.health < -75) return 0
if((M.head && (M.head.flags & HEADCOVERSMOUTH)) || (M.wear_mask && (M.wear_mask.flags & MASKCOVERSMOUTH)))
M << "\blue <B>Remove your mask!</B>"
if((M.head && (M.head.flags & HEADCOVERSMOUTH)) || (M.wear_mask && (M.wear_mask.flags & MASKCOVERSMOUTH) && !M.wear_mask.mask_adjusted))
M << "<span class='boldnotice'>Remove your mask!</span>"
return 0
if((head && (head.flags & HEADCOVERSMOUTH)) || (wear_mask && (wear_mask.flags & MASKCOVERSMOUTH)))
M << "\blue <B>Remove his mask!</B>"
if((head && (head.flags & HEADCOVERSMOUTH)) || (wear_mask && (wear_mask.flags & MASKCOVERSMOUTH) && !wear_mask.mask_adjusted))
M << "<span class='boldnotice'>Remove his mask!</span>"
return 0
var/obj/effect/equip_e/human/O = new /obj/effect/equip_e/human()
File diff suppressed because it is too large Load Diff
+174 -299
View File
@@ -1,10 +1,16 @@
//////////////////////////////
// POWER MACHINERY BASE CLASS
//////////////////////////////
/////////////////////////////
// Definitions
/////////////////////////////
/obj/machinery/power
name = null
icon = 'icons/obj/power.dmi'
anchored = 1.0
var/datum/powernet/powernet = null
var/directwired = 1 // by default, power machines are connected by a cable in a neighbouring turf
// if set to 0, requires a 0-X cable on this turf
use_power = 0
idle_power_usage = 0
active_power_usage = 0
@@ -13,14 +19,19 @@
disconnect_from_network()
return ..()
///////////////////////////////
// General procedures
//////////////////////////////
// common helper procs for all power machines
/obj/machinery/power/proc/add_avail(var/amount)
if(powernet)
powernet.newavail += amount
/obj/machinery/power/proc/add_load(var/amount)
/obj/machinery/power/proc/draw_power(var/amount)
if(powernet)
powernet.load += amount
return powernet.draw_power(amount)
return 0
/obj/machinery/power/proc/surplus()
if(powernet)
@@ -34,17 +45,16 @@
else
return 0
/obj/machinery/power/proc/disconnect_terminal() // machines without a terminal will just return, no harm no fowl.
return
// returns true if the area has power on given channel (or doesn't require power).
// defaults to power_channel
/obj/machinery/proc/powered(var/chan = -1)
/obj/machinery/proc/powered(var/chan = -1) // defaults to power_channel
if(!src.loc)
return 0
if(!use_power)
return 1
var/area/A = src.loc.loc // make sure it's in an area
if(!A || !isarea(A))
return 0 // if not, then not powered
@@ -71,94 +81,63 @@
stat |= NOPOWER
return
// connect the machine to a powernet if a node cable is present on the turf
/obj/machinery/power/proc/connect_to_network()
var/turf/T = src.loc
if(!T || !istype(T))
return 0
// the powernet datum
// each contiguous network of cables & nodes
// rebuild all power networks from scratch
/hook/startup/proc/buildPowernets()
return makepowernets()
/proc/makepowernets()
for(var/datum/powernet/PN in powernets)
qdel(PN)
powernets.Cut()
for(var/obj/structure/cable/PC in cable_list)
if(!PC.powernet)
PC.powernet = new()
powernets += PC.powernet
// if(Debug) world.log << "Starting mpn at [PC.x],[PC.y] ([PC.d1]/[PC.d2])"
powernet_nextlink(PC,PC.powernet)
// if(Debug) world.log << "[powernets.len] powernets found"
for(var/obj/structure/cable/C in cable_list)
if(!C.powernet) continue
C.powernet.cables += C
for(var/obj/machinery/power/M in machines)
if(!M.powernet) continue // APCs have powernet=0 so they don't count as network nodes directly
M.powernet.nodes[M] = M
var/obj/structure/cable/C = T.get_cable_node() //check if we have a node cable on the machine turf, the first found is picked
if(!C || !C.powernet)
return 0
C.powernet.add_machine(src)
return 1
// remove and disconnect the machine from its current powernet
/obj/machinery/power/proc/disconnect_from_network()
if(!powernet)
return 0
powernet.remove_machine(src)
return 1
// returns a list of all power-related objects (nodes, cable, junctions) in turf,
// excluding source, that match the direction d
// if unmarked==1, only return those with no powernet
/proc/power_list(var/turf/T, var/source, var/d, var/unmarked=0)
. = list()
var/fdir = (!d)? 0 : turn(d, 180) // the opposite direction to d (or 0 if d==0)
// world.log << "d=[d] fdir=[fdir]"
for(var/AM in T)
if(AM == source) continue //we don't want to return source
// attach a wire to a power machine - leads from the turf you are standing on
//almost never called, overwritten by all power machines but terminal and generator
/obj/machinery/power/attackby(obj/item/weapon/W, mob/user)
if(istype(AM,/obj/machinery/power))
var/obj/machinery/power/P = AM
if(P.powernet == 0) continue // exclude APCs which have powernet=0
if(istype(W, /obj/item/stack/cable_coil))
if(!unmarked || !P.powernet) //if unmarked=1 we only return things with no powernet
if(P.directwired || (d == 0))
. += P
var/obj/item/stack/cable_coil/coil = W
else if(istype(AM,/obj/structure/cable))
var/obj/structure/cable/C = AM
var/turf/T = user.loc
if(!unmarked || !C.powernet)
if(C.d1 == fdir || C.d2 == fdir)
. += C
else if(C.d1 == turn(C.d2, 180))
. += C
return .
if(T.intact || !istype(T, /turf/simulated/floor))
return
if(get_dist(src, user) > 1)
return
/obj/structure/cable/proc/get_connections()
. = list() // this will be a list of all connected power objects
var/turf/T = loc
if(d1) T = get_step(src, d1)
if(T) . += power_list(T, src, d1, 1)
T = get_step(src, d2)
if(T) . += power_list(T, src, d2, 1)
return .
coil.turf_place(T, user)
return
else
..()
return
///////////////////////////////////////////
// Powernet handling helpers
//////////////////////////////////////////
//returns all the cables WITHOUT a powernet in neighbors turfs,
//pointing towards the turf the machine is located at
/obj/machinery/power/proc/get_connections()
. = list()
if(!directwired)
return get_indirect_connections()
var/cdir
var/turf/T
for(var/card in cardinal)
var/turf/T = get_step(loc,card)
T = get_step(loc,card)
cdir = get_dir(T,loc)
for(var/obj/structure/cable/C in T)
@@ -167,193 +146,132 @@
. += C
return .
//returns all the cables in neighbors turfs,
//pointing towards the turf the machine is located at
/obj/machinery/power/proc/get_marked_connections()
. = list()
var/cdir
var/turf/T
for(var/card in cardinal)
T = get_step(loc,card)
cdir = get_dir(T,loc)
for(var/obj/structure/cable/C in T)
if(C.d1 == cdir || C.d2 == cdir)
. += C
return .
//returns all the NODES (O-X) cables WITHOUT a powernet in the turf the machine is located at
/obj/machinery/power/proc/get_indirect_connections()
. = list()
for(var/obj/structure/cable/C in loc)
if(C.powernet) continue
if(C.d1 == 0)
if(C.d1 == 0) // the cable is a node cable
. += C
return .
///////////////////////////////////////////
// GLOBAL PROCS for powernets handling
//////////////////////////////////////////
/proc/powernet_nextlink(var/obj/O, var/datum/powernet/PN)
var/list/P
while(1)
if( istype(O,/obj/structure/cable) )
var/obj/structure/cable/C = O
C.powernet = PN
P = C.get_connections()
// returns a list of all power-related objects (nodes, cable, junctions) in turf,
// excluding source, that match the direction d
// if unmarked==1, only return those with no powernet
/proc/power_list(var/turf/T, var/source, var/d, var/unmarked=0, var/cable_only = 0)
. = list()
var/fdir = (!d)? 0 : turn(d, 180) // the opposite direction to d (or 0 if d==0)
///// Z-Level Stuff
var/Zdir
if(d==11)
Zdir = 11
else if (d==12)
Zdir = 12
else
Zdir = 999
///// Z-Level Stuff
for(var/AM in T)
if(AM == source) continue //we don't want to return source
else if(O.anchored && istype(O,/obj/machinery/power))
var/obj/machinery/power/M = O
M.powernet = PN
P = M.get_connections()
if(!cable_only && istype(AM,/obj/machinery/power))
var/obj/machinery/power/P = AM
if(P.powernet == 0) continue // exclude APCs which have powernet=0
if(!unmarked || !P.powernet) //if unmarked=1 we only return things with no powernet
if(d == 0)
. += P
else if(istype(AM,/obj/structure/cable))
var/obj/structure/cable/C = AM
if(!unmarked || !C.powernet)
///// Z-Level Stuff
if(C.d1 == fdir || C.d2 == fdir || C.d1 == Zdir || C.d2 == Zdir)
///// Z-Level Stuff
. += C
else if(C.d1 == d || C.d2 == d)
. += C
return .
/hook/startup/proc/buildPowernets()
return makepowernets()
// rebuild all power networks from scratch - only called at world creation or by the admin verb
/proc/makepowernets()
for(var/datum/powernet/PN in powernets)
qdel(PN)
powernets.Cut()
for(var/obj/structure/cable/PC in cable_list)
if(!PC.powernet)
var/datum/powernet/NewPN = new()
NewPN.add_cable(PC)
propagate_network(PC,PC.powernet)
return 1
//remove the old powernet and replace it with a new one throughout the network.
/proc/propagate_network(var/obj/O, var/datum/powernet/PN)
//world.log << "propagating new network"
var/list/worklist = list()
var/list/found_machines = list()
var/index = 1
var/obj/P = null
worklist+=O //start propagating from the passed object
while(index<=worklist.len) //until we've exhausted all power objects
P = worklist[index] //get the next power object found
index++
if( istype(P,/obj/structure/cable))
var/obj/structure/cable/C = P
if(C.powernet != PN) //add it to the powernet, if it isn't already there
PN.add_cable(C)
worklist |= C.get_connections() //get adjacents power objects, with or without a powernet
else if(P.anchored && istype(P,/obj/machinery/power))
var/obj/machinery/power/M = P
found_machines |= M //we wait until the powernet is fully propagates to connect the machines
else
return
continue
if(P.len == 0) return
O = P[1]
for(var/L = 2 to P.len)
powernet_nextlink(P[L], PN)
//now that the powernet is set, connect found machines to it
for(var/obj/machinery/power/PM in found_machines)
if(!PM.connect_to_network()) //couldn't find a node on its turf...
PM.disconnect_from_network() //... so disconnect if already on a powernet
// cut a powernet at this cable object
/datum/powernet/proc/cut_cable(var/obj/structure/cable/C)
var/turf/T1 = C.loc
if(!T1) return
var/node = 0
if(C.d1 == 0)
node = 1
var/turf/T2
if(C.d2) T2 = get_step(T1, C.d2)
if(C.d1) T1 = get_step(T1, C.d1)
var/list/P1 = power_list(T1, C, C.d1) // what joins on to cut cable in dir1
var/list/P2 = power_list(T2, C, C.d2) // what joins on to cut cable in dir2
// if(Debug)
// for(var/obj/O in P1)
// world.log << "P1: [O] at [O.x] [O.y] : [istype(O, /obj/structure/cable) ? "[O:d1]/[O:d2]" : null] "
// for(var/obj/O in P2)
// world.log << "P2: [O] at [O.x] [O.y] : [istype(O, /obj/structure/cable) ? "[O:d1]/[O:d2]" : null] "
if(P1.len == 0 || P2.len == 0)//if nothing in either list, then the cable was an endpoint no need to rebuild the powernet,
cables -= C //just remove cut cable from the list
// if(Debug) world.log << "Was end of cable"
//Merge two powernets, the bigger (in cable length term) absorbing the other
/proc/merge_powernets(var/datum/powernet/net1, var/datum/powernet/net2)
if(!net1 || !net2) //if one of the powernet doesn't exist, return
return
//null the powernet reference of all cables & nodes in this powernet
var/i=1
while(i<=cables.len)
var/obj/structure/cable/Cable = cables[i]
if(Cable)
Cable.powernet = null
if(Cable == C)
cables.Cut(i,i+1)
continue
i++
i=1
while(i<=nodes.len)
var/obj/machinery/power/Node = nodes[i]
if(Node)
Node.powernet = null
i++
// remove the cut cable from the network
// C.netnum = -1
C.loc = null
powernet_nextlink(P1[1], src) // propagate network from 1st side of cable, using current netnum //TODO?
// now test to see if propagation reached to the other side
// if so, then there's a loop in the network
var/notlooped = 0
for(var/O in P2)
if( istype(O, /obj/machinery/power) )
var/obj/machinery/power/Machine = O
if(Machine.powernet != src)
notlooped = 1
break
else if( istype(O, /obj/structure/cable) )
var/obj/structure/cable/Cable = O
if(Cable.powernet != src)
notlooped = 1
break
if(notlooped)
// not looped, so make a new powernet
var/datum/powernet/PN = new()
powernets += PN
// if(Debug) world.log << "Was not looped: spliting PN#[number] ([cables.len];[nodes.len])"
i=1
while(i<=cables.len)
var/obj/structure/cable/Cable = cables[i]
if(Cable && !Cable.powernet) // non-connected cables will have powernet=null, since they weren't reached by propagation
Cable.powernet = PN
cables.Cut(i,i+1) // remove from old network & add to new one
PN.cables += Cable
continue
i++
i=1
while(i<=nodes.len)
var/obj/machinery/power/Node = nodes[i]
if(Node && !Node.powernet)
Node.powernet = PN
nodes.Cut(i,i+1)
PN.nodes[Node] = Node
continue
i++
// Disconnect machines connected to nodes
if(node)
for(var/obj/machinery/power/P in T1)
if(P.powernet && !P.powernet.nodes[src])
P.disconnect_from_network()
// if(Debug)
// world.log << "Old PN#[number] : ([cables.len];[nodes.len])"
// world.log << "New PN#[PN.number] : ([PN.cables.len];[PN.nodes.len])"
//
// else
// if(Debug)
// world.log << "Was looped."
// //there is a loop, so nothing to be done
// return
/datum/powernet/proc/reset()
//see if there's a surplus of power remaining in the powernet and stores unused power in the SMES
netexcess = avail - load
if(netexcess > 100 && nodes && nodes.len) // if there was excess power last cycle
for(var/obj/machinery/power/smes/S in nodes) // find the SMESes in the network
S.restore() // and restore some of the power that was used
//updates the viewed load (as seen on power computers)
viewload = 0.8*viewload + 0.2*load
viewload = round(viewload)
//reset the powernet
load = 0
avail = newavail
newavail = 0
/datum/powernet/proc/get_electrocute_damage()
switch(avail)
if (5000000 to INFINITY)
return min(rand(200,300),rand(200,300))
if (4000000 to 5000000)
return min(rand(80,180),rand(80,180))
if (1000000 to 4000000)
return min(rand(50,160),rand(50,160))
if (200000 to 1000000)
return min(rand(25,80),rand(25,80))
if (100000 to 200000)//Ave powernet
return min(rand(20,60),rand(20,60))
if (50000 to 100000)
return min(rand(15,40),rand(15,40))
if (1000 to 50000)
return min(rand(10,20),rand(10,20))
else
return 0
//The powernet that calls this proc will consume the other powernet - Rockdtben
//TODO: rewrite so the larger net absorbs the smaller net
/proc/merge_powernets(var/datum/powernet/net1, var/datum/powernet/net2)
if(!net1 || !net2) return
if(net1 == net2) return
if(net1 == net2) //don't merge same powernets
return
//We assume net1 is larger. If net2 is in fact larger we are just going to make them switch places to reduce on code.
if(net1.cables.len < net2.cables.len) //net2 is larger than net1. Let's switch them around
@@ -361,57 +279,18 @@
net1 = net2
net2 = temp
for(var/i=1,i<=net2.nodes.len,i++) //merge net2 into net1
var/obj/machinery/power/Node = net2.nodes[i]
if(Node)
Node.powernet = net1
net1.nodes[Node] = Node
//merge net2 into net1
for(var/obj/structure/cable/Cable in net2.cables) //merge cables
net1.add_cable(Cable)
if(!net2) return net1
for(var/i=1,i<=net2.cables.len,i++)
var/obj/structure/cable/Cable = net2.cables[i]
if(Cable)
Cable.powernet = net1
net1.cables += Cable
for(var/obj/machinery/power/Node in net2.nodes) //merge power machines
if(!Node.connect_to_network())
Node.disconnect_from_network() //if somehow we can't connect the machine to the new powernet, disconnect it from the old nonetheless
qdel(net2)
return net1
/obj/machinery/power/proc/connect_to_network()
var/turf/T = src.loc
var/obj/structure/cable/C = T.get_cable_node()
if(!C || !C.powernet) return 0
// makepowernets() //TODO: find fast way //EWWWW what are you doing!?
powernet = C.powernet
powernet.nodes[src] = src
return 1
/obj/machinery/power/proc/disconnect_from_network()
if(!powernet)
//world << " no powernet"
return 0
powernet.nodes -= src
powernet = null
//world << "powernet null"
return 1
/turf/proc/get_cable_node()
if(!istype(src, /turf/simulated/floor))
return null
for(var/obj/structure/cable/C in src)
if(C.d1 == 0)
return C
return null
/area/proc/get_apc()
// This was a simple locate() in src, but an unresolved BYOND bug causes trying to locate() in an
// area to take an inconceivably long time, especially for large areas.
// See: http://www.byond.com/forum/?post=1860571
var/obj/machinery/power/apc/FINDME
for(FINDME in src)
return FINDME
//Determines how strong could be shock, deals damage to mob, uses power.
//M is a mob who touched wire/whatever
//power_source is a source of electricity, can be powercell, area, apc, cable, powernet or null
@@ -419,9 +298,6 @@
//No animations will be performed by this proc.
/proc/electrocute_mob(mob/living/carbon/M as mob, var/power_source, var/obj/source, var/siemens_coeff = 1.0)
if(istype(M.loc,/obj/mecha)) return 0 //feckin mechs are dumb
//This is for performance optimization only.
//DO NOT modify siemens_coeff here. That is checked in human/electrocute_act()
if(istype(M,/mob/living/carbon/human))
var/mob/living/carbon/human/H = M
if(H.gloves)
@@ -475,8 +351,7 @@
source_area.use_power(drained_energy/CELLRATE)
else if (istype(power_source,/datum/powernet))
var/drained_power = drained_energy/CELLRATE //convert from "joules" to "watts"
PN.load+=drained_power
drained_power = PN.draw_power(drained_power)
else if (istype(power_source, /obj/item/weapon/stock_parts/cell))
cell.use(drained_energy)
return drained_energy
+162
View File
@@ -0,0 +1,162 @@
/datum/powernet
var/list/cables = list() // all cables & junctions
var/list/nodes = list() // all connected machines
var/load = 0 // the current load on the powernet, increased by each machine at processing
var/newavail = 0 // what available power was gathered last tick, then becomes...
var/avail = 0 //...the current available power in the powernet
var/viewload = 0 // the load as it appears on the power console (gradually updated)
var/number = 0 // Unused //TODEL
var/perapc = 0 // per-apc avilability
var/perapc_excess = 0
var/netexcess = 0 // excess power on the powernet (typically avail-load)
var/problem = 0 // If either of these is set to 1 there is some sort of issue at the powernet.
/datum/powernet/New()
powernets += src
..()
/datum/powernet/Destroy()
powernets -= src
return ..()
//Returns the amount of excess power (before refunding to SMESs) from last tick.
//This is for machines that might adjust their power consumption using this data.
/datum/powernet/proc/last_surplus()
return max(avail - load, 0)
/datum/powernet/proc/draw_power(var/amount)
var/draw = between(0, amount, avail - load)
load += draw
return draw
/datum/powernet/proc/is_empty()
return !cables.len && !nodes.len
//remove a cable from the current powernet
//if the powernet is then empty, delete it
//Warning : this proc DON'T check if the cable exists
/datum/powernet/proc/remove_cable(var/obj/structure/cable/C)
cables -= C
C.powernet = null
if(is_empty())//the powernet is now empty...
del(src)///... delete it - qdel
//add a cable to the current powernet
//Warning : this proc DON'T check if the cable exists
/datum/powernet/proc/add_cable(var/obj/structure/cable/C)
if(C.powernet)// if C already has a powernet...
if(C.powernet == src)
return
else
C.powernet.remove_cable(C) //..remove it
C.powernet = src
cables +=C
//remove a power machine from the current powernet
//if the powernet is then empty, delete it
//Warning : this proc DON'T check if the machine exists
/datum/powernet/proc/remove_machine(var/obj/machinery/power/M)
nodes -=M
M.powernet = null
if(is_empty())//the powernet is now empty...
del(src)///... delete it - qdel
//add a power machine to the current powernet
//Warning : this proc DON'T check if the machine exists
/datum/powernet/proc/add_machine(var/obj/machinery/power/M)
if(M.powernet)// if M already has a powernet...
if(M.powernet == src)
return
else
M.disconnect_from_network()//..remove it
M.powernet = src
nodes[M] = M
// Triggers warning for certain amount of ticks
/datum/powernet/proc/trigger_warning(var/duration_ticks = 20)
problem = max(duration_ticks, problem)
//handles the power changes in the powernet
//called every ticks by the powernet controller
/datum/powernet/proc/reset()
var/numapc = 0
if(problem > 0)
problem = max(problem - 1, 0)
if(nodes && nodes.len) // Added to fix a bad list bug -- TLE
for(var/obj/machinery/power/terminal/term in nodes)
if( istype( term.master, /obj/machinery/power/apc ) )
numapc++
netexcess = avail - load
if(numapc)
//very simple load balancing. If there was a net excess this tick then it must have been that some APCs used less than perapc, since perapc*numapc = avail
//Therefore we can raise the amount of power rationed out to APCs on the assumption that those APCs that used less than perapc will continue to do so.
//If that assumption fails, then some APCs will miss out on power next tick, however it will be rebalanced for the tick after.
if (netexcess >= 0)
perapc_excess += min(netexcess/numapc, (avail - perapc) - perapc_excess)
else
perapc_excess = 0
perapc = avail/numapc + perapc_excess
if(netexcess > 100 && nodes && nodes.len) // if there was excess power last cycle
for(var/obj/machinery/power/smes/S in nodes) // find the SMESes in the network
S.restore() // and restore some of the power that was used
//updates the viewed load (as seen on power computers)
viewload = round(load)
//reset the powernet
load = 0
avail = newavail
newavail = 0
/datum/powernet/proc/get_electrocute_damage()
switch(avail)
if (5000000 to INFINITY)
return min(rand(200,300),rand(200,300))
if (4000000 to 5000000)
return min(rand(80,180),rand(80,180))
if (1000000 to 4000000)
return min(rand(50,160),rand(50,160))
if (200000 to 1000000)
return min(rand(25,80),rand(25,80))
if (100000 to 200000)//Ave powernet
return min(rand(20,60),rand(20,60))
if (50000 to 100000)
return min(rand(15,40),rand(15,40))
if (1000 to 50000)
return min(rand(10,20),rand(10,20))
else
return 0
////////////////////////////////////////////////
// Misc.
///////////////////////////////////////////////
// return a knot cable (O-X) if one is present in the turf
// null if there's none
/turf/proc/get_cable_node()
if(!istype(src, /turf/simulated/floor))
return null
for(var/obj/structure/cable/C in src)
if(C.d1 == 0)
return C
return null
/area/proc/get_apc()
// This was a simple locate() in src, but an unresolved BYOND bug causes trying to locate() in an
// area to take an inconceivably long time, especially for large areas.
// See: http://www.byond.com/forum/?post=1860571
var/obj/machinery/power/apc/FINDME
for(FINDME in src)
return FINDME
@@ -8,7 +8,6 @@ var/global/list/rad_collectors = list()
icon_state = "ca"
anchored = 0
density = 1
directwired = 1
req_access = list(access_engine_equip)
// use_power = 0
var/obj/item/weapon/tank/plasma/P = null
@@ -46,57 +46,23 @@
return 1
return 0
/obj/machinery/containment_field/proc/shock(mob/living/user as mob)
/obj/machinery/containment_field/shock(mob/living/user as mob)
if(hasShocked)
return 0
if(!FG1 || !FG2)
qdel(src)
return 0
if(iscarbon(user))
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, user.loc)
s.start()
if(isliving(user))
hasShocked = 1
var/shock_damage = min(rand(30,40),rand(30,40))
user.burn_skin(shock_damage)
user.updatehealth()
user.visible_message("\red [user.name] was shocked by the [src.name]!", \
"\red <B>You feel a powerful shock course through your body sending you flying!</B>", \
"\red You hear a heavy electrical crack")
user.electrocute_act(shock_damage, src)
var/stun = min(shock_damage, 15)
user.Stun(stun)
user.Weaken(10)
user.updatehealth()
var/atom/target = get_edge_target_turf(user, get_dir(src, get_step_away(user, src)))
user.throw_at(target, 200, 4)
sleep(20)
hasShocked = 0
return
else if(issilicon(user))
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, user.loc)
s.start()
hasShocked = 1
var/shock_damage = rand(15,30)
user.take_overall_damage(0,shock_damage)
user.visible_message("\red [user.name] was shocked by the [src.name]!", \
"\red <B>Energy pulse detected, system damaged!</B>", \
"\red You hear an electrical crack")
if(prob(20))
user.Stun(2)
sleep(20)
hasShocked = 0
return
return
/obj/machinery/containment_field/proc/set_master(var/master1,var/master2)
+4 -10
View File
@@ -48,7 +48,6 @@
..()
if(state == 2 && anchored)
connect_to_network()
src.directwired = 1
if(frequency)
set_frequency(frequency)
/obj/machinery/power/emitter/multitool_menu(var/mob/user,var/obj/item/device/multitool/P)
@@ -145,8 +144,8 @@
return
if(((src.last_shot + src.fire_delay) <= world.time) && (src.active == 1))
if(!active_power_usage || avail(active_power_usage))
add_load(active_power_usage)
var/actual_load = draw_power(active_power_usage)
if(actual_load >= active_power_usage) //does the laser have enough power to shoot?
if(!powered)
powered = 1
update_icon()
@@ -238,7 +237,6 @@
state = 2
user << "You weld the [src] to the floor."
connect_to_network()
src.directwired = 1
else
user << "\red You need more welding fuel to complete this task."
if(2)
@@ -252,7 +250,6 @@
state = 1
user << "You cut the [src] free from the floor."
disconnect_from_network()
src.directwired = 0
else
user << "\red You need more welding fuel to complete this task."
return
@@ -275,11 +272,8 @@
..()
return
/obj/machinery/power/emitter/emag_act(user as mob)
/obj/machinery/power/emitter/emag_act(var/mob/living/user as mob)
if(!emagged)
if(!ishuman(user))
return
var/mob/living/carbon/human/H = user
locked = 0
emagged = 1
H.visible_message("[H.name] emags the [src.name].","\red You short out the lock.")
user.visible_message("[user.name] emags the [src.name].","\red You short out the lock.")
+185 -200
View File
@@ -13,22 +13,32 @@
icon_state = "smes"
density = 1
anchored = 1
use_power = 0
var/output = 50000
var/lastout = 0
var/loaddemand = 0
var/capacity = 5e6
var/charge = 0
var/charging = 0
var/chargemode = 0
var/chargecount = 0
var/chargelevel = 50000
var/input_level_max = 200000 // cap on input_level
var/output_level_max = 200000 // cap on output_level
var/online = 1
var/capacity = 5e6 // maximum charge
var/charge = 0 // actual charge
var/input_attempt = 0 // 1 = attempting to charge, 0 = not attempting to charge
var/inputting = 0 // 1 = actually inputting, 0 = not inputting
var/input_level = 50000 // amount of power the SMES attempts to charge by
var/input_level_max = 200000 // cap on input_level
var/input_available = 0 // amount of charge available from input last tick
var/output_attempt = 1 // 1 = attempting to output, 0 = not attempting to output
var/outputting = 1 // 1 = actually outputting, 0 = not outputting
var/output_level = 50000 // amount of power the SMES attempts to output
var/output_level_max = 200000 // cap on output_level
var/output_used = 0 // amount of power actually outputted. may be less than output_level if the powernet returns excess power
//Holders for powerout event.
var/last_output_attempt = 0
var/last_input_attempt = 0
var/last_charge = 0
var/open_hatch = 0
var/name_tag = null
var/building_terminal = 0 //Suggestions about how to avoid clickspam building several terminals accepted!
var/obj/machinery/power/terminal/terminal = null
var/list/overlay_images
/obj/machinery/power/smes/New()
..()
@@ -42,35 +52,7 @@
component_parts += new /obj/item/weapon/stock_parts/capacitor(null)
component_parts += new /obj/item/stack/cable_coil(null, 5)
RefreshParts()
setup()
return
/obj/machinery/power/smes/upgraded/New()
..()
component_parts = list()
component_parts += new /obj/item/weapon/circuitboard/smes(null)
component_parts += new /obj/item/weapon/stock_parts/cell/hyper(null)
component_parts += new /obj/item/weapon/stock_parts/cell/hyper(null)
component_parts += new /obj/item/weapon/stock_parts/cell/hyper(null)
component_parts += new /obj/item/weapon/stock_parts/cell/hyper(null)
component_parts += new /obj/item/weapon/stock_parts/cell/hyper(null)
component_parts += new /obj/item/weapon/stock_parts/capacitor/super(null)
component_parts += new /obj/item/stack/cable_coil(null, 5)
RefreshParts()
return
/obj/machinery/power/smes/RefreshParts()
var/IO = 0
var/C = 0
for(var/obj/item/weapon/stock_parts/capacitor/CP in component_parts)
IO += CP.rating
input_level_max = 200000 * IO
output_level_max = 200000 * IO
for(var/obj/item/weapon/stock_parts/cell/PC in component_parts)
C += PC.maxcharge
capacity = C / (15000) * 1e6
/obj/machinery/power/smes/proc/setup()
spawn(5)
if(!powernet)
connect_to_network()
@@ -88,43 +70,52 @@
terminal.master = src
if(!terminal.powernet)
terminal.connect_to_network()
updateicon()
update_icon()
return
/obj/machinery/power/smes/proc/updateicon()
/obj/machinery/power/smes/upgraded/New()
..()
component_parts = list()
component_parts += new /obj/item/weapon/circuitboard/smes(null)
component_parts += new /obj/item/weapon/stock_parts/cell/hyper(null)
component_parts += new /obj/item/weapon/stock_parts/cell/hyper(null)
component_parts += new /obj/item/weapon/stock_parts/cell/hyper(null)
component_parts += new /obj/item/weapon/stock_parts/cell/hyper(null)
component_parts += new /obj/item/weapon/stock_parts/cell/hyper(null)
component_parts += new /obj/item/weapon/stock_parts/capacitor/super(null)
component_parts += new /obj/item/stack/cable_coil(null, 5)
RefreshParts()
/obj/machinery/power/smes/RefreshParts()
var/IO = 0
var/C = 0
for(var/obj/item/weapon/stock_parts/capacitor/CP in component_parts)
IO += CP.rating
input_level_max = 200000 * IO
output_level_max = 200000 * IO
for(var/obj/item/weapon/stock_parts/cell/PC in component_parts)
C += PC.maxcharge
capacity = C / (15000) * 1e6
/obj/machinery/power/smes/update_icon()
overlays.Cut()
if(stat & BROKEN) return
if(isnull(src.overlay_images))
src.overlay_images = new
src.overlay_images.len = 3
overlays += image('icons/obj/power.dmi', "smes-op[outputting]")
src.overlay_images[1] = image('icons/obj/power.dmi', "smes-op[online]")
src.overlay_images[2] = image('icons/obj/power.dmi', "smes-oc0")
src.overlay_images[3] = image('icons/obj/power.dmi', "smes-og1")
var/image/buffer
buffer = src.overlay_images[1]
buffer.icon_state = "smes-op[online]"
overlays += src.overlay_images[1]
if(!charging && chargemode)
buffer = src.overlay_images[2]
buffer.icon_state = "smes-oc0"
overlays += src.overlay_images[2]
if(inputting == 2)
overlays += image('icons/obj/power.dmi', "smes-oc2")
else if (inputting == 1)
overlays += image('icons/obj/power.dmi', "smes-oc1")
else
buffer = src.overlay_images[2]
buffer.icon_state = "smes-oc1"
overlays += src.overlay_images[2]
if(input_attempt)
overlays += image('icons/obj/power.dmi', "smes-oc0")
var/clevel = chargedisplay()
if(clevel > 0)
buffer = src.overlay_images[3]
buffer.icon_state = "smes-og[clevel]"
overlays += src.overlay_images[3]
if(clevel>0)
overlays += image('icons/obj/power.dmi', "smes-og[clevel]")
return
/obj/machinery/power/smes/attackby(obj/item/I, mob/user, params)
//opening using screwdriver
if(default_deconstruction_screwdriver(user, "[initial(icon_state)]-o", initial(icon_state), I))
@@ -220,7 +211,7 @@
user.visible_message(\
"<span class='alert'>[user.name] cuts the cables and dismantles the power terminal.</span>",\
"You cut the cables and dismantle the power terminal.")
charging = 0 //stop inputting, since we have don't have a terminal anymore
inputting = 0 //stop inputting, since we have don't have a terminal anymore
qdel(terminal)
return
@@ -238,92 +229,70 @@
disconnect_terminal()
return ..()
// create a terminal object pointing towards the SMES
// wires will attach to this
/obj/machinery/power/smes/proc/make_terminal(var/turf/T)
terminal = new/obj/machinery/power/terminal(T)
terminal.dir = get_dir(T,src)
terminal.master = src
/obj/machinery/power/smes/proc/disconnect_terminal()
if(terminal)
terminal.master = null
terminal = null
return round(5.5*charge/(capacity ? capacity : 5e6))
/obj/machinery/power/smes/proc/chargedisplay()
return round(5.5*charge/capacity)
return round(5.5*charge/(capacity ? capacity : 5e6))
#define SMESRATE 0.05
/obj/machinery/power/smes/process()
if(stat & BROKEN)
return
if(stat & BROKEN) return
//store machine state to see if we need to update the icon overlays
var/last_disp = chargedisplay()
var/last_chrg = charging
var/last_onln = online
var/last_chrg = inputting
var/last_onln = outputting
if(terminal)
var/excess = terminal.surplus()
//inputting
if(input_attempt)
var/target_load = min((capacity-charge)/SMESRATE, input_level) // charge at set rate, limited to spare capacity
var/actual_load = draw_power(target_load) // add the load to the terminal side network
charge += actual_load * SMESRATE // increase the charge
if(charging)
if(excess >= 0) // if there's power available, try to charge
if (actual_load >= target_load) // Did we charge at full rate?
inputting = 2
else if (actual_load) // If not, did we charge at least partially?
inputting = 1
else // Or not at all?
inputting = 0
var/load = min((capacity-charge)/SMESRATE, chargelevel) // charge at set rate, limited to spare capacity
//outputting
if(outputting)
output_used = min( charge/SMESRATE, output_level) //limit output to that stored
charge += load * SMESRATE // increase the charge
charge -= output_used*SMESRATE // reduce the storage (may be recovered in /restore() if excessive)
add_load(load) // add the load to the terminal side network
add_avail(output_used) // add output to powernet (smes side)
else // if not enough capcity
charging = 0 // stop charging
chargecount = 0
else
if(chargemode)
if(chargecount > rand(3,6))
charging = 1
chargecount = 0
if(excess > chargelevel)
chargecount++
else
chargecount = 0
else
chargecount = 0
if(online) // if outputting
lastout = min( charge/SMESRATE, output) //limit output to that stored
charge -= lastout*SMESRATE // reduce the storage (may be recovered in /restore() if excessive)
add_avail(lastout) // add output to powernet (smes side)
if(charge < 0.0001)
online = 0 // stop output if charge falls to zero
if(output_used < 0.0001) // either from no charge or set to 0
outputting = 0
investigate_log("lost power and turned <font color='red'>off</font>","singulo")
else if(output_attempt && charge > output_level && output_level > 0)
outputting = 1
else
output_used = 0
// only update icon if state changed
if(last_disp != chargedisplay() || last_chrg != charging || last_onln != online)
updateicon()
if(last_disp != chargedisplay() || last_chrg != inputting || last_onln != outputting)
update_icon()
return
// called after all power processes are finished
// restores charge level to smes if there was excess this ptick
/obj/machinery/power/smes/proc/restore()
if(stat & BROKEN)
return
if(!online)
loaddemand = 0
if(!outputting)
output_used = 0
return
var/excess = powernet.netexcess // this was how much wasn't used on the network last ptick, minus any removed by other SMESes
excess = min(lastout, excess) // clamp it to how much was actually output by this SMES last ptick
excess = min(output_used, excess) // clamp it to how much was actually output by this SMES last ptick
excess = min((capacity-charge)/SMESRATE, excess) // for safety, also limit recharge by space capacity of SMES (shouldn't happen)
@@ -331,23 +300,51 @@
var/clev = chargedisplay()
charge += excess * SMESRATE
charge += excess * SMESRATE // restore unused power
powernet.netexcess -= excess // remove the excess from the powernet, so later SMESes don't try to use it
loaddemand = lastout-excess
output_used -= excess
if(clev != chargedisplay() )
updateicon()
if(clev != chargedisplay() ) //if needed updates the icons overlay
update_icon()
return
//Will return 1 on failure
/obj/machinery/power/smes/proc/make_terminal(const/mob/user)
if (user.loc == loc)
user << "<span class='warning'>You must not be on the same tile as the [src].</span>"
return 1
/obj/machinery/power/smes/add_load(var/amount)
//Direction the terminal will face to
var/tempDir = get_dir(user, src)
switch(tempDir)
if (NORTHEAST, SOUTHEAST)
tempDir = EAST
if (NORTHWEST, SOUTHWEST)
tempDir = WEST
var/turf/tempLoc = get_step(src, reverse_direction(tempDir))
if (istype(tempLoc, /turf/space))
user << "<span class='warning'>You can't build a terminal on space.</span>"
return 1
else if (istype(tempLoc))
if(tempLoc.intact)
user << "<span class='warning'>You must remove the floor plating first.</span>"
return 1
user << "<span class='notice'>You start adding cable to the [src].</span>"
if(do_after(user, 50))
terminal = new /obj/machinery/power/terminal(tempLoc)
terminal.dir = tempDir
terminal.master = src
return 0
return 1
/obj/machinery/power/smes/draw_power(var/amount)
if(terminal && terminal.powernet)
terminal.powernet.load += amount
return terminal.powernet.draw_power(amount)
return 0
/obj/machinery/power/smes/attack_ai(mob/user)
add_fingerprint(user)
add_hiddenprint(user)
ui_interact(user)
/obj/machinery/power/smes/attack_ghost(mob/user)
@@ -361,7 +358,6 @@
return
/obj/machinery/power/smes/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
if(stat & BROKEN)
return
@@ -369,14 +365,21 @@
var/data[0]
data["nameTag"] = name_tag
data["storedCapacity"] = round(100.0*charge/capacity, 0.1)
data["charging"] = charging
data["chargeMode"] = chargemode
data["chargeLevel"] = chargelevel
data["charging"] = inputting
data["chargeMode"] = input_attempt
data["chargeLevel"] = input_level
data["chargeMax"] = input_level_max
data["outputOnline"] = online
data["outputLevel"] = output
data["outputOnline"] = output_attempt
data["outputLevel"] = output_level
data["outputMax"] = output_level_max
data["outputLoad"] = round(loaddemand)
data["outputLoad"] = round(output_used)
if(outputting)
data["outputting"] = 2 // smes is outputting
else if(!outputting && output_attempt)
data["outputting"] = 1 // smes is online but not outputting because it's charge level is too low
else
data["outputting"] = 0 // smes is not outputting
// update the ui if it exists, returns null if no ui is passed/found
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
@@ -391,60 +394,45 @@
// auto update every Master Controller tick
ui.set_auto_update(1)
/obj/machinery/power/smes/Topic(href, href_list)
..()
if (usr.stat || usr.restrained() )
return
if (!(istype(usr, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
if(!istype(usr, /mob/living/silicon/ai))
usr << "\red You don't have the dexterity to do this!"
return
//world << "[href] ; [href_list[href]]"
if (!istype(src.loc, /turf) && !istype(usr, /mob/living/silicon/))
return 0 // Do not update ui
if(..())
return 1
if( href_list["cmode"] )
chargemode = !chargemode
if(!chargemode)
charging = 0
updateicon()
inputting(!input_attempt)
update_icon()
else if( href_list["online"] )
online = !online
updateicon()
outputting(!output_attempt)
update_icon()
else if( href_list["input"] )
switch( href_list["input"] )
if("min")
chargelevel = 0
input_level = 0
if("max")
chargelevel = input_level_max //30000
input_level = input_level_max
if("set")
chargelevel = input(usr, "Enter new input level (0-[input_level_max])", "SMES Input Power Control", chargelevel) as num
chargelevel = max(0, min(input_level_max, chargelevel)) // clamp to range
input_level = input(usr, "Enter new input level (0-[input_level_max])", "SMES Input Power Control", input_level) as num
input_level = max(0, min(input_level_max, input_level)) // clamp to range
else if( href_list["output"] )
switch( href_list["output"] )
if("min")
output = 0
output_level = 0
if("max")
output = output_level_max //30000
output_level = output_level_max
if("set")
output = input(usr, "Enter new output level (0-[output_level_max])", "SMES Output Power Control", output) as num
output = max(0, min(output_level_max, output)) // clamp to range
output_level = input(usr, "Enter new output level (0-[output_level_max])", "SMES Output Power Control", output_level) as num
output_level = max(0, min(output_level_max, output_level)) // clamp to range
investigate_log("input/output; [chargelevel>output?"<font color='green'>":"<font color='red'>"][chargelevel]/[output]</font> | Output-mode: [online?"<font color='green'>on</font>":"<font color='red'>off</font>"] | Input-mode: [chargemode?"<font color='green'>auto</font>":"<font color='red'>off</font>"] by [usr.key]","singulo")
investigate_log("input/output; [input_level>output_level?"<font color='green'>":"<font color='red'>"][input_level]/[output_level]</font> | Output-mode: [output_attempt?"<font color='green'>on</font>":"<font color='red'>off</font>"] | Input-mode: [input_attempt?"<font color='green'>auto</font>":"<font color='red'>off</font>"] by [usr.key]","singulo")
return 1
/obj/machinery/power/smes/proc/ion_act()
if((src.z in config.station_levels))
if(src.z in config.station_levels)
if(prob(1)) //explosion
world << "\red SMES explosion in [src.loc.loc]"
for(var/mob/M in viewers(src))
M.show_message("\red The [src.name] is making strange noises!", 3, "\red You hear sizzling electronics.", 2)
sleep(10*pick(4,5,6,7,10,14))
@@ -452,11 +440,10 @@
smoke.set_up(3, 0, src.loc)
smoke.attach(src)
smoke.start()
explosion(src.loc, -1, 0, 1, 3, 0)
explosion(src.loc, -1, 0, 1, 3, 1, 0)
qdel(src)
return
if(prob(15)) //Power drain
world << "\red SMES power drain in [src.loc.loc]"
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
@@ -465,45 +452,43 @@
else
emp_act(2)
if(prob(5)) //smoke only
world << "\red SMES smoke in [src.loc.loc]"
var/datum/effect/effect/system/harmless_smoke_spread/smoke = new /datum/effect/effect/system/harmless_smoke_spread()
smoke.set_up(3, 0, src.loc)
smoke.attach(src)
smoke.start()
/obj/machinery/power/smes/proc/inputting(var/do_input)
input_attempt = do_input
if(!input_attempt)
inputting = 0
/obj/machinery/power/smes/proc/outputting(var/do_output)
output_attempt = do_output
if(!output_attempt)
outputting = 0
/obj/machinery/power/smes/emp_act(severity)
online = 0
charging = 0
output = 0
inputting(rand(0,1))
outputting(rand(0,1))
output_level = rand(0, output_level_max)
input_level = rand(0, input_level_max)
charge -= 1e6/severity
if (charge < 0)
charge = 0
spawn(100)
output = initial(output)
charging = initial(charging)
online = initial(online)
update_icon()
..()
/obj/machinery/power/smes/engineering
charge = 1e6 // Engineering starts with some charge for singulo
charge = 1e6 // Engineering starts with some charge for singulo
/obj/machinery/power/smes/magical
name = "magical power storage unit"
desc = "A high-capacity superconducting magnetic energy storage (SMES) unit. Magically produces power."
process()
capacity = INFINITY
charge = INFINITY
..()
capacity = 9000000
output_level = 250000
/proc/rate_control(var/S, var/V, var/C, var/Min=1, var/Max=5, var/Limit=null)
var/href = "<A href='?src=\ref[S];rate control=1;[V]"
var/rate = "[href]=-[Max]'>-</A>[href]=-[Min]'>-</A> [(C?C : 0)] [href]=[Min]'>+</A>[href]=[Max]'>+</A>"
if(Limit) return "[href]=-[Limit]'>-</A>"+rate+"[href]=[Limit]'>+</A>"
return rate
/obj/machinery/power/smes/magical/process()
charge = 5000000
..()
#undef SMESRATE
#undef SMESRATE
+34 -19
View File
@@ -289,16 +289,25 @@
var/lastgen = 0
var/track = 0 // 0= off 1=timed 2=auto (tracker)
var/trackrate = 600 // 300-900 seconds
var/nexttime = 0 // time for a panel to rotate of 1° in manual tracking
var/nexttime = 0 // time for a panel to rotate of 1? in manual tracking
var/autostart = 0 // Automatically search for connected devices
var/obj/machinery/power/tracker/connected_tracker = null
var/list/connected_panels = list()
// Used for mapping in solar array which automatically starts itself (telecomms, for example)
/obj/machinery/power/solar_control/autostart
track = 2 // Auto tracking mode
autostart = 1 // Automatically start
/obj/machinery/power/solar_control/New()
/obj/machinery/power/solar_control/initialize()
..()
if(ticker)
initialize()
connect_to_network()
if(!powernet)
return
if(autostart)
src.search_for_connected()
if(connected_tracker && track == 2)
connected_tracker.set_angle(sun.angle)
set_panels(cdir)
/obj/machinery/power/solar_control/Destroy()
for(var/obj/machinery/power/solar/M in connected_panels)
@@ -309,11 +318,12 @@
/obj/machinery/power/solar_control/disconnect_from_network()
..()
sun.solars.Remove(src)
if(sun)
sun.solars.Remove(src)
/obj/machinery/power/solar_control/connect_to_network()
var/to_return = ..()
if(powernet) //if connected and not already in solar list...
if(powernet && sun) //if connected and not already in solar list...
sun.solars |= src //... add it
return to_return
@@ -347,12 +357,6 @@
set_panels(cdir)
updateDialog()
/obj/machinery/power/solar_control/initialize()
..()
if(!powernet) return
set_panels(cdir)
/obj/machinery/power/solar_control/update_icon()
overlays.Cut()
if(stat & NOPOWER)
@@ -366,9 +370,21 @@
if(cdir > -1)
overlays += image('icons/obj/computer.dmi', "solcon-o", FLY_LAYER, angle2dir(cdir))
/obj/machinery/power/solar_control/attack_ai(mob/user as mob)
src.add_hiddenprint(user)
ui_interact(user)
/obj/machinery/power/solar_control/attack_ghost(mob/user as mob)
ui_interact(user)
/obj/machinery/power/solar_control/attack_hand(mob/user)
if(!..())
ui_interact(user)
if(..(user))
return 1
if(stat & BROKEN)
return
ui_interact(user)
/obj/machinery/power/solar_control/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
@@ -438,9 +454,9 @@
connected_tracker.unset_control()
if(track==1 && trackrate) //manual tracking and set a rotation speed
if(nexttime <= world.time) //every time we need to increase/decrease the angle by 1°...
if(nexttime <= world.time) //every time we need to increase/decrease the angle by 1?...
targetdir = (targetdir + trackrate/abs(trackrate) + 360) % 360 //... do it
nexttime += 36000/abs(trackrate) //reset the counter for the next 1°
nexttime += 36000/abs(trackrate) //reset the counter for the next 1?
/obj/machinery/power/solar_control/Topic(href, href_list)
if(..())
@@ -514,7 +530,6 @@
broken()
src.density = 0
//
// MISC
//
+5 -1
View File
@@ -11,7 +11,6 @@
layer = TURF_LAYER
var/obj/machinery/power/master = null
anchored = 1
directwired = 0 // must have a cable on same turf connecting to terminal
layer = 2.6 // a bit above wires
@@ -20,6 +19,11 @@
var/turf/T = src.loc
if(level==1) hide(T.intact)
return
/obj/machinery/power/terminal/Destroy()
if(master)
master.disconnect_terminal()
return ..()
/obj/machinery/power/terminal/hide(var/i)
+4 -4
View File
@@ -27,7 +27,7 @@
//set the control of the tracker to a given computer if closer than SOLAR_MAX_DIST
/obj/machinery/power/tracker/proc/set_control(var/obj/machinery/power/solar_control/SC)
if(!SC || (get_dist(src, SC) > SOLAR_MAX_DIST))
if(SC && (get_dist(src, SC) > SOLAR_MAX_DIST))
return 0
control = SC
SC.connected_tracker = src
@@ -58,7 +58,7 @@
if(powernet && (powernet == control.powernet)) //update if we're still in the same powernet
control.cdir = angle
/obj/machinery/power/tracker/attackby(var/obj/item/weapon/W, var/mob/user, params)
/obj/machinery/power/tracker/attackby(var/obj/item/weapon/W, var/mob/user)
if(istype(W, /obj/item/weapon/crowbar))
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
@@ -70,7 +70,7 @@
S.give_glass()
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
user.visible_message("<span class='notice'>[user] takes the glass off the tracker.</span>")
qdel(src)
qdel(src) // qdel
return
..()
@@ -81,4 +81,4 @@
name = "tracker electronics"
icon = 'icons/obj/doors/door_assembly.dmi'
icon_state = "door_electronics"
w_class = 2.0
w_class = 2.0
-1
View File
@@ -22,7 +22,6 @@
anchored = 1
density = 1
var/obj/machinery/compressor/compressor
directwired = 1
var/turf/simulated/outturf
var/lastgen
@@ -176,7 +176,7 @@
reagents.add_reagent("methamphetamine", 5)
/obj/item/weapon/reagent_containers/pill/charcoal
name = "Chacoal pill"
name = "Charcoal pill"
desc = "Neutralizes many common toxins."
icon_state = "pill17"
New()
-14
View File
@@ -35,20 +35,6 @@
src.disable_wire = pick(w)
w -= src.disable_wire
/obj/machinery/r_n_d/proc/
shock(mob/user, prb)
if(stat & (BROKEN|NOPOWER)) // unpowered, no shock
return 0
if(!prob(prb))
return 0
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
if (electrocute_mob(user, get_area(src), src, 0.7))
return 1
else
return 0
/obj/machinery/r_n_d/attack_hand(mob/user as mob)
if (shocked)
shock(user,50)
+1 -1
View File
@@ -18,7 +18,7 @@ var/global/datum/global_init/init = new ()
cache_lifespan = 0 //stops player uploaded stuff from being kept in the rsc past the current session
#define RECOMMENDED_VERSION 501
#define RECOMMENDED_VERSION 508
/world/New()
//logs