#create explosion that doesn't deal damage to entities

529 messages · Page 1 of 1 (latest)

floral plover
#

how would i make an explosion that applies knockback to entities, but doesn't deal damage?

eternal lionBOT
#

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

green dock
#

bump

floral plover
#

why are you bumping this?

green dock
floral plover
#

fair

green dock
#

ill send the testing script im using to try this out in just a sec

carmine jackal
#

aight

green dock
#

LevelEvents.afterExplosion(event => {
    const { x, y, z, level } = event
    level.getEntitiesWithin(AABB.of(x - 20, y - 20, z - 20, x + 20, y + 20, z + 20)).forEach(entity => {
            entity.knockback(20, x, z)
        }
    })
})```
#

i am currently using afterExplosion to test this as a leftover of my own script

#

i dont receive any noticeable extra knockback however

green dock
#

wait i think it works?? maybe?? but only on survival mode

green dock
green dock
#
EntityJSEvents.modifyEntity(event => {
    event.modify("minecraft:firework_rocket", entity => {
        entity.onRemovedFromWorld(entity => {
            const { x, y, z, level } = event
            level.getEntitiesWithin(AABB.of(x - 20, y - 20, z - 20, x + 20, y + 20, z + 20)).forEach(entity => {
            entity.knockback(20, x, z)
            global.onRemoved(entity)
        })
    })
})})

global.onRemoved = entity => {
    console.log(entity)
}```


[15:28:52] [Server thread/ERROR] [KubeJS Startup/]: registerEntities.js#5: [EntityJS]: Error in entity.minecraft.firework_rocketbuilder for field: onRemovedFromWorld.: TypeError: Cannot call method "getEntitiesWithin" of undefined
#

ignore the fact im not doing the knockback

#

in the global

#

i'm just slowly hacking away at this and

#

god damnit man!!

carmine jackal
#

so level is null there too hmmm

#

although wait theres no event here

green dock
#

fuuck

#

wait what

carmine jackal
#

it all goes off entity just like entity builders

#

the callback is entity not event

#

so entity.level

green dock
#

OH okay

#
EntityJSEvents.modifyEntity(event => {
    event.modify("minecraft:firework_rocket", entity => {
        entity.onRemovedFromWorld(entity => {
            // const { x, y, z, level } = event
            entity.level.getEntitiesWithin(AABB.of(x - 20, y - 20, z - 20, x + 20, y + 20, z + 20)).forEach(entity => {
            entity.knockback(20, x, z)
            global.onRemoved(entity)
        })
    })
})})

global.onRemoved = entity => {
    console.log(entity)
}```

[15:34:27] [Render thread/ERROR] [KubeJS Startup/]: registerEntities.js#5: [EntityJS]: Error in entity.minecraft.firework_rocketbuilder for field: onRemovedFromWorld.: ReferenceError: "x" is not defined.
#

wuh,,

#

wait

#

oph shoot

#

okay

#

ic

carmine jackal
#

heck i'd just do js const { x, y, z, level } = entity

green dock
#

thats what i just put in

#

trying tnow

carmine jackal
#

also why arent you doing everything in the global event?

#

np

green dock
#

just testing

#

YES

#

HOLY SHIT

carmine jackal
#

with the global you can do /kubejs reload startup_scripts without reloading the entire game

green dock
#

but the knockback is REALLY random

green dock
carmine jackal
#
EntityJSEvents.modifyEntity(event => {
    event.modify("minecraft:firework_rocket", entity => {
        entity.onRemovedFromWorld(entity => global.onRemoved(entity))
    })
})
/**
 * 
 * @param {$Entity} entity 
 */
global.onRemoved = entity => {
    const { x, y, z, level } = entity
    entity.level.getEntitiesWithin(AABB.of(x - 20, y - 20, z - 20, x + 20, y + 20, z + 20)).forEach(entity => {
        entity.knockback(20, x, z)
    })
}```
#

kk

#

there now you'll get probejs typings for entity too

green dock
#

very weird behavior

#

i want it to act like a rocket jump

#

this is with

EntityJSEvents.modifyEntity(event => {
    event.modify("minecraft:firework_rocket", entity => {
        entity.onRemovedFromWorld(entity => global.onRemoved(entity))
    })
})
/**
 * 
 * @param {$Entity} entity 
 */
