diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index 641454a799..94b9c84fb0 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -39,6 +39,14 @@ #define COMSIG_MOVABLE_COLLIDE "movable_collide" //from base of atom/movable/Collide(): (atom) #define COMSIG_MOVABLE_IMPACT "movable_impact" //from base of atom/movable/throw_impact(): (atom, throwingdatum) +// /obj/item signals +#define COMSIG_ITEM_ATTACK "item_attack" //from base of obj/item/attack(): (mob/living/target, mob/living/user) +#define COMSIG_ITEM_ATTACK_SELF "item_attack_self" //from base of obj/item/attack_self(): (mob) +#define COMSIG_ITEM_ATTACK_OBJ "item_attack_obj" //from base of obj/item/attack_obj(): (obj, mob) + +// /obj/item/clothing signals +#define COMSIG_SHOES_STEP_ACTION "shoes_step_action" //from base of obj/item/clothing/shoes/proc/step_action(): () + // /obj/machinery signals #define COMSIG_MACHINE_PROCESS "machine_process" //from machinery subsystem fire(): () #define COMSIG_MACHINE_PROCESS_ATMOS "machine_process_atmos" //from air subsystem process_atmos_machinery(): () \ No newline at end of file diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 5265a8e8ea..987818924f 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -9,17 +9,18 @@ // Called when the item is in the active hand, and clicked; alternately, there is an 'activate held object' verb or you can hit pagedown. /obj/item/proc/attack_self(mob/user) - return + SendSignal(COMSIG_ITEM_ATTACK_SELF, user) + interact(user) /obj/item/proc/pre_attackby(atom/A, mob/living/user, params) //do stuff before attackby! return TRUE //return FALSE to avoid calling attackby after this proc does stuff // No comment /atom/proc/attackby(obj/item/W, mob/user, params) - return + return SendSignal(COMSIG_PARENT_ATTACKBY, W, user, params) /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/living/user, params) user.changeNext_move(CLICK_CD_MELEE) @@ -35,6 +36,7 @@ /obj/item/proc/attack(mob/living/M, mob/living/user) + SendSignal(COMSIG_ITEM_ATTACK, M, user) if(flags_1 & NOBLUDGEON_1) return if(!force) @@ -54,6 +56,7 @@ //the equivalent of the standard version of attack() but for object targets. /obj/item/proc/attack_obj(obj/O, mob/living/user) + SendSignal(COMSIG_ITEM_ATTACK_OBJ, O, user) if(flags_1 & NOBLUDGEON_1) return user.changeNext_move(CLICK_CD_MELEE) 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..55504d47d5 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 diff --git a/code/datums/components/squeek.dm b/code/datums/components/squeek.dm new file mode 100644 index 0000000000..40fd0af598 --- /dev/null +++ b/code/datums/components/squeek.dm @@ -0,0 +1,61 @@ +/datum/component/squeak + var/static/list/default_squeak_sounds = list('sound/items/toysqueak1.ogg'=1, 'sound/items/toysqueak2.ogg'=1, 'sound/items/toysqueak3.ogg'=1) + var/list/override_squeak_sounds + var/squeak_chance = 100 + var/volume = 30 + + // This is so shoes don't squeak every step + var/steps = 0 + var/step_delay = 1 + + // This is to stop squeak spam from inhand usage + var/last_use = 0 + var/use_delay = 20 + +/datum/component/squeak/Initialize(custom_sounds, volume_override, chance_override, step_delay_override, use_delay_override) + if(custom_sounds) + override_squeak_sounds = custom_sounds + if(chance_override) + squeak_chance = chance_override + if(volume_override) + volume = volume_override + if(step_delay_override) + step_delay = step_delay_override + if(use_delay_override) + use_delay = use_delay_override + + if(istype(parent, /atom)) + RegisterSignal(COMSIG_ATOM_BLOB_ACT, .proc/play_squeak) + RegisterSignal(COMSIG_ATOM_HULK_ATTACK, .proc/play_squeak) + RegisterSignal(COMSIG_PARENT_ATTACKBY, .proc/play_squeak) + if(istype(parent, /atom/movable)) + RegisterSignal(COMSIG_MOVABLE_CROSSED, .proc/play_squeak) + RegisterSignal(COMSIG_MOVABLE_COLLIDE, .proc/play_squeak) + RegisterSignal(COMSIG_MOVABLE_IMPACT, .proc/play_squeak) + if(istype(parent, /obj/item)) + RegisterSignal(COMSIG_ITEM_ATTACK, .proc/play_squeak) + RegisterSignal(COMSIG_ITEM_ATTACK_SELF, .proc/use_squeak) + RegisterSignal(COMSIG_ITEM_ATTACK_OBJ, .proc/play_squeak) + if(istype(parent, /obj/item/clothing/shoes)) + RegisterSignal(COMSIG_SHOES_STEP_ACTION, .proc/step_squeak) + else + RegisterSignal(COMSIG_ATOM_ENTERED, .proc/play_squeak) + +/datum/component/squeak/proc/play_squeak() + if(prob(squeak_chance)) + if(!override_squeak_sounds) + playsound(parent, pickweight(default_squeak_sounds), volume, 1, -1) + else + playsound(parent, pickweight(override_squeak_sounds), volume, 1, -1) + +/datum/component/squeak/proc/step_squeak() + if(steps > step_delay) + play_squeak() + steps = 0 + else + steps++ + +/datum/component/squeak/proc/use_squeak() + if(last_use + use_delay < world.time) + last_use = world.time + play_squeak() \ No newline at end of file diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index c185a8f734..9fa53765ed 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))) diff --git a/code/game/machinery/droneDispenser.dm b/code/game/machinery/droneDispenser.dm index 2d848d95ed..5d7be7fbd8 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].") diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm index b4bee2bdae..fbe02dca37 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) diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm index 79c4971665..8efc14d966 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) @@ -479,17 +455,3 @@ 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..bf3a1f28e0 100644 --- a/code/modules/clothing/shoes/bananashoes.dm +++ b/code/modules/clothing/shoes/bananashoes.dm @@ -5,59 +5,39 @@ 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) + AddComponent(/datum/component/squeak, list('sound/items/bikehorn.ogg'=1), 75) /obj/item/clothing/shoes/clown_shoes/banana_shoes/step_action() + . = ..() if(on) - if(footstep > 1)//honks when its on - playsound(src, 'sound/items/bikehorn.ogg', 75, 1) - footstep = 0 - else - 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 flags_1 &= ~NOSLIP_1 update_icon() to_chat(loc, "You ran out of bananium!") - else - ..() /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() 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 abead3ab9a..38e02474f4 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) diff --git a/code/modules/mining/mint.dm b/code/modules/mining/mint.dm index e48db7c6fd..1a4e4c5ed1 100644 --- a/code/modules/mining/mint.dm +++ b/code/modules/mining/mint.dm @@ -1,107 +1,103 @@ -/**********************Mint**************************/ - - -/obj/machinery/mineral/mint - name = "coin press" - icon = 'icons/obj/economy.dmi' - icon_state = "coinpress0" +/**********************Mint**************************/ + + +/obj/machinery/mineral/mint + name = "coin press" + icon = 'icons/obj/economy.dmi' + icon_state = "coinpress0" density = TRUE anchored = TRUE - var/datum/material_container/materials - var/newCoins = 0 //how many coins the machine made in it's last load + var/newCoins = 0 //how many coins the machine made in it's last load var/processing = FALSE - var/chosen = MAT_METAL //which material will be used to make coins - var/coinsToProduce = 10 - speed_process = 1 - - + 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/process() - var/turf/T = get_step(src, input_dir) - if(!T) - return - - 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
" - - for(var/mat_id in materials.materials) - var/datum/material/M = materials.materials[mat_id] - if(!M.amount && chosen != mat_id) - continue - dat += "
[M.name] amount: [M.amount] cm3 " - if (chosen == mat_id) - dat += "Chosen" - else - dat += "Choose" - - var/datum/material/M = materials.materials[chosen] - - dat += "

