#Registering EntityJS entity in a script

285 messages · Page 1 of 1 (latest)

tender yacht
#

I feel like I am just on the cusp of making this all work, and if I am, I am very proud of myself, however I think I am going to need a little push from you @royal sedge to get me across the finish line. I am currently trying to register my projectile inside the script for a spell from SpellJS using

const $cosmicCortexProjectile = Java.loadClass('net.liopyu.entityjs.entities.nonliving.entityjs.ProjectileEntityJS')

to do so. I can assume this is the right way of going about this as I have gotten as far as I have. I can't figure out what arguements I need to put at

let cosmicCortex = new $cosmicCortexProjectile(player.level, player)

to at the very least get past that stage and continue testing the rest of the script.

cosmiccortex.js#37: Error while calling onCast: Java constructor for "net.liopyu.entityjs.entities.nonliving.entityjs.ProjectileEntityJS" with arguments "net.minecraft.server.level.ServerLevel,net.minecraft.server.level.ServerPlayer" not found.

dense siloBOT
#

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

tender yacht
#
const $EntityEffect = Java.loadClass('com.lowdragmc.photon.client.fx.EntityEffect')
const $FXHelper = Java.loadClass('com.lowdragmc.photon.client.fx.FXHelper')
        global.cosmic_cortex = (/** @type {Internal.CustomSpell$CastContext} */ ctx) => {
            let /** @type {Internal.LivingEntity} */ player = ctx.entity;
            let spellPower = ctx.getSpellLevel();
            let rayTrace = player.rayTrace(16)
            if(rayTrace == null) return
            let target = rayTrace.entity
            if(target == null) return
            player.tell('BOOM')
            let cosmicCortex = new $cosmicCortexProjectile(player.level, player)
            cosmicCortex.onAddedToWorld(entity => {
                console.log(Utils.server.runCommand('playsound irons_spellbooks:magic_arrow_release master @p ~ ~ ~'))
                const FX_NEBULA = $FXHelper.getFX('photon:nebula_orb4')
                entity.setNoGravity(true)
                let effect = new $EntityEffect(FX_NEBULA, entity.level, entity)
                effect.setAllowMulti(false)
                effect.start()
            })
            cosmicCortex.onHitEntity(context => {
                const { entity, result } = context;
                // Custom behavior when the arrow hits an entity, for example, applying potion effects
                if (result.entity.living) {
                    // Create damage source
                    const damageSource = getDamageSource(entity.level, "kubejs:astral_damage");
                    if (entity.level.clientSide) return;
                    result.entity.attack(damageSource, 20 + (spellPower * 10));
                    entity.remove("discarded")
                }
            })
            cosmicCortex.onHitBlock(context => {
                let { result: { blockPos }, entity } = context
                entity.getLevel().createExplosion(blockPos.x, blockPos.y, blockPos.z)
                    .strength(4)
                    .explosionMode('tnt')
                    .explode()
                entity.kill()
            })
            cosmicCortex.setPos(target.x, target.y+10, target.z)
            cosmicCortex.setMotionY(-2)
            cosmicCortex.spawn()
        }
#

full code

royal sedge
#

theres a spell projectile builder though

tender yacht
#

yea I was struggling to convert my projectile to a spell projectile upon learning that

royal sedge
#

what did you try?

tender yacht
#

well I tried switching the register to irons_spells_js instead of entityjs:projectile and it didnt like some of the functions that were in the original projectile so I removed them and didnt get any errors but it wasnt working

royal sedge
#

its "irons_spells_js:spell_projectile"

tender yacht
#

mb thats what I meant

royal sedge
#

what methods didnt it like off the entityjs:projectile builder?

#

should be the same builder

#

essentially

tender yacht
#

it didnt like item but that makes sense, and it didnt like sized

royal sedge
#

say what

#

both of those should be on the ProjectileEntityBuilder hmmm

tender yacht
#

I can try it again now that I have a second

royal sedge
#

aight

#

if it errors send the startup logs

tender yacht
tame yarrowBOT
#

Paste version of startup.log from @tender yacht

royal sedge
#

crap i think i know whats going on

#

aight this ones on me, im gonna have to put out an update, apparently i put item in the projectile builder's parent class, also the sized should be there

#

item is the only one that isnt inherited in the spelljs compat so i'll have to do that

#