global.onRemoved = entity => {
    const { x, y, z, level } = entity
    entity.level.getEntitiesWithin(AABB.of(x - 3, y - 3, z - 3, x + 3, y + 3, z + 3)).forEach(entity => {
        entity.knockback(2, x, z)
    })
}```
#

i think its actually based off 0, 0

#

maybe????

#

which is so weird

#

yeah it always launches me towards 0 0

carmine jackal
#

log x and y and see what it is

#

it looks like you can modfy the direction by adding/subtracting from the x and z field hmmm

carmine jackal
#

i assume minecraft does this with level.random or something

#

although you're shooting a firework and you probably want the explosion to push them away from the firework hmmm

green dock
#

ahh sorry back

green dock
#

[16:21:56] [Render thread/INFO] [KubeJS Startup/]: registerEntities.js#13: FireworkRocketEntity['Firework Rocket'/303, l='ClientLevel', x=12.05, y=55.73, z=989.25, removed=DISCARDED]
[16:21:56] [Render thread/INFO] [KubeJS Startup/]: registerEntities.js#14: 12.045995315901287
[16:21:56] [Render thread/INFO] [KubeJS Startup/]: registerEntities.js#15: 55.7267218221549
[16:21:56] [Render thread/INFO] [KubeJS Startup/]: registerEntities.js#16: 989.2533581522126

#
    console.log(x)
    console.log(y)
    console.log(z)```
carmine jackal
#

ok i think what you might have to do is get the x/z coordinate of the target entity from the getentitieswithin callback and offset it

green dock
#

ouch

carmine jackal
#

that way it'll knock all the entities back the correct direction

#

by the way if you want it to spawn particles/play the explosion sounds without doing any damage to the player then you'd do this js let explosion = player.level.explode(player, null, null, x, y, z, 5, false, "block", true) explosion.explode()

#

i think thats what toaster wanted anyways

green dock
#

oops i've overtaken his thread

#

sorry toaster soingbob

green dock
#

probejs doesnt work on linux

#

(the probejs thing)

carmine jackal
#

ah

#

rip

green dock
#

im not actually sure what the parameters do for entity knockback

#

i heard that it was strength, y, z

#

but why would it even be that

carmine jackal
#

y z or x z

#

its x z i guess ```java
public void knockback(double pStrength, double pX, double pZ) {
LivingKnockBackEvent event = ForgeHooks.onLivingKnockBack(this, (float)pStrength, pX, pZ);
if (!event.isCanceled()) {
pStrength = (double)event.getStrength();
pX = event.getRatioX();
pZ = event.getRatioZ();
pStrength *= 1.0 - this.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE);
if (!(pStrength <= 0.0)) {
this.hasImpulse = true;
Vec3 vec3 = this.getDeltaMovement();
Vec3 vec31 = (new Vec3(pX, 0.0, pZ)).normalize().scale(pStrength);
this.setDeltaMovement(vec3.x / 2.0 - vec31.x, this.onGround() ? Math.min(0.4, vec3.y / 2.0 + pStrength) : vec3.y, vec3.z / 2.0 - vec31.z);
}

    }
}```
green dock
#

and the first value is strength?

carmine jackal
#

looks like all it does is set your delta movement

#

yea

green dock
#

entity.knockback(2, x, z)
is still producing the weird 'launch to one area' bug

#

to be more accurate, launching to 0 0

#
EntityJSEvents.modifyEntity(event => {
    event.modify("minecraft:firework_rocket", entity => {
        entity.onRemovedFromWorld(entity => global.onRemoved(entity))
    })
})
/**
 * 
 * @param {$Entity} entity 
 */
global.onRemoved = entity => {
    const { x, y, z, level } = entity
    console.log(entity)
    console.log(x)
    console.log(y)
    console.log(z)
    entity.level.getEntitiesWithin(AABB.of(x - 3, y - 3, z - 3, x + 3, y + 3, z + 3)).forEach(entity => {
        let x = entity.x
        let y = entity.y
        let z = entity.z
        entity.knockback(2, x, z)
    })
}```
carmine jackal
#

yeah, like i said i messed around with it and if you do x + 10, z + 10 or something itll override the direction so you'll have to do something like js entity.x + (target.x * 5),entity.z + (target.z * 5) or something

#

mess around with it ect

green dock
#

alr

green dock
#

is entity the entities hit

#

or the firework?

carmine jackal
#

you should change this js .forEach(entity => { to js .forEach(target => { for more clarity heh

#

cause then you'll have both

green dock
#

oo alr

green dock
#

-x and -z send me away from 0 0

#

but i dont know where it would be even getting 0 0 from???

#

im logging it and it shows the coordinates at their correct positions

#

ill test without siny

#

its not a sinytra issue

#

ffs

green dock
#

my math genie friends r helping me in dms rn

carmine jackal
#

the LivingEntity class

green dock
#

yeah but er

#
    public void knockback(double var1, double var3, double var5) {
        var1 *= 1.0 - this.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE);
        if (!(var1 <= 0.0)) {
            this.hasImpulse = true;
            Vec3 var7 = this.getDeltaMovement();
            Vec3 var8 = new Vec3(var3, 0.0, var5).normalize().scale(var1);
            this.setDeltaMovement(var7.x / 2.0 - var8.x, this.onGround() ? Math.min(0.4, var7.y / 2.0 + var1) : var7.y, var7.z / 2.0 - var8.z);
        }
    }```
