#Custom Mob Explosion and Threshold

66 messages · Page 1 of 1 (latest)

weak quail
#

So im currently trying to make a zombie that carries a bomb with himself, which behaves like a creeper, however, i want to enlarge how big the explosion is and what particle it can emite.
The other thing im trying to do is a threshold so that if the mob is at 50% hp, it will give certain buffs:

StartupEvents.registry("entity_type", event => {
    // Doom Zombie
    const doomZombie = event.create('doom_zombie', 'minecraft:creeper')
    doomZombie.mobCategory('monster')
    doomZombie.sized(0.6, 1.95)
    doomZombie.clientTrackingRange(32)
    doomZombie.defaultGoals(true)
    doomZombie.setRenderType('translucent')
    doomZombie.animationResource(() => 'kubejs:animations/entity/doom_zombie.animation.json')

    // idle / walk
    doomZombie.addAnimationController('movement', 1, event => {
        if (event.entity.animationProcedure && event.entity.animationProcedure !== 'empty') return false
        if (event.entity.isMoving()) {
            event.thenLoop('animation.doom_zombie.walk')
        } else {
            event.thenLoop('animation.doom_zombie.idle')
        }
        return true
    })

    // play procedure-driven animation
    doomZombie.addAnimationController('charge', 1, event => {
        if (event.entity.animationProcedure === 'animation.doom_zombie.attack') {
            event.thenLoop('animation.doom_zombie.attack')
            return true
        }
        return false
    })

    doomZombie.setAmbientSound('minecraft:entity.zombie.ambient')
    doomZombie.setDeathSound('minecraft:entity.zombie.death')
    doomZombie.setHurtSound(() => 'minecraft:entity.zombie.hurt')

    // Angry Zombie
    const angryZombie = event.create('angry_zombie', 'minecraft:zombie')
    angryZombie.mobCategory('monster')
    angryZombie.sized(0.6, 1.95)
    angryZombie.clientTrackingRange(32)
    angryZombie.defaultGoals(true)
    angryZombie.setRenderType('cutout')
    angryZombie.animationResource(() => 'kubejs:animations/entity/angry_zombie.animation.json')

    // idle / walk
    angryZombie.addAnimationController('movement', 1, event => {
        if (event.entity.animationProcedure && event.entity.animationProcedure !== 'empty') return false
        if (event.entity.isMoving()) {
            event.thenLoop('animation.angry_zombie.walk')
        } else {
            event.thenLoop('animation.angry_zombie.idle')
        }
        return true
    })

    // attack
    angryZombie.addAnimationController('attack', 1, event => {
        if (event.entity.swingTime > 0) {
            if (event.getController().getAnimationState() === 'STOPPED') {
                event.getController().forceAnimationReset()
                event.thenPlay('animation.angry_zombie.attack')
            }
        }
        return true
    })

    angryZombie.setAmbientSound('minecraft:entity.zombie.ambient')
    angryZombie.setDeathSound('minecraft:entity.zombie.death')
    angryZombie.setHurtSound(() => 'minecraft:entity.zombie.hurt')
})```

EntityJSEvents.modifyEntity(event => {
event.modify("kubejs:angry_zombie", builder => {
builder.tick(zombie => {
if (!zombie || zombie.level().isClientSide()) return

        const currentHealth = zombie.getHealth()
        const maxHealth = zombie.getMaxHealth()

        // If health drops below 50% of max
        if (currentHealth <= maxHealth * 0.5) {
            zombie.addEffect("minecraft:resistance", 200, 0)
            zombie.addEffect("minecraft:strength", 200, 0)
            zombie.addEffect("minecraft:speed", 200, 0)
        }
    })
})

})```

@modest vigil this is what i got right now, cant seem to get it to work

celest trailBOT
#

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

weak quail
#

kinda wish we had something like EntityEvents.tick

weak quail
#
EntityEvents.hurt(event => {
    try {
        let mob = event.entity;
        if (mob.type !== 'kubejs:angry_zombie') return;

        let current = mob.health;
        let max = mob.getMaxHealth();

        // Enrage only once when health <= 50%
        if (current <= max * 0.5 && !mob.persistentData.enraged) {
            mob.persistentData.enraged = true;

            mob.potionEffects.add('minecraft:strength', 600, 1, false, true);
            mob.potionEffects.add('minecraft:resistance', 600, 1, false, true);
            mob.potionEffects.add('minecraft:speed', 600, 1, false, true);
        }
    } catch (e) {
        console.error(`Error applying buffs to angry zombie: ${e}`);
    }
});```
#

this kinda works? but idk if there is a better way to do this

modest vigil
#

instead of the hurt event i suggest doing it inside the tick callback so it retains those effects if its lower than 50% hp, then yo ucan set up an else statement that clears the potion effects if for some reason it gets healed

#

as for the blast radius this can be changed via its nbt tag js entity.nbt.putByte("ExplosionRadius", 10)

#

i suggest putting this in the onAddedToWorld callback in your entity builder

weak quail
#

from what i know

modest vigil
#
doomZombie.tick(entity => {})```
weak quail
#

