diff --git a/_std/defines/gang.dm b/_std/defines/gang.dm
index e43fd3a83b2c6..de6ab3e6f1252 100644
--- a/_std/defines/gang.dm
+++ b/_std/defines/gang.dm
@@ -103,7 +103,8 @@
// CRATE DROP DEFINES
#define GANG_CRATE_SCORE 500 //! how many points gang crates grant to each member, when opened
-#define GANG_CRATE_LOCK_TIME 300 SECONDS //! how long gang crates stay locked to the floor, in seconds
+#define GANG_CRATE_DROP_TIME 300 SECONDS //! How long it takes for gang crates to arrive after being announced
+#define GANG_CRATE_LOCK_TIME 10 SECONDS //! How long it takes for gang crates to unlock after arriving
#define GANG_LOOT_SCORE 300 //! how many points gang duffel bags grant to each member when opened
diff --git a/_std/defines/sight.dm b/_std/defines/sight.dm
index 3565dbae54c29..56d63c0df94dd 100644
--- a/_std/defines/sight.dm
+++ b/_std/defines/sight.dm
@@ -18,4 +18,5 @@
#define CLIENT_IMAGE_GROUP_ALL_ANTAGONISTS "all_antagonist_icons"
#define CLIENT_IMAGE_GROUP_HEADS_OF_STAFF "heads_of_staff"
#define CLIENT_IMAGE_GROUP_POD_WARS "pod_wars_team_icons"
-#define CLIENT_IMAGE_GROUP_GANGS "client_image_group_gang"
+#define CLIENT_IMAGE_GROUP_GANGS "client_image_group_gang" // covers tags and territory
+#define CLIENT_IMAGE_GROUP_GANG_OBJECTIVES "client_image_group_gang_objective" // covers crate spawns
diff --git a/code/datums/controllers/process/gang.dm b/code/datums/controllers/process/gang.dm
index d6986e29c878d..e484d46462c4d 100644
--- a/code/datums/controllers/process/gang.dm
+++ b/code/datums/controllers/process/gang.dm
@@ -110,18 +110,27 @@
if (!length(turfList))
message_admins("All attempts to find a valid location to spawn a weapons crate failed!")
return
- var/obj/storage/crate/gang_crate/guns_and_gear/crate = new(pick(turfList))
- broadcast_to_all_gangs(" We've dropped off weapons & ammunition at \the [drop_zone.name]! It's anchored in place for 5 minutes, so get fortifying!")
+ var/turf/location = pick(turfList)
+ var/datum/client_image_group/imgroup = get_image_group(CLIENT_IMAGE_GROUP_GANG_OBJECTIVES)
+ var/obj/effects/gang_crate_indicator/indicator = new(location)
+ var/image/objective_image = image('icons/effects/gang_overlays.dmi', indicator, "cratedrop")
+ objective_image.plane = PLANE_WALL
+ objective_image.alpha = 180
+ imgroup.add_image(objective_image)
+ broadcast_to_all_gangs(" We're dropping off weapons & ammunition at \the [drop_zone.name]! It'll arrive in [GANG_CRATE_DROP_TIME/(1 MINUTE)] minute[s_es(GANG_CRATE_DROP_TIME/(1 MINUTE))] so get fortifying!")
- SPAWN(GANG_CRATE_LOCK_TIME - 1 MINUTE)
+ SPAWN(GANG_CRATE_DROP_TIME - 30 SECONDS)
if(drop_zone != null)
- broadcast_to_all_gangs("The weapons crate at the [drop_zone.name] can be moved in 1 minute!")
- logTheThing(LOG_GAMEMODE, crate, "The crate in [drop_zone.name] has 1 minute left. Current location: [crate.x],[crate.y].")
- sleep(1 MINUTE)
+ broadcast_to_all_gangs("The weapons crate at the [drop_zone.name] will arrive in 30 seconds!")
+ logTheThing(LOG_GAMEMODE, src, "The crate in [drop_zone.name] will arrive in 30 seconds. Location: [location.x],[location.y].")
+ sleep(30 SECONDS)
if(drop_zone != null)
- broadcast_to_all_gangs("The weapons crate at the [drop_zone.name] is free! Drag it to your locker.")
- logTheThing(LOG_GAMEMODE, crate, "The crate in [drop_zone.name] is freed. Current location: [crate.x],[crate.y].")
+ imgroup.remove_image(objective_image)
+ qdel(indicator)
+ var/obj/storage/crate/gang_crate/guns_and_gear/crate = new(location)
+ broadcast_to_all_gangs("The weapons crate at the [drop_zone.name] is has arrived! Drag it to your locker.")
+ logTheThing(LOG_GAMEMODE, crate, "The crate in [drop_zone.name] arrives on station. Location: [location.x],[location.y].")
/datum/controller/process/gang_duffle_drop
var/repeats = 1
diff --git a/code/modules/antagonists/gang/gang_leader.dm b/code/modules/antagonists/gang/gang_leader.dm
index d3cb4d5af8857..799a4fbc46e07 100644
--- a/code/modules/antagonists/gang/gang_leader.dm
+++ b/code/modules/antagonists/gang/gang_leader.dm
@@ -82,6 +82,8 @@
image_group.add_mind(src.owner)
var/datum/client_image_group/imgroup = get_image_group(CLIENT_IMAGE_GROUP_GANGS)
imgroup.add_mind(src.owner)
+ var/datum/client_image_group/objimgroup = get_image_group(CLIENT_IMAGE_GROUP_GANG_OBJECTIVES)
+ objimgroup.add_mind(src.owner)
remove_from_image_groups()
. = ..()
@@ -90,6 +92,8 @@
image_group.remove_mind(src.owner)
var/datum/client_image_group/imgroup = get_image_group(CLIENT_IMAGE_GROUP_GANGS)
imgroup.remove_mind(src.owner)
+ var/datum/client_image_group/objimgroup = get_image_group(CLIENT_IMAGE_GROUP_GANG_OBJECTIVES)
+ objimgroup.remove_mind(src.owner)
transfer_to(datum/mind/target, take_gear, source, silent = FALSE)
var/datum/abilityHolder/gang/ability_source = src.owner.current.get_ability_holder(/datum/abilityHolder/gang)
diff --git a/code/modules/antagonists/gang/gang_member.dm b/code/modules/antagonists/gang/gang_member.dm
index 2e245877e7887..3d496a578d331 100644
--- a/code/modules/antagonists/gang/gang_member.dm
+++ b/code/modules/antagonists/gang/gang_member.dm
@@ -72,6 +72,8 @@
var/datum/client_image_group/imgroup = get_image_group(CLIENT_IMAGE_GROUP_GANGS)
imgroup.add_mind(src.owner)
+ var/datum/client_image_group/objimgroup = get_image_group(CLIENT_IMAGE_GROUP_GANG_OBJECTIVES)
+ objimgroup.add_mind(src.owner)
remove_from_image_groups()
. = ..()
@@ -81,6 +83,9 @@
var/datum/client_image_group/imgroup = get_image_group(CLIENT_IMAGE_GROUP_GANGS)
imgroup.remove_mind(src.owner)
+ var/datum/client_image_group/objimgroup = get_image_group(CLIENT_IMAGE_GROUP_GANG_OBJECTIVES)
+ objimgroup.remove_mind(src.owner)
+
assign_objectives()
ticker.mode.bestow_objective(src.owner, /datum/objective/specialist/gang/member, src)
diff --git a/code/obj/effects/misc.dm b/code/obj/effects/misc.dm
index 806c61e51588f..ee7367137ee77 100644
--- a/code/obj/effects/misc.dm
+++ b/code/obj/effects/misc.dm
@@ -45,3 +45,11 @@
pixel_x = -32
pixel_y = -32
layer = EFFECTS_LAYER_4
+
+/obj/effects/gang_crate_indicator
+ name = "gang crate indicator"
+ anchored = ANCHORED
+ icon = null
+ pixel_x = 0
+ pixel_y = 0
+ layer = EFFECTS_LAYER_4
diff --git a/code/obj/storage/gang_crate.dm b/code/obj/storage/gang_crate.dm
index 7893080a3cb52..d236a9f57cd44 100644
--- a/code/obj/storage/gang_crate.dm
+++ b/code/obj/storage/gang_crate.dm
@@ -18,6 +18,7 @@
icon_closed = "lootcrimegang"
icon_opened = "lootcrimeopengang"
can_flip_bust = FALSE
+ grab_stuff_on_spawn = FALSE
anchored = ANCHORED
var/image/light = null
var/datum/loot_generator/lootMaster
@@ -105,7 +106,7 @@
SPAWN(2*GANG_CRATE_LOCK_TIME/3 )
src.light = image('icons/obj/large_storage.dmi',"gangcratelowlight")
UpdateIcon()
- SPAWN((GANG_CRATE_LOCK_TIME - 15 SECONDS) )
+ SPAWN((GANG_CRATE_LOCK_TIME - 3 SECONDS) )
src.light = image('icons/obj/large_storage.dmi',"gangcrateblinkinglight")
UpdateIcon()
SPAWN(GANG_CRATE_LOCK_TIME)
diff --git a/icons/effects/gang_overlays.dmi b/icons/effects/gang_overlays.dmi
index 206e4ce7730f3..050874be5d5fd 100644
Binary files a/icons/effects/gang_overlays.dmi and b/icons/effects/gang_overlays.dmi differ