diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm
index 54d5e473b7..c43cf8f3db 100644
--- a/code/__defines/mobs.dm
+++ b/code/__defines/mobs.dm
@@ -351,6 +351,11 @@
#define SA_ROBOTIC 3
#define SA_HUMANOID 4
+// Robot module categorization
+#define ROBOT_MODULE_TYPE_GROUNDED "grounded"
+#define ROBOT_MODULE_TYPE_FLYING "flying"
+#define ROBOT_MODULE_TYPE_PLATFORM "platform"
+
// More refined version of SA_* ""intelligence"" separators.
// Now includes bitflags, so to target two classes you just do 'MOB_CLASS_ANIMAL|MOB_CLASS_HUMANOID'
#define MOB_CLASS_NONE 0 // Default value, and used to invert for _ALL.
diff --git a/code/controllers/subsystems/robots.dm b/code/controllers/subsystems/robots.dm
new file mode 100644
index 0000000000..1c09e3f7eb
--- /dev/null
+++ b/code/controllers/subsystems/robots.dm
@@ -0,0 +1,62 @@
+SUBSYSTEM_DEF(robots)
+ name = "Robots"
+ init_order = INIT_ORDER_MISC_EARLY
+ flags = SS_NO_FIRE
+
+ var/list/modules_by_category = list()
+ var/list/crisis_modules_by_category = list()
+ var/list/upgrade_modules_by_category = list()
+ var/list/all_module_names = list()
+
+ var/list/mob_types_by_title = list(
+ "cyborg, flying" = /mob/living/silicon/robot/flying,
+ "robot, flying" = /mob/living/silicon/robot/flying,
+ "drone, flying" = /mob/living/silicon/robot/flying,
+ "drone, platform" = /mob/living/silicon/robot/platform
+ )
+
+ var/list/mmi_types_by_title = list(
+ "robot" = /obj/item/mmi/digital/posibrain,
+ "robot, flying" = /obj/item/mmi/digital/posibrain,
+ "drone" = /obj/item/mmi/digital/robot,
+ "drone, flying" = /obj/item/mmi/digital/robot,
+ "drone, platform" = /obj/item/mmi/digital/robot
+ )
+
+/datum/controller/subsystem/robots/Initialize(start_uptime)
+
+ for(var/module_type in subtypesof(/obj/item/robot_module))
+ var/obj/item/robot_module/module = module_type
+ if(initial(module.unavailable_by_default))
+ continue
+ var/module_category = initial(module.module_category)
+ var/module_name = initial(module.display_name)
+ if(module_name && module_category)
+ if(initial(module.upgrade_locked))
+ LAZYINITLIST(upgrade_modules_by_category[module_category])
+ LAZYSET(upgrade_modules_by_category[module_category], module_name, module)
+ else if(initial(module.crisis_locked))
+ LAZYINITLIST(crisis_modules_by_category[module_category])
+ LAZYSET(crisis_modules_by_category[module_category], module_name, module)
+ else
+ LAZYINITLIST(modules_by_category[module_category])
+ LAZYSET(modules_by_category[module_category], module_name, module)
+ all_module_names |= module_name
+ all_module_names = sortTim(all_module_names, /proc/cmp_text_asc)
+
+/datum/controller/subsystem/robots/proc/get_available_modules(module_category, crisis_mode, include_override)
+ . = list()
+ if(modules_by_category[module_category])
+ . += modules_by_category[module_category]
+ if(crisis_mode && crisis_modules_by_category[module_category])
+ . |= crisis_modules_by_category[module_category]
+ if(include_override && upgrade_modules_by_category[module_category])
+ var/list/modules = upgrade_modules_by_category[module_category]
+ if(modules[include_override])
+ .[include_override] = modules[include_override]
+
+/datum/controller/subsystem/robots/proc/get_mmi_type_by_title(check_title)
+ . = mmi_types_by_title[lowertext(trim(check_title))] || /obj/item/mmi
+
+/datum/controller/subsystem/robots/proc/get_mob_type_by_title(check_title)
+ . = mob_types_by_title[lowertext(trim(check_title))] || /mob/living/silicon/robot
diff --git a/code/game/jobs/job/job.dm b/code/game/jobs/job/job.dm
index 6b3acbe6a2..89537b12e7 100644
--- a/code/game/jobs/job/job.dm
+++ b/code/game/jobs/job/job.dm
@@ -205,6 +205,5 @@
/datum/job/proc/handle_nonhuman_mob(var/mob/living/carbon/human/player, var/alt_title)
if(mob_type & JOB_SILICON_ROBOT)
- return player.Robotize()
- if(mob_type & JOB_SILICON_AI)
- return player
+ return player.Robotize(SSrobots.get_mob_type_by_title(alt_title || title))
+ return player
diff --git a/code/game/jobs/job/silicon.dm b/code/game/jobs/job/silicon.dm
index d101f301c0..b59ce7cf24 100644
--- a/code/game/jobs/job/silicon.dm
+++ b/code/game/jobs/job/silicon.dm
@@ -57,9 +57,17 @@
assignable = FALSE
mob_type = JOB_SILICON_ROBOT
outfit_type = /decl/hierarchy/outfit/job/silicon/cyborg
+ substitute_announce_title = "Stationbound Synthetic"
job_description = "A Cyborg is a mobile station synthetic, piloted by a cybernetically preserved brain. It is considered a person, but is still required \
to follow its Laws."
- alt_titles = list("Robot" = /datum/alt_title/robot, "Drone" = /datum/alt_title/drone)
+ alt_titles = list(
+ "Cyborg, Flying",
+ "Robot" = /datum/alt_title/robot,
+ "Robot, Flying" = /datum/alt_title/robot,
+ "Drone" = /datum/alt_title/drone,
+ "Drone, Flying" = /datum/alt_title/drone,
+ "Drone, Platform" = /datum/alt_title/drone
+ )
// Cyborg Alt Titles
/datum/alt_title/robot
diff --git a/code/game/machinery/robot_fabricator.dm b/code/game/machinery/robot_fabricator.dm
index 43c281e42e..aaca267a44 100644
--- a/code/game/machinery/robot_fabricator.dm
+++ b/code/game/machinery/robot_fabricator.dm
@@ -71,55 +71,54 @@ Please wait until completion...
if(!operating)
var/part_type = text2num(href_list["make"])
- var/build_type = ""
+ var/build_type
var/build_time = 200
var/build_cost = 25000
switch (part_type)
if(1)
- build_type = "/obj/item/robot_parts/l_arm"
+ build_type = /obj/item/robot_parts/l_arm
build_time = 200
build_cost = 25000
if(2)
- build_type = "/obj/item/robot_parts/r_arm"
+ build_type = /obj/item/robot_parts/r_arm
build_time = 200
build_cost = 25000
if(3)
- build_type = "/obj/item/robot_parts/l_leg"
+ build_type = /obj/item/robot_parts/l_leg
build_time = 200
build_cost = 25000
if(4)
- build_type = "/obj/item/robot_parts/r_leg"
+ build_type = /obj/item/robot_parts/r_leg
build_time = 200
build_cost = 25000
if(5)
- build_type = "/obj/item/robot_parts/chest"
+ build_type = /obj/item/robot_parts/chest
build_time = 350
build_cost = 50000
if(6)
- build_type = "/obj/item/robot_parts/head"
+ build_type = /obj/item/robot_parts/head
build_time = 350
build_cost = 50000
if(7)
- build_type = "/obj/item/robot_parts/robot_suit"
+ build_type = /obj/item/robot_parts/frame
build_time = 600
build_cost = 75000
- var/building = text2path(build_type)
- if(!isnull(building))
+ if(!isnull(build_type))
if(metal_amount >= build_cost)
operating = 1
update_use_power(USE_POWER_ACTIVE)
metal_amount = max(0, metal_amount - build_cost)
- being_built = new building(src)
+ being_built = new build_type(src) // TODO: pass in model info to new
add_overlay("fab-active")
updateUsrDialog()
diff --git a/code/game/objects/effects/decals/Cleanable/robots.dm b/code/game/objects/effects/decals/Cleanable/robots.dm
index 16ea69c868..b3e2778629 100644
--- a/code/game/objects/effects/decals/Cleanable/robots.dm
+++ b/code/game/objects/effects/decals/Cleanable/robots.dm
@@ -1,7 +1,7 @@
/obj/effect/decal/cleanable/blood/gibs/robot
name = "robot debris"
desc = "It's a useless heap of junk... or is it?"
- icon = 'icons/mob/robots.dmi'
+ icon = 'icons/mob/robot_gibs.dmi'
icon_state = "gib1"
basecolor = SYNTH_BLOOD_COLOUR
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7")
diff --git a/code/game/objects/effects/decals/remains.dm b/code/game/objects/effects/decals/remains.dm
index 14360092cd..3266ab0732 100644
--- a/code/game/objects/effects/decals/remains.dm
+++ b/code/game/objects/effects/decals/remains.dm
@@ -14,7 +14,7 @@
/obj/effect/decal/remains/robot
desc = "They look like the remains of something mechanical. They have a strange aura about them."
- icon = 'icons/mob/robots.dmi'
+ icon = 'icons/mob/robot_gibs.dmi'
icon_state = "remainsrobot"
/obj/effect/decal/remains/mouse
diff --git a/code/game/objects/items/robot/robot_frame.dm b/code/game/objects/items/robot/robot_frame.dm
new file mode 100644
index 0000000000..29591915c7
--- /dev/null
+++ b/code/game/objects/items/robot/robot_frame.dm
@@ -0,0 +1,194 @@
+/obj/item/robot_parts/frame
+ name = "standard robot frame"
+ desc = "A complex metal backbone with standard limb sockets and pseudomuscle anchors."
+ icon_state = "robo_suit"
+ var/list/parts = list()
+ var/list/required_parts = list(
+ BP_L_ARM = /obj/item/robot_parts/l_arm,
+ BP_R_ARM = /obj/item/robot_parts/r_arm,
+ BP_TORSO = /obj/item/robot_parts/chest,
+ BP_L_LEG = /obj/item/robot_parts/l_leg,
+ BP_R_LEG = /obj/item/robot_parts/r_leg,
+ BP_HEAD = /obj/item/robot_parts/head
+ )
+ var/created_name = ""
+ var/product = /mob/living/silicon/robot
+
+/obj/item/robot_parts/frame/examine(mob/user)
+ . = ..()
+ if(check_completion())
+ . += SPAN_NOTICE("It is ready to receive a controlling intelligence.")
+ else
+ for(var/part in required_parts)
+ if(!parts[part])
+ var/obj/item/part_type = part
+ . += SPAN_WARNING("It is missing \a [initial(part_type.name)]")
+
+/obj/item/robot_parts/frame/update_model_info(var/model)
+ return FALSE
+
+/obj/item/robot_parts/frame/Initialize()
+ . = ..()
+ update_icon()
+
+/obj/item/robot_parts/frame/update_icon()
+ cut_overlays()
+ for(var/part in required_parts)
+ if(parts[part])
+ add_overlay("[part]+o")
+
+/obj/item/robot_parts/frame/proc/check_completion()
+ for(var/part in required_parts)
+ if(!parts[part])
+ return FALSE
+ return TRUE
+
+/obj/item/robot_parts/frame/attackby(obj/item/W, mob/user)
+
+ // Uninstall a robotic part.
+ if(W.is_crowbar())
+ if(!parts.len)
+ to_chat(user, SPAN_WARNING("\The [src] has no parts to remove."))
+ return
+ var/removing = pick(parts)
+ var/obj/item/robot_parts/part = parts[removing]
+ part.forceMove(get_turf(src))
+ user.put_in_hands(part)
+ parts -= removing
+ to_chat(user, SPAN_WARNING("You lever \the [part] off \the [src]."))
+ update_icon()
+
+ // Install a robotic part.
+ else if (istype(W, /obj/item/robot_parts))
+ var/obj/item/robot_parts/part = W
+ if(!required_parts[part.bp_tag] || !istype(W, required_parts[part.bp_tag]))
+ to_chat(user, SPAN_WARNING("\The [src] is not compatible with \the [W]."))
+ return
+ if(parts[part.bp_tag])
+ to_chat(user, SPAN_WARNING("\The [src] already has \a [W] installed."))
+ return
+ if(part.can_install(user) && user.unEquip(W, src))
+ parts[part.bp_tag] = part
+ part.forceMove(src)
+ update_icon()
+
+ // Install an MMI/brain.
+ else if(istype(W, /obj/item/mmi))
+
+ if(!istype(loc,/turf))
+ to_chat(user, SPAN_WARNING("You can't put \the [W] in without the frame being on the ground."))
+ return
+
+ if(!check_completion())
+ to_chat(user, SPAN_WARNING("The frame is not ready for the central processor to be installed."))
+ return
+
+ var/obj/item/mmi/M = W
+ var/mob/living/carbon/brain/B = M.brainmob
+ if(!B)
+ to_chat(user, SPAN_WARNING("Sticking an empty [W.name] into the frame would sort of defeat the purpose."))
+ return
+
+ if(jobban_isbanned(B, "Robot"))
+ to_chat(user, SPAN_WARNING("\The [W] does not seem to fit."))
+ return
+
+ if(B.stat == DEAD)
+ to_chat(user, SPAN_WARNING("Sticking a dead [W.name] into the frame would sort of defeat the purpose."))
+ return
+
+ var/ghost_can_reenter = 0
+ if(B.mind)
+ if(B.key)
+ ghost_can_reenter = TRUE
+ else
+ for(var/mob/observer/dead/G in player_list)
+ if(G.can_reenter_corpse && G.mind == B.mind)
+ ghost_can_reenter = TRUE
+ //Jamming a ghosted brain into a borg is likely detrimental, and may result in some problems.
+ to_chat(user, SPAN_NOTICE("\The [W] is completely unresponsive, but it may be able to auto-resuscitate if you leave it be for awhile."))
+ break
+
+ if(!ghost_can_reenter)
+ to_chat(user, SPAN_WARNING("\The [W] is completely unresponsive; there's no point."))
+ return
+
+ if(!user.unEquip(W))
+ return
+ var/mob/living/silicon/robot/O = new product(get_turf(loc))
+ if(!O)
+ return
+
+ O.mmi = W
+ O.invisibility = 0
+ O.custom_name = created_name
+ O.updatename("Default")
+ B.mind.transfer_to(O)
+ if(O.mind && O.mind.assigned_role)
+ O.job = O.mind.assigned_role
+ else
+ O.job = "Robot"
+
+ var/obj/item/robot_parts/chest/chest = parts[BP_TORSO]
+ if (chest && chest.cell)
+ chest.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
+ callHook("borgify", list(O))
+ O.Namepick()
+ qdel(src)
+
+ else if(istype(W, /obj/item/pen))
+ var/t = sanitizeSafe(input(user, "Enter new robot name", src.name, src.created_name), MAX_NAME_LEN)
+ if(t && (in_range(src, user) || loc == user))
+ created_name = t
+ else
+ ..()
+
+/obj/item/robot_parts/frame/Destroy()
+ parts.Cut()
+ for(var/thing in contents)
+ qdel(thing)
+ . = ..()
+
+/obj/item/robot_parts/frame/proc/dismantled_from(mob/living/silicon/robot/donor)
+ for(var/thing in required_parts - list(BP_TORSO, BP_HEAD))
+ var/part_type = required_parts[thing]
+ parts[thing] = new part_type(src)
+ var/obj/item/robot_parts/chest/chest = (locate() in donor.contents) || new
+ if(chest)
+ chest.forceMove(src)
+ parts[BP_TORSO] = chest
+ update_icon()
+
+/obj/item/robot_parts/frame/SetDefaultName()
+ name = initial(name)
+
+/obj/item/robot_parts/frame/flyer
+ name = "flying robot frame"
+ icon = 'icons/obj/robot_parts_flying.dmi'
+ product = /mob/living/silicon/robot/flying
+ required_parts = list(
+ BP_L_ARM = /obj/item/robot_parts/l_arm,
+ BP_R_ARM = /obj/item/robot_parts/r_arm,
+ BP_TORSO = /obj/item/robot_parts/chest,
+ BP_HEAD = /obj/item/robot_parts/head
+ )
+
+/obj/item/robot_parts/frame/platform
+ name = "large robot frame"
+ icon = 'icons/obj/robot_parts_platform.dmi'
+ product = /mob/living/silicon/robot/platform
+ required_parts = list(
+ BP_L_ARM = /obj/item/robot_parts/l_arm,
+ BP_R_ARM = /obj/item/robot_parts/r_arm,
+ BP_L_LEG = /obj/item/robot_parts/l_leg,
+ BP_R_LEG = /obj/item/robot_parts/r_leg,
+ BP_TORSO = /obj/item/robot_parts/chest,
+ BP_HEAD = /obj/item/robot_parts/head
+ )
diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm
index 8fe77a0d1c..617ba34aa2 100644
--- a/code/game/objects/items/robot/robot_parts.dm
+++ b/code/game/objects/items/robot/robot_parts.dm
@@ -4,294 +4,222 @@
item_state = "buildpipe"
icon_state = "blank"
slot_flags = SLOT_BELT
+ dir = SOUTH
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
- dir = SOUTH
+ var/bp_tag = null // What part is this?
/obj/item/robot_parts/set_dir()
return
+/obj/item/robot_parts/proc/update_model_info(var/model)
+ if(!model)
+ return FALSE
+ model_info = model
+ var/datum/robolimb/R = all_robolimbs[model]
+ if(R)
+ name = "[R.company] [initial(name)]"
+ desc = "[R.desc]"
+ if(icon_state in icon_states(R.icon))
+ icon = R.icon
+ return TRUE
+ return FALSE
+
+/obj/item/robot_parts/Initialize(ml, model)
+ . = ..(ml)
+ if(!update_model_info(model))
+ SetDefaultName()
+
+/obj/item/robot_parts/proc/SetDefaultName()
+ name = "robot [initial(name)]"
+
+/obj/item/robot_parts/proc/can_install(mob/user)
+ return TRUE
+
/obj/item/robot_parts/l_arm
- name = "cyborg left 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
+ bp_tag = BP_L_ARM
/obj/item/robot_parts/r_arm
- name = "cyborg right 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
+ bp_tag = BP_R_ARM
/obj/item/robot_parts/l_leg
- name = "cyborg left 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
+ bp_tag = BP_L_LEG
/obj/item/robot_parts/r_leg
- name = "cyborg 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 = "cyborg chest"
- desc = "A heavily reinforced case containing cyborg logic boards, with space for a standard power cell."
- icon_state = "chest"
- part = list(BP_GROIN,BP_TORSO)
- var/wires = 0.0
- var/obj/item/cell/cell = null
+ bp_tag = BP_R_LEG
/obj/item/robot_parts/head
- name = "cyborg head"
+ name = "head"
desc = "A standard reinforced braincase, with spine-plugged neural socket and sensor gimbals."
icon_state = "head"
part = list(BP_HEAD)
+ bp_tag = BP_HEAD
var/obj/item/flash/flash1 = null
var/obj/item/flash/flash2 = null
-/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/head/can_install(mob/user)
+ var/success = TRUE
+ if(!flash1 || !flash2)
+ to_chat(user, SPAN_WARNING("You need to attach a flash to it first!"))
+ success = FALSE
+ return success && ..()
-/obj/item/robot_parts/robot_suit/Initialize()
- . = ..()
- src.updateicon()
+/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 = "torso"
+ part = list(BP_GROIN,BP_TORSO)
+ bp_tag = BP_TORSO
+ var/wires = 0.0
+ var/obj/item/cell/cell = null
-/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/chest/can_install(mob/user)
+ var/success = TRUE
+ if(!wires)
+ to_chat(user, SPAN_WARNING("You need to attach wires to it first!"))
+ success = FALSE
+ if(!cell)
+ to_chat(user, SPAN_WARNING("You need to attach a cell to it first!"))
+ success = FALSE
+ return success && ..()
-/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/chest/attackby(obj/item/W, mob/user)
-/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() == MAT_STEEL && !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.loc = 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_item()
- W.loc = src
- src.l_leg = W
- src.updateicon()
-
- if(istype(W, /obj/item/robot_parts/r_leg))
- if(src.r_leg) return
- user.drop_item()
- W.loc = src
- src.r_leg = W
- src.updateicon()
-
- if(istype(W, /obj/item/robot_parts/l_arm))
- if(src.l_arm) return
- user.drop_item()
- W.loc = src
- src.l_arm = W
- src.updateicon()
-
- if(istype(W, /obj/item/robot_parts/r_arm))
- if(src.r_arm) return
- user.drop_item()
- W.loc = 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_item()
- W.loc = 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_item()
- W.loc = src
- src.head = W
- src.updateicon()
- else
- to_chat(user, "You need to attach a flash to it first!")
-
- if(istype(W, /obj/item/mmi))
- var/obj/item/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(!istype(W, /obj/item/mmi/inert))
- 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/observer/dead/G in player_list)
- if(G.can_reenter_corpse && G.mind == M.brainmob.mind)
- ghost_can_reenter = 1 //May come in use again at another point.
- to_chat(user, "\The [W] is completely unresponsive; though it may be able to auto-resuscitate.") //Jamming a ghosted brain into a borg is likely detrimental, and may result in some problems.
- return
- 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(jobban_isbanned(M.brainmob, "Cyborg"))
- to_chat(user, "This [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()
-
- O.mmi = W
- O.post_mmi_setup()
- O.invisibility = 0
- O.custom_name = created_name
- O.updatename("Default")
-
- if(M.brainmob)
- 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")
- for(var/datum/language/L in M.brainmob.languages)
- O.add_language(L.name)
- O.job = "Cyborg"
- O.cell = chest.cell
- O.cell.loc = O
- W.loc = 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 (istype(W, /obj/item/pen))
- 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_item()
- W.loc = src
+ to_chat(user, SPAN_WARNING("You have already inserted a cell!"))
+ return TRUE
+ if(user.unEquip(W, src))
src.cell = W
- to_chat(user, "You insert the cell!")
+ W.forceMove(src)
+ to_chat(user, SPAN_NOTICE("You insert the cell!"))
+ return TRUE
+
if(istype(W, /obj/item/stack/cable_coil))
if(src.wires)
- to_chat(user, "You have already inserted wire!")
- return
- else
- var/obj/item/stack/cable_coil/coil = W
- coil.use(1)
+ to_chat(user, SPAN_WARNING("You have already inserted wire!"))
+ return TRUE
+ var/obj/item/stack/cable_coil/coil = W
+ if(coil.use(1))
src.wires = 1.0
- to_chat(user, "You insert the wire!")
- return
+ to_chat(user, SPAN_NOTICE("You insert the wire!"))
+ return TRUE
-/obj/item/robot_parts/head/attackby(obj/item/W as obj, mob/user as mob)
+ if(istype(W, /obj/item/robot_parts/head))
+ var/obj/item/robot_parts/head/head_part = W
+ // Attempt to create full-body prosthesis.
+ var/success = TRUE
+ success &= can_install(user)
+ success &= head_part.can_install(user)
+ if (success)
+
+ // Species selection.
+ var/species = input(user, "Select a species for the prosthetic.") as null|anything in GetCyborgSpecies()
+ if(!species)
+ return TRUE
+ var/name = sanitizeSafe(input(user,"Set a name for the new prosthetic."), MAX_NAME_LEN)
+ if(!name)
+ name = "prosthetic ([random_id("prosthetic_id", 1, 999)])"
+
+ // Create a new, nonliving human.
+ var/mob/living/carbon/human/H = new /mob/living/carbon/human(get_turf(loc))
+ H.death(0, DEATHGASP_NO_MESSAGE)
+ H.set_species(species)
+ H.fully_replace_character_name(name)
+
+ // Remove all external organs other than chest and head..
+ for (var/O in list(BP_L_ARM, BP_R_ARM, BP_L_LEG, BP_R_LEG))
+ var/obj/item/organ/external/organ = H.organs_by_name[O]
+ H.organs -= organ
+ H.organs_by_name[organ.organ_tag] = null
+ qdel(organ)
+
+ // Remove brain (we want to put one in).
+ var/obj/item/organ/internal/brain = H.internal_organs_by_name[O_BRAIN]
+ H.organs -= brain
+ H.organs_by_name[brain.organ_tag] = null
+ qdel(brain)
+
+ // Robotize remaining organs: Eyes, head, and chest.
+ // Respect brand used.
+ var/obj/item/organ/internal/eyes = H.internal_organs_by_name[O_EYES]
+ eyes.robotize()
+
+ var/obj/item/organ/external/head = H.organs_by_name[BP_HEAD]
+ var/head_company = head_part.model_info
+ head.robotize(head_company)
+
+ var/obj/item/organ/external/chest = H.organs_by_name[BP_TORSO]
+ var/chest_company = model_info
+ chest.robotize(chest_company)
+
+ // Cleanup
+ qdel(W)
+ qdel(src)
+ return TRUE
+
+ return ..()
+
+/obj/item/robot_parts/chest/proc/GetCyborgSpecies()
+ . = list()
+ for(var/N in GLOB.playable_species)
+ var/datum/species/S = GLOB.all_species[N]
+ if(S.spawn_flags & SPECIES_NO_FBP_CONSTRUCTION)
+ continue
+ . += N
+
+/obj/item/robot_parts/head/attackby(obj/item/W, mob/user)
..()
if(istype(W, /obj/item/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?")
+ to_chat(user, SPAN_WARNING("How do you propose to do that?"))
return
else
add_flashes(W,user)
else
add_flashes(W,user)
- return
-/obj/item/robot_parts/head/proc/add_flashes(obj/item/W as obj, mob/user as mob) //Made into a separate proc to avoid copypasta
+/obj/item/robot_parts/head/proc/add_flashes(obj/item/W, mob/user) //Made into a seperate proc to avoid copypasta
if(src.flash1 && src.flash2)
- to_chat(user, "You have already inserted the eyes!")
+ to_chat(user, SPAN_NOTICE("You have already inserted the eyes!"))
return
else if(src.flash1)
- user.drop_item()
- W.loc = src
+ if(!user.unEquip(W, src))
+ return
src.flash2 = W
- to_chat(user, "You insert the flash into the eye socket!")
+ W.forceMove(src)
+ to_chat(user, SPAN_NOTICE("You insert the flash into the eye socket!"))
else
- user.drop_item()
- W.loc = src
+ if(!user.unEquip(W, src))
+ return
src.flash1 = W
- to_chat(user, "You insert the flash into the eye socket!")
+ W.forceMove(src)
+ to_chat(user, SPAN_NOTICE("You insert the flash into the eye socket!"))
-/obj/item/robot_parts/emag_act(var/remaining_charges, var/mob/user)
+/obj/item/robot_parts/emag_act(remaining_charges, mob/user)
if(sabotaged)
- to_chat(user, "[src] is already sabotaged!")
+ to_chat(user, SPAN_WARNING("[src] is already sabotaged!"))
else
- to_chat(user, "You short out the safeties.")
+ to_chat(user, SPAN_WARNING("You short out the safeties."))
sabotaged = 1
return 1
diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm
index fd05f92676..75ef6516be 100644
--- a/code/game/objects/items/robot/robot_upgrades.dm
+++ b/code/game/objects/items/robot/robot_upgrades.dm
@@ -133,22 +133,17 @@
require_module = 1
/obj/item/borg/upgrade/jetpack/action(var/mob/living/silicon/robot/R)
- if(..()) return 0
+ if(..())
+ return FALSE
- var/obj/item/tank/jetpack/carbondioxide/T = locate() in R.module
- if(!T)
- T = locate() in R.module.contents
- if(!T)
- T = locate() in R.module.modules
- if(!T)
- R.module.modules += new/obj/item/tank/jetpack/carbondioxide(R.module)
- for(var/obj/item/tank/jetpack/carbondioxide in R.module.modules)
- R.internals = src
- return 1
- if(T)
- to_chat(R, "Upgrade mounting error! No suitable hardpoint detected!")
+ if(R.module.jetpack)
+ to_chat(R, "Upgrade mounting error! No suitable hardpoint detected!")
to_chat(usr, "There's no mounting point for the module!")
- return 0
+ return FALSE
+
+ R.module.jetpack = new /obj/item/tank/jetpack/carbondioxide(R.module)
+ R.internals = R.module.jetpack
+ return TRUE
/obj/item/borg/upgrade/advhealth
name = "advanced health analyzer module"
diff --git a/code/game/objects/structures/door_assembly.dm b/code/game/objects/structures/door_assembly.dm
index 4a984b1606..428c5243df 100644
--- a/code/game/objects/structures/door_assembly.dm
+++ b/code/game/objects/structures/door_assembly.dm
@@ -163,7 +163,7 @@
update_state()
/obj/structure/door_assembly/attack_robot(mob/living/silicon/robot/user)
- if(Adjacent(user) && (user.module && (istype(user.module,/obj/item/robot_module/robot/engineering/general)) \
+ if(Adjacent(user) && (user.module && (istype(user.module,/obj/item/robot_module/robot/engineering)) \
|| istype(user.module,/obj/item/robot_module/drone))) //Only dron (and engiborg) needs this.
rename_door(user)
diff --git a/code/game/objects/structures/ghost_pods/silicon.dm b/code/game/objects/structures/ghost_pods/silicon.dm
index 74f53e9204..28ed8976e9 100644
--- a/code/game/objects/structures/ghost_pods/silicon.dm
+++ b/code/game/objects/structures/ghost_pods/silicon.dm
@@ -17,7 +17,7 @@
/obj/structure/ghost_pod/manual/lost_drone/create_occupant(var/mob/M)
density = FALSE
- var/mob/living/silicon/robot/lost/randomlaws/R = new(get_turf(src))
+ var/mob/living/silicon/robot/flying/lost/randomlaws/R = new(get_turf(src))
R.adjustBruteLoss(rand(5, 30))
R.adjustFireLoss(rand(5, 10))
if(M.mind)
diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm
index b1f06306c8..a759cea6f6 100644
--- a/code/game/objects/structures/windoor_assembly.dm
+++ b/code/game/objects/structures/windoor_assembly.dm
@@ -75,7 +75,7 @@
update_state()
/obj/structure/windoor_assembly/attack_robot(mob/living/silicon/robot/user)
- if(Adjacent(user) && (user.module && (istype(user.module,/obj/item/robot_module/robot/engineering/general)) \
+ if(Adjacent(user) && (user.module && (istype(user.module,/obj/item/robot_module/robot/engineering)) \
|| istype(user.module,/obj/item/robot_module/drone))) //Only dron (and engiborg) needs this.
rename_door(user)
diff --git a/code/global.dm b/code/global.dm
index 72f4d34e20..b797a11bb2 100644
--- a/code/global.dm
+++ b/code/global.dm
@@ -124,14 +124,6 @@ var/global/DBConnection/dbcon_old = new() // /tg/station database (Old database)
// Added for Xenoarchaeology, might be useful for other stuff.
var/global/list/alphabet_uppercase = list("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z")
-
-// Used by robots and robot preferences.
-var/global/list/robot_module_types = list(
- "Standard", "Engineering", "Surgeon", "Crisis",
- "Miner", "Janitor", "Service", "Clerical", "Security",
- "Research"
-)
-
// Some scary sounds.
var/global/static/list/scarySounds = list(
'sound/weapons/thudswoosh.ogg',
diff --git a/code/modules/client/preference_setup/general/06_flavor.dm b/code/modules/client/preference_setup/general/06_flavor.dm
index 94525ee06f..7dc82a131f 100644
--- a/code/modules/client/preference_setup/general/06_flavor.dm
+++ b/code/modules/client/preference_setup/general/06_flavor.dm
@@ -15,7 +15,7 @@
//Flavour text for robots.
S["flavour_texts_robot_Default"] >> pref.flavour_texts_robot["Default"]
- for(var/module in robot_module_types)
+ for(var/module in SSrobots.all_module_names)
S["flavour_texts_robot_[module]"] >> pref.flavour_texts_robot[module]
/datum/category_item/player_setup_item/general/flavor/save_character(var/savefile/S)
@@ -30,7 +30,7 @@
S["flavor_texts_feet"] << pref.flavor_texts["feet"]
S["flavour_texts_robot_Default"] << pref.flavour_texts_robot["Default"]
- for(var/module in robot_module_types)
+ for(var/module in SSrobots.all_module_names)
S["flavour_texts_robot_[module]"] << pref.flavour_texts_robot[module]
/datum/category_item/player_setup_item/general/flavor/sanitize_character()
@@ -129,7 +129,7 @@
HTML += "Default: "
HTML += TextPreview(pref.flavour_texts_robot["Default"])
HTML += "
"
- for(var/module in robot_module_types)
+ for(var/module in SSrobots.all_module_names)
HTML += "[module]: "
HTML += TextPreview(pref.flavour_texts_robot[module])
HTML += "
"
diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm
index fe70d0fa25..7429608d94 100644
--- a/code/modules/clothing/spacesuits/rig/rig.dm
+++ b/code/modules/clothing/spacesuits/rig/rig.dm
@@ -912,7 +912,7 @@
return
if((istype(wearer.loc, /turf/space)) || (wearer.lastarea.has_gravity == 0))
- if(!wearer.Process_Spacemove(0))
+ if(!wearer.Process_Spacemove(FALSE))
return 0
if(malfunctioning)
diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm
index ad0c08abfb..7d909aa9f3 100644
--- a/code/modules/mob/living/carbon/brain/MMI.dm
+++ b/code/modules/mob/living/carbon/brain/MMI.dm
@@ -211,7 +211,7 @@
. += "It appears to be completely inactive."
else
. += "It appears to be completely inactive."
-
+
/obj/item/mmi/digital/emp_act(severity)
if(!src.brainmob)
return
@@ -351,4 +351,4 @@
icon = 'icons/obj/module.dmi'
icon_state = "mainboard"
w_class = ITEMSIZE_NORMAL
- origin_tech = list(TECH_ENGINEERING = 2, TECH_MATERIAL = 2, TECH_BLUESPACE = 2, TECH_DATA = 3)
\ No newline at end of file
+ origin_tech = list(TECH_ENGINEERING = 2, TECH_MATERIAL = 2, TECH_BLUESPACE = 2, TECH_DATA = 3)
diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm
index 865de0b8e6..2013c39ab0 100644
--- a/code/modules/mob/living/carbon/human/human_movement.dm
+++ b/code/modules/mob/living/carbon/human/human_movement.dm
@@ -173,34 +173,12 @@
for(var/obj/item/rig_module/maneuvering_jets/module in rig.installed_modules)
return module.jets
-/mob/living/carbon/human/Process_Spacemove(var/check_drift = 0)
- //Can we act?
- if(restrained()) return 0
-
- if(..()) //Can move due to other reasons, don't use jetpack fuel
- return 1
-
- //Do we have a working jetpack?
- var/obj/item/tank/jetpack/thrust = get_jetpack()
-
- if(thrust)
- if(((!check_drift) || (check_drift && thrust.stabilization_on)) && (!lying) && (thrust.do_thrust(0.01, src)))
- inertia_dir = 0
- return 1
-
- return 0
-
-
/mob/living/carbon/human/Process_Spaceslipping(var/prob_slip = 5)
//If knocked out we might just hit it and stop. This makes it possible to get dead bodies and such.
if(species.flags & NO_SLIP)
return 0
- var/obj/item/tank/jetpack/thrust = get_jetpack()
- if(thrust?.can_thrust(0.01))
- return 0
-
if(stat)
prob_slip = 0 // Changing this to zero to make it line up with the comment, and also, make more sense.
@@ -209,13 +187,16 @@
prob_slip = 0
//Check hands and mod slip
- if(!l_hand) prob_slip -= 2
- else if(l_hand.w_class <= 2) prob_slip -= 1
- if (!r_hand) prob_slip -= 2
- else if(r_hand.w_class <= 2) prob_slip -= 1
+ if(!l_hand)
+ prob_slip -= 2
+ else if(l_hand.w_class <= 2)
+ prob_slip -= 1
+ if (!r_hand)
+ prob_slip -= 2
+ else if(r_hand.w_class <= 2)
+ prob_slip -= 1
- prob_slip = round(prob_slip)
- return(prob_slip)
+ return round(prob_slip)
// Handle footstep sounds
/mob/living/carbon/human/handle_footstep(var/turf/T)
diff --git a/code/modules/mob/living/living_movement.dm b/code/modules/mob/living/living_movement.dm
index 0ae3086a27..19c39ea1b2 100644
--- a/code/modules/mob/living/living_movement.dm
+++ b/code/modules/mob/living/living_movement.dm
@@ -249,7 +249,7 @@ default behaviour is:
/mob/living/proc/inertial_drift()
if(x > 1 && x < (world.maxx) && y > 1 && y < (world.maxy))
- if(Process_Spacemove(1))
+ if(Process_Spacemove(TRUE))
inertia_dir = 0
return
diff --git a/code/modules/mob/living/silicon/robot/component.dm b/code/modules/mob/living/silicon/robot/component.dm
index 38586be2c4..09bc9d0274 100644
--- a/code/modules/mob/living/silicon/robot/component.dm
+++ b/code/modules/mob/living/silicon/robot/component.dm
@@ -82,6 +82,11 @@
external_type = /obj/item/robot_parts/robot_component/armour_platform
max_damage = 140
+/datum/robot_component/armour/light
+ name = "lightweight armour plating"
+ external_type = /obj/item/robot_parts/robot_component/armour_light
+ max_damage = 75
+
// ACTUATOR
// Enables movement.
// Uses no power when idle. Uses 200J for each tile the cyborg moves.
@@ -181,13 +186,13 @@
// Initializes cyborg's components. Technically, adds default set of components to new borgs
/mob/living/silicon/robot/proc/initialize_components()
- components["actuator"] = new/datum/robot_component/actuator(src)
- components["radio"] = new/datum/robot_component/radio(src)
- components["power cell"] = new/datum/robot_component/cell(src)
- components["diagnosis unit"] = new/datum/robot_component/diagnosis_unit(src)
- components["camera"] = new/datum/robot_component/camera(src)
- components["comms"] = new/datum/robot_component/binary_communication(src)
- components["armour"] = new/datum/robot_component/armour(src)
+ components["actuator"] = new /datum/robot_component/actuator(src)
+ components["radio"] = new /datum/robot_component/radio(src)
+ components["power cell"] = new /datum/robot_component/cell(src)
+ components["diagnosis unit"] = new /datum/robot_component/diagnosis_unit(src)
+ components["camera"] = new /datum/robot_component/camera(src)
+ components["comms"] = new /datum/robot_component/binary_communication(src)
+ components["armour"] = new /datum/robot_component/armour(src)
// Checks if component is functioning
/mob/living/silicon/robot/proc/is_component_functioning(module_name)
@@ -258,6 +263,12 @@
icon_state_broken = "armor_broken"
color = COLOR_GRAY80
+/obj/item/robot_parts/robot_component/armour_light
+ name = "lightweight armour plating"
+ desc = "A pair of flexible, light armor plates, used to protect the internals of robots equipped with anti-gravity frames."
+ icon_state = "armor_l"
+ icon_state_broken = "armor_l_broken"
+
/obj/item/robot_parts/robot_component/camera
name = "camera"
desc = "A modified camera module used as a visual receptor for robots and exosuits, also serving as a relay for wireless video feed."
@@ -274,4 +285,4 @@
name = "radio"
desc = "A modular, multi-frequency radio used by robots and exosuits to enable communication systems. Comes with built-in subspace receivers."
icon_state = "radio"
- icon_state_broken = "radio_broken"
\ No newline at end of file
+ icon_state_broken = "radio_broken"
diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm
index 809c916ec8..15173fb41a 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone.dm
@@ -21,7 +21,6 @@ var/global/list/mob_hat_cache = list()
/mob/living/silicon/robot/drone
name = "maintenance drone"
real_name = "drone"
- icon = 'icons/mob/robots.dmi'
icon_state = "repairbot"
maxHealth = 35
health = 35
@@ -153,7 +152,7 @@ var/global/list/mob_hat_cache = list()
/mob/living/silicon/robot/drone/choose_icon()
return
-/mob/living/silicon/robot/drone/pick_module()
+/mob/living/silicon/robot/drone/pick_module(override)
return
/mob/living/silicon/robot/drone/proc/wear_hat(var/obj/item/new_hat)
@@ -272,10 +271,6 @@ var/global/list/mob_hat_cache = list()
return
..()
-//DRONE MOVEMENT.
-/mob/living/silicon/robot/drone/Process_Spaceslipping(var/prob_slip)
- return 0
-
//CONSOLE PROCS
/mob/living/silicon/robot/drone/proc/law_resync()
if(stat != DEAD)
diff --git a/code/modules/mob/living/silicon/robot/drone/drone_items.dm b/code/modules/mob/living/silicon/robot/drone/drone_items.dm
index 84c770f46e..17b50223ec 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone_items.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone_items.dm
@@ -129,6 +129,17 @@
)
+/obj/item/gripper/cultivator
+ name = "cultivator gripper"
+ icon_state = "gripper"
+ desc = "A simple grasping tool used to perform tasks in the xenobiology division, such as handling plant samples and disks."
+ can_hold = list(
+ /obj/item/reagent_containers/glass,
+ /obj/item/seeds,
+ /obj/item/slime_extract,
+ /obj/item/disk/botany
+ )
+
/obj/item/gripper/circuit
name = "circuit assembly gripper"
icon_state = "gripper-circ"
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index aed89d79ea..315890eb95 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -3,7 +3,7 @@
/mob/living/silicon/robot
name = "Cyborg"
real_name = "Cyborg"
- icon = 'icons/mob/robots.dmi'
+ icon = 'icons/mob/robots/robots_grounded.dmi'
icon_state = "robot"
maxHealth = 200
health = 200
@@ -14,6 +14,7 @@
var/lights_on = 0 // Is our integrated light on?
var/used_power_this_tick = 0
+ var/power_efficiency = 1
var/sight_mode = 0
var/custom_name = ""
var/custom_sprite = 0 //Due to all the sprites involved, a var for our custom borgs may be best
@@ -22,6 +23,8 @@
var/crisis_override = 0
var/integrated_light_power = 6
var/datum/wires/robot/wires
+ var/module_category = ROBOT_MODULE_TYPE_GROUNDED
+ var/dismantle_type = /obj/item/robot_parts/frame
can_be_antagged = TRUE
@@ -75,7 +78,6 @@
var/viewalerts = 0
var/modtype = "Default"
var/lower_mod = 0
- var/jetpack = 0
var/datum/effect_system/ion_trail_follow/ion_trail = null
var/datum/effect_system/spark_spread/spark_system//So they can initialize sparks whenever/N
var/jeton = 0
@@ -258,28 +260,42 @@
updateicon()
return module_sprites
-/mob/living/silicon/robot/proc/pick_module()
- if(module)
- return
- var/list/modules = list()
- modules.Add(robot_module_types)
- if((crisis && security_level == SEC_LEVEL_RED) || crisis_override) //Leaving this in until it's balanced appropriately.
- to_chat(src, "Crisis mode active. Combat module available.")
- modules+="Combat"
- modtype = input("Please, select a module!", "Robot module", null, null) as null|anything in modules
+/mob/living/silicon/robot/proc/pick_module(override)
- if(module)
+ if(module && !override)
return
- if(!(modtype in robot_modules))
+
+ var/is_crisis_mode = crisis_override || (security_level == SEC_LEVEL_RED)
+ var/list/robot_modules = SSrobots.get_available_modules(module_category, is_crisis_mode, override)
+ if(!length(robot_modules))
+ to_chat(src, SPAN_WARNING("For some reason, no modules are available to you. Please report this on the issue tracker!"))
+ return
+
+ if(!override)
+ if(is_crisis_mode)
+ to_chat(src, SPAN_WARNING("Crisis mode active. Additional modules available."))
+ modtype = input("Please select a module!", "Robot module", null, null) as null|anything in robot_modules
+ else
+ if(module)
+ QDEL_NULL(module)
+ modtype = override
+
+ if(module || !modtype)
return
var/module_type = robot_modules[modtype]
+ if(!module_type)
+ to_chat(src, SPAN_WARNING("You are unable to select a module."))
+ return
+
new module_type(src)
- hands.icon_state = lowertext(modtype)
+ if(hands)
+ hands.icon_state = lowertext(modtype)
feedback_inc("cyborg_[lowertext(modtype)]",1)
updatename()
- notify_ai(ROBOT_NOTIFICATION_NEW_MODULE, module.name)
+ if(module)
+ notify_ai(ROBOT_NOTIFICATION_NEW_MODULE, module.name)
/mob/living/silicon/robot/proc/update_braintype()
if(istype(mmi, /obj/item/mmi/digital/posibrain))
@@ -416,19 +432,11 @@
// this function displays jetpack pressure in the stat panel
/mob/living/silicon/robot/proc/show_jetpack_pressure()
// if you have a jetpack, show the internal tank pressure
- var/obj/item/tank/jetpack/current_jetpack = installed_jetpack()
+ var/obj/item/tank/jetpack/current_jetpack = get_jetpack()
if (current_jetpack)
stat("Internal Atmosphere Info", current_jetpack.name)
stat("Tank Pressure", current_jetpack.air_contents.return_pressure())
-
-// this function returns the robots jetpack, if one is installed
-/mob/living/silicon/robot/proc/installed_jetpack()
- if(module)
- return (locate(/obj/item/tank/jetpack) in module.modules)
- return 0
-
-
// this function displays the cyborgs current cell charge in the stat panel
/mob/living/silicon/robot/proc/show_cell_power()
if(cell)
@@ -555,13 +563,8 @@
to_chat(user, "You jam the crowbar into the robot and begin levering [mmi].")
sleep(30)
to_chat(user, "You damage some parts of the chassis, but eventually manage to rip out [mmi]!")
- var/obj/item/robot_parts/robot_suit/C = new/obj/item/robot_parts/robot_suit(loc)
- C.l_leg = new/obj/item/robot_parts/l_leg(C)
- C.r_leg = new/obj/item/robot_parts/r_leg(C)
- C.l_arm = new/obj/item/robot_parts/l_arm(C)
- C.r_arm = new/obj/item/robot_parts/r_arm(C)
- C.updateicon()
- new/obj/item/robot_parts/chest(loc)
+ var/obj/item/robot_parts/frame/C = new dismantle_type(loc)
+ C.dismantled_from(src)
qdel(src)
else
// Okay we're not removing the cell or an MMI, but maybe something else?
@@ -1016,7 +1019,7 @@
if(icontype == "Custom")
icon = CUSTOM_ITEM_SYNTH
else // This is to fix an issue where someone with a custom borg sprite chooses a non-custom sprite and turns invisible.
- icon = 'icons/mob/robots.dmi'
+ icon = initial(icon)
icon_state = module_sprites[icontype]
updateicon()
diff --git a/code/modules/mob/living/silicon/robot/robot_modules/_module.dm b/code/modules/mob/living/silicon/robot/robot_modules/_module.dm
new file mode 100644
index 0000000000..e743c192c1
--- /dev/null
+++ b/code/modules/mob/living/silicon/robot/robot_modules/_module.dm
@@ -0,0 +1,256 @@
+/obj/item/robot_module
+ name = "robot module"
+ icon = 'icons/obj/module.dmi'
+ icon_state = "std_module"
+ w_class = ITEMSIZE_NO_CONTAINER
+ item_state = "std_mod"
+
+ var/unavailable_by_default
+ var/display_name
+ var/hide_on_manifest = FALSE
+ var/channels = list()
+ var/networks = list()
+ var/languages = list(
+ LANGUAGE_SOL_COMMON = 1,
+ LANGUAGE_SIVIAN= 0,
+ LANGUAGE_TRADEBAND = 1,
+ LANGUAGE_UNATHI = 0,
+ LANGUAGE_SIIK = 0,
+ LANGUAGE_AKHANI = 0,
+ LANGUAGE_SKRELLIAN = 0,
+ LANGUAGE_GUTTER = 0,
+ LANGUAGE_SCHECHI = 0,
+ LANGUAGE_SIGN = 0,
+ LANGUAGE_TERMINUS = 1,
+ LANGUAGE_ZADDAT = 0
+ )
+ var/sprites = list()
+ var/can_be_pushed = 1
+ var/no_slip = 0
+ var/list/modules = list()
+ var/list/datum/matter_synth/synths = list()
+ var/obj/item/emag = null
+ var/obj/item/borg/upgrade/advhealth = null
+ var/list/subsystems = list()
+ var/list/obj/item/borg/upgrade/supported_upgrades = list()
+
+ var/obj/item/tank/jetpack/jetpack
+
+ var/list/universal_equipment = list(
+ /obj/item/flash/robot,
+ /obj/item/tool/crowbar/cyborg,
+ /obj/item/extinguisher,
+ /obj/item/gps/robot
+ )
+ // Module categorization values.
+ var/module_category = ROBOT_MODULE_TYPE_GROUNDED
+ var/upgrade_locked = FALSE
+ var/crisis_locked = FALSE
+
+ // Bookkeeping
+ var/list/original_languages = list()
+ var/list/added_networks = list()
+
+/obj/item/robot_module/proc/hide_on_manifest()
+ . = hide_on_manifest
+
+/obj/item/robot_module/Initialize(var/ml)
+ . = ..()
+ var/mob/living/silicon/robot/R = loc
+ if(!istype(R))
+ return INITIALIZE_HINT_QDEL
+
+ R.module = src
+
+ build_equipment(R)
+ build_emag(R)
+ build_synths(R)
+
+ finalize_equipment(R)
+ finalize_emag(R)
+ finalize_synths(R)
+
+ add_camera_networks(R)
+ add_languages(R)
+ add_subsystems(R)
+ apply_status_flags(R)
+ handle_shell(R)
+
+ if(R.radio)
+ addtimer(CALLBACK(R.radio, /obj/item/radio/proc/recalculateChannels), 0)
+
+ R.set_module_sprites(sprites)
+ addtimer(CALLBACK(R, /mob/living/silicon/robot/proc/choose_icon, R.module_sprites.len + 1, R.module_sprites), 0)
+
+/obj/item/robot_module/proc/build_equipment()
+ SHOULD_CALL_PARENT(TRUE)
+ for(var/thing in (modules|universal_equipment))
+ modules -= thing
+ if(ispath(thing, /obj/item))
+ modules += new thing(src)
+ else if(isitem(thing))
+ var/obj/item/I = thing
+ I.forceMove(src)
+ modules += I
+ else
+ log_debug("Invalid var type in [type] equipment creation - [thing]")
+ if(ispath(jetpack))
+ jetpack = new jetpack(src)
+
+/obj/item/robot_module/proc/finalize_equipment()
+ SHOULD_CALL_PARENT(TRUE)
+ for(var/obj/item/I in modules)
+ I.canremove = FALSE
+ if(jetpack)
+ if(istype(jetpack))
+ jetpack.canremove = FALSE
+ var/mob/living/silicon/robot/robit = loc
+ if(istype(robit))
+ jetpack.forceMove(robit)
+ robit.internals = jetpack
+ else
+ log_debug("Invalid var type in [type] jetpack creation - [jetpack]")
+ jetpack = null
+
+/obj/item/robot_module/proc/build_emag()
+ SHOULD_CALL_PARENT(TRUE)
+ if(ispath(emag))
+ emag = new emag(src)
+
+/obj/item/robot_module/proc/finalize_emag()
+ SHOULD_CALL_PARENT(TRUE)
+ if(emag)
+ if(istype(emag))
+ emag.canremove = FALSE
+ else
+ log_debug("Invalid var type in [type] emag creation - [emag]")
+ emag = null
+
+/obj/item/robot_module/proc/build_synths()
+ SHOULD_CALL_PARENT(TRUE)
+ for(var/thing in synths)
+ if(istype(thing, /datum/matter_synth))
+ continue
+ if(!ispath(thing, /datum/matter_synth))
+ log_debug("Invalid var type in [type] synth creation - [thing]")
+ continue
+ if(isnull(synths[thing]))
+ synths += new thing
+ else
+ synths += new thing(synths[thing])
+ synths -= thing
+
+/obj/item/robot_module/proc/finalize_synths()
+ SHOULD_CALL_PARENT(TRUE)
+ return
+
+/obj/item/robot_module/proc/Reset(var/mob/living/silicon/robot/R)
+ remove_camera_networks(R)
+ remove_languages(R)
+ remove_subsystems(R)
+ remove_status_flags(R)
+
+ if(R.radio)
+ R.radio.recalculateChannels()
+ R.choose_icon(0, R.set_module_sprites(list("Default" = "robot")))
+
+// This can qdel before init if spawned outside a mob, so
+// Destroy() needs to be a bit nuanced to avoid runtimes.
+/obj/item/robot_module/Destroy()
+ for(var/datum/thing in modules)
+ qdel(thing)
+// Robot icons unit test needs the module types list.
+#ifndef UNIT_TEST
+ modules = null
+#endif
+ for(var/datum/thing in synths)
+ qdel(thing)
+ synths = null
+ if(istype(emag))
+ QDEL_NULL(emag)
+ if(istype(jetpack))
+ QDEL_NULL(jetpack)
+ return ..()
+
+/obj/item/robot_module/emp_act(severity)
+ if(modules)
+ for(var/obj/O in modules)
+ O.emp_act(severity)
+ if(emag)
+ emag.emp_act(severity)
+ if(synths)
+ for(var/datum/matter_synth/S in synths)
+ S.emp_act(severity)
+ ..()
+ return
+
+/obj/item/robot_module/proc/respawn_consumable(var/mob/living/silicon/robot/R, var/rate)
+ if(!synths || !synths.len)
+ return
+
+ for(var/datum/matter_synth/T in synths)
+ T.add_charge(T.recharge_rate * rate)
+
+/obj/item/robot_module/proc/rebuild()//Rebuilds the list so it's possible to add/remove items from the module
+ var/list/temp_list = modules
+ modules = list()
+ for(var/obj/O in temp_list)
+ if(O)
+ modules += O
+
+/obj/item/robot_module/proc/add_languages(var/mob/living/silicon/robot/R)
+ // Stores the languages as they were before receiving the module, and whether they could be synthezized.
+ for(var/datum/language/language_datum in R.languages)
+ original_languages[language_datum] = (language_datum in R.speech_synthesizer_langs)
+
+ for(var/language in languages)
+ R.add_language(language, languages[language])
+
+/obj/item/robot_module/proc/remove_languages(var/mob/living/silicon/robot/R)
+ // Clear all added languages, whether or not we originally had them.
+ for(var/language in languages)
+ R.remove_language(language)
+
+ // Then add back all the original languages, and the relevant synthezising ability
+ for(var/original_language in original_languages)
+ R.add_language(original_language, original_languages[original_language])
+ original_languages.Cut()
+
+/obj/item/robot_module/proc/add_camera_networks(var/mob/living/silicon/robot/R)
+ if(R.camera && (NETWORK_ROBOTS in R.camera.network))
+ for(var/network in networks)
+ if(!(network in R.camera.network))
+ R.camera.add_network(network)
+ added_networks |= network
+
+/obj/item/robot_module/proc/remove_camera_networks(var/mob/living/silicon/robot/R)
+ if(R.camera)
+ R.camera.remove_networks(added_networks)
+ added_networks.Cut()
+
+/obj/item/robot_module/proc/add_subsystems(var/mob/living/silicon/robot/R)
+ R.verbs |= subsystems
+
+/obj/item/robot_module/proc/remove_subsystems(var/mob/living/silicon/robot/R)
+ R.verbs -= subsystems
+
+/obj/item/robot_module/proc/apply_status_flags(var/mob/living/silicon/robot/R)
+ if(!can_be_pushed)
+ R.status_flags &= ~CANPUSH
+
+/obj/item/robot_module/proc/remove_status_flags(var/mob/living/silicon/robot/R)
+ if(!can_be_pushed)
+ R.status_flags |= CANPUSH
+
+/obj/item/robot_module/proc/handle_shell(var/mob/living/silicon/robot/R)
+ if(R.braintype == BORG_BRAINTYPE_AI_SHELL)
+ channels = list(
+ "Medical" = 1,
+ "Engineering" = 1,
+ "Security" = 1,
+ "Service" = 1,
+ "Supply" = 1,
+ "Science" = 1,
+ "Command" = 1,
+ "Explorer" = 1
+ )
diff --git a/code/modules/mob/living/silicon/robot/robot_modules/event.dm b/code/modules/mob/living/silicon/robot/robot_modules/event.dm
index 61788e8a64..cc87f0b62a 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules/event.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules/event.dm
@@ -3,86 +3,68 @@
// The module that borgs on the surface have. Generally has a lot of useful tools in exchange for questionable loyalty to the crew.
/obj/item/robot_module/robot/lost
name = "lost robot module"
+ display_name = "Unregistered"
+ module_category = ROBOT_MODULE_TYPE_FLYING
+ unavailable_by_default = TRUE
hide_on_manifest = TRUE
sprites = list(
- "Drone" = "drone-lost"
- )
-
-/obj/item/robot_module/robot/lost/Initialize(var/ml)
+ "Drone" = "drone-lost"
+ )
+ modules = list(
+ /obj/item/melee/baton/shocker/robot,
+ /obj/item/handcuffs/cyborg,
+ /obj/item/borg/combat/shield,
+ /obj/item/healthanalyzer,
+ /obj/item/reagent_containers/borghypo/lost,
+ /obj/item/weldingtool/electric/mounted,
+ /obj/item/tool/screwdriver/cyborg,
+ /obj/item/tool/wrench/cyborg,
+ /obj/item/tool/wirecutters/cyborg,
+ /obj/item/multitool,
+ /obj/item/robotanalyzer,
+ /obj/item/stack/cable_coil/cyborg
+ )
+ emag = /obj/item/gun/energy/retro/mounted
+ synths = list(
+ /datum/matter_synth/wire
+ )
+/obj/item/robot_module/robot/lost/finalize_synths()
. = ..()
- if(. != INITIALIZE_HINT_NORMAL)
- return
-
- // Sec
- src.modules += new /obj/item/melee/baton/shocker/robot(src)
- src.modules += new /obj/item/handcuffs/cyborg(src)
- src.modules += new /obj/item/borg/combat/shield(src)
-
- // Med
- src.modules += new /obj/item/healthanalyzer(src)
- src.modules += new /obj/item/reagent_containers/borghypo/lost(src)
-
- // Engi
- src.modules += new /obj/item/weldingtool/electric/mounted(src)
- src.modules += new /obj/item/tool/screwdriver/cyborg(src)
- src.modules += new /obj/item/tool/wrench/cyborg(src)
- src.modules += new /obj/item/tool/wirecutters/cyborg(src)
- src.modules += new /obj/item/multitool(src)
-
- // Sci
- src.modules += new /obj/item/robotanalyzer(src)
-
- // Potato
- src.emag = new /obj/item/gun/energy/retro/mounted(src)
-
- var/datum/matter_synth/wire = new /datum/matter_synth/wire()
- synths += wire
-
- var/obj/item/stack/cable_coil/cyborg/C = new /obj/item/stack/cable_coil/cyborg(src)
+ var/datum/matter_synth/wire/wire = locate() in synths
+ var/obj/item/stack/cable_coil/cyborg/C = locate() in modules
C.synths = list(wire)
- src.modules += C
/obj/item/robot_module/robot/gravekeeper
name = "gravekeeper robot module"
+ display_name = "Gravekeeper"
+ unavailable_by_default = TRUE
hide_on_manifest = TRUE
sprites = list(
- "Drone" = "drone-gravekeeper",
- "Sleek" = "sleek-gravekeeper"
- )
-
-/obj/item/robot_module/robot/gravekeeper/Initialize(var/ml)
+ "Gravekeeper" = "sleek-gravekeeper"
+ )
+ modules = list(
+ /obj/item/melee/baton/shocker/robot,
+ /obj/item/borg/combat/shield,
+ /obj/item/weldingtool/electric/mounted,
+ /obj/item/tool/screwdriver/cyborg,
+ /obj/item/tool/wrench/cyborg,
+ /obj/item/material/minihoe,
+ /obj/item/material/knife/machete/hatchet,
+ /obj/item/analyzer/plant_analyzer,
+ /obj/item/storage/bag/plants,
+ /obj/item/robot_harvester,
+ /obj/item/shovel,
+ /obj/item/gripper/gravekeeper
+ )
+ emag = /obj/item/gun/energy/retro/mounted
+ synths = list(
+ /datum/matter_synth/wood = 25000
+ )
+/obj/item/robot_module/robot/gravekeeper/finalize_synths()
. = ..()
- if(. != INITIALIZE_HINT_NORMAL)
- return
-
- // For fending off animals and looters
- src.modules += new /obj/item/melee/baton/shocker/robot(src)
- src.modules += new /obj/item/borg/combat/shield(src)
-
- // For repairing gravemarkers
- src.modules += new /obj/item/weldingtool/electric/mounted(src)
- src.modules += new /obj/item/tool/screwdriver/cyborg(src)
- src.modules += new /obj/item/tool/wrench/cyborg(src)
-
- // For growing flowers
- src.modules += new /obj/item/material/minihoe(src)
- src.modules += new /obj/item/material/knife/machete/hatchet(src)
- src.modules += new /obj/item/analyzer/plant_analyzer(src)
- src.modules += new /obj/item/storage/bag/plants(src)
- src.modules += new /obj/item/robot_harvester(src)
-
- // For digging and beautifying graves
- src.modules += new /obj/item/shovel(src)
- src.modules += new /obj/item/gripper/gravekeeper(src)
-
- // For really persistent looters
- src.emag = new /obj/item/gun/energy/retro/mounted(src)
-
- var/datum/matter_synth/wood = new /datum/matter_synth/wood(25000)
- synths += wood
-
- var/obj/item/stack/material/cyborg/wood/W = new (src)
+ var/datum/matter_synth/wood/wood = locate() in synths
+ var/obj/item/stack/material/cyborg/wood/W = locate() in modules
W.synths = list(wood)
- src.modules += W
\ No newline at end of file
+ src.modules += W
diff --git a/code/modules/mob/living/silicon/robot/robot_modules/station.dm b/code/modules/mob/living/silicon/robot/robot_modules/station.dm
index b62fbe3089..ee6d8435f4 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules/station.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules/station.dm
@@ -1,222 +1,42 @@
-var/global/list/robot_modules = list(
- "Standard" = /obj/item/robot_module/robot/standard,
- "Service" = /obj/item/robot_module/robot/clerical/butler,
- "Clerical" = /obj/item/robot_module/robot/clerical/general,
- "Research" = /obj/item/robot_module/robot/research,
- "Miner" = /obj/item/robot_module/robot/miner,
- "Crisis" = /obj/item/robot_module/robot/medical/crisis,
- "Surgeon" = /obj/item/robot_module/robot/medical/surgeon,
- "Security" = /obj/item/robot_module/robot/security/general,
- "Combat" = /obj/item/robot_module/robot/security/combat,
- "Engineering" = /obj/item/robot_module/robot/engineering/general,
- "Janitor" = /obj/item/robot_module/robot/janitor
- )
-
-/obj/item/robot_module
- name = "robot module"
- icon = 'icons/obj/module.dmi'
- icon_state = "std_module"
- w_class = ITEMSIZE_NO_CONTAINER
- item_state = "std_mod"
- var/hide_on_manifest = FALSE
- var/channels = list()
- var/networks = list()
- var/languages = list(LANGUAGE_SOL_COMMON = 1, LANGUAGE_SIVIAN= 0, LANGUAGE_TRADEBAND = 1, LANGUAGE_UNATHI = 0, LANGUAGE_SIIK = 0, LANGUAGE_AKHANI = 0, LANGUAGE_SKRELLIAN = 0, LANGUAGE_GUTTER = 0, LANGUAGE_SCHECHI = 0, LANGUAGE_SIGN = 0, LANGUAGE_TERMINUS = 1, LANGUAGE_ZADDAT = 0)
- var/sprites = list()
- var/can_be_pushed = 1
- var/no_slip = 0
- var/list/modules = list()
- var/list/datum/matter_synth/synths = list()
- var/obj/item/emag = null
- var/obj/item/borg/upgrade/jetpack = null
- var/obj/item/borg/upgrade/advhealth = null
- var/list/subsystems = list()
- var/list/obj/item/borg/upgrade/supported_upgrades = list()
-
- // Bookkeeping
- var/list/original_languages = list()
- var/list/added_networks = list()
-
-/obj/item/robot_module/proc/hide_on_manifest()
- . = hide_on_manifest
-
-/obj/item/robot_module/Initialize(var/ml)
- . = ..()
- var/mob/living/silicon/robot/R = loc
- if(!istype(R))
- return INITIALIZE_HINT_QDEL
-
- R.module = src
- add_camera_networks(R)
- add_languages(R)
- add_subsystems(R)
- apply_status_flags(R)
- handle_shell(R)
-
- if(R.radio)
- addtimer(CALLBACK(R.radio, /obj/item/radio/proc/recalculateChannels), 0)
-
- R.set_module_sprites(sprites)
- addtimer(CALLBACK(R, /mob/living/silicon/robot/proc/choose_icon, R.module_sprites.len + 1, R.module_sprites), 0)
-
- for(var/obj/item/I in modules)
- I.canremove = 0
-
-/obj/item/robot_module/proc/Reset(var/mob/living/silicon/robot/R)
- remove_camera_networks(R)
- remove_languages(R)
- remove_subsystems(R)
- remove_status_flags(R)
-
- if(R.radio)
- R.radio.recalculateChannels()
- R.choose_icon(0, R.set_module_sprites(list("Default" = "robot")))
-
-/obj/item/robot_module/Destroy()
- for(var/module in modules)
- qdel(module)
- for(var/synth in synths)
- qdel(synth)
- modules.Cut()
- synths.Cut()
- qdel(emag)
- qdel(jetpack)
- emag = null
- jetpack = null
- return ..()
-
-/obj/item/robot_module/emp_act(severity)
- if(modules)
- for(var/obj/O in modules)
- O.emp_act(severity)
- if(emag)
- emag.emp_act(severity)
- if(synths)
- for(var/datum/matter_synth/S in synths)
- S.emp_act(severity)
- ..()
- return
-
-/obj/item/robot_module/proc/respawn_consumable(var/mob/living/silicon/robot/R, var/rate)
- if(!synths || !synths.len)
- return
-
- for(var/datum/matter_synth/T in synths)
- T.add_charge(T.recharge_rate * rate)
-
-/obj/item/robot_module/proc/rebuild()//Rebuilds the list so it's possible to add/remove items from the module
- var/list/temp_list = modules
- modules = list()
- for(var/obj/O in temp_list)
- if(O)
- modules += O
-
-/obj/item/robot_module/proc/add_languages(var/mob/living/silicon/robot/R)
- // Stores the languages as they were before receiving the module, and whether they could be synthezized.
- for(var/datum/language/language_datum in R.languages)
- original_languages[language_datum] = (language_datum in R.speech_synthesizer_langs)
-
- for(var/language in languages)
- R.add_language(language, languages[language])
-
-/obj/item/robot_module/proc/remove_languages(var/mob/living/silicon/robot/R)
- // Clear all added languages, whether or not we originally had them.
- for(var/language in languages)
- R.remove_language(language)
-
- // Then add back all the original languages, and the relevant synthezising ability
- for(var/original_language in original_languages)
- R.add_language(original_language, original_languages[original_language])
- original_languages.Cut()
-
-/obj/item/robot_module/proc/add_camera_networks(var/mob/living/silicon/robot/R)
- if(R.camera && (NETWORK_ROBOTS in R.camera.network))
- for(var/network in networks)
- if(!(network in R.camera.network))
- R.camera.add_network(network)
- added_networks |= network
-
-/obj/item/robot_module/proc/remove_camera_networks(var/mob/living/silicon/robot/R)
- if(R.camera)
- R.camera.remove_networks(added_networks)
- added_networks.Cut()
-
-/obj/item/robot_module/proc/add_subsystems(var/mob/living/silicon/robot/R)
- R.verbs |= subsystems
-
-/obj/item/robot_module/proc/remove_subsystems(var/mob/living/silicon/robot/R)
- R.verbs -= subsystems
-
-/obj/item/robot_module/proc/apply_status_flags(var/mob/living/silicon/robot/R)
- if(!can_be_pushed)
- R.status_flags &= ~CANPUSH
-
-/obj/item/robot_module/proc/remove_status_flags(var/mob/living/silicon/robot/R)
- if(!can_be_pushed)
- R.status_flags |= CANPUSH
-
-/obj/item/robot_module/proc/handle_shell(var/mob/living/silicon/robot/R)
- if(R.braintype == BORG_BRAINTYPE_AI_SHELL)
- channels = list(
- "Medical" = 1,
- "Engineering" = 1,
- "Security" = 1,
- "Service" = 1,
- "Supply" = 1,
- "Science" = 1,
- "Command" = 1,
- "Explorer" = 1
- )
-
-// Cyborgs (non-drones), default loadout. This will be given to every module.
-/obj/item/robot_module/robot/Initialize()
-
- . = ..()
- if(. != INITIALIZE_HINT_NORMAL)
- return
-
- src.modules += new /obj/item/flash/robot(src)
- src.modules += new /obj/item/tool/crowbar/cyborg(src)
- src.modules += new /obj/item/extinguisher(src)
- src.modules += new /obj/item/gps/robot(src)
-
/obj/item/robot_module/robot/standard
name = "standard robot module"
+ display_name = "Standard"
sprites = list(
- "M-USE NanoTrasen" = "robot",
- "Cabeiri" = "eyebot-standard",
- "Haruka" = "marinaSD",
- "Usagi" = "tallflower",
- "Telemachus" = "toiletbot",
- "WTOperator" = "sleekstandard",
- "WTOmni" = "omoikane",
- "XI-GUS" = "spider",
- "XI-ALP" = "heavyStandard",
- "Basic" = "robot_old",
- "Android" = "droid",
- "Drone" = "drone-standard",
- "Insekt" = "insekt-Default",
- "Usagi-II" = "tall2standard",
- "Pyralis" = "Glitterfly-Standard",
- "Decapod" = "decapod-Standard",
- "Pneuma" = "pneuma-Standard",
- "Tower" = "drider-Standard"
- )
+ "M-USE NanoTrasen" = "robot",
+ "Haruka" = "marinaSD",
+ "Usagi" = "tallflower",
+ "Telemachus" = "toiletbot",
+ "WTOperator" = "sleekstandard",
+ "WTOmni" = "omoikane",
+ "XI-GUS" = "spider",
+ "XI-ALP" = "heavyStandard",
+ "Basic" = "robot_old",
+ "Android" = "droid",
+ "Insekt" = "insekt-Default",
+ "Usagi-II" = "tall2standard",
+ "Decapod" = "decapod-Standard",
+ "Pneuma" = "pneuma-Standard",
+ "Tower" = "drider-Standard"
+ )
+ modules = list(
+ /obj/item/melee/baton/loaded,
+ /obj/item/tool/wrench/cyborg,
+ /obj/item/healthanalyzer
+ )
+ emag = /obj/item/melee/energy/sword
-
-/obj/item/robot_module/robot/standard/Initialize()
-
- . = ..()
- if(. != INITIALIZE_HINT_NORMAL)
- return
-
- src.modules += new /obj/item/melee/baton/loaded(src)
- src.modules += new /obj/item/tool/wrench/cyborg(src)
- src.modules += new /obj/item/healthanalyzer(src)
- src.emag = new /obj/item/melee/energy/sword(src)
+/obj/item/robot_module/robot/standard/flying
+ module_category = ROBOT_MODULE_TYPE_FLYING
+ can_be_pushed = TRUE
+ sprites = list(
+ "Drone" = "drone-standard",
+ "Pyralis" = "Glitterfly-Standard",
+ "Cabeiri" = "eyebot-standard"
+ )
/obj/item/robot_module/robot/medical
name = "medical robot module"
+ display_name = "Medical"
channels = list("Medical" = 1)
networks = list(NETWORK_MEDICAL)
subsystems = list(/mob/living/silicon/proc/subsystem_crew_monitor)
@@ -224,68 +44,76 @@ var/global/list/robot_modules = list(
/obj/item/robot_module/robot/medical/surgeon
name = "surgeon robot module"
+ display_name = "Surgeon"
sprites = list(
- "M-USE NanoTrasen" = "robotMedi",
- "Cabeiri" = "eyebot-medical",
- "Haruka" = "marinaMD",
- "Minako" = "arachne",
- "Usagi" = "tallwhite",
- "Telemachus" = "toiletbotsurgeon",
- "WTOperator" = "sleekcmo",
- "XI-ALP" = "heavyMed",
- "Basic" = "Medbot",
- "Advanced Droid" = "droid-medical",
- "Needles" = "medicalrobot",
- "Drone" = "drone-surgery",
- "Handy" = "handy-med",
- "Insekt" = "insekt-Med",
- "Usagi-II" = "tall2medical",
- "Pyralis" = "Glitterfly-Surgeon",
- "Decapod" = "decapod-Surgeon",
- "Pneuma" = "pneuma-Surgeon",
- "Tower" = "drider-Surgeon"
- )
+ "M-USE NanoTrasen" = "robotMedi",
+ "Haruka" = "marinaMD",
+ "Minako" = "arachne",
+ "Usagi" = "tallwhite",
+ "Telemachus" = "toiletbotsurgeon",
+ "WTOperator" = "sleekcmo",
+ "XI-ALP" = "heavyMed",
+ "Basic" = "Medbot",
+ "Advanced Droid" = "droid-medical",
+ "Needles" = "medicalrobot",
+ "Insekt" = "insekt-Med",
+ "Usagi-II" = "tall2medical",
+ "Decapod" = "decapod-Surgeon",
+ "Pneuma" = "pneuma-Surgeon",
+ "Tower" = "drider-Surgeon"
+ )
+ modules = list(
+ /obj/item/healthanalyzer,
+ /obj/item/reagent_containers/borghypo/surgeon,
+ /obj/item/autopsy_scanner,
+ /obj/item/surgical/scalpel/cyborg,
+ /obj/item/surgical/hemostat/cyborg,
+ /obj/item/surgical/retractor/cyborg,
+ /obj/item/surgical/cautery/cyborg,
+ /obj/item/surgical/bonegel/cyborg,
+ /obj/item/surgical/FixOVein/cyborg,
+ /obj/item/surgical/bonesetter/cyborg,
+ /obj/item/surgical/circular_saw/cyborg,
+ /obj/item/surgical/surgicaldrill/cyborg,
+ /obj/item/gripper/no_use/organ,
+ /obj/item/gripper/medical,
+ /obj/item/shockpaddles/robot,
+ /obj/item/reagent_containers/dropper,
+ /obj/item/reagent_containers/syringe,
+ /obj/item/stack/nanopaste,
+ /obj/item/stack/medical/advanced/bruise_pack
+ )
+ emag = /obj/item/reagent_containers/spray
+ synths = list(
+ /datum/matter_synth/medicine = 10000
+ )
-/obj/item/robot_module/robot/medical/surgeon/Initialize()
+/obj/item/robot_module/robot/medical/surgeon/flying
+ module_category = ROBOT_MODULE_TYPE_FLYING
+ can_be_pushed = TRUE
+ sprites = list(
+ "Handy" = "handy-med",
+ "Drone" = "drone-surgery",
+ "Eyebot" = "eyebot-medical",
+ "Pyralis" = "Glitterfly-Surgeon"
+ )
+/obj/item/robot_module/robot/medical/surgeon/finalize_emag()
. = ..()
- if(. != INITIALIZE_HINT_NORMAL)
- return
+ emag.reagents.add_reagent("pacid", 250)
+ emag.name = "polyacid spray"
- src.modules += new /obj/item/healthanalyzer(src)
- src.modules += new /obj/item/reagent_containers/borghypo/surgeon(src)
- src.modules += new /obj/item/autopsy_scanner(src)
- src.modules += new /obj/item/surgical/scalpel/cyborg(src)
- src.modules += new /obj/item/surgical/hemostat/cyborg(src)
- src.modules += new /obj/item/surgical/retractor/cyborg(src)
- src.modules += new /obj/item/surgical/cautery/cyborg(src)
- src.modules += new /obj/item/surgical/bonegel/cyborg(src)
- src.modules += new /obj/item/surgical/FixOVein/cyborg(src)
- src.modules += new /obj/item/surgical/bonesetter/cyborg(src)
- src.modules += new /obj/item/surgical/circular_saw/cyborg(src)
- src.modules += new /obj/item/surgical/surgicaldrill/cyborg(src)
- src.modules += new /obj/item/gripper/no_use/organ(src)
- src.modules += new /obj/item/gripper/medical(src)
- src.modules += new /obj/item/shockpaddles/robot(src)
- src.modules += new /obj/item/reagent_containers/dropper(src) // Allows surgeon borg to fix necrosis
- src.modules += new /obj/item/reagent_containers/syringe(src)
- src.emag = new /obj/item/reagent_containers/spray(src)
- src.emag.reagents.add_reagent("pacid", 250)
- src.emag.name = "Polyacid spray"
-
- var/datum/matter_synth/medicine = new /datum/matter_synth/medicine(10000)
- synths += medicine
-
- var/obj/item/stack/nanopaste/N = new /obj/item/stack/nanopaste(src)
- var/obj/item/stack/medical/advanced/bruise_pack/B = new /obj/item/stack/medical/advanced/bruise_pack(src)
+/obj/item/robot_module/robot/medical/surgeon/finalize_synths()
+ . = ..()
+ var/datum/matter_synth/medicine/medicine = locate() in synths
+ var/obj/item/stack/nanopaste/N = locate() in modules
N.uses_charge = 1
N.charge_costs = list(1000)
N.synths = list(medicine)
+ var/obj/item/stack/medical/advanced/bruise_pack/B = locate() in modules
B.uses_charge = 1
B.charge_costs = list(1000)
B.synths = list(medicine)
- src.modules += N
- src.modules += B
/obj/item/robot_module/robot/medical/surgeon/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
@@ -304,66 +132,74 @@ var/global/list/robot_modules = list(
/obj/item/robot_module/robot/medical/crisis
name = "crisis robot module"
+ display_name = "Crisis"
sprites = list(
- "M-USE NanoTrasen" = "robotMedi",
- "Cabeiri" = "eyebot-medical",
- "Haruka" = "marinaMD",
- "Minako" = "arachne",
- "Usagi" = "tallwhite",
- "Telemachus" = "toiletbotmedical",
- "WTOperator" = "sleekmedic",
- "XI-ALP" = "heavyMed",
- "Basic" = "Medbot",
- "Advanced Droid" = "droid-medical",
- "Needles" = "medicalrobot",
- "Drone - Medical" = "drone-medical",
- "Drone - Chemistry" = "drone-chemistry",
- "Insekt" = "insekt-Med",
- "Usagi-II" = "tall2medical",
- "Pyralis" = "Glitterfly-Crisis",
- "Decapod" = "decapod-Crisis",
- "Pneuma" = "pneuma-Crisis",
- "Tower" = "drider-Crisis"
- )
+ "M-USE NanoTrasen" = "robotMedi",
+ "Haruka" = "marinaMD",
+ "Minako" = "arachne",
+ "Usagi" = "tallwhite",
+ "Telemachus" = "toiletbotmedical",
+ "WTOperator" = "sleekmedic",
+ "XI-ALP" = "heavyMed",
+ "Basic" = "Medbot",
+ "Advanced Droid" = "droid-medical",
+ "Needles" = "medicalrobot",
+ "Insekt" = "insekt-Med",
+ "Usagi-II" = "tall2medical",
+ "Decapod" = "decapod-Crisis",
+ "Pneuma" = "pneuma-Crisis",
+ "Tower" = "drider-Crisis"
+ )
+ modules = list(
+ /obj/item/healthanalyzer,
+ /obj/item/reagent_scanner/adv,
+ /obj/item/roller_holder,
+ /obj/item/reagent_containers/borghypo/crisis,
+ /obj/item/reagent_containers/glass/beaker/large,
+ /obj/item/reagent_containers/dropper/industrial,
+ /obj/item/reagent_containers/syringe,
+ /obj/item/gripper/no_use/organ,
+ /obj/item/gripper/medical,
+ /obj/item/shockpaddles/robot,
+ /obj/item/stack/medical/advanced/ointment,
+ /obj/item/stack/medical/advanced/bruise_pack,
+ /obj/item/stack/medical/splint
+ )
+ emag = /obj/item/reagent_containers/spray
+ synths = list(
+ /datum/matter_synth/medicine = 15000
+ )
-/obj/item/robot_module/robot/medical/crisis/Initialize()
+/obj/item/robot_module/robot/medical/crisis/flying
+ module_category = ROBOT_MODULE_TYPE_FLYING
+ can_be_pushed = TRUE
+ sprites = list(
+ "Drone" = "drone-medical",
+ "Chemistry Drone" = "drone-chemistry",
+ "Eyebot" = "eyebot-medical",
+ "Pyralis" = "Glitterfly-Crisis"
+ )
+/obj/item/robot_module/robot/medical/crisis/finalize_emag()
. = ..()
- if(. != INITIALIZE_HINT_NORMAL)
- return
+ emag.reagents.add_reagent("pacid", 250)
+ emag.name = "polyacid spray"
- src.modules += new /obj/item/healthanalyzer(src)
- src.modules += new /obj/item/reagent_scanner/adv(src)
- src.modules += new /obj/item/roller_holder(src)
- src.modules += new /obj/item/reagent_containers/borghypo/crisis(src)
- src.modules += new /obj/item/reagent_containers/glass/beaker/large(src)
- src.modules += new /obj/item/reagent_containers/dropper/industrial(src)
- src.modules += new /obj/item/reagent_containers/syringe(src)
- src.modules += new /obj/item/gripper/no_use/organ(src)
- src.modules += new /obj/item/gripper/medical(src)
- src.modules += new /obj/item/shockpaddles/robot(src)
- src.emag = new /obj/item/reagent_containers/spray(src)
- src.emag.reagents.add_reagent("pacid", 250)
- src.emag.name = "Polyacid spray"
-
- var/datum/matter_synth/medicine = new /datum/matter_synth/medicine(15000)
- synths += medicine
-
- var/obj/item/stack/medical/advanced/ointment/O = new /obj/item/stack/medical/advanced/ointment(src)
- var/obj/item/stack/medical/advanced/bruise_pack/B = new /obj/item/stack/medical/advanced/bruise_pack(src)
- var/obj/item/stack/medical/splint/S = new /obj/item/stack/medical/splint(src)
+/obj/item/robot_module/robot/medical/crisis/finalize_synths()
+ . = ..()
+ var/datum/matter_synth/medicine/medicine = locate() in synths
+ var/obj/item/stack/medical/advanced/ointment/O = locate() in modules
O.uses_charge = 1
O.charge_costs = list(1000)
O.synths = list(medicine)
+ var/obj/item/stack/medical/advanced/bruise_pack/B = locate() in modules
B.uses_charge = 1
B.charge_costs = list(1000)
B.synths = list(medicine)
+ var/obj/item/stack/medical/splint/S = locate() in modules
S.uses_charge = 1
S.charge_costs = list(1000)
S.synths = list(medicine)
- src.modules += O
- src.modules += B
- src.modules += S
/obj/item/robot_module/robot/medical/crisis/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
@@ -380,171 +216,164 @@ var/global/list/robot_modules = list(
..()
-
/obj/item/robot_module/robot/engineering
name = "engineering robot module"
+ display_name = "Engineering"
channels = list("Engineering" = 1)
networks = list(NETWORK_ENGINEERING)
subsystems = list(/mob/living/silicon/proc/subsystem_power_monitor)
sprites = list(
- "M-USE NanoTrasen" = "robotEngi",
- "Cabeiri" = "eyebot-engineering",
- "Haruka" = "marinaENG",
- "Usagi" = "tallyellow",
- "Telemachus" = "toiletbotengineering",
- "WTOperator" = "sleekce",
- "XI-GUS" = "spidereng",
- "XI-ALP" = "heavyEng",
- "Basic" = "Engineering",
- "Antique" = "engineerrobot",
- "Landmate" = "landmate",
- "Landmate - Treaded" = "engiborg+tread",
- "Drone" = "drone-engineer",
- "Treadwell" = "treadwell",
- "Handy" = "handy-engineer",
- "Usagi-II" = "tall2engineer",
- "Pyralis" = "Glitterfly-Engineering",
- "Decapod" = "decapod-Engineering",
- "Pneuma" = "pneuma-Engineering",
- "Tower" = "drider-Engineering"
- )
-
-/obj/item/robot_module/robot/engineering/general/Initialize()
+ "M-USE NanoTrasen" = "robotEngi",
+ "Haruka" = "marinaENG",
+ "Usagi" = "tallyellow",
+ "Telemachus" = "toiletbotengineering",
+ "WTOperator" = "sleekce",
+ "XI-GUS" = "spidereng",
+ "XI-ALP" = "heavyEng",
+ "Basic" = "Engineering",
+ "Antique" = "engineerrobot",
+ "Landmate" = "landmate",
+ "Landmate - Treaded" = "engiborg+tread",
+ "Treadwell" = "treadwell",
+ "Usagi-II" = "tall2engineer",
+ "Decapod" = "decapod-Engineering",
+ "Pneuma" = "pneuma-Engineering",
+ "Tower" = "drider-Engineering"
+ )
+ modules = list(
+ /obj/item/borg/sight/meson,
+ /obj/item/weldingtool/electric/mounted/cyborg,
+ /obj/item/tool/screwdriver/cyborg,
+ /obj/item/tool/wrench/cyborg,
+ /obj/item/tool/wirecutters/cyborg,
+ /obj/item/multitool,
+ /obj/item/t_scanner,
+ /obj/item/analyzer,
+ /obj/item/taperoll/engineering,
+ /obj/item/gripper,
+ /obj/item/gripper/circuit,
+ /obj/item/lightreplacer,
+ /obj/item/pipe_painter,
+ /obj/item/floor_painter,
+ /obj/item/inflatable_dispenser/robot,
+ /obj/item/geiger,
+ /obj/item/rcd/electric/mounted/borg,
+ /obj/item/pipe_dispenser,
+ /obj/item/pickaxe/plasmacutter,
+ /obj/item/gripper/no_use/loader,
+ /obj/item/matter_decompiler,
+ /obj/item/stack/material/cyborg/steel,
+ /obj/item/stack/material/cyborg/glass,
+ /obj/item/stack/rods/cyborg,
+ /obj/item/stack/cable_coil/cyborg,
+ /obj/item/stack/material/cyborg/plasteel,
+ /obj/item/stack/tile/floor/cyborg,
+ /obj/item/stack/tile/roofing/cyborg,
+ /obj/item/stack/material/cyborg/glass/reinforced,
+ /obj/item/stack/tile/wood/cyborg,
+ /obj/item/stack/material/cyborg/wood,
+ /obj/item/stack/material/cyborg/plastic
+ )
+ emag = /obj/item/melee/baton/robot/arm
+ synths = list(
+ /datum/matter_synth/metal = 40000,
+ /datum/matter_synth/glass = 40000,
+ /datum/matter_synth/plasteel = 20000,
+ /datum/matter_synth/wood = 40000,
+ /datum/matter_synth/plastic = 40000,
+ /datum/matter_synth/wire
+ )
+/obj/item/robot_module/robot/engineering/finalize_synths()
. = ..()
- if(. != INITIALIZE_HINT_NORMAL)
- return
-
- src.modules += new /obj/item/borg/sight/meson(src)
- src.modules += new /obj/item/weldingtool/electric/mounted/cyborg(src)
- src.modules += new /obj/item/tool/screwdriver/cyborg(src)
- src.modules += new /obj/item/tool/wrench/cyborg(src)
- src.modules += new /obj/item/tool/wirecutters/cyborg(src)
- src.modules += new /obj/item/multitool(src)
- src.modules += new /obj/item/t_scanner(src)
- src.modules += new /obj/item/analyzer(src)
- src.modules += new /obj/item/taperoll/engineering(src)
- src.modules += new /obj/item/gripper(src)
- src.modules += new /obj/item/gripper/circuit(src)
- src.modules += new /obj/item/lightreplacer(src)
- src.modules += new /obj/item/pipe_painter(src)
- src.modules += new /obj/item/floor_painter(src)
- src.modules += new /obj/item/inflatable_dispenser/robot(src)
- src.emag = new /obj/item/melee/baton/robot/arm(src)
- src.modules += new /obj/item/geiger(src)
- src.modules += new /obj/item/rcd/electric/mounted/borg(src)
- src.modules += new /obj/item/pipe_dispenser(src)
- src.modules += new /obj/item/pickaxe/plasmacutter(src)
- src.modules += new /obj/item/gripper/no_use/loader(src)
-
- var/datum/matter_synth/metal = new /datum/matter_synth/metal(40000)
- var/datum/matter_synth/glass = new /datum/matter_synth/glass(40000)
- var/datum/matter_synth/plasteel = new /datum/matter_synth/plasteel(20000)
- var/datum/matter_synth/wood = new /datum/matter_synth/wood(40000)
- var/datum/matter_synth/plastic = new /datum/matter_synth/plastic(40000)
-
- var/datum/matter_synth/wire = new /datum/matter_synth/wire()
- synths += metal
- synths += glass
- synths += plasteel
- synths += wood
- synths += plastic
- synths += wire
-
- var/obj/item/matter_decompiler/MD = new /obj/item/matter_decompiler(src)
+ var/datum/matter_synth/metal/metal = locate() in synths
+ var/datum/matter_synth/glass/glass = locate() in synths
+ var/datum/matter_synth/plasteel/plasteel = locate() in synths
+ var/datum/matter_synth/wood/wood = locate() in synths
+ var/datum/matter_synth/plastic/plastic = locate() in synths
+ var/datum/matter_synth/wire/wire = locate() in synths
+ var/obj/item/matter_decompiler/MD = locate() in modules
MD.metal = metal
MD.glass = glass
- src.modules += MD
-
- var/obj/item/stack/material/cyborg/steel/M = new (src)
+ var/obj/item/stack/material/cyborg/steel/M = locate() in modules
M.synths = list(metal)
- src.modules += M
-
- var/obj/item/stack/material/cyborg/glass/G = new (src)
+ var/obj/item/stack/material/cyborg/glass/G = locate() in modules
G.synths = list(glass)
- src.modules += G
-
- var/obj/item/stack/rods/cyborg/R = new /obj/item/stack/rods/cyborg(src)
+ var/obj/item/stack/rods/cyborg/R = locate() in modules
R.synths = list(metal)
- src.modules += R
-
- var/obj/item/stack/cable_coil/cyborg/C = new /obj/item/stack/cable_coil/cyborg(src)
+ var/obj/item/stack/cable_coil/cyborg/C =locate() in modules
C.synths = list(wire)
- src.modules += C
-
- var/obj/item/stack/material/cyborg/plasteel/PS = new (src)
+ var/obj/item/stack/material/cyborg/plasteel/PS = locate() in modules
PS.synths = list(plasteel)
- src.modules += PS
-
- var/obj/item/stack/tile/floor/cyborg/S = new /obj/item/stack/tile/floor/cyborg(src)
+ var/obj/item/stack/tile/floor/cyborg/S = locate() in modules
S.synths = list(metal)
- src.modules += S
-
- var/obj/item/stack/tile/roofing/cyborg/CT = new /obj/item/stack/tile/roofing/cyborg(src)
+ var/obj/item/stack/tile/roofing/cyborg/CT = locate() in modules
CT.synths = list(metal)
- src.modules += CT
-
- var/obj/item/stack/material/cyborg/glass/reinforced/RG = new (src)
+ var/obj/item/stack/material/cyborg/glass/reinforced/RG = locate() in modules
RG.synths = list(metal, glass)
- src.modules += RG
-
- var/obj/item/stack/tile/wood/cyborg/WT = new /obj/item/stack/tile/wood/cyborg(src)
+ var/obj/item/stack/tile/wood/cyborg/WT = locate() in modules
WT.synths = list(wood)
- src.modules += WT
-
- var/obj/item/stack/material/cyborg/wood/W = new (src)
+ var/obj/item/stack/material/cyborg/wood/W = locate() in modules
W.synths = list(wood)
- src.modules += W
-
- var/obj/item/stack/material/cyborg/plastic/PL = new (src)
+ var/obj/item/stack/material/cyborg/plastic/PL = locate() in modules
PL.synths = list(plastic)
- src.modules += PL
+
+/obj/item/robot_module/robot/engineering/flying
+ module_category = ROBOT_MODULE_TYPE_FLYING
+ can_be_pushed = TRUE
+ sprites = list(
+ "Handy" = "handy-engineer",
+ "Drone" = "drone-engineer",
+ "Eyebot" = "eyebot-engineering",
+ "Pyralis" = "Glitterfly-Engineering",
+ )
/obj/item/robot_module/robot/security
name = "security robot module"
+ display_name = "Security"
channels = list("Security" = 1)
networks = list(NETWORK_SECURITY)
subsystems = list(/mob/living/silicon/proc/subsystem_crew_monitor)
can_be_pushed = 0
supported_upgrades = list(/obj/item/borg/upgrade/tasercooler)
-
-/obj/item/robot_module/robot/security/general
+ modules = list(
+ /obj/item/handcuffs/cyborg,
+ /obj/item/melee/baton/robot,
+ /obj/item/gun/energy/taser/mounted/cyborg,
+ /obj/item/gun/energy/taser/xeno/sec/robot,
+ /obj/item/taperoll/police,
+ /obj/item/reagent_containers/spray/pepper,
+ /obj/item/gripper/security
+ )
+ emag = /obj/item/gun/energy/laser/mounted
sprites = list(
- "M-USE NanoTrasen" = "robotSecy",
- "Cabeiri" = "eyebot-security",
- "Cerberus" = "bloodhound",
- "Cerberus - Treaded" = "treadhound",
- "Haruka" = "marinaSC",
- "Usagi" = "tallred",
- "Telemachus" = "toiletbotsecurity",
- "WTOperator" = "sleeksecurity",
- "XI-GUS" = "spidersec",
- "XI-ALP" = "heavySec",
- "Basic" = "secborg",
- "Black Knight" = "securityrobot",
- "Drone" = "drone-sec",
- "Insekt" = "insekt-Sec",
- "Usagi-II" = "tall2security",
- "Pyralis" = "Glitterfly-Security",
- "Decapod" = "decapod-Security",
- "Pneuma" = "pneuma-Security",
- "Tower" = "drider-Security"
- )
+ "M-USE NanoTrasen" = "robotSecy",
+ "Cerberus" = "bloodhound",
+ "Cerberus - Treaded" = "treadhound",
+ "Haruka" = "marinaSC",
+ "Usagi" = "tallred",
+ "Telemachus" = "toiletbotsecurity",
+ "WTOperator" = "sleeksecurity",
+ "XI-GUS" = "spidersec",
+ "XI-ALP" = "heavySec",
+ "Basic" = "secborg",
+ "Hedge Knight" = "Security",
+ "Black Knight" = "securityrobot",
+ "Insekt" = "insekt-Sec",
+ "Usagi-II" = "tall2security",
+ "Decapod" = "decapod-Security",
+ "Pneuma" = "pneuma-Security",
+ "Tower" = "drider-Security"
+ )
-/obj/item/robot_module/robot/security/general/Initialize()
-
- . = ..()
- if(. != INITIALIZE_HINT_NORMAL)
- return
-
- src.modules += new /obj/item/handcuffs/cyborg(src)
- src.modules += new /obj/item/melee/baton/robot(src)
- src.modules += new /obj/item/gun/energy/taser/mounted/cyborg(src)
- src.modules += new /obj/item/gun/energy/taser/xeno/sec/robot(src)
- src.modules += new /obj/item/taperoll/police(src)
- src.modules += new /obj/item/reagent_containers/spray/pepper(src)
- src.modules += new /obj/item/gripper/security(src)
- src.emag = new /obj/item/gun/energy/laser/mounted(src)
+/obj/item/robot_module/robot/security/flying
+ module_category = ROBOT_MODULE_TYPE_FLYING
+ can_be_pushed = TRUE
+ sprites = list(
+ "Pyralis" = "Glitterfly-Security",
+ "Drone" = "drone-sec",
+ "Eyebot" = "eyebot-security"
+ )
/obj/item/robot_module/robot/security/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
var/obj/item/flash/F = locate() in src.modules
@@ -563,39 +392,45 @@ var/global/list/robot_modules = list(
/obj/item/robot_module/robot/janitor
name = "janitorial robot module"
+ display_name = "Janitor"
channels = list("Service" = 1)
sprites = list(
- "M-USE NanoTrasen" = "robotJani",
- "Arachne" = "crawler",
- "Cabeiri" = "eyebot-janitor",
- "Haruka" = "marinaJN",
- "Telemachus" = "toiletbotjanitor",
- "WTOperator" = "sleekjanitor",
- "XI-ALP" = "heavyRes",
- "Basic" = "JanBot2",
- "Mopbot" = "janitorrobot",
- "Mop Gear Rex" = "mopgearrex",
- "Drone" = "drone-janitor",
- "Usagi-II" = "tall2janitor",
- "Pyralis" = "Glitterfly-Janitor",
- "Decapod" = "decapod-Janitor",
- "Pneuma" = "pneuma-Janitor",
- "Tower" = "drider-Janitor"
- )
+ "M-USE NanoTrasen" = "robotJani",
+ "Arachne" = "crawler",
+ "Haruka" = "marinaJN",
+ "Telemachus" = "toiletbotjanitor",
+ "WTOperator" = "sleekjanitor",
+ "XI-ALP" = "heavyRes",
+ "Basic" = "JanBot2",
+ "Mopbot" = "janitorrobot",
+ "Mop Gear Rex" = "mopgearrex",
+ "Usagi" = "tallblue",
+ "Usagi-II" = "tall2janitor",
+ "Decapod" = "decapod-Janitor",
+ "Pneuma" = "pneuma-Janitor",
+ "Tower" = "drider-Janitor"
+ )
+ modules = list(
+ /obj/item/soap/nanotrasen,
+ /obj/item/storage/bag/trash,
+ /obj/item/mop,
+ /obj/item/lightreplacer
+ )
+ emag = /obj/item/reagent_containers/spray
-/obj/item/robot_module/robot/janitor/Initialize()
+/obj/item/robot_module/robot/janitor/flying
+ module_category = ROBOT_MODULE_TYPE_FLYING
+ can_be_pushed = TRUE
+ sprites = list(
+ "Drone" = "drone-janitor",
+ "Pyralis" = "Glitterfly-Janitor",
+ "Cabeiri" = "eyebot-janitor"
+ )
+/obj/item/robot_module/robot/janitor/finalize_emag()
. = ..()
- if(. != INITIALIZE_HINT_NORMAL)
- return
-
- src.modules += new /obj/item/soap/nanotrasen(src)
- src.modules += new /obj/item/storage/bag/trash(src)
- src.modules += new /obj/item/mop(src)
- src.modules += new /obj/item/lightreplacer(src)
- src.emag = new /obj/item/reagent_containers/spray(src)
- src.emag.reagents.add_reagent("lube", 250)
- src.emag.name = "Lube spray"
+ emag.reagents.add_reagent("lube", 250)
+ emag.name = "lube spray"
/obj/item/robot_module/robot/janitor/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
var/obj/item/lightreplacer/LR = locate() in src.modules
@@ -609,125 +444,135 @@ var/global/list/robot_modules = list(
channels = list(
"Service" = 1,
"Command" = 1
- )
+ )
languages = list(
- LANGUAGE_SOL_COMMON = 1,
- LANGUAGE_SIVIAN = 1,
- LANGUAGE_UNATHI = 1,
- LANGUAGE_SIIK = 1,
- LANGUAGE_AKHANI = 1,
- LANGUAGE_SKRELLIAN = 1,
- LANGUAGE_SKRELLIANFAR = 0,
- LANGUAGE_ROOTLOCAL = 0,
- LANGUAGE_TRADEBAND = 1,
- LANGUAGE_GUTTER = 1,
- LANGUAGE_SCHECHI = 1,
- LANGUAGE_EAL = 1,
- LANGUAGE_TERMINUS = 1,
- LANGUAGE_SIGN = 0,
- LANGUAGE_ZADDAT = 1,
- )
+ LANGUAGE_SOL_COMMON = 1,
+ LANGUAGE_SIVIAN = 1,
+ LANGUAGE_UNATHI = 1,
+ LANGUAGE_SIIK = 1,
+ LANGUAGE_AKHANI = 1,
+ LANGUAGE_SKRELLIAN = 1,
+ LANGUAGE_SKRELLIANFAR = 0,
+ LANGUAGE_ROOTLOCAL = 0,
+ LANGUAGE_TRADEBAND = 1,
+ LANGUAGE_GUTTER = 1,
+ LANGUAGE_SCHECHI = 1,
+ LANGUAGE_EAL = 1,
+ LANGUAGE_TERMINUS = 1,
+ LANGUAGE_SIGN = 0,
+ LANGUAGE_ZADDAT = 1,
+ )
/obj/item/robot_module/robot/clerical/butler
+ display_name = "Butler"
sprites = list(
- "M-USE NanoTrasen" = "robotServ",
- "Cabeiri" = "eyebot-standard",
- "Haruka" = "marinaSV",
- "Michiru" = "maidbot",
- "Usagi" = "tallgreen",
- "Telemachus" = "toiletbot",
- "WTOperator" = "sleekservice",
- "WTOmni" = "omoikane",
- "XI-GUS" = "spider",
- "XI-ALP" = "heavyServ",
- "Standard" = "Service2",
- "Waitress" = "Service",
- "Bro" = "Brobot",
- "Rich" = "maximillion",
- "Drone - Service" = "drone-service",
- "Drone - Hydro" = "drone-hydro",
- "Usagi-II" = "tall2service",
- "Pyralis" = "Glitterfly-Service",
- "Decapod" = "decapod-Service",
- "Pneuma" = "pneuma-Service",
- "Tower" = "drider-Service"
- )
+ "M-USE NanoTrasen" = "robotServ",
+ "Haruka" = "marinaSV",
+ "Michiru" = "maidbot",
+ "Usagi" = "tallgreen",
+ "Telemachus" = "toiletbot",
+ "WTOperator" = "sleekservice",
+ "WTOmni" = "omoikane",
+ "XI-GUS" = "spider",
+ "XI-ALP" = "heavyServ",
+ "Standard" = "Service2",
+ "Waitress" = "Service",
+ "Bro" = "Brobot",
+ "Usagi" = "tall2clown",
+ "Rich" = "maximillion",
+ "Usagi-II" = "tall2service",
+ "Decapod" = "decapod-Service",
+ "Pneuma" = "pneuma-Service",
+ "Tower" = "drider-Service"
+ )
+ modules = list(
+ /obj/item/gripper/service,
+ /obj/item/reagent_containers/glass/bucket,
+ /obj/item/material/minihoe,
+ /obj/item/material/knife/machete/hatchet,
+ /obj/item/analyzer/plant_analyzer,
+ /obj/item/storage/bag/plants,
+ /obj/item/robot_harvester,
+ /obj/item/material/knife,
+ /obj/item/material/kitchen/rollingpin,
+ /obj/item/multitool,
+ /obj/item/reagent_containers/dropper/industrial,
+ /obj/item/tray/robotray,
+ /obj/item/reagent_containers/borghypo/service,
+ /obj/item/flame/lighter/zippo,
+ /obj/item/rsf
+ )
+ emag = /obj/item/reagent_containers/food/drinks/bottle/small/beer
-/obj/item/robot_module/robot/clerical/butler/Initialize()
+/obj/item/robot_module/robot/clerical/butler/flying
+ module_category = ROBOT_MODULE_TYPE_FLYING
+ can_be_pushed = TRUE
+ sprites = list(
+ "Pyralis" = "Glitterfly-Service",
+ "Eyebot" = "eyebot-standard",
+ "Service Drone" = "drone-service",
+ "Hydroponics Drone" = "drone-hydro"
+ )
+/obj/item/robot_module/robot/clerical/butler/finalize_emag()
. = ..()
- if(. != INITIALIZE_HINT_NORMAL)
- return
+ if(!emag.reagents)
+ emag.create_reagents(50)
+ else
+ emag.reagents.clear_reagents()
+ emag.reagents.add_reagent("beer2", 50)
+ emag.name = "Mickey Finn's Special Brew"
- 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)
- src.modules += new /obj/item/material/knife/machete/hatchet(src)
- src.modules += new /obj/item/analyzer/plant_analyzer(src)
- src.modules += new /obj/item/storage/bag/plants(src)
- src.modules += new /obj/item/robot_harvester(src)
- src.modules += new /obj/item/material/knife(src)
- src.modules += new /obj/item/material/kitchen/rollingpin(src)
- src.modules += new /obj/item/multitool(src) //to freeze trays
-
- var/obj/item/rsf/M = new /obj/item/rsf(src)
+/obj/item/robot_module/robot/clerical/butler/finalize_equipment()
+ . = ..()
+ var/obj/item/rsf/M = locate() in modules
M.stored_matter = 30
- src.modules += M
-
- src.modules += new /obj/item/reagent_containers/dropper/industrial(src)
-
- var/obj/item/flame/lighter/zippo/L = new /obj/item/flame/lighter/zippo(src)
- L.lit = 1
- src.modules += L
-
- src.modules += new /obj/item/tray/robotray(src)
- 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("beer2", 50)
- src.emag.name = "Mickey Finn's Special Brew"
+ var/obj/item/flame/lighter/zippo/L = locate() in modules
+ L.lit = TRUE
/obj/item/robot_module/robot/clerical/general
name = "clerical robot module"
+ display_name = "Clerical"
sprites = list(
- "M-USE NanoTrasen" = "robotCler",
- "Cabeiri" = "eyebot-standard",
- "Haruka" = "marinaSV",
- "Usagi" = "tallgreen",
- "Telemachus" = "toiletbot",
- "WTOperator" = "sleekclerical",
- "WTOmni" = "omoikane",
- "XI-GUS" = "spidercom",
- "XI-ALP" = "heavyServ",
- "Waitress" = "Service",
- "Bro" = "Brobot",
- "Rich" = "maximillion",
- "Default" = "Service2",
- "Drone" = "drone-blu",
- "Usagi-II" = "tall2service",
- "Pyralis" = "Glitterfly-Clerical",
- "Decapod" = "decapod-Clerical",
- "Pneuma" = "pneuma-Clerical",
- "Tower" = "drider-Clerical"
- )
+ "M-USE NanoTrasen" = "robotCler",
+ "Haruka" = "marinaSV",
+ "Usagi" = "tallgreen",
+ "Telemachus" = "toiletbot",
+ "WTOperator" = "sleekclerical",
+ "WTOmni" = "omoikane",
+ "XI-GUS" = "spidercom",
+ "XI-ALP" = "heavyServ",
+ "Waitress" = "Service",
+ "Bro" = "Brobot",
+ "Rich" = "maximillion",
+ "Default" = "Service2",
+ "Usagi-II" = "tall2service",
+ "Decapod" = "decapod-Clerical",
+ "Pneuma" = "pneuma-Clerical",
+ "Tower" = "drider-Clerical",
+ "Hedge" = "Hydrobot"
+ )
+ modules = list(
+ /obj/item/pen/robopen,
+ /obj/item/form_printer,
+ /obj/item/gripper/paperwork,
+ /obj/item/hand_labeler,
+ /obj/item/stamp,
+ /obj/item/stamp/denied
+ )
+ emag = /obj/item/pen/chameleon
-/obj/item/robot_module/robot/clerical/general/Initialize()
-
- . = ..()
- if(. != INITIALIZE_HINT_NORMAL)
- return
-
- src.modules += new /obj/item/pen/robopen(src)
- src.modules += new /obj/item/form_printer(src)
- src.modules += new /obj/item/gripper/paperwork(src)
- src.modules += new /obj/item/hand_labeler(src)
- src.modules += new /obj/item/stamp(src)
- src.modules += new /obj/item/stamp/denied(src)
- src.emag = new /obj/item/stamp/chameleon(src)
- src.emag = new /obj/item/pen/chameleon(src)
+/obj/item/robot_module/robot/clerical/general/flying
+ module_category = ROBOT_MODULE_TYPE_FLYING
+ can_be_pushed = TRUE
+ sprites = list(
+ "Eyebot" = "eyebot-standard",
+ "Drone" = "drone-blu",
+ "Service Drone" = "drone-service",
+ "Gravekeeper" = "drone-gravekeeper",
+ "Hydroponics Drone" = "drone-hydro",
+ "Pyralis" = "Glitterfly-Clerical"
+ )
/obj/item/robot_module/general/butler/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
var/obj/item/reagent_containers/food/condiment/enzyme/E = locate() in src.modules
@@ -738,275 +583,254 @@ var/global/list/robot_modules = list(
/obj/item/robot_module/robot/miner
name = "miner robot module"
+ display_name = "Miner"
channels = list("Supply" = 1)
networks = list(NETWORK_MINE)
sprites = list(
- "NM-USE NanoTrasen" = "robotMine",
- "Cabeiri" = "eyebot-miner",
- "Haruka" = "marinaMN",
- "Telemachus" = "toiletbotminer",
- "WTOperator" = "sleekminer",
- "XI-GUS" = "spidermining",
- "XI-ALP" = "heavyMiner",
- "Basic" = "Miner_old",
- "Advanced Droid" = "droid-miner",
- "Treadhead" = "Miner",
- "Drone" = "drone-miner",
- "Usagi-II" = "tall2miner",
- "Pyralis" = "Glitterfly-Miner",
- "Decapod" = "decapod-Miner",
- "Pneuma" = "pneuma-Miner",
- "Tower" = "drider-Miner"
- )
+ "NM-USE NanoTrasen" = "robotMine",
+ "Haruka" = "marinaMN",
+ "Telemachus" = "toiletbotminer",
+ "WTOperator" = "sleekminer",
+ "XI-GUS" = "spidermining",
+ "XI-ALP" = "heavyMiner",
+ "Basic" = "Miner_old",
+ "Advanced Droid" = "droid-miner",
+ "Treadhead" = "Miner",
+ "Usagi-II" = "tall2miner",
+ "Decapod" = "decapod-Miner",
+ "Pneuma" = "pneuma-Miner",
+ "Tower" = "drider-Miner"
+ )
+ modules = list(
+ /obj/item/borg/sight/material,
+ /obj/item/tool/wrench/cyborg,
+ /obj/item/tool/screwdriver/cyborg,
+ /obj/item/storage/bag/ore,
+ /obj/item/pickaxe/borgdrill,
+ /obj/item/storage/bag/sheetsnatcher/borg,
+ /obj/item/gripper/miner,
+ /obj/item/mining_scanner
+ )
+ emag = /obj/item/pickaxe/diamonddrill
-/obj/item/robot_module/robot/miner/Initialize()
-
- . = ..()
- if(. != INITIALIZE_HINT_NORMAL)
- return
-
- src.modules += new /obj/item/borg/sight/material(src)
- src.modules += new /obj/item/tool/wrench/cyborg(src)
- src.modules += new /obj/item/tool/screwdriver/cyborg(src)
- src.modules += new /obj/item/storage/bag/ore(src)
- src.modules += new /obj/item/pickaxe/borgdrill(src)
- src.modules += new /obj/item/storage/bag/sheetsnatcher/borg(src)
- src.modules += new /obj/item/gripper/miner(src)
- src.modules += new /obj/item/mining_scanner(src)
- src.emag = new /obj/item/pickaxe/plasmacutter(src)
- src.emag = new /obj/item/pickaxe/diamonddrill(src)
+/obj/item/robot_module/robot/miner/flying
+ module_category = ROBOT_MODULE_TYPE_FLYING
+ can_be_pushed = TRUE
+ sprites = list(
+ "Drone" = "drone-miner",
+ "Cabeiri" = "eyebot-miner",
+ "Pyralis" = "Glitterfly-Miner"
+ )
/obj/item/robot_module/robot/research
name = "research module"
+ display_name = "Research"
channels = list("Science" = 1)
sprites = list(
- "L'Ouef" = "peaceborg",
- "Cabeiri" = "eyebot-science",
- "Haruka" = "marinaSCI",
- "WTDove" = "whitespider",
- "WTOperator" = "sleekscience",
- "Droid" = "droid-science",
- "Drone" = "drone-science",
- "Handy" = "handy-science",
- "Insekt" = "insekt-Sci",
- "Usagi-II" = "tall2peace",
- "Pyralis" = "Glitterfly-Research",
- "Decapod" = "decapod-Research",
- "Pneuma" = "pneuma-Research",
- "Tower" = "drider-Research"
- )
+ "L'Ouef" = "peaceborg",
+ "Haruka" = "marinaSCI",
+ "WTDove" = "whitespider",
+ "WTOperator" = "sleekscience",
+ "Droid" = "droid-science",
+ "Insekt" = "insekt-Sci",
+ "Usagi-II" = "tall2peace",
+ "Decapod" = "decapod-Research",
+ "Pneuma" = "pneuma-Research",
+ "Tower" = "drider-Research"
+ )
+ modules = list(
+ /obj/item/portable_destructive_analyzer,
+ /obj/item/gripper/research,
+ /obj/item/gripper/circuit,
+ /obj/item/gripper/no_use/organ/robotics,
+ /obj/item/gripper/no_use/mech,
+ /obj/item/gripper/no_use/loader,
+ /obj/item/robotanalyzer,
+ /obj/item/card/robot,
+ /obj/item/weldingtool/electric/mounted/cyborg,
+ /obj/item/tool/screwdriver/cyborg,
+ /obj/item/tool/wrench/cyborg,
+ /obj/item/tool/wirecutters/cyborg,
+ /obj/item/multitool,
+ /obj/item/surgical/scalpel/cyborg,
+ /obj/item/surgical/circular_saw/cyborg,
+ /obj/item/reagent_containers/syringe,
+ /obj/item/reagent_containers/glass/beaker/large,
+ /obj/item/storage/part_replacer,
+ /obj/item/shockpaddles/robot/jumper,
+ /obj/item/melee/baton/slime/robot,
+ /obj/item/gun/energy/taser/xeno/robot,
+ /obj/item/xenoarch_multi_tool,
+ /obj/item/pickaxe/excavationdrill,
+ /obj/item/cataloguer,
+ /obj/item/stack/cable_coil/cyborg,
+ /obj/item/stack/nanopaste
+ )
+ emag = /obj/item/hand_tele
+ synths = list(
+ /datum/matter_synth/nanite = 10000,
+ /datum/matter_synth/wire
+ )
-/obj/item/robot_module/robot/research/Initialize()
+/obj/item/robot_module/robot/research/flying
+ module_category = ROBOT_MODULE_TYPE_FLYING
+ can_be_pushed = TRUE
+ sprites = list(
+ "Handy" = "handy-science",
+ "Drone" = "drone-science",
+ "Pyralis" = "Glitterfly-Research",
+ "Cabeiri" = "eyebot-science"
+ )
+/obj/item/robot_module/robot/research/finalize_synths()
. = ..()
- if(. != INITIALIZE_HINT_NORMAL)
- return
-
- src.modules += new /obj/item/portable_destructive_analyzer(src)
- src.modules += new /obj/item/gripper/research(src)
- src.modules += new /obj/item/gripper/circuit(src)
- src.modules += new /obj/item/gripper/no_use/organ/robotics(src)
- src.modules += new /obj/item/gripper/no_use/mech(src)
- src.modules += new /obj/item/gripper/no_use/loader(src)
- src.modules += new /obj/item/robotanalyzer(src)
- src.modules += new /obj/item/card/robot(src)
- src.modules += new /obj/item/weldingtool/electric/mounted/cyborg(src)
- src.modules += new /obj/item/tool/screwdriver/cyborg(src)
- src.modules += new /obj/item/tool/wrench/cyborg(src)
- src.modules += new /obj/item/tool/wirecutters/cyborg(src)
- src.modules += new /obj/item/multitool(src)
- src.modules += new /obj/item/surgical/scalpel/cyborg(src)
- src.modules += new /obj/item/surgical/circular_saw/cyborg(src)
- src.modules += new /obj/item/reagent_containers/syringe(src)
- src.modules += new /obj/item/reagent_containers/glass/beaker/large(src)
- src.modules += new /obj/item/storage/part_replacer(src)
- src.modules += new /obj/item/shockpaddles/robot/jumper(src)
- src.modules += new /obj/item/melee/baton/slime/robot(src)
- src.modules += new /obj/item/gun/energy/taser/xeno/robot(src)
- src.modules += new /obj/item/xenoarch_multi_tool(src)
- src.modules += new /obj/item/pickaxe/excavationdrill(src)
- src.modules += new /obj/item/cataloguer(src)
-
- src.emag = new /obj/item/hand_tele(src)
-
- var/datum/matter_synth/nanite = new /datum/matter_synth/nanite(10000)
- synths += nanite
- var/datum/matter_synth/wire = new /datum/matter_synth/wire() //Added to allow repairs, would rather add cable now than be asked to add it later,
- synths += wire //Cable code, taken from engiborg,
-
- var/obj/item/stack/nanopaste/N = new /obj/item/stack/nanopaste(src)
+ var/datum/matter_synth/nanite = locate() in synths
+ var/obj/item/stack/nanopaste/N = locate() in modules
N.uses_charge = 1
N.charge_costs = list(1000)
N.synths = list(nanite)
- src.modules += N
-
- var/obj/item/stack/cable_coil/cyborg/C = new /obj/item/stack/cable_coil/cyborg(src) //Cable code, taken from engiborg,
+ var/datum/matter_synth/wire = locate() in synths
+ var/obj/item/stack/cable_coil/cyborg/C = locate() in modules
C.synths = list(wire)
- src.modules += C
/obj/item/robot_module/robot/research/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
-
var/obj/item/reagent_containers/syringe/S = locate() in src.modules
if(S.mode == 2)
S.reagents.clear_reagents()
S.mode = initial(S.mode)
S.desc = initial(S.desc)
S.update_icon()
-
..()
-
/obj/item/robot_module/robot/security/combat
name = "combat robot module"
+ display_name = "Combat"
+ crisis_locked = TRUE
hide_on_manifest = TRUE
sprites = list(
- "Haruka" = "marinaCB",
- "Combat Android" = "droid-combat",
- "Insekt" = "insekt-Combat",
- "Decapod" = "decapod-Combat"
- )
-
-/obj/item/robot_module/robot/security/combat/Initialize()
-
- . = ..()
- if(. != INITIALIZE_HINT_NORMAL)
- return
-
- src.modules += new /obj/item/flash(src)
- src.modules += new /obj/item/borg/sight/thermal(src)
- src.modules += new /obj/item/gun/energy/laser/mounted(src)
- src.modules += new /obj/item/pickaxe/plasmacutter(src)
- src.modules += new /obj/item/borg/combat/shield(src)
- src.modules += new /obj/item/borg/combat/mobility(src)
- src.emag = new /obj/item/gun/energy/lasercannon/mounted(src)
-
+ "Haruka" = "marinaCB",
+ "Combat Android" = "droid-combat",
+ "Insekt" = "insekt-Combat",
+ "Decapod" = "decapod-Combat"
+ )
+ modules = list(
+ /obj/item/flash,
+ /obj/item/borg/sight/thermal,
+ /obj/item/gun/energy/laser/mounted,
+ /obj/item/pickaxe/plasmacutter,
+ /obj/item/borg/combat/shield,
+ /obj/item/borg/combat/mobility
+ )
+ emag = /obj/item/gun/energy/lasercannon/mounted
/* Drones */
-
/obj/item/robot_module/drone
name = "drone module"
+ display_name = "Drone"
+ sprites = list("Drone" = "repairbot")
+ unavailable_by_default = TRUE
hide_on_manifest = TRUE
- no_slip = 1
+ no_slip = TRUE
networks = list(NETWORK_ENGINEERING)
+ modules = list(
+ /obj/item/borg/sight/meson,
+ /obj/item/weldingtool/electric/mounted/cyborg,
+ /obj/item/tool/screwdriver/cyborg,
+ /obj/item/tool/wrench/cyborg,
+ /obj/item/tool/crowbar/cyborg,
+ /obj/item/tool/wirecutters/cyborg,
+ /obj/item/t_scanner,
+ /obj/item/multitool,
+ /obj/item/lightreplacer,
+ /obj/item/gripper,
+ /obj/item/soap,
+ /obj/item/gripper/no_use/loader,
+ /obj/item/extinguisher,
+ /obj/item/pipe_painter,
+ /obj/item/floor_painter,
+ /obj/item/matter_decompiler,
+ /obj/item/stack/material/cyborg/steel,
+ /obj/item/stack/material/cyborg/glass,
+ /obj/item/stack/rods/cyborg,
+ /obj/item/stack/cable_coil/cyborg,
+ /obj/item/stack/tile/floor/cyborg,
+ /obj/item/stack/material/cyborg/glass/reinforced,
+ /obj/item/stack/tile/wood/cyborg,
+ /obj/item/stack/material/cyborg/wood,
+ /obj/item/stack/material/cyborg/plastic
+ )
+ jetpack = /obj/item/tank/jetpack/carbondioxide
+ emag = /obj/item/pickaxe/plasmacutter
+ synths = list(
+ /datum/matter_synth/metal = 25000,
+ /datum/matter_synth/glass = 25000,
+ /datum/matter_synth/wood = 25000,
+ /datum/matter_synth/plastic = 25000,
+ /datum/matter_synth/wire = 30
+ )
-/obj/item/robot_module/drone/Initialize(var/ml)
-
+/obj/item/robot_module/drone/finalize_synths()
. = ..()
- if(. != INITIALIZE_HINT_NORMAL)
- return
+ var/datum/matter_synth/metal/metal = locate() in synths
+ var/datum/matter_synth/glass/glass = locate() in synths
+ var/datum/matter_synth/wood/wood = locate() in synths
+ var/datum/matter_synth/plastic/plastic = locate() in synths
+ var/datum/matter_synth/wire/wire = locate() in synths
- src.modules += new /obj/item/borg/sight/meson(src)
- src.modules += new /obj/item/weldingtool/electric/mounted/cyborg(src)
- src.modules += new /obj/item/tool/screwdriver/cyborg(src)
- src.modules += new /obj/item/tool/wrench/cyborg(src)
- src.modules += new /obj/item/tool/crowbar/cyborg(src)
- src.modules += new /obj/item/tool/wirecutters/cyborg(src)
- src.modules += new /obj/item/t_scanner(src)
- src.modules += new /obj/item/multitool(src)
- src.modules += new /obj/item/lightreplacer(src)
- src.modules += new /obj/item/gripper(src)
- src.modules += new /obj/item/soap(src)
- src.modules += new /obj/item/gripper/no_use/loader(src)
- src.modules += new /obj/item/extinguisher(src)
- src.modules += new /obj/item/pipe_painter(src)
- src.modules += new /obj/item/floor_painter(src)
-
- var/mob/living/silicon/robot/robit = loc
- robit.internals = new/obj/item/tank/jetpack/carbondioxide(src)
- src.modules += robit.internals
-
- src.emag = new /obj/item/pickaxe/plasmacutter(src)
- src.emag.name = "Plasma Cutter"
-
- var/datum/matter_synth/metal = new /datum/matter_synth/metal(25000)
- var/datum/matter_synth/glass = new /datum/matter_synth/glass(25000)
- var/datum/matter_synth/wood = new /datum/matter_synth/wood(25000)
- var/datum/matter_synth/plastic = new /datum/matter_synth/plastic(25000)
- var/datum/matter_synth/wire = new /datum/matter_synth/wire(30)
- synths += metal
- synths += glass
- synths += wood
- synths += plastic
- synths += wire
-
- var/obj/item/matter_decompiler/MD = new /obj/item/matter_decompiler(src)
+ var/obj/item/matter_decompiler/MD = locate() in modules
MD.metal = metal
MD.glass = glass
MD.wood = wood
MD.plastic = plastic
- src.modules += MD
- var/obj/item/stack/material/cyborg/steel/M = new (src)
+ var/obj/item/stack/material/cyborg/steel/M = locate() in modules
M.synths = list(metal)
- src.modules += M
-
- var/obj/item/stack/material/cyborg/glass/G = new (src)
+ var/obj/item/stack/material/cyborg/glass/G = locate() in modules
G.synths = list(glass)
- src.modules += G
-
- var/obj/item/stack/rods/cyborg/R = new /obj/item/stack/rods/cyborg(src)
+ var/obj/item/stack/rods/cyborg/R = locate() in modules
R.synths = list(metal)
- src.modules += R
-
- var/obj/item/stack/cable_coil/cyborg/C = new /obj/item/stack/cable_coil/cyborg(src)
+ var/obj/item/stack/cable_coil/cyborg/C = locate() in modules
C.synths = list(wire)
- src.modules += C
-
- var/obj/item/stack/tile/floor/cyborg/S = new /obj/item/stack/tile/floor/cyborg(src)
+ var/obj/item/stack/tile/floor/cyborg/S = locate() in modules
S.synths = list(metal)
- src.modules += S
-
- var/obj/item/stack/material/cyborg/glass/reinforced/RG = new (src)
+ var/obj/item/stack/material/cyborg/glass/reinforced/RG = locate() in modules
RG.synths = list(metal, glass)
- src.modules += RG
-
- var/obj/item/stack/tile/wood/cyborg/WT = new /obj/item/stack/tile/wood/cyborg(src)
+ var/obj/item/stack/tile/wood/cyborg/WT = locate() in modules
WT.synths = list(wood)
- src.modules += WT
-
- var/obj/item/stack/material/cyborg/wood/W = new (src)
+ var/obj/item/stack/material/cyborg/wood/W = locate() in modules
W.synths = list(wood)
- src.modules += W
-
- var/obj/item/stack/material/cyborg/plastic/P = new (src)
+ var/obj/item/stack/material/cyborg/plastic/P = locate() in modules
P.synths = list(plastic)
- src.modules += P
src.modules += new /obj/item/pipe_dispenser(src) // At the end to go beside the construction's RCD.
/obj/item/robot_module/drone/construction
name = "construction drone module"
+ display_name = "Construction Drone"
hide_on_manifest = TRUE
+ sprites = list("Drone" = "constructiondrone")
channels = list("Engineering" = 1)
languages = list()
-/obj/item/robot_module/drone/construction/Initialize()
-
+/obj/item/robot_module/drone/construction/build_equipment()
+ modules += /obj/item/rcd/electric/mounted/borg/lesser
. = ..()
- if(. != INITIALIZE_HINT_NORMAL)
- return
-
- src.modules += new /obj/item/rcd/electric/mounted/borg/lesser(src)
/obj/item/robot_module/drone/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
var/obj/item/lightreplacer/LR = locate() in src.modules
LR.Charge(R, amount)
..()
- return
/obj/item/robot_module/drone/mining
name = "miner drone module"
+ display_name = "Mining Drone"
channels = list("Supply" = 1)
networks = list(NETWORK_MINE)
-
-/obj/item/robot_module/drone/mining/Initialize()
-
- . = ..()
- if(. != INITIALIZE_HINT_NORMAL)
- return
-
- src.modules += new /obj/item/borg/sight/material(src)
- src.modules += new /obj/item/pickaxe/borgdrill(src)
- src.modules += new /obj/item/storage/bag/ore(src)
- src.modules += new /obj/item/storage/bag/sheetsnatcher/borg(src)
- src.emag = new /obj/item/pickaxe/diamonddrill(src)
+ sprites = list("Drone" = "miningdrone")
+ modules = list(
+ /obj/item/borg/sight/material,
+ /obj/item/pickaxe/borgdrill,
+ /obj/item/storage/bag/ore,
+ /obj/item/storage/bag/sheetsnatcher/borg
+ )
+ emag = /obj/item/pickaxe/diamonddrill
diff --git a/code/modules/mob/living/silicon/robot/robot_modules/swarm.dm b/code/modules/mob/living/silicon/robot/robot_modules/swarm.dm
index 55ae50cda1..31dc08c544 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules/swarm.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules/swarm.dm
@@ -1,32 +1,31 @@
/obj/item/robot_module/drone/swarm
name = "swarm drone module"
+ display_name = "Swarm Drone"
+ unavailable_by_default = TRUE
+ modules = list(
+ /obj/item/rcd/electric/mounted/borg/swarm,
+ /obj/item/flash/robot,
+ /obj/item/handcuffs/cable/tape/cyborg,
+ /obj/item/melee/baton/robot,
+ /obj/item/gun/energy/taser/mounted/cyborg/swarm,
+ /obj/item/matter_decompiler/swarm
+ )
var/id
-/obj/item/robot_module/drone/swarm/Initialize(var/ml)
-
+/obj/item/robot_module/drone/swarm/build_equipment()
. = ..()
- if(. != INITIALIZE_HINT_NORMAL)
- return
-
var/mob/living/silicon/robot/R = loc
- id = R.idcard
- src.modules += id
- src.modules += new /obj/item/rcd/electric/mounted/borg/swarm(src)
- src.modules += new /obj/item/flash/robot(src)
- src.modules += new /obj/item/handcuffs/cable/tape/cyborg(src)
- src.modules += new /obj/item/melee/baton/robot(src)
- src.modules += new /obj/item/gun/energy/taser/mounted/cyborg/swarm(src)
- src.modules += new /obj/item/matter_decompiler/swarm(src)
+ if(istype(R) && R.idcard)
+ id = R.idcard
+ modules += id
/obj/item/robot_module/drone/swarm/ranged
name = "swarm gunner module"
-/obj/item/robot_module/drone/swarm/ranged/Initialize(var/ml)
+/obj/item/robot_module/drone/swarm/ranged/build_equipment()
. = ..()
- if(. == INITIALIZE_HINT_NORMAL)
- modules += new /obj/item/gun/energy/xray/swarm(src)
+ modules += new /obj/item/gun/energy/xray/swarm(src)
-/obj/item/robot_module/drone/swarm/melee/Initialize(var/ml)
+/obj/item/robot_module/drone/swarm/melee/build_equipment()
. = ..()
- if(. == INITIALIZE_HINT_NORMAL)
- modules += new /obj/item/melee/energy/sword/ionic_rapier/lance(src)
+ modules += new /obj/item/melee/energy/sword/ionic_rapier/lance(src)
diff --git a/code/modules/mob/living/silicon/robot/robot_modules/syndicate.dm b/code/modules/mob/living/silicon/robot/robot_modules/syndicate.dm
index a3d558466c..d3de12b630 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules/syndicate.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules/syndicate.dm
@@ -2,7 +2,9 @@
/obj/item/robot_module/robot/syndicate
name = "illegal robot module"
+ display_name = "Subverted"
hide_on_manifest = TRUE
+ unavailable_by_default = TRUE
languages = list(
LANGUAGE_SOL_COMMON = 1,
LANGUAGE_SIVIAN = 0,
@@ -21,42 +23,42 @@
LANGUAGE_ZADDAT = 0
)
sprites = list(
- "Cerberus" = "syndie_bloodhound",
- "Cerberus - Treaded" = "syndie_treadhound",
- "Ares" = "squats",
- "Telemachus" = "toiletbotantag",
- "WTOperator" = "hosborg",
- "XI-GUS" = "spidersyndi",
- "XI-ALP" = "syndi-heavy"
- )
+ "Cerberus" = "syndie_bloodhound",
+ "Cerberus - Treaded" = "syndie_treadhound",
+ "Ares" = "squats",
+ "Telemachus" = "toiletbotantag",
+ "XI-GUS" = "spidersyndi",
+ "XI-ALP" = "syndi-heavy"
+ )
+ universal_equipment = list(
+ /obj/item/flash/robot,
+ /obj/item/tool/crowbar/cyborg,
+ /obj/item/extinguisher,
+ /obj/item/gps/robot,
+ /obj/item/pinpointer/shuttle/merc,
+ /obj/item/melee/energy/sword,
+ )
+ jetpack = /obj/item/tank/jetpack/carbondioxide
+ synths = list(
+ /datum/matter_synth/cloth = 40000
+ )
var/id
// All syndie modules get these, and the base borg items (flash, crowbar, etc).
-/obj/item/robot_module/robot/syndicate/Initialize()
-
+/obj/item/robot_module/robot/syndicate/finalize_synths()
. = ..()
- if(. != INITIALIZE_HINT_NORMAL)
- return
-
- src.modules += new /obj/item/pinpointer/shuttle/merc(src)
- src.modules += new /obj/item/melee/energy/sword(src)
-
- var/datum/matter_synth/cloth = new /datum/matter_synth/cloth(40000)
- synths += cloth
-
- var/obj/item/stack/sandbags/cyborg/SB = new /obj/item/stack/sandbags/cyborg(src)
+ var/datum/matter_synth/cloth/cloth = locate() in synths
+ var/obj/item/stack/sandbags/cyborg/SB = locate() in modules
SB.synths += list(cloth)
- var/jetpack = new/obj/item/tank/jetpack/carbondioxide(src)
- src.modules += jetpack
+/obj/item/robot_module/robot/syndicate/finalize_equipment()
+ . = ..()
var/mob/living/silicon/robot/R = loc
- R.internals = jetpack
-
- id = R.idcard
- src.modules += id
+ if(istype(R))
+ id = R.idcard
+ modules += id
/obj/item/robot_module/robot/syndicate/Destroy()
- src.modules -= id
id = null
return ..()
@@ -69,17 +71,12 @@
"Ares" = "squats",
"XI-ALP" = "syndi-heavy"
)
-
-/obj/item/robot_module/robot/syndicate/protector/Initialize()
-
- . = ..()
- if(. != INITIALIZE_HINT_NORMAL)
- return
-
- src.modules += new /obj/item/shield_projector/rectangle/weak(src)
- src.modules += new /obj/item/gun/energy/dakkalaser(src)
- src.modules += new /obj/item/handcuffs/cyborg(src)
- src.modules += new /obj/item/melee/baton/robot(src)
+ modules = list(
+ /obj/item/shield_projector/rectangle/weak,
+ /obj/item/gun/energy/dakkalaser,
+ /obj/item/handcuffs/cyborg,
+ /obj/item/melee/baton/robot
+ )
// 95% engi-borg and 15% roboticist.
/obj/item/robot_module/robot/syndicate/mechanist
@@ -87,133 +84,114 @@
sprites = list(
"XI-GUS" = "spidersyndi",
"WTOperator" = "sleekhos"
- )
-
-/obj/item/robot_module/robot/syndicate/mechanist/Initialize()
+ )
+ modules = list(
+ /obj/item/borg/sight/meson,
+ /obj/item/weldingtool/electric/mounted/cyborg,
+ /obj/item/tool/screwdriver/cyborg,
+ /obj/item/tool/wrench/cyborg,
+ /obj/item/tool/wirecutters/cyborg,
+ /obj/item/multitool/ai_detector,
+ /obj/item/pickaxe/plasmacutter,
+ /obj/item/rcd/electric/mounted/borg/lesser,
+ /obj/item/melee/energy/sword/ionic_rapier,
+ /obj/item/robotanalyzer,
+ /obj/item/shockpaddles/robot/jumper,
+ /obj/item/gripper/no_use/organ/robotics,
+ /obj/item/card/robot/syndi,
+ /obj/item/card/emag,
+ /obj/item/stack/nanopaste,
+ /obj/item/stack/material/cyborg/steel,
+ /obj/item/stack/material/cyborg/glass,
+ /obj/item/stack/rods/cyborg,
+ /obj/item/stack/cable_coil/cyborg,
+ /obj/item/stack/material/cyborg/glass/reinforced
+ )
+ synths = list(
+ /datum/matter_synth/nanite = 10000,
+ /datum/matter_synth/metal = 40000,
+ /datum/matter_synth/glass = 40000,
+ /datum/matter_synth/wire
+ )
+/obj/item/robot_module/robot/syndicate/mechanist/finalize_synths()
. = ..()
- if(. != INITIALIZE_HINT_NORMAL)
- return
- // General engineering/hacking.
- src.modules += new /obj/item/borg/sight/meson(src)
- src.modules += new /obj/item/weldingtool/electric/mounted/cyborg(src)
- src.modules += new /obj/item/tool/screwdriver/cyborg(src)
- src.modules += new /obj/item/tool/wrench/cyborg(src)
- src.modules += new /obj/item/tool/wirecutters/cyborg(src)
- src.modules += new /obj/item/multitool/ai_detector(src)
- src.modules += new /obj/item/pickaxe/plasmacutter(src)
- src.modules += new /obj/item/rcd/electric/mounted/borg/lesser(src) // Can't eat rwalls to prevent AI core cheese.
- src.modules += new /obj/item/melee/energy/sword/ionic_rapier(src)
-
- // FBP repair.
- src.modules += new /obj/item/robotanalyzer(src)
- src.modules += new /obj/item/shockpaddles/robot/jumper(src)
- src.modules += new /obj/item/gripper/no_use/organ/robotics(src)
-
- // Hacking other things.
- src.modules += new /obj/item/card/robot/syndi(src)
- src.modules += new /obj/item/card/emag(src)
-
- // Materials.
- var/datum/matter_synth/nanite = new /datum/matter_synth/nanite(10000)
- synths += nanite
- var/datum/matter_synth/wire = new /datum/matter_synth/wire()
- synths += wire
- var/datum/matter_synth/metal = new /datum/matter_synth/metal(40000)
- synths += metal
- var/datum/matter_synth/glass = new /datum/matter_synth/glass(40000)
- synths += glass
-
- var/obj/item/stack/nanopaste/N = new /obj/item/stack/nanopaste(src)
+ var/datum/matter_synth/nanite/nanite = locate() in synths
+ var/obj/item/stack/nanopaste/N = locate() in modules
N.uses_charge = 1
N.charge_costs = list(1000)
N.synths = list(nanite)
- src.modules += N
- var/obj/item/stack/material/cyborg/steel/M = new (src)
+ var/datum/matter_synth/metal/metal = locate() in synths
+ var/obj/item/stack/material/cyborg/steel/M = locate() in modules
+ var/obj/item/stack/rods/cyborg/rods = locate() in modules
M.synths = list(metal)
- src.modules += M
-
- var/obj/item/stack/material/cyborg/glass/G = new (src)
- G.synths = list(glass)
- src.modules += G
-
- 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)
+ var/datum/matter_synth/glass/glass = locate() in synths
+ var/obj/item/stack/material/cyborg/glass/G = locate() in modules
+ G.synths = list(glass)
+
+ var/datum/matter_synth/wire/wire = locate() in synths
+ var/obj/item/stack/cable_coil/cyborg/C = locate() in modules
C.synths = list(wire)
- src.modules += C
- var/obj/item/stack/material/cyborg/glass/reinforced/RG = new (src)
+ var/obj/item/stack/material/cyborg/glass/reinforced/RG = locate() in modules
RG.synths = list(metal, glass)
- src.modules += RG
-
-
-
// Mediborg optimized for on-the-field healing, but can also do surgery if needed.
/obj/item/robot_module/robot/syndicate/combat_medic
name = "combat medic robot module"
sprites = list(
"Telemachus" = "toiletbotantag"
- )
-
-/obj/item/robot_module/robot/syndicate/combat_medic/Initialize()
+ )
+ modules = list(
+ /obj/item/borg/sight/hud/med,
+ /obj/item/healthanalyzer/advanced,
+ /obj/item/reagent_containers/borghypo/merc,
+ /obj/item/autopsy_scanner,
+ /obj/item/surgical/scalpel/cyborg,
+ /obj/item/surgical/hemostat/cyborg,
+ /obj/item/surgical/retractor/cyborg,
+ /obj/item/surgical/cautery/cyborg,
+ /obj/item/surgical/bonegel/cyborg,
+ /obj/item/surgical/FixOVein/cyborg,
+ /obj/item/surgical/bonesetter/cyborg,
+ /obj/item/surgical/circular_saw/cyborg,
+ /obj/item/surgical/surgicaldrill/cyborg,
+ /obj/item/gripper/no_use/organ,
+ /obj/item/gripper/medical,
+ /obj/item/shockpaddles/robot/combat,
+ /obj/item/reagent_containers/dropper,
+ /obj/item/reagent_containers/syringe,
+ /obj/item/roller_holder,
+ /obj/item/stack/medical/advanced/ointment,
+ /obj/item/stack/medical/advanced/bruise_pack,
+ /obj/item/stack/medical/splint
+ )
+ synths = list(
+ /datum/matter_synth/medicine = 15000
+ )
+/obj/item/robot_module/robot/syndicate/combat_medic/finalize_synths()
. = ..()
- if(. != INITIALIZE_HINT_NORMAL)
- return
-
- src.modules += new /obj/item/borg/sight/hud/med(src)
- src.modules += new /obj/item/healthanalyzer/advanced(src)
- src.modules += new /obj/item/reagent_containers/borghypo/merc(src)
-
- // Surgery things.
- src.modules += new /obj/item/autopsy_scanner(src)
- src.modules += new /obj/item/surgical/scalpel/cyborg(src)
- src.modules += new /obj/item/surgical/hemostat/cyborg(src)
- src.modules += new /obj/item/surgical/retractor/cyborg(src)
- src.modules += new /obj/item/surgical/cautery/cyborg(src)
- src.modules += new /obj/item/surgical/bonegel/cyborg(src)
- src.modules += new /obj/item/surgical/FixOVein/cyborg(src)
- src.modules += new /obj/item/surgical/bonesetter/cyborg(src)
- src.modules += new /obj/item/surgical/circular_saw/cyborg(src)
- src.modules += new /obj/item/surgical/surgicaldrill/cyborg(src)
- src.modules += new /obj/item/gripper/no_use/organ(src)
-
- // General healing.
- src.modules += new /obj/item/gripper/medical(src)
- src.modules += new /obj/item/shockpaddles/robot/combat(src)
- src.modules += new /obj/item/reagent_containers/dropper(src) // Allows borg to fix necrosis apparently
- src.modules += new /obj/item/reagent_containers/syringe(src)
- src.modules += new /obj/item/roller_holder(src)
-
- // Materials.
- var/datum/matter_synth/medicine = new /datum/matter_synth/medicine(15000)
- synths += medicine
-
- var/obj/item/stack/medical/advanced/ointment/O = new /obj/item/stack/medical/advanced/ointment(src)
- var/obj/item/stack/medical/advanced/bruise_pack/B = new /obj/item/stack/medical/advanced/bruise_pack(src)
- var/obj/item/stack/medical/splint/S = new /obj/item/stack/medical/splint(src)
+ var/datum/matter_synth/medicine/medicine = locate() in synths
+ var/obj/item/stack/medical/advanced/ointment/O = locate() in modules
O.uses_charge = 1
O.charge_costs = list(1000)
O.synths = list(medicine)
+ var/obj/item/stack/medical/advanced/bruise_pack/B = locate() in modules
B.uses_charge = 1
B.charge_costs = list(1000)
B.synths = list(medicine)
+ var/obj/item/stack/medical/splint/S = locate() in modules
S.uses_charge = 1
S.charge_costs = list(1000)
S.synths = list(medicine)
- src.modules += O
- src.modules += B
- src.modules += S
/obj/item/robot_module/robot/syndicate/combat_medic/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
-
- var/obj/item/reagent_containers/syringe/S = locate() in src.modules
+ var/obj/item/reagent_containers/syringe/S = locate() in modules
if(S.mode == 2)
S.reagents.clear_reagents()
S.mode = initial(S.mode)
diff --git a/code/modules/mob/living/silicon/robot/robot_movement.dm b/code/modules/mob/living/silicon/robot/robot_movement.dm
index a554176536..23edeb6877 100644
--- a/code/modules/mob/living/silicon/robot/robot_movement.dm
+++ b/code/modules/mob/living/silicon/robot/robot_movement.dm
@@ -1,29 +1,11 @@
/mob/living/silicon/robot/get_jetpack()
- if(module)
- for(var/obj/item/tank/jetpack/J in module.modules)
- return J
+ return module?.jetpack
/mob/living/silicon/robot/Check_Shoegrip()
return module && module.no_slip
/mob/living/silicon/robot/Process_Spaceslipping(var/prob_slip)
- var/obj/item/tank/jetpack/thrust = get_jetpack()
- if(thrust?.can_thrust(0.01))
- return 0
- if(module && module.no_slip)
- return 0
- ..(prob_slip)
-
-/mob/living/silicon/robot/Process_Spacemove(var/check_drift = 0)
- if(..())//Can move due to other reasons, don't use jetpack fuel
- return 1
-
- var/obj/item/tank/jetpack/thrust = get_jetpack()
- if(thrust && (!check_drift || (check_drift && thrust.stabilization_on)) && thrust.do_thrust(0.01))
- inertia_dir = 0
- return 1
-
- return 0
+ return ..(module?.no_slip ? 0 : prob_slip)
//No longer needed, but I'll leave it here incase we plan to re-use it.
/mob/living/silicon/robot/movement_delay()
@@ -43,7 +25,7 @@
return 0
var/datum/robot_component/actuator/A = get_component("actuator")
- if (cell_use_power(A.active_usage))
+ if (cell_use_power(A.active_usage * power_efficiency))
return ..()
/mob/living/silicon/robot/Moved(atom/old_loc, direction, forced = FALSE)
diff --git a/code/modules/mob/living/silicon/robot/subtypes/flying.dm b/code/modules/mob/living/silicon/robot/subtypes/flying.dm
new file mode 100644
index 0000000000..cfcd3ea266
--- /dev/null
+++ b/code/modules/mob/living/silicon/robot/subtypes/flying.dm
@@ -0,0 +1,58 @@
+/mob/living/silicon/robot/flying
+ desc = "A utility robot with an anti-gravity hover unit and a lightweight frame."
+ icon = 'icons/mob/robots/robots_flying.dmi'
+ icon_state = "drone-standard"
+ module_category = ROBOT_MODULE_TYPE_FLYING
+ dismantle_type = /obj/item/robot_parts/frame/flyer
+ power_efficiency = 0.75
+
+ // They are not very heavy or strong.
+ mob_size = MOB_SMALL
+ mob_bump_flag = SIMPLE_ANIMAL
+ mob_swap_flags = MONKEY|SLIME|SIMPLE_ANIMAL
+ mob_push_flags = MONKEY|SLIME|SIMPLE_ANIMAL
+
+/mob/living/silicon/robot/flying/initialize_components()
+ components["actuator"] = new/datum/robot_component/actuator(src)
+ components["radio"] = new/datum/robot_component/radio(src)
+ components["power cell"] = new/datum/robot_component/cell(src)
+ components["diagnosis unit"] = new/datum/robot_component/diagnosis_unit(src)
+ components["camera"] = new /datum/robot_component/camera(src)
+ components["comms"] = new/datum/robot_component/binary_communication(src)
+ components["armour"] = new/datum/robot_component/armour/light(src)
+
+/mob/living/silicon/robot/flying/Life()
+ . = ..()
+ if(incapacitated() || !is_component_functioning("actuator"))
+ stop_hovering()
+ else
+ start_hovering()
+
+/mob/living/silicon/robot/flying/proc/start_hovering()
+ hovering = TRUE
+ pass_flags |= PASSTABLE
+ default_pixel_y = 0
+ make_floating(10)
+
+/mob/living/silicon/robot/flying/proc/stop_hovering()
+ hovering = FALSE
+ pass_flags &= ~PASSTABLE
+ default_pixel_y = -8
+ stop_floating()
+
+/mob/living/silicon/robot/flying/death()
+ . = ..()
+ if(!QDELETED(src) && stat == DEAD)
+ stop_hovering()
+
+/mob/living/silicon/robot/flying/Allow_Spacemove(var/dense_object, check_drift = 0)
+ return hovering || ..()
+
+/mob/living/silicon/robot/flying/Process_Spaceslipping(var/prob_slip = 5)
+ return ..(hovering ? 0 : prob_slip)
+
+/mob/living/silicon/robot/flying/can_fall(anchor_bypass = FALSE, turf/location_override = loc)
+ return !hovering && ..()
+
+/mob/living/silicon/robot/flying/can_overcome_gravity()
+ return hovering
diff --git a/code/modules/mob/living/silicon/robot/subtypes/gravekeeper.dm b/code/modules/mob/living/silicon/robot/subtypes/gravekeeper.dm
index 3706f212c9..a71cd78a44 100644
--- a/code/modules/mob/living/silicon/robot/subtypes/gravekeeper.dm
+++ b/code/modules/mob/living/silicon/robot/subtypes/gravekeeper.dm
@@ -11,17 +11,12 @@
/mob/living/silicon/robot/gravekeeper/init()
aiCamera = new/obj/item/camera/siliconcam/robot_camera(src)
-
mmi = new /obj/item/mmi/digital/robot(src)
module = new /obj/item/robot_module/robot/gravekeeper(src)
cut_overlays()
init_id()
-
updatename("Gravekeeper")
-
if(!cell)
cell = new /obj/item/cell/high(src) // 15k cell, as recharging stations are a lot more rare on the Surface.
-
laws = new /datum/ai_laws/gravekeeper()
-
playsound(src, 'sound/mecha/nominalsyndi.ogg', 75, 0)
diff --git a/code/modules/mob/living/silicon/robot/subtypes/lost_drone.dm b/code/modules/mob/living/silicon/robot/subtypes/lost_drone.dm
index 41a750332f..5084e66018 100644
--- a/code/modules/mob/living/silicon/robot/subtypes/lost_drone.dm
+++ b/code/modules/mob/living/silicon/robot/subtypes/lost_drone.dm
@@ -1,4 +1,4 @@
-/mob/living/silicon/robot/lost
+/mob/living/silicon/robot/flying/lost
lawupdate = 0
scrambledcodes = 1
icon_state = "drone-lost"
@@ -8,7 +8,7 @@
idcard_type = /obj/item/card/id
icon_selected = FALSE
-/mob/living/silicon/robot/lost/init()
+/mob/living/silicon/robot/flying/lost/init()
aiCamera = new/obj/item/camera/siliconcam/robot_camera(src)
mmi = new /obj/item/mmi/digital/robot(src)
@@ -23,12 +23,12 @@
playsound(src, 'sound/mecha/nominalsyndi.ogg', 75, 0)
-/mob/living/silicon/robot/lost/speech_bubble_appearance()
+/mob/living/silicon/robot/flying/lost/speech_bubble_appearance()
return "synthetic_evil"
-/mob/living/silicon/robot/lost/randomlaws
+/mob/living/silicon/robot/flying/lost/randomlaws
-/mob/living/silicon/robot/lost/randomlaws/init()
+/mob/living/silicon/robot/flying/lost/randomlaws/init()
..()
laws = give_random_lawset()
diff --git a/code/modules/mob/living/silicon/robot/subtypes/thinktank/_thinktank.dm b/code/modules/mob/living/silicon/robot/subtypes/thinktank/_thinktank.dm
index 57c76909b9..c860b94977 100644
--- a/code/modules/mob/living/silicon/robot/subtypes/thinktank/_thinktank.dm
+++ b/code/modules/mob/living/silicon/robot/subtypes/thinktank/_thinktank.dm
@@ -1,28 +1,12 @@
-// Spawner landmarks are used because platforms that are mapped during
-// SSatoms init try to Initialize() twice. I have no idea why and I am
-// not paid enough to spend more time trying to debug it.
-/obj/effect/landmark/robot_platform
- name = "recon platform spawner"
- icon = 'icons/mob/screen1.dmi'
- icon_state = "x3"
- delete_me = TRUE
- var/platform_type
-
-/obj/effect/landmark/robot_platform/Initialize()
- if(platform_type)
- new platform_type(get_turf(src))
- return ..()
-
/mob/living/silicon/robot/platform
name = "support platform"
desc = "A large quadrupedal AI platform, colloquially known as a 'think-tank' due to the flexible onboard intelligence."
- icon = 'icons/mob/robots_thinktank.dmi'
+ icon = 'icons/mob/robots/robots_platform.dmi'
icon_state = "tachi"
color = "#68a2f2"
cell = /obj/item/cell/mech
idcard_type = /obj/item/card/id/platform
- module = /obj/item/robot_module/robot/platform
lawupdate = FALSE
modtype = "Standard"
@@ -33,6 +17,10 @@
mob_push_flags = HEAVY
mob_size = MOB_LARGE
+ dismantle_type = /obj/item/robot_parts/frame/platform
+ module_category = ROBOT_MODULE_TYPE_PLATFORM
+
+ var/mapped = FALSE
var/has_had_player = FALSE
var/const/platform_respawn_time = 3 MINUTES
@@ -42,19 +30,6 @@
var/tmp/recharger_tick_cost = 80 KILOWATTS
var/weakref/recharging
- var/list/stored_atoms
- var/max_stored_atoms = 1
- var/static/list/can_store_types = list(
- /mob/living,
- /obj/item,
- /obj/structure,
- /obj/machinery
- )
- // Currently set to prevent tonks hauling a deliaminating SM into the middle of the station.
- var/static/list/cannot_store_types = list(
- /obj/machinery/power/supermatter
- )
-
/mob/living/silicon/robot/platform/Login()
. = ..()
has_had_player = TRUE
@@ -66,9 +41,10 @@
/mob/living/silicon/robot/platform/Initialize(var/mapload)
. = ..()
- if(!mmi)
- mmi = new /obj/item/mmi/digital/robot(src)
- SetName("inactive [initial(name)]")
+ if(mapped)
+ if(!mmi)
+ mmi = new /obj/item/mmi/digital/robot(src)
+ SetName("inactive [initial(name)]")
updateicon()
// Copypasting from root proc to avoid calling ..() and accidentally creating duplicate armour etc.
@@ -82,11 +58,13 @@
components["armour"] = new /datum/robot_component/armour/platform(src)
/mob/living/silicon/robot/platform/Destroy()
- for(var/weakref/drop_ref in stored_atoms)
- var/atom/movable/drop_atom = drop_ref.resolve()
- if(istype(drop_atom) && !QDELETED(drop_atom) && drop_atom.loc == src)
- drop_atom.dropInto(loc)
- stored_atoms = null
+ var/obj/item/robot_module/robot/platform/thinktank_module = module
+ if(istype(thinktank_module))
+ for(var/weakref/drop_ref in thinktank_module.stored_atoms)
+ var/atom/movable/drop_atom = drop_ref.resolve()
+ if(istype(drop_atom) && !QDELETED(drop_atom) && drop_atom.loc == src)
+ drop_atom.dropInto(loc)
+ thinktank_module.stored_atoms = null
if(recharging)
var/obj/item/recharging_atom = recharging.resolve()
if(istype(recharging_atom) && recharging_atom.loc == src)
@@ -108,9 +86,10 @@
else
. += "Its recharging port is empty."
- if(length(stored_atoms))
+ var/obj/item/robot_module/robot/platform/thinktank_module = module
+ if(istype(thinktank_module) && length(thinktank_module.stored_atoms))
var/list/atom_names = list()
- for(var/weakref/stored_ref in stored_atoms)
+ for(var/weakref/stored_ref in thinktank_module.stored_atoms)
var/atom/movable/AM = stored_ref.resolve()
if(istype(AM))
atom_names += "\a [AM]"
@@ -127,9 +106,6 @@
if(ispath(module, /obj/item/robot_module))
module = new module(src)
-/mob/living/silicon/robot/platform/module_reset()
- return FALSE
-
/mob/living/silicon/robot/platform/use_power()
. = ..()
diff --git a/code/modules/mob/living/silicon/robot/subtypes/thinktank/thinktank_icon.dm b/code/modules/mob/living/silicon/robot/subtypes/thinktank/thinktank_icon.dm
index cbc8c4e4a1..245240efed 100644
--- a/code/modules/mob/living/silicon/robot/subtypes/thinktank/thinktank_icon.dm
+++ b/code/modules/mob/living/silicon/robot/subtypes/thinktank/thinktank_icon.dm
@@ -5,56 +5,74 @@
cut_overlays()
underlays.Cut()
+
+ var/use_armor_color
+ var/use_pupil_color
+ var/use_base_color
+ var/use_eye_color
+ var/use_state
+ var/list/use_decals
var/obj/item/robot_module/robot/platform/tank_module = module
- if(!istype(tank_module))
- icon = initial(icon)
- icon_state = initial(icon_state)
- color = initial(color)
- return
+ if(istype(tank_module))
+ use_pupil_color = tank_module.pupil_color
+ use_base_color = tank_module.base_color
+ use_eye_color = tank_module.eye_color
+ use_armor_color = tank_module.armor_color
+ icon = tank_module.user_icon
+ use_state = tank_module.user_icon_state
+ use_decals = tank_module.decals
+ else
+ tank_module = /obj/item/robot_module/robot/platform
+ use_pupil_color = initial(tank_module.pupil_color)
+ use_base_color = initial(tank_module.base_color)
+ use_eye_color = initial(tank_module.eye_color)
+ use_armor_color = initial(tank_module.armor_color)
+ icon = initial(tank_module.user_icon)
+ use_state = initial(tank_module.user_icon_state)
// This is necessary due to Polaris' liberal use of KEEP_TOGETHER and propensity for scaling transforms.
// If we just apply state/colour to the base icon, RESET_COLOR on the additional overlays is ignored.
- icon = tank_module.user_icon
icon_state = "blank"
color = null
- var/image/I = image(tank_module.user_icon, tank_module.user_icon_state)
- I.color = tank_module.base_color
+
+ var/image/I = image(icon, use_state)
+ I.color = use_base_color
I.appearance_flags |= (RESET_COLOR|PIXEL_SCALE)
underlays += I
- if(tank_module.armor_color)
- I = image(icon, "[tank_module.user_icon_state]_armour")
- I.color = tank_module.armor_color
+ if(use_armor_color)
+ I = image(icon, "[use_state]_armour")
+ I.color = use_armor_color
I.appearance_flags |= (RESET_COLOR|PIXEL_SCALE)
add_overlay(I)
- for(var/decal in tank_module.decals)
- I = image(icon, "[tank_module.user_icon_state]_[decal]")
- I.color = tank_module.decals[decal]
+ for(var/decal in use_decals)
+ I = image(icon, "[use_state]_[decal]")
+ I.color = use_decals[decal]
I.appearance_flags |= (RESET_COLOR|PIXEL_SCALE)
add_overlay(I)
- if(tank_module.eye_color)
- I = image(icon, "[tank_module.user_icon_state]_eyes")
- I.color = tank_module.eye_color
+ if(use_eye_color)
+ I = image(icon, "[use_state]_eyes")
+ I.color = use_eye_color
I.appearance_flags |= (RESET_COLOR|PIXEL_SCALE)
add_overlay(I)
- if(client && key && stat == CONSCIOUS && tank_module.pupil_color)
- I = image(icon, "[tank_module.user_icon_state]_pupils")
- I.color = tank_module.pupil_color
+ if(use_pupil_color && client && key && stat == CONSCIOUS)
+ I = image(icon, "[use_state]_pupils")
+ I.color = use_pupil_color
I.plane = PLANE_LIGHTING_ABOVE
I.appearance_flags |= (RESET_COLOR|PIXEL_SCALE)
add_overlay(I)
if(opened)
- add_overlay("[tank_module.user_icon_state]-open")
+ add_overlay("[use_state]-open")
if(wiresexposed)
- I = image(icon, "[tank_module.user_icon_state]-wires")
+ I = image(icon, "[use_state]-wires")
else if(cell)
- I = image(icon, "[tank_module.user_icon_state]-cell")
+ I = image(icon, "[use_state]-cell")
else
- I = image(icon, "[tank_module.user_icon_state]-nowires")
+ I = image(icon, "[use_state]-nowires")
I.appearance_flags |= (RESET_COLOR|PIXEL_SCALE)
add_overlay(I)
diff --git a/code/modules/mob/living/silicon/robot/subtypes/thinktank/thinktank_interactions.dm b/code/modules/mob/living/silicon/robot/subtypes/thinktank/thinktank_interactions.dm
index f728e3bfd0..c3f3383d2d 100644
--- a/code/modules/mob/living/silicon/robot/subtypes/thinktank/thinktank_interactions.dm
+++ b/code/modules/mob/living/silicon/robot/subtypes/thinktank/thinktank_interactions.dm
@@ -34,7 +34,7 @@
/mob/living/silicon/robot/platform/attack_ghost(mob/observer/ghost/user)
- if(client || key || stat == DEAD || !ticker || !ticker.mode)
+ if(!mapped || client || key || stat == DEAD || !ticker || !ticker.mode)
return ..()
var/confirm = alert("Do you wish to take control of \the [src]?", "Platform Control", "No", "Yes")
@@ -43,7 +43,7 @@
if(jobban_isbanned(user, "Robot"))
to_chat(user, SPAN_WARNING("You are banned from synthetic roles and cannot take control of \the [src]."))
- return
+ return
// Boilerplate from drone fabs, unsure if there's a shared proc to use instead.
var/deathtime = world.time - user.timeofdeath
diff --git a/code/modules/mob/living/silicon/robot/subtypes/thinktank/thinktank_module.dm b/code/modules/mob/living/silicon/robot/subtypes/thinktank/thinktank_module.dm
index c018fe3090..8e2ea9d50a 100644
--- a/code/modules/mob/living/silicon/robot/subtypes/thinktank/thinktank_module.dm
+++ b/code/modules/mob/living/silicon/robot/subtypes/thinktank/thinktank_module.dm
@@ -1,25 +1,36 @@
/obj/item/robot_module/robot/platform
- hide_on_manifest = TRUE
+ module_category = ROBOT_MODULE_TYPE_PLATFORM
+ unavailable_by_default = TRUE
var/pupil_color = COLOR_CYAN
var/base_color = COLOR_WHITE
var/eye_color = COLOR_BEIGE
var/armor_color = "#68a2f2"
- var/user_icon = 'icons/mob/robots_thinktank.dmi'
+ var/user_icon = 'icons/mob/robots/robots_platform.dmi'
var/user_icon_state = "tachi"
var/list/decals
var/list/available_decals = list(
- "Stripe" = "stripe",
+ "Stripe" = "stripe",
"Vertical Stripe" = "stripe_vertical"
)
-// Only show on manifest if they have a player.
-/obj/item/robot_module/robot/platform/hide_on_manifest()
- if(isrobot(loc))
- var/mob/living/silicon/robot/R = loc
- return !R.key
+ var/list/stored_atoms
+ var/max_stored_atoms = 1
+ var/static/list/can_store_types = list(
+ /mob/living,
+ /obj/item,
+ /obj/structure,
+ /obj/machinery
+ )
+ // Currently set to prevent tonks hauling a deliaminating SM into the middle of the station.
+ var/static/list/cannot_store_types = list(
+ /obj/machinery/power/supermatter
+ )
+
+/obj/item/robot_module/robot/platform/Destroy()
+ QDEL_NULL_LIST(stored_atoms)
return ..()
/obj/item/robot_module/robot/platform/verb/set_eye_colour()
@@ -31,11 +42,14 @@
var/new_pupil_color = input(usr, "Select a pupil colour.", "Pupil Colour Selection") as color|null
if(usr.incapacitated() || QDELETED(usr) || QDELETED(src) || loc != usr)
return
-
+
pupil_color = new_pupil_color || initial(pupil_color)
usr.update_icon()
/obj/item/robot_module/robot/platform/explorer
+ name = "recon platform module"
+ display_name = "Recon"
+ unavailable_by_default = FALSE
armor_color = "#528052"
eye_color = "#7b7b46"
decals = list(
@@ -46,32 +60,28 @@
"Science" = 1,
"Explorer" = 1
)
+ modules = list(
+ /obj/item/tool/wrench/cyborg,
+ /obj/item/weldingtool/electric/mounted/cyborg,
+ /obj/item/tool/wirecutters/cyborg,
+ /obj/item/tool/screwdriver/cyborg,
+ /obj/item/pickaxe/plasmacutter,
+ /obj/item/material/knife/machete/cyborg,
+ /obj/item/gun/energy/phasegun/mounted/cyborg,
+ /obj/item/stack/medical/bruise_pack
+ )
+ emag = /obj/item/chainsaw
+ synths = list(
+ /datum/matter_synth/medicine = 7500
+ )
-/obj/item/robot_module/robot/platform/explorer/Initialize()
-
- . = ..()
- if(. != INITIALIZE_HINT_NORMAL)
- return
-
- modules += new /obj/item/tool/wrench/cyborg(src)
- modules += new /obj/item/weldingtool/electric/mounted/cyborg(src)
- modules += new /obj/item/tool/wirecutters/cyborg(src)
- modules += new /obj/item/tool/screwdriver/cyborg(src)
- modules += new /obj/item/pickaxe/plasmacutter(src)
- modules += new /obj/item/material/knife/machete/cyborg(src)
-
- var/datum/matter_synth/medicine = new /datum/matter_synth/medicine(7500)
- var/obj/item/stack/medical/bruise_pack/bandaid = new(src)
+/obj/item/robot_module/robot/platform/explorer/finalize_synths()
+ ..()
+ var/datum/matter_synth/medicine/medicine = locate() in synths
+ var/obj/item/stack/medical/bruise_pack/bandaid = locate() in modules
bandaid.uses_charge = 1
bandaid.charge_costs = list(1000)
bandaid.synths = list(medicine)
- modules += bandaid
- synths += medicine
-
- var/obj/item/gun/energy/phasegun/mounted/cyborg/phasegun = new(src)
- modules += phasegun
-
- emag = new /obj/item/chainsaw(src)
/obj/item/robot_module/robot/platform/explorer/respawn_consumable(var/mob/living/silicon/robot/R, rate)
. = ..()
@@ -83,6 +93,9 @@
pew.charge_tick = 0
/obj/item/robot_module/robot/platform/cargo
+ name = "logistics platform module"
+ display_name = "Logistics"
+ unavailable_by_default = FALSE
armor_color = "#d5b222"
eye_color = "#686846"
decals = list(
@@ -91,17 +104,13 @@
)
channels = list("Supply" = 1)
networks = list(NETWORK_MINE)
-
-/obj/item/robot_module/robot/platform/cargo/Initialize()
-
- . = ..()
- if(. != INITIALIZE_HINT_NORMAL)
- return
-
- modules += new /obj/item/packageWrap(src)
- modules += new /obj/item/pen/multi(src)
- modules += new /obj/item/destTagger(src)
- emag = new /obj/item/stamp/denied
+ max_stored_atoms = 3
+ modules = list(
+ /obj/item/packageWrap,
+ /obj/item/pen/multi,
+ /obj/item/destTagger,
+ )
+ emag = /obj/item/stamp/denied
/obj/item/robot_module/robot/platform/cargo/respawn_consumable(mob/living/silicon/robot/R, rate)
. = ..()
diff --git a/code/modules/mob/living/silicon/robot/subtypes/thinktank/thinktank_storage.dm b/code/modules/mob/living/silicon/robot/subtypes/thinktank/thinktank_storage.dm
index ec6d6f4267..ed01060cb4 100644
--- a/code/modules/mob/living/silicon/robot/subtypes/thinktank/thinktank_storage.dm
+++ b/code/modules/mob/living/silicon/robot/subtypes/thinktank/thinktank_storage.dm
@@ -9,18 +9,24 @@
recharging_atom.throw_at(get_edge_target_turf(src,pick(GLOB.alldirs)),rand(1,3),30)
recharging = null
- if(length(stored_atoms))
- for(var/weakref/stored_ref in stored_atoms)
+ var/obj/item/robot_module/robot/platform/thinktank_module = module
+ if(istype(thinktank_module) && length(thinktank_module.stored_atoms))
+ for(var/weakref/stored_ref in thinktank_module.stored_atoms)
var/atom/movable/dropping = stored_ref.resolve()
if(istype(dropping) && !QDELETED(dropping) && dropping.loc == src)
dropping.dropInto(loc)
dropping.throw_at(get_edge_target_turf(src,pick(GLOB.alldirs)),rand(1,3),30)
- stored_atoms = null
+ thinktank_module.stored_atoms = null
. = ..()
/mob/living/silicon/robot/platform/proc/can_store_atom(var/atom/movable/storing, var/mob/user)
+ var/obj/item/robot_module/robot/platform/thinktank_module = module
+ if(!istype(thinktank_module))
+ to_chat(user, SPAN_WARNING("Select a module first!"))
+ return FALSE
+
if(!istype(storing))
var/storing_target = (user == src) ? "yourself" : "\the [src]"
to_chat(user, SPAN_WARNING("You cannot store that inside [storing_target]."))
@@ -38,7 +44,7 @@
to_chat(user, SPAN_WARNING("You cannot store [storing_target] inside [storing_target]!"))
return FALSE
- if(length(stored_atoms) >= max_stored_atoms)
+ if(length(thinktank_module.stored_atoms) >= thinktank_module.max_stored_atoms)
var/storing_target = (user == src) ? "Your" : "\The [src]'s"
to_chat(user, SPAN_WARNING("[storing_target] cargo compartment is full."))
return FALSE
@@ -50,13 +56,13 @@
to_chat(user, SPAN_WARNING("\The [storing] is too big for [storing_target]."))
return FALSE
- for(var/store_type in can_store_types)
+ for(var/store_type in thinktank_module.can_store_types)
if(istype(storing, store_type))
. = TRUE
break
if(.)
- for(var/store_type in cannot_store_types)
+ for(var/store_type in thinktank_module.cannot_store_types)
if(istype(storing, store_type))
. = FALSE
break
@@ -65,20 +71,25 @@
to_chat(user, SPAN_WARNING("You cannot store \the [storing] inside [storing_target]."))
/mob/living/silicon/robot/platform/proc/store_atom(var/atom/movable/storing, var/mob/user)
- if(istype(storing))
+ var/obj/item/robot_module/robot/platform/thinktank_module = module
+ if(istype(thinktank_module) && istype(storing))
storing.forceMove(src)
- LAZYDISTINCTADD(stored_atoms, weakref(storing))
+ LAZYDISTINCTADD(thinktank_module.stored_atoms, weakref(storing))
/mob/living/silicon/robot/platform/proc/drop_stored_atom(var/atom/movable/ejecting, var/mob/user)
- if(!ejecting && length(stored_atoms))
- var/weakref/stored_ref = stored_atoms[1]
+ var/obj/item/robot_module/robot/platform/thinktank_module = module
+ if(!istype(thinktank_module))
+ return
+
+ if(!ejecting && length(thinktank_module.stored_atoms))
+ var/weakref/stored_ref = thinktank_module.stored_atoms[1]
if(!istype(stored_ref))
- LAZYREMOVE(stored_atoms, stored_ref)
+ LAZYREMOVE(thinktank_module.stored_atoms, stored_ref)
else
ejecting = stored_ref?.resolve()
- LAZYREMOVE(stored_atoms, weakref(ejecting))
+ LAZYREMOVE(thinktank_module.stored_atoms, weakref(ejecting))
if(istype(ejecting) && !QDELETED(ejecting) && ejecting.loc == src)
ejecting.dropInto(loc)
if(user == src)
@@ -90,14 +101,15 @@
if(isrobot(user) && user.Adjacent(src))
return try_remove_cargo(user)
return ..()
-
+
/mob/living/silicon/robot/platform/proc/try_remove_cargo(var/mob/user)
- if(!length(stored_atoms) || !istype(user))
+ var/obj/item/robot_module/robot/platform/thinktank_module = module
+ if(!istype(thinktank_module) || !length(thinktank_module.stored_atoms) || !istype(user))
return FALSE
- var/weakref/remove_ref = stored_atoms[length(stored_atoms)]
+ var/weakref/remove_ref = thinktank_module.stored_atoms[length(thinktank_module.stored_atoms)]
var/atom/movable/removing = remove_ref?.resolve()
if(!istype(removing) || QDELETED(removing) || removing.loc != src)
- LAZYREMOVE(stored_atoms, remove_ref)
+ LAZYREMOVE(thinktank_module.stored_atoms, remove_ref)
else
user.visible_message(SPAN_NOTICE("\The [user] begins unloading \the [removing] from \the [src]'s cargo compartment."))
if(do_after(user, 3 SECONDS, src) && !QDELETED(removing) && removing.loc == src)
@@ -113,7 +125,8 @@
to_chat(src, SPAN_WARNING("You are not in any state to do that."))
return
- if(length(stored_atoms))
+ var/obj/item/robot_module/robot/platform/thinktank_module = module
+ if(istype(thinktank_module) && length(thinktank_module.stored_atoms))
drop_stored_atom(user = src)
else
to_chat(src, SPAN_WARNING("You have nothing in your cargo compartment."))
@@ -136,4 +149,4 @@
return FALSE
if(user.incapacitated() || !Adjacent(user) || !dropping.Adjacent(user))
return FALSE
- return TRUE
\ No newline at end of file
+ return TRUE
diff --git a/code/modules/mob/living/silicon/robot/subtypes/thinktank/thinktank_subtypes.dm b/code/modules/mob/living/silicon/robot/subtypes/thinktank/thinktank_subtypes.dm
deleted file mode 100644
index 1ffc3df88d..0000000000
--- a/code/modules/mob/living/silicon/robot/subtypes/thinktank/thinktank_subtypes.dm
+++ /dev/null
@@ -1,32 +0,0 @@
-/mob/living/silicon/robot/platform/explorer
- name = "recon platform"
- desc = "A large quadrupedal AI platform, colloquially known as a 'think-tank' due to the flexible onboard intelligence. This one is lightly armoured and fitted with all-terrain wheels."
- modtype = "Recon"
- module = /obj/item/robot_module/robot/platform/explorer
-
-/mob/living/silicon/robot/platform/explorer/Initialize()
- . = ..()
- laws = new /datum/ai_laws/explorer
-
-/mob/living/silicon/robot/platform/explorer/welcome_client()
- ..()
- if(client) // ganbatte tachikoma-san
- to_chat(src, SPAN_NOTICE("You are tasked with supporting the Exploration and Science staff as they unearth the secrets of the planet. Do your best!"))
-
-/obj/effect/landmark/robot_platform/explorer
- platform_type = /mob/living/silicon/robot/platform/explorer
-
-/mob/living/silicon/robot/platform/cargo
- name = "logistics platform"
- desc = "A large quadrupedal AI platform, colloquially known as a 'think-tank' due to the flexible onboard intelligence. This one has an expanded storage compartment."
- modtype = "Logistics"
- module = /obj/item/robot_module/robot/platform/cargo
- max_stored_atoms = 3
-
-/mob/living/silicon/robot/platform/cargo/welcome_client()
- ..()
- if(client)
- to_chat(src, SPAN_NOTICE("You are tasked with supporting the Cargo and Supply staff as they handle operational logistics. Do your best!"))
-
-/obj/effect/landmark/robot_platform/cargo
- platform_type = /mob/living/silicon/robot/platform/cargo
diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/pets/bird.dm b/code/modules/mob/living/simple_mob/subtypes/animal/pets/bird.dm
index 4065af0d70..4b7559f49e 100644
--- a/code/modules/mob/living/simple_mob/subtypes/animal/pets/bird.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/animal/pets/bird.dm
@@ -99,4 +99,4 @@
icon_scale_y = 0.5
/decl/mob_organ_names/bird
- hit_zones = list("head", "chest", "left leg", "right leg", "left wing", "right wing")
\ No newline at end of file
+ hit_zones = list("head", "chest", "left leg", "right leg", "left wing", "right wing")
diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/space/space.dm b/code/modules/mob/living/simple_mob/subtypes/animal/space/space.dm
index b7f77e6410..a56227b63d 100644
--- a/code/modules/mob/living/simple_mob/subtypes/animal/space/space.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/animal/space/space.dm
@@ -12,4 +12,4 @@
// They can also, you know, move around, in space
/mob/living/simple_mob/animal/space/Process_Spacemove(var/check_drift = 0)
- return TRUE
\ No newline at end of file
+ return TRUE
diff --git a/code/modules/mob/living/simple_mob/subtypes/humanoid/mercs/mercs.dm b/code/modules/mob/living/simple_mob/subtypes/humanoid/mercs/mercs.dm
index c28c490789..c055da140f 100644
--- a/code/modules/mob/living/simple_mob/subtypes/humanoid/mercs/mercs.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/humanoid/mercs/mercs.dm
@@ -430,4 +430,4 @@
/obj/random/projectile/scrapped_grenadelauncher = 100,
/obj/item/grenade/spawnergrenade/manhacks/mercenary = 50,
/obj/item/grenade/spawnergrenade/manhacks/mercenary = 30
- )
\ No newline at end of file
+ )
diff --git a/code/modules/mob/living/simple_mob/subtypes/mechanical/drones/mining_drone.dm b/code/modules/mob/living/simple_mob/subtypes/mechanical/drones/mining_drone.dm
index f0f5647ce0..5246478721 100644
--- a/code/modules/mob/living/simple_mob/subtypes/mechanical/drones/mining_drone.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/mechanical/drones/mining_drone.dm
@@ -150,4 +150,4 @@
/decl/mob_organ_names/miningdrone
- hit_zones = list("chassis", "comms array", "sensor suite", "left excavator module", "right excavator module", "maneuvering thruster")
\ No newline at end of file
+ hit_zones = list("chassis", "comms array", "sensor suite", "left excavator module", "right excavator module", "maneuvering thruster")
diff --git a/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/hoverpod.dm b/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/hoverpod.dm
index cf8dc16ae7..be5cb7768e 100644
--- a/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/hoverpod.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/hoverpod.dm
@@ -44,4 +44,4 @@
return TRUE
/decl/mob_organ_names/hoverpod
- hit_zones = list("central chassis", "control module", "hydraulics", "left manipulator", "right manipulator", "left landing strut", "right landing strut", "maneuvering thruster", "sensor suite", "radiator", "power supply")
\ No newline at end of file
+ hit_zones = list("central chassis", "control module", "hydraulics", "left manipulator", "right manipulator", "left landing strut", "right landing strut", "maneuvering thruster", "sensor suite", "radiator", "power supply")
diff --git a/code/modules/mob/living/simple_mob/subtypes/occult/constructs/_construct.dm b/code/modules/mob/living/simple_mob/subtypes/occult/constructs/_construct.dm
index 3a3c95042a..c58ce0bd7c 100644
--- a/code/modules/mob/living/simple_mob/subtypes/occult/constructs/_construct.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/occult/constructs/_construct.dm
@@ -142,8 +142,8 @@
. += "It looks severely dented!"
//Constructs levitate, can fall from a shuttle with no harm, and are piloted by either damned spirits or some otherworldly entity. Let 'em float in space.
-/mob/living/simple_mob/construct/Process_Spacemove()
- return 1
+/mob/living/simple_mob/construct/Process_Spacemove(var/check_drift = 0)
+ return TRUE
/*
// Glowing Procs
@@ -155,4 +155,4 @@
/mob/living/simple_mob/construct/proc/remove_glow()
overlays.Cut()
-*/
\ No newline at end of file
+*/
diff --git a/code/modules/mob/living/simple_mob/subtypes/occult/faithless.dm b/code/modules/mob/living/simple_mob/subtypes/occult/faithless.dm
index daca3721da..f47d733ff6 100644
--- a/code/modules/mob/living/simple_mob/subtypes/occult/faithless.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/occult/faithless.dm
@@ -43,7 +43,7 @@
minbodytemp = 0
/mob/living/simple_mob/faithless/Process_Spacemove(var/check_drift = 0)
- return 1
+ return TRUE
/mob/living/simple_mob/faithless/apply_melee_effects(var/atom/A)
if(isliving(A))
diff --git a/code/modules/mob/living/simple_mob/subtypes/slime/slime.dm b/code/modules/mob/living/simple_mob/subtypes/slime/slime.dm
index 48efc9e9e1..984dafb0dc 100644
--- a/code/modules/mob/living/simple_mob/subtypes/slime/slime.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/slime/slime.dm
@@ -238,4 +238,4 @@ var/global/list/_slime_default_emotes = list(
visible_message("\The [src] squishes!")
/decl/mob_organ_names/slime
- hit_zones = list("cytoplasmic membrane")
\ No newline at end of file
+ hit_zones = list("cytoplasmic membrane")
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index 9e4aa252d0..91d988eaee 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -202,7 +202,7 @@
// Can't control ourselves when drifting
if((isspace(loc) || my_mob.lastarea?.has_gravity == 0) && isturf(loc))
- if(!my_mob.Process_Spacemove(0))
+ if(!my_mob.Process_Spacemove(FALSE))
return 0
// Inside an object, tell it we moved
@@ -395,6 +395,18 @@
/mob/proc/get_jetpack()
return
+// Checks whether this mob is allowed to move in space
+// Return 1 for movement, 0 for none,
+/mob/proc/Allow_Spacemove(var/dense_object)
+ if(restrained())
+ return FALSE
+ var/obj/item/tank/jetpack/J = get_jetpack()
+ if(J?.can_thrust(0.01))
+ return TRUE
+ if(!dense_object) //Nothing to push off of so end here
+ return FALSE
+ return TRUE
+
///Process_Spacemove
///Called by /client/Move()
///For moving in space
@@ -402,26 +414,31 @@
/mob/proc/Process_Spacemove(var/check_drift = 0)
if(is_incorporeal())
- return
+ return FALSE
- if(!Check_Dense_Object()) //Nothing to push off of so end here
- update_floating(0)
- return 0
+ var/dense_object = Check_Dense_Object()
+ if(!Allow_Spacemove())
+ update_floating(dense_object)
+ return FALSE
- update_floating(1)
-
- if(restrained()) //Check to see if we can do things
- return 0
+ var/obj/item/tank/jetpack/thrust = get_jetpack()
+ if(dense_object || ((!check_drift || thrust?.stabilization_on) && !lying && thrust.do_thrust(0.01, src)))
+ inertia_dir = 0
+ return TRUE
+ else if(!dense_object) //Nothing to push off of so end here
+ update_floating(FALSE)
+ return FALSE
//Check to see if we slipped
if(prob(Process_Spaceslipping(5)) && !buckled)
to_chat(src, "You slipped!")
inertia_dir = last_move
step(src, src.inertia_dir) // Not using Move for smooth glide here because this is a 'slip' so should be sudden.
- return 0
+ return FALSE
+
//If not then we can reset inertia and move
inertia_dir = 0
- return 1
+ return TRUE
/mob/proc/Check_Dense_Object() //checks for anything to push off in the vicinity. also handles magboots on gravity-less floors tiles
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index ea7022a060..b7b33494ac 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -419,6 +419,13 @@
var/datum/job/J = SSjob.get_job(rank)
+ // Get the appropriate announcement title.
+ var/announce_rank = rank
+ if(J?.substitute_announce_title)
+ announce_rank = J.substitute_announce_title
+ else if(character.mind.role_alt_title)
+ announce_rank = character.mind.role_alt_title
+
// AIs don't need a spawnpoint, they must spawn at an empty core
if(J.mob_type & JOB_SILICON_AI)
@@ -431,7 +438,7 @@
// AIize the character, but don't move them yet
character = character.AIize(move = FALSE) // Dupe of code in /datum/controller/subsystem/ticker/proc/create_characters() for non-latespawn, unify?
- AnnounceCyborg(character, rank, "has been transferred to the empty core in \the [character.loc.loc]")
+ AnnounceCyborg(character, announce_rank, "has been transferred to the empty core in \the [character.loc.loc]")
ticker.mode.latespawn(character)
qdel(C) //Deletes empty core (really?)
@@ -453,10 +460,10 @@
var/do_announce = join_props["announce"] && join_message && announce_channel
if(J.mob_type & JOB_SILICON)
if(do_announce)
- AnnounceCyborg(character, rank, join_message, announce_channel, character.z)
+ AnnounceCyborg(character, announce_rank, join_message, announce_channel, character.z)
else
if(do_announce)
- AnnounceArrival(character, J?.substitute_announce_title || rank, join_message, announce_channel, character.z)
+ AnnounceArrival(character, announce_rank, join_message, announce_channel, character.z)
data_core.manifest_inject(character)
ticker.minds += character.mind//Cyborgs and AIs handle this in the transform proc. //TODO!!!!! ~Carn
@@ -465,8 +472,6 @@
/mob/new_player/proc/AnnounceCyborg(var/mob/living/character, var/rank, var/join_message, var/channel, var/zlevel)
if (ticker.current_state == GAME_STATE_PLAYING)
var/list/zlevels = zlevel ? using_map.get_map_levels(zlevel, TRUE, om_range = DEFAULT_OVERMAP_RANGE) : null
- if(character.mind.role_alt_title)
- rank = character.mind.role_alt_title
// can't use their name here, since cyborg namepicking is done post-spawn, so we'll just say "A new Cyborg has arrived"/"A new Android has arrived"/etc.
global_announcer.autosay("A new[rank ? " [rank]" : " visitor" ] [join_message ? join_message : "has arrived on the station"].", "Arrivals Announcement Computer", channel, zlevels)
diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm
index c7f0efe4d2..022cba9ccc 100644
--- a/code/modules/mob/transform_procs.dm
+++ b/code/modules/mob/transform_procs.dm
@@ -136,7 +136,7 @@
return O
//human -> robot
-/mob/living/carbon/human/proc/Robotize()
+/mob/living/carbon/human/proc/Robotize(supplied_robot_type = /mob/living/silicon/robot)
if (transforming)
return
for(var/obj/item/W in src)
@@ -149,7 +149,7 @@
for(var/t in organs)
qdel(t)
- var/mob/living/silicon/robot/O = new /mob/living/silicon/robot( loc )
+ var/mob/living/silicon/robot/O = new supplied_robot_type( loc )
// cyborgs produced by Robotize get an automatic power cell
O.cell = new(O)
@@ -171,15 +171,12 @@
O.loc = loc
O.job = "Cyborg"
- if(O.mind.assigned_role == "Cyborg")
- if(O.mind.role_alt_title == "Robot")
- O.mmi = new /obj/item/mmi/digital/posibrain(O)
- else if(O.mind.role_alt_title == "Drone")
- O.mmi = new /obj/item/mmi/digital/robot(O)
- else
- O.mmi = new /obj/item/mmi(O)
- O.mmi.transfer_identity(src)
+ if(O.mind.assigned_role == "Cyborg")
+ var/mmi_type = SSrobots.get_mmi_type_by_title(O.mind.role_alt_title ? O.mind.role_alt_title : O.mind.assigned_role)
+ if(mmi_type)
+ O.mmi = new mmi_type(O)
+ O.mmi.transfer_identity(src)
if(O.client && O.client.prefs)
var/datum/preferences/B = O.client.prefs
diff --git a/code/modules/paperwork/handlabeler.dm b/code/modules/paperwork/handlabeler.dm
index 649a926fe2..ceb8b74d21 100644
--- a/code/modules/paperwork/handlabeler.dm
+++ b/code/modules/paperwork/handlabeler.dm
@@ -29,18 +29,6 @@
if(length(A.name) + length(label) > 64)
to_chat(user, SPAN_WARNING("\The [src]'s label too big."))
return
- if(istype(A, /mob/living/silicon/robot/platform))
- var/mob/living/silicon/robot/platform/P = A
- if(!P.allowed(user))
- to_chat(usr, SPAN_WARNING("Access denied."))
- else if(P.client || P.key)
- to_chat(user, SPAN_NOTICE("You rename \the [P] to [label]."))
- to_chat(P, SPAN_NOTICE("\The [user] renames you to [label]."))
- P.custom_name = label
- P.SetName(P.custom_name)
- else
- to_chat(user, SPAN_WARNING("\The [src] is inactive and cannot be renamed."))
- return
if(ishuman(A))
to_chat(user, SPAN_WARNING("The label refuses to stick to [A.name]."))
return
@@ -80,4 +68,4 @@
label = str
to_chat(user, SPAN_NOTICE("You set the text to '[str]'."))
else
- to_chat(user, SPAN_NOTICE("You turn off \the [src]."))
\ No newline at end of file
+ to_chat(user, SPAN_NOTICE("You turn off \the [src]."))
diff --git a/code/modules/research/prosfab_designs.dm b/code/modules/research/prosfab_designs.dm
index a89cf7eea7..11d29d553d 100644
--- a/code/modules/research/prosfab_designs.dm
+++ b/code/modules/research/prosfab_designs.dm
@@ -277,10 +277,24 @@
/datum/design/item/prosfab/cyborg/exoskeleton
name = "Robot Exoskeleton"
id = "robot_exoskeleton"
- build_path = /obj/item/robot_parts/robot_suit
+ build_path = /obj/item/robot_parts/frame
time = 50
materials = list(MAT_STEEL = 37500)
+/datum/design/item/prosfab/cyborg/exoskeleton_flying
+ name = "Flying Robot Exoskeleton"
+ id = "robot_exoskeleton_flyer"
+ build_path = /obj/item/robot_parts/frame/flyer
+ time = 40
+ materials = list(MAT_STEEL = 32500)
+
+/datum/design/item/prosfab/cyborg/exoskeleton_platform
+ name = "Platform Exoskeleton"
+ id = "robot_exoskeleton_platform"
+ build_path = /obj/item/robot_parts/frame/platform
+ time = 60
+ materials = list(MAT_STEEL = 42500)
+
/datum/design/item/prosfab/cyborg/torso
name = "Robot Torso"
id = "robot_torso"
@@ -366,6 +380,11 @@
id = "platform_armour"
build_path = /obj/item/robot_parts/robot_component/armour_platform
+/datum/design/item/prosfab/cyborg/component/armour_light
+ name = "Armour Plating (Light)"
+ id = "light_armour"
+ build_path = /obj/item/robot_parts/robot_component/armour_light
+
/datum/design/item/prosfab/cyborg/component/ai_shell
name = "AI Remote Interface"
id = "mmi_ai_shell"
diff --git a/code/modules/xenoarcheaology/finds/find_spawning.dm b/code/modules/xenoarcheaology/finds/find_spawning.dm
index 134fcd6243..7789923b44 100644
--- a/code/modules/xenoarcheaology/finds/find_spawning.dm
+++ b/code/modules/xenoarcheaology/finds/find_spawning.dm
@@ -424,7 +424,7 @@
//robot remains
apply_prefix = FALSE
item_type = "[pick("mechanical","robotic","cyborg")] [pick("remains","chassis","debris")]"
- icon = 'icons/mob/robots.dmi'
+ icon = 'icons/mob/robot_gibs.dmi'
icon_state = "remainsrobot"
additional_desc = pick("Almost mistakeable for the remains of a modern cyborg.",\
"They are barely recognisable as anything other than a pile of waste metals.",\
diff --git a/code/unit_tests/icon_tests.dm b/code/unit_tests/icon_tests.dm
new file mode 100644
index 0000000000..e3cb07eb34
--- /dev/null
+++ b/code/unit_tests/icon_tests.dm
@@ -0,0 +1,139 @@
+/datum/unit_test/robot_module_icons_shall_be_valid
+ name = "ICONS: Robot module icons shall be valid"
+ var/list/check_module_categories = list(
+ ROBOT_MODULE_TYPE_GROUNDED,
+ ROBOT_MODULE_TYPE_FLYING
+ )
+ var/list/panel_overlays = list(
+ "ov-openpanel +w",
+ "ov-openpanel +c",
+ "ov-openpanel -c"
+ )
+ var/list/gear_to_check = list(
+ /obj/item/borg/combat/shield = "-shield",
+ /obj/item/borg/combat/mobility = "-roll"
+ )
+
+/datum/unit_test/robot_module_icons_shall_be_valid/start_test()
+
+ var/list/failures = list()
+ // fetch our icon states to check against
+ var/list/icon_state_cache = list(
+ ROBOT_MODULE_TYPE_GROUNDED = icon_states('icons/mob/robots/robots_grounded.dmi'),
+ ROBOT_MODULE_TYPE_FLYING = icon_states('icons/mob/robots/robots_flying.dmi')
+ )
+
+ var/list/found_states = list() // Keep track of this for checking for unused states later.
+
+ // Kick it off by doing a sprite check on all flying and grounded modules.
+ for(var/module_type in typesof(/obj/item/robot_module))
+
+ // Skip abstract modules and think-tanks as they do icon gen differently.
+ var/obj/item/robot_module/module = module_type
+ if(!initial(module.display_name) || !(initial(module.module_category) in check_module_categories))
+ continue
+
+ module = new module // this will automatically qdelete, but we just want the sprites.
+
+ // Check that the expected states are actually in the icon file.
+ var/check_states = icon_state_cache[module.module_category]
+ for(var/sprite in module.sprites)
+
+ // Basic sprite.
+ var/check_state = module.sprites[sprite]
+ if(check_state in check_states)
+ LAZYDISTINCTADD(found_states[module.module_category], check_state)
+ else
+ failures += "missing base state '[check_state]' for [module.display_name] ([module.module_category])"
+
+ // Eyes overlay.
+ var/eye_check_state = "eyes-[check_state]"
+ if(eye_check_state in check_states)
+ LAZYDISTINCTADD(found_states[module.module_category], eye_check_state)
+ else
+ failures += "missing eyes state '[eye_check_state]' for [module.display_name] ([module.module_category])"
+
+ // Equipment overlays.
+ for(var/geartype in gear_to_check)
+ var/suffix = gear_to_check[geartype]
+ for(var/gear in module.modules)
+ if(!ispath(gear, geartype))
+ continue
+ var/gear_check_state = "[check_state][suffix]"
+ if(gear_check_state in check_states)
+ LAZYDISTINCTADD(found_states[module.module_category], gear_check_state)
+ else
+ failures += "missing gear state '[gear_check_state]' for [module.display_name] ([module.module_category])"
+ break
+
+ // Check for drone AI eyes.
+ if(istype(module, /obj/item/robot_module/drone))
+ var/ai_eye_state = "[eye_check_state]-ai"
+ if(ai_eye_state in check_states)
+ LAZYDISTINCTADD(found_states[module.module_category], ai_eye_state)
+ else
+ failures += "missing drone AI control state '[ai_eye_state]' for [module.display_name] ([module.module_category])"
+
+ // Check for missing panel states.
+ for(var/module_category in check_module_categories)
+ var/list/check_states = icon_state_cache[module_category]
+ for(var/panel_state in panel_overlays)
+ if(panel_state in check_states)
+ LAZYDISTINCTADD(found_states[module_category], panel_state)
+ else
+ failures += "missing panel state '[panel_state]' for [module_category]"
+
+ // Now we can do tachikoma sprites.
+ var/list/tachikoma_icon_states = list()
+ for(var/module_type in typesof(/obj/item/robot_module/robot/platform))
+ // Skip abstract modules.
+ var/obj/item/robot_module/robot/platform/module = module_type
+ if(!initial(module.display_name) || !initial(module.module_category) || !initial(module.user_icon))
+ continue
+
+ // We need a module instance to check the decal list.
+ module = new module_type
+ if(!tachikoma_icon_states[module.user_icon])
+ tachikoma_icon_states[module.user_icon] = icon_states(module.user_icon)
+ LAZYDISTINCTADD(icon_state_cache[ROBOT_MODULE_TYPE_PLATFORM], tachikoma_icon_states[module.user_icon])
+
+/*
+unexpected state 'tachi_cross' for platform
+unexpected state 'tachi-open-wires' for platform
+unexpected state 'tachi-open-cell' for platform
+*/
+ var/list/states_to_check = list(
+ "blank",
+ module.user_icon_state,
+ "[module.user_icon_state]-open",
+ "[module.user_icon_state]-wires",
+ "[module.user_icon_state]-cell",
+ "[module.user_icon_state]-nowires"
+ )
+ if(module.armor_color)
+ states_to_check += "[module.user_icon_state]_armour"
+ for(var/decal in module.decals)
+ states_to_check += "[module.user_icon_state]_[decal]"
+ if(module.eye_color)
+ states_to_check += "[module.user_icon_state]_eyes"
+ if(module.pupil_color)
+ states_to_check += "[module.user_icon_state]_pupils"
+
+ for(var/check_state in states_to_check)
+ if(check_state in tachikoma_icon_states[module.user_icon])
+ LAZYDISTINCTADD(found_states[ROBOT_MODULE_TYPE_PLATFORM], check_state)
+ else
+ failures += "missing platform state '[check_state]' in icon file [module.user_icon]"
+
+ // Check that there aren't any unexpected states.
+ for(var/module_category in icon_state_cache)
+ var/list/check_found_states = LAZYACCESS(found_states, module_category)
+ for(var/check_state in icon_state_cache[module_category])
+ if(!(check_state in check_found_states))
+ failures += "unexpected state '[check_state]' for [module_category]"
+
+ if(length(failures))
+ fail("Some robot module sprites are invalid:\n" + failures.Join("\n"))
+ else
+ pass("All robot module sprites are valid.")
+ return 1
diff --git a/icons/mob/robot_gibs.dmi b/icons/mob/robot_gibs.dmi
new file mode 100644
index 0000000000..79ccbf7370
Binary files /dev/null and b/icons/mob/robot_gibs.dmi differ
diff --git a/icons/mob/robots.dmi b/icons/mob/robots.dmi
deleted file mode 100644
index 42ffba5547..0000000000
Binary files a/icons/mob/robots.dmi and /dev/null differ
diff --git a/icons/mob/robots/robot_unused.dmi b/icons/mob/robots/robot_unused.dmi
new file mode 100644
index 0000000000..63c52b2eb1
Binary files /dev/null and b/icons/mob/robots/robot_unused.dmi differ
diff --git a/icons/mob/robots/robots_flying.dmi b/icons/mob/robots/robots_flying.dmi
new file mode 100644
index 0000000000..9e59bb8bf2
Binary files /dev/null and b/icons/mob/robots/robots_flying.dmi differ
diff --git a/icons/mob/robots/robots_grounded.dmi b/icons/mob/robots/robots_grounded.dmi
new file mode 100644
index 0000000000..d7b1df3a71
Binary files /dev/null and b/icons/mob/robots/robots_grounded.dmi differ
diff --git a/icons/mob/robots/robots_platform.dmi b/icons/mob/robots/robots_platform.dmi
new file mode 100644
index 0000000000..364eaef48d
Binary files /dev/null and b/icons/mob/robots/robots_platform.dmi differ
diff --git a/icons/mob/robots_thinktank.dmi b/icons/mob/robots_thinktank.dmi
deleted file mode 100644
index 471647bf60..0000000000
Binary files a/icons/mob/robots_thinktank.dmi and /dev/null differ
diff --git a/icons/obj/robot_parts.dmi b/icons/obj/robot_parts.dmi
index 9461028091..724a179add 100644
Binary files a/icons/obj/robot_parts.dmi and b/icons/obj/robot_parts.dmi differ
diff --git a/icons/obj/robot_parts_flying.dmi b/icons/obj/robot_parts_flying.dmi
new file mode 100644
index 0000000000..43c81d957d
Binary files /dev/null and b/icons/obj/robot_parts_flying.dmi differ
diff --git a/icons/obj/robot_parts_platform.dmi b/icons/obj/robot_parts_platform.dmi
new file mode 100644
index 0000000000..390c3e7ba3
Binary files /dev/null and b/icons/obj/robot_parts_platform.dmi differ
diff --git a/maps/cynosure/cynosure-2.dmm b/maps/cynosure/cynosure-2.dmm
index a2643da8e0..5b7b39a368 100644
--- a/maps/cynosure/cynosure-2.dmm
+++ b/maps/cynosure/cynosure-2.dmm
@@ -20941,7 +20941,6 @@
/area/shuttle/exploration/general)
"jDG" = (
/obj/machinery/mech_recharger,
-/obj/effect/landmark/robot_platform/cargo,
/turf/simulated/floor/tiled/dark,
/area/surface/station/quartermaster/lockerroom)
"jDW" = (
@@ -37761,7 +37760,6 @@
/area/surface/station/library)
"qCU" = (
/obj/machinery/mech_recharger,
-/obj/effect/landmark/robot_platform/explorer,
/turf/simulated/floor/tiled/dark,
/area/surface/station/garage)
"qCW" = (
@@ -43241,7 +43239,6 @@
/area/surface/station/quartermaster/lockerroom)
"tdK" = (
/obj/machinery/mech_recharger,
-/obj/effect/landmark/robot_platform/explorer,
/obj/machinery/firealarm{
pixel_y = 24
},
diff --git a/maps/cynosure/cynosure-6.dmm b/maps/cynosure/cynosure-6.dmm
index 6c287bd15f..ed96d787a2 100644
--- a/maps/cynosure/cynosure-6.dmm
+++ b/maps/cynosure/cynosure-6.dmm
@@ -7793,7 +7793,7 @@
/turf/simulated/floor/tiled/milspec/dark,
/area/shuttle/escape/centcom)
"iNR" = (
-/obj/item/robot_parts/robot_suit,
+/obj/item/robot_parts/frame,
/obj/item/robot_parts/r_leg,
/obj/item/robot_parts/r_arm,
/turf/simulated/shuttle/plating,
diff --git a/maps/cynosure/cynosure.dm b/maps/cynosure/cynosure.dm
index c300cfa910..26fe33d8d3 100644
--- a/maps/cynosure/cynosure.dm
+++ b/maps/cynosure/cynosure.dm
@@ -5,7 +5,6 @@
#include "cynosure_jobs.dm"
#include "cynosure_elevator.dm"
#include "cynosure_events.dm"
- #include "cynosure_overrides.dm"
#include "cynosure_presets.dm"
#include "cynosure_shuttles.dm"
diff --git a/maps/cynosure/cynosure_overrides.dm b/maps/cynosure/cynosure_overrides.dm
deleted file mode 100644
index ec7b607d0b..0000000000
--- a/maps/cynosure/cynosure_overrides.dm
+++ /dev/null
@@ -1,9 +0,0 @@
-/mob/living/silicon/robot/platform/explorer
- req_access = list(access_explorer)
-
-/mob/living/silicon/robot/platform/cargo
- req_access = list(access_cargo_bot)
-
-/obj/item/card/id/platform/Initialize()
- . = ..()
- access |= access_explorer
diff --git a/maps/northern_star/polaris-2.dmm b/maps/northern_star/polaris-2.dmm
index f7a285787f..3c6cc6c4d1 100644
--- a/maps/northern_star/polaris-2.dmm
+++ b/maps/northern_star/polaris-2.dmm
@@ -2285,7 +2285,7 @@
"RW" = (/obj/structure/table/rack,/obj/item/grenade/empgrenade,/obj/item/grenade/flashbang,/obj/item/grenade/spawnergrenade/manhacks,/turf/simulated/shuttle/floor/red,/area/skipjack_station/start)
"RX" = (/obj/structure/table/steel,/obj/machinery/recharger,/obj/machinery/light/small{dir = 4},/turf/simulated/shuttle/floor/red,/area/skipjack_station/start)
"RY" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/shuttle/plating,/area/skipjack_station/start)
-"RZ" = (/obj/item/robot_parts/robot_suit,/obj/item/robot_parts/r_leg,/obj/item/robot_parts/r_arm,/turf/simulated/shuttle/plating,/area/skipjack_station/start)
+"RZ" = (/obj/item/robot_parts/frame,/obj/item/robot_parts/r_leg,/obj/item/robot_parts/r_arm,/turf/simulated/shuttle/plating,/area/skipjack_station/start)
"Sa" = (/obj/machinery/computer/communications,/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station)
"Sb" = (/obj/structure/sign/double/map/left{pixel_y = 32},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station)
"Sc" = (/obj/structure/sign/double/map/right{pixel_y = 32},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station)
diff --git a/maps/overmap/bearcat/bearcat.dmm b/maps/overmap/bearcat/bearcat.dmm
index cd69db0be2..51f6df01f6 100644
--- a/maps/overmap/bearcat/bearcat.dmm
+++ b/maps/overmap/bearcat/bearcat.dmm
@@ -107,7 +107,7 @@
"cc" = (/obj/machinery/light/small{ icon_state = "bulb1"; dir = 4},/obj/machinery/atmospherics/pipe/simple{ icon_state = "intact"; dir = 2; level = 2},/turf/simulated/floor/plating,/area/ship/scrap/crew)
"cd" = (/turf/simulated/wall/r_wall,/area/ship/scrap/crew/saloon)
"ce" = (/obj/machinery/atmospherics/pipe/simple{ icon_state = "intact"; dir = 2; level = 2},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/maintenance_hatch{name = "Hatch"; normalspeed = 0},/turf/simulated/floor{icon_state = "white"},/area/ship/scrap/crew/saloon)
-"cf" = (/obj/machinery/light/small{ icon_state = "bulb1"; dir = 8},/obj/item/crowbar,/obj/machinery/atmospherics/pipe/simple{ icon_state = "intact"; dir = 2; level = 2},/turf/simulated/floor/plating,/area/ship/scrap/crew)
+"cf" = (/obj/machinery/light/small{ icon_state = "bulb1"; dir = 8},/obj/item/tool/crowbar,/obj/machinery/atmospherics/pipe/simple{ icon_state = "intact"; dir = 2; level = 2},/turf/simulated/floor/plating,/area/ship/scrap/crew)
"cg" = (/turf/simulated/wall/r_wall,/area/ship/scrap/crew/dorms)
"ch" = (/obj/structure/sign/poster,/turf/simulated/wall,/area/ship/scrap/crew/dorms)
"ci" = (/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/structure/grille,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "scraplock"; name = "External Blast Doors"; opacity = 0},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/simulated/floor{icon_state = "white"},/area/ship/scrap/crew/dorms)
@@ -229,7 +229,7 @@
"eu" = (/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/ship/scrap/maintenance/engine)
"ev" = (/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating/airless,/area/ship/scrap/maintenance/engine)
"ew" = (/obj/structure/window/reinforced{dir = 1},/obj/machinery/light/small{ icon_state = "bulb1"; dir = 1},/turf/simulated/floor/plating/airless,/area/ship/scrap/maintenance/engine)
-"ex" = (/obj/item/screwdriver,/turf/simulated/floor/plating,/area)
+"ex" = (/obj/item/tool/screwdriver,/turf/simulated/floor/plating,/area)
"ey" = (/turf/simulated/wall,/area/ship/scrap/crew/wash)
"ez" = (/obj/structure/closet/crate,/obj/item/stack/sheet/metal{amount = 50},/obj/item/stack/sheet/metal{amount = 50},/turf/simulated/floor{ icon_state = "bot"; dir = 2},/area/ship/scrap/cargo)
"eA" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple{ icon_state = "intact"; dir = 2; level = 2},/turf/simulated/floor,/area/ship/scrap/cargo)
@@ -326,7 +326,7 @@
"gn" = (/obj/machinery/atmospherics/pipe/simple{dir = 4; icon_state = "intact"; level = 2},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{ icon_state = "floorgrime"; dir = 6},/area/ship/scrap/maintenance)
"go" = (/obj/machinery/atmospherics/pipe/simple{dir = 4; icon_state = "intact"; level = 2},/turf/simulated/floor/plating,/area/ship/scrap/maintenance)
"gp" = (/obj/machinery/atmospherics/pipe/manifold4w{level = 2},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/light/small{dir = 8; icon_state = "bulb1"; pixel_y = 16},/turf/simulated/floor,/area/ship/scrap/maintenance)
-"gq" = (/obj/machinery/atmospherics/pipe/simple{dir = 4; icon_state = "intact"; level = 2},/obj/machinery/light/small{ icon_state = "bulb1"; dir = 1},/obj/item/crowbar,/turf/simulated/floor/plating,/area/ship/scrap/maintenance)
+"gq" = (/obj/machinery/atmospherics/pipe/simple{dir = 4; icon_state = "intact"; level = 2},/obj/machinery/light/small{ icon_state = "bulb1"; dir = 1},/obj/item/tool/crowbar,/turf/simulated/floor/plating,/area/ship/scrap/maintenance)
"gr" = (/obj/machinery/atmospherics/pipe/simple{dir = 9; icon_state = "intact"; level = 2},/turf/simulated/floor{ icon_state = "wall_thermite"; dir = 2},/area/ship/scrap/maintenance)
"gs" = (/turf/simulated/wall/r_wall,/area/ship/scrap/maintenance/atmos)
"gt" = (/turf/simulated/wall,/area/ship/scrap/maintenance/atmos)
diff --git a/maps/southern_cross/southern_cross-1.dmm b/maps/southern_cross/southern_cross-1.dmm
index b627d8ba12..25aebcf1ec 100644
--- a/maps/southern_cross/southern_cross-1.dmm
+++ b/maps/southern_cross/southern_cross-1.dmm
@@ -72947,7 +72947,6 @@
},
/obj/machinery/mech_recharger,
/obj/effect/floor_decal/industrial/hatch/yellow,
-/obj/effect/landmark/robot_platform/cargo,
/turf/simulated/floor/tiled/steel,
/area/quartermaster/warehouse)
"cHa" = (
diff --git a/maps/southern_cross/southern_cross-3.dmm b/maps/southern_cross/southern_cross-3.dmm
index 6b0e9bdea6..c4df22abeb 100644
--- a/maps/southern_cross/southern_cross-3.dmm
+++ b/maps/southern_cross/southern_cross-3.dmm
@@ -13977,7 +13977,6 @@
dir = 4
},
/obj/machinery/mech_recharger,
-/obj/effect/landmark/robot_platform/explorer,
/turf/simulated/floor/plating,
/area/surface/outpost/main/garage)
"GT" = (
@@ -14102,7 +14101,6 @@
"Lz" = (
/obj/effect/floor_decal/industrial/hatch/yellow,
/obj/machinery/mech_recharger,
-/obj/effect/landmark/robot_platform/explorer,
/turf/simulated/floor/plating,
/area/surface/outpost/main/garage)
"LH" = (
diff --git a/maps/southern_cross/southern_cross-6.dmm b/maps/southern_cross/southern_cross-6.dmm
index e458bae5c8..63b0baebcd 100644
--- a/maps/southern_cross/southern_cross-6.dmm
+++ b/maps/southern_cross/southern_cross-6.dmm
@@ -2135,7 +2135,7 @@
"Pc" = (/obj/structure/table/steel,/obj/machinery/recharger,/obj/machinery/light/small{dir = 4},/turf/simulated/shuttle/floor/darkred,/area/skipjack_station/start)
"Pd" = (/obj/machinery/portable_atmospherics/canister/oxygen,/turf/simulated/shuttle/floor/darkred,/area/skipjack_station/start)
"Pe" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/shuttle/plating,/area/skipjack_station/start)
-"Pf" = (/obj/item/robot_parts/robot_suit,/obj/item/robot_parts/r_leg,/obj/item/robot_parts/r_arm,/turf/simulated/shuttle/plating,/area/skipjack_station/start)
+"Pf" = (/obj/item/robot_parts/frame,/obj/item/robot_parts/r_leg,/obj/item/robot_parts/r_arm,/turf/simulated/shuttle/plating,/area/skipjack_station/start)
"Pg" = (/obj/structure/flight_left{icon_state = "left"; dir = 8},/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start)
"Ph" = (/obj/item/radio/intercom{desc = "Talk through this. Evilly"; frequency = 1213; name = "Syndicate Intercom"; pixel_x = 32; subspace_transmission = 1; syndie = 1},/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start)
"Pi" = (/obj/item/radio/intercom{desc = "Talk through this. Evilly"; frequency = 1213; name = "Syndicate Intercom"; pixel_x = -32; subspace_transmission = 1; syndie = 1},/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start)
diff --git a/maps/southern_cross/southern_cross.dm b/maps/southern_cross/southern_cross.dm
index 8339b085cc..ed9528b552 100644
--- a/maps/southern_cross/southern_cross.dm
+++ b/maps/southern_cross/southern_cross.dm
@@ -7,7 +7,6 @@
#include "southern_cross_jobs.dm"
#include "southern_cross_elevator.dm"
#include "southern_cross_events.dm"
- #include "southern_cross_overrides.dm"
#include "southern_cross_presets.dm"
#include "southern_cross_shuttles.dm"
@@ -56,4 +55,4 @@
#warn A map has already been included, ignoring Southern Cross
-#endif
\ No newline at end of file
+#endif
diff --git a/maps/southern_cross/southern_cross_overrides.dm b/maps/southern_cross/southern_cross_overrides.dm
deleted file mode 100644
index 5458cb51da..0000000000
--- a/maps/southern_cross/southern_cross_overrides.dm
+++ /dev/null
@@ -1,10 +0,0 @@
-/mob/living/silicon/robot/platform/explorer
- req_access = list(access_explorer)
-
-/mob/living/silicon/robot/platform/cargo
- req_access = list(access_cargo_bot)
-
-/obj/item/card/id/platform/Initialize()
- . = ..()
- access |= access_explorer
- access |= access_pilot
diff --git a/polaris.dme b/polaris.dme
index be8eeacc52..89e903b963 100644
--- a/polaris.dme
+++ b/polaris.dme
@@ -244,6 +244,7 @@
#include "code\controllers\subsystems\persistence.dm"
#include "code\controllers\subsystems\planets.dm"
#include "code\controllers\subsystems\radiation.dm"
+#include "code\controllers\subsystems\robots.dm"
#include "code\controllers\subsystems\shuttles.dm"
#include "code\controllers\subsystems\skybox.dm"
#include "code\controllers\subsystems\sqlite.dm"
@@ -1017,6 +1018,7 @@
#include "code\game\objects\items\devices\radio\jammer.dm"
#include "code\game\objects\items\devices\radio\radio.dm"
#include "code\game\objects\items\devices\radio\radiopack.dm"
+#include "code\game\objects\items\robot\robot_frame.dm"
#include "code\game\objects\items\mines\_mine.dm"
#include "code\game\objects\items\mines\_mine_payload.dm"
#include "code\game\objects\items\mines\mine_assembly.dm"
@@ -2447,10 +2449,12 @@
#include "code\modules\mob\living\silicon\robot\drone\swarm.dm"
#include "code\modules\mob\living\silicon\robot\drone\swarm_abilities.dm"
#include "code\modules\mob\living\silicon\robot\drone\swarm_items.dm"
+#include "code\modules\mob\living\silicon\robot\robot_modules\_module.dm"
#include "code\modules\mob\living\silicon\robot\robot_modules\event.dm"
#include "code\modules\mob\living\silicon\robot\robot_modules\station.dm"
#include "code\modules\mob\living\silicon\robot\robot_modules\swarm.dm"
#include "code\modules\mob\living\silicon\robot\robot_modules\syndicate.dm"
+#include "code\modules\mob\living\silicon\robot\subtypes\flying.dm"
#include "code\modules\mob\living\silicon\robot\subtypes\gravekeeper.dm"
#include "code\modules\mob\living\silicon\robot\subtypes\lost_drone.dm"
#include "code\modules\mob\living\silicon\robot\subtypes\syndicate.dm"
@@ -2459,7 +2463,6 @@
#include "code\modules\mob\living\silicon\robot\subtypes\thinktank\thinktank_interactions.dm"
#include "code\modules\mob\living\silicon\robot\subtypes\thinktank\thinktank_module.dm"
#include "code\modules\mob\living\silicon\robot\subtypes\thinktank\thinktank_storage.dm"
-#include "code\modules\mob\living\silicon\robot\subtypes\thinktank\thinktank_subtypes.dm"
#include "code\modules\mob\living\simple_mob\appearance.dm"
#include "code\modules\mob\living\simple_mob\butchering.dm"
#include "code\modules\mob\living\simple_mob\combat.dm"
@@ -3314,6 +3317,7 @@
#include "code\modules\xgm\xgm_gas_data.dm"
#include "code\modules\xgm\xgm_gas_mixture.dm"
#include "code\unit_tests\decl_tests.dm"
+#include "code\unit_tests\icon_tests.dm"
#include "code\unit_tests\language_tests.dm"
#include "code\unit_tests\loadout_tests.dm"
#include "code\unit_tests\map_tests.dm"