Skip to content

Commit

Permalink
XM4 Armor Integral Motion Detector (#5586)
Browse files Browse the repository at this point in the history
# About the pull request

Adds a motion detector action to the XM4 Intelligence Officer (IO)
Armor.
<!-- Remove this text and explain what the purpose of your PR is.

Mention if you have tested your changes. If you changed a map, make sure
you used the mapmerge tool.
If this is an Issue Correction, you can type "Fixes Issue #169420" to
link the PR to the corresponding Issue number #169420.

Remember: something that is self-evident to you might not be to others.
Explain your rationale fully, even if you feel it goes without saying.
-->

# Explain why it's good for the game
1. Currently there is no difference between the standard M4 "RTO" armor
and the XM4 IO armor. The integral motion detector makes the X for
"Experimental" meaningful.
2. The XM4 currently goes _mostly_ unused by IOs, this would change
that.
3. The Motion Detector is already an essential item for IOs, this change
distinguishes it from the other armor choices in game and adds a
uniqueness to their piece of kit.
4. I envision the XM4 as the "safety" choice for IOs: it has extra
storage, slower, and (with this feature) includes a Motion Detector to
improve situational awareness. The other common choices for IOs are the
Service Jacket I.E. the "speed" choice, and the M3-L armor a "middle
ground" option.
5. This should not have any meaningful impact on balance vs. skirmishers
as the Motion Detector is already an essential item for IOs.
6. Keep in mind the XM4 is only attainable by IOs and ~cannot be worn or
purchased by anyone else.~

NOTE: This is my first "major" feature. I am open to suggestions,
including "balance" related stuff.
# Testing Photographs and Procedure


https://github.com/cmss13-devs/cmss13/assets/32654903/445352b4-bfec-460f-95d8-2eadea27b953

Edit: Tested to confirm that the MD turns off upon user death. ✔️
# Changelog
:cl:
NervanCatos
add: Adds integral Motion Detector to XM4 IO Armor
balance: Uniform utility accessories (I.E. Webbing) no longer can be
equipped while the XM4 is worn. Armor slots increased to 5 to
compensate.
/:cl:

---------

Co-authored-by: Drathek <[email protected]>
  • Loading branch information
MobiusWon and Drulikar committed Feb 16, 2024
1 parent ea467d2 commit 0a90983
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 3 deletions.
8 changes: 8 additions & 0 deletions code/game/objects/items/devices/motion_detector.dm
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,14 @@
if(ishuman(A.loc))
return A.loc

/obj/item/device/motiondetector/xm4

///Forces the blue blip to appear around the detected mob
/obj/item/device/motiondetector/xm4/get_user()
var/atom/holder = loc
if(ishuman(holder.loc))
return holder.loc

/obj/item/device/motiondetector/proc/apply_debuff(mob/M)
return

Expand Down
116 changes: 115 additions & 1 deletion code/modules/clothing/suits/marine_armor.dm
Original file line number Diff line number Diff line change
Expand Up @@ -281,8 +281,122 @@

/obj/item/clothing/suit/storage/marine/medium/rto/intel
name = "\improper XM4 pattern intelligence officer armor"
uniform_restricted = list(/obj/item/clothing/under/marine/officer, /obj/item/clothing/under/rank/qm_suit, /obj/item/clothing/under/marine/officer/intel)
uniform_restricted = list(/obj/item/clothing/under/marine/officer/intel)
specialty = "XM4 pattern intel"
desc = "Tougher than steel, quieter than whispers, the XM4 Intel Armor provides capable protection combined with an experimental integrated motion tracker. It took an R&D team a weekend to develop and costs more than the Chinook Station... probably. When worn, uniform accessories such as webbing cannot be attached due to the motion sensors occupying the clips."
desc_lore = "ARMAT Perfection. The XM4 Soldier Awareness System mixes M4-style hard armor and a distributed series of motion sensors clipped onto the breastplate. When connected to any HUD optic, it replicates the effects of an M314 Motion Detector unit, increasing user situational awareness. It is currently undergoing field trials by intelligence operatives."
storage_slots = 5
/// XM4 Integral Motion Detector Ability
actions_types = list(/datum/action/item_action/toggle, /datum/action/item_action/intel/toggle_motion_detector)
var/motion_detector = FALSE
var/obj/item/device/motiondetector/xm4/proximity
var/long_range_cooldown = 2
var/recycletime = 120

/obj/item/clothing/suit/storage/marine/medium/rto/intel/Initialize(mapload, ...)
. = ..()
proximity = new(src)
update_icon()

/datum/action/item_action/intel/action_activate()
if(!ishuman(owner))
return

/datum/action/item_action/intel/update_button_icon()
return

/datum/action/item_action/intel/toggle_motion_detector/New(Target, obj/item/holder)
. = ..()
name = "Toggle Motion Detector"
action_icon_state = "motion_detector"
button.name = name
button.overlays.Cut()
button.overlays += image('icons/mob/hud/actions.dmi', button, action_icon_state)

/datum/action/item_action/intel/toggle_motion_detector/action_activate()
. = ..()
var/obj/item/clothing/suit/storage/marine/medium/rto/intel/recon = holder_item
recon.toggle_motion_detector(owner)

/datum/action/item_action/intel/toggle_motion_detector/proc/update_icon()
if(!holder_item)
return
var/obj/item/clothing/suit/storage/marine/medium/rto/intel/recon = holder_item
if(recon.motion_detector)
button.icon_state = "template_on"
else
button.icon_state = "template"

/obj/item/clothing/suit/storage/marine/medium/rto/intel/process()
if(!motion_detector)
STOP_PROCESSING(SSobj, src)
if(motion_detector)
recycletime--
if(!recycletime)
recycletime = initial(recycletime)
proximity.refresh_blip_pool()
long_range_cooldown--
if(long_range_cooldown)
return
long_range_cooldown = initial(long_range_cooldown)
proximity.scan()

/obj/item/clothing/suit/storage/marine/medium/rto/intel/proc/toggle_motion_detector(mob/user)
to_chat(user,SPAN_NOTICE("You [motion_detector? "<B>disable</b>" : "<B>enable</b>"] \the [src]'s motion detector."))
if(!motion_detector)
playsound(loc,'sound/items/detector_turn_on.ogg', 25, 1)
else
playsound(loc,'sound/items/detector_turn_off.ogg', 25, 1)
motion_detector = !motion_detector
var/datum/action/item_action/intel/toggle_motion_detector/TMD = locate(/datum/action/item_action/intel/toggle_motion_detector) in actions
TMD.update_icon()
motion_detector()

/obj/item/clothing/suit/storage/marine/medium/rto/intel/proc/motion_detector()
if(motion_detector)
START_PROCESSING(SSobj, src)
else
STOP_PROCESSING(SSobj, src)

/obj/item/clothing/suit/storage/marine/medium/rto/intel/mob_can_equip(mob/living/carbon/human/user, slot, disable_warning) //Thanks to Drathek for the help on this part!
if(!..())
return FALSE

// Only equip if uniform doesn't already have a utility accessory slot equipped
var/obj/item/clothing/under/uniform = user.w_uniform
var/accessory = locate(/obj/item/clothing/accessory/storage) in uniform.accessories
if(accessory)
to_chat(user, SPAN_WARNING("[src] can't be worn with [accessory]."))
return FALSE
// Only equip if user has expert intel skill level
if(!skillcheck(user, SKILL_INTEL, SKILL_INTEL_EXPERT))
to_chat(user, SPAN_WARNING("You don't seem to know how to use [src]..."))
return FALSE
return TRUE

/obj/item/clothing/suit/storage/marine/medium/rto/intel/equipped(mob/user, slot, silent) //When XM4 is equipped this removes ACCESSORY_SLOT_UTILITY as a valid accessory for the uniform
. = ..()
if(slot == WEAR_JACKET)
var/mob/living/carbon/human/human = user
var/obj/item/clothing/under/uniform = human.w_uniform
if(uniform?.valid_accessory_slots)
uniform?.valid_accessory_slots -= ACCESSORY_SLOT_UTILITY

/obj/item/clothing/suit/storage/marine/medium/rto/intel/unequipped(mob/user, slot) //When unequipped this adds the ACCESSORY_SLOT_UTILITY back as a valid accessory
. = ..()
if(slot == WEAR_JACKET)
var/mob/living/carbon/human/human = user
var/obj/item/clothing/under/uniform = human.w_uniform
if(uniform)
// Figure out if the uniform originally allowed ACCESSORY_SLOT_UTILITY
var/obj/item/clothing/under/temp_uniform = new uniform.type
if(temp_uniform.valid_accessory_slots)
for(var/allowed in temp_uniform.valid_accessory_slots)
if(allowed == ACCESSORY_SLOT_UTILITY)
// It was allowed previously, now add it back
uniform.valid_accessory_slots += ACCESSORY_SLOT_UTILITY
break
qdel(temp_uniform)

/obj/item/clothing/suit/storage/marine/MP
name = "\improper M2 pattern MP armor"
Expand Down
2 changes: 0 additions & 2 deletions code/modules/gear_presets/uscm.dm
Original file line number Diff line number Diff line change
Expand Up @@ -251,8 +251,6 @@
/datum/equipment_preset/uscm/intel/full/load_gear(mob/living/carbon/human/new_human)

var/obj/item/clothing/under/marine/officer/intel/U = new(new_human)
var/obj/item/clothing/accessory/storage/webbing/W = new()
U.attach_accessory(new_human, W)
new_human.equip_to_slot_or_del(U, WEAR_BODY)
new_human.equip_to_slot_or_del(new /obj/item/device/radio/headset/almayer/intel(new_human), WEAR_L_EAR)
new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/knife(new_human), WEAR_FEET)
Expand Down
7 changes: 7 additions & 0 deletions code/modules/mob/living/carbon/human/human_helpers.dm
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,13 @@
var/datum/action/item_action/smartgun/toggle_motion_detector/TMD = locate(/datum/action/item_action/smartgun/toggle_motion_detector) in sg.actions
TMD.update_icon()
sg.motion_detector()
if(istype(i, /obj/item/clothing/suit/storage/marine/medium/rto/intel))
var/obj/item/clothing/suit/storage/marine/medium/rto/intel/xm4 = i
if(xm4.motion_detector)
xm4.motion_detector = FALSE
var/datum/action/item_action/intel/toggle_motion_detector/TMD = locate(/datum/action/item_action/intel/toggle_motion_detector) in xm4.actions
TMD.update_icon()
xm4.motion_detector()

/mob/living/carbon/human/proc/disable_headsets()
//Disable all radios to reduce radio spam for dead people
Expand Down

0 comments on commit 0a90983

Please sign in to comment.