diff --git a/code/game/machinery/bots/farmbot.dm b/code/game/machinery/bots/farmbot.dm
deleted file mode 100644
index ef582351570..00000000000
--- a/code/game/machinery/bots/farmbot.dm
+++ /dev/null
@@ -1,590 +0,0 @@
-//Farmbots by GauHelldragon - 12/30/2012
-// A new type of buildable aiBot that helps out in hydroponics
-
-// Made by using a robot arm on a water tank and then adding:
-// A plant analyzer, a bucket, a mini-hoe and then a proximity sensor (in that order)
-
-// Will water, weed and fertilize plants that need it
-// When emagged, it will "water", "weed" and "fertilize" humans instead
-// Holds up to 10 fertilizers (only the type dispensed by the machines, not chemistry bottles)
-// It will fill up it's water tank at a sink when low.
-
-// The behavior panel can be unlocked with hydroponics access and be modified to disable certain behaviors
-// By default, it will ignore weeds and mushrooms, but can be set to tend to these types of plants as well.
-
-
-#define FARMBOT_MODE_WATER 1
-#define FARMBOT_MODE_FERTILIZE 2
-#define FARMBOT_MODE_WEED 3
-#define FARMBOT_MODE_REFILL 4
-#define FARMBOT_MODE_WAITING 5
-
-#define FARMBOT_ANIMATION_TIME 25 //How long it takes to use one of the action animations
-#define FARMBOT_EMAG_DELAY 60 //How long of a delay after doing one of the emagged attack actions
-#define FARMBOT_ACTION_DELAY 35 //How long of a delay after doing one of the normal actions
-
-/obj/machinery/bot/farmbot
- name = "Farmbot"
- desc = "The botanist's best friend."
- icon = 'aibots.dmi'
- icon_state = "farmbot0"
- layer = 5.0
- density = 1
- anchored = 0
- health = 50
- maxhealth = 50
- req_access =list(access_hydroponics)
-
- var/Max_Fertilizers = 10
-
- var/setting_water = 1
- var/setting_refill = 1
- var/setting_fertilize = 1
- var/setting_weed = 1
- var/setting_ignoreWeeds = 1
- var/setting_ignoreMushrooms = 1
-
- var/atom/target //Current target, can be a human, a hydroponics tray, or a sink
- var/mode //Which mode is being used, 0 means it is looking for work
-
- var/obj/structure/reagent_dispensers/watertank/tank // the water tank that was used to make it, remains inside the bot.
-
- var/path[] = new() // used for pathing
- var/frustration
-
-/obj/machinery/bot/farmbot/New()
- ..()
- src.icon_state = "farmbot[src.on]"
- spawn (4)
- src.botcard = new /obj/item/weapon/card/id(src)
- src.botcard.access = req_access
-
- if ( !tank ) //Should be set as part of making it... but lets check anyway
- tank = locate(/obj/structure/reagent_dispensers/watertank/) in contents
- if ( !tank ) //An admin must have spawned the farmbot! Better give it a tank.
- tank = new /obj/structure/reagent_dispensers/watertank(src)
-
-/obj/machinery/bot/farmbot/Bump(M as mob|obj) //Leave no door unopened!
- spawn(0)
- 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))
- D.open()
- src.frustration = 0
- return
- return
-
-/obj/machinery/bot/farmbot/turn_on()
- . = ..()
- src.icon_state = "farmbot[src.on]"
- src.updateUsrDialog()
-
-/obj/machinery/bot/farmbot/turn_off()
- ..()
- src.path = new()
- src.icon_state = "farmbot[src.on]"
- src.updateUsrDialog()
-
-/obj/machinery/bot/farmbot/attack_paw(mob/user as mob)
- return attack_hand(user)
-
-
-/obj/machinery/bot/farmbot/proc/get_total_ferts()
- var total_fert = 0
- for (var/obj/item/nutrient/fert in contents)
- total_fert++
- return total_fert
-
-/obj/machinery/bot/farmbot/attack_hand(mob/user as mob)
- . = ..()
- if (.)
- return
- var/dat
- dat += "Automatic Hyrdoponic Assisting Unit v1.0
"
- dat += "Status: [src.on ? "On" : "Off"]
"
-
- dat += "Water Tank: "
- if ( tank )
- dat += "\[[tank.reagents.total_volume]/[tank.reagents.maximum_volume]\]"
- else
- dat += "Error: Water Tank not Found"
-
- dat += "
Fertilizer Storage: \[[get_total_ferts()]/[Max_Fertilizers]\]"
-
- dat += "
Behaviour controls are [src.locked ? "locked" : "unlocked"]
"
- if(!src.locked)
- dat += "Watering Controls:
"
- dat += " Water Plants : [src.setting_water ? "Yes" : "No"]
"
- dat += " Refill Watertank : [src.setting_refill ? "Yes" : "No"]
"
- dat += "
Fertilizer Controls:
"
- dat += " Fertilize Plants : [src.setting_fertilize ? "Yes" : "No"]
"
- dat += "
Weeding Controls:
"
- dat += " Weed Plants : [src.setting_weed ? "Yes" : "No"]
"
- dat += "
Ignore Weeds : [src.setting_ignoreWeeds ? "Yes" : "No"]
"
- dat += "Ignore Mushrooms : [src.setting_ignoreMushrooms ? "Yes" : "No"]
"
- dat += ""
-
- user << browse("Farmbot v1.0 controls[dat]", "window=autofarm")
- onclose(user, "autofarm")
- return
-
-/obj/machinery/bot/farmbot/Topic(href, href_list)
- if(..())
- return
- usr.machine = src
- src.add_fingerprint(usr)
- if ((href_list["power"]) && (src.allowed(usr)))
- if (src.on)
- turn_off()
- else
- turn_on()
-
- else if((href_list["water"]) && (!src.locked))
- setting_water = !setting_water
- else if((href_list["refill"]) && (!src.locked))
- setting_refill = !setting_refill
- else if((href_list["fertilize"]) && (!src.locked))
- setting_fertilize = !setting_fertilize
- else if((href_list["weed"]) && (!src.locked))
- setting_weed = !setting_weed
- else if((href_list["ignoreWeed"]) && (!src.locked))
- setting_ignoreWeeds = !setting_ignoreWeeds
- else if((href_list["ignoreMush"]) && (!src.locked))
- setting_ignoreMushrooms = !setting_ignoreMushrooms
- else if (href_list["eject"] )
- flick("farmbot_hatch",src)
- for (var/obj/item/nutrient/fert in contents)
- fert.loc = get_turf(src)
-
- src.updateUsrDialog()
- return
-
-/obj/machinery/bot/farmbot/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))
- src.locked = !src.locked
- user << "Controls are now [src.locked ? "locked." : "unlocked."]"
- src.updateUsrDialog()
- else
- user << "\red Access denied."
-
- else if (istype(W, /obj/item/nutrient))
- if ( get_total_ferts() >= Max_Fertilizers )
- user << "The fertilizer storage is full!"
- return
- user.drop_item()
- W.loc = src
- user << "You insert [W]."
- flick("farmbot_hatch",src)
- src.updateUsrDialog()
- return
-
- else
- ..()
-
-/obj/machinery/bot/farmbot/Emag(mob/user as mob)
- ..()
- if(user) user << "\red You short out [src]'s plant identifier circuits."
- spawn(0)
- for(var/mob/O in hearers(src, null))
- O.show_message("\red [src] buzzes oddly!", 1)
- flick("farmbot_broke", src)
- src.emagged = 1
- src.on = 1
- src.icon_state = "farmbot[src.on]"
- target = null
- mode = FARMBOT_MODE_WAITING //Give the emagger a chance to get away! 15 seconds should be good.
- spawn(150)
- mode = 0
-
-/obj/machinery/bot/farmbot/explode()
- src.on = 0
- visible_message("\red [src] blows apart!", 1)
- var/turf/Tsec = get_turf(src)
-
- new /obj/item/weapon/minihoe(Tsec)
- new /obj/item/weapon/reagent_containers/glass/bucket(Tsec)
- new /obj/item/device/assembly/prox_sensor(Tsec)
- new /obj/item/device/analyzer/plant_analyzer(Tsec)
-
- if ( tank )
- tank.loc = Tsec
-
- for ( var/obj/item/nutrient/fert in contents )
- if ( prob(50) )
- fert.loc = Tsec
-
- if (prob(50))
- new /obj/item/robot_parts/l_arm(Tsec)
-
- var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
- s.set_up(3, 1, src)
- s.start()
- del(src)
- return
-
-/obj/machinery/bot/farmbot/process()
- set background = 1
-
- if(!src.on)
- return
-
- if ( emagged && prob(1) )
- flick("farmbot_broke", src)
-
- if ( mode == FARMBOT_MODE_WAITING )
- return
-
- if ( !mode || !target || !(target in view(7,src)) ) //Don't bother chasing down targets out of view
-
- mode = 0
- target = null
- if ( !find_target() )
- // Couldn't find a target, wait a while before trying again.
- mode = FARMBOT_MODE_WAITING
- spawn(100)
- mode = 0
- return
-
- if ( mode && target )
- if ( get_dist(target,src) <= 1 || ( emagged && mode == FARMBOT_MODE_FERTILIZE ) )
- // If we are in emagged fertilize mode, we throw the fertilizer, so distance doesn't matter
- frustration = 0
- use_farmbot_item()
- else
- move_to_target()
- return
-
-/obj/machinery/bot/farmbot/proc/use_farmbot_item()
- if ( !target )
- mode = 0
- return 0
-
- if ( emagged && !ismob(target) ) // Humans are plants!
- mode = 0
- target = null
- return 0
-
- if ( !emagged && !istype(target,/obj/machinery/hydroponics) && !istype(target,/obj/structure/sink) ) // Humans are not plants!
- mode = 0
- target = null
- return 0
-
- if ( mode == FARMBOT_MODE_FERTILIZE )
- //Find which fertilizer to use
- var/obj/item/nutrient/fert
- for ( var/obj/item/nutrient/nut in contents )
- fert = nut
- break
- if ( !fert )
- target = null
- mode = 0
- return
- fertilize(fert)
-
- if ( mode == FARMBOT_MODE_WEED )
- weed()
-
- if ( mode == FARMBOT_MODE_WATER )
- water()
-
- if ( mode == FARMBOT_MODE_REFILL )
- refill()
-
-
-
-
-/obj/machinery/bot/farmbot/proc/find_target()
- if ( emagged ) //Find a human and help them!
- for ( var/mob/living/carbon/human/human in view(7,src) )
- if (human.stat == 2)
- continue
-
- var list/options = list(FARMBOT_MODE_WEED)
- if ( get_total_ferts() )
- options.Add(FARMBOT_MODE_FERTILIZE)
- if ( tank && tank.reagents.total_volume >= 1 )
- options.Add(FARMBOT_MODE_WATER)
- mode = pick(options)
- target = human
- return mode
- return 0
- else
- if ( setting_refill && tank && tank.reagents.total_volume < 100 )
- for ( var/obj/structure/sink/source in view(7,src) )
- target = source
- mode = FARMBOT_MODE_REFILL
- return 1
- for ( var/obj/machinery/hydroponics/tray in view(7,src) )
- var newMode = GetNeededMode(tray)
- if ( newMode )
- mode = newMode
- target = tray
- return 1
- return 0
-
-/obj/machinery/bot/farmbot/proc/GetNeededMode(obj/machinery/hydroponics/tray)
- if ( !tray.planted || tray.dead )
- return 0
- if ( tray.myseed.plant_type == 1 && setting_ignoreWeeds )
- return 0
- if ( tray.myseed.plant_type == 2 && setting_ignoreMushrooms )
- return 0
-
- if ( setting_water && tray.waterlevel <= 10 && tank && tank.reagents.total_volume >= 1 )
- return FARMBOT_MODE_WATER
-
- if ( setting_weed && tray.weedlevel >= 5 )
- return FARMBOT_MODE_WEED
-
- if ( setting_fertilize && tray.nutrilevel <= 2 && get_total_ferts() )
- return FARMBOT_MODE_FERTILIZE
-
- return 0
-
-/obj/machinery/bot/farmbot/proc/move_to_target()
- //Mostly copied from medibot code.
-
- if(src.frustration > 8)
- target = null
- mode = 0
- frustration = 0
- src.path = new()
- if(src.target && (src.path.len) && (get_dist(src.target,src.path[src.path.len]) > 2))
- src.path = new()
- if(src.target && src.path.len == 0 && (get_dist(src,src.target) > 1))
- spawn(0)
- var/turf/dest = get_step_towards(target,src) //Can't pathfind to a tray, as it is dense, so pathfind to the spot next to the tray
-
- src.path = AStar(src.loc, dest, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 30,id=botcard)
- src.path = reverselist(src.path)
- if(src.path.len == 0)
- for ( var/turf/spot in orange(1,target) ) //The closest one is unpathable, try the other spots
- if ( spot == dest ) //We already tried this spot
- continue
- if ( spot.density )
- continue
- src.path = AStar(src.loc, spot, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 30,id=botcard)
- src.path = reverselist(src.path)
- if ( src.path.len > 0 )
- break
-
- if ( src.path.len == 0 )
- target = null
- mode = 0
- return
-
- if(src.path.len > 0 && src.target)
- step_to(src, src.path[1])
- src.path -= src.path[1]
- spawn(3)
- if(src.path.len)
- step_to(src, src.path[1])
- src.path -= src.path[1]
-
- if(src.path.len > 8 && src.target)
- src.frustration++
-
-
-/obj/machinery/bot/farmbot/proc/fertilize(obj/item/nutrient/fert)
- if ( !fert )
- target = null
- mode = 0
- return 0
-
- if ( emagged ) // Warning, hungry humans detected: throw fertilizer at them
- spawn(0)
- fert.loc = src.loc
- fert.throw_at(target, 16, 3)
- src.visible_message("\red [src] launches [fert.name] at [target.name]!")
- flick("farmbot_broke", src)
- spawn (FARMBOT_EMAG_DELAY)
- mode = 0
- target = null
- return 1
-
- else // feed them plants~
- var /obj/machinery/hydroponics/tray = target
- tray.nutrilevel = 10
- tray.yieldmod = fert.yieldmod
- tray.mutmod = fert.mutmod
- del fert
- tray.updateicon()
- icon_state = "farmbot_fertile"
- mode = FARMBOT_MODE_WAITING
-
- spawn (FARMBOT_ACTION_DELAY)
- mode = 0
- target = null
- spawn (FARMBOT_ANIMATION_TIME)
- icon_state = "farmbot[src.on]"
- return 1
-
-/obj/machinery/bot/farmbot/proc/weed()
- icon_state = "farmbot_hoe"
- spawn(FARMBOT_ANIMATION_TIME)
- icon_state = "farmbot[src.on]"
-
- if ( emagged ) // Warning, humans infested with weeds!
- mode = FARMBOT_MODE_WAITING
- spawn(FARMBOT_EMAG_DELAY)
- mode = 0
-
- if ( prob(50) ) // better luck next time little guy
- src.visible_message("\red [src] swings wildly at [target] with a minihoe, missing completely!")
-
- else // yayyy take that weeds~
- var/attackVerb = pick("slashed", "sliced", "cut", "clawed")
- var /mob/living/carbon/human/human = target
-
- src.visible_message("\red [src] [attackVerb] [human]!")
- var/damage = 5
- var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
- var/datum/organ/external/affecting = human.get_organ(ran_zone(dam_zone))
- var/armor = human.run_armor_check(affecting, "melee")
- human.apply_damage(damage,BRUTE,affecting,armor)
-
- else // warning, plants infested with weeds!
- mode = FARMBOT_MODE_WAITING
- spawn(FARMBOT_ACTION_DELAY)
- mode = 0
-
- var /obj/machinery/hydroponics/tray = target
- tray.weedlevel = 0
- tray.updateicon()
-
-/obj/machinery/bot/farmbot/proc/water()
- if ( !tank || tank.reagents.total_volume < 1 )
- mode = 0
- target = null
- return 0
-
- icon_state = "farmbot_water"
- spawn(FARMBOT_ANIMATION_TIME)
- icon_state = "farmbot[src.on]"
-
- if ( emagged ) // warning, humans are thirsty!
- var splashAmount = min(70,tank.reagents.total_volume)
- src.visible_message("\red [src] splashes [target] with a bucket of water!")
- playsound(src.loc, 'sound/effects/slosh.ogg', 25, 1)
- if ( prob(50) )
- tank.reagents.reaction(target, TOUCH) //splash the human!
- else
- tank.reagents.reaction(target.loc, TOUCH) //splash the human's roots!
- spawn(5)
- tank.reagents.remove_any(splashAmount)
-
- mode = FARMBOT_MODE_WAITING
- spawn(FARMBOT_EMAG_DELAY)
- mode = 0
- else
- var /obj/machinery/hydroponics/tray = target
- var/b_amount = tank.reagents.get_reagent_amount("water")
- if(b_amount > 0 && tray.waterlevel < 100)
- if(b_amount + tray.waterlevel > 100)
- b_amount = 100 - tray.waterlevel
- tank.reagents.remove_reagent("water", b_amount)
- tray.waterlevel += b_amount
- playsound(src.loc, 'sound/effects/slosh.ogg', 25, 1)
-
- // Toxicity dilutation code. The more water you put in, the lesser the toxin concentration.
- tray.toxic -= round(b_amount/4)
- if (tray.toxic < 0 ) // Make sure it won't go overboard
- tray.toxic = 0
-
- tray.updateicon()
- mode = FARMBOT_MODE_WAITING
- spawn(FARMBOT_ACTION_DELAY)
- mode = 0
-
-/obj/machinery/bot/farmbot/proc/refill()
- if ( !tank || !tank.reagents.total_volume > 600 || !istype(target,/obj/structure/sink) )
- mode = 0
- target = null
- return
-
- mode = FARMBOT_MODE_WAITING
- playsound(src.loc, 'sound/effects/slosh.ogg', 25, 1)
- src.visible_message("\blue [src] starts filling it's tank from [target].")
- spawn(300)
- src.visible_message("\blue [src] finishes filling it's tank.")
- src.mode = 0
- tank.reagents.add_reagent("water", tank.reagents.maximum_volume - tank.reagents.total_volume )
- playsound(src.loc, 'sound/effects/slosh.ogg', 25, 1)
-
-
-/obj/item/weapon/farmbot_arm_assembly
- name = "water tank/robot arm assembly"
- desc = "A water tank with a robot arm permanently grafted to it."
- icon = 'aibots.dmi'
- icon_state = "water_arm"
- var/build_step = 0
- var/created_name = "Farmbot" //To preserve the name if it's a unique farmbot I guess
- w_class = 3.0
-
- New()
- ..()
- spawn(4) // If an admin spawned it, it won't have a watertank it, so lets make one for em!
- var tank = locate(/obj/structure/reagent_dispensers/watertank) in contents
- if( !tank )
- new /obj/structure/reagent_dispensers/watertank(src)
-
-
-/obj/structure/reagent_dispensers/watertank/attackby(var/obj/item/robot_parts/S, mob/user as mob)
-
- if ((!istype(S, /obj/item/robot_parts/l_arm)) && (!istype(S, /obj/item/robot_parts/r_arm)))
- ..()
- return
-
- //Making a farmbot!
-
- var/obj/item/weapon/farmbot_arm_assembly/A = new /obj/item/weapon/farmbot_arm_assembly
-
- A.loc = src.loc
- A.layer = 20
- user << "You add the robot arm to the [src]"
- src.loc = A //Place the water tank into the assembly, it will be needed for the finished bot
-
- del(S)
-
-/obj/item/weapon/farmbot_arm_assembly/attackby(obj/item/weapon/W as obj, mob/user as mob)
- ..()
- if((istype(W, /obj/item/device/analyzer/plant_analyzer)) && (!src.build_step))
- src.build_step++
- user << "You add the plant analyzer to [src]!"
- src.name = "farmbot assembly"
- del(W)
-
- else if(( istype(W, /obj/item/weapon/reagent_containers/glass/bucket)) && (src.build_step == 1))
- src.build_step++
- user << "You add a bucket to [src]!"
- src.name = "farmbot assembly with bucket"
- del(W)
-
- else if(( istype(W, /obj/item/weapon/minihoe)) && (src.build_step == 2))
- src.build_step++
- user << "You add a minihoe to [src]!"
- src.name = "farmbot assembly with bucket and minihoe"
- del(W)
-
- else if((isprox(W)) && (src.build_step == 3))
- src.build_step++
- user << "You complete the Farmbot! Beep boop."
- var/obj/machinery/bot/farmbot/S = new /obj/machinery/bot/farmbot
- for ( var/obj/structure/reagent_dispensers/watertank/wTank in src.contents )
- wTank.loc = S
- S.tank = wTank
- S.loc = get_turf(src)
- S.name = src.created_name
- del(W)
- del(src)
-
- else if(istype(W, /obj/item/weapon/pen))
- var/t = input(user, "Enter new robot name", src.name, src.created_name) as text
- t = copytext(sanitize(t), 1, MAX_NAME_LEN)
- if (!t)
- return
- if (!in_range(src, usr) && src.loc != usr)
- return
-
- src.created_name = t