Will produce [coinsToProduce] [lowertext(M.name)] coins if enough materials are available.
" - dat += "-10 " - dat += "-5 " - dat += "-1 " - dat += "+1 " - dat += "+5 " - dat += "+10 " - - dat += "

In total this machine produced [newCoins] coins." - dat += "
Make coins" - user << browse(dat, "window=mint") - -/obj/machinery/mineral/mint/Topic(href, href_list) - if(..()) - return - usr.set_machine(src) - src.add_fingerprint(usr) - if(processing==1) - to_chat(usr, "The machine is processing.") - return - if(href_list["choose"]) - if(materials.materials[href_list["choose"]]) - chosen = href_list["choose"] - if(href_list["chooseAmt"]) - coinsToProduce = Clamp(coinsToProduce + text2num(href_list["chooseAmt"]), 0, 1000) - if(href_list["makeCoins"]) - var/temp_coins = coinsToProduce + 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) + continue + dat += "
[M.name] amount: [M.amount] cm3 " + if (chosen == mat_id) + dat += "Chosen" + else + dat += "Choose" + + var/datum/material/M = materials.materials[chosen] + + dat += "

Will produce [coinsToProduce] [lowertext(M.name)] coins if enough materials are available.
" + dat += "-10 " + dat += "-5 " + dat += "-1 " + dat += "+1 " + dat += "+5 " + dat += "+10 " + + dat += "

