#General & Development Help

1 messages Β· Page 3 of 1

shadow helm
#

πŸ‘†
Soon as you get near OpenGL it hurts

Well that message was stuck in the ether quite a while

radiant depot
#

@hexed flint umh, i can't manage to add hexcasting to my gradle. Paucal and kff have been setup fine.
I'm using
implementation fg.deobf("at.petra-k.hexcasting:hexcasting-forge-1.19.2:0.11.0-pre-551")

the gradle throw a chain of errors so it' kinda hard to tell which is the problem, any ideas?

#

(i tried with 0.10.3 too but not result)

#

i'll rely on the cursemaven until you can help <.<

radiant depot
#

Oh, and for some reason when i use the custom staff the spellcraft mode ends immediatly

#

Since it's half kotlin i can't really debug to know why

#

oh, maybe i know why

#

yeah, got it

hexed flint
#

can you post the stack trace?

#

api being less shit is something I'm working on, probably starting and ending with kotlin yeet

radiant depot
#

it's basically just that my gradle can't find the hexcasting jar at those coords

#

i'll switch back to your maven to get you the st

#

Could not resolve at.petra-k.hexcasting:hexcasting-forge-1.19.2:0.10.3_mapped_parchment_2022.08.14-1.19.2

#

i can't upload it on paste since it's too big, lol

#

basically a chain of these

#

not useful

#

i think it's just the maven coords that are wrong

hexed flint
#

Mmm

#

try { transitive = false } after

#

and is this on forge or fabric?

#

ah, forge

#

youwanna rely on at.petra-k.hexcasting:hexcasting-common-1.19.2:whatever

#

not forge

radiant depot
#

Oh

#

What's the whatever tho

#

The version?

#

Oh, works now

radiant depot
#

i might just use that as compile and curse as runtime

#

it's good enough for me

hexed flint
#

Yeah

#

common contains no code

#

or, no entrypoints

#

you want common at compileOnly and forge at runtimeOnly

radiant depot
#

oh,didn't expect that

hexed flint
#

common is all the API and actual inner workings, forge is a thin wrapper that tells FML that hex is a mod, how to set it up, and provides impls for xplat stuff

#

it's like, imagine you're making a library for some app with several front-ends

#

you can use it over terminal, or with a GUI, or with a web

radiant depot
#

is that multiloader?

hexed flint
#

Hex is

#

when making the addon, you just want the API for the internals

#

but when testing it, you also want to bring in the frontend so you can actually use it

radiant depot
#

well, the forge doesn't work from maven for reason

hexed flint
#

and i only upload fabric/forge to curse

radiant depot
#

but i'm good with pulling from curse

hexed flint
#

Did you try putting { transitive = false } after it

#

looks like it's trying to find JEI but you haven't given it in the maven repo where it could find it

radiant depot
#

ok, it worked

#

i forgot to try that

bright shore
#

Could an addon add new colors to existing familiars?

radiant depot
#

Yes

#

I do it with the starbuncle raccoon

#

The only problem is how to set it

mossy hollow
#

I have finally got ArsNouveauExampleAddon working with archloom πŸ˜„

#

now I can finally start exploring addon development

zealous zenith
#

archloom? thinkies

radiant depot
#

I have no idea on how the datagen behaves with arch/loom

#

Probably it doesn't

mossy hollow
#

It works fine

#

out of the box

mossy hollow
radiant depot
#

Well, you are just on forge afterall. No risk of fabric clashes

mossy hollow
#

Indeed

zealous zenith
#

forgegradle is horrifying

#

cannot argue with that

#

the addon project is still out dated, might want to yoink configs from ars-caelum

radiant depot
#

I usually keep them updated too, but caelum is maybe cleaner and on latest

mossy hollow
#

I've updated a bunch of them myself while cleaning up the build.gradle

zealous zenith
#

the datagen is also a tad confusing since it works a little differently

#

mostly just the patchouli stuff

radiant depot
#

Also double check the datagen, i forgot to replace few "ars_elemental" strings

#

you can just replace that with root or whatever that variable is refractored to point to your modid

mossy hollow
#

for anyone interested

zealous zenith
mossy hollow
#

Ah I was searching for caelum

mossy hollow
#

Alright, I'm making progress on my first addon, I have a scribeable ring that will auto-cast with a configurable cooldown. The goal of this is to work primarily with spells that apply potion effects, which I'd like to expand later, for example heal + extend time actually gives regeneration, etc.

#

My goal with this addon is to produce magical scribeable items that will augment or amplify specific types of magic, to essentially allow people to create custom magical items

shadow helm
radiant depot
#

Well, as long as it's not a regen II+ it can be balanced

#

But asap can you get over regen II everything falls apart

mossy hollow
#

I understand that entirely, and I'm considering the implications of potions, but I also find that a lot of players don't care for the idea of brewing potions because of the amount of effort required to create a consumable

#

Especially as the rest of magic is very permanent, once you have a glyph you can always use it etc.

#

I'm not sure if I want the ring to specifically just auto-cast spells or whether I want it to augment spells to specifically make them function more like effects

#

So heal would only change to regen while inside the ring, and would restrict amplifies

#

Or do I just implement the effects of heal + extend time to be regen

shadow helm
#

Tying it to the auto cast ring could be cool if there's other worthwhile alternatives so it generates player agency and choice again

#

