diff --git a/code/__HELPERS/lists.dm b/code/__HELPERS/lists.dm index b7caf86669..a1f13c18ab 100644 --- a/code/__HELPERS/lists.dm +++ b/code/__HELPERS/lists.dm @@ -30,6 +30,13 @@ return "[output][and_text][input[index]]" + +/proc/ConvertReqString2List(var/list/source_list) + var/list/temp_list = params2list(source_list) + for(var/O in temp_list) + temp_list[O] = text2num(temp_list[O]) + return temp_list + //Returns list element or null. Should prevent "index out of bounds" error. proc/listgetindex(var/list/list,index) if(istype(list) && list.len) diff --git a/code/game/machinery/OpTable.dm b/code/game/machinery/OpTable.dm index b01b0bbda6..6e1ecdf4ca 100644 --- a/code/game/machinery/OpTable.dm +++ b/code/game/machinery/OpTable.dm @@ -105,6 +105,16 @@ else icon_state = "table2-idle" +/obj/machinery/optable/MouseDrop_T(mob/target, mob/user) + + var/mob/living/M = user + if(user.stat || user.restrained() || !check_table(user) || !iscarbon(target)) + return + if(istype(M)) + take_victim(target,user) + else + return ..() + /obj/machinery/optable/verb/climb_on() set name = "Climb On Table" set category = "Object" diff --git a/code/game/machinery/kitchen/microwave.dm b/code/game/machinery/kitchen/microwave.dm index fbdcfd2760..fe75dff633 100644 --- a/code/game/machinery/kitchen/microwave.dm +++ b/code/game/machinery/kitchen/microwave.dm @@ -135,11 +135,12 @@ return 1 else user << "\red You have no idea what you can cook with this [O]." - return 1 + ..() src.updateUsrDialog() /obj/machinery/microwave/attack_ai(mob/user as mob) - return 0 + if(istype(user, /mob/living/silicon/robot) && Adjacent(user)) + attack_hand(user) /obj/machinery/microwave/attack_hand(mob/user as mob) user.set_machine(src) diff --git a/code/game/machinery/kitchen/smartfridge.dm b/code/game/machinery/kitchen/smartfridge.dm index 1b1bb9bfb5..f4e910a47d 100644 --- a/code/game/machinery/kitchen/smartfridge.dm +++ b/code/game/machinery/kitchen/smartfridge.dm @@ -244,7 +244,7 @@ ..() /obj/machinery/smartfridge/attack_ai(mob/user as mob) - return 0 + attack_hand(user) /obj/machinery/smartfridge/attack_hand(mob/user as mob) if(stat & (NOPOWER|BROKEN)) diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index 88819e492f..794fb0a887 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -479,17 +479,6 @@ if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf)))) if ((href_list["vend"]) && (src.vend_ready) && (!currently_vending)) - - if(istype(usr,/mob/living/silicon)) - if(istype(usr,/mob/living/silicon/robot)) - var/mob/living/silicon/robot/R = usr - if(!(R.module && istype(R.module,/obj/item/weapon/robot_module/butler) )) - usr << "\red The vending machine refuses to interface with you, as you are not in its target demographic!" - return - else - usr << "\red The vending machine refuses to interface with you, as you are not in its target demographic!" - return - if((!allowed(usr)) && !emagged && scan_id) //For SECURE VENDING MACHINES YEAH usr << "Access denied." //Unless emagged of course flick(icon_deny,src) @@ -504,6 +493,9 @@ if(R.price <= 0) src.vend(R, usr) + else if(istype(usr,/mob/living/silicon)) //If the item is not free, provide feedback if a synth is trying to buy something. + usr << "Artificial unit recognized. Artificial units cannot complete this transaction. Purchase canceled." + return else src.currently_vending = R if(!vendor_account || vendor_account.suspended) diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index 9c262243c6..da508a8a31 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -291,21 +291,14 @@ ..() if(istype(W, /obj/item/device/flash)) if(istype(user,/mob/living/silicon/robot)) - user << "\red How do you propose to do that?" - return - else if(src.flash1 && src.flash2) - user << "\blue You have already inserted the eyes!" - return - else if(src.flash1) - user.drop_item() - W.loc = src - src.flash2 = W - user << "\blue You insert the flash into the eye socket!" + var/current_module = user.get_active_hand() + if(current_module == W) + user << "How do you propose to do that?" + return + else + add_flashes(W,user) else - user.drop_item() - W.loc = src - src.flash1 = W - user << "\blue You insert the flash into the eye socket!" + add_flashes(W,user) else if(istype(W, /obj/item/weapon/stock_parts/manipulator)) user << "\blue You install some manipulators and modify the head, creating a functional spider-bot!" new /mob/living/simple_animal/spiderbot(get_turf(loc)) @@ -315,6 +308,22 @@ return return +/obj/item/robot_parts/head/proc/add_flashes(obj/item/W as obj, mob/user as mob) //Made into a seperate proc to avoid copypasta + if(src.flash1 && src.flash2) + user << "You have already inserted the eyes!" + return + else if(src.flash1) + user.drop_item() + W.loc = src + src.flash2 = W + user << "You insert the flash into the eye socket!" + else + user.drop_item() + W.loc = src + src.flash1 = W + user << "You insert the flash into the eye socket!" + + /obj/item/robot_parts/attackby(obj/item/W as obj, mob/user as mob) if(istype(W,/obj/item/weapon/card/emag)) if(sabotaged) diff --git a/code/game/objects/items/stacks/matter_synth.dm b/code/game/objects/items/stacks/matter_synth.dm index 0842f70d66..3483dfbc61 100644 --- a/code/game/objects/items/stacks/matter_synth.dm +++ b/code/game/objects/items/stacks/matter_synth.dm @@ -28,6 +28,9 @@ /datum/matter_synth/medicine name = "Medicine Synthesizer" +/datum/matter_synth/nanite + name = "Nanite Synthesizer" + /datum/matter_synth/metal name = "Metal Synthesizer" diff --git a/code/game/objects/items/weapons/RSF.dm b/code/game/objects/items/weapons/RSF.dm index 596675a094..d3dc598cc3 100644 --- a/code/game/objects/items/weapons/RSF.dm +++ b/code/game/objects/items/weapons/RSF.dm @@ -54,14 +54,9 @@ RSF user << "Changed dispensing mode to 'Dice Pack'" return if (mode == 5) - mode = 6 + mode = 1 user << "Changed dispensing mode to 'Cigarette'" return - if (mode == 6) - mode = 1 - user << "Changed dispensing mode to 'Dosh'" - return - // Change mode /obj/item/weapon/rsf/afterattack(atom/A, mob/user as mob, proximity) @@ -84,8 +79,8 @@ RSF switch(mode) if(1) - product = new /obj/item/weapon/spacecash/c10() - used_energy = 200 + product = new /obj/item/clothing/mask/smokable/cigarette() + used_energy = 10 if(2) product = new /obj/item/weapon/reagent_containers/food/drinks/drinkingglass() used_energy = 50 @@ -98,9 +93,6 @@ RSF if(5) product = new /obj/item/weapon/storage/pill_bottle/dice() used_energy = 200 - if(6) - product = new /obj/item/clothing/mask/smokable/cigarette() - used_energy = 10 user << "Dispensing [product ? product : "product"]..." product.loc = get_turf(A) diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 40163e7c78..08abff9c2b 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -249,6 +249,10 @@ src.add_fingerprint(user) return +/obj/structure/closet/attack_ai(mob/user) + if(istype(user, /mob/living/silicon/robot) && Adjacent(user)) // Robots can open/close it, but not the AI. + attack_hand(user) + /obj/structure/closet/relaymove(mob/user as mob) if(user.stat || !isturf(src.loc)) return diff --git a/code/global.dm b/code/global.dm index c7a1738127..86386e6b0e 100644 --- a/code/global.dm +++ b/code/global.dm @@ -231,7 +231,8 @@ var/list/cheartstopper = list("potassium_chloride") // Thi // Used by robots and robot preferences. var/list/robot_module_types = list( "Standard", "Engineering", "Construction", "Surgeon", "Crisis", - "Miner", "Janitor", "Service", "Clerical", "Security" + "Miner", "Janitor", "Service", "Clerical", "Security", + "Research" ) // Some scary sounds. @@ -264,4 +265,4 @@ var/global/obj/item/device/radio/intercom/global_announcer = new(null) var/list/station_departments = list("Command", "Medical", "Engineering", "Science", "Security", "Cargo", "Civilian") var/global/const/TICKS_IN_DAY = 864000 -var/global/const/TICKS_IN_SECOND = 10 \ No newline at end of file +var/global/const/TICKS_IN_SECOND = 10 diff --git a/code/modules/mob/living/silicon/robot/drone/drone_items.dm b/code/modules/mob/living/silicon/robot/drone/drone_items.dm index 68df16d020..8353972ba2 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_items.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_items.dm @@ -2,10 +2,12 @@ //Limited use. /obj/item/weapon/gripper name = "magnetic gripper" - desc = "A simple grasping tool for synthetic assets." + desc = "A simple grasping tool specialized in construction and engineering work." icon = 'icons/obj/device.dmi' icon_state = "gripper" + flags = NOBLUDGEON + //Has a list of items that it can hold. var/list/can_hold = list( /obj/item/weapon/cell, @@ -28,8 +30,14 @@ var/obj/item/wrapped = null // Item currently being held. + var/force_holder = null // + // VEEEEERY limited version for mining borgs. Basically only for swapping cells and upgrading the drills. /obj/item/weapon/gripper/miner + name = "drill maintenance gripper" + desc = "A simple grasping tool for the maintenance of heavy drilling machines." + icon_state = "gripper-mining" + can_hold = list( /obj/item/weapon/cell, /obj/item/weapon/stock_parts @@ -38,14 +46,58 @@ /obj/item/weapon/gripper/paperwork name = "paperwork gripper" desc = "A simple grasping tool for clerical work." - icon = 'icons/obj/device.dmi' - icon_state = "gripper" can_hold = list( /obj/item/weapon/clipboard, /obj/item/weapon/paper, /obj/item/weapon/paper_bundle, - /obj/item/weapon/card/id + /obj/item/weapon/card/id, + /obj/item/weapon/book, + /obj/item/weapon/newspaper + ) + +/obj/item/weapon/gripper/research //A general usage gripper, used for toxins/robotics/xenobio/etc + name = "scientific gripper" + icon_state = "gripper-sci" + desc = "A simple grasping tool suited to assist in a wide array of research applications." + + can_hold = list( + /obj/item/weapon/cell, + /obj/item/weapon/stock_parts, + /obj/item/device/mmi, + /obj/item/robot_parts, + /obj/item/borg/upgrade, + /obj/item/device/flash, //to build borgs + /obj/item/organ/brain, //to insert into MMIs. + /obj/item/stack/cable_coil, //again, for borg building + /obj/item/weapon/circuitboard, + /obj/item/slime_extract, + /obj/item/weapon/reagent_containers/glass, + /obj/item/weapon/reagent_containers/food/snacks/monkeycube + + ) + +/obj/item/weapon/gripper/service //Used to handle food, drinks, and seeds. + name = "service gripper" + icon_state = "gripper" + desc = "A simple grasping tool used to perform tasks in the service sector, such as handling food, drinks, and seeds." + + can_hold = list( + /obj/item/weapon/reagent_containers/glass, + /obj/item/weapon/reagent_containers/food, + /obj/item/seeds, + /obj/item/weapon/grown + ) + +/obj/item/weapon/gripper/no_use //Used when you want to hold and put items in other things, but not able to 'use' the item + +/obj/item/weapon/gripper/no_use/loader //This is used to disallow building with metal. + name = "sheet loader" + desc = "A specialized loading device, designed to pick up and insert sheets of materials inside machines." + icon_state = "gripper-sheet" + + can_hold = list( + /obj/item/stack/sheet ) /obj/item/weapon/gripper/attack_self(mob/user as mob) @@ -53,6 +105,9 @@ return wrapped.attack_self(user) return ..() +/obj/item/weapon/gripper/no_use/attack_self(mob/user as mob) + return + /obj/item/weapon/gripper/verb/drop_item() set name = "Drop Item" @@ -75,7 +130,12 @@ //update_icon() /obj/item/weapon/gripper/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob) - return (wrapped ? wrapped.attack(M,user) : 0) + if(wrapped) //The force of the wrapped obj gets set to zero during the attack() and afterattack(). + force_holder = wrapped.force + wrapped.force = 0.0 + wrapped.attack(M,user) + return 1 + return 0 /obj/item/weapon/gripper/afterattack(var/atom/target, var/mob/living/user, proximity, params) @@ -97,6 +157,9 @@ if(!resolved && wrapped && target) wrapped.afterattack(target,user,1) + //wrapped's force was set to zero. This resets it to the value it had before. + wrapped.force = force_holder + force_holder = null //If wrapped was neither deleted nor put into target, put it back into the gripper. if(wrapped && user && (wrapped.loc == user)) wrapped.loc = src @@ -145,6 +208,21 @@ user.visible_message("[user] removes the power cell from [A]!", "You remove the power cell.") + else if(istype(target,/mob/living/silicon/robot)) + var/mob/living/silicon/robot/A = target + if(A.opened) + if(A.cell) + + wrapped = A.cell + + A.cell.add_fingerprint(user) + A.cell.updateicon() + A.updateicon() + A.cell.loc = src + A.cell = null + + user.visible_message("[user] removes the power cell from [A]!", "You remove the power cell.") + //TODO: Matter decompiler. /obj/item/weapon/matter_decompiler diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 5ff1c23213..cab055696d 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -265,7 +265,8 @@ module_sprites["Bro"] = "Brobot" module_sprites["Rich"] = "maximillion" module_sprites["Default"] = "Service2" - module_sprites["Drone"] = "drone-service" // How does this even work...? Oh well. + module_sprites["Drone - Service"] = "drone-service" + module_sprites["Drone - Hydro"] = "drone-hydro" if("Clerical") module = new /obj/item/weapon/robot_module/clerical(src) @@ -277,6 +278,12 @@ module_sprites["Default"] = "Service2" module_sprites["Drone"] = "drone-service" + if("Research") + module = new /obj/item/weapon/robot_module/research(src) + module.channels = list("Science" = 1) + module_sprites["Droid"] = "droid-science" + module_sprites["Drone"] = "drone-science" + if("Miner") module = new /obj/item/weapon/robot_module/miner(src) module.channels = list("Supply" = 1) @@ -296,7 +303,8 @@ module_sprites["Standard"] = "surgeon" module_sprites["Advanced Droid"] = "droid-medical" module_sprites["Needles"] = "medicalrobot" - module_sprites["Drone" ] = "drone-medical" + module_sprites["Drone - Medical" ] = "drone-medical" + module_sprites["Drone - Chemistry" ] = "drone-chemistry" if("Surgeon") module = new /obj/item/weapon/robot_module/surgeon(src) @@ -731,7 +739,7 @@ else user << "Unable to locate a radio." - else if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) // trying to unlock the interface with an ID card + else if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)||istype(W, /obj/item/weapon/card/robot)) // trying to unlock the interface with an ID card if(emagged)//still allow them to open the cover user << "The interface seems slightly damaged" if(opened) @@ -868,6 +876,10 @@ //if they are holding or wearing a card that has access, that works if(check_access(H.get_active_hand()) || check_access(H.wear_id)) return 1 + else if(istype(M, /mob/living/silicon/robot)) + var/mob/living/silicon/robot/R = M + if(check_access(R.get_active_hand()) || istype(R.get_active_hand(), /obj/item/weapon/card/robot)) + return 1 return 0 /mob/living/silicon/robot/proc/check_access(obj/item/weapon/card/id/I) diff --git a/code/modules/mob/living/silicon/robot/robot_items.dm b/code/modules/mob/living/silicon/robot/robot_items.dm index 0d40f0954a..d18ca506cc 100644 --- a/code/modules/mob/living/silicon/robot/robot_items.dm +++ b/code/modules/mob/living/silicon/robot/robot_items.dm @@ -1,3 +1,138 @@ +//A portable analyzer, for research borgs. This is better then giving them a gripper which can hold anything and letting them use the normal analyzer. +/obj/item/weapon/portable_destructive_analyzer + name = "Portable Destructive Analyzer" + icon = 'icons/obj/items.dmi' + icon_state = "portable_analyzer" + desc = "Similar to the stationary version, this rather unwieldy device allows you to break down objects in the name of science." + + var/min_reliability = 90 //Can't upgrade, call it laziness or a drawback + + var/datum/research/techonly/files //The device uses the same datum structure as the R&D computer/server. + //This analyzer can only store tech levels, however. + + var/obj/item/weapon/loaded_item //What is currently inside the analyzer. + +/obj/item/weapon/portable_destructive_analyzer/New() + ..() + files = new /datum/research/techonly(src) //Setup the research data holder. + +/obj/item/weapon/portable_destructive_analyzer/attack_self(user as mob) + var/response = alert(user, "Analyzing the item inside will *DESTROY* the item for good.\n\ + Syncing to the research server will send the data that is stored inside to research.\n\ + Ejecting will place the loaded item onto the floor.", + "What would you like to do?", "Analyze", "Sync", "Eject") + if(response == "Analyze") + if(loaded_item) + var/confirm = alert(user, "This will destroy the item inside forever. Are you sure?","Confirm Analyze","Yes","No") + if(confirm == "Yes") //This is pretty copypasta-y + user << "You activate the analyzer's microlaser, analyzing \the [loaded_item] and breaking it down." + flick("portable_analyzer_scan", src) + playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1) + if(loaded_item.reliability >= min_reliability) + var/list/temp_tech = ConvertReqString2List(loaded_item.origin_tech) + for(var/T in temp_tech) + files.UpdateTech(T, temp_tech[T]) + user << "\The [loaded_item] had level [temp_tech[T]] in [T]." + loaded_item = null + for(var/obj/I in contents) + for(var/mob/M in I.contents) + M.death() + if(istype(I,/obj/item/stack/sheet))//Only deconsturcts one sheet at a time instead of the entire stack + var/obj/item/stack/sheet/S = I + if(S.get_amount() > 1) + S.use(1) + loaded_item = S + else + del(S) + desc = initial(desc) + icon_state = initial(icon_state) + else + del(I) + desc = initial(desc) + icon_state = initial(icon_state) + else + return + else + user << "The [src] is empty. Put something inside it first." + if(response == "Sync") + var/success = 0 + for(var/obj/machinery/r_n_d/server/S in machines) + if(S.disabled) + continue + for(var/datum/tech/T in files.known_tech) //Uploading + S.files.AddTech2Known(T) + for(var/datum/tech/T in S.files.known_tech) //Downloading + files.AddTech2Known(T) + success = 1 + files.RefreshResearch() + if(success) + user << "You connect to the research server, push your data upstream to it, then pull the resulting merged data from the master branch." + playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 1) + else + user << "Reserch server ping response timed out. Unable to connect. Please contact the system administrator." + playsound(src.loc, 'sound/machines/buzz-two.ogg', 50, 1) + if(response == "Eject") + if(loaded_item) + loaded_item.loc = get_turf(src) + desc = initial(desc) + icon_state = initial(icon_state) + loaded_item = null + else + user << "The [src] is already empty." + + +/obj/item/weapon/portable_destructive_analyzer/afterattack(var/atom/target, var/mob/living/user, proximity) + if(!target) + return + if(!proximity) + return + if(!isturf(target.loc)) // Don't load up stuff if it's inside a container or mob! + return + if(istype(target,/obj/item)) + if(loaded_item) + user << "Your [src] already has something inside. Analyze or eject it first." + return + var/obj/item/I = target + I.loc = src + loaded_item = I + for(var/mob/M in viewers()) + M.show_message(text("[user] adds the [I] to the [src]."), 1) + desc = initial(desc) + "
It is holding \the [loaded_item]." + flick("portable_analyzer_load", src) + icon_state = "portable_analyzer_full" + +//This is used to unlock other borg covers. +/obj/item/weapon/card/robot //This is not a child of id cards, as to avoid dumb typechecks on computers. + name = "access code transmission device" + icon_state = "id-robot" + desc = "A circuit grafted onto the bottom of an ID card. It is used to transmit access codes into other robot chassis, \ + allowing you to lock and unlock other robots' panels." + +/obj/item/weapon/card/id/robot/attack_self() //override so borgs can't flash their IDs. + return + +/obj/item/weapon/card/id/robot/read() + usr << "The ID card does not appear to have any writing on it." + return + +//A harvest item for serviceborgs. +/obj/item/weapon/robot_harvester + name = "auto harvester" + desc = "A hand-held harvest tool that resembles a sickle. It uses energy to cut plant matter very efficently." + icon = 'icons/obj/weapons.dmi' + icon_state = "autoharvester" + +/obj/item/weapon/robot_harvester/afterattack(var/atom/target, var/mob/living/user, proximity) + if(!target) + return + if(!proximity) + return + if(istype(target,/obj/machinery/portable_atmospherics/hydroponics)) + var/obj/machinery/portable_atmospherics/hydroponics/T = target + T.harvest(user) + else + user << "Harvesting \a [target] is not the purpose of this tool. The [src] is for plants being grown." + // A special tray for the service droid. Allow droid to pick up and drop items as if they were using the tray normally // Click on table to unload, click on item to load. Otherwise works identically to a tray. // Unlike the base item "tray", robotrays ONLY pick up food, drinks and condiments. diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index 12565f4ea4..418860c0e1 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -314,8 +314,13 @@ /obj/item/weapon/robot_module/butler/New() ..() src.modules += new /obj/item/device/flash(src) - src.modules += new /obj/item/weapon/reagent_containers/food/drinks/cans/beer(src) - src.modules += new /obj/item/weapon/reagent_containers/food/condiment/enzyme(src) + src.modules += new /obj/item/weapon/gripper/service(src) + src.modules += new /obj/item/weapon/reagent_containers/glass/bucket(src) + src.modules += new /obj/item/weapon/minihoe(src) + src.modules += new /obj/item/weapon/hatchet(src) + src.modules += new /obj/item/device/analyzer/plant_analyzer(src) + src.modules += new /obj/item/weapon/storage/bag/plants(src) + src.modules += new /obj/item/weapon/robot_harvester(src) var/obj/item/weapon/rsf/M = new /obj/item/weapon/rsf(src) M.stored_matter = 30 @@ -358,6 +363,7 @@ src.modules += new /obj/item/weapon/pen/robopen(src) src.modules += new /obj/item/weapon/form_printer(src) src.modules += new /obj/item/weapon/gripper/paperwork(src) + src.modules += new /obj/item/weapon/hand_labeler(src) src.emag = new /obj/item/weapon/stamp/denied(src) /obj/item/weapon/robot_module/clerical/add_languages(var/mob/living/silicon/robot/R) @@ -395,6 +401,38 @@ src.emag = new /obj/item/weapon/pickaxe/plasmacutter(src) return +/obj/item/weapon/robot_module/research + name = "research module" + +/obj/item/weapon/robot_module/research/New() + ..() + src.modules += new /obj/item/device/flash(src) + src.modules += new /obj/item/weapon/portable_destructive_analyzer(src) + src.modules += new /obj/item/weapon/gripper/research(src) + src.modules += new /obj/item/weapon/gripper/no_use/loader(src) + src.modules += new /obj/item/device/robotanalyzer(src) + src.modules += new /obj/item/weapon/card/robot(src) + src.modules += new /obj/item/weapon/wrench(src) + src.modules += new /obj/item/weapon/screwdriver(src) + src.modules += new /obj/item/weapon/crowbar(src) + src.modules += new /obj/item/weapon/scalpel(src) + src.modules += new /obj/item/weapon/circular_saw(src) + src.modules += new /obj/item/weapon/extinguisher/mini(src) + src.modules += new /obj/item/weapon/reagent_containers/syringe(src) + src.modules += new /obj/item/weapon/reagent_containers/glass/beaker/large(src) + src.emag = new /obj/item/weapon/hand_tele(src) + + var/datum/matter_synth/nanite = new /datum/matter_synth/nanite(10000) + synths += nanite + + var/obj/item/stack/nanopaste/N = new /obj/item/stack/nanopaste(src) + N.uses_charge = 1 + N.charge_costs = list(1000) + N.synths = list(nanite) + src.modules += N + + return + /obj/item/weapon/robot_module/syndicate name = "illegal robot module" diff --git a/code/modules/research/circuitprinter.dm b/code/modules/research/circuitprinter.dm index a16e5653a9..e1e63c08dc 100644 --- a/code/modules/research/circuitprinter.dm +++ b/code/modules/research/circuitprinter.dm @@ -104,46 +104,51 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis). return 1 if(O.is_open_container()) return 0 - if(!istype(O, /obj/item/stack/sheet/glass) && !istype(O, /obj/item/stack/sheet/mineral/gold) && !istype(O, /obj/item/stack/sheet/mineral/diamond) && !istype(O, /obj/item/stack/sheet/mineral/uranium)) - user << "You cannot insert this item into \the [src]!" - return 1 +// if(!istype(O, /obj/item/stack/sheet/glass) && !istype(O, /obj/item/stack/sheet/mineral/gold) && !istype(O, /obj/item/stack/sheet/mineral/diamond) && !istype(O, /obj/item/stack/sheet/mineral/uranium)) +// user << "You cannot insert this item into \the [src]!" +// return 1 if(stat) return 1 if(busy) user << "\The [src] is busy. Please wait for completion of previous operation." return 1 - var/obj/item/stack/sheet/stack = O - if((TotalMaterials() + stack.perunit) > max_material_amount) - user << "\The [src] is full. Please remove glass from \the [src] in order to insert more." - return 1 - var/amount = round(input("How many sheets do you want to add?") as num) - if(amount < 0) - amount = 0 - if(amount == 0) - return - if(amount > stack.amount) - amount = min(stack.amount, round((max_material_amount - TotalMaterials()) / stack.perunit)) + if(istype(O, /obj/item/stack/sheet/glass) || istype(O, /obj/item/stack/sheet/mineral/gold) || istype(O, /obj/item/stack/sheet/mineral/diamond) || istype(O, /obj/item/stack/sheet/mineral/uranium)) - busy = 1 - use_power(max(1000, (3750 * amount / 10))) - var/stacktype = stack.type - stack.use(amount) - if(do_after(usr, 16)) - user << "You add [amount] sheets to \the [src]." - switch(stacktype) - if(/obj/item/stack/sheet/glass) - g_amount += amount * 3750 - if(/obj/item/stack/sheet/mineral/gold) - gold_amount += amount * 2000 - if(/obj/item/stack/sheet/mineral/diamond) - diamond_amount += amount * 2000 - if(/obj/item/stack/sheet/mineral/uranium) - uranium_amount += amount * 2000 - else - new stacktype(loc, amount) - busy = 0 - updateUsrDialog() + var/obj/item/stack/sheet/stack = O + if((TotalMaterials() + stack.perunit) > max_material_amount) + user << "\The [src] is full. Please remove glass from \the [src] in order to insert more." + return 1 + + var/amount = round(input("How many sheets do you want to add?") as num) + if(amount < 0) + amount = 0 + if(amount == 0) + return + if(amount > stack.amount) + amount = min(stack.amount, round((max_material_amount - TotalMaterials()) / stack.perunit)) + + busy = 1 + use_power(max(1000, (3750 * amount / 10))) + var/stacktype = stack.type + stack.use(amount) + if(do_after(usr, 16)) + user << "You add [amount] sheets to \the [src]." + switch(stacktype) + if(/obj/item/stack/sheet/glass) + g_amount += amount * 3750 + if(/obj/item/stack/sheet/mineral/gold) + gold_amount += amount * 2000 + if(/obj/item/stack/sheet/mineral/diamond) + diamond_amount += amount * 2000 + if(/obj/item/stack/sheet/mineral/uranium) + uranium_amount += amount * 2000 + else + new stacktype(loc, amount) + busy = 0 + updateUsrDialog() + + ..() //This is to stop these machines being hackable via clicking. /obj/machinery/r_n_d/circuit_imprinter/attack_hand(mob/user as mob) diff --git a/code/modules/research/destructive_analyzer.dm b/code/modules/research/destructive_analyzer.dm index 7b7445f099..3fc97cc6ab 100644 --- a/code/modules/research/destructive_analyzer.dm +++ b/code/modules/research/destructive_analyzer.dm @@ -13,7 +13,7 @@ Note: Must be placed within 3 tiles of the R&D Console var/obj/item/weapon/loaded_item = null var/decon_mod = 1 var/min_reliability = 90 - + use_power = 1 idle_power_usage = 30 active_power_usage = 2500 @@ -38,12 +38,6 @@ Note: Must be placed within 3 tiles of the R&D Console del(src) return -/obj/machinery/r_n_d/destructive_analyzer/proc/ConvertReqString2List(var/list/source_list) - var/list/temp_list = params2list(source_list) - for(var/O in temp_list) - temp_list[O] = text2num(temp_list[O]) - return temp_list - /obj/machinery/r_n_d/destructive_analyzer/update_icon() if(panel_open) icon_state = "d_analyzer_t" diff --git a/code/modules/research/protolathe.dm b/code/modules/research/protolathe.dm index 22df4b82dd..06f3f7b760 100644 --- a/code/modules/research/protolathe.dm +++ b/code/modules/research/protolathe.dm @@ -116,9 +116,6 @@ Note: Must be placed west/left of and R&D console to function. if(busy) user << "\The [src] is busy. Please wait for completion of previous operation." return 1 - if(!istype(O, /obj/item/stack/sheet)) - user << "You cannot insert this item into \the [src]!" - return 1 if(stat) return 1 if(istype(O,/obj/item/stack/sheet)) @@ -127,51 +124,52 @@ Note: Must be placed west/left of and R&D console to function. user << "\The [src]'s material bin is full. Please remove material before adding more." return 1 - var/obj/item/stack/sheet/stack = O - var/amount = round(input("How many sheets do you want to add?") as num)//No decimals - if(!O) - return - if(amount < 0)//No negative numbers - amount = 0 - if(amount == 0) - return - if(amount > stack.get_amount()) - amount = stack.get_amount() - if(max_material_storage - TotalMaterials() < (amount * stack.perunit))//Can't overfill - amount = min(stack.amount, round((max_material_storage - TotalMaterials()) / stack.perunit)) + var/obj/item/stack/sheet/stack = O + var/amount = round(input("How many sheets do you want to add?") as num)//No decimals + if(!O) + return + if(amount < 0)//No negative numbers + amount = 0 + if(amount == 0) + return + if(amount > stack.get_amount()) + amount = stack.get_amount() + if(max_material_storage - TotalMaterials() < (amount * stack.perunit))//Can't overfill + amount = min(stack.amount, round((max_material_storage - TotalMaterials()) / stack.perunit)) - overlays += "protolathe_[stack.name]" - sleep(10) - overlays -= "protolathe_[stack.name]" + overlays += "protolathe_[stack.name]" + sleep(10) + overlays -= "protolathe_[stack.name]" - icon_state = "protolathe" - busy = 1 - use_power(max(1000, (3750 * amount / 10))) - var/stacktype = stack.type - stack.use(amount) - if(do_after(user, 16)) - user << "You add [amount] sheets to \the [src]." icon_state = "protolathe" - switch(stacktype) - if(/obj/item/stack/sheet/metal) - m_amount += amount * 3750 - if(/obj/item/stack/sheet/glass) - g_amount += amount * 3750 - if(/obj/item/stack/sheet/mineral/gold) - gold_amount += amount * 2000 - if(/obj/item/stack/sheet/mineral/silver) - silver_amount += amount * 2000 - if(/obj/item/stack/sheet/mineral/phoron) - phoron_amount += amount * 2000 - if(/obj/item/stack/sheet/mineral/uranium) - uranium_amount += amount * 2000 - if(/obj/item/stack/sheet/mineral/diamond) - diamond_amount += amount * 2000 - else - new stacktype(loc, amount) - busy = 0 - updateUsrDialog() - return + busy = 1 + use_power(max(1000, (3750 * amount / 10))) + var/stacktype = stack.type + stack.use(amount) + if(do_after(user, 16)) + user << "You add [amount] sheets to \the [src]." + icon_state = "protolathe" + switch(stacktype) + if(/obj/item/stack/sheet/metal) + m_amount += amount * 3750 + if(/obj/item/stack/sheet/glass) + g_amount += amount * 3750 + if(/obj/item/stack/sheet/mineral/gold) + gold_amount += amount * 2000 + if(/obj/item/stack/sheet/mineral/silver) + silver_amount += amount * 2000 + if(/obj/item/stack/sheet/mineral/phoron) + phoron_amount += amount * 2000 + if(/obj/item/stack/sheet/mineral/uranium) + uranium_amount += amount * 2000 + if(/obj/item/stack/sheet/mineral/diamond) + diamond_amount += amount * 2000 + else + new stacktype(loc, amount) + busy = 0 + updateUsrDialog() + return + ..() //This is to stop these machines being hackable via clicking. /obj/machinery/r_n_d/protolathe/attack_hand(mob/user as mob) diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index 1ad86378b0..89e31574d2 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -256,7 +256,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, screen = 1.0 return if(linked_destroy.loaded_item.reliability >= linked_destroy.min_reliability) - var/list/temp_tech = linked_destroy.ConvertReqString2List(linked_destroy.loaded_item.origin_tech) + var/list/temp_tech = ConvertReqString2List(linked_destroy.loaded_item.origin_tech) for(var/T in temp_tech) files.UpdateTech(T, temp_tech[T]) if(linked_destroy.loaded_item.reliability < 100 && linked_destroy.loaded_item.crit_fail) @@ -753,7 +753,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, dat += "Name: [linked_destroy.loaded_item.name]
" dat += "Origin Tech:" dat += "