should work otherwise if you remove item for now

tender yacht
#

maybe I just fudged the script when I removed item before, didn't get the error for sized this time, however summoning the projectile doesn't seem to do anything

#

ok so it summons as I can see the hitbox, but it doesn't seem to do any of the things it would do previously, it doesn't have its photon effect, it doesn't explode upon hitting the ground

royal sedge
#

are there any errors when you summon it?

tender yacht
#

server and startup logs don't report anything when I summon it

royal sedge
#

cause besides having no .item its pretty much the same as the entityjs:projectile builder

#

odd

#

do you have connector mod?

tender yacht
#

as in sinytra?

royal sedge
#

yea

tender yacht
#

nope

royal sedge
#

hmm

#

console log the level whether or not its level.clientSide

tender yacht
#

how and where do I do that heh

royal sedge
#

uh

#

probably wherever your methods arent working i assume

#

also it looks like the spell projectile extends from the irons spells projectile class which doesnt have a setItem field so i suppose it wouldnt have mattered if the spell projectile had the .item method anyways

tender yacht
#

as far as I can tell, they aren't working even at the very first line, because I already had something like that in place at the start and the command never gets logged at all

royal sedge
#

i could impliment a manual way anyways though i dont think spells are meant to be thrown

royal sedge
#

utils.server.runcommand is a void method no?

tender yacht
#

it goes into the server logs 0.0 or 1.0 whether or not the command runs correctly

royal sedge
#

ah

tender yacht
#

and it isnt even logging 0.0

royal sedge
#

so log entity.level.clientSided

#

also it says fxhelper is declared multiple times

#

set it to let instead of const

tender yacht
#

yea I fixed that, I knew about that one but thanks

royal sedge
#

ah ok

#

yeah log the level and let me know

tender yacht
#

so like this?

console.log(entity.level.clientSided)
royal sedge
#

yea

#

also dont forget you can put your functions in a global event so you can live edit without restarting the game

tender yacht
#

it explains that in the Spell Registry example script but I never really understood how it worked

royal sedge
#

send your onAddedToWorld block

tender yacht
#
.onAddedToWorld(entity => {
            console.log(entity.level.clientSided)
            const FX_NEBULA = $FXHelper.getFX('photon:nebula_orb4')
            entity.setNoGravity(true)
            let effect = new $EntityEffect(FX_NEBULA, entity.level, entity)
            effect.setAllowMulti(false)
            effect.start()
        })
royal sedge
#