like a ring that gives you permanent autocast regen or permanent autocast glide/fireworks (getting that for free if it's a usual spell item actually)

#

as long as the pack doesn't add like 10 ring slots it could be a cool way to have choices

radiant depot
#

If want to dive on the wearable ring effects, you might look into contingency activation

shadow helm
radiant depot
#

Since it's something people want, but we other devs never got to try

#

If you are not familiar with the old AM/Psi contingency, it was basically a suspended spell that only triggered when something happens

shadow helm
#

or decided against it for various reasons

radiant depot
#

A bit like a more specific reactive

shadow helm
mossy hollow
#

Ah yeah reaction based activation

radiant depot
#

"Cast this spell only if the wearer is on fire"

#

"Cast this spell every time the wearer heals"

shadow helm
#

"Cast this spell every time the wearer is falling 5 or more blocks"

radiant depot
#

It's interesting, but easily lead to abuse if not balanced

mossy hollow
radiant depot
#

That's an easy option too

shadow helm
#

You always could. Alex got an example in Elemental with the elemental Bangles

radiant depot
#

Or even more similar, #1042887307021266954

mossy hollow
#

Yeah the reactive casting would be cool, but I'm also thinking of you can have spell activate as a reaction generally, why would you need the curio

#

Or perhaps they're only valid for scribing on the curio? In which case, how do I handle exposing those glyphs without having them be castable

lots to think about

radiant depot
#

Oh, I was not meaning contingency glyphs

#

But curios with the different activation

#

The first one you mentioned would be simply a cyclic activation, on a timer

mossy hollow
#

Ooh, that sounds interestign actually

#

I like that concept

#

Also, can I get thoughts on the name, I'm considering either Ars Artifice, or Ars Apparatus

shadow helm
#

I like both, but Artifice might get confused with Mana & Artifice.
Artifact, maybe?

mossy hollow
#

Ah potentially, I was swaying towards Artifice because the concept made me think of what I wish D&D Artificers were

#

and also want to stick with the latin theme from the rest of the mods/addons

shadow helm
#

Understandable, but you did that with Ars already.
Nouveau's French, Omega's Greek, Instrumentum is Latin, Elemental is English, so is Arsenal. I think you're free to choose your language for the second part 😁
At least that's the "Convention" that formed itself.
And then there's Too Many Glyphs cause Derringer is anti-establishment πŸ˜‰

mossy hollow
#

I mean Ars is latin, but included on everything, but Caelum, Instrumentum and Creo is Latin too

#

and Industria πŸ˜„

shadow helm
#

That's true. Just wanted to say that there's other options if you wanted to keep the Artificing-Meaning but willing to change the language a little ^^

radiant depot
#

And StarbuncleMania is just based on mass exploiting a cute mascott for profit

Totally not inspired by The Pokemon Company

mossy hollow
#

Understandable, I'll try look at some synonyms for Artifice

radiant depot
#

But hey, Scalaes is Latin too

mossy hollow
#

that's true

#

I want to stick with Latin

radiant depot
#

It's just cooler for magic, I guess

mossy hollow
#

Indeed

shadow helm
#

Ferrarius is the Iron Forger.
Depending on how much smithing you plan to include in the Artifice part, that might be an option?

radiant depot
#

Artifice is derived from Artificium anyway

mossy hollow
#

Not sure on smithing because I can't think of an existing mechanic to handle that side of things

shadow helm
#

Anvil Crafting feels very lacking, yeah

mossy hollow
#

Artificium is a little long winded πŸ˜…

radiant depot
#

Indeed too long to chain to "Ars" nicely

mossy hollow
#

Yeah it could be cool to add some anvil crafting magic mechanic, but that's a whole other thing

shadow helm
#

Invent and Inventor are apparently the exact same thing between english and Latin so that's not really satisfying either

radiant depot
#

Too bad Arsifacts doesn't sound that good

mossy hollow
#

There's Forge -> Incudo, Ars Incudo could be cool

#

like to forge an item

#

Or Ars Cudo

radiant depot
#

It's just usually used as elementum or elementi when referring to object/s

shadow helm
#

So kind of the same thing as with Inventor

mossy hollow
#

Ars Peritia - skill, expertise, knowledge, etc.

#

So my top 3 are Ars Peritia, Ars Incudo and Ars Artifice

#

my favourite is Artifice, but no idea if that'd be confusing

radiant depot
#

I don't think so

#

We usually refer to the other mod as M&A

#

Not just artifice

mossy hollow
#

Alright, you've sold me on it Alex, I'm making AA

radiant depot
#

Or idk, Mithion mod, or Ars Magica 3

shadow helm
radiant depot
#

As long as you make the icon a clear reference to Ars it should be fine?

mossy hollow
#

Yeah that'd be the goal

radiant depot
#

The search for Ars and addons usually start with Ars

mossy hollow
#

I have to find an artist because I'm allergic to programmer art

shadow helm
#

https://www.deviantart.com/supremacyrain
Rain's done some commissions for Goo & Bailey for the mod (and for me as well, the imbuement stickers are from her).
She never did pixelart before but last time I talked to her she mentioned being open to give it a try

signal kiln
#

IntellIj's terminal makes me physically ill. πŸ™‚ It keeps glitching out.

shadow helm
#

That's a new one, it's been pretty stable since forever for me since forever
Guessing you're on the newest community edition?

signal kiln
#

I'm actually probably pretty behind. I've had it installed on this laptop for years. πŸ˜… Should have thought of that.

#

I'll update. πŸ™‚

bright shore
#

ok so dumb question but I forget: light level of a block can be based on the blockstate, right?

zealous zenith
#

it is only based on the blockstate

radiant depot
#

redstone lamp

bright shore
#

lol I forgot that existed

#

nice

quartz stump
#

what's a good IDE for working on an add-on mod?

#

I'm used to working in C# with VS so idk what's a good dev environment for minecraft modding lmao

zealous zenith
#

IntelliJ is pretty much the only one I think you could use

radiant depot
#

Eclipse is very borderline

#

Thank Gradle for making it hard to other IDEs

calm cove
#

(hopefully this is the right channel)

#

Does Ars have the possibilities of effecting and/or working with mods like Ad Astral?

shadow helm
#

Theoretically probably maybe, but compats are mostly put into their own addons

calm cove
#

I was thinking of either magic with a space element, threads to help in space, or glyphs to assist in space, and just wanted to confirm that it was at least possible

radiant depot
#

And you should be more specific on what the compat would be

calm cove
#

I also wasn't sure if such an idea would fit better in an already named add-on, like Industria, or a different one entirely

radiant depot
#

Referring to Ad Astra stuff is possible, but for few things are probably out of reach? I haven't checked that mod yet

#

Two of the devs got into FC last week, so i have a way to talk to them if small things on their side are needed

pallid rapids
#

I could see stuff like Threads made out of the Ad Astra armor materials to give you space suit qualities in your mage armor

calm cove
#

I could see smaller stuff like that fitting into, Industria (if I understood that add-on properly), but if there was enough for a complete space mage mod, then what would it need, but Alexthw answered that mostly

radiant depot
#

Ars Astra doesn't sound bad

quartz stump
#

Is there an easy way to just grant a flat amount of current mana?

#

I altering @sleek ibex's tetra-ars compatibility thing to make Source Leech just leech a flat amount of mana, rather than grant Mana Regen, but I am trying to find whether or not I can add current mana easily

#

It is my first time using KubeJS and I lack a console to poke around with so it's hard for me to see what i have access to or not

radiant depot
#

if Tetra allows you to give an attribute modifier to tools it's easy, or at least it should

#

if there's something that boost your speed while held for example

#

same logic of that would be applied to ars attribute for mana boost

sleek ibex
#

wait, you're talking about max mana, right?

#

I believe Vyk is talking about current mana (like a single tick of burst regen)

shadow helm
#

I think Vyk doesn't want to talk max mana, instead they want to increase current mana
Ah damn, typed to slow.

quartz stump
#

yeah i mean current mana

#

I also want to eventually bring forth the idea i put in #1074698167855091742

#

Or at least figure out some way to make it work but that's for later

radiant depot
#

oh that's not easy unless you can call to java code

sleek ibex
#

you can

quartz stump
#

KubeJS lets you iirc

sleek ibex
#

Kube has Java.loadClass() to get a dynamically generated wrapper

quartz stump
#

My idea is to subscribe to the hurt event and call code there

shadow helm
sleek ibex
#

yeah, that was my take on it too

#

technically possible, but ugly

radiant depot
#

import com.hollingsworth.arsnouveau.common.capability.CapabilityRegistry;

CapabilityRegistry.getMana(player).ifPresent(mana -> mana.addMana(AMOUNT));

quartz stump
#

My idea was to basically make a Tetra effect which increases the chance of (and efficiency of) the existing Reactive enchantment

#

you still put reactive on the weapon as normal

#

but you can slot in a gem socket to the weapon to make Reactive use less mana or proc more often

sleek ibex
#

also yeah, what alex put is totally usable to do a single static pull of mana

quartz stump
#

I would be leaning onto ars own existing methods for proccing Reactive

radiant depot
#
ReactiveCaster reactiveCaster = new ReactiveCaster(itemstack);
reactiveCaster.castSpell(player.getCommandSenderWorld(), player, InteractionHand.OFF_HAND, null);
#

this trigger reactive from the itemstack

quartz stump
#

gotcha

shadow helm
#

you can then cheat by adding in some mana via the call shared before to make it cheaper. Easier to explain than that you're actually refunding a bit anyways πŸ˜„

sleek ibex
#

actually, perhaps the coolest thing about doing the mana leech properly is that it means you can also make it remove that much mana from the target

#

make it a proper osmose effect

#

actually... do monsters have mana capability? Osmose would be a cool glyph too

pallid rapids
#

mobs don't have mana

shadow helm
pallid rapids
#

so it would only be for PVP

#

which tbh most of us aren't super interested in, haha

zealous zenith
#

Monsters get to cast for free

#

Like enigmaticas mobs with enchanters gear

quartz stump
#

source leech works heck yeah

#

It now restores 5 Mana/level flat

#

I'll tweak numbers later

#

now let's see if I can get this working with throwables too

sleek ibex
#

shouldn't it automatically? I'd think a throwable still registers the event source as the player that threw it

quartz stump
#

Yeah i wanted to confirm that

#

and it does

#

so that's good

sleek ibex
#

yeah, should work with bows too

quartz stump
#

well that was somewhat easy

#

I can get it to proc Reactive on command now

#

Now I have to alter Ars Noveau's end

#

I need to see if I can have it allow you to inscribe spell parchments into modular items without the need for the reactive enchantment Thonk

calm cove
#

also, I would suggest testing to make sure it leaves regular use of Reactive unchanged, but that could just be from wanting to be overly careful

quartz stump
#

oh absolutely!

#

I plan on making this a sort of alternate option for Tetra weapons

#

That will likely be locked to weapons made of Source Gems (which do not have that great stats) or weapons with the Source Gem socket in them

quartz stump
#

my current idea is to create a module which can be applied to weapons, the module uses a Source Gem Socket

#

resulting in a reactive-like effect

#

I am now just trying to figure out how to give the item the NBT data required

sleek ibex
#

so that's the part I said would be tricky

#

I believe you need tetra modular items to implement IScribeable

#

you could try to get creative and do something like a shapeless recipe with a spell parchment and a modular item that has a source socket that merges the nbt

#

but it would be a bit messy

#

actually, the cleanest way to do it might be that the module automatically applies the enchantment

quartz stump
#

my idea was to just somehow donate a Spell Parchment's NBT data to the modular weapon

#

because if I can get the NBT data from a partchment scroll into the weapon

#

I can just execute the spell

#

even if it doesn't have the actual reactive spell

radiant depot
#

Well, that's doable

quartz stump
#

Yeah I just gotta figure out if Tetra allows me to pass NBT data to a modular weapon

radiant depot
#

To copy over, do something similar to this

#

Without the extra parts

#

And by using the parchment as the "heldStack"

quartz stump
#

It's not a lot but

#

I got this working :)

