|
| 1 | +//radiation needs to be over this amount to get power |
| 2 | +#define RAD_COLLECTOR_THRESHOLD 80 |
| 3 | +//amount of joules created for each rad point over RAD_COLLECTOR_THRESHOLD |
| 4 | +#define RAD_COLLECTOR_COEFFICIENT 200 |
| 5 | + |
| 6 | +/obj/machinery/power/energy_accumulator/rad_collector |
| 7 | + name = "Hawking Radiation Collector Array" |
| 8 | + desc = "A device which uses hawking radiation generated from singularities and plasma to produce power." |
| 9 | + icon = 'modular_nova/modules/aesthetics/emitter/icons/emitter.dmi' |
| 10 | + icon_state = "ca" |
| 11 | + req_access = list(ACCESS_ENGINE_EQUIP, ACCESS_ATMOSPHERICS) |
| 12 | + max_integrity = 350 |
| 13 | + integrity_failure = 0.2 |
| 14 | + rad_insulation = RAD_EXTREME_INSULATION |
| 15 | + circuit = /obj/item/circuitboard/machine/rad_collector |
| 16 | + /// Stores the loaded tank instance |
| 17 | + var/obj/item/tank/internals/plasma/loaded_tank = null |
| 18 | + /// Is the collector working? |
| 19 | + var/active = FALSE |
| 20 | + /// Is the collector locked with an id? |
| 21 | + var/locked = FALSE |
| 22 | + /// Amount of gas removed per tick |
| 23 | + var/drain_ratio = 0.5 |
| 24 | + /// Multiplier for the amount of gas removed per tick |
| 25 | + var/power_production_drain = 0.001 |
| 26 | + /// Base efficiency |
| 27 | + var/efficiency_multiplier = 1.0 |
| 28 | + |
| 29 | +/obj/machinery/power/energy_accumulator/rad_collector/anchored |
| 30 | + anchored = TRUE |
| 31 | + |
| 32 | +/obj/machinery/power/energy_accumulator/rad_collector/process(delta_time) |
| 33 | + if(!loaded_tank) |
| 34 | + return |
| 35 | + var/datum/gas_mixture/tank_mix = loaded_tank.return_air() |
| 36 | + if(!tank_mix.gases[/datum/gas/plasma]) |
| 37 | + investigate_log("<font color='red'>out of fuel</font>.", INVESTIGATE_ENGINE) |
| 38 | + playsound(src, 'sound/machines/ding.ogg', 50, TRUE) |
| 39 | + eject() |
| 40 | + return |
| 41 | + var/gasdrained = min(power_production_drain * drain_ratio * delta_time, tank_mix.gases[/datum/gas/plasma][MOLES]) |
| 42 | + tank_mix.gases[/datum/gas/plasma][MOLES] -= gasdrained |
| 43 | + tank_mix.assert_gas(/datum/gas/tritium) |
| 44 | + tank_mix.gases[/datum/gas/tritium][MOLES] += gasdrained |
| 45 | + tank_mix.garbage_collect() |
| 46 | + |
| 47 | + . = ..() |
| 48 | + |
| 49 | +/obj/machinery/power/energy_accumulator/rad_collector/interact(mob/user) |
| 50 | + if(!anchored) |
| 51 | + return |
| 52 | + if(locked) |
| 53 | + to_chat(user, span_warning("The controls are locked!")) |
| 54 | + return |
| 55 | + toggle_power() |
| 56 | + user.visible_message(span_notice("[user.name] turns the [src.name] [active? "on":"off"]."), \ |
| 57 | + span_notice("You turn the [src.name] [active? "on":"off"].")) |
| 58 | + var/datum/gas_mixture/tank_mix = loaded_tank?.return_air() |
| 59 | + var/fuel |
| 60 | + if(loaded_tank) |
| 61 | + fuel = tank_mix.gases[/datum/gas/plasma] |
| 62 | + fuel = fuel ? fuel[MOLES] : 0 |
| 63 | + 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_ENGINE) |
| 64 | + |
| 65 | +/obj/machinery/power/energy_accumulator/rad_collector/can_be_unfasten_wrench(mob/user, silent) |
| 66 | + if(!loaded_tank) |
| 67 | + return ..() |
| 68 | + if(!silent) |
| 69 | + to_chat(user, span_warning("Remove the plasma tank first!")) |
| 70 | + return FAILED_UNFASTEN |
| 71 | + |
| 72 | +/obj/machinery/power/energy_accumulator/rad_collector/attackby(obj/item/item, mob/user, params) |
| 73 | + if(istype(item, /obj/item/tank/internals/plasma)) |
| 74 | + if(!anchored) |
| 75 | + to_chat(user, span_warning("[src] needs to be secured to the floor first!")) |
| 76 | + return TRUE |
| 77 | + if(loaded_tank) |
| 78 | + to_chat(user, span_warning("There's already a plasma tank loaded!")) |
| 79 | + return TRUE |
| 80 | + if(panel_open) |
| 81 | + to_chat(user, span_warning("Close the maintenance panel first!")) |
| 82 | + return TRUE |
| 83 | + if(!user.transferItemToLoc(item, src)) |
| 84 | + return |
| 85 | + loaded_tank = item |
| 86 | + update_appearance() |
| 87 | + else if(item.GetID()) |
| 88 | + if(!allowed(user)) |
| 89 | + to_chat(user, span_danger("Access denied.")) |
| 90 | + return TRUE |
| 91 | + if(!active) |
| 92 | + to_chat(user, span_warning("The controls can only be locked when \the [src] is active!")) |
| 93 | + return TRUE |
| 94 | + locked = !locked |
| 95 | + to_chat(user, span_notice("You [locked ? "lock" : "unlock"] the controls.")) |
| 96 | + return TRUE |
| 97 | + else |
| 98 | + return ..() |
| 99 | + |
| 100 | +/obj/machinery/power/energy_accumulator/rad_collector/wrench_act(mob/living/user, obj/item/item) |
| 101 | + . = ..() |
| 102 | + default_unfasten_wrench(user, item) |
| 103 | + return TRUE |
| 104 | + |
| 105 | +/obj/machinery/power/energy_accumulator/rad_collector/screwdriver_act(mob/living/user, obj/item/item) |
| 106 | + if(..()) |
| 107 | + return TRUE |
| 108 | + if(!loaded_tank) |
| 109 | + default_deconstruction_screwdriver(user, icon_state, icon_state, item) |
| 110 | + return TRUE |
| 111 | + to_chat(user, span_warning("Remove the plasma tank first!")) |
| 112 | + return TRUE |
| 113 | + |
| 114 | +/obj/machinery/power/energy_accumulator/rad_collector/crowbar_act(mob/living/user, obj/item/I) |
| 115 | + if(loaded_tank) |
| 116 | + if(!locked) |
| 117 | + eject() |
| 118 | + return TRUE |
| 119 | + to_chat(user, span_warning("The controls are locked!")) |
| 120 | + return TRUE |
| 121 | + if(default_deconstruction_crowbar(I)) |
| 122 | + return TRUE |
| 123 | + to_chat(user, span_warning("There isn't a tank loaded!")) |
| 124 | + return TRUE |
| 125 | + |
| 126 | +/obj/machinery/power/energy_accumulator/rad_collector/return_analyzable_air() |
| 127 | + if(!loaded_tank) |
| 128 | + return null |
| 129 | + return loaded_tank.return_analyzable_air() |
| 130 | + |
| 131 | +/obj/machinery/power/energy_accumulator/rad_collector/examine(mob/user) |
| 132 | + . = ..() |
| 133 | + if(!active) |
| 134 | + . += span_notice("<b>[src]'s display displays the words:</b> \"Power production mode. Please insert <b>Plasma</b>.\"") |
| 135 | + . += span_notice("[src]'s display states that it has stored <b>[display_joules(get_stored_joules())]</b>, and is processing <b>[display_power(get_power_output())]</b>.") |
| 136 | + |
| 137 | +/obj/machinery/power/energy_accumulator/rad_collector/atom_break(damage_flag) |
| 138 | + . = ..() |
| 139 | + if(.) |
| 140 | + eject() |
| 141 | + |
| 142 | +/obj/machinery/power/energy_accumulator/rad_collector/RefreshParts() |
| 143 | + . = ..() |
| 144 | + |
| 145 | + // Reset the upgrades to base values |
| 146 | + efficiency_multiplier = 1.0 |
| 147 | + |
| 148 | + // Calculate efficiency based on micro-laser parts |
| 149 | + for(var/datum/stock_part/micro_laser/laser in component_parts) |
| 150 | + efficiency_multiplier += (laser.tier - 1) * 0.2 // Each tier above 1 increases efficiency by 20% |
| 151 | + |
| 152 | +/obj/machinery/power/energy_accumulator/rad_collector/proc/eject() |
| 153 | + locked = FALSE |
| 154 | + var/obj/item/tank/internals/plasma/tank = loaded_tank |
| 155 | + if (!tank) |
| 156 | + return |
| 157 | + tank.forceMove(drop_location()) |
| 158 | + tank.layer = initial(tank.layer) |
| 159 | + tank.plane = initial(tank.plane) |
| 160 | + loaded_tank = null |
| 161 | + if(active) |
| 162 | + toggle_power() |
| 163 | + else |
| 164 | + update_appearance() |
| 165 | + |
| 166 | +/obj/machinery/power/energy_accumulator/rad_collector/proc/hawking_pulse(atom/source, pulse_strength) |
| 167 | + if(loaded_tank && active && pulse_strength > RAD_COLLECTOR_THRESHOLD) |
| 168 | + // Adjust energy calculation based on efficiency multiplier |
| 169 | + stored_energy += joules_to_energy((pulse_strength - RAD_COLLECTOR_THRESHOLD) * RAD_COLLECTOR_COEFFICIENT * efficiency_multiplier) |
| 170 | + new /obj/effect/temp_visual/hawking_radiation(get_turf(src)) |
| 171 | + |
| 172 | +/obj/machinery/power/energy_accumulator/rad_collector/update_overlays() |
| 173 | + . = ..() |
| 174 | + if(loaded_tank) |
| 175 | + . += "ptank" |
| 176 | + if(machine_stat & (NOPOWER|BROKEN)) |
| 177 | + return |
| 178 | + if(active) |
| 179 | + . += "on" // SKYRAT EDIT CHANGE - ORIGINAL. += loaded_tank ? "on" : "error" |
| 180 | + |
| 181 | +/obj/machinery/power/energy_accumulator/rad_collector/proc/toggle_power() |
| 182 | + active = !active |
| 183 | + if(active) |
| 184 | + icon_state = "ca_on" |
| 185 | + flick("ca_active", src) |
| 186 | + else |
| 187 | + icon_state = "ca" |
| 188 | + flick("ca_deactive", src) |
| 189 | + update_appearance() |
| 190 | + return |
| 191 | + |
| 192 | +#undef RAD_COLLECTOR_THRESHOLD |
| 193 | +#undef RAD_COLLECTOR_COEFFICIENT |
| 194 | + |
| 195 | + |
| 196 | +/obj/item/circuitboard/machine/rad_collector |
| 197 | + name = "Radiation Collector(hawking)" |
| 198 | + greyscale_colors = CIRCUIT_COLOR_ENGINEERING |
| 199 | + build_path = /obj/machinery/power/energy_accumulator/rad_collector |
| 200 | + req_components = list( |
| 201 | + /datum/stock_part/micro_laser = 1, |
| 202 | + /obj/item/stack/cable_coil = 2, |
| 203 | + /obj/item/stack/sheet/glass = 2) |
| 204 | + needs_anchored = FALSE |
0 commit comments