From 32300086d5a16a960a06764533bfada0c1719401 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 4 Sep 2017 04:08:42 -0500 Subject: [PATCH] [MIRROR] Port material containers to datum components (#2562) * Port material containers to datum components * Fixes Rej --- code/__DEFINES/components.dm | 6 +- code/_onclick/item_attack.dm | 4 +- code/datums/components.dm | 97 ++++++++++++++++ code/datums/components/README.md | 2 +- .../{ => components}/material_container.dm | 109 +++++++++++++----- code/datums/components/powered.dm | 6 + code/game/atoms.dm | 1 + code/game/machinery/autolathe.dm | 69 +++++------ code/game/machinery/droneDispenser.dm | 35 +----- code/game/machinery/recycler.dm | 9 +- code/game/mecha/mech_fabricator.dm | 94 +++++---------- code/modules/clothing/shoes/bananashoes.dm | 30 ++--- code/modules/mining/machine_processing.dm | 10 +- code/modules/mining/machine_redemption.dm | 20 ++-- code/modules/mining/mint.dm | 28 ++--- code/modules/research/circuitprinter.dm | 73 ++++-------- code/modules/research/experimentor.dm | 5 +- code/modules/research/protolathe.dm | 85 ++++---------- code/modules/research/rdconsole.dm | 51 +++++--- tgstation.dme | 2 +- 20 files changed, 373 insertions(+), 363 deletions(-) create mode 100644 code/datums/components.dm rename code/datums/{ => components}/material_container.dm (61%) create mode 100644 code/datums/components/powered.dm diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index 0225dad669..ce7bdc132b 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -14,5 +14,7 @@ #define COMSIG_COMPONENT_ADDED "component_added" //when a component is added to a datum: (datum/component) #define COMSIG_COMPONENT_REMOVING "component_removing" //before a component is removed from a datum because of RemoveComponent: (datum/component) #define COMSIG_PARENT_QDELETED "parent_qdeleted" //before a datum's Destroy() is called: () -#define COMSIG_ATOM_ENTERED "atom_entered" //from base of atom/Entered(): (atom/movable, atom) -#define COMSIG_MOVABLE_CROSSED "movable_crossed" //from base of atom/movable/Crossed(): (atom/movable) +#define COMSIG_PARENT_ATTACKBY "atom_attackby" //from the base of atom/attackby: (obj/item, mob/living, params) +#define COMSIG_PARENT_EXAMINE "atom_examine" //from the base of atom/examine: (mob) +#define COMSIG_ATOM_ENTERED "atom_entered" //from base of atom/Entered(): (atom/movable, atom) +#define COMSIG_MOVABLE_CROSSED "movable_crossed" //from base of atom/movable/Crossed(): (atom/movable) \ No newline at end of file diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index f1ac1af1af..c8df2bd0b9 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -16,10 +16,10 @@ // No comment /atom/proc/attackby(obj/item/W, mob/user, params) - return + return SendSignal(COMSIG_PARENT_ATTACKBY, list(W, user, params), FALSE) /obj/attackby(obj/item/I, mob/living/user, params) - return I.attack_obj(src, user) + return ..() || I.attack_obj(src, user) /mob/living/attackby(obj/item/I, mob/user, params) user.changeNext_move(CLICK_CD_MELEE) diff --git a/code/datums/components.dm b/code/datums/components.dm new file mode 100644 index 0000000000..b9212d2786 --- /dev/null +++ b/code/datums/components.dm @@ -0,0 +1,97 @@ +/datum/component + var/enabled = TRUE // Enables or disables the components + var/dupe_mode = COMPONENT_DUPE_HIGHLANDER // How components of the same type are handled in the same parent + var/list/signal_procs // list of signals -> callbacks + var/datum/parent // parent datum + +/datum/component/New(datum/P, ...) + var/dm = dupe_mode + if(dm != COMPONENT_DUPE_ALLOWED) + var/datum/component/old = P.GetExactComponent(type) + if(old) + switch(dm) + if(COMPONENT_DUPE_HIGHLANDER) + P.RemoveComponent(old) + old = null //in case SendSignal() blocks + if(COMPONENT_DUPE_UNIQUE) + qdel(src) + return + P.SendSignal(COMSIG_COMPONENT_ADDED, list(src), FALSE) + LAZYADD(P.datum_components, src) + parent = P + +/datum/component/Destroy() + RemoveNoSignal() + return ..() + +/datum/component/proc/RemoveNoSignal() + var/datum/P = parent + if(P) + LAZYREMOVE(P.datum_components, src) + parent = null + +/datum/component/proc/RegisterSignal(sig_type, proc_on_self, override = FALSE) + var/list/procs = signal_procs + if(!procs) + procs = list() + signal_procs = procs + + if(!override) + . = procs[sig_type] + if(.) + stack_trace("[sig_type] overridden. Use override = TRUE to suppress this warning") + + procs[sig_type] = CALLBACK(src, proc_on_self) + +/datum/var/list/datum_components //list of /datum/component + +// Send a signal to all other components in the container. +/datum/proc/SendSignal(sigtype, list/sig_args, async = FALSE) + var/list/comps = datum_components + . = FALSE + for(var/I in comps) + var/datum/component/C = I + if(!C.enabled) + continue + var/list/sps = C.signal_procs + var/datum/callback/CB = LAZYACCESS(sps, sigtype) + if(!CB) + continue + if(!async) + . |= CB.Invoke(sig_args) + else + . |= CB.InvokeAsync(sig_args) + +/datum/proc/GetComponent(c_type) + for(var/I in datum_components) + if(istype(I, c_type)) + return I + +/datum/proc/GetExactComponent(c_type) + for(var/I in datum_components) + var/datum/component/C = I + if(C.type == c_type) + return I + +/datum/proc/GetComponents(c_type) + . = list() + for(var/I in datum_components) + if(istype(I, c_type)) + . += I + +/datum/proc/AddComponents(list/new_types) + for(var/new_type in new_types) + AddComponent(new_type) + +/datum/proc/AddComponent(new_type, ...) + var/nt = new_type + args[1] = src + var/datum/component/C = new nt(arglist(args)) + return QDELING(C) ? GetComponent(new_type) : C + +/datum/proc/RemoveComponent(datum/component/C) + if(!C) + return + C.RemoveNoSignal() + SendSignal(COMSIG_COMPONENT_REMOVING, list(C), FALSE) + qdel(C) diff --git a/code/datums/components/README.md b/code/datums/components/README.md index 93a846035f..e9e8301df6 100644 --- a/code/datums/components/README.md +++ b/code/datums/components/README.md @@ -105,4 +105,4 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo * Called when a component recieves any signal and is enabled * Default implementation looks if the signal is registered and runs the appropriate proc -### See/Define signals and their arguments in __DEFINES\components.dm +### See signals and their arguments in __DEFINES\components.dm diff --git a/code/datums/material_container.dm b/code/datums/components/material_container.dm similarity index 61% rename from code/datums/material_container.dm rename to code/datums/components/material_container.dm index a8863c70bc..dea7632391 100644 --- a/code/datums/material_container.dm +++ b/code/datums/components/material_container.dm @@ -5,22 +5,34 @@ amount - raw amount of the mineral this container is holding, calculated by the defined value MINERAL_MATERIAL_AMOUNT=2000. max_amount - max raw amount of mineral this container can hold. sheet_type - type of the mineral sheet the container handles, used for output. - owner - object that this container is being used by, used for output. + parent - object that this container is being used by, used for output. MAX_STACK_SIZE - size of a stack of mineral sheets. Constant. */ -/datum/material_container +/datum/component/material_container var/total_amount = 0 var/max_amount var/sheet_type - var/obj/owner - var/list/materials = list() + var/list/materials + var/show_on_examine + var/list/allowed_typecache + var/last_inserted_type + var/last_amount_inserted + var/last_insert_success + var/datum/callback/precondition //MAX_STACK_SIZE = 50 //MINERAL_MATERIAL_AMOUNT = 2000 -/datum/material_container/New(obj/O, list/mat_list, max_amt = 0) - owner = O +/datum/component/material_container/Initialize(list/mat_list, max_amt = 0, _show_on_examine = FALSE, list/allowed_types, datum/callback/_precondition) + materials = list() max_amount = max(0, max_amt) + show_on_examine = _show_on_examine + if(allowed_types) + allowed_typecache = typecacheof(allowed_types) + precondition = _precondition + + RegisterSignal(COMSIG_PARENT_ATTACKBY, .proc/OnAttackBy) + RegisterSignal(COMSIG_PARENT_EXAMINE, .proc/OnExamine) var/list/possible_mats = list() for(var/mat_type in subtypesof(/datum/material)) @@ -31,12 +43,47 @@ var/mat_path = possible_mats[id] materials[id] = new mat_path() -/datum/material_container/Destroy() - owner = null - return ..() +/datum/component/material_container/proc/OnExamine(mob/user) + for(var/I in materials) + var/datum/material/M = materials[I] + var/amt = amount(M.id) + if(amt) + to_chat(user, "It has [amt] units of [lowertext(M.name)] stored.") + +/datum/component/material_container/proc/OnAttackBy(obj/item/I, mob/living/user) + var/list/tc = allowed_typecache + if(user.a_intent == INTENT_HARM || (I.flags_2 & HOLOGRAM_2) || (tc && !is_type_in_typecache(I, tc))) + return FALSE + . = TRUE + last_insert_success = FALSE + var/datum/callback/pc = precondition + if(pc && !pc.Invoke()) + return + var/material_amount = get_item_material_amount(I) + if(!material_amount) + to_chat(user, "[I] does not contain sufficient amounts of metal or glass to be accepted by [parent].") + return + if(!has_space(material_amount)) + to_chat(user, "[parent] is full. Please remove metal or glass from [parent] in order to insert more.") + return + if(!user.temporarilyRemoveItemFromInventory(I)) + to_chat(user, "[I] is stuck to you and cannot be placed into [parent].") + return + var/inserted = insert_item(I) + if(inserted) + last_insert_success = TRUE + if(istype(I, /obj/item/stack)) + to_chat(user, "You insert [inserted] sheet[inserted>1 ? "s" : ""] into [parent].") + if(!QDELETED(I)) + user.put_in_active_hand(I) + else + to_chat(user, "You insert a material total of [inserted] into [parent].") + qdel(I) + else + user.put_in_active_hand(I) //For inserting an amount of material -/datum/material_container/proc/insert_amount(amt, id = null) +/datum/component/material_container/proc/insert_amount(amt, id = null) if(amt > 0 && has_space(amt)) var/total_amount_saved = total_amount if(id) @@ -52,7 +99,7 @@ return (total_amount - total_amount_saved) return 0 -/datum/material_container/proc/insert_stack(obj/item/stack/S, amt = 0) +/datum/component/material_container/proc/insert_stack(obj/item/stack/S, amt = 0) if(amt <= 0) return 0 if(amt > S.amount) @@ -67,10 +114,12 @@ return 0 insert_materials(S,amt) + last_inserted_type = S.type S.use(amt) + last_amount_inserted = amt return amt -/datum/material_container/proc/insert_item(obj/item/I, multiplier = 1) +/datum/component/material_container/proc/insert_item(obj/item/I, multiplier = 1) if(!I) return 0 if(istype(I, /obj/item/stack)) @@ -82,9 +131,11 @@ return 0 insert_materials(I, multiplier) + last_inserted_type = I.type + last_amount_inserted = material_amount return material_amount -/datum/material_container/proc/insert_materials(obj/item/I, multiplier = 1) //for internal usage only +/datum/component/material_container/proc/insert_materials(obj/item/I, multiplier = 1) //for internal usage only var/datum/material/M for(var/MAT in materials) M = materials[MAT] @@ -93,7 +144,7 @@ //For consuming material //mats is a list of types of material to use and the corresponding amounts, example: list(MAT_METAL=100, MAT_GLASS=200) -/datum/material_container/proc/use_amount(list/mats, multiplier=1) +/datum/component/material_container/proc/use_amount(list/mats, multiplier=1) if(!mats || !mats.len) return 0 @@ -112,7 +163,7 @@ return total_amount_save - total_amount -/datum/material_container/proc/use_amount_type(amt, id) +/datum/component/material_container/proc/use_amount_type(amt, id) var/datum/material/M = materials[id] if(M) if(M.amount >= amt) @@ -121,7 +172,7 @@ return amt return 0 -/datum/material_container/proc/can_use_amount(amt, id, list/mats) +/datum/component/material_container/proc/can_use_amount(amt, id, list/mats) if(amt && id) var/datum/material/M = materials[id] if(M && M.amount >= amt) @@ -136,7 +187,7 @@ return FALSE //For spawning mineral sheets; internal use only -/datum/material_container/proc/retrieve(sheet_amt, datum/material/M, target = null) +/datum/component/material_container/proc/retrieve(sheet_amt, datum/material/M, target = null) if(!M.sheet_type) return 0 if(sheet_amt > 0) @@ -144,12 +195,12 @@ sheet_amt = round(M.amount / MINERAL_MATERIAL_AMOUNT) var/count = 0 while(sheet_amt > MAX_STACK_SIZE) - new M.sheet_type(get_turf(owner), MAX_STACK_SIZE) + new M.sheet_type(get_turf(parent), MAX_STACK_SIZE) count += MAX_STACK_SIZE use_amount_type(sheet_amt * MINERAL_MATERIAL_AMOUNT, M.id) sheet_amt -= MAX_STACK_SIZE if(round((sheet_amt * MINERAL_MATERIAL_AMOUNT) / MINERAL_MATERIAL_AMOUNT)) - var/obj/item/stack/sheet/s = new M.sheet_type(get_turf(owner), sheet_amt) + var/obj/item/stack/sheet/s = new M.sheet_type(get_turf(parent), sheet_amt) if(target) s.forceMove(target) count += sheet_amt @@ -157,15 +208,15 @@ return count return 0 -/datum/material_container/proc/retrieve_sheets(sheet_amt, id, target = null) +/datum/component/material_container/proc/retrieve_sheets(sheet_amt, id, target = null) if(materials[id]) return retrieve(sheet_amt, materials[id], target) return 0 -/datum/material_container/proc/retrieve_amount(amt, id, target) +/datum/component/material_container/proc/retrieve_amount(amt, id, target) return retrieve_sheets(amount2sheet(amt), id, target) -/datum/material_container/proc/retrieve_all(target = null) +/datum/component/material_container/proc/retrieve_all(target = null) var/result = 0 var/datum/material/M for(var/MAT in materials) @@ -173,10 +224,10 @@ result += retrieve_sheets(amount2sheet(M.amount), MAT, target) return result -/datum/material_container/proc/has_space(amt = 0) +/datum/component/material_container/proc/has_space(amt = 0) return (total_amount + amt) <= max_amount -/datum/material_container/proc/has_materials(list/mats, multiplier=1) +/datum/component/material_container/proc/has_materials(list/mats, multiplier=1) if(!mats || !mats.len) return 0 @@ -187,23 +238,23 @@ return 0 return 1 -/datum/material_container/proc/amount2sheet(amt) +/datum/component/material_container/proc/amount2sheet(amt) if(amt >= MINERAL_MATERIAL_AMOUNT) return round(amt / MINERAL_MATERIAL_AMOUNT) return 0 -/datum/material_container/proc/sheet2amount(sheet_amt) +/datum/component/material_container/proc/sheet2amount(sheet_amt) if(sheet_amt > 0) return sheet_amt * MINERAL_MATERIAL_AMOUNT return 0 -/datum/material_container/proc/amount(id) +/datum/component/material_container/proc/amount(id) var/datum/material/M = materials[id] return M ? M.amount : 0 //returns the amount of material relevant to this container; //if this container does not support glass, any glass in 'I' will not be taken into account -/datum/material_container/proc/get_item_material_amount(obj/item/I) +/datum/component/material_container/proc/get_item_material_amount(obj/item/I) if(!istype(I)) return 0 var/material_amount = 0 @@ -278,4 +329,4 @@ /datum/material/biomass name = "Biomass" - id = MAT_BIOMASS + id = MAT_BIOMASS \ No newline at end of file diff --git a/code/datums/components/powered.dm b/code/datums/components/powered.dm new file mode 100644 index 0000000000..b4233cddbe --- /dev/null +++ b/code/datums/components/powered.dm @@ -0,0 +1,6 @@ +//These components require a powered machine as a parent to run +/datum/component/powered + +/datum/component/powered/ReceiveSignal(sigtype, list/sig_args, async) + var/obj/machinery/M = parent + return M.is_operational() && ..() diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 272ec34d94..d52c298d9d 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -290,6 +290,7 @@ to_chat(user, "[total_volume] units of various reagents") else to_chat(user, "Nothing.") + SendSignal(COMSIG_PARENT_EXAMINE, list(user), FALSE) /atom/proc/relaymove() return diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index c185a8f734..42cf20907c 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -32,8 +32,6 @@ var/selected_category var/screen = 1 - var/datum/material_container/materials - var/list/categories = list( "Tools", "Electronics", @@ -48,15 +46,15 @@ ) /obj/machinery/autolathe/Initialize() - materials = new /datum/material_container(src, list(MAT_METAL, MAT_GLASS)) + AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS)) + . = ..() + wires = new /datum/wires/autolathe(src) files = new /datum/research/autolathe(src) matching_designs = list() - return ..() /obj/machinery/autolathe/Destroy() QDEL_NULL(wires) - QDEL_NULL(materials) return ..() /obj/machinery/autolathe/interact(mob/user) @@ -81,6 +79,7 @@ popup.open() /obj/machinery/autolathe/on_deconstruction() + GET_COMPONENT(materials, /datum/component/material_container) materials.retrieve_all() /obj/machinery/autolathe/attackby(obj/item/O, mob/user, params) @@ -123,42 +122,26 @@ busy = FALSE return 1 - if(O.flags_2 & HOLOGRAM_2) - return 1 + return ..() - var/material_amount = materials.get_item_material_amount(O) - if(!material_amount) - to_chat(user, "This object does not contain sufficient amounts of metal or glass to be accepted by the autolathe.") - return 1 - if(!materials.has_space(material_amount)) - to_chat(user, "The autolathe is full. Please remove metal or glass from the autolathe in order to insert more.") - return 1 - if(!user.temporarilyRemoveItemFromInventory(O)) - to_chat(user, "\The [O] is stuck to you and cannot be placed into the autolathe.") - return 1 - - busy = TRUE - var/inserted = materials.insert_item(O) - if(inserted) - if(istype(O, /obj/item/stack)) - if (O.materials[MAT_METAL]) - flick("autolathe_o",src)//plays metal insertion animation - if (O.materials[MAT_GLASS]) - flick("autolathe_r",src)//plays glass insertion animation - to_chat(user, "You insert [inserted] sheet[inserted>1 ? "s" : ""] to the autolathe.") - use_power(inserted*100) - if(!QDELETED(O)) - user.put_in_active_hand(O) +/obj/machinery/mecha_part_fabricator/ComponentActivated(datum/component/C) + ..() + if(istype(C, /datum/component/material_container)) + var/datum/component/material_container/M = C + if(!M.last_insert_success) + return + var/lit = M.last_inserted_type + if(ispath(lit, /obj/item/ore/bluespace_crystal)) + use_power(max(500,M.last_amount_inserted/10)) else - to_chat(user, "You insert a material total of [inserted] to the autolathe.") - use_power(max(500,inserted/10)) - qdel(O) - else - user.put_in_active_hand(O) - - busy = FALSE - updateUsrDialog() - return 1 + var/obj/item/stack/S = lit + var/list/initmats = initial(S.materials) + if (initmats[MAT_METAL]) + flick("autolathe_o",src)//plays metal insertion animation + if (initmats[MAT_GLASS]) + flick("autolathe_r",src)//plays glass insertion animation + use_power(M.last_amount_inserted*100) + updateUsrDialog() /obj/machinery/autolathe/Topic(href, href_list) if(..()) @@ -193,6 +176,7 @@ var/power = max(2000, (metal_cost+glass_cost)*multiplier/5) + GET_COMPONENT(materials, /datum/component/material_container) if((materials.amount(MAT_METAL) >= metal_cost*multiplier*coeff) && (materials.amount(MAT_GLASS) >= glass_cost*multiplier*coeff)) busy = TRUE use_power(power) @@ -246,6 +230,7 @@ var/T = 0 for(var/obj/item/stock_parts/matter_bin/MB in component_parts) T += MB.rating*75000 + GET_COMPONENT(materials, /datum/component/material_container) materials.max_amount = T T=1.2 for(var/obj/item/stock_parts/manipulator/M in component_parts) @@ -294,6 +279,7 @@ dat += "[D.name]" if(ispath(D.build_path, /obj/item/stack)) + GET_COMPONENT(materials, /datum/component/material_container) var/max_multiplier = min(D.maxstack, D.materials[MAT_METAL] ?round(materials.amount(MAT_METAL)/D.materials[MAT_METAL]):INFINITY,D.materials[MAT_GLASS]?round(materials.amount(MAT_GLASS)/D.materials[MAT_GLASS]):INFINITY) if (max_multiplier>10 && !disabled) dat += " x10" @@ -325,6 +311,7 @@ dat += "[D.name]" if(ispath(D.build_path, /obj/item/stack)) + GET_COMPONENT(materials, /datum/component/material_container) var/max_multiplier = min(D.maxstack, D.materials[MAT_METAL] ?round(materials.amount(MAT_METAL)/D.materials[MAT_METAL]):INFINITY,D.materials[MAT_GLASS]?round(materials.amount(MAT_GLASS)/D.materials[MAT_GLASS]):INFINITY) if (max_multiplier>10 && !disabled) dat += " x10" @@ -339,6 +326,7 @@ return dat /obj/machinery/autolathe/proc/materials_printout() + GET_COMPONENT(materials, /datum/component/material_container) var/dat = "Total amount: [materials.total_amount] / [materials.max_amount] cm3
" for(var/mat_id in materials.materials) var/datum/material/M = materials.materials[mat_id] @@ -351,6 +339,7 @@ var/coeff = (ispath(D.build_path, /obj/item/stack) ? 1 : prod_coeff) + GET_COMPONENT(materials, /datum/component/material_container) if(D.materials[MAT_METAL] && (materials.amount(MAT_METAL) < (D.materials[MAT_METAL] * coeff * amount))) return 0 if(D.materials[MAT_GLASS] && (materials.amount(MAT_GLASS) < (D.materials[MAT_GLASS] * coeff * amount))) @@ -403,4 +392,4 @@ //Called when the object is constructed by an autolathe //Has a reference to the autolathe so you can do !!FUN!! things with hacked lathes /obj/item/proc/autolathe_crafted(obj/machinery/autolathe/A) - return + return \ No newline at end of file diff --git a/code/game/machinery/droneDispenser.dm b/code/game/machinery/droneDispenser.dm index 31643fa177..013c606ab7 100644 --- a/code/game/machinery/droneDispenser.dm +++ b/code/game/machinery/droneDispenser.dm @@ -22,7 +22,6 @@ var/icon_recharging = "recharge" var/icon_creating = "make" - var/datum/material_container/materials var/list/using_materials var/starting_amount = 0 var/metal_cost = 1000 @@ -55,14 +54,10 @@ /obj/machinery/droneDispenser/Initialize() . = ..() - materials = new(src, list(MAT_METAL, MAT_GLASS), MINERAL_MATERIAL_AMOUNT*MAX_STACK_SIZE*2) + var/datum/component/material_container/materials = AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS), MINERAL_MATERIAL_AMOUNT * MAX_STACK_SIZE * 2, TRUE) materials.insert_amount(starting_amount) using_materials = list(MAT_METAL=metal_cost, MAT_GLASS=glass_cost) -/obj/machinery/droneDispenser/Destroy() - QDEL_NULL(materials) - return ..() - /obj/machinery/droneDispenser/preloaded starting_amount = 5000 @@ -148,10 +143,6 @@ ..() if((mode == DRONE_RECHARGING) && !stat && recharging_text) to_chat(user, "[recharging_text]") - if(metal_cost) - to_chat(user, "It has [materials.amount(MAT_METAL)] units of metal stored.") - if(glass_cost) - to_chat(user, "It has [materials.amount(MAT_GLASS)] units of glass stored.") /obj/machinery/droneDispenser/power_change() ..() @@ -166,6 +157,7 @@ if((stat & (NOPOWER|BROKEN)) || !anchored) return + GET_COMPONENT(materials, /datum/component/material_container) if(!materials.has_materials(using_materials)) return // We require more minerals @@ -232,25 +224,8 @@ icon_state = icon_on /obj/machinery/droneDispenser/attackby(obj/item/O, mob/living/user) - if(istype(O, /obj/item/stack)) - if(!O.materials[MAT_METAL] && !O.materials[MAT_GLASS]) - return ..() - if(!metal_cost && !glass_cost) - to_chat(user, "There isn't a place to insert [O]!") - return - var/obj/item/stack/sheets = O - if(!user.canUnEquip(sheets)) - to_chat(user, "[O] is stuck to your hand, you can't get it off!") - return - - var/used = materials.insert_stack(sheets, sheets.amount) - - if(used) - to_chat(user, "You insert [used] sheet[used > 1 ? "s" : ""] into [src].") - else - to_chat(user, "The [src] isn't accepting the [sheets].") - - else if(istype(O, /obj/item/crowbar)) + if(istype(O, /obj/item/crowbar)) + GET_COMPONENT(materials, /datum/component/material_container) materials.retrieve_all() playsound(loc, O.usesound, 50, 1) to_chat(user, "You retrieve the materials from [src].") @@ -309,4 +284,4 @@ #undef DRONE_PRODUCTION #undef DRONE_RECHARGING -#undef DRONE_READY +#undef DRONE_READY \ No newline at end of file diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm index b4bee2bdae..24e15366d4 100644 --- a/code/game/machinery/recycler.dm +++ b/code/game/machinery/recycler.dm @@ -14,15 +14,14 @@ var/blood = 0 var/eat_dir = WEST var/amount_produced = 50 - var/datum/material_container/materials var/crush_damage = 1000 var/eat_victim_items = TRUE var/item_recycle_sound = 'sound/items/welder.ogg' /obj/machinery/recycler/Initialize() - materials = new /datum/material_container(src, list(MAT_METAL, MAT_GLASS, MAT_PLASMA, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM)) + AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS, MAT_PLASMA, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM)) + . = ..() update_icon() - return ..() /obj/machinery/recycler/RefreshParts() var/amt_made = 0 @@ -32,6 +31,7 @@ mat_mod *= 50000 for(var/obj/item/stock_parts/manipulator/M in component_parts) amt_made = 12.5 * M.rating //% of materials salvaged + GET_COMPONENT(materials, /datum/component/material_container) materials.max_amount = mat_mod amount_produced = min(50, amt_made) + 50 @@ -126,6 +126,7 @@ /obj/machinery/recycler/proc/recycle_item(obj/item/I) I.loc = src.loc + GET_COMPONENT(materials, /datum/component/material_container) var/material_amount = materials.get_item_material_amount(I) if(!material_amount) qdel(I) @@ -193,4 +194,4 @@ name = "paper - 'garbage duty instructions'" info = "

New Assignment

You have been assigned to collect garbage from trash bins, located around the station. The crewmembers will put their trash into it and you will collect the said trash.

There is a recycling machine near your closet, inside maintenance; use it to recycle the trash for a small chance to get useful minerals. Then deliver these minerals to cargo or engineering. You are our last hope for a clean station, do not screw this up!" -#undef SAFETY_COOLDOWN +#undef SAFETY_COOLDOWN \ No newline at end of file diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm index 14efd0a610..38f436f10d 100644 --- a/code/game/mecha/mech_fabricator.dm +++ b/code/game/mecha/mech_fabricator.dm @@ -12,7 +12,6 @@ circuit = /obj/item/circuitboard/machine/mechfab var/time_coeff = 1 var/component_coeff = 1 - var/datum/material_container/materials var/datum/research/files var/sync = 0 var/part_set @@ -36,9 +35,11 @@ ) /obj/machinery/mecha_part_fabricator/Initialize() + AddComponent(/datum/component/material_container, + list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE), + FALSE, list(/obj/item/stack, /obj/item/ore/bluespace_crystal), CALLBACK(src, .proc/is_insertion_ready)) + . = ..() files = new /datum/research(src) //Setup the research data holder. - materials = new(src, list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE)) - return ..() /obj/machinery/mecha_part_fabricator/RefreshParts() var/T = 0 @@ -46,6 +47,7 @@ //maximum stocking amount (default 300000, 600000 at T4) for(var/obj/item/stock_parts/matter_bin/M in component_parts) T += M.rating + GET_COMPONENT(materials, /datum/component/material_container) materials.max_amount = (200000 + (T*50000)) //resources adjustment coefficient (1 -> 0.85 -> 0.7 -> 0.55) @@ -113,6 +115,7 @@ /obj/machinery/mecha_part_fabricator/proc/output_available_resources() var/output + GET_COMPONENT(materials, /datum/component/material_container) for(var/mat_id in materials.materials) var/datum/material/M = materials.materials[mat_id] output += "[M.name]: [M.amount] cm³" @@ -133,6 +136,7 @@ /obj/machinery/mecha_part_fabricator/proc/check_resources(datum/design/D) if(D.reagents_list.len) // No reagents storage - no reagent designs. return 0 + GET_COMPONENT(materials, /datum/component/material_container) if(materials.has_materials(get_resources_w_coeff(D))) return 1 return 0 @@ -142,6 +146,7 @@ desc = "It's building \a [initial(D.name)]." var/list/res_coef = get_resources_w_coeff(D) + GET_COMPONENT(materials, /datum/component/material_container) materials.use_amount(res_coef) add_overlay("fab-active") use_power = ACTIVE_POWER_USE @@ -398,15 +403,34 @@ break if(href_list["remove_mat"] && href_list["material"]) + GET_COMPONENT(materials, /datum/component/material_container) materials.retrieve_sheets(text2num(href_list["remove_mat"]), href_list["material"]) updateUsrDialog() return /obj/machinery/mecha_part_fabricator/on_deconstruction() + GET_COMPONENT(materials, /datum/component/material_container) materials.retrieve_all() ..() +/obj/machinery/mecha_part_fabricator/ComponentActivated(datum/component/C) + ..() + if(istype(C, /datum/component/material_container)) + var/datum/component/material_container/M = C + if(!M.last_insert_success) + return + var/lit = M.last_inserted_type + var/stack_name + if(ispath(lit, /obj/item/ore/bluespace_crystal)) + stack_name = "bluespace" + else + var/obj/item/stack/S = lit + stack_name = material2name(initial(S.materials)[1]) + add_overlay("fab-load-[stack_name]") + addtimer(CALLBACK(src, /atom/proc/cut_overlay, "fab-load-[stack_name]"), 10) + updateUsrDialog() + /obj/machinery/mecha_part_fabricator/attackby(obj/item/W, mob/user, params) if(default_deconstruction_screwdriver(user, "fab-o", "fab-idle", W)) return 1 @@ -417,55 +441,7 @@ if(default_deconstruction_crowbar(W)) return 1 - if(istype(W, /obj/item/stack/sheet)) - - if(!is_insertion_ready(user)) - return 1 - - var/material_amount = materials.get_item_material_amount(W) - - if(!try_insert(user, W, material_amount)) - return 1 - - var/inserted = materials.insert_item(W) - if(inserted) - to_chat(user, "You insert [inserted] sheet\s into [src].") - if(W && W.materials.len) - if(!QDELETED(W)) - user.put_in_active_hand(W) - var/mat_overlay = "fab-load-[material2name(W.materials[1])]" - add_overlay(mat_overlay) - sleep(10) - if(!QDELETED(src)) - cut_overlay(mat_overlay) //No matter what the overlay shall still be deleted - - updateUsrDialog() - - else if(istype(W, /obj/item/ore/bluespace_crystal)) - - if(!is_insertion_ready(user)) - return 1 - - var/material_amount = materials.get_item_material_amount(W) - - if(!try_insert(user, W, material_amount)) - return 1 - - var/inserted = materials.insert_item(W) - if(inserted) - to_chat(user, "You add [W] to the [src].") - if(W && W.materials.len) - qdel(W) - var/mat_overlay = "fab-load-bluespace" - add_overlay(mat_overlay) - sleep(10) - if(!QDELETED(src)) - cut_overlay(mat_overlay) - - updateUsrDialog() - - else - return ..() + return ..() /obj/machinery/mecha_part_fabricator/proc/material2name(ID) return copytext(ID,2) @@ -478,18 +454,4 @@ to_chat(user, "\The [src] is currently processing! Please wait until completion.") return FALSE - return TRUE - - -/obj/machinery/mecha_part_fabricator/proc/try_insert(mob/user, obj/item/I, material_amount) - if(!material_amount) - to_chat(user, "This object does not contain sufficient amounts of materials to be accepted by [src].") - return FALSE - if(!materials.has_space(material_amount)) - to_chat(user, "\The [src] is full. Please remove some materials from [src] in order to insert more.") - return FALSE - if(!user.temporarilyRemoveItemFromInventory(I)) - to_chat(user, "\The [I] is stuck to you and cannot be placed into [src].") - return FALSE - return TRUE \ No newline at end of file diff --git a/code/modules/clothing/shoes/bananashoes.dm b/code/modules/clothing/shoes/bananashoes.dm index e10f089eb8..175710365c 100644 --- a/code/modules/clothing/shoes/bananashoes.dm +++ b/code/modules/clothing/shoes/bananashoes.dm @@ -5,12 +5,11 @@ desc = "Lost prototype of advanced clown tech. Powered by bananium, these shoes leave a trail of chaos in their wake." icon_state = "clown_prototype_off" var/on = FALSE - var/datum/material_container/bananium actions_types = list(/datum/action/item_action/toggle) -/obj/item/clothing/shoes/clown_shoes/banana_shoes/New() - ..() - bananium = new/datum/material_container(src,list(MAT_BANANIUM),200000) +/obj/item/clothing/shoes/clown_shoes/banana_shoes/Initialize() + . = ..() + AddComponent(/datum/component/material_container, list(MAT_BANANIUM), 200000, TRUE) /obj/item/clothing/shoes/clown_shoes/banana_shoes/step_action() if(on) @@ -21,6 +20,7 @@ footstep++ new/obj/item/grown/bananapeel/specialpeel(get_step(src,turn(usr.dir, 180))) //honk + GET_COMPONENT(bananium, /datum/component/material_container) bananium.use_amount_type(100, MAT_BANANIUM) if(bananium.amount(MAT_BANANIUM) < 100) on = !on @@ -31,33 +31,19 @@ ..() /obj/item/clothing/shoes/clown_shoes/banana_shoes/attack_self(mob/user) + GET_COMPONENT(bananium, /datum/component/material_container) var/sheet_amount = bananium.retrieve_all() if(sheet_amount) to_chat(user, "You retrieve [sheet_amount] sheets of bananium from the prototype shoes.") else to_chat(user, "You cannot retrieve any bananium from the prototype shoes.") -/obj/item/clothing/shoes/clown_shoes/banana_shoes/attackby(obj/item/O, mob/user, params) - if(!bananium.get_item_material_amount(O)) - to_chat(user, "This item has no bananium!") - return - if(!user.dropItemToGround(O)) - to_chat(user, "You can't drop [O]!") - return - - var/bananium_amount = bananium.insert_item(O) - if(bananium_amount) - to_chat(user, "You insert [O] into the prototype shoes.") - qdel(O) - else - to_chat(user, "You are unable to insert more bananium!") - /obj/item/clothing/shoes/clown_shoes/banana_shoes/examine(mob/user) ..() - var/ban_amt = bananium.amount(MAT_BANANIUM) - to_chat(user, "The shoes are [on ? "enabled" : "disabled"]. There is [ban_amt ? ban_amt : "no"] bananium left.") + to_chat(user, "The shoes are [on ? "enabled" : "disabled"]") /obj/item/clothing/shoes/clown_shoes/banana_shoes/ui_action_click(mob/user) + GET_COMPONENT(bananium, /datum/component/material_container) if(bananium.amount(MAT_BANANIUM)) on = !on update_icon() @@ -77,4 +63,4 @@ usr.update_inv_shoes() for(var/X in actions) var/datum/action/A = X - A.UpdateButtonIcon() + A.UpdateButtonIcon() \ No newline at end of file diff --git a/code/modules/mining/machine_processing.dm b/code/modules/mining/machine_processing.dm index 8428036860..0927a0ba88 100644 --- a/code/modules/mining/machine_processing.dm +++ b/code/modules/mining/machine_processing.dm @@ -66,7 +66,6 @@ density = TRUE anchored = TRUE var/obj/machinery/mineral/CONSOLE = null - var/datum/material_container/materials var/on = FALSE var/selected_material = MAT_METAL var/selected_alloy = null @@ -75,12 +74,11 @@ /obj/machinery/mineral/processing_unit/Initialize() . = ..() proximity_monitor = new(src, 1) - materials = new(src, list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE),INFINITY) + AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE), INFINITY) files = new /datum/research/smelter(src) /obj/machinery/mineral/processing_unit/Destroy() CONSOLE = null - QDEL_NULL(materials) QDEL_NULL(files) return ..() @@ -89,6 +87,7 @@ process_ore(AM) /obj/machinery/mineral/processing_unit/proc/process_ore(obj/item/ore/O) + GET_COMPONENT(materials, /datum/component/material_container) var/material_amount = materials.get_item_material_amount(O) if(!materials.has_space(material_amount)) unload_mineral(O) @@ -100,6 +99,7 @@ /obj/machinery/mineral/processing_unit/proc/get_machine_data() var/dat = "Smelter control console

" + GET_COMPONENT(materials, /datum/component/material_container) for(var/mat_id in materials.materials) var/datum/material/M = materials.materials[mat_id] dat += "[M.name]: [M.amount] cm³" @@ -165,6 +165,7 @@ continue*/ /obj/machinery/mineral/processing_unit/proc/smelt_ore() + GET_COMPONENT(materials, /datum/component/material_container) var/datum/material/mat = materials.materials[selected_material] if(mat) var/sheets_to_remove = (mat.amount >= (MINERAL_MATERIAL_AMOUNT * SMELT_AMOUNT) ) ? SMELT_AMOUNT : round(mat.amount / MINERAL_MATERIAL_AMOUNT) @@ -187,6 +188,7 @@ on = FALSE return + GET_COMPONENT(materials, /datum/component/material_container) materials.use_amount(alloy.materials, amount) generate_mineral(alloy.build_path) @@ -197,6 +199,7 @@ var/build_amount = SMELT_AMOUNT + GET_COMPONENT(materials, /datum/component/material_container) for(var/mat_id in D.materials) var/M = D.materials[mat_id] @@ -214,6 +217,7 @@ unload_mineral(O) /obj/machinery/mineral/processing_unit/on_deconstruction() + GET_COMPONENT(materials, /datum/component/material_container) materials.retrieve_all() ..() diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm index 9726022afc..9c0cd2e146 100644 --- a/code/modules/mining/machine_redemption.dm +++ b/code/modules/mining/machine_redemption.dm @@ -22,17 +22,15 @@ var/list/ore_values = list(MAT_GLASS = 1, MAT_METAL = 1, MAT_PLASMA = 15, MAT_SILVER = 16, MAT_GOLD = 18, MAT_TITANIUM = 30, MAT_URANIUM = 30, MAT_DIAMOND = 50, MAT_BLUESPACE = 50, MAT_BANANIUM = 60) var/message_sent = FALSE var/list/ore_buffer = list() - var/datum/material_container/materials var/datum/research/files var/obj/item/disk/design_disk/inserted_disk /obj/machinery/mineral/ore_redemption/Initialize() . = ..() - materials = new(src, list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE),INFINITY) + AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE),INFINITY) files = new /datum/research/smelter(src) /obj/machinery/mineral/ore_redemption/Destroy() - QDEL_NULL(materials) QDEL_NULL(files) return ..() @@ -57,6 +55,7 @@ if(O && O.refined_type) points += O.points * point_upgrade + GET_COMPONENT(materials, /datum/component/material_container) var/material_amount = materials.get_item_material_amount(O) if(!material_amount) @@ -75,6 +74,7 @@ var/build_amount = 0 + GET_COMPONENT(materials, /datum/component/material_container) for(var/mat_id in D.materials) var/M = D.materials[mat_id] var/datum/material/redemption_mat = materials.materials[mat_id] @@ -110,6 +110,7 @@ var/has_minerals = FALSE + GET_COMPONENT(materials, /datum/component/material_container) for(var/mat_id in materials.materials) var/datum/material/M = materials.materials[mat_id] var/mineral_amount = M.amount / MINERAL_MATERIAL_AMOUNT @@ -148,6 +149,7 @@ /obj/machinery/mineral/ore_redemption/attackby(obj/item/W, mob/user, params) if(exchange_parts(user, W)) return + GET_COMPONENT(materials, /datum/component/material_container) if(default_pry_open(W)) materials.retrieve_all() return @@ -181,16 +183,10 @@ if(user.transferItemToLoc(W, src)) inserted_disk = W return TRUE - - if(istype(W, /obj/item/stack/sheet)) - var/obj/item/stack/sheet/S = W - var/inserted = materials.insert_stack(S, S.amount) - to_chat(user, "You add [inserted] [S] sheets to \the [src].") - return - return ..() /obj/machinery/mineral/ore_redemption/on_deconstruction() + GET_COMPONENT(materials, /datum/component/material_container) materials.retrieve_all() ..() @@ -213,6 +209,7 @@ data["claimedPoints"] = inserted_id.mining_points data["materials"] = list() + GET_COMPONENT(materials, /datum/component/material_container) for(var/mat_id in materials.materials) var/datum/material/M = materials.materials[mat_id] var/sheet_amount = M.amount ? M.amount / MINERAL_MATERIAL_AMOUNT : "0" @@ -236,6 +233,7 @@ /obj/machinery/mineral/ore_redemption/ui_act(action, params) if(..()) return + GET_COMPONENT(materials, /datum/component/material_container) switch(action) if("Eject") if(!inserted_id) @@ -354,4 +352,4 @@ icon_state = initial(icon_state) else icon_state = "[initial(icon_state)]-off" - return + return \ No newline at end of file diff --git a/code/modules/mining/mint.dm b/code/modules/mining/mint.dm index e48db7c6fd..13f7d56cd8 100644 --- a/code/modules/mining/mint.dm +++ b/code/modules/mining/mint.dm @@ -5,37 +5,32 @@ name = "coin press" icon = 'icons/obj/economy.dmi' icon_state = "coinpress0" - density = TRUE - anchored = TRUE - var/datum/material_container/materials + density = TRUE + anchored = TRUE var/newCoins = 0 //how many coins the machine made in it's last load - var/processing = FALSE + var/processing = FALSE var/chosen = MAT_METAL //which material will be used to make coins var/coinsToProduce = 10 speed_process = 1 -/obj/machinery/mineral/mint/Initialize() - . = ..() - materials = new /datum/material_container(src, - list(MAT_METAL, MAT_PLASMA, MAT_SILVER, MAT_GOLD, MAT_URANIUM, MAT_DIAMOND, MAT_BANANIUM), - max_amt = MINERAL_MATERIAL_AMOUNT*50) - -/obj/machinery/mineral/mint/Destroy() - QDEL_NULL(materials) - return ..() +/obj/machinery/mineral/mint/Initialize() + . = ..() + AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_PLASMA, MAT_SILVER, MAT_GOLD, MAT_URANIUM, MAT_DIAMOND, MAT_BANANIUM), MINERAL_MATERIAL_AMOUNT * 50) /obj/machinery/mineral/mint/process() var/turf/T = get_step(src, input_dir) if(!T) return - + + GET_COMPONENT(materials, /datum/component/material_container) for(var/obj/item/stack/sheet/O in T) materials.insert_stack(O, O.amount) /obj/machinery/mineral/mint/attack_hand(mob/user) var/dat = "Coin Press
" + GET_COMPONENT(materials, /datum/component/material_container) for(var/mat_id in materials.materials) var/datum/material/M = materials.materials[mat_id] if(!M.amount && chosen != mat_id) @@ -68,6 +63,7 @@ if(processing==1) to_chat(usr, "The machine is processing.") return + GET_COMPONENT(materials, /datum/component/material_container) if(href_list["choose"]) if(materials.materials[href_list["choose"]]) chosen = href_list["choose"] @@ -75,7 +71,7 @@ coinsToProduce = Clamp(coinsToProduce + text2num(href_list["chooseAmt"]), 0, 1000) if(href_list["makeCoins"]) var/temp_coins = coinsToProduce - processing = TRUE + processing = TRUE icon_state = "coinpress1" var/coin_mat = MINERAL_MATERIAL_AMOUNT * 0.2 var/datum/material/M = materials.materials[chosen] @@ -91,7 +87,7 @@ sleep(5) icon_state = "coinpress0" - processing = FALSE + processing = FALSE coinsToProduce = temp_coins src.updateUsrDialog() return diff --git a/code/modules/research/circuitprinter.dm b/code/modules/research/circuitprinter.dm index ad2345afe5..344f0cec76 100644 --- a/code/modules/research/circuitprinter.dm +++ b/code/modules/research/circuitprinter.dm @@ -11,7 +11,6 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis). container_type = OPENCONTAINER_1 circuit = /obj/item/circuitboard/machine/circuit_imprinter - var/datum/material_container/materials var/efficiency_coeff var/list/categories = list( @@ -29,20 +28,18 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis). ) /obj/machinery/r_n_d/circuit_imprinter/Initialize() - materials = new(src, list(MAT_GLASS, MAT_GOLD, MAT_DIAMOND, MAT_METAL, MAT_BLUESPACE)) + AddComponent(/datum/component/material_container, list(MAT_GLASS, MAT_GOLD, MAT_DIAMOND, MAT_METAL, MAT_BLUESPACE), + FALSE, list(/obj/item/stack, /obj/item/ore/bluespace_crystal), CALLBACK(src, .proc/is_insertion_ready)) create_reagents(0) return ..() -/obj/machinery/r_n_d/circuit_imprinter/Destroy() - QDEL_NULL(materials) - return ..() - /obj/machinery/r_n_d/circuit_imprinter/RefreshParts() reagents.maximum_volume = 0 for(var/obj/item/reagent_containers/glass/G in component_parts) reagents.maximum_volume += G.volume G.reagents.trans_to(src, G.reagents.total_volume) + GET_COMPONENT(materials, /datum/component/material_container) materials.max_amount = 0 for(var/obj/item/stock_parts/matter_bin/M in component_parts) materials.max_amount += M.rating * 75000 @@ -59,6 +56,7 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis). /obj/machinery/r_n_d/circuit_imprinter/proc/check_mat(datum/design/being_built, M) // now returns how many times the item can be built with the material var/list/all_materials = being_built.reagents_list + being_built.materials + GET_COMPONENT(materials, /datum/component/material_container) var/A = materials.amount(M) if(!A) A = reagents.get_reagent_amount(M) @@ -69,6 +67,7 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis). /obj/machinery/r_n_d/circuit_imprinter/on_deconstruction() for(var/obj/item/reagent_containers/glass/G in component_parts) reagents.trans_to(G, G.reagents.maximum_volume) + GET_COMPONENT(materials, /datum/component/material_container) materials.retrieve_all() ..() @@ -77,52 +76,20 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis). linked_console.linked_imprinter = null ..() -/obj/machinery/r_n_d/circuit_imprinter/Insert_Item(obj/item/O, mob/user) - - if(istype(O, /obj/item/stack/sheet)) - . = 1 - if(!is_insertion_ready(user)) +/obj/machinery/r_n_d/circuit_imprinter/ComponentActivated(datum/component/C) + ..() + if(istype(C, /datum/component/material_container)) + var/datum/component/material_container/M = C + if(!M.last_insert_success) return - var/sheet_material = materials.get_item_material_amount(O) - if(!sheet_material) - return - - if(!materials.has_space(sheet_material)) - to_chat(user, "The [src.name]'s material bin is full! Please remove material before adding more.") - 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(!in_range(src, stack) || !user.Adjacent(src)) - return - var/amount_inserted = materials.insert_stack(O,amount) - if(!amount_inserted) - return 1 + var/lit = M.last_inserted_type + var/stack_name + if(ispath(lit, /obj/item/ore/bluespace_crystal)) + stack_name = "bluespace" + use_power(MINERAL_MATERIAL_AMOUNT / 10) else - use_power(max(1000, (MINERAL_MATERIAL_AMOUNT*amount_inserted/10))) - to_chat(user, "You add [amount_inserted] sheets to the [src.name].") - updateUsrDialog() - - else if(istype(O, /obj/item/ore/bluespace_crystal)) //Bluespace crystals can be either a stack or an item - . = 1 - if(!is_insertion_ready(user)) - return - var/bs_material = materials.get_item_material_amount(O) - if(!bs_material) - return - - if(!materials.has_space(bs_material)) - to_chat(user, "The [src.name]'s material bin is full! Please remove material before adding more.") - return 1 - - materials.insert_item(O) - use_power(MINERAL_MATERIAL_AMOUNT/10) - to_chat(user, "You add [O] to the [src.name].") - qdel(O) - updateUsrDialog() - - else if(user.a_intent != INTENT_HARM) - to_chat(user, "You cannot insert this item into the [name]!") - return 1 - else - return 0 \ No newline at end of file + var/obj/item/stack/S = lit + stack_name = initial(S.name) + use_power(max(1000, (MINERAL_MATERIAL_AMOUNT * M.last_amount_inserted / 10))) + add_overlay("protolathe_[stack_name]") + addtimer(CALLBACK(src, /atom/proc/cut_overlay, "protolathe_[stack_name]"), 10) \ No newline at end of file diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm index cbbb73652b..04a580963a 100644 --- a/code/modules/research/experimentor.dm +++ b/code/modules/research/experimentor.dm @@ -418,8 +418,9 @@ if(exp == SCANTYPE_OBLITERATE) visible_message("[exp_on] activates the crushing mechanism, [exp_on] is destroyed!") if(linked_console.linked_lathe) + GET_COMPONENT_FROM(linked_materials, /datum/component/material_container, linked_console.linked_lathe) for(var/material in exp_on.materials) - linked_console.linked_lathe.materials.insert_amount( min((linked_console.linked_lathe.materials.max_amount - linked_console.linked_lathe.materials.total_amount), (exp_on.materials[material])), material) + linked_materials.insert_amount( min((linked_materials.max_amount - linked_materials.total_amount), (exp_on.materials[material])), material) if(prob(EFFECT_PROB_LOW) && criticalReaction) visible_message("[src]'s crushing mechanism slowly and smoothly descends, flattening the [exp_on]!") new /obj/item/stack/sheet/plasteel(get_turf(pick(oview(1,src)))) @@ -706,4 +707,4 @@ if(priority) //For truly dangerous relics that may need an admin's attention. BWOINK! message_admins("[RelicType] relic activated by [ADMIN_LOOKUPFLW(user)] in [ADMIN_COORDJMP(T)]",0,1) log_game(log_msg) - investigate_log(log_msg, "experimentor") + investigate_log(log_msg, "experimentor") \ No newline at end of file diff --git a/code/modules/research/protolathe.dm b/code/modules/research/protolathe.dm index 7a18a5e630..ef655f3bec 100644 --- a/code/modules/research/protolathe.dm +++ b/code/modules/research/protolathe.dm @@ -14,7 +14,6 @@ Note: Must be placed west/left of and R&D console to function. container_type = OPENCONTAINER_1 circuit = /obj/item/circuitboard/machine/protolathe - var/datum/material_container/materials var/efficiency_coeff var/list/categories = list( @@ -34,11 +33,9 @@ Note: Must be placed west/left of and R&D console to function. /obj/machinery/r_n_d/protolathe/Initialize() create_reagents(0) - materials = new(src, list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE)) - return ..() - -/obj/machinery/r_n_d/protolathe/Destroy() - QDEL_NULL(materials) + AddComponent(/datum/component/material_container, + list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE), + FALSE, list(/obj/item/stack, /obj/item/ore/bluespace_crystal), CALLBACK(src, .proc/is_insertion_ready)) return ..() /obj/machinery/r_n_d/protolathe/RefreshParts() @@ -47,6 +44,7 @@ Note: Must be placed west/left of and R&D console to function. reagents.maximum_volume += G.volume G.reagents.trans_to(src, G.reagents.total_volume) + GET_COMPONENT(materials, /datum/component/material_container) materials.max_amount = 0 for(var/obj/item/stock_parts/matter_bin/M in component_parts) materials.max_amount += M.rating * 75000 @@ -59,6 +57,7 @@ Note: Must be placed west/left of and R&D console to function. /obj/machinery/r_n_d/protolathe/proc/check_mat(datum/design/being_built, M) // now returns how many times the item can be built with the material var/list/all_materials = being_built.reagents_list + being_built.materials + GET_COMPONENT(materials, /datum/component/material_container) var/A = materials.amount(M) if(!A) A = reagents.get_reagent_amount(M) @@ -69,6 +68,7 @@ Note: Must be placed west/left of and R&D console to function. /obj/machinery/r_n_d/protolathe/on_deconstruction() for(var/obj/item/reagent_containers/glass/G in component_parts) reagents.trans_to(G, G.reagents.maximum_volume) + GET_COMPONENT(materials, /datum/component/material_container) materials.retrieve_all() ..() @@ -77,63 +77,20 @@ Note: Must be placed west/left of and R&D console to function. linked_console.linked_lathe = null ..() -/obj/machinery/r_n_d/protolathe/Insert_Item(obj/item/O, mob/user) - - if(istype(O, /obj/item/stack/sheet)) - . = 1 - if(!is_insertion_ready(user)) +/obj/machinery/r_n_d/protolathe/ComponentActivated(datum/component/C) + ..() + if(istype(C, /datum/component/material_container)) + var/datum/component/material_container/M = C + if(!M.last_insert_success) return - var/sheet_material = materials.get_item_material_amount(O) - if(!sheet_material) - return - - if(!materials.has_space(sheet_material)) - to_chat(user, "The [src.name]'s material bin is full! Please remove material before adding more.") - 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(!in_range(src, stack) || !user.Adjacent(src)) - return - var/amount_inserted = materials.insert_stack(O,amount) - if(!amount_inserted) - return 1 + var/lit = M.last_inserted_type + var/stack_name + if(ispath(lit, /obj/item/ore/bluespace_crystal)) + stack_name = "bluespace" + use_power(MINERAL_MATERIAL_AMOUNT / 10) else - var/stack_name = stack.name - busy = TRUE - use_power(max(1000, (MINERAL_MATERIAL_AMOUNT*amount_inserted/10))) - to_chat(user, "You add [amount_inserted] sheets to the [src.name].") - add_overlay("protolathe_[stack_name]") - sleep(10) - cut_overlay("protolathe_[stack_name]") - busy = FALSE - updateUsrDialog() - - else if(istype(O, /obj/item/ore/bluespace_crystal)) //Bluespace crystals can be either a stack or an item - . = 1 - if(!is_insertion_ready(user)) - return - var/bs_material = materials.get_item_material_amount(O) - if(!bs_material) - return - - if(!materials.has_space(bs_material)) - to_chat(user, "The [src.name]'s material bin is full! Please remove material before adding more.") - return 1 - - materials.insert_item(O) - busy = TRUE - use_power(MINERAL_MATERIAL_AMOUNT/10) - to_chat(user, "You add [O] to the [src.name].") - qdel(O) - add_overlay("protolathe_bluespace") - sleep(10) - cut_overlay("protolathe_bluespace") - busy = FALSE - updateUsrDialog() - - else if(user.a_intent != INTENT_HARM) - to_chat(user, "You cannot insert this item into the [name]!") - return 1 - else - return 0 + var/obj/item/stack/S = lit + stack_name = initial(S.name) + use_power(max(1000, (MINERAL_MATERIAL_AMOUNT * M.last_amount_inserted / 10))) + add_overlay("protolathe_[stack_name]") + addtimer(CALLBACK(src, /atom/proc/cut_overlay, "protolathe_[stack_name]"), 10) \ No newline at end of file diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index 2f60e280ec..ee2cba39fd 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -169,6 +169,15 @@ won't update every console in existence) but it's more of a hassle to do. Also, if(href_list["menu"]) //Switches menu screens. Converts a sent text string into a number. Saves a LOT of code. var/temp_screen = text2num(href_list["menu"]) screen = temp_screen + + + var/datum/component/material_container/linked_materials + if(linked_lathe) + linked_materials = linked_lathe.GetComponent(/datum/component/material_container) + + var/datum/component/material_container/imprinter_materials + if(linked_imprinter) + imprinter_materials = linked_imprinter.GetComponent(/datum/component/material_container) if(href_list["category"]) selected_category = href_list["category"] @@ -315,7 +324,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, if(linked_lathe) //Also sends salvaged materials to a linked protolathe, if any. for(var/material in linked_destroy.loaded_item.materials) - linked_lathe.materials.insert_amount(min((linked_lathe.materials.max_amount - linked_lathe.materials.total_amount), (linked_destroy.loaded_item.materials[material]*(linked_destroy.decon_mod/10))), material) + linked_materials.insert_amount(min((linked_materials.max_amount - linked_materials.total_amount), (linked_destroy.loaded_item.materials[material]*(linked_destroy.decon_mod/10))), material) SSblackbox.add_details("item_deconstructed","[linked_destroy.loaded_item.type]") linked_destroy.loaded_item = null for(var/obj/I in linked_destroy.contents) @@ -421,7 +430,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, for(var/MAT in being_built.materials) efficient_mats[MAT] = being_built.materials[MAT]*coeff - if(!linked_lathe.materials.has_materials(efficient_mats, amount)) + if(!linked_materials.has_materials(efficient_mats, amount)) linked_lathe.say("Not enough materials to complete prototype.") enough_materials = 0 g2g = 0 @@ -433,7 +442,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, g2g = 0 if(enough_materials) - linked_lathe.materials.use_amount(efficient_mats, amount) + linked_materials.use_amount(efficient_mats, amount) for(var/R in being_built.reagents_list) linked_lathe.reagents.remove_reagent(R, being_built.reagents_list[R]*coeff) @@ -497,7 +506,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, for(var/MAT in being_built.materials) efficient_mats[MAT] = being_built.materials[MAT]/coeff - if(!linked_imprinter.materials.has_materials(efficient_mats)) + if(!imprinter_materials.has_materials(efficient_mats)) linked_imprinter.say("Not enough materials to complete prototype.") enough_materials = 0 g2g = 0 @@ -509,7 +518,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, g2g = 0 if(enough_materials) - linked_imprinter.materials.use_amount(efficient_mats) + imprinter_materials.use_amount(efficient_mats) for(var/R in being_built.reagents_list) linked_imprinter.reagents.remove_reagent(R, being_built.reagents_list[R]/coeff) @@ -536,7 +545,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, linked_lathe.reagents.clear_reagents() else if(href_list["ejectsheet"] && linked_lathe) //Causes the protolathe to eject a sheet of material - linked_lathe.materials.retrieve_sheets(text2num(href_list["eject_amt"]), href_list["ejectsheet"]) + linked_materials.retrieve_sheets(text2num(href_list["eject_amt"]), href_list["ejectsheet"]) //Circuit Imprinter Materials else if(href_list["disposeI"] && linked_imprinter) //Causes the circuit imprinter to dispose of a single reagent (all of it) @@ -546,7 +555,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, linked_imprinter.reagents.clear_reagents() else if(href_list["imprinter_ejectsheet"] && linked_imprinter) //Causes the imprinter to eject a sheet of material - linked_imprinter.materials.retrieve_sheets(text2num(href_list["eject_amt"]), href_list["imprinter_ejectsheet"]) + imprinter_materials.retrieve_sheets(text2num(href_list["eject_amt"]), href_list["imprinter_ejectsheet"]) else if(href_list["find_device"]) //The R&D console looks for devices nearby to link up with. @@ -634,6 +643,14 @@ won't update every console in existence) but it's more of a hassle to do. Also, if(linked_imprinter == null) screen = 4.0 + + var/datum/component/material_container/linked_materials + if(linked_lathe) + linked_materials = linked_lathe.GetComponent(/datum/component/material_container) + + var/datum/component/material_container/imprinter_materials + if(linked_imprinter) + imprinter_materials = linked_imprinter.GetComponent(/datum/component/material_container) switch(screen) //////////////////////R&D CONSOLE SCREENS////////////////// @@ -823,7 +840,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, dat += "Material Storage" dat += "Chemical Storage
" dat += "

