#create explosion that doesn't deal damage to entities
529 messages · Page 1 of 1 (latest)
Once your ticket has been resolved, please close it with </ticket close:1054771505520717835> command!
bump
why are you bumping this?
because i also want to know this
fair
@carmine jackal i summon liopyu!
ill send the testing script im using to try this out in just a sec
aight
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
wait i think it works?? maybe?? but only on survival mode
okay so this works but only on survival mode (aka damage taken?) AND it shoots in what feels like a completely random direction
@carmine jackal any tips?
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!!
it all goes off entity just like entity builders
the callback is entity not event
so entity.level
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
heck i'd just do js const { x, y, z, level } = entity
with the global you can do /kubejs reload startup_scripts without reloading the entire game
but the knockback is REALLY random
oh sweet
retesting with global, ik it wont change anything but still
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
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
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 
so maybe randomly set bigger values that will override the x and z strengths so it doesnt always go to 0,0
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 
ahh sorry back
mhm
sure
[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)```

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
ouch
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
oh btw this does nothing for me
probejs doesnt work on linux
(the probejs thing)
let x = entity.x
let y = entity.y
let z = entity.z
entity.knockback(2, y, z)
})``` ?
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
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);
}
}
}```
and the first value is strength?
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)
})
}```
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
alr
hmm actually
is entity the entities hit
or the firework?
you should change this js .forEach(entity => { to js .forEach(target => { for more clarity 
cause then you'll have both
oo alr
-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
where did you get this from btw
my math genie friends r helping me in dms rn
the LivingEntity class
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
thats because i have parchement mappings and im in my ide
its all the same though
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
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
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
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
when i put 0 0 manually in for x and z
it does nothing
they only know math

i can send them the entity methods
but once again, probejs doesnt work (it didnt start working as far as i can tell)
and all your files are in the new src folders?

okay i think i've got a working formula but i am very sorry i have to ask this as i do not have probejs: if 'entity' is the firework itself, how could i target whatever's in the radius?
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
entity is the firework yea
so it works but its just. Kinda Buggy?
shooting directly at my feet doesnt launch me up
thats just math stuff
phew..

deltaMovement
tyty
yup
yea
sweet
where are we at currently?
he did?
as im basically solved too
here
oh shit I pinged
oops sorry liopyu
gimme sec, im doing a test to see if i can improve it
idc about getting pinged 
@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
oh shit!! upwards motion helps a lot, the rest I had
very good
ok i have a revision for if you dont want it to hurt other entities, sec
ive already setup the knockback n such it was just the upwards formula I needed
thank you so much!
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()
})
}
}```
you have to put it in both server and client scripts
i see
wait
ForgeEvents only doesn't work on server
or is it because it's the same file?
no
whered you get this script then if you didnt write it 
thats not what i sent you
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
though i am returning the clientside event due to it running twice or else
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"); })
dying from an explosion that doesn't deal damage is very funny
imagine
also i rearranged it because you actually need that getDamageSource function in the same script you use the damage source in
death.fell.accident.water moment
also i forgot i left my test code in the hurt event js if (event.entity.mainHandItem.id == "minecraft:diamond") return remove this from your code if you have it 
lol
i believe you can use a try catch function in the global to prevent most crashes from happening
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
well, i did and it seems to deal damage
does it deal damage when theres no power?
yes

wait so its reversed?
??whythishappen
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
lol
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
servers null somewhere
well yeah the bolt is created on the server and client, no?
please tell me you don't know that by heart
i do not sadly, i looked it up in my ide 
oh ok
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]
i see
so wherever that code is is on client side
you need serverlevel to create entities
show the rest of your code
that forge event runs on server and client
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 
some stuff is excluded btw to make it fit
but its just functions
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')
you mean it spawns a lightning bolt?
yeah

particle and damage
whats the error message
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
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
would ```js
if(user.level != "ClientLevel") {
let /**@type {Internal.LightningBolt}*/bolt = projectile.level.getBlock(strikePos).createEntity('lightning_bolt')
}
there try that
you can simplify this with js if (projectile.level.isClientSide) but yeah try it
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.
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
btw with that the lightning doesn't render
try going off this js projectile.level.dimension
its probably not syncing to client then
i assume you're checking if the level is client earlier in the script and the code is being ran only on the server
same error with ```js
let serverLevel = Utils.server"getLevel(net.minecraft.resources.ResourceKey)"
oh wait sec
this js let level = Utils.getServer().getLevel(projectile.level.dimension)
no i removed that
ah ok
what does
the lightning
it spawns 2 lightning you mean?
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)
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
it should only be giving you the server level and client level 
yeah try this one, it should only let the code run once every 1500 ticks
persistentData on the projectile?
yea
we want projectile and not user because we want it to be unique per projectile
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]
the ish is because the higher the level of the enchan, the more lightning is spawns
using level 3, it only spawned one
yes
and it is or isnt
it is
i see
so its desync then 

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
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
but won't the forEach() cause some lag?
why would it?
all its doing is iterating over the list of entities saved like you would any other array list
yeah i guess something like that gets called more often than you'd think
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
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);
also why not just go off user.block btw
you dont have to go through level at all
i just realized
logs ```js
ServerLevel[New World] [net.minecraft.server.level.ServerLevel]
1.0
ServerLevel[New World] [net.minecraft.server.level.ServerLevel]
2.0
ClientLevel [net.minecraft.client.multiplayer.ClientLevel]
1.0
how
user.block?
oh true

