Files
Paradise/code/game/machinery/bots/mulebot.dm
elly1989@rocketmail.com 48088b79d9 ugh...this was horrible. I'm really sorry if I fucked anything up, I was literally going braindead towards the end.
Replaced every l_hand = and r_hand = and all that if(hand) crap to use standardised procs. This means we can use procs like Dropped() reliably as they will always be called when things are dropped.

Thorough documentation to come. But generally, if you want a mob's icons to update after deleting something in the inventory...use drop_from_inventory(the_thing_you_wanna_drop) just before deleting it. If you wanna put something in a mob's hands use put_in_hands() (or one of the variants). It'll try putting it in active hand first, then inactive, then the floor. They handle layers, overlays, screenlocs calling various procs such as dropped() etc for you. Easy

mob.equipped() is now mob.get_active_hand() because there was another totally unrelated proc named equipped() and stuff was confusing.

Weakening was made instantaneous.

Minor optimisations for human/handle_regular_status_updates(). I'll port these changes over to the other mobs next. Basically it should stop it constantly incrementing every status effect even after death.

umm... bunch of overlays related fixes... I think that's everything. :/

git-svn-id: http://tgstation13.googlecode.com/svn/trunk@3900 316c924e-a436-60f5-8080-3fe189b3f50e
2012-06-23 21:24:45 +00:00

957 lines
26 KiB
Plaintext