zealous zenith
#

Nice

quartz stump
#

Core functionality is working

#

I can inscribe a modular weapon

#

and it casts the spell inscribed onto it

#

next goal: figure out of if I can set the 'target' of the spell

#

Force the spell to have a form of self centered on the target of the strike

#

oh also figure out tooltip stuff

#

since right now you can't see what spell you have

quartz stump
#

Hmm

#

I am having a hard time finding a way to set the target as the starting point of the spell while still having the caster be the one paying the cost

#

If i set the player as the caster, it all originates from them

#

and while that works for touch-based spells

#

i want to also support throwable modular weapons

zealous zenith
#

You may need your own custom spell resolver

quartz stump
#

Hmmm

radiant depot
#

The weapon doesn't store the thrower?

#

What's the problem?

quartz stump
#

The issue is that while yes, it will cast a spell

#

i wont quite work with thrown weapons if your form is touch

zealous zenith
#

Why not?

quartz stump
#

you'd be too far way

zealous zenith
#

Touch just takes a hit vec

radiant depot
#

Oh, you're using the full reactive functionality

#

Not like the sword

#

Let me check how the spell horn was working

zealous zenith
#

The book and other tools are what dictate how the raytrace result is created, you can give the form anything. The actual forms don't really care how far away the user is

#

So you can cast a touch spell a million blocks away, just give it the block or entity trace result

quartz stump
#

hmmm

zealous zenith
#

on the entity hit, just use the spell resolver to cast the spell with the hit target, mana should expend if its successful

quartz stump
#

So I should instance a SpellResolver then?

zealous zenith
#

its really hard to know since I dont see your code, but I presume you have an entity that is thrown from a tetra weapon, and the weapon is enchanted or has some tag?

quartz stump
#

basically I am working within the hurt forge event

#

I have access to the spell, the caster and the target being struck

#

what I did to start was just declare a new ReactiveCaster instance using the tag data placed in the modular weapon

#

re-creating the Reactive trait

#

Then I just ran

