diff --git a/code/modules/recycling/conveyor2.dm b/code/modules/recycling/conveyor2.dm new file mode 100644 index 00000000000..da31364f326 --- /dev/null +++ b/code/modules/recycling/conveyor2.dm @@ -0,0 +1,223 @@ +//conveyor2 is pretty much like the original, except it supports corners, but not diverters. +//note that corner pieces transfer stuff clockwise when running forward, and anti-clockwise backwards. + +/obj/machinery/conveyor + icon = 'recycling.dmi' + icon_state = "conveyor0" + name = "conveyor belt" + desc = "A conveyor belt." + anchored = 1 + var/operating = 0 // 1 if running forward, -1 if backwards, 0 if off + var/operable = 1 // true if can operate (no broken segments in this belt run) + var/forwards // this is the default (forward) direction, set by the map dir + var/backwards // hopefully self-explanatory + var/movedir // the actual direction to move stuff in + + var/list/affecting // the list of all items that will be moved this ptick + var/id = "" // the control ID - must match controller ID + + // create a conveyor +/obj/machinery/conveyor/New() + ..() + switch(dir) + if(NORTH) + forwards = NORTH + backwards = SOUTH + if(SOUTH) + forwards = SOUTH + backwards = NORTH + if(EAST) + forwards = EAST + backwards = WEST + if(WEST) + forwards = WEST + backwards = EAST + if(NORTHEAST) + forwards = EAST + backwards = SOUTH + if(NORTHWEST) + forwards = SOUTH + backwards = WEST + if(SOUTHEAST) + forwards = NORTH + backwards = EAST + if(SOUTHWEST) + forwards = WEST + backwards = NORTH + +/obj/machinery/conveyor/proc/setmove() + if(operating == 1) + movedir = forwards + else + movedir = backwards + update() + +/obj/machinery/conveyor/proc/update() + if(stat & BROKEN) + icon_state = "conveyor-broken" + operating = 0 + return + if(!operable) + operating = 0 + if(stat & NOPOWER) + operating = 0 + icon_state = "conveyor[operating]" + + // machine process + // move items to the target location +/obj/machinery/conveyor/process() + if(stat & (BROKEN | NOPOWER)) + return + if(!operating) + return + use_power(100) + + affecting = loc.contents - src // moved items will be all in loc + spawn(1) // slight delay to prevent infinite propagation due to map order + var/items_moved = 0 + for(var/atom/movable/A in affecting) + if(!A.anchored) + if(isturf(A.loc)) // this is to prevent an ugly bug that forces a player to drop what they're holding if they recently pick it up from the conveyer belt + step(A,movedir) + items_moved++ + if(items_moved >= 10) + break + +// attack with item, place item on conveyor +/obj/machinery/conveyor/attackby(var/obj/item/I, mob/user) + user.drop_item() + if(I && I.loc) I.loc = src.loc + return + +// attack with hand, move pulled object onto conveyor +/obj/machinery/conveyor/attack_hand(mob/user as mob) + if ((!( user.canmove ) || user.restrained() || !( user.pulling ))) + return + if (user.pulling.anchored) + return + if ((user.pulling.loc != user.loc && get_dist(user, user.pulling) > 1)) + return + if (ismob(user.pulling)) + var/mob/M = user.pulling + M.pulling = null + step(user.pulling, get_dir(user.pulling.loc, src)) + user.pulling = null + else + step(user.pulling, get_dir(user.pulling.loc, src)) + user.pulling = null + return + + +// make the conveyor broken +// also propagate inoperability to any connected conveyor with the same ID +/obj/machinery/conveyor/proc/broken() + stat |= BROKEN + update() + + var/obj/machinery/conveyor/C = locate() in get_step(src, dir) + if(C) + C.set_operable(dir, id, 0) + + C = locate() in get_step(src, turn(dir,180)) + if(C) + C.set_operable(turn(dir,180), id, 0) + + +//set the operable var if ID matches, propagating in the given direction + +/obj/machinery/conveyor/proc/set_operable(stepdir, match_id, op) + + if(id != match_id) + return + operable = op + + update() + var/obj/machinery/conveyor/C = locate() in get_step(src, stepdir) + if(C) + C.set_operable(stepdir, id, op) + +/* +/obj/machinery/conveyor/verb/destroy() + set src in view() + src.broken() +*/ + +/obj/machinery/conveyor/power_change() + ..() + update() + +// the conveyor control switch +// +// + +/obj/machinery/conveyor_switch + + name = "conveyor switch" + desc = "A conveyor control switch." + icon = 'recycling.dmi' + icon_state = "switch-off" + var/position = 0 // 0 off, -1 reverse, 1 forward + var/last_pos = -1 // last direction setting + var/operated = 1 // true if just operated + + var/id = "" // must match conveyor IDs to control them + + var/list/conveyors // the list of converyors that are controlled by this switch + anchored = 1 + + + +/obj/machinery/conveyor_switch/New() + ..() + update() + + spawn(5) // allow map load + conveyors = list() + for(var/obj/machinery/conveyor/C in world) + if(C.id == id) + conveyors += C + +// update the icon depending on the position + +/obj/machinery/conveyor_switch/proc/update() + if(position<0) + icon_state = "switch-rev" + else if(position>0) + icon_state = "switch-fwd" + else + icon_state = "switch-off" + + +// timed process +// if the switch changed, update the linked conveyors + +/obj/machinery/conveyor_switch/process() + if(!operated) + return + operated = 0 + + for(var/obj/machinery/conveyor/C in conveyors) + C.operating = position + C.setmove() + +// attack with hand, switch position +/obj/machinery/conveyor_switch/attack_hand(mob/user) + if(position == 0) + if(last_pos < 0) + position = 1 + last_pos = 0 + else + position = -1 + last_pos = 0 + else + last_pos = position + position = 0 + + operated = 1 + update() + + // find any switches with same id as this one, and set their positions to match us + for(var/obj/machinery/conveyor_switch/S in world) + if(S.id == src.id) + S.position = position + S.update()