#Need help figuring out this Java class

77 messages · Page 1 of 1 (latest)

errant sorrel
#

As far as I can tell, you cant summon the Species spectrte mobs tamed, even with the owner tag, so ive resorted to reading the source code to find the trigger event for the tamed spawning

Ive gotten so very close, but I cant figure out what to input for the 3rd var in the spawnSpectre event

const Spectre = Java.loadClass("com.ninni.species.server.entity.mob.update_3.Spectre")
const ServerLevel = Java.loadClass("net.minecraft.server.level.ServerLevel")

ForgeEvents.onEvent("net.minecraftforge.event.entity.living.MobEffectEvent$Expired", event => global.effectsSpectralibur(event));
/**
 * 
 * @param {Internal.MobEffectEvent$Expired} event 
 */
global.effectsSpectralibur = event => {
    const { effectInstance, effectInstance: { descriptionId }, entity, player, ServerLevel} = event
    console.log(descriptionId, effectInstance.amplifier)
    try {
        if (descriptionId == "effect.weapon_class.stealth" && effectInstance.amplifier > -1 && entity.mainHandItem === 'species:spectralibur') {
            entity.server.scheduleInTicks(10, () => {
              Spectre.spawnSpectre(ServerLevel, player, player.getOnPos(), Spectre.Type.SPECTRE, true)
              Utils.server.runCommandSilent(`say it problably worked...`)
            }
          )
        }
    } catch (error) {
        console.log(error)
    }
}

sorce code for the mod here: https://github.com/Peculiar-Room/Species/blob/main/src/main/java/com/ninni/species/server/item/SpectraliburItem.java

returns [Server thread/ERROR] [KubeJS Server/]: startup_scripts:weapon_class/spectralibur.js#15: Error occurred while handling scheduled event callback: TypeError: Cannot call method "getOnPos" of undefined on effect end

any help is greatly appreciated

crisp dockBOT
#

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

errant sorrel
#

It would be so nice if the mod wasn't hard coded to just not let you spawn the mob as a tamed pet

#

If any more information is needed, please let me know so I can provide it

errant sorrel
#

it has only been 3 hours but ima bump this anyway

last pagoda
#

Neither player nor ServerLevel exist in event, so both are undefined

#

I really wonder, why are you setting your event in global?

errant sorrel
#

This is the result of me just throwing things at the wall untill it stops giving me errors

#

Both ServerLevel and player where comming out as empty at first but it seems to have stopped doing that nor did it causes a crash when they where defined

last pagoda
#

Ok, but that doesn't change the fact that player and ServerLevel are not present in event object

errant sorrel
#

Makes sense

#

But how would I add em?

last pagoda
#

You can't

#

Remove ServerLevel from the destructuring pattern

#

So that ServerLevel variable will be visible (due to being in scope)

errant sorrel
#

Or teal

#

this color

const Spectre = Java.loadClass("com.ninni.species.server.entity.mob.update_3.Spectre")
const ServerLevel = Java.loadClass("net.minecraft.server.level.ServerLevel")

ForgeEvents.onEvent("net.minecraftforge.event.entity.living.MobEffectEvent$Expired", event => global.effectsSpectralibur(event));
/**
 * 
 * @param {Internal.MobEffectEvent$Expired} event 
 */
global.effectsSpectralibur = event => {
    const { effectInstance, effectInstance: { descriptionId }, entity, player} = event
    console.log(descriptionId, effectInstance.amplifier)
    try {
        if (descriptionId == "effect.weapon_class.stealth" && effectInstance.amplifier > -1 && entity.mainHandItem === 'species:spectralibur') {
            entity.server.scheduleInTicks(10, () => {
              Spectre.spawnSpectre(ServerLevel, player, player.getOnPos(), Spectre.Type.SPECTRE, true)
              Utils.server.runCommandSilent(`say it problably worked...`)
            }
          )
        }
    } catch (error) {
        console.log(error)
    }
}
#

o wait that dosent work

#

Teal

last pagoda
#

You are still trying to destructure player from event which is undefined

#

Also, what are you trying to do with the ServerLevel?

#

Oh, you want a dimension

#

But ServerLevel is a class reference, not an instance

#

One thing I can tell you immediately, this won't be needed

errant sorrel
#

I see

last pagoda
#

You should get level from the entity

errant sorrel
# last pagoda You should get level from the entity

easy enough

