mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-04 05:51:54 +00:00
* [GBP No Update] Perish, individual logging runtime (#69024) missed 2 or 3(lol it was more when I look back at the files), LOG_GAME tags on the log_message line, and did some cleaning up since i was looking through every log_message again Co-authored-by: tattle <66640614+dragomagol@ users.noreply.github.com> Co-authored-by: tattle <66640614+dragomagol@ users.noreply.github.com> * [GBP No Update] Perish, individual logging runtime Co-authored-by: Mooshimi <85910816+Mooshimi@users.noreply.github.com> Co-authored-by: tattle <66640614+dragomagol@ users.noreply.github.com>
203 lines
6.4 KiB
Plaintext
203 lines
6.4 KiB
Plaintext
#define DISCONNECTED 0
|
|
#define CLAMPED_OFF 1
|
|
#define OPERATING 2
|
|
|
|
#define FRACTION_TO_RELEASE 50
|
|
#define ALERT 90
|
|
#define MINIMUM_HEAT 10000
|
|
|
|
// Powersink - used to drain station power
|
|
|
|
/obj/item/powersink
|
|
name = "power sink"
|
|
desc = "A power sink which drains energy from electrical systems and converts it to heat. Ensure short workloads and ample time to cool down if used in high energy systems."
|
|
icon = 'icons/obj/device.dmi'
|
|
icon_state = "powersink0"
|
|
inhand_icon_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
|
|
item_flags = NO_PIXEL_RANDOM_DROP
|
|
throwforce = 5
|
|
throw_speed = 1
|
|
throw_range = 2
|
|
custom_materials = list(/datum/material/iron=750)
|
|
var/max_heat = 5e7 // Maximum contained heat before exploding. Not actual temperature.
|
|
var/internal_heat = 0 // Contained heat, goes down every tick.
|
|
var/mode = DISCONNECTED // DISCONNECTED, CLAMPED_OFF, OPERATING
|
|
var/admins_warned = FALSE // Stop spam, only warn the admins once that we are about to boom.
|
|
|
|
var/obj/structure/cable/attached
|
|
|
|
/obj/item/powersink/update_icon_state()
|
|
icon_state = "powersink[mode == OPERATING]"
|
|
return ..()
|
|
|
|
/obj/item/powersink/examine(mob/user)
|
|
. = ..()
|
|
if(mode)
|
|
. += "\The [src] is bolted to the floor."
|
|
if(in_range(user, src) || isobserver(user) && internal_heat > max_heat * 0.5)
|
|
. += span_danger("[src] is warping the air above it. It must be very hot.")
|
|
|
|
/obj/item/powersink/set_anchored(anchorvalue)
|
|
. = ..()
|
|
set_density(anchorvalue)
|
|
|
|
/obj/item/powersink/proc/set_mode(value)
|
|
if(value == mode)
|
|
return
|
|
switch(value)
|
|
if(DISCONNECTED)
|
|
attached = null
|
|
if(mode == OPERATING && internal_heat < MINIMUM_HEAT)
|
|
STOP_PROCESSING(SSobj, src)
|
|
internal_heat = 0
|
|
set_anchored(FALSE)
|
|
|
|
if(CLAMPED_OFF)
|
|
if(!attached)
|
|
return
|
|
if(mode == OPERATING && internal_heat < MINIMUM_HEAT)
|
|
STOP_PROCESSING(SSobj, src)
|
|
internal_heat = 0
|
|
set_anchored(TRUE)
|
|
|
|
if(OPERATING)
|
|
if(!attached)
|
|
return
|
|
START_PROCESSING(SSobj, src)
|
|
set_anchored(TRUE)
|
|
|
|
mode = value
|
|
update_appearance()
|
|
set_light(0)
|
|
|
|
/obj/item/powersink/wrench_act(mob/living/user, obj/item/tool)
|
|
. = TRUE
|
|
if(mode == DISCONNECTED)
|
|
var/turf/T = loc
|
|
if(isturf(T) && T.underfloor_accessibility >= UNDERFLOOR_INTERACTABLE)
|
|
attached = locate() in T
|
|
if(!attached)
|
|
to_chat(user, span_warning("\The [src] must be placed over an exposed, powered cable node!"))
|
|
else
|
|
set_mode(CLAMPED_OFF)
|
|
user.visible_message( \
|
|
"[user] attaches \the [src] to the cable.", \
|
|
span_notice("You bolt \the [src] into the floor and connect it to the cable."),
|
|
span_hear("You hear some wires being connected to something."))
|
|
else
|
|
to_chat(user, span_warning("\The [src] must be placed over an exposed, powered cable node!"))
|
|
else
|
|
set_mode(DISCONNECTED)
|
|
user.visible_message( \
|
|
"[user] detaches \the [src] from the cable.", \
|
|
span_notice("You unbolt \the [src] from the floor and detach it from the cable."),
|
|
span_hear("You hear some wires being disconnected from something."))
|
|
|
|
/obj/item/powersink/screwdriver_act(mob/living/user, obj/item/tool)
|
|
user.visible_message( \
|
|
"[user] messes with \the [src] for a bit.", \
|
|
span_notice("You can't fit the screwdriver into \the [src]'s bolts! Try using a wrench."))
|
|
return TRUE
|
|
|
|
/obj/item/powersink/attack_paw(mob/user, list/modifiers)
|
|
return
|
|
|
|
/obj/item/powersink/attack_ai()
|
|
return
|
|
|
|
/obj/item/powersink/attack_hand(mob/user, list/modifiers)
|
|
. = ..()
|
|
if(.)
|
|
return
|
|
switch(mode)
|
|
if(DISCONNECTED)
|
|
..()
|
|
|
|
if(CLAMPED_OFF)
|
|
user.visible_message( \
|
|
"[user] activates \the [src]!", \
|
|
span_notice("You activate \the [src]."),
|
|
span_hear("You hear a click."))
|
|
message_admins("Power sink activated by [ADMIN_LOOKUPFLW(user)] at [ADMIN_VERBOSEJMP(src)]")
|
|
user.log_message("activated a powersink", LOG_GAME)
|
|
set_mode(OPERATING)
|
|
|
|
if(OPERATING)
|
|
user.visible_message( \
|
|
"[user] deactivates \the [src]!", \
|
|
span_notice("You deactivate \the [src]."),
|
|
span_hear("You hear a click."))
|
|
user.log_message("deactivated the powersink", LOG_GAME)
|
|
set_mode(CLAMPED_OFF)
|
|
|
|
/// Removes internal heat and shares it with the atmosphere.
|
|
/obj/item/powersink/proc/release_heat()
|
|
var/turf/our_turf = get_turf(src)
|
|
var/temp_to_give = internal_heat / FRACTION_TO_RELEASE
|
|
internal_heat -= temp_to_give
|
|
var/datum/gas_mixture/environment = our_turf.return_air()
|
|
var/delta_temperature = temp_to_give / environment.heat_capacity()
|
|
if(delta_temperature)
|
|
environment.temperature += delta_temperature
|
|
air_update_turf(FALSE, FALSE)
|
|
if(admins_warned && internal_heat < max_heat * 0.75)
|
|
admins_warned = FALSE
|
|
message_admins("Power sink at ([x],[y],[z] - <A HREF='?_src_=holder;[HrefToken()];adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>) has cooled down and will not explode.")
|
|
if(mode != OPERATING && internal_heat < MINIMUM_HEAT)
|
|
internal_heat = 0
|
|
STOP_PROCESSING(SSobj, src)
|
|
|
|
/// Drains power from the connected powernet, if any.
|
|
/obj/item/powersink/proc/drain_power()
|
|
var/datum/powernet/PN = attached.powernet
|
|
var/drained = 0
|
|
set_light(5)
|
|
|
|
// Drain as much as we can from the powernet.
|
|
drained = attached.newavail()
|
|
attached.add_delayedload(drained)
|
|
|
|
// If tried to drain more than available on powernet, now look for APCs and drain their cells
|
|
for(var/obj/machinery/power/terminal/T in PN.nodes)
|
|
if(istype(T.master, /obj/machinery/power/apc))
|
|
var/obj/machinery/power/apc/A = T.master
|
|
if(A.operating && A.cell)
|
|
A.cell.charge = max(0, A.cell.charge - 50)
|
|
drained += 50
|
|
if(A.charging == 2) // If the cell was full
|
|
A.charging = 1 // It's no longer full
|
|
internal_heat += drained
|
|
|
|
/obj/item/powersink/process()
|
|
if(!attached)
|
|
set_mode(DISCONNECTED)
|
|
|
|
release_heat()
|
|
|
|
if(mode != OPERATING)
|
|
return
|
|
|
|
drain_power()
|
|
|
|
if(internal_heat > max_heat * ALERT / 100)
|
|
if (!admins_warned)
|
|
admins_warned = TRUE
|
|
message_admins("Power sink at ([x],[y],[z] - <A HREF='?_src_=holder;[HrefToken()];adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>) has reached [ALERT]% of max heat. Explosion imminent.")
|
|
playsound(src, 'sound/effects/screech.ogg', 100, TRUE, TRUE)
|
|
|
|
if(internal_heat >= max_heat)
|
|
STOP_PROCESSING(SSobj, src)
|
|
explosion(src, devastation_range = 4, heavy_impact_range = 8, light_impact_range = 16, flash_range = 32)
|
|
qdel(src)
|
|
|
|
#undef DISCONNECTED
|
|
#undef CLAMPED_OFF
|
|
#undef OPERATING
|
|
#undef FRACTION_TO_RELEASE
|
|
#undef ALERT
|
|
#undef MINIMUM_HEAT
|