diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index 4f7be974eee..f2f03915fe7 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -3086,6 +3086,8 @@ var/global/num_vending_terminals = 1 /obj/item/weapon/reagent_containers/food/drinks/flask/ancient = 1, /obj/item/device/crank_charger/generous = 1, /obj/item/weapon/fakeposter_kit = 1, + /obj/structure/closet/crate/flatpack/ancient/condiment_dispenser = 1, + /obj/structure/closet/crate/flatpack/ancient/chemmaster_electrolyzer = 1, ) prices = list( /obj/item/clothing/suit/storage/trader = 100, @@ -3127,6 +3129,8 @@ var/global/num_vending_terminals = 1 /obj/item/weapon/reagent_containers/food/drinks/flask/ancient = 175, /obj/item/device/crank_charger/generous = 50, /obj/item/weapon/fakeposter_kit = 50, + /obj/structure/closet/crate/flatpack/ancient/condiment_dispenser = 100, + /obj/structure/closet/crate/flatpack/ancient/chemmaster_electrolyzer = 100, ) /obj/machinery/vending/trader/New() diff --git a/code/modules/reagents/machinery/chem_dispenser.dm b/code/modules/reagents/machinery/chem_dispenser.dm index 5e775a330f6..da38b83a34d 100644 --- a/code/modules/reagents/machinery/chem_dispenser.dm +++ b/code/modules/reagents/machinery/chem_dispenser.dm @@ -2,6 +2,7 @@ /obj/machinery/chem_dispenser name = "\improper Chem Dispenser" + desc = "It dispenses chemicals." density = TRUE anchored = TRUE icon = 'icons/obj/chemical.dmi' @@ -18,6 +19,7 @@ var/custom = 0 var/useramount = 30 // Last used amount var/required_quirk = MODULE_CAN_HANDLE_CHEMS + var/template_path = "chem_dispenser.tmpl" var/list/dispensable_reagents = list( HYDROGEN, LITHIUM, @@ -201,7 +203,7 @@ USE THIS CHEMISTRY DISPENSER FOR MAPS SO THEY START AT 100 ENERGY if (!ui) // the ui does not exist, so we'll create a new() one // for a list of parameters and their descriptions see the code docs in \code\\modules\nano\nanoui.dm - ui = new(user, src, ui_key, "chem_dispenser.tmpl", "[src.name] 5000", 390, 630) + ui = new(user, src, ui_key, template_path, "[src.name]", 390, 630) // when the ui is first opened this is the data it will use ui.set_initial_data(data) // open the new ui window @@ -281,6 +283,9 @@ USE THIS CHEMISTRY DISPENSER FOR MAPS SO THEY START AT 100 ENERGY return return ..() +/obj/machinery/chem_dispenser/proc/can_insert(var/obj/item/I) + return istype(I, /obj/item/weapon/reagent_containers/glass) || istype(I, /obj/item/weapon/reagent_containers/food/drinks) + /obj/machinery/chem_dispenser/attackby(var/obj/item/weapon/D as obj, var/mob/user as mob) //to be worked on if(..()) @@ -290,7 +295,7 @@ USE THIS CHEMISTRY DISPENSER FOR MAPS SO THEY START AT 100 ENERGY if(!can_use(user)) return - if(istype(D, /obj/item/weapon/reagent_containers/glass) || istype(D, /obj/item/weapon/reagent_containers/food/drinks)) + if(can_insert(D)) if(src.container) to_chat(user, "\A [src.container] is already loaded into the machine.") return @@ -469,6 +474,34 @@ USE THIS CHEMISTRY DISPENSER FOR MAPS SO THEY START AT 100 ENERGY max_energy = 100 energy = 100 +/obj/machinery/chem_dispenser/condiment + name = "\improper Condiment Dispenser" + desc = "A dispenser designed to output condiments directly onto food, or into condiment bottles. These were banned for being 'unhygienic' after one too many licking incidents." + icon_state = "condi_dispenser" + pass_flags = PASSTABLE + max_energy = 30 + required_quirk = MODULE_CAN_HANDLE_FOOD + template_path = "condi_dispenser.tmpl" + dispensable_reagents = list( + SODIUMCHLORIDE, + BLACKPEPPER, + KETCHUP, + MUSTARD, + RELISH, + CAPSAICIN, + FROSTOIL, + LIQUIDBUTTER, + SOYSAUCE, + SPRINKLES + ) + machine_flags = SCREWTOGGLE | WRENCHMOVE | FIXED2WORK + +/obj/machinery/chem_dispenser/condiment/can_insert(obj/item/I) + return istype(I,/obj/item/weapon/reagent_containers/food/snacks) || istype(I,/obj/item/weapon/reagent_containers/food/condiment) + +/obj/machinery/chem_dispenser/condiment/update_icon() + return //no overlays for this one, it takes special inputs + #undef FORMAT_DISPENSER_NAME /obj/machinery/chem_dispenser/npc_tamper_act(mob/living/L) diff --git a/code/modules/reagents/machinery/chem_master.dm b/code/modules/reagents/machinery/chem_master.dm index 7d1206fe1ea..2a712bd0199 100644 --- a/code/modules/reagents/machinery/chem_master.dm +++ b/code/modules/reagents/machinery/chem_master.dm @@ -37,6 +37,8 @@ var/global/list/pillIcon2Name = list("oblong purple-pink", "oblong green-white", var/max_pill_size = 50 var/pill_display_number = MAX_PILL_SPRITE/2 + var/electrolytic = FALSE + light_color = LIGHT_COLOR_BLUE light_range_on = 3 light_power_on = 2 @@ -200,6 +202,37 @@ var/global/list/pillIcon2Name = list("oblong purple-pink", "oblong green-white", popup.open() return 1 + else if(href_list["electrolyze"]) + if(!electrolytic) + return + var/datum/reagent/target = locate(href_list["electrolyze"]) + var/datum/chemical_reaction/unreaction + for(var/poss in typesof(/datum/chemical_reaction/)) + var/datum/chemical_reaction/check = poss + if(initial(check.id) == target.id) + unreaction = new check + break + if(!unreaction) + to_chat(usr, "The chemical couldn't be broken down.") + return + if(unreaction.result_amount > target.volume) + to_chat(usr, "There wasn't enough [target] to break down!") + return + var/total_reactions = round(target.volume / unreaction.result_amount) + use_power(30*total_reactions) + var/amount_to_electrolyze = total_reactions*unreaction.result_amount + //The reason we have this new var is because the rounding may mean there are less reactions than total volume! + container.reagents.remove_reagent(unreaction.result,amount_to_electrolyze) //This moves over the reactive bulk, and leaves behind the amount too small to react + for(var/E in unreaction.required_reagents) + var/reagent_ID = E + if(islist(E)) + var/list/L = E + reagent_ID = L[1] //the first element should be the synthetic version of the chemical + reagents.add_reagent(reagent_ID, unreaction.required_reagents[E]*total_reactions) + updateUsrDialog() + playsound(src, 'sound/effects/bubbles.ogg', 80, 1) + return 1 + else if(href_list["add"]) var/id = href_list["add"] var/amount @@ -516,7 +549,7 @@ var/global/list/pillIcon2Name = list("oblong purple-pink", "oblong green-white", reg_name = "[reg_name] ([vaccines])" dat += {" - [reg_name] , [round(G.volume, 0.01)] Units - (?) + [reg_name], [round(G.volume, 0.01)] Units - (?) [electrolytic ? "(Electrolyze)" : ""] 1u @@ -591,7 +624,7 @@ var/global/list/pillIcon2Name = list("oblong purple-pink", "oblong green-white", reg_name = "[reg_name] ([vaccines])" dat += {" - [reg_name] , [round(N.volume, 0.01)] Units - (?) + [reg_name], [round(N.volume, 0.01)] Units - (?) 1u @@ -679,4 +712,10 @@ var/global/list/pillIcon2Name = list("oblong purple-pink", "oblong green-white", chem_board = /obj/item/weapon/circuitboard/condimaster windowtype = "condi_master" +/obj/machinery/chem_master/electrolytic + name = "\improper Electrolytic ChemMaster" + desc = "The ultimate industrial chemical cooker, its chemical reservoir is made from non-reactive stasis technology and it can electrolyze individual chemicals within. These were banned after the Junkie Wars of 2420, but you can still find them in shady places." + electrolytic = TRUE + flags = FPRINT | NOREACT + #undef MAX_PILL_SPRITE diff --git a/code/modules/research/mechanic/flatpack.dm b/code/modules/research/mechanic/flatpack.dm index 2edc2a64681..d5f6dbaf19a 100644 --- a/code/modules/research/mechanic/flatpack.dm +++ b/code/modules/research/mechanic/flatpack.dm @@ -1,5 +1,7 @@ #define MAX_FLATPACK_STACKS 6 //how many flatpacks we can stack at once #define FLATPACK_HEIGHT 4 //the height of the icon +#define UNASSEMBLED 2 //2 = not opened, 1 = opened, assembling, 0 = ready to use +#define ASSEMBLING 1 //only ancient flatpacks use these, normal flatpacks start ready to use /obj/structure/closet/crate/flatpack name = "\improper flatpack" @@ -11,10 +13,14 @@ anchored = 0 pass_flags = PASSTABLE var/obj/machinery/machine = null -// var/datum/construction/flatpack_unpack/unpacking - var/assembling = 0 + var/datum/construction/flatpack_unpack/unpacking + var/assembling = FALSE var/list/image/stacked = list() //assoc ref list +/obj/structure/closet/crate/flatpack/ancient + name = "ancient flatpack" + assembling = UNASSEMBLED + /obj/structure/closet/crate/flatpack/examine(mob/user) ..() if(stacked.len) @@ -23,7 +29,8 @@ /obj/structure/closet/crate/flatpack/New() ..() -// unpacking = new (src) + if(assembling) + unpacking = new (src) icon_state = "flatpack" //it gets changed in the crate code, so we reset it here /obj/structure/closet/crate/flatpack/update_icon() @@ -47,8 +54,8 @@ icon_state = "flatpackeng" break -/* if(assembling) - overlays += image(icon = icon, icon_state = "assembly") */ + if(assembling == ASSEMBLING) + overlays += image(icon = icon, icon_state = "assembly") else if(stacked.len) for(var/i = 1 to stacked.len) var/image/stack_image = stacked[stacked[i]] //because it's an assoc list @@ -57,36 +64,35 @@ overlays += stack_image /obj/structure/closet/crate/flatpack/attackby(var/atom/A, mob/user) -/* if(assembling) + if(assembling == ASSEMBLING) if(unpacking.action(A, user)) - return 1 */ - if(iscrowbar(A) && !assembling) + return 1 + if(iscrowbar(A)) if(stacked.len) to_chat(user, "You can't open this flatpack while others are stacked on top of it!") return - assembling = 1 user.visible_message("[user] begins to open the flatpack...", "You begin to open the flatpack...") if(do_after(user, src, rand(10,40))) if(machine) - to_chat(user, "[bicon(src)]You successfully unpack \the [machine]!") -// overlays += image(icon = icon, icon_state = "assembly") -/* var/obj/item/weapon/paper/instructions = new (get_turf(src)) - var/list/inst_list = unpacking.GenerateInstructions() - instructions.name = "instructions ([machine.name])" - instructions.info = inst_list["instructions"] - if(inst_list["misprint"]) - instructions.overlays += image(icon = icon, icon_state = "paper_stamp-deny") - instructions.name = "misprinted " + instructions.name - instructions.update_icon() -*/ - machine.forceMove(src.loc) - machine = null - qdel(src) + to_chat(user, "[bicon(src)] You successfully unpack \the [machine]!") + if(assembling == UNASSEMBLED) + overlays += image(icon = icon, icon_state = "assembly") + var/obj/item/weapon/paper/instructions = new (get_turf(src)) + var/list/inst_list = unpacking.GenerateInstructions() + instructions.name = "instructions ([machine.name])" + instructions.info = inst_list["instructions"] + if(inst_list["misprint"]) + instructions.overlays += image(icon = icon, icon_state = "paper_stamp-deny") + instructions.name = "misprinted " + instructions.name + instructions.update_icon() + assembling = ASSEMBLING + else + machine.forceMove(src.loc) + machine = null + qdel(src) else - to_chat(user, "[bicon(src)]It seems this [src] was empty...") + to_chat(user, "[bicon(src)] It seems this [src] was empty...") qdel(src) - assembling = 0 - return /obj/structure/closet/crate/flatpack/proc/Finalize() machine.forceMove(get_turf(src)) @@ -141,9 +147,9 @@ /obj/structure/closet/crate/flatpack/MouseDropTo(atom/dropping, mob/user) if(istype(dropping, /obj/structure/closet/crate/flatpack) && dropping != src) var/obj/structure/closet/crate/flatpack/stacking = dropping -/* if(assembling || stacking.assembling) + if(assembling == ASSEMBLING || stacking.assembling == ASSEMBLING) to_chat(user, "You can't stack opened flatpacks.") - return */ + return if((stacked.len + stacking.stacked.len + 2) >= MAX_FLATPACK_STACKS) //how many flatpacks we can in a stack (including the bases) to_chat(user, "You can't stack flatpacks that high.") return @@ -198,7 +204,7 @@ machine = thing update_icon() -/* + #define Fl_ACTION "action" /datum/construction/flatpack_unpack @@ -270,7 +276,6 @@ return 1 #undef Fl_ACTION -*/ /obj/structure/closet/crate/flatpack/suit_modifier/New() @@ -302,3 +307,10 @@ ..() machine = new /obj/machinery/shield_capacitor(src) +/obj/structure/closet/crate/flatpack/ancient/condiment_dispenser/New() + ..() + machine = new /obj/machinery/chem_dispenser/condiment(src) + +/obj/structure/closet/crate/flatpack/ancient/chemmaster_electrolyzer/New() + ..() + machine = new /obj/machinery/chem_master/electrolytic(src) \ No newline at end of file diff --git a/icons/obj/chemical.dmi b/icons/obj/chemical.dmi index c288b5cd466..85f73b89435 100644 Binary files a/icons/obj/chemical.dmi and b/icons/obj/chemical.dmi differ diff --git a/nano/templates/condi_dispenser.tmpl b/nano/templates/condi_dispenser.tmpl new file mode 100644 index 00000000000..384e8421534 --- /dev/null +++ b/nano/templates/condi_dispenser.tmpl @@ -0,0 +1,70 @@ + +
+
+ Energy: +
+
+ {{:helper.displayBar(data.energy, 0, data.maxEnergy, 'good', data.energy + ' Units')}} +
+
+ +
+
+ Dispense: +
+
+ {{:helper.link('5', 'gear', {'amount' : 5}, (data.amount == 5 && !data.custom) ? 'selected' : null)}} + {{:helper.link('10', 'gear', {'amount' : 10}, (data.amount == 10 && !data.custom) ? 'selected' : null)}} + {{:helper.link('15', 'gear', {'amount' : 15}, (data.amount == 15 && !data.custom) ? 'selected' : null)}} + {{:helper.link('20', 'gear', {'amount' : 20}, (data.amount == 20 && !data.custom) ? 'selected' : null)}} + {{:helper.link('25', 'gear', {'amount' : 25}, (data.amount == 25 && !data.custom) ? 'selected' : null)}} + {{:helper.link('30', 'gear', {'amount' : 30}, (data.amount == 30 && !data.custom) ? 'selected' : null)}} + {{:helper.link((data.custom) ? 'Custom: ' + data.amount : 'Custom', 'gear', {'amount' : 0}, (data.amount == 0), (data.custom) ? 'selected' : null)}} + +
+
+
 
+
+
+ Condiment Dispenser +
+
+
+
+ {{for data.chemicals}} + {{:helper.link(value.title, 'circle-arrow-s', value.commands, null, data.glass ? 'fixedLeftWide' : 'fixedLeft')}} + {{/for}} + +
+
+
 
+
+
+ Target Contents +
+
+ {{:helper.link('Eject Target', 'eject', {'ejectBeaker' : 1}, data.isBeakerLoaded ? null : 'disabled', 'floatRight')}} +
+
+
+
+
+ {{if data.isBeakerLoaded}} + Volume: {{:data.beakerCurrentVolume}} / {{:data.beakerMaxVolume}}
+ {{for data.beakerContents}} + {{:value.volume}} units of {{:value.name}}
+ {{empty}} + + Target is empty + + {{/for}} + {{else}} + + No food/condiment bottle loaded + + {{/if}} +
+
+