From 50235d0533356c617d02bafc415b7e04ef0b5629 Mon Sep 17 00:00:00 2001 From: Molti <108117184+Moltijoe@users.noreply.github.com> Date: Fri, 19 Apr 2024 20:50:11 -0500 Subject: [PATCH] Fixes shielded hardsuits not properly appearing + refactor (#21831) * work * done --- code/modules/clothing/spacesuits/hardsuit.dm | 54 +------ yogstation/code/datums/components/shielded.dm | 133 +++++++++++------- .../code/modules/jungleland/jungle_items.dm | 2 +- 3 files changed, 86 insertions(+), 103 deletions(-) diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm index 60255b2de124..b868b39dd731 100644 --- a/code/modules/clothing/spacesuits/hardsuit.dm +++ b/code/modules/clothing/spacesuits/hardsuit.dm @@ -961,57 +961,15 @@ allowed = null armor = list(MELEE = 30, BULLET = 15, LASER = 30, ENERGY = 10, BOMB = 10, BIO = 100, RAD = 50, FIRE = 100, ACID = 100, ELECTRIC = 100) resistance_flags = FIRE_PROOF | ACID_PROOF - var/current_charges = 3 - var/max_charges = 3 //How many charges total the shielding has - var/recharge_delay = 200 //How long after we've been shot before we can start recharging. 20 seconds here - var/recharge_cooldown = 0 //Time since we've last been shot - var/recharge_rate = 1 //How quickly the shield recharges once it starts charging + var/num_charges = 3 //How many charges total the shielding has + var/recharge_delay = 20 SECONDS //How long after we've been shot before we can start recharging. 20 seconds here var/shield_state = "shield-old" - var/shield_on = "shield-old" /obj/item/clothing/suit/space/hardsuit/shielded/Initialize(mapload) . = ..() if(!allowed) allowed = GLOB.advanced_hardsuit_allowed - -/obj/item/clothing/suit/space/hardsuit/shielded/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) - recharge_cooldown = world.time + recharge_delay - if(current_charges > 0) - var/datum/effect_system/spark_spread/s = new - s.set_up(2, 1, src) - s.start() - owner.visible_message(span_danger("[owner]'s shields deflect [attack_text] in a shower of sparks!")) - current_charges-- - if(recharge_rate) - START_PROCESSING(SSobj, src) - if(current_charges <= 0) - owner.visible_message("[owner]'s shield overloads!") - shield_state = "broken" - owner.update_inv_wear_suit() - return 1 - return 0 - - -/obj/item/clothing/suit/space/hardsuit/shielded/Destroy() - STOP_PROCESSING(SSobj, src) - return ..() - -/obj/item/clothing/suit/space/hardsuit/shielded/process() - if(world.time > recharge_cooldown && current_charges < max_charges) - current_charges = clamp((current_charges + recharge_rate), 0, max_charges) - playsound(loc, 'sound/magic/charge.ogg', 50, 1) - if(current_charges == max_charges) - playsound(loc, 'sound/machines/ding.ogg', 50, 1) - STOP_PROCESSING(SSobj, src) - shield_state = "[shield_on]" - if(ishuman(loc)) - var/mob/living/carbon/human/C = loc - C.update_inv_wear_suit() - -/obj/item/clothing/suit/space/hardsuit/shielded/worn_overlays(mutable_appearance/standing, isinhands = FALSE, icon_file) - . = ..() - if(!isinhands) - . += mutable_appearance('icons/effects/effects.dmi', shield_state, MOB_LAYER + 0.01) + AddComponent(/datum/component/shielded, 'icons/effects/effects.dmi', shield_state, num_charges, recharge_delay, ITEM_SLOT_OCLOTHING, TRUE) /obj/item/clothing/head/helmet/space/hardsuit/shielded resistance_flags = FIRE_PROOF | ACID_PROOF @@ -1028,7 +986,7 @@ helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf armor = list(MELEE = 0, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 50, BIO = 100, RAD = 100, FIRE = 95, ACID = 95, ELECTRIC = 100) slowdown = 0 - max_charges = 5 + num_charges = 5 /obj/item/clothing/suit/space/hardsuit/shielded/ctf/red name = "red team armor" @@ -1037,7 +995,6 @@ hardsuit_type = "ert_security" helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/red shield_state = "shield-red" - shield_on = "shield-red" /obj/item/clothing/suit/space/hardsuit/shielded/ctf/blue name = "blue team armor" @@ -1131,8 +1088,7 @@ icon_state = "deathsquad" item_state = "swat_suit" hardsuit_type = "syndi" - max_charges = 4 - current_charges = 4 + num_charges = 4 recharge_delay = 15 armor = list(MELEE = 80, BULLET = 80, LASER = 50, ENERGY = 50, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, ELECTRIC = 100) strip_delay = 130 diff --git a/yogstation/code/datums/components/shielded.dm b/yogstation/code/datums/components/shielded.dm index b35e4b5585f7..b0f09bda6954 100644 --- a/yogstation/code/datums/components/shielded.dm +++ b/yogstation/code/datums/components/shielded.dm @@ -1,89 +1,116 @@ /datum/component/shielded + + ///file to get the shield icon from var/shield_icon + ///specific icon used for the shield var/shield_icon_state + + + ///current number of shield charges + var/current_shield_charges + ///maximum number of charges the shield can have + var/max_shield_charges + ///How long it takes for a shield charge to recharge var/shield_recharge + ///Cooldown after getting hit for the shield to recharge + COOLDOWN_DECLARE(recharge_cooldown) + + ///clothing slot the item is stored in var/target_slot - var/cached_mutable_appearance + ///the visual overlay of the shield + var/mutable_appearance/cached_mutable_appearance + + ///whether or not the shield visual is emissive + var/emissive = FALSE + + ///the emissive visual overlay of the shield + var/mutable_appearance/cached_emissive_appearance - var/is_shielded = FALSE - var/is_charged = TRUE + ///Boolean whether or not the shield is currently worn the user + var/shield_active = TRUE var/mob/living/current_owner -/datum/component/shielded/Initialize(shielded_icon, shielded_icon_state, shielded_recharge, slot) +/datum/component/shielded/Initialize(shielded_icon, shielded_icon_state, max_shield, shielded_recharge, slot, emissive_shield = FALSE) if(!shielded_icon) CRASH("Invalid shield icon passed") if(!shielded_icon_state) CRASH("Invalid shield icon state passed") + if(!isnum(max_shield)) + CRASH("Invalid max shield charges passed, expected number, found [max_shield]") if(!isnum(shielded_recharge)) CRASH("Invalid shield recharge passed, expected number, found [shielded_recharge]") shield_icon = shielded_icon shield_icon_state = shielded_icon_state + max_shield_charges = max_shield + current_shield_charges = max_shield_charges shield_recharge = shielded_recharge target_slot = slot + emissive = emissive_shield cached_mutable_appearance = mutable_appearance(shield_icon, shield_icon_state) + cached_emissive_appearance = emissive_appearance(shield_icon, shield_icon_state, parent) - RegisterSignal(parent,COMSIG_ITEM_HIT_REACT,PROC_REF(on_hit_react)) - RegisterSignal(parent,COMSIG_ITEM_EQUIPPED, PROC_REF(on_equipped)) - RegisterSignal(parent,COMSIG_ITEM_DROPPED, PROC_REF(on_dropped)) - -/datum/component/shielded/proc/apply_shield() - if(is_shielded) - return - - is_shielded = TRUE - - if(!current_owner) - return - - if(is_charged) - current_owner.add_overlay(cached_mutable_appearance) + RegisterSignal(parent, COMSIG_ITEM_HIT_REACT, PROC_REF(on_hit_react)) + RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(on_equipped)) + RegisterSignal(parent, COMSIG_ITEM_DROPPED, PROC_REF(on_dropped)) -/datum/component/shielded/proc/remove_shield() - if(!is_shielded) - return +/datum/component/shielded/Destroy(force, silent) + STOP_PROCESSING(SSobj, src) + return ..() - is_shielded = FALSE +/datum/component/shielded/proc/on_hit_react(datum/source, mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) + if(drain_charge()) + var/datum/effect_system/spark_spread/s = new + s.set_up(2, 1, current_owner) + s.start() + current_owner.visible_message(span_danger("[current_owner]'s shields deflect [attack_text] in a shower of sparks!")) + return COMPONENT_HIT_REACTION_BLOCK - if(!current_owner) - return - - if(is_charged) - current_owner.cut_overlay(cached_mutable_appearance) - /datum/component/shielded/proc/drain_charge() - if(!is_charged) - return - is_charged = FALSE - if(!current_owner) - return - current_owner.cut_overlay(cached_mutable_appearance) - addtimer(CALLBACK(src,PROC_REF(recharge)),shield_recharge) - -/datum/component/shielded/proc/recharge() - if(is_charged) - return - is_charged = TRUE + if(!shield_active) + return FALSE if(!current_owner) - return - current_owner.add_overlay(cached_mutable_appearance) + return FALSE + if(current_shield_charges <= 0) + return FALSE + + current_shield_charges -- -/datum/component/shielded/proc/on_hit_react(datum/source, mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) - if(!is_shielded || !is_charged) - return - drain_charge() - return COMPONENT_HIT_REACTION_BLOCK + current_owner.update_appearance(UPDATE_OVERLAYS) + + if(shield_recharge) + COOLDOWN_START(src, recharge_cooldown, shield_recharge) + START_PROCESSING(SSobj, src) + return TRUE + +/datum/component/shielded/process(delta_time) + if(COOLDOWN_FINISHED(src, recharge_cooldown) && current_shield_charges < max_shield_charges) + current_shield_charges = clamp(current_shield_charges + 1, 0, max_shield_charges) + playsound(get_turf(parent), 'sound/magic/charge.ogg', 50, 1) + if(current_shield_charges >= max_shield_charges) + STOP_PROCESSING(SSobj, src) + if(current_owner) + current_owner.update_appearance(UPDATE_OVERLAYS) /datum/component/shielded/proc/on_equipped(datum/source, mob/equipper, slot) current_owner = equipper - if(target_slot && target_slot != slot) - remove_shield() - return - apply_shield() + shield_active = (target_slot == slot) + RegisterSignal(current_owner, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(update_shield_overlay)) + current_owner.update_appearance(UPDATE_OVERLAYS) /datum/component/shielded/proc/on_dropped(datum/source,mob/dropper) - remove_shield() + shield_active = FALSE + UnregisterSignal(current_owner, COMSIG_ATOM_UPDATE_OVERLAYS) + current_owner.update_appearance(UPDATE_OVERLAYS) current_owner = null + +/datum/component/shielded/proc/update_shield_overlay(atom/source, list/overlays) + SIGNAL_HANDLER + + if(shield_active && current_shield_charges >= 1) + overlays += cached_mutable_appearance + if(emissive) + overlays += cached_emissive_appearance diff --git a/yogstation/code/modules/jungleland/jungle_items.dm b/yogstation/code/modules/jungleland/jungle_items.dm index a21d9c8b1da5..579c91ffaeea 100644 --- a/yogstation/code/modules/jungleland/jungle_items.dm +++ b/yogstation/code/modules/jungleland/jungle_items.dm @@ -685,7 +685,7 @@ if(!proximity_flag) return ..() if(istype(target,/obj/item/clothing/suit/space/hardsuit)) - target.AddComponent(/datum/component/shielded,'yogstation/icons/effects/effects.dmi',"tar_shield", 30 SECONDS, ITEM_SLOT_OCLOTHING) + target.AddComponent(/datum/component/shielded,'yogstation/icons/effects/effects.dmi',"tar_shield", 1, 30 SECONDS, ITEM_SLOT_OCLOTHING) visible_message("[user] inserts [src] into [target]") qdel(src) return