diff --git a/code/datums/actions/mobs/charge.dm b/code/datums/actions/mobs/charge.dm index 4dc016a66e6..dd80650065e 100644 --- a/code/datums/actions/mobs/charge.dm +++ b/code/datums/actions/mobs/charge.dm @@ -212,18 +212,21 @@ if(!isliving(target)) source.visible_message(span_danger("[source] smashes into [target]!")) - living_source?.Stun(recoil_duration, ignore_canstun = TRUE) + if (recoil_duration >= 0) // Because 0 stun/knockdown is still a valid value + living_source?.Stun(recoil_duration, ignore_canstun = TRUE) return var/mob/living/living_target = target if(ishuman(living_target)) var/mob/living/carbon/human/human_target = living_target if(human_target.check_block(source, 0, "\the [source]", attack_type = LEAP_ATTACK) && living_source) - living_source.Stun(recoil_duration, ignore_canstun = TRUE) + if (recoil_duration >= 0) + living_source.Stun(recoil_duration, ignore_canstun = TRUE) return living_target.visible_message(span_danger("[source] charges into [living_target]!"), span_userdanger("[source] charges into you!")) - living_target.Knockdown(knockdown_duration) + if (knockdown_duration >= 0) + living_target.Knockdown(knockdown_duration) /datum/status_effect/tired_post_charge id = "tired_post_charge" diff --git a/code/datums/actions/mobs/dash.dm b/code/datums/actions/mobs/dash.dm index ad87ab93f9a..36db85531c1 100644 --- a/code/datums/actions/mobs/dash.dm +++ b/code/datums/actions/mobs/dash.dm @@ -6,8 +6,6 @@ cooldown_time = 1.5 SECONDS /// The range of the dash var/dash_range = 4 - /// The distance you will be from the target after you dash - var/pick_range = 5 /datum/action/cooldown/mob_cooldown/dash/Activate(atom/target_atom) disable_cooldown_actions() diff --git a/code/datums/actions/mobs/projectileattack.dm b/code/datums/actions/mobs/projectileattack.dm index 183df71e03f..bdbea403e2f 100644 --- a/code/datums/actions/mobs/projectileattack.dm +++ b/code/datums/actions/mobs/projectileattack.dm @@ -78,7 +78,7 @@ /datum/action/cooldown/mob_cooldown/projectile_attack/rapid_fire/attack_sequence(mob/living/firer, atom/target) for(var/i in 1 to shot_count) shoot_projectile(firer, target, null, firer, rand(-default_projectile_spread, default_projectile_spread), null) - SLEEP_CHECK_DEATH(shot_delay, src) + SLEEP_CHECK_DEATH(shot_delay, firer) /datum/action/cooldown/mob_cooldown/projectile_attack/rapid_fire/direct shot_count = 40 diff --git a/code/datums/actions/mobs/sequences/dash_attack.dm b/code/datums/actions/mobs/sequences/dash_attack.dm index b5fff4cb492..42486f8d9f3 100644 --- a/code/datums/actions/mobs/sequences/dash_attack.dm +++ b/code/datums/actions/mobs/sequences/dash_attack.dm @@ -6,6 +6,12 @@ cooldown_time = 3 SECONDS shared_cooldown = MOB_SHARED_COOLDOWN_2 sequence_actions = list( - /datum/action/cooldown/mob_cooldown/dash = 0.1 SECONDS, - /datum/action/cooldown/mob_cooldown/projectile_attack/kinetic_accelerator = 0, + /datum/action/cooldown/mob_cooldown/charge/basic_charge/blood_drunk_miner = 0.22 SECONDS, // 0.1s windup + 0.12s max dash + /datum/action/cooldown/mob_cooldown/projectile_attack/rapid_fire/kinetic_accelerator = 0, + ) + +/datum/action/cooldown/mob_cooldown/dash_attack/long_burst + sequence_actions = list( + /datum/action/cooldown/mob_cooldown/charge/basic_charge/blood_drunk_miner = 0.22 SECONDS, + /datum/action/cooldown/mob_cooldown/projectile_attack/rapid_fire/kinetic_accelerator/long_burst = 0, ) diff --git a/code/datums/actions/mobs/transform_weapon.dm b/code/datums/actions/mobs/transform_weapon.dm deleted file mode 100644 index 6cb97e0c635..00000000000 --- a/code/datums/actions/mobs/transform_weapon.dm +++ /dev/null @@ -1,26 +0,0 @@ -/datum/action/cooldown/mob_cooldown/transform_weapon - name = "Transform Weapon" - button_icon = 'icons/obj/mining_zones/artefacts.dmi' - button_icon_state = "cleaving_saw" - desc = "Transform weapon into a different state." - cooldown_time = 5 SECONDS - shared_cooldown = MOB_SHARED_COOLDOWN_2 - /// The max possible cooldown, cooldown is random between the default cooldown time and this - var/max_cooldown_time = 10 SECONDS - -/datum/action/cooldown/mob_cooldown/transform_weapon/Activate(atom/target_atom) - disable_cooldown_actions() - do_transform() - StartCooldown(rand(cooldown_time, max_cooldown_time), 0) - enable_cooldown_actions() - return TRUE - -/datum/action/cooldown/mob_cooldown/transform_weapon/proc/do_transform() - if(!istype(owner, /mob/living/basic/boss/blood_drunk_miner)) - return - var/mob/living/basic/boss/blood_drunk_miner/blood_drunk_miner = owner - blood_drunk_miner.miner_saw.attack_self(owner) - var/saw_open = HAS_TRAIT(blood_drunk_miner.miner_saw, TRAIT_TRANSFORM_ACTIVE) - blood_drunk_miner.rapid_melee_hits = saw_open ? 3 : 5 - blood_drunk_miner.icon_state = "miner[saw_open ? "_transformed":""]" - blood_drunk_miner.icon_living = "miner[saw_open ? "_transformed":""]" diff --git a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm index 66f7e2780e5..83981f1bedd 100644 --- a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm +++ b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm @@ -91,18 +91,20 @@ playsound(loc, 'sound/machines/chime.ogg', 50, FALSE, -5) /// Does the MGS ! animation -/atom/proc/do_alert_animation() +/atom/proc/do_alert_animation(duration = 1 SECONDS) var/mutable_appearance/alert = mutable_appearance('icons/obj/storage/closet.dmi', "cardboard_special") SET_PLANE_EXPLICIT(alert, ABOVE_LIGHTING_PLANE, src) - var/atom/movable/flick_visual/exclamation = flick_overlay_view(alert, 1 SECONDS) + var/atom/movable/flick_visual/exclamation = flick_overlay_view(alert, duration) exclamation.alpha = 0 exclamation.pixel_x = -pixel_x - animate(exclamation, pixel_z = 32, alpha = 255, time = 0.5 SECONDS, easing = ELASTIC_EASING) + animate(exclamation, pixel_z = 32, alpha = 255, time = duration * 0.5, easing = ELASTIC_EASING) + animate(time = duration * 0.35) + animate(pixel_z = 64, alpha = 0, time = duration * 0.15, easing = SINE_EASING) // We use this list to update plane values on parent z change, which is why we need the timer too // I'm sorry :( LAZYADD(update_on_z, exclamation) // Intentionally less time then the flick so we don't get weird shit - addtimer(CALLBACK(src, PROC_REF(forget_alert), exclamation), 0.8 SECONDS, TIMER_CLIENT_TIME) + addtimer(CALLBACK(src, PROC_REF(forget_alert), exclamation), max(0.05 SECONDS, duration - 0.1 SECONDS), TIMER_CLIENT_TIME) /atom/proc/forget_alert(atom/movable/flick_visual/exclamation) LAZYREMOVE(update_on_z, exclamation) diff --git a/code/modules/cargo/exports/lavaland.dm b/code/modules/cargo/exports/lavaland.dm index 78f98cb04da..576ca4d8c95 100644 --- a/code/modules/cargo/exports/lavaland.dm +++ b/code/modules/cargo/exports/lavaland.dm @@ -45,6 +45,7 @@ /obj/item/jacobs_ladder, /obj/item/borg/upgrade/modkit/lifesteal, /obj/item/clockwork_alloy, + /obj/item/gun/energy/recharge/kinetic_accelerator/bdm, ) /datum/export/lavaland/major //valuable chest/ruin loot, minor megafauna loot diff --git a/code/modules/mob/living/basic/boss/blood_drunk_miner/_blood_drunk_miner.dm b/code/modules/mob/living/basic/boss/blood_drunk_miner/_blood_drunk_miner.dm index 7462974381e..0e9e734a21d 100644 --- a/code/modules/mob/living/basic/boss/blood_drunk_miner/_blood_drunk_miner.dm +++ b/code/modules/mob/living/basic/boss/blood_drunk_miner/_blood_drunk_miner.dm @@ -12,16 +12,17 @@ Difficulty: Medium /mob/living/basic/boss/blood_drunk_miner name = "blood-drunk miner" desc = "A miner destined to wander forever, engaged in an endless hunt." - health = 900 - maxHealth = 900 + health = 1300 + maxHealth = 1300 icon_state = "miner" icon_living = "miner" + base_icon_state = "miner" icon = 'icons/mob/simple/broadMobs.dmi' health_doll_icon = "miner" mob_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_SPECIAL|MOB_MINING light_color = COLOR_LIGHT_GRAYISH_RED speak_emote = list("roars") - speed = 3 + speed = 2.5 pixel_x = -16 base_pixel_x = -16 basic_mob_flags = DEL_ON_DEATH @@ -43,7 +44,7 @@ Difficulty: Medium victor_memory_type = /datum/memory/megafauna_slayer crusher_loot = list(/obj/item/crusher_trophy/miner_eye, /obj/item/knife/hunting/wildhunter) - regular_loot = list(/obj/item/melee/cleaving_saw, /obj/item/gun/energy/recharge/kinetic_accelerator) + regular_loot = list(/obj/item/melee/cleaving_saw, /obj/item/gun/energy/recharge/kinetic_accelerator/bdm) /// Their little saw var/obj/item/melee/cleaving_saw/miner/miner_saw @@ -87,9 +88,9 @@ Difficulty: Medium /// Returns a list of innate actions for the blood-drunk miner. /mob/living/basic/boss/blood_drunk_miner/proc/get_innate_actions() - var/static/list/innate_abilities = list( - /datum/action/cooldown/mob_cooldown/dash = BB_BDM_DASH_ABILITY, - /datum/action/cooldown/mob_cooldown/projectile_attack/kinetic_accelerator = BB_BDM_KINETIC_ACCELERATOR_ABILITY, + var/list/innate_abilities = list( + /datum/action/cooldown/mob_cooldown/charge/basic_charge/blood_drunk_miner = BB_BDM_DASH_ABILITY, + /datum/action/cooldown/mob_cooldown/projectile_attack/rapid_fire/kinetic_accelerator = BB_BDM_KINETIC_ACCELERATOR_ABILITY, /datum/action/cooldown/mob_cooldown/dash_attack = BB_BDM_DASH_ATTACK_ABILITY, /datum/action/cooldown/mob_cooldown/transform_weapon = BB_BDM_TRANSFORM_WEAPON_ABILITY, ) @@ -101,6 +102,13 @@ Difficulty: Medium INVOKE_ASYNC(ai_controller.blackboard[BB_BDM_TRANSFORM_WEAPON_ABILITY], TYPE_PROC_REF(/datum/action, Trigger), src, NONE) +/mob/living/basic/boss/blood_drunk_miner/proc/transform_saw() + miner_saw.attack_self(src) + var/saw_open = HAS_TRAIT(miner_saw, TRAIT_TRANSFORM_ACTIVE) + rapid_melee_hits = saw_open ? 3 : 5 + icon_state = "[base_icon_state][saw_open ? "_transformed":""]" + icon_living = "[base_icon_state][saw_open ? "_transformed":""]" + /mob/living/basic/boss/blood_drunk_miner/ex_act(severity, target) var/datum/action/cooldown/mob_cooldown/dash_ability = ai_controller.blackboard[BB_BDM_DASH_ABILITY] if(dash_ability.Trigger(target = target)) @@ -145,28 +153,58 @@ Difficulty: Medium /// Namely, we just use the miner saw to rapidly hit the target multiple times /mob/living/basic/boss/blood_drunk_miner/proc/attack_override(mob/living/source, atom/target, proximity, modifiers) SIGNAL_HANDLER - if(!istype(target, /mob/living)) + + if(!isliving(target)) return var/mob/living/victim = target - if(should_devour(target)) - devour(target) + if(should_devour(victim)) + devour(victim) return COMPONENT_HOSTILE_NO_ATTACK + do_chain_attack(victim, modifiers) + return COMPONENT_HOSTILE_NO_ATTACK + +/mob/living/basic/boss/blood_drunk_miner/proc/do_chain_attack(mob/living/victim, modifiers, sequence_hit = 1) + if (!Adjacent(victim)) + post_attack_effects(victim, modifiers) + return + changeNext_move(CLICK_CD_MELEE) victim.visible_message( span_danger("[src] slashes at [victim] with [p_their()] cleaving saw!"), span_userdanger("You are slashed at by [src]'s cleaving saw!"), ) - var/datum/callback/melee_callback = CALLBACK(miner_saw, TYPE_PROC_REF(/obj/item/melee/cleaving_saw/miner, melee_attack_chain), src, victim, modifiers) - var/delay = 0.2 SECONDS - for(var/i in 1 to rapid_melee_hits) - addtimer(melee_callback, (i - 1) * delay) + var/delay = HAS_TRAIT(miner_saw, TRAIT_TRANSFORM_ACTIVE) ? 0.5 SECONDS : 0.3 SECONDS + apply_status_effect(/datum/status_effect/saw_slashes_slowdown, delay) + INVOKE_ASYNC(miner_saw, TYPE_PROC_REF(/obj/item/melee/cleaving_saw/miner, melee_attack_chain), src, victim, modifiers) - post_attack_effects(victim, modifiers) + if (sequence_hit >= rapid_melee_hits) + post_attack_effects(victim, modifiers) + return - return COMPONENT_HOSTILE_NO_ATTACK + addtimer(CALLBACK(src, PROC_REF(do_chain_attack), victim, modifiers, sequence_hit + 1), delay) + +/datum/status_effect/saw_slashes_slowdown + id = "saw_slashes_slowdown" + alert_type = null + status_type = STATUS_EFFECT_REFRESH + +/datum/status_effect/saw_slashes_slowdown/on_creation(mob/living/new_owner, new_duration) + duration = new_duration + return ..() + +/datum/status_effect/saw_slashes_slowdown/refresh(effect, new_duration) + duration = new_duration + +/datum/status_effect/saw_slashes_slowdown/on_apply() + . = ..() + owner.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/saw_slashes_slowdown) + +/datum/status_effect/saw_slashes_slowdown/on_remove() + . = ..() + owner.remove_movespeed_modifier(/datum/movespeed_modifier/status_effect/saw_slashes_slowdown) /// Hook for potential additional behaviors after attacking /mob/living/basic/boss/blood_drunk_miner/proc/post_attack_effects(mob/living/victim, list/modifiers) diff --git a/code/modules/mob/living/basic/boss/blood_drunk_miner/blood_drunk_actions.dm b/code/modules/mob/living/basic/boss/blood_drunk_miner/blood_drunk_actions.dm new file mode 100644 index 00000000000..468d01ce3a9 --- /dev/null +++ b/code/modules/mob/living/basic/boss/blood_drunk_miner/blood_drunk_actions.dm @@ -0,0 +1,82 @@ +/datum/action/cooldown/mob_cooldown/charge/basic_charge/blood_drunk_miner + cooldown_time = 1.5 SECONDS + charge_delay = 0.1 SECONDS + shake_duration = 0.2 SECONDS // A bit longer so he shakes during the dash too + charge_distance = 6 + // Don't stun ourselves or the target + recoil_duration = -1 + knockdown_duration = -1 + destroy_objects = FALSE + charge_damage = 0 + charge_speed = 0.3 + +/datum/action/cooldown/mob_cooldown/charge/basic_charge/blood_drunk_miner/hit_target(atom/movable/source, atom/target, damage_dealt) + . = ..() + if(!isbasicmob(source) || !isliving(target)) + return + var/mob/living/basic/basic_source = source + basic_source.melee_attack(target, ignore_cooldown = TRUE) + +/datum/action/cooldown/mob_cooldown/transform_weapon + name = "Transform Weapon" + button_icon = 'icons/obj/mining_zones/artefacts.dmi' + button_icon_state = "cleaving_saw" + desc = "Transform weapon into a different state." + cooldown_time = 5 SECONDS + shared_cooldown = MOB_SHARED_COOLDOWN_2 + /// The max possible cooldown, cooldown is random between the default cooldown time and this + var/max_cooldown_time = 10 SECONDS + +/datum/action/cooldown/mob_cooldown/transform_weapon/Activate(atom/target_atom) + disable_cooldown_actions() + do_transform() + StartCooldown(rand(cooldown_time, max_cooldown_time), 0) + enable_cooldown_actions() + return TRUE + +/datum/action/cooldown/mob_cooldown/transform_weapon/proc/do_transform() + if(!istype(owner, /mob/living/basic/boss/blood_drunk_miner)) + return + var/mob/living/basic/boss/blood_drunk_miner/blood_drunk_miner = owner + blood_drunk_miner.transform_saw() + +/datum/action/cooldown/mob_cooldown/projectile_attack/rapid_fire/kinetic_accelerator + name = "Fire Kinetic Accelerator" + desc = "Fires a kinetic accelerator projectile at the target." + button_icon = 'icons/obj/weapons/guns/energy.dmi' + button_icon_state = "kineticgun" + cooldown_time = 1.5 SECONDS + projectile_type = /obj/projectile/kinetic/miner + projectile_sound = 'sound/items/weapons/kinetic_accel.ogg' + shot_count = 3 + shot_delay = 0.15 SECONDS + default_projectile_spread = 10 + can_move = FALSE + /// Delay for the alert + var/alert_delay = 0.5 SECONDS + /// Delay before we start shooting during which we cannot move + var/prefire_delay = 0.2 SECONDS + /// Delay before the user can move or act again after firing + var/reload_delay = 0.1 SECONDS + +/datum/action/cooldown/mob_cooldown/projectile_attack/rapid_fire/kinetic_accelerator/Activate(atom/target_atom) + owner.visible_message(span_danger("[owner] fires the proto-kinetic accelerator!")) + owner.face_atom(target_atom) + owner.do_alert_animation(alert_delay + (shot_count - 1) * shot_delay) + disable_cooldown_actions() + if (alert_delay > prefire_delay) // As to delay movement blocking + SLEEP_CHECK_DEATH(alert_delay - prefire_delay, owner) + return ..() + +/datum/action/cooldown/mob_cooldown/projectile_attack/rapid_fire/kinetic_accelerator/attack_sequence(mob/living/firer, atom/target) + SLEEP_CHECK_DEATH(prefire_delay, firer) + . = ..() + sleep(reload_delay) + +/datum/action/cooldown/mob_cooldown/projectile_attack/rapid_fire/kinetic_accelerator/shoot_projectile(atom/origin, atom/target, set_angle, mob/firer, projectile_spread, speed_multiplier, override_projectile_type, override_homing) + . = ..() + new /obj/effect/temp_visual/dir_setting/firing_effect(get_turf(firer), firer.dir) + +/datum/action/cooldown/mob_cooldown/projectile_attack/rapid_fire/kinetic_accelerator/long_burst + shot_count = 5 + shot_delay = 0.1 SECONDS diff --git a/code/modules/mob/living/basic/boss/blood_drunk_miner/blood_drunk_ai.dm b/code/modules/mob/living/basic/boss/blood_drunk_miner/blood_drunk_ai.dm index f41400aa52a..64efdb0b8a9 100644 --- a/code/modules/mob/living/basic/boss/blood_drunk_miner/blood_drunk_ai.dm +++ b/code/modules/mob/living/basic/boss/blood_drunk_miner/blood_drunk_ai.dm @@ -12,7 +12,7 @@ BB_BDM_RANGED_ATTACK_COOLDOWN = 0, ) - movement_delay = 0.3 SECONDS + movement_delay = 0.25 SECONDS ai_movement = /datum/ai_movement/basic_avoidance idle_behavior = /datum/idle_behavior/idle_random_walk planning_subtrees = list( @@ -63,4 +63,4 @@ return TRUE /datum/ai_controller/blood_drunk_miner/doom - movement_delay = 0.8 SECONDS + movement_delay = 0.5 SECONDS diff --git a/code/modules/mob/living/basic/boss/blood_drunk_miner/blood_drunk_objects.dm b/code/modules/mob/living/basic/boss/blood_drunk_miner/blood_drunk_objects.dm index 81b49ea593a..df502855770 100644 --- a/code/modules/mob/living/basic/boss/blood_drunk_miner/blood_drunk_objects.dm +++ b/code/modules/mob/living/basic/boss/blood_drunk_miner/blood_drunk_objects.dm @@ -1,15 +1,10 @@ /// A slightly nerfed saw as the normal one is much too murdery. /obj/item/melee/cleaving_saw/miner - force = 6 - open_force = 10 - -/obj/item/melee/cleaving_saw/miner/attack(mob/living/target, mob/living/carbon/human/user) - target.add_stun_absorption(source = "miner", duration = 1 SECONDS, priority = INFINITY) - return ..() + force = 8 + open_force = 12 /obj/projectile/kinetic/miner - damage = 20 - speed = 1.1 + damage = 18 icon_state = "ka_tracer" range = 4 diff --git a/code/modules/mob/living/basic/boss/blood_drunk_miner/blood_drunk_subtypes.dm b/code/modules/mob/living/basic/boss/blood_drunk_miner/blood_drunk_subtypes.dm index a9e6c4d50b1..414fafe2b49 100644 --- a/code/modules/mob/living/basic/boss/blood_drunk_miner/blood_drunk_subtypes.dm +++ b/code/modules/mob/living/basic/boss/blood_drunk_miner/blood_drunk_subtypes.dm @@ -1,6 +1,6 @@ #define HUNTER_DASH_PROBABILITY 12 -/// heals slightly on melee hits +/// Heals slightly on melee hits /mob/living/basic/boss/blood_drunk_miner/guidance /mob/living/basic/boss/blood_drunk_miner/guidance/attack_override(mob/living/source, atom/target, proximity, modifiers) @@ -19,10 +19,11 @@ if(!isnull(dash_attack)) INVOKE_ASYNC(dash_attack, TYPE_PROC_REF(/datum/action, Trigger), src, NONE, victim) +/// Slow but constantly dashes and has longer barrages /mob/living/basic/boss/blood_drunk_miner/doom name = "hostile-environment miner" desc = "A miner destined to hop across dimensions for all eternity, hunting anomalous creatures." - speed = 8 + speed = 5 ranged_attack_cooldown_duration = 0.8 SECONDS ai_controller = /datum/ai_controller/blood_drunk_miner/doom @@ -32,4 +33,17 @@ if(!isnull(dash_ability)) dash_ability.cooldown_time = 0.8 SECONDS + var/datum/action/cooldown/dash_attack = ai_controller.blackboard[BB_BDM_DASH_ATTACK_ABILITY] + if(!isnull(dash_attack)) + dash_attack.cooldown_time = 4 SECONDS + +/mob/living/basic/boss/blood_drunk_miner/doom/get_innate_actions() + var/list/innate_abilities = list( + /datum/action/cooldown/mob_cooldown/charge/basic_charge/blood_drunk_miner = BB_BDM_DASH_ABILITY, + /datum/action/cooldown/mob_cooldown/projectile_attack/rapid_fire/kinetic_accelerator/long_burst = BB_BDM_KINETIC_ACCELERATOR_ABILITY, + /datum/action/cooldown/mob_cooldown/dash_attack = BB_BDM_DASH_ATTACK_ABILITY, + /datum/action/cooldown/mob_cooldown/transform_weapon = BB_BDM_TRANSFORM_WEAPON_ABILITY, + ) + return innate_abilities + #undef HUNTER_DASH_PROBABILITY diff --git a/code/modules/movespeed/modifiers/status_effects.dm b/code/modules/movespeed/modifiers/status_effects.dm index df114aca407..265362f7b8c 100644 --- a/code/modules/movespeed/modifiers/status_effects.dm +++ b/code/modules/movespeed/modifiers/status_effects.dm @@ -41,6 +41,9 @@ /datum/movespeed_modifier/status_effect/tired_post_charge/lesser multiplicative_slowdown = 2 +/datum/movespeed_modifier/status_effect/saw_slashes_slowdown + multiplicative_slowdown = 0.5 + /// Get slower the more gold is in your system. /datum/movespeed_modifier/status_effect/midas_blight id = MOVESPEED_ID_MIDAS_BLIGHT diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm index 80d9aa26d84..c91985e71ea 100644 --- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm +++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm @@ -80,7 +80,8 @@ to_chat(user, span_notice("You pry all the modifications out.")) I.play_tool_sound(src, 100) 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 + if (modkit_upgrade.removable) + 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.")) @@ -98,7 +99,9 @@ var/list/display_names = list() var/list/items = list() for(var/modkits_length in 1 to length(modkits)) - var/obj/item/thing = modkits[modkits_length] + var/obj/item/borg/upgrade/modkit/thing = modkits[modkits_length] + if (!thing.removable) + continue display_names["[thing.name] ([modkits_length])"] = REF(thing) var/image/item_image = image(icon = thing.icon, icon_state = thing.icon_state) if(length(thing.overlays)) @@ -156,6 +159,16 @@ 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/bdm + name = "infernal proto-kinetic accelerator" + icon_state = "kineticgun_evil" + inhand_icon_state = "kineticgun_evil" + +/obj/item/gun/energy/recharge/kinetic_accelerator/bdm/Initialize(mapload) + . = ..() + var/obj/item/borg/upgrade/modkit/cooldown/repeater/bdm/repeater_mod = new() + repeater_mod.install(src) + /obj/item/gun/energy/recharge/kinetic_accelerator/cyborg icon_state = "kineticgun_b" holds_charge = TRUE @@ -299,6 +312,8 @@ var/modifier = 1 //For use in any mod kit that has numerical modifiers var/minebot_upgrade = TRUE var/minebot_exclusive = FALSE + /// Can it be removed? + var/removable = TRUE /obj/item/borg/upgrade/modkit/examine(mob/user) . = ..() @@ -320,10 +335,12 @@ . = TRUE if(minebot_upgrade) if(minebot_exclusive && !istype(KA.loc, /mob/living/basic/mining_drone)) - to_chat(user, span_notice("The modkit you're trying to install is only rated for minebot use.")) + if (user) + to_chat(user, span_notice("The modkit you're trying to install is only rated for minebot use.")) return FALSE else if(istype(KA.loc, /mob/living/basic/mining_drone)) - to_chat(user, span_notice("The modkit you're trying to install is not rated for minebot use.")) + if (user) + to_chat(user, span_notice("The modkit you're trying to install is not rated for minebot use.")) return FALSE var/type_to_limit = denied_type @@ -337,21 +354,24 @@ if(istype(modkit_upgrade, type_to_limit)) number_of_denied++ if(maximum_of_type && number_of_denied >= maximum_of_type || !maximum_of_type && number_of_denied) //if we denied a type, or we have a maximum to reach, break - . = FALSE - break + if (user) + to_chat(user, span_notice("The modkit you're trying to install would conflict with an already installed modkit. Remove existing modkits first.")) + return FALSE - if(KA.get_remaining_mod_capacity() >= cost) - if(.) - if(transfer_to_loc && !user.transferItemToLoc(src, KA)) - return - to_chat(user, span_notice("You install the modkit.")) - playsound(loc, 'sound/items/tools/screwdriver.ogg', 100, TRUE) - KA.modkits |= src - else - to_chat(user, span_notice("The modkit you're trying to install would conflict with an already installed modkit. Remove existing modkits first.")) - else + if(KA.get_remaining_mod_capacity() < cost) to_chat(user, span_notice("You don't have room([KA.get_remaining_mod_capacity()]% remaining, [cost]% needed) to install this modkit. Use a crowbar or right click with an empty hand to remove existing modkits.")) - . = FALSE + return FALSE + + if(transfer_to_loc) + if (user && !user.transferItemToLoc(src, KA)) + return FALSE + else if (!user) + forceMove(KA) + + if (user) + to_chat(user, span_notice("You install the modkit.")) + playsound(loc, 'sound/items/tools/screwdriver.ogg', 100, TRUE) + KA.modkits |= src /obj/item/borg/upgrade/modkit/deactivate(mob/living/silicon/robot/R, user = usr) . = ..() @@ -554,6 +574,12 @@ KA.cell.use(KA.cell.charge) KA.attempt_reload(KA.recharge_time * 0.25) //If you hit, the cooldown drops to 0.75 seconds. +/obj/item/borg/upgrade/modkit/cooldown/repeater/bdm + name = "infernal repeater" + removable = FALSE + cost = 30 + modifier = -10 + /obj/item/borg/upgrade/modkit/lifesteal name = "lifesteal crystal" desc = "Causes kinetic accelerator shots to slightly heal the firer on striking a living target." diff --git a/icons/mob/inhands/weapons/guns_lefthand.dmi b/icons/mob/inhands/weapons/guns_lefthand.dmi index de606157390..df7edf9077b 100644 Binary files a/icons/mob/inhands/weapons/guns_lefthand.dmi and b/icons/mob/inhands/weapons/guns_lefthand.dmi differ diff --git a/icons/mob/inhands/weapons/guns_righthand.dmi b/icons/mob/inhands/weapons/guns_righthand.dmi index 4e97ea35e56..62518d7646b 100644 Binary files a/icons/mob/inhands/weapons/guns_righthand.dmi and b/icons/mob/inhands/weapons/guns_righthand.dmi differ diff --git a/icons/mob/simple/broadMobs.dmi b/icons/mob/simple/broadMobs.dmi index 00d01226f8e..ae99a6ad7f0 100644 Binary files a/icons/mob/simple/broadMobs.dmi and b/icons/mob/simple/broadMobs.dmi differ diff --git a/icons/obj/weapons/guns/energy.dmi b/icons/obj/weapons/guns/energy.dmi index 5d3834b6030..46e2ceefdc4 100644 Binary files a/icons/obj/weapons/guns/energy.dmi and b/icons/obj/weapons/guns/energy.dmi differ diff --git a/tgstation.dme b/tgstation.dme index 526f84801f6..7f0a9318305 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -956,7 +956,6 @@ #include "code\datums\actions\mobs\sign_language.dm" #include "code\datums\actions\mobs\sneak.dm" #include "code\datums\actions\mobs\teleport.dm" -#include "code\datums\actions\mobs\transform_weapon.dm" #include "code\datums\actions\mobs\sequences\dash_attack.dm" #include "code\datums\actions\mobs\sequences\projectile.dm" #include "code\datums\ai\_ai_behavior.dm" @@ -5197,6 +5196,7 @@ #include "code\modules\mob\living\basic\blob_minions\blobbernaut.dm" #include "code\modules\mob\living\basic\boss\boss.dm" #include "code\modules\mob\living\basic\boss\blood_drunk_miner\_blood_drunk_miner.dm" +#include "code\modules\mob\living\basic\boss\blood_drunk_miner\blood_drunk_actions.dm" #include "code\modules\mob\living\basic\boss\blood_drunk_miner\blood_drunk_ai.dm" #include "code\modules\mob\living\basic\boss\blood_drunk_miner\blood_drunk_objects.dm" #include "code\modules\mob\living\basic\boss\blood_drunk_miner\blood_drunk_subtypes.dm"