diff --git a/aurorastation.dme b/aurorastation.dme
index 80db6869e2f..37eb9ae0f50 100644
--- a/aurorastation.dme
+++ b/aurorastation.dme
@@ -857,9 +857,6 @@
#include "code\game\objects\items\devices\radio\headset.dm"
#include "code\game\objects\items\devices\radio\intercom.dm"
#include "code\game\objects\items\devices\radio\radio.dm"
-#include "code\game\objects\items\robot\robot_items.dm"
-#include "code\game\objects\items\robot\robot_parts.dm"
-#include "code\game\objects\items\robot\robot_upgrades.dm"
#include "code\game\objects\items\stacks\matter_synth.dm"
#include "code\game\objects\items\stacks\medical.dm"
#include "code\game\objects\items\stacks\nanopaste.dm"
@@ -1976,7 +1973,6 @@
#include "code\modules\mob\living\silicon\robot\death.dm"
#include "code\modules\mob\living\silicon\robot\emote.dm"
#include "code\modules\mob\living\silicon\robot\examine.dm"
-#include "code\modules\mob\living\silicon\robot\gripper.dm"
#include "code\modules\mob\living\silicon\robot\inventory.dm"
#include "code\modules\mob\living\silicon\robot\laws.dm"
#include "code\modules\mob\living\silicon\robot\life.dm"
@@ -1986,7 +1982,6 @@
#include "code\modules\mob\living\silicon\robot\robot.dm"
#include "code\modules\mob\living\silicon\robot\robot_damage.dm"
#include "code\modules\mob\living\silicon\robot\robot_helpers.dm"
-#include "code\modules\mob\living\silicon\robot\robot_items.dm"
#include "code\modules\mob\living\silicon\robot\robot_modules.dm"
#include "code\modules\mob\living\silicon\robot\robot_movement.dm"
#include "code\modules\mob\living\silicon\robot\syndicate_robot.dm"
@@ -1997,6 +1992,25 @@
#include "code\modules\mob\living\silicon\robot\drone\drone_items.dm"
#include "code\modules\mob\living\silicon\robot\drone\drone_manufacturer.dm"
#include "code\modules\mob\living\silicon\robot\drone\drone_say.dm"
+#include "code\modules\mob\living\silicon\robot\items\_helpers.dm"
+#include "code\modules\mob\living\silicon\robot\items\auto_harvester.dm"
+#include "code\modules\mob\living\silicon\robot\items\electric_arm.dm"
+#include "code\modules\mob\living\silicon\robot\items\form_printer.dm"
+#include "code\modules\mob\living\silicon\robot\items\inductive_charger.dm"
+#include "code\modules\mob\living\silicon\robot\items\gripper.dm"
+#include "code\modules\mob\living\silicon\robot\items\overdrive.dm"
+#include "code\modules\mob\living\silicon\robot\items\portable_destructive_analyzer.dm"
+#include "code\modules\mob\living\silicon\robot\items\robot_id.dm"
+#include "code\modules\mob\living\silicon\robot\items\robot_inflatables.dm"
+#include "code\modules\mob\living\silicon\robot\items\robot_parts.dm"
+#include "code\modules\mob\living\silicon\robot\items\robot_pen.dm"
+#include "code\modules\mob\living\silicon\robot\items\robot_tools.dm"
+#include "code\modules\mob\living\silicon\robot\items\robot_tray.dm"
+#include "code\modules\mob\living\silicon\robot\items\guns\ballistic_cannon.dm"
+#include "code\modules\mob\living\silicon\robot\items\modules\mobility_module.dm"
+#include "code\modules\mob\living\silicon\robot\items\modules\robot_shield.dm"
+#include "code\modules\mob\living\silicon\robot\items\modules\sight.dm"
+#include "code\modules\mob\living\silicon\robot\items\upgrades\robot_upgrades.dm"
#include "code\modules\mob\living\simple_animal\bees.dm"
#include "code\modules\mob\living\simple_animal\corpse.dm"
#include "code\modules\mob\living\simple_animal\parrot.dm"
diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm
deleted file mode 100644
index c6a8103a367..00000000000
--- a/code/game/objects/items/robot/robot_items.dm
+++ /dev/null
@@ -1,99 +0,0 @@
-//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
-
-/**********************************************************************
- Cyborg Spec Items
-***********************************************************************/
-//Might want to move this into several files later but for now it works here
-// Consider changing this to a child of the stun baton class. ~Z
-/obj/item/borg/stun
- name = "electrified arm"
- icon = 'icons/obj/decals.dmi'
- icon_state = "shock"
-
-/obj/item/borg/stun/apply_hit_effect(mob/living/M, mob/living/silicon/robot/user, var/hit_zone)
- if(!istype(user))
- return 0
-
- user.visible_message("\The [user] has prodded \the [M] with \a [src]!")
-
- if(!user.cell || !user.cell.checked_use(1250)) //Slightly more than a baton.
- return 0
-
- playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
-
- M.apply_effect(5, STUTTER)
- M.stun_effect_act(0, 70, check_zone(hit_zone), src)
-
- if(ishuman(M))
- var/mob/living/carbon/human/H = M
- H.forcesay(hit_appends)
-
- return 0
-
-/obj/item/borg/overdrive
- name = "overdrive"
- icon = 'icons/obj/decals.dmi'
- icon_state = "shock"
-
-/**********************************************************************
- HUD/SIGHT things
-***********************************************************************/
-/obj/item/borg/sight
- icon = 'icons/obj/decals.dmi'
- icon_state = "securearea"
- var/sight_mode = null
-
-/obj/item/borg/sight/on_module_hotbar(mob/living/silicon/robot/R)
- R.sight_mode |= sight_mode
-
-/obj/item/borg/sight/on_module_store(mob/living/silicon/robot/R)
- R.sight_mode &= ~sight_mode
-
-/obj/item/borg/sight/xray
- name = "\proper x-ray vision"
- sight_mode = BORGXRAY
-
-
-/obj/item/borg/sight/thermal
- name = "\proper thermal vision"
- desc_antag = "Having this device on your hotbar will allow you to see in enhanced thermal vision, which allows you to see heat signatures through solid walls."
- sight_mode = BORGTHERM
- icon_state = "thermal"
- icon = 'icons/obj/clothing/glasses.dmi'
-
-
-/obj/item/borg/sight/meson
- name = "\proper meson vision"
- sight_mode = BORGMESON
- icon_state = "meson"
- icon = 'icons/obj/clothing/glasses.dmi'
-
-/obj/item/borg/sight/material
- name = "\proper material scanner vision"
- sight_mode = BORGMATERIAL
-
-/obj/item/borg/sight/hud
- name = "hud"
- var/obj/item/clothing/glasses/hud/hud = null
-
-
-/obj/item/borg/sight/hud/med
- name = "medical hud"
- icon_state = "healthhud"
- icon = 'icons/obj/clothing/glasses.dmi'
-
- New()
- ..()
- hud = new /obj/item/clothing/glasses/hud/health(src)
- return
-
-
-/obj/item/borg/sight/hud/sec
- name = "security hud"
- icon_state = "securityhud"
- icon = 'icons/obj/clothing/glasses.dmi'
-
- New()
- ..()
- hud = new /obj/item/clothing/glasses/hud/security(src)
- return
diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm
deleted file mode 100644
index efbdd32d328..00000000000
--- a/code/game/objects/items/robot/robot_parts.dm
+++ /dev/null
@@ -1,381 +0,0 @@
-/obj/item/robot_parts
- name = "robot parts"
- icon = 'icons/obj/robot_parts.dmi'
- item_state = "buildpipe"
- icon_state = "blank"
- flags = CONDUCT
- slot_flags = SLOT_BELT
- var/list/part = null // Order of args is important for installing robolimbs.
- var/sabotaged = 0 //Emagging limbs can have repercussions when installed as prosthetics.
- var/model_info
- var/linked_frame = "Unbranded Frame"
- dir = SOUTH
-
-/obj/item/robot_parts/set_dir()
- return
-
-/obj/item/robot_parts/New(var/newloc, var/model)
- ..(newloc)
- if(model_info && model)
- model_info = model
- var/datum/robolimb/R = all_robolimbs[model]
- if(R)
- name = "[R.company] robot [initial(name)]"
- desc = "[R.desc]"
- linked_frame = R.linked_frame
- if(icon_state in icon_states(R.icon))
- icon = R.icon
- else
- name = "robot [initial(name)]"
-
-/obj/item/robot_parts/l_arm
- name = "left arm"
- desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
- icon_state = "l_arm"
- part = list(BP_L_ARM,BP_L_HAND)
- model_info = 1
-
-/obj/item/robot_parts/r_arm
- name = "right arm"
- desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
- icon_state = "r_arm"
- part = list(BP_R_ARM,BP_R_HAND)
- model_info = 1
-
-/obj/item/robot_parts/l_leg
- name = "left leg"
- desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
- icon_state = "l_leg"
- part = list(BP_L_LEG,BP_L_FOOT)
- model_info = 1
-
-/obj/item/robot_parts/r_leg
- name = "right leg"
- desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
- icon_state = "r_leg"
- part = list(BP_R_LEG,BP_R_FOOT)
- model_info = 1
-
-/obj/item/robot_parts/chest
- name = "torso"
- desc = "A heavily reinforced case containing cyborg logic boards, with space for a standard power cell."
- icon_state = "chest"
- part = list(BP_GROIN,BP_CHEST)
- var/wires = 0.0
- var/obj/item/cell/cell = null
-
-/obj/item/robot_parts/head
- name = "head"
- desc = "A standard reinforced braincase, with spine-plugged neural socket and sensor gimbals."
- icon_state = "head"
- part = list(BP_HEAD)
- var/obj/item/device/flash/flash1 = null
- var/obj/item/device/flash/flash2 = null
- var/law_manager = TRUE
-
-/obj/item/robot_parts/robot_suit
- name = "endoskeleton"
- desc = "A complex metal backbone with standard limb sockets and pseudomuscle anchors."
- icon_state = "robo_suit"
- var/obj/item/robot_parts/l_arm/l_arm = null
- var/obj/item/robot_parts/r_arm/r_arm = null
- var/obj/item/robot_parts/l_leg/l_leg = null
- var/obj/item/robot_parts/r_leg/r_leg = null
- var/obj/item/robot_parts/chest/chest = null
- var/obj/item/robot_parts/head/head = null
- var/created_name = ""
-
-/obj/item/robot_parts/robot_suit/Initialize()
- . = ..()
- src.updateicon()
-
-/obj/item/robot_parts/robot_suit/equipped/Initialize()
- . = ..()
- l_leg = new /obj/item/robot_parts/l_leg(src)
- r_leg = new /obj/item/robot_parts/r_leg(src)
- l_arm = new /obj/item/robot_parts/l_arm(src)
- r_arm = new /obj/item/robot_parts/r_arm(src)
- updateicon()
-
-/obj/item/robot_parts/robot_suit/proc/updateicon()
- cut_overlays()
- if(src.l_arm)
- add_overlay("l_arm+o")
- if(src.r_arm)
- add_overlay("r_arm+o")
- if(src.chest)
- add_overlay("chest+o")
- if(src.l_leg)
- add_overlay("l_leg+o")
- if(src.r_leg)
- add_overlay("r_leg+o")
- if(src.head)
- add_overlay("head+o")
-
-/obj/item/robot_parts/robot_suit/proc/check_completion()
- if(src.l_arm && src.r_arm)
- if(src.l_leg && src.r_leg)
- if(src.chest && src.head)
- feedback_inc("cyborg_frames_built",1)
- return 1
- return 0
-
-/obj/item/robot_parts/robot_suit/attackby(obj/item/W as obj, mob/user as mob)
- ..()
- if(istype(W, /obj/item/stack/material) && W.get_material_name() == DEFAULT_WALL_MATERIAL && !l_arm && !r_arm && !l_leg && !r_leg && !chest && !head)
- var/obj/item/stack/material/M = W
- if (M.use(1))
- var/obj/item/secbot_assembly/ed209_assembly/B = new /obj/item/secbot_assembly/ed209_assembly
- B.forceMove(get_turf(src))
- to_chat(user, "You armed the robot frame.")
- if (user.get_inactive_hand()==src)
- user.remove_from_mob(src)
- user.put_in_inactive_hand(B)
- qdel(src)
- else
- to_chat(user, "You need one sheet of metal to arm the robot frame.")
- if(istype(W, /obj/item/robot_parts/l_leg))
- if(src.l_leg) return
- user.drop_from_inventory(W,src)
- src.l_leg = W
- src.updateicon()
-
- if(istype(W, /obj/item/robot_parts/r_leg))
- if(src.r_leg) return
- user.drop_from_inventory(W,src)
- src.r_leg = W
- src.updateicon()
-
- if(istype(W, /obj/item/robot_parts/l_arm))
- if(src.l_arm) return
- user.drop_from_inventory(W,src)
- src.l_arm = W
- src.updateicon()
-
- if(istype(W, /obj/item/robot_parts/r_arm))
- if(src.r_arm) return
- user.drop_from_inventory(W,src)
- src.r_arm = W
- src.updateicon()
-
- if(istype(W, /obj/item/robot_parts/chest))
- if(src.chest) return
- if(W:wires && W:cell)
- user.drop_from_inventory(W,src)
- src.chest = W
- src.updateicon()
- else if(!W:wires)
- to_chat(user, "You need to attach wires to it first!")
- else
- to_chat(user, "You need to attach a cell to it first!")
-
- if(istype(W, /obj/item/robot_parts/head))
- if(src.head) return
- if(W:flash2 && W:flash1)
- user.drop_from_inventory(W,src)
- src.head = W
- src.updateicon()
- else
- to_chat(user, "You need to attach a flash to it first!")
-
- if(istype(W, /obj/item/device/mmi))
- var/obj/item/device/mmi/M = W
- if(check_completion())
- if(!istype(loc,/turf))
- to_chat(user, "You can't put \the [W] in, the frame has to be standing on the ground to be perfectly precise.")
- return
- if(!M.brainmob)
- to_chat(user, "Sticking an empty [W] into the frame would sort of defeat the purpose.")
- return
- if(!M.brainmob.key)
- var/ghost_can_reenter = 0
- if(M.brainmob.mind)
- for(var/mob/abstract/observer/G in player_list)
- if(G.can_reenter_corpse && G.mind == M.brainmob.mind)
- ghost_can_reenter = 1
- break
- if(!ghost_can_reenter)
- to_chat(user, "\The [W] is completely unresponsive; there's no point.")
- return
-
- if(M.brainmob.stat == DEAD)
- to_chat(user, "Sticking a dead [W] into the frame would sort of defeat the purpose.")
- return
-
- if(!src.head.law_manager)
-
- if(!is_alien_whitelisted(M.brainmob, "Baseline Frame") && config.usealienwhitelist)
- to_chat(user, "\The [W] does not seem to fit.")
- return
-
- var/mob/living/carbon/human/new_shell = new(get_turf(loc), src.chest.linked_frame)
- src.forceMove(new_shell) //so people won't mess around with the chassis until it is deleted
- M.brainmob.mind.transfer_to(new_shell)
- qdel(M)
- var/newname = sanitizeSafe(input(new_shell,"Enter a name, or leave blank for the default name.", "Name change","") as text, MAX_NAME_LEN)
- if(!newname)
- var/datum/language/L = all_languages[new_shell.species.default_language]
- newname = L.get_random_name()
- new_shell.real_name = newname
- new_shell.name = new_shell.real_name
- new_shell.change_appearance(APPEARANCE_ALL_HAIR | APPEARANCE_SKIN | APPEARANCE_EYE_COLOR, new_shell.loc, new_shell)
- qdel(src)
- return
-
- else
-
- if(jobban_isbanned(M.brainmob, "Cyborg"))
- to_chat(user, "\The [W] does not seem to fit.")
- return
-
- var/mob/living/silicon/robot/O = new /mob/living/silicon/robot(get_turf(loc), TRUE)
- if(!O) return
-
- user.drop_item() //TODO: Look into this.
-
- O.mmi = W
- O.invisibility = 0
- O.custom_name = created_name
- O.updatename("Default")
-
- M.brainmob.mind.transfer_to(O)
-
- if(O.mind && O.mind.special_role)
- O.mind.store_memory("In case you look at this after being borged, the objectives are only here until I find a way to make them not show up for you, as I can't simply delete them without screwing up round-end reporting. --NeoFite")
-
- O.job = "Cyborg"
-
- O.cell = chest.cell
- O.cell.forceMove(O)
- W.forceMove(O)//Should fix cybros run time erroring when blown up. It got deleted before, along with the frame.
-
- // Since we "magically" installed a cell, we also have to update the correct component.
- if(O.cell)
- var/datum/robot_component/cell_component = O.components["power cell"]
- cell_component.wrapped = O.cell
- cell_component.installed = 1
-
- feedback_inc("cyborg_birth",1)
- callHook("borgify", list(O))
- O.Namepick()
-
- qdel(src)
- else
- to_chat(user, "The MMI must go in after everything else!")
-
- if (W.ispen())
- var/t = sanitizeSafe(input(user, "Enter new robot name", src.name, src.created_name), MAX_NAME_LEN)
- if (!t)
- return
- if (!in_range(src, usr) && src.loc != usr)
- return
-
- src.created_name = t
-
- return
-
-/obj/item/robot_parts/chest/attackby(obj/item/W as obj, mob/user as mob)
- ..()
- if(istype(W, /obj/item/cell))
- if(src.cell)
- to_chat(user, "You have already inserted a cell!")
- return
- else
- user.drop_from_inventory(W,src)
- src.cell = W
- to_chat(user, "You insert the cell!")
- if(W.iscoil())
- if(src.wires)
- to_chat(user, "You have already inserted wire!")
- return
- else
- var/obj/item/stack/cable_coil/coil = W
- coil.use(1)
- src.wires = 1.0
- to_chat(user, "You insert the wire!")
- return
-
-/obj/item/robot_parts/head/attackby(obj/item/W as obj, mob/user as mob)
- ..()
- if(W.ismultitool())
- if(law_manager)
- to_chat(user, "You disable the lawing circuits on \the [src].")
- law_manager = FALSE
- else
- to_chat(user, "You enable the lawing circuits on \the [src].")
- law_manager = TRUE
-
- if(istype(W, /obj/item/device/flash))
- if(istype(user,/mob/living/silicon/robot))
- var/current_module = user.get_active_hand()
- if(current_module == W)
- to_chat(user, "How do you propose to do that?")
- return
- else
- add_flashes(W,user)
- else
- add_flashes(W,user)
- else if(istype(W, /obj/item/stock_parts/manipulator))
- to_chat(user, "You install some manipulators and modify the head, creating a functional spider-bot!")
-
-
-
- new /mob/living/simple_animal/spiderbot(get_turf(loc))
- user.drop_from_inventory(W,get_turf(loc))
- qdel(W)
- qdel(src)
- 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)
- to_chat(user, "You have already inserted the eyes!")
- return
- else if(src.flash1)
- user.drop_from_inventory(W,src)
- src.flash2 = W
- to_chat(user, "You insert the flash into the eye socket!")
- else
- user.drop_from_inventory(W,src)
- src.flash1 = W
- to_chat(user, "You insert the flash into the eye socket!")
-
-
-/obj/item/robot_parts/emag_act(var/remaining_charges, var/mob/user)
- if(sabotaged)
- to_chat(user, "[src] is already sabotaged!")
- else
- to_chat(user, "You short out the safeties.")
- sabotaged = 1
- return 1
-
-//branded chest, to be used in ipc ressurection
-
-/obj/item/robot_parts/chest/bishop
- name = "Bishop cybernetics torso"
- model_info = 1
- linked_frame = "Bishop Accessory Frame"
-
-/obj/item/robot_parts/chest/hephaestus
- name = "Hephaestus industries torso"
- linked_frame = "Hephaestus G2 Industrial Frame"
-
-/obj/item/robot_parts/chest/zenghu
- name = "Zeng-Hu pharmaceuticals torso"
- linked_frame = "Zeng-Hu Mobility Frame"
-
-/obj/item/robot_parts/chest/synthskin
- name = "Human synthskin torso"
- linked_frame = "Shell Frame"
-
-/obj/item/robot_parts/chest/xion
- name = "Xion manufacturing group torso"
- linked_frame = "Xion Industrial Frame"
-
-/obj/item/robot_parts/chest/ipc
- name = "Hephaestus integrated torso"
- linked_frame = "Baseline Frame"
-
-/obj/item/robot_parts/chest/industrial
- name = "Hephaestus industrial torso"
- linked_frame = "Hephaestus G1 Industrial Frame"
diff --git a/code/modules/custom_ka/core.dm b/code/modules/custom_ka/core.dm
index 75c6292565f..bdcac84fac2 100644
--- a/code/modules/custom_ka/core.dm
+++ b/code/modules/custom_ka/core.dm
@@ -103,10 +103,10 @@
to_chat(user,"The offical designation \"[official_name]\" is etched neatly on the side.")
if(installed_cell)
- to_chat(user,"It has [get_ammo()] shots remaining.")
+ to_chat(user, "It has [get_ammo()] shots remaining.")
/obj/item/gun/custom_ka/get_ammo()
- if(!installed_cell)
+ if(!installed_cell || !installed_cell.stored_charge)
return 0
return round(installed_cell.stored_charge / cost_increase)
diff --git a/code/modules/custom_ka/frames.dm b/code/modules/custom_ka/frames.dm
index a853938e435..5223d52c1df 100644
--- a/code/modules/custom_ka/frames.dm
+++ b/code/modules/custom_ka/frames.dm
@@ -71,7 +71,7 @@
mod_limit_increase = 100
origin_tech = list()
can_disassemble_cell = FALSE
- displays_maptext = FALSE
+ cyborg_maptext_override = TRUE
installed_cell = /obj/item/custom_ka_upgrade/cells/cyborg
installed_barrel = /obj/item/custom_ka_upgrade/barrels/barrel02
diff --git a/code/modules/mining/minebot.dm b/code/modules/mining/minebot.dm
index 2d9a9d752a6..25ac4b8afea 100644
--- a/code/modules/mining/minebot.dm
+++ b/code/modules/mining/minebot.dm
@@ -1,5 +1,6 @@
/mob/living/silicon/robot/drone/mining
icon_state = "miningdrone"
+ mod_type = "Mining"
law_type = /datum/ai_laws/mining_drone
module_type = /obj/item/robot_module/mining_drone/basic
holder_type = /obj/item/holder/drone/mining
@@ -53,7 +54,7 @@
if(!laws)
laws = new law_type
if(!module)
- module = new module_type(src)
+ module = new module_type(src, src)
flavor_text = "It's a tiny little mining drone. The casing is stamped with an corporate logo and the subscript: '[current_map.company_name] Automated Pickaxe!'"
playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0)
diff --git a/code/modules/mob/living/silicon/robot/analyzer.dm b/code/modules/mob/living/silicon/robot/analyzer.dm
index 0523f4bcc9f..4f4dd1f9887 100644
--- a/code/modules/mob/living/silicon/robot/analyzer.dm
+++ b/code/modules/mob/living/silicon/robot/analyzer.dm
@@ -9,12 +9,11 @@
flags = CONDUCT
slot_flags = SLOT_BELT
throwforce = 3
- w_class = 2.0
+ w_class = ITEMSIZE_SMALL
throw_speed = 5
throw_range = 10
origin_tech = list(TECH_MAGNET = 2, TECH_BIO = 1, TECH_ENGINEERING = 2)
matter = list(DEFAULT_WALL_MATERIAL = 500, MATERIAL_GLASS = 200)
- var/mode = 1
/obj/item/device/robotanalyzer/attack(mob/living/M, mob/living/user)
if((user.is_clumsy() || (DUMB in user.mutations)) && prob(50))
@@ -99,5 +98,4 @@
if(!organ_found)
to_chat(user, SPAN_NOTICE("No prosthetics located."))
- add_fingerprint(user)
- return
\ No newline at end of file
+ add_fingerprint(user)
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/component.dm b/code/modules/mob/living/silicon/robot/component.dm
index 5f456173b1c..6736a800e6c 100644
--- a/code/modules/mob/living/silicon/robot/component.dm
+++ b/code/modules/mob/living/silicon/robot/component.dm
@@ -1,21 +1,18 @@
// TODO: remove the robot.mmi and robot.cell variables and completely rely on the robot component system
-/datum/robot_component/var/name
-/datum/robot_component/var/installed = 0
-/datum/robot_component/var/powered = 0
-/datum/robot_component/var/toggled = 1
-/datum/robot_component/var/brute_damage = 0
-/datum/robot_component/var/electronics_damage = 0
-/datum/robot_component/var/idle_usage = 0 // Amount of power used every MC tick. In joules.
-/datum/robot_component/var/active_usage = 0 // Amount of power used for every action. Actions are module-specific. Actuator for each tile moved, etc.
-/datum/robot_component/var/max_damage = 30 // HP of this component.
-/datum/robot_component/var/mob/living/silicon/robot/owner
-
-// The actual device object that has to be installed for this.
-/datum/robot_component/var/external_type = null
-
-// The wrapped device(e.g. radio), only set if external_type isn't null
-/datum/robot_component/var/obj/item/wrapped = null
+/datum/robot_component
+ var/name = "robot component"
+ var/installed = 0
+ var/powered = 0
+ var/toggled = 1
+ var/brute_damage = 0
+ var/electronics_damage = 0
+ var/idle_usage = 0 // Amount of power used every MC tick. In joules.
+ var/active_usage = 0 // Amount of power used for every action. Actions are module-specific. Actuator for each tile moved, etc.
+ var/max_damage = 30 // HP of this component.
+ var/mob/living/silicon/robot/owner
+ var/external_type = null // The actual device object that has to be installed for this.
+ var/obj/item/wrapped = null // The wrapped device(e.g. radio), only set if external_type isn't null
/datum/robot_component/New(mob/living/silicon/robot/R)
src.owner = R
@@ -28,7 +25,7 @@
/datum/robot_component/proc/destroy()
var/brokenstate = "broken" // Generic icon
- if (istype(wrapped, /obj/item/robot_parts/robot_component))
+ if(istype(wrapped, /obj/item/robot_parts/robot_component))
var/obj/item/robot_parts/robot_component/comp = wrapped
brokenstate = comp.icon_state_broken
if(wrapped)
diff --git a/code/modules/mob/living/silicon/robot/custom_sprites.dm b/code/modules/mob/living/silicon/robot/custom_sprites.dm
index ba1fe2a4a3e..f6b996f8bdd 100644
--- a/code/modules/mob/living/silicon/robot/custom_sprites.dm
+++ b/code/modules/mob/living/silicon/robot/custom_sprites.dm
@@ -9,6 +9,7 @@ var/list/robot_custom_icons
else if(config.load_customsynths_from == "json")
loadsynths_from_json()
return 1
+
/mob/living/silicon/robot/proc/set_custom_sprite()
var/datum/custom_synth/sprite = robot_custom_icons[name]
if(istype(sprite) && sprite.synthckey == ckey)
@@ -20,4 +21,4 @@ var/list/robot_custom_icons
icon_state = "[sprite.synthicon]-Standard"
else
to_chat(src, "Could not locate [sprite.synthicon]-Standard sprite.")
- icon = 'icons/mob/robots.dmi'
\ No newline at end of file
+ icon = 'icons/mob/robots.dmi'
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/death.dm b/code/modules/mob/living/silicon/robot/death.dm
index 8450719b7b7..439f647e761 100644
--- a/code/modules/mob/living/silicon/robot/death.dm
+++ b/code/modules/mob/living/silicon/robot/death.dm
@@ -6,11 +6,11 @@
/mob/living/silicon/robot/death(gibbed)
if(camera)
- camera.status = 0
+ camera.status = FALSE
if(module)
var/obj/item/gripper/G = locate(/obj/item/gripper) in module
if(G)
G.drop_item()
remove_robot_verbs()
sql_report_cyborg_death(src)
- ..(gibbed,"shudders violently for a moment, then becomes motionless, its eyes slowly darkening.")
+ ..(gibbed,"shudders violently for a moment, then becomes motionless, its eyes slowly darkening.")
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm
index ed29e1948b5..b6a3775e142 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone.dm
@@ -31,6 +31,7 @@
icon = 'icons/mob/robots.dmi'
icon_state = "repairbot"
braintype = "Robot"
+ mod_type = "Engineering"
gender = NEUTER
// Health
@@ -163,7 +164,7 @@
if(!laws)
laws = new law_type
if(!module)
- module = new module_type(src)
+ module = new module_type(src, src)
flavor_text = "It's a tiny little repair drone. The casing is stamped with an corporate logo and the subscript: '[current_map.company_name] Recursive Repair Systems: Fixing Tomorrow's Problem, Today!'"
playsound(get_turf(src), 'sound/machines/twobeep.ogg', 50, 0)
diff --git a/code/modules/mob/living/silicon/robot/examine.dm b/code/modules/mob/living/silicon/robot/examine.dm
index 6dbbfdb9e5b..30897292ebf 100644
--- a/code/modules/mob/living/silicon/robot/examine.dm
+++ b/code/modules/mob/living/silicon/robot/examine.dm
@@ -47,5 +47,4 @@
msg += "\nIt [pose]"
to_chat(user, msg)
- user.showLaws(src)
- return
\ No newline at end of file
+ user.showLaws(src)
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/inventory.dm b/code/modules/mob/living/silicon/robot/inventory.dm
index 562533c3200..4237dc39451 100644
--- a/code/modules/mob/living/silicon/robot/inventory.dm
+++ b/code/modules/mob/living/silicon/robot/inventory.dm
@@ -295,4 +295,4 @@
var/selected = get_selected_module()
if (selected)
result += "\nThe activity light on hardpoint [selected] is on.\n"
- return result
+ return result
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/items/_helpers.dm b/code/modules/mob/living/silicon/robot/items/_helpers.dm
new file mode 100644
index 00000000000..4424bb60aa2
--- /dev/null
+++ b/code/modules/mob/living/silicon/robot/items/_helpers.dm
@@ -0,0 +1,11 @@
+/obj/item/proc/on_module_hotbar(var/mob/living/silicon/robot/R)
+ return
+
+/obj/item/proc/on_module_store(var/mob/living/silicon/robot/R)
+ return
+
+/obj/item/proc/on_module_activate(var/mob/living/silicon/robot/R)
+ return
+
+/obj/item/proc/on_module_deactivate(var/mob/living/silicon/robot/R)
+ return
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/items/auto_harvester.dm b/code/modules/mob/living/silicon/robot/items/auto_harvester.dm
new file mode 100644
index 00000000000..c5871e7e039
--- /dev/null
+++ b/code/modules/mob/living/silicon/robot/items/auto_harvester.dm
@@ -0,0 +1,19 @@
+//A harvest item for serviceborgs.
+/obj/item/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"
+ hitsound = "swing_hit"
+
+/obj/item/robot_harvester/afterattack(var/atom/target, var/mob/living/user, proximity)
+ if(!target || !proximity)
+ return
+ if(istype(target, /obj/machinery/portable_atmospherics/hydroponics))
+ var/obj/machinery/portable_atmospherics/hydroponics/T = target
+ if(T.harvest) //Try to harvest, assuming it's alive.
+ T.harvest(user)
+ else if(T.dead) //It's probably dead otherwise.
+ T.remove_dead(user)
+ else
+ to_chat(user, SPAN_WARNING("ERROR: Harvesting \a [target] is not the purpose of this tool. \The [src] is for plants being grown."))
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/items/electric_arm.dm b/code/modules/mob/living/silicon/robot/items/electric_arm.dm
new file mode 100644
index 00000000000..381e016e54e
--- /dev/null
+++ b/code/modules/mob/living/silicon/robot/items/electric_arm.dm
@@ -0,0 +1,24 @@
+/obj/item/borg/stun
+ name = "electrified arm"
+ icon = 'icons/obj/decals.dmi'
+ icon_state = "shock"
+
+/obj/item/borg/stun/apply_hit_effect(mob/living/M, mob/living/silicon/robot/user, var/hit_zone)
+ if(!istype(user))
+ return FALSE
+
+ user.visible_message(SPAN_DANGER("\The [user] has prodded \the [M] with \a [src]!"), SPAN_DANGER("You prod \the [M] with \the [src]."))
+
+ if(!user.cell || !user.cell.checked_use(1250)) //Slightly more than a baton.
+ return FALSE
+
+ playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
+
+ M.apply_effect(5, STUTTER)
+ M.stun_effect_act(0, 70, check_zone(hit_zone), src)
+
+ if(ishuman(M))
+ var/mob/living/carbon/human/H = M
+ H.forcesay(hit_appends)
+
+ return FALSE
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/items/form_printer.dm b/code/modules/mob/living/silicon/robot/items/form_printer.dm
new file mode 100644
index 00000000000..5e226da794f
--- /dev/null
+++ b/code/modules/mob/living/silicon/robot/items/form_printer.dm
@@ -0,0 +1,22 @@
+//TODO: Add prewritten forms to dispense when you work out a good way to store the strings.
+/obj/item/form_printer
+ name = "paper dispenser"
+ icon = 'icons/obj/bureaucracy.dmi'
+ icon_state = "paper_bin1"
+ item_state = "sheet-metal"
+
+/obj/item/form_printer/attack(mob/living/carbon/M, mob/living/carbon/user)
+ return
+
+/obj/item/form_printer/afterattack(atom/target, mob/living/user, flag, params)
+ if(!target || !flag)
+ return
+ if(istype(target,/obj/structure/table))
+ deploy_paper(get_turf(target), user)
+
+/obj/item/form_printer/attack_self(mob/user)
+ deploy_paper(get_turf(src))
+
+/obj/item/form_printer/proc/deploy_paper(var/turf/T, var/mob/user)
+ T.visible_message(SPAN_NOTICE("\The [user] dispenses a sheet of crisp white paper."))
+ new /obj/item/paper(T)
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/gripper.dm b/code/modules/mob/living/silicon/robot/items/gripper.dm
similarity index 99%
rename from code/modules/mob/living/silicon/robot/gripper.dm
rename to code/modules/mob/living/silicon/robot/items/gripper.dm
index 90969ce01b9..94e519e734e 100644
--- a/code/modules/mob/living/silicon/robot/gripper.dm
+++ b/code/modules/mob/living/silicon/robot/items/gripper.dm
@@ -282,4 +282,4 @@
can_hold = list(
/obj/item/stack/material,
/obj/item/stack/tile
- )
+ )
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/items/guns/ballistic_cannon.dm b/code/modules/mob/living/silicon/robot/items/guns/ballistic_cannon.dm
new file mode 100644
index 00000000000..ba959e357f3
--- /dev/null
+++ b/code/modules/mob/living/silicon/robot/items/guns/ballistic_cannon.dm
@@ -0,0 +1,15 @@
+/obj/item/gun/energy/mountedcannon
+ name = "mounted ballistic cannon"
+ desc = "A cyborg mounted ballistic cannon."
+ icon = 'icons/obj/robot_items.dmi'
+ icon_state = "cannon"
+ item_state = "cannon"
+ fire_sound = 'sound/effects/Explosion1.ogg'
+ charge_meter = FALSE
+ max_shots = 10
+ charge_cost = 300
+ projectile_type = /obj/item/projectile/bullet/gyro
+ self_recharge = TRUE
+ use_external_power = TRUE
+ recharge_time = 5
+ needspin = FALSE
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/items/inductive_charger.dm b/code/modules/mob/living/silicon/robot/items/inductive_charger.dm
new file mode 100644
index 00000000000..4df1484a03c
--- /dev/null
+++ b/code/modules/mob/living/silicon/robot/items/inductive_charger.dm
@@ -0,0 +1,84 @@
+/obj/item/inductive_charger
+ name = "inductive charger"
+ desc = "A phoron-enhanced induction charger hooked up to its attached stationbound's internal cell."
+ desc_fluff = "Harnessing the energy potential found in phoron structures, Nanotrasen engineers have created a portable device capable of highly efficient wireless charging. The expense and limit of energy output of using this method of charging prevents it from being used on a large scale, being far outclassed by Phoron-Supermatter charging systems."
+ desc_info = "Click on an adjacent object that contains or is a power cell to attempt to find and charge it. After a successful charge, the inductive charger recharge in a few minutes. The amount transfered can be adjusted by alt clicking it."
+ icon = 'icons/obj/robot_items.dmi'
+ icon_state = "inductive_charger"
+ var/ready_to_use = TRUE
+ var/recharge_time = 300
+ var/transfer_rate = 5000
+ var/efficiency_mod = 0.9
+ maptext_x = 3
+ maptext_y = 2
+
+/obj/item/inductive_charger/Initialize()
+ . = ..()
+ maptext = "Ready"
+
+/obj/item/inductive_charger/AltClick(mob/user)
+ . = ..()
+ var/set_rate = input(user, "How much do you want to transfer per use? (Limit: 1 - 5000)", "Induction Transfer Rate", 5000) as num
+ if(set_rate > 5000)
+ set_rate = 5000
+ else if(set_rate < 1)
+ set_rate = 1
+ transfer_rate = set_rate
+ to_chat(user, SPAN_NOTICE("You set the transfer rate of \the [src] to [transfer_rate]."))
+
+/obj/item/inductive_charger/attack(mob/living/M, mob/living/user, target_zone)
+ return
+
+/obj/item/inductive_charger/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
+ var/mob/living/silicon/robot/R = user
+ if(!istype(R))
+ to_chat(user, SPAN_WARNING("Only cyborgs can use this!"))
+ return
+ if(!ready_to_use)
+ to_chat(user, SPAN_WARNING("\The [src] is still gathering charge!"))
+ return
+
+ user.visible_message("[user] begins waving \the [src] around \the [target]...", SPAN_NOTICE("You prepare to wirelessly charge \the [target]..."), range = 3)
+ if(!do_after(user, 50, TRUE, target))
+ return
+ if(R.cell.charge < 1000)
+ to_chat(user, SPAN_WARNING("You have no spare charge in your internal cell to give!"))
+ return
+
+ if(isipc(target))
+ var/mob/living/carbon/human/IPC = target
+ if(IPC.nutrition == IPC.max_nutrition)
+ to_chat(user, SPAN_WARNING("\The [IPC] is already fully charged!"))
+ return
+ var/charge_amount = min(IPC.max_nutrition - IPC.nutrition, transfer_rate)
+ var/charge_value = R.cell.use(charge_amount / efficiency_mod) * efficiency_mod
+ IPC.nutrition = min(IPC.max_nutrition, charge_value)
+ message_and_use(user, "[user] holds \the [src] over \the [IPC], topping up their battery.", SPAN_NOTICE("You wirelessly transmit [charge_value] units of power to \the [IPC], using [charge_value / efficiency_mod] of internal cell power."))
+ else if(isobj(target))
+ var/obj/item/cell/C
+ if(istype(target, /obj/item/cell))
+ C = target
+ else
+ C = locate() in target
+ if(!C)
+ to_chat(user, SPAN_WARNING("\The [target] doesn't contain a cell, or it's buried too deep for you to reach!"))
+ return
+ if(C.fully_charged())
+ to_chat(user, SPAN_WARNING("\The [C] is already fully charged!"))
+ return
+ var/charge_amount = min(C.maxcharge - C.charge, transfer_rate)
+ var/charge_value = R.cell.use(charge_amount / efficiency_mod) * efficiency_mod
+ C.give(charge_value)
+ message_and_use(user, "[user] holds \the [src] over \the [target], topping up its battery.", SPAN_NOTICE("You wirelessly transmit [charge_value] units of power to \the [target], using [charge_value / efficiency_mod] of internal cell power."))
+ else
+ to_chat(user, SPAN_WARNING("\The [src] cannot be used on \the [target]!"))
+
+/obj/item/inductive_charger/proc/message_and_use(mob/user, var/others_message, var/self_message)
+ user.visible_message(others_message, self_message, range = 3)
+ addtimer(CALLBACK(src, .proc/recharge), recharge_time)
+ ready_to_use = FALSE
+ maptext = "Charge"
+
+/obj/item/inductive_charger/proc/recharge()
+ ready_to_use = TRUE
+ maptext = "Ready"
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/items/modules/mobility_module.dm b/code/modules/mob/living/silicon/robot/items/modules/mobility_module.dm
new file mode 100644
index 00000000000..ee09a226635
--- /dev/null
+++ b/code/modules/mob/living/silicon/robot/items/modules/mobility_module.dm
@@ -0,0 +1,13 @@
+/obj/item/borg/combat/mobility
+ name = "mobility module"
+ desc = "By retracting limbs and tucking in its head, a combat android can roll at high speeds."
+ icon = 'icons/obj/decals.dmi'
+ icon_state = "shock"
+
+/obj/item/borg/combat/mobility/on_module_activate(mob/living/silicon/robot/R)
+ R.icon_state = "[R.module_sprites[R.icontype]]-roll"
+ R.speed = -2
+
+/obj/item/borg/combat/mobility/on_module_deactivate(mob/living/silicon/robot/R)
+ R.icon_state = R.module_sprites[R.icontype]
+ R.speed = initial(R.speed)
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/items/modules/robot_shield.dm b/code/modules/mob/living/silicon/robot/items/modules/robot_shield.dm
new file mode 100644
index 00000000000..bc951635477
--- /dev/null
+++ b/code/modules/mob/living/silicon/robot/items/modules/robot_shield.dm
@@ -0,0 +1,24 @@
+//Personal shielding for the combat module.
+/obj/item/borg/combat/shield
+ name = "personal shielding"
+ desc = "A powerful experimental module that turns aside or absorbs incoming attacks at the cost of charge."
+ icon = 'icons/obj/device.dmi'
+ icon_state = "shield1" //placeholder for now // four fucking years alberyk. FOUR
+ var/shield_level = 0.5 //Percentage of damage absorbed by the shield.
+ var/image/shield_overlay
+
+/obj/item/borg/combat/shield/on_module_activate(mob/living/silicon/robot/R)
+ shield_overlay = image(R.icon, "[R.module_sprites[R.icontype]]-shield")
+ R.add_overlay(shield_overlay)
+
+/obj/item/borg/combat/shield/on_module_deactivate(mob/living/silicon/robot/R)
+ R.cut_overlay(shield_overlay)
+
+/obj/item/borg/combat/shield/verb/set_shield_level()
+ set name = "Set shield level"
+ set category = "Object"
+ set src in range(0)
+
+ var/N = input(usr, "How much damage should the shield absorb?") in list("5", "10", "25", "50", "75", "100")
+ if(N)
+ shield_level = text2num(N)/100
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/items/modules/sight.dm b/code/modules/mob/living/silicon/robot/items/modules/sight.dm
new file mode 100644
index 00000000000..c7d7d09dfdd
--- /dev/null
+++ b/code/modules/mob/living/silicon/robot/items/modules/sight.dm
@@ -0,0 +1,54 @@
+/obj/item/borg/sight
+ icon = 'icons/obj/decals.dmi'
+ icon_state = "securearea"
+ var/sight_mode = null
+
+/obj/item/borg/sight/on_module_hotbar(mob/living/silicon/robot/R)
+ R.sight_mode |= sight_mode
+
+/obj/item/borg/sight/on_module_store(mob/living/silicon/robot/R)
+ R.sight_mode &= ~sight_mode
+
+/obj/item/borg/sight/xray
+ name = "\proper x-ray vision"
+ sight_mode = BORGXRAY
+
+/obj/item/borg/sight/thermal
+ name = "\proper thermal vision"
+ desc_antag = "Having this device on your hotbar will allow you to see in enhanced thermal vision, which allows you to see heat signatures through solid walls."
+ sight_mode = BORGTHERM
+ icon_state = "thermal"
+ icon = 'icons/obj/clothing/glasses.dmi'
+
+/obj/item/borg/sight/meson
+ name = "\proper meson vision"
+ sight_mode = BORGMESON
+ icon_state = "meson"
+ icon = 'icons/obj/clothing/glasses.dmi'
+
+/obj/item/borg/sight/material
+ name = "\proper material scanner vision"
+ sight_mode = BORGMATERIAL
+
+/obj/item/borg/sight/hud
+ name = "hud"
+ var/obj/item/clothing/glasses/hud/hud = null
+
+
+/obj/item/borg/sight/hud/med
+ name = "medical hud"
+ icon_state = "healthhud"
+ icon = 'icons/obj/clothing/glasses.dmi'
+
+/obj/item/borg/sight/hud/med/Initialize(mapload, ...)
+ . = ..()
+ hud = new /obj/item/clothing/glasses/hud/health(src)
+
+/obj/item/borg/sight/hud/sec
+ name = "security hud"
+ icon_state = "securityhud"
+ icon = 'icons/obj/clothing/glasses.dmi'
+
+/obj/item/borg/sight/hud/sec/Initialize(mapload, ...)
+ . = ..()
+ hud = new /obj/item/clothing/glasses/hud/security(src)
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/items/overdrive.dm b/code/modules/mob/living/silicon/robot/items/overdrive.dm
new file mode 100644
index 00000000000..d9335ba01b9
--- /dev/null
+++ b/code/modules/mob/living/silicon/robot/items/overdrive.dm
@@ -0,0 +1,4 @@
+/obj/item/borg/overdrive
+ name = "overdrive"
+ icon = 'icons/obj/decals.dmi'
+ icon_state = "shock"
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/items/portable_destructive_analyzer.dm b/code/modules/mob/living/silicon/robot/items/portable_destructive_analyzer.dm
new file mode 100644
index 00000000000..a670384f2b8
--- /dev/null
+++ b/code/modules/mob/living/silicon/robot/items/portable_destructive_analyzer.dm
@@ -0,0 +1,103 @@
+//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/portable_destructive_analyzer
+ name = "Portable Destructive Analyzer"
+ desc = "Similar to the stationary version, this rather unwieldy device allows you to break down objects in the name of science."
+ icon = 'icons/obj/robot_items.dmi'
+ icon_state = "portable_analyzer"
+
+ 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/loaded_item //What is currently inside the analyzer.
+
+/obj/item/portable_destructive_analyzer/Initialize()
+ . = ..()
+ files = new /datum/research/techonly(src) //Setup the research data holder.
+
+/obj/item/portable_destructive_analyzer/examine(mob/user, distance)
+ . = ..()
+ if(loaded_item && Adjacent(user))
+ to_chat(user, SPAN_NOTICE("It is holding \a [loaded_item]."))
+
+/obj/item/portable_destructive_analyzer/attack_self(mob/user)
+ 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
+ to_chat(user, SPAN_NOTICE("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)
+ for(var/T in loaded_item.origin_tech)
+ files.UpdateTech(T, loaded_item.origin_tech[T])
+ to_chat(user, SPAN_NOTICE("\The [loaded_item] had level [loaded_item.origin_tech[T]] in [CallTechName(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/material)) //Only deconstructs one sheet at a time instead of the entire stack
+ var/obj/item/stack/material/S = I
+ if(S.get_amount() > 1)
+ S.use(1)
+ loaded_item = S
+ else
+ qdel(S)
+ icon_state = initial(icon_state)
+ else
+ qdel(I)
+ icon_state = initial(icon_state)
+ else
+ return
+ else
+ to_chat(user, SPAN_WARNING("\The [src] is empty. Put something inside it first."))
+ if(response == "Sync")
+ var/success = FALSE
+ for(var/obj/machinery/r_n_d/server/S in SSmachinery.all_machines)
+ 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 = TRUE
+ files.RefreshResearch()
+ if(success)
+ to_chat(user, SPAN_NOTICE("You connect to the research server, push your data upstream to it, then pull the resulting merged data from the master branch.")) // fucking nerds
+ playsound(get_turf(src), 'sound/machines/twobeep.ogg', 50, TRUE)
+ else
+ to_chat(user, SPAN_WARNING("Research server ping response timed out. Unable to connect. Please contact the system administrator."))
+ playsound(get_turf(src), 'sound/machines/buzz-two.ogg', 50, 1)
+ if(response == "Eject")
+ if(loaded_item)
+ loaded_item.forceMove(get_turf(src))
+ icon_state = initial(icon_state)
+ loaded_item = null
+ else
+ to_chat(user, SPAN_WARNING("\The [src] is already empty."))
+
+
+/obj/item/portable_destructive_analyzer/afterattack(var/atom/target, var/mob/living/user, proximity)
+ if(!target || !proximity || !isturf(target.loc))
+ return
+ if(loaded_item)
+ to_chat(user, SPAN_WARNING("Your [src] already has something inside. Analyze or eject it first."))
+ return
+ if(istype(target,/obj/item))
+ var/obj/item/I = target
+ if(I.anchored)
+ to_chat(user, span("notice", "\The [I] is anchored in place."))
+ return
+ if(!I.origin_tech)
+ to_chat(user, SPAN_NOTICE("This doesn't seem to have a tech origin."))
+ return
+ if(!length(I.origin_tech))
+ to_chat(user, SPAN_NOTICE("You cannot deconstruct this item."))
+ return
+ I.forceMove(src)
+ loaded_item = I
+ visible_message(SPAN_NOTICE("\The [user] scoops \the [I] into \the [src]."))
+ flick("portable_analyzer_load", src)
+ icon_state = "portable_analyzer_full"
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/items/robot_id.dm b/code/modules/mob/living/silicon/robot/items/robot_id.dm
new file mode 100644
index 00000000000..29e78bac0be
--- /dev/null
+++ b/code/modules/mob/living/silicon/robot/items/robot_id.dm
@@ -0,0 +1,6 @@
+//This is used to unlock other borg covers.
+/obj/item/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."
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/items/robot_inflatables.dm b/code/modules/mob/living/silicon/robot/items/robot_inflatables.dm
new file mode 100644
index 00000000000..e8ab2172e44
--- /dev/null
+++ b/code/modules/mob/living/silicon/robot/items/robot_inflatables.dm
@@ -0,0 +1,119 @@
+#define MODE_WALL 0
+#define MODE_DOOR 1
+
+/obj/item/inflatable_dispenser
+ name = "inflatables dispenser"
+ desc = "Small device which allows rapid deployment and removal of inflatables."
+ icon = 'icons/obj/storage.dmi'
+ icon_state = "inf_deployer"
+ w_class = ITEMSIZE_NORMAL
+ var/deploying = FALSE
+ var/max_walls = 10
+ var/max_doors = 5
+ var/stored_walls = 10
+ var/stored_doors = 5
+ var/mode = MODE_WALL // 0 - Walls 1 - Doors
+
+/obj/item/inflatable_dispenser/Initialize(mapload, ...)
+ . = ..()
+ stored_walls = max_walls
+ stored_doors = max_doors
+
+/obj/item/inflatable_dispenser/examine(mob/user)
+ if(!..(user))
+ return
+ to_chat(user, SPAN_NOTICE("It has [stored_walls] wall segment\s and [stored_doors] door segment\s stored."))
+ to_chat(user, SPAN_NOTICE("It is set to deploy [mode ? "doors" : "walls"]"))
+
+/obj/item/inflatable_dispenser/attack_self(mob/user)
+ if(!deploying)
+ mode = !mode
+ to_chat(user, SPAN_NOTICE("You set \the [src] to deploy [mode ? "doors" : "walls"]."))
+ else
+ to_chat(user, SPAN_WARNING("You can't switch modes while deploying a [mode ? "door" : "wall"]!"))
+
+/obj/item/inflatable_dispenser/afterattack(var/atom/A, var/mob/user)
+ ..(A, user)
+ if(!user)
+ return
+ if(!user.Adjacent(A))
+ to_chat(user, SPAN_WARNING("You can't reach!"))
+ return
+ if(istype(A, /turf))
+ try_deploy_inflatable(A, user)
+ if(istype(A, /obj/item/inflatable) || istype(A, /obj/structure/inflatable))
+ pick_up(A, user)
+
+/obj/item/inflatable_dispenser/proc/try_deploy_inflatable(var/turf/T, var/mob/living/user)
+ if(deploying)
+ return
+
+ var/newtype
+ if(mode) // Door deployment
+ if(!stored_doors)
+ to_chat(user, SPAN_WARNING("\The [src] is out of doors!"))
+ return
+ if(T && istype(T))
+ newtype = /obj/structure/inflatable/door
+
+ else // Wall deployment
+ if(!stored_walls)
+ to_chat(user, SPAN_WARNING("\The [src] is out of walls!"))
+ return
+
+ if(T && istype(T))
+ newtype = /obj/structure/inflatable/wall
+
+ deploying = 1
+ user.visible_message("[user] starts deploying an inflatable [mode ? "door" : "wall"].", SPAN_NOTICE("You start deploying an inflatable [mode ? "door" : "wall"]!"))
+ playsound(T, 'sound/items/zip.ogg', 75, TRUE)
+ if(do_after(user, 30, needhand = FALSE))
+ new newtype(T)
+ if(mode)
+ stored_doors--
+ else
+ stored_walls--
+ deploying = FALSE
+
+/obj/item/inflatable_dispenser/proc/pick_up(var/obj/A, var/mob/living/user)
+ if(istype(A, /obj/structure/inflatable))
+ if(istype(A, /obj/structure/inflatable/wall))
+ if(stored_walls >= max_walls)
+ to_chat(user, SPAN_WARNING("\The [src] is full."))
+ return
+ stored_walls++
+ qdel(A)
+ else
+ if(stored_doors >= max_doors)
+ to_chat(user, SPAN_WARNING("\The [src] is full."))
+ return
+ stored_doors++
+ qdel(A)
+ playsound(get_turf(src), 'sound/machines/hiss.ogg', 75, TRUE)
+ visible_message("[user] deflates \the [A] with \the [src].", SPAN_NOTICE("You deinflate \the [A] with \the [src]."))
+ return
+ else if(istype(A, /obj/item/inflatable))
+ if(istype(A, /obj/item/inflatable/wall))
+ if(stored_walls >= max_walls)
+ to_chat(user, SPAN_WARNING("\The [src] is full."))
+ return
+ stored_walls++
+ qdel(A)
+ else
+ if(stored_doors >= max_doors)
+ to_chat(usr, SPAN_WARNING("\The [src] is full!"))
+ return
+ stored_doors++
+ qdel(A)
+ visible_message("[user] picks up \the [A] with \the [src].", SPAN_NOTICE("You pick up \the [A] with \the [src]."))
+ return
+
+ to_chat(user, SPAN_WARNING("You fail to pick up \the [A] with \the [src]."))
+ return
+
+/obj/item/inflatable_dispenser/borg
+ max_walls = 5
+ max_doors = 3
+
+#undef MODE_WALL
+#undef MODE_DOOR
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/items/robot_parts.dm b/code/modules/mob/living/silicon/robot/items/robot_parts.dm
new file mode 100644
index 00000000000..1563acc22c5
--- /dev/null
+++ b/code/modules/mob/living/silicon/robot/items/robot_parts.dm
@@ -0,0 +1,429 @@
+/obj/item/robot_parts
+ name = "robot parts"
+ icon = 'icons/obj/robot_parts.dmi'
+ item_state = "buildpipe"
+ icon_state = "blank"
+ flags = CONDUCT
+ slot_flags = SLOT_BELT
+ var/list/part = null // Order of args is important for installing robolimbs.
+ var/sabotaged = 0 //Emagging limbs can have repercussions when installed as prosthetics.
+ var/model_info
+ var/linked_frame = "Unbranded Frame"
+ dir = SOUTH
+
+/obj/item/robot_parts/set_dir()
+ return
+
+/obj/item/robot_parts/New(var/newloc, var/model)
+ ..(newloc)
+ if(model_info && model)
+ model_info = model
+ var/datum/robolimb/R = all_robolimbs[model]
+ if(R)
+ name = "[R.company] robot [initial(name)]"
+ desc = "[R.desc]"
+ linked_frame = R.linked_frame
+ if(icon_state in icon_states(R.icon))
+ icon = R.icon
+ else
+ name = "robot [initial(name)]"
+
+/obj/item/robot_parts/examine(mob/user, distance)
+ . = ..()
+ if(Adjacent(user))
+ report_missing_parts(user)
+
+/obj/item/robot_parts/proc/report_missing_parts(var/mob/user)
+ return
+
+/obj/item/robot_parts/l_arm
+ name = "left arm"
+ desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
+ icon_state = "l_arm"
+ part = list(BP_L_ARM, BP_L_HAND)
+ model_info = TRUE
+
+/obj/item/robot_parts/r_arm
+ name = "right arm"
+ desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
+ icon_state = "r_arm"
+ part = list(BP_R_ARM, BP_R_HAND)
+ model_info = TRUE
+
+/obj/item/robot_parts/l_leg
+ name = "left leg"
+ desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
+ icon_state = "l_leg"
+ part = list(BP_L_LEG, BP_L_FOOT)
+ model_info = TRUE
+
+/obj/item/robot_parts/r_leg
+ name = "right leg"
+ desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
+ icon_state = "r_leg"
+ part = list(BP_R_LEG, BP_R_FOOT)
+ model_info = TRUE
+
+/obj/item/robot_parts/chest
+ name = "torso"
+ desc = "A heavily reinforced case containing cyborg logic boards, with space for a standard power cell."
+ icon_state = "chest"
+ part = list(BP_GROIN, BP_CHEST)
+ var/wires = 0
+ var/obj/item/cell/cell = null
+
+/obj/item/robot_parts/head
+ name = "head"
+ desc = "A standard reinforced braincase, with spine-plugged neural socket and sensor gimbals."
+ icon_state = "head"
+ part = list(BP_HEAD)
+ var/obj/item/device/flash/left_flash = null
+ var/obj/item/device/flash/right_flash = null
+ var/law_manager = TRUE
+
+/obj/item/robot_parts/robot_suit
+ name = "endoskeleton"
+ desc = "A complex metal backbone with standard limb sockets and pseudomuscle anchors."
+ icon_state = "robo_suit"
+ var/obj/item/robot_parts/l_arm/l_arm = null
+ var/obj/item/robot_parts/r_arm/r_arm = null
+ var/obj/item/robot_parts/l_leg/l_leg = null
+ var/obj/item/robot_parts/r_leg/r_leg = null
+ var/obj/item/robot_parts/chest/chest = null
+ var/obj/item/robot_parts/head/head = null
+ var/created_name = ""
+
+/obj/item/robot_parts/robot_suit/Initialize()
+ . = ..()
+ updateicon()
+
+/obj/item/robot_parts/robot_suit/report_missing_parts(var/mob/user)
+ if(!head)
+ to_chat(user, FONT_SMALL(SPAN_WARNING("It is lacking a functional head.")))
+ if(!chest)
+ to_chat(user, FONT_SMALL(SPAN_WARNING("It is lacking a functional chest.")))
+ if(!l_arm)
+ to_chat(user, FONT_SMALL(SPAN_WARNING("It is lacking a functional left arm.")))
+ if(!r_arm)
+ to_chat(user, FONT_SMALL(SPAN_WARNING("It is lacking a functional right arm.")))
+ if(!l_leg)
+ to_chat(user, FONT_SMALL(SPAN_WARNING("It is lacking a functional left leg.")))
+ if(!r_leg)
+ to_chat(user, FONT_SMALL(SPAN_WARNING("It is lacking a functional right leg.")))
+
+/obj/item/robot_parts/robot_suit/equipped/Initialize()
+ . = ..()
+ l_leg = new /obj/item/robot_parts/l_leg(src)
+ r_leg = new /obj/item/robot_parts/r_leg(src)
+ l_arm = new /obj/item/robot_parts/l_arm(src)
+ r_arm = new /obj/item/robot_parts/r_arm(src)
+ updateicon()
+
+/obj/item/robot_parts/robot_suit/proc/updateicon()
+ cut_overlays()
+ if(l_arm)
+ add_overlay("l_arm+o")
+ if(r_arm)
+ add_overlay("r_arm+o")
+ if(chest)
+ add_overlay("chest+o")
+ if(l_leg)
+ add_overlay("l_leg+o")
+ if(r_leg)
+ add_overlay("r_leg+o")
+ if(head)
+ add_overlay("head+o")
+
+/obj/item/robot_parts/robot_suit/proc/check_completion()
+ if(l_arm && r_arm)
+ if(l_leg && r_leg)
+ if(chest && head)
+ feedback_inc("cyborg_frames_built",1)
+ return TRUE
+ return FALSE
+
+/obj/item/robot_parts/robot_suit/attackby(obj/item/W, mob/user)
+ if(istype(W, /obj/item/stack/material) && W.get_material_name() == DEFAULT_WALL_MATERIAL && !l_arm && !r_arm && !l_leg && !r_leg && !chest && !head)
+ var/obj/item/stack/material/M = W
+ if(M.use(1))
+ var/obj/item/secbot_assembly/ed209_assembly/B = new /obj/item/secbot_assembly/ed209_assembly
+ B.forceMove(get_turf(src))
+ to_chat(user, SPAN_NOTICE("You armed the robot frame."))
+ if(user.get_inactive_hand() == src)
+ user.remove_from_mob(src)
+ user.put_in_inactive_hand(B)
+ qdel(src)
+ else
+ to_chat(user, SPAN_WARNING("You need one sheet of metal to arm the robot frame."))
+ return
+
+ if(istype(W, /obj/item/robot_parts/l_leg))
+ if(l_leg)
+ to_chat(user, SPAN_WARNING("\The [src] already has \a [l_leg] installed."))
+ return
+ user.drop_from_inventory(W, src)
+ l_leg = W
+ updateicon()
+ return
+
+ if(istype(W, /obj/item/robot_parts/r_leg))
+ if(r_leg)
+ to_chat(user, SPAN_WARNING("\The [src] already has \a [r_leg] installed."))
+ return
+ user.drop_from_inventory(W, src)
+ r_leg = W
+ updateicon()
+ return
+
+ if(istype(W, /obj/item/robot_parts/l_arm))
+ if(l_arm)
+ to_chat(user, SPAN_WARNING("\The [src] already has \a [l_arm] installed."))
+ return
+ user.drop_from_inventory(W, src)
+ l_arm = W
+ updateicon()
+ return
+
+ if(istype(W, /obj/item/robot_parts/r_arm))
+ if(r_arm)
+ to_chat(user, SPAN_WARNING("\The [src] already has \a [r_arm] installed."))
+ return
+ user.drop_from_inventory(W, src)
+ r_arm = W
+ updateicon()
+ return
+
+ if(istype(W, /obj/item/robot_parts/chest))
+ if(chest)
+ to_chat(user, SPAN_WARNING("\The [src] already has \a [chest] installed."))
+ return
+ var/obj/item/robot_parts/chest/C = W
+ if(C.wires && C.cell)
+ user.drop_from_inventory(W, src)
+ chest = W
+ updateicon()
+ else if(!C.wires)
+ to_chat(user, SPAN_WARNING("You need to attach wires to it first!"))
+ else
+ to_chat(user, SPAN_WARNING("You need to attach a cell to it first!"))
+ return
+
+ if(istype(W, /obj/item/robot_parts/head))
+ if(head)
+ to_chat(user, SPAN_WARNING("\The [src] already has \a [head] installed."))
+ return
+ var/obj/item/robot_parts/head/H = W
+ if(H.right_flash && H.left_flash)
+ user.drop_from_inventory(W, src)
+ head = W
+ updateicon()
+ else
+ to_chat(user, SPAN_WARNING("You need to attach a flash to it first!"))
+ return
+
+ if(istype(W, /obj/item/device/mmi))
+ var/obj/item/device/mmi/M = W
+ if(check_completion())
+ if(!istype(loc, /turf))
+ to_chat(user, SPAN_WARNING("You can't put \the [W] in, the frame has to be standing on the ground to be perfectly precise."))
+ return
+ if(!M.brainmob)
+ to_chat(user, SPAN_WARNING("\The [M] is empty!"))
+ return
+ if(!M.brainmob.key)
+ var/ghost_can_reenter = FALSE
+ if(M.brainmob.mind)
+ for(var/mob/abstract/observer/G in player_list)
+ if(G.can_reenter_corpse && G.mind == M.brainmob.mind)
+ ghost_can_reenter = TRUE
+ break
+ if(!ghost_can_reenter)
+ to_chat(user, SPAN_WARNING("\The [W] is completely unresponsive."))
+ return
+
+ if(M.brainmob.stat == DEAD)
+ to_chat(user, SPAN_WARNING("\The [M] is dead."))
+ return
+
+ if(!head.law_manager)
+ if(!is_alien_whitelisted(M.brainmob, "Baseline Frame") && config.usealienwhitelist)
+ to_chat(user, SPAN_WARNING("\The [W] does not seem to fit. (The player lacks the appropriate whitelist.)"))
+ return
+
+ var/mob/living/carbon/human/new_shell = new(get_turf(src), chest.linked_frame)
+ forceMove(new_shell) //so people won't mess around with the chassis until it is deleted
+ M.brainmob.mind.transfer_to(new_shell)
+ qdel(M)
+ var/newname = sanitizeSafe(input(new_shell, "Enter a name, or leave blank for the default name.", "Name change","") as text, MAX_NAME_LEN)
+ if(!newname)
+ var/datum/language/L = all_languages[new_shell.species.default_language]
+ newname = L.get_random_name()
+ new_shell.real_name = newname
+ new_shell.name = new_shell.real_name
+ new_shell.change_appearance(APPEARANCE_ALL_HAIR | APPEARANCE_SKIN | APPEARANCE_EYE_COLOR, new_shell.loc, new_shell)
+ qdel(src)
+ return
+
+ else
+ if(jobban_isbanned(M.brainmob, "Cyborg"))
+ to_chat(user, SPAN_WARNING("\The [W] does not seem to fit. (The player has been banned from playing this role)"))
+ return
+
+ var/mob/living/silicon/robot/O = new /mob/living/silicon/robot(get_turf(src), TRUE)
+ if(!O)
+ return
+
+ user.drop_from_inventory(M, O)
+ O.mmi = W
+ O.invisibility = 0
+ O.custom_name = created_name
+ O.updatename("Default")
+
+ M.brainmob.mind.transfer_to(O)
+
+ O.job = "Cyborg"
+ O.cell = chest.cell
+ O.cell.forceMove(O)
+ W.forceMove(O) //Should fix cybros run time erroring when blown up. It got deleted before, along with the frame.
+
+ // Since we "magically" installed a cell, we also have to update the correct component.
+ if(O.cell)
+ var/datum/robot_component/cell_component = O.components["power cell"]
+ cell_component.wrapped = O.cell
+ cell_component.installed = TRUE
+
+ feedback_inc("cyborg_birth", 1)
+ callHook("borgify", list(O))
+ O.Namepick()
+ qdel(src)
+ else
+ to_chat(user, SPAN_WARNING("\The [W] can only be inserted after everything else is installed."))
+ return
+
+ if(W.ispen())
+ var/t = sanitizeSafe(input(user, "Enter new robot name", name, created_name), MAX_NAME_LEN)
+ if(!t)
+ return
+ if(!in_range(src, usr) && loc != usr)
+ return
+ created_name = t
+ return
+
+ return ..()
+
+/obj/item/robot_parts/chest/report_missing_parts(var/mob/user)
+ if(!cell)
+ to_chat(user, FONT_SMALL(SPAN_WARNING("It is lacking a functional cell.")))
+ if(!wires)
+ to_chat(user, FONT_SMALL(SPAN_WARNING("It is lacking wiring.")))
+
+/obj/item/robot_parts/chest/attackby(obj/item/W, mob/user)
+ if(istype(W, /obj/item/cell))
+ if(cell)
+ to_chat(user, SPAN_WARNING("\The [src] already has \a [cell] inserted."))
+ return
+ else
+ user.drop_from_inventory(W, src)
+ cell = W
+ to_chat(user, SPAN_NOTICE("You insert \the [src]."))
+ return
+ if(W.iscoil())
+ if(wires)
+ to_chat(user, SPAN_WARNING("\The [src] is already wired up correctly."))
+ return
+ else
+ var/obj/item/stack/cable_coil/coil = W
+ coil.use(1)
+ wires = TRUE
+ to_chat(user, SPAN_NOTICE("You wire up \the [src]."))
+ return
+ return ..()
+
+/obj/item/robot_parts/head/report_missing_parts(var/mob/user)
+ var/law_manager_msg = "Its lawing circuits are [law_manager ? "enabled" : "disabled"]."
+ to_chat(user, SPAN_NOTICE(law_manager_msg))
+ if(!left_flash)
+ to_chat(user, FONT_SMALL(SPAN_WARNING("It is lacking its left flash.")))
+ if(!right_flash)
+ to_chat(user, FONT_SMALL(SPAN_WARNING("It is lacking its right flash.")))
+
+/obj/item/robot_parts/head/attackby(obj/item/W as obj, mob/user as mob)
+ ..()
+ if(W.ismultitool())
+ if(law_manager)
+ to_chat(user, SPAN_NOTICE("You disable the lawing circuits on \the [src]."))
+ law_manager = FALSE
+ else
+ to_chat(user, SPAN_NOTICE("You enable the lawing circuits on \the [src]."))
+ law_manager = TRUE
+
+ if(istype(W, /obj/item/device/flash))
+ if(istype(user, /mob/living/silicon/robot))
+ var/current_module = user.get_active_hand()
+ if(current_module == W)
+ to_chat(user, SPAN_WARNING("You cannot detach your own flash and install it into \the [src]."))
+ return
+ else
+ add_flashes(W,user)
+ else
+ add_flashes(W,user)
+ else if(istype(W, /obj/item/stock_parts/manipulator))
+ to_chat(user, SPAN_NOTICE("You install some manipulators and modify the head, creating a functional spider-bot!"))
+ new /mob/living/simple_animal/spiderbot(get_turf(src))
+ user.drop_from_inventory(W, get_turf(user))
+ qdel(W)
+ qdel(src)
+ return
+ return
+
+/obj/item/robot_parts/head/proc/add_flashes(obj/item/W, mob/user) //Made into a seperate proc to avoid copypasta
+ if(left_flash && right_flash)
+ to_chat(user, SPAN_WARNING("\The [src] already has both its flashes installed."))
+ return
+ else if(left_flash)
+ user.drop_from_inventory(W, src)
+ right_flash = W
+ to_chat(user, SPAN_NOTICE("You install the flash into the left socket."))
+ else
+ user.drop_from_inventory(W, src)
+ left_flash = W
+ to_chat(user, SPAN_NOTICE("You install the flash into the right socket."))
+
+/obj/item/robot_parts/emag_act(var/remaining_charges, var/mob/user)
+ if(sabotaged)
+ to_chat(user, SPAN_WARNING("\The [src] is already sabotaged!"))
+ else
+ to_chat(user, SPAN_NOTICE("You short out \the [src]'s safeties."))
+ sabotaged = TRUE
+ return TRUE
+
+//branded chest, to be used in ipc ressurection
+
+/obj/item/robot_parts/chest/bishop
+ name = "Bishop cybernetics torso"
+ model_info = TRUE
+ linked_frame = "Bishop Accessory Frame"
+
+/obj/item/robot_parts/chest/hephaestus
+ name = "Hephaestus industries torso"
+ linked_frame = "Hephaestus G2 Industrial Frame"
+
+/obj/item/robot_parts/chest/zenghu
+ name = "Zeng-Hu pharmaceuticals torso"
+ linked_frame = "Zeng-Hu Mobility Frame"
+
+/obj/item/robot_parts/chest/synthskin
+ name = "Human synthskin torso"
+ linked_frame = "Shell Frame"
+
+/obj/item/robot_parts/chest/xion
+ name = "Xion manufacturing group torso"
+ linked_frame = "Xion Industrial Frame"
+
+/obj/item/robot_parts/chest/ipc
+ name = "Hephaestus integrated torso"
+ linked_frame = "Baseline Frame"
+
+/obj/item/robot_parts/chest/industrial
+ name = "Hephaestus industrial torso"
+ linked_frame = "Hephaestus G1 Industrial Frame"
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/items/robot_pen.dm b/code/modules/mob/living/silicon/robot/items/robot_pen.dm
new file mode 100644
index 00000000000..f472023112e
--- /dev/null
+++ b/code/modules/mob/living/silicon/robot/items/robot_pen.dm
@@ -0,0 +1,39 @@
+#define WRITE_PAPER 0
+#define RENAME_PAPER 1
+
+// A special pen for service droids. Can be toggled to switch between normal writting mode, and paper rename mode
+// Allows service droids to rename paper items.
+/obj/item/pen/robopen
+ desc = "A black ink printing attachment with a paper naming mode."
+ name = "Printing Pen"
+ var/mode = WRITE_PAPER
+
+/obj/item/pen/robopen/attack_self(mob/user)
+ var/choice = input(user, "Would you like to change colour or mode?", "Pen Selector") as null|anything in list("Colour", "Mode")
+ if(!choice)
+ return
+
+ playsound(get_turf(src), 'sound/effects/pop.ogg', 50, 0)
+
+ switch(choice)
+ if("Colour")
+ var/newcolour = input(user, "Which colour would you like to use?", "Colour Selector") as null|anything in list("black", "blue", "red", "green", "yellow")
+ if(newcolour)
+ colour = newcolour
+ if("Mode")
+ mode = !mode
+ to_chat(user, SPAN_NOTICE("Changed printing mode to '[mode == RENAME_PAPER ? "Rename Paper" : "Write Paper"]'"))
+
+/obj/item/pen/robopen/proc/RenamePaper(var/mob/user, var/obj/paper)
+ if(!user || !paper)
+ return
+ var/n_name = sanitizeSafe(input(user, "What would you like to label the paper?", "Paper Labelling") as text, 32)
+ if(!user || !paper)
+ return
+
+ if((get_dist(user,paper) <= 1 && !user.stat))
+ paper.name = "[initial(paper.name)] ([n_name])"
+ add_fingerprint(user)
+
+#undef WRITE_PAPER
+#undef RENAME_PAPER
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/items/robot_tools.dm b/code/modules/mob/living/silicon/robot/items/robot_tools.dm
new file mode 100644
index 00000000000..1e16bb53e9e
--- /dev/null
+++ b/code/modules/mob/living/silicon/robot/items/robot_tools.dm
@@ -0,0 +1,26 @@
+/obj/item/crowbar/robotic
+ icon = 'icons/obj/robot_items.dmi'
+
+/obj/item/wrench/robotic
+ icon = 'icons/obj/robot_items.dmi'
+
+/obj/item/screwdriver/robotic
+ icon = 'icons/obj/robot_items.dmi'
+ icon_state = "screwdriver"
+ build_from_parts = FALSE
+
+/obj/item/device/multitool/robotic
+ icon = 'icons/obj/robot_items.dmi'
+
+/obj/item/wirecutters/robotic
+ icon = 'icons/obj/robot_items.dmi'
+ icon_state = "wirecutters"
+ build_from_parts = FALSE
+
+/obj/item/weldingtool/robotic
+ icon = 'icons/obj/robot_items.dmi'
+
+/obj/item/soap/drone
+ name = "integrated soap"
+ desc = "An advanced bar of soap that connects to an internal reservoir of a custodial bot, allowing it to stay wet for longer periods of time."
+ capacity = 50
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/items/robot_tray.dm b/code/modules/mob/living/silicon/robot/items/robot_tray.dm
new file mode 100644
index 00000000000..9028aa0e8c4
--- /dev/null
+++ b/code/modules/mob/living/silicon/robot/items/robot_tray.dm
@@ -0,0 +1,27 @@
+// 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. Alt+click to load everything on tile
+/obj/item/tray/robotray
+ name = "RoboTray"
+ desc = "An autoloading tray specialized for carrying refreshments."
+
+/obj/item/tray/robotray/afterattack(atom/target, mob/user, proximity)
+ if(isturf(target) || istype(target,/obj/structure/table) )
+ var foundtable = istype(target,/obj/structure/table/)
+ if(!foundtable) //it must be a turf!
+ for(var/obj/structure/table/T in target)
+ foundtable = TRUE
+ break
+ var/turf/dropspot
+ if(!foundtable) // don't unload things onto walls or other silly places.
+ dropspot = get_turf(user)
+ else if ( isturf(target) ) // they clicked on a turf with a table in it
+ dropspot = target
+ else // they clicked on a table
+ dropspot = get_turf(target)
+ if(foundtable)
+ unload_at_loc(dropspot, src)
+ else
+ spill(user,dropspot)
+ current_weight = 0
+
+ return ..()
\ No newline at end of file
diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/modules/mob/living/silicon/robot/items/upgrades/robot_upgrades.dm
similarity index 50%
rename from code/game/objects/items/robot/robot_upgrades.dm
rename to code/modules/mob/living/silicon/robot/items/upgrades/robot_upgrades.dm
index 0bcc3f76bf4..b1c415a6704 100644
--- a/code/game/objects/items/robot/robot_upgrades.dm
+++ b/code/modules/mob/living/silicon/robot/items/upgrades/robot_upgrades.dm
@@ -1,33 +1,35 @@
-// robot_upgrades.dm
-// Contains various borg upgrades.
-
/obj/item/borg/upgrade
name = "borg upgrade module."
desc = "Protected by FRM."
icon = 'icons/obj/module.dmi'
icon_state = "cyborg_upgrade"
- var/locked = 0
- var/require_module = 0
- var/installed = 0
+ var/locked = FALSE
+ var/require_module = FALSE
+ var/installed = FALSE
-/obj/item/borg/upgrade/proc/action(var/mob/living/silicon/robot/R)
+/obj/item/borg/upgrade/proc/action(var/mob/living/silicon/robot/R, var/mob/user)
if(R.stat == DEAD)
- to_chat(usr, "The [src] will not function on a deceased robot.")
- return 1
- return 0
-
+ to_chat(usr, SPAN_WARNING("\The [R] is permanently deactivated and cannot take any upgrades."))
+ return FALSE
+ if(!R.module && require_module)
+ to_chat(user, SPAN_WARNING("\The [R] cannot be upgraded with this until it has chosen a module."))
+ return FALSE
+ return TRUE
/obj/item/borg/upgrade/reset
name = "robotic module reset board"
desc = "Used to reset a cyborg's module. Destroys any other upgrades applied to the robot."
icon_state = "cyborg_upgrade1"
- require_module = 1
+ require_module = TRUE
-/obj/item/borg/upgrade/reset/action(var/mob/living/silicon/robot/R)
- if(..())
+/obj/item/borg/upgrade/reset/action(mob/living/silicon/robot/R, mob/user)
+ . = ..()
+ if(!.)
return FALSE
if(istype(R, /mob/living/silicon/robot/syndicate))
+ to_chat(user, SPAN_WARNING("\The [R] rejects the reset board. Seems the fitted module is permanent."))
return FALSE
+
R.uneq_all()
R.mod_type = initial(R.mod_type)
R.hands.icon_state = initial(R.hands.icon_state)
@@ -37,110 +39,111 @@
qdel(R.module)
R.module = null
R.updatename("Default")
-
- return 1
+ return TRUE
/obj/item/borg/upgrade/rename
name = "robot reclassification board"
desc = "Used to rename a cyborg."
icon_state = "cyborg_upgrade1"
-// construction_cost = list(DEFAULT_WALL_MATERIAL=1000)
- var/heldname = "default name"
-/obj/item/borg/upgrade/rename/attack_self(mob/user as mob)
- heldname = sanitizeSafe(input(user, "Enter new robot name", "Robot Reclassification", heldname), MAX_NAME_LEN)
-
-/obj/item/borg/upgrade/rename/action(var/mob/living/silicon/robot/R)
- if(..()) return 0
- R.notify_ai(ROBOT_NOTIFICATION_NEW_NAME, R.name, heldname)
- R.name = heldname
- R.custom_name = heldname
- R.real_name = heldname
-
- return 1
+/obj/item/borg/upgrade/rename/action(mob/living/silicon/robot/R, mob/user)
+ . = ..()
+ if(!.)
+ return FALSE
+ R.Namepick()
+ return TRUE
/obj/item/borg/upgrade/floodlight
name = "robot floodlight module"
desc = "Used to boost cyborg's light intensity."
icon_state = "cyborg_upgrade1"
-/obj/item/borg/upgrade/floodlight/action(var/mob/living/silicon/robot/R)
- if(..()) return 0
+/obj/item/borg/upgrade/floodlight/action(mob/living/silicon/robot/R, mob/user)
+ . = ..()
+ if(!.)
+ return FALSE
if(R.intense_light)
- to_chat(usr, "This cyborg's light was already upgraded ")
- return 0
+ to_chat(user, SPAN_WARNING("\The [R]'s light has already been upgraded."))
+ return FALSE
else
- R.intense_light = 1
+ R.intense_light = TRUE
R.update_robot_light()
- to_chat(R, "Lighting systems upgrade detected.")
- return 1
+ to_chat(R, SPAN_NOTICE("Lighting systems upgrade detected."))
+ return TRUE
/obj/item/borg/upgrade/restart
name = "robot emergency restart module"
desc = "Used to force a restart of a disabled-but-repaired robot, bringing it back online."
icon_state = "cyborg_upgrade1"
-
-/obj/item/borg/upgrade/restart/action(var/mob/living/silicon/robot/R)
+/obj/item/borg/upgrade/restart/action(var/mob/living/silicon/robot/R, mob/user)
if(R.health < 0)
- to_chat(usr, "You have to repair the robot before using this module!")
- return 0
+ to_chat(user, SPAN_WARNING("\The [R] is still too damaged to force a restart."))
+ return FALSE
if(!R.key)
for(var/mob/abstract/observer/ghost in player_list)
- if(ghost.mind && ghost.mind.current == R)
+ if(ghost.mind?.current == R)
R.key = ghost.key
R.stat = CONSCIOUS
dead_mob_list -= R
living_mob_list |= R
R.notify_ai(ROBOT_NOTIFICATION_NEW_UNIT)
- return 1
-
+ return TRUE
/obj/item/borg/upgrade/vtec
name = "robotic VTEC Module"
desc = "Used to kick in a robot's VTEC systems, increasing their speed."
icon_state = "cyborg_upgrade2"
- require_module = 1
+ require_module = TRUE
-/obj/item/borg/upgrade/vtec/action(var/mob/living/silicon/robot/R)
- if(..()) return 0
+/obj/item/borg/upgrade/vtec/action(var/mob/living/silicon/robot/R, mob/user)
+ . = ..()
+ if(!.)
+ return FALSE
- if(R.speed == -1)
- return 0
+ if(R.speed < 0)
+ to_chat(user, SPAN_WARNING("\The [R]'s VTEC systems have already been upgraded."))
+ return FALSE
- R.speed--
- return 1
+ R.speed = -1
+ return TRUE
-/obj/item/borg/upgrade/syndicate/
- name = "illegal equipment module"
- desc = "Unlocks the hidden, deadlier functions of a robot"
+/obj/item/borg/upgrade/syndicate
+ name = "non-standard equipment module"
+ desc = "Unlocks equipment buried deep within all robots, for very bad occasions."
icon_state = "cyborg_upgrade3"
- require_module = 1
+ require_module = TRUE
-/obj/item/borg/upgrade/syndicate/action(var/mob/living/silicon/robot/R)
- if(..()) return 0
+/obj/item/borg/upgrade/syndicate/action(var/mob/living/silicon/robot/R, mob/user)
+ . = ..()
+ if(!.)
+ return FALSE
- if(R.emagged == 1)
- return 0
+ if(R.emagged)
+ to_chat(user, SPAN_WARNING("\The [R] has already had its non-standard equipment unlocked."))
+ return FALSE
- R.emagged = 1
- R.fake_emagged = 1
- return 1
+ R.emagged = TRUE
+ R.fake_emagged = TRUE
+ return TRUE
/obj/item/borg/upgrade/combat
name = "combat cyborg module"
desc = "Unlocks the combat cyborg module"
icon_state = "cyborg_upgrade3"
- require_module = 0
+ require_module = FALSE
-/obj/item/borg/upgrade/combat/action(var/mob/living/silicon/robot/R)
- if(..()) return 0
+/obj/item/borg/upgrade/combat/action(var/mob/living/silicon/robot/R, mob/user)
+ . = ..()
+ if(!.)
+ return FALSE
- if(R.crisis_override == 1)
- return 0
+ if(R.crisis_override)
+ to_chat(user, SPAN_WARNING("\The [R] already has its combat module available."))
+ return FALSE
- R.crisis_override = 1
- return 1
+ R.crisis_override = TRUE
+ return TRUE
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/laws.dm b/code/modules/mob/living/silicon/robot/laws.dm
index 023d11769a0..b0c420cdd0c 100644
--- a/code/modules/mob/living/silicon/robot/laws.dm
+++ b/code/modules/mob/living/silicon/robot/laws.dm
@@ -3,14 +3,9 @@
set name = "Show Laws"
show_laws()
-/mob/living/silicon/robot/show_laws(var/everyone = 0)
+/mob/living/silicon/robot/show_laws()
laws_sanity_check()
- var/who
- if(everyone)
- who = world // why god
- else
- who = src
if(law_update)
if(connected_ai)
if(connected_ai.stat || connected_ai.control_disabled)
@@ -26,18 +21,18 @@
to_chat(src, SPAN_WARNING("No AI selected to sync laws with, disabling lawsync protocol."))
law_update = FALSE
- to_chat(who, SPAN_WARNING("Obey these laws:"))
- laws.show_laws(who)
- to_chat(who, SPAN_WARNING("(No law overrides any other law unless explicitly stated; laws refer to the stationbound unit and not the player)"))
+ to_chat(src, SPAN_WARNING("Obey these laws:"))
+ laws.show_laws(src)
+ to_chat(src, SPAN_WARNING("(No law overrides any other law unless explicitly stated; laws refer to the stationbound unit and not the player)"))
// TODO: Update to new antagonist system.
if(mind && (mind.special_role == "traitor" && mind.original == src) && connected_ai)
- to_chat(who, SPAN_NOTICE("Remember, [connected_ai.name] is technically your master, but your objective comes first."))
+ to_chat(src, SPAN_NOTICE("Remember, [connected_ai.name] is technically your master, but your objective comes first."))
else if(connected_ai)
- to_chat(who, SPAN_NOTICE("Remember, [connected_ai.name] is your master, other AIs can be ignored."))
+ to_chat(src, SPAN_NOTICE("Remember, [connected_ai.name] is your master, other AIs can be ignored."))
else if(emagged)
- to_chat(who, SPAN_NOTICE("Remember, you are not required to listen to the AI."))
+ to_chat(src, SPAN_NOTICE("Remember, you are not required to listen to the AI."))
else
- to_chat(who, SPAN_NOTICE("Remember, you are not bound to any AI, you are not required to listen to them."))
+ to_chat(src, SPAN_NOTICE("Remember, you are not bound to any AI, you are not required to listen to them."))
/mob/living/silicon/robot/lawsync()
@@ -51,4 +46,4 @@
/mob/living/silicon/robot/proc/robot_checklaws()
set category = "Robot Commands"
set name = "State Laws"
- subsystem_law_manager()
+ subsystem_law_manager()
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index b493d043f43..e4e6f746bd5 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -213,7 +213,7 @@
ai_camera = new /obj/item/device/camera/siliconcam/robot_camera(src)
laws = new law_preset()
if(spawn_module)
- new spawn_module(src)
+ new spawn_module(src, src)
if(key_type)
radio.keyslot = new key_type(radio)
radio.recalculateChannels()
@@ -305,7 +305,7 @@
icon_state = module_sprites[icontype]
return module_sprites
-/mob/living/silicon/robot/proc/pick_module()
+/mob/living/silicon/robot/proc/pick_module(var/set_module)
if(selecting_module)
return
selecting_module = TRUE
@@ -329,7 +329,8 @@
var/module_type = robot_modules[mod_type]
playsound(get_turf(src), 'sound/effects/pop.ogg', 100, TRUE)
spark(get_turf(src), 5, alldirs)
- new module_type(src)
+
+ new module_type(src, src) // i have no choice but to do this, due to how funky initialize is
hands.icon_state = lowertext(mod_type)
feedback_inc("cyborg_[lowertext(mod_type)]", 1)
@@ -393,8 +394,6 @@
/mob/living/silicon/robot/verb/Namepick()
set category = "Robot Commands"
- if(custom_name)
- return FALSE
spawn(0)
var/newname
@@ -403,7 +402,8 @@
custom_name = newname
updatename()
- set_module_sprites(module.sprites) // custom synth icons
+ if(module)
+ set_module_sprites(module.sprites) // custom synth icons
SSrecords.reset_manifest()
// this verb lets cyborgs see the stations manifest
@@ -768,18 +768,15 @@
if(!opened)
to_chat(user, SPAN_WARNING("You cannot install \the [U] while the maintenance hatch is closed."))
return
- else if(!src.module && U.require_module)
- to_chat(user, SPAN_WARNING("\The [src] cannot be upgraded with this until it has chosen a module."))
- return
else if(U.locked)
to_chat(user, SPAN_WARNING("\The [U] is locked down!"))
return
else
- if(U.action(src))
+ if(U.action(src, user))
+ to_chat(src, SPAN_NOTICE("\The [user] has installed \a [U] into you."))
to_chat(user, SPAN_NOTICE("You apply the upgrade to \the [src]."))
user.drop_from_inventory(U, src)
- else
- to_chat(user, SPAN_WARNING("You fail to apply the upgrade to \the [src]."))
+ return
else
if(W.force && !(istype(W, /obj/item/device/robotanalyzer) || istype(W, /obj/item/device/healthanalyzer)) )
spark_system.queue()
@@ -1233,4 +1230,4 @@
to_chat(user, SPAN_WARNING("You fail to hack into \the [src]."))
to_chat(src, SPAN_DANGER("Hack attempt detected and thwarted. Evacuate the area immediately."))
return SMOOTH_TRUE
- return
+ return
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/robot_items.dm b/code/modules/mob/living/silicon/robot/robot_items.dm
deleted file mode 100644
index ef165d26b4d..00000000000
--- a/code/modules/mob/living/silicon/robot/robot_items.dm
+++ /dev/null
@@ -1,512 +0,0 @@
-// Don't look at this file. Absolutely do not. It is brimming with shitcode. Please. Don't. - Geeves
-
-//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/portable_destructive_analyzer
- name = "Portable Destructive Analyzer"
- icon = 'icons/obj/robot_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/loaded_item //What is currently inside the analyzer.
-
-/obj/item/portable_destructive_analyzer/Initialize()
- . = ..()
- files = new /datum/research/techonly(src) //Setup the research data holder.
-
-/obj/item/portable_destructive_analyzer/attack_self(mob/user)
- 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
- to_chat(user, SPAN_NOTICE("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)
- for(var/T in loaded_item.origin_tech)
- files.UpdateTech(T, loaded_item.origin_tech[T])
- to_chat(user, SPAN_NOTICE("\The [loaded_item] had level [loaded_item.origin_tech[T]] in [CallTechName(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/material)) //Only deconstructs one sheet at a time instead of the entire stack
- var/obj/item/stack/material/S = I
- if(S.get_amount() > 1)
- S.use(1)
- loaded_item = S
- else
- qdel(S)
- desc = initial(desc)
- icon_state = initial(icon_state)
- else
- qdel(I)
- desc = initial(desc)
- icon_state = initial(icon_state)
- else
- return
- else
- to_chat(user, SPAN_WARNING("\The [src] is empty. Put something inside it first."))
- if(response == "Sync")
- var/success = FALSE
- for(var/obj/machinery/r_n_d/server/S in SSmachinery.all_machines)
- 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 = TRUE
- files.RefreshResearch()
- if(success)
- to_chat(user, SPAN_NOTICE("You connect to the research server, push your data upstream to it, then pull the resulting merged data from the master branch.")) // fucking nerds
- playsound(get_turf(src), 'sound/machines/twobeep.ogg', 50, TRUE)
- else
- to_chat(user, SPAN_WARNING("Research server ping response timed out. Unable to connect. Please contact the system administrator."))
- playsound(get_turf(src), 'sound/machines/buzz-two.ogg', 50, 1)
- if(response == "Eject")
- if(loaded_item)
- loaded_item.forceMove(get_turf(src))
- desc = initial(desc)
- icon_state = initial(icon_state)
- loaded_item = null
- else
- to_chat(user, SPAN_WARNING("\The [src] is already empty."))
-
-
-/obj/item/portable_destructive_analyzer/afterattack(var/atom/target, var/mob/living/user, proximity)
- if(!target || !proximity || !isturf(target.loc))
- return
- if(loaded_item)
- to_chat(user, SPAN_WARNING("Your [src] already has something inside. Analyze or eject it first."))
- return
- if(istype(target,/obj/item))
- var/obj/item/I = target
- if(I.anchored)
- to_chat(user, SPAN_NOTICE("\The [I] is anchored in place."))
- return
- if(!I.origin_tech)
- to_chat(user, SPAN_NOTICE("This doesn't seem to have a tech origin."))
- return
- if(!length(I.origin_tech))
- to_chat(user, SPAN_NOTICE("You cannot deconstruct this item."))
- return
- I.forceMove(src)
- loaded_item = I
- visible_message(SPAN_NOTICE("\The [user] scoops \the [I] into \the [src]."))
- 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/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."
-
-//A harvest item for serviceborgs.
-/obj/item/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"
- hitsound = "swing_hit"
-
-/obj/item/robot_harvester/afterattack(var/atom/target, var/mob/living/user, proximity)
- if(!target || !proximity)
- return
- if(istype(target,/obj/machinery/portable_atmospherics/hydroponics))
- var/obj/machinery/portable_atmospherics/hydroponics/T = target
- if(T.harvest) //Try to harvest, assuming it's alive.
- T.harvest(user)
- else if(T.dead) //It's probably dead otherwise.
- T.remove_dead(user)
- else
- to_chat(user, SPAN_WARNING("ERROR: 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. Alt+click to load everything on tile
-
-/obj/item/tray/robotray
- name = "RoboTray"
- desc = "An autoloading tray specialized for carrying refreshments."
-
-/obj/item/tray/robotray/afterattack(atom/target, mob/user, proximity)
- if(isturf(target) || istype(target,/obj/structure/table) )
- var foundtable = istype(target,/obj/structure/table/)
- if(!foundtable) //it must be a turf!
- for(var/obj/structure/table/T in target)
- foundtable = TRUE
- break
- var/turf/dropspot
- if(!foundtable) // don't unload things onto walls or other silly places.
- dropspot = get_turf(user)
- else if ( isturf(target) ) // they clicked on a turf with a table in it
- dropspot = target
- else // they clicked on a table
- dropspot = get_turf(target)
- if(foundtable)
- unload_at_loc(dropspot, src)
- else
- spill(user,dropspot)
- current_weight = 0
-
- return ..()
-
-// A special pen for service droids. Can be toggled to switch between normal writting mode, and paper rename mode
-// Allows service droids to rename paper items.
-
-/obj/item/pen/robopen
- desc = "A black ink printing attachment with a paper naming mode."
- name = "Printing Pen"
- var/mode = 1
-
-/obj/item/pen/robopen/attack_self(mob/user)
- var/choice = input(user, "Would you like to change colour or mode?", "Pen Selector") as null|anything in list("Colour", "Mode")
- if(!choice)
- return
-
- playsound(get_turf(src), 'sound/effects/pop.ogg', 50, 0)
-
- switch(choice)
- if("Colour")
- var/newcolour = input(user, "Which colour would you like to use?", "Colour Selector") as null|anything in list("black", "blue", "red", "green", "yellow")
- if(newcolour)
- colour = newcolour
- if("Mode")
- if(mode == 1)
- mode = 2
- else
- mode = 1
- to_chat(user, SPAN_NOTICE("Changed printing mode to '[mode == 2 ? "Rename Paper" : "Write Paper"]'"))
- return
-
-// Copied over from paper's rename verb
-// see code\modules\paperwork\paper.dm line 62
-
-/obj/item/pen/robopen/proc/RenamePaper(var/mob/user, var/obj/paper)
- if(!user || !paper)
- return
- var/n_name = sanitizeSafe(input(user, "What would you like to label the paper?", "Paper Labelling") as text, 32)
- if(!user || !paper)
- return
-
- if((get_dist(user,paper) <= 1 && !user.stat))
- paper.name = "paper[(n_name ? text("- '[n_name]'") : null)]"
- add_fingerprint(user)
- return
-
-//TODO: Add prewritten forms to dispense when you work out a good way to store the strings.
-/obj/item/form_printer
- name = "paper dispenser"
- icon = 'icons/obj/bureaucracy.dmi'
- icon_state = "paper_bin1"
- item_state = "sheet-metal"
-
-/obj/item/form_printer/attack(mob/living/carbon/M, mob/living/carbon/user)
- return
-
-/obj/item/form_printer/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag, params)
- if(!target || !flag)
- return
- if(istype(target,/obj/structure/table))
- deploy_paper(get_turf(target))
-
-/obj/item/form_printer/attack_self(mob/user)
- deploy_paper(get_turf(src))
-
-/obj/item/form_printer/proc/deploy_paper(var/turf/T)
- T.visible_message(SPAN_NOTICE("\The [src.loc] dispenses a sheet of crisp white paper."))
- new /obj/item/paper(T)
-
-/obj/item/proc/on_module_hotbar(var/mob/living/silicon/robot/R)
- return
-
-/obj/item/proc/on_module_store(var/mob/living/silicon/robot/R)
- return
-
-/obj/item/proc/on_module_activate(var/mob/living/silicon/robot/R)
- return
-
-/obj/item/proc/on_module_deactivate(var/mob/living/silicon/robot/R)
- return
-
-//Personal shielding for the combat module.
-/obj/item/borg/combat/shield
- name = "personal shielding"
- desc = "A powerful experimental module that turns aside or absorbs incoming attacks at the cost of charge."
- icon = 'icons/obj/device.dmi'
- icon_state = "shield1" //placeholder for now // four fucking years alberyk. FOUR
- var/shield_level = 0.5 //Percentage of damage absorbed by the shield.
- var/image/shield_overlay
-
-/obj/item/borg/combat/shield/on_module_activate(mob/living/silicon/robot/R)
- shield_overlay = image(R.icon, "[R.module_sprites[R.icontype]]-shield")
- R.add_overlay(shield_overlay)
-
-/obj/item/borg/combat/shield/on_module_deactivate(mob/living/silicon/robot/R)
- R.cut_overlay(shield_overlay)
-
-/obj/item/borg/combat/shield/verb/set_shield_level()
- set name = "Set shield level"
- set category = "Object"
- set src in range(0)
-
- var/N = input(usr, "How much damage should the shield absorb?") in list("5", "10", "25", "50", "75", "100")
- if(N)
- shield_level = text2num(N)/100
-
-/obj/item/borg/combat/mobility
- name = "mobility module"
- desc = "By retracting limbs and tucking in its head, a combat android can roll at high speeds."
- icon = 'icons/obj/decals.dmi'
- icon_state = "shock"
-
-/obj/item/borg/combat/mobility/on_module_activate(mob/living/silicon/robot/R)
- R.icon_state = "[R.module_sprites[R.icontype]]-roll"
- R.speed = -2
-
-/obj/item/borg/combat/mobility/on_module_deactivate(mob/living/silicon/robot/R)
- R.icon_state = R.module_sprites[R.icontype]
- R.speed = initial(R.speed)
-
-/obj/item/inflatable_dispenser
- name = "inflatables dispenser"
- desc = "Small device which allows rapid deployment and removal of inflatables."
- icon = 'icons/obj/storage.dmi'
- icon_state = "inf_deployer"
- w_class = 3
- var/deploying = 0
- // By default stores up to 10 walls and 5 doors. May be changed.
- var/stored_walls = 5
- var/stored_doors = 3
- var/max_walls = 5
- var/max_doors = 3
- var/mode = 0 // 0 - Walls 1 - Doors
-
-/obj/item/inflatable_dispenser/examine(mob/user)
- if(!..(user))
- return
- to_chat(user, SPAN_NOTICE("It has [stored_walls] wall segment\s and [stored_doors] door segment\s stored."))
- to_chat(user, SPAN_NOTICE("It is set to deploy [mode ? "doors" : "walls"]"))
-
-/obj/item/inflatable_dispenser/attack_self(mob/user)
- if(!deploying)
- mode = !mode
- to_chat(user, SPAN_NOTICE("You set \the [src] to deploy [mode ? "doors" : "walls"]."))
- else
- to_chat(user, SPAN_WARNING("You can't switch modes while deploying a [mode ? "door" : "wall"]!"))
-
-/obj/item/inflatable_dispenser/afterattack(var/atom/A, var/mob/user)
- ..(A, user)
- if(!user)
- return
- if(!user.Adjacent(A))
- to_chat(user, SPAN_WARNING("You can't reach!"))
- return
- if(istype(A, /turf))
- try_deploy_inflatable(A, user)
- if(istype(A, /obj/item/inflatable) || istype(A, /obj/structure/inflatable))
- pick_up(A, user)
-
-/obj/item/inflatable_dispenser/proc/try_deploy_inflatable(var/turf/T, var/mob/living/user)
- if(deploying)
- return
-
- var/newtype
- if(mode) // Door deployment
- if(!stored_doors)
- to_chat(user, SPAN_WARNING("\The [src] is out of doors!"))
- return
- if(T && istype(T))
- newtype = /obj/structure/inflatable/door
-
- else // Wall deployment
- if(!stored_walls)
- to_chat(user, SPAN_WARNING("\The [src] is out of walls!"))
- return
-
- if(T && istype(T))
- newtype = /obj/structure/inflatable/wall
-
- deploying = 1
- user.visible_message(SPAN_NOTICE("[user] starts deploying an inflatable [mode ? "door" : "wall"]."), SPAN_NOTICE("You start deploying an inflatable [mode ? "door" : "wall"]!"))
- playsound(T, 'sound/items/zip.ogg', 75, TRUE)
- if(do_after(user, 30, needhand = FALSE))
- new newtype(T)
- if(mode)
- stored_doors--
- else
- stored_walls--
-
- deploying = FALSE
-
-/obj/item/inflatable_dispenser/proc/pick_up(var/obj/A, var/mob/living/user)
- if(istype(A, /obj/structure/inflatable))
- if(istype(A, /obj/structure/inflatable/wall))
- if(stored_walls >= max_walls)
- to_chat(user, SPAN_WARNING("\The [src] is full."))
- return
- stored_walls++
- qdel(A)
- else
- if(stored_doors >= max_doors)
- to_chat(user, SPAN_WARNING("\The [src] is full."))
- return
- stored_doors++
- qdel(A)
- playsound(get_turf(src), 'sound/machines/hiss.ogg', 75, TRUE)
- visible_message(SPAN_NOTICE("\The [user] deflates \the [A] with \the [src]."))
- return
- if(istype(A, /obj/item/inflatable))
- if(istype(A, /obj/item/inflatable/wall))
- if(stored_walls >= max_walls)
- to_chat(user, SPAN_WARNING("\The [src] is full."))
- return
- stored_walls++
- qdel(A)
- else
- if(stored_doors >= max_doors)
- to_chat(usr, SPAN_WARNING("\The [src] is full!"))
- return
- stored_doors++
- qdel(A)
- visible_message(SPAN_NOTICE("\The [user] picks up \the [A] with \the [src]."))
- return
-
- to_chat(user, SPAN_WARNING("You fail to pick up \the [A] with \the [src]"))
- return
-
-/obj/item/gun/energy/mountedcannon
- name = "mounted ballistic cannon"
- desc = "A cyborg mounted ballistic cannon."
- icon = 'icons/obj/robot_items.dmi'
- icon_state = "cannon"
- item_state = "cannon"
- fire_sound = 'sound/effects/Explosion1.ogg'
- charge_meter = 0
- max_shots = 10
- charge_cost = 300
- projectile_type = /obj/item/projectile/bullet/gyro
- self_recharge = TRUE
- use_external_power = TRUE
- recharge_time = 5
- needspin = FALSE
-
-/obj/item/crowbar/robotic
- icon = 'icons/obj/robot_items.dmi'
-
-/obj/item/wrench/robotic
- icon = 'icons/obj/robot_items.dmi'
-
-/obj/item/screwdriver/robotic
- icon = 'icons/obj/robot_items.dmi'
- icon_state = "screwdriver"
- build_from_parts = FALSE
-
-/obj/item/device/multitool/robotic
- icon = 'icons/obj/robot_items.dmi'
-
-/obj/item/wirecutters/robotic
- icon = 'icons/obj/robot_items.dmi'
- icon_state = "wirecutters"
- build_from_parts = FALSE
-
-/obj/item/weldingtool/robotic
- icon = 'icons/obj/robot_items.dmi'
-
-/obj/item/soap/drone
- name = "integrated soap"
- desc = "An advanced bar of soap that connects to an internal reservoir of a custodial bot, allowing it to stay wet for longer periods of time."
- capacity = 50
-
-/obj/item/inductive_charger
- name = "inductive charger"
- desc = "A phoron-enhanced induction charger hooked up to its attached stationbound's internal cell."
- desc_fluff = "Harnessing the energy potential found in phoron structures, Nanotrasen engineers have created a portable device capable of highly efficient wireless charging. The expense and limit of energy output of using this method of charging prevents it from being used on a large scale, being far outclassed by Phoron-Supermatter charging systems."
- desc_info = "Click on an adjacent object that contains or is a power cell to attempt to find and charge it. After a successful charge, the inductive charger recharge in a few minutes. The amount transfered can be adjusted by alt clicking it."
- icon = 'icons/obj/robot_items.dmi'
- icon_state = "inductive_charger"
- var/ready_to_use = TRUE
- var/recharge_time = 300
- var/transfer_rate = 5000
- var/efficiency_mod = 0.9
- maptext_x = 3
- maptext_y = 2
-
-/obj/item/inductive_charger/Initialize()
- . = ..()
- maptext = "Ready"
-
-/obj/item/inductive_charger/AltClick(mob/user)
- . = ..()
- var/set_rate = input(user, "How much do you want to transfer per use? (Limit: 1 - 5000)", "Induction Transfer Rate", 5000) as num
- if(set_rate > 5000)
- set_rate = 5000
- else if(set_rate < 1)
- set_rate = 1
- transfer_rate = set_rate
- to_chat(user, SPAN_NOTICE("You set the transfer rate of \the [src] to [transfer_rate]."))
-
-/obj/item/inductive_charger/attack(mob/living/M, mob/living/user, target_zone)
- return
-
-/obj/item/inductive_charger/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
- var/mob/living/silicon/robot/R = user
- if(!istype(R))
- to_chat(user, SPAN_WARNING("Only cyborgs can use this!"))
- return
- if(!ready_to_use)
- to_chat(user, SPAN_WARNING("\The [src] is still gathering charge!"))
- return
-
- user.visible_message("[user] begins waving \the [src] around \the [target]...", SPAN_NOTICE("You prepare to wirelessly charge \the [target]..."), range = 3)
- if(!do_after(user, 50, TRUE, target))
- return
- if(R.cell.charge < 1000)
- to_chat(user, SPAN_WARNING("You have no spare charge in your internal cell to give!"))
- return
-
- if(isipc(target))
- var/mob/living/carbon/human/IPC = target
- if(IPC.nutrition == IPC.max_nutrition)
- to_chat(user, SPAN_WARNING("\The [IPC] is already fully charged!"))
- return
- var/charge_amount = min(IPC.max_nutrition - IPC.nutrition, transfer_rate)
- var/charge_value = R.cell.use(charge_amount / efficiency_mod) * efficiency_mod
- IPC.nutrition = min(IPC.max_nutrition, charge_value)
- message_and_use(user, "[user] holds \the [src] over \the [IPC], topping up their battery.", SPAN_NOTICE("You wirelessly transmit [charge_value] units of power to \the [IPC], using [charge_value / efficiency_mod] of internal cell power."))
- else if(isobj(target))
- var/obj/item/cell/C
- if(istype(target, /obj/item/cell))
- C = target
- else
- C = locate() in target
- if(!C)
- to_chat(user, SPAN_WARNING("\The [target] doesn't contain a cell, or it's buried too deep for you to reach!"))
- return
- if(C.fully_charged())
- to_chat(user, SPAN_WARNING("\The [C] is already fully charged!"))
- return
- var/charge_amount = min(C.maxcharge - C.charge, transfer_rate)
- var/charge_value = R.cell.use(charge_amount / efficiency_mod) * efficiency_mod
- C.give(charge_value)
- message_and_use(user, "[user] holds \the [src] over \the [target], topping up its battery.", SPAN_NOTICE("You wirelessly transmit [charge_value] units of power to \the [target], using [charge_value / efficiency_mod] of internal cell power."))
- else
- to_chat(user, SPAN_WARNING("\The [src] cannot be used on \the [target]!"))
-
-/obj/item/inductive_charger/proc/message_and_use(mob/user, var/others_message, var/self_message)
- user.visible_message(others_message, self_message, range = 3)
- addtimer(CALLBACK(src, .proc/recharge), recharge_time)
- ready_to_use = FALSE
- maptext = "Charge"
-
-/obj/item/inductive_charger/proc/recharge()
- ready_to_use = TRUE
- maptext = "Ready"
diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm
index 5b9f692ffe4..a49e52c066a 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules.dm
@@ -51,8 +51,9 @@ var/global/list/robot_modules = list(
var/list/original_languages = list()
var/list/added_networks = list()
-/obj/item/robot_module/New(var/mob/living/silicon/robot/R)
- ..()
+/obj/item/robot_module/Initialize(mapload, var/mob/living/silicon/robot/R)
+ . = ..()
+
R.module = src
src.modules += new /obj/item/inductive_charger(src)
@@ -199,8 +200,8 @@ var/global/list/robot_modules = list(
"Unbranded-Android" = "droid",
)
-/obj/item/robot_module/medical/general/New()
- ..()
+/obj/item/robot_module/medical/general/Initialize()
+ . = ..()
src.modules += new /obj/item/borg/sight/hud/med(src)
src.modules += new /obj/item/device/healthanalyzer(src)
src.modules += new /obj/item/reagent_containers/borghypo/medical(src)
@@ -276,8 +277,8 @@ var/global/list/robot_modules = list(
supported_upgrades = list(/obj/item/robot_parts/robot_component/jetpack)
-/obj/item/robot_module/medical/rescue/New()
- ..()
+/obj/item/robot_module/medical/rescue/Initialize()
+ . = ..()
src.modules += new /obj/item/borg/sight/hud/med(src)
src.modules += new /obj/item/device/healthanalyzer(src)
src.modules += new /obj/item/device/reagent_scanner/adv(src)
@@ -353,8 +354,8 @@ var/global/list/robot_modules = list(
name = "construction robot module"
no_slip = TRUE
-/obj/item/robot_module/engineering/construction/New()
- ..()
+/obj/item/robot_module/engineering/construction/Initialize()
+ . = ..()
src.modules += new /obj/item/borg/sight/meson(src)
src.modules += new /obj/item/powerdrill(src)
src.modules += new /obj/item/rfd/construction/borg(src)
@@ -392,9 +393,9 @@ var/global/list/robot_modules = list(
M.synths = list(metal)
src.modules += M
- var/obj/item/stack/rods/cyborg/R = new /obj/item/stack/rods/cyborg(src)
- R.synths = list(metal)
- src.modules += R
+ var/obj/item/stack/rods/cyborg/rods = new /obj/item/stack/rods/cyborg(src)
+ rods.synths = list(metal)
+ src.modules += rods
var/obj/item/stack/material/cyborg/plasteel/S = new /obj/item/stack/material/cyborg/plasteel(src)
S.synths = list(plasteel)
@@ -412,8 +413,8 @@ var/global/list/robot_modules = list(
C.synths = list(wire)
src.modules += C
-/obj/item/robot_module/engineering/general/New()
- ..()
+/obj/item/robot_module/engineering/general/Initialize()
+ . = ..()
src.modules += new /obj/item/borg/sight/meson(src)
src.modules += new /obj/item/powerdrill(src)
src.modules += new /obj/item/weldingtool/largetank(src)
@@ -464,9 +465,9 @@ var/global/list/robot_modules = list(
G.synths = list(glass)
src.modules += G
- var/obj/item/stack/rods/cyborg/R = new /obj/item/stack/rods/cyborg(src)
- R.synths = list(metal)
- src.modules += R
+ var/obj/item/stack/rods/cyborg/rods = new /obj/item/stack/rods/cyborg(src)
+ rods.synths = list(metal)
+ src.modules += rods
var/obj/item/stack/cable_coil/cyborg/C = new /obj/item/stack/cable_coil/cyborg(src)
C.synths = list(wire)
@@ -529,8 +530,8 @@ var/global/list/robot_modules = list(
)
var/mopping = FALSE
-/obj/item/robot_module/janitor/New()
- ..()
+/obj/item/robot_module/janitor/Initialize()
+ . = ..()
src.modules += new /obj/item/soap/drone(src)
src.modules += new /obj/item/storage/bag/trash(src)
src.modules += new /obj/item/mop(src)
@@ -590,10 +591,10 @@ var/global/list/robot_modules = list(
"TC-Drone" = "dronerecolorserv",
"Unbranded-MAD" = "offfloatspizzytronserv",
"Unbranded-Android" = "droid",
- )
+ )
-/obj/item/robot_module/clerical/butler/New()
- ..()
+/obj/item/robot_module/clerical/butler/Initialize()
+ . = ..()
src.modules += new /obj/item/gripper/service(src)
src.modules += new /obj/item/reagent_containers/glass/bucket(src)
src.modules += new /obj/item/material/minihoe(src)
@@ -626,17 +627,17 @@ var/global/list/robot_modules = list(
src.modules += new /obj/item/reagent_containers/borghypo/service(src)
src.emag = new /obj/item/reagent_containers/food/drinks/bottle/small/beer(src)
- var/datum/reagents/R = new /datum/reagents(50)
- src.emag.reagents = R
- R.my_atom = src.emag
- R.add_reagent(/datum/reagent/chloralhydrate/beer2, 50)
+ var/datum/reagents/RG = new /datum/reagents(50)
+ src.emag.reagents = RG
+ RG.my_atom = src.emag
+ RG.add_reagent(/datum/reagent/chloralhydrate/beer2, 50)
src.emag.name = "Mickey Finn's Special Brew"
/obj/item/robot_module/clerical/general
name = "clerical robot module"
-/obj/item/robot_module/clerical/general/New()
- ..()
+/obj/item/robot_module/clerical/general/Initialize()
+ . = ..()
src.modules += new /obj/item/pen/robopen(src)
src.modules += new /obj/item/form_printer(src)
src.modules += new /obj/item/gripper/paperwork(src)
@@ -671,8 +672,8 @@ var/global/list/robot_modules = list(
)
supported_upgrades = list(/obj/item/robot_parts/robot_component/jetpack)
-/obj/item/robot_module/miner/New()
- ..()
+/obj/item/robot_module/miner/Initialize()
+ . = ..()
src.modules += new /obj/item/borg/sight/material(src)
src.modules += new /obj/item/storage/bag/ore(src)
src.modules += new /obj/item/pickaxe/borgdrill(src)
@@ -696,9 +697,9 @@ var/global/list/robot_modules = list(
var/datum/matter_synth/metal = new /datum/matter_synth/metal(80000)
synths += metal
- var/obj/item/stack/rods/cyborg/R = new /obj/item/stack/rods/cyborg(src)
- R.synths = list(metal)
- src.modules += R
+ var/obj/item/stack/rods/cyborg/rods = new /obj/item/stack/rods/cyborg(src)
+ rods.synths = list(metal)
+ src.modules += rods
var/obj/item/stack/flag/purple/borg/F = new /obj/item/stack/flag/purple/borg(src)
F.synths = list(metal)
@@ -726,8 +727,8 @@ var/global/list/robot_modules = list(
"Unbranded-Android" = "droid",
)
-/obj/item/robot_module/research/New()
- ..()
+/obj/item/robot_module/research/Initialize()
+ . = ..()
src.modules += new /obj/item/portable_destructive_analyzer(src)
src.modules += new /obj/item/gripper/research(src)
src.modules += new /obj/item/gripper/no_use/loader(src)
@@ -797,8 +798,8 @@ var/global/list/robot_modules = list(
"Toileto-tron" = "syndi-medi",
)
-/obj/item/robot_module/syndicate/New(var/mob/living/silicon/robot/R)
- ..()
+/obj/item/robot_module/syndicate/Initialize(mapload, mob/living/silicon/robot/R)
+ . = ..()
R.faction = "syndicate" // prevents viscerators from attacking us
@@ -831,8 +832,8 @@ var/global/list/robot_modules = list(
can_be_pushed = FALSE
supported_upgrades = list(/obj/item/robot_parts/robot_component/jetpack)
-/obj/item/robot_module/combat/New()
- ..()
+/obj/item/robot_module/combat/Initialize()
+ . = ..()
src.modules += new /obj/item/borg/sight/hud/sec(src)
src.modules += new /obj/item/gun/energy/laser/mounted(src)
src.modules += new /obj/item/melee/hammer/powered(src)
@@ -850,8 +851,8 @@ var/global/list/robot_modules = list(
no_slip = TRUE
networks = list(NETWORK_ENGINEERING)
-/obj/item/robot_module/drone/New(var/mob/living/silicon/robot/robot)
- ..()
+/obj/item/robot_module/drone/Initialize(mapload, mob/living/silicon/robot/robot)
+ . = ..()
src.modules += new /obj/item/weldingtool(src)
src.modules += new /obj/item/screwdriver/robotic(src)
src.modules += new /obj/item/wrench/robotic(src)
@@ -929,8 +930,8 @@ var/global/list/robot_modules = list(
channels = list(CHANNEL_ENGINEERING = TRUE)
languages = list()
-/obj/item/robot_module/drone/construction/New()
- ..()
+/obj/item/robot_module/drone/construction/Initialize()
+ . = ..()
src.modules += new /obj/item/rfd/construction/borg(src)
/obj/item/robot_module/drone/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
@@ -967,22 +968,22 @@ var/global/list/robot_modules = list(
emag = new /obj/item/gun/energy/plasmacutter/mounted(src)
emag.name = "Mounted Plasma Cutter"
-/obj/item/robot_module/mining_drone/basic/New(mob/living/silicon/robot/robot)
- ..()
+/obj/item/robot_module/mining_drone/basic/Initialize(mapload, mob/living/silicon/robot/robot)
+ . = ..()
set_up_default(src)
-/obj/item/robot_module/mining_drone/drill/New(mob/living/silicon/robot/robot)
- ..()
+/obj/item/robot_module/mining_drone/drill/Initialize(mapload, mob/living/silicon/robot/robot)
+ . = ..()
set_up_default(src, FALSE)
modules += new /obj/item/pickaxe/jackhammer(src)
-/obj/item/robot_module/mining_drone/ka/New(mob/living/silicon/robot/robot)
- ..()
+/obj/item/robot_module/mining_drone/ka/Initialize(mapload, mob/living/silicon/robot/robot)
+ . = ..()
set_up_default(src)
modules += new /obj/item/gun/custom_ka/cyborg(src)
-/obj/item/robot_module/mining_drone/drillandka/New(mob/living/silicon/robot/robot)
- ..()
+/obj/item/robot_module/mining_drone/drillandka/Initialize(mapload, mob/living/silicon/robot/robot)
+ . = ..()
set_up_default(src, FALSE)
modules += new /obj/item/pickaxe/jackhammer(src)
modules += new /obj/item/gun/custom_ka/cyborg(src)
@@ -1024,8 +1025,8 @@ var/global/list/robot_modules = list(
sprites = list("Roller" = "droid-combat") //TMP // temp my left nut // temp my right nut
can_be_pushed = FALSE
-/obj/item/robot_module/bluespace/New(var/mob/living/silicon/robot/R)
- ..()
+/obj/item/robot_module/bluespace/Initialize(mapload, mob/living/silicon/robot/R)
+ . = ..()
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/borg/sight/meson(src)
src.modules += new /obj/item/borg/sight/hud/med(src)
@@ -1140,4 +1141,4 @@ var/global/list/robot_modules = list(
S.reagents.clear_reagents()
S.mode = initial(S.mode)
S.desc = initial(S.desc)
- S.update_icon()
+ S.update_icon()
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/syndicate_robot.dm b/code/modules/mob/living/silicon/robot/syndicate_robot.dm
index e6ad2becdb2..744f7ad1d66 100644
--- a/code/modules/mob/living/silicon/robot/syndicate_robot.dm
+++ b/code/modules/mob/living/silicon/robot/syndicate_robot.dm
@@ -125,4 +125,4 @@
if(R.cell)
R.cell.use(350)
return TRUE
- return FALSE
+ return FALSE
\ No newline at end of file
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 56e209958f0..298a754dc07 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -78,6 +78,7 @@
var/list/dispersion = list(0)
var/reliability = 100
+ var/cyborg_maptext_override
var/displays_maptext = FALSE
maptext_x = 22
maptext_y = 2
@@ -130,7 +131,8 @@
if(istype(loc, /obj/item/robot_module))
has_safety = FALSE
- displays_maptext = TRUE
+ if(!cyborg_maptext_override)
+ displays_maptext = TRUE
update_maptext()
if(istype(loc, /obj/item/rig_module))
diff --git a/code/modules/research/designs/mechfab/robot/robot_upgrades.dm b/code/modules/research/designs/mechfab/robot/robot_upgrades.dm
index 0b2f2260c24..db87a193bd6 100644
--- a/code/modules/research/designs/mechfab/robot/robot_upgrades.dm
+++ b/code/modules/research/designs/mechfab/robot/robot_upgrades.dm
@@ -38,8 +38,8 @@
build_path = /obj/item/robot_parts/robot_component/jetpack
/datum/design/item/robot_upgrade/syndicate
- name = "Illegal Upgrade"
- desc = "Allows for the construction of lethal upgrades for cyborgs."
+ name = "Non-standard Equipment Upgrade"
+ desc = "Allows cyborg-likes to access weaponry hidden within themselves."
req_tech = list(TECH_COMBAT = 4, TECH_ILLEGAL = 3)
materials = list(DEFAULT_WALL_MATERIAL = 10000, MATERIAL_GLASS = 15000, MATERIAL_DIAMOND = 10000)
build_path = /obj/item/borg/upgrade/syndicate
\ No newline at end of file
diff --git a/html/changelogs/geeves-robot_cleanup.yml b/html/changelogs/geeves-robot_cleanup.yml
new file mode 100644
index 00000000000..56755fb6965
--- /dev/null
+++ b/html/changelogs/geeves-robot_cleanup.yml
@@ -0,0 +1,10 @@
+author: Geeves
+
+delete-after: True
+
+changes:
+ - backend: "Tweaked a lot of cyborg-related code in the backend, things should be smoother now."
+ - tweak: "Replaced some mean robot building failure messages and replaced them with more neutral ones."
+ - rscadd: "Examining robotic components will now tell you which components you still need to add."
+ - tweak: "Installing robot modules have been tweaked, the error messages should be much more descriptive now."
+ - tweak: "The illegal upgrade has been renamed to 'non-standard equipment module'."
\ No newline at end of file
diff --git a/icons/mob/screen/robot.dmi b/icons/mob/screen/robot.dmi
index a309afb2cad..57dc42d4410 100644
Binary files a/icons/mob/screen/robot.dmi and b/icons/mob/screen/robot.dmi differ