#define AUTOLATHE_MAIN_MENU 1
#define AUTOLATHE_CATEGORY_MENU 2
#define AUTOLATHE_SEARCH_MENU 3
/obj/machinery/autolathe
name = "autolathe"
desc = "It produces items using metal and glass."
icon_state = "autolathe"
density = TRUE
use_power = IDLE_POWER_USE
idle_power_usage = 10
active_power_usage = 100
circuit = /obj/item/circuitboard/machine/autolathe
layer = BELOW_OBJ_LAYER
var/operating = FALSE
var/list/L = list()
var/list/LL = list()
var/hacked = FALSE
var/disabled = FALSE
var/shocked = FALSE
var/hack_wire
var/disable_wire
var/shock_wire
var/busy = FALSE
var/prod_coeff = 1
var/datum/design/being_built
var/datum/techweb/stored_research
var/list/datum/design/matching_designs
var/selected_category
var/screen = 1
var/base_price = 25
var/hacked_price = 50
var/list/categories = list(
"Tools",
"Electronics",
"Construction",
"T-Comm",
"Security",
"Machinery",
"Medical",
"Misc",
"Dinnerware",
"Imported"
)
/obj/machinery/autolathe/Initialize()
. = ..()
wires = new /datum/wires/autolathe(src)
stored_research = new /datum/techweb/specialized/autounlocking/autolathe
matching_designs = list()
/obj/machinery/autolathe/ComponentInitialize()
AddComponent(/datum/component/material_container, SSmaterials.materialtypes_by_category[MAT_CATEGORY_RIGID], 0, TRUE, null, null, CALLBACK(src, .proc/AfterMaterialInsert))
/obj/machinery/autolathe/Destroy()
QDEL_NULL(wires)
return ..()
/obj/machinery/autolathe/ui_interact(mob/user)
. = ..()
if(!is_operational())
return
if(shocked && !(stat & NOPOWER))
shock(user,50)
var/dat
switch(screen)
if(AUTOLATHE_MAIN_MENU)
dat = main_win(user)
if(AUTOLATHE_CATEGORY_MENU)
dat = category_win(user,selected_category)
if(AUTOLATHE_SEARCH_MENU)
dat = search_win(user)
var/datum/browser/popup = new(user, "autolathe", name, 400, 500)
popup.set_content(dat)
popup.open()
/obj/machinery/autolathe/on_deconstruction()
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
materials.retrieve_all()
/obj/machinery/autolathe/attackby(obj/item/O, mob/user, params)
if (busy)
to_chat(user, "The autolathe is busy. Please wait for completion of previous operation.")
return TRUE
if(default_deconstruction_screwdriver(user, "autolathe_t", "autolathe", O))
updateUsrDialog()
return TRUE
if(default_deconstruction_crowbar(O))
return TRUE
if(panel_open && is_wire_tool(O))
wires.interact(user)
return TRUE
if(user.a_intent == INTENT_HARM) //so we can hit the machine
return ..()
if(stat)
return TRUE
if(istype(O, /obj/item/disk/design_disk))
user.visible_message("[user] begins to load \the [O] in \the [src]...",
"You begin to load a design from \the [O]...",
"You hear the chatter of a floppy drive.")
busy = TRUE
var/obj/item/disk/design_disk/D = O
if(do_after(user, 14.4, target = src))
for(var/B in D.blueprints)
if(B)
stored_research.add_design(B)
busy = FALSE
return TRUE
return ..()
/obj/machinery/autolathe/proc/AfterMaterialInsert(item_inserted, id_inserted, amount_inserted)
if(istype(item_inserted, /obj/item/stack/ore/bluespace_crystal))
use_power(MINERAL_MATERIAL_AMOUNT / 10)
else if(custom_materials && custom_materials.len && custom_materials[SSmaterials.GetMaterialRef(/datum/material/glass)])
flick("autolathe_r",src)//plays glass insertion animation by default otherwise
else
flick("autolathe_o",src)//plays metal insertion animation
use_power(min(1000, amount_inserted / 100))
updateUsrDialog()
/obj/machinery/autolathe/Topic(href, href_list)
if(..())
return
if (!busy)
if(href_list["menu"])
screen = text2num(href_list["menu"])
updateUsrDialog()
if(href_list["category"])
selected_category = href_list["category"]
updateUsrDialog()
if(href_list["make"])
/////////////////
//href protection
being_built = stored_research.isDesignResearchedID(href_list["make"])
if(!being_built)
return
var/multiplier = text2num(href_list["multiplier"])
var/is_stack = ispath(being_built.build_path, /obj/item/stack)
multiplier = clamp(multiplier,1,50)
/////////////////
var/coeff = (is_stack ? 1 : prod_coeff) //stacks are unaffected by production coefficient
var/total_amount = 0
for(var/MAT in being_built.materials)
total_amount += being_built.materials[MAT]
var/power = max(2000, (total_amount)*multiplier/5) //Change this to use all materials
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
var/list/materials_used = list()
var/list/custom_materials = list() //These will apply their material effect, This should usually only be one.
for(var/MAT in being_built.materials)
var/datum/material/used_material = MAT
var/amount_needed = being_built.materials[MAT] * coeff * multiplier
if(istext(used_material)) //This means its a category
var/list/list_to_show = list()
for(var/i in SSmaterials.materials_by_category[used_material])
if(materials.materials[i] > 0)
list_to_show += i
used_material = input("Choose [used_material]", "Custom Material") as null|anything in sortList(list_to_show, /proc/cmp_typepaths_asc)
if(!used_material)
return //Didn't pick any material, so you can't build shit either.
custom_materials[used_material] += amount_needed
materials_used[used_material] = amount_needed
if(materials.has_materials(materials_used))
busy = TRUE
use_power(power)
icon_state = "autolathe_n"
var/time = is_stack ? 32 : (32 * coeff * multiplier) ** 0.8
addtimer(CALLBACK(src, .proc/make_item, power, materials_used, custom_materials, multiplier, coeff, is_stack, usr), time)
else
to_chat(usr, "Not enough materials for this operation.")
if(href_list["search"])
matching_designs.Cut()
for(var/v in stored_research.researched_designs)
var/datum/design/D = SSresearch.techweb_design_by_id(v)
if(findtext(D.name,href_list["to_search"]))
matching_designs.Add(D)
updateUsrDialog()
else
to_chat(usr, "The autolathe is busy. Please wait for completion of previous operation.")
updateUsrDialog()
return
/obj/machinery/autolathe/proc/make_item(power, list/materials_used, list/picked_materials, multiplier, coeff, is_stack, mob/user)
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
var/atom/A = drop_location()
use_power(power)
materials.use_materials(materials_used)
if(is_stack)
var/obj/item/stack/N = new being_built.build_path(A, multiplier)
N.update_icon()
N.autolathe_crafted(src)
else
for(var/i=1, i<=multiplier, i++)
var/obj/item/new_item = new being_built.build_path(A)
new_item.autolathe_crafted(src)
if(length(picked_materials))
new_item.set_custom_materials(picked_materials, 1 / multiplier) //Ensure we get the non multiplied amount
for(var/x in picked_materials)
var/datum/material/M = x
if(!istype(M, /datum/material/glass) && !istype(M, /datum/material/iron))
user.client.give_award(/datum/award/achievement/misc/getting_an_upgrade, user)
icon_state = "autolathe"
busy = FALSE
updateDialog()
/obj/machinery/autolathe/RefreshParts()
var/T = 0
for(var/obj/item/stock_parts/matter_bin/MB in component_parts)
T += MB.rating*75000
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
materials.max_amount = T
T=1.2
for(var/obj/item/stock_parts/manipulator/M in component_parts)
T -= M.rating*0.2
prod_coeff = min(1,max(0,T)) // Coeff going 1 -> 0,8 -> 0,6 -> 0,4
/obj/machinery/autolathe/examine(mob/user)
. += ..()
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
if(in_range(user, src) || isobserver(user))
. += "The status display reads: Storing up to [materials.max_amount] material units.
Material consumption at [prod_coeff*100]%."
/obj/machinery/autolathe/proc/main_win(mob/user)
var/dat = "
| [C] | " line_length++ dat += "