From df902d50fc09a002b182807085511cb08c401086 Mon Sep 17 00:00:00 2001 From: GunHog Date: Sun, 3 May 2015 17:31:10 -0500 Subject: [PATCH 1/5] Bots Revamp - Viciously rips radio code from bots, replacing it with something better and faster! - Bot patrol logic redesigned, much faster. - Gives all bots Robotics access for easy patrol activation. - Bot navigation beacons are no longer radios. Instead, they are maintained in a global list. - Navbeacons can now be accessed by Roboticists, and they use a better UI. - PDA bot code rewritten. They no longer use radio objects at all! - Captain now has all-access! His cartridge now has everything except Mime and Clown functions. - There is now one button across all PDAs for accessing bots. Only bots you have access to control will show on the list. - Buffed the signaler cartridge! It may now be used to signal on all valid frequencies. - The AI's botcall interface now includes the bot's model, so it can always identify the type of bot it is controlling. PDAs have this as well. - Spilled my blood to begin Jordie's dark ritual. --- code/_globalvars/lists/objects.dm | 5 +- code/game/machinery/bots/bots.dm | 262 +++++---------- code/game/machinery/bots/cleanbot.dm | 7 +- code/game/machinery/bots/ed209bot.dm | 3 +- code/game/machinery/bots/floorbot.dm | 3 +- code/game/machinery/bots/medbot.dm | 9 +- code/game/machinery/bots/mulebot.dm | 269 +++++---------- code/game/machinery/bots/secbot.dm | 3 +- code/game/machinery/navbeacon.dm | 82 ++--- code/game/objects/items/devices/PDA/PDA.dm | 15 +- code/game/objects/items/devices/PDA/cart.dm | 313 ++++++------------ code/game/objects/items/devices/PDA/radio.dm | 215 +----------- code/modules/mob/living/silicon/ai/ai.dm | 4 +- html/changelogs/Gun-Hog-Bots-Radio-Revamp.yml | 14 + 14 files changed, 328 insertions(+), 876 deletions(-) create mode 100644 html/changelogs/Gun-Hog-Bots-Radio-Revamp.yml diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm index 975897168faf7..6855ed2efcbc8 100644 --- a/code/_globalvars/lists/objects.dm +++ b/code/_globalvars/lists/objects.dm @@ -4,8 +4,11 @@ var/global/list/airlocks = list() //list of all airlocks var/global/list/mechas_list = list() //list of all mechs. Used by hostile mobs target tracking. var/global/list/shuttle_caller_list = list() //list of all communication consoles and AIs, for automatic shuttle calls when there are none. var/global/list/machines = list() //NOTE: this is a list of ALL machines now. The processing machines list is SSmachine.processing ! +var/global/list/navbeacons = list() //list of all bot nagivation beacons, used for patrolling. +var/global/list/deliverybeacons = list() //list of all MULEbot delivery beacons. +var/global/list/deliverybeacontags = list() //list of all tags associated with delivery beacons. var/global/list/chemical_reactions_list //list of all /datum/chemical_reaction datums. Used during chemical reactions var/global/list/chemical_reagents_list //list of all /datum/reagent datums indexed by reagent id. Used by chemistry stuff var/global/list/surgeries_list = list() //list of all surgeries by name, associated with their path. -var/global/list/table_recipes = list() //list of all table craft recipes +var/global/list/table_recipes = list() //list of all table craft recipes \ No newline at end of file diff --git a/code/game/machinery/bots/bots.dm b/code/game/machinery/bots/bots.dm index 9e33f0731db22..77c7bc33a6cf6 100644 --- a/code/game/machinery/bots/bots.dm +++ b/code/game/machinery/bots/bots.dm @@ -46,14 +46,14 @@ var/turf/nearest_beacon_loc // the nearest beacon's location var/beacon_freq = 1445 // navigation beacon frequency - var/control_freq = 1447 // bot control frequency + var/model = "" //The type of bot it is. var/bot_type = 0 //The type of bot it is, for radio control. #define SEC_BOT 1 // Secutritrons (Beepsky) and ED-209s #define MULE_BOT 2 // MULEbots - #define FLOOR_BOT 3 // Floorbots - #define CLEAN_BOT 4 // Cleanbots - #define MED_BOT 5 // Medibots + #define FLOOR_BOT 4 // Floorbots + #define CLEAN_BOT 8 // Cleanbots + #define MED_BOT 16 // Medibots #define DEFAULT_SCAN_RANGE 7 //default view range for finding targets. @@ -77,10 +77,18 @@ #define BOT_NAV 16 // computing navigation #define BOT_WAIT_FOR_NAV 17 // waiting for nav computation #define BOT_NO_ROUTE 18 // no destination beacon found (or no route) - var/list/mode_name = list("In Pursuit","Preparing to Arrest","Arresting","Beginning Patrol","Patrolling","Summoned by PDA", \ - "Cleaning", "Repairing", "Proceeding to work site","Healing","Responding","Loading/Unloading","Navigating to Delivery Location","Navigating to Home", \ - "Waiting for clear path","Calculating navigation path","Pinging beacon network","Unable to reach destination") - //This holds text for what the bot is mode doing, reported on the AI's 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", \ + "Proceeding to AI waypoint", "Loading/Unloading", "Navigating to Delivery Location", "Navigating to Home", \ + "Waiting for clear path", "Calculating navigation path", "Pinging beacon network", "Unable to reach destination") + //This holds text for what the bot is mode doing, reported on the remote bot control interface. + +/obj/machinery/bot/proc/get_mode() + if(!mode) + return "Idle" + else + return mode_name[mode] /obj/machinery/bot/proc/turn_on() if(stat) return 0 @@ -98,23 +106,15 @@ SSbot.processing += src //Global bot list SSbp.insertBot(src) botcard = new /obj/item/weapon/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. + botcard.access += access_robotics set_custom_texts() Radio = new /obj/item/device/radio(src) Radio.listening = 0 //Makes bot radios transmit only so no one hears things while adjacent to one. - spawn(5) - add_to_beacons() /obj/machinery/bot/Destroy() - if(radio_controller) - radio_controller.remove_object(src,beacon_freq) - radio_controller.remove_object(src,control_freq) ..() -/obj/machinery/bot/proc/add_to_beacons() //Master radio control for bots. Must be placed in the bot's local New() to support map spawned bots. - if(radio_controller) - radio_controller.add_object(src, beacon_freq, filter = RADIO_NAVBEACONS) - radio_controller.add_object(src, control_freq) - /obj/machinery/bot/proc/explode() SSbot.processing -= src @@ -191,7 +191,7 @@ switch(href_list["operation"]) if("patrol") auto_patrol = !auto_patrol - mode = BOT_IDLE + bot_reset() if("remote") remote_disabled = !remote_disabled if("hack") @@ -524,12 +524,12 @@ obj/machinery/bot/proc/start_patrol() spawn(0) calc_path() // Find a route to it if(path.len == 0) - patrol_target = 0 + patrol_target = null return mode = BOT_PATROL else // no patrol target, so need a new one - find_patrol_target() speak("Engaging patrol mode.") + find_patrol_target() tries++ return @@ -538,8 +538,9 @@ obj/machinery/bot/proc/start_patrol() /obj/machinery/bot/proc/patrol_step() if(loc == patrol_target) // reached target - - at_patrol_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. return else if(path.len > 0 && patrol_target) // valid path @@ -562,7 +563,8 @@ obj/machinery/bot/proc/start_patrol() spawn(2) calc_path(next) if(path.len == 0) - find_patrol_target() + find_patrol_target() //Start looking for the next nearest beacon + tries++ else blockcount = 0 tries = 0 @@ -576,167 +578,74 @@ obj/machinery/bot/proc/start_patrol() return -// finds a new patrol target +// finds the nearest beacon to self /obj/machinery/bot/proc/find_patrol_target() - send_status() - if(awaiting_beacon) // awaiting beacon response - awaiting_beacon++ - if(awaiting_beacon > 5) // wait 5 secs for beacon response - find_nearest_beacon() // then go to nearest instead - return - if(next_destination) - set_destination(next_destination) + nearest_beacon = null + new_destination = null + find_nearest_beacon() + if(nearest_beacon) + patrol_target = nearest_beacon_loc + destination = next_destination else + auto_patrol = 0 + mode = BOT_IDLE + speak("Disengaging patrol mode.") + +/obj/machinery/bot/proc/get_next_patrol_target() + // search the beacon list for the next target in the list. + for(var/obj/machinery/navbeacon/NB in navbeacons) + 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 - find_nearest_beacon() - return - - -// finds the nearest beacon to self -// signals all beacons matching the patrol code /obj/machinery/bot/proc/find_nearest_beacon() - nearest_beacon = null - new_destination = "__nearest__" - post_signal(beacon_freq, "findbeacon", "patrol") - awaiting_beacon = 1 - spawn(10) - awaiting_beacon = 0 - if(nearest_beacon) - set_destination(nearest_beacon) - tries = 0 - else + for(var/obj/machinery/navbeacon/NB in navbeacons) + var/dist = get_dist(src, NB) + if(nearest_beacon) //Loop though the beacon net to find the true closest beacon. + //Ignore the beacon if were are located on it. + if(dist>1 && dist 1) //Begin the search, save this one for comparison on the next loop. + nearest_beacon = NB.location + nearest_beacon_loc = NB.loc + patrol_target = nearest_beacon_loc + destination = nearest_beacon + +//PDA control. Some bots, especially MULEs, may have more parameters. +/obj/machinery/bot/proc/bot_control(var/command, mob/user, var/turf/user_turf, var/list/user_access = list()) + if(!on || emagged == 2 || remote_disabled) //Emagged bots do not respect anyone's authority! Bots with their remote controls off cannot get commands. + return 1 //ACCESS DENIED + // process control input + switch(command) + if("patroloff") + bot_reset() //HOLD IT!! auto_patrol = 0 - mode = BOT_IDLE - speak("Disengaging patrol mode.") - send_status() - - -/obj/machinery/bot/proc/at_patrol_target() - - find_patrol_target() - return - - -// sets the current destination -// signals all beacons matching the patrol code -// beacons will return a signal giving their locations -/obj/machinery/bot/proc/set_destination(var/new_dest) - new_destination = new_dest - post_signal(beacon_freq, "findbeacon", "patrol") - awaiting_beacon = 1 - - -// receive a radio signal -// used for beacon reception - -/obj/machinery/bot/receive_signal(datum/signal/signal) - //log_admin("DEBUG \[[// world.timeofday]\]: /obj/machinery/bot/receive_signal([signal.debug_print()])") - if(!on) - return -/* - if(!signal.data["beacon"]) - - for(var/x in signal.data) - world << "* [x] = [signal.data[x]]" - */ - - var/recv = signal.data["command"] - // process all-bot input - - if(recv=="bot_status") - send_status() + return - // check to see if we are the commanded bot - if(signal.data["active"] == src) - if(emagged == 2 || remote_disabled) //Emagged bots do not respect anyone's authority! Bots with their remote controls off cannot get commands. + if("patrolon") + auto_patrol = 1 return - // process control input - switch(recv) - if("stop") - bot_reset() //HOLD IT!! - auto_patrol = 0 - return - if("go") - auto_patrol = 1 - return + if("summon") + bot_reset() + summon_target = user_turf + if(user_access.len != 0) + botcard.access = user_access + prev_access //Adds the user's access, if any. + mode = BOT_SUMMON + speak("Responding.", radio_frequency) + calc_summon_path() + return - if("summon") - bot_reset() - var/list/user_access = signal.data["useraccess"] - summon_target = signal.data["target"] //Location of the user - if(user_access.len != 0) - botcard.access = user_access + prev_access //Adds the user's access, if any. - mode = BOT_SUMMON - calc_summon_path() - speak("Responding.", radio_frequency) - return - // receive response from beacon - recv = signal.data["beacon"] - var/valid = signal.data["patrol"] - if(!recv || !valid) - return - if(recv == new_destination) // if the recvd beacon location matches the set destination - // the we will navigate there - destination = new_destination - patrol_target = signal.source.loc - next_destination = signal.data["next_patrol"] - awaiting_beacon = 0 - - // if looking for nearest beacon - else if(new_destination == "__nearest__") - var/dist = get_dist(src,signal.source.loc) - if(nearest_beacon) - // note we ignore the beacon we are located at - if(dist>1 && dist 1) - nearest_beacon = recv - nearest_beacon_loc = signal.source.loc return -// send a radio signal with a single data key/value pair -/obj/machinery/bot/proc/post_signal(var/freq, var/key, var/value) - post_signal_multiple(freq, list("[key]" = value) ) - -// send a radio signal with multiple data key/values -/obj/machinery/bot/proc/post_signal_multiple(var/freq, var/list/keyval) - var/datum/radio_frequency/frequency = radio_controller.return_frequency(freq) - - if(!frequency) return - - var/datum/signal/signal = new() - signal.source = src - signal.transmission_method = 1 -// for(var/key in keyval) -// signal.data[key] = keyval[key] - signal.data = keyval -// world << "sent [key],[keyval[key]] on [freq]" - if(signal.data["findbeacon"]) - frequency.post_signal(src, signal, filter = RADIO_NAVBEACONS) - else - frequency.post_signal(src, signal) - -// signals bot status etc. to controller -/obj/machinery/bot/proc/send_status() - if(remote_disabled || emagged == 2) - return - var/list/kv = list( - "type" = bot_type, - "name" = name, - "loca" = get_area(src), // area - "mode" = mode, - "sect" = z // z-level, or "sector" - ) - post_signal_multiple(control_freq, kv) - - obj/machinery/bot/proc/bot_summon() // summoned to PDA summon_step() @@ -750,10 +659,11 @@ obj/machinery/bot/proc/bot_summon() /obj/machinery/bot/proc/calc_summon_path(var/turf/avoid) check_bot_access() - path = get_path_to(loc, summon_target, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance_cardinal, 0, 150, id=botcard, exclude=avoid) - if(!path.len || tries >= 5) //Cannot reach target. Give up and announce the issue. - speak("Summon command failed, destination unreachable.",radio_frequency) - bot_reset() + spawn() + path = get_path_to(loc, summon_target, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance_cardinal, 0, 150, id=botcard, exclude=avoid) + if(!path.len || tries >= 5) //Cannot reach target. Give up and announce the issue. + speak("Summon command failed, destination unreachable.",radio_frequency) + bot_reset() /obj/machinery/bot/proc/summon_step() diff --git a/code/game/machinery/bots/cleanbot.dm b/code/game/machinery/bots/cleanbot.dm index 2b327a0da306e..6b151a3d4f967 100644 --- a/code/game/machinery/bots/cleanbot.dm +++ b/code/game/machinery/bots/cleanbot.dm @@ -39,6 +39,7 @@ var/next_dest_loc radio_frequency = SERV_FREQ //Service bot_type = CLEAN_BOT + model = "Cleanbot" /obj/machinery/bot/cleanbot/New() ..() @@ -46,7 +47,7 @@ icon_state = "cleanbot[on]" var/datum/job/janitor/J = new/datum/job/janitor - botcard.access = J.get_access() + botcard.access += J.get_access() prev_access = botcard.access /obj/machinery/bot/cleanbot/turn_on() @@ -103,10 +104,6 @@ text("[on ? "On" : "Off"]")) blood =!blood get_targets() updateUsrDialog() - if("freq") - var/freq = text2num(input("Select frequency for navigation beacons", "Frequency", num2text(beacon_freq / 10))) * 10 - if (freq > 0) - beacon_freq = freq updateUsrDialog() /obj/machinery/bot/cleanbot/attackby(obj/item/weapon/W, mob/user as mob, params) diff --git a/code/game/machinery/bots/ed209bot.dm b/code/game/machinery/bots/ed209bot.dm index c198b79897498..b4ecddd72c757 100644 --- a/code/game/machinery/bots/ed209bot.dm +++ b/code/game/machinery/bots/ed209bot.dm @@ -35,6 +35,7 @@ var/shoot_sound = 'sound/weapons/Taser.ogg' radio_frequency = SEC_FREQ bot_type = SEC_BOT + model = "ED-209" /obj/item/weapon/ed209_assembly @@ -58,7 +59,7 @@ set_weapon() //giving it the right projectile and firing sound. spawn(3) var/datum/job/detective/J = new/datum/job/detective - botcard.access = J.get_access() + botcard.access += J.get_access() prev_access = botcard.access if(lasercolor) diff --git a/code/game/machinery/bots/floorbot.dm b/code/game/machinery/bots/floorbot.dm index fb262db136f0d..9ab6f15d70723 100644 --- a/code/game/machinery/bots/floorbot.dm +++ b/code/game/machinery/bots/floorbot.dm @@ -50,6 +50,7 @@ var/targetdirection radio_frequency = ENG_FREQ //Engineering channel bot_type = FLOOR_BOT + model = "Floorbot" var/process_type //Determines what to do when process_scan() recieves a target. See process_scan() for details. #define HULL_BREACH 1 #define BRIDGE_MODE 2 @@ -62,7 +63,7 @@ ..() updateicon() var/datum/job/engineer/J = new/datum/job/engineer - botcard.access = J.get_access() + botcard.access += J.get_access() prev_access = botcard.access /obj/machinery/bot/floorbot/turn_on() diff --git a/code/game/machinery/bots/medbot.dm b/code/game/machinery/bots/medbot.dm index 3ac38374cc6d7..1aa670c9ac01d 100644 --- a/code/game/machinery/bots/medbot.dm +++ b/code/game/machinery/bots/medbot.dm @@ -40,6 +40,7 @@ var/treat_virus = 1 //If on, the bot will attempt to treat viral infections, curing them if possible. var/shut_up = 0 //self explanatory :) bot_type = MED_BOT + model = "Medibot" /obj/machinery/bot/medbot/mysterious name = "\improper Mysterious Medibot" @@ -97,13 +98,11 @@ if(skin) overlays += image('icons/obj/aibots.dmi', "medskin_[skin]") - if(isnull(botcard_access) || (botcard_access.len < 1)) - var/datum/job/doctor/J = new/datum/job/doctor - botcard.access = J.get_access() - else - botcard.access = botcard_access + var/datum/job/doctor/J = new/datum/job/doctor + botcard.access += J.get_access() prev_access = botcard.access + /obj/machinery/bot/medbot/turn_on() . = ..() updateicon() diff --git a/code/game/machinery/bots/mulebot.dm b/code/game/machinery/bots/mulebot.dm index 17e2305723b1e..b62b45b547eeb 100644 --- a/code/game/machinery/bots/mulebot.dm +++ b/code/game/machinery/bots/mulebot.dm @@ -19,10 +19,8 @@ var/global/mulebot_count = 0 fire_dam_coeff = 0.7 brute_dam_coeff = 0.5 var/atom/movable/load = null // the loaded crate (usually) - var/list/delivery_beacons = list() //List of beacons that serve as delivery locations. - beacon_freq = 1400 - control_freq = 1447 bot_type = MULE_BOT + model = "MULE" blood_DNA = list() suffix = "" @@ -238,7 +236,7 @@ obj/machinery/bot/mulebot/bot_reset() //user << browse("M.U.L.E. Mk. III [suffix ? "([suffix])" : ""][dat]", "window=mulebot;size=350x500") //onclose(user, "mulebot") - var/datum/browser/popup = new(user, "mulebot", "M.U.L.E. Mk. V [suffix ? "([suffix])" : ""]", 350, 550) + var/datum/browser/popup = new(user, "mulebot", "M.U.L.E. Mk. V [suffix ? "([suffix])" : ""]", 350, 600) popup.set_content(dat) popup.set_title_image(user.browse_rsc_icon(icon, icon_state)) popup.open() @@ -258,6 +256,7 @@ obj/machinery/bot/mulebot/bot_reset() usr.set_machine(src) switch(href_list["op"]) + if("lock", "unlock") toggle_lock(usr) @@ -295,74 +294,83 @@ obj/machinery/bot/mulebot/bot_reset() usr.visible_message("[usr] inserts a power cell into [src].", "You insert the power cell into [src].") updateDialog() + else + bot_control(href_list["op"], usr) - if("stop") - if(mode >= BOT_DELIVER) - bot_reset() - updateDialog() + updateDialog() + //updateUsrDialog() + else + usr << browse(null, "window=mulebot") + usr.unset_machine() + return - if("go") - if(mode == BOT_IDLE) - start() - updateDialog() +/obj/machinery/bot/mulebot/bot_control(var/command, mob/user, pda= 0) + if(pda && !wires.RemoteRX()) //MULE wireless is controlled by wires. + return - if("home") - if(mode == BOT_IDLE || mode == BOT_DELIVER) - start_home() - updateDialog() + switch(command) - if("destination") - refresh=0 - var/new_dest = input("Select M.U.L.E. Destination", "Mulebot [suffix ? "([suffix])" : ""]", destination) as null|anything in delivery_beacons - refresh=1 - if(new_dest) - set_destination(new_dest) - - - if("setid") - refresh=0 - var/new_id = stripped_input(usr, "Enter new bot ID", "Mulebot [suffix ? "([suffix])" : ""]", suffix, MAX_NAME_LEN) - refresh=1 - if(new_id) - suffix = new_id - name = "\improper Mulebot ([suffix])" - updateDialog() + if("stop") + if(mode >= BOT_DELIVER) + bot_reset() + updateDialog() - if("sethome") - refresh=0 - var/new_home = stripped_input(usr, "Enter new home tag", "Mulebot [suffix ? "([suffix])" : ""]", home_destination) - refresh=1 - if(new_home) - home_destination = new_home - updateDialog() + if("go") + if(mode == BOT_IDLE) + start() + updateDialog() + + if("home") + if(mode == BOT_IDLE || mode == BOT_DELIVER) + start_home() + updateDialog() - if("unload") - if(load && mode !=1) - if(loc == target) - unload(loaddir) - else - unload(0) + if("destination") + refresh=0 + var/new_dest = input(user, "Select M.U.L.E. Destination", "Mulebot [suffix ? "([suffix])" : ""]", destination) as null|anything in deliverybeacontags + refresh=1 + if(new_dest) + set_destination(new_dest) + + + if("setid") + refresh=0 + var/new_id = stripped_input(user, "Enter new bot ID", "Mulebot [suffix ? "([suffix])" : ""]", suffix, MAX_NAME_LEN) + refresh=1 + if(new_id) + suffix = new_id + name = "\improper Mulebot ([suffix])" + updateDialog() - if("autoret") - auto_return = !auto_return + if("sethome") + refresh=0 + var/new_home = stripped_input(user, "Enter new home tag", "Mulebot [suffix ? "([suffix])" : ""]", home_destination) + refresh=1 + if(new_home) + home_destination = new_home + updateDialog() - if("autopick") - auto_pickup = !auto_pickup + if("unload") + if(load && mode !=1) + if(loc == target) + unload(loaddir) + else + unload(0) - if("report") - report_delivery = !report_delivery + if("autoret") + auto_return = !auto_return - if("close") - usr.unset_machine() - usr << browse(null,"window=mulebot") + if("autopick") + auto_pickup = !auto_pickup + + if("report") + report_delivery = !report_delivery + + if("close") + usr.unset_machine() + usr << browse(null,"window=mulebot") - updateDialog() - //updateUsrDialog() - else - usr << browse(null, "window=mulebot") - usr.unset_machine() - return @@ -438,7 +446,6 @@ obj/machinery/bot/mulebot/bot_reset() M.client.eye = src mode = BOT_IDLE - send_status() // called to unload the bot // argument is optional direction to unload @@ -575,9 +582,6 @@ obj/machinery/bot/mulebot/bot_reset() path -= loc - if(mode == BOT_BLOCKED) - spawn(1) - send_status() if(destination == home_destination) mode = BOT_GO_HOME @@ -656,11 +660,10 @@ obj/machinery/bot/mulebot/bot_reset() // sets the current destination // signals all beacons matching the delivery code // beacons will return a signal giving their locations -/obj/machinery/bot/mulebot/set_destination(var/new_dest) - spawn(0) - new_destination = new_dest - post_signal(beacon_freq, "findbeacon", "delivery") - updateDialog() +/obj/machinery/bot/mulebot/proc/set_destination(var/new_dest) + new_destination = new_dest + get_nav() + updateDialog() // starts bot moving to current destination /obj/machinery/bot/mulebot/proc/start() @@ -669,6 +672,7 @@ obj/machinery/bot/mulebot/bot_reset() else mode = BOT_DELIVER icon_state = "mulebot[(wires.MobAvoid() != 0)]" + get_nav() // starts bot moving to home // sends a beacon query to find @@ -695,7 +699,8 @@ obj/machinery/bot/mulebot/bot_reset() radio_frequency = AIPRIV_FREQ //Report on AI Private instead if the AI is controlling us. if(load) // if loaded, unload at target - speak("Destination [destination] reached. Unloading [load].",radio_frequency) + if(report_delivery) + speak("Destination [destination] reached. Unloading [load].",radio_frequency) unload(loaddir) else // not loaded @@ -721,8 +726,6 @@ obj/machinery/bot/mulebot/bot_reset() else bot_reset() // otherwise go idle - send_status() // report status to anyone listening - return // called when bot bumps into anything @@ -771,73 +774,19 @@ obj/machinery/bot/mulebot/bot_reset() unload(0) return -// receive a radio signal -// used for control and beacon reception -/obj/machinery/bot/mulebot/receive_signal(datum/signal/signal) - - if(!on) +//Update navigation data. Called when commanded to deliver, return home, or a route update is needed... +/obj/machinery/bot/mulebot/proc/get_nav() +//Formerly the beacon reception proc, except that it is no longer a potential lag bomb called TEN TIMES A SECOND OR MORE in some cases! + if(!on || !wires.BeaconRX()) return - /* - world << "rec signal: [signal.source]" - for(var/x in signal.data) - world << "* [x] = [signal.data[x]]" - */ - var/recv = signal.data["command"] - // process all-bot input - if(recv=="bot_status" && wires.RemoteRX()) - send_status() - - - recv = signal.data["command [suffix]"] - if(wires.RemoteRX()) - // process control input - switch(recv) - if("stop") - bot_reset() - return - - if("go") - start() - return - - if("target") - set_destination(signal.data["destination"] ) - return - - if("unload") - if(loc == target) - unload(loaddir) - else - unload(0) - return - - if("home") - start_home() - return - - if("bot_status") - send_status() - return - - if("autoret") - auto_return = text2num(signal.data["value"]) - return - - if("autopick") - auto_pickup = text2num(signal.data["value"]) - return - - // receive response from beacon - recv = signal.data["beacon"] - - if(wires.BeaconRX()) - if(recv == new_destination) // if the recvd beacon location matches the set destination + for(var/obj/machinery/navbeacon/NB in deliverybeacons) + if(NB.location == new_destination) // if the beacon location matches the set destination // the we will navigate there destination = new_destination - target = signal.source.loc - var/direction = signal.data["dir"] // this will be the load/unload dir + target = NB.loc + var/direction = NB.dir // this will be the load/unload dir if(direction) loaddir = text2num(direction) else @@ -847,58 +796,6 @@ obj/machinery/bot/mulebot/bot_reset() calc_path() updateDialog() - //Detects and stores current active delivery beacons. - if(signal.data["beacon"]) - if(!delivery_beacons) - delivery_beacons = new() - delivery_beacons[signal.data["beacon"] ] = signal.source - -// send a radio signal with a single data key/value pair -/obj/machinery/bot/mulebot/post_signal(var/freq, var/key, var/value) - post_signal_multiple(freq, list("[key]" = value) ) - -// send a radio signal with multiple data key/values -/obj/machinery/bot/mulebot/post_signal_multiple(var/freq, var/list/keyval) - - if(freq == beacon_freq && !(wires.BeaconRX())) - return - if(freq == control_freq && !(wires.RemoteTX())) - return - - var/datum/radio_frequency/frequency = radio_controller.return_frequency(freq) - - if(!frequency) return - - - - var/datum/signal/signal = new() - signal.source = src - signal.transmission_method = 1 - //for(var/key in keyval) - // signal.data[key] = keyval[key] - signal.data = keyval - //world << "sent [key],[keyval[key]] on [freq]" - if (signal.data["findbeacon"]) - frequency.post_signal(src, signal, filter = RADIO_NAVBEACONS) - else - frequency.post_signal(src, signal) - -// signals bot status etc. to controller -/obj/machinery/bot/mulebot/send_status() - var/list/kv = list( - "type" = MULE_BOT, - "name" = suffix, - "loca" = get_area(src), - "mode" = mode, - "powr" = (cell ? cell.percent() : 0), - "dest" = destination, - "home" = home_destination, - "load" = load, - "retn" = auto_return, - "pick" = auto_pickup, - ) - post_signal_multiple(control_freq, kv) - /obj/machinery/bot/mulebot/emp_act(severity) if (cell) cell.emp_act(severity) diff --git a/code/game/machinery/bots/secbot.dm b/code/game/machinery/bots/secbot.dm index b8a0114fc33b2..d45db2442fe01 100644 --- a/code/game/machinery/bots/secbot.dm +++ b/code/game/machinery/bots/secbot.dm @@ -25,6 +25,7 @@ var/arrest_type = 0 //If true, don't handcuff radio_frequency = SEC_FREQ //Security channel bot_type = SEC_BOT + model = "Securitron" /obj/machinery/bot/secbot/beepsky name = "Officer Beep O'sky" @@ -55,7 +56,7 @@ spawn(3) var/datum/job/detective/J = new/datum/job/detective - botcard.access = J.get_access() + botcard.access += J.get_access() prev_access = botcard.access diff --git a/code/game/machinery/navbeacon.dm b/code/game/machinery/navbeacon.dm index 7c2a44e115cd9..e23456392ae87 100644 --- a/code/game/machinery/navbeacon.dm +++ b/code/game/machinery/navbeacon.dm @@ -1,5 +1,5 @@ // Navigation beacon for AI robots -// Functions as a transponder: looks for incoming signal matching +// No longer exists on the radio controller, it is managed by a global list. /obj/machinery/navbeacon @@ -18,7 +18,7 @@ var/list/codes // assoc. list of transponder codes var/codes_txt = "" // codes as set on map: "tag1;tag2" or "tag1=value;tag2=value" - req_access = list(access_engine) + req_access = list(access_engine, access_robotics) /obj/machinery/navbeacon/New() ..() @@ -27,14 +27,15 @@ var/turf/T = loc hide(T.intact) - - spawn(5) // must wait for map loading to finish - if(radio_controller) - radio_controller.add_object(src, freq, RADIO_NAVBEACONS) + if(codes["patrol"]) + navbeacons += src //Register with the patrol list! + if(codes["delivery"]) + deliverybeacons += src + deliverybeacontags += location /obj/machinery/navbeacon/Destroy() - if(radio_controller) - radio_controller.remove_object(src, freq) + navbeacons &= src //Remove from beacon list, if in one. + deliverybeacons &= src ..() // set the transponder codes assoc list from codes_txt @@ -72,38 +73,6 @@ else icon_state = "[state]" - -// look for a signal of the form "findbeacon=X" -// where X is any -// or the location -// or one of the set transponder keys -// if found, return a signal -/obj/machinery/navbeacon/receive_signal(datum/signal/signal) - - var/request = signal.data["findbeacon"] - if(request && ((request in codes) || request == "any" || request == location)) - spawn(1) - post_signal() - -// return a signal giving location and transponder codes - -/obj/machinery/navbeacon/proc/post_signal() - - var/datum/radio_frequency/frequency = radio_controller.return_frequency(freq) - - if(!frequency) return - - var/datum/signal/signal = new() - signal.source = src - signal.transmission_method = 1 - signal.data["beacon"] = location - - for(var/key in codes) - signal.data[key] = codes[key] - - frequency.post_signal(src, signal, filter = RADIO_NAVBEACONS) - - /obj/machinery/navbeacon/attackby(var/obj/item/I, var/mob/user, params) var/turf/T = loc if(T.intact) @@ -152,7 +121,6 @@ if(locked && !ai) t = {"Navigation Beacon

(swipe card to unlock controls)
-Frequency: [format_frequency(freq)]

Location: [location ? location : "(none)"]
Transponder Codes: