#Converting excess effect intensity into duration
63 messages · Page 1 of 1 (latest)
Once your ticket has been resolved, please close it with </ticket close:1054771505520717835> command!
-# bump
yes it should be possible but it might need tick events
if there's an event when an effect is applied or changed then that makes things a little easier
you see the issue is wiki says that exists but has no info on it
Use probejs and look for example scripts
I don't even use the wiki when making scripts lol
whats probejs?
huh
thanks
it's highly highly recommended
However it is not 100% accurate on what is possible to autocomplete so check the forge packages to make sure
yeah it also says it requires 1.21
the latest version does I'm sure, but there are older versions
how do i select a different version in vscode?
nvm
okay anything seem wrong with this script before i test it?
const maxIntensity = 9;
const durationPer = 30
PlayerEvents.tick(event => {
const player = event.player;
player.activeEffects.forEach(effect => {
//Return if the potion effect is below the bound
if (effect.amplifier <= maxIntensity) return
let nbt = effect.save({})
console.log("Old: " + nbt)
//new duration and level
nbt.Duration = NBT.b(nbt.Duration + durationPer * (nbt.Amplifier - maxIntensity))
//apply effect
nbt.Amplifier = NBT.b(maxIntensity)
let newInstance = effect.load(nbt)
console.log("New: " + newInstance.save({}))
player.forceAddEffect(newInstance, player)
})
});
side question, does forceAddEffect() override current effect or do i need to clear the current one first because itll have higher intensity?
note that using tick events will cause lag on high population servers
okay so what should i use instead?
did you see if there was an event for effects being applied?
i couldnt find any in #1048591172165189632 and assumed none existed
ah you should check the forge packages for things like that: https://lexxie.dev/forge/1.20.1
package index
if you realy can't find any then your script should be fine
You can use these forge events to have more granular control over the effect life cycle
event => {
global.mob_effect_added(event);
}
)
ForgeEvents.onEvent("net.minecraftforge.event.entity.living.MobEffectEvent$Applicable",
event => {
global.mob_effect_applicable(event);
}
)
ForgeEvents.onEvent("net.minecraftforge.event.entity.living.MobEffectEvent$Expired",
event => {
global.mob_effect_expired(event);
}
)
ForgeEvents.onEvent("net.minecraftforge.event.entity.living.MobEffectEvent$Remove",
event => {
global.mob_effect_remove(event);
}
)```
so i should use the effect added event instead?
that or potentially applicable, depending on how specifically you want the logic to work, but yeah using one of these would be more efficient than use the tick event. you can read up on the specific events a bit here https://lexxie.dev/forge/1.20.1/net/minecraftforge/event/entity/living/MobEffectEvent.html
declaration: package: net.minecraftforge.event.entity.living, class: MobEffectEvent
like do this?
replace the event with that one and do event.entity instead of event.player?
const maxIntensity = 9;
const durationPer = 30
ForgeEvents.onEvent("net.minecraftforge.event.entity.living.MobEffectEvent$Applicable", event => {
const player = event.entity;
player.activeEffects.forEach(effect => {
//Return if the potion effect is below the bound
if (effect.amplifier <= maxIntensity) return
let nbt = effect.save({})
console.log("Old: " + nbt)
//new duration and level
nbt.Duration = NBT.b(nbt.Duration + durationPer * (nbt.Amplifier - maxIntensity))
//apply effect
nbt.Amplifier = NBT.b(maxIntensity)
let newInstance = effect.load(nbt)
console.log("New: " + newInstance.save({}))
player.forceAddEffect(newInstance, player)
})
});
whats the difference between is added and can be added?
the main difference in this case is just when in the chain of events they happen. the way it could matter in a use case like this is that if you use Added instead of Applicable, technically an effect with an amplifier greater than the max allowed value will still be applied for ~a tick, whereas if you use Applicable then you can ensure that effects that actually get applied to the player are only ever within the range you want
functionally it might not matter, but it could
okay so applicable lets me interupt it getting applied at all instead of correcting it after
probably want that then yeah
if you only want this to apply to players you'd want to check that the entity is a player as well, other than that I haven't used this method of saving & loading effects but if it works it seems clean
so then does any of the other syntax need to change for this new event type?
and how would i do that?
event.entity.isPlayer() should do
so this?
const maxIntensity = 9;
const durationPer = 30
ForgeEvents.onEvent("net.minecraftforge.event.entity.living.MobEffectEvent$Applicable", event => {
const player = event.player;
if (!player.isPlayer()) return
player.activeEffects.forEach(effect => {
//Return if the potion effect is below the bound
if (effect.amplifier <= maxIntensity) return
let nbt = effect.save({})
console.log("Old: " + nbt)
//new duration and level
nbt.Duration = NBT.b(nbt.Duration + durationPer * (nbt.Amplifier - maxIntensity))
//apply effect
nbt.Amplifier = NBT.b(maxIntensity)
let newInstance = effect.load(nbt)
console.log("New: " + newInstance.save({}))
player.forceAddEffect(newInstance, player)
})
});
oh also I should mention that when you hook into forge events like this the code has to go in a startup script. that's why I pass the event to a global method so that you can put that global method in a server script and reload / test without restarting the whole game
okay but outside of testing the only difference is throw this in startup instead of server and its good to go?
yep 🙂↕️ that looks like it should do
also i forget how for each works in js,
should i be using a continue instead of return for the if <= maxIntensity?
would return end the forEach early or no?
yes
oh yeah forgor about that
if you were to use a normal for loop then yes you would use continue
so then how do i make it skip that effect but still parse the others?
return
return, or set up a traditional loop
okay so it isnt a loop
yeah it's technically different