mirror of
https://github.com/vgstation-coders/vgstation13.git
synced 2025-12-10 18:32:03 +00:00
Previously if you clicked on an object and you already had the NanoUI open, two things could happen: * The UI only updates * The UI reopens with a white BYOND flash. The latter did always move it to the foreground, but the flash and UI moving was pretty ugly. The former only updates the UI, so if you had multiple stacked windows open it gets kinda annoying. With this change, all UIs always do the former, and the UI for an object always moves to the front when you interact with said object.
268 lines
9.9 KiB
Plaintext
268 lines
9.9 KiB
Plaintext
#define REV_ENG_HEIGHT 400
|
|
#define REV_ENG_WIDTH 1200
|
|
|
|
#define REV_ENG_RESEARCHBASE 150
|
|
|
|
/obj/machinery/r_n_d/reverse_engine
|
|
name = "Reverse Engine"
|
|
desc = ""
|
|
icon = 'icons/obj/machines/mechanic.dmi'
|
|
icon_state = "reverse-engine"
|
|
|
|
var/list/datum/design/research_queue = list()//all the designs we are waiting to research
|
|
var/list/datum/design/ready_queue = list()//all the designs we HAVE researched, and are ready to print
|
|
var/max_queue_len = 0 as num //maximum number of items in the research queue
|
|
|
|
var/scan_rating = 1 //the scanner rating
|
|
var/cap_rating = 1 //the capacitor rating
|
|
|
|
research_flags = NANOTOUCH
|
|
|
|
/obj/machinery/r_n_d/reverse_engine/New()
|
|
..()
|
|
|
|
component_parts = newlist(
|
|
/obj/item/weapon/circuitboard/reverse_engine,
|
|
/obj/item/weapon/stock_parts/scanning_module,
|
|
/obj/item/weapon/stock_parts/scanning_module,
|
|
/obj/item/weapon/stock_parts/capacitor,
|
|
/obj/item/weapon/stock_parts/capacitor,
|
|
/obj/item/weapon/stock_parts/manipulator,
|
|
/obj/item/weapon/stock_parts/console_screen
|
|
)
|
|
|
|
RefreshParts()
|
|
|
|
/obj/machinery/r_n_d/reverse_engine/RefreshParts()
|
|
var/i = 0
|
|
for(var/obj/item/weapon/stock_parts/scanning_module/S in component_parts)
|
|
i++
|
|
scan_rating += S.rating //sum
|
|
scan_rating = scan_rating / i //average
|
|
|
|
i = 0
|
|
for(var/obj/item/weapon/stock_parts/capacitor/C in component_parts)
|
|
i++
|
|
cap_rating += C.rating
|
|
cap_rating = cap_rating / i
|
|
|
|
for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts)
|
|
max_queue_len = 10 * M.rating
|
|
|
|
/obj/machinery/r_n_d/reverse_engine/attackby(var/obj/O as obj, var/mob/user as mob)
|
|
if(..())
|
|
return 1
|
|
if(busy)
|
|
to_chat(user, "<span class='notice'>The [src] is currently busy, please wait until the current operation is finished.</span>")
|
|
return
|
|
if(istype(O, /obj/item/device/device_analyser))
|
|
var/obj/item/device/device_analyser/DA = O
|
|
if(DA.loaded_designs && DA.loaded_designs.len)
|
|
if(DA.loadone)
|
|
var/list/name_list = list()
|
|
for(var/datum/design/thisdesign in DA.loaded_designs)
|
|
name_list[thisdesign.name] = thisdesign
|
|
var/design_name = input(user, "Select a design to load", "Select Design", "") as null|anything in name_list
|
|
var/datum/design/chosen_design = name_list[design_name]
|
|
AddDesign(chosen_design, DA.loaded_designs, user)
|
|
return 1
|
|
else
|
|
var/i = 0
|
|
for(var/datum/design/loop_design in DA.loaded_designs)
|
|
if(!AddDesign(loop_design, DA.loaded_designs, user))
|
|
break
|
|
i++
|
|
to_chat(user, "Successfully transferred [i] design\s.")
|
|
return 1
|
|
return
|
|
if(istype(O, /obj/item/device/pda))
|
|
var/obj/item/device/pda/PDA = O
|
|
if(PDA.dev_analys)
|
|
var/obj/item/device/device_analyser/DA = PDA.dev_analys
|
|
for(var/datum/design/loop_design in DA.loaded_designs)
|
|
AddDesign(loop_design, DA.loaded_designs, user)
|
|
return 1
|
|
return 0
|
|
|
|
//Loads a design from a list onto the machine to be researched
|
|
//Pretty simple, just checks if the design is already present and then adds it and removes it from the parent list
|
|
/obj/machinery/r_n_d/reverse_engine/proc/AddDesign(var/datum/design/design, var/list/design_list, var/mob/user)
|
|
if(!istype(design))
|
|
design_list -= design //lets just brush that under the rug
|
|
return
|
|
for(var/datum/design/MD in research_queue)
|
|
if(MD.build_path == design.build_path)
|
|
design_list -= design
|
|
to_chat(user, "<span class='notice'>The [design.name] is already loaded onto \the [src]!</span>")
|
|
return
|
|
for(var/datum/design/MD in ready_queue)
|
|
if(MD.build_path == design.build_path)
|
|
design_list -= design
|
|
to_chat(user, "<span class='notice'>The [design.name] has already been researched by \the [src]!</span>")
|
|
return
|
|
if(research_queue.len >= max_queue_len)
|
|
to_chat(user, "<span class='notice'>The [src]'s research queue is full. Research some designs first before adding more.</span>")
|
|
return
|
|
if(design in design_list) //let's make sure, here
|
|
research_queue += design
|
|
design_list -= design
|
|
to_chat(user, "<span class='notice'>The [design.name] was successfully loaded onto the [src].</span>")
|
|
return 1
|
|
return
|
|
|
|
//proc used to determine how quickly a design is researched.
|
|
//given a design, it checks to see the difference between the tech levels of the design and of the rd console it is linked to.
|
|
//returns the number of levels difference between the design and the console, if any at all ( no negatives )
|
|
/obj/machinery/r_n_d/reverse_engine/proc/Tech_Difference(var/datum/design/design)
|
|
var/list/techlist = design.req_tech
|
|
var/techdifference = 0
|
|
if(techlist.len && linked_console)
|
|
//message_admins("We have a techlist and a linked_console")
|
|
for(var/checktech in techlist)
|
|
//message_admins("Looking at [checktech] with value of [techlist[checktech]]")
|
|
for(var/datum/tech/pointed_tech in tech_list) //if we find that technology
|
|
if(pointed_tech.id == checktech)
|
|
if(techlist[checktech] > pointed_tech.level) //if the machine board's research level is higher than the one on the console
|
|
//message_admins("Found a difference of [techlist[checktech] - pointed_tech.level]")
|
|
techdifference += techlist[checktech] - pointed_tech.level //then add this to the tech difference
|
|
else if(techlist.len)
|
|
//message_admins("We only have a techlist")
|
|
for(var/checktech in techlist) //we have no console, so this is the worst case scenario
|
|
techdifference += techlist[checktech] - 1 //maximum time possible
|
|
//message_admins("Techdifference before adjust is [techdifference]")
|
|
if(techdifference < 0) //I'm not sure how this could happen, but just for sanity
|
|
techdifference = 0
|
|
return techdifference
|
|
|
|
/obj/machinery/r_n_d/reverse_engine/proc/researchQueue()
|
|
if(!research_queue.len)
|
|
return
|
|
while(research_queue[1])
|
|
if(stat&(NOPOWER|BROKEN))
|
|
return 0
|
|
var/datum/design/current_design = research_queue[1]
|
|
if(!researchDesign(current_design))
|
|
break
|
|
if(!research_queue.len)
|
|
break
|
|
else
|
|
current_design = research_queue[1]
|
|
if(!research_queue.len)
|
|
src.visible_message("<span class='notice'>[bicon(src)] \The [src] beeps: 'Successfully researched all designs.'</span>")
|
|
|
|
/obj/machinery/r_n_d/reverse_engine/proc/researchDesign(var/datum/design/design)
|
|
//message_admins("This researchDesign got called with the [design.design_name].")
|
|
if(busy)
|
|
return
|
|
if(!istype(design) || !(design in research_queue)) //sanity checking, always good
|
|
return
|
|
if(design in ready_queue)
|
|
src.visible_message("<span class='notice'>[bicon(src)] \The [src] beeps:'The [design.name] is already researched.'</span>")
|
|
research_queue -= design
|
|
return
|
|
var/researchtime = ( (REV_ENG_RESEARCHBASE * Tech_Difference(design)) / (scan_rating + cap_rating) )
|
|
busy = 1
|
|
overlays += image(icon = icon, icon_state = "[base_state]_ani")
|
|
sleep(researchtime) //we use sleep instead of spawn because code like the queue code has to hang on this proc
|
|
research_queue -= design
|
|
busy = 0
|
|
overlays -= image(icon = icon, icon_state = "[base_state]_ani")
|
|
if(!(design in ready_queue))
|
|
ready_queue += design
|
|
src.visible_message("<span class='notice'>[bicon(src)] \The [src] beeps: 'Successfully researched \the [design.name].'</span>")
|
|
return 1
|
|
return
|
|
|
|
//finds a printer connected to the console, and use it to print our design
|
|
/obj/machinery/r_n_d/reverse_engine/proc/PrintDesign(var/datum/design/design, var/use_nano = 0)
|
|
if(linked_console)
|
|
//message_admins("Looking for machines...")
|
|
for(var/obj/machinery/r_n_d/M in linked_console.linked_machines)
|
|
if(istype(M, /obj/machinery/r_n_d/blueprinter))
|
|
var/obj/machinery/r_n_d/blueprinter/BP = M
|
|
//message_admins("Found the blueprinter!")
|
|
BP.PrintDesign(design, use_nano)
|
|
return 1
|
|
else
|
|
src.visible_message("You need to link this machine to a research console first!")
|
|
|
|
|
|
/obj/machinery/r_n_d/reverse_engine/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open=NANOUI_FOCUS)
|
|
if(src.stat & (BROKEN|NOPOWER))
|
|
return
|
|
if((user.stat && !isobserver(user)) || user.restrained() || !allowed(user) || !Adjacent(user))
|
|
return
|
|
|
|
var/data[0]
|
|
var/list/todo_queue = list()
|
|
var/list/done_queue = list()
|
|
|
|
for(var/i=1;i<=research_queue.len;i++)
|
|
var/datum/design/research_item = research_queue[i]
|
|
if(istype(research_item, /datum/design/))
|
|
todo_queue.Add(list(list("name" = research_item.name, "command1" = list("research" = i), "command2" = list("remove_tosearch" = i))))
|
|
|
|
for(var/i=1;i<=ready_queue.len;i++)
|
|
var/datum/design/ready_item = ready_queue[i]
|
|
if(istype(ready_item,/datum/design/))
|
|
done_queue.Add(list(list("name" = ready_item.name, "command1" = list("print_design" = i), "command2" = list("nanoprint_design" = i), "command3" = list("remove_researched" = i))))
|
|
|
|
data["research_queue"] = todo_queue
|
|
data["ready_queue"] = done_queue
|
|
|
|
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
|
|
if (!ui)
|
|
ui = new(user, src, ui_key, "rev-engine.tmpl", name, REV_ENG_WIDTH, REV_ENG_HEIGHT)
|
|
ui.set_initial_data(data)
|
|
ui.open()
|
|
|
|
/obj/machinery/r_n_d/reverse_engine/Topic(href, href_list)
|
|
|
|
if(..())
|
|
return
|
|
if(href_list["close"])
|
|
if(usr.machine == src)
|
|
usr.unset_machine()
|
|
return 1
|
|
if(href_list["remove_tosearch"])
|
|
var/datum/design/design = research_queue[text2num(href_list["remove_tosearch"])]
|
|
if(design)
|
|
research_queue -= design
|
|
qdel(design)
|
|
design = null
|
|
ui_interact(usr)
|
|
return 1
|
|
|
|
if(href_list["remove_researched"])
|
|
var/datum/design/design = ready_queue[text2num(href_list["remove_researched"])]
|
|
if(design)
|
|
ready_queue -= design
|
|
qdel(design)
|
|
design = null
|
|
ui_interact(usr)
|
|
return 1
|
|
|
|
if(href_list["research"])
|
|
var/datum/design/design = research_queue[text2num(href_list["research"])]
|
|
if(design)
|
|
researchDesign(design)
|
|
ui_interact(usr)
|
|
return 1
|
|
|
|
if(href_list["research_all"])
|
|
researchQueue()
|
|
ui_interact(usr)
|
|
return 1
|
|
|
|
if(href_list["print_design"])
|
|
var/datum/design/design = ready_queue[text2num(href_list["print_design"])]
|
|
if(design)
|
|
PrintDesign(design, 0)
|
|
return 1
|
|
|
|
if(href_list["nanoprint_design"])
|
|
var/datum/design/design = ready_queue[text2num(href_list["nanoprint_design"])]
|
|
if(design)
|
|
PrintDesign(design, 1)
|
|
return 1
|