this in the builder```js
.onAddedToWorld(entity => global.addedToWorld(entity))

then this outside the startup event handler
```js
global.addedToWorld = entity => {
    console.log(entity.level.clientSided)
    const FX_NEBULA = $FXHelper.getFX('photon:nebula_orb4')
    entity.setNoGravity(true)
    let effect = new $EntityEffect(FX_NEBULA, entity.level, entity)
    effect.setAllowMulti(false)
    effect.start()
}```
#

then you should be able to restart with /kubejs reload startup_scripts

tender yacht
#

oh awesome so I could've been testing the spell script this whole time without restarting heh

#

anyhow, it isnt logging anything still

royal sedge
#

its clientSide not clientSided

tender yacht
#

whoopsi, still nothing

royal sedge
#

and you restarted your game after adding in the new global event?

#

gotta restart at least once

tender yacht
#

ah ok, from the top

royal sedge
#

yeah cause anything in that function here will need a restart js .onAddedToWorld(entity => global.addedToWorld(entity)) though the global function which is outside the registry event will reload

#

if that makes sense

tender yacht
#

yea that checks out

royal sedge
#

also make sure the global event is outside the registry event, just to make certain

tender yacht
#

yea nothing

royal sedge
#

if its not console logging anything then something is wrong

#

send your full script

#

just the registry

tender yacht
tame yarrowBOT
#

Paste version of message.txt from @tender yacht

royal sedge
#

oh good god

#

the projectile overrides are just not there in kjs irons spells mod pepelaugh

#

so its literally not reading it

#

ok well thats something i'll have to impliment with squoshi tomorrow i guess

tender yacht
#

oh my god squoshi has alot of debts owed to me haha

royal sedge
#

lmao

tender yacht
#

i keep doing this as I get further and further into my spell/school creation process

royal sedge
#

i'll take care of it and will ping you here when its fixed

tender yacht
#

ok thank you, also, was I onto something at all with my original script?

#

trying to register the projectile in the spell script

royal sedge
#

eh

#

you'd have to also register a builder

#

and that would be the same thing as event.create except just pointless effort

#

also probably not possible with just reflection tbh considering you also would have to register renderers ect

tender yacht
#

the whole reason I was trying that in the first place was the need to change the projectiles damage based on the spell level, which since I couldn't seem to change the projectiles damage in the spell script, and couldn't access the spellLevel from the projectile builder, I thought to try that, so I'll also need to know how to modify the spell_projectile damage based on level, would it work pretty much exactly like this once its fixed?

royal sedge
#

i mean you can always use pdata i assume or if AbstractMagicProjectile has a method off of it that detects the spell's level you can modify the damage that way

tender yacht
#

yea you can use event.getSpellLevel() for that, and then input it into the damage formula like

let spellPower = ctx.getSpellLevel();
result.entity.attack(damageSource, 20 + (spellPower * 10));
royal sedge
#

ah i see

tender yacht
#

I guess I was asking if something like .setDamage exists to use in the spell script for the projectile, or if you can do it from the spell_projectile registry

royal sedge
#

it does

#

pretty sure anyways

tender yacht
#

ok cool, thank you so much, I'll test that out when its fixed

royal sedge
#

oh wait thats for the arrow entity hmmm

#

you could definately do .attack in the onHitEntity method though i assume, thats how irons spells does it anyways

tender yacht
#

interesting, so they setup the damage specific stuff in the registry, but modify it in the spell itself

royal sedge
#

yeah i was looking at that too

#

well, the source is the spell

#

the damage is whatever is set in the method

#

oh wait

#

maybe they have a setDamage function?

tender yacht
#

as in, in the SpellJS registry?

royal sedge
#

oo

#

in the AbstractSpellProjectile

#

off the projectile entity

#

so then you'd override the onhitentity method and copy what they did

tender yacht
#

so register the spell_projectile normally, and then modify the .onHitEntity in the spell script for it?

royal sedge
#

something like that js .onHitEntity(context => { const { entity, result } = context; DamageSources.applyDamage(result.entity, entity.getDamage(), SpellRegistry.LIGHTNING_LANCE_SPELL.get().getDamageSource(entity, entity.getOwner())); })

#

except instead of lighting lance spell you'd get your spell somehow

#

wait didnt you create your custom damage source already? or was that someone else

tender yacht
#

nvm if it works exactly the same then I shouldn't need to modify it in the spell script, however I'm not sure about getting the spell, as it doesn't seem like it comes up in SpellRegistry unless its because ProbeJS doesn't know about it

#

yea I did

royal sedge
#

yeah just use that then

#

and true, no need to complicate it if all you need to do is js result.entity.attack(damagesource,10) or something lul

#

also one question from me

tender yacht
#

yes?

royal sedge
#

why do we need to do the spell entity builder in this case? why not just do normal projectile builder?

#

at this point squosh hasnt really added much to the spell projectile builder anyways so they're essentially the same

#

i think the only thing he added was onAntiMagic

#

(not sure what it does)

tender yacht
#

is there a way I can modify the projectiles damage post registry? or access the entities spellLevel in the damage formula?

#

thats basically the whole reason, is to make the projectile damage scale based on spellLevel

royal sedge
#

you dont need to modify damage when you can set the damage to what you need when you attack right?

#

cause all the damage is in the spell entity projectile is a setter and getter and a predefined float

#

and they grab it once when they attack pepelaugh

royal sedge
tender yacht
#

well there are (in this case) 3 different levels of the spell, and only 1 overarching spell script to control all 3 levels of the spell, so it would have to be able to fluctuate the damage in the context of one script

royal sedge
#

right

#

i wonder if you could store it in the player's persistent data

#

cause you have the owner of the projectile i assume

#

entity.getOwner()

tender yacht
#

I swear someone else in the discord has done this before but I think I'm just remembering looking at the ISS github a while ago

royal sedge
#

you also have this method js setOwner(player)

#

which you can set upon shooting

tender yacht
#

yea the owner part is easy, however I had an idea before (which wasn't working with the projectile thing) to use something like

cosmicCortex.onRemovedFromWorld

and then doing the attack from that in the spell script rather than giving the projectile itself a damage amount onHit and use the onHit to remove the projectile and trigger the removedFromWorld

#

but probejs was just giving me false hope as that doesn't work with the projectile

royal sedge
#

what doesnt work, the remove?

tender yacht
#

onRemovedFromWorld doesn't work with the projectile builder

royal sedge
#

looks like it should

#

actually

#

i wonder if calling super before the function just voids everything

#

crap uh, thats another thing ill have to test tomorrow

tender yacht
#

I'm so good at testing things heh

royal sedge
#

lmao fr though

#

also i assume you probably just want to do everything in the onhitentity method right before you call entity.remove

#

instead of using the onremovedfromworld method indirectly calling your logic

#

its up to you though, im gonna fix it tomorrow either way

tender yacht
#

the only reason I wanted to try and use onRemovedFromWorld was to use it in the spell script like you would use

cosmicCortex.setPos

and then have the ability to use getSpellLevel() since I am in the spell registry rather than the projectile registry and then do the result.entity.attack with the damage calculation directly in the spell script, its just my only logic I could come up with as a slightly experienced user of KubeJS haha

#

so instead of dealing damage when it hits the entity, it would deal it when it gets removed (which is sort of the same concept but with a scuffed execution to make it work how I wanted to)

royal sedge
#

@tender yacht there should be an updated entityjs version which fixes onRemovedFromWorld method, test it out and lemme know if it works now

tender yacht
#

ok, downloaded the update, switched the projectile back to entityjs:projectile, lets see

#

hmm, not related but I am getting a different issue one second

#

cosmiccortex.js#36: Error while calling onCast: Can't find method net.liopyu.entityjs.entities.nonliving.entityjs.ProjectileEntityJS.onRemovedFromWorld(function).

#
global.cosmic_cortex = (/** @type {Internal.CustomSpell$CastContext} */ ctx) => {
    let /** @type {Internal.ServerPlayer} */ player = ctx.entity;
    let spellPower = ctx.getSpellLevel();
    let rayTrace = player.rayTrace(16)
    if(rayTrace == null) return
    let target = rayTrace.entity
    if(target == null) return
    player.tell('BOOM')
    let cosmicCortex = target.block.createEntity("kubejs:cosmic_cortex_projectile")
    cosmicCortex.onRemovedFromWorld(context => {
        const entity = context
        const damageSource = getDamageSource(entity.level, "kubejs:astral_damage");
        target.entity.attack(damageSource, 10 * spellPower)
    })
    cosmicCortex.setPos(target.x, target.y+10, target.z)
    cosmicCortex.setMotionY(-2)
    cosmicCortex.spawn()
}
#

is it not possible to use it outside of the context of the registry like using .setPos?

royal sedge
#

without the full script i dont know what im looking at tbh

tender yacht
#

this is the full script for the spell, which is where I am trying to utilize it

royal sedge
#

if you're asking if its possible to do onRemovedFromWorld off the entity object then no its not possible just like any other of the void methods

royal sedge
#

althought you could try js entityjsentity.getBuilder().onRemovedFromWorld( ive never tried it before though

royal sedge
tender yacht
#

and put that as

cosmicCortex.entityjsentity.getBuilder().onRemovedFromWorld(

???

royal sedge
#

yeah or whatever your function is

#
cosmicCortex.getBuilder().onRemovedFromWorld(context => {
        const entity = context
        const damageSource = getDamageSource(entity.level, "kubejs:astral_damage");
        target.entity.attack(damageSource, 10 * spellPower)
    })```
