From b15fb8a04bfcd3b4e27c01fb954060042efecf19 Mon Sep 17 00:00:00 2001 From: Ccomp5950 Date: Wed, 15 Jan 2014 20:22:50 -0600 Subject: [PATCH] Supermatter update. Now gives an instability% warning in it's messages. Limited the "If they can see it and aren't wearing mesons, have some hallucinations" range to a max of 7 Can't be pelted with lasers while out in space allowing for unlimited power only to drag it back on a turf and instantly explode. Removed extra if(!removed) check, we already checked for that above. Moved the oxygen ratio variable "oxygen" to be declared under the object instead of it's process proc for easier debugging. Changed the alert interval. Add luminosity value so the big glowing shard of supermatter actually generates light. Conflicts: code/modules/supermatter/supermatter.dm --- code/modules/supermatter/supermatter.dm | 330 ++++++++++++------------ 1 file changed, 171 insertions(+), 159 deletions(-) diff --git a/code/modules/supermatter/supermatter.dm b/code/modules/supermatter/supermatter.dm index 05f6bdf042e..477aab3914a 100644 --- a/code/modules/supermatter/supermatter.dm +++ b/code/modules/supermatter/supermatter.dm @@ -1,80 +1,82 @@ #define NITROGEN_RETARDATION_FACTOR 4 //Higher == N2 slows reaction more -#define THERMAL_RELEASE_MODIFIER 20 //Higher == less heat released during reaction +#define THERMAL_RELEASE_MODIFIER 10 //Higher == less heat released during reaction #define PLASMA_RELEASE_MODIFIER 1500 //Higher == less plasma released by reaction #define OXYGEN_RELEASE_MODIFIER 750 //Higher == less oxygen released at high temperature/power #define REACTION_POWER_MODIFIER 1.1 //Higher == more overall power //These would be what you would get at point blank, decreases with distance -#define DETONATION_RADS 350000 -#define DETONATION_HALLUCINATION 600000 +#define DETONATION_RADS 200 +#define DETONATION_HALLUCINATION 600 -#define WARNING_DELAY 60 //45 seconds between warnings. +#define WARNING_DELAY 30 //seconds between warnings. /obj/machinery/power/supermatter - name = "Supermatter" - desc = "A strangely translucent and iridescent crystal. \red You get headaches just from looking at it." - icon = 'icons/obj/engine.dmi' - icon_state = "darkmatter" - density = 1 - anchored = 0 + name = "Supermatter" + desc = "A strangely translucent and iridescent crystal. \red You get headaches just from looking at it." + icon = 'icons/obj/engine.dmi' + icon_state = "darkmatter" + density = 1 + anchored = 0 + luminosity = 4 - var/gasefficency = 0.25 + var/gasefficency = 0.25 - var/base_icon_state = "darkmatter" + var/base_icon_state = "darkmatter" - var/damage = 0 - var/damage_archived = 0 - var/safe_alert = "Crystaline hyperstructure returning to safe operating levels." - var/warning_point = 100 - var/warning_alert = "Danger! Crystal hyperstructure instability!" - var/emergency_point = 700 - var/emergency_alert = "CRYSTAL DELAMINATION IMMINENT." - var/explosion_point = 1000 + var/damage = 0 + var/damage_archived = 0 + var/safe_alert = "Crystaline hyperstructure returning to safe operating levels." + var/warning_point = 100 + var/warning_alert = "Danger! Crystal hyperstructure instability!" + var/emergency_point = 700 + var/emergency_alert = "CRYSTAL DELAMINATION IMMINENT." + var/explosion_point = 1000 - var/emergency_issued = 0 + var/emergency_issued = 0 - var/explosion_power = 8 + var/explosion_power = 8 - var/lastwarning = 0 // Time in 1/10th of seconds since the last sent warning + var/lastwarning = 0 // Time in 1/10th of seconds since the last sent warning + var/power = 0 - var/power = 0 + var/oxygen = 0 // Moving this up here for easier debugging. - //Temporary values so that we can optimize this - //How much the bullets damage should be multiplied by when it is added to the internal variables - var/config_bullet_energy = 2 - //How much of the power is left after processing is finished? + //Temporary values so that we can optimize this + //How much the bullets damage should be multiplied by when it is added to the internal variables + var/config_bullet_energy = 2 + //How much of the power is left after processing is finished? // var/config_power_reduction_per_tick = 0.5 - //How much hallucination should it produce per unit of power? - var/config_hallucination_power = 0.1 + //How much hallucination should it produce per unit of power? + var/config_hallucination_power = 0.1 - var/obj/item/device/radio/radio + var/obj/item/device/radio/radio - shard //Small subtype, less efficient and more sensitive, but less boom. - name = "Supermatter Shard" - desc = "A strangely translucent and iridescent crystal that looks like it used to be part of a larger structure. \red You get headaches just from looking at it." - icon_state = "darkmatter_shard" - base_icon_state = "darkmatter_shard" + shard //Small subtype, less efficient and more sensitive, but less boom. + name = "Supermatter Shard" + desc = "A strangely translucent and iridescent crystal that looks like it used to be part of a larger structure. \red You get headaches just from looking at it." + icon_state = "darkmatter_shard" + base_icon_state = "darkmatter_shard" - warning_point = 50 - emergency_point = 500 - explosion_point = 900 + warning_point = 50 + emergency_point = 500 + explosion_point = 900 - gasefficency = 0.125 + gasefficency = 0.125 - explosion_power = 3 //3,6,9,12? Or is that too small? + explosion_power = 3 //3,6,9,12? Or is that too small? /obj/machinery/power/supermatter/New() - . = ..() - radio = new (src) + . = ..() + radio = new (src) /obj/machinery/power/supermatter/Del() - del radio - . = ..() + del radio + . = ..() /obj/machinery/power/supermatter/proc/explode() explosion(get_turf(src), explosion_power, explosion_power * 2, explosion_power * 3, explosion_power * 4, 1) @@ -83,133 +85,143 @@ /obj/machinery/power/supermatter/process() - var/turf/L = loc + var/turf/L = loc - if(!istype(L)) //If we are not on a turf, uh oh. - del src + if(isnull(L)) // We have a null turf...something is wrong, stop processing this entity. + return PROCESS_KILL - //Ok, get the air from the turf - var/datum/gas_mixture/env = L.return_air() + if(!istype(L)) //We are in a crate or somewhere that isn't turf, if we return to turf resume processing but for now. + return //Yeah just stop. - //Remove gas from surrounding area - var/datum/gas_mixture/removed = env.remove(gasefficency * env.total_moles) + //Ok, get the air from the turf + var/datum/gas_mixture/env = L.return_air() - if(!removed || !removed.total_moles) - damage += max((power-1600)/10, 0) - power = min(power, 1600) - return 1 + //Remove gas from surrounding area + var/datum/gas_mixture/removed = env.remove(gasefficency * env.total_moles) - if (!removed) - return 1 + if(!removed || !removed.total_moles) + damage += max((power-1600)/10, 0) + power = min(power, 1600) + return 1 - damage_archived = damage - damage = max( damage + ( (removed.temperature - 800) / 150 ) , 0 ) + damage_archived = damage + damage = max( damage + ( (removed.temperature - 800) / 150 ) , 0 ) - if(damage > warning_point) // while the core is still damaged and it's still worth noting its status - if((world.timeofday - lastwarning) / 10 >= WARNING_DELAY) + if(damage > warning_point) // while the core is still damaged and it's still worth noting its status + if((world.timeofday - lastwarning) / 10 >= WARNING_DELAY) + var/stability = num2text(round((damage / explosion_point) * 100)) - if(damage > emergency_point) - radio.autosay(emergency_alert, "Supermatter Monitor") - lastwarning = world.timeofday + if(damage > emergency_point) - else if(damage >= damage_archived) // The damage is still going up - radio.autosay(warning_alert, "Supermatter Monitor") - lastwarning = world.timeofday - 150 + radio.autosay(addtext(emergency_alert, " Stability: ",stability,"%"), "Supermatter Monitor") + lastwarning = world.timeofday - else // Phew, we're safe - radio.autosay(safe_alert, "Supermatter Monitor") - lastwarning = world.timeofday + else if(damage >= damage_archived) // The damage is still going up + radio.autosay(addtext(warning_alert," Stability: ",stability,"%"), "Supermatter Monitor") + lastwarning = world.timeofday - 150 - if(damage > explosion_point) - for(var/mob/living/mob in living_mob_list) - if ((mob.z != src.z) && (mob.z != 0)) - continue - if(istype(mob, /mob/living/carbon/human)) - //Hilariously enough, running into a closet should make you get hit the hardest. - mob:hallucination += max(50, min(300, DETONATION_HALLUCINATION/((get_dist(mob, src)+1)**2) ) ) - var/rads = DETONATION_RADS/((get_dist(mob, src)+1)**2) - mob.apply_effect(rads, IRRADIATE) + else // Phew, we're safe + radio.autosay(safe_alert, "Supermatter Monitor") + lastwarning = world.timeofday - explode() + if(damage > explosion_point) + for(var/mob/living/mob in living_mob_list) + if(istype(mob, /mob/living/carbon/human)) + //Hilariously enough, running into a closet should make you get hit the hardest. + mob:hallucination += max(50, min(300, DETONATION_HALLUCINATION * sqrt(1 / (get_dist(mob, src) + 1)) ) ) + var/rads = DETONATION_RADS * sqrt( 1 / (get_dist(mob, src) + 1) ) + mob.apply_effect(rads, IRRADIATE) - //Ok, 100% oxygen atmosphere = best reaction - //Maxes out at 100% oxygen pressure - var/oxygen = max(min((removed.oxygen - (removed.nitrogen * NITROGEN_RETARDATION_FACTOR)) / MOLES_CELLSTANDARD, 1), 0) + explode() - var/temp_factor = 100 + //Ok, 100% oxygen atmosphere = best reaction + //Maxes out at 100% oxygen pressure + oxygen = max(min((removed.oxygen - (removed.nitrogen * NITROGEN_RETARDATION_FACTOR)) / MOLES_CELLSTANDARD, 1), 0) - if(oxygen > 0.8) - // with a perfect gas mix, make the power less based on heat - icon_state = "[base_icon_state]_glow" - else - // in normal mode, base the produced energy around the heat - temp_factor = 60 - icon_state = base_icon_state + var/temp_factor = 100 - power = max( (removed.temperature * temp_factor / T0C) * oxygen + power, 0) //Total laser power plus an overload + if(oxygen > 0.8) + // with a perfect gas mix, make the power less based on heat + icon_state = "[base_icon_state]_glow" + else + // in normal mode, base the produced energy around the heat + temp_factor = 60 + icon_state = base_icon_state - //We've generated power, now let's transfer it to the collectors for storing/usage - transfer_energy() + power = max( (removed.temperature * temp_factor / T0C) * oxygen + power, 0) //Total laser power plus an overload - var/device_energy = power * REACTION_POWER_MODIFIER + //We've generated power, now let's transfer it to the collectors for storing/usage + transfer_energy() - //To figure out how much temperature to add each tick, consider that at one atmosphere's worth - //of pure oxygen, with all four lasers firing at standard energy and no N2 present, at room temperature - //that the device energy is around 2140. At that stage, we don't want too much heat to be put out - //Since the core is effectively "cold" + var/device_energy = power * REACTION_POWER_MODIFIER - //Also keep in mind we are only adding this temperature to (efficiency)% of the one tile the rock - //is on. An increase of 4*C @ 25% efficiency here results in an increase of 1*C / (#tilesincore) overall. - removed.temperature += (device_energy / THERMAL_RELEASE_MODIFIER) + //To figure out how much temperature to add each tick, consider that at one atmosphere's worth + //of pure oxygen, with all four lasers firing at standard energy and no N2 present, at room temperature + //that the device energy is around 2140. At that stage, we don't want too much heat to be put out + //Since the core is effectively "cold" - removed.temperature = max(0, min(removed.temperature, 2500)) + //Also keep in mind we are only adding this temperature to (efficiency)% of the one tile the rock + //is on. An increase of 4*C @ 25% efficiency here results in an increase of 1*C / (#tilesincore) overall. + removed.temperature += (device_energy / THERMAL_RELEASE_MODIFIER) - //Calculate how much gas to release - removed.toxins += max(device_energy / PLASMA_RELEASE_MODIFIER, 0) + removed.temperature = max(0, min(removed.temperature, 2500)) - removed.oxygen += max((device_energy + removed.temperature - T0C) / OXYGEN_RELEASE_MODIFIER, 0) + //Calculate how much gas to release + removed.toxins += max(device_energy / PLASMA_RELEASE_MODIFIER, 0) - removed.update_values() + removed.oxygen += max((device_energy + removed.temperature - T0C) / OXYGEN_RELEASE_MODIFIER, 0) - env.merge(removed) + removed.update_values() - for(var/mob/living/carbon/human/l in view(src, round(power ** 0.25))) // you have to be seeing the core to get hallucinations - if(!istype(l.glasses, /obj/item/clothing/glasses/meson)) - l.hallucination = max(0, min(200, l.hallucination + power * config_hallucination_power * sqrt( 1 / get_dist(l, src) ) ) ) + env.merge(removed) - for(var/mob/living/l in range(src, round((power / 100) ** 0.25))) - var/rads = (power / 10) * sqrt( 1 / get_dist(l, src) ) - l.apply_effect(rads, IRRADIATE) + for(var/mob/living/carbon/human/l in view(src, min(7, round(power ** 0.25)))) // If they can see it without mesons on. Bad on them. + if(!istype(l.glasses, /obj/item/clothing/glasses/meson)) + l.hallucination = max(0, min(200, l.hallucination + power * config_hallucination_power * sqrt( 1 / get_dist(l, src) ) ) ) - power -= (power/500)**3 + for(var/mob/living/l in range(src, round((power / 100) ** 0.25))) + var/rads = (power / 10) * sqrt( 1 / get_dist(l, src) ) + l.apply_effect(rads, IRRADIATE) - return 1 + power -= (power/500)**3 + + return 1 /obj/machinery/power/supermatter/bullet_act(var/obj/item/projectile/Proj) - if(Proj.flag != "bullet") - power += Proj.damage * config_bullet_energy - else - damage += Proj.damage * config_bullet_energy - return 0 + var/turf/L = loc + if(!istype(L)) // We don't run process() when we are in space + return 0 // This stops people from being able to really power up the supermatter + // Then bring it inside to explode instantly upon landing on a valid turf. + + + if(Proj.flag != "bullet") + power += Proj.damage * config_bullet_energy + else + damage += Proj.damage * config_bullet_energy + return 0 -/obj/machinery/power/supermatter/attack_ai() - return /obj/machinery/power/supermatter/attack_paw(mob/user as mob) - return attack_hand(user) + return attack_hand(user) -/obj/machinery/power/supermatter/attack_robot() - return +/obj/machinery/power/supermatter/attack_robot(mob/user as mob) + if(Adjacent(user)) + return attack_hand(user) + else + user << "You attempt to interface with the control circuits but find they are not connected to your network. Maybe in a future firmware update." + return +/obj/machinery/power/supermatter/attack_ai(mob/user as mob) + user << "You attempt to interface with the control circuits but find they are not connected to your network. Maybe in a future firmware update." /obj/machinery/power/supermatter/attack_hand(mob/user as mob) - user.visible_message("\The [user] reaches out and touches \the [src] inducing a resonance... \his body starts to glow and catch flame before flashing into ash.",\ - "You reach out and touch \the [src], everything starts burning and all you can hear is ringing. Your last thought is \"That was not a wise decision.\"",\ - "You hear an uneartly ringing, then what sounds like a shrilling kettle as you are washed with a wave of heat.") + user.visible_message("\The [user] reaches out and touches \the [src], inducing a resonance... \his body starts to glow and bursts into flames before flashing into ash.",\ + "You reach out and touch \the [src]. Everything starts burning and all you can hear is ringing. Your last thought is \"That was not a wise decision.\"",\ + "You hear an uneartly ringing, then what sounds like a shrilling kettle as you are washed with a wave of heat.") - Consume(user) + Consume(user) /obj/machinery/power/supermatter/proc/transfer_energy() for(var/obj/machinery/power/rad_collector/R in rad_collectors) @@ -218,44 +230,44 @@ return /obj/machinery/power/supermatter/attackby(obj/item/weapon/W as obj, mob/living/user as mob) - user.visible_message("\The [user] touches \a [W] to \the [src] as a silence fills the room...",\ - "You touch \the [W] to \the [src] when everything suddenly goes silent.\"\n\The [W] flashes into dust as you flinch away from \the [src].",\ - "Everything suddenly goes silent.") + user.visible_message("\The [user] touches \a [W] to \the [src] as a silence fills the room...",\ + "You touch \the [W] to \the [src] when everything suddenly goes silent.\"\n\The [W] flashes into dust as you flinch away from \the [src].",\ + "Everything suddenly goes silent.") - user.drop_from_inventory(W) - Consume(W) + user.drop_from_inventory(W) + Consume(W) - user.apply_effect(150, IRRADIATE) + user.apply_effect(150, IRRADIATE) /obj/machinery/power/supermatter/Bumped(atom/AM as mob|obj) - if(istype(AM, /mob/living)) - AM.visible_message("\The [AM] slams into \the [src] inducing a resonance... \his body starts to glow and catch flame before flashing into ash.",\ - "You slam into \the [src] as your ears are filled with unearthly ringing. Your last thought is \"Oh, fuck.\"",\ - "You hear an uneartly ringing, then what sounds like a shrilling kettle as you are washed with a wave of heat.") - else - AM.visible_message("\The [AM] smacks into \the [src] and rapidly flashes to ash.",\ - "You hear a loud crack as you are washed with a wave of heat.") + if(istype(AM, /mob/living)) + AM.visible_message("\The [AM] slams into \the [src] inducing a resonance... \his body starts to glow and catch flame before flashing into ash.",\ + "You slam into \the [src] as your ears are filled with unearthly ringing. Your last thought is \"Oh, fuck.\"",\ + "You hear an uneartly ringing, then what sounds like a shrilling kettle as you are washed with a wave of heat.") + else + AM.visible_message("\The [AM] smacks into \the [src] and rapidly flashes to ash.",\ + "You hear a loud crack as you are washed with a wave of heat.") - Consume(AM) + Consume(AM) /obj/machinery/power/supermatter/proc/Consume(var/mob/living/user) - if(istype(user)) - user.dust() - power += 200 - else - del user + if(istype(user)) + user.dust() + power += 200 + else + del user - power += 200 + power += 200 //Some poor sod got eaten, go ahead and irradiate people nearby. - for(var/mob/living/l in range(10)) - if(l in view()) - l.show_message("As \the [src] slowly stops resonating, you find your skin covered in new radiation burns.", 1,\ - "The unearthly ringing subsides and you notice you have new radiation burns.", 2) - else - l.show_message("You hear an uneartly ringing and notice your skin is covered in fresh radiation burns.", 2) - var/rads = 500 * sqrt( 1 / (get_dist(l, src) + 1) ) - l.apply_effect(rads, IRRADIATE) + for(var/mob/living/l in range(10)) + if(l in view()) + l.show_message("As \the [src] slowly stops resonating, you find your skin covered in new radiation burns.", 1,\ + "The unearthly ringing subsides and you notice you have new radiation burns.", 2) + else + l.show_message("You hear an uneartly ringing and notice your skin is covered in fresh radiation burns.", 2) + var/rads = 500 * sqrt( 1 / (get_dist(l, src) + 1) ) + l.apply_effect(rads, IRRADIATE)