#

the variable names aren't what they are on yours

#

it doesnt make a huge diff i can change manually but its a pain

carmine jackal
#

thats because i have parchement mappings and im in my ide

#

its all the same though

green dock
#

my friends are trying to figure out

#

what ratioX and ratioZ does

carmine jackal
#

those are the direction it knocks you in

#

i've already tested it, for example have them put 50 in for each of them and it'll knock them that way

#

if that makes sense

#

but yeah i'd just keep messing around with it tbh

green dock
#

heres the thing though i really dont think this is a math problem

#

if x and z were truly the coordinates of the firework

#

then it should be working normal

carmine jackal
#

i think so too, and i also think that if minecraft is using this function then they're doing some other math to make the explosion knock back the player the right way

#

this is also what they use for the knockback enchantment

#

i dont think you're supposed to just put the x and z coordinate of the entity in there

green dock
#

issue is i need to find that other math

#

i have friends who can decode the math easily

#

i just dont know where it could be located

green dock
#

it does nothing

carmine jackal
#

do they have intellij open?

#

if so have them look through the entity methods

green dock
#

they only know math

carmine jackal
green dock
#

i can send them the entity methods

#

but once again, probejs doesnt work (it didnt start working as far as i can tell)

carmine jackal
#

and all your files are in the new src folders?

green dock
#

there is no new src folder

#

even with probejs 7.0.0

#

i run probejs dump

carmine jackal
green dock
#

wait is entity even the firework???

#

console.log(entity.[thecoordleter]) shows the firework's coords

#

WAIT NVM I GOT IT FOF GUESSING

#

OK ITS HALF WORKING

carmine jackal
green dock
#

shooting directly at my feet doesnt launch me up

#

thats just math stuff

#

phew..

carmine jackal
green dock
#

is there a way to grab entity velocity?

#

instaed of entity position

carmine jackal
#

deltaMovement

green dock
#

tyty

carmine jackal
#

yup

green dock
#

like uhh

#

entity.deltaMovement.y ?

carmine jackal
#

yea

green dock
#

sweet

floral plover
#

where are we at currently?

green dock
#

Ctrl + f for toaster in here

#

liopyu solved urs I think

#

so you can close thread

floral plover
#

he did?

green dock
#

as im basically solved too

green dock
#

oh shit I pinged

#

oops sorry liopyu

carmine jackal
#

gimme sec, im doing a test to see if i can improve it

carmine jackal
carmine jackal
#

@floral plover test this script out and see if its what you need
(put this in both server scripts as well as client scripts) ```js
BlockEvents.rightClicked(event => {
const { player, block } = event
const { x, y, z } = block

let explosion = player.level.explode(player, null, null, x, y, z, 5, false, "tnt", true)
explosion.explode()

const knockbackStrength = 1
const maxUpwardStrength = 1.0 // Maximum upward strength
const baseUpwardStrength = 0.1 // Minimum upward strength
const directionX = x - player.x
const directionY = y - player.y
const directionZ = z - player.z
const distance = Math.sqrt(directionX * directionX + directionZ * directionZ)
if (distance > 0) {
    const normalizedX = directionX / distance
    const normalizedZ = directionZ / distance
    player.knockback(knockbackStrength, normalizedX, normalizedZ)
    let upwardStrength = baseUpwardStrength
    if (directionY < 0) {
        upwardStrength = Math.min(maxUpwardStrength, baseUpwardStrength - directionY / distance * knockbackStrength)
    }
    player.addMotion(0, upwardStrength, 0)
}

})```

#

@green dock if you also are still having trouble with the caluclations i basically came to a somewhat decent knockback formula

green dock
#

oh shit!! upwards motion helps a lot, the rest I had

carmine jackal
#

very good

#

ok i have a revision for if you dont want it to hurt other entities, sec

green dock
#

ive already setup the knockback n such it was just the upwards formula I needed

#

thank you so much!

floral plover
#

hmmm

#

i'm not getting the particles

#
ForgeEvents.onEvent("net.minecraftforge.event.entity.ProjectileImpactEvent", event => {
  global.projectileImpact(event)
})
/**
 * @param {Internal.ProjectileImpactEvent} event 
 */
