mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-11 16:14:08 +01:00
[MIRROR] General maintenance for Lathes (#26410)
* General maintenance for Lathes (#81244) ## About The Pull Request 1. **Qol Stuff** - Screentips & examines for screwdriver, crowbar acts, multiool & wirecutter Also for Alt click - Techfabs can now also use the Mouse drag functionality to set drop target for items - Lathe printing animation now plays on loop instead of just flicking once till printing is finished for more visual feedback 2. **Code Improvements** - Merged `start_making()` with `do_make_item()`. That proc was like only 3 lines long and used only in 1 place so let's just move that code to `ui_act()` - Merged `user_print_item_id()` with `ui_act()`. Again was used only in 1 place so let's just move that code in to save some proc overhead - Sets `processing_flags` for autolathe to `NONE` cause we don't use `process()` - Autodocs vars such as `hacked` , `shocked` etc & procs - `maxmult` is now computed client side saving backend bandwidth, `construction_time` is removed from lathes which did not use it - Removed all usages of lathe taxes and their related vars, removed engineering lathe no tax from ice moon, replaced with normal engineering lathe 3. **Fixes** - Lathe sheet insertion animations are now linked & work again for all material types inserted via remote silo/local storage, silver/titanium/plastic all play the same animation(that is `protolathe_shiny` overlay). Other materials have their own respective overlays - Fixes #81243. Calling `update_static_data_for_all_viewers()` is too expensive for the UI. We should instead use `SStgui.update_uis(src)` which will report the `busy` status to the UI more immediatly - Fixes #81236. Some problems with the params passed to the timer callback. It should now print the correct number of requested items - Fixes #81192. `design.materials` would runtime for custom material items as they were list of texts not materials. We have to pass our manually parsed list of materials for an specific item to ensure they are set & used correctly. Same fixes apply for techfabs as well ## Changelog 🆑 qol: adds screentips & examines for screwdriver & crowbar acts & alt click. qol: techfabs can now use the mouse drop functionality to set drop target. qol: lathe printing animation plays on loop while printing rather than flicking once for more visual feedback fix: lathe sheet insertion animations are now linked & work again for all material types inserted via remote silo/local storage fix: printing custom materials items from autolathe works again. fix: printing multiple items from lathes will actually print that correct quantity of items requested. fix: printing items the 2nd time around from lathes won't cause the UI to reload each time. code: autodoc for some vars & procs, merges procs. refactor: Optimized code for autolathe & techfabs in general. Report bugs on github /🆑 --------- Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com> * There we go * aaaa * Missed this little thingy * There we go, should be clean af --------- Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com> Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com> Co-authored-by: Useroth <37159550+Useroth@users.noreply.github.com>
This commit is contained in:
@@ -88,7 +88,7 @@
|
||||
/turf/open/floor/iron,
|
||||
/area/ruin/planetengi)
|
||||
"aA" = (
|
||||
/obj/machinery/rnd/production/protolathe/department/engineering/no_tax,
|
||||
/obj/machinery/rnd/production/protolathe/department/engineering,
|
||||
/obj/effect/turf_decal/trimline/yellow/filled/warning{
|
||||
dir = 9
|
||||
},
|
||||
|
||||
@@ -1162,7 +1162,7 @@
|
||||
/obj/item/stack/sheet/glass/fifty,
|
||||
/obj/item/circuitboard/machine/protolathe/offstation,
|
||||
/obj/effect/spawner/random/engineering/toolbox,
|
||||
/obj/item/circuitboard/machine/circuit_imprinter/department/no_tax,
|
||||
/obj/item/circuitboard/machine/circuit_imprinter/department,
|
||||
/obj/item/circuitboard/machine/rtg/advanced,
|
||||
/obj/item/circuitboard/machine/rtg/advanced,
|
||||
/obj/item/circuitboard/machine/rtg/advanced,
|
||||
|
||||
@@ -118,6 +118,12 @@ handles linking back and forth.
|
||||
else
|
||||
silo.holds -= src
|
||||
|
||||
/**
|
||||
* Sets the storage size for local materials when not linked with silo
|
||||
* Arguments
|
||||
*
|
||||
* * size - the new size for local storage. measured in SHEET_MATERIAL_SIZE units
|
||||
*/
|
||||
/datum/component/remote_materials/proc/set_local_size(size)
|
||||
local_size = size
|
||||
if (!silo && mat_container)
|
||||
@@ -209,7 +215,7 @@ handles linking back and forth.
|
||||
return check_z_level() ? silo.holds[src] : FALSE
|
||||
|
||||
/**
|
||||
* Internal proc to check if this connection can use any materials from the silo
|
||||
* Check if this connection can use any materials from the silo
|
||||
* Returns true only if
|
||||
* - The parent is of type movable atom
|
||||
* - A mat container is actually present
|
||||
@@ -217,9 +223,7 @@ handles linking back and forth.
|
||||
* Arguments
|
||||
* * check_hold - should we check if the silo is on hold
|
||||
*/
|
||||
/datum/component/remote_materials/proc/_can_use_resource(check_hold = TRUE)
|
||||
PRIVATE_PROC(TRUE)
|
||||
|
||||
/datum/component/remote_materials/proc/can_use_resource(check_hold = TRUE)
|
||||
var/atom/movable/movable_parent = parent
|
||||
if (!istype(movable_parent))
|
||||
return FALSE
|
||||
@@ -243,7 +247,7 @@ handles linking back and forth.
|
||||
* name- For logging only. the design you are trying to build e.g. matter bin, etc.
|
||||
*/
|
||||
/datum/component/remote_materials/proc/use_materials(list/mats, coefficient = 1, multiplier = 1, action = "build", name = "design")
|
||||
if(!_can_use_resource())
|
||||
if(!can_use_resource())
|
||||
return 0
|
||||
|
||||
var/amount_consumed = mat_container.use_materials(mats, coefficient, multiplier)
|
||||
@@ -265,7 +269,7 @@ handles linking back and forth.
|
||||
* [drop_target][atom]- optional where to drop the sheets. null means it is dropped at this components parent location
|
||||
*/
|
||||
/datum/component/remote_materials/proc/eject_sheets(datum/material/material_ref, eject_amount, atom/drop_target = null)
|
||||
if(!_can_use_resource())
|
||||
if(!can_use_resource())
|
||||
return 0
|
||||
|
||||
var/atom/movable/movable_parent = parent
|
||||
@@ -282,7 +286,7 @@ handles linking back and forth.
|
||||
* * multiplier - the multiplier applied on the materials consumed
|
||||
*/
|
||||
/datum/component/remote_materials/proc/insert_item(obj/item/weapon, multiplier = 1)
|
||||
if(!_can_use_resource(FALSE))
|
||||
if(!can_use_resource(FALSE))
|
||||
return MATERIAL_INSERT_ITEM_FAILURE
|
||||
|
||||
return mat_container.insert_item(weapon, multiplier, parent)
|
||||
|
||||
+217
-163
@@ -7,24 +7,24 @@
|
||||
active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 0.5
|
||||
circuit = /obj/item/circuitboard/machine/autolathe
|
||||
layer = BELOW_OBJ_LAYER
|
||||
processing_flags = NONE
|
||||
|
||||
///Is the autolathe hacked via wiring
|
||||
var/hacked = FALSE
|
||||
///Is the autolathe disabled via wiring
|
||||
var/disabled = FALSE
|
||||
///Did we recently shock a mob who medled with the wiring
|
||||
var/shocked = FALSE
|
||||
///Are we currently printing something
|
||||
var/busy = FALSE
|
||||
|
||||
/// Coefficient applied to consumed materials. Lower values result in lower material consumption.
|
||||
///Coefficient applied to consumed materials. Lower values result in lower material consumption.
|
||||
var/creation_efficiency = 1.6
|
||||
|
||||
var/datum/design/being_built
|
||||
///Designs related to the autolathe
|
||||
var/datum/techweb/autounlocking/stored_research
|
||||
|
||||
///Designs imported from technology disks that we can print.
|
||||
var/list/imported_designs = list()
|
||||
|
||||
///The container to hold materials
|
||||
var/datum/component/material_container/materials
|
||||
|
||||
///direction we output onto (if 0, on top of us)
|
||||
var/drop_direction = 0
|
||||
|
||||
@@ -43,17 +43,69 @@
|
||||
GLOB.autounlock_techwebs[/datum/techweb/autounlocking/autolathe] = new /datum/techweb/autounlocking/autolathe
|
||||
stored_research = GLOB.autounlock_techwebs[/datum/techweb/autounlocking/autolathe]
|
||||
|
||||
register_context()
|
||||
|
||||
/obj/machinery/autolathe/Destroy()
|
||||
materials = null
|
||||
QDEL_NULL(wires)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/autolathe/examine(mob/user)
|
||||
. = ..()
|
||||
if(!in_range(user, src) && !isobserver(user))
|
||||
return
|
||||
|
||||
. += span_notice("Material usage cost at <b>[creation_efficiency * 100]%</b>")
|
||||
if(drop_direction)
|
||||
. += span_notice("Currently configured to drop printed objects <b>[dir2text(drop_direction)]</b>.")
|
||||
. += span_notice("[EXAMINE_HINT("Alt-click")] to reset.")
|
||||
else
|
||||
. += span_notice("[EXAMINE_HINT("Drag")] towards a direction (while next to it) to change drop direction.")
|
||||
|
||||
. += span_notice("Its maintainence panel can be [EXAMINE_HINT("screwed")] [panel_open ? "closed" : "open"].")
|
||||
if(panel_open)
|
||||
. += span_notice("The machine can be [EXAMINE_HINT("pried")] apart.")
|
||||
|
||||
/obj/machinery/autolathe/add_context(atom/source, list/context, obj/item/held_item, mob/user)
|
||||
if(drop_direction)
|
||||
context[SCREENTIP_CONTEXT_ALT_LMB] = "Reset Drop"
|
||||
return CONTEXTUAL_SCREENTIP_SET
|
||||
|
||||
if(isnull(held_item))
|
||||
return NONE
|
||||
|
||||
if(held_item.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
context[SCREENTIP_CONTEXT_RMB] = "[panel_open ? "Close" : "Open"] Panel"
|
||||
return CONTEXTUAL_SCREENTIP_SET
|
||||
|
||||
if(panel_open && held_item.tool_behaviour == TOOL_CROWBAR)
|
||||
context[SCREENTIP_CONTEXT_LMB] = "Deconstruct"
|
||||
return CONTEXTUAL_SCREENTIP_SET
|
||||
|
||||
/obj/machinery/autolathe/crowbar_act(mob/living/user, obj/item/tool)
|
||||
. = ITEM_INTERACT_BLOCKING
|
||||
if(default_deconstruction_crowbar(tool))
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
/obj/machinery/autolathe/screwdriver_act_secondary(mob/living/user, obj/item/tool)
|
||||
. = ITEM_INTERACT_BLOCKING
|
||||
if(default_deconstruction_screwdriver(user, "autolathe_t", "autolathe", tool))
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
/obj/machinery/autolathe/proc/AfterMaterialInsert(container, obj/item/item_inserted, last_inserted_id, mats_consumed, amount_inserted, atom/context)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
flick("autolathe_[item_inserted.has_material_type(/datum/material/glass) ? "r" : "o"]", src)
|
||||
|
||||
directly_use_power(round((amount_inserted / SHEET_MATERIAL_AMOUNT) * active_power_usage * 0.0025))
|
||||
|
||||
/obj/machinery/autolathe/ui_interact(mob/user, datum/tgui/ui)
|
||||
if(!is_operational)
|
||||
return
|
||||
|
||||
if(shocked && !(machine_stat & NOPOWER))
|
||||
shock(user, 50)
|
||||
return
|
||||
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
|
||||
@@ -61,23 +113,75 @@
|
||||
ui = new(user, src, "Autolathe")
|
||||
ui.open()
|
||||
|
||||
|
||||
/**
|
||||
* Converts all the designs supported by this autolathe into UI data
|
||||
* Arguments
|
||||
*
|
||||
* * list/designs - the list of techweb designs we are trying to send to the UI
|
||||
*/
|
||||
/obj/machinery/autolathe/proc/handle_designs(list/designs)
|
||||
PRIVATE_PROC(TRUE)
|
||||
|
||||
var/list/output = list()
|
||||
|
||||
var/datum/asset/spritesheet/research_designs/spritesheet = get_asset_datum(/datum/asset/spritesheet/research_designs)
|
||||
var/size32x32 = "[spritesheet.name]32x32"
|
||||
|
||||
for(var/design_id in designs)
|
||||
var/datum/design/design = SSresearch.techweb_design_by_id(design_id)
|
||||
if(design.make_reagent)
|
||||
continue
|
||||
|
||||
//compute cost & maximum number of printable items
|
||||
var/coeff = (ispath(design.build_path, /obj/item/stack) ? 1 : creation_efficiency)
|
||||
var/list/cost = list()
|
||||
var/customMaterials = FALSE
|
||||
for(var/i in design.materials)
|
||||
var/datum/material/mat = i
|
||||
|
||||
var/design_cost = OPTIMAL_COST(design.materials[i] * coeff)
|
||||
if(istype(mat))
|
||||
cost[mat.name] = design_cost
|
||||
customMaterials = FALSE
|
||||
else
|
||||
cost[i] = design_cost
|
||||
customMaterials = TRUE
|
||||
|
||||
//create & send ui data
|
||||
var/icon_size = spritesheet.icon_size_id(design.id)
|
||||
var/list/design_data = list(
|
||||
"name" = design.name,
|
||||
"desc" = design.get_description(),
|
||||
"cost" = cost,
|
||||
"id" = design.id,
|
||||
"categories" = design.category,
|
||||
"icon" = "[icon_size == size32x32 ? "" : "[icon_size] "][design.id]",
|
||||
"customMaterials" = customMaterials
|
||||
)
|
||||
|
||||
output += list(design_data)
|
||||
|
||||
return output
|
||||
|
||||
/obj/machinery/autolathe/ui_static_data(mob/user)
|
||||
var/list/data = materials.ui_static_data()
|
||||
|
||||
var/max_available = materials.total_amount()
|
||||
for(var/datum/material/container_mat as anything in materials.materials)
|
||||
var/available = materials.materials[container_mat]
|
||||
if(available)
|
||||
max_available = max(max_available, available)
|
||||
|
||||
data["designs"] = handle_designs(stored_research.researched_designs, max_available)
|
||||
data["designs"] = handle_designs(stored_research.researched_designs)
|
||||
if(imported_designs.len)
|
||||
data["designs"] += handle_designs(imported_designs, max_available)
|
||||
data["designs"] += handle_designs(imported_designs)
|
||||
if(hacked)
|
||||
data["designs"] += handle_designs(stored_research.hacked_designs, max_available)
|
||||
data["designs"] += handle_designs(stored_research.hacked_designs)
|
||||
|
||||
return data
|
||||
|
||||
|
||||
/obj/machinery/autolathe/ui_assets(mob/user)
|
||||
return list(
|
||||
get_asset_datum(/datum/asset/spritesheet/sheetmaterials),
|
||||
get_asset_datum(/datum/asset/spritesheet/research_designs),
|
||||
)
|
||||
|
||||
/obj/machinery/autolathe/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
@@ -89,107 +193,51 @@
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/autolathe/proc/handle_designs(list/designs, max_available)
|
||||
var/list/output = list()
|
||||
|
||||
var/datum/asset/spritesheet/research_designs/spritesheet = get_asset_datum(/datum/asset/spritesheet/research_designs)
|
||||
var/size32x32 = "[spritesheet.name]32x32"
|
||||
|
||||
var/max_multiplier = INFINITY
|
||||
for(var/design_id in designs)
|
||||
var/datum/design/design = SSresearch.techweb_design_by_id(design_id)
|
||||
if(design.make_reagent)
|
||||
continue
|
||||
|
||||
//compute cost & maximum number of printable items
|
||||
max_multiplier = INFINITY
|
||||
var/coeff = (ispath(design.build_path, /obj/item/stack) ? 1 : creation_efficiency)
|
||||
var/list/cost = list()
|
||||
for(var/i in design.materials)
|
||||
var/datum/material/mat = i
|
||||
|
||||
var/design_cost = OPTIMAL_COST(design.materials[i] * coeff)
|
||||
if(istype(mat))
|
||||
cost[mat.name] = design_cost
|
||||
else
|
||||
cost[i] = design_cost
|
||||
|
||||
var/mat_available
|
||||
if(istype(mat)) //regular mat
|
||||
mat_available = materials.get_material_amount(mat)
|
||||
else //category mat means we can make it from any mat, use largest available mat
|
||||
mat_available = max_available
|
||||
|
||||
max_multiplier = min(max_multiplier, 50, round(mat_available / design_cost))
|
||||
|
||||
//create & send ui data
|
||||
var/icon_size = spritesheet.icon_size_id(design.id)
|
||||
var/list/design_data = list(
|
||||
"name" = design.name,
|
||||
"desc" = design.get_description(),
|
||||
"cost" = cost,
|
||||
"id" = design.id,
|
||||
"categories" = design.category,
|
||||
"icon" = "[icon_size == size32x32 ? "" : "[icon_size] "][design.id]",
|
||||
"constructionTime" = -1,
|
||||
"maxmult" = max_multiplier
|
||||
)
|
||||
|
||||
output += list(design_data)
|
||||
|
||||
return output
|
||||
|
||||
/obj/machinery/autolathe/ui_assets(mob/user)
|
||||
return list(
|
||||
get_asset_datum(/datum/asset/spritesheet/sheetmaterials),
|
||||
get_asset_datum(/datum/asset/spritesheet/research_designs),
|
||||
)
|
||||
|
||||
/obj/machinery/autolathe/ui_act(action, list/params, datum/tgui/ui)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
//sanity checks to start printing
|
||||
if(action != "make")
|
||||
stack_trace("unknown autolathe ui_act: [action]")
|
||||
return
|
||||
|
||||
if(disabled)
|
||||
say("Unable to print, voltage mismatch in internal wiring.")
|
||||
return
|
||||
|
||||
if(busy)
|
||||
balloon_alert(ui.user, "busy!")
|
||||
return
|
||||
|
||||
var/turf/target_location = get_step(src, drop_direction)
|
||||
if(isclosedturf(target_location))
|
||||
say("Output path is obstructed by a large object.")
|
||||
say("currently printing.")
|
||||
return
|
||||
|
||||
//validate design
|
||||
var/design_id = params["id"]
|
||||
|
||||
if(!design_id)
|
||||
return
|
||||
var/valid_design = stored_research.researched_designs[design_id]
|
||||
valid_design ||= stored_research.hacked_designs[design_id]
|
||||
valid_design ||= imported_designs[design_id]
|
||||
if(!valid_design)
|
||||
return
|
||||
|
||||
var/datum/design/design = SSresearch.techweb_design_by_id(design_id)
|
||||
if(isnull(design))
|
||||
stack_trace("got passed an invalid design id: [design_id] and somehow made it past all checks")
|
||||
return
|
||||
|
||||
if(!(design.build_type & AUTOLATHE))
|
||||
say("This fabricator does not have the necessary keys to decrypt this design.")
|
||||
return
|
||||
|
||||
var/build_count = text2num(params["multiplier"])
|
||||
if(!build_count)
|
||||
//validate print quantity
|
||||
var/build_count = params["multiplier"]
|
||||
if(isnull(build_count))
|
||||
return
|
||||
build_count = text2num(build_count)
|
||||
if(isnull(build_count))
|
||||
return
|
||||
build_count = clamp(build_count, 1, 50)
|
||||
|
||||
//check for materials required. For custom material items decode their required materials
|
||||
var/list/materials_needed = list()
|
||||
for(var/datum/material/material as anything in design.materials)
|
||||
for(var/material in design.materials)
|
||||
var/amount_needed = design.materials[material]
|
||||
if(istext(material)) // category
|
||||
var/list/choices = list()
|
||||
@@ -215,64 +263,70 @@
|
||||
return
|
||||
materials_needed[material] = amount_needed
|
||||
|
||||
//checks for available materials
|
||||
var/material_cost_coefficient = ispath(design.build_path, /obj/item/stack) ? 1 : creation_efficiency
|
||||
if(!materials.has_materials(materials_needed, material_cost_coefficient, build_count))
|
||||
say("Not enough materials to begin production.")
|
||||
return
|
||||
|
||||
//use power
|
||||
var/total_charge = 0
|
||||
//compute power & time to print 1 item
|
||||
var/charge_per_item = 0
|
||||
for(var/material in design.materials)
|
||||
total_charge += round(design.materials[material] * material_cost_coefficient * build_count)
|
||||
var/charge_per_item = total_charge / build_count
|
||||
|
||||
var/total_time = (design.construction_time * design.lathe_time_factor * build_count) ** 0.8
|
||||
var/time_per_item = total_time / build_count
|
||||
start_making(design, build_count, time_per_item, material_cost_coefficient, charge_per_item)
|
||||
return TRUE
|
||||
|
||||
/// Begins the act of making the given design the given number of items
|
||||
/// Does not check or use materials/power/etc
|
||||
/obj/machinery/autolathe/proc/start_making(datum/design/design, build_count, build_time_per_item, material_cost_coefficient, charge_per_item)
|
||||
PROTECTED_PROC(TRUE)
|
||||
charge_per_item += design.materials[material]
|
||||
charge_per_item = min(active_power_usage, round(charge_per_item * material_cost_coefficient))
|
||||
var/build_time_per_item = (design.construction_time * design.lathe_time_factor) ** 0.8
|
||||
|
||||
//do the printing sequentially
|
||||
busy = TRUE
|
||||
icon_state = "autolathe_n"
|
||||
update_static_data_for_all_viewers()
|
||||
SStgui.update_uis(src)
|
||||
var/turf/target_location
|
||||
if(drop_direction)
|
||||
target_location = get_step(src, drop_direction)
|
||||
if(isclosedturf(target_location))
|
||||
target_location = get_turf(src)
|
||||
else
|
||||
target_location = get_turf(src)
|
||||
addtimer(CALLBACK(src, PROC_REF(do_make_item), design, build_count, build_time_per_item, material_cost_coefficient, charge_per_item, materials_needed, target_location), build_time_per_item)
|
||||
|
||||
addtimer(CALLBACK(src, PROC_REF(do_make_item), design, material_cost_coefficient, build_time_per_item, charge_per_item, build_count), build_time_per_item)
|
||||
return TRUE
|
||||
|
||||
/// Callback for start_making, actually makes the item
|
||||
/// Called using timers started by start_making
|
||||
/obj/machinery/autolathe/proc/do_make_item(datum/design/design, material_cost_coefficient, time_per_item, charge_per_item, items_remaining)
|
||||
/**
|
||||
* Callback for start_making, actually makes the item
|
||||
* Arguments
|
||||
*
|
||||
* * datum/design/design - the design we are trying to print
|
||||
* * items_remaining - the number of designs left out to print
|
||||
* * build_time_per_item - the time taken to print 1 item
|
||||
* * material_cost_coefficient - the cost efficiency to print 1 design
|
||||
* * charge_per_item - the amount of power to print 1 item
|
||||
* * list/materials_needed - the list of materials to print 1 item
|
||||
* * turf/target - the location to drop the printed item on
|
||||
*/
|
||||
/obj/machinery/autolathe/proc/do_make_item(datum/design/design, items_remaining, build_time_per_item, material_cost_coefficient, charge_per_item, list/materials_needed, turf/target)
|
||||
PROTECTED_PROC(TRUE)
|
||||
|
||||
if(!items_remaining) // how
|
||||
if(items_remaining <= 0) // how
|
||||
finalize_build()
|
||||
return
|
||||
|
||||
if(!directly_use_power(charge_per_item))
|
||||
if(!is_operational || !directly_use_power(charge_per_item))
|
||||
say("Unable to continue production, power failure.")
|
||||
finalize_build()
|
||||
return
|
||||
|
||||
var/list/design_materials = design.materials
|
||||
var/is_stack = ispath(design.build_path, /obj/item/stack)
|
||||
if(!materials.has_materials(design_materials, material_cost_coefficient, is_stack ? items_remaining : 1))
|
||||
if(!materials.has_materials(materials_needed, material_cost_coefficient, is_stack ? items_remaining : 1))
|
||||
say("Unable to continue production, missing materials.")
|
||||
return
|
||||
materials.use_materials(design_materials, material_cost_coefficient, is_stack ? items_remaining : 1)
|
||||
|
||||
var/turf/target = get_step(src, drop_direction)
|
||||
if(isclosedturf(target))
|
||||
target = get_turf(src)
|
||||
materials.use_materials(materials_needed, material_cost_coefficient, is_stack ? items_remaining : 1)
|
||||
|
||||
var/atom/movable/created
|
||||
if(is_stack)
|
||||
created = new design.build_path(target, items_remaining)
|
||||
else
|
||||
created = new design.build_path(target)
|
||||
split_materials_uniformly(design_materials, material_cost_coefficient, created)
|
||||
split_materials_uniformly(materials_needed, material_cost_coefficient, created)
|
||||
|
||||
created.pixel_x = created.base_pixel_x + rand(-6, 6)
|
||||
created.pixel_y = created.base_pixel_y + rand(-6, 6)
|
||||
@@ -283,26 +337,44 @@
|
||||
else
|
||||
items_remaining -= 1
|
||||
|
||||
if(!items_remaining)
|
||||
if(items_remaining <= 0)
|
||||
finalize_build()
|
||||
return
|
||||
addtimer(CALLBACK(src, PROC_REF(do_make_item), design, material_cost_coefficient, time_per_item, items_remaining), time_per_item)
|
||||
addtimer(CALLBACK(src, PROC_REF(do_make_item), design, items_remaining, build_time_per_item, material_cost_coefficient, charge_per_item, materials_needed, target), build_time_per_item)
|
||||
|
||||
/// Resets the icon state and busy flag
|
||||
/// Called at the end of do_make_item's timer loop
|
||||
/**
|
||||
* Resets the icon state and busy flag
|
||||
* Called at the end of do_make_item's timer loop
|
||||
*/
|
||||
/obj/machinery/autolathe/proc/finalize_build()
|
||||
PROTECTED_PROC(TRUE)
|
||||
|
||||
icon_state = initial(icon_state)
|
||||
busy = FALSE
|
||||
update_static_data_for_all_viewers()
|
||||
SStgui.update_uis(src)
|
||||
|
||||
/obj/machinery/autolathe/crowbar_act(mob/living/user, obj/item/tool)
|
||||
if(default_deconstruction_crowbar(tool))
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
/obj/machinery/autolathe/MouseDrop(atom/over, src_location, over_location, src_control, over_control, params)
|
||||
. = ..()
|
||||
if((!issilicon(usr) && !isAdminGhostAI(usr)) && !Adjacent(usr))
|
||||
return
|
||||
if(busy)
|
||||
balloon_alert(usr, "printing started!")
|
||||
return
|
||||
var/direction = get_dir(src, over_location)
|
||||
if(!direction)
|
||||
return
|
||||
drop_direction = direction
|
||||
balloon_alert(usr, "dropping [dir2text(drop_direction)]")
|
||||
|
||||
/obj/machinery/autolathe/screwdriver_act_secondary(mob/living/user, obj/item/tool)
|
||||
if(default_deconstruction_screwdriver(user, "autolathe_t", "autolathe", tool))
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
/obj/machinery/autolathe/AltClick(mob/user)
|
||||
. = ..()
|
||||
if(!drop_direction || !can_interact(user))
|
||||
return
|
||||
if(busy)
|
||||
balloon_alert(user, "busy printing!")
|
||||
return
|
||||
balloon_alert(user, "drop direction reset")
|
||||
drop_direction = 0
|
||||
|
||||
/obj/machinery/autolathe/attackby(obj/item/attacking_item, mob/living/user, params)
|
||||
if(user.combat_mode) //so we can hit the machine
|
||||
@@ -346,25 +418,6 @@
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/autolathe/proc/AfterMaterialInsert(container, obj/item/item_inserted, last_inserted_id, mats_consumed, amount_inserted, atom/context)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
flick("autolathe_[item_inserted.has_material_type(/datum/material/glass) ? "r" : "o"]", src)
|
||||
|
||||
use_power(min(active_power_usage * 0.25, amount_inserted / SHEET_MATERIAL_AMOUNT))
|
||||
|
||||
update_static_data_for_all_viewers()
|
||||
|
||||
/obj/machinery/autolathe/MouseDrop(atom/over, src_location, over_location, src_control, over_control, params)
|
||||
. = ..()
|
||||
if((!issilicon(usr) && !isAdminGhostAI(usr)) && !Adjacent(usr))
|
||||
return
|
||||
var/direction = get_dir(src, over_location)
|
||||
if(!direction)
|
||||
return
|
||||
drop_direction = direction
|
||||
balloon_alert(usr, "dropping [dir2text(drop_direction)]")
|
||||
|
||||
/obj/machinery/autolathe/RefreshParts()
|
||||
. = ..()
|
||||
var/mat_capacity = 0
|
||||
@@ -377,24 +430,12 @@
|
||||
efficiency -= new_servo.tier * 0.2
|
||||
creation_efficiency = max(1,efficiency) // creation_efficiency goes 1.6 -> 1.4 -> 1.2 -> 1 per level of servo efficiency
|
||||
|
||||
/obj/machinery/autolathe/examine(mob/user)
|
||||
. += ..()
|
||||
if(in_range(user, src) || isobserver(user))
|
||||
. += span_notice("The status display reads: Storing up to <b>[materials.max_amount]</b> material units.<br>Material consumption at <b>[creation_efficiency*100]%</b>.")
|
||||
if(drop_direction)
|
||||
. += span_notice("Currently configured to drop printed objects <b>[dir2text(drop_direction)]</b>.")
|
||||
. += span_notice("<b>Alt-click</b> to reset.")
|
||||
else
|
||||
. += span_notice("<b>Drag towards a direction</b> (while next to it) to change drop direction.")
|
||||
|
||||
/obj/machinery/autolathe/AltClick(mob/user)
|
||||
. = ..()
|
||||
if(!can_interact(user))
|
||||
return
|
||||
if(drop_direction)
|
||||
balloon_alert(user, "drop direction reset")
|
||||
drop_direction = 0
|
||||
|
||||
/**
|
||||
* Cut a wire in the autolathe
|
||||
* Arguments
|
||||
*
|
||||
* * wire - the wire we are trying to cut
|
||||
*/
|
||||
/obj/machinery/autolathe/proc/reset(wire)
|
||||
switch(wire)
|
||||
if(WIRE_HACK)
|
||||
@@ -407,6 +448,13 @@
|
||||
if(!wires.is_cut(wire))
|
||||
disabled = FALSE
|
||||
|
||||
/**
|
||||
* Shock a mob who is trying to interact with the autolathe
|
||||
* Arguments
|
||||
*
|
||||
* * mob/user - the mob we are trying to shock
|
||||
* * prb - the probability of getting shocked
|
||||
*/
|
||||
/obj/machinery/autolathe/proc/shock(mob/user, prb)
|
||||
if(machine_stat & (BROKEN|NOPOWER)) // unpowered, no shock
|
||||
return FALSE
|
||||
@@ -417,6 +465,12 @@
|
||||
s.start()
|
||||
return electrocute_mob(user, get_area(src), src, 0.7, TRUE)
|
||||
|
||||
/**
|
||||
* Is the autolathe hacked. Allowing us to acess hidden designs
|
||||
* Arguments
|
||||
*
|
||||
* state - TRUE/FALSE for is the autolathe hacked
|
||||
*/
|
||||
/obj/machinery/autolathe/proc/adjust_hacked(state)
|
||||
hacked = state
|
||||
update_static_data_for_all_viewers()
|
||||
|
||||
@@ -309,9 +309,6 @@
|
||||
greyscale_colors = CIRCUIT_COLOR_ENGINEERING
|
||||
build_path = /obj/machinery/rnd/production/protolathe/department/engineering
|
||||
|
||||
/obj/item/circuitboard/machine/protolathe/department/engineering/no_tax
|
||||
build_path = /obj/machinery/rnd/production/protolathe/department/engineering/no_tax
|
||||
|
||||
/obj/item/circuitboard/machine/rtg
|
||||
name = "RTG"
|
||||
greyscale_colors = CIRCUIT_COLOR_ENGINEERING
|
||||
|
||||
@@ -4,15 +4,24 @@
|
||||
req_access = list(ACCESS_AWAY_SCIENCE)
|
||||
|
||||
/obj/machinery/rnd/server/oldstation/Initialize(mapload)
|
||||
register_context()
|
||||
var/datum/techweb/oldstation_web = locate(/datum/techweb/oldstation) in SSresearch.techwebs
|
||||
stored_research = oldstation_web
|
||||
return ..()
|
||||
|
||||
/obj/machinery/rnd/server/oldstation/add_context(atom/source, list/context, obj/item/held_item, mob/user)
|
||||
. = ..()
|
||||
|
||||
if(held_item && istype(held_item, /obj/item/research_notes))
|
||||
context[SCREENTIP_CONTEXT_LMB] = "Generate research points"
|
||||
return CONTEXTUAL_SCREENTIP_SET
|
||||
return CONTEXTUAL_SCREENTIP_SET
|
||||
|
||||
/obj/machinery/rnd/server/oldstation/examine(mob/user)
|
||||
. = ..()
|
||||
|
||||
if(!in_range(user, src) && !isobserver(user))
|
||||
return
|
||||
|
||||
. += span_notice("Insert [EXAMINE_HINT("Research Notes")] to generate points.")
|
||||
|
||||
/obj/machinery/rnd/server/oldstation/attackby(obj/item/attacking_item, mob/user, params)
|
||||
if(istype(attacking_item, /obj/item/research_notes) && stored_research)
|
||||
|
||||
@@ -14,16 +14,29 @@
|
||||
base_icon_state = "d_analyzer"
|
||||
circuit = /obj/item/circuitboard/machine/destructive_analyzer
|
||||
|
||||
/obj/machinery/rnd/destructive_analyzer/Initialize(mapload)
|
||||
. = ..()
|
||||
register_context()
|
||||
|
||||
/obj/machinery/rnd/destructive_analyzer/add_context(atom/source, list/context, obj/item/held_item, mob/living/user)
|
||||
. = ..()
|
||||
|
||||
var/screentip_set = FALSE
|
||||
if(loaded_item)
|
||||
context[SCREENTIP_CONTEXT_ALT_LMB] = "Remove Item"
|
||||
screentip_set = TRUE
|
||||
else if(!isnull(held_item))
|
||||
context[SCREENTIP_CONTEXT_LMB] = "Insert Item"
|
||||
return CONTEXTUAL_SCREENTIP_SET
|
||||
screentip_set = TRUE
|
||||
|
||||
if(screentip_set)
|
||||
. = CONTEXTUAL_SCREENTIP_SET
|
||||
|
||||
/obj/machinery/rnd/destructive_analyzer/examine(mob/user)
|
||||
. = ..()
|
||||
if(!in_range(user, src) && !isobserver(user))
|
||||
return
|
||||
|
||||
if(loaded_item)
|
||||
. += span_notice("[EXAMINE_HINT("Left-Click")] to remove loaded item inside.")
|
||||
else
|
||||
. += span_notice("An item can be loaded inside via [EXAMINE_HINT("Left-Click")].")
|
||||
|
||||
/obj/machinery/rnd/destructive_analyzer/attackby(obj/item/weapon, mob/living/user, params)
|
||||
if(user.combat_mode)
|
||||
|
||||
@@ -1,38 +1,37 @@
|
||||
/obj/machinery/rnd/production
|
||||
name = "technology fabricator"
|
||||
desc = "Makes researched and prototype items with materials and energy."
|
||||
layer = BELOW_OBJ_LAYER
|
||||
|
||||
/// The efficiency coefficient. Material costs and print times are multiplied by this number;
|
||||
/// better parts result in a higher efficiency (and lower value).
|
||||
var/efficiency_coeff = 1
|
||||
|
||||
/// The material storage used by this fabricator.
|
||||
var/datum/component/remote_materials/materials
|
||||
|
||||
/// Which departments are allowed to process this design
|
||||
var/allowed_department_flags = ALL
|
||||
|
||||
/// What's flick()'d on print.
|
||||
/// Icon state when production has started
|
||||
var/production_animation
|
||||
|
||||
/// The types of designs this fabricator can print.
|
||||
var/allowed_buildtypes = NONE
|
||||
|
||||
/// All designs in the techweb that can be fabricated by this machine, since the last update.
|
||||
var/list/datum/design/cached_designs
|
||||
|
||||
/// What color is this machine's stripe? Leave null to not have a stripe.
|
||||
var/stripe_color = null
|
||||
|
||||
/// Does this charge the user's ID on fabrication?
|
||||
var/charges_tax = TRUE
|
||||
///direction we output onto (if 0, on top of us)
|
||||
var/drop_direction = 0
|
||||
|
||||
/obj/machinery/rnd/production/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
cached_designs = list()
|
||||
materials = AddComponent(/datum/component/remote_materials, mapload)
|
||||
materials = AddComponent(
|
||||
/datum/component/remote_materials, \
|
||||
mapload, \
|
||||
mat_container_signals = list( \
|
||||
COMSIG_MATCONTAINER_ITEM_CONSUMED = TYPE_PROC_REF(/obj/machinery/rnd, local_material_insert)
|
||||
) \
|
||||
)
|
||||
|
||||
RegisterSignal(src, COMSIG_SILO_ITEM_CONSUMED, TYPE_PROC_REF(/obj/machinery/rnd/production, silo_material_insert))
|
||||
|
||||
AddComponent(
|
||||
/datum/component/payment, \
|
||||
@@ -42,9 +41,49 @@
|
||||
TRUE, \
|
||||
)
|
||||
|
||||
RefreshParts()
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
|
||||
/obj/machinery/rnd/production/Destroy()
|
||||
materials = null
|
||||
cached_designs = null
|
||||
return ..()
|
||||
|
||||
|
||||
// Stuff for the stripe on the department machines
|
||||
/obj/machinery/rnd/production/default_deconstruction_screwdriver(mob/user, icon_state_open, icon_state_closed, obj/item/screwdriver)
|
||||
. = ..()
|
||||
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
|
||||
/obj/machinery/rnd/production/update_overlays()
|
||||
. = ..()
|
||||
|
||||
if(!stripe_color)
|
||||
return
|
||||
|
||||
var/mutable_appearance/stripe = mutable_appearance('icons/obj/machines/research.dmi', "protolathe_stripe[panel_open ? "_t" : ""]")
|
||||
stripe.color = stripe_color
|
||||
. += stripe
|
||||
|
||||
|
||||
/obj/machinery/rnd/production/examine(mob/user)
|
||||
. = ..()
|
||||
if(!in_range(user, src) && !isobserver(user))
|
||||
return
|
||||
|
||||
. += span_notice("Material usage cost at <b>[efficiency_coeff * 100]%</b>")
|
||||
if(drop_direction)
|
||||
. += span_notice("Currently configured to drop printed objects <b>[dir2text(drop_direction)]</b>.")
|
||||
. += span_notice("[EXAMINE_HINT("Alt-click")] to reset.")
|
||||
else
|
||||
. += span_notice("[EXAMINE_HINT("Drag")] towards a direction (while next to it) to change drop direction.")
|
||||
|
||||
/obj/machinery/rnd/production/add_context(atom/source, list/context, obj/item/held_item, mob/user)
|
||||
. = ..()
|
||||
if(drop_direction)
|
||||
context[SCREENTIP_CONTEXT_ALT_LMB] = "Reset Drop"
|
||||
return CONTEXTUAL_SCREENTIP_SET
|
||||
|
||||
/obj/machinery/rnd/production/connect_techweb(datum/techweb/new_techweb)
|
||||
if(stored_research)
|
||||
UnregisterSignal(stored_research, list(COMSIG_TECHWEB_ADD_DESIGN, COMSIG_TECHWEB_REMOVE_DESIGN))
|
||||
@@ -55,24 +94,14 @@
|
||||
RegisterSignals(
|
||||
stored_research,
|
||||
list(COMSIG_TECHWEB_ADD_DESIGN, COMSIG_TECHWEB_REMOVE_DESIGN),
|
||||
PROC_REF(on_techweb_update)
|
||||
TYPE_PROC_REF(/obj/machinery/rnd/production, on_techweb_update)
|
||||
)
|
||||
update_designs()
|
||||
|
||||
/obj/machinery/rnd/production/Destroy()
|
||||
materials = null
|
||||
cached_designs = null
|
||||
return ..()
|
||||
|
||||
/obj/machinery/rnd/production/proc/on_techweb_update()
|
||||
SIGNAL_HANDLER
|
||||
|
||||
// We're probably going to get more than one update (design) at a time, so batch
|
||||
// them together.
|
||||
addtimer(CALLBACK(src, PROC_REF(update_designs)), 2 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE)
|
||||
|
||||
/// Updates the list of designs this fabricator can print.
|
||||
/obj/machinery/rnd/production/proc/update_designs()
|
||||
PROTECTED_PROC(TRUE)
|
||||
|
||||
var/previous_design_count = cached_designs.len
|
||||
|
||||
cached_designs.Cut()
|
||||
@@ -91,12 +120,98 @@
|
||||
|
||||
update_static_data_for_all_viewers()
|
||||
|
||||
/obj/machinery/rnd/production/proc/on_techweb_update()
|
||||
SIGNAL_HANDLER
|
||||
|
||||
// We're probably going to get more than one update (design) at a time, so batch
|
||||
// them together.
|
||||
addtimer(CALLBACK(src, PROC_REF(update_designs)), 2 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE)
|
||||
|
||||
///When materials are instered via silo link
|
||||
/obj/machinery/rnd/proc/silo_material_insert(obj/machinery/rnd/machine, container, obj/item/item_inserted, last_inserted_id, list/mats_consumed, amount_inserted)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
process_item(item_inserted, mats_consumed, amount_inserted)
|
||||
|
||||
/**
|
||||
* Consumes power for the item inserted either into silo or local storage.
|
||||
* Arguments
|
||||
*
|
||||
* * obj/item/item_inserted - the item to process
|
||||
* * list/mats_consumed - list of mats consumed
|
||||
* * amount_inserted - amount of material actually processed
|
||||
*/
|
||||
/obj/machinery/rnd/proc/process_item(obj/item/item_inserted, list/mats_consumed, amount_inserted)
|
||||
PRIVATE_PROC(TRUE)
|
||||
|
||||
if(directly_use_power(round((amount_inserted / SHEET_MATERIAL_AMOUNT) * active_power_usage * 0.00025)))
|
||||
var/mat_name = "iron"
|
||||
|
||||
var/highest_mat = 0
|
||||
for(var/datum/material/mat as anything in mats_consumed)
|
||||
var/present_mat = mats_consumed[mat]
|
||||
if(present_mat > highest_mat)
|
||||
mat_name = initial(mat.name)
|
||||
if(mat_name == "silver" || mat_name == "titanium" || mat_name == "plastic") //these materials have similar appearances so use an common overlay for them
|
||||
mat_name = "shiny"
|
||||
highest_mat = present_mat
|
||||
|
||||
flick_animation(mat_name)
|
||||
/**
|
||||
* Plays an visual animation when materials are inserted
|
||||
* Arguments
|
||||
*
|
||||
* * mat_name - the name of the material we are trying to animate on the machine
|
||||
*/
|
||||
/obj/machinery/rnd/proc/flick_animation(mat_name)
|
||||
PROTECTED_PROC(TRUE)
|
||||
SHOULD_CALL_PARENT(FALSE)
|
||||
|
||||
flick_overlay_view(mutable_appearance('icons/obj/machines/research.dmi', "protolathe_[mat_name]"), 1 SECONDS)
|
||||
|
||||
///When materials are instered into local storage
|
||||
/obj/machinery/rnd/proc/local_material_insert(container, obj/item/item_inserted, last_inserted_id, list/mats_consumed, amount_inserted, atom/context)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
process_item(item_inserted, mats_consumed, amount_inserted)
|
||||
|
||||
/obj/machinery/rnd/production/RefreshParts()
|
||||
. = ..()
|
||||
|
||||
calculate_efficiency()
|
||||
if(materials)
|
||||
var/total_storage = 0
|
||||
for(var/datum/stock_part/matter_bin/bin in component_parts)
|
||||
total_storage += bin.tier * 37.5 * SHEET_MATERIAL_AMOUNT
|
||||
materials.set_local_size(total_storage)
|
||||
|
||||
efficiency_coeff = compute_efficiency()
|
||||
|
||||
update_static_data_for_all_viewers()
|
||||
|
||||
///Computes this machines cost efficiency based on the available parts
|
||||
/obj/machinery/rnd/production/proc/compute_efficiency()
|
||||
PROTECTED_PROC(TRUE)
|
||||
|
||||
var/efficiency = 1.2
|
||||
for(var/datum/stock_part/servo/servo in component_parts)
|
||||
efficiency -= servo.tier * 0.1
|
||||
|
||||
return efficiency
|
||||
|
||||
/**
|
||||
* The cost efficiency for an particular design
|
||||
* Arguments
|
||||
*
|
||||
* * path - the design path to check for
|
||||
*/
|
||||
/obj/machinery/rnd/production/proc/build_efficiency(path)
|
||||
PRIVATE_PROC(TRUE)
|
||||
|
||||
if(ispath(path, /obj/item/stack/sheet) || ispath(path, /obj/item/stack/ore/bluespace_crystal))
|
||||
return 1
|
||||
else
|
||||
return efficiency_coeff
|
||||
|
||||
/obj/machinery/rnd/production/ui_assets(mob/user)
|
||||
return list(
|
||||
get_asset_datum(/datum/asset/spritesheet/sheetmaterials),
|
||||
@@ -117,16 +232,13 @@
|
||||
var/datum/asset/spritesheet/research_designs/spritesheet = get_asset_datum(/datum/asset/spritesheet/research_designs)
|
||||
var/size32x32 = "[spritesheet.name]32x32"
|
||||
|
||||
var/max_multiplier = INFINITY
|
||||
var/coefficient
|
||||
for(var/datum/design/design in cached_designs)
|
||||
var/cost = list()
|
||||
|
||||
max_multiplier = INFINITY
|
||||
coefficient = build_efficiency(design.build_path)
|
||||
for(var/datum/material/mat in design.materials)
|
||||
cost[mat.name] = OPTIMAL_COST(design.materials[mat] * coefficient)
|
||||
max_multiplier = min(max_multiplier, 50, round(materials.mat_container.get_material_amount(mat) / cost[mat.name]))
|
||||
|
||||
var/icon_size = spritesheet.icon_size_id(design.id)
|
||||
designs[design.id] = list(
|
||||
@@ -135,9 +247,7 @@
|
||||
"cost" = cost,
|
||||
"id" = design.id,
|
||||
"categories" = design.category,
|
||||
"icon" = "[icon_size == size32x32 ? "" : "[icon_size] "][design.id]",
|
||||
"constructionTime" = 0,
|
||||
"maxmult" = max_multiplier
|
||||
"icon" = "[icon_size == size32x32 ? "" : "[icon_size] "][design.id]"
|
||||
)
|
||||
|
||||
data["designs"] = designs
|
||||
@@ -158,141 +268,126 @@
|
||||
|
||||
/obj/machinery/rnd/production/ui_act(action, list/params, datum/tgui/ui)
|
||||
. = ..()
|
||||
|
||||
if(.)
|
||||
return
|
||||
|
||||
. = TRUE
|
||||
|
||||
switch (action)
|
||||
if("remove_mat")
|
||||
var/datum/material/material = locate(params["ref"])
|
||||
var/amount = text2num(params["amount"])
|
||||
// SAFETY: eject_sheets checks for valid mats
|
||||
if(!istype(material))
|
||||
return
|
||||
|
||||
var/amount = params["amount"]
|
||||
if(isnull(amount))
|
||||
return
|
||||
|
||||
amount = text2num(amount)
|
||||
if(isnull(amount))
|
||||
return
|
||||
|
||||
materials.eject_sheets(material, amount)
|
||||
return TRUE
|
||||
|
||||
if("build")
|
||||
user_try_print_id(ui.user, params["ref"], params["amount"])
|
||||
if(busy)
|
||||
say("Warning: fabricator is busy!")
|
||||
return
|
||||
|
||||
/// Updates the fabricator's efficiency coefficient based on the installed parts.
|
||||
/obj/machinery/rnd/production/proc/calculate_efficiency()
|
||||
efficiency_coeff = 1
|
||||
//validate design
|
||||
var/design_id = params["ref"]
|
||||
if(!design_id)
|
||||
return
|
||||
var/datum/design/design = stored_research.researched_designs[design_id] ? SSresearch.techweb_design_by_id(design_id) : null
|
||||
if(!istype(design))
|
||||
return FALSE
|
||||
if(!(isnull(allowed_department_flags) || (design.departmental_flags & allowed_department_flags)))
|
||||
say("This fabricator does not have the necessary keys to decrypt this design.")
|
||||
return FALSE
|
||||
if(design.build_type && !(design.build_type & allowed_buildtypes))
|
||||
say("This fabricator does not have the necessary manipulation systems for this design.")
|
||||
return FALSE
|
||||
|
||||
if(materials)
|
||||
var/total_storage = 0
|
||||
//validate print quantity
|
||||
var/print_quantity = params["amount"]
|
||||
if(isnull(print_quantity))
|
||||
return
|
||||
print_quantity = text2num(print_quantity)
|
||||
if(isnull(print_quantity))
|
||||
return
|
||||
print_quantity = clamp(print_quantity, 1, 50)
|
||||
|
||||
for(var/datum/stock_part/matter_bin/bin in component_parts)
|
||||
total_storage += bin.tier * (37.5*SHEET_MATERIAL_AMOUNT)
|
||||
//efficiency for this design, stacks use exact materials
|
||||
var/coefficient = build_efficiency(design.build_path)
|
||||
|
||||
materials.set_local_size(total_storage)
|
||||
//check for materials
|
||||
if(!materials.can_use_resource())
|
||||
return
|
||||
if(!materials.mat_container.has_materials(design.materials, coefficient, print_quantity))
|
||||
say("Not enough materials to complete prototype[print_quantity > 1 ? "s" : ""].")
|
||||
return FALSE
|
||||
|
||||
var/total_rating = 1.2
|
||||
//compute power & time to print 1 item
|
||||
var/charge_per_item = 0
|
||||
for(var/material in design.materials)
|
||||
charge_per_item += design.materials[material]
|
||||
charge_per_item = min(active_power_usage, round(charge_per_item * coefficient))
|
||||
var/build_time_per_item = (design.construction_time * design.lathe_time_factor) ** 0.8
|
||||
|
||||
for(var/datum/stock_part/servo/servo in component_parts)
|
||||
total_rating -= servo.tier * 0.1
|
||||
//start production
|
||||
busy = TRUE
|
||||
SStgui.update_uis(src)
|
||||
if(production_animation)
|
||||
icon_state = production_animation
|
||||
var/turf/target_location
|
||||
if(drop_direction)
|
||||
target_location = get_step(src, drop_direction)
|
||||
if(isclosedturf(target_location))
|
||||
target_location = get_turf(src)
|
||||
else
|
||||
target_location = get_turf(src)
|
||||
addtimer(CALLBACK(src, PROC_REF(do_make_item), design, print_quantity, build_time_per_item, coefficient, charge_per_item, target_location), build_time_per_item)
|
||||
|
||||
efficiency_coeff = max(total_rating, 0)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/rnd/production/proc/build_efficiency(path)
|
||||
if(ispath(path, /obj/item/stack/sheet) || ispath(path, /obj/item/stack/ore/bluespace_crystal))
|
||||
return 1
|
||||
else
|
||||
return efficiency_coeff
|
||||
|
||||
/obj/machinery/rnd/production/proc/user_try_print_id(mob/user, design_id, print_quantity)
|
||||
if(!design_id)
|
||||
return FALSE
|
||||
|
||||
if(istext(print_quantity))
|
||||
print_quantity = text2num(print_quantity)
|
||||
|
||||
if(isnull(print_quantity))
|
||||
print_quantity = 1
|
||||
|
||||
var/datum/design/design = stored_research.researched_designs[design_id] ? SSresearch.techweb_design_by_id(design_id) : null
|
||||
|
||||
if(!istype(design))
|
||||
return FALSE
|
||||
|
||||
if(busy)
|
||||
say("Warning: fabricator is busy!")
|
||||
return FALSE
|
||||
|
||||
if(!(isnull(allowed_department_flags) || (design.departmental_flags & allowed_department_flags)))
|
||||
say("This fabricator does not have the necessary keys to decrypt this design.")
|
||||
return FALSE
|
||||
|
||||
if(design.build_type && !(design.build_type & allowed_buildtypes))
|
||||
say("This fabricator does not have the necessary manipulation systems for this design.")
|
||||
return FALSE
|
||||
|
||||
if(!materials.mat_container)
|
||||
say("No connection to material storage, please contact the quartermaster.")
|
||||
return FALSE
|
||||
|
||||
if(materials.on_hold())
|
||||
say("Mineral access is on hold, please contact the quartermaster.")
|
||||
return FALSE
|
||||
|
||||
print_quantity = clamp(print_quantity, 1, 50)
|
||||
var/coefficient = build_efficiency(design.build_path)
|
||||
|
||||
// check if sufficient materials are available.
|
||||
if(!materials.mat_container.has_materials(design.materials, coefficient, print_quantity))
|
||||
say("Not enough materials to complete prototype[print_quantity > 1 ? "s" : ""].")
|
||||
return FALSE
|
||||
|
||||
//use power
|
||||
var/total_charge = 0
|
||||
for(var/material in design.materials)
|
||||
total_charge += round(design.materials[material] * coefficient * print_quantity / 35)
|
||||
var/charge_per_item = total_charge / print_quantity
|
||||
|
||||
if(production_animation)
|
||||
flick(production_animation, src)
|
||||
|
||||
var/total_time = (design.construction_time * design.lathe_time_factor * print_quantity) ** 0.8
|
||||
var/time_per_item = total_time / print_quantity
|
||||
start_making(design, print_quantity, time_per_item, coefficient, charge_per_item)
|
||||
|
||||
return TRUE
|
||||
|
||||
/// Begins the act of making the given design the given number of items
|
||||
/// Does not check or use materials/power/etc
|
||||
/obj/machinery/rnd/production/proc/start_making(datum/design/design, build_count, build_time_per_item, build_efficiency, charge_per_item)
|
||||
PROTECTED_PROC(TRUE)
|
||||
|
||||
busy = TRUE
|
||||
update_static_data_for_all_viewers()
|
||||
addtimer(CALLBACK(src, PROC_REF(do_make_item), design, build_efficiency, build_time_per_item, charge_per_item, build_count), build_time_per_item)
|
||||
|
||||
/// Callback for start_making, actually makes the item
|
||||
/// Called using timers started by start_making
|
||||
/obj/machinery/rnd/production/proc/do_make_item(datum/design/design, build_efficiency, time_per_item, charge_per_item, items_remaining)
|
||||
/**
|
||||
* Callback for start_making, actually makes the item
|
||||
* Arguments
|
||||
*
|
||||
* * datum/design/design - the design we are trying to print
|
||||
* * items_remaining - the number of designs left out to print
|
||||
* * build_time_per_item - the time taken to print 1 item
|
||||
* * material_cost_coefficient - the cost efficiency to print 1 design
|
||||
* * charge_per_item - the amount of power to print 1 item
|
||||
* * turf/target - the location to drop the printed item on
|
||||
*/
|
||||
/obj/machinery/rnd/production/proc/do_make_item(datum/design/design, items_remaining, build_time_per_item, material_cost_coefficient, charge_per_item, turf/target)
|
||||
PROTECTED_PROC(TRUE)
|
||||
|
||||
if(!items_remaining) // how
|
||||
finalize_build()
|
||||
return
|
||||
|
||||
if(!directly_use_power(charge_per_item))
|
||||
if(!is_operational || !directly_use_power(charge_per_item))
|
||||
say("Unable to continue production, power failure.")
|
||||
finalize_build()
|
||||
return
|
||||
if(!materials.can_use_resource())
|
||||
finalize_build()
|
||||
return
|
||||
|
||||
var/is_stack = ispath(design.build_path, /obj/item/stack)
|
||||
var/list/design_materials = design.materials
|
||||
if(!materials.mat_container.has_materials(design_materials, build_efficiency, is_stack ? items_remaining : 1))
|
||||
if(!materials.mat_container.has_materials(design_materials, material_cost_coefficient, is_stack ? items_remaining : 1))
|
||||
say("Unable to continue production, missing materials.")
|
||||
return
|
||||
materials.use_materials(design_materials, build_efficiency, is_stack ? items_remaining : 1, "built", "[design.name]")
|
||||
materials.use_materials(design_materials, material_cost_coefficient, is_stack ? items_remaining : 1, "built", "[design.name]")
|
||||
|
||||
var/atom/movable/created
|
||||
if(is_stack)
|
||||
created = new design.build_path(get_turf(src), items_remaining)
|
||||
created = new design.build_path(target, items_remaining)
|
||||
else
|
||||
created = new design.build_path(get_turf(src))
|
||||
split_materials_uniformly(design_materials, build_efficiency, created)
|
||||
created = new design.build_path(target)
|
||||
split_materials_uniformly(design_materials, material_cost_coefficient, created)
|
||||
|
||||
created.pixel_x = created.base_pixel_x + rand(-6, 6)
|
||||
created.pixel_y = created.base_pixel_y + rand(-6, 6)
|
||||
@@ -305,40 +400,36 @@
|
||||
if(!items_remaining)
|
||||
finalize_build()
|
||||
return
|
||||
addtimer(CALLBACK(src, PROC_REF(do_make_item), design, build_efficiency, time_per_item, items_remaining), time_per_item)
|
||||
addtimer(CALLBACK(src, PROC_REF(do_make_item), design, items_remaining, build_time_per_item, material_cost_coefficient, charge_per_item, target), build_time_per_item)
|
||||
|
||||
/// Resets the busy flag
|
||||
/// Called at the end of do_make_item's timer loop
|
||||
/obj/machinery/rnd/production/proc/finalize_build()
|
||||
PROTECTED_PROC(TRUE)
|
||||
|
||||
busy = FALSE
|
||||
update_static_data_for_all_viewers()
|
||||
SStgui.update_uis(src)
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
// Stuff for the stripe on the department machines
|
||||
/obj/machinery/rnd/production/default_deconstruction_screwdriver(mob/user, icon_state_open, icon_state_closed, obj/item/screwdriver)
|
||||
/obj/machinery/rnd/production/MouseDrop(atom/over, src_location, over_location, src_control, over_control, params)
|
||||
. = ..()
|
||||
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
|
||||
/obj/machinery/rnd/production/update_overlays()
|
||||
. = ..()
|
||||
|
||||
if(!stripe_color)
|
||||
if((!issilicon(usr) && !isAdminGhostAI(usr)) && !Adjacent(usr))
|
||||
return
|
||||
if(busy)
|
||||
balloon_alert(usr, "busy printing!")
|
||||
return
|
||||
var/direction = get_dir(src, over_location)
|
||||
if(!direction)
|
||||
return
|
||||
drop_direction = direction
|
||||
balloon_alert(usr, "dropping [dir2text(drop_direction)]")
|
||||
|
||||
var/mutable_appearance/stripe = mutable_appearance('icons/obj/machines/research.dmi', "protolate_stripe")
|
||||
|
||||
if(!panel_open)
|
||||
stripe.icon_state = "protolathe_stripe"
|
||||
else
|
||||
stripe.icon_state = "protolathe_stripe_t"
|
||||
|
||||
stripe.color = stripe_color
|
||||
|
||||
. += stripe
|
||||
|
||||
/obj/machinery/rnd/production/examine(mob/user)
|
||||
/obj/machinery/rnd/production/AltClick(mob/user)
|
||||
. = ..()
|
||||
|
||||
if(in_range(user, src) || isobserver(user))
|
||||
. += span_notice("The status display reads: Storing up to <b>[materials.local_size]</b> material units.<br>Material consumption at <b>[efficiency_coeff * 100]%</b>.<br>Build time reduced by <b>[100 - efficiency_coeff * 100]%</b>.")
|
||||
if(!drop_direction || !can_interact(user))
|
||||
return
|
||||
if(busy)
|
||||
balloon_alert(user, "busy printing!")
|
||||
return
|
||||
balloon_alert(user, "drop direction reset")
|
||||
drop_direction = 0
|
||||
|
||||
@@ -2,23 +2,22 @@
|
||||
name = "circuit imprinter"
|
||||
desc = "Manufactures circuit boards for the construction of machines."
|
||||
icon_state = "circuit_imprinter"
|
||||
circuit = /obj/item/circuitboard/machine/circuit_imprinter
|
||||
production_animation = "circuit_imprinter_ani"
|
||||
circuit = /obj/item/circuitboard/machine/circuit_imprinter
|
||||
allowed_buildtypes = IMPRINTER
|
||||
|
||||
/obj/machinery/rnd/production/circuit_imprinter/calculate_efficiency()
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/rnd/production/circuit_imprinter/compute_efficiency()
|
||||
var/rating = 0
|
||||
|
||||
for(var/datum/stock_part/servo/servo in component_parts)
|
||||
rating += servo.tier // There is only one.
|
||||
rating += servo.tier
|
||||
|
||||
efficiency_coeff = 0.5 ** max(rating - 1, 0) // One sheet, half sheet, quarter sheet, eighth sheet.
|
||||
return 0.5 ** max(rating - 1, 0) // One sheet, half sheet, quarter sheet, eighth sheet.
|
||||
|
||||
/obj/machinery/rnd/production/circuit_imprinter/flick_animation(mat_name)
|
||||
return //we presently have no animation
|
||||
|
||||
/obj/machinery/rnd/production/circuit_imprinter/offstation
|
||||
name = "ancient circuit imprinter"
|
||||
desc = "Manufactures circuit boards for the construction of machines. Its ancient construction may limit its ability to print all known technology."
|
||||
allowed_buildtypes = AWAY_IMPRINTER
|
||||
circuit = /obj/item/circuitboard/machine/circuit_imprinter/offstation
|
||||
charges_tax = FALSE
|
||||
|
||||
@@ -11,10 +11,6 @@
|
||||
stripe_color = "#EFB341"
|
||||
payment_department = ACCOUNT_ENG
|
||||
|
||||
/obj/machinery/rnd/production/protolathe/department/engineering/no_tax
|
||||
circuit = /obj/item/circuitboard/machine/protolathe/department/engineering/no_tax
|
||||
charges_tax = FALSE
|
||||
|
||||
/obj/machinery/rnd/production/protolathe/department/service
|
||||
name = "department protolathe (Service)"
|
||||
allowed_department_flags = DEPARTMENT_BITFLAG_SERVICE
|
||||
|
||||
@@ -23,4 +23,3 @@
|
||||
desc = "Converts raw materials into useful objects. Its ancient construction may limit its ability to print all known technology."
|
||||
circuit = /obj/item/circuitboard/machine/protolathe/offstation
|
||||
allowed_buildtypes = AWAY_LATHE
|
||||
charges_tax = FALSE
|
||||
|
||||
@@ -3,6 +3,5 @@
|
||||
desc = "Produces researched prototypes with raw materials and energy."
|
||||
icon_state = "protolathe"
|
||||
circuit = /obj/item/circuitboard/machine/techfab
|
||||
console_link = FALSE
|
||||
production_animation = "protolathe_n"
|
||||
allowed_buildtypes = PROTOLATHE | IMPRINTER
|
||||
|
||||
@@ -7,21 +7,22 @@
|
||||
icon = 'icons/obj/machines/research.dmi'
|
||||
density = TRUE
|
||||
use_power = IDLE_POWER_USE
|
||||
|
||||
///Are we currently printing a machine
|
||||
var/busy = FALSE
|
||||
///Is this machne hacked via wires
|
||||
var/hacked = FALSE
|
||||
var/console_link = TRUE //allow console link.
|
||||
///Is this machine disabled via wires
|
||||
var/disabled = FALSE
|
||||
/// Ref to global science techweb.
|
||||
///Ref to global science techweb.
|
||||
var/datum/techweb/stored_research
|
||||
///The item loaded inside the machine, used by experimentors and destructive analyzers only.
|
||||
var/obj/item/loaded_item
|
||||
|
||||
/obj/machinery/rnd/proc/reset_busy()
|
||||
busy = FALSE
|
||||
|
||||
/obj/machinery/rnd/Initialize(mapload)
|
||||
. = ..()
|
||||
set_wires(new /datum/wires/rnd(src))
|
||||
register_context()
|
||||
|
||||
/obj/machinery/rnd/LateInitialize()
|
||||
. = ..()
|
||||
@@ -37,6 +38,46 @@
|
||||
QDEL_NULL(wires)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/rnd/examine(mob/user)
|
||||
. = ..()
|
||||
if(!in_range(user, src) && !isobserver(user))
|
||||
return
|
||||
|
||||
. += span_notice("A [EXAMINE_HINT("multitool")] with techweb designs can be uploaded here.")
|
||||
. += span_notice("Its maintainence panel can be [EXAMINE_HINT("screwed")] [panel_open ? "closed" : "open"].")
|
||||
if(panel_open)
|
||||
. += span_notice("Use a [EXAMINE_HINT("multitool")] or [EXAMINE_HINT("wirecutters")] to interact with wires.")
|
||||
. += span_notice("The machine can be [EXAMINE_HINT("pried")] apart.")
|
||||
|
||||
/obj/machinery/rnd/add_context(atom/source, list/context, obj/item/held_item, mob/user)
|
||||
. = NONE
|
||||
if(isnull(held_item))
|
||||
return
|
||||
|
||||
if(held_item.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
context[SCREENTIP_CONTEXT_LMB] = "[panel_open ? "Close" : "Open"] Panel"
|
||||
context[SCREENTIP_CONTEXT_RMB] = "[panel_open ? "Close" : "Open"] Panel"
|
||||
return CONTEXTUAL_SCREENTIP_SET
|
||||
|
||||
if(panel_open)
|
||||
var/msg
|
||||
if(held_item.tool_behaviour == TOOL_CROWBAR)
|
||||
msg = "Deconstruct"
|
||||
else if(is_wire_tool(held_item))
|
||||
msg = "Open Wires"
|
||||
|
||||
if(msg)
|
||||
context[SCREENTIP_CONTEXT_LMB] = msg
|
||||
context[SCREENTIP_CONTEXT_RMB] = msg
|
||||
return CONTEXTUAL_SCREENTIP_SET
|
||||
else
|
||||
if(held_item.tool_behaviour == TOOL_MULTITOOL)
|
||||
var/obj/item/multitool/tool = held_item
|
||||
if(!QDELETED(tool.buffer) && istype(tool.buffer, /datum/techweb))
|
||||
context[SCREENTIP_CONTEXT_LMB] = "Upload Techweb"
|
||||
context[SCREENTIP_CONTEXT_RMB] = "Upload Techweb"
|
||||
return CONTEXTUAL_SCREENTIP_SET
|
||||
|
||||
///Called when attempting to connect the machine to a techweb, forgetting the old.
|
||||
/obj/machinery/rnd/proc/connect_techweb(datum/techweb/new_techweb)
|
||||
if(stored_research)
|
||||
@@ -49,52 +90,42 @@
|
||||
/obj/machinery/rnd/proc/on_connected_techweb()
|
||||
SHOULD_CALL_PARENT(FALSE)
|
||||
|
||||
/obj/machinery/rnd/proc/shock(mob/user, prb)
|
||||
if(machine_stat & (BROKEN|NOPOWER)) // unpowered, no shock
|
||||
return FALSE
|
||||
if(!prob(prb))
|
||||
return FALSE
|
||||
do_sparks(5, TRUE, src)
|
||||
if (electrocute_mob(user, get_area(src), src, 0.7, TRUE))
|
||||
return TRUE
|
||||
else
|
||||
return FALSE
|
||||
///Reset the state of this machine
|
||||
/obj/machinery/rnd/proc/reset_busy()
|
||||
busy = FALSE
|
||||
|
||||
/obj/machinery/rnd/crowbar_act(mob/living/user, obj/item/tool)
|
||||
return default_deconstruction_crowbar(tool)
|
||||
|
||||
/obj/machinery/rnd/crowbar_act_secondary(mob/living/user, obj/item/tool)
|
||||
return default_deconstruction_crowbar(tool)
|
||||
return crowbar_act(user, tool)
|
||||
|
||||
/obj/machinery/rnd/screwdriver_act(mob/living/user, obj/item/tool)
|
||||
return default_deconstruction_screwdriver(user, "[initial(icon_state)]_t", initial(icon_state), tool)
|
||||
|
||||
/obj/machinery/rnd/screwdriver_act_secondary(mob/living/user, obj/item/tool)
|
||||
return default_deconstruction_screwdriver(user, "[initial(icon_state)]_t", initial(icon_state), tool)
|
||||
return screwdriver_act(user, tool)
|
||||
|
||||
/obj/machinery/rnd/multitool_act(mob/living/user, obj/item/multitool/tool)
|
||||
. = ITEM_INTERACT_BLOCKING
|
||||
if(panel_open)
|
||||
wires.interact(user)
|
||||
return TRUE
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
if(!QDELETED(tool.buffer) && istype(tool.buffer, /datum/techweb))
|
||||
connect_techweb(tool.buffer)
|
||||
return TRUE
|
||||
return FALSE
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
/obj/machinery/rnd/multitool_act_secondary(mob/living/user, obj/item/tool)
|
||||
if(panel_open)
|
||||
wires.interact(user)
|
||||
return TRUE
|
||||
return multitool_act(user, tool)
|
||||
|
||||
/obj/machinery/rnd/wirecutter_act(mob/living/user, obj/item/tool)
|
||||
. = ITEM_INTERACT_BLOCKING
|
||||
if(panel_open)
|
||||
wires.interact(user)
|
||||
return TRUE
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
/obj/machinery/rnd/wirecutter_act_secondary(mob/living/user, obj/item/tool)
|
||||
if(panel_open)
|
||||
wires.interact(user)
|
||||
return TRUE
|
||||
return wirecutter_act(user, tool)
|
||||
|
||||
//whether the machine can have an item inserted in its current state.
|
||||
/obj/machinery/rnd/proc/is_insertion_ready(mob/user)
|
||||
@@ -123,15 +154,3 @@
|
||||
if(loaded_item)
|
||||
loaded_item.forceMove(drop_location())
|
||||
..()
|
||||
|
||||
/obj/machinery/rnd/proc/AfterMaterialInsert(item_inserted, id_inserted, amount_inserted)
|
||||
var/stack_name
|
||||
if(istype(item_inserted, /obj/item/stack/ore/bluespace_crystal))
|
||||
stack_name = "bluespace"
|
||||
use_power(SHEET_MATERIAL_AMOUNT / 10)
|
||||
else
|
||||
var/obj/item/stack/S = item_inserted
|
||||
stack_name = S.name
|
||||
use_power(min(active_power_usage, (amount_inserted / 100)))
|
||||
add_overlay("protolathe_[stack_name]")
|
||||
addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, cut_overlay), "protolathe_[stack_name]"), 10)
|
||||
|
||||
@@ -184,8 +184,7 @@
|
||||
"cost" = cost,
|
||||
"id" = researched_design_id,
|
||||
"categories" = design.category,
|
||||
"icon" = "[icon_size == size32x32 ? "" : "[icon_size] "][design.id]",
|
||||
"constructionTime" = -1
|
||||
"icon" = "[icon_size == size32x32 ? "" : "[icon_size] "][design.id]"
|
||||
)
|
||||
|
||||
data["designs"] = designs
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 28 KiB |
-5
@@ -1,5 +0,0 @@
|
||||
/obj/item/circuitboard/machine/circuit_imprinter/department/no_tax
|
||||
build_path = /obj/machinery/rnd/production/circuit_imprinter/department/no_tax
|
||||
|
||||
/obj/machinery/rnd/production/circuit_imprinter/department/no_tax
|
||||
charges_tax = FALSE
|
||||
@@ -12,7 +12,6 @@
|
||||
obj_flags = CAN_BE_HIT | NO_DECONSTRUCTION
|
||||
light_color = LIGHT_COLOR_BRIGHT_YELLOW
|
||||
light_power = 5
|
||||
charges_tax = FALSE
|
||||
allowed_buildtypes = COLONY_FABRICATOR
|
||||
/// The item we turn into when repacked
|
||||
var/repacked_type = /obj/item/flatpacked_machine
|
||||
@@ -33,16 +32,13 @@
|
||||
QDEL_NULL(soundloop)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/rnd/production/colony_lathe/user_try_print_id(design_id, print_quantity)
|
||||
/obj/machinery/rnd/production/colony_lathe/ui_act(action, list/params, datum/tgui/ui)
|
||||
. = ..()
|
||||
|
||||
if(!.)
|
||||
return
|
||||
|
||||
soundloop.start()
|
||||
set_light(l_range = 1.5)
|
||||
icon_state = "colony_lathe_working"
|
||||
update_appearance()
|
||||
if (. && action == "build")
|
||||
soundloop.start()
|
||||
set_light(l_range = 1.5)
|
||||
icon_state = "colony_lathe_working"
|
||||
update_appearance()
|
||||
|
||||
/obj/machinery/rnd/production/colony_lathe/finalize_build()
|
||||
. = ..()
|
||||
@@ -52,9 +48,6 @@
|
||||
update_appearance()
|
||||
flick("colony_lathe_finish_print", src)
|
||||
|
||||
/obj/machinery/rnd/production/colony_lathe/calculate_efficiency()
|
||||
efficiency_coeff = 1
|
||||
|
||||
// We take from all nodes even unresearched ones
|
||||
/obj/machinery/rnd/production/colony_lathe/update_designs()
|
||||
var/previous_design_count = cached_designs.len
|
||||
|
||||
@@ -88,15 +88,21 @@
|
||||
req_access = list(ACCESS_AWAY_SCIENCE)
|
||||
|
||||
/obj/machinery/rnd/server/tarkon/Initialize(mapload)
|
||||
register_context()
|
||||
var/datum/techweb/tarkon_techweb = locate(/datum/techweb/tarkon) in SSresearch.techwebs
|
||||
stored_research = tarkon_techweb
|
||||
return ..()
|
||||
|
||||
/obj/machinery/rnd/server/tarkon/add_context(atom/source, list/context, obj/item/held_item, mob/user)
|
||||
. = ..()
|
||||
if(held_item && istype(held_item, /obj/item/research_notes))
|
||||
context[SCREENTIP_CONTEXT_LMB] = "Generate research points"
|
||||
return CONTEXTUAL_SCREENTIP_SET
|
||||
return CONTEXTUAL_SCREENTIP_SET
|
||||
|
||||
/obj/machinery/rnd/server/tarkon/examine(mob/user)
|
||||
. = ..()
|
||||
if(!in_range(user, src) && !isobserver(user))
|
||||
return
|
||||
. += span_notice("Insert [EXAMINE_HINT("Research Notes")] to generate points.")
|
||||
|
||||
/obj/machinery/rnd/server/tarkon/attackby(obj/item/attacking_item, mob/user, params)
|
||||
if(istype(attacking_item, /obj/item/research_notes) && stored_research)
|
||||
@@ -112,8 +118,6 @@
|
||||
desc = "Converts raw materials into useful objects. Refurbished and updated from its previous, limited capabilities."
|
||||
circuit = /obj/item/circuitboard/machine/protolathe/tarkon
|
||||
stripe_color = "#350f04"
|
||||
charges_tax = FALSE
|
||||
|
||||
/obj/item/circuitboard/machine/protolathe/tarkon
|
||||
name = "Tarkon Industries Protolathe"
|
||||
greyscale_colors = CIRCUIT_COLOR_SUPPLY
|
||||
|
||||
@@ -6506,7 +6506,6 @@
|
||||
#include "modular_skyrat\master_files\code\modules\research\designs\medical_designs.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\research\designs\misc_designs.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\research\designs\tool_designs.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\research\machinery\departmental_circuit_imprinter.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\research\techweb\all_nodes.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\shuttle\shuttle.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\shuttle\shuttle_events\meteors.dm"
|
||||
|
||||
@@ -19,12 +19,16 @@ import { MaterialCostSequence } from './Fabrication/MaterialCostSequence';
|
||||
import { Design, MaterialMap } from './Fabrication/Types';
|
||||
import { Material } from './Fabrication/Types';
|
||||
|
||||
type AutolatheDesign = Design & {
|
||||
customMaterials: BooleanLike;
|
||||
};
|
||||
|
||||
type AutolatheData = {
|
||||
materials: Material[];
|
||||
materialtotal: number;
|
||||
materialsmax: number;
|
||||
SHEET_MATERIAL_AMOUNT: number;
|
||||
designs: Design[];
|
||||
designs: AutolatheDesign[];
|
||||
active: BooleanLike;
|
||||
};
|
||||
|
||||
@@ -174,7 +178,7 @@ const PrintButton = (props: PrintButtonProps) => {
|
||||
};
|
||||
|
||||
type AutolatheRecipeProps = {
|
||||
design: Design;
|
||||
design: AutolatheDesign;
|
||||
availableMaterials: MaterialMap;
|
||||
SHEET_MATERIAL_AMOUNT: number;
|
||||
};
|
||||
@@ -183,7 +187,38 @@ const AutolatheRecipe = (props: AutolatheRecipeProps) => {
|
||||
const { act } = useBackend<AutolatheData>();
|
||||
const { design, availableMaterials, SHEET_MATERIAL_AMOUNT } = props;
|
||||
|
||||
const maxmult = design.maxmult;
|
||||
let maxmult = 0;
|
||||
if (design.customMaterials) {
|
||||
const smallest_mat =
|
||||
Object.entries(availableMaterials).reduce(
|
||||
(accumulator: number, [material, amount]) => {
|
||||
return Math.min(accumulator, amount);
|
||||
},
|
||||
Infinity,
|
||||
) || 0;
|
||||
|
||||
if (smallest_mat > 0) {
|
||||
maxmult = Object.entries(design.cost).reduce(
|
||||
(accumulator: number, [material, required]) => {
|
||||
return Math.min(accumulator, smallest_mat / required);
|
||||
},
|
||||
Infinity,
|
||||
);
|
||||
} else {
|
||||
maxmult = 0;
|
||||
}
|
||||
} else {
|
||||
maxmult = Object.entries(design.cost).reduce(
|
||||
(accumulator: number, [material, required]) => {
|
||||
return Math.min(
|
||||
accumulator,
|
||||
(availableMaterials[material] || 0) / required,
|
||||
);
|
||||
},
|
||||
Infinity,
|
||||
);
|
||||
}
|
||||
maxmult = Math.min(Math.floor(maxmult), 50);
|
||||
const canPrint = maxmult > 0;
|
||||
|
||||
return (
|
||||
|
||||
@@ -9,8 +9,13 @@ import { MaterialAccessBar } from './Fabrication/MaterialAccessBar';
|
||||
import { MaterialCostSequence } from './Fabrication/MaterialCostSequence';
|
||||
import { Design, FabricatorData, MaterialMap } from './Fabrication/Types';
|
||||
|
||||
type ExosuitDesign = Design & {
|
||||
constructionTime: number;
|
||||
};
|
||||
|
||||
type ExosuitFabricatorData = FabricatorData & {
|
||||
processing: BooleanLike;
|
||||
designs: Record<string, ExosuitDesign>;
|
||||
};
|
||||
|
||||
export const ExosuitFabricator = (props) => {
|
||||
|
||||
@@ -68,16 +68,6 @@ export type Design = {
|
||||
* 32x32.**
|
||||
*/
|
||||
icon: string;
|
||||
|
||||
/**
|
||||
* The amount of time, in seconds, that this design takes to print.
|
||||
*/
|
||||
constructionTime: number;
|
||||
|
||||
/**
|
||||
* The maximum number of items than can be printed
|
||||
*/
|
||||
maxmult: number;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -116,10 +116,14 @@ type CustomPrintProps = {
|
||||
const CustomPrint = (props: CustomPrintProps) => {
|
||||
const { act } = useBackend();
|
||||
const { design, available } = props;
|
||||
const canPrint = !Object.entries(design.cost).some(
|
||||
([material, amount]) =>
|
||||
!available[material] || amount > (available[material] ?? 0),
|
||||
let maxMult = Object.entries(design.cost).reduce(
|
||||
(accumulator: number, [material, required]) => {
|
||||
return Math.min(accumulator, (available[material] || 0) / required);
|
||||
},
|
||||
Infinity,
|
||||
);
|
||||
maxMult = Math.min(Math.floor(maxMult), 50);
|
||||
const canPrint = maxMult > 0;
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -137,7 +141,7 @@ const CustomPrint = (props: CustomPrintProps) => {
|
||||
})
|
||||
}
|
||||
>
|
||||
[Max: {design.maxmult}]
|
||||
[Max: {maxMult}]
|
||||
</Button.Input>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user