mirror of
https://github.com/Yawn-Wider/YWPolarisVore.git
synced 2026-08-31 00:49:34 +01:00
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:
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
+1000
-1000
File diff suppressed because it is too large
Load Diff
+291
-291
@@ -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
@@ -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
@@ -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
|
||||
|
||||
|
||||
+1181
-1181
File diff suppressed because it is too large
Load Diff
+419
-419
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
+554
-554
File diff suppressed because it is too large
Load Diff
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user