global.projectileImpact = event => {
  const {projectile, rayTraceResult} = event
  if(projectile.level == "ClientLevel") return
  if(
    projectile.type != "avaritia:heaven_sub_arrow" &&
    projectile.type != "minecraft:arrow" &&
    projectile.type != "mekaweapons:meka_arrow"
  ) return
  if(rayTraceResult.type == "MISS") return
    let /**@type {Internal.LivingEntity}*/ user = projectile.owner
    let bow = user.getItemInHand("main_hand")
  if(
    bow != "avaritia:infinity_bow" &&
    bow != "mekanism:electric_bow" &&
    bow != "mekaweapons:mekabow" &&
    bow != "minecraft:bow") bow = user.getItemInHand("off_hand")
  if(!(bow.hasEnchantment("kubejs:arcbolt", 1) || bow.hasEnchantment("kubejs:arcbolt", 2) || bow.hasEnchantment("kubejs:arcbolt", 3))) return
    let level = bow.getEnchantmentLevel("kubejs:arcbolt")
  for(let n = 0; n < level; n++) {
    Utils.server.scheduleInTicks(n*15, () => {
      let strikePos = strikeArea(projectile.block, 4-level)
      let /**@type {Internal.LightningBolt}*/bolt = user.level.getBlock(strikePos).createEntity('lightning_bolt')
      let power = bow.getEnchantmentLevel("power")
      let punch = bow.getEnchantmentLevel("punch")
      let flame = bow.getEnchantmentLevel("flame")
      let hasFlame = flame != 0
        if(power != 0) {
          bolt.setDamage(bolt.getDamage() * (power + 1))
        }
        if(punch != 0) {
          let explosion = user.level.explode(user, null, null, strikePos.x, strikePos.y, strikePos.z, (power + punch), false, "none", true) //the important part
          if(hasFlame) explosion.fire = true
          explosion.explode()
        }
      bolt.spawn()
    })
  }
}```
carmine jackal
#

you have to put it in both server and client scripts

floral plover
#

i see

#

wait

#

ForgeEvents only doesn't work on server

#

or is it because it's the same file?

carmine jackal
#

forgeevents does work on server

#

are you server only or something?

floral plover
#

no

carmine jackal
#

wait you mean server scripts?

#

yeah those go in startup

floral plover
#

yeah

#

but why is kube not yelling at me when i copy the script in client

carmine jackal
#

thats not what i sent you

floral plover
#

i did write it?

#

i just yoinked the level.explosion() thing for now

carmine jackal
#

ah

#

yeah if its forge event then i dont think theres a need to put it in client events

#

only the block right click example you have to do that to sync it

#

if you do need to sync it then you'd have to send packets not put it in client scripts

floral plover
#

though i am returning the clientside event due to it running twice or else

carmine jackal
#

put the explosion code outside of that

#

so it runs on both client and server

#

i should note that if you want it to not damage entities with the explosion you'll have to create your own dummy damage source and cancel it in the hurt event.
Server Script:js ServerEvents.highPriorityData(event => { event.addJson("kubejs:damage_type/nullexplosion", { "effects": "hurt", "exhaustion": 0.5, "message_id": "nullExplosion", "scaling": "when_caused_by_living_non_player" }) }) EntityEvents.hurt(event => { if (event.source.getType().toString() == 'nullExplosion') { event.cancel() } })
then you'd use the damage source in the explosion method like so js let $ResourceKey = Java.loadClass("net.minecraft.resources.ResourceKey") let DAMAGE_TYPE = $ResourceKey.createRegistryKey("damage_type") function getDamageSource(level, damageType) { const resourceKey = $ResourceKey.create(DAMAGE_TYPE, Utils.id(damageType)) const holder = level.registryAccess().registryOrThrow(DAMAGE_TYPE).getHolderOrThrow(resourceKey) return new DamageSource(holder) } const damageSource = getDamageSource(player.level, "kubejs:nullexplosion"); let explosion = player.level.explode(player, damageSource, null, x, y, z, 5, false, "tnt", true) explosion.explode()

#

i dont think you need the client lang event but here it is anyways just in case
Client Script:js ClientEvents.lang('en_us', (e) => { e.add("death.attack.nullexplosion", "%1$s died in a horrible way"); })

floral plover
#

dying from an explosion that doesn't deal damage is very funny

carmine jackal
#

imagine

#

also i rearranged it because you actually need that getDamageSource function in the same script you use the damage source in

floral plover
carmine jackal
floral plover
#

yeah

#

whoops

#

forgot to put the serverEvent

#

(game crashed)

carmine jackal
#

lol

#

i believe you can use a try catch function in the global to prevent most crashes from happening

floral plover
#

maybe

#

if i want to make the explosion deal damage only when the bow has power on it, would ```js
let explosion = user.level.explode(user, hasPower ? damageSource : null, null, strikePos.x, strikePos.y, strikePos.z, (power + punch), false, "none", true)

#

@carmine jackal

carmine jackal
#

uh

#

??tryitandsee

wraith surgeBOT
floral plover
#

