#Trying to create an entity

115 messages · Page 1 of 1 (latest)

fluid ibex
#

I am currently trying to create an entity that:

  1. Doesn't move and is resistant to knockback.
  2. Has a spawn-in animation and plays a sound when initially spawned.
  3. Will turn its head along the Y-axis to face the closest player after the spawn-in animation is done playing.
  4. Has a hitbox that is the size of one block.
  5. Is resistant to fire, fall damage, drowning. (I know how to make it immune to fire and drowning.)

I'll provide the assets here:

  • Files go under assets/amfc/....
  • BBMODEL file will also be provided.
knotty oxideBOT
#

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

stoic otterBOT
#

Paste version of stone_golem.geo.json, stone_golem.spawn.json from @fluid ibex

fluid ibex
#

This is all I have so far for code
server_scripts/src/entities.js

StartupEvents.registry('entity_type', e => {
    e.create('amfc:stone_golem', 'entityjs:living')
        .canJump(false)
        .canBreatheUnderwater(true)
        .fireImmune(true)
        .isAlwaysExperienceDropper(false)
        .noEggItem()
})
#

And squoshi told me I should ping @clear hatch.

woeful gate
#

indeed

clear hatch
# fluid ibex And squoshi told me I should ping <@696035922030100561>.
  1. youll want .isPushable(false)
  2. add a triggerable animation to the animationcontroller and trigger it on added to world, also note youll have to rename your stone_golem.spawn.json to stone_golem.animation.json
  3. get the geo bone and rotate it along the entity's head rotation, then in the .tick() method after it's 20 ticks old have it look at the nearest player if there is one
  4. .sized(1,1)
  5. isInvulnerableTo()
