mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-10 17:52:36 +00:00
adds some "factory" machines (#86063)
## About The Pull Request https://github.com/user-attachments/assets/4ceb4c0f-d5ef-4fc0-8436-d7eec5b6f396 https://github.com/user-attachments/assets/56ddd387-7376-4c35-a067-1adccbddeecd https://github.com/user-attachments/assets/dda6cc2b-614a-4adb-a8f4-2c03b51162e0 https://github.com/user-attachments/assets/fa7697fb-f484-48a0-bb85-ee0c2f4867e2 https://github.com/user-attachments/assets/02de4b24-2fa0-4a1e-b147-df9500109b3c https://github.com/user-attachments/assets/b56c03ab-49c9-487f-a99f-fcba5ce038ac https://github.com/user-attachments/assets/52bae5a4-68b0-4f25-99c1-1b677b99790a i didnt feel like recording the lathe and crafter for a suitable file size again but essentially the crafter crafts and the lathe lathes all machines but the router and sorter are cable powered (suitable on lavaland) theyre researched roundstart they can receive any resource that bumps into it if that resource is on the conveyor ## Why It's Good For The Game more fun engineering stuff and perhaps mining given these are more efficient but require effort to set up https://hackmd.io/@jimmyl/S1dZRZosC ## Changelog 🆑 add: added the manufacturing smelter,router,sorter,crafter,lathe,crusher,unloader /🆑 --------- Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
This commit is contained in:
4
code/controllers/subsystem/processing/manufacturing.dm
Normal file
4
code/controllers/subsystem/processing/manufacturing.dm
Normal file
@@ -0,0 +1,4 @@
|
||||
PROCESSING_SUBSYSTEM_DEF(manufacturing)
|
||||
name = "Manufacturing Processing"
|
||||
wait = 1 SECONDS
|
||||
stat_tag = "MN"
|
||||
@@ -21,6 +21,8 @@
|
||||
var/display_craftable_only = FALSE
|
||||
var/display_compact = FALSE
|
||||
var/forced_mode = FALSE
|
||||
/// crafting flags we ignore when considering a recipe
|
||||
var/ignored_flags = NONE
|
||||
|
||||
/* This is what procs do:
|
||||
get_environment - gets a list of things accessable for crafting by user
|
||||
@@ -205,16 +207,16 @@
|
||||
if(!check_tools(crafter, recipe, contents))
|
||||
return ", missing tool."
|
||||
|
||||
var/considered_flags = recipe.crafting_flags & ~(ignored_flags)
|
||||
|
||||
|
||||
if((recipe.crafting_flags & CRAFT_ONE_PER_TURF) && (locate(recipe.result) in dest_turf))
|
||||
if((considered_flags & CRAFT_ONE_PER_TURF) && (locate(recipe.result) in dest_turf))
|
||||
return ", already one here!"
|
||||
|
||||
if(recipe.crafting_flags & CRAFT_CHECK_DIRECTION)
|
||||
if(!valid_build_direction(dest_turf, crafter.dir, is_fulltile = (recipe.crafting_flags & CRAFT_IS_FULLTILE)))
|
||||
if(considered_flags & CRAFT_CHECK_DIRECTION)
|
||||
if(!valid_build_direction(dest_turf, crafter.dir, is_fulltile = (considered_flags & CRAFT_IS_FULLTILE)))
|
||||
return ", won't fit here!"
|
||||
|
||||
if(recipe.crafting_flags & CRAFT_ON_SOLID_GROUND)
|
||||
if(considered_flags & CRAFT_ON_SOLID_GROUND)
|
||||
if(isclosedturf(dest_turf))
|
||||
return ", cannot be made on a wall!"
|
||||
|
||||
@@ -222,7 +224,7 @@
|
||||
if(!locate(/obj/structure/thermoplastic) in dest_turf) // for tram construction
|
||||
return ", must be made on solid ground!"
|
||||
|
||||
if(recipe.crafting_flags & CRAFT_CHECK_DENSITY)
|
||||
if(considered_flags & CRAFT_CHECK_DENSITY)
|
||||
for(var/obj/object in dest_turf)
|
||||
if(object.density && !(object.obj_flags & IGNORE_DENSITY) || object.obj_flags & BLOCKS_CONSTRUCTION)
|
||||
return ", something is in the way!"
|
||||
@@ -703,3 +705,20 @@
|
||||
if(recipe == potential_recipe)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/component/personal_crafting/machine
|
||||
ignored_flags = CRAFT_CHECK_DENSITY
|
||||
|
||||
/datum/component/personal_crafting/machine/get_environment(atom/crafter, list/blacklist = null, radius_range = 1)
|
||||
. = list()
|
||||
for(var/atom/movable/content in crafter.contents)
|
||||
if((content.flags_1 & HOLOGRAM_1) || (blacklist && (content.type in blacklist)))
|
||||
continue
|
||||
if(isitem(content))
|
||||
var/obj/item/item = content
|
||||
if(item.item_flags & ABSTRACT) //let's not tempt fate, shall we?
|
||||
continue
|
||||
. += content
|
||||
|
||||
/datum/component/personal_crafting/machine/check_tools(atom/source, datum/crafting_recipe/recipe, list/surroundings)
|
||||
return TRUE
|
||||
|
||||
@@ -74,3 +74,14 @@
|
||||
)
|
||||
category = CAT_STRUCTURE
|
||||
crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_MUST_BE_LEARNED
|
||||
|
||||
/datum/crafting_recipe/manucrate
|
||||
name = "Manufacturing Storage Unit"
|
||||
result = /obj/machinery/power/manufacturing/storagebox
|
||||
tool_behaviors = list(TOOL_SCREWDRIVER, TOOL_WELDER)
|
||||
time = 6 SECONDS
|
||||
reqs = list(
|
||||
/obj/item/stack/sheet/iron = 10,
|
||||
)
|
||||
category = CAT_STRUCTURE
|
||||
crafting_flags = CRAFT_CHECK_DENSITY
|
||||
|
||||
@@ -1715,3 +1715,65 @@
|
||||
req_components = list(
|
||||
/datum/stock_part/servo = 1,
|
||||
)
|
||||
|
||||
/obj/item/circuitboard/machine/manucrafter
|
||||
name = /obj/machinery/power/manufacturing/crafter::name
|
||||
greyscale_colors = CIRCUIT_COLOR_ENGINEERING
|
||||
build_path = /obj/machinery/power/manufacturing/crafter
|
||||
req_components = list(
|
||||
/obj/item/stack/sheet/iron = 5,
|
||||
/datum/stock_part/servo = 1,
|
||||
)
|
||||
|
||||
/obj/item/circuitboard/machine/manulathe
|
||||
name = /obj/machinery/power/manufacturing/lathe::name
|
||||
greyscale_colors = CIRCUIT_COLOR_ENGINEERING
|
||||
build_path = /obj/machinery/power/manufacturing/lathe
|
||||
req_components = list(
|
||||
/obj/item/stack/sheet/iron = 5,
|
||||
/datum/stock_part/servo = 1,
|
||||
)
|
||||
|
||||
/obj/item/circuitboard/machine/manucrusher
|
||||
name = /obj/machinery/power/manufacturing/crusher::name
|
||||
greyscale_colors = CIRCUIT_COLOR_ENGINEERING
|
||||
build_path = /obj/machinery/power/manufacturing/crusher
|
||||
req_components = list(
|
||||
/obj/item/stack/sheet/iron = 5,
|
||||
/datum/stock_part/servo = 1,
|
||||
)
|
||||
|
||||
/obj/item/circuitboard/machine/manuunloader
|
||||
name = /obj/machinery/power/manufacturing/unloader::name
|
||||
greyscale_colors = CIRCUIT_COLOR_ENGINEERING
|
||||
build_path = /obj/machinery/power/manufacturing/unloader
|
||||
req_components = list(
|
||||
/obj/item/stack/sheet/iron = 5,
|
||||
/datum/stock_part/servo = 1,
|
||||
)
|
||||
|
||||
/obj/item/circuitboard/machine/manusorter
|
||||
name = /obj/machinery/power/manufacturing/sorter::name
|
||||
greyscale_colors = CIRCUIT_COLOR_ENGINEERING
|
||||
build_path = /obj/machinery/power/manufacturing/sorter
|
||||
req_components = list(
|
||||
/obj/item/stack/sheet/iron = 5,
|
||||
/datum/stock_part/scanning_module = 1,
|
||||
)
|
||||
|
||||
/obj/item/circuitboard/machine/manusmelter
|
||||
name = /obj/machinery/power/manufacturing/smelter::name
|
||||
greyscale_colors = CIRCUIT_COLOR_ENGINEERING
|
||||
build_path = /obj/machinery/power/manufacturing/smelter
|
||||
req_components = list(
|
||||
/obj/item/stack/sheet/iron = 5,
|
||||
/datum/stock_part/micro_laser = 1,
|
||||
)
|
||||
|
||||
/obj/item/circuitboard/machine/manurouter
|
||||
name = /obj/machinery/power/manufacturing/router::name
|
||||
greyscale_colors = CIRCUIT_COLOR_ENGINEERING
|
||||
build_path = /obj/machinery/power/manufacturing/router
|
||||
req_components = list(
|
||||
/obj/item/stack/sheet/iron = 5,
|
||||
)
|
||||
|
||||
@@ -270,7 +270,7 @@ GLOBAL_LIST_EMPTY(station_turfs)
|
||||
* * type_list - are we checking for types of atoms to ignore and not physical atoms
|
||||
*/
|
||||
/turf/proc/is_blocked_turf(exclude_mobs = FALSE, source_atom = null, list/ignore_atoms, type_list = FALSE)
|
||||
if(density)
|
||||
if((!isnull(source_atom) && !CanPass(source_atom, get_dir(src, source_atom))) || density)
|
||||
return TRUE
|
||||
|
||||
for(var/atom/movable/movable_content as anything in contents)
|
||||
|
||||
123
code/modules/manufactorio/_manufacturing.dm
Normal file
123
code/modules/manufactorio/_manufacturing.dm
Normal file
@@ -0,0 +1,123 @@
|
||||
#define MANUFACTURING_FAIL_FULL -1
|
||||
#define MANUFACTURING_FAIL 0
|
||||
#define MANUFACTURING_SUCCESS 1
|
||||
|
||||
#define POCKET_INPUT "Input"
|
||||
#define POCKET_OUTPUT "Output"
|
||||
|
||||
#define MANUFACTURING_TURF_LAG_LIMIT 10 // max items on a turf before we consider it full
|
||||
|
||||
/obj/machinery/power/manufacturing
|
||||
icon = 'icons/obj/machines/manufactorio.dmi'
|
||||
name = "base manufacture receiving type"
|
||||
desc = "this shouldnt exist"
|
||||
density = TRUE
|
||||
/// Do we add the simple_rotation component and a text that we are powered by cable? Also allows unwrenching
|
||||
var/may_be_moved = TRUE
|
||||
/// Allow taking in mobs from conveyors?
|
||||
var/allow_mob_bump_intake = FALSE
|
||||
|
||||
/obj/machinery/power/manufacturing/Initialize(mapload)
|
||||
. = ..()
|
||||
if(may_be_moved)
|
||||
AddComponent(/datum/component/simple_rotation)
|
||||
if(anchored)
|
||||
connect_to_network()
|
||||
|
||||
/obj/machinery/power/manufacturing/examine(mob/user)
|
||||
. = ..()
|
||||
if(may_be_moved)
|
||||
. += "It receives power via cable, but certain buildings do not need power."
|
||||
. += length(contents - circuit) ? "It contains:" : "Its empty."
|
||||
for(var/atom/movable/thing as anything in contents - circuit)
|
||||
var/text = thing.name
|
||||
var/obj/item/stack/possible_stack = thing
|
||||
if(istype(possible_stack))
|
||||
text = "[possible_stack.amount] [text]"
|
||||
. += text
|
||||
|
||||
|
||||
/obj/machinery/power/manufacturing/Bumped(atom/movable/bumped_atom) //attempt to put in whatever is pushed into us via conveyor
|
||||
. = ..()
|
||||
if((!allow_mob_bump_intake && ismob(bumped_atom)) || !anchored) //only uncomment if youre brave
|
||||
return
|
||||
var/conveyor = locate(/obj/machinery/conveyor) in bumped_atom.loc
|
||||
if(isnull(conveyor))
|
||||
return
|
||||
receive_resource(bumped_atom, bumped_atom.loc, get_dir(src, bumped_atom))
|
||||
|
||||
/obj/machinery/power/manufacturing/wrench_act(mob/living/user, obj/item/tool)
|
||||
. = ..()
|
||||
if(!may_be_moved)
|
||||
return
|
||||
default_unfasten_wrench(user, tool)
|
||||
if(anchored)
|
||||
connect_to_network()
|
||||
else
|
||||
disconnect_from_network()
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
/obj/machinery/power/manufacturing/screwdriver_act(mob/living/user, obj/item/tool)
|
||||
if(default_deconstruction_screwdriver(user, icon_state, icon_state, tool))
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
return ITEM_INTERACT_BLOCKING
|
||||
|
||||
/obj/machinery/power/manufacturing/crowbar_act(mob/living/user, obj/item/tool)
|
||||
. = ITEM_INTERACT_BLOCKING
|
||||
if(default_deconstruction_crowbar(tool))
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
/obj/machinery/power/manufacturing/proc/generate_io_overlays(direction, color, offsets_override)
|
||||
var/list/dir_offset
|
||||
if(islist(offsets_override))
|
||||
dir_offset = offsets_override
|
||||
else
|
||||
dir_offset = dir2offset(direction)
|
||||
dir_offset[1] *= 32
|
||||
dir_offset[2] *= 32
|
||||
var/image/nonemissive = image(icon='icons/obj/doors/airlocks/station/overlays.dmi', icon_state="unres_[direction]")
|
||||
nonemissive.pixel_x = dir_offset[1]
|
||||
nonemissive.pixel_y = dir_offset[2]
|
||||
nonemissive.color = color
|
||||
var/mutable_appearance/emissive = emissive_appearance(nonemissive.icon, nonemissive.icon_state, offset_spokesman = src, alpha = nonemissive.alpha)
|
||||
emissive.pixel_y = nonemissive.pixel_y
|
||||
emissive.pixel_x = nonemissive.pixel_x
|
||||
return list(nonemissive, emissive)
|
||||
|
||||
/// Returns whatever object it may output, or null if it cant do that
|
||||
/obj/machinery/power/manufacturing/proc/request_resource()
|
||||
|
||||
|
||||
/obj/machinery/power/manufacturing/proc/receive_resource(atom/movable/receiving, atom/from, receive_dir)
|
||||
CRASH("Unimplemented!") //check can_receive_resource here
|
||||
|
||||
//use dir please
|
||||
/obj/machinery/power/manufacturing/proc/send_resource(atom/movable/sending, atom/what_or_dir)
|
||||
if(isobj(what_or_dir))
|
||||
var/obj/machinery/power/manufacturing/target = what_or_dir
|
||||
return target.receive_resource(sending, src, get_step(src, what_or_dir))
|
||||
var/turf/next_turf = isturf(what_or_dir) ? what_or_dir : get_step(src, what_or_dir)
|
||||
var/obj/machinery/power/manufacturing/manufactury = locate(/obj/machinery/power/manufacturing) in next_turf
|
||||
if(!isnull(manufactury))
|
||||
if(!manufactury.anchored)
|
||||
return MANUFACTURING_FAIL
|
||||
return manufactury.receive_resource(sending, src, isturf(what_or_dir) ? get_dir(src, what_or_dir) : what_or_dir)
|
||||
if(next_turf.is_blocked_turf(exclude_mobs = TRUE, source_atom = sending))
|
||||
return MANUFACTURING_FAIL
|
||||
if(length(next_turf.contents) >= MANUFACTURING_TURF_LAG_LIMIT)
|
||||
return MANUFACTURING_FAIL_FULL
|
||||
if(isnull(sending))
|
||||
return MANUFACTURING_SUCCESS // for the sake of being used as a check
|
||||
if(isnull(sending.loc) || !sending.Move(next_turf, get_dir(src, next_turf)))
|
||||
sending.forceMove(next_turf)
|
||||
return MANUFACTURING_SUCCESS
|
||||
|
||||
/// Checks if this stack (if not a stack does not do anything) can merge WITHOUT creating two stacks in contents
|
||||
/obj/machinery/power/manufacturing/proc/may_merge_in_contents(obj/item/stack/stack)
|
||||
if(!istype(stack))
|
||||
return
|
||||
for(var/obj/item/stack/other in contents - circuit)
|
||||
if(!other.can_merge(stack))
|
||||
continue
|
||||
if(other.amount + stack.amount <= other.max_amount)
|
||||
return other
|
||||
139
code/modules/manufactorio/machines/crafter.dm
Normal file
139
code/modules/manufactorio/machines/crafter.dm
Normal file
@@ -0,0 +1,139 @@
|
||||
/obj/machinery/power/manufacturing/crafter
|
||||
name = "manufacturing assembling machine"
|
||||
desc = "Assembles (crafts) the set recipe until it runs out of resources. Inputs irrelevant to the recipe are ignored."
|
||||
icon_state = "crafter"
|
||||
circuit = /obj/item/circuitboard/machine/manucrafter
|
||||
/// power used per process() spent crafting
|
||||
var/power_cost = 5 KILO WATTS
|
||||
/// our output, if the way out was blocked is held here
|
||||
var/atom/movable/withheld
|
||||
/// current recipe
|
||||
var/datum/crafting_recipe/recipe
|
||||
/// crafting component
|
||||
var/datum/component/personal_crafting/machine/craftsman
|
||||
/// current timer for our crafting
|
||||
var/craft_timer
|
||||
/// do we use cooking recipes instead
|
||||
var/cooking = FALSE
|
||||
|
||||
/obj/machinery/power/manufacturing/crafter/Initialize(mapload)
|
||||
. = ..()
|
||||
craftsman = AddComponent(/datum/component/personal_crafting/machine)
|
||||
|
||||
/obj/machinery/power/manufacturing/crafter/examine(mob/user)
|
||||
. = ..()
|
||||
. += span_notice("It is currently manufacturing <b>[isnull(recipe) ? "nothing. Use a multitool to set it" : recipe.name]</b>.")
|
||||
if(isnull(recipe))
|
||||
return
|
||||
. += span_notice("It needs:")
|
||||
for(var/valid_type in recipe.reqs)
|
||||
// Check if they're datums, specifically reagents.
|
||||
var/datum/reagent/reagent_ingredient = valid_type
|
||||
if(istype(reagent_ingredient))
|
||||
var/amount = recipe.reqs[reagent_ingredient]
|
||||
. += "[amount] unit[amount > 1 ? "s" : ""] of [initial(reagent_ingredient.name)]"
|
||||
|
||||
var/atom/ingredient = valid_type
|
||||
var/amount = recipe.reqs[ingredient]
|
||||
|
||||
. += "[amount > 1 ? ("[amount]" + " of") : "a"] [initial(ingredient.name)]"
|
||||
|
||||
/obj/machinery/power/manufacturing/crafter/update_overlays()
|
||||
. = ..()
|
||||
. += generate_io_overlays(dir, COLOR_ORANGE)
|
||||
for(var/target_dir in GLOB.cardinals - dir)
|
||||
. += generate_io_overlays(target_dir, COLOR_MODERATE_BLUE)
|
||||
|
||||
/obj/machinery/power/manufacturing/crafter/proc/valid_for_recipe(obj/item/checking)
|
||||
. = FALSE
|
||||
for(var/requirement_path in recipe.reqs)
|
||||
if(!ispath(checking.type, requirement_path) || recipe.blacklist.Find(checking.type))
|
||||
continue
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/manufacturing/crafter/proc/contains_type(path)
|
||||
. = FALSE
|
||||
for(var/content in contents - circuit)
|
||||
if(!istype(content, path))
|
||||
continue
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/manufacturing/crafter/receive_resource(obj/receiving, atom/from, receive_dir)
|
||||
if(isnull(recipe) || !isitem(receiving) || surplus() < power_cost)
|
||||
return MANUFACTURING_FAIL
|
||||
if(receive_dir == dir || !valid_for_recipe(receiving))
|
||||
return MANUFACTURING_FAIL
|
||||
if(!may_merge_in_contents(receiving) && contains_type(receiving.type))
|
||||
return MANUFACTURING_FAIL_FULL
|
||||
receiving.Move(src, get_dir(receiving, src))
|
||||
START_PROCESSING(SSmanufacturing, src)
|
||||
return MANUFACTURING_SUCCESS
|
||||
|
||||
/obj/machinery/power/manufacturing/crafter/multitool_act(mob/living/user, obj/item/tool)
|
||||
. = NONE
|
||||
var/list/unavailable = list()
|
||||
for(var/datum/crafting_recipe/potential_recipe as anything in cooking ? GLOB.cooking_recipes : GLOB.crafting_recipes)
|
||||
if(craftsman.is_recipe_available(potential_recipe, user))
|
||||
continue
|
||||
var/obj/result = initial(potential_recipe.result)
|
||||
if(istype(result) && initial(result.anchored))
|
||||
continue
|
||||
unavailable += potential_recipe
|
||||
var/result = tgui_input_list(usr, "Recipe", "Select Recipe", (cooking ? GLOB.cooking_recipes : GLOB.crafting_recipes) - unavailable)
|
||||
if(isnull(result) || result == recipe || !user.can_perform_action(src))
|
||||
return ITEM_INTERACT_FAILURE
|
||||
var/dump_target = get_step(src, get_dir(src, user))
|
||||
for(var/atom/movable/thing as anything in contents - circuit)
|
||||
thing.Move(dump_target)
|
||||
recipe = result
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
/obj/machinery/power/manufacturing/crafter/Exited(atom/movable/gone, direction)
|
||||
. = ..()
|
||||
if(gone == withheld)
|
||||
withheld = null
|
||||
|
||||
/obj/machinery/power/manufacturing/crafter/atom_destruction(damage_flag)
|
||||
. = ..()
|
||||
withheld?.Move(drop_location(src))
|
||||
|
||||
/obj/machinery/power/manufacturing/crafter/Destroy()
|
||||
. = ..()
|
||||
recipe = null
|
||||
craftsman = null
|
||||
QDEL_NULL(withheld)
|
||||
|
||||
/obj/machinery/power/manufacturing/crafter/process(seconds_per_tick)
|
||||
if(!isnull(withheld) && !send_resource(withheld, dir))
|
||||
return
|
||||
if(!isnull(craft_timer))
|
||||
if(surplus() >= power_cost)
|
||||
add_load()
|
||||
else
|
||||
deltimer(craft_timer)
|
||||
craft_timer = null
|
||||
say("Power failure!")
|
||||
return
|
||||
if(isnull(recipe) || !craftsman.check_contents(src, recipe, craftsman.get_surroundings(src)))
|
||||
return
|
||||
flick_overlay_view(mutable_appearance(icon, "crafter_printing"), recipe.time)
|
||||
craft_timer = addtimer(CALLBACK(src, PROC_REF(craft), recipe), recipe.time, TIMER_STOPPABLE)
|
||||
|
||||
/obj/machinery/power/manufacturing/crafter/proc/craft(datum/crafting_recipe/recipe)
|
||||
if(QDELETED(src))
|
||||
return
|
||||
craft_timer = null
|
||||
var/atom/movable/result = craftsman.construct_item(src, recipe)
|
||||
if(istype(result))
|
||||
if(isitem(result))
|
||||
result.pixel_x += rand(-4, 4)
|
||||
result.pixel_y += rand(-4, 4)
|
||||
result.Move(src)
|
||||
send_resource(result, dir)
|
||||
else
|
||||
say(result)
|
||||
|
||||
/obj/machinery/power/manufacturing/crafter/cooker
|
||||
name = "manufacturing cooking machine" // maybe this shouldnt be available dont wanna make chef useless, though otherwise it would need a sprite
|
||||
desc = "Cooks the set recipe until it runs out of resources. Inputs irrelevant to the recipe are ignored."
|
||||
cooking = TRUE
|
||||
83
code/modules/manufactorio/machines/crusher.dm
Normal file
83
code/modules/manufactorio/machines/crusher.dm
Normal file
@@ -0,0 +1,83 @@
|
||||
/obj/machinery/power/manufacturing/crusher //todo make it work for other stuff
|
||||
name = "manufacturing crusher"
|
||||
desc = "Crushes any item put into it, boulders and such. Materials below a sheet are stored in the machine."
|
||||
icon_state = "crusher"
|
||||
circuit = /obj/item/circuitboard/machine/manucrusher
|
||||
/// power used to crush
|
||||
var/crush_cost = 3 KILO WATTS
|
||||
/// how much can we hold
|
||||
var/capacity = 5
|
||||
/// withheld output because output is either blocked or full
|
||||
var/atom/movable/withholding
|
||||
/// list of held mats
|
||||
var/list/obj/item/stack/held_mats = list()
|
||||
|
||||
/obj/machinery/power/manufacturing/crusher/update_overlays()
|
||||
. = ..()
|
||||
. += generate_io_overlays(dir, COLOR_ORANGE) // OUT - stuff in it
|
||||
. += generate_io_overlays(REVERSE_DIR(dir), COLOR_MODERATE_BLUE) // IN - to crush
|
||||
|
||||
/obj/machinery/power/manufacturing/crusher/Destroy()
|
||||
. = ..()
|
||||
QDEL_NULL(withholding)
|
||||
|
||||
/obj/machinery/power/manufacturing/crusher/atom_destruction(damage_flag)
|
||||
withholding?.Move(drop_location())
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/manufacturing/crusher/receive_resource(obj/receiving, atom/from, receive_dir)
|
||||
if(istype(receiving, /obj/item/stack/ore) || receiving.resistance_flags & INDESTRUCTIBLE || !isitem(receiving) || surplus() < crush_cost || receive_dir != REVERSE_DIR(dir))
|
||||
return MANUFACTURING_FAIL
|
||||
if(!may_merge_in_contents(receiving) && length(contents - circuit) >= capacity)
|
||||
return MANUFACTURING_FAIL_FULL
|
||||
receiving.Move(src, get_dir(receiving, src))
|
||||
START_PROCESSING(SSmanufacturing, src)
|
||||
return MANUFACTURING_SUCCESS
|
||||
|
||||
/obj/machinery/power/manufacturing/crusher/Exited(atom/movable/gone, direction)
|
||||
. = ..()
|
||||
if(gone == withholding)
|
||||
withholding = null
|
||||
|
||||
/obj/machinery/power/manufacturing/crusher/process(seconds_per_tick) //noot functional
|
||||
if(!isnull(withholding) && !send_resource(withholding, dir))
|
||||
return
|
||||
for(var/material in held_mats)
|
||||
if(held_mats[material] >= 1)
|
||||
var/new_amount = floor(held_mats[material])
|
||||
held_mats[material] -= new_amount
|
||||
if(held_mats[material] <= 0)
|
||||
held_mats -= material
|
||||
withholding = new material(null, new_amount)
|
||||
return
|
||||
var/list/poor_saps = contents - circuit
|
||||
if(!length(poor_saps))
|
||||
return PROCESS_KILL
|
||||
if(surplus() < crush_cost)
|
||||
return
|
||||
var/obj/victim = poor_saps[length(poor_saps)]
|
||||
if(istype(victim)) //todo handling for other things
|
||||
if(!length(victim.custom_materials))
|
||||
add_load(crush_cost)
|
||||
victim.atom_destruction()
|
||||
for(var/obj/object in victim.contents+victim)
|
||||
for(var/datum/material/possible_mat as anything in object.custom_materials)
|
||||
var/quantity = object.custom_materials[possible_mat]
|
||||
object.set_custom_materials(object.custom_materials.Copy() - possible_mat, 1)
|
||||
var/type_to_use = istype(victim, /obj/item/boulder) ? possible_mat.ore_type : possible_mat.sheet_type
|
||||
if(quantity < SHEET_MATERIAL_AMOUNT)
|
||||
if(!(type_to_use in held_mats))
|
||||
held_mats[type_to_use] = quantity / SHEET_MATERIAL_AMOUNT
|
||||
continue
|
||||
held_mats[type_to_use] += quantity / SHEET_MATERIAL_AMOUNT
|
||||
continue
|
||||
var/obj/item/stack/sheet/new_item = new type_to_use(src, quantity / SHEET_MATERIAL_AMOUNT)
|
||||
if(!send_resource(new_item, dir))
|
||||
withholding = new_item
|
||||
return
|
||||
else if(isliving(victim))
|
||||
var/mob/living/poor_sap = victim
|
||||
poor_sap.adjustBruteLoss(95, TRUE)
|
||||
if(!send_resource(poor_sap, dir))
|
||||
withholding = poor_sap
|
||||
return
|
||||
18
code/modules/manufactorio/machines/debug.dm
Normal file
18
code/modules/manufactorio/machines/debug.dm
Normal file
@@ -0,0 +1,18 @@
|
||||
/obj/loop_spawner
|
||||
name = "testing loop spawner"
|
||||
icon = 'icons/obj/machines/mining_machines.dmi'
|
||||
icon_state = "unloader"
|
||||
anchored = TRUE
|
||||
color = COLOR_PURPLE
|
||||
/// directions we can output to right now
|
||||
var/to_spawn = /obj/item/screwdriver
|
||||
/// the subsystem to process us
|
||||
var/subsystem_to_process_us = /datum/controller/subsystem/processing/obj
|
||||
|
||||
/obj/loop_spawner/Initialize(mapload)
|
||||
. = ..()
|
||||
var/datum/controller/subsystem/processing/subsystem = locate(subsystem_to_process_us) in Master.subsystems
|
||||
START_PROCESSING(subsystem, src)
|
||||
|
||||
/obj/loop_spawner/process(seconds_per_tick)
|
||||
new to_spawn(get_step(src, dir))
|
||||
145
code/modules/manufactorio/machines/lathe.dm
Normal file
145
code/modules/manufactorio/machines/lathe.dm
Normal file
@@ -0,0 +1,145 @@
|
||||
/obj/machinery/power/manufacturing/lathe // this is a heavily gutted autolathe
|
||||
name = "manufacturing lathe"
|
||||
desc = "Lathes the set recipe until it runs out of resources. Only accepts sheets or other kinds of material stacks."
|
||||
icon_state = "lathe"
|
||||
circuit = /obj/item/circuitboard/machine/manulathe
|
||||
/// power cost for lathing
|
||||
var/power_cost = 5 KILO WATTS
|
||||
/// design id we print
|
||||
var/design_id
|
||||
///The container to hold materials
|
||||
var/datum/component/material_container/materials
|
||||
//looping sound for printing items
|
||||
var/datum/looping_sound/lathe_print/print_sound
|
||||
///Designs related to the autolathe
|
||||
var/datum/techweb/autounlocking/stored_research
|
||||
/// timer id of printing
|
||||
var/busy = FALSE
|
||||
/// our output, if the way out was blocked is held here
|
||||
var/atom/movable/withheld
|
||||
|
||||
/obj/machinery/power/manufacturing/lathe/Initialize(mapload)
|
||||
. = ..()
|
||||
print_sound = new(src, FALSE)
|
||||
materials = AddComponent( \
|
||||
/datum/component/material_container, \
|
||||
SSmaterials.materials_by_category[MAT_CATEGORY_ITEM_MATERIAL], \
|
||||
SHEET_MATERIAL_AMOUNT * MAX_STACK_SIZE * 2, \
|
||||
MATCONTAINER_EXAMINE|MATCONTAINER_NO_INSERT, \
|
||||
)
|
||||
if(!GLOB.autounlock_techwebs[/datum/techweb/autounlocking/autolathe])
|
||||
GLOB.autounlock_techwebs[/datum/techweb/autounlocking/autolathe] = new /datum/techweb/autounlocking/autolathe
|
||||
stored_research = GLOB.autounlock_techwebs[/datum/techweb/autounlocking/autolathe]
|
||||
|
||||
/obj/machinery/power/manufacturing/lathe/examine(mob/user)
|
||||
. = ..()
|
||||
var/datum/design/design
|
||||
if(!isnull(design_id))
|
||||
design = SSresearch.techweb_design_by_id(design_id)
|
||||
. += span_notice("It is set to print [!isnull(design) ? design.name : "nothing, set with a multitool"].")
|
||||
if(isnull(design))
|
||||
return
|
||||
. += span_notice("It needs:")
|
||||
for(var/valid_type in design.materials)
|
||||
var/atom/ingredient = valid_type
|
||||
var/amount = design.materials[ingredient] / SHEET_MATERIAL_AMOUNT
|
||||
|
||||
. += "[amount] sheets of [initial(ingredient.name)]"
|
||||
|
||||
/obj/machinery/power/manufacturing/lathe/update_overlays()
|
||||
. = ..()
|
||||
. += generate_io_overlays(dir, COLOR_ORANGE) // OUT - stuff in it
|
||||
. += generate_io_overlays(REVERSE_DIR(dir), COLOR_MODERATE_BLUE) // IN - to crush
|
||||
|
||||
/obj/machinery/power/manufacturing/lathe/Destroy()
|
||||
. = ..()
|
||||
stored_research = null
|
||||
QDEL_NULL(print_sound)
|
||||
materials = null
|
||||
QDEL_NULL(withheld)
|
||||
|
||||
/obj/machinery/power/manufacturing/lathe/atom_destruction(damage_flag)
|
||||
withheld?.Move(drop_location())
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/manufacturing/lathe/receive_resource(atom/movable/receiving, atom/from, receive_dir)
|
||||
if(!isstack(receiving) || receiving.resistance_flags & INDESTRUCTIBLE || receive_dir != REVERSE_DIR(dir))
|
||||
return MANUFACTURING_FAIL
|
||||
materials.insert_item(receiving)
|
||||
return MANUFACTURING_SUCCESS
|
||||
|
||||
/obj/machinery/power/manufacturing/lathe/multitool_act(mob/living/user, obj/item/tool)
|
||||
. = ..()
|
||||
var/list/name_to_id = list()
|
||||
for(var/id in stored_research.researched_designs)
|
||||
var/datum/design/design = SSresearch.techweb_design_by_id(id)
|
||||
name_to_id[design.name] = id
|
||||
var/result = tgui_input_list(user, "Select Design", "Select Design", sort_list(name_to_id))
|
||||
if(isnull(result))
|
||||
return ITEM_INTERACT_FAILURE
|
||||
design_id = name_to_id[result]
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
/obj/machinery/power/manufacturing/lathe/process()
|
||||
if(!isnull(withheld) && !send_resource(withheld, dir))
|
||||
return
|
||||
|
||||
var/datum/design/design = SSresearch.techweb_design_by_id(design_id)
|
||||
if(isnull(design) || !(design.build_type & AUTOLATHE))
|
||||
return
|
||||
if(surplus() < power_cost)
|
||||
finalize_build()
|
||||
return
|
||||
//check for materials required. For custom material items decode their required materials
|
||||
var/list/materials_needed = list()
|
||||
for(var/material in design.materials)
|
||||
var/amount_needed = design.materials[material]
|
||||
if(istext(material)) // category
|
||||
for(var/datum/material/valid_candidate as anything in SSmaterials.materials_by_category[material])
|
||||
if(materials.get_material_amount(valid_candidate) < amount_needed)
|
||||
continue
|
||||
material = valid_candidate
|
||||
break
|
||||
if(isnull(material))
|
||||
return
|
||||
materials_needed[material] = amount_needed
|
||||
|
||||
if(!materials.has_materials(materials_needed))
|
||||
return
|
||||
|
||||
var/craft_time = (design.construction_time * design.lathe_time_factor) ** 0.8
|
||||
flick_overlay_view(mutable_appearance(icon, "crafter_printing"), craft_time)
|
||||
print_sound.start()
|
||||
add_load(power_cost)
|
||||
busy = addtimer(CALLBACK(src, PROC_REF(do_make_item), design, materials_needed), craft_time, TIMER_UNIQUE | TIMER_STOPPABLE | TIMER_DELETE_ME)
|
||||
|
||||
/obj/machinery/power/manufacturing/lathe/proc/do_make_item(datum/design/design, list/materials_needed)
|
||||
finalize_build()
|
||||
if(surplus() < power_cost)
|
||||
return
|
||||
|
||||
var/is_stack = ispath(design.build_path, /obj/item/stack)
|
||||
if(!materials.has_materials(materials_needed))
|
||||
return
|
||||
materials.use_materials(materials_needed)
|
||||
|
||||
var/atom/movable/created
|
||||
if(is_stack)
|
||||
var/obj/item/stack/stack_item = initial(design.build_path)
|
||||
created = new stack_item(null, 1)
|
||||
else
|
||||
created = new design.build_path(null)
|
||||
split_materials_uniformly(materials_needed, target_object = created)
|
||||
if(isitem(created))
|
||||
created.pixel_x = created.base_pixel_x + rand(-6, 6)
|
||||
created.pixel_y = created.base_pixel_y + rand(-6, 6)
|
||||
SSblackbox.record_feedback("nested tally", "lathe_printed_items", 1, list("[type]", "[created.type]"))
|
||||
|
||||
if(!send_resource(created, dir))
|
||||
withheld = created
|
||||
|
||||
|
||||
/obj/machinery/power/manufacturing/lathe/proc/finalize_build()
|
||||
print_sound.stop()
|
||||
deltimer(busy)
|
||||
busy = null
|
||||
66
code/modules/manufactorio/machines/router.dm
Normal file
66
code/modules/manufactorio/machines/router.dm
Normal file
@@ -0,0 +1,66 @@
|
||||
/obj/machinery/power/manufacturing/router // Basically a splitter
|
||||
name = "manufacturing router"
|
||||
desc = "Distributes input to 3 output directions equally. Stacks are split, and you may toggle outputs with a multitool. May not receive from other routers."
|
||||
allow_mob_bump_intake = TRUE
|
||||
icon_state = "splitter"
|
||||
circuit = /obj/item/circuitboard/machine/manurouter
|
||||
/// outputs disabled with a multitool
|
||||
var/list/disabled_dirs = list()
|
||||
/// directions we can output to right now
|
||||
var/list/directions
|
||||
|
||||
/obj/machinery/power/manufacturing/router/Initialize(mapload)
|
||||
. = ..()
|
||||
directions = GLOB.cardinals.Copy()
|
||||
|
||||
/obj/machinery/power/manufacturing/router/multitool_act(mob/living/user, obj/item/tool)
|
||||
. = ..()
|
||||
var/to_toggle = get_dir(src, user)
|
||||
if(!(to_toggle in GLOB.cardinals))
|
||||
balloon_alert(user, "stand inline!")
|
||||
return ITEM_INTERACT_FAILURE
|
||||
if(to_toggle in disabled_dirs)
|
||||
disabled_dirs -= to_toggle
|
||||
else
|
||||
disabled_dirs += to_toggle
|
||||
update_appearance(UPDATE_OVERLAYS)
|
||||
balloon_alert(user, "toggled output")
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
/obj/machinery/power/manufacturing/router/update_overlays()
|
||||
. = ..()
|
||||
for(var/direction in GLOB.cardinals)
|
||||
var/variant
|
||||
if(disabled_dirs.Find(direction))
|
||||
variant = "bl"
|
||||
else
|
||||
variant = (direction == dir) ? "in" : "out"
|
||||
var/image/new_overlay = image(icon, "splitter_[variant]", layer = layer+0.001, dir = direction)
|
||||
. += new_overlay
|
||||
|
||||
/obj/machinery/power/manufacturing/router/receive_resource(obj/receiving, atom/from, receive_dir)
|
||||
if(istype(from, /obj/machinery/power/manufacturing/router))
|
||||
return MANUFACTURING_FAIL
|
||||
var/list/filtered = directions - receive_dir - disabled_dirs
|
||||
if(!length(filtered))
|
||||
directions = GLOB.cardinals.Copy()
|
||||
for(var/target in filtered)
|
||||
directions -= target
|
||||
if(isstack(receiving))
|
||||
receiving = handle_stack(receiving, receive_dir)
|
||||
if(send_resource(receiving, target))
|
||||
dir = receive_dir
|
||||
update_appearance(UPDATE_OVERLAYS) // im sorry
|
||||
return MANUFACTURING_SUCCESS
|
||||
return MANUFACTURING_FAIL_FULL
|
||||
|
||||
/obj/machinery/power/manufacturing/router/proc/handle_stack(obj/item/stack/stack, direction)
|
||||
. = stack
|
||||
var/potential_output_count = length(GLOB.cardinals - direction - disabled_dirs)
|
||||
if(potential_output_count <= 1)
|
||||
return
|
||||
var/split_amount = round(stack.amount / potential_output_count, 1)
|
||||
if(stack.amount == potential_output_count)
|
||||
return
|
||||
var/atom/movable/new_stack = stack.split_stack(amount = min(stack.amount, split_amount))
|
||||
return new_stack
|
||||
59
code/modules/manufactorio/machines/smelter.dm
Normal file
59
code/modules/manufactorio/machines/smelter.dm
Normal file
@@ -0,0 +1,59 @@
|
||||
/obj/machinery/power/manufacturing/smelter
|
||||
name = "manufacturing smelter"
|
||||
desc = "Pretty much incinerates whatever is put into it. Refines ore (not boulders)."
|
||||
icon_state = "smelter"
|
||||
circuit = /obj/item/circuitboard/machine/manusmelter
|
||||
/// power used to smelt
|
||||
var/power_cost = 4 KILO WATTS
|
||||
/// our output, if the way out was blocked is held here
|
||||
var/atom/movable/withheld
|
||||
|
||||
/obj/machinery/power/manufacturing/smelter/update_overlays()
|
||||
. = ..()
|
||||
. += generate_io_overlays(dir, COLOR_ORANGE) // OUT - stuff in it
|
||||
. += generate_io_overlays(REVERSE_DIR(dir), COLOR_MODERATE_BLUE) // IN - to crush
|
||||
|
||||
/obj/machinery/power/manufacturing/smelter/receive_resource(obj/receiving, atom/from, receive_dir)
|
||||
if(!isitem(receiving) || surplus() < power_cost || receive_dir != REVERSE_DIR(dir))
|
||||
return MANUFACTURING_FAIL
|
||||
var/list/stacks = contents - circuit
|
||||
if(!may_merge_in_contents(receiving) && length(stacks) >= 5)
|
||||
return MANUFACTURING_FAIL_FULL
|
||||
receiving.Move(src, get_dir(receiving, src))
|
||||
START_PROCESSING(SSmanufacturing, src)
|
||||
return MANUFACTURING_SUCCESS
|
||||
|
||||
/obj/machinery/power/manufacturing/smelter/Destroy()
|
||||
. = ..()
|
||||
QDEL_NULL(withheld)
|
||||
|
||||
/obj/machinery/power/manufacturing/smelter/atom_destruction(damage_flag)
|
||||
withheld?.Move(drop_location())
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/manufacturing/smelter/process(seconds_per_tick)
|
||||
var/list/stacks = contents - circuit
|
||||
if(!length(stacks))
|
||||
return
|
||||
|
||||
var/list/stacks_preprocess = contents - circuit
|
||||
var/obj/item/stack/ore/ore = stacks_preprocess[length(stacks_preprocess)]
|
||||
if(isnull(ore))
|
||||
return
|
||||
if(isnull(withheld) && surplus() >= power_cost)
|
||||
icon_state="smelter_on"
|
||||
add_load(power_cost)
|
||||
if(istype(ore))
|
||||
var/obj/item/stack/new_stack = new ore.refined_type(null, min(5, ore.amount), FALSE)
|
||||
new_stack.moveToNullspace()
|
||||
ore.use(min(5, ore.amount))
|
||||
ore = new_stack
|
||||
else
|
||||
ore.fire_act(1400)
|
||||
withheld = ore
|
||||
else if(surplus() < power_cost)
|
||||
icon_state = "smelter"
|
||||
if(send_resource(withheld, dir))
|
||||
withheld = null // nullspace thumbs down
|
||||
if(!length(contents - circuit))
|
||||
return PROCESS_KILL //we finished
|
||||
149
code/modules/manufactorio/machines/sorter.dm
Normal file
149
code/modules/manufactorio/machines/sorter.dm
Normal file
@@ -0,0 +1,149 @@
|
||||
/obj/machinery/power/manufacturing/sorter
|
||||
icon_state = "router"
|
||||
name = "conveyor sort-router"
|
||||
desc = "Pushes things on it to its sides following set criteria, set via multitool."
|
||||
layer = BELOW_OPEN_DOOR_LAYER
|
||||
density = FALSE
|
||||
interaction_flags_atom = INTERACT_ATOM_ATTACK_HAND
|
||||
circuit = /obj/item/circuitboard/machine/manurouter
|
||||
/// for mappers; filter path = list(direction, value), otherwise a list of initialized filters
|
||||
var/list/sort_filters = list()
|
||||
/// dir to push to if there is no criteria
|
||||
var/dir_if_not_met
|
||||
/// timer id of the thing that makes stuff move
|
||||
var/delay_timerid
|
||||
/// max filters
|
||||
var/max_filters = 10
|
||||
|
||||
/obj/machinery/power/manufacturing/sorter/Initialize(mapload)
|
||||
. = ..()
|
||||
if(isnull(dir_if_not_met))
|
||||
dir_if_not_met = dir
|
||||
var/static/list/loc_connections = list(
|
||||
COMSIG_ATOM_ENTERED = PROC_REF(on_entered),
|
||||
)
|
||||
AddElement(/datum/element/connect_loc, loc_connections)
|
||||
for(var/i in 1 to length(sort_filters))
|
||||
var/creating_type = sort_filters[i]
|
||||
var/list/values = sort_filters[creating_type]
|
||||
var/datum/sortrouter_filter/new_type = new creating_type(src)
|
||||
new_type.dir_target = values[1]
|
||||
new_type.value = values[2]
|
||||
sort_filters[i] = new_type
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/machinery/power/manufacturing/sorter/Destroy()
|
||||
. = ..()
|
||||
QDEL_LIST(sort_filters)
|
||||
|
||||
/obj/machinery/power/manufacturing/sorter/multitool_act(mob/living/user, obj/item/tool)
|
||||
. = ..()
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/power/manufacturing/sorter/receive_resource(atom/movable/receiving, atom/from, receive_dir)
|
||||
if(length(loc.contents) >= MANUFACTURING_TURF_LAG_LIMIT)
|
||||
return MANUFACTURING_FAIL_FULL
|
||||
receiving.Move(loc)
|
||||
return MANUFACTURING_SUCCESS
|
||||
|
||||
|
||||
/obj/machinery/power/manufacturing/sorter/ui_data(mob/user)
|
||||
. = list()
|
||||
.["unmet_dir"] = dir_if_not_met
|
||||
.["filters"] = list()
|
||||
for(var/datum/sortrouter_filter/sorting as anything in sort_filters)
|
||||
.["filters"] += list(list(
|
||||
"name" = sorting.return_name(),
|
||||
"ref" = REF(sorting),
|
||||
"inverted" = sorting.inverted,
|
||||
"dir" = sorting.dir_target,
|
||||
))
|
||||
|
||||
/obj/machinery/power/manufacturing/sorter/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
switch(action)
|
||||
if("del_filter")
|
||||
var/datum/sortrouter_filter/filter = locate(params["ref"])
|
||||
if(isnull(filter))
|
||||
return
|
||||
sort_filters -= filter
|
||||
qdel(filter)
|
||||
return TRUE
|
||||
if("new_filter")
|
||||
if(length(sort_filters) >= max_filters)
|
||||
return
|
||||
var/static/list/filter_by_name
|
||||
if(!length(filter_by_name))
|
||||
filter_by_name = list()
|
||||
for(var/datum/sortrouter_filter/to_do as anything in subtypesof(/datum/sortrouter_filter))
|
||||
filter_by_name[initial(to_do.name)] = to_do
|
||||
filter_by_name = sort_list(filter_by_name)
|
||||
var/target_type = tgui_input_list(usr, "Select a filter", "New Filter", filter_by_name)
|
||||
if(isnull(target_type)|| !usr.can_perform_action(src, ALLOW_SILICON_REACH))
|
||||
return
|
||||
target_type = filter_by_name[target_type]
|
||||
sort_filters += new target_type(src)
|
||||
return TRUE
|
||||
if("rotate")
|
||||
var/datum/sortrouter_filter/filter = locate(params["ref"])
|
||||
if(isnull(filter))
|
||||
return
|
||||
var/next_ind = GLOB.cardinals.Find(filter.dir_target) + 1
|
||||
filter.dir_target = GLOB.cardinals[WRAP(next_ind, 1, 5)]
|
||||
return TRUE
|
||||
if("rotate_unmet")
|
||||
var/next_ind = GLOB.cardinals.Find(dir_if_not_met) + 1
|
||||
dir_if_not_met = GLOB.cardinals[WRAP(next_ind, 1, 5)]
|
||||
return TRUE
|
||||
if("edit")
|
||||
var/datum/sortrouter_filter/filter = locate(params["ref"])
|
||||
if(isnull(filter))
|
||||
return
|
||||
filter.edit(usr)
|
||||
return TRUE
|
||||
if("shift")
|
||||
var/datum/sortrouter_filter/filter = locate(params["ref"])
|
||||
if(isnull(filter))
|
||||
return
|
||||
var/next_ind = WRAP(sort_filters.Find(filter) + text2num(params["amount"]), 1, length(sort_filters)+1)
|
||||
sort_filters -= filter
|
||||
sort_filters.Insert(next_ind, filter)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/manufacturing/sorter/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "ManufacturingSorter")
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/power/manufacturing/sorter/proc/send_nomobs(atom/movable/moving, dir)
|
||||
var/mutable_appearance/operate = mutable_appearance(icon, "router_operate")
|
||||
operate.dir = dir
|
||||
flick_overlay_view(operate, 1 SECONDS)
|
||||
return ismob(moving) ? moving.Move(get_step(src,dir), dir) : send_resource(moving, dir)
|
||||
|
||||
/obj/machinery/power/manufacturing/sorter/process()
|
||||
if(delay_timerid || !length(loc?.contents - 1))
|
||||
return
|
||||
launch_everything()
|
||||
|
||||
/obj/machinery/power/manufacturing/sorter/proc/on_entered(datum/source, atom/movable/mover)
|
||||
SIGNAL_HANDLER
|
||||
if(mover == src || !istype(mover) || mover.anchored || delay_timerid)
|
||||
return
|
||||
delay_timerid = addtimer(CALLBACK(src, PROC_REF(launch_everything)), 0.2 SECONDS)
|
||||
|
||||
/obj/machinery/power/manufacturing/sorter/proc/launch_everything()
|
||||
delay_timerid = null
|
||||
var/turf/where_we_at = get_turf(src)
|
||||
for(var/atom/movable/mover as anything in where_we_at.contents)
|
||||
if(mover.anchored)
|
||||
continue
|
||||
for(var/datum/sortrouter_filter/sorting as anything in sort_filters)
|
||||
if(sorting.meets_conditions(mover) == sorting.inverted)
|
||||
continue
|
||||
send_nomobs(mover, sorting.dir_target)
|
||||
return
|
||||
send_nomobs(mover, dir_if_not_met)
|
||||
120
code/modules/manufactorio/machines/sorter_filters.dm
Normal file
120
code/modules/manufactorio/machines/sorter_filters.dm
Normal file
@@ -0,0 +1,120 @@
|
||||
/datum/sortrouter_filter
|
||||
/// name of the filter shown in UI
|
||||
var/name
|
||||
/// if it meets criteria, item is pushed to this direction
|
||||
var/dir_target = NORTH
|
||||
/// value of our filter, checked by us
|
||||
var/value = ""
|
||||
/// is our output inverted? checked by sorter
|
||||
var/inverted = FALSE
|
||||
/// the sorter we belong to
|
||||
var/obj/machinery/power/manufacturing/sorter/sorter
|
||||
|
||||
/datum/sortrouter_filter/New(sorter)
|
||||
. = ..()
|
||||
if(isnull(sorter))
|
||||
return
|
||||
src.sorter = sorter
|
||||
|
||||
/datum/sortrouter_filter/Destroy()
|
||||
. = ..()
|
||||
if(isnull(sorter))
|
||||
return
|
||||
sorter = null
|
||||
|
||||
/datum/sortrouter_filter
|
||||
|
||||
/datum/sortrouter_filter/proc/return_name()
|
||||
return name
|
||||
|
||||
/datum/sortrouter_filter/proc/edit(mob/user)
|
||||
to_chat(user, "This filter is not editable.")
|
||||
|
||||
/datum/sortrouter_filter/proc/meets_conditions(atom/checking)
|
||||
|
||||
/datum/sortrouter_filter/is_stack
|
||||
name = "input is stack"
|
||||
|
||||
/datum/sortrouter_filter/is_stack/meets_conditions(atom/checking)
|
||||
return isstack(checking)
|
||||
|
||||
/datum/sortrouter_filter/is_ore
|
||||
name = "input is ore"
|
||||
|
||||
/datum/sortrouter_filter/is_ore/meets_conditions(atom/checking)
|
||||
return istype(checking, /obj/item/stack/ore)
|
||||
|
||||
/datum/sortrouter_filter/is_mail
|
||||
name = "input is mail"
|
||||
|
||||
/datum/sortrouter_filter/is_mail/meets_conditions(atom/checking)
|
||||
return istype(checking, /obj/item/mail)
|
||||
|
||||
/datum/sortrouter_filter/is_tagged
|
||||
name = "input is tagged X"
|
||||
|
||||
/datum/sortrouter_filter/is_tagged/edit(mob/user)
|
||||
var/target = tgui_input_list(user, "Select a tag", "Tag", sort_list(GLOB.TAGGERLOCATIONS))
|
||||
if(isnull(target) || !user.can_perform_action(sorter, ALLOW_SILICON_REACH))
|
||||
return
|
||||
value = GLOB.TAGGERLOCATIONS.Find(target)
|
||||
|
||||
/datum/sortrouter_filter/is_tagged/return_name()
|
||||
return "input is tagged [value ? GLOB.TAGGERLOCATIONS[value] : ""]"
|
||||
|
||||
/datum/sortrouter_filter/is_tagged/meets_conditions(checking)
|
||||
var/obj/item/delivery/mail_or_delivery = checking
|
||||
var/sort_tag
|
||||
if(istype(checking, /obj/item/delivery) || istype(checking, /obj/item/mail))
|
||||
sort_tag = mail_or_delivery.sort_tag
|
||||
|
||||
return value == sort_tag
|
||||
|
||||
/datum/sortrouter_filter/name_contains
|
||||
name = "input's name contains"
|
||||
|
||||
/datum/sortrouter_filter/name_contains/edit(mob/user)
|
||||
var/target = tgui_input_text(user, "What should it contain?", "Name", value, 12)
|
||||
if(isnull(target)|| !user.can_perform_action(sorter, ALLOW_SILICON_REACH))
|
||||
return
|
||||
value = target
|
||||
|
||||
/datum/sortrouter_filter/name_contains/return_name()
|
||||
return "input's name contains [value]"
|
||||
|
||||
/datum/sortrouter_filter/name_contains/meets_conditions(atom/checking)
|
||||
return findtext(LOWER_TEXT(checking.name), value)
|
||||
|
||||
/datum/sortrouter_filter/is_path_specific
|
||||
name = "input is specific item"
|
||||
/// are we currently listening for an item to set as our filter?
|
||||
var/currently_listening = FALSE
|
||||
|
||||
/datum/sortrouter_filter/is_path_specific/edit(mob/user)
|
||||
name = initial(name)
|
||||
if(!currently_listening)
|
||||
name = "awaiting item"
|
||||
to_chat(user, "Hit the sorter with the item of choice to set the filter.")
|
||||
sorter.balloon_alert(user, "awaiting item!")
|
||||
currently_listening = TRUE
|
||||
RegisterSignal(sorter, COMSIG_ATOM_ATTACKBY, PROC_REF(sorter_hit))
|
||||
else
|
||||
currently_listening = FALSE
|
||||
UnregisterSignal(sorter, COMSIG_ATOM_ATTACKBY)
|
||||
|
||||
/datum/sortrouter_filter/is_path_specific/proc/sorter_hit(datum/source, obj/item/attacking_item, user, params)
|
||||
currently_listening = FALSE
|
||||
value = attacking_item.type
|
||||
name = attacking_item.name
|
||||
sorter.balloon_alert(user, "filter set")
|
||||
UnregisterSignal(sorter, COMSIG_ATOM_ATTACKBY)
|
||||
return COMPONENT_NO_AFTERATTACK
|
||||
|
||||
/datum/sortrouter_filter/is_path_specific/meets_conditions(atom/checking)
|
||||
return checking.type == value
|
||||
|
||||
/datum/sortrouter_filter/is_path_specific/subtypes
|
||||
name = "input is specific kind of item"
|
||||
|
||||
/datum/sortrouter_filter/is_path_specific/subtypes/meets_conditions(atom/checking)
|
||||
return istype(checking.type, value)
|
||||
46
code/modules/manufactorio/machines/storagebox.dm
Normal file
46
code/modules/manufactorio/machines/storagebox.dm
Normal file
@@ -0,0 +1,46 @@
|
||||
/obj/machinery/power/manufacturing/storagebox
|
||||
name = "manufacturing storage unit"
|
||||
desc = "Its basically a box. Receives resources (if anchored). Needs a machine to take stuff out of without dumping everything out."
|
||||
icon_state = "box"
|
||||
/// how much can we hold
|
||||
var/max_stuff = 16
|
||||
|
||||
/obj/machinery/power/manufacturing/request_resource() //returns last inserted item
|
||||
var/list/real_contents = contents - circuit
|
||||
if(!length(real_contents))
|
||||
return
|
||||
return (real_contents)[length(real_contents)]
|
||||
|
||||
/obj/machinery/power/manufacturing/storagebox/receive_resource(atom/movable/receiving, atom/from, receive_dir)
|
||||
if(iscloset(receiving) && length(receiving.contents))
|
||||
return MANUFACTURING_FAIL
|
||||
if(!may_merge_in_contents(receiving) && length(contents - circuit) >= max_stuff)
|
||||
return MANUFACTURING_FAIL_FULL
|
||||
receiving.Move(src,receive_dir)
|
||||
return MANUFACTURING_SUCCESS
|
||||
|
||||
/obj/machinery/power/manufacturing/storagebox/container_resist_act(mob/living/user)
|
||||
. = ..()
|
||||
user.Move(drop_location())
|
||||
|
||||
/obj/machinery/power/manufacturing/storagebox/screwdriver_act(mob/living/user, obj/item/tool)
|
||||
. = NONE
|
||||
balloon_alert(user, "disassembling...")
|
||||
if(!do_after(user, 5 SECONDS, src))
|
||||
return ITEM_INTERACT_FAILURE
|
||||
atom_destruction()
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
/obj/machinery/power/manufacturing/storagebox/atom_destruction(damage_flag)
|
||||
new /obj/item/stack/sheet/iron(drop_location(), 10)
|
||||
dump_inventory_contents()
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/manufacturing/storagebox/attack_hand(mob/living/user, list/modifiers)
|
||||
. = ..()
|
||||
if(user.combat_mode)
|
||||
return
|
||||
balloon_alert(user, "dumping..")
|
||||
if(!do_after(user, 1.25 SECONDS, src))
|
||||
return
|
||||
dump_inventory_contents()
|
||||
78
code/modules/manufactorio/machines/unloader.dm
Normal file
78
code/modules/manufactorio/machines/unloader.dm
Normal file
@@ -0,0 +1,78 @@
|
||||
/obj/machinery/power/manufacturing/unloader
|
||||
name = "manufacturing crate unloader"
|
||||
desc = "Unloads crates (and ore boxes) passed into it, ejecting the empty crate to the side and its contents forwards. Use a multitool to flip the crate output."
|
||||
icon = 'icons/obj/machines/mining_machines.dmi'
|
||||
icon_state = "unloader-corner"
|
||||
circuit = /obj/item/circuitboard/machine/manuunloader
|
||||
/// power used per attempt to unload a crate
|
||||
var/power_to_unload_crate = 2 KILO WATTS
|
||||
/// whether the side we output unloaded crates is flipped
|
||||
var/flip_side = FALSE
|
||||
|
||||
/obj/machinery/power/manufacturing/unloader/update_overlays()
|
||||
. = ..()
|
||||
. += generate_io_overlays(dir, COLOR_ORANGE) // OUT - stuff in it
|
||||
. += generate_io_overlays(REVERSE_DIR(dir), COLOR_MODERATE_BLUE) // IN - crate
|
||||
. += generate_io_overlays(turn(dir, flip_side ? 90 : -90), COLOR_ORANGE) // OUT -- empty crate
|
||||
|
||||
/obj/machinery/power/manufacturing/unloader/request_resource() //returns held crate if someone wants to do that for some reason
|
||||
var/list/real_contents = contents - circuit
|
||||
if(!length(real_contents))
|
||||
return
|
||||
return (real_contents)[1]
|
||||
|
||||
/obj/machinery/power/manufacturing/unloader/multitool_act(mob/living/user, obj/item/tool)
|
||||
. = ..()
|
||||
balloon_alert(user, "flipped")
|
||||
flip_side = !flip_side
|
||||
update_appearance()
|
||||
|
||||
/obj/machinery/power/manufacturing/unloader/receive_resource(obj/receiving, atom/from, receive_dir)
|
||||
if(surplus() < power_to_unload_crate || receive_dir != REVERSE_DIR(dir))
|
||||
return MANUFACTURING_FAIL
|
||||
var/list/real_contents = contents - circuit
|
||||
if(length(real_contents))
|
||||
return MANUFACTURING_FAIL_FULL
|
||||
|
||||
var/obj/structure/closet/as_closet = receiving
|
||||
var/obj/structure/ore_box/as_orebox = receiving
|
||||
if(istype(as_closet))
|
||||
if(!as_closet.can_open())
|
||||
return MANUFACTURING_FAIL
|
||||
else if(!istype(as_orebox))
|
||||
return MANUFACTURING_FAIL
|
||||
receiving.Move(src, get_dir(receiving, src))
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
return MANUFACTURING_SUCCESS
|
||||
|
||||
/obj/machinery/power/manufacturing/unloader/process(seconds_per_tick)
|
||||
var/list/real_contents = contents - circuit
|
||||
if(!length(real_contents))
|
||||
return PROCESS_KILL
|
||||
if(surplus() < power_to_unload_crate)
|
||||
return
|
||||
add_load(power_to_unload_crate)
|
||||
var/obj/structure/closet/closet = real_contents[1]
|
||||
if(istype(closet))
|
||||
return unload_crate(closet)
|
||||
else
|
||||
return unload_orebox(closet)
|
||||
|
||||
/obj/machinery/power/manufacturing/unloader/proc/unload_crate(obj/structure/closet/closet)
|
||||
if (!closet.contents_initialized)
|
||||
closet.contents_initialized = TRUE
|
||||
closet.PopulateContents()
|
||||
SEND_SIGNAL(closet, COMSIG_CLOSET_CONTENTS_INITIALIZED)
|
||||
for(var/atom/thing as anything in closet.contents)
|
||||
if(ismob(thing))
|
||||
continue
|
||||
send_resource(thing, dir)
|
||||
if(!length(closet.contents) && send_resource(closet, turn(dir, flip_side ? 90 : -90)))
|
||||
closet.open(force = TRUE)
|
||||
return PROCESS_KILL
|
||||
|
||||
/obj/machinery/power/manufacturing/unloader/proc/unload_orebox(obj/structure/ore_box/box)
|
||||
for(var/atom/thing as anything in box.contents)
|
||||
send_resource(thing, dir)
|
||||
if(!length(box.contents) && send_resource(box, turn(dir, flip_side ? 90 : -90)))
|
||||
return PROCESS_KILL
|
||||
@@ -34,15 +34,18 @@ GLOBAL_LIST_EMPTY(conveyors_by_id)
|
||||
var/flipped = FALSE
|
||||
/// Are we currently conveying items?
|
||||
var/conveying = FALSE
|
||||
//Direction -> if we have a conveyor belt in that direction
|
||||
///Direction -> if we have a conveyor belt in that direction
|
||||
var/list/neighbors
|
||||
/// are we operating in wire power mode
|
||||
var/wire_mode = FALSE
|
||||
/// weakref to attached cable if wire mode
|
||||
var/datum/weakref/attached_wire_ref
|
||||
|
||||
/obj/machinery/conveyor/Initialize(mapload, new_dir, new_id)
|
||||
. = ..()
|
||||
AddElement(/datum/element/footstep_override, priority = STEP_SOUND_CONVEYOR_PRIORITY)
|
||||
AddElement(/datum/element/give_turf_traits, string_list(list(TRAIT_TURF_IGNORE_SLOWDOWN)))
|
||||
register_context()
|
||||
|
||||
if(new_dir)
|
||||
setDir(new_dir)
|
||||
if(new_id)
|
||||
@@ -58,6 +61,9 @@ GLOBAL_LIST_EMPTY(conveyors_by_id)
|
||||
AddElement(/datum/element/connect_loc, loc_connections)
|
||||
update_move_direction()
|
||||
LAZYADD(GLOB.conveyors_by_id[id], src)
|
||||
if(wire_mode)
|
||||
update_cable()
|
||||
START_PROCESSING(SSmachines, src)
|
||||
|
||||
/obj/machinery/conveyor/examine(mob/user)
|
||||
. = ..()
|
||||
@@ -66,6 +72,7 @@ GLOBAL_LIST_EMPTY(conveyors_by_id)
|
||||
. += "\nLeft-click with a <b>wrench</b> to rotate."
|
||||
. += "Left-click with a <b>screwdriver</b> to invert its direction."
|
||||
. += "Right-click with a <b>screwdriver</b> to flip its belt around."
|
||||
. += "Left-click with a <b>multitool</b> to toggle whether this conveyor receives power via cable. Toggling connects and disconnects."
|
||||
. += "Using another <b>conveyor belt assembly</b> on this will place a <b>new conveyor belt<b> in the direction this one is pointing."
|
||||
|
||||
/obj/machinery/conveyor/add_context(atom/source, list/context, obj/item/held_item, mob/user)
|
||||
@@ -80,6 +87,9 @@ GLOBAL_LIST_EMPTY(conveyors_by_id)
|
||||
context[SCREENTIP_CONTEXT_LMB] = "Invert conveyor belt"
|
||||
context[SCREENTIP_CONTEXT_RMB] = "Flip conveyor belt"
|
||||
return CONTEXTUAL_SCREENTIP_SET
|
||||
if(held_item?.tool_behaviour == TOOL_MULTITOOL)
|
||||
context[SCREENTIP_CONTEXT_LMB] = "Toggle conveyor belt wire mode"
|
||||
return CONTEXTUAL_SCREENTIP_SET
|
||||
|
||||
/obj/machinery/conveyor/centcom_auto
|
||||
id = "round_end_belt"
|
||||
@@ -118,6 +128,7 @@ GLOBAL_LIST_EMPTY(conveyors_by_id)
|
||||
/obj/machinery/conveyor/Destroy()
|
||||
set_operating(FALSE)
|
||||
LAZYREMOVE(GLOB.conveyors_by_id[id], src)
|
||||
attached_wire_ref = null
|
||||
return ..()
|
||||
|
||||
/obj/machinery/conveyor/vv_edit_var(var_name, var_value)
|
||||
@@ -295,7 +306,16 @@ GLOBAL_LIST_EMPTY(conveyors_by_id)
|
||||
inverted = !inverted
|
||||
update_move_direction()
|
||||
to_chat(user, span_notice("You set [src]'s direction [inverted ? "backwards" : "back to default"]."))
|
||||
|
||||
else if(attacking_item.tool_behaviour == TOOL_MULTITOOL)
|
||||
attacking_item.play_tool_sound(src)
|
||||
wire_mode = !wire_mode
|
||||
update_cable()
|
||||
power_change()
|
||||
if(wire_mode)
|
||||
START_PROCESSING(SSmachines, src)
|
||||
else
|
||||
STOP_PROCESSING(SSmachines, src)
|
||||
to_chat(user, span_notice("You set [src]'s wire mode [wire_mode ? "on" : "off"]."))
|
||||
else if(istype(attacking_item, /obj/item/stack/conveyor))
|
||||
// We should place a new conveyor belt machine on the output turf the conveyor is pointing to.
|
||||
var/turf/target_turf = get_step(get_turf(src), forwards)
|
||||
@@ -334,10 +354,51 @@ GLOBAL_LIST_EMPTY(conveyors_by_id)
|
||||
return
|
||||
user.Move_Pulled(src)
|
||||
|
||||
/obj/machinery/conveyor/powered(chan = power_channel, ignore_use_power = FALSE)
|
||||
if(!wire_mode)
|
||||
return ..()
|
||||
var/datum/powernet/powernet = get_powernet()
|
||||
if(!isnull(powernet))
|
||||
return clamp(powernet.avail-powernet.load, 0, powernet.avail) >= active_power_usage
|
||||
return ..()
|
||||
|
||||
/obj/machinery/conveyor/power_change()
|
||||
. = ..()
|
||||
update()
|
||||
|
||||
/obj/machinery/conveyor/process()
|
||||
if(!wire_mode)
|
||||
return PROCESS_KILL
|
||||
if(isnull(attached_wire_ref))
|
||||
update_cable()
|
||||
return
|
||||
var/datum/powernet/powernet = get_powernet()
|
||||
if(isnull(powernet))
|
||||
return
|
||||
if(powered())
|
||||
powernet.load += active_power_usage
|
||||
else
|
||||
power_change()
|
||||
|
||||
|
||||
/obj/machinery/conveyor/proc/update_cable()
|
||||
if(!wire_mode)
|
||||
attached_wire_ref = null
|
||||
return
|
||||
var/turf/our_turf = get_turf(src)
|
||||
attached_wire_ref = WEAKREF(locate(/obj/structure/cable) in our_turf)
|
||||
if(attached_wire_ref)
|
||||
return power_change()
|
||||
|
||||
/obj/machinery/conveyor/proc/get_powernet()
|
||||
if(!wire_mode)
|
||||
return
|
||||
var/obj/structure/cable/cable = attached_wire_ref.resolve()
|
||||
if(isnull(cable))
|
||||
attached_wire_ref = null
|
||||
return
|
||||
return cable.powernet
|
||||
|
||||
// Conveyor switch
|
||||
/obj/machinery/conveyor_switch
|
||||
name = "conveyor switch"
|
||||
|
||||
@@ -1257,3 +1257,73 @@
|
||||
RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_ENGINEERING
|
||||
)
|
||||
departmental_flags = DEPARTMENT_BITFLAG_SCIENCE | DEPARTMENT_BITFLAG_ENGINEERING | DEPARTMENT_BITFLAG_CARGO | DEPARTMENT_BITFLAG_SERVICE
|
||||
|
||||
/datum/design/board/manulathe
|
||||
name = /obj/machinery/power/manufacturing/lathe::name
|
||||
desc = "The circuit board for this machine."
|
||||
id = "manulathe"
|
||||
build_path = /obj/machinery/power/manufacturing/lathe
|
||||
category = list(
|
||||
RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_ENGINEERING
|
||||
)
|
||||
departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING | DEPARTMENT_BITFLAG_CARGO
|
||||
|
||||
/datum/design/board/manucrafter
|
||||
name = /obj/machinery/power/manufacturing/crafter::name
|
||||
desc = "The circuit board for this machine."
|
||||
id = "manucrafter"
|
||||
build_path = /obj/machinery/power/manufacturing/crafter
|
||||
category = list(
|
||||
RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_ENGINEERING
|
||||
)
|
||||
departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING | DEPARTMENT_BITFLAG_CARGO
|
||||
|
||||
/datum/design/board/manucrusher
|
||||
name = /obj/machinery/power/manufacturing/crusher::name
|
||||
desc = "The circuit board for this machine."
|
||||
id = "manucrusher"
|
||||
build_path = /obj/machinery/power/manufacturing/crusher
|
||||
category = list(
|
||||
RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_ENGINEERING
|
||||
)
|
||||
departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING | DEPARTMENT_BITFLAG_CARGO
|
||||
|
||||
/datum/design/board/manurouter
|
||||
name = /obj/machinery/power/manufacturing/router::name
|
||||
desc = "The circuit board for this machine."
|
||||
id = "manurouter"
|
||||
build_path = /obj/machinery/power/manufacturing/router
|
||||
category = list(
|
||||
RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_ENGINEERING
|
||||
)
|
||||
departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING | DEPARTMENT_BITFLAG_CARGO
|
||||
|
||||
/datum/design/board/manusorter
|
||||
name = /obj/machinery/power/manufacturing/sorter::name
|
||||
desc = "The circuit board for this machine."
|
||||
id = "manusorter"
|
||||
build_path = /obj/machinery/power/manufacturing/sorter
|
||||
category = list(
|
||||
RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_ENGINEERING
|
||||
)
|
||||
departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING | DEPARTMENT_BITFLAG_CARGO
|
||||
|
||||
/datum/design/board/manuunloader
|
||||
name = /obj/machinery/power/manufacturing/unloader::name
|
||||
desc = "The circuit board for this machine."
|
||||
id = "manuunloader"
|
||||
build_path = /obj/machinery/power/manufacturing/unloader
|
||||
category = list(
|
||||
RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_ENGINEERING
|
||||
)
|
||||
departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING | DEPARTMENT_BITFLAG_CARGO
|
||||
|
||||
/datum/design/board/manusmelter
|
||||
name = /obj/machinery/power/manufacturing/smelter::name
|
||||
desc = "The circuit board for this machine."
|
||||
id = "manusmelter"
|
||||
build_path = /obj/machinery/power/manufacturing/smelter
|
||||
category = list(
|
||||
RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_ENGINEERING
|
||||
)
|
||||
departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING | DEPARTMENT_BITFLAG_CARGO
|
||||
|
||||
@@ -148,6 +148,13 @@
|
||||
"light_tube",
|
||||
"crossing_signal",
|
||||
"guideway_sensor",
|
||||
"manuunloader",
|
||||
"manusmelter",
|
||||
"manucrusher",
|
||||
"manucrafter",
|
||||
"manulathe",
|
||||
"manusorter",
|
||||
"manurouter",
|
||||
)
|
||||
|
||||
/datum/techweb_node/energy_manipulation
|
||||
|
||||
BIN
icons/obj/machines/manufactorio.dmi
Normal file
BIN
icons/obj/machines/manufactorio.dmi
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.9 KiB |
@@ -758,6 +758,7 @@
|
||||
#include "code\controllers\subsystem\processing\fishing.dm"
|
||||
#include "code\controllers\subsystem\processing\greyscale.dm"
|
||||
#include "code\controllers\subsystem\processing\instruments.dm"
|
||||
#include "code\controllers\subsystem\processing\manufacturing.dm"
|
||||
#include "code\controllers\subsystem\processing\obj.dm"
|
||||
#include "code\controllers\subsystem\processing\plumbing.dm"
|
||||
#include "code\controllers\subsystem\processing\processing.dm"
|
||||
@@ -4576,6 +4577,17 @@
|
||||
#include "code\modules\mafia\roles\town\town_killing.dm"
|
||||
#include "code\modules\mafia\roles\town\town_protective.dm"
|
||||
#include "code\modules\mafia\roles\town\town_support.dm"
|
||||
#include "code\modules\manufactorio\_manufacturing.dm"
|
||||
#include "code\modules\manufactorio\machines\crafter.dm"
|
||||
#include "code\modules\manufactorio\machines\crusher.dm"
|
||||
#include "code\modules\manufactorio\machines\debug.dm"
|
||||
#include "code\modules\manufactorio\machines\lathe.dm"
|
||||
#include "code\modules\manufactorio\machines\router.dm"
|
||||
#include "code\modules\manufactorio\machines\smelter.dm"
|
||||
#include "code\modules\manufactorio\machines\sorter.dm"
|
||||
#include "code\modules\manufactorio\machines\sorter_filters.dm"
|
||||
#include "code\modules\manufactorio\machines\storagebox.dm"
|
||||
#include "code\modules\manufactorio\machines\unloader.dm"
|
||||
#include "code\modules\mapfluff\centcom\nuke_ops.dm"
|
||||
#include "code\modules\mapfluff\ruins\generic.dm"
|
||||
#include "code\modules\mapfluff\ruins\lavaland_ruin_code.dm"
|
||||
|
||||
113
tgui/packages/tgui/interfaces/ManufacturingSorter.tsx
Normal file
113
tgui/packages/tgui/interfaces/ManufacturingSorter.tsx
Normal file
@@ -0,0 +1,113 @@
|
||||
import { BooleanLike } from 'common/react';
|
||||
|
||||
import { useBackend } from '../backend';
|
||||
import { Box, Button, Icon, LabeledList, Section, Stack } from '../components';
|
||||
import { Window } from '../layouts';
|
||||
|
||||
type Data = {
|
||||
filters: Filter[];
|
||||
unmet_dir: number;
|
||||
};
|
||||
|
||||
function dir2icon(dir) {
|
||||
switch (dir) {
|
||||
case 1:
|
||||
return 'arrow-up';
|
||||
case 2:
|
||||
return 'arrow-down';
|
||||
case 4:
|
||||
return 'arrow-right';
|
||||
case 8:
|
||||
return 'arrow-left';
|
||||
default:
|
||||
return 'arrow-up';
|
||||
}
|
||||
}
|
||||
|
||||
type Filter = {
|
||||
name: string;
|
||||
ref: string;
|
||||
inverted: BooleanLike;
|
||||
dir: number;
|
||||
};
|
||||
|
||||
export function ManufacturingSorter(props) {
|
||||
const { act, data } = useBackend<Data>();
|
||||
const { filters, unmet_dir } = data;
|
||||
|
||||
return (
|
||||
<Window width={450} height={350} title="Manufacturing Sorter">
|
||||
<Window.Content>
|
||||
<Stack vertical fill>
|
||||
<Stack.Item height="90%">
|
||||
<Section
|
||||
title="Filters"
|
||||
height="100%"
|
||||
overflowY="auto"
|
||||
buttons={
|
||||
<Button
|
||||
color="green"
|
||||
icon="plus"
|
||||
onClick={() => act('new_filter')}
|
||||
>
|
||||
New filter
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
<LabeledList>
|
||||
{filters.map((filter, i) => (
|
||||
<LabeledList.Item
|
||||
label={i + 1 + '. ' + filter.name}
|
||||
key={filter.ref}
|
||||
>
|
||||
<Button
|
||||
icon={dir2icon(filter.dir)}
|
||||
onClick={() => act('rotate', { ref: filter.ref })}
|
||||
>
|
||||
Output
|
||||
</Button>
|
||||
<Button onClick={() => act('edit', { ref: filter.ref })}>
|
||||
<Icon ml="0.2rem" name="pencil" />
|
||||
</Button>
|
||||
<Button
|
||||
color="red"
|
||||
onClick={() => act('del_filter', { ref: filter.ref })}
|
||||
>
|
||||
<Icon ml="0.2rem" name="trash" />
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('shift', { ref: filter.ref, amount: -1 })
|
||||
}
|
||||
>
|
||||
<Icon ml="0.2rem" name="arrow-up" />
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('shift', { ref: filter.ref, amount: 1 })
|
||||
}
|
||||
>
|
||||
<Icon ml="0.2rem" name="arrow-down" />
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
))}
|
||||
</LabeledList>
|
||||
</Section>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Stack>
|
||||
<Stack.Item>
|
||||
<Box>If no criteria is met, outputting to:</Box>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button onClick={() => act('rotate_unmet')}>
|
||||
<Icon ml="0.2rem" name={dir2icon(unmet_dir)} />
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user