diff --git a/code/__DEFINES/robots.dm b/code/__DEFINES/robots.dm index 433e3d9087d..4c172c14656 100644 --- a/code/__DEFINES/robots.dm +++ b/code/__DEFINES/robots.dm @@ -177,6 +177,14 @@ ///Whether we will stun & cuff or endlessly stun #define SECBOT_HANDCUFF_TARGET (1<<4) +DEFINE_BITFIELD(security_mode_flags, list( + "SECBOT_DECLARE_ARRESTS" = SECBOT_DECLARE_ARRESTS, + "SECBOT_CHECK_IDS" = SECBOT_CHECK_IDS, + "SECBOT_CHECK_WEAPONS" = SECBOT_CHECK_WEAPONS, + "SECBOT_CHECK_RECORDS" = SECBOT_CHECK_RECORDS, + "SECBOT_HANDCUFF_TARGET" = SECBOT_HANDCUFF_TARGET, +)) + //MedBOT defines ///Whether to declare if someone (we are healing) is in critical condition #define MEDBOT_DECLARE_CRIT (1<<0) @@ -184,3 +192,22 @@ #define MEDBOT_STATIONARY_MODE (1<<1) ///Whether the bot will randomly speak from time to time. This will not actually prevent all speech. #define MEDBOT_SPEAK_MODE (1<<2) + +DEFINE_BITFIELD(medical_mode_flags, list( + "MEDBOT_DECLARE_CRIT" = MEDBOT_DECLARE_CRIT, + "MEDBOT_STATIONARY_MODE" = MEDBOT_STATIONARY_MODE, + "MEDBOT_SPEAK_MODE" = MEDBOT_SPEAK_MODE, +)) + +//cleanBOT defines on what to clean +#define CLEANBOT_CLEAN_BLOOD (1<<0) +#define CLEANBOT_CLEAN_TRASH (1<<1) +#define CLEANBOT_CLEAN_PESTS (1<<2) +#define CLEANBOT_CLEAN_DRAWINGS (1<<3) + +DEFINE_BITFIELD(janitor_mode_flags, list( + "CLEANBOT_CLEAN_BLOOD" = CLEANBOT_CLEAN_BLOOD, + "CLEANBOT_CLEAN_TRASH" = CLEANBOT_CLEAN_TRASH, + "CLEANBOT_CLEAN_PESTS" = CLEANBOT_CLEAN_PESTS, + "CLEANBOT_CLEAN_DRAWINGS" = CLEANBOT_CLEAN_DRAWINGS, +)) diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index 5b2ad2a7359..223bc5a279a 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -37,8 +37,6 @@ var/maints_access_required = list(ACCESS_ROBOTICS) ///The Robot arm attached to this robot - has a 50% chance to drop on death. var/robot_arm = /obj/item/bodypart/r_arm/robot - ///People currently looking into a bot's UI panel. - var/list/users = list() ///The inserted (if any) pAI in this bot. var/obj/item/pai_card/paicard ///The type of bot it is, for radio control. @@ -231,7 +229,7 @@ /mob/living/simple_animal/bot/death(gibbed) explode() - ..() + return ..() /mob/living/simple_animal/bot/proc/explode() visible_message(span_boldnotice("[src] blows apart!")) @@ -257,7 +255,7 @@ if(user) log_combat(user, src, "emagged") return - else //Bot is unlocked, but the maint panel has not been opened with a screwdriver yet. + else //Bot is unlocked, but the maint panel has not been opened with a screwdriver (or through the UI) yet. to_chat(user, span_warning("You need to open maintenance panel first!")) /mob/living/simple_animal/bot/examine(mob/user) @@ -284,7 +282,7 @@ /mob/living/simple_animal/bot/adjustHealth(amount, updating_health = TRUE, forced = FALSE) if(amount > 0 && prob(10)) new /obj/effect/decal/cleanable/oil(loc) - . = ..() + return ..() /mob/living/simple_animal/bot/updatehealth() ..() @@ -525,7 +523,7 @@ continue var/scan_result = process_scan(scan) //Some bots may require additional processing when a result is selected. - if(scan_result) + if(!isnull(scan_result)) return scan_result //When the scan finds a target, run bot specific processing to select it for the next step. Empty by default. @@ -533,11 +531,14 @@ return scan_target /mob/living/simple_animal/bot/proc/check_bot(targ) - var/turf/T = get_turf(targ) - if(T) - for(var/C in T.contents) - if(istype(C,type) && (C != src)) //Is there another bot there already? If so, let's skip it so we dont all atack on top of eachother. - return TRUE //Let's abort if we find a bot so we dont have to keep rechecking + var/turf/target_turf = get_turf(targ) + if(!target_turf) + return FALSE + for(var/turf_contents in target_turf.contents) + //Is there another bot there already? If so, let's skip it so we dont all atack on top of eachother. + if(istype(turf_contents, type) && (turf_contents != src)) + return TRUE //Let's abort if we find a bot so we dont have to keep rechecking + return FALSE /mob/living/simple_animal/bot/proc/add_to_ignore(subject) if(ignore_list.len < 50) //This will help keep track of them, so the bot is always trying to reach a blocked spot. @@ -643,6 +644,7 @@ Pass a positive integer as an argument to override a bot's default speed. access_card.set_access(prev_access) tries = 0 mode = BOT_IDLE + ignore_list = list() diag_hud_set_botstat() diag_hud_set_botmode() diff --git a/code/modules/mob/living/simple_animal/bot/cleanbot.dm b/code/modules/mob/living/simple_animal/bot/cleanbot.dm index 49246c6fbb2..e4b7531ec8f 100644 --- a/code/modules/mob/living/simple_animal/bot/cleanbot.dm +++ b/code/modules/mob/living/simple_animal/bot/cleanbot.dm @@ -1,3 +1,5 @@ +#define CLEANBOT_CLEANING_TIME (1 SECONDS) + //Cleanbot /mob/living/simple_animal/bot/cleanbot name = "\improper Cleanbot" @@ -12,33 +14,28 @@ maints_access_required = list(ACCESS_ROBOTICS, ACCESS_JANITOR) radio_key = /obj/item/encryptionkey/headset_service - radio_channel = RADIO_CHANNEL_SERVICE //Service + radio_channel = RADIO_CHANNEL_SERVICE //Service //true bot_type = CLEAN_BOT hackables = "cleaning software" path_image_color = "#993299" - var/blood = 1 - var/trash = 0 - var/pests = 0 - var/drawn = 0 + ///Flags indicating what kind of cleanables we should scan for to set as our target to clean. + var/janitor_mode_flags = CLEANBOT_CLEAN_BLOOD +// Selections: CLEANBOT_CLEAN_BLOOD | CLEANBOT_CLEAN_TRASH | CLEANBOT_CLEAN_PESTS | CLEANBOT_CLEAN_DRAWINGS - var/base_icon = "cleanbot" /// icon_state to use in update_icon_state + ///the base icon state, used in updating icons. + var/base_icon = "cleanbot" + ///List of things cleanbots can target for cleaning. var/list/target_types + ///The current bot's target. var/atom/target - var/max_targets = 50 //Maximum number of targets a cleanbot can ignore. - var/closest_dist - var/closest_loc - var/failed_steps - var/next_dest - var/next_dest_loc + ///Currently attached weapon, usually a knife. var/obj/item/weapon - var/weapon_orig_force = 0 - var/chosen_name - - /// The time it takes for the cleanbot to clean something. - var/cleaning_time = 1 SECONDS + /// if we have all the top titles, grant achievements to living mobs that gaze upon our cleanbot god + var/ascended = FALSE + ///List of all stolen names the cleanbot currently has. var/list/stolen_valor = list() var/static/list/officers_titles = list( @@ -77,19 +74,19 @@ JOB_LAWYER = "Esq.", ) + ///What ranks are prefixes to the name. var/static/list/prefixes = list( command_titles, security_titles, engineering_titles, ) + ///What ranks are suffixes to the name. var/static/list/suffixes = list( research_titles, medical_titles, legal_titles, ) - var/ascended = FALSE // if we have all the top titles, grant achievements to living mobs that gaze upon our cleanbot god - /mob/living/simple_animal/bot/cleanbot/autopatrol bot_mode_flags = BOT_MODE_ON | BOT_MODE_AUTOPATROL | BOT_MODE_REMOTE_ENABLED | BOT_MODE_PAI_CONTROLLABLE @@ -98,79 +95,38 @@ maints_access_required = list(ACCESS_ROBOTICS, ACCESS_JANITOR, ACCESS_MEDICAL) bot_mode_flags = ~(BOT_MODE_ON | BOT_MODE_REMOTE_ENABLED) -/mob/living/simple_animal/bot/cleanbot/proc/deputize(obj/item/W, mob/user) - if(in_range(src, user) && user.transferItemToLoc(W, src)) - balloon_alert(user, "attached") - weapon = W - weapon_orig_force = weapon.force - if(!(bot_cover_flags & BOT_COVER_EMAGGED)) - weapon.force = weapon.force / 2 - add_overlay(image(icon=weapon.lefthand_file,icon_state=weapon.inhand_icon_state)) - return TRUE - balloon_alert(user, "couldn't attach!") - return FALSE - -/mob/living/simple_animal/bot/cleanbot/proc/update_titles() - var/working_title = "" - - ascended = TRUE - - for(var/all_prefixes as anything in prefixes) - for(var/prefix_titles as anything in all_prefixes) - if(prefix_titles in stolen_valor) - working_title += all_prefixes[prefix_titles] + " " - if(prefix_titles in officers_titles) - commissioned = TRUE - else - ascended = FALSE // we didn't have the first entry in the list if we got here, so we're not achievement worthy yet - - working_title += chosen_name - - for(var/suf in suffixes) - for(var/title in suf) - if(title in stolen_valor) - working_title += " " + suf[title] - break - else - ascended = FALSE - - name = working_title - -/mob/living/simple_animal/bot/cleanbot/examine(mob/user) - . = ..() - if(weapon) - . += "[span_warning("Is that \a [weapon] taped to it...?")]" - - if(ascended && user.stat == CONSCIOUS && user.client) - user.client.give_award(/datum/award/achievement/misc/cleanboss, user) - /mob/living/simple_animal/bot/cleanbot/Initialize(mapload) . = ..() - AddComponent(/datum/component/cleaner, cleaning_time, on_cleaned_callback=CALLBACK(src, /atom/.proc/update_icon_state)) + AddComponent(/datum/component/cleaner, CLEANBOT_CLEANING_TIME, \ + on_cleaned_callback = CALLBACK(src, /atom/.proc/update_appearance, UPDATE_ICON)) - chosen_name = name get_targets() - update_icon_state() + update_appearance(UPDATE_ICON) // Doing this hurts my soul, but simplebot access reworks are for another day. var/datum/id_trim/job/jani_trim = SSid_access.trim_singletons_by_path[/datum/id_trim/job/janitor] access_card.add_access(jani_trim.access + jani_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) GLOB.janitor_devices += src /mob/living/simple_animal/bot/cleanbot/Destroy() GLOB.janitor_devices -= src if(weapon) - var/atom/Tsec = drop_location() - weapon.force = weapon_orig_force - drop_part(weapon, Tsec) + var/atom/drop_loc = drop_location() + weapon.force = initial(weapon.force) + drop_part(weapon, drop_loc) return ..() +/mob/living/simple_animal/bot/cleanbot/examine(mob/user) + . = ..() + if(!weapon) + return + . += "[span_warning("Is that \a [weapon] taped to it...?")]" + + if(ascended && user.stat == CONSCIOUS && user.client) + user.client.give_award(/datum/award/achievement/misc/cleanboss, user) + /mob/living/simple_animal/bot/cleanbot/update_icon_state() . = ..() switch(mode) @@ -179,101 +135,120 @@ else icon_state = "[base_icon][get_bot_flag(bot_mode_flags, BOT_MODE_ON)]" +/mob/living/simple_animal/bot/cleanbot/vv_edit_var(var_name, var_value) + . = ..() + if(var_name == NAMEOF(src, base_icon)) + update_appearance(UPDATE_ICON) + +/mob/living/simple_animal/bot/cleanbot/proc/deputize(obj/item/knife, mob/user) + if(!in_range(src, user) || !user.transferItemToLoc(knife, src)) + balloon_alert(user, "couldn't attach!") + return FALSE + balloon_alert(user, "attached!") + weapon = knife + if(!(bot_cover_flags & BOT_COVER_EMAGGED)) + weapon.force = weapon.force / 2 + add_overlay(image(icon = weapon.lefthand_file, icon_state = weapon.inhand_icon_state)) + var/static/list/loc_connections = list( + COMSIG_ATOM_ENTERED = .proc/on_entered, + ) + AddElement(/datum/element/connect_loc, loc_connections) + return TRUE + +/mob/living/simple_animal/bot/cleanbot/proc/update_titles() + name = initial(name) //reset the name + ascended = TRUE + + for(var/title in (prefixes + suffixes)) + for(var/title_name in title) + if(!(title_name in stolen_valor)) + ascended = FALSE + continue + + if(title_name in officers_titles) + commissioned = TRUE + if(title in prefixes) + name = title[title_name] + " [name]" + if(title in suffixes) + name = "[name] " + title[title_name] + /mob/living/simple_animal/bot/cleanbot/bot_reset() - ..() - if(weapon && bot_cover_flags & BOT_COVER_EMAGGED) - weapon.force = weapon_orig_force - ignore_list = list() //Allows the bot to clean targets it previously ignored due to being unreachable. + . = ..() target = null /mob/living/simple_animal/bot/cleanbot/proc/on_entered(datum/source, atom/movable/AM) SIGNAL_HANDLER + if(!weapon || !has_gravity() || !iscarbon(AM)) + return - zone_selected = pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) - if(weapon && has_gravity() && ismob(AM)) - var/mob/living/carbon/C = AM - if(!istype(C)) - return - - if(!(C.job in stolen_valor)) - stolen_valor += C.job + var/mob/living/carbon/stabbed_carbon = AM + if(!(stabbed_carbon.mind.assigned_role.title in stolen_valor)) + stolen_valor += stabbed_carbon.mind.assigned_role.title update_titles() - INVOKE_ASYNC(weapon, /obj/item.proc/attack, C, src) - C.Knockdown(20) + zone_selected = pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) + INVOKE_ASYNC(weapon, /obj/item.proc/attack, stabbed_carbon, src) + stabbed_carbon.Knockdown(20) /mob/living/simple_animal/bot/cleanbot/attackby(obj/item/attacking_item, mob/living/user, params) if(istype(attacking_item, /obj/item/knife) && !user.combat_mode) - to_chat(user, span_notice("You start attaching \the [attacking_item] to \the [src]...")) + balloon_alert(user, "attaching knife...") if(!do_after(user, 2.5 SECONDS, target = src)) return deputize(attacking_item, user) return return ..() -/mob/living/simple_animal/bot/cleanbot/emag_act(mob/user) - ..() - +/mob/living/simple_animal/bot/cleanbot/emag_act(mob/user, obj/item/card/emag/emag_card) + . = ..() if(!(bot_cover_flags & BOT_COVER_EMAGGED)) return + if(weapon) - weapon.force = weapon_orig_force + weapon.force = initial(weapon.force) if(user) to_chat(user, span_danger("[src] buzzes and beeps.")) + get_targets() //recalibrate target list /mob/living/simple_animal/bot/cleanbot/process_scan(atom/scan_target) if(iscarbon(scan_target)) var/mob/living/carbon/scan_carbon = scan_target - if(scan_carbon.stat != DEAD && scan_carbon.body_position == LYING_DOWN) - return scan_carbon - else if(is_type_in_typecache(scan_target, target_types)) + if(!(scan_carbon in view(DEFAULT_SCAN_RANGE, src))) + return null + if(scan_carbon.stat == DEAD) + return null + if(scan_carbon.body_position != LYING_DOWN) + return null + return scan_carbon + if(is_type_in_typecache(scan_target, target_types)) return scan_target +/mob/living/simple_animal/bot/cleanbot/handle_atom_del(atom/deleting_atom) + if(deleting_atom == weapon) + weapon = null + update_appearance(UPDATE_ICON) + return ..() + /mob/living/simple_animal/bot/cleanbot/handle_automated_action() . = ..() if(!.) return - if(mode == BOT_CLEANING) return if(bot_cover_flags & BOT_COVER_EMAGGED) //Emag functions - var/mob/living/carbon/victim = locate(/mob/living/carbon) in loc if(victim && victim == target) UnarmedAttack(victim) // Acid spray - - if(isopenturf(loc)) - if(prob(15)) // Wets floors and spawns foam randomly - UnarmedAttack(src) - + if(isopenturf(loc) && prob(15)) // Wets floors and spawns foam randomly + UnarmedAttack(src) else if(prob(5)) audible_message("[src] makes an excited beeping booping sound!") - if(ismob(target)) - if(!(target in view(DEFAULT_SCAN_RANGE, src))) - target = null - if(!process_scan(target)) - target = null - + if(ismob(target) && isnull(process_scan(target))) + target = null if(!target) - var/list/scan_targets = list() - - if(bot_cover_flags & BOT_COVER_EMAGGED) // When emagged, ignore cleanables and scan humans first. - scan_targets += list(/mob/living/carbon) - if(pests) - scan_targets += list(/mob/living/simple_animal) - if(trash) - scan_targets += list( - /obj/item/trash, - /obj/item/food/deadmouse, - ) - scan_targets += list( - /obj/effect/decal/cleanable, - /obj/effect/decal/remains, - ) - - target = scan(scan_targets) + target = scan(target_types) if(!target && bot_mode_flags & BOT_MODE_AUTOPATROL) //Search for cleanables it can see. switch(mode) @@ -288,17 +263,17 @@ return if(loc == get_turf(target)) - if(!(check_bot(target))) + if(check_bot(target)) + shuffle = TRUE //Shuffle the list the next time we scan so we dont both go the same way. + path = list() + else UnarmedAttack(target) //Rather than check at every step of the way, let's check before we do an action, so we can rescan before the other bot. if(QDELETED(target)) //We done here. target = null mode = BOT_IDLE return - else - shuffle = TRUE //Shuffle the list the next time we scan so we dont both go the same way. - path = list() - if(!path || path.len == 0) //No path, need a new one + if(!length(path)) //No path, need a new one //Try to produce a path to the target, and ignore airlocks to which it has access. path = get_path_to(src, target, 30, id=access_card) if(!bot_move(target)) @@ -313,6 +288,11 @@ return /mob/living/simple_animal/bot/cleanbot/proc/get_targets() + if(bot_cover_flags & BOT_COVER_EMAGGED) // When emagged, ignore cleanables and scan humans first. + target_types = list(/mob/living/carbon) + return + + //main targets target_types = list( /obj/effect/decal/cleanable/oil, /obj/effect/decal/cleanable/vomit, @@ -326,23 +306,23 @@ /obj/effect/decal/remains, ) - if(blood) + if(janitor_mode_flags & CLEANBOT_CLEAN_BLOOD) target_types += list( /obj/effect/decal/cleanable/xenoblood, /obj/effect/decal/cleanable/blood, /obj/effect/decal/cleanable/trail_holder, ) - if(pests) + if(janitor_mode_flags & CLEANBOT_CLEAN_PESTS) target_types += list( /mob/living/basic/cockroach, /mob/living/simple_animal/mouse, ) - if(drawn) + if(janitor_mode_flags & CLEANBOT_CLEAN_DRAWINGS) target_types += list(/obj/effect/decal/cleanable/crayon) - if(trash) + if(janitor_mode_flags & CLEANBOT_CLEAN_TRASH) target_types += list( /obj/item/trash, /obj/item/food/deadmouse, @@ -350,36 +330,40 @@ target_types = typecacheof(target_types) -/mob/living/simple_animal/bot/cleanbot/UnarmedAttack(atom/A, proximity_flag, list/modifiers) +/mob/living/simple_animal/bot/cleanbot/UnarmedAttack(atom/attack_target, proximity_flag, list/modifiers) if(HAS_TRAIT(src, TRAIT_HANDS_BLOCKED)) return - if(ismopable(A)) + . = ..() + if(ismopable(attack_target)) mode = BOT_CLEANING update_icon_state() - var/turf/T = get_turf(A) - start_cleaning(src, T, src) + var/turf/turf_to_clean = get_turf(attack_target) + start_cleaning(src, turf_to_clean, src) target = null mode = BOT_IDLE - else if(isitem(A) || istype(A, /obj/effect/decal/remains)) - visible_message(span_danger("[src] sprays hydrofluoric acid at [A]!")) + else if(isitem(attack_target) || istype(attack_target, /obj/effect/decal)) + visible_message(span_danger("[src] sprays hydrofluoric acid at [attack_target]!")) playsound(src, 'sound/effects/spray2.ogg', 50, TRUE, -6) - A.acid_act(75, 10) + attack_target.acid_act(75, 10) target = null - else if(istype(A, /mob/living/basic/cockroach) || ismouse(A)) - var/mob/living/living_target = A + else if(istype(attack_target, /mob/living/basic/cockroach) || ismouse(attack_target)) + var/mob/living/living_target = attack_target if(!living_target.stat) visible_message(span_danger("[src] smashes [living_target] with its mop!")) living_target.death() target = null else if(bot_cover_flags & BOT_COVER_EMAGGED) //Emag functions - if(iscarbon(A)) - var/mob/living/carbon/victim = A + if(iscarbon(attack_target)) + var/mob/living/carbon/victim = attack_target if(victim.stat == DEAD)//cleanbots always finish the job + target = null return - victim.visible_message(span_danger("[src] sprays hydrofluoric acid at [victim]!"), span_userdanger("[src] sprays you with hydrofluoric acid!")) + victim.visible_message( + span_danger("[src] sprays hydrofluoric acid at [victim]!"), + span_userdanger("[src] sprays you with hydrofluoric acid!")) var/phrase = pick( "PURIFICATION IN PROGRESS.", "THIS IS FOR ALL THE MESSES YOU'VE MADE ME CLEAN.", @@ -396,22 +380,19 @@ victim.emote("scream") playsound(src.loc, 'sound/effects/spray2.ogg', 50, TRUE, -6) victim.acid_act(5, 100) - else if(A == src) // Wets floors and spawns foam randomly + else if(attack_target == src) // Wets floors and spawns foam randomly if(prob(75)) - var/turf/open/T = loc - if(istype(T)) - T.MakeSlippery(TURF_WET_WATER, min_wet_time = 20 SECONDS, wet_time_to_add = 15 SECONDS) + var/turf/open/current_floor = loc + if(istype(current_floor)) + current_floor.MakeSlippery(TURF_WET_WATER, min_wet_time = 20 SECONDS, wet_time_to_add = 15 SECONDS) else visible_message(span_danger("[src] whirs and bubbles violently, before releasing a plume of froth!")) new /obj/effect/particle_effect/fluid/foam(loc) - else - ..() - /mob/living/simple_animal/bot/cleanbot/explode() - var/atom/Tsec = drop_location() - new /obj/item/reagent_containers/cup/bucket(Tsec) - new /obj/item/assembly/prox_sensor(Tsec) + var/atom/drop_loc = drop_location() + new /obj/item/reagent_containers/cup/bucket(drop_loc) + new /obj/item/assembly/prox_sensor(drop_loc) return ..() // Variables sent to TGUI @@ -419,10 +400,10 @@ var/list/data = ..() if(!(bot_cover_flags & BOT_COVER_LOCKED) || issilicon(user)|| isAdminGhostAI(user)) - data["custom_controls"]["clean_blood"] = blood - data["custom_controls"]["clean_trash"] = trash - data["custom_controls"]["clean_graffiti"] = drawn - data["custom_controls"]["pest_control"] = pests + data["custom_controls"]["clean_blood"] = janitor_mode_flags & CLEANBOT_CLEAN_BLOOD + data["custom_controls"]["clean_trash"] = janitor_mode_flags & CLEANBOT_CLEAN_TRASH + data["custom_controls"]["clean_graffiti"] = janitor_mode_flags & CLEANBOT_CLEAN_DRAWINGS + data["custom_controls"]["pest_control"] = janitor_mode_flags & CLEANBOT_CLEAN_PESTS return data // Actions received from TGUI @@ -433,11 +414,11 @@ switch(action) if("clean_blood") - blood = !blood + janitor_mode_flags ^= CLEANBOT_CLEAN_BLOOD if("pest_control") - pests = !pests + janitor_mode_flags ^= CLEANBOT_CLEAN_PESTS if("clean_trash") - trash = !trash + janitor_mode_flags ^= CLEANBOT_CLEAN_TRASH if("clean_graffiti") - drawn = !drawn + janitor_mode_flags ^= CLEANBOT_CLEAN_DRAWINGS get_targets() diff --git a/code/modules/mob/living/simple_animal/bot/firebot.dm b/code/modules/mob/living/simple_animal/bot/firebot.dm index e3cb673b642..03012317d71 100644 --- a/code/modules/mob/living/simple_animal/bot/firebot.dm +++ b/code/modules/mob/living/simple_animal/bot/firebot.dm @@ -89,7 +89,6 @@ ..() target_fire = null old_target_fire = null - ignore_list = list() set_anchored(FALSE) update_appearance() @@ -250,19 +249,16 @@ //Look for burning people or turfs around the bot /mob/living/simple_animal/bot/firebot/process_scan(atom/scan_target) - var/result - if(scan_target == src) - return result + return src + if(!is_burning(scan_target)) + return null - if(is_burning(scan_target)) - if((detected_cooldown + DETECTED_VOICE_INTERVAL) < world.time) - speak("Fire detected!") - playsound(src, 'sound/voice/firebot/detected.ogg', 50, FALSE) - detected_cooldown = world.time - result = scan_target - - return result + if((detected_cooldown + DETECTED_VOICE_INTERVAL) < world.time) + speak("Fire detected!") + playsound(src, 'sound/voice/firebot/detected.ogg', 50, FALSE) + detected_cooldown = world.time + return scan_target /mob/living/simple_animal/bot/firebot/should_atmos_process(datum/gas_mixture/air, exposed_temperature) return (exposed_temperature > T0C + 200 || exposed_temperature < BODYTEMP_COLD_DAMAGE_LIMIT) diff --git a/code/modules/mob/living/simple_animal/bot/floorbot.dm b/code/modules/mob/living/simple_animal/bot/floorbot.dm index 258ef5502f2..8288f039f65 100644 --- a/code/modules/mob/living/simple_animal/bot/floorbot.dm +++ b/code/modules/mob/living/simple_animal/bot/floorbot.dm @@ -23,7 +23,6 @@ var/obj/item/stack/tile/tilestack var/fixfloors = TRUE var/autotile = FALSE - var/max_targets = 50 var/turf/target var/toolbox = /obj/item/storage/toolbox/mechanical var/toolbox_color = "" @@ -73,7 +72,6 @@ /mob/living/simple_animal/bot/floorbot/bot_reset() ..() target = null - ignore_list = list() toggle_magnet(FALSE) /mob/living/simple_animal/bot/floorbot/attackby(obj/item/W , mob/user, params) diff --git a/code/modules/mob/living/simple_animal/bot/medbot.dm b/code/modules/mob/living/simple_animal/bot/medbot.dm index af3ed8ad0b2..410d6d718e3 100644 --- a/code/modules/mob/living/simple_animal/bot/medbot.dm +++ b/code/modules/mob/living/simple_animal/bot/medbot.dm @@ -232,20 +232,20 @@ /mob/living/simple_animal/bot/medbot/process_scan(mob/living/carbon/human/H) if(H.stat == DEAD) - return - + return null if((H == oldpatient) && (world.time < last_found + 200)) - return + return null + if(!assess_patient(H)) + return null - if(assess_patient(H)) - last_found = world.time - if(COOLDOWN_FINISHED(src, last_newpatient_speak)) - COOLDOWN_START(src, last_newpatient_speak, MEDBOT_NEW_PATIENTSPEAK_DELAY) - var/list/messagevoice = list("Hey, [H.name]! Hold on, I'm coming." = 'sound/voice/medbot/coming.ogg',"Wait [H.name]! I want to help!" = 'sound/voice/medbot/help.ogg',"[H.name], you appear to be injured!" = 'sound/voice/medbot/injured.ogg') - var/message = pick(messagevoice) - speak(message) - playsound(src, messagevoice[message], 50, FALSE) - return H + last_found = world.time + if(COOLDOWN_FINISHED(src, last_newpatient_speak)) + COOLDOWN_START(src, last_newpatient_speak, MEDBOT_NEW_PATIENTSPEAK_DELAY) + var/list/messagevoice = list("Hey, [H.name]! Hold on, I'm coming." = 'sound/voice/medbot/coming.ogg',"Wait [H.name]! I want to help!" = 'sound/voice/medbot/help.ogg',"[H.name], you appear to be injured!" = 'sound/voice/medbot/injured.ogg') + var/message = pick(messagevoice) + speak(message) + playsound(src, messagevoice[message], 50, FALSE) + return H /* * Proc used in a callback for before this medibot is tipped by the tippable component. diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm index bc27d056ecd..471f39c0651 100644 --- a/code/modules/mob/living/simple_animal/bot/secbot.dm +++ b/code/modules/mob/living/simple_animal/bot/secbot.dm @@ -149,6 +149,12 @@ playsound(src, 'sound/machines/defib_zap.ogg', 50) visible_message(span_warning("[src] shakes and speeds up!")) +/mob/living/simple_animal/bot/secbot/handle_atom_del(atom/deleting_atom) + if(deleting_atom == weapon) + weapon = null + update_appearance() + return ..() + // Variables sent to TGUI /mob/living/simple_animal/bot/secbot/ui_data(mob/user) var/list/data = ..()