diff --git a/code/game/objects/items/broom.dm b/code/game/objects/items/broom.dm index 6b89ab7b792..4f7cb137d30 100644 --- a/code/game/objects/items/broom.dm +++ b/code/game/objects/items/broom.dm @@ -68,13 +68,24 @@ * * user - The user of the pushbroom * * A - The atom which is located at the location to push atoms from */ -/obj/item/pushbroom/proc/sweep(mob/user, atom/A) +/obj/item/pushbroom/proc/sweep(mob/user, atom/atom) SIGNAL_HANDLER - var/turf/current_item_loc = isturf(A) ? A : A.loc + do_sweep(src, user, atom, user.dir) + +/** +* Sweep objects in the direction we're facing towards our direction +* Arguments +* * broomer - The object being used for brooming +* * user - The person who is brooming +* * target - The object or tile that's target of a broom click or being moved into +* * sweep_dir - The directions in which we sweep objects +*/ +/proc/do_sweep(obj/broomer, mob/user, atom/target, sweep_dir) + var/turf/current_item_loc = isturf(target) ? target : target.loc if (!isturf(current_item_loc)) return - var/turf/new_item_loc = get_step(current_item_loc, user.dir) + var/turf/new_item_loc = get_step(current_item_loc, sweep_dir) var/list/items_to_sweep = list() var/i = 1 @@ -86,16 +97,15 @@ if(i > BROOM_PUSH_LIMIT) break - SEND_SIGNAL(new_item_loc, COMSIG_TURF_RECEIVE_SWEEPED_ITEMS, src, user, items_to_sweep) + SEND_SIGNAL(new_item_loc, COMSIG_TURF_RECEIVE_SWEEPED_ITEMS, broomer, user, items_to_sweep) if(!length(items_to_sweep)) return for (var/obj/item/garbage in items_to_sweep) - garbage.Move(new_item_loc, user.dir) - - playsound(loc, 'sound/weapons/thudswoosh.ogg', 30, TRUE, -1) + garbage.Move(new_item_loc, sweep_dir) + playsound(current_item_loc, 'sound/weapons/thudswoosh.ogg', 30, TRUE, -1) /obj/item/pushbroom/cyborg name = "cyborg push broom" diff --git a/code/modules/jobs/job_types/roboticist.dm b/code/modules/jobs/job_types/roboticist.dm index 69b58335768..cc03854957c 100644 --- a/code/modules/jobs/job_types/roboticist.dm +++ b/code/modules/jobs/job_types/roboticist.dm @@ -26,7 +26,8 @@ mail_goodies = list( /obj/item/storage/box/flashes = 20, /obj/item/stack/sheet/iron/twenty = 15, - /obj/item/modular_computer/laptop = 5 + /obj/item/modular_computer/laptop = 5, + /obj/item/mmi/posibrain/sphere = 5, ) family_heirlooms = list(/obj/item/toy/plush/pkplush) diff --git a/code/modules/mob/living/brain/MMI.dm b/code/modules/mob/living/brain/MMI.dm index 56693b20b36..1963e13dbf5 100644 --- a/code/modules/mob/living/brain/MMI.dm +++ b/code/modules/mob/living/brain/MMI.dm @@ -14,6 +14,8 @@ var/datum/ai_laws/laws = new() var/force_replace_ai_name = FALSE var/overrides_aicore_laws = FALSE // Whether the laws on the MMI, if any, override possible pre-existing laws loaded on the AI core. + /// Whether the brainmob can move. Doesnt usually matter but SPHERICAL POSIBRAINSSS + var/immobilize = TRUE /obj/item/mmi/Initialize(mapload) . = ..() @@ -250,7 +252,7 @@ if(new_mecha) if(!. && brainmob) // There was no mecha, there now is, and we have a brain mob that is no longer unaided. brainmob.remove_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED), BRAIN_UNAIDED) - else if(. && brainmob) // There was a mecha, there no longer is one, and there is a brain mob that is now again unaided. + else if(. && brainmob && immobilize) // There was a mecha, there no longer is one, and there is a brain mob that is now again unaided. brainmob.add_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED), BRAIN_UNAIDED) diff --git a/code/modules/mob/living/brain/brain.dm b/code/modules/mob/living/brain/brain.dm index bd22fb42eb1..1bacc08a8b6 100644 --- a/code/modules/mob/living/brain/brain.dm +++ b/code/modules/mob/living/brain/brain.dm @@ -14,10 +14,9 @@ var/obj/item/organ/internal/brain/OB = new(loc) //we create a new brain organ for it. OB.brainmob = src forceMove(OB) - if(!container?.mecha) //Unless inside a mecha, brains are rather helpless. + if(!container?.mecha && (!container || container.immobilize)) //Unless inside a mecha, brains are rather helpless. add_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED), BRAIN_UNAIDED) - /mob/living/brain/on_changed_z_level(turf/old_turf, turf/new_turf, same_z_layer, notify_contents) var/obj/item/organ/internal/brain/brain_loc = loc if(brain_loc && isnull(new_turf) && brain_loc.owner) //we're actively being put inside a new body. diff --git a/code/modules/mob/living/brain/posibrain.dm b/code/modules/mob/living/brain/posibrain.dm index 9df1697e400..7d4255d54d5 100644 --- a/code/modules/mob/living/brain/posibrain.dm +++ b/code/modules/mob/living/brain/posibrain.dm @@ -222,3 +222,63 @@ GLOBAL_VAR(posibrain_notify_cooldown) /obj/item/mmi/posibrain/display/is_occupied() return TRUE + +/// Posibrains but spherical. They can roll around and you can kick them +/obj/item/mmi/posibrain/sphere + name = "positronic sphere" + desc = "Recent developments on cost-cutting measures have allowed us to cut positronic brain cubes into twice-as-cheap spheres. \ + Unfortunately, it also allows them to move around the lab via rolling maneuvers." + icon_state = "spheribrain" + base_icon_state = "spheribrain" + immobilize = FALSE + /// Delay between movements + var/move_delay = 0.5 SECONDS + /// when can we move again? + var/can_move + +/obj/item/mmi/posibrain/sphere/Initialize(mapload, autoping) + . = ..() + + var/matrix/matrix = matrix() + transform = matrix.Scale(0.8, 0.8) + + brainmob.remove_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED), BRAIN_UNAIDED) + +/obj/item/mmi/posibrain/sphere/relaymove(mob/living/user, direction) + if(isspaceturf(loc) || !direction || mecha) + return + + if(can_move >= world.time) + return + can_move = world.time + move_delay + + // ESCAPE PRISON + if(ismovable(loc) && prob(25)) + var/obj/item/item = pick(loc.contents) + if(istype(loc, /obj/item/storage)) + item.forceMove(loc.drop_location()) //throw stuff out of the inventory till we free ourselves! + playsound(src, SFX_RUSTLE, 30, TRUE) + return + + // MOVE US + if(isturf(loc)) + can_move = world.time + move_delay + try_step_multiz(direction) + SpinAnimation(move_delay, 1, direction == NORTH || direction == EAST) + +/obj/item/mmi/posibrain/sphere/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change) + . = ..() + if(brainmob && isturf(loc)) + anchored = TRUE //anchor so we dont broom ourselves. + do_sweep(src, brainmob, loc, get_dir(old_loc, loc)) //movement dir doesnt work on objects + anchored = FALSE + +/// Punt the shit across the room +/obj/item/mmi/posibrain/sphere/attack_hand_secondary(mob/user, list/modifiers) + . = ..() + if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN) + return . + throw_at(get_edge_target_turf(src, get_dir(user, src)), 7, 1, user) + user.do_attack_animation(src) + can_move = world.time + move_delay //pweeze stawp + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm index d1722519b5e..25e8326bbcc 100644 --- a/code/modules/research/designs/mechfabricator_designs.dm +++ b/code/modules/research/designs/mechfabricator_designs.dm @@ -2608,3 +2608,21 @@ category = list( RND_CATEGORY_MODSUIT_MODULES + RND_SUBCATEGORY_MODSUIT_MODULES_ENGINEERING ) + +/datum/design/posisphere + name = "Positronic Sphere" + desc = "The latest in Artificial Pesterance." + id = "posisphere" + build_type = MECHFAB + materials = list( + /datum/material/iron = HALF_SHEET_MATERIAL_AMOUNT * 0.85, + /datum/material/glass = HALF_SHEET_MATERIAL_AMOUNT * 0.65, + /datum/material/gold =SMALL_MATERIAL_AMOUNT * 2.5 + ) + construction_time = 7.5 SECONDS + build_path = /obj/item/mmi/posibrain/sphere + category = list( + RND_CATEGORY_MECHFAB_CYBORG + RND_SUBCATEGORY_MECHFAB_CYBORG_CONTROL_INTERFACES + ) + departmental_flags = DEPARTMENT_BITFLAG_SCIENCE + diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index cb1ec6bb1cc..a8ce5f274eb 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -2468,3 +2468,30 @@ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) hidden = TRUE experimental = TRUE + +/datum/techweb_node/mod_experimental + id = "mod_experimental" + display_name = "Experimental Modular Suits" + description = "Applications of experimentality when creating MODsuits have created these..." + prereq_ids = list("base") + design_ids = list( + "mod_disposal", + "mod_joint_torsion", + "mod_recycler", + "mod_shooting", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) + hidden = TRUE + experimental = TRUE + +/datum/techweb_node/posisphere + id = "positronic_sphere" + display_name = "Experimental Spherical Positronic Brain" + description = "Recent developments on cost-cutting measures have allowed us to cut positronic brain cubes into twice-as-cheap spheres. Unfortunately, it also allows them to move around the lab via rolling maneuvers." + prereq_ids = list("base") + design_ids = list( + "posisphere", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) + hidden = TRUE + experimental = TRUE diff --git a/icons/obj/devices/assemblies.dmi b/icons/obj/devices/assemblies.dmi index c1b0fd05f13..95c9227ab3a 100644 Binary files a/icons/obj/devices/assemblies.dmi and b/icons/obj/devices/assemblies.dmi differ