mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 10:12:45 +00:00
Conflicts: code/game/machinery/computer3/buildandrepair.dm code/game/objects/items/devices/lightreplacer.dm code/modules/research/circuitprinter.dm code/modules/research/protolathe.dm
303 lines
9.7 KiB
Plaintext
303 lines
9.7 KiB
Plaintext
/obj/machinery/autolathe
|
|
name = "autolathe"
|
|
desc = "It produces items using metal and glass."
|
|
icon_state = "autolathe"
|
|
density = 1
|
|
anchored = 1
|
|
use_power = 1
|
|
idle_power_usage = 10
|
|
active_power_usage = 2000
|
|
|
|
var/list/machine_recipes
|
|
var/list/stored_material = list(DEFAULT_WALL_MATERIAL = 0, "glass" = 0)
|
|
var/list/storage_capacity = list(DEFAULT_WALL_MATERIAL = 0, "glass" = 0)
|
|
var/show_category = "All"
|
|
|
|
var/hacked = 0
|
|
var/disabled = 0
|
|
var/shocked = 0
|
|
var/busy = 0
|
|
|
|
var/mat_efficiency = 1
|
|
var/build_time = 50
|
|
|
|
var/datum/wires/autolathe/wires = null
|
|
|
|
|
|
/obj/machinery/autolathe/New()
|
|
|
|
..()
|
|
wires = new(src)
|
|
//Create parts for lathe.
|
|
component_parts = list()
|
|
component_parts += new /obj/item/weapon/circuitboard/autolathe(src)
|
|
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
|
|
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
|
|
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
|
|
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
|
|
component_parts += new /obj/item/weapon/stock_parts/console_screen(src)
|
|
RefreshParts()
|
|
|
|
/obj/machinery/autolathe/proc/update_recipe_list()
|
|
if(!machine_recipes)
|
|
machine_recipes = autolathe_recipes
|
|
|
|
/obj/machinery/autolathe/interact(mob/user as mob)
|
|
|
|
update_recipe_list()
|
|
|
|
if(..() || (disabled && !panel_open))
|
|
user << "<span class='danger'>\The [src] is disabled!</span>"
|
|
return
|
|
|
|
if(shocked)
|
|
shock(user, 50)
|
|
|
|
var/dat = "<center><h1>Autolathe Control Panel</h1><hr/>"
|
|
|
|
if(!disabled)
|
|
dat += "<table width = '100%'>"
|
|
var/material_top = "<tr>"
|
|
var/material_bottom = "<tr>"
|
|
|
|
for(var/material in stored_material)
|
|
material_top += "<td width = '25%' align = center><b>[material]</b></td>"
|
|
material_bottom += "<td width = '25%' align = center>[stored_material[material]]<b>/[storage_capacity[material]]</b></td>"
|
|
|
|
dat += "[material_top]</tr>[material_bottom]</tr></table><hr>"
|
|
dat += "<h2>Printable Designs</h2><h3>Showing: <a href='?src=\ref[src];change_category=1'>[show_category]</a>.</h3></center><table width = '100%'>"
|
|
|
|
var/index = 0
|
|
for(var/datum/autolathe/recipe/R in machine_recipes)
|
|
index++
|
|
if(R.hidden && !hacked || (show_category != "All" && show_category != R.category))
|
|
continue
|
|
var/can_make = 1
|
|
var/material_string = ""
|
|
var/multiplier_string = ""
|
|
var/max_sheets
|
|
var/comma
|
|
if(!R.resources || !R.resources.len)
|
|
material_string = "No resources required.</td>"
|
|
else
|
|
//Make sure it's buildable and list requires resources.
|
|
for(var/material in R.resources)
|
|
var/sheets = round(stored_material[material]/round(R.resources[material]*mat_efficiency))
|
|
if(isnull(max_sheets) || max_sheets > sheets)
|
|
max_sheets = sheets
|
|
if(!isnull(stored_material[material]) && stored_material[material] < round(R.resources[material]*mat_efficiency))
|
|
can_make = 0
|
|
if(!comma)
|
|
comma = 1
|
|
else
|
|
material_string += ", "
|
|
material_string += "[round(R.resources[material] * mat_efficiency)] [material]"
|
|
material_string += ".<br></td>"
|
|
//Build list of multipliers for sheets.
|
|
if(R.is_stack)
|
|
if(max_sheets && max_sheets > 0)
|
|
multiplier_string += "<br>"
|
|
for(var/i = 5;i<max_sheets;i*=2) //5,10,20,40...
|
|
multiplier_string += "<a href='?src=\ref[src];make=[index];multiplier=[i]'>\[x[i]\]</a>"
|
|
multiplier_string += "<a href='?src=\ref[src];make=[index];multiplier=[max_sheets]'>\[x[max_sheets]\]</a>"
|
|
|
|
dat += "<tr><td width = 180>[R.hidden ? "<font color = 'red'>*</font>" : ""]<b>[can_make ? "<a href='?src=\ref[src];make=[index];multiplier=1'>" : ""][R.name][can_make ? "</a>" : ""]</b>[R.hidden ? "<font color = 'red'>*</font>" : ""][multiplier_string]</td><td align = right>[material_string]</tr>"
|
|
|
|
dat += "</table><hr>"
|
|
//Hacking.
|
|
if(panel_open)
|
|
dat += "<h2>Maintenance Panel</h2>"
|
|
dat += wires.GetInteractWindow()
|
|
|
|
dat += "<hr>"
|
|
|
|
user << browse(dat, "window=autolathe")
|
|
onclose(user, "autolathe")
|
|
|
|
/obj/machinery/autolathe/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
|
|
|
if(busy)
|
|
user << "<span class='notice'>\The [src] is busy. Please wait for completion of previous operation.</span>"
|
|
return
|
|
|
|
if(default_deconstruction_screwdriver(user, O))
|
|
updateUsrDialog()
|
|
return
|
|
if(default_deconstruction_crowbar(user, O))
|
|
return
|
|
if(default_part_replacement(user, O))
|
|
return
|
|
|
|
if(stat)
|
|
return
|
|
|
|
if(panel_open)
|
|
//Don't eat multitools or wirecutters used on an open lathe.
|
|
if(istype(O, /obj/item/device/multitool) || istype(O, /obj/item/weapon/wirecutters))
|
|
attack_hand(user)
|
|
return
|
|
|
|
if(O.loc != user && !(istype(O,/obj/item/stack)))
|
|
return 0
|
|
|
|
if(is_robot_module(O))
|
|
return 0
|
|
|
|
//Resources are being loaded.
|
|
var/obj/item/eating = O
|
|
if(!eating.matter)
|
|
user << "\The [eating] does not contain significant amounts of useful materials and cannot be accepted."
|
|
return
|
|
|
|
var/filltype = 0 // Used to determine message.
|
|
var/total_used = 0 // Amount of material used.
|
|
var/mass_per_sheet = 0 // Amount of material constituting one sheet.
|
|
|
|
for(var/material in eating.matter)
|
|
|
|
if(isnull(stored_material[material]) || isnull(storage_capacity[material]))
|
|
continue
|
|
|
|
if(stored_material[material] >= storage_capacity[material])
|
|
continue
|
|
|
|
var/total_material = eating.matter[material]
|
|
|
|
//If it's a stack, we eat multiple sheets.
|
|
if(istype(eating,/obj/item/stack))
|
|
var/obj/item/stack/stack = eating
|
|
total_material *= stack.get_amount()
|
|
|
|
if(stored_material[material] + total_material > storage_capacity[material])
|
|
total_material = storage_capacity[material] - stored_material[material]
|
|
filltype = 1
|
|
else
|
|
filltype = 2
|
|
|
|
stored_material[material] += total_material
|
|
total_used += total_material
|
|
mass_per_sheet += eating.matter[material]
|
|
|
|
if(!filltype)
|
|
user << "<span class='notice'>\The [src] is full. Please remove material from the autolathe in order to insert more.</span>"
|
|
return
|
|
else if(filltype == 1)
|
|
user << "You fill \the [src] to capacity with \the [eating]."
|
|
else
|
|
user << "You fill \the [src] with \the [eating]."
|
|
|
|
flick("autolathe_o", src) // Plays metal insertion animation. Work out a good way to work out a fitting animation. ~Z
|
|
|
|
if(istype(eating,/obj/item/stack))
|
|
var/obj/item/stack/stack = eating
|
|
stack.use(max(1, round(total_used/mass_per_sheet))) // Always use at least 1 to prevent infinite materials.
|
|
else
|
|
user.remove_from_mob(O)
|
|
qdel(O)
|
|
|
|
updateUsrDialog()
|
|
return
|
|
|
|
/obj/machinery/autolathe/attack_hand(mob/user as mob)
|
|
user.set_machine(src)
|
|
interact(user)
|
|
|
|
/obj/machinery/autolathe/Topic(href, href_list)
|
|
|
|
if(..())
|
|
return
|
|
|
|
usr.set_machine(src)
|
|
add_fingerprint(usr)
|
|
|
|
if(busy)
|
|
usr << "<span class='notice'>The autolathe is busy. Please wait for completion of previous operation.</span>"
|
|
return
|
|
|
|
if(href_list["change_category"])
|
|
|
|
var/choice = input("Which category do you wish to display?") as null|anything in autolathe_categories+"All"
|
|
if(!choice) return
|
|
show_category = choice
|
|
|
|
if(href_list["make"] && machine_recipes)
|
|
|
|
var/index = text2num(href_list["make"])
|
|
var/multiplier = text2num(href_list["multiplier"])
|
|
var/datum/autolathe/recipe/making
|
|
|
|
if(index > 0 && index <= machine_recipes.len)
|
|
making = machine_recipes[index]
|
|
|
|
//Exploit detection, not sure if necessary after rewrite.
|
|
if(!making || multiplier < 0 || multiplier > 100)
|
|
var/turf/exploit_loc = get_turf(usr)
|
|
message_admins("[key_name_admin(usr)] tried to exploit an autolathe to duplicate an item! ([exploit_loc ? "<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[exploit_loc.x];Y=[exploit_loc.y];Z=[exploit_loc.z]'>JMP</a>" : "null"])", 0)
|
|
log_admin("EXPLOIT : [key_name(usr)] tried to exploit an autolathe to duplicate an item!")
|
|
return
|
|
|
|
busy = 1
|
|
update_use_power(2)
|
|
|
|
//Check if we still have the materials.
|
|
for(var/material in making.resources)
|
|
if(!isnull(stored_material[material]))
|
|
if(stored_material[material] < round(making.resources[material] * mat_efficiency) * multiplier)
|
|
return
|
|
|
|
//Consume materials.
|
|
for(var/material in making.resources)
|
|
if(!isnull(stored_material[material]))
|
|
stored_material[material] = max(0, stored_material[material] - round(making.resources[material] * mat_efficiency) * multiplier)
|
|
|
|
//Fancy autolathe animation.
|
|
flick("autolathe_n", src)
|
|
|
|
sleep(build_time)
|
|
|
|
busy = 0
|
|
update_use_power(1)
|
|
|
|
//Sanity check.
|
|
if(!making || !src) return
|
|
|
|
//Create the desired item.
|
|
var/obj/item/I = new making.path(loc)
|
|
if(multiplier > 1 && istype(I, /obj/item/stack))
|
|
var/obj/item/stack/S = I
|
|
S.amount = multiplier
|
|
|
|
updateUsrDialog()
|
|
|
|
/obj/machinery/autolathe/update_icon()
|
|
icon_state = (panel_open ? "autolathe_t" : "autolathe")
|
|
|
|
//Updates overall lathe storage size.
|
|
/obj/machinery/autolathe/RefreshParts()
|
|
..()
|
|
var/mb_rating = 0
|
|
var/man_rating = 0
|
|
for(var/obj/item/weapon/stock_parts/matter_bin/MB in component_parts)
|
|
mb_rating += MB.rating
|
|
for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts)
|
|
man_rating += M.rating
|
|
|
|
storage_capacity[DEFAULT_WALL_MATERIAL] = mb_rating * 25000
|
|
storage_capacity["glass"] = mb_rating * 12500
|
|
build_time = 50 / man_rating
|
|
mat_efficiency = 1.1 - man_rating * 0.1// Normally, price is 1.25 the amount of material, so this shouldn't go higher than 0.8. Maximum rating of parts is 3
|
|
|
|
/obj/machinery/autolathe/dismantle()
|
|
|
|
for(var/mat in stored_material)
|
|
var/material/M = get_material_by_name(mat)
|
|
if(!istype(M))
|
|
continue
|
|
var/obj/item/stack/material/S = new M.stack_type(get_turf(src))
|
|
if(stored_material[mat] > S.perunit)
|
|
S.amount = round(stored_material[mat] / S.perunit)
|
|
else
|
|
qdel(S)
|
|
..()
|
|
return 1
|