wait
you're spawning the lightning where
when the projectile hits block?
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)
so a random pos around the block hit?
yes
how the hell did you already understant that
impressive ngl
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 
i might add a projectile modification event too in that case to get the hitblock/hitentity overrides
this is the beta build i sent ouroborous to test out if you also would like to test it out #1259244226496036965 message
[➤](#1259244226496036965 message) i worked on it a bit more and i did some bug fixes, delete that other one
startup script
cool
i'll have a wiki page on it as well whenever i finish it
wait
won't this make it spawn lightning immediately when i shoot it?
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
right
just gotta remove that scheduleintick callback that sets it back to 0
so when you set it to 1/2 its finished
still
how
the forge event
though i think i get it now
do the level logic over there where its not broken
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

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()
}
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
wait what did you even change
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
yeah
cool you solved it though 😄
my brain kinda shut off when i saw that 
like is it all coming together in my head now
welp time for me to eep, dont forget to close your ticket when you're done 
i'll be posting this in examples Soon™
Ticket re-opened!
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
accompanied with this
Paste version of crash-2024-07-08_16.53.43-client.txt from @floral plover
Paste version of arcbolt.js from @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)
instead of Utils.random do Math.random maybe
i assume its an error from the strikeArea function though not sure
no i think it's the specific arrow not having a clientside version
since it only happens with "avaritia:heaven_sub_arrow"
ah
i'm trying to find a way to get a client level rn
maybe js let Minecraft = Java.loadClass("net.minecraft.client.Minecraft") Minecraft.getInstance().player.level

crashed with the same error
though through testing i can confirm tnat only running it on server side doesn't crash
but doesn't render particles either
you can send a packet
wat
like this?
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"
})
i revised it to show the other thing you can do with this which is send compound tags
can you send thing that aren't compond tags?
no but all you need are compound tags 
what i thought
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
can i send data with something that isn't player?
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
Ticket re-opened!
is there a way to negate knockback on nearby arrows?

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) }) })
for context using a barrage of arrows gives massive knockback to some of them, pushing them sometimes out of render distance, which i don't like
still using the beta version of EntityJS?
👏
also i guess now you can take a look at the available methods to use since modifyEntity event is officially a thing with a wiki page https://github.com/liopyu/EntityJS/wiki/Entity-Modification-Event#:~:text=entity being modified.-,Methods by Builder Type,-ModifyEntityBuilder Methods
since arrows are non living entities all you have for them are the ModifyEntityBuilder methods
though theres like 50 of them
idk man
i'll still try it
oh
i see

EntityJSEvents.attributes(event => {
event.modify("avaritia:heaven_sub_arrow", attribute => {
attribute.add('minecraft:generic.knockback_resistance', 1)
})
})```
do 100
i'm assuming it's not reloadable in game
nope
🙃

