emilyploszaj / emi

A featureful and accessible item and recipe viewer
MIT License
235 stars 45 forks source link

[Request] KubeJS support for adding or removing items from search #189

Open aaronhowser1 opened 1 year ago

lxly9 commented 1 year ago

that works actually

lxly9 commented 1 year ago

just do event.add("c:hidden_from_recipe_viewers", /[your item here]/)

aaronhowser1 commented 1 year ago

I can't add items at least

JEIEvents.addItems((event) => {
    let itemsToAdd = [
        Item.of(
            'akashictome:tome',
            '{"akashictome:data":{advancedperipherals:{Count:1b,id:"patchouli:guide_book",tag:{"patchouli:book":"advancedperipherals:manual"}},ae2:{Count:1b,id:"ae2:guide"},alexsmobs:{Count:1b,id:"alexsmobs:animal_dictionary"},apotheosis:{Count:1b,id:"patchouli:guide_book",tag:{"patchouli:book":"apotheosis:apoth_chronicle"}},ars_nouveau:{Count:1b,id:"ars_nouveau:worn_notebook"},botania:{Count:1b,id:"botania:lexicon"},engineersdecor:{Count:1b,id:"patchouli:guide_book",tag:{"patchouli:book":"engineersdecor:engineersdecor_manual"}},ftbquests:{Count:1b,id:"ftbquests:book"},hexcasting:{Count:1b,id:"patchouli:guide_book",tag:{"patchouli:book":"hexcasting:thehexbook"}},immersiveengineering:{Count:1b,id:"immersiveengineering:manual"},integratedtunnels:{Count:1b,id:"integrateddynamics:on_the_dynamics_of_integration"},laserio:{Count:1b,id:"patchouli:guide_book",tag:{"patchouli:book":"laserio:laseriobook"}},littlelogistics:{Count:1b,id:"patchouli:guide_book",tag:{"patchouli:book":"littlelogistics:guide"}},modularrouters:{Count:1b,id:"patchouli:guide_book",tag:{"patchouli:book":"modularrouters:book"}},naturesaura:{Count:1b,id:"patchouli:guide_book",tag:{"patchouli:book":"naturesaura:book"}},occultism:{Count:1b,id:"occultism:dictionary_of_spirits",tag:{"modonomicon:book_id":"occultism:dictionary_of_spirits"}},pneumaticcraft:{Count:1b,id:"patchouli:guide_book",tag:{"patchouli:book":"pneumaticcraft:book"}},statues:{Count:1b,id:"patchouli:guide_book",tag:{"patchouli:book":"statues:statues"}}},display:{Lore:[\'"More can be crafted if needed"\']}}'
        ),
        Item.of('ae2:facade', '{item:"minecraft:stone"}'),
        Item.of(
            'tetra:modular_double',
            '{Damage:0,"double/basic_hammer_left_material":"basic_hammer/oak","double/basic_hammer_right_material":"basic_hammer/oak","double/basic_handle_material":"basic_handle/stick","double/handle":"double/basic_handle","double/head_left":"double/basic_hammer_left","double/head_right":"double/basic_hammer_right",id:"85eae421-c1e8-4f34-b9f6-00ecdc6228f4"}'
        ),
        Item.of(
            'tetra:modular_double',
            '{Damage:0,"double/basic_hammer_left_material":"basic_hammer/stone","double/basic_hammer_right_material":"basic_hammer/stone","double/basic_handle_material":"basic_handle/stick","double/handle":"double/basic_handle","double/head_left":"double/basic_hammer_left","double/head_right":"double/basic_hammer_right",id:"5e132b1f-f860-4244-b027-df75804ac097"}'
        ),
        Item.of(
            'tetra:modular_double',
            '{Damage:0,"double/basic_hammer_left_material":"basic_hammer/iron","double/basic_hammer_right_material":"basic_hammer/iron","double/basic_handle_material":"basic_handle/spruce","double/handle":"double/basic_handle","double/head_left":"double/basic_hammer_left","double/head_right":"double/basic_hammer_right",id:"2e064b20-ae8c-4c9b-97f1-dd68189d29d8"}'
        ),
        Item.of(
            'tetra:modular_double',
            '{Damage:0,"double/basic_hammer_left_material":"basic_hammer/blackstone","double/basic_hammer_right_material":"basic_hammer/blackstone","double/basic_handle_material":"basic_handle/spruce","double/handle":"double/basic_handle","double/head_left":"double/basic_hammer_left","double/head_right":"double/basic_hammer_right",id:"d604f4d0-c50e-4015-926b-3f7b007c36e7"}'
        ),
        Item.of(
            'tetra:modular_double',
            '{Damage:0,"double/basic_hammer_left_material":"basic_hammer/obsidian","double/basic_hammer_right_material":"basic_hammer/obsidian","double/basic_handle_material":"basic_handle/iron","double/handle":"double/basic_handle","double/head_left":"double/basic_hammer_left","double/head_right":"double/basic_hammer_right",id:"611bfca6-0e47-4668-b215-384b06057cc4"}'
        ),
        Item.of(
            'tetra:modular_double',
            '{Damage:0,"double/basic_hammer_left_material":"basic_hammer/netherite","double/basic_hammer_right_material":"basic_hammer/netherite","double/basic_handle_material":"basic_handle/forged_beam","double/handle":"double/basic_handle","double/head_left":"double/basic_hammer_left","double/head_right":"double/basic_hammer_right",id:"14aa886d-9c09-4f88-91fe-87b9ed6c59ee"}'
        ),
        Item.of(
            'tetra:modular_sword',
            '{Damage:0,HideFlags:1,honing_progress:305,id:"87f12176-abdd-4d89-a0a3-edd46f47f77d","sword/basic_hilt_material":"basic_hilt/stick","sword/blade":"sword/short_blade","sword/blade:arrested":0,"sword/hilt":"sword/basic_hilt","sword/hilt:basic_hilt/soot":0,"sword/short_blade_material":"short_blade/obsidian"}'
        ),
        Item.of(
            'tetra:modular_double',
            '{Damage:0,HideFlags:1,"double/basic_handle_material":"basic_handle/iron","double/butt_right_material":"butt/netherite","double/claw_left_material":"claw/netherite","double/handle":"double/basic_handle","double/head_left":"double/claw_left","double/head_right":"double/butt_right",honing_progress:365,id:"35d5e2f0-efff-42a6-9971-c0919f20aef5"}'
        ),
        Item.of(
            'tetra:modular_sword',
            '{Damage:0,id:"5fc9fae8-6c21-4cb0-a465-f039ee94c800","sword/basic_hilt_material":"basic_hilt/stick","sword/blade":"sword/stonecutter","sword/hilt":"sword/basic_hilt","sword/stonecutter_material":"stonecutter/stonecutter"}'
        ),
        Item.of(
            'tetra:modular_single',
            '{Damage:0,id:"a6fba635-4540-4c6e-8719-b097e9a49cf4","single/basic_handle_material":"basic_handle/stick","single/earthpiercer_material":"earthpiercer/earthpiercer","single/handle":"single/basic_handle","single/head":"single/earthpiercer"}'
        ),
    ]

    for (let item of itemsToAdd) {
        event.add(item)
        if (global.debug) {
            console.log(`Adding item to JEI: ${item}`)
        }
    }
})

