diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm
index 7445fed15fd..1dbf4a1c62f 100644
--- a/code/modules/mob/living/simple_animal/bot/bot.dm
+++ b/code/modules/mob/living/simple_animal/bot/bot.dm
@@ -15,7 +15,7 @@
minbodytemp = 0
has_unlimited_silicon_privilege = TRUE
sentience_type = SENTIENCE_ARTIFICIAL
- status_flags = 0 //no default canpush
+ status_flags = 0 // No default canpush
can_strip = FALSE
speak_emote = list("states")
@@ -23,66 +23,104 @@
bubble_icon = "machine"
faction = list("neutral", "silicon")
- var/list/users = list() //for dialog updates
+ var/list/users = list() // For dialog updates
var/window_id = "bot_control"
- var/window_name = "Protobot 1.0" //Popup title
- var/window_width = 0 //0 for default size
+ var/window_name = "Protobot 1.0" // Popup title
+ var/window_width = 0 // 0 for default size
var/window_height = 0
- var/obj/item/paicard/paicard // Inserted pai card.
- var/allow_pai = TRUE // Are we even allowed to insert a pai card.
+ var/obj/item/paicard/paicard // Inserted pai card.
+ var/allow_pai = TRUE // Are we even allowed to insert a pai card.
var/bot_name
var/disabling_timer_id = null
var/list/player_access = list()
var/emagged = FALSE
- var/obj/item/card/id/access_card // the ID card that the bot "holds"
+ /// The ID card that the bot "holds"
+ var/obj/item/card/id/access_card
var/list/prev_access = list()
var/on = TRUE
- var/open = FALSE //Maint panel
+ /// Maint panel
+ var/open = FALSE
var/locked = TRUE
- var/hacked = FALSE //Used to differentiate between being hacked by silicons and emagged by humans.
+ /// Used to differentiate between being hacked by silicons and emagged by humans.
+ var/hacked = FALSE
/// Is currently hijacked by a pulse demon?
var/hijacked = FALSE
- var/text_hack = "" //Custom text returned to a silicon upon hacking a bot.
- var/text_dehack = "" //Text shown when resetting a bots hacked status to normal.
- var/text_dehack_fail = "" //Shown when a silicon tries to reset a bot emagged with the emag item, which cannot be reset.
- var/declare_message = "" //What the bot will display to the HUD user.
- var/frustration = 0 //Used by some bots for tracking failures to reach their target.
- var/base_speed = 2 //The speed at which the bot moves, or the number of times it moves per process() tick.
- var/turf/ai_waypoint //The end point of a bot's path, or the target location.
- var/list/path = list() //List of turfs through which a bot 'steps' to reach the waypoint
+ /// Custom text returned to a silicon upon hacking a bot.
+ var/text_hack = ""
+ /// Text shown when resetting a bots hacked status to normal.
+ var/text_dehack = ""
+ /// Shown when a silicon tries to reset a bot emagged with the emag item, which cannot be reset.
+ var/text_dehack_fail = ""
+ /// What the bot will display to the HUD user.
+ var/declare_message = ""
+ /// Used by some bots for tracking failures to reach their target.
+ var/frustration = 0
+ /// The speed at which the bot moves, or the number of times it moves per process() tick.
+ var/base_speed = 2
+ /// The end point of a bot's path, or the target location.
+ var/turf/ai_waypoint
+ /// List of turfs through which a bot 'steps' to reach the waypoint
+ var/list/path = list()
var/pathset = FALSE
- var/list/ignore_list = list() //List of unreachable targets for an ignore-list enabled bot to ignore.
- var/mode = BOT_IDLE //Standardizes the vars that indicate the bot is busy with its function.
- var/tries = 0 //Number of times the bot tried and failed to move.
- var/remote_disabled = FALSE //If enabled, the AI cannot *Remotely* control a bot. It can still control it through cameras.
- var/mob/living/silicon/ai/calling_ai //Links a bot to the AI calling it.
- var/obj/item/radio/Radio //The bot's radio, for speaking to people.
- var/list/radio_config = null //which channels can the bot listen to
- var/radio_channel = "Common" //The bot's default radio channel
- var/auto_patrol = FALSE // set to make bot automatically patrol
- var/turf/patrol_target // this is turf to navigate to (location of beacon)
- var/turf/summon_target // The turf of a user summoning a bot.
- var/new_destination // pending new destination (waiting for beacon response)
- var/destination // destination description tag
- var/next_destination // the next destination in the patrol route
- var/ignorelistcleanuptimer = 1 // This ticks up every automated action, at 300 we clean the ignore list
+ /// List of unreachable targets for an ignore-list enabled bot to ignore.
+ var/list/ignore_list = list()
+ /// List of jobs claimed by bot
+ var/static/list/ignore_job = list()
+ /// Standardizes the vars that indicate the bot is busy with its function.
+ var/mode = BOT_IDLE
+ /// Number of times the bot tried and failed to move.
+ var/tries = 0
+ /// If enabled, the AI cannot *Remotely* control a bot. It can still control it through cameras.
+ var/remote_disabled = FALSE
+ /// Links a bot to the AI calling it.
+ var/mob/living/silicon/ai/calling_ai
+ /// The bot's radio, for speaking to people.
+ var/obj/item/radio/Radio
+ /// Which channels can the bot listen to
+ var/list/radio_config = null
+ /// The bot's default radio channel
+ var/radio_channel = "Common"
+ /// Set to make bot automatically patrol
+ var/auto_patrol = FALSE
+ /// This is turf to navigate to (location of beacon)
+ var/turf/patrol_target
+ /// The turf of a user summoning a bot.
+ var/turf/summon_target
+ /// Pending new destination (waiting for beacon response)
+ var/new_destination
+ /// Destination description tag
+ var/destination
+ /// The next destination in the patrol route
+ var/next_destination
+ /// This ticks up every automated action, at 300 we clean the ignore list
+ var/ignore_list_cleanup_timer = 1
var/robot_arm = /obj/item/robot_parts/r_arm
- var/blockcount = 0 //number of times retried a blocked path
- var/awaiting_beacon = 0 // count of pticks awaiting a beacon response
+ /// Number of times retried a blocked path
+ var/blockcount = 0
+ /// Count of pticks awaiting a beacon response
+ var/awaiting_beacon = 0
- var/nearest_beacon // the nearest beacon's tag
- var/turf/nearest_beacon_loc // the nearest beacon's location
+ /// The nearest beacon's tag
+ var/nearest_beacon
+ /// The nearest beacon's location
+ var/turf/nearest_beacon_loc
- var/model = "" //The type of bot it is.
+ ///The type of bot it is.
+ var/model = ""
+ /// Bot Purpose under Show Laws
var/bot_purpose = "improve the station to the best of your ability"
- var/control_freq = BOT_FREQ // bot control frequency
- var/bot_filter // The radio filter the bot uses to identify itself on the network.
- var/bot_type = 0 //The type of bot it is, for radio control.
+ /// Bot control frequency
+ var/control_freq = BOT_FREQ
+
+ /// The radio filter the bot uses to identify itself on the network.
+ var/bot_filter
+ /// The type of bot it is, for radio control.
+ var/bot_type = 0
/// The type of data HUD the bot uses. Diagnostic by default.
var/data_hud_type = DATA_HUD_DIAGNOSTIC_BASIC
- //This holds text for what the bot is mode doing, reported on the remote bot control interface.
+ // This holds text for what the bot is mode doing, reported on the remote bot control interface.
var/list/mode_name = list("In Pursuit","Preparing to Arrest", "Arresting", \
"Beginning Patrol", "Patrolling", "Summoned by PDA", \
"Cleaning", "Repairing", "Proceeding to work site", "Healing", \
@@ -94,11 +132,11 @@
/// List of access values you can have to access the bot. Consider this as req_one_access
var/list/req_access = list()
- hud_possible = list(DIAG_STAT_HUD, DIAG_BOT_HUD, DIAG_HUD)//Diagnostic HUD views
+ hud_possible = list(DIAG_STAT_HUD, DIAG_BOT_HUD, DIAG_HUD) // Diagnostic HUD views
- /// storing last chased target known location
+ /// Storing last chased target known location
var/turf/last_target_location
- /// will be true if we lost target we were chasing
+ /// Will be true if we lost target we were chasing
var/lost_target = FALSE
/obj/item/radio/headset/bot
@@ -110,7 +148,7 @@
if(istype(B))
if(!B.radio_config)
B.radio_config = list("AI Private" = 1)
- if(!(B.radio_channel in B.radio_config)) // put it first so it's the :h channel
+ if(!(B.radio_channel in B.radio_config)) // Put it first so it's the :h channel
B.radio_config.Insert(1, "[B.radio_channel]")
B.radio_config["[B.radio_channel]"] = 1
config(B.radio_config)
@@ -146,7 +184,7 @@
frustration++
/mob/living/simple_animal/bot/proc/get_mode()
- if(client) //Player bots do not have modes, thus the override. Also an easy way for PDA users/AI to know when a bot is a player.
+ if(client) // Player bots do not have modes, thus the override. Also an easy way for PDA users/AI to know when a bot is a player.
if(paicard)
return "pAI Controlled"
else
@@ -164,20 +202,20 @@
if(disabling_timer_id)
return FALSE
if(stat)
- return 0
+ return FALSE
on = TRUE
REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, "depowered")
set_light(initial(light_range))
update_icon(UPDATE_ICON_STATE | UPDATE_OVERLAYS)
update_controls()
diag_hud_set_botstat()
- return 1
+ return TRUE
/mob/living/simple_animal/bot/proc/turn_off()
on = FALSE
ADD_TRAIT(src, TRAIT_IMMOBILIZED, "depowered")
set_light(0)
- bot_reset() //Resets an AI's call, should it exist.
+ bot_reset() // Resets an AI's call, should it exist.
update_icon(UPDATE_ICON_STATE | UPDATE_OVERLAYS)
update_controls()
@@ -187,7 +225,7 @@
icon_living = icon_state
icon_dead = icon_state
access_card = new /obj/item/card/id(src)
- //This access is so bots can be immediately set to patrol and leave Robotics, instead of having to be let out first.
+ // This access is so bots can be immediately set to patrol and leave Robotics, instead of having to be let out first.
access_card.access += ACCESS_ROBOTICS
set_custom_texts()
Radio = new/obj/item/radio/headset/bot(src)
@@ -210,10 +248,10 @@
/mob/living/simple_animal/bot/med_hud_set_health()
- return //we use a different hud
+ return // We use a different hud
/mob/living/simple_animal/bot/med_hud_set_status()
- return //we use a different hud
+ return // We use a different hud
/mob/living/simple_animal/bot/Destroy()
@@ -250,21 +288,23 @@
qdel(src)
/mob/living/simple_animal/bot/emag_act(mob/user)
- if(locked) //First emag application unlocks the bot's interface. Apply a screwdriver to use the emag again.
+ if(locked) // First emag application unlocks the bot's interface. Apply a screwdriver to use the emag again.
locked = FALSE
to_chat(user, "You bypass [src]'s controls.")
return TRUE
+
if(!locked && open) //Bot panel is unlocked by ID or emag, and the panel is screwed open. Ready for emagging.
emagged = TRUE
- remote_disabled = TRUE //Manually emagging the bot locks out the AI built in panel.
- locked = TRUE //Access denied forever!
+ remote_disabled = TRUE // Manually emagging the bot locks out the AI built in panel.
+ locked = TRUE // Access denied forever!
bot_reset()
- turn_on() //The bot automatically turns on when emagged, unless recently hit with EMP.
+ turn_on() // The bot automatically turns on when emagged, unless recently hit with EMP.
to_chat(src, "(#$*#$^^( OVERRIDE DETECTED")
show_laws()
if(user)
add_attack_logs(user, src, "Emagged")
return TRUE
+
else //Bot is unlocked, but the maint panel has not been opened with a screwdriver yet.
to_chat(user, "You need to open maintenance panel first!")
@@ -290,14 +330,14 @@
/mob/living/simple_animal/bot/handle_automated_action()
diag_hud_set_botmode()
- if(ignorelistcleanuptimer % 300 == 0) // Every 300 actions, clean up the ignore list from old junk
+ if(++ignore_list_cleanup_timer == 300) // Every 300 actions, clean up the ignore list from old junk
for(var/uid in ignore_list)
- var/atom/referredatom = locateUID(uid)
- if(!referredatom || QDELETED(referredatom))
+ var/atom/referred_atom = locateUID(uid)
+ if(!referred_atom || QDELETED(referred_atom))
ignore_list -= uid
- ignorelistcleanuptimer = 1
+ ignore_list_cleanup_timer = 0
else
- ignorelistcleanuptimer++
+ ignore_list_cleanup_timer++
if(!on)
return
@@ -305,14 +345,14 @@
if(hijacked)
return
- switch(mode) //High-priority overrides are processed first. Bots can do nothing else while under direct command.
- if(BOT_RESPONDING) //Called by the AI.
+ switch(mode) // High-priority overrides are processed first. Bots can do nothing else while under direct command.
+ if(BOT_RESPONDING) // Called by the AI.
call_mode()
return
- if(BOT_SUMMON) //Called by PDA
+ if(BOT_SUMMON) // Called by PDA
bot_summon()
return
- return 1 //Successful completion. Used to prevent child process() continuing if this one is ended early.
+ return TRUE // Successful completion. Used to prevent child process() continuing if this one is ended early.
/mob/living/simple_animal/bot/attack_alien(mob/living/carbon/alien/user)
user.changeNext_move(CLICK_CD_MELEE)
@@ -407,7 +447,7 @@
return ..()
if(locked)
to_chat(user, "The maintenance panel is locked.")
- return TRUE // must be true or we attempt to stab the bot
+ return TRUE // Must be true or we attempt to stab the bot
open = !open
I.play_tool_sound(src)
@@ -418,7 +458,7 @@
/mob/living/simple_animal/bot/welder_act(mob/user, obj/item/I)
if(user.a_intent != INTENT_HELP)
return
- if(user == src) //No self-repair dummy
+ if(user == src) // No self-repair dummy
return
. = TRUE
if(health >= maxHealth)
@@ -467,7 +507,7 @@
/mob/living/simple_animal/bot/proc/disable(time)
if(disabling_timer_id)
- deltimer(disabling_timer_id) // if we already have disabling timer, lets replace it with new one
+ deltimer(disabling_timer_id) // If we already have disabling timer, lets replace it with new one
if(on)
turn_off()
disabling_timer_id = addtimer(CALLBACK(src, PROC_REF(enable)), time, TIMER_STOPPABLE)
@@ -486,12 +526,12 @@
set_custom_texts()
return TRUE
-/mob/living/simple_animal/bot/proc/set_custom_texts() //Superclass for setting hack texts. Appears only if a set is not given to a bot locally.
+/mob/living/simple_animal/bot/proc/set_custom_texts() // Superclass for setting hack texts. Appears only if a set is not given to a bot locally.
text_hack = "You hack [name]."
text_dehack = "You reset [name]."
text_dehack_fail = "You fail to reset [name]."
-/mob/living/simple_animal/bot/proc/speak(message, channel) //Pass a message to have the bot say() it. Pass a frequency to say it on the radio.
+/mob/living/simple_animal/bot/proc/speak(message, channel) // Pass a message to have the bot say() it. Pass a frequency to say it on the radio.
if((!on) || (!message))
return
if(channel)
@@ -500,74 +540,73 @@
say(message)
return
-//Generalized behavior code, override where needed!
+// Generalized behavior code, override where needed!
/*
scan() will search for a given type (such as turfs, human mobs, or objects) in the bot's view range, and return a single result.
Arguments: The object type to be searched (such as "/mob/living/carbon/human"), the old scan result to be ignored, if one exists,
and the view range, which defaults to 7 (full screen) if an override is not passed.
If the bot maintains an ignore list, it is also checked here.
-If the bot has avoid_bot, which inserts its own path, it will ignore turfs with the same bot type
-
+If avoid_bot = TRUE, it will claim it's target. List of bots that use it: Cleanbot and Floorbot
Example usage: patient = scan(/mob/living/carbon/human, oldpatient, 1)
The proc would return a human next to the bot to be set to the patient var.
Pass the desired type path itself, declaring a temporary var beforehand is not required.
*/
/mob/living/simple_animal/bot/proc/scan(atom/scan_type, atom/old_target, scan_range = DEFAULT_SCAN_RANGE, avoid_bot)
- var/final_result
- for(var/scan in view(scan_range, src)) //Search for something in range!
- var/atom/A = scan
- if(!istype(A, scan_type)) //Check that the thing we found is the type we want!
- continue //If not, keep searching!
- if((A.UID() in ignore_list) || (A == old_target)) //Filter for blacklisted elements, usually unreachable or previously processed oness
+ for(var/atom/A in view(scan_range, src)) // Search for something in range!
+ if(!istype(A, scan_type)) // Check that the thing we found is the type we want!
+ continue // If not, keep searching!
+ if((A.UID() in ignore_list) || (A == old_target)) // Filter for blacklisted elements, usually unreachable or previously processed oness
continue
- if(turf_has_bot(avoid_bot, get_turf(A))) //Ignores targets that already have a bot of the same type on it, meant for cleanbot and floorbot seperation
+ var/scan_result = process_scan(A) // Some bots may require additional processing when a result is selected.
+ if(!scan_result)
+ continue // The current element failed assessment, move on to the next.
+ if(assign_bot(A, avoid_bot)) // Is the target claimed by a bot
continue
- var/scan_result = process_scan(A) //Some bots may require additional processing when a result is selected.
- if(scan_result)
- final_result = scan_result
- else
- continue //The current element failed assessment, move on to the next.
- return final_result
+ return scan_result
-/mob/living/simple_animal/bot/proc/turf_has_bot(avoid_bot, turf/turf_to_search)
- if(!avoid_bot)
+/mob/living/simple_animal/bot/proc/assign_bot(atom/A, avoid_bot)
+ if(!avoid_bot) // Only bots with avoid bot should be considered
return FALSE
- for(var/bot in turf_to_search)
- if(istype(bot, avoid_bot))
- return TRUE
- return FALSE
+ if(A.UID() in ignore_job) // Is this target already claimed by a bot
+ return TRUE
+ claim_job(A) // Claim the job so other bots don't come
-//When the scan finds a target, run bot specific processing to select it for the next step. Empty by default.
+/mob/living/simple_animal/bot/proc/claim_job(atom/A) // Adds the target to ignore_job list
+ var/ignore_amount = length(GLOB.bots_list) // 1 claim per bot
+ if(length(ignore_job) >= ++ignore_amount) // Something went wrong, cull the herd
+ ignore_job.Cut()
+ ignore_job |= A.UID()
+
+// When the scan finds a target, run bot specific processing to select it for the next step. Empty by default.
/mob/living/simple_animal/bot/proc/process_scan(atom/scan_target)
return scan_target
/mob/living/simple_animal/bot/proc/add_to_ignore(atom/A)
- if(ignore_list.len < 50) //This will help keep track of them, so the bot is always trying to reach a blocked spot.
- ignore_list |= A.UID()
- else //If the list is full, insert newest, delete oldest.
- ignore_list.Cut(1, 2)
- ignore_list |= A.UID()
+ if(length(ignore_list) >= 50) // This will help keep track of them, so the bot is always trying to reach a blocked spot.
+ ignore_list.Cut(1, 2) // If the list is full, insert newest, delete oldest.
+ ignore_list |= A.UID()
+
/*
Movement proc for stepping a bot through a path generated through A-star.
Pass a positive integer as an argument to override a bot's default speed.
*/
/mob/living/simple_animal/bot/proc/bot_move(dest, move_speed)
- if(!dest || !path || !length(path)) //A-star failed or a path/destination was not set.
+ if(!dest || !path || !length(path)) // A-star failed or a path/destination was not set.
set_path(null)
return FALSE
- dest = get_turf(dest) //We must always compare turfs, so get the turf of the dest var if dest was originally something else.
- var/turf/last_node = get_turf(path[length(path)]) //This is the turf at the end of the path, it should be equal to dest.
- if(get_turf(src) == dest) //We have arrived, no need to move again.
+ dest = get_turf(dest) // We must always compare turfs, so get the turf of the dest var if dest was originally something else.
+ var/turf/last_node = get_turf(path[length(path)]) // This is the turf at the end of the path, it should be equal to dest.
+ if(get_turf(src) == dest) // We have arrived, no need to move again.
return TRUE
- else if(dest != last_node) //The path should lead us to our given destination. If this is not true, we must stop.
+ else if(dest != last_node) // The path should lead us to our given destination. If this is not true, we must stop.
set_path(null)
return FALSE
- var/step_count = move_speed ? move_speed : base_speed //If a value is passed into move_speed, use that instead of the default speed var.
+ var/step_count = move_speed ? move_speed : base_speed // If a value is passed into move_speed, use that instead of the default speed var.
if(step_count >= 1 && tries < BOT_STEP_MAX_RETRIES)
for(var/step_number in 1 to step_count)
@@ -578,7 +617,7 @@ Pass a positive integer as an argument to override a bot's default speed.
return TRUE
-/mob/living/simple_animal/bot/proc/bot_step() //Step,increase tries if failed
+/mob/living/simple_animal/bot/proc/bot_step() // Step,increase tries if failed
if(!length(path))
return FALSE
@@ -596,19 +635,19 @@ Pass a positive integer as an argument to override a bot's default speed.
access_card.access = prev_access
/mob/living/simple_animal/bot/proc/call_bot(caller, turf/waypoint, message=TRUE)
- bot_reset() //Reset a bot before setting it to call mode.
+ bot_reset() // Reset a bot before setting it to call mode.
var/area/end_area = get_area(waypoint)
var/datum/job/captain/All = new/datum/job/captain
access_card.access = All.get_access() // Give the bot temporary all access
set_path(get_path_to(src, waypoint, 200, id = access_card))
- calling_ai = caller //Link the AI to the bot!
+ calling_ai = caller // Link the AI to the bot!
ai_waypoint = waypoint
- if(path && length(path)) //Ensures that a valid path is calculated!
+ if(path && length(path)) // Ensures that a valid path is calculated!
if(!on)
- turn_on() //Saves the AI the hassle of having to activate a bot manually.
+ turn_on() // Saves the AI the hassle of having to activate a bot manually.
if(client)
reset_access_timer_id = addtimer(CALLBACK(src, PROC_REF(bot_reset)), 600, TIMER_OVERRIDE|TIMER_STOPPABLE) //if the bot is player controlled, they get the extra access for a limited time
to_chat(src, "Priority waypoint set by [calling_ai] [caller]. Proceed to [end_area.name].
[length(path)-1] meters to destination. You have been granted additional door access for 60 seconds.")
@@ -624,8 +663,8 @@ Pass a positive integer as an argument to override a bot's default speed.
access_card.access = prev_access // Don't forget to reset it
set_path(null)
-/mob/living/simple_animal/bot/proc/call_mode() //Handles preparing a bot for a call, as well as calling the move proc.
-//Handles the bot's movement during a call.
+/mob/living/simple_animal/bot/proc/call_mode() // Handles preparing a bot for a call, as well as calling the move proc.
+// Handles the bot's movement during a call.
var/success = bot_move(ai_waypoint, 3)
if(!success)
if(calling_ai)
@@ -634,13 +673,14 @@ Pass a positive integer as an argument to override a bot's default speed.
bot_reset()
/mob/living/simple_animal/bot/proc/bot_reset()
- if(calling_ai) //Simple notification to the AI if it called a bot. It will not know the cause or identity of the bot.
+ if(calling_ai) // Simple notification to the AI if it called a bot. It will not know the cause or identity of the bot.
to_chat(calling_ai, "Call command to a bot has been reset.")
calling_ai = null
if(reset_access_timer_id)
deltimer(reset_access_timer_id)
reset_access_timer_id = null
set_path(null)
+ ignore_job.Cut()
last_target_location = null
lost_target = FALSE
summon_target = null
@@ -668,21 +708,21 @@ Pass a positive integer as an argument to override a bot's default speed.
/mob/living/simple_animal/bot/proc/start_patrol()
set_path(null)
- if(tries >= BOT_STEP_MAX_RETRIES) //Bot is trapped, so stop trying to patrol.
+ if(tries >= BOT_STEP_MAX_RETRIES) // Bot is trapped, so stop trying to patrol.
auto_patrol = FALSE
tries = 0
speak("Unable to start patrol.")
return
- if(!auto_patrol) //A bot not set to patrol should not be patrolling.
+ if(!auto_patrol) // A bot not set to patrol should not be patrolling.
mode = BOT_IDLE
return
if(patrol_target) // has patrol target
INVOKE_ASYNC(src, PROC_REF(target_patrol))
- else // no patrol target, so need a new one
+ else // No patrol target, so need a new one
speak("Engaging patrol mode.")
find_patrol_target()
tries++
@@ -694,30 +734,30 @@ Pass a positive integer as an argument to override a bot's default speed.
return
mode = BOT_PATROL
-// perform a single patrol step
+// Perform a single patrol step
/mob/living/simple_animal/bot/proc/patrol_step()
if(client) // In use by player, don't actually move.
return
- if(loc == patrol_target) // reached target
- //Find the next beacon matching the target.
+ if(loc == patrol_target) // Reached target
+ // Find the next beacon matching the target.
if(!get_next_patrol_target())
- find_patrol_target() //If it fails, look for the nearest one instead.
+ find_patrol_target() // If it fails, look for the nearest one instead.
return
- else if(length(path) && patrol_target) // valid path
+ else if(length(path) && patrol_target) // Valid path
if(path[1] == loc)
increment_path()
return
- var/moved = bot_move(patrol_target)//step_towards(src, next) // attempt to move
- if(!moved) //Couldn't proceed the next step of the path BOT_STEP_MAX_RETRIES times
+ var/moved = bot_move(patrol_target) // step_towards(src, next) // attempt to move
+ if(!moved) // Couldn't proceed the next step of the path BOT_STEP_MAX_RETRIES times
addtimer(CALLBACK(src, PROC_REF(patrol_step_not_moved)), 2)
- else // no path, so calculate new one
+ else // No path, so calculate new one
mode = BOT_START_PATROL
/mob/living/simple_animal/bot/proc/patrol_step_not_moved()
@@ -726,7 +766,7 @@ Pass a positive integer as an argument to override a bot's default speed.
find_patrol_target()
tries = 0
-// finds the nearest beacon to self
+// Finds the nearest beacon to self
/mob/living/simple_animal/bot/proc/find_patrol_target()
nearest_beacon = null
new_destination = null
@@ -740,13 +780,13 @@ Pass a positive integer as an argument to override a bot's default speed.
speak("Disengaging patrol mode.")
/mob/living/simple_animal/bot/proc/get_next_patrol_target()
- // search the beacon list for the next target in the list.
+ // Search the beacon list for the next target in the list.
for(var/obj/machinery/navbeacon/NB in GLOB.navbeacons["[z]"])
- if(NB.location == next_destination) //Does the Beacon location text match the destination?
- destination = new_destination //We now know the name of where we want to go.
- patrol_target = NB.loc //Get its location and set it as the target.
- next_destination = NB.codes["next_patrol"] //Also get the name of the next beacon in line.
- return 1
+ if(NB.location == next_destination) // Does the Beacon location text match the destination?
+ destination = new_destination // We now know the name of where we want to go.
+ patrol_target = NB.loc // Get its location and set it as the target.
+ next_destination = NB.codes["next_patrol"] // Also get the name of the next beacon in line.
+ return TRUE
/mob/living/simple_animal/bot/proc/find_nearest_beacon()
for(var/obj/machinery/navbeacon/NB in GLOB.navbeacons["[z]"])
@@ -786,17 +826,17 @@ Pass a positive integer as an argument to override a bot's default speed.
if(!on)
return FALSE
- // check to see if we are the commanded bot
- if(emagged || remote_disabled || hijacked) //Emagged bots do not respect anyone's authority! Bots with their remote controls off cannot get commands.
+ // Check to see if we are the commanded bot
+ if(emagged || remote_disabled || hijacked) // Emagged bots do not respect anyone's authority! Bots with their remote controls off cannot get commands.
return FALSE
if(client)
bot_control_message(command, user, params["target"] ? params["target"] : "Unknown")
- // process control input
+ // Process control input
switch(command)
if("stop")
- bot_reset() //HOLD IT!!
+ bot_reset() // HOLD IT!!
auto_patrol = FALSE
if("go")
@@ -808,7 +848,7 @@ Pass a positive integer as an argument to override a bot's default speed.
summon_target = params["target"] // Location of the user
if(length(user_access))
- access_card.access = user_access + prev_access //Adds the user's access, if any.
+ access_card.access = user_access + prev_access // Adds the user's access, if any.
mode = BOT_SUMMON
calc_summon_path()
@@ -817,11 +857,11 @@ Pass a positive integer as an argument to override a bot's default speed.
return TRUE
-/mob/living/simple_animal/bot/proc/bot_summon() // summoned to PDA
+/mob/living/simple_animal/bot/proc/bot_summon() // Summoned to PDA
summon_step()
-// calculates a path to the current destination
-// given an optional turf to avoid
+// Calculates a path to the current destination
+// Given an optional turf to avoid
/mob/living/simple_animal/bot/proc/calc_path(turf/avoid)
check_bot_access()
set_path(get_path_to(src, patrol_target, 120, id=access_card, exclude=avoid))
@@ -830,7 +870,7 @@ Pass a positive integer as an argument to override a bot's default speed.
set waitfor = FALSE
check_bot_access()
set_path(get_path_to(src, summon_target, 150, id=access_card, exclude=avoid))
- if(!length(path)) //Cannot reach target. Give up and announce the issue.
+ if(!length(path)) // Cannot reach target. Give up and announce the issue.
speak("Summon command failed, destination unreachable.",radio_channel)
bot_reset()
@@ -854,7 +894,7 @@ Pass a positive integer as an argument to override a bot's default speed.
addtimer(CALLBACK(src, PROC_REF(try_calc_path)), 2)
- else // no path, so calculate new one
+ else // No path, so calculate new one
calc_summon_path()
/mob/living/simple_animal/bot/proc/try_calc_path()
@@ -886,22 +926,22 @@ Pass a positive integer as an argument to override a bot's default speed.
return "PROTOBOT - NOT FOR USE"
/mob/living/simple_animal/bot/proc/allowed(mob/M)
- var/acc = M.get_access() //see mob.dm
+ var/acc = M.get_access() // See mob.dm
if(acc == IGNORE_ACCESS || M.can_admin_interact())
- return TRUE //Mob ignores access
+ return TRUE // Mob ignores access
return has_access(list(), req_access, acc)
/mob/living/simple_animal/bot/Topic(href, href_list)
- if(href_list["close"])// HUE HUE
+ if(href_list["close"]) // HUE HUE
if(usr in users)
users.Remove(usr)
- return 1
+ return TRUE
if(topic_denied(usr))
to_chat(usr, "[src]'s interface is not responding!")
- return 1
+ return TRUE
add_fingerprint(usr)
if((href_list["power"]) && (allowed(usr) || !locked || usr.can_admin_interact()))
@@ -927,7 +967,7 @@ Pass a positive integer as an argument to override a bot's default speed.
/mob/living/simple_animal/bot/proc/canhack(mob/M)
return ((issilicon(M) && (!emagged || hacked)) || M.can_admin_interact())
-/mob/living/simple_animal/bot/proc/handle_hacking(mob/M) // refactored out of Topic/ to allow re-use by TGUIs
+/mob/living/simple_animal/bot/proc/handle_hacking(mob/M) // Refactored out of Topic/ to allow re-use by TGUIs
if(!canhack(M))
return
if(!emagged)
@@ -951,15 +991,15 @@ Pass a positive integer as an argument to override a bot's default speed.
/mob/living/simple_animal/bot/update_icon_state()
icon_state = "[initial(icon_state)][on]"
-/mob/living/simple_animal/bot/proc/topic_denied(mob/user) //Access check proc for bot topics! Remember to place in a bot's individual Topic if desired.
+/mob/living/simple_animal/bot/proc/topic_denied(mob/user) // Access check proc for bot topics! Remember to place in a bot's individual Topic if desired.
if(user.can_admin_interact())
return FALSE
if(user.incapacitated() || !(issilicon(user) || in_range(src, user)))
return TRUE
- if(emagged) //An emagged bot cannot be controlled by humans, silicons can if one hacked it.
- if(!hacked) //Manually emagged by a human - access denied to all.
+ if(emagged) // An emagged bot cannot be controlled by humans, silicons can if one hacked it.
+ if(!hacked) // Manually emagged by a human - access denied to all.
return TRUE
- else if(!(issilicon(user) || ispulsedemon(user))) //Bot is hacked, so only silicons are allowed access.
+ else if(!(issilicon(user) || ispulsedemon(user))) // Bot is hacked, so only silicons are allowed access.
return TRUE
if(hijacked && !ispulsedemon(user))
return FALSE
@@ -969,10 +1009,10 @@ Pass a positive integer as an argument to override a bot's default speed.
/mob/living/simple_animal/bot/proc/hack(mob/user)
var/hack
- if(issilicon(user) || user.can_admin_interact()) //Allows silicons or admins to toggle the emag status of a bot.
+ if(issilicon(user) || user.can_admin_interact()) // Allows silicons or admins to toggle the emag status of a bot.
hack += "[emagged ? "Software compromised! Unit may exhibit dangerous or erratic behavior." : "Unit operating normally. Release safety lock?"]
"
hack += "Harm Prevention Safety System: [emagged ? "DANGER" : "Engaged"]
"
- else if(!locked) //Humans with access can use this option to hide a bot from the AI's remote control panel and PDA control.
+ else if(!locked) // Humans with access can use this option to hide a bot from the AI's remote control panel and PDA control.
hack += "Remote network control radio: [remote_disabled ? "Disconnected" : "Connected"]
"
return hack
@@ -1095,7 +1135,7 @@ Pass a positive integer as an argument to override a bot's default speed.
used_radios += Radio
/mob/living/simple_animal/bot/is_mechanical()
- return 1
+ return TRUE
/mob/living/simple_animal/bot/proc/set_path(list/newpath)
path = newpath ? newpath : list()
@@ -1112,13 +1152,13 @@ Pass a positive integer as an argument to override a bot's default speed.
// Common data shared among all the bots, used by BotStatus.js
/mob/living/simple_animal/bot/ui_data(mob/user)
var/list/data = list()
- data["locked"] = locked // controls, locked or not
- data["noaccess"] = topic_denied(user) // does the current user have access? admins, silicons etc can still access bots with locked controls
+ data["locked"] = locked // Controls, locked or not
+ data["noaccess"] = topic_denied(user) // Does the current user have access? admins, silicons etc can still access bots with locked controls
data["maintpanel"] = open
data["on"] = on
data["autopatrol"] = auto_patrol
data["painame"] = paicard ? paicard.pai.name : null
data["canhack"] = canhack(user)
- data["emagged"] = emagged // this is an int, NOT a boolean
+ data["emagged"] = emagged
data["remote_disabled"] = remote_disabled
return data
diff --git a/code/modules/mob/living/simple_animal/bot/cleanbot.dm b/code/modules/mob/living/simple_animal/bot/cleanbot.dm
index cba5965884b..10090833b57 100644
--- a/code/modules/mob/living/simple_animal/bot/cleanbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/cleanbot.dm
@@ -124,7 +124,7 @@
audible_message("[src] makes an excited beeping booping sound!")
if(!target) //Search for cleanables it can see.
- target = scan(/obj/effect/decal/cleanable, avoid_bot = /mob/living/simple_animal/bot/cleanbot)
+ target = scan(/obj/effect/decal/cleanable, avoid_bot = TRUE)
if(!target && auto_patrol) //Search for cleanables it can see.
if(mode == BOT_IDLE || mode == BOT_START_PATROL)
@@ -143,12 +143,14 @@
//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))
+ ignore_job -= target.UID()
add_to_ignore(target)
target = null
path = list()
return
mode = BOT_MOVING
else if(!bot_move(target))
+ ignore_job -= target.UID()
target = null
mode = BOT_IDLE
return
@@ -164,6 +166,7 @@
/mob/living/simple_animal/bot/cleanbot/proc/do_clean(obj/effect/decal/cleanable/target)
if(mode == BOT_CLEANING)
+ ignore_job -= target.UID()
QDEL_NULL(target)
anchored = FALSE
mode = BOT_IDLE
diff --git a/code/modules/mob/living/simple_animal/bot/floorbot.dm b/code/modules/mob/living/simple_animal/bot/floorbot.dm
index bfbbcc18702..a8e7e3d0653 100644
--- a/code/modules/mob/living/simple_animal/bot/floorbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/floorbot.dm
@@ -1,4 +1,4 @@
-//Floorbot
+// Floorbot
/mob/living/simple_animal/bot/floorbot
name = "\improper Floorbot"
desc = "A little floor repairing robot, he looks so excited!"
@@ -167,37 +167,37 @@
if(prob(5))
audible_message("[src] makes an excited booping beeping sound!")
- //Normal scanning procedure. We have tiles loaded, are not emagged.
+ // Normal scanning procedure. We have tiles loaded, are not emagged.
if(!target && !emagged && amount)
if(!target)
- process_type = HULL_BREACH //Ensures the floorbot does not try to "fix" space areas or shuttle docking zones.
- target = scan(/turf/space, avoid_bot = /mob/living/simple_animal/bot/floorbot)
+ process_type = HULL_BREACH // Ensures the floorbot does not try to "fix" space areas or shuttle docking zones.
+ target = scan(/turf/space, avoid_bot = TRUE)
- if(!target && replace_tiles) //Finds a floor without a tile and gives it one.
- process_type = REPLACE_TILE //The target must be the floor and not a tile. The floor must not already have a floortile.
- target = scan(/turf/simulated/floor, avoid_bot = /mob/living/simple_animal/bot/floorbot)
-
- if(!target && fix_floor) //Repairs damaged floors and tiles.
+ if(!target && fix_floor) // Repairs damaged floors and tiles.
process_type = FIX_TILE
- target = scan(/turf/simulated/floor, avoid_bot = /mob/living/simple_animal/bot/floorbot)
+ target = scan(/turf/simulated/floor, avoid_bot = TRUE)
- if(!target && emagged) //We are emagged! Time to rip up the floors!
+ if(!target && replace_tiles) // Finds a floor without a tile and gives it one.
+ process_type = REPLACE_TILE // The target must be the floor and not a tile. The floor must not already have a floortile.
+ target = scan(/turf/simulated/floor/plating, avoid_bot = TRUE)
+
+ if(!target && emagged) // We are emagged! Time to rip up the floors!
process_type = TILE_EMAG
- target = scan(/turf/simulated/floor, avoid_bot = /mob/living/simple_animal/bot/floorbot)
+ target = scan(/turf/simulated/floor, avoid_bot = TRUE)
- if(amount < MAX_AMOUNT && !target) //Out of tiles! We must refill!
- if(eat_tiles) //Configured to find and consume floortiles!
+ if(amount < MAX_AMOUNT && !target) // Out of tiles! We must refill!
+
+ if(!target && eat_tiles) // Configured to find and consume floortiles!
process_type = null
target = scan(/obj/item/stack/tile/plasteel)
- if(!target && make_tiles) //We did not manage to find any floor tiles! Scan for metal stacks and make our own!
+ if(!target && make_tiles) // We did not manage to find any floor tiles! Scan for metal stacks and make our own!
process_type = null
target = scan(/obj/item/stack/sheet/metal)
- if(!target && nag_on_empty) //Floorbot is empty and cannot acquire more tiles, nag the engineers for more!
+ if(!target && nag_on_empty) // Floorbot is empty and cannot acquire more tiles, nag the engineers for more!
nag()
-
if(!target)
if(auto_patrol)
@@ -211,10 +211,10 @@
if(loc == target || loc == target.loc)
if(istype(target, /obj/item/stack/tile/plasteel))
- start_eattile(target)
+ start_eat_tile(target)
if(istype(target, /obj/item/stack/sheet/metal))
- start_maketile(target)
+ start_make_tile(target)
if(isturf(target) && !emagged)
repair(target)
@@ -232,7 +232,7 @@
path = list()
return
- if(!length(path))
+ if(!length(path)) // No path, need a new one
if(!isturf(target))
var/turf/TL = get_turf(target)
path = get_path_to(src, TL, 30, id = access_card, simulated_only = 0)
@@ -241,10 +241,12 @@
if(!bot_move(target))
add_to_ignore(target)
+ ignore_job -= target.UID()
target = null
mode = BOT_IDLE
return
else if(!bot_move(target))
+ ignore_job -= target.UID()
target = null
mode = BOT_IDLE
return
@@ -255,45 +257,50 @@
amount ++
anchored = FALSE
mode = BOT_IDLE
+ ignore_job -= target.UID()
target = null
-/mob/living/simple_animal/bot/floorbot/proc/nag() //Annoy everyone on the channel to refill us!
+/mob/living/simple_animal/bot/floorbot/proc/nag() // Annoy everyone on the channel to refill us!
if(!nagged)
speak("Requesting refill [MAX_AMOUNT - amount] at [get_area(src)]!", radio_channel)
nagged = TRUE
-/mob/living/simple_animal/bot/floorbot/proc/is_hull_breach(turf/t) //Ignore space tiles not considered part of a structure, also ignores shuttle docking areas.
+/mob/living/simple_animal/bot/floorbot/proc/is_hull_breach(turf/t) // Ignore space tiles not considered part of a structure, also ignores shuttle docking areas.
return !istype(get_area(t), /area/space)
-//Floorbots, having several functions, need sort out special conditions here.
+// Floorbots, having several functions, need sort out special conditions here.
/mob/living/simple_animal/bot/floorbot/process_scan(atom/scan_target)
var/result
var/turf/simulated/floor/F
switch(process_type)
- if(HULL_BREACH) //The most common job, patching breaches in the station's hull.
- if(is_hull_breach(scan_target)) //Ensure that the targeted space turf is actually part of the station, and not random space.
+ if(HULL_BREACH) // The most common job, patching breaches in the station's hull.
+ if(is_hull_breach(scan_target)) // Ensure that the targeted space turf is actually part of the station, and not random space.
result = scan_target
- anchored = TRUE //Prevent the floorbot being blown off-course while trying to reach a hull breach.
+ anchored = TRUE // Prevent the floorbot being blown off-course while trying to reach a hull breach.
if(REPLACE_TILE)
F = scan_target
- if(istype(F, /turf/simulated/floor/plating)) //The floor must not already have a tile.
+ if(istype(F, /turf/simulated/floor/plating)) // The floor must not already have a tile.
+ if(locate(/obj/structure/window) in get_turf(F)) // Targeting plating under window
+ add_to_ignore(scan_target)
+ return FALSE
result = F
- if(FIX_TILE) //Selects only damaged floors.
+ if(FIX_TILE) // Selects only damaged floors.
F = scan_target
if(istype(F) && (F.broken || F.burnt))
result = F
- if(TILE_EMAG) //Emag mode! Rip up the floor and cause breaches to space!
+ if(TILE_EMAG) // Emag mode! Rip up the floor and cause breaches to space!
F = scan_target
if(!istype(F, /turf/simulated/floor/plating))
result = F
- else //If no special processing is needed, simply return the result.
+ else // If no special processing is needed, simply return the result.
result = scan_target
return result
/mob/living/simple_animal/bot/floorbot/proc/repair(turf/target_turf)
if(isspaceturf(target_turf))
- //Must be a hull breach to continue.
+ // Must be a hull breach to continue.
if(!is_hull_breach(target_turf))
+ ignore_job -= target.UID()
target = null
return
@@ -302,12 +309,13 @@
if(amount <= 0)
mode = BOT_IDLE
+ ignore_job -= target.UID()
target = null
return
anchored = TRUE
- if(isspaceturf(target_turf)) //If we are fixing an area not part of pure space, it is
+ if(isspaceturf(target_turf)) // If we are fixing an area not part of pure space, it is
visible_message("[src] begins to repair the hole.")
mode = BOT_REPAIRING
update_icon(UPDATE_OVERLAYS)
@@ -326,6 +334,8 @@
if(mode != BOT_REPAIRING)
return
+ ignore_job -= target_turf.UID() // If called after the tile fix, turf changes and the UID with it
+
if(autotile || replace_tiles)
if(process_type != HULL_BREACH)
F.break_tile_to_plating()
@@ -339,15 +349,16 @@
anchored = FALSE
target = null
-/mob/living/simple_animal/bot/floorbot/proc/start_eattile(obj/item/stack/tile/plasteel/T)
+/mob/living/simple_animal/bot/floorbot/proc/start_eat_tile(obj/item/stack/tile/plasteel/T)
if(!istype(T, /obj/item/stack/tile/plasteel))
return
+ anchored = TRUE
visible_message("[src] begins to collect tiles.")
mode = BOT_EAT_TILE
update_icon(UPDATE_OVERLAYS)
- addtimer(CALLBACK(src, PROC_REF(do_eattile), T), 2 SECONDS)
+ addtimer(CALLBACK(src, PROC_REF(do_eat_tile), T), 2 SECONDS)
-/mob/living/simple_animal/bot/floorbot/proc/do_eattile(obj/item/stack/tile/plasteel/T)
+/mob/living/simple_animal/bot/floorbot/proc/do_eat_tile(obj/item/stack/tile/plasteel/T)
if(isnull(T))
target = null
mode = BOT_IDLE
@@ -359,30 +370,39 @@
else
amount += T.amount
qdel(T)
+ anchored = FALSE
target = null
mode = BOT_IDLE
update_icon(UPDATE_OVERLAYS)
-/mob/living/simple_animal/bot/floorbot/proc/start_maketile(obj/item/stack/sheet/metal/M)
+/mob/living/simple_animal/bot/floorbot/proc/start_make_tile(obj/item/stack/sheet/metal/M)
if(!istype(M, /obj/item/stack/sheet/metal))
return
+ anchored = TRUE
visible_message("[src] begins to create tiles.")
mode = BOT_MAKE_TILE
update_icon(UPDATE_OVERLAYS)
- addtimer(CALLBACK(src, PROC_REF(do_maketile), M), 2 SECONDS)
+ addtimer(CALLBACK(src, PROC_REF(do_make_tile), M), 2 SECONDS)
-/mob/living/simple_animal/bot/floorbot/proc/do_maketile(obj/item/stack/sheet/metal/M)
+/mob/living/simple_animal/bot/floorbot/proc/do_make_tile(obj/item/stack/sheet/metal/M)
if(isnull(M))
target = null
mode = BOT_IDLE
return
- var/obj/item/stack/tile/plasteel/T = new /obj/item/stack/tile/plasteel
- T.amount = 4
- T.forceMove(M.loc)
+
+ if((amount + 4) > MAX_AMOUNT) // 1 metal = 4 tiles, hence + 4
+ var/missing_amount = MAX_AMOUNT - amount
+ var/extra = amount + 4 - MAX_AMOUNT
+ amount += missing_amount
+ new /obj/item/stack/tile/plasteel(get_turf(src), extra)
+ else
+ amount += 4
+
if(M.amount > 1)
- M.amount--
+ M.amount --
else
qdel(M)
+ anchored = FALSE
target = null
mode = BOT_IDLE
update_icon(UPDATE_OVERLAYS)
@@ -408,7 +428,7 @@
if(prob(50))
drop_part(robot_arm, Tsec)
- while(amount)//Dumps the tiles into the appropriate sized stacks
+ while(amount)// Dumps the tiles into the appropriate sized stacks
if(amount >= 16)
var/obj/item/stack/tile/plasteel/T = new (Tsec)
T.amount = 16
@@ -425,9 +445,9 @@
if(isturf(A))
repair(A)
else if(istype(A,/obj/item/stack/tile/plasteel))
- start_eattile(A)
+ start_eat_tile(A)
else if(istype(A,/obj/item/stack/sheet/metal))
- start_maketile(A)
+ start_make_tile(A)
else
..()