well, i did and it seems to deal damage

carmine jackal
#

does it deal damage when theres no power?

floral plover
#

yes

carmine jackal
floral plover
#

oh

#

it deals no damage when power is on

#

WHY??????

carmine jackal
#

wait so its reversed?

floral plover
#

yeah

#

js is amazing

carmine jackal
#

??whythishappen

carmine jackal
#

js is the language ever yes

floral plover
#

wait

#

i just got it

#

i thought null was no damage and damageSource was yes damage

#

because thats the intuitive thing

#

js has been saved

carmine jackal
#

lol

floral plover
#

hmmm

#

on this line js let /**@type {Internal.LightningBolt}*/bolt = user.level.getBlock(strikePos).createEntity('lightning_bolt') i'm getting this error ```cmd
startup_scripts:arcbolt.js#55: Error occurred while handling scheduled event callback: Wrapped java.lang.NullPointerException: Cannot invoke "net.minecraft.server.MinecraftServer.m_129880_(net.minecraft.resources.ResourceKey)" because the return value of "dev.latvian.mods.kubejs.core.EntityKJS.kjs$getServer()" is null

carmine jackal
#

servers null somewhere

floral plover
#

well yeah the bolt is created on the server and client, no?

carmine jackal
#

m_129880_ is getLevel() btw

floral plover
#

please tell me you don't know that by heart

carmine jackal
#

i do not sadly, i looked it up in my ide heh

floral plover
#

oh ok

carmine jackal
#

log level

#

also log the user

floral plover
#
ClientLevel [net.minecraft.client.multiplayer.ClientLevel]
LocalPlayer['Pizzaboy0265'/159, l='ClientLevel', x=-37.47, y=89.68, z=-49.76] [net.minecraft.client.player.LocalPlayer]
carmine jackal
#

i see

#

so wherever that code is is on client side

#

you need serverlevel to create entities

#

show the rest of your code

floral plover
#

that forge event runs on server and client

carmine jackal
#

that it does

#

unless you have syntra connector which messes with some things

floral plover
#
ForgeEvents.onEvent("net.minecraftforge.event.entity.ProjectileImpactEvent", event => {
  global.projectileImpact(event)
})
/**
 * @param {Internal.ProjectileImpactEvent} event 
 */
global.projectileImpact = event => {
  const {projectile, rayTraceResult} = event
  if(
    projectile.type != "avaritia:heaven_sub_arrow" &&
    projectile.type != "minecraft:arrow" &&
    projectile.type != "mekaweapons:meka_arrow"
  ) return
  if(rayTraceResult.type == "MISS") return
    let /**@type {Internal.LivingEntity}*/ user = projectile.owner
    let bow = user.getItemInHand("main_hand")
  if(
    bow != "avaritia:infinity_bow" &&
    bow != "mekanism:electric_bow" &&
    bow != "mekaweapons:mekabow" &&
    bow != "minecraft:bow") bow = user.getItemInHand("off_hand")
  if(!(bow.hasEnchantment("kubejs:arcbolt", 1) || bow.hasEnchantment("kubejs:arcbolt", 2) || bow.hasEnchantment("kubejs:arcbolt", 3))) return
    let level = bow.getEnchantmentLevel("kubejs:arcbolt")
    let power = bow.getEnchantmentLevel("power")
    let punch = bow.getEnchantmentLevel("punch")
    let flame = bow.getEnchantmentLevel("flame")
    let hasFlame = flame != 0
    let hasPower = power != 0
    let hasPunch = punch != 0
    const negateDamage = getDamageSource(user.level, "kubejs:nullexplosion");
    for(let n = 0; n < level; n++) {
      Utils.server.scheduleInTicks(n*15, () => {
      let strikePos = strikeArea(projectile.block, 4-level)
      if(hasPunch) {
        let explosion = user.level.explode(user, hasPower ? null : negateDamage, null, strikePos.x, strikePos.y, strikePos.z, hasPower ? (power + punch)/10 : punch, false, "none", true)
        if(hasFlame) explosion.fire = true
        explosion.explode()
      }
      console.log(user.level, user);
      let /**@type {Internal.LightningBolt}*/bolt = user.level.getBlock(strikePos).createEntity('lightning_bolt')
        if(hasPower) {
          bolt.setDamage(bolt.getDamage() * (power + 1))
      }
      bolt.spawn()
    })
  }
}```
#

8 characters left in discord despair

#

some stuff is excluded btw to make it fit

#

but its just functions

carmine jackal
#

try instead going off the projectile.level

#

should be the same

floral plover
#

also you should note that the code works fine, it's just that that error gets spmmed in the logs

#

error is still there with ```js
let /**@type {Internal.LightningBolt}*/bolt = projectile.level.getBlock(strikePos).createEntity('lightning_bolt')

