Merge remote-tracking branch 'citadel/master' into mobility_flags
This commit is contained in:
@@ -1,40 +1,40 @@
|
||||
/obj/item/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/am_containment/ex_act(severity, target)
|
||||
switch(severity)
|
||||
if(1)
|
||||
explosion(get_turf(src), 1, 2, 3, 5)//Should likely be larger but this works fine for now I guess
|
||||
if(src)
|
||||
qdel(src)
|
||||
if(2)
|
||||
if(prob((fuel/10)-stability))
|
||||
explosion(get_turf(src), 1, 2, 3, 5)
|
||||
if(src)
|
||||
qdel(src)
|
||||
return
|
||||
stability -= 40
|
||||
if(3)
|
||||
stability -= 20
|
||||
//check_stability()
|
||||
return
|
||||
|
||||
/obj/item/am_containment/proc/usefuel(wanted)
|
||||
if(fuel < wanted)
|
||||
wanted = fuel
|
||||
fuel -= wanted
|
||||
/obj/item/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/am_containment/ex_act(severity, target)
|
||||
switch(severity)
|
||||
if(1)
|
||||
explosion(get_turf(src), 1, 2, 3, 5)//Should likely be larger but this works fine for now I guess
|
||||
if(src)
|
||||
qdel(src)
|
||||
if(2)
|
||||
if(prob((fuel/10)-stability))
|
||||
explosion(get_turf(src), 1, 2, 3, 5)
|
||||
if(src)
|
||||
qdel(src)
|
||||
return
|
||||
stability -= 40
|
||||
if(3)
|
||||
stability -= 20
|
||||
//check_stability()
|
||||
return
|
||||
|
||||
/obj/item/am_containment/proc/usefuel(wanted)
|
||||
if(fuel < wanted)
|
||||
wanted = fuel
|
||||
fuel -= wanted
|
||||
return wanted
|
||||
@@ -1,357 +1,357 @@
|
||||
/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 = FALSE
|
||||
density = TRUE
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 100
|
||||
active_power_usage = 1000
|
||||
|
||||
interaction_flags_atom = INTERACT_ATOM_ATTACK_HAND | INTERACT_ATOM_UI_INTERACT | INTERACT_ATOM_REQUIRES_ANCHORED
|
||||
|
||||
var/list/obj/machinery/am_shielding/linked_shielding
|
||||
var/list/obj/machinery/am_shielding/linked_cores
|
||||
var/obj/item/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/Initialize()
|
||||
. = ..()
|
||||
linked_shielding = list()
|
||||
linked_cores = list()
|
||||
|
||||
|
||||
/obj/machinery/power/am_control_unit/Destroy()//Perhaps damage and run stability checks rather than just del on the others
|
||||
for(var/obj/machinery/am_shielding/AMS in linked_shielding)
|
||||
AMS.control_unit = null
|
||||
qdel(AMS)
|
||||
QDEL_NULL(fueljar)
|
||||
return ..()
|
||||
|
||||
|
||||
/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()
|
||||
playsound(src.loc, 'sound/machines/buzz-two.ogg', 50, 0)
|
||||
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.loc, '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.loc, 'sound/effects/bang.ogg', 50, 1)
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/power/am_control_unit/emp_act(severity)
|
||||
. = ..()
|
||||
if(. & EMP_PROTECT_SELF)
|
||||
return
|
||||
switch(severity)
|
||||
if(1)
|
||||
if(active)
|
||||
toggle_power()
|
||||
stability -= rand(15,30)
|
||||
if(2)
|
||||
if(active)
|
||||
toggle_power()
|
||||
stability -= rand(10,20)
|
||||
|
||||
/obj/machinery/power/am_control_unit/blob_act()
|
||||
stability -= 20
|
||||
if(prob(100-stability))//Might infect the rest of the machine
|
||||
for(var/obj/machinery/am_shielding/AMS in linked_shielding)
|
||||
AMS.blob_act()
|
||||
qdel(src)
|
||||
return
|
||||
check_stability()
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/power/am_control_unit/ex_act(severity, target)
|
||||
stability -= (80 - (severity * 20))
|
||||
check_stability()
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/power/am_control_unit/bullet_act(obj/item/projectile/Proj)
|
||||
. = ..()
|
||||
if(Proj.flag != "bullet")
|
||||
stability -= Proj.force
|
||||
check_stability()
|
||||
|
||||
|
||||
/obj/machinery/power/am_control_unit/power_change()
|
||||
..()
|
||||
if(stat & NOPOWER)
|
||||
if(active)
|
||||
toggle_power(1)
|
||||
else
|
||||
use_power = NO_POWER_USE
|
||||
|
||||
else if(!stat && anchored)
|
||||
use_power = IDLE_POWER_USE
|
||||
|
||||
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, params)
|
||||
if(istype(W, /obj/item/wrench))
|
||||
if(!anchored)
|
||||
W.play_tool_sound(src, 75)
|
||||
user.visible_message("[user.name] secures the [src.name] to the floor.", \
|
||||
"<span class='notice'>You secure the anchor bolts to the floor.</span>", \
|
||||
"<span class='italics'>You hear a ratchet.</span>")
|
||||
src.anchored = TRUE
|
||||
connect_to_network()
|
||||
else if(!linked_shielding.len > 0)
|
||||
W.play_tool_sound(src, 75)
|
||||
user.visible_message("[user.name] unsecures the [src.name].", \
|
||||
"<span class='notice'>You remove the anchor bolts.</span>", \
|
||||
"<span class='italics'>You hear a ratchet.</span>")
|
||||
src.anchored = FALSE
|
||||
disconnect_from_network()
|
||||
else
|
||||
to_chat(user, "<span class='warning'>Once bolted and linked to a shielding unit it the [src.name] is unable to be moved!</span>")
|
||||
|
||||
else if(istype(W, /obj/item/am_containment))
|
||||
if(fueljar)
|
||||
to_chat(user, "<span class='warning'>There is already a [fueljar] inside!</span>")
|
||||
return
|
||||
|
||||
if(!user.transferItemToLoc(W, src))
|
||||
return
|
||||
fueljar = W
|
||||
user.visible_message("[user.name] loads an [W.name] into the [src.name].", \
|
||||
"<span class='notice'>You load an [W.name].</span>", \
|
||||
"<span class='italics'>You hear a thunk.</span>")
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/machinery/power/am_control_unit/take_damage(damage, damage_type = BRUTE, sound_effect = 1)
|
||||
switch(damage_type)
|
||||
if(BRUTE)
|
||||
if(sound_effect)
|
||||
if(damage)
|
||||
playsound(loc, 'sound/weapons/smash.ogg', 50, 1)
|
||||
else
|
||||
playsound(loc, 'sound/weapons/tap.ogg', 50, 1)
|
||||
if(BURN)
|
||||
if(sound_effect)
|
||||
playsound(src.loc, 'sound/items/welder.ogg', 100, 1)
|
||||
else
|
||||
return
|
||||
if(damage >= 20)
|
||||
stability -= damage/2
|
||||
check_stability()
|
||||
|
||||
/obj/machinery/power/am_control_unit/proc/add_shielding(obj/machinery/am_shielding/AMS, 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(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(powerfail = 0)
|
||||
active = !active
|
||||
if(active)
|
||||
use_power = ACTIVE_POWER_USE
|
||||
visible_message("The [src.name] starts up.")
|
||||
else
|
||||
use_power = !powerfail
|
||||
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
|
||||
addtimer(CALLBACK(AMS, /obj/machinery/am_shielding.proc/controllerscan), 10)
|
||||
linked_shielding = list()
|
||||
else
|
||||
for(var/obj/machinery/am_shielding/AMS in linked_shielding)
|
||||
AMS.update_icon()
|
||||
addtimer(CALLBACK(src, .proc/reset_shield_icon_delay), 20)
|
||||
|
||||
/obj/machinery/power/am_control_unit/proc/reset_shield_icon_delay()
|
||||
shield_icon_delay = 0
|
||||
|
||||
/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
|
||||
addtimer(CALLBACK(src, .proc/reset_stored_core_stability_delay), 40)
|
||||
|
||||
/obj/machinery/power/am_control_unit/proc/reset_stored_core_stability_delay()
|
||||
stored_core_stability_delay = 0
|
||||
|
||||
/obj/machinery/power/am_control_unit/ui_interact(mob/user)
|
||||
. = ..()
|
||||
if((get_dist(src, user) > 1) || (stat & (BROKEN|NOPOWER)))
|
||||
if(!isAI(user))
|
||||
user.unset_machine()
|
||||
user << browse(null, "window=AMcontrol")
|
||||
return
|
||||
|
||||
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 += "Stability: [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: [DisplayPower(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)
|
||||
if(..())
|
||||
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.forceMove(drop_location())
|
||||
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 = FALSE
|
||||
density = TRUE
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 100
|
||||
active_power_usage = 1000
|
||||
|
||||
interaction_flags_atom = INTERACT_ATOM_ATTACK_HAND | INTERACT_ATOM_UI_INTERACT | INTERACT_ATOM_REQUIRES_ANCHORED
|
||||
|
||||
var/list/obj/machinery/am_shielding/linked_shielding
|
||||
var/list/obj/machinery/am_shielding/linked_cores
|
||||
var/obj/item/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/Initialize()
|
||||
. = ..()
|
||||
linked_shielding = list()
|
||||
linked_cores = list()
|
||||
|
||||
|
||||
/obj/machinery/power/am_control_unit/Destroy()//Perhaps damage and run stability checks rather than just del on the others
|
||||
for(var/obj/machinery/am_shielding/AMS in linked_shielding)
|
||||
AMS.control_unit = null
|
||||
qdel(AMS)
|
||||
QDEL_NULL(fueljar)
|
||||
return ..()
|
||||
|
||||
|
||||
/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()
|
||||
playsound(src.loc, 'sound/machines/buzz-two.ogg', 50, 0)
|
||||
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.loc, '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.loc, 'sound/effects/bang.ogg', 50, 1)
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/power/am_control_unit/emp_act(severity)
|
||||
. = ..()
|
||||
if(. & EMP_PROTECT_SELF)
|
||||
return
|
||||
switch(severity)
|
||||
if(1)
|
||||
if(active)
|
||||
toggle_power()
|
||||
stability -= rand(15,30)
|
||||
if(2)
|
||||
if(active)
|
||||
toggle_power()
|
||||
stability -= rand(10,20)
|
||||
|
||||
/obj/machinery/power/am_control_unit/blob_act()
|
||||
stability -= 20
|
||||
if(prob(100-stability))//Might infect the rest of the machine
|
||||
for(var/obj/machinery/am_shielding/AMS in linked_shielding)
|
||||
AMS.blob_act()
|
||||
qdel(src)
|
||||
return
|
||||
check_stability()
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/power/am_control_unit/ex_act(severity, target)
|
||||
stability -= (80 - (severity * 20))
|
||||
check_stability()
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/power/am_control_unit/bullet_act(obj/item/projectile/Proj)
|
||||
. = ..()
|
||||
if(Proj.flag != "bullet")
|
||||
stability -= Proj.force
|
||||
check_stability()
|
||||
|
||||
|
||||
/obj/machinery/power/am_control_unit/power_change()
|
||||
..()
|
||||
if(stat & NOPOWER)
|
||||
if(active)
|
||||
toggle_power(1)
|
||||
else
|
||||
use_power = NO_POWER_USE
|
||||
|
||||
else if(!stat && anchored)
|
||||
use_power = IDLE_POWER_USE
|
||||
|
||||
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, params)
|
||||
if(istype(W, /obj/item/wrench))
|
||||
if(!anchored)
|
||||
W.play_tool_sound(src, 75)
|
||||
user.visible_message("[user.name] secures the [src.name] to the floor.", \
|
||||
"<span class='notice'>You secure the anchor bolts to the floor.</span>", \
|
||||
"<span class='italics'>You hear a ratchet.</span>")
|
||||
src.anchored = TRUE
|
||||
connect_to_network()
|
||||
else if(!linked_shielding.len > 0)
|
||||
W.play_tool_sound(src, 75)
|
||||
user.visible_message("[user.name] unsecures the [src.name].", \
|
||||
"<span class='notice'>You remove the anchor bolts.</span>", \
|
||||
"<span class='italics'>You hear a ratchet.</span>")
|
||||
src.anchored = FALSE
|
||||
disconnect_from_network()
|
||||
else
|
||||
to_chat(user, "<span class='warning'>Once bolted and linked to a shielding unit it the [src.name] is unable to be moved!</span>")
|
||||
|
||||
else if(istype(W, /obj/item/am_containment))
|
||||
if(fueljar)
|
||||
to_chat(user, "<span class='warning'>There is already a [fueljar] inside!</span>")
|
||||
return
|
||||
|
||||
if(!user.transferItemToLoc(W, src))
|
||||
return
|
||||
fueljar = W
|
||||
user.visible_message("[user.name] loads an [W.name] into the [src.name].", \
|
||||
"<span class='notice'>You load an [W.name].</span>", \
|
||||
"<span class='italics'>You hear a thunk.</span>")
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/machinery/power/am_control_unit/take_damage(damage, damage_type = BRUTE, sound_effect = 1)
|
||||
switch(damage_type)
|
||||
if(BRUTE)
|
||||
if(sound_effect)
|
||||
if(damage)
|
||||
playsound(loc, 'sound/weapons/smash.ogg', 50, 1)
|
||||
else
|
||||
playsound(loc, 'sound/weapons/tap.ogg', 50, 1)
|
||||
if(BURN)
|
||||
if(sound_effect)
|
||||
playsound(src.loc, 'sound/items/welder.ogg', 100, 1)
|
||||
else
|
||||
return
|
||||
if(damage >= 20)
|
||||
stability -= damage/2
|
||||
check_stability()
|
||||
|
||||
/obj/machinery/power/am_control_unit/proc/add_shielding(obj/machinery/am_shielding/AMS, 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(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(powerfail = 0)
|
||||
active = !active
|
||||
if(active)
|
||||
use_power = ACTIVE_POWER_USE
|
||||
visible_message("The [src.name] starts up.")
|
||||
else
|
||||
use_power = !powerfail
|
||||
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
|
||||
addtimer(CALLBACK(AMS, /obj/machinery/am_shielding.proc/controllerscan), 10)
|
||||
linked_shielding = list()
|
||||
else
|
||||
for(var/obj/machinery/am_shielding/AMS in linked_shielding)
|
||||
AMS.update_icon()
|
||||
addtimer(CALLBACK(src, .proc/reset_shield_icon_delay), 20)
|
||||
|
||||
/obj/machinery/power/am_control_unit/proc/reset_shield_icon_delay()
|
||||
shield_icon_delay = 0
|
||||
|
||||
/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
|
||||
addtimer(CALLBACK(src, .proc/reset_stored_core_stability_delay), 40)
|
||||
|
||||
/obj/machinery/power/am_control_unit/proc/reset_stored_core_stability_delay()
|
||||
stored_core_stability_delay = 0
|
||||
|
||||
/obj/machinery/power/am_control_unit/ui_interact(mob/user)
|
||||
. = ..()
|
||||
if((get_dist(src, user) > 1) || (stat & (BROKEN|NOPOWER)))
|
||||
if(!isAI(user))
|
||||
user.unset_machine()
|
||||
user << browse(null, "window=AMcontrol")
|
||||
return
|
||||
|
||||
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 += "Stability: [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: [DisplayPower(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)
|
||||
if(..())
|
||||
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.forceMove(drop_location())
|
||||
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,253 +1,253 @@
|
||||
//like orange but only checks north/south/east/west for one step
|
||||
/proc/cardinalrange(var/center)
|
||||
var/list/things = list()
|
||||
for(var/direction in GLOB.cardinals)
|
||||
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 plasma life-form that seems to increase plasma's natural ability to react with neutrinos while reducing the combustibility."
|
||||
|
||||
icon = 'icons/obj/machines/antimatter.dmi'
|
||||
icon_state = "shield"
|
||||
density = TRUE
|
||||
dir = NORTH
|
||||
use_power = NO_POWER_USE//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 = FALSE//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, plasma in the air and stability could affect this
|
||||
var/coredirs = 0
|
||||
var/dirs = 0
|
||||
|
||||
|
||||
/obj/machinery/am_shielding/Initialize()
|
||||
. = ..()
|
||||
addtimer(CALLBACK(src, .proc/controllerscan), 10)
|
||||
|
||||
/obj/machinery/am_shielding/proc/overheat()
|
||||
visible_message("<span class='danger'>[src] melts!</span>")
|
||||
new /obj/effect/hotspot(loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/am_shielding/proc/collapse()
|
||||
visible_message("<span class='notice'>[src] collapses back into a container!</span>")
|
||||
new /obj/item/am_shielding_container(drop_location())
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/am_shielding/proc/controllerscan(priorscan = 0)
|
||||
//Make sure we are the only one here
|
||||
if(!isturf(loc))
|
||||
collapse()
|
||||
for(var/obj/machinery/am_shielding/AMS in loc.contents)
|
||||
if(AMS == src)
|
||||
continue
|
||||
collapse()
|
||||
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 GLOB.cardinals)
|
||||
for(var/obj/machinery/power/am_control_unit/AMC in cardinalrange(src))
|
||||
if(AMC.add_shielding(src))
|
||||
break
|
||||
|
||||
if(!control_unit)
|
||||
if(!priorscan)
|
||||
addtimer(CALLBACK(src, .proc/controllerscan, 1), 20)
|
||||
return
|
||||
collapse()
|
||||
|
||||
|
||||
/obj/machinery/am_shielding/Destroy()
|
||||
if(control_unit)
|
||||
control_unit.remove_shielding(src)
|
||||
if(processing)
|
||||
shutdown_core()
|
||||
//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 0
|
||||
|
||||
|
||||
/obj/machinery/am_shielding/process()
|
||||
if(!processing)
|
||||
. = PROCESS_KILL
|
||||
//TODO: core functions and stability
|
||||
//TODO: think about checking the airmix for plasma and increasing power output
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/am_shielding/emp_act()//Immune due to not really much in the way of electronics.
|
||||
return
|
||||
|
||||
/obj/machinery/am_shielding/ex_act(severity, target)
|
||||
stability -= (80 - (severity * 20))
|
||||
check_stability()
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/am_shielding/bullet_act(obj/item/projectile/Proj)
|
||||
. = ..()
|
||||
if(Proj.flag != "bullet")
|
||||
stability -= Proj.force/2
|
||||
check_stability()
|
||||
|
||||
|
||||
/obj/machinery/am_shielding/update_icon()
|
||||
dirs = 0
|
||||
coredirs = 0
|
||||
cut_overlays()
|
||||
for(var/direction in GLOB.alldirs)
|
||||
var/turf/T = get_step(loc, direction)
|
||||
for(var/obj/machinery/machine in T)
|
||||
if(istype(machine, /obj/machinery/am_shielding))
|
||||
var/obj/machinery/am_shielding/shield = machine
|
||||
if(shield.control_unit == control_unit)
|
||||
if(shield.processing)
|
||||
coredirs |= direction
|
||||
if(direction in GLOB.cardinals)
|
||||
dirs |= direction
|
||||
|
||||
else
|
||||
if(istype(machine, /obj/machinery/power/am_control_unit) && (direction in GLOB.cardinals))
|
||||
var/obj/machinery/power/am_control_unit/control = machine
|
||||
if(control == control_unit)
|
||||
dirs |= direction
|
||||
|
||||
|
||||
var/prefix = ""
|
||||
var/icondirs=dirs
|
||||
|
||||
if(coredirs)
|
||||
prefix="core"
|
||||
|
||||
icon_state = "[prefix]shield_[icondirs]"
|
||||
|
||||
if(core_check())
|
||||
add_overlay("core[control_unit && control_unit.active]")
|
||||
if(!processing)
|
||||
setup_core()
|
||||
else if(processing)
|
||||
shutdown_core()
|
||||
|
||||
|
||||
/obj/machinery/am_shielding/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1)
|
||||
switch(damage_type)
|
||||
if(BRUTE)
|
||||
if(sound_effect)
|
||||
if(damage_amount)
|
||||
playsound(loc, 'sound/weapons/smash.ogg', 50, 1)
|
||||
else
|
||||
playsound(loc, 'sound/weapons/tap.ogg', 50, 1)
|
||||
if(BURN)
|
||||
if(sound_effect)
|
||||
playsound(src.loc, 'sound/items/welder.ogg', 100, 1)
|
||||
else
|
||||
return
|
||||
if(damage_amount >= 10)
|
||||
stability -= damage_amount/2
|
||||
check_stability()
|
||||
|
||||
|
||||
//Call this to link a detected shilding unit to the controller
|
||||
/obj/machinery/am_shielding/proc/link_control(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 GLOB.alldirs)
|
||||
var/found_am_device=0
|
||||
for(var/obj/machinery/machine in get_step(loc, direction))
|
||||
if(!machine)
|
||||
continue//Need all for a core
|
||||
if(istype(machine, /obj/machinery/am_shielding) || istype(machine, /obj/machinery/power/am_control_unit))
|
||||
found_am_device = 1
|
||||
break
|
||||
if(!found_am_device)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
|
||||
/obj/machinery/am_shielding/proc/setup_core()
|
||||
processing = TRUE
|
||||
GLOB.machines |= src
|
||||
START_PROCESSING(SSmachines, 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 = FALSE
|
||||
if(!control_unit)
|
||||
return
|
||||
control_unit.linked_cores.Remove(src)
|
||||
control_unit.reported_core_efficiency -= efficiency
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/am_shielding/proc/check_stability(injecting_fuel = 0)
|
||||
if(stability > 0)
|
||||
return
|
||||
if(injecting_fuel && control_unit)
|
||||
control_unit.exploding = 1
|
||||
if(src)
|
||||
overheat()
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/am_shielding/proc/recalc_efficiency(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/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"
|
||||
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
flags_1 = CONDUCT_1
|
||||
throwforce = 5
|
||||
throw_speed = 1
|
||||
throw_range = 2
|
||||
materials = list(MAT_METAL=100)
|
||||
|
||||
/obj/item/am_shielding_container/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/multitool) && istype(src.loc, /turf))
|
||||
new/obj/machinery/am_shielding(src.loc)
|
||||
qdel(src)
|
||||
else
|
||||
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 GLOB.cardinals)
|
||||
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 plasma life-form that seems to increase plasma's natural ability to react with neutrinos while reducing the combustibility."
|
||||
|
||||
icon = 'icons/obj/machines/antimatter.dmi'
|
||||
icon_state = "shield"
|
||||
density = TRUE
|
||||
dir = NORTH
|
||||
use_power = NO_POWER_USE//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 = FALSE//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, plasma in the air and stability could affect this
|
||||
var/coredirs = 0
|
||||
var/dirs = 0
|
||||
|
||||
|
||||
/obj/machinery/am_shielding/Initialize()
|
||||
. = ..()
|
||||
addtimer(CALLBACK(src, .proc/controllerscan), 10)
|
||||
|
||||
/obj/machinery/am_shielding/proc/overheat()
|
||||
visible_message("<span class='danger'>[src] melts!</span>")
|
||||
new /obj/effect/hotspot(loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/am_shielding/proc/collapse()
|
||||
visible_message("<span class='notice'>[src] collapses back into a container!</span>")
|
||||
new /obj/item/am_shielding_container(drop_location())
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/am_shielding/proc/controllerscan(priorscan = 0)
|
||||
//Make sure we are the only one here
|
||||
if(!isturf(loc))
|
||||
collapse()
|
||||
for(var/obj/machinery/am_shielding/AMS in loc.contents)
|
||||
if(AMS == src)
|
||||
continue
|
||||
collapse()
|
||||
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 GLOB.cardinals)
|
||||
for(var/obj/machinery/power/am_control_unit/AMC in cardinalrange(src))
|
||||
if(AMC.add_shielding(src))
|
||||
break
|
||||
|
||||
if(!control_unit)
|
||||
if(!priorscan)
|
||||
addtimer(CALLBACK(src, .proc/controllerscan, 1), 20)
|
||||
return
|
||||
collapse()
|
||||
|
||||
|
||||
/obj/machinery/am_shielding/Destroy()
|
||||
if(control_unit)
|
||||
control_unit.remove_shielding(src)
|
||||
if(processing)
|
||||
shutdown_core()
|
||||
//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 0
|
||||
|
||||
|
||||
/obj/machinery/am_shielding/process()
|
||||
if(!processing)
|
||||
. = PROCESS_KILL
|
||||
//TODO: core functions and stability
|
||||
//TODO: think about checking the airmix for plasma and increasing power output
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/am_shielding/emp_act()//Immune due to not really much in the way of electronics.
|
||||
return
|
||||
|
||||
/obj/machinery/am_shielding/ex_act(severity, target)
|
||||
stability -= (80 - (severity * 20))
|
||||
check_stability()
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/am_shielding/bullet_act(obj/item/projectile/Proj)
|
||||
. = ..()
|
||||
if(Proj.flag != "bullet")
|
||||
stability -= Proj.force/2
|
||||
check_stability()
|
||||
|
||||
|
||||
/obj/machinery/am_shielding/update_icon()
|
||||
dirs = 0
|
||||
coredirs = 0
|
||||
cut_overlays()
|
||||
for(var/direction in GLOB.alldirs)
|
||||
var/turf/T = get_step(loc, direction)
|
||||
for(var/obj/machinery/machine in T)
|
||||
if(istype(machine, /obj/machinery/am_shielding))
|
||||
var/obj/machinery/am_shielding/shield = machine
|
||||
if(shield.control_unit == control_unit)
|
||||
if(shield.processing)
|
||||
coredirs |= direction
|
||||
if(direction in GLOB.cardinals)
|
||||
dirs |= direction
|
||||
|
||||
else
|
||||
if(istype(machine, /obj/machinery/power/am_control_unit) && (direction in GLOB.cardinals))
|
||||
var/obj/machinery/power/am_control_unit/control = machine
|
||||
if(control == control_unit)
|
||||
dirs |= direction
|
||||
|
||||
|
||||
var/prefix = ""
|
||||
var/icondirs=dirs
|
||||
|
||||
if(coredirs)
|
||||
prefix="core"
|
||||
|
||||
icon_state = "[prefix]shield_[icondirs]"
|
||||
|
||||
if(core_check())
|
||||
add_overlay("core[control_unit && control_unit.active]")
|
||||
if(!processing)
|
||||
setup_core()
|
||||
else if(processing)
|
||||
shutdown_core()
|
||||
|
||||
|
||||
/obj/machinery/am_shielding/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1)
|
||||
switch(damage_type)
|
||||
if(BRUTE)
|
||||
if(sound_effect)
|
||||
if(damage_amount)
|
||||
playsound(loc, 'sound/weapons/smash.ogg', 50, 1)
|
||||
else
|
||||
playsound(loc, 'sound/weapons/tap.ogg', 50, 1)
|
||||
if(BURN)
|
||||
if(sound_effect)
|
||||
playsound(src.loc, 'sound/items/welder.ogg', 100, 1)
|
||||
else
|
||||
return
|
||||
if(damage_amount >= 10)
|
||||
stability -= damage_amount/2
|
||||
check_stability()
|
||||
|
||||
|
||||
//Call this to link a detected shilding unit to the controller
|
||||
/obj/machinery/am_shielding/proc/link_control(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 GLOB.alldirs)
|
||||
var/found_am_device=0
|
||||
for(var/obj/machinery/machine in get_step(loc, direction))
|
||||
if(!machine)
|
||||
continue//Need all for a core
|
||||
if(istype(machine, /obj/machinery/am_shielding) || istype(machine, /obj/machinery/power/am_control_unit))
|
||||
found_am_device = 1
|
||||
break
|
||||
if(!found_am_device)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
|
||||
/obj/machinery/am_shielding/proc/setup_core()
|
||||
processing = TRUE
|
||||
GLOB.machines |= src
|
||||
START_PROCESSING(SSmachines, 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 = FALSE
|
||||
if(!control_unit)
|
||||
return
|
||||
control_unit.linked_cores.Remove(src)
|
||||
control_unit.reported_core_efficiency -= efficiency
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/am_shielding/proc/check_stability(injecting_fuel = 0)
|
||||
if(stability > 0)
|
||||
return
|
||||
if(injecting_fuel && control_unit)
|
||||
control_unit.exploding = 1
|
||||
if(src)
|
||||
overheat()
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/am_shielding/proc/recalc_efficiency(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/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"
|
||||
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
flags_1 = CONDUCT_1
|
||||
throwforce = 5
|
||||
throw_speed = 1
|
||||
throw_range = 2
|
||||
materials = list(MAT_METAL=100)
|
||||
|
||||
/obj/item/am_shielding_container/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/multitool) && istype(src.loc, /turf))
|
||||
new/obj/machinery/am_shielding(src.loc)
|
||||
qdel(src)
|
||||
else
|
||||
return ..()
|
||||
|
||||
+85
-15
@@ -98,6 +98,7 @@
|
||||
var/force_update = 0
|
||||
var/emergency_lights = FALSE
|
||||
var/nightshift_lights = FALSE
|
||||
var/nightshift_requires_auth = FALSE
|
||||
var/last_nightshift_switch = 0
|
||||
var/update_state = -1
|
||||
var/update_overlay = -1
|
||||
@@ -239,6 +240,7 @@
|
||||
update_icon()
|
||||
|
||||
make_terminal()
|
||||
update_nightshift_auth_requirement()
|
||||
|
||||
addtimer(CALLBACK(src, .proc/update), 5)
|
||||
|
||||
@@ -701,6 +703,52 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/apc/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd)
|
||||
if(the_rcd.upgrade & RCD_UPGRADE_SIMPLE_CIRCUITS)
|
||||
if(!has_electronics)
|
||||
if(stat & BROKEN)
|
||||
to_chat(user, "<span class='warning'>[src]'s frame is too damaged to support a circuit.</span>")
|
||||
return FALSE
|
||||
return list("mode" = RCD_UPGRADE_SIMPLE_CIRCUITS, "delay" = 20, "cost" = 1)
|
||||
else if(!cell)
|
||||
if(stat & MAINT)
|
||||
to_chat(user, "<span class='warning'>There's no connector for a power cell.</span>")
|
||||
return FALSE
|
||||
return list("mode" = RCD_UPGRADE_SIMPLE_CIRCUITS, "delay" = 50, "cost" = 10) //16 for a wall
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[src] has both electronics and a cell.</span>")
|
||||
return FALSE
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/power/apc/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode)
|
||||
switch(passed_mode)
|
||||
if(RCD_UPGRADE_SIMPLE_CIRCUITS)
|
||||
if(!has_electronics)
|
||||
if(stat & BROKEN)
|
||||
to_chat(user, "<span class='warning'>[src]'s frame is too damaged to support a circuit.</span>")
|
||||
return
|
||||
user.visible_message("<span class='notice'>[user] fabricates a circuit and places it into [src].</span>", \
|
||||
"<span class='notice'>You adapt a power control board and click it into place in [src]'s guts.</span>")
|
||||
has_electronics = TRUE
|
||||
locked = TRUE
|
||||
return TRUE
|
||||
else if(!cell)
|
||||
if(stat & MAINT)
|
||||
to_chat(user, "<span class='warning'>There's no connector for a power cell.</span>")
|
||||
return FALSE
|
||||
var/obj/item/stock_parts/cell/crap/empty/C = new(src)
|
||||
C.forceMove(src)
|
||||
cell = C
|
||||
chargecount = 0
|
||||
user.visible_message("<span class='notice'>[user] fabricates a weak power cell and places it into [src].</span>", \
|
||||
"<span class='warning'>Your [the_rcd.name] whirrs with strain as you create a weak power cell and place it into [src]!</span>")
|
||||
update_icon()
|
||||
return TRUE
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[src] has both electronics and a cell.</span>")
|
||||
return FALSE
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/power/apc/AltClick(mob/user)
|
||||
. = ..()
|
||||
if(!user.canUseTopic(src, !issilicon(user)) || !isturf(loc))
|
||||
@@ -806,6 +854,7 @@
|
||||
/obj/machinery/power/apc/ui_data(mob/user)
|
||||
var/list/data = list(
|
||||
"locked" = locked && !(integration_cog && is_servant_of_ratvar(user)),
|
||||
"lock_nightshift" = nightshift_requires_auth,
|
||||
"failTime" = failure_timer,
|
||||
"isOperating" = operating,
|
||||
"externalPower" = main_status,
|
||||
@@ -913,7 +962,18 @@
|
||||
. = UI_INTERACTIVE
|
||||
|
||||
/obj/machinery/power/apc/ui_act(action, params)
|
||||
if(..() || !can_use(usr, 1) || (locked && !usr.has_unlimited_silicon_privilege && !failure_timer && !(integration_cog && (is_servant_of_ratvar(usr)))))
|
||||
if(..() || !can_use(usr, 1))
|
||||
return
|
||||
if(failure_timer)
|
||||
if(action == "reboot")
|
||||
failure_timer = 0
|
||||
update_icon()
|
||||
update()
|
||||
var/authorized = (!locked || usr.has_unlimited_silicon_privilege || (integration_cog && (is_servant_of_ratvar(usr))))
|
||||
if((action == "toggle_nightshift") && (!nightshift_requires_auth || authorized))
|
||||
toggle_nightshift_lights()
|
||||
return TRUE
|
||||
if(!authorized)
|
||||
return
|
||||
switch(action)
|
||||
if("lock")
|
||||
@@ -923,22 +983,19 @@
|
||||
else
|
||||
locked = !locked
|
||||
update_icon()
|
||||
. = TRUE
|
||||
return TRUE
|
||||
if("cover")
|
||||
coverlocked = !coverlocked
|
||||
. = TRUE
|
||||
return TRUE
|
||||
if("breaker")
|
||||
toggle_breaker()
|
||||
. = TRUE
|
||||
if("toggle_nightshift")
|
||||
toggle_nightshift_lights()
|
||||
. = TRUE
|
||||
return TRUE
|
||||
if("charge")
|
||||
chargemode = !chargemode
|
||||
if(!chargemode)
|
||||
charging = APC_NOT_CHARGING
|
||||
update_icon()
|
||||
. = TRUE
|
||||
return TRUE
|
||||
if("channel")
|
||||
if(params["eqp"])
|
||||
equipment = setsubsystem(text2num(params["eqp"]))
|
||||
@@ -952,24 +1009,23 @@
|
||||
environ = setsubsystem(text2num(params["env"]))
|
||||
update_icon()
|
||||
update()
|
||||
. = TRUE
|
||||
return TRUE
|
||||
if("overload")
|
||||
if(usr.has_unlimited_silicon_privilege)
|
||||
overload_lighting()
|
||||
. = TRUE
|
||||
return TRUE
|
||||
if("hack")
|
||||
if(get_malf_status(usr))
|
||||
malfhack(usr)
|
||||
return TRUE
|
||||
if("occupy")
|
||||
if(get_malf_status(usr))
|
||||
malfoccupy(usr)
|
||||
return TRUE
|
||||
if("deoccupy")
|
||||
if(get_malf_status(usr))
|
||||
malfvacate()
|
||||
if("reboot")
|
||||
failure_timer = 0
|
||||
update_icon()
|
||||
update()
|
||||
return TRUE
|
||||
if("emergency_lighting")
|
||||
emergency_lights = !emergency_lights
|
||||
for(var/obj/machinery/light/L in area)
|
||||
@@ -977,7 +1033,7 @@
|
||||
L.no_emergency = emergency_lights
|
||||
INVOKE_ASYNC(L, /obj/machinery/light/.proc/update, FALSE)
|
||||
CHECK_TICK
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/apc/proc/toggle_breaker()
|
||||
if(!is_operational() || failure_timer)
|
||||
@@ -1383,6 +1439,8 @@
|
||||
|
||||
/obj/machinery/power/apc/proc/set_nightshift(on)
|
||||
set waitfor = FALSE
|
||||
if(nightshift_lights == on)
|
||||
return
|
||||
nightshift_lights = on
|
||||
for(var/obj/machinery/light/L in area)
|
||||
if(L.nightshift_allowed)
|
||||
@@ -1390,6 +1448,18 @@
|
||||
L.update(FALSE)
|
||||
CHECK_TICK
|
||||
|
||||
/obj/machinery/power/apc/proc/update_nightshift_auth_requirement()
|
||||
nightshift_requires_auth = nightshift_toggle_requires_auth()
|
||||
|
||||
/obj/machinery/power/apc/proc/nightshift_toggle_requires_auth()
|
||||
if(!area)
|
||||
return FALSE
|
||||
var/configured_level = CONFIG_GET(number/night_shift_public_areas_only)
|
||||
var/our_level = area.nightshift_public_area
|
||||
var/public_requires_auth = CONFIG_GET(flag/nightshift_toggle_public_requires_auth)
|
||||
var/normal_requires_auth = CONFIG_GET(flag/nightshift_toggle_requires_auth)
|
||||
return (configured_level && our_level && ((our_level <= configured_level)? public_requires_auth : normal_requires_auth))
|
||||
|
||||
#undef UPSTATE_CELL_IN
|
||||
#undef UPSTATE_OPENED1
|
||||
#undef UPSTATE_OPENED2
|
||||
|
||||
+850
-850
File diff suppressed because it is too large
Load Diff
+366
-366
@@ -1,366 +1,366 @@
|
||||
/obj/item/stock_parts/cell
|
||||
name = "power cell"
|
||||
desc = "A rechargeable electrochemical power cell."
|
||||
icon = 'icons/obj/power.dmi'
|
||||
icon_state = "cell"
|
||||
item_state = "cell"
|
||||
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
|
||||
force = 5
|
||||
throwforce = 5
|
||||
throw_speed = 2
|
||||
throw_range = 5
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
var/charge = 0 // note %age conveted to actual charge in New
|
||||
var/maxcharge = 1000
|
||||
materials = list(MAT_METAL=700, MAT_GLASS=50)
|
||||
grind_results = list("lithium" = 15, "iron" = 5, "silicon" = 5)
|
||||
var/rigged = FALSE // true if rigged to explode
|
||||
var/chargerate = 100 //how much power is given every tick in a recharger
|
||||
var/self_recharge = 0 //does it self recharge, over time, or not?
|
||||
var/ratingdesc = TRUE
|
||||
var/grown_battery = FALSE // If it's a grown that acts as a battery, add a wire overlay to it.
|
||||
rad_flags = RAD_NO_CONTAMINATE // Prevent the same cheese as with the stock parts
|
||||
|
||||
/obj/item/stock_parts/cell/get_cell()
|
||||
return src
|
||||
|
||||
/obj/item/stock_parts/cell/Initialize(mapload, override_maxcharge)
|
||||
. = ..()
|
||||
if(self_recharge)
|
||||
START_PROCESSING(SSobj, src)
|
||||
create_reagents(5, INJECTABLE | DRAINABLE)
|
||||
if (override_maxcharge)
|
||||
maxcharge = override_maxcharge
|
||||
charge = maxcharge
|
||||
if(ratingdesc)
|
||||
desc += " This one has a rating of [DisplayEnergy(maxcharge)], and you should not swallow it."
|
||||
update_icon()
|
||||
|
||||
/obj/item/stock_parts/cell/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/stock_parts/cell/vv_edit_var(var_name, var_value)
|
||||
switch(var_name)
|
||||
if("self_recharge")
|
||||
if(var_value)
|
||||
START_PROCESSING(SSobj, src)
|
||||
else
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
. = ..()
|
||||
|
||||
/obj/item/stock_parts/cell/process()
|
||||
if(self_recharge)
|
||||
give(chargerate * 0.25)
|
||||
else
|
||||
return PROCESS_KILL
|
||||
|
||||
/obj/item/stock_parts/cell/update_icon()
|
||||
cut_overlays()
|
||||
if(grown_battery)
|
||||
add_overlay(image('icons/obj/power.dmi',"grown_wires"))
|
||||
if(charge < 0.01)
|
||||
return
|
||||
else if(charge/maxcharge >=0.995)
|
||||
add_overlay("cell-o2")
|
||||
else
|
||||
add_overlay("cell-o1")
|
||||
|
||||
/obj/item/stock_parts/cell/proc/percent() // return % charge of cell
|
||||
return 100*charge/maxcharge
|
||||
|
||||
// use power from a cell
|
||||
/obj/item/stock_parts/cell/use(amount, can_explode = TRUE)
|
||||
if(rigged && amount > 0 && can_explode)
|
||||
explode()
|
||||
return 0
|
||||
if(charge < amount)
|
||||
return 0
|
||||
charge = (charge - amount)
|
||||
if(!istype(loc, /obj/machinery/power/apc))
|
||||
SSblackbox.record_feedback("tally", "cell_used", 1, type)
|
||||
return 1
|
||||
|
||||
// recharge the cell
|
||||
/obj/item/stock_parts/cell/proc/give(amount)
|
||||
if(rigged && amount > 0)
|
||||
explode()
|
||||
return 0
|
||||
if(maxcharge < amount)
|
||||
amount = maxcharge
|
||||
var/power_used = min(maxcharge-charge,amount)
|
||||
charge += power_used
|
||||
return power_used
|
||||
|
||||
/obj/item/stock_parts/cell/examine(mob/user)
|
||||
. = ..()
|
||||
if(rigged)
|
||||
. += "<span class='danger'>This power cell seems to be faulty!</span>"
|
||||
else
|
||||
. += "The charge meter reads [round(src.percent() )]%."
|
||||
|
||||
/obj/item/stock_parts/cell/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] is licking the electrodes of [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
return (FIRELOSS)
|
||||
|
||||
/obj/item/stock_parts/cell/on_reagent_change(changetype)
|
||||
..()
|
||||
rigged = reagents?.has_reagent("plasma", 5) ? TRUE : FALSE //has_reagent returns the reagent datum
|
||||
|
||||
/obj/item/stock_parts/cell/proc/explode()
|
||||
var/turf/T = get_turf(src.loc)
|
||||
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 = FALSE
|
||||
corrupt()
|
||||
return
|
||||
//explosion(T, 0, 1, 2, 2)
|
||||
explosion(T, devastation_range, heavy_impact_range, light_impact_range, flash_range)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/stock_parts/cell/proc/corrupt()
|
||||
charge /= 2
|
||||
maxcharge = max(maxcharge/2, chargerate)
|
||||
if (prob(10))
|
||||
rigged = TRUE //broken batterys are dangerous
|
||||
|
||||
/obj/item/stock_parts/cell/emp_act(severity)
|
||||
. = ..()
|
||||
if(. & EMP_PROTECT_SELF)
|
||||
return
|
||||
charge -= 1000 / severity
|
||||
if (charge < 0)
|
||||
charge = 0
|
||||
|
||||
/obj/item/stock_parts/cell/ex_act(severity, target)
|
||||
..()
|
||||
if(!QDELETED(src))
|
||||
switch(severity)
|
||||
if(2)
|
||||
if(prob(50))
|
||||
corrupt()
|
||||
if(3)
|
||||
if(prob(25))
|
||||
corrupt()
|
||||
|
||||
|
||||
/obj/item/stock_parts/cell/blob_act(obj/structure/blob/B)
|
||||
ex_act(EXPLODE_DEVASTATE)
|
||||
|
||||
/obj/item/stock_parts/cell/proc/get_electrocute_damage()
|
||||
if(charge >= 1000)
|
||||
return CLAMP(round(charge/10000), 10, 90) + rand(-5,5)
|
||||
else
|
||||
return 0
|
||||
|
||||
/obj/item/stock_parts/cell/get_part_rating()
|
||||
return rating * maxcharge
|
||||
|
||||
/* Cell variants*/
|
||||
/obj/item/stock_parts/cell/empty/Initialize()
|
||||
. = ..()
|
||||
charge = 0
|
||||
|
||||
/obj/item/stock_parts/cell/crap
|
||||
name = "\improper Nanotrasen brand rechargeable AA battery"
|
||||
desc = "You can't top the plasma top." //TOTALLY TRADEMARK INFRINGEMENT
|
||||
maxcharge = 500
|
||||
materials = list(MAT_GLASS=40)
|
||||
|
||||
/obj/item/stock_parts/cell/crap/empty/Initialize()
|
||||
. = ..()
|
||||
charge = 0
|
||||
update_icon()
|
||||
|
||||
/obj/item/stock_parts/cell/upgraded
|
||||
name = "upgraded power cell"
|
||||
desc = "A power cell with a slightly higher capacity than normal!"
|
||||
maxcharge = 2500
|
||||
materials = list(MAT_GLASS=50)
|
||||
chargerate = 1000
|
||||
|
||||
/obj/item/stock_parts/cell/upgraded/plus
|
||||
name = "upgraded power cell+"
|
||||
desc = "A power cell with an even higher capacity than the base model!"
|
||||
maxcharge = 5000
|
||||
|
||||
/obj/item/stock_parts/cell/secborg
|
||||
name = "security borg rechargeable D battery"
|
||||
maxcharge = 1250 //25/12/6 disabler/laser/taser shots.
|
||||
materials = list(MAT_GLASS=40)
|
||||
|
||||
/obj/item/stock_parts/cell/secborg/empty/Initialize()
|
||||
. = ..()
|
||||
charge = 0
|
||||
update_icon()
|
||||
|
||||
/obj/item/stock_parts/cell/lascarbine
|
||||
name = "laser carbine power supply"
|
||||
maxcharge = 1500 //20 laser shots.
|
||||
|
||||
/obj/item/stock_parts/cell/pulse //200 pulse shots
|
||||
name = "pulse rifle power cell"
|
||||
maxcharge = 40000
|
||||
chargerate = 1500
|
||||
|
||||
/obj/item/stock_parts/cell/pulse/carbine //25 pulse shots
|
||||
name = "pulse carbine power cell"
|
||||
maxcharge = 5000
|
||||
|
||||
/obj/item/stock_parts/cell/pulse/pistol //10 pulse shots
|
||||
name = "pulse pistol power cell"
|
||||
maxcharge = 2000
|
||||
|
||||
/obj/item/stock_parts/cell/high
|
||||
name = "high-capacity power cell"
|
||||
icon_state = "hcell"
|
||||
maxcharge = 10000
|
||||
materials = list(MAT_GLASS=60)
|
||||
chargerate = 1500
|
||||
|
||||
/obj/item/stock_parts/cell/high/plus
|
||||
name = "high-capacity power cell+"
|
||||
desc = "Where did these come from?"
|
||||
icon_state = "h+cell"
|
||||
maxcharge = 15000
|
||||
chargerate = 2250
|
||||
|
||||
/obj/item/stock_parts/cell/high/empty/Initialize()
|
||||
. = ..()
|
||||
charge = 0
|
||||
update_icon()
|
||||
|
||||
/obj/item/stock_parts/cell/super
|
||||
name = "super-capacity power cell"
|
||||
icon_state = "scell"
|
||||
maxcharge = 20000
|
||||
materials = list(MAT_GLASS=300)
|
||||
chargerate = 2000
|
||||
|
||||
/obj/item/stock_parts/cell/super/empty/Initialize()
|
||||
. = ..()
|
||||
charge = 0
|
||||
update_icon()
|
||||
|
||||
/obj/item/stock_parts/cell/hyper
|
||||
name = "hyper-capacity power cell"
|
||||
icon_state = "hpcell"
|
||||
maxcharge = 30000
|
||||
materials = list(MAT_GLASS=400)
|
||||
chargerate = 3000
|
||||
|
||||
/obj/item/stock_parts/cell/hyper/empty/Initialize()
|
||||
. = ..()
|
||||
charge = 0
|
||||
update_icon()
|
||||
|
||||
/obj/item/stock_parts/cell/bluespace
|
||||
name = "bluespace power cell"
|
||||
desc = "A rechargeable transdimensional power cell."
|
||||
icon_state = "bscell"
|
||||
maxcharge = 40000
|
||||
materials = list(MAT_GLASS=600)
|
||||
chargerate = 4000
|
||||
|
||||
/obj/item/stock_parts/cell/bluespace/empty/Initialize()
|
||||
. = ..()
|
||||
charge = 0
|
||||
update_icon()
|
||||
|
||||
/obj/item/stock_parts/cell/infinite
|
||||
name = "infinite-capacity power cell!"
|
||||
icon_state = "icell"
|
||||
maxcharge = 30000
|
||||
materials = list(MAT_GLASS=1000)
|
||||
rating = 100
|
||||
chargerate = 30000
|
||||
|
||||
/obj/item/stock_parts/cell/infinite/use()
|
||||
return 1
|
||||
|
||||
/obj/item/stock_parts/cell/infinite/abductor
|
||||
name = "void core"
|
||||
desc = "An alien power cell that produces energy seemingly out of nowhere."
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
icon_state = "cell"
|
||||
maxcharge = 50000
|
||||
ratingdesc = FALSE
|
||||
|
||||
/obj/item/stock_parts/cell/infinite/abductor/update_icon()
|
||||
return
|
||||
|
||||
|
||||
/obj/item/stock_parts/cell/potato
|
||||
name = "potato battery"
|
||||
desc = "A rechargeable starch based power cell."
|
||||
icon = 'icons/obj/hydroponics/harvest.dmi'
|
||||
icon_state = "potato"
|
||||
charge = 100
|
||||
maxcharge = 300
|
||||
materials = list()
|
||||
grown_battery = TRUE //it has the overlays for wires
|
||||
|
||||
/obj/item/stock_parts/cell/high/slime
|
||||
name = "charged slime core"
|
||||
desc = "A yellow slime core infused with plasma, it crackles with power."
|
||||
icon = 'icons/mob/slimes.dmi'
|
||||
icon_state = "yellow slime extract"
|
||||
materials = list()
|
||||
rating = 5 //self-recharge makes these desirable
|
||||
self_recharge = 1 // Infused slime cores self-recharge, over time
|
||||
|
||||
/obj/item/stock_parts/cell/emproof
|
||||
name = "\improper EMP-proof cell"
|
||||
desc = "An EMP-proof cell."
|
||||
maxcharge = 500
|
||||
rating = 3
|
||||
|
||||
/obj/item/stock_parts/cell/emproof/empty/Initialize()
|
||||
. = ..()
|
||||
charge = 0
|
||||
update_icon()
|
||||
|
||||
/obj/item/stock_parts/cell/emproof/empty/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/empprotection, EMP_PROTECT_SELF)
|
||||
|
||||
/obj/item/stock_parts/cell/emproof/corrupt()
|
||||
return
|
||||
|
||||
/obj/item/stock_parts/cell/beam_rifle
|
||||
name = "beam rifle capacitor"
|
||||
desc = "A high powered capacitor that can provide huge amounts of energy in an instant."
|
||||
maxcharge = 50000
|
||||
chargerate = 5000 //Extremely energy intensive
|
||||
|
||||
/obj/item/stock_parts/cell/beam_rifle/corrupt()
|
||||
return
|
||||
|
||||
/obj/item/stock_parts/cell/beam_rifle/emp_act(severity)
|
||||
. = ..()
|
||||
if(. & EMP_PROTECT_SELF)
|
||||
return
|
||||
charge = CLAMP((charge-(10000/severity)),0,maxcharge)
|
||||
|
||||
/obj/item/stock_parts/cell/emergency_light
|
||||
name = "miniature power cell"
|
||||
desc = "A tiny power cell with a very low power capacity. Used in light fixtures to power them in the event of an outage."
|
||||
maxcharge = 120 //Emergency lights use 0.2 W per tick, meaning ~10 minutes of emergency power from a cell
|
||||
materials = list(MAT_GLASS = 20)
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
|
||||
/obj/item/stock_parts/cell/emergency_light/Initialize()
|
||||
. = ..()
|
||||
var/area/A = get_area(src)
|
||||
if(!A.lightswitch || !A.light_power)
|
||||
charge = 0 //For naturally depowered areas, we start with no power
|
||||
|
||||
//found inside the inducers ordered from cargo.
|
||||
/obj/item/stock_parts/cell/inducer_supply
|
||||
maxcharge = 5000
|
||||
/obj/item/stock_parts/cell
|
||||
name = "power cell"
|
||||
desc = "A rechargeable electrochemical power cell."
|
||||
icon = 'icons/obj/power.dmi'
|
||||
icon_state = "cell"
|
||||
item_state = "cell"
|
||||
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
|
||||
force = 5
|
||||
throwforce = 5
|
||||
throw_speed = 2
|
||||
throw_range = 5
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
var/charge = 0 // note %age conveted to actual charge in New
|
||||
var/maxcharge = 1000
|
||||
materials = list(MAT_METAL=700, MAT_GLASS=50)
|
||||
grind_results = list(/datum/reagent/lithium = 15, /datum/reagent/iron = 5, /datum/reagent/silicon = 5)
|
||||
var/rigged = FALSE // true if rigged to explode
|
||||
var/chargerate = 100 //how much power is given every tick in a recharger
|
||||
var/self_recharge = 0 //does it self recharge, over time, or not?
|
||||
var/ratingdesc = TRUE
|
||||
var/grown_battery = FALSE // If it's a grown that acts as a battery, add a wire overlay to it.
|
||||
rad_flags = RAD_NO_CONTAMINATE // Prevent the same cheese as with the stock parts
|
||||
|
||||
/obj/item/stock_parts/cell/get_cell()
|
||||
return src
|
||||
|
||||
/obj/item/stock_parts/cell/Initialize(mapload, override_maxcharge)
|
||||
. = ..()
|
||||
if(self_recharge)
|
||||
START_PROCESSING(SSobj, src)
|
||||
create_reagents(5, INJECTABLE | DRAINABLE)
|
||||
if (override_maxcharge)
|
||||
maxcharge = override_maxcharge
|
||||
charge = maxcharge
|
||||
if(ratingdesc)
|
||||
desc += " This one has a rating of [DisplayEnergy(maxcharge)], and you should not swallow it."
|
||||
update_icon()
|
||||
|
||||
/obj/item/stock_parts/cell/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/stock_parts/cell/vv_edit_var(var_name, var_value)
|
||||
switch(var_name)
|
||||
if("self_recharge")
|
||||
if(var_value)
|
||||
START_PROCESSING(SSobj, src)
|
||||
else
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
. = ..()
|
||||
|
||||
/obj/item/stock_parts/cell/process()
|
||||
if(self_recharge)
|
||||
give(chargerate * 0.25)
|
||||
else
|
||||
return PROCESS_KILL
|
||||
|
||||
/obj/item/stock_parts/cell/update_icon()
|
||||
cut_overlays()
|
||||
if(grown_battery)
|
||||
add_overlay(image('icons/obj/power.dmi',"grown_wires"))
|
||||
if(charge < 0.01)
|
||||
return
|
||||
else if(charge/maxcharge >=0.995)
|
||||
add_overlay("cell-o2")
|
||||
else
|
||||
add_overlay("cell-o1")
|
||||
|
||||
/obj/item/stock_parts/cell/proc/percent() // return % charge of cell
|
||||
return 100*charge/maxcharge
|
||||
|
||||
// use power from a cell
|
||||
/obj/item/stock_parts/cell/use(amount, can_explode = TRUE)
|
||||
if(rigged && amount > 0 && can_explode)
|
||||
explode()
|
||||
return 0
|
||||
if(charge < amount)
|
||||
return 0
|
||||
charge = (charge - amount)
|
||||
if(!istype(loc, /obj/machinery/power/apc))
|
||||
SSblackbox.record_feedback("tally", "cell_used", 1, type)
|
||||
return 1
|
||||
|
||||
// recharge the cell
|
||||
/obj/item/stock_parts/cell/proc/give(amount)
|
||||
if(rigged && amount > 0)
|
||||
explode()
|
||||
return 0
|
||||
if(maxcharge < amount)
|
||||
amount = maxcharge
|
||||
var/power_used = min(maxcharge-charge,amount)
|
||||
charge += power_used
|
||||
return power_used
|
||||
|
||||
/obj/item/stock_parts/cell/examine(mob/user)
|
||||
. = ..()
|
||||
if(rigged)
|
||||
. += "<span class='danger'>This power cell seems to be faulty!</span>"
|
||||
else
|
||||
. += "The charge meter reads [round(src.percent() )]%."
|
||||
|
||||
/obj/item/stock_parts/cell/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] is licking the electrodes of [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
return (FIRELOSS)
|
||||
|
||||
/obj/item/stock_parts/cell/on_reagent_change(changetype)
|
||||
..()
|
||||
rigged = reagents?.has_reagent(/datum/reagent/toxin/plasma, 5) ? TRUE : FALSE //has_reagent returns the reagent datum
|
||||
|
||||
/obj/item/stock_parts/cell/proc/explode()
|
||||
var/turf/T = get_turf(src.loc)
|
||||
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 = FALSE
|
||||
corrupt()
|
||||
return
|
||||
//explosion(T, 0, 1, 2, 2)
|
||||
explosion(T, devastation_range, heavy_impact_range, light_impact_range, flash_range)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/stock_parts/cell/proc/corrupt()
|
||||
charge /= 2
|
||||
maxcharge = max(maxcharge/2, chargerate)
|
||||
if (prob(10))
|
||||
rigged = TRUE //broken batterys are dangerous
|
||||
|
||||
/obj/item/stock_parts/cell/emp_act(severity)
|
||||
. = ..()
|
||||
if(. & EMP_PROTECT_SELF)
|
||||
return
|
||||
charge -= 1000 / severity
|
||||
if (charge < 0)
|
||||
charge = 0
|
||||
|
||||
/obj/item/stock_parts/cell/ex_act(severity, target)
|
||||
..()
|
||||
if(!QDELETED(src))
|
||||
switch(severity)
|
||||
if(2)
|
||||
if(prob(50))
|
||||
corrupt()
|
||||
if(3)
|
||||
if(prob(25))
|
||||
corrupt()
|
||||
|
||||
|
||||
/obj/item/stock_parts/cell/blob_act(obj/structure/blob/B)
|
||||
ex_act(EXPLODE_DEVASTATE)
|
||||
|
||||
/obj/item/stock_parts/cell/proc/get_electrocute_damage()
|
||||
if(charge >= 1000)
|
||||
return CLAMP(round(charge/10000), 10, 90) + rand(-5,5)
|
||||
else
|
||||
return 0
|
||||
|
||||
/obj/item/stock_parts/cell/get_part_rating()
|
||||
return rating * maxcharge
|
||||
|
||||
/* Cell variants*/
|
||||
/obj/item/stock_parts/cell/empty/Initialize()
|
||||
. = ..()
|
||||
charge = 0
|
||||
|
||||
/obj/item/stock_parts/cell/crap
|
||||
name = "\improper Nanotrasen brand rechargeable AA battery"
|
||||
desc = "You can't top the plasma top." //TOTALLY TRADEMARK INFRINGEMENT
|
||||
maxcharge = 500
|
||||
materials = list(MAT_GLASS=40)
|
||||
|
||||
/obj/item/stock_parts/cell/crap/empty/Initialize()
|
||||
. = ..()
|
||||
charge = 0
|
||||
update_icon()
|
||||
|
||||
/obj/item/stock_parts/cell/upgraded
|
||||
name = "upgraded power cell"
|
||||
desc = "A power cell with a slightly higher capacity than normal!"
|
||||
maxcharge = 2500
|
||||
materials = list(MAT_GLASS=50)
|
||||
chargerate = 1000
|
||||
|
||||
/obj/item/stock_parts/cell/upgraded/plus
|
||||
name = "upgraded power cell+"
|
||||
desc = "A power cell with an even higher capacity than the base model!"
|
||||
maxcharge = 5000
|
||||
|
||||
/obj/item/stock_parts/cell/secborg
|
||||
name = "security borg rechargeable D battery"
|
||||
maxcharge = 1250 //25/12/6 disabler/laser/taser shots.
|
||||
materials = list(MAT_GLASS=40)
|
||||
|
||||
/obj/item/stock_parts/cell/secborg/empty/Initialize()
|
||||
. = ..()
|
||||
charge = 0
|
||||
update_icon()
|
||||
|
||||
/obj/item/stock_parts/cell/lascarbine
|
||||
name = "laser carbine power supply"
|
||||
maxcharge = 1500 //20 laser shots.
|
||||
|
||||
/obj/item/stock_parts/cell/pulse //200 pulse shots
|
||||
name = "pulse rifle power cell"
|
||||
maxcharge = 40000
|
||||
chargerate = 1500
|
||||
|
||||
/obj/item/stock_parts/cell/pulse/carbine //25 pulse shots
|
||||
name = "pulse carbine power cell"
|
||||
maxcharge = 5000
|
||||
|
||||
/obj/item/stock_parts/cell/pulse/pistol //10 pulse shots
|
||||
name = "pulse pistol power cell"
|
||||
maxcharge = 2000
|
||||
|
||||
/obj/item/stock_parts/cell/high
|
||||
name = "high-capacity power cell"
|
||||
icon_state = "hcell"
|
||||
maxcharge = 10000
|
||||
materials = list(MAT_GLASS=60)
|
||||
chargerate = 1500
|
||||
|
||||
/obj/item/stock_parts/cell/high/plus
|
||||
name = "high-capacity power cell+"
|
||||
desc = "Where did these come from?"
|
||||
icon_state = "h+cell"
|
||||
maxcharge = 15000
|
||||
chargerate = 2250
|
||||
|
||||
/obj/item/stock_parts/cell/high/empty/Initialize()
|
||||
. = ..()
|
||||
charge = 0
|
||||
update_icon()
|
||||
|
||||
/obj/item/stock_parts/cell/super
|
||||
name = "super-capacity power cell"
|
||||
icon_state = "scell"
|
||||
maxcharge = 20000
|
||||
materials = list(MAT_GLASS=300)
|
||||
chargerate = 2000
|
||||
|
||||
/obj/item/stock_parts/cell/super/empty/Initialize()
|
||||
. = ..()
|
||||
charge = 0
|
||||
update_icon()
|
||||
|
||||
/obj/item/stock_parts/cell/hyper
|
||||
name = "hyper-capacity power cell"
|
||||
icon_state = "hpcell"
|
||||
maxcharge = 30000
|
||||
materials = list(MAT_GLASS=400)
|
||||
chargerate = 3000
|
||||
|
||||
/obj/item/stock_parts/cell/hyper/empty/Initialize()
|
||||
. = ..()
|
||||
charge = 0
|
||||
update_icon()
|
||||
|
||||
/obj/item/stock_parts/cell/bluespace
|
||||
name = "bluespace power cell"
|
||||
desc = "A rechargeable transdimensional power cell."
|
||||
icon_state = "bscell"
|
||||
maxcharge = 40000
|
||||
materials = list(MAT_GLASS=600)
|
||||
chargerate = 4000
|
||||
|
||||
/obj/item/stock_parts/cell/bluespace/empty/Initialize()
|
||||
. = ..()
|
||||
charge = 0
|
||||
update_icon()
|
||||
|
||||
/obj/item/stock_parts/cell/infinite
|
||||
name = "infinite-capacity power cell!"
|
||||
icon_state = "icell"
|
||||
maxcharge = 30000
|
||||
materials = list(MAT_GLASS=1000)
|
||||
rating = 100
|
||||
chargerate = 30000
|
||||
|
||||
/obj/item/stock_parts/cell/infinite/use()
|
||||
return 1
|
||||
|
||||
/obj/item/stock_parts/cell/infinite/abductor
|
||||
name = "void core"
|
||||
desc = "An alien power cell that produces energy seemingly out of nowhere."
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
icon_state = "cell"
|
||||
maxcharge = 50000
|
||||
ratingdesc = FALSE
|
||||
|
||||
/obj/item/stock_parts/cell/infinite/abductor/update_icon()
|
||||
return
|
||||
|
||||
|
||||
/obj/item/stock_parts/cell/potato
|
||||
name = "potato battery"
|
||||
desc = "A rechargeable starch based power cell."
|
||||
icon = 'icons/obj/hydroponics/harvest.dmi'
|
||||
icon_state = "potato"
|
||||
charge = 100
|
||||
maxcharge = 300
|
||||
materials = list()
|
||||
grown_battery = TRUE //it has the overlays for wires
|
||||
|
||||
/obj/item/stock_parts/cell/high/slime
|
||||
name = "charged slime core"
|
||||
desc = "A yellow slime core infused with plasma, it crackles with power."
|
||||
icon = 'icons/mob/slimes.dmi'
|
||||
icon_state = "yellow slime extract"
|
||||
materials = list()
|
||||
rating = 5 //self-recharge makes these desirable
|
||||
self_recharge = 1 // Infused slime cores self-recharge, over time
|
||||
|
||||
/obj/item/stock_parts/cell/emproof
|
||||
name = "\improper EMP-proof cell"
|
||||
desc = "An EMP-proof cell."
|
||||
maxcharge = 500
|
||||
rating = 3
|
||||
|
||||
/obj/item/stock_parts/cell/emproof/empty/Initialize()
|
||||
. = ..()
|
||||
charge = 0
|
||||
update_icon()
|
||||
|
||||
/obj/item/stock_parts/cell/emproof/empty/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/empprotection, EMP_PROTECT_SELF)
|
||||
|
||||
/obj/item/stock_parts/cell/emproof/corrupt()
|
||||
return
|
||||
|
||||
/obj/item/stock_parts/cell/beam_rifle
|
||||
name = "beam rifle capacitor"
|
||||
desc = "A high powered capacitor that can provide huge amounts of energy in an instant."
|
||||
maxcharge = 50000
|
||||
chargerate = 5000 //Extremely energy intensive
|
||||
|
||||
/obj/item/stock_parts/cell/beam_rifle/corrupt()
|
||||
return
|
||||
|
||||
/obj/item/stock_parts/cell/beam_rifle/emp_act(severity)
|
||||
. = ..()
|
||||
if(. & EMP_PROTECT_SELF)
|
||||
return
|
||||
charge = CLAMP((charge-(10000/severity)),0,maxcharge)
|
||||
|
||||
/obj/item/stock_parts/cell/emergency_light
|
||||
name = "miniature power cell"
|
||||
desc = "A tiny power cell with a very low power capacity. Used in light fixtures to power them in the event of an outage."
|
||||
maxcharge = 120 //Emergency lights use 0.2 W per tick, meaning ~10 minutes of emergency power from a cell
|
||||
materials = list(MAT_GLASS = 20)
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
|
||||
/obj/item/stock_parts/cell/emergency_light/Initialize()
|
||||
. = ..()
|
||||
var/area/A = get_area(src)
|
||||
if(!A.lightswitch || !A.light_power)
|
||||
charge = 0 //For naturally depowered areas, we start with no power
|
||||
|
||||
//found inside the inducers ordered from cargo.
|
||||
/obj/item/stock_parts/cell/inducer_supply
|
||||
maxcharge = 5000
|
||||
|
||||
+234
-234
@@ -1,234 +1,234 @@
|
||||
/obj/machinery/power/generator
|
||||
name = "thermoelectric generator"
|
||||
desc = "It's a high efficiency thermoelectric generator."
|
||||
icon_state = "teg"
|
||||
density = TRUE
|
||||
use_power = NO_POWER_USE
|
||||
|
||||
var/obj/machinery/atmospherics/components/binary/circulator/cold_circ
|
||||
var/obj/machinery/atmospherics/components/binary/circulator/hot_circ
|
||||
|
||||
var/lastgen = 0
|
||||
var/lastgenlev = -1
|
||||
var/lastcirc = "00"
|
||||
|
||||
|
||||
/obj/machinery/power/generator/Initialize(mapload)
|
||||
. = ..()
|
||||
find_circs()
|
||||
connect_to_network()
|
||||
SSair.atmos_machinery += src
|
||||
update_icon()
|
||||
component_parts = list(new /obj/item/circuitboard/machine/generator)
|
||||
|
||||
/obj/machinery/power/generator/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/simple_rotation,ROTATION_ALTCLICK | ROTATION_CLOCKWISE | ROTATION_COUNTERCLOCKWISE | ROTATION_VERBS )
|
||||
|
||||
/obj/machinery/power/generator/Destroy()
|
||||
kill_circs()
|
||||
SSair.atmos_machinery -= src
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/generator/update_icon()
|
||||
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
cut_overlays()
|
||||
else
|
||||
cut_overlays()
|
||||
|
||||
var/L = min(round(lastgenlev/100000),11)
|
||||
if(L != 0)
|
||||
add_overlay(image('icons/obj/power.dmi', "teg-op[L]"))
|
||||
|
||||
if(hot_circ && cold_circ)
|
||||
add_overlay("teg-oc[lastcirc]")
|
||||
|
||||
|
||||
#define GENRATE 800 // generator output coefficient from Q
|
||||
|
||||
/obj/machinery/power/generator/process_atmos()
|
||||
|
||||
if(!cold_circ || !hot_circ)
|
||||
return
|
||||
|
||||
if(powernet)
|
||||
var/datum/gas_mixture/cold_air = cold_circ.return_transfer_air()
|
||||
var/datum/gas_mixture/hot_air = hot_circ.return_transfer_air()
|
||||
|
||||
if(cold_air && hot_air)
|
||||
|
||||
var/cold_air_heat_capacity = cold_air.heat_capacity()
|
||||
var/hot_air_heat_capacity = hot_air.heat_capacity()
|
||||
|
||||
var/delta_temperature = hot_air.temperature - cold_air.temperature
|
||||
|
||||
|
||||
if(delta_temperature > 0 && cold_air_heat_capacity > 0 && hot_air_heat_capacity > 0)
|
||||
var/efficiency = 0.00025 + (hot_air.reaction_results["fire"]*0.01)
|
||||
|
||||
var/energy_transfer = delta_temperature*hot_air_heat_capacity*cold_air_heat_capacity/(hot_air_heat_capacity+cold_air_heat_capacity)
|
||||
|
||||
var/heat = energy_transfer*(1-efficiency)
|
||||
lastgen += energy_transfer*efficiency
|
||||
|
||||
hot_air.temperature = hot_air.temperature - energy_transfer/hot_air_heat_capacity
|
||||
cold_air.temperature = cold_air.temperature + heat/cold_air_heat_capacity
|
||||
|
||||
//add_avail(lastgen) This is done in process now
|
||||
// update icon overlays only if displayed level has changed
|
||||
|
||||
if(hot_air)
|
||||
var/datum/gas_mixture/hot_circ_air1 = hot_circ.airs[1]
|
||||
hot_circ_air1.merge(hot_air)
|
||||
|
||||
if(cold_air)
|
||||
var/datum/gas_mixture/cold_circ_air1 = cold_circ.airs[1]
|
||||
cold_circ_air1.merge(cold_air)
|
||||
|
||||
update_icon()
|
||||
|
||||
var/circ = "[cold_circ && cold_circ.last_pressure_delta > 0 ? "1" : "0"][hot_circ && hot_circ.last_pressure_delta > 0 ? "1" : "0"]"
|
||||
if(circ != lastcirc)
|
||||
lastcirc = circ
|
||||
update_icon()
|
||||
|
||||
src.updateDialog()
|
||||
|
||||
/obj/machinery/power/generator/process()
|
||||
//Setting this number higher just makes the change in power output slower, it doesnt actualy reduce power output cause **math**
|
||||
var/power_output = round(lastgen / 10)
|
||||
add_avail(power_output)
|
||||
lastgenlev = power_output
|
||||
lastgen -= power_output
|
||||
..()
|
||||
|
||||
/obj/machinery/power/generator/proc/get_menu(include_link = TRUE)
|
||||
var/t = ""
|
||||
if(!powernet)
|
||||
t += "<span class='bad'>Unable to connect to the power network!</span>"
|
||||
else if(cold_circ && hot_circ)
|
||||
var/datum/gas_mixture/cold_circ_air1 = cold_circ.airs[1]
|
||||
var/datum/gas_mixture/cold_circ_air2 = cold_circ.airs[2]
|
||||
var/datum/gas_mixture/hot_circ_air1 = hot_circ.airs[1]
|
||||
var/datum/gas_mixture/hot_circ_air2 = hot_circ.airs[2]
|
||||
|
||||
t += "<div class='statusDisplay'>"
|
||||
|
||||
t += "Output: [DisplayPower(lastgenlev)]"
|
||||
|
||||
t += "<BR>"
|
||||
|
||||
t += "<B><font color='blue'>Cold loop</font></B><BR>"
|
||||
t += "Temperature Inlet: [round(cold_circ_air2.temperature, 0.1)] K / Outlet: [round(cold_circ_air1.temperature, 0.1)] K<BR>"
|
||||
t += "Pressure Inlet: [round(cold_circ_air2.return_pressure(), 0.1)] kPa / Outlet: [round(cold_circ_air1.return_pressure(), 0.1)] kPa<BR>"
|
||||
|
||||
t += "<B><font color='red'>Hot loop</font></B><BR>"
|
||||
t += "Temperature Inlet: [round(hot_circ_air2.temperature, 0.1)] K / Outlet: [round(hot_circ_air1.temperature, 0.1)] K<BR>"
|
||||
t += "Pressure Inlet: [round(hot_circ_air2.return_pressure(), 0.1)] kPa / Outlet: [round(hot_circ_air1.return_pressure(), 0.1)] kPa<BR>"
|
||||
|
||||
t += "</div>"
|
||||
else if(!hot_circ && cold_circ)
|
||||
t += "<span class='bad'>Unable to locate hot circulator!</span>"
|
||||
else if(hot_circ && !cold_circ)
|
||||
t += "<span class='bad'>Unable to locate cold circulator!</span>"
|
||||
else
|
||||
t += "<span class='bad'>Unable to locate any parts!</span>"
|
||||
if(include_link)
|
||||
t += "<BR><A href='?src=[REF(src)];close=1'>Close</A>"
|
||||
|
||||
return t
|
||||
|
||||
/obj/machinery/power/generator/ui_interact(mob/user)
|
||||
. = ..()
|
||||
var/datum/browser/popup = new(user, "teg", "Thermo-Electric Generator", 460, 300)
|
||||
popup.set_content(get_menu())
|
||||
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
|
||||
popup.open()
|
||||
|
||||
/obj/machinery/power/generator/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
if( href_list["close"] )
|
||||
usr << browse(null, "window=teg")
|
||||
usr.unset_machine()
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/machinery/power/generator/power_change()
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/power/generator/proc/find_circs()
|
||||
kill_circs()
|
||||
var/list/circs = list()
|
||||
var/obj/machinery/atmospherics/components/binary/circulator/C
|
||||
var/circpath = /obj/machinery/atmospherics/components/binary/circulator
|
||||
if(dir == NORTH || dir == SOUTH)
|
||||
C = locate(circpath) in get_step(src, EAST)
|
||||
if(C && C.dir == WEST)
|
||||
circs += C
|
||||
|
||||
C = locate(circpath) in get_step(src, WEST)
|
||||
if(C && C.dir == EAST)
|
||||
circs += C
|
||||
|
||||
else
|
||||
C = locate(circpath) in get_step(src, NORTH)
|
||||
if(C && C.dir == SOUTH)
|
||||
circs += C
|
||||
|
||||
C = locate(circpath) in get_step(src, SOUTH)
|
||||
if(C && C.dir == NORTH)
|
||||
circs += C
|
||||
|
||||
if(circs.len)
|
||||
for(C in circs)
|
||||
if(C.mode == CIRCULATOR_COLD && !cold_circ)
|
||||
cold_circ = C
|
||||
C.generator = src
|
||||
else if(C.mode == CIRCULATOR_HOT && !hot_circ)
|
||||
hot_circ = C
|
||||
C.generator = src
|
||||
|
||||
/obj/machinery/power/generator/wrench_act(mob/living/user, obj/item/I)
|
||||
if(!panel_open)
|
||||
return
|
||||
anchored = !anchored
|
||||
I.play_tool_sound(src)
|
||||
if(!anchored)
|
||||
kill_circs()
|
||||
connect_to_network()
|
||||
to_chat(user, "<span class='notice'>You [anchored?"secure":"unsecure"] [src].</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/generator/multitool_act(mob/living/user, obj/item/I)
|
||||
if(!anchored)
|
||||
return
|
||||
find_circs()
|
||||
to_chat(user, "<span class='notice'>You update [src]'s circulator links.</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/generator/screwdriver_act(mob/user, obj/item/I)
|
||||
if(..())
|
||||
return TRUE
|
||||
panel_open = !panel_open
|
||||
I.play_tool_sound(src)
|
||||
to_chat(user, "<span class='notice'>You [panel_open?"open":"close"] the panel on [src].</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/generator/crowbar_act(mob/user, obj/item/I)
|
||||
default_deconstruction_crowbar(I)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/generator/on_deconstruction()
|
||||
kill_circs()
|
||||
|
||||
/obj/machinery/power/generator/proc/kill_circs()
|
||||
if(hot_circ)
|
||||
hot_circ.generator = null
|
||||
hot_circ = null
|
||||
if(cold_circ)
|
||||
cold_circ.generator = null
|
||||
cold_circ = null
|
||||
/obj/machinery/power/generator
|
||||
name = "thermoelectric generator"
|
||||
desc = "It's a high efficiency thermoelectric generator."
|
||||
icon_state = "teg"
|
||||
density = TRUE
|
||||
use_power = NO_POWER_USE
|
||||
|
||||
var/obj/machinery/atmospherics/components/binary/circulator/cold_circ
|
||||
var/obj/machinery/atmospherics/components/binary/circulator/hot_circ
|
||||
|
||||
var/lastgen = 0
|
||||
var/lastgenlev = -1
|
||||
var/lastcirc = "00"
|
||||
|
||||
|
||||
/obj/machinery/power/generator/Initialize(mapload)
|
||||
. = ..()
|
||||
find_circs()
|
||||
connect_to_network()
|
||||
SSair.atmos_machinery += src
|
||||
update_icon()
|
||||
component_parts = list(new /obj/item/circuitboard/machine/generator)
|
||||
|
||||
/obj/machinery/power/generator/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/simple_rotation,ROTATION_ALTCLICK | ROTATION_CLOCKWISE | ROTATION_COUNTERCLOCKWISE | ROTATION_VERBS )
|
||||
|
||||
/obj/machinery/power/generator/Destroy()
|
||||
kill_circs()
|
||||
SSair.atmos_machinery -= src
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/generator/update_icon()
|
||||
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
cut_overlays()
|
||||
else
|
||||
cut_overlays()
|
||||
|
||||
var/L = min(round(lastgenlev/100000),11)
|
||||
if(L != 0)
|
||||
add_overlay(image('icons/obj/power.dmi', "teg-op[L]"))
|
||||
|
||||
if(hot_circ && cold_circ)
|
||||
add_overlay("teg-oc[lastcirc]")
|
||||
|
||||
|
||||
#define GENRATE 800 // generator output coefficient from Q
|
||||
|
||||
/obj/machinery/power/generator/process_atmos()
|
||||
|
||||
if(!cold_circ || !hot_circ)
|
||||
return
|
||||
|
||||
if(powernet)
|
||||
var/datum/gas_mixture/cold_air = cold_circ.return_transfer_air()
|
||||
var/datum/gas_mixture/hot_air = hot_circ.return_transfer_air()
|
||||
|
||||
if(cold_air && hot_air)
|
||||
|
||||
var/cold_air_heat_capacity = cold_air.heat_capacity()
|
||||
var/hot_air_heat_capacity = hot_air.heat_capacity()
|
||||
|
||||
var/delta_temperature = hot_air.temperature - cold_air.temperature
|
||||
|
||||
|
||||
if(delta_temperature > 0 && cold_air_heat_capacity > 0 && hot_air_heat_capacity > 0)
|
||||
var/efficiency = 0.45
|
||||
|
||||
var/energy_transfer = delta_temperature*hot_air_heat_capacity*cold_air_heat_capacity/(hot_air_heat_capacity+cold_air_heat_capacity)
|
||||
|
||||
var/heat = energy_transfer*(1-efficiency)
|
||||
lastgen += energy_transfer*efficiency
|
||||
|
||||
hot_air.temperature = hot_air.temperature - energy_transfer/hot_air_heat_capacity
|
||||
cold_air.temperature = cold_air.temperature + heat/cold_air_heat_capacity
|
||||
|
||||
//add_avail(lastgen) This is done in process now
|
||||
// update icon overlays only if displayed level has changed
|
||||
|
||||
if(hot_air)
|
||||
var/datum/gas_mixture/hot_circ_air1 = hot_circ.airs[1]
|
||||
hot_circ_air1.merge(hot_air)
|
||||
|
||||
if(cold_air)
|
||||
var/datum/gas_mixture/cold_circ_air1 = cold_circ.airs[1]
|
||||
cold_circ_air1.merge(cold_air)
|
||||
|
||||
update_icon()
|
||||
|
||||
var/circ = "[cold_circ && cold_circ.last_pressure_delta > 0 ? "1" : "0"][hot_circ && hot_circ.last_pressure_delta > 0 ? "1" : "0"]"
|
||||
if(circ != lastcirc)
|
||||
lastcirc = circ
|
||||
update_icon()
|
||||
|
||||
src.updateDialog()
|
||||
|
||||
/obj/machinery/power/generator/process()
|
||||
//Setting this number higher just makes the change in power output slower, it doesnt actualy reduce power output cause **math**
|
||||
var/power_output = round(lastgen / 10)
|
||||
add_avail(power_output)
|
||||
lastgenlev = power_output
|
||||
lastgen -= power_output
|
||||
..()
|
||||
|
||||
/obj/machinery/power/generator/proc/get_menu(include_link = TRUE)
|
||||
var/t = ""
|
||||
if(!powernet)
|
||||
t += "<span class='bad'>Unable to connect to the power network!</span>"
|
||||
else if(cold_circ && hot_circ)
|
||||
var/datum/gas_mixture/cold_circ_air1 = cold_circ.airs[1]
|
||||
var/datum/gas_mixture/cold_circ_air2 = cold_circ.airs[2]
|
||||
var/datum/gas_mixture/hot_circ_air1 = hot_circ.airs[1]
|
||||
var/datum/gas_mixture/hot_circ_air2 = hot_circ.airs[2]
|
||||
|
||||
t += "<div class='statusDisplay'>"
|
||||
|
||||
t += "Output: [DisplayPower(lastgenlev)]"
|
||||
|
||||
t += "<BR>"
|
||||
|
||||
t += "<B><font color='blue'>Cold loop</font></B><BR>"
|
||||
t += "Temperature Inlet: [round(cold_circ_air2.temperature, 0.1)] K / Outlet: [round(cold_circ_air1.temperature, 0.1)] K<BR>"
|
||||
t += "Pressure Inlet: [round(cold_circ_air2.return_pressure(), 0.1)] kPa / Outlet: [round(cold_circ_air1.return_pressure(), 0.1)] kPa<BR>"
|
||||
|
||||
t += "<B><font color='red'>Hot loop</font></B><BR>"
|
||||
t += "Temperature Inlet: [round(hot_circ_air2.temperature, 0.1)] K / Outlet: [round(hot_circ_air1.temperature, 0.1)] K<BR>"
|
||||
t += "Pressure Inlet: [round(hot_circ_air2.return_pressure(), 0.1)] kPa / Outlet: [round(hot_circ_air1.return_pressure(), 0.1)] kPa<BR>"
|
||||
|
||||
t += "</div>"
|
||||
else if(!hot_circ && cold_circ)
|
||||
t += "<span class='bad'>Unable to locate hot circulator!</span>"
|
||||
else if(hot_circ && !cold_circ)
|
||||
t += "<span class='bad'>Unable to locate cold circulator!</span>"
|
||||
else
|
||||
t += "<span class='bad'>Unable to locate any parts!</span>"
|
||||
if(include_link)
|
||||
t += "<BR><A href='?src=[REF(src)];close=1'>Close</A>"
|
||||
|
||||
return t
|
||||
|
||||
/obj/machinery/power/generator/ui_interact(mob/user)
|
||||
. = ..()
|
||||
var/datum/browser/popup = new(user, "teg", "Thermo-Electric Generator", 460, 300)
|
||||
popup.set_content(get_menu())
|
||||
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
|
||||
popup.open()
|
||||
|
||||
/obj/machinery/power/generator/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
if( href_list["close"] )
|
||||
usr << browse(null, "window=teg")
|
||||
usr.unset_machine()
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/machinery/power/generator/power_change()
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/power/generator/proc/find_circs()
|
||||
kill_circs()
|
||||
var/list/circs = list()
|
||||
var/obj/machinery/atmospherics/components/binary/circulator/C
|
||||
var/circpath = /obj/machinery/atmospherics/components/binary/circulator
|
||||
if(dir == NORTH || dir == SOUTH)
|
||||
C = locate(circpath) in get_step(src, EAST)
|
||||
if(C && C.dir == WEST)
|
||||
circs += C
|
||||
|
||||
C = locate(circpath) in get_step(src, WEST)
|
||||
if(C && C.dir == EAST)
|
||||
circs += C
|
||||
|
||||
else
|
||||
C = locate(circpath) in get_step(src, NORTH)
|
||||
if(C && C.dir == SOUTH)
|
||||
circs += C
|
||||
|
||||
C = locate(circpath) in get_step(src, SOUTH)
|
||||
if(C && C.dir == NORTH)
|
||||
circs += C
|
||||
|
||||
if(circs.len)
|
||||
for(C in circs)
|
||||
if(C.mode == CIRCULATOR_COLD && !cold_circ)
|
||||
cold_circ = C
|
||||
C.generator = src
|
||||
else if(C.mode == CIRCULATOR_HOT && !hot_circ)
|
||||
hot_circ = C
|
||||
C.generator = src
|
||||
|
||||
/obj/machinery/power/generator/wrench_act(mob/living/user, obj/item/I)
|
||||
if(!panel_open)
|
||||
return
|
||||
anchored = !anchored
|
||||
I.play_tool_sound(src)
|
||||
if(!anchored)
|
||||
kill_circs()
|
||||
connect_to_network()
|
||||
to_chat(user, "<span class='notice'>You [anchored?"secure":"unsecure"] [src].</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/generator/multitool_act(mob/living/user, obj/item/I)
|
||||
if(!anchored)
|
||||
return
|
||||
find_circs()
|
||||
to_chat(user, "<span class='notice'>You update [src]'s circulator links.</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/generator/screwdriver_act(mob/user, obj/item/I)
|
||||
if(..())
|
||||
return TRUE
|
||||
panel_open = !panel_open
|
||||
I.play_tool_sound(src)
|
||||
to_chat(user, "<span class='notice'>You [panel_open?"open":"close"] the panel on [src].</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/generator/crowbar_act(mob/user, obj/item/I)
|
||||
default_deconstruction_crowbar(I)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/generator/on_deconstruction()
|
||||
kill_circs()
|
||||
|
||||
/obj/machinery/power/generator/proc/kill_circs()
|
||||
if(hot_circ)
|
||||
hot_circ.generator = null
|
||||
hot_circ = null
|
||||
if(cold_circ)
|
||||
cold_circ.generator = null
|
||||
cold_circ = null
|
||||
|
||||
@@ -1,417 +1,417 @@
|
||||
|
||||
//
|
||||
// Gravity Generator
|
||||
//
|
||||
|
||||
GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding new gravity generators to the list, and keying it with the z level.
|
||||
|
||||
#define POWER_IDLE 0
|
||||
#define POWER_UP 1
|
||||
#define POWER_DOWN 2
|
||||
|
||||
#define GRAV_NEEDS_SCREWDRIVER 0
|
||||
#define GRAV_NEEDS_WELDING 1
|
||||
#define GRAV_NEEDS_PLASTEEL 2
|
||||
#define GRAV_NEEDS_WRENCH 3
|
||||
|
||||
//
|
||||
// Abstract Generator
|
||||
//
|
||||
|
||||
/obj/machinery/gravity_generator
|
||||
name = "gravitational generator"
|
||||
desc = "A device which produces a graviton field when set up."
|
||||
icon = 'icons/obj/machines/gravity_generator.dmi'
|
||||
density = TRUE
|
||||
use_power = NO_POWER_USE
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
var/sprite_number = 0
|
||||
|
||||
/obj/machinery/gravity_generator/safe_throw_at()
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/gravity_generator/ex_act(severity, target)
|
||||
if(severity == 1) // Very sturdy.
|
||||
set_broken()
|
||||
|
||||
/obj/machinery/gravity_generator/blob_act(obj/structure/blob/B)
|
||||
if(prob(20))
|
||||
set_broken()
|
||||
|
||||
/obj/machinery/gravity_generator/tesla_act(power, tesla_flags)
|
||||
..()
|
||||
if(tesla_flags & TESLA_MACHINE_EXPLOSIVE)
|
||||
qdel(src)//like the singulo, tesla deletes it. stops it from exploding over and over
|
||||
|
||||
/obj/machinery/gravity_generator/update_icon()
|
||||
..()
|
||||
icon_state = "[get_status()]_[sprite_number]"
|
||||
|
||||
/obj/machinery/gravity_generator/proc/get_status()
|
||||
return "off"
|
||||
|
||||
// You aren't allowed to move.
|
||||
/obj/machinery/gravity_generator/Move()
|
||||
. = ..()
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/gravity_generator/proc/set_broken()
|
||||
stat |= BROKEN
|
||||
|
||||
/obj/machinery/gravity_generator/proc/set_fix()
|
||||
stat &= ~BROKEN
|
||||
|
||||
/obj/machinery/gravity_generator/part/Destroy()
|
||||
if(main_part)
|
||||
qdel(main_part)
|
||||
set_broken()
|
||||
return ..()
|
||||
|
||||
//
|
||||
// Part generator which is mostly there for looks
|
||||
//
|
||||
|
||||
/obj/machinery/gravity_generator/part
|
||||
var/obj/machinery/gravity_generator/main/main_part = null
|
||||
|
||||
/obj/machinery/gravity_generator/part/attackby(obj/item/I, mob/user, params)
|
||||
return main_part.attackby(I, user)
|
||||
|
||||
/obj/machinery/gravity_generator/part/get_status()
|
||||
return main_part.get_status()
|
||||
|
||||
/obj/machinery/gravity_generator/part/attack_hand(mob/user)
|
||||
return main_part.attack_hand(user)
|
||||
|
||||
/obj/machinery/gravity_generator/part/set_broken()
|
||||
..()
|
||||
if(main_part && !(main_part.stat & BROKEN))
|
||||
main_part.set_broken()
|
||||
|
||||
//
|
||||
// Generator which spawns with the station.
|
||||
//
|
||||
|
||||
/obj/machinery/gravity_generator/main/station/Initialize()
|
||||
. = ..()
|
||||
setup_parts()
|
||||
middle.add_overlay("activated")
|
||||
update_list()
|
||||
|
||||
//
|
||||
// Generator an admin can spawn
|
||||
//
|
||||
/obj/machinery/gravity_generator/main/station/admin
|
||||
use_power = NO_POWER_USE
|
||||
|
||||
//
|
||||
// Main Generator with the main code
|
||||
//
|
||||
|
||||
/obj/machinery/gravity_generator/main
|
||||
icon_state = "on_8"
|
||||
idle_power_usage = 0
|
||||
active_power_usage = 3000
|
||||
power_channel = ENVIRON
|
||||
sprite_number = 8
|
||||
use_power = IDLE_POWER_USE
|
||||
interaction_flags_machine = INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OFFLINE
|
||||
var/on = TRUE
|
||||
var/breaker = TRUE
|
||||
var/list/parts = list()
|
||||
var/obj/middle = null
|
||||
var/charging_state = POWER_IDLE
|
||||
var/charge_count = 100
|
||||
var/current_overlay = null
|
||||
var/broken_state = 0
|
||||
var/setting = 1 //Gravity value when on
|
||||
|
||||
/obj/machinery/gravity_generator/main/Destroy() // If we somehow get deleted, remove all of our other parts.
|
||||
investigate_log("was destroyed!", INVESTIGATE_GRAVITY)
|
||||
on = FALSE
|
||||
update_list()
|
||||
for(var/obj/machinery/gravity_generator/part/O in parts)
|
||||
O.main_part = null
|
||||
if(!QDESTROYING(O))
|
||||
qdel(O)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/gravity_generator/main/proc/setup_parts()
|
||||
var/turf/our_turf = get_turf(src)
|
||||
// 9x9 block obtained from the bottom middle of the block
|
||||
var/list/spawn_turfs = block(locate(our_turf.x - 1, our_turf.y + 2, our_turf.z), locate(our_turf.x + 1, our_turf.y, our_turf.z))
|
||||
var/count = 10
|
||||
for(var/turf/T in spawn_turfs)
|
||||
count--
|
||||
if(T == our_turf) // Skip our turf.
|
||||
continue
|
||||
var/obj/machinery/gravity_generator/part/part = new(T)
|
||||
if(count == 5) // Middle
|
||||
middle = part
|
||||
if(count <= 3) // Their sprite is the top part of the generator
|
||||
part.density = FALSE
|
||||
part.layer = WALL_OBJ_LAYER
|
||||
part.sprite_number = count
|
||||
part.main_part = src
|
||||
parts += part
|
||||
part.update_icon()
|
||||
|
||||
/obj/machinery/gravity_generator/main/proc/connected_parts()
|
||||
return parts.len == 8
|
||||
|
||||
/obj/machinery/gravity_generator/main/set_broken()
|
||||
..()
|
||||
for(var/obj/machinery/gravity_generator/M in parts)
|
||||
if(!(M.stat & BROKEN))
|
||||
M.set_broken()
|
||||
middle.cut_overlays()
|
||||
charge_count = 0
|
||||
breaker = FALSE
|
||||
set_power()
|
||||
set_state(0)
|
||||
investigate_log("has broken down.", INVESTIGATE_GRAVITY)
|
||||
|
||||
/obj/machinery/gravity_generator/main/set_fix()
|
||||
..()
|
||||
for(var/obj/machinery/gravity_generator/M in parts)
|
||||
if(M.stat & BROKEN)
|
||||
M.set_fix()
|
||||
broken_state = FALSE
|
||||
update_icon()
|
||||
set_power()
|
||||
|
||||
// Interaction
|
||||
|
||||
// Fixing the gravity generator.
|
||||
/obj/machinery/gravity_generator/main/attackby(obj/item/I, mob/user, params)
|
||||
switch(broken_state)
|
||||
if(GRAV_NEEDS_SCREWDRIVER)
|
||||
if(istype(I, /obj/item/screwdriver))
|
||||
to_chat(user, "<span class='notice'>You secure the screws of the framework.</span>")
|
||||
I.play_tool_sound(src)
|
||||
broken_state++
|
||||
update_icon()
|
||||
return
|
||||
if(GRAV_NEEDS_WELDING)
|
||||
if(istype(I, /obj/item/weldingtool))
|
||||
if(I.use_tool(src, user, 0, volume=50, amount=1))
|
||||
to_chat(user, "<span class='notice'>You mend the damaged framework.</span>")
|
||||
broken_state++
|
||||
update_icon()
|
||||
return
|
||||
if(GRAV_NEEDS_PLASTEEL)
|
||||
if(istype(I, /obj/item/stack/sheet/plasteel))
|
||||
var/obj/item/stack/sheet/plasteel/PS = I
|
||||
if(PS.get_amount() >= 10)
|
||||
PS.use(10)
|
||||
to_chat(user, "<span class='notice'>You add the plating to the framework.</span>")
|
||||
playsound(src.loc, 'sound/machines/click.ogg', 75, 1)
|
||||
broken_state++
|
||||
update_icon()
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need 10 sheets of plasteel!</span>")
|
||||
return
|
||||
if(GRAV_NEEDS_WRENCH)
|
||||
if(istype(I, /obj/item/wrench))
|
||||
to_chat(user, "<span class='notice'>You secure the plating to the framework.</span>")
|
||||
I.play_tool_sound(src)
|
||||
set_fix()
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/machinery/gravity_generator/main/ui_interact(mob/user)
|
||||
if(stat & BROKEN)
|
||||
return
|
||||
var/dat = "Gravity Generator Breaker: "
|
||||
if(breaker)
|
||||
dat += "<span class='linkOn'>ON</span> <A href='?src=[REF(src)];gentoggle=1'>OFF</A>"
|
||||
else
|
||||
dat += "<A href='?src=[REF(src)];gentoggle=1'>ON</A> <span class='linkOn'>OFF</span> "
|
||||
|
||||
dat += "<br>Generator Status:<br><div class='statusDisplay'>"
|
||||
if(charging_state != POWER_IDLE)
|
||||
dat += "<font class='bad'>WARNING</font> Radiation Detected. <br>[charging_state == POWER_UP ? "Charging..." : "Discharging..."]"
|
||||
else if(on)
|
||||
dat += "Powered."
|
||||
else
|
||||
dat += "Unpowered."
|
||||
|
||||
dat += "<br>Gravity Charge: [charge_count]%</div>"
|
||||
|
||||
var/datum/browser/popup = new(user, "gravgen", name)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
|
||||
/obj/machinery/gravity_generator/main/Topic(href, href_list)
|
||||
|
||||
if(..())
|
||||
return
|
||||
|
||||
if(href_list["gentoggle"])
|
||||
breaker = !breaker
|
||||
investigate_log("was toggled [breaker ? "<font color='green'>ON</font>" : "<font color='red'>OFF</font>"] by [key_name(usr)].", INVESTIGATE_GRAVITY)
|
||||
set_power()
|
||||
src.updateUsrDialog()
|
||||
|
||||
// Power and Icon States
|
||||
|
||||
/obj/machinery/gravity_generator/main/power_change()
|
||||
..()
|
||||
investigate_log("has [stat & NOPOWER ? "lost" : "regained"] power.", INVESTIGATE_GRAVITY)
|
||||
set_power()
|
||||
|
||||
/obj/machinery/gravity_generator/main/get_status()
|
||||
if(stat & BROKEN)
|
||||
return "fix[min(broken_state, 3)]"
|
||||
return on || charging_state != POWER_IDLE ? "on" : "off"
|
||||
|
||||
/obj/machinery/gravity_generator/main/update_icon()
|
||||
..()
|
||||
for(var/obj/O in parts)
|
||||
O.update_icon()
|
||||
|
||||
// Set the charging state based on power/breaker.
|
||||
/obj/machinery/gravity_generator/main/proc/set_power()
|
||||
var/new_state = FALSE
|
||||
if(stat & (NOPOWER|BROKEN) || !breaker)
|
||||
new_state = FALSE
|
||||
else if(breaker)
|
||||
new_state = TRUE
|
||||
|
||||
charging_state = new_state ? POWER_UP : POWER_DOWN // Startup sequence animation.
|
||||
investigate_log("is now [charging_state == POWER_UP ? "charging" : "discharging"].", INVESTIGATE_GRAVITY)
|
||||
update_icon()
|
||||
|
||||
// Set the state of the gravity.
|
||||
/obj/machinery/gravity_generator/main/proc/set_state(new_state)
|
||||
charging_state = POWER_IDLE
|
||||
on = new_state
|
||||
use_power = on ? ACTIVE_POWER_USE : IDLE_POWER_USE
|
||||
// Sound the alert if gravity was just enabled or disabled.
|
||||
var/alert = FALSE
|
||||
if(SSticker.IsRoundInProgress())
|
||||
if(on) // If we turned on and the game is live.
|
||||
if(gravity_in_level() == FALSE)
|
||||
alert = TRUE
|
||||
investigate_log("was brought online and is now producing gravity for this level.", INVESTIGATE_GRAVITY)
|
||||
message_admins("The gravity generator was brought online [ADMIN_VERBOSEJMP(src)]")
|
||||
else
|
||||
if(gravity_in_level() == TRUE)
|
||||
alert = TRUE
|
||||
investigate_log("was brought offline and there is now no gravity for this level.", INVESTIGATE_GRAVITY)
|
||||
message_admins("The gravity generator was brought offline with no backup generator. [ADMIN_VERBOSEJMP(src)]")
|
||||
|
||||
update_icon()
|
||||
update_list()
|
||||
src.updateUsrDialog()
|
||||
if(alert)
|
||||
shake_everyone()
|
||||
|
||||
// Charge/Discharge and turn on/off gravity when you reach 0/100 percent.
|
||||
// Also emit radiation and handle the overlays.
|
||||
/obj/machinery/gravity_generator/main/process()
|
||||
if(stat & BROKEN)
|
||||
return
|
||||
if(charging_state != POWER_IDLE)
|
||||
if(charging_state == POWER_UP && charge_count >= 100)
|
||||
set_state(1)
|
||||
else if(charging_state == POWER_DOWN && charge_count <= 0)
|
||||
set_state(0)
|
||||
else
|
||||
if(charging_state == POWER_UP)
|
||||
charge_count += 2
|
||||
else if(charging_state == POWER_DOWN)
|
||||
charge_count -= 2
|
||||
|
||||
if(charge_count % 4 == 0 && prob(75)) // Let them know it is charging/discharging.
|
||||
playsound(src.loc, 'sound/effects/empulse.ogg', 100, 1)
|
||||
|
||||
updateDialog()
|
||||
if(prob(25)) // To help stop "Your clothes feel warm." spam.
|
||||
pulse_radiation()
|
||||
|
||||
var/overlay_state = null
|
||||
switch(charge_count)
|
||||
if(0 to 20)
|
||||
overlay_state = null
|
||||
if(21 to 40)
|
||||
overlay_state = "startup"
|
||||
if(41 to 60)
|
||||
overlay_state = "idle"
|
||||
if(61 to 80)
|
||||
overlay_state = "activating"
|
||||
if(81 to 100)
|
||||
overlay_state = "activated"
|
||||
|
||||
if(overlay_state != current_overlay)
|
||||
if(middle)
|
||||
middle.cut_overlays()
|
||||
if(overlay_state)
|
||||
middle.add_overlay(overlay_state)
|
||||
current_overlay = overlay_state
|
||||
|
||||
|
||||
/obj/machinery/gravity_generator/main/proc/pulse_radiation()
|
||||
radiation_pulse(src, 200)
|
||||
|
||||
// Shake everyone on the z level to let them know that gravity was enagaged/disenagaged.
|
||||
/obj/machinery/gravity_generator/main/proc/shake_everyone()
|
||||
var/turf/T = get_turf(src)
|
||||
var/sound/alert_sound = sound('sound/effects/alert.ogg')
|
||||
for(var/i in GLOB.mob_list)
|
||||
var/mob/M = i
|
||||
if(M.z != z && !(SSmapping.level_trait(z, ZTRAITS_STATION) && SSmapping.level_trait(M.z, ZTRAITS_STATION)))
|
||||
continue
|
||||
M.update_gravity(M.mob_has_gravity())
|
||||
if(M.client)
|
||||
shake_camera(M, 15, 1)
|
||||
M.playsound_local(T, null, 100, 1, 0.5, S = alert_sound)
|
||||
|
||||
/obj/machinery/gravity_generator/main/proc/gravity_in_level()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!T)
|
||||
return FALSE
|
||||
if(GLOB.gravity_generators["[T.z]"])
|
||||
return length(GLOB.gravity_generators["[T.z]"])
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/gravity_generator/main/proc/update_list()
|
||||
var/turf/T = get_turf(src.loc)
|
||||
if(T)
|
||||
var/list/z_list = list()
|
||||
// Multi-Z, station gravity generator generates gravity on all ZTRAIT_STATION z-levels.
|
||||
if(SSmapping.level_trait(T.z, ZTRAIT_STATION))
|
||||
for(var/z in SSmapping.levels_by_trait(ZTRAIT_STATION))
|
||||
z_list += z
|
||||
else
|
||||
z_list += T.z
|
||||
for(var/z in z_list)
|
||||
if(!GLOB.gravity_generators["[z]"])
|
||||
GLOB.gravity_generators["[z]"] = list()
|
||||
if(on)
|
||||
GLOB.gravity_generators["[z]"] |= src
|
||||
else
|
||||
GLOB.gravity_generators["[z]"] -= src
|
||||
|
||||
/obj/machinery/gravity_generator/main/proc/change_setting(value)
|
||||
if(value != setting)
|
||||
setting = value
|
||||
shake_everyone()
|
||||
|
||||
// Misc
|
||||
|
||||
/obj/item/paper/guides/jobs/engi/gravity_gen
|
||||
name = "paper- 'Generate your own gravity!'"
|
||||
info = {"<h1>Gravity Generator Instructions For Dummies</h1>
|
||||
<p>Surprisingly, gravity isn't that hard to make! All you have to do is inject deadly radioactive minerals into a ball of
|
||||
energy and you have yourself gravity! You can turn the machine on or off when required but you must remember that the generator
|
||||
will EMIT RADIATION when charging or discharging, you can tell it is charging or discharging by the noise it makes, so please WEAR PROTECTIVE CLOTHING.</p>
|
||||
<br>
|
||||
<h3>It blew up!</h3>
|
||||
<p>Don't panic! The gravity generator was designed to be easily repaired. If, somehow, the sturdy framework did not survive then
|
||||
please proceed to panic; otherwise follow these steps.</p><ol>
|
||||
<li>Secure the screws of the framework with a screwdriver.</li>
|
||||
<li>Mend the damaged framework with a welding tool.</li>
|
||||
<li>Add additional plasteel plating.</li>
|
||||
<li>Secure the additional plating with a wrench.</li></ol>"}
|
||||
|
||||
//
|
||||
// Gravity Generator
|
||||
//
|
||||
|
||||
GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding new gravity generators to the list, and keying it with the z level.
|
||||
|
||||
#define POWER_IDLE 0
|
||||
#define POWER_UP 1
|
||||
#define POWER_DOWN 2
|
||||
|
||||
#define GRAV_NEEDS_SCREWDRIVER 0
|
||||
#define GRAV_NEEDS_WELDING 1
|
||||
#define GRAV_NEEDS_PLASTEEL 2
|
||||
#define GRAV_NEEDS_WRENCH 3
|
||||
|
||||
//
|
||||
// Abstract Generator
|
||||
//
|
||||
|
||||
/obj/machinery/gravity_generator
|
||||
name = "gravitational generator"
|
||||
desc = "A device which produces a graviton field when set up."
|
||||
icon = 'icons/obj/machines/gravity_generator.dmi'
|
||||
density = TRUE
|
||||
use_power = NO_POWER_USE
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
var/sprite_number = 0
|
||||
|
||||
/obj/machinery/gravity_generator/safe_throw_at()
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/gravity_generator/ex_act(severity, target)
|
||||
if(severity == 1) // Very sturdy.
|
||||
set_broken()
|
||||
|
||||
/obj/machinery/gravity_generator/blob_act(obj/structure/blob/B)
|
||||
if(prob(20))
|
||||
set_broken()
|
||||
|
||||
/obj/machinery/gravity_generator/tesla_act(power, tesla_flags)
|
||||
..()
|
||||
if(tesla_flags & TESLA_MACHINE_EXPLOSIVE)
|
||||
qdel(src)//like the singulo, tesla deletes it. stops it from exploding over and over
|
||||
|
||||
/obj/machinery/gravity_generator/update_icon()
|
||||
..()
|
||||
icon_state = "[get_status()]_[sprite_number]"
|
||||
|
||||
/obj/machinery/gravity_generator/proc/get_status()
|
||||
return "off"
|
||||
|
||||
// You aren't allowed to move.
|
||||
/obj/machinery/gravity_generator/Move()
|
||||
. = ..()
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/gravity_generator/proc/set_broken()
|
||||
stat |= BROKEN
|
||||
|
||||
/obj/machinery/gravity_generator/proc/set_fix()
|
||||
stat &= ~BROKEN
|
||||
|
||||
/obj/machinery/gravity_generator/part/Destroy()
|
||||
if(main_part)
|
||||
qdel(main_part)
|
||||
set_broken()
|
||||
return ..()
|
||||
|
||||
//
|
||||
// Part generator which is mostly there for looks
|
||||
//
|
||||
|
||||
/obj/machinery/gravity_generator/part
|
||||
var/obj/machinery/gravity_generator/main/main_part = null
|
||||
|
||||
/obj/machinery/gravity_generator/part/attackby(obj/item/I, mob/user, params)
|
||||
return main_part.attackby(I, user)
|
||||
|
||||
/obj/machinery/gravity_generator/part/get_status()
|
||||
return main_part.get_status()
|
||||
|
||||
/obj/machinery/gravity_generator/part/attack_hand(mob/user)
|
||||
return main_part.attack_hand(user)
|
||||
|
||||
/obj/machinery/gravity_generator/part/set_broken()
|
||||
..()
|
||||
if(main_part && !(main_part.stat & BROKEN))
|
||||
main_part.set_broken()
|
||||
|
||||
//
|
||||
// Generator which spawns with the station.
|
||||
//
|
||||
|
||||
/obj/machinery/gravity_generator/main/station/Initialize()
|
||||
. = ..()
|
||||
setup_parts()
|
||||
middle.add_overlay("activated")
|
||||
update_list()
|
||||
|
||||
//
|
||||
// Generator an admin can spawn
|
||||
//
|
||||
/obj/machinery/gravity_generator/main/station/admin
|
||||
use_power = NO_POWER_USE
|
||||
|
||||
//
|
||||
// Main Generator with the main code
|
||||
//
|
||||
|
||||
/obj/machinery/gravity_generator/main
|
||||
icon_state = "on_8"
|
||||
idle_power_usage = 0
|
||||
active_power_usage = 3000
|
||||
power_channel = ENVIRON
|
||||
sprite_number = 8
|
||||
use_power = IDLE_POWER_USE
|
||||
interaction_flags_machine = INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OFFLINE
|
||||
var/on = TRUE
|
||||
var/breaker = TRUE
|
||||
var/list/parts = list()
|
||||
var/obj/middle = null
|
||||
var/charging_state = POWER_IDLE
|
||||
var/charge_count = 100
|
||||
var/current_overlay = null
|
||||
var/broken_state = 0
|
||||
var/setting = 1 //Gravity value when on
|
||||
|
||||
/obj/machinery/gravity_generator/main/Destroy() // If we somehow get deleted, remove all of our other parts.
|
||||
investigate_log("was destroyed!", INVESTIGATE_GRAVITY)
|
||||
on = FALSE
|
||||
update_list()
|
||||
for(var/obj/machinery/gravity_generator/part/O in parts)
|
||||
O.main_part = null
|
||||
if(!QDESTROYING(O))
|
||||
qdel(O)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/gravity_generator/main/proc/setup_parts()
|
||||
var/turf/our_turf = get_turf(src)
|
||||
// 9x9 block obtained from the bottom middle of the block
|
||||
var/list/spawn_turfs = block(locate(our_turf.x - 1, our_turf.y + 2, our_turf.z), locate(our_turf.x + 1, our_turf.y, our_turf.z))
|
||||
var/count = 10
|
||||
for(var/turf/T in spawn_turfs)
|
||||
count--
|
||||
if(T == our_turf) // Skip our turf.
|
||||
continue
|
||||
var/obj/machinery/gravity_generator/part/part = new(T)
|
||||
if(count == 5) // Middle
|
||||
middle = part
|
||||
if(count <= 3) // Their sprite is the top part of the generator
|
||||
part.density = FALSE
|
||||
part.layer = WALL_OBJ_LAYER
|
||||
part.sprite_number = count
|
||||
part.main_part = src
|
||||
parts += part
|
||||
part.update_icon()
|
||||
|
||||
/obj/machinery/gravity_generator/main/proc/connected_parts()
|
||||
return parts.len == 8
|
||||
|
||||
/obj/machinery/gravity_generator/main/set_broken()
|
||||
..()
|
||||
for(var/obj/machinery/gravity_generator/M in parts)
|
||||
if(!(M.stat & BROKEN))
|
||||
M.set_broken()
|
||||
middle.cut_overlays()
|
||||
charge_count = 0
|
||||
breaker = FALSE
|
||||
set_power()
|
||||
set_state(0)
|
||||
investigate_log("has broken down.", INVESTIGATE_GRAVITY)
|
||||
|
||||
/obj/machinery/gravity_generator/main/set_fix()
|
||||
..()
|
||||
for(var/obj/machinery/gravity_generator/M in parts)
|
||||
if(M.stat & BROKEN)
|
||||
M.set_fix()
|
||||
broken_state = FALSE
|
||||
update_icon()
|
||||
set_power()
|
||||
|
||||
// Interaction
|
||||
|
||||
// Fixing the gravity generator.
|
||||
/obj/machinery/gravity_generator/main/attackby(obj/item/I, mob/user, params)
|
||||
switch(broken_state)
|
||||
if(GRAV_NEEDS_SCREWDRIVER)
|
||||
if(istype(I, /obj/item/screwdriver))
|
||||
to_chat(user, "<span class='notice'>You secure the screws of the framework.</span>")
|
||||
I.play_tool_sound(src)
|
||||
broken_state++
|
||||
update_icon()
|
||||
return
|
||||
if(GRAV_NEEDS_WELDING)
|
||||
if(istype(I, /obj/item/weldingtool))
|
||||
if(I.use_tool(src, user, 0, volume=50, amount=1))
|
||||
to_chat(user, "<span class='notice'>You mend the damaged framework.</span>")
|
||||
broken_state++
|
||||
update_icon()
|
||||
return
|
||||
if(GRAV_NEEDS_PLASTEEL)
|
||||
if(istype(I, /obj/item/stack/sheet/plasteel))
|
||||
var/obj/item/stack/sheet/plasteel/PS = I
|
||||
if(PS.get_amount() >= 10)
|
||||
PS.use(10)
|
||||
to_chat(user, "<span class='notice'>You add the plating to the framework.</span>")
|
||||
playsound(src.loc, 'sound/machines/click.ogg', 75, 1)
|
||||
broken_state++
|
||||
update_icon()
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need 10 sheets of plasteel!</span>")
|
||||
return
|
||||
if(GRAV_NEEDS_WRENCH)
|
||||
if(istype(I, /obj/item/wrench))
|
||||
to_chat(user, "<span class='notice'>You secure the plating to the framework.</span>")
|
||||
I.play_tool_sound(src)
|
||||
set_fix()
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/machinery/gravity_generator/main/ui_interact(mob/user)
|
||||
if(stat & BROKEN)
|
||||
return
|
||||
var/dat = "Gravity Generator Breaker: "
|
||||
if(breaker)
|
||||
dat += "<span class='linkOn'>ON</span> <A href='?src=[REF(src)];gentoggle=1'>OFF</A>"
|
||||
else
|
||||
dat += "<A href='?src=[REF(src)];gentoggle=1'>ON</A> <span class='linkOn'>OFF</span> "
|
||||
|
||||
dat += "<br>Generator Status:<br><div class='statusDisplay'>"
|
||||
if(charging_state != POWER_IDLE)
|
||||
dat += "<font class='bad'>WARNING</font> Radiation Detected. <br>[charging_state == POWER_UP ? "Charging..." : "Discharging..."]"
|
||||
else if(on)
|
||||
dat += "Powered."
|
||||
else
|
||||
dat += "Unpowered."
|
||||
|
||||
dat += "<br>Gravity Charge: [charge_count]%</div>"
|
||||
|
||||
var/datum/browser/popup = new(user, "gravgen", name)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
|
||||
/obj/machinery/gravity_generator/main/Topic(href, href_list)
|
||||
|
||||
if(..())
|
||||
return
|
||||
|
||||
if(href_list["gentoggle"])
|
||||
breaker = !breaker
|
||||
investigate_log("was toggled [breaker ? "<font color='green'>ON</font>" : "<font color='red'>OFF</font>"] by [key_name(usr)].", INVESTIGATE_GRAVITY)
|
||||
set_power()
|
||||
src.updateUsrDialog()
|
||||
|
||||
// Power and Icon States
|
||||
|
||||
/obj/machinery/gravity_generator/main/power_change()
|
||||
..()
|
||||
investigate_log("has [stat & NOPOWER ? "lost" : "regained"] power.", INVESTIGATE_GRAVITY)
|
||||
set_power()
|
||||
|
||||
/obj/machinery/gravity_generator/main/get_status()
|
||||
if(stat & BROKEN)
|
||||
return "fix[min(broken_state, 3)]"
|
||||
return on || charging_state != POWER_IDLE ? "on" : "off"
|
||||
|
||||
/obj/machinery/gravity_generator/main/update_icon()
|
||||
..()
|
||||
for(var/obj/O in parts)
|
||||
O.update_icon()
|
||||
|
||||
// Set the charging state based on power/breaker.
|
||||
/obj/machinery/gravity_generator/main/proc/set_power()
|
||||
var/new_state = FALSE
|
||||
if(stat & (NOPOWER|BROKEN) || !breaker)
|
||||
new_state = FALSE
|
||||
else if(breaker)
|
||||
new_state = TRUE
|
||||
|
||||
charging_state = new_state ? POWER_UP : POWER_DOWN // Startup sequence animation.
|
||||
investigate_log("is now [charging_state == POWER_UP ? "charging" : "discharging"].", INVESTIGATE_GRAVITY)
|
||||
update_icon()
|
||||
|
||||
// Set the state of the gravity.
|
||||
/obj/machinery/gravity_generator/main/proc/set_state(new_state)
|
||||
charging_state = POWER_IDLE
|
||||
on = new_state
|
||||
use_power = on ? ACTIVE_POWER_USE : IDLE_POWER_USE
|
||||
// Sound the alert if gravity was just enabled or disabled.
|
||||
var/alert = FALSE
|
||||
if(SSticker.IsRoundInProgress())
|
||||
if(on) // If we turned on and the game is live.
|
||||
if(gravity_in_level() == FALSE)
|
||||
alert = TRUE
|
||||
investigate_log("was brought online and is now producing gravity for this level.", INVESTIGATE_GRAVITY)
|
||||
message_admins("The gravity generator was brought online [ADMIN_VERBOSEJMP(src)]")
|
||||
else
|
||||
if(gravity_in_level() == TRUE)
|
||||
alert = TRUE
|
||||
investigate_log("was brought offline and there is now no gravity for this level.", INVESTIGATE_GRAVITY)
|
||||
message_admins("The gravity generator was brought offline with no backup generator. [ADMIN_VERBOSEJMP(src)]")
|
||||
|
||||
update_icon()
|
||||
update_list()
|
||||
src.updateUsrDialog()
|
||||
if(alert)
|
||||
shake_everyone()
|
||||
|
||||
// Charge/Discharge and turn on/off gravity when you reach 0/100 percent.
|
||||
// Also emit radiation and handle the overlays.
|
||||
/obj/machinery/gravity_generator/main/process()
|
||||
if(stat & BROKEN)
|
||||
return
|
||||
if(charging_state != POWER_IDLE)
|
||||
if(charging_state == POWER_UP && charge_count >= 100)
|
||||
set_state(1)
|
||||
else if(charging_state == POWER_DOWN && charge_count <= 0)
|
||||
set_state(0)
|
||||
else
|
||||
if(charging_state == POWER_UP)
|
||||
charge_count += 2
|
||||
else if(charging_state == POWER_DOWN)
|
||||
charge_count -= 2
|
||||
|
||||
if(charge_count % 4 == 0 && prob(75)) // Let them know it is charging/discharging.
|
||||
playsound(src.loc, 'sound/effects/empulse.ogg', 100, 1)
|
||||
|
||||
updateDialog()
|
||||
if(prob(25)) // To help stop "Your clothes feel warm." spam.
|
||||
pulse_radiation()
|
||||
|
||||
var/overlay_state = null
|
||||
switch(charge_count)
|
||||
if(0 to 20)
|
||||
overlay_state = null
|
||||
if(21 to 40)
|
||||
overlay_state = "startup"
|
||||
if(41 to 60)
|
||||
overlay_state = "idle"
|
||||
if(61 to 80)
|
||||
overlay_state = "activating"
|
||||
if(81 to 100)
|
||||
overlay_state = "activated"
|
||||
|
||||
if(overlay_state != current_overlay)
|
||||
if(middle)
|
||||
middle.cut_overlays()
|
||||
if(overlay_state)
|
||||
middle.add_overlay(overlay_state)
|
||||
current_overlay = overlay_state
|
||||
|
||||
|
||||
/obj/machinery/gravity_generator/main/proc/pulse_radiation()
|
||||
radiation_pulse(src, 200)
|
||||
|
||||
// Shake everyone on the z level to let them know that gravity was enagaged/disenagaged.
|
||||
/obj/machinery/gravity_generator/main/proc/shake_everyone()
|
||||
var/turf/T = get_turf(src)
|
||||
var/sound/alert_sound = sound('sound/effects/alert.ogg')
|
||||
for(var/i in GLOB.mob_list)
|
||||
var/mob/M = i
|
||||
if(M.z != z && !(SSmapping.level_trait(z, ZTRAITS_STATION) && SSmapping.level_trait(M.z, ZTRAITS_STATION)))
|
||||
continue
|
||||
M.update_gravity(M.mob_has_gravity())
|
||||
if(M.client)
|
||||
shake_camera(M, 15, 1)
|
||||
M.playsound_local(T, null, 100, 1, 0.5, S = alert_sound)
|
||||
|
||||
/obj/machinery/gravity_generator/main/proc/gravity_in_level()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!T)
|
||||
return FALSE
|
||||
if(GLOB.gravity_generators["[T.z]"])
|
||||
return length(GLOB.gravity_generators["[T.z]"])
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/gravity_generator/main/proc/update_list()
|
||||
var/turf/T = get_turf(src.loc)
|
||||
if(T)
|
||||
var/list/z_list = list()
|
||||
// Multi-Z, station gravity generator generates gravity on all ZTRAIT_STATION z-levels.
|
||||
if(SSmapping.level_trait(T.z, ZTRAIT_STATION))
|
||||
for(var/z in SSmapping.levels_by_trait(ZTRAIT_STATION))
|
||||
z_list += z
|
||||
else
|
||||
z_list += T.z
|
||||
for(var/z in z_list)
|
||||
if(!GLOB.gravity_generators["[z]"])
|
||||
GLOB.gravity_generators["[z]"] = list()
|
||||
if(on)
|
||||
GLOB.gravity_generators["[z]"] |= src
|
||||
else
|
||||
GLOB.gravity_generators["[z]"] -= src
|
||||
|
||||
/obj/machinery/gravity_generator/main/proc/change_setting(value)
|
||||
if(value != setting)
|
||||
setting = value
|
||||
shake_everyone()
|
||||
|
||||
// Misc
|
||||
|
||||
/obj/item/paper/guides/jobs/engi/gravity_gen
|
||||
name = "paper- 'Generate your own gravity!'"
|
||||
info = {"<h1>Gravity Generator Instructions For Dummies</h1>
|
||||
<p>Surprisingly, gravity isn't that hard to make! All you have to do is inject deadly radioactive minerals into a ball of
|
||||
energy and you have yourself gravity! You can turn the machine on or off when required but you must remember that the generator
|
||||
will EMIT RADIATION when charging or discharging, you can tell it is charging or discharging by the noise it makes, so please WEAR PROTECTIVE CLOTHING.</p>
|
||||
<br>
|
||||
<h3>It blew up!</h3>
|
||||
<p>Don't panic! The gravity generator was designed to be easily repaired. If, somehow, the sturdy framework did not survive then
|
||||
please proceed to panic; otherwise follow these steps.</p><ol>
|
||||
<li>Secure the screws of the framework with a screwdriver.</li>
|
||||
<li>Mend the damaged framework with a welding tool.</li>
|
||||
<li>Add additional plasteel plating.</li>
|
||||
<li>Secure the additional plating with a wrench.</li></ol>"}
|
||||
|
||||
@@ -719,7 +719,7 @@
|
||||
var/base_state
|
||||
var/switchcount = 0 // number of times switched
|
||||
materials = list(MAT_GLASS=100)
|
||||
grind_results = list("silicon" = 5, "nitrogen" = 10) //Nitrogen is used as a cheaper alternative to argon in incandescent lighbulbs
|
||||
grind_results = list(/datum/reagent/silicon = 5, /datum/reagent/nitrogen = 10) //Nitrogen is used as a cheaper alternative to argon in incandescent lighbulbs
|
||||
var/rigged = 0 // true if rigged to explode
|
||||
var/brightness = 2 //how much light it gives off
|
||||
|
||||
@@ -789,7 +789,7 @@
|
||||
|
||||
to_chat(user, "<span class='notice'>You inject the solution into \the [src].</span>")
|
||||
|
||||
if(S.reagents.has_reagent("plasma", 5))
|
||||
if(S.reagents.has_reagent(/datum/reagent/toxin/plasma, 5))
|
||||
|
||||
rigged = 1
|
||||
|
||||
|
||||
+121
-121
@@ -1,121 +1,121 @@
|
||||
//modular computer program version is located in code\modules\modular_computers\file_system\programs\powermonitor.dm, /datum/computer_file/program/power_monitor
|
||||
|
||||
/obj/machinery/computer/monitor
|
||||
name = "power monitoring console"
|
||||
desc = "It monitors power levels across the station."
|
||||
icon_screen = "power"
|
||||
icon_keyboard = "power_key"
|
||||
light_color = LIGHT_COLOR_YELLOW
|
||||
use_power = ACTIVE_POWER_USE
|
||||
idle_power_usage = 20
|
||||
active_power_usage = 100
|
||||
circuit = /obj/item/circuitboard/computer/powermonitor
|
||||
|
||||
var/obj/structure/cable/attached_wire
|
||||
var/obj/machinery/power/apc/local_apc
|
||||
|
||||
var/list/history = list()
|
||||
var/record_size = 60
|
||||
var/record_interval = 50
|
||||
var/next_record = 0
|
||||
var/is_secret_monitor = FALSE
|
||||
|
||||
/obj/machinery/computer/monitor/secret //Hides the power monitor (such as ones on ruins & CentCom) from PDA's to prevent metagaming.
|
||||
name = "outdated power monitoring console"
|
||||
desc = "It monitors power levels across the local powernet."
|
||||
circuit = /obj/item/circuitboard/computer/powermonitor/secret
|
||||
is_secret_monitor = TRUE
|
||||
|
||||
/obj/machinery/computer/monitor/secret/examine(mob/user)
|
||||
. = ..()
|
||||
. += "<span class='notice'>It's operating system seems quite outdated... It doesn't seem like it'd be compatible with the latest remote NTOS monitoring systems.</span>"
|
||||
|
||||
/obj/machinery/computer/monitor/Initialize()
|
||||
. = ..()
|
||||
search()
|
||||
history["supply"] = list()
|
||||
history["demand"] = list()
|
||||
|
||||
/obj/machinery/computer/monitor/process()
|
||||
if(!get_powernet())
|
||||
use_power = IDLE_POWER_USE
|
||||
search()
|
||||
else
|
||||
use_power = ACTIVE_POWER_USE
|
||||
record()
|
||||
|
||||
/obj/machinery/computer/monitor/proc/search() //keep in sync with /datum/computer_file/program/power_monitor's version
|
||||
var/turf/T = get_turf(src)
|
||||
attached_wire = locate(/obj/structure/cable) in T
|
||||
if(attached_wire)
|
||||
return
|
||||
var/area/A = get_area(src) //if the computer isn't directly connected to a wire, attempt to find the APC powering it to pull it's powernet instead
|
||||
if(!A)
|
||||
return
|
||||
local_apc = A.get_apc()
|
||||
if(!local_apc)
|
||||
return
|
||||
if(!local_apc.terminal) //this really shouldn't happen without badminnery.
|
||||
local_apc = null
|
||||
|
||||
/obj/machinery/computer/monitor/proc/get_powernet() //keep in sync with /datum/computer_file/program/power_monitor's version
|
||||
if(attached_wire || (local_apc && local_apc.terminal))
|
||||
return attached_wire ? attached_wire.powernet : local_apc.terminal.powernet
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/computer/monitor/proc/record() //keep in sync with /datum/computer_file/program/power_monitor's version
|
||||
if(world.time >= next_record)
|
||||
next_record = world.time + record_interval
|
||||
|
||||
var/datum/powernet/connected_powernet = get_powernet()
|
||||
|
||||
var/list/supply = history["supply"]
|
||||
if(connected_powernet)
|
||||
supply += connected_powernet.viewavail
|
||||
if(supply.len > record_size)
|
||||
supply.Cut(1, 2)
|
||||
|
||||
var/list/demand = history["demand"]
|
||||
if(connected_powernet)
|
||||
demand += connected_powernet.viewload
|
||||
if(demand.len > record_size)
|
||||
demand.Cut(1, 2)
|
||||
|
||||
/obj/machinery/computer/monitor/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "power_monitor", name, 1200, 1000, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/monitor/ui_data()
|
||||
var/datum/powernet/connected_powernet = get_powernet()
|
||||
var/list/data = list()
|
||||
data["stored"] = record_size
|
||||
data["interval"] = record_interval / 10
|
||||
data["attached"] = connected_powernet ? TRUE : FALSE
|
||||
data["history"] = history
|
||||
data["areas"] = list()
|
||||
|
||||
if(connected_powernet)
|
||||
data["supply"] = DisplayPower(connected_powernet.viewavail)
|
||||
data["demand"] = DisplayPower(connected_powernet.viewload)
|
||||
for(var/obj/machinery/power/terminal/term in connected_powernet.nodes)
|
||||
var/obj/machinery/power/apc/A = term.master
|
||||
if(istype(A))
|
||||
var/cell_charge
|
||||
if(!A.cell)
|
||||
cell_charge = 0
|
||||
else
|
||||
cell_charge = A.cell.percent()
|
||||
data["areas"] += list(list(
|
||||
"name" = A.area.name,
|
||||
"charge" = cell_charge,
|
||||
"load" = DisplayPower(A.lastused_total),
|
||||
"charging" = A.charging,
|
||||
"eqp" = A.equipment,
|
||||
"lgt" = A.lighting,
|
||||
"env" = A.environ
|
||||
))
|
||||
|
||||
return data
|
||||
//modular computer program version is located in code\modules\modular_computers\file_system\programs\powermonitor.dm, /datum/computer_file/program/power_monitor
|
||||
|
||||
/obj/machinery/computer/monitor
|
||||
name = "power monitoring console"
|
||||
desc = "It monitors power levels across the station."
|
||||
icon_screen = "power"
|
||||
icon_keyboard = "power_key"
|
||||
light_color = LIGHT_COLOR_YELLOW
|
||||
use_power = ACTIVE_POWER_USE
|
||||
idle_power_usage = 20
|
||||
active_power_usage = 100
|
||||
circuit = /obj/item/circuitboard/computer/powermonitor
|
||||
|
||||
var/obj/structure/cable/attached_wire
|
||||
var/obj/machinery/power/apc/local_apc
|
||||
|
||||
var/list/history = list()
|
||||
var/record_size = 60
|
||||
var/record_interval = 50
|
||||
var/next_record = 0
|
||||
var/is_secret_monitor = FALSE
|
||||
|
||||
/obj/machinery/computer/monitor/secret //Hides the power monitor (such as ones on ruins & CentCom) from PDA's to prevent metagaming.
|
||||
name = "outdated power monitoring console"
|
||||
desc = "It monitors power levels across the local powernet."
|
||||
circuit = /obj/item/circuitboard/computer/powermonitor/secret
|
||||
is_secret_monitor = TRUE
|
||||
|
||||
/obj/machinery/computer/monitor/secret/examine(mob/user)
|
||||
. = ..()
|
||||
. += "<span class='notice'>It's operating system seems quite outdated... It doesn't seem like it'd be compatible with the latest remote NTOS monitoring systems.</span>"
|
||||
|
||||
/obj/machinery/computer/monitor/Initialize()
|
||||
. = ..()
|
||||
search()
|
||||
history["supply"] = list()
|
||||
history["demand"] = list()
|
||||
|
||||
/obj/machinery/computer/monitor/process()
|
||||
if(!get_powernet())
|
||||
use_power = IDLE_POWER_USE
|
||||
search()
|
||||
else
|
||||
use_power = ACTIVE_POWER_USE
|
||||
record()
|
||||
|
||||
/obj/machinery/computer/monitor/proc/search() //keep in sync with /datum/computer_file/program/power_monitor's version
|
||||
var/turf/T = get_turf(src)
|
||||
attached_wire = locate(/obj/structure/cable) in T
|
||||
if(attached_wire)
|
||||
return
|
||||
var/area/A = get_area(src) //if the computer isn't directly connected to a wire, attempt to find the APC powering it to pull it's powernet instead
|
||||
if(!A)
|
||||
return
|
||||
local_apc = A.get_apc()
|
||||
if(!local_apc)
|
||||
return
|
||||
if(!local_apc.terminal) //this really shouldn't happen without badminnery.
|
||||
local_apc = null
|
||||
|
||||
/obj/machinery/computer/monitor/proc/get_powernet() //keep in sync with /datum/computer_file/program/power_monitor's version
|
||||
if(attached_wire || (local_apc && local_apc.terminal))
|
||||
return attached_wire ? attached_wire.powernet : local_apc.terminal.powernet
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/computer/monitor/proc/record() //keep in sync with /datum/computer_file/program/power_monitor's version
|
||||
if(world.time >= next_record)
|
||||
next_record = world.time + record_interval
|
||||
|
||||
var/datum/powernet/connected_powernet = get_powernet()
|
||||
|
||||
var/list/supply = history["supply"]
|
||||
if(connected_powernet)
|
||||
supply += connected_powernet.viewavail
|
||||
if(supply.len > record_size)
|
||||
supply.Cut(1, 2)
|
||||
|
||||
var/list/demand = history["demand"]
|
||||
if(connected_powernet)
|
||||
demand += connected_powernet.viewload
|
||||
if(demand.len > record_size)
|
||||
demand.Cut(1, 2)
|
||||
|
||||
/obj/machinery/computer/monitor/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "power_monitor", name, 1200, 1000, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/monitor/ui_data()
|
||||
var/datum/powernet/connected_powernet = get_powernet()
|
||||
var/list/data = list()
|
||||
data["stored"] = record_size
|
||||
data["interval"] = record_interval / 10
|
||||
data["attached"] = connected_powernet ? TRUE : FALSE
|
||||
data["history"] = history
|
||||
data["areas"] = list()
|
||||
|
||||
if(connected_powernet)
|
||||
data["supply"] = DisplayPower(connected_powernet.viewavail)
|
||||
data["demand"] = DisplayPower(connected_powernet.viewload)
|
||||
for(var/obj/machinery/power/terminal/term in connected_powernet.nodes)
|
||||
var/obj/machinery/power/apc/A = term.master
|
||||
if(istype(A))
|
||||
var/cell_charge
|
||||
if(!A.cell)
|
||||
cell_charge = 0
|
||||
else
|
||||
cell_charge = A.cell.percent()
|
||||
data["areas"] += list(list(
|
||||
"name" = A.area.name,
|
||||
"charge" = cell_charge,
|
||||
"load" = DisplayPower(A.lastused_total),
|
||||
"charging" = A.charging,
|
||||
"eqp" = A.equipment,
|
||||
"lgt" = A.lighting,
|
||||
"env" = A.environ
|
||||
))
|
||||
|
||||
return data
|
||||
|
||||
+287
-287
@@ -1,287 +1,287 @@
|
||||
|
||||
//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 = "portable generator"
|
||||
desc = "A portable generator for emergency backup power."
|
||||
icon = 'icons/obj/power.dmi'
|
||||
icon_state = "portgen0_0"
|
||||
density = TRUE
|
||||
anchored = FALSE
|
||||
use_power = NO_POWER_USE
|
||||
|
||||
var/active = 0
|
||||
var/power_gen = 5000
|
||||
var/recent_fault = 0
|
||||
var/power_output = 1
|
||||
var/consumption = 0
|
||||
var/base_icon = "portgen0"
|
||||
var/datum/looping_sound/generator/soundloop
|
||||
|
||||
interaction_flags_atom = INTERACT_ATOM_ATTACK_HAND | INTERACT_ATOM_UI_INTERACT | INTERACT_ATOM_REQUIRES_ANCHORED
|
||||
|
||||
/obj/machinery/power/port_gen/Initialize()
|
||||
. = ..()
|
||||
soundloop = new(list(src), active)
|
||||
|
||||
/obj/machinery/power/port_gen/Destroy()
|
||||
QDEL_NULL(soundloop)
|
||||
return ..()
|
||||
|
||||
/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/update_icon()
|
||||
icon_state = "[base_icon]_[active]"
|
||||
|
||||
/obj/machinery/power/port_gen/process()
|
||||
if(active && HasFuel() && !crit_fail && anchored && powernet)
|
||||
add_avail(power_gen * power_output)
|
||||
UseFuel()
|
||||
src.updateDialog()
|
||||
soundloop.start()
|
||||
|
||||
else
|
||||
active = 0
|
||||
handleInactive()
|
||||
update_icon()
|
||||
soundloop.stop()
|
||||
|
||||
/obj/machinery/power/port_gen/examine(mob/user)
|
||||
. = ..()
|
||||
. += "It is[!active?"n't":""] running."
|
||||
|
||||
/obj/machinery/power/port_gen/pacman
|
||||
name = "\improper P.A.C.M.A.N.-type portable generator"
|
||||
circuit = /obj/item/circuitboard/machine/pacman
|
||||
var/sheets = 0
|
||||
var/max_sheets = 100
|
||||
var/sheet_name = ""
|
||||
var/sheet_path = /obj/item/stack/sheet/mineral/plasma
|
||||
var/sheet_left = 0 // How much is left of the sheet
|
||||
var/time_per_sheet = 260
|
||||
var/current_heat = 0
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/Initialize()
|
||||
. = ..()
|
||||
if(anchored)
|
||||
connect_to_network()
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/Initialize()
|
||||
. = ..()
|
||||
|
||||
var/obj/sheet = new sheet_path(null)
|
||||
sheet_name = sheet.name
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/Destroy()
|
||||
DropFuel()
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/RefreshParts()
|
||||
var/temp_rating = 0
|
||||
var/consumption_coeff = 0
|
||||
for(var/obj/item/stock_parts/SP in component_parts)
|
||||
if(istype(SP, /obj/item/stock_parts/matter_bin))
|
||||
max_sheets = SP.rating * SP.rating * 50
|
||||
else if(istype(SP, /obj/item/stock_parts/capacitor))
|
||||
temp_rating += SP.rating
|
||||
else
|
||||
consumption_coeff += SP.rating
|
||||
power_gen = round(initial(power_gen) * temp_rating * 2)
|
||||
consumption = consumption_coeff
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/examine(mob/user)
|
||||
. = ..()
|
||||
. += "<span class='notice'>The generator has [sheets] units of [sheet_name] fuel left, producing [power_gen] per cycle.</span>"
|
||||
if(crit_fail)
|
||||
. += "<span class='danger'>The generator seems to have broken down.</span>"
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/HasFuel()
|
||||
if(sheets >= 1 / (time_per_sheet / power_output) - sheet_left)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/DropFuel()
|
||||
if(sheets)
|
||||
new sheet_path(drop_location(), sheets)
|
||||
sheets = 0
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/UseFuel()
|
||||
var/needed_sheets = 1 / (time_per_sheet * consumption / power_output)
|
||||
var/temp = min(needed_sheets, sheet_left)
|
||||
needed_sheets -= temp
|
||||
sheet_left -= temp
|
||||
sheets -= round(needed_sheets)
|
||||
needed_sheets -= round(needed_sheets)
|
||||
if (sheet_left <= 0 && sheets > 0)
|
||||
sheet_left = 1 - needed_sheets
|
||||
sheets--
|
||||
|
||||
var/lower_limit = 56 + power_output * 10
|
||||
var/upper_limit = 76 + power_output * 10
|
||||
var/bias = 0
|
||||
if (power_output > 4)
|
||||
upper_limit = 400
|
||||
bias = power_output - consumption * (4 - consumption)
|
||||
if (current_heat < lower_limit)
|
||||
current_heat += 4 - consumption
|
||||
else
|
||||
current_heat += rand(-7 + bias, 7 + bias)
|
||||
if (current_heat < lower_limit)
|
||||
current_heat = lower_limit
|
||||
if (current_heat > upper_limit)
|
||||
current_heat = upper_limit
|
||||
|
||||
if (current_heat > 300)
|
||||
overheat()
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/handleInactive()
|
||||
|
||||
if (current_heat > 0)
|
||||
current_heat = max(current_heat - 2, 0)
|
||||
src.updateDialog()
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/proc/overheat()
|
||||
explosion(src.loc, 2, 5, 2, -1)
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/attackby(obj/item/O, mob/user, params)
|
||||
if(istype(O, sheet_path))
|
||||
var/obj/item/stack/addstack = O
|
||||
var/amount = min((max_sheets - sheets), addstack.amount)
|
||||
if(amount < 1)
|
||||
to_chat(user, "<span class='notice'>The [src.name] is full!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You add [amount] sheets to the [src.name].</span>")
|
||||
sheets += amount
|
||||
addstack.use(amount)
|
||||
updateUsrDialog()
|
||||
return
|
||||
else if(!active)
|
||||
|
||||
if(istype(O, /obj/item/wrench))
|
||||
|
||||
if(!anchored && !isinspace())
|
||||
connect_to_network()
|
||||
to_chat(user, "<span class='notice'>You secure the generator to the floor.</span>")
|
||||
anchored = TRUE
|
||||
else if(anchored)
|
||||
disconnect_from_network()
|
||||
to_chat(user, "<span class='notice'>You unsecure the generator from the floor.</span>")
|
||||
anchored = FALSE
|
||||
|
||||
playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
|
||||
return
|
||||
else if(istype(O, /obj/item/screwdriver))
|
||||
panel_open = !panel_open
|
||||
O.play_tool_sound(src)
|
||||
if(panel_open)
|
||||
to_chat(user, "<span class='notice'>You open the access panel.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You close the access panel.</span>")
|
||||
return
|
||||
else if(default_deconstruction_crowbar(O))
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/emag_act(mob/user)
|
||||
. = ..()
|
||||
if(obj_flags & EMAGGED)
|
||||
return
|
||||
obj_flags |= EMAGGED
|
||||
emp_act(EMP_HEAVY)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/attack_ai(mob/user)
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/attack_paw(mob/user)
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/ui_interact(mob/user)
|
||||
. = ..()
|
||||
if (get_dist(src, user) > 1 )
|
||||
if(!isAI(user))
|
||||
user.unset_machine()
|
||||
user << browse(null, "window=port_gen")
|
||||
return
|
||||
|
||||
var/dat = text("<b>[name]</b><br>")
|
||||
if (active)
|
||||
dat += text("Generator: <A href='?src=[REF(src)];action=disable'>On</A><br>")
|
||||
else
|
||||
dat += text("Generator: <A href='?src=[REF(src)];action=enable'>Off</A><br>")
|
||||
dat += text("[capitalize(sheet_name)]: [sheets] - <A href='?src=[REF(src)];action=eject'>Eject</A><br>")
|
||||
var/stack_percent = round(sheet_left * 100, 1)
|
||||
dat += text("Current stack: [stack_percent]% <br>")
|
||||
dat += text("Power output: <A href='?src=[REF(src)];action=lower_power'>-</A> [power_gen * power_output] <A href='?src=[REF(src)];action=higher_power'>+</A><br>")
|
||||
dat += text("Power current: [(powernet == null ? "Unconnected" : "[DisplayPower(avail())]")]<br>")
|
||||
dat += text("Heat: [current_heat]<br>")
|
||||
dat += "<br><A href='?src=[REF(src)];action=close'>Close</A>"
|
||||
user << browse(dat, "window=port_gen")
|
||||
onclose(user, "port_gen")
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
|
||||
src.add_fingerprint(usr)
|
||||
if(href_list["action"])
|
||||
if(href_list["action"] == "enable")
|
||||
if(!active && HasFuel() && !crit_fail)
|
||||
active = 1
|
||||
src.updateUsrDialog()
|
||||
update_icon()
|
||||
if(href_list["action"] == "disable")
|
||||
if (active)
|
||||
active = 0
|
||||
src.updateUsrDialog()
|
||||
update_icon()
|
||||
if(href_list["action"] == "eject")
|
||||
if(!active)
|
||||
DropFuel()
|
||||
src.updateUsrDialog()
|
||||
if(href_list["action"] == "lower_power")
|
||||
if (power_output > 1)
|
||||
power_output--
|
||||
src.updateUsrDialog()
|
||||
if (href_list["action"] == "higher_power")
|
||||
if (power_output < 4 || (obj_flags & EMAGGED))
|
||||
power_output++
|
||||
src.updateUsrDialog()
|
||||
if (href_list["action"] == "close")
|
||||
usr << browse(null, "window=port_gen")
|
||||
usr.unset_machine()
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/super
|
||||
name = "\improper S.U.P.E.R.P.A.C.M.A.N.-type portable generator"
|
||||
icon_state = "portgen1_0"
|
||||
base_icon = "portgen1"
|
||||
circuit = /obj/item/circuitboard/machine/pacman/super
|
||||
sheet_path = /obj/item/stack/sheet/mineral/uranium
|
||||
power_gen = 15000
|
||||
time_per_sheet = 85
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/super/overheat()
|
||||
explosion(src.loc, 3, 3, 3, -1)
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/mrs
|
||||
name = "\improper M.R.S.P.A.C.M.A.N.-type portable generator"
|
||||
base_icon = "portgen2"
|
||||
icon_state = "portgen2_0"
|
||||
circuit = /obj/item/circuitboard/machine/pacman/mrs
|
||||
sheet_path = /obj/item/stack/sheet/mineral/diamond
|
||||
power_gen = 40000
|
||||
time_per_sheet = 80
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/mrs/overheat()
|
||||
explosion(src.loc, 4, 4, 4, -1)
|
||||
|
||||
//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 = "portable generator"
|
||||
desc = "A portable generator for emergency backup power."
|
||||
icon = 'icons/obj/power.dmi'
|
||||
icon_state = "portgen0_0"
|
||||
density = TRUE
|
||||
anchored = FALSE
|
||||
use_power = NO_POWER_USE
|
||||
|
||||
var/active = 0
|
||||
var/power_gen = 5000
|
||||
var/recent_fault = 0
|
||||
var/power_output = 1
|
||||
var/consumption = 0
|
||||
var/base_icon = "portgen0"
|
||||
var/datum/looping_sound/generator/soundloop
|
||||
|
||||
interaction_flags_atom = INTERACT_ATOM_ATTACK_HAND | INTERACT_ATOM_UI_INTERACT | INTERACT_ATOM_REQUIRES_ANCHORED
|
||||
|
||||
/obj/machinery/power/port_gen/Initialize()
|
||||
. = ..()
|
||||
soundloop = new(list(src), active)
|
||||
|
||||
/obj/machinery/power/port_gen/Destroy()
|
||||
QDEL_NULL(soundloop)
|
||||
return ..()
|
||||
|
||||
/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/update_icon()
|
||||
icon_state = "[base_icon]_[active]"
|
||||
|
||||
/obj/machinery/power/port_gen/process()
|
||||
if(active && HasFuel() && !crit_fail && anchored && powernet)
|
||||
add_avail(power_gen * power_output)
|
||||
UseFuel()
|
||||
src.updateDialog()
|
||||
soundloop.start()
|
||||
|
||||
else
|
||||
active = 0
|
||||
handleInactive()
|
||||
update_icon()
|
||||
soundloop.stop()
|
||||
|
||||
/obj/machinery/power/port_gen/examine(mob/user)
|
||||
. = ..()
|
||||
. += "It is[!active?"n't":""] running."
|
||||
|
||||
/obj/machinery/power/port_gen/pacman
|
||||
name = "\improper P.A.C.M.A.N.-type portable generator"
|
||||
circuit = /obj/item/circuitboard/machine/pacman
|
||||
var/sheets = 0
|
||||
var/max_sheets = 100
|
||||
var/sheet_name = ""
|
||||
var/sheet_path = /obj/item/stack/sheet/mineral/plasma
|
||||
var/sheet_left = 0 // How much is left of the sheet
|
||||
var/time_per_sheet = 260
|
||||
var/current_heat = 0
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/Initialize()
|
||||
. = ..()
|
||||
if(anchored)
|
||||
connect_to_network()
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/Initialize()
|
||||
. = ..()
|
||||
|
||||
var/obj/sheet = new sheet_path(null)
|
||||
sheet_name = sheet.name
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/Destroy()
|
||||
DropFuel()
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/RefreshParts()
|
||||
var/temp_rating = 0
|
||||
var/consumption_coeff = 0
|
||||
for(var/obj/item/stock_parts/SP in component_parts)
|
||||
if(istype(SP, /obj/item/stock_parts/matter_bin))
|
||||
max_sheets = SP.rating * SP.rating * 50
|
||||
else if(istype(SP, /obj/item/stock_parts/capacitor))
|
||||
temp_rating += SP.rating
|
||||
else
|
||||
consumption_coeff += SP.rating
|
||||
power_gen = round(initial(power_gen) * temp_rating * 2)
|
||||
consumption = consumption_coeff
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/examine(mob/user)
|
||||
. = ..()
|
||||
. += "<span class='notice'>The generator has [sheets] units of [sheet_name] fuel left, producing [power_gen] per cycle.</span>"
|
||||
if(crit_fail)
|
||||
. += "<span class='danger'>The generator seems to have broken down.</span>"
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/HasFuel()
|
||||
if(sheets >= 1 / (time_per_sheet / power_output) - sheet_left)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/DropFuel()
|
||||
if(sheets)
|
||||
new sheet_path(drop_location(), sheets)
|
||||
sheets = 0
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/UseFuel()
|
||||
var/needed_sheets = 1 / (time_per_sheet * consumption / power_output)
|
||||
var/temp = min(needed_sheets, sheet_left)
|
||||
needed_sheets -= temp
|
||||
sheet_left -= temp
|
||||
sheets -= round(needed_sheets)
|
||||
needed_sheets -= round(needed_sheets)
|
||||
if (sheet_left <= 0 && sheets > 0)
|
||||
sheet_left = 1 - needed_sheets
|
||||
sheets--
|
||||
|
||||
var/lower_limit = 56 + power_output * 10
|
||||
var/upper_limit = 76 + power_output * 10
|
||||
var/bias = 0
|
||||
if (power_output > 4)
|
||||
upper_limit = 400
|
||||
bias = power_output - consumption * (4 - consumption)
|
||||
if (current_heat < lower_limit)
|
||||
current_heat += 4 - consumption
|
||||
else
|
||||
current_heat += rand(-7 + bias, 7 + bias)
|
||||
if (current_heat < lower_limit)
|
||||
current_heat = lower_limit
|
||||
if (current_heat > upper_limit)
|
||||
current_heat = upper_limit
|
||||
|
||||
if (current_heat > 300)
|
||||
overheat()
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/handleInactive()
|
||||
|
||||
if (current_heat > 0)
|
||||
current_heat = max(current_heat - 2, 0)
|
||||
src.updateDialog()
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/proc/overheat()
|
||||
explosion(src.loc, 2, 5, 2, -1)
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/attackby(obj/item/O, mob/user, params)
|
||||
if(istype(O, sheet_path))
|
||||
var/obj/item/stack/addstack = O
|
||||
var/amount = min((max_sheets - sheets), addstack.amount)
|
||||
if(amount < 1)
|
||||
to_chat(user, "<span class='notice'>The [src.name] is full!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You add [amount] sheets to the [src.name].</span>")
|
||||
sheets += amount
|
||||
addstack.use(amount)
|
||||
updateUsrDialog()
|
||||
return
|
||||
else if(!active)
|
||||
|
||||
if(istype(O, /obj/item/wrench))
|
||||
|
||||
if(!anchored && !isinspace())
|
||||
connect_to_network()
|
||||
to_chat(user, "<span class='notice'>You secure the generator to the floor.</span>")
|
||||
anchored = TRUE
|
||||
else if(anchored)
|
||||
disconnect_from_network()
|
||||
to_chat(user, "<span class='notice'>You unsecure the generator from the floor.</span>")
|
||||
anchored = FALSE
|
||||
|
||||
playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
|
||||
return
|
||||
else if(istype(O, /obj/item/screwdriver))
|
||||
panel_open = !panel_open
|
||||
O.play_tool_sound(src)
|
||||
if(panel_open)
|
||||
to_chat(user, "<span class='notice'>You open the access panel.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You close the access panel.</span>")
|
||||
return
|
||||
else if(default_deconstruction_crowbar(O))
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/emag_act(mob/user)
|
||||
. = ..()
|
||||
if(obj_flags & EMAGGED)
|
||||
return
|
||||
obj_flags |= EMAGGED
|
||||
emp_act(EMP_HEAVY)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/attack_ai(mob/user)
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/attack_paw(mob/user)
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/ui_interact(mob/user)
|
||||
. = ..()
|
||||
if (get_dist(src, user) > 1 )
|
||||
if(!isAI(user))
|
||||
user.unset_machine()
|
||||
user << browse(null, "window=port_gen")
|
||||
return
|
||||
|
||||
var/dat = text("<b>[name]</b><br>")
|
||||
if (active)
|
||||
dat += text("Generator: <A href='?src=[REF(src)];action=disable'>On</A><br>")
|
||||
else
|
||||
dat += text("Generator: <A href='?src=[REF(src)];action=enable'>Off</A><br>")
|
||||
dat += text("[capitalize(sheet_name)]: [sheets] - <A href='?src=[REF(src)];action=eject'>Eject</A><br>")
|
||||
var/stack_percent = round(sheet_left * 100, 1)
|
||||
dat += text("Current stack: [stack_percent]% <br>")
|
||||
dat += text("Power output: <A href='?src=[REF(src)];action=lower_power'>-</A> [power_gen * power_output] <A href='?src=[REF(src)];action=higher_power'>+</A><br>")
|
||||
dat += text("Power current: [(powernet == null ? "Unconnected" : "[DisplayPower(avail())]")]<br>")
|
||||
dat += text("Heat: [current_heat]<br>")
|
||||
dat += "<br><A href='?src=[REF(src)];action=close'>Close</A>"
|
||||
user << browse(dat, "window=port_gen")
|
||||
onclose(user, "port_gen")
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
|
||||
src.add_fingerprint(usr)
|
||||
if(href_list["action"])
|
||||
if(href_list["action"] == "enable")
|
||||
if(!active && HasFuel() && !crit_fail)
|
||||
active = 1
|
||||
src.updateUsrDialog()
|
||||
update_icon()
|
||||
if(href_list["action"] == "disable")
|
||||
if (active)
|
||||
active = 0
|
||||
src.updateUsrDialog()
|
||||
update_icon()
|
||||
if(href_list["action"] == "eject")
|
||||
if(!active)
|
||||
DropFuel()
|
||||
src.updateUsrDialog()
|
||||
if(href_list["action"] == "lower_power")
|
||||
if (power_output > 1)
|
||||
power_output--
|
||||
src.updateUsrDialog()
|
||||
if (href_list["action"] == "higher_power")
|
||||
if (power_output < 4 || (obj_flags & EMAGGED))
|
||||
power_output++
|
||||
src.updateUsrDialog()
|
||||
if (href_list["action"] == "close")
|
||||
usr << browse(null, "window=port_gen")
|
||||
usr.unset_machine()
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/super
|
||||
name = "\improper S.U.P.E.R.P.A.C.M.A.N.-type portable generator"
|
||||
icon_state = "portgen1_0"
|
||||
base_icon = "portgen1"
|
||||
circuit = /obj/item/circuitboard/machine/pacman/super
|
||||
sheet_path = /obj/item/stack/sheet/mineral/uranium
|
||||
power_gen = 15000
|
||||
time_per_sheet = 85
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/super/overheat()
|
||||
explosion(src.loc, 3, 3, 3, -1)
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/mrs
|
||||
name = "\improper M.R.S.P.A.C.M.A.N.-type portable generator"
|
||||
base_icon = "portgen2"
|
||||
icon_state = "portgen2_0"
|
||||
circuit = /obj/item/circuitboard/machine/pacman/mrs
|
||||
sheet_path = /obj/item/stack/sheet/mineral/diamond
|
||||
power_gen = 40000
|
||||
time_per_sheet = 80
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/mrs/overheat()
|
||||
explosion(src.loc, 4, 4, 4, -1)
|
||||
|
||||
@@ -1,232 +1,232 @@
|
||||
// stored_power += (pulse_strength-RAD_COLLECTOR_EFFICIENCY)*RAD_COLLECTOR_COEFFICIENT
|
||||
#define RAD_COLLECTOR_EFFICIENCY 80 // radiation needs to be over this amount to get power
|
||||
#define RAD_COLLECTOR_COEFFICIENT 100
|
||||
#define RAD_COLLECTOR_STORED_OUT 0.04 // (this*100)% of stored power outputted per tick. Doesn't actualy change output total, lower numbers just means collectors output for longer in absence of a source
|
||||
#define RAD_COLLECTOR_MINING_CONVERSION_RATE 0.00001 //This is gonna need a lot of tweaking to get right. This is the number used to calculate the conversion of watts to research points per process()
|
||||
#define RAD_COLLECTOR_OUTPUT min(stored_power, (stored_power*RAD_COLLECTOR_STORED_OUT)+1000) //Produces at least 1000 watts if it has more than that stored
|
||||
|
||||
/obj/machinery/power/rad_collector
|
||||
name = "Radiation Collector Array"
|
||||
desc = "A device which uses Hawking Radiation and plasma to produce power."
|
||||
icon = 'icons/obj/singularity.dmi'
|
||||
icon_state = "ca"
|
||||
anchored = FALSE
|
||||
density = TRUE
|
||||
req_access = list(ACCESS_ENGINE_EQUIP)
|
||||
// use_power = NO_POWER_USE
|
||||
max_integrity = 350
|
||||
integrity_failure = 80
|
||||
circuit = /obj/item/circuitboard/machine/rad_collector
|
||||
var/obj/item/tank/internals/plasma/loaded_tank = null
|
||||
var/stored_power = 0
|
||||
var/last_push
|
||||
var/active = 0
|
||||
var/locked = FALSE
|
||||
var/drainratio = 1
|
||||
var/powerproduction_drain = 0.001
|
||||
|
||||
var/bitcoinproduction_drain = 0.15
|
||||
var/bitcoinmining = FALSE
|
||||
rad_insulation = RAD_EXTREME_INSULATION
|
||||
|
||||
/obj/machinery/power/rad_collector/anchored
|
||||
anchored = TRUE
|
||||
|
||||
/obj/machinery/power/rad_collector/Destroy()
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/rad_collector/process()
|
||||
if(!loaded_tank)
|
||||
return
|
||||
if(!bitcoinmining)
|
||||
if(!loaded_tank.air_contents.gases[/datum/gas/plasma])
|
||||
investigate_log("<font color='red'>out of fuel</font>.", INVESTIGATE_SINGULO)
|
||||
playsound(src, 'sound/machines/ding.ogg', 50, 1)
|
||||
eject()
|
||||
else
|
||||
var/gasdrained = min(powerproduction_drain*drainratio,loaded_tank.air_contents.gases[/datum/gas/plasma])
|
||||
loaded_tank.air_contents.gases[/datum/gas/plasma] -= gasdrained
|
||||
loaded_tank.air_contents.gases[/datum/gas/tritium] += gasdrained
|
||||
GAS_GARBAGE_COLLECT(loaded_tank.air_contents.gases)
|
||||
|
||||
var/power_produced = RAD_COLLECTOR_OUTPUT
|
||||
add_avail(power_produced)
|
||||
stored_power-=power_produced
|
||||
else if(is_station_level(z) && SSresearch.science_tech)
|
||||
if(!loaded_tank.air_contents.gases[/datum/gas/tritium] || !loaded_tank.air_contents.gases[/datum/gas/oxygen])
|
||||
playsound(src, 'sound/machines/ding.ogg', 50, 1)
|
||||
eject()
|
||||
else
|
||||
var/gasdrained = bitcoinproduction_drain*drainratio
|
||||
loaded_tank.air_contents.gases[/datum/gas/tritium] -= gasdrained
|
||||
loaded_tank.air_contents.gases[/datum/gas/oxygen] -= gasdrained
|
||||
loaded_tank.air_contents.gases[/datum/gas/carbon_dioxide] += gasdrained*2
|
||||
GAS_GARBAGE_COLLECT(loaded_tank.air_contents.gases)
|
||||
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, stored_power*RAD_COLLECTOR_MINING_CONVERSION_RATE)
|
||||
last_push = stored_power
|
||||
stored_power = 0
|
||||
|
||||
/obj/machinery/power/rad_collector/interact(mob/user)
|
||||
if(anchored)
|
||||
if(!src.locked)
|
||||
toggle_power()
|
||||
user.visible_message("[user.name] turns the [src.name] [active? "on":"off"].", \
|
||||
"<span class='notice'>You turn the [src.name] [active? "on":"off"].</span>")
|
||||
var/fuel
|
||||
if(loaded_tank)
|
||||
fuel = loaded_tank.air_contents.gases[/datum/gas/plasma]
|
||||
investigate_log("turned [active?"<font color='green'>on</font>":"<font color='red'>off</font>"] by [key_name(user)]. [loaded_tank?"Fuel: [round(fuel/0.29)]%":"<font color='red'>It is empty</font>"].", INVESTIGATE_SINGULO)
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='warning'>The controls are locked!</span>")
|
||||
return
|
||||
|
||||
/obj/machinery/power/rad_collector/can_be_unfasten_wrench(mob/user, silent)
|
||||
if(loaded_tank)
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='warning'>Remove the plasma tank first!</span>")
|
||||
return FAILED_UNFASTEN
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/rad_collector/default_unfasten_wrench(mob/user, obj/item/I, time = 20)
|
||||
. = ..()
|
||||
if(. == SUCCESSFUL_UNFASTEN)
|
||||
if(anchored)
|
||||
connect_to_network()
|
||||
else
|
||||
disconnect_from_network()
|
||||
|
||||
/obj/machinery/power/rad_collector/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/tank/internals/plasma))
|
||||
if(!anchored)
|
||||
to_chat(user, "<span class='warning'>[src] needs to be secured to the floor first!</span>")
|
||||
return TRUE
|
||||
if(loaded_tank)
|
||||
to_chat(user, "<span class='warning'>There's already a plasma tank loaded!</span>")
|
||||
return TRUE
|
||||
if(panel_open)
|
||||
to_chat(user, "<span class='warning'>Close the maintenance panel first!</span>")
|
||||
return TRUE
|
||||
if(!user.transferItemToLoc(W, src))
|
||||
return
|
||||
loaded_tank = W
|
||||
update_icon()
|
||||
else if(W.GetID())
|
||||
if(allowed(user))
|
||||
if(active)
|
||||
locked = !locked
|
||||
to_chat(user, "<span class='notice'>You [locked ? "lock" : "unlock"] the controls.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>The controls can only be locked when \the [src] is active!</span>")
|
||||
else
|
||||
to_chat(user, "<span class='danger'>Access denied.</span>")
|
||||
return TRUE
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/rad_collector/wrench_act(mob/living/user, obj/item/I)
|
||||
default_unfasten_wrench(user, I)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/rad_collector/screwdriver_act(mob/living/user, obj/item/I)
|
||||
if(..())
|
||||
return TRUE
|
||||
if(loaded_tank)
|
||||
to_chat(user, "<span class='warning'>Remove the plasma tank first!</span>")
|
||||
else
|
||||
default_deconstruction_screwdriver(user, icon_state, icon_state, I)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/rad_collector/crowbar_act(mob/living/user, obj/item/I)
|
||||
if(loaded_tank)
|
||||
if(locked)
|
||||
to_chat(user, "<span class='warning'>The controls are locked!</span>")
|
||||
return TRUE
|
||||
eject()
|
||||
return TRUE
|
||||
if(default_deconstruction_crowbar(I))
|
||||
return TRUE
|
||||
to_chat(user, "<span class='warning'>There isn't a tank loaded!</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/rad_collector/multitool_act(mob/living/user, obj/item/I)
|
||||
if(!is_station_level(z) && !SSresearch.science_tech)
|
||||
to_chat(user, "<span class='warning'>[src] isn't linked to a research system!</span>")
|
||||
return TRUE
|
||||
if(locked)
|
||||
to_chat(user, "<span class='warning'>[src] is locked!</span>")
|
||||
return TRUE
|
||||
if(active)
|
||||
to_chat(user, "<span class='warning'>[src] is currently active, producing [bitcoinmining ? "research points":"power"].</span>")
|
||||
return TRUE
|
||||
bitcoinmining = !bitcoinmining
|
||||
to_chat(user, "<span class='warning'>You [bitcoinmining ? "enable":"disable"] the research point production feature of [src].</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/rad_collector/analyzer_act(mob/living/user, obj/item/I)
|
||||
if(loaded_tank)
|
||||
loaded_tank.analyzer_act(user, I)
|
||||
|
||||
/obj/machinery/power/rad_collector/examine(mob/user)
|
||||
. = ..()
|
||||
if(active)
|
||||
if(!bitcoinmining)
|
||||
. += "<span class='notice'>[src]'s display states that it has stored <b>[DisplayPower(stored_power)]</b>, and is processing <b>[DisplayPower((RAD_COLLECTOR_OUTPUT)*((60 SECONDS)/SSmachines.wait))]</b> per minute. <br>The <b>plasma</b> within it's tank is being irradiated into <b>tritium</b>.</span>"
|
||||
else
|
||||
. += "<span class='notice'>[src]'s display states that it's producing a total of <b>[(last_push*RAD_COLLECTOR_MINING_CONVERSION_RATE)*((60 SECONDS)/SSmachines.wait)]</b> research points per minute. <br>The <b>tritium</b> and <b>oxygen</b> within it's tank is being combusted into <b>carbon dioxide</b>.</span>"
|
||||
else
|
||||
if(!bitcoinmining)
|
||||
. += "<span class='notice'><b>[src]'s display displays the words:</b> \"Power production mode. Please insert <b>Plasma</b>. Use a multitool to change production modes.\"</span>"
|
||||
else
|
||||
. += "<span class='notice'><b>[src]'s display displays the words:</b> \"Research point production mode. Please insert <b>Tritium</b> and <b>Oxygen</b>. Use a multitool to change production modes.\"</span>"
|
||||
|
||||
/obj/machinery/power/rad_collector/obj_break(damage_flag)
|
||||
if(!(stat & BROKEN) && !(flags_1 & NODECONSTRUCT_1))
|
||||
eject()
|
||||
stat |= BROKEN
|
||||
|
||||
/obj/machinery/power/rad_collector/proc/eject()
|
||||
locked = FALSE
|
||||
var/obj/item/tank/internals/plasma/Z = src.loaded_tank
|
||||
if (!Z)
|
||||
return
|
||||
Z.forceMove(drop_location())
|
||||
Z.layer = initial(Z.layer)
|
||||
Z.plane = initial(Z.plane)
|
||||
src.loaded_tank = null
|
||||
if(active)
|
||||
toggle_power()
|
||||
else
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/power/rad_collector/rad_act(pulse_strength)
|
||||
. = ..()
|
||||
if(loaded_tank && active && pulse_strength > RAD_COLLECTOR_EFFICIENCY)
|
||||
stored_power += (pulse_strength-RAD_COLLECTOR_EFFICIENCY)*RAD_COLLECTOR_COEFFICIENT
|
||||
|
||||
/obj/machinery/power/rad_collector/update_icon()
|
||||
cut_overlays()
|
||||
if(loaded_tank)
|
||||
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_icon()
|
||||
return
|
||||
|
||||
#undef RAD_COLLECTOR_EFFICIENCY
|
||||
#undef RAD_COLLECTOR_COEFFICIENT
|
||||
#undef RAD_COLLECTOR_STORED_OUT
|
||||
#undef RAD_COLLECTOR_MINING_CONVERSION_RATE
|
||||
#undef RAD_COLLECTOR_OUTPUT
|
||||
// stored_power += (pulse_strength-RAD_COLLECTOR_EFFICIENCY)*RAD_COLLECTOR_COEFFICIENT
|
||||
#define RAD_COLLECTOR_EFFICIENCY 80 // radiation needs to be over this amount to get power
|
||||
#define RAD_COLLECTOR_COEFFICIENT 100
|
||||
#define RAD_COLLECTOR_STORED_OUT 0.04 // (this*100)% of stored power outputted per tick. Doesn't actualy change output total, lower numbers just means collectors output for longer in absence of a source
|
||||
#define RAD_COLLECTOR_MINING_CONVERSION_RATE 0.00001 //This is gonna need a lot of tweaking to get right. This is the number used to calculate the conversion of watts to research points per process()
|
||||
#define RAD_COLLECTOR_OUTPUT min(stored_power, (stored_power*RAD_COLLECTOR_STORED_OUT)+1000) //Produces at least 1000 watts if it has more than that stored
|
||||
|
||||
/obj/machinery/power/rad_collector
|
||||
name = "Radiation Collector Array"
|
||||
desc = "A device which uses Hawking Radiation and plasma to produce power."
|
||||
icon = 'icons/obj/singularity.dmi'
|
||||
icon_state = "ca"
|
||||
anchored = FALSE
|
||||
density = TRUE
|
||||
req_access = list(ACCESS_ENGINE_EQUIP)
|
||||
// use_power = NO_POWER_USE
|
||||
max_integrity = 350
|
||||
integrity_failure = 80
|
||||
circuit = /obj/item/circuitboard/machine/rad_collector
|
||||
var/obj/item/tank/internals/plasma/loaded_tank = null
|
||||
var/stored_power = 0
|
||||
var/last_push
|
||||
var/active = 0
|
||||
var/locked = FALSE
|
||||
var/drainratio = 1
|
||||
var/powerproduction_drain = 0.001
|
||||
|
||||
var/bitcoinproduction_drain = 0.15
|
||||
var/bitcoinmining = FALSE
|
||||
rad_insulation = RAD_EXTREME_INSULATION
|
||||
|
||||
/obj/machinery/power/rad_collector/anchored
|
||||
anchored = TRUE
|
||||
|
||||
/obj/machinery/power/rad_collector/Destroy()
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/rad_collector/process()
|
||||
if(!loaded_tank)
|
||||
return
|
||||
if(!bitcoinmining)
|
||||
if(!loaded_tank.air_contents.gases[/datum/gas/plasma])
|
||||
investigate_log("<font color='red'>out of fuel</font>.", INVESTIGATE_SINGULO)
|
||||
playsound(src, 'sound/machines/ding.ogg', 50, 1)
|
||||
eject()
|
||||
else
|
||||
var/gasdrained = min(powerproduction_drain*drainratio,loaded_tank.air_contents.gases[/datum/gas/plasma])
|
||||
loaded_tank.air_contents.gases[/datum/gas/plasma] -= 2.7 * gasdrained
|
||||
loaded_tank.air_contents.gases[/datum/gas/tritium] += 2.7 * gasdrained
|
||||
GAS_GARBAGE_COLLECT(loaded_tank.air_contents.gases)
|
||||
|
||||
var/power_produced = RAD_COLLECTOR_OUTPUT
|
||||
add_avail(power_produced)
|
||||
stored_power-=power_produced
|
||||
else if(is_station_level(z) && SSresearch.science_tech)
|
||||
if(!loaded_tank.air_contents.gases[/datum/gas/tritium] || !loaded_tank.air_contents.gases[/datum/gas/oxygen])
|
||||
playsound(src, 'sound/machines/ding.ogg', 50, 1)
|
||||
eject()
|
||||
else
|
||||
var/gasdrained = bitcoinproduction_drain*drainratio
|
||||
loaded_tank.air_contents.gases[/datum/gas/tritium] -= gasdrained
|
||||
loaded_tank.air_contents.gases[/datum/gas/oxygen] -= gasdrained
|
||||
loaded_tank.air_contents.gases[/datum/gas/carbon_dioxide] += gasdrained*2
|
||||
GAS_GARBAGE_COLLECT(loaded_tank.air_contents.gases)
|
||||
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, stored_power*RAD_COLLECTOR_MINING_CONVERSION_RATE)
|
||||
last_push = stored_power
|
||||
stored_power = 0
|
||||
|
||||
/obj/machinery/power/rad_collector/interact(mob/user)
|
||||
if(anchored)
|
||||
if(!src.locked)
|
||||
toggle_power()
|
||||
user.visible_message("[user.name] turns the [src.name] [active? "on":"off"].", \
|
||||
"<span class='notice'>You turn the [src.name] [active? "on":"off"].</span>")
|
||||
var/fuel
|
||||
if(loaded_tank)
|
||||
fuel = loaded_tank.air_contents.gases[/datum/gas/plasma]
|
||||
investigate_log("turned [active?"<font color='green'>on</font>":"<font color='red'>off</font>"] by [key_name(user)]. [loaded_tank?"Fuel: [round(fuel/0.29)]%":"<font color='red'>It is empty</font>"].", INVESTIGATE_SINGULO)
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='warning'>The controls are locked!</span>")
|
||||
return
|
||||
|
||||
/obj/machinery/power/rad_collector/can_be_unfasten_wrench(mob/user, silent)
|
||||
if(loaded_tank)
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='warning'>Remove the plasma tank first!</span>")
|
||||
return FAILED_UNFASTEN
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/rad_collector/default_unfasten_wrench(mob/user, obj/item/I, time = 20)
|
||||
. = ..()
|
||||
if(. == SUCCESSFUL_UNFASTEN)
|
||||
if(anchored)
|
||||
connect_to_network()
|
||||
else
|
||||
disconnect_from_network()
|
||||
|
||||
/obj/machinery/power/rad_collector/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/tank/internals/plasma))
|
||||
if(!anchored)
|
||||
to_chat(user, "<span class='warning'>[src] needs to be secured to the floor first!</span>")
|
||||
return TRUE
|
||||
if(loaded_tank)
|
||||
to_chat(user, "<span class='warning'>There's already a plasma tank loaded!</span>")
|
||||
return TRUE
|
||||
if(panel_open)
|
||||
to_chat(user, "<span class='warning'>Close the maintenance panel first!</span>")
|
||||
return TRUE
|
||||
if(!user.transferItemToLoc(W, src))
|
||||
return
|
||||
loaded_tank = W
|
||||
update_icon()
|
||||
else if(W.GetID())
|
||||
if(allowed(user))
|
||||
if(active)
|
||||
locked = !locked
|
||||
to_chat(user, "<span class='notice'>You [locked ? "lock" : "unlock"] the controls.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>The controls can only be locked when \the [src] is active!</span>")
|
||||
else
|
||||
to_chat(user, "<span class='danger'>Access denied.</span>")
|
||||
return TRUE
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/rad_collector/wrench_act(mob/living/user, obj/item/I)
|
||||
default_unfasten_wrench(user, I)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/rad_collector/screwdriver_act(mob/living/user, obj/item/I)
|
||||
if(..())
|
||||
return TRUE
|
||||
if(loaded_tank)
|
||||
to_chat(user, "<span class='warning'>Remove the plasma tank first!</span>")
|
||||
else
|
||||
default_deconstruction_screwdriver(user, icon_state, icon_state, I)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/rad_collector/crowbar_act(mob/living/user, obj/item/I)
|
||||
if(loaded_tank)
|
||||
if(locked)
|
||||
to_chat(user, "<span class='warning'>The controls are locked!</span>")
|
||||
return TRUE
|
||||
eject()
|
||||
return TRUE
|
||||
if(default_deconstruction_crowbar(I))
|
||||
return TRUE
|
||||
to_chat(user, "<span class='warning'>There isn't a tank loaded!</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/rad_collector/multitool_act(mob/living/user, obj/item/I)
|
||||
if(!is_station_level(z) && !SSresearch.science_tech)
|
||||
to_chat(user, "<span class='warning'>[src] isn't linked to a research system!</span>")
|
||||
return TRUE
|
||||
if(locked)
|
||||
to_chat(user, "<span class='warning'>[src] is locked!</span>")
|
||||
return TRUE
|
||||
if(active)
|
||||
to_chat(user, "<span class='warning'>[src] is currently active, producing [bitcoinmining ? "research points":"power"].</span>")
|
||||
return TRUE
|
||||
bitcoinmining = !bitcoinmining
|
||||
to_chat(user, "<span class='warning'>You [bitcoinmining ? "enable":"disable"] the research point production feature of [src].</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/rad_collector/analyzer_act(mob/living/user, obj/item/I)
|
||||
if(loaded_tank)
|
||||
loaded_tank.analyzer_act(user, I)
|
||||
|
||||
/obj/machinery/power/rad_collector/examine(mob/user)
|
||||
. = ..()
|
||||
if(active)
|
||||
if(!bitcoinmining)
|
||||
. += "<span class='notice'>[src]'s display states that it has stored <b>[DisplayPower(stored_power)]</b>, and is processing <b>[DisplayPower((RAD_COLLECTOR_OUTPUT)*((60 SECONDS)/SSmachines.wait))]</b> per minute. <br>The <b>plasma</b> within it's tank is being irradiated into <b>tritium</b>.</span>"
|
||||
else
|
||||
. += "<span class='notice'>[src]'s display states that it's producing a total of <b>[(last_push*RAD_COLLECTOR_MINING_CONVERSION_RATE)*((60 SECONDS)/SSmachines.wait)]</b> research points per minute. <br>The <b>tritium</b> and <b>oxygen</b> within it's tank is being combusted into <b>carbon dioxide</b>.</span>"
|
||||
else
|
||||
if(!bitcoinmining)
|
||||
. += "<span class='notice'><b>[src]'s display displays the words:</b> \"Power production mode. Please insert <b>Plasma</b>. Use a multitool to change production modes.\"</span>"
|
||||
else
|
||||
. += "<span class='notice'><b>[src]'s display displays the words:</b> \"Research point production mode. Please insert <b>Tritium</b> and <b>Oxygen</b>. Use a multitool to change production modes.\"</span>"
|
||||
|
||||
/obj/machinery/power/rad_collector/obj_break(damage_flag)
|
||||
if(!(stat & BROKEN) && !(flags_1 & NODECONSTRUCT_1))
|
||||
eject()
|
||||
stat |= BROKEN
|
||||
|
||||
/obj/machinery/power/rad_collector/proc/eject()
|
||||
locked = FALSE
|
||||
var/obj/item/tank/internals/plasma/Z = src.loaded_tank
|
||||
if (!Z)
|
||||
return
|
||||
Z.forceMove(drop_location())
|
||||
Z.layer = initial(Z.layer)
|
||||
Z.plane = initial(Z.plane)
|
||||
src.loaded_tank = null
|
||||
if(active)
|
||||
toggle_power()
|
||||
else
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/power/rad_collector/rad_act(pulse_strength)
|
||||
. = ..()
|
||||
if(loaded_tank && active && pulse_strength > RAD_COLLECTOR_EFFICIENCY)
|
||||
stored_power += (pulse_strength-RAD_COLLECTOR_EFFICIENCY)*RAD_COLLECTOR_COEFFICIENT
|
||||
|
||||
/obj/machinery/power/rad_collector/update_icon()
|
||||
cut_overlays()
|
||||
if(loaded_tank)
|
||||
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_icon()
|
||||
return
|
||||
|
||||
#undef RAD_COLLECTOR_EFFICIENCY
|
||||
#undef RAD_COLLECTOR_COEFFICIENT
|
||||
#undef RAD_COLLECTOR_STORED_OUT
|
||||
#undef RAD_COLLECTOR_MINING_CONVERSION_RATE
|
||||
#undef RAD_COLLECTOR_OUTPUT
|
||||
|
||||
@@ -1,134 +1,134 @@
|
||||
|
||||
|
||||
/obj/machinery/field/containment
|
||||
name = "containment field"
|
||||
desc = "An energy field."
|
||||
icon = 'icons/obj/singularity.dmi'
|
||||
icon_state = "Contain_F"
|
||||
density = FALSE
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
use_power = NO_POWER_USE
|
||||
interaction_flags_atom = NONE
|
||||
interaction_flags_machine = NONE
|
||||
light_range = 4
|
||||
layer = ABOVE_OBJ_LAYER
|
||||
var/obj/machinery/field/generator/FG1 = null
|
||||
var/obj/machinery/field/generator/FG2 = null
|
||||
|
||||
/obj/machinery/field/containment/Destroy()
|
||||
FG1.fields -= src
|
||||
FG2.fields -= src
|
||||
return ..()
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/machinery/field/containment/attack_hand(mob/user)
|
||||
if(get_dist(src, user) > 1)
|
||||
return FALSE
|
||||
else
|
||||
shock(user)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/field/containment/attackby(obj/item/W, mob/user, params)
|
||||
shock(user)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/field/containment/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
|
||||
switch(damage_type)
|
||||
if(BURN)
|
||||
playsound(loc, 'sound/effects/empulse.ogg', 75, 1)
|
||||
if(BRUTE)
|
||||
playsound(loc, 'sound/effects/empulse.ogg', 75, 1)
|
||||
|
||||
/obj/machinery/field/containment/blob_act(obj/structure/blob/B)
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/field/containment/ex_act(severity, target)
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/field/containment/attack_animal(mob/living/simple_animal/M)
|
||||
if(!FG1 || !FG2)
|
||||
qdel(src)
|
||||
return
|
||||
if(ismegafauna(M))
|
||||
M.visible_message("<span class='warning'>[M] glows fiercely as the containment field flickers out!</span>")
|
||||
FG1.calc_power(INFINITY) //rip that 'containment' field
|
||||
M.adjustHealth(-M.obj_damage)
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/machinery/field/containment/Crossed(mob/mover)
|
||||
if(isliving(mover))
|
||||
shock(mover)
|
||||
|
||||
if(ismachinery(mover) || isstructure(mover) || ismecha(mover))
|
||||
bump_field(mover)
|
||||
|
||||
/obj/machinery/field/containment/proc/set_master(master1,master2)
|
||||
if(!master1 || !master2)
|
||||
return FALSE
|
||||
FG1 = master1
|
||||
FG2 = master2
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/field/containment/shock(mob/living/user)
|
||||
if(!FG1 || !FG2)
|
||||
qdel(src)
|
||||
return FALSE
|
||||
..()
|
||||
|
||||
/obj/machinery/field/containment/Move()
|
||||
qdel(src)
|
||||
return FALSE
|
||||
|
||||
|
||||
// Abstract Field Class
|
||||
// Used for overriding certain procs
|
||||
|
||||
/obj/machinery/field
|
||||
var/hasShocked = FALSE //Used to add a delay between shocks. In some cases this used to crash servers by spawning hundreds of sparks every second.
|
||||
|
||||
/obj/machinery/field/Bumped(atom/movable/mover)
|
||||
if(hasShocked)
|
||||
return
|
||||
if(isliving(mover))
|
||||
shock(mover)
|
||||
return
|
||||
if(ismachinery(mover) || isstructure(mover) || ismecha(mover))
|
||||
bump_field(mover)
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/field/CanPass(atom/movable/mover, turf/target)
|
||||
if(hasShocked || isliving(mover) || ismachinery(mover) || isstructure(mover) || ismecha(mover))
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/machinery/field/proc/shock(mob/living/user)
|
||||
var/shock_damage = min(rand(30,40),rand(30,40))
|
||||
|
||||
if(iscarbon(user))
|
||||
user.DefaultCombatKnockdown(300)
|
||||
user.electrocute_act(shock_damage, src, 1)
|
||||
|
||||
else if(issilicon(user))
|
||||
if(prob(20))
|
||||
user.Stun(40)
|
||||
user.take_overall_damage(0, shock_damage)
|
||||
user.visible_message("<span class='danger'>[user.name] was shocked by the [src.name]!</span>", \
|
||||
"<span class='userdanger'>Energy pulse detected, system damaged!</span>", \
|
||||
"<span class='italics'>You hear an electrical crack.</span>")
|
||||
|
||||
user.updatehealth()
|
||||
bump_field(user)
|
||||
|
||||
/obj/machinery/field/proc/clear_shock()
|
||||
hasShocked = FALSE
|
||||
|
||||
/obj/machinery/field/proc/bump_field(atom/movable/AM as mob|obj)
|
||||
if(hasShocked)
|
||||
return FALSE
|
||||
hasShocked = TRUE
|
||||
do_sparks(5, TRUE, AM.loc)
|
||||
var/atom/target = get_edge_target_turf(AM, get_dir(src, get_step_away(AM, src)))
|
||||
AM.throw_at(target, 200, 4)
|
||||
addtimer(CALLBACK(src, .proc/clear_shock), 5)
|
||||
|
||||
|
||||
/obj/machinery/field/containment
|
||||
name = "containment field"
|
||||
desc = "An energy field."
|
||||
icon = 'icons/obj/singularity.dmi'
|
||||
icon_state = "Contain_F"
|
||||
density = FALSE
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
use_power = NO_POWER_USE
|
||||
interaction_flags_atom = NONE
|
||||
interaction_flags_machine = NONE
|
||||
light_range = 4
|
||||
layer = ABOVE_OBJ_LAYER
|
||||
var/obj/machinery/field/generator/FG1 = null
|
||||
var/obj/machinery/field/generator/FG2 = null
|
||||
|
||||
/obj/machinery/field/containment/Destroy()
|
||||
FG1.fields -= src
|
||||
FG2.fields -= src
|
||||
return ..()
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/machinery/field/containment/attack_hand(mob/user)
|
||||
if(get_dist(src, user) > 1)
|
||||
return FALSE
|
||||
else
|
||||
shock(user)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/field/containment/attackby(obj/item/W, mob/user, params)
|
||||
shock(user)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/field/containment/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
|
||||
switch(damage_type)
|
||||
if(BURN)
|
||||
playsound(loc, 'sound/effects/empulse.ogg', 75, 1)
|
||||
if(BRUTE)
|
||||
playsound(loc, 'sound/effects/empulse.ogg', 75, 1)
|
||||
|
||||
/obj/machinery/field/containment/blob_act(obj/structure/blob/B)
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/field/containment/ex_act(severity, target)
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/field/containment/attack_animal(mob/living/simple_animal/M)
|
||||
if(!FG1 || !FG2)
|
||||
qdel(src)
|
||||
return
|
||||
if(ismegafauna(M))
|
||||
M.visible_message("<span class='warning'>[M] glows fiercely as the containment field flickers out!</span>")
|
||||
FG1.calc_power(INFINITY) //rip that 'containment' field
|
||||
M.adjustHealth(-M.obj_damage)
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/machinery/field/containment/Crossed(mob/mover)
|
||||
if(isliving(mover))
|
||||
shock(mover)
|
||||
|
||||
if(ismachinery(mover) || isstructure(mover) || ismecha(mover))
|
||||
bump_field(mover)
|
||||
|
||||
/obj/machinery/field/containment/proc/set_master(master1,master2)
|
||||
if(!master1 || !master2)
|
||||
return FALSE
|
||||
FG1 = master1
|
||||
FG2 = master2
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/field/containment/shock(mob/living/user)
|
||||
if(!FG1 || !FG2)
|
||||
qdel(src)
|
||||
return FALSE
|
||||
..()
|
||||
|
||||
/obj/machinery/field/containment/Move()
|
||||
qdel(src)
|
||||
return FALSE
|
||||
|
||||
|
||||
// Abstract Field Class
|
||||
// Used for overriding certain procs
|
||||
|
||||
/obj/machinery/field
|
||||
var/hasShocked = FALSE //Used to add a delay between shocks. In some cases this used to crash servers by spawning hundreds of sparks every second.
|
||||
|
||||
/obj/machinery/field/Bumped(atom/movable/mover)
|
||||
if(hasShocked)
|
||||
return
|
||||
if(isliving(mover))
|
||||
shock(mover)
|
||||
return
|
||||
if(ismachinery(mover) || isstructure(mover) || ismecha(mover))
|
||||
bump_field(mover)
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/field/CanPass(atom/movable/mover, turf/target)
|
||||
if(hasShocked || isliving(mover) || ismachinery(mover) || isstructure(mover) || ismecha(mover))
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/machinery/field/proc/shock(mob/living/user)
|
||||
var/shock_damage = min(rand(30,40),rand(30,40))
|
||||
|
||||
if(iscarbon(user))
|
||||
user.DefaultCombatKnockdown(300)
|
||||
user.electrocute_act(shock_damage, src, 1)
|
||||
|
||||
else if(issilicon(user))
|
||||
if(prob(20))
|
||||
user.Stun(40)
|
||||
user.take_overall_damage(0, shock_damage)
|
||||
user.visible_message("<span class='danger'>[user.name] was shocked by the [src.name]!</span>", \
|
||||
"<span class='userdanger'>Energy pulse detected, system damaged!</span>", \
|
||||
"<span class='italics'>You hear an electrical crack.</span>")
|
||||
|
||||
user.updatehealth()
|
||||
bump_field(user)
|
||||
|
||||
/obj/machinery/field/proc/clear_shock()
|
||||
hasShocked = FALSE
|
||||
|
||||
/obj/machinery/field/proc/bump_field(atom/movable/AM as mob|obj)
|
||||
if(hasShocked)
|
||||
return FALSE
|
||||
hasShocked = TRUE
|
||||
do_sparks(5, TRUE, AM.loc)
|
||||
var/atom/target = get_edge_target_turf(AM, get_dir(src, get_step_away(AM, src)))
|
||||
AM.throw_at(target, 200, 4)
|
||||
addtimer(CALLBACK(src, .proc/clear_shock), 5)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,353 +1,353 @@
|
||||
|
||||
|
||||
|
||||
/*
|
||||
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 250
|
||||
|
||||
#define FG_OFFLINE 0
|
||||
#define FG_CHARGING 1
|
||||
#define FG_ONLINE 2
|
||||
|
||||
//field generator construction defines
|
||||
#define FG_UNSECURED 0
|
||||
#define FG_SECURED 1
|
||||
#define FG_WELDED 2
|
||||
|
||||
/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 = NO_POWER_USE
|
||||
max_integrity = 500
|
||||
//100% immune to lasers and energy projectiles since it absorbs their energy.
|
||||
armor = list("melee" = 25, "bullet" = 10, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 70)
|
||||
var/const/num_power_levels = 6 // Total number of power level icon has
|
||||
var/power_level = 0
|
||||
var/active = FG_OFFLINE
|
||||
var/power = 20 // Current amount of power
|
||||
var/state = FG_UNSECURED
|
||||
var/warming_up = 0
|
||||
var/list/obj/machinery/field/containment/fields
|
||||
var/list/obj/machinery/field/generator/connected_gens
|
||||
var/clean_up = 0
|
||||
|
||||
/obj/machinery/field/generator/update_icon()
|
||||
cut_overlays()
|
||||
if(warming_up)
|
||||
add_overlay("+a[warming_up]")
|
||||
if(fields.len)
|
||||
add_overlay("+on")
|
||||
if(power_level)
|
||||
add_overlay("+p[power_level]")
|
||||
|
||||
|
||||
/obj/machinery/field/generator/Initialize()
|
||||
. = ..()
|
||||
fields = list()
|
||||
connected_gens = list()
|
||||
|
||||
/obj/machinery/field/generator/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES)
|
||||
|
||||
/obj/machinery/field/generator/process()
|
||||
if(active == FG_ONLINE)
|
||||
calc_power()
|
||||
|
||||
/obj/machinery/field/generator/interact(mob/user)
|
||||
if(state == FG_WELDED)
|
||||
if(get_dist(src, user) <= 1)//Need to actually touch the thing to turn it on
|
||||
if(active >= FG_CHARGING)
|
||||
to_chat(user, "<span class='warning'>You are unable to turn off [src] once it is online!</span>")
|
||||
return 1
|
||||
else
|
||||
user.visible_message("[user] turns on [src].", \
|
||||
"<span class='notice'>You turn on [src].</span>", \
|
||||
"<span class='italics'>You hear heavy droning.</span>")
|
||||
turn_on()
|
||||
investigate_log("<font color='green'>activated</font> by [key_name(user)].", INVESTIGATE_SINGULO)
|
||||
|
||||
add_fingerprint(user)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[src] needs to be firmly secured to the floor first!</span>")
|
||||
|
||||
/obj/machinery/field/generator/can_be_unfasten_wrench(mob/user, silent)
|
||||
if(active)
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='warning'>Turn \the [src] off first!</span>")
|
||||
return FAILED_UNFASTEN
|
||||
|
||||
else if(state == FG_WELDED)
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='warning'>[src] is welded to the floor!</span>")
|
||||
return FAILED_UNFASTEN
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/field/generator/default_unfasten_wrench(mob/user, obj/item/I, time = 20)
|
||||
. = ..()
|
||||
if(. == SUCCESSFUL_UNFASTEN)
|
||||
if(anchored)
|
||||
state = FG_SECURED
|
||||
else
|
||||
state = FG_UNSECURED
|
||||
|
||||
/obj/machinery/field/generator/wrench_act(mob/living/user, obj/item/I)
|
||||
default_unfasten_wrench(user, I)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/field/generator/welder_act(mob/living/user, obj/item/I)
|
||||
if(active)
|
||||
to_chat(user, "<span class='warning'>[src] needs to be off!</span>")
|
||||
return TRUE
|
||||
|
||||
switch(state)
|
||||
if(FG_UNSECURED)
|
||||
to_chat(user, "<span class='warning'>[src] needs to be wrenched to the floor!</span>")
|
||||
|
||||
if(FG_SECURED)
|
||||
if(!I.tool_start_check(user, amount=0))
|
||||
return TRUE
|
||||
user.visible_message("[user] starts to weld [src] to the floor.", \
|
||||
"<span class='notice'>You start to weld \the [src] to the floor...</span>", \
|
||||
"<span class='italics'>You hear welding.</span>")
|
||||
if(I.use_tool(src, user, 20, volume=50) && state == FG_SECURED)
|
||||
state = FG_WELDED
|
||||
to_chat(user, "<span class='notice'>You weld the field generator to the floor.</span>")
|
||||
|
||||
if(FG_WELDED)
|
||||
if(!I.tool_start_check(user, amount=0))
|
||||
return TRUE
|
||||
user.visible_message("[user] starts to cut [src] free from the floor.", \
|
||||
"<span class='notice'>You start to cut \the [src] free from the floor...</span>", \
|
||||
"<span class='italics'>You hear welding.</span>")
|
||||
if(I.use_tool(src, user, 20, volume=50) && state == FG_WELDED)
|
||||
state = FG_SECURED
|
||||
to_chat(user, "<span class='notice'>You cut \the [src] free from the floor.</span>")
|
||||
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/machinery/field/generator/attack_animal(mob/living/simple_animal/M)
|
||||
if(M.environment_smash & ENVIRONMENT_SMASH_RWALLS && active == FG_OFFLINE && state != FG_UNSECURED)
|
||||
state = FG_UNSECURED
|
||||
anchored = FALSE
|
||||
M.visible_message("<span class='warning'>[M] rips [src] free from its moorings!</span>")
|
||||
else
|
||||
..()
|
||||
if(!anchored)
|
||||
step(src, get_dir(M, src))
|
||||
|
||||
/obj/machinery/field/generator/blob_act(obj/structure/blob/B)
|
||||
if(active)
|
||||
return 0
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/machinery/field/generator/bullet_act(obj/item/projectile/Proj)
|
||||
if(Proj.flag != "bullet")
|
||||
power = min(power + Proj.damage, field_generator_max_power)
|
||||
check_power_level()
|
||||
..()
|
||||
|
||||
|
||||
/obj/machinery/field/generator/Destroy()
|
||||
cleanup()
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/machinery/field/generator/proc/check_power_level()
|
||||
var/new_level = round(num_power_levels * power / field_generator_max_power)
|
||||
if(new_level != power_level)
|
||||
power_level = new_level
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/field/generator/proc/turn_off()
|
||||
active = FG_OFFLINE
|
||||
spawn(1)
|
||||
cleanup()
|
||||
while (warming_up>0 && !active)
|
||||
sleep(50)
|
||||
warming_up--
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/field/generator/proc/turn_on()
|
||||
active = FG_CHARGING
|
||||
spawn(1)
|
||||
while (warming_up<3 && active)
|
||||
sleep(50)
|
||||
warming_up++
|
||||
update_icon()
|
||||
if(warming_up >= 3)
|
||||
start_fields()
|
||||
|
||||
|
||||
/obj/machinery/field/generator/proc/calc_power(set_power_draw)
|
||||
var/power_draw = 2 + fields.len
|
||||
if(set_power_draw)
|
||||
power_draw = set_power_draw
|
||||
|
||||
if(draw_power(round(power_draw/2,1)))
|
||||
check_power_level()
|
||||
return 1
|
||||
else
|
||||
visible_message("<span class='danger'>The [name] shuts down!</span>", "<span class='italics'>You hear something shutting down.</span>")
|
||||
turn_off()
|
||||
investigate_log("ran out of power and <font color='red'>deactivated</font>", INVESTIGATE_SINGULO)
|
||||
power = 0
|
||||
check_power_level()
|
||||
return 0
|
||||
|
||||
//This could likely be better, it tends to start loopin if you have a complex generator loop setup. Still works well enough to run the engine fields will likely recode the field gens and fields sometime -Mport
|
||||
/obj/machinery/field/generator/proc/draw_power(draw = 0, failsafe = FALSE, obj/machinery/field/generator/G = null, obj/machinery/field/generator/last = null)
|
||||
if((G && (G == src)) || (failsafe >= 8))//Loopin, set fail
|
||||
return 0
|
||||
else
|
||||
failsafe++
|
||||
|
||||
if(power >= draw)//We have enough power
|
||||
power -= draw
|
||||
return 1
|
||||
|
||||
else//Need more power
|
||||
draw -= power
|
||||
power = 0
|
||||
for(var/CG in connected_gens)
|
||||
var/obj/machinery/field/generator/FG = CG
|
||||
if(FG == last)//We just asked you
|
||||
continue
|
||||
if(G)//Another gen is askin for power and we dont have it
|
||||
if(FG.draw_power(draw,failsafe,G,src))//Can you take the load
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
else//We are askin another for power
|
||||
if(FG.draw_power(draw,failsafe,src,src))
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
|
||||
/obj/machinery/field/generator/proc/start_fields()
|
||||
if(state != FG_WELDED || !anchored)
|
||||
turn_off()
|
||||
return
|
||||
spawn(1)
|
||||
setup_field(1)
|
||||
spawn(2)
|
||||
setup_field(2)
|
||||
spawn(3)
|
||||
setup_field(4)
|
||||
spawn(4)
|
||||
setup_field(8)
|
||||
spawn(5)
|
||||
active = FG_ONLINE
|
||||
|
||||
|
||||
/obj/machinery/field/generator/proc/setup_field(NSEW)
|
||||
var/turf/T = loc
|
||||
if(!istype(T))
|
||||
return 0
|
||||
|
||||
var/obj/machinery/field/generator/G = null
|
||||
var/steps = 0
|
||||
if(!NSEW)//Make sure its ran right
|
||||
return 0
|
||||
for(var/dist in 0 to 7) // 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
|
||||
|
||||
G = locate(/obj/machinery/field/generator) in T
|
||||
if(G)
|
||||
steps -= 1
|
||||
if(!G.active)
|
||||
return 0
|
||||
break
|
||||
|
||||
for(var/TC in T.contents)
|
||||
var/atom/A = TC
|
||||
if(ismob(A))
|
||||
continue
|
||||
if(A.density)
|
||||
return 0
|
||||
|
||||
steps++
|
||||
|
||||
if(!G)
|
||||
return 0
|
||||
|
||||
T = loc
|
||||
for(var/dist in 0 to steps) // creates each field tile
|
||||
var/field_dir = get_dir(T,get_step(G.loc, NSEW))
|
||||
T = get_step(T, NSEW)
|
||||
if(!locate(/obj/machinery/field/containment) in T)
|
||||
var/obj/machinery/field/containment/CF = new(T)
|
||||
CF.set_master(src,G)
|
||||
CF.setDir(field_dir)
|
||||
fields += CF
|
||||
G.fields += CF
|
||||
for(var/mob/living/L in T)
|
||||
CF.Crossed(L)
|
||||
|
||||
connected_gens |= G
|
||||
G.connected_gens |= src
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/machinery/field/generator/proc/cleanup()
|
||||
clean_up = 1
|
||||
for (var/F in fields)
|
||||
qdel(F)
|
||||
|
||||
for(var/CG in connected_gens)
|
||||
var/obj/machinery/field/generator/FG = CG
|
||||
FG.connected_gens -= src
|
||||
if(!FG.clean_up)//Makes the other gens clean up as well
|
||||
FG.cleanup()
|
||||
connected_gens -= FG
|
||||
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 GLOB.singularities)
|
||||
if(O.last_warning && temp)
|
||||
if((world.time - O.last_warning) > 50) //to stop message-spam
|
||||
temp = 0
|
||||
var/turf/T = get_turf(src)
|
||||
message_admins("A singulo exists and a containment field has failed at [ADMIN_VERBOSEJMP(T)].")
|
||||
investigate_log("has <font color='red'>failed</font> whilst a singulo exists at [AREACOORD(T)].", INVESTIGATE_SINGULO)
|
||||
O.last_warning = world.time
|
||||
|
||||
/obj/machinery/field/generator/shock(mob/living/user)
|
||||
if(fields.len)
|
||||
..()
|
||||
|
||||
/obj/machinery/field/generator/bump_field(atom/movable/AM as mob|obj)
|
||||
if(fields.len)
|
||||
..()
|
||||
|
||||
#undef FG_UNSECURED
|
||||
#undef FG_SECURED
|
||||
#undef FG_WELDED
|
||||
|
||||
#undef FG_OFFLINE
|
||||
#undef FG_CHARGING
|
||||
#undef FG_ONLINE
|
||||
|
||||
|
||||
|
||||
/*
|
||||
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 250
|
||||
|
||||
#define FG_OFFLINE 0
|
||||
#define FG_CHARGING 1
|
||||
#define FG_ONLINE 2
|
||||
|
||||
//field generator construction defines
|
||||
#define FG_UNSECURED 0
|
||||
#define FG_SECURED 1
|
||||
#define FG_WELDED 2
|
||||
|
||||
/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 = NO_POWER_USE
|
||||
max_integrity = 500
|
||||
//100% immune to lasers and energy projectiles since it absorbs their energy.
|
||||
armor = list("melee" = 25, "bullet" = 10, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 70)
|
||||
var/const/num_power_levels = 6 // Total number of power level icon has
|
||||
var/power_level = 0
|
||||
var/active = FG_OFFLINE
|
||||
var/power = 20 // Current amount of power
|
||||
var/state = FG_UNSECURED
|
||||
var/warming_up = 0
|
||||
var/list/obj/machinery/field/containment/fields
|
||||
var/list/obj/machinery/field/generator/connected_gens
|
||||
var/clean_up = 0
|
||||
|
||||
/obj/machinery/field/generator/update_icon()
|
||||
cut_overlays()
|
||||
if(warming_up)
|
||||
add_overlay("+a[warming_up]")
|
||||
if(fields.len)
|
||||
add_overlay("+on")
|
||||
if(power_level)
|
||||
add_overlay("+p[power_level]")
|
||||
|
||||
|
||||
/obj/machinery/field/generator/Initialize()
|
||||
. = ..()
|
||||
fields = list()
|
||||
connected_gens = list()
|
||||
|
||||
/obj/machinery/field/generator/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES)
|
||||
|
||||
/obj/machinery/field/generator/process()
|
||||
if(active == FG_ONLINE)
|
||||
calc_power()
|
||||
|
||||
/obj/machinery/field/generator/interact(mob/user)
|
||||
if(state == FG_WELDED)
|
||||
if(get_dist(src, user) <= 1)//Need to actually touch the thing to turn it on
|
||||
if(active >= FG_CHARGING)
|
||||
to_chat(user, "<span class='warning'>You are unable to turn off [src] once it is online!</span>")
|
||||
return 1
|
||||
else
|
||||
user.visible_message("[user] turns on [src].", \
|
||||
"<span class='notice'>You turn on [src].</span>", \
|
||||
"<span class='italics'>You hear heavy droning.</span>")
|
||||
turn_on()
|
||||
investigate_log("<font color='green'>activated</font> by [key_name(user)].", INVESTIGATE_SINGULO)
|
||||
|
||||
add_fingerprint(user)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[src] needs to be firmly secured to the floor first!</span>")
|
||||
|
||||
/obj/machinery/field/generator/can_be_unfasten_wrench(mob/user, silent)
|
||||
if(active)
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='warning'>Turn \the [src] off first!</span>")
|
||||
return FAILED_UNFASTEN
|
||||
|
||||
else if(state == FG_WELDED)
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='warning'>[src] is welded to the floor!</span>")
|
||||
return FAILED_UNFASTEN
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/field/generator/default_unfasten_wrench(mob/user, obj/item/I, time = 20)
|
||||
. = ..()
|
||||
if(. == SUCCESSFUL_UNFASTEN)
|
||||
if(anchored)
|
||||
state = FG_SECURED
|
||||
else
|
||||
state = FG_UNSECURED
|
||||
|
||||
/obj/machinery/field/generator/wrench_act(mob/living/user, obj/item/I)
|
||||
default_unfasten_wrench(user, I)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/field/generator/welder_act(mob/living/user, obj/item/I)
|
||||
if(active)
|
||||
to_chat(user, "<span class='warning'>[src] needs to be off!</span>")
|
||||
return TRUE
|
||||
|
||||
switch(state)
|
||||
if(FG_UNSECURED)
|
||||
to_chat(user, "<span class='warning'>[src] needs to be wrenched to the floor!</span>")
|
||||
|
||||
if(FG_SECURED)
|
||||
if(!I.tool_start_check(user, amount=0))
|
||||
return TRUE
|
||||
user.visible_message("[user] starts to weld [src] to the floor.", \
|
||||
"<span class='notice'>You start to weld \the [src] to the floor...</span>", \
|
||||
"<span class='italics'>You hear welding.</span>")
|
||||
if(I.use_tool(src, user, 20, volume=50) && state == FG_SECURED)
|
||||
state = FG_WELDED
|
||||
to_chat(user, "<span class='notice'>You weld the field generator to the floor.</span>")
|
||||
|
||||
if(FG_WELDED)
|
||||
if(!I.tool_start_check(user, amount=0))
|
||||
return TRUE
|
||||
user.visible_message("[user] starts to cut [src] free from the floor.", \
|
||||
"<span class='notice'>You start to cut \the [src] free from the floor...</span>", \
|
||||
"<span class='italics'>You hear welding.</span>")
|
||||
if(I.use_tool(src, user, 20, volume=50) && state == FG_WELDED)
|
||||
state = FG_SECURED
|
||||
to_chat(user, "<span class='notice'>You cut \the [src] free from the floor.</span>")
|
||||
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/machinery/field/generator/attack_animal(mob/living/simple_animal/M)
|
||||
if(M.environment_smash & ENVIRONMENT_SMASH_RWALLS && active == FG_OFFLINE && state != FG_UNSECURED)
|
||||
state = FG_UNSECURED
|
||||
anchored = FALSE
|
||||
M.visible_message("<span class='warning'>[M] rips [src] free from its moorings!</span>")
|
||||
else
|
||||
..()
|
||||
if(!anchored)
|
||||
step(src, get_dir(M, src))
|
||||
|
||||
/obj/machinery/field/generator/blob_act(obj/structure/blob/B)
|
||||
if(active)
|
||||
return 0
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/machinery/field/generator/bullet_act(obj/item/projectile/Proj)
|
||||
if(Proj.flag != "bullet")
|
||||
power = min(power + Proj.damage, field_generator_max_power)
|
||||
check_power_level()
|
||||
..()
|
||||
|
||||
|
||||
/obj/machinery/field/generator/Destroy()
|
||||
cleanup()
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/machinery/field/generator/proc/check_power_level()
|
||||
var/new_level = round(num_power_levels * power / field_generator_max_power)
|
||||
if(new_level != power_level)
|
||||
power_level = new_level
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/field/generator/proc/turn_off()
|
||||
active = FG_OFFLINE
|
||||
spawn(1)
|
||||
cleanup()
|
||||
while (warming_up>0 && !active)
|
||||
sleep(50)
|
||||
warming_up--
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/field/generator/proc/turn_on()
|
||||
active = FG_CHARGING
|
||||
spawn(1)
|
||||
while (warming_up<3 && active)
|
||||
sleep(50)
|
||||
warming_up++
|
||||
update_icon()
|
||||
if(warming_up >= 3)
|
||||
start_fields()
|
||||
|
||||
|
||||
/obj/machinery/field/generator/proc/calc_power(set_power_draw)
|
||||
var/power_draw = 2 + fields.len
|
||||
if(set_power_draw)
|
||||
power_draw = set_power_draw
|
||||
|
||||
if(draw_power(round(power_draw/2,1)))
|
||||
check_power_level()
|
||||
return 1
|
||||
else
|
||||
visible_message("<span class='danger'>The [name] shuts down!</span>", "<span class='italics'>You hear something shutting down.</span>")
|
||||
turn_off()
|
||||
investigate_log("ran out of power and <font color='red'>deactivated</font>", INVESTIGATE_SINGULO)
|
||||
power = 0
|
||||
check_power_level()
|
||||
return 0
|
||||
|
||||
//This could likely be better, it tends to start loopin if you have a complex generator loop setup. Still works well enough to run the engine fields will likely recode the field gens and fields sometime -Mport
|
||||
/obj/machinery/field/generator/proc/draw_power(draw = 0, failsafe = FALSE, obj/machinery/field/generator/G = null, obj/machinery/field/generator/last = null)
|
||||
if((G && (G == src)) || (failsafe >= 8))//Loopin, set fail
|
||||
return 0
|
||||
else
|
||||
failsafe++
|
||||
|
||||
if(power >= draw)//We have enough power
|
||||
power -= draw
|
||||
return 1
|
||||
|
||||
else//Need more power
|
||||
draw -= power
|
||||
power = 0
|
||||
for(var/CG in connected_gens)
|
||||
var/obj/machinery/field/generator/FG = CG
|
||||
if(FG == last)//We just asked you
|
||||
continue
|
||||
if(G)//Another gen is askin for power and we dont have it
|
||||
if(FG.draw_power(draw,failsafe,G,src))//Can you take the load
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
else//We are askin another for power
|
||||
if(FG.draw_power(draw,failsafe,src,src))
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
|
||||
/obj/machinery/field/generator/proc/start_fields()
|
||||
if(state != FG_WELDED || !anchored)
|
||||
turn_off()
|
||||
return
|
||||
spawn(1)
|
||||
setup_field(1)
|
||||
spawn(2)
|
||||
setup_field(2)
|
||||
spawn(3)
|
||||
setup_field(4)
|
||||
spawn(4)
|
||||
setup_field(8)
|
||||
spawn(5)
|
||||
active = FG_ONLINE
|
||||
|
||||
|
||||
/obj/machinery/field/generator/proc/setup_field(NSEW)
|
||||
var/turf/T = loc
|
||||
if(!istype(T))
|
||||
return 0
|
||||
|
||||
var/obj/machinery/field/generator/G = null
|
||||
var/steps = 0
|
||||
if(!NSEW)//Make sure its ran right
|
||||
return 0
|
||||
for(var/dist in 0 to 7) // 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
|
||||
|
||||
G = locate(/obj/machinery/field/generator) in T
|
||||
if(G)
|
||||
steps -= 1
|
||||
if(!G.active)
|
||||
return 0
|
||||
break
|
||||
|
||||
for(var/TC in T.contents)
|
||||
var/atom/A = TC
|
||||
if(ismob(A))
|
||||
continue
|
||||
if(A.density)
|
||||
return 0
|
||||
|
||||
steps++
|
||||
|
||||
if(!G)
|
||||
return 0
|
||||
|
||||
T = loc
|
||||
for(var/dist in 0 to steps) // creates each field tile
|
||||
var/field_dir = get_dir(T,get_step(G.loc, NSEW))
|
||||
T = get_step(T, NSEW)
|
||||
if(!locate(/obj/machinery/field/containment) in T)
|
||||
var/obj/machinery/field/containment/CF = new(T)
|
||||
CF.set_master(src,G)
|
||||
CF.setDir(field_dir)
|
||||
fields += CF
|
||||
G.fields += CF
|
||||
for(var/mob/living/L in T)
|
||||
CF.Crossed(L)
|
||||
|
||||
connected_gens |= G
|
||||
G.connected_gens |= src
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/machinery/field/generator/proc/cleanup()
|
||||
clean_up = 1
|
||||
for (var/F in fields)
|
||||
qdel(F)
|
||||
|
||||
for(var/CG in connected_gens)
|
||||
var/obj/machinery/field/generator/FG = CG
|
||||
FG.connected_gens -= src
|
||||
if(!FG.clean_up)//Makes the other gens clean up as well
|
||||
FG.cleanup()
|
||||
connected_gens -= FG
|
||||
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 GLOB.singularities)
|
||||
if(O.last_warning && temp)
|
||||
if((world.time - O.last_warning) > 50) //to stop message-spam
|
||||
temp = 0
|
||||
var/turf/T = get_turf(src)
|
||||
message_admins("A singulo exists and a containment field has failed at [ADMIN_VERBOSEJMP(T)].")
|
||||
investigate_log("has <font color='red'>failed</font> whilst a singulo exists at [AREACOORD(T)].", INVESTIGATE_SINGULO)
|
||||
O.last_warning = world.time
|
||||
|
||||
/obj/machinery/field/generator/shock(mob/living/user)
|
||||
if(fields.len)
|
||||
..()
|
||||
|
||||
/obj/machinery/field/generator/bump_field(atom/movable/AM as mob|obj)
|
||||
if(fields.len)
|
||||
..()
|
||||
|
||||
#undef FG_UNSECURED
|
||||
#undef FG_SECURED
|
||||
#undef FG_WELDED
|
||||
|
||||
#undef FG_OFFLINE
|
||||
#undef FG_CHARGING
|
||||
#undef FG_ONLINE
|
||||
|
||||
@@ -1,35 +1,35 @@
|
||||
/////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 = NO_POWER_USE
|
||||
resistance_flags = FIRE_PROOF
|
||||
|
||||
// You can buckle someone to the singularity generator, then start the engine. Fun!
|
||||
can_buckle = TRUE
|
||||
buckle_lying = FALSE
|
||||
buckle_requires_restraints = TRUE
|
||||
|
||||
var/energy = 0
|
||||
var/creation_type = /obj/singularity
|
||||
|
||||
/obj/machinery/the_singularitygen/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/wrench))
|
||||
default_unfasten_wrench(user, W, 0)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/the_singularitygen/process()
|
||||
if(energy > 0)
|
||||
if(energy >= 200)
|
||||
var/turf/T = get_turf(src)
|
||||
SSblackbox.record_feedback("tally", "engine_started", 1, type)
|
||||
var/obj/singularity/S = new creation_type(T, 50)
|
||||
transfer_fingerprints_to(S)
|
||||
qdel(src)
|
||||
else
|
||||
energy -= 1
|
||||
/////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 = NO_POWER_USE
|
||||
resistance_flags = FIRE_PROOF
|
||||
|
||||
// You can buckle someone to the singularity generator, then start the engine. Fun!
|
||||
can_buckle = TRUE
|
||||
buckle_lying = FALSE
|
||||
buckle_requires_restraints = TRUE
|
||||
|
||||
var/energy = 0
|
||||
var/creation_type = /obj/singularity
|
||||
|
||||
/obj/machinery/the_singularitygen/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/wrench))
|
||||
default_unfasten_wrench(user, W, 0)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/the_singularitygen/process()
|
||||
if(energy > 0)
|
||||
if(energy >= 200)
|
||||
var/turf/T = get_turf(src)
|
||||
SSblackbox.record_feedback("tally", "engine_started", 1, type)
|
||||
var/obj/singularity/S = new creation_type(T, 50)
|
||||
transfer_fingerprints_to(S)
|
||||
qdel(src)
|
||||
else
|
||||
energy -= 1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/area/engine/engineering/poweralert(state, source)
|
||||
if (state != poweralm)
|
||||
investigate_log("has a power alarm!", INVESTIGATE_SINGULO)
|
||||
/area/engine/engineering/poweralert(state, source)
|
||||
if (state != poweralm)
|
||||
investigate_log("has a power alarm!", INVESTIGATE_SINGULO)
|
||||
..()
|
||||
@@ -1,68 +1,68 @@
|
||||
/obj/effect/accelerated_particle
|
||||
name = "Accelerated Particles"
|
||||
desc = "Small things moving very fast."
|
||||
icon = 'icons/obj/machines/particle_accelerator.dmi'
|
||||
icon_state = "particle"
|
||||
anchored = TRUE
|
||||
density = FALSE
|
||||
var/movement_range = 10
|
||||
var/energy = 10
|
||||
var/speed = 1
|
||||
|
||||
/obj/effect/accelerated_particle/weak
|
||||
movement_range = 8
|
||||
energy = 5
|
||||
|
||||
/obj/effect/accelerated_particle/strong
|
||||
movement_range = 15
|
||||
energy = 15
|
||||
|
||||
/obj/effect/accelerated_particle/powerful
|
||||
movement_range = 20
|
||||
energy = 50
|
||||
|
||||
|
||||
/obj/effect/accelerated_particle/New(loc)
|
||||
..()
|
||||
|
||||
addtimer(CALLBACK(src, .proc/move), 1)
|
||||
|
||||
|
||||
/obj/effect/accelerated_particle/Bump(atom/A)
|
||||
if(A)
|
||||
if(isliving(A))
|
||||
toxmob(A)
|
||||
else if(istype(A, /obj/machinery/the_singularitygen))
|
||||
var/obj/machinery/the_singularitygen/S = A
|
||||
S.energy += energy
|
||||
else if(istype(A, /obj/singularity))
|
||||
var/obj/singularity/S = A
|
||||
S.energy += energy
|
||||
else if(istype(A, /obj/structure/blob))
|
||||
var/obj/structure/blob/B = A
|
||||
B.take_damage(energy*0.6)
|
||||
movement_range = 0
|
||||
|
||||
/obj/effect/accelerated_particle/Crossed(atom/A)
|
||||
if(isliving(A))
|
||||
toxmob(A)
|
||||
|
||||
|
||||
/obj/effect/accelerated_particle/ex_act(severity, target)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/accelerated_particle/singularity_pull()
|
||||
return
|
||||
|
||||
/obj/effect/accelerated_particle/proc/toxmob(mob/living/M)
|
||||
M.rad_act(energy*6)
|
||||
|
||||
/obj/effect/accelerated_particle/proc/move()
|
||||
if(!step(src,dir))
|
||||
forceMove(get_step(src,dir))
|
||||
movement_range--
|
||||
if(movement_range == 0)
|
||||
qdel(src)
|
||||
else
|
||||
sleep(speed)
|
||||
move()
|
||||
/obj/effect/accelerated_particle
|
||||
name = "Accelerated Particles"
|
||||
desc = "Small things moving very fast."
|
||||
icon = 'icons/obj/machines/particle_accelerator.dmi'
|
||||
icon_state = "particle"
|
||||
anchored = TRUE
|
||||
density = FALSE
|
||||
var/movement_range = 10
|
||||
var/energy = 10
|
||||
var/speed = 1
|
||||
|
||||
/obj/effect/accelerated_particle/weak
|
||||
movement_range = 8
|
||||
energy = 5
|
||||
|
||||
/obj/effect/accelerated_particle/strong
|
||||
movement_range = 15
|
||||
energy = 15
|
||||
|
||||
/obj/effect/accelerated_particle/powerful
|
||||
movement_range = 20
|
||||
energy = 50
|
||||
|
||||
|
||||
/obj/effect/accelerated_particle/New(loc)
|
||||
..()
|
||||
|
||||
addtimer(CALLBACK(src, .proc/move), 1)
|
||||
|
||||
|
||||
/obj/effect/accelerated_particle/Bump(atom/A)
|
||||
if(A)
|
||||
if(isliving(A))
|
||||
toxmob(A)
|
||||
else if(istype(A, /obj/machinery/the_singularitygen))
|
||||
var/obj/machinery/the_singularitygen/S = A
|
||||
S.energy += energy
|
||||
else if(istype(A, /obj/singularity))
|
||||
var/obj/singularity/S = A
|
||||
S.energy += energy
|
||||
else if(istype(A, /obj/structure/blob))
|
||||
var/obj/structure/blob/B = A
|
||||
B.take_damage(energy*0.6)
|
||||
movement_range = 0
|
||||
|
||||
/obj/effect/accelerated_particle/Crossed(atom/A)
|
||||
if(isliving(A))
|
||||
toxmob(A)
|
||||
|
||||
|
||||
/obj/effect/accelerated_particle/ex_act(severity, target)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/accelerated_particle/singularity_pull()
|
||||
return
|
||||
|
||||
/obj/effect/accelerated_particle/proc/toxmob(mob/living/M)
|
||||
M.rad_act(energy*6)
|
||||
|
||||
/obj/effect/accelerated_particle/proc/move()
|
||||
if(!step(src,dir))
|
||||
forceMove(get_step(src,dir))
|
||||
movement_range--
|
||||
if(movement_range == 0)
|
||||
qdel(src)
|
||||
else
|
||||
sleep(speed)
|
||||
move()
|
||||
|
||||
@@ -1,172 +1,172 @@
|
||||
/*Composed of 7 parts :
|
||||
|
||||
3 Particle Emitters
|
||||
1 Power Box
|
||||
1 Fuel Chamber
|
||||
1 End Cap
|
||||
1 Control computer
|
||||
|
||||
Setup map
|
||||
|
||||
|EC|
|
||||
CC|FC|
|
||||
|PB|
|
||||
PE|PE|PE
|
||||
|
||||
*/
|
||||
#define PA_CONSTRUCTION_UNSECURED 0
|
||||
#define PA_CONSTRUCTION_UNWIRED 1
|
||||
#define PA_CONSTRUCTION_PANEL_OPEN 2
|
||||
#define PA_CONSTRUCTION_COMPLETE 3
|
||||
|
||||
/obj/structure/particle_accelerator
|
||||
name = "Particle Accelerator"
|
||||
desc = "Part of a Particle Accelerator."
|
||||
icon = 'icons/obj/machines/particle_accelerator.dmi'
|
||||
icon_state = "none"
|
||||
anchored = FALSE
|
||||
density = TRUE
|
||||
max_integrity = 500
|
||||
armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 80)
|
||||
|
||||
var/obj/machinery/particle_accelerator/control_box/master = null
|
||||
var/construction_state = PA_CONSTRUCTION_UNSECURED
|
||||
var/reference = null
|
||||
var/powered = 0
|
||||
var/strength = null
|
||||
|
||||
/obj/structure/particle_accelerator/examine(mob/user)
|
||||
. = ..()
|
||||
switch(construction_state)
|
||||
if(PA_CONSTRUCTION_UNSECURED)
|
||||
. += "Looks like it's not attached to the flooring."
|
||||
if(PA_CONSTRUCTION_UNWIRED)
|
||||
. += "It is missing some cables."
|
||||
if(PA_CONSTRUCTION_PANEL_OPEN)
|
||||
. += "The panel is open."
|
||||
|
||||
/obj/structure/particle_accelerator/Destroy()
|
||||
construction_state = PA_CONSTRUCTION_UNSECURED
|
||||
if(master)
|
||||
master.connected_parts -= src
|
||||
master.assembled = 0
|
||||
master = null
|
||||
return ..()
|
||||
|
||||
/obj/structure/particle_accelerator/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/simple_rotation,ROTATION_ALTCLICK | ROTATION_CLOCKWISE | ROTATION_COUNTERCLOCKWISE | ROTATION_VERBS )
|
||||
|
||||
|
||||
/obj/structure/particle_accelerator/attackby(obj/item/W, mob/user, params)
|
||||
var/did_something = FALSE
|
||||
|
||||
switch(construction_state)
|
||||
if(PA_CONSTRUCTION_UNSECURED)
|
||||
if(istype(W, /obj/item/wrench) && !isinspace())
|
||||
W.play_tool_sound(src, 75)
|
||||
anchored = TRUE
|
||||
user.visible_message("[user.name] secures the [name] to the floor.", \
|
||||
"You secure the external bolts.")
|
||||
construction_state = PA_CONSTRUCTION_UNWIRED
|
||||
did_something = TRUE
|
||||
if(PA_CONSTRUCTION_UNWIRED)
|
||||
if(istype(W, /obj/item/wrench))
|
||||
W.play_tool_sound(src, 75)
|
||||
anchored = FALSE
|
||||
user.visible_message("[user.name] detaches the [name] from the floor.", \
|
||||
"You remove the external bolts.")
|
||||
construction_state = PA_CONSTRUCTION_UNSECURED
|
||||
did_something = TRUE
|
||||
else if(istype(W, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/CC = W
|
||||
if(CC.use(1))
|
||||
user.visible_message("[user.name] adds wires to the [name].", \
|
||||
"You add some wires.")
|
||||
construction_state = PA_CONSTRUCTION_PANEL_OPEN
|
||||
did_something = TRUE
|
||||
if(PA_CONSTRUCTION_PANEL_OPEN)
|
||||
if(istype(W, /obj/item/wirecutters))//TODO:Shock user if its on?
|
||||
user.visible_message("[user.name] removes some wires from the [name].", \
|
||||
"You remove some wires.")
|
||||
construction_state = PA_CONSTRUCTION_UNWIRED
|
||||
did_something = TRUE
|
||||
else if(istype(W, /obj/item/screwdriver))
|
||||
user.visible_message("[user.name] closes the [name]'s access panel.", \
|
||||
"You close the access panel.")
|
||||
construction_state = PA_CONSTRUCTION_COMPLETE
|
||||
did_something = TRUE
|
||||
if(PA_CONSTRUCTION_COMPLETE)
|
||||
if(istype(W, /obj/item/screwdriver))
|
||||
user.visible_message("[user.name] opens the [name]'s access panel.", \
|
||||
"You open the access panel.")
|
||||
construction_state = PA_CONSTRUCTION_PANEL_OPEN
|
||||
did_something = TRUE
|
||||
|
||||
if(did_something)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
update_state()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/structure/particle_accelerator/deconstruct(disassembled = TRUE)
|
||||
if(!(flags_1 & NODECONSTRUCT_1))
|
||||
new /obj/item/stack/sheet/metal (loc, 5)
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/particle_accelerator/Move()
|
||||
. = ..()
|
||||
if(master && master.active)
|
||||
master.toggle_power()
|
||||
investigate_log("was moved whilst active; it <font color='red'>powered down</font>.", INVESTIGATE_SINGULO)
|
||||
|
||||
|
||||
/obj/structure/particle_accelerator/update_icon()
|
||||
switch(construction_state)
|
||||
if(PA_CONSTRUCTION_UNSECURED,PA_CONSTRUCTION_UNWIRED)
|
||||
icon_state="[reference]"
|
||||
if(PA_CONSTRUCTION_PANEL_OPEN)
|
||||
icon_state="[reference]w"
|
||||
if(PA_CONSTRUCTION_COMPLETE)
|
||||
if(powered)
|
||||
icon_state="[reference]p[strength]"
|
||||
else
|
||||
icon_state="[reference]c"
|
||||
|
||||
/obj/structure/particle_accelerator/proc/update_state()
|
||||
if(master)
|
||||
master.update_state()
|
||||
|
||||
/obj/structure/particle_accelerator/proc/connect_master(obj/O)
|
||||
if(O.dir == dir)
|
||||
master = O
|
||||
return 1
|
||||
return 0
|
||||
|
||||
///////////
|
||||
// PARTS //
|
||||
///////////
|
||||
|
||||
|
||||
/obj/structure/particle_accelerator/end_cap
|
||||
name = "Alpha Particle Generation Array"
|
||||
desc = "This is where Alpha particles are generated from \[REDACTED\]."
|
||||
icon_state = "end_cap"
|
||||
reference = "end_cap"
|
||||
|
||||
/obj/structure/particle_accelerator/power_box
|
||||
name = "Particle Focusing EM Lens"
|
||||
desc = "This uses electromagnetic waves to focus the Alpha particles."
|
||||
icon = 'icons/obj/machines/particle_accelerator.dmi'
|
||||
icon_state = "power_box"
|
||||
reference = "power_box"
|
||||
|
||||
/obj/structure/particle_accelerator/fuel_chamber
|
||||
name = "EM Acceleration Chamber"
|
||||
desc = "This is where the Alpha particles are accelerated to <b><i>radical speeds</i></b>."
|
||||
icon = 'icons/obj/machines/particle_accelerator.dmi'
|
||||
icon_state = "fuel_chamber"
|
||||
reference = "fuel_chamber"
|
||||
/*Composed of 7 parts :
|
||||
|
||||
3 Particle Emitters
|
||||
1 Power Box
|
||||
1 Fuel Chamber
|
||||
1 End Cap
|
||||
1 Control computer
|
||||
|
||||
Setup map
|
||||
|
||||
|EC|
|
||||
CC|FC|
|
||||
|PB|
|
||||
PE|PE|PE
|
||||
|
||||
*/
|
||||
#define PA_CONSTRUCTION_UNSECURED 0
|
||||
#define PA_CONSTRUCTION_UNWIRED 1
|
||||
#define PA_CONSTRUCTION_PANEL_OPEN 2
|
||||
#define PA_CONSTRUCTION_COMPLETE 3
|
||||
|
||||
/obj/structure/particle_accelerator
|
||||
name = "Particle Accelerator"
|
||||
desc = "Part of a Particle Accelerator."
|
||||
icon = 'icons/obj/machines/particle_accelerator.dmi'
|
||||
icon_state = "none"
|
||||
anchored = FALSE
|
||||
density = TRUE
|
||||
max_integrity = 500
|
||||
armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 80)
|
||||
|
||||
var/obj/machinery/particle_accelerator/control_box/master = null
|
||||
var/construction_state = PA_CONSTRUCTION_UNSECURED
|
||||
var/reference = null
|
||||
var/powered = 0
|
||||
var/strength = null
|
||||
|
||||
/obj/structure/particle_accelerator/examine(mob/user)
|
||||
. = ..()
|
||||
switch(construction_state)
|
||||
if(PA_CONSTRUCTION_UNSECURED)
|
||||
. += "Looks like it's not attached to the flooring."
|
||||
if(PA_CONSTRUCTION_UNWIRED)
|
||||
. += "It is missing some cables."
|
||||
if(PA_CONSTRUCTION_PANEL_OPEN)
|
||||
. += "The panel is open."
|
||||
|
||||
/obj/structure/particle_accelerator/Destroy()
|
||||
construction_state = PA_CONSTRUCTION_UNSECURED
|
||||
if(master)
|
||||
master.connected_parts -= src
|
||||
master.assembled = 0
|
||||
master = null
|
||||
return ..()
|
||||
|
||||
/obj/structure/particle_accelerator/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/simple_rotation,ROTATION_ALTCLICK | ROTATION_CLOCKWISE | ROTATION_COUNTERCLOCKWISE | ROTATION_VERBS )
|
||||
|
||||
|
||||
/obj/structure/particle_accelerator/attackby(obj/item/W, mob/user, params)
|
||||
var/did_something = FALSE
|
||||
|
||||
switch(construction_state)
|
||||
if(PA_CONSTRUCTION_UNSECURED)
|
||||
if(istype(W, /obj/item/wrench) && !isinspace())
|
||||
W.play_tool_sound(src, 75)
|
||||
anchored = TRUE
|
||||
user.visible_message("[user.name] secures the [name] to the floor.", \
|
||||
"You secure the external bolts.")
|
||||
construction_state = PA_CONSTRUCTION_UNWIRED
|
||||
did_something = TRUE
|
||||
if(PA_CONSTRUCTION_UNWIRED)
|
||||
if(istype(W, /obj/item/wrench))
|
||||
W.play_tool_sound(src, 75)
|
||||
anchored = FALSE
|
||||
user.visible_message("[user.name] detaches the [name] from the floor.", \
|
||||
"You remove the external bolts.")
|
||||
construction_state = PA_CONSTRUCTION_UNSECURED
|
||||
did_something = TRUE
|
||||
else if(istype(W, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/CC = W
|
||||
if(CC.use(1))
|
||||
user.visible_message("[user.name] adds wires to the [name].", \
|
||||
"You add some wires.")
|
||||
construction_state = PA_CONSTRUCTION_PANEL_OPEN
|
||||
did_something = TRUE
|
||||
if(PA_CONSTRUCTION_PANEL_OPEN)
|
||||
if(istype(W, /obj/item/wirecutters))//TODO:Shock user if its on?
|
||||
user.visible_message("[user.name] removes some wires from the [name].", \
|
||||
"You remove some wires.")
|
||||
construction_state = PA_CONSTRUCTION_UNWIRED
|
||||
did_something = TRUE
|
||||
else if(istype(W, /obj/item/screwdriver))
|
||||
user.visible_message("[user.name] closes the [name]'s access panel.", \
|
||||
"You close the access panel.")
|
||||
construction_state = PA_CONSTRUCTION_COMPLETE
|
||||
did_something = TRUE
|
||||
if(PA_CONSTRUCTION_COMPLETE)
|
||||
if(istype(W, /obj/item/screwdriver))
|
||||
user.visible_message("[user.name] opens the [name]'s access panel.", \
|
||||
"You open the access panel.")
|
||||
construction_state = PA_CONSTRUCTION_PANEL_OPEN
|
||||
did_something = TRUE
|
||||
|
||||
if(did_something)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
update_state()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/structure/particle_accelerator/deconstruct(disassembled = TRUE)
|
||||
if(!(flags_1 & NODECONSTRUCT_1))
|
||||
new /obj/item/stack/sheet/metal (loc, 5)
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/particle_accelerator/Move()
|
||||
. = ..()
|
||||
if(master && master.active)
|
||||
master.toggle_power()
|
||||
investigate_log("was moved whilst active; it <font color='red'>powered down</font>.", INVESTIGATE_SINGULO)
|
||||
|
||||
|
||||
/obj/structure/particle_accelerator/update_icon()
|
||||
switch(construction_state)
|
||||
if(PA_CONSTRUCTION_UNSECURED,PA_CONSTRUCTION_UNWIRED)
|
||||
icon_state="[reference]"
|
||||
if(PA_CONSTRUCTION_PANEL_OPEN)
|
||||
icon_state="[reference]w"
|
||||
if(PA_CONSTRUCTION_COMPLETE)
|
||||
if(powered)
|
||||
icon_state="[reference]p[strength]"
|
||||
else
|
||||
icon_state="[reference]c"
|
||||
|
||||
/obj/structure/particle_accelerator/proc/update_state()
|
||||
if(master)
|
||||
master.update_state()
|
||||
|
||||
/obj/structure/particle_accelerator/proc/connect_master(obj/O)
|
||||
if(O.dir == dir)
|
||||
master = O
|
||||
return 1
|
||||
return 0
|
||||
|
||||
///////////
|
||||
// PARTS //
|
||||
///////////
|
||||
|
||||
|
||||
/obj/structure/particle_accelerator/end_cap
|
||||
name = "Alpha Particle Generation Array"
|
||||
desc = "This is where Alpha particles are generated from \[REDACTED\]."
|
||||
icon_state = "end_cap"
|
||||
reference = "end_cap"
|
||||
|
||||
/obj/structure/particle_accelerator/power_box
|
||||
name = "Particle Focusing EM Lens"
|
||||
desc = "This uses electromagnetic waves to focus the Alpha particles."
|
||||
icon = 'icons/obj/machines/particle_accelerator.dmi'
|
||||
icon_state = "power_box"
|
||||
reference = "power_box"
|
||||
|
||||
/obj/structure/particle_accelerator/fuel_chamber
|
||||
name = "EM Acceleration Chamber"
|
||||
desc = "This is where the Alpha particles are accelerated to <b><i>radical speeds</i></b>."
|
||||
icon = 'icons/obj/machines/particle_accelerator.dmi'
|
||||
icon_state = "fuel_chamber"
|
||||
reference = "fuel_chamber"
|
||||
|
||||
@@ -1,330 +1,330 @@
|
||||
/obj/machinery/particle_accelerator/control_box
|
||||
name = "Particle Accelerator Control Console"
|
||||
desc = "This controls the density of the particles."
|
||||
icon = 'icons/obj/machines/particle_accelerator.dmi'
|
||||
icon_state = "control_box"
|
||||
anchored = FALSE
|
||||
density = TRUE
|
||||
use_power = NO_POWER_USE
|
||||
idle_power_usage = 500
|
||||
active_power_usage = 10000
|
||||
dir = NORTH
|
||||
var/strength_upper_limit = 2
|
||||
var/interface_control = 1
|
||||
var/list/obj/structure/particle_accelerator/connected_parts
|
||||
var/assembled = 0
|
||||
var/construction_state = PA_CONSTRUCTION_UNSECURED
|
||||
var/active = 0
|
||||
var/strength = 0
|
||||
var/powered = 0
|
||||
mouse_opacity = MOUSE_OPACITY_OPAQUE
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/Initialize()
|
||||
. = ..()
|
||||
wires = new /datum/wires/particle_accelerator/control_box(src)
|
||||
connected_parts = list()
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/Destroy()
|
||||
if(active)
|
||||
toggle_power()
|
||||
for(var/CP in connected_parts)
|
||||
var/obj/structure/particle_accelerator/part = CP
|
||||
part.master = null
|
||||
connected_parts.Cut()
|
||||
QDEL_NULL(wires)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/attack_hand(mob/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(construction_state == PA_CONSTRUCTION_COMPLETE)
|
||||
interact(user)
|
||||
else if(construction_state == PA_CONSTRUCTION_PANEL_OPEN)
|
||||
wires.interact(user)
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/proc/update_state()
|
||||
if(construction_state < PA_CONSTRUCTION_COMPLETE)
|
||||
use_power = NO_POWER_USE
|
||||
assembled = 0
|
||||
active = 0
|
||||
for(var/CP in connected_parts)
|
||||
var/obj/structure/particle_accelerator/part = CP
|
||||
part.strength = null
|
||||
part.powered = 0
|
||||
part.update_icon()
|
||||
connected_parts.Cut()
|
||||
return
|
||||
if(!part_scan())
|
||||
use_power = IDLE_POWER_USE
|
||||
active = 0
|
||||
connected_parts.Cut()
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/update_icon()
|
||||
if(active)
|
||||
icon_state = "control_boxp1"
|
||||
else
|
||||
if(use_power)
|
||||
if(assembled)
|
||||
icon_state = "control_boxp"
|
||||
else
|
||||
icon_state = "ucontrol_boxp"
|
||||
else
|
||||
switch(construction_state)
|
||||
if(PA_CONSTRUCTION_UNSECURED, PA_CONSTRUCTION_UNWIRED)
|
||||
icon_state = "control_box"
|
||||
if(PA_CONSTRUCTION_PANEL_OPEN)
|
||||
icon_state = "control_boxw"
|
||||
else
|
||||
icon_state = "control_boxc"
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
|
||||
if(!interface_control)
|
||||
to_chat(usr, "<span class='error'>ERROR: Request timed out. Check wire contacts.</span>")
|
||||
return
|
||||
|
||||
if(href_list["close"])
|
||||
usr << browse(null, "window=pacontrol")
|
||||
usr.unset_machine()
|
||||
return
|
||||
if(href_list["togglep"])
|
||||
if(!wires.is_cut(WIRE_POWER))
|
||||
toggle_power()
|
||||
|
||||
else if(href_list["scan"])
|
||||
part_scan()
|
||||
|
||||
else if(href_list["strengthup"])
|
||||
if(!wires.is_cut(WIRE_STRENGTH))
|
||||
add_strength()
|
||||
|
||||
else if(href_list["strengthdown"])
|
||||
if(!wires.is_cut(WIRE_STRENGTH))
|
||||
remove_strength()
|
||||
|
||||
updateDialog()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/proc/strength_change()
|
||||
for(var/CP in connected_parts)
|
||||
var/obj/structure/particle_accelerator/part = CP
|
||||
part.strength = strength
|
||||
part.update_icon()
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/proc/add_strength(s)
|
||||
if(assembled && (strength < strength_upper_limit))
|
||||
strength++
|
||||
strength_change()
|
||||
|
||||
message_admins("PA Control Computer increased to [strength] by [ADMIN_LOOKUPFLW(usr)] in [ADMIN_VERBOSEJMP(src)]")
|
||||
log_game("PA Control Computer increased to [strength] by [key_name(usr)] in [AREACOORD(src)]")
|
||||
investigate_log("increased to <font color='red'>[strength]</font> by [key_name(usr)] at [AREACOORD(src)]", INVESTIGATE_SINGULO)
|
||||
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/proc/remove_strength(s)
|
||||
if(assembled && (strength > 0))
|
||||
strength--
|
||||
strength_change()
|
||||
|
||||
message_admins("PA Control Computer decreased to [strength] by [ADMIN_LOOKUPFLW(usr)] in [ADMIN_VERBOSEJMP(src)]")
|
||||
log_game("PA Control Computer decreased to [strength] by [key_name(usr)] in [AREACOORD(src)]")
|
||||
investigate_log("decreased to <font color='green'>[strength]</font> by [key_name(usr)] at [AREACOORD(src)]", INVESTIGATE_SINGULO)
|
||||
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/power_change()
|
||||
..()
|
||||
if(stat & NOPOWER)
|
||||
active = 0
|
||||
use_power = NO_POWER_USE
|
||||
else if(!stat && construction_state == PA_CONSTRUCTION_COMPLETE)
|
||||
use_power = IDLE_POWER_USE
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/process()
|
||||
if(active)
|
||||
//a part is missing!
|
||||
if(connected_parts.len < 6)
|
||||
investigate_log("lost a connected part; It <font color='red'>powered down</font>.", INVESTIGATE_SINGULO)
|
||||
toggle_power()
|
||||
update_icon()
|
||||
return
|
||||
//emit some particles
|
||||
for(var/obj/structure/particle_accelerator/particle_emitter/PE in connected_parts)
|
||||
PE.emit_particle(strength)
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/proc/part_scan()
|
||||
var/ldir = turn(dir,-90)
|
||||
var/rdir = turn(dir,90)
|
||||
var/odir = turn(dir,180)
|
||||
var/turf/T = loc
|
||||
|
||||
assembled = 0
|
||||
critical_machine = FALSE
|
||||
|
||||
var/obj/structure/particle_accelerator/fuel_chamber/F = locate() in orange(1,src)
|
||||
if(!F)
|
||||
return 0
|
||||
|
||||
setDir(F.dir)
|
||||
connected_parts.Cut()
|
||||
|
||||
T = get_step(T,rdir)
|
||||
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
|
||||
critical_machine = TRUE //Only counts if the PA is actually assembled.
|
||||
return 1
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/proc/check_part(turf/T, type)
|
||||
var/obj/structure/particle_accelerator/PA = locate(/obj/structure/particle_accelerator) in T
|
||||
if(istype(PA, type) && (PA.construction_state == PA_CONSTRUCTION_COMPLETE))
|
||||
if(PA.connect_master(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='green'>ON</font>":"<font color='red'>OFF</font>"] by [usr ? key_name(usr) : "outside forces"] at [AREACOORD(src)]", INVESTIGATE_SINGULO)
|
||||
message_admins("PA Control Computer turned [active ?"ON":"OFF"] by [usr ? ADMIN_LOOKUPFLW(usr) : "outside forces"] in [ADMIN_VERBOSEJMP(src)]")
|
||||
log_game("PA Control Computer turned [active ?"ON":"OFF"] by [usr ? "[key_name(usr)]" : "outside forces"] at [AREACOORD(src)]")
|
||||
if(active)
|
||||
use_power = ACTIVE_POWER_USE
|
||||
for(var/CP in connected_parts)
|
||||
var/obj/structure/particle_accelerator/part = CP
|
||||
part.strength = strength
|
||||
part.powered = 1
|
||||
part.update_icon()
|
||||
else
|
||||
use_power = IDLE_POWER_USE
|
||||
for(var/CP in connected_parts)
|
||||
var/obj/structure/particle_accelerator/part = CP
|
||||
part.strength = null
|
||||
part.powered = 0
|
||||
part.update_icon()
|
||||
return 1
|
||||
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/ui_interact(mob/user)
|
||||
. = ..()
|
||||
if((get_dist(src, user) > 1) || (stat & (BROKEN|NOPOWER)))
|
||||
if(!issilicon(user))
|
||||
user.unset_machine()
|
||||
user << browse(null, "window=pacontrol")
|
||||
return
|
||||
|
||||
var/dat = ""
|
||||
dat += "<A href='?src=[REF(src)];close=1'>Close</A><BR><BR>"
|
||||
dat += "<h3>Status</h3>"
|
||||
if(!assembled)
|
||||
dat += "Unable to detect all parts!<BR>"
|
||||
dat += "<A href='?src=[REF(src)];scan=1'>Run Scan</A><BR><BR>"
|
||||
else
|
||||
dat += "All parts in place.<BR><BR>"
|
||||
dat += "Power:"
|
||||
if(active)
|
||||
dat += "On<BR>"
|
||||
else
|
||||
dat += "Off <BR>"
|
||||
dat += "<A href='?src=[REF(src)];togglep=1'>Toggle Power</A><BR><BR>"
|
||||
dat += "Particle Strength: [strength] "
|
||||
dat += "<A href='?src=[REF(src)];strengthdown=1'>--</A>|<A href='?src=[REF(src)];strengthup=1'>++</A><BR><BR>"
|
||||
|
||||
var/datum/browser/popup = new(user, "pacontrol", name, 420, 300)
|
||||
popup.set_content(dat)
|
||||
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
|
||||
popup.open()
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/examine(mob/user)
|
||||
. = ..()
|
||||
switch(construction_state)
|
||||
if(PA_CONSTRUCTION_UNSECURED)
|
||||
. += "Looks like it's not attached to the flooring."
|
||||
if(PA_CONSTRUCTION_UNWIRED)
|
||||
. += "It is missing some cables."
|
||||
if(PA_CONSTRUCTION_PANEL_OPEN)
|
||||
. += "The panel is open."
|
||||
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/attackby(obj/item/W, mob/user, params)
|
||||
var/did_something = FALSE
|
||||
|
||||
switch(construction_state)
|
||||
if(PA_CONSTRUCTION_UNSECURED)
|
||||
if(istype(W, /obj/item/wrench) && !isinspace())
|
||||
W.play_tool_sound(src, 75)
|
||||
anchored = TRUE
|
||||
user.visible_message("[user.name] secures the [name] to the floor.", \
|
||||
"You secure the external bolts.")
|
||||
construction_state = PA_CONSTRUCTION_UNWIRED
|
||||
did_something = TRUE
|
||||
if(PA_CONSTRUCTION_UNWIRED)
|
||||
if(istype(W, /obj/item/wrench))
|
||||
W.play_tool_sound(src, 75)
|
||||
anchored = FALSE
|
||||
user.visible_message("[user.name] detaches the [name] from the floor.", \
|
||||
"You remove the external bolts.")
|
||||
construction_state = PA_CONSTRUCTION_UNSECURED
|
||||
did_something = TRUE
|
||||
else if(istype(W, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/CC = W
|
||||
if(CC.use(1))
|
||||
user.visible_message("[user.name] adds wires to the [name].", \
|
||||
"You add some wires.")
|
||||
construction_state = PA_CONSTRUCTION_PANEL_OPEN
|
||||
did_something = TRUE
|
||||
if(PA_CONSTRUCTION_PANEL_OPEN)
|
||||
if(istype(W, /obj/item/wirecutters))//TODO:Shock user if its on?
|
||||
user.visible_message("[user.name] removes some wires from the [name].", \
|
||||
"You remove some wires.")
|
||||
construction_state = PA_CONSTRUCTION_UNWIRED
|
||||
did_something = TRUE
|
||||
else if(istype(W, /obj/item/screwdriver))
|
||||
user.visible_message("[user.name] closes the [name]'s access panel.", \
|
||||
"You close the access panel.")
|
||||
construction_state = PA_CONSTRUCTION_COMPLETE
|
||||
did_something = TRUE
|
||||
if(PA_CONSTRUCTION_COMPLETE)
|
||||
if(istype(W, /obj/item/screwdriver))
|
||||
user.visible_message("[user.name] opens the [name]'s access panel.", \
|
||||
"You open the access panel.")
|
||||
construction_state = PA_CONSTRUCTION_PANEL_OPEN
|
||||
did_something = TRUE
|
||||
|
||||
if(did_something)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
update_state()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
..()
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/blob_act(obj/structure/blob/B)
|
||||
if(prob(50))
|
||||
qdel(src)
|
||||
|
||||
#undef PA_CONSTRUCTION_UNSECURED
|
||||
#undef PA_CONSTRUCTION_UNWIRED
|
||||
#undef PA_CONSTRUCTION_PANEL_OPEN
|
||||
#undef PA_CONSTRUCTION_COMPLETE
|
||||
/obj/machinery/particle_accelerator/control_box
|
||||
name = "Particle Accelerator Control Console"
|
||||
desc = "This controls the density of the particles."
|
||||
icon = 'icons/obj/machines/particle_accelerator.dmi'
|
||||
icon_state = "control_box"
|
||||
anchored = FALSE
|
||||
density = TRUE
|
||||
use_power = NO_POWER_USE
|
||||
idle_power_usage = 500
|
||||
active_power_usage = 10000
|
||||
dir = NORTH
|
||||
var/strength_upper_limit = 2
|
||||
var/interface_control = 1
|
||||
var/list/obj/structure/particle_accelerator/connected_parts
|
||||
var/assembled = 0
|
||||
var/construction_state = PA_CONSTRUCTION_UNSECURED
|
||||
var/active = 0
|
||||
var/strength = 0
|
||||
var/powered = 0
|
||||
mouse_opacity = MOUSE_OPACITY_OPAQUE
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/Initialize()
|
||||
. = ..()
|
||||
wires = new /datum/wires/particle_accelerator/control_box(src)
|
||||
connected_parts = list()
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/Destroy()
|
||||
if(active)
|
||||
toggle_power()
|
||||
for(var/CP in connected_parts)
|
||||
var/obj/structure/particle_accelerator/part = CP
|
||||
part.master = null
|
||||
connected_parts.Cut()
|
||||
QDEL_NULL(wires)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/attack_hand(mob/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(construction_state == PA_CONSTRUCTION_COMPLETE)
|
||||
interact(user)
|
||||
else if(construction_state == PA_CONSTRUCTION_PANEL_OPEN)
|
||||
wires.interact(user)
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/proc/update_state()
|
||||
if(construction_state < PA_CONSTRUCTION_COMPLETE)
|
||||
use_power = NO_POWER_USE
|
||||
assembled = 0
|
||||
active = 0
|
||||
for(var/CP in connected_parts)
|
||||
var/obj/structure/particle_accelerator/part = CP
|
||||
part.strength = null
|
||||
part.powered = 0
|
||||
part.update_icon()
|
||||
connected_parts.Cut()
|
||||
return
|
||||
if(!part_scan())
|
||||
use_power = IDLE_POWER_USE
|
||||
active = 0
|
||||
connected_parts.Cut()
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/update_icon()
|
||||
if(active)
|
||||
icon_state = "control_boxp1"
|
||||
else
|
||||
if(use_power)
|
||||
if(assembled)
|
||||
icon_state = "control_boxp"
|
||||
else
|
||||
icon_state = "ucontrol_boxp"
|
||||
else
|
||||
switch(construction_state)
|
||||
if(PA_CONSTRUCTION_UNSECURED, PA_CONSTRUCTION_UNWIRED)
|
||||
icon_state = "control_box"
|
||||
if(PA_CONSTRUCTION_PANEL_OPEN)
|
||||
icon_state = "control_boxw"
|
||||
else
|
||||
icon_state = "control_boxc"
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
|
||||
if(!interface_control)
|
||||
to_chat(usr, "<span class='error'>ERROR: Request timed out. Check wire contacts.</span>")
|
||||
return
|
||||
|
||||
if(href_list["close"])
|
||||
usr << browse(null, "window=pacontrol")
|
||||
usr.unset_machine()
|
||||
return
|
||||
if(href_list["togglep"])
|
||||
if(!wires.is_cut(WIRE_POWER))
|
||||
toggle_power()
|
||||
|
||||
else if(href_list["scan"])
|
||||
part_scan()
|
||||
|
||||
else if(href_list["strengthup"])
|
||||
if(!wires.is_cut(WIRE_STRENGTH))
|
||||
add_strength()
|
||||
|
||||
else if(href_list["strengthdown"])
|
||||
if(!wires.is_cut(WIRE_STRENGTH))
|
||||
remove_strength()
|
||||
|
||||
updateDialog()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/proc/strength_change()
|
||||
for(var/CP in connected_parts)
|
||||
var/obj/structure/particle_accelerator/part = CP
|
||||
part.strength = strength
|
||||
part.update_icon()
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/proc/add_strength(s)
|
||||
if(assembled && (strength < strength_upper_limit))
|
||||
strength++
|
||||
strength_change()
|
||||
|
||||
message_admins("PA Control Computer increased to [strength] by [ADMIN_LOOKUPFLW(usr)] in [ADMIN_VERBOSEJMP(src)]")
|
||||
log_game("PA Control Computer increased to [strength] by [key_name(usr)] in [AREACOORD(src)]")
|
||||
investigate_log("increased to <font color='red'>[strength]</font> by [key_name(usr)] at [AREACOORD(src)]", INVESTIGATE_SINGULO)
|
||||
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/proc/remove_strength(s)
|
||||
if(assembled && (strength > 0))
|
||||
strength--
|
||||
strength_change()
|
||||
|
||||
message_admins("PA Control Computer decreased to [strength] by [ADMIN_LOOKUPFLW(usr)] in [ADMIN_VERBOSEJMP(src)]")
|
||||
log_game("PA Control Computer decreased to [strength] by [key_name(usr)] in [AREACOORD(src)]")
|
||||
investigate_log("decreased to <font color='green'>[strength]</font> by [key_name(usr)] at [AREACOORD(src)]", INVESTIGATE_SINGULO)
|
||||
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/power_change()
|
||||
..()
|
||||
if(stat & NOPOWER)
|
||||
active = 0
|
||||
use_power = NO_POWER_USE
|
||||
else if(!stat && construction_state == PA_CONSTRUCTION_COMPLETE)
|
||||
use_power = IDLE_POWER_USE
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/process()
|
||||
if(active)
|
||||
//a part is missing!
|
||||
if(connected_parts.len < 6)
|
||||
investigate_log("lost a connected part; It <font color='red'>powered down</font>.", INVESTIGATE_SINGULO)
|
||||
toggle_power()
|
||||
update_icon()
|
||||
return
|
||||
//emit some particles
|
||||
for(var/obj/structure/particle_accelerator/particle_emitter/PE in connected_parts)
|
||||
PE.emit_particle(strength)
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/proc/part_scan()
|
||||
var/ldir = turn(dir,-90)
|
||||
var/rdir = turn(dir,90)
|
||||
var/odir = turn(dir,180)
|
||||
var/turf/T = loc
|
||||
|
||||
assembled = 0
|
||||
critical_machine = FALSE
|
||||
|
||||
var/obj/structure/particle_accelerator/fuel_chamber/F = locate() in orange(1,src)
|
||||
if(!F)
|
||||
return 0
|
||||
|
||||
setDir(F.dir)
|
||||
connected_parts.Cut()
|
||||
|
||||
T = get_step(T,rdir)
|
||||
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
|
||||
critical_machine = TRUE //Only counts if the PA is actually assembled.
|
||||
return 1
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/proc/check_part(turf/T, type)
|
||||
var/obj/structure/particle_accelerator/PA = locate(/obj/structure/particle_accelerator) in T
|
||||
if(istype(PA, type) && (PA.construction_state == PA_CONSTRUCTION_COMPLETE))
|
||||
if(PA.connect_master(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='green'>ON</font>":"<font color='red'>OFF</font>"] by [usr ? key_name(usr) : "outside forces"] at [AREACOORD(src)]", INVESTIGATE_SINGULO)
|
||||
message_admins("PA Control Computer turned [active ?"ON":"OFF"] by [usr ? ADMIN_LOOKUPFLW(usr) : "outside forces"] in [ADMIN_VERBOSEJMP(src)]")
|
||||
log_game("PA Control Computer turned [active ?"ON":"OFF"] by [usr ? "[key_name(usr)]" : "outside forces"] at [AREACOORD(src)]")
|
||||
if(active)
|
||||
use_power = ACTIVE_POWER_USE
|
||||
for(var/CP in connected_parts)
|
||||
var/obj/structure/particle_accelerator/part = CP
|
||||
part.strength = strength
|
||||
part.powered = 1
|
||||
part.update_icon()
|
||||
else
|
||||
use_power = IDLE_POWER_USE
|
||||
for(var/CP in connected_parts)
|
||||
var/obj/structure/particle_accelerator/part = CP
|
||||
part.strength = null
|
||||
part.powered = 0
|
||||
part.update_icon()
|
||||
return 1
|
||||
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/ui_interact(mob/user)
|
||||
. = ..()
|
||||
if((get_dist(src, user) > 1) || (stat & (BROKEN|NOPOWER)))
|
||||
if(!issilicon(user))
|
||||
user.unset_machine()
|
||||
user << browse(null, "window=pacontrol")
|
||||
return
|
||||
|
||||
var/dat = ""
|
||||
dat += "<A href='?src=[REF(src)];close=1'>Close</A><BR><BR>"
|
||||
dat += "<h3>Status</h3>"
|
||||
if(!assembled)
|
||||
dat += "Unable to detect all parts!<BR>"
|
||||
dat += "<A href='?src=[REF(src)];scan=1'>Run Scan</A><BR><BR>"
|
||||
else
|
||||
dat += "All parts in place.<BR><BR>"
|
||||
dat += "Power:"
|
||||
if(active)
|
||||
dat += "On<BR>"
|
||||
else
|
||||
dat += "Off <BR>"
|
||||
dat += "<A href='?src=[REF(src)];togglep=1'>Toggle Power</A><BR><BR>"
|
||||
dat += "Particle Strength: [strength] "
|
||||
dat += "<A href='?src=[REF(src)];strengthdown=1'>--</A>|<A href='?src=[REF(src)];strengthup=1'>++</A><BR><BR>"
|
||||
|
||||
var/datum/browser/popup = new(user, "pacontrol", name, 420, 300)
|
||||
popup.set_content(dat)
|
||||
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
|
||||
popup.open()
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/examine(mob/user)
|
||||
. = ..()
|
||||
switch(construction_state)
|
||||
if(PA_CONSTRUCTION_UNSECURED)
|
||||
. += "Looks like it's not attached to the flooring."
|
||||
if(PA_CONSTRUCTION_UNWIRED)
|
||||
. += "It is missing some cables."
|
||||
if(PA_CONSTRUCTION_PANEL_OPEN)
|
||||
. += "The panel is open."
|
||||
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/attackby(obj/item/W, mob/user, params)
|
||||
var/did_something = FALSE
|
||||
|
||||
switch(construction_state)
|
||||
if(PA_CONSTRUCTION_UNSECURED)
|
||||
if(istype(W, /obj/item/wrench) && !isinspace())
|
||||
W.play_tool_sound(src, 75)
|
||||
anchored = TRUE
|
||||
user.visible_message("[user.name] secures the [name] to the floor.", \
|
||||
"You secure the external bolts.")
|
||||
construction_state = PA_CONSTRUCTION_UNWIRED
|
||||
did_something = TRUE
|
||||
if(PA_CONSTRUCTION_UNWIRED)
|
||||
if(istype(W, /obj/item/wrench))
|
||||
W.play_tool_sound(src, 75)
|
||||
anchored = FALSE
|
||||
user.visible_message("[user.name] detaches the [name] from the floor.", \
|
||||
"You remove the external bolts.")
|
||||
construction_state = PA_CONSTRUCTION_UNSECURED
|
||||
did_something = TRUE
|
||||
else if(istype(W, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/CC = W
|
||||
if(CC.use(1))
|
||||
user.visible_message("[user.name] adds wires to the [name].", \
|
||||
"You add some wires.")
|
||||
construction_state = PA_CONSTRUCTION_PANEL_OPEN
|
||||
did_something = TRUE
|
||||
if(PA_CONSTRUCTION_PANEL_OPEN)
|
||||
if(istype(W, /obj/item/wirecutters))//TODO:Shock user if its on?
|
||||
user.visible_message("[user.name] removes some wires from the [name].", \
|
||||
"You remove some wires.")
|
||||
construction_state = PA_CONSTRUCTION_UNWIRED
|
||||
did_something = TRUE
|
||||
else if(istype(W, /obj/item/screwdriver))
|
||||
user.visible_message("[user.name] closes the [name]'s access panel.", \
|
||||
"You close the access panel.")
|
||||
construction_state = PA_CONSTRUCTION_COMPLETE
|
||||
did_something = TRUE
|
||||
if(PA_CONSTRUCTION_COMPLETE)
|
||||
if(istype(W, /obj/item/screwdriver))
|
||||
user.visible_message("[user.name] opens the [name]'s access panel.", \
|
||||
"You open the access panel.")
|
||||
construction_state = PA_CONSTRUCTION_PANEL_OPEN
|
||||
did_something = TRUE
|
||||
|
||||
if(did_something)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
update_state()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
..()
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/blob_act(obj/structure/blob/B)
|
||||
if(prob(50))
|
||||
qdel(src)
|
||||
|
||||
#undef PA_CONSTRUCTION_UNSECURED
|
||||
#undef PA_CONSTRUCTION_UNWIRED
|
||||
#undef PA_CONSTRUCTION_PANEL_OPEN
|
||||
#undef PA_CONSTRUCTION_COMPLETE
|
||||
|
||||
@@ -1,93 +1,93 @@
|
||||
//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 = 'goon/icons/obj/power.dmi'
|
||||
icon_state = "tracker"
|
||||
density = TRUE
|
||||
use_power = NO_POWER_USE
|
||||
max_integrity = 250
|
||||
integrity_failure = 50
|
||||
|
||||
var/id = 0
|
||||
var/sun_angle = 0 // sun angle as set by sun datum
|
||||
var/obj/machinery/power/solar_control/control = null
|
||||
|
||||
/obj/machinery/power/tracker/Initialize(mapload, obj/item/solar_assembly/S)
|
||||
. = ..()
|
||||
Make(S)
|
||||
connect_to_network()
|
||||
|
||||
/obj/machinery/power/tracker/Destroy()
|
||||
unset_control() //remove from control computer
|
||||
return ..()
|
||||
|
||||
//set the control of the tracker to a given computer if closer than SOLAR_MAX_DIST
|
||||
/obj/machinery/power/tracker/proc/set_control(obj/machinery/power/solar_control/SC)
|
||||
if(!SC || (get_dist(src, SC) > SOLAR_MAX_DIST))
|
||||
return 0
|
||||
control = SC
|
||||
SC.connected_tracker = src
|
||||
return 1
|
||||
|
||||
//set the control of the tracker to null and removes it from the previous control computer if needed
|
||||
/obj/machinery/power/tracker/proc/unset_control()
|
||||
if(control)
|
||||
control.connected_tracker = null
|
||||
control = null
|
||||
|
||||
/obj/machinery/power/tracker/proc/Make(obj/item/solar_assembly/S)
|
||||
if(!S)
|
||||
S = new /obj/item/solar_assembly(src)
|
||||
S.glass_type = /obj/item/stack/sheet/glass
|
||||
S.tracker = 1
|
||||
S.anchored = TRUE
|
||||
S.forceMove(src)
|
||||
update_icon()
|
||||
|
||||
//updates the tracker icon and the facing angle for the control computer
|
||||
/obj/machinery/power/tracker/proc/set_angle(angle)
|
||||
sun_angle = angle
|
||||
|
||||
//set icon dir to show sun illumination
|
||||
setDir(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.currentdir = angle
|
||||
|
||||
/obj/machinery/power/tracker/crowbar_act(mob/user, obj/item/I)
|
||||
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
|
||||
user.visible_message("[user] begins to take the glass off [src].", "<span class='notice'>You begin to take the glass off [src]...</span>")
|
||||
if(I.use_tool(src, user, 50))
|
||||
playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
|
||||
user.visible_message("[user] takes the glass off [src].", "<span class='notice'>You take the glass off [src].</span>")
|
||||
deconstruct(TRUE)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/tracker/obj_break(damage_flag)
|
||||
if(!(stat & BROKEN) && !(flags_1 & NODECONSTRUCT_1))
|
||||
playsound(loc, 'sound/effects/glassbr3.ogg', 100, 1)
|
||||
stat |= BROKEN
|
||||
unset_control()
|
||||
|
||||
/obj/machinery/power/solar/deconstruct(disassembled = TRUE)
|
||||
if(!(flags_1 & NODECONSTRUCT_1))
|
||||
if(disassembled)
|
||||
var/obj/item/solar_assembly/S = locate() in src
|
||||
if(S)
|
||||
S.forceMove(loc)
|
||||
S.give_glass(stat & BROKEN)
|
||||
else
|
||||
playsound(src, "shatter", 70, 1)
|
||||
new /obj/item/shard(src.loc)
|
||||
new /obj/item/shard(src.loc)
|
||||
qdel(src)
|
||||
|
||||
// Tracker Electronic
|
||||
|
||||
/obj/item/electronics/tracker
|
||||
name = "tracker electronics"
|
||||
//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 = 'goon/icons/obj/power.dmi'
|
||||
icon_state = "tracker"
|
||||
density = TRUE
|
||||
use_power = NO_POWER_USE
|
||||
max_integrity = 250
|
||||
integrity_failure = 50
|
||||
|
||||
var/id = 0
|
||||
var/sun_angle = 0 // sun angle as set by sun datum
|
||||
var/obj/machinery/power/solar_control/control = null
|
||||
|
||||
/obj/machinery/power/tracker/Initialize(mapload, obj/item/solar_assembly/S)
|
||||
. = ..()
|
||||
Make(S)
|
||||
connect_to_network()
|
||||
|
||||
/obj/machinery/power/tracker/Destroy()
|
||||
unset_control() //remove from control computer
|
||||
return ..()
|
||||
|
||||
//set the control of the tracker to a given computer if closer than SOLAR_MAX_DIST
|
||||
/obj/machinery/power/tracker/proc/set_control(obj/machinery/power/solar_control/SC)
|
||||
if(!SC || (get_dist(src, SC) > SOLAR_MAX_DIST))
|
||||
return 0
|
||||
control = SC
|
||||
SC.connected_tracker = src
|
||||
return 1
|
||||
|
||||
//set the control of the tracker to null and removes it from the previous control computer if needed
|
||||
/obj/machinery/power/tracker/proc/unset_control()
|
||||
if(control)
|
||||
control.connected_tracker = null
|
||||
control = null
|
||||
|
||||
/obj/machinery/power/tracker/proc/Make(obj/item/solar_assembly/S)
|
||||
if(!S)
|
||||
S = new /obj/item/solar_assembly(src)
|
||||
S.glass_type = /obj/item/stack/sheet/glass
|
||||
S.tracker = 1
|
||||
S.anchored = TRUE
|
||||
S.forceMove(src)
|
||||
update_icon()
|
||||
|
||||
//updates the tracker icon and the facing angle for the control computer
|
||||
/obj/machinery/power/tracker/proc/set_angle(angle)
|
||||
sun_angle = angle
|
||||
|
||||
//set icon dir to show sun illumination
|
||||
setDir(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.currentdir = angle
|
||||
|
||||
/obj/machinery/power/tracker/crowbar_act(mob/user, obj/item/I)
|
||||
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
|
||||
user.visible_message("[user] begins to take the glass off [src].", "<span class='notice'>You begin to take the glass off [src]...</span>")
|
||||
if(I.use_tool(src, user, 50))
|
||||
playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
|
||||
user.visible_message("[user] takes the glass off [src].", "<span class='notice'>You take the glass off [src].</span>")
|
||||
deconstruct(TRUE)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/tracker/obj_break(damage_flag)
|
||||
if(!(stat & BROKEN) && !(flags_1 & NODECONSTRUCT_1))
|
||||
playsound(loc, 'sound/effects/glassbr3.ogg', 100, 1)
|
||||
stat |= BROKEN
|
||||
unset_control()
|
||||
|
||||
/obj/machinery/power/solar/deconstruct(disassembled = TRUE)
|
||||
if(!(flags_1 & NODECONSTRUCT_1))
|
||||
if(disassembled)
|
||||
var/obj/item/solar_assembly/S = locate() in src
|
||||
if(S)
|
||||
S.forceMove(loc)
|
||||
S.give_glass(stat & BROKEN)
|
||||
else
|
||||
playsound(src, "shatter", 70, 1)
|
||||
new /obj/item/shard(src.loc)
|
||||
new /obj/item/shard(src.loc)
|
||||
qdel(src)
|
||||
|
||||
// Tracker Electronic
|
||||
|
||||
/obj/item/electronics/tracker
|
||||
name = "tracker electronics"
|
||||
|
||||
Reference in New Issue
Block a user