//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
// Mulebot - carries crates around for Quartermaster
// Navigates via floor navbeacons
// Remote Controlled from QM's PDA
/obj/machinery/bot/mulebot
name = "Mulebot"
desc = "A Multiple Utility Load Effector bot."
icon_state = "mulebot0"
layer = MOB_LAYER
density = 1
anchored = 1
animate_movement=1
health = 150 //yeah, it's tougher than ed209 because it is a big metal box with wheels --rastaf0
maxhealth = 150
fire_dam_coeff = 0.7
brute_dam_coeff = 0.5
var/locked = 1
var/atom/movable/load = null // the loaded crate (usually)
var/beacon_freq = 1400
var/control_freq = 1447
suffix = ""
var/turf/target // this is turf to navigate to (location of beacon)
var/loaddir = 0 // this the direction to unload onto/load from
var/new_destination = "" // pending new destination (waiting for beacon response)
var/destination = "" // destination description
var/home_destination = "" // tag of home beacon
req_access = list(access_cargo, access_cargo_bot) // added robotics access so assembly line drop-off works properly -veyveyr //I don't think so, Tim. You need to add it to the MULE's hidden robot ID card. -NEO
var/path[] = new()
var/mode = 0 //0 = idle/ready
//1 = loading/unloading
//2 = moving to deliver
//3 = returning to home
//4 = blocked
//5 = computing navigation
//6 = waiting for nav computation
//7 = no destination beacon found (or no route)
var/blockcount = 0 //number of times retried a blocked path
var/reached_target = 1 //true if already reached the target
var/refresh = 1 // true to refresh dialogue
var/auto_return = 1 // true if auto return to home beacon after unload
var/auto_pickup = 1 // true if auto-pickup at beacon
var/open = 0 // true if maint hatch is open
var/obj/item/weapon/cell/cell
// the installed power cell
// constants for internal wiring bitflags
var/const/wire_power1 = 1 // power connections
var/const/wire_power2 = 2
var/const/wire_mobavoid = 4 // mob avoidance
var/const/wire_loadcheck = 8 // load checking (non-crate)
var/const/wire_motor1 = 16 // motor wires
var/const/wire_motor2 = 32 //
var/const/wire_remote_rx = 64 // remote recv functions
var/const/wire_remote_tx = 128 // remote trans status
var/const/wire_beacon_rx = 256 // beacon ping recv
var/const/wire_beacon_tx = 512 // beacon ping trans
var/wires = 1023 // all flags on
var/list/wire_text // list of wire colours
var/list/wire_order // order of wire indices
var/bloodiness = 0 // count of bloodiness
/obj/machinery/bot/mulebot/New()
..()
botcard = new(src)
botcard.access = get_access("Quartermaster")
botcard.access += access_robotics
cell = new(src)
cell.charge = 2000
cell.maxcharge = 2000
setup_wires()
spawn(5) // must wait for map loading to finish
if(radio_controller)
radio_controller.add_object(src, control_freq, filter = RADIO_MULEBOT)
radio_controller.add_object(src, beacon_freq, filter = RADIO_NAVBEACONS)
var/count = 0
for(var/obj/machinery/bot/mulebot/other in world)
count++
if(!suffix)
suffix = "#[count]"
name = "Mulebot ([suffix])"
verbs -= /atom/movable/verb/pull
// set up the wire colours in random order
// and the random wire display order
// needs 10 wire colours
/obj/machinery/bot/mulebot/proc/setup_wires()
var/list/colours = list("Red", "Green", "Blue", "Magenta", "Cyan", "Yellow", "Black", "White", "Orange", "Grey")
var/list/orders = list("0","1","2","3","4","5","6","7","8","9")
wire_text = list()
wire_order = list()
while(colours.len > 0)
var/colour = colours[ rand(1,colours.len) ]
wire_text += colour
colours -= colour
var/order = orders[ rand(1,orders.len) ]
wire_order += text2num(order)
orders -= order
// attack by item
// emag : lock/unlock,
// screwdriver: open/close hatch
// cell: insert it
// other: chance to knock rider off bot
/obj/machinery/bot/mulebot/attackby(var/obj/item/I, var/mob/user)
if(istype(I,/obj/item/weapon/card/emag))
locked = !locked
user << "\blue You [locked ? "lock" : "unlock"] the mulebot's controls!"
flick("mulebot-emagged", src)
playsound(src.loc, 'sparks1.ogg', 100, 0)
else if(istype(I,/obj/item/weapon/cell) && open && !cell)
var/obj/item/weapon/cell/C = I
user.drop_item()
C.loc = src
cell = C
updateDialog()
else if(istype(I,/obj/item/weapon/screwdriver))
if(locked)
user << "\blue The maintenance hatch cannot be opened or closed while the controls are locked."
return
open = !open
if(open)
src.visible_message("[user] opens the maintenance hatch of [src]", "\blue You open [src]'s maintenance hatch.")
on = 0
icon_state="mulebot-hatch"
else
src.visible_message("[user] closes the maintenance hatch of [src]", "\blue You close [src]'s maintenance hatch.")
icon_state = "mulebot0"
updateDialog()
else if (istype(I, /obj/item/weapon/wrench))
if (src.health < maxhealth)
src.health = min(maxhealth, src.health+25)
user.visible_message(
"\red [user] repairs [src]!",
"\blue You repair [src]!"
)
else
user << "\blue [src] does not need a repair!"
else if(load && ismob(load)) // chance to knock off rider
if(prob(1+I.force * 2))
unload(0)
user.visible_message("\red [user] knocks [load] off [src] with \the [I]!", "\red You knock [load] off [src] with \the [I]!")
else
user << "You hit [src] with \the [I] but to no effect."
else
..()
return
/obj/machinery/bot/mulebot/ex_act(var/severity)
unload(0)
switch(severity)
if(2)
wires &= ~(1 << rand(0,9))
wires &= ~(1 << rand(0,9))
wires &= ~(1 << rand(0,9))
if(3)
wires &= ~(1 << rand(0,9))
..()
return
/obj/machinery/bot/mulebot/bullet_act()
if(prob(50) && !isnull(load))
unload(0)
if(prob(25))
src.visible_message("\red Something shorts out inside [src]!")
var/index = 1<< (rand(0,9))
if(wires & index)
wires &= ~index
else
wires |= index
..()
/obj/machinery/bot/mulebot/attack_ai(var/mob/user)
user.machine = src
interact(user, 1)
/obj/machinery/bot/mulebot/attack_hand(var/mob/user)
. = ..()
if (.)
return
user.machine = src
interact(user, 0)
/obj/machinery/bot/mulebot/proc/interact(var/mob/user, var/ai=0)
var/dat
dat += "<TT><B>Multiple Utility Load Effector Mk. III</B></TT><BR><BR>"
dat += "ID: [suffix]<BR>"
dat += "Power: [on ? "On" : "Off"]<BR>"
if(!open)
dat += "Status: "
switch(mode)
if(0)
dat += "Ready"
if(1)
dat += "Loading/Unloading"
if(2)
dat += "Navigating to Delivery Location"
if(3)
dat += "Navigating to Home"
if(4)
dat += "Waiting for clear path"
if(5,6)
dat += "Calculating navigation path"
if(7)
dat += "Unable to locate destination"
dat += "<BR>Current Load: [load ? load.name : "<i>none</i>"]<BR>"
dat += "Destination: [!destination ? "<i>none</i>" : destination]<BR>"
dat += "Power level: [cell ? cell.percent() : 0]%<BR>"
if(locked && !ai)
dat += "<HR>Controls are locked <A href='byond://?src=\ref[src];op=unlock'><I>(unlock)</I></A>"
else
dat += "<HR>Controls are unlocked <A href='byond://?src=\ref[src];op=lock'><I>(lock)</I></A><BR><BR>"
dat += "<A href='byond://?src=\ref[src];op=power'>Toggle Power</A><BR>"
dat += "<A href='byond://?src=\ref[src];op=stop'>Stop</A><BR>"
dat += "<A href='byond://?src=\ref[src];op=go'>Proceed</A><BR>"
dat += "<A href='byond://?src=\ref[src];op=home'>Return to Home</A><BR>"
dat += "<A href='byond://?src=\ref[src];op=destination'>Set Destination</A><BR>"
dat += "<A href='byond://?src=\ref[src];op=setid'>Set Bot ID</A><BR>"
dat += "<A href='byond://?src=\ref[src];op=sethome'>Set Home</A><BR>"
dat += "<A href='byond://?src=\ref[src];op=autoret'>Toggle Auto Return Home</A> ([auto_return ? "On":"Off"])<BR>"
dat += "<A href='byond://?src=\ref[src];op=autopick'>Toggle Auto Pickup Crate</A> ([auto_pickup ? "On":"Off"])<BR>"
if(load)
dat += "<A href='byond://?src=\ref[src];op=unload'>Unload Now</A><BR>"
dat += "<HR>The maintenance hatch is closed.<BR>"
else
if(!ai)
dat += "The maintenance hatch is open.<BR><BR>"
dat += "Power cell: "
if(cell)
dat += "<A href='byond://?src=\ref[src];op=cellremove'>Installed</A><BR>"
else
dat += "<A href='byond://?src=\ref[src];op=cellinsert'>Removed</A><BR>"
dat += wires()
else
dat += "The bot is in maintenance mode and cannot be controlled.<BR>"
user << browse("<HEAD><TITLE>Mulebot [suffix ? "([suffix])" : ""]</TITLE></HEAD>[dat]", "window=mulebot;size=350x500")
onclose(user, "mulebot")
return
// returns the wire panel text
/obj/machinery/bot/mulebot/proc/wires()
var/t = ""
for(var/i = 0 to 9)
var/index = 1<<wire_order[i+1]
t += "[wire_text[i+1]] wire: "
if(index & wires)
t += "<A href='byond://?src=\ref[src];op=wirecut;wire=[index]'>(cut)</A> <A href='byond://?src=\ref[src];op=wirepulse;wire=[index]'>(pulse)</A><BR>"
else
t += "<A href='byond://?src=\ref[src];op=wiremend;wire=[index]'>(mend)</A><BR>"
return t
/obj/machinery/bot/mulebot/Topic(href, href_list)
if(..())
return
if (usr.stat)
return
if ((in_range(src, usr) && istype(src.loc, /turf)) || (istype(usr, /mob/living/silicon)))
usr.machine = src
switch(href_list["op"])
if("lock", "unlock")
if(src.allowed(usr))
locked = !locked
updateDialog()
else
usr << "\red Access denied."
return
if("power")
if (src.on)
turn_off()
else if (cell && !open)
if (!turn_on())
usr << "\red You can't switch on [src]."
return
else
return
usr << "You switch [on ? "on" : "off"] [src]."
for(var/mob/M in viewers(src))
if(M==usr) continue
M << "[usr] switches [on ? "on" : "off"] [src]."
updateDialog()
if("cellremove")
if(open && cell && !usr.get_active_hand())
cell.updateicon()
usr.put_in_active_hand(cell)
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].")
updateDialog()
if("cellinsert")
if(open && !cell)
var/obj/item/weapon/cell/C = usr.get_active_hand()
if(istype(C))
usr.drop_item()
cell = C
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].")
updateDialog()
if("stop")
if(mode >=2)
mode = 0
updateDialog()
if("go")
if(mode == 0)
start()
updateDialog()
if("home")
if(mode == 0 || mode == 2)
start_home()
updateDialog()
if("destination")
refresh=0
var/new_dest = input("Enter new destination tag", "Mulebot [suffix ? "([suffix])" : ""]", destination) as text|null
refresh=1
if(new_dest)
set_destination(new_dest)
if("setid")
refresh=0
var/new_id = copytext(sanitize(input("Enter new bot ID", "Mulebot [suffix ? "([suffix])" : ""]", suffix) as text|null),1,MAX_NAME_LEN)
refresh=1
if(new_id)
suffix = new_id
name = "Mulebot ([suffix])"
updateDialog()
if("sethome")
refresh=0
var/new_home = input("Enter new home tag", "Mulebot [suffix ? "([suffix])" : ""]", home_destination) as text|null
refresh=1
if(new_home)
home_destination = new_home
updateDialog()
if("unload")
if(load && mode !=1)
if(loc == target)
unload(loaddir)
else
unload(0)
if("autoret")
auto_return = !auto_return
if("autopick")
auto_pickup = !auto_pickup
if("close")
usr.machine = null
usr << browse(null,"window=mulebot")
if("wirecut")
if(istype(usr.get_active_hand(), /obj/item/weapon/wirecutters))
var/wirebit = text2num(href_list["wire"])
wires &= ~wirebit
else
usr << "\blue You need wirecutters!"
if("wiremend")
if(istype(usr.get_active_hand(), /obj/item/weapon/wirecutters))
var/wirebit = text2num(href_list["wire"])
wires |= wirebit
else
usr << "\blue You need wirecutters!"
if("wirepulse")
if(istype(usr.get_active_hand(), /obj/item/device/multitool))
switch(href_list["wire"])
if("1","2")
usr << "\blue \icon[src] The charge light flickers."
if("4")
usr << "\blue \icon[src] The external warning lights flash briefly."
if("8")
usr << "\blue \icon[src] The load platform clunks."
if("16", "32")
usr << "\blue \icon[src] The drive motor whines briefly."
else
usr << "\blue \icon[src] You hear a radio crackle."
else
usr << "\blue You need a multitool!"
updateDialog()
//src.updateUsrDialog()
else
usr << browse(null, "window=mulebot")
usr.machine = null
return
// returns true if the bot has power
/obj/machinery/bot/mulebot/proc/has_power()
return !open && cell && cell.charge>0 && (wires & wire_power1) && (wires & wire_power2)
// mousedrop a crate to load the bot
// can load anything if emagged
/obj/machinery/bot/mulebot/MouseDrop_T(var/atom/movable/C, mob/user)
if(user.stat)
return
if (!on || !istype(C)|| C.anchored || get_dist(user, src) > 1 || get_dist(src,C) > 1 )
return
if(load)
return
load(C)
// called to load a crate
/obj/machinery/bot/mulebot/proc/load(var/atom/movable/C)
if((wires & wire_loadcheck) && !istype(C,/obj/structure/closet/crate))
src.visible_message("[src] makes a sighing buzz.", "You hear an electronic buzzing sound.")
playsound(src.loc, 'buzz-sigh.ogg', 50, 0)
return // if not emagged, only allow crates to be loaded
if(get_dist(C, src) > 1 || load || !on)
return
mode = 1
// if a create, close before loading
var/obj/structure/closet/crate/crate = C
if(istype(crate))
crate.close()
C.loc = src.loc
sleep(2)
C.loc = src
load = C
C.pixel_y += 9
if(C.layer < layer)
C.layer = layer + 0.1
overlays += C
if(ismob(C))
var/mob/M = C
if(M.client)
M.client.perspective = EYE_PERSPECTIVE
M.client.eye = src
mode = 0
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)
if(!load)
return
mode = 1
overlays = null
load.loc = src.loc
load.pixel_y -= 9
load.layer = initial(load.layer)
if(ismob(load))
var/mob/M = load
if(M.client)
M.client.perspective = MOB_PERSPECTIVE
M.client.eye = src
if(dirn)
step(load, dirn)
load = null
// in case non-load items end up in contents, dump every else too
// this seems to happen sometimes due to race conditions
// with items dropping as mobs are loaded
for(var/atom/movable/AM in src)
if(AM == cell || AM == botcard) continue
AM.loc = src.loc
AM.layer = initial(AM.layer)
AM.pixel_y = initial(AM.pixel_y)
if(ismob(AM))
var/mob/M = AM
if(M.client)
M.client.perspective = MOB_PERSPECTIVE
M.client.eye = src
mode = 0
/obj/machinery/bot/mulebot/process()
if(!has_power())
on = 0
return
if(on)
var/speed = ((wires & wire_motor1) ? 1:0) + ((wires & wire_motor2) ? 2:0)
//world << "speed: [speed]"
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()
if(2)
process_bot()
spawn(4)
process_bot()
if(3)
process_bot()
if(refresh) updateDialog()
/obj/machinery/bot/mulebot/proc/process_bot()
//if(mode) world << "Mode: [mode]"
switch(mode)
if(0) // idle
icon_state = "mulebot0"
return
if(1) // loading/unloading
return
if(2,3,4) // navigating to deliver,home, or blocked
if(loc == target) // reached target
at_target()
return
else if(path.len > 0 && target) // valid path
var/turf/next = path[1]
reached_target = 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/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
//world << "Successful move."
blockcount = 0
path -= loc
if(mode==4)
spawn(1)
send_status()
if(destination == home_destination)
mode = 3
else
mode = 2
else // failed to move
//world << "Unable to move."
blockcount++
mode = 4
if(blockcount == 3)
src.visible_message("[src] makes an annoyed buzzing sound", "You hear an electronic buzzing sound.")
playsound(src.loc, 'buzz-two.ogg', 50, 0)
if(blockcount > 5) // attempt 5 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, '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, 'ping.ogg', 50, 0)
mode = 4
mode =6
return
return
else
src.visible_message("[src] makes an annoyed buzzing sound", "You hear an electronic buzzing sound.")
playsound(src.loc, 'buzz-two.ogg', 50, 0)
//world << "Bad turf."
mode = 5
return
else
//world << "No path."
mode = 5
return
if(5) // calculate new path
//world << "Calc new path."
mode = 6
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, 'ping.ogg', 50, 0)
else
src.visible_message("[src] makes a sighing buzz.", "You hear an electronic buzzing sound.")
playsound(src.loc, 'buzz-sigh.ogg', 50, 0)
mode = 7
//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, 0, 250, id=botcard, exclude=avoid)
src.path = reverselist(src.path)
// 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)
spawn(0)
new_destination = new_dest
post_signal(beacon_freq, "findbeacon", "delivery")
updateDialog()
// starts bot moving to current destination
/obj/machinery/bot/mulebot/proc/start()
if(destination == home_destination)
mode = 3
else
mode = 2
icon_state = "mulebot[(wires & wire_mobavoid) == wire_mobavoid]"
// starts bot moving to home
// sends a beacon query to find
/obj/machinery/bot/mulebot/proc/start_home()
spawn(0)
set_destination(home_destination)
mode = 4
icon_state = "mulebot[(wires & wire_mobavoid) == wire_mobavoid]"
// 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, 'chime.ogg', 50, 0)
reached_target = 1
if(load) // if loaded, unload at target
unload(loaddir)
else
// not loaded
if(auto_pickup) // find a crate
var/atom/movable/AM
if(!(wires & wire_loadcheck)) // if emagged, load first unanchored thing we find
for(var/atom/movable/A in get_step(loc, loaddir))
if(!A.anchored)
AM = A
break
else // otherwise, look for crates only
AM = locate(/obj/structure/closet/crate) in get_step(loc,loaddir)
if(AM)
load(AM)
// 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
else
mode = 0 // otherwise go idle
send_status() // report status to anyone listening
return
// called when bot bumps into anything
/obj/machinery/bot/mulebot/Bump(var/atom/obs)
if(!(wires & wire_mobavoid)) //usually just bumps, but if avoidance disabled knock over mobs
var/mob/M = obs
if(ismob(M))
if(istype(M,/mob/living/silicon/robot))
src.visible_message("\red [src] bumps into [M]!")
else
src.visible_message("\red [src] knocks over [M]!")
M.pulling = null
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()
// 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]!")
playsound(src.loc, 'splat.ogg', 50, 1)
var/damage = rand(5,15)
H.apply_damage(2*damage, BRUTE, "head")
H.apply_damage(2*damage, BRUTE, "chest")
H.apply_damage(0.5*damage, BRUTE, "l_leg")
H.apply_damage(0.5*damage, BRUTE, "r_leg")
H.apply_damage(0.5*damage, BRUTE, "l_arm")
H.apply_damage(0.5*damage, BRUTE, "r_arm")
var/obj/effect/decal/cleanable/blood/B = new(src.loc)
B.blood_DNA = list()
B.blood_DNA[H.dna.unique_enzymes] = H.dna.b_type
bloodiness += 4
// player on mulebot attempted to move
/obj/machinery/bot/mulebot/relaymove(var/mob/user)
if(user.stat)
return
if(load == user)
unload(0)
return
// receive a radio signal
// used for control and beacon reception
/obj/machinery/bot/mulebot/receive_signal(datum/signal/signal)
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" && (wires & wire_remote_rx))
send_status()
recv = signal.data["command [suffix]"]
if(wires & wire_remote_rx)
// process control input
switch(recv)
if("stop")
mode = 0
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 & wire_beacon_rx)
if(recv == new_destination) // if the recvd 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
if(direction)
loaddir = text2num(direction)
else
loaddir = 0
icon_state = "mulebot[(wires & wire_mobavoid) == wire_mobavoid]"
calc_path()
updateDialog()
// send a radio signal with a single data key/value pair
/obj/machinery/bot/mulebot/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/mulebot/proc/post_signal_multiple(var/freq, var/list/keyval)
if(freq == beacon_freq && !(wires & wire_beacon_tx))
return
if(freq == control_freq && !(wires & wire_remote_tx))
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 if (signal.data["type"] == "mulebot")
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()
var/list/kv = list(
"type" = "mulebot",
"name" = suffix,
"loca" = (loc ? loc.loc : "Unknown"), // somehow loc can be null and cause a runtime - Quarxink
"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)
if(load)
load.emp_act(severity)
..()
/obj/machinery/bot/mulebot/explode()
src.visible_message("\red <B>[src] blows apart!</B>", 1)
var/turf/Tsec = get_turf(src)
new /obj/item/device/assembly/prox_sensor(Tsec)
new /obj/item/stack/rods(Tsec)
new /obj/item/stack/rods(Tsec)
new /obj/item/weapon/cable_coil/cut(Tsec)
if (cell)
cell.loc = Tsec
cell.update_icon()
cell = null
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
new /obj/effect/decal/cleanable/oil(src.loc)
unload(0)
del(src)