tender yacht
#

oh ok got it

royal sedge
#

just make sure not to run it on a tick event or something because its only meant to be set on startup of the game or on /kubejs reload startup_scripts since it does set the function of the builder

#

im assuming its not good for performance though again not sure cause i've never tried it

tender yacht
#

it should only be run when the spell itself is cast, and I guess we are about to find out

royal sedge
#

fair enough

#

could also set a boolean variable that detects if the function has been set for a certain spell or not

#

assuming it works that is heh

tender yacht
#

cosmiccortex.js#36: Error while calling onCast: TypeError: Cannot find function getBuilder in object ProjectileEntityJS['entity.kubejs.cosmic_cortex_projectile'/986, l='ServerLevel[zwevadeva]', x=506.00, y=126.00, z=621.00].

#

womp womp

royal sedge
#

oof

#

wait

#

it might be called something different in the projectile builder

royal sedge
tender yacht
#

and also for some reason despite the spell script being in the global, I can't reload it in game for whatever reason, despite it being in the example script, but thats a whole different thing

royal sedge
#

yeah you can only load callback functions

#

not the actual functions themselves

tender yacht
#

wahhhgone so many rules

#

WAIT IT... is working?

royal sedge
#

i honestly didnt even think that was possible but OK

#

i guess you have the entire builder access then lul