let RenderUtils = Java.loadClass("software.bernie.geckolib.util.RenderUtils")
StartupEvents.registry('entity_type', e => {
    e.create('amfc:stone_golem', 'entityjs:living')
        .addAnimationController("somecontrollername", 1, event => {
            let { entity } = event
            // The first arguemnt is the name of the animation found in the json animation file
            event.addTriggerableAnimation('animation.stone_golem.spawn', 'spawning', 'default')
            let geoModel = RenderUtils.getGeoModelForEntity(entity)
            let /**@type {Internal.GeoBone} */ head = geoModel.getBone("head").get()
            if (head) {
                head.setRotX(entity.yHeadRot)
            }
            return true;
        })
        .onAddedToWorld( /**@param {Internal.BaseLivingEntityJS} entity */ entity => {
            entity.triggerAnimation("somecontrollername", "spawning")
        })
        .tick(entity => {
            let aabb = entity.boundingBox.inflate(20)
            entity.level.getEntitiesWithin(aabb).forEach(target => {
                if ((!target || !target.isPlayer())) return
                // Delay them looking at the player 'til they're done spawning
                if (entity.age > 20) {
                    entity.lookAt("eyes", new Vec3d(target.x, target.y, target.z))
                }
            })

        })
        .isPushable(false)
        .sized(1, 1)
        .isInvulnerableTo(ctx => {
            let { damageSource, entity } = ctx
            if (damageSource == entity.level.damageSources().fall() ||
                damageSource == entity.level.damageSources().inFire() ||
                damageSource == entity.level.damageSources().onFire() ||
                damageSource == entity.level.damageSources().lava() ||
                damageSource == entity.level.damageSources().hotFloor() ||
                damageSource == entity.level.damageSources().drown()
            ) {
                return true
            }
            return false
        })
        .canJump(false)
        .canBreatheUnderwater(true)
        .fireImmune(true)
        .isAlwaysExperienceDropper(false)
        .noEggItem()
})```
fluid ibex
#

thank you Lio

clear hatch
#

you remove canjump

#

some methods wont be there since you're using the living entity base builder

#

either that or do "entityjs:mob" or something, should be little difference tbh

#

i just realized youll also need to remove noEggItem as well if you dont decide to go with the mob builder

fluid ibex
#

alrighty then

fluid ibex
clear hatch
#

??neversay

stoic otterBOT
# clear hatch ??neversay

Never say 'it crashed', 'it errored', or 'it didn't work' without providing the full scripts and log/crash report!

fluid ibex
#

I am very sorry, gimme a moment.

fluid ibex
stoic otterBOT
#

Paste version of latest.log from @fluid ibex

clear hatch
#

amfc:geo/entity/stone_golem.geo.json: Unable to find model

#

where'd you put your stone_golem.geo.json?

stoic otterBOT
#

📁 File Structure for Geckolib Entities

Ensure the following file structure for Geckolib entity animations, geo models, and textures:

  • Animations: assets/modname/animations/entity/mobname.animation.json
  • Geo Model: assets/modname/geo/entity/mobname.geo.json
  • Texture: assets/modname/textures/entity/mobname.png
fluid ibex
#

damn i forgot an entity folder after geo

#

my fault

clear hatch
#

happens hih

fluid ibex
clear hatch
#

lmao, sec

fluid ibex
#

its ight

clear hatch
#

i guess setRotX was the wrong one js head.setRotX(entity.yHeadRot)

fluid ibex
#

What would I change?

clear hatch
#

put your thing in a global event like this so you can do /kubejs reload startup_scripts js .addAnimationController("somecontrollername", 1, event => global.animation(event))

then outside the startup event```js
/**
*

  • @param {Internal.BaseLivingEntityBuilder$AnimationEventJS<Internal.MobEntityJS>} event
  • @returns
    */
    global.animation = event => {
    let { entity } = event
    // The first arguemnt is the name of the animation found in the json animation file
    event.addTriggerableAnimation('animation.stone_golem.spawn', 'spawning', 'default')
    let geoModel = RenderUtils.getGeoModelForEntity(entity)
    let /**@type {Internal.GeoBone} */ head = geoModel.getBone("head").get()
    if (head) {
    head.setRotY(entity.yHeadRot)
    }
    return true;
    }```
#

we'll try setRotY next

clear hatch
#

i think i know whats happening

#

it auto turns already and is maybe turning the head extra more than it needs to

fluid ibex
#

maybe could it just not turn its body and only turn its head

clear hatch
#

comment out thehead.setrotY line and do /kubejs reload startup_scripts and see what happens

fluid ibex
#

and why is the spawn animation no worky 💀

clear hatch
clear hatch
#

also did you fix your animation file name/

fluid ibex
#

ah ok

fluid ibex
#

bruh the spawn animation is still not working

clear hatch
#

whered you put your animation.json?

fluid ibex
#

sorry gimme a moment

fluid ibex
#

it does the same thing where it just stays still for a moment and then locks on

clear hatch
#

send the full script as well as the texture

#

texture being the only thing you havent sent so far

#

actually no need, i forgot you sent the actual bb file lol

#

just the script

fluid ibex
stoic otterBOT
#

Paste version of entities.js from @fluid ibex

clear hatch
#

ty

clear hatch
fluid ibex
#

yeah thats what i want it to look like

clear hatch
#

bet

#
// thank you Liopyu for the script, I am forever in his debt

let RenderUtils = Java.loadClass("software.bernie.geckolib.util.RenderUtils")
/**
 * 
 * @param {Internal.BaseLivingEntityBuilder$AnimationEventJS<Internal.MobEntityJS>} event 
 * @returns 
 */
global.animation = event => {
    let { entity } = event
    if (!(entity.age > 40)) {
        event.thenPlay("spawn")
    }
    let aabb = entity.boundingBox.inflate(20);
    let nearestPlayer = null;
    let nearestDistance = Infinity;
    try {
        entity.level.getEntitiesWithin(aabb).forEach(target => {
            if (!target || !target.isPlayer()) return;

            let distance = entity.distanceToSqr(target);
            if (distance < nearestDistance) {
                nearestDistance = distance;
                nearestPlayer = target;
            }
        });

        if (nearestPlayer) {
            if (entity.age > 40) {
                let dx = nearestPlayer.x - entity.x;
                let dz = nearestPlayer.z - entity.z;
                let yaw = Math.atan2(dz, dx) * (180 / JavaMath.PI) - 90;
                let geoModel = RenderUtils.getGeoModelForEntity(entity)
                let /**@type {Internal.GeoBone} */ head = geoModel.getBone("head").get()
                if (head) {
                    head.setRotY(-(yaw / 57))
                }
            }
        }
    } catch (error) {
        console.log(error)
    }
    return true;
}
StartupEvents.registry('entity_type', e => {
    e.create('amfc:stone_golem', 'entityjs:mob')
        .canJump(false)
        .canBreatheUnderwater(true)
        .fireImmune(true)
        .isAlwaysExperienceDropper(false)
        .noEggItem()
        .addAnimationController("somecontrollername", 1, event => global.animation(event))
        .isPushable(false)
        .sized(1, 1)
        .isInvulnerableTo(ctx => {
            let { damageSource, entity } = ctx
            if (damageSource == entity.level.damageSources().fall() ||
                damageSource == entity.level.damageSources().inFire() ||
                damageSource == entity.level.damageSources().onFire() ||
                damageSource == entity.level.damageSources().lava() ||
                damageSource == entity.level.damageSources().hotFloor() ||
                damageSource == entity.level.damageSources().drown()
            ) {
                return true
            }
            return false
        })
})```
#

