|
2 | 2 | #define HEATER_MODE_HEAT "heat"
|
3 | 3 | #define HEATER_MODE_COOL "cool"
|
4 | 4 | #define HEATER_MODE_AUTO "auto"
|
5 |
| -#define BASE_HEATING_ENERGY (STANDARD_CELL_RATE * 4) |
| 5 | +#define BASE_HEATING_ENERGY (40 KILO JOULES) |
6 | 6 |
|
7 | 7 | /obj/machinery/space_heater
|
8 | 8 | anchored = FALSE
|
|
32 | 32 | ///How much heat/cold we can deliver
|
33 | 33 | var/heating_energy = BASE_HEATING_ENERGY
|
34 | 34 | ///How efficiently we can deliver that heat/cold (higher indicates less cell consumption)
|
35 |
| - var/efficiency = 200 |
| 35 | + var/efficiency = 20 MEGA JOULES / STANDARD_CELL_CHARGE |
36 | 36 | ///The amount of degrees above and below the target temperature for us to change mode to heater or cooler
|
37 | 37 | var/temperature_tolerance = 1
|
38 | 38 | ///What's the middle point of our settable temperature (30 °C)
|
|
176 | 176 | for(var/datum/stock_part/capacitor/capacitor in component_parts)
|
177 | 177 | cap += capacitor.tier
|
178 | 178 |
|
179 |
| - heating_energy = laser * BASE_HEATING_ENERGY |
| 179 | + heating_energy = laser * initial(heating_energy) |
180 | 180 |
|
181 | 181 | settable_temperature_range = cap * initial(settable_temperature_range)
|
182 | 182 | efficiency = (cap + 1) * initial(efficiency) * 0.5
|
|
295 | 295 | on = !on
|
296 | 296 | mode = HEATER_MODE_STANDBY
|
297 | 297 | if(!isnull(user))
|
298 |
| - balloon_alert(user, "turned [on ? "on" : "off"]") |
| 298 | + if(QDELETED(cell)) |
| 299 | + balloon_alert(user, "no cell!") |
| 300 | + else if(!cell.charge()) |
| 301 | + balloon_alert(user, "no charge!") |
| 302 | + else if(!is_operational) |
| 303 | + balloon_alert(user, "not operational!") |
| 304 | + else |
| 305 | + balloon_alert(user, "turned [on ? "on" : "off"]") |
299 | 306 | update_appearance()
|
300 | 307 | if(on)
|
301 | 308 | SSair.start_processing_machine(src)
|
|
310 | 317 | //We inherit the cell from the heater prior
|
311 | 318 | cell = null
|
312 | 319 | interaction_flags_click = FORBID_TELEKINESIS_REACH
|
| 320 | + display_panel = FALSE |
| 321 | + settable_temperature_range = 50 |
313 | 322 | ///The beaker within the heater
|
314 | 323 | var/obj/item/reagent_containers/beaker = null
|
315 |
| - ///How powerful the heating is, upgrades with parts. (ala chem_heater.dm's method, basically the same level of heating, but this is restricted) |
316 |
| - var/chem_heating_power = 1 |
317 |
| - display_panel = FALSE |
| 324 | + /// How quickly it delivers heat to the reagents. In watts per joule of the thermal energy difference of the reagent from the temperature difference of the current and target temperatures. |
| 325 | + var/beaker_conduction_power = 0.1 |
| 326 | + /// The subsystem we're being processed by. |
| 327 | + var/datum/controller/subsystem/processing/our_subsystem |
| 328 | + |
| 329 | +/obj/machinery/space_heater/improvised_chem_heater/Initialize(mapload) |
| 330 | + our_subsystem = locate(subsystem_type) in Master.subsystems |
| 331 | + . = ..() |
318 | 332 |
|
319 | 333 | /obj/machinery/space_heater/improvised_chem_heater/Destroy()
|
320 | 334 | . = ..()
|
321 | 335 | QDEL_NULL(beaker)
|
322 | 336 |
|
323 | 337 | /obj/machinery/space_heater/improvised_chem_heater/heating_examine()
|
324 | 338 | . = ..()
|
325 |
| - |
326 |
| - var/power_mod = 0.1 * chem_heating_power |
327 |
| - if(set_mode == HEATER_MODE_AUTO) |
328 |
| - power_mod *= 0.5 |
329 |
| - . += span_notice("Heating power for beaker: <b>[display_power(heating_energy * power_mod, convert = TRUE)]</b>") |
| 339 | + // Conducted energy per joule of thermal energy difference in a tick. |
| 340 | + var/conduction_energy = beaker_conduction_power * (set_mode == HEATER_MODE_AUTO ? 0.5 : 1) * our_subsystem.wait / (1 SECONDS) |
| 341 | + // This accounts for the timestep inaccuracy. |
| 342 | + . += span_notice("Reagent conduction power: <b>[conduction_energy < 1 ? display_power(-log(1 - conduction_energy) SECONDS / our_subsystem.wait, convert = FALSE) : "∞W"]/J</b>") |
330 | 343 |
|
331 | 344 | /obj/machinery/space_heater/improvised_chem_heater/toggle_power(user)
|
332 | 345 | . = ..()
|
|
341 | 354 | return PROCESS_KILL
|
342 | 355 |
|
343 | 356 | if(beaker.reagents.total_volume)
|
344 |
| - var/power_mod = 0.1 * chem_heating_power |
| 357 | + var/conduction_modifier = beaker_conduction_power |
345 | 358 | switch(set_mode)
|
346 | 359 | if(HEATER_MODE_AUTO)
|
347 |
| - power_mod *= 0.5 |
| 360 | + conduction_modifier *= 0.5 |
348 | 361 | if(HEATER_MODE_HEAT)
|
349 | 362 | if(target_temperature < beaker.reagents.chem_temp)
|
350 | 363 | return
|
351 | 364 | if(HEATER_MODE_COOL)
|
352 | 365 | if(target_temperature > beaker.reagents.chem_temp)
|
353 | 366 | return
|
354 | 367 |
|
355 |
| - var/required_energy = abs(target_temperature - beaker.reagents.chem_temp) * power_mod * seconds_per_tick * beaker.reagents.heat_capacity() |
| 368 | + var/required_energy = abs(target_temperature - beaker.reagents.chem_temp) * conduction_modifier * seconds_per_tick * beaker.reagents.heat_capacity() |
356 | 369 | required_energy = min(required_energy, heating_energy, cell.charge * efficiency)
|
357 | 370 | if(required_energy < 1)
|
358 | 371 | return
|
|
468 | 481 | for(var/datum/stock_part/capacitor/capacitor in component_parts)
|
469 | 482 | capacitors_rating += capacitor.tier
|
470 | 483 |
|
471 |
| - heating_energy = lasers_rating * BASE_HEATING_ENERGY |
| 484 | + heating_energy = lasers_rating * initial(heating_energy) |
472 | 485 |
|
473 |
| - settable_temperature_range = capacitors_rating * 50 //-20 - 80 at base |
474 |
| - efficiency = (capacitors_rating + 1) * 10 |
| 486 | + settable_temperature_range = capacitors_rating * initial(settable_temperature_range) //-20 - 80 at base |
| 487 | + efficiency = (capacitors_rating + 1) * initial(efficiency) * 0.5 |
475 | 488 |
|
476 | 489 | target_temperature = clamp(target_temperature,
|
477 | 490 | max(settable_temperature_median - settable_temperature_range, TCMB),
|
478 | 491 | settable_temperature_median + settable_temperature_range)
|
479 | 492 |
|
480 |
| - chem_heating_power = efficiency / 20 |
| 493 | + // No time integration is used, so we should clamp this to prevent being able to overshoot if there was a subtype with a high initial value. |
| 494 | + beaker_conduction_power = min((capacitors_rating + 1) * 0.5 * initial(beaker_conduction_power), 1 SECONDS / our_subsystem.wait) |
481 | 495 |
|
482 | 496 | #undef HEATER_MODE_STANDBY
|
483 | 497 | #undef HEATER_MODE_HEAT
|
|
0 commit comments