diff --git a/_maps/shuttles/emergency_casino.dmm b/_maps/shuttles/emergency_casino.dmm index e1e5acf552d..a0d60bbe47f 100644 --- a/_maps/shuttles/emergency_casino.dmm +++ b/_maps/shuttles/emergency_casino.dmm @@ -178,13 +178,6 @@ /obj/machinery/status_display/evac/directional/east, /turf/open/floor/carpet/green, /area/shuttle/escape) -"gg" = ( -/obj/effect/turf_decal/siding/wood{ - dir = 4 - }, -/obj/structure/chair/stool/directional/north, -/turf/open/floor/wood, -/area/shuttle/escape) "gm" = ( /obj/structure/chair/stool/bar/directional/south, /turf/open/floor/carpet/green, @@ -332,10 +325,6 @@ }, /turf/open/floor/carpet/green, /area/shuttle/escape) -"ji" = ( -/obj/structure/chair/stool/directional/east, -/turf/open/floor/carpet/green, -/area/shuttle/escape) "jE" = ( /obj/structure/chair/sofa/corp/left{ dir = 1 @@ -415,10 +404,6 @@ /obj/effect/turf_decal/siding, /turf/open/floor/carpet/royalblue, /area/shuttle/escape) -"kU" = ( -/obj/structure/chair/stool/directional/east, -/turf/open/floor/wood, -/area/shuttle/escape) "la" = ( /obj/structure/table/wood/poker, /obj/item/storage/fancy/cigarettes/cigars{ @@ -980,10 +965,6 @@ /obj/machinery/light/directional/east, /turf/open/floor/carpet/green, /area/shuttle/escape) -"BD" = ( -/obj/structure/chair/stool/bar/directional/north, -/turf/open/floor/carpet/green, -/area/shuttle/escape) "BY" = ( /obj/effect/spawner/random/entertainment/arcade, /turf/open/floor/carpet/green, @@ -1294,7 +1275,7 @@ /obj/item/storage/crayons, /obj/item/storage/crayons, /obj/item/storage/crayons, -/mob/living/simple_animal/bot/honkbot, +/mob/living/simple_animal/bot/secbot/honkbot, /turf/open/floor/sepia, /area/shuttle/escape) "NN" = ( @@ -1455,13 +1436,6 @@ /obj/machinery/light/directional/south, /turf/open/floor/wood, /area/shuttle/escape) -"Td" = ( -/obj/effect/turf_decal/siding/wood{ - dir = 8 - }, -/obj/structure/chair/stool/directional/north, -/turf/open/floor/wood, -/area/shuttle/escape) "Ty" = ( /turf/open/floor/mineral/titanium/purple, /area/shuttle/escape) diff --git a/code/datums/components/crafting/recipes.dm b/code/datums/components/crafting/recipes.dm index 1c0ed923b7a..685be06b295 100644 --- a/code/datums/components/crafting/recipes.dm +++ b/code/datums/components/crafting/recipes.dm @@ -386,7 +386,7 @@ /datum/crafting_recipe/honkbot name = "Honkbot" - result = /mob/living/simple_animal/bot/honkbot + result = /mob/living/simple_animal/bot/secbot/honkbot reqs = list(/obj/item/storage/box/clown = 1, /obj/item/bodypart/r_arm/robot = 1, /obj/item/assembly/prox_sensor = 1, diff --git a/code/modules/mining/abandoned_crates.dm b/code/modules/mining/abandoned_crates.dm index b9916368823..b5930c3c400 100644 --- a/code/modules/mining/abandoned_crates.dm +++ b/code/modules/mining/abandoned_crates.dm @@ -139,7 +139,7 @@ if(6 to 10) new /obj/item/melee/skateboard/pro(src) if(11 to 15) - new /mob/living/simple_animal/bot/honkbot(src) + new /mob/living/simple_animal/bot/secbot/honkbot(src) if(16 to 20) new /obj/item/stack/ore/diamond(src, 10) if(21 to 25) diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index 8bfe37636e3..34134da0a52 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -210,7 +210,7 @@ diag_hud_set_botmode() //If a bot has its own HUD (for player bots), provide it. - if(data_hud_type) + if(!isnull(data_hud_type)) var/datum/atom_hud/datahud = GLOB.huds[data_hud_type] datahud.add_hud_to(src) if(path_hud) diff --git a/code/modules/mob/living/simple_animal/bot/construction.dm b/code/modules/mob/living/simple_animal/bot/construction.dm index cbd36c2eab1..d311dbf9565 100644 --- a/code/modules/mob/living/simple_animal/bot/construction.dm +++ b/code/modules/mob/living/simple_animal/bot/construction.dm @@ -278,30 +278,30 @@ icon_state = "honkbot_arm" created_name = "Honkbot" -/obj/item/bot_assembly/honkbot/attackby(obj/item/I, mob/user, params) +/obj/item/bot_assembly/honkbot/attackby(obj/item/attacking_item, mob/user, params) ..() switch(build_step) if(ASSEMBLY_FIRST_STEP) - if(isprox(I)) - if(!user.temporarilyRemoveItemFromInventory(I)) + if(isprox(attacking_item)) + if(!user.temporarilyRemoveItemFromInventory(attacking_item)) return - to_chat(user, span_notice("You add the [I] to [src]!")) + to_chat(user, span_notice("You add the [attacking_item] to [src]!")) icon_state = "honkbot_proxy" name = "incomplete Honkbot assembly" - qdel(I) + qdel(attacking_item) build_step++ if(ASSEMBLY_SECOND_STEP) - if(istype(I, /obj/item/bikehorn)) - if(!can_finish_build(I, user)) + if(istype(attacking_item, /obj/item/bikehorn)) + if(!can_finish_build(attacking_item, user)) return - to_chat(user, span_notice("You add the [I] to [src]! Honk!")) - var/mob/living/simple_animal/bot/honkbot/S = new(drop_location()) - S.name = created_name - S.limiting_spam = TRUE // only long enough to hear the first ping. - addtimer(CALLBACK (S, .mob/living/simple_animal/bot/honkbot/proc/react_ping), 5) - S.bikehorn = I.type - qdel(I) + to_chat(user, span_notice("You add the [attacking_item] to [src]! Honk!")) + var/mob/living/simple_animal/bot/secbot/honkbot/new_honkbot = new(drop_location()) + new_honkbot.name = created_name + new_honkbot.limiting_spam = TRUE // only long enough to hear the first ping. + playsound(new_honkbot, 'sound/machines/ping.ogg', 50, TRUE, -1) + new_honkbot.baton_type = attacking_item.type + qdel(attacking_item) qdel(src) diff --git a/code/modules/mob/living/simple_animal/bot/honkbot.dm b/code/modules/mob/living/simple_animal/bot/honkbot.dm index 73842cd3164..8b08f91ab24 100644 --- a/code/modules/mob/living/simple_animal/bot/honkbot.dm +++ b/code/modules/mob/living/simple_animal/bot/honkbot.dm @@ -1,349 +1,147 @@ -/mob/living/simple_animal/bot/honkbot - name = "\improper honkbot" +/mob/living/simple_animal/bot/secbot/honkbot + name = "\improper Honkbot" desc = "A little robot. It looks happy with its bike horn." - icon = 'icons/mob/aibots.dmi' icon_state = "honkbot" - density = FALSE - anchored = FALSE - health = 25 - maxHealth = 25 damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0) - pass_flags = PASSMOB | PASSFLAPS + combat_mode = FALSE maints_access_required = list(ACCESS_ROBOTICS, ACCESS_THEATRE) radio_key = /obj/item/encryptionkey/headset_service //doesn't have security key radio_channel = RADIO_CHANNEL_SERVICE //Doesn't even use the radio anyway. bot_type = HONK_BOT - data_hud_type = DATA_HUD_SECURITY_BASIC // show jobs + bot_mode_flags = BOT_MODE_ON | BOT_MODE_REMOTE_ENABLED | BOT_MODE_PAI_CONTROLLABLE | BOT_MODE_AUTOPATROL hackables = "sound control systems" path_image_color = "#FF69B4" + data_hud_type = DATA_HUD_SECURITY_BASIC //show jobs - var/honksound = 'sound/items/bikehorn.ogg' //customizable sound + baton_type = /obj/item/bikehorn + security_mode_flags = SECBOT_CHECK_WEAPONS + + ///Keeping track of how much we honk to prevent spamming it var/limiting_spam = FALSE + ///Sound played when HONKing someone + var/honksound = 'sound/items/bikehorn.ogg' + ///Cooldown between honks var/cooldowntime = 30 + ///Cooldown between ear-breaking horn sounds var/cooldowntimehorn = 10 - var/mob/living/carbon/target - var/oldtarget_name - var/target_lastloc = FALSE //Loc of target when arrested. - var/last_found = FALSE //There's a delay - var/threatlevel = FALSE - var/declare_arrests = FALSE // speak, you shall not, unless to Honk - var/idcheck = TRUE - var/fcheck = TRUE - var/check_records = TRUE - var/arrest_type = FALSE - var/weaponscheck = TRUE - var/bikehorn = /obj/item/bikehorn -/mob/living/simple_animal/bot/honkbot/Initialize(mapload) +/mob/living/simple_animal/bot/secbot/honkbot/Initialize(mapload) . = ..() - update_appearance() - bot_mode_flags |= BOT_MODE_AUTOPATROL // Doing this hurts my soul, but simplebot access reworks are for another day. var/datum/id_trim/job/clown_trim = SSid_access.trim_singletons_by_path[/datum/id_trim/job/clown] - access_card.add_access(clown_trim.access + clown_trim.wildcard_access) + //We're doing set_access instead to overwrite the sec access they get. + access_card.set_access(clown_trim.access + clown_trim.wildcard_access) prev_access = access_card.access.Copy() - var/static/list/loc_connections = list( - COMSIG_ATOM_ENTERED = .proc/on_entered, - ) - AddElement(/datum/element/connect_loc, loc_connections) -/mob/living/simple_animal/bot/honkbot/proc/limiting_spam_false() //used for addtimer - limiting_spam = FALSE - -/mob/living/simple_animal/bot/honkbot/proc/sensor_blink() - icon_state = "honkbot-c" - addtimer(CALLBACK(src, /atom/.proc/update_appearance), 0.5 SECONDS, TIMER_OVERRIDE|TIMER_UNIQUE) - -//honkbots react with sounds. -/mob/living/simple_animal/bot/honkbot/proc/react_ping() - playsound(src, 'sound/machines/ping.ogg', 50, TRUE, -1) //the first sound upon creation! - limiting_spam = TRUE - sensor_blink() - addtimer(CALLBACK(src, .proc/limiting_spam_false), 18) // calibrates before starting the honk - -/mob/living/simple_animal/bot/honkbot/proc/react_buzz() - playsound(src, 'sound/machines/buzz-sigh.ogg', 50, TRUE, -1) - sensor_blink() - -/mob/living/simple_animal/bot/honkbot/bot_reset() - ..() - target = null - oldtarget_name = null - set_anchored(FALSE) - SSmove_manager.stop_looping(src) - last_found = world.time - limiting_spam = FALSE - -/mob/living/simple_animal/bot/honkbot/proc/judgement_criteria() - var/final = NONE - if(check_records) - final |= JUDGE_RECORDCHECK - if(bot_cover_flags & BOT_COVER_EMAGGED) - final |= JUDGE_EMAGGED - return final - -/mob/living/simple_animal/bot/honkbot/proc/retaliate(mob/living/carbon/human/H) - var/judgement_criteria = judgement_criteria() - threatlevel = H.assess_threat(judgement_criteria) - threatlevel += 6 - if(threatlevel >= 4) - target = H - mode = BOT_HUNT - -/mob/living/simple_animal/bot/honkbot/attack_hand(mob/living/carbon/human/user, list/modifiers) - if(user.combat_mode) - retaliate(user) - addtimer(CALLBACK(src, .proc/react_buzz), 5) - return ..() - - -/mob/living/simple_animal/bot/honkbot/attackby(obj/item/W, mob/user, params) - if(W.tool_behaviour != TOOL_SCREWDRIVER && (W.force) && (!target) && (W.damtype != STAMINA) ) - retaliate(user) - addtimer(CALLBACK(src, .proc/react_buzz), 5) - ..() - -/mob/living/simple_animal/bot/honkbot/emag_act(mob/user) - ..() - if(!(bot_cover_flags & BOT_COVER_EMAGGED)) +/mob/living/simple_animal/bot/secbot/honkbot/on_entered(datum/source, atom/movable/AM) + if(!ismob(AM) || !(bot_mode_flags & BOT_MODE_ON)) return - if(user) - to_chat(user, span_danger("You short out [src]'s sound control system. It gives out an evil laugh!!")) - oldtarget_name = user.name - audible_message(span_danger("[src] gives out an evil laugh!")) - playsound(src, 'sound/machines/honkbot_evil_laugh.ogg', 75, TRUE, -1) // evil laughter - update_appearance() + if(prob(70)) + return + var/mob/living/carbon/entered_carbon = AM + if(!istype(entered_carbon) || !entered_carbon || in_range(src, target)) + return + knockOver(entered_carbon) -/mob/living/simple_animal/bot/honkbot/bullet_act(obj/projectile/Proj) - if((istype(Proj,/obj/projectile/beam)) || (istype(Proj,/obj/projectile/bullet) && (Proj.damage_type == BURN))||(Proj.damage_type == BRUTE) && (!Proj.nodamage && Proj.damage < health && ishuman(Proj.firer))) - retaliate(Proj.firer) - return ..() +/mob/living/simple_animal/bot/secbot/honkbot/knockOver(mob/living/carbon/tripped_target) + ..() + INVOKE_ASYNC(src, /mob/living/simple_animal/bot.proc/speak, "Honk!") + playsound(loc, 'sound/misc/sadtrombone.ogg', 50, TRUE, -1) + icon_state = "[initial(icon_state)]-c" + addtimer(CALLBACK(src, /atom.proc/update_appearance), 0.2 SECONDS) -/mob/living/simple_animal/bot/honkbot/UnarmedAttack(atom/A, proximity_flag, list/modifiers) +/mob/living/simple_animal/bot/secbot/honkbot/bot_reset() + ..() + limiting_spam = FALSE + +/mob/living/simple_animal/bot/secbot/honkbot/stun_attack(mob/living/carbon/current_target, harm = FALSE) // airhorn stun + if(limiting_spam) + return + + playsound(src, 'sound/items/AirHorn.ogg', 100, TRUE, -1) //HEEEEEEEEEEEENK!! + icon_state = "[initial(icon_state)]-c" + addtimer(CALLBACK(src, /atom.proc/update_appearance), 0.2 SECONDS) + if(!ishuman(current_target)) + current_target.stuttering = 20 + current_target.Paralyze(8 SECONDS) + addtimer(CALLBACK(src, .proc/limiting_spam_false), cooldowntime) + return + current_target.stuttering = 20 + var/obj/item/organ/ears/target_ears = current_target.getorganslot(ORGAN_SLOT_EARS) + if(target_ears && !HAS_TRAIT_FROM(current_target, TRAIT_DEAF, CLOTHING_TRAIT)) + target_ears.adjustEarDamage(0, 5) //far less damage than the H.O.N.K. + current_target.Jitter(5 SECONDS) + current_target.Paralyze(6 SECONDS) + if(client) //prevent spam from players + limiting_spam = TRUE + + if(bot_cover_flags & BOT_COVER_EMAGGED) // you really don't want to hit an emagged honkbot + threatlevel = 6 // will never let you go + else + //HONK once, then leave + var/judgement_criteria = judgement_criteria() + if(ishuman(current_target)) + var/mob/living/carbon/human/human_target = current_target + threatlevel = human_target.assess_threat(judgement_criteria) + threatlevel -= 6 + addtimer(CALLBACK(src, .proc/limiting_spam_false), cooldowntime) + + log_combat(src, current_target, "honked") + + current_target.visible_message( + span_danger("[src] honks [current_target]!"), \ + span_userdanger("[src] honks you!"), \ + ) + + target_lastloc = target.loc + back_to_idle() + +/mob/living/simple_animal/bot/secbot/honkbot/retaliate(mob/living/carbon/human/attacking_human) + ..() + playsound(src, 'sound/machines/buzz-sigh.ogg', 50, TRUE, -1) + icon_state = "[initial(icon_state)]-c" + addtimer(CALLBACK(src, /atom.proc/update_appearance), 0.2 SECONDS) + +/mob/living/simple_animal/bot/secbot/honkbot/UnarmedAttack(atom/attack_target, proximity_flag, list/modifiers) if(!(bot_mode_flags & BOT_MODE_ON)) return - if(HAS_TRAIT(src, TRAIT_HANDS_BLOCKED)) - return - if(iscarbon(A)) - var/mob/living/carbon/C = A - if(bot_cover_flags & BOT_COVER_EMAGGED) - honk_attack(A) - else - if(!C.IsParalyzed() || arrest_type) - stun_attack(A) - ..() - else if (!limiting_spam) //honking at the ground - bike_horn(A) + if(!limiting_spam) + bike_horn() + . = ..() +/mob/living/simple_animal/bot/secbot/honkbot/handle_automated_action() + . = ..() + if(!limiting_spam && prob(30)) + bike_horn() -/mob/living/simple_animal/bot/honkbot/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum) - if(istype(AM, /obj/item)) - playsound(src, honksound, 50, TRUE, -1) - var/obj/item/I = AM - var/mob/thrown_by = I.thrownby?.resolve() - if(I.throwforce < health && thrown_by && (istype(thrown_by, /mob/living/carbon/human))) - var/mob/living/carbon/human/H = thrown_by - retaliate(H) - ..() - -/mob/living/simple_animal/bot/honkbot/proc/bike_horn() //use bike_horn - if (bot_cover_flags & BOT_COVER_EMAGGED) //emagged honkbots will spam short and memorable sounds. - if (!limiting_spam) +/mob/living/simple_animal/bot/secbot/honkbot/start_handcuffing(mob/living/carbon/current_target) + if(bot_cover_flags & BOT_COVER_EMAGGED) //emagged honkbots will spam short and memorable sounds. + if(!limiting_spam) playsound(src, "honkbot_e", 50, FALSE) - limiting_spam = TRUE // prevent spam icon_state = "honkbot-e" - addtimer(CALLBACK(src, /atom/.proc/update_appearance), 3 SECONDS, TIMER_OVERRIDE|TIMER_UNIQUE) - addtimer(CALLBACK(src, .proc/limiting_spam_false), cooldowntimehorn) - return - if (!limiting_spam) + else if(!limiting_spam) playsound(src, honksound, 50, TRUE, -1) - limiting_spam = TRUE //prevent spam - sensor_blink() - addtimer(CALLBACK(src, .proc/limiting_spam_false), cooldowntimehorn) + icon_state = "[initial(icon_state)]-c" -/mob/living/simple_animal/bot/honkbot/proc/honk_attack(mob/living/carbon/C) // horn attack - if(!limiting_spam) - playsound(loc, honksound, 50, TRUE, -1) - limiting_spam = TRUE // prevent spam - sensor_blink() - addtimer(CALLBACK(src, .proc/limiting_spam_false), cooldowntimehorn) + limiting_spam = TRUE // prevent spam + addtimer(CALLBACK(src, .proc/limiting_spam_false), cooldowntimehorn) + addtimer(CALLBACK(src, /atom.proc/update_appearance), 3 SECONDS, TIMER_OVERRIDE|TIMER_UNIQUE) + back_to_idle() -/mob/living/simple_animal/bot/honkbot/proc/stun_attack(mob/living/carbon/C) // airhorn stun - if(!limiting_spam) - playsound(src, 'sound/items/AirHorn.ogg', 100, TRUE, -1) //HEEEEEEEEEEEENK!! - sensor_blink() - if(limiting_spam == 0) - if(ishuman(C)) - C.stuttering = 20 - var/obj/item/organ/ears/ears = C.getorganslot(ORGAN_SLOT_EARS) - if (ears && !HAS_TRAIT_FROM(C, TRAIT_DEAF, CLOTHING_TRAIT)) - ears.adjustEarDamage(0, 5) //far less damage than the H.O.N.K. - C.Jitter(50) - C.Paralyze(60) - var/mob/living/carbon/human/H = C - if(client) //prevent spam from players.. - limiting_spam = TRUE - if (bot_cover_flags & BOT_COVER_EMAGGED) // you really don't want to hit an emagged honkbot - threatlevel = 6 // will never let you go - else - //HONK once, then leave - var/judgement_criteria = judgement_criteria() - threatlevel = H.assess_threat(judgement_criteria) - threatlevel -= 6 - target = oldtarget_name - addtimer(CALLBACK(src, .proc/limiting_spam_false), cooldowntime) +//Honkbots don't care for NAP violations +/mob/living/simple_animal/bot/secbot/honkbot/check_nap_violations() + return TRUE - log_combat(src,C,"honked") +/mob/living/simple_animal/bot/secbot/honkbot/proc/limiting_spam_false() //used for addtimer + limiting_spam = FALSE - C.visible_message(span_danger("[src] honks [C]!"),\ - span_userdanger("[src] honks you!")) - else - C.stuttering = 20 - C.Paralyze(80) - addtimer(CALLBACK(src, .proc/limiting_spam_false), cooldowntime) - - -/mob/living/simple_animal/bot/honkbot/handle_automated_action() - if(!..()) +/mob/living/simple_animal/bot/secbot/honkbot/proc/bike_horn() // horn attack + if(limiting_spam) return - - switch(mode) - - if(BOT_IDLE) // idle - - SSmove_manager.stop_looping(src) - look_for_perp() - if(!mode && bot_mode_flags & BOT_MODE_AUTOPATROL) - mode = BOT_START_PATROL - - if(BOT_HUNT) - - // if can't reach perp for long enough, go idle - if(frustration >= 5) //gives up easier than beepsky - SSmove_manager.stop_looping(src) - back_to_idle() - return - - if(target) // make sure target exists - if(Adjacent(target) && isturf(target.loc)) - - if(threatlevel <= 4) - honk_attack(target) - else - if(threatlevel >= 6) - set waitfor = 0 - stun_attack(target) - set_anchored(FALSE) - target_lastloc = target.loc - return - - else // not next to perp - var/turf/olddist = get_dist(src, target) - SSmove_manager.move_to(src, target, 1, 2) - if((get_dist(src, target)) >= (olddist)) - frustration++ - else - frustration = 0 - else - back_to_idle() - - - if(BOT_START_PATROL) - look_for_perp() - start_patrol() - - if(BOT_PATROL) - look_for_perp() - bot_patrol() - - return - -/mob/living/simple_animal/bot/honkbot/proc/back_to_idle() - set_anchored(FALSE) - mode = BOT_IDLE - target = null - last_found = world.time - frustration = 0 - INVOKE_ASYNC(src, .proc/handle_automated_action) //responds quickly - -/mob/living/simple_animal/bot/honkbot/proc/back_to_hunt() - set_anchored(FALSE) - frustration = 0 - mode = BOT_HUNT - INVOKE_ASYNC(src, .proc/handle_automated_action) // responds quickly - -/mob/living/simple_animal/bot/honkbot/proc/look_for_perp() - set_anchored(FALSE) - for (var/mob/living/carbon/C in view(7,src)) - if((C.stat) || (C.handcuffed)) - continue - - if((C.name == oldtarget_name) && (world.time < last_found + 100)) - continue - - var/judgement_criteria = judgement_criteria() - threatlevel = C.assess_threat(judgement_criteria) - - if(threatlevel <= 3) - if(C in view(4,src)) //keep the range short for patrolling - if(!limiting_spam) - bike_horn() - - else if(threatlevel >= 10) - bike_horn() //just spam the shit outta this - - else if(threatlevel >= 4) - if(!limiting_spam) - target = C - oldtarget_name = C.name - bike_horn() - speak("Honk!") - visible_message("[src] starts chasing [C.name]!") - mode = BOT_HUNT - INVOKE_ASYNC(src, .proc/handle_automated_action) - break - else - continue - -/mob/living/simple_animal/bot/honkbot/explode() - visible_message(span_boldannounce("[src] blows apart!")) - var/atom/Tsec = drop_location() - //doesn't drop cardboard nor its assembly, since its a very frail material. - new bikehorn(Tsec) - new /obj/item/assembly/prox_sensor(Tsec) - - var/datum/effect_system/spark_spread/s = new - s.set_up(3, 1, src) - s.start() - - new /obj/effect/decal/cleanable/oil(loc) - ..() - -/mob/living/simple_animal/bot/honkbot/attack_alien(mob/living/carbon/alien/user, list/modifiers) - ..() - if(!isalien(target)) - target = user - mode = BOT_HUNT - -/mob/living/simple_animal/bot/honkbot/proc/on_entered(datum/source, atom/movable/AM) - SIGNAL_HANDLER - if(ismob(AM) && (bot_mode_flags & BOT_MODE_ON)) //only if its online - if(prob(30)) //you're far more likely to trip on a honkbot - var/mob/living/carbon/C = AM - if(!istype(C) || !C || in_range(src, target)) - return - C.visible_message("[pick( \ - "[C] dives out of [src]'s way!", \ - "[C] stumbles over [src]!", \ - "[C] jumps out of [src]'s path!", \ - "[C] trips over [src] and falls!", \ - "[C] topples over [src]!", \ - "[C] leaps out of [src]'s way!")]") - C.Paralyze(10) - playsound(loc, 'sound/misc/sadtrombone.ogg', 50, TRUE, -1) - if(!client) - INVOKE_ASYNC(src, /mob/living/simple_animal/bot/proc/speak, "Honk!") - sensor_blink() - return + playsound(loc, honksound, 50, TRUE, -1) + limiting_spam = TRUE // prevent spam + icon_state = "[initial(icon_state)]-c" + addtimer(CALLBACK(src, /atom.proc/update_appearance), 0.2 SECONDS) + addtimer(CALLBACK(src, .proc/limiting_spam_false), cooldowntimehorn) diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm index e55e876ba3b..e33c6cf9928 100644 --- a/code/modules/mob/living/simple_animal/bot/secbot.dm +++ b/code/modules/mob/living/simple_animal/bot/secbot.dm @@ -1,6 +1,6 @@ /mob/living/simple_animal/bot/secbot name = "\improper Securitron" - desc = "A little security robot. He looks less than thrilled." + desc = "A little security robot. He looks less than thrilled." icon = 'icons/mob/aibots.dmi' icon_state = "secbot" density = FALSE @@ -107,9 +107,6 @@ access_card.add_access(det_trim.access + det_trim.wildcard_access) prev_access = access_card.access.Copy() - //SECHUD - var/datum/atom_hud/secsensor = GLOB.huds[DATA_HUD_SECURITY_ADVANCED] - secsensor.add_hud_to(src) var/static/list/loc_connections = list( COMSIG_ATOM_ENTERED = .proc/on_entered, ) @@ -232,12 +229,18 @@ if(user) to_chat(user, span_danger("You short out [src]'s target assessment circuits.")) oldtarget_name = user.name - audible_message(span_danger("[src] buzzes oddly!")) + + if(bot_type == HONK_BOT) + audible_message(span_danger("[src] gives out an evil laugh!")) + playsound(src, 'sound/machines/honkbot_evil_laugh.ogg', 75, TRUE, -1) // evil laughter + else + audible_message(span_danger("[src] buzzes oddly!")) + security_mode_flags &= ~SECBOT_DECLARE_ARRESTS update_appearance() /mob/living/simple_animal/bot/secbot/bullet_act(obj/projectile/Proj) - if(istype(Proj , /obj/projectile/beam)||istype(Proj, /obj/projectile/bullet)) + if(istype(Proj, /obj/projectile/beam) || istype(Proj, /obj/projectile/bullet)) if((Proj.damage_type == BURN) || (Proj.damage_type == BRUTE)) if(!Proj.nodamage && Proj.damage < src.health && ishuman(Proj.firer)) retaliate(Proj.firer) @@ -273,11 +276,16 @@ playsound(src, 'sound/weapons/cablecuff.ogg', 30, TRUE, -2) current_target.visible_message(span_danger("[src] is trying to put zipties on [current_target]!"),\ span_userdanger("[src] is trying to put zipties on you!")) - addtimer(CALLBACK(src, .proc/handcuff_target, target), 60) + addtimer(CALLBACK(src, .proc/handcuff_target, target), 6 SECONDS) /mob/living/simple_animal/bot/secbot/proc/handcuff_target(mob/living/carbon/current_target) - if(!(bot_mode_flags & BOT_MODE_ON) || !Adjacent(current_target) || !isturf(current_target.loc)) //if he's in a closet or not adjacent, we cancel cuffing. + if(!(bot_mode_flags & BOT_MODE_ON)) //if he's in a closet or not adjacent, we cancel cuffing. return + if(!isturf(current_target.loc)) + return + if(!Adjacent(current_target)) + return + if(!current_target.handcuffed) current_target.set_handcuffed(new /obj/item/restraints/handcuffs/cable/zipties/used(current_target)) current_target.update_handcuffed() @@ -294,12 +302,12 @@ if(harm) weapon.attack(current_target, src) if(ishuman(current_target)) - current_target.StaminaKnockdown(60,TRUE) // SKYRAT EDIT - ORIGINAL: current_target.Paralyze(100) current_target.stuttering = 5 + current_target.StaminaKnockdown(60,TRUE) // SKYRAT EDIT CHANGE var/mob/living/carbon/human/human_target = current_target threat = human_target.assess_threat(judgement_criteria, weaponcheck = CALLBACK(src, .proc/check_for_weapons)) else - current_target.StaminaKnockdown(60,TRUE) // SKYRAT EDIT - ORIGINAL: current_target.Paralyze(100) + current_target.StaminaKnockdown(60,TRUE) // SKYRAT EDIT CHANGE current_target.stuttering = 5 threat = current_target.assess_threat(judgement_criteria, weaponcheck = CALLBACK(src, .proc/check_for_weapons)) @@ -310,6 +318,9 @@ current_target.visible_message(span_danger("[src] stuns [current_target]!"),\ span_userdanger("[src] stuns you!")) + target_lastloc = target.loc + mode = BOT_PREP_ARREST + /mob/living/simple_animal/bot/secbot/handle_automated_action() . = ..() if(!.) @@ -339,12 +350,7 @@ else stun_attack(target) - //mode = BOT_PREP_ARREST SKYRAT EDIT CHANGE BELOW - //set_anchored(TRUE) - target_lastloc = target.loc - if(target.incapacitated()) //SKYRAT EDIT ADDITION - mode = BOT_PREP_ARREST - set_anchored(TRUE) + set_anchored(TRUE) return // not next to perp @@ -357,7 +363,7 @@ if(BOT_PREP_ARREST) // preparing to arrest target // see if he got away. If he's no no longer adjacent or inside a closet or about to get up, we hunt again. - if(!Adjacent(target) || !isturf(target.loc) || (target.AmountParalyzed() < 40 && target.staminaloss < STAMINA_THRESHOLD_SOFTCRIT)) //SKYRAT EDIT CHANGE: if(!Adjacent(target) || !isturf(target.loc) || target.AmountParalyzed() < 40) + if(!Adjacent(target) || !isturf(target.loc) || (target.AmountParalyzed() < 40 && target.staminaloss < STAMINA_THRESHOLD_SOFTCRIT)) //SKYRAT EDIT CHANGE back_to_hunt() return @@ -419,7 +425,7 @@ /mob/living/simple_animal/bot/secbot/proc/look_for_perp() set_anchored(FALSE) var/judgement_criteria = judgement_criteria() - for(var/mob/living/carbon/nearby_carbons in view(7,src)) //Let's find us a criminal + for(var/mob/living/carbon/nearby_carbons in view(7, src)) //Let's find us a criminal if((nearby_carbons.stat) || (nearby_carbons.handcuffed)) continue @@ -434,11 +440,17 @@ if(threatlevel >= 4) target = nearby_carbons oldtarget_name = nearby_carbons.name - speak("Level [threatlevel] infraction alert!") - if(bot_type == ADVANCED_SEC_BOT) - playsound(src, pick('sound/voice/ed209_20sec.ogg', 'sound/voice/edplaceholder.ogg'), 50, FALSE) - else - playsound(src, pick('sound/voice/beepsky/criminal.ogg', 'sound/voice/beepsky/justice.ogg', 'sound/voice/beepsky/freeze.ogg'), 50, FALSE) + switch(bot_type) + if(ADVANCED_SEC_BOT) + speak("Level [threatlevel] infraction alert!") + playsound(src, pick('sound/voice/ed209_20sec.ogg', 'sound/voice/edplaceholder.ogg'), 50, FALSE) + if(HONK_BOT) + speak("Honk!") + playsound(src, pick('sound/items/bikehorn.ogg'), 50, FALSE) + else + speak("Level [threatlevel] infraction alert!") + playsound(src, pick('sound/voice/beepsky/criminal.ogg', 'sound/voice/beepsky/justice.ogg', 'sound/voice/beepsky/freeze.ogg'), 50, FALSE) + visible_message("[src] points at [nearby_carbons.name]!") mode = BOT_HUNT INVOKE_ASYNC(src, .proc/handle_automated_action) @@ -452,33 +464,38 @@ /mob/living/simple_animal/bot/secbot/explode() visible_message(span_boldannounce("[src] blows apart!")) var/atom/Tsec = drop_location() - if(bot_type == ADVANCED_SEC_BOT) - var/obj/item/bot_assembly/ed209/ed_assembly = new(Tsec) - ed_assembly.build_step = ASSEMBLY_FIRST_STEP - ed_assembly.add_overlay("hs_hole") - ed_assembly.created_name = name - new /obj/item/assembly/prox_sensor(Tsec) - /* SKYRAT EDIT REMOVAL START - no more disabler farms - var/obj/item/gun/energy/disabler/disabler_gun = new(Tsec) - disabler_gun.cell.charge = 0 - disabler_gun.update_appearance() - */ // SKYRAT EDIT END - if(prob(50)) - new /obj/item/bodypart/l_leg/robot(Tsec) - if(prob(25)) - new /obj/item/bodypart/r_leg/robot(Tsec) - if(prob(25))//50% chance for a helmet OR vest + switch(bot_type) + if(ADVANCED_SEC_BOT) + var/obj/item/bot_assembly/ed209/ed_assembly = new(Tsec) + ed_assembly.build_step = ASSEMBLY_FIRST_STEP + ed_assembly.add_overlay("hs_hole") + ed_assembly.created_name = name + new /obj/item/assembly/prox_sensor(Tsec) + var/obj/item/gun/energy/disabler/disabler_gun = new(Tsec) + disabler_gun.cell.charge = 0 + disabler_gun.update_appearance() if(prob(50)) - new /obj/item/clothing/head/helmet(Tsec) - else - new /obj/item/clothing/suit/armor/vest(Tsec) - else - var/obj/item/bot_assembly/secbot/secbot_assembly = new(Tsec) - secbot_assembly.build_step = ASSEMBLY_FIRST_STEP - secbot_assembly.add_overlay("hs_hole") - secbot_assembly.created_name = name - new /obj/item/assembly/prox_sensor(Tsec) - // drop_part(baton_type, Tsec) // SKYRAT EDIT REMOVAL - no more baton farms + new /obj/item/bodypart/l_leg/robot(Tsec) + if(prob(25)) + new /obj/item/bodypart/r_leg/robot(Tsec) + if(prob(25))//50% chance for a helmet OR vest + if(prob(50)) + new /obj/item/clothing/head/helmet(Tsec) + else + new /obj/item/clothing/suit/armor/vest(Tsec) + if(HONK_BOT) + var/obj/item/bot_assembly/honkbot/honkbot_assembly = new(Tsec) + honkbot_assembly.build_step = ASSEMBLY_FIRST_STEP + honkbot_assembly.created_name = name + new /obj/item/assembly/prox_sensor(Tsec) + drop_part(baton_type, Tsec) + else + var/obj/item/bot_assembly/secbot/secbot_assembly = new(Tsec) + secbot_assembly.build_step = ASSEMBLY_FIRST_STEP + secbot_assembly.add_overlay("hs_hole") + secbot_assembly.created_name = name + new /obj/item/assembly/prox_sensor(Tsec) + drop_part(baton_type, Tsec) do_sparks(3, TRUE, src) diff --git a/modular_skyrat/modules/secbotsrback/code/botpacks.dm b/modular_skyrat/modules/secbotsrback/code/botpacks.dm deleted file mode 100644 index 2c34a9a6251..00000000000 --- a/modular_skyrat/modules/secbotsrback/code/botpacks.dm +++ /dev/null @@ -1,20 +0,0 @@ -/obj/item/botpack - name = "robot part pack" - desc = "A pack of robot parts." - icon = 'modular_skyrat/modules/secbotsrback/icons/secbotpack.dmi' - icon_state = "beepskybox" - w_class = WEIGHT_CLASS_BULKY - -/obj/item/botpack/secbot - name = "securitron part pack" - desc = "A pack of robot parts. This one makes a Securitron" - icon = 'modular_skyrat/modules/secbotsrback/icons/secbotpack.dmi' - icon_state = "beepskybox" - w_class = WEIGHT_CLASS_BULKY - -/obj/item/botpack/ed209 - name = "ED-209 security bot part pack" - desc = "A pack of robot parts. This one makes an ED-209" - icon = 'modular_skyrat/modules/secbotsrback/icons/secbotpack.dmi' - icon_state = "ed209box" - w_class = WEIGHT_CLASS_BULKY diff --git a/modular_skyrat/modules/secbotsrback/code/packs.dm b/modular_skyrat/modules/secbotsrback/code/packs.dm deleted file mode 100644 index a38dca52370..00000000000 --- a/modular_skyrat/modules/secbotsrback/code/packs.dm +++ /dev/null @@ -1,19 +0,0 @@ -/datum/supply_pack/science/secbotpack - name = "Securitron Parts Crate" - desc = "The parts you need to replace those unrobust security officers with a robust robot army! Contains parts for one Securitron brand security robot. Requires Security access to open." - cost = CARGO_CRATE_VALUE * 4 - access = ACCESS_SECURITY - access_view = ACCESS_SECURITY - contains = list(/obj/item/botpack/secbot) - crate_name = "securitron part crate" - crate_type = /obj/structure/closet/crate/secure/science - -/datum/supply_pack/science/ed209pack - name = "ED-209 Parts Crate" - desc = "The parts you need to ahnillate and destroy crime, permanently! Contains parts for one ED-209 brand security robot. Requires Security access to open." - cost = CARGO_CRATE_VALUE * 5 - access = ACCESS_SECURITY - access_view = ACCESS_SECURITY - contains = list(/obj/item/botpack/ed209) - crate_name = "ED-209 part crate" - crate_type = /obj/structure/closet/crate/secure/science diff --git a/modular_skyrat/modules/secbotsrback/code/recipes.dm b/modular_skyrat/modules/secbotsrback/code/recipes.dm deleted file mode 100644 index 8a782e01b5d..00000000000 --- a/modular_skyrat/modules/secbotsrback/code/recipes.dm +++ /dev/null @@ -1,27 +0,0 @@ -/datum/crafting_recipe/ed209 - name = "ED209" - result = /mob/living/simple_animal/bot/secbot/ed209 - reqs = list(/obj/item/robot_suit = 1, - /obj/item/clothing/head/helmet = 1, - /obj/item/clothing/suit/armor/vest = 1, - /obj/item/bodypart/l_leg/robot = 1, - /obj/item/bodypart/r_leg/robot = 1, - /obj/item/stack/sheet/iron = 1, - /obj/item/stack/cable_coil = 1, - /obj/item/botpack/ed209 = 1, - /obj/item/assembly/prox_sensor = 1) - tool_behaviors = list(TOOL_WELDER, TOOL_SCREWDRIVER) - time = 60 - category = CAT_ROBOT - -/datum/crafting_recipe/secbot - name = "Secbot" - result = /mob/living/simple_animal/bot/secbot - reqs = list(/obj/item/assembly/signaler = 1, - /obj/item/clothing/head/helmet/sec = 1, - /obj/item/botpack/secbot = 1, - /obj/item/assembly/prox_sensor = 1, - /obj/item/bodypart/r_arm/robot = 1) - tool_behaviors = list(TOOL_WELDER) - time = 60 - category = CAT_ROBOT diff --git a/modular_skyrat/modules/secbotsrback/icons/secbotpack.dmi b/modular_skyrat/modules/secbotsrback/icons/secbotpack.dmi deleted file mode 100644 index 79fc8d18f23..00000000000 Binary files a/modular_skyrat/modules/secbotsrback/icons/secbotpack.dmi and /dev/null differ diff --git a/modular_skyrat/modules/secbotsrback/readme.md b/modular_skyrat/modules/secbotsrback/readme.md deleted file mode 100644 index a845c1adda4..00000000000 --- a/modular_skyrat/modules/secbotsrback/readme.md +++ /dev/null @@ -1,29 +0,0 @@ -https://github.com/Skyrat-SS13/Skyrat-tg/pull/5085 - -## Title: Security bots are back - -MODULE ID: SECBOTSRBACK - -### Description: - -Adds 2 new items, security robot part kits, orderable from cargo, that are used in the making of securitrons and ED-209s. The bots also no longer drop stunbatons or disablers - -### TG Proc Changes: - -- code/modules/mob/living/simple_animal/bot/secbot.dm - removed disabler/baton drops - -### Defines: - -- N/A - -### Master file additions - -- N/A - -### Included files that are not contained in this module: - -- N/A - - -### Credits: -- FlamingLily diff --git a/tgstation.dme b/tgstation.dme index 56db885f762..c5363b42574 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -5234,9 +5234,6 @@ #include "modular_skyrat\modules\sec_haul\code\security_medic\secmed_clothes.dm" #include "modular_skyrat\modules\sec_haul\code\security_medic\security_medic.dm" #include "modular_skyrat\modules\sec_haul\code\security_sergeant\secseg_clothes.dm" -#include "modular_skyrat\modules\secbotsrback\code\botpacks.dm" -#include "modular_skyrat\modules\secbotsrback\code\packs.dm" -#include "modular_skyrat\modules\secbotsrback\code\recipes.dm" #include "modular_skyrat\modules\server_overflow\code\chat_link.dm" #include "modular_skyrat\modules\server_overflow\code\client_procs.dm" #include "modular_skyrat\modules\server_overflow\code\server_connect_panel.dm"