oh sec

stoic otterBOT
#

Paste version of stone_golem.animation.json from @clear hatch

fluid ibex
#

Why is the head on backwards

#

I might have must've messed something up in the model gimme a moment

#

Hey @clear hatch, how could I make it where the head smoothly rotates to face the nearest player instead of its head snapping to face them.

#

Its a bit jarring seeing the head snap to face the player after the spawn animation is done playing.

clear hatch
#

youd have to lerp the head

fluid ibex
#

thats a funny word

#

And how would I go about doing that?

clear hatch
#

replace the global.animation function with this one ```js
global.animation = event => {
let { entity } = event
if (!(entity.age > 40)) {
event.thenPlay("spawn")
}
let aabb = entity.boundingBox.inflate(20);
let nearestPlayer = null;
let nearestDistance = Infinity;
try {
entity.level.getEntitiesWithin(aabb).forEach(target => {
if (!target || !target.isPlayer()) return;

        let distance = entity.distanceToSqr(target);
        if (distance < nearestDistance) {
            nearestDistance = distance;
            nearestPlayer = target;
        }
    });

    if (nearestPlayer) {
        if (entity.age > 40) {
            let dx = nearestPlayer.x - entity.x;
            let dz = nearestPlayer.z - entity.z;
            let yaw = Math.atan2(dz, dx) * (180 / JavaMath.PI) - 90;
            let geoModel = RenderUtils.getGeoModelForEntity(entity);
            let /** @type {Internal.GeoBone} */ head = geoModel.getBone("head").get();
            if (head) {
                let currentRotY = head.getRotY(); 
                let targetRotY = -(yaw / 57); 

                let smoothingFactor = 0.1; // Adjust for speed of smoothing (lower = slower)
                let smoothedRotY = currentRotY + (targetRotY - currentRotY) * smoothingFactor;

                head.setRotY(smoothedRotY); 
            }
        }
    }

} catch (error) {
    console.log(error)
}
return true;

}```

clear hatch
fluid ibex
clear hatch
#

any errors in logs?

#

also does it do this even with the first global.animation i sent?

fluid ibex
#

nope only with this new one

clear hatch
#

ah

fluid ibex
clear hatch
#

thats with the new one?

fluid ibex
stoic otterBOT
#

Paste version of latest.log from @fluid ibex

fluid ibex
clear hatch
#

gotcha

#

just send your startup logs

#

??kjslogs

#

ugh did don remove that macro

fluid ibex
stoic otterBOT
#

Paste version of startup.log from @fluid ibex

clear hatch
#

ty

stuck shale
clear hatch
#

ok no errors

stuck shale
#

it's been renamed

#

??log startup

stoic otterBOT
# stuck shale ??log startup

You can find your KubeJS startup log in /minecraft/logs/kubejs/startup.log.
If you are on 1.18 or 1.16 it will be called startup.txt.
Please send the file directly, without links or snippets.

clear hatch
#

o

stuck shale
#

and it's a bundle now

#

ye

clear hatch
clear hatch
fluid ibex
#

Alrighty then

clear hatch
#

or ask squoshi about it, hes good at that

fluid ibex
#

Lio how do I change the hurt noise?

#

Or hurt sound

#

Because there's a thing for death sound (.setDeathSound()) but not for hurt sound?

clear hatch
#
.setHurtSound(context => {
    // Custom logic to determine the hurt sound for the entity
    // You can use information from the HurtContext to customize the sound based on the context
    const { entity, damageSource } = context;
    // Determine the hurt sound based on the type of damage source
    switch (damageSource.getType()) {
        case "fire":
            return "minecraft:entity.generic.burn";
        case "fall":
            return "minecraft:entity.generic.hurt";
        case "drown":
            return "minecraft:entity.generic.hurt";
        case "explosion":
            return "minecraft:entity.generic.explode";
        default:
            return "minecraft:entity.generic.explode";
    }
})```
fluid ibex
#

ah I see

clear hatch
#

if you have probejs then there are examples in the text you can use

fluid ibex
#

neat

kind summit
#

setRotY is yaw
setRotX is pitch
and setRotZ is roll?