diff --git a/code/_onclick/hud/action_button.dm b/code/_onclick/hud/action_button.dm
index fd7abb1257f..9afcfeaf73e 100644
--- a/code/_onclick/hud/action_button.dm
+++ b/code/_onclick/hud/action_button.dm
@@ -43,13 +43,11 @@
else
icon_state = "bg_default"
UpdateIcon()
- return
/obj/screen/movable/action_button/hide_toggle/proc/UpdateIcon()
cut_overlays()
var/image/img = image(icon, src, hidden ? "show" : "hide")
add_overlay(img)
- return
/obj/screen/movable/action_button/MouseEntered(location,control,params)
diff --git a/code/controllers/subsystem/augury.dm b/code/controllers/subsystem/augury.dm
new file mode 100644
index 00000000000..1aed514f37e
--- /dev/null
+++ b/code/controllers/subsystem/augury.dm
@@ -0,0 +1,74 @@
+var/datum/subsystem/augury/SSaugury
+
+/datum/subsystem/augury
+ name = "Augury"
+ flags = SS_NO_INIT
+
+ var/list/watchers = list()
+ var/list/doombringers = list()
+
+ var/list/observers_given_action = list()
+
+/datum/subsystem/augury/New()
+ NEW_SS_GLOBAL(SSaugury)
+
+/datum/subsystem/augury/stat_entry(msg)
+ ..("W:[watchers.len]|D:[doombringers.len]")
+
+/datum/subsystem/augury/proc/register_doom(atom/A, severity)
+ doombringers[A] = severity
+
+/datum/subsystem/augury/fire()
+ var/biggest_doom = null
+ var/biggest_threat = null
+
+ for(var/d in doombringers)
+ if(!d || qdeleted(d))
+ doombringers -= d
+ continue
+ var/threat = doombringers[d]
+ if((biggest_threat == null) || (biggest_threat < threat))
+ biggest_doom = d
+ biggest_threat = threat
+
+ if(doombringers.len)
+ for(var/i in player_list)
+ if(isobserver(i) && (!(observers_given_action[i])))
+ var/datum/action/innate/augury/A = new
+ A.Grant(i)
+ observers_given_action[i] = TRUE
+
+ for(var/w in watchers)
+ if(!w)
+ watchers -= w
+ continue
+ var/mob/dead/observer/O = w
+ if(O.orbiting)
+ continue
+ else if(biggest_doom)
+ addtimer(O, "orbit", 0, FALSE, biggest_doom)
+
+/datum/action/innate/augury
+ name = "Auto Follow Debris"
+ icon_icon = 'icons/obj/meteor.dmi'
+ button_icon_state = "flaming"
+
+/datum/action/innate/augury/Activate()
+ SSaugury.watchers[owner] = TRUE
+ owner << "You are now auto-following debris."
+ active = TRUE
+ UpdateButtonIcon()
+
+/datum/action/innate/augury/Deactivate()
+ SSaugury.watchers -= owner
+ owner << "You are no longer auto-following \
+ debris."
+ active = FALSE
+ UpdateButtonIcon()
+
+/datum/action/innate/augury/UpdateButtonIcon()
+ ..()
+ if(active)
+ button.icon_state = "bg_default_on"
+ else
+ button.icon_state = background_icon_state
diff --git a/code/datums/action.dm b/code/datums/action.dm
index dd04d7e95a3..2498f4d7c5c 100644
--- a/code/datums/action.dm
+++ b/code/datums/action.dm
@@ -11,8 +11,10 @@
var/processing = 0
var/obj/screen/movable/action_button/button = null
var/button_icon = 'icons/mob/actions.dmi'
- var/button_icon_state = "default"
var/background_icon_state = "bg_default"
+
+ var/icon_icon = 'icons/mob/actions.dmi'
+ var/button_icon_state = "default"
var/mob/owner
/datum/action/New(Target)
@@ -88,9 +90,9 @@
/datum/action/proc/ApplyIcon(obj/screen/movable/action_button/current_button)
current_button.cut_overlays()
- if(button_icon && button_icon_state)
+ if(icon_icon && button_icon_state)
var/image/img
- img = image(button_icon, current_button, button_icon_state)
+ img = image(icon_icon, current_button, button_icon_state)
img.pixel_x = 0
img.pixel_y = 0
current_button.add_overlay(img)
diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm
index ad6679ea9bc..3a90b3499d8 100644
--- a/code/game/gamemodes/meteor/meteors.dm
+++ b/code/game/gamemodes/meteor/meteors.dm
@@ -1,3 +1,4 @@
+#define DEFAULT_METEOR_LIFETIME 1800
/var/const/meteor_wave_delay = 625 //minimum wait between waves in tenths of seconds
//set to at least 100 unless you want evarr ruining every round
@@ -39,7 +40,8 @@
var/obj/effect/meteor/M = new Me(pickedstart)
M.dest = pickedgoal
M.z_original = 1
- addtimer(GLOBAL_PROC, "walk_towards", 0, FALSE, M, M.dest, 1)
+ spawn(0)
+ walk_towards(M, M.dest, 1)
/proc/spaceDebrisStartLoc(startSide, Z)
var/starty
@@ -57,8 +59,7 @@
if(WEST)
starty = rand((TRANSITIONEDGE+1), world.maxy-(TRANSITIONEDGE+1))
startx = (TRANSITIONEDGE+1)
- var/turf/T = locate(startx, starty, Z)
- return T
+ . = locate(startx, starty, Z)
/proc/spaceDebrisFinishLoc(startSide, Z)
var/endy
@@ -76,8 +77,7 @@
if(WEST)
endy = rand(TRANSITIONEDGE,world.maxy-TRANSITIONEDGE)
endx = world.maxx-TRANSITIONEDGE
- var/turf/T = locate(endx, endy, Z)
- return T
+ . = locate(endx, endy, Z)
///////////////////////
//The meteor effect
@@ -97,6 +97,8 @@
var/heavy = 0
var/meteorsound = 'sound/effects/meteorimpact.ogg'
var/z_original = 1
+ var/threat = 0 // used for determining which meteors are most interesting
+ var/lifetime = DEFAULT_METEOR_LIFETIME
var/list/meteordrop = list(/obj/item/weapon/ore/iron)
var/dropamt = 2
@@ -117,11 +119,14 @@
/obj/effect/meteor/Destroy()
walk(src,0) //this cancels the walk_towards() proc
- return ..()
+ . = ..()
/obj/effect/meteor/New()
..()
+ if(SSaugury)
+ SSaugury.register_doom(src, threat)
SpinAnimation()
+ QDEL_IN(src, lifetime)
/obj/effect/meteor/Bump(atom/A)
if(A)
@@ -149,7 +154,7 @@
hits--
if(hits <= 0)
make_debris()
- meteor_effect(heavy)
+ meteor_effect()
qdel(src)
/obj/effect/meteor/ex_act()
@@ -160,16 +165,18 @@
make_debris()
qdel(src)
else
- return ..()
+ . = ..()
/obj/effect/meteor/proc/make_debris()
for(var/throws = dropamt, throws > 0, throws--)
var/thing_to_spawn = pick(meteordrop)
new thing_to_spawn(get_turf(src))
-/obj/effect/meteor/proc/meteor_effect(sound=1)
- if(sound)
+/obj/effect/meteor/proc/meteor_effect()
+ if(heavy)
for(var/mob/M in player_list)
+ if((M.orbiting) && (SSaugury.watchers[M]))
+ continue
var/turf/T = get_turf(M)
if(!T || T.z != src.z)
continue
@@ -190,14 +197,16 @@
hitpwr = 3
meteorsound = 'sound/weapons/Gunshot_smg.ogg'
meteordrop = list(/obj/item/weapon/ore/glass)
+ threat = 1
//Medium-sized
/obj/effect/meteor/medium
name = "meteor"
dropamt = 3
+ threat = 5
/obj/effect/meteor/medium/meteor_effect()
- ..(heavy)
+ ..()
explosion(src.loc, 0, 1, 2, 3, 0)
//Large-sized
@@ -207,9 +216,10 @@
hits = 6
heavy = 1
dropamt = 4
+ threat = 10
/obj/effect/meteor/big/meteor_effect()
- ..(heavy)
+ ..()
explosion(src.loc, 1, 2, 3, 4, 0)
//Flaming meteor
@@ -220,9 +230,10 @@
heavy = 1
meteorsound = 'sound/effects/bamf.ogg'
meteordrop = list(/obj/item/weapon/ore/plasma)
+ threat = 20
/obj/effect/meteor/flaming/meteor_effect()
- ..(heavy)
+ ..()
explosion(src.loc, 1, 2, 3, 4, 0, 0, 5)
//Radiation meteor
@@ -231,10 +242,11 @@
icon_state = "glowing"
heavy = 1
meteordrop = list(/obj/item/weapon/ore/uranium)
+ threat = 15
/obj/effect/meteor/irradiated/meteor_effect()
- ..(heavy)
+ ..()
explosion(src.loc, 0, 0, 4, 3, 0)
new /obj/effect/decal/cleanable/greenglow(get_turf(src))
radiation_pulse(get_turf(src), 2, 5, 50, 1)
@@ -249,6 +261,7 @@
meteorsound = 'sound/effects/blobattack.ogg'
meteordrop = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/human, /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant, /obj/item/organ/heart, /obj/item/organ/lungs, /obj/item/organ/tongue, /obj/item/organ/appendix/)
var/meteorgibs = /obj/effect/gibspawner/generic
+ threat = 2
/obj/effect/meteor/meaty/New()
for(var/path in meteordrop)
@@ -269,7 +282,7 @@
/obj/effect/meteor/meaty/ram_turf(turf/T)
if(!istype(T, /turf/open/space))
- new /obj/effect/decal/cleanable/blood (T)
+ new /obj/effect/decal/cleanable/blood(T)
/obj/effect/meteor/meaty/Bump(atom/A)
A.ex_act(hitpwr)
@@ -287,21 +300,28 @@
/obj/effect/meteor/meaty/xeno/ram_turf(turf/T)
if(!istype(T, /turf/open/space))
- new /obj/effect/decal/cleanable/xenoblood (T)
+ new /obj/effect/decal/cleanable/xenoblood(T)
//Station buster Tunguska
/obj/effect/meteor/tunguska
name = "tunguska meteor"
icon_state = "flaming"
- desc = "Your life briefly passes before your eyes the moment you lay them on this monstruosity"
+ desc = "Your life briefly passes before your eyes the moment you lay \
+ them on this monstrosity."
hits = 30
hitpwr = 1
heavy = 1
meteorsound = 'sound/effects/bamf.ogg'
meteordrop = list(/obj/item/weapon/ore/plasma)
+ threat = 50
+
+/obj/effect/meteor/tunguska/Move()
+ . = ..()
+ if(.)
+ PoolOrNew(/obj/effect/overlay/temp/revenant, get_turf(src))
/obj/effect/meteor/tunguska/meteor_effect()
- ..(heavy)
+ ..()
explosion(src.loc, 5, 10, 15, 20, 0)
/obj/effect/meteor/tunguska/Bump()
@@ -324,8 +344,10 @@
heavy = 1
dropamt = 1
meteordrop = list(/obj/item/clothing/head/hardhat/pumpkinhead, /obj/item/weapon/reagent_containers/food/snacks/grown/pumpkin)
+ threat = 100
/obj/effect/meteor/pumpkin/New()
..()
meteorsound = pick('sound/hallucinations/im_here1.ogg','sound/hallucinations/im_here2.ogg')
//////////////////////////
+#undef DEFAULT_METEOR_LIFETIME
diff --git a/code/modules/events/dust.dm b/code/modules/events/dust.dm
index 6a9685186d9..61a792384c5 100644
--- a/code/modules/events/dust.dm
+++ b/code/modules/events/dust.dm
@@ -1,21 +1,15 @@
-/datum/round_event_control/meteor_wave/dust
+/datum/round_event_control/space_dust
name = "Minor Space Dust"
- typepath = /datum/round_event/meteor_wave/dust
+ typepath = /datum/round_event/space_dust
weight = 200
max_occurrences = 1000
earliest_start = 0
alertadmins = 0
-
-/datum/round_event/meteor_wave/dust
+
+/datum/round_event/space_dust
startWhen = 1
endWhen = 2
announceWhen = 0
-/datum/round_event/meteor_wave/dust/announce()
- return
-
-/datum/round_event/meteor_wave/dust/start()
+/datum/round_event/space_dust/start()
spawn_meteors(1, meteorsC)
-
-/datum/round_event/meteor_wave/dust/tick()
- return
diff --git a/code/modules/events/immovable_rod.dm b/code/modules/events/immovable_rod.dm
index eb5d3223d5c..5495c652189 100644
--- a/code/modules/events/immovable_rod.dm
+++ b/code/modules/events/immovable_rod.dm
@@ -38,6 +38,8 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
/obj/effect/immovablerod/New(atom/start, atom/end)
..()
+ if(SSaugury)
+ SSaugury.register_doom(src, 2000)
z_original = z
destination = end
notify_ghosts("\A [src] is inbound!",
diff --git a/code/modules/events/major_dust.dm b/code/modules/events/major_dust.dm
new file mode 100644
index 00000000000..678a419670e
--- /dev/null
+++ b/code/modules/events/major_dust.dm
@@ -0,0 +1,19 @@
+/datum/round_event_control/meteor_wave/major_dust
+ name = "Major Space Dust"
+ typepath = /datum/round_event/meteor_wave/major_dust
+ weight = 30
+
+/datum/round_event/meteor_wave/major_dust
+ wave_name = "space dust"
+
+/datum/round_event/meteor_wave/major_dust/announce()
+ var/reason = pick(
+ "The station is passing through a debris cloud, expect minor damage \
+ to external fittings and fixtures.",
+ "Nanotrasen Superweapons Division is testing a new prototype \
+ [pick("field","projection","nova","super-colliding","reactive")] \
+ [pick("cannon","artillery","tank","cruiser","\[REDACTED\]")], \
+ some mild debris is expected.",
+ "A neighbouring station is throwing rocks at you. (Perhaps they've \
+ grown tired of your messages.)")
+ priority_announce(pick(reason), "Collision Alert")
diff --git a/code/modules/events/meateor_wave.dm b/code/modules/events/meateor_wave.dm
index fa26633e90f..204d901a3c3 100644
--- a/code/modules/events/meateor_wave.dm
+++ b/code/modules/events/meateor_wave.dm
@@ -1,12 +1,11 @@
/datum/round_event_control/meteor_wave/meaty
- name = "Meaty Ore Wave"
+ name = "Meteor Wave: Meaty"
typepath = /datum/round_event/meteor_wave/meaty
- weight = 1
+ weight = 2
max_occurrences = 1
+/datum/round_event/meteor_wave/meaty
+ wave_name = "meaty"
+
/datum/round_event/meteor_wave/meaty/announce()
priority_announce("Meaty ores have been detected on collision course with the station.", "Oh crap, get the mop.",'sound/AI/meteors.ogg')
-
-/datum/round_event/meteor_wave/meaty/tick()
- if(IsMultiple(activeFor, 3))
- spawn_meteors(5, meteorsB) //meteor list types defined in gamemode/meteor/meteors.dm
\ No newline at end of file
diff --git a/code/modules/events/meteor_wave.dm b/code/modules/events/meteor_wave.dm
index b670df5bdf2..786ab768d38 100644
--- a/code/modules/events/meteor_wave.dm
+++ b/code/modules/events/meteor_wave.dm
@@ -1,5 +1,7 @@
+// Normal strength
+
/datum/round_event_control/meteor_wave
- name = "Meteor Wave"
+ name = "Meteor Wave: Normal"
typepath = /datum/round_event/meteor_wave
weight = 5
min_players = 5
@@ -10,25 +12,57 @@
endWhen = 66
announceWhen = 1
var/list/wave_type
+ var/wave_name = "normal"
/datum/round_event/meteor_wave/New()
..()
- random_wave_type()
+ if(!wave_type)
+ determine_wave_type()
-/datum/round_event/meteor_wave/proc/random_wave_type()
- var/picked_wave = pickweight(list("normal" = 50, "threatening" = 40, "catastrophic" = 10))
- switch(picked_wave)
+/datum/round_event/meteor_wave/proc/determine_wave_type()
+ if(!wave_name)
+ wave_name = pickweight(list(
+ "normal" = 50,
+ "threatening" = 40,
+ "catastrophic" = 10))
+ switch(wave_name)
if("normal")
wave_type = meteors_normal
if("threatening")
wave_type = meteors_threatening
if("catastrophic")
wave_type = meteors_catastrophic
+ if("meaty")
+ wave_type = meteorsB
+ if("space dust")
+ wave_type = meteorsC
+ else
+ WARNING("Wave name of [wave_name] not recognised.")
+ kill()
/datum/round_event/meteor_wave/announce()
priority_announce("Meteors have been detected on collision course with the station.", "Meteor Alert", 'sound/AI/meteors.ogg')
-
/datum/round_event/meteor_wave/tick()
if(IsMultiple(activeFor, 3))
spawn_meteors(5, wave_type) //meteor list types defined in gamemode/meteor/meteors.dm
+
+/datum/round_event_control/meteor_wave/threatening
+ name = "Meteor Wave: Threatening"
+ typepath = /datum/round_event/meteor_wave/threatening
+ weight = 4
+ min_players = 5
+ max_occurrences = 3
+
+/datum/round_event/meteor_wave/threatening
+ wave_name = "threatening"
+
+/datum/round_event_control/meteor_wave/catastrophic
+ name = "Meteor Wave: Catastrophic"
+ typepath = /datum/round_event/meteor_wave/catastrophic
+ weight = 1
+ min_players = 5
+ max_occurrences = 3
+
+/datum/round_event/meteor_wave/catastrophic
+ wave_name = "catastrophic"
diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm
index 6d41c309c92..ac9b1fdffb1 100644
--- a/code/modules/mining/mine_turfs.dm
+++ b/code/modules/mining/mine_turfs.dm
@@ -487,11 +487,10 @@
if(3)
return
if(2)
- if (prob(20))
+ if(prob(20))
src.gets_dug()
if(1)
src.gets_dug()
- return
/turf/open/floor/plating/asteroid/attackby(obj/item/weapon/W, mob/user, params)
//note that this proc does not call ..()
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 7ea02593ac8..abe9e6335e9 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -57,10 +57,10 @@ var/list/image/ghost_images_simple = list() //this is a list of all ghost images
/mob/dead/observer/New(mob/body)
verbs += /mob/dead/observer/proc/dead_tele
-
+
if(global.cross_allowed)
verbs += /mob/dead/observer/proc/server_hop
-
+
ghostimage = image(src.icon,src,src.icon_state)
if(icon_state in ghost_forms_with_directions_list)
ghostimage_default = image(src.icon,src,src.icon_state + "_nodir")
@@ -563,7 +563,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
set desc= "Jump to the other server"
if (alert(src, "Jump to server running at [global.cross_address]?", "Server Hop", "Yes", "No") != "Yes")
return 0
- if (client && global.cross_allowed)
+ if (client && global.cross_allowed)
src << "Sending you to [global.cross_address]."
winset(src, null, "command=.options") //other wise the user never knows if byond is downloading resources
client << link(global.cross_address)
diff --git a/tgstation.dme b/tgstation.dme
index 57a8652b793..74a3db9c8d3 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -133,6 +133,7 @@
#include "code\controllers\subsystem.dm"
#include "code\controllers\subsystem\air.dm"
#include "code\controllers\subsystem\assets.dm"
+#include "code\controllers\subsystem\augury.dm"
#include "code\controllers\subsystem\diseases.dm"
#include "code\controllers\subsystem\events.dm"
#include "code\controllers\subsystem\fastprocess.dm"
@@ -1079,6 +1080,7 @@
#include "code\modules\events\immovable_rod.dm"
#include "code\modules\events\ion_storm.dm"
#include "code\modules\events\mass_hallucination.dm"
+#include "code\modules\events\major_dust.dm"
#include "code\modules\events\meateor_wave.dm"
#include "code\modules\events\meteor_wave.dm"
#include "code\modules\events\operative.dm"