#Trying to replicate bartering using entityJS

60 messages · Page 1 of 1 (latest)

ruby sun
#

I am trying to replace villager trading with bartering, as with piglins. I was trying to use entityJS entity modification event .canPickupLoot to enable them to pick up emeralds, and then I believe I could use onItemPickUp to create the bartering functionality. However, it seems villagers already have canpPickUpLoot set to true, for breeding and farming I suppose. I can't figure out how to modify this to allow them to also pick up emeralds. Does anyone have a suggestion / workaround?

hasty glacierBOT
#

Once your ticket has been resolved, please close it with </ticket close:1054771505520717835> command!

ruby sun
#

Specifically, I want emeralds thrown on the ground near a villager to disappear one at a time and then drop a specified loot table a few seconds later, which can depend on the villagers profession

celest wyvern
earnest crag
#

this will need special handling because the modifyEntity event only modifies methods that arent explicitly overridden by the entity top level class, in this case, Villager.
it is still possible through the .aiStep() to replicate how minecraft detects bounding box interaction with an item entity and then remove one from that entity stack and place it in the villagers mainhand. you would then through persistent data keep track of how long the villager is holding onto the emerald in its mainhanditem slot and remove it after a bit, popping a random item from a selection. for reference this is the java method for how they detect item entities touching the mob java for(ItemEntity itementity : this.level().getEntitiesOfClass(ItemEntity.class, this.getBoundingBox().inflate((double)vec3i.getX(), (double)vec3i.getY(), (double)vec3i.getZ()))) { if (!itementity.isRemoved() && !itementity.getItem().isEmpty() && !itementity.hasPickUpDelay() && this.wantsToPickUp(itementity.getItem())) { this.pickUpItem(itementity); } }
this would translate to something like this where you would call the function inside your aiStep callback ```js
let ItemEntity = Java.loadClass("net.minecraft.world.entity.item.ItemEntity")
/**
*

  • @param {Internal.LivingEntity} entity
    */
    function hasItemNearby(entity) {
    for (let e of entity.level.getEntitiesOfClass(ItemEntity, entity.getBoundingBox().inflate(1, 0, 1))) {
    let/**@type {Internal.ItemEntity} */ itementity = e
    if (!itementity.isRemoved() && !itementity.getItem().isEmpty() && !itementity.hasPickUpDelay()) {
    if (entity.mainHandItem.id == "minecraft:air") {
    entity.setItemInHand("main_hand", itementity.getItem())
    itementity.item.count--
    }
    }
    }
    }```
celest wyvern
#

Oh I was trying to do this without that part, instead having a player give an enderman an item directly and have them look at it for a sec then throw something

I'll update my progress here I guess lol

celest wyvern
#

Actually maybe I will...

earnest crag
celest wyvern
rough scrollBOT
#

Paste version of enderBartering.js from @celest wyvern

celest wyvern
# earnest crag very cool

Do you know how I can disable endermen teleporting/placing a block temporarily?

I am just going to double check it still has the block and within range for now :P

earnest crag
#

you can try something like this ```js
mob.goalSelector.runningGoals.forEach(g => {
if (g.goal.class instanceof Java.loadClass("net.minecraft.world.entity.monster.EnderMan$EndermanTakeBlockGoal")) {
g.goal.stop()
}
})

there is another example of this in example scripts for controlling tamed mob goals [here](<https://discord.com/channels/303440391124942858/1360058916666605628>)
celest wyvern
#

Thanks!

celest wyvern
#

But it maybe doable in EntityJS I am not familiar enough

queen root
celest wyvern
#

I like to think they're fairly calm and reasonable when not angered

earnest crag
earnest crag
celest wyvern
#

can't get that class load instanceof check to work 😭 I am just gonna compare strings 🥹

earnest crag
celest wyvern
rough scrollBOT
#

Paste version of enderBarteringServer.js, enderBarteringStartup.js from @celest wyvern

celest wyvern
#

and fake loot table lmao

naive kiln
celest wyvern
naive kiln
#

Ah gotcha

naive kiln
#

You should post this i. #1048591172165189632

#

It's a quite useful script

celest wyvern
#

Liopyu giving me a "lgtm" or some constructive criticism lol

#

I mean I have quite a few scripts with more "advanced" contents I should post

naive kiln
#

fair enough

earnest crag
earnest crag
celest wyvern
earnest crag
#

hmm, yeah youd have to do it the official way with loot params

earnest crag
# celest wyvern doesn't give a entity stack since it can output multiple, then I can't apply mot...
let ServerLevel = Java.loadClass("net.minecraft.server.level.ServerLevel")
let LootBuilder = Java.loadClass("net.minecraft.world.level.storage.loot.LootParams$Builder")
let LootContextParams = Java.loadClass("net.minecraft.world.level.storage.loot.parameters.LootContextParams")
let ItemEntity = Java.loadClass("net.minecraft.world.entity.item.ItemEntity")
/**
 * 
 * @param {ResourceLocation_} lootTableId 
 * @param {Internal.PathfinderMob} entity 
 * @returns {Internal.ObjectArrayList<Internal.ItemStack>}
 */
function getLootFromTable(lootTableId, entity) {
    let level = entity.level
    let server = level.getServer()
    if (server == null) return []
    let table = server.getLootData().getLootTable(lootTableId)
    if (table == null) return []
    let paramSet = table.getParamSet()
    let builder = new LootBuilder(level)
    let required = paramSet.getRequired()
    if (required.contains(LootContextParams.THIS_ENTITY)) builder = builder.withParameter(LootContextParams.THIS_ENTITY, entity)
    if (required.contains(LootContextParams.ORIGIN)) builder = builder.withParameter(LootContextParams.ORIGIN, entity.position())
    let params = builder.create(paramSet)
    let items = table.getRandomItems(params)
    return items
}
// example usage of loot func
ItemEvents.rightClicked(event => {
    let { level, entity } = event
    let loot = getLootFromTable("minecraft:chests/ancient_city", entity)
    loot.forEach(item => {
        let itemEntity = new ItemEntity(level, entity.x, entity.y, entity.z, item)
        itemEntity.setPickUpDelay(20)
        itemEntity.spawn()
    })
})```

this way you would be able to set the motion for each of the items you get from the official loot table
#

@naive kiln if you were also interested in this

celest wyvern
#

Ouh wow

earnest crag
#

this was basically pulled from the official PiglinAi code and how they do it

celest wyvern
#

Very interesting

earnest crag
#

||just with a lot of reflection||

naive kiln
#

That is impressive and very useful, thanks @earnest crag

earnest crag
#

np, that being said there isnt much of a difference since people will probably not change your modpack's loot tables, it is a good example though

#

also is this ticket finished? if so then

rough scrollBOT
#

Please close your ticket (with </ticket close:1054771505520717835> or the button atop this thread) once you resolved your issue!
This also helps others that would like to help out, as they don't have to look into this thread to check if it has been resolved by now.

Do you have any other questions regarding your issue? Feel free to ask!
Note: You should create a new post for unrelated issues.

earnest crag
naive kiln
#

Lol

earnest crag
#

oh the op isnt even active in it

celest wyvern
#

Not even our ticket I took it over absolutecinema

earnest crag
#

lmao

#

well, they'll come back to it if/when they come back to it

naive kiln
#

Fucking hilarious

earnest crag
#

imma go ahead and close it though, thank you all for your contributions