From 7125897ebbd4da88ec9c1ed8d4dbce9a97d706c9 Mon Sep 17 00:00:00 2001
From: Contrabang <91113370+Contrabang@users.noreply.github.com>
Date: Tue, 2 Sep 2025 16:47:56 -0400
Subject: [PATCH] Refactors Mousepointers + Code improvements (#29960)
* blah
* tweaks
* refactor
* awesome
* put everything in mouse_icons folder
* make spells work
* update twin
* tweak
* woop woop
* remove dynamic mousepointers
* bam
---
code/__DEFINES/mob_defines.dm | 7 ++++++
code/_onclick/drag_drop.dm | 4 ---
code/datums/components/fullauto.dm | 7 +++---
code/datums/spells/spell_base.dm | 16 ++++++------
code/game/gamemodes/cult/blood_magic.dm | 2 +-
.../gamemodes/malfunction/Malf_Modules.dm | 8 +++---
code/game/mecha/combat/combat.dm | 23 ++++++------------
code/game/objects/items.dm | 3 +++
code/modules/client/client_defines.dm | 7 ------
.../modules/mob/living/carbon/carbon_procs.dm | 12 +++------
code/modules/mob/living/carbon/give.dm | 4 +--
code/modules/mob/living/living.dm | 4 ---
code/modules/mob/living/living_logout.dm | 2 --
.../mob/living/silicon/ai/ai_programs.dm | 22 ++++++++---------
.../living/silicon/robot/robot_inventory.dm | 2 --
.../mob/living/silicon/robot/robot_mob.dm | 2 +-
code/modules/mob/mob.dm | 21 ++++++++++++++++
code/modules/mob/mob_login_base.dm | 2 ++
code/modules/mob/mob_vars.dm | 2 ++
.../vehicle/tg_vehicles/cars/clowncar.dm | 7 +++---
icons/mouse_icons/base_item.dmi | Bin 0 -> 264 bytes
.../{effects => mouse_icons}/cult_target.dmi | Bin
.../explode_machine_target.dmi} | Bin
icons/{mecha => mouse_icons}/mecha_mouse.dmi | Bin
.../override_machine_target.dmi | Bin
.../weapon_pointer.dmi | Bin
26 files changed, 80 insertions(+), 77 deletions(-)
create mode 100644 icons/mouse_icons/base_item.dmi
rename icons/{effects => mouse_icons}/cult_target.dmi (100%)
rename icons/{effects/overload_machine_target.dmi => mouse_icons/explode_machine_target.dmi} (100%)
rename icons/{mecha => mouse_icons}/mecha_mouse.dmi (100%)
rename icons/{effects => mouse_icons}/override_machine_target.dmi (100%)
rename icons/{effects/mouse_pointers => mouse_icons}/weapon_pointer.dmi (100%)
diff --git a/code/__DEFINES/mob_defines.dm b/code/__DEFINES/mob_defines.dm
index 3f6ef0995df..ca99b2f63ff 100644
--- a/code/__DEFINES/mob_defines.dm
+++ b/code/__DEFINES/mob_defines.dm
@@ -394,3 +394,10 @@
#define NPC_DEFAULT_MIN_TEMP 250
/// Default maximum body temperature mobs can exist in before taking damage
#define NPC_DEFAULT_MAX_TEMP 350
+
+#define MP_SPELL_PRIORITY 1
+#define MP_THROW_MODE_PRIORITY 2
+#define MP_GIVE_MODE_PRIORITY 3
+#define MP_AUTO_GUN_PRIORITY 4
+#define MP_CLOWN_CAR_PRIORITY 5
+#define MP_MECHA_PRIORITY 6
diff --git a/code/_onclick/drag_drop.dm b/code/_onclick/drag_drop.dm
index 9f40c657b95..4392619e69d 100644
--- a/code/_onclick/drag_drop.dm
+++ b/code/_onclick/drag_drop.dm
@@ -53,8 +53,6 @@ to inform the game this action was expected and its fine
if(QDELETED(object)) // Yep, you can click on qdeleted things before they have time to nullspace. Fun.
return
SEND_SIGNAL(src, COMSIG_CLIENT_MOUSEDOWN, object, location, control, params)
- if(mouse_down_icon)
- mouse_pointer_icon = mouse_down_icon
var/delay = mob.CanMobAutoclick(object, location, params)
if(delay)
selected_target[1] = object
@@ -66,8 +64,6 @@ to inform the game this action was expected and its fine
/client/MouseUp(object, location, control, params)
if(SEND_SIGNAL(src, COMSIG_CLIENT_MOUSEUP, object, location, control, params) & COMPONENT_CLIENT_MOUSEUP_INTERCEPT)
click_intercept_time = world.time
- if(mouse_up_icon)
- mouse_pointer_icon = mouse_up_icon
selected_target[1] = null
/mob/proc/CanMobAutoclick(object, location, params)
diff --git a/code/datums/components/fullauto.dm b/code/datums/components/fullauto.dm
index 0c2c1a20a8f..c82266a6be8 100644
--- a/code/datums/components/fullauto.dm
+++ b/code/datums/components/fullauto.dm
@@ -97,6 +97,7 @@
if(!QDELETED(clicker))
UnregisterSignal(clicker, list(COMSIG_CLIENT_MOUSEDOWN, COMSIG_CLIENT_MOUSEUP, COMSIG_CLIENT_MOUSEDRAG))
+ clicker.mob.remove_mousepointer(MP_AUTO_GUN_PRIORITY)
mouse_status = AUTOFIRE_MOUSEUP // In regards to the component there's no click anymore to care about.
clicker = null
if(!QDELETED(shooter))
@@ -164,8 +165,7 @@
return
autofire_stat = AUTOFIRE_STAT_FIRING
- clicker.mouse_override_icon = 'icons/effects/mouse_pointers/weapon_pointer.dmi'
- clicker.mouse_pointer_icon = clicker.mouse_override_icon
+ clicker.mob.add_mousepointer(MP_AUTO_GUN_PRIORITY, 'icons/mouse_icons/weapon_pointer.dmi')
if(mouse_status == AUTOFIRE_MOUSEUP) // See mouse_status definition for the reason for this.
RegisterSignal(clicker, COMSIG_CLIENT_MOUSEUP, PROC_REF(on_mouse_up))
@@ -206,8 +206,7 @@
STOP_PROCESSING(SSprojectiles, src)
autofire_stat = AUTOFIRE_STAT_ALERT
if(clicker)
- clicker.mouse_override_icon = null
- clicker.mouse_pointer_icon = clicker.mouse_override_icon
+ clicker.mob.remove_mousepointer(MP_AUTO_GUN_PRIORITY)
UnregisterSignal(clicker, COMSIG_CLIENT_MOUSEDRAG)
if(!QDELETED(shooter))
UnregisterSignal(shooter, COMSIG_MOB_SWAPPED_HANDS)
diff --git a/code/datums/spells/spell_base.dm b/code/datums/spells/spell_base.dm
index f783b871951..12aaccc3158 100644
--- a/code/datums/spells/spell_base.dm
+++ b/code/datums/spells/spell_base.dm
@@ -136,7 +136,7 @@ GLOBAL_LIST_INIT(spells, typesof(/datum/spell))
user.ranged_ability = src
ranged_ability_user = user
user.client.click_intercept = new /datum/click_intercept/proc_holder(user.client, user.ranged_ability)
- add_mousepointer(user.client)
+ add_mousepointer(user)
active = TRUE
if(msg)
to_chat(user, msg)
@@ -145,13 +145,13 @@ GLOBAL_LIST_INIT(spells, typesof(/datum/spell))
/datum/spell/proc/update_spell_icon()
return
-/datum/spell/proc/add_mousepointer(client/C)
- if(C && ranged_mousepointer && C.mouse_pointer_icon == initial(C.mouse_pointer_icon))
- C.mouse_pointer_icon = ranged_mousepointer
+/datum/spell/proc/add_mousepointer(mob/user)
+ if(ranged_mousepointer)
+ user.add_mousepointer(MP_SPELL_PRIORITY, ranged_mousepointer)
-/datum/spell/proc/remove_mousepointer(client/C)
- if(C && ranged_mousepointer && C.mouse_pointer_icon == ranged_mousepointer)
- C.mouse_pointer_icon = initial(C.mouse_pointer_icon)
+/datum/spell/proc/remove_mousepointer(mob/user)
+ if(ranged_mousepointer)
+ user.remove_mousepointer(MP_SPELL_PRIORITY)
/datum/spell/proc/remove_ranged_ability(mob/user, msg)
if(!user || (user.ranged_ability && user.ranged_ability != src)) //To avoid removing the wrong ability
@@ -162,7 +162,7 @@ GLOBAL_LIST_INIT(spells, typesof(/datum/spell))
if(user.client)
qdel(user.client.click_intercept)
user.client.click_intercept = null
- remove_mousepointer(user.client)
+ remove_mousepointer(user)
if(msg)
to_chat(user, msg)
update_spell_icon()
diff --git a/code/game/gamemodes/cult/blood_magic.dm b/code/game/gamemodes/cult/blood_magic.dm
index 9f463ec006b..f33884083f7 100644
--- a/code/game/gamemodes/cult/blood_magic.dm
+++ b/code/game/gamemodes/cult/blood_magic.dm
@@ -271,7 +271,7 @@
return TRUE
/datum/spell/horror
- ranged_mousepointer = 'icons/effects/cult_target.dmi'
+ ranged_mousepointer = 'icons/mouse_icons/cult_target.dmi'
var/datum/action/innate/cult/blood_spell/attached_action
/datum/spell/horror/Destroy()
diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm
index 8c15e1bc1e0..a13c4ed2fc8 100644
--- a/code/game/gamemodes/malfunction/Malf_Modules.dm
+++ b/code/game/gamemodes/malfunction/Malf_Modules.dm
@@ -490,7 +490,7 @@
desc = "Overheats a machine, causing a moderately-sized explosion after a short time."
action_icon_state = "overload_machine"
uses = 4
- ranged_mousepointer = 'icons/effects/cult_target.dmi'
+ ranged_mousepointer = 'icons/mouse_icons/cult_target.dmi'
selection_activated_message = "You tap into the station's powernet. Click on a machine to detonate it, or use the ability again to cancel."
selection_deactivated_message = "You release your hold on the powernet."
@@ -531,7 +531,7 @@
desc = "Animates a targeted machine, causing it to attack anyone nearby."
action_icon_state = "override_machine"
uses = 4
- ranged_mousepointer = 'icons/effects/override_machine_target.dmi'
+ ranged_mousepointer = 'icons/mouse_icons/override_machine_target.dmi'
selection_activated_message = "You tap into the station's powernet. Click on a machine to animate it, or use the ability again to cancel."
selection_deactivated_message = "You release your hold on the powernet."
@@ -888,7 +888,7 @@
desc = "Shocks a cyborg back to 'life' after a short delay."
action_icon_state = "overload_machine"
uses = 2
- ranged_mousepointer = 'icons/effects/overload_machine_target.dmi'
+ ranged_mousepointer = 'icons/mouse_icons/explode_machine_target.dmi'
selection_activated_message = "Call to address 0FFFFFFF in APC logic thread, awaiting user response."
selection_deactivated_message = "APC logic thread restarting..."
var/is_active = FALSE
@@ -934,7 +934,7 @@
name = "Roll Over"
action_icon_state = "roll_over"
desc = "Allows you to roll over in the direction of your choosing, crushing anything in your way."
- ranged_mousepointer = 'icons/effects/cult_target.dmi'
+ ranged_mousepointer = 'icons/mouse_icons/cult_target.dmi'
selection_activated_message = "Your inner servos shift as you prepare to roll around. Click adjacent tiles to roll into them!"
selection_deactivated_message = "You disengage your rolling protocols."
COOLDOWN_DECLARE(time_til_next_tilt)
diff --git a/code/game/mecha/combat/combat.dm b/code/game/mecha/combat/combat.dm
index 481dc8f6e77..555c13ffa14 100644
--- a/code/game/mecha/combat/combat.dm
+++ b/code/game/mecha/combat/combat.dm
@@ -5,24 +5,17 @@
armor = list(MELEE = 30, BULLET = 30, LASER = 15, ENERGY = 20, BOMB = 20, RAD = 0, FIRE = 100)
destruction_sleep_duration = 4 SECONDS
-/obj/mecha/combat/moved_inside(mob/living/carbon/human/H as mob)
+/obj/mecha/combat/moved_inside(mob/living/carbon/human/H)
if(..())
- if(H.client)
- H.client.mouse_pointer_icon = file("icons/mecha/mecha_mouse.dmi")
- return 1
- else
- return 0
+ H.add_mousepointer(MP_MECHA_PRIORITY, 'icons/mouse_icons/mecha_mouse.dmi')
+ return TRUE
-/obj/mecha/combat/mmi_moved_inside(obj/item/mmi/mmi_as_oc as obj, mob/user as mob)
+/obj/mecha/combat/mmi_moved_inside(obj/item/mmi/mmi_as_oc, mob/user as mob)
if(..())
- if(occupant.client)
- occupant.client.mouse_pointer_icon = file("icons/mecha/mecha_mouse.dmi")
- return 1
- else
- return 0
-
+ occupant.add_mousepointer(MP_MECHA_PRIORITY, 'icons/mouse_icons/mecha_mouse.dmi')
+ return TRUE
/obj/mecha/combat/go_out()
- if(occupant && occupant.client)
- occupant.client.mouse_pointer_icon = initial(occupant.client.mouse_pointer_icon)
+ if(occupant)
+ occupant.remove_mousepointer(MP_MECHA_PRIORITY)
..()
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index ad0f66e1d69..beb3de104b9 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -1076,3 +1076,6 @@ GLOBAL_DATUM_INIT(welding_sparks, /mutable_appearance, mutable_appearance('icons
if(iscarbon(user))
var/mob/living/carbon/C = user
C.update_hands_hud()
+
+/obj/item/proc/on_hands_swap(mob/user, in_active_hand)
+ return
diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm
index ad8d8734e02..be558fbe601 100644
--- a/code/modules/client/client_defines.dm
+++ b/code/modules/client/client_defines.dm
@@ -134,13 +134,6 @@
/// The client's movement keybindings to directions, which work regardless of modifiers.
var/list/movement_kb_dirs = list()
- /// Used to make a special mouse cursor, this one for mouse up icon
- var/mouse_up_icon = null
- /// Used to make a special mouse cursor, this one for mouse up icon
- var/mouse_down_icon = null
- /// Used to override the mouse cursor so it doesnt get reset
- var/mouse_override_icon = null
-
/// Autoclick list of two elements, first being the clicked thing, second being the parameters.
var/list/atom/selected_target[2]
/// Used in MouseDrag to preserve the original mouse click parameters
diff --git a/code/modules/mob/living/carbon/carbon_procs.dm b/code/modules/mob/living/carbon/carbon_procs.dm
index 26784e21515..08b47aaa57b 100644
--- a/code/modules/mob/living/carbon/carbon_procs.dm
+++ b/code/modules/mob/living/carbon/carbon_procs.dm
@@ -233,6 +233,8 @@
return
hand = !hand
update_hands_hud()
+ r_hand?.on_hands_swap(src, hand == HAND_BOOL_RIGHT)
+ l_hand?.on_hands_swap(src, hand == HAND_BOOL_LEFT)
SEND_SIGNAL(src, COMSIG_CARBON_SWAP_HANDS)
@@ -706,24 +708,18 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven
if(I)
SEND_SIGNAL(I, COMSIG_CARBON_TOGGLE_THROW, in_throw_mode)
-#define THROW_MODE_ICON 'icons/effects/cult_target.dmi'
-
/mob/living/carbon/proc/throw_mode_off()
in_throw_mode = FALSE
if(throw_icon) //in case we don't have the HUD and we use the hotkey
throw_icon.icon_state = "act_throw_off"
- if(client?.mouse_pointer_icon == THROW_MODE_ICON)
- client.mouse_pointer_icon = initial(client.mouse_pointer_icon)
+ remove_mousepointer(MP_THROW_MODE_PRIORITY)
/mob/living/carbon/proc/throw_mode_on()
SIGNAL_HANDLER //This signal is here so we can turn throw mode back on via carp when an object is caught
in_throw_mode = TRUE
if(throw_icon)
throw_icon.icon_state = "act_throw_on"
- if(client?.mouse_pointer_icon == initial(client.mouse_pointer_icon))
- client.mouse_pointer_icon = THROW_MODE_ICON
-
-#undef THROW_MODE_ICON
+ add_mousepointer(MP_THROW_MODE_PRIORITY, 'icons/mouse_icons/cult_target.dmi')
/mob/proc/throw_item(atom/target)
return
diff --git a/code/modules/mob/living/carbon/give.dm b/code/modules/mob/living/carbon/give.dm
index 7ab9d9cf540..336e75e8225 100644
--- a/code/modules/mob/living/carbon/give.dm
+++ b/code/modules/mob/living/carbon/give.dm
@@ -70,14 +70,14 @@
/datum/click_intercept/give/New(client/C)
..()
- holder.mouse_pointer_icon = 'icons/mouse_icons/give_item.dmi'
+ holder.mob.add_mousepointer(MP_GIVE_MODE_PRIORITY, 'icons/mouse_icons/give_item.dmi')
to_chat(holder, "You can now left click on someone to give them your held item.")
RegisterSignal(holder.mob.get_active_hand(), list(COMSIG_PARENT_QDELETING, COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED), PROC_REF(signal_qdel))
RegisterSignal(holder.mob, list(SIGNAL_ADDTRAIT(TRAIT_HANDS_BLOCKED), COMSIG_CARBON_SWAP_HANDS), PROC_REF(signal_qdel))
/datum/click_intercept/give/Destroy(force = FALSE, ...)
- holder.mouse_pointer_icon = initial(holder.mouse_pointer_icon)
+ holder.mob.remove_mousepointer(MP_GIVE_MODE_PRIORITY)
if(!item_offered)
to_chat(holder.mob, "You're no longer trying to give someone your held item.")
return ..()
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 110227eafb1..563a5105bf5 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -62,11 +62,7 @@
return ..()
/mob/living/ghostize(can_reenter_corpse = 1)
- var/prev_client = client
. = ..()
- if(.)
- if(ranged_ability && prev_client)
- ranged_ability.remove_mousepointer(prev_client)
SEND_SIGNAL(src, COMSIG_LIVING_GHOSTIZED)
/// Legacy method for simplemobs to handle turning off their AI.
diff --git a/code/modules/mob/living/living_logout.dm b/code/modules/mob/living/living_logout.dm
index e34c9bc6cea..195feb42d78 100644
--- a/code/modules/mob/living/living_logout.dm
+++ b/code/modules/mob/living/living_logout.dm
@@ -1,7 +1,5 @@
/mob/living/Logout()
update_z(null)
- if(ranged_ability && client)
- ranged_ability.remove_mousepointer(client)
if(isobj(loc))
var/obj/our_location = loc
if(length(our_location.client_mobs_in_contents))
diff --git a/code/modules/mob/living/silicon/ai/ai_programs.dm b/code/modules/mob/living/silicon/ai/ai_programs.dm
index a136eaf8514..250f4959ba0 100644
--- a/code/modules/mob/living/silicon/ai/ai_programs.dm
+++ b/code/modules/mob/living/silicon/ai/ai_programs.dm
@@ -295,7 +295,7 @@
desc = "Changes the color of a selected light."
action_icon = 'icons/effects/random_spawners.dmi'
action_icon_state = "glowstick"
- ranged_mousepointer = 'icons/mecha/mecha_mouse.dmi'
+ ranged_mousepointer = 'icons/mouse_icons/mecha_mouse.dmi'
base_cooldown = 30 SECONDS
cooldown_min = 5 SECONDS
level_max = 5
@@ -367,7 +367,7 @@
desc = "Recharge an APC, Borg, or Mech with power directly from your SMES."
action_icon = 'icons/obj/power.dmi'
action_icon_state = "smes-o"
- ranged_mousepointer = 'icons/mecha/mecha_mouse.dmi'
+ ranged_mousepointer = 'icons/mouse_icons/mecha_mouse.dmi'
base_cooldown = 120 SECONDS
cooldown_min = 30 SECONDS
level_max = 7
@@ -448,7 +448,7 @@
desc = "Repair an APC, Borg, or Mech with large numbers of robotic nanomachines!"
action_icon = 'icons/obj/surgery.dmi'
action_icon_state = "tube"
- ranged_mousepointer = 'icons/mecha/mecha_mouse.dmi'
+ ranged_mousepointer = 'icons/mouse_icons/mecha_mouse.dmi'
base_cooldown = 150 SECONDS
cooldown_min = 30 SECONDS
level_max = 7
@@ -550,7 +550,7 @@
desc = "Repair the wires in an airlock that still has an intact AI control wire."
action_icon = 'icons/obj/doors/doorint.dmi'
action_icon_state = "door_closed"
- ranged_mousepointer = 'icons/mecha/mecha_mouse.dmi'
+ ranged_mousepointer = 'icons/mouse_icons/mecha_mouse.dmi'
base_cooldown = 60 SECONDS
cooldown_min = 60 SECONDS
level_max = 5
@@ -615,7 +615,7 @@
desc = "Deploy a nanofrost globule to a target to rapidly extinguish plasmafires."
action_icon = 'icons/effects/effects.dmi'
action_icon_state = "frozen_smoke_capsule"
- ranged_mousepointer = 'icons/mecha/mecha_mouse.dmi'
+ ranged_mousepointer = 'icons/mouse_icons/mecha_mouse.dmi'
base_cooldown = 60 SECONDS
cooldown_min = 30 SECONDS
level_max = 3
@@ -731,7 +731,7 @@
desc = "Replace damaged or missing lightbulbs."
action_icon = 'icons/obj/janitor.dmi'
action_icon_state = "lightreplacer0"
- ranged_mousepointer = 'icons/mecha/mecha_mouse.dmi'
+ ranged_mousepointer = 'icons/mouse_icons/mecha_mouse.dmi'
base_cooldown = 30 SECONDS
cooldown_min = 5 SECONDS
level_max = 5
@@ -788,7 +788,7 @@
desc = "Heal a crew member with large numbers of robotic nanomachines!"
action_icon = 'icons/obj/surgery.dmi'
action_icon_state = "scalpel_laser1_on"
- ranged_mousepointer = 'icons/mecha/mecha_mouse.dmi'
+ ranged_mousepointer = 'icons/mouse_icons/mecha_mouse.dmi'
base_cooldown = 150 SECONDS
cooldown_min = 30 SECONDS
level_max = 10
@@ -930,7 +930,7 @@
desc = "Deploy an area of metal foam to rapidly repair and seal hull breaches."
action_icon = 'icons/obj/structures.dmi'
action_icon_state = "reinforced"
- ranged_mousepointer = 'icons/mecha/mecha_mouse.dmi'
+ ranged_mousepointer = 'icons/mouse_icons/mecha_mouse.dmi'
base_cooldown = 180 SECONDS
cooldown_min = 30 SECONDS
level_max = 5
@@ -983,7 +983,7 @@
desc = "Deploy a holographic sign to alert crewmembers to potential hazards."
action_icon = 'icons/obj/device.dmi'
action_icon_state = "signmaker"
- ranged_mousepointer = 'icons/mecha/mecha_mouse.dmi'
+ ranged_mousepointer = 'icons/mouse_icons/mecha_mouse.dmi'
base_cooldown = 30 SECONDS
cooldown_min = 30 SECONDS
level_max = 8
@@ -1052,7 +1052,7 @@
desc = "Download a program from Clowns.NT to be able to play bike horn sounds on demand."
action_icon = 'icons/obj/items.dmi'
action_icon_state = "bike_horn"
- ranged_mousepointer = 'icons/mecha/mecha_mouse.dmi'
+ ranged_mousepointer = 'icons/mouse_icons/mecha_mouse.dmi'
base_cooldown = 30 SECONDS
cooldown_min = 15 SECONDS
level_max = 10
@@ -1170,7 +1170,7 @@
desc = "Illuminate a hologram to notify or beckon crew."
action_icon = 'icons/mob/telegraphing/telegraph_holographic.dmi'
action_icon_state = "target_circle"
- ranged_mousepointer = 'icons/mecha/mecha_mouse.dmi'
+ ranged_mousepointer = 'icons/mouse_icons/mecha_mouse.dmi'
base_cooldown = 15 SECONDS
cooldown_min = 15 SECONDS
level_max = 1
diff --git a/code/modules/mob/living/silicon/robot/robot_inventory.dm b/code/modules/mob/living/silicon/robot/robot_inventory.dm
index 7397f30a6b7..612c9c8d2a7 100644
--- a/code/modules/mob/living/silicon/robot/robot_inventory.dm
+++ b/code/modules/mob/living/silicon/robot/robot_inventory.dm
@@ -153,7 +153,6 @@
else
inventory.deactivate()
update_icons()
- return
//deselect_module(module) - Deselects the module slot specified by "module"
/mob/living/silicon/robot/proc/deselect_module(module) //Module is 1-3
@@ -164,7 +163,6 @@
var/atom/movable/screen/robot/active_module/inventory = inventory_screens[i]
inventory.deactivate()
update_icons()
- return
//toggle_module(module) - Toggles the selection of the module slot specified by "module".
/mob/living/silicon/robot/proc/toggle_module(module) //Module is 1-3
diff --git a/code/modules/mob/living/silicon/robot/robot_mob.dm b/code/modules/mob/living/silicon/robot/robot_mob.dm
index ac08443a49c..9bde0107c63 100644
--- a/code/modules/mob/living/silicon/robot/robot_mob.dm
+++ b/code/modules/mob/living/silicon/robot/robot_mob.dm
@@ -27,7 +27,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
/// A reference to the type of cyborg it is, i.e. Engineering, Security, Medical etc.
var/obj/item/robot_module/module = null
/// The item the borg currently has selected, or null if nothing is selected
- var/selected_item
+ var/obj/item/selected_item
/// The list of up to 3 items the borg can have "equipped". The contents will either be CYBORG_EMPTY_MODULE for nothing, or the item selected
var/list/all_active_items = list(CYBORG_EMPTY_MODULE, CYBORG_EMPTY_MODULE, CYBORG_EMPTY_MODULE)
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 9c5d853ea20..9e6dba11b35 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -1625,3 +1625,24 @@ GLOBAL_LIST_INIT(holy_areas, typecacheof(list(
. = STATUS_UPDATE_HEALTH
if(updating_health)
updatehealth()
+
+/mob/proc/add_mousepointer(priority = INFINITY, new_icon)
+ mousepointers["[priority]"] = new_icon
+ update_mousepointer()
+
+/mob/proc/remove_mousepointer(priority)
+ mousepointers -= "[priority]"
+ update_mousepointer()
+
+/mob/proc/update_mousepointer()
+ if(!client)
+ return
+ var/lowest_prio = INFINITY
+ for(var/prio in mousepointers)
+ prio = text2num(prio)
+ if(prio < lowest_prio)
+ lowest_prio = prio
+ if(lowest_prio == INFINITY)
+ client.mouse_pointer_icon = null
+ return
+ client.mouse_pointer_icon = mousepointers["[lowest_prio]"]
diff --git a/code/modules/mob/mob_login_base.dm b/code/modules/mob/mob_login_base.dm
index d0676420680..cbb4a7f043c 100644
--- a/code/modules/mob/mob_login_base.dm
+++ b/code/modules/mob/mob_login_base.dm
@@ -85,3 +85,5 @@
client.init_verbs()
SEND_SIGNAL(src, COMSIG_MOB_LOGIN)
SEND_SIGNAL(src, COMSIG_MOB_CLIENT_LOGIN, client)
+
+ update_mousepointer()
diff --git a/code/modules/mob/mob_vars.dm b/code/modules/mob/mob_vars.dm
index 69f4cbae906..a68a5492df1 100644
--- a/code/modules/mob/mob_vars.dm
+++ b/code/modules/mob/mob_vars.dm
@@ -259,3 +259,5 @@
/// For storing what do_after's something has, key = string, value = amount of interactions of that type happening.
var/list/do_afters
new_attack_chain = TRUE
+
+ var/list/mousepointers = list()
diff --git a/code/modules/vehicle/tg_vehicles/cars/clowncar.dm b/code/modules/vehicle/tg_vehicles/cars/clowncar.dm
index 00ad52d9e51..5c3dcc884ab 100644
--- a/code/modules/vehicle/tg_vehicles/cars/clowncar.dm
+++ b/code/modules/vehicle/tg_vehicles/cars/clowncar.dm
@@ -273,19 +273,18 @@
/// Finalizes cannon activation
/obj/tgvehicle/sealed/car/clowncar/proc/activate_cannon()
- var/mouse_pointer = 'icons/effects/mouse_pointers/weapon_pointer.dmi'
+ var/mouse_pointer = 'icons/mouse_icons/weapon_pointer.dmi'
cannonmode = CLOWN_CANNON_READY
for(var/mob/living/driver as anything in return_controllers_with_flag(VEHICLE_CONTROL_DRIVE))
REMOVE_TRAIT(driver, TRAIT_HANDS_BLOCKED, VEHICLE_TRAIT)
- if(driver.client.mouse_pointer_icon == initial(driver.client.mouse_pointer_icon))
- driver.client.mouse_pointer_icon = mouse_pointer
+ driver.add_mousepointer(MP_CLOWN_CAR_PRIORITY, mouse_pointer)
/// Finalizes cannon deactivation
/obj/tgvehicle/sealed/car/clowncar/proc/deactivate_cannon()
canmove = TRUE
cannonmode = CLOWN_CANNON_INACTIVE
for(var/mob/living/driver as anything in return_controllers_with_flag(VEHICLE_CONTROL_DRIVE))
- driver.client.mouse_pointer_icon = initial(driver.client.mouse_pointer_icon)
+ driver.remove_mousepointer(MP_CLOWN_CAR_PRIORITY)
ADD_TRAIT(driver, TRAIT_HANDS_BLOCKED, VEHICLE_TRAIT)
/// Fires the cannon where the user clicks
diff --git a/icons/mouse_icons/base_item.dmi b/icons/mouse_icons/base_item.dmi
new file mode 100644
index 0000000000000000000000000000000000000000..cf3ecb5f6f8f115ae0702f9396826287c3fea07e
GIT binary patch
literal 264
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0L3?#3!&-4XSoB=)|t_Kbr05bpo|KGb%L=DJd
zED7=pW^j0RBMrz&uL_AMaY-#sF3Kz@$;{7VV5pcA99B?N`u$6A!N;#pw7hk-&Yd|Q
zydl)!qVa=AI_G^fPcjsp@!4Tv9Atdi*h^u~qe(|5g(w7T8mhZ@b{ng1ULkS9_{k$5
zZLc%FtsAC_#{7*r(8k2@lSR_crn=@T&`K*$7sn8b-sA)c*2N7R4;u6Y8uTVK=}qX=
zo6wr)agC*