reactive.castSpell(source.getCommandSenderWorld(), source, InteractionHand.OFF_HAND, null);```
#

which basically parrots 1:1 what Reactive does

#

but without the bonus glyphs

#

Ideally, I want the target struck to be the starting point of the spell

#

So whether you struck in melee or with at throwable weapon, the spell hits your target

#

my cast code was literally just

let reactive = new ReactiveCaster(hand);
reactive.castSpell(source.getCommandSenderWorld(), source, InteractionHand.OFF_HAND, null);
radiant depot
#

Do you allow projectiles too?

#

Or self effects?

quartz stump
#

yeah currently it allows those

radiant depot
#

If not, it would be easier to swap to simply resolve the effects directly on the enemy

#

Like the sword does

quartz stump
#

I tried swapping the caster to be the enemy and it kinda works which was funny

#

but it didn't use the caster's mana

quartz stump
#

I'm looking at the sword code and I can't quite figure out where this switch is happening Thonk

#

Never-fucking-mind

#

I think i got it

#

I have a strange issue now tho

#

the weapon uses basically all mana Thonk

#

I think what is happening is that the spell is being cast repeatedly?

radiant depot
#

possibly

#

first by the weapon throw

#

then by the spell

#

since you're using the damage event

quartz stump
#

strangely though

#

I am checking that the source is a player

#

so wouldn't it only ever trigger once?

#
    let source = event.source.getActual();
    let target = event.entity;
    
    if ( source && source.isPlayer()) {
        let main_hand = source.mainHandItem;
        let off_hand = source.offHandItem;
        for ( let hand of [main_hand, off_hand] ) {

            if ( hand && hand.getItem() instanceof ModularItem ) {

                let sourceLeechLevel = hand.getItem().getEffectLevel(hand, ItemEffect.get("source_leech"));
                let spellstriker = hand.getItem().getEffectLevel(hand, ItemEffect.get("spellstrike"));
                
                if (sourceLeechLevel > 0) {
                        ArsCapability.getMana(source).ifPresent(mana => mana.addMana(5 * sourceLeechLevel));
                }//if player is wielding a source leech item
                
                if (spellstriker > 0){
                    let reactive = new ReactiveCaster(hand);
                    let caster = new PlayerCaster(source);
                    let spellContext = new SpellContext(source.getCommandSenderWorld(), reactive.modifySpellBeforeCasting(source.getCommandSenderWorld(), source, InteractionHand.MAIN_HAND, reactive.getSpell()), source, caster);
                    let resolver = new SpellResolver(spellContext);
                    resolver.onCastOnEntity(hand, target, InteractionHand.MAIN_HAND);
                }//if player is wielding a spellstriker weapon
                
            }//if the weapon is a modular weapon
        }
    }//if damage was done by a player
#

that's the whole logic right there

radiant depot
#

try get DirectSource or smth

quartz stump
#

like from the event?

radiant depot
#

event.getSource().getDirectEntity()

#

but maybe it's not the right track

#

the source should be player anyway, since the player is the caster of the spell

#

so either damaging with the weapon or the spell, the damage still originates from the caster

#

getDirectEntity should give you the player when damage is dealt directly with weapon in hand or via spell, and the throwable entity when the weapon is trown and it hits something

quartz stump
#

the thing that confuses me the most is that

#

event.source.getActual() returns a ServerPlayer instance

#

i don't think it can get more direct than that

#

let me see if it's just an issue with reloading or smth

#

yeah even after a relaunch it persists

#

maybe it's because it is resolving the hit result multiple times?

radiant depot
#

there is surely a way to fix it, but not sure how from kube

quartz stump
#

how would it be solved in Java itself?

radiant depot
#

I'm just too tired to think about it, maybe you have a way to mark the entity or the weapon or the caster

#

So it won't proc twice

#

You need a way to reset that mark too tho

quartz stump
#

Hmmm

#

it appears to be specifically be an issue with the casting code too

#

commenting out that code causes the code to only execute once per hit as intended

quartz stump
#

I think I know what may be happening

#

and if it's true

#

it's pretty funny

#

basically, I think that what's going on is that we're getting an infinite loop

#

hurt triggers a damage effect which triggers hurt again and so on and so forth

quartz stump
#

I will try to add a simple attribute or NBT tag to allow me to just

#

add a brief cooldown to the hook

#

it should prevent infinite loops

mossy hollow
#

Do 2-wide blocks require a custom block renderer? If yes does that mean they require a tile entity? I'm trying to create my own table block, but I can't get textures to display

radiant depot
#

Either split the model into two blocks, like a door

#

Or have a tile entity renderer

mossy hollow
#

Ah doors have models based on the blockstates, that will work, thank you

radiant depot
#

Block renderers are always based on blockstates

#

Otherwise it's the tile renderer, like for most of ars machines

mossy hollow
#

Yeah but it doesn't use a custom renderer, I checked beds which do

#

was trying to find a way without one

quartz stump
#

Y'all wanna see something cool?

#

I'll change how inscribing works to instead be inscibed like you inscribe Enchanter's items

#

aka you put the item on the table then Shift-Right Click with the tome

shadow helm
#

That's indeed pretty cool

#

Nice!

radiant depot
#

Oh lol, you reversed the scribing

#

Still functional enough

quartz stump
#

Yeah lmao I'll fix that now

#

Since now i know I can just create SpellCaster instances out of anything with the right NBT data

#

I can just transfer the metadata from the spellbook to the weapon

#

and then let Ars parse it

#

Once this is finished I will share it maybe in #1019655289873641555?

quartz stump
#

Holy shit

#

So uhhh

#

turns out

#

doing this was miles easier than i thought?

#

Wanna see the extremely advanced and complex code needed to turn ANY ITEM into a spellcasting item that holds spellcasting data on it?

#

ok ready, this will be saucy

#
                    let caster = CasterUtil.getCaster(item); // Get the Spellcaster out of the book
                    let spell = caster.getSpell(); // Get the current Spell
                    let newCaster = new SpellCaster(tableItem); // Instance a new Spellcaster out of the destination item
                    newCaster.setColor(caster.getColor()); 
                    newCaster.setFlavorText(caster.getFlavorText());
                    newCaster.setSpellName(caster.getSpellName());
                    newCaster.setSound(caster.getCurrentSound());
                    newCaster.setSpell(spell); // Set the Spell on the new spellcaster 
                    PortUtil.sendMessageNoSpam(player, Component.translate("ars_nouveau.set_spell")); // Notify the player
#

This will add spellcasting NBT to any item

radiant depot
#

Well, tbf the new caster tome datapack support basically allow any item to have caster data

#

well, to generate as one

quartz stump
#

yeah im just amazed at how easy it was

#

You literally just create a new spellcaster instance and set as pell

#

and bam

quartz stump
#

And infinite casting bug resolved too!

#

I created a MobEffect which lasts for all of 10 ticks which prevents chain casting

#

though something interesting i noticed

#

adding Harm to a weapon actually lowers the weapon's damage

#

i wonder if this is because it bundles the weapon and spell damage into one instance, and since Harm is coded in as normal damage it ends up overwriting the weapon's damage

#

or maybe i'm just seeing things

#

I'm using the test dummy from the TargetDummy to test the damage

#

and when i put any damage effect on the weapon, the only damage that happens is the spell's damage

radiant depot
#

welcome to minecraft iframes

quartz stump
#

oh right! I frames

radiant depot
#

only the highest damage applies during those

quartz stump
#

hmmm

#

I wonder if there's any way I can 'delay' the spell damage

radiant depot
#

The enchanter sword have the same issue

quartz stump
#

Oh is that a current issue with the sword?

radiant depot
#

and we simply suggest to start with a delay if you want a damage effect as first glyph

quartz stump
#

the big question is

#

Can I even append a Delay as the first glyph?

radiant depot
#

yeah

quartz stump
#

and does Delay work as the first glyph? before forms are declared?

radiant depot
#

java list.add(x, i) adds x in the i-th spot and shift the rest to right

#

so you should be able to take the spell recipe, do .add(Delay, 1) and it will append right after the form

#

(not actual code)

quartz stump
#

Hmm now the delay cause the infinite cast to happen again

#

Maybe I can jack up the 'spellstrike fatigue' to last longer and make it a deliberate game mechanic

#

the counter-cost of having a cheaper enchanter's weapon

#

How many ticks of delay does Delay add?

#

and by how much is it altered if you add Duration Down?

pallid rapids
#

I think Delay is 20 ticks? So one second. Duration Down I believe cuts it in half, and you need at least 11 ticks to bypass iframes

#

as of recent fixes at least

#

if you're in an old version then there was a bug that meant that Duration Down was always being applied

quartz stump
#

gotcha

pallid rapids
#

also just to be super clear about iframes in minecraft, they will discard any damage that is lesser than the initial hit, but if you get hit by an attack that deals more damage than the first hit, you will take the difference between the two hits as damage.

quartz stump
#

Just to be clear

#

currently

#

enchanter's sword does nothing to prevent I-frames?

pallid rapids
#

nope. I always suggest that people start their spell with a delay if they are using damage spells on their sword

quartz stump
#

Hmmm

#

I wonder if I can fix that internally lmao

#

If I can delay my code 11-ticks after the Hurt event

#

I could actually just make the spell trigger on time

#

which would be neat to have

pallid rapids
#

mmm. See, sometimes I want something to happen immediately though

#

I see it as a constraint that the player has to work around, personally

quartz stump
#

That is true

bright shore
#

Or you could hack the sword to remove I-frames after doing damage but that seems OP

zealous zenith
#

Is this all a kubejs thing?

pallid rapids
#

yeah I can see that having unintended consequences

quartz stump
#

This is all being implemented thru KubeJS yeah

zealous zenith
#

Wild

#

A mad man

bright shore
quartz stump
#

If the enchanter's sword doesn't have I-frame work-around i'm less inclined to fix it myself

#

call it a feature not a bug or smth

pallid rapids
#

I see it as a learning opportunity for players, tbh

#

to learn how i-frames work

#

and think their own way around the problem

quartz stump
#

I just gotta add my anti-infinite-cast workaround and we good then

#

The idea is that you get Spellstrike Fatigue for 10 ticks + 20 more ticks per Delay Glyph

#

to ensure i don't accidentally infinite cast again RynnLaugh

pallid rapids
#

just like when people come here asking why projectile harm harm harm harm harm harm isn't doing more damage than projectile harm

quartz stump
#

I still want to just not deal with this spellstrike fatigue thing if i can

#

Does anyone happen to know if Minecraft records where the source of damage comes from?

#

And if there is any way for me to tell that the Hurt event is triggering off a spell lmao RynnLaugh

pallid rapids
#

I mean, the Enchanter's Sword doesn't have an issue with that

zealous zenith
#

Minecraft damage sources are pretty barebones

#

There is a spell damage event

radiant depot
#

Yeah, but I don't know if kube is limited to supported events or work with any

#

If it need support, we can investigate on some kind of ArsJs

zealous zenith
#

I believe it can listen to modded events too

#

not usre

quartz stump
#

huh turns out even the slightest bit of delay is enough?

#

oh wait nvm having enough of a delay still triggers it dogkek

#

As in triggers the infinite loop

radiant depot
#

21 of cast sickness?

#

well, still a problem if delay is augmented kekw

#

this is not the solution

mossy hollow
#

What's the event you're triggering on?

quartz stump
#

It's triggering off Hurt

#

so it creates this cyclic loop of hurt triggering hurt again

#

I gotta figure out how to read whether the source of the damage is from a spell or not

mossy hollow
#

And the effect is you want to increase the damage once per spell?

quartz stump
#

I'm re-creating Enchanter's Sword for Tetra weapons

#

Aka cast spell on target when hit

#

So far it works

#

but the code triggers on EntityEvents.Hurt

#

which means that when your spell is cast

#

if it hurts the arget

#

it triggers the cast again

#

and it just loops

#

So i gotta figure out a way to stop that lmao

mossy hollow
#

Can you check if the damage event is magic damage? Swords shouldn't be, but spells should be I think

radiant depot
#

most spells aren't

mossy hollow
#

rip

quartz stump
#

my current work-around is to inflict a status condition which lasts for a duration of time based on the number of delays in your spell

pallid rapids
#

what way does the enchanter's sword trigger? Could you copy that?

quartz stump
#

as long as that debuff exists, the cast can't happen

quartz stump
pallid rapids
#

ah

quartz stump
#
EntityEvents.hurt(event => {
    let source = event.source.getActual();
    let target = event.entity;   
    if ( source && source.isPlayer()) {
        let main_hand = source.mainHandItem;
        let off_hand = source.offHandItem;      
        for ( let hand of [main_hand, off_hand] ) {
            if ( hand && hand.getItem() instanceof ModularItem ) {           
                let sourceLeechLevel = hand.getItem().getEffectLevel(hand, ItemEffect.get("source_leech"));
                let spellstriker = hand.getItem().getEffectLevel(hand, ItemEffect.get("spellstrike"));      
                if (sourceLeechLevel > 0) {
                        console.info("Instance of Source Leech!");
                        ArsCapability.getMana(source).ifPresent(mana => mana.addMana(5 * sourceLeechLevel));
                }//if player is wielding a source leech item
                if (spellstriker > 0 && !source.potionEffects.isActive('tetra:spellstrike_fatigue')) {
                    console.info("Instance of Spellstriker!");
                    let reactive = new SpellCaster(hand);
                    let caster = new PlayerCaster(source);
                    let spell = reactive.modifySpellBeforeCasting(source.getCommandSenderWorld(), source, InteractionHand.MAIN_HAND, reactive.getSpell());
                    source.addEffect(new MobEffectInstance('tetra:spellstrike_fatigue', 25)); // Anti-infinite-loop measures.
                    let spellContext = new SpellContext(source.getCommandSenderWorld(), spell, source, caster);
                    let resolver = new SpellResolver(spellContext);
                    resolver.onCastOnEntity(hand, target, InteractionHand.MAIN_HAND);
                }//if player is wielding a spellstriker weapon, cast a spell.
            }//if the weapon is a modular weapon
        }
    }//if damage was done by a player
})```
#

