From a97599ced190eb7d351abef44d580fbe53c50ae8 Mon Sep 17 00:00:00 2001 From: John Willard <53777086+JohnFulpWillard@users.noreply.github.com> Date: Wed, 13 Mar 2024 20:41:56 -0400 Subject: [PATCH] (upstream PR 81940) --- .../status_effects/_status_effect_helpers.dm | 13 +- code/datums/status_effects/debuffs/debuffs.dm | 8 +- .../orders/order_items/mining/order_pka.dm | 8 + .../mining/equipment/kinetic_crusher.dm | 186 ++++++++++-------- .../hostile/megafauna/hierophant.dm | 1 + .../guns/energy/kinetic_accelerator.dm | 77 +++++--- code/modules/projectiles/projectile.dm | 2 +- 7 files changed, 176 insertions(+), 119 deletions(-) diff --git a/code/datums/status_effects/_status_effect_helpers.dm b/code/datums/status_effects/_status_effect_helpers.dm index 0ee95220061..f887afd9142 100644 --- a/code/datums/status_effects/_status_effect_helpers.dm +++ b/code/datums/status_effects/_status_effect_helpers.dm @@ -56,7 +56,7 @@ . = FALSE for(var/datum/status_effect/existing_effect as anything in status_effects) - if(existing_effect.id == initial(removed_effect.id) && existing_effect.before_remove(arguments)) + if(existing_effect.id == initial(removed_effect.id) && existing_effect.before_remove(arglist(arguments))) qdel(existing_effect) . = TRUE @@ -84,6 +84,17 @@ return null +///Gets every status effect of an ID and returns all of them in a list, rather than the individual 'has_status_effect' +/mob/living/proc/get_all_status_effect_of_id(datum/status_effect/checked_effect) + RETURN_TYPE(/list/datum/status_effect) + + var/list/all_effects_of_type = list() + for(var/datum/status_effect/present_effect as anything in status_effects) + if(present_effect.id == initial(checked_effect.id)) + all_effects_of_type += present_effect + + return all_effects_of_type + /** * Checks if this mob has a status effect that shares the passed effect's ID * and has the passed sources are in its list of sources (ONLY works for grouped efects!) diff --git a/code/datums/status_effects/debuffs/debuffs.dm b/code/datums/status_effects/debuffs/debuffs.dm index 685ca49011a..f03aa98c6cb 100644 --- a/code/datums/status_effects/debuffs/debuffs.dm +++ b/code/datums/status_effects/debuffs/debuffs.dm @@ -343,7 +343,7 @@ /datum/status_effect/crusher_mark id = "crusher_mark" duration = 300 //if you leave for 30 seconds you lose the mark, deal with it - status_type = STATUS_EFFECT_REPLACE + status_type = STATUS_EFFECT_MULTIPLE alert_type = null var/mutable_appearance/marked_underlay var/obj/item/kinetic_crusher/hammer_synced @@ -370,9 +370,9 @@ QDEL_NULL(marked_underlay) return ..() -/datum/status_effect/crusher_mark/be_replaced() - owner.underlays -= marked_underlay //if this is being called, we should have an owner at this point. - ..() +//we will only clear ourselves if the crusher is the one that owns us. +/datum/status_effect/crusher_mark/before_remove(obj/item/kinetic_crusher/attacking_hammer) + return (attacking_hammer == hammer_synced) /datum/status_effect/stacking/saw_bleed id = "saw_bleed" diff --git a/code/game/machinery/computer/orders/order_items/mining/order_pka.dm b/code/game/machinery/computer/orders/order_items/mining/order_pka.dm index 7ba37721e36..107c4954d3a 100644 --- a/code/game/machinery/computer/orders/order_items/mining/order_pka.dm +++ b/code/game/machinery/computer/orders/order_items/mining/order_pka.dm @@ -39,4 +39,12 @@ /datum/orderable_item/accelerator/minebot_passthrough item_path = /obj/item/borg/upgrade/modkit/minebot_passthrough +<<<<<<< HEAD cost_per_order = 1000 +======= + cost_per_order = 800 + +/datum/orderable_item/accelerator/friendly_fire + item_path = /obj/item/borg/upgrade/modkit/human_passthrough + cost_per_order = 750 +>>>>>>> 405d369694e (Crushers and PKAs: Coop Upgrades (#81940)) diff --git a/code/modules/mining/equipment/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher.dm index 6a6df5452bd..92ded187109 100644 --- a/code/modules/mining/equipment/kinetic_crusher.dm +++ b/code/modules/mining/equipment/kinetic_crusher.dm @@ -1,4 +1,10 @@ -/*********************Mining Hammer****************/ +/** + * Kinetic Crusher + * + * Lavaland's "Hard Mode" option for players, requiring melee attacks (backstabs even better), + * but allowing you to upgrade it with trophies gained from fighting lavaland monsters, making it + * a good tradeoff and a decent playstyle. + */ /obj/item/kinetic_crusher icon = 'icons/obj/mining.dmi' icon_state = "crusher" @@ -6,8 +12,9 @@ lefthand_file = 'icons/mob/inhands/weapons/hammers_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/hammers_righthand.dmi' name = "proto-kinetic crusher" - desc = "An early design of the proto-kinetic accelerator, it is little more than a combination of various mining tools cobbled together, forming a high-tech club. \ - While it is an effective mining tool, it did little to aid any but the most skilled and/or suicidal miners against local fauna." + desc = "An early design of the proto-kinetic accelerator, it is little more than a combination of various mining tools cobbled together, \ + forming a high-tech club. While it is an effective mining tool, it did little to aid any but the most skilled and/or \ + suicidal miners against local fauna." force = 0 //You can't hit stuff unless wielded w_class = WEIGHT_CLASS_BULKY slot_flags = ITEM_SLOT_BACK @@ -26,9 +33,10 @@ light_power = 1.2 light_color = "#ffff66" light_on = FALSE - var/list/trophies = list() + ///List of all crusher trophies attached to this. + var/list/obj/item/crusher_trophy/trophies = list() var/charged = TRUE - var/charge_time = 15 + var/charge_time = 1.5 SECONDS var/detonation_damage = 50 var/backstab_bonus = 30 @@ -54,75 +62,81 @@ . = ..() . += span_notice("Mark a large creature with a destabilizing force with right-click, then hit them in melee to do [force + detonation_damage] damage.") . += span_notice("Does [force + detonation_damage + backstab_bonus] damage if the target is backstabbed, instead of [force + detonation_damage].") - for(var/t in trophies) - var/obj/item/crusher_trophy/T = t - . += span_notice("It has \a [T] attached, which causes [T.effect_desc()].") - -/obj/item/kinetic_crusher/attackby(obj/item/I, mob/living/user) - if(I.tool_behaviour == TOOL_CROWBAR) - if(LAZYLEN(trophies)) - to_chat(user, span_notice("You remove [src]'s trophies.")) - I.play_tool_sound(src) - for(var/t in trophies) - var/obj/item/crusher_trophy/T = t - T.remove_from(src, user) - else - to_chat(user, span_warning("There are no trophies on [src].")) - else if(istype(I, /obj/item/crusher_trophy)) - var/obj/item/crusher_trophy/T = I - T.add_to(src, user) - else - return ..() + for(var/obj/item/crusher_trophy/crusher_trophy as anything in trophies) + . += span_notice("It has \a [crusher_trophy] attached, which causes [crusher_trophy.effect_desc()].") + +/obj/item/kinetic_crusher/attackby(obj/item/attacking_item, mob/user, params) + if(istype(attacking_item, /obj/item/crusher_trophy)) + var/obj/item/crusher_trophy/crusher_trophy = attacking_item + crusher_trophy.add_to(src, user) + return + return ..() + +/obj/item/kinetic_crusher/crowbar_act(mob/living/user, obj/item/tool) + . = ..() + if(!LAZYLEN(trophies)) + user.balloon_alert(user, "no trophies!") + return ITEM_INTERACT_BLOCKING + user.balloon_alert(user, "trophies removed") + tool.play_tool_sound(src) + for(var/obj/item/crusher_trophy/crusher_trophy as anything in trophies) + crusher_trophy.remove_from(src, user) + return ITEM_INTERACT_SUCCESS /obj/item/kinetic_crusher/attack(mob/living/target, mob/living/carbon/user) if(!HAS_TRAIT(src, TRAIT_WIELDED)) to_chat(user, span_warning("[src] is too heavy to use with one hand! You fumble and drop everything.")) user.drop_all_held_items() return - var/datum/status_effect/crusher_damage/C = target.has_status_effect(/datum/status_effect/crusher_damage) - if(!C) - C = target.apply_status_effect(/datum/status_effect/crusher_damage) + var/datum/status_effect/crusher_damage/crusher_damage_effect = target.has_status_effect(/datum/status_effect/crusher_damage) + if(!crusher_damage_effect) + crusher_damage_effect = target.apply_status_effect(/datum/status_effect/crusher_damage) var/target_health = target.health ..() - for(var/t in trophies) + for(var/obj/item/crusher_trophy/crusher_trophy as anything in trophies) if(!QDELETED(target)) - var/obj/item/crusher_trophy/T = t - T.on_melee_hit(target, user) - if(!QDELETED(C) && !QDELETED(target)) - C.total_damage += target_health - target.health //we did some damage, but let's not assume how much we did - -/obj/item/kinetic_crusher/afterattack(atom/target, mob/living/user, proximity_flag, clickparams) - if(proximity_flag && isliving(target)) - var/mob/living/L = target - var/datum/status_effect/crusher_mark/CM = L.has_status_effect(/datum/status_effect/crusher_mark) - if(!CM || CM.hammer_synced != src || !L.remove_status_effect(/datum/status_effect/crusher_mark)) - return - var/datum/status_effect/crusher_damage/C = L.has_status_effect(/datum/status_effect/crusher_damage) - if(!C) - C = L.apply_status_effect(/datum/status_effect/crusher_damage) - var/target_health = L.health - for(var/t in trophies) - var/obj/item/crusher_trophy/T = t - T.on_mark_detonation(target, user) - if(!QDELETED(L)) - if(!QDELETED(C)) - C.total_damage += target_health - L.health //we did some damage, but let's not assume how much we did - new /obj/effect/temp_visual/kinetic_blast(get_turf(L)) - var/backstabbed = FALSE - var/combined_damage = detonation_damage - var/backstab_dir = get_dir(user, L) - var/def_check = L.getarmor(type = BOMB) - if((user.dir & backstab_dir) && (L.dir & backstab_dir)) - backstabbed = TRUE - combined_damage += backstab_bonus - playsound(user, 'sound/weapons/kinetic_accel.ogg', 100, TRUE) //Seriously who spelled it wrong - - if(!QDELETED(C)) - C.total_damage += combined_damage - - - SEND_SIGNAL(user, COMSIG_LIVING_CRUSHER_DETONATE, L, src, backstabbed) - L.apply_damage(combined_damage, BRUTE, blocked = def_check) + crusher_trophy.on_melee_hit(target, user) + if(!QDELETED(crusher_damage_effect) && !QDELETED(target)) + crusher_damage_effect.total_damage += target_health - target.health //we did some damage, but let's not assume how much we did + +/obj/item/kinetic_crusher/afterattack(mob/living/target, mob/living/user, proximity_flag, clickparams) + . = ..() + if(.) + return + if(!proximity_flag || !isliving(target)) + return + var/valid_crusher_attack = FALSE + for(var/datum/status_effect/crusher_mark/crusher_mark_effect as anything in target.get_all_status_effect_of_id(/datum/status_effect/crusher_mark)) + //this will erase ALL crusher marks, not only ones by you. + if(crusher_mark_effect.hammer_synced != src || !target.remove_status_effect(/datum/status_effect/crusher_mark, src)) + continue + valid_crusher_attack = TRUE + break + if(!valid_crusher_attack) + return + var/datum/status_effect/crusher_damage/crusher_damage_effect = target.has_status_effect(/datum/status_effect/crusher_damage) + if(!crusher_damage_effect) + crusher_damage_effect = target.apply_status_effect(/datum/status_effect/crusher_damage) + var/target_health = target.health + for(var/obj/item/crusher_trophy/crusher_trophy as anything in trophies) + crusher_trophy.on_mark_detonation(target, user) + if(QDELETED(target)) + return + if(!QDELETED(crusher_damage_effect)) + crusher_damage_effect.total_damage += target_health - target.health //we did some damage, but let's not assume how much we did + new /obj/effect/temp_visual/kinetic_blast(get_turf(target)) + var/backstabbed = FALSE + var/combined_damage = detonation_damage + var/backstab_dir = get_dir(user, target) + var/def_check = target.getarmor(type = BOMB) + if((user.dir & backstab_dir) && (target.dir & backstab_dir)) + backstabbed = TRUE + combined_damage += backstab_bonus + playsound(user, 'sound/weapons/kinetic_accel.ogg', 100, TRUE) //Seriously who spelled it wrong + if(!QDELETED(crusher_damage_effect)) + crusher_damage_effect.total_damage += combined_damage + SEND_SIGNAL(user, COMSIG_LIVING_CRUSHER_DETONATE, target, src, backstabbed) + target.apply_damage(combined_damage, BRUTE, blocked = def_check) /obj/item/kinetic_crusher/attack_secondary(atom/target, mob/living/user, clickparams) return SECONDARY_ATTACK_CONTINUE_CHAIN @@ -155,9 +169,9 @@ destabilizer.fire() charged = FALSE update_appearance() - addtimer(CALLBACK(src, PROC_REF(Recharge)), charge_time) + addtimer(CALLBACK(src, PROC_REF(recharge_projectile)), charge_time) -/obj/item/kinetic_crusher/proc/Recharge() +/obj/item/kinetic_crusher/proc/recharge_projectile() if(!charged) charged = TRUE update_appearance() @@ -197,6 +211,7 @@ armor_flag = BOMB range = 6 log_override = TRUE + ///The crusher that's firing this projectile. var/obj/item/kinetic_crusher/hammer_synced /obj/projectile/destabilizer/Destroy() @@ -205,19 +220,21 @@ /obj/projectile/destabilizer/on_hit(atom/target, blocked = 0, pierce_hit) if(isliving(target)) - var/mob/living/L = target - var/had_effect = (L.has_status_effect(/datum/status_effect/crusher_mark)) //used as a boolean - var/datum/status_effect/crusher_mark/CM = L.apply_status_effect(/datum/status_effect/crusher_mark, hammer_synced) - if(hammer_synced) - for(var/t in hammer_synced.trophies) - var/obj/item/crusher_trophy/T = t - T.on_mark_application(target, CM, had_effect) + var/mob/living/living_target = target + var/has_mark_from_this_crusher = FALSE + for(var/datum/status_effect/crusher_mark/crusher_mark_effect as anything in living_target.get_all_status_effect_of_id(/datum/status_effect/crusher_mark)) + if(crusher_mark_effect.hammer_synced != hammer_synced) + continue + has_mark_from_this_crusher = TRUE + break + if(!has_mark_from_this_crusher) + living_target.apply_status_effect(/datum/status_effect/crusher_mark, hammer_synced) var/target_turf = get_turf(target) if(ismineralturf(target_turf)) - var/turf/closed/mineral/M = target_turf - new /obj/effect/temp_visual/kinetic_blast(M) - M.gets_drilled(firer) - ..() + var/turf/closed/mineral/hit_mineral = target_turf + new /obj/effect/temp_visual/kinetic_blast(hit_mineral) + hit_mineral.gets_drilled(firer) + return ..() //trophies /obj/item/crusher_trophy @@ -258,7 +275,6 @@ /obj/item/crusher_trophy/proc/on_melee_hit(mob/living/target, mob/living/user) //the target and the user /obj/item/crusher_trophy/proc/on_projectile_fire(obj/projectile/destabilizer/marker, mob/living/user) //the projectile fired and the user -/obj/item/crusher_trophy/proc/on_mark_application(mob/living/target, datum/status_effect/crusher_mark/mark, had_mark) //the target, the mark applied, and if the target had a mark before /obj/item/crusher_trophy/proc/on_mark_detonation(mob/living/target, mob/living/user) //the target and the user //watcher @@ -350,13 +366,13 @@ return "mark detonation to do [bonus_value] damage to nearby creatures and push them back" /obj/item/crusher_trophy/tail_spike/on_mark_detonation(mob/living/target, mob/living/user) - for(var/mob/living/L in oview(2, user)) - if(L.stat == DEAD) + for(var/mob/living/living_target in oview(2, user)) + if(user.faction_check_atom(living_target) || living_target.stat == DEAD) continue - playsound(L, 'sound/magic/fireball.ogg', 20, TRUE) - new /obj/effect/temp_visual/fire(L.loc) - addtimer(CALLBACK(src, PROC_REF(pushback), L, user), 1) //no free backstabs, we push AFTER module stuff is done - L.adjustFireLoss(bonus_value, forced = TRUE) + playsound(living_target, 'sound/magic/fireball.ogg', 20, TRUE) + new /obj/effect/temp_visual/fire(living_target.loc) + addtimer(CALLBACK(src, PROC_REF(pushback), living_target, user), 1) //no free backstabs, we push AFTER module stuff is done + living_target.adjustFireLoss(bonus_value, forced = TRUE) /obj/item/crusher_trophy/tail_spike/proc/pushback(mob/living/target, mob/living/user) if(!QDELETED(target) && !QDELETED(user) && (!target.anchored || ismegafauna(target))) //megafauna will always be pushed diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm index 375d4993cfd..d7fceecf053 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm @@ -618,6 +618,7 @@ Difficulty: Hard moving-- sleep(speed) targetturf = get_turf(target) + /obj/effect/temp_visual/hierophant/chaser/proc/make_blast() var/obj/effect/temp_visual/hierophant/blast/damaging/B = new(loc, caster, friendly_fire_check) B.damage = damage diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm index 71d28e70a5e..ba6b5d89223 100644 --- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm +++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm @@ -11,11 +11,13 @@ can_bayonet = TRUE knife_x_offset = 20 knife_y_offset = 12 - var/mob/holder - var/max_mod_capacity = 100 - var/list/modkits = list() gun_flags = NOT_A_REAL_GUN - + ///List of all mobs that projectiles fired from this gun will ignore. + var/list/ignored_mob_types + ///List of all modkits currently in the kinetic accelerator. + var/list/obj/item/borg/upgrade/modkit/modkits = list() + ///The max capacity of modkits the PKA can have installed at once. + var/max_mod_capacity = 100 /obj/item/gun/energy/recharge/kinetic_accelerator/Initialize(mapload) . = ..() @@ -68,18 +70,16 @@ if(max_mod_capacity) . += "[get_remaining_mod_capacity()]% mod capacity remaining." . += span_info("You can use a crowbar to remove all modules or right-click with an empty hand to remove a specific one.") - for(var/A in modkits) - var/obj/item/borg/upgrade/modkit/M = A - . += span_notice("There is \a [M] installed, using [M.cost]% capacity.") + for(var/obj/item/borg/upgrade/modkit/modkit_upgrade as anything in modkits) + . += span_notice("There is \a [modkit_upgrade] installed, using [modkit_upgrade.cost]% capacity.") /obj/item/gun/energy/recharge/kinetic_accelerator/crowbar_act(mob/living/user, obj/item/I) . = TRUE if(modkits.len) to_chat(user, span_notice("You pry all the modifications out.")) I.play_tool_sound(src, 100) - for(var/a in modkits) - var/obj/item/borg/upgrade/modkit/M = a - M.forceMove(drop_location()) //uninstallation handled in Exited(), or /mob/living/silicon/robot/remove_from_upgrades() for borgs + for(var/obj/item/borg/upgrade/modkit/modkit_upgrade as anything in modkits) + modkit_upgrade.forceMove(drop_location()) //uninstallation handled in Exited(), or /mob/living/silicon/robot/remove_from_upgrades() for borgs else to_chat(user, span_notice("There are no modifications currently installed.")) @@ -138,16 +138,14 @@ /obj/item/gun/energy/recharge/kinetic_accelerator/proc/get_remaining_mod_capacity() var/current_capacity_used = 0 - for(var/A in modkits) - var/obj/item/borg/upgrade/modkit/M = A - current_capacity_used += M.cost + for(var/obj/item/borg/upgrade/modkit/modkit_upgrade as anything in modkits) + current_capacity_used += modkit_upgrade.cost return max_mod_capacity - current_capacity_used -/obj/item/gun/energy/recharge/kinetic_accelerator/proc/modify_projectile(obj/projectile/kinetic/K) - K.kinetic_gun = src //do something special on-hit, easy! - for(var/A in modkits) - var/obj/item/borg/upgrade/modkit/M = A - M.modify_projectile(K) +/obj/item/gun/energy/recharge/kinetic_accelerator/proc/modify_projectile(obj/projectile/kinetic/kinetic_projectile) + kinetic_projectile.kinetic_gun = src //do something special on-hit, easy! + for(var/obj/item/borg/upgrade/modkit/modkit_upgrade as anything in modkits) + modkit_upgrade.modify_projectile(kinetic_projectile) /obj/item/gun/energy/recharge/kinetic_accelerator/cyborg icon_state = "kineticgun_b" @@ -193,13 +191,14 @@ return ..() /obj/projectile/kinetic/prehit_pierce(atom/target) + if(is_type_in_typecache(target, kinetic_gun.ignored_mob_types)) + return PROJECTILE_PIERCE_PHASE . = ..() if(. == PROJECTILE_PIERCE_PHASE) return if(kinetic_gun) - var/list/mods = kinetic_gun.modkits - for(var/obj/item/borg/upgrade/modkit/modkit in mods) - modkit.projectile_prehit(src, target, kinetic_gun) + for(var/obj/item/borg/upgrade/modkit/modkit_upgrade as anything in kinetic_gun.modkits) + modkit_upgrade.projectile_prehit(src, target, kinetic_gun) if(!pressure_decrease_active && !lavaland_equipment_pressure_check(get_turf(target))) name = "weakened [name]" damage = damage * pressure_decrease @@ -219,10 +218,10 @@ target_turf = get_turf(src) if(kinetic_gun) //hopefully whoever shot this was not very, very unfortunate. var/list/mods = kinetic_gun.modkits - for(var/obj/item/borg/upgrade/modkit/M in mods) - M.projectile_strike_predamage(src, target_turf, target, kinetic_gun) - for(var/obj/item/borg/upgrade/modkit/M in mods) - M.projectile_strike(src, target_turf, target, kinetic_gun) + for(var/obj/item/borg/upgrade/modkit/modkit_upgrade as anything in mods) + modkit_upgrade.projectile_strike_predamage(src, target_turf, target, kinetic_gun) + for(var/obj/item/borg/upgrade/modkit/modkit_upgrade as anything in mods) + modkit_upgrade.projectile_strike(src, target_turf, target, kinetic_gun) if(ismineralturf(target_turf)) var/turf/closed/mineral/M = target_turf M.gets_drilled(firer, TRUE) @@ -284,9 +283,8 @@ return FALSE if(denied_type) var/number_of_denied = 0 - for(var/A in KA.modkits) - var/obj/item/borg/upgrade/modkit/M = A - if(istype(M, denied_type)) + for(var/obj/item/borg/upgrade/modkit/modkit_upgrade as anything in KA.modkits) + if(istype(modkit_upgrade, denied_type)) number_of_denied++ if(number_of_denied >= maximum_of_type) . = FALSE @@ -434,8 +432,31 @@ /obj/item/borg/upgrade/modkit/minebot_passthrough name = "minebot passthrough" desc = "Causes kinetic accelerator shots to pass through minebots." + denied_type = /obj/item/borg/upgrade/modkit/human_passthrough + cost = 0 + +/obj/item/borg/upgrade/modkit/minebot_passthrough/install(obj/item/gun/energy/recharge/kinetic_accelerator/KA, mob/user, transfer_to_loc) + . = ..() + LAZYADD(KA.ignored_mob_types, typecacheof(/mob/living/basic/mining_drone)) + +/obj/item/borg/upgrade/modkit/minebot_passthrough/uninstall(obj/item/gun/energy/recharge/kinetic_accelerator/KA) + . = ..() + LAZYREMOVE(KA.ignored_mob_types, typecacheof(/mob/living/basic/mining_drone)) + +/obj/item/borg/upgrade/modkit/human_passthrough + name = "human passthrough" + desc = "Causes kinetic accelerator shots to pass through humans, good for preventing friendly fire." + denied_type = /obj/item/borg/upgrade/modkit/minebot_passthrough cost = 0 +/obj/item/borg/upgrade/modkit/human_passthrough/install(obj/item/gun/energy/recharge/kinetic_accelerator/KA, mob/user, transfer_to_loc) + . = ..() + LAZYADD(KA.ignored_mob_types, typecacheof(/mob/living/carbon/human)) + +/obj/item/borg/upgrade/modkit/human_passthrough/uninstall(obj/item/gun/energy/recharge/kinetic_accelerator/KA) + . = ..() + LAZYREMOVE(KA.ignored_mob_types, typecacheof(/mob/living/carbon/human)) + //Tendril-unique modules /obj/item/borg/upgrade/modkit/cooldown/repeater name = "rapid repeater" diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index d1dd5364477..60adbfed24d 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -707,7 +707,7 @@ if(ismovable(A)) var/atom/movable/AM = A if(AM.throwing) - return (projectile_phasing & LETPASSTHROW)? PROJECTILE_PIERCE_PHASE : ((projectile_piercing & LETPASSTHROW)? PROJECTILE_PIERCE_HIT : PROJECTILE_PIERCE_NONE) + return (projectile_phasing & LETPASSTHROW) ? PROJECTILE_PIERCE_PHASE : ((projectile_piercing & LETPASSTHROW)? PROJECTILE_PIERCE_HIT : PROJECTILE_PIERCE_NONE) return PROJECTILE_PIERCE_NONE /obj/projectile/proc/check_ricochet(atom/A)