mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-07-21 04:48:18 +01:00
Refactored the mecha fabricator (#19264)
Refactored the mecha fabricator to use a queue system instead of processing. Typed a GLOB list for robolimbs. Build time is now correct.
This commit is contained in:
@@ -8,22 +8,6 @@
|
||||
idle_power_usage = 20
|
||||
active_power_usage = 5000
|
||||
req_access = list(ACCESS_ROBOTICS)
|
||||
|
||||
var/speed = 1
|
||||
var/mat_efficiency = 1
|
||||
var/list/materials = list(DEFAULT_WALL_MATERIAL = 0, MATERIAL_GLASS = 0, MATERIAL_GOLD = 0, MATERIAL_SILVER = 0, MATERIAL_DIAMOND = 0, MATERIAL_PHORON = 0, MATERIAL_URANIUM = 0)
|
||||
var/res_max_amount = 200000
|
||||
|
||||
var/datum/research/files
|
||||
var/list/datum/design/queue = list()
|
||||
var/progress = 0
|
||||
var/busy = 0
|
||||
|
||||
var/list/categories = list()
|
||||
var/category = null
|
||||
var/sync_message = ""
|
||||
var/limb_manufacturer
|
||||
|
||||
component_types = list(
|
||||
/obj/item/circuitboard/mechfab,
|
||||
/obj/item/stock_parts/matter_bin = 2,
|
||||
@@ -32,6 +16,34 @@
|
||||
/obj/item/stock_parts/console_screen
|
||||
)
|
||||
|
||||
/**
|
||||
* A `/list` of enqueued `/datum/design` to be printed, processed in the queue
|
||||
*/
|
||||
var/list/datum/design/queue = list()
|
||||
|
||||
/**
|
||||
* How much efficient (or inefficient) the protolathe is at manufacturing things
|
||||
*/
|
||||
var/mat_efficiency = 1
|
||||
|
||||
/**
|
||||
* The production speed of this specific protolathe, a factor
|
||||
*/
|
||||
var/production_speed = 1
|
||||
|
||||
var/list/materials = list(DEFAULT_WALL_MATERIAL = 0, MATERIAL_GLASS = 0, MATERIAL_GOLD = 0, MATERIAL_SILVER = 0, MATERIAL_DIAMOND = 0, MATERIAL_PHORON = 0, MATERIAL_URANIUM = 0)
|
||||
var/res_max_amount = 200000
|
||||
|
||||
var/datum/research/files
|
||||
|
||||
var/list/categories = list()
|
||||
var/category = null
|
||||
var/sync_message = ""
|
||||
var/limb_manufacturer
|
||||
|
||||
///The timer id for the build callback, if we're building something
|
||||
var/build_callback_timer
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/Initialize()
|
||||
. = ..()
|
||||
|
||||
@@ -39,22 +51,10 @@
|
||||
limb_manufacturer = GLOB.basic_robolimb.company
|
||||
update_categories()
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/process()
|
||||
..()
|
||||
if(stat)
|
||||
return
|
||||
if(busy)
|
||||
update_use_power(POWER_USE_ACTIVE)
|
||||
progress += speed
|
||||
check_build()
|
||||
else
|
||||
update_use_power(POWER_USE_IDLE)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/update_icon()
|
||||
ClearOverlays()
|
||||
icon_state = "fab-base"
|
||||
if(busy)
|
||||
if(build_callback_timer)
|
||||
AddOverlays("fab-active")
|
||||
if(panel_open)
|
||||
AddOverlays("fab-panel")
|
||||
@@ -77,7 +77,7 @@
|
||||
|
||||
for(var/obj/item/stock_parts/micro_laser/M in component_parts) // Not resetting T is intended; speed is affected by both
|
||||
T += M.rating
|
||||
speed = T / 2 // 1 -> 3
|
||||
production_speed = T / 2 // 1 -> 3
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/attack_hand(var/mob/user)
|
||||
if(..())
|
||||
@@ -98,6 +98,7 @@
|
||||
data["buildable"] = get_build_options()
|
||||
data["category"] = category
|
||||
data["categories"] = categories
|
||||
|
||||
if(GLOB.fabricator_robolimbs)
|
||||
var/list/T = list()
|
||||
for(var/A in GLOB.fabricator_robolimbs)
|
||||
@@ -105,11 +106,18 @@
|
||||
T += list(list("id" = A, "company" = R.company))
|
||||
data["manufacturers"] = T
|
||||
data["manufacturer"] = limb_manufacturer
|
||||
|
||||
data["materials"] = get_materials()
|
||||
data["maxres"] = res_max_amount
|
||||
data["sync"] = sync_message
|
||||
|
||||
//If we have something in the queue that we're trying to build, show the time left if the build is undergoing, otherwise null
|
||||
//the logic of displaying it is handled client-side
|
||||
if(current)
|
||||
data["builtperc"] = round((progress / current.time) * 100)
|
||||
if(build_callback_timer)
|
||||
data["timeleft"] = round(timeleft(build_callback_timer))
|
||||
else
|
||||
data["timeleft"] = null
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if(!ui)
|
||||
@@ -148,7 +156,7 @@
|
||||
return 1
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/attackby(obj/item/attacking_item, mob/user)
|
||||
if(busy)
|
||||
if(build_callback_timer)
|
||||
to_chat(user, SPAN_NOTICE("\The [src] is busy. Please wait for completion of previous operation."))
|
||||
return TRUE
|
||||
if(default_deconstruction_screwdriver(user, attacking_item))
|
||||
@@ -182,7 +190,7 @@
|
||||
M.use(1)
|
||||
count++
|
||||
to_chat(user, SPAN_NOTICE("You insert [count] [sname] into \the [src]."))
|
||||
update_busy()
|
||||
|
||||
else
|
||||
to_chat(user, SPAN_NOTICE("\The [src] cannot hold more [sname]."))
|
||||
return TRUE
|
||||
@@ -250,27 +258,70 @@
|
||||
if(1)
|
||||
visible_message("[icon2html(src, viewers(get_turf(src)))] <b>[src]</b> beeps: \"No records in User DB\"")
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/update_busy()
|
||||
if(queue.len)
|
||||
if(can_build(queue[1]))
|
||||
busy = 1
|
||||
else
|
||||
busy = 0
|
||||
else
|
||||
busy = 0
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/add_to_queue(var/path)
|
||||
/**
|
||||
* Adds a design to the queue
|
||||
*
|
||||
* * path: The path of the design to add
|
||||
*/
|
||||
/obj/machinery/mecha_part_fabricator/proc/add_to_queue(path)
|
||||
var/datum/design/D = files.known_designs[path]
|
||||
if(!D)
|
||||
return
|
||||
queue += D
|
||||
update_busy()
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/remove_from_queue(var/index)
|
||||
if(index == 1)
|
||||
progress = 0
|
||||
//Wake up, we have things to do
|
||||
handle_queue()
|
||||
|
||||
/**
|
||||
* Removes a design from the queue
|
||||
*
|
||||
* * index: The index of the design to remove
|
||||
*/
|
||||
/obj/machinery/mecha_part_fabricator/proc/remove_from_queue(index)
|
||||
queue.Cut(index, index + 1)
|
||||
update_busy()
|
||||
|
||||
//If we're removing the first thing in the queue, stop the build timer
|
||||
if(index == 1)
|
||||
deltimer(build_callback_timer)
|
||||
build_callback_timer = null
|
||||
|
||||
//Wake up, we have things to do
|
||||
handle_queue()
|
||||
|
||||
/**
|
||||
* Handle the construction queue
|
||||
*/
|
||||
/obj/machinery/mecha_part_fabricator/proc/handle_queue()
|
||||
|
||||
//No work to do or already busy, stop
|
||||
if(!length(queue) || build_callback_timer)
|
||||
//If we don't have a build in progress, revert to idle power usage
|
||||
if(!build_callback_timer)
|
||||
update_use_power(POWER_USE_IDLE)
|
||||
|
||||
update_icon()
|
||||
return
|
||||
|
||||
//If there's no power, there's no building
|
||||
if(stat & NOPOWER)
|
||||
queue = list()
|
||||
return
|
||||
|
||||
//Get the first design in the queue
|
||||
var/datum/design/D = queue[1]
|
||||
|
||||
//If we can build it, process the request
|
||||
if(can_build(D))
|
||||
update_use_power(POWER_USE_ACTIVE)
|
||||
|
||||
//Add the callback timer for printing, and remove the design from the queue
|
||||
build_callback_timer = addtimer(CALLBACK(src, PROC_REF(build), D), (D.time / production_speed), TIMER_UNIQUE|TIMER_STOPPABLE)
|
||||
//No queue removal here because we show how long it takes to build in the UI
|
||||
|
||||
else
|
||||
visible_message(SPAN_NOTICE("[icon2html(src, viewers(get_turf(src)))] \The [src] flashes: Insufficient materials to complete build: [D.name]."))
|
||||
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/can_build(var/datum/design/D)
|
||||
for(var/M in D.materials)
|
||||
@@ -278,31 +329,34 @@
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/check_build()
|
||||
if(!queue.len)
|
||||
progress = 0
|
||||
return
|
||||
var/datum/design/D = queue[1]
|
||||
if(!can_build(D))
|
||||
progress = 0
|
||||
return
|
||||
if(D.time > progress)
|
||||
return
|
||||
for(var/M in D.materials)
|
||||
materials[M] = max(0, materials[M] - D.materials[M] * mat_efficiency)
|
||||
/**
|
||||
* Builds the given design, assuming all the necessary conditions are met
|
||||
*
|
||||
* * design_to_build: The design to build
|
||||
*/
|
||||
/obj/machinery/mecha_part_fabricator/proc/build(datum/design/design_to_build)
|
||||
//Consume the materials
|
||||
for(var/M in design_to_build.materials)
|
||||
materials[M] = max(0, materials[M] - design_to_build.materials[M] * mat_efficiency)
|
||||
|
||||
intent_message(MACHINE_SOUND)
|
||||
|
||||
if(D.build_path)
|
||||
if(design_to_build.build_path)
|
||||
var/loc_offset = get_step(src, dir)
|
||||
var/obj/new_item = D.Fabricate(loc_offset, src)
|
||||
var/obj/new_item = design_to_build.Fabricate(loc_offset, src)
|
||||
visible_message("\The <b>[src]</b> pings, indicating that \the [new_item] is complete.", "You hear a ping.", intent_message = PING_SOUND)
|
||||
if(mat_efficiency != 1)
|
||||
if(new_item.matter && new_item.matter.len > 0)
|
||||
for(var/i in new_item.matter)
|
||||
new_item.matter[i] = new_item.matter[i] * mat_efficiency
|
||||
|
||||
//We finished building, clear the timer and remove the thing from the queue
|
||||
build_callback_timer = null
|
||||
remove_from_queue(1)
|
||||
|
||||
//Do the queue handling for the next item, or to stop
|
||||
handle_queue()
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/get_queue_names()
|
||||
. = list()
|
||||
for(var/i = 2 to queue.len)
|
||||
@@ -324,7 +378,7 @@
|
||||
return english_list(F, and_text = ", ")
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/get_design_time(var/datum/design/D)
|
||||
return time2text(round(10 * D.time / speed), "mm:ss")
|
||||
return time2text(round(10 * D.time / production_speed), "mm:ss")
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/update_categories()
|
||||
categories = list()
|
||||
@@ -358,7 +412,6 @@
|
||||
materials[material] -= ejected * S.perunit
|
||||
if(recursive && materials[material] >= S.perunit)
|
||||
eject_materials(material, -1)
|
||||
update_busy()
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/sync()
|
||||
sync_message = "Error: no console found."
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
GLOBAL_LIST_EMPTY(all_robolimbs)
|
||||
GLOBAL_LIST_EMPTY(internal_robolimbs)
|
||||
GLOBAL_LIST_EMPTY(chargen_robolimbs)
|
||||
GLOBAL_LIST_EMPTY(fabricator_robolimbs)
|
||||
GLOBAL_LIST_EMPTY_TYPED(fabricator_robolimbs, /datum/robolimb)
|
||||
GLOBAL_DATUM(basic_robolimb, /datum/robolimb)
|
||||
|
||||
/proc/populate_robolimb_list()
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
################################
|
||||
# Example Changelog File
|
||||
#
|
||||
# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
|
||||
#
|
||||
# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
|
||||
# When it is, any changes listed below will disappear.
|
||||
#
|
||||
# Valid Prefixes:
|
||||
# bugfix
|
||||
# - (fixes bugs)
|
||||
# wip
|
||||
# - (work in progress)
|
||||
# qol
|
||||
# - (quality of life)
|
||||
# soundadd
|
||||
# - (adds a sound)
|
||||
# sounddel
|
||||
# - (removes a sound)
|
||||
# rscadd
|
||||
# - (adds a feature)
|
||||
# rscdel
|
||||
# - (removes a feature)
|
||||
# imageadd
|
||||
# - (adds an image or sprite)
|
||||
# imagedel
|
||||
# - (removes an image or sprite)
|
||||
# spellcheck
|
||||
# - (fixes spelling or grammar)
|
||||
# experiment
|
||||
# - (experimental change)
|
||||
# balance
|
||||
# - (balance changes)
|
||||
# code_imp
|
||||
# - (misc internal code change)
|
||||
# refactor
|
||||
# - (refactors code)
|
||||
# config
|
||||
# - (makes a change to the config files)
|
||||
# admin
|
||||
# - (makes changes to administrator tools)
|
||||
# server
|
||||
# - (miscellaneous changes to server)
|
||||
#################################
|
||||
|
||||
# Your name.
|
||||
author: FluffyGhost
|
||||
|
||||
# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
|
||||
delete-after: True
|
||||
|
||||
# Any changes you've made. See valid prefix list above.
|
||||
# INDENT WITH TWO SPACES. NOT TABS. SPACES.
|
||||
# SCREW THIS UP AND IT WON'T WORK.
|
||||
# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit.
|
||||
# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog.
|
||||
changes:
|
||||
- refactor: "Refactored the mecha fabricator to use a queue system instead of processing."
|
||||
- refactor: "Typed a GLOB list for robolimbs."
|
||||
- bugfix: "Build time is now correct."
|
||||
@@ -41,7 +41,11 @@
|
||||
{{if data.current}}
|
||||
<div class="item">
|
||||
<div class="itemLabelWide">
|
||||
<b>Now: {{:data.current}}</b> ({{:data.builtperc}}% ready)
|
||||
{{if data.timeleft}}
|
||||
<b>Time left: {{:data.current}}</b> ({{:data.timeleft / 10}} seconds)
|
||||
{{else}}
|
||||
<b>{{:data.current}} (Awaiting to start)</b>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="itemContentMedium">
|
||||
{{:helper.link('Cancel', null, {'remove' : 1})}}
|
||||
|
||||
Reference in New Issue
Block a user