ohhhh

#

well thats gonna be a pain to test because im gonna have to restart every time sadge

modest vigil
#

oh nah

#

just use global functions

#

sec

#

with global functions you can do /kubejs reload startup_scripts to reload instead of having to restart the game every time.

weak quail
#

oh like that

#

thats very convenient

chilly irisBOT
modest vigil
#

yup, its pain and suffering otherwise lol

#

i also suggest you wrap it with a try catch like so, so if it errors it doesnt crash the game and instead outputs the error message js global.somefunction = entity => { try { // your code }catch(e) { console.log(e) } }

weak quail
modest vigil
#

nice

weak quail
#

ok, let me test

#
EntityJSEvents.modifyEntity(event => {
    event.modify('kubejs:angry_zombie', builder => {
        builder.tick(zombie => {
            global.handleEnrage(zombie, 0.5);
        });
    });
});

global.handleEnrage = function (entity, threshold) {
    if (threshold === undefined) threshold = 0.5;

    const current = entity.health;
    const max = entity.getMaxHealth();

    if (current <= max * threshold) {
        if (!entity.persistentData.enraged) {
            entity.persistentData.enraged = true;
        }

        entity.potionEffects.add('minecraft:strength', 20, 1, false, true);
        entity.potionEffects.add('minecraft:resistance', 20, 1, false, true);
        entity.potionEffects.add('minecraft:speed', 20, 1, false, true);
    } else {
        if (entity.persistentData.enraged) {
            entity.persistentData.enraged = false;
            entity.potionEffects.remove('minecraft:strength');
            entity.potionEffects.remove('minecraft:resistance');
            entity.potionEffects.remove('minecraft:speed');
        }
    }
};```
#

good enough?

modest vigil
#

do this instead js builder.tick(zombie => global.handleEnrage(zombie,0.5))
rhino does a weird thing when you call a global like that in {} when its the only thing

#

also i would move that 0.5 parameter to the global event itself as modifying it after startup will not change it unless you restart the game

#

other than that it looks good to me

weak quail
#

sure! will do

#

ok, works like a charm

#

now for the other zombie

#
    const doom_zombie = event.create('doom_zombie', 'minecraft:creeper')
    doom_zombie.mobCategory('monster')
    doom_zombie.sized(0.6, 1.95)
    doom_zombie.clientTrackingRange(32)
    doom_zombie.defaultGoals(true)
    doom_zombie.setRenderType('translucent')
    doom_zombie.animationResource(() => 'kubejs:animations/entity/doom_zombie.animation.json')

    doom_zombie.addAnimationController('movement', 1, event => {
        if (event.entity.animationProcedure && event.entity.animationProcedure !== 'empty') return false
        if (event.entity.isMoving()) {
            event.thenLoop('animation.doom_zombie.walk')
        } else {
            event.thenLoop('animation.doom_zombie.idle')
        }
        return true
    })
    doom_zombie.addAnimationController('charge', 1, event => {
        if (event.entity.animationProcedure === 'animation.doom_zombie.attack') {
            event.thenLoop('animation.doom_zombie.attack')
            return true
        }
        return false
    })
    doom_zombie.setAmbientSound('minecraft:entity.zombie.ambient')
    doom_zombie.setDeathSound('minecraft:entity.zombie.death')
    doom_zombie.setHurtSound(() => 'minecraft:entity.zombie.hurt')

    doom_zombie.onAddedToWorld(ctx => {
        ctx.entity.nbt.putByte('ExplosionRadius', 10)
    })```
#

something like this you mean?

modest vigil
#

does onaddedtoworld take a context? i thought it was just entity

weak quail
#

am not sure

modest vigil
#

yeah its just entity

weak quail
#

alright ill change that

modest vigil
#

theres a full example page on the wiki if you ever wanna see

weak quail
#

thank you

#

yes i will take a look

modest vigil
#

here you can cross check if needed though again probejs also has this if you hover over the method

#

it also has other useful information and all of them have example implementations you can directly copy

weak quail
#

those are some REALLLY helpful examples im seeing

modest vigil
#

ye

weak quail
#

thank you for the goldmine king, fixing this real quick 🙏

modest vigil
#

np

weak quail
#

tried entity.nbt.putByte("ExplosionRadius", 10) cant seem to notice any difference compared to the regular creeper explosion

#

mhhh

#

@modest vigil maybe there is a different name for it?

modest vigil
#

any errors in startup

chilly irisBOT
#

Please send your KubeJS startup log. It can be found at /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.

weak quail
#

nope

modest vigil
#

hmm

#

try js entity.nbt.ExplosionRadius = {ExplosionRadius: 10}

#

if that doesnt work then js entity.nbt.ExplosionRadius = 10

#

if that doesnt work then js entity.mergeNbt({ExplosionRadius: 10})

weak quail
#

ill test these 3

#

entity.mergeNbt({ExplosionRadius: 10})
this one worked

#

thank you so much @modest vigil, this was really helpful MumeiPray2