Files
CHOMPStation2/code/modules/research/protolathe.dm
Kelenius db30c15e4c Updates to science
Protolathe and CI build procs moved to them from RD console.
Protolathe and CI now have a build queue. Designs take varying time to
build.
P and CI material storage is now a list instead of a set of vars.
origin_tech is now a list.
All sheets now contain exactly 2000 units of matter.
In design datum, chemicals and materials are two separate lists.
Designs are now sorted. The method is kinda hacky but flexible. They
have a var, sort_string. Designs are sorted alphabetically using it.
Circuits how show whether they build a machine or a computer in CI menu.
Adds item construction, for now protolathe is used.
2015-04-04 13:38:03 +03:00

255 lines
8.0 KiB
Plaintext

/obj/machinery/r_n_d/protolathe
name = "Protolathe"
icon_state = "protolathe"
flags = OPENCONTAINER
use_power = 1
idle_power_usage = 30
active_power_usage = 5000
var/list/materials = list("metal" = 0, "glass" = 0, "gold" = 0, "silver" = 0, "phoron" = 0, "uranium" = 0, "diamond" = 0)
var/list/datum/design/queue = list()
var/progress = 0
var/max_material_storage = 100000 // All this could probably be done better with a list but meh.
var/mat_efficiency = 1
var/speed = 1
var/datum/design/chassis/current_chassis = null
var/list/datum/design/current_components = list()
/obj/machinery/r_n_d/protolathe/New()
..()
component_parts = list()
component_parts += new /obj/item/weapon/circuitboard/protolathe(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/manipulator(src)
component_parts += new /obj/item/weapon/reagent_containers/glass/beaker(src)
component_parts += new /obj/item/weapon/reagent_containers/glass/beaker(src)
RefreshParts()
/obj/machinery/r_n_d/protolathe/process()
..()
if(stat)
update_icon()
return
if(queue.len == 0)
busy = 0
update_icon()
return
var/datum/design/D = queue[1]
if(canBuild(D))
busy = 1
progress += speed
if(progress >= D.time)
build(D)
progress = 0
removeFromQueue(1)
if(linked_console)
linked_console.updateUsrDialog()
update_icon()
else
if(busy)
visible_message("<span class='notice'>\icon [src] flashes: insufficient materials: [getLackingMaterials(D)].</span>")
busy = 0
update_icon()
/obj/machinery/r_n_d/protolathe/proc/TotalMaterials() //returns the total of all the stored materials. Makes code neater.
var/t = 0
for(var/f in materials)
t += materials[f]
return t
/obj/machinery/r_n_d/protolathe/RefreshParts()
var/T = 0
for(var/obj/item/weapon/reagent_containers/glass/G in component_parts)
T += G.reagents.maximum_volume
create_reagents(T)
max_material_storage = 0
for(var/obj/item/weapon/stock_parts/matter_bin/M in component_parts)
max_material_storage += M.rating * 75000
T = 0
for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts)
T += M.rating
mat_efficiency = 1 - (T - 2) / 8
speed = T / 2
/obj/machinery/r_n_d/protolathe/dismantle()
for(var/obj/I in component_parts)
if(istype(I, /obj/item/weapon/reagent_containers/glass/beaker))
reagents.trans_to(I, reagents.total_volume)
for(var/f in materials)
if(materials[f] >= SHEET_MATERIAL_AMOUNT)
var/path = getMaterialType(f)
if(path)
var/obj/item/stack/S = new f(loc)
S.amount = round(materials[f] / SHEET_MATERIAL_AMOUNT)
..()
/obj/machinery/r_n_d/protolathe/update_icon()
if(panel_open)
icon_state = "protolathe_t"
else if(busy)
icon_state = "protolathe_n"
else
icon_state = "protolathe"
/obj/machinery/r_n_d/protolathe/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 1
if(default_deconstruction_screwdriver(user, O))
if(linked_console)
linked_console.linked_lathe = null
linked_console = null
return
if(default_deconstruction_crowbar(user, O))
return
if(default_part_replacement(user, O))
return
if(O.is_open_container())
return 1
if(panel_open)
user << "<span class='notice'>You can't load \the [src] while it's opened.</span>"
return 1
if(!linked_console)
user << "<span class='notice'>\The [src] must be linked to an R&D console first!</span>"
return 1
if(!istype(O, /obj/item/stack/sheet))
user << "<span class='notice'>You cannot insert this item into \the [src]!</span>"
return 1
if(stat)
return 1
if(TotalMaterials() + SHEET_MATERIAL_AMOUNT > max_material_storage)
user << "<span class='notice'>\The [src]'s material bin is full. Please remove material before adding more.</span>"
return 1
var/obj/item/stack/sheet/stack = O
var/amount = round(input("How many sheets do you want to add?") as num)//No decimals
if(!O)
return
if(amount <= 0)//No negative numbers
return
if(amount > stack.get_amount())
amount = stack.get_amount()
if(max_material_storage - TotalMaterials() < (amount * SHEET_MATERIAL_AMOUNT)) //Can't overfill
amount = min(stack.get_amount(), round((max_material_storage - TotalMaterials()) / SHEET_MATERIAL_AMOUNT))
var/stacktype = stack.type
var/t = getMaterialName(stacktype)
overlays += "protolathe_[t]"
spawn(10)
overlays -= "protolathe_[t]"
busy = 1
use_power(max(1000, (SHEET_MATERIAL_AMOUNT * amount / 10)))
if(t)
if(do_after(user, 16))
if(stack.use(amount))
user << "<span class='notice'>You add [amount] sheets to \the [src].</span>"
materials[t] += amount * SHEET_MATERIAL_AMOUNT
busy = 0
updateUsrDialog()
return
/obj/machinery/r_n_d/protolathe/proc/getMaterialType(var/name) // TODO: make not copypasted to CI
switch(name)
if("metal")
return /obj/item/stack/sheet/metal
if("glass")
return /obj/item/stack/sheet/glass
if("gold")
return /obj/item/stack/sheet/mineral/gold
if("silver")
return /obj/item/stack/sheet/mineral/silver
if("phoron")
return /obj/item/stack/sheet/mineral/phoron
if("uranium")
return /obj/item/stack/sheet/mineral/uranium
if("diamond")
return /obj/item/stack/sheet/mineral/diamond
return null
/obj/machinery/r_n_d/protolathe/proc/getMaterialName(var/type)
switch(type)
if(/obj/item/stack/sheet/metal)
return "metal"
if(/obj/item/stack/sheet/glass)
return "glass"
if(/obj/item/stack/sheet/mineral/gold)
return "gold"
if(/obj/item/stack/sheet/mineral/silver)
return "silver"
if(/obj/item/stack/sheet/mineral/phoron)
return "phoron"
if(/obj/item/stack/sheet/mineral/uranium)
return "uranium"
if(/obj/item/stack/sheet/mineral/diamond)
return "diamond"
/obj/machinery/r_n_d/protolathe/proc/addToQueue(var/datum/design/D)
queue += D
return
/obj/machinery/r_n_d/protolathe/proc/removeFromQueue(var/index)
queue.Cut(index, index + 1)
return
/obj/machinery/r_n_d/protolathe/proc/canBuild(var/datum/design/D)
for(var/M in D.materials)
if(materials[M] < D.materials[M])
return 0
for(var/C in D.chemicals)
if(!reagents.has_reagent(C, D.chemicals[C]))
return 0
return 1
/obj/machinery/r_n_d/protolathe/proc/getLackingMaterials(var/datum/design/D)
var/ret = ""
for(var/M in D.materials)
if(materials[M] < D.materials[M])
if(ret != "")
ret += ", "
ret += "[D.materials[M] - materials[M]] [M]"
for(var/C in D.chemicals)
if(!reagents.has_reagent(C, D.chemicals[C]))
if(ret != "")
ret += ", "
ret += C
return ret
/obj/machinery/r_n_d/protolathe/proc/build(var/datum/design/D)
var/power = active_power_usage
for(var/M in D.materials)
power += round(D.materials[M] / 5)
power = max(active_power_usage, power)
use_power(power)
for(var/M in D.materials)
materials[M] = max(0, materials[M] - D.materials[M] * mat_efficiency)
for(var/C in D.chemicals)
reagents.remove_reagent(C, D.chemicals[C] * mat_efficiency)
if(D.build_path)
var/obj/new_item = new D.build_path(src)
new_item.loc = loc
if(mat_efficiency != 1) // No matter out of nowhere
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
/obj/machinery/r_n_d/protolathe/proc/choosePart(var/name, var/datum/design/D)
current_components[name] = D
/obj/machinery/r_n_d/protolathe/proc/buildChassis()
var/obj/item/I = new current_chassis.build_path(loc)
for(var/t in current_components)
var/datum/design/D = current_components[t]
var/obj/item/O = new D.build_path(I)
world << I
world << I.type
current_chassis.setup(I, O, t)
current_components.Cut()
current_chassis = null