diff --git a/code/__defines/dcs/signals_ch/signals_mob/signals_mob_main_ch.dm b/code/__defines/dcs/signals_ch/signals_mob/signals_mob_main_ch.dm
new file mode 100644
index 0000000000..ae06f69a02
--- /dev/null
+++ b/code/__defines/dcs/signals_ch/signals_mob/signals_mob_main_ch.dm
@@ -0,0 +1,2 @@
+///from base of /mob/verb/pointed: (atom/A)
+#define COMSIG_MOB_POINTED "mob_pointed"
diff --git a/code/game/atoms_movable_ch.dm b/code/game/atoms_movable_ch.dm
index b1ae68fb7c..e3ef8169ee 100644
--- a/code/game/atoms_movable_ch.dm
+++ b/code/game/atoms_movable_ch.dm
@@ -73,3 +73,9 @@
cut_overlay(source)
if(em_block == source)
em_block = null
+
+/atom/movable/proc/abstract_move(atom/new_loc)
+ var/atom/old_loc = loc
+ var/direction = get_dir(old_loc, new_loc)
+ loc = new_loc
+ Moved(old_loc, direction, TRUE)
diff --git a/code/game/objects/effects/decals/misc.dm b/code/game/objects/effects/decals/misc.dm
index df2d3ee32b..31257f49de 100644
--- a/code/game/objects/effects/decals/misc.dm
+++ b/code/game/objects/effects/decals/misc.dm
@@ -1,3 +1,4 @@
+/* CHOMPEdit - This is now in modular_chomp/modules/point/point.dm
/obj/effect/decal/point
name = "arrow"
desc = "It's an arrow hanging in mid-air. There may be a wizard about."
@@ -6,9 +7,9 @@
plane = ABOVE_PLANE
anchored = TRUE
mouse_opacity = 0
-
+*/
// Used for spray that you spray at walls, tables, hydrovats etc
/obj/effect/decal/spraystill
density = FALSE
anchored = TRUE
- plane = ABOVE_PLANE
\ No newline at end of file
+ plane = ABOVE_PLANE
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 76a1672a2e..5f5ac3c912 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -807,11 +807,20 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
W.add_hiddenprint(src)
W.visible_message("[span_red("Invisible fingers crudely paint something in blood on [T]...")]")
+// CHOMPEdit Start - Point Refactor
+/*
/mob/observer/dead/pointed(atom/A as mob|obj|turf in view())
if(!..())
return 0
usr.visible_message("[src] points to [A].")
return 1
+*/
+
+/mob/observer/dead/_pointed(atom/pointed_at)
+ if(!..())
+ return FALSE
+
+ visible_message(span_deadsay("[src] points to [pointed_at]."))
/mob/observer/dead/proc/manifest(mob/user)
is_manifest = TRUE
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index e39220357b..e54fb13d81 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -87,16 +87,26 @@
return
//mob verbs are faster than object verbs. See above.
-/mob/living/pointed(atom/A as mob|obj|turf in view())
+// CHOMPEdit Start - Point refactor
+/mob/living/pointed(atom/A as mob|obj|turf in view(client.view, src))
if(src.stat || src.restrained())
- return 0
+ return FALSE
if(src.status_flags & FAKEDEATH)
- return 0
+ return FALSE
+ /*
if(!..())
return 0
usr.visible_message("[src] points to [A].")
- return 1
+*/
+ return ..()
+
+/mob/living/_pointed(atom/pointing_at)
+ if(!..())
+ return FALSE
+
+ visible_message(span_info("[src] points at [pointing_at]."), span_info("You point at [pointing_at]."))
+// CHOMPEdit End
/mob/living/verb/succumb()
set name = "Succumb to death"
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index eaac9283de..d14b1f104b 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -230,7 +230,7 @@
client.perspective = EYE_PERSPECTIVE
client.eye = loc
return TRUE
-
+/* CHOMPEdit - Moved to modular_chomp/modules/point/point.dm
/mob/verb/pointed(atom/A as mob|obj|turf in view())
set name = "Point To"
set category = "Object"
@@ -260,7 +260,7 @@
face_atom(A)
return 1
-
+*/
/mob/proc/ret_grab(list/L, flag)
return
diff --git a/modular_chomp/code/modules/point/point.dm b/modular_chomp/code/modules/point/point.dm
new file mode 100644
index 0000000000..b4c9d90ba2
--- /dev/null
+++ b/modular_chomp/code/modules/point/point.dm
@@ -0,0 +1,89 @@
+#define POINT_TIME (2.5 SECONDS)
+
+/atom/movable/proc/point_at(atom/pointed_atom)
+ if(!isturf(loc))
+ return
+
+ if (pointed_atom in src)
+ create_point_bubble(pointed_atom)
+ return
+
+ var/turf/tile = get_turf(pointed_atom)
+ if (!tile)
+ return
+
+ var/turf/our_tile = get_turf(src)
+ var/obj/visual = new /obj/effect/temp_visual/point(our_tile, invisibility)
+
+ animate(visual, pixel_x = (tile.x - our_tile.x) * world.icon_size + pointed_atom.pixel_x, pixel_y = (tile.y - our_tile.y) * world.icon_size + pointed_atom.pixel_y, time = 1.7, easing = EASE_OUT)
+
+/atom/movable/proc/create_point_bubble(atom/pointed_atom)
+ var/mutable_appearance/thought_bubble = mutable_appearance(
+ 'modular_chomp/icons/effects/effects.dmi',
+ "thought_bubble",
+ plane = PLANE_RUNECHAT,
+ appearance_flags = KEEP_APART,
+ )
+
+ var/mutable_appearance/pointed_atom_appearance = new(pointed_atom.appearance)
+ pointed_atom_appearance.blend_mode = BLEND_INSET_OVERLAY
+ pointed_atom_appearance.plane = FLOAT_PLANE
+ pointed_atom_appearance.layer = FLOAT_LAYER
+ pointed_atom_appearance.pixel_x = 0
+ pointed_atom_appearance.pixel_y = 0
+ thought_bubble.overlays += pointed_atom_appearance
+
+ thought_bubble.pixel_x = 16
+ thought_bubble.pixel_y = 32
+ thought_bubble.alpha = 200
+ thought_bubble.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
+
+ var/mutable_appearance/point_visual = mutable_appearance(
+ 'icons/mob/screen1.dmi',
+ "arrow"
+ )
+
+ thought_bubble.overlays += point_visual
+
+ add_overlay(thought_bubble)
+ LAZYADD(update_on_z, thought_bubble)
+ addtimer(CALLBACK(src, PROC_REF(clear_point_bubble), thought_bubble), POINT_TIME)
+
+/atom/movable/proc/clear_point_bubble(mutable_appearance/thought_bubble)
+ LAZYREMOVE(update_on_z, thought_bubble)
+ cut_overlay(thought_bubble)
+
+/obj/effect/temp_visual/point
+ name = "pointer"
+ icon = 'icons/mob/screen1.dmi'
+ icon_state = "arrow"
+ plane = ABOVE_PLANE
+ duration = POINT_TIME
+
+/obj/effect/temp_visual/point/Initialize(mapload, set_invis = 0)
+ . = ..()
+ var/atom/old_loc = loc
+ abstract_move(get_turf(src))
+ pixel_x = old_loc.pixel_x
+ pixel_y = old_loc.pixel_y
+ invisibility = set_invis
+
+#undef POINT_TIME
+
+/mob/verb/pointed(atom/A as mob|obj|turf in view())
+ set name = "Point To"
+ set category = "Object"
+
+ if(istype(A, /obj/effect/temp_visual/point))
+ return FALSE
+
+ DEFAULT_QUEUE_OR_CALL_VERB(VERB_CALLBACK(src, PROC_REF(_pointed), A))
+
+/mob/proc/_pointed(atom/pointing_at)
+ if(client && !(pointing_at in view(client.view, src)))
+ return FALSE
+
+ point_at(pointing_at)
+
+ SEND_SIGNAL(src, COMSIG_MOB_POINTED, pointing_at)
+ return TRUE
diff --git a/modular_chomp/icons/effects/effects.dmi b/modular_chomp/icons/effects/effects.dmi
index eca4771b5e..d88ec3bd05 100644
Binary files a/modular_chomp/icons/effects/effects.dmi and b/modular_chomp/icons/effects/effects.dmi differ
diff --git a/vorestation.dme b/vorestation.dme
index 31718d2935..1276218ce6 100644
--- a/vorestation.dme
+++ b/vorestation.dme
@@ -172,6 +172,7 @@
#include "code\__defines\dcs\signals.dm"
#include "code\__defines\dcs\signals_ch.dm"
#include "code\__defines\dcs\signals_ch\signals_subsystem.dm"
+#include "code\__defines\dcs\signals_ch\signals_mob\signals_mob_main_ch.dm"
#include "code\__defines\traits\_traits.dm"
#include "code\_global_vars\_regexes.dm"
#include "code\_global_vars\bitfields.dm"
@@ -5005,6 +5006,7 @@
#include "modular_chomp\code\modules\planet\sif.dm"
#include "modular_chomp\code\modules\planet\smokestar\turf.dm"
#include "modular_chomp\code\modules\player_tips\player_tips_list.dm"
+#include "modular_chomp\code\modules\point\point.dm"
#include "modular_chomp\code\modules\power\cells\device_cells.dm"
#include "modular_chomp\code\modules\power\cells\esoteric_cells.dm"
#include "modular_chomp\code\modules\power\cells\power_cells.dm"