carmine jackal
#

you mean it spawns a lightning bolt?

floral plover
#

yeah

carmine jackal
floral plover
#

particle and damage

carmine jackal
#

whats the error message

floral plover
#
startup_scripts:arcbolt.js#55: Error occurred while handling scheduled event callback: Wrapped java.lang.NullPointerException: Cannot invoke "net.minecraft.server.MinecraftServer.m_129880_(net.minecraft.resources.ResourceKey)" because the return value of "dev.latvian.mods.kubejs.core.EntityKJS.kjs$getServer()" is null
carmine jackal
#

ah so same thing

#

ok sec

#

try going off this level js let level = Utils.server["getLevel(net.minecraft.resources.ResourceKey)"](projectile.level.dimensionKey)

#

that should just be serverlevel

#

although wait itll be ambiguous sec

floral plover
#

would ```js
if(user.level != "ClientLevel") {
let /**@type {Internal.LightningBolt}*/bolt = projectile.level.getBlock(strikePos).createEntity('lightning_bolt')
}

carmine jackal
floral plover
#
startup_scripts:arcbolt.js#54: Error occurred while handling scheduled event callback: TypeError: Cannot find function getLevel(net.minecraft.resources.ResourceKey) in object net.minecraft.client.server.IntegratedServer@458cb759.
carmine jackal
#

it said its only giving the client level though in the error so i assume we need to provide it with the server level

#

ah ok

floral plover
#

btw with that the lightning doesn't render

carmine jackal
#

try going off this js projectile.level.dimension

carmine jackal
#

i assume you're checking if the level is client earlier in the script and the code is being ran only on the server

floral plover
carmine jackal
#

oh wait sec

#

this js let level = Utils.getServer().getLevel(projectile.level.dimension)

carmine jackal
#

ah ok

floral plover
#

no errors

#

but it gets duped

carmine jackal
#

what does

floral plover
#

the lightning

carmine jackal
#

it spawns 2 lightning you mean?

floral plover
#

yeah

#

js is dead again

#

ok

carmine jackal
#

try this js if (!projectile.persistentData.fireOnce) projectile.persistentData.fireOnce = 0 if (projectile.persistentData.fireOnce != 0) return projectile.persistentData.fireOnce = 1 Utils.getServer().scheduleInTicks(1500, () => { projectile.persistentData.fireOnce = 0 }) let level = Utils.getServer().getLevel(projectile.level.dimension)

floral plover
#

with console.log(serverLevel, user.level);
i got ```js
ServerLevel[New World] [net.minecraft.server.level.ServerLevel]
ServerLevel[New World] [net.minecraft.server.level.ServerLevel]
ServerLevel[New World] [net.minecraft.server.level.ServerLevel]
ClientLevel [net.minecraft.client.multiplayer.ClientLevel]

#

with the old one

carmine jackal
#

it should only be giving you the server level and client level hmmm

carmine jackal
floral plover
#

persistentData on the projectile?

carmine jackal
#

yea

#

we want projectile and not user because we want it to be unique per projectile

floral plover
#

i see

#

logged ```js
ServerLevel[New World] [net.minecraft.server.level.ServerLevel]
ServerLevel[New World] [net.minecraft.server.level.ServerLevel]
ServerLevel[New World] [net.minecraft.server.level.ServerLevel]
ClientLevel [net.minecraft.client.multiplayer.ClientLevel]

carmine jackal
#

was there ever a point where it was working?

#

spawning only one lightning

floral plover
#

the ish is because the higher the level of the enchan, the more lightning is spawns

#

using level 3, it only spawned one

carmine jackal
#

hmm

#

have you confirmed if its just visually spawning 2?

floral plover
#

yes

carmine jackal
#

and it is or isnt

floral plover
#

it is

carmine jackal
#

i see

#

so its desync then hmmm

#

i mean what you could do is check in another event like the levelevents.tick to see if the projectile has a certain persistent data on it and if so then spawn the lighting there

floral plover
#

even i have standards

#

that's illegal in every county in europe

carmine jackal
#

eh

#
LevelEvents.tick(event => {
    event.level.getEntities().forEach(entity => {
        if (entity.type != "myprojectile:name") return
        if (entity.persistentData.fireOnce == 1) {
            entity.persistentData.fireOnce = 2
            //summon lightning
        }
    })
    })
})``` mojang does things on tick more than you'd think
#

and if its just value checking then it should be fine

#

then you'd set it's persistent data to 2 which will lock it from firing again ect

floral plover
#

but won't the forEach() cause some lag?

carmine jackal
#

why would it?

floral plover
#

on

#

oh

carmine jackal
#

all its doing is iterating over the list of entities saved like you would any other array list

floral plover
#