global.effectsSpectralibur = event => {
    const { effectInstance, effectInstance: { descriptionId }, entity} = event
    console.log(descriptionId, effectInstance.amplifier)
    try {
        if (descriptionId == "effect.weapon_class.stealth" && effectInstance.amplifier > -1 && entity.mainHandItem === 'species:spectralibur') {
            entity.server.scheduleInTicks(10, () => {
              Spectre.spawnSpectre(entity.level.dimension, player, player.getOnPos(), Spectre.Type.SPECTRE, true)
              Utils.server.runCommandSilent(`say it problably worked...`)
            }
          )
        }
    } catch (error) {
        console.log(error)
    }
}
last pagoda
#
const Spectre = Java.loadClass('com.ninni.species.server.entity.mob.update_3.Spectre')
const $MobEffectEventExpired = Java.loadClass('net.minecraftforge.event.entity.living.MobEffectEvent$Expired')

ForgeEvents.onEvent($MobEffectEventExpired, event => {
  const { effectInstance, entity } = event
  const { descriptionId } = effectInstance
  console.log(descriptionId, effectInstance.amplifier)
  if (entity.isPlayer())
    if (
      descriptionId == 'effect.weapon_class.stealth' &&
      effectInstance.amplifier > -1 &&
      entity.mainHandItem === 'species:spectralibur'
    ) {
      entity.server.scheduleInTicks(10, () => {
        Spectre.spawnSpectre(entity.level, entity, entity.getOnPos(), Spectre.Type.SPECTRE, true)
        Utils.server.runCommandSilent(`say it problably worked...`)
      })
    }
})
errant sorrel
#

99% sure this is how that's fone

#

Donw

#

Done

#

GOD

last pagoda
#

level.dimension is a ResourceLocation, not a ServerLevel.

#

Maybe there's a type wrapper (as usual with KubeJS), it there is I'll be surprised

errant sorrel
#

Or

#

Most functions anyway

last pagoda
#

What do you mean by "inline commands"?

#

level.dimension is a "bean" - which is equivalent to level.getDimension()

errant sorrel
#

Utils.server.runcommandsilent

last pagoda
#

You should get the server from the entity as well

#

Or even better - don't use commands

#
ForgeEvents.onEvent($MobEffectEventExpired, event => {
  const { effectInstance, entity } = event
  const { descriptionId } = effectInstance
  const server = entity.server
  console.log(descriptionId, effectInstance.amplifier)
  if (entity.isPlayer())
    if (
      descriptionId == 'effect.weapon_class.stealth' &&
      effectInstance.amplifier > -1 &&
      entity.mainHandItem === 'species:spectralibur'
    ) {
      entity.server.scheduleInTicks(10, () => {
        Spectre.spawnSpectre(entity.level, entity, entity.getOnPos(), Spectre.Type.SPECTRE, true)
        server.tell('it problably worked...')
      })
    }
})
last pagoda
#

ResourceLocation will be converted quite straightforwardly to string

#

But not ServerLevel

errant sorrel
#

Yeah that makes sense!

#

Seems kinda dumb but i'm guessing that's just a result of something like "IDs are handled differently than strings"

last pagoda
#

No

#

All non-string objects are handled differently from strings

#

If you pass an object in a place that expects a string, the object's toString() method is invoked

errant sorrel
#

I mean I know that

last pagoda
#

And object conversion to string will differ from object to object

errant sorrel
#

Aaaaaaaaah

#

Ok that makes sense

last pagoda
#

Each class can specify its own behavior of toString

errant sorrel
#

Sorry if I'm asking too many questions

#

You're just explaining things to me in a way that makes a lot of sense

last pagoda
errant sorrel
#

Which thank you

errant sorrel
#

My dad purchased a Java crash course for himself but I'm gonna take that too in your honor

#

And it works perfectly now!

#

Thank you so so much

last pagoda
errant sorrel
#

You have been a huge help

errant sorrel
last pagoda
#

But ServerLevel's toString is generic, and helps one learn that this is indeed a ServerLevel

public String toString() {
    return "ServerLevel[" + this.serverLevelData.getLevelName() + "]";
}
#

You can read vanilla source code by:

  • Opening up IntelliJ IDEA
  • Downloading the "Minecraft Development" plugin (just to make creating mod dev environments easier)
  • Creating a 1.20.1 Forge mod dev env
  • Wating for Gradle to do its job
errant sorrel
#

Understood

#

I'm gonna try and do that tonight

#

Again, thank you for your help