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 diff --git a/code/game/machinery/computer/ai_core.dm b/code/game/machinery/computer/ai_core.dm index 616a62c78b6..c3e0941b101 100644 --- a/code/game/machinery/computer/ai_core.dm +++ b/code/game/machinery/computer/ai_core.dm @@ -117,16 +117,16 @@ laws.add_inherent_law(M.newFreeFormLaw) usr << "Added a freeform law." - if(istype(P, /obj/item/device/mmi)) + if(istype(P, /obj/item/device/mmi) || istype(P, /obj/item/device/posibrain)) if(!P:brainmob) - user << "\red Sticking an empty MMI into the frame would sort of defeat the purpose." + user << "\red Sticking an empty [P] into the frame would sort of defeat the purpose." return if(P:brainmob.stat == 2) - user << "\red Sticking a dead brain into the frame would sort of defeat the purpose." + user << "\red Sticking a dead [P] into the frame would sort of defeat the purpose." return if(jobban_isbanned(P:brainmob, "AI")) - user << "\red This MMI does not seem to fit." + user << "\red This [P] does not seem to fit." return if(P:brainmob.mind) @@ -136,7 +136,7 @@ user.drop_item() P.loc = src brain = P - usr << "Added a brain." + usr << "Added [P]." icon_state = "3b" if(istype(P, /obj/item/weapon/crowbar) && brain) diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 84fd6c7ae9f..f3e14d0b291 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -668,7 +668,7 @@ /obj/mecha/attackby(obj/item/weapon/W as obj, mob/user as mob) - if(istype(W, /obj/item/device/mmi)) + if(istype(W, /obj/item/device/mmi) || istype(W, /obj/item/device/posibrain)) if(mmi_move_inside(W,user)) user << "[src]-MMI interface initialized successfuly" else @@ -1804,4 +1804,4 @@ //src.health = initial(src.health)/2.2 //src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) return -*/ +*/ diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index acd210f5ddc..189aad862a7 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -161,14 +161,14 @@ else user << "\blue You need to attach a flash to it first!" - if(istype(W, /obj/item/device/mmi)) + if(istype(W, /obj/item/device/mmi) || istype(W, /obj/item/device/posibrain)) var/obj/item/device/mmi/M = W if(check_completion()) if(!istype(loc,/turf)) - user << "\red You can't put the MMI in, the frame has to be standing on the ground to be perfectly precise." + user << "\red You can't put the [W] in, the frame has to be standing on the ground to be perfectly precise." return if(!M.brainmob) - user << "\red Sticking an empty MMI into the frame would sort of defeat the purpose." + user << "\red Sticking an empty [W] into the frame would sort of defeat the purpose." return if(!M.brainmob.key) var/ghost_can_reenter = 0 @@ -178,19 +178,19 @@ ghost_can_reenter = 1 break if(!ghost_can_reenter) - user << "The mmi indicates that their mind is completely unresponsive; there's no point." + user << "The [W] is completely unresponsive; there's no point." return if(M.brainmob.stat == DEAD) - user << "\red Sticking a dead brain into the frame would sort of defeat the purpose." + user << "\red Sticking a dead [W] into the frame would sort of defeat the purpose." return if(M.brainmob.mind in ticker.mode.head_revolutionaries) - user << "\red The frame's firmware lets out a shrill sound, and flashes 'Abnormal Memory Engram'. It refuses to accept the MMI." + user << "\red The frame's firmware lets out a shrill sound, and flashes 'Abnormal Memory Engram'. It refuses to accept the [W]." return if(jobban_isbanned(M.brainmob, "Cyborg")) - user << "\red This MMI does not seem to fit." + user << "\red This [W] does not seem to fit." return var/mob/living/silicon/robot/O = new /mob/living/silicon/robot(get_turf(loc)) diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm index 14304c59ad2..33677a3e9a9 100644 --- a/code/game/objects/items/weapons/cards_ids.dm +++ b/code/game/objects/items/weapons/cards_ids.dm @@ -69,7 +69,7 @@ if(!src.registered_name) //Stop giving the players unsanitized unputs! You are giving ways for players to intentionally crash clients! -Nodrak var t = copytext(sanitize(input(user, "What name would you like to put on this card?", "Agent card name", ishuman(user) ? user.real_name : user.name)),1,26) - if(!t || t == "Unknown" || t == "floor" || t == "wall" || t == "r-wall") //Same as mob/new_player/prefrences.dm + if(!t || t == "Unknown" || t == "floor" || t == "wall" || t == "r-wall" || t == "") //Same as mob/new_player/prefrences.dm alert("Invalid name.") return src.registered_name = t diff --git a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm index 87d964ada16..440c3718846 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm @@ -63,6 +63,8 @@ src.MouseDrop_T(W:affecting, user) //act like they were dragged onto the closet else user << "The locker is too small to stuff [W] into!" + if(isrobot(user)) + return user.drop_item() if(W) W.loc = src.loc diff --git a/code/modules/mob/living/carbon/brain/posibrain.dm b/code/modules/mob/living/carbon/brain/posibrain.dm new file mode 100644 index 00000000000..aad1b6ef253 --- /dev/null +++ b/code/modules/mob/living/carbon/brain/posibrain.dm @@ -0,0 +1,118 @@ +/obj/item/device/posibrain + name = "positronic brain" + desc = "A cube of shining metal, four inches to a side and covered in shallow grooves." + icon = 'icons/obj/assemblies.dmi' + icon_state = "posibrain" + w_class = 3 + origin_tech = "engineering=4;materials=4;bluespace=2;programming=6" + + var/list/construction_cost = list("metal"=500,"glass"=500,"silver"=200,"gold"=200,"plasma"=100,"diamond"=10) + var/construction_time = 75 + var/searching = 0 + var/askDelay = 10 * 60 * 1 + + req_access = list(access_robotics) + var/locked = 0 + var/mob/living/carbon/brain/brainmob = null//The current occupant. + var/obj/mecha = null//This does not appear to be used outside of reference in mecha.dm. + + attack_self(mob/user as mob) + if(!brainmob && searching == 0) + //Start the process of searching for a new user. + user << "\blue You carefully locate the manual activation switch and start the positronic brain's boot process." + icon_state = "posibrain-searching" + src.searching = 1 + src.request_player() + + proc/request_player() + for(var/mob/dead/observer/O in player_list) + if(jobban_isbanned(O, "pAI")) + continue + if(O.client) + if(O.client.be_pai) + question(O.client) + + proc/question(var/client/C) + spawn(0) + if(!C) return + var/response = alert(C, "Someone is requesting a personality for a positronic brain. Would you like to play as one?", "Positronic brain request", "Yes", "No", "Never for this round") + if(!C || brainmob) return //handle logouts that happen whilst the alert is waiting for a response, and responses issued after a brain has been located. + if(response == "Yes") + transfer_personality(C.mob) + else if (response == "Never for this round") + C.be_pai = 0 + + + proc/transfer_personality(var/mob/candidate) + + var/mob/living/carbon/brain/B = new(src) + + src.searching = 0 + + src.brainmob = B + src.brainmob.mind = candidate.mind + + src.brainmob.name = "PBU-[rand(100, 999)]" + src.brainmob.real_name = "PBU-[rand(100, 999)]" + src.brainmob.loc = src + src.brainmob.container = src + src.brainmob.stat = 0 + src.brainmob.silent = 0 + src.brainmob.brain_op_stage = 4.0 + src.brainmob.key = candidate.key + + dead_mob_list -= src.brainmob + living_mob_list += src.brainmob + + var/turf/T = get_turf_or_move(src.loc) + for (var/mob/M in viewers(T)) + M.show_message("\blue The positronic brain chimes quietly.") + icon_state = "posibrain-occupied" + + proc/reset_search() //We give the players sixty seconds to decide, then reset the timer. + + if(brainmob) return + + src.searching = 0 + icon_state = "posibrain" + + var/turf/T = get_turf_or_move(src.loc) + for (var/mob/M in viewers(T)) + M.show_message("\blue The positronic brain buzzes quietly, and the golden lights fade away. Perhaps you could try again?") + +/obj/item/device/posibrain/examine() + + set src in oview() + + if(!usr || !src) return + if( (usr.sdisabilities & BLIND || usr.blinded || usr.stat) && !istype(usr,/mob/dead/observer) ) + usr << "Something is there but you can't see it." + return + + var/msg = "*---------*\nThis is \icon[src] \a [src]!\n[desc]\n" + msg += "" + + if(src.brainmob) + switch(src.brainmob.stat) + if(CONSCIOUS) + if(!src.brainmob.client) msg += "It appears to be in stand-by mode.\n" //afk + if(UNCONSCIOUS) msg += "It doesn't seem to be responsive.\n" + if(DEAD) msg += "It appears to be completely inactive.\n" + else + msg += "[desc]\n" + msg += "*---------*" + usr << msg + return + +/obj/item/device/posibrain/emp_act(severity) + if(!brainmob) + return + else + switch(severity) + if(1) + brainmob.emp_damage += rand(20,30) + if(2) + brainmob.emp_damage += rand(10,20) + if(3) + brainmob.emp_damage += rand(0,10) + ..() \ No newline at end of file diff --git a/code/modules/mob/living/carbon/brain/say.dm b/code/modules/mob/living/carbon/brain/say.dm index 4b8174cc21b..c4d9a865da2 100644 --- a/code/modules/mob/living/carbon/brain/say.dm +++ b/code/modules/mob/living/carbon/brain/say.dm @@ -2,7 +2,7 @@ if (silent) return - if(!(container && istype(container, /obj/item/device/mmi))) + if(!(container && (istype(container, /obj/item/device/mmi) || istype(container, /obj/item/device/posibrain)))) return //No MMI, can't speak, bucko./N else if(prob(emp_damage*4)) diff --git a/code/modules/research/destructive_analyzer.dm b/code/modules/research/destructive_analyzer.dm index 719647ebaba..72430976b84 100644 --- a/code/modules/research/destructive_analyzer.dm +++ b/code/modules/research/destructive_analyzer.dm @@ -78,6 +78,8 @@ Note: Must be placed within 3 tiles of the R&D Console user << "\red The protolathe is busy right now." return if (istype(O, /obj/item) && !loaded_item) + if(isrobot(user)) //Don't put your module items in there! + return if(!O.origin_tech) user << "\red This doesn't seem to have a tech origin!" return diff --git a/html/changelog.html b/html/changelog.html index 8087b78fc83..dd89066edf0 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -46,6 +46,8 @@ Header Section +Visit the bleeding-edge test server at byond://tekkit.fallemmc.com:8000 + diff --git a/icons/obj/assemblies.dmi b/icons/obj/assemblies.dmi index a0c27d7816b..a4a72b0a380 100644 Binary files a/icons/obj/assemblies.dmi and b/icons/obj/assemblies.dmi differ