yeah i guess something like that gets called more often than you'd think

carmine jackal
#

yeah i mean this is essentially what the LivingTickEvent forge event does too

#

though there isnt a non living tick event sadly so we do this

#

although i just realized

#

i am putting out the new entityjs update which will let you modify entity methods so you technically would have access to the tick method

#

heck even the onremovedfromworld method too

floral plover
#

hold

#

this ```js
console.log(user.level, 1);
let /**@type {Internal.LightningBolt}*/bolt = user.level.getBlock(strikePos).createEntity('lightning_bolt')
console.log(user.level , 2);

carmine jackal
#

also why not just go off user.block btw

#

you dont have to go through level at all

#

i just realized

floral plover
#

how

floral plover
carmine jackal
#

yea

#

try it

floral plover
#

it will strike the user

#

the player

carmine jackal
#

oh true

#

wait

#

you're spawning the lightning where

#

when the projectile hits block?

floral plover
#

good question

#

where this ```js
/**

  • @param {Internal.BlockContainerJS} blockPos
  • @param {number} r
    */
    function strikeArea(blockPos, r) {
    let randomX = Utils.random.nextInt(-r, r)
    let randomZ = Utils.random.nextInt(-r, r)
    for(let dx = -r; dx <= r; dx++) {
    for(let dz = -r; dz <= r; dz++) {
    if(dx == randomX && dz == randomZ) {
    const {x,y,z} = blockPos
    return new BlockPos(x + dx, y, z + dz)
    }
    }
    }
    }``` returns
#

called from ```js
let strikePos = strikeArea(projectile.block, 4-level)

carmine jackal
#

so a random pos around the block hit?

floral plover
#

yes

carmine jackal
#

and it increases accuracy the higher the level

floral plover
#

how the hell did you already understant that

carmine jackal
#

context

floral plover
#

impressive ngl

carmine jackal
#

btw this is what i meant by the new entityjs update js EntityJSEvents.modifyEntity(event => { event.modify("minecraft:firework_rocket", entity => { entity.onRemovedFromWorld(entity => { global.onRemoved(entity) }) }) }) global.onRemoved = entity => { console.log(entity) } you'd be able to do stuff off this for example

#

so essentially when the projectile hits the block anyways

#

well, when it gets removed hmmm

#

i might add a projectile modification event too in that case to get the hitblock/hitentity overrides

wraith surgeBOT
carmine jackal
#

startup script

floral plover
#

cool

carmine jackal
#

i'll have a wiki page on it as well whenever i finish it

floral plover
carmine jackal
#

no because it wont have the persistent data yet til it hits block

#

you'd set the persistent data in the projectile hit block forge event

floral plover
#

right

carmine jackal
#

just gotta remove that scheduleintick callback that sets it back to 0

#

so when you set it to 1/2 its finished

carmine jackal
#

where are you spawning the lightning?

#

the level event?

floral plover
#

the forge event

carmine jackal
#

you spawn it in level event

#

that was the whole point of it heh

carmine jackal
#

do the level logic over there where its not broken

floral plover
#

no need

#

i just fixed it

#

with forge

carmine jackal
#

oh

#

??nosolution

wraith surgeBOT
# carmine jackal ??nosolution

Please post how you solved your issue. Others may find this ticket later, but then have to create another because the actual solution wasn't mentioned. thanks <3

carmine jackal
floral plover
#
      if(!user.level.isClientSide()) {
        let /**@type {Internal.LightningBolt}*/bolt = user.level.getBlock(strikePos).createEntity('lightning_bolt')
        console.log(user.level , 2);
        if(hasPower) {
           bolt.setDamage(bolt.getDamage() * (power + 1))
        }
        bolt.spawn()
      }
carmine jackal
#

so doing only clientside?

#

er non client

#

interesting hmmm

floral plover
#

cortrary to ```js
if(!user.level.isClientSide()) {
let /**@type {Internal.LightningBolt}*/bolt = user.level.getBlock(strikePos).createEntity('lightning_bolt')
console.log(user.level , 2);
if(hasPower) {
bolt.setDamage(bolt.getDamage() * (power + 1))
}
}
bolt.spawn()

#

which was giving the error

carmine jackal
#

wait what did you even change

floral plover
#

bolt.spawn()

#

in or out

carmine jackal
#

ahhhh

#

gotcha

#

makes sense

floral plover
#

outside it gives ```cmd
startup_scripts:arcbolt.js#62: Error occurred while handling scheduled event callback: ReferenceError: "bolt" is not defined.

#

which is why i dismissed it

carmine jackal
#

that actually

#

woulda solved it immediately had you shown me heh

floral plover
#

yeah

carmine jackal
#

cool you solved it though 😄

floral plover
#

my brain kinda shut off when i saw that heh

