Merge pull request #11104 from phil235/BuckleMulebot

Mob buckled to mulebots
This commit is contained in:
Cheridan
2015-08-27 12:06:28 -05:00
4 changed files with 138 additions and 104 deletions

View File

@@ -70,17 +70,16 @@
#define BOT_MOVING 9 // for clean/floor/med bots, when moving. #define BOT_MOVING 9 // for clean/floor/med bots, when moving.
#define BOT_HEALING 10 // healing people (medbots) #define BOT_HEALING 10 // healing people (medbots)
#define BOT_RESPONDING 11 // responding to a call from the AI #define BOT_RESPONDING 11 // responding to a call from the AI
#define BOT_LOADING 12 // loading/unloading #define BOT_DELIVER 12 // moving to deliver
#define BOT_DELIVER 13 // moving to deliver #define BOT_GO_HOME 13 // returning to home
#define BOT_GO_HOME 14 // returning to home #define BOT_BLOCKED 14 // blocked
#define BOT_BLOCKED 15 // blocked #define BOT_NAV 15 // computing navigation
#define BOT_NAV 16 // computing navigation #define BOT_WAIT_FOR_NAV 16 // waiting for nav computation
#define BOT_WAIT_FOR_NAV 17 // waiting for nav computation #define BOT_NO_ROUTE 17 // no destination beacon found (or no route)
#define BOT_NO_ROUTE 18 // no destination beacon found (or no route)
var/list/mode_name = list("In Pursuit","Preparing to Arrest", "Arresting", \ var/list/mode_name = list("In Pursuit","Preparing to Arrest", "Arresting", \
"Beginning Patrol", "Patrolling", "Summoned by PDA", \ "Beginning Patrol", "Patrolling", "Summoned by PDA", \
"Cleaning", "Repairing", "Proceeding to work site", "Healing", \ "Cleaning", "Repairing", "Proceeding to work site", "Healing", \
"Proceeding to AI waypoint", "Loading/Unloading", "Navigating to Delivery Location", "Navigating to Home", \ "Proceeding to AI waypoint", "Navigating to Delivery Location", "Navigating to Home", \
"Waiting for clear path", "Calculating navigation path", "Pinging beacon network", "Unable to reach destination") "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. //This holds text for what the bot is mode doing, reported on the remote bot control interface.

View File

@@ -6,6 +6,11 @@
var/global/mulebot_count = 0 var/global/mulebot_count = 0
#define SIGH 0
#define ANNOYED 1
#define DELIGHT 2
/obj/machinery/bot/mulebot /obj/machinery/bot/mulebot
name = "\improper MULEbot" name = "\improper MULEbot"
desc = "A Multiple Utility Load Effector bot." desc = "A Multiple Utility Load Effector bot."
@@ -22,13 +27,15 @@ var/global/mulebot_count = 0
bot_type = MULE_BOT bot_type = MULE_BOT
model = "MULE" model = "MULE"
blood_DNA = list() blood_DNA = list()
can_buckle = 1
buckle_lying = 0
suffix = "" suffix = ""
var/turf/target // this is turf to navigate to (location of beacon) var/turf/target // this is turf to navigate to (location of beacon)
var/loaddir = 0 // this the direction to unload onto/load from var/loaddir = 0 // this the direction to unload onto/load from
var/home_destination = "" // tag of home beacon var/home_destination = "" // tag of home beacon
req_access = list(access_cargo) req_access = list(access_cargo)
mode = BOT_IDLE mode = BOT_IDLE
@@ -77,6 +84,26 @@ obj/machinery/bot/mulebot/bot_reset()
reached_target = 0 reached_target = 0
obj/machinery/bot/mulebot/Move(atom/newloc, direct)
. = ..()
if(buckled_mob)
if(!buckled_mob.Move(loc, direct))
loc = buckled_mob.loc //we gotta go back
last_move = buckled_mob.last_move
inertia_dir = last_move
buckled_mob.inertia_dir = last_move
. = 0
obj/machinery/bot/mulebot/Process_Spacemove(movement_dir = 0)
if(buckled_mob)
return buckled_mob.Process_Spacemove(movement_dir)
return ..()
obj/machinery/bot/mulebot/CanPass(atom/movable/mover, turf/target, height=1.5)
if(mover == buckled_mob)
return 1
return ..()
// attack by item // attack by item
// emag : lock/unlock, // emag : lock/unlock,
// screwdriver: open/close hatch // screwdriver: open/close hatch
@@ -183,8 +210,6 @@ obj/machinery/bot/mulebot/bot_reset()
switch(mode) switch(mode)
if(BOT_IDLE) if(BOT_IDLE)
dat += "<span class='good'>Ready</span>" dat += "<span class='good'>Ready</span>"
if(BOT_LOADING)
dat += "<span class='good'>[mode_name[BOT_LOADING]]</span>"
if(BOT_DELIVER) if(BOT_DELIVER)
dat += "<span class='good'>[mode_name[BOT_DELIVER]]</span>" dat += "<span class='good'>[mode_name[BOT_DELIVER]]</span>"
if(BOT_GO_HOME) if(BOT_GO_HOME)
@@ -358,7 +383,7 @@ obj/machinery/bot/mulebot/bot_reset()
updateDialog() updateDialog()
if("unload") if("unload")
if(load && mode !=1) if(load && mode != BOT_HUNT)
if(loc == target) if(loc == target)
unload(loaddir) unload(loaddir)
else else
@@ -379,7 +404,6 @@ obj/machinery/bot/mulebot/bot_reset()
// returns true if the bot has power // returns true if the bot has power
/obj/machinery/bot/mulebot/proc/has_power() /obj/machinery/bot/mulebot/proc/has_power()
return !open && cell && cell.charge > 0 && wires.HasPower() return !open && cell && cell.charge > 0 && wires.HasPower()
@@ -393,66 +417,94 @@ obj/machinery/bot/mulebot/bot_reset()
user << "<span class='danger'>Access denied.</span>" user << "<span class='danger'>Access denied.</span>"
return 0 return 0
/obj/machinery/bot/mulebot/proc/buzz(type)
switch(type)
if(SIGH)
visible_message("[src] makes a sighing buzz.", "<span class='italics'>You hear an electronic buzzing sound.</span>")
playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
if(ANNOYED)
visible_message("[src] makes an annoyed buzzing sound.", "<span class='italics'>You hear an electronic buzzing sound.</span>")
playsound(loc, 'sound/machines/buzz-two.ogg', 50, 0)
if(DELIGHT)
visible_message("[src] makes a delighted ping!", "<span class='italics'>You hear a ping.</span>")
playsound(loc, 'sound/machines/ping.ogg', 50, 0)
// mousedrop a crate to load the bot // mousedrop a crate to load the bot
// can load anything if emagged // can load anything if emagged
/obj/machinery/bot/mulebot/MouseDrop_T(atom/movable/AM, mob/user)
/obj/machinery/bot/mulebot/MouseDrop_T(atom/movable/C, mob/user) if(user.incapacitated() || user.lying)
if(user.stat)
return return
if (!on || !istype(C)|| C.anchored || get_dist(user, src) > 1 || get_dist(src,C) > 1 ) if (!istype(AM))
return return
if(load) load(AM)
return
load(C)
// called to load a crate // called to load a crate
/obj/machinery/bot/mulebot/proc/load(atom/movable/C) /obj/machinery/bot/mulebot/proc/load(atom/movable/AM)
if(wires.LoadCheck() && !istype(C,/obj/structure/closet/crate)) if(load || AM.anchored)
visible_message("[src] makes a sighing buzz.", "<span class='italics'>You hear an electronic buzzing sound.</span>")
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.
//So this is a simple fix that only allows a selection of item types to be considered. Further narrowing-down is below.
if(!istype(C,/obj/item) && !istype(C,/obj/machinery) && !istype(C,/obj/structure) && !ismob(C))
return
if(!isturf(C.loc)) //To prevent the loading from stuff from someone's inventory, which wouldn't get handled properly.
return return
if(get_dist(C, src) > 1 || load || !on) if(!isturf(AM.loc)) //To prevent the loading from stuff from someone's inventory or screen icons.
return return
mode = BOT_LOADING
// if a create, close before loading var/obj/structure/closet/crate/CRATE
var/obj/structure/closet/crate/crate = C if(istype(AM,/obj/structure/closet/crate))
if(istype(crate)) CRATE = AM
crate.close() else
if(wires.LoadCheck())
buzz(SIGH)
return // if not emagged, only allow crates to be loaded
C.loc = loc if(CRATE) // if it's a crate, close before loading
sleep(2) CRATE.close()
if(C.loc != loc) //To prevent you from going onto more thano ne bot.
return
C.loc = src
load = C
C.pixel_y += 9 if(isobj(AM))
if(C.layer < layer) var/obj/O = AM
C.layer = layer + 0.1 if(O.buckled_mob || (locate(/mob) in AM)) //can't load non crates objects with mobs buckled to it or inside it.
overlays += C buzz(SIGH)
return
if(ismob(C)) if(isliving(AM))
var/mob/M = C if(!buckle_mob(AM))
if(M.client) return
M.client.perspective = EYE_PERSPECTIVE else
M.client.eye = src AM.loc = src
AM.pixel_y += 9
if(AM.layer < layer)
AM.layer = layer + 0.1
overlays += AM
load= AM
mode = BOT_IDLE mode = BOT_IDLE
/obj/machinery/bot/mulebot/buckle_mob(mob/living/M)
if(M.buckled)
return 0
var/turf/T = get_turf(src)
if(M.loc != T)
density = 0
var/can_step = step_towards(M, T)
density = 1
if(!can_step)
return 0
return ..()
/obj/machinery/bot/mulebot/post_buckle_mob(mob/living/M)
if(M == buckled_mob) //post buckling
M.pixel_y = initial(M.pixel_y) + 9
if(M.layer < layer)
M.layer = layer + 0.1
else //post unbuckling
load = null
M.layer = initial(M.layer)
M.pixel_y = initial(M.pixel_y)
// called to unload the bot // called to unload the bot
// argument is optional direction to unload // argument is optional direction to unload
// if zero, unload at bot's location // if zero, unload at bot's location
@@ -460,18 +512,16 @@ obj/machinery/bot/mulebot/bot_reset()
if(!load) if(!load)
return return
mode = BOT_LOADING mode = BOT_IDLE
overlays.Cut() overlays.Cut()
if(ismob(load)) if(buckled_mob)
var/mob/M = load unbuckle_mob()
if(M.client) return
M.client.perspective = MOB_PERSPECTIVE
M.client.eye = src
load.loc = loc load.loc = loc
load.pixel_y -= 9 load.pixel_y = initial(load.pixel_y)
load.layer = initial(load.layer) load.layer = initial(load.layer)
if(dirn) if(dirn)
var/turf/T = loc var/turf/T = loc
@@ -481,22 +531,7 @@ obj/machinery/bot/mulebot/bot_reset()
load = null 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 || istype(AM , botcard) || AM == Radio) continue
AM.loc = 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 = BOT_IDLE
/obj/machinery/bot/mulebot/call_bot() /obj/machinery/bot/mulebot/call_bot()
..() ..()
@@ -536,14 +571,14 @@ obj/machinery/bot/mulebot/bot_reset()
if(refresh) updateDialog() if(refresh) updateDialog()
/obj/machinery/bot/mulebot/proc/process_bot() /obj/machinery/bot/mulebot/proc/process_bot()
//if(mode) world << "Mode: [mode]"
if(!on)
return
switch(mode) switch(mode)
if(BOT_IDLE) // idle if(BOT_IDLE) // idle
icon_state = "mulebot0" icon_state = "mulebot0"
return return
if(BOT_LOADING) // loading/unloading
return
if(BOT_DELIVER,BOT_GO_HOME,BOT_BLOCKED) // 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 if(loc == target) // reached target
@@ -603,26 +638,22 @@ obj/machinery/bot/mulebot/bot_reset()
blockcount++ blockcount++
mode = BOT_BLOCKED mode = BOT_BLOCKED
if(blockcount == 3) if(blockcount == 3)
visible_message("[src] makes an annoyed buzzing sound.", "<span class='italics'>You hear an electronic buzzing sound.</span>") buzz(ANNOYED)
playsound(loc, 'sound/machines/buzz-two.ogg', 50, 0)
if(blockcount > 10) // attempt 10 times before recomputing if(blockcount > 10) // attempt 10 times before recomputing
// find new path excluding blocked turf // find new path excluding blocked turf
visible_message("[src] makes a sighing buzz.", "<span class='italics'>You hear an electronic buzzing sound.</span>") buzz(SIGH)
playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
spawn(2) spawn(2)
calc_path(next) calc_path(next)
if(path.len > 0) if(path.len > 0)
visible_message("[src] makes a delighted ping!", "<span class='italics'>You hear a ping.</span>") buzz(DELIGHT)
playsound(loc, 'sound/machines/ping.ogg', 50, 0)
mode = BOT_BLOCKED mode = BOT_BLOCKED
mode = BOT_WAIT_FOR_NAV mode = BOT_WAIT_FOR_NAV
return return
return return
else else
visible_message("[src] makes an annoyed buzzing sound.", "<span class='italics'>You hear an electronic buzzing sound.</span>") buzz(ANNOYED)
playsound(loc, 'sound/machines/buzz-two.ogg', 50, 0)
//world << "Bad turf." //world << "Bad turf."
mode = BOT_NAV mode = BOT_NAV
return return
@@ -641,20 +672,12 @@ obj/machinery/bot/mulebot/bot_reset()
if(path.len > 0) if(path.len > 0)
blockcount = 0 blockcount = 0
mode = BOT_BLOCKED mode = BOT_BLOCKED
visible_message("[src] makes a delighted ping!", "<span class='italics'>You hear a ping.</span>") buzz(DELIGHT)
playsound(loc, 'sound/machines/ping.ogg', 50, 0)
else else
visible_message("[src] makes a sighing buzz.", "<span class='italics'>You hear an electronic buzzing sound.</span>") buzz(SIGH)
playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
mode = BOT_NO_ROUTE 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 // calculates a path to the current destination
@@ -673,6 +696,8 @@ obj/machinery/bot/mulebot/bot_reset()
// starts bot moving to current destination // starts bot moving to current destination
/obj/machinery/bot/mulebot/proc/start() /obj/machinery/bot/mulebot/proc/start()
if(!on)
return
if(destination == home_destination) if(destination == home_destination)
mode = BOT_GO_HOME mode = BOT_GO_HOME
else else
@@ -683,6 +708,8 @@ obj/machinery/bot/mulebot/bot_reset()
// starts bot moving to home // starts bot moving to home
// sends a beacon query to find // sends a beacon query to find
/obj/machinery/bot/mulebot/proc/start_home() /obj/machinery/bot/mulebot/proc/start_home()
if(!on)
return
spawn(0) spawn(0)
set_destination(home_destination) set_destination(home_destination)
mode = BOT_BLOCKED mode = BOT_BLOCKED
@@ -719,7 +746,7 @@ obj/machinery/bot/mulebot/bot_reset()
break break
else // otherwise, look for crates only else // otherwise, look for crates only
AM = locate(/obj/structure/closet/crate) in get_step(loc,loaddir) AM = locate(/obj/structure/closet/crate) in get_step(loc,loaddir)
if(AM) if(AM && AM.Adjacent(src))
load(AM) load(AM)
if(report_delivery) if(report_delivery)
speak("Now loading [load] at <b>[get_area(src)]</b>.", radio_frequency) speak("Now loading [load] at <b>[get_area(src)]</b>.", radio_frequency)
@@ -774,11 +801,10 @@ obj/machinery/bot/mulebot/bot_reset()
// player on mulebot attempted to move // player on mulebot attempted to move
/obj/machinery/bot/mulebot/relaymove(mob/user) /obj/machinery/bot/mulebot/relaymove(mob/user)
if(user.stat) if(user.incapacitated())
return return
if(load == user) if(load == user)
unload(0) unload(0)
return
//Update navigation data. Called when commanded to deliver, return home, or a route update is needed... //Update navigation data. Called when commanded to deliver, return home, or a route update is needed...
@@ -828,5 +854,12 @@ obj/machinery/bot/mulebot/bot_reset()
s.start() s.start()
new /obj/effect/decal/cleanable/oil(loc) new /obj/effect/decal/cleanable/oil(loc)
unload(0)
qdel(src) qdel(src)
/obj/machinery/bot/mulebot/Destroy()
unload(0)
return ..()
#undef SIGH
#undef ANNOYED
#undef DELIGHT

View File

@@ -93,7 +93,9 @@
else if(istype(A, /mob/living)) // You Shall Not Pass! else if(istype(A, /mob/living)) // You Shall Not Pass!
var/mob/living/M = A var/mob/living/M = A
if(!M.lying && !ismonkey(M) && !isslime(M)) //If your not laying down, or a small creature, no pass. if(M.buckled && istype(M.buckled, /obj/machinery/bot/mulebot)) // mulebot passenger gets a free pass.
return 1
if(!M.lying && !M.ventcrawler && M.mob_size != MOB_SIZE_TINY) //If your not laying down, or a ventcrawler or a small creature, no pass.
return 0 return 0
return ..() return ..()

View File

@@ -72,7 +72,7 @@
//Wrapper procs that handle sanity and user feedback //Wrapper procs that handle sanity and user feedback
/obj/proc/user_buckle_mob(mob/living/M, mob/user) /obj/proc/user_buckle_mob(mob/living/M, mob/user)
if(!user.Adjacent(M) || user.restrained() || user.lying || user.stat) if(!user.Adjacent(M) || user.lying || user.incapacitated())
return return
add_fingerprint(user) add_fingerprint(user)