diff --git a/baystation12.dme b/baystation12.dme
index 26ddab85b63db..6ddbaa7cd564c 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -2116,6 +2116,7 @@
#include "code\modules\halo\structures\closets.dm"
#include "code\modules\halo\structures\cryopod.dm"
#include "code\modules\halo\structures\decals.dm"
+#include "code\modules\halo\structures\dense_obstructions.dm"
#include "code\modules\halo\structures\diesel_gen.dm"
#include "code\modules\halo\structures\electric_fence.dm"
#include "code\modules\halo\structures\explosive.dm"
diff --git a/code/modules/halo/structures/_destructible.dm b/code/modules/halo/structures/_destructible.dm
index 0147d82238048..172374fcc909c 100644
--- a/code/modules/halo/structures/_destructible.dm
+++ b/code/modules/halo/structures/_destructible.dm
@@ -10,6 +10,7 @@
var/health = 200
var/maxHealth = 200
var/closerange_freefire = 1 //mobs within 1 tile are allowed to shoot through if set to 1
+ var/climb_desc = "climb over"
var/list/maneuvring_mobs = list()
var/repair_material_name
var/cover_rating = 10
@@ -351,12 +352,12 @@
var/turf/T = get_step(user, climb_dir)
if(T.CanPass(user, T))
user.dir = climb_dir
- to_chat(user, "You start climbing over [src]...")
+ to_chat(user, "You start to [climb_desc] [src]...")
if(do_after(user, mob_climb_time))
- src.visible_message("[user] climbs over [src].")
+ src.visible_message("[user] begins to [climb_desc] [src].")
user.loc = T
else
- to_chat(user,"You cannot climb over [src] as it is being blocked.")
+ to_chat(user,"You cannot [climb_desc] [src] as it is being blocked.")
/obj/structure/destructible/proc/verb_climb()
set name = "Climb over structure"
diff --git a/code/modules/halo/structures/dense_obstructions.dm b/code/modules/halo/structures/dense_obstructions.dm
new file mode 100644
index 0000000000000..3b2a87aa7478d
--- /dev/null
+++ b/code/modules/halo/structures/dense_obstructions.dm
@@ -0,0 +1,145 @@
+
+#define DENSE_OBSTRUCTION_PATH_ITER_CAP 25
+
+//Used for fields of obstructing trees, boulders, flora, etc. Takes a while to pass over them, and blocks view, but can be destroyed with enough firepower.
+//You could also just use this for normal clusters of icons by removing the density, I suppose.
+
+/obj/structure/destructible/dense_obstruction
+ name = "dense obstruction"
+ desc = "A dense obstruction."
+ icon = 'code/modules/halo/flora/jungleflora.dmi'
+ icon_state = "bush_1"
+ climb_desc = "manouver past"
+ plane = ABOVE_HUMAN_PLANE
+ density = 1
+ opacity = 1
+ alpha = 150
+ pixel_x = 0
+ health = 1250
+ maxHealth = 1250
+ closerange_freefire = 0
+ bump_climb = 1
+ mob_climb_time = 4 SECONDS
+ explosion_damage_mult = 0.1
+ var/list/states_ignore = list("rocks_1","rocks_2","rocks_3","rocks_4") //States in the provided icon file to ignore whilst randomising tree type.
+ var/max_offset = 12
+ var/min_offset = -12
+ var/obstruction_num = 5 //How many obstacles make up our density?
+
+ var/obst_num_hp_cache = 0//Internal use only.
+ var/next_icon_loss_threshold = 0
+
+/obj/structure/destructible/dense_obstruction/update_icon()
+ if(obst_num_hp_cache == 0)
+ obst_num_hp_cache = maxHealth / obstruction_num //Our HP interval to lose an icon.
+ next_icon_loss_threshold = maxHealth - obst_num_hp_cache
+ if(overlays.len == 0) //Only on first init.
+ icon_state = "blank" //The baseline icon shouldn't be visible.
+ var/icon/icon_obj = new(icon)
+ var/list/valid_Istates = icon_obj.IconStates() - states_ignore
+ qdel(icon_obj)
+ for(var/iter = 0 to obstruction_num)
+ var/image/I = image(icon,pick(valid_Istates))
+ var/x_offset = rand(min_offset,max_offset)
+ var/y_offset = rand(min_offset,max_offset)
+ I.pixel_x = src.pixel_x + x_offset
+ I.pixel_y = src.pixel_y + y_offset
+ I.alpha = alpha
+ overlays += I
+ else
+ if(health < next_icon_loss_threshold)
+ next_icon_loss_threshold -= obst_num_hp_cache
+ var/image/img = overlays[overlays.len]
+ overlays -= img
+
+
+/obj/structure/destructible/dense_obstruction/Initialize()
+ . = ..()
+ update_icon()
+
+
+//Variants//
+/obj/structure/destructible/dense_obstruction/flora_assorted
+ name = "dense flora"
+ desc = "Hard to see through, but easy to move through. Provides minimal protection against gunfire. Can be destroyed with enough concentrated firepower."
+ icon = 'code/modules/halo/flora/ausflora.dmi'
+ icon_state = "fern_1"
+ density = 0
+ cover_rating = 20
+ states_ignore = list() //States in the provided icon file to ignore whilst randomising tree type.
+ max_offset = 7
+ min_offset = -7
+ obstruction_num = 4
+
+/obj/structure/destructible/dense_obstruction/flora_jungle
+ name = "dense flora"
+ desc = "Hard to see through, but easy to move through. Provides minimal protection against gunfire. Can be destroyed with enough concentrated firepower."
+ icon = 'code/modules/halo/flora/jungleflora.dmi'
+ icon_state = "bush_1"
+ density = 0
+ cover_rating = 20
+ states_ignore = list("rocks_1","rocks_2","rocks_3","rocks_4") //States in the provided icon file to ignore whilst randomising tree type.
+ max_offset = 10
+ min_offset = -10
+ obstruction_num = 6
+
+/obj/structure/destructible/dense_obstruction/flora_jungle_large
+ name = "dense flora"
+ desc = "Hard to see through, and hard to move through. Provides minimal protection against gunfire. Can be destroyed with enough concentrated firepower."
+ icon = 'code/modules/halo/flora/swamp_ausflora_large.dmi'
+ icon_state = "bush_1"
+ pixel_x = -16
+ cover_rating = 30
+ states_ignore = list("rocks_1","rocks_2","rocks_3","rocks_4") //States in the provided icon file to ignore whilst randomising tree type.
+ max_offset = 10
+ min_offset = -10
+ obstruction_num = 3
+
+/obj/structure/destructible/dense_obstruction/rocks
+ name = "boulders"
+ desc = "Hard to see through, and hard to move through. Provides significant protection against gunfire. Can be destroyed with enough concentrated firepower."
+ icon = 'code/modules/halo/flora/jungleflora.dmi'
+ icon_state = "rocks_1"
+ cover_rating = 60
+ states_ignore = list("bush_1","bush_2","bush_3") //States in the provided icon file to ignore whilst randomising tree type.
+ max_offset = 10
+ min_offset = -10
+ obstruction_num = 5
+
+/obj/structure/destructible/dense_obstruction/rocks_large
+ name = "boulders"
+ desc = "Hard to see through, and hard to move through. Provides significant protection against gunfire. Can be destroyed with enough concentrated firepower."
+ icon = 'code/modules/halo/flora/swamp_ausflora_large.dmi'
+ icon_state = "rocks_1"
+ pixel_x = -16
+ cover_rating = 60
+ states_ignore = list("bush_1","bush_2","bush_3") //States in the provided icon file to ignore whilst randomising tree type.
+ max_offset = 10
+ min_offset = -10
+ obstruction_num = 3
+
+/obj/structure/destructible/dense_obstruction/trees
+ name = "dense trees"
+ desc = "Hard to see through, and hard to move through. Provides excellent protection against gunfire. Can be destroyed with enough concentrated firepower."
+ icon = 'code/modules/halo/flora/jungletree.dmi'
+ icon_state = "tree_1"
+ cover_rating = 80
+ states_ignore = list() //States in the provided icon file to ignore whilst randomising tree type.
+ pixel_x = -32
+ pixel_y = -6
+ max_offset = 7
+ min_offset = -7
+ obstruction_num = 2
+
+/obj/structure/destructible/dense_obstruction/trees_large
+ name = "dense trees"
+ desc = "Hard to see through, and hard to move through. Provides excellent protection against gunfire. Can be destroyed with enough concentrated firepower."
+ icon = 'code/modules/halo/flora/jungletreelarge.dmi'
+ icon_state = "tree_1"
+ cover_rating = 80
+ states_ignore = list() //States in the provided icon file to ignore whilst randomising tree type.
+ pixel_x = -64
+ pixel_y = -16
+ max_offset = 7
+ min_offset = -7
+ obstruction_num = 2
\ No newline at end of file