entire event for those curious

#

I wish there was a Hit event i could target man

radiant depot
#

"Hit" as in?

#

There are few events

mossy hollow
#

KubeJS only has hurt afaik

quartz stump
#

Yeah can only really see a Hurt event

mossy hollow
#

Could try this

ForgeEvents.onEvent('net.minecraftforge.event.entity.living.LivingAttackEvent', (event) => {
  ...
});
radiant depot
#

can you mark the entity instead of the caster?

radiant depot
#

like, if it have an effect on it, the spell won't resolve

quartz stump
mossy hollow
#

That just shifts the issue elsewhere rather than fixing it

#

Huh maybe they changed it

radiant depot
#

right, potions and delay don't work together

#

since we base off the hurt event

quartz stump
#

I can increase the effect based on delay glyphs!

mossy hollow
quartz stump
#

ah so they're a Startup script?

mossy hollow
#

Yeah I think so

quartz stump
#

ok let's give that a try

#

Ok we're getting different crashes now let's go

#

progress

#

I forgot to load a class lmao

#

let's try that again

quartz stump
#

literally working through this one crash at a time lmao

#

I forgot that the forge event runs every time and i only want it to happen on the server so i gotta check that i'm running on the server lmao

quartz stump
#

Seems that spellcasting counts as a LivingAttackEvent Thonk

mossy hollow
#

Huh, maybe take a look at other forge events then

quartz stump
#

Yeah looking at events, I don't think I can avoid the issue of the damage event always linking back to the player directly

#

and thus creating an infinite loop of some sorts

#

Unless I can somehow find a way to identify or flag the spell as it not originating from the player

mossy hollow
#

You can use the events from ars

quartz stump
#

Hmmm

#

perhaps

#

This may be an idea but

#

Ars has events that trigger after a spell had done and truly resolved its effects right?

#

What if I add a singular flag on the player which is removed on this event?

mossy hollow
#

Could work

#

Would cause the weapon to not buff any attacks that happen between the time of the first attack and the spell resolution

quartz stump
#

yeah

#

It would also mean any damage that happens during the spell wont proc the spell again

#

sine it has not yet resolved

#

would the event be
com.hollingsworth.arsnouveau.api.event.SpellResolveEvent.Post?

#

like that?

#

I have not used forge events before so

mossy hollow
#

I think so yeah

quartz stump
#

it was com.hollingsworth.arsnouveau.api.event.SpellResolveEvent$Post

#

rather than .post

#

java is dumb

#

ok it works for instant spells

#

but now delayed spells still trigger an infinite loop lmao

#

oh I have an idea lmao

quartz stump
#

hmmm my crazy idea is having issues

#

I was going to hook onto the DelayedSpelEvent, which has the duration of how many ticks a spell is delayed for

#

I was going to basically do this:
Player attacks > Spellstriker variable goes up by 3 > If there are delayed spell effects, add to this number by the duration of the delay > Every tick lower variable by 1

#

it's a cooldown but it's far more precise and less janky

#

it means you always have a delay between spellstrikes equal to 3 + the delay of your runes

#

But it seems that DelayedSpellEvent is not a true event

#

it's some internal event interface

sleek ibex
#

Doing it as a debuff/cooldown seems much less flexible to me than fishing out details about the source

quartz stump
#

The issue is that the root of the problem is that EntityEvents.Hurt is extremely blind as to what hurt the entity

#

I haven't found a way to differentiate between the player's initial swing with the weapon vs the aftermath spell cast which technically happens on the same tick

#

but then the spell ticks the weapon effect again

sleek ibex
#

does source.isMagic() not fit your needs?

#

unless you've got some other enchantment adding magic damage to the swing

quartz stump
#

nope, apparently Ars spells don't all use magic as its damage

sleek ibex
#

I'd think ars is coded as magic typed, but the swing is not

#

ah

quartz stump
#

some do but most don't

sleek ibex
#

well then can you still fish it out of .getMsgId() and do some ugly string pattern matching?

quartz stump
#

i'm gonna do some aggressive data search right now and just print the .toString() of the damagesources

#

and comb for any possible differences

#

surely there has to be SOMETHING in here i can use

zealous zenith
#

just curious what the motivation for using kubejs instead of a small addon is

sleek ibex
#

I imagine it's familiarity with JS vs Java

quartz stump
#

That and because I already got this stuff going

#

I have not worked on Forge since uhhh

#

like 2016?

zealous zenith
#

you seem fully competent to make a forge mod but more power to you haha

bright shore
#

I agreee with Bailey it's probably easier at this point to make an addon

sleek ibex
#

honestly, I end up gravitating toward kube scripts just because the minecraft moding toolchain is abysmal

#

but yeah, this is rapidly entering "Java is like half the effort" territory

zealous zenith
#

we have an example addon project, while slightly out of date, gets you most of the way there

sleek ibex
#

just because of strong typing and being able to see what methods are available on an object

bright shore
#

and I doubt kubejs lets you use mixins lol

#

that would be... beyond insanity

sleek ibex
#

yeah, inheritance and mixins are the big hard lines for KubeJS

bright shore
#

I doubt forge even allows you to create ANYTHING that uses json to create those things

#

it could be done I believe, you'd just need a new loader

#

no?

zealous zenith
#

kubejs executes real java code

#

it could probably do whatever it wants with enough hackery

quartz stump
#

I think the issue would still happen even in Java because the issue is not the language at this rate

bright shore
quartz stump
#

It's how the spell is being cast

bright shore
#

you can'd do that in Kubejs

quartz stump
#

Basically, unless using Java allows me to quite literally add an entire new inheritance to Tetra weapons, it will work the same as with KubeJS

zealous zenith
#

it does let you do that

#

lol

bright shore
#

nor can I imagine that ever bieng possible unless the JVM lets you do more with the class loader than I thought

sleek ibex
#

the power of mixins!

quartz stump
zealous zenith
#

mixins are all powerful

bright shore
#

well, ok, java doesn't let you edit a class

quartz stump
#

As a C# nerd what you just said sounds like absolute black magic lmao

bright shore
#

but mixins are smart as hell

#

best thing ever

sleek ibex
#

welcome to the jank of post-OOP OOP

bright shore
#

they load a fake class instead with the modifications they want

zealous zenith
#

I think you are also kneecapping yourself by not having the mod in an IDE in front of you that you can debug through

bright shore
#

that too

sleek ibex
#

pfft, I've switched my students over to coding in sublime text this semester

quartz stump
#

I have been using Notepad++ to edit the js files RynnLaugh

zealous zenith
#

I dont think what you are trying to do needs a mixin at all, but we dont know much about kubejs to help you make a proper addon

sleek ibex
#

IDEs are for the WEAK!

quartz stump
#

I'm fueled by nothing but ADHD hyperfixation into getting this working

#

that and complete fear of having to look at forge documentation

sleek ibex
#

forge documentation > no documentation, which is what you get with kube

bright shore
#

ok but seriously tangent but is it possible to swap out the class loader at runtime?
And how early can you get forge to run a part of your mod? mixin plugins already happen pretty early, no?

zealous zenith
#

forge docs are worthless, embrace other mods

bright shore
#

I wonder....

zealous zenith
#

every mod is just botania codebase reskinned

sleek ibex
#

yeah, honestly, reading code is the best documentation for minecraft modding

#

especially for version upgrades

#

"well how did pipes get fixed in the other dozen pipes mods?"

bright shore
#

wait no can a mixin plugin just do what I'm thinking of lol

#

"as

  • well as an opportunity to apply their own transformations to the target class
  • pre- and post-transform. Since all methods in this class are called
  • indirectly from the transformer, the same precautions as for writing class
  • transformers should be taken. Implementors should take care to not reference
  • any game classes, and avoid referencing other classes in their own mod except
  • those specificially designed to be available at early startup, such as
  • coremod classes or other standalone bootstrap objects."

if your careful writing all your parsers...

#

can you make a crafttweaker equivalent but with mixins and inheritance?

#

maybe even as a kubejs addon though less likely?

#

or is it not possible to get the targets right?

quartz stump
#

