From ec88636e6c0dab06de1cf0b2ee012e02bc6997cf Mon Sep 17 00:00:00 2001 From: BiancaWilkson <42818125+BiancaWilkson@users.noreply.github.com> Date: Tue, 9 Jul 2024 13:44:50 -0400 Subject: [PATCH] Cyborg Damage, Movement, and Power Overhaul (#25252) * Adding defines * More signals for external power * Gets the reboot working * renaming a proc * config stuff * Working on cyborg movement * Update code/modules/mob/living/silicon/robot/robot_damage.dm Co-authored-by: CRUNCH <143041327+Fordoxia@users.noreply.github.com> * Update code/modules/mob/living/silicon/robot/robot_damage.dm Co-authored-by: CRUNCH <143041327+Fordoxia@users.noreply.github.com> * Update code/modules/mob/living/silicon/robot/robot_damage.dm Co-authored-by: CRUNCH <143041327+Fordoxia@users.noreply.github.com> * IOSYS where'd you come from * begon return 0 * VTEC caps slowdown * Adjusting EMPs * Funny arm is GONE * Oh yeah regenerating stamina might be a good thing * Forgot you could uninstall vtec * icon machine broke * Cell-less borgs can enter chargers to stay powered * oh that was almost bad * Fixes some logic * its a surprise tool that will help us later * Adjusting some numbers * Adds a sound to go along with the text alarm * dead things can still charge * Another logic error * Xenos too * sorry linter * fixes CL * Slightly more slowdown on stam damage * neurotoxin won't stun * SOUNDS! * 3 flashes to stun instead of 4 * Slightly longer stun * SPEEDING UP BORGS JUST FOR THE TM SINCE CONFIG DONT WORK * Keep borgs stunned forever * Power loss is more dangerous * Adds a stamina hud to borgs * Cyborgs now heal up properly * Removes an outdated comment * Replacing parts works better now * EMPs disable components for a brief time * More missed rebalances * When you forget to remove debug messages * WHAT * Cult magic works + borgs can be silenced * 2 flashes to stun, flashes confuse now * Update code/game/objects/items/devices/flash.dm Co-authored-by: AffectedArc07 <25063394+AffectedArc07@users.noreply.github.com> Signed-off-by: BiancaWilkson <42818125+BiancaWilkson@users.noreply.github.com> * Abductors can stun borgs * Watcher/cyro rays deal stam to brog * Fixes a rounding error when healing borgs back to full HP * Fixed span Co-authored-by: Ryan <80364400+Sirryan2002@users.noreply.github.com> Signed-off-by: BiancaWilkson <42818125+BiancaWilkson@users.noreply.github.com> * Fixed whitespace Co-authored-by: Ryan <80364400+Sirryan2002@users.noreply.github.com> Signed-off-by: BiancaWilkson <42818125+BiancaWilkson@users.noreply.github.com> * Guard clausify * Indents a message * Update code/modules/mob/living/silicon/robot/robot_damage.dm Co-authored-by: Charlie <69320440+hal9000PR@users.noreply.github.com> Signed-off-by: BiancaWilkson <42818125+BiancaWilkson@users.noreply.github.com> * Update code/modules/mob/living/silicon/robot/component.dm Co-authored-by: Charlie <69320440+hal9000PR@users.noreply.github.com> Signed-off-by: BiancaWilkson <42818125+BiancaWilkson@users.noreply.github.com> * Update code/modules/mob/living/silicon/robot/robot_damage.dm Co-authored-by: Charlie <69320440+hal9000PR@users.noreply.github.com> Signed-off-by: BiancaWilkson <42818125+BiancaWilkson@users.noreply.github.com> * that's not what stat does * No more hardcoded speed, don't TM this branch --------- Signed-off-by: BiancaWilkson <42818125+BiancaWilkson@users.noreply.github.com> Co-authored-by: CRUNCH <143041327+Fordoxia@users.noreply.github.com> Co-authored-by: S34N <12197162+S34NW@users.noreply.github.com> Co-authored-by: AffectedArc07 <25063394+AffectedArc07@users.noreply.github.com> Co-authored-by: Ryan <80364400+Sirryan2002@users.noreply.github.com> Co-authored-by: Charlie <69320440+hal9000PR@users.noreply.github.com> --- code/__DEFINES/combat_defines.dm | 1 + code/__DEFINES/dcs/signals.dm | 4 + code/_onclick/hud/robot_hud.dm | 2 + .../sections/movement_configuration.dm | 2 +- code/datums/status_effects/debuffs.dm | 5 +- code/game/gamemodes/cult/blood_magic.dm | 10 +-- .../miniantags/abduction/abduction_gear.dm | 7 +- code/game/machinery/rechargestation.dm | 15 ++-- code/game/objects/items/devices/flash.dm | 19 ++-- .../objects/items/devices/laserpointer.dm | 3 +- .../objects/items/devices/traitordevices.dm | 3 +- code/game/objects/items/robot/robot_items.dm | 9 +- code/game/objects/items/robot/robot_parts.dm | 1 - .../objects/items/robot/robot_upgrades.dm | 4 +- code/game/objects/items/weapons/stunbaton.dm | 5 ++ .../antagonists/changeling/powers/shriek.dm | 4 +- code/modules/mob/language.dm | 3 + .../mob/living/carbon/carbon_status_procs.dm | 6 +- .../mob/living/carbon/carbon_update_status.dm | 6 +- code/modules/mob/living/living_say.dm | 2 +- code/modules/mob/living/silicon/ai/ai_mob.dm | 8 +- .../mob/living/silicon/robot/component.dm | 65 ++++++++++---- .../mob/living/silicon/robot/robot_damage.dm | 81 +++++++++++++++++- .../mob/living/silicon/robot/robot_defense.dm | 11 ++- .../mob/living/silicon/robot/robot_life.dm | 48 ++++++----- .../mob/living/silicon/robot/robot_mob.dm | 65 ++++++++------ .../mob/living/silicon/robot/robot_modules.dm | 2 +- .../living/silicon/robot/robot_movement.dm | 6 +- .../silicon/robot/robot_update_status.dm | 6 +- .../modules/mob/living/silicon/silicon_mob.dm | 2 - .../simple_animal/hostile/mining/basilisk.dm | 6 ++ .../modules/projectiles/projectile/bullets.dm | 2 - config/example/config.toml | 2 +- sound/machines/reboot_chime.ogg | Bin 0 -> 14486 bytes sound/machines/shut_down.ogg | Bin 0 -> 35338 bytes 35 files changed, 279 insertions(+), 136 deletions(-) create mode 100644 sound/machines/reboot_chime.ogg create mode 100644 sound/machines/shut_down.ogg diff --git a/code/__DEFINES/combat_defines.dm b/code/__DEFINES/combat_defines.dm index 368e1cb2df4..88e5cf34211 100644 --- a/code/__DEFINES/combat_defines.dm +++ b/code/__DEFINES/combat_defines.dm @@ -20,6 +20,7 @@ #define MAGIC "magic" #define STUN "stun" +#define STAM_CRIT "stam_crit" #define WEAKEN "weaken" #define KNOCKDOWN "knockdown" #define PARALYZE "paralize" diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index 269585c0239..e00e6f47f1d 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -495,6 +495,10 @@ #define COMPONENT_NO_ATTACH (1<<0) ///sent from borg recharge stations: (amount, repairs) #define COMSIG_PROCESS_BORGCHARGER_OCCUPANT "living_charge" +///sent when a mob enters a borg charger +#define COMSIG_ENTERED_BORGCHARGER "enter_charger" +///sent when a mob exits a borg charger +#define COMSIG_EXITED_BORGCHARGER "exit_charger" ///sent when a mob/login() finishes: (client) #define COMSIG_MOB_CLIENT_LOGIN "comsig_mob_client_login" ///sent from borg mobs to itself, for tools to catch an upcoming destroy() due to safe decon (rather than detonation) diff --git a/code/_onclick/hud/robot_hud.dm b/code/_onclick/hud/robot_hud.dm index 60310611b71..95c2861049e 100644 --- a/code/_onclick/hud/robot_hud.dm +++ b/code/_onclick/hud/robot_hud.dm @@ -176,6 +176,8 @@ //Health mymob.healths = new /atom/movable/screen/healths/robot() infodisplay += mymob.healths + mymob.staminas = new /atom/movable/screen/healths/stamina() + infodisplay += mymob.staminas //Installed Module mymobR.hands = new /atom/movable/screen/robot/module() diff --git a/code/controllers/configuration/sections/movement_configuration.dm b/code/controllers/configuration/sections/movement_configuration.dm index 16925951246..4c5ddd9c08b 100644 --- a/code/controllers/configuration/sections/movement_configuration.dm +++ b/code/controllers/configuration/sections/movement_configuration.dm @@ -9,7 +9,7 @@ /// Move delay for humanoids var/human_delay = 1.5 /// Move delay for cyborgs - var/robot_delay = 2.5 + var/robot_delay = 1.5 /// Move delay for xenomorphs var/alien_delay = 1.5 /// Move delay for slimes (xenobio, not slimepeople) diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm index 8285baf82e7..c8373ec00c0 100644 --- a/code/datums/status_effects/debuffs.dm +++ b/code/datums/status_effects/debuffs.dm @@ -239,11 +239,10 @@ /datum/status_effect/cult_stun_mark/on_apply() . = ..() - if(!ishuman(owner)) + if(!isliving(owner)) return overlay = mutable_appearance('icons/effects/cult_effects.dmi', "cult-mark", ABOVE_MOB_LAYER) - var/mob/living/carbon/human/H = owner - H.add_overlay(overlay) + owner.add_overlay(overlay) /datum/status_effect/cult_stun_mark/on_remove() owner.cut_overlay(overlay) diff --git a/code/game/gamemodes/cult/blood_magic.dm b/code/game/gamemodes/cult/blood_magic.dm index a00e4b8a064..8d0dc1e03d5 100644 --- a/code/game/gamemodes/cult/blood_magic.dm +++ b/code/game/gamemodes/cult/blood_magic.dm @@ -468,20 +468,20 @@ else to_chat(user, "In a brilliant flash of red, [L] falls to the ground!") - L.KnockDown(10 SECONDS) - L.apply_damage(60, STAMINA) L.apply_status_effect(STATUS_EFFECT_CULT_STUN) - L.flash_eyes(1, TRUE) + L.Silence(6 SECONDS) if(issilicon(target)) var/mob/living/silicon/S = L S.emp_act(EMP_HEAVY) else if(iscarbon(target)) var/mob/living/carbon/C = L - C.Silence(6 SECONDS) + C.KnockDown(10 SECONDS) + C.apply_damage(60, STAMINA) + C.flash_eyes(1, TRUE) C.Stuttering(16 SECONDS) C.CultSlur(20 SECONDS) C.Jitter(16 SECONDS) - to_chat(user, "Stun mark applied! Stab them with a dagger, sword or blood spear to stun them fully!") + to_chat(user, "Stun mark applied! Stab them with a dagger, sword or blood spear to stun them fully!") user.do_attack_animation(target) uses-- ..() diff --git a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm index ec13c9c829b..90e9a9f2f6c 100644 --- a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm +++ b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm @@ -288,9 +288,6 @@ CONTENTS: if(!isabductor(user)) return - if(isrobot(target)) - ..() - return if(!isliving(target)) return @@ -299,6 +296,10 @@ CONTENTS: user.do_attack_animation(L) + if(isrobot(L)) + L.apply_damage(120, STAMINA) //Force a reboot instantly + return + if(ishuman(L)) var/mob/living/carbon/human/H = L if(H.check_shields(src, 0, "[user]'s [name]", MELEE_ATTACK)) diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm index 614c260162d..b5e3fab26db 100644 --- a/code/game/machinery/rechargestation.dm +++ b/code/game/machinery/rechargestation.dm @@ -165,6 +165,7 @@ /obj/machinery/recharge_station/proc/go_out() if(!occupant) return + SEND_SIGNAL(occupant, COMSIG_EXITED_BORGCHARGER) UnregisterSignal(occupant, COMSIG_MOVABLE_MOVED) occupant.forceMove(loc) occupant = null @@ -200,18 +201,11 @@ var/can_accept_user if(isrobot(target)) var/mob/living/silicon/robot/R = target - - if(R.stat == DEAD) - //Whoever had it so that a borg with a dead cell can't enter this thing should be shot. --NEO - return + if(occupant) to_chat(R, "The cell is already occupied!") return - if(!R.cell) - to_chat(R, "Without a power cell, you can't be recharged.") - //Make sure they actually HAVE a cell, now that they can get in while powerless. --NEO - return - can_accept_user = 1 + can_accept_user = TRUE else if(ishuman(target)) var/mob/living/carbon/human/H = target @@ -224,7 +218,7 @@ if(!ismodcontrol(H.back)) if(!H.get_int_organ(/obj/item/organ/internal/cell)) return - can_accept_user = 1 + can_accept_user = TRUE if(!can_accept_user) to_chat(user, "Only non-organics may enter the recharger!") @@ -232,6 +226,7 @@ target.stop_pulling() QDEL_LIST_CONTENTS(target.grabbed_by) + SEND_SIGNAL(target, COMSIG_ENTERED_BORGCHARGER) target.forceMove(src) occupant = target RegisterSignal(target, COMSIG_MOVABLE_MOVED, PROC_REF(go_out)) diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm index 5faa9203f8c..6a96e40bc1b 100644 --- a/code/game/objects/items/devices/flash.dm +++ b/code/game/objects/items/devices/flash.dm @@ -28,8 +28,8 @@ /obj/item/flash/proc/clown_check(mob/user) if(user && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50)) flash_carbon(user, user, 30 SECONDS, 0) - return 0 - return 1 + return FALSE + return TRUE /obj/item/flash/attackby(obj/item/I, mob/user, params) if(can_overcharge) @@ -66,7 +66,7 @@ /obj/item/flash/proc/flash_recharge(mob/user) if(prob(times_used * 2)) //if you use it 5 times in a minute it has a 10% chance to break! burn_out() - return 0 + return FALSE var/deciseconds_passed = world.time - last_used for(var/seconds = deciseconds_passed/10, seconds>=10, seconds-=10) //get 1 charge every 10 seconds @@ -122,20 +122,19 @@ /obj/item/flash/attack(mob/living/M, mob/user) if(!try_use_flash(user)) - return 0 + return FALSE if(iscarbon(M)) flash_carbon(M, user, 10 SECONDS, 1) if(overcharged) M.adjust_fire_stacks(6) M.IgniteMob() burn_out() - return 1 + return TRUE else if(issilicon(M)) add_attack_logs(user, M, "Flashed with [src]") - if(M.flash_eyes(affect_silicon = 1)) - M.Weaken(rand(8 SECONDS, 12 SECONDS)) + if(M.flash_eyes(intensity = 1.25, affect_silicon = TRUE)) // 40 * 1.25 = 50 stamina damage user.visible_message("[user] overloads [M]'s sensors with [src]!", "You overload [M]'s sensors with [src]!") - return 1 + return TRUE user.visible_message("[user] fails to blind [M] with [src]!", "You fail to blind [M] with [src]!") /obj/item/flash/afterattack(atom/target, mob/living/user, proximity, params) @@ -155,7 +154,7 @@ /obj/item/flash/attack_self(mob/living/carbon/user, flag = 0, emp = 0) if(!try_use_flash(user)) - return 0 + return FALSE user.visible_message("[user]'s [name] emits a blinding light!", "Your [name] emits a blinding light!") for(var/mob/living/carbon/M in oviewers(3, null)) flash_carbon(M, user, 6 SECONDS, 0) @@ -168,7 +167,7 @@ /obj/item/flash/emp_act(severity) if(!try_use_flash()) - return 0 + return FALSE for(var/mob/living/carbon/M in viewers(3, null)) flash_carbon(M, null, 20 SECONDS, 0) burn_out() diff --git a/code/game/objects/items/devices/laserpointer.dm b/code/game/objects/items/devices/laserpointer.dm index 51107e2eba9..bc8f1a0cc05 100644 --- a/code/game/objects/items/devices/laserpointer.dm +++ b/code/game/objects/items/devices/laserpointer.dm @@ -117,8 +117,7 @@ var/mob/living/silicon/S = target //20% chance to actually hit the sensors if(prob(effectchance * diode.rating)) - S.flash_eyes(affect_silicon = 1) - S.Weaken(rand(10 SECONDS, 20 SECONDS)) + S.flash_eyes(affect_silicon = TRUE) to_chat(S, "Your sensors were overloaded by a laser!") outmsg = "You overload [S] by shining [src] at [S.p_their()] sensors." diff --git a/code/game/objects/items/devices/traitordevices.dm b/code/game/objects/items/devices/traitordevices.dm index 1d6bca8cf14..0db33374ecf 100644 --- a/code/game/objects/items/devices/traitordevices.dm +++ b/code/game/objects/items/devices/traitordevices.dm @@ -380,7 +380,8 @@ if(!M.client) continue if(issilicon(M)) - M.Weaken(10 SECONDS) + var/mob/living/silicon/robot/R = M + R.flash_eyes(3, affect_silicon = TRUE) //Enough stamina damage to instantly force a reboot else M.Confused(45 SECONDS) M.adjustBrainLoss(10) diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm index c40fb8d86c3..e84bdd20be1 100644 --- a/code/game/objects/items/robot/robot_items.dm +++ b/code/game/objects/items/robot/robot_items.dm @@ -5,6 +5,10 @@ icon = 'icons/mob/robot_items.dmi' var/powerneeded // Percentage of power remaining required to run item +/* +The old, instant-stun borg arm. +Keeping it in for adminabuse but the malf one is /obj/item/melee/baton/borg_stun_arm +*/ /obj/item/borg/stun name = "electrically-charged arm" icon_state = "elecarm" @@ -136,8 +140,3 @@ #undef CYBORG_HUG #undef CYBORG_SHOCK #undef CYBORG_CRUSH - -/obj/item/borg/overdrive - name = "Overdrive" - icon = 'icons/obj/decals.dmi' - icon_state = "shock" diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index 82282c1f96c..6cb40e0e326 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -296,7 +296,6 @@ var/datum/robot_component/cell_component = O.components["power cell"] cell_component.install(chest.cell) - chest.cell.forceMove(O) chest.cell = null M.forceMove(O) //Should fix cybros run time erroring when blown up. It got deleted before, along with the frame. diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index 245656352e4..59a94e277d5 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -253,7 +253,7 @@ /obj/item/borg/upgrade/vtec name = "robotic VTEC Module" - desc = "Used to activate a cyborg's VTEC systems, increasing their speed." + desc = "Used to activate a cyborg's VTEC systems, allowing them to retain more speed when damaged. Alternatively speeds up slow vehicles." icon_state = "cyborg_upgrade2" require_module = TRUE origin_tech = "engineering=4;materials=5;programming=4" @@ -264,7 +264,7 @@ to_chat(usr, "There's no room for another VTEC unit!") return - R.speed -= 1 // Gotta go fast. + R.slowdown_cap = 3.5 return TRUE /***********************/ diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm index 88e24cf6554..ca4e38529b5 100644 --- a/code/game/objects/items/weapons/stunbaton.dm +++ b/code/game/objects/items/weapons/stunbaton.dm @@ -316,3 +316,8 @@ /obj/item/melee/baton/cattleprod/baton_stun(mob/living/L, mob/user, skip_cooldown = FALSE, ignore_shield_check = FALSE) if(sparkler.activate()) return ..() + +/obj/item/melee/baton/loaded/borg_stun_arm + name = "electrically-charged arm" + desc = "A piece of scrap metal wired directly to your power cell." + hitcost = 100 diff --git a/code/modules/antagonists/changeling/powers/shriek.dm b/code/modules/antagonists/changeling/powers/shriek.dm index 21dc282a534..27b1303c534 100644 --- a/code/modules/antagonists/changeling/powers/shriek.dm +++ b/code/modules/antagonists/changeling/powers/shriek.dm @@ -27,8 +27,10 @@ SEND_SOUND(M, sound('sound/effects/clingscream.ogg')) if(issilicon(M)) + var/mob/living/silicon/robot/R = M + R.disable_component("actuator", 7 SECONDS) SEND_SOUND(M, sound('sound/weapons/flash.ogg')) - M.Weaken(rand(10 SECONDS, 20 SECONDS)) + R.flash_eyes(2, affect_silicon = TRUE) //80 Stamina damage for(var/obj/machinery/light/L in range(4, user)) L.on = TRUE diff --git a/code/modules/mob/language.dm b/code/modules/mob/language.dm index 322f994df1e..9c8ac77ccc3 100644 --- a/code/modules/mob/language.dm +++ b/code/modules/mob/language.dm @@ -605,6 +605,9 @@ if(!message) return + if(HAS_TRAIT(speaker, TRAIT_MUTE)) + return + var/log_message = "(ROBOT) [message]" log_say(log_message, speaker) speaker.create_log(SAY_LOG, log_message) diff --git a/code/modules/mob/living/carbon/carbon_status_procs.dm b/code/modules/mob/living/carbon/carbon_status_procs.dm index b96a55084a3..7448ec8262a 100644 --- a/code/modules/mob/living/carbon/carbon_status_procs.dm +++ b/code/modules/mob/living/carbon/carbon_status_procs.dm @@ -12,8 +12,8 @@ stam_regen_start_time = world.time + (STAMINA_REGEN_BLOCK_TIME * stamina_regen_block_modifier) var/prev = stam_paralyzed stam_paralyzed = TRUE - ADD_TRAIT(src, TRAIT_IMMOBILIZED, "stam_crit") // make defines later - ADD_TRAIT(src, TRAIT_FLOORED, "stam_crit") - ADD_TRAIT(src, TRAIT_HANDS_BLOCKED, "stam_crit") + ADD_TRAIT(src, TRAIT_IMMOBILIZED, STAM_CRIT) + ADD_TRAIT(src, TRAIT_FLOORED, STAM_CRIT) + ADD_TRAIT(src, TRAIT_HANDS_BLOCKED, STAM_CRIT) if(!prev && getStaminaLoss() < 120) // Puts you a little further into the initial stamcrit, makes stamcrit harder to outright counter with chems. adjustStaminaLoss(30, FALSE) diff --git a/code/modules/mob/living/carbon/carbon_update_status.dm b/code/modules/mob/living/carbon/carbon_update_status.dm index f98d41b6863..58b0c6a3a77 100644 --- a/code/modules/mob/living/carbon/carbon_update_status.dm +++ b/code/modules/mob/living/carbon/carbon_update_status.dm @@ -29,9 +29,9 @@ else if(stam_paralyzed) SEND_SIGNAL(src, COMSIG_CARBON_EXIT_STAMINACRIT) stam_paralyzed = FALSE - REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, "stam_crit") // make defines later - REMOVE_TRAIT(src, TRAIT_FLOORED, "stam_crit") - REMOVE_TRAIT(src, TRAIT_HANDS_BLOCKED, "stam_crit") + REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, STAM_CRIT) + REMOVE_TRAIT(src, TRAIT_FLOORED, STAM_CRIT) + REMOVE_TRAIT(src, TRAIT_HANDS_BLOCKED, STAM_CRIT) /mob/living/carbon/can_hear() . = FALSE diff --git a/code/modules/mob/living/living_say.dm b/code/modules/mob/living/living_say.dm index 6bb553548cc..18ad834c87e 100644 --- a/code/modules/mob/living/living_say.dm +++ b/code/modules/mob/living/living_say.dm @@ -86,7 +86,7 @@ GLOBAL_LIST_EMPTY(channel_to_radio_key) S.message = cultslur(S.message) verb = "slurs" - if(!IsVocal()) + if(!IsVocal() || HAS_TRAIT(src, TRAIT_MUTE)) S.message = "" return list("verb" = verb) diff --git a/code/modules/mob/living/silicon/ai/ai_mob.dm b/code/modules/mob/living/silicon/ai/ai_mob.dm index 21473ee908c..5999eb34eda 100644 --- a/code/modules/mob/living/silicon/ai/ai_mob.dm +++ b/code/modules/mob/living/silicon/ai/ai_mob.dm @@ -680,12 +680,8 @@ GLOBAL_LIST_INIT(ai_verbs_default, list( /mob/living/silicon/ai/emp_act(severity) ..() - if(prob(30)) - switch(pick(1,2)) - if(1) - view_core() - if(2) - ai_call_shuttle() + Stun((12 SECONDS) / severity) + view_core() /mob/living/silicon/ai/ex_act(severity) ..() diff --git a/code/modules/mob/living/silicon/robot/component.dm b/code/modules/mob/living/silicon/robot/component.dm index f3f11facad0..643d344c9f5 100644 --- a/code/modules/mob/living/silicon/robot/component.dm +++ b/code/modules/mob/living/silicon/robot/component.dm @@ -8,13 +8,21 @@ var/brute_damage = 0 var/electronics_damage = 0 var/max_damage = 30 - var/component_disabled = 0 + var/component_disabled = FALSE var/mob/living/silicon/robot/owner var/external_type = null // The actual device object that has to be installed for this. var/obj/item/wrapped = null // The wrapped device(e.g. radio), only set if external_type isn't null + ///How much a component is contributing to slowdown, set on New to be equal to min_slowdown_factor + var/current_slowdown_factor + ///The max amount of slowness a component can contribute, set on New to be 1% of the max damage + var/max_slowdown_factor + ///The minimum amount of speed modification a component can contribute. Currently just 0 for all. + var/min_slowdown_factor = 0 /datum/robot_component/New(mob/living/silicon/robot/R) owner = R + max_slowdown_factor = (max_damage / 100) + current_slowdown_factor = min_slowdown_factor // Should only ever be destroyed when a borg gets destroyed /datum/robot_component/Destroy(force, ...) @@ -25,6 +33,8 @@ /datum/robot_component/proc/install(obj/item/I, update_health = TRUE) wrapped = I installed = TRUE + I.forceMove(owner) + current_slowdown_factor = (brute_damage + electronics_damage) / 100 go_online() if(update_health) owner.updatehealth("component '[src]' installed") @@ -35,7 +45,7 @@ go_offline() owner.updatehealth("component '[src]' removed") -/datum/robot_component/proc/destroy() +/datum/robot_component/proc/break_component() if(wrapped) qdel(wrapped) uninstall() @@ -50,9 +60,9 @@ brute_damage += brute electronics_damage += electronics - + current_slowdown_factor = clamp((current_slowdown_factor + ((brute + electronics) / 100)), min_slowdown_factor, max_slowdown_factor) if(brute_damage + electronics_damage >= max_damage) - destroy() + break_component() SStgui.update_uis(owner.self_diagnosis) @@ -63,12 +73,19 @@ if(owner && updating_health) owner.updatehealth("component '[src]' heal damage") - - brute_damage = max(0, brute_damage - brute) - electronics_damage = max(0, electronics_damage - electronics) - + var/burn_damage_healed = clamp(electronics, 0, electronics_damage) + var/brute_damage_healed = clamp(brute, 0, brute_damage) + current_slowdown_factor = clamp((current_slowdown_factor - ((burn_damage_healed + brute_damage_healed) / 100)), min_slowdown_factor, max_slowdown_factor) + rounding_error_check() + brute_damage -= brute_damage_healed + electronics_damage -= burn_damage_healed SStgui.update_uis(owner.self_diagnosis) +///There tends to be some desync between slowdown and damage when being healed up slowly like through self-repair or upgraded rechargers. +/datum/robot_component/proc/rounding_error_check() + if(current_slowdown_factor < (min_slowdown_factor) + 0.0001) //Within .0001 of the minimum, just set it to the minimum + current_slowdown_factor = min_slowdown_factor + /datum/robot_component/proc/is_powered() return installed && (brute_damage + electronics_damage < max_damage) && (powered) @@ -90,12 +107,12 @@ /datum/robot_component/proc/disable() if(!component_disabled) go_offline() - component_disabled++ + component_disabled = TRUE /datum/robot_component/proc/enable() - component_disabled-- - if(!component_disabled) + if(component_disabled) go_online() + component_disabled = FALSE /datum/robot_component/proc/toggle() toggled = !toggled @@ -112,6 +129,13 @@ /datum/robot_component/proc/go_offline() return +/datum/robot_component/proc/get_movement_delay() + if(is_missing()) + return 0 + if(is_destroyed()) + return max_slowdown_factor + return current_slowdown_factor + /datum/robot_component/armour name = "armour plating" external_type = /obj/item/robot_parts/robot_component/armour @@ -136,16 +160,19 @@ owner.cell = null /datum/robot_component/cell/is_powered() - return ..() && owner.cell + return ..() && owner.cell?.charge /datum/robot_component/cell/Destroy(force, ...) owner.cell = null return ..() -/datum/robot_component/cell/destroy() +/datum/robot_component/cell/break_component() ..() owner.cell = null +/datum/robot_component/cell/disable() //This can't be manually disabled, and shouldn't be accidentally disabled + return + /datum/robot_component/radio name = "radio" external_type = /obj/item/robot_parts/robot_component/radio @@ -189,11 +216,19 @@ var/datum/robot_component/C = components[module_name] return C && C.installed && C.toggled && C.is_powered() && !C.component_disabled +///Disables a random component for the duration, or until manually turned back on. +/mob/living/silicon/robot/proc/disable_random_component(number_disabled, duration) + var/list/random_components = pick_multiple_unique(components, number_disabled) + for(var/component in random_components) + disable_component(component, duration) + /mob/living/silicon/robot/proc/disable_component(module_name, duration) var/datum/robot_component/D = get_component(module_name) D.disable() - spawn(duration) - D.enable() + addtimer(CALLBACK(src, PROC_REF(reenable_component), D), duration) + +/mob/living/silicon/robot/proc/reenable_component(datum/robot_component/to_enable) + to_enable.enable() // Returns component by it's string name /mob/living/silicon/robot/proc/get_component(component_name) diff --git a/code/modules/mob/living/silicon/robot/robot_damage.dm b/code/modules/mob/living/silicon/robot/robot_damage.dm index 60dbb398218..c618bb5f67a 100644 --- a/code/modules/mob/living/silicon/robot/robot_damage.dm +++ b/code/modules/mob/living/silicon/robot/robot_damage.dm @@ -32,6 +32,21 @@ heal_overall_damage(0, -amount, updating_health) return STATUS_UPDATE_HEALTH +/mob/living/silicon/robot/update_stamina() + if(rebooting) + return + var/current_stam_damage = getStaminaLoss() + if(current_stam_damage > DAMAGE_PRECISION && (maxHealth - current_stam_damage) <= HEALTH_THRESHOLD_CRIT && stat == CONSCIOUS) + start_emergency_reboot() + +/mob/living/silicon/robot/handle_status_effects() + ..() + if(stam_regen_start_time <= world.time) + update_stamina() + if(staminaloss && !rebooting) + setStaminaLoss(0, FALSE) + update_stamina_hud() + /mob/living/silicon/robot/proc/get_damaged_components(get_brute, get_burn, get_borked = FALSE, get_missing = FALSE) var/list/datum/robot_component/parts = list() for(var/V in components) @@ -55,14 +70,32 @@ if(C.installed) rval += C return rval - +///Returns the armour component for a borg, or false if its missing or broken /mob/living/silicon/robot/proc/get_armour() if(!LAZYLEN(components)) - return 0 + return FALSE var/datum/robot_component/C = components["armour"] if(C && C.installed) return C - return 0 + return FALSE +///Returns the power cell component for a borg, or false if its missing or broken +/mob/living/silicon/robot/proc/get_cell_component() + if(!LAZYLEN(components)) + return FALSE + var/datum/robot_component/C = components["power cell"] + if(C?.installed) + return C + return FALSE + +/mob/living/silicon/robot/proc/get_total_component_slowdown() + var/total_slowdown = 0 + for(var/V in components) + var/datum/robot_component/C = components[V] + total_slowdown += C.get_movement_delay() + return total_slowdown + +/mob/living/silicon/robot/proc/get_stamina_slowdown() + return round((staminaloss / 40), 0.125) /mob/living/silicon/robot/heal_organ_damage(brute, burn, updating_health = TRUE) var/list/datum/robot_component/parts = get_damaged_components(brute, burn) @@ -131,3 +164,45 @@ parts -= picked updatehealth() + +/* +Begins the stamcrit reboot process for borgs. Stuns them, and warns people if the borg has no power source. +*/ +/mob/living/silicon/robot/proc/start_emergency_reboot() + rebooting = TRUE + playsound(src, 'sound/machines/shut_down.ogg', 100, FALSE, SOUND_RANGE_SET(10)) + if(!has_power_source()) + visible_message( + "[src]'s system sounds an alarm, \"ERROR: NO POWER SOURCE DETECTED. SYSTEM SHUTDOWN IMMINENT.\"", + "EMERGENCY: FULL SYSTEM SHUTDOWN IMMINENT.") + playsound(src, 'sound/machines/buzz-two.ogg' , 50, FALSE, SOUND_RANGE_SET(10)) + else + visible_message( + "[src]'s lights suddenly go dark and [p_they()] seem to shut down.", + "A critical neural connection error has occurred. Beginning emergency reboot..." + ) + var/stun_time = rand(13 SECONDS, 18 SECONDS) //Slightly longer than old flash timer + setStaminaLoss(0) //Have you tried turning it off and on again? + Weaken(stun_time) + addtimer(CALLBACK(src, PROC_REF(end_emergency_reboot)), stun_time) +/* +Finishes the stamcrit process. If the borg doesn't have a power source for the reboot, they die. +*/ +/mob/living/silicon/robot/proc/end_emergency_reboot() + if(!has_power_source()) //Can't turn itself back on + rebooting = FALSE + death() + return + if(getStaminaLoss()) //If someone has been chain-flashing a borg then the ride never ends + var/restun_time = rand(7 SECONDS, 10 SECONDS) + to_chat(src, "Error: Continual sensor overstimulation resulted in faulty reboot. Retrying in [restun_time / 10] seconds.") + setStaminaLoss(0) //Just keep trying to turn it off and on again, surely it'll work eventually + Weaken(restun_time) + addtimer(CALLBACK(src, PROC_REF(end_emergency_reboot)), restun_time) + return + rebooting = FALSE + if(stat != CONSCIOUS) + return + playsound(src, 'sound/machines/reboot_chime.ogg' , 100, FALSE, SOUND_RANGE_SET(10)) + update_stamina_hud() + to_chat(src, "Reboot complete, neural interface operational.") diff --git a/code/modules/mob/living/silicon/robot/robot_defense.dm b/code/modules/mob/living/silicon/robot/robot_defense.dm index b397601193b..9129dd97b27 100644 --- a/code/modules/mob/living/silicon/robot/robot_defense.dm +++ b/code/modules/mob/living/silicon/robot/robot_defense.dm @@ -8,7 +8,7 @@ visible_message("[M] disarmed [src]!", "[M] has disabled [src]'s active module!") add_attack_logs(M, src, "alien disarmed") else - Stun(4 SECONDS) + adjustStaminaLoss(30) //Same as carbons, I guess? step(src, get_dir(M,src)) add_attack_logs(M, src, "Alien pushed over") visible_message("[M] forces back [src]!", "[M] forces back [src]!") @@ -55,3 +55,12 @@ step_away(src, user, 15) sleep(3) step_away(src, user, 15) + +/mob/living/silicon/robot/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /atom/movable/screen/fullscreen/stretch/flash/noise) + if(!affect_silicon) + return + Confused(intensity * 4 SECONDS) + var/software_damage = (intensity * 40) + adjustStaminaLoss(software_damage) + to_chat(src, "Error: Optical sensors overstimulated.") + ..() diff --git a/code/modules/mob/living/silicon/robot/robot_life.dm b/code/modules/mob/living/silicon/robot/robot_life.dm index 7f104251361..c25b202e3f2 100644 --- a/code/modules/mob/living/silicon/robot/robot_life.dm +++ b/code/modules/mob/living/silicon/robot/robot_life.dm @@ -15,33 +15,35 @@ /mob/living/silicon/robot/proc/handle_robot_cell() - if(stat != DEAD) - if(!is_component_functioning("power cell")) - uneq_all() - low_power_mode = TRUE - update_headlamp() - diag_hud_set_borgcell() - return - if(low_power_mode) - if(is_component_functioning("power cell") && cell.charge) - low_power_mode = FALSE - update_headlamp() - else if(stat == CONSCIOUS) - use_power() + if(stat == DEAD) + return + if(externally_powered) + return + if(low_power_mode) + handle_no_power() + else if(!is_component_functioning("power cell")) //This makes it so you'll only get the warnings once per running out of charge + enter_low_power_mode() + else if(stat == CONSCIOUS) + use_power() /mob/living/silicon/robot/proc/use_power() - // this check is safe because `cell` is guaranteed to be set when the power cell is functioning - if(is_component_functioning("power cell") && cell.charge) - if(cell.charge <= 100) - uneq_all() - var/amt = clamp((lamp_intensity - 2) * 2,1,cell.charge) //Always try to use at least one charge per tick, but allow it to completely drain the cell. - cell.use(amt) //Usage table: 1/tick if off/lowest setting, 4 = 4/tick, 6 = 8/tick, 8 = 12/tick, 10 = 16/tick - else - uneq_all() - low_power_mode = TRUE - update_headlamp() + var/amt = clamp((lamp_intensity - 2) * 2, 1, cell.charge) //Always try to use at least one charge per tick, but allow it to completely drain the cell. + cell.use(amt) //Usage table: 1/tick if off/lowest setting, 4 = 4/tick, 6 = 8/tick, 8 = 12/tick, 10 = 16/tick diag_hud_set_borgcell() +/mob/living/silicon/robot/proc/handle_no_power() + diag_hud_set_borgcell() + if(is_component_functioning("power cell")) + low_power_mode = FALSE + return + adjustStaminaLoss(3) + +/mob/living/silicon/robot/proc/enter_low_power_mode() + low_power_mode = TRUE + playsound(src, "sound/mecha/lowpower.ogg", 50, FALSE, SOUND_RANGE_SET(10)) + to_chat(src, "Alert: Power cell requires immediate charging.") + handle_no_power() + /mob/living/silicon/robot/proc/handle_equipment() if(camera && !scrambledcodes) if(stat == DEAD || wires.is_cut(WIRE_BORG_CAMERA)) diff --git a/code/modules/mob/living/silicon/robot/robot_mob.dm b/code/modules/mob/living/silicon/robot/robot_mob.dm index bb700a8d976..b6d5163c105 100644 --- a/code/modules/mob/living/silicon/robot/robot_mob.dm +++ b/code/modules/mob/living/silicon/robot/robot_mob.dm @@ -75,7 +75,12 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( var/brute_mod = 1 /// Incoming burn damage is multiplied by this number. var/burn_mod = 1 - + ///If the cyborg is rebooting from stamcrit + var/rebooting = FALSE + ///If the cyborg is in a charger, or otherwise receiving power from an outside source. + var/externally_powered = FALSE + ///What the cyborg's maximum slowdown penalty is, if it has one. + var/slowdown_cap = INFINITY var/list/force_modules /// Can a robot rename itself with the Namepick verb? var/allow_rename = TRUE @@ -212,7 +217,8 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( scanner = new(src) scanner.Grant(src) RegisterSignal(src, COMSIG_MOVABLE_MOVED, PROC_REF(create_trail)) - + RegisterSignal(src, COMSIG_ENTERED_BORGCHARGER, PROC_REF(gain_external_power)) + RegisterSignal(src, COMSIG_EXITED_BORGCHARGER, PROC_REF(lose_external_power)) robot_module_hat_offset(icon_state) /mob/living/silicon/robot/get_radio() @@ -684,7 +690,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( if("lava" in weather_immunities) // Remove the lava-immunity effect given by a printable upgrade weather_immunities -= "lava" armor = getArmor(arglist(initial(armor))) - + slowdown_cap = INFINITY status_flags |= CANPUSH hud_used.update_robot_modules_display() @@ -881,21 +887,17 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( if(istype(W, /obj/item/robot_parts/robot_component) && opened) for(var/V in components) var/datum/robot_component/C = components[V] - if(C.is_missing() && istype(W, C.external_type)) - if(!user.drop_item()) - to_chat(user, "[W] seems to be stuck in your hand!") - return - C.install(W) - W.loc = null - - var/obj/item/robot_parts/robot_component/WC = W - if(istype(WC)) - C.brute_damage = WC.brute - C.electronics_damage = WC.burn - - to_chat(usr, "You install [W].") - + if(!C.is_missing() || !istype(W, C.external_type)) + continue + if(!user.drop_item()) + to_chat(user, "[W] seems to be stuck in your hand!") return + var/obj/item/robot_parts/robot_component/WC = W + C.brute_damage = WC.brute + C.electronics_damage = WC.burn + C.install(WC) + to_chat(usr, "You install [W].") + return if(istype(W, /obj/item/stack/cable_coil) && user.a_intent == INTENT_HELP && (wiresexposed || isdrone(src))) user.changeNext_move(CLICK_CD_MELEE) @@ -920,12 +922,8 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( to_chat(user, "There is a power cell already installed.") else user.drop_item() - W.loc = src to_chat(user, "You insert the power cell.") C.install(W) - //This will mean that removing and replacing a power cell will repair the mount, but I don't care at this point. ~Z - C.brute_damage = 0 - C.electronics_damage = 0 var/been_hijacked = FALSE for(var/mob/living/simple_animal/demon/pulse_demon/demon in cell) @@ -1092,7 +1090,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( thing.burn = C.electronics_damage C.uninstall() - thing.loc = loc + thing.forceMove(loc) @@ -1485,11 +1483,12 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( if(emp_protection) return ..() + adjustStaminaLoss((30 / severity)) //They also get flashed for an additional 30 switch(severity) - if(1) - disable_component("comms", 160) - if(2) - disable_component("comms", 60) + if(EMP_HEAVY) + disable_random_component(2, 20 SECONDS) + if(EMP_LIGHT) + disable_random_component(1, 10 SECONDS) /mob/living/silicon/robot/deathsquad base_icon = "nano_bloodhound" @@ -1750,3 +1749,17 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( old_ai.connected_robots -= src if(connected_ai) connected_ai.connected_robots |= src + +/mob/living/silicon/robot/proc/gain_external_power() + SIGNAL_HANDLER //COMSIG_ENTERED_BORGCHARGER + externally_powered = TRUE + +/mob/living/silicon/robot/proc/lose_external_power() + SIGNAL_HANDLER //COMSIG_EXITED_BORGCHARGER + externally_powered = FALSE + +/mob/living/silicon/robot/proc/has_power_source() + var/datum/robot_component/cell/cell = get_cell_component() + if(!cell) + return externally_powered + return cell.is_powered() || externally_powered diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index 00f93669a17..7ecc75569d7 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -472,7 +472,7 @@ /obj/item/inflatable/cyborg, /obj/item/inflatable/cyborg/door ) - emag_modules = list(/obj/item/borg/stun, /obj/item/restraints/handcuffs/cable/zipties/cyborg, /obj/item/rcd/borg) + emag_modules = list(/obj/item/melee/baton/loaded/borg_stun_arm, /obj/item/restraints/handcuffs/cable/zipties/cyborg, /obj/item/rcd/borg) override_modules = list(/obj/item/gun/energy/emitter/cyborg/proto) malf_modules = list(/obj/item/gun/energy/emitter/cyborg) special_rechargables = list(/obj/item/extinguisher, /obj/item/weldingtool/largetank/cyborg, /obj/item/gun/energy/emitter/cyborg) diff --git a/code/modules/mob/living/silicon/robot/robot_movement.dm b/code/modules/mob/living/silicon/robot/robot_movement.dm index 2c4eccf2b78..89ff5cc82ea 100644 --- a/code/modules/mob/living/silicon/robot/robot_movement.dm +++ b/code/modules/mob/living/silicon/robot/robot_movement.dm @@ -5,16 +5,18 @@ return TRUE return FALSE - //No longer needed, but I'll leave it here incase we plan to re-use it. /mob/living/silicon/robot/movement_delay() . = ..() + . += GLOB.configuration.movement.robot_delay . += speed + . += get_total_component_slowdown() + . += get_stamina_slowdown() // Counteract magboot slow in 0G. if(!has_gravity(src) && HAS_TRAIT(src, TRAIT_MAGPULSE)) . -= 2 // The slowdown value on the borg magpulse. if(module_active && istype(module_active,/obj/item/borg/destroyer/mobility)) . -= 3 - . += GLOB.configuration.movement.robot_delay + . = min(., slowdown_cap) /mob/living/silicon/robot/mob_negates_gravity() return HAS_TRAIT(src, TRAIT_MAGPULSE) diff --git a/code/modules/mob/living/silicon/robot/robot_update_status.dm b/code/modules/mob/living/silicon/robot/robot_update_status.dm index ee0efa21cb2..a152d926235 100644 --- a/code/modules/mob/living/silicon/robot/robot_update_status.dm +++ b/code/modules/mob/living/silicon/robot/robot_update_status.dm @@ -14,7 +14,7 @@ death() create_debug_log("died of damage, trigger reason: [reason]") return - if(!is_component_functioning("actuator") || !is_component_functioning("power cell") || HAS_TRAIT(src, TRAIT_KNOCKEDOUT) || IsStunned() || IsWeakened() || getOxyLoss() > maxHealth * 0.5) // Borgs need to be able to sleep for adminfreeze + if(HAS_TRAIT(src, TRAIT_KNOCKEDOUT) || IsStunned() || IsWeakened() || getOxyLoss() > maxHealth * 0.5) // Borgs need to be able to sleep for adminfreeze if(stat == CONSCIOUS) KnockOut() create_debug_log("fell unconscious, trigger reason: [reason]") @@ -23,11 +23,11 @@ WakeUp() create_debug_log("woke up, trigger reason: [reason]") else - if(health > 0 && !suiciding) + if(health > 0 && !suiciding && has_power_source()) update_revive() var/mob/dead/observer/ghost = get_ghost() if(ghost) - to_chat(ghost, "Your cyborg shell has been repaired, re-enter if you want to continue! (Verbs -> Ghost -> Re-enter corpse)") + to_chat(ghost, "Your cyborg shell has been repaired and repowered, re-enter if you want to continue! (Verbs -> Ghost -> Re-enter corpse)") SEND_SOUND(ghost, sound('sound/effects/genetics.ogg')) create_attack_log("revived, trigger reason: [reason]") create_log(MISC_LOG, "revived, trigger reason: [reason]") diff --git a/code/modules/mob/living/silicon/silicon_mob.dm b/code/modules/mob/living/silicon/silicon_mob.dm index 42d8bf19b98..8c5026b2ec3 100644 --- a/code/modules/mob/living/silicon/silicon_mob.dm +++ b/code/modules/mob/living/silicon/silicon_mob.dm @@ -230,10 +230,8 @@ switch(severity) if(EMP_HEAVY) take_organ_damage(20) - Stun(16 SECONDS) if(EMP_LIGHT) take_organ_damage(10) - Stun(6 SECONDS) flash_eyes(affect_silicon = 1) to_chat(src, "*BZZZT*") to_chat(src, "Warning: Electromagnetic pulse detected.") diff --git a/code/modules/mob/living/simple_animal/hostile/mining/basilisk.dm b/code/modules/mob/living/simple_animal/hostile/mining/basilisk.dm index 6ead2543757..5fd8f200321 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining/basilisk.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining/basilisk.dm @@ -43,6 +43,12 @@ flag = ENERGY temperature = 50 +/obj/item/projectile/temp/basilisk/on_hit(atom/target, blocked) + ..() + if(isrobot(target)) + var/mob/living/silicon/robot/cyborg = target + cyborg.apply_damage(35, STAMINA) + /mob/living/simple_animal/hostile/asteroid/basilisk/GiveTarget(new_target) if(..()) //we have a target if(isliving(target) && !target.Adjacent(targets_from) && ranged_cooldown <= world.time)//No more being shot at point blank or spammed with RNG beams diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index d509a37b8f9..28d21843b85 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -294,8 +294,6 @@ if(isalien(target)) knockdown = 0 nodamage = TRUE - if(isrobot(target)) - stun = 10 SECONDS . = ..() // Execute the rest of the code. /obj/item/projectile/bullet/anti_alien_toxin diff --git a/config/example/config.toml b/config/example/config.toml index 846ba5bc816..28050252d5a 100644 --- a/config/example/config.toml +++ b/config/example/config.toml @@ -594,7 +594,7 @@ crawling_speed_reduction = 4 # Move delay for humanoids human_delay = 1.5 # Move delay for cyborgs -robot_delay = 2.5 +robot_delay = 1.5 # Move delay for xenomorphs alien_delay = 1.5 # Move delay for slimes (xenobio, not slimepeople) diff --git a/sound/machines/reboot_chime.ogg b/sound/machines/reboot_chime.ogg new file mode 100644 index 0000000000000000000000000000000000000000..ff90a50dd053c0035b6c3b30d6f8a4f95bd48f09 GIT binary patch literal 14486 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

ttLmF$<=WiF^^zPl*0~ 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 Ro}Alv8oyUU`Og#p{tq;(oI3yj literal 0 HcmV?d00001 diff --git a/sound/machines/shut_down.ogg b/sound/machines/shut_down.ogg new file mode 100644 index 0000000000000000000000000000000000000000..66be028b0df80fe7bb003e441dc192d79dc7abb8 GIT binary patch literal 35338 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