image image

aaronhowser1 commented 1 year ago

just do event.add("c:hidden_from_recipe_viewers", /[your item here]/)

What is c:hidden_from_recipe_viewers, and why would I be using that in a script that adds items to view? Is that a fabric thing? Maybe I should have specified I'm on forge on 1.19

lxly9 commented 1 year ago

JEIEvents

idk about adding but removing works by just using the event i specified above

aaronhowser1 commented 1 year ago

As for hiding, this also doesn't fully work

JEIEvents.hideItems((event) => {

    for (let item of global.itemsToRemove) {
        event.hide(item)
    }

    event.hide([/ae2:facade/])
})

where global.itemsToRemove is

global.itemsToRemove = [
    /prefab.*swift/,
    /prefab.*sickle/,
    // /thermal.*device/,
    // /thermal.*cell/,
    // /thermal.*grenade/,
    // /thermal.*tnt/
]

image

aaronhowser1 commented 1 year ago

JEIEvents

idk about adding but removing works by just using the event i specified above

That's not how KubeJS works. You can't just rawdog event. into the ether, it has to be in an event. event is a variable, it's an argument.

BookerCatch commented 1 year ago

As a temporary workaround, you can just finesse JsonIO to achieve the same effect. See below and populate the empty list with items or fluids using the syntax outlined in the repo's wiki. Iterate over a list of ingredients and push them to the list using specific syntax. I'll post a more detailed example in kubejs's discord shortly.

  let obj = {
    removed: [],
  };

  JsonIO.write("kubejs/assets/emi/index/stacks/hidden_stacks.json", obj);