I basically just need to do 2 things

  1. Register new Tetra parts (Ez sine this is all just datapacks)
  2. Somehow flag weapons with a specific Tetra part/NBT to gain the ICasterTool interface
  3. That's pretty much it tbh
sleek ibex
#

aren't mixins generated at compiletime?

#

I would think that's why they're a no-go for Kube/CraftTweaker

bright shore
#

hmmmmm

zealous zenith
#

What do you need the ICasterTool interface for?

#

I think attaching NBT that looks like a caster tool gets you most of the way there

quartz stump
#

yeah that is true

sleek ibex
#

(also recall that ICasterTool is an interface -- you need impl to live somewhere)

bright shore
#

I guess it's not possible refmaps need to be made compile time 😦

zealous zenith
#

items are not usually even checked for ICasterTool, there is a method to return a representation of a caster based on its NBT data

#

like reactive

#

let me double check that

quartz stump
#

I just worry that without making the weapon a proper caster weapon i'll run into the same issues

#

Since the issue is that, since the command to cast the spell happens on hurt

#

it loops

zealous zenith
#

ah yeah

        int level = EnchantmentHelper.getItemEnchantmentLevel(EnchantmentRegistry.REACTIVE_ENCHANTMENT.get(), stack);
        if (level > 0 && new ReactiveCaster(stack).getSpell().isValid()) {
            Spell spell = new ReactiveCaster(stack).getSpell();
            event.getToolTip().add(Component.literal(spell.getDisplayString()));
        }
#

you want to cast a spell with a tetra sword?

quartz stump
#

basically yeah

sleek ibex
#

basically a module that makes it into a pseudo-enchanters sword

quartz stump
#
EntityEvents.hurt(event => {
    let source = event.source.getActual();
    let target = event.entity;   
    if ( source && source.isPlayer()) {
        let main_hand = source.mainHandItem;
        let off_hand = source.offHandItem;      
        for ( let hand of [main_hand, off_hand] ) {
            if ( hand && hand.getItem() instanceof ModularItem ) {           
                let sourceLeechLevel = hand.getItem().getEffectLevel(hand, ItemEffect.get("source_leech"));
                let spellstriker = hand.getItem().getEffectLevel(hand, ItemEffect.get("spellstrike"));      
                if (sourceLeechLevel > 0) {
                        console.info("Instance of Source Leech!");
                        ArsCapability.getMana(source).ifPresent(mana => mana.addMana(5 * sourceLeechLevel));
                }//if player is wielding a source leech item
                if (spellstriker > 0) {
                    console.info("Instance of Spellstriker!");
                    console.info(event.source.toString());
                    let reactive = new SpellCaster(hand);
                    let caster = new PlayerCaster(source);
                    let spell = reactive.modifySpellBeforeCasting(source.getCommandSenderWorld(), source, InteractionHand.MAIN_HAND, reactive.getSpell());
                    // Anti-Loop measures. 
                    //source.addEffect(new MobEffectInstance('tetra:spellstrike_fatigue', 5 + (20 * Collections.frequency(spell.recipe, EffectDelay.INSTANCE)))); 
                    //source.persistentData.spellstriking += 3;
                    let spellContext = new SpellContext(source.getCommandSenderWorld(), spell, source, caster);
                    let resolver = new SpellResolver(spellContext);
                    resolver.onCastOnEntity(hand, target, InteractionHand.MAIN_HAND);
                }//if player is wielding a spellstriker weapon, cast a spell.
            }//if the weapon is a modular weapon
        }
    }//if damage was done by a player
})```
#

the whole ass hurt script if you're curious

#

I am basically trying to find a way to let the game know "hey, this hurt instance is not from the weapon anymore"

bright shore
#

the problem is this event isn't up to the task

zealous zenith
#

So what was wrong with AttackEntityEvent?

#

that one is called when you smack an entity with an item

bright shore
#

is that the one triggered when you leftclick then? or is it triggered anytime you deal damage

bright shore
sleek ibex
#

sounded like they were saying the spell hit triggers a new attackEntityEvent and they were getting a loop?

quartz stump
bright shore
#

it sounds like it

quartz stump
#

I was looking at events earlier but couldn't find one

zealous zenith
#

AttackEnttiy is different than damage iirc

quartz stump
#

that matched

bright shore
#

I don't have intellij on this pc to check

quartz stump
#

Let me try that and i'll get back to you rq

zealous zenith
#

yeah this looks like it

#

called on left click smack

#

I only see it fired thius one time before the entityHurt method is called

#

this is what reactive uses

sleek ibex
#

sounds like that's definitely what they want then

bright shore
#

is there a kubejs discord?

sleek ibex
#

yes

quartz stump
#

there is and i loathe it

#

you can't ask for help

#

you have to open a fucking thread in the forum channel

#

which doesn't sound bad until you realize it means your pleads for help are entirely invisible

zealous zenith
#

yeah new threads are unfortunately very invisible once you click the tab once to dismiss the notification

quartz stump
#

It also means you have to make a whole ass thread for extremely benign questions

#

things that take like 2 messages to answer

mossy hollow
#

I've never been able to get help in their discord

zealous zenith
#

Next vyklade, make a glyph in kubejs yotefuckenhaw

mossy hollow
#

And the documentation is very incomplete

zealous zenith
#

Ive never seen anyone make one of those yet

quartz stump
#

forge saying that .getPlayer() is not a method of AttackEntityEvent

#

what the fuck are you smoking forge

#

it is literally in your documentation

#

I am going to commit a violence

mossy hollow
#

Forge and Documentation, name a worse pair

sleek ibex
#

in Java or in Kube?

quartz stump
#

shouldn't matter?

sleek ibex
#

kube sometimes renames getters from getThing to .thing

#

makes them autoprops

quartz stump
#

ah let's try that

#

I sure would love if this stuff was put somewhere readable

#

a document containing information of some sorts

mossy hollow
#

You need to get ProbeJS

quartz stump
#

a documentation perhaps

mossy hollow
sleek ibex
#

probeJS was broken for 1.19 last time I checked, but they might've fixed it

#

it was just hanging forever

zealous zenith
#

lmao that mod icon

mossy hollow
#

update released 7 days ago?

sleek ibex
#

ah, so that might be the fix

mossy hollow
#

if not go harass their github

#
  • I am not responsible for any github harassment
quartz stump
#

ok i am not getting crashes anymore

#

but it is not triggering the code

#

I assume is because i'm still using the old checks

#

I'll cautiosly remove the if (source && source.isPlayer()) since this code can only be ran as a player

quartz stump
#

Unless you can define entire new classes inside of KubeJS i doubt that's gonna happen

zealous zenith
#

You can

sleek ibex
#

you can define entirely new classes

quartz stump
#

Ah then it may be possible

zealous zenith
#

when I was asking max it seemed very possible

quartz stump
#

Probably not worth it at that point though

zealous zenith
#

but its one of those things you should just make a mod for because you need minecraft docs to do anything lol

quartz stump
#

exactly lmao

zealous zenith
#

I guess you could make a glyph that runs a command for another mod

mossy hollow
#

but, dynamic glyphs

#

ngl, I'd love something akin to Origins powers for Ars Nouveau glyphs

zealous zenith
#

could do that

#

as long as you had kubejs I guess

#

the real bummer with items/blocks is no datapack driven registry for them

quartz stump
#

I love working my way backwards from crashes let's go danse

#

I'm getting close tho

#

It's just a bit annoying that using Forge hooks means even the slightest error crashes

#

and i can't reload scripts

#

Still tho, this is looking to be the most promising one

#

since i'm not seeing 40 instances of the attack lmao

mossy hollow
quartz stump
#

oh boy i think I ran through all of the errors

#

now its the real test

#

Great googly magoogly it works

#

it actually, genuinely works!

#

No dumb loops this time

#

it even allows dual-wielding

#

if you wield two spellstriking tetra weapons it will cast the spell on both

mossy hollow
#

Woah, nice!

#

and if you spam attacks? it casts as normal?

quartz stump
#

yep

#

there is one cassualty tho

#

thrown tetra weapons wont proc spells

#

not sure i can do much about that tough

mossy hollow
#

It has thrown weapons?

quartz stump
#

yeah

#

but i think i may have one option tho

radiant depot
#

Check the projectile hit event?

quartz stump
#

I was going to check that yeah

radiant depot
#

Then check the projectile, assuming that's how the thrown thing is handled

quartz stump
#

either that or see if by any chance the thrown weapon still triggers the attack event

quartz stump
#

How much do we want to bet this wont work first try?

#

my money is in HitResult somehow beign improperly defined

shadow helm
#

It's development, it's basically guaranteed not to work first try, isn't it? πŸ˜‰

quartz stump
#

well i didn't crash loading

#

that's good news

#

lmao immediate crash within the first few lines let's go

#

getting

#

dangerously close to getting this working???

#

I am not getting crashes anymore, just code that isn't executing due to the previous If check not triggering

#

If this works I'll basically have this little 'mod' ready to go

#

I just gotta figure out how to package it

#

and people will be able to use it

mossy hollow
#

buddy you need to use inverse if statements

#

Can you post the code here?

quartz stump
#
ForgeEvents.onEvent('net.minecraftforge.event.entity.ProjectileImpactEvent', (event) => {
    let proj = event.getProjectile();
    let result = event.getRayTraceResult();
    let level = proj.getLevel();
    if (level instanceof ServerLevel) {
        console.info(result.getType());
        if (result.getType() == Hitresult.ENTITY) {
            console.info("Hit an Entity!");
            let target = event.getEntity();
            if(target) {
                console.info(target);
                if (proj instanceof ThrowableItemProjectile) {
                    let item = proj.getItem();
                    if (item) {
                        console.info(item);
                        let owner = proj.getOwner();
                        if (owner) {
                            if (item instanceof ModularItem){
                                let spellstriker = item.getEffectLevel(hand, ItemEffect.get("spellstrike")); 
                                if (spellstriker > 0) {
                                    console.info("Instance of Spellstriker!");
                                    let reactive = new SpellCaster(item);
                                    let caster = new PlayerCaster(owner);
                                    let spell = reactive.modifySpellBeforeCasting(source.getCommandSenderWorld(), owner, InteractionHand.MAIN_HAND, reactive.getSpell());
                                    let spellContext = new SpellContext(level, spell, owner, caster);
                                    let resolver = new SpellResolver(spellContext);
                                    resolver.onCastOnEntity(item, target, InteractionHand.MAIN_HAND);
                                }//if player is wielding a spellstriker weapon, cast a spell.
                            }// if the item is a modular item
                        } // If the item has an owner
                    } // If an item exists
                } // If the projectiel is a ThrowableItemProjectile
            } // If the entity exists
        } // If the projectile hit an Entity
    } // If this is happening on the server
});```
#

