mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-09 16:12:17 +00:00
425 lines
14 KiB
Plaintext
425 lines
14 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_vr.dmi' //VOREStation Edit
|
|
icon_state = "portgen0" //VOREStation Edit
|
|
density = TRUE
|
|
anchored = FALSE
|
|
use_power = USE_POWER_OFF
|
|
interact_offline = TRUE
|
|
|
|
var/active = 0
|
|
var/power_gen = 5000
|
|
var/recent_fault = 0
|
|
var/power_output = 1
|
|
|
|
/obj/machinery/power/port_gen/proc/IsBroken()
|
|
return (stat & (BROKEN|EMPED))
|
|
|
|
/obj/machinery/power/port_gen/proc/HasFuel() //Placeholder for fuel check.
|
|
return 1
|
|
|
|
/obj/machinery/power/port_gen/proc/UseFuel() //Placeholder for fuel use.
|
|
return
|
|
|
|
/obj/machinery/power/port_gen/proc/DropFuel()
|
|
return
|
|
|
|
/obj/machinery/power/port_gen/proc/handleInactive()
|
|
return
|
|
|
|
/obj/machinery/power/port_gen/proc/TogglePower()
|
|
if(active)
|
|
active = FALSE
|
|
update_icon()
|
|
// soundloop.stop()
|
|
else if(HasFuel())
|
|
active = TRUE
|
|
update_icon()
|
|
// soundloop.start()
|
|
|
|
/obj/machinery/power/port_gen/process()
|
|
if(active && HasFuel() && !IsBroken() && anchored && powernet)
|
|
add_avail(power_gen * power_output)
|
|
UseFuel()
|
|
else
|
|
active = FALSE
|
|
update_icon()
|
|
handleInactive()
|
|
|
|
/obj/machinery/power/port_gen/update_icon()
|
|
if(active)
|
|
icon_state = "[initial(icon_state)]on"
|
|
else
|
|
icon_state = initial(icon_state)
|
|
|
|
/obj/machinery/power/powered()
|
|
return 1 //doesn't require an external power source
|
|
|
|
/obj/machinery/power/port_gen/attack_hand(mob/user as mob)
|
|
if(..())
|
|
return
|
|
if(!anchored)
|
|
return
|
|
|
|
/obj/machinery/power/port_gen/examine(mob/user)
|
|
. = ..()
|
|
if(Adjacent(user)) //It literally has a light on the sprite, are you sure this is necessary?
|
|
if(active)
|
|
. += span_notice("The generator is on.")
|
|
else
|
|
. += span_notice("The generator is off.")
|
|
|
|
/obj/machinery/power/port_gen/emp_act(severity)
|
|
var/duration = 6000 //ten minutes
|
|
switch(severity)
|
|
if(1)
|
|
stat &= BROKEN
|
|
if(prob(75)) explode()
|
|
if(2)
|
|
if(prob(50)) stat &= BROKEN
|
|
if(prob(10)) explode()
|
|
if(3)
|
|
if(prob(25)) stat &= BROKEN
|
|
duration = 300
|
|
if(4)
|
|
if(prob(10)) stat &= BROKEN
|
|
duration = 300
|
|
|
|
stat |= EMPED
|
|
if(duration)
|
|
spawn(duration)
|
|
stat &= ~EMPED
|
|
|
|
/obj/machinery/power/port_gen/proc/explode()
|
|
explosion(src.loc, -1, 3, 5, -1)
|
|
qdel(src)
|
|
|
|
#define TEMPERATURE_DIVISOR 40
|
|
#define TEMPERATURE_CHANGE_MAX 20
|
|
|
|
//A power generator that runs on solid plasma sheets.
|
|
/obj/machinery/power/port_gen/pacman
|
|
name = "\improper P.A.C.M.A.N.-type Portable Generator"
|
|
desc = "A power generator that runs on solid phoron sheets. Rated for 80 kW max safe output."
|
|
circuit = /obj/item/circuitboard/pacman
|
|
var/sheet_name = "Phoron Sheets"
|
|
var/sheet_path = /obj/item/stack/material/phoron
|
|
|
|
/*
|
|
These values were chosen so that the generator can run safely up to 80 kW
|
|
A full 50 phoron sheet stack should last 20 minutes at power_output = 4
|
|
temperature_gain and max_temperature are set so that the max safe power level is 4.
|
|
Setting to 5 or higher can only be done temporarily before the generator overheats.
|
|
*/
|
|
power_gen = 20000 //Watts output per power_output level
|
|
var/max_power_output = 5 //The maximum power setting without emagging.
|
|
var/max_safe_output = 4 // For UI use, maximal output that won't cause overheat.
|
|
var/time_per_sheet = 96 //fuel efficiency - how long 1 sheet lasts at power level 1
|
|
var/max_sheets = 100 //max capacity of the hopper
|
|
var/max_temperature = 300 //max temperature before overheating increases
|
|
var/temperature_gain = 50 //how much the temperature increases per power output level, in degrees per level
|
|
|
|
var/sheets = 0 //How many sheets of material are loaded in the generator
|
|
var/sheet_left = 0 //How much is left of the current sheet
|
|
var/temperature = 0 //The current temperature
|
|
var/overheating = 0 //if this gets high enough the generator explodes
|
|
|
|
/obj/machinery/power/port_gen/pacman/Initialize(mapload)
|
|
. = ..()
|
|
default_apply_parts()
|
|
if(anchored)
|
|
connect_to_network()
|
|
|
|
/obj/machinery/power/port_gen/pacman/Destroy()
|
|
DropFuel()
|
|
return ..()
|
|
|
|
/obj/machinery/power/port_gen/pacman/dismantle()
|
|
while( sheets > 0 )
|
|
DropFuel()
|
|
return ..()
|
|
|
|
/obj/machinery/power/port_gen/pacman/RefreshParts()
|
|
var/temp_rating = 0
|
|
for(var/obj/item/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)
|
|
. = ..()
|
|
. += "It appears to be producing [power_gen*power_output] W."
|
|
. += "There [sheets == 1 ? "is" : "are"] [sheets] sheet\s left in the hopper."
|
|
if(IsBroken())
|
|
. += span_warning("It seems to have broken down.")
|
|
if(overheating)
|
|
. += span_danger("It is overheating!")
|
|
|
|
/obj/machinery/power/port_gen/pacman/HasFuel()
|
|
var/needed_sheets = power_output / time_per_sheet
|
|
if(sheets >= needed_sheets - sheet_left)
|
|
return 1
|
|
return 0
|
|
|
|
//Removes one stack's worth of material from the generator.
|
|
/obj/machinery/power/port_gen/pacman/DropFuel()
|
|
if(sheets)
|
|
var/obj/item/stack/material/S = new sheet_path(loc, sheets)
|
|
sheets -= S.get_amount()
|
|
|
|
/obj/machinery/power/port_gen/pacman/UseFuel()
|
|
|
|
//how much material are we using this iteration?
|
|
var/needed_sheets = power_output / time_per_sheet
|
|
|
|
//HasFuel() should guarantee us that there is enough fuel left, so no need to check that
|
|
//the only thing we need to worry about is if we are going to rollover to the next sheet
|
|
if (needed_sheets > sheet_left)
|
|
sheets--
|
|
sheet_left = (1 + sheet_left) - needed_sheets
|
|
else
|
|
sheet_left -= needed_sheets
|
|
|
|
//calculate the "target" temperature range
|
|
//This should probably depend on the external temperature somehow, but whatever.
|
|
var/lower_limit = 56 + power_output * temperature_gain
|
|
var/upper_limit = 76 + power_output * temperature_gain
|
|
|
|
/*
|
|
Hot or cold environments can affect the equilibrium temperature
|
|
The lower the pressure the less effect it has. I guess it cools using a radiator or something when in vacuum.
|
|
Gives traitors more opportunities to sabotage the generator or allows enterprising engineers to build additional
|
|
cooling in order to get more power out.
|
|
*/
|
|
var/datum/gas_mixture/environment = loc.return_air()
|
|
if (environment)
|
|
var/ratio = min(environment.return_pressure()/ONE_ATMOSPHERE, 1)
|
|
var/ambient = environment.temperature - T20C
|
|
lower_limit += ambient*ratio
|
|
upper_limit += ambient*ratio
|
|
|
|
var/average = (upper_limit + lower_limit)/2
|
|
|
|
//calculate the temperature increase
|
|
var/bias = 0
|
|
if (temperature < lower_limit)
|
|
bias = min(round((average - temperature)/TEMPERATURE_DIVISOR, 1), TEMPERATURE_CHANGE_MAX)
|
|
else if (temperature > upper_limit)
|
|
bias = max(round((temperature - average)/TEMPERATURE_DIVISOR, 1), -TEMPERATURE_CHANGE_MAX)
|
|
|
|
//limit temperature increase so that it cannot raise temperature above upper_limit,
|
|
//or if it is already above upper_limit, limit the increase to 0.
|
|
var/inc_limit = max(upper_limit - temperature, 0)
|
|
var/dec_limit = min(temperature - lower_limit, 0)
|
|
temperature += between(dec_limit, rand(-7 + bias, 7 + bias), inc_limit)
|
|
|
|
if (temperature > max_temperature)
|
|
overheat()
|
|
else if (overheating > 0)
|
|
overheating--
|
|
update_icon() //Port RS PR #484
|
|
|
|
/obj/machinery/power/port_gen/pacman/handleInactive()
|
|
var/cooling_temperature = 20
|
|
var/datum/gas_mixture/environment = loc.return_air()
|
|
if(environment)
|
|
var/ratio = min(environment.return_pressure()/ONE_ATMOSPHERE, 1)
|
|
var/ambient = environment.temperature - T20C
|
|
cooling_temperature += ambient*ratio
|
|
|
|
if(temperature > cooling_temperature)
|
|
var/temp_loss = (temperature - cooling_temperature)/TEMPERATURE_DIVISOR
|
|
temp_loss = between(2, round(temp_loss, 1), TEMPERATURE_CHANGE_MAX)
|
|
temperature = max(temperature - temp_loss, cooling_temperature)
|
|
updateDialog()
|
|
|
|
if(overheating)
|
|
overheating--
|
|
update_icon() //Port RS PR #484
|
|
|
|
/obj/machinery/power/port_gen/pacman/proc/overheat()
|
|
overheating++
|
|
if (overheating > 60)
|
|
explode()
|
|
|
|
/obj/machinery/power/port_gen/pacman/explode()
|
|
//Vapourize all the phoron
|
|
//When ground up in a grinder, 1 sheet produces 20 u of phoron -- Chemistry-Machinery.dm
|
|
//1 mol = 10 u? I dunno. 1 mol of carbon is definitely bigger than a pill
|
|
var/phoron = (sheets+sheet_left)*20
|
|
var/datum/gas_mixture/environment = loc.return_air()
|
|
if (environment)
|
|
environment.adjust_gas_temp(GAS_PHORON, phoron/10, temperature + T0C)
|
|
|
|
sheets = 0
|
|
sheet_left = 0
|
|
..()
|
|
|
|
/obj/machinery/power/port_gen/pacman/emag_act(var/remaining_charges, var/mob/user)
|
|
if (active && prob(25))
|
|
explode() //if they're foolish enough to emag while it's running
|
|
|
|
if (!emagged)
|
|
emagged = 1
|
|
return 1
|
|
|
|
/obj/machinery/power/port_gen/pacman/attackby(var/obj/item/O, var/mob/user)
|
|
if(istype(O, sheet_path))
|
|
var/obj/item/stack/addstack = O
|
|
var/amount = min((max_sheets - sheets), addstack.get_amount())
|
|
if(amount < 1)
|
|
to_chat(user, span_warning("The [src.name] is full!"))
|
|
return
|
|
to_chat(user, span_notice("You add [amount] sheet\s to the [src.name]."))
|
|
sheets += amount
|
|
addstack.use(amount)
|
|
return
|
|
else if(!active)
|
|
if(O.has_tool_quality(TOOL_WRENCH))
|
|
if(!anchored)
|
|
connect_to_network()
|
|
to_chat(user, span_notice("You secure the generator to the floor."))
|
|
else
|
|
disconnect_from_network()
|
|
to_chat(user, span_notice("You unsecure the generator from the floor."))
|
|
playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
|
|
anchored = !anchored
|
|
return
|
|
else if(default_deconstruction_screwdriver(user, O))
|
|
return
|
|
else if(default_deconstruction_crowbar(user, O))
|
|
return
|
|
else if(default_part_replacement(user, O))
|
|
return
|
|
return ..()
|
|
|
|
/obj/machinery/power/port_gen/pacman/attack_hand(mob/user)
|
|
..()
|
|
if (!anchored)
|
|
return
|
|
tgui_interact(user)
|
|
|
|
/obj/machinery/power/port_gen/pacman/attack_ai(mob/user as mob)
|
|
tgui_interact(user)
|
|
|
|
/obj/machinery/power/port_gen/tgui_status(mob/user, datum/tgui_state/state)
|
|
if(IsBroken())
|
|
return STATUS_CLOSE
|
|
return ..()
|
|
|
|
/obj/machinery/power/port_gen/pacman/tgui_interact(mob/user, datum/tgui/ui)
|
|
ui = SStgui.try_update_ui(user, src, ui)
|
|
if(!ui)
|
|
ui = new(user, src, "PortableGenerator", name)
|
|
ui.open()
|
|
|
|
/obj/machinery/power/port_gen/pacman/tgui_data(mob/user)
|
|
var/list/data = list()
|
|
|
|
data["active"] = active
|
|
|
|
if(isAI(user))
|
|
data["is_ai"] = TRUE
|
|
else if(isrobot(user) && !Adjacent(user))
|
|
data["is_ai"] = TRUE
|
|
else
|
|
data["is_ai"] = FALSE
|
|
|
|
data["sheet_name"] = capitalize(sheet_name)
|
|
data["fuel_stored"] = round((sheets * 1000) + (sheet_left * 1000))
|
|
data["fuel_capacity"] = round(max_sheets * 1000, 0.1)
|
|
data["fuel_usage"] = active ? round((power_output / time_per_sheet) * 1000) : 0
|
|
|
|
data["anchored"] = anchored
|
|
data["connected"] = (powernet == null ? 0 : 1)
|
|
data["ready_to_boot"] = anchored && HasFuel()
|
|
data["power_generated"] = DisplayPower(power_gen)
|
|
data["power_output"] = DisplayPower(power_gen * power_output)
|
|
data["unsafe_output"] = power_output > max_safe_output
|
|
data["power_available"] = (powernet == null ? 0 : DisplayPower(avail()))
|
|
data["temperature_current"] = temperature
|
|
data["temperature_max"] = max_temperature
|
|
data["temperature_overheat"] = overheating
|
|
// 1 sheet = 1000cm3?
|
|
|
|
return data
|
|
|
|
/obj/machinery/power/port_gen/pacman/tgui_act(action, params, datum/tgui/ui)
|
|
if(..())
|
|
return
|
|
|
|
add_fingerprint(ui.user)
|
|
switch(action)
|
|
if("toggle_power")
|
|
TogglePower()
|
|
. = TRUE
|
|
|
|
if("eject")
|
|
if(!active)
|
|
DropFuel()
|
|
. = TRUE
|
|
|
|
if("lower_power")
|
|
if(power_output > 1)
|
|
power_output--
|
|
. = TRUE
|
|
|
|
if("higher_power")
|
|
if(power_output < max_power_output || (emagged && power_output < round(max_power_output * 2.5)))
|
|
power_output++
|
|
. = TRUE
|
|
|
|
/obj/machinery/power/port_gen/pacman/super
|
|
name = "S.U.P.E.R.P.A.C.M.A.N.-type Portable Generator"
|
|
desc = "A power generator that utilizes uranium sheets as fuel. Can run for much longer than the standard PACMAN type generators. Rated for 80 kW max safe output."
|
|
icon_state = "portgen1"
|
|
sheet_path = /obj/item/stack/material/uranium
|
|
sheet_name = "Uranium Sheets"
|
|
time_per_sheet = 576 //same power output, but a 50 sheet stack will last 2 hours at max safe power
|
|
circuit = /obj/item/circuitboard/pacman/super
|
|
|
|
/obj/machinery/power/port_gen/pacman/super/UseFuel()
|
|
//produces a tiny amount of radiation when in use
|
|
if (prob(2*power_output))
|
|
SSradiation.radiate(src, 4)
|
|
..()
|
|
|
|
/obj/machinery/power/port_gen/pacman/super/explode()
|
|
//a nice burst of radiation
|
|
var/rads = 50 + (sheets + sheet_left)*1.5
|
|
SSradiation.radiate(src, (max(20, rads)))
|
|
|
|
explosion(src.loc, 3, 3, 5, 3)
|
|
qdel(src)
|
|
|
|
/obj/machinery/power/port_gen/pacman/mrs
|
|
name = "M.R.S.P.A.C.M.A.N.-type Portable Generator"
|
|
desc = "An advanced power generator that runs on tritium. Rated for 200 kW maximum safe output!"
|
|
icon_state = "portgen2"
|
|
sheet_path = /obj/item/stack/material/tritium
|
|
sheet_name = "Tritium Fuel Sheets"
|
|
|
|
//I don't think tritium has any other use, so we might as well make this rewarding for players
|
|
//max safe power output (power level = 8) is 200 kW and lasts for 1 hour - 3 or 4 of these could power the station
|
|
power_gen = 25000 //watts
|
|
max_power_output = 10
|
|
max_safe_output = 8
|
|
time_per_sheet = 576
|
|
max_temperature = 800
|
|
temperature_gain = 90
|
|
circuit = /obj/item/circuitboard/pacman/mrs
|
|
|
|
/obj/machinery/power/port_gen/pacman/mrs/explode()
|
|
//no special effects, but the explosion is pretty big (same as a supermatter shard).
|
|
explosion(src.loc, 3, 6, 12, 16, 1)
|
|
qdel(src)
|
|
|
|
|
|
#undef TEMPERATURE_DIVISOR
|
|
#undef TEMPERATURE_CHANGE_MAX
|