diff --git a/code/__DEFINES/dcs/signals/signals_heretic.dm b/code/__DEFINES/dcs/signals/signals_heretic.dm
new file mode 100644
index 000000000000..a80526f96ab4
--- /dev/null
+++ b/code/__DEFINES/dcs/signals/signals_heretic.dm
@@ -0,0 +1,15 @@
+/// Heretic signals
+
+/// From /obj/item/melee/touch_attack/mansus_fist/on_mob_hit : (mob/living/source, mob/living/target)
+#define COMSIG_HERETIC_MANSUS_GRASP_ATTACK "mansus_grasp_attack"
+ /// Default behavior is to use the hand, so return this to blocks the mansus fist from being consumed after use.
+ #define COMPONENT_BLOCK_HAND_USE (1<<0)
+/// From /obj/item/melee/touch_attack/mansus_fist/afterattack_secondary : (mob/living/source, atom/target)
+#define COMSIG_HERETIC_MANSUS_GRASP_ATTACK_SECONDARY "mansus_grasp_attack_secondary"
+ /// Default behavior is to continue attack chain and do nothing else, so return this to use up the hand after use.
+ #define COMPONENT_USE_HAND (1<<0)
+
+/// From /obj/item/melee/sickly_blade/afterattack (with proximity) : (mob/living/source, mob/living/target)
+#define COMSIG_HERETIC_BLADE_ATTACK "blade_attack"
+/// From /obj/item/melee/sickly_blade/afterattack (without proximity) : (mob/living/source, mob/living/target)
+#define COMSIG_HERETIC_RANGED_BLADE_ATTACK "ranged_blade_attack"
diff --git a/code/__DEFINES/hud.dm b/code/__DEFINES/hud.dm
index 2e5199d6fa43..1f04f5d9454f 100644
--- a/code/__DEFINES/hud.dm
+++ b/code/__DEFINES/hud.dm
@@ -124,8 +124,8 @@
//Middle right (status indicators)
#define ui_healthdoll "EAST-1:28,CENTER-2:13"
#define ui_health "EAST-1:28,CENTER-1:15"
-#define ui_internal "EAST-1:28,CENTER:17"
-#define ui_mood "EAST-1:28,CENTER-4:10"
+#define ui_internal "EAST-1:28,CENTER+1:17"
+#define ui_mood "EAST-1:28,CENTER:17"
#define ui_stamina "EAST-1:28,CENTER-3:10"
//living
@@ -208,7 +208,7 @@
//Ghosts
-#define ui_ghost_jumptomob "SOUTH:6,CENTER-3:24"
+#define ui_ghost_jump_to_mob "SOUTH:6,CENTER-3:24"
#define ui_ghost_orbit "SOUTH:6,CENTER-2:24"
#define ui_ghost_reenter_corpse "SOUTH:6,CENTER-1:24"
#define ui_ghost_teleport "SOUTH:6,CENTER:24"
diff --git a/code/__byond_version_compat.dm b/code/__byond_version_compat.dm
index f5bdb349bc04..474785960cc7 100644
--- a/code/__byond_version_compat.dm
+++ b/code/__byond_version_compat.dm
@@ -31,19 +31,37 @@
#define LIBCALL call_ext
#endif
-// So we want to have compile time guarantees these procs exist on local type, unfortunately 515 killed the .proc/procname syntax so we have to use nameof()
+// So we want to have compile time guarantees these methods exist on local type, unfortunately 515 killed the .proc/procname and .verb/verbname syntax so we have to use nameof()
+// For the record: GLOBAL_VERB_REF would be useless as verbs can't be global.
+
#if DM_VERSION < 515
+
/// Call by name proc reference, checks if the proc exists on this type or as a global proc
#define PROC_REF(X) (.proc/##X)
+/// Call by name verb references, checks if the verb exists on either this type or as a global verb.
+#define VERB_REF(X) (.verb/##X)
+
/// Call by name proc reference, checks if the proc exists on given type or as a global proc
#define TYPE_PROC_REF(TYPE, X) (##TYPE.proc/##X)
+/// Call by name verb reference, checks if the verb exists on either the given type or as a global verb
+#define TYPE_VERB_REF(TYPE, X) (##TYPE.verb/##X)
+
/// Call by name proc reference, checks if the proc is existing global proc
#define GLOBAL_PROC_REF(X) (/proc/##X)
+
#else
-/// Call by name proc reference, checks if the proc exists on this type or as a global proc
+
+/// Call by name proc references, checks if the proc exists on either this type or as a global proc.
#define PROC_REF(X) (nameof(.proc/##X))
-/// Call by name proc reference, checks if the proc exists on given type or as a global proc
+/// Call by name verb references, checks if the verb exists on either this type or as a global verb.
+#define VERB_REF(X) (nameof(.verb/##X))
+
+/// Call by name proc reference, checks if the proc exists on either the given type or as a global proc
#define TYPE_PROC_REF(TYPE, X) (nameof(##TYPE.proc/##X))
-/// Call by name proc reference, checks if the proc is existing global proc
+/// Call by name verb reference, checks if the verb exists on either the given type or as a global verb
+#define TYPE_VERB_REF(TYPE, X) (nameof(##TYPE.verb/##X))
+
+/// Call by name proc reference, checks if the proc is an existing global proc
#define GLOBAL_PROC_REF(X) (/proc/##X)
+
#endif
diff --git a/code/_onclick/hud/ghost.dm b/code/_onclick/hud/ghost.dm
index 70984d1bd4c9..b3e456eeb0ec 100644
--- a/code/_onclick/hud/ghost.dm
+++ b/code/_onclick/hud/ghost.dm
@@ -4,13 +4,13 @@
/atom/movable/screen/ghost/MouseEntered()
flick(icon_state + "_anim", src)
-/atom/movable/screen/ghost/jumptomob
+/atom/movable/screen/ghost/jump_to_mob
name = "Jump to mob"
- icon_state = "jumptomob"
+ icon_state = "jump_to_mob"
-/atom/movable/screen/ghost/jumptomob/Click()
+/atom/movable/screen/ghost/jump_to_mob/Click()
var/mob/dead/observer/G = usr
- G.jumptomob()
+ G.jump_to_mob()
/atom/movable/screen/ghost/orbit
name = "Orbit"
@@ -48,8 +48,8 @@
..()
var/atom/movable/screen/using
- using = new /atom/movable/screen/ghost/jumptomob()
- using.screen_loc = ui_ghost_jumptomob
+ using = new /atom/movable/screen/ghost/jump_to_mob()
+ using.screen_loc = ui_ghost_jump_to_mob
static_inventory += using
using = new /atom/movable/screen/ghost/orbit()
diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm
index 9c305e79af83..3dcce9b09a83 100644
--- a/code/_onclick/hud/hud.dm
+++ b/code/_onclick/hud/hud.dm
@@ -61,7 +61,6 @@ GLOBAL_LIST_INIT(available_ui_styles, list(
var/atom/movable/screen/healths
var/atom/movable/screen/healthdoll
- var/atom/movable/screen/internals
var/atom/movable/screen/stamina
// subtypes can override this to force a specific UI style
@@ -115,7 +114,6 @@ GLOBAL_LIST_INIT(available_ui_styles, list(
healths = null
stamina = null
healthdoll = null
- internals = null
devilsouldisplay = null
blobpwrdisplay = null
alien_plasma_display = null
diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm
index f340dedd5ade..595a23350ceb 100644
--- a/code/_onclick/hud/human.dm
+++ b/code/_onclick/hud/human.dm
@@ -276,9 +276,6 @@
rest_icon.screen_loc = ui_above_movement
static_inventory += rest_icon
- internals = new /atom/movable/screen/internals()
- infodisplay += internals
-
healths = new /atom/movable/screen/healths()
infodisplay += healths
diff --git a/code/_onclick/hud/monkey.dm b/code/_onclick/hud/monkey.dm
index ca06be2a8013..8af41afa477d 100644
--- a/code/_onclick/hud/monkey.dm
+++ b/code/_onclick/hud/monkey.dm
@@ -78,9 +78,6 @@
throw_icon.screen_loc = ui_drop_throw
hotkeybuttons += throw_icon
- internals = new /atom/movable/screen/internals()
- infodisplay += internals
-
healths = new /atom/movable/screen/healths()
infodisplay += healths
diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm
index fd90a5c787d5..46b8fa12902d 100644
--- a/code/_onclick/hud/screen_objects.dm
+++ b/code/_onclick/hud/screen_objects.dm
@@ -324,59 +324,6 @@
icon = 'icons/mob/screen_cyborg.dmi'
screen_loc = ui_borg_intents
-/atom/movable/screen/internals
- name = "toggle internals"
- icon_state = "internal0"
- screen_loc = ui_internal
-
-/atom/movable/screen/internals/Click()
- if(!iscarbon(usr))
- return
-
- var/mob/living/carbon/C = usr
- if(C.incapacitated())
- return
-
- if(C.internal)
- C.close_internals()
- to_chat(C, span_notice("You are no longer running on internals."))
- icon_state = "internal0"
- else
- if (!C.can_breathe_internals())
- to_chat(C, span_warning("You are not wearing a suitable internals mask!"))
- return
-
- var/obj/item/I = C.is_holding_item_of_type(/obj/item/tank)
- if(I)
- to_chat(C, span_notice("You are now running on internals from [I] in your [C.get_held_index_name(C.get_held_index_of_item(I))]."))
- C.open_internals(I)
- else if(ishuman(C))
- var/mob/living/carbon/human/H = C
- if(istype(H.s_store, /obj/item/tank))
- to_chat(H, span_notice("You are now running on internals from [H.s_store] on your [H.wear_suit.name]."))
- H.open_internals(H.s_store)
- else if(istype(H.belt, /obj/item/tank))
- to_chat(H, span_notice("You are now running on internals from [H.belt] on your belt."))
- H.open_internals(H.belt)
- else if(istype(H.l_store, /obj/item/tank))
- to_chat(H, span_notice("You are now running on internals from [H.l_store] in your left pocket."))
- H.open_internals(H.l_store)
- else if(istype(H.r_store, /obj/item/tank))
- to_chat(H, span_notice("You are now running on internals from [H.r_store] in your right pocket."))
- H.open_internals(H.r_store)
-
- //Separate so CO2 jetpacks are a little less cumbersome.
- if(!C.internal && istype(C.back, /obj/item/tank))
- to_chat(C, span_notice("You are now running on internals from [C.back] on your back."))
- C.open_internals(C.back)
-
- if(C.internal)
- icon_state = "internal1"
- else
- to_chat(C, span_warning("You don't have a suitable tank!"))
- return
- C.update_mob_action_buttons()
-
/atom/movable/screen/mov_intent
name = "run/walk toggle"
icon = 'icons/mob/screen_midnight.dmi'
diff --git a/code/datums/actions/action.dm b/code/datums/actions/action.dm
index a1941e582716..555e769039f4 100644
--- a/code/datums/actions/action.dm
+++ b/code/datums/actions/action.dm
@@ -55,7 +55,7 @@
RegisterSignal(target, COMSIG_PARENT_QDELETING, PROC_REF(clear_ref), override = TRUE)
if(isatom(target))
- RegisterSignal(target, COMSIG_ATOM_UPDATED_ICON, PROC_REF(update_status_on_signal))
+ RegisterSignal(target, COMSIG_ATOM_UPDATED_ICON, PROC_REF(on_target_icon_update))
if(istype(target, /datum/mind))
RegisterSignal(target, COMSIG_MIND_TRANSFERRED, PROC_REF(on_target_mind_swapped))
diff --git a/code/datums/actions/items/clockcult.dm b/code/datums/actions/items/clockcult.dm
index 036b94063658..e8724cfe0240 100644
--- a/code/datums/actions/items/clockcult.dm
+++ b/code/datums/actions/items/clockcult.dm
@@ -8,19 +8,6 @@
return FALSE
return ..()
-/datum/action/item_action/clock/toggle_visor
- name = "Create Judicial Marker"
- desc = "Allows you to create a stunning Judicial Marker at any location in view. Click again to disable."
-
-/datum/action/item_action/clock/toggle_visor/IsAvailable(feedback = FALSE)
- if(!is_servant_of_ratvar(owner))
- return FALSE
- if(istype(target, /obj/item/clothing/glasses/judicial_visor))
- var/obj/item/clothing/glasses/judicial_visor/visor = target
- if(visor.recharging)
- return FALSE
- return ..()
-
/datum/action/item_action/clock/hierophant
name = "Hierophant Network"
desc = "Lets you discreetly talk with all other servants. Nearby listeners can hear you whispering, so make sure to do this privately."
diff --git a/code/datums/components/nanites.dm b/code/datums/components/nanites.dm
index e080f6b0362d..a6d4d4dcc4f1 100644
--- a/code/datums/components/nanites.dm
+++ b/code/datums/components/nanites.dm
@@ -173,11 +173,13 @@
var/icon/I = icon(host_mob.icon, host_mob.icon_state, host_mob.dir)
holder.pixel_y = I.Height() - world.icon_size
holder.icon_state = null
+ host_mob.set_hud_image_inactive(DIAG_NANITE_FULL_HUD)
if(remove || stealth)
return //bye icon
var/nanite_percent = (nanite_volume / max_nanites) * 100
nanite_percent = clamp(CEILING(nanite_percent, 10), 10, 100)
holder.icon_state = "nanites[nanite_percent]"
+ host_mob.set_hud_image_active(DIAG_NANITE_FULL_HUD)
/datum/component/nanites/proc/on_emp(datum/source, severity)
var/datum/component/empprotection/empproof = host_mob.GetExactComponent(/datum/component/empprotection)
diff --git a/code/datums/mutations/cold.dm b/code/datums/mutations/cold.dm
index a5af2739b14f..ee6f0f09c68b 100644
--- a/code/datums/mutations/cold.dm
+++ b/code/datums/mutations/cold.dm
@@ -32,6 +32,7 @@
name = "Cryobeam"
desc = "This power fires a frozen bolt at a target."
button_icon_state = "icebeam"
+ active_icon_state = "icebeam_active"
base_icon_state = "icebeam"
active_overlay_icon_state = "bg_spell_border_active_blue"
cooldown_time = 16 SECONDS
diff --git a/code/datums/mutations/fire_breath.dm b/code/datums/mutations/fire_breath.dm
index 066a8e8ef48b..c3cb4a406b5b 100644
--- a/code/datums/mutations/fire_breath.dm
+++ b/code/datums/mutations/fire_breath.dm
@@ -26,7 +26,7 @@
/datum/action/cooldown/spell/cone/staggered/fire_breath
name = "Fire Breath"
desc = "You breathe a cone of fire directly in front of you."
- button_icon_state = "fireball0"
+ button_icon_state = "fireball"
sound = 'sound/magic/demon_dies.ogg' //horrifying lizard noises
school = SCHOOL_EVOCATION
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 023e82831b3b..d0fcf47e4263 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -1390,7 +1390,6 @@
* Override this if you want custom behaviour in whatever gets hit by the rust
*/
/atom/proc/rust_heretic_act()
- return
/**
* Used to set something as 'open' if it's being used as a supplypod
diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm
index 38b25f98b593..3b909b527340 100644
--- a/code/game/data_huds.dm
+++ b/code/game/data_huds.dm
@@ -18,7 +18,7 @@
/datum/atom_hud/data
/datum/atom_hud/data/human/medical
- hud_icons = list(STATUS_HUD, HEALTH_HUD)
+ hud_icons = list(STATUS_HUD, HEALTH_HUD, NANITE_HUD)
/datum/atom_hud/data/human/medical/basic
@@ -55,10 +55,10 @@
/datum/atom_hud/data/diagnostic
/datum/atom_hud/data/diagnostic/basic
- hud_icons = list(DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_TRACK_HUD, DIAG_AIRLOCK_HUD, DIAG_LAUNCHPAD_HUD)
+ hud_icons = list(DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_TRACK_HUD, DIAG_AIRLOCK_HUD, DIAG_LAUNCHPAD_HUD, DIAG_NANITE_FULL_HUD)
/datum/atom_hud/data/diagnostic/advanced
- hud_icons = list(DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_TRACK_HUD, DIAG_AIRLOCK_HUD, DIAG_LAUNCHPAD_HUD, DIAG_PATH_HUD)
+ hud_icons = list(DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_TRACK_HUD, DIAG_AIRLOCK_HUD, DIAG_LAUNCHPAD_HUD, DIAG_PATH_HUD, DIAG_NANITE_FULL_HUD)
/datum/atom_hud/data/bot_path
// This hud exists so the bot can see itself, that's all
@@ -248,7 +248,6 @@ Security HUDs! Basic mode shows only the job.
set_hud_image_inactive(WANTED_HUD)
return
-
var/datum/data/record/target = find_record("name", perp_name, GLOB.data_core.security)
if(!target || target.fields["criminal"] == WANTED_NONE)
holder.icon_state = null
@@ -278,8 +277,10 @@ Diagnostic HUDs!
var/icon/I = icon(icon, icon_state, dir)
holder.pixel_y = I.Height() - world.icon_size
holder.icon_state = null
+ set_hud_image_inactive(NANITE_HUD)
if(src in SSnanites.nanite_monitored_mobs)
holder.icon_state = "nanite_ping"
+ set_hud_image_active(NANITE_HUD)
//For Diag health and cell bars!
/proc/RoundDiagBar(value)
diff --git a/code/game/machinery/computer/camera_advanced.dm b/code/game/machinery/computer/camera_advanced.dm
index 85dd7f284c36..5bf0ce6d6762 100644
--- a/code/game/machinery/computer/camera_advanced.dm
+++ b/code/game/machinery/computer/camera_advanced.dm
@@ -332,6 +332,7 @@
if(QDELETED(target) || !(ishuman(owner) || iscyborg(owner)) || !owner.canUseTopic(target))
return
if(!GLOB.servants_active) //No leaving unless there's servants from the get-go
+ to_chat(owner, "[span_sevtug_small("The Ark doesn't let you leave!")]")
return
if(warping)
cancel = TRUE
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index ea5303bf77f8..e06a9408d2ef 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -61,7 +61,7 @@ GLOBAL_PROTECT(admin_verbs_admin)
// /client/proc/sendmob, /*sends a mob somewhere*/ -Removed due to it needing two sorting procs to work, which were executed every time an admin right-clicked. ~Errorage
/client/proc/jumptoarea,
/client/proc/jumptokey, /*allows us to jump to the location of a mob with a certain ckey*/
- /client/proc/jumptomob, /*allows us to jump to a specific mob*/
+ /client/proc/jump_to_mob, /*allows us to jump to a specific mob*/
/client/proc/jumptoturf, /*allows us to jump to a specific turf*/
/client/proc/admin_call_shuttle, /*allows us to call the emergency shuttle*/
/client/proc/admin_cancel_shuttle, /*allows us to cancel the emergency shuttle, sending it back to centcom*/
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 0c30a071d368..b9a6b5e9a898 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -1457,7 +1457,7 @@
return
var/mob/M = locate(href_list["jumpto"])
- usr.client.jumptomob(M)
+ usr.client.jump_to_mob(M)
else if(href_list["getmob"])
if(!check_rights(R_ADMIN))
diff --git a/code/modules/admin/verbs/adminjump.dm b/code/modules/admin/verbs/adminjump.dm
index 4e815d67b40a..8125bc2e223c 100644
--- a/code/modules/admin/verbs/adminjump.dm
+++ b/code/modules/admin/verbs/adminjump.dm
@@ -37,7 +37,7 @@
SSblackbox.record_feedback("tally", "admin_verb", 1, "Jump To Turf") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
-/client/proc/jumptomob(mob/M in GLOB.mob_list)
+/client/proc/jump_to_mob(mob/M in GLOB.mob_list)
set category = "Admin"
set name = "Jump to Mob"
diff --git a/code/modules/antagonists/bloodsuckers/bloodsucker_flaws.dm b/code/modules/antagonists/bloodsuckers/bloodsucker_flaws.dm
index a1900f6728ba..49d158c23254 100644
--- a/code/modules/antagonists/bloodsuckers/bloodsucker_flaws.dm
+++ b/code/modules/antagonists/bloodsuckers/bloodsucker_flaws.dm
@@ -1,7 +1,4 @@
-/datum/antagonist/bloodsucker/proc/assign_clan_and_bane(tzimisce = FALSE)
- if(tzimisce)
- my_clan = new /datum/bloodsucker_clan/tzimisce(owner.current)
- return
+/datum/antagonist/bloodsucker/proc/assign_clan_and_bane()
if(my_clan)
return
var/list/options = list()
diff --git a/code/modules/antagonists/clockcult/clock_helpers/slab_abilities.dm b/code/modules/antagonists/clockcult/clock_helpers/slab_abilities.dm
index 37434bb8fb49..1ed27ec10768 100644
--- a/code/modules/antagonists/clockcult/clock_helpers/slab_abilities.dm
+++ b/code/modules/antagonists/clockcult/clock_helpers/slab_abilities.dm
@@ -13,11 +13,6 @@
/datum/action/innate/slab/IsAvailable(feedback = FALSE)
return TRUE
-/datum/action/innate/slab/unset_ranged_ability(mob/living/on_who)
- . = ..()
- finished = TRUE
- QDEL_IN(src, 1 SECONDS)
-
/datum/action/innate/slab/InterceptClickOn(mob/living/caller, params, atom/clicked_on)
if(in_progress)
return FALSE
@@ -26,8 +21,15 @@
return FALSE
. = ..()
- if(.)
- unset_ranged_ability(caller || usr)
+ if(!.)
+ return FALSE
+ var/mob/living/i_hate_this = caller || owner || usr
+ i_hate_this?.client?.mouse_override_icon = initial(caller?.client?.mouse_override_icon)
+ i_hate_this?.update_mouse_pointer()
+ i_hate_this?.click_intercept = null
+ finished = TRUE
+ QDEL_IN(src, 0.1 SECONDS)
+ return TRUE
//For the Hateful Manacles scripture; applies replicant handcuffs to the clicked_on.
/datum/action/innate/slab/hateful_manacles
@@ -242,7 +244,7 @@
//For the cyborg Judicial Marker scripture, places a judicial marker
/datum/action/innate/slab/judicial
- ranged_mousepointer = 'icons/effects/visor_reticule.dmi'
+ ranged_mousepointer = 'icons/effects/mouse_pointers/visor_reticule.dmi'
/datum/action/innate/slab/judicial/do_ability(mob/living/caller, params, atom/clicked_on)
var/turf/T = caller.loc
diff --git a/code/modules/antagonists/clockcult/clock_items/clockwork_slab.dm b/code/modules/antagonists/clockcult/clock_items/clockwork_slab.dm
index ff0819cb91b9..1152e74df8ac 100644
--- a/code/modules/antagonists/clockcult/clock_items/clockwork_slab.dm
+++ b/code/modules/antagonists/clockcult/clock_items/clockwork_slab.dm
@@ -98,13 +98,13 @@
slab_ability = null
return ..()
-/obj/item/clockwork/slab/dropped(mob/user)
+/obj/item/clockwork/slab/dropped(mob/user, slot)
. = ..()
- addtimer(CALLBACK(src, PROC_REF(check_on_mob), user), 1) //dropped is called before the item is out of the slot, so we need to check slightly later
+ addtimer(CALLBACK(src, PROC_REF(check_on_mob), user, slot), 0.1 SECONDS) //dropped is called before the item is out of the slot, so we need to check slightly later
-/obj/item/clockwork/slab/equipped(mob/user)
+/obj/item/clockwork/slab/equipped(mob/user, slot)
. = ..()
- update_quickbind()
+ update_quickbind(user)
/obj/item/clockwork/slab/worn_overlays(isinhands = FALSE, icon_file)
. = list()
@@ -112,10 +112,13 @@
var/mutable_appearance/M = mutable_appearance(icon_file, "slab_[inhand_overlay]")
. += M
-/obj/item/clockwork/slab/proc/check_on_mob(mob/user)
- if(user && !(src in user.held_items) && slab_ability?.owner) //if we happen to check and we AREN'T in user's hands, remove whatever ability we have
+/obj/item/clockwork/slab/proc/check_on_mob(mob/user, slot)
+ if(!user)
+ CRASH("No user on dropped slab.")
+ if(slab_ability?.owner) //if we happen to check and we AREN'T in user's hands, remove whatever ability we have
slab_ability.unset_ranged_ability(user)
- update_quickbind(user, TRUE)
+ if(!LAZYFIND(user.held_items, src))
+ update_quickbind(user, TRUE)
//Power generation
/obj/item/clockwork/slab/process()
diff --git a/code/modules/antagonists/clockcult/clock_items/judicial_visor.dm b/code/modules/antagonists/clockcult/clock_items/judicial_visor.dm
index 1534d5553c8e..a7af991fd810 100644
--- a/code/modules/antagonists/clockcult/clock_items/judicial_visor.dm
+++ b/code/modules/antagonists/clockcult/clock_items/judicial_visor.dm
@@ -10,14 +10,13 @@
var/active = FALSE //If the visor is online
var/recharging = FALSE //If the visor is currently recharging
var/datum/action/cooldown/judicial_visor/blaster
- var/recharge_cooldown = 300 //divided by 10 if ratvar is alive
- actions_types = list(/datum/action/item_action/clock/toggle_visor)
+ var/recharge_cooldown = 30 SECONDS //divided by 10 if ratvar is alive
+ actions_types = list(/datum/action/cooldown/judicial_visor)
/obj/item/clothing/glasses/judicial_visor/Initialize()
. = ..()
GLOB.all_clockwork_objects += src
blaster = new(src)
- blaster.visor = src
/obj/item/clothing/glasses/judicial_visor/Destroy()
GLOB.all_clockwork_objects -= src
@@ -99,43 +98,54 @@
user.update_inv_glasses()
/datum/action/cooldown/judicial_visor
- ranged_mousepointer = 'icons/effects/visor_reticule.dmi'
+ name = "Create Judicial Marker"
+ desc = "Allows you to create a stunning Judicial Marker at any location in view. Click again to disable."
+ ranged_mousepointer = 'icons/effects/mouse_pointers/visor_reticule.dmi'
+ button_icon = 'icons/obj/clothing/clockwork_garb.dmi'
+ button_icon_state = "judicial_visor_1"
+ background_icon_state = "bg_clock"
+ click_to_activate = TRUE
+ var/judgment_range = 7
var/obj/item/clothing/glasses/judicial_visor/visor
-/datum/action/cooldown/judicial_visor/InterceptClickOn(mob/living/caller, params, atom/target)
- if(!..())
+/datum/action/cooldown/judicial_visor/link_to(Target)
+ . = ..()
+ visor = Target
+
+/datum/action/cooldown/judicial_visor/IsAvailable(feedback = FALSE)
+ if(!is_servant_of_ratvar(owner))
+ return FALSE
+ if(visor.recharging)
return FALSE
if(owner.incapacitated() || !visor || visor != owner.get_item_by_slot(SLOT_GLASSES))
- unset_click_ability(owner)
return FALSE
-
- var/turf/T = owner.loc
- if(!isturf(T))
+ if(!isturf(owner.loc))
return FALSE
-
- if(target in view(7, get_turf(owner)))
- visor.recharging = TRUE
- visor.update_status()
- for(var/obj/item/clothing/glasses/judicial_visor/V in caller.get_all_contents())
- if(V == visor)
- continue
- V.recharging = TRUE //To prevent exploiting multiple visors to bypass the cooldown
- V.update_status()
- addtimer(CALLBACK(V, TYPE_PROC_REF(/obj/item/clothing/glasses/judicial_visor, recharge_visor), owner), (GLOB.ratvar_awakens ? visor.recharge_cooldown*0.1 : visor.recharge_cooldown) * 2)
- clockwork_say(owner, text2ratvar("Kneel, heathens!"))
- owner.visible_message(span_warning("[owner]'s judicial visor fires a stream of energy at [target], creating a strange mark!"), "[span_heavy_brass("You direct [visor]'s power to [target]. You must wait for some time before doing this again.")]")
- var/turf/targetturf = get_turf(target)
- new/obj/effect/clockwork/judicial_marker(targetturf, owner)
- log_combat(owner, targetturf, "created a judicial marker")
- owner.update_mob_action_buttons()
- owner.update_inv_glasses()
- addtimer(CALLBACK(visor, TYPE_PROC_REF(/obj/item/clothing/glasses/judicial_visor, recharge_visor), owner), GLOB.ratvar_awakens ? visor.recharge_cooldown*0.1 : visor.recharge_cooldown)//Cooldown is reduced by 10x if Ratvar is up
- unset_click_ability(owner)
-
- return FALSE
-
return TRUE
+/datum/action/cooldown/judicial_visor/Activate(atom/target_atom)
+ var/mob/living/living_owner = owner
+ if(owner && get_dist(get_turf(owner), get_turf(target_atom)) > judgment_range)
+ target_atom.balloon_alert(owner, "too far away!")
+ return
+ visor.recharging = TRUE
+ visor.update_status()
+ for(var/obj/item/clothing/glasses/judicial_visor/V in living_owner.get_all_contents())
+ if(V == visor)
+ continue
+ V.recharging = TRUE //To prevent exploiting multiple visors to bypass the cooldown
+ V.update_status()
+ addtimer(CALLBACK(V, TYPE_PROC_REF(/obj/item/clothing/glasses/judicial_visor, recharge_visor), owner), (GLOB.ratvar_awakens ? visor.recharge_cooldown*0.1 : visor.recharge_cooldown) * 2)
+ clockwork_say(owner, text2ratvar("Kneel, heathens!"))
+ owner.visible_message(span_warning("[owner]'s judicial visor fires a stream of energy at [target_atom], creating a strange mark!"), "[span_heavy_brass("You direct [visor]'s power to [target_atom]. You must wait for some time before doing this again.")]")
+ var/turf/target_turf = get_turf(target_atom)
+ new /obj/effect/clockwork/judicial_marker(target_turf, owner)
+ log_combat(owner, target_turf, "created a judicial marker")
+ owner.update_mob_action_buttons()
+ owner.update_inv_glasses()
+ addtimer(CALLBACK(visor, TYPE_PROC_REF(/obj/item/clothing/glasses/judicial_visor, recharge_visor), owner), GLOB.ratvar_awakens ? visor.recharge_cooldown*0.1 : visor.recharge_cooldown)//Cooldown is reduced by 10x if Ratvar is up
+ unset_click_ability(owner)
+
//Judicial marker: Created by the judicial visor. Immediately applies Belligerent and briefly knocks down, then after 3 seconds does large damage and briefly knocks down again
/obj/effect/clockwork/judicial_marker
name = "judicial marker"
diff --git a/code/modules/antagonists/clockcult/clockcult.dm b/code/modules/antagonists/clockcult/clockcult.dm
index 9f6645683cc7..e0ee446142a4 100644
--- a/code/modules/antagonists/clockcult/clockcult.dm
+++ b/code/modules/antagonists/clockcult/clockcult.dm
@@ -168,6 +168,8 @@
/datum/antagonist/clockcult/on_removal()
SSticker.mode.servants_of_ratvar -= owner
+ for(var/datum/action/item_action/clock/quickbind/existing_binds in owner.current.actions)
+ existing_binds.Remove(owner.current) //regenerate all our quickbound scriptures
if(!silent)
owner.current.visible_message("[span_deconversion_message("[owner.current] seems to have remembered [owner.current.p_their()] true allegiance!")]", null, null, null, owner.current)
to_chat(owner, span_userdanger("A cold, cold darkness flows through your mind, extinguishing the Justiciar's light and all of your memories as his servant."))
@@ -175,7 +177,7 @@
owner.special_role = null
if(iscyborg(owner.current))
to_chat(owner.current, span_warning("Despite your freedom from Ratvar's influence, you are still irreparably damaged and no longer possess certain functions such as AI linking."))
- . = ..()
+ return ..()
/datum/antagonist/clockcult/admin_add(datum/mind/new_owner,mob/admin)
diff --git a/code/modules/antagonists/demon/general_powers.dm b/code/modules/antagonists/demon/general_powers.dm
index 419442d6a616..99310c2a7338 100644
--- a/code/modules/antagonists/demon/general_powers.dm
+++ b/code/modules/antagonists/demon/general_powers.dm
@@ -11,6 +11,8 @@
shapeshift_type = /mob/living/simple_animal/lesserdemon
+ spell_requirements = NONE
+
/mob/living/simple_animal/lesserdemon
name = "demon"
real_name = "demon"
diff --git a/code/modules/antagonists/demon/sins/gluttony.dm b/code/modules/antagonists/demon/sins/gluttony.dm
index d17739dccd08..d52e68ed59de 100644
--- a/code/modules/antagonists/demon/sins/gluttony.dm
+++ b/code/modules/antagonists/demon/sins/gluttony.dm
@@ -10,6 +10,7 @@
invocation_type = INVOCATION_SHOUT
wall_type = /obj/effect/gluttony/timed
+ spell_requirements = NONE
/datum/action/cooldown/spell/shapeshift/demon/gluttony //emergency get out of jail card, but better. It also eats everything.
name = "Gluttony Demon Form"
diff --git a/code/modules/antagonists/devil/devil.dm b/code/modules/antagonists/devil/devil.dm
index 98f192554837..7e9fd06e5cd2 100644
--- a/code/modules/antagonists/devil/devil.dm
+++ b/code/modules/antagonists/devil/devil.dm
@@ -539,9 +539,8 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
var/mob/living/silicon/robot_devil = owner.current
var/laws = list("You may not use violence to coerce someone into selling their soul.", "You may not directly and knowingly physically harm a devil, other than yourself.", GLOB.lawlorify[LAW][ban], GLOB.lawlorify[LAW][obligation], "Accomplish your objectives at all costs.")
robot_devil.set_law_sixsixsix(laws)
- sleep(1 SECONDS)
handle_clown_mutation(owner.current, "Your infernal nature has allowed you to overcome your clownishness.")
- . = ..()
+ return ..()
/datum/antagonist/devil/on_removal()
to_chat(owner.current, span_userdanger("Your infernal link has been severed! You are no longer a devil!"))
diff --git a/code/modules/antagonists/disease/disease_abilities.dm b/code/modules/antagonists/disease/disease_abilities.dm
index 3fcc27566723..f8914e40b071 100644
--- a/code/modules/antagonists/disease/disease_abilities.dm
+++ b/code/modules/antagonists/disease/disease_abilities.dm
@@ -169,11 +169,9 @@ new /datum/disease_ability/symptom/powerful/heal/youth
button_icon = 'icons/mob/actions/actions_minor_antag.dmi'
button_icon_state = "cough"
desc = "Force the host you are following to cough with extra force, spreading your infection to those within two meters of your host even if your transmissibility is low.
Cooldown: 10 seconds"
- cooldown_time = 100
+ cooldown_time = 10 SECONDS
-/datum/action/cooldown/disease_cough/Trigger()
- if(!..())
- return FALSE
+/datum/action/cooldown/disease_cough/Activate()
var/mob/camera/disease/D = owner
var/mob/living/L = D.following_host
if(!L)
@@ -187,8 +185,6 @@ new /datum/disease_ability/symptom/powerful/heal/youth
var/datum/disease/advance/sentient_disease/SD = D.hosts[L]
SD.spread(2)
StartCooldown()
- return TRUE
-
/datum/disease_ability/action/sneeze
name = "Voluntary Sneezing"
@@ -203,11 +199,9 @@ new /datum/disease_ability/symptom/powerful/heal/youth
button_icon = 'icons/mob/actions/actions_minor_antag.dmi'
button_icon_state = "sneeze"
desc = "Force the host you are following to sneeze with extra force, spreading your infection to any victims in a 4 meter cone in front of your host even if your transmissibility is low.
Cooldown: 20 seconds"
- cooldown_time = 200
+ cooldown_time = 20 SECONDS
-/datum/action/cooldown/disease_sneeze/Trigger()
- if(!..())
- return FALSE
+/datum/action/cooldown/disease_sneeze/Activate()
var/mob/camera/disease/D = owner
var/mob/living/L = D.following_host
if(!L)
@@ -225,7 +219,6 @@ new /datum/disease_ability/symptom/powerful/heal/youth
M.AirborneContractDisease(SD, TRUE)
StartCooldown()
- return TRUE
/datum/disease_ability/action/infect
@@ -241,11 +234,9 @@ new /datum/disease_ability/symptom/powerful/heal/youth
button_icon = 'icons/mob/actions/actions_minor_antag.dmi'
button_icon_state = "infect"
desc = "Cause the host you are following to excrete an infective substance from their pores, causing all objects touching their skin to transmit your infection to anyone who touches them for the next 30 seconds.
Cooldown: 40 seconds"
- cooldown_time = 400
+ cooldown_time = 40 SECONDS
-/datum/action/cooldown/disease_infect/Trigger()
- if(!..())
- return FALSE
+/datum/action/cooldown/disease_infect/Activate()
var/mob/camera/disease/D = owner
var/mob/living/carbon/human/H = D.following_host
if(!H)
@@ -266,7 +257,6 @@ new /datum/disease_ability/symptom/powerful/heal/youth
var/obj/O = V
O.AddComponent(/datum/component/infective, D.disease_template, 300)
StartCooldown()
- return TRUE
/*******************BASE SYMPTOM TYPES*******************/
diff --git a/code/modules/antagonists/eldritch_cult/eldritch_knowledge.dm b/code/modules/antagonists/eldritch_cult/eldritch_knowledge.dm
index 2641b568eb7d..6e771904498b 100644
--- a/code/modules/antagonists/eldritch_cult/eldritch_knowledge.dm
+++ b/code/modules/antagonists/eldritch_cult/eldritch_knowledge.dm
@@ -41,7 +41,11 @@
* This proc is called whenever a new eldritch knowledge is added to an antag datum
*/
/datum/eldritch_knowledge/proc/on_gain(mob/user, datum/antagonist/heretic/our_heretic)
- return
+ var/datum/antagonist/heretic/EC = user.mind?.has_antag_datum(/datum/antagonist/heretic)
+ for(var/X in unlocked_transmutations)
+ var/datum/eldritch_transmutation/ET = new X
+ EC.transmutations |= ET
+
/**
* What happens when you lose this
*
@@ -49,6 +53,7 @@
*/
/datum/eldritch_knowledge/proc/on_lose(mob/user, datum/antagonist/heretic/our_heretic)
return
+
/**
* What happens every tick
*
@@ -82,17 +87,6 @@
var/datum/action/cooldown/spell/created_spell = created_spell_ref?.resolve()
created_spell?.Remove(user)
-
-
-/**
- * Mansus grasp act
- *
- * Gives addtional effects to mansus grasp spell
- */
-/datum/eldritch_knowledge/proc/on_mansus_grasp(atom/target, mob/user, proximity_flag, click_parameters)
- return FALSE
-
-
/**
* Sickly blade act
*
diff --git a/code/modules/antagonists/eldritch_cult/eldritch_magic.dm b/code/modules/antagonists/eldritch_cult/eldritch_magic.dm
index edc80de72812..4ec64ef051db 100644
--- a/code/modules/antagonists/eldritch_cult/eldritch_magic.dm
+++ b/code/modules/antagonists/eldritch_cult/eldritch_magic.dm
@@ -63,28 +63,27 @@
/datum/action/cooldown/spell/touch/mansus_grasp/can_cast_spell(feedback = TRUE)
return ..() && !!IS_HERETIC(owner)
+/datum/action/cooldown/spell/touch/mansus_grasp/on_antimagic_triggered(obj/item/melee/touch_attack/hand, atom/victim, mob/living/carbon/caster)
+ victim.visible_message(
+ span_danger("The spell bounces off of [victim]!"),
+ span_danger("The spell bounces off of you!"),
+ )
/datum/action/cooldown/spell/touch/mansus_grasp/cast_on_hand_hit(obj/item/melee/touch_attack/hand, atom/victim, mob/living/carbon/caster)
- if(!isliving(victim))
- return FALSE
-
- var/mob/living/living_hit = victim
- if(living_hit.can_block_magic(antimagic_flags))
- victim.visible_message(
- span_danger("The spell bounces off of [victim]!"),
- span_danger("The spell bounces off of you!"),
- )
- return FALSE
-
-// if(SEND_SIGNAL(caster, COMSIG_HERETIC_MANSUS_GRASP_ATTACK, victim) & COMPONENT_BLOCK_HAND_USE)
+// if(!isliving(victim)) for now, makes heretic hand hit everything but it's for the best
// return FALSE
- living_hit.apply_damage(10, BRUTE, wound_bonus = CANT_WOUND)
- if(iscarbon(victim))
- var/mob/living/carbon/carbon_hit = victim
- carbon_hit.adjust_timed_status_effect(4 SECONDS, /datum/status_effect/speech/slurring/heretic)
- carbon_hit.AdjustKnockdown(5 SECONDS)
- carbon_hit.adjustStaminaLoss(80)
+ if(SEND_SIGNAL(caster, COMSIG_HERETIC_MANSUS_GRASP_ATTACK, victim) & COMPONENT_BLOCK_HAND_USE)
+ return FALSE
+
+ if(isliving(victim))
+ var/mob/living/living_hit = victim
+ living_hit.apply_damage(10, BRUTE, wound_bonus = CANT_WOUND)
+ if(iscarbon(victim))
+ var/mob/living/carbon/carbon_hit = victim
+ carbon_hit.adjust_timed_status_effect(4 SECONDS, /datum/status_effect/speech/slurring/heretic)
+ carbon_hit.AdjustKnockdown(5 SECONDS)
+ carbon_hit.adjustStaminaLoss(80)
return TRUE
@@ -98,7 +97,7 @@
/obj/item/melee/touch_attack/mansus_fist/ignition_effect(atom/A, mob/user)
. = span_notice("[user] effortlessly snaps [user.p_their()] fingers near [A], igniting it with eldritch energies. Fucking badass!")
- qdel(src)
+ remove_hand_with_no_refund(user)
/datum/action/cooldown/spell/aoe/rust_conversion
name = "Aggressive Spread"
diff --git a/code/modules/antagonists/eldritch_cult/knowledge/ash_lore.dm b/code/modules/antagonists/eldritch_cult/knowledge/ash_lore.dm
index 7cb0d7c96452..7afb5cf3b41e 100644
--- a/code/modules/antagonists/eldritch_cult/knowledge/ash_lore.dm
+++ b/code/modules/antagonists/eldritch_cult/knowledge/ash_lore.dm
@@ -15,17 +15,20 @@
H.physiology.heat_mod *= 0.6
var/obj/realknife = new /obj/item/gun/magic/hook/sickly_blade/ash
user.put_in_hands(realknife)
+ RegisterSignal(user, COMSIG_HERETIC_MANSUS_GRASP_ATTACK, PROC_REF(on_mansus_grasp))
+
+/datum/eldritch_knowledge/base_ash/on_lose(mob/user)
+ UnregisterSignal(user, COMSIG_HERETIC_MANSUS_GRASP_ATTACK)
+
+/datum/eldritch_knowledge/base_ash/proc/on_mansus_grasp(mob/living/source, mob/living/target)
+// SIGNAL_HANDLER
-/datum/eldritch_knowledge/base_ash/on_mansus_grasp(atom/target, mob/user, proximity_flag, click_parameters)
- . = ..()
if(!iscarbon(target))
return
var/mob/living/carbon/C = target
- var/atom/throw_target = get_edge_target_turf(C, user.dir)
+ var/atom/throw_target = get_edge_target_turf(C, source.dir)
if(!C.anchored)
- . = TRUE
- C.throw_at(throw_target, rand(4,8), 14, user)
- return
+ C.throw_at(throw_target, rand(4,8), 14, source)
/datum/eldritch_knowledge/base_ash/on_eldritch_blade(atom/target, mob/user, proximity_flag, click_parameters)
. = ..()
@@ -66,10 +69,17 @@
route = PATH_ASH
tier = TIER_MARK
-/datum/eldritch_knowledge/ash_mark/on_mansus_grasp(atom/target,mob/user,proximity_flag,click_parameters)
+/datum/eldritch_knowledge/ash_mark/on_gain(mob/user)
. = ..()
+ RegisterSignal(user, COMSIG_HERETIC_MANSUS_GRASP_ATTACK, PROC_REF(on_mansus_grasp))
+
+/datum/eldritch_knowledge/ash_mark/on_lose(mob/user, datum/antagonist/heretic/our_heretic)
+ UnregisterSignal(user, COMSIG_HERETIC_MANSUS_GRASP_ATTACK)
+
+/datum/eldritch_knowledge/ash_mark/proc/on_mansus_grasp(mob/living/source, mob/living/target)
+ SIGNAL_HANDLER
+
if(isliving(target))
- . = TRUE
var/mob/living/living_target = target
living_target.apply_status_effect(/datum/status_effect/eldritch/ash, 5)
diff --git a/code/modules/antagonists/eldritch_cult/knowledge/flesh_lore.dm b/code/modules/antagonists/eldritch_cult/knowledge/flesh_lore.dm
index 576689a6c78f..4b0a20f16054 100644
--- a/code/modules/antagonists/eldritch_cult/knowledge/flesh_lore.dm
+++ b/code/modules/antagonists/eldritch_cult/knowledge/flesh_lore.dm
@@ -14,10 +14,15 @@
. = ..()
var/obj/realknife = new /obj/item/gun/magic/hook/sickly_blade/flesh
user.put_in_hands(realknife)
+ RegisterSignal(user, COMSIG_HERETIC_MANSUS_GRASP_ATTACK, PROC_REF(on_mansus_grasp))
-/datum/eldritch_knowledge/base_flesh/on_mansus_grasp(atom/target, mob/user, proximity_flag, click_parameters)
- . = ..()
- if(!ishuman(target) || target == user)
+/datum/eldritch_knowledge/base_flesh/on_lose(mob/user, datum/antagonist/heretic/our_heretic)
+ UnregisterSignal(user, COMSIG_HERETIC_MANSUS_GRASP_ATTACK)
+
+/datum/eldritch_knowledge/base_flesh/proc/on_mansus_grasp(mob/living/source, mob/living/target)
+// SIGNAL_HANDLER godammit
+
+ if(!ishuman(target) || target == source)
return
var/mob/living/carbon/human/human_target = target
@@ -27,25 +32,24 @@
human_target.grab_ghost()
if(!human_target.mind || !human_target.client)
- to_chat(user, span_warning("There is no soul connected to this body..."))
+ to_chat(source, span_warning("There is no soul connected to this body..."))
return
if(HAS_TRAIT(human_target, TRAIT_HUSK))
- to_chat(user, span_warning("The body is too damaged to be revived this way!"))
+ to_chat(source, span_warning("The body is too damaged to be revived this way!"))
return
if(HAS_TRAIT(human_target, TRAIT_MINDSHIELD))
- to_chat(user, span_warning("Their will cannot be malformed to obey your own!"))
+ to_chat(source, span_warning("Their will cannot be malformed to obey your own!"))
return
if(LAZYLEN(spooky_scaries) >= ghoul_amt)
- to_chat(user, span_warning("Your Oath cannot support more ghouls on this plane!"))
+ to_chat(source, span_warning("Your Oath cannot support more ghouls on this plane!"))
return
LAZYADD(spooky_scaries, human_target)
- log_game("[key_name_admin(human_target)] has become a ghoul, their master is [user.real_name]")
+ log_game("[key_name_admin(human_target)] has become a ghoul, their master is [source.real_name]")
//we change it to true only after we know they passed all the checks
- . = TRUE
RegisterSignal(human_target,COMSIG_GLOB_MOB_DEATH, PROC_REF(remove_ghoul))
human_target.revive(full_heal = TRUE, admin_revive = TRUE)
human_target.setMaxHealth(25)
@@ -53,9 +57,8 @@
human_target.become_husk()
human_target.faction |= "heretics"
var/datum/antagonist/heretic_monster/heretic_monster = human_target.mind.add_antag_datum(/datum/antagonist/heretic_monster)
- var/datum/antagonist/heretic/master = user.mind.has_antag_datum(/datum/antagonist/heretic)
+ var/datum/antagonist/heretic/master = source.mind.has_antag_datum(/datum/antagonist/heretic)
heretic_monster.set_owner(master)
- return
/datum/eldritch_knowledge/base_flesh/proc/remove_ghoul(datum/source)
var/mob/living/carbon/human/humie = source
@@ -95,8 +98,16 @@
route = PATH_FLESH
tier = TIER_MARK
-/datum/eldritch_knowledge/flesh_mark/on_mansus_grasp(atom/target, mob/user, proximity_flag, click_parameters)
+/datum/eldritch_knowledge/flesh_mark/on_gain(mob/user)
. = ..()
+ RegisterSignal(user, COMSIG_HERETIC_MANSUS_GRASP_ATTACK, PROC_REF(on_mansus_grasp))
+
+/datum/eldritch_knowledge/flesh_mark/on_lose(mob/user)
+ UnregisterSignal(user, COMSIG_HERETIC_MANSUS_GRASP_ATTACK)
+
+/datum/eldritch_knowledge/flesh_mark/proc/on_mansus_grasp(mob/living/source, mob/living/target)
+ SIGNAL_HANDLER
+
if(isliving(target))
. = TRUE
var/mob/living/living_target = target
diff --git a/code/modules/antagonists/eldritch_cult/knowledge/rust_lore.dm b/code/modules/antagonists/eldritch_cult/knowledge/rust_lore.dm
index 310d5a45cea4..e30acac4ca2a 100644
--- a/code/modules/antagonists/eldritch_cult/knowledge/rust_lore.dm
+++ b/code/modules/antagonists/eldritch_cult/knowledge/rust_lore.dm
@@ -12,11 +12,15 @@
. = ..()
var/obj/realknife = new /obj/item/gun/magic/hook/sickly_blade/rust
user.put_in_hands(realknife)
+ RegisterSignal(user, COMSIG_HERETIC_MANSUS_GRASP_ATTACK, PROC_REF(on_mansus_grasp))
-/datum/eldritch_knowledge/base_rust/on_mansus_grasp(atom/target, mob/user, proximity_flag, click_parameters)
- . = ..()
- if(user.a_intent == INTENT_HARM)
- . = TRUE
+/datum/eldritch_knowledge/base_rust/on_lose(mob/user)
+ UnregisterSignal(user, COMSIG_HERETIC_MANSUS_GRASP_ATTACK)
+
+/datum/eldritch_knowledge/base_rust/proc/on_mansus_grasp(mob/living/source, atom/target)
+ SIGNAL_HANDLER
+
+ if(source.a_intent == INTENT_HARM)
target.rust_heretic_act()
/datum/eldritch_knowledge/base_rust/on_eldritch_blade(atom/target, mob/user, proximity_flag, click_parameters)
@@ -72,9 +76,17 @@
banned_knowledge = list(/datum/eldritch_knowledge/ash_mark,/datum/eldritch_knowledge/flesh_mark)
route = PATH_RUST
tier = TIER_MARK
-
-/datum/eldritch_knowledge/rust_mark/on_mansus_grasp(atom/target, mob/user, proximity_flag, click_parameters)
+
+/datum/eldritch_knowledge/rust_mark/on_gain(mob/user)
. = ..()
+ RegisterSignal(user, COMSIG_HERETIC_MANSUS_GRASP_ATTACK, PROC_REF(on_mansus_grasp))
+
+/datum/eldritch_knowledge/rust_mark/on_lose(mob/user)
+ UnregisterSignal(user, COMSIG_HERETIC_MANSUS_GRASP_ATTACK)
+
+/datum/eldritch_knowledge/rust_mark/proc/on_mansus_grasp(mob/living/source, mob/living/target)
+ SIGNAL_HANDLER
+
if(isliving(target))
var/mob/living/living_target = target
living_target.apply_status_effect(/datum/status_effect/eldritch/rust)
diff --git a/code/modules/antagonists/horror/horror.dm b/code/modules/antagonists/horror/horror.dm
index 7b2b95aa12ca..5f6309a1c10d 100644
--- a/code/modules/antagonists/horror/horror.dm
+++ b/code/modules/antagonists/horror/horror.dm
@@ -117,7 +117,7 @@
return
Infect(C)
return
- ..()
+ return ..()
/mob/living/simple_animal/horror/proc/has_chemicals(amt)
return chemicals >= amt
diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm
index d8e1f3ba7e97..913470993949 100644
--- a/code/modules/client/client_procs.dm
+++ b/code/modules/client/client_procs.dm
@@ -1038,7 +1038,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
var/mob/living/M = mob
M.update_damage_hud()
if (prefs.read_preference(/datum/preference/toggle/auto_fit_viewport))
- addtimer(CALLBACK(src,.verb/fit_viewport,10)) //Delayed to avoid wingets from Login calls.
+ addtimer(CALLBACK(src, VERB_REF(fit_viewport), 1 SECONDS)) //Delayed to avoid wingets from Login calls.
/client/proc/generate_clickcatcher()
if(!void)
diff --git a/code/modules/events/tzimisce.dm b/code/modules/events/tzimisce.dm
index 852b950defa5..f94b66aa51c1 100644
--- a/code/modules/events/tzimisce.dm
+++ b/code/modules/events/tzimisce.dm
@@ -8,7 +8,7 @@
/datum/round_event_control/tzimisce/bloodsucker
name = "Spawn Tzimisce - Bloodsucker"
max_occurrences = 1
- weight = 2000
+// weight = 2000
typepath = /datum/round_event/ghost_role/tzimisce/bloodsucker
min_players = 25
earliest_start = 30 MINUTES
@@ -63,7 +63,8 @@
bloodsuckerdatum.antag_hud_name = "tzimisce"
bloodsuckerdatum.add_team_hud(tzimisce)
bloodsuckerdatum.bloodsucker_level_unspent += round(world.time / (15 MINUTES), 1)
- bloodsuckerdatum.assign_clan_and_bane(tzimisce = TRUE)
+ bloodsuckerdatum.my_clan = new /datum/bloodsucker_clan/tzimisce(bloodsuckerdatum)
+ bloodsuckerdatum.owner.announce_objectives()
spawned_mobs += tzimisce
message_admins("[ADMIN_LOOKUPFLW(tzimisce)] has been made into a tzimisce bloodsucker an event.")
diff --git a/code/modules/mining/lavaland/seismicarm.dm b/code/modules/mining/lavaland/seismicarm.dm
index 30e3e37dad7e..aa1593197bf1 100644
--- a/code/modules/mining/lavaland/seismicarm.dm
+++ b/code/modules/mining/lavaland/seismicarm.dm
@@ -1,7 +1,7 @@
/datum/action/cooldown/spell/pointed/seismic
spell_requirements = SPELL_REQUIRES_HUMAN
-/datum/action/cooldown/spell/pointed/seismic/can_cast_spell()
+/datum/action/cooldown/spell/pointed/seismic/can_cast_spell(feedback = TRUE)
if(!isliving(owner))
return FALSE
var/mob/living/user = owner
@@ -27,7 +27,7 @@
if(!.)
return FALSE
if(user.incapacitated())
- return
+ return FALSE
var/turf/T = get_step(get_turf(user), user.dir)
var/turf/Z = get_turf(user)
var/obj/effect/temp_visual/decoy/fading/threesecond/F = new(Z, user)
@@ -35,40 +35,42 @@
playsound(user,'sound/effects/gravhit.ogg', 20, 1)
for(var/i = 0 to jumpdistance)
if(T.density)
- return
+ return FALSE
for(var/obj/D in T.contents)
- if(D.density == TRUE)
- return
+ if(D.density)
+ return FALSE
for(var/turf/open/chasm/C in T.contents)
- return
+ return FALSE
for(var/turf/closed/indestructible/I in T.contents)
- return
+ return FALSE
for(var/turf/open/lava/V in T.contents)
- return
+ return FALSE
for(var/obj/machinery/door/window/E in Z.contents)
- if(E.density == TRUE)
- return
+ if(E.density)
+ return FALSE
if(T)
- sleep(0.1 SECONDS)
- user.forceMove(T)
- walk_towards(F,user,0, 1.5)
- animate(F, alpha = 0, color = "#00d9ff", time = 0.3 SECONDS)
- for(var/mob/living/L in T.contents)
- if(L != user)
- user.forceMove(get_turf(L))
- to_chat(L, span_userdanger("[user] catches you with [user.p_their()] arm and clotheslines you!"))
- user.visible_message(span_warning("[user] hits [L] with a lariat!"))
- L.SpinAnimation(0.5 SECONDS, 1)
- if(isanimal(L))
- L.adjustBruteLoss(50)
- if(iscarbon(L))
- L.adjustBruteLoss(10)
- if(issilicon(L))
- L.adjustBruteLoss(12)
- playsound(L,'sound/effects/meteorimpact.ogg', 60, 1)
- T = get_step(user,user.dir)
+ addtimer(CALLBACK(src, PROC_REF(finish_lariat), user, T, F), 0.1 SECONDS)
return TRUE
+
+/datum/action/cooldown/spell/pointed/seismic/lariat/proc/finish_lariat(mob/living/user, turf/target_turf, obj/effect/temp_visual/decoy/fading/threesecond/effect)
+ user.forceMove(target_turf)
+ walk_towards(effect,user,0, 1.5)
+ animate(effect, alpha = 0, color = "#00d9ff", time = 0.3 SECONDS)
+ for(var/mob/living/L in target_turf.contents)
+ if(L != user)
+ user.forceMove(get_turf(L))
+ to_chat(L, span_userdanger("[user] catches you with [user.p_their()] arm and clotheslines you!"))
+ user.visible_message(span_warning("[user] hits [L] with a lariat!"))
+ L.SpinAnimation(0.5 SECONDS, 1)
+ if(isanimal(L))
+ L.adjustBruteLoss(50)
+ if(iscarbon(L))
+ L.adjustBruteLoss(10)
+ if(issilicon(L))
+ L.adjustBruteLoss(12)
+ playsound(L,'sound/effects/meteorimpact.ogg', 60, 1)
+ target_turf = get_step(user,user.dir)
/datum/action/cooldown/spell/pointed/seismic/mop
name = "Mop the Floor"
@@ -82,70 +84,71 @@
/datum/action/cooldown/spell/pointed/seismic/mop/InterceptClickOn(mob/living/user, params, atom/target)
. = ..()
if(!.)
- return
+ return FALSE
if(user.incapacitated())
- return
+ return FALSE
var/turf/T = get_step(get_turf(user), user.dir)
var/turf/Z = get_turf(user)
var/obj/effect/temp_visual/decoy/fading/threesecond/F = new(Z, user)
- var/list/mopped = list()
user.visible_message(span_warning("[user] sprints forward with [user.p_their()] hand outstretched!"))
playsound(user,'sound/effects/gravhit.ogg', 20, 1)
for(var/i = 0 to jumpdistance)
if(T.density)
- return
+ return FALSE
for(var/obj/D in T.contents)
- if(D.density == TRUE)
- return
- for (var/turf/open/chasm/C in T.contents)
- return
- for (var/turf/closed/indestructible/I in T.contents)
- return
+ if(D.density)
+ return FALSE
+ for(var/turf/open/chasm/C in T.contents)
+ return FALSE
+ for(var/turf/closed/indestructible/I in T.contents)
+ return FALSE
for(var/obj/machinery/door/window/E in Z.contents)
- if(E.density == TRUE)
- return
+ if(E.density)
+ return FALSE
if(T)
- sleep(0.1 SECONDS)
- user.forceMove(T)
- walk_towards(F,user,0, 1.5)
- animate(F, alpha = 0, color = "#00d9ff", time = 0.3 SECONDS)
- for(var/mob/living/L in T.contents)
- if(L != user)
- mopped |= L
- var/turf/Q = get_step(get_turf(user), user.dir)
- var/mob/living/U = user
- animate(L, transform = matrix(90, MATRIX_ROTATE), time = 0.1 SECONDS, loop = 0)
- if(ismineralturf(Q))
- var/turf/closed/mineral/M = Q
- M.attempt_drill()
- L.adjustBruteLoss(5)
- if(Q.density)
- return
- for(var/obj/D in Q.contents)
- if(D.density == TRUE)
- return
- U.forceMove(get_turf(L))
- to_chat(L, span_userdanger("[U] catches you with [U.p_their()] hand and drags you down!"))
- U.visible_message(span_warning("[U] hits [L] and drags them through the dirt!"))
- L.forceMove(Q)
- if(isanimal(L))
- U.apply_status_effect(STATUS_EFFECT_BLOODDRUNK)//guaranteed extended contact with a fauna so i have to make it not a death sentence
- L.adjustBruteLoss(20)
- if(L.stat == DEAD)
- L.visible_message(span_warning("[L] is ground into paste!"))
- L.gib()
- if(iscarbon(L))
- L.adjustBruteLoss(4)
- if(issilicon(L))
- L.adjustBruteLoss(5)
- playsound(L,'sound/effects/meteorimpact.ogg', 60, 1)
- T = get_step(user,user.dir)
+ addtimer(CALLBACK(src, PROC_REF(finish_mop), user, T, F), 0.1 SECONDS)
+
+ return TRUE
+
+/datum/action/cooldown/spell/pointed/seismic/mop/proc/finish_mop(mob/living/user, turf/target_turf, obj/effect/temp_visual/decoy/fading/threesecond/effect)
+ user.forceMove(target_turf)
+ walk_towards(effect,user,0, 1.5)
+ animate(effect, alpha = 0, color = "#00d9ff", time = 0.3 SECONDS)
+ var/list/mopped = list()
+ for(var/mob/living/L in target_turf.contents)
+ if(L != user)
+ mopped |= L
+ var/turf/Q = get_step(get_turf(user), user.dir)
+ animate(L, transform = matrix(90, MATRIX_ROTATE), time = 0.1 SECONDS, loop = 0)
+ if(ismineralturf(Q))
+ var/turf/closed/mineral/M = Q
+ M.attempt_drill()
+ L.adjustBruteLoss(5)
+ if(Q.density)
+ return FALSE
+ for(var/obj/D in Q.contents)
+ if(D.density)
+ return FALSE
+ user.forceMove(get_turf(L))
+ to_chat(L, span_userdanger("[user] catches you with [user.p_their()] hand and drags you down!"))
+ user.visible_message(span_warning("[user] hits [L] and drags them through the dirt!"))
+ L.forceMove(Q)
+ if(isanimal(L))
+ user.apply_status_effect(STATUS_EFFECT_BLOODDRUNK)//guaranteed extended contact with a fauna so i have to make it not a death sentence
+ L.adjustBruteLoss(20)
+ if(L.stat == DEAD)
+ L.visible_message(span_warning("[L] is ground into paste!"))
+ L.gib()
+ if(iscarbon(L))
+ L.adjustBruteLoss(4)
+ if(issilicon(L))
+ L.adjustBruteLoss(5)
+ playsound(L,'sound/effects/meteorimpact.ogg', 60, 1)
+ target_turf = get_step(user, user.dir)
for(var/mob/living/C in mopped)
if(C.stat == CONSCIOUS && C.resting == FALSE)
animate(C, transform = null, time = 0.5 SECONDS, loop = 0)
- return TRUE
-
/datum/action/cooldown/spell/pointed/seismic/suplex
name = "Suplex"
desc = "Grab the target in front of you and slam them back onto the ground."
@@ -199,11 +202,15 @@
L.adjustBruteLoss(6)
if(issilicon(L))
L.adjustBruteLoss(8)
- sleep(0.5 SECONDS)
- if(L.stat == CONSCIOUS && L.resting == FALSE)
- animate(L, transform = null, time = 0.1 SECONDS, loop = 0)
+ addtimer(CALLBACK(src, PROC_REF(fix_target_anim), L), 0.5 SECONDS)
-/datum/action/cooldown/spell/pointed/seismic/righthook
+ return TRUE
+
+/datum/action/cooldown/spell/pointed/seismic/suplex/proc/fix_target_anim(mob/living/target)
+ if(target.stat == CONSCIOUS && target.resting == FALSE)
+ animate(target, transform = null, time = 0.1 SECONDS, loop = 0)
+
+/datum/action/cooldown/spell/touch/righthook
name = "Right Hook"
desc = "Put the arm through its paces, cranking the outputs located at the front and back of the hand to full capacity for a powerful blow. This attack can only be readied for five seconds and connecting with it will temporarily overwhelm the entire arm for fifteen."
button_icon = 'icons/mob/actions/actions_arm.dmi'
@@ -211,17 +218,27 @@
cooldown_time = 3 SECONDS
-/datum/action/cooldown/spell/pointed/seismic/InterceptClickOn(mob/living/user, params, atom/target)
- . = ..()
- if(!.)
+ sound = 'sound/effects/gravhit.ogg'
+ draw_message = span_notice("Your arm begins crackling loudly!")
+ drop_message = span_notice("You dissipate the power in your hand.")
+
+ spell_requirements = SPELL_REQUIRES_HUMAN
+
+ hand_path = /obj/item/melee/touch_attack/overcharged_emitter
+
+/datum/action/cooldown/spell/touch/righthook/can_cast_spell(feedback = TRUE)
+ if(!isliving(owner))
+ return FALSE
+ var/mob/living/user = owner
+ var/obj/item/bodypart/r_arm/R = user.get_bodypart(BODY_ZONE_R_ARM)
+ if(R?.bodypart_disabled)
+ to_chat(user, span_warning("The arm isn't in a functional state right now!"))
+ return FALSE
+ if(user.IsParalyzed() || user.IsStun() || user.restrained())
return FALSE
- playsound(user,'sound/effects/beepskyspinsabre.ogg', 60, 1)
- do_after(user, 2 SECONDS, user, TRUE, stayStill = FALSE)
- user.put_in_r_hand(new /obj/item/overcharged_emitter)
- user.visible_message(span_warning("[user]'s arm begins crackling loudly!"))
return TRUE
-/obj/item/overcharged_emitter
+/obj/item/melee/touch_attack/overcharged_emitter
name = "supercharged emitter"
desc = "The result of all the prosthetic's power building up in its palm. It's fading fast."
icon = 'icons/obj/wizard.dmi'
@@ -232,7 +249,7 @@
w_class = 5
var/flightdist = 8
-/obj/item/overcharged_emitter/afterattack(mob/living/L, mob/living/user, proximity)
+/obj/item/melee/touch_attack/overcharged_emitter/afterattack(mob/living/L, mob/living/user, proximity)
var/direction = user.dir
var/obj/item/bodypart/r_arm/R = user.get_bodypart(BODY_ZONE_R_ARM)
var/list/knockedback = list()
@@ -246,7 +263,7 @@
qdel(src, force = TRUE)
L.SpinAnimation(0.5 SECONDS, 2)
playsound(L,'sound/effects/gravhit.ogg', 60, 1)
- (R?.set_disabled(TRUE))
+ R?.set_disabled(TRUE)
to_chat(user, span_warning("The huge impact takes the arm out of commission!"))
shake_camera(L, 4, 3)
shake_camera(user, 2, 3)
@@ -294,14 +311,19 @@
for(var/mob/living/S in knockedback)
S.forceMove(T)
S.SpinAnimation(0.2 SECONDS, 1)
- sleep(0.001 SECONDS)
-/obj/item/overcharged_emitter/Initialize()
+/obj/item/melee/touch_attack/overcharged_emitter/Initialize()
. = ..()
ADD_TRAIT(src, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT)
animate(src, alpha = 50, time = 5 SECONDS)
QDEL_IN(src, 5 SECONDS)
+/obj/item/melee/touch_attack/overcharged_emitter/Destroy()
+ var/datum/action/cooldown/spell/our_spell = spell_which_made_us?.resolve()
+ if(our_spell)
+ our_spell.build_all_button_icons()
+ return ..()
+
//Seismic Arm
/obj/item/bodypart/r_arm/robot/seismic
name = "seismic right arm"
@@ -309,15 +331,22 @@
icon = 'icons/mob/augmentation/augments_seismic.dmi'
icon_state = "seismic_r_arm"
max_damage = 60
+ var/list/seismic_arm_moves = list(
+ /datum/action/cooldown/spell/pointed/seismic/lariat,
+ /datum/action/cooldown/spell/pointed/seismic/mop,
+ /datum/action/cooldown/spell/pointed/seismic/suplex,
+ /datum/action/cooldown/spell/touch/righthook,
+ )
/obj/item/bodypart/r_arm/robot/seismic/attach_limb(mob/living/carbon/C, special)
. = ..()
- for(var/datum/action/cooldown/spell/pointed/seismic/spells as anything in subtypesof(/datum/action/cooldown/spell/pointed/seismic))
- spells = new(C)
- spells.Grant(C)
+ for(var/datum/action/cooldown/spell/moves as anything in seismic_arm_moves)
+ moves = new moves(C)
+ moves.Grant(C)
/obj/item/bodypart/r_arm/robot/seismic/drop_limb(special)
var/mob/living/carbon/C = owner
- for(var/datum/action/cooldown/spell/pointed/seismic/spells in C.actions)
- spells.Remove(C)
+ for(var/datum/action/cooldown/spell/moves in C.actions)
+ if(LAZYFIND(seismic_arm_moves, moves))
+ moves.Remove(C)
return ..()
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 57311a10fe05..46512979f21c 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -59,7 +59,6 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
var/deadchat_name
var/datum/orbit_menu/orbit_menu
var/datum/spawners_menu/spawners_menu
- var/datum/action/unobserve/UO
// Current Viewrange
var/view = 0
@@ -421,7 +420,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
for(var/area/A as anything in get_sorted_areas())
if(!A.hidden)
filtered += A
- var/area/thearea = input("Area to jump to", "BOOYEA") as null|anything in filtered
+ var/area/thearea = tgui_input_list(usr, "Area to jump to", "BOOYEA", filtered)
if(!thearea)
return
@@ -483,7 +482,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
pixel_y = 0
animate(src, pixel_y = 2, time = 1 SECONDS, loop = -1)
-/mob/dead/observer/verb/jumptomob() //Moves the ghost instead of just changing the ghosts's eye -Nodrak
+/mob/dead/observer/verb/jump_to_mob() //Moves the ghost instead of just changing the ghosts's eye -Nodrak
set category = "Ghost"
set name = "Jump to Mob"
set desc = "Teleport to a mob"
@@ -491,16 +490,15 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(isobserver(usr)) //Make sure they're an observer!
- var/list/dest = list() //List of possible destinations (mobs)
+ var/list/possible_destinations = getpois(mobs_only = TRUE) //List of possible destinations (mobs)
var/target = null //Chosen target.
- dest += getpois(mobs_only = TRUE) //Fill list, prompt user with list
- target = input("Please, select a player!", "Jump to Mob", null, null) as null|anything in dest
+ target = tgui_input_list(usr, "Please, select a player!", "Jump to Mob", possible_destinations)
if (!target)//Make sure we actually have a target
return
else
- var/mob/M = dest[target] //Destination mob
+ var/mob/M = possible_destinations[target] //Destination mob
var/mob/A = src //Source mob
var/turf/T = get_turf(M) //Turf of the destination mob
@@ -525,7 +523,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
var/list/views = list()
for(var/i in 7 to max_view)
views |= i
- var/new_view = input("Choose your new view", "Modify view range", 0) as null|anything in views
+ var/new_view = tgui_input_list(usr, "Choose your new view", "Modify view range", views)
if(new_view)
client.rescale_view(new_view, 0, ((max_view*2)+1) - 15)
else
@@ -637,7 +635,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(!(L in GLOB.player_list) && !L.mind)
possessible += L
- var/mob/living/target = input("Your new life begins today!", "Possess Mob", null, null) as null|anything in possessible
+ var/mob/living/target = tgui_input_list(usr, "Your new life begins today!", "Possess Mob", sortUsernames(possessible))
if(!target)
return 0
@@ -840,7 +838,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
remove_verb(src, /mob/dead/observer/verb/possess)
/mob/dead/observer/reset_perspective(atom/A)
- UO?.Remove(src)
if(client)
if(ismob(client.eye) && (client.eye != src))
cleanup_observe()
@@ -860,7 +857,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
hide_other_mob_action_buttons(target)
LAZYREMOVE(target.observers, src)
actions = originalactions
- actions -= UO
update_action_buttons()
/mob/dead/observer/verb/observe()
@@ -904,26 +900,24 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(is_secret_level(mob_eye.z) && !client?.holder)
sight = null //we dont want ghosts to see through walls in secret areas
RegisterSignal(mob_eye, COMSIG_MOVABLE_Z_CHANGED, PROC_REF(on_observing_z_changed), TRUE)
- if(!UO)
- UO = new(src) // Convinent way to unobserve
- UO.Grant(src)
if(mob_eye.hud_used)
client.screen = list()
LAZYOR(mob_eye.observers, src)
mob_eye.hud_used.show_hud(mob_eye.hud_used.hud_version, src)
observetarget = mob_eye
-/datum/action/unobserve
+/datum/action/innate/unobserve
name = "Stop Observing"
desc = "Stops observing the person."
button_icon = 'icons/mob/mob.dmi'
button_icon_state = "ghost_nodir"
show_to_observers = FALSE
-/datum/action/unobserve/Trigger()
- owner.reset_perspective(null)
+/datum/action/innate/unobserve/Activate()
+ var/mob/dead/observer/ghost = owner
+ ghost.reset_perspective(null)
-/datum/action/unobserve/IsAvailable(feedback = FALSE)
+/datum/action/innate/unobserve/IsAvailable(feedback = FALSE)
return TRUE
/mob/dead/observer/proc/on_observing_z_changed(datum/source, oldz, newz)
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index be0e733053c3..0d3828b96862 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -1251,7 +1251,7 @@
else
mobility_flags |= MOBILITY_UI|MOBILITY_PULL
-
+ SEND_SIGNAL(src, COMSIG_LIVING_SET_BODY_POSITION, mobility_flags, .) //REMOVE THIS WHEN LAYING DOWN GETS PORTED
var/canitem = !paralyzed && !stun && conscious && !chokehold && !restrained && has_arms
if(canitem)
diff --git a/code/modules/mob/living/silicon/robot/inventory.dm b/code/modules/mob/living/silicon/robot/inventory.dm
index 3dc942248a97..359da210af97 100644
--- a/code/modules/mob/living/silicon/robot/inventory.dm
+++ b/code/modules/mob/living/silicon/robot/inventory.dm
@@ -144,7 +144,7 @@
if(disabled_modules & BORG_MODULE_ALL_DISABLED)
return FALSE
- inv1.icon_state = "[initial(inv1.icon_state)] +b"
+ inv1?.icon_state = "[initial(inv1?.icon_state)] +b"
disabled_modules |= BORG_MODULE_ALL_DISABLED
if(!quiet)
@@ -156,7 +156,7 @@
if(disabled_modules & BORG_MODULE_TWO_DISABLED)
return FALSE
- inv2.icon_state = "[initial(inv2.icon_state)] +b"
+ inv2?.icon_state = "[initial(inv2?.icon_state)] +b"
disabled_modules |= BORG_MODULE_TWO_DISABLED
if(!quiet)
@@ -168,7 +168,7 @@
if(disabled_modules & BORG_MODULE_THREE_DISABLED)
return FALSE
- inv3.icon_state = "[initial(inv3.icon_state)] +b"
+ inv3?.icon_state = "[initial(inv3?.icon_state)] +b"
disabled_modules |= BORG_MODULE_THREE_DISABLED
if(!quiet)
diff --git a/code/modules/mob/living/simple_animal/hostile/regalrat.dm b/code/modules/mob/living/simple_animal/hostile/regalrat.dm
index 84ef2136b5ae..272aec419480 100644
--- a/code/modules/mob/living/simple_animal/hostile/regalrat.dm
+++ b/code/modules/mob/living/simple_animal/hostile/regalrat.dm
@@ -109,12 +109,9 @@
// /datum/pet_command/point_targetting/attack/glockroach
// )
-/datum/action/cooldown/riot/Trigger()
- . = ..()
- if(!.)
- return
+/datum/action/cooldown/riot/Activate()
if(!isopenturf(owner.loc))
- to_chat(owner,"You can't use raise soldiers while in an object!")
+ to_chat(owner, span_warning("You can't use raise soldiers while in an object!"))
return
var/cap = CONFIG_GET(number/ratcap)
var/something_from_nothing = FALSE
@@ -171,7 +168,7 @@
new /obj/effect/decal/cleanable/dirt(T)
StartCooldown()
-/datum/action/cooldown/domain/Activate(atom/target)
+/datum/action/cooldown/domain/Activate()
StartCooldown(10 SECONDS)
domain()
StartCooldown()
diff --git a/code/modules/projectiles/guns/ballistic/bow.dm b/code/modules/projectiles/guns/ballistic/bow.dm
index c3d0c64db5ae..a627ad529b40 100644
--- a/code/modules/projectiles/guns/ballistic/bow.dm
+++ b/code/modules/projectiles/guns/ballistic/bow.dm
@@ -394,9 +394,12 @@
returning = TRUE
var/obj/item/break_blade/secondblade = thrower.get_inactive_held_item()
if(istype(secondblade))
- sleep(0.2 SECONDS)
- thrower.dropItemToGround(secondblade, silent = TRUE)
- secondblade.throw_at(target, range, speed, thrower, spin, diagonals_first, callback, force, quickstart)
+ addtimer(CALLBACK(src, PROC_REF(finish_throw), secondblade, target, range, speed, thrower, spin, diagonals_first, callback, force, quickstart), 0.2 SECONDS)
+
+/obj/item/break_blade/proc/finish_throw(obj/item/break_blade/secondblade, atom/target, range, speed, mob/thrower, \
+ spin, diagonals_first, datum/callback/callback, force, quickstart)
+ thrower.dropItemToGround(secondblade, silent = TRUE)
+ secondblade.throw_at(target, range, speed, thrower, spin, diagonals_first, callback, force, quickstart)
/obj/item/break_blade/proc/return_to(mob/living/user)
if(!istype(user))
diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm
index 6e9257df52cd..fbc14a11946e 100644
--- a/code/modules/reagents/chemistry/reagents/food_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm
@@ -397,22 +397,23 @@
/datum/reagent/drug/mushroomhallucinogen/on_mob_life(mob/living/carbon/M)
M.set_slurring_if_lower(1 SECONDS)
+
switch(current_cycle)
if(1 to 5)
- M.adjust_dizzy(5 SECONDS)
- M.set_drugginess(30)
+ M.set_dizzy_if_lower(5 SECONDS)
+ M.set_drugginess_if_lower(30 SECONDS)
if(prob(10))
M.emote(pick("twitch","giggle"))
if(5 to 10)
- M.adjust_jitter(10 SECONDS)
- M.adjust_dizzy(10 SECONDS)
- M.set_drugginess(35)
+ M.set_jitter_if_lower(20 SECONDS)
+ M.set_dizzy_if_lower(10 SECONDS)
+ M.set_drugginess_if_lower(35 SECONDS)
if(prob(20))
M.emote(pick("twitch","giggle"))
if (10 to INFINITY)
- M.adjust_jitter(20 SECONDS)
+ M.set_jitter_if_lower(40 SECONDS)
M.adjust_dizzy(20 SECONDS)
- M.set_drugginess(40)
+ M.set_drugginess_if_lower(40 SECONDS)
if(prob(30))
M.emote(pick("twitch","giggle"))
..()
diff --git a/code/modules/spells/spell_types/pointed/_pointed.dm b/code/modules/spells/spell_types/pointed/_pointed.dm
index a454a207c440..4145460cc76e 100644
--- a/code/modules/spells/spell_types/pointed/_pointed.dm
+++ b/code/modules/spells/spell_types/pointed/_pointed.dm
@@ -69,7 +69,6 @@
return TRUE
/datum/action/cooldown/spell/pointed/InterceptClickOn(mob/living/caller, params, atom/click_target)
-
var/atom/aim_assist_target
if(aim_assist && isturf(click_target))
// Find any human in the list. We aren't picky, it's aim assist after all
@@ -78,6 +77,8 @@
// If we didn't find a human, we settle for any living at all
aim_assist_target = locate(/mob/living) in click_target
+ caller.face_atom(click_target)
+
return ..(caller, params, aim_assist_target || click_target)
/datum/action/cooldown/spell/pointed/is_valid_target(atom/cast_on)
diff --git a/code/modules/spells/spell_types/pointed/fireball.dm b/code/modules/spells/spell_types/pointed/fireball.dm
index 7a23abe6ad21..ecadbf73c0f2 100644
--- a/code/modules/spells/spell_types/pointed/fireball.dm
+++ b/code/modules/spells/spell_types/pointed/fireball.dm
@@ -1,7 +1,7 @@
/datum/action/cooldown/spell/pointed/projectile/fireball
name = "Fireball"
desc = "This spell fires an explosive fireball at a target."
- button_icon_state = "fireball0"
+ button_icon_state = "fireball"
sound = 'sound/magic/fireball.ogg'
school = SCHOOL_EVOCATION
@@ -13,6 +13,7 @@
spell_requirements = SPELL_REQUIRES_NO_ANTIMAGIC
base_icon_state = "fireball"
+ active_icon_state = "fireball_active"
active_msg = "You prepare to cast your fireball spell!"
deactive_msg = "You extinguish your fireball... for now."
cast_range = 8
diff --git a/code/modules/surgery/organs/augment_legs.dm b/code/modules/surgery/organs/augment_legs.dm
index 55b836df6baf..9d48dceb8e6d 100644
--- a/code/modules/surgery/organs/augment_legs.dm
+++ b/code/modules/surgery/organs/augment_legs.dm
@@ -189,7 +189,7 @@
/obj/item/organ/cyberimp/leg/jumpboots/AddEffect()
ADD_TRAIT(owner, TRAIT_NOSLIPICE, "Jumpboot_implant")
- implant_ability = new
+ implant_ability = new(src)
implant_ability.Grant(owner)
/obj/item/organ/cyberimp/leg/jumpboots/RemoveEffect()
@@ -203,11 +203,10 @@
desc = "Dash forward."
button_icon = 'icons/mob/actions/actions_items.dmi'
button_icon_state = "jetboot"
- check_flags = AB_CHECK_HANDS_BLOCKED| AB_CHECK_IMMOBILE|AB_CHECK_CONSCIOUS
+ check_flags = AB_CHECK_HANDS_BLOCKED | AB_CHECK_IMMOBILE | AB_CHECK_CONSCIOUS
cooldown_time = 6 SECONDS
var/jumpdistance = 5 //-1 from to see the actual distance, e.g 4 goes over 3 tiles
var/jumpspeed = 3
- var/mob/living/carbon/human/holder
/datum/action/cooldown/boost/link_to(target)
..()
@@ -216,24 +215,18 @@
LAZYINITLIST(I.actions)
I.actions += src
-/datum/action/cooldown/boost/Grant(mob/user)
- . = ..()
- holder = user
+/datum/action/cooldown/boost/Activate()
+ var/mob/living/carbon/user = owner
+ var/atom/target = get_edge_target_turf(owner, owner.dir) //gets the user's direction
-/datum/action/cooldown/boost/Trigger()
- . = ..()
- if(!.)
+ if(!owner.throw_at(target, jumpdistance, jumpspeed, spin = FALSE, diagonals_first = TRUE))
+ to_chat(owner, span_warning("Something prevents you from dashing forward!"))
return
- var/atom/target = get_edge_target_turf(holder, holder.dir) //gets the user's direction
-
- if (holder.throw_at(target, jumpdistance, jumpspeed, spin = FALSE, diagonals_first = TRUE))
- StartCooldown()
- holder.Immobilize(0.1 SECONDS)
- playsound(holder, 'sound/effects/stealthoff.ogg', 50, 1, 1)
- holder.visible_message(span_warning("[usr] dashes forward into the air!"))
- else
- to_chat(holder, span_warning("Something prevents you from dashing forward!"))
+ user.Immobilize(0.1 SECONDS)
+ playsound(owner, 'sound/effects/stealthoff.ogg', 50, TRUE, 1)
+ owner.visible_message(span_warning("[owner] dashes forward into the air!"))
+ StartCooldown()
//------------wheelies implant
/obj/item/organ/cyberimp/leg/wheelies
diff --git a/icons/effects/visor_reticule.dmi b/icons/effects/mouse_pointers/visor_reticule.dmi
similarity index 100%
rename from icons/effects/visor_reticule.dmi
rename to icons/effects/mouse_pointers/visor_reticule.dmi
diff --git a/icons/mob/actions/actions_spells.dmi b/icons/mob/actions/actions_spells.dmi
index d9a7fc5d17ad..9373204fc7c5 100644
Binary files a/icons/mob/actions/actions_spells.dmi and b/icons/mob/actions/actions_spells.dmi differ
diff --git a/icons/mob/screen_ghost.dmi b/icons/mob/screen_ghost.dmi
index f7a312e33ff7..f4010e95c09a 100644
Binary files a/icons/mob/screen_ghost.dmi and b/icons/mob/screen_ghost.dmi differ
diff --git a/yogstation.dme b/yogstation.dme
index 10965f3f17d4..f9264ed83454 100644
--- a/yogstation.dme
+++ b/yogstation.dme
@@ -141,6 +141,7 @@
#include "code\__DEFINES\dcs\signals\signals_food.dm"
#include "code\__DEFINES\dcs\signals\signals_gib.dm"
#include "code\__DEFINES\dcs\signals\signals_global.dm"
+#include "code\__DEFINES\dcs\signals\signals_heretic.dm"
#include "code\__DEFINES\dcs\signals\signals_global_object.dm"
#include "code\__DEFINES\dcs\signals\signals_janitor.dm"
#include "code\__DEFINES\dcs\signals\signals_mood.dm"
diff --git a/yogstation/code/modules/antagonists/gang/gang.dm b/yogstation/code/modules/antagonists/gang/gang.dm
index 5f10a1604a97..6e8018670d56 100644
--- a/yogstation/code/modules/antagonists/gang/gang.dm
+++ b/yogstation/code/modules/antagonists/gang/gang.dm
@@ -1,11 +1,10 @@
/datum/antagonist/gang
name = "Gangster"
roundend_category = "gangsters"
- antag_hud_name = "hud_gangster"
+ antag_hud_name = "gangster"
can_coexist_with_others = FALSE
job_rank = ROLE_GANG
antagpanel_category = "Gang"
- var/hud_type = "gangster"
var/message_name = "Gangster"
var/datum/team/gang/gang
preview_outfit = /datum/outfit/gangster
@@ -17,7 +16,34 @@
return FALSE
/datum/antagonist/gang/apply_innate_effects(mob/living/mob_override)
- add_team_hud(mob_override || owner.current, /datum/antagonist/gang)
+ add_team_hud(mob_override || owner.current)
+
+/datum/antagonist/gang/add_team_hud(mob/target)
+ QDEL_NULL(team_hud_ref)
+
+ team_hud_ref = WEAKREF(target.add_alt_appearance(
+ /datum/atom_hud/alternate_appearance/basic/has_antagonist,
+ "antag_team_hud_[REF(src)]",
+ hud_image_on(target),
+ ))
+
+ var/datum/atom_hud/alternate_appearance/basic/has_antagonist/hud = team_hud_ref.resolve()
+
+ var/list/mob/living/mob_list = list()
+ for(var/datum/mind/collegues_minds as anything in gang.members)
+ mob_list += collegues_minds.current
+
+ for (var/datum/atom_hud/alternate_appearance/basic/has_antagonist/antag_hud as anything in GLOB.has_antagonist_huds)
+ if(!(antag_hud.target in mob_list))
+ continue
+ antag_hud.show_to(target)
+ hud.show_to(antag_hud.target)
+
+/datum/antagonist/gang/hud_image_on(mob/hud_loc)
+ var/image/hud = image(hud_icon, hud_loc, antag_hud_name)
+ hud.color = gang.color
+ hud.plane = ABOVE_HUD_PLANE //not quite but needed
+ return hud
/datum/antagonist/gang/get_team()
return gang
@@ -150,7 +176,7 @@
// Boss type. Those can use gang tools to buy items for their gang, in particular the Dominator, used to win the gamemode, along with more gang tools to promote fellow gangsters to boss status.
/datum/antagonist/gang/boss
name = "Gang boss"
- hud_type = "gang_boss"
+ antag_hud_name = "gang_boss"
message_name = "Leader"
/datum/antagonist/gang/boss/on_gain()