From 8643cb2645e609b2adf81d75796fb2a3824f16d3 Mon Sep 17 00:00:00 2001 From: morrowwolf Date: Tue, 3 Oct 2023 14:12:26 -0400 Subject: [PATCH 01/17] Underbarrel extinguisher no longer requires wield (#4567) # About the pull request Underbarrel extinguisher no longer requires wield # Explain why it's good for the game Frankly, this just feels so much better and it's not an offensive weapon. # Testing Photographs and Procedure
Screenshots & Videos Put screenshots and videos here with an empty line between the screenshots and the `
` tags.
# Changelog :cl: Morrow balance: Underbarrel extinguisher no longer requires wield /:cl: --- code/modules/projectiles/gun_attachables.dm | 3 --- 1 file changed, 3 deletions(-) diff --git a/code/modules/projectiles/gun_attachables.dm b/code/modules/projectiles/gun_attachables.dm index 2438947ef254..20781639a579 100644 --- a/code/modules/projectiles/gun_attachables.dm +++ b/code/modules/projectiles/gun_attachables.dm @@ -3058,9 +3058,6 @@ Defined in conflicts.dm of the #defines folder. /obj/item/attachable/attached_gun/extinguisher/fire_attachment(atom/target, obj/item/weapon/gun/gun, mob/living/user) if(!internal_extinguisher) return - if(!(gun.flags_item & WIELDED)) - to_chat(user, SPAN_WARNING("You must wield [gun] to fire [src]!")) - return if(..()) return internal_extinguisher.afterattack(target, user) From 0e220d29fb7f5868882257cc5c8b5eb7e94a5ed4 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Tue, 3 Oct 2023 19:21:31 +0100 Subject: [PATCH 02/17] Automatic changelog for PR #4567 [ci skip] --- html/changelogs/AutoChangeLog-pr-4567.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4567.yml diff --git a/html/changelogs/AutoChangeLog-pr-4567.yml b/html/changelogs/AutoChangeLog-pr-4567.yml new file mode 100644 index 000000000000..b3002c15f75a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4567.yml @@ -0,0 +1,4 @@ +author: "Morrow" +delete-after: True +changes: + - balance: "Underbarrel extinguisher no longer requires wield" \ No newline at end of file From 93179913d19bc521572bf135036144aadde8012d Mon Sep 17 00:00:00 2001 From: BeagleGaming1 <56142455+BeagleGaming1@users.noreply.github.com> Date: Tue, 3 Oct 2023 16:25:59 -0400 Subject: [PATCH 03/17] Inventory Manipulation Keybinds (#4578) # About the pull request Adds keybinds for interaction with inventory slots # Explain why it's good for the game Allows you to access inventory storages without needing to click on them. (I will use this to play without a hud) # Testing Photographs and Procedure
Screenshots & Videos Put screenshots and videos here with an empty line between the screenshots and the `
` tags.
# Changelog :cl: add: Added keybinds to allow inventory manipulation /:cl: --- code/__DEFINES/keybinding.dm | 28 ++- code/datums/keybinding/human.dm | 118 +---------- code/datums/keybinding/human_combat.dm | 1 - code/datums/keybinding/human_inventory.dm | 244 ++++++++++++++++++++++ colonialmarines.dme | 1 + 5 files changed, 271 insertions(+), 121 deletions(-) create mode 100644 code/datums/keybinding/human_inventory.dm diff --git a/code/__DEFINES/keybinding.dm b/code/__DEFINES/keybinding.dm index b044e3426bc1..437c1e74f81f 100644 --- a/code/__DEFINES/keybinding.dm +++ b/code/__DEFINES/keybinding.dm @@ -43,12 +43,6 @@ #define COMSIG_KG_CLIENT_RADIO_DOWN "keybinding_client_radio_down" //Human -#define COMSIG_KB_HUMAN_QUICKEQUIP_DOWN "keybinding_human_quickequip_down" -#define COMSIG_KB_HUMAN_SECONDARY_DOWN "keybinding_human_secondary_down" -#define COMSIG_KB_HUMAN_TERTIARY_DOWN "keybinding_human_tertiary_down" -#define COMSIG_KB_HUMAN_QUATERNARY_DOWN "keybinding_human_quaternary_down" -#define COMSIG_KB_HUMAN_QUICK_EQUIP_DOWN "keybinding_human_quick_equip_down" - #define COMSIG_KB_HUMAN_ISSUE_ORDER "keybinding_human_issue_order" #define COMSIG_KB_HUMAN_ISSUE_ORDER_MOVE "keybinding_human_issue_order_move" #define COMSIG_KB_HUMAN_ISSUE_ORDER_HOLD "keybinding_human_issue_order_hold" @@ -57,12 +51,29 @@ #define COMSIG_KB_HUMAN_SPECIALIST_ACTIVATION_ONE "keybinding_human_specialist_activation_one" #define COMSIG_KB_HUMAN_SPECIALIST_ACTIVATION_TWO "keybinding_human_specialist_activation_two" -#define COMSIG_KB_HUMAN_PICK_UP "keybinding_human_pick_up" - #define COMSIG_KB_HUMAN_ROTATE_CHAIR "keybinding_human_rotate_chair" #define COMSIG_KB_HUMAN_SHOW_HELD_ITEM "keybinding_human_show_held_item" +// Human Inventory Navigation +#define COMSIG_KB_HUMAN_INTERACT_OTHER_HAND "keybinding_human_interact_other_hand" +#define COMSIG_KB_HUMAN_INTERACT_SLOT_BACK "keybinding_human_interact_slot_back" +#define COMSIG_KB_HUMAN_INTERACT_SLOT_BELT "keybinding_human_interact_slot_belt" +#define COMSIG_KB_HUMAN_INTERACT_SLOT_UNIFORM "keybinding_human_interact_slot_uniform" +#define COMSIG_KB_HUMAN_INTERACT_SLOT_SUIT "keybinding_human_interact_slot_suit" +#define COMSIG_KB_HUMAN_INTERACT_SLOT_HELMET "keybinding_human_interact_slot_helmet" +#define COMSIG_KB_HUMAN_INTERACT_SLOT_LEFT_POUCH "keybinding_human_interact_slot_left_pouch" +#define COMSIG_KB_HUMAN_INTERACT_SLOT_RIGHT_POUCH "keybinding_human_interact_slot_right_pouch" +#define COMSIG_KB_HUMAN_INTERACT_SUIT_S_STORE "keybinding_human_interact_slot_suit_storage" + +#define COMSIG_KB_HUMAN_INTERACT_QUICKEQUIP_DOWN "keybinding_human_interact_quickequip_down" +#define COMSIG_KB_HUMAN_INTERACT_SECONDARY_DOWN "keybinding_human_interact_secondary_down" +#define COMSIG_KB_HUMAN_INTERACT_TERTIARY_DOWN "keybinding_human_interact_tertiary_down" +#define COMSIG_KB_HUMAN_INTERACT_QUATERNARY_DOWN "keybinding_human_interact_quaternary_down" +#define COMSIG_KB_HUMAN_INTERACT_QUICK_EQUIP_DOWN "keybinding_human_interact_quick_equip_down" + +#define COMSIG_KB_HUMAN_INTERACT_PICK_UP "keybinding_human_interact_pick_up" + // Human Combat #define COMSIG_KB_HUMAN_WEAPON_FIELDSTRIP "keybinding_human_weapon_fieldstrip" #define COMSIG_KB_HUMAN_WEAPON_BURSTFIRE "keybinding_human_weapon_burstfire" @@ -199,6 +210,7 @@ #define CATEGORY_CARBON "CARBON" #define CATEGORY_HUMAN "HUMAN" #define CATEGORY_HUMAN_COMBAT "HUMAN COMBAT" +#define CATEGORY_HUMAN_INVENTORY "HUMAN INVENTORY" #define CATEGORY_ROBOT "ROBOT" #define CATEGORY_YAUTJA "YAUTJA" #define CATEGORY_MISC "MISC" diff --git a/code/datums/keybinding/human.dm b/code/datums/keybinding/human.dm index 6580c38083ea..42cb17ed1059 100644 --- a/code/datums/keybinding/human.dm +++ b/code/datums/keybinding/human.dm @@ -1,8 +1,3 @@ -#define QUICK_EQUIP_PRIMARY 1 -#define QUICK_EQUIP_SECONDARY 2 -#define QUICK_EQUIP_TERTIARY 3 -#define QUICK_EQUIP_QUATERNARY 4 - /datum/keybinding/human category = CATEGORY_HUMAN weight = WEIGHT_MOB @@ -10,86 +5,6 @@ /datum/keybinding/human/can_use(client/user) return ishuman(user.mob) -/datum/keybinding/human/quick_equip - hotkey_keys = list("E") - classic_keys = list("E") - name = "quick_equip" - full_name = "Unholster" - description = "Take out an available weapon" - keybind_signal = COMSIG_KB_HUMAN_QUICKEQUIP_DOWN - -/datum/keybinding/human/quick_equip/down(client/user) - . = ..() - if(.) - return - var/mob/living/carbon/human/H = user.mob - H.holster_verb(QUICK_EQUIP_PRIMARY) - return TRUE - -/datum/keybinding/human/quick_equip_secondary - hotkey_keys = list("Shift+E") - classic_keys = list("Shift+E") - name = "quick_equip_secondary" - full_name = "Unholster secondary" - description = "Take out your secondary weapon" - keybind_signal = COMSIG_KB_HUMAN_SECONDARY_DOWN - -/datum/keybinding/human/quick_equip_secondary/down(client/user) - . = ..() - if(.) - return - var/mob/living/carbon/human/H = user.mob - H.holster_verb(QUICK_EQUIP_SECONDARY) - return TRUE - -/datum/keybinding/human/quick_equip_tertiary - hotkey_keys = list("Ctrl+E", "Alt+E") - classic_keys = list("Ctrl+E", "Alt+E") - name = "quick_equip_tertiary" - full_name = "Unholster tertiary" - description = "Take out your tertiary item." - keybind_signal = COMSIG_KB_HUMAN_TERTIARY_DOWN - -/datum/keybinding/human/quick_equip_tertiary/down(client/user) - . = ..() - if(.) - return - var/mob/living/carbon/human/H = user.mob - H.holster_verb(QUICK_EQUIP_TERTIARY) - return TRUE - -/datum/keybinding/human/quick_equip_quaternary - hotkey_keys = list("Unbound") - classic_keys = list("Unbound") - name = "quick_equip_quaternary" - full_name = "Unholster quaternary" - description = "Take out your quaternary item." - keybind_signal = COMSIG_KB_HUMAN_QUATERNARY_DOWN - -/datum/keybinding/human/quick_equip_quaternary/down(client/user) - . = ..() - if(.) - return - var/mob/living/carbon/human/H = user.mob - H.holster_verb(QUICK_EQUIP_QUATERNARY) - return TRUE - -/datum/keybinding/human/quick_equip_inventory - hotkey_keys = list("Unbound") - classic_keys = list("Unbound") - name = "quick_equip_inventory" - full_name = "Quick equip inventory" - description = "Quickly puts an item in the best slot available" - keybind_signal = COMSIG_KB_HUMAN_QUICK_EQUIP_DOWN - -/datum/keybinding/human/quick_equip_inventory/down(client/user) - . = ..() - if(.) - return - var/mob/living/carbon/human/H = user.mob - H.quick_equip() - return TRUE - /datum/keybinding/human/issue_order hotkey_keys = list("Unbound") classic_keys = list("Unbound") @@ -103,8 +18,8 @@ . = ..() if(.) return - var/mob/living/carbon/human/H = user.mob - H.issue_order(order) + var/mob/living/carbon/human/human_mob = user.mob + human_mob.issue_order(order) return TRUE /datum/keybinding/human/issue_order/move @@ -139,8 +54,8 @@ . = ..() if(.) return - var/mob/living/carbon/human/H = user.mob - H.spec_activation_one() + var/mob/living/carbon/human/human_mob = user.mob + human_mob.spec_activation_one() return TRUE /datum/keybinding/human/specialist_two @@ -154,24 +69,8 @@ . = ..() if(.) return - var/mob/living/carbon/human/H = user.mob - H.spec_activation_two() - return TRUE - -/datum/keybinding/human/pick_up - hotkey_keys = list("F") - classic_keys = list("Unbound") - name = "pick_up" - full_name = "Pick Up Dropped Items" - keybind_signal = COMSIG_KB_HUMAN_PICK_UP - -/datum/keybinding/human/pick_up/down(client/user) - . = ..() - if(.) - return - - var/mob/living/carbon/human/human_user = user.mob - human_user.pickup_recent() + var/mob/living/carbon/human/human_mob = user.mob + human_mob.spec_activation_two() return TRUE /datum/keybinding/human/rotate_chair @@ -208,8 +107,3 @@ if(shown_item && !(shown_item.flags_item & ITEM_ABSTRACT)) shown_item.showoff(human_user) return TRUE - -#undef QUICK_EQUIP_PRIMARY -#undef QUICK_EQUIP_SECONDARY -#undef QUICK_EQUIP_TERTIARY -#undef QUICK_EQUIP_QUATERNARY diff --git a/code/datums/keybinding/human_combat.dm b/code/datums/keybinding/human_combat.dm index 003fba3b00bd..2f37efc61438 100644 --- a/code/datums/keybinding/human_combat.dm +++ b/code/datums/keybinding/human_combat.dm @@ -1,6 +1,5 @@ /datum/keybinding/human/combat category = CATEGORY_HUMAN_COMBAT - weight = WEIGHT_MOB /datum/keybinding/human/combat/can_use(client/user) . = ..() diff --git a/code/datums/keybinding/human_inventory.dm b/code/datums/keybinding/human_inventory.dm new file mode 100644 index 000000000000..163cbccdd5c0 --- /dev/null +++ b/code/datums/keybinding/human_inventory.dm @@ -0,0 +1,244 @@ +/datum/keybinding/human/inventory + category = CATEGORY_HUMAN_INVENTORY + +#define QUICK_EQUIP_PRIMARY 1 +#define QUICK_EQUIP_SECONDARY 2 +#define QUICK_EQUIP_TERTIARY 3 +#define QUICK_EQUIP_QUATERNARY 4 + +/datum/keybinding/human/inventory/quick_equip + hotkey_keys = list("E") + classic_keys = list("E") + name = "quick_equip" + full_name = "Unholster" + description = "Take out an available weapon" + keybind_signal = COMSIG_KB_HUMAN_INTERACT_QUICKEQUIP_DOWN + +/datum/keybinding/human/inventory/quick_equip/down(client/user) + . = ..() + if(.) + return + var/mob/living/carbon/human/human_mob = user.mob + human_mob.holster_verb(QUICK_EQUIP_PRIMARY) + return TRUE + +/datum/keybinding/human/inventory/quick_equip_secondary + hotkey_keys = list("Shift+E") + classic_keys = list("Shift+E") + name = "quick_equip_secondary" + full_name = "Unholster secondary" + description = "Take out your secondary weapon" + keybind_signal = COMSIG_KB_HUMAN_INTERACT_SECONDARY_DOWN + +/datum/keybinding/human/inventory/quick_equip_secondary/down(client/user) + . = ..() + if(.) + return + var/mob/living/carbon/human/human_mob = user.mob + human_mob.holster_verb(QUICK_EQUIP_SECONDARY) + return TRUE + +/datum/keybinding/human/inventory/quick_equip_tertiary + hotkey_keys = list("Ctrl+E", "Alt+E") + classic_keys = list("Ctrl+E", "Alt+E") + name = "quick_equip_tertiary" + full_name = "Unholster tertiary" + description = "Take out your tertiary item." + keybind_signal = COMSIG_KB_HUMAN_INTERACT_TERTIARY_DOWN + +/datum/keybinding/human/inventory/quick_equip_tertiary/down(client/user) + . = ..() + if(.) + return + var/mob/living/carbon/human/human_mob = user.mob + human_mob.holster_verb(QUICK_EQUIP_TERTIARY) + return TRUE + +/datum/keybinding/human/inventory/quick_equip_quaternary + hotkey_keys = list("Unbound") + classic_keys = list("Unbound") + name = "quick_equip_quaternary" + full_name = "Unholster quaternary" + description = "Take out your quaternary item." + keybind_signal = COMSIG_KB_HUMAN_INTERACT_QUATERNARY_DOWN + +/datum/keybinding/human/inventory/quick_equip_quaternary/down(client/user) + . = ..() + if(.) + return + var/mob/living/carbon/human/human_mob = user.mob + human_mob.holster_verb(QUICK_EQUIP_QUATERNARY) + return TRUE + +#undef QUICK_EQUIP_PRIMARY +#undef QUICK_EQUIP_SECONDARY +#undef QUICK_EQUIP_TERTIARY +#undef QUICK_EQUIP_QUATERNARY + +/datum/keybinding/human/inventory/quick_equip_inventory + hotkey_keys = list("Unbound") + classic_keys = list("Unbound") + name = "quick_equip_inventory" + full_name = "Quick equip inventory" + description = "Quickly puts an item in the best slot available" + keybind_signal = COMSIG_KB_HUMAN_INTERACT_QUICK_EQUIP_DOWN + +/datum/keybinding/human/inventory/quick_equip_inventory/down(client/user) + . = ..() + if(.) + return + var/mob/living/carbon/human/human_mob = user.mob + human_mob.quick_equip() + return TRUE + +/datum/keybinding/human/inventory/pick_up + hotkey_keys = list("F") + classic_keys = list("Unbound") + name = "pick_up" + full_name = "Pick Up Dropped Items" + keybind_signal = COMSIG_KB_HUMAN_INTERACT_PICK_UP + +/datum/keybinding/human/inventory/pick_up/down(client/user) + . = ..() + if(.) + return + + var/mob/living/carbon/human/human_user = user.mob + human_user.pickup_recent() + return TRUE + +/datum/keybinding/human/inventory/interact_other_hand + hotkey_keys = list("Unbound") + classic_keys = list("Unbound") + name = "interact_other_hand" + full_name = "Interact With Other Hand" + keybind_signal = COMSIG_KB_HUMAN_INTERACT_OTHER_HAND + +/datum/keybinding/human/inventory/interact_other_hand/down(client/user) + . = ..() + if(.) + return + + var/mob/living/carbon/human/human_user = user.mob + + var/active_hand = human_user.get_active_hand() + var/inactive_hand = human_user.get_inactive_hand() + + if(!inactive_hand) + return + human_user.click_adjacent(inactive_hand, active_hand) + return TRUE + +#define INTERACT_KEYBIND_COOLDOWN_TIME (0.2 SECONDS) +#define COOLDOWN_SLOT_INTERACT_KEYBIND "slot_interact_keybind_cooldown" + +/datum/keybinding/human/inventory/interact_slot + hotkey_keys = list("Unbound") + classic_keys = list("Unbound") + var/storage_slot + +/datum/keybinding/human/inventory/interact_slot/proc/check_slot(mob/living/carbon/human/user) + return + +/datum/keybinding/human/inventory/interact_slot/down(client/user) + . = ..() + if(.) + return + if(!storage_slot) + return + if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_SLOT_INTERACT_KEYBIND)) + return + + TIMER_COOLDOWN_START(src, COOLDOWN_SLOT_INTERACT_KEYBIND, INTERACT_KEYBIND_COOLDOWN_TIME) + var/mob/living/carbon/human/human_user = user.mob + var/obj/item/current_item = check_slot(human_user) + var/obj/item/in_hand_item = human_user.get_active_hand() + + if(in_hand_item) + if(!current_item) + if(!human_user.equip_to_slot_if_possible(in_hand_item, storage_slot, FALSE, FALSE)) + return + return TRUE + + current_item.attackby(in_hand_item, human_user) + return TRUE + + if(!current_item) + return + current_item.attack_hand(human_user) + return TRUE + +/datum/keybinding/human/inventory/interact_slot/back + name = "interact_storage_back" + full_name = "Interact With Back Slot" + keybind_signal = COMSIG_KB_HUMAN_INTERACT_SLOT_BACK + storage_slot = WEAR_BACK + +/datum/keybinding/human/inventory/interact_slot/back/check_slot(mob/living/carbon/human/user) + return user.back + +/datum/keybinding/human/inventory/interact_slot/belt + name = "interact_storage_belt" + full_name = "Interact With Belt Slot" + keybind_signal = COMSIG_KB_HUMAN_INTERACT_SLOT_BELT + storage_slot = WEAR_WAIST + +/datum/keybinding/human/inventory/interact_slot/belt/check_slot(mob/living/carbon/human/user) + return user.belt + +/datum/keybinding/human/inventory/interact_slot/pouch_left + name = "interact_storage_pouch_left" + full_name = "Interact With Left Pouch Slot" + keybind_signal = COMSIG_KB_HUMAN_INTERACT_SLOT_LEFT_POUCH + storage_slot = WEAR_L_STORE + +/datum/keybinding/human/inventory/interact_slot/pouch_left/check_slot(mob/living/carbon/human/user) + return user.l_store + +/datum/keybinding/human/inventory/interact_slot/pouch_right + name = "interact_storage_pouch_right" + full_name = "Interact With Right Pouch Slot" + keybind_signal = COMSIG_KB_HUMAN_INTERACT_SLOT_RIGHT_POUCH + storage_slot = WEAR_R_STORE + +/datum/keybinding/human/inventory/interact_slot/pouch_right/check_slot(mob/living/carbon/human/user) + return user.r_store + +/datum/keybinding/human/inventory/interact_slot/uniform + name = "interact_storage_uniform" + full_name = "Interact With Uniform Slot" + keybind_signal = COMSIG_KB_HUMAN_INTERACT_SLOT_UNIFORM + storage_slot = WEAR_BODY + +/datum/keybinding/human/inventory/interact_slot/uniform/check_slot(mob/living/carbon/human/user) + return user.w_uniform + +/datum/keybinding/human/inventory/interact_slot/suit + name = "interact_storage_suit" + full_name = "Interact With Suit Slot" + keybind_signal = COMSIG_KB_HUMAN_INTERACT_SLOT_SUIT + storage_slot = WEAR_JACKET + +/datum/keybinding/human/inventory/interact_slot/suit/check_slot(mob/living/carbon/human/user) + return user.wear_suit + +/datum/keybinding/human/inventory/interact_slot/helmet + name = "interact_storage_helmet" + full_name = "Interact With Head Slot" + keybind_signal = COMSIG_KB_HUMAN_INTERACT_SLOT_HELMET + storage_slot = WEAR_HEAD + +/datum/keybinding/human/inventory/interact_slot/helmet/check_slot(mob/living/carbon/human/user) + return user.head + +/datum/keybinding/human/inventory/interact_slot/suit_storage + name = "interact_storage_suit_store" + full_name = "Interact With Suit Storage Slot" + keybind_signal = COMSIG_KB_HUMAN_INTERACT_SUIT_S_STORE + storage_slot = WEAR_J_STORE + +/datum/keybinding/human/inventory/interact_slot/suit_storage/check_slot(mob/living/carbon/human/user) + return user.s_store + +#undef INTERACT_KEYBIND_COOLDOWN_TIME +#undef COOLDOWN_SLOT_INTERACT_KEYBIND diff --git a/colonialmarines.dme b/colonialmarines.dme index 3f40c156d075..63140be5e458 100644 --- a/colonialmarines.dme +++ b/colonialmarines.dme @@ -529,6 +529,7 @@ s// DM Environment file for colonialmarines.dme. #include "code\datums\keybinding\emote.dm" #include "code\datums\keybinding\human.dm" #include "code\datums\keybinding\human_combat.dm" +#include "code\datums\keybinding\human_inventory.dm" #include "code\datums\keybinding\living.dm" #include "code\datums\keybinding\mob.dm" #include "code\datums\keybinding\movement.dm" From a623ee3d8a852f18a3b1fe3818e37fb8ee564488 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Tue, 3 Oct 2023 21:34:22 +0100 Subject: [PATCH 04/17] Automatic changelog for PR #4578 [ci skip] --- html/changelogs/AutoChangeLog-pr-4578.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4578.yml diff --git a/html/changelogs/AutoChangeLog-pr-4578.yml b/html/changelogs/AutoChangeLog-pr-4578.yml new file mode 100644 index 000000000000..ccce54c8337e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4578.yml @@ -0,0 +1,4 @@ +author: "BeagleGaming1" +delete-after: True +changes: + - rscadd: "Added keybinds to allow inventory manipulation" \ No newline at end of file From f0c52f7585eaba2808c092f4bff6ef17772bb801 Mon Sep 17 00:00:00 2001 From: morrowwolf Date: Tue, 3 Oct 2023 19:19:01 -0400 Subject: [PATCH 05/17] UPP surv redo and removing ambiguous text (#4576) # About the pull request The previous UPP surv changes got undone in a soft conflict while moving things around so they're back. The removed text creates a feeling of *possibly* the USCM are hostile but this is never the case and UPP are explicitly not hostile as survivors. # Explain why it's good for the game Not losing PRs good. Confusing text bad. # Testing Photographs and Procedure
Screenshots & Videos Put screenshots and videos here with an empty line between the screenshots and the `
` tags.
# Changelog :cl: Morrow fix: Re-added previous UPP changes that were lost in soft conflict spellcheck: Removed some ambiguous text about loyalties for UPP survivors /:cl: --- .../game/objects/effects/landmarks/survivor_spawner.dm | 10 +++++----- .../trijent/crashlanding_upp_bar_insert_trijent.dm | 9 ++------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/code/game/objects/effects/landmarks/survivor_spawner.dm b/code/game/objects/effects/landmarks/survivor_spawner.dm index 25cc1a80d0b4..fe4254982d57 100644 --- a/code/game/objects/effects/landmarks/survivor_spawner.dm +++ b/code/game/objects/effects/landmarks/survivor_spawner.dm @@ -145,7 +145,7 @@ intro_text = list("

You are a member of a UPP recon force!

",\ "You ARE aware of the xenomorph threat.",\ "Your primary objective is to survive. You believe a second dropship crashed somewhere to the south east, which was carrying additional weapons") - story_text = "Your orders were simple, Recon the site, ascertain if there is a biological weapons program in the area, and if so to secure the colony and retrieve a sample. However your team failed to account for an active anti-air battery near the area. Both your craft and your sister ship crashed. Barely having a chance to catch your breath, you found yourself being assailed by vile xenomorphs! You and your team have barely held your ground, at the cost of four of your own, but more are coming and ammo is low. You believe an American rescue force is en route, but is the enemy of my enemy truly your friend?" + story_text = "Your orders were simple, Recon the site, ascertain if there is a biological weapons program in the area, and if so to secure the colony and retrieve a sample. However your team failed to account for an active anti-air battery near the area. Both your craft and your sister ship crashed. Barely having a chance to catch your breath, you found yourself being assailed by vile xenomorphs! You and your team have barely held your ground, at the cost of four of your own, but more are coming and ammo is low. You believe an American rescue force is en route." spawn_priority = SPAWN_PRIORITY_LOW /obj/effect/landmark/survivor_spawner/upp_sapper @@ -154,7 +154,7 @@ intro_text = list("

You are a member of a UPP recon force!

",\ "You ARE aware of the xenomorph threat.",\ "Your primary objective is to survive. You believe a second dropship crashed somewhere to the south east, which was carrying additional weapons") - story_text = "Your orders were simple, Recon the site, ascertain if there is a biological weapons program in the area, and if so to secure the colony and retrieve a sample. However your team failed to account for an active anti-air battery near the area. Both your craft and your sister ship crashed. Barely having a chance to catch your breath, you found yourself being assailed by vile xenomorphs! You and your team have barely held your ground, at the cost of four of your own, but more are coming and ammo is low. You believe an American rescue force is en route, but is the enemy of my enemy truly your friend?" + story_text = "Your orders were simple, Recon the site, ascertain if there is a biological weapons program in the area, and if so to secure the colony and retrieve a sample. However your team failed to account for an active anti-air battery near the area. Both your craft and your sister ship crashed. Barely having a chance to catch your breath, you found yourself being assailed by vile xenomorphs! You and your team have barely held your ground, at the cost of four of your own, but more are coming and ammo is low. You believe an American rescue force is en route." spawn_priority = SPAWN_PRIORITY_MEDIUM /obj/effect/landmark/survivor_spawner/upp_medic @@ -163,7 +163,7 @@ intro_text = list("

You are a member of a UPP recon force!

",\ "You ARE aware of the xenomorph threat.",\ "Your primary objective is to survive. You believe a second dropship crashed somewhere to the south east, which was carrying additional weapons") - story_text = "Your orders were simple, Recon the site, ascertain if there is a biological weapons program in the area, and if so to secure the colony and retrieve a sample. However your team failed to account for an active anti-air battery near the area. Both your craft and your sister ship crashed. Barely having a chance to catch your breath, you found yourself being assailed by vile xenomorphs! You and your team have barely held your ground, at the cost of four of your own, but more are coming and ammo is low. You believe an American rescue force is en route, but is the enemy of my enemy truly your friend?" + story_text = "Your orders were simple, Recon the site, ascertain if there is a biological weapons program in the area, and if so to secure the colony and retrieve a sample. However your team failed to account for an active anti-air battery near the area. Both your craft and your sister ship crashed. Barely having a chance to catch your breath, you found yourself being assailed by vile xenomorphs! You and your team have barely held your ground, at the cost of four of your own, but more are coming and ammo is low. You believe an American rescue force is en route." spawn_priority = SPAWN_PRIORITY_MEDIUM /obj/effect/landmark/survivor_spawner/upp_specialist @@ -172,7 +172,7 @@ intro_text = list("

You are a member of a UPP recon force!

",\ "You ARE aware of the xenomorph threat.",\ "Your primary objective is to survive. You believe a second dropship crashed somewhere to the south east, which was carrying additional weapons") - story_text = "Your orders were simple, Recon the site, ascertain if there is a biological weapons program in the area, and if so to secure the colony and retrieve a sample. However your team failed to account for an active anti-air battery near the area. Both your craft and your sister ship crashed. Barely having a chance to catch your breath, you found yourself being assailed by vile xenomorphs! You and your team have barely held your ground, at the cost of four of your own, but more are coming and ammo is low. You believe an American rescue force is en route, but is the enemy of my enemy truly your friend?" + story_text = "Your orders were simple, Recon the site, ascertain if there is a biological weapons program in the area, and if so to secure the colony and retrieve a sample. However your team failed to account for an active anti-air battery near the area. Both your craft and your sister ship crashed. Barely having a chance to catch your breath, you found yourself being assailed by vile xenomorphs! You and your team have barely held your ground, at the cost of four of your own, but more are coming and ammo is low. You believe an American rescue force is en route." spawn_priority = SPAWN_PRIORITY_HIGH /obj/effect/landmark/survivor_spawner/squad_leader @@ -181,5 +181,5 @@ intro_text = list("

You are a member of a UPP recon force!

",\ "You ARE aware of the xenomorph threat.",\ "Your primary objective is to survive. You believe a second dropship crashed somewhere to the south east, which was carrying additional weapons") - story_text = "Your orders were simple, Recon the site, ascertain if there is a biological weapons program in the area, and if so to secure the colony and retrieve a sample. However your team failed to account for an active anti-air battery near the area. Both your craft and your sister ship crashed. Barely having a chance to catch your breath, you found yourself being assailed by vile xenomorphs! You and your team have barely held your ground, at the cost of four of your own, but more are coming and ammo is low. You believe an American rescue force is en route, but is the enemy of my enemy truly your friend?" + story_text = "Your orders were simple, Recon the site, ascertain if there is a biological weapons program in the area, and if so to secure the colony and retrieve a sample. However your team failed to account for an active anti-air battery near the area. Both your craft and your sister ship crashed. Barely having a chance to catch your breath, you found yourself being assailed by vile xenomorphs! You and your team have barely held your ground, at the cost of four of your own, but more are coming and ammo is low. You believe an American rescue force is en route." spawn_priority = SPAWN_PRIORITY_VERY_HIGH diff --git a/code/modules/gear_presets/survivors/trijent/crashlanding_upp_bar_insert_trijent.dm b/code/modules/gear_presets/survivors/trijent/crashlanding_upp_bar_insert_trijent.dm index e8dc8482b769..147e40a24314 100644 --- a/code/modules/gear_presets/survivors/trijent/crashlanding_upp_bar_insert_trijent.dm +++ b/code/modules/gear_presets/survivors/trijent/crashlanding_upp_bar_insert_trijent.dm @@ -9,18 +9,13 @@ languages = list(LANGUAGE_RUSSIAN, LANGUAGE_GERMAN, LANGUAGE_CHINESE) faction = FACTION_UPP faction_group = list(FACTION_UPP, FACTION_SURVIVOR) - role_comm_title = "UPP 173RD RECON" + role_comm_title = "173/RECON" idtype = /obj/item/card/id/dogtag flags = EQUIPMENT_PRESET_EXTRA - uses_special_name = TRUE access = list( ACCESS_CIVILIAN_PUBLIC, ) -/datum/equipment_preset/survivor/upp/load_name(mob/living/carbon/human/new_human, randomise) - var/random_name = capitalize(pick(new_human.gender == MALE ? first_names_male_upp : first_names_female_upp)) + " " + capitalize(pick(last_names_upp)) - new_human.change_real_name(new_human, random_name) - /datum/equipment_preset/survivor/upp/load_gear(mob/living/carbon/human/new_human) var/obj/item/clothing/under/marine/veteran/UPP/uniform = new() var/random_number = rand(1,2) @@ -152,7 +147,7 @@ assignment = JOB_UPP_LEADER rank = JOB_UPP_LEADER languages = list(LANGUAGE_RUSSIAN, LANGUAGE_ENGLISH, LANGUAGE_GERMAN, LANGUAGE_CHINESE) - role_comm_title = "UPP 173Rd RECON SL" + role_comm_title = "173/RECON SL" skills = /datum/skills/military/survivor/upp_sl /datum/equipment_preset/survivor/upp/squad_leader/load_gear(mob/living/carbon/human/new_human) From cc920371dec4cd5f66ae5e618edaa35f9f5821e4 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Wed, 4 Oct 2023 00:26:59 +0100 Subject: [PATCH 06/17] Automatic changelog for PR #4576 [ci skip] --- html/changelogs/AutoChangeLog-pr-4576.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4576.yml diff --git a/html/changelogs/AutoChangeLog-pr-4576.yml b/html/changelogs/AutoChangeLog-pr-4576.yml new file mode 100644 index 000000000000..d37ec48e7603 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4576.yml @@ -0,0 +1,5 @@ +author: "Morrow" +delete-after: True +changes: + - bugfix: "Re-added previous UPP changes that were lost in soft conflict" + - spellcheck: "Removed some ambiguous text about loyalties for UPP survivors" \ No newline at end of file From f7b9853619f1602fced467ec5f81c67178b2f417 Mon Sep 17 00:00:00 2001 From: morrowwolf Date: Tue, 3 Oct 2023 19:24:12 -0400 Subject: [PATCH 07/17] Fixes storage depth for internal storages (#4568) # About the pull request Allows two depth storage removal for internal storages # Explain why it's good for the game Inconsistency bad # Testing Photographs and Procedure
Screenshots & Videos Put screenshots and videos here with an empty line between the screenshots and the `
` tags.
# Changelog :cl: Morrow fix: Fixed storage depth for internal storages /:cl: --- code/_onclick/adjacent.dm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/code/_onclick/adjacent.dm b/code/_onclick/adjacent.dm index dd7a528bb8a6..6504db0d9f0c 100644 --- a/code/_onclick/adjacent.dm +++ b/code/_onclick/adjacent.dm @@ -94,6 +94,11 @@ Quick adjacency (to turf): /obj/item/Adjacent(atom/neighbor, recurse = 1) if(neighbor == loc || (loc && neighbor == loc.loc)) return TRUE + + // Internal storages have special relationships with the object they are connected to and we still want two depth adjacency for storages + if(istype(loc?.loc, /obj/item/storage/internal) && recurse > 0) + return loc.loc.Adjacent(neighbor, recurse) + if(issurface(loc)) return loc.Adjacent(neighbor, recurse) //Surfaces don't count as storage depth. else if(istype(loc, /obj/item)) From 29b4d091a75ca8094dbef2e64974b4de2dc19d70 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Wed, 4 Oct 2023 00:40:53 +0100 Subject: [PATCH 08/17] Automatic changelog for PR #4568 [ci skip] --- html/changelogs/AutoChangeLog-pr-4568.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4568.yml diff --git a/html/changelogs/AutoChangeLog-pr-4568.yml b/html/changelogs/AutoChangeLog-pr-4568.yml new file mode 100644 index 000000000000..dab5059a60a8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4568.yml @@ -0,0 +1,4 @@ +author: "Morrow" +delete-after: True +changes: + - bugfix: "Fixed storage depth for internal storages" \ No newline at end of file From 1c6e894c8fd457b170fb9a4eb349457951a4b287 Mon Sep 17 00:00:00 2001 From: morrowwolf Date: Tue, 3 Oct 2023 19:28:00 -0400 Subject: [PATCH 09/17] =?UTF-8?q?Candle=20box=20nerf=20=F0=9F=98=AD=20=20(?= =?UTF-8?q?#4569)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # About the pull request Makes it so candle boxes only hold candles # Explain why it's good for the game Goodbye my friend, I will miss you. # Testing Photographs and Procedure
Screenshots & Videos Put screenshots and videos here with an empty line between the screenshots and the `
` tags.
# Changelog :cl: Morrow fix: Candle boxes can now only hold candles /:cl: --- code/game/objects/items/storage/fancy.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/storage/fancy.dm b/code/game/objects/items/storage/fancy.dm index ea43d6b074b9..9afa0dfd1851 100644 --- a/code/game/objects/items/storage/fancy.dm +++ b/code/game/objects/items/storage/fancy.dm @@ -71,7 +71,7 @@ storage_slots = 5 throwforce = 2 flags_equip_slot = SLOT_WAIST - + can_hold = list(/obj/item/tool/candle) /obj/item/storage/fancy/candle_box/fill_preset_inventory() for(var/i=1; i <= storage_slots; i++) From 53b53999918136476742286cba1f80dfe58c8e28 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Wed, 4 Oct 2023 00:55:43 +0100 Subject: [PATCH 10/17] Automatic changelog for PR #4569 [ci skip] --- html/changelogs/AutoChangeLog-pr-4569.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4569.yml diff --git a/html/changelogs/AutoChangeLog-pr-4569.yml b/html/changelogs/AutoChangeLog-pr-4569.yml new file mode 100644 index 000000000000..e74d8a2ba876 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4569.yml @@ -0,0 +1,4 @@ +author: "Morrow" +delete-after: True +changes: + - bugfix: "Candle boxes can now only hold candles" \ No newline at end of file From 4c78d9fb327e2a442556162003637b7114721f44 Mon Sep 17 00:00:00 2001 From: morrowwolf Date: Tue, 3 Oct 2023 20:46:19 -0400 Subject: [PATCH 11/17] Operation time logging (#4570) # About the pull request This PR adds operation time offset to logs. # Explain why it's good for the game I don't see it logged anywhere else and it may be relevant in the coming map drawing PR. # Testing Photographs and Procedure
Screenshots & Videos Put screenshots and videos here with an empty line between the screenshots and the `
` tags.
# Changelog :cl: Morrow admin: Operation time logging /:cl: --- code/game/gamemodes/game_mode.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index f6f75c6ba4e0..5382d80f37a2 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -105,6 +105,7 @@ var/global/cas_tracking_id_increment = 0 //this var used to assign unique tracki np.new_player_panel_proc() round_time_lobby = world.time log_game("Round started at [time2text(world.realtime)]") + log_game("Operation time at round start is [worldtime2text()]") if(SSticker.mode) log_game("Game mode set to [SSticker.mode]") log_game("Server IP: [world.internet_address]:[world.port]") From abb458b275283847bd135e479f02aa79106cef7e Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Wed, 4 Oct 2023 01:55:45 +0100 Subject: [PATCH 12/17] Automatic changelog for PR #4570 [ci skip] --- html/changelogs/AutoChangeLog-pr-4570.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4570.yml diff --git a/html/changelogs/AutoChangeLog-pr-4570.yml b/html/changelogs/AutoChangeLog-pr-4570.yml new file mode 100644 index 000000000000..338ea713cb89 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4570.yml @@ -0,0 +1,4 @@ +author: "Morrow" +delete-after: True +changes: + - admin: "Operation time logging" \ No newline at end of file From bc59287e1d1db07fcfd8d8fd081549421ec4b893 Mon Sep 17 00:00:00 2001 From: Changelogs Date: Wed, 4 Oct 2023 01:09:35 +0000 Subject: [PATCH 13/17] Automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-pr-4567.yml | 4 ---- html/changelogs/AutoChangeLog-pr-4568.yml | 4 ---- html/changelogs/AutoChangeLog-pr-4569.yml | 4 ---- html/changelogs/AutoChangeLog-pr-4570.yml | 4 ---- html/changelogs/AutoChangeLog-pr-4573.yml | 4 ---- html/changelogs/AutoChangeLog-pr-4576.yml | 5 ----- html/changelogs/AutoChangeLog-pr-4578.yml | 4 ---- html/changelogs/archive/2023-10.yml | 12 ++++++++++++ 8 files changed, 12 insertions(+), 29 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-4567.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-4568.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-4569.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-4570.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-4573.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-4576.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-4578.yml diff --git a/html/changelogs/AutoChangeLog-pr-4567.yml b/html/changelogs/AutoChangeLog-pr-4567.yml deleted file mode 100644 index b3002c15f75a..000000000000 --- a/html/changelogs/AutoChangeLog-pr-4567.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Morrow" -delete-after: True -changes: - - balance: "Underbarrel extinguisher no longer requires wield" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-4568.yml b/html/changelogs/AutoChangeLog-pr-4568.yml deleted file mode 100644 index dab5059a60a8..000000000000 --- a/html/changelogs/AutoChangeLog-pr-4568.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Morrow" -delete-after: True -changes: - - bugfix: "Fixed storage depth for internal storages" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-4569.yml b/html/changelogs/AutoChangeLog-pr-4569.yml deleted file mode 100644 index e74d8a2ba876..000000000000 --- a/html/changelogs/AutoChangeLog-pr-4569.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Morrow" -delete-after: True -changes: - - bugfix: "Candle boxes can now only hold candles" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-4570.yml b/html/changelogs/AutoChangeLog-pr-4570.yml deleted file mode 100644 index 338ea713cb89..000000000000 --- a/html/changelogs/AutoChangeLog-pr-4570.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Morrow" -delete-after: True -changes: - - admin: "Operation time logging" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-4573.yml b/html/changelogs/AutoChangeLog-pr-4573.yml deleted file mode 100644 index bcc8300e8578..000000000000 --- a/html/changelogs/AutoChangeLog-pr-4573.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "blackdragonTOW" -delete-after: True -changes: - - sounddel: "removed 300+ ancient and unused Piano and Violin notes." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-4576.yml b/html/changelogs/AutoChangeLog-pr-4576.yml deleted file mode 100644 index d37ec48e7603..000000000000 --- a/html/changelogs/AutoChangeLog-pr-4576.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Morrow" -delete-after: True -changes: - - bugfix: "Re-added previous UPP changes that were lost in soft conflict" - - spellcheck: "Removed some ambiguous text about loyalties for UPP survivors" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-4578.yml b/html/changelogs/AutoChangeLog-pr-4578.yml deleted file mode 100644 index ccce54c8337e..000000000000 --- a/html/changelogs/AutoChangeLog-pr-4578.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "BeagleGaming1" -delete-after: True -changes: - - rscadd: "Added keybinds to allow inventory manipulation" \ No newline at end of file diff --git a/html/changelogs/archive/2023-10.yml b/html/changelogs/archive/2023-10.yml index e67005c1e744..3d9b9b3270e0 100644 --- a/html/changelogs/archive/2023-10.yml +++ b/html/changelogs/archive/2023-10.yml @@ -42,3 +42,15 @@ - rscadd: Adds the surgical drop pouch item. It comes in green, blue and black. Only available from the synthetic vendor currently. - imageadd: Adds sprites for the surgical drop pouches. +2023-10-04: + BeagleGaming1: + - rscadd: Added keybinds to allow inventory manipulation + Morrow: + - admin: Operation time logging + - balance: Underbarrel extinguisher no longer requires wield + - bugfix: Re-added previous UPP changes that were lost in soft conflict + - spellcheck: Removed some ambiguous text about loyalties for UPP survivors + - bugfix: Fixed storage depth for internal storages + - bugfix: Candle boxes can now only hold candles + blackdragonTOW: + - sounddel: removed 300+ ancient and unused Piano and Violin notes. From 8713e576c145e2919664a4afd18839c7debfec21 Mon Sep 17 00:00:00 2001 From: morrowwolf Date: Tue, 3 Oct 2023 21:33:55 -0400 Subject: [PATCH 14/17] Pylon tweaks (#4571) # About the pull request Comms relays now have a cooldown for how often they can get pylon'd. Once it gets destroyed you have to wait five minutes to turn a cluster into a pylon again. (Which then takes five minutes to get a benefit at all) Pylon bonus cap now accounts for stored larva. # Explain why it's good for the game Constantly spamming pylons was pretty frustrating and the pylon bonus cap just had an oversight with not counting stored larva. # Testing Photographs and Procedure
Screenshots & Videos Put screenshots and videos here with an empty line between the screenshots and the `
` tags.
# Changelog :cl: Morrow balance: Comms relays now have a five minute cooldown to be re-pylon'd after a pylon was destroyed fix: Pylons now account for stored larva /:cl: --- code/__DEFINES/xeno.dm | 4 ++++ code/game/machinery/telecomms/presets.dm | 14 ++++++++++++++ .../cm_aliens/structures/special/pylon_core.dm | 6 ++++-- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/code/__DEFINES/xeno.dm b/code/__DEFINES/xeno.dm index b178f0692dd6..a0a4c927d3d9 100644 --- a/code/__DEFINES/xeno.dm +++ b/code/__DEFINES/xeno.dm @@ -174,6 +174,10 @@ /// The time it takes for a pylon to give one larva while activated #define XENO_PYLON_ACTIVATION_COOLDOWN (5 MINUTES) +/// The time until you can re-corrupt a comms relay after the last pylon was destroyed +#define XENO_PYLON_DESTRUCTION_DELAY (5 MINUTES) + + /// The time against away_timer when an AFK xeno larva can be replaced #define XENO_LEAVE_TIMER_LARVA 80 //80 seconds /// The time against away_timer when an AFK xeno (not larva) can be replaced diff --git a/code/game/machinery/telecomms/presets.dm b/code/game/machinery/telecomms/presets.dm index b327bd6fdf26..5f26e9d5ed25 100644 --- a/code/game/machinery/telecomms/presets.dm +++ b/code/game/machinery/telecomms/presets.dm @@ -218,12 +218,20 @@ GLOBAL_LIST_EMPTY(all_static_telecomms_towers) /// Held image for the current overlay on the tower from xeno corruption var/image/corruption_image + /// Holds the delay for when a cluster can recorrupt the comms tower after a pylon has been destroyed + COOLDOWN_DECLARE(corruption_delay) + /obj/structure/machinery/telecomms/relay/preset/tower/mapcomms/Initialize() . = ..() RegisterSignal(src, COMSIG_ATOM_TURF_CHANGE, PROC_REF(register_with_turf)) register_with_turf() +/obj/structure/machinery/telecomms/relay/preset/tower/mapcomms/get_examine_text(mob/user) + . = ..() + if(isxeno(user) && !COOLDOWN_FINISHED(src, corruption_delay)) + . += SPAN_XENO("Corruption cooldown: [(COOLDOWN_TIMELEFT(src, corruption_delay) / (1 SECONDS))] seconds.") + /obj/structure/machinery/telecomms/relay/preset/tower/mapcomms/attack_hand(mob/user) if(user.action_busy) return @@ -323,6 +331,10 @@ GLOBAL_LIST_EMPTY(all_static_telecomms_towers) addtimer(CALLBACK(src, PROC_REF(handle_xeno_acquisition), weeded_turf), (XENO_COMM_ACQUISITION_TIME - ROUND_TIME)) return + if(!COOLDOWN_FINISHED(src, corruption_delay)) + addtimer(CALLBACK(src, PROC_REF(handle_xeno_acquisition), weeded_turf), (COOLDOWN_TIMELEFT(src, corruption_delay))) + return + var/obj/effect/alien/weeds/node/pylon/cluster/parent_node = weeded_turf.weeds.parent var/obj/effect/alien/resin/special/cluster/cluster_parent = parent_node.resin_parent @@ -362,6 +374,8 @@ GLOBAL_LIST_EMPTY(all_static_telecomms_towers) overlays -= corruption_image + COOLDOWN_START(src, corruption_delay, XENO_PYLON_DESTRUCTION_DELAY) + /// Handles moving the overlay from growing to idle /obj/structure/machinery/telecomms/relay/preset/tower/mapcomms/proc/switch_to_idle_corruption() if(!corrupted) diff --git a/code/modules/cm_aliens/structures/special/pylon_core.dm b/code/modules/cm_aliens/structures/special/pylon_core.dm index 4eff0240939d..96ded23c8ac7 100644 --- a/code/modules/cm_aliens/structures/special/pylon_core.dm +++ b/code/modules/cm_aliens/structures/special/pylon_core.dm @@ -196,10 +196,12 @@ if(!xeno.counts_for_slots) hive_xenos -= xeno - if(length(hive_xenos) > (length(GLOB.alive_human_list) * ENDGAME_LARVA_CAP_MULTIPLIER)) + var/real_total_xeno_count = length(hive_xenos) + linked_hive.stored_larva + + if(real_total_xeno_count > (length(GLOB.alive_human_list) * ENDGAME_LARVA_CAP_MULTIPLIER)) return - linked_hive.partial_larva += length(hive_xenos) * LARVA_ADDITION_MULTIPLIER + linked_hive.partial_larva += real_total_xeno_count * LARVA_ADDITION_MULTIPLIER linked_hive.convert_partial_larva_to_full_larva() linked_hive.hive_ui.update_burrowed_larva() From 597337f6651ab1ae620f92ddf4b95de8edc7267c Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Wed, 4 Oct 2023 02:42:18 +0100 Subject: [PATCH 15/17] Automatic changelog for PR #4571 [ci skip] --- html/changelogs/AutoChangeLog-pr-4571.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4571.yml diff --git a/html/changelogs/AutoChangeLog-pr-4571.yml b/html/changelogs/AutoChangeLog-pr-4571.yml new file mode 100644 index 000000000000..bd51c77a8f37 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4571.yml @@ -0,0 +1,5 @@ +author: "Morrow" +delete-after: True +changes: + - balance: "Comms relays now have a five minute cooldown to be re-pylon'd after a pylon was destroyed" + - bugfix: "Pylons now account for stored larva" \ No newline at end of file From 766b4ab975ace1acab3f79b37cccaac750cb0078 Mon Sep 17 00:00:00 2001 From: morrowwolf Date: Tue, 3 Oct 2023 21:53:11 -0400 Subject: [PATCH 16/17] Helmet Optics Update (#4549) # About the pull request This PR: Adds NVG optics Removes functional tube NVGs from gameplay Adds a hotkey to cycle optics Refactors a bunch of backend optic stuff to make it less redundant Stops helmet destruction, or somehow visors in helmets destruction ???, from forcing a HUD or effect to stay on Adds special marine raider optic which gives night vision, medical readouts, and USCM HUD. Adds examine text for visors Adds research publication to advanced medical optic # Explain why it's good for the game Optics are awesome! Better code is good (at least I hope it's better) # Testing Photographs and Procedure
Screenshots & Videos Put screenshots and videos here with an empty line between the screenshots and the `
` tags.
# Changelog :cl: Morrow add: Added NVG optics add: Added a hotkey to cycle optics add: Added special marine raider optic add: Added examine text for optics add: Added research publication to advanced medical optic del: Removed functional tube NVGs from gameplay refactor: Moved some optics code around to make it less redundant fix: Fixed a bug with duplicate optic actions fix: Fixed a reported bug where HUDs would stay on forever with destruction of a helmet /:cl: --- code/__DEFINES/keybinding.dm | 2 + code/datums/keybinding/human.dm | 21 ++ code/datums/supply_packs/gear.dm | 12 - code/game/machinery/recharger.dm | 17 +- .../vendor_types/intelligence_officer.dm | 2 +- .../vendor_types/squad_prep/squad_leader.dm | 2 +- .../vendor_types/squad_prep/squad_tl.dm | 2 +- .../objects/items/devices/helmet_visors.dm | 267 ++++++++++++++++-- code/modules/clothing/head/helmet.dm | 62 ++-- code/modules/gear_presets/uscm.dm | 1 - icons/mob/humans/onmob/helmet_garb.dmi | Bin 29385 -> 30043 bytes icons/obj/items/clothing/helmet_visors.dmi | Bin 2645 -> 2647 bytes .../LV522_Chances_Claim.dmm | 8 +- 13 files changed, 321 insertions(+), 75 deletions(-) diff --git a/code/__DEFINES/keybinding.dm b/code/__DEFINES/keybinding.dm index 437c1e74f81f..88f194bb33df 100644 --- a/code/__DEFINES/keybinding.dm +++ b/code/__DEFINES/keybinding.dm @@ -55,6 +55,8 @@ #define COMSIG_KB_HUMAN_SHOW_HELD_ITEM "keybinding_human_show_held_item" +#define COMSIG_KB_HUMAN_CYCLE_HELMET_HUD "keybinding_human_cycle_helmet_hud" + // Human Inventory Navigation #define COMSIG_KB_HUMAN_INTERACT_OTHER_HAND "keybinding_human_interact_other_hand" #define COMSIG_KB_HUMAN_INTERACT_SLOT_BACK "keybinding_human_interact_slot_back" diff --git a/code/datums/keybinding/human.dm b/code/datums/keybinding/human.dm index 42cb17ed1059..6d7037eac398 100644 --- a/code/datums/keybinding/human.dm +++ b/code/datums/keybinding/human.dm @@ -107,3 +107,24 @@ if(shown_item && !(shown_item.flags_item & ITEM_ABSTRACT)) shown_item.showoff(human_user) return TRUE + +/datum/keybinding/human/cycle_helmet_hud + hotkey_keys = list("Unbound") + classic_keys = list("Unbound") + name = "cycle_helmet_hud" + full_name = "Cycle Helmet HUD" + keybind_signal = COMSIG_KB_HUMAN_CYCLE_HELMET_HUD + +/datum/keybinding/human/cycle_helmet_hud/down(client/user) + . = ..() + if(.) + return + + var/mob/living/carbon/human/human_user = user.mob + var/obj/item/clothing/head/helmet/marine/marine_helmet = human_user?.head + var/cycled_hud = marine_helmet?.cycle_huds(human_user) + + var/datum/action/item_action/cycle_helmet_huds/cycle_action = locate() in marine_helmet.actions + cycle_action.set_action_overlay(cycled_hud) + + return TRUE diff --git a/code/datums/supply_packs/gear.dm b/code/datums/supply_packs/gear.dm index b67f8f134c25..54a2ae221c9d 100644 --- a/code/datums/supply_packs/gear.dm +++ b/code/datums/supply_packs/gear.dm @@ -63,15 +63,3 @@ containertype = /obj/structure/closet/crate/ammo containername = "fulton recovery device crate" group = "Gear" - -/datum/supply_packs/nvg - name = "M2 Night Vision Goggles Crate (x3)" - contains = list( - /obj/item/prop/helmetgarb/helmet_nvg, - /obj/item/prop/helmetgarb/helmet_nvg, - /obj/item/prop/helmetgarb/helmet_nvg, - ) - cost = 60 - containertype = /obj/structure/closet/crate/supply - containername = "M2 Night Vission Goggles Crate" - group = "Gear" diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index 7855f446c805..c75360e07568 100644 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -11,7 +11,7 @@ black_market_value = 35 var/obj/item/charging = null var/percent_charge_complete = 0 - var/list/allowed_devices = list(/obj/item/weapon/baton, /obj/item/cell, /obj/item/weapon/gun/energy, /obj/item/device/defibrillator, /obj/item/tool/portadialysis, /obj/item/clothing/suit/auto_cpr, /obj/item/smartgun_battery) + var/list/allowed_devices = list(/obj/item/weapon/baton, /obj/item/cell, /obj/item/weapon/gun/energy, /obj/item/device/defibrillator, /obj/item/tool/portadialysis, /obj/item/clothing/suit/auto_cpr, /obj/item/smartgun_battery, /obj/item/device/helmet_visor/night_vision) var/charge_amount = 1000 @@ -181,6 +181,21 @@ update_icon() return + if(istype(charging, /obj/item/device/helmet_visor/night_vision)) + var/obj/item/device/helmet_visor/night_vision/charging_night_vision_visor = charging + if(charging_night_vision_visor.power_cell) + if(!charging_night_vision_visor.power_cell.fully_charged()) + charging_night_vision_visor.power_cell.give(charge_amount) + percent_charge_complete = charging_night_vision_visor.power_cell.percent() + update_use_power(USE_POWER_ACTIVE) + update_icon() + return + + percent_charge_complete = 100 + update_use_power(USE_POWER_IDLE) + update_icon() + return + /* Disable defib recharging if(istype(charging, /obj/item/device/defibrillator)) var/obj/item/device/defibrillator/D = charging diff --git a/code/game/machinery/vending/vendor_types/intelligence_officer.dm b/code/game/machinery/vending/vendor_types/intelligence_officer.dm index 46394bea8c2c..ad10037ccfe1 100644 --- a/code/game/machinery/vending/vendor_types/intelligence_officer.dm +++ b/code/game/machinery/vending/vendor_types/intelligence_officer.dm @@ -7,7 +7,7 @@ GLOBAL_LIST_INIT(cm_vending_gear_intelligence_officer, list( list("SUPPLIES", 0, null, null, null), list("Power Control Module", 5, /obj/item/circuitboard/apc, null, VENDOR_ITEM_REGULAR), list("Binoculars", 5, /obj/item/device/binoculars, null, VENDOR_ITEM_REGULAR), - list("M2 Night Vision Goggles", 25, /obj/item/prop/helmetgarb/helmet_nvg, null, VENDOR_ITEM_RECOMMENDED), + list("Night Vision Optic", 25, /obj/item/device/helmet_visor/night_vision, null, VENDOR_ITEM_RECOMMENDED), list("Data Detector", 5, /obj/item/device/motiondetector/intel, null, VENDOR_ITEM_REGULAR), list("Intel Radio Encryption Key", 5, /obj/item/device/encryptionkey/intel, null, VENDOR_ITEM_REGULAR), list("Fire Extinguisher (Portable)", 5, /obj/item/tool/extinguisher/mini, null, VENDOR_ITEM_REGULAR), diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_leader.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_leader.dm index ea3423260ec0..9845ff9cb610 100644 --- a/code/game/machinery/vending/vendor_types/squad_prep/squad_leader.dm +++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_leader.dm @@ -23,7 +23,7 @@ GLOBAL_LIST_INIT(cm_vending_gear_leader, list( list("Machete Pouch (Full)", 4, /obj/item/storage/pouch/machete/full, null, VENDOR_ITEM_REGULAR), list("USCM Radio Telephone Pack", 5, /obj/item/storage/backpack/marine/satchel/rto, null, VENDOR_ITEM_REGULAR), list("M276 Pattern Combat Toolbelt Rig", 15, /obj/item/storage/belt/gun/utility, null, VENDOR_ITEM_REGULAR), - list("M2 Night Vision Goggles", 20, /obj/item/prop/helmetgarb/helmet_nvg, null, VENDOR_ITEM_RECOMMENDED), + list("Night Vision Optic", 20, /obj/item/device/helmet_visor/night_vision, null, VENDOR_ITEM_RECOMMENDED), list("UTILITIES", 0, null, null, null), list("Whistle", 3, /obj/item/device/whistle, null, VENDOR_ITEM_REGULAR), diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_tl.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_tl.dm index c03d79eddfd0..875f84264c0a 100644 --- a/code/game/machinery/vending/vendor_types/squad_prep/squad_tl.dm +++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_tl.dm @@ -40,7 +40,7 @@ GLOBAL_LIST_INIT(cm_vending_gear_tl, list( list("M276 Pattern Combat Toolbelt Rig", 15, /obj/item/storage/belt/gun/utility, null, VENDOR_ITEM_REGULAR), list("Autoinjector Pouch (Full)", 15, /obj/item/storage/pouch/autoinjector/full, null, VENDOR_ITEM_REGULAR), list("Insulated Gloves", 3, /obj/item/clothing/gloves/yellow, null, VENDOR_ITEM_REGULAR), - list("M2 Night Vision Goggles", 30, /obj/item/prop/helmetgarb/helmet_nvg, null, VENDOR_ITEM_RECOMMENDED), + list("Night Vision Optic", 30, /obj/item/device/helmet_visor/night_vision, null, VENDOR_ITEM_RECOMMENDED), list("UTILITIES", 0, null, null, null), list("Binoculars", 5, /obj/item/device/binoculars, null, VENDOR_ITEM_REGULAR), diff --git a/code/game/objects/items/devices/helmet_visors.dm b/code/game/objects/items/devices/helmet_visors.dm index dd913daf7620..596409c88c8b 100644 --- a/code/game/objects/items/devices/helmet_visors.dm +++ b/code/game/objects/items/devices/helmet_visors.dm @@ -14,31 +14,65 @@ ///The sound when toggling off the visor var/toggle_off_sound = 'sound/handling/hud_off.ogg' - ///The icon name for our helmet's action + ///The icon name for our helmet's action, in 'icons/obj/items/clothing/helmet_visors.dmi' var/action_icon_string = "hud_sight_down" - ///The overlay name for when our visor is active + ///The overlay name for when our visor is active, in 'icons/mob/humans/onmob/helmet_garb.dmi' var/helmet_overlay = "hud_sight_right" +/obj/item/device/helmet_visor/Destroy(force) + if(!istype(loc, /obj/item/clothing/head/helmet/marine)) + return ..() + + if(!istype(loc?.loc, /mob/living/carbon/human)) + return ..() + + var/obj/item/clothing/head/helmet/marine/attached_helmet = loc + var/mob/living/carbon/human/user = loc.loc + deactivate_visor(attached_helmet, user) + . = ..() + /// Called to see if the user can even use this visor /obj/item/device/helmet_visor/proc/can_toggle(mob/living/carbon/human/user) return TRUE /// Called to see if this visor is a special non-HUD visor -/obj/item/device/helmet_visor/proc/visor_function(obj/item/clothing/head/helmet/marine/attached_helmet, mob/living/carbon/human/user, silent = FALSE) +/obj/item/device/helmet_visor/proc/toggle_visor(obj/item/clothing/head/helmet/marine/attached_helmet, mob/living/carbon/human/user, silent = FALSE) if(attached_helmet == user.head && attached_helmet.active_visor == src) - var/datum/mob_hud/current_mob_hud = huds[hud_type] - current_mob_hud.add_hud_to(user, attached_helmet) + + if(!can_toggle(user)) + return FALSE + + activate_visor(attached_helmet, user) + if(!silent) to_chat(user, SPAN_NOTICE("You activate [src] on [attached_helmet].")) + playsound_client(user.client, toggle_on_sound, null, 75) + return TRUE - var/datum/mob_hud/current_mob_hud = huds[hud_type] - current_mob_hud.remove_hud_from(user, attached_helmet) + deactivate_visor(attached_helmet, user) + if(!silent) to_chat(user, SPAN_NOTICE("You deactivate [src] on [attached_helmet].")) + playsound_client(user.client, toggle_off_sound, null, 75) + return TRUE +/// Called by toggle_visor() to activate the visor's effects +/obj/item/device/helmet_visor/proc/activate_visor(obj/item/clothing/head/helmet/marine/attached_helmet, mob/living/carbon/human/user) + var/datum/mob_hud/current_mob_hud = huds[hud_type] + current_mob_hud.add_hud_to(user, attached_helmet) + +/// Called by toggle_visor() to deactivate the visor's effects +/obj/item/device/helmet_visor/proc/deactivate_visor(obj/item/clothing/head/helmet/marine/attached_helmet, mob/living/carbon/human/user) + var/datum/mob_hud/current_mob_hud = huds[hud_type] + current_mob_hud.remove_hud_from(user, attached_helmet) + +/// Called by /obj/item/clothing/head/helmet/marine/get_examine_text(mob/user) to get extra examine text for this visor +/obj/item/device/helmet_visor/proc/get_helmet_examine_text() + return SPAN_NOTICE("\A [name] is flipped down.") + /obj/item/device/helmet_visor/medical name = "basic medical optic" icon_state = "med_sight" @@ -50,13 +84,75 @@ name = "advanced medical optic" helmet_overlay = "med_sight_left" +/obj/item/device/helmet_visor/medical/advanced/activate_visor(obj/item/clothing/head/helmet/marine/attached_helmet, mob/living/carbon/human/user) + . = ..() + + var/datum/action/item_action/view_publications/helmet_visor/publication_action = new(attached_helmet) + publication_action.give_to(user) + +/obj/item/device/helmet_visor/medical/advanced/deactivate_visor(obj/item/clothing/head/helmet/marine/attached_helmet, mob/living/carbon/human/user) + . = ..() + + var/datum/action/item_action/view_publications/helmet_visor/publication_action = locate() in attached_helmet.actions + qdel(publication_action) + /obj/item/device/helmet_visor/medical/advanced/can_toggle(mob/living/carbon/human/user) + . = ..() + if(!.) + return + if(!skillcheck(user, SKILL_MEDICAL, SKILL_MEDICAL_MEDIC)) to_chat(user, SPAN_NOTICE("You are not skilled enough to use [src].")) return FALSE return TRUE +/obj/item/device/helmet_visor/medical/advanced/ui_state(mob/user) + return GLOB.not_incapacitated_and_adjacent_strict_state + +/obj/item/device/helmet_visor/medical/advanced/ui_data(mob/user) + var/list/data = list( + "published_documents" = chemical_data.research_publications, + "terminal_view" = FALSE + ) + return data + +/obj/item/device/helmet_visor/medical/advanced/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if (!ui) + ui = new(user, src, "PublishedDocsHud", name) + ui.open() + +/obj/item/device/helmet_visor/medical/advanced/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + . = ..() + if(.) + return + + if(!ishuman(ui.user)) + return + + var/mob/living/carbon/human/user = ui.user + + if(user.stat || user.is_mob_restrained() || !in_range(src, user)) + return + + switch(action) + if ("read_document") + var/print_type = params["print_type"] + var/print_title = params["print_title"] + var/obj/item/paper/research_report/report = chemical_data.get_report(print_type, print_title) + if(report) + report.read_paper(user) + return + +/datum/action/item_action/view_publications/helmet_visor/action_activate() + var/obj/item/device/helmet_visor/medical/advanced/medical_visor = locate() in holder_item + + if(!medical_visor) + return + + medical_visor.tgui_interact(owner) + /obj/item/device/helmet_visor/security name = "security optic" icon_state = "sec_sight" @@ -71,28 +167,159 @@ action_icon_string = "blank_hud_sight_down" helmet_overlay = "weld_visor" -/obj/item/device/helmet_visor/welding_visor/visor_function(obj/item/clothing/head/helmet/marine/attached_helmet, mob/living/carbon/human/user, silent = FALSE) - if(attached_helmet == user.head && attached_helmet.active_visor == src) - attached_helmet.vision_impair = VISION_IMPAIR_MAX - attached_helmet.flags_inventory |= COVEREYES|COVERMOUTH - attached_helmet.flags_inv_hide |= HIDEEYES|HIDEFACE - attached_helmet.eye_protection = EYE_PROTECTION_WELDING - user.update_tint() - if(!silent) - to_chat(user, SPAN_NOTICE("You activate [src] on [attached_helmet].")) - return TRUE +/obj/item/device/helmet_visor/welding_visor/activate_visor(obj/item/clothing/head/helmet/marine/attached_helmet, mob/living/carbon/human/user) + attached_helmet.vision_impair = VISION_IMPAIR_MAX + attached_helmet.flags_inventory |= COVEREYES|COVERMOUTH + attached_helmet.flags_inv_hide |= HIDEEYES|HIDEFACE + attached_helmet.eye_protection = EYE_PROTECTION_WELDING + user.update_tint() +/obj/item/device/helmet_visor/welding_visor/deactivate_visor(obj/item/clothing/head/helmet/marine/attached_helmet, mob/living/carbon/human/user) attached_helmet.vision_impair = VISION_IMPAIR_NONE attached_helmet.flags_inventory &= ~(COVEREYES|COVERMOUTH) attached_helmet.flags_inv_hide &= ~(HIDEEYES|HIDEFACE) attached_helmet.eye_protection = EYE_PROTECTION_NONE - if(!silent) - to_chat(user, SPAN_NOTICE("You deactivate [src] on [attached_helmet].")) user.update_tint() - return TRUE /obj/item/device/helmet_visor/welding_visor/mercenary helmet_overlay = "" /obj/item/device/helmet_visor/welding_visor/tanker helmet_overlay = "tanker_weld_visor" + +#define NVG_VISOR_USAGE(delta_time) (power_cell.use(power_use * (delta_time ? delta_time : 1))) + +/obj/item/device/helmet_visor/night_vision + name = "night vision optic" + desc = "An insertable visor HUD into a standard USCM helmet. This type gives a form of night vision and is standard issue in units with regular funding." + icon_state = "nvg_sight" + hud_type = null + action_icon_string = "nvg_sight_down" + helmet_overlay = "nvg_sight_right" + toggle_on_sound = 'sound/handling/toggle_nv1.ogg' + toggle_off_sound = 'sound/handling/toggle_nv2.ogg' + + /// The internal battery for the visor + var/obj/item/cell/high/power_cell + + /// About 5 minutes active use charge (hypothetically) + var/power_use = 33 + + /// The alpha of darkness we set to for the mob while the visor is on, not completely fullbright but see-able + var/lighting_alpha = 100 + + /// A slight glowing green light while the NVG is activated, is initialized as in the attached_helmet's contents + var/atom/movable/nvg_light/on_light + + /// Whether or not the sight uses on_light and produces light + var/visor_glows = TRUE + +/obj/item/device/helmet_visor/night_vision/Initialize(mapload, ...) + . = ..() + power_cell = new(src) + +/obj/item/device/helmet_visor/night_vision/Destroy() + power_cell = null + . = ..() + +/obj/item/device/helmet_visor/night_vision/get_examine_text(mob/user) + . = ..() + + . += SPAN_NOTICE("It is currently at [round((power_cell.charge / power_cell.maxcharge) * 100)]% charge.") + +/obj/item/device/helmet_visor/night_vision/activate_visor(obj/item/clothing/head/helmet/marine/attached_helmet, mob/living/carbon/human/user) + RegisterSignal(user, COMSIG_HUMAN_POST_UPDATE_SIGHT, PROC_REF(on_update_sight)) + + user.add_client_color_matrix("nvg_visor", 99, color_matrix_multiply(color_matrix_saturation(0), color_matrix_from_string("#7aff7a"))) + user.overlay_fullscreen("nvg_visor", /atom/movable/screen/fullscreen/flash/noise/nvg) + user.overlay_fullscreen("nvg_visor_blur", /atom/movable/screen/fullscreen/brute/nvg, 3) + user.update_sight() + if(visor_glows) + on_light = new(attached_helmet) + on_light.set_light_on(TRUE) + START_PROCESSING(SSobj, src) + +/obj/item/device/helmet_visor/night_vision/deactivate_visor(obj/item/clothing/head/helmet/marine/attached_helmet, mob/living/carbon/human/user) + user.remove_client_color_matrix("nvg_visor", 1 SECONDS) + user.clear_fullscreen("nvg_visor", 0.5 SECONDS) + user.clear_fullscreen("nvg_visor_blur", 0.5 SECONDS) + + if(visor_glows) + qdel(on_light) + UnregisterSignal(user, COMSIG_HUMAN_POST_UPDATE_SIGHT) + + user.update_sight() + STOP_PROCESSING(SSobj, src) + +/obj/item/device/helmet_visor/night_vision/process(delta_time) + if(!NVG_VISOR_USAGE(delta_time)) + + if(!istype(loc, /obj/item/clothing/head/helmet/marine)) + return PROCESS_KILL + + if(!istype(loc?.loc, /mob/living/carbon/human)) + return PROCESS_KILL + + var/obj/item/clothing/head/helmet/marine/attached_helmet = loc + var/mob/living/carbon/human/user = loc.loc + to_chat(user, SPAN_NOTICE("[src] deactivates as the battery goes out.")) + deactivate_visor(attached_helmet, user) + return PROCESS_KILL + +/obj/item/device/helmet_visor/night_vision/can_toggle(mob/living/carbon/human/user) + . = ..() + if(!.) + return + + if(!NVG_VISOR_USAGE(FALSE)) + to_chat(user, SPAN_NOTICE("Your [src] is out of power! You'll need to recharge it.")) + return FALSE + + return TRUE + +/obj/item/device/helmet_visor/night_vision/get_helmet_examine_text() + . = ..() + + . += SPAN_NOTICE(" It is currently at [round((power_cell.charge / power_cell.maxcharge) * 100)]% charge.") + +/obj/item/device/helmet_visor/night_vision/proc/on_update_sight(mob/user) + SIGNAL_HANDLER + + if(lighting_alpha < 255) + user.see_in_dark = 12 + user.lighting_alpha = lighting_alpha + user.sync_lighting_plane_alpha() + +#undef NVG_VISOR_USAGE + +/atom/movable/nvg_light + light_power = 0.5 + light_range = 1 + light_color = COLOUR_GREEN + light_system = MOVABLE_LIGHT + light_flags = LIGHT_ATTACHED + +/obj/item/device/helmet_visor/night_vision/marine_raider + name = "advanced night vision optic" + desc = "An insertable visor HUD into a standard USCM helmet. This type gives a form of night vision and is standard issue in special forces units." + hud_type = list(MOB_HUD_FACTION_USCM, MOB_HUD_MEDICAL_ADVANCED) + helmet_overlay = "nvg_sight_right_raider" + power_use = 0 + visor_glows = FALSE + +/obj/item/device/helmet_visor/night_vision/marine_raider/activate_visor(obj/item/clothing/head/helmet/marine/attached_helmet, mob/living/carbon/human/user) + . = ..() + + for(var/type in hud_type) + var/datum/mob_hud/current_mob_hud = huds[type] + current_mob_hud.add_hud_to(user, attached_helmet) + +/obj/item/device/helmet_visor/night_vision/marine_raider/deactivate_visor(obj/item/clothing/head/helmet/marine/attached_helmet, mob/living/carbon/human/user) + . = ..() + + for(var/type in hud_type) + var/datum/mob_hud/current_mob_hud = huds[type] + current_mob_hud.remove_hud_from(user, attached_helmet) + +/obj/item/device/helmet_visor/night_vision/marine_raider/process(delta_time) + return PROCESS_KILL diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index c64c2a14764d..585a651582ed 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -416,9 +416,11 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list( camera = new /obj/structure/machinery/camera(src) camera.network = list(CAMERA_NET_OVERWATCH) + for(var/obj/visor as anything in built_in_visors) + visor.forceMove(src) + if(length(inserted_visors) || length(built_in_visors)) var/datum/action/item_action/cycle_helmet_huds/new_action = new(src) - LAZYADD(actions, new_action) if(ishuman(loc)) var/mob/living/carbon/human/holding_human = loc if(holding_human.head == src) @@ -439,6 +441,12 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list( helmet_overlays = null QDEL_NULL(camera) QDEL_NULL(pockets) + if(active_visor && istype(loc, /mob/living/carbon/human)) + var/mob/living/carbon/human/potential_user = loc + if(potential_user.head == src) + var/obj/item/device/helmet_visor/temp_visor_holder = active_visor + active_visor = null + toggle_visor(potential_user, temp_visor_holder, TRUE) return ..() /obj/item/clothing/head/helmet/marine/attack_hand(mob/user) @@ -494,21 +502,22 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list( return if(HAS_TRAIT(attacking_item, TRAIT_TOOL_SCREWDRIVER) && length(inserted_visors)) + if(active_visor) + var/obj/item/device/helmet_visor/temp_visor_holder = active_visor + active_visor = null + toggle_visor(user, temp_visor_holder, TRUE) + for(var/obj/item/device/helmet_visor/visor as anything in inserted_visors) visor.forceMove(get_turf(src)) inserted_visors = list() to_chat(user, SPAN_NOTICE("You remove the inserted visors.")) - var/obj/item/device/helmet_visor/temp_visor_holder = active_visor - active_visor = null - turn_off_visor(user, temp_visor_holder, TRUE) var/datum/action/item_action/cycle_helmet_huds/cycle_action = locate() in actions cycle_action.set_default_overlay() if(!length(built_in_visors)) cycle_action.remove_from(user) - recalculate_visors(user) return ..() @@ -589,6 +598,11 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list( /obj/item/clothing/head/helmet/marine/has_garb_overlay() return flags_marine_helmet & HELMET_GARB_OVERLAY +/obj/item/clothing/head/helmet/marine/get_examine_text(mob/user) + . = ..() + if(active_visor) + . += active_visor.get_helmet_examine_text() + /obj/item/clothing/head/helmet/marine/proc/add_hugger_damage() //This is called in XenoFacehuggers.dm to first add the overlay and set the var. if(flags_marine_helmet & HELMET_DAMAGE_OVERLAY && !(flags_marine_helmet & HELMET_IS_DAMAGED)) helmet_overlays["damage"] = image('icons/obj/items/clothing/cm_hats.dmi',icon_state = "hugger_damage") @@ -615,29 +629,17 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list( if(!human_user || human_user.head != src) return - turn_on_visor(human_user) + toggle_visor(user, silent = TRUE) -/// Turns on the current active visor -/obj/item/clothing/head/helmet/marine/proc/turn_on_visor(mob/user) - if(!active_visor) - return +/// Toggles the specified visor, if nothing specified then the active visor, if the visor is the active visor and the helmet is on the user's head it will turn on, if it is not the active visor it will turn off +/obj/item/clothing/head/helmet/marine/proc/toggle_visor(mob/user, obj/item/device/helmet_visor/current_visor, silent = FALSE) + current_visor = current_visor || active_visor - if(active_visor.can_toggle(user)) - active_visor.visor_function(src, user) - - playsound_client(user.client, active_visor.toggle_on_sound, null, 75) - update_icon() - -/// Turns off the specified visor -/obj/item/clothing/head/helmet/marine/proc/turn_off_visor(mob/user, obj/item/device/helmet_visor/current_visor, sound = FALSE) if(!current_visor) return - if(current_visor.can_toggle(user)) - current_visor.visor_function(src, user) + current_visor.toggle_visor(src, user, silent) - if(sound) - playsound_client(user.client, current_visor.toggle_off_sound, null, 75) update_icon() /// Attempts to turn off all visors @@ -645,8 +647,7 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list( var/list/total_visors = built_in_visors + inserted_visors for(var/obj/item/device/helmet_visor/cycled_helmet_visor in total_visors) - if(cycled_helmet_visor.can_toggle(user)) - cycled_helmet_visor.visor_function(src, user, TRUE) + cycled_helmet_visor.deactivate_visor(src, user) update_icon() @@ -662,20 +663,19 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list( for(var/hud_type in total_visors) if(hud_type == active_visor) if(length(total_visors) > iterator) - turn_off_visor(user, active_visor, FALSE) active_visor = total_visors[(iterator + 1)] - recalculate_visors(user) + toggle_visor(user, total_visors[iterator], TRUE) + toggle_visor(user) return active_visor else - turn_off_visor(user, active_visor, TRUE) active_visor = null - recalculate_visors(user) + toggle_visor(user, total_visors[iterator], FALSE) return FALSE iterator++ if(total_visors[1]) active_visor = total_visors[1] - recalculate_visors(user) + toggle_visor(user) return active_visor active_visor = null @@ -944,8 +944,8 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list( armor_bio = CLOTHING_ARMOR_MEDIUMHIGH specialty = "M10 pattern SOF" flags_atom = NO_SNOW_TYPE - built_in_visors = list(new /obj/item/device/helmet_visor, new /obj/item/device/helmet_visor/medical, new /obj/item/device/helmet_visor/security) - + built_in_visors = list(new /obj/item/device/helmet_visor/night_vision/marine_raider, new /obj/item/device/helmet_visor/security) + start_down_visor_type = /obj/item/device/helmet_visor/night_vision/marine_raider //=============================//PMCS\\==================================\\ //=======================================================================\\ diff --git a/code/modules/gear_presets/uscm.dm b/code/modules/gear_presets/uscm.dm index 1c84e7cad4ba..ec0195e928c5 100644 --- a/code/modules/gear_presets/uscm.dm +++ b/code/modules/gear_presets/uscm.dm @@ -803,7 +803,6 @@ new_human.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/pmc/marsoc, WEAR_FACE) //head new_human.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/marine/sof, WEAR_HEAD) - new_human.equip_to_slot_or_del(new /obj/item/prop/helmetgarb/helmet_nvg/marsoc, WEAR_IN_HELMET) new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/handful/shotgun/buckshot, WEAR_IN_HELMET) //uniform var/obj/item/clothing/under/marine/veteran/marsoc/M = new() diff --git a/icons/mob/humans/onmob/helmet_garb.dmi b/icons/mob/humans/onmob/helmet_garb.dmi index 325aed72b15524ed326dfbe4180c2bb27b912f66..645223618d7460acbac6929a1fdbe9638aafd925 100644 GIT binary patch literal 30043 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 literal 29385 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 QqfrJ|u3s+Kxf$`l0Luk(xc~qF diff --git a/icons/obj/items/clothing/helmet_visors.dmi b/icons/obj/items/clothing/helmet_visors.dmi index 6ba0cfe5623edec5826782fb4590bfb1e06bcbf8..f47bc9aa26d26f2f872692fc088a3a0cfd8271cf 100644 GIT binary patch delta 220 zcmV<203-j^6xS4xB!9fFDZ*Bkpc$}5dzY2pe5C-tsJjJ2A^xvAL zD8)fvK~i%~LYqWPRQmQE1ceUuy4}H#kK?-xuH~(2pr|W0;Sh{>z~Pb~STY+KHE=ke zSfbG=9hW6U5fM0~!6+Tuu}@hd%@BaYktL5oSX|~Wh_;XKT~Vt?*#@I@q)W;PZc@Zp zi@`g3utn;sx4itB}OEYJTwy W%BFy#uGk0K!RZwWR_1}R@?!}^9BO9( delta 218 zcmV<0044v|6x9@vB!9(vR9JLGWpiV4X>fFDZ*Bkpc$}4y%L;=q5JlJKD+b+5U)yYo zQe5aSNNQ3O+9YDeO8>qKL8Xg2?q=Z3;c_Q|Ykn&#$jXAfRUeFZz~Pb}STq`m8aSL! zEYixf8mA?oKm{D)U|Nm!(8Vm0rVqg3$f8FtteWN@P}vSYn@_ABWF1Vakxo(~SQWe@ zidQU6O-($Lq|#JF)XpSDD;hN3g;ZLz$=+YWJ?o`s=|{KYEhKzhHt}GWe<|l5o