tender yacht
#

however I need to fix the attack defined entity, thats the part not working now haha

#

oh wait

#

that means I can just use onHitEntity instead right

royal sedge
#

probably lol

tender yacht
#

uhhh hmm ccprojectile.js#5: [EntityJS]: Error in entity.kubejs.cosmic_cortex_projectilebuilder for field: onHitEntity.: TypeError: Cannot call method "registryAccess" of undefined

royal sedge
#

level is undefined

#

show the script part

tender yacht
#
cosmicCortex.getProjectileBuilder().onHitEntity(context => {
        const entity = context
        const damageSource = getDamageSource(entity.level, "kubejs:astral_damage");
        entity.entity.attack(damageSource, 10 * spellPower)
    })
royal sedge
#

whats line 5?

#

assuming its the getDamageSource line

tender yacht
#

oh wait

#

its happening from the projectile registry script

#
const $ResourceKey = Java.loadClass("net.minecraft.resources.ResourceKey")
const DAMAGE_TYPE = $ResourceKey.createRegistryKey("damage_type")
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)
#

line 5

#

is it because the original script already has .onHitEntity?

royal sedge
#

yeah level is null here

#

assuming level is clientsided wherever you're getting it from

#

or its null altogether

#

wait

#

this should be const js entity = context.entity

#

not const entity = context

tender yacht
#

I knew it was a wording thing in the rest of my script I just couldnt get past the other lines in order to debug it haha

royal sedge
#

Xd

tender yacht
#

me when I have the silly and do entity.entity.attack forgetting that entity already does context.entity and I dont need the extra one anymore

#

holy shit its all working but it has a few bugs I think I can work out

#

mostly specifics with the hitbox and the damage calculation but thats all stuff I

#

think I can manage

#

this has been a great development and extreme help thank you

royal sedge
#

??closeticket heh

tame yarrowBOT
# royal sedge ??closeticket <:heh:504730156792021002>

Please close your ticket (with </ticket close:1054771505520717835> or the button atop this thread) once you resolved your issue! This also helps others that would like to help out, as they don't have to look into this thread to check if it has been resolved by now.

Do you have any other questions regarding your issue? Feel free to ask!
Note: You should generally create a new post for unrelated issues.

tender yacht
#

teehee

dense siloBOT
#

Ticket re-opened!

dense siloBOT
tender yacht
#

Ok one final issue that I can't figure out, and its the owner part. Presumably the setOwner function allows the spell to access the players attributes to factor in the players spell power for the damage, I have gotten to a point where I do not have errors, but the spell no longer does damage upon impact, so I believe I am using the wrong thing to get the damageSource now that the owner is assigned to the ctx.entity

#
global.cosmic_cortex = (/** @type {Internal.CustomSpell$CastContext} */ ctx) => {
    let /** @type {Internal.ServerPlayer} */ player = ctx.entity;
    let /** @type {Internal.LivingEntity} */ shooter = ctx.entity
    let spellPower = ctx.getSpellLevel();
    let astralPower = ctx.getPlayerMagicData();
    let rayTrace = player.rayTrace(16)
    if(rayTrace == null) return
    let target = rayTrace.entity
    if(target == null) return
    player.tell('BOOM')
    let cosmicCortex = target.block.createEntity("kubejs:cosmic_cortex_projectile")
    cosmicCortex.setOwner(shooter)
    cosmicCortex.getProjectileBuilder().onHitEntity(context => {
        const { entity, result } = context;
            // Custom behavior when the arrow hits an entity, for example, applying potion effects
            if (result.entity.living) {
                // Create damage source
                const damageSource = getDamageSource(entity.level, "kubejs:astral_damage");
                if (entity.level.clientSide) return;
                result.entity.attack(damageSource, spellPower * 10 + 15);
                entity.remove("discarded")
            }
        })
    cosmicCortex.setPos(target.x, target.y+10, target.z)
    cosmicCortex.setMotionY(-2)
    cosmicCortex.spawn()
}
#