#

like is it all coming together in my head now

carmine jackal
#

welp time for me to eep, dont forget to close your ticket when you're done heh

floral plover
#

i'll be posting this in examples Soon™

floral plover
#

reopening this bc of weird crash

#
startup_scripts:arcbolt.js#58: Error occurred while handling scheduled event callback: Wrapped net.minecraft.ReportedException: Accessing LegacyRandomSource from multiple threads
wraith surgeBOT
#

Paste version of crash-2024-07-08_16.53.43-client.txt from @floral plover

floral plover
#

@carmine jackal if you're not busy

wraith surgeBOT
#

Paste version of arcbolt.js from @floral plover

floral plover
#

line 58 is ```js
let explosion = level.explode(user, hasPower ? null : negateDamage, null, strikePos.x, strikePos.y, strikePos.z, hasPower ? (power + punch)/10 : punch/3, false, "none", true)

carmine jackal
#

instead of Utils.random do Math.random maybe

#

i assume its an error from the strikeArea function though not sure

floral plover
#

no i think it's the specific arrow not having a clientside version

#

since it only happens with "avaritia:heaven_sub_arrow"

carmine jackal
#

ah

floral plover
#

i'm trying to find a way to get a client level rn

carmine jackal
floral plover
#

no way

#

using minecraft itself in my code is crazy

carmine jackal
carmine jackal
#

then its something else

floral plover
#

though through testing i can confirm tnat only running it on server side doesn't crash

#

but doesn't render particles either

carmine jackal
#

you can send a packet

floral plover
#

wat

carmine jackal
#
PlayerEvents.tick(event => {
    //sending data from the server side (can be in your forge event)
    event.player.sendData("myDataTicket", { data: "my data" })
})
//Event that goes in client scripts
NetworkEvents.dataReceived("myDataTicket", event => {
    //code here will fire on the client side if in client scripts whenever
    //you send data from the server
    console.log(event.data.get("data")) // will output "my data"
})
carmine jackal
floral plover
#

can you send thing that aren't compond tags?

carmine jackal
#

no but all you need are compound tags THONK

floral plover
#

what i thought

carmine jackal
#

all you're tryna do is trigger an explosion in client scripts which is why you send the coords through the compound tag

#

ect

#

can also send the dimension's resource location and parse it over there if needed

floral plover
#

can i send data with something that isn't player?

carmine jackal
#

yea

#

any entity i believe

floral plover
#

idk man

#

i guess i can just assume that user is going to be a player, right?

carmine jackal
#

well try

#

just send it off server

#

Utils.server.sendData works too

floral plover
#

the worst part of this is that it bypasses try catch so i have to restart my game every time it crashes

#

interesting development

#

i managed to crash the game with a different arrow

#

i have decided to let go of the particles and give up

eternal lionBOT
#

Ticket re-opened!

floral plover
carmine jackal
#

maybe modify the arrow's knockback resistance attribute? shot in the dark

#

with the attribute modification event js //attributes Startup Script EntityJSEvents.attributes(event => { event.modify('minecraft:allay', attribute => { //Overwrite an allay's max health attribute setting it to 30. attribute.add("minecraft:generic.max_health", 30) }) })

floral plover
floral plover
carmine jackal
#

no

#

there should be a new update out

#

its properly debugged and updated

floral plover
#

👏

carmine jackal
#

since arrows are non living entities all you have for them are the ModifyEntityBuilder methods

#

though theres like 50 of them

floral plover
#

using F3 i couldn't find a knockback resistance method

#

oh well

carmine jackal
#

there isnt one no

#

i meant generally if you wanted to do something else

floral plover
#

ah

#

i wasn't even doing anything with it before heh

carmine jackal
#

np

#

did the attribute event work?

floral plover
carmine jackal
#

thats not an attribute

#

i think its generic.knockback_resistance

floral plover
#

idk man

floral plover
#

oh

carmine jackal
floral plover
#

hmmm

#

didn't seem to work

carmine jackal
#

what value you set it at

floral plover
#
EntityJSEvents.attributes(event => {
  event.modify("avaritia:heaven_sub_arrow", attribute => {
    attribute.add('minecraft:generic.knockback_resistance', 1)
  })
})```
carmine jackal
#

do 100

floral plover
#

i'm assuming it's not reloadable in game

carmine jackal
#

nope

floral plover
#

🙃

carmine jackal
floral plover
#

there is a difference

#

but they still fly

#

i am going to try this ```js
attribute.add('minecraft:generic.knockback_resistance', Infinity)

carmine jackal
#

thats not a thing

#

but you can maybe try 500

#

or 1k idk

#

1 million

floral plover
#

idk 100 seems to cause the least knockback

#

i guess it'll do

#

thanks again!