mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-07-11 07:58:57 +01:00
4ecb0bc21c
Repaths obj/machinery to obj/structure/machinery. **Note for reviewers:** the only meaningful changed code exists within **code/game/objects/structures.dm** and **code/game/objects/structures/_machinery.dm**, largely concerning damage procs. With the exception of moving airlock defines to their own file, ALL OTHER CHANGES ARE STRICTLY PATH CHANGES. Objects, _categorically_, are largely divided between those you can hold in your hand/inventory and those you can't. Machinery objects are already subtypes of Structures behaviorally, this PR just makes their pathing reflect that, and allows for future work (tool actions, more health/destruction functionality) to be developed without unnecessary code duplication. I have tested this PR by loading up the Horizon and dismantling various machines and structures with tools, shooting guns of various types throughout the ship, and detonating a bunch of explosions throughout the ship.
267 lines
9.0 KiB
Plaintext
267 lines
9.0 KiB
Plaintext
/// A global list of all radiation collectors.
|
|
GLOBAL_LIST_INIT_TYPED(rad_collectors, /obj/structure/machinery/power/rad_collector, list())
|
|
|
|
/obj/structure/machinery/power/rad_collector
|
|
name = "radiation collector array"
|
|
desc = "A device which uses radiation and phoron to produce power."
|
|
icon = 'icons/obj/machinery/rad_collector.dmi'
|
|
icon_state = "ca"
|
|
anchored = FALSE
|
|
density = TRUE
|
|
req_access = list(ACCESS_ENGINE_EQUIP)
|
|
/// The tank of phoron currently attached to the radiation collector
|
|
var/obj/item/tank/phoron/loaded_tank = null
|
|
|
|
maxhealth = OBJECT_HEALTH_LOW
|
|
/// The maximum safe temperature that the radiation collector can handle
|
|
var/max_safe_temp = 1000 + T0C
|
|
/// A boolean determining whether the collector has melted or not.
|
|
var/melted = FALSE
|
|
|
|
/// Internal variable storing last power generation amount
|
|
var/last_power = 0
|
|
/// Internal variable storing last power generation amount. Duplicate variable to account for the SM being processed first
|
|
var/last_power_new = 0
|
|
/// Whether the radiation collector is active or not.
|
|
var/active = FALSE
|
|
/// Whether the radiation collector's controls are locked or not.
|
|
var/locked = FALSE
|
|
/// Determines the ratio of default draining of phoron while radiation collector is active
|
|
var/drainratio = 1
|
|
|
|
/// Internal variable storing last radiation amount measured
|
|
var/last_rads
|
|
/// Radiation collector will reach max power output at this value, and break at twice this value
|
|
var/max_rads = 250
|
|
/// Maximum power output for this radiation collector.
|
|
var/max_power = 5e5
|
|
/// Pulse coefficient, for multiplying power output by radiation input
|
|
var/pulse_coeff = 20
|
|
/// Internal variable storing last time an alert message was outputted
|
|
var/end_time = 0
|
|
/// How long to wait between alert messages, if radiation input exceeds safe levels
|
|
var/alert_delay = 10 SECONDS
|
|
|
|
/obj/structure/machinery/power/rad_collector/feedback_hints(mob/user, distance, is_adjacent)
|
|
. += ..()
|
|
if (..(user, 3))
|
|
var/last_power_kw = round(last_power / 1000, 0.1)
|
|
. += "The meter indicates that \the [src] is collecting [last_power_kw] kW."
|
|
|
|
/obj/structure/machinery/power/rad_collector/Initialize()
|
|
. = ..()
|
|
GLOB.rad_collectors += src
|
|
|
|
/obj/structure/machinery/power/rad_collector/Destroy()
|
|
GLOB.rad_collectors -= src
|
|
return ..()
|
|
|
|
/obj/structure/machinery/power/rad_collector/process(seconds_per_tick)
|
|
if((stat && BROKEN) || melted)
|
|
return
|
|
var/turf/T = get_turf(src)
|
|
if(T)
|
|
var/datum/gas_mixture/our_turfs_air = T.return_air()
|
|
if(our_turfs_air.temperature > max_safe_temp)
|
|
health -= ((our_turfs_air.temperature - max_safe_temp) / 10) * seconds_per_tick
|
|
if(health <= 0)
|
|
collector_break()
|
|
|
|
//so that we don't zero out the meter if the SM is processed first.
|
|
last_power = last_power_new
|
|
last_power_new = 0
|
|
last_rads = SSradiation.get_rads_at_turf(get_turf(src))
|
|
if(loaded_tank && active)
|
|
if(last_rads > max_rads*2)
|
|
collector_break()
|
|
if(last_rads)
|
|
if(last_rads > max_rads)
|
|
if(world.time > end_time)
|
|
end_time = world.time + alert_delay
|
|
visible_message("[icon2html(src, viewers(get_turf(src)))] \the [src] beeps loudly as the radiation reaches dangerous levels, indicating imminent damage.")
|
|
playsound(src, 'sound/effects/screech.ogg', 100, 1, 1)
|
|
receive_pulse(12.5*(last_rads/max_rads)/(0.3+(last_rads/max_rads)) * seconds_per_tick)
|
|
|
|
if(loaded_tank)
|
|
if(loaded_tank.air_contents.gas[GAS_PHORON] == 0)
|
|
investigate_log("[SPAN_COLOR("red", "out of fuel")].","singulo")
|
|
eject()
|
|
else
|
|
loaded_tank.air_contents.adjust_gas(GAS_PHORON, (-0.01*drainratio*min(last_rads,max_rads)/max_rads) * seconds_per_tick) //fuel cost increases linearly with incoming radiation
|
|
|
|
|
|
/obj/structure/machinery/power/rad_collector/CanUseTopic(mob/user)
|
|
if(!anchored)
|
|
return STATUS_CLOSE
|
|
return ..()
|
|
|
|
|
|
/obj/structure/machinery/power/rad_collector/attack_hand(mob/user)
|
|
if(!CanInteract(user, GLOB.physical_state))
|
|
return FALSE
|
|
. = TRUE
|
|
if((stat & BROKEN) || melted)
|
|
USE_FEEDBACK_FAILURE("The [src] is completely destroyed!")
|
|
if(!src.locked)
|
|
toggle_power()
|
|
user.visible_message("[user.name] turns the [src.name] [active? "on":"off"].", \
|
|
"You turn the [src.name] [active? "on":"off"].")
|
|
investigate_log("turned [active ? SPAN_COLOR("green", "on") : SPAN_COLOR("red", "off")] by [user.key]. [loaded_tank ? "Fuel: [round(loaded_tank.air_contents.gas[GAS_PHORON]/0.29)]%" : SPAN_COLOR("red", "It is empty")].","singulo")
|
|
else
|
|
USE_FEEDBACK_FAILURE("The controls are locked!")
|
|
..()
|
|
|
|
/obj/structure/machinery/power/rad_collector/attackby(obj/item/attacking_item, mob/user)
|
|
if(istype(attacking_item, /obj/item/tank/phoron))
|
|
if(!anchored)
|
|
USE_FEEDBACK_FAILURE("The [src] needs to be secured to the floor first.")
|
|
return TRUE
|
|
if(loaded_tank)
|
|
USE_FEEDBACK_FAILURE("There's already a phoron tank loaded.")
|
|
return TRUE
|
|
if(!user.unEquip(attacking_item, src))
|
|
return TRUE
|
|
loaded_tank = attacking_item
|
|
attacking_item.forceMove(src)
|
|
to_chat(user, SPAN_NOTICE("You slot [attacking_item] into [src] and tighten the connecting valve."))
|
|
update_icon()
|
|
return TRUE
|
|
|
|
if(attacking_item.tool_behaviour == TOOL_CROWBAR)
|
|
if(loaded_tank && !locked)
|
|
to_chat(user, SPAN_NOTICE("You detach and remove \the [loaded_tank.name]."))
|
|
eject(user)
|
|
return TRUE
|
|
|
|
if(attacking_item.tool_behaviour == TOOL_WRENCH)
|
|
if(loaded_tank)
|
|
USE_FEEDBACK_FAILURE("Remove the phoron tank first.")
|
|
return TRUE
|
|
for(var/obj/structure/machinery/power/rad_collector/R in get_turf(src))
|
|
if(R != src)
|
|
USE_FEEDBACK_FAILURE("You cannot install more than one collector on the same spot.")
|
|
return TRUE
|
|
playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1)
|
|
src.anchored = !src.anchored
|
|
user.visible_message("[user.name] [anchored? "secures":"unsecures"] the [src.name].", \
|
|
"You [anchored? "secure":"undo"] the external bolts.", \
|
|
"You hear a ratchet")
|
|
if(anchored && !(stat & BROKEN))
|
|
connect_to_network()
|
|
else
|
|
disconnect_from_network()
|
|
return TRUE
|
|
|
|
if(istype(attacking_item, /obj/item/card/id)||istype(attacking_item, /obj/item/modular_computer))
|
|
if (allowed(user))
|
|
if(active)
|
|
locked = !locked
|
|
to_chat(user, "The controls are now [locked ? "locked." : "unlocked."]")
|
|
else
|
|
locked = FALSE //just in case it somehow gets locked while the collector is active
|
|
USE_FEEDBACK_FAILURE("The controls can only be locked when the [src] is active.")
|
|
else
|
|
to_chat(user, SPAN_ALERT("Access denied!"))
|
|
return TRUE
|
|
|
|
return ..()
|
|
|
|
/// Handles dealing with a breaking radiation collector
|
|
/obj/structure/machinery/power/rad_collector/proc/collector_break()
|
|
if(loaded_tank && loaded_tank.air_contents)
|
|
var/turf/T = get_turf(src)
|
|
if(T)
|
|
T.assume_air(loaded_tank.air_contents)
|
|
audible_message(SPAN_DANGER("\The [loaded_tank.name] detonates, sending shrapnel flying!"))
|
|
explosion(T, -1, -1, 0)
|
|
QDEL_NULL(loaded_tank)
|
|
disconnect_from_network()
|
|
stat |= BROKEN
|
|
melted = TRUE
|
|
anchored = FALSE
|
|
active = FALSE
|
|
desc += " This one is destroyed beyond repair."
|
|
update_icon()
|
|
|
|
/obj/structure/machinery/power/rad_collector/return_air()
|
|
if(loaded_tank)
|
|
return loaded_tank.return_air()
|
|
|
|
/obj/structure/machinery/power/rad_collector/ex_act(severity)
|
|
switch(severity)
|
|
if(2, 3)
|
|
eject()
|
|
return ..()
|
|
|
|
/**
|
|
* Ejects the stored phoron tank. If user is not defined or user is an invalid target, will eject onto the collector's position.
|
|
*
|
|
* Arguments:
|
|
* - user: Optional. If defined, will eject the tank into the user's hands, if possible.
|
|
*/
|
|
/obj/structure/machinery/power/rad_collector/proc/eject(mob/user)
|
|
locked = 0
|
|
var/obj/item/tank/phoron/tank = src.loaded_tank
|
|
if(!tank)
|
|
return
|
|
if(user)
|
|
user.put_in_hands(tank, TRUE)
|
|
else
|
|
tank.dropInto(loc)
|
|
tank.reset_plane_and_layer()
|
|
src.loaded_tank = null
|
|
if(active)
|
|
toggle_power()
|
|
else
|
|
update_icon()
|
|
|
|
/**
|
|
* Handles the generation of power for the radiation collector
|
|
*
|
|
* Arguments:
|
|
* - pulse_strength: The strength of the pulse to calculate into power output
|
|
*/
|
|
/obj/structure/machinery/power/rad_collector/proc/receive_pulse(pulse_strength)
|
|
if(loaded_tank && active)
|
|
var/power_produced = 0
|
|
power_produced = min(100*loaded_tank.air_contents.gas[GAS_PHORON]*pulse_strength*pulse_coeff,max_power)
|
|
ADD_TO_POWERNET(src, power_produced)
|
|
last_power_new = power_produced
|
|
return
|
|
return
|
|
|
|
|
|
/obj/structure/machinery/power/rad_collector/update_icon()
|
|
if(melted)
|
|
icon_state = "ca_melt"
|
|
else if(active)
|
|
icon_state = "ca_on"
|
|
else
|
|
icon_state = "ca"
|
|
|
|
ClearOverlays()
|
|
underlays.Cut()
|
|
|
|
if(loaded_tank)
|
|
AddOverlays(image(icon, "ptank"))
|
|
AddOverlays(emissive_appearance(icon, "ca_filling"))
|
|
underlays += image(icon, "ca_filling")
|
|
underlays += image(icon, "ca_inside")
|
|
if(!operable())
|
|
return
|
|
if(active)
|
|
var/rad_power = round(min(100 * last_rads / max_rads, 100), 20)
|
|
AddOverlays(emissive_appearance(icon, "rads_[rad_power]"))
|
|
AddOverlays(image(icon, "rads_[rad_power]"))
|
|
AddOverlays(emissive_appearance(icon, "on"))
|
|
AddOverlays(image(icon, "on"))
|
|
|
|
|
|
/obj/structure/machinery/power/rad_collector/toggle_power()
|
|
active = !active
|
|
if(active)
|
|
flick("ca_active", src)
|
|
else
|
|
flick("ca_deactive", src)
|
|
update_icon()
|