The reason i'm doing this if chain is so that i can print logs at specific spots

#

and figure out what is going wrong before i change anything

quartz stump
#

It's not the most elegant

#

But it's how i'm making up for lack of debugging tools lmao

mossy hollow
#

Lemme show 1 sec

quartz stump
#

for example, i now know that the code is stopping exactly after the check on whether the item is a ThrowableItemProjectile

#

which is concerning because it implies that Tetra modular items are somehow not actually thrown items???

mossy hollow
#

Here, a bit easier to read through and follow, with the exact same code

ForgeEvents.onEvent('net.minecraftforge.event.entity.ProjectileImpactEvent', (event) => {
    const proj = event.getProjectile();
    const result = event.getRayTraceResult();

    const level = proj.getLevel();
    if (!(level instanceof ServerLevel)) return;
    
    console.info(result.getType());
    if (result.getType() != HitResult.ENTITY) return;
    
    console.info("Hit an Entity!");
    const target = event.getEntity();
    if (!target) return;
    console.info(target);
    
    if (!(proj instanceof ThrowableItemProjectile)) return;
    const item = proj.getItem();

    if (!item) return;
    console.info(item);

    const owner = proj.getOwner();
    if (!owner) return;

    if (!(item instanceof ModularItem)) return;

    const spellstriker = item.getEffectLevel(hand, ItemEffect.get("spellstrike"));
    if (spellstriker >= 0) return;

    console.info("Instance of Spellstriker!");
    const reactive = new SpellCaster(item);
    const caster = new PlayerCaster(owner);
    const spell = reactive.modifySpellBeforeCasting(source.getCommandSenderWorld(), owner, InteractionHand.MAIN_HAND, reactive.getSpell());
    const spellContext = new SpellContext(level, spell, owner, caster);
    const resolver = new SpellResolver(spellContext);
    resolver.onCastOnEntity(item, target, InteractionHand.MAIN_HAND);
});
#

This is a technique called defensive programming, where you filter out all logic paths you're not interested in

quartz stump
#

I see

sleek ibex
#

I've always heard this technique called guard clauses, while defensive programming was more doing things like " != null" everywhere

#

but either way, yeah, effective way to reduce nesting if your indentation is going crazy

mossy hollow
#

Yeah that can also work, I may be calling it wrong, I don't typically refer to programming techniques by name haha

quartz stump
#

I also found out my exit clause here, it's because modular items don't inherit from ThrowableItemProjectile, they inherit from AbstractArrow

mossy hollow
#

Ah

sleek ibex
#

I'm a CS professor, so I at least try to keep up to date on names so my students have half a chance when they leave my class πŸ˜‰

quartz stump
#

fortunately this is not a problem

#

all i care about is fetching what item is given to the player when they normally pick this up

mossy hollow
sleek ibex
#

honestly, the reality is every pattern has like three different names depending on where/when you learned it

#

it took me years to stop calling all class instance variables "properties"

mossy hollow
#

I still call them properties

#

or I say "that variable there, no the other one"

quartz stump
#

I kinda forced myself to call declared variables variables and properties of classes properties and/or fields if i feel pedantic

shadow helm
sleek ibex
#

I swear my students are getting worse at off by one errors every year

#

naming has always been bad

#

I don't understand how like 20% of programmers can understand a single thing they write when their code looks like:

    int x = 4;
    int y = x * 2;
    int z = Math.sqrt(y);
    int a = 0;
    int b = x + z / a;
mossy hollow
#

It's a maturity thing, most people grow out of it, I know I used to be guilty πŸ˜…

shadow helm
mossy hollow
#

I used to code golf my actual code

#

I'm not proud of that

sleek ibex
#

literally had someone in my office hours today show me his class:

   public class Gradebook {
     public int x;
     public String y;
     public int z;
     private int a;
     private double b;
   ....
  }
quartz stump
#

jesus christ

sleek ibex
#

I still don't know what x was supposed to do

#

or why it was public

quartz stump
#

I get having have a really small name for something that only lives 2 lines

#

like if you need x for the next two lines that's fine i think

#

but for an entire ass property!?

#

that's maddening

shadow helm
sleek ibex
#

I'm remote, but I newspaper them with my eyes. I have a reputation for unintentionally expressing concern at code without saying a word

shadow helm
#

And hey, if it's

public class Point {
  public int x;
  public int y;
  public int z;
}

Then I'm even fine with x,y,z as variable names because the purpose is obvious. But it's obviously not, in whatever that Gradebook was supposed to be.
At least they named the class something probably useful and not foo

sleek ibex
#

yeah, in that case x,y,and z are actually semantic names, indicating the X axis, Y axis, and Z axis

shadow helm
#

Eh. Ranting about it doesn't help, took me a year with an actual job and coming back to code that I totally ruined after 4 weeks and not understanding it for me to get why sensible names are important.

quartz stump
#

Hmmm

#

Does anyone know off the top of their head if KubeJS can run protected methods?

#

turns out .getPickupItem() is protected

#

and the property it returns is private

#

Which is not ideal

sleek ibex
#

is there a public equivalent to the method you're looking at?

quartz stump
#

AbstractArrow has getPickupItem() as protected and abstract

#

wait!

#

I think I see a public method in here

#

let's pray it works

#

it worked! yay!

#

I got the itemstack

#

I forgot to actually do .getItem() on it though

#

I need the actual item before I can run logic on it

#

sometimes my inability to see dumb mistakes is unparalleled

#

I forgor to rename one of the arguments that goes into a method

bright shore
quartz stump
#

Me when i know how to access private classes and fields in C# but can't do it on Java

#

shit tier programming language smh smh

shadow helm
quartz stump
#

I think i got this though

#

The code stopped at the spellstriker check because Jarva's change flipped the logic when it shouldn't have lmao

#

it was exiting if the weapon had the effect

#

rather than the other way around RynnLaugh

#

at least that's an easy thing to catch and fix

mossy hollow
#

Oh yeah meant to do <=

quartz stump
#