Protolathe Menu:


" - dat += "Material Amount: [linked_lathe.materials.total_amount] / [linked_lathe.materials.max_amount]
" + dat += "Material Amount: [linked_materials.total_amount] / [linked_materials.max_amount]
" dat += "Chemical Volume: [linked_lathe.reagents.total_volume] / [linked_lathe.reagents.maximum_volume]
" dat += "
\ @@ -841,7 +858,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, dat += "Main Menu" dat += "Protolathe Menu" dat += "

Browsing [selected_category]:


" - dat += "Material Amount: [linked_lathe.materials.total_amount] / [linked_lathe.materials.max_amount]
" + dat += "Material Amount: [linked_materials.total_amount] / [linked_materials.max_amount]
" dat += "Chemical Volume: [linked_lathe.reagents.total_volume] / [linked_lathe.reagents.maximum_volume]
" var/coeff = linked_lathe.efficiency_coeff @@ -879,7 +896,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, dat += "Main Menu" dat += "Protolathe Menu" dat += "

Search results:


" - dat += "Material Amount: [linked_lathe.materials.total_amount] / [linked_lathe.materials.max_amount]
" + dat += "Material Amount: [linked_materials.total_amount] / [linked_materials.max_amount]
" dat += "Chemical Volume: [linked_lathe.reagents.total_volume] / [linked_lathe.reagents.maximum_volume]
" var/coeff = linked_lathe.efficiency_coeff @@ -916,8 +933,8 @@ won't update every console in existence) but it's more of a hassle to do. Also, if(!linked_lathe) dat += "ERROR: Protolathe connection failed." else - for(var/mat_id in linked_lathe.materials.materials) - var/datum/material/M = linked_lathe.materials.materials[mat_id] + for(var/mat_id in linked_materials.materials) + var/datum/material/M = linked_materials.materials[mat_id] dat += "* [M.amount] of [M.name]: " if(M.amount >= MINERAL_MATERIAL_AMOUNT) dat += "Eject " if(M.amount >= MINERAL_MATERIAL_AMOUNT*5) dat += "5x " @@ -944,7 +961,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, dat += "Material Storage" dat += "Chemical Storage
" dat += "

