"
else
if(!ai)
- dat += "The maintenance hatch is open.
"
- dat += "Power cell: "
+ dat += "
The maintenance hatch is open.
"
+ dat += "Power cell: "
if(cell)
dat += "Installed "
else
@@ -239,10 +233,14 @@ var/global/mulebot_count = 0
dat += wires()
else
- dat += "The bot is in maintenance mode and cannot be controlled. "
+ dat += "
The bot is in maintenance mode and cannot be controlled.
"
- user << browse("Mulebot [suffix ? "([suffix])" : ""][dat]", "window=mulebot;size=350x500")
- onclose(user, "mulebot")
+ //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, 500)
+ popup.set_content(dat)
+ popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
+ popup.open()
return
// returns the wire panel text
@@ -255,7 +253,7 @@ var/global/mulebot_count = 0
return
if (usr.stat)
return
- if ((in_range(src, usr) && istype(src.loc, /turf)) || (istype(usr, /mob/living/silicon)))
+ if ((in_range(src, usr) && istype(loc, /turf)) || (istype(usr, /mob/living/silicon)))
usr.set_machine(src)
switch(href_list["op"])
@@ -263,11 +261,11 @@ var/global/mulebot_count = 0
toggle_lock(usr)
if("power")
- if (src.on)
+ if (on)
turn_off()
else if (cell && !open)
if (!turn_on())
- usr << "\red You can't switch on [src]."
+ usr << "You can't switch on [src]."
return
else
return
@@ -282,7 +280,7 @@ var/global/mulebot_count = 0
cell.add_fingerprint(usr)
cell = null
- usr.visible_message("\blue [usr] removes the power cell from [src].", "\blue You remove the power cell from [src].")
+ usr.visible_message("[usr] removes the power cell from [src].", "You remove the power cell from [src].")
updateDialog()
if("cellinsert")
@@ -294,28 +292,28 @@ var/global/mulebot_count = 0
C.loc = src
C.add_fingerprint(usr)
- usr.visible_message("\blue [usr] inserts a power cell into [src].", "\blue You insert the power cell into [src].")
+ usr.visible_message("[usr] inserts a power cell into [src].", "You insert the power cell into [src].")
updateDialog()
if("stop")
- if(mode >=2)
- mode = 0
+ if(mode >= BOT_DELIVER)
+ bot_reset()
updateDialog()
if("go")
- if(mode == 0)
+ if(mode == BOT_IDLE)
start()
updateDialog()
if("home")
- if(mode == 0 || mode == 2)
+ if(mode == BOT_IDLE || mode == BOT_DELIVER)
start_home()
updateDialog()
if("destination")
refresh=0
- var/new_dest = input("Enter new destination tag", "Mulebot [suffix ? "([suffix])" : ""]", destination) as text|null
+ 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)
@@ -351,12 +349,15 @@ var/global/mulebot_count = 0
if("autopick")
auto_pickup = !auto_pickup
+ if("report")
+ report_delivery = !report_delivery
+
if("close")
usr.unset_machine()
usr << browse(null,"window=mulebot")
updateDialog()
- //src.updateUsrDialog()
+ //updateUsrDialog()
else
usr << browse(null, "window=mulebot")
usr.unset_machine()
@@ -369,12 +370,12 @@ var/global/mulebot_count = 0
return !open && cell && cell.charge > 0 && wires.HasPower()
/obj/machinery/bot/mulebot/proc/toggle_lock(var/mob/user)
- if(src.allowed(user))
+ if(allowed(user))
locked = !locked
updateDialog()
return 1
else
- user << "\red Access denied."
+ user << "Access denied."
return 0
// mousedrop a crate to load the bot
@@ -397,8 +398,8 @@ var/global/mulebot_count = 0
// called to load a crate
/obj/machinery/bot/mulebot/proc/load(var/atom/movable/C)
if(wires.LoadCheck() && !istype(C,/obj/structure/closet/crate))
- src.visible_message("[src] makes a sighing buzz.", "You hear an electronic buzzing sound.")
- playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
+ visible_message("[src] makes a sighing buzz.", "You hear an electronic buzzing sound.")
+ playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
return // if not emagged, only allow crates to be loaded
//I'm sure someone will come along and ask why this is here... well people were dragging screen items onto the mule, and that was not cool.
@@ -410,19 +411,16 @@ var/global/mulebot_count = 0
if(get_dist(C, src) > 1 || load || !on)
return
- for(var/obj/structure/plasticflaps/P in src.loc)//Takes flaps into account
- if(!CanPass(C,P))
- return
- mode = 1
+ mode = BOT_LOADING
// if a create, close before loading
var/obj/structure/closet/crate/crate = C
if(istype(crate))
crate.close()
- C.loc = src.loc
+ C.loc = loc
sleep(2)
- if(C.loc != src.loc) //To prevent you from going onto more thano ne bot.
+ if(C.loc != loc) //To prevent you from going onto more thano ne bot.
return
C.loc = src
load = C
@@ -438,22 +436,19 @@ var/global/mulebot_count = 0
M.client.perspective = EYE_PERSPECTIVE
M.client.eye = src
- mode = 0
+ mode = BOT_IDLE
send_status()
// called to unload the bot
// argument is optional direction to unload
// if zero, unload at bot's location
-/obj/machinery/bot/mulebot/proc/unload(var/dirn = 0)
+/obj/machinery/bot/mulebot/proc/unload(var/dirn)
if(!load)
return
- mode = 1
+ mode = BOT_LOADING
overlays.Cut()
- load.loc = src.loc
- load.pixel_y -= 9
- load.layer = initial(load.layer)
if(ismob(load))
var/mob/M = load
if(M.client)
@@ -461,13 +456,14 @@ var/global/mulebot_count = 0
M.client.eye = src
+ load.loc = loc
+ load.pixel_y -= 9
+ load.layer = initial(load.layer)
if(dirn)
- var/turf/T = src.loc
- T = get_step(T,dirn)
- if(CanPass(load,T))//Can't get off onto anything that wouldn't let you pass normally
+ var/turf/T = loc
+ var/turf/newT = get_step(T,dirn)
+ if(load.CanPass(load,newT)) //Can't get off onto anything that wouldn't let you pass normally
step(load, dirn)
- else
- load.loc = src.loc//Drops you right there, so you shouldn't be able to get yourself stuck
load = null
@@ -476,9 +472,9 @@ var/global/mulebot_count = 0
// with items dropping as mobs are loaded
for(var/atom/movable/AM in src)
- if(AM == cell || AM == botcard) continue
+ if(AM == cell || istype(AM , botcard) || AM == Radio) continue
- AM.loc = src.loc
+ AM.loc = loc
AM.layer = initial(AM.layer)
AM.pixel_y = initial(AM.pixel_y)
if(ismob(AM))
@@ -486,47 +482,56 @@ var/global/mulebot_count = 0
if(M.client)
M.client.perspective = MOB_PERSPECTIVE
M.client.eye = src
- mode = 0
+ mode = BOT_IDLE
+/obj/machinery/bot/mulebot/call_bot()
+ ..()
+ var/area/dest_area
+ if (path && path.len)
+ target = ai_waypoint //Target is the end point of the path, the waypoint set by the AI.
+ dest_area = get_area(target)
+ destination = format_text(dest_area.name)
+ pathset = 1 //Indicates the AI's custom path is initialized.
+ start()
-/obj/machinery/bot/mulebot/process()
+/obj/machinery/bot/mulebot/bot_process()
if(!has_power())
on = 0
return
if(on)
var/speed = (wires.Motor1() ? 1 : 0) + (wires.Motor2() ? 2 : 0)
//world << "speed: [speed]"
+ var/num_steps = 0
switch(speed)
if(0)
// do nothing
if(1)
- process_bot()
- spawn(2)
- process_bot()
- sleep(2)
- process_bot()
- sleep(2)
- process_bot()
- sleep(2)
- process_bot()
+ num_steps = 10
if(2)
- process_bot()
- spawn(4)
- process_bot()
+ num_steps = 5
if(3)
- process_bot()
+ num_steps = 3
+
+ if(num_steps)
+ process_bot()
+ num_steps--
+ spawn(0)
+ for(var/i=num_steps,i>0,i--)
+ sleep(2)
+ process_bot()
if(refresh) updateDialog()
/obj/machinery/bot/mulebot/proc/process_bot()
//if(mode) world << "Mode: [mode]"
+
switch(mode)
- if(0) // idle
+ if(BOT_IDLE) // idle
icon_state = "mulebot0"
return
- if(1) // loading/unloading
+ if(BOT_LOADING) // loading/unloading
return
- if(2,3,4) // navigating to deliver,home, or blocked
+ if(BOT_DELIVER,BOT_GO_HOME,BOT_BLOCKED) // navigating to deliver,home, or blocked
if(loc == target) // reached target
at_target()
@@ -539,26 +544,28 @@ var/global/mulebot_count = 0
if(next == loc)
path -= next
return
+
+
if(istype( next, /turf/simulated))
//world << "at ([x],[y]) moving to ([next.x],[next.y])"
- if(bloodiness)
- var/turf/simulated/T=loc
- if(istype(T))
- var/goingdir=0
- var/newdir = get_dir(next, loc)
- if(newdir == dir)
- goingdir = newdir
- else
- newdir = newdir | dir
- if(newdir == 3)
- newdir = 1
- else if(newdir == 12)
- newdir = 4
- goingdir = newdir
- T.AddTracks(/obj/effect/decal/cleanable/blood/tracks/wheels,list(),0,goingdir,currentBloodColor)
+
+ if(bloodiness)
+ var/obj/effect/decal/cleanable/blood/tracks/B = new(loc)
+ var/newdir = get_dir(next, loc)
+ if(newdir == dir)
+ B.dir = newdir
+ else
+ newdir = newdir | dir
+ if(newdir == 3)
+ newdir = 1
+ else if(newdir == 12)
+ newdir = 4
+ B.dir = newdir
bloodiness--
+
+
var/moved = step_towards(src, next) // attempt to move
if(cell) cell.use(1)
if(moved) // successful move
@@ -567,14 +574,14 @@ var/global/mulebot_count = 0
path -= loc
- if(mode==4)
+ if(mode == BOT_BLOCKED)
spawn(1)
send_status()
if(destination == home_destination)
- mode = 3
+ mode = BOT_GO_HOME
else
- mode = 2
+ mode = BOT_DELIVER
else // failed to move
@@ -583,73 +590,74 @@ var/global/mulebot_count = 0
blockcount++
- mode = 4
+ mode = BOT_BLOCKED
if(blockcount == 3)
- src.visible_message("[src] makes an annoyed buzzing sound.", "You hear an electronic buzzing sound.")
- playsound(src.loc, 'sound/machines/buzz-two.ogg', 50, 0)
+ visible_message("[src] makes an annoyed buzzing sound.", "You hear an electronic buzzing sound.")
+ playsound(loc, 'sound/machines/buzz-two.ogg', 50, 0)
- if(blockcount > 5) // attempt 5 times before recomputing
+ if(blockcount > 10) // attempt 10 times before recomputing
// find new path excluding blocked turf
- src.visible_message("[src] makes a sighing buzz.", "You hear an electronic buzzing sound.")
- playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
+ visible_message("[src] makes a sighing buzz.", "You hear an electronic buzzing sound.")
+ playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
spawn(2)
calc_path(next)
if(path.len > 0)
- src.visible_message("[src] makes a delighted ping!", "You hear a ping.")
- playsound(src.loc, 'sound/machines/ping.ogg', 50, 0)
- mode = 4
- mode =6
+ visible_message("[src] makes a delighted ping!", "You hear a ping.")
+ playsound(loc, 'sound/machines/ping.ogg', 50, 0)
+ mode = BOT_BLOCKED
+ mode = BOT_WAIT_FOR_NAV
return
return
else
- src.visible_message("[src] makes an annoyed buzzing sound.", "You hear an electronic buzzing sound.")
- playsound(src.loc, 'sound/machines/buzz-two.ogg', 50, 0)
+ visible_message("[src] makes an annoyed buzzing sound.", "You hear an electronic buzzing sound.")
+ playsound(loc, 'sound/machines/buzz-two.ogg', 50, 0)
//world << "Bad turf."
- mode = 5
+ mode = BOT_NAV
return
else
//world << "No path."
- mode = 5
+ mode = BOT_NAV
return
- if(5) // calculate new path
+ if(BOT_NAV) // calculate new path
//world << "Calc new path."
- mode = 6
+ mode = BOT_WAIT_FOR_NAV
spawn(0)
calc_path()
if(path.len > 0)
blockcount = 0
- mode = 4
- src.visible_message("[src] makes a delighted ping!", "You hear a ping.")
- playsound(src.loc, 'sound/machines/ping.ogg', 50, 0)
+ mode = BOT_BLOCKED
+ visible_message("[src] makes a delighted ping!", "You hear a ping.")
+ playsound(loc, 'sound/machines/ping.ogg', 50, 0)
else
- src.visible_message("[src] makes a sighing buzz.", "You hear an electronic buzzing sound.")
- playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
+ visible_message("[src] makes a sighing buzz.", "You hear an electronic buzzing sound.")
+ playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
- mode = 7
+ mode = BOT_NO_ROUTE
//if(6)
//world << "Pending path calc."
//if(7)
//world << "No dest / no route."
+
return
// calculates a path to the current destination
// given an optional turf to avoid
-/obj/machinery/bot/mulebot/proc/calc_path(var/turf/avoid = null)
- src.path = AStar(src.loc, src.target, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance_cardinal, 0, 250, id=botcard, exclude=avoid)
- if(!src.path)
- src.path = list()
+/obj/machinery/bot/mulebot/calc_path(var/turf/avoid = null)
+ path = AStar(loc, target, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance_cardinal, 0, 250, id=botcard, exclude=avoid)
+ if(!path)
+ path = list()
// sets the current destination
// signals all beacons matching the delivery code
// beacons will return a signal giving their locations
-/obj/machinery/bot/mulebot/proc/set_destination(var/new_dest)
+/obj/machinery/bot/mulebot/set_destination(var/new_dest)
spawn(0)
new_destination = new_dest
post_signal(beacon_freq, "findbeacon", "delivery")
@@ -658,9 +666,9 @@ var/global/mulebot_count = 0
// starts bot moving to current destination
/obj/machinery/bot/mulebot/proc/start()
if(destination == home_destination)
- mode = 3
+ mode = BOT_GO_HOME
else
- mode = 2
+ mode = BOT_DELIVER
icon_state = "mulebot[(wires.MobAvoid() != 0)]"
// starts bot moving to home
@@ -668,17 +676,27 @@ var/global/mulebot_count = 0
/obj/machinery/bot/mulebot/proc/start_home()
spawn(0)
set_destination(home_destination)
- mode = 4
+ mode = BOT_BLOCKED
icon_state = "mulebot[(wires.MobAvoid() != 0)]"
// called when bot reaches current target
/obj/machinery/bot/mulebot/proc/at_target()
if(!reached_target)
- src.visible_message("[src] makes a chiming sound!", "You hear a chime.")
- playsound(src.loc, 'sound/machines/chime.ogg', 50, 0)
+ radio_frequency = SUP_FREQ //Supply channel
+ visible_message("[src] makes a chiming sound!", "You hear a chime.")
+ playsound(loc, 'sound/machines/chime.ogg', 50, 0)
reached_target = 1
+ if(pathset) //The AI called us here, so notify it of our arrival.
+ loaddir = dir //The MULE will attempt to load a crate in whatever direction the MULE is "facing".
+ if(calling_ai)
+ calling_ai << "\icon[src] [src] wirelessly plays a chiming sound!"
+ playsound(calling_ai, 'sound/machines/chime.ogg',40, 0)
+ calling_ai = null
+ 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*/)
unload(loaddir)
else
// not loaded
@@ -693,14 +711,16 @@ var/global/mulebot_count = 0
AM = locate(/obj/structure/closet/crate) in get_step(loc,loaddir)
if(AM)
load(AM)
+ if(report_delivery)
+ speak("Now loading [load] at [get_area(src)]."/*,radio_frequency*/)
// whatever happened, check to see if we return home
if(auto_return && destination != home_destination)
// auto return set and not at home already
start_home()
- mode = 4
+ mode = BOT_BLOCKED
else
- mode = 0 // otherwise go idle
+ bot_reset() // otherwise go idle
send_status() // report status to anyone listening
@@ -712,23 +732,22 @@ var/global/mulebot_count = 0
var/mob/M = obs
if(ismob(M))
if(istype(M,/mob/living/silicon/robot))
- src.visible_message("\red [src] bumps into [M]!")
+ visible_message("[src] bumps into [M]!")
else
- src.visible_message("\red [src] knocks over [M]!")
+ visible_message("[src] knocks over [M]!")
M.stop_pulling()
M.Stun(8)
M.Weaken(5)
- M.lying = 1
..()
/obj/machinery/bot/mulebot/alter_health()
return get_turf(src)
-// called from mob/living/carbon/human/HasEntered()
+// called from mob/living/carbon/human/Crossed()
// when mulebot is in the same loc
/obj/machinery/bot/mulebot/proc/RunOver(var/mob/living/carbon/human/H)
- src.visible_message("\red [src] drives over [H]!")
+ visible_message("\red [src] drives over [H]!")
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
var/damage = rand(5,15)
@@ -746,12 +765,6 @@ var/global/mulebot_count = 0
bloodiness += 4
currentBloodColor="#A10808" // For if species get different blood colors.
-/obj/machinery/bot/mulebot/proc/RunOverCreature(var/mob/living/H,var/bloodcolor)
- src.visible_message("\red [src] drives over [H]!")
- playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
- bloodiness += 4
- currentBloodColor=bloodcolor // For if species get different blood colors.
-
// player on mulebot attempted to move
/obj/machinery/bot/mulebot/relaymove(var/mob/user)
if(user.stat)
@@ -784,7 +797,7 @@ var/global/mulebot_count = 0
// process control input
switch(recv)
if("stop")
- mode = 0
+ bot_reset()
return
if("go")
@@ -820,6 +833,7 @@ var/global/mulebot_count = 0
// receive response from beacon
recv = signal.data["beacon"]
+
if(wires.BeaconRX())
if(recv == new_destination) // if the recvd beacon location matches the set destination
// the we will navigate there
@@ -834,12 +848,18 @@ var/global/mulebot_count = 0
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/proc/post_signal(var/freq, var/key, var/value)
+/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/proc/post_signal_multiple(var/freq, var/list/keyval)
+/obj/machinery/bot/mulebot/post_signal_multiple(var/freq, var/list/keyval)
if(freq == beacon_freq && !(wires.BeaconRX()))
return
@@ -861,17 +881,17 @@ var/global/mulebot_count = 0
//world << "sent [key],[keyval[key]] on [freq]"
if (signal.data["findbeacon"])
frequency.post_signal(src, signal, filter = RADIO_NAVBEACONS)
- else if (signal.data["type"] == "mulebot")
+ else if (signal.data["type"] == MULE_BOT)
frequency.post_signal(src, signal, filter = RADIO_MULEBOT)
else
frequency.post_signal(src, signal)
// signals bot status etc. to controller
-/obj/machinery/bot/mulebot/proc/send_status()
+/obj/machinery/bot/mulebot/send_status()
var/list/kv = list(
- "type" = "mulebot",
+ "type" = MULE_BOT,
"name" = suffix,
- "loca" = (loc ? loc.loc : "Unknown"), // somehow loc can be null and cause a runtime - Quarxink
+ "loca" = get_area(src),
"mode" = mode,
"powr" = (cell ? cell.percent() : 0),
"dest" = destination,
@@ -891,7 +911,7 @@ var/global/mulebot_count = 0
/obj/machinery/bot/mulebot/explode()
- src.visible_message("\red [src] blows apart!", 1)
+ visible_message("[src] blows apart!")
var/turf/Tsec = get_turf(src)
new /obj/item/device/assembly/prox_sensor(Tsec)
@@ -907,6 +927,6 @@ var/global/mulebot_count = 0
s.set_up(3, 1, src)
s.start()
- new /obj/effect/decal/cleanable/oil(src.loc)
+ new /obj/effect/decal/cleanable/oil(loc)
unload(0)
- del(src)
+ qdel(src)
diff --git a/code/game/machinery/bots/secbot.dm b/code/game/machinery/bots/secbot.dm
index 7e22805b5f9..0afd2215f3a 100644
--- a/code/game/machinery/bots/secbot.dm
+++ b/code/game/machinery/bots/secbot.dm
@@ -1,5 +1,5 @@
/obj/machinery/bot/secbot
- name = "Securitron"
+ name = "\improper Securitron"
desc = "A little security robot. He looks less than thrilled."
icon = 'icons/obj/aibots.dmi'
icon_state = "secbot0"
@@ -17,41 +17,15 @@
var/threatlevel = 0
var/target_lastloc //Loc of target when arrested.
var/last_found //There's a delay
- var/frustration = 0
// var/emagged = 0 //Emagged Secbots view everyone as a criminal
- var/declare_arrests = 1 //When making an arrest, should it notify everyone wearing sechuds?
+ var/declare_arrests = 1 //When making an arrest, should it notify everyone on the security channel?
var/idcheck = 0 //If true, arrest people with no IDs
- var/weaponscheck = 1 //If true, arrest people for weapons if they don't have access
+ var/weaponscheck = 1 //If true, arrest people for weapons if they lack access
var/check_records = 1 //Does it check security records?
var/arrest_type = 0 //If true, don't handcuff
- var/next_harm_time = 0
-
- var/mode = 0
-#define SECBOT_IDLE 0 // idle
-#define SECBOT_HUNT 1 // found target, hunting
-#define SECBOT_PREP_ARREST 2 // at target, preparing to arrest
-#define SECBOT_ARREST 3 // arresting target
-#define SECBOT_START_PATROL 4 // start patrol
-#define SECBOT_PATROL 5 // patrolling
-#define SECBOT_SUMMON 6 // summoned by PDA
-
- var/auto_patrol = 0 // set to make bot automatically patrol
-
- var/beacon_freq = 1445 // navigation beacon frequency
- var/control_freq = 1447 // bot control frequency
-
-
- var/turf/patrol_target // this is turf to navigate to (location of beacon)
- 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/list/path = new // list of path turfs
-
- var/blockcount = 0 //number of times retried a blocked path
- var/awaiting_beacon = 0 // count of pticks awaiting a beacon response
-
- var/nearest_beacon // the nearest beacon's tag
- var/turf/nearest_beacon_loc // the nearest beacon's location
+ radio_frequency = SEC_FREQ //Security channel
+ bot_type = SEC_BOT
+ bot_filter = RADIO_SECBOT
//List of weapons that secbots will not arrest for
var/safe_weapons = list(\
@@ -59,24 +33,24 @@
/obj/item/weapon/gun/energy/laser/redtag,\
/obj/item/weapon/gun/energy/laser/practice,\
/obj/item/weapon/melee/telebaton,\
- /obj/item/weapon/melee/baton/loaded/ntcane)
+ /obj/item/weapon/gun/energy/kinetic_accelerator)
/obj/machinery/bot/secbot/beepsky
name = "Officer Beep O'sky"
desc = "It's Officer Beep O'sky! Powered by a potato and a shot of whiskey."
idcheck = 0
- weaponscheck = 1
+ weaponscheck = 0
auto_patrol = 1
/obj/machinery/bot/secbot/pingsky
name = "Officer Pingsky"
desc = "It's Officer Pingsky! Delegated to satellite guard duty for harbouring anti-human sentiment."
- declare_arrests = 0
+ radio_frequency = AIPRIV_FREQ
/obj/item/weapon/secbot_assembly
- name = "helmet/signaler assembly"
- desc = "Some sort of bizarre assembly."
+ name = "incomplete securitron assembly"
+ desc = "Some sort of bizarre assembly made from a proximity sensor, helmet, and signaler."
icon = 'icons/obj/aibots.dmi'
icon_state = "helmet_signaler"
item_state = "helmet"
@@ -87,30 +61,38 @@
/obj/machinery/bot/secbot/New()
..()
- src.icon_state = "secbot[src.on]"
+ icon_state = "secbot[on]"
spawn(3)
- src.botcard = new /obj/item/weapon/card/id(src)
- var/datum/job/detective/J = new /datum/job/detective
- src.botcard.access = J.get_access()
- if(radio_controller)
- radio_controller.add_object(src, control_freq, filter = RADIO_SECBOT)
- radio_controller.add_object(src, beacon_freq, filter = RADIO_NAVBEACONS)
+
+ var/datum/job/detective/J = new/datum/job/detective
+ botcard.access = J.get_access()
+ prev_access = botcard.access
+ add_to_beacons(bot_filter)
/obj/machinery/bot/secbot/turn_on()
..()
- src.icon_state = "secbot[src.on]"
- src.updateUsrDialog()
+ icon_state = "secbot[on]"
+ updateUsrDialog()
/obj/machinery/bot/secbot/turn_off()
..()
- src.target = null
- src.oldtarget_name = null
- src.anchored = 0
- src.mode = SECBOT_IDLE
+ icon_state = "secbot[on]"
+ updateUsrDialog()
+
+/obj/machinery/bot/secbot/bot_reset()
+ ..()
+ target = null
+ oldtarget_name = null
+ anchored = 0
walk_to(src,0)
- src.icon_state = "secbot[src.on]"
- src.updateUsrDialog()
+ last_found = world.time
+
+/obj/machinery/bot/secbot/set_custom_texts()
+
+ text_hack = "You overload [name]'s target identification system."
+ text_dehack = "You reboot [name] and restore the target identification."
+ text_dehack_fail = "[name] refuses to accept your authority!"
/obj/machinery/bot/secbot/attack_hand(mob/user as mob)
. = ..()
@@ -121,151 +103,123 @@
/obj/machinery/bot/secbot/interact(mob/user as mob)
var/dat
-
+ dat += hack(user)
dat += text({"
+Securitron v1.6 controls
Status: []
-Behaviour controls are [src.locked ? "locked" : "unlocked"]
-Maintenance panel panel is [src.open ? "opened" : "closed"] "},
+Behaviour controls are [locked ? "locked" : "unlocked"]
+Maintenance panel panel is [open ? "opened" : "closed"]"},
-"[src.on ? "On" : "Off"]" )
+"[on ? "On" : "Off"]" )
- if(!src.locked || issilicon(user))
+ if(!locked || issilicon(user))
dat += text({"
-Arrest for No ID: []
+Arrest Unidentifiable Persons: []
Arrest for Unauthorized Weapons: []
Arrest for Warrant: []
-
Operating Mode: []
Report Arrests[]
Auto Patrol: []"},
-"[src.idcheck ? "Yes" : "No"]",
-"[src.weaponscheck ? "Yes" : "No"]",
-"[src.check_records ? "Yes" : "No"]",
-"[src.arrest_type ? "Detain" : "Arrest"]",
-"[src.declare_arrests ? "Yes" : "No"]",
+"[idcheck ? "Yes" : "No"]",
+"[weaponscheck ? "Yes" : "No"]",
+"[check_records ? "Yes" : "No"]",
+"[arrest_type ? "Detain" : "Arrest"]",
+"[declare_arrests ? "Yes" : "No"]",
"[auto_patrol ? "On" : "Off"]" )
- var/datum/browser/popup = new(user, "autosec", "Securitron v1.5 controls")
+ var/datum/browser/popup = new(user, "autosec", "Automatic Security Unit v1.6")
popup.set_content(dat)
popup.open()
return
/obj/machinery/bot/secbot/Topic(href, href_list)
- usr.set_machine(src)
- src.add_fingerprint(usr)
- if((href_list["power"]) && (src.allowed(usr)))
- if(src.on)
- turn_off()
- else
- turn_on()
- return
+
+ ..()
switch(href_list["operation"])
if("idcheck")
- src.idcheck = !src.idcheck
- src.updateUsrDialog()
+ idcheck = !idcheck
+ updateUsrDialog()
if("weaponscheck")
- src.weaponscheck = !src.weaponscheck
- src.updateUsrDialog()
+ weaponscheck = !weaponscheck
+ updateUsrDialog()
if("ignorerec")
- src.check_records = !src.check_records
- src.updateUsrDialog()
+ check_records = !check_records
+ updateUsrDialog()
if("switchmode")
- src.arrest_type = !src.arrest_type
- src.updateUsrDialog()
- if("patrol")
- auto_patrol = !auto_patrol
- mode = SECBOT_IDLE
+ arrest_type = !arrest_type
updateUsrDialog()
if("declarearrests")
- src.declare_arrests = !src.declare_arrests
- src.updateUsrDialog()
- if("hack")
- if(!src.emagged)
- src.emagged = 2
- src.hacked = 1
- usr << "You overload [src]'s target identification system."
- else if(!src.hacked)
- usr << "[src] refuses to accept your authority!"
- else
- src.emagged = 0
- src.hacked = 0
- usr << "You reboot [src] and restore the target identification."
- src.updateUsrDialog()
+ declare_arrests = !declare_arrests
+ updateUsrDialog()
+
/obj/machinery/bot/secbot/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda))
- if(src.allowed(user) && !open && !emagged)
- src.locked = !src.locked
- user << "Controls are now [src.locked ? "locked." : "unlocked."]"
+ if(allowed(user) && !open && !emagged)
+ locked = !locked
+ user << "Controls are now [locked ? "locked." : "unlocked."]"
+ updateUsrDialog()
else
if(emagged)
user << "ERROR"
if(open)
- user << "\red Please close the access panel before locking it."
+ user << "Please close the access panel before locking it."
else
- user << "\red Access denied."
+ user << " Access denied."
else
..()
- if(!istype(W, /obj/item/weapon/screwdriver) && (W.force) && (!src.target))
- src.target = user
- src.mode = SECBOT_HUNT
+ if(istype(W, /obj/item/weapon/weldingtool) && user.a_intent != "harm") // Any intent but harm will heal, so we shouldn't get angry.
+ return
+ if(!istype(W, /obj/item/weapon/screwdriver) && (W.force) && (!target)) // Added check for welding tool to fix #2432. Welding tool behavior is handled in superclass.
+ threatlevel = user.assess_threat(src)
+ threatlevel += 6
+ if(threatlevel >= 4)
+ target = user
+ mode = BOT_HUNT
/obj/machinery/bot/secbot/Emag(mob/user as mob)
..()
- if((!locked && open) || !user)
- if(user) user << "\red You short out [src]'s target assessment circuits."
- spawn(0)
- for(var/mob/O in hearers(src, null))
- O.show_message("\red [src] buzzes oddly!", 1)
- src.target = null
- if(user) src.oldtarget_name = user.name
- src.last_found = world.time
- src.anchored = 0
- src.declare_arrests = 0
- src.emagged = 2
- src.on = 1
- src.icon_state = "secbot[src.on]"
- mode = SECBOT_IDLE
-/obj/machinery/bot/secbot/process()
- //set background = 1
+ if(emagged == 2)
+ if(user)
+ user << " You short out [src]'s target assessment circuits."
+ oldtarget_name = user.name
+ visible_message("[src] buzzes oddly!")
+ declare_arrests = 0
+ icon_state = "secbot[on]"
- if(!src.on)
+/obj/machinery/bot/secbot/bot_process()
+ if (!..())
return
switch(mode)
- if(SECBOT_IDLE) // idle
+ if(BOT_IDLE) // idle
walk_to(src,0)
look_for_perp() // see if any criminals are in range
if(!mode && auto_patrol) // still idle, and set to patrol
- mode = SECBOT_START_PATROL // switch to patrol mode
+ mode = BOT_START_PATROL // switch to patrol mode
- if(SECBOT_HUNT) // hunting for perp
+ if(BOT_HUNT) // hunting for perp
// if can't reach perp for long enough, go idle
- if(src.frustration >= 8)
- // for(var/mob/O in hearers(src, null))
- // O << "[src] beeps, \"Backup requested! Suspect has evaded arrest.\""
- src.target = null
- src.last_found = world.time
- src.frustration = 0
- src.mode = SECBOT_IDLE
+ if(frustration >= 8)
walk_to(src,0)
+ back_to_idle()
+ return
if(target) // make sure target exists
- if(src.Adjacent(target) && isturf(src.target.loc)) // if right next to perp
- playsound(src.loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
- src.icon_state = "secbot-c"
+ if(Adjacent(target) && isturf(target.loc)) // if right next to perp
+ playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
+ icon_state = "secbot-c"
spawn(2)
- src.icon_state = "secbot[src.on]"
- var/mob/living/carbon/M = src.target
- var/maxstuns = 4
+ icon_state = "secbot[on]"
+ var/mob/living/carbon/M = target
if(istype(M, /mob/living/carbon/human))
- if(M.stuttering < 5 && (!(M_HULK in M.mutations)))
+ if( M.stuttering < 5 && !(M_HULK in M.mutations) )
M.stuttering = 5
M.Stun(5)
M.Weaken(5)
@@ -275,412 +229,146 @@ Auto Patrol: []"},
M.Stun(5)
if(declare_arrests)
+ //var/area/location = get_area(src)
declare_arrest()
- target.visible_message("[src.target] has been stunned by [src]!",\
- "[src.target] has been stunned by [src]!")
+ target.visible_message("[target] has been stunned by [src]!",\
+ "[target] has been stunned by [src]!")
- maxstuns--
- if(maxstuns <= 0)
- target = null
-
- mode = SECBOT_PREP_ARREST
- src.anchored = 1
- src.target_lastloc = M.loc
+ mode = BOT_PREP_ARREST
+ anchored = 1
+ target_lastloc = M.loc
return
else // not next to perp
- var/turf/olddist = get_dist(src, src.target)
- walk_to(src, src.target,1,4)
- if((get_dist(src, src.target)) >= (olddist))
- src.frustration++
+ var/turf/olddist = get_dist(src, target)
+ walk_to(src, target,1,4)
+ if((get_dist(src, target)) >= (olddist))
+ frustration++
else
- src.frustration = 0
+ frustration = 0
else
- src.frustration = 8
+ back_to_idle()
- if(SECBOT_PREP_ARREST) // preparing to arrest target
+ if(BOT_PREP_ARREST) // preparing to arrest target
- // see if he got away
- if((get_dist(src, src.target) > 1) || ((src.target:loc != src.target_lastloc) && src.target:weakened < 2))
- src.anchored = 0
- mode = SECBOT_HUNT
+ // see if he got away. If he's no no longer adjacent or inside a closet or about to get up, we hunt again.
+ if( !Adjacent(target) || !isturf(target.loc) || target.weakened < 2 )
+ back_to_hunt()
return
- if(istype(src.target,/mob/living/carbon))
- var/mob/living/carbon/C = target
- if(!C.handcuffed && !src.arrest_type)
- playsound(src.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -2)
- mode = SECBOT_ARREST
- target.visible_message("[src] is trying to put handcuffs on [src.target]!",\
- "[src] is trying to put handcuffs on [src.target]!")
-
- spawn(60)
- if(get_dist(src, src.target) <= 1)
- /*if(src.target.handcuffed)
- return*/
-
- if(istype(src.target,/mob/living/carbon))
- C = target
- if(!C.handcuffed)
- C.handcuffed = new /obj/item/weapon/handcuffs(target)
- C.update_inv_handcuffed() //update the handcuffs overlay
-
- mode = SECBOT_IDLE
- src.target = null
- src.anchored = 0
- src.last_found = world.time
- src.frustration = 0
-
- playsound(src.loc, pick('sound/voice/bgod.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/bsecureday.ogg', 'sound/voice/bradio.ogg', 'sound/voice/binsult.ogg', 'sound/voice/bcreep.ogg'), 50, 0)
- // var/arrest_message = pick("Have a secure day!","I AM THE LAW.", "God made tomorrow for the crooks we don't catch today.","You can't outrun a radio.")
- // src.speak(arrest_message)
-
+ if(iscarbon(target) && target.canBeHandcuffed())
+ if(!arrest_type)
+ if(!target.handcuffed) //he's not cuffed? Try to cuff him!
+ mode = BOT_ARREST
+ playsound(loc, 'sound/weapons/handcuffs.ogg', 30, 1, -2)
+ target.visible_message("[src] is trying to put handcuffs on [target]!",\
+ "[src] is trying to put handcuffs on [target]!")
+ spawn(80)
+ if( !Adjacent(target) || !isturf(target.loc) ) //if he's in a closet or not adjacent, we cancel cuffing.
+ return
+ if(!target.handcuffed)
+ target.handcuffed = new /obj/item/weapon/handcuffs(target)
+ target.update_inv_handcuffed(0) //update the handcuffs overlay
+ playsound(loc, pick('sound/voice/bgod.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/bsecureday.ogg', 'sound/voice/bradio.ogg', 'sound/voice/binsult.ogg', 'sound/voice/bcreep.ogg'), 50, 0)
+ back_to_idle()
+ else
+ back_to_idle()
+ return
else
- mode = SECBOT_IDLE
- src.target = null
- src.anchored = 0
- src.last_found = world.time
- src.frustration = 0
-
- if(SECBOT_ARREST) // arresting
-
- if(!target || !istype(target, /mob/living/carbon))
- src.anchored = 0
- mode = SECBOT_IDLE
+ back_to_idle()
return
- else
- var/mob/living/carbon/C = target
- if(!C.handcuffed)
- src.anchored = 0
- mode = SECBOT_IDLE
- return
+ if(BOT_ARREST)
+ if (!target)
+ anchored = 0
+ mode = BOT_IDLE
+ last_found = world.time
+ frustration = 0
+ return
- if(SECBOT_START_PATROL) // start a patrol
- if(path != null)
- if(path.len > 0 && patrol_target) // have a valid path, so just resume
- mode = SECBOT_PATROL
- return
+ if(target.handcuffed) //no target or target cuffed? back to idle.
+ back_to_idle()
+ return
- else if(patrol_target) // has patrol target already
- spawn(0)
- calc_path() // so just find a route to it
- if(path.len == 0)
- patrol_target = 0
- return
- mode = SECBOT_PATROL
+ if( !Adjacent(target) || !isturf(target.loc) || (target.loc != target_lastloc && target.weakened < 2) ) //if he's changed loc and about to get up or not adjacent or got into a closet, we prep arrest again.
+ back_to_hunt()
+ return
+ else //Try arresting again if the target escapes.
+ mode = BOT_PREP_ARREST
+ anchored = 0
+ if(BOT_START_PATROL)
+ look_for_perp()
+ start_patrol()
- else // no patrol target, so need a new one
- find_patrol_target()
- speak("Engaging patrol mode.")
+ if(BOT_PATROL)
+ look_for_perp()
+ bot_patrol()
- if(SECBOT_PATROL) // patrol mode
-
- patrol_step()
- spawn(5)
- if(mode == SECBOT_PATROL)
- patrol_step()
-
- if(SECBOT_SUMMON) // summoned to PDA
- patrol_step()
- spawn(4)
- if(mode == SECBOT_SUMMON)
- patrol_step()
- sleep(4)
- patrol_step()
-
return
+/obj/machinery/bot/secbot/proc/back_to_idle()
+ anchored = 0
+ mode = BOT_IDLE
+ target = null
+ last_found = world.time
+ frustration = 0
+ spawn(0)
+ bot_process() //ensure bot quickly responds
-// perform a single patrol step
-/obj/machinery/bot/secbot/proc/patrol_step()
-
- if(loc == patrol_target) // reached target
- at_patrol_target()
- return
-
- else if(path.len > 0 && patrol_target) // valid path
-
- var/turf/next = path[1]
- if(next == loc)
- path -= next
- return
-
-
- if(istype( next, /turf/simulated))
-
- var/moved = step_towards(src, next) // attempt to move
- if(moved) // successful move
- blockcount = 0
- path -= loc
-
- look_for_perp()
- else // failed to move
-
- blockcount++
-
- if(blockcount > 5) // attempt 5 times before recomputing
- // find new path excluding blocked turf
-
- spawn(2)
- calc_path(next)
- if(path.len == 0)
- find_patrol_target()
- else
- blockcount = 0
-
- return
-
- return
-
- else // not a valid turf
- mode = SECBOT_IDLE
- return
-
- else // no path, so calculate new one
- mode = SECBOT_START_PATROL
-
-
-// finds a new patrol target
-/obj/machinery/bot/secbot/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)
- else
- find_nearest_beacon()
- return
-
-
-// finds the nearest beacon to self
-// signals all beacons matching the patrol code
-/obj/machinery/bot/secbot/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)
- else
- auto_patrol = 0
- mode = SECBOT_IDLE
- speak("Disengaging patrol mode.")
- send_status()
-
-
-/obj/machinery/bot/secbot/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/secbot/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/secbot/receive_signal(datum/signal/signal)
- //log_admin("DEBUG \[[world.timeofday]\]: /obj/machinery/bot/secbot/receive_signal([signal.debug_print()])")
- if(!on)
- 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")
- send_status()
-
- // check to see if we are the commanded bot
- if(signal.data["active"] == src)
- // process control input
- switch(recv)
- if("stop")
- mode = SECBOT_IDLE
- auto_patrol = 0
- return
-
- if("go")
- mode = SECBOT_IDLE
- auto_patrol = 1
- return
-
- if("summon")
- patrol_target = signal.data["target"]
- next_destination = destination
- destination = null
- awaiting_beacon = 0
- mode = SECBOT_SUMMON
- calc_path()
- speak("Responding.")
-
- 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/secbot/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/secbot/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 if(signal.data["type"] == "secbot")
- frequency.post_signal(src, signal, filter = RADIO_SECBOT)
- else
- frequency.post_signal(src, signal)
-
-// signals bot status etc. to controller
-/obj/machinery/bot/secbot/proc/send_status()
- var/list/kv = list(
- "type" = "secbot",
- "name" = name,
- "loca" = loc.loc, // area
- "mode" = mode
- )
- post_signal_multiple(control_freq, kv)
-
-
-
-// calculates a path to the current destination
-// given an optional turf to avoid
-/obj/machinery/bot/secbot/proc/calc_path(var/turf/avoid = null)
- src.path = AStar(src.loc, patrol_target, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance_cardinal, 0, 120, id=botcard, exclude=avoid)
- if(!src.path)
- src.path = list()
-
-
+/obj/machinery/bot/secbot/proc/back_to_hunt()
+ anchored = 0
+ frustration = 0
+ mode = BOT_HUNT
+ spawn(0)
+ bot_process() //ensure bot quickly responds
// look for a criminal in view of the bot
/obj/machinery/bot/secbot/proc/look_for_perp()
- src.anchored = 0
+ anchored = 0
for (var/mob/living/carbon/C in view(7,src)) //Let's find us a criminal
if((C.stat) || (C.handcuffed))
continue
- if((C.name == src.oldtarget_name) && (world.time < src.last_found + 100))
+ if((C.name == oldtarget_name) && (world.time < last_found + 100))
continue
- src.threatlevel = C.assess_threat(src)
+ threatlevel = C.assess_threat(src)
- if(!src.threatlevel)
+ if(!threatlevel)
continue
- else if(src.threatlevel >= 4)
- src.target = C
- src.oldtarget_name = C.name
- src.speak("Level [src.threatlevel] infraction alert!")
- playsound(src.loc, pick('sound/voice/bcriminal.ogg', 'sound/voice/bjustice.ogg', 'sound/voice/bfreeze.ogg'), 50, 0)
- src.visible_message("[src] points at [C.name]!")
- mode = SECBOT_HUNT
+ else if(threatlevel >= 4)
+ target = C
+ oldtarget_name = C.name
+ speak("Level [threatlevel] infraction alert!")
+ playsound(loc, pick('sound/voice/bcriminal.ogg', 'sound/voice/bjustice.ogg', 'sound/voice/bfreeze.ogg'), 50, 0)
+ visible_message("[src] points at [C.name]!")
+ mode = BOT_HUNT
spawn(0)
- process() // ensure bot quickly responds to a perp
+ bot_process() // ensure bot quickly responds to a perp
break
else
continue
-
/obj/machinery/bot/secbot/proc/check_for_weapons(var/obj/item/slot_item)
if(istype(slot_item, /obj/item/weapon/gun) || istype(slot_item, /obj/item/weapon/melee))
if(!(slot_item.type in safe_weapons))
return 1
return 0
-/obj/machinery/bot/secbot/Bump(M as mob|obj) //Leave no door unopened!
- if((istype(M, /obj/machinery/door)) && (!isnull(src.botcard)))
- var/obj/machinery/door/D = M
- if(!istype(D, /obj/machinery/door/firedoor) && D.check_access(src.botcard) && !istype(D,/obj/machinery/door/poddoor))
- D.open()
- src.frustration = 0
- else if((istype(M, /mob/living/)) && (!src.anchored))
- src.loc = M:loc
- src.frustration = 0
- return
-
-/* terrible
-/obj/machinery/bot/secbot/Bumped(atom/movable/M as mob|obj)
- spawn(0)
- if(M)
- var/turf/T = get_turf(src)
- M:loc = T
-*/
-
-
-
/obj/machinery/bot/secbot/explode()
walk_to(src,0)
- src.visible_message("\red [src] blows apart!", 1)
+ visible_message("[src] blows apart!")
var/turf/Tsec = get_turf(src)
var/obj/item/weapon/secbot_assembly/Sa = new /obj/item/weapon/secbot_assembly(Tsec)
Sa.build_step = 1
- Sa.overlays += image('icons/obj/aibots.dmi', "hs_hole")
- Sa.created_name = src.name
+ Sa.overlays += "hs_hole"
+ Sa.created_name = name
new /obj/item/device/assembly/prox_sensor(Tsec)
- new /obj/item/weapon/melee/baton/loaded(Tsec)
+ new /obj/item/weapon/melee/baton(Tsec)
if(prob(50))
new /obj/item/robot_parts/l_arm(Tsec)
@@ -689,14 +377,14 @@ Auto Patrol: []"},
s.set_up(3, 1, src)
s.start()
- new /obj/effect/decal/cleanable/oil(src.loc)
- del(src)
+ new /obj/effect/decal/cleanable/oil(loc)
+ qdel(src)
/obj/machinery/bot/secbot/attack_alien(var/mob/living/carbon/alien/user as mob)
..()
if(!isalien(target))
- src.target = user
- src.mode = SECBOT_HUNT
+ target = user
+ mode = BOT_HUNT
//Secbot Construction
@@ -706,63 +394,70 @@ Auto Patrol: []"},
..()
return
- if(src.type != /obj/item/clothing/head/helmet) //Eh, but we don't want people making secbots out of space helmets.
+ if(type != /obj/item/clothing/head/helmet) //Eh, but we don't want people making secbots out of space helmets.
return
if(S.secured)
- del(S)
+ qdel(S)
var/obj/item/weapon/secbot_assembly/A = new /obj/item/weapon/secbot_assembly
user.put_in_hands(A)
- user << "You add the signaler to the helmet."
- user.drop_from_inventory(src)
- del(src)
+ user << "You add the signaler to the helmet."
+ user.before_take_item(src, 1)
+ qdel(src)
else
return
-/obj/item/weapon/secbot_assembly/attackby(obj/item/weapon/W as obj, mob/user as mob)
+/obj/item/weapon/secbot_assembly/attackby(obj/item/I, mob/user)
..()
- if((istype(W, /obj/item/weapon/weldingtool)) && (!src.build_step))
- var/obj/item/weapon/weldingtool/WT = W
- if(WT.remove_fuel(0,user))
- src.build_step++
- src.overlays += image('icons/obj/aibots.dmi', "hs_hole")
- user << "You weld a hole in [src]!"
+ if(istype(I, /obj/item/weapon/weldingtool))
+ if(!build_step)
+ var/obj/item/weapon/weldingtool/WT = I
+ if(WT.remove_fuel(0, user))
+ build_step++
+ overlays += "hs_hole"
+ user << "You weld a hole in [src]!"
+ else if(build_step == 1)
+ var/obj/item/weapon/weldingtool/WT = I
+ if(WT.remove_fuel(0, user))
+ build_step--
+ overlays -= "hs_hole"
+ user << "You weld the hole in [src] shut!"
- else if(isprox(W) && (src.build_step == 1))
+ else if(isprox(I) && (build_step == 1))
user.drop_item()
- src.build_step++
- user << "You add the prox sensor to [src]!"
- src.overlays += image('icons/obj/aibots.dmi', "hs_eye")
- src.name = "helmet/signaler/prox sensor assembly"
- del(W)
+ build_step++
+ user << "You add the prox sensor to [src]!"
+ overlays += "hs_eye"
+ name = "helmet/signaler/prox sensor assembly"
+ qdel(I)
- else if(((istype(W, /obj/item/robot_parts/l_arm)) || (istype(W, /obj/item/robot_parts/r_arm))) && (src.build_step == 2))
+ else if(((istype(I, /obj/item/robot_parts/l_arm)) || (istype(I, /obj/item/robot_parts/r_arm))) && (build_step == 2))
user.drop_item()
- src.build_step++
- user << "You add the robot arm to [src]!"
- src.name = "helmet/signaler/prox sensor/robot arm assembly"
- src.overlays += image('icons/obj/aibots.dmi', "hs_arm")
- del(W)
+ build_step++
+ user << "You add the robot arm to [src]!"
+ name = "helmet/signaler/prox sensor/robot arm assembly"
+ overlays += "hs_arm"
+ qdel(I)
- else if((istype(W, /obj/item/weapon/melee/baton)) && (src.build_step >= 3))
+ else if((istype(I, /obj/item/weapon/melee/baton)) && (build_step >= 3))
user.drop_item()
- src.build_step++
- user << "You complete the Securitron! Beep boop."
+ build_step++
+ user << "You complete the Securitron! Beep boop."
var/obj/machinery/bot/secbot/S = new /obj/machinery/bot/secbot
S.loc = get_turf(src)
- S.name = src.created_name
- del(W)
- del(src)
+ S.name = created_name
+ qdel(I)
+ qdel(src)
- else if(istype(W, /obj/item/weapon/pen))
- var/t = copytext(stripped_input(user, "Enter new robot name", src.name, src.created_name),1,MAX_NAME_LEN)
+ else if(istype(I, /obj/item/weapon/pen))
+ var/t = stripped_input(user, "Enter new robot name", name, created_name,MAX_NAME_LEN)
if(!t)
return
- if(!in_range(src, usr) && src.loc != usr)
+ if(!in_range(src, usr) && loc != usr)
return
created_name = t
- else if(istype(W, /obj/item/weapon/screwdriver))
+ else if(istype(I, /obj/item/weapon/screwdriver))
if(!build_step)
new /obj/item/device/assembly/signaler(get_turf(src))
new /obj/item/clothing/head/helmet(get_turf(src))
@@ -780,9 +475,9 @@ Auto Patrol: []"},
new /obj/item/robot_parts/l_arm(get_turf(src))
user << "You remove the robot arm from [src]."
build_step--
-
-/obj/machinery/bot/secbot/proc/declare_arrest()
+
+/obj/machinery/bot/secbot/proc/declare_arrest()
var/area/location = get_area(src)
for(var/mob/living/carbon/human/human in world)
if((human.z == src.z) && istype(human.glasses, /obj/item/clothing/glasses/hud/security) || istype(human.glasses, /obj/item/clothing/glasses/sunglasses/sechud) && !human.blinded)
- human << "\icon[human.glasses] [src.name] is [arrest_type ? "detaining" : "arresting"] level [threatlevel] [target] in [location]"
+ human << "\icon[human.glasses] [src.name] is [arrest_type ? "detaining" : "arresting"] level [threatlevel] threat [target] in [location]"
\ No newline at end of file
diff --git a/code/game/machinery/navbeacon.dm b/code/game/machinery/navbeacon.dm
index 71f450e70fe..59bf0f2ea17 100644
--- a/code/game/machinery/navbeacon.dm
+++ b/code/game/machinery/navbeacon.dm
@@ -20,144 +20,146 @@
req_access = list(access_engine)
- New()
- ..()
+/obj/machinery/navbeacon/New()
+ ..()
- set_codes()
+ set_codes()
- var/turf/T = loc
- hide(T.intact)
+ 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)
+ spawn(50) // must wait for map loading to finish
+ if(radio_controller)
+ radio_controller.add_object(src, freq, RADIO_NAVBEACONS)
- // set the transponder codes assoc list from codes_txt
- proc/set_codes()
- if(!codes_txt)
- return
+/obj/machinery/navbeacon/Destroy()
+ if(radio_controller)
+ radio_controller.remove_object(src, freq)
+ ..()
- codes = new()
+// set the transponder codes assoc list from codes_txt
+/obj/machinery/navbeacon/proc/set_codes()
+ if(!codes_txt)
+ return
- var/list/entries = text2list(codes_txt, ";") // entries are separated by semicolons
+ codes = new()
- for(var/e in entries)
- var/index = findtext(e, "=") // format is "key=value"
- if(index)
- var/key = copytext(e, 1, index)
- var/val = copytext(e, index+1)
- codes[key] = val
- else
- codes[e] = "1"
+ var/list/entries = text2list(codes_txt, ";") // entries are separated by semicolons
+
+ for(var/e in entries)
+ var/index = findtext(e, "=") // format is "key=value"
+ if(index)
+ var/key = copytext(e, 1, index)
+ var/val = copytext(e, index+1)
+ codes[key] = val
+ else
+ codes[e] = "1"
- // called when turf state changes
- // hide the object if turf is intact
- hide(var/intact)
- invisibility = intact ? 101 : 0
+// called when turf state changes
+// hide the object if turf is intact
+/obj/machinery/navbeacon/hide(var/intact)
+ invisibility = intact ? 101 : 0
+ updateicon()
+
+// update the icon_state
+/obj/machinery/navbeacon/proc/updateicon()
+ var/state="navbeacon[open]"
+
+ if(invisibility)
+ icon_state = "[state]-f" // if invisible, set icon to faded version
+ // in case revealed by T-scanner
+ 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)
+ var/turf/T = loc
+ if(T.intact)
+ return // prevent intraction when T-scanner revealed
+
+ if(istype(I, /obj/item/weapon/screwdriver))
+ open = !open
+
+ user.visible_message("[user] [open ? "opens" : "closes"] the beacon's cover.", "You [open ? "open" : "close"] the beacon's cover.")
+
updateicon()
- // update the icon_state
- proc/updateicon()
- var/state="navbeacon[open]"
-
- if(invisibility)
- icon_state = "[state]-f" // if invisible, set icon to faded version
- // in case revealed by T-scanner
- 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
- 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
-
- 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)
-
-
- attackby(var/obj/item/I, var/mob/user)
- var/turf/T = loc
- if(T.intact)
- return // prevent intraction when T-scanner revealed
-
- if(istype(I, /obj/item/weapon/screwdriver))
- open = !open
-
- user.visible_message("[user] [open ? "opens" : "closes"] the beacon's cover.", "You [open ? "open" : "close"] the beacon's cover.")
-
- updateicon()
-
- else if (istype(I, /obj/item/weapon/card/id)||istype(I, /obj/item/device/pda))
- if(open)
- if (src.allowed(user))
- src.locked = !src.locked
- user << "Controls are now [src.locked ? "locked." : "unlocked."]"
- else
- user << "\red Access denied."
- updateDialog()
+ else if (istype(I, /obj/item/weapon/card/id)||istype(I, /obj/item/device/pda))
+ if(open)
+ if (src.allowed(user))
+ src.locked = !src.locked
+ user << "Controls are now [src.locked ? "locked." : "unlocked."]"
else
- user << "You must open the cover first!"
+ user << "Access denied."
+ updateDialog()
+ else
+ user << "You must open the cover first!"
+ return
+
+/obj/machinery/navbeacon/attack_ai(var/mob/user)
+ interact(user, 1)
+
+/obj/machinery/navbeacon/attack_paw()
+ return
+
+/obj/machinery/navbeacon/attack_hand(var/mob/user)
+ interact(user, 0)
+
+/obj/machinery/navbeacon/interact(var/mob/user, var/ai = 0)
+ var/turf/T = loc
+ if(T.intact)
+ return // prevent intraction when T-scanner revealed
+
+ if(!open && !ai) // can't alter controls if not open, unless you're an AI
+ user << "The beacon's control cover is closed."
return
- attack_ai(var/mob/user)
- interact(user, 1)
- attack_paw()
- return
+ var/t
- attack_hand(var/mob/user)
- interact(user, 0)
-
- interact(var/mob/user, var/ai = 0)
- var/turf/T = loc
- if(T.intact)
- return // prevent intraction when T-scanner revealed
-
- if(!open && !ai) // can't alter controls if not open, unless you're an AI
- user << "The beacon's control cover is closed."
- return
-
-
- var/t
-
- if(locked && !ai)
- t = {"Navigation Beacon
+ if(locked && !ai)
+ t = {"Navigation Beacon (swipe card to unlock controls)
Frequency: [format_frequency(freq)]
Location: [location ? location : "(none)"]
Transponder Codes: