#Batch replace thrown item that matches tags that matches
242 messages · Page 1 of 1 (latest)
Once your ticket has been resolved, please close it with </ticket close:1054771505520717835> command!
the tags event is for adding and removing tags from items, blocks, entities, etc
you also cannot nest events like that, it wont have any effect, except for the outer one
i cant remember the syntax to find the item in the item entity 
Ah yes exactly what I've guessed, nested events are horrible anyway
I already have something llike this:
let swapSpawn = (old_input, new_input) =>{
if (event.entity.item.hasTag(old_input)){
event.entity.setItem(Item.of(new_input, event.entity.item.count))
}
}
if (event.entity.type == 'minecraft:item'){
swapSpawn('minecraft:coals',"minecraft:coal")
swapSpawn('c:raw_tin_ores',"modern_industrialization:raw_tin")
swapSpawn('c:raw_tungsten_ores',"techreborn:raw_tungsten")
swapSpawn('c:raw_silver_ores',"modern_industrialization:raw_silver")
swapSpawn('c:raw_lead_ores',"techreborn:raw_lead")
}```
that seems right at first glance, does it not have any effect?
can I write something like a regex or a regex concat'd string in place of old_input?
It does
you should be able to write regex, im pretty sure
hm maybe not, looking at kjs github, it only seems to be accepting resourcelocation
default boolean kjs$hasTag(ResourceLocation tag) {
return kjs$self().is(Tags.item(tag));
}
ow
I want to iterate thru every tag that starts with #c:raw_, and for each one of the tags, I swap the spawned item to the first item in that tag. Can I do that with something like tag.at(0)?
(cursed idea)
you could try something like this
let items = Ingredient.of(/regex here/).itemIds
if(items.contains(event.entity.item.id)) //do something

if you want the first item in a tag you can use Item.of()
you can??
if you look at my example ^
Ingredient will return a list, so it gives you all the items with that tag
if you replace with Item, it will get the first item
Item.of(/regex here/) // will give you the first ItemStack with what youre looking for
can I get the first item in the list of items tho?
let items = Ingredient.of(/regex here/).itemIds
let item = Item.of(/regex here/)
my senses tell that something will go wrong under this circumstance...
will two matches be the same?
umm how do you mean that 
I think, I mean, I think that Item.of an regex will just gracefully return one item that just so happen to happily match first
...I don't know if I'm thinking straight
ah you mean you wanna guarantee that it returns the same item every time
similarly, the Ingredient.of might just return every tag that matches, like {#c:raw_iron_ores, #c:raw_cods...}
as far as i know, i think it should do that, unless you add or remove mods, that will change that list
and if Item.of only contains something like some_mod:raw_lemon
I'm then doing a thing of pure stupid
but why not just have it set to something manual instead
let me find something on github
also what does Ingredient.of return? Tags and Items?
Ingredient.of() returns a list of Item
which can be singular Items right
if you give it an item ID, it will only have one item, the one you gave it
but if you give it regex or a tag, it will return a list of items matching that filter
if you wanna test it, put something like this in a chat event:
console.log(Ingredient.of('#minecraft:logs').itemIds)
console.log(Ingredient.of(/carpet/).itemIds)
then just do /kubejs reload server_scripts and write something in chat, then look at the logs
testing stuff like that in a chat event is really easy cuz you dont need to /reload for half an hour, and you can trigger it manually by sending a message
ye you can do that too, or check if it has an item by using .contains()
lemme try
let tags = Ingredient.of(/c:raw_.*/).itemIds
tags.forEach(tag => {
swapSpawn(tag,Item.of(tag))
})```
does this look good to you
i was actually thinking if the regex works with tags or just item IDs, and i have a feeling its just item IDs
however, maybe you could try this and let me know if it worked o.o
let tags = Ingredient.of(/#c:raw_.*/).itemIds
console.log(tags)
tags.forEach(tag => {
swapSpawn(tag,Item.of(tag))
})
keep in mind, if this does work, it will return a list of Item, not a list of tags
it will always be a list of items
hmm i wonder if theres a list of all the tags that are registered in the game
i know you can do Ingredient.all to get all the items in the game 
o_O would that be simply overkill
there has to be a list of all the tags somewhere
[21:46:57] [Server thread/INFO]: server_scripts:script2.js:19: [] [java.util.ArrayList]
empty tag
aw
oh wait
I missed a # in front of c
o.o
same result tho
meanwhile i asked in #off-topic if someone knows of such a list haha
welp shit
Lat said there isnt such a list
and the only way i can think of creating one is less than ideal
i made a new thread on this 
<#1074329179237142649 message>
hol up
someone gave me this gem
try this
console.log(Registry.ITEM.tags())
o_O
haha it took me 2 seconds to realise
this haha
um
look at my name
question: you're trying to do some weird 'after the fact' unification of items.... why not do it before they even get these things?
change loot tables for the ores (lootjs), change your oregen rules, unify your recipes (almost unified), etc.
Wow...
let RegistryMC = Java.loadClass("net.minecraft.core.Registry")
RegistryMC.ITEM.tagNames.map(e => e).forEach(tag => console.info(tag.toString()))
Actually it is
literally can't understand what happened here
@paper fulcrum
I guess it's because the stream returned by the method itself is actually not accessible by Rhino somehow
But by converting it to another stream via map, it becomes available magically
Hmm
um
The ReferencePipeline$Head is package private
PlayerEvents.chat(e => {
let RegistryMC = Java.loadClass("net.minecraft.core.Registry")
RegistryMC.ITEM.tagNames.map(e => e).forEach(tag => console.info(tag.toString()))
})
So it's possible that Rhino did try to get this class as public class
am i doing something wrong and im just being stupid
I think that's not where it is
You forgot to reload?
The code should print each tag name as a new line I think
does the java class thing need a full reload 
ive been using the chat event to do the faster kjs server script reload
let me try that
thats what i found weird too~
hm hold on
i did get a different result, but still wrong
i need to put this in startup dont i
Weird
this is after the /reload with the same code in server scripts
Dunno what happened

i copied these 2 lines to startup and it worked
and just did /kjs reload startup blab
So sus
At least it worked
so i managed to make the server event work
but the results are a bit fishy
PlayerEvents.chat(e => {
const itemReg = Java.loadClass("net.minecraft.core.Registry").ITEM
const Collectors = Java.loadClass("java.util.stream.Collectors")
let tags = itemReg.getTagNames().map(key => key.location()).collect(Collectors.toList())
console.log(tags)
})
im... fairly sure theres more than that many tags
or does it look right
hmm
could actually be right, im basically on vanilla at this point
@deep elm das a list of all tags in the game >w>
I mean, I am also doing that too
are you using almost unified? because you can leverage some of it's methods to do the heavy lifting for you on the item replacement
But that doesn't account for what we already have in our chest
Oh it's for Fabric?
I'll look into it
it's for both, does all the recipe unification for you
k
but, you can lookup inside kjs what the replacement was. So.... you could run a check on any item thrown and see if it has a different item from unification and then change it to that
https://github.com/AlmostReliable/almostunified/wiki/KubeJS
AlmostUnified.getReplacementForItem(item)
but if you're not already using it and have already done your unification, probably unnecessary to add
k
...how do I match all tags to a regex?
you can iterate through the list and use /regex here/.test('thing to test')
might be able to use .filter() too
.filter(/^c:raw_/)?
ok
const itemReg = Java.loadClass("net.minecraft.core.Registry").ITEM
const Collectors = Java.loadClass("java.util.stream.Collectors")
let tags = itemReg.getTagNames().map(key => key.location()).collect(Collectors.toList()).filter(i => /^c:raw_.*/.test(i))
console.log(tags)
tags.forEach(tag => {
swapSpawn(tag,Item.of(tag))
})```
I think I wrote something illegible
show me the full script, theres something sussy wussy going on
EntityEvents.spawned(event => {
let swapSpawn = (old_input, new_input) =>{
if (event.entity.item.hasTag(old_input)){
event.entity.setItem(Item.of(new_input, event.entity.item.count))
}
}
if (event.entity.type == 'minecraft:item'){
const itemReg = Java.loadClass("net.minecraft.core.Registry").ITEM // offending line
const Collectors = Java.loadClass("java.util.stream.Collectors")
let tags = itemReg.getTagNames().map(key => key.location()).collect(Collectors.toList()).filter(i => /^c:raw_.*/.test(i))
console.log(tags)
tags.forEach(tag => {
swapSpawn(tag,Item.of(tag))
})
}
})```
I am a bit concerned about whether is this mapping used on Fabric
gimme a min
const itemReg = Java.loadClass('net.minecraft.core.Registry').ITEM
const Collectors = Java.loadClass('java.util.stream.Collectors')
const tagList = itemReg.getTagNames().map(key => key.location()).collect(Collectors.toList())
let getTagList = (regex) => tagList.filter(i => regex.test(i))
EntityEvents.spawned(event => {
if (event.entity.type != 'minecraft:item') return
let swapSpawn = (old_input, new_input) => {
if (event.entity.item.hasTag(old_input)) {
event.entity.setItem(Item.of(new_input, event.entity.item.count))
}
}
let tags = getTagList(/^c:raw_.*/)
console.log(tags)
tags.forEach(tag => swapSpawn(tag, Item.of(`#${tag}`)))
})
is (regex) just (regex)
extra question: I want to match tags but remove ones that has another undesired tag in it
let getTagList = (match, unmatch) => tagList.filter(i => match.test(i) && !unmatch.test(i))
``` like that?
no, thats what caused the issue, you also dont have a reason to, you only need to generate those values once, not every time a mob spawns
ah yeah that
you could move them to a completely different file if you want to
that's why it's "redeclared"
oh wait, under this circumstance I only need one match tag and one unmatch tag, for example c:raw_meats w/o c:raw_fishes
...in a recipe tho
(json recipe too, since it's not integrated with Kube
in that case i think you can replace .filter() with .match()
if i remmeber correctly
let me look it up
ah derp
its .find()
and it returns the first match
I mean I don't have to iterate thru tags again, I have two available, static tags
oh 
Ingredient.of(#c:raw_meats).without(#c:raw_fishes)... is the first syntax I came up with
or I can build a tag #custom:raw_meats_that_are_not_fish and use for later too
let getItemList = (tag, match, unmatch) => tag.find(i => match.test(i) && !unmatch.test(i))
or can I do that?
the functions looks right
oh wait I don't mean that
let getItemList = (tag, unmatch) => tag.find(i => !unmatch.test(i))
```is enough, since I remove some items from a known tag
then can I do
let items = getItemList('#c:raw_meats', '#c:raw_fishes')
items.forEach(item => {
...
Ingredient.of(item).toJson()
...
})
``` this?
its a string, so yeah 
mmmm
I replaced it with search and it doesn't complain there again
instead it's illegal forEach
im trying to think what changes youre making to the original code
but i feel like youve made so many small changes that you are literally back at square 1 where we started
lemme show you the whole thing I'm doing, on what's borked
ServerEvents.recipes(event => {
let getItemList = (tag, unmatch) => tag.match(i => !unmatch.test(i))
let items = getItemList('minecraft:logs_that_burn', 'c:stripped_logs')
items.forEach(item => {
event.custom({
type: "farmersdelight:cutting",
ingredients: [
Ingredient.of(item).toJson()
],
tool: {
type: 'farmersdelight:tool',
tag: 'c:tools/axes'
},
result: [
Item.of(item.replace(':',':stripped_')).toJson(),
Item.of('farmersdelight:tree_bark').toJson
],
sound: 'minecraft:item.axe.strip'
})
});
})```
right but
so first of all
it was .find(), but that obviously wont work, cuz you no longer have a list of items
you have a string
you have removed the list completely
ah yes fuck me
this is why i was saying i dont understand what youre trying to achieve now, because what was written before was generally correct
and now its completely fucked 
I know it won't convert a string to a tag, it's just a string
shot in the dark, but maybe try
let getItemList = (tag, unmatch) => Ingredient.of(tag).stacks.find(i => !i.hasTag(unmatch))
and also
let items = getItemList('#minecraft:logs_that_burn', 'c:stripped_logs')

cannot do find on null
mmmmmmmmmmmmmmmmmmm fuck me its a set
let getItemList = (tag, unmatch) => {
let stacks = Ingredient.of(tag).stacks
for(let item in stacks){
if(!item.hasTag(unmatch)) return item
}
return null
}
i dunno if theres a better way, its very late and my brain is disconnected
I guess we can go to sleep then
hasTag has illegal argument
I can't understand how's that illegal either
time to sleep I guess
I cut it to stacks and I got something like
Paste version of message.txt from @deep elm
I guess I need .itemIds?
let getItemList = (tag, unmatch) => Ingredient.of(tag).itemIds.filter(item => !unmatch.test(item))
ServerEvents.recipes(event => {
let items = getItemList('#minecraft:logs_that_burn', /stripped_.*/)
items.forEach(item => {
event.custom({
type: "farmersdelight:cutting",
ingredients: [
Ingredient.of(item).toJson()
],
tool: {
type: 'farmersdelight:tool',
tag: 'c:tools/axes'
},
result: [
Item.of(item.replace(':',':stripped_')).toResultJson(),
Item.of('farmersdelight:tree_bark').toResultJson()
],
sound: 'minecraft:item.axe.strip'
})
});
})```
Oh
it's gone now?
done!



