diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index 6900f36a33..bdee4cdcd5 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -15,22 +15,31 @@ ////////////////////////////////////////////////////////////////// // /datum signals -#define COMSIG_COMPONENT_ADDED "component_added" //sent to the new datum parent when a component is added to them: (/datum/component) -#define COMSIG_COMPONENT_REMOVING "component_removing" //sent to the datum parent before a component is removed from them because of RemoveComponent: (/datum/component) -#define COMSIG_COMPONENT_UNREGISTER_PARENT "component_unregister_parent" //sent to the component itself when unregistered from a parent -#define COMSIG_COMPONENT_REGISTER_PARENT "component_register_parent" //sent to the component itself when registered to a parent -#define COMSIG_PARENT_PREQDELETED "parent_preqdeleted" //before a datum's Destroy() is called: (force), returning a nonzero value will cancel the qdel operation -#define COMSIG_PARENT_QDELETING "parent_qdeleting" //just before a datum's Destroy() is called: (force), at this point none of the other components chose to interrupt qdel and Destroy will be called - -/// Trait signals -#define COMPONENT_ADD_TRAIT (1<<0) -#define COMPONENT_REMOVE_TRAIT (1<<1) +/// when a component is added to a datum: (/datum/component) +#define COMSIG_COMPONENT_ADDED "component_added" +/// before a component is removed from a datum because of RemoveComponent: (/datum/component) +#define COMSIG_COMPONENT_REMOVING "component_removing" +/// before a datum's Destroy() is called: (force), returning a nonzero value will cancel the qdel operation +#define COMSIG_PARENT_PREQDELETED "parent_preqdeleted" +/// just before a datum's Destroy() is called: (force), at this point none of the other components chose to interrupt qdel and Destroy will be called +#define COMSIG_PARENT_QDELETING "parent_qdeleting" +/// generic topic handler (usr, href_list) +#define COMSIG_TOPIC "handle_topic" /// fires on the target datum when an element is attached to it (/datum/element) #define COMSIG_ELEMENT_ATTACH "element_attach" /// fires on the target datum when an element is attached to it (/datum/element) #define COMSIG_ELEMENT_DETACH "element_detach" +/// sent to the component itself when unregistered from a parent +#define COMSIG_COMPONENT_UNREGISTER_PARENT "component_unregister_parent" +/// sent to the component itself when registered to a parent +#define COMSIG_COMPONENT_REGISTER_PARENT "component_register_parent" + +/// Trait signals +#define COMPONENT_ADD_TRAIT (1<<0) +#define COMPONENT_REMOVE_TRAIT (1<<1) + // /atom signals //from base of atom/proc/Initialize(): sent any time a new atom is created #define COMSIG_ATOM_CREATED "atom_created" @@ -56,30 +65,54 @@ #define COMSIG_ATOM_EXIT "atom_exit" //from base of atom/Exit(): (/atom/movable/exiting, /atom/newloc) #define COMPONENT_ATOM_BLOCK_EXIT 1 #define COMSIG_ATOM_EXITED "atom_exited" //from base of atom/Exited(): (atom/movable/exiting, atom/newloc) -#define COMSIG_ATOM_EX_ACT "atom_ex_act" //from base of atom/ex_act(): (severity, target) -#define COMSIG_ATOM_EMP_ACT "atom_emp_act" //from base of atom/emp_act(): (severity) -#define COMSIG_ATOM_FIRE_ACT "atom_fire_act" //from base of atom/fire_act(): (exposed_temperature, exposed_volume) -#define COMSIG_ATOM_BULLET_ACT "atom_bullet_act" //from base of atom/bullet_act(): (/obj/item/projectile, def_zone) -#define COMSIG_ATOM_BLOB_ACT "atom_blob_act" //from base of atom/blob_act(): (/obj/structure/blob) -#define COMSIG_ATOM_ACID_ACT "atom_acid_act" //from base of atom/acid_act(): (acidpwr, acid_volume) -#define COMSIG_ATOM_EMAG_ACT "atom_emag_act" //from base of atom/emag_act(): () -#define COMSIG_ATOM_RAD_ACT "atom_rad_act" //from base of atom/rad_act(intensity) -#define COMSIG_ATOM_NARSIE_ACT "atom_narsie_act" //from base of atom/narsie_act(): () -#define COMSIG_ATOM_RATVAR_ACT "atom_ratvar_act" //from base of atom/ratvar_act(): () -#define COMSIG_ATOM_RCD_ACT "atom_rcd_act" //from base of atom/rcd_act(): (/mob, /obj/item/construction/rcd, passed_mode) -#define COMSIG_ATOM_SING_PULL "atom_sing_pull" //from base of atom/singularity_pull(): (S, current_size) -#define COMSIG_ATOM_SET_LIGHT "atom_set_light" //from base of atom/set_light(): (l_range, l_power, l_color) -#define COMSIG_ATOM_DIR_CHANGE "atom_dir_change" //from base of atom/setDir(): (old_dir, new_dir) -#define COMSIG_ATOM_CONTENTS_DEL "atom_contents_del" //from base of atom/handle_atom_del(): (atom/deleted) -#define COMSIG_ATOM_HAS_GRAVITY "atom_has_gravity" //from base of atom/has_gravity(): (turf/location, list/forced_gravities) -#define COMSIG_ATOM_RAD_PROBE "atom_rad_probe" //from proc/get_rad_contents(): () - #define COMPONENT_BLOCK_RADIATION 1 -#define COMSIG_ATOM_RAD_CONTAMINATING "atom_rad_contam" //from base of datum/radiation_wave/radiate(): (strength) - #define COMPONENT_BLOCK_CONTAMINATION 1 -#define COMSIG_ATOM_RAD_WAVE_PASSING "atom_rad_wave_pass" //from base of datum/radiation_wave/check_obstructions(): (datum/radiation_wave, width) - #define COMPONENT_RAD_WAVE_HANDLED 1 -#define COMSIG_ATOM_CANREACH "atom_can_reach" //from internal loop in atom/movable/proc/CanReach(): (list/next) - #define COMPONENT_BLOCK_REACH 1 +///from base of atom/ex_act(): (severity, target) +#define COMSIG_ATOM_EX_ACT "atom_ex_act" +///from base of atom/emp_act(): (severity) +#define COMSIG_ATOM_EMP_ACT "atom_emp_act" +///from base of atom/fire_act(): (exposed_temperature, exposed_volume) +#define COMSIG_ATOM_FIRE_ACT "atom_fire_act" +///from base of atom/bullet_act(): (/obj/projectile, def_zone) +#define COMSIG_ATOM_BULLET_ACT "atom_bullet_act" +///from base of atom/blob_act(): (/obj/structure/blob) +#define COMSIG_ATOM_BLOB_ACT "atom_blob_act" +///from base of atom/acid_act(): (acidpwr, acid_volume) +#define COMSIG_ATOM_ACID_ACT "atom_acid_act" +///from base of atom/emag_act(): (/mob/user) +#define COMSIG_ATOM_EMAG_ACT "atom_emag_act" +///from base of atom/rad_act(intensity) +#define COMSIG_ATOM_RAD_ACT "atom_rad_act" +///from base of atom/narsie_act(): () +#define COMSIG_ATOM_NARSIE_ACT "atom_narsie_act" +///from base of atom/ratvar_act(): () +#define COMSIG_ATOM_RATVAR_ACT "atom_ratvar_act" +///from base of atom/rcd_act(): (/mob, /obj/item/construction/rcd, passed_mode) +#define COMSIG_ATOM_RCD_ACT "atom_rcd_act" +///from base of atom/singularity_pull(): (S, current_size) +#define COMSIG_ATOM_SING_PULL "atom_sing_pull" +///from obj/machinery/bsa/full/proc/fire(): () +#define COMSIG_ATOM_BSA_BEAM "atom_bsa_beam_pass" + #define COMSIG_ATOM_BLOCKS_BSA_BEAM (1<<0) +///from base of atom/set_light(): (l_range, l_power, l_color) +#define COMSIG_ATOM_SET_LIGHT "atom_set_light" +///from base of atom/setDir(): (old_dir, new_dir). Called before the direction changes. +#define COMSIG_ATOM_DIR_CHANGE "atom_dir_change" +///from base of atom/handle_atom_del(): (atom/deleted) +#define COMSIG_ATOM_CONTENTS_DEL "atom_contents_del" +///from base of atom/has_gravity(): (turf/location, list/forced_gravities) +#define COMSIG_ATOM_HAS_GRAVITY "atom_has_gravity" +///from proc/get_rad_contents(): () +#define COMSIG_ATOM_RAD_PROBE "atom_rad_probe" + #define COMPONENT_BLOCK_RADIATION (1<<0) +///from base of datum/radiation_wave/radiate(): (strength) +#define COMSIG_ATOM_RAD_CONTAMINATING "atom_rad_contam" + #define COMPONENT_BLOCK_CONTAMINATION (1<<0) +///from base of datum/radiation_wave/check_obstructions(): (datum/radiation_wave, width) +#define COMSIG_ATOM_RAD_WAVE_PASSING "atom_rad_wave_pass" + #define COMPONENT_RAD_WAVE_HANDLED (1<<0) +///from internal loop in atom/movable/proc/CanReach(): (list/next) +#define COMSIG_ATOM_CANREACH "atom_can_reach" + #define COMPONENT_BLOCK_REACH (1<<0) + #define COMSIG_ATOM_SCREWDRIVER_ACT "atom_screwdriver_act" //from base of atom/screwdriver_act(): (mob/living/user, obj/item/I) #define COMSIG_ATOM_INTERCEPT_TELEPORT "intercept_teleport" //called when teleporting into a protected turf: (channel, turf/origin, turf/destination) #define COMPONENT_BLOCK_TELEPORT 1 diff --git a/code/datums/elements/bsa_blocker.dm b/code/datums/elements/bsa_blocker.dm new file mode 100644 index 0000000000..61140ad0ed --- /dev/null +++ b/code/datums/elements/bsa_blocker.dm @@ -0,0 +1,10 @@ +//blocks bluespace artillery beams that try to fly through +//look not all elements need to be fancy +/datum/element/bsa_blocker/Attach(datum/target) + if(!isatom(target)) + return ELEMENT_INCOMPATIBLE + RegisterSignal(target, COMSIG_ATOM_BSA_BEAM, .proc/block_bsa) + return ..() + +/datum/element/bsa_blocker/proc/block_bsa() + return COMSIG_ATOM_BLOCKS_BSA_BEAM diff --git a/code/game/objects/effects/temporary_visuals/miscellaneous.dm b/code/game/objects/effects/temporary_visuals/miscellaneous.dm index 396f463136..8d5458333c 100644 --- a/code/game/objects/effects/temporary_visuals/miscellaneous.dm +++ b/code/game/objects/effects/temporary_visuals/miscellaneous.dm @@ -139,6 +139,23 @@ /obj/effect/temp_visual/dir_setting/curse/hand icon_state = "cursehand" +/obj/effect/temp_visual/bsa_splash + name = "\improper Bluespace energy wave" + desc = "A massive, rippling wave of bluepace energy, all rapidly exhausting itself the moment it leaves the concentrated beam of light." + icon = 'icons/effects/beam_splash.dmi' + icon_state = "beam_splash_l" + layer = ABOVE_ALL_MOB_LAYER + pixel_y = -16 + duration = 50 + +/obj/effect/temp_visual/bsa_splash/Initialize(mapload, dir) + . = ..() + switch(dir) + if(WEST) + icon_state = "beam_splash_w" + if(EAST) + icon_state = "beam_splash_e" + /obj/effect/temp_visual/wizard name = "water" icon = 'icons/mob/mob.dmi' diff --git a/code/game/sound.dm b/code/game/sound.dm index 577b058178..0feb01c223 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -226,5 +226,9 @@ soundin = pick('sound/effects/clangsmall1.ogg', 'sound/effects/clangsmall2.ogg') if("slosh") soundin = pick('sound/effects/slosh1.ogg', 'sound/effects/slosh2.ogg') + if("smcalm") + soundin = pick('sound/machines/sm/accent/normal/1.ogg', 'sound/machines/sm/accent/normal/2.ogg', 'sound/machines/sm/accent/normal/3.ogg', 'sound/machines/sm/accent/normal/4.ogg', 'sound/machines/sm/accent/normal/5.ogg', 'sound/machines/sm/accent/normal/6.ogg', 'sound/machines/sm/accent/normal/7.ogg', 'sound/machines/sm/accent/normal/8.ogg', 'sound/machines/sm/accent/normal/9.ogg', 'sound/machines/sm/accent/normal/10.ogg', 'sound/machines/sm/accent/normal/11.ogg', 'sound/machines/sm/accent/normal/12.ogg', 'sound/machines/sm/accent/normal/13.ogg', 'sound/machines/sm/accent/normal/14.ogg', 'sound/machines/sm/accent/normal/15.ogg', 'sound/machines/sm/accent/normal/16.ogg', 'sound/machines/sm/accent/normal/17.ogg', 'sound/machines/sm/accent/normal/18.ogg', 'sound/machines/sm/accent/normal/19.ogg', 'sound/machines/sm/accent/normal/20.ogg', 'sound/machines/sm/accent/normal/21.ogg', 'sound/machines/sm/accent/normal/22.ogg', 'sound/machines/sm/accent/normal/23.ogg', 'sound/machines/sm/accent/normal/24.ogg', 'sound/machines/sm/accent/normal/25.ogg', 'sound/machines/sm/accent/normal/26.ogg', 'sound/machines/sm/accent/normal/27.ogg', 'sound/machines/sm/accent/normal/28.ogg', 'sound/machines/sm/accent/normal/29.ogg', 'sound/machines/sm/accent/normal/30.ogg', 'sound/machines/sm/accent/normal/31.ogg', 'sound/machines/sm/accent/normal/32.ogg', 'sound/machines/sm/accent/normal/33.ogg') + if("smdelam") + soundin = pick('sound/machines/sm/accent/delam/1.ogg', 'sound/machines/sm/accent/normal/2.ogg', 'sound/machines/sm/accent/normal/3.ogg', 'sound/machines/sm/accent/normal/4.ogg', 'sound/machines/sm/accent/normal/5.ogg', 'sound/machines/sm/accent/normal/6.ogg', 'sound/machines/sm/accent/normal/7.ogg', 'sound/machines/sm/accent/normal/8.ogg', 'sound/machines/sm/accent/normal/9.ogg', 'sound/machines/sm/accent/normal/10.ogg', 'sound/machines/sm/accent/normal/11.ogg', 'sound/machines/sm/accent/normal/12.ogg', 'sound/machines/sm/accent/normal/13.ogg', 'sound/machines/sm/accent/normal/14.ogg', 'sound/machines/sm/accent/normal/15.ogg', 'sound/machines/sm/accent/normal/16.ogg', 'sound/machines/sm/accent/normal/17.ogg', 'sound/machines/sm/accent/normal/18.ogg', 'sound/machines/sm/accent/normal/19.ogg', 'sound/machines/sm/accent/normal/20.ogg', 'sound/machines/sm/accent/normal/21.ogg', 'sound/machines/sm/accent/normal/22.ogg', 'sound/machines/sm/accent/normal/23.ogg', 'sound/machines/sm/accent/normal/24.ogg', 'sound/machines/sm/accent/normal/25.ogg', 'sound/machines/sm/accent/normal/26.ogg', 'sound/machines/sm/accent/normal/27.ogg', 'sound/machines/sm/accent/normal/28.ogg', 'sound/machines/sm/accent/normal/29.ogg', 'sound/machines/sm/accent/normal/30.ogg', 'sound/machines/sm/accent/normal/31.ogg', 'sound/machines/sm/accent/normal/32.ogg', 'sound/machines/sm/accent/normal/33.ogg') //END OF CIT CHANGES return soundin diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index 8559b8ba45..fd8f900552 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -2,34 +2,54 @@ //Please do not bother them with bugs from this port, however, as it has been modified quite a bit. //Modifications include removing the world-ending full supermatter variation, and leaving only the shard. +//Zap constants, speeds up targeting + +#define BIKE (COIL + 1) +#define COIL (ROD + 1) +#define ROD (LIVING + 1) +#define LIVING (MACHINERY + 1) +#define MACHINERY (OBJECT + 1) +#define OBJECT (LOWEST + 1) +#define LOWEST (1) + #define PLASMA_HEAT_PENALTY 15 // Higher == Bigger heat and waste penalty from having the crystal surrounded by this gas. Negative numbers reduce penalty. #define OXYGEN_HEAT_PENALTY 1 -#define CO2_HEAT_PENALTY 0.1 #define PLUOXIUM_HEAT_PENALTY -1 #define TRITIUM_HEAT_PENALTY 10 +#define CO2_HEAT_PENALTY 0.1 #define NITROGEN_HEAT_PENALTY -1.5 #define BZ_HEAT_PENALTY 5 +#define H2O_HEAT_PENALTY 8 +//#define FREON_HEAT_PENALTY -10 //very good heat absorbtion and less plasma and o2 generation +//#define HYDROGEN_HEAT_PENALTY 10 // similar heat penalty as tritium (dangerous) + +//All of these get divided by 10-bzcomp * 5 before having 1 added and being multiplied with power to determine rads +//Keep the negative values here above -10 and we won't get negative rads #define OXYGEN_TRANSMIT_MODIFIER 1.5 //Higher == Bigger bonus to power generation. #define PLASMA_TRANSMIT_MODIFIER 4 #define BZ_TRANSMIT_MODIFIER -2 +#define TRITIUM_TRANSMIT_MODIFIER 30 //We divide by 10, so this works out to 3 +#define PLUOXIUM_TRANSMIT_MODIFIER -5 //Should halve the power output +#define H2O_TRANSMIT_MODIFIER 2 +//#define HYDROGEN_TRANSMIT_MODIFIER 25 //increase the radiation emission, but less than the trit (2.5) -#define TRITIUM_RADIOACTIVITY_MODIFIER 3 //Higher == Crystal spews out more radiation -#define BZ_RADIOACTIVITY_MODIFIER 5 -#define PLUOXIUM_RADIOACTIVITY_MODIFIER -2 +#define BZ_RADIOACTIVITY_MODIFIER 5 //Improves the effect of transmit modifiers #define N2O_HEAT_RESISTANCE 6 //Higher == Gas makes the crystal more resistant against heat damage. #define PLUOXIUM_HEAT_RESISTANCE 3 +//#define HYDROGEN_HEAT_RESISTANCE 2 // just a bit of heat resistance to spice it up #define POWERLOSS_INHIBITION_GAS_THRESHOLD 0.20 //Higher == Higher percentage of inhibitor gas needed before the charge inertia chain reaction effect starts. #define POWERLOSS_INHIBITION_MOLE_THRESHOLD 20 //Higher == More moles of the gas are needed before the charge inertia chain reaction effect starts. //Scales powerloss inhibition down until this amount of moles is reached #define POWERLOSS_INHIBITION_MOLE_BOOST_THRESHOLD 500 //bonus powerloss inhibition boost if this amount of moles is reached -#define MOLE_PENALTY_THRESHOLD 1800 //Higher == Shard can absorb more moles before triggering the high mole penalties. +#define MOLE_PENALTY_THRESHOLD 1800 //Above this value we can get lord singulo and independent mol damage, below it we can heal damage #define MOLE_HEAT_PENALTY 350 //Heat damage scales around this. Too hot setups with this amount of moles do regular damage, anything above and below is scaled -#define POWER_PENALTY_THRESHOLD 5000 //Higher == Engine can generate more power before triggering the high power penalties. -#define SEVERE_POWER_PENALTY_THRESHOLD 7000 //Same as above, but causes more dangerous effects -#define CRITICAL_POWER_PENALTY_THRESHOLD 12000 //Even more dangerous effects, threshold for tesla delamination +//Along with damage_penalty_point, makes flux anomalies. +#define POWER_PENALTY_THRESHOLD 5000 //The cutoff on power properly doing damage, pulling shit around, and delamming into a tesla. Low chance of pyro anomalies, +2 bolts of electricity +#define SEVERE_POWER_PENALTY_THRESHOLD 7000 //+1 bolt of electricity, allows for gravitational anomalies, and higher chances of pyro anomalies +#define CRITICAL_POWER_PENALTY_THRESHOLD 9000 //+1 bolt of electricity. #define HEAT_PENALTY_THRESHOLD 40 //Higher == Crystal safe operational temperature is higher. #define DAMAGE_HARDCAP 0.002 #define DAMAGE_INCREASE_MULTIPLIER 0.25 @@ -66,6 +86,13 @@ #define SUPERMATTER_COUNTDOWN_TIME 30 SECONDS +///to prevent accent sounds from layering +#define SUPERMATTER_ACCENT_SOUND_MIN_COOLDOWN 2 SECONDS + +#define DEFAULT_ZAP_ICON_STATE "sm_arc" +#define SLIGHTLY_CHARGED_ZAP_ICON_STATE "sm_arc_supercharged" +#define OVER_9000_ZAP_ICON_STATE "sm_arc_dbz_referance" //Witty I know + GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) /obj/machinery/power/supermatter_crystal @@ -76,89 +103,183 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) density = TRUE anchored = TRUE flags_1 = PREVENT_CONTENTS_EXPLOSION_1 - var/uid = 1 - var/static/gl_uid = 1 light_range = 4 resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | FREEZE_PROOF - critical_machine = TRUE + ///The id of our supermatter + var/uid = 1 + ///The amount of supermatters that have been created this round + var/static/gl_uid = 1 + ///Tracks the bolt color we are using + var/zap_icon = DEFAULT_ZAP_ICON_STATE + ///The portion of the gasmix we're on that we should remove var/gasefficency = 0.15 - + ///Used for changing icon states for diff base sprites var/base_icon_state = "darkmatter" + ///Are we exploding? var/final_countdown = FALSE + ///The amount of damage we have currently var/damage = 0 + ///The damage we had before this cycle. Used to limit the damage we can take each cycle, and for safe_alert var/damage_archived = 0 + ///Our "Shit is no longer fucked" message. We send it when damage is less then damage_archived var/safe_alert = "Crystalline hyperstructure returning to safe operating parameters." + ///The point at which we should start sending messeges about the damage to the engi channels. var/warning_point = 50 + ///The alert we send when we've reached warning_point var/warning_alert = "Danger! Crystal hyperstructure integrity faltering!" - var/damage_penalty_point = 550 + ///The point at which we start sending messages to the common channel var/emergency_point = 700 + ///The alert we send when we've reached emergency_point var/emergency_alert = "CRYSTAL DELAMINATION IMMINENT." + ///The point at which we delam var/explosion_point = 900 + ///When we pass this amount of damage we start shooting bolts + var/damage_penalty_point = 550 - var/emergency_issued = FALSE - + ///A scaling value that affects the severity of explosions. var/explosion_power = 35 - var/temp_factor = 30 - - var/lastwarning = 0 // Time in 1/10th of seconds since the last sent warning + ///Time in 1/10th of seconds since the last sent warning + var/lastwarning = 0 + ///Refered to as eer on the moniter. This value effects gas output, heat, damage, and radiation. var/power = 0 - - var/n2comp = 0 // raw composition of each gas in the chamber, ranges from 0 to 1 - - var/plasmacomp = 0 - var/o2comp = 0 - var/co2comp = 0 - var/n2ocomp = 0 - var/pluoxiumcomp = 0 - var/tritiumcomp = 0 - var/bzcomp = 0 - - var/pluoxiumbonus = 0 - + ///Determines the rate of positve change in gas comp values + var/gas_change_rate = 0.05 + ///The list of gases we will be interacting with in process_atoms() + var/list/gases_we_care_about = list( + /datum/gas/oxygen, + /datum/gas/water_vapor, + /datum/gas/plasma, + /datum/gas/carbon_dioxide, + /datum/gas/nitrous_oxide, + /datum/gas/nitrogen, + /datum/gas/pluoxium, + /datum/gas/tritium, + /datum/gas/bz, +// /datum/gas/freon, +// /datum/gas/hydrogen, + ) + ///The list of gases mapped against their current comp. We use this to calculate different values the supermatter uses, like power or heat resistance. It doesn't perfectly match the air around the sm, instead moving up at a rate determined by gas_change_rate per call. Ranges from 0 to 1 + var/list/gas_comp = list( + /datum/gas/oxygen = 0, + /datum/gas/water_vapor = 0, + /datum/gas/plasma = 0, + /datum/gas/carbon_dioxide = 0, + /datum/gas/nitrous_oxide = 0, + /datum/gas/nitrogen = 0, + /datum/gas/pluoxium = 0, + /datum/gas/tritium = 0, + /datum/gas/bz = 0, +// /datum/gas/freon = 0, +// /datum/gas/hydrogen = 0, + ) + ///The list of gases mapped against their transmit values. We use it to determine the effect different gases have on radiation + var/list/gas_trans = list( + /datum/gas/oxygen = OXYGEN_TRANSMIT_MODIFIER, + /datum/gas/water_vapor = H2O_TRANSMIT_MODIFIER, + /datum/gas/plasma = PLASMA_TRANSMIT_MODIFIER, + /datum/gas/pluoxium = PLUOXIUM_TRANSMIT_MODIFIER, + /datum/gas/tritium = TRITIUM_TRANSMIT_MODIFIER, + /datum/gas/bz = BZ_TRANSMIT_MODIFIER, +// /datum/gas/hydrogen = HYDROGEN_TRANSMIT_MODIFIER, + ) + ///The list of gases mapped against their heat penaltys. We use it to determin molar and heat output + var/list/gas_heat = list( + /datum/gas/oxygen = OXYGEN_HEAT_PENALTY, + /datum/gas/water_vapor = H2O_HEAT_PENALTY, + /datum/gas/plasma = PLASMA_HEAT_PENALTY, + /datum/gas/carbon_dioxide = CO2_HEAT_PENALTY, + /datum/gas/nitrogen = NITROGEN_HEAT_PENALTY, + /datum/gas/pluoxium = PLUOXIUM_HEAT_PENALTY, + /datum/gas/tritium = TRITIUM_HEAT_PENALTY, + /datum/gas/bz = BZ_HEAT_PENALTY, +// /datum/gas/freon = FREON_HEAT_PENALTY, +// /datum/gas/hydrogen = HYDROGEN_HEAT_PENALTY, + ) + ///The list of gases mapped against their heat resistance. We use it to moderate heat damage. + var/list/gas_resist = list( + /datum/gas/nitrous_oxide = N2O_HEAT_RESISTANCE, + /datum/gas/pluoxium = PLUOXIUM_HEAT_RESISTANCE, +// /datum/gas/hydrogen = HYDROGEN_HEAT_RESISTANCE, + ) + ///The list of gases mapped against their powermix ratio + var/list/gas_powermix = list( + /datum/gas/oxygen = 1, + /datum/gas/water_vapor = 1, + /datum/gas/plasma = 1, + /datum/gas/carbon_dioxide = 1, + /datum/gas/nitrogen = -1, + /datum/gas/pluoxium = -1, + /datum/gas/tritium = 1, + /datum/gas/bz = 1, +// /datum/gas/freon = -1, +// /datum/gas/hydrogen = 1, + ) + ///The last air sample's total molar count, will always be above or equal to 0 var/combined_gas = 0 + ///Affects the power gain the sm experiances from heat var/gasmix_power_ratio = 0 + ///Affects the amount of o2 and plasma the sm outputs, along with the heat it makes. var/dynamic_heat_modifier = 1 + ///Affects the amount of damage and minimum point at which the sm takes heat damage var/dynamic_heat_resistance = 1 + ///Uses powerloss_dynamic_scaling and combined_gas to lessen the effects of our powerloss functions var/powerloss_inhibitor = 1 + ///Based on co2 percentage, slowly moves between 0 and 1. We use it to calc the powerloss_inhibitor var/powerloss_dynamic_scaling= 0 + ///Affects the amount of radiation the sm makes. We multiply this with power to find the rads. var/power_transmission_bonus = 0 + ///Used to increase or lessen the amount of damage the sm takes from heat based on molar counts. var/mole_heat_penalty = 0 - - + ///Takes the energy throwing things into the sm generates and slowly turns it into actual power var/matter_power = 0 + ///The cutoff for a bolt jumping, grows with heat, lowers with higher mol count, + var/zap_cutoff = 1500 + ///How much the bullets damage should be multiplied by when it is added to the internal variables + var/bullet_energy = 2 + ///How much hallucination should we produce per unit of power? + var/hallucination_power = 0.1 - //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 - + ///Our internal radio var/obj/item/radio/radio + ///The key our internal radio uses var/radio_key = /obj/item/encryptionkey/headset_eng + ///The engineering channel var/engineering_channel = "Engineering" + ///The common channel var/common_channel = null - //for logging + ///Boolean used for logging if we've been powered var/has_been_powered = FALSE + ///Boolean used for logging if we've passed the emergency point var/has_reached_emergency = FALSE - // For making hugbox supermatter - var/takes_damage = TRUE - var/produces_gas = TRUE + ///An effect we show to admins and ghosts the percentage of delam we're at var/obj/effect/countdown/supermatter/countdown + ///Used along with a global var to track if we can give out the sm sliver stealing objective var/is_main_engine = FALSE - + ///Our soundloop var/datum/looping_sound/supermatter/soundloop - + ///Can it be moved? var/moveable = FALSE + ///cooldown tracker for accent sounds + var/last_accent_sound = 0 + + //For making hugbox supermatters + ///Disables all methods of taking damage + var/takes_damage = TRUE + ///Disables the production of gas, and pretty much any handling of it we do. + var/produces_gas = TRUE + ///Disables power changes + var/power_changes = TRUE + ///Disables the sm's proccessing totally. + var/processes = TRUE + /obj/machinery/power/supermatter_crystal/Initialize() . = ..() uid = gl_uid++ @@ -174,6 +295,9 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) if(is_main_engine) GLOB.main_supermatter_engine = src + AddElement(/datum/element/bsa_blocker) + RegisterSignal(src, COMSIG_ATOM_BSA_BEAM, .proc/call_explode) + soundloop = new(list(src), TRUE) /obj/machinery/power/supermatter_crystal/Destroy() @@ -184,12 +308,11 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) QDEL_NULL(countdown) if(is_main_engine && GLOB.main_supermatter_engine == src) GLOB.main_supermatter_engine = null - QDEL_NULL(soundloop) return ..() /obj/machinery/power/supermatter_crystal/examine(mob/user) . = ..() - if (iscarbon(user)) + if (istype(user, /mob/living/carbon)) var/mob/living/carbon/C = user if (!istype(C.glasses, /obj/item/clothing/glasses/meson) && (get_dist(user, src) < HALLUCINATION_RANGE(power))) . += "You get headaches just from looking at it." @@ -202,16 +325,17 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) if(!air) return SUPERMATTER_ERROR - if(get_integrity() < SUPERMATTER_DELAM_PERCENT) + var/integrity = get_integrity() + if(integrity < SUPERMATTER_DELAM_PERCENT) return SUPERMATTER_DELAMINATING - if(get_integrity() < SUPERMATTER_EMERGENCY_PERCENT) + if(integrity < SUPERMATTER_EMERGENCY_PERCENT) return SUPERMATTER_EMERGENCY - if(get_integrity() < SUPERMATTER_DANGER_PERCENT) + if(integrity < SUPERMATTER_DANGER_PERCENT) return SUPERMATTER_DANGER - if((get_integrity() < SUPERMATTER_WARNING_PERCENT) || (air.return_temperature() > CRITICAL_TEMPERATURE)) + if((integrity < SUPERMATTER_WARNING_PERCENT) || (air.return_temperature() > CRITICAL_TEMPERATURE)) return SUPERMATTER_WARNING if(air.return_temperature() > (CRITICAL_TEMPERATURE * 0.8)) @@ -238,23 +362,26 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) integrity = integrity < 0 ? 0 : integrity return integrity +/obj/machinery/power/supermatter_crystal/update_overlays() + . = ..() + if(final_countdown) + . += "casuality_field" + /obj/machinery/power/supermatter_crystal/proc/countdown() set waitfor = FALSE if(final_countdown) // We're already doing it go away return final_countdown = TRUE - - var/image/causality_field = image(icon, null, "causality_field") - add_overlay(causality_field, TRUE) + update_icon() var/speaking = "[emergency_alert] The supermatter has reached critical integrity failure. Emergency causality destabilization field has been activated." radio.talk_into(src, speaking, common_channel, language = get_selected_language()) for(var/i in SUPERMATTER_COUNTDOWN_TIME to 0 step -10) if(damage < explosion_point) // Cutting it a bit close there engineers radio.talk_into(src, "[safe_alert] Failsafe has been disengaged.", common_channel) - cut_overlay(causality_field, TRUE) final_countdown = FALSE + update_icon() return else if((i % 50) != 0 && i > 50) // A message once every 5 seconds until the final 5 seconds which count down individualy sleep(10) @@ -287,48 +414,65 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "delam", /datum/mood_event/delam) if(combined_gas > MOLE_PENALTY_THRESHOLD) investigate_log("has collapsed into a singularity.", INVESTIGATE_SUPERMATTER) - if(T) + if(T) //If something fucks up we blow anyhow. This fix is 4 years old and none ever said why it's here. help. var/obj/singularity/S = new(T) S.energy = 800 S.consume(src) - else - investigate_log("has exploded.", INVESTIGATE_SUPERMATTER) - explosion(get_turf(T), explosion_power * max(gasmix_power_ratio, 0.205) * 0.5 , explosion_power * max(gasmix_power_ratio, 0.205) + 2, explosion_power * max(gasmix_power_ratio, 0.205) + 4 , explosion_power * max(gasmix_power_ratio, 0.205) + 6, 1, 1) - if(power > POWER_PENALTY_THRESHOLD) - investigate_log("has spawned additional energy balls.", INVESTIGATE_SUPERMATTER) + return //No boom for me sir + else if(power > POWER_PENALTY_THRESHOLD) + investigate_log("has spawned additional energy balls.", INVESTIGATE_SUPERMATTER) + if(T) var/obj/singularity/energy_ball/E = new(T) E.energy = power - qdel(src) + investigate_log("has exploded.", INVESTIGATE_SUPERMATTER) + //Dear mappers, balance the sm max explosion radius to 17.5, 37, 39, 41 + explosion(get_turf(T), explosion_power * max(gasmix_power_ratio, 0.205) * 0.5 , explosion_power * max(gasmix_power_ratio, 0.205) + 2, explosion_power * max(gasmix_power_ratio, 0.205) + 4 , explosion_power * max(gasmix_power_ratio, 0.205) + 6, 1, 1) + qdel(src) -/obj/machinery/power/supermatter_crystal/proc/consume_turf(turf/T) - var/oldtype = T.type - var/turf/newT = T.ScrapeAway() - if(newT.type == oldtype) - return - playsound(T, 'sound/effects/supermatter.ogg', 50, 1) - T.visible_message("[T] smacks into [src] and rapidly flashes to ash.",\ - "You hear a loud crack as you are washed with a wave of heat.") - CALCULATE_ADJACENT_TURFS(T) + +//this is here to eat arguments +/obj/machinery/power/supermatter_crystal/proc/call_explode() + explode() /obj/machinery/power/supermatter_crystal/process_atmos() + if(!processes) //Just fuck me up bro + return var/turf/T = loc - if(isnull(T)) // We have a null turf...something is wrong, stop processing this entity. + if(isnull(T))// We have a null turf...something is wrong, stop processing this entity. return PROCESS_KILL - if(!istype(T)) //We are in a crate or somewhere that isn't turf, if we return to turf resume processing but for now. + if(!istype(T))//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. - if(istype(T, /turf/closed)) - consume_turf(T) + if(isclosedturf(T)) + var/turf/did_it_melt = T.Melt() + if(!isclosedturf(did_it_melt)) //In case some joker finds way to place these on indestructible walls + visible_message("[src] melts through [T]!") + return + + //We vary volume by power, and handle OH FUCK FUSION IN COOLING LOOP noises. if(power) - soundloop.volume = min(40, (round(power/100)/50)+1) // 5 +1 volume per 20 power. 2500 power is max + soundloop.volume = clamp((50 + (power / 50)), 50, 100) + if(damage >= 300) + soundloop.mid_sounds = list('sound/machines/sm/loops/delamming.ogg' = 1) + else + soundloop.mid_sounds = list('sound/machines/sm/loops/calm.ogg' = 1) + + //We play delam/neutral sounds at a rate determined by power and damage + if(last_accent_sound < world.time && prob(20)) + var/aggression = min(((damage / 800) * (power / 2500)), 1.0) * 100 + if(damage >= 300) + playsound(src, "smdelam", max(50, aggression), FALSE, 10) + else + playsound(src, "smcalm", max(50, aggression), FALSE, 10) + var/next_sound = round((100 - aggression) * 5) + last_accent_sound = world.time + max(SUPERMATTER_ACCENT_SOUND_MIN_COOLDOWN, next_sound) //Ok, get the air from the turf var/datum/gas_mixture/env = T.return_air() var/datum/gas_mixture/removed - if(produces_gas) //Remove gas from surrounding area removed = env.remove(gasefficency * env.total_moles()) @@ -336,141 +480,240 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) // Pass all the gas related code an empty gas container removed = new() damage_archived = damage + + /******** + EXPERIMENTAL, HUGBOXY AS HELL CITADEL CHANGES: Even in a vaccum, update gas composition and modifiers. + This means that the SM will usually have a very small explosion if it ends up being breached to space, + and CO2 tesla delaminations basically require multiple grounding rods to stabilize it long enough to not have it vent. + *********/ + if(!removed || !removed.total_moles() || isspaceturf(T)) //we're in space or there is no gas to process if(takes_damage) damage += max((power / 1000) * DAMAGE_INCREASE_MULTIPLIER, 0.1) // always does at least some damage + combined_gas = max(0, combined_gas - 0.5) // Slowly wear off. + for(var/gasID in gases_we_care_about) + gas_comp[gasID] = max(0, gas_comp[gasID] - 0.05) //slowly ramp down else if(takes_damage) //causing damage + //Due to DAMAGE_INCREASE_MULTIPLIER, we only deal one 4th of the damage the statements otherwise would cause + + //((((some value between 0.5 and 1 * temp - ((273.15 + 40) * some values between 1 and 10)) * some number between 0.25 and knock your socks off / 150) * 0.25 + //Heat and mols account for each other, a lot of hot mols are more damaging then a few + //Mols start to have a positive effect on damage after 350 damage = max(damage + (max(clamp(removed.total_moles() / 200, 0.5, 1) * removed.return_temperature() - ((T0C + HEAT_PENALTY_THRESHOLD)*dynamic_heat_resistance), 0) * mole_heat_penalty / 150 ) * DAMAGE_INCREASE_MULTIPLIER, 0) + //Power only starts affecting damage when it is above 5000 damage = max(damage + (max(power - POWER_PENALTY_THRESHOLD, 0)/500) * DAMAGE_INCREASE_MULTIPLIER, 0) + //Molar count only starts affecting damage when it is above 1800 damage = max(damage + (max(combined_gas - MOLE_PENALTY_THRESHOLD, 0)/80) * DAMAGE_INCREASE_MULTIPLIER, 0) + //There might be a way to integrate healing and hurting via heat //healing damage if(combined_gas < MOLE_PENALTY_THRESHOLD) - damage = max(damage + (min(removed.return_temperature() - (T0C + HEAT_PENALTY_THRESHOLD), 0) / 150 ), 0) + //Only has a net positive effect when the temp is below 313.15, heals up to 2 damage. Psycologists increase this temp min by up to 45 + damage = max(damage + (min(removed.return_temperature() - (T0C + HEAT_PENALTY_THRESHOLD), 0) / 150), 0) - //capping damage - damage = min(damage_archived + (DAMAGE_HARDCAP * explosion_point),damage) - if(damage > damage_archived && prob(10)) - playsound(get_turf(src), 'sound/effects/empulse.ogg', 50, 1) + //caps damage rate - //calculating gas related values - combined_gas = max(removed.total_moles(), 0) + //Takes the lower number between archived damage + (1.8) and damage + //This means we can only deal 1.8 damage per function call + damage = min(damage_archived + (DAMAGE_HARDCAP * explosion_point), damage) - plasmacomp = max(removed.get_moles(/datum/gas/plasma)/combined_gas, 0) - o2comp = max(removed.get_moles(/datum/gas/oxygen)/combined_gas, 0) - co2comp = max(removed.get_moles(/datum/gas/carbon_dioxide)/combined_gas, 0) - tritiumcomp = max(removed.get_moles(/datum/gas/tritium)/combined_gas, 0) - bzcomp = max(removed.get_moles(/datum/gas/bz)/combined_gas, 0) + //calculating gas related values + //Wanna know a secret? See that max() to zero? it's used for error checking. If we get a mol count in the negative, we'll get a divide by zero error + combined_gas = max(removed.total_moles(), 0) - pluoxiumcomp = max(removed.get_moles(/datum/gas/pluoxium)/combined_gas, 0) - n2ocomp = max(removed.get_moles(/datum/gas/nitrous_oxide)/combined_gas, 0) - n2comp = max(removed.get_moles(/datum/gas/nitrogen)/combined_gas, 0) + //This is more error prevention, according to all known laws of atmos, gas_mix.remove() should never make negative mol values. + //But this is tg - if(pluoxiumcomp >= 0.15) - pluoxiumbonus = 1 //makes pluoxium only work at 15%+ - else - pluoxiumbonus = 0 + //Lets get the proportions of the gasses in the mix and then slowly move our comp to that value + //Can cause an overestimation of mol count, should stabalize things though. + //Prevents huge bursts of gas/heat when a large amount of something is introduced + //They range between 0 and 1 + for(var/gasID in gases_we_care_about) + gas_comp[gasID] += clamp(max(removed.get_moles(gasID)/combined_gas, 0) - gas_comp[gasID], -1, gas_change_rate) - gasmix_power_ratio = min(max(plasmacomp + o2comp + co2comp + tritiumcomp + bzcomp - pluoxiumcomp - n2comp, 0), 1) + var/list/heat_mod = gases_we_care_about.Copy() + var/list/transit_mod = gases_we_care_about.Copy() + var/list/resistance_mod = gases_we_care_about.Copy() - dynamic_heat_modifier = max((plasmacomp * PLASMA_HEAT_PENALTY) + (o2comp * OXYGEN_HEAT_PENALTY) + (co2comp * CO2_HEAT_PENALTY) + (tritiumcomp * TRITIUM_HEAT_PENALTY) + ((pluoxiumcomp * PLUOXIUM_HEAT_PENALTY) * pluoxiumbonus) + (n2comp * NITROGEN_HEAT_PENALTY) + (bzcomp * BZ_HEAT_PENALTY), 0.5) - dynamic_heat_resistance = max((n2ocomp * N2O_HEAT_RESISTANCE) + ((pluoxiumcomp * PLUOXIUM_HEAT_RESISTANCE) * pluoxiumbonus), 1) + //We're concerned about pluoxium being too easy to abuse at low percents, so we make sure there's a substantial amount. + var/pluoxiumbonus = (gas_comp[/datum/gas/pluoxium] >= 0.15) //makes pluoxium only work at 15%+ + var/h2obonus = 1 - (gas_comp[/datum/gas/water_vapor] * 0.25)//At max this value should be 0.75 +// var/freonbonus = (gas_comp[/datum/gas/freon] <= 0.03) //Let's just yeet power output if this shit is high - power_transmission_bonus = max((plasmacomp * PLASMA_TRANSMIT_MODIFIER) + (o2comp * OXYGEN_TRANSMIT_MODIFIER) + (bzcomp * BZ_TRANSMIT_MODIFIER), 0) + heat_mod[/datum/gas/pluoxium] = pluoxiumbonus + transit_mod[/datum/gas/pluoxium] = pluoxiumbonus + resistance_mod[/datum/gas/pluoxium] = pluoxiumbonus - //more moles of gases are harder to heat than fewer, so let's scale heat damage around them - mole_heat_penalty = max(combined_gas / MOLE_HEAT_PENALTY, 0.25) + //No less then zero, and no greater then one, we use this to do explosions and heat to power transfer + //Be very careful with modifing this var by large amounts, and for the love of god do not push it past 1 + gasmix_power_ratio = 0 + for(var/gasID in gas_powermix) + gasmix_power_ratio += gas_comp[gasID] * gas_powermix[gasID] + gasmix_power_ratio = clamp(gasmix_power_ratio, 0, 1) - if (combined_gas > POWERLOSS_INHIBITION_MOLE_THRESHOLD && co2comp > POWERLOSS_INHIBITION_GAS_THRESHOLD) - powerloss_dynamic_scaling = clamp(powerloss_dynamic_scaling + clamp(co2comp - powerloss_dynamic_scaling, -0.02, 0.02), 0, 1) - else - powerloss_dynamic_scaling = clamp(powerloss_dynamic_scaling - 0.05,0, 1) - powerloss_inhibitor = clamp(1-(powerloss_dynamic_scaling * clamp(combined_gas/POWERLOSS_INHIBITION_MOLE_BOOST_THRESHOLD,1 ,1.5)),0 ,1) + //Minimum value of -10, maximum value of 23. Effects plasma and o2 output and the output heat + dynamic_heat_modifier = 0 + for(var/gasID in gas_heat) + dynamic_heat_modifier += gas_comp[gasID] * gas_heat[gasID] * (isnull(heat_mod[gasID]) ? 1 : heat_mod[gasID]) + dynamic_heat_modifier *= h2obonus + dynamic_heat_modifier = max(dynamic_heat_modifier, 0.5) - if(matter_power) - var/removed_matter = max(matter_power/MATTER_POWER_CONVERSION, 40) - power = max(power + removed_matter, 0) - matter_power = max(matter_power - removed_matter, 0) + //Value between 1 and 10. Effects the damage heat does to the crystal + dynamic_heat_resistance = 0 + for(var/gasID in gas_resist) + dynamic_heat_resistance += gas_comp[gasID] * gas_resist[gasID] * (isnull(resistance_mod[gasID]) ? 1 : resistance_mod[gasID]) + dynamic_heat_resistance = max(dynamic_heat_resistance, 1) - var/temp_factor = 50 + //Value between -5 and 30, used to determine radiation output as it concerns things like collectors. + power_transmission_bonus = 0 + for(var/gasID in gas_trans) + power_transmission_bonus += gas_comp[gasID] * gas_trans[gasID] * (isnull(transit_mod[gasID]) ? 1 : transit_mod[gasID]) + power_transmission_bonus *= h2obonus - if(gasmix_power_ratio > 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 = 30 - icon_state = base_icon_state + //more moles of gases are harder to heat than fewer, so let's scale heat damage around them + mole_heat_penalty = max(combined_gas / MOLE_HEAT_PENALTY, 0.25) - power = max( (removed.return_temperature() * temp_factor / T0C) * gasmix_power_ratio + power, 0) //Total laser power plus an overload + //Ramps up or down in increments of 0.02 up to the proportion of co2 + //Given infinite time, powerloss_dynamic_scaling = co2comp + //Some value between 0 and 1 + if (combined_gas > POWERLOSS_INHIBITION_MOLE_THRESHOLD && gas_comp[/datum/gas/carbon_dioxide] > POWERLOSS_INHIBITION_GAS_THRESHOLD) //If there are more then 20 mols, and more then 20% co2 + powerloss_dynamic_scaling = clamp(powerloss_dynamic_scaling + clamp(gas_comp[/datum/gas/carbon_dioxide] - powerloss_dynamic_scaling, -0.02, 0.02), 0, 1) + else + powerloss_dynamic_scaling = clamp(powerloss_dynamic_scaling - 0.05, 0, 1) + //Ranges from 0 to 1(1-(value between 0 and 1 * ranges from 1 to 1.5(mol / 500))) + //We take the mol count, and scale it to be our inhibitor + powerloss_inhibitor = clamp(1-(powerloss_dynamic_scaling * clamp(combined_gas/POWERLOSS_INHIBITION_MOLE_BOOST_THRESHOLD, 1, 1.5)), 0, 1) - if(prob(50)) - radiation_pulse(src, power * (1 + (tritiumcomp * TRITIUM_RADIOACTIVITY_MODIFIER) + ((pluoxiumcomp * PLUOXIUM_RADIOACTIVITY_MODIFIER) * pluoxiumbonus) * (power_transmission_bonus/(10-(bzcomp * BZ_RADIOACTIVITY_MODIFIER))))) // Rad Modifiers BZ(500%), Tritium(300%), and Pluoxium(-200%) - if(bzcomp >= 0.4 && prob(30 * bzcomp)) - fire_nuclear_particle() // Start to emit radballs at a maximum of 30% chance per tick + //Releases stored power into the general pool + //We get this by consuming shit or being scalpeled + if(matter_power && power_changes) + //We base our removed power off one 10th of the matter_power. + var/removed_matter = max(matter_power/MATTER_POWER_CONVERSION, 40) + //Adds at least 40 power + power = max(power + removed_matter, 0) + //Removes at least 40 matter power + matter_power = max(matter_power - removed_matter, 0) - var/device_energy = power * REACTION_POWER_MODIFIER + var/temp_factor = 50 + if(gasmix_power_ratio > 0.8) + //with a perfect gas mix, make the power more based on heat + icon_state = "[base_icon_state]_glow" + else + //in normal mode, power is less effected by heat + temp_factor = 30 + icon_state = base_icon_state - //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" + //if there is more pluox and n2 then anything else, we receive no power increase from heat + if(power_changes) + power = max((removed.return_temperature() * temp_factor / T0C) * gasmix_power_ratio + power, 0) - //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.set_temperature(removed.return_temperature() + ((device_energy * dynamic_heat_modifier) / THERMAL_RELEASE_MODIFIER)) + if(prob(50)) + //(1 + (tritRad + pluoxDampen * bzDampen * o2Rad * plasmaRad / (10 - bzrads))) * freonbonus + radiation_pulse(src, power * max(0, (1 + (power_transmission_bonus/(10-(gas_comp[/datum/gas/bz] * BZ_RADIOACTIVITY_MODIFIER)))) * 1))//freonbonus))// RadModBZ(500%) + if(gas_comp[/datum/gas/bz] >= 0.4 && prob(30 * gas_comp[/datum/gas/bz])) + src.fire_nuclear_particle() // Start to emit radballs at a maximum of 30% chance per tick - removed.set_temperature(max(0, min(removed.return_temperature(), 2500 * dynamic_heat_modifier))) + //Power * 0.55 * a value between 1 and 0.8 + var/device_energy = power * REACTION_POWER_MODIFIER - //Calculate how much gas to release - removed.adjust_moles(/datum/gas/plasma, max((device_energy * dynamic_heat_modifier) / PLASMA_RELEASE_MODIFIER, 0)) + //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.adjust_moles(/datum/gas/oxygen, max(((device_energy + removed.return_temperature() * dynamic_heat_modifier) - T0C) / OXYGEN_RELEASE_MODIFIER, 0)) + //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. + //Power * 0.55 * (some value between 1.5 and 23) / 5 + removed.set_temperature(removed.return_temperature() + ((device_energy * dynamic_heat_modifier) / THERMAL_RELEASE_MODIFIER)) + //We can only emit so much heat, that being 57500 + removed.set_temperature(max(0, min(removed.return_temperature(), 2500 * dynamic_heat_modifier))) - if(produces_gas) - env.merge(removed) - air_update_turf() + //Calculate how much gas to release + //Varies based on power and gas content + removed.adjust_moles(/datum/gas/plasma, max((device_energy * dynamic_heat_modifier) / PLASMA_RELEASE_MODIFIER, 0)) + //Varies based on power, gas content, and heat + removed.adjust_moles(/datum/gas/oxygen, max(((device_energy + removed.return_temperature() * dynamic_heat_modifier) - T0C) / OXYGEN_RELEASE_MODIFIER, 0)) - for(var/mob/living/carbon/human/l in fov_viewers(HALLUCINATION_RANGE(power), src)) // If they can see it without mesons on. Bad on them. + if(produces_gas) + env.merge(removed) + air_update_turf() + + /********* + END CITADEL CHANGES + *********/ + + //Makes em go mad and accumulate rads. + for(var/mob/living/carbon/human/l in fov_viewers(src, HALLUCINATION_RANGE(power))) // If they can see it without mesons on. Bad on them. if(!istype(l.glasses, /obj/item/clothing/glasses/meson)) var/D = sqrt(1 / max(1, get_dist(l, src))) - l.hallucination += power * config_hallucination_power * D - l.hallucination = clamp(0, 200, l.hallucination) - + l.hallucination += power * hallucination_power * D + l.hallucination = clamp(l.hallucination, 0, 200) for(var/mob/living/l in range(src, round((power / 100) ** 0.25))) var/rads = (power / 10) * sqrt( 1 / max(get_dist(l, src),1) ) l.rad_act(rads) - power -= ((power/500)**3) * powerloss_inhibitor + //Transitions between one function and another, one we use for the fast inital startup, the other is used to prevent errors with fusion temperatures. + //Use of the second function improves the power gain imparted by using co2 + if(power_changes) + power = max(power - min(((power/500)**3) * powerloss_inhibitor, power * 0.83 * powerloss_inhibitor),0) + //After this point power is lowered + //This wraps around to the begining of the function + //Handle high power zaps/anomaly generation + if(power > POWER_PENALTY_THRESHOLD || damage > damage_penalty_point) //If the power is above 5000 or if the damage is above 550 + var/range = 4 + zap_cutoff = 1500 + if(removed && removed.return_pressure() > 0 && removed.return_temperature() > 0) + //You may be able to freeze the zapstate of the engine with good planning, we'll see + zap_cutoff = clamp(3000 - (power * (removed.total_moles()) / 10) / removed.return_temperature(), 350, 3000)//If the core is cold, it's easier to jump, ditto if there are a lot of mols + //We should always be able to zap our way out of the default enclosure + //See supermatter_zap() for more details + range = clamp(power / removed.return_pressure() * 10, 2, 7) + var/flags = ZAP_SUPERMATTER_FLAGS + var/zap_count = 0 + //Deal with power zaps + switch(power) + if(POWER_PENALTY_THRESHOLD to SEVERE_POWER_PENALTY_THRESHOLD) + zap_icon = DEFAULT_ZAP_ICON_STATE + zap_count = 2 + if(SEVERE_POWER_PENALTY_THRESHOLD to CRITICAL_POWER_PENALTY_THRESHOLD) + zap_icon = SLIGHTLY_CHARGED_ZAP_ICON_STATE + //Uncaps the zap damage, it's maxed by the input power + //Objects take damage now + flags |= (ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE) + zap_count = 3 + if(CRITICAL_POWER_PENALTY_THRESHOLD to INFINITY) + zap_icon = OVER_9000_ZAP_ICON_STATE + //It'll stun more now, and damage will hit harder, gloves are no garentee. + //Machines go boom + flags |= (ZAP_MOB_STUN | ZAP_MACHINE_EXPLOSIVE | ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE) + zap_count = 4 + //Now we deal with damage shit + if (damage > damage_penalty_point && prob(20)) + zap_count += 1 - if(power > POWER_PENALTY_THRESHOLD || damage > damage_penalty_point) + if(zap_count >= 1) + playsound(src.loc, 'sound/weapons/emitter2.ogg', 100, TRUE, extrarange = 10) + for(var/i in 1 to zap_count) + supermatter_zap(src, range, clamp(power*2, 4000, 20000), flags) - if(power > POWER_PENALTY_THRESHOLD) - playsound(src.loc, 'sound/weapons/emitter2.ogg', 100, 1, extrarange = 10) - supermatter_zap(src, 5, min(power*2, 20000)) - supermatter_zap(src, 5, min(power*2, 20000)) - if(power > SEVERE_POWER_PENALTY_THRESHOLD) - supermatter_zap(src, 5, min(power*2, 20000)) - if(power > CRITICAL_POWER_PENALTY_THRESHOLD) - supermatter_zap(src, 5, min(power*2, 20000)) - else if (damage > damage_penalty_point && prob(20)) - playsound(src.loc, 'sound/weapons/emitter2.ogg', 100, 1, extrarange = 10) - supermatter_zap(src, 5, clamp(power*2, 4000, 20000)) - - if(prob(15) && power > POWER_PENALTY_THRESHOLD) - supermatter_pull(src, power/750) if(prob(5)) supermatter_anomaly_gen(src, FLUX_ANOMALY, rand(5, 10)) if(power > SEVERE_POWER_PENALTY_THRESHOLD && prob(5) || prob(1)) supermatter_anomaly_gen(src, GRAVITATIONAL_ANOMALY, rand(5, 10)) - if(power > SEVERE_POWER_PENALTY_THRESHOLD && prob(2) || prob(0.3) && power > POWER_PENALTY_THRESHOLD) + if((power > SEVERE_POWER_PENALTY_THRESHOLD && prob(2)) || (prob(0.3) && power > POWER_PENALTY_THRESHOLD)) supermatter_anomaly_gen(src, PYRO_ANOMALY, rand(5, 10)) + + if(prob(15)) + supermatter_pull(loc, min(power/850, 3))//850, 1700, 2550 + + //Tells the engi team to get their butt in gear if(damage > warning_point) // while the core is still damaged and it's still worth noting its status if((REALTIMEOFDAY - lastwarning) / 10 >= WARNING_DELAY) alarm() + //Oh shit it's bad, time to freak out if(damage > emergency_point) radio.talk_into(src, "[emergency_alert] Integrity: [get_integrity()]%", common_channel) lastwarning = REALTIMEOFDAY @@ -493,7 +736,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) if(combined_gas > MOLE_PENALTY_THRESHOLD) radio.talk_into(src, "Warning: Critical coolant mass reached.", engineering_channel) - + //Boom (Mind blown) if(damage > explosion_point) countdown() @@ -503,16 +746,17 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) var/turf/L = loc if(!istype(L)) return FALSE - if(!istype(Proj.firer, /obj/machinery/power/emitter)) + if(!istype(Proj.firer, /obj/machinery/power/emitter) && power_changes) investigate_log("has been hit by [Proj] fired by [key_name(Proj.firer)]", INVESTIGATE_SUPERMATTER) if(Proj.flag != "bullet") - power += Proj.damage * config_bullet_energy - if(!has_been_powered) - investigate_log("has been powered for the first time.", INVESTIGATE_SUPERMATTER) - message_admins("[src] has been powered for the first time [ADMIN_JMP(src)].") - has_been_powered = TRUE + if(power_changes) //This needs to be here I swear + power += Proj.damage * bullet_energy + if(!has_been_powered) + investigate_log("has been powered for the first time.", INVESTIGATE_SUPERMATTER) + message_admins("[src] has been powered for the first time [ADMIN_JMP(src)].") + has_been_powered = TRUE else if(takes_damage) - matter_power += Proj.damage * config_bullet_energy + matter_power += Proj.damage * bullet_energy return BULLET_ACT_HIT /obj/machinery/power/supermatter_crystal/singularity_act() @@ -529,15 +773,15 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) /obj/machinery/power/supermatter_crystal/blob_act(obj/structure/blob/B) if(B && !isspaceturf(loc)) //does nothing in space - playsound(get_turf(src), 'sound/effects/supermatter.ogg', 50, 1) + playsound(get_turf(src), 'sound/effects/supermatter.ogg', 50, TRUE) damage += B.obj_integrity * 0.5 //take damage equal to 50% of remaining blob health before it tried to eat us if(B.obj_integrity > 100) B.visible_message("\The [B] strikes at \the [src] and flinches away!",\ - "You hear a loud crack as you are washed with a wave of heat.") + "You hear a loud crack as you are washed with a wave of heat.") B.take_damage(100, BURN) else B.visible_message("\The [B] strikes at \the [src] and rapidly flashes to ash.",\ - "You hear a loud crack as you are washed with a wave of heat.") + "You hear a loud crack as you are washed with a wave of heat.") Consume(B) /obj/machinery/power/supermatter_crystal/attack_tk(mob/user) @@ -546,11 +790,10 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) log_game("[key_name(C)] has been disintegrated by a telekenetic grab on a supermatter crystal.") to_chat(C, "That was a really dense idea.") C.visible_message("A bright flare of radiation is seen from [C]'s head, shortly before you hear a sickening sizzling!") + C.ghostize() var/obj/item/organ/brain/rip_u = locate(/obj/item/organ/brain) in C.internal_organs - rip_u.Remove() + rip_u.Remove(C) qdel(rip_u) - return - return ..() /obj/machinery/power/supermatter_crystal/attack_paw(mob/user) dust_mob(user, cause = "monkey attack") @@ -559,9 +802,14 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) dust_mob(user, cause = "alien attack") /obj/machinery/power/supermatter_crystal/attack_animal(mob/living/simple_animal/S) + var/murder + if(!S.melee_damage_upper && !S.melee_damage_lower) + murder = S.friendly_verb_continuous + else + murder = S.attack_verb_continuous dust_mob(S, \ - "[S] unwisely [S.attack_verb_continuous] [src], and [S.p_their()] body burns brilliantly before flashing into ash!", \ - "You unwisely [S.attack_verb_simple] [src], and your vision glows brightly as your body crumbles to dust. Oops.", \ + "[S] unwisely [murder] [src], and [S.p_their()] body burns brilliantly before flashing into ash!", \ + "You unwisely touch [src], and your vision glows brightly as your body crumbles to dust. Oops.", \ "simple animal attack") /obj/machinery/power/supermatter_crystal/attack_robot(mob/user) @@ -571,65 +819,103 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) /obj/machinery/power/supermatter_crystal/attack_ai(mob/user) return -/obj/machinery/power/supermatter_crystal/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) +/obj/machinery/power/supermatter_crystal/on_attack_hand(mob/living/user) . = ..() - if(.) - return dust_mob(user, cause = "hand") /obj/machinery/power/supermatter_crystal/proc/dust_mob(mob/living/nom, vis_msg, mob_msg, cause) - if(nom.incorporeal_move || nom.status_flags & GODMODE) + if(nom.incorporeal_move || nom.status_flags & GODMODE) //try to keep supermatter sliver's + hemostat's dust conditions in sync with this too return if(!vis_msg) - vis_msg = "[nom] reaches out and touches [src], inducing a resonance... [nom.p_their()] body starts to glow and bursts into flames before flashing into ash" + vis_msg = "[nom] reaches out and touches [src], inducing a resonance... [nom.p_their()] body starts to glow and burst into flames before flashing into dust!" if(!mob_msg) mob_msg = "You reach out and touch [src]. Everything starts burning and all you can hear is ringing. Your last thought is \"That was not a wise decision.\"" if(!cause) cause = "contact" - nom.visible_message(vis_msg, mob_msg, "You hear an unearthly noise as a wave of heat washes over you.") + nom.visible_message(vis_msg, mob_msg, "You hear an unearthly noise as a wave of heat washes over you.") investigate_log("has been attacked ([cause]) by [key_name(nom)]", INVESTIGATE_SUPERMATTER) - playsound(get_turf(src), 'sound/effects/supermatter.ogg', 50, 1) + playsound(get_turf(src), 'sound/effects/supermatter.ogg', 50, TRUE) Consume(nom) /obj/machinery/power/supermatter_crystal/attackby(obj/item/W, mob/living/user, params) if(!istype(W) || (W.item_flags & ABSTRACT) || !istype(user)) return - if (istype(W, /obj/item/melee/roastingstick)) + if(istype(W, /obj/item/melee/roastingstick)) return ..() + if(istype(W, /obj/item/clothing/mask/cigarette)) + var/obj/item/clothing/mask/cigarette/cig = W + var/clumsy = HAS_TRAIT(user, TRAIT_CLUMSY) + if(clumsy) + var/which_hand = BODY_ZONE_L_ARM + if(!(user.active_hand_index % 2)) + which_hand = BODY_ZONE_R_ARM + var/obj/item/bodypart/dust_arm = user.get_bodypart(which_hand) + dust_arm.dismember() + user.visible_message("The [W] flashes out of existence on contact with \the [src], resonating with a horrible sound...",\ + "Oops! The [W] flashes out of existence on contact with \the [src], taking your arm with it! That was clumsy of you!") + playsound(src, 'sound/effects/supermatter.ogg', 150, TRUE) + Consume(dust_arm) + qdel(W) + return + if(cig.lit || user.a_intent != INTENT_HELP) + user.visible_message("A hideous sound echoes as [W] is ashed out on contact with \the [src]. That didn't seem like a good idea...") + playsound(src, 'sound/effects/supermatter.ogg', 150, TRUE) + Consume(W) + radiation_pulse(src, 150, 4) + return ..() + else + cig.light() + user.visible_message("As [user] lights \their [W] on \the [src], silence fills the room...",\ + "Time seems to slow to a crawl as you touch \the [src] with \the [W].\n\The [W] flashes alight with an eerie energy as you nonchalantly lift your hand away from \the [src]. Damn.") + playsound(src, 'sound/effects/supermatter.ogg', 50, TRUE) + radiation_pulse(src, 50, 3) + return if(istype(W, /obj/item/scalpel/supermatter)) + var/obj/item/scalpel/supermatter/scalpel = W to_chat(user, "You carefully begin to scrape \the [src] with \the [W]...") if(W.use_tool(src, user, 60, volume=100)) - to_chat(user, "You extract a sliver from \the [src]. \The [src] begins to react violently!") - new /obj/item/nuke_core/supermatter_sliver(drop_location()) - matter_power += 200 + if (scalpel.usesLeft) + to_chat(user, "You extract a sliver from \the [src]. \The [src] begins to react violently!") + new /obj/item/nuke_core/supermatter_sliver(drop_location()) + matter_power += 800 + scalpel.usesLeft-- + if (!scalpel.usesLeft) + to_chat(user, "A tiny piece of \the [W] falls off, rendering it useless!") + else + to_chat(user, "You fail to extract a sliver from \The [src]! \the [W] isn't sharp enough anymore.") else if(user.dropItemToGround(W)) user.visible_message("As [user] touches \the [src] with \a [W], silence fills the room...",\ "You touch \the [src] with \the [W], and everything suddenly goes silent.\n\The [W] flashes into dust as you flinch away from \the [src].",\ - "Everything suddenly goes silent.") + "Everything suddenly goes silent.") investigate_log("has been attacked ([W]) by [key_name(user)]", INVESTIGATE_SUPERMATTER) Consume(W) - playsound(get_turf(src), 'sound/effects/supermatter.ogg', 50, 1) + playsound(get_turf(src), 'sound/effects/supermatter.ogg', 50, TRUE) radiation_pulse(src, 150, 4) + else if(Adjacent(user)) //if the item is stuck to the person, kill the person too instead of eating just the item. + var/vis_msg = "[user] reaches out and touches [src] with [W], inducing a resonance... [W] starts to glow briefly before the light continues up to [user]'s body. [user.p_they(TRUE)] bursts into flames before flashing into dust!" + var/mob_msg = "You reach out and touch [src] with [W]. Everything starts burning and all you can hear is ringing. Your last thought is \"That was not a wise decision.\"" + dust_mob(user, vis_msg, mob_msg) + /obj/machinery/power/supermatter_crystal/wrench_act(mob/user, obj/item/tool) + ..() if (moveable) default_unfasten_wrench(user, tool, time = 20) return TRUE /obj/machinery/power/supermatter_crystal/Bumped(atom/movable/AM) if(isliving(AM)) - AM.visible_message("\The [AM] slams into \the [src] inducing a resonance... [AM.p_their()] body starts to glow and catch flame before flashing into ash.",\ + AM.visible_message("\The [AM] slams into \the [src] inducing a resonance... [AM.p_their()] body starts to glow and burst into flames before flashing into dust!",\ "You slam into \the [src] as your ears are filled with unearthly ringing. Your last thought is \"Oh, fuck.\"",\ - "You hear an unearthly noise as a wave of heat washes over you.") + "You hear an unearthly noise as a wave of heat washes over you.") else if(isobj(AM) && !iseffect(AM)) AM.visible_message("\The [AM] smacks into \the [src] and rapidly flashes to ash.", null,\ - "You hear a loud crack as you are washed with a wave of heat.") + "You hear a loud crack as you are washed with a wave of heat.") else return - playsound(get_turf(src), 'sound/effects/supermatter.ogg', 50, 1) - + playsound(get_turf(src), 'sound/effects/supermatter.ogg', 50, TRUE) Consume(AM) /obj/machinery/power/supermatter_crystal/intercept_zImpact(atom/movable/AM, levels) @@ -645,7 +931,8 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) message_admins("[src] has consumed [key_name_admin(user)] [ADMIN_JMP(src)].") investigate_log("has consumed [key_name(user)].", INVESTIGATE_SUPERMATTER) user.dust(force = TRUE) - matter_power += 200 + if(power_changes) + matter_power += 200 else if(istype(AM, /obj/singularity)) return else if(isobj(AM)) @@ -656,19 +943,29 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) message_admins("[src] has consumed [AM], [suspicion] [ADMIN_JMP(src)].") investigate_log("has consumed [AM] - [suspicion].", INVESTIGATE_SUPERMATTER) qdel(AM) - if(!iseffect(AM)) + if(!iseffect(AM) && power_changes) matter_power += 200 //Some poor sod got eaten, go ahead and irradiate people nearby. radiation_pulse(src, 3000, 2, TRUE) - var/list/viewers = fov_viewers(world.view, src) for(var/mob/living/L in range(10)) investigate_log("has irradiated [key_name(L)] after consuming [AM].", INVESTIGATE_SUPERMATTER) + var/list/viewers = fov_viewers(world.view, src) if(L in viewers) L.show_message("As \the [src] slowly stops resonating, you find your skin covered in new radiation burns.", MSG_VISUAL,\ "The unearthly ringing subsides and you notice you have new radiation burns.", MSG_AUDIBLE) else - L.show_message("You hear an unearthly ringing and notice your skin is covered in fresh radiation burns.", MSG_AUDIBLE) + L.show_message("You hear an unearthly ringing and notice your skin is covered in fresh radiation burns.", MSG_AUDIBLE) + +/obj/machinery/power/supermatter_crystal/proc/consume_turf(turf/T) + var/oldtype = T.type + var/turf/newT = T.ScrapeAway() + if(newT.type == oldtype) + return + playsound(T, 'sound/effects/supermatter.ogg', 50, 1) + T.visible_message("[T] smacks into [src] and rapidly flashes to ash.",\ + "You hear a loud crack as you are washed with a wave of heat.") + CALCULATE_ADJACENT_TURFS(T) //Do not blow up our internal radio /obj/machinery/power/supermatter_crystal/contents_explosion(severity, target) @@ -685,6 +982,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) anchored = FALSE gasefficency = 0.125 explosion_power = 12 + layer = ABOVE_MOB_LAYER moveable = TRUE /obj/machinery/power/supermatter_crystal/shard/engine @@ -699,6 +997,8 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) name = "anchored supermatter shard" takes_damage = FALSE produces_gas = FALSE + power_changes = FALSE + processes = FALSE //SHUT IT DOWN moveable = FALSE anchored = TRUE @@ -707,101 +1007,183 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) base_icon_state = "darkmatter" icon_state = "darkmatter" -/obj/machinery/power/supermatter_crystal/proc/supermatter_pull(turf/center, pull_range = 10) - playsound(src.loc, 'sound/weapons/marauder.ogg', 100, 1, extrarange = 7) - for(var/atom/P in orange(pull_range,center)) - if(ismovable(P)) - var/atom/movable/pulled_object = P - if(ishuman(P)) - var/mob/living/carbon/human/H = P - H.apply_effect(40, EFFECT_KNOCKDOWN, 0) - if(pulled_object && !pulled_object.anchored && !ishuman(P)) - step_towards(pulled_object,center) - step_towards(pulled_object,center) - step_towards(pulled_object,center) - step_towards(pulled_object,center) +/obj/machinery/power/supermatter_crystal/proc/supermatter_pull(turf/center, pull_range = 3) + playsound(center, 'sound/weapons/marauder.ogg', 100, TRUE, extrarange = pull_range - world.view) + for(var/atom/movable/P in orange(pull_range,center)) + if((P.anchored || P.move_resist >= MOVE_FORCE_EXTREMELY_STRONG)) //move resist memes. + if(istype(P, /obj/structure/closet)) + var/obj/structure/closet/toggle = P + toggle.open() + continue + if(ismob(P)) + var/mob/M = P + if(M.mob_negates_gravity()) + continue //You can't pull someone nailed to the deck + step_towards(P,center) /obj/machinery/power/supermatter_crystal/proc/supermatter_anomaly_gen(turf/anomalycenter, type = FLUX_ANOMALY, anomalyrange = 5) var/turf/L = pick(orange(anomalyrange, anomalycenter)) if(L) switch(type) if(FLUX_ANOMALY) - var/obj/effect/anomaly/flux/A = new(L, 300) + var/obj/effect/anomaly/flux/A = new(L, 300, FALSE) A.explosive = FALSE if(GRAVITATIONAL_ANOMALY) - new /obj/effect/anomaly/grav(L, 250) + new /obj/effect/anomaly/grav(L, 250, FALSE) if(PYRO_ANOMALY) - new /obj/effect/anomaly/pyro(L, 200) + new /obj/effect/anomaly/pyro(L, 200, FALSE) -/obj/machinery/power/supermatter_crystal/proc/supermatter_zap(atom/zapstart, range = 3, power) - . = zapstart.dir - if(power < 1000) +/obj/machinery/power/supermatter_crystal/proc/supermatter_zap(atom/zapstart = src, range = 5, zap_str = 4000, zap_flags = ZAP_SUPERMATTER_FLAGS, list/targets_hit = list()) + if(QDELETED(zapstart)) return + . = zapstart.dir + //If the strength of the zap decays past the cutoff, we stop + if(zap_str < zap_cutoff) + return + var/atom/target + var/target_type = LOWEST + var/list/arctargets = list() + //Making a new copy so additons further down the recursion do not mess with other arcs + //Lets put this ourself into the do not hit list, so we don't curve back to hit the same thing twice with one arc + for(var/test in oview(zapstart, range)) + if(!(zap_flags & ZAP_ALLOW_DUPLICATES) && LAZYACCESS(targets_hit, test)) + continue - var/target_atom - var/mob/living/target_mob - var/obj/machinery/target_machine - var/obj/structure/target_structure - var/list/arctargetsmob = list() - var/list/arctargetsmachine = list() - var/list/arctargetsstructure = list() + if(istype(test, /obj/vehicle/ridden/bicycle/)) + var/obj/vehicle/ridden/bicycle/bike = test + if(!(bike.obj_flags & BEING_SHOCKED) && bike.can_buckle)//God's not on our side cause he hates idiots. + if(target_type != BIKE) + arctargets = list() + arctargets += test + target_type = BIKE - if(prob(20)) //let's not hit all the engineers with every beam and/or segment of the arc - for(var/mob/living/Z in oview(zapstart, range+2)) - arctargetsmob += Z - if(arctargetsmob.len) - var/mob/living/H = pick(arctargetsmob) - var/atom/A = H - target_mob = H - target_atom = A + if(target_type > COIL) + continue - else - for(var/obj/machinery/X in oview(zapstart, range+2)) - arctargetsmachine += X - if(arctargetsmachine.len) - var/obj/machinery/M = pick(arctargetsmachine) - var/atom/A = M - target_machine = M - target_atom = A + if(istype(test, /obj/machinery/power/tesla_coil/)) + var/obj/machinery/power/tesla_coil/coil = test + if(coil.anchored && !(coil.obj_flags & BEING_SHOCKED) && !coil.panel_open && prob(70))//Diversity of death + if(target_type != COIL) + arctargets = list() + arctargets += test + target_type = COIL - else - for(var/obj/structure/Y in oview(zapstart, range+2)) - arctargetsstructure += Y - if(arctargetsstructure.len) - var/obj/structure/O = pick(arctargetsstructure) - var/atom/A = O - target_structure = O - target_atom = A + if(target_type > ROD) + continue - if(target_atom) - zapstart.Beam(target_atom, icon_state="nzcrentrs_power", time=5) - var/zapdir = get_dir(zapstart, target_atom) + if(istype(test, /obj/machinery/power/grounding_rod/)) + var/obj/machinery/power/grounding_rod/rod = test + //We're adding machine damaging effects, rods need to be surefire + if(rod.anchored && !rod.panel_open) + if(target_type != ROD) + arctargets = list() + arctargets += test + target_type = ROD + + if(target_type > LIVING) + continue + + if(istype(test, /mob/living/)) + var/mob/living/alive = test + if(!(HAS_TRAIT(alive, TRAIT_TESLA_SHOCKIMMUNE)) && !(alive.flags_1 & SHOCKED_1) && alive.stat != DEAD && prob(20))//let's not hit all the engineers with every beam and/or segment of the arc + if(target_type != LIVING) + arctargets = list() + arctargets += test + target_type = LIVING + + if(target_type > MACHINERY) + continue + + if(istype(test, /obj/machinery/)) + var/obj/machinery/machine = test + if(!(machine.obj_flags & BEING_SHOCKED) && prob(40)) + if(target_type != MACHINERY) + arctargets = list() + arctargets += test + target_type = MACHINERY + + if(target_type > OBJECT) + continue + + if(istype(test, /obj/)) + var/obj/object = test + if(!(object.obj_flags & BEING_SHOCKED)) + if(target_type != OBJECT) + arctargets = list() + arctargets += test + target_type = OBJECT + + if(arctargets.len)//Pick from our pool + target = pick(arctargets) + + if(!QDELETED(target))//If we found something + //Do the animation to zap to it from here + if(!(zap_flags & ZAP_ALLOW_DUPLICATES)) + LAZYSET(targets_hit, target, TRUE) + zapstart.Beam(target, icon_state=zap_icon, time=5) + var/zapdir = get_dir(zapstart, target) if(zapdir) . = zapdir - if(target_mob) - target_mob.electrocute_act(rand(5,10), "Supermatter Discharge Bolt", 1, SHOCK_NOSTUN) - if(prob(15)) - supermatter_zap(target_mob, 5, power / 2) - supermatter_zap(target_mob, 5, power / 2) - else - supermatter_zap(target_mob, 5, power / 1.5) + //Going boom should be rareish + if(prob(80)) + zap_flags &= ~ZAP_MACHINE_EXPLOSIVE + if(target_type == COIL) + //In the best situation we can expect this to grow up to 2120kw before a delam/IT'S GONE TOO FAR FRED SHUT IT DOWN + //The formula for power gen is zap_str * zap_mod / 2 * capacitor rating, between 1 and 4 + var/multi = 10 + switch(power)//Between 7k and 9k it's 20, above that it's 40 + if(SEVERE_POWER_PENALTY_THRESHOLD to CRITICAL_POWER_PENALTY_THRESHOLD) + multi = 20 + if(CRITICAL_POWER_PENALTY_THRESHOLD to INFINITY) + multi = 40 + target.zap_act(zap_str * multi, zap_flags, list()) + zap_str /= 3 //Coils should take a lot out of the power of the zap - else if(target_machine) - if(prob(15)) - supermatter_zap(target_machine, 5, power / 2) - supermatter_zap(target_machine, 5, power / 2) - else - supermatter_zap(target_machine, 5, power / 1.5) + else if(target_type == ROD) + //We can expect this to do very little, maybe shock the poor soul buckled to it, but that's all. + //This is one of our endpoints, if the bolt hits a grounding rod, it stops jumping + target.zap_act(zap_str, zap_flags, list()) + return + + else if(isliving(target))//If we got a fleshbag on our hands + var/mob/living/creature = target + creature.set_shocked() + addtimer(CALLBACK(creature, /mob/living/proc/reset_shocked), 10) + //3 shots a human with no resistance. 2 to crit, one to death. This is at at least 10000 power. + //There's no increase after that because the input power is effectivly capped at 10k + //Does 1.5 damage at the least + var/shock_damage = ((zap_flags & ZAP_MOB_DAMAGE) ? (power / 200) - 10 : rand(5,10)) + creature.electrocute_act(shock_damage, "Supermatter Discharge Bolt", 1, ((zap_flags & ZAP_MOB_STUN) ? SHOCK_TESLA : SHOCK_NOSTUN)) + zap_str /= 1.5 //Meatsacks are conductive, makes working in pairs more destructive - else if(target_structure) - if(prob(15)) - supermatter_zap(target_structure, 5, power / 2) - supermatter_zap(target_structure, 5, power / 2) else - supermatter_zap(target_structure, 5, power / 1.5) + target.zap_act(zap_str, zap_flags, list()) + zap_str /= 2 // worse then living things, better then coils + //This gotdamn variable is a boomer and keeps giving me problems + var/turf/T = get_turf(target) + var/pressure = 1 + if(T && T.return_air()) + pressure = max(1,T.return_air().return_pressure()) + //We get our range with the strength of the zap and the pressure, the higher the former and the lower the latter the better + var/new_range = clamp(zap_str / pressure * 10, 2, 7) + var/zap_count = 1 + if(prob(5)) + zap_str -= (zap_str/10) + zap_count += 1 + for(var/j in 1 to zap_count) + if(zap_count > 1) + targets_hit = targets_hit.Copy() //Pass by ref begone + supermatter_zap(target, new_range, zap_str, zap_flags, targets_hit) #undef HALLUCINATION_RANGE #undef GRAVITATIONAL_ANOMALY #undef FLUX_ANOMALY #undef PYRO_ANOMALY +#undef BIKE +#undef COIL +#undef ROD +#undef LIVING +#undef MACHINERY +#undef OBJECT +#undef LOWEST diff --git a/code/modules/station_goals/bsa.dm b/code/modules/station_goals/bsa.dm index 4c3f30a786..472734b74b 100644 --- a/code/modules/station_goals/bsa.dm +++ b/code/modules/station_goals/bsa.dm @@ -180,16 +180,37 @@ reload() /obj/machinery/bsa/full/proc/fire(mob/user, turf/bullseye) - var/turf/point = get_front_turf() - for(var/turf/T in getline(get_step(point,dir),get_target_turf())) - T.ex_act(EXPLODE_DEVASTATE) - point.Beam(get_target_turf(),icon_state="bsa_beam",time=50,maxdistance = world.maxx) //ZZZAP - - message_admins("[ADMIN_LOOKUPFLW(user)] has launched an artillery strike.") - explosion(bullseye,ex_power,ex_power*2,ex_power*4) - reload() + var/turf/point = get_front_turf() + var/turf/target = get_target_turf() + var/atom/movable/blocker + for(var/T in getline(get_step(point, dir), target)) + var/turf/tile = T + if(SEND_SIGNAL(tile, COMSIG_ATOM_BSA_BEAM) & COMSIG_ATOM_BLOCKS_BSA_BEAM) + blocker = tile + else + for(var/AM in tile) + var/atom/movable/stuff = AM + if(SEND_SIGNAL(stuff, COMSIG_ATOM_BSA_BEAM) & COMSIG_ATOM_BLOCKS_BSA_BEAM) + blocker = stuff + break + if(blocker) + target = tile + break + else + tile.ex_act(EXPLODE_DEVASTATE) + point.Beam(target, icon_state = "bsa_beam", time = 50, maxdistance = world.maxx) //ZZZAP + new /obj/effect/temp_visual/bsa_splash(point, dir) + + if(!blocker) + message_admins("[ADMIN_LOOKUPFLW(user)] has launched an artillery strike targeting [ADMIN_VERBOSEJMP(bullseye)].") + log_game("[key_name(user)] has launched an artillery strike targeting [AREACOORD(bullseye)].") + explosion(bullseye, ex_power, ex_power*2, ex_power*4) + else + message_admins("[ADMIN_LOOKUPFLW(user)] has launched an artillery strike targeting [ADMIN_VERBOSEJMP(bullseye)] but it was blocked by [blocker] at [ADMIN_VERBOSEJMP(target)].") + log_game("[key_name(user)] has launched an artillery strike targeting [AREACOORD(bullseye)] but it was blocked by [blocker] at [AREACOORD(target)].") + /obj/machinery/bsa/full/proc/reload() ready = FALSE use_power(power_used_per_shot) diff --git a/icons/effects/beam.dmi b/icons/effects/beam.dmi index 0c4784553c..e5bff44ac4 100644 Binary files a/icons/effects/beam.dmi and b/icons/effects/beam.dmi differ diff --git a/icons/effects/beam_splash.dmi b/icons/effects/beam_splash.dmi new file mode 100644 index 0000000000..d7deb3e927 Binary files /dev/null and b/icons/effects/beam_splash.dmi differ diff --git a/sound/machines/sm/accent/delam/1.ogg b/sound/machines/sm/accent/delam/1.ogg new file mode 100644 index 0000000000..75c79f89ab Binary files /dev/null and b/sound/machines/sm/accent/delam/1.ogg differ diff --git a/sound/machines/sm/accent/delam/10.ogg b/sound/machines/sm/accent/delam/10.ogg new file mode 100644 index 0000000000..c87b63b526 Binary files /dev/null and b/sound/machines/sm/accent/delam/10.ogg differ diff --git a/sound/machines/sm/accent/delam/11.ogg b/sound/machines/sm/accent/delam/11.ogg new file mode 100644 index 0000000000..c7f678245b Binary files /dev/null and b/sound/machines/sm/accent/delam/11.ogg differ diff --git a/sound/machines/sm/accent/delam/12.ogg b/sound/machines/sm/accent/delam/12.ogg new file mode 100644 index 0000000000..a395942183 Binary files /dev/null and b/sound/machines/sm/accent/delam/12.ogg differ diff --git a/sound/machines/sm/accent/delam/13.ogg b/sound/machines/sm/accent/delam/13.ogg new file mode 100644 index 0000000000..934f17947d Binary files /dev/null and b/sound/machines/sm/accent/delam/13.ogg differ diff --git a/sound/machines/sm/accent/delam/14.ogg b/sound/machines/sm/accent/delam/14.ogg new file mode 100644 index 0000000000..4175e5b947 Binary files /dev/null and b/sound/machines/sm/accent/delam/14.ogg differ diff --git a/sound/machines/sm/accent/delam/15.ogg b/sound/machines/sm/accent/delam/15.ogg new file mode 100644 index 0000000000..dcf73deb84 Binary files /dev/null and b/sound/machines/sm/accent/delam/15.ogg differ diff --git a/sound/machines/sm/accent/delam/16.ogg b/sound/machines/sm/accent/delam/16.ogg new file mode 100644 index 0000000000..20bc19399b Binary files /dev/null and b/sound/machines/sm/accent/delam/16.ogg differ diff --git a/sound/machines/sm/accent/delam/17.ogg b/sound/machines/sm/accent/delam/17.ogg new file mode 100644 index 0000000000..b517fb3d3d Binary files /dev/null and b/sound/machines/sm/accent/delam/17.ogg differ diff --git a/sound/machines/sm/accent/delam/18.ogg b/sound/machines/sm/accent/delam/18.ogg new file mode 100644 index 0000000000..4ef138d27a Binary files /dev/null and b/sound/machines/sm/accent/delam/18.ogg differ diff --git a/sound/machines/sm/accent/delam/19.ogg b/sound/machines/sm/accent/delam/19.ogg new file mode 100644 index 0000000000..f638a6971b Binary files /dev/null and b/sound/machines/sm/accent/delam/19.ogg differ diff --git a/sound/machines/sm/accent/delam/2.ogg b/sound/machines/sm/accent/delam/2.ogg new file mode 100644 index 0000000000..5b480daa2e Binary files /dev/null and b/sound/machines/sm/accent/delam/2.ogg differ diff --git a/sound/machines/sm/accent/delam/20.ogg b/sound/machines/sm/accent/delam/20.ogg new file mode 100644 index 0000000000..6072bc6227 Binary files /dev/null and b/sound/machines/sm/accent/delam/20.ogg differ diff --git a/sound/machines/sm/accent/delam/21.ogg b/sound/machines/sm/accent/delam/21.ogg new file mode 100644 index 0000000000..1223dd946d Binary files /dev/null and b/sound/machines/sm/accent/delam/21.ogg differ diff --git a/sound/machines/sm/accent/delam/22.ogg b/sound/machines/sm/accent/delam/22.ogg new file mode 100644 index 0000000000..9ccfb9b55a Binary files /dev/null and b/sound/machines/sm/accent/delam/22.ogg differ diff --git a/sound/machines/sm/accent/delam/23.ogg b/sound/machines/sm/accent/delam/23.ogg new file mode 100644 index 0000000000..6399a8376a Binary files /dev/null and b/sound/machines/sm/accent/delam/23.ogg differ diff --git a/sound/machines/sm/accent/delam/24.ogg b/sound/machines/sm/accent/delam/24.ogg new file mode 100644 index 0000000000..b51d359807 Binary files /dev/null and b/sound/machines/sm/accent/delam/24.ogg differ diff --git a/sound/machines/sm/accent/delam/25.ogg b/sound/machines/sm/accent/delam/25.ogg new file mode 100644 index 0000000000..823f22f136 Binary files /dev/null and b/sound/machines/sm/accent/delam/25.ogg differ diff --git a/sound/machines/sm/accent/delam/26.ogg b/sound/machines/sm/accent/delam/26.ogg new file mode 100644 index 0000000000..24b2a2f040 Binary files /dev/null and b/sound/machines/sm/accent/delam/26.ogg differ diff --git a/sound/machines/sm/accent/delam/27.ogg b/sound/machines/sm/accent/delam/27.ogg new file mode 100644 index 0000000000..4b4b145b7b Binary files /dev/null and b/sound/machines/sm/accent/delam/27.ogg differ diff --git a/sound/machines/sm/accent/delam/28.ogg b/sound/machines/sm/accent/delam/28.ogg new file mode 100644 index 0000000000..7bc71bf0e6 Binary files /dev/null and b/sound/machines/sm/accent/delam/28.ogg differ diff --git a/sound/machines/sm/accent/delam/29.ogg b/sound/machines/sm/accent/delam/29.ogg new file mode 100644 index 0000000000..7fec2f271c Binary files /dev/null and b/sound/machines/sm/accent/delam/29.ogg differ diff --git a/sound/machines/sm/accent/delam/3.ogg b/sound/machines/sm/accent/delam/3.ogg new file mode 100644 index 0000000000..5b57cc2707 Binary files /dev/null and b/sound/machines/sm/accent/delam/3.ogg differ diff --git a/sound/machines/sm/accent/delam/30.ogg b/sound/machines/sm/accent/delam/30.ogg new file mode 100644 index 0000000000..ed1ec7d89f Binary files /dev/null and b/sound/machines/sm/accent/delam/30.ogg differ diff --git a/sound/machines/sm/accent/delam/31.ogg b/sound/machines/sm/accent/delam/31.ogg new file mode 100644 index 0000000000..0baa82e246 Binary files /dev/null and b/sound/machines/sm/accent/delam/31.ogg differ diff --git a/sound/machines/sm/accent/delam/32.ogg b/sound/machines/sm/accent/delam/32.ogg new file mode 100644 index 0000000000..e925b32d67 Binary files /dev/null and b/sound/machines/sm/accent/delam/32.ogg differ diff --git a/sound/machines/sm/accent/delam/33.ogg b/sound/machines/sm/accent/delam/33.ogg new file mode 100644 index 0000000000..9ddec0e84a Binary files /dev/null and b/sound/machines/sm/accent/delam/33.ogg differ diff --git a/sound/machines/sm/accent/delam/4.ogg b/sound/machines/sm/accent/delam/4.ogg new file mode 100644 index 0000000000..aa4f4da071 Binary files /dev/null and b/sound/machines/sm/accent/delam/4.ogg differ diff --git a/sound/machines/sm/accent/delam/5.ogg b/sound/machines/sm/accent/delam/5.ogg new file mode 100644 index 0000000000..be438f6f15 Binary files /dev/null and b/sound/machines/sm/accent/delam/5.ogg differ diff --git a/sound/machines/sm/accent/delam/6.ogg b/sound/machines/sm/accent/delam/6.ogg new file mode 100644 index 0000000000..b89d52a564 Binary files /dev/null and b/sound/machines/sm/accent/delam/6.ogg differ diff --git a/sound/machines/sm/accent/delam/7.ogg b/sound/machines/sm/accent/delam/7.ogg new file mode 100644 index 0000000000..3a9cfc62ca Binary files /dev/null and b/sound/machines/sm/accent/delam/7.ogg differ diff --git a/sound/machines/sm/accent/delam/8.ogg b/sound/machines/sm/accent/delam/8.ogg new file mode 100644 index 0000000000..7bc0a727fa Binary files /dev/null and b/sound/machines/sm/accent/delam/8.ogg differ diff --git a/sound/machines/sm/accent/delam/9.ogg b/sound/machines/sm/accent/delam/9.ogg new file mode 100644 index 0000000000..5c1bd37405 Binary files /dev/null and b/sound/machines/sm/accent/delam/9.ogg differ diff --git a/sound/machines/sm/accent/normal/1.ogg b/sound/machines/sm/accent/normal/1.ogg new file mode 100644 index 0000000000..e92beed7fe Binary files /dev/null and b/sound/machines/sm/accent/normal/1.ogg differ diff --git a/sound/machines/sm/accent/normal/10.ogg b/sound/machines/sm/accent/normal/10.ogg new file mode 100644 index 0000000000..9efb616f0b Binary files /dev/null and b/sound/machines/sm/accent/normal/10.ogg differ diff --git a/sound/machines/sm/accent/normal/11.ogg b/sound/machines/sm/accent/normal/11.ogg new file mode 100644 index 0000000000..2af0981ef1 Binary files /dev/null and b/sound/machines/sm/accent/normal/11.ogg differ diff --git a/sound/machines/sm/accent/normal/12.ogg b/sound/machines/sm/accent/normal/12.ogg new file mode 100644 index 0000000000..2fab78b02d Binary files /dev/null and b/sound/machines/sm/accent/normal/12.ogg differ diff --git a/sound/machines/sm/accent/normal/13.ogg b/sound/machines/sm/accent/normal/13.ogg new file mode 100644 index 0000000000..784e84e4a8 Binary files /dev/null and b/sound/machines/sm/accent/normal/13.ogg differ diff --git a/sound/machines/sm/accent/normal/14.ogg b/sound/machines/sm/accent/normal/14.ogg new file mode 100644 index 0000000000..af170394dd Binary files /dev/null and b/sound/machines/sm/accent/normal/14.ogg differ diff --git a/sound/machines/sm/accent/normal/15.ogg b/sound/machines/sm/accent/normal/15.ogg new file mode 100644 index 0000000000..05c88c6b29 Binary files /dev/null and b/sound/machines/sm/accent/normal/15.ogg differ diff --git a/sound/machines/sm/accent/normal/16.ogg b/sound/machines/sm/accent/normal/16.ogg new file mode 100644 index 0000000000..46b0e33980 Binary files /dev/null and b/sound/machines/sm/accent/normal/16.ogg differ diff --git a/sound/machines/sm/accent/normal/17.ogg b/sound/machines/sm/accent/normal/17.ogg new file mode 100644 index 0000000000..e432b2ee02 Binary files /dev/null and b/sound/machines/sm/accent/normal/17.ogg differ diff --git a/sound/machines/sm/accent/normal/18.ogg b/sound/machines/sm/accent/normal/18.ogg new file mode 100644 index 0000000000..1e0e91abc8 Binary files /dev/null and b/sound/machines/sm/accent/normal/18.ogg differ diff --git a/sound/machines/sm/accent/normal/19.ogg b/sound/machines/sm/accent/normal/19.ogg new file mode 100644 index 0000000000..31de063e02 Binary files /dev/null and b/sound/machines/sm/accent/normal/19.ogg differ diff --git a/sound/machines/sm/accent/normal/2.ogg b/sound/machines/sm/accent/normal/2.ogg new file mode 100644 index 0000000000..05e3c9ff17 Binary files /dev/null and b/sound/machines/sm/accent/normal/2.ogg differ diff --git a/sound/machines/sm/accent/normal/20.ogg b/sound/machines/sm/accent/normal/20.ogg new file mode 100644 index 0000000000..36810bd8f1 Binary files /dev/null and b/sound/machines/sm/accent/normal/20.ogg differ diff --git a/sound/machines/sm/accent/normal/21.ogg b/sound/machines/sm/accent/normal/21.ogg new file mode 100644 index 0000000000..306e8856e5 Binary files /dev/null and b/sound/machines/sm/accent/normal/21.ogg differ diff --git a/sound/machines/sm/accent/normal/22.ogg b/sound/machines/sm/accent/normal/22.ogg new file mode 100644 index 0000000000..38286aa98b Binary files /dev/null and b/sound/machines/sm/accent/normal/22.ogg differ diff --git a/sound/machines/sm/accent/normal/23.ogg b/sound/machines/sm/accent/normal/23.ogg new file mode 100644 index 0000000000..89f85fed91 Binary files /dev/null and b/sound/machines/sm/accent/normal/23.ogg differ diff --git a/sound/machines/sm/accent/normal/24.ogg b/sound/machines/sm/accent/normal/24.ogg new file mode 100644 index 0000000000..7c12a3e768 Binary files /dev/null and b/sound/machines/sm/accent/normal/24.ogg differ diff --git a/sound/machines/sm/accent/normal/25.ogg b/sound/machines/sm/accent/normal/25.ogg new file mode 100644 index 0000000000..f89175ceb1 Binary files /dev/null and b/sound/machines/sm/accent/normal/25.ogg differ diff --git a/sound/machines/sm/accent/normal/26.ogg b/sound/machines/sm/accent/normal/26.ogg new file mode 100644 index 0000000000..9efd1d8ef3 Binary files /dev/null and b/sound/machines/sm/accent/normal/26.ogg differ diff --git a/sound/machines/sm/accent/normal/27.ogg b/sound/machines/sm/accent/normal/27.ogg new file mode 100644 index 0000000000..1fb1edbb5a Binary files /dev/null and b/sound/machines/sm/accent/normal/27.ogg differ diff --git a/sound/machines/sm/accent/normal/28.ogg b/sound/machines/sm/accent/normal/28.ogg new file mode 100644 index 0000000000..890c5ea429 Binary files /dev/null and b/sound/machines/sm/accent/normal/28.ogg differ diff --git a/sound/machines/sm/accent/normal/29.ogg b/sound/machines/sm/accent/normal/29.ogg new file mode 100644 index 0000000000..cd2aa40714 Binary files /dev/null and b/sound/machines/sm/accent/normal/29.ogg differ diff --git a/sound/machines/sm/accent/normal/3.ogg b/sound/machines/sm/accent/normal/3.ogg new file mode 100644 index 0000000000..38de5571a4 Binary files /dev/null and b/sound/machines/sm/accent/normal/3.ogg differ diff --git a/sound/machines/sm/accent/normal/30.ogg b/sound/machines/sm/accent/normal/30.ogg new file mode 100644 index 0000000000..87d1782768 Binary files /dev/null and b/sound/machines/sm/accent/normal/30.ogg differ diff --git a/sound/machines/sm/accent/normal/31.ogg b/sound/machines/sm/accent/normal/31.ogg new file mode 100644 index 0000000000..9ce3eeb72e Binary files /dev/null and b/sound/machines/sm/accent/normal/31.ogg differ diff --git a/sound/machines/sm/accent/normal/32.ogg b/sound/machines/sm/accent/normal/32.ogg new file mode 100644 index 0000000000..26ca056142 Binary files /dev/null and b/sound/machines/sm/accent/normal/32.ogg differ diff --git a/sound/machines/sm/accent/normal/33.ogg b/sound/machines/sm/accent/normal/33.ogg new file mode 100644 index 0000000000..24964c1ce9 Binary files /dev/null and b/sound/machines/sm/accent/normal/33.ogg differ diff --git a/sound/machines/sm/accent/normal/4.ogg b/sound/machines/sm/accent/normal/4.ogg new file mode 100644 index 0000000000..2e71e976e8 Binary files /dev/null and b/sound/machines/sm/accent/normal/4.ogg differ diff --git a/sound/machines/sm/accent/normal/5.ogg b/sound/machines/sm/accent/normal/5.ogg new file mode 100644 index 0000000000..04852e10f2 Binary files /dev/null and b/sound/machines/sm/accent/normal/5.ogg differ diff --git a/sound/machines/sm/accent/normal/6.ogg b/sound/machines/sm/accent/normal/6.ogg new file mode 100644 index 0000000000..bf06c06bbe Binary files /dev/null and b/sound/machines/sm/accent/normal/6.ogg differ diff --git a/sound/machines/sm/accent/normal/7.ogg b/sound/machines/sm/accent/normal/7.ogg new file mode 100644 index 0000000000..d29821701f Binary files /dev/null and b/sound/machines/sm/accent/normal/7.ogg differ diff --git a/sound/machines/sm/accent/normal/8.ogg b/sound/machines/sm/accent/normal/8.ogg new file mode 100644 index 0000000000..0b94b9dbe0 Binary files /dev/null and b/sound/machines/sm/accent/normal/8.ogg differ diff --git a/sound/machines/sm/accent/normal/9.ogg b/sound/machines/sm/accent/normal/9.ogg new file mode 100644 index 0000000000..545b038be1 Binary files /dev/null and b/sound/machines/sm/accent/normal/9.ogg differ diff --git a/sound/machines/sm/loops/calm.ogg b/sound/machines/sm/loops/calm.ogg new file mode 100644 index 0000000000..cee14fcd13 Binary files /dev/null and b/sound/machines/sm/loops/calm.ogg differ diff --git a/sound/machines/sm/loops/delamming.ogg b/sound/machines/sm/loops/delamming.ogg new file mode 100644 index 0000000000..7d79f0e3c4 Binary files /dev/null and b/sound/machines/sm/loops/delamming.ogg differ diff --git a/sound/machines/sm/supermatter1.ogg b/sound/machines/sm/supermatter1.ogg index 1860e78800..be5185009e 100644 Binary files a/sound/machines/sm/supermatter1.ogg and b/sound/machines/sm/supermatter1.ogg differ diff --git a/sound/machines/sm/supermatter2.ogg b/sound/machines/sm/supermatter2.ogg index fb2d39fe26..5c98d28ed1 100644 Binary files a/sound/machines/sm/supermatter2.ogg and b/sound/machines/sm/supermatter2.ogg differ diff --git a/sound/machines/sm/supermatter3.ogg b/sound/machines/sm/supermatter3.ogg index 93ac3d505b..fb8e09166c 100644 Binary files a/sound/machines/sm/supermatter3.ogg and b/sound/machines/sm/supermatter3.ogg differ diff --git a/tgstation.dme b/tgstation.dme index 7184d074aa..1fc7765311 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -558,6 +558,7 @@ #include "code\datums\elements\_element.dm" #include "code\datums\elements\art.dm" #include "code\datums\elements\beauty.dm" +#include "code\datums\elements\bsa_blocker.dm" #include "code\datums\elements\cleaning.dm" #include "code\datums\elements\decal.dm" #include "code\datums\elements\dusts_on_catatonia.dm"