Bluberry-Kat commented 1 year ago

aaron is also requesting a way to add stacks through kubejs.
there is no way to do this through kubejs right now.
here is documentation for the json method (for adding and removing) in the meantime.
https://github.com/emilyploszaj/emi/wiki/Hiding-and-Adding-Index-Stacks

this isn't the first time kubejs support has been requested. this will have to be deliberated

lxly9 commented 1 year ago

JEIEvents

idk about adding but removing works by just using the event i specified above

That's not how KubeJS works. You can't just rawdog event. into the ether, it has to be in an event. event is a variable, it's an argument.

ServerEvents.tags('item', event => { event.add("c:hidden_from_recipe_viewers", /[your item here]/) })

i thought it was given that you use server events to hide something. you dont need to be so hostile...

BookerCatch commented 1 year ago

JEIEvents

idk about adding but removing works by just using the event i specified above

That's not how KubeJS works. You can't just rawdog event. into the ether, it has to be in an event. event is a variable, it's an argument.

ServerEvents.tags('item', event => { event.add("c:hidden_from_recipe_viewers", /[your item here]/) })

i thought it was given that you use server events to hide something. you dont need to be so hostile...

Just wanted to chime in to comment that the tag works great for simple item stacks, but more complex cases including nbt stacks, like enchanted books, potions, etc. will have to abide by the examples provided in the wiki as Bluberry-Kat mentioned. So it is for that reason I advise just creating custom objects and writing them with JsonIO. At least for complex cases.

BookerCatch commented 1 year ago

Oh, to the OP, here is a very specific, copy-pasteable example of adding items using JsonIO. No events necessary, although it's preferable to have this in server or startup scripts, because from what I gathered, it won't load properly in client scripts unless you manually F3+T

let myArbitrayListOfItems = [
  "minecraft:stone",
  "minecraft:enchanted_book{StoredEnchantments:[{id:'minecraft:fire_aspect',lvl:1s}]}"
]

let obj = {
    added: [],
  };

  myArbitrayListOfItems.forEach(item => {
    obj.added.push({
      stack: `item:${item}`
    })
  })

JsonIO.write("kubejs/assets/emi/index/stacks/my_added_stacks.json", obj);
BookerCatch commented 1 year ago

@aaronhowser1 Here is another example, this time literally just what you wanted. I haven't tested if it works with JEI alone anymore, but it works with JEI+EMI.