In total this machine produced [newCoins] coins." + dat += "
Make coins" + user << browse(dat, "window=mint") + +/obj/machinery/mineral/mint/Topic(href, href_list) + if(..()) + return + usr.set_machine(src) + src.add_fingerprint(usr) + 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"] + if(href_list["chooseAmt"]) + coinsToProduce = Clamp(coinsToProduce + text2num(href_list["chooseAmt"]), 0, 1000) + if(href_list["makeCoins"]) + var/temp_coins = coinsToProduce processing = TRUE - icon_state = "coinpress1" - var/coin_mat = MINERAL_MATERIAL_AMOUNT * 0.2 - var/datum/material/M = materials.materials[chosen] - if(!M || !M.coin_type) - updateUsrDialog() - return - - while(coinsToProduce > 0 && materials.use_amount_type(coin_mat, chosen)) - create_coins(M.coin_type) - coinsToProduce-- - newCoins++ - src.updateUsrDialog() - sleep(5) - - icon_state = "coinpress0" + icon_state = "coinpress1" + var/coin_mat = MINERAL_MATERIAL_AMOUNT * 0.2 + var/datum/material/M = materials.materials[chosen] + if(!M || !M.coin_type) + updateUsrDialog() + return + + while(coinsToProduce > 0 && materials.use_amount_type(coin_mat, chosen)) + create_coins(M.coin_type) + coinsToProduce-- + newCoins++ + src.updateUsrDialog() + sleep(5) + + icon_state = "coinpress0" processing = FALSE - coinsToProduce = temp_coins - src.updateUsrDialog() - return - -/obj/machinery/mineral/mint/proc/create_coins(P) - var/turf/T = get_step(src,output_dir) - if(T) - var/obj/item/O = new P(src) - var/obj/item/storage/bag/money/M = locate(/obj/item/storage/bag/money, T) - if(!M) - M = new /obj/item/storage/bag/money(src) - unload_mineral(M) + coinsToProduce = temp_coins + src.updateUsrDialog() + return + +/obj/machinery/mineral/mint/proc/create_coins(P) + var/turf/T = get_step(src,output_dir) + if(T) + var/obj/item/O = new P(src) + var/obj/item/storage/bag/money/M = locate(/obj/item/storage/bag/money, T) + if(!M) + M = new /obj/item/storage/bag/money(src) + unload_mineral(M) O.loc = M \ No newline at end of file diff --git a/code/modules/research/circuitprinter.dm b/code/modules/research/circuitprinter.dm index ad2345afe5..f9a2c0d63c 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) diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm index cbbb73652b..4d8938b1b8 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)))) diff --git a/code/modules/research/protolathe.dm b/code/modules/research/protolathe.dm index 7a18a5e630..88c902a70d 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) 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/sound/items/toysqueak1.ogg b/sound/items/toysqueak1.ogg new file mode 100644 index 0000000000..e64a6fb179 Binary files /dev/null and b/sound/items/toysqueak1.ogg differ diff --git a/sound/items/toysqueak2.ogg b/sound/items/toysqueak2.ogg new file mode 100644 index 0000000000..fddf1edfb9 Binary files /dev/null and b/sound/items/toysqueak2.ogg differ diff --git a/sound/items/toysqueak3.ogg b/sound/items/toysqueak3.ogg new file mode 100644 index 0000000000..338f4d8aa9 Binary files /dev/null and b/sound/items/toysqueak3.ogg differ diff --git a/tgstation.dme b/tgstation.dme index d852af48c0..a0365fdd75 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -263,7 +263,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" @@ -286,7 +285,9 @@ #include "code\datums\antagonists\ninja.dm" #include "code\datums\components\archaeology.dm" #include "code\datums\components\component.dm" +#include "code\datums\components\material_container.dm" #include "code\datums\components\slippery.dm" +#include "code\datums\components\squeek.dm" #include "code\datums\diseases\_disease.dm" #include "code\datums\diseases\_MobProcs.dm" #include "code\datums\diseases\anxiety.dm"