diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm
index 7e1a83486d..30e2135fbf 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,52 @@
#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/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_ALLOW_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/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index 3e5b27d376..8bfce40923 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -310,4 +310,4 @@
#define ACTIVE_BLOCK_TRAIT "active_block"
/// This trait is added by the parry system.
#define ACTIVE_PARRY_TRAIT "active_parry"
-#define STICKY_NODROP "sticky-nodrop" //sticky nodrop sounds like a bad soundcloud rapper's name
\ No newline at end of file
+#define STICKY_NODROP "sticky-nodrop" //sticky nodrop sounds like a bad soundcloud rapper's name
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/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm
index 8e9b1d9233..5d44e9c97f 100644
--- a/code/modules/power/supermatter/supermatter.dm
+++ b/code/modules/power/supermatter/supermatter.dm
@@ -619,7 +619,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
//if there is more pluox and n2 then anything else, we receive no power increase from heat
if(power_changes)
- power = max((removed.temperature * temp_factor / T0C) * gasmix_power_ratio + power, 0)
+ power = max((removed.return_temperature() * temp_factor / T0C) * gasmix_power_ratio + power, 0)
if(prob(50))
//(1 + (tritRad + pluoxDampen * bzDampen * o2Rad * plasmaRad / (10 - bzrads))) * freonbonus
@@ -642,7 +642,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
// oh and
//We can only emit so much heat, that being 57500
// so max() it all.
- removed.set_temperature(max(0, min(removed.temperature + ((device_energy * dynamic_heat_modifier) / THERMAL_RELEASE_MODIFIER), 2500 * dynamic_heat_modifier)))
+ removed.set_temperature(max(0, min(removed.return_temperature() + ((device_energy * dynamic_heat_modifier) / THERMAL_RELEASE_MODIFIER), 2500 * dynamic_heat_modifier)))
//Calculate how much gas to release
//Varies based on power and gas content
@@ -970,6 +970,17 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
"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)
+
+/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)
return
diff --git a/code/modules/station_goals/bsa.dm b/code/modules/station_goals/bsa.dm
index 2ca0e65477..4e3310655f 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/tgstation.dme b/tgstation.dme
index faa1ce990c..65283cd1cb 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -556,6 +556,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"