if (Platform.isLoaded("tetra")) {
  var wt = [
    "tetra:modular_sword{HideFlags:1,'sword/basic_blade_material':'basic_blade/oak','sword/basic_hilt_material':'basic_hilt/stick','sword/blade':'sword/basic_blade','sword/decorative_pommel_material':'decorative_pommel/oak','sword/guard':'sword/makeshift_guard','sword/hilt':'sword/basic_hilt','sword/makeshift_guard_material':'makeshift_guard/oak','sword/pommel':'sword/decorative_pommel'}",
    "tetra:modular_single{HideFlags:1,'single/basic_handle_material':'basic_handle/stick','single/basic_shovel_material':'basic_shovel/oak','single/handle':'single/basic_handle','single/head':'single/basic_shovel'}",
    "tetra:modular_double{HideFlags:1,'double/basic_handle_material':'basic_handle/stick','double/basic_pickaxe_left_material':'basic_pickaxe/oak','double/basic_pickaxe_right_material':'basic_pickaxe/oak','double/handle':'double/basic_handle','double/head_left':'double/basic_pickaxe_left','double/head_right':'double/basic_pickaxe_right'}",
    "tetra:modular_double{HideFlags:1,'double/basic_handle_material':'basic_handle/stick','double/basic_axe_left_material':'basic_axe/oak','double/basic_axe_right_material':'basic_axe/oak','double/handle':'double/basic_handle','double/head_left':'double/basic_axe_left','double/head_right':'double/basic_axe_right'}",
    "tetra:modular_double{HideFlags:1,'double/basic_handle_material':'basic_handle/stick','double/butt_right_material':'butt/oak','double/handle':'double/basic_handle','double/head_left':'double/hoe_left','double/head_right':'double/butt_right','double/hoe_left_material':'hoe/oak'}",
  ];

  if (Platform.isLoaded("jei") && !Platform.isLoaded("emi")) {
    JEIEvents.addItems((event) => {
      wt.forEach((tool) => {
        event.add(tool);
      });
    });

    JEIEvents.subtypes((event) => {
      event.registerInterpreter("tetra:modular_sword", (stack) => {
        if (Item.of(wt[0].weakNBT().test(stack))) {
          return "wooden sword";
        } else {
          return null;
        }
      });

      event.registerInterpreter("tetra:modular_single", (stack) => {
        if (wt[1].weakNBT().test(stack)) {
          return "wooden shovel";
        } else {
          return null;
        }
      });

      event.registerInterpreter("tetra:modular_double", (stack) => {
        if (wt[2].weakNBT().test(stack)) {
          return "wooden pickaxe";
        } else if (wt[3].weakNBT().test(stack)) {
          return "wooden axe";
        } else if (wt[4].weakNBT().test(stack)) {
          return "wooden hoe";
        } else {
          return null;
        }
      });
    });
  } else if (Platform.isLoaded("emi")) {
    let obj = {
      added: [],
    };
    wt.forEach((tool) => {
      obj.added.push({
        stack: `item:${tool}`,
      });
    });

    JsonIO.write("kubejs/assets/emi/index/stacks/tetra_tools.json", obj);
  }
}
emilyploszaj commented 1 year ago

Wow there is a lot of discussion on this bug, I'll do my best to summarize my thoughts.

It's worth noting off the bat that my experience with KubeJS is minimal, and from my investigation it seems like the JEI/REI integration that exists is inside of and maintained by the KubeJS team.

#c:hidden_from_recipe_viewers is the first class index stack removal solution supported by all of JEI, REI, and EMI as of relatively recently. Any item, fluid, or block in their respective tags will be hidden from the index. In addition, EMI also removes recipes that are derivative of those items, such as dying, repairing, anvil enchanting and repairing, etc. I'd recommend utilization of this tag for general stack removing as it supports having tags, and should be trivial to manipulate via KubeJS.

For other resource formats (specifically resource packs, as EMI is a client side mods) present on the Modpack Section of the Wiki, I believe they should be relatively trivial to interface with using KubeJS's JsonIO task if what is shown above is how it works. I would consider it slightly less nice than dedicated events, but the formats are relatively simple for adding/removing stacks.

Considering the KubeJS owns and maintains support for, and especially considering my inexperience with the project, I believe it'd be most reasonable and best to continue the tradition and have them be responsible for EMI integration as well.

Is this a reasonable collection of information? Let me know if you need more guidance with EMI's resource formats so I can augment the wiki or if you think my conclusion is unreasonable.

SiverDX commented 1 year ago

Regarding hiding things from JEI using JEI api: JEI uses an internal object / list to store hidden items

EMI gets all items / resources from JEI with the explicit call to include hidden items

Thats why you're still seeing them

emilyploszaj commented 1 year ago

EMI doesn't really have a great way of getting info from JEI for added stacks that I can think of at the moment, but I was able to work in removal through KubeJS in 1.0.2. I'll look into stack addition further and see if I can find a solution there eventually.