mirror of
https://github.com/Citadel-Station-13/Citadel-Station-13-RP.git
synced 2026-08-16 22:06:58 +01:00
- all cells in the game are now small, medium, large - super, hyper capacity cells, device, and weapon cells are all removed - cells now have standardized variants, some of which are printable by R&D - energy weapons rebalanced - **advanced energy guns and stun revolvers removed** - use the new modular weapon system and microfission cells. --------- Co-authored-by: silicons <silicons@silicons.dev>
382 lines
14 KiB
Plaintext
382 lines
14 KiB
Plaintext
/obj/item/integrated_circuit_printer
|
|
name = "integrated circuit printer"
|
|
desc = "A portable(ish) machine made to print tiny modular circuitry out of metal."
|
|
icon = 'icons/obj/integrated_electronics/electronic_tools.dmi'
|
|
icon_state = "circuit_printer"
|
|
w_class = WEIGHT_CLASS_BULKY
|
|
worth_intrinsic = 150
|
|
var/cur_metal = 0
|
|
var/max_metal = 250
|
|
/// One sheet equals this much metal.
|
|
var/metal_per_sheet = 10
|
|
/// When hit with an upgrade disk, will turn true, allowing it to print the higher tier circuits.
|
|
var/upgraded = FALSE
|
|
/// Same for above, but will allow the printer to duplicate a specific assembly.
|
|
var/can_clone = TRUE
|
|
/// If this is false, then cloning will take an amount of deciseconds equal to the metal cost divided by 100.
|
|
var/fast_clone = FALSE
|
|
/// If true, metal is infinite.
|
|
var/debug = FALSE
|
|
var/static/list/recipe_list = list()
|
|
/// If the printer is currently creating a circuit
|
|
var/cloning = FALSE
|
|
/// If an assembly is being emptied into this printer
|
|
var/recycling = FALSE
|
|
/// Currently loaded save, in form of list
|
|
var/list/program
|
|
var/dirty_items = FALSE
|
|
|
|
// todo: get_containing_worth for the metal inside
|
|
|
|
/obj/item/integrated_circuit_printer/examine(mob/user, dist)
|
|
. = ..()
|
|
ui_interact(user)
|
|
|
|
/obj/item/integrated_circuit_printer/upgraded
|
|
upgraded = TRUE
|
|
can_clone = TRUE
|
|
fast_clone = TRUE
|
|
|
|
/obj/item/integrated_circuit_printer/debug
|
|
name = "fractal integrated circuit printer"
|
|
desc = "A portable(ish) machine that makes modular circuitry seemingly out of thin air."
|
|
cur_metal = 250
|
|
debug = TRUE
|
|
upgraded = TRUE
|
|
can_clone = TRUE
|
|
fast_clone = TRUE
|
|
w_class = WEIGHT_CLASS_TINY
|
|
/* TBI: Requires material containers
|
|
/obj/item/integrated_circuit_printer/Initialize(mapload)
|
|
. = ..()
|
|
var/datum/component/material_container/materials = AddComponent(/datum/component/material_container, list(/datum/prototype/material/iron), MINERAL_MATERIAL_AMOUNT * 25, TRUE, list(/obj/item/stack, /obj/item/integrated_circuit, /obj/item/electronic_assembly))
|
|
materials.precise_insertion = TRUE
|
|
*/
|
|
/obj/item/integrated_circuit_printer/proc/print_program(mob/user)
|
|
visible_message(SPAN_NOTICE("[src] has finished printing its assembly!"))
|
|
playsound(src, 'sound/items/poster_being_created.ogg', 50, TRUE)
|
|
var/obj/item/electronic_assembly/assembly = SScircuit.load_electronic_assembly(get_turf(src), program)
|
|
assembly.creator = key_name(user)
|
|
assembly.investigate_log("was printed by [assembly.creator].", INVESTIGATE_CIRCUIT)
|
|
cloning = FALSE
|
|
|
|
/obj/item/integrated_circuit_printer/proc/check_max_metal(inc)
|
|
if(cur_metal + inc > max_metal)
|
|
inc = CEILING(src.cur_metal + inc - src.max_metal, src.metal_per_sheet) / 10
|
|
var/obj/item/stack/material/steel/S = new /obj/item/stack/material/steel(loc, inc, TRUE)
|
|
to_chat(usr, SPAN_NOTICE("[src] ejects [S.amount] [S.singular_name]\s!"))
|
|
src.cur_metal -= src.metal_per_sheet * inc
|
|
return TRUE
|
|
return FALSE
|
|
|
|
/obj/item/integrated_circuit_printer/attack_robot(mob/user as mob)
|
|
if(Adjacent(user))
|
|
return ui_interact(user)
|
|
else
|
|
return ..()
|
|
|
|
/obj/item/integrated_circuit_printer/attackby(var/obj/item/O, var/mob/user)
|
|
if(istype(O,/obj/item/stack/material))
|
|
var/obj/item/stack/material/stack = O
|
|
if(stack.material.name == MAT_STEEL)
|
|
if(debug)
|
|
to_chat(user, SPAN_WARNING("\The [src] does not need any material."))
|
|
return
|
|
var/num = round(min((max_metal - cur_metal) / metal_per_sheet, stack.amount))
|
|
if(num < 1)
|
|
to_chat(user, SPAN_WARNING("\The [src] is too full to add more metal."))
|
|
return
|
|
if(stack.use(max(1, round(num)))) // We don't want to create stacks that aren't whole numbers
|
|
to_chat(user, SPAN_NOTICE("You add [num] sheet\s to \the [src]."))
|
|
cur_metal += num * metal_per_sheet
|
|
return TRUE
|
|
|
|
if(istype(O,/obj/item/integrated_circuit))
|
|
if(!user.attempt_consume_item_for_construction(O))
|
|
return
|
|
var/obj/item/integrated_circuit/IC = O
|
|
to_chat(user, SPAN_NOTICE("You insert the circuit into \the [src]."))
|
|
check_max_metal(IC.cost)
|
|
cur_metal += IC.cost
|
|
return TRUE
|
|
|
|
if(istype(O,/obj/item/disk/integrated_circuit/upgrade/advanced))
|
|
if(upgraded)
|
|
to_chat(user, SPAN_WARNING("\The [src] already has this upgrade."))
|
|
return TRUE
|
|
to_chat(user, SPAN_NOTICE("You install \the [O] into \the [src]."))
|
|
upgraded = TRUE
|
|
dirty_items = TRUE
|
|
return TRUE
|
|
|
|
if(istype(O,/obj/item/disk/integrated_circuit/upgrade/clone))
|
|
if(fast_clone)
|
|
to_chat(user, SPAN_WARNING("\The [src] already has this upgrade."))
|
|
return TRUE
|
|
to_chat(user, SPAN_NOTICE("You install \the [O] into \the [src]."))
|
|
can_clone = TRUE
|
|
fast_clone = TRUE
|
|
return TRUE
|
|
|
|
if(istype(O, /obj/item/electronic_assembly))
|
|
var/obj/item/electronic_assembly/EA = O //microtransactions not included
|
|
if(recycling)
|
|
return
|
|
if(!EA.opened)
|
|
to_chat(user, SPAN_WARNING("You can't reach [EA]'s components to remove them!"))
|
|
return
|
|
if(EA.obj_cell_slot?.cell)
|
|
to_chat(user, SPAN_WARNING("Remove [EA]'s power cell first!"))
|
|
return
|
|
var/inc = 0
|
|
for(var/V in EA.assembly_components) // Start looking for recyclable components.
|
|
var/obj/item/integrated_circuit/IC = V
|
|
if(IC.removable) // If found, don't destroy the assembly later.
|
|
++inc
|
|
to_chat(user, SPAN_NOTICE("You begin recycling [EA]'s components..."))
|
|
playsound(src, 'sound/items/electronic_assembly_emptying.ogg', 50, TRUE)
|
|
if(!do_after(user, 30, target = src) && !recycling) //short channel so you don't accidentally start emptying out a complex assembly
|
|
recycling = TRUE
|
|
break
|
|
if (inc == 1)
|
|
for(var/V in EA.assembly_components)
|
|
var/obj/item/integrated_circuit/IC = V
|
|
if(IC.removable)
|
|
if(!do_after(user, 5, target = user))
|
|
recycling = FALSE
|
|
return
|
|
if(IC.removable)
|
|
playsound(src, 'sound/items/crowbar.ogg', 50, TRUE)
|
|
check_max_metal(IC.cost)
|
|
cur_metal += IC.cost
|
|
IC.remove(usr, TRUE, inc)
|
|
qdel(IC)
|
|
else ++inc
|
|
to_chat(user, SPAN_NOTICE("You recycle all the components[EA.assembly_components.len ? " you could " : " "]from [EA]!"))
|
|
playsound(src, 'sound/items/electronic_assembly_empty.ogg', 50, TRUE)
|
|
recycling = FALSE
|
|
return TRUE
|
|
if(inc == 0)
|
|
if(!do_after(user, 10, target = user))
|
|
recycling = FALSE
|
|
return
|
|
if(!user.attempt_consume_item_for_construction(EA))
|
|
return
|
|
to_chat(user, SPAN_NOTICE("You recycle the [EA]!"))
|
|
check_max_metal(EA.cost)
|
|
cur_metal += EA.cost
|
|
return TRUE
|
|
return ..()
|
|
|
|
/obj/item/integrated_circuit_printer/vv_edit_var(var_name, var_value)
|
|
// Gotta update the static data in case an admin VV's the upgraded var for some reason..! //I would :) -Zan
|
|
if(var_name == "upgraded")
|
|
dirty_items = TRUE
|
|
return ..()
|
|
|
|
/obj/item/integrated_circuit_printer/attack_self(mob/user, datum/event_args/actor/actor)
|
|
. = ..()
|
|
if(.)
|
|
return
|
|
ui_interact(user)
|
|
|
|
/obj/item/integrated_circuit_printer/ui_state()
|
|
return GLOB.physical_state
|
|
|
|
/obj/item/integrated_circuit_printer/ui_interact(mob/user, datum/tgui/ui)
|
|
if(dirty_items)
|
|
update_static_data(user, ui)
|
|
dirty_items = FALSE
|
|
|
|
ui = SStgui.try_update_ui(user, src, ui)
|
|
if(!ui)
|
|
ui = new(user, src, "ICPrinter", name) // 500, 600
|
|
ui.open()
|
|
|
|
/obj/item/integrated_circuit_printer/ui_static_data(mob/user, datum/tgui/ui)
|
|
var/list/data = ..()
|
|
|
|
var/list/categories = list()
|
|
for(var/category in SScircuit.circuit_fabricator_recipe_list)
|
|
var/list/cat_obj = list(
|
|
"name" = category,
|
|
"items" = null
|
|
)
|
|
var/list/circuit_list = SScircuit.circuit_fabricator_recipe_list[category]
|
|
var/list/items = list()
|
|
for(var/path in circuit_list)
|
|
var/obj/O = path
|
|
var/can_build = TRUE
|
|
var/obj/item/integrated_circuit/IC = path
|
|
|
|
if(ispath(path, /obj/item/integrated_circuit))
|
|
if((initial(IC.spawn_flags) & IC_SPAWN_RESEARCH) && (!(initial(IC.spawn_flags) & IC_SPAWN_DEFAULT)) && !upgraded)
|
|
can_build = FALSE
|
|
|
|
var/cost = 1
|
|
if(ispath(path, /obj/item/electronic_assembly))
|
|
var/obj/item/electronic_assembly/E = path
|
|
cost = round((initial(E.max_complexity) + initial(E.max_components)) / 4)
|
|
else if(ispath(path, /obj/item/integrated_circuit))
|
|
// var/obj/item/integrated_circuit/I = path
|
|
cost = initial(IC.cost)
|
|
else
|
|
cost = initial(O.w_class)
|
|
|
|
items.Add(list(list(
|
|
"name" = initial(O.name),
|
|
"desc" = initial(O.desc),
|
|
"can_build" = can_build,
|
|
"cost" = cost,
|
|
"path" = path,
|
|
)))
|
|
|
|
cat_obj["items"] = items
|
|
categories.Add(list(cat_obj))
|
|
data["categories"] = categories
|
|
|
|
return data
|
|
|
|
/obj/item/integrated_circuit_printer/ui_data(mob/user, datum/tgui/ui)
|
|
var/list/data = ..()
|
|
|
|
data["metal"] = cur_metal
|
|
data["max_metal"] = max_metal
|
|
data["metal_per_sheet"] = metal_per_sheet
|
|
data["debug"] = debug
|
|
data["upgraded"] = upgraded
|
|
data["can_clone"] = can_clone
|
|
data["program"] = program
|
|
/*
|
|
data["used_space"] = program.Find("used_space")
|
|
data["max_space"] = program.Find("max_space")
|
|
data["complexity"] = program.Find("complexity")
|
|
data["max_complexity"] = program.Find("max_complexity")
|
|
data["metal_cost"] = program.Find("metal_cost")
|
|
data["unsupported_circuit"] = program.Find("unsupported_circuit")
|
|
data["requires_upgrades"] = program.Find("requires_upgrades")
|
|
*/
|
|
|
|
return data
|
|
|
|
/obj/item/integrated_circuit_printer/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state, datum/event_args/actor/actor)
|
|
if(..())
|
|
return TRUE
|
|
|
|
switch(action)
|
|
if("build")
|
|
var/cost = text2num(params["cost"])
|
|
var/build_type = text2path(params["build"])
|
|
if(!build_type || !ispath(build_type))
|
|
return TRUE
|
|
|
|
var/in_some_category = FALSE
|
|
for(var/category in SScircuit.circuit_fabricator_recipe_list)
|
|
if(build_type in SScircuit.circuit_fabricator_recipe_list[category])
|
|
in_some_category = TRUE
|
|
break
|
|
if(!in_some_category)
|
|
return
|
|
|
|
if(!debug)
|
|
if(!Adjacent(usr))
|
|
to_chat(usr, SPAN_NOTICE("You are too far away from \the [src]."))
|
|
if(cur_metal - cost < 0)
|
|
to_chat(usr, SPAN_WARNING("You need [cost] metal to build that!."))
|
|
return TRUE
|
|
cur_metal -= cost
|
|
var/obj/item/built = new build_type(get_turf(loc))
|
|
usr.put_in_hands(built)
|
|
to_chat(usr, SPAN_NOTICE("[capitalize(built.name)] printed."))
|
|
playsound(src, 'sound/items/jaws_pry.ogg', 50, TRUE)
|
|
return TRUE
|
|
if("load_blueprint") //! This should be done through disks and modular comps! For now we have copy-paste here.
|
|
var/new_input = input(usr, "Enter blueprint:", "loading",null) as null|text
|
|
if(!new_input)
|
|
program = null
|
|
return
|
|
if(istext(new_input))
|
|
to_chat(usr, SPAN_NOTICE("[new_input]"))
|
|
to_chat(usr, SPAN_NOTICE("Load blueprint pressed"))
|
|
log_game("[usr] inputted blueprint for circuit [new_input]")
|
|
var/validation = SScircuit.validate_electronic_assembly(new_input)
|
|
// Validation error codes are returned as text.
|
|
if(istext(validation))
|
|
to_chat(usr, SPAN_WARNING("Error: [validation]"))
|
|
return
|
|
else if(islist(validation))
|
|
program = validation
|
|
to_chat(usr, SPAN_NOTICE("This is a valid program for [program["assembly"]["type"]]."))
|
|
if(program["requires_upgrades"])
|
|
if(upgraded)
|
|
to_chat(usr, SPAN_NOTICE("It uses advanced component designs."))
|
|
else
|
|
to_chat(usr, SPAN_WARNING("It uses unknown component designs. Printer upgrade is required to proceed."))
|
|
if(program["unsupported_circuit"])
|
|
to_chat(usr, SPAN_WARNING("This program uses components not supported by the specified assembly. Please change the assembly type in the save file to a supported one."))
|
|
to_chat(usr, SPAN_NOTICE("Used space: [program["used_space"]]/[program["max_space"]]."))
|
|
to_chat(usr, SPAN_NOTICE("Complexity: [program["complexity"]]/[program["max_complexity"]]."))
|
|
to_chat(usr, SPAN_NOTICE("Metal cost: [program["metal_cost"]]."))
|
|
return TRUE
|
|
if("clone")
|
|
if(!program || cloning)
|
|
return
|
|
if(program["requires_upgrades"] && !upgraded && !debug)
|
|
to_chat(usr, SPAN_WARNING("This program uses unknown component designs. Printer upgrade is required to proceed."))
|
|
return
|
|
if(program["unsupported_circuit"] && !debug)
|
|
to_chat(usr, SPAN_WARNING("This program uses components not supported by the specified assembly. Please change the assembly type in the save file to a supported one."))
|
|
return
|
|
else if(fast_clone)
|
|
if(debug || cur_metal < program["metal_cost"])
|
|
cloning = TRUE
|
|
print_program(usr)
|
|
return TRUE
|
|
else
|
|
to_chat(usr, SPAN_WARNING("You need [program["metal_cost"]] metal to build that!"))
|
|
else
|
|
if(cur_metal < program["metal_cost"])
|
|
to_chat(usr, SPAN_WARNING("You need [program["metal_cost"]] metal to build that!"))
|
|
return
|
|
var/cloning_time = round(program["metal_cost"] / 15)
|
|
cloning_time = min(cloning_time, MAX_CIRCUIT_CLONE_TIME)
|
|
cloning = TRUE
|
|
cur_metal -= program["metal_cost"]
|
|
to_chat(usr, SPAN_NOTICE("You begin printing a custom assembly. This will take approximately [DisplayTimeText(cloning_time)]. You can still print \
|
|
off normal parts during this time."))
|
|
playsound(src, 'sound/items/poster_being_created.ogg', 50, TRUE)
|
|
addtimer(CALLBACK(src, PROC_REF(print_program), usr), cloning_time)
|
|
return TRUE
|
|
|
|
if("cancel")
|
|
if(!cloning || !program)
|
|
return
|
|
to_chat(usr, SPAN_NOTICE("Cloning has been canceled. Metal cost has been refunded."))
|
|
cloning = FALSE
|
|
cur_metal += program["metal_cost"]
|
|
check_max_metal(cur_metal)
|
|
return TRUE
|
|
|
|
|
|
// FUKKEN UPGRADE DISKS
|
|
/obj/item/disk/integrated_circuit/upgrade
|
|
name = "integrated circuit printer upgrade disk"
|
|
desc = "Install this into your integrated circuit printer to enhance it."
|
|
icon = 'icons/obj/integrated_electronics/electronic_tools.dmi'
|
|
icon_state = "upgrade_disk"
|
|
item_state = "card-id"
|
|
w_class = WEIGHT_CLASS_SMALL
|
|
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 4)
|
|
|
|
/obj/item/disk/integrated_circuit/upgrade/advanced
|
|
name = "integrated circuit printer upgrade disk - advanced designs"
|
|
desc = "Install this into your integrated circuit printer to enhance it. This one adds new, advanced designs to the printer."
|
|
worth_intrinsic = 150
|
|
|
|
/obj/item/disk/integrated_circuit/upgrade/clone
|
|
name = "integrated circuit printer upgrade disk - circuit cloner"
|
|
desc = "Install this into your integrated circuit printer to enhance it. This one allows the printer to duplicate assemblies."
|
|
icon_state = "upgrade_disk_clone"
|
|
origin_tech = list(TECH_ENGINEERING = 5, TECH_DATA = 6)
|
|
worth_intrinsic = 150
|