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"