diff --git a/code/__DEFINES/cooldowns.dm b/code/__DEFINES/cooldowns.dm
index 17b451f71fe..95634570355 100644
--- a/code/__DEFINES/cooldowns.dm
+++ b/code/__DEFINES/cooldowns.dm
@@ -27,6 +27,7 @@
#define COOLDOWN_RACK_BOLT "rack_bolt"
#define COOLDOWN_LIGHT "cooldown_light"
#define COOLDOWN_JETPACK "jetpack"
+#define COOLDOWN_SKILL_ORDERS "skill_orders"
#define COOLDOWN_CIC_ORDERS "cic_orders"
#define COOLDOWN_HUD_ORDER "hud_order"
#define COOLDOWN_CLOAK_IMPLANT "cloak_implant"
diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm
index 12f1834c045..ec035c4e288 100644
--- a/code/__DEFINES/dcs/signals.dm
+++ b/code/__DEFINES/dcs/signals.dm
@@ -1015,7 +1015,11 @@
//Signals for CIC orders
#define COMSIG_ORDER_SELECTED "order_selected"
-#define COMSIG_ORDER_SENT "order_updated"
+#define COMSIG_CIC_ORDER_SENT "order_updated"
+#define COMSIG_CIC_ORDER_OFF_CD "order_off_cd"
+
+#define COMSIG_SKILL_ORDER_SENT "skill_order_updated"
+#define COMSIG_SKILL_ORDER_OFF_CD "skill_order_off_cd"
//Signals for automatic fire at component
#define COMSIG_AUTOMATIC_SHOOTER_START_SHOOTING_AT "start_shooting_at"
diff --git a/code/__DEFINES/overwatch.dm b/code/__DEFINES/overwatch.dm
index 884335f68a9..ca375ca1702 100644
--- a/code/__DEFINES/overwatch.dm
+++ b/code/__DEFINES/overwatch.dm
@@ -1,3 +1,5 @@
-#define ORDER_DURATION 30 SECONDS
-#define ORDER_COOLDOWN 30 SECONDS
-#define RALLY_ORDER_DURATION 30 SECONDS
+#define CIC_ORDER_DURATION 30 SECONDS
+#define CIC_ORDER_COOLDOWN 30 SECONDS
+
+#define SKILL_ORDER_DURATION 30 SECONDS
+#define SKILL_ORDER_COOLDOWN 45 SECONDS
diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm
index ff080acd59d..0ed74e9c7ee 100644
--- a/code/_onclick/click.dm
+++ b/code/_onclick/click.dm
@@ -410,8 +410,13 @@ if(selected_ability.target_flags & flagname && !istype(A, typepath)){\
/mob/living/carbon/human/ShiftClickOn(atom/A)
if(client.prefs.toggles_gameplay & MIDDLESHIFTCLICKING)
return ..()
- var/obj/item/held_thing = get_active_held_item()
+ if(selected_ability)
+ A = ability_target(A)
+ if(selected_ability.can_use_ability(A))
+ selected_ability.use_ability(A)
+ return TRUE
+ var/obj/item/held_thing = get_active_held_item()
if(held_thing && SEND_SIGNAL(held_thing, COMSIG_ITEM_SHIFTCLICKON, A, src) & COMPONENT_ITEM_CLICKON_BYPASS)
return FALSE
return ..()
diff --git a/code/_onclick/hud/screen_objects/screen_objects.dm b/code/_onclick/hud/screen_objects/screen_objects.dm
index 8b46ebdf282..13a5e3e75a5 100644
--- a/code/_onclick/hud/screen_objects/screen_objects.dm
+++ b/code/_onclick/hud/screen_objects/screen_objects.dm
@@ -796,17 +796,17 @@
/atom/movable/screen/arrow/attack_order_arrow
name = "attack order arrow"
icon_state = "Attack_arrow"
- duration = ORDER_DURATION
+ duration = CIC_ORDER_DURATION
/atom/movable/screen/arrow/rally_order_arrow
name = "Rally order arrow"
icon_state = "Rally_arrow"
- duration = RALLY_ORDER_DURATION
+ duration = CIC_ORDER_DURATION
/atom/movable/screen/arrow/defend_order_arrow
name = "Defend order arrow"
icon_state = "Defend_arrow"
- duration = ORDER_DURATION
+ duration = CIC_ORDER_DURATION
/atom/movable/screen/arrow/hunter_mark_arrow
name = "hunter mark arrow"
diff --git a/code/datums/actions/action.dm b/code/datums/actions/action.dm
index 3c350c1fe53..788b28fd68a 100644
--- a/code/datums/actions/action.dm
+++ b/code/datums/actions/action.dm
@@ -26,6 +26,8 @@ KEYBINDINGS
var/action_type = ACTION_CLICK
///Used for keeping track of the addition of the selected/active frames
var/toggled = FALSE
+ ///Is this action explicitly hidden from the owner
+ var/hidden = FALSE
/datum/action/New(Target)
target = Target
@@ -66,8 +68,9 @@ KEYBINDINGS
SHOULD_CALL_PARENT(TRUE)
qdel(src)
+///Whether the owner can see this action
/datum/action/proc/should_show()
- return TRUE
+ return !hidden
///Depending on the action type , toggles the selected/active frame to show without allowing stacking multiple overlays
/datum/action/proc/set_toggle(value)
@@ -186,7 +189,6 @@ KEYBINDINGS
owner.actions += src
if(owner.client)
owner.client.screen += button
- owner.update_action_buttons()
owner.actions_by_path[type] = src
for(var/type in keybinding_signals)
var/signal = keybinding_signals[type]
@@ -197,6 +199,7 @@ KEYBINDINGS
update_map_text(our_kb.get_keys_formatted(M.client), signal)
SEND_SIGNAL(M, ACTION_GIVEN)
+ owner.update_action_buttons()
/datum/action/proc/remove_action(mob/M)
for(var/type in keybinding_signals)
@@ -207,9 +210,9 @@ KEYBINDINGS
M.client.screen -= button
M.actions_by_path[type] = null
M.actions -= src
- M.update_action_buttons()
owner = null
SEND_SIGNAL(M, ACTION_REMOVED)
+ M.update_action_buttons()
///Should a AI element occasionally see if this ability should be used?
/datum/action/proc/ai_should_start_consider()
diff --git a/code/datums/actions/innate.dm b/code/datums/actions/innate.dm
index 7deb8d282ef..3a8b59aad03 100644
--- a/code/datums/actions/innate.dm
+++ b/code/datums/actions/innate.dm
@@ -12,12 +12,6 @@
Deactivate()
return TRUE
-
-/datum/action/innate/give_action()
- . = ..()
- update_button_icon()
-
-
/datum/action/innate/proc/Activate()
return
diff --git a/code/datums/actions/item_action.dm b/code/datums/actions/item_action.dm
index cc7d21e3928..5a4dbe99115 100644
--- a/code/datums/actions/item_action.dm
+++ b/code/datums/actions/item_action.dm
@@ -59,6 +59,10 @@
. = ..()
set_toggle(!toggled)
+/datum/action/item_action/toggle/remove_action(mob/M)
+ deselect()
+ return ..()
+
/datum/action/item_action/toggle/suit_toggle
keybinding_signals = list(KEYBINDING_NORMAL = COMSIG_KB_SUITLIGHT)
@@ -79,7 +83,6 @@
/datum/action/item_action/firemode/New()
. = ..()
holder_gun = holder_item
- update_button_icon()
/datum/action/item_action/firemode/update_button_icon()
diff --git a/code/datums/actions/item_toggles.dm b/code/datums/actions/item_toggles.dm
index 9804364b421..3d2b5bc30af 100644
--- a/code/datums/actions/item_toggles.dm
+++ b/code/datums/actions/item_toggles.dm
@@ -38,3 +38,7 @@
else
visual_references[VREF_MUTABLE_LINKED_OBJ] = null
return ..()
+
+/datum/action/ability/activable/item_toggle/remove_action(mob/M)
+ deselect()
+ return ..()
diff --git a/code/datums/actions/order_action.dm b/code/datums/actions/order_action.dm
index 47d49aa0808..393c539d8e7 100644
--- a/code/datums/actions/order_action.dm
+++ b/code/datums/actions/order_action.dm
@@ -13,11 +13,11 @@
/datum/action/innate/order/give_action(mob/M)
. = ..()
- RegisterSignal(M, COMSIG_ORDER_SENT, PROC_REF(update_button_icon))
+ RegisterSignals(M, list(COMSIG_CIC_ORDER_SENT, COMSIG_CIC_ORDER_OFF_CD), PROC_REF(update_button_icon))
/datum/action/innate/order/remove_action(mob/M)
. = ..()
- UnregisterSignal(M, COMSIG_ORDER_SENT)
+ UnregisterSignal(M, list(COMSIG_CIC_ORDER_SENT, COMSIG_CIC_ORDER_OFF_CD))
/datum/action/innate/order/Activate()
active = TRUE
@@ -53,9 +53,9 @@
if(visual_type)
target = get_turf(target)
new visual_type(target, faction)
- TIMER_COOLDOWN_START(owner, COOLDOWN_CIC_ORDERS, ORDER_COOLDOWN)
- SEND_SIGNAL(owner, COMSIG_ORDER_SENT)
- addtimer(CALLBACK(owner, TYPE_PROC_REF(/mob, update_all_icons_orders)), ORDER_COOLDOWN)
+ TIMER_COOLDOWN_START(owner, COOLDOWN_CIC_ORDERS, CIC_ORDER_COOLDOWN)
+ SEND_SIGNAL(owner, COMSIG_CIC_ORDER_SENT)
+ addtimer(CALLBACK(src, PROC_REF(on_cooldown_finish)), CIC_ORDER_COOLDOWN + 1)
if(squad)
for(var/mob/living/carbon/human/marine AS in squad.marines_list)
marine.receive_order(target, arrow_type, verb_name, faction)
@@ -65,11 +65,9 @@
human.receive_order(target, arrow_type, verb_name, faction)
return TRUE
-///Update all icons of orders action of the mob
-/mob/proc/update_all_icons_orders()
- for(var/datum/action/action AS in actions)
- if(istype(action, /datum/action/innate/order))
- action.update_button_icon()
+///Lets any other orders know when we're off CD
+/datum/action/innate/order/proc/on_cooldown_finish()
+ SEND_SIGNAL(owner, COMSIG_CIC_ORDER_OFF_CD, src)
/**
* Proc to give a marine an order
@@ -114,6 +112,9 @@
)
/datum/action/innate/order/attack_order/personal/should_show()
+ . = ..()
+ if(!.)
+ return
return owner.skills.getRating(skill_name) >= skill_min
/datum/action/innate/order/attack_order/personal/action_activate()
@@ -135,6 +136,9 @@
)
/datum/action/innate/order/defend_order/personal/should_show()
+ . = ..()
+ if(!.)
+ return
return owner.skills.getRating(skill_name) >= skill_min
/datum/action/innate/order/defend_order/personal/action_activate()
@@ -155,6 +159,9 @@
)
/datum/action/innate/order/retreat_order/personal/should_show()
+ . = ..()
+ if(!.)
+ return
return owner.skills.getRating(skill_name) >= skill_min
/datum/action/innate/order/retreat_order/personal/action_activate()
@@ -176,6 +183,9 @@
)
/datum/action/innate/order/rally_order/personal/should_show()
+ . = ..()
+ if(!.)
+ return
return owner.skills.getRating(skill_name) >= skill_min
/datum/action/innate/order/rally_order/personal/action_activate()
diff --git a/code/datums/actions/skill.dm b/code/datums/actions/skill.dm
index d0c1433e4c6..cc20ca9215d 100644
--- a/code/datums/actions/skill.dm
+++ b/code/datums/actions/skill.dm
@@ -3,7 +3,10 @@
var/skill_min
/datum/action/skill/should_show()
- return can_use_action()
+ . = ..()
+ if(!.)
+ return
+ return owner.skills.getRating(skill_name) >= skill_min
/datum/action/skill/can_use_action()
return owner.skills.getRating(skill_name) >= skill_min
diff --git a/code/datums/jobs/job/job.dm b/code/datums/jobs/job/job.dm
index 0d6d9437bb6..202deec3d26 100644
--- a/code/datums/jobs/job/job.dm
+++ b/code/datums/jobs/job/job.dm
@@ -181,18 +181,18 @@ GLOBAL_PROTECT(exp_specialmap)
/datum/outfit/job/proc/handle_id(mob/living/carbon/human/H, client/override_client)
var/datum/job/job = H.job ? H.job : SSjob.GetJobType(jobtype)
var/obj/item/card/id/id = H.wear_id
- if(istype(id))
- id.access = job.get_access()
- id.iff_signal = GLOB.faction_to_iff[job.faction]
- shuffle_inplace(id.access) // Shuffle access list to make NTNet passkeys less predictable
- id.registered_name = H.real_name
- id.assignment = job.title
- id.rank = job.title
- id.paygrade = job.paygrade
- id.update_label()
- if(H.mind?.initial_account) // In most cases they won't have a mind at this point.
- id.associated_account_number = H.mind.initial_account.account_number
- H.update_action_buttons()
+ if(!istype(id))
+ return
+ id.access = job.get_access()
+ id.iff_signal = GLOB.faction_to_iff[job.faction]
+ shuffle_inplace(id.access) // Shuffle access list to make NTNet passkeys less predictable
+ id.registered_name = H.real_name
+ id.assignment = job.title
+ id.rank = job.title
+ id.paygrade = job.paygrade
+ id.update_label()
+ if(H.mind?.initial_account) // In most cases they won't have a mind at this point.
+ id.associated_account_number = H.mind.initial_account.account_number
/datum/job/proc/get_special_name(client/preference_source)
return
@@ -222,8 +222,9 @@ GLOBAL_PROTECT(exp_specialmap)
var/datum/job/scaled_job = SSjob.GetJobType(index)
if(!(scaled_job in SSjob.active_joinable_occupations))
continue
- scaled_job.add_job_points(-jobworth[index])
+ scaled_job.remove_job_points(jobworth[index])
+///Adds to job points, adding a new slot if threshold reached
/datum/job/proc/add_job_points(amount)
job_points += amount
if(total_positions >= max_positions)
@@ -232,6 +233,17 @@ GLOBAL_PROTECT(exp_specialmap)
job_points -= job_points_needed
add_job_positions(1)
+///Removes job points, and if needed, job positions
+/datum/job/proc/remove_job_points(amount)
+ if(job_points_needed == INFINITY || total_positions == -1)
+ return
+ if(job_points >= amount)
+ job_points -= amount
+ return
+ var/job_slots_removed = ROUND_UP((amount - job_points) / job_points_needed)
+ remove_job_positions(job_slots_removed)
+ job_points += (job_slots_removed * job_points_needed) - amount
+
/datum/job/proc/add_job_positions(amount)
if(!(job_flags & (JOB_FLAG_LATEJOINABLE|JOB_FLAG_ROUNDSTARTJOINABLE)))
CRASH("add_job_positions called for a non-joinable job")
diff --git a/code/datums/jobs/job/militarypolice.dm b/code/datums/jobs/job/militarypolice.dm
index 2eb8aeabbce..5b3ca4f89a2 100644
--- a/code/datums/jobs/job/militarypolice.dm
+++ b/code/datums/jobs/job/militarypolice.dm
@@ -84,12 +84,6 @@ In addition, you are tasked with the security of high-ranking personnel, includi
wear_suit = /obj/item/clothing/suit/armor/bulletproof/mp
suit_store = /obj/item/weapon/gun/energy/taser
-/obj/item/radio/headset/mainship/mp
- icon = 'icons/obj/items/radio.dmi'
- name = "security radio headset"
- icon_state = "mp_headset"
- keyslot = /obj/item/encryptionkey/mcom
-
/obj/item/storage/pouch/pistol/laserpistol/Initialize()
. = ..()
new /obj/item/weapon/gun/energy/lasgun/lasrifle/standard_marine_pistol/tactical(src)
diff --git a/code/datums/jobs/job/other.dm b/code/datums/jobs/job/other.dm
index f3cab152069..37d00fdcd2e 100644
--- a/code/datums/jobs/job/other.dm
+++ b/code/datums/jobs/job/other.dm
@@ -66,6 +66,7 @@
gloves = /obj/item/clothing/gloves/marine/officer/chief/sa
glasses = /obj/item/clothing/glasses/sunglasses/sa/nodrop
back = /obj/item/storage/backpack/marine/satchel
+ ears = /obj/item/radio/headset/mainship/spatial
/datum/job/spatial_agent/galaxy_red
outfit = /datum/outfit/job/other/spatial_agent/galaxy_red
diff --git a/code/datums/jobs/squads.dm b/code/datums/jobs/squads.dm
index 699fa9ffd34..b002e9f2910 100644
--- a/code/datums/jobs/squads.dm
+++ b/code/datums/jobs/squads.dm
@@ -108,7 +108,7 @@
CRASH("attempted to insert marine [new_squaddie] into squad while already having one")
if(!(new_squaddie.job.title in current_positions))
- CRASH("Attempted to insert [new_squaddie.job.title] into squad [name]")
+ return FALSE
current_positions[new_squaddie.job.title]++
@@ -144,7 +144,6 @@
marines_list += new_squaddie
new_squaddie.assigned_squad = src
new_squaddie.hud_set_job(faction)
- new_squaddie.update_action_buttons()
new_squaddie.update_inv_head()
new_squaddie.update_inv_wear_suit()
return TRUE
@@ -192,7 +191,6 @@
leaving_squaddie.assigned_squad = null
leaving_squaddie.hud_set_job(faction)
- leaving_squaddie.update_action_buttons()
leaving_squaddie.update_inv_head()
leaving_squaddie.update_inv_wear_suit()
return TRUE
@@ -222,7 +220,6 @@
to_chat(squad_leader, "You're no longer the Squad Leader for [src]!")
var/mob/living/carbon/human/H = squad_leader
squad_leader = null
- H.update_action_buttons()
H.hud_set_job(faction)
H.update_inv_head()
H.update_inv_wear_suit()
@@ -251,7 +248,6 @@
R.use_command = TRUE
squad_leader.hud_set_job(faction)
- squad_leader.update_action_buttons()
squad_leader.update_inv_head()
squad_leader.update_inv_wear_suit()
to_chat(squad_leader, "You're now the Squad Leader for [src]!")
diff --git a/code/datums/outfit.dm b/code/datums/outfit.dm
index bd9ced9abe7..65bae3aad70 100644
--- a/code/datums/outfit.dm
+++ b/code/datums/outfit.dm
@@ -105,7 +105,6 @@
H.update_body()
return TRUE
-
/datum/outfit/proc/get_json_data()
. = list()
.["outfit_type"] = type
diff --git a/code/game/objects/effects/temporary_visuals/miscellaneous.dm b/code/game/objects/effects/temporary_visuals/miscellaneous.dm
index 527fd5fce96..b2122619c6a 100644
--- a/code/game/objects/effects/temporary_visuals/miscellaneous.dm
+++ b/code/game/objects/effects/temporary_visuals/miscellaneous.dm
@@ -155,7 +155,7 @@ GLOBAL_LIST_EMPTY(blood_particles)
icon = 'icons/Marine/marine-items.dmi'
var/icon_state_on
hud_possible = list(SQUAD_HUD_TERRAGOV, SQUAD_HUD_SOM)
- duration = ORDER_DURATION
+ duration = CIC_ORDER_DURATION
layer = TURF_LAYER
/obj/effect/temp_visual/order/Initialize(mapload, faction)
@@ -186,7 +186,7 @@ GLOBAL_LIST_EMPTY(blood_particles)
/obj/effect/temp_visual/order/rally_order
name = "rally order"
icon_state_on = "rally"
- duration = RALLY_ORDER_DURATION
+ duration = CIC_ORDER_DURATION
///Set visuals for the hud
/obj/effect/temp_visual/order/proc/set_visuals(faction)
diff --git a/code/game/objects/items/radio/headset.dm b/code/game/objects/items/radio/headset.dm
index 3722a2a11ce..0df5bb7e19b 100644
--- a/code/game/objects/items/radio/headset.dm
+++ b/code/game/objects/items/radio/headset.dm
@@ -488,6 +488,16 @@ GLOBAL_LIST_INIT(channel_tokens, list(
name = "silicon radio"
keyslot = /obj/item/encryptionkey/mcom/ai
+/obj/item/radio/headset/mainship/mp
+ name = "security radio headset"
+ icon_state = "mp_headset"
+ keyslot = /obj/item/encryptionkey/mcom
+
+/obj/item/radio/headset/mainship/spatial
+ name = "spatial agent headset"
+ icon_state = "headset_marine_generic"
+ keyslot = /obj/item/encryptionkey/mcom/ai
+
/obj/item/radio/headset/mainship/marine
keyslot = /obj/item/encryptionkey/general
diff --git a/code/game/objects/machinery/computer/communications.dm b/code/game/objects/machinery/computer/communications.dm
index 29c62ad5836..4a8927e617d 100644
--- a/code/game/objects/machinery/computer/communications.dm
+++ b/code/game/objects/machinery/computer/communications.dm
@@ -124,7 +124,7 @@
priority_announce(input, subtitle = "Sent by [usr]", type = ANNOUNCEMENT_COMMAND)
message_admins("[ADMIN_TPMONTY(usr)] has just sent a command announcement")
log_game("[key_name(usr)] has just sent a command announcement.")
- TIMER_COOLDOWN_START(usr, COOLDOWN_HUD_ORDER, ORDER_COOLDOWN)
+ TIMER_COOLDOWN_START(usr, COOLDOWN_HUD_ORDER, CIC_ORDER_COOLDOWN)
cooldown_message = world.time
if("award")
diff --git a/code/game/objects/machinery/overwatch.dm b/code/game/objects/machinery/overwatch.dm
index adb8d859298..9411f2a0039 100644
--- a/code/game/objects/machinery/overwatch.dm
+++ b/code/game/objects/machinery/overwatch.dm
@@ -371,7 +371,7 @@ GLOBAL_LIST_EMPTY(active_cas_targets)
return
var/input = tgui_input_text(operator, "Please write a message to announce to the squad leader:", "SL Message", max_length = MAX_COMMAND_MESSAGE_LENGTH)
if(input)
- TIMER_COOLDOWN_START(operator, COOLDOWN_HUD_ORDER, ORDER_COOLDOWN)
+ TIMER_COOLDOWN_START(operator, COOLDOWN_HUD_ORDER, CIC_ORDER_COOLDOWN)
message_member(current_squad.squad_leader, input, operator)
if(issilicon(operator))
to_chat(operator, span_boldnotice("Message sent to Squad Leader [current_squad.squad_leader] of squad '[current_squad]'."))
@@ -781,7 +781,7 @@ GLOBAL_LIST_EMPTY(active_cas_targets)
return
var/input = tgui_input_text(source, "Please write a message to announce to this marine:", "CIC Message", max_length = MAX_COMMAND_MESSAGE_LENGTH)
message_member(human_target, input, source)
- TIMER_COOLDOWN_START(operator, COOLDOWN_HUD_ORDER, ORDER_COOLDOWN)
+ TIMER_COOLDOWN_START(operator, COOLDOWN_HUD_ORDER, CIC_ORDER_COOLDOWN)
if(ASL)
if(human_target == human_target.assigned_squad.squad_leader)
human_target.assigned_squad.demote_leader()
@@ -813,7 +813,7 @@ GLOBAL_LIST_EMPTY(active_cas_targets)
continue
message_member(target, input, source)
message_member(source, input, source)
- TIMER_COOLDOWN_START(operator, COOLDOWN_HUD_ORDER, ORDER_COOLDOWN)
+ TIMER_COOLDOWN_START(operator, COOLDOWN_HUD_ORDER, CIC_ORDER_COOLDOWN)
if(SQUAD_ACTIONS)
choice = show_radial_menu(source, turf_target, squad_radial_options, null, 48, null, FALSE, TRUE)
var/datum/squad/chosen_squad = squad_select(source, turf_target)
@@ -825,7 +825,7 @@ GLOBAL_LIST_EMPTY(active_cas_targets)
var/input = tgui_input_text(source, "Please write a message to announce to the squad:", "Squad Message", max_length = MAX_COMMAND_MESSAGE_LENGTH)
if(input)
chosen_squad.message_squad(input, source)
- TIMER_COOLDOWN_START(operator, COOLDOWN_HUD_ORDER, ORDER_COOLDOWN)
+ TIMER_COOLDOWN_START(operator, COOLDOWN_HUD_ORDER, CIC_ORDER_COOLDOWN)
if(SWITCH_SQUAD_NEAR)
for(var/mob/living/carbon/human/target in GLOB.human_mob_list)
if(!target.faction == faction || get_dist(target, turf_target) > 9)
@@ -913,7 +913,7 @@ GLOBAL_LIST_EMPTY(active_cas_targets)
to_chat(src, span_warning("You cannot give an order while muted."))
return
- if(command_aura_cooldown)
+ if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_SKILL_ORDERS))
to_chat(src, span_warning("You have recently given an order. Calm down."))
return
@@ -925,7 +925,7 @@ GLOBAL_LIST_EMPTY(active_cas_targets)
if(!command_aura)
return
- if(command_aura_cooldown)
+ if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_SKILL_ORDERS))
to_chat(src, span_warning("You have recently given an order. Calm down."))
return
@@ -933,7 +933,7 @@ GLOBAL_LIST_EMPTY(active_cas_targets)
return
var/aura_strength = skills.getRating(SKILL_LEADERSHIP) - 1
var/aura_target = pick_order_target()
- SSaura.add_emitter(aura_target, command_aura, aura_strength + 4, aura_strength, 30 SECONDS, faction)
+ SSaura.add_emitter(aura_target, command_aura, aura_strength + 4, aura_strength, SKILL_ORDER_DURATION, faction)
var/message = ""
switch(command_aura)
@@ -953,10 +953,6 @@ GLOBAL_LIST_EMPTY(active_cas_targets)
say(message)
add_emote_overlay(focus)
- command_aura_cooldown = addtimer(CALLBACK(src, PROC_REF(end_command_aura_cooldown)), 45 SECONDS)
-
- update_action_buttons()
-
///Choose what we're sending a buff order through
/mob/living/carbon/human/proc/pick_order_target()
//If we're in overwatch, use the camera eye
@@ -964,10 +960,6 @@ GLOBAL_LIST_EMPTY(active_cas_targets)
return remote_control
return src
-/mob/living/carbon/human/proc/end_command_aura_cooldown()
- command_aura_cooldown = null
- update_action_buttons()
-
/datum/action/skill/issue_order
name = "Issue Order"
action_icon = 'icons/mob/order_icons.dmi'
@@ -975,10 +967,28 @@ GLOBAL_LIST_EMPTY(active_cas_targets)
skill_min = SKILL_LEAD_TRAINED
var/order_type = null
+/datum/action/skill/issue_order/give_action(mob/M)
+ . = ..()
+ RegisterSignals(M, list(COMSIG_SKILL_ORDER_SENT, COMSIG_SKILL_ORDER_OFF_CD), PROC_REF(update_button_icon))
+
+/datum/action/skill/issue_order/remove_action(mob/M)
+ . = ..()
+ UnregisterSignal(M, list(COMSIG_CIC_ORDER_SENT, COMSIG_CIC_ORDER_OFF_CD))
+
+/datum/action/skill/issue_order/can_use_action()
+ . = ..()
+ if(!.)
+ return
+ if(owner.stat || TIMER_COOLDOWN_CHECK(owner, COOLDOWN_SKILL_ORDERS))
+ return FALSE
+
/datum/action/skill/issue_order/action_activate()
var/mob/living/carbon/human/human = owner
if(istype(human))
human.issue_order(order_type)
+ TIMER_COOLDOWN_START(owner, COOLDOWN_SKILL_ORDERS, SKILL_ORDER_COOLDOWN)
+ addtimer(CALLBACK(src, PROC_REF(on_cooldown_finish)), SKILL_ORDER_COOLDOWN + 1)
+ SEND_SIGNAL(owner, COMSIG_SKILL_ORDER_SENT)
/datum/action/skill/issue_order/update_button_icon()
var/mob/living/carbon/human/human = owner
@@ -991,11 +1001,15 @@ GLOBAL_LIST_EMPTY(active_cas_targets)
var/mob/living/carbon/human/human = owner
if(!istype(human))
return
- if(human.command_aura_cooldown)
+ if(TIMER_COOLDOWN_CHECK(human, COOLDOWN_SKILL_ORDERS))
button.color = rgb(255,0,0,255)
else
button.color = rgb(255,255,255,255)
+///Lets any other orders know when we're off CD
+/datum/action/skill/issue_order/proc/on_cooldown_finish()
+ SEND_SIGNAL(owner, COMSIG_SKILL_ORDER_OFF_CD, src)
+
/datum/action/skill/issue_order/move
name = "Issue Move Order"
order_type = AURA_HUMAN_MOVE
@@ -1031,16 +1045,14 @@ GLOBAL_LIST_EMPTY(active_cas_targets)
if(orders_visible)
orders_visible = FALSE
action_icon_state = "show_order"
- for(var/datum/action/skill/path in owner.actions)
- if(istype(path, /datum/action/skill/issue_order))
- path.remove_action(H)
+ for(var/datum/action/skill/issue_order/action in owner.actions)
+ action.hidden = TRUE
else
orders_visible = TRUE
action_icon_state = "hide_order"
- var/list/subtypeactions = subtypesof(/datum/action/skill/issue_order)
- for(var/path in subtypeactions)
- var/datum/action/skill/issue_order/A = new path()
- A.give_action(H)
+ for(var/datum/action/skill/issue_order/action in owner.actions)
+ action.hidden = FALSE
+ owner.update_action_buttons()
/obj/machinery/computer/camera_advanced/overwatch/proc/get_squad_by_id(id)
for(var/datum/squad/squad AS in watchable_squads)
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index 2d8022f688b..2953b7b235f 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -107,9 +107,7 @@
///Auras we can create, used for the order choice UI.
var/static/list/command_aura_allowed = list(AURA_HUMAN_MOVE, AURA_HUMAN_HOLD, AURA_HUMAN_FOCUS)
- ///Whether we can use another command order yet. Either null or a timer ID.
- var/command_aura_cooldown
-
+ ///Strength of the move order aura affecting us
var/mobility_aura = 0
var/protection_aura = 0
var/marksman_aura = 0
diff --git a/code/modules/mob/living/carbon/xenomorph/abilities.dm b/code/modules/mob/living/carbon/xenomorph/abilities.dm
index 7df6bc58996..ba5cc47514a 100644
--- a/code/modules/mob/living/carbon/xenomorph/abilities.dm
+++ b/code/modules/mob/living/carbon/xenomorph/abilities.dm
@@ -514,40 +514,33 @@
keybinding_signals = list(
KEYBINDING_NORMAL = COMSIG_XENOABILITY_EMIT_RECOVERY,
)
+ hidden = TRUE
/datum/action/ability/xeno_action/pheromones/emit_recovery/action_activate()
apply_pheros(AURA_XENO_RECOVERY)
-/datum/action/ability/xeno_action/pheromones/emit_recovery/should_show()
- return FALSE
-
/datum/action/ability/xeno_action/pheromones/emit_warding
name = "Toggle Warding Pheromones"
desc = "Increases armor for yourself and nearby teammates."
keybinding_signals = list(
KEYBINDING_NORMAL = COMSIG_XENOABILITY_EMIT_WARDING,
)
+ hidden = TRUE
/datum/action/ability/xeno_action/pheromones/emit_warding/action_activate()
apply_pheros(AURA_XENO_WARDING)
-/datum/action/ability/xeno_action/pheromones/emit_warding/should_show()
- return FALSE
-
/datum/action/ability/xeno_action/pheromones/emit_frenzy
name = "Toggle Frenzy Pheromones"
desc = "Increases damage for yourself and nearby teammates."
keybinding_signals = list(
KEYBINDING_NORMAL = COMSIG_XENOABILITY_EMIT_FRENZY,
)
+ hidden = TRUE
/datum/action/ability/xeno_action/pheromones/emit_frenzy/action_activate()
apply_pheros(AURA_XENO_FRENZY)
-/datum/action/ability/xeno_action/pheromones/emit_frenzy/should_show()
- return FALSE
-
-
/datum/action/ability/activable/xeno/transfer_plasma
name = "Transfer Plasma"
action_icon_state = "transfer_plasma"
@@ -1382,9 +1375,7 @@
KEYBINDING_NORMAL = COMSIG_XENOABILITY_BLESSINGSMENU,
)
use_state_flags = ABILITY_USE_LYING|ABILITY_USE_CRESTED
-
-/datum/action/ability/xeno_action/blessing_menu/should_show()
- return FALSE // Blessings meni now done through hive status UI!
+ hidden = TRUE
/datum/action/ability/xeno_action/blessing_menu/action_activate()
var/mob/living/carbon/xenomorph/X = owner
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/hunter/abilities_hunter.dm b/code/modules/mob/living/carbon/xenomorph/castes/hunter/abilities_hunter.dm
index 00efedefec0..be8f5635701 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/hunter/abilities_hunter.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/hunter/abilities_hunter.dm
@@ -632,6 +632,7 @@
ability_cost = 0
cooldown_duration = 0
keybind_flags = ABILITY_USE_STAGGERED | ABILITY_IGNORE_SELECTED_ABILITY
+ hidden = TRUE
/datum/action/ability/xeno_action/hunter_army/give_action(mob/living/L)
. = ..()
@@ -653,9 +654,6 @@
if(prob(ILUSSION_CHANCE))
new /mob/illusion/xeno(target_turf, owner, owner, ILLUSION_LIFETIME)
-/datum/action/ability/xeno_action/hunter_army/should_show()
- return FALSE
-
// ***************************************
// *********** Crippling strike
// ***************************************
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/queen/abilities_queen.dm b/code/modules/mob/living/carbon/xenomorph/castes/queen/abilities_queen.dm
index 33f365838ab..243e84dceda 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/queen/abilities_queen.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/queen/abilities_queen.dm
@@ -224,6 +224,7 @@
desc = "See from the target Xenomorphs vision. Click again the ability to stop observing"
ability_cost = 0
use_state_flags = ABILITY_USE_LYING
+ hidden = TRUE
var/overwatch_active = FALSE
/datum/action/ability/xeno_action/watch_xeno/give_action(mob/living/L)
@@ -237,9 +238,6 @@
UnregisterSignal(L, list(COMSIG_MOB_DEATH, COMSIG_XENOMORPH_WATCHXENO))
return ..()
-/datum/action/ability/xeno_action/watch_xeno/should_show()
- return FALSE // Overwatching now done through hive status UI!
-
/datum/action/ability/xeno_action/watch_xeno/proc/start_overwatch(mob/living/carbon/xenomorph/target)
if(!can_use_action()) // Check for action now done here as action_activate pipeline has been bypassed with signal activation.
return
@@ -359,9 +357,7 @@
desc = "Make a target Xenomorph a leader."
ability_cost = 200
use_state_flags = ABILITY_USE_LYING
-
-/datum/action/ability/xeno_action/set_xeno_lead/should_show()
- return FALSE // Leadership now set through hive status UI!
+ hidden = TRUE
/datum/action/ability/xeno_action/set_xeno_lead/give_action(mob/living/L)
. = ..()
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/warrior/abilities_warrior.dm b/code/modules/mob/living/carbon/xenomorph/castes/warrior/abilities_warrior.dm
index 26dbc36d1e4..282fadf01ae 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/warrior/abilities_warrior.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/warrior/abilities_warrior.dm
@@ -18,9 +18,7 @@
/datum/action/ability/activable/xeno/warrior/punch/jab,
/datum/action/ability/activable/xeno/warrior/punch/flurry,
)
-
-/datum/action/ability/xeno_action/empower/should_show()
- return FALSE
+ hidden = TRUE
/// Checks if Empower is capped and gives bonuses if so, otherwise increases combo count.
/datum/action/ability/xeno_action/empower/proc/check_empower(atom/target)
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/widow/abilities_widow.dm b/code/modules/mob/living/carbon/xenomorph/castes/widow/abilities_widow.dm
index 53e96c87446..67f701a772b 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/widow/abilities_widow.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/widow/abilities_widow.dm
@@ -411,6 +411,7 @@
ability_cost = 0
cooldown_duration = 0
keybind_flags = ABILITY_USE_STAGGERED | ABILITY_IGNORE_SELECTED_ABILITY
+ hidden = TRUE
/datum/action/ability/xeno_action/spider_venom/give_action(mob/living/L)
. = ..()
@@ -428,6 +429,3 @@
return
target.apply_status_effect(STATUS_EFFECT_SPIDER_VENOM)
-
-/datum/action/ability/xeno_action/spider_venom/should_show()
- return FALSE
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 88130e2750f..9bffe969dd4 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -527,7 +527,7 @@
if(!can_use_action())
return
owner.playsound_local(owner, "sound/effects/CIC_order.ogg", 10, 1)
- TIMER_COOLDOWN_START(owner, COOLDOWN_HUD_ORDER, ORDER_COOLDOWN)
+ TIMER_COOLDOWN_START(owner, COOLDOWN_HUD_ORDER, CIC_ORDER_COOLDOWN)
log_game("[key_name(owner)] has broadcasted the hud message [text] at [AREACOORD(owner)]")
deadchat_broadcast(" has sent the command order \"[text]\"", owner, owner)
for(var/mob/living/carbon/human/human AS in GLOB.alive_human_list)
diff --git a/code/modules/projectiles/attachables/foldable.dm b/code/modules/projectiles/attachables/foldable.dm
index 7cd6cdc94aa..8e76cc5cb07 100644
--- a/code/modules/projectiles/attachables/foldable.dm
+++ b/code/modules/projectiles/attachables/foldable.dm
@@ -61,9 +61,6 @@
if(master_gun)
apply_modifiers(master_gun, user, !folded)
- for(var/X in master_gun.actions)
- var/datum/action/A = X
- A.update_button_icon()
return TRUE
diff --git a/code/modules/projectiles/attachables/rail.dm b/code/modules/projectiles/attachables/rail.dm
index e8083e12ad6..98507e5e8f8 100644
--- a/code/modules/projectiles/attachables/rail.dm
+++ b/code/modules/projectiles/attachables/rail.dm
@@ -76,10 +76,6 @@
else
return
- for(var/X in master_gun.actions)
- var/datum/action/A = X
- A.update_button_icon()
-
update_icon()
/obj/item/attachable/flashlight/attackby(obj/item/I, mob/user, params)
diff --git a/code/modules/projectiles/attachables/underbarrel.dm b/code/modules/projectiles/attachables/underbarrel.dm
index 6a346ae1b4d..c4879773cbf 100644
--- a/code/modules/projectiles/attachables/underbarrel.dm
+++ b/code/modules/projectiles/attachables/underbarrel.dm
@@ -59,13 +59,6 @@
flags_attach_features = ATTACH_REMOVABLE|ATTACH_ACTIVATION
attachment_action_type = /datum/action/item_action/toggle
-/obj/item/attachable/lace/t500
- name = "R-500 lace"
- icon = 'icons/Marine/attachments_64.dmi'
- slot = ATTACHMENT_SLOT_STOCK
- pixel_shift_x = 0
- pixel_shift_y = 0
-
/obj/item/attachable/lace/activate(mob/living/user, turn_off)
if(lace_deployed)
REMOVE_TRAIT(master_gun, TRAIT_NODROP, PISTOL_LACE_TRAIT)
@@ -87,13 +80,16 @@
lace_deployed = !lace_deployed
- for(var/i in master_gun.actions)
- var/datum/action/action_to_update = i
- action_to_update.update_button_icon()
-
update_icon()
return TRUE
+/obj/item/attachable/lace/t500
+ name = "R-500 lace"
+ icon = 'icons/Marine/attachments_64.dmi'
+ slot = ATTACHMENT_SLOT_STOCK
+ pixel_shift_x = 0
+ pixel_shift_y = 0
+
/obj/item/attachable/burstfire_assembly
name = "burst fire assembly"
desc = "A mechanism re-assembly kit that allows for automatic fire, or more shots per burst if the weapon already has the ability."
diff --git a/code/modules/projectiles/gun_system.dm b/code/modules/projectiles/gun_system.dm
index 79935f3b1b3..722749767d0 100644
--- a/code/modules/projectiles/gun_system.dm
+++ b/code/modules/projectiles/gun_system.dm
@@ -504,16 +504,8 @@
SIGNAL_HANDLER
set_gun_user(null)
-/obj/item/weapon/gun/update_icon()
+/obj/item/weapon/gun/update_icon(updates=ALL)
. = ..()
-
- for(var/datum/action/action AS in actions)
- action.update_button_icon()
-
- if(master_gun)
- for(var/datum/action/action AS in master_gun.actions)
- action.update_button_icon()
-
update_item_state()
/obj/item/weapon/gun/update_icon_state()
diff --git a/code/modules/screen_alert/command_alert.dm b/code/modules/screen_alert/command_alert.dm
index b489b9fb9bc..61d48ddf19e 100644
--- a/code/modules/screen_alert/command_alert.dm
+++ b/code/modules/screen_alert/command_alert.dm
@@ -24,6 +24,9 @@
var/skill_min = SKILL_LEAD_EXPERT
/datum/action/innate/message_squad/should_show()
+ . = ..()
+ if(!.)
+ return
return owner.skills.getRating(skill_name) >= skill_min
/datum/action/innate/message_squad/can_use_action()
@@ -53,7 +56,9 @@
return
var/sound/S = sound('sound/misc/notice2.ogg')
S.channel = CHANNEL_ANNOUNCEMENTS
- TIMER_COOLDOWN_START(owner, COOLDOWN_HUD_ORDER, ORDER_COOLDOWN)
+ TIMER_COOLDOWN_START(owner, COOLDOWN_HUD_ORDER, CIC_ORDER_COOLDOWN)
+ addtimer(CALLBACK(src, PROC_REF(update_button_icon)), CIC_ORDER_COOLDOWN + 1)
+ update_button_icon()
log_game("[key_name(human_owner)] has broadcasted the hud message [text] at [AREACOORD(human_owner)]")
var/override_color // for squad colors
var/list/alert_receivers = (GLOB.alive_human_list + GLOB.ai_list + GLOB.observer_list) // for full faction alerts, do this so that faction's AI and ghosts can hear aswell