mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-22 03:27:05 +01:00
This converts the machine and mob processes to the SMC. Additionally, it adds the Atom subsystem, which handles all Initialize() calls in place of the old gameticker. Due to incompatibility with our atmospherics (FUCK OUR ATMOSPHERICS FOR FUCKING EVER JESUS CHRIST WHO THE FUCK MADE THIS PIECE OF GODDAMN SHIT) atmospherics machines do not use Initialize() as they should, instead opting for a custom atmos_init proc that the air controller handles.
458 lines
16 KiB
Plaintext
458 lines
16 KiB
Plaintext
//Baseline portable generator. Has all the default handling. Not intended to be used on it's own (since it generates unlimited power).
|
|
/obj/machinery/power/port_gen
|
|
name = "Placeholder Generator" //seriously, don't use this. It can't be anchored without VV magic.
|
|
desc = "A portable generator for emergency backup power"
|
|
icon = 'icons/obj/power.dmi'
|
|
icon_state = "portgen0_0"
|
|
density = 1
|
|
anchored = 0
|
|
use_power = 0
|
|
|
|
var/active = 0
|
|
var/power_gen = 5000
|
|
var/open = 0
|
|
var/recent_fault = 0
|
|
var/power_output = 1
|
|
var/base_icon = "portgen0"
|
|
|
|
/obj/machinery/power/port_gen/proc/IsBroken()
|
|
return (stat & (BROKEN|EMPED))
|
|
|
|
/obj/machinery/power/port_gen/proc/HasFuel() //Placeholder for fuel check.
|
|
return 1
|
|
|
|
/obj/machinery/power/port_gen/proc/UseFuel() //Placeholder for fuel use.
|
|
return
|
|
|
|
/obj/machinery/power/port_gen/proc/DropFuel()
|
|
return
|
|
|
|
/obj/machinery/power/port_gen/proc/handleInactive()
|
|
return
|
|
|
|
/obj/machinery/power/port_gen/update_icon()
|
|
icon_state = "[base_icon]_[active]"
|
|
|
|
/obj/machinery/power/port_gen/process()
|
|
if(active && HasFuel() && !IsBroken() && anchored && powernet)
|
|
add_avail(power_gen * power_output)
|
|
UseFuel()
|
|
else
|
|
active = 0
|
|
handleInactive()
|
|
update_icon()
|
|
|
|
/obj/machinery/power/powered()
|
|
return 1 //doesn't require an external power source
|
|
|
|
/obj/machinery/power/port_gen/attack_hand(mob/user as mob)
|
|
if(..())
|
|
return
|
|
if(!anchored)
|
|
return
|
|
|
|
/obj/machinery/power/port_gen/examine(mob/user)
|
|
if(!..(user,1 ))
|
|
return
|
|
if(active)
|
|
to_chat(usr, "<span class='notice'>The generator is on.</span>")
|
|
else
|
|
to_chat(usr, "<span class='notice'>The generator is off.</span>")
|
|
|
|
/obj/machinery/power/port_gen/emp_act(severity)
|
|
var/duration = 6000 //ten minutes
|
|
switch(severity)
|
|
if(1)
|
|
stat &= BROKEN
|
|
if(prob(75)) explode()
|
|
if(2)
|
|
if(prob(25)) stat &= BROKEN
|
|
if(prob(10)) explode()
|
|
if(3)
|
|
if(prob(10)) stat &= BROKEN
|
|
duration = 300
|
|
|
|
stat |= EMPED
|
|
if(duration)
|
|
spawn(duration)
|
|
stat &= ~EMPED
|
|
|
|
/obj/machinery/power/port_gen/proc/explode()
|
|
explosion(src.loc, -1, 3, 5, -1)
|
|
qdel(src)
|
|
|
|
#define TEMPERATURE_DIVISOR 40
|
|
#define TEMPERATURE_CHANGE_MAX 20
|
|
|
|
//A power generator that runs on solid plasma sheets.
|
|
/obj/machinery/power/port_gen/pacman
|
|
name = "\improper P.A.C.M.A.N.-type Portable Generator"
|
|
desc = "A power generator that runs on solid plasma sheets. Rated for 80 kW max safe output."
|
|
|
|
var/sheet_name = "Plasma Sheets"
|
|
var/sheet_path = /obj/item/stack/sheet/mineral/plasma
|
|
var/board_path = /obj/item/circuitboard/pacman
|
|
|
|
/*
|
|
These values were chosen so that the generator can run safely up to 80 kW
|
|
A full 50 plasma sheet stack should last 20 minutes at power_output = 4
|
|
temperature_gain and max_temperature are set so that the max safe power level is 4.
|
|
Setting to 5 or higher can only be done temporarily before the generator overheats.
|
|
*/
|
|
power_gen = 20000 //Watts output per power_output level
|
|
var/max_power_output = 5 //The maximum power setting without emagging.
|
|
var/max_safe_output = 4 // For UI use, maximal output that won't cause overheat.
|
|
var/time_per_sheet = 96 //fuel efficiency - how long 1 sheet lasts at power level 1
|
|
var/max_sheets = 100 //max capacity of the hopper
|
|
var/max_temperature = 300 //max temperature before overheating increases
|
|
var/temperature_gain = 50 //how much the temperature increases per power output level, in degrees per level
|
|
|
|
var/sheets = 0 //How many sheets of material are loaded in the generator
|
|
var/sheet_left = 0 //How much is left of the current sheet
|
|
var/temperature = 0 //The current temperature
|
|
var/overheating = 0 //if this gets high enough the generator explodes
|
|
|
|
/obj/machinery/power/port_gen/pacman/Initialize()
|
|
..()
|
|
if(anchored)
|
|
connect_to_network()
|
|
|
|
/obj/machinery/power/port_gen/pacman/New()
|
|
..()
|
|
component_parts = list()
|
|
component_parts += new /obj/item/stock_parts/matter_bin(null)
|
|
component_parts += new /obj/item/stock_parts/micro_laser(null)
|
|
component_parts += new /obj/item/stack/cable_coil(null, 1)
|
|
component_parts += new /obj/item/stack/cable_coil(null, 1)
|
|
component_parts += new /obj/item/stock_parts/capacitor(null)
|
|
component_parts += new board_path(null)
|
|
RefreshParts()
|
|
|
|
/obj/machinery/power/port_gen/pacman/upgraded/New()
|
|
..()
|
|
component_parts = list()
|
|
component_parts += new /obj/item/stock_parts/matter_bin/super(null)
|
|
component_parts += new /obj/item/stock_parts/micro_laser/ultra(null)
|
|
component_parts += new /obj/item/stack/cable_coil(null, 1)
|
|
component_parts += new /obj/item/stack/cable_coil(null, 1)
|
|
component_parts += new /obj/item/stock_parts/capacitor/super(null)
|
|
component_parts += new board_path(null)
|
|
RefreshParts()
|
|
|
|
/obj/machinery/power/port_gen/pacman/Destroy()
|
|
DropFuel()
|
|
return ..()
|
|
|
|
/obj/machinery/power/port_gen/pacman/RefreshParts()
|
|
var/temp_rating = 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/micro_laser) || istype(SP, /obj/item/stock_parts/capacitor))
|
|
temp_rating += SP.rating
|
|
|
|
power_gen = round(initial(power_gen) * (max(2, temp_rating) / 2))
|
|
|
|
/obj/machinery/power/port_gen/pacman/examine(mob/user)
|
|
..(user)
|
|
to_chat(user, "\The [src] appears to be producing [power_gen*power_output] W.")
|
|
to_chat(user, "There [sheets == 1 ? "is" : "are"] [sheets] sheet\s left in the hopper.")
|
|
if(IsBroken())
|
|
to_chat(user, "<span class='warning'>\The [src] seems to have broken down.</span>")
|
|
if(overheating)
|
|
to_chat(user, "<span class='danger'>\The [src] is overheating!</span>")
|
|
|
|
/obj/machinery/power/port_gen/pacman/HasFuel()
|
|
var/needed_sheets = power_output / time_per_sheet
|
|
if(sheets >= needed_sheets - sheet_left)
|
|
return 1
|
|
return 0
|
|
|
|
//Removes one stack's worth of material from the generator.
|
|
/obj/machinery/power/port_gen/pacman/DropFuel()
|
|
if(sheets)
|
|
var/obj/item/stack/sheet/mineral/S = new sheet_path(loc)
|
|
var/amount = min(sheets, S.max_amount)
|
|
S.amount = amount
|
|
sheets -= amount
|
|
|
|
/obj/machinery/power/port_gen/pacman/UseFuel()
|
|
|
|
//how much material are we using this iteration?
|
|
var/needed_sheets = power_output / time_per_sheet
|
|
|
|
//HasFuel() should guarantee us that there is enough fuel left, so no need to check that
|
|
//the only thing we need to worry about is if we are going to rollover to the next sheet
|
|
if(needed_sheets > sheet_left)
|
|
sheets--
|
|
sheet_left = (1 + sheet_left) - needed_sheets
|
|
else
|
|
sheet_left -= needed_sheets
|
|
|
|
//calculate the "target" temperature range
|
|
//This should probably depend on the external temperature somehow, but whatever.
|
|
var/lower_limit = 56 + power_output * temperature_gain
|
|
var/upper_limit = 76 + power_output * temperature_gain
|
|
|
|
/*
|
|
Hot or cold environments can affect the equilibrium temperature
|
|
The lower the pressure the less effect it has. I guess it cools using a radiator or something when in vacuum.
|
|
Gives traitors more opportunities to sabotage the generator or allows enterprising engineers to build additional
|
|
cooling in order to get more power out.
|
|
*/
|
|
var/datum/gas_mixture/environment = loc.return_air()
|
|
if(environment)
|
|
var/ratio = min(environment.return_pressure()/ONE_ATMOSPHERE, 1)
|
|
var/ambient = environment.temperature - T20C
|
|
lower_limit += ambient*ratio
|
|
upper_limit += ambient*ratio
|
|
|
|
var/average = (upper_limit + lower_limit)/2
|
|
|
|
//calculate the temperature increase
|
|
var/bias = 0
|
|
if(temperature < lower_limit)
|
|
bias = min(round((average - temperature)/TEMPERATURE_DIVISOR, 1), TEMPERATURE_CHANGE_MAX)
|
|
else if(temperature > upper_limit)
|
|
bias = max(round((temperature - average)/TEMPERATURE_DIVISOR, 1), -TEMPERATURE_CHANGE_MAX)
|
|
|
|
//limit temperature increase so that it cannot raise temperature above upper_limit,
|
|
//or if it is already above upper_limit, limit the increase to 0.
|
|
var/inc_limit = max(upper_limit - temperature, 0)
|
|
var/dec_limit = min(temperature - lower_limit, 0)
|
|
temperature += between(dec_limit, rand(-7 + bias, 7 + bias), inc_limit)
|
|
|
|
if(temperature > max_temperature)
|
|
overheat()
|
|
else if(overheating > 0)
|
|
overheating--
|
|
|
|
/obj/machinery/power/port_gen/pacman/handleInactive()
|
|
var/cooling_temperature = 20
|
|
var/datum/gas_mixture/environment = loc.return_air()
|
|
if(environment)
|
|
var/ratio = min(environment.return_pressure()/ONE_ATMOSPHERE, 1)
|
|
var/ambient = environment.temperature - T20C
|
|
cooling_temperature += ambient*ratio
|
|
|
|
if(temperature > cooling_temperature)
|
|
var/temp_loss = (temperature - cooling_temperature)/TEMPERATURE_DIVISOR
|
|
temp_loss = between(2, round(temp_loss, 1), TEMPERATURE_CHANGE_MAX)
|
|
temperature = max(temperature - temp_loss, cooling_temperature)
|
|
SSnanoui.update_uis(src)
|
|
|
|
if(overheating)
|
|
overheating--
|
|
|
|
/obj/machinery/power/port_gen/pacman/proc/overheat()
|
|
overheating++
|
|
if(overheating > 60)
|
|
explode()
|
|
|
|
/obj/machinery/power/port_gen/pacman/explode()
|
|
//Vapourize all the plasma
|
|
//When ground up in a grinder, 1 sheet produces 20 u of plasma -- Chemistry-Machinery.dm
|
|
//1 mol = 10 u? I dunno. 1 mol of carbon is definitely bigger than a pill
|
|
/*var/plasma = (sheets+sheet_left)*20
|
|
var/datum/gas_mixture/environment = loc.return_air()
|
|
if(environment)
|
|
environment.adjust_gas("plasma", plasma/10, temperature + T0C)*/
|
|
|
|
sheets = 0
|
|
sheet_left = 0
|
|
..()
|
|
|
|
/obj/machinery/power/port_gen/pacman/emag_act(var/remaining_charges, var/mob/user)
|
|
if(active && prob(25))
|
|
explode() //if they're foolish enough to emag while it's running
|
|
|
|
if(!emagged)
|
|
emagged = 1
|
|
return 1
|
|
|
|
/obj/machinery/power/port_gen/pacman/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
|
if(istype(O, sheet_path))
|
|
var/obj/item/stack/addstack = O
|
|
var/amount = min((max_sheets - sheets), addstack.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] sheet\s to the [src.name].</span>")
|
|
sheets += amount
|
|
addstack.use(amount)
|
|
SSnanoui.update_uis(src)
|
|
return
|
|
else if(!active)
|
|
if(istype(O, /obj/item/wrench))
|
|
|
|
if(!anchored)
|
|
connect_to_network()
|
|
to_chat(user, "<span class='notice'>You secure the generator to the floor.</span>")
|
|
else
|
|
disconnect_from_network()
|
|
to_chat(user, "<span class='notice'>You unsecure the generator from the floor.</span>")
|
|
|
|
playsound(src.loc, O.usesound, 50, 1)
|
|
anchored = !anchored
|
|
|
|
else if(istype(O, /obj/item/screwdriver))
|
|
panel_open = !panel_open
|
|
playsound(src.loc, O.usesound, 50, 1)
|
|
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>")
|
|
else if(istype(O, /obj/item/storage/part_replacer) && panel_open)
|
|
exchange_parts(user, O)
|
|
return
|
|
else if(istype(O, /obj/item/crowbar) && panel_open)
|
|
default_deconstruction_crowbar(O)
|
|
|
|
/obj/machinery/power/port_gen/pacman/attack_hand(mob/user as mob)
|
|
..()
|
|
if(!anchored)
|
|
return
|
|
ui_interact(user)
|
|
|
|
/obj/machinery/power/port_gen/pacman/attack_ai(var/mob/user as mob)
|
|
src.add_hiddenprint(user)
|
|
return src.attack_hand(user)
|
|
|
|
/obj/machinery/power/port_gen/pacman/attack_ghost(var/mob/user)
|
|
return src.attack_hand(user)
|
|
|
|
/obj/machinery/power/port_gen/pacman/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
|
if(IsBroken())
|
|
return
|
|
|
|
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
|
if(!ui)
|
|
ui = new(user, src, ui_key, "pacman.tmpl", src.name, 500, 560)
|
|
ui.open()
|
|
ui.set_auto_update(1)
|
|
|
|
/obj/machinery/power/port_gen/pacman/ui_data(mob/user, ui_key = "main", datum/topic_state/state = default_state)
|
|
var/data[0]
|
|
|
|
data["active"] = active
|
|
if(istype(user, /mob/living/silicon/ai))
|
|
data["is_ai"] = 1
|
|
else if(istype(user, /mob/living/silicon/robot) && !Adjacent(user))
|
|
data["is_ai"] = 1
|
|
else
|
|
data["is_ai"] = 0
|
|
|
|
data["output_set"] = power_output
|
|
data["output_max"] = max_power_output
|
|
data["output_safe"] = max_safe_output
|
|
data["output_watts"] = power_output * power_gen
|
|
data["temperature_current"] = src.temperature
|
|
data["temperature_max"] = src.max_temperature
|
|
data["temperature_overheat"] = overheating
|
|
// 1 sheet = 1000cm3?
|
|
data["fuel_stored"] = round((sheets * 1000) + (sheet_left * 1000))
|
|
data["fuel_capacity"] = round(max_sheets * 1000, 0.1)
|
|
data["fuel_usage"] = active ? round((power_output / time_per_sheet) * 1000) : 0
|
|
data["fuel_type"] = sheet_name
|
|
|
|
return data
|
|
|
|
/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() && !IsBroken())
|
|
active = 1
|
|
update_icon()
|
|
if(href_list["action"] == "disable")
|
|
if(active)
|
|
active = 0
|
|
update_icon()
|
|
if(href_list["action"] == "eject")
|
|
if(!active)
|
|
DropFuel()
|
|
if(href_list["action"] == "lower_power")
|
|
if(power_output > 1)
|
|
power_output--
|
|
if(href_list["action"] == "higher_power")
|
|
if(power_output < max_power_output || (emagged && power_output < round(max_power_output*2.5)))
|
|
power_output++
|
|
|
|
SSnanoui.update_uis(src)
|
|
|
|
/obj/machinery/power/port_gen/pacman/super
|
|
name = "S.U.P.E.R.P.A.C.M.A.N.-type Portable Generator"
|
|
desc = "A power generator that utilizes uranium sheets as fuel. Can run for much longer than the standard PACMAN type generators. Rated for 80 kW max safe output."
|
|
icon_state = "portgen1_0"
|
|
base_icon = "portgen1"
|
|
sheet_path = /obj/item/stack/sheet/mineral/uranium
|
|
sheet_name = "Uranium Sheets"
|
|
time_per_sheet = 576 //same power output, but a 50 sheet stack will last 2 hours at max safe power
|
|
board_path = /obj/item/circuitboard/pacman/super
|
|
|
|
/obj/machinery/power/port_gen/pacman/super/upgraded/New()
|
|
..()
|
|
component_parts = list()
|
|
component_parts += new /obj/item/stock_parts/matter_bin/super(null)
|
|
component_parts += new /obj/item/stock_parts/micro_laser/ultra(null)
|
|
component_parts += new /obj/item/stack/cable_coil(null, 1)
|
|
component_parts += new /obj/item/stack/cable_coil(null, 1)
|
|
component_parts += new /obj/item/stock_parts/capacitor/super(null)
|
|
component_parts += new board_path(null)
|
|
RefreshParts()
|
|
|
|
/obj/machinery/power/port_gen/pacman/super/UseFuel()
|
|
//produces a tiny amount of radiation when in use
|
|
if(prob(2*power_output))
|
|
for(var/mob/living/L in range(src, 5))
|
|
L.apply_effect(1, IRRADIATE) //should amount to ~5 rads per minute at max safe power
|
|
..()
|
|
|
|
/obj/machinery/power/port_gen/pacman/super/explode()
|
|
//a nice burst of radiation
|
|
var/rads = 50 + (sheets + sheet_left)*1.5
|
|
for(var/mob/living/L in range(src, 10))
|
|
//should really fall with the square of the distance, but that makes the rads value drop too fast
|
|
//I dunno, maybe physics works different when you live in 2D -- SM radiation also works like this, apparently
|
|
L.apply_effect(max(20, round(rads/get_dist(L,src))), IRRADIATE)
|
|
|
|
explosion(src.loc, 3, 3, 5, 3)
|
|
qdel(src)
|
|
|
|
/obj/machinery/power/port_gen/pacman/mrs
|
|
name = "M.R.S.P.A.C.M.A.N.-type Portable Generator"
|
|
desc = "An advanced power generator that runs on diamonds. Rated for 200 kW maximum safe output!"
|
|
icon_state = "portgen2_0"
|
|
base_icon = "portgen2"
|
|
sheet_path = /obj/item/stack/sheet/mineral/diamond
|
|
sheet_name = "Diamond Sheets"
|
|
|
|
//I don't think tritium has any other use, so we might as well make this rewarding for players
|
|
//max safe power output (power level = 8) is 200 kW and lasts for 1 hour - 3 or 4 of these could power the station
|
|
power_gen = 25000 //watts
|
|
max_power_output = 10
|
|
max_safe_output = 8
|
|
time_per_sheet = 576
|
|
max_temperature = 800
|
|
temperature_gain = 90
|
|
board_path = /obj/item/circuitboard/pacman/mrs
|
|
|
|
/obj/machinery/power/port_gen/pacman/mrs/upgraded/New()
|
|
..()
|
|
component_parts = list()
|
|
component_parts += new /obj/item/stock_parts/matter_bin/super(null)
|
|
component_parts += new /obj/item/stock_parts/micro_laser/ultra(null)
|
|
component_parts += new /obj/item/stack/cable_coil(null, 1)
|
|
component_parts += new /obj/item/stack/cable_coil(null, 1)
|
|
component_parts += new /obj/item/stock_parts/capacitor/super(null)
|
|
component_parts += new board_path(null)
|
|
RefreshParts()
|
|
|
|
/obj/machinery/power/port_gen/pacman/mrs/explode()
|
|
//no special effects, but the explosion is pretty big (same as a supermatter shard).
|
|
explosion(src.loc, 3, 6, 12, 16, 1)
|
|
qdel(src)
|