#Custom damage source in 1.20

73 messages · Page 1 of 1 (latest)

gleaming locust
#

I'm trying to port the radiation example script to 1.20 from 1.19 and apparently the damage source builder in 1.20 is very different to the 1.19 way and requires a bunch of reflection to create. Someone said you can create a custom damage source(really we're just looking for a custom death message here) without reflection and I must know how(if it's possible)
Here's the current 1.20 Radiation port where it damages the player/displays the death message correctly ect. The one issue is a client error where it fails to "send a packet" which we avoided in the 1.19 script by returning if (player.level.clientside) which if we try here results in the player not taking damage anymore.

#1181006153853960373 message

also heres the client error im getting
#1181006153853960373 message

hasty badgerBOT
#

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

fervent ivyBOT
#

[Quote ➤](#1181006153853960373 message) ```js
const $EntityDamageSource = Java.loadClass('net.minecraft.world.damagesource.DamageSource');
const DamageType = Java.loadClass('net.minecraft.world.damagesource.DamageType');
const Holder = Java.loadClass('net.minecraft.core.Holder');
const DeathMessageType = Java.loadClass('net.minecraft.world.damagesource.DeathMessageType');
const DamageScaling = Java.loadClass('net.minecraft.world.damagesource.DamageScaling');
const DamageEffects = Java.loadClass('net.minecraft.world.damagesource.DamageEffects');

/** Register effects */
StartupEvents.registry('mob_effect', event => {
event.create('radiation')
.displayName(Component.green("Radiation Poisoning"))
.effectTick((entity, lvl) => {
global.customDamageEffect(entity, lvl)
})
.color(Color.GREEN)
.harmful();
});

/**

  • Applies the custom damage effect.

  • @param {Internal.Entity} entity The entity to apply the effect to

  • @param {number} lvl The level of the effect
    */
    global.customDamageEffect = (entity, lvl) => {
    // Define your new damage type with the appropriate enum constant (e.g., DamageEffects.BURNING)
    let newDamageType = new DamageType(radiation, DamageScaling.WHEN_CAUSED_BY_LIVING_NON_PLAYER, 0.5, DamageEffects.BURNING, DeathMessageType.DEFAULT);

    // Create a Holder for the DamageType
    let damageTypeHolder = Holder.direct(newDamageType);

    // Create the DamageSource using the Holder<DamageType>
    let damageSource = new $EntityDamageSource(damageTypeHolder);
    entity.attack(damageSource, lvl + 1)
    };```

#

[Quote ➤](#1181006153853960373 message) you might want to open up a seperate ticket focused on this clientbound packet error though to fix it because currently its not playing sound when you get hurt

java.util.NoSuchElementException: No value present
    at java.base/java.util.Optional.get(Optional.java:143)
    at TRANSFORMER/[email protected]/net.minecraft.network.protocol.game.ClientboundDamageEventPacket.m_269591_(ClientboundDamageEventPacket.java:70)
    at TRANSFORMER/[email protected]/net.minecraft.client.multiplayer.ClientPacketListener.m_269082_(ClientPacketListener.java:1007)
    at TRANSFORMER/[email protected]/net.minecraft.network.protocol.game.ClientboundDamageEventPacket.m_5797_(ClientboundDamageEventPacket.java:66)```
low idol
#

@gleaming locust so how is this going?

gleaming locust
#

im at the same point i was a week ago when i wrote this script lol

#

i opened this mainly because you said there was a way maybe without reflection to set the custom damage source or something

fervent ivyBOT
#

[Quote ➤](#1149852342703894598 message) DamageSource on 1.20 doesn't need reflection

low idol
#

it means you don't need to import DamageSource, you can directly call it DamageSource

#

but that is just it lol heh

gleaming locust
#

ahh

#

crap

#

so then i have to somehow resolve this error, we avoided this error last time by returning if the level was clientside but if we do that here it doesnt damage the player is the issue#1183085911974608977 message

#

the heck does no value present meanwhatcat

low idol
#

@gleaming locust

#

on startup

/** Register effects */
StartupEvents.registry('mob_effect', event => {
    // Register radiation effect
    event.create('radiation')
        // Change the name to be "Radiation", in green
        .displayName("Radiation")
        // Set a tick event to apply the action
        .effectTick((entity, lvl) => global.radiationEffect(entity, lvl))
        // Set the color of the effect
        .color(Color.GREEN)
        // Set whether the effect is harmful
        .harmful();
})

const $ResourceKey = Java.loadClass("net.minecraft.resources.ResourceKey")
const DAMAGE_TYPE = $ResourceKey.createRegistryKey("damage_type")

/**
 * Applies the radiation effect.
 * Damages the entity (likely player) with 2 HP (1 hearts) per 10 ticks.
 *
 * @param {Internal.Entity} entity The entity to apply the effect to
 * @param {number} lvl The level of the effect
 */
global.radiationEffect = (entity, lvl) => {
    // Create damage source
    const damageSource = getDamageSource(entity.level(), "kubejs:radiation");
    // Check if the global is run on the client. If so, return
    if (entity.level().clientSide) return;
    // Damage based on level 
    entity.attack(damageSource, lvl + 1);
}

function getDamageSource(/** @type {Internal.Level}*/ level, /** @type {Internal.DamageType_}*/ damageType) {
    const resourceKey = $ResourceKey.create(DAMAGE_TYPE, Utils.id(damageType))
    const holder = level.registryAccess().registryOrThrow(DAMAGE_TYPE).getHolderOrThrow(resourceKey)
    return new DamageSource(holder)
}
#

on client


/** Add language entries */
ClientEvents.lang('en_us', (e) => {
    // Effect / Radiation
    e.add("death.attack.radiationKill", "%1$s died in a horrible way");
})

on server

// Register Damage Type
ServerEvents.highPriorityData(event => {
  event.addJson("kubejs:damage_type/radiation", {
    "effects": "burning",
    "exhaustion": 0.5,
    "message_id": "radiationKill",
    "scaling": "when_caused_by_living_non_player"
  })
})
gleaming locust
#

whoaa bet

#

ty

#

ill have to try it tomorrow, its working?

low idol
#

it is

low idol
#

what is the namespace of your radiation? cuz of icon to showup

#

i registered at kubejs

gleaming locust
#

kubejs:radiation i think

#

yess

low idol
#

ok

gleaming locust
#

man youre awesome

#

will update the Radiation post to support the 1.20 port tomorrow once i run it

low idol
#

damage is very high tho lol

gleaming locust
#

lol

#

ill dial it back a bit, no worries

low idol
#

because of the burning I guess

gleaming locust
#

i didnt know you could add exhaustion too

low idol
#

your original post didnt have burning

#

🤔

gleaming locust
#

nah it made it's own custom damage source

#

in 1.20 you have to specify

low idol
#

actually I don't know if those burning are real burning or just for sound effects

gleaming locust
#

right

#

either way this gives me some room to customize it and have it work so all g

low idol
#

how do you define this 10 tick effect? is it default?

gleaming locust
#

i assume it runs every tick but the player has the invincibility ticks

low idol
#

oh yeah..

gleaming locust
#

not sure how to override that

low idol
gleaming locust
#

might actually be cool to make it a 1 tick delay with smaller damage to simulate radiation poisoning, ill have to look into that

gleaming locust
#

though would that turn the hearts black?

#

i basically want to change the sound effect from the burning one to a normal damage sound

low idol
#

that effect is just for sound, it is a Enum you can check on lexxie @gleaming locust

#

DamageEffects I guess

gleaming locust
#

ahh ok

low idol
#

is the name

gleaming locust
#

thx

gleaming locust
#

although ive gotta nerf that a lot

low idol
#

@gleaming locust lol how did you do that

gleaming locust
#
EntityEvents.hurt(event => {
  event.entity.tell('Before' + event.entity.invulnerableTime)
  if (event.source.getType().toString() == 'radiationKill') {
    event.entity.invulnerableTime = 1
    event.entity.tell('After' + event.entity.invulnerableTime)
  }
})```
#

although it only ever either gets rid of the whole invulnerableTime or sets it back to 20

low idol
#

oh the invuln

gleaming locust
#

yea

#

i cant set it to 10 for example which is what im troubleshooting rn

#

im gonna test with event.server.scheduleinticks maybe idk

#

or maybe run it on a timer with the player.age

#

yeah this works js ItemEvents.rightClicked('stick', event => { event.player.heal(20) event.player.attack(1) }) EntityEvents.hurt(event => { if (!(event.entity.age % 10 == 0)) return event.entity.tell('Before' + event.entity.invulnerableTime) if (event.source.getType().toString() == 'generic') { event.entity.invulnerableTime = 1 event.entity.tell('After' + event.entity.invulnerableTime) } })

#

thanks uncandango, gonna update the examplescript now

#

also gotta post it all here sec

#

1.20 Radiation Port
Startup Script:js StartupEvents.registry('mob_effect', event => { // Register radiation effect event.create('radiation') // Change the name to be "Radiation", in green .displayName("Radiation") // Set a tick event to apply the action .effectTick((entity, lvl) => global.radiationEffect(entity, lvl)) // Set the color of the effect .color(Color.GREEN) // Set whether the effect is harmful .harmful(); }) const $ResourceKey = Java.loadClass("net.minecraft.resources.ResourceKey") const DAMAGE_TYPE = $ResourceKey.createRegistryKey("damage_type") global.radiationEffect = (entity, lvl) => { // Create damage source const damageSource = getDamageSource(entity.level(), "kubejs:radiation"); // Check if the global is run on the client. If so, return if (entity.level().clientSide) return; // Damage based on level entity.attack(damageSource, (lvl - 0.2) + 1); } function getDamageSource(/** @type {Internal.Level}*/ level, /** @type {Internal.DamageType_}*/ damageType) { const resourceKey = $ResourceKey.create(DAMAGE_TYPE, Utils.id(damageType)) const holder = level.registryAccess().registryOrThrow(DAMAGE_TYPE).getHolderOrThrow(resourceKey) return new DamageSource(holder) }
Server Script:js // Register Damage Type ServerEvents.highPriorityData(event => { event.addJson("kubejs:damage_type/radiation", { "effects": "hurt", "exhaustion": 0.5, "message_id": "radiationKill", "scaling": "when_caused_by_living_non_player" }) }) EntityEvents.hurt(event => { if (!(event.entity.age % 10 == 0)) return if (event.source.getType().toString() == 'radiationKill') { event.entity.invulnerableTime = 1 } })
Client Script:js /** Add language entries */ ClientEvents.lang('en_us', (e) => { // Effect / Radiation e.add("death.attack.radiationKill", "%1$s died in a horrible way"); })