It works!

#

kinda

#

it's putting the spell on the weapon wheeze2

#

I think I'm pulling the wrong entity lmao

#

yeah i was pulling the wrong entity lmao

#

I should've pulled the entity from the HitResult

#

which can be of type EntityHitResult

mossy hollow
#

Ah nice

#

Hopefully fixed soon then

quartz stump
#

I got a crash but idk if it was because of my code or because of lag lmao

#

it's hard to tell when my laptop is just kicking and screaming each time the game loads RynnLaugh

mossy hollow
zealous zenith
#

I was holding off because there isnt currently a way to communicate to the user that portals are disabled

#

I was going to think of something but have been working on other bits

#

a config on the warp scroll would probably be fine in the meantime, I cant imagine many packs will disable them

mossy hollow
#

Ah okay, I can try think of something

quartz stump
#

I can confirm, Spellstriking tetra weapons are a go and they are beautiful

zealous zenith
#

er a tooltip on the warp scrol

quartz stump
#

Now to figure out how I can like

#

publish this

#

so people can use it

mossy hollow
#

Ah right, yeah that could work

#

We have no issues with warp scrolls, because they're single-use, but we don't like permanent warp portals because it eliminates other travel forms

#

I'll add a tooltip

mossy hollow
mossy hollow
zealous zenith
#

nice

#

going to probably release a version tonight with the new caster tool and animated block

mossy hollow
#

Feel free to edit the wording, I just put something rough in there

#

What's the new caster tool?

bright shore
zealous zenith
#

casting spells through scryer crystals

mossy hollow
#

Ooh cool

shadow helm
bright shore
#

well, yea, ideally it would be in base KubeJs. People have already found a need of it

quartz stump
#

I have shared my bastard creation in #1075543936640233473

#

Hopefully that's accceptable

#

It seems that KubeJS doesn't really lend itself to easy sharing

#

Files are meant to be distributed in entire modpacks

#

so i can't make it into a Datapack

#

which makes me angy

shadow helm
#

Good name choice πŸ‘

bright shore
#

isn't this just an addon but harder to share and worse for startup performance?

zealous zenith
#

you could still publish it as a datapack couldnt you?

quartz stump
#

I'll look into migrating the plugin into a full mod when I have time

quartz stump
zealous zenith
#

does kubejs read other mods datapacks for integrations?

#

probably not

bright shore
#

can't you publish it as "customization: scripts"

#

?

mossy hollow
#

This isn't a datapack, it's a kubejs script which isn't used for integrations, only kubejs APIs are used for integrations

quartz stump
#

I could give it a try

#

I don't care exactly what curse forge thinks my project is

#

as long as I can make it downloadable there

#

I need an image for the project

#

hmmm

mossy hollow
#

I finally have the UI working how I want it to, with a bit of cleaning up needed

#

Most of it's torn out of the base spell book, but it'll all be repurposed now

#

The idea of this is a station that displays glyphs not visible within the spellbook to use for programming events into caster curios

#

So caster curios will be programmed with events in this station and then can be scribed with the spell that should be cast when the event fulfills

#

The first glyph I have is a Cyclic Artifice Method, which will cast a spell every X seconds, and then it's extended twice to increase that interval

#

this could be programmed into a ring that is scribed with a self conjure magelight spell and it would self cast conjure magelight on the interval

quartz stump
#

Someone remind me to like

#

work on making this into an add-on mod

#

for now, JankJS will be needed

bright shore
quartz stump
#

Just poking fun at how my little add-on is super janky lmao

quartz stump
#

Day 1 of forge wrangling: Commence!

shadow helm
#

Good luck. You're gonna need it for forgegradle!

quartz stump
#

:')

#

I'm using the boilerplate from the pins here

#

and just adding Tetra to the gradle dependencies

#

which tetra's dev graciously tell you how to add

#

god bless them

shadow helm
#

he. Now the import just has to resolve. The first time is going to take forever since you're basically downloading every minecraft file. Just FYI

quartz stump
#

Yeah it's been downloading this file for a hot minute

#

oh it moved onto to another file ok good

#

i feared it may have locked up lmao

shadow helm
#

If it feels like it's stuck on the same file for 5-6 minutes, feel free to give it a kick by restarting.
But since it's doing a lot of shit sequentially, expect this to take like 20 minutes. First time sucks.

quartz stump
#

as long as it runs

#

Seeing as i'm not adding any new items through java code

#

It should be easy to do the thing?

#

I just have to register to some events and include data from a datapack

#

Patchouli entries use datapacks right?

#

I want to add an entry into the ars book about tetra compatibility

radiant depot
#

Yep

quartz stump
#

then yeah, I may be able to get this done today if things to well

radiant depot
#

If you are using the ars add-on template there's a setup for datagen patchouli stuff

quartz stump
#

Let's pray that things don't gogo gadget nuclear anahilation on me

mossy hollow
shadow helm
#

still haven't taken a look at that, need to though, if it saves me from forge gradle

shadow helm
#

ahhh. Archloom is still gradle, but not forge gradle. Good start for learning new things

quartz stump
#

it is still downloading files SCREEM

#

just how many files do you need gradle

shadow helm
#

gradle minecraft

#

every texture, language, etc

quartz stump
#

I'm wondering how i should handle the Spellstrike augment

#

I know it shouldn't be as good as a real Enchanter's Sword

#

since that thing costs a lot of more resources to get

#

So maybe it wont ever have the free x2 Amplify

#

but maybe i will have it get a free touch form

mossy hollow
shadow helm
#

Now that makes me sceptical

mossy hollow
#

why

#

It's what Architectury is based on

#

In that repo everything else is setup the same as the forgegradle example

shadow helm
#

On first read it seems like another layer of indirection. But if it's faster I'll take as many layers of indirection as necessary

mossy hollow
#

this is the internals

#

It uses the forge runtime but no forge build system

#

(it also makes life so much easier if you decide to make crossplatform mod)

quartz stump
#

hmmm

#

Gradle is having a hard time finding the mod dependencies

#

I am slowly reverse engineering the gradle file to see what's going on

radiant depot
#

even just one wrong cause a cascade of fake errors

quartz stump
#

The first error in the list is not finding JEI

zealous zenith
#

ooo yeah JEI moved mavens

radiant depot
#

shouldn't the addon have that updated?

zealous zenith
#

I havent updated it yet

quartz stump
#

Ah that makes sense

#

what's the new maven repository?

radiant depot
#

Welp, wait a sec

quartz stump
#

I at least know how to change that

radiant depot
#

Or look at Elemental/StarbuncleMania

quartz stump
#

as a comparison piece

#

kinda hard when the first post isn't pinned

zealous zenith
#

blamejared repository is the new maven iirc

quartz stump
#

ok found the github

#

let's see now

radiant depot
quartz stump
#

taht's odd

#

i think i have "https://maven.blamejared.com" as a repository Thonk

#

yeah it can't find any of the mods

#

rather than just JEI

#

Hmmmm

radiant depot
#

is your build.gradle on git?

quartz stump
#

let me push the changes i made

radiant depot
#

i'll try to update the example addon first then check yours

mossy hollow
radiant depot
#

try to comment out tetra imports to check if there's an error there

mossy hollow
#

The template imports and installs for me

radiant depot
#

i got error with
implementation fg.deobf("se.mickelus.mutil:mutil:1.19-5.1.0")
implementation fg.deobf("se.mickelus.tetra:tetra:1.19-5.0.0")

#

fine without

quartz stump
#

hmmm

#

that is basically what their wiki said to do

#

Let's see if I can see other tetra add-ons and copy their homewo- I mean ✨ learn from them ✨

mossy hollow
radiant depot
#

can always pull from cursemaven

mossy hollow
#

ick

radiant depot
#

@quartz stump
implementation fg.deobf("se.mickelus.mutil:mutil:${mc_version}-5.1.0")

implementation fg.deobf("curse.maven:tetra-289712:4379764")
#

(mc_version is set to 1.19.2)

mossy hollow
#

Weird that mutil is publishjed to maven but tetra isn't

quartz stump
#

I looked at how Art of Forging, a tetra addon i use, does it

#

they do

    implementation fg.deobf("curse.maven:tetra-289712:4370833")
    implementation fg.deobf("curse.maven:mutil-351914:3941314")```
#

which looks cursed

mossy hollow
#

Yeah they just use curse maven