Circuit Imprinter Menu:


" - dat += "Material Amount: [linked_imprinter.materials.total_amount]
" + dat += "Material Amount: [imprinter_materials.total_amount]
" dat += "Chemical Volume: [linked_imprinter.reagents.total_volume]
" dat += "\ @@ -961,7 +978,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, dat += "Main Menu" dat += "Circuit Imprinter Menu" dat += "

Browsing [selected_category]:


" - dat += "Material Amount: [linked_imprinter.materials.total_amount]
" + dat += "Material Amount: [imprinter_materials.total_amount]
" dat += "Chemical Volume: [linked_imprinter.reagents.total_volume]
" var/coeff = linked_imprinter.efficiency_coeff @@ -991,7 +1008,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, dat += "Main Menu" dat += "Circuit Imprinter Menu" dat += "

Search results:


" - dat += "Material Amount: [linked_imprinter.materials.total_amount]
" + dat += "Material Amount: [imprinter_materials.total_amount]
" dat += "Chemical Volume: [linked_imprinter.reagents.total_volume]
" var/coeff = linked_imprinter.efficiency_coeff @@ -1028,8 +1045,8 @@ won't update every console in existence) but it's more of a hassle to do. Also, if(!linked_imprinter) dat += "ERROR: Protolathe connection failed." else - for(var/mat_id in linked_imprinter.materials.materials) - var/datum/material/M = linked_imprinter.materials.materials[mat_id] + for(var/mat_id in imprinter_materials.materials) + var/datum/material/M = imprinter_materials.materials[mat_id] dat += "* [M.amount] of [M.name]: " if(M.amount >= MINERAL_MATERIAL_AMOUNT) dat += "Eject " if(M.amount >= MINERAL_MATERIAL_AMOUNT*5) dat += "5x " diff --git a/tgstation.dme b/tgstation.dme index ee43dcafd7..3bc3db1c0f 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -261,7 +261,6 @@ #include "code\datums\hud.dm" #include "code\datums\map_config.dm" #include "code\datums\martial.dm" -#include "code\datums\material_container.dm" #include "code\datums\mind.dm" #include "code\datums\mutable_appearance.dm" #include "code\datums\mutations.dm" @@ -282,6 +281,7 @@ #include "code\datums\antagonists\devil.dm" #include "code\datums\antagonists\ninja.dm" #include "code\datums\components\component.dm" +#include "code\datums\components\material_container.dm" #include "code\datums\components\slippery.dm" #include "code\datums\diseases\_disease.dm" #include "code\datums\diseases\_MobProcs.dm"