Whitespace Standardization [MDB IGNORE] (#15748)

* Update settings

* Whitespace changes

* Comment out merger hooks in gitattributes

Corrupt maps would have to be resolved in repo before hooks could be updated

* Revert "Whitespace changes"

This reverts commit afbdd1d8442973f5d570c30920d9d865b5acd479.

* Whitespace again minus example

* Gitignore example changelog

* Restore changelog merge setting

* Keep older dmi hook attribute until hooks can be updated

* update vscode settings too

* Renormalize remaining

* Revert "Gitignore example changelog"

This reverts commit de22ad375d3ee4d5930c550da2fd23a29a86e616.

* Attempt to normalize example.yml (and another file I guess)

* Try again
This commit is contained in:
Drathek
2024-02-20 11:28:51 +01:00
committed by GitHub
parent 3b61f677b3
commit 7c8bb85de3
1175 changed files with 818171 additions and 818145 deletions
+95 -95
View File
@@ -1,95 +1,95 @@
//This file was auto-corrected by findeclaration.exe on 29/05/2012 15:03:05
#define STATE_DEFAULT 1
#define STATE_INJECTOR 2
#define STATE_ENGINE 3
/obj/machinery/computer/am_engine
name = "Antimatter Engine Console"
icon = 'icons/obj/stationobjs.dmi'
icon_state = "comm_computer"
req_access = list(ACCESS_ENGINE)
var/engine_id = 0
var/authenticated = 0
var/obj/machinery/power/am_engine/engine/connected_E = null
var/obj/machinery/power/am_engine/injector/connected_I = null
var/state = STATE_DEFAULT
/obj/machinery/computer/am_engine/New()
..()
spawn( 24 )
for(var/obj/machinery/power/am_engine/engine/E in world)
if(E.engine_id == src.engine_id)
src.connected_E = E
for(var/obj/machinery/power/am_engine/injector/I in world)
if(I.engine_id == src.engine_id)
src.connected_I = I
return
/obj/machinery/computer/am_engine/Topic(href, href_list)
if(..())
return
usr.machine = src
if(!href_list["operation"])
return
switch(href_list["operation"])
// main interface
if("activate")
src.connected_E.engine_process()
if("engine")
src.state = STATE_ENGINE
if("injector")
src.state = STATE_INJECTOR
if("main")
src.state = STATE_DEFAULT
if("login")
var/mob/M = usr
var/obj/item/weapon/card/id/I = M.get_active_hand()
if (I && istype(I))
if(src.check_access(I))
authenticated = 1
if("deactivate")
src.connected_E.stopping = 1
if("logout")
authenticated = 0
src.updateUsrDialog()
/obj/machinery/computer/am_engine/attack_ai(var/mob/user as mob)
return src.attack_hand(user)
/obj/machinery/computer/am_engine/attack_paw(var/mob/user as mob)
return src.attack_hand(user)
/obj/machinery/computer/am_engine/attack_hand(var/mob/user as mob)
if(..())
return
user.machine = src
var/dat = "<head><title>Engine Computer</title></head><body>"
switch(src.state)
if(STATE_DEFAULT)
if (src.authenticated)
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=logout'>Log Out</A> \]<br>"
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=engine'>Engine Menu</A> \]"
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=injector'>Injector Menu</A> \]"
else
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=login'>Log In</A> \]"
if(STATE_INJECTOR)
if(src.connected_I.injecting)
dat += "<BR>\[ Injecting \]<br>"
else
dat += "<BR>\[ Injecting not in progress \]<br>"
if(STATE_ENGINE)
if(src.connected_E.stopping)
dat += "<BR>\[ STOPPING \]"
else if(src.connected_E.operating && !src.connected_E.stopping)
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=deactivate'>Emergency Stop</A> \]"
else
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=activate'>Activate Engine</A> \]"
dat += "<BR>Contents:<br>[src.connected_E.H_fuel]kg of Hydrogen<br>[src.connected_E.antiH_fuel]kg of Anti-Hydrogen<br>"
dat += "<BR>\[ [(src.state != STATE_DEFAULT) ? "<A HREF='?src=\ref[src];operation=main'>Main Menu</A> | " : ""]<A HREF='?src=\ref[user];mach_close=communications'>Close</A> \]"
user << browse(dat, "window=communications;size=400x500")
onclose(user, "communications")
//This file was auto-corrected by findeclaration.exe on 29/05/2012 15:03:05
#define STATE_DEFAULT 1
#define STATE_INJECTOR 2
#define STATE_ENGINE 3
/obj/machinery/computer/am_engine
name = "Antimatter Engine Console"
icon = 'icons/obj/stationobjs.dmi'
icon_state = "comm_computer"
req_access = list(ACCESS_ENGINE)
var/engine_id = 0
var/authenticated = 0
var/obj/machinery/power/am_engine/engine/connected_E = null
var/obj/machinery/power/am_engine/injector/connected_I = null
var/state = STATE_DEFAULT
/obj/machinery/computer/am_engine/New()
..()
spawn( 24 )
for(var/obj/machinery/power/am_engine/engine/E in world)
if(E.engine_id == src.engine_id)
src.connected_E = E
for(var/obj/machinery/power/am_engine/injector/I in world)
if(I.engine_id == src.engine_id)
src.connected_I = I
return
/obj/machinery/computer/am_engine/Topic(href, href_list)
if(..())
return
usr.machine = src
if(!href_list["operation"])
return
switch(href_list["operation"])
// main interface
if("activate")
src.connected_E.engine_process()
if("engine")
src.state = STATE_ENGINE
if("injector")
src.state = STATE_INJECTOR
if("main")
src.state = STATE_DEFAULT
if("login")
var/mob/M = usr
var/obj/item/weapon/card/id/I = M.get_active_hand()
if (I && istype(I))
if(src.check_access(I))
authenticated = 1
if("deactivate")
src.connected_E.stopping = 1
if("logout")
authenticated = 0
src.updateUsrDialog()
/obj/machinery/computer/am_engine/attack_ai(var/mob/user as mob)
return src.attack_hand(user)
/obj/machinery/computer/am_engine/attack_paw(var/mob/user as mob)
return src.attack_hand(user)
/obj/machinery/computer/am_engine/attack_hand(var/mob/user as mob)
if(..())
return
user.machine = src
var/dat = "<head><title>Engine Computer</title></head><body>"
switch(src.state)
if(STATE_DEFAULT)
if (src.authenticated)
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=logout'>Log Out</A> \]<br>"
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=engine'>Engine Menu</A> \]"
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=injector'>Injector Menu</A> \]"
else
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=login'>Log In</A> \]"
if(STATE_INJECTOR)
if(src.connected_I.injecting)
dat += "<BR>\[ Injecting \]<br>"
else
dat += "<BR>\[ Injecting not in progress \]<br>"
if(STATE_ENGINE)
if(src.connected_E.stopping)
dat += "<BR>\[ STOPPING \]"
else if(src.connected_E.operating && !src.connected_E.stopping)
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=deactivate'>Emergency Stop</A> \]"
else
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=activate'>Activate Engine</A> \]"
dat += "<BR>Contents:<br>[src.connected_E.H_fuel]kg of Hydrogen<br>[src.connected_E.antiH_fuel]kg of Anti-Hydrogen<br>"
dat += "<BR>\[ [(src.state != STATE_DEFAULT) ? "<A HREF='?src=\ref[src];operation=main'>Main Menu</A> | " : ""]<A HREF='?src=\ref[user];mach_close=communications'>Close</A> \]"
user << browse(dat, "window=communications;size=400x500")
onclose(user, "communications")
@@ -1,41 +1,41 @@
/obj/item/weapon/am_containment
name = "antimatter containment jar"
desc = "Holds antimatter."
icon = 'icons/obj/machines/antimatter.dmi'
icon_state = "jar"
density = FALSE
anchored = FALSE
force = 8
throwforce = 10
throw_speed = 1
throw_range = 2
var/fuel = 10000
var/fuel_max = 10000//Lets try this for now
var/stability = 100//TODO: add all the stability things to this so its not very safe if you keep hitting in on things
/obj/item/weapon/am_containment/ex_act(severity)
switch(severity)
if(1.0)
explosion(get_turf(src), 1, 2, 3, 5)//Should likely be larger but this works fine for now I guess
if(src)
qdel(src)
return
if(2.0)
if(prob((fuel/10)-stability))
explosion(get_turf(src), 1, 2, 3, 5)
if(src)
qdel(src)
return
stability -= 40
if(3.0)
stability -= 20
//check_stability()
return
/obj/item/weapon/am_containment/proc/usefuel(var/wanted)
if(fuel < wanted)
wanted = fuel
fuel -= wanted
/obj/item/weapon/am_containment
name = "antimatter containment jar"
desc = "Holds antimatter."
icon = 'icons/obj/machines/antimatter.dmi'
icon_state = "jar"
density = FALSE
anchored = FALSE
force = 8
throwforce = 10
throw_speed = 1
throw_range = 2
var/fuel = 10000
var/fuel_max = 10000//Lets try this for now
var/stability = 100//TODO: add all the stability things to this so its not very safe if you keep hitting in on things
/obj/item/weapon/am_containment/ex_act(severity)
switch(severity)
if(1.0)
explosion(get_turf(src), 1, 2, 3, 5)//Should likely be larger but this works fine for now I guess
if(src)
qdel(src)
return
if(2.0)
if(prob((fuel/10)-stability))
explosion(get_turf(src), 1, 2, 3, 5)
if(src)
qdel(src)
return
stability -= 40
if(3.0)
stability -= 20
//check_stability()
return
/obj/item/weapon/am_containment/proc/usefuel(var/wanted)
if(fuel < wanted)
wanted = fuel
fuel -= wanted
return wanted
+330 -330
View File
@@ -1,330 +1,330 @@
/obj/machinery/power/am_control_unit
name = "antimatter control unit"
desc = "This device injects antimatter into connected shielding units, the more antimatter injected the more power produced. Wrench the device to set it up."
icon = 'icons/obj/machines/antimatter.dmi'
icon_state = "control"
anchored = TRUE
density = TRUE
use_power = USE_POWER_IDLE
idle_power_usage = 100
active_power_usage = 1000
var/list/obj/machinery/am_shielding/linked_shielding
var/list/obj/machinery/am_shielding/linked_cores
var/obj/item/weapon/am_containment/fueljar
var/update_shield_icons = 0
var/stability = 100
var/exploding = 0
var/active = 0//On or not
var/fuel_injection = 2//How much fuel to inject
var/shield_icon_delay = 0//delays resetting for a short time
var/reported_core_efficiency = 0
var/power_cycle = 0
var/power_cycle_delay = 4//How many ticks till produce_power is called
var/stored_core_stability = 0
var/stored_core_stability_delay = 0
var/stored_power = 0//Power to deploy per tick
/obj/machinery/power/am_control_unit/New()
..()
linked_shielding = list()
linked_cores = list()
/obj/machinery/power/am_control_unit/Destroy()//Perhaps damage and run stability checks rather than just qdel on the others
for(var/obj/machinery/am_shielding/AMS in linked_shielding)
qdel(AMS)
..()
/obj/machinery/power/am_control_unit/process()
if(exploding)
explosion(get_turf(src),8,12,18,12)
if(src) qdel(src)
if(update_shield_icons && !shield_icon_delay)
check_shield_icons()
update_shield_icons = 0
if(stat & (NOPOWER|BROKEN) || !active)//can update the icons even without power
return
if(!fueljar)//No fuel but we are on, shutdown
toggle_power()
//Angry buzz or such here
return
add_avail(stored_power)
power_cycle++
if(power_cycle >= power_cycle_delay)
produce_power()
power_cycle = 0
return
/obj/machinery/power/am_control_unit/proc/produce_power()
playsound(src, 'sound/effects/bang.ogg', 25, 1)
var/core_power = reported_core_efficiency//Effectively how much fuel we can safely deal with
if(core_power <= 0) return 0//Something is wrong
var/core_damage = 0
var/fuel = fueljar.usefuel(fuel_injection)
stored_power = (fuel/core_power)*fuel*200000
//Now check if the cores could deal with it safely, this is done after so you can overload for more power if needed, still a bad idea
if(fuel > (2*core_power))//More fuel has been put in than the current cores can deal with
if(prob(50))core_damage = 1//Small chance of damage
if((fuel-core_power) > 5) core_damage = 5//Now its really starting to overload the cores
if((fuel-core_power) > 10) core_damage = 20//Welp now you did it, they wont stand much of this
if(core_damage == 0) return
for(var/obj/machinery/am_shielding/AMS in linked_cores)
AMS.stability -= core_damage
AMS.check_stability(1)
playsound(src, 'sound/effects/bang.ogg', 50, 1)
return
/obj/machinery/power/am_control_unit/emp_act(severity)
switch(severity)
if(1)
if(active) toggle_power()
stability -= rand(15,30)
if(2)
if(active) toggle_power()
stability -= rand(10,20)
if(3)
if(active) toggle_power()
stability -= rand(8,15)
if(4)
if(active) toggle_power()
stability -= rand(5,10)
..()
return 0
/obj/machinery/power/am_control_unit/ex_act(severity)
switch(severity)
if(1.0)
stability -= 60
if(2.0)
stability -= 40
if(3.0)
stability -= 20
check_stability()
return
/obj/machinery/power/am_control_unit/bullet_act(var/obj/item/projectile/Proj)
if(Proj.check_armour != "bullet")
stability -= Proj.force
return 0
/obj/machinery/power/am_control_unit/power_change()
..()
if(stat & NOPOWER && active)
toggle_power()
return
/obj/machinery/power/am_control_unit/update_icon()
if(active) icon_state = "control_on"
else icon_state = "control"
//No other icons for it atm
/obj/machinery/power/am_control_unit/attackby(obj/item/W, mob/user)
if(!istype(W) || !user) return
if(W.has_tool_quality(TOOL_WRENCH))
if(!anchored)
playsound(src, W.usesound, 75, 1)
user.visible_message("[user.name] secures the [src.name] to the floor.", \
"You secure the anchor bolts to the floor.", \
"You hear a ratchet.")
src.anchored = TRUE
connect_to_network()
else if(!linked_shielding.len > 0)
playsound(src, W.usesound, 75, 1)
user.visible_message("[user.name] unsecures the [src.name].", \
"You remove the anchor bolts.", \
"You hear a ratchet.")
src.anchored = FALSE
disconnect_from_network()
else
to_chat(user, span_red("Once bolted and linked to a shielding unit it the [src.name] is unable to be moved!"))
return
if(istype(W, /obj/item/weapon/am_containment))
if(fueljar)
to_chat(user, span_red("There is already a [fueljar] inside!"))
return
fueljar = W
user.remove_from_mob(W)
W.loc = src
user.update_icons()
user.visible_message("[user.name] loads an [W.name] into the [src.name].", \
"You load an [W.name].", \
"You hear a thunk.")
return
if(W.force >= 20)
stability -= W.force/2
check_stability()
..()
return
/obj/machinery/power/am_control_unit/attack_hand(mob/user as mob)
if(anchored)
interact(user)
return
/obj/machinery/power/am_control_unit/proc/add_shielding(var/obj/machinery/am_shielding/AMS, var/AMS_linking = 0)
if(!istype(AMS)) return 0
if(!anchored) return 0
if(!AMS_linking && !AMS.link_control(src)) return 0
linked_shielding.Add(AMS)
update_shield_icons = 1
return 1
/obj/machinery/power/am_control_unit/proc/remove_shielding(var/obj/machinery/am_shielding/AMS)
if(!istype(AMS)) return 0
linked_shielding.Remove(AMS)
update_shield_icons = 2
if(active) toggle_power()
return 1
/obj/machinery/power/am_control_unit/proc/check_stability()//TODO: make it break when low also might want to add a way to fix it like a part or such that can be replaced
if(stability <= 0)
qdel(src)
return
/obj/machinery/power/am_control_unit/proc/toggle_power()
active = !active
if(active)
update_use_power(USE_POWER_ACTIVE)
visible_message("The [src.name] starts up.")
else
update_use_power(USE_POWER_IDLE)
visible_message("The [src.name] shuts down.")
update_icon()
return
/obj/machinery/power/am_control_unit/proc/check_shield_icons()//Forces icon_update for all shields
if(shield_icon_delay) return
shield_icon_delay = 1
if(update_shield_icons == 2)//2 means to clear everything and rebuild
for(var/obj/machinery/am_shielding/AMS in linked_shielding)
if(AMS.processing) AMS.shutdown_core()
AMS.control_unit = null
spawn(10)
AMS.controllerscan()
linked_shielding = list()
else
for(var/obj/machinery/am_shielding/AMS in linked_shielding)
AMS.update_icon()
spawn(20)
shield_icon_delay = 0
return
/obj/machinery/power/am_control_unit/proc/check_core_stability()
if(stored_core_stability_delay || linked_cores.len <= 0) return
stored_core_stability_delay = 1
stored_core_stability = 0
for(var/obj/machinery/am_shielding/AMS in linked_cores)
stored_core_stability += AMS.stability
stored_core_stability/=linked_cores.len
spawn(40)
stored_core_stability_delay = 0
return
/obj/machinery/power/am_control_unit/interact(mob/user)
if((get_dist(src, user) > 1) || (stat & (BROKEN|NOPOWER)))
if(!istype(user, /mob/living/silicon/ai))
user.unset_machine()
user << browse(null, "window=AMcontrol")
return
user.set_machine(src)
var/dat = ""
dat += "AntiMatter Control Panel<BR>"
dat += "<A href='?src=\ref[src];close=1'>Close</A><BR>"
dat += "<A href='?src=\ref[src];refresh=1'>Refresh</A><BR>"
dat += "<A href='?src=\ref[src];refreshicons=1'>Force Shielding Update</A><BR><BR>"
dat += "Status: [(active?"Injecting":"Standby")] <BR>"
dat += "<A href='?src=\ref[src];togglestatus=1'>Toggle Status</A><BR>"
dat += "Instability: [stability]%<BR>"
dat += "Reactor parts: [linked_shielding.len]<BR>"//TODO: perhaps add some sort of stability check
dat += "Cores: [linked_cores.len]<BR><BR>"
dat += "-Current Efficiency: [reported_core_efficiency]<BR>"
dat += "-Average Stability: [stored_core_stability] <A href='?src=\ref[src];refreshstability=1'>(update)</A><BR>"
dat += "Last Produced: [stored_power]<BR>"
dat += "Fuel: "
if(!fueljar)
dat += "<BR>No fuel receptacle detected."
else
dat += "<A href='?src=\ref[src];ejectjar=1'>Eject</A><BR>"
dat += "- [fueljar.fuel]/[fueljar.fuel_max] Units<BR>"
dat += "- Injecting: [fuel_injection] units<BR>"
dat += "- <A href='?src=\ref[src];strengthdown=1'>--</A>|<A href='?src=\ref[src];strengthup=1'>++</A><BR><BR>"
user << browse(dat, "window=AMcontrol;size=420x500")
onclose(user, "AMcontrol")
return
/obj/machinery/power/am_control_unit/Topic(href, href_list)
..()
//Ignore input if we are broken or guy is not touching us, AI can control from a ways away
if(stat & (BROKEN|NOPOWER) || (get_dist(src, usr) > 1 && !istype(usr, /mob/living/silicon/ai)))
usr.unset_machine()
usr << browse(null, "window=AMcontrol")
return
if(href_list["close"])
usr << browse(null, "window=AMcontrol")
usr.unset_machine()
return
if(href_list["togglestatus"])
toggle_power()
if(href_list["refreshicons"])
update_shield_icons = 1
if(href_list["ejectjar"])
if(fueljar)
fueljar.loc = src.loc
fueljar = null
//fueljar.control_unit = null currently it does not care where it is
//update_icon() when we have the icon for it
if(href_list["strengthup"])
fuel_injection++
if(href_list["strengthdown"])
fuel_injection--
if(fuel_injection < 0) fuel_injection = 0
if(href_list["refreshstability"])
check_core_stability()
updateDialog()
return
/obj/machinery/power/am_control_unit
name = "antimatter control unit"
desc = "This device injects antimatter into connected shielding units, the more antimatter injected the more power produced. Wrench the device to set it up."
icon = 'icons/obj/machines/antimatter.dmi'
icon_state = "control"
anchored = TRUE
density = TRUE
use_power = USE_POWER_IDLE
idle_power_usage = 100
active_power_usage = 1000
var/list/obj/machinery/am_shielding/linked_shielding
var/list/obj/machinery/am_shielding/linked_cores
var/obj/item/weapon/am_containment/fueljar
var/update_shield_icons = 0
var/stability = 100
var/exploding = 0
var/active = 0//On or not
var/fuel_injection = 2//How much fuel to inject
var/shield_icon_delay = 0//delays resetting for a short time
var/reported_core_efficiency = 0
var/power_cycle = 0
var/power_cycle_delay = 4//How many ticks till produce_power is called
var/stored_core_stability = 0
var/stored_core_stability_delay = 0
var/stored_power = 0//Power to deploy per tick
/obj/machinery/power/am_control_unit/New()
..()
linked_shielding = list()
linked_cores = list()
/obj/machinery/power/am_control_unit/Destroy()//Perhaps damage and run stability checks rather than just qdel on the others
for(var/obj/machinery/am_shielding/AMS in linked_shielding)
qdel(AMS)
..()
/obj/machinery/power/am_control_unit/process()
if(exploding)
explosion(get_turf(src),8,12,18,12)
if(src) qdel(src)
if(update_shield_icons && !shield_icon_delay)
check_shield_icons()
update_shield_icons = 0
if(stat & (NOPOWER|BROKEN) || !active)//can update the icons even without power
return
if(!fueljar)//No fuel but we are on, shutdown
toggle_power()
//Angry buzz or such here
return
add_avail(stored_power)
power_cycle++
if(power_cycle >= power_cycle_delay)
produce_power()
power_cycle = 0
return
/obj/machinery/power/am_control_unit/proc/produce_power()
playsound(src, 'sound/effects/bang.ogg', 25, 1)
var/core_power = reported_core_efficiency//Effectively how much fuel we can safely deal with
if(core_power <= 0) return 0//Something is wrong
var/core_damage = 0
var/fuel = fueljar.usefuel(fuel_injection)
stored_power = (fuel/core_power)*fuel*200000
//Now check if the cores could deal with it safely, this is done after so you can overload for more power if needed, still a bad idea
if(fuel > (2*core_power))//More fuel has been put in than the current cores can deal with
if(prob(50))core_damage = 1//Small chance of damage
if((fuel-core_power) > 5) core_damage = 5//Now its really starting to overload the cores
if((fuel-core_power) > 10) core_damage = 20//Welp now you did it, they wont stand much of this
if(core_damage == 0) return
for(var/obj/machinery/am_shielding/AMS in linked_cores)
AMS.stability -= core_damage
AMS.check_stability(1)
playsound(src, 'sound/effects/bang.ogg', 50, 1)
return
/obj/machinery/power/am_control_unit/emp_act(severity)
switch(severity)
if(1)
if(active) toggle_power()
stability -= rand(15,30)
if(2)
if(active) toggle_power()
stability -= rand(10,20)
if(3)
if(active) toggle_power()
stability -= rand(8,15)
if(4)
if(active) toggle_power()
stability -= rand(5,10)
..()
return 0
/obj/machinery/power/am_control_unit/ex_act(severity)
switch(severity)
if(1.0)
stability -= 60
if(2.0)
stability -= 40
if(3.0)
stability -= 20
check_stability()
return
/obj/machinery/power/am_control_unit/bullet_act(var/obj/item/projectile/Proj)
if(Proj.check_armour != "bullet")
stability -= Proj.force
return 0
/obj/machinery/power/am_control_unit/power_change()
..()
if(stat & NOPOWER && active)
toggle_power()
return
/obj/machinery/power/am_control_unit/update_icon()
if(active) icon_state = "control_on"
else icon_state = "control"
//No other icons for it atm
/obj/machinery/power/am_control_unit/attackby(obj/item/W, mob/user)
if(!istype(W) || !user) return
if(W.has_tool_quality(TOOL_WRENCH))
if(!anchored)
playsound(src, W.usesound, 75, 1)
user.visible_message("[user.name] secures the [src.name] to the floor.", \
"You secure the anchor bolts to the floor.", \
"You hear a ratchet.")
src.anchored = TRUE
connect_to_network()
else if(!linked_shielding.len > 0)
playsound(src, W.usesound, 75, 1)
user.visible_message("[user.name] unsecures the [src.name].", \
"You remove the anchor bolts.", \
"You hear a ratchet.")
src.anchored = FALSE
disconnect_from_network()
else
to_chat(user, span_red("Once bolted and linked to a shielding unit it the [src.name] is unable to be moved!"))
return
if(istype(W, /obj/item/weapon/am_containment))
if(fueljar)
to_chat(user, span_red("There is already a [fueljar] inside!"))
return
fueljar = W
user.remove_from_mob(W)
W.loc = src
user.update_icons()
user.visible_message("[user.name] loads an [W.name] into the [src.name].", \
"You load an [W.name].", \
"You hear a thunk.")
return
if(W.force >= 20)
stability -= W.force/2
check_stability()
..()
return
/obj/machinery/power/am_control_unit/attack_hand(mob/user as mob)
if(anchored)
interact(user)
return
/obj/machinery/power/am_control_unit/proc/add_shielding(var/obj/machinery/am_shielding/AMS, var/AMS_linking = 0)
if(!istype(AMS)) return 0
if(!anchored) return 0
if(!AMS_linking && !AMS.link_control(src)) return 0
linked_shielding.Add(AMS)
update_shield_icons = 1
return 1
/obj/machinery/power/am_control_unit/proc/remove_shielding(var/obj/machinery/am_shielding/AMS)
if(!istype(AMS)) return 0
linked_shielding.Remove(AMS)
update_shield_icons = 2
if(active) toggle_power()
return 1
/obj/machinery/power/am_control_unit/proc/check_stability()//TODO: make it break when low also might want to add a way to fix it like a part or such that can be replaced
if(stability <= 0)
qdel(src)
return
/obj/machinery/power/am_control_unit/proc/toggle_power()
active = !active
if(active)
update_use_power(USE_POWER_ACTIVE)
visible_message("The [src.name] starts up.")
else
update_use_power(USE_POWER_IDLE)
visible_message("The [src.name] shuts down.")
update_icon()
return
/obj/machinery/power/am_control_unit/proc/check_shield_icons()//Forces icon_update for all shields
if(shield_icon_delay) return
shield_icon_delay = 1
if(update_shield_icons == 2)//2 means to clear everything and rebuild
for(var/obj/machinery/am_shielding/AMS in linked_shielding)
if(AMS.processing) AMS.shutdown_core()
AMS.control_unit = null
spawn(10)
AMS.controllerscan()
linked_shielding = list()
else
for(var/obj/machinery/am_shielding/AMS in linked_shielding)
AMS.update_icon()
spawn(20)
shield_icon_delay = 0
return
/obj/machinery/power/am_control_unit/proc/check_core_stability()
if(stored_core_stability_delay || linked_cores.len <= 0) return
stored_core_stability_delay = 1
stored_core_stability = 0
for(var/obj/machinery/am_shielding/AMS in linked_cores)
stored_core_stability += AMS.stability
stored_core_stability/=linked_cores.len
spawn(40)
stored_core_stability_delay = 0
return
/obj/machinery/power/am_control_unit/interact(mob/user)
if((get_dist(src, user) > 1) || (stat & (BROKEN|NOPOWER)))
if(!istype(user, /mob/living/silicon/ai))
user.unset_machine()
user << browse(null, "window=AMcontrol")
return
user.set_machine(src)
var/dat = ""
dat += "AntiMatter Control Panel<BR>"
dat += "<A href='?src=\ref[src];close=1'>Close</A><BR>"
dat += "<A href='?src=\ref[src];refresh=1'>Refresh</A><BR>"
dat += "<A href='?src=\ref[src];refreshicons=1'>Force Shielding Update</A><BR><BR>"
dat += "Status: [(active?"Injecting":"Standby")] <BR>"
dat += "<A href='?src=\ref[src];togglestatus=1'>Toggle Status</A><BR>"
dat += "Instability: [stability]%<BR>"
dat += "Reactor parts: [linked_shielding.len]<BR>"//TODO: perhaps add some sort of stability check
dat += "Cores: [linked_cores.len]<BR><BR>"
dat += "-Current Efficiency: [reported_core_efficiency]<BR>"
dat += "-Average Stability: [stored_core_stability] <A href='?src=\ref[src];refreshstability=1'>(update)</A><BR>"
dat += "Last Produced: [stored_power]<BR>"
dat += "Fuel: "
if(!fueljar)
dat += "<BR>No fuel receptacle detected."
else
dat += "<A href='?src=\ref[src];ejectjar=1'>Eject</A><BR>"
dat += "- [fueljar.fuel]/[fueljar.fuel_max] Units<BR>"
dat += "- Injecting: [fuel_injection] units<BR>"
dat += "- <A href='?src=\ref[src];strengthdown=1'>--</A>|<A href='?src=\ref[src];strengthup=1'>++</A><BR><BR>"
user << browse(dat, "window=AMcontrol;size=420x500")
onclose(user, "AMcontrol")
return
/obj/machinery/power/am_control_unit/Topic(href, href_list)
..()
//Ignore input if we are broken or guy is not touching us, AI can control from a ways away
if(stat & (BROKEN|NOPOWER) || (get_dist(src, usr) > 1 && !istype(usr, /mob/living/silicon/ai)))
usr.unset_machine()
usr << browse(null, "window=AMcontrol")
return
if(href_list["close"])
usr << browse(null, "window=AMcontrol")
usr.unset_machine()
return
if(href_list["togglestatus"])
toggle_power()
if(href_list["refreshicons"])
update_shield_icons = 1
if(href_list["ejectjar"])
if(fueljar)
fueljar.loc = src.loc
fueljar = null
//fueljar.control_unit = null currently it does not care where it is
//update_icon() when we have the icon for it
if(href_list["strengthup"])
fuel_injection++
if(href_list["strengthdown"])
fuel_injection--
if(fuel_injection < 0) fuel_injection = 0
if(href_list["refreshstability"])
check_core_stability()
updateDialog()
return
+207 -207
View File
@@ -1,207 +1,207 @@
/obj/machinery/power/am_engine
icon = 'icons/am_engine.dmi'
density = TRUE
anchored = TRUE
flags = ON_BORDER
/obj/machinery/power/am_engine/bits
name = "Antimatter Engine"
icon_state = "1"
/obj/machinery/power/am_engine/engine
name = "Antimatter Engine"
icon_state = "am_engine"
var/engine_id = 0
var/H_fuel = 0
var/antiH_fuel = 0
var/operating = 0
var/stopping = 0
var/obj/machinery/power/am_engine/injector/connected = null
/obj/machinery/power/am_engine/injector
name = "Injector"
icon_state = "injector"
var/engine_id = 0
var/injecting = 0
var/fuel = 0
var/obj/machinery/power/am_engine/engine/connected = null
//injector
/obj/machinery/power/am_engine/injector/New()
..()
spawn( 13 )
var/loc = get_step(src, NORTH)
src.connected = locate(/obj/machinery/power/am_engine/engine, get_step(loc, NORTH))
return
return
/obj/machinery/power/am_engine/injector/attackby(obj/item/weapon/fuel/F, mob/user)
if( (stat & BROKEN) || !connected) return
if(istype(F, /obj/item/weapon/fuel/H))
if(injecting)
to_chat(user, "There's already a fuel rod in the injector!")
return
to_chat(user, "You insert the rod into the injector")
injecting = 1
var/fuel = F.fuel
qdel(F)
spawn( 300 )
injecting = 0
new/obj/item/weapon/fuel(src.loc)
connected.H_fuel += fuel
if(istype(F, /obj/item/weapon/fuel/antiH))
if(injecting)
to_chat(user, "There's already a fuel rod in the injector!")
return
to_chat(user, "You insert the rod into the injector")
injecting = 1
var/fuel = F.fuel
qdel(F)
spawn( 300 )
injecting = 0
new /obj/item/weapon/fuel(src.loc)
connected.antiH_fuel += fuel
return
//engine
/obj/machinery/power/am_engine/engine/New()
..()
spawn( 7 )
var/loc = get_step(src, SOUTH)
src.connected = locate(/obj/machinery/power/am_engine/injector, get_step(loc, SOUTH))
return
return
/obj/machinery/power/am_engine/engine/proc/engine_go()
if( (!src.connected) || (stat & BROKEN) )
return
if(!antiH_fuel || !H_fuel)
return
operating = 1
var/energy = 0
if(antiH_fuel == H_fuel)
var/mass = antiH_fuel + H_fuel
energy = convert2energy(mass)
H_fuel = 0
antiH_fuel = 0
else
var/residual_matter = abs(H_fuel - antiH_fuel)
var/mass = antiH_fuel + H_fuel - residual_matter
energy = convert2energy(mass)
if( H_fuel > antiH_fuel )
H_fuel = residual_matter
antiH_fuel = 0
else
H_fuel = 0
antiH_fuel = residual_matter
for(var/mob/M in hearers(src, null))
M.show_message(span_red(text("You hear a loud bang!")))
//Q = k x (delta T)
energy = energy*0.75
operating = 0
//TODO: DEFERRED Heat tile
return
/obj/machinery/power/am_engine/engine/proc/engine_process()
do
if( (!src.connected) || (stat & BROKEN) )
return
if(!antiH_fuel || !H_fuel)
return
if(operating)
return
operating = 1
sleep(50)
var/energy //energy from the reaction
var/H //residual matter if H
var/antiH //residual matter if antiH
var/mass //total mass
if(antiH_fuel == H_fuel) //if they're equal then convert the whole mass to energy
mass = antiH_fuel + H_fuel
energy = convert2energy(mass)
else //else if they're not equal determine which isn't equal
//and set it equal to either H or antiH so we don't lose anything
var/residual_matter = abs(H_fuel - antiH_fuel)
mass = antiH_fuel + H_fuel - residual_matter
energy = convert2energy(mass)
if( H_fuel > antiH_fuel )
H = residual_matter
else
antiH = residual_matter
if(energy > convert2energy(8e-12)) //TOO MUCH ENERGY
for(var/mob/M in hearers(src, null))
M.show_message(span_red(text("You hear a loud whirring!")))
sleep(20)
//Q = k x (delta T)
//Too much energy so machine panics and dissapates half of it as heat
//The rest of the energetic photons then form into H and anti H particles again!
H_fuel -= H
antiH_fuel -= antiH
antiH_fuel = antiH_fuel/2
H_fuel = H_fuel/2
energy = convert2energy(H_fuel + antiH_fuel)
H_fuel += H
antiH_fuel += antiH
if(energy > convert2energy(8e-12)) //FAR TOO MUCH ENERGY STILL
for(var/mob/M in hearers(src, null))
M.show_message(span_red(text("<big>BANG!</big>")))
new /obj/effect/bhole(src.loc)
else //this amount of energy is okay so it does the proper output thing
sleep(60)
//E = Pt
//Lets say its 86% efficient
var/output = 0.86*energy/20
add_avail(output)
//yeah the machine realises that something isn't right and accounts for it if H or antiH
H_fuel -= H
antiH_fuel -= antiH
antiH_fuel = antiH_fuel/4
H_fuel = H_fuel/4
H_fuel += H
antiH_fuel += antiH
operating = 0
sleep(100)
while(!stopping)
stopping = 0
return
/obj/machinery/power/am_engine
icon = 'icons/am_engine.dmi'
density = TRUE
anchored = TRUE
flags = ON_BORDER
/obj/machinery/power/am_engine/bits
name = "Antimatter Engine"
icon_state = "1"
/obj/machinery/power/am_engine/engine
name = "Antimatter Engine"
icon_state = "am_engine"
var/engine_id = 0
var/H_fuel = 0
var/antiH_fuel = 0
var/operating = 0
var/stopping = 0
var/obj/machinery/power/am_engine/injector/connected = null
/obj/machinery/power/am_engine/injector
name = "Injector"
icon_state = "injector"
var/engine_id = 0
var/injecting = 0
var/fuel = 0
var/obj/machinery/power/am_engine/engine/connected = null
//injector
/obj/machinery/power/am_engine/injector/New()
..()
spawn( 13 )
var/loc = get_step(src, NORTH)
src.connected = locate(/obj/machinery/power/am_engine/engine, get_step(loc, NORTH))
return
return
/obj/machinery/power/am_engine/injector/attackby(obj/item/weapon/fuel/F, mob/user)
if( (stat & BROKEN) || !connected) return
if(istype(F, /obj/item/weapon/fuel/H))
if(injecting)
to_chat(user, "There's already a fuel rod in the injector!")
return
to_chat(user, "You insert the rod into the injector")
injecting = 1
var/fuel = F.fuel
qdel(F)
spawn( 300 )
injecting = 0
new/obj/item/weapon/fuel(src.loc)
connected.H_fuel += fuel
if(istype(F, /obj/item/weapon/fuel/antiH))
if(injecting)
to_chat(user, "There's already a fuel rod in the injector!")
return
to_chat(user, "You insert the rod into the injector")
injecting = 1
var/fuel = F.fuel
qdel(F)
spawn( 300 )
injecting = 0
new /obj/item/weapon/fuel(src.loc)
connected.antiH_fuel += fuel
return
//engine
/obj/machinery/power/am_engine/engine/New()
..()
spawn( 7 )
var/loc = get_step(src, SOUTH)
src.connected = locate(/obj/machinery/power/am_engine/injector, get_step(loc, SOUTH))
return
return
/obj/machinery/power/am_engine/engine/proc/engine_go()
if( (!src.connected) || (stat & BROKEN) )
return
if(!antiH_fuel || !H_fuel)
return
operating = 1
var/energy = 0
if(antiH_fuel == H_fuel)
var/mass = antiH_fuel + H_fuel
energy = convert2energy(mass)
H_fuel = 0
antiH_fuel = 0
else
var/residual_matter = abs(H_fuel - antiH_fuel)
var/mass = antiH_fuel + H_fuel - residual_matter
energy = convert2energy(mass)
if( H_fuel > antiH_fuel )
H_fuel = residual_matter
antiH_fuel = 0
else
H_fuel = 0
antiH_fuel = residual_matter
for(var/mob/M in hearers(src, null))
M.show_message(span_red(text("You hear a loud bang!")))
//Q = k x (delta T)
energy = energy*0.75
operating = 0
//TODO: DEFERRED Heat tile
return
/obj/machinery/power/am_engine/engine/proc/engine_process()
do
if( (!src.connected) || (stat & BROKEN) )
return
if(!antiH_fuel || !H_fuel)
return
if(operating)
return
operating = 1
sleep(50)
var/energy //energy from the reaction
var/H //residual matter if H
var/antiH //residual matter if antiH
var/mass //total mass
if(antiH_fuel == H_fuel) //if they're equal then convert the whole mass to energy
mass = antiH_fuel + H_fuel
energy = convert2energy(mass)
else //else if they're not equal determine which isn't equal
//and set it equal to either H or antiH so we don't lose anything
var/residual_matter = abs(H_fuel - antiH_fuel)
mass = antiH_fuel + H_fuel - residual_matter
energy = convert2energy(mass)
if( H_fuel > antiH_fuel )
H = residual_matter
else
antiH = residual_matter
if(energy > convert2energy(8e-12)) //TOO MUCH ENERGY
for(var/mob/M in hearers(src, null))
M.show_message(span_red(text("You hear a loud whirring!")))
sleep(20)
//Q = k x (delta T)
//Too much energy so machine panics and dissapates half of it as heat
//The rest of the energetic photons then form into H and anti H particles again!
H_fuel -= H
antiH_fuel -= antiH
antiH_fuel = antiH_fuel/2
H_fuel = H_fuel/2
energy = convert2energy(H_fuel + antiH_fuel)
H_fuel += H
antiH_fuel += antiH
if(energy > convert2energy(8e-12)) //FAR TOO MUCH ENERGY STILL
for(var/mob/M in hearers(src, null))
M.show_message(span_red(text("<big>BANG!</big>")))
new /obj/effect/bhole(src.loc)
else //this amount of energy is okay so it does the proper output thing
sleep(60)
//E = Pt
//Lets say its 86% efficient
var/output = 0.86*energy/20
add_avail(output)
//yeah the machine realises that something isn't right and accounts for it if H or antiH
H_fuel -= H
antiH_fuel -= antiH
antiH_fuel = antiH_fuel/4
H_fuel = H_fuel/4
H_fuel += H
antiH_fuel += antiH
operating = 0
sleep(100)
while(!stopping)
stopping = 0
return
+100 -100
View File
@@ -1,100 +1,100 @@
/obj/item/weapon/fuel
name = "Magnetic Storage Ring"
desc = "A magnetic storage ring."
icon = 'icons/obj/items.dmi'
icon_state = "rcdammo"
opacity = 0
density = FALSE
anchored = FALSE
var/fuel = 0
var/s_time = 1.0
var/content = null
/obj/item/weapon/fuel/H
name = "Hydrogen storage ring"
content = "Hydrogen"
fuel = 1e-12 //pico-kilogram
/obj/item/weapon/fuel/antiH
name = "Anti-Hydrogen storage ring"
content = "Anti-Hydrogen"
fuel = 1e-12 //pico-kilogram
/obj/item/weapon/fuel/attackby(obj/item/weapon/fuel/F, mob/user)
..()
if(istype(src, /obj/item/weapon/fuel/antiH))
if(istype(F, /obj/item/weapon/fuel/antiH))
src.fuel += F.fuel
F.fuel = 0
to_chat(user, "You have added the anti-Hydrogen to the storage ring, it now contains [src.fuel]kg")
if(istype(F, /obj/item/weapon/fuel/H))
src.fuel += F.fuel
qdel(F)
src:annihilation(src.fuel)
if(istype(src, /obj/item/weapon/fuel/H))
if(istype(F, /obj/item/weapon/fuel/H))
src.fuel += F.fuel
F.fuel = 0
to_chat(user, "You have added the Hydrogen to the storage ring, it now contains [src.fuel]kg")
if(istype(F, /obj/item/weapon/fuel/antiH))
src.fuel += F.fuel
qdel(src)
F:annihilation(F.fuel)
/obj/item/weapon/fuel/antiH/proc/annihilation(var/mass)
var/strength = convert2energy(mass)
if (strength < 773.0)
var/turf/T = get_turf(src)
if (strength > (450+T0C))
explosion(T, 0, 1, 2, 4)
else
if (strength > (300+T0C))
explosion(T, 0, 0, 2, 3)
qdel(src)
return
var/turf/ground_zero = get_turf(loc)
var/ground_zero_range = round(strength / 387)
explosion(ground_zero, ground_zero_range, ground_zero_range*2, ground_zero_range*3, ground_zero_range*4)
//SN src = null
qdel(src)
return
/obj/item/weapon/fuel/examine(mob/user)
. = ..()
if(Adjacent(user))
. += "It contains [fuel]kg of [content ? content : "nothing"]."
/obj/item/weapon/fuel/proc/injest(mob/M as mob)
switch(content)
if("Anti-Hydrogen")
M.gib() //Yikes!
if("Hydrogen")
to_chat(M, span_blue("You feel very light, as if you might just float away..."))
qdel(src)
return
/obj/item/weapon/fuel/attack(mob/M as mob, mob/user as mob)
if (user != M)
var/obj/effect/equip_e/human/O = new /obj/effect/equip_e/human( )
O.source = user
O.target = M
O.item = src
O.s_loc = user.loc
O.t_loc = M.loc
O.place = "fuel"
M.requests += O
spawn( 0 )
O.process()
return
else
for(var/mob/O in viewers(M, null))
O.show_message(span_red(text("[M] ate the [content ? content : "empty canister"]!")), 1)
src.injest(M)
/obj/item/weapon/fuel
name = "Magnetic Storage Ring"
desc = "A magnetic storage ring."
icon = 'icons/obj/items.dmi'
icon_state = "rcdammo"
opacity = 0
density = FALSE
anchored = FALSE
var/fuel = 0
var/s_time = 1.0
var/content = null
/obj/item/weapon/fuel/H
name = "Hydrogen storage ring"
content = "Hydrogen"
fuel = 1e-12 //pico-kilogram
/obj/item/weapon/fuel/antiH
name = "Anti-Hydrogen storage ring"
content = "Anti-Hydrogen"
fuel = 1e-12 //pico-kilogram
/obj/item/weapon/fuel/attackby(obj/item/weapon/fuel/F, mob/user)
..()
if(istype(src, /obj/item/weapon/fuel/antiH))
if(istype(F, /obj/item/weapon/fuel/antiH))
src.fuel += F.fuel
F.fuel = 0
to_chat(user, "You have added the anti-Hydrogen to the storage ring, it now contains [src.fuel]kg")
if(istype(F, /obj/item/weapon/fuel/H))
src.fuel += F.fuel
qdel(F)
src:annihilation(src.fuel)
if(istype(src, /obj/item/weapon/fuel/H))
if(istype(F, /obj/item/weapon/fuel/H))
src.fuel += F.fuel
F.fuel = 0
to_chat(user, "You have added the Hydrogen to the storage ring, it now contains [src.fuel]kg")
if(istype(F, /obj/item/weapon/fuel/antiH))
src.fuel += F.fuel
qdel(src)
F:annihilation(F.fuel)
/obj/item/weapon/fuel/antiH/proc/annihilation(var/mass)
var/strength = convert2energy(mass)
if (strength < 773.0)
var/turf/T = get_turf(src)
if (strength > (450+T0C))
explosion(T, 0, 1, 2, 4)
else
if (strength > (300+T0C))
explosion(T, 0, 0, 2, 3)
qdel(src)
return
var/turf/ground_zero = get_turf(loc)
var/ground_zero_range = round(strength / 387)
explosion(ground_zero, ground_zero_range, ground_zero_range*2, ground_zero_range*3, ground_zero_range*4)
//SN src = null
qdel(src)
return
/obj/item/weapon/fuel/examine(mob/user)
. = ..()
if(Adjacent(user))
. += "It contains [fuel]kg of [content ? content : "nothing"]."
/obj/item/weapon/fuel/proc/injest(mob/M as mob)
switch(content)
if("Anti-Hydrogen")
M.gib() //Yikes!
if("Hydrogen")
to_chat(M, span_blue("You feel very light, as if you might just float away..."))
qdel(src)
return
/obj/item/weapon/fuel/attack(mob/M as mob, mob/user as mob)
if (user != M)
var/obj/effect/equip_e/human/O = new /obj/effect/equip_e/human( )
O.source = user
O.target = M
O.item = src
O.s_loc = user.loc
O.t_loc = M.loc
O.place = "fuel"
M.requests += O
spawn( 0 )
O.process()
return
else
for(var/mob/O in viewers(M, null))
O.show_message(span_red(text("[M] ate the [content ? content : "empty canister"]!")), 1)
src.injest(M)
+205 -205
View File
@@ -1,205 +1,205 @@
//like orange but only checks north/south/east/west for one step
/proc/cardinalrange(var/center)
var/list/things = list()
for(var/direction in cardinal)
var/turf/T = get_step(center, direction)
if(!T) continue
things += T.contents
return things
/obj/machinery/am_shielding
name = "antimatter reactor section"
desc = "This device was built using a phoron life-form that seems to increase phoron's natural ability to react with neutrinos while reducing the combustibility."
icon = 'icons/obj/machines/antimatter.dmi'
icon_state = "shield"
anchored = TRUE
density = TRUE
dir = 1
use_power = USE_POWER_OFF //Living things generally dont use power
idle_power_usage = 0
active_power_usage = 0
var/obj/machinery/power/am_control_unit/control_unit = null
var/processing = 0//To track if we are in the update list or not, we need to be when we are damaged and if we ever
var/stability = 100//If this gets low bad things tend to happen
var/efficiency = 1//How many cores this core counts for when doing power processing, phoron in the air and stability could affect this
/obj/machinery/am_shielding/New(loc)
..(loc)
spawn(10)
controllerscan()
return
/obj/machinery/am_shielding/proc/controllerscan(var/priorscan = 0)
//Make sure we are the only one here
if(!istype(src.loc, /turf))
qdel(src)
return
for(var/obj/machinery/am_shielding/AMS in loc.contents)
if(AMS == src) continue
spawn(0)
qdel(src)
return
//Search for shielding first
for(var/obj/machinery/am_shielding/AMS in cardinalrange(src))
if(AMS && AMS.control_unit && link_control(AMS.control_unit))
break
if(!control_unit)//No other guys nearby look for a control unit
for(var/direction in cardinal)
for(var/obj/machinery/power/am_control_unit/AMC in cardinalrange(src))
if(AMC.add_shielding(src))
break
if(!control_unit)
if(!priorscan)
spawn(20)
controllerscan(1)//Last chance
return
spawn(0)
qdel(src)
return
/obj/machinery/am_shielding/Destroy()
if(control_unit) control_unit.remove_shielding(src)
if(processing) shutdown_core()
visible_message(span_red("The [src.name] melts!"))
//Might want to have it leave a mess on the floor but no sprites for now
..()
return
/obj/machinery/am_shielding/CanPass(atom/movable/mover, turf/target)
return FALSE
/obj/machinery/am_shielding/process()
if(!processing) . = PROCESS_KILL
//TODO: core functions and stability
//TODO: think about checking the airmix for phoron and increasing power output
return
/obj/machinery/am_shielding/emp_act()//Immune due to not really much in the way of electronics.
return 0
/obj/machinery/am_shielding/ex_act(severity)
switch(severity)
if(1.0)
stability -= 80
if(2.0)
stability -= 40
if(3.0)
stability -= 20
check_stability()
return
/obj/machinery/am_shielding/bullet_act(var/obj/item/projectile/Proj)
if(Proj.check_armour != "bullet")
stability -= Proj.force/2
return 0
/obj/machinery/am_shielding/update_icon()
cut_overlays()
for(var/direction in alldirs)
var/machine = locate(/obj/machinery, get_step(loc, direction))
if((istype(machine, /obj/machinery/am_shielding) && machine:control_unit == control_unit)||(istype(machine, /obj/machinery/power/am_control_unit) && machine == control_unit))
add_overlay("shield_[direction]")
if(core_check())
add_overlay("core")
if(!processing) setup_core()
else if(processing) shutdown_core()
/obj/machinery/am_shielding/attackby(obj/item/W, mob/user)
if(!istype(W) || !user) return
if(W.force > 10)
stability -= W.force/2
check_stability()
..()
return
//Call this to link a detected shilding unit to the controller
/obj/machinery/am_shielding/proc/link_control(var/obj/machinery/power/am_control_unit/AMC)
if(!istype(AMC)) return 0
if(control_unit && control_unit != AMC) return 0//Already have one
control_unit = AMC
control_unit.add_shielding(src,1)
return 1
//Scans cards for shields or the control unit and if all there it
/obj/machinery/am_shielding/proc/core_check()
for(var/direction in alldirs)
var/machine = locate(/obj/machinery, get_step(loc, direction))
if(!machine) return 0//Need all for a core
if(!istype(machine, /obj/machinery/am_shielding) && !istype(machine, /obj/machinery/power/am_control_unit)) return 0
return 1
/obj/machinery/am_shielding/proc/setup_core()
processing = 1
START_MACHINE_PROCESSING(src)
if(!control_unit) return
control_unit.linked_cores.Add(src)
control_unit.reported_core_efficiency += efficiency
return
/obj/machinery/am_shielding/proc/shutdown_core()
processing = 0
if(!control_unit) return
control_unit.linked_cores.Remove(src)
control_unit.reported_core_efficiency -= efficiency
return
/obj/machinery/am_shielding/proc/check_stability(var/injecting_fuel = 0)
if(stability > 0) return
if(injecting_fuel && control_unit)
control_unit.exploding = 1
if(src)
qdel(src)
return
/obj/machinery/am_shielding/proc/recalc_efficiency(var/new_efficiency)//tbh still not 100% sure how I want to deal with efficiency so this is likely temp
if(!control_unit || !processing) return
if(stability < 50)
new_efficiency /= 2
control_unit.reported_core_efficiency += (new_efficiency - efficiency)
efficiency = new_efficiency
return
/obj/item/device/am_shielding_container
name = "packaged antimatter reactor section"
desc = "A small storage unit containing an antimatter reactor section. To use place near an antimatter control unit or deployed antimatter reactor section and use a multitool to activate this package."
icon = 'icons/obj/machines/antimatter.dmi'
icon_state = "box"
item_state = "electronic"
w_class = ITEMSIZE_LARGE
throwforce = 5
throw_speed = 1
throw_range = 2
matter = list(MAT_STEEL = 100)
/obj/item/device/am_shielding_container/attackby(var/obj/item/I, var/mob/user)
if(istype(I, /obj/item/device/multitool) && istype(src.loc,/turf))
new/obj/machinery/am_shielding(src.loc)
qdel(src)
return
..()
return
//like orange but only checks north/south/east/west for one step
/proc/cardinalrange(var/center)
var/list/things = list()
for(var/direction in cardinal)
var/turf/T = get_step(center, direction)
if(!T) continue
things += T.contents
return things
/obj/machinery/am_shielding
name = "antimatter reactor section"
desc = "This device was built using a phoron life-form that seems to increase phoron's natural ability to react with neutrinos while reducing the combustibility."
icon = 'icons/obj/machines/antimatter.dmi'
icon_state = "shield"
anchored = TRUE
density = TRUE
dir = 1
use_power = USE_POWER_OFF //Living things generally dont use power
idle_power_usage = 0
active_power_usage = 0
var/obj/machinery/power/am_control_unit/control_unit = null
var/processing = 0//To track if we are in the update list or not, we need to be when we are damaged and if we ever
var/stability = 100//If this gets low bad things tend to happen
var/efficiency = 1//How many cores this core counts for when doing power processing, phoron in the air and stability could affect this
/obj/machinery/am_shielding/New(loc)
..(loc)
spawn(10)
controllerscan()
return
/obj/machinery/am_shielding/proc/controllerscan(var/priorscan = 0)
//Make sure we are the only one here
if(!istype(src.loc, /turf))
qdel(src)
return
for(var/obj/machinery/am_shielding/AMS in loc.contents)
if(AMS == src) continue
spawn(0)
qdel(src)
return
//Search for shielding first
for(var/obj/machinery/am_shielding/AMS in cardinalrange(src))
if(AMS && AMS.control_unit && link_control(AMS.control_unit))
break
if(!control_unit)//No other guys nearby look for a control unit
for(var/direction in cardinal)
for(var/obj/machinery/power/am_control_unit/AMC in cardinalrange(src))
if(AMC.add_shielding(src))
break
if(!control_unit)
if(!priorscan)
spawn(20)
controllerscan(1)//Last chance
return
spawn(0)
qdel(src)
return
/obj/machinery/am_shielding/Destroy()
if(control_unit) control_unit.remove_shielding(src)
if(processing) shutdown_core()
visible_message(span_red("The [src.name] melts!"))
//Might want to have it leave a mess on the floor but no sprites for now
..()
return
/obj/machinery/am_shielding/CanPass(atom/movable/mover, turf/target)
return FALSE
/obj/machinery/am_shielding/process()
if(!processing) . = PROCESS_KILL
//TODO: core functions and stability
//TODO: think about checking the airmix for phoron and increasing power output
return
/obj/machinery/am_shielding/emp_act()//Immune due to not really much in the way of electronics.
return 0
/obj/machinery/am_shielding/ex_act(severity)
switch(severity)
if(1.0)
stability -= 80
if(2.0)
stability -= 40
if(3.0)
stability -= 20
check_stability()
return
/obj/machinery/am_shielding/bullet_act(var/obj/item/projectile/Proj)
if(Proj.check_armour != "bullet")
stability -= Proj.force/2
return 0
/obj/machinery/am_shielding/update_icon()
cut_overlays()
for(var/direction in alldirs)
var/machine = locate(/obj/machinery, get_step(loc, direction))
if((istype(machine, /obj/machinery/am_shielding) && machine:control_unit == control_unit)||(istype(machine, /obj/machinery/power/am_control_unit) && machine == control_unit))
add_overlay("shield_[direction]")
if(core_check())
add_overlay("core")
if(!processing) setup_core()
else if(processing) shutdown_core()
/obj/machinery/am_shielding/attackby(obj/item/W, mob/user)
if(!istype(W) || !user) return
if(W.force > 10)
stability -= W.force/2
check_stability()
..()
return
//Call this to link a detected shilding unit to the controller
/obj/machinery/am_shielding/proc/link_control(var/obj/machinery/power/am_control_unit/AMC)
if(!istype(AMC)) return 0
if(control_unit && control_unit != AMC) return 0//Already have one
control_unit = AMC
control_unit.add_shielding(src,1)
return 1
//Scans cards for shields or the control unit and if all there it
/obj/machinery/am_shielding/proc/core_check()
for(var/direction in alldirs)
var/machine = locate(/obj/machinery, get_step(loc, direction))
if(!machine) return 0//Need all for a core
if(!istype(machine, /obj/machinery/am_shielding) && !istype(machine, /obj/machinery/power/am_control_unit)) return 0
return 1
/obj/machinery/am_shielding/proc/setup_core()
processing = 1
START_MACHINE_PROCESSING(src)
if(!control_unit) return
control_unit.linked_cores.Add(src)
control_unit.reported_core_efficiency += efficiency
return
/obj/machinery/am_shielding/proc/shutdown_core()
processing = 0
if(!control_unit) return
control_unit.linked_cores.Remove(src)
control_unit.reported_core_efficiency -= efficiency
return
/obj/machinery/am_shielding/proc/check_stability(var/injecting_fuel = 0)
if(stability > 0) return
if(injecting_fuel && control_unit)
control_unit.exploding = 1
if(src)
qdel(src)
return
/obj/machinery/am_shielding/proc/recalc_efficiency(var/new_efficiency)//tbh still not 100% sure how I want to deal with efficiency so this is likely temp
if(!control_unit || !processing) return
if(stability < 50)
new_efficiency /= 2
control_unit.reported_core_efficiency += (new_efficiency - efficiency)
efficiency = new_efficiency
return
/obj/item/device/am_shielding_container
name = "packaged antimatter reactor section"
desc = "A small storage unit containing an antimatter reactor section. To use place near an antimatter control unit or deployed antimatter reactor section and use a multitool to activate this package."
icon = 'icons/obj/machines/antimatter.dmi'
icon_state = "box"
item_state = "electronic"
w_class = ITEMSIZE_LARGE
throwforce = 5
throw_speed = 1
throw_range = 2
matter = list(MAT_STEEL = 100)
/obj/item/device/am_shielding_container/attackby(var/obj/item/I, var/mob/user)
if(istype(I, /obj/item/device/multitool) && istype(src.loc,/turf))
new/obj/machinery/am_shielding(src.loc)
qdel(src)
return
..()
return
+1375 -1375
View File
File diff suppressed because it is too large Load Diff
+1000 -1000
View File
File diff suppressed because it is too large Load Diff
+291 -291
View File
@@ -1,292 +1,292 @@
#define LOGIC_HIGH 5
//Indicators only have one input and no outputs
/obj/machinery/logic/indicator
//Input is searched from the 'dir' direction
var/obj/structure/cable/input
/obj/machinery/logic/indicator/process()
if(input)
return 1
if(!input)
var/turf/T = get_step(src, dir)
if(T)
var/inv_dir = turn(dir, 180)
for(var/obj/structure/cable/C in T)
if(C.d1 == inv_dir || C.d2 == inv_dir)
input = C
return 1
return 0 //If it gets to here, it means no suitable wire to link to was found.
/obj/machinery/logic/indicator/bulb
icon = 'icons/obj/lighting.dmi'
icon_state = "bulb0"
/obj/machinery/logic/indicator/bulb/process()
if(!..()) //Parent proc checks if input1 exists.
return
var/datum/powernet/pn_input = input.powernet
if(!pn_input)
return
if(pn_input.avail >= LOGIC_HIGH)
icon_state = "bulb1"
else
icon_state = "bulb0"
//Sensors only have one output and no inputs
/obj/machinery/logic/sensor
//Output is searched from the 'dir' direction
var/obj/structure/cable/output
/obj/machinery/logic/sensor/process()
if(output)
return 1
if(!output)
var/turf/T = get_step(src, dir)
if(T)
var/inv_dir = turn(dir, 180)
for(var/obj/structure/cable/C in T)
if(C.d1 == inv_dir || C.d2 == inv_dir)
output = C
return 1
return 0 //If it gets to here, it means no suitable wire to link to was found.
//Constant high generator. This will continue to send a signal of LOGIC_HIGH as long as it exists.
/obj/machinery/logic/sensor/constant_high
icon = 'icons/obj/atmospherics/outlet_injector.dmi'
icon_state = "off"
/obj/machinery/logic/sensor/constant_high/process()
if(!..()) //Parent proc checks if input1 exists.
return
var/datum/powernet/pn_output = output.powernet
if(!pn_output)
return
pn_output.newavail = max(pn_output.avail, LOGIC_HIGH)
//ONE INPUT logic elements have one input and one output
/obj/machinery/logic/oneinput
var/dir_input = 2
var/dir_output = 1
var/obj/structure/cable/input
var/obj/structure/cable/output
icon = 'icons/atmos/heat.dmi'
icon_state = "intact"
/obj/machinery/logic/oneinput/process()
if(input && output)
return 1
if(!dir_input || !dir_output)
return 0
if(!input)
var/turf/T = get_step(src, dir_input)
if(T)
var/inv_dir = turn(dir_input, 180)
for(var/obj/structure/cable/C in T)
if(C.d1 == inv_dir || C.d2 == inv_dir)
input = C
if(!output)
var/turf/T = get_step(src, dir_output)
if(T)
var/inv_dir = turn(dir_output, 180)
for(var/obj/structure/cable/C in T)
if(C.d1 == inv_dir || C.d2 == inv_dir)
output = C
return 0 //On the process() call, where everything is still being searched for, it returns 0. It will return 1 on the next process() call.
//NOT GATE
/obj/machinery/logic/oneinput/not/process()
if(!..()) //Parent proc checks if input1, input2 and output exist.
return
var/datum/powernet/pn_input = input.powernet
if(!pn_input)
return
var/datum/powernet/pn_output = output.powernet
if(!pn_output)
return
if( !(pn_input.avail >= LOGIC_HIGH))
pn_output.newavail = max(pn_output.avail, LOGIC_HIGH) //Set the output avilable power to 5 or whatever it was before.
else
pn_output.draw_power(LOGIC_HIGH) //Otherwise increase the load to 5
//TWO INPUT logic elements have two inputs and one output
/obj/machinery/logic/twoinput
var/dir_input1 = 2
var/dir_input2 = 8
var/dir_output = 1
var/obj/structure/cable/input1
var/obj/structure/cable/input2
var/obj/structure/cable/output
icon = 'icons/obj/atmospherics/mixer.dmi'
icon_state = "intact_off"
/obj/machinery/logic/twoinput/process()
if(input1 && input2 && output)
return 1
if(!dir_input1 || !dir_input2 || !dir_output)
return 0
if(!input1)
var/turf/T = get_step(src, dir_input1)
if(T)
var/inv_dir = turn(dir_input1, 180)
for(var/obj/structure/cable/C in T)
if(C.d1 == inv_dir || C.d2 == inv_dir)
input1 = C
if(!input2)
var/turf/T = get_step(src, dir_input2)
if(T)
var/inv_dir = turn(dir_input2, 180)
for(var/obj/structure/cable/C in T)
if(C.d1 == inv_dir || C.d2 == inv_dir)
input2 = C
if(!output)
var/turf/T = get_step(src, dir_output)
if(T)
var/inv_dir = turn(dir_output, 180)
for(var/obj/structure/cable/C in T)
if(C.d1 == inv_dir || C.d2 == inv_dir)
output = C
return 0 //On the process() call, where everything is still being searched for, it returns 0. It will return 1 on the next process() call.
//AND GATE
/obj/machinery/logic/twoinput/and/process()
if(!..()) //Parent proc checks if input1, input2 and output exist.
return
var/datum/powernet/pn_input1 = input1.powernet
var/datum/powernet/pn_input2 = input2.powernet
if(!pn_input1 || !pn_input2)
return
var/datum/powernet/pn_output = output.powernet
if(!pn_output)
return
if( (pn_input1.avail >= LOGIC_HIGH) && (pn_input2.avail >= LOGIC_HIGH) )
pn_output.newavail = max(pn_output.avail, LOGIC_HIGH) //Set the output avilable power to 5 or whatever it was before.
else
pn_output.draw_power(LOGIC_HIGH) //Otherwise increase the load to 5
//OR GATE
/obj/machinery/logic/twoinput/or/process()
if(!..()) //Parent proc checks if input1, input2 and output exist.
return
var/datum/powernet/pn_input1 = input1.powernet
var/datum/powernet/pn_input2 = input2.powernet
if(!pn_input1 || !pn_input2)
return
var/datum/powernet/pn_output = output.powernet
if(!pn_output)
return
if( (pn_input1.avail >= LOGIC_HIGH) || (pn_input2.avail >= LOGIC_HIGH) )
pn_output.newavail = max(pn_output.avail, LOGIC_HIGH) //Set the output avilable power to 5 or whatever it was before.
else
pn_output.draw_power(LOGIC_HIGH) //Otherwise increase the load to 5
//XOR GATE
/obj/machinery/logic/twoinput/xor/process()
if(!..()) //Parent proc checks if input1, input2 and output exist.
return
var/datum/powernet/pn_input1 = input1.powernet
var/datum/powernet/pn_input2 = input2.powernet
if(!pn_input1 || !pn_input2)
return
var/datum/powernet/pn_output = output.powernet
if(!pn_output)
return
if( (pn_input1.avail >= LOGIC_HIGH) != (pn_input2.avail >= LOGIC_HIGH) )
pn_output.newavail = max(pn_output.avail, LOGIC_HIGH) //Set the output avilable power to 5 or whatever it was before.
else
pn_output.draw_power(LOGIC_HIGH) //Otherwise increase the load to 5
//XNOR GATE (EQUIVALENCE)
/obj/machinery/logic/twoinput/xnor/process()
if(!..()) //Parent proc checks if input1, input2 and output exist.
return
var/datum/powernet/pn_input1 = input1.powernet
var/datum/powernet/pn_input2 = input2.powernet
if(!pn_input1 || !pn_input2)
return
var/datum/powernet/pn_output = output.powernet
if(!pn_output)
return
if( (pn_input1.avail >= LOGIC_HIGH) == (pn_input2.avail >= LOGIC_HIGH) )
pn_output.newavail = max(pn_output.avail, LOGIC_HIGH) //Set the output avilable power to 5 or whatever it was before.
else
pn_output.draw_power(LOGIC_HIGH) //Otherwise increase the load to 5
#define RELAY_POWER_TRANSFER 2000 //How much power a relay transfers through.
//RELAY - input1 governs the flow from input2 to output
/obj/machinery/logic/twoinput/relay/process()
if(!..()) //Parent proc checks if input1, input2 and output exist.
return
var/datum/powernet/pn_input1 = input1.powernet
if(!pn_input1)
return
if( pn_input1.avail >= LOGIC_HIGH )
var/datum/powernet/pn_input2 = input2.powernet
var/datum/powernet/pn_output = output.powernet
if(!pn_output)
return
if(pn_input2.avail >= RELAY_POWER_TRANSFER)
pn_input2.draw_power(RELAY_POWER_TRANSFER)
pn_output.newavail += RELAY_POWER_TRANSFER
#undef RELAY_POWER_TRANSFER
#define LOGIC_HIGH 5
//Indicators only have one input and no outputs
/obj/machinery/logic/indicator
//Input is searched from the 'dir' direction
var/obj/structure/cable/input
/obj/machinery/logic/indicator/process()
if(input)
return 1
if(!input)
var/turf/T = get_step(src, dir)
if(T)
var/inv_dir = turn(dir, 180)
for(var/obj/structure/cable/C in T)
if(C.d1 == inv_dir || C.d2 == inv_dir)
input = C
return 1
return 0 //If it gets to here, it means no suitable wire to link to was found.
/obj/machinery/logic/indicator/bulb
icon = 'icons/obj/lighting.dmi'
icon_state = "bulb0"
/obj/machinery/logic/indicator/bulb/process()
if(!..()) //Parent proc checks if input1 exists.
return
var/datum/powernet/pn_input = input.powernet
if(!pn_input)
return
if(pn_input.avail >= LOGIC_HIGH)
icon_state = "bulb1"
else
icon_state = "bulb0"
//Sensors only have one output and no inputs
/obj/machinery/logic/sensor
//Output is searched from the 'dir' direction
var/obj/structure/cable/output
/obj/machinery/logic/sensor/process()
if(output)
return 1
if(!output)
var/turf/T = get_step(src, dir)
if(T)
var/inv_dir = turn(dir, 180)
for(var/obj/structure/cable/C in T)
if(C.d1 == inv_dir || C.d2 == inv_dir)
output = C
return 1
return 0 //If it gets to here, it means no suitable wire to link to was found.
//Constant high generator. This will continue to send a signal of LOGIC_HIGH as long as it exists.
/obj/machinery/logic/sensor/constant_high
icon = 'icons/obj/atmospherics/outlet_injector.dmi'
icon_state = "off"
/obj/machinery/logic/sensor/constant_high/process()
if(!..()) //Parent proc checks if input1 exists.
return
var/datum/powernet/pn_output = output.powernet
if(!pn_output)
return
pn_output.newavail = max(pn_output.avail, LOGIC_HIGH)
//ONE INPUT logic elements have one input and one output
/obj/machinery/logic/oneinput
var/dir_input = 2
var/dir_output = 1
var/obj/structure/cable/input
var/obj/structure/cable/output
icon = 'icons/atmos/heat.dmi'
icon_state = "intact"
/obj/machinery/logic/oneinput/process()
if(input && output)
return 1
if(!dir_input || !dir_output)
return 0
if(!input)
var/turf/T = get_step(src, dir_input)
if(T)
var/inv_dir = turn(dir_input, 180)
for(var/obj/structure/cable/C in T)
if(C.d1 == inv_dir || C.d2 == inv_dir)
input = C
if(!output)
var/turf/T = get_step(src, dir_output)
if(T)
var/inv_dir = turn(dir_output, 180)
for(var/obj/structure/cable/C in T)
if(C.d1 == inv_dir || C.d2 == inv_dir)
output = C
return 0 //On the process() call, where everything is still being searched for, it returns 0. It will return 1 on the next process() call.
//NOT GATE
/obj/machinery/logic/oneinput/not/process()
if(!..()) //Parent proc checks if input1, input2 and output exist.
return
var/datum/powernet/pn_input = input.powernet
if(!pn_input)
return
var/datum/powernet/pn_output = output.powernet
if(!pn_output)
return
if( !(pn_input.avail >= LOGIC_HIGH))
pn_output.newavail = max(pn_output.avail, LOGIC_HIGH) //Set the output avilable power to 5 or whatever it was before.
else
pn_output.draw_power(LOGIC_HIGH) //Otherwise increase the load to 5
//TWO INPUT logic elements have two inputs and one output
/obj/machinery/logic/twoinput
var/dir_input1 = 2
var/dir_input2 = 8
var/dir_output = 1
var/obj/structure/cable/input1
var/obj/structure/cable/input2
var/obj/structure/cable/output
icon = 'icons/obj/atmospherics/mixer.dmi'
icon_state = "intact_off"
/obj/machinery/logic/twoinput/process()
if(input1 && input2 && output)
return 1
if(!dir_input1 || !dir_input2 || !dir_output)
return 0
if(!input1)
var/turf/T = get_step(src, dir_input1)
if(T)
var/inv_dir = turn(dir_input1, 180)
for(var/obj/structure/cable/C in T)
if(C.d1 == inv_dir || C.d2 == inv_dir)
input1 = C
if(!input2)
var/turf/T = get_step(src, dir_input2)
if(T)
var/inv_dir = turn(dir_input2, 180)
for(var/obj/structure/cable/C in T)
if(C.d1 == inv_dir || C.d2 == inv_dir)
input2 = C
if(!output)
var/turf/T = get_step(src, dir_output)
if(T)
var/inv_dir = turn(dir_output, 180)
for(var/obj/structure/cable/C in T)
if(C.d1 == inv_dir || C.d2 == inv_dir)
output = C
return 0 //On the process() call, where everything is still being searched for, it returns 0. It will return 1 on the next process() call.
//AND GATE
/obj/machinery/logic/twoinput/and/process()
if(!..()) //Parent proc checks if input1, input2 and output exist.
return
var/datum/powernet/pn_input1 = input1.powernet
var/datum/powernet/pn_input2 = input2.powernet
if(!pn_input1 || !pn_input2)
return
var/datum/powernet/pn_output = output.powernet
if(!pn_output)
return
if( (pn_input1.avail >= LOGIC_HIGH) && (pn_input2.avail >= LOGIC_HIGH) )
pn_output.newavail = max(pn_output.avail, LOGIC_HIGH) //Set the output avilable power to 5 or whatever it was before.
else
pn_output.draw_power(LOGIC_HIGH) //Otherwise increase the load to 5
//OR GATE
/obj/machinery/logic/twoinput/or/process()
if(!..()) //Parent proc checks if input1, input2 and output exist.
return
var/datum/powernet/pn_input1 = input1.powernet
var/datum/powernet/pn_input2 = input2.powernet
if(!pn_input1 || !pn_input2)
return
var/datum/powernet/pn_output = output.powernet
if(!pn_output)
return
if( (pn_input1.avail >= LOGIC_HIGH) || (pn_input2.avail >= LOGIC_HIGH) )
pn_output.newavail = max(pn_output.avail, LOGIC_HIGH) //Set the output avilable power to 5 or whatever it was before.
else
pn_output.draw_power(LOGIC_HIGH) //Otherwise increase the load to 5
//XOR GATE
/obj/machinery/logic/twoinput/xor/process()
if(!..()) //Parent proc checks if input1, input2 and output exist.
return
var/datum/powernet/pn_input1 = input1.powernet
var/datum/powernet/pn_input2 = input2.powernet
if(!pn_input1 || !pn_input2)
return
var/datum/powernet/pn_output = output.powernet
if(!pn_output)
return
if( (pn_input1.avail >= LOGIC_HIGH) != (pn_input2.avail >= LOGIC_HIGH) )
pn_output.newavail = max(pn_output.avail, LOGIC_HIGH) //Set the output avilable power to 5 or whatever it was before.
else
pn_output.draw_power(LOGIC_HIGH) //Otherwise increase the load to 5
//XNOR GATE (EQUIVALENCE)
/obj/machinery/logic/twoinput/xnor/process()
if(!..()) //Parent proc checks if input1, input2 and output exist.
return
var/datum/powernet/pn_input1 = input1.powernet
var/datum/powernet/pn_input2 = input2.powernet
if(!pn_input1 || !pn_input2)
return
var/datum/powernet/pn_output = output.powernet
if(!pn_output)
return
if( (pn_input1.avail >= LOGIC_HIGH) == (pn_input2.avail >= LOGIC_HIGH) )
pn_output.newavail = max(pn_output.avail, LOGIC_HIGH) //Set the output avilable power to 5 or whatever it was before.
else
pn_output.draw_power(LOGIC_HIGH) //Otherwise increase the load to 5
#define RELAY_POWER_TRANSFER 2000 //How much power a relay transfers through.
//RELAY - input1 governs the flow from input2 to output
/obj/machinery/logic/twoinput/relay/process()
if(!..()) //Parent proc checks if input1, input2 and output exist.
return
var/datum/powernet/pn_input1 = input1.powernet
if(!pn_input1)
return
if( pn_input1.avail >= LOGIC_HIGH )
var/datum/powernet/pn_input2 = input2.powernet
var/datum/powernet/pn_output = output.powernet
if(!pn_output)
return
if(pn_input2.avail >= RELAY_POWER_TRANSFER)
pn_input2.draw_power(RELAY_POWER_TRANSFER)
pn_output.newavail += RELAY_POWER_TRANSFER
#undef RELAY_POWER_TRANSFER
#undef LOGIC_HIGH
+249 -249
View File
@@ -1,249 +1,249 @@
// the power cell
// charge from 0 to 100%
// fits in APC to provide backup power
/obj/item/weapon/cell
name = "power cell"
desc = "A rechargable electrochemical power cell."
icon = 'icons/obj/power_cells.dmi'
icon_state = "standard"
item_state = "cell"
origin_tech = list(TECH_POWER = 1)
force = 5.0
throwforce = 5.0
throw_speed = 3
throw_range = 5
w_class = ITEMSIZE_NORMAL
/// Are we EMP immune?
var/emp_proof = FALSE
var/static/cell_uid = 1 // Unique ID of this power cell. Used to reduce bunch of uglier code in nanoUI.
var/c_uid
var/charge = 0 // note %age conveted to actual charge in New
var/maxcharge = 1000
var/rigged = 0 // true if rigged to explode
var/minor_fault = 0 //If not 100% reliable, it will build up faults.
var/self_recharge = FALSE // If true, the cell will recharge itself.
var/charge_amount = 25 // How much power to give, if self_recharge is true. The number is in absolute cell charge, as it gets divided by CELLRATE later.
var/last_use = 0 // A tracker for use in self-charging
var/connector_type = "standard" //What connector sprite to use when in a cell charger, null if no connectors
var/charge_delay = 0 // How long it takes for the cell to start recharging after last use
matter = list(MAT_STEEL = 700, MAT_GLASS = 50)
drop_sound = 'sound/items/drop/component.ogg'
pickup_sound = 'sound/items/pickup/component.ogg'
// Overlay stuff.
var/standard_overlays = TRUE
var/last_overlay_state = null // Used to optimize update_icon() calls.
/obj/item/weapon/cell/New()
..()
c_uid = cell_uid++
charge = maxcharge
update_icon()
if(self_recharge)
START_PROCESSING(SSobj, src)
/obj/item/weapon/cell/Destroy()
if(self_recharge)
STOP_PROCESSING(SSobj, src)
return ..()
/obj/item/weapon/cell/get_cell()
return src
/obj/item/weapon/cell/process()
if(self_recharge)
if(world.time >= last_use + charge_delay)
give(charge_amount)
// TGMC Ammo HUD - Update the HUD every time we're called to recharge.
if(istype(loc, /obj/item/weapon/gun/energy)) // Are we in a gun currently?
var/obj/item/weapon/gun/energy/gun = loc
var/mob/living/user = gun.loc
if(istype(user))
user?.hud_used.update_ammo_hud(user, gun) // Update the HUD
else
return PROCESS_KILL
/obj/item/weapon/cell/drain_power(var/drain_check, var/surge, var/power = 0)
if(drain_check)
return 1
if(charge <= 0)
return 0
var/cell_amt = power * CELLRATE
return use(cell_amt) / CELLRATE
#define OVERLAY_FULL 2
#define OVERLAY_PARTIAL 1
#define OVERLAY_EMPTY 0
/obj/item/weapon/cell/update_icon()
if(!standard_overlays)
return
var/ratio = clamp(round(charge / maxcharge, 0.25) * 100, 0, 100)
var/new_state = "[icon_state]_[ratio]"
if(new_state != last_overlay_state)
cut_overlay(last_overlay_state)
add_overlay(new_state)
last_overlay_state = new_state
#undef OVERLAY_FULL
#undef OVERLAY_PARTIAL
#undef OVERLAY_EMPTY
/obj/item/weapon/cell/proc/percent() // return % charge of cell
return 100.0*charge/maxcharge
/obj/item/weapon/cell/proc/fully_charged()
return (charge == maxcharge)
// checks if the power cell is able to provide the specified amount of charge
/obj/item/weapon/cell/proc/check_charge(var/amount)
return (charge >= amount)
// Returns how much charge is missing from the cell, useful to make sure not overdraw from the grid when recharging.
/obj/item/weapon/cell/proc/amount_missing()
return max(maxcharge - charge, 0)
// use power from a cell, returns the amount actually used
/obj/item/weapon/cell/proc/use(var/amount)
if(rigged && amount > 0)
explode()
return 0
var/used = min(charge, amount)
charge -= used
last_use = world.time
update_icon()
return used
// Checks if the specified amount can be provided. If it can, it removes the amount
// from the cell and returns 1. Otherwise does nothing and returns 0.
/obj/item/weapon/cell/proc/checked_use(var/amount)
if(!check_charge(amount))
return 0
use(amount)
return 1
// recharge the cell
/obj/item/weapon/cell/proc/give(var/amount)
if(rigged && amount > 0)
explode()
return 0
if(maxcharge < amount) return 0
var/amount_used = min(maxcharge-charge,amount)
charge += amount_used
update_icon()
if(loc)
loc.update_icon()
return amount_used
/obj/item/weapon/cell/examine(mob/user)
. = ..()
if(Adjacent(user))
. += "It has a power rating of [maxcharge]."
. += "The charge meter reads [round(src.percent() )]%."
/obj/item/weapon/cell/attackby(obj/item/W, mob/user)
..()
if(istype(W, /obj/item/weapon/reagent_containers/syringe))
var/obj/item/weapon/reagent_containers/syringe/S = W
to_chat(user, "You inject the solution into the power cell.")
if(S.reagents.has_reagent("phoron", 5))
rigged = 1
log_admin("LOG: [user.name] ([user.ckey]) injected a power cell with phoron, rigging it to explode.")
message_admins("LOG: [user.name] ([user.ckey]) injected a power cell with phoron, rigging it to explode.")
S.reagents.clear_reagents()
/obj/item/weapon/cell/proc/explode()
var/turf/T = get_turf(src.loc)
/*
* 1000-cell explosion(T, -1, 0, 1, 1)
* 2500-cell explosion(T, -1, 0, 1, 1)
* 10000-cell explosion(T, -1, 1, 3, 3)
* 15000-cell explosion(T, -1, 2, 4, 4)
* */
if (charge==0)
return
var/devastation_range = -1 //round(charge/11000)
var/heavy_impact_range = round(sqrt(charge)/60)
var/light_impact_range = round(sqrt(charge)/30)
var/flash_range = light_impact_range
if (light_impact_range==0)
rigged = 0
corrupt()
return
//explosion(T, 0, 1, 2, 2)
log_admin("LOG: Rigged power cell explosion, last touched by [fingerprintslast]")
message_admins("LOG: Rigged power cell explosion, last touched by [fingerprintslast]")
explosion(T, devastation_range, heavy_impact_range, light_impact_range, flash_range)
qdel(src)
/obj/item/weapon/cell/proc/corrupt()
charge /= 2
maxcharge /= 2
if (prob(10))
rigged = 1 //broken batterys are dangerous
/obj/item/weapon/cell/emp_act(severity)
if(emp_proof)
return
//remove this once emp changes on dev are merged in
if(isrobot(loc))
var/mob/living/silicon/robot/R = loc
severity *= R.cell_emp_mult
charge -= charge / severity
if (charge < 0)
charge = 0
update_icon()
..()
/obj/item/weapon/cell/ex_act(severity)
switch(severity)
if(1.0)
qdel(src)
return
if(2.0)
if (prob(50))
qdel(src)
return
if (prob(50))
corrupt()
if(3.0)
if (prob(25))
qdel(src)
return
if (prob(25))
corrupt()
return
/obj/item/weapon/cell/proc/get_electrocute_damage()
//1kW = 5
//10kW = 24
//100kW = 45
//250kW = 53
//1MW = 66
//10MW = 88
//100MW = 110
//1GW = 132
if(charge >= 1000)
var/damage = log(1.1,charge)
damage = damage - (log(1.1,damage)*1.5)
return round(damage)
else
return 0
// the power cell
// charge from 0 to 100%
// fits in APC to provide backup power
/obj/item/weapon/cell
name = "power cell"
desc = "A rechargable electrochemical power cell."
icon = 'icons/obj/power_cells.dmi'
icon_state = "standard"
item_state = "cell"
origin_tech = list(TECH_POWER = 1)
force = 5.0
throwforce = 5.0
throw_speed = 3
throw_range = 5
w_class = ITEMSIZE_NORMAL
/// Are we EMP immune?
var/emp_proof = FALSE
var/static/cell_uid = 1 // Unique ID of this power cell. Used to reduce bunch of uglier code in nanoUI.
var/c_uid
var/charge = 0 // note %age conveted to actual charge in New
var/maxcharge = 1000
var/rigged = 0 // true if rigged to explode
var/minor_fault = 0 //If not 100% reliable, it will build up faults.
var/self_recharge = FALSE // If true, the cell will recharge itself.
var/charge_amount = 25 // How much power to give, if self_recharge is true. The number is in absolute cell charge, as it gets divided by CELLRATE later.
var/last_use = 0 // A tracker for use in self-charging
var/connector_type = "standard" //What connector sprite to use when in a cell charger, null if no connectors
var/charge_delay = 0 // How long it takes for the cell to start recharging after last use
matter = list(MAT_STEEL = 700, MAT_GLASS = 50)
drop_sound = 'sound/items/drop/component.ogg'
pickup_sound = 'sound/items/pickup/component.ogg'
// Overlay stuff.
var/standard_overlays = TRUE
var/last_overlay_state = null // Used to optimize update_icon() calls.
/obj/item/weapon/cell/New()
..()
c_uid = cell_uid++
charge = maxcharge
update_icon()
if(self_recharge)
START_PROCESSING(SSobj, src)
/obj/item/weapon/cell/Destroy()
if(self_recharge)
STOP_PROCESSING(SSobj, src)
return ..()
/obj/item/weapon/cell/get_cell()
return src
/obj/item/weapon/cell/process()
if(self_recharge)
if(world.time >= last_use + charge_delay)
give(charge_amount)
// TGMC Ammo HUD - Update the HUD every time we're called to recharge.
if(istype(loc, /obj/item/weapon/gun/energy)) // Are we in a gun currently?
var/obj/item/weapon/gun/energy/gun = loc
var/mob/living/user = gun.loc
if(istype(user))
user?.hud_used.update_ammo_hud(user, gun) // Update the HUD
else
return PROCESS_KILL
/obj/item/weapon/cell/drain_power(var/drain_check, var/surge, var/power = 0)
if(drain_check)
return 1
if(charge <= 0)
return 0
var/cell_amt = power * CELLRATE
return use(cell_amt) / CELLRATE
#define OVERLAY_FULL 2
#define OVERLAY_PARTIAL 1
#define OVERLAY_EMPTY 0
/obj/item/weapon/cell/update_icon()
if(!standard_overlays)
return
var/ratio = clamp(round(charge / maxcharge, 0.25) * 100, 0, 100)
var/new_state = "[icon_state]_[ratio]"
if(new_state != last_overlay_state)
cut_overlay(last_overlay_state)
add_overlay(new_state)
last_overlay_state = new_state
#undef OVERLAY_FULL
#undef OVERLAY_PARTIAL
#undef OVERLAY_EMPTY
/obj/item/weapon/cell/proc/percent() // return % charge of cell
return 100.0*charge/maxcharge
/obj/item/weapon/cell/proc/fully_charged()
return (charge == maxcharge)
// checks if the power cell is able to provide the specified amount of charge
/obj/item/weapon/cell/proc/check_charge(var/amount)
return (charge >= amount)
// Returns how much charge is missing from the cell, useful to make sure not overdraw from the grid when recharging.
/obj/item/weapon/cell/proc/amount_missing()
return max(maxcharge - charge, 0)
// use power from a cell, returns the amount actually used
/obj/item/weapon/cell/proc/use(var/amount)
if(rigged && amount > 0)
explode()
return 0
var/used = min(charge, amount)
charge -= used
last_use = world.time
update_icon()
return used
// Checks if the specified amount can be provided. If it can, it removes the amount
// from the cell and returns 1. Otherwise does nothing and returns 0.
/obj/item/weapon/cell/proc/checked_use(var/amount)
if(!check_charge(amount))
return 0
use(amount)
return 1
// recharge the cell
/obj/item/weapon/cell/proc/give(var/amount)
if(rigged && amount > 0)
explode()
return 0
if(maxcharge < amount) return 0
var/amount_used = min(maxcharge-charge,amount)
charge += amount_used
update_icon()
if(loc)
loc.update_icon()
return amount_used
/obj/item/weapon/cell/examine(mob/user)
. = ..()
if(Adjacent(user))
. += "It has a power rating of [maxcharge]."
. += "The charge meter reads [round(src.percent() )]%."
/obj/item/weapon/cell/attackby(obj/item/W, mob/user)
..()
if(istype(W, /obj/item/weapon/reagent_containers/syringe))
var/obj/item/weapon/reagent_containers/syringe/S = W
to_chat(user, "You inject the solution into the power cell.")
if(S.reagents.has_reagent("phoron", 5))
rigged = 1
log_admin("LOG: [user.name] ([user.ckey]) injected a power cell with phoron, rigging it to explode.")
message_admins("LOG: [user.name] ([user.ckey]) injected a power cell with phoron, rigging it to explode.")
S.reagents.clear_reagents()
/obj/item/weapon/cell/proc/explode()
var/turf/T = get_turf(src.loc)
/*
* 1000-cell explosion(T, -1, 0, 1, 1)
* 2500-cell explosion(T, -1, 0, 1, 1)
* 10000-cell explosion(T, -1, 1, 3, 3)
* 15000-cell explosion(T, -1, 2, 4, 4)
* */
if (charge==0)
return
var/devastation_range = -1 //round(charge/11000)
var/heavy_impact_range = round(sqrt(charge)/60)
var/light_impact_range = round(sqrt(charge)/30)
var/flash_range = light_impact_range
if (light_impact_range==0)
rigged = 0
corrupt()
return
//explosion(T, 0, 1, 2, 2)
log_admin("LOG: Rigged power cell explosion, last touched by [fingerprintslast]")
message_admins("LOG: Rigged power cell explosion, last touched by [fingerprintslast]")
explosion(T, devastation_range, heavy_impact_range, light_impact_range, flash_range)
qdel(src)
/obj/item/weapon/cell/proc/corrupt()
charge /= 2
maxcharge /= 2
if (prob(10))
rigged = 1 //broken batterys are dangerous
/obj/item/weapon/cell/emp_act(severity)
if(emp_proof)
return
//remove this once emp changes on dev are merged in
if(isrobot(loc))
var/mob/living/silicon/robot/R = loc
severity *= R.cell_emp_mult
charge -= charge / severity
if (charge < 0)
charge = 0
update_icon()
..()
/obj/item/weapon/cell/ex_act(severity)
switch(severity)
if(1.0)
qdel(src)
return
if(2.0)
if (prob(50))
qdel(src)
return
if (prob(50))
corrupt()
if(3.0)
if (prob(25))
qdel(src)
return
if (prob(25))
corrupt()
return
/obj/item/weapon/cell/proc/get_electrocute_damage()
//1kW = 5
//10kW = 24
//100kW = 45
//250kW = 53
//1MW = 66
//10MW = 88
//100MW = 110
//1GW = 132
if(charge >= 1000)
var/damage = log(1.1,charge)
damage = damage - (log(1.1,damage)*1.5)
return round(damage)
else
return 0
+292 -292
View File
@@ -1,292 +1,292 @@
GLOBAL_LIST_EMPTY(all_turbines)
/obj/machinery/power/generator
name = "thermoelectric generator"
desc = "It's a high efficiency thermoelectric generator."
icon_state = "teg-unassembled"
density = TRUE
anchored = FALSE
unacidable = TRUE
use_power = USE_POWER_IDLE
idle_power_usage = 100 //Watts, I hope. Just enough to do the computer and display things.
var/max_power = 500000
var/thermal_efficiency = 0.65
var/obj/machinery/atmospherics/binary/circulator/circ1
var/obj/machinery/atmospherics/binary/circulator/circ2
var/last_circ1_gen = 0
var/last_circ2_gen = 0
var/last_thermal_gen = 0
var/stored_energy = 0
var/lastgen1 = 0
var/lastgen2 = 0
var/effective_gen = 0
var/lastgenlev = 0
var/datum/looping_sound/generator/soundloop
/obj/machinery/power/generator/Initialize()
soundloop = new(list(src), FALSE)
desc = initial(desc) + " Rated for [round(max_power/1000)] kW."
GLOB.all_turbines += src
..() //Not returned, because...
return INITIALIZE_HINT_LATELOAD
/obj/machinery/power/generator/LateInitialize()
reconnect()
/obj/machinery/power/generator/Destroy()
QDEL_NULL(soundloop)
GLOB.all_turbines -= src
return ..()
//generators connect in dir and reverse_dir(dir) directions
//mnemonic to determine circulator/generator directions: the cirulators orbit clockwise around the generator
//so a circulator to the NORTH of the generator connects first to the EAST, then to the WEST
//and a circulator to the WEST of the generator connects first to the NORTH, then to the SOUTH
//note that the circulator's outlet dir is it's always facing dir, and it's inlet is always the reverse
/obj/machinery/power/generator/proc/reconnect()
circ1 = null
circ2 = null
if(src.loc && anchored)
if(src.dir & (EAST|WEST))
circ1 = locate(/obj/machinery/atmospherics/binary/circulator) in get_step(src,WEST)
circ2 = locate(/obj/machinery/atmospherics/binary/circulator) in get_step(src,EAST)
if(circ1 && circ2)
if(circ1.dir != NORTH || circ2.dir != SOUTH)
circ1 = null
circ2 = null
else if(src.dir & (NORTH|SOUTH))
circ1 = locate(/obj/machinery/atmospherics/binary/circulator) in get_step(src,NORTH)
circ2 = locate(/obj/machinery/atmospherics/binary/circulator) in get_step(src,SOUTH)
if(circ1 && circ2 && (circ1.dir != EAST || circ2.dir != WEST))
circ1 = null
circ2 = null
/obj/machinery/power/generator/update_icon()
icon_state = anchored ? "teg-assembled" : "teg-unassembled"
cut_overlays()
if (circ1)
circ1.temperature_overlay = null
if (circ2)
circ2.temperature_overlay = null
if (stat & (NOPOWER|BROKEN))
return 1
else
if (lastgenlev != 0)
add_overlay("teg-op[lastgenlev]")
if (circ1 && circ2)
var/extreme = (lastgenlev > 9) ? "ex" : ""
if (circ1.last_temperature < circ2.last_temperature)
circ1.temperature_overlay = "circ-[extreme]cold"
circ2.temperature_overlay = "circ-[extreme]hot"
else
circ1.temperature_overlay = "circ-[extreme]hot"
circ2.temperature_overlay = "circ-[extreme]cold"
return 1
/obj/machinery/power/generator/process()
if(!circ1 || !circ2 || !anchored || stat & (BROKEN|NOPOWER))
stored_energy = 0
return
updateDialog()
var/datum/gas_mixture/air1 = circ1.return_transfer_air()
var/datum/gas_mixture/air2 = circ2.return_transfer_air()
lastgen2 = lastgen1
lastgen1 = 0
last_thermal_gen = 0
last_circ1_gen = 0
last_circ2_gen = 0
if(air1 && air2)
var/air1_heat_capacity = air1.heat_capacity()
var/air2_heat_capacity = air2.heat_capacity()
var/delta_temperature = abs(air2.temperature - air1.temperature)
if(delta_temperature > 0 && air1_heat_capacity > 0 && air2_heat_capacity > 0)
var/energy_transfer = delta_temperature*air2_heat_capacity*air1_heat_capacity/(air2_heat_capacity+air1_heat_capacity)
var/heat = energy_transfer*(1-thermal_efficiency)
last_thermal_gen = energy_transfer*thermal_efficiency
if(air2.temperature > air1.temperature)
air2.temperature = air2.temperature - energy_transfer/air2_heat_capacity
air1.temperature = air1.temperature + heat/air1_heat_capacity
else
air2.temperature = air2.temperature + heat/air2_heat_capacity
air1.temperature = air1.temperature - energy_transfer/air1_heat_capacity
//Transfer the air
if (air1)
circ1.air2.merge(air1)
if (air2)
circ2.air2.merge(air2)
//Update the gas networks
if(circ1.network2)
circ1.network2.update = 1
if(circ2.network2)
circ2.network2.update = 1
//Exceeding maximum power leads to some power loss
if(effective_gen > max_power && prob(5))
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
stored_energy *= 0.5
//Power
last_circ1_gen = circ1.return_stored_energy()
last_circ2_gen = circ2.return_stored_energy()
stored_energy += last_thermal_gen + last_circ1_gen + last_circ2_gen
lastgen1 = stored_energy*0.4 //smoothened power generation to prevent slingshotting as pressure is equalized, then restored by pumps
stored_energy -= lastgen1
effective_gen = (lastgen1 + lastgen2) / 2
// Sounds.
if(effective_gen > (max_power * 0.05)) // More than 5% and sounds start.
soundloop.start()
soundloop.volume = LERP(1, 40, effective_gen / max_power)
else
soundloop.stop()
// update icon overlays and power usage only if displayed level has changed
var/genlev = max(0, min( round(11*effective_gen / max_power), 11))
if(effective_gen > 100 && genlev == 0)
genlev = 1
if(genlev != lastgenlev)
lastgenlev = genlev
update_icon()
add_avail(effective_gen)
/obj/machinery/power/generator/attack_ai(mob/user)
attack_hand(user)
/obj/machinery/power/generator/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(W.has_tool_quality(TOOL_WRENCH))
playsound(src, W.usesound, 75, 1)
anchored = !anchored
user.visible_message("[user.name] [anchored ? "secures" : "unsecures"] the bolts holding [src.name] to the floor.", \
"You [anchored ? "secure" : "unsecure"] the bolts holding [src] to the floor.", \
"You hear a ratchet.")
update_use_power(anchored ? USE_POWER_IDLE : USE_POWER_ACTIVE)
if(anchored) // Powernet connection stuff.
connect_to_network()
else
disconnect_from_network()
reconnect()
lastgenlev = 0
effective_gen = 0
update_icon()
else
..()
/obj/machinery/power/generator/attack_hand(mob/user)
add_fingerprint(user)
if(stat & (BROKEN|NOPOWER) || !anchored) return
if(!circ1 || !circ2) //Just incase the middle part of the TEG was not wrenched last.
reconnect()
tgui_interact(user)
/obj/machinery/power/generator/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "TEGenerator", name)
ui.open()
/obj/machinery/power/generator/tgui_data(mob/user)
// this is the data which will be sent to the ui
var/vertical = 0
if (dir == NORTH || dir == SOUTH)
vertical = 1
var/list/data = list()
data["totalOutput"] = effective_gen
data["maxTotalOutput"] = max_power
data["thermalOutput"] = last_thermal_gen
data["primary"] = list()
if(circ1)
//The one on the left (or top)
data["primary"]["dir"] = vertical ? "top" : "left"
data["primary"]["output"] = last_circ1_gen
data["primary"]["flowCapacity"] = circ1.volume_capacity_used*100
data["primary"]["inletPressure"] = circ1.air1.return_pressure()
data["primary"]["inletTemperature"] = circ1.air1.temperature
data["primary"]["outletPressure"] = circ1.air2.return_pressure()
data["primary"]["outletTemperature"] = circ1.air2.temperature
data["secondary"] = list()
if(circ2)
//Now for the one on the right (or bottom)
data["secondary"]["dir"] = vertical ? "bottom" : "right"
data["secondary"]["output"] = last_circ2_gen
data["secondary"]["flowCapacity"] = circ2.volume_capacity_used*100
data["secondary"]["inletPressure"] = circ2.air1.return_pressure()
data["secondary"]["inletTemperature"] = circ2.air1.temperature
data["secondary"]["outletPressure"] = circ2.air2.return_pressure()
data["secondary"]["outletTemperature"] = circ2.air2.temperature
return data
/obj/machinery/power/generator/power_change()
..()
update_icon()
/obj/machinery/power/generator/verb/rotate_clockwise()
set category = "Object"
set name = "Rotate Generator Clockwise"
set src in view(1)
if (usr.stat || usr.restrained() || anchored)
return
src.set_dir(turn(src.dir, 270))
/obj/machinery/power/generator/verb/rotate_counterclockwise()
set category = "Object"
set name = "Rotate Generator Counterclockwise"
set src in view(1)
if (usr.stat || usr.restrained() || anchored)
return
src.set_dir(turn(src.dir, 90))
/obj/machinery/power/generator/power_spike(var/announce_prob = 30)
if(!(effective_gen >= max_power / 2 && powernet)) // Don't make a spike if we're not making a whole lot of power.
return
var/list/powernet_union = powernet.nodes.Copy()
for(var/obj/machinery/power/terminal/T in powernet.nodes)
if(T.master && istype(T.master, /obj/machinery/power/smes))
var/obj/machinery/power/smes/S = T.master
powernet_union |= S.powernet.nodes
var/found_grid_checker = FALSE
for(var/obj/machinery/power/grid_checker/G in powernet_union)
G.power_failure(announce_prob) // If we found a grid checker, then all is well.
found_grid_checker = TRUE
if(!found_grid_checker) // Otherwise lets break some stuff.
spawn(1)
command_announcement.Announce("Dangerous power spike detected in the power network. Please check machinery \
for electrical damage.",
"Critical Power Overload")
var/i = 0
var/limit = rand(30, 50)
for(var/obj/machinery/power/P in powernet_union)
P.overload(src)
i++
if(i % 5)
sleep(1)
if(i >= limit)
break
GLOBAL_LIST_EMPTY(all_turbines)
/obj/machinery/power/generator
name = "thermoelectric generator"
desc = "It's a high efficiency thermoelectric generator."
icon_state = "teg-unassembled"
density = TRUE
anchored = FALSE
unacidable = TRUE
use_power = USE_POWER_IDLE
idle_power_usage = 100 //Watts, I hope. Just enough to do the computer and display things.
var/max_power = 500000
var/thermal_efficiency = 0.65
var/obj/machinery/atmospherics/binary/circulator/circ1
var/obj/machinery/atmospherics/binary/circulator/circ2
var/last_circ1_gen = 0
var/last_circ2_gen = 0
var/last_thermal_gen = 0
var/stored_energy = 0
var/lastgen1 = 0
var/lastgen2 = 0
var/effective_gen = 0
var/lastgenlev = 0
var/datum/looping_sound/generator/soundloop
/obj/machinery/power/generator/Initialize()
soundloop = new(list(src), FALSE)
desc = initial(desc) + " Rated for [round(max_power/1000)] kW."
GLOB.all_turbines += src
..() //Not returned, because...
return INITIALIZE_HINT_LATELOAD
/obj/machinery/power/generator/LateInitialize()
reconnect()
/obj/machinery/power/generator/Destroy()
QDEL_NULL(soundloop)
GLOB.all_turbines -= src
return ..()
//generators connect in dir and reverse_dir(dir) directions
//mnemonic to determine circulator/generator directions: the cirulators orbit clockwise around the generator
//so a circulator to the NORTH of the generator connects first to the EAST, then to the WEST
//and a circulator to the WEST of the generator connects first to the NORTH, then to the SOUTH
//note that the circulator's outlet dir is it's always facing dir, and it's inlet is always the reverse
/obj/machinery/power/generator/proc/reconnect()
circ1 = null
circ2 = null
if(src.loc && anchored)
if(src.dir & (EAST|WEST))
circ1 = locate(/obj/machinery/atmospherics/binary/circulator) in get_step(src,WEST)
circ2 = locate(/obj/machinery/atmospherics/binary/circulator) in get_step(src,EAST)
if(circ1 && circ2)
if(circ1.dir != NORTH || circ2.dir != SOUTH)
circ1 = null
circ2 = null
else if(src.dir & (NORTH|SOUTH))
circ1 = locate(/obj/machinery/atmospherics/binary/circulator) in get_step(src,NORTH)
circ2 = locate(/obj/machinery/atmospherics/binary/circulator) in get_step(src,SOUTH)
if(circ1 && circ2 && (circ1.dir != EAST || circ2.dir != WEST))
circ1 = null
circ2 = null
/obj/machinery/power/generator/update_icon()
icon_state = anchored ? "teg-assembled" : "teg-unassembled"
cut_overlays()
if (circ1)
circ1.temperature_overlay = null
if (circ2)
circ2.temperature_overlay = null
if (stat & (NOPOWER|BROKEN))
return 1
else
if (lastgenlev != 0)
add_overlay("teg-op[lastgenlev]")
if (circ1 && circ2)
var/extreme = (lastgenlev > 9) ? "ex" : ""
if (circ1.last_temperature < circ2.last_temperature)
circ1.temperature_overlay = "circ-[extreme]cold"
circ2.temperature_overlay = "circ-[extreme]hot"
else
circ1.temperature_overlay = "circ-[extreme]hot"
circ2.temperature_overlay = "circ-[extreme]cold"
return 1
/obj/machinery/power/generator/process()
if(!circ1 || !circ2 || !anchored || stat & (BROKEN|NOPOWER))
stored_energy = 0
return
updateDialog()
var/datum/gas_mixture/air1 = circ1.return_transfer_air()
var/datum/gas_mixture/air2 = circ2.return_transfer_air()
lastgen2 = lastgen1
lastgen1 = 0
last_thermal_gen = 0
last_circ1_gen = 0
last_circ2_gen = 0
if(air1 && air2)
var/air1_heat_capacity = air1.heat_capacity()
var/air2_heat_capacity = air2.heat_capacity()
var/delta_temperature = abs(air2.temperature - air1.temperature)
if(delta_temperature > 0 && air1_heat_capacity > 0 && air2_heat_capacity > 0)
var/energy_transfer = delta_temperature*air2_heat_capacity*air1_heat_capacity/(air2_heat_capacity+air1_heat_capacity)
var/heat = energy_transfer*(1-thermal_efficiency)
last_thermal_gen = energy_transfer*thermal_efficiency
if(air2.temperature > air1.temperature)
air2.temperature = air2.temperature - energy_transfer/air2_heat_capacity
air1.temperature = air1.temperature + heat/air1_heat_capacity
else
air2.temperature = air2.temperature + heat/air2_heat_capacity
air1.temperature = air1.temperature - energy_transfer/air1_heat_capacity
//Transfer the air
if (air1)
circ1.air2.merge(air1)
if (air2)
circ2.air2.merge(air2)
//Update the gas networks
if(circ1.network2)
circ1.network2.update = 1
if(circ2.network2)
circ2.network2.update = 1
//Exceeding maximum power leads to some power loss
if(effective_gen > max_power && prob(5))
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
stored_energy *= 0.5
//Power
last_circ1_gen = circ1.return_stored_energy()
last_circ2_gen = circ2.return_stored_energy()
stored_energy += last_thermal_gen + last_circ1_gen + last_circ2_gen
lastgen1 = stored_energy*0.4 //smoothened power generation to prevent slingshotting as pressure is equalized, then restored by pumps
stored_energy -= lastgen1
effective_gen = (lastgen1 + lastgen2) / 2
// Sounds.
if(effective_gen > (max_power * 0.05)) // More than 5% and sounds start.
soundloop.start()
soundloop.volume = LERP(1, 40, effective_gen / max_power)
else
soundloop.stop()
// update icon overlays and power usage only if displayed level has changed
var/genlev = max(0, min( round(11*effective_gen / max_power), 11))
if(effective_gen > 100 && genlev == 0)
genlev = 1
if(genlev != lastgenlev)
lastgenlev = genlev
update_icon()
add_avail(effective_gen)
/obj/machinery/power/generator/attack_ai(mob/user)
attack_hand(user)
/obj/machinery/power/generator/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(W.has_tool_quality(TOOL_WRENCH))
playsound(src, W.usesound, 75, 1)
anchored = !anchored
user.visible_message("[user.name] [anchored ? "secures" : "unsecures"] the bolts holding [src.name] to the floor.", \
"You [anchored ? "secure" : "unsecure"] the bolts holding [src] to the floor.", \
"You hear a ratchet.")
update_use_power(anchored ? USE_POWER_IDLE : USE_POWER_ACTIVE)
if(anchored) // Powernet connection stuff.
connect_to_network()
else
disconnect_from_network()
reconnect()
lastgenlev = 0
effective_gen = 0
update_icon()
else
..()
/obj/machinery/power/generator/attack_hand(mob/user)
add_fingerprint(user)
if(stat & (BROKEN|NOPOWER) || !anchored) return
if(!circ1 || !circ2) //Just incase the middle part of the TEG was not wrenched last.
reconnect()
tgui_interact(user)
/obj/machinery/power/generator/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "TEGenerator", name)
ui.open()
/obj/machinery/power/generator/tgui_data(mob/user)
// this is the data which will be sent to the ui
var/vertical = 0
if (dir == NORTH || dir == SOUTH)
vertical = 1
var/list/data = list()
data["totalOutput"] = effective_gen
data["maxTotalOutput"] = max_power
data["thermalOutput"] = last_thermal_gen
data["primary"] = list()
if(circ1)
//The one on the left (or top)
data["primary"]["dir"] = vertical ? "top" : "left"
data["primary"]["output"] = last_circ1_gen
data["primary"]["flowCapacity"] = circ1.volume_capacity_used*100
data["primary"]["inletPressure"] = circ1.air1.return_pressure()
data["primary"]["inletTemperature"] = circ1.air1.temperature
data["primary"]["outletPressure"] = circ1.air2.return_pressure()
data["primary"]["outletTemperature"] = circ1.air2.temperature
data["secondary"] = list()
if(circ2)
//Now for the one on the right (or bottom)
data["secondary"]["dir"] = vertical ? "bottom" : "right"
data["secondary"]["output"] = last_circ2_gen
data["secondary"]["flowCapacity"] = circ2.volume_capacity_used*100
data["secondary"]["inletPressure"] = circ2.air1.return_pressure()
data["secondary"]["inletTemperature"] = circ2.air1.temperature
data["secondary"]["outletPressure"] = circ2.air2.return_pressure()
data["secondary"]["outletTemperature"] = circ2.air2.temperature
return data
/obj/machinery/power/generator/power_change()
..()
update_icon()
/obj/machinery/power/generator/verb/rotate_clockwise()
set category = "Object"
set name = "Rotate Generator Clockwise"
set src in view(1)
if (usr.stat || usr.restrained() || anchored)
return
src.set_dir(turn(src.dir, 270))
/obj/machinery/power/generator/verb/rotate_counterclockwise()
set category = "Object"
set name = "Rotate Generator Counterclockwise"
set src in view(1)
if (usr.stat || usr.restrained() || anchored)
return
src.set_dir(turn(src.dir, 90))
/obj/machinery/power/generator/power_spike(var/announce_prob = 30)
if(!(effective_gen >= max_power / 2 && powernet)) // Don't make a spike if we're not making a whole lot of power.
return
var/list/powernet_union = powernet.nodes.Copy()
for(var/obj/machinery/power/terminal/T in powernet.nodes)
if(T.master && istype(T.master, /obj/machinery/power/smes))
var/obj/machinery/power/smes/S = T.master
powernet_union |= S.powernet.nodes
var/found_grid_checker = FALSE
for(var/obj/machinery/power/grid_checker/G in powernet_union)
G.power_failure(announce_prob) // If we found a grid checker, then all is well.
found_grid_checker = TRUE
if(!found_grid_checker) // Otherwise lets break some stuff.
spawn(1)
command_announcement.Announce("Dangerous power spike detected in the power network. Please check machinery \
for electrical damage.",
"Critical Power Overload")
var/i = 0
var/limit = rand(30, 50)
for(var/obj/machinery/power/P in powernet_union)
P.overload(src)
i++
if(i % 5)
sleep(1)
if(i >= limit)
break
File diff suppressed because it is too large Load Diff
+419 -419
View File
@@ -1,419 +1,419 @@
//Baseline portable generator. Has all the default handling. Not intended to be used on it's own (since it generates unlimited power).
/obj/machinery/power/port_gen
name = "Placeholder Generator" //seriously, don't use this. It can't be anchored without VV magic.
desc = "A portable generator for emergency backup power"
icon = 'icons/obj/power_vr.dmi' //VOREStation Edit
icon_state = "portgen0" //VOREStation Edit
density = TRUE
anchored = FALSE
use_power = USE_POWER_OFF
interact_offline = TRUE
var/active = 0
var/power_gen = 5000
var/recent_fault = 0
var/power_output = 1
/obj/machinery/power/port_gen/proc/IsBroken()
return (stat & (BROKEN|EMPED))
/obj/machinery/power/port_gen/proc/HasFuel() //Placeholder for fuel check.
return 1
/obj/machinery/power/port_gen/proc/UseFuel() //Placeholder for fuel use.
return
/obj/machinery/power/port_gen/proc/DropFuel()
return
/obj/machinery/power/port_gen/proc/handleInactive()
return
/obj/machinery/power/port_gen/proc/TogglePower()
if(active)
active = FALSE
update_icon()
// soundloop.stop()
else if(HasFuel())
active = TRUE
update_icon()
// soundloop.start()
/obj/machinery/power/port_gen/process()
if(active && HasFuel() && !IsBroken() && anchored && powernet)
add_avail(power_gen * power_output)
UseFuel()
else
active = FALSE
update_icon()
handleInactive()
/obj/machinery/power/port_gen/update_icon()
if(active)
icon_state = "[initial(icon_state)]on"
else
icon_state = initial(icon_state)
/obj/machinery/power/powered()
return 1 //doesn't require an external power source
/obj/machinery/power/port_gen/attack_hand(mob/user as mob)
if(..())
return
if(!anchored)
return
/obj/machinery/power/port_gen/examine(mob/user)
. = ..()
if(Adjacent(user)) //It literally has a light on the sprite, are you sure this is necessary?
if(active)
. += "<span class='notice'>The generator is on.</span>"
else
. += "<span class='notice'>The generator is off.</span>"
/obj/machinery/power/port_gen/emp_act(severity)
var/duration = 6000 //ten minutes
switch(severity)
if(1)
stat &= BROKEN
if(prob(75)) explode()
if(2)
if(prob(50)) stat &= BROKEN
if(prob(10)) explode()
if(3)
if(prob(25)) stat &= BROKEN
duration = 300
if(4)
if(prob(10)) stat &= BROKEN
duration = 300
stat |= EMPED
if(duration)
spawn(duration)
stat &= ~EMPED
/obj/machinery/power/port_gen/proc/explode()
explosion(src.loc, -1, 3, 5, -1)
qdel(src)
#define TEMPERATURE_DIVISOR 40
#define TEMPERATURE_CHANGE_MAX 20
//A power generator that runs on solid plasma sheets.
/obj/machinery/power/port_gen/pacman
name = "\improper P.A.C.M.A.N.-type Portable Generator"
desc = "A power generator that runs on solid phoron sheets. Rated for 80 kW max safe output."
circuit = /obj/item/weapon/circuitboard/pacman
var/sheet_name = "Phoron Sheets"
var/sheet_path = /obj/item/stack/material/phoron
/*
These values were chosen so that the generator can run safely up to 80 kW
A full 50 phoron sheet stack should last 20 minutes at power_output = 4
temperature_gain and max_temperature are set so that the max safe power level is 4.
Setting to 5 or higher can only be done temporarily before the generator overheats.
*/
power_gen = 20000 //Watts output per power_output level
var/max_power_output = 5 //The maximum power setting without emagging.
var/max_safe_output = 4 // For UI use, maximal output that won't cause overheat.
var/time_per_sheet = 96 //fuel efficiency - how long 1 sheet lasts at power level 1
var/max_sheets = 100 //max capacity of the hopper
var/max_temperature = 300 //max temperature before overheating increases
var/temperature_gain = 50 //how much the temperature increases per power output level, in degrees per level
var/sheets = 0 //How many sheets of material are loaded in the generator
var/sheet_left = 0 //How much is left of the current sheet
var/temperature = 0 //The current temperature
var/overheating = 0 //if this gets high enough the generator explodes
/obj/machinery/power/port_gen/pacman/Initialize()
. = ..()
default_apply_parts()
if(anchored)
connect_to_network()
/obj/machinery/power/port_gen/pacman/Destroy()
DropFuel()
return ..()
/obj/machinery/power/port_gen/pacman/dismantle()
while( sheets > 0 )
DropFuel()
return ..()
/obj/machinery/power/port_gen/pacman/RefreshParts()
var/temp_rating = 0
for(var/obj/item/weapon/stock_parts/SP in component_parts)
if(istype(SP, /obj/item/weapon/stock_parts/matter_bin))
max_sheets = SP.rating * SP.rating * 50
else if(istype(SP, /obj/item/weapon/stock_parts/micro_laser) || istype(SP, /obj/item/weapon/stock_parts/capacitor))
temp_rating += SP.rating
power_gen = round(initial(power_gen) * (max(2, temp_rating) / 2))
/obj/machinery/power/port_gen/pacman/examine(mob/user)
. = ..()
. += "It appears to be producing [power_gen*power_output] W."
. += "There [sheets == 1 ? "is" : "are"] [sheets] sheet\s left in the hopper."
if(IsBroken())
. += "<span class='warning'>It seems to have broken down.</span>"
if(overheating)
. += "<span class='danger'>It is overheating!</span>"
/obj/machinery/power/port_gen/pacman/HasFuel()
var/needed_sheets = power_output / time_per_sheet
if(sheets >= needed_sheets - sheet_left)
return 1
return 0
//Removes one stack's worth of material from the generator.
/obj/machinery/power/port_gen/pacman/DropFuel()
if(sheets)
var/obj/item/stack/material/S = new sheet_path(loc, sheets)
sheets -= S.get_amount()
/obj/machinery/power/port_gen/pacman/UseFuel()
//how much material are we using this iteration?
var/needed_sheets = power_output / time_per_sheet
//HasFuel() should guarantee us that there is enough fuel left, so no need to check that
//the only thing we need to worry about is if we are going to rollover to the next sheet
if (needed_sheets > sheet_left)
sheets--
sheet_left = (1 + sheet_left) - needed_sheets
else
sheet_left -= needed_sheets
//calculate the "target" temperature range
//This should probably depend on the external temperature somehow, but whatever.
var/lower_limit = 56 + power_output * temperature_gain
var/upper_limit = 76 + power_output * temperature_gain
/*
Hot or cold environments can affect the equilibrium temperature
The lower the pressure the less effect it has. I guess it cools using a radiator or something when in vacuum.
Gives traitors more opportunities to sabotage the generator or allows enterprising engineers to build additional
cooling in order to get more power out.
*/
var/datum/gas_mixture/environment = loc.return_air()
if (environment)
var/ratio = min(environment.return_pressure()/ONE_ATMOSPHERE, 1)
var/ambient = environment.temperature - T20C
lower_limit += ambient*ratio
upper_limit += ambient*ratio
var/average = (upper_limit + lower_limit)/2
//calculate the temperature increase
var/bias = 0
if (temperature < lower_limit)
bias = min(round((average - temperature)/TEMPERATURE_DIVISOR, 1), TEMPERATURE_CHANGE_MAX)
else if (temperature > upper_limit)
bias = max(round((temperature - average)/TEMPERATURE_DIVISOR, 1), -TEMPERATURE_CHANGE_MAX)
//limit temperature increase so that it cannot raise temperature above upper_limit,
//or if it is already above upper_limit, limit the increase to 0.
var/inc_limit = max(upper_limit - temperature, 0)
var/dec_limit = min(temperature - lower_limit, 0)
temperature += between(dec_limit, rand(-7 + bias, 7 + bias), inc_limit)
if (temperature > max_temperature)
overheat()
else if (overheating > 0)
overheating--
/obj/machinery/power/port_gen/pacman/handleInactive()
var/cooling_temperature = 20
var/datum/gas_mixture/environment = loc.return_air()
if(environment)
var/ratio = min(environment.return_pressure()/ONE_ATMOSPHERE, 1)
var/ambient = environment.temperature - T20C
cooling_temperature += ambient*ratio
if(temperature > cooling_temperature)
var/temp_loss = (temperature - cooling_temperature)/TEMPERATURE_DIVISOR
temp_loss = between(2, round(temp_loss, 1), TEMPERATURE_CHANGE_MAX)
temperature = max(temperature - temp_loss, cooling_temperature)
updateDialog()
if(overheating)
overheating--
/obj/machinery/power/port_gen/pacman/proc/overheat()
overheating++
if (overheating > 60)
explode()
/obj/machinery/power/port_gen/pacman/explode()
//Vapourize all the phoron
//When ground up in a grinder, 1 sheet produces 20 u of phoron -- Chemistry-Machinery.dm
//1 mol = 10 u? I dunno. 1 mol of carbon is definitely bigger than a pill
var/phoron = (sheets+sheet_left)*20
var/datum/gas_mixture/environment = loc.return_air()
if (environment)
environment.adjust_gas_temp("phoron", phoron/10, temperature + T0C)
sheets = 0
sheet_left = 0
..()
/obj/machinery/power/port_gen/pacman/emag_act(var/remaining_charges, var/mob/user)
if (active && prob(25))
explode() //if they're foolish enough to emag while it's running
if (!emagged)
emagged = 1
return 1
/obj/machinery/power/port_gen/pacman/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(istype(O, sheet_path))
var/obj/item/stack/addstack = O
var/amount = min((max_sheets - sheets), addstack.get_amount())
if(amount < 1)
to_chat(user, "<span class='warning'>The [src.name] is full!</span>")
return
to_chat(user, "<span class='notice'>You add [amount] sheet\s to the [src.name].</span>")
sheets += amount
addstack.use(amount)
updateUsrDialog()
return
else if(!active)
if(O.has_tool_quality(TOOL_WRENCH))
if(!anchored)
connect_to_network()
to_chat(user, "<span class='notice'>You secure the generator to the floor.</span>")
else
disconnect_from_network()
to_chat(user, "<span class='notice'>You unsecure the generator from the floor.</span>")
playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
anchored = !anchored
return
else if(default_deconstruction_screwdriver(user, O))
return
else if(default_deconstruction_crowbar(user, O))
return
else if(default_part_replacement(user, O))
return
return ..()
/obj/machinery/power/port_gen/pacman/attack_hand(mob/user as mob)
..()
if (!anchored)
return
tgui_interact(user)
/obj/machinery/power/port_gen/pacman/attack_ai(mob/user as mob)
tgui_interact(user)
/obj/machinery/power/port_gen/tgui_status(mob/user, datum/tgui_state/state)
if(IsBroken())
return STATUS_CLOSE
return ..()
/obj/machinery/power/port_gen/pacman/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "PortableGenerator", name)
ui.open()
/obj/machinery/power/port_gen/pacman/tgui_data(mob/user)
var/list/data = list()
data["active"] = active
if(istype(user, /mob/living/silicon/ai))
data["is_ai"] = TRUE
else if(istype(user, /mob/living/silicon/robot) && !Adjacent(user))
data["is_ai"] = TRUE
else
data["is_ai"] = FALSE
data["sheet_name"] = capitalize(sheet_name)
data["fuel_stored"] = round((sheets * 1000) + (sheet_left * 1000))
data["fuel_capacity"] = round(max_sheets * 1000, 0.1)
data["fuel_usage"] = active ? round((power_output / time_per_sheet) * 1000) : 0
data["anchored"] = anchored
data["connected"] = (powernet == null ? 0 : 1)
data["ready_to_boot"] = anchored && HasFuel()
data["power_generated"] = DisplayPower(power_gen)
data["power_output"] = DisplayPower(power_gen * power_output)
data["unsafe_output"] = power_output > max_safe_output
data["power_available"] = (powernet == null ? 0 : DisplayPower(avail()))
data["temperature_current"] = temperature
data["temperature_max"] = max_temperature
data["temperature_overheat"] = overheating
// 1 sheet = 1000cm3?
return data
/obj/machinery/power/port_gen/pacman/tgui_act(action, params)
if(..())
return
add_fingerprint(usr)
switch(action)
if("toggle_power")
TogglePower()
. = TRUE
if("eject")
if(!active)
DropFuel()
. = TRUE
if("lower_power")
if(power_output > 1)
power_output--
. = TRUE
if("higher_power")
if(power_output < max_power_output || (emagged && power_output < round(max_power_output * 2.5)))
power_output++
. = TRUE
/obj/machinery/power/port_gen/pacman/super
name = "S.U.P.E.R.P.A.C.M.A.N.-type Portable Generator"
desc = "A power generator that utilizes uranium sheets as fuel. Can run for much longer than the standard PACMAN type generators. Rated for 80 kW max safe output."
icon_state = "portgen1"
sheet_path = /obj/item/stack/material/uranium
sheet_name = "Uranium Sheets"
time_per_sheet = 576 //same power output, but a 50 sheet stack will last 2 hours at max safe power
circuit = /obj/item/weapon/circuitboard/pacman/super
/obj/machinery/power/port_gen/pacman/super/UseFuel()
//produces a tiny amount of radiation when in use
if (prob(2*power_output))
SSradiation.radiate(src, 4)
..()
/obj/machinery/power/port_gen/pacman/super/explode()
//a nice burst of radiation
var/rads = 50 + (sheets + sheet_left)*1.5
SSradiation.radiate(src, (max(20, rads)))
explosion(src.loc, 3, 3, 5, 3)
qdel(src)
/obj/machinery/power/port_gen/pacman/mrs
name = "M.R.S.P.A.C.M.A.N.-type Portable Generator"
desc = "An advanced power generator that runs on tritium. Rated for 200 kW maximum safe output!"
icon_state = "portgen2"
sheet_path = /obj/item/stack/material/tritium
sheet_name = "Tritium Fuel Sheets"
//I don't think tritium has any other use, so we might as well make this rewarding for players
//max safe power output (power level = 8) is 200 kW and lasts for 1 hour - 3 or 4 of these could power the station
power_gen = 25000 //watts
max_power_output = 10
max_safe_output = 8
time_per_sheet = 576
max_temperature = 800
temperature_gain = 90
circuit = /obj/item/weapon/circuitboard/pacman/mrs
/obj/machinery/power/port_gen/pacman/mrs/explode()
//no special effects, but the explosion is pretty big (same as a supermatter shard).
explosion(src.loc, 3, 6, 12, 16, 1)
qdel(src)
//Baseline portable generator. Has all the default handling. Not intended to be used on it's own (since it generates unlimited power).
/obj/machinery/power/port_gen
name = "Placeholder Generator" //seriously, don't use this. It can't be anchored without VV magic.
desc = "A portable generator for emergency backup power"
icon = 'icons/obj/power_vr.dmi' //VOREStation Edit
icon_state = "portgen0" //VOREStation Edit
density = TRUE
anchored = FALSE
use_power = USE_POWER_OFF
interact_offline = TRUE
var/active = 0
var/power_gen = 5000
var/recent_fault = 0
var/power_output = 1
/obj/machinery/power/port_gen/proc/IsBroken()
return (stat & (BROKEN|EMPED))
/obj/machinery/power/port_gen/proc/HasFuel() //Placeholder for fuel check.
return 1
/obj/machinery/power/port_gen/proc/UseFuel() //Placeholder for fuel use.
return
/obj/machinery/power/port_gen/proc/DropFuel()
return
/obj/machinery/power/port_gen/proc/handleInactive()
return
/obj/machinery/power/port_gen/proc/TogglePower()
if(active)
active = FALSE
update_icon()
// soundloop.stop()
else if(HasFuel())
active = TRUE
update_icon()
// soundloop.start()
/obj/machinery/power/port_gen/process()
if(active && HasFuel() && !IsBroken() && anchored && powernet)
add_avail(power_gen * power_output)
UseFuel()
else
active = FALSE
update_icon()
handleInactive()
/obj/machinery/power/port_gen/update_icon()
if(active)
icon_state = "[initial(icon_state)]on"
else
icon_state = initial(icon_state)
/obj/machinery/power/powered()
return 1 //doesn't require an external power source
/obj/machinery/power/port_gen/attack_hand(mob/user as mob)
if(..())
return
if(!anchored)
return
/obj/machinery/power/port_gen/examine(mob/user)
. = ..()
if(Adjacent(user)) //It literally has a light on the sprite, are you sure this is necessary?
if(active)
. += "<span class='notice'>The generator is on.</span>"
else
. += "<span class='notice'>The generator is off.</span>"
/obj/machinery/power/port_gen/emp_act(severity)
var/duration = 6000 //ten minutes
switch(severity)
if(1)
stat &= BROKEN
if(prob(75)) explode()
if(2)
if(prob(50)) stat &= BROKEN
if(prob(10)) explode()
if(3)
if(prob(25)) stat &= BROKEN
duration = 300
if(4)
if(prob(10)) stat &= BROKEN
duration = 300
stat |= EMPED
if(duration)
spawn(duration)
stat &= ~EMPED
/obj/machinery/power/port_gen/proc/explode()
explosion(src.loc, -1, 3, 5, -1)
qdel(src)
#define TEMPERATURE_DIVISOR 40
#define TEMPERATURE_CHANGE_MAX 20
//A power generator that runs on solid plasma sheets.
/obj/machinery/power/port_gen/pacman
name = "\improper P.A.C.M.A.N.-type Portable Generator"
desc = "A power generator that runs on solid phoron sheets. Rated for 80 kW max safe output."
circuit = /obj/item/weapon/circuitboard/pacman
var/sheet_name = "Phoron Sheets"
var/sheet_path = /obj/item/stack/material/phoron
/*
These values were chosen so that the generator can run safely up to 80 kW
A full 50 phoron sheet stack should last 20 minutes at power_output = 4
temperature_gain and max_temperature are set so that the max safe power level is 4.
Setting to 5 or higher can only be done temporarily before the generator overheats.
*/
power_gen = 20000 //Watts output per power_output level
var/max_power_output = 5 //The maximum power setting without emagging.
var/max_safe_output = 4 // For UI use, maximal output that won't cause overheat.
var/time_per_sheet = 96 //fuel efficiency - how long 1 sheet lasts at power level 1
var/max_sheets = 100 //max capacity of the hopper
var/max_temperature = 300 //max temperature before overheating increases
var/temperature_gain = 50 //how much the temperature increases per power output level, in degrees per level
var/sheets = 0 //How many sheets of material are loaded in the generator
var/sheet_left = 0 //How much is left of the current sheet
var/temperature = 0 //The current temperature
var/overheating = 0 //if this gets high enough the generator explodes
/obj/machinery/power/port_gen/pacman/Initialize()
. = ..()
default_apply_parts()
if(anchored)
connect_to_network()
/obj/machinery/power/port_gen/pacman/Destroy()
DropFuel()
return ..()
/obj/machinery/power/port_gen/pacman/dismantle()
while( sheets > 0 )
DropFuel()
return ..()
/obj/machinery/power/port_gen/pacman/RefreshParts()
var/temp_rating = 0
for(var/obj/item/weapon/stock_parts/SP in component_parts)
if(istype(SP, /obj/item/weapon/stock_parts/matter_bin))
max_sheets = SP.rating * SP.rating * 50
else if(istype(SP, /obj/item/weapon/stock_parts/micro_laser) || istype(SP, /obj/item/weapon/stock_parts/capacitor))
temp_rating += SP.rating
power_gen = round(initial(power_gen) * (max(2, temp_rating) / 2))
/obj/machinery/power/port_gen/pacman/examine(mob/user)
. = ..()
. += "It appears to be producing [power_gen*power_output] W."
. += "There [sheets == 1 ? "is" : "are"] [sheets] sheet\s left in the hopper."
if(IsBroken())
. += "<span class='warning'>It seems to have broken down.</span>"
if(overheating)
. += "<span class='danger'>It is overheating!</span>"
/obj/machinery/power/port_gen/pacman/HasFuel()
var/needed_sheets = power_output / time_per_sheet
if(sheets >= needed_sheets - sheet_left)
return 1
return 0
//Removes one stack's worth of material from the generator.
/obj/machinery/power/port_gen/pacman/DropFuel()
if(sheets)
var/obj/item/stack/material/S = new sheet_path(loc, sheets)
sheets -= S.get_amount()
/obj/machinery/power/port_gen/pacman/UseFuel()
//how much material are we using this iteration?
var/needed_sheets = power_output / time_per_sheet
//HasFuel() should guarantee us that there is enough fuel left, so no need to check that
//the only thing we need to worry about is if we are going to rollover to the next sheet
if (needed_sheets > sheet_left)
sheets--
sheet_left = (1 + sheet_left) - needed_sheets
else
sheet_left -= needed_sheets
//calculate the "target" temperature range
//This should probably depend on the external temperature somehow, but whatever.
var/lower_limit = 56 + power_output * temperature_gain
var/upper_limit = 76 + power_output * temperature_gain
/*
Hot or cold environments can affect the equilibrium temperature
The lower the pressure the less effect it has. I guess it cools using a radiator or something when in vacuum.
Gives traitors more opportunities to sabotage the generator or allows enterprising engineers to build additional
cooling in order to get more power out.
*/
var/datum/gas_mixture/environment = loc.return_air()
if (environment)
var/ratio = min(environment.return_pressure()/ONE_ATMOSPHERE, 1)
var/ambient = environment.temperature - T20C
lower_limit += ambient*ratio
upper_limit += ambient*ratio
var/average = (upper_limit + lower_limit)/2
//calculate the temperature increase
var/bias = 0
if (temperature < lower_limit)
bias = min(round((average - temperature)/TEMPERATURE_DIVISOR, 1), TEMPERATURE_CHANGE_MAX)
else if (temperature > upper_limit)
bias = max(round((temperature - average)/TEMPERATURE_DIVISOR, 1), -TEMPERATURE_CHANGE_MAX)
//limit temperature increase so that it cannot raise temperature above upper_limit,
//or if it is already above upper_limit, limit the increase to 0.
var/inc_limit = max(upper_limit - temperature, 0)
var/dec_limit = min(temperature - lower_limit, 0)
temperature += between(dec_limit, rand(-7 + bias, 7 + bias), inc_limit)
if (temperature > max_temperature)
overheat()
else if (overheating > 0)
overheating--
/obj/machinery/power/port_gen/pacman/handleInactive()
var/cooling_temperature = 20
var/datum/gas_mixture/environment = loc.return_air()
if(environment)
var/ratio = min(environment.return_pressure()/ONE_ATMOSPHERE, 1)
var/ambient = environment.temperature - T20C
cooling_temperature += ambient*ratio
if(temperature > cooling_temperature)
var/temp_loss = (temperature - cooling_temperature)/TEMPERATURE_DIVISOR
temp_loss = between(2, round(temp_loss, 1), TEMPERATURE_CHANGE_MAX)
temperature = max(temperature - temp_loss, cooling_temperature)
updateDialog()
if(overheating)
overheating--
/obj/machinery/power/port_gen/pacman/proc/overheat()
overheating++
if (overheating > 60)
explode()
/obj/machinery/power/port_gen/pacman/explode()
//Vapourize all the phoron
//When ground up in a grinder, 1 sheet produces 20 u of phoron -- Chemistry-Machinery.dm
//1 mol = 10 u? I dunno. 1 mol of carbon is definitely bigger than a pill
var/phoron = (sheets+sheet_left)*20
var/datum/gas_mixture/environment = loc.return_air()
if (environment)
environment.adjust_gas_temp("phoron", phoron/10, temperature + T0C)
sheets = 0
sheet_left = 0
..()
/obj/machinery/power/port_gen/pacman/emag_act(var/remaining_charges, var/mob/user)
if (active && prob(25))
explode() //if they're foolish enough to emag while it's running
if (!emagged)
emagged = 1
return 1
/obj/machinery/power/port_gen/pacman/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(istype(O, sheet_path))
var/obj/item/stack/addstack = O
var/amount = min((max_sheets - sheets), addstack.get_amount())
if(amount < 1)
to_chat(user, "<span class='warning'>The [src.name] is full!</span>")
return
to_chat(user, "<span class='notice'>You add [amount] sheet\s to the [src.name].</span>")
sheets += amount
addstack.use(amount)
updateUsrDialog()
return
else if(!active)
if(O.has_tool_quality(TOOL_WRENCH))
if(!anchored)
connect_to_network()
to_chat(user, "<span class='notice'>You secure the generator to the floor.</span>")
else
disconnect_from_network()
to_chat(user, "<span class='notice'>You unsecure the generator from the floor.</span>")
playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
anchored = !anchored
return
else if(default_deconstruction_screwdriver(user, O))
return
else if(default_deconstruction_crowbar(user, O))
return
else if(default_part_replacement(user, O))
return
return ..()
/obj/machinery/power/port_gen/pacman/attack_hand(mob/user as mob)
..()
if (!anchored)
return
tgui_interact(user)
/obj/machinery/power/port_gen/pacman/attack_ai(mob/user as mob)
tgui_interact(user)
/obj/machinery/power/port_gen/tgui_status(mob/user, datum/tgui_state/state)
if(IsBroken())
return STATUS_CLOSE
return ..()
/obj/machinery/power/port_gen/pacman/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "PortableGenerator", name)
ui.open()
/obj/machinery/power/port_gen/pacman/tgui_data(mob/user)
var/list/data = list()
data["active"] = active
if(istype(user, /mob/living/silicon/ai))
data["is_ai"] = TRUE
else if(istype(user, /mob/living/silicon/robot) && !Adjacent(user))
data["is_ai"] = TRUE
else
data["is_ai"] = FALSE
data["sheet_name"] = capitalize(sheet_name)
data["fuel_stored"] = round((sheets * 1000) + (sheet_left * 1000))
data["fuel_capacity"] = round(max_sheets * 1000, 0.1)
data["fuel_usage"] = active ? round((power_output / time_per_sheet) * 1000) : 0
data["anchored"] = anchored
data["connected"] = (powernet == null ? 0 : 1)
data["ready_to_boot"] = anchored && HasFuel()
data["power_generated"] = DisplayPower(power_gen)
data["power_output"] = DisplayPower(power_gen * power_output)
data["unsafe_output"] = power_output > max_safe_output
data["power_available"] = (powernet == null ? 0 : DisplayPower(avail()))
data["temperature_current"] = temperature
data["temperature_max"] = max_temperature
data["temperature_overheat"] = overheating
// 1 sheet = 1000cm3?
return data
/obj/machinery/power/port_gen/pacman/tgui_act(action, params)
if(..())
return
add_fingerprint(usr)
switch(action)
if("toggle_power")
TogglePower()
. = TRUE
if("eject")
if(!active)
DropFuel()
. = TRUE
if("lower_power")
if(power_output > 1)
power_output--
. = TRUE
if("higher_power")
if(power_output < max_power_output || (emagged && power_output < round(max_power_output * 2.5)))
power_output++
. = TRUE
/obj/machinery/power/port_gen/pacman/super
name = "S.U.P.E.R.P.A.C.M.A.N.-type Portable Generator"
desc = "A power generator that utilizes uranium sheets as fuel. Can run for much longer than the standard PACMAN type generators. Rated for 80 kW max safe output."
icon_state = "portgen1"
sheet_path = /obj/item/stack/material/uranium
sheet_name = "Uranium Sheets"
time_per_sheet = 576 //same power output, but a 50 sheet stack will last 2 hours at max safe power
circuit = /obj/item/weapon/circuitboard/pacman/super
/obj/machinery/power/port_gen/pacman/super/UseFuel()
//produces a tiny amount of radiation when in use
if (prob(2*power_output))
SSradiation.radiate(src, 4)
..()
/obj/machinery/power/port_gen/pacman/super/explode()
//a nice burst of radiation
var/rads = 50 + (sheets + sheet_left)*1.5
SSradiation.radiate(src, (max(20, rads)))
explosion(src.loc, 3, 3, 5, 3)
qdel(src)
/obj/machinery/power/port_gen/pacman/mrs
name = "M.R.S.P.A.C.M.A.N.-type Portable Generator"
desc = "An advanced power generator that runs on tritium. Rated for 200 kW maximum safe output!"
icon_state = "portgen2"
sheet_path = /obj/item/stack/material/tritium
sheet_name = "Tritium Fuel Sheets"
//I don't think tritium has any other use, so we might as well make this rewarding for players
//max safe power output (power level = 8) is 200 kW and lasts for 1 hour - 3 or 4 of these could power the station
power_gen = 25000 //watts
max_power_output = 10
max_safe_output = 8
time_per_sheet = 576
max_temperature = 800
temperature_gain = 90
circuit = /obj/item/weapon/circuitboard/pacman/mrs
/obj/machinery/power/port_gen/pacman/mrs/explode()
//no special effects, but the explosion is pretty big (same as a supermatter shard).
explosion(src.loc, 3, 6, 12, 16, 1)
qdel(src)
+343 -343
View File
@@ -1,343 +1,343 @@
//////////////////////////////
// POWER MACHINERY BASE CLASS
//////////////////////////////
/////////////////////////////
// Definitions
/////////////////////////////
/obj/machinery/power
name = null
icon = 'icons/obj/power.dmi'
anchored = TRUE
var/datum/powernet/powernet = null
use_power = USE_POWER_OFF
idle_power_usage = 0
active_power_usage = 0
/obj/machinery/power/Destroy()
disconnect_from_network()
return ..()
///////////////////////////////
// General procedures
//////////////////////////////
// common helper procs for all power machines
/obj/machinery/power/drain_power(var/drain_check, var/surge, var/amount = 0)
if(drain_check)
return 1
if(powernet && powernet.avail)
powernet.trigger_warning()
return powernet.draw_power(amount)
/obj/machinery/power/proc/add_avail(var/amount)
if(powernet)
powernet.newavail += amount
return TRUE
return FALSE
/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.avail-powernet.load
else
return 0
/obj/machinery/power/proc/avail()
if(powernet)
return powernet.avail
else
return 0
/obj/machinery/power/proc/viewload()
if(powernet)
return powernet.viewload
else
return 0
/obj/machinery/power/proc/disconnect_terminal(var/obj/machinery/power/terminal/term) // machines without a terminal will just return, no harm no fowl.
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
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
// 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.is_plating() || !istype(T, /turf/simulated/floor))
return
if(get_dist(src, user) > 1)
return
coil.turf_place(T, user)
return
else
..()
return
// Power machinery should also connect/disconnect from the network.
/obj/machinery/power/default_unfasten_wrench(var/mob/user, var/obj/item/weapon/W, var/time = 20)
if((. = ..()))
if(anchored)
connect_to_network()
else
disconnect_from_network()
// Used for power spikes by the engine, has specific effects on different machines.
/obj/machinery/power/proc/overload(var/obj/machinery/power/source)
return
// Used by the grid checker upon receiving a power spike.
/obj/machinery/power/proc/do_grid_check()
return
/obj/machinery/power/proc/power_spike()
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, var/cable_only = 0)
. = list()
var/reverse = d ? reverse_dir[d] : 0
for(var/AM in T)
if(AM == source) continue //we don't want to return source
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)
if(C.d1 == d || C.d2 == d || C.d1 == reverse || C.d2 == reverse )
. += C
return .
//remove the old powernet and replace it with a new one throughout the network.
/proc/propagate_network(var/obj/O, var/datum/powernet/PN)
//to_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
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)
if(!net2) return net1
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
//power_source is a source of electricity, can be powercell, area, apc, cable, powernet or null
//source is an object caused electrocuting (airlock, grille, etc)
//No animations will be performed by this proc.
/proc/electrocute_mob(mob/living/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
if(issilicon(M)) return 0 //No more robot shocks from machinery
var/area/source_area
if(istype(power_source,/area))
source_area = power_source
power_source = source_area.get_apc()
if(istype(power_source,/obj/structure/cable))
var/obj/structure/cable/Cable = power_source
power_source = Cable.powernet
var/datum/powernet/PN
var/obj/item/weapon/cell/cell
if(istype(power_source,/datum/powernet))
PN = power_source
else if(istype(power_source,/obj/item/weapon/cell))
cell = power_source
else if(istype(power_source,/obj/machinery/power/apc))
var/obj/machinery/power/apc/apc = power_source
cell = apc.cell
if (apc.terminal)
PN = apc.terminal.powernet
else if (!power_source)
return 0
else
log_admin("ERROR: /proc/electrocute_mob([M], [power_source], [source]): wrong power_source")
return 0
//Triggers powernet warning, but only for 5 ticks (if applicable)
//If following checks determine user is protected we won't alarm for long.
if(PN)
PN.trigger_warning(5)
if(istype(M,/mob/living/carbon/human))
var/mob/living/carbon/human/H = M
if(H.species.siemens_coefficient <= 0)
return
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
//Checks again. If we are still here subject will be shocked, trigger standard 20 tick warning
//Since this one is longer it will override the original one.
if(PN)
PN.trigger_warning()
if (!cell && !PN)
return 0
var/PN_damage = 0
var/cell_damage = 0
if (PN)
PN_damage = PN.get_electrocute_damage()
if (cell)
cell_damage = cell.get_electrocute_damage()
var/shock_damage = 0
if (PN_damage>=cell_damage)
power_source = PN
shock_damage = PN_damage
else
power_source = cell
shock_damage = cell_damage
var/drained_hp = M.electrocute_act(shock_damage, source, siemens_coeff) //zzzzzzap!
var/drained_energy = drained_hp*20
if (source_area)
source_area.use_power_oneoff(drained_energy/CELLRATE, EQUIP)
else if (istype(power_source,/datum/powernet))
var/drained_power = drained_energy/CELLRATE
drained_power = PN.draw_power(drained_power)
else if (istype(power_source, /obj/item/weapon/cell))
cell.use(drained_energy)
return drained_energy
//////////////////////////////
// POWER MACHINERY BASE CLASS
//////////////////////////////
/////////////////////////////
// Definitions
/////////////////////////////
/obj/machinery/power
name = null
icon = 'icons/obj/power.dmi'
anchored = TRUE
var/datum/powernet/powernet = null
use_power = USE_POWER_OFF
idle_power_usage = 0
active_power_usage = 0
/obj/machinery/power/Destroy()
disconnect_from_network()
return ..()
///////////////////////////////
// General procedures
//////////////////////////////
// common helper procs for all power machines
/obj/machinery/power/drain_power(var/drain_check, var/surge, var/amount = 0)
if(drain_check)
return 1
if(powernet && powernet.avail)
powernet.trigger_warning()
return powernet.draw_power(amount)
/obj/machinery/power/proc/add_avail(var/amount)
if(powernet)
powernet.newavail += amount
return TRUE
return FALSE
/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.avail-powernet.load
else
return 0
/obj/machinery/power/proc/avail()
if(powernet)
return powernet.avail
else
return 0
/obj/machinery/power/proc/viewload()
if(powernet)
return powernet.viewload
else
return 0
/obj/machinery/power/proc/disconnect_terminal(var/obj/machinery/power/terminal/term) // machines without a terminal will just return, no harm no fowl.
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
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
// 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.is_plating() || !istype(T, /turf/simulated/floor))
return
if(get_dist(src, user) > 1)
return
coil.turf_place(T, user)
return
else
..()
return
// Power machinery should also connect/disconnect from the network.
/obj/machinery/power/default_unfasten_wrench(var/mob/user, var/obj/item/weapon/W, var/time = 20)
if((. = ..()))
if(anchored)
connect_to_network()
else
disconnect_from_network()
// Used for power spikes by the engine, has specific effects on different machines.
/obj/machinery/power/proc/overload(var/obj/machinery/power/source)
return
// Used by the grid checker upon receiving a power spike.
/obj/machinery/power/proc/do_grid_check()
return
/obj/machinery/power/proc/power_spike()
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, var/cable_only = 0)
. = list()
var/reverse = d ? reverse_dir[d] : 0
for(var/AM in T)
if(AM == source) continue //we don't want to return source
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)
if(C.d1 == d || C.d2 == d || C.d1 == reverse || C.d2 == reverse )
. += C
return .
//remove the old powernet and replace it with a new one throughout the network.
/proc/propagate_network(var/obj/O, var/datum/powernet/PN)
//to_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
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)
if(!net2) return net1
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
//power_source is a source of electricity, can be powercell, area, apc, cable, powernet or null
//source is an object caused electrocuting (airlock, grille, etc)
//No animations will be performed by this proc.
/proc/electrocute_mob(mob/living/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
if(issilicon(M)) return 0 //No more robot shocks from machinery
var/area/source_area
if(istype(power_source,/area))
source_area = power_source
power_source = source_area.get_apc()
if(istype(power_source,/obj/structure/cable))
var/obj/structure/cable/Cable = power_source
power_source = Cable.powernet
var/datum/powernet/PN
var/obj/item/weapon/cell/cell
if(istype(power_source,/datum/powernet))
PN = power_source
else if(istype(power_source,/obj/item/weapon/cell))
cell = power_source
else if(istype(power_source,/obj/machinery/power/apc))
var/obj/machinery/power/apc/apc = power_source
cell = apc.cell
if (apc.terminal)
PN = apc.terminal.powernet
else if (!power_source)
return 0
else
log_admin("ERROR: /proc/electrocute_mob([M], [power_source], [source]): wrong power_source")
return 0
//Triggers powernet warning, but only for 5 ticks (if applicable)
//If following checks determine user is protected we won't alarm for long.
if(PN)
PN.trigger_warning(5)
if(istype(M,/mob/living/carbon/human))
var/mob/living/carbon/human/H = M
if(H.species.siemens_coefficient <= 0)
return
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
//Checks again. If we are still here subject will be shocked, trigger standard 20 tick warning
//Since this one is longer it will override the original one.
if(PN)
PN.trigger_warning()
if (!cell && !PN)
return 0
var/PN_damage = 0
var/cell_damage = 0
if (PN)
PN_damage = PN.get_electrocute_damage()
if (cell)
cell_damage = cell.get_electrocute_damage()
var/shock_damage = 0
if (PN_damage>=cell_damage)
power_source = PN
shock_damage = PN_damage
else
power_source = cell
shock_damage = cell_damage
var/drained_hp = M.electrocute_act(shock_damage, source, siemens_coeff) //zzzzzzap!
var/drained_energy = drained_hp*20
if (source_area)
source_area.use_power_oneoff(drained_energy/CELLRATE, EQUIP)
else if (istype(power_source,/datum/powernet))
var/drained_power = drained_energy/CELLRATE
drained_power = PN.draw_power(drained_power)
else if (istype(power_source, /obj/item/weapon/cell))
cell.use(drained_energy)
return drained_energy
+125 -125
View File
@@ -1,125 +1,125 @@
#define I_SINGULO "singulo"
/atom/proc/singularity_act()
return
/atom/proc/singularity_pull(S, current_size)
return
/mob/living/singularity_act()
investigate_log("has been consumed by a singularity", I_SINGULO)
gib()
return 20
/mob/living/singularity_pull(S, current_size)
step_towards(src, S)
apply_effect(current_size * 3, IRRADIATE, blocked = getarmor(null, "rad"))
/mob/living/carbon/human/singularity_act()
var/gain = 20
if(mind)
if((mind.assigned_role == "Engineer") || (mind.assigned_role == "Chief Engineer"))
gain = 100
if(mind.assigned_role == USELESS_JOB) //VOREStation Edit - Visitor not Assistant
gain = rand(0, 300)
investigate_log(I_SINGULO,"has been consumed by a singularity", I_SINGULO)
gib()
return gain
/mob/living/carbon/human/singularity_pull(S, current_size)
if(current_size >= STAGE_THREE)
var/list/handlist = list(l_hand, r_hand)
for(var/obj/item/hand in handlist)
if(prob(current_size*5) && hand.w_class >= ((11-current_size)/2) && unEquip(hand))
step_towards(hand, S)
to_chat(src, "<span class = 'warning'>The [S] pulls \the [hand] from your grip!</span>")
if(!lying && (!shoes || !(shoes.item_flags & NOSLIP)) && (!species || !(species.flags & NOSLIP)) && prob(current_size*5))
to_chat(src, "<span class='danger'>A strong gravitational force slams you to the ground!</span>")
Weaken(current_size)
..()
/obj/singularity_act()
if(simulated)
ex_act(1)
if(src)
qdel(src)
return 2
/obj/singularity_pull(S, current_size)
set waitfor = 0
if(anchored)
return
sleep(0) //this is needed or multiple items will be thrown sequentially and not simultaneously
if(current_size >= STAGE_FOUR)
step_towards(src,S)
sleep(1)
step_towards(src,S)
else if(current_size > STAGE_ONE)
step_towards(src,S)
else ..()
/obj/effect/beam/singularity_pull()
return
/obj/effect/overlay/singularity_pull()
return
/obj/machinery/power/supermatter/shard/singularity_act()
qdel(src)
return 5000
/obj/machinery/power/supermatter/singularity_act()
if(!src.loc)
return
var/prints = ""
if(src.fingerprintshidden)
prints = ", all touchers : " + src.fingerprintshidden
SetUniversalState(/datum/universal_state/supermatter_cascade)
log_admin("New super singularity made by eating a SM crystal [prints]. Last touched by [src.fingerprintslast].")
message_admins("New super singularity made by eating a SM crystal [prints]. Last touched by [src.fingerprintslast].")
qdel(src)
return 50000
/obj/item/projectile/beam/emitter/singularity_pull()
return
/obj/effect/projectile/emitter/singularity_pull()
return
/obj/item/weapon/storage/backpack/holding/singularity_act(S, current_size)
var/dist = max((current_size - 2), 1)
explosion(src.loc,(dist),(dist*2),(dist*4))
return 1000
/turf/singularity_act(S, current_size)
if(!is_plating())
for(var/obj/O in contents)
if(O.level != 1)
continue
if(O.invisibility == 101)
O.singularity_act(src, current_size)
ChangeTurf(get_base_turf_by_area(src))
return 2
/turf/space/singularity_act()
return
/turf/simulated/open/singularity_act()
return
/*******************
* Nar-Sie Act/Pull *
*******************/
/atom/proc/singuloCanEat()
return 1
/mob/observer/singuloCanEat()
return 0
/mob/new_player/singuloCanEat()
return 0
#define I_SINGULO "singulo"
/atom/proc/singularity_act()
return
/atom/proc/singularity_pull(S, current_size)
return
/mob/living/singularity_act()
investigate_log("has been consumed by a singularity", I_SINGULO)
gib()
return 20
/mob/living/singularity_pull(S, current_size)
step_towards(src, S)
apply_effect(current_size * 3, IRRADIATE, blocked = getarmor(null, "rad"))
/mob/living/carbon/human/singularity_act()
var/gain = 20
if(mind)
if((mind.assigned_role == "Engineer") || (mind.assigned_role == "Chief Engineer"))
gain = 100
if(mind.assigned_role == USELESS_JOB) //VOREStation Edit - Visitor not Assistant
gain = rand(0, 300)
investigate_log(I_SINGULO,"has been consumed by a singularity", I_SINGULO)
gib()
return gain
/mob/living/carbon/human/singularity_pull(S, current_size)
if(current_size >= STAGE_THREE)
var/list/handlist = list(l_hand, r_hand)
for(var/obj/item/hand in handlist)
if(prob(current_size*5) && hand.w_class >= ((11-current_size)/2) && unEquip(hand))
step_towards(hand, S)
to_chat(src, "<span class = 'warning'>The [S] pulls \the [hand] from your grip!</span>")
if(!lying && (!shoes || !(shoes.item_flags & NOSLIP)) && (!species || !(species.flags & NOSLIP)) && prob(current_size*5))
to_chat(src, "<span class='danger'>A strong gravitational force slams you to the ground!</span>")
Weaken(current_size)
..()
/obj/singularity_act()
if(simulated)
ex_act(1)
if(src)
qdel(src)
return 2
/obj/singularity_pull(S, current_size)
set waitfor = 0
if(anchored)
return
sleep(0) //this is needed or multiple items will be thrown sequentially and not simultaneously
if(current_size >= STAGE_FOUR)
step_towards(src,S)
sleep(1)
step_towards(src,S)
else if(current_size > STAGE_ONE)
step_towards(src,S)
else ..()
/obj/effect/beam/singularity_pull()
return
/obj/effect/overlay/singularity_pull()
return
/obj/machinery/power/supermatter/shard/singularity_act()
qdel(src)
return 5000
/obj/machinery/power/supermatter/singularity_act()
if(!src.loc)
return
var/prints = ""
if(src.fingerprintshidden)
prints = ", all touchers : " + src.fingerprintshidden
SetUniversalState(/datum/universal_state/supermatter_cascade)
log_admin("New super singularity made by eating a SM crystal [prints]. Last touched by [src.fingerprintslast].")
message_admins("New super singularity made by eating a SM crystal [prints]. Last touched by [src.fingerprintslast].")
qdel(src)
return 50000
/obj/item/projectile/beam/emitter/singularity_pull()
return
/obj/effect/projectile/emitter/singularity_pull()
return
/obj/item/weapon/storage/backpack/holding/singularity_act(S, current_size)
var/dist = max((current_size - 2), 1)
explosion(src.loc,(dist),(dist*2),(dist*4))
return 1000
/turf/singularity_act(S, current_size)
if(!is_plating())
for(var/obj/O in contents)
if(O.level != 1)
continue
if(O.invisibility == 101)
O.singularity_act(src, current_size)
ChangeTurf(get_base_turf_by_area(src))
return 2
/turf/space/singularity_act()
return
/turf/simulated/open/singularity_act()
return
/*******************
* Nar-Sie Act/Pull *
*******************/
/atom/proc/singuloCanEat()
return 1
/mob/observer/singuloCanEat()
return 0
/mob/new_player/singuloCanEat()
return 0
+159 -159
View File
@@ -1,159 +1,159 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33
var/global/list/rad_collectors = list()
/obj/machinery/power/rad_collector
name = "Radiation Collector Array"
desc = "A device which uses Hawking Radiation and phoron to produce power."
icon = 'icons/obj/singularity.dmi'
icon_state = "ca"
anchored = FALSE
density = TRUE
req_access = list(access_engine_equip)
// use_power = 0
var/obj/item/weapon/tank/phoron/P = null
var/last_power = 0
var/last_power_new = 0
var/active = 0
var/locked = 0
var/drainratio = 1
/obj/machinery/power/rad_collector/New()
..()
rad_collectors += src
/obj/machinery/power/rad_collector/Destroy()
rad_collectors -= src
return ..()
/obj/machinery/power/rad_collector/process()
//so that we don't zero out the meter if the SM is processed first.
last_power = last_power_new
last_power_new = 0
if(P && active)
var/rads = SSradiation.get_rads_at_turf(get_turf(src))
if(rads)
receive_pulse(rads * 5) //Maths is hard
if(P)
if(P.air_contents.gas["phoron"] == 0)
investigate_log("<font color='red'>out of fuel</font>.","singulo")
eject()
else
P.air_contents.adjust_gas("phoron", -0.001*drainratio)
return
/obj/machinery/power/rad_collector/attack_hand(mob/user as mob)
if(anchored)
if(!src.locked)
toggle_power()
user.visible_message("[user.name] turns the [src.name] [active? "on":"off"].", \
"You turn the [src.name] [active? "on":"off"].")
investigate_log("turned [active?"<font color='green'>on</font>":"<font color='red'>off</font>"] by [user.key]. [P?"Fuel: [round(P.air_contents.gas["phoron"]/0.29)]%":"<font color='red'>It is empty</font>"].","singulo")
return
else
to_chat(user, span_red("The controls are locked!"))
return
/obj/machinery/power/rad_collector/attackby(obj/item/W, mob/user)
if(istype(W, /obj/item/weapon/tank/phoron))
if(!src.anchored)
to_chat(user, span_red("The [src] needs to be secured to the floor first."))
return 1
if(src.P)
to_chat(user, span_red("There's already a phoron tank loaded."))
return 1
user.drop_item()
src.P = W
W.loc = src
update_icons()
return 1
else if(W.has_tool_quality(TOOL_CROWBAR))
if(P && !src.locked)
eject()
return 1
else if(W.has_tool_quality(TOOL_WRENCH))
if(P)
to_chat(user, span_blue("Remove the phoron tank first."))
return 1
playsound(src, W.usesound, 75, 1)
src.anchored = !src.anchored
user.visible_message("[user.name] [anchored? "secures":"unsecures"] the [src.name].", \
"You [anchored? "secure":"undo"] the external bolts.", \
"You hear a ratchet.")
if(anchored)
connect_to_network()
else
disconnect_from_network()
return 1
else if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda))
if (src.allowed(user))
if(active)
src.locked = !src.locked
to_chat(user, "The controls are now [src.locked ? "locked." : "unlocked."]")
else
src.locked = 0 //just in case it somehow gets locked
to_chat(user, span_red("The controls can only be locked when the [src] is active."))
else
to_chat(user, span_red("Access denied!"))
return 1
return ..()
/obj/machinery/power/rad_collector/examine(mob/user)
. = ..()
if(get_dist(user, src) <= 3)
. += "The meter indicates that it is collecting [last_power] W."
/obj/machinery/power/rad_collector/ex_act(severity)
switch(severity)
if(2, 3)
eject()
return ..()
/obj/machinery/power/rad_collector/proc/eject()
locked = 0
var/obj/item/weapon/tank/phoron/Z = src.P
if (!Z)
return
Z.loc = get_turf(src)
Z.layer = initial(Z.layer)
src.P = null
if(active)
toggle_power()
else
update_icons()
/obj/machinery/power/rad_collector/proc/receive_pulse(var/pulse_strength)
if(P && active)
var/power_produced = 0
power_produced = P.air_contents.gas["phoron"]*pulse_strength*20
add_avail(power_produced)
last_power_new = power_produced
return
return
/obj/machinery/power/rad_collector/proc/update_icons()
cut_overlays()
if(P)
add_overlay("ptank")
if(stat & (NOPOWER|BROKEN))
return
if(active)
add_overlay("on")
/obj/machinery/power/rad_collector/proc/toggle_power()
active = !active
if(active)
icon_state = "ca_on"
flick("ca_active", src)
else
icon_state = "ca"
flick("ca_deactive", src)
update_icons()
return
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33
var/global/list/rad_collectors = list()
/obj/machinery/power/rad_collector
name = "Radiation Collector Array"
desc = "A device which uses Hawking Radiation and phoron to produce power."
icon = 'icons/obj/singularity.dmi'
icon_state = "ca"
anchored = FALSE
density = TRUE
req_access = list(access_engine_equip)
// use_power = 0
var/obj/item/weapon/tank/phoron/P = null
var/last_power = 0
var/last_power_new = 0
var/active = 0
var/locked = 0
var/drainratio = 1
/obj/machinery/power/rad_collector/New()
..()
rad_collectors += src
/obj/machinery/power/rad_collector/Destroy()
rad_collectors -= src
return ..()
/obj/machinery/power/rad_collector/process()
//so that we don't zero out the meter if the SM is processed first.
last_power = last_power_new
last_power_new = 0
if(P && active)
var/rads = SSradiation.get_rads_at_turf(get_turf(src))
if(rads)
receive_pulse(rads * 5) //Maths is hard
if(P)
if(P.air_contents.gas["phoron"] == 0)
investigate_log("<font color='red'>out of fuel</font>.","singulo")
eject()
else
P.air_contents.adjust_gas("phoron", -0.001*drainratio)
return
/obj/machinery/power/rad_collector/attack_hand(mob/user as mob)
if(anchored)
if(!src.locked)
toggle_power()
user.visible_message("[user.name] turns the [src.name] [active? "on":"off"].", \
"You turn the [src.name] [active? "on":"off"].")
investigate_log("turned [active?"<font color='green'>on</font>":"<font color='red'>off</font>"] by [user.key]. [P?"Fuel: [round(P.air_contents.gas["phoron"]/0.29)]%":"<font color='red'>It is empty</font>"].","singulo")
return
else
to_chat(user, span_red("The controls are locked!"))
return
/obj/machinery/power/rad_collector/attackby(obj/item/W, mob/user)
if(istype(W, /obj/item/weapon/tank/phoron))
if(!src.anchored)
to_chat(user, span_red("The [src] needs to be secured to the floor first."))
return 1
if(src.P)
to_chat(user, span_red("There's already a phoron tank loaded."))
return 1
user.drop_item()
src.P = W
W.loc = src
update_icons()
return 1
else if(W.has_tool_quality(TOOL_CROWBAR))
if(P && !src.locked)
eject()
return 1
else if(W.has_tool_quality(TOOL_WRENCH))
if(P)
to_chat(user, span_blue("Remove the phoron tank first."))
return 1
playsound(src, W.usesound, 75, 1)
src.anchored = !src.anchored
user.visible_message("[user.name] [anchored? "secures":"unsecures"] the [src.name].", \
"You [anchored? "secure":"undo"] the external bolts.", \
"You hear a ratchet.")
if(anchored)
connect_to_network()
else
disconnect_from_network()
return 1
else if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda))
if (src.allowed(user))
if(active)
src.locked = !src.locked
to_chat(user, "The controls are now [src.locked ? "locked." : "unlocked."]")
else
src.locked = 0 //just in case it somehow gets locked
to_chat(user, span_red("The controls can only be locked when the [src] is active."))
else
to_chat(user, span_red("Access denied!"))
return 1
return ..()
/obj/machinery/power/rad_collector/examine(mob/user)
. = ..()
if(get_dist(user, src) <= 3)
. += "The meter indicates that it is collecting [last_power] W."
/obj/machinery/power/rad_collector/ex_act(severity)
switch(severity)
if(2, 3)
eject()
return ..()
/obj/machinery/power/rad_collector/proc/eject()
locked = 0
var/obj/item/weapon/tank/phoron/Z = src.P
if (!Z)
return
Z.loc = get_turf(src)
Z.layer = initial(Z.layer)
src.P = null
if(active)
toggle_power()
else
update_icons()
/obj/machinery/power/rad_collector/proc/receive_pulse(var/pulse_strength)
if(P && active)
var/power_produced = 0
power_produced = P.air_contents.gas["phoron"]*pulse_strength*20
add_avail(power_produced)
last_power_new = power_produced
return
return
/obj/machinery/power/rad_collector/proc/update_icons()
cut_overlays()
if(P)
add_overlay("ptank")
if(stat & (NOPOWER|BROKEN))
return
if(active)
add_overlay("on")
/obj/machinery/power/rad_collector/proc/toggle_power()
active = !active
if(active)
icon_state = "ca_on"
flick("ca_active", src)
else
icon_state = "ca"
flick("ca_deactive", src)
update_icons()
return
@@ -1,88 +1,88 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33
/obj/machinery/containment_field
name = "Containment Field"
desc = "An energy field."
icon = 'icons/obj/machines/field_generator.dmi'
icon_state = "Contain_F"
anchored = TRUE
density = FALSE
unacidable = TRUE
use_power = USE_POWER_OFF
light_on = TRUE
light_range = 2
light_power = 0.5
light_color = "#5BA8FF"
var/obj/machinery/field_generator/FG1 = null
var/obj/machinery/field_generator/FG2 = null
var/list/shockdirs
var/hasShocked = 0 //Used to add a delay between shocks. In some cases this used to crash servers by spawning hundreds of sparks every second.
/obj/machinery/containment_field/Initialize()
. = ..()
shockdirs = list(turn(dir,90),turn(dir,-90))
sense_proximity(callback = /atom/proc/HasProximity)
/obj/machinery/containment_field/set_dir(new_dir)
. = ..()
if(.)
shockdirs = list(turn(dir,90),turn(dir,-90))
/obj/machinery/containment_field/Destroy()
unsense_proximity(callback = /atom/proc/HasProximity)
if(FG1 && !FG1.clean_up)
FG1.cleanup()
if(FG2 && !FG2.clean_up)
FG2.cleanup()
. = ..()
/obj/machinery/containment_field/attack_hand(mob/user as mob)
if(get_dist(src, user) > 1)
return 0
else
shock(user)
return 1
/obj/machinery/containment_field/ex_act(severity)
return 0
/obj/machinery/containment_field/Crossed(mob/living/L)
if(!istype(L) || L.incorporeal_move)
return
shock(L)
/obj/machinery/containment_field/HasProximity(turf/T, atom/movable/AM, old_loc)
if(!istype(AM, /mob/living) || AM:incorporeal_move)
return 0
if(!(get_dir(src,AM) in shockdirs))
return 0
if(issilicon(AM) ? prob(40) : prob(50))
shock(AM)
return 1
return 0
/obj/machinery/containment_field/shock(mob/living/user as mob)
if(hasShocked)
return 0
if(!FG1 || !FG2)
qdel(src)
return 0
if(isliving(user))
hasShocked = 1
var/shock_damage = min(rand(30,40),rand(30,40))
user.electrocute_act(shock_damage, src, 1, BP_TORSO)
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
/obj/machinery/containment_field/proc/set_master(var/master1,var/master2)
if(!master1 || !master2)
return 0
FG1 = master1
FG2 = master2
return 1
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33
/obj/machinery/containment_field
name = "Containment Field"
desc = "An energy field."
icon = 'icons/obj/machines/field_generator.dmi'
icon_state = "Contain_F"
anchored = TRUE
density = FALSE
unacidable = TRUE
use_power = USE_POWER_OFF
light_on = TRUE
light_range = 2
light_power = 0.5
light_color = "#5BA8FF"
var/obj/machinery/field_generator/FG1 = null
var/obj/machinery/field_generator/FG2 = null
var/list/shockdirs
var/hasShocked = 0 //Used to add a delay between shocks. In some cases this used to crash servers by spawning hundreds of sparks every second.
/obj/machinery/containment_field/Initialize()
. = ..()
shockdirs = list(turn(dir,90),turn(dir,-90))
sense_proximity(callback = /atom/proc/HasProximity)
/obj/machinery/containment_field/set_dir(new_dir)
. = ..()
if(.)
shockdirs = list(turn(dir,90),turn(dir,-90))
/obj/machinery/containment_field/Destroy()
unsense_proximity(callback = /atom/proc/HasProximity)
if(FG1 && !FG1.clean_up)
FG1.cleanup()
if(FG2 && !FG2.clean_up)
FG2.cleanup()
. = ..()
/obj/machinery/containment_field/attack_hand(mob/user as mob)
if(get_dist(src, user) > 1)
return 0
else
shock(user)
return 1
/obj/machinery/containment_field/ex_act(severity)
return 0
/obj/machinery/containment_field/Crossed(mob/living/L)
if(!istype(L) || L.incorporeal_move)
return
shock(L)
/obj/machinery/containment_field/HasProximity(turf/T, atom/movable/AM, old_loc)
if(!istype(AM, /mob/living) || AM:incorporeal_move)
return 0
if(!(get_dir(src,AM) in shockdirs))
return 0
if(issilicon(AM) ? prob(40) : prob(50))
shock(AM)
return 1
return 0
/obj/machinery/containment_field/shock(mob/living/user as mob)
if(hasShocked)
return 0
if(!FG1 || !FG2)
qdel(src)
return 0
if(isliving(user))
hasShocked = 1
var/shock_damage = min(rand(30,40),rand(30,40))
user.electrocute_act(shock_damage, src, 1, BP_TORSO)
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
/obj/machinery/containment_field/proc/set_master(var/master1,var/master2)
if(!master1 || !master2)
return 0
FG1 = master1
FG2 = master2
return 1
+312 -312
View File
@@ -1,312 +1,312 @@
#define EMITTER_DAMAGE_POWER_TRANSFER 450 //used to transfer power to containment field generators
/obj/machinery/power/emitter
name = "emitter"
desc = "It is a heavy duty industrial laser."
icon = 'icons/obj/singularity.dmi'
icon_state = "emitter"
anchored = FALSE
density = TRUE
unacidable = TRUE
req_access = list(access_engine_equip)
var/id = null
use_power = USE_POWER_OFF //uses powernet power, not APC power
active_power_usage = 30000 //30 kW laser. I guess that means 30 kJ per shot.
var/active = 0
var/powered = 0
var/fire_delay = 100
var/max_burst_delay = 100
var/min_burst_delay = 20
var/burst_shots = 3
var/last_shot = 0
var/shot_number = 0
var/state = 0
var/locked = 0
var/burst_delay = 2
var/initial_fire_delay = 100
var/integrity = 80
/obj/machinery/power/emitter/verb/rotate_clockwise()
set name = "Rotate Emitter Clockwise"
set category = "Object"
set src in oview(1)
if (src.anchored || usr:stat)
to_chat(usr, "It is fastened to the floor!")
return 0
src.set_dir(turn(src.dir, 270))
return 1
/obj/machinery/power/emitter/verb/rotate_counterclockwise()
set name = "Rotate Emitter Counter-Clockwise"
set category = "Object"
set src in oview(1)
if (src.anchored || usr:stat)
to_chat(usr, "It is fastened to the floor!")
return 0
src.set_dir(turn(src.dir, 90))
return 1
/obj/machinery/power/emitter/Initialize()
. = ..()
if(state == 2 && anchored)
connect_to_network()
/obj/machinery/power/emitter/Destroy()
message_admins("Emitter deleted at ([x],[y],[z] - <A HREF='?_src_=holder;[HrefToken()];adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)",0,1)
log_game("EMITTER([x],[y],[z]) Destroyed/deleted.")
investigate_log("<font color='red'>deleted</font> at ([x],[y],[z])","singulo")
..()
/obj/machinery/power/emitter/update_icon()
if (active && powernet && avail(active_power_usage))
icon_state = "emitter_+a"
else
icon_state = "emitter"
/obj/machinery/power/emitter/attack_hand(mob/user as mob)
src.add_fingerprint(user)
activate(user)
/obj/machinery/power/emitter/proc/activate(mob/user as mob)
if(state == 2)
if(!powernet)
to_chat(user, "\The [src] isn't connected to a wire.")
return 1
if(!src.locked)
if(src.active==1)
src.active = 0
to_chat(user, "You turn off [src].")
message_admins("Emitter turned off by [key_name(user, user.client)](<A HREF='?_src_=holder;[HrefToken()];adminmoreinfo=\ref[user]'>?</A>) in ([x],[y],[z] - <A HREF='?_src_=holder;[HrefToken()];adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)",0,1)
log_game("EMITTER([x],[y],[z]) OFF by [key_name(user)]")
investigate_log("turned <font color='red'>off</font> by [user.key]","singulo")
else
src.active = 1
to_chat(user, "You turn on [src].")
src.shot_number = 0
src.fire_delay = get_initial_fire_delay()
message_admins("Emitter turned on by [key_name(user, user.client)](<A HREF='?_src_=holder;[HrefToken()];adminmoreinfo=\ref[user]'>?</A>) in ([x],[y],[z] - <A HREF='?_src_=holder;[HrefToken()];adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)",0,1)
log_game("EMITTER([x],[y],[z]) ON by [key_name(user)]")
investigate_log("turned <font color='green'>on</font> by [user.key]","singulo")
update_icon()
else
to_chat(user, "<span class='warning'>The controls are locked!</span>")
else
to_chat(user, "<span class='warning'>\The [src] needs to be firmly secured to the floor first.</span>")
return 1
/obj/machinery/power/emitter/emp_act(var/severity)//Emitters are hardened but still might have issues
// add_load(1000)
/* if((severity == 1)&&prob(1)&&prob(1))
if(src.active)
src.active = 0
src.use_power = 1 */
return 1
/obj/machinery/power/emitter/process()
if(stat & (BROKEN))
return
if(src.state != 2 || (!powernet && active_power_usage))
src.active = 0
update_icon()
return
if(((src.last_shot + src.fire_delay) <= world.time) && (src.active == 1))
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()
log_game("EMITTER([x],[y],[z]) Regained power and is ON.")
investigate_log("regained power and turned <font color='green'>on</font>","singulo")
else
if(powered)
powered = 0
update_icon()
log_game("EMITTER([x],[y],[z]) Lost power and was ON.")
investigate_log("lost power and turned <font color='red'>off</font>","singulo")
return
src.last_shot = world.time
if(src.shot_number < burst_shots)
src.fire_delay = get_burst_delay() //R-UST port
src.shot_number ++
else
src.fire_delay = get_rand_burst_delay() //R-UST port
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
playsound(src, 'sound/weapons/emitter.ogg', 25, 1)
if(prob(35))
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
var/obj/item/projectile/beam/emitter/A = get_emitter_beam()
A.damage = round(power_per_shot/EMITTER_DAMAGE_POWER_TRANSFER)
A.firer = src
A.fire(dir2angle(dir))
/obj/machinery/power/emitter/attackby(obj/item/W, mob/user)
if(W.has_tool_quality(TOOL_WRENCH))
if(active)
to_chat(user, "Turn off [src] first.")
return
switch(state)
if(0)
state = 1
playsound(src, W.usesound, 75, 1)
user.visible_message("[user.name] secures [src] to the floor.", \
"You secure the external reinforcing bolts to the floor.", \
"You hear a ratchet.")
src.anchored = TRUE
if(1)
state = 0
playsound(src, W.usesound, 75, 1)
user.visible_message("[user.name] unsecures [src] reinforcing bolts from the floor.", \
"You undo the external reinforcing bolts.", \
"You hear a ratchet.")
src.anchored = FALSE
disconnect_from_network()
if(2)
to_chat(user, "<span class='warning'>\The [src] needs to be unwelded from the floor.</span>")
update_icon() // VOREStation Add
return
if(W.has_tool_quality(TOOL_WELDER))
var/obj/item/weapon/weldingtool/WT = W.get_welder()
if(active)
to_chat(user, "Turn off [src] first.")
return
switch(state)
if(0)
to_chat(user, "<span class='warning'>\The [src] needs to be wrenched to the floor.</span>")
if(1)
if (WT.remove_fuel(0,user))
playsound(src, WT.usesound, 50, 1)
user.visible_message("[user.name] starts to weld [src] to the floor.", \
"You start to weld [src] to the floor.", \
"You hear welding")
if (do_after(user,20 * WT.toolspeed))
if(!src || !WT.isOn()) return
state = 2
to_chat(user, "You weld [src] to the floor.")
connect_to_network()
else
to_chat(user, "<span class='warning'>You need more welding fuel to complete this task.</span>")
if(2)
if (WT.remove_fuel(0,user))
playsound(src, WT.usesound, 50, 1)
user.visible_message("[user.name] starts to cut [src] free from the floor.", \
"You start to cut [src] free from the floor.", \
"You hear welding")
if (do_after(user,20 * WT.toolspeed))
if(!src || !WT.isOn()) return
state = 1
to_chat(user, "You cut [src] free from the floor.")
disconnect_from_network()
else
to_chat(user, "<span class='warning'>You need more welding fuel to complete this task.</span>")
update_icon() // VOREStation Add
return
if(istype(W, /obj/item/stack/material) && W.get_material_name() == MAT_STEEL)
var/amt = CEILING(( initial(integrity) - integrity)/10, 1)
if(!amt)
to_chat(user, "<span class='notice'>\The [src] is already fully repaired.</span>")
return
var/obj/item/stack/P = W
if(!P.can_use(amt))
to_chat(user, "<span class='warning'>You don't have enough sheets to repair this! You need at least [amt] sheets.</span>")
return
to_chat(user, "<span class='notice'>You begin repairing \the [src]...</span>")
if(do_after(user, 30))
if(P.use(amt))
to_chat(user, "<span class='notice'>You have repaired \the [src].</span>")
integrity = initial(integrity)
return
else
to_chat(user, "<span class='warning'>You don't have enough sheets to repair this! You need at least [amt] sheets.</span>")
return
if(istype(W, /obj/item/weapon/card/id) || istype(W, /obj/item/device/pda))
if(emagged)
to_chat(user, "<span class='warning'>The lock seems to be broken.</span>")
return
if(src.allowed(user))
src.locked = !src.locked
to_chat(user, "The controls are now [src.locked ? "locked." : "unlocked."]")
update_icon() // VOREStation Add
else
to_chat(user, "<span class='warning'>Access denied.</span>")
return
..()
return
/obj/machinery/power/emitter/emag_act(var/remaining_charges, var/mob/user)
if(!emagged)
locked = 0
emagged = 1
user.visible_message("[user.name] emags [src].","<span class='warning'>You short out the lock.</span>")
return 1
/obj/machinery/power/emitter/bullet_act(var/obj/item/projectile/P)
if(!P || !P.damage || P.get_structure_damage() <= 0 )
return
adjust_integrity(-P.get_structure_damage())
/obj/machinery/power/emitter/blob_act()
adjust_integrity(-1000) // This kills the emitter.
/obj/machinery/power/emitter/proc/adjust_integrity(amount)
integrity = between(0, integrity + amount, initial(integrity))
if(integrity == 0)
if(powernet && avail(active_power_usage)) // If it's powered, it goes boom if killed.
visible_message(src, "<span class='danger'>\The [src] explodes violently!</span>", "<span class='danger'>You hear an explosion!</span>")
explosion(get_turf(src), 1, 2, 4)
else
src.visible_message("<span class='danger'>\The [src] crumples apart!</span>", "<span class='warning'>You hear metal collapsing.</span>")
if(src)
qdel(src)
/obj/machinery/power/emitter/examine(mob/user)
. = ..()
switch(state)
if(0)
. += "<span class='warning'>It is not secured in place!</span>"
if(1)
. += "<span class='warning'>It has been bolted down securely, but not welded into place.</span>"
if(2)
. += "<span class='notice'>It has been bolted down securely and welded down into place.</span>"
var/integrity_percentage = round((integrity / initial(integrity)) * 100)
switch(integrity_percentage)
if(0 to 30)
. += "<span class='danger'>It is close to falling apart!</span>"
if(31 to 70)
. += "<span class='danger'>It is damaged.</span>"
if(77 to 99)
. += "<span class='warning'>It is slightly damaged.</span>"
//R-UST port
/obj/machinery/power/emitter/proc/get_initial_fire_delay()
return initial_fire_delay
/obj/machinery/power/emitter/proc/get_rand_burst_delay()
return rand(min_burst_delay, max_burst_delay)
/obj/machinery/power/emitter/proc/get_burst_delay()
return burst_delay
/obj/machinery/power/emitter/proc/get_emitter_beam()
return new /obj/item/projectile/beam/emitter(get_turf(src))
#define EMITTER_DAMAGE_POWER_TRANSFER 450 //used to transfer power to containment field generators
/obj/machinery/power/emitter
name = "emitter"
desc = "It is a heavy duty industrial laser."
icon = 'icons/obj/singularity.dmi'
icon_state = "emitter"
anchored = FALSE
density = TRUE
unacidable = TRUE
req_access = list(access_engine_equip)
var/id = null
use_power = USE_POWER_OFF //uses powernet power, not APC power
active_power_usage = 30000 //30 kW laser. I guess that means 30 kJ per shot.
var/active = 0
var/powered = 0
var/fire_delay = 100
var/max_burst_delay = 100
var/min_burst_delay = 20
var/burst_shots = 3
var/last_shot = 0
var/shot_number = 0
var/state = 0
var/locked = 0
var/burst_delay = 2
var/initial_fire_delay = 100
var/integrity = 80
/obj/machinery/power/emitter/verb/rotate_clockwise()
set name = "Rotate Emitter Clockwise"
set category = "Object"
set src in oview(1)
if (src.anchored || usr:stat)
to_chat(usr, "It is fastened to the floor!")
return 0
src.set_dir(turn(src.dir, 270))
return 1
/obj/machinery/power/emitter/verb/rotate_counterclockwise()
set name = "Rotate Emitter Counter-Clockwise"
set category = "Object"
set src in oview(1)
if (src.anchored || usr:stat)
to_chat(usr, "It is fastened to the floor!")
return 0
src.set_dir(turn(src.dir, 90))
return 1
/obj/machinery/power/emitter/Initialize()
. = ..()
if(state == 2 && anchored)
connect_to_network()
/obj/machinery/power/emitter/Destroy()
message_admins("Emitter deleted at ([x],[y],[z] - <A HREF='?_src_=holder;[HrefToken()];adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)",0,1)
log_game("EMITTER([x],[y],[z]) Destroyed/deleted.")
investigate_log("<font color='red'>deleted</font> at ([x],[y],[z])","singulo")
..()
/obj/machinery/power/emitter/update_icon()
if (active && powernet && avail(active_power_usage))
icon_state = "emitter_+a"
else
icon_state = "emitter"
/obj/machinery/power/emitter/attack_hand(mob/user as mob)
src.add_fingerprint(user)
activate(user)
/obj/machinery/power/emitter/proc/activate(mob/user as mob)
if(state == 2)
if(!powernet)
to_chat(user, "\The [src] isn't connected to a wire.")
return 1
if(!src.locked)
if(src.active==1)
src.active = 0
to_chat(user, "You turn off [src].")
message_admins("Emitter turned off by [key_name(user, user.client)](<A HREF='?_src_=holder;[HrefToken()];adminmoreinfo=\ref[user]'>?</A>) in ([x],[y],[z] - <A HREF='?_src_=holder;[HrefToken()];adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)",0,1)
log_game("EMITTER([x],[y],[z]) OFF by [key_name(user)]")
investigate_log("turned <font color='red'>off</font> by [user.key]","singulo")
else
src.active = 1
to_chat(user, "You turn on [src].")
src.shot_number = 0
src.fire_delay = get_initial_fire_delay()
message_admins("Emitter turned on by [key_name(user, user.client)](<A HREF='?_src_=holder;[HrefToken()];adminmoreinfo=\ref[user]'>?</A>) in ([x],[y],[z] - <A HREF='?_src_=holder;[HrefToken()];adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)",0,1)
log_game("EMITTER([x],[y],[z]) ON by [key_name(user)]")
investigate_log("turned <font color='green'>on</font> by [user.key]","singulo")
update_icon()
else
to_chat(user, "<span class='warning'>The controls are locked!</span>")
else
to_chat(user, "<span class='warning'>\The [src] needs to be firmly secured to the floor first.</span>")
return 1
/obj/machinery/power/emitter/emp_act(var/severity)//Emitters are hardened but still might have issues
// add_load(1000)
/* if((severity == 1)&&prob(1)&&prob(1))
if(src.active)
src.active = 0
src.use_power = 1 */
return 1
/obj/machinery/power/emitter/process()
if(stat & (BROKEN))
return
if(src.state != 2 || (!powernet && active_power_usage))
src.active = 0
update_icon()
return
if(((src.last_shot + src.fire_delay) <= world.time) && (src.active == 1))
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()
log_game("EMITTER([x],[y],[z]) Regained power and is ON.")
investigate_log("regained power and turned <font color='green'>on</font>","singulo")
else
if(powered)
powered = 0
update_icon()
log_game("EMITTER([x],[y],[z]) Lost power and was ON.")
investigate_log("lost power and turned <font color='red'>off</font>","singulo")
return
src.last_shot = world.time
if(src.shot_number < burst_shots)
src.fire_delay = get_burst_delay() //R-UST port
src.shot_number ++
else
src.fire_delay = get_rand_burst_delay() //R-UST port
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
playsound(src, 'sound/weapons/emitter.ogg', 25, 1)
if(prob(35))
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
var/obj/item/projectile/beam/emitter/A = get_emitter_beam()
A.damage = round(power_per_shot/EMITTER_DAMAGE_POWER_TRANSFER)
A.firer = src
A.fire(dir2angle(dir))
/obj/machinery/power/emitter/attackby(obj/item/W, mob/user)
if(W.has_tool_quality(TOOL_WRENCH))
if(active)
to_chat(user, "Turn off [src] first.")
return
switch(state)
if(0)
state = 1
playsound(src, W.usesound, 75, 1)
user.visible_message("[user.name] secures [src] to the floor.", \
"You secure the external reinforcing bolts to the floor.", \
"You hear a ratchet.")
src.anchored = TRUE
if(1)
state = 0
playsound(src, W.usesound, 75, 1)
user.visible_message("[user.name] unsecures [src] reinforcing bolts from the floor.", \
"You undo the external reinforcing bolts.", \
"You hear a ratchet.")
src.anchored = FALSE
disconnect_from_network()
if(2)
to_chat(user, "<span class='warning'>\The [src] needs to be unwelded from the floor.</span>")
update_icon() // VOREStation Add
return
if(W.has_tool_quality(TOOL_WELDER))
var/obj/item/weapon/weldingtool/WT = W.get_welder()
if(active)
to_chat(user, "Turn off [src] first.")
return
switch(state)
if(0)
to_chat(user, "<span class='warning'>\The [src] needs to be wrenched to the floor.</span>")
if(1)
if (WT.remove_fuel(0,user))
playsound(src, WT.usesound, 50, 1)
user.visible_message("[user.name] starts to weld [src] to the floor.", \
"You start to weld [src] to the floor.", \
"You hear welding")
if (do_after(user,20 * WT.toolspeed))
if(!src || !WT.isOn()) return
state = 2
to_chat(user, "You weld [src] to the floor.")
connect_to_network()
else
to_chat(user, "<span class='warning'>You need more welding fuel to complete this task.</span>")
if(2)
if (WT.remove_fuel(0,user))
playsound(src, WT.usesound, 50, 1)
user.visible_message("[user.name] starts to cut [src] free from the floor.", \
"You start to cut [src] free from the floor.", \
"You hear welding")
if (do_after(user,20 * WT.toolspeed))
if(!src || !WT.isOn()) return
state = 1
to_chat(user, "You cut [src] free from the floor.")
disconnect_from_network()
else
to_chat(user, "<span class='warning'>You need more welding fuel to complete this task.</span>")
update_icon() // VOREStation Add
return
if(istype(W, /obj/item/stack/material) && W.get_material_name() == MAT_STEEL)
var/amt = CEILING(( initial(integrity) - integrity)/10, 1)
if(!amt)
to_chat(user, "<span class='notice'>\The [src] is already fully repaired.</span>")
return
var/obj/item/stack/P = W
if(!P.can_use(amt))
to_chat(user, "<span class='warning'>You don't have enough sheets to repair this! You need at least [amt] sheets.</span>")
return
to_chat(user, "<span class='notice'>You begin repairing \the [src]...</span>")
if(do_after(user, 30))
if(P.use(amt))
to_chat(user, "<span class='notice'>You have repaired \the [src].</span>")
integrity = initial(integrity)
return
else
to_chat(user, "<span class='warning'>You don't have enough sheets to repair this! You need at least [amt] sheets.</span>")
return
if(istype(W, /obj/item/weapon/card/id) || istype(W, /obj/item/device/pda))
if(emagged)
to_chat(user, "<span class='warning'>The lock seems to be broken.</span>")
return
if(src.allowed(user))
src.locked = !src.locked
to_chat(user, "The controls are now [src.locked ? "locked." : "unlocked."]")
update_icon() // VOREStation Add
else
to_chat(user, "<span class='warning'>Access denied.</span>")
return
..()
return
/obj/machinery/power/emitter/emag_act(var/remaining_charges, var/mob/user)
if(!emagged)
locked = 0
emagged = 1
user.visible_message("[user.name] emags [src].","<span class='warning'>You short out the lock.</span>")
return 1
/obj/machinery/power/emitter/bullet_act(var/obj/item/projectile/P)
if(!P || !P.damage || P.get_structure_damage() <= 0 )
return
adjust_integrity(-P.get_structure_damage())
/obj/machinery/power/emitter/blob_act()
adjust_integrity(-1000) // This kills the emitter.
/obj/machinery/power/emitter/proc/adjust_integrity(amount)
integrity = between(0, integrity + amount, initial(integrity))
if(integrity == 0)
if(powernet && avail(active_power_usage)) // If it's powered, it goes boom if killed.
visible_message(src, "<span class='danger'>\The [src] explodes violently!</span>", "<span class='danger'>You hear an explosion!</span>")
explosion(get_turf(src), 1, 2, 4)
else
src.visible_message("<span class='danger'>\The [src] crumples apart!</span>", "<span class='warning'>You hear metal collapsing.</span>")
if(src)
qdel(src)
/obj/machinery/power/emitter/examine(mob/user)
. = ..()
switch(state)
if(0)
. += "<span class='warning'>It is not secured in place!</span>"
if(1)
. += "<span class='warning'>It has been bolted down securely, but not welded into place.</span>"
if(2)
. += "<span class='notice'>It has been bolted down securely and welded down into place.</span>"
var/integrity_percentage = round((integrity / initial(integrity)) * 100)
switch(integrity_percentage)
if(0 to 30)
. += "<span class='danger'>It is close to falling apart!</span>"
if(31 to 70)
. += "<span class='danger'>It is damaged.</span>"
if(77 to 99)
. += "<span class='warning'>It is slightly damaged.</span>"
//R-UST port
/obj/machinery/power/emitter/proc/get_initial_fire_delay()
return initial_fire_delay
/obj/machinery/power/emitter/proc/get_rand_burst_delay()
return rand(min_burst_delay, max_burst_delay)
/obj/machinery/power/emitter/proc/get_burst_delay()
return burst_delay
/obj/machinery/power/emitter/proc/get_emitter_beam()
return new /obj/item/projectile/beam/emitter(get_turf(src))
+359 -359
View File
@@ -1,359 +1,359 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33
/*
field_generator power level display
The icon used for the field_generator need to have 'num_power_levels' number of icon states
named 'Field_Gen +p[num]' where 'num' ranges from 1 to 'num_power_levels'
The power level is displayed using overlays. The current displayed power level is stored in 'powerlevel'.
The overlay in use and the powerlevel variable must be kept in sync. A powerlevel equal to 0 means that
no power level overlay is currently in the overlays list.
-Aygar
*/
#define field_generator_max_power 250000
/obj/machinery/field_generator
name = "Field Generator"
desc = "A large thermal battery that projects a high amount of energy when powered."
icon = 'icons/obj/machines/field_generator.dmi'
icon_state = "Field_Gen"
anchored = FALSE
density = TRUE
use_power = USE_POWER_OFF
var/const/num_power_levels = 6 // Total number of power level icon has
var/Varedit_start = 0
var/Varpower = 0
var/active = 0
var/power = 30000 // Current amount of power
var/state = 0
var/warming_up = 0
var/list/obj/machinery/containment_field/fields
var/list/obj/machinery/field_generator/connected_gens
var/clean_up = 0
//If keeping field generators powered is hard then increase the emitter active power usage.
var/gen_power_draw = 5500 //power needed per generator
var/field_power_draw = 2000 //power needed per field object
var/light_range_on = 3
var/light_power_on = 1
light_color = "#5BA8FF"
/obj/machinery/field_generator/examine()
. = ..()
switch(state)
if(0)
. += "<span class='warning'>It is not secured in place!</span>"
if(1)
. += "<span class='warning'>It has been bolted down securely, but not welded into place.</span>"
if(2)
. += "<span class='notice'>It has been bolted down securely and welded down into place.</span>"
/obj/machinery/field_generator/update_icon()
cut_overlays()
if(!active)
if(warming_up)
add_overlay("+a[warming_up]")
if(fields.len)
add_overlay("+on")
// Power level indicator
// Scale % power to % num_power_levels and truncate value
var/level = round(num_power_levels * power / field_generator_max_power)
// Clamp between 0 and num_power_levels for out of range power values
level = between(0, level, num_power_levels)
if(level)
add_overlay("+p[level]")
return
/obj/machinery/field_generator/New()
..()
fields = list()
connected_gens = list()
return
/obj/machinery/field_generator/process()
if(Varedit_start == 1)
if(active == 0)
active = 1
state = 2
power = field_generator_max_power
anchored = TRUE
warming_up = 3
start_fields()
update_icon()
Varedit_start = 0
if(src.active == 2)
calc_power()
update_icon()
return
/obj/machinery/field_generator/attack_hand(mob/user as mob)
if(state == 2)
if(get_dist(src, user) <= 1)//Need to actually touch the thing to turn it on
if(src.active >= 1)
to_chat(user, "You are unable to turn off the [src.name] once it is online.")
return 1
else
user.visible_message("[user.name] turns on the [src.name]", \
"You turn on the [src.name].", \
"You hear heavy droning")
turn_on()
log_game("FIELDGEN([x],[y],[z]) Activated by [key_name(user)]")
investigate_log("<font color='green'>activated</font> by [user.key].","singulo")
src.add_fingerprint(user)
else
to_chat(user, "The [src] needs to be firmly secured to the floor first.")
return
/obj/machinery/field_generator/attackby(obj/item/W, mob/user)
if(active)
to_chat(user, "The [src] needs to be off.")
return
else if(W.has_tool_quality(TOOL_WRENCH))
switch(state)
if(0)
state = 1
playsound(src, W.usesound, 75, 1)
user.visible_message("[user.name] secures [src.name] to the floor.", \
"You secure the external reinforcing bolts to the floor.", \
"You hear ratchet")
src.anchored = TRUE
if(1)
state = 0
playsound(src, W.usesound, 75, 1)
user.visible_message("[user.name] unsecures [src.name] reinforcing bolts from the floor.", \
"You undo the external reinforcing bolts.", \
"You hear ratchet")
src.anchored = FALSE
if(2)
to_chat(user, span_red("The [src.name] needs to be unwelded from the floor."))
return
else if(W.has_tool_quality(TOOL_WELDER))
var/obj/item/weapon/weldingtool/WT = W.get_welder()
switch(state)
if(0)
to_chat(user, span_red("The [src.name] needs to be wrenched to the floor."))
return
if(1)
if (WT.remove_fuel(0,user))
playsound(src, WT.usesound, 50, 1)
user.visible_message("[user.name] starts to weld the [src.name] to the floor.", \
"You start to weld the [src] to the floor.", \
"You hear welding")
if (do_after(user,20 * WT.toolspeed))
if(!src || !WT.isOn()) return
state = 2
to_chat(user, "You weld the field generator to the floor.")
else
return
if(2)
if (WT.remove_fuel(0,user))
playsound(src, WT.usesound, 50, 1)
user.visible_message("[user.name] starts to cut the [src.name] free from the floor.", \
"You start to cut the [src] free from the floor.", \
"You hear welding")
if (do_after(user,20 * WT.toolspeed))
if(!src || !WT.isOn()) return
state = 1
to_chat(user, "You cut the [src] free from the floor.")
else
return
else
..()
return
/obj/machinery/field_generator/emp_act()
return 0
/obj/machinery/field_generator/bullet_act(var/obj/item/projectile/Proj)
if(istype(Proj, /obj/item/projectile/beam))
power += Proj.damage * EMITTER_DAMAGE_POWER_TRANSFER
update_icon()
return 0
/obj/machinery/field_generator/Destroy()
src.cleanup()
. = ..()
/obj/machinery/field_generator/proc/turn_off()
active = 0
spawn(1)
src.cleanup()
set_light(0)
update_icon()
/obj/machinery/field_generator/proc/turn_on()
active = 1
warming_up = 1
spawn(1)
while (warming_up<3 && active)
sleep(50)
warming_up++
update_icon()
if(warming_up >= 3)
start_fields()
set_light(light_range_on, light_power_on)
update_icon()
/obj/machinery/field_generator/proc/calc_power()
if(Varpower)
return 1
update_icon()
if(src.power > field_generator_max_power)
src.power = field_generator_max_power
var/power_draw = gen_power_draw
for(var/obj/machinery/field_generator/FG in connected_gens)
if (!isnull(FG))
power_draw += gen_power_draw
for (var/obj/machinery/containment_field/F in fields)
if (!isnull(F))
power_draw += field_power_draw
power_draw /= 2 //because this will be mirrored for both generators
if(draw_power(round(power_draw)) >= power_draw)
return 1
else
for(var/mob/M in viewers(src))
M.show_message(span_red("\The [src] shuts down!"))
turn_off()
log_game("FIELDGEN([x],[y],[z]) Lost power and was ON.")
investigate_log("ran out of power and <font color='red'>deactivated</font>","singulo")
src.power = 0
return 0
//Tries to draw the needed power from our own power reserve, or connected generators if we can. Returns the amount of power we were able to get.
/obj/machinery/field_generator/proc/draw_power(var/draw = 0, var/list/flood_list = list())
flood_list += src
if(src.power >= draw)//We have enough power
src.power -= draw
return draw
//Need more power
var/actual_draw = src.power //already checked that power < draw
src.power = 0
for(var/obj/machinery/field_generator/FG in connected_gens)
if (FG in flood_list)
continue
actual_draw += FG.draw_power(draw - actual_draw, flood_list) //since the flood list reference is shared this actually works.
if (actual_draw >= draw)
return actual_draw
return actual_draw
/obj/machinery/field_generator/proc/start_fields()
if(!src.state == 2 || !anchored)
turn_off()
return
spawn(1)
setup_field(1)
spawn(2)
setup_field(2)
spawn(3)
setup_field(4)
spawn(4)
setup_field(8)
src.active = 2
/obj/machinery/field_generator/proc/setup_field(var/NSEW)
var/turf/T = src.loc
var/obj/machinery/field_generator/G
var/steps = 0
if(!NSEW)//Make sure its ran right
return
for(var/dist = 0, dist <= 9, dist += 1) // checks out to 8 tiles away for another generator
T = get_step(T, NSEW)
if(T.density)//We cant shoot a field though this
return 0
for(var/atom/A in T.contents)
if(ismob(A))
continue
if(!istype(A,/obj/machinery/field_generator))
if((istype(A,/obj/machinery/door)||istype(A,/obj/machinery/the_singularitygen))&&(A.density))
return 0
steps += 1
G = locate(/obj/machinery/field_generator) in T
if(!isnull(G))
steps -= 1
if(!G.active)
return 0
break
if(isnull(G))
return
T = src.loc
for(var/dist = 0, dist < steps, dist += 1) // creates each field tile
var/field_dir = get_dir(T,get_step(G.loc, NSEW))
T = get_step(T, NSEW)
if(!locate(/obj/machinery/containment_field) in T)
var/obj/machinery/containment_field/CF = new/obj/machinery/containment_field(T)
CF.set_master(src,G)
fields += CF
G.fields += CF
CF.set_dir(field_dir)
var/listcheck = 0
for(var/obj/machinery/field_generator/FG in connected_gens)
if (isnull(FG))
continue
if(FG == G)
listcheck = 1
break
if(!listcheck)
connected_gens.Add(G)
listcheck = 0
for(var/obj/machinery/field_generator/FG2 in G.connected_gens)
if (isnull(FG2))
continue
if(FG2 == src)
listcheck = 1
break
if(!listcheck)
G.connected_gens.Add(src)
/obj/machinery/field_generator/proc/cleanup()
clean_up = 1
for (var/obj/machinery/containment_field/F in fields)
if (QDELETED(F))
continue
qdel(F)
fields = list()
for(var/obj/machinery/field_generator/FG in connected_gens)
if (QDELETED(FG))
continue
FG.connected_gens.Remove(src)
if(!FG.clean_up)//Makes the other gens clean up as well
FG.cleanup()
connected_gens.Remove(FG)
connected_gens = list()
clean_up = 0
update_icon()
//This is here to help fight the "hurr durr, release singulo cos nobody will notice before the
//singulo eats the evidence". It's not fool-proof but better than nothing.
//I want to avoid using global variables.
spawn(1)
var/temp = 1 //stops spam
for(var/obj/singularity/O in machines)
if(O.last_warning && temp)
if((world.time - O.last_warning) > 50) //to stop message-spam
temp = 0
admin_chat_message(message = "SINGUL/TESLOOSE!", color = "#FF2222") //VOREStation Add
message_admins("A singulo exists and a containment field has failed.",1)
investigate_log("has <font color='red'>failed</font> whilst a singulo exists.","singulo")
log_game("FIELDGEN([x],[y],[z]) Containment failed while singulo/tesla exists.")
O.last_warning = world.time
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33
/*
field_generator power level display
The icon used for the field_generator need to have 'num_power_levels' number of icon states
named 'Field_Gen +p[num]' where 'num' ranges from 1 to 'num_power_levels'
The power level is displayed using overlays. The current displayed power level is stored in 'powerlevel'.
The overlay in use and the powerlevel variable must be kept in sync. A powerlevel equal to 0 means that
no power level overlay is currently in the overlays list.
-Aygar
*/
#define field_generator_max_power 250000
/obj/machinery/field_generator
name = "Field Generator"
desc = "A large thermal battery that projects a high amount of energy when powered."
icon = 'icons/obj/machines/field_generator.dmi'
icon_state = "Field_Gen"
anchored = FALSE
density = TRUE
use_power = USE_POWER_OFF
var/const/num_power_levels = 6 // Total number of power level icon has
var/Varedit_start = 0
var/Varpower = 0
var/active = 0
var/power = 30000 // Current amount of power
var/state = 0
var/warming_up = 0
var/list/obj/machinery/containment_field/fields
var/list/obj/machinery/field_generator/connected_gens
var/clean_up = 0
//If keeping field generators powered is hard then increase the emitter active power usage.
var/gen_power_draw = 5500 //power needed per generator
var/field_power_draw = 2000 //power needed per field object
var/light_range_on = 3
var/light_power_on = 1
light_color = "#5BA8FF"
/obj/machinery/field_generator/examine()
. = ..()
switch(state)
if(0)
. += "<span class='warning'>It is not secured in place!</span>"
if(1)
. += "<span class='warning'>It has been bolted down securely, but not welded into place.</span>"
if(2)
. += "<span class='notice'>It has been bolted down securely and welded down into place.</span>"
/obj/machinery/field_generator/update_icon()
cut_overlays()
if(!active)
if(warming_up)
add_overlay("+a[warming_up]")
if(fields.len)
add_overlay("+on")
// Power level indicator
// Scale % power to % num_power_levels and truncate value
var/level = round(num_power_levels * power / field_generator_max_power)
// Clamp between 0 and num_power_levels for out of range power values
level = between(0, level, num_power_levels)
if(level)
add_overlay("+p[level]")
return
/obj/machinery/field_generator/New()
..()
fields = list()
connected_gens = list()
return
/obj/machinery/field_generator/process()
if(Varedit_start == 1)
if(active == 0)
active = 1
state = 2
power = field_generator_max_power
anchored = TRUE
warming_up = 3
start_fields()
update_icon()
Varedit_start = 0
if(src.active == 2)
calc_power()
update_icon()
return
/obj/machinery/field_generator/attack_hand(mob/user as mob)
if(state == 2)
if(get_dist(src, user) <= 1)//Need to actually touch the thing to turn it on
if(src.active >= 1)
to_chat(user, "You are unable to turn off the [src.name] once it is online.")
return 1
else
user.visible_message("[user.name] turns on the [src.name]", \
"You turn on the [src.name].", \
"You hear heavy droning")
turn_on()
log_game("FIELDGEN([x],[y],[z]) Activated by [key_name(user)]")
investigate_log("<font color='green'>activated</font> by [user.key].","singulo")
src.add_fingerprint(user)
else
to_chat(user, "The [src] needs to be firmly secured to the floor first.")
return
/obj/machinery/field_generator/attackby(obj/item/W, mob/user)
if(active)
to_chat(user, "The [src] needs to be off.")
return
else if(W.has_tool_quality(TOOL_WRENCH))
switch(state)
if(0)
state = 1
playsound(src, W.usesound, 75, 1)
user.visible_message("[user.name] secures [src.name] to the floor.", \
"You secure the external reinforcing bolts to the floor.", \
"You hear ratchet")
src.anchored = TRUE
if(1)
state = 0
playsound(src, W.usesound, 75, 1)
user.visible_message("[user.name] unsecures [src.name] reinforcing bolts from the floor.", \
"You undo the external reinforcing bolts.", \
"You hear ratchet")
src.anchored = FALSE
if(2)
to_chat(user, span_red("The [src.name] needs to be unwelded from the floor."))
return
else if(W.has_tool_quality(TOOL_WELDER))
var/obj/item/weapon/weldingtool/WT = W.get_welder()
switch(state)
if(0)
to_chat(user, span_red("The [src.name] needs to be wrenched to the floor."))
return
if(1)
if (WT.remove_fuel(0,user))
playsound(src, WT.usesound, 50, 1)
user.visible_message("[user.name] starts to weld the [src.name] to the floor.", \
"You start to weld the [src] to the floor.", \
"You hear welding")
if (do_after(user,20 * WT.toolspeed))
if(!src || !WT.isOn()) return
state = 2
to_chat(user, "You weld the field generator to the floor.")
else
return
if(2)
if (WT.remove_fuel(0,user))
playsound(src, WT.usesound, 50, 1)
user.visible_message("[user.name] starts to cut the [src.name] free from the floor.", \
"You start to cut the [src] free from the floor.", \
"You hear welding")
if (do_after(user,20 * WT.toolspeed))
if(!src || !WT.isOn()) return
state = 1
to_chat(user, "You cut the [src] free from the floor.")
else
return
else
..()
return
/obj/machinery/field_generator/emp_act()
return 0
/obj/machinery/field_generator/bullet_act(var/obj/item/projectile/Proj)
if(istype(Proj, /obj/item/projectile/beam))
power += Proj.damage * EMITTER_DAMAGE_POWER_TRANSFER
update_icon()
return 0
/obj/machinery/field_generator/Destroy()
src.cleanup()
. = ..()
/obj/machinery/field_generator/proc/turn_off()
active = 0
spawn(1)
src.cleanup()
set_light(0)
update_icon()
/obj/machinery/field_generator/proc/turn_on()
active = 1
warming_up = 1
spawn(1)
while (warming_up<3 && active)
sleep(50)
warming_up++
update_icon()
if(warming_up >= 3)
start_fields()
set_light(light_range_on, light_power_on)
update_icon()
/obj/machinery/field_generator/proc/calc_power()
if(Varpower)
return 1
update_icon()
if(src.power > field_generator_max_power)
src.power = field_generator_max_power
var/power_draw = gen_power_draw
for(var/obj/machinery/field_generator/FG in connected_gens)
if (!isnull(FG))
power_draw += gen_power_draw
for (var/obj/machinery/containment_field/F in fields)
if (!isnull(F))
power_draw += field_power_draw
power_draw /= 2 //because this will be mirrored for both generators
if(draw_power(round(power_draw)) >= power_draw)
return 1
else
for(var/mob/M in viewers(src))
M.show_message(span_red("\The [src] shuts down!"))
turn_off()
log_game("FIELDGEN([x],[y],[z]) Lost power and was ON.")
investigate_log("ran out of power and <font color='red'>deactivated</font>","singulo")
src.power = 0
return 0
//Tries to draw the needed power from our own power reserve, or connected generators if we can. Returns the amount of power we were able to get.
/obj/machinery/field_generator/proc/draw_power(var/draw = 0, var/list/flood_list = list())
flood_list += src
if(src.power >= draw)//We have enough power
src.power -= draw
return draw
//Need more power
var/actual_draw = src.power //already checked that power < draw
src.power = 0
for(var/obj/machinery/field_generator/FG in connected_gens)
if (FG in flood_list)
continue
actual_draw += FG.draw_power(draw - actual_draw, flood_list) //since the flood list reference is shared this actually works.
if (actual_draw >= draw)
return actual_draw
return actual_draw
/obj/machinery/field_generator/proc/start_fields()
if(!src.state == 2 || !anchored)
turn_off()
return
spawn(1)
setup_field(1)
spawn(2)
setup_field(2)
spawn(3)
setup_field(4)
spawn(4)
setup_field(8)
src.active = 2
/obj/machinery/field_generator/proc/setup_field(var/NSEW)
var/turf/T = src.loc
var/obj/machinery/field_generator/G
var/steps = 0
if(!NSEW)//Make sure its ran right
return
for(var/dist = 0, dist <= 9, dist += 1) // checks out to 8 tiles away for another generator
T = get_step(T, NSEW)
if(T.density)//We cant shoot a field though this
return 0
for(var/atom/A in T.contents)
if(ismob(A))
continue
if(!istype(A,/obj/machinery/field_generator))
if((istype(A,/obj/machinery/door)||istype(A,/obj/machinery/the_singularitygen))&&(A.density))
return 0
steps += 1
G = locate(/obj/machinery/field_generator) in T
if(!isnull(G))
steps -= 1
if(!G.active)
return 0
break
if(isnull(G))
return
T = src.loc
for(var/dist = 0, dist < steps, dist += 1) // creates each field tile
var/field_dir = get_dir(T,get_step(G.loc, NSEW))
T = get_step(T, NSEW)
if(!locate(/obj/machinery/containment_field) in T)
var/obj/machinery/containment_field/CF = new/obj/machinery/containment_field(T)
CF.set_master(src,G)
fields += CF
G.fields += CF
CF.set_dir(field_dir)
var/listcheck = 0
for(var/obj/machinery/field_generator/FG in connected_gens)
if (isnull(FG))
continue
if(FG == G)
listcheck = 1
break
if(!listcheck)
connected_gens.Add(G)
listcheck = 0
for(var/obj/machinery/field_generator/FG2 in G.connected_gens)
if (isnull(FG2))
continue
if(FG2 == src)
listcheck = 1
break
if(!listcheck)
G.connected_gens.Add(src)
/obj/machinery/field_generator/proc/cleanup()
clean_up = 1
for (var/obj/machinery/containment_field/F in fields)
if (QDELETED(F))
continue
qdel(F)
fields = list()
for(var/obj/machinery/field_generator/FG in connected_gens)
if (QDELETED(FG))
continue
FG.connected_gens.Remove(src)
if(!FG.clean_up)//Makes the other gens clean up as well
FG.cleanup()
connected_gens.Remove(FG)
connected_gens = list()
clean_up = 0
update_icon()
//This is here to help fight the "hurr durr, release singulo cos nobody will notice before the
//singulo eats the evidence". It's not fool-proof but better than nothing.
//I want to avoid using global variables.
spawn(1)
var/temp = 1 //stops spam
for(var/obj/singularity/O in machines)
if(O.last_warning && temp)
if((world.time - O.last_warning) > 50) //to stop message-spam
temp = 0
admin_chat_message(message = "SINGUL/TESLOOSE!", color = "#FF2222") //VOREStation Add
message_admins("A singulo exists and a containment field has failed.",1)
investigate_log("has <font color='red'>failed</font> whilst a singulo exists.","singulo")
log_game("FIELDGEN([x],[y],[z]) Containment failed while singulo/tesla exists.")
O.last_warning = world.time
+60 -60
View File
@@ -1,60 +1,60 @@
/////SINGULARITY SPAWNER
/obj/machinery/the_singularitygen/
name = "Gravitational Singularity Generator"
desc = "An Odd Device which produces a Gravitational Singularity when set up."
icon = 'icons/obj/singularity.dmi'
icon_state = "TheSingGen"
anchored = FALSE
density = TRUE
use_power = USE_POWER_OFF
var/energy = 0
var/creation_type = /obj/singularity
/obj/machinery/the_singularitygen/examine()
. = ..()
if(anchored)
. += "<span class='notice'>It has been securely bolted down and is ready for operation.</span>"
else
. += "<span class='warning'>It is not secured!</span>"
/obj/machinery/the_singularitygen/process()
var/turf/T = get_turf(src)
if(src.energy >= 200)
new creation_type(T, 50)
if(src) qdel(src)
/obj/machinery/the_singularitygen/attackby(obj/item/W, mob/user)
if(W.has_tool_quality(TOOL_WRENCH))
anchored = !anchored
playsound(src, W.usesound, 75, 1)
if(anchored)
user.visible_message("[user.name] secures [src.name] to the floor.", \
"You secure the [src.name] to the floor.", \
"You hear a ratchet.")
else
user.visible_message("[user.name] unsecures [src.name] from the floor.", \
"You unsecure the [src.name] from the floor.", \
"You hear a ratchet.")
return
if(W.has_tool_quality(TOOL_SCREWDRIVER))
panel_open = !panel_open
playsound(src, W.usesound, 50, 1)
visible_message("<b>\The [user]</b> adjusts \the [src]'s mechanisms.")
if(panel_open && do_after(user, 30))
to_chat(user, "<span class='notice'>\The [src] looks like it could be modified.</span>")
if(panel_open && do_after(user, 80 * W.toolspeed)) // We don't have skills, so a delayed hint for engineers will have to do for now. (Panel open check for sanity)
playsound(src, W.usesound, 50, 1)
to_chat(user, "<span class='cult'>\The [src] looks like it could be adapted to forge advanced materials via particle acceleration, somehow..</span>")
else
to_chat(user, "<span class='notice'>\The [src]'s mechanisms look secure.</span>")
if(istype(W, /obj/item/weapon/smes_coil/super_io) && panel_open)
visible_message("<b>\The [user]</b> begins to modify \the [src] with \the [W].")
if(do_after(user, 300))
user.drop_from_inventory(W)
visible_message("<b>\The [user]</b> installs \the [W] onto \the [src].")
qdel(W)
var/turf/T = get_turf(src)
var/new_machine = /obj/machinery/particle_smasher
new new_machine(T)
qdel(src)
return ..()
/////SINGULARITY SPAWNER
/obj/machinery/the_singularitygen/
name = "Gravitational Singularity Generator"
desc = "An Odd Device which produces a Gravitational Singularity when set up."
icon = 'icons/obj/singularity.dmi'
icon_state = "TheSingGen"
anchored = FALSE
density = TRUE
use_power = USE_POWER_OFF
var/energy = 0
var/creation_type = /obj/singularity
/obj/machinery/the_singularitygen/examine()
. = ..()
if(anchored)
. += "<span class='notice'>It has been securely bolted down and is ready for operation.</span>"
else
. += "<span class='warning'>It is not secured!</span>"
/obj/machinery/the_singularitygen/process()
var/turf/T = get_turf(src)
if(src.energy >= 200)
new creation_type(T, 50)
if(src) qdel(src)
/obj/machinery/the_singularitygen/attackby(obj/item/W, mob/user)
if(W.has_tool_quality(TOOL_WRENCH))
anchored = !anchored
playsound(src, W.usesound, 75, 1)
if(anchored)
user.visible_message("[user.name] secures [src.name] to the floor.", \
"You secure the [src.name] to the floor.", \
"You hear a ratchet.")
else
user.visible_message("[user.name] unsecures [src.name] from the floor.", \
"You unsecure the [src.name] from the floor.", \
"You hear a ratchet.")
return
if(W.has_tool_quality(TOOL_SCREWDRIVER))
panel_open = !panel_open
playsound(src, W.usesound, 50, 1)
visible_message("<b>\The [user]</b> adjusts \the [src]'s mechanisms.")
if(panel_open && do_after(user, 30))
to_chat(user, "<span class='notice'>\The [src] looks like it could be modified.</span>")
if(panel_open && do_after(user, 80 * W.toolspeed)) // We don't have skills, so a delayed hint for engineers will have to do for now. (Panel open check for sanity)
playsound(src, W.usesound, 50, 1)
to_chat(user, "<span class='cult'>\The [src] looks like it could be adapted to forge advanced materials via particle acceleration, somehow..</span>")
else
to_chat(user, "<span class='notice'>\The [src]'s mechanisms look secure.</span>")
if(istype(W, /obj/item/weapon/smes_coil/super_io) && panel_open)
visible_message("<b>\The [user]</b> begins to modify \the [src] with \the [W].")
if(do_after(user, 300))
user.drop_from_inventory(W)
visible_message("<b>\The [user]</b> installs \the [W] onto \the [src].")
qdel(W)
var/turf/T = get_turf(src)
var/new_machine = /obj/machinery/particle_smasher
new new_machine(T)
qdel(src)
return ..()
@@ -1,103 +1,103 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33
/obj/effect/accelerated_particle
name = "Accelerated Particles"
desc = "Small things moving very fast."
icon = 'icons/obj/machines/particle_accelerator2.dmi'
icon_state = "particle1"//Need a new icon for this
anchored = TRUE
density = TRUE
movement_type = UNSTOPPABLE // for bumps to trigger
var/movement_range = 10
var/energy = 10 //energy in eV
var/mega_energy = 0 //energy in MeV
var/frequency = 1
var/ionizing = 0
var/particle_type
var/additional_particles = 0
var/turf/target
var/turf/source
var/movetotarget = 1
/obj/effect/accelerated_particle/weak
icon_state = "particle0"
movement_range = 8
energy = 5
/obj/effect/accelerated_particle/strong
icon_state = "particle2"
movement_range = 15
energy = 15
/obj/effect/accelerated_particle/powerful
icon_state = "particle3"
movement_range = 25
energy = 50
/obj/effect/accelerated_particle/New(loc, dir = 2)
src.loc = loc
src.set_dir(dir)
spawn(0)
move(1)
/obj/effect/accelerated_particle/Bump(atom/A)
if (A)
if(ismob(A))
toxmob(A)
if((istype(A,/obj/machinery/the_singularitygen))||(istype(A,/obj/singularity/))||(istype(A, /obj/machinery/particle_smasher)))
A:energy += energy
//R-UST port
else if(istype(A,/obj/machinery/power/fusion_core))
var/obj/machinery/power/fusion_core/collided_core = A
if(particle_type && particle_type != "neutron")
if(collided_core.AddParticles(particle_type, 1 + additional_particles))
collided_core.owned_field.plasma_temperature += mega_energy
collided_core.owned_field.energy += energy
loc = null
else if(istype(A, /obj/effect/fusion_particle_catcher))
var/obj/effect/fusion_particle_catcher/PC = A
if(particle_type && particle_type != "neutron")
if(PC.parent.owned_core.AddParticles(particle_type, 1 + additional_particles))
PC.parent.plasma_temperature += mega_energy
PC.parent.energy += energy
loc = null
/obj/effect/accelerated_particle/Bumped(atom/A)
if(ismob(A))
Bump(A)
/obj/effect/accelerated_particle/ex_act(severity)
qdel(src)
/obj/effect/accelerated_particle/singularity_act()
return
/obj/effect/accelerated_particle/proc/toxmob(var/mob/living/M)
var/radiation = (energy*2)
M.apply_effect((radiation*3),IRRADIATE,0)
M.updatehealth()
//to_chat(M, "<font color='red'>You feel odd.</font>")
/obj/effect/accelerated_particle/proc/move(var/lag)
if(target)
if(movetotarget)
if(!step_towards(src,target))
src.loc = get_step(src, get_dir(src,target))
if(get_dist(src,target) < 1)
movetotarget = 0
else
if(!step(src, get_step_away(src,source)))
src.loc = get_step(src, get_step_away(src,source))
else
if(!step(src,dir))
src.loc = get_step(src,dir)
movement_range--
if(movement_range <= 0)
qdel(src)
else
sleep(lag)
move(lag)
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33
/obj/effect/accelerated_particle
name = "Accelerated Particles"
desc = "Small things moving very fast."
icon = 'icons/obj/machines/particle_accelerator2.dmi'
icon_state = "particle1"//Need a new icon for this
anchored = TRUE
density = TRUE
movement_type = UNSTOPPABLE // for bumps to trigger
var/movement_range = 10
var/energy = 10 //energy in eV
var/mega_energy = 0 //energy in MeV
var/frequency = 1
var/ionizing = 0
var/particle_type
var/additional_particles = 0
var/turf/target
var/turf/source
var/movetotarget = 1
/obj/effect/accelerated_particle/weak
icon_state = "particle0"
movement_range = 8
energy = 5
/obj/effect/accelerated_particle/strong
icon_state = "particle2"
movement_range = 15
energy = 15
/obj/effect/accelerated_particle/powerful
icon_state = "particle3"
movement_range = 25
energy = 50
/obj/effect/accelerated_particle/New(loc, dir = 2)
src.loc = loc
src.set_dir(dir)
spawn(0)
move(1)
/obj/effect/accelerated_particle/Bump(atom/A)
if (A)
if(ismob(A))
toxmob(A)
if((istype(A,/obj/machinery/the_singularitygen))||(istype(A,/obj/singularity/))||(istype(A, /obj/machinery/particle_smasher)))
A:energy += energy
//R-UST port
else if(istype(A,/obj/machinery/power/fusion_core))
var/obj/machinery/power/fusion_core/collided_core = A
if(particle_type && particle_type != "neutron")
if(collided_core.AddParticles(particle_type, 1 + additional_particles))
collided_core.owned_field.plasma_temperature += mega_energy
collided_core.owned_field.energy += energy
loc = null
else if(istype(A, /obj/effect/fusion_particle_catcher))
var/obj/effect/fusion_particle_catcher/PC = A
if(particle_type && particle_type != "neutron")
if(PC.parent.owned_core.AddParticles(particle_type, 1 + additional_particles))
PC.parent.plasma_temperature += mega_energy
PC.parent.energy += energy
loc = null
/obj/effect/accelerated_particle/Bumped(atom/A)
if(ismob(A))
Bump(A)
/obj/effect/accelerated_particle/ex_act(severity)
qdel(src)
/obj/effect/accelerated_particle/singularity_act()
return
/obj/effect/accelerated_particle/proc/toxmob(var/mob/living/M)
var/radiation = (energy*2)
M.apply_effect((radiation*3),IRRADIATE,0)
M.updatehealth()
//to_chat(M, "<font color='red'>You feel odd.</font>")
/obj/effect/accelerated_particle/proc/move(var/lag)
if(target)
if(movetotarget)
if(!step_towards(src,target))
src.loc = get_step(src, get_dir(src,target))
if(get_dist(src,target) < 1)
movetotarget = 0
else
if(!step(src, get_step_away(src,source)))
src.loc = get_step(src, get_step_away(src,source))
else
if(!step(src,dir))
src.loc = get_step(src,dir)
movement_range--
if(movement_range <= 0)
qdel(src)
else
sleep(lag)
move(lag)
@@ -1,385 +1,385 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33
/*Composed of 7 parts
3 Particle emitters
proc
emit_particle()
1 power box
the only part of this thing that uses power, can hack to mess with the pa/make it better.
Lies, only the control computer draws power.
1 fuel chamber
contains procs for mixing gas and whatever other fuel it uses
mix_gas()
1 gas holder WIP
acts like a tank valve on the ground that you wrench gas tanks onto
proc
extract_gas()
return_gas()
attach_tank()
remove_tank()
get_available_mix()
1 End Cap
1 Control computer
interface for the pa, acts like a computer with an html menu for diff parts and a status report
all other parts contain only a ref to this
a /machine/, tells the others to do work
contains ref for all parts
proc
process()
check_build()
Setup map
|EC|
CC|FC|
|PB|
PE|PE|PE
Icon Addemdum
Icon system is much more robust, and the icons are all variable based.
Each part has a reference string, powered, strength, and contruction values.
Using this the update_icon() proc is simplified a bit (using for absolutely was problematic with naming),
so the icon_state comes out be:
"[reference][strength]", with a switch controlling construction_states and ensuring that it doesn't
power on while being contructed, and all these variables are set by the computer through it's scan list
Essential order of the icons:
Standard - [reference]
Wrenched - [reference]
Wired - [reference]w
Closed - [reference]c
Powered - [reference]p[strength]
Strength being set by the computer and a null strength (Computer is powered off or inactive) returns a 'null', counting as empty
So, hopefully this is helpful if any more icons are to be added/changed/wondering what the hell is going on here
*/
/obj/structure/particle_accelerator
name = "Particle Accelerator"
desc = "Part of a Particle Accelerator."
icon = 'icons/obj/machines/particle_accelerator2.dmi'
icon_state = "none"
anchored = FALSE
density = TRUE
var/obj/machinery/particle_accelerator/control_box/master = null
var/construction_state = 0
var/reference = null
var/powered = 0
var/strength = null
var/desc_holder = null
/obj/structure/particle_accelerator/Destroy()
construction_state = 0
if(master)
master.part_scan()
..()
/obj/structure/particle_accelerator/end_cap
name = "Alpha Particle Generation Array"
desc_holder = "This is where Alpha particles are generated from \[REDACTED\]"
icon_state = "end_cap"
reference = "end_cap"
/obj/structure/particle_accelerator/update_icon()
..()
return
/obj/structure/particle_accelerator/verb/rotate_clockwise()
set name = "Rotate Clockwise"
set category = "Object"
set src in oview(1)
if (src.anchored || usr:stat)
to_chat(usr, "It is fastened to the floor!")
return 0
src.set_dir(turn(src.dir, 270))
return 1
/obj/structure/particle_accelerator/verb/rotate_counterclockwise()
set name = "Rotate Counter Clockwise"
set category = "Object"
set src in oview(1)
if (src.anchored || usr:stat)
to_chat(usr, "It is fastened to the floor!")
return 0
src.set_dir(turn(src.dir, 90))
return 1
/obj/structure/particle_accelerator/examine(mob/user)
. = ..()
switch(construction_state)
if(0)
. += "Looks like it's not attached to the flooring."
if(1)
. += "It is missing some cables."
if(2)
. += "The panel is open."
if(3)
. += "It is assembled."
/obj/structure/particle_accelerator/attackby(obj/item/W, mob/user)
if(istool(W))
if(src.process_tool_hit(W,user))
return
..()
return
/obj/structure/particle_accelerator/Moved(atom/old_loc, direction, forced = FALSE)
. = ..()
if(master?.active)
master.toggle_power()
log_game("PACCEL([x],[y],[z]) Was moved while active and turned off.")
investigate_log("was moved whilst active; it <font color='red'>powered down</font>.","singulo")
/obj/structure/particle_accelerator/ex_act(severity)
switch(severity)
if(1.0)
qdel(src)
return
if(2.0)
if (prob(50))
qdel(src)
return
if(3.0)
if (prob(25))
qdel(src)
return
else
return
/obj/structure/particle_accelerator/update_icon()
switch(construction_state)
if(0,1)
icon_state="[reference]"
if(2)
icon_state="[reference]w"
if(3)
if(powered)
icon_state="[reference]p[strength]"
else
icon_state="[reference]c"
return
/obj/structure/particle_accelerator/proc/update_state()
if(master)
master.update_state()
return 0
/obj/structure/particle_accelerator/proc/report_ready(var/obj/O)
if(O && (O == master))
if(construction_state >= 3)
return 1
return 0
/obj/structure/particle_accelerator/proc/report_master()
if(master)
return master
return 0
/obj/structure/particle_accelerator/proc/connect_master(var/obj/O)
if(O && istype(O,/obj/machinery/particle_accelerator/control_box))
if(O.dir == src.dir)
master = O
return 1
return 0
/obj/structure/particle_accelerator/proc/process_tool_hit(var/obj/item/O, var/mob/user)
if(!(O) || !(user))
return 0
if(!ismob(user) || !isobj(O))
return 0
var/temp_state = src.construction_state
switch(src.construction_state)//TODO:Might be more interesting to have it need several parts rather than a single list of steps
if(0)
if(O.has_tool_quality(TOOL_WRENCH))
playsound(src, O.usesound, 75, 1)
src.anchored = TRUE
user.visible_message("[user.name] secures the [src.name] to the floor.", \
"You secure the external bolts.")
temp_state++
if(1)
if(O.has_tool_quality(TOOL_WRENCH))
playsound(src, O.usesound, 75, 1)
src.anchored = FALSE
user.visible_message("[user.name] detaches the [src.name] from the floor.", \
"You remove the external bolts.")
temp_state--
else if(istype(O, /obj/item/stack/cable_coil))
if(O:use(1,user))
user.visible_message("[user.name] adds wires to the [src.name].", \
"You add some wires.")
temp_state++
if(2)
if(O.has_tool_quality(TOOL_WIRECUTTER))//TODO:Shock user if its on?
user.visible_message("[user.name] removes some wires from the [src.name].", \
"You remove some wires.")
temp_state--
else if(O.has_tool_quality(TOOL_SCREWDRIVER))
user.visible_message("[user.name] closes the [src.name]'s access panel.", \
"You close the access panel.")
temp_state++
if(3)
if(O.has_tool_quality(TOOL_SCREWDRIVER))
user.visible_message("[user.name] opens the [src.name]'s access panel.", \
"You open the access panel.")
temp_state--
if(temp_state == src.construction_state)//Nothing changed
return 0
else
src.construction_state = temp_state
if(src.construction_state < 3)//Was taken apart, update state
update_state()
update_icon()
return 1
/obj/machinery/particle_accelerator
name = "Particle Accelerator"
desc = "Part of a Particle Accelerator."
icon = 'icons/obj/machines/particle_accelerator2.dmi'
icon_state = "none"
anchored = FALSE
density = TRUE
use_power = USE_POWER_OFF
idle_power_usage = 0
active_power_usage = 0
var/construction_state = 0
var/active = 0
var/reference = null
var/powered = null
var/strength = 0
var/desc_holder = null
/obj/machinery/particle_accelerator/verb/rotate_clockwise()
set name = "Rotate Clockwise"
set category = "Object"
set src in oview(1)
if (src.anchored || usr:stat)
to_chat(usr, "It is fastened to the floor!")
return 0
src.set_dir(turn(src.dir, 270))
return 1
/obj/machinery/particle_accelerator/verb/rotate_counterclockwise()
set name = "Rotate Counter-Clockwise"
set category = "Object"
set src in oview(1)
if (src.anchored || usr:stat)
to_chat(usr, "It is fastened to the floor!")
return 0
src.set_dir(turn(src.dir, 90))
return 1
/obj/machinery/particle_accelerator/update_icon()
return
/obj/machinery/particle_accelerator/examine(mob/user)
. = ..()
switch(construction_state)
if(0)
. += "Looks like it's not attached to the flooring."
if(1)
. += "It is missing some cables."
if(2)
. += "The panel is open."
if(3)
. += "It is assembled."
/obj/machinery/particle_accelerator/attackby(obj/item/W, mob/user)
if(istool(W))
if(src.process_tool_hit(W,user))
return
..()
return
/obj/machinery/particle_accelerator/ex_act(severity)
switch(severity)
if(1.0)
qdel(src)
return
if(2.0)
if (prob(50))
qdel(src)
return
if(3.0)
if (prob(25))
qdel(src)
return
else
return
/obj/machinery/particle_accelerator/proc/update_state()
return 0
/obj/machinery/particle_accelerator/proc/process_tool_hit(var/obj/item/O, var/mob/user)
if(!(O) || !(user))
return 0
if(!ismob(user) || !isobj(O))
return 0
var/temp_state = src.construction_state
switch(src.construction_state)//TODO:Might be more interesting to have it need several parts rather than a single list of steps
if(0)
if(O.has_tool_quality(TOOL_WRENCH))
playsound(src, O.usesound, 75, 1)
src.anchored = TRUE
user.visible_message("[user.name] secures the [src.name] to the floor.", \
"You secure the external bolts.")
temp_state++
if(1)
if(O.has_tool_quality(TOOL_WRENCH))
playsound(src, O.usesound, 75, 1)
src.anchored = FALSE
user.visible_message("[user.name] detaches the [src.name] from the floor.", \
"You remove the external bolts.")
temp_state--
else if(istype(O, /obj/item/stack/cable_coil))
if(O:use(1))
user.visible_message("[user.name] adds wires to the [src.name].", \
"You add some wires.")
temp_state++
if(2)
if(O.has_tool_quality(TOOL_WIRECUTTER))//TODO:Shock user if its on?
user.visible_message("[user.name] removes some wires from the [src.name].", \
"You remove some wires.")
temp_state--
else if(O.has_tool_quality(TOOL_SCREWDRIVER))
user.visible_message("[user.name] closes the [src.name]'s access panel.", \
"You close the access panel.")
temp_state++
if(3)
if(O.has_tool_quality(TOOL_SCREWDRIVER))
user.visible_message("[user.name] opens the [src.name]'s access panel.", \
"You open the access panel.")
temp_state--
active = 0
if(temp_state == src.construction_state)//Nothing changed
return 0
else
if(src.construction_state < 3)//Was taken apart, update state
update_state()
if(use_power)
update_use_power(USE_POWER_OFF)
src.construction_state = temp_state
if(src.construction_state >= 3)
update_use_power(USE_POWER_IDLE)
update_icon()
return 1
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33
/*Composed of 7 parts
3 Particle emitters
proc
emit_particle()
1 power box
the only part of this thing that uses power, can hack to mess with the pa/make it better.
Lies, only the control computer draws power.
1 fuel chamber
contains procs for mixing gas and whatever other fuel it uses
mix_gas()
1 gas holder WIP
acts like a tank valve on the ground that you wrench gas tanks onto
proc
extract_gas()
return_gas()
attach_tank()
remove_tank()
get_available_mix()
1 End Cap
1 Control computer
interface for the pa, acts like a computer with an html menu for diff parts and a status report
all other parts contain only a ref to this
a /machine/, tells the others to do work
contains ref for all parts
proc
process()
check_build()
Setup map
|EC|
CC|FC|
|PB|
PE|PE|PE
Icon Addemdum
Icon system is much more robust, and the icons are all variable based.
Each part has a reference string, powered, strength, and contruction values.
Using this the update_icon() proc is simplified a bit (using for absolutely was problematic with naming),
so the icon_state comes out be:
"[reference][strength]", with a switch controlling construction_states and ensuring that it doesn't
power on while being contructed, and all these variables are set by the computer through it's scan list
Essential order of the icons:
Standard - [reference]
Wrenched - [reference]
Wired - [reference]w
Closed - [reference]c
Powered - [reference]p[strength]
Strength being set by the computer and a null strength (Computer is powered off or inactive) returns a 'null', counting as empty
So, hopefully this is helpful if any more icons are to be added/changed/wondering what the hell is going on here
*/
/obj/structure/particle_accelerator
name = "Particle Accelerator"
desc = "Part of a Particle Accelerator."
icon = 'icons/obj/machines/particle_accelerator2.dmi'
icon_state = "none"
anchored = FALSE
density = TRUE
var/obj/machinery/particle_accelerator/control_box/master = null
var/construction_state = 0
var/reference = null
var/powered = 0
var/strength = null
var/desc_holder = null
/obj/structure/particle_accelerator/Destroy()
construction_state = 0
if(master)
master.part_scan()
..()
/obj/structure/particle_accelerator/end_cap
name = "Alpha Particle Generation Array"
desc_holder = "This is where Alpha particles are generated from \[REDACTED\]"
icon_state = "end_cap"
reference = "end_cap"
/obj/structure/particle_accelerator/update_icon()
..()
return
/obj/structure/particle_accelerator/verb/rotate_clockwise()
set name = "Rotate Clockwise"
set category = "Object"
set src in oview(1)
if (src.anchored || usr:stat)
to_chat(usr, "It is fastened to the floor!")
return 0
src.set_dir(turn(src.dir, 270))
return 1
/obj/structure/particle_accelerator/verb/rotate_counterclockwise()
set name = "Rotate Counter Clockwise"
set category = "Object"
set src in oview(1)
if (src.anchored || usr:stat)
to_chat(usr, "It is fastened to the floor!")
return 0
src.set_dir(turn(src.dir, 90))
return 1
/obj/structure/particle_accelerator/examine(mob/user)
. = ..()
switch(construction_state)
if(0)
. += "Looks like it's not attached to the flooring."
if(1)
. += "It is missing some cables."
if(2)
. += "The panel is open."
if(3)
. += "It is assembled."
/obj/structure/particle_accelerator/attackby(obj/item/W, mob/user)
if(istool(W))
if(src.process_tool_hit(W,user))
return
..()
return
/obj/structure/particle_accelerator/Moved(atom/old_loc, direction, forced = FALSE)
. = ..()
if(master?.active)
master.toggle_power()
log_game("PACCEL([x],[y],[z]) Was moved while active and turned off.")
investigate_log("was moved whilst active; it <font color='red'>powered down</font>.","singulo")
/obj/structure/particle_accelerator/ex_act(severity)
switch(severity)
if(1.0)
qdel(src)
return
if(2.0)
if (prob(50))
qdel(src)
return
if(3.0)
if (prob(25))
qdel(src)
return
else
return
/obj/structure/particle_accelerator/update_icon()
switch(construction_state)
if(0,1)
icon_state="[reference]"
if(2)
icon_state="[reference]w"
if(3)
if(powered)
icon_state="[reference]p[strength]"
else
icon_state="[reference]c"
return
/obj/structure/particle_accelerator/proc/update_state()
if(master)
master.update_state()
return 0
/obj/structure/particle_accelerator/proc/report_ready(var/obj/O)
if(O && (O == master))
if(construction_state >= 3)
return 1
return 0
/obj/structure/particle_accelerator/proc/report_master()
if(master)
return master
return 0
/obj/structure/particle_accelerator/proc/connect_master(var/obj/O)
if(O && istype(O,/obj/machinery/particle_accelerator/control_box))
if(O.dir == src.dir)
master = O
return 1
return 0
/obj/structure/particle_accelerator/proc/process_tool_hit(var/obj/item/O, var/mob/user)
if(!(O) || !(user))
return 0
if(!ismob(user) || !isobj(O))
return 0
var/temp_state = src.construction_state
switch(src.construction_state)//TODO:Might be more interesting to have it need several parts rather than a single list of steps
if(0)
if(O.has_tool_quality(TOOL_WRENCH))
playsound(src, O.usesound, 75, 1)
src.anchored = TRUE
user.visible_message("[user.name] secures the [src.name] to the floor.", \
"You secure the external bolts.")
temp_state++
if(1)
if(O.has_tool_quality(TOOL_WRENCH))
playsound(src, O.usesound, 75, 1)
src.anchored = FALSE
user.visible_message("[user.name] detaches the [src.name] from the floor.", \
"You remove the external bolts.")
temp_state--
else if(istype(O, /obj/item/stack/cable_coil))
if(O:use(1,user))
user.visible_message("[user.name] adds wires to the [src.name].", \
"You add some wires.")
temp_state++
if(2)
if(O.has_tool_quality(TOOL_WIRECUTTER))//TODO:Shock user if its on?
user.visible_message("[user.name] removes some wires from the [src.name].", \
"You remove some wires.")
temp_state--
else if(O.has_tool_quality(TOOL_SCREWDRIVER))
user.visible_message("[user.name] closes the [src.name]'s access panel.", \
"You close the access panel.")
temp_state++
if(3)
if(O.has_tool_quality(TOOL_SCREWDRIVER))
user.visible_message("[user.name] opens the [src.name]'s access panel.", \
"You open the access panel.")
temp_state--
if(temp_state == src.construction_state)//Nothing changed
return 0
else
src.construction_state = temp_state
if(src.construction_state < 3)//Was taken apart, update state
update_state()
update_icon()
return 1
/obj/machinery/particle_accelerator
name = "Particle Accelerator"
desc = "Part of a Particle Accelerator."
icon = 'icons/obj/machines/particle_accelerator2.dmi'
icon_state = "none"
anchored = FALSE
density = TRUE
use_power = USE_POWER_OFF
idle_power_usage = 0
active_power_usage = 0
var/construction_state = 0
var/active = 0
var/reference = null
var/powered = null
var/strength = 0
var/desc_holder = null
/obj/machinery/particle_accelerator/verb/rotate_clockwise()
set name = "Rotate Clockwise"
set category = "Object"
set src in oview(1)
if (src.anchored || usr:stat)
to_chat(usr, "It is fastened to the floor!")
return 0
src.set_dir(turn(src.dir, 270))
return 1
/obj/machinery/particle_accelerator/verb/rotate_counterclockwise()
set name = "Rotate Counter-Clockwise"
set category = "Object"
set src in oview(1)
if (src.anchored || usr:stat)
to_chat(usr, "It is fastened to the floor!")
return 0
src.set_dir(turn(src.dir, 90))
return 1
/obj/machinery/particle_accelerator/update_icon()
return
/obj/machinery/particle_accelerator/examine(mob/user)
. = ..()
switch(construction_state)
if(0)
. += "Looks like it's not attached to the flooring."
if(1)
. += "It is missing some cables."
if(2)
. += "The panel is open."
if(3)
. += "It is assembled."
/obj/machinery/particle_accelerator/attackby(obj/item/W, mob/user)
if(istool(W))
if(src.process_tool_hit(W,user))
return
..()
return
/obj/machinery/particle_accelerator/ex_act(severity)
switch(severity)
if(1.0)
qdel(src)
return
if(2.0)
if (prob(50))
qdel(src)
return
if(3.0)
if (prob(25))
qdel(src)
return
else
return
/obj/machinery/particle_accelerator/proc/update_state()
return 0
/obj/machinery/particle_accelerator/proc/process_tool_hit(var/obj/item/O, var/mob/user)
if(!(O) || !(user))
return 0
if(!ismob(user) || !isobj(O))
return 0
var/temp_state = src.construction_state
switch(src.construction_state)//TODO:Might be more interesting to have it need several parts rather than a single list of steps
if(0)
if(O.has_tool_quality(TOOL_WRENCH))
playsound(src, O.usesound, 75, 1)
src.anchored = TRUE
user.visible_message("[user.name] secures the [src.name] to the floor.", \
"You secure the external bolts.")
temp_state++
if(1)
if(O.has_tool_quality(TOOL_WRENCH))
playsound(src, O.usesound, 75, 1)
src.anchored = FALSE
user.visible_message("[user.name] detaches the [src.name] from the floor.", \
"You remove the external bolts.")
temp_state--
else if(istype(O, /obj/item/stack/cable_coil))
if(O:use(1))
user.visible_message("[user.name] adds wires to the [src.name].", \
"You add some wires.")
temp_state++
if(2)
if(O.has_tool_quality(TOOL_WIRECUTTER))//TODO:Shock user if its on?
user.visible_message("[user.name] removes some wires from the [src.name].", \
"You remove some wires.")
temp_state--
else if(O.has_tool_quality(TOOL_SCREWDRIVER))
user.visible_message("[user.name] closes the [src.name]'s access panel.", \
"You close the access panel.")
temp_state++
if(3)
if(O.has_tool_quality(TOOL_SCREWDRIVER))
user.visible_message("[user.name] opens the [src.name]'s access panel.", \
"You open the access panel.")
temp_state--
active = 0
if(temp_state == src.construction_state)//Nothing changed
return 0
else
if(src.construction_state < 3)//Was taken apart, update state
update_state()
if(use_power)
update_use_power(USE_POWER_OFF)
src.construction_state = temp_state
if(src.construction_state >= 3)
update_use_power(USE_POWER_IDLE)
update_icon()
return 1
@@ -1,6 +1,6 @@
/obj/structure/particle_accelerator/fuel_chamber
name = "EM Acceleration Chamber"
desc_holder = "This is where the Alpha particles are accelerated to <b><i>radical speeds</i></b>."
icon = 'icons/obj/machines/particle_accelerator2.dmi'
icon_state = "fuel_chamber"
/obj/structure/particle_accelerator/fuel_chamber
name = "EM Acceleration Chamber"
desc_holder = "This is where the Alpha particles are accelerated to <b><i>radical speeds</i></b>."
icon = 'icons/obj/machines/particle_accelerator2.dmi'
icon_state = "fuel_chamber"
reference = "fuel_chamber"
@@ -1,253 +1,253 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33
/obj/machinery/particle_accelerator/control_box
name = "Particle Accelerator Control Computer"
desc = "This controls the density of the particles."
icon = 'icons/obj/machines/particle_accelerator_vr.dmi' //VOREStation Edit
icon_state = "control_box"
reference = "control_box"
anchored = FALSE
density = TRUE
use_power = USE_POWER_OFF
idle_power_usage = 500
active_power_usage = 70000 //70 kW per unit of strength
construction_state = 0
active = 0
dir = 1
var/strength_upper_limit = 2
var/interface_control = 1
var/list/obj/structure/particle_accelerator/connected_parts
var/assembled = 0
var/parts = null
var/datum/wires/particle_acc/control_box/wires = null
/obj/machinery/particle_accelerator/control_box/New()
wires = new(src)
connected_parts = list()
update_active_power_usage(initial(active_power_usage) * (strength + 1))
..()
/obj/machinery/particle_accelerator/control_box/Destroy()
if(active)
toggle_power()
qdel(wires)
wires = null
return ..()
/obj/machinery/particle_accelerator/control_box/attack_hand(mob/user as mob)
if(construction_state >= 3)
tgui_interact(user)
else if(construction_state == 2) // Wires exposed
wires.Interact(user)
/obj/machinery/particle_accelerator/control_box/update_state()
if(construction_state < 3)
update_use_power(USE_POWER_OFF)
assembled = 0
active = 0
for(var/obj/structure/particle_accelerator/part in connected_parts)
part.strength = null
part.powered = 0
part.update_icon()
connected_parts = list()
return
if(!part_scan())
update_use_power(USE_POWER_IDLE)
active = 0
connected_parts = list()
/obj/machinery/particle_accelerator/control_box/update_icon()
if(active)
icon_state = "[reference]p[strength]"
else
if(use_power)
if(assembled)
icon_state = "[reference]p"
else
icon_state = "u[reference]p"
else
switch(construction_state)
if(0)
icon_state = "[reference]"
if(1)
icon_state = "[reference]"
if(2)
icon_state = "[reference]w"
else
icon_state = "[reference]c"
/obj/machinery/particle_accelerator/control_box/proc/strength_change()
for(var/obj/structure/particle_accelerator/part in connected_parts)
part.strength = strength
part.update_icon()
/obj/machinery/particle_accelerator/control_box/proc/add_strength(var/s)
if(assembled)
strength++
if(strength > strength_upper_limit)
strength = strength_upper_limit
else
message_admins("PA Control Computer increased to [strength] by [key_name(usr, usr.client)][ADMIN_QUE(usr)] in [ADMIN_COORDJMP(src)]",0,1)
log_game("PACCEL([x],[y],[z]) [key_name(usr)] increased to [strength]")
investigate_log("increased to <font color='red'>[strength]</font> by [usr.key]","singulo")
strength_change()
/obj/machinery/particle_accelerator/control_box/proc/remove_strength(var/s)
if(assembled)
strength--
if(strength < 0)
strength = 0
else
message_admins("PA Control Computer decreased to [strength] by [key_name(usr, usr.client)][ADMIN_QUE(usr)] in [ADMIN_COORDJMP(src)]",0,1)
log_game("PACCEL([x],[y],[z]) [key_name(usr)] decreased to [strength]")
investigate_log("decreased to <font color='green'>[strength]</font> by [usr.key]","singulo")
strength_change()
/obj/machinery/particle_accelerator/control_box/power_change()
..()
if(stat & NOPOWER)
active = 0
update_use_power(USE_POWER_OFF)
else if(!stat && construction_state == 3)
update_use_power(USE_POWER_IDLE)
/obj/machinery/particle_accelerator/control_box/process()
if(src.active)
//a part is missing!
if( length(connected_parts) < 6 )
log_game("PACCEL([x],[y],[z]) Failed due to missing parts.")
investigate_log("lost a connected part; It <font color='red'>powered down</font>.","singulo")
toggle_power()
return
//emit some particles
for(var/obj/structure/particle_accelerator/particle_emitter/PE in connected_parts)
if(PE)
PE.emit_particle(src.strength)
/obj/machinery/particle_accelerator/control_box/proc/part_scan()
for(var/obj/structure/particle_accelerator/fuel_chamber/F in orange(1,src))
src.set_dir(F.dir)
break
connected_parts = list()
assembled = 0
var/ldir = turn(dir,90)
var/rdir = turn(dir,-90)
var/odir = turn(dir,180)
var/turf/T = src.loc
T = get_step(T,ldir)
if(!check_part(T,/obj/structure/particle_accelerator/fuel_chamber))
return 0
T = get_step(T,odir)
if(!check_part(T,/obj/structure/particle_accelerator/end_cap))
return 0
T = get_step(T,dir)
T = get_step(T,dir)
if(!check_part(T,/obj/structure/particle_accelerator/power_box))
return 0
T = get_step(T,dir)
if(!check_part(T,/obj/structure/particle_accelerator/particle_emitter/center))
return 0
T = get_step(T,ldir)
if(!check_part(T,/obj/structure/particle_accelerator/particle_emitter/left))
return 0
T = get_step(T,rdir)
T = get_step(T,rdir)
if(!check_part(T,/obj/structure/particle_accelerator/particle_emitter/right))
return 0
assembled = 1
return 1
/obj/machinery/particle_accelerator/control_box/proc/check_part(var/turf/T, var/type)
if(!(T)||!(type))
return 0
var/obj/structure/particle_accelerator/PA = locate(/obj/structure/particle_accelerator) in T
if(istype(PA, type) && PA.connect_master(src) && PA.report_ready(src))
src.connected_parts.Add(PA)
return 1
return 0
/obj/machinery/particle_accelerator/control_box/proc/toggle_power()
active = !active
investigate_log("turned [active?"<font color='red'>ON</font>":"<font color='green'>OFF</font>"] by [usr ? usr.key : "outside forces"]","singulo")
message_admins("PA Control Computer turned [active ?"ON":"OFF"] by [usr ? key_name(usr, usr.client) : "outside forces"][ADMIN_QUE(usr)] in [ADMIN_COORDJMP(src)]",0,1)
log_game("PACCEL([x],[y],[z]) [usr ? key_name(usr, usr.client) : "outside forces"] turned [active?"ON":"OFF"].")
if(active)
update_use_power(USE_POWER_ACTIVE)
for(var/obj/structure/particle_accelerator/part in connected_parts)
part.strength = src.strength
part.powered = 1
part.update_icon()
else
update_use_power(USE_POWER_IDLE)
for(var/obj/structure/particle_accelerator/part in connected_parts)
part.strength = null
part.powered = 0
part.update_icon()
return 1
/obj/machinery/particle_accelerator/control_box/proc/is_interactive(mob/user)
if(!interface_control)
to_chat(user, "<span class='alert'>ERROR: Request timed out. Check wire contacts.</span>")
return FALSE
if(construction_state != 3)
return FALSE
return TRUE
/obj/machinery/particle_accelerator/control_box/tgui_status(mob/user)
if(is_interactive(user))
return ..()
return STATUS_CLOSE
/obj/machinery/particle_accelerator/control_box/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "ParticleAccelerator", name)
ui.open()
/obj/machinery/particle_accelerator/control_box/tgui_data(mob/user)
var/list/data = list()
data["assembled"] = assembled
data["power"] = active
data["strength"] = strength
return data
/obj/machinery/particle_accelerator/control_box/tgui_act(action, params)
if(..())
return
switch(action)
if("power")
if(wires.is_cut(WIRE_POWER))
return
toggle_power()
. = TRUE
if("scan")
part_scan()
. = TRUE
if("add_strength")
if(wires.is_cut(WIRE_PARTICLE_STRENGTH))
return
add_strength()
. = TRUE
if("remove_strength")
if(wires.is_cut(WIRE_PARTICLE_STRENGTH))
return
remove_strength()
. = TRUE
update_icon()
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33
/obj/machinery/particle_accelerator/control_box
name = "Particle Accelerator Control Computer"
desc = "This controls the density of the particles."
icon = 'icons/obj/machines/particle_accelerator_vr.dmi' //VOREStation Edit
icon_state = "control_box"
reference = "control_box"
anchored = FALSE
density = TRUE
use_power = USE_POWER_OFF
idle_power_usage = 500
active_power_usage = 70000 //70 kW per unit of strength
construction_state = 0
active = 0
dir = 1
var/strength_upper_limit = 2
var/interface_control = 1
var/list/obj/structure/particle_accelerator/connected_parts
var/assembled = 0
var/parts = null
var/datum/wires/particle_acc/control_box/wires = null
/obj/machinery/particle_accelerator/control_box/New()
wires = new(src)
connected_parts = list()
update_active_power_usage(initial(active_power_usage) * (strength + 1))
..()
/obj/machinery/particle_accelerator/control_box/Destroy()
if(active)
toggle_power()
qdel(wires)
wires = null
return ..()
/obj/machinery/particle_accelerator/control_box/attack_hand(mob/user as mob)
if(construction_state >= 3)
tgui_interact(user)
else if(construction_state == 2) // Wires exposed
wires.Interact(user)
/obj/machinery/particle_accelerator/control_box/update_state()
if(construction_state < 3)
update_use_power(USE_POWER_OFF)
assembled = 0
active = 0
for(var/obj/structure/particle_accelerator/part in connected_parts)
part.strength = null
part.powered = 0
part.update_icon()
connected_parts = list()
return
if(!part_scan())
update_use_power(USE_POWER_IDLE)
active = 0
connected_parts = list()
/obj/machinery/particle_accelerator/control_box/update_icon()
if(active)
icon_state = "[reference]p[strength]"
else
if(use_power)
if(assembled)
icon_state = "[reference]p"
else
icon_state = "u[reference]p"
else
switch(construction_state)
if(0)
icon_state = "[reference]"
if(1)
icon_state = "[reference]"
if(2)
icon_state = "[reference]w"
else
icon_state = "[reference]c"
/obj/machinery/particle_accelerator/control_box/proc/strength_change()
for(var/obj/structure/particle_accelerator/part in connected_parts)
part.strength = strength
part.update_icon()
/obj/machinery/particle_accelerator/control_box/proc/add_strength(var/s)
if(assembled)
strength++
if(strength > strength_upper_limit)
strength = strength_upper_limit
else
message_admins("PA Control Computer increased to [strength] by [key_name(usr, usr.client)][ADMIN_QUE(usr)] in [ADMIN_COORDJMP(src)]",0,1)
log_game("PACCEL([x],[y],[z]) [key_name(usr)] increased to [strength]")
investigate_log("increased to <font color='red'>[strength]</font> by [usr.key]","singulo")
strength_change()
/obj/machinery/particle_accelerator/control_box/proc/remove_strength(var/s)
if(assembled)
strength--
if(strength < 0)
strength = 0
else
message_admins("PA Control Computer decreased to [strength] by [key_name(usr, usr.client)][ADMIN_QUE(usr)] in [ADMIN_COORDJMP(src)]",0,1)
log_game("PACCEL([x],[y],[z]) [key_name(usr)] decreased to [strength]")
investigate_log("decreased to <font color='green'>[strength]</font> by [usr.key]","singulo")
strength_change()
/obj/machinery/particle_accelerator/control_box/power_change()
..()
if(stat & NOPOWER)
active = 0
update_use_power(USE_POWER_OFF)
else if(!stat && construction_state == 3)
update_use_power(USE_POWER_IDLE)
/obj/machinery/particle_accelerator/control_box/process()
if(src.active)
//a part is missing!
if( length(connected_parts) < 6 )
log_game("PACCEL([x],[y],[z]) Failed due to missing parts.")
investigate_log("lost a connected part; It <font color='red'>powered down</font>.","singulo")
toggle_power()
return
//emit some particles
for(var/obj/structure/particle_accelerator/particle_emitter/PE in connected_parts)
if(PE)
PE.emit_particle(src.strength)
/obj/machinery/particle_accelerator/control_box/proc/part_scan()
for(var/obj/structure/particle_accelerator/fuel_chamber/F in orange(1,src))
src.set_dir(F.dir)
break
connected_parts = list()
assembled = 0
var/ldir = turn(dir,90)
var/rdir = turn(dir,-90)
var/odir = turn(dir,180)
var/turf/T = src.loc
T = get_step(T,ldir)
if(!check_part(T,/obj/structure/particle_accelerator/fuel_chamber))
return 0
T = get_step(T,odir)
if(!check_part(T,/obj/structure/particle_accelerator/end_cap))
return 0
T = get_step(T,dir)
T = get_step(T,dir)
if(!check_part(T,/obj/structure/particle_accelerator/power_box))
return 0
T = get_step(T,dir)
if(!check_part(T,/obj/structure/particle_accelerator/particle_emitter/center))
return 0
T = get_step(T,ldir)
if(!check_part(T,/obj/structure/particle_accelerator/particle_emitter/left))
return 0
T = get_step(T,rdir)
T = get_step(T,rdir)
if(!check_part(T,/obj/structure/particle_accelerator/particle_emitter/right))
return 0
assembled = 1
return 1
/obj/machinery/particle_accelerator/control_box/proc/check_part(var/turf/T, var/type)
if(!(T)||!(type))
return 0
var/obj/structure/particle_accelerator/PA = locate(/obj/structure/particle_accelerator) in T
if(istype(PA, type) && PA.connect_master(src) && PA.report_ready(src))
src.connected_parts.Add(PA)
return 1
return 0
/obj/machinery/particle_accelerator/control_box/proc/toggle_power()
active = !active
investigate_log("turned [active?"<font color='red'>ON</font>":"<font color='green'>OFF</font>"] by [usr ? usr.key : "outside forces"]","singulo")
message_admins("PA Control Computer turned [active ?"ON":"OFF"] by [usr ? key_name(usr, usr.client) : "outside forces"][ADMIN_QUE(usr)] in [ADMIN_COORDJMP(src)]",0,1)
log_game("PACCEL([x],[y],[z]) [usr ? key_name(usr, usr.client) : "outside forces"] turned [active?"ON":"OFF"].")
if(active)
update_use_power(USE_POWER_ACTIVE)
for(var/obj/structure/particle_accelerator/part in connected_parts)
part.strength = src.strength
part.powered = 1
part.update_icon()
else
update_use_power(USE_POWER_IDLE)
for(var/obj/structure/particle_accelerator/part in connected_parts)
part.strength = null
part.powered = 0
part.update_icon()
return 1
/obj/machinery/particle_accelerator/control_box/proc/is_interactive(mob/user)
if(!interface_control)
to_chat(user, "<span class='alert'>ERROR: Request timed out. Check wire contacts.</span>")
return FALSE
if(construction_state != 3)
return FALSE
return TRUE
/obj/machinery/particle_accelerator/control_box/tgui_status(mob/user)
if(is_interactive(user))
return ..()
return STATUS_CLOSE
/obj/machinery/particle_accelerator/control_box/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "ParticleAccelerator", name)
ui.open()
/obj/machinery/particle_accelerator/control_box/tgui_data(mob/user)
var/list/data = list()
data["assembled"] = assembled
data["power"] = active
data["strength"] = strength
return data
/obj/machinery/particle_accelerator/control_box/tgui_act(action, params)
if(..())
return
switch(action)
if("power")
if(wires.is_cut(WIRE_POWER))
return
toggle_power()
. = TRUE
if("scan")
part_scan()
. = TRUE
if("add_strength")
if(wires.is_cut(WIRE_PARTICLE_STRENGTH))
return
add_strength()
. = TRUE
if("remove_strength")
if(wires.is_cut(WIRE_PARTICLE_STRENGTH))
return
remove_strength()
. = TRUE
update_icon()
@@ -1,47 +1,47 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33
/obj/structure/particle_accelerator/particle_emitter
name = "EM Containment Grid"
desc_holder = "This launchs the Alpha particles, might not want to stand near this end."
icon = 'icons/obj/machines/particle_accelerator2.dmi'
icon_state = "none"
var/fire_delay = 50
var/last_shot = 0
/obj/structure/particle_accelerator/particle_emitter/center
icon_state = "emitter_center"
reference = "emitter_center"
/obj/structure/particle_accelerator/particle_emitter/right // It's looking for these in opposite directions.
icon_state = "emitter_left"
reference = "emitter_left"
/obj/structure/particle_accelerator/particle_emitter/left
icon_state = "emitter_right"
reference = "emitter_right"
/obj/structure/particle_accelerator/particle_emitter/proc/set_delay(var/delay)
if(delay && delay >= 0)
fire_delay = delay
return 1
return 0
/obj/structure/particle_accelerator/particle_emitter/proc/emit_particle(var/strength = 0)
if((last_shot + fire_delay) <= world.time)
last_shot = world.time
var/obj/effect/accelerated_particle/A = null
var/turf/T = src.loc // if it doesn't spawn here, it won't bump stuff directly infront of the PA
switch(strength)
if(0)
A = new/obj/effect/accelerated_particle/weak(T, dir)
if(1)
A = new/obj/effect/accelerated_particle(T, dir)
if(2)
A = new/obj/effect/accelerated_particle/strong(T, dir)
if(3)
A = new/obj/effect/accelerated_particle/powerful(T, dir)
if(A)
A.set_dir(src.dir)
return 1
return 0
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33
/obj/structure/particle_accelerator/particle_emitter
name = "EM Containment Grid"
desc_holder = "This launchs the Alpha particles, might not want to stand near this end."
icon = 'icons/obj/machines/particle_accelerator2.dmi'
icon_state = "none"
var/fire_delay = 50
var/last_shot = 0
/obj/structure/particle_accelerator/particle_emitter/center
icon_state = "emitter_center"
reference = "emitter_center"
/obj/structure/particle_accelerator/particle_emitter/right // It's looking for these in opposite directions.
icon_state = "emitter_left"
reference = "emitter_left"
/obj/structure/particle_accelerator/particle_emitter/left
icon_state = "emitter_right"
reference = "emitter_right"
/obj/structure/particle_accelerator/particle_emitter/proc/set_delay(var/delay)
if(delay && delay >= 0)
fire_delay = delay
return 1
return 0
/obj/structure/particle_accelerator/particle_emitter/proc/emit_particle(var/strength = 0)
if((last_shot + fire_delay) <= world.time)
last_shot = world.time
var/obj/effect/accelerated_particle/A = null
var/turf/T = src.loc // if it doesn't spawn here, it won't bump stuff directly infront of the PA
switch(strength)
if(0)
A = new/obj/effect/accelerated_particle/weak(T, dir)
if(1)
A = new/obj/effect/accelerated_particle(T, dir)
if(2)
A = new/obj/effect/accelerated_particle/strong(T, dir)
if(3)
A = new/obj/effect/accelerated_particle/powerful(T, dir)
if(A)
A.set_dir(src.dir)
return 1
return 0
@@ -1,6 +1,6 @@
/obj/structure/particle_accelerator/power_box
name = "Particle Focusing EM Lens"
desc_holder = "This uses electromagnetic waves to focus the Alpha-Particles."
icon = 'icons/obj/machines/particle_accelerator2.dmi'
icon_state = "power_box"
/obj/structure/particle_accelerator/power_box
name = "Particle Focusing EM Lens"
desc_holder = "This uses electromagnetic waves to focus the Alpha-Particles."
icon = 'icons/obj/machines/particle_accelerator2.dmi'
icon_state = "power_box"
reference = "power_box"
+490 -490
View File
@@ -1,490 +1,490 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33
GLOBAL_LIST_BOILERPLATE(all_singularities, /obj/singularity)
/obj/singularity/
name = "gravitational singularity"
desc = "A gravitational singularity."
icon = 'icons/obj/singularity.dmi'
icon_state = "singularity_s1"
anchored = TRUE
density = TRUE
plane = ABOVE_PLANE
light_range = 6
unacidable = TRUE //Don't comment this out.
var/current_size = 1
var/allowed_size = 1
var/contained = 1 //Are we going to move around?
var/energy = 100 //How strong are we?
var/dissipate = 1 //Do we lose energy over time?
var/dissipate_delay = 10
var/dissipate_track = 0
var/dissipate_strength = 1 //How much energy do we lose?
var/move_self = 1 //Do we move on our own?
var/grav_pull = 4 //How many tiles out do we pull?
var/consume_range = 0 //How many tiles out do we eat.
var/event_chance = 15 //Prob for event each tick.
var/target = null //Its target. Moves towards the target if it has one.
var/last_failed_movement = 0 //Will not move in the same dir if it couldnt before, will help with the getting stuck on fields thing.
var/last_warning
var/chained = 0//Adminbus chain-grab
/obj/singularity/New(loc, var/starting_energy = 50)
//CARN: admin-alert for chuckle-fuckery.
admin_investigate_setup()
energy = starting_energy
..()
START_PROCESSING(SSobj, src)
for(var/obj/machinery/power/singularity_beacon/singubeacon in machines)
if(singubeacon.active)
target = singubeacon
break
/obj/singularity/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/singularity/attack_hand(mob/user as mob)
consume(user)
return 1
/obj/singularity/ex_act(severity)
if(current_size == STAGE_SUPER)//IT'S UNSTOPPABLE
return
switch(severity)
if(1.0)
if(prob(25))
investigate_log("has been destroyed by an explosion.", I_SINGULO)
qdel(src)
return
else
energy += 50
if(2.0 to 3.0)
energy += round((rand(20,60)/2),1)
return
/obj/singularity/bullet_act(obj/item/projectile/P)
return 0 //Will there be an impact? Who knows. Will we see it? No.
/obj/singularity/Bump(atom/A)
consume(A)
/obj/singularity/Bumped(atom/A)
consume(A)
/obj/singularity/process()
eat()
dissipate()
check_energy()
if (current_size >= STAGE_TWO)
move()
pulse()
if (prob(event_chance)) //Chance for it to run a special event TODO: Come up with one or two more that fit.
event()
/obj/singularity/attack_ai() //To prevent ais from gibbing themselves when they click on one.
return
/obj/singularity/proc/admin_investigate_setup()
last_warning = world.time
var/count = locate(/obj/machinery/containment_field) in orange(30, src)
if (!count)
message_admins("A singulo has been created without containment fields active ([x], [y], [z] - <A HREF='?_src_=holder;[HrefToken()];adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>).")
investigate_log("was created. [count ? "" : "<font color='red'>No containment fields were active.</font>"]", I_SINGULO)
/obj/singularity/proc/dissipate()
if (!dissipate)
return
if(dissipate_track >= dissipate_delay)
energy -= dissipate_strength
dissipate_track = 0
else
dissipate_track++
/obj/singularity/proc/expand(var/force_size = 0, var/growing = 1)
if(current_size == STAGE_SUPER)//if this is happening, this is an error
message_admins("expand() was called on a super singulo. This should not happen. Contact a coder immediately!")
return
var/temp_allowed_size = allowed_size
if (force_size)
temp_allowed_size = force_size
switch (temp_allowed_size)
if (STAGE_ONE)
name = "gravitational singularity"
desc = "A gravitational singularity."
current_size = STAGE_ONE
icon = 'icons/obj/singularity.dmi'
icon_state = "singularity_s1"
pixel_x = 0
pixel_y = 0
grav_pull = 4
consume_range = 0
dissipate_delay = 10
dissipate_track = 0
dissipate_strength = 1
overlays = 0
if(chained)
overlays = "chain_s1"
visible_message("<span class='notice'>The singularity has shrunk to a rather pitiful size.</span>")
if (STAGE_TWO) //1 to 3 does not check for the turfs if you put the gens right next to a 1x1 then its going to eat them.
name = "gravitational singularity"
desc = "A gravitational singularity."
current_size = STAGE_TWO
icon = 'icons/effects/96x96.dmi'
icon_state = "singularity_s3"
pixel_x = -32
pixel_y = -32
grav_pull = 6
consume_range = 1
dissipate_delay = 10
dissipate_track = 0
dissipate_strength = 5
overlays = 0
if(chained)
overlays = "chain_s3"
if(growing)
visible_message("<span class='notice'>The singularity noticeably grows in size.</span>")
else
visible_message("<span class='notice'>The singularity has shrunk to a less powerful size.</span>")
if (STAGE_THREE)
if ((check_turfs_in(1, 2)) && (check_turfs_in(2, 2)) && (check_turfs_in(4, 2)) && (check_turfs_in(8, 2)))
name = "gravitational singularity"
desc = "A gravitational singularity."
current_size = STAGE_THREE
icon = 'icons/effects/160x160.dmi'
icon_state = "singularity_s5"
pixel_x = -64
pixel_y = -64
grav_pull = 8
consume_range = 2
dissipate_delay = 4
dissipate_track = 0
dissipate_strength = 20
overlays = 0
if(chained)
overlays = "chain_s5"
if(growing)
visible_message("<span class='notice'>The singularity expands to a reasonable size.</span>")
else
visible_message("<span class='notice'>The singularity has returned to a safe size.</span>")
if(STAGE_FOUR)
if ((check_turfs_in(1, 3)) && (check_turfs_in(2, 3)) && (check_turfs_in(4, 3)) && (check_turfs_in(8, 3)))
name = "gravitational singularity"
desc = "A gravitational singularity."
current_size = STAGE_FOUR
icon = 'icons/effects/224x224.dmi'
icon_state = "singularity_s7"
pixel_x = -96
pixel_y = -96
grav_pull = 10
consume_range = 3
dissipate_delay = 10
dissipate_track = 0
dissipate_strength = 8
overlays = 0
if(chained)
overlays = "chain_s7"
if(growing)
visible_message("<span class='warning'>The singularity expands to a dangerous size.</span>")
else
visible_message("<span class='notice'>Miraculously, the singularity reduces in size, and can be contained.</span>")
if(STAGE_FIVE) //This one also lacks a check for gens because it eats everything.
name = "gravitational singularity"
desc = "A gravitational singularity."
current_size = STAGE_FIVE
icon = 'icons/effects/288x288.dmi'
icon_state = "singularity_s9"
pixel_x = -128
pixel_y = -128
grav_pull = 10
consume_range = 4
dissipate = 0 //It cant go smaller due to e loss.
overlays = 0
if(chained)
overlays = "chain_s9"
if(growing)
visible_message("<span class='danger'><font size='2'>The singularity has grown out of control!</font></span>")
else
visible_message("<span class='warning'>The singularity miraculously reduces in size and loses its supermatter properties.</span>")
if(STAGE_SUPER)//SUPERSINGULO
name = "super gravitational singularity"
desc = "A gravitational singularity with the properties of supermatter. <b>It has the power to destroy worlds.</b>"
current_size = STAGE_SUPER
icon = 'icons/effects/352x352.dmi'
icon_state = "singularity_s11"//uh, whoever drew that, you know that black holes are supposed to look dark right? What's this, the clown's singulo?
pixel_x = -160
pixel_y = -160
grav_pull = 16
consume_range = 5
dissipate = 0 //It cant go smaller due to e loss
event_chance = 25 //Events will fire off more often.
if(chained)
overlays = "chain_s9"
visible_message("<span class='sinister'><font size='3'>You witness the creation of a destructive force that cannot possibly be stopped by human hands.</font></span>")
if (current_size == allowed_size)
investigate_log("<font color='red'>grew to size [current_size].</font>", I_SINGULO)
return 1
else if (current_size < (--temp_allowed_size) && current_size != STAGE_SUPER)
expand(temp_allowed_size)
else
return 0
/obj/singularity/proc/check_energy()
if (energy <= 0)
investigate_log("collapsed.", I_SINGULO)
qdel(src)
return 0
switch (energy) //Some of these numbers might need to be changed up later -Mport.
if (1 to 199)
allowed_size = STAGE_ONE
if (200 to 499)
allowed_size = STAGE_TWO
if (500 to 999)
allowed_size = STAGE_THREE
if (1000 to 1999)
allowed_size = STAGE_FOUR
if(2000 to 49999)
allowed_size = STAGE_FIVE
if(50000 to INFINITY)
allowed_size = STAGE_SUPER
if (current_size != allowed_size && current_size != STAGE_SUPER)
expand(null, current_size > allowed_size)
return 1
/obj/singularity/proc/eat()
for(var/atom/X as anything in orange(grav_pull, src))
if(!X.simulated)
continue
var/dist = get_dist(X, src)
if(dist > consume_range)
X.singularity_pull(src, current_size)
else
consume(X)
return
/obj/singularity/proc/consume(const/atom/A)
src.energy += A.singularity_act(src, current_size)
return
/obj/singularity/proc/move(var/force_move = 0)
if(!move_self)
return 0
var/movement_dir = pick(alldirs - last_failed_movement)
if(force_move)
movement_dir = force_move
if(target && prob(60))
movement_dir = get_dir(src,target) //moves to a singulo beacon, if there is one
if(current_size >= STAGE_FIVE)//The superlarge one does not care about things in its way
spawn(0)
step(src, movement_dir)
spawn(1)
step(src, movement_dir)
return 1
else if(check_turfs_in(movement_dir))
last_failed_movement = 0//Reset this because we moved
spawn(0)
step(src, movement_dir)
return 1
else
last_failed_movement = movement_dir
return 0
/obj/singularity/proc/check_turfs_in(var/direction = 0, var/step = 0)
if(!direction)
return 0
var/steps = 0
if(!step)
switch(current_size)
if(STAGE_ONE)
steps = 1
if(STAGE_TWO)
steps = 3//Yes this is right
if(STAGE_THREE)
steps = 3
if(STAGE_FOUR)
steps = 4
if(STAGE_FIVE)
steps = 5
if(STAGE_SUPER)
steps = 6
else
steps = step
var/list/turfs = list()
var/turf/T = src.loc
for(var/i = 1 to steps)
T = get_step(T,direction)
if(!isturf(T))
return 0
turfs.Add(T)
var/dir2 = 0
var/dir3 = 0
switch(direction)
if(NORTH,SOUTH)
dir2 = 4
dir3 = 8
if(EAST,WEST)
dir2 = 1
dir3 = 2
var/turf/T2 = T
for(var/j = 1 to steps)
T2 = get_step(T2,dir2)
if(!isturf(T2))
return 0
turfs.Add(T2)
for(var/k = 1 to steps)
T = get_step(T,dir3)
if(!isturf(T))
return 0
turfs.Add(T)
for(var/turf/T3 in turfs)
if(isnull(T3))
continue
if(!can_move(T3))
return 0
return 1
/obj/singularity/proc/can_move(const/turf/T)
if (!isturf(T))
return 0
// VOREStation Edit Start
var/area/A = get_area(T)
if(A.forbid_singulo) //No going to dorms
return 0
// VOREStation Edit End
if ((locate(/obj/machinery/containment_field) in T) || (locate(/obj/machinery/shieldwall) in T))
return 0
else if (locate(/obj/machinery/field_generator) in T)
var/obj/machinery/field_generator/G = locate(/obj/machinery/field_generator) in T
if (G && G.active)
return 0
else if (locate(/obj/machinery/shieldwallgen) in T)
var/obj/machinery/shieldwallgen/S = locate(/obj/machinery/shieldwallgen) in T
if (S && S.active)
return 0
return 1
/obj/singularity/proc/event()
var/numb = pick(1, 2, 3, 4, 5, 6)
switch (numb)
if (1) //EMP.
emp_area()
if (2, 3) //Tox damage all carbon mobs in area.
toxmob()
if (4) //Stun mobs who lack optic scanners.
mezzer()
else
return 0
if(current_size == STAGE_SUPER)
smwave()
return 1
/obj/singularity/proc/toxmob()
var/toxrange = 10
var/toxdamage = 4
var/radiation = 15
if (src.energy>200)
toxdamage = round(((src.energy-150)/50)*4,1)
radiation = round(((src.energy-150)/50)*5,1)
SSradiation.radiate(src, radiation) //Always radiate at max, so a decent dose of radiation is applied
for(var/mob/living/M in view(toxrange, src.loc))
if(M.status_flags & GODMODE)
continue
toxdamage = (toxdamage - (toxdamage*M.getarmor(null, "rad")))
M.apply_effect(toxdamage, TOX)
return
/obj/singularity/proc/mezzer()
for(var/mob/living/carbon/M in oviewers(8, src))
if(istype(M, /mob/living/carbon/brain)) //Ignore brains
continue
if(M.status_flags & GODMODE)
continue
if(M.stat == CONSCIOUS)
if (istype(M,/mob/living/carbon/human))
var/mob/living/carbon/human/H = M
if(istype(H.glasses,/obj/item/clothing/glasses/meson) && current_size != STAGE_SUPER)
to_chat(H, "<span class=\"notice\">You look directly into The [src.name], good thing you had your protective eyewear on!</span>")
return
else
to_chat(H, "<span class=\"warning\">You look directly into The [src.name], but your eyewear does absolutely nothing to protect you from it!</span>")
to_chat(M, "<span class='danger'>You look directly into The [src.name] and feel [current_size == STAGE_SUPER ? "helpless" : "weak"].</span>")
M.apply_effect(3, STUN)
for(var/mob/O in viewers(M, null))
O.show_message(text("<span class='danger'>[] stares blankly at The []!</span>", M, src), 1)
/obj/singularity/proc/emp_area()
if(current_size != STAGE_SUPER)
empulse(src, 4, 6, 8, 10)
else
empulse(src, 12, 14, 16, 18)
/obj/singularity/proc/smwave()
for(var/mob/living/M in view(10, src.loc))
if(prob(67))
to_chat(M, "<span class=\"warning\">You hear an uneartly ringing, then what sounds like a shrilling kettle as you are washed with a wave of heat.</span>")
to_chat(M, "<span class=\"notice\">Miraculously, it fails to kill you.</span>")
else
to_chat(M, "<span class=\"danger\">You hear an uneartly ringing, then what sounds like a shrilling kettle as you are washed with a wave of heat.</span>")
to_chat(M, "<span class=\"danger\">You don't even have a moment to react as you are reduced to ashes by the intense radiation.</span>")
M.dust()
SSradiation.radiate(src, rand(energy))
return
/obj/singularity/proc/pulse()
for(var/obj/machinery/power/rad_collector/R in rad_collectors)
if (get_dist(R, src) <= 15) //Better than using orange() every process.
R.receive_pulse(energy)
/obj/singularity/proc/on_capture()
chained = 1
overlays = 0
move_self = 0
switch (current_size)
if(STAGE_ONE)
add_overlay(image('icons/obj/singularity.dmi',"chain_s1"))
if(STAGE_TWO)
add_overlay(image('icons/effects/96x96.dmi',"chain_s3"))
if(STAGE_THREE)
add_overlay(image('icons/effects/160x160.dmi',"chain_s5"))
if(STAGE_FOUR)
add_overlay(image('icons/effects/224x224.dmi',"chain_s7"))
if(STAGE_FIVE)
add_overlay(image('icons/effects/288x288.dmi',"chain_s9"))
/obj/singularity/proc/on_release()
chained = 0
overlays = 0
move_self = 1
/obj/singularity/singularity_act(S, size)
if(current_size <= size)
var/gain = (energy/2)
var/dist = max((current_size - 2), 1)
explosion(src.loc,(dist),(dist*2),(dist*4))
spawn(0)
qdel(src)
return gain
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33
GLOBAL_LIST_BOILERPLATE(all_singularities, /obj/singularity)
/obj/singularity/
name = "gravitational singularity"
desc = "A gravitational singularity."
icon = 'icons/obj/singularity.dmi'
icon_state = "singularity_s1"
anchored = TRUE
density = TRUE
plane = ABOVE_PLANE
light_range = 6
unacidable = TRUE //Don't comment this out.
var/current_size = 1
var/allowed_size = 1
var/contained = 1 //Are we going to move around?
var/energy = 100 //How strong are we?
var/dissipate = 1 //Do we lose energy over time?
var/dissipate_delay = 10
var/dissipate_track = 0
var/dissipate_strength = 1 //How much energy do we lose?
var/move_self = 1 //Do we move on our own?
var/grav_pull = 4 //How many tiles out do we pull?
var/consume_range = 0 //How many tiles out do we eat.
var/event_chance = 15 //Prob for event each tick.
var/target = null //Its target. Moves towards the target if it has one.
var/last_failed_movement = 0 //Will not move in the same dir if it couldnt before, will help with the getting stuck on fields thing.
var/last_warning
var/chained = 0//Adminbus chain-grab
/obj/singularity/New(loc, var/starting_energy = 50)
//CARN: admin-alert for chuckle-fuckery.
admin_investigate_setup()
energy = starting_energy
..()
START_PROCESSING(SSobj, src)
for(var/obj/machinery/power/singularity_beacon/singubeacon in machines)
if(singubeacon.active)
target = singubeacon
break
/obj/singularity/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/singularity/attack_hand(mob/user as mob)
consume(user)
return 1
/obj/singularity/ex_act(severity)
if(current_size == STAGE_SUPER)//IT'S UNSTOPPABLE
return
switch(severity)
if(1.0)
if(prob(25))
investigate_log("has been destroyed by an explosion.", I_SINGULO)
qdel(src)
return
else
energy += 50
if(2.0 to 3.0)
energy += round((rand(20,60)/2),1)
return
/obj/singularity/bullet_act(obj/item/projectile/P)
return 0 //Will there be an impact? Who knows. Will we see it? No.
/obj/singularity/Bump(atom/A)
consume(A)
/obj/singularity/Bumped(atom/A)
consume(A)
/obj/singularity/process()
eat()
dissipate()
check_energy()
if (current_size >= STAGE_TWO)
move()
pulse()
if (prob(event_chance)) //Chance for it to run a special event TODO: Come up with one or two more that fit.
event()
/obj/singularity/attack_ai() //To prevent ais from gibbing themselves when they click on one.
return
/obj/singularity/proc/admin_investigate_setup()
last_warning = world.time
var/count = locate(/obj/machinery/containment_field) in orange(30, src)
if (!count)
message_admins("A singulo has been created without containment fields active ([x], [y], [z] - <A HREF='?_src_=holder;[HrefToken()];adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>).")
investigate_log("was created. [count ? "" : "<font color='red'>No containment fields were active.</font>"]", I_SINGULO)
/obj/singularity/proc/dissipate()
if (!dissipate)
return
if(dissipate_track >= dissipate_delay)
energy -= dissipate_strength
dissipate_track = 0
else
dissipate_track++
/obj/singularity/proc/expand(var/force_size = 0, var/growing = 1)
if(current_size == STAGE_SUPER)//if this is happening, this is an error
message_admins("expand() was called on a super singulo. This should not happen. Contact a coder immediately!")
return
var/temp_allowed_size = allowed_size
if (force_size)
temp_allowed_size = force_size
switch (temp_allowed_size)
if (STAGE_ONE)
name = "gravitational singularity"
desc = "A gravitational singularity."
current_size = STAGE_ONE
icon = 'icons/obj/singularity.dmi'
icon_state = "singularity_s1"
pixel_x = 0
pixel_y = 0
grav_pull = 4
consume_range = 0
dissipate_delay = 10
dissipate_track = 0
dissipate_strength = 1
overlays = 0
if(chained)
overlays = "chain_s1"
visible_message("<span class='notice'>The singularity has shrunk to a rather pitiful size.</span>")
if (STAGE_TWO) //1 to 3 does not check for the turfs if you put the gens right next to a 1x1 then its going to eat them.
name = "gravitational singularity"
desc = "A gravitational singularity."
current_size = STAGE_TWO
icon = 'icons/effects/96x96.dmi'
icon_state = "singularity_s3"
pixel_x = -32
pixel_y = -32
grav_pull = 6
consume_range = 1
dissipate_delay = 10
dissipate_track = 0
dissipate_strength = 5
overlays = 0
if(chained)
overlays = "chain_s3"
if(growing)
visible_message("<span class='notice'>The singularity noticeably grows in size.</span>")
else
visible_message("<span class='notice'>The singularity has shrunk to a less powerful size.</span>")
if (STAGE_THREE)
if ((check_turfs_in(1, 2)) && (check_turfs_in(2, 2)) && (check_turfs_in(4, 2)) && (check_turfs_in(8, 2)))
name = "gravitational singularity"
desc = "A gravitational singularity."
current_size = STAGE_THREE
icon = 'icons/effects/160x160.dmi'
icon_state = "singularity_s5"
pixel_x = -64
pixel_y = -64
grav_pull = 8
consume_range = 2
dissipate_delay = 4
dissipate_track = 0
dissipate_strength = 20
overlays = 0
if(chained)
overlays = "chain_s5"
if(growing)
visible_message("<span class='notice'>The singularity expands to a reasonable size.</span>")
else
visible_message("<span class='notice'>The singularity has returned to a safe size.</span>")
if(STAGE_FOUR)
if ((check_turfs_in(1, 3)) && (check_turfs_in(2, 3)) && (check_turfs_in(4, 3)) && (check_turfs_in(8, 3)))
name = "gravitational singularity"
desc = "A gravitational singularity."
current_size = STAGE_FOUR
icon = 'icons/effects/224x224.dmi'
icon_state = "singularity_s7"
pixel_x = -96
pixel_y = -96
grav_pull = 10
consume_range = 3
dissipate_delay = 10
dissipate_track = 0
dissipate_strength = 8
overlays = 0
if(chained)
overlays = "chain_s7"
if(growing)
visible_message("<span class='warning'>The singularity expands to a dangerous size.</span>")
else
visible_message("<span class='notice'>Miraculously, the singularity reduces in size, and can be contained.</span>")
if(STAGE_FIVE) //This one also lacks a check for gens because it eats everything.
name = "gravitational singularity"
desc = "A gravitational singularity."
current_size = STAGE_FIVE
icon = 'icons/effects/288x288.dmi'
icon_state = "singularity_s9"
pixel_x = -128
pixel_y = -128
grav_pull = 10
consume_range = 4
dissipate = 0 //It cant go smaller due to e loss.
overlays = 0
if(chained)
overlays = "chain_s9"
if(growing)
visible_message("<span class='danger'><font size='2'>The singularity has grown out of control!</font></span>")
else
visible_message("<span class='warning'>The singularity miraculously reduces in size and loses its supermatter properties.</span>")
if(STAGE_SUPER)//SUPERSINGULO
name = "super gravitational singularity"
desc = "A gravitational singularity with the properties of supermatter. <b>It has the power to destroy worlds.</b>"
current_size = STAGE_SUPER
icon = 'icons/effects/352x352.dmi'
icon_state = "singularity_s11"//uh, whoever drew that, you know that black holes are supposed to look dark right? What's this, the clown's singulo?
pixel_x = -160
pixel_y = -160
grav_pull = 16
consume_range = 5
dissipate = 0 //It cant go smaller due to e loss
event_chance = 25 //Events will fire off more often.
if(chained)
overlays = "chain_s9"
visible_message("<span class='sinister'><font size='3'>You witness the creation of a destructive force that cannot possibly be stopped by human hands.</font></span>")
if (current_size == allowed_size)
investigate_log("<font color='red'>grew to size [current_size].</font>", I_SINGULO)
return 1
else if (current_size < (--temp_allowed_size) && current_size != STAGE_SUPER)
expand(temp_allowed_size)
else
return 0
/obj/singularity/proc/check_energy()
if (energy <= 0)
investigate_log("collapsed.", I_SINGULO)
qdel(src)
return 0
switch (energy) //Some of these numbers might need to be changed up later -Mport.
if (1 to 199)
allowed_size = STAGE_ONE
if (200 to 499)
allowed_size = STAGE_TWO
if (500 to 999)
allowed_size = STAGE_THREE
if (1000 to 1999)
allowed_size = STAGE_FOUR
if(2000 to 49999)
allowed_size = STAGE_FIVE
if(50000 to INFINITY)
allowed_size = STAGE_SUPER
if (current_size != allowed_size && current_size != STAGE_SUPER)
expand(null, current_size > allowed_size)
return 1
/obj/singularity/proc/eat()
for(var/atom/X as anything in orange(grav_pull, src))
if(!X.simulated)
continue
var/dist = get_dist(X, src)
if(dist > consume_range)
X.singularity_pull(src, current_size)
else
consume(X)
return
/obj/singularity/proc/consume(const/atom/A)
src.energy += A.singularity_act(src, current_size)
return
/obj/singularity/proc/move(var/force_move = 0)
if(!move_self)
return 0
var/movement_dir = pick(alldirs - last_failed_movement)
if(force_move)
movement_dir = force_move
if(target && prob(60))
movement_dir = get_dir(src,target) //moves to a singulo beacon, if there is one
if(current_size >= STAGE_FIVE)//The superlarge one does not care about things in its way
spawn(0)
step(src, movement_dir)
spawn(1)
step(src, movement_dir)
return 1
else if(check_turfs_in(movement_dir))
last_failed_movement = 0//Reset this because we moved
spawn(0)
step(src, movement_dir)
return 1
else
last_failed_movement = movement_dir
return 0
/obj/singularity/proc/check_turfs_in(var/direction = 0, var/step = 0)
if(!direction)
return 0
var/steps = 0
if(!step)
switch(current_size)
if(STAGE_ONE)
steps = 1
if(STAGE_TWO)
steps = 3//Yes this is right
if(STAGE_THREE)
steps = 3
if(STAGE_FOUR)
steps = 4
if(STAGE_FIVE)
steps = 5
if(STAGE_SUPER)
steps = 6
else
steps = step
var/list/turfs = list()
var/turf/T = src.loc
for(var/i = 1 to steps)
T = get_step(T,direction)
if(!isturf(T))
return 0
turfs.Add(T)
var/dir2 = 0
var/dir3 = 0
switch(direction)
if(NORTH,SOUTH)
dir2 = 4
dir3 = 8
if(EAST,WEST)
dir2 = 1
dir3 = 2
var/turf/T2 = T
for(var/j = 1 to steps)
T2 = get_step(T2,dir2)
if(!isturf(T2))
return 0
turfs.Add(T2)
for(var/k = 1 to steps)
T = get_step(T,dir3)
if(!isturf(T))
return 0
turfs.Add(T)
for(var/turf/T3 in turfs)
if(isnull(T3))
continue
if(!can_move(T3))
return 0
return 1
/obj/singularity/proc/can_move(const/turf/T)
if (!isturf(T))
return 0
// VOREStation Edit Start
var/area/A = get_area(T)
if(A.forbid_singulo) //No going to dorms
return 0
// VOREStation Edit End
if ((locate(/obj/machinery/containment_field) in T) || (locate(/obj/machinery/shieldwall) in T))
return 0
else if (locate(/obj/machinery/field_generator) in T)
var/obj/machinery/field_generator/G = locate(/obj/machinery/field_generator) in T
if (G && G.active)
return 0
else if (locate(/obj/machinery/shieldwallgen) in T)
var/obj/machinery/shieldwallgen/S = locate(/obj/machinery/shieldwallgen) in T
if (S && S.active)
return 0
return 1
/obj/singularity/proc/event()
var/numb = pick(1, 2, 3, 4, 5, 6)
switch (numb)
if (1) //EMP.
emp_area()
if (2, 3) //Tox damage all carbon mobs in area.
toxmob()
if (4) //Stun mobs who lack optic scanners.
mezzer()
else
return 0
if(current_size == STAGE_SUPER)
smwave()
return 1
/obj/singularity/proc/toxmob()
var/toxrange = 10
var/toxdamage = 4
var/radiation = 15
if (src.energy>200)
toxdamage = round(((src.energy-150)/50)*4,1)
radiation = round(((src.energy-150)/50)*5,1)
SSradiation.radiate(src, radiation) //Always radiate at max, so a decent dose of radiation is applied
for(var/mob/living/M in view(toxrange, src.loc))
if(M.status_flags & GODMODE)
continue
toxdamage = (toxdamage - (toxdamage*M.getarmor(null, "rad")))
M.apply_effect(toxdamage, TOX)
return
/obj/singularity/proc/mezzer()
for(var/mob/living/carbon/M in oviewers(8, src))
if(istype(M, /mob/living/carbon/brain)) //Ignore brains
continue
if(M.status_flags & GODMODE)
continue
if(M.stat == CONSCIOUS)
if (istype(M,/mob/living/carbon/human))
var/mob/living/carbon/human/H = M
if(istype(H.glasses,/obj/item/clothing/glasses/meson) && current_size != STAGE_SUPER)
to_chat(H, "<span class=\"notice\">You look directly into The [src.name], good thing you had your protective eyewear on!</span>")
return
else
to_chat(H, "<span class=\"warning\">You look directly into The [src.name], but your eyewear does absolutely nothing to protect you from it!</span>")
to_chat(M, "<span class='danger'>You look directly into The [src.name] and feel [current_size == STAGE_SUPER ? "helpless" : "weak"].</span>")
M.apply_effect(3, STUN)
for(var/mob/O in viewers(M, null))
O.show_message(text("<span class='danger'>[] stares blankly at The []!</span>", M, src), 1)
/obj/singularity/proc/emp_area()
if(current_size != STAGE_SUPER)
empulse(src, 4, 6, 8, 10)
else
empulse(src, 12, 14, 16, 18)
/obj/singularity/proc/smwave()
for(var/mob/living/M in view(10, src.loc))
if(prob(67))
to_chat(M, "<span class=\"warning\">You hear an uneartly ringing, then what sounds like a shrilling kettle as you are washed with a wave of heat.</span>")
to_chat(M, "<span class=\"notice\">Miraculously, it fails to kill you.</span>")
else
to_chat(M, "<span class=\"danger\">You hear an uneartly ringing, then what sounds like a shrilling kettle as you are washed with a wave of heat.</span>")
to_chat(M, "<span class=\"danger\">You don't even have a moment to react as you are reduced to ashes by the intense radiation.</span>")
M.dust()
SSradiation.radiate(src, rand(energy))
return
/obj/singularity/proc/pulse()
for(var/obj/machinery/power/rad_collector/R in rad_collectors)
if (get_dist(R, src) <= 15) //Better than using orange() every process.
R.receive_pulse(energy)
/obj/singularity/proc/on_capture()
chained = 1
overlays = 0
move_self = 0
switch (current_size)
if(STAGE_ONE)
add_overlay(image('icons/obj/singularity.dmi',"chain_s1"))
if(STAGE_TWO)
add_overlay(image('icons/effects/96x96.dmi',"chain_s3"))
if(STAGE_THREE)
add_overlay(image('icons/effects/160x160.dmi',"chain_s5"))
if(STAGE_FOUR)
add_overlay(image('icons/effects/224x224.dmi',"chain_s7"))
if(STAGE_FIVE)
add_overlay(image('icons/effects/288x288.dmi',"chain_s9"))
/obj/singularity/proc/on_release()
chained = 0
overlays = 0
move_self = 1
/obj/singularity/singularity_act(S, size)
if(current_size <= size)
var/gain = (energy/2)
var/dist = max((current_size - 2), 1)
explosion(src.loc,(dist),(dist*2),(dist*4))
spawn(0)
qdel(src)
return gain
+513 -513
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+38 -38
View File
@@ -1,38 +1,38 @@
// the underfloor wiring terminal for the APC
// autogenerated when an APC is placed
// all conduit connects go to this object instead of the APC
// using this solves the problem of having the APC in a wall yet also inside an area
/obj/machinery/power/terminal
name = "terminal"
icon_state = "term"
desc = "It's an underfloor wiring terminal for power equipment."
level = 1
var/obj/machinery/power/master = null
anchored = TRUE
plane = PLATING_PLANE
layer = WIRES_LAYER+0.01
/obj/machinery/power/terminal/New()
..()
var/turf/T = src.loc
if(level==1) hide(!T.is_plating())
return
/obj/machinery/power/terminal/Destroy()
if(master)
master.disconnect_terminal(src)
master = null
return ..()
/obj/machinery/power/terminal/hide(var/i)
invisibility = i ? 101 : 0
icon_state = i ? "term-f" : "term"
/obj/machinery/power/terminal/hides_under_flooring()
return 1
/obj/machinery/power/terminal/overload(var/obj/machinery/power/source)
if(master)
master.overload(source)
// the underfloor wiring terminal for the APC
// autogenerated when an APC is placed
// all conduit connects go to this object instead of the APC
// using this solves the problem of having the APC in a wall yet also inside an area
/obj/machinery/power/terminal
name = "terminal"
icon_state = "term"
desc = "It's an underfloor wiring terminal for power equipment."
level = 1
var/obj/machinery/power/master = null
anchored = TRUE
plane = PLATING_PLANE
layer = WIRES_LAYER+0.01
/obj/machinery/power/terminal/New()
..()
var/turf/T = src.loc
if(level==1) hide(!T.is_plating())
return
/obj/machinery/power/terminal/Destroy()
if(master)
master.disconnect_terminal(src)
master = null
return ..()
/obj/machinery/power/terminal/hide(var/i)
invisibility = i ? 101 : 0
icon_state = i ? "term-f" : "term"
/obj/machinery/power/terminal/hides_under_flooring()
return 1
/obj/machinery/power/terminal/overload(var/obj/machinery/power/source)
if(master)
master.overload(source)
+77 -77
View File
@@ -1,77 +1,77 @@
//Solar tracker
//Machine that tracks the sun and reports it's direction to the solar controllers
//As long as this is working, solar panels on same powernet will track automatically
/obj/machinery/power/tracker
name = "solar tracker"
desc = "A solar directional tracker."
icon = 'icons/obj/power.dmi'
icon_state = "tracker"
anchored = TRUE
density = TRUE
use_power = USE_POWER_OFF
var/glass_type = /obj/item/stack/material/glass
var/id = 0
var/sun_angle = 0 // sun angle as set by sun datum
var/obj/machinery/power/solar_control/control = null
var/SOLAR_MAX_DIST = 40 //VOREStation Addition
/obj/machinery/power/tracker/Initialize(mapload, glass_type)
. = ..()
update_icon()
connect_to_network()
/obj/machinery/power/tracker/Destroy()
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
//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
set_dir(turn(NORTH, -angle - 22.5)) // 22.5 deg bias ensures, e.g. 67.5-112.5 is EAST
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(W.has_tool_quality(TOOL_CROWBAR))
playsound(src, '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 = new(loc)
S.tracker = TRUE
S.anchored = TRUE
new glass_type(loc, 2)
playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
user.visible_message("<span class='notice'>[user] takes the glass off the tracker.</span>")
qdel(src)
return
..()
// Tracker Electronic
/obj/item/weapon/tracker_electronics
name = "tracker electronics"
icon = 'icons/obj/doors/door_assembly.dmi'
icon_state = "door_electronics"
w_class = ITEMSIZE_SMALL
//Solar tracker
//Machine that tracks the sun and reports it's direction to the solar controllers
//As long as this is working, solar panels on same powernet will track automatically
/obj/machinery/power/tracker
name = "solar tracker"
desc = "A solar directional tracker."
icon = 'icons/obj/power.dmi'
icon_state = "tracker"
anchored = TRUE
density = TRUE
use_power = USE_POWER_OFF
var/glass_type = /obj/item/stack/material/glass
var/id = 0
var/sun_angle = 0 // sun angle as set by sun datum
var/obj/machinery/power/solar_control/control = null
var/SOLAR_MAX_DIST = 40 //VOREStation Addition
/obj/machinery/power/tracker/Initialize(mapload, glass_type)
. = ..()
update_icon()
connect_to_network()
/obj/machinery/power/tracker/Destroy()
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
//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
set_dir(turn(NORTH, -angle - 22.5)) // 22.5 deg bias ensures, e.g. 67.5-112.5 is EAST
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(W.has_tool_quality(TOOL_CROWBAR))
playsound(src, '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 = new(loc)
S.tracker = TRUE
S.anchored = TRUE
new glass_type(loc, 2)
playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
user.visible_message("<span class='notice'>[user] takes the glass off the tracker.</span>")
qdel(src)
return
..()
// Tracker Electronic
/obj/item/weapon/tracker_electronics
name = "tracker electronics"
icon = 'icons/obj/doors/door_assembly.dmi'
icon_state = "door_electronics"
w_class = ITEMSIZE_SMALL
+408 -408
View File
@@ -1,408 +1,408 @@
// TURBINE v2 AKA rev4407 Engine reborn!
// How to use it? - Mappers
//
// This is a very good power generating mechanism. All you need is a blast furnace with soaring flames and output.
// Not everything is included yet so the turbine can run out of fuel quiet quickly. The best thing about the turbine is that even
// though something is on fire that passes through it, it won't be on fire as it passes out of it. So the exhaust fumes can still
// containt unreacted fuel - plasma and oxygen that needs to be filtered out and re-routed back. This of course requires smart piping
// For a computer to work with the turbine the compressor requires a comp_id matching with the turbine computer's id. This will be
// subjected to a change in the near future mind you. Right now this method of generating power is a good backup but don't expect it
// become a main power source unless some work is done. Have fun. At 50k RPM it generates 60k power. So more than one turbine is needed!
//
// - Numbers
//
// Example setup S - sparker
// B - Blast doors into space for venting
// *BBB****BBB* C - Compressor
// S CT * T - Turbine
// * ^ * * V * D - Doors with firedoor
// **|***D**|** ^ - Fuel feed (Not vent, but a gas outlet)
// | | V - Suction vent (Like the ones in atmos
//
/obj/machinery/compressor
name = "compressor"
desc = "The compressor stage of a gas turbine generator."
icon = 'icons/obj/pipes.dmi'
icon_state = "compressor"
anchored = TRUE
density = TRUE
can_atmos_pass = ATMOS_PASS_PROC
circuit = /obj/item/weapon/circuitboard/machine/power_compressor
var/obj/machinery/power/turbine/turbine
var/datum/gas_mixture/gas_contained
var/turf/simulated/inturf
var/starter = 0
var/rpm = 0
var/rpmtarget = 0
var/capacity = 1e6
var/comp_id = 0
var/efficiency
/obj/machinery/power/turbine
name = "gas turbine generator"
desc = "A gas turbine used for backup power generation."
icon = 'icons/obj/pipes.dmi'
icon_state = "turbine"
anchored = TRUE
density = TRUE
circuit = /obj/item/weapon/circuitboard/machine/power_turbine
var/obj/machinery/compressor/compressor
var/turf/simulated/outturf
var/lastgen
var/productivity = 1
/obj/machinery/computer/turbine_computer
name = "gas turbine control computer"
desc = "A computer to remotely control a gas turbine."
icon_keyboard = "tech_key"
icon_screen = "turbinecomp"
circuit = /obj/item/weapon/circuitboard/turbine_control
var/obj/machinery/compressor/compressor
var/list/obj/machinery/door/blast/doors
var/id = 0
var/door_status = 0
/obj/item/weapon/circuitboard/machine/power_compressor
name = T_BOARD("power compressor")
build_path = /obj/machinery/compressor
board_type = new /datum/frame/frame_types/machine
origin_tech = list(TECH_MATERIAL = 4, TECH_POWER = 2)
req_components = list(/obj/item/stack/cable_coil = 5, /obj/item/weapon/stock_parts/manipulator = 6)
/obj/item/weapon/circuitboard/machine/power_turbine
name = T_BOARD("power turbine")
build_path = /obj/machinery/power/turbine
board_type = new /datum/frame/frame_types/machine
origin_tech = list(TECH_ENGINEERING = 2, TECH_POWER = 4)
req_components = list(/obj/item/stack/cable_coil = 5, /obj/item/weapon/stock_parts/capacitor = 6)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Compressor
// the inlet stage of the gas turbine electricity generator
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define COMPFRICTION 5e5
#define COMPSTARTERLOAD 2800
/obj/machinery/compressor/Initialize()
. = ..()
default_apply_parts()
gas_contained = new()
inturf = get_step(src, dir)
locate_machinery()
if(!turbine)
stat |= BROKEN
// When anchored, don't let air past us.
/obj/machinery/compressor/CanZASPass(turf/T, is_zone)
return !anchored
/obj/machinery/compressor/proc/locate_machinery()
if(turbine)
return
turbine = locate() in get_step(src, get_dir(inturf, src))
if(turbine)
turbine.locate_machinery()
/obj/machinery/compressor/RefreshParts()
var/E = 0
for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts)
E += M.rating
efficiency = E / 6
/obj/machinery/compressor/attackby(obj/item/W, mob/user)
src.add_fingerprint(user)
if(default_deconstruction_screwdriver(user, W))
return
if(default_part_replacement(user, W))
return
if(default_unfasten_wrench(user, W))
return
if(default_deconstruction_crowbar(user, W))
return
if(istype(W, /obj/item/device/multitool))
var/new_ident = tgui_input_text(usr, "Enter a new ident tag.", name, comp_id, MAX_NAME_LEN)
new_ident = sanitize(new_ident,MAX_NAME_LEN)
if(new_ident && user.Adjacent(src))
comp_id = new_ident
return
return ..()
/obj/machinery/compressor/default_unfasten_wrench(var/mob/user, var/obj/item/weapon/W, var/time = 20)
if((. = ..()))
turbine = null
if(anchored)
inturf = get_step(src, dir)
locate_machinery()
if(turbine)
to_chat(user, "<span class='notice'>Turbine connected.</span>")
stat &= ~BROKEN
else
to_chat(user, "<span class='alert'>Turbine not connected.</span>")
stat |= BROKEN
/obj/machinery/compressor/process()
if(!turbine)
stat = BROKEN
if(stat & BROKEN || panel_open)
return
if(!starter)
return
cut_overlays()
rpm = 0.9* rpm + 0.1 * rpmtarget
var/datum/gas_mixture/environment = inturf.return_air()
// It's a simplified version taking only 1/10 of the moles from the turf nearby. It should be later changed into a better version
var/transfer_moles = environment.total_moles / 10
var/datum/gas_mixture/removed = inturf.remove_air(transfer_moles)
gas_contained.merge(removed)
// RPM function to include compression friction - be advised that too low/high of a compfriction value can make things screwy
rpm = max(0, rpm - (rpm*rpm)/(COMPFRICTION*efficiency))
if(starter && !(stat & NOPOWER))
use_power(2800)
if(rpm<1000)
rpmtarget = 1000
else
if(rpm<1000)
rpmtarget = 0
if(rpm>50000)
add_overlay(image('icons/obj/pipes.dmi', "comp-o4", FLY_LAYER))
else if(rpm>10000)
add_overlay(image('icons/obj/pipes.dmi', "comp-o3", FLY_LAYER))
else if(rpm>2000)
add_overlay(image('icons/obj/pipes.dmi', "comp-o2", FLY_LAYER))
else if(rpm>500)
add_overlay(image('icons/obj/pipes.dmi', "comp-o1", FLY_LAYER))
//TODO: DEFERRED
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Turbine
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// These are crucial to working of a turbine - the stats modify the power output. TurbGenQ modifies how much raw energy can you get from
// rpms, TurbGenG modifies the shape of the curve - the lower the value the less straight the curve is.
#define TURBPRES 9000000
#define TURBGENQ 100000
#define TURBGENG 0.8
/obj/machinery/power/turbine/Initialize()
. = ..()
default_apply_parts()
// The outlet is pointed at the direction of the turbine component
outturf = get_step(src, dir)
locate_machinery()
if(!compressor)
stat |= BROKEN
/obj/machinery/power/turbine/RefreshParts()
var/P = 0
for(var/obj/item/weapon/stock_parts/capacitor/C in component_parts)
P += C.rating
productivity = P / 6
/obj/machinery/power/turbine/proc/locate_machinery()
if(compressor)
return
compressor = locate() in get_step(src, get_dir(outturf, src))
if(compressor)
compressor.locate_machinery()
/obj/machinery/power/turbine/attackby(obj/item/W, mob/user)
src.add_fingerprint(user)
if(default_deconstruction_screwdriver(user, W))
return
if(default_part_replacement(user, W))
return
if(default_unfasten_wrench(user, W))
return
if(default_deconstruction_crowbar(user, W))
return
return ..()
/obj/machinery/power/turbine/default_unfasten_wrench(var/mob/user, var/obj/item/weapon/W, var/time = 20)
if((. = ..()))
compressor = null
if(anchored)
outturf = get_step(src, dir)
locate_machinery()
if(compressor)
to_chat(user, "<span class='notice'>Compressor connected.</span>")
stat &= ~BROKEN
else
to_chat(user, "<span class='alert'>Compressor not connected.</span>")
stat |= BROKEN
/obj/machinery/power/turbine/process()
if(!compressor)
stat = BROKEN
if((stat & BROKEN) || panel_open)
return
if(!compressor.starter)
return
cut_overlays()
// This is the power generation function. If anything is needed it's good to plot it in EXCEL before modifying
// the TURBGENQ and TURBGENG values
lastgen = ((compressor.rpm / TURBGENQ)**TURBGENG) * TURBGENQ * productivity
add_avail(lastgen)
// Weird function but it works. Should be something else...
var/newrpm = ((compressor.gas_contained.temperature) * compressor.gas_contained.total_moles)/4
newrpm = max(0, newrpm)
if(!compressor.starter || newrpm > 1000)
compressor.rpmtarget = newrpm
if(compressor.gas_contained.total_moles>0)
var/oamount = min(compressor.gas_contained.total_moles, (compressor.rpm+100)/35000*compressor.capacity)
var/datum/gas_mixture/removed = compressor.gas_contained.remove(oamount)
outturf.assume_air(removed)
// If it works, put an overlay that it works!
if(lastgen > 100)
add_overlay(image('icons/obj/pipes.dmi', "turb-o", FLY_LAYER))
updateDialog()
/obj/machinery/power/turbine/attack_hand(var/mob/user as mob)
if((. = ..()))
return
src.interact(user)
/obj/machinery/power/turbine/interact(mob/user)
if(!Adjacent(user) || (stat & (NOPOWER|BROKEN)) && !issilicon(user))
user.unset_machine(src)
user << browse(null, "window=turbine")
return
user.set_machine(src)
var/t = "<TT><B>Gas Turbine Generator</B><HR><PRE>"
t += "Generated power : [DisplayPower(lastgen)]<BR><BR>"
t += "Turbine: [round(compressor.rpm)] RPM<BR>"
t += "Starter: [ compressor.starter ? "<A href='?src=\ref[src];str=1'>Off</A> <B>On</B>" : "<B>Off</B> <A href='?src=\ref[src];str=1'>On</A>"]"
t += "</PRE><HR><A href='?src=\ref[src];close=1'>Close</A>"
t += "</TT>"
var/datum/browser/popup = new(user, "turbine", name, 700, 500, src)
popup.set_content(t)
popup.open()
return
/obj/machinery/power/turbine/Topic(href, href_list)
if(..())
return
if(href_list["close"])
usr << browse(null, "window=turbine")
usr.unset_machine(src)
return
else if(href_list["str"])
if(compressor)
compressor.starter = !compressor.starter
updateDialog()
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Turbine Computer
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/obj/machinery/computer/turbine_computer/Initialize()
..()
return INITIALIZE_HINT_LATELOAD
/obj/machinery/computer/turbine_computer/LateInitialize()
locate_machinery()
/obj/machinery/computer/turbine_computer/proc/locate_machinery()
if(!id)
return
for(var/obj/machinery/compressor/C in machines)
if(C.comp_id == id)
compressor = C
LAZYINITLIST(doors)
for(var/obj/machinery/door/blast/P in machines)
if(P.id == id)
doors += P
/obj/machinery/computer/turbine_computer/attackby(obj/item/W, mob/user)
if(istype(W, /obj/item/device/multitool))
var/new_ident = tgui_input_text(usr, "Enter a new ident tag.", name, id, MAX_NAME_LEN)
new_ident = sanitize(new_ident,MAX_NAME_LEN)
if(new_ident && user.Adjacent(src))
id = new_ident
return
/obj/machinery/computer/turbine_computer/attack_hand(var/mob/user as mob)
if((. = ..()))
return
tgui_interact(user)
/obj/machinery/computer/turbine_computer/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "TurbineControl", name)
ui.open()
/obj/machinery/computer/turbine_computer/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
var/list/data = list()
data["connected"] = (compressor && compressor.turbine) ? TRUE : FALSE
data["compressor_broke"] = (!compressor || (compressor.stat & BROKEN)) ? TRUE : FALSE
data["turbine_broke"] = (!compressor || !compressor.turbine || (compressor.turbine.stat & BROKEN)) ? TRUE : FALSE
data["broken"] = (data["compressor_broke"] || data["turbine_broke"])
data["door_status"] = door_status ? TRUE : FALSE
data["online"] = FALSE
data["power"] = 0
data["rpm"] = 0
data["temp"] = 0
if(compressor && compressor.turbine)
data["online"] = compressor.starter
data["power"] = compressor.turbine.lastgen // DisplayPower
data["rpm"] = compressor.rpm
data["temp"] = compressor.gas_contained.temperature
return data
/obj/machinery/computer/turbine_computer/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
if(..())
return TRUE
switch(action)
if("power-on")
if(compressor && compressor.turbine)
compressor.starter = TRUE
. = TRUE
if("power-off")
if(compressor && compressor.turbine)
compressor.starter = FALSE
. = TRUE
if("reconnect")
locate_machinery()
. = TRUE
if("doors")
door_status = !door_status
for(var/obj/machinery/door/blast/D in src.doors)
if (door_status)
spawn(0) D.close()
else
spawn(0)D.open()
. = TRUE
#undef COMPFRICTION
#undef COMPSTARTERLOAD
#undef TURBPRES
#undef TURBGENQ
#undef TURBGENG
// TURBINE v2 AKA rev4407 Engine reborn!
// How to use it? - Mappers
//
// This is a very good power generating mechanism. All you need is a blast furnace with soaring flames and output.
// Not everything is included yet so the turbine can run out of fuel quiet quickly. The best thing about the turbine is that even
// though something is on fire that passes through it, it won't be on fire as it passes out of it. So the exhaust fumes can still
// containt unreacted fuel - plasma and oxygen that needs to be filtered out and re-routed back. This of course requires smart piping
// For a computer to work with the turbine the compressor requires a comp_id matching with the turbine computer's id. This will be
// subjected to a change in the near future mind you. Right now this method of generating power is a good backup but don't expect it
// become a main power source unless some work is done. Have fun. At 50k RPM it generates 60k power. So more than one turbine is needed!
//
// - Numbers
//
// Example setup S - sparker
// B - Blast doors into space for venting
// *BBB****BBB* C - Compressor
// S CT * T - Turbine
// * ^ * * V * D - Doors with firedoor
// **|***D**|** ^ - Fuel feed (Not vent, but a gas outlet)
// | | V - Suction vent (Like the ones in atmos
//
/obj/machinery/compressor
name = "compressor"
desc = "The compressor stage of a gas turbine generator."
icon = 'icons/obj/pipes.dmi'
icon_state = "compressor"
anchored = TRUE
density = TRUE
can_atmos_pass = ATMOS_PASS_PROC
circuit = /obj/item/weapon/circuitboard/machine/power_compressor
var/obj/machinery/power/turbine/turbine
var/datum/gas_mixture/gas_contained
var/turf/simulated/inturf
var/starter = 0
var/rpm = 0
var/rpmtarget = 0
var/capacity = 1e6
var/comp_id = 0
var/efficiency
/obj/machinery/power/turbine
name = "gas turbine generator"
desc = "A gas turbine used for backup power generation."
icon = 'icons/obj/pipes.dmi'
icon_state = "turbine"
anchored = TRUE
density = TRUE
circuit = /obj/item/weapon/circuitboard/machine/power_turbine
var/obj/machinery/compressor/compressor
var/turf/simulated/outturf
var/lastgen
var/productivity = 1
/obj/machinery/computer/turbine_computer
name = "gas turbine control computer"
desc = "A computer to remotely control a gas turbine."
icon_keyboard = "tech_key"
icon_screen = "turbinecomp"
circuit = /obj/item/weapon/circuitboard/turbine_control
var/obj/machinery/compressor/compressor
var/list/obj/machinery/door/blast/doors
var/id = 0
var/door_status = 0
/obj/item/weapon/circuitboard/machine/power_compressor
name = T_BOARD("power compressor")
build_path = /obj/machinery/compressor
board_type = new /datum/frame/frame_types/machine
origin_tech = list(TECH_MATERIAL = 4, TECH_POWER = 2)
req_components = list(/obj/item/stack/cable_coil = 5, /obj/item/weapon/stock_parts/manipulator = 6)
/obj/item/weapon/circuitboard/machine/power_turbine
name = T_BOARD("power turbine")
build_path = /obj/machinery/power/turbine
board_type = new /datum/frame/frame_types/machine
origin_tech = list(TECH_ENGINEERING = 2, TECH_POWER = 4)
req_components = list(/obj/item/stack/cable_coil = 5, /obj/item/weapon/stock_parts/capacitor = 6)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Compressor
// the inlet stage of the gas turbine electricity generator
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define COMPFRICTION 5e5
#define COMPSTARTERLOAD 2800
/obj/machinery/compressor/Initialize()
. = ..()
default_apply_parts()
gas_contained = new()
inturf = get_step(src, dir)
locate_machinery()
if(!turbine)
stat |= BROKEN
// When anchored, don't let air past us.
/obj/machinery/compressor/CanZASPass(turf/T, is_zone)
return !anchored
/obj/machinery/compressor/proc/locate_machinery()
if(turbine)
return
turbine = locate() in get_step(src, get_dir(inturf, src))
if(turbine)
turbine.locate_machinery()
/obj/machinery/compressor/RefreshParts()
var/E = 0
for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts)
E += M.rating
efficiency = E / 6
/obj/machinery/compressor/attackby(obj/item/W, mob/user)
src.add_fingerprint(user)
if(default_deconstruction_screwdriver(user, W))
return
if(default_part_replacement(user, W))
return
if(default_unfasten_wrench(user, W))
return
if(default_deconstruction_crowbar(user, W))
return
if(istype(W, /obj/item/device/multitool))
var/new_ident = tgui_input_text(usr, "Enter a new ident tag.", name, comp_id, MAX_NAME_LEN)
new_ident = sanitize(new_ident,MAX_NAME_LEN)
if(new_ident && user.Adjacent(src))
comp_id = new_ident
return
return ..()
/obj/machinery/compressor/default_unfasten_wrench(var/mob/user, var/obj/item/weapon/W, var/time = 20)
if((. = ..()))
turbine = null
if(anchored)
inturf = get_step(src, dir)
locate_machinery()
if(turbine)
to_chat(user, "<span class='notice'>Turbine connected.</span>")
stat &= ~BROKEN
else
to_chat(user, "<span class='alert'>Turbine not connected.</span>")
stat |= BROKEN
/obj/machinery/compressor/process()
if(!turbine)
stat = BROKEN
if(stat & BROKEN || panel_open)
return
if(!starter)
return
cut_overlays()
rpm = 0.9* rpm + 0.1 * rpmtarget
var/datum/gas_mixture/environment = inturf.return_air()
// It's a simplified version taking only 1/10 of the moles from the turf nearby. It should be later changed into a better version
var/transfer_moles = environment.total_moles / 10
var/datum/gas_mixture/removed = inturf.remove_air(transfer_moles)
gas_contained.merge(removed)
// RPM function to include compression friction - be advised that too low/high of a compfriction value can make things screwy
rpm = max(0, rpm - (rpm*rpm)/(COMPFRICTION*efficiency))
if(starter && !(stat & NOPOWER))
use_power(2800)
if(rpm<1000)
rpmtarget = 1000
else
if(rpm<1000)
rpmtarget = 0
if(rpm>50000)
add_overlay(image('icons/obj/pipes.dmi', "comp-o4", FLY_LAYER))
else if(rpm>10000)
add_overlay(image('icons/obj/pipes.dmi', "comp-o3", FLY_LAYER))
else if(rpm>2000)
add_overlay(image('icons/obj/pipes.dmi', "comp-o2", FLY_LAYER))
else if(rpm>500)
add_overlay(image('icons/obj/pipes.dmi', "comp-o1", FLY_LAYER))
//TODO: DEFERRED
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Turbine
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// These are crucial to working of a turbine - the stats modify the power output. TurbGenQ modifies how much raw energy can you get from
// rpms, TurbGenG modifies the shape of the curve - the lower the value the less straight the curve is.
#define TURBPRES 9000000
#define TURBGENQ 100000
#define TURBGENG 0.8
/obj/machinery/power/turbine/Initialize()
. = ..()
default_apply_parts()
// The outlet is pointed at the direction of the turbine component
outturf = get_step(src, dir)
locate_machinery()
if(!compressor)
stat |= BROKEN
/obj/machinery/power/turbine/RefreshParts()
var/P = 0
for(var/obj/item/weapon/stock_parts/capacitor/C in component_parts)
P += C.rating
productivity = P / 6
/obj/machinery/power/turbine/proc/locate_machinery()
if(compressor)
return
compressor = locate() in get_step(src, get_dir(outturf, src))
if(compressor)
compressor.locate_machinery()
/obj/machinery/power/turbine/attackby(obj/item/W, mob/user)
src.add_fingerprint(user)
if(default_deconstruction_screwdriver(user, W))
return
if(default_part_replacement(user, W))
return
if(default_unfasten_wrench(user, W))
return
if(default_deconstruction_crowbar(user, W))
return
return ..()
/obj/machinery/power/turbine/default_unfasten_wrench(var/mob/user, var/obj/item/weapon/W, var/time = 20)
if((. = ..()))
compressor = null
if(anchored)
outturf = get_step(src, dir)
locate_machinery()
if(compressor)
to_chat(user, "<span class='notice'>Compressor connected.</span>")
stat &= ~BROKEN
else
to_chat(user, "<span class='alert'>Compressor not connected.</span>")
stat |= BROKEN
/obj/machinery/power/turbine/process()
if(!compressor)
stat = BROKEN
if((stat & BROKEN) || panel_open)
return
if(!compressor.starter)
return
cut_overlays()
// This is the power generation function. If anything is needed it's good to plot it in EXCEL before modifying
// the TURBGENQ and TURBGENG values
lastgen = ((compressor.rpm / TURBGENQ)**TURBGENG) * TURBGENQ * productivity
add_avail(lastgen)
// Weird function but it works. Should be something else...
var/newrpm = ((compressor.gas_contained.temperature) * compressor.gas_contained.total_moles)/4
newrpm = max(0, newrpm)
if(!compressor.starter || newrpm > 1000)
compressor.rpmtarget = newrpm
if(compressor.gas_contained.total_moles>0)
var/oamount = min(compressor.gas_contained.total_moles, (compressor.rpm+100)/35000*compressor.capacity)
var/datum/gas_mixture/removed = compressor.gas_contained.remove(oamount)
outturf.assume_air(removed)
// If it works, put an overlay that it works!
if(lastgen > 100)
add_overlay(image('icons/obj/pipes.dmi', "turb-o", FLY_LAYER))
updateDialog()
/obj/machinery/power/turbine/attack_hand(var/mob/user as mob)
if((. = ..()))
return
src.interact(user)
/obj/machinery/power/turbine/interact(mob/user)
if(!Adjacent(user) || (stat & (NOPOWER|BROKEN)) && !issilicon(user))
user.unset_machine(src)
user << browse(null, "window=turbine")
return
user.set_machine(src)
var/t = "<TT><B>Gas Turbine Generator</B><HR><PRE>"
t += "Generated power : [DisplayPower(lastgen)]<BR><BR>"
t += "Turbine: [round(compressor.rpm)] RPM<BR>"
t += "Starter: [ compressor.starter ? "<A href='?src=\ref[src];str=1'>Off</A> <B>On</B>" : "<B>Off</B> <A href='?src=\ref[src];str=1'>On</A>"]"
t += "</PRE><HR><A href='?src=\ref[src];close=1'>Close</A>"
t += "</TT>"
var/datum/browser/popup = new(user, "turbine", name, 700, 500, src)
popup.set_content(t)
popup.open()
return
/obj/machinery/power/turbine/Topic(href, href_list)
if(..())
return
if(href_list["close"])
usr << browse(null, "window=turbine")
usr.unset_machine(src)
return
else if(href_list["str"])
if(compressor)
compressor.starter = !compressor.starter
updateDialog()
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Turbine Computer
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/obj/machinery/computer/turbine_computer/Initialize()
..()
return INITIALIZE_HINT_LATELOAD
/obj/machinery/computer/turbine_computer/LateInitialize()
locate_machinery()
/obj/machinery/computer/turbine_computer/proc/locate_machinery()
if(!id)
return
for(var/obj/machinery/compressor/C in machines)
if(C.comp_id == id)
compressor = C
LAZYINITLIST(doors)
for(var/obj/machinery/door/blast/P in machines)
if(P.id == id)
doors += P
/obj/machinery/computer/turbine_computer/attackby(obj/item/W, mob/user)
if(istype(W, /obj/item/device/multitool))
var/new_ident = tgui_input_text(usr, "Enter a new ident tag.", name, id, MAX_NAME_LEN)
new_ident = sanitize(new_ident,MAX_NAME_LEN)
if(new_ident && user.Adjacent(src))
id = new_ident
return
/obj/machinery/computer/turbine_computer/attack_hand(var/mob/user as mob)
if((. = ..()))
return
tgui_interact(user)
/obj/machinery/computer/turbine_computer/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "TurbineControl", name)
ui.open()
/obj/machinery/computer/turbine_computer/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
var/list/data = list()
data["connected"] = (compressor && compressor.turbine) ? TRUE : FALSE
data["compressor_broke"] = (!compressor || (compressor.stat & BROKEN)) ? TRUE : FALSE
data["turbine_broke"] = (!compressor || !compressor.turbine || (compressor.turbine.stat & BROKEN)) ? TRUE : FALSE
data["broken"] = (data["compressor_broke"] || data["turbine_broke"])
data["door_status"] = door_status ? TRUE : FALSE
data["online"] = FALSE
data["power"] = 0
data["rpm"] = 0
data["temp"] = 0
if(compressor && compressor.turbine)
data["online"] = compressor.starter
data["power"] = compressor.turbine.lastgen // DisplayPower
data["rpm"] = compressor.rpm
data["temp"] = compressor.gas_contained.temperature
return data
/obj/machinery/computer/turbine_computer/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
if(..())
return TRUE
switch(action)
if("power-on")
if(compressor && compressor.turbine)
compressor.starter = TRUE
. = TRUE
if("power-off")
if(compressor && compressor.turbine)
compressor.starter = FALSE
. = TRUE
if("reconnect")
locate_machinery()
. = TRUE
if("doors")
door_status = !door_status
for(var/obj/machinery/door/blast/D in src.doors)
if (door_status)
spawn(0) D.close()
else
spawn(0)D.open()
. = TRUE
#undef COMPFRICTION
#undef COMPSTARTERLOAD
#undef TURBPRES
#undef TURBGENQ
#undef TURBGENG