I believe the issue lies in this line

const damageSource = getDamageSource(entity.level, "kubejs:astral_damage");
#

since this should determine who is dealing the damage correct?

royal sedge
#

the damage source has nothing to do with the shooter

#

for testing sake you can do attack(spellPower * 10 + 15) to see if the damage source is erroring though i dont think thats the issue here

tender yacht
#

yea the damage calculation works just fine, I am now trying to factor in the players spell power attribute, presumably assigning the owner of the projectile would do that, but it now deals 0 damage onhit

#

the owner should be the LivingEntity according to ISS, however it is making the owner the ServerPlayer instead

#

i setup a log for entity.level and the owner of the projectile and it returns these values
[16:31:17] [INFO] cosmiccortex.js#47: ServerLevel[zwevadeva] [net.minecraft.server.level.ServerLevel]
[16:31:17] [INFO] cosmiccortex.js#48: ServerPlayer['Xerulatha'/258, l='ServerLevel[zwevadeva]', x=819.00, y=148.01, z=907.79] [net.minecraft.server.level.ServerPlayer]

royal sedge
#

javascript doesnt cast like that

#

so context.entity if its a serverplayer will always be ServerPlayer

#

this javadocs is only for probejs in vsc /** @type {Internal.LivingEntity} */

#

doesnt actually cast the object

tender yacht
#

oh wait let me try something facepalm

tender yacht
#

I feel like I've exhausted most of my options, atleast things I can figure out myself, perhaps squoshi would know the correct way

#

@quiet swallow hello SpellJS man, putting the finishing touches on my spell, and I am trying to make the spell able to use the players Spell Power attribute for it's damage. Assuming that setOwner is the pure thing responsible for making that happen, I have not been able to figure out a correct configuration for it to work

quiet swallow
#

i'm assuming it's using a projectile?

tender yacht
#

Yes it is

quiet swallow
#

you'll have to set the damage it does manually iirc, pretty sure either the magic data or spellLevel will scale with spell power

#

i'll have to check though

tender yacht
#

I have the damage calculation to scale with the spellLevel already, is the PlayerMagicData actually the right thing?

quiet swallow
#

oh hold on

#

spell power is completely separate from spell level, ofc

#

what if you try

ctx.getPlayerMagicData().getCastingSpell().getSpell().getSpellPower(ctx.getSpellLevel(), ctx.entity)
#

i know it's a long line but that's all i can find right now, i'll make something better for it later

tender yacht
#

strangely enough, no damage at all I'll try logging it this time

#

so does .getSpellPower part encompass all school spell powers?

quiet swallow
#

it is a method on the spell itself, which also uses its school

tender yacht
#

ah ok just checking

#

hmm, so it is working

#

[INFO] cosmiccortex.js#37: 2.299999952316284

#

not sure why the projectileDamage is zero though

quiet swallow
#

it might be some kind of issue with it being such a specific number

tender yacht
#

I also have no idea why its that number lol

#

this is what my current astral spell power is

quiet swallow
tender yacht
#

I feel like the spellLevel shouldnt be relevant atleast in my case, they probably just do the spell level and spell power stuff at the same time, but I'm not sure why the spellLevel would matter pertaining to the players spell power

#

gonna try something anyways, mightve been because I already had a let for ctx.getSpellLevel()

#

nvm wishful thinking, same number

#

gonna now test if its because of my damage formula, gonna just use the 2.299999952316284 as the only damage number

#

oh wait, it is doing damage, but the target dummy isn't registering it now for some reason

#

also, doesn't that mean that ISS calculates spell damage addition by multiplying the base damage by the level and then the spell power

#

or, I guess, multiplying spell power and spell level and then multiplying the spell damage by that amount, but that doesnt explain the weird number outputted if thats the case

#

oh I understand now, except I don't know why, the spellLevel is being outputted as 2 and then multiplied by 15%, resulting in 2.3, but I don't know why its 2 instead of 3

quiet swallow
tender yacht
#

its a smart way of doing the math, I just don't understand why the spell level is one lower than it should be, perhaps thats just how they do it for some unknown reason

#

well anyhow, everything seems to work as intended now, I'm sure I'll be back with more spell things soon enough, thank you as always