particle update! but the math is borken. asking @Alwinfy for help
This commit is contained in:
parent
3fb5f0d1b2
commit
de3be9d04a
45 changed files with 695 additions and 372 deletions
|
@ -1,7 +1,7 @@
|
|||
eb78f6a2b68dd772a5016fc5a3db10488a65abfa assets/hexcasting/models/item/amethyst_dust.json
|
||||
df940dd798240fac6fde700c57f8ae6aa43d1c9e assets/hexcasting/models/item/artifact.json
|
||||
1a66f279c030ebd5ed6a596f63205094b2529819 assets/hexcasting/models/item/artifact_filled.json
|
||||
9f3d25fb7fd5e4f3ee81142ac9396709ac068860 assets/hexcasting/models/item/battery.json
|
||||
1b3a4bd9dd3c2af2894e0acc1d9d3c74d16c7625 assets/hexcasting/models/item/battery.json
|
||||
dc72e3345c4375b37f3624040c9a8df435c958d1 assets/hexcasting/models/item/charged_amethyst.json
|
||||
b9916a82d647db5d3c505de2eb5f0a528169e1db assets/hexcasting/models/item/cypher.json
|
||||
5082df8eee8f56f8c0d74db71ccda37a165bc76f assets/hexcasting/models/item/cypher_filled.json
|
||||
|
@ -21,7 +21,7 @@ c2ceb08a8662a7e4a311401b0baced1add6f2e35 assets/hexcasting/models/item/dye_color
|
|||
f41fb9405b869644333872cd1ece40b1b07410d2 assets/hexcasting/models/item/dye_colorizer_red.json
|
||||
5894e7a1cc38ae5b09c651791c65c983d984d20c assets/hexcasting/models/item/dye_colorizer_white.json
|
||||
07959b86ed25559b4960c5f4aa7bab88bf9b5bf1 assets/hexcasting/models/item/dye_colorizer_yellow.json
|
||||
5ee629510cbd0058a5736be2bf426d3a1b6717a0 assets/hexcasting/models/item/focus.json
|
||||
f7f98a306a8a0529a54446b4876e624201525a1d assets/hexcasting/models/item/focus.json
|
||||
0146e90177ed71b25d2936ff3b2d9975e47c5142 assets/hexcasting/models/item/focus_double.json
|
||||
167b8e3f3367f12f8045369bea26d7a48e59b0d0 assets/hexcasting/models/item/focus_double_sealed.json
|
||||
3ff6209fdfc13c6f5e4741a5892787cb5700a34c assets/hexcasting/models/item/focus_empty.json
|
||||
|
|
|
@ -3,105 +3,105 @@
|
|||
{
|
||||
"predicate": {
|
||||
"hexcasting:mana": 0.0,
|
||||
"hexcasting:max_mana": 1.0
|
||||
"hexcasting:max_mana": 0.0
|
||||
},
|
||||
"model": "hexcasting:item/phial_small_0"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:mana": 0.25,
|
||||
"hexcasting:max_mana": 1.0
|
||||
"hexcasting:max_mana": 0.0
|
||||
},
|
||||
"model": "hexcasting:item/phial_small_1"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:mana": 0.5,
|
||||
"hexcasting:max_mana": 1.0
|
||||
"hexcasting:max_mana": 0.0
|
||||
},
|
||||
"model": "hexcasting:item/phial_small_2"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:mana": 0.75,
|
||||
"hexcasting:max_mana": 1.0
|
||||
"hexcasting:max_mana": 0.0
|
||||
},
|
||||
"model": "hexcasting:item/phial_small_3"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:mana": 1.0,
|
||||
"hexcasting:max_mana": 1.0
|
||||
"hexcasting:max_mana": 0.0
|
||||
},
|
||||
"model": "hexcasting:item/phial_small_4"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:mana": 0.0,
|
||||
"hexcasting:max_mana": 2.0
|
||||
"hexcasting:max_mana": 1.0
|
||||
},
|
||||
"model": "hexcasting:item/phial_medium_0"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:mana": 0.25,
|
||||
"hexcasting:max_mana": 2.0
|
||||
"hexcasting:max_mana": 1.0
|
||||
},
|
||||
"model": "hexcasting:item/phial_medium_1"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:mana": 0.5,
|
||||
"hexcasting:max_mana": 2.0
|
||||
"hexcasting:max_mana": 1.0
|
||||
},
|
||||
"model": "hexcasting:item/phial_medium_2"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:mana": 0.75,
|
||||
"hexcasting:max_mana": 2.0
|
||||
"hexcasting:max_mana": 1.0
|
||||
},
|
||||
"model": "hexcasting:item/phial_medium_3"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:mana": 1.0,
|
||||
"hexcasting:max_mana": 2.0
|
||||
"hexcasting:max_mana": 1.0
|
||||
},
|
||||
"model": "hexcasting:item/phial_medium_4"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:mana": 0.0,
|
||||
"hexcasting:max_mana": 3.0
|
||||
"hexcasting:max_mana": 2.0
|
||||
},
|
||||
"model": "hexcasting:item/phial_large_0"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:mana": 0.25,
|
||||
"hexcasting:max_mana": 3.0
|
||||
"hexcasting:max_mana": 2.0
|
||||
},
|
||||
"model": "hexcasting:item/phial_large_1"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:mana": 0.5,
|
||||
"hexcasting:max_mana": 3.0
|
||||
"hexcasting:max_mana": 2.0
|
||||
},
|
||||
"model": "hexcasting:item/phial_large_2"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:mana": 0.75,
|
||||
"hexcasting:max_mana": 3.0
|
||||
"hexcasting:max_mana": 2.0
|
||||
},
|
||||
"model": "hexcasting:item/phial_large_3"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:mana": 1.0,
|
||||
"hexcasting:max_mana": 3.0
|
||||
"hexcasting:max_mana": 2.0
|
||||
},
|
||||
"model": "hexcasting:item/phial_large_4"
|
||||
}
|
||||
|
|
|
@ -6,78 +6,78 @@
|
|||
},
|
||||
"model": "hexcasting:item/focus_empty"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:datatype": 99.99
|
||||
},
|
||||
"model": "hexcasting:item/focus_empty_sealed"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:datatype": 0.99
|
||||
},
|
||||
"model": "hexcasting:item/focus_entity"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:datatype": 100.99
|
||||
},
|
||||
"model": "hexcasting:item/focus_entity_sealed"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:datatype": 1.99
|
||||
},
|
||||
"model": "hexcasting:item/focus_double"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:datatype": 101.99
|
||||
},
|
||||
"model": "hexcasting:item/focus_double_sealed"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:datatype": 2.99
|
||||
},
|
||||
"model": "hexcasting:item/focus_vec3"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:datatype": 102.99
|
||||
},
|
||||
"model": "hexcasting:item/focus_vec3_sealed"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:datatype": 3.99
|
||||
},
|
||||
"model": "hexcasting:item/focus_widget"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:datatype": 103.99
|
||||
},
|
||||
"model": "hexcasting:item/focus_widget_sealed"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:datatype": 4.99
|
||||
},
|
||||
"model": "hexcasting:item/focus_list"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:datatype": 104.99
|
||||
},
|
||||
"model": "hexcasting:item/focus_list_sealed"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:datatype": 5.99
|
||||
},
|
||||
"model": "hexcasting:item/focus_pattern"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:datatype": 99.99
|
||||
},
|
||||
"model": "hexcasting:item/focus_empty_sealed"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:datatype": 100.99
|
||||
},
|
||||
"model": "hexcasting:item/focus_entity_sealed"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:datatype": 101.99
|
||||
},
|
||||
"model": "hexcasting:item/focus_double_sealed"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:datatype": 102.99
|
||||
},
|
||||
"model": "hexcasting:item/focus_vec3_sealed"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:datatype": 103.99
|
||||
},
|
||||
"model": "hexcasting:item/focus_widget_sealed"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:datatype": 104.99
|
||||
},
|
||||
"model": "hexcasting:item/focus_list_sealed"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:datatype": 105.99
|
||||
|
|
17
src/main/java/at/petrak/hexcasting/api/ParticleSpray.kt
Normal file
17
src/main/java/at/petrak/hexcasting/api/ParticleSpray.kt
Normal file
|
@ -0,0 +1,17 @@
|
|||
package at.petrak.hexcasting.api
|
||||
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
data class ParticleSpray(val pos: Vec3, val vel: Vec3, val fuzziness: Double, val spread: Double) {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun Burst(pos: Vec3, size: Double): ParticleSpray {
|
||||
return ParticleSpray(pos, Vec3(size, 0.0, 0.0), 0.0, 6.28)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun Cloud(pos: Vec3, size: Double): ParticleSpray {
|
||||
return ParticleSpray(pos, Vec3.ZERO, size, 0.0)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,28 +3,31 @@ package at.petrak.hexcasting.api
|
|||
import at.petrak.hexcasting.common.casting.CastException
|
||||
import at.petrak.hexcasting.common.casting.CastingContext
|
||||
import at.petrak.hexcasting.common.casting.OperatorSideEffect
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
interface SpellOperator : Operator {
|
||||
val argc: Int
|
||||
|
||||
fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): Triple<RenderedSpell, Int, List<Vec3>>
|
||||
fun execute(
|
||||
args: List<SpellDatum<*>>,
|
||||
ctx: CastingContext
|
||||
): Triple<RenderedSpell, Int, List<ParticleSpray>>
|
||||
|
||||
override fun operate(stack: MutableList<SpellDatum<*>>, ctx: CastingContext): OperationResult {
|
||||
if (this.argc > stack.size)
|
||||
throw CastException(CastException.Reason.NOT_ENOUGH_ARGS, this.argc, stack.size)
|
||||
val args = stack.takeLast(this.argc)
|
||||
for (_i in 0 until this.argc) stack.removeLast()
|
||||
val (spell, mana, particlePoses) = this.execute(args, ctx)
|
||||
val (spell, mana, particles) = this.execute(args, ctx)
|
||||
|
||||
val sideEffects = mutableListOf(
|
||||
OperatorSideEffect.ConsumeMana(mana),
|
||||
OperatorSideEffect.AttemptSpell(spell, this.isGreat)
|
||||
)
|
||||
for (pos in particlePoses) {
|
||||
sideEffects.add(OperatorSideEffect.Particles(pos))
|
||||
for (spray in particles) {
|
||||
sideEffects.add(OperatorSideEffect.Particles(spray))
|
||||
}
|
||||
|
||||
return OperationResult(stack, sideEffects)
|
||||
}
|
||||
|
||||
}
|
|
@ -2,16 +2,15 @@ package at.petrak.hexcasting.client;
|
|||
|
||||
import at.petrak.hexcasting.HexMod;
|
||||
import at.petrak.hexcasting.api.SpellDatum;
|
||||
import at.petrak.hexcasting.client.particles.ConjureParticle;
|
||||
import at.petrak.hexcasting.common.blocks.HexBlocks;
|
||||
import at.petrak.hexcasting.common.items.HexItems;
|
||||
import at.petrak.hexcasting.common.items.ItemFocus;
|
||||
import at.petrak.hexcasting.common.items.ItemScroll;
|
||||
import at.petrak.hexcasting.common.items.magic.ItemManaBattery;
|
||||
import at.petrak.hexcasting.common.items.magic.ItemPackagedSpell;
|
||||
import at.petrak.hexcasting.common.particles.ConjureParticle;
|
||||
import at.petrak.hexcasting.common.particles.HexParticles;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.particle.ParticleEngine;
|
||||
import net.minecraft.client.renderer.ItemBlockRenderTypes;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.item.ItemProperties;
|
||||
|
@ -89,8 +88,9 @@ public class RegisterClientStuff {
|
|||
|
||||
@SubscribeEvent(priority = EventPriority.LOWEST)
|
||||
public static void registerParticles(ParticleFactoryRegisterEvent event) {
|
||||
ParticleEngine particleManager = Minecraft.getInstance().particleEngine;
|
||||
particleManager.register(HexParticles.CONJURE_BLOCK_PARTICLE.get(), ConjureParticle.BlockProvider::new);
|
||||
particleManager.register(HexParticles.CONJURE_LIGHT_PARTICLE.get(), ConjureParticle.LightProvider::new);
|
||||
// does whatever a particle can
|
||||
var particleMan = Minecraft.getInstance().particleEngine;
|
||||
particleMan.register(HexParticles.LIGHT_PARTICLE.get(), ConjureParticle.Provider::new);
|
||||
particleMan.register(HexParticles.CONJURE_PARTICLE.get(), ConjureParticle.Provider::new);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
package at.petrak.hexcasting.client.particles;
|
||||
|
||||
import at.petrak.hexcasting.HexMod;
|
||||
import at.petrak.hexcasting.common.particles.ConjureParticleOptions;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||
import com.mojang.blaze3d.vertex.Tesselator;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.particle.*;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlas;
|
||||
import net.minecraft.client.renderer.texture.TextureManager;
|
||||
import net.minecraft.util.FastColor;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class ConjureParticle extends TextureSheetParticle {
|
||||
private static final Random RANDOM = new Random();
|
||||
|
||||
private final SpriteSet sprites;
|
||||
private final boolean light;
|
||||
|
||||
ConjureParticle(ClientLevel pLevel, double x, double y, double z, double dx, double dy, double dz,
|
||||
SpriteSet pSprites, int color, boolean light) {
|
||||
super(pLevel, x, y, z, dx, dy, dz);
|
||||
this.light = light;
|
||||
this.quadSize *= light ? 0.9f : 0.75f;
|
||||
this.setParticleSpeed(dx, dy, dz);
|
||||
|
||||
var r = FastColor.ARGB32.red(color);
|
||||
var g = FastColor.ARGB32.green(color);
|
||||
var b = FastColor.ARGB32.blue(color);
|
||||
var a = FastColor.ARGB32.alpha(color);
|
||||
this.setColor(r / 255f, g / 255f, b / 255f);
|
||||
this.setAlpha(a / 255f);
|
||||
|
||||
this.friction = 0.96F;
|
||||
this.gravity = light ? -0.01F : 0F;
|
||||
this.speedUpWhenYMotionIsBlocked = true;
|
||||
this.sprites = pSprites;
|
||||
|
||||
this.roll = RANDOM.nextFloat(360);
|
||||
this.oRoll = this.roll;
|
||||
|
||||
this.lifetime = (int) ((light ? 64.0D : 32.0D) / ((Math.random() + 3f) * 0.25f));
|
||||
this.hasPhysics = false;
|
||||
this.setSpriteFromAge(pSprites);
|
||||
}
|
||||
|
||||
public @NotNull ParticleRenderType getRenderType() {
|
||||
return this.light ? I_STOLE_THIS_FROM_PSI : ParticleRenderType.PARTICLE_SHEET_TRANSLUCENT;
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
super.tick();
|
||||
this.setSpriteFromAge(this.sprites);
|
||||
if (light) {
|
||||
this.quadSize *= 0.96f;
|
||||
this.alpha = 1.0f - ((float) this.age / (float) this.lifetime);
|
||||
}
|
||||
}
|
||||
|
||||
public void setSpriteFromAge(@NotNull SpriteSet pSprite) {
|
||||
if (!this.removed) {
|
||||
int age = this.age * 4;
|
||||
if (age > this.lifetime) {
|
||||
age /= 4;
|
||||
}
|
||||
this.setSprite(pSprite.get(age, this.lifetime));
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class Provider implements ParticleProvider<ConjureParticleOptions> {
|
||||
private final SpriteSet sprite;
|
||||
|
||||
public Provider(SpriteSet pSprites) {
|
||||
this.sprite = pSprites;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Particle createParticle(ConjureParticleOptions type, ClientLevel level,
|
||||
double pX, double pY, double pZ,
|
||||
double pXSpeed, double pYSpeed, double pZSpeed) {
|
||||
return new ConjureParticle(level, pX, pY, pZ, pXSpeed, pYSpeed, pZSpeed, this.sprite, type.color(),
|
||||
type.isLight());
|
||||
}
|
||||
}
|
||||
|
||||
// pretty sure this prevents the gross culling
|
||||
// https://github.com/VazkiiMods/Psi/blob/1.18/src/main/java/vazkii/psi/client/fx/FXWisp.java
|
||||
private static final ParticleRenderType I_STOLE_THIS_FROM_PSI = new ParticleRenderType() {
|
||||
@Override
|
||||
public void begin(BufferBuilder buf, TextureManager texMan) {
|
||||
RenderSystem.depthMask(false);
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE);
|
||||
|
||||
RenderSystem.setShaderTexture(0, TextureAtlas.LOCATION_PARTICLES);
|
||||
texMan.bindForSetup(TextureAtlas.LOCATION_PARTICLES);
|
||||
texMan.getTexture(TextureAtlas.LOCATION_PARTICLES).setFilter(true, false);
|
||||
buf.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.PARTICLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end(Tesselator tess) {
|
||||
tess.end();
|
||||
Minecraft.getInstance()
|
||||
.getTextureManager()
|
||||
.getTexture(TextureAtlas.LOCATION_PARTICLES)
|
||||
.restoreLastBlurMipmap();
|
||||
RenderSystem.disableBlend();
|
||||
RenderSystem.depthMask(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return HexMod.MOD_ID + ":conjure";
|
||||
}
|
||||
};
|
||||
}
|
|
@ -44,7 +44,7 @@ public class BlockConjured extends Block implements SimpleWaterloggedBlock, Enti
|
|||
@Override
|
||||
public void stepOn(Level pLevel, @NotNull BlockPos pPos, @NotNull BlockState pState, @NotNull Entity pEntity) {
|
||||
BlockEntity tile = pLevel.getBlockEntity(pPos);
|
||||
if (tile instanceof BlockEntityConjured bec) {
|
||||
if (tile instanceof BlockEntityConjured bec && !bec.getBlockState().getValue(LIGHT)) {
|
||||
bec.walkParticle(pEntity);
|
||||
}
|
||||
super.stepOn(pLevel, pPos, pState, pEntity);
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
package at.petrak.hexcasting.common.blocks;
|
||||
|
||||
import at.petrak.hexcasting.common.casting.colors.FrozenColorizer;
|
||||
import at.petrak.hexcasting.common.particles.HexParticles;
|
||||
import at.petrak.hexcasting.common.particles.ConjureParticleOptions;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.Connection;
|
||||
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
|
||||
import net.minecraft.util.FastColor;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
|
@ -33,14 +32,12 @@ public class BlockEntityConjured extends BlockEntity {
|
|||
int color = this.colorizer.getColor(pEntity.tickCount, pEntity.position()
|
||||
.add(new Vec3(RANDOM.nextFloat(), RANDOM.nextFloat(), RANDOM.nextFloat()).scale(
|
||||
RANDOM.nextFloat() * 3)));
|
||||
int r = FastColor.ARGB32.red(color);
|
||||
int g = FastColor.ARGB32.green(color);
|
||||
int b = FastColor.ARGB32.blue(color);
|
||||
assert level != null;
|
||||
level.addParticle(HexParticles.CONJURE_BLOCK_PARTICLE.get(),
|
||||
level.addParticle(new ConjureParticleOptions(color, false),
|
||||
pEntity.getX() + (RANDOM.nextFloat() * 0.6D) - 0.3D,
|
||||
getBlockPos().getY() + (RANDOM.nextFloat() * 0.05D) + 0.95D,
|
||||
pEntity.getZ() + (RANDOM.nextFloat() * 0.6D) - 0.3D, r / 255d, g / 255d, b / 255d);
|
||||
pEntity.getZ() + (RANDOM.nextFloat() * 0.6D) - 0.3D,
|
||||
0.0, 0.0, 0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -50,21 +47,20 @@ public class BlockEntityConjured extends BlockEntity {
|
|||
int color = this.colorizer.getColor(RANDOM.nextFloat() * 16384,
|
||||
new Vec3(RANDOM.nextFloat(), RANDOM.nextFloat(), RANDOM.nextFloat()).scale(
|
||||
RANDOM.nextFloat() * 3));
|
||||
double r = FastColor.ARGB32.red(color) / 255d;
|
||||
double g = FastColor.ARGB32.green(color) / 255d;
|
||||
double b = FastColor.ARGB32.blue(color) / 255d;
|
||||
assert level != null;
|
||||
if (getBlockState().getValue(BlockConjured.LIGHT)) {
|
||||
level.addParticle(HexParticles.CONJURE_LIGHT_PARTICLE.get(),
|
||||
level.addParticle(new ConjureParticleOptions(color, true),
|
||||
(double) getBlockPos().getX() + 0.4D + (RANDOM.nextFloat() * 0.2D),
|
||||
(double) getBlockPos().getY() + 0.4D + (RANDOM.nextFloat() * 0.2D),
|
||||
(double) getBlockPos().getZ() + 0.4D + (RANDOM.nextFloat() * 0.2D), r, g, b);
|
||||
(double) getBlockPos().getZ() + 0.4D + (RANDOM.nextFloat() * 0.2D),
|
||||
0.0, 0.0, 0.0);
|
||||
} else {
|
||||
if (RANDOM.nextBoolean()) {
|
||||
level.addParticle(HexParticles.CONJURE_BLOCK_PARTICLE.get(),
|
||||
if (RANDOM.nextFloat() < 0.7) {
|
||||
level.addParticle(new ConjureParticleOptions(color, false),
|
||||
(double) getBlockPos().getX() + RANDOM.nextFloat(),
|
||||
(double) getBlockPos().getY() + RANDOM.nextFloat(),
|
||||
(double) getBlockPos().getZ() + RANDOM.nextFloat(), r, g, b);
|
||||
(double) getBlockPos().getZ() + RANDOM.nextFloat(),
|
||||
0.0, 0.0, 0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -76,14 +72,12 @@ public class BlockEntityConjured extends BlockEntity {
|
|||
int color = this.colorizer.getColor(entity.tickCount, entity.position()
|
||||
.add(new Vec3(RANDOM.nextFloat(), RANDOM.nextFloat(), RANDOM.nextFloat()).scale(
|
||||
RANDOM.nextFloat() * 3)));
|
||||
double r = FastColor.ARGB32.red(color) / 255d;
|
||||
double g = FastColor.ARGB32.green(color) / 255d;
|
||||
double b = FastColor.ARGB32.blue(color) / 255d;
|
||||
assert level != null;
|
||||
level.addParticle(HexParticles.CONJURE_BLOCK_PARTICLE.get(),
|
||||
level.addParticle(new ConjureParticleOptions(color, false),
|
||||
entity.getX() + (RANDOM.nextFloat() * 0.8D) - 0.2D,
|
||||
getBlockPos().getY() + (RANDOM.nextFloat() * 0.05D) + 0.95D,
|
||||
entity.getZ() + (RANDOM.nextFloat() * 0.8D) - 0.2D, r, g, b);
|
||||
entity.getZ() + (RANDOM.nextFloat() * 0.8D) - 0.2D,
|
||||
0.0, 0.0, 0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package at.petrak.hexcasting.common.casting
|
||||
|
||||
import at.petrak.hexcasting.HexMod
|
||||
import at.petrak.hexcasting.api.ParticleSpray
|
||||
import at.petrak.hexcasting.api.PatternRegistry
|
||||
import at.petrak.hexcasting.api.SpellDatum
|
||||
import at.petrak.hexcasting.common.casting.colors.FrozenColorizer
|
||||
|
@ -65,7 +66,16 @@ class CastingHarness private constructor(
|
|||
val (stack2, sideEffectsUnmut) = operator.operate(this.stack.toMutableList(), this.ctx)
|
||||
// Stick a poofy particle effect at the caster position
|
||||
val sideEffects = sideEffectsUnmut.toMutableList()
|
||||
sideEffects.add(OperatorSideEffect.Particles(this.ctx.position))
|
||||
sideEffects.add(
|
||||
OperatorSideEffect.Particles(
|
||||
ParticleSpray(
|
||||
this.ctx.caster.eyePosition.add(this.ctx.caster.lookAngle.scale(0.5)),
|
||||
this.ctx.caster.lookAngle,
|
||||
0.0,
|
||||
0.1
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
val fd = this.getFunctionalData().copy(
|
||||
stack = stack2,
|
||||
|
|
|
@ -1,20 +1,15 @@
|
|||
package at.petrak.hexcasting.common.casting
|
||||
|
||||
import at.petrak.hexcasting.api.ParticleSpray
|
||||
import at.petrak.hexcasting.api.RenderedSpell
|
||||
import at.petrak.hexcasting.api.SpellDatum
|
||||
import at.petrak.hexcasting.common.particles.HexParticles
|
||||
import at.petrak.hexcasting.common.network.HexMessages
|
||||
import at.petrak.hexcasting.common.network.MsgCastParticleAck
|
||||
import at.petrak.hexcasting.datagen.Advancements
|
||||
import com.mojang.math.Quaternion
|
||||
import com.mojang.math.Vector3f
|
||||
import net.minecraft.Util
|
||||
import net.minecraft.network.chat.TextComponent
|
||||
import net.minecraft.network.chat.TranslatableComponent
|
||||
import net.minecraft.util.Mth
|
||||
import net.minecraft.world.phys.Vec3
|
||||
import kotlin.math.acos
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
import kotlin.math.sqrt
|
||||
import net.minecraftforge.network.PacketDistributor
|
||||
import kotlin.random.Random
|
||||
import kotlin.random.nextInt
|
||||
|
||||
|
@ -46,7 +41,7 @@ sealed class OperatorSideEffect {
|
|||
override fun performEffect(harness: CastingHarness): Boolean {
|
||||
val overcastOk = harness.ctx.canOvercast
|
||||
val leftoverMana = harness.withdrawMana(this.amount, overcastOk)
|
||||
if (leftoverMana > 0 && overcastOk) {
|
||||
if (leftoverMana > 0 && !overcastOk) {
|
||||
harness.ctx.caster.sendMessage(
|
||||
TranslatableComponent("hexcasting.message.cant_overcast"),
|
||||
Util.NIL_UUID
|
||||
|
@ -56,43 +51,21 @@ sealed class OperatorSideEffect {
|
|||
}
|
||||
}
|
||||
|
||||
data class Particles(val position: Vec3, val velocity: Vec3, val fuzziness: Double, val spread: Double) :
|
||||
data class Particles(val spray: ParticleSpray) :
|
||||
OperatorSideEffect() {
|
||||
override fun performEffect(harness: CastingHarness): Boolean {
|
||||
val colorizer = harness.getColorizer()
|
||||
val pos = spray.pos
|
||||
|
||||
for (i in 0 until 20) {
|
||||
// For the colors, pick any random time to get a mix of colors
|
||||
val color = colorizer.getColor(Random.nextFloat() * 256f, Vec3.ZERO)
|
||||
|
||||
// https://math.stackexchange.com/questions/44689/how-to-find-a-random-axis-or-unit-vector-in-3d
|
||||
fun randomInCircle(maxTh: Double = Mth.TWO_PI.toDouble()): Vec3 {
|
||||
val th = Random.nextDouble(0.0, maxTh)
|
||||
val z = Random.nextDouble(-1.0, 1.0)
|
||||
return Vec3(sqrt(1.0 - z * z) * cos(th), sqrt(1.0 - z * z) * sin(th), z)
|
||||
}
|
||||
|
||||
val offset = randomInCircle().scale(fuzziness)
|
||||
val pos = position.add(offset)
|
||||
|
||||
// https://math.stackexchange.com/questions/56784/generate-a-random-direction-within-a-cone
|
||||
val northCone = randomInCircle(spread)
|
||||
val velNorm = velocity.normalize()
|
||||
val zp = Vec3(0.0, 0.0, 1.0)
|
||||
val rotAxis = velNorm.cross(zp)
|
||||
val th = acos(velNorm.dot(zp))
|
||||
val dagn = Quaternion(Vector3f(rotAxis), th.toFloat(), false)
|
||||
val velf = Vector3f(northCone)
|
||||
velf.transform(dagn)
|
||||
val vel = Vec3(velf).scale(velocity.length())
|
||||
|
||||
// TODO: this doesn't work because xyz velocity is a lie
|
||||
harness.ctx.world.addParticle(
|
||||
HexParticles.CONJURE_BLOCK_PARTICLE.get(),
|
||||
pos.x, pos.y, pos.z,
|
||||
vel.x, vel.y, vel.z,
|
||||
HexMessages.getNetwork().send(PacketDistributor.NEAR.with {
|
||||
PacketDistributor.TargetPoint(
|
||||
pos.x,
|
||||
pos.y,
|
||||
pos.z,
|
||||
128.0 * 128.0,
|
||||
harness.ctx.world.dimension()
|
||||
)
|
||||
}
|
||||
}, MsgCastParticleAck(spray, colorizer))
|
||||
|
||||
return false
|
||||
}
|
||||
|
@ -113,7 +86,7 @@ sealed class OperatorSideEffect {
|
|||
else -> {}
|
||||
}
|
||||
|
||||
return false
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
|
@ -81,8 +81,7 @@ public record FrozenColorizer(Item item, UUID owner) {
|
|||
|
||||
int baseIdx = Mth.floor(fIdx);
|
||||
float tRaw = fIdx - baseIdx;
|
||||
// float t = -(float) (Math.cbrt(Mth.cos(tRaw * Mth.PI)) / 2) + 0.5f;
|
||||
float t = tRaw;
|
||||
float t = tRaw < 0.5 ? 4 * tRaw * tRaw * tRaw : (float) (1 - Math.pow(-2 * tRaw + 2, 3) / 2);
|
||||
int start = colors[baseIdx % colors.length];
|
||||
int end = colors[(baseIdx + 1) % colors.length];
|
||||
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
package at.petrak.hexcasting.common.casting.operators
|
||||
|
||||
import at.petrak.hexcasting.api.ParticleSpray
|
||||
import at.petrak.hexcasting.api.RenderedSpell
|
||||
import at.petrak.hexcasting.api.SpellDatum
|
||||
import at.petrak.hexcasting.api.SpellOperator
|
||||
import at.petrak.hexcasting.common.casting.CastingContext
|
||||
import at.petrak.hexcasting.common.items.ItemDataHolder
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
// we make this a spell cause imo it's a little ... anticlimactic for it to just make no noise
|
||||
object OpWrite : SpellOperator {
|
||||
override val argc = 1
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): Triple<RenderedSpell, Int, List<Vec3>> {
|
||||
override fun execute(
|
||||
args: List<SpellDatum<*>>,
|
||||
ctx: CastingContext
|
||||
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
|
||||
return Triple(
|
||||
Spell(args[0]),
|
||||
0,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.spells
|
||||
|
||||
import at.petrak.hexcasting.api.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.ParticleSpray
|
||||
import at.petrak.hexcasting.api.RenderedSpell
|
||||
import at.petrak.hexcasting.api.SpellDatum
|
||||
import at.petrak.hexcasting.api.SpellOperator
|
||||
|
@ -16,13 +17,23 @@ object OpAddMotion : SpellOperator {
|
|||
override val argc: Int
|
||||
get() = 2
|
||||
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): Triple<RenderedSpell, Int, List<Vec3>> {
|
||||
override fun execute(
|
||||
args: List<SpellDatum<*>>,
|
||||
ctx: CastingContext
|
||||
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
|
||||
val target = args.getChecked<Entity>(0)
|
||||
val motion = args.getChecked<Vec3>(1)
|
||||
return Triple(
|
||||
Spell(target, motion),
|
||||
(motion.lengthSqr() * 10_000f).toInt(),
|
||||
listOf(target.position()),
|
||||
listOf(
|
||||
ParticleSpray(
|
||||
target.position().add(0.0, target.eyeHeight / 2.0, 0.0),
|
||||
motion.normalize(),
|
||||
0.0,
|
||||
0.1
|
||||
)
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.spells
|
||||
|
||||
import at.petrak.hexcasting.api.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.ParticleSpray
|
||||
import at.petrak.hexcasting.api.RenderedSpell
|
||||
import at.petrak.hexcasting.api.SpellDatum
|
||||
import at.petrak.hexcasting.api.SpellOperator
|
||||
|
@ -16,7 +17,10 @@ import kotlin.math.roundToInt
|
|||
|
||||
object OpBlink : SpellOperator {
|
||||
override val argc = 2
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): Triple<RenderedSpell, Int, List<Vec3>> {
|
||||
override fun execute(
|
||||
args: List<SpellDatum<*>>,
|
||||
ctx: CastingContext
|
||||
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
|
||||
val target = args.getChecked<Entity>(0)
|
||||
val delta = args.getChecked<Double>(1)
|
||||
|
||||
|
@ -25,10 +29,12 @@ object OpBlink : SpellOperator {
|
|||
ctx.assertVecInRange(target.position())
|
||||
ctx.assertVecInRange(target.position().add(dvec))
|
||||
|
||||
val targetMiddlePos = target.position().add(0.0, target.eyeHeight / 2.0, 0.0)
|
||||
|
||||
return Triple(
|
||||
Spell(target, delta),
|
||||
50_000 * delta.roundToInt(),
|
||||
listOf(target.position().add(dvec))
|
||||
listOf(ParticleSpray.Cloud(targetMiddlePos, 2.0), ParticleSpray.Burst(targetMiddlePos.add(dvec), 2.0))
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package at.petrak.hexcasting.common.casting.operators.spells
|
|||
|
||||
import at.petrak.hexcasting.HexMod
|
||||
import at.petrak.hexcasting.api.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.ParticleSpray
|
||||
import at.petrak.hexcasting.api.RenderedSpell
|
||||
import at.petrak.hexcasting.api.SpellDatum
|
||||
import at.petrak.hexcasting.api.SpellOperator
|
||||
|
@ -14,13 +15,18 @@ object OpBreakBlock : SpellOperator {
|
|||
override val argc: Int
|
||||
get() = 1
|
||||
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): Triple<RenderedSpell, Int, List<Vec3>> {
|
||||
override fun execute(
|
||||
args: List<SpellDatum<*>>,
|
||||
ctx: CastingContext
|
||||
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
|
||||
val pos = args.getChecked<Vec3>(0)
|
||||
ctx.assertVecInRange(pos)
|
||||
|
||||
val centered = Vec3.atCenterOf(BlockPos(pos))
|
||||
return Triple(
|
||||
Spell(pos),
|
||||
20_000,
|
||||
listOf(pos)
|
||||
listOf(ParticleSpray.Burst(centered, 1.0))
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.spells
|
||||
|
||||
import at.petrak.hexcasting.api.ParticleSpray
|
||||
import at.petrak.hexcasting.api.RenderedSpell
|
||||
import at.petrak.hexcasting.api.SpellDatum
|
||||
import at.petrak.hexcasting.api.SpellOperator
|
||||
|
@ -8,13 +9,15 @@ import at.petrak.hexcasting.common.casting.colors.FrozenColorizer
|
|||
import at.petrak.hexcasting.common.lib.HexCapabilities
|
||||
import at.petrak.hexcasting.common.network.HexMessages
|
||||
import at.petrak.hexcasting.common.network.MsgColorizerUpdateAck
|
||||
import net.minecraft.world.phys.Vec3
|
||||
import net.minecraftforge.network.PacketDistributor
|
||||
|
||||
object OpColorize : SpellOperator {
|
||||
override val argc = 0
|
||||
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): Triple<RenderedSpell, Int, List<Vec3>> {
|
||||
override fun execute(
|
||||
args: List<SpellDatum<*>>,
|
||||
ctx: CastingContext
|
||||
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
|
||||
return Triple(
|
||||
Spell,
|
||||
10_000,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.spells
|
||||
|
||||
import at.petrak.hexcasting.api.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.ParticleSpray
|
||||
import at.petrak.hexcasting.api.RenderedSpell
|
||||
import at.petrak.hexcasting.api.SpellDatum
|
||||
import at.petrak.hexcasting.api.SpellOperator
|
||||
|
@ -13,14 +14,17 @@ import net.minecraft.world.phys.Vec3
|
|||
|
||||
class OpConjure(val light: Boolean) : SpellOperator {
|
||||
override val argc = 1
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): Triple<RenderedSpell, Int, List<Vec3>> {
|
||||
override fun execute(
|
||||
args: List<SpellDatum<*>>,
|
||||
ctx: CastingContext
|
||||
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
|
||||
val target = args.getChecked<Vec3>(0)
|
||||
ctx.assertVecInRange(target)
|
||||
|
||||
return Triple(
|
||||
Spell(target, light),
|
||||
10_000,
|
||||
listOf(target)
|
||||
listOf(ParticleSpray.Cloud(Vec3.atCenterOf(BlockPos(target)), 1.0))
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package at.petrak.hexcasting.common.casting.operators.spells
|
|||
|
||||
import at.petrak.hexcasting.HexMod
|
||||
import at.petrak.hexcasting.api.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.ParticleSpray
|
||||
import at.petrak.hexcasting.api.RenderedSpell
|
||||
import at.petrak.hexcasting.api.SpellDatum
|
||||
import at.petrak.hexcasting.api.SpellOperator
|
||||
|
@ -13,14 +14,17 @@ import net.minecraft.world.phys.Vec3
|
|||
|
||||
object OpCreateWater : SpellOperator {
|
||||
override val argc = 1
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): Triple<RenderedSpell, Int, List<Vec3>> {
|
||||
override fun execute(
|
||||
args: List<SpellDatum<*>>,
|
||||
ctx: CastingContext
|
||||
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
|
||||
val target = args.getChecked<Vec3>(0)
|
||||
ctx.assertVecInRange(target)
|
||||
|
||||
return Triple(
|
||||
Spell(target),
|
||||
10_000,
|
||||
listOf(target)
|
||||
listOf(ParticleSpray.Burst(Vec3.atCenterOf(BlockPos(target)), 1.0))
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.spells
|
||||
|
||||
import at.petrak.hexcasting.api.Operator
|
||||
import at.petrak.hexcasting.api.*
|
||||
import at.petrak.hexcasting.api.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.RenderedSpell
|
||||
import at.petrak.hexcasting.api.SpellDatum
|
||||
import at.petrak.hexcasting.api.SpellOperator
|
||||
import at.petrak.hexcasting.common.casting.CastingContext
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.Direction
|
||||
|
@ -22,14 +19,17 @@ import net.minecraft.world.phys.Vec3
|
|||
|
||||
object OpDestroyWater : SpellOperator {
|
||||
override val argc = 1
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): Triple<RenderedSpell, Int, List<Vec3>> {
|
||||
override fun execute(
|
||||
args: List<SpellDatum<*>>,
|
||||
ctx: CastingContext
|
||||
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
|
||||
val target = args.getChecked<Vec3>(0)
|
||||
ctx.assertVecInRange(target)
|
||||
|
||||
return Triple(
|
||||
Spell(target),
|
||||
200_000,
|
||||
listOf(target)
|
||||
listOf(ParticleSpray.Burst(target, 3.0))
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,17 +1,20 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.spells
|
||||
|
||||
import at.petrak.hexcasting.api.ParticleSpray
|
||||
import at.petrak.hexcasting.api.RenderedSpell
|
||||
import at.petrak.hexcasting.api.SpellDatum
|
||||
import at.petrak.hexcasting.api.SpellOperator
|
||||
import at.petrak.hexcasting.common.casting.CastException
|
||||
import at.petrak.hexcasting.common.casting.CastingContext
|
||||
import at.petrak.hexcasting.common.items.magic.ItemPackagedSpell
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class OpErase : SpellOperator {
|
||||
override val argc = 0
|
||||
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): Triple<RenderedSpell, Int, List<Vec3>> {
|
||||
override fun execute(
|
||||
args: List<SpellDatum<*>>,
|
||||
ctx: CastingContext
|
||||
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
|
||||
val otherHandItem = ctx.caster.getItemInHand(ctx.otherHand)
|
||||
if (otherHandItem.item !is ItemPackagedSpell) {
|
||||
throw CastException(CastException.Reason.BAD_OFFHAND_ITEM, ItemPackagedSpell::class.java, otherHandItem)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.spells
|
||||
|
||||
import at.petrak.hexcasting.api.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.ParticleSpray
|
||||
import at.petrak.hexcasting.api.RenderedSpell
|
||||
import at.petrak.hexcasting.api.SpellDatum
|
||||
import at.petrak.hexcasting.api.SpellOperator
|
||||
|
@ -13,14 +14,17 @@ class OpExplode(val fire: Boolean) : SpellOperator {
|
|||
override val argc: Int
|
||||
get() = 2
|
||||
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): Triple<RenderedSpell, Int, List<Vec3>> {
|
||||
override fun execute(
|
||||
args: List<SpellDatum<*>>,
|
||||
ctx: CastingContext
|
||||
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
|
||||
val pos = args.getChecked<Vec3>(0)
|
||||
val strength = args.getChecked<Double>(1)
|
||||
ctx.assertVecInRange(pos)
|
||||
return Triple(
|
||||
Spell(pos, strength, this.fire),
|
||||
((1 + strength + if (this.fire) 2 else 0) * 50_000.0).toInt(),
|
||||
listOf(pos)
|
||||
listOf(ParticleSpray.Burst(pos, strength))
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.spells
|
||||
|
||||
import at.petrak.hexcasting.api.Operator
|
||||
import at.petrak.hexcasting.api.*
|
||||
import at.petrak.hexcasting.api.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.RenderedSpell
|
||||
import at.petrak.hexcasting.api.SpellDatum
|
||||
import at.petrak.hexcasting.api.SpellOperator
|
||||
import at.petrak.hexcasting.common.casting.CastingContext
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.Direction
|
||||
|
@ -21,14 +18,17 @@ import net.minecraft.world.phys.Vec3
|
|||
|
||||
object OpExtinguish : SpellOperator {
|
||||
override val argc = 1
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): Triple<RenderedSpell, Int, List<Vec3>> {
|
||||
override fun execute(
|
||||
args: List<SpellDatum<*>>,
|
||||
ctx: CastingContext
|
||||
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
|
||||
val target = args.getChecked<Vec3>(0)
|
||||
ctx.assertVecInRange(target)
|
||||
|
||||
return Triple(
|
||||
Spell(target),
|
||||
200_000,
|
||||
listOf(target)
|
||||
listOf(ParticleSpray.Burst(target, 1.0))
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -48,37 +48,58 @@ object OpExtinguish : SpellOperator {
|
|||
val distFromFocus =
|
||||
ctx.caster.position().distanceToSqr(Vec3(here.x.toDouble(), here.y.toDouble(), here.z.toDouble()))
|
||||
val distFromTarget =
|
||||
target.distanceTo(Vec3(here.x.toDouble(), here.y.toDouble(), here.z.toDouble())) // max distance to prevent runaway shenanigans
|
||||
target.distanceTo(
|
||||
Vec3(
|
||||
here.x.toDouble(),
|
||||
here.y.toDouble(),
|
||||
here.z.toDouble()
|
||||
)
|
||||
) // max distance to prevent runaway shenanigans
|
||||
if (distFromFocus < Operator.MAX_DISTANCE * Operator.MAX_DISTANCE && seen.add(here) && distFromTarget < 10) {
|
||||
// never seen this pos in my life
|
||||
val blockstate = ctx.world.getBlockState(here)
|
||||
val success =
|
||||
when (blockstate.block) {
|
||||
is BaseFireBlock -> {ctx.world.setBlock(here, Blocks.AIR.defaultBlockState(), 3); true}
|
||||
is CampfireBlock -> {if (blockstate.getValue(CampfireBlock.LIT)) { // check if campfire is lit before putting it out
|
||||
val wilson = Items.WOODEN_SHOVEL // summon shovel from the ether to do our bidding
|
||||
val hereVec = (Vec3(here.x.toDouble(), here.y.toDouble(), here.z.toDouble()))
|
||||
wilson.useOn(UseOnContext(ctx.world, null, InteractionHand.MAIN_HAND, ItemStack(wilson.asItem()), BlockHitResult(hereVec, Direction.UP, here, false))); true}
|
||||
else false}
|
||||
is AbstractCandleBlock -> {
|
||||
if (blockstate.getValue(AbstractCandleBlock.LIT)) { // same check for candles
|
||||
AbstractCandleBlock.extinguish(null, blockstate, ctx.world, here); true}
|
||||
else false}
|
||||
is NetherPortalBlock -> {ctx.world.setBlock(here, Blocks.AIR.defaultBlockState(), 3); true}
|
||||
else -> false
|
||||
}
|
||||
when (blockstate.block) {
|
||||
is BaseFireBlock -> {
|
||||
ctx.world.setBlock(here, Blocks.AIR.defaultBlockState(), 3); true
|
||||
}
|
||||
is CampfireBlock -> {
|
||||
if (blockstate.getValue(CampfireBlock.LIT)) { // check if campfire is lit before putting it out
|
||||
val wilson = Items.WOODEN_SHOVEL // summon shovel from the ether to do our bidding
|
||||
val hereVec = (Vec3(here.x.toDouble(), here.y.toDouble(), here.z.toDouble()))
|
||||
wilson.useOn(
|
||||
UseOnContext(
|
||||
ctx.world,
|
||||
null,
|
||||
InteractionHand.MAIN_HAND,
|
||||
ItemStack(wilson.asItem()),
|
||||
BlockHitResult(hereVec, Direction.UP, here, false)
|
||||
)
|
||||
); true
|
||||
} else false
|
||||
}
|
||||
is AbstractCandleBlock -> {
|
||||
if (blockstate.getValue(AbstractCandleBlock.LIT)) { // same check for candles
|
||||
AbstractCandleBlock.extinguish(null, blockstate, ctx.world, here); true
|
||||
} else false
|
||||
}
|
||||
is NetherPortalBlock -> {
|
||||
ctx.world.setBlock(here, Blocks.AIR.defaultBlockState(), 3); true
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
|
||||
if (success) {
|
||||
ctx.world.sendParticles(
|
||||
ParticleTypes.SMOKE,
|
||||
here.x + 0.5 + Math.random() * 0.4 - 0.2,
|
||||
here.y + 0.5 + Math.random() * 0.4 - 0.2,
|
||||
here.z + 0.5 + Math.random() * 0.4 - 0.2,
|
||||
2,
|
||||
0.0,
|
||||
0.05,
|
||||
0.0,
|
||||
0.0
|
||||
ParticleTypes.SMOKE,
|
||||
here.x + 0.5 + Math.random() * 0.4 - 0.2,
|
||||
here.y + 0.5 + Math.random() * 0.4 - 0.2,
|
||||
here.z + 0.5 + Math.random() * 0.4 - 0.2,
|
||||
2,
|
||||
0.0,
|
||||
0.05,
|
||||
0.0,
|
||||
0.0
|
||||
)
|
||||
successes++
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package at.petrak.hexcasting.common.casting.operators.spells
|
|||
|
||||
import at.petrak.hexcasting.HexMod
|
||||
import at.petrak.hexcasting.api.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.ParticleSpray
|
||||
import at.petrak.hexcasting.api.RenderedSpell
|
||||
import at.petrak.hexcasting.api.SpellDatum
|
||||
import at.petrak.hexcasting.api.SpellOperator
|
||||
|
@ -18,14 +19,17 @@ import net.minecraft.world.phys.Vec3
|
|||
|
||||
object OpIgnite : SpellOperator {
|
||||
override val argc = 1
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): Triple<RenderedSpell, Int, List<Vec3>> {
|
||||
override fun execute(
|
||||
args: List<SpellDatum<*>>,
|
||||
ctx: CastingContext
|
||||
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
|
||||
val target = args.getChecked<Vec3>(0)
|
||||
ctx.assertVecInRange(target)
|
||||
|
||||
return Triple(
|
||||
Spell(target),
|
||||
10_000,
|
||||
listOf(target)
|
||||
listOf(ParticleSpray.Burst(Vec3.atCenterOf(BlockPos(target)), 1.0))
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -35,7 +39,15 @@ object OpIgnite : SpellOperator {
|
|||
val maxwell = Items.FIRE_CHARGE
|
||||
if (maxwell is FireChargeItem) {
|
||||
// help
|
||||
maxwell.useOn(UseOnContext(ctx.world, null, InteractionHand.MAIN_HAND, ItemStack(maxwell.asItem()), BlockHitResult(target, Direction.UP, BlockPos(target), false)))
|
||||
maxwell.useOn(
|
||||
UseOnContext(
|
||||
ctx.world,
|
||||
null,
|
||||
InteractionHand.MAIN_HAND,
|
||||
ItemStack(maxwell.asItem()),
|
||||
BlockHitResult(target, Direction.UP, BlockPos(target), false)
|
||||
)
|
||||
)
|
||||
} else {
|
||||
HexMod.getLogger().warn("Items.FIRE_CHARGE wasn't a FireChargeItem?")
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.spells
|
||||
|
||||
import at.petrak.hexcasting.api.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.ParticleSpray
|
||||
import at.petrak.hexcasting.api.RenderedSpell
|
||||
import at.petrak.hexcasting.api.SpellDatum
|
||||
import at.petrak.hexcasting.api.SpellOperator
|
||||
|
@ -12,11 +13,13 @@ import at.petrak.hexcasting.common.items.magic.ItemManaHolder
|
|||
import net.minecraft.world.entity.item.ItemEntity
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.Items
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
object OpMakeBattery : SpellOperator {
|
||||
override val argc = 1
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): Triple<RenderedSpell, Int, List<Vec3>> {
|
||||
override fun execute(
|
||||
args: List<SpellDatum<*>>,
|
||||
ctx: CastingContext
|
||||
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
|
||||
val otherHandItem = ctx.caster.getItemInHand(ctx.otherHand)
|
||||
if (otherHandItem.item != Items.GLASS_BOTTLE) {
|
||||
throw CastException(CastException.Reason.BAD_OFFHAND_ITEM_ITEM, Items.GLASS_BOTTLE, otherHandItem)
|
||||
|
@ -27,7 +30,7 @@ object OpMakeBattery : SpellOperator {
|
|||
|
||||
val entity = args.getChecked<ItemEntity>(0)
|
||||
|
||||
return Triple(Spell(entity), 100_000, listOf(entity.position()))
|
||||
return Triple(Spell(entity), 100_000, listOf(ParticleSpray.Burst(entity.position(), 0.5)))
|
||||
}
|
||||
|
||||
private data class Spell(val itemEntity: ItemEntity) : RenderedSpell {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.spells
|
||||
|
||||
import at.petrak.hexcasting.api.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.ParticleSpray
|
||||
import at.petrak.hexcasting.api.RenderedSpell
|
||||
import at.petrak.hexcasting.api.SpellDatum
|
||||
import at.petrak.hexcasting.api.SpellOperator
|
||||
|
@ -11,11 +12,13 @@ import at.petrak.hexcasting.common.items.magic.ItemPackagedSpell
|
|||
import at.petrak.hexcasting.hexmath.HexPattern
|
||||
import net.minecraft.nbt.ListTag
|
||||
import net.minecraft.world.entity.item.ItemEntity
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class OpMakePackagedSpell<T : ItemPackagedSpell>(val type: Class<T>, val cost: Int) : SpellOperator {
|
||||
override val argc = 2
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): Triple<RenderedSpell, Int, List<Vec3>> {
|
||||
override fun execute(
|
||||
args: List<SpellDatum<*>>,
|
||||
ctx: CastingContext
|
||||
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
|
||||
val otherHandItem = ctx.caster.getItemInHand(ctx.otherHand)
|
||||
if (!type.isAssignableFrom(otherHandItem.item.javaClass)) {
|
||||
throw CastException(CastException.Reason.BAD_OFFHAND_ITEM, type, otherHandItem)
|
||||
|
@ -24,7 +27,7 @@ class OpMakePackagedSpell<T : ItemPackagedSpell>(val type: Class<T>, val cost: I
|
|||
val entity = args.getChecked<ItemEntity>(0)
|
||||
val patterns = args.getChecked<List<SpellDatum<*>>>(1).map { it.tryGet<HexPattern>() }
|
||||
|
||||
return Triple(Spell(entity, patterns), cost, listOf(entity.position()))
|
||||
return Triple(Spell(entity, patterns), cost, listOf(ParticleSpray.Burst(entity.position(), 0.5)))
|
||||
}
|
||||
|
||||
private data class Spell(val itemEntity: ItemEntity, val patterns: List<HexPattern>) : RenderedSpell {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.spells
|
||||
|
||||
import at.petrak.hexcasting.api.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.ParticleSpray
|
||||
import at.petrak.hexcasting.api.RenderedSpell
|
||||
import at.petrak.hexcasting.api.SpellDatum
|
||||
import at.petrak.hexcasting.api.SpellOperator
|
||||
|
@ -22,13 +23,16 @@ object OpPlaceBlock : SpellOperator {
|
|||
override val argc: Int
|
||||
get() = 1
|
||||
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): Triple<RenderedSpell, Int, List<Vec3>> {
|
||||
override fun execute(
|
||||
args: List<SpellDatum<*>>,
|
||||
ctx: CastingContext
|
||||
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
|
||||
val pos = args.getChecked<Vec3>(0)
|
||||
ctx.assertVecInRange(pos)
|
||||
return Triple(
|
||||
Spell(pos),
|
||||
10_000,
|
||||
listOf(pos)
|
||||
listOf(ParticleSpray.Cloud(Vec3.atCenterOf(BlockPos(pos)), 1.0))
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.spells
|
||||
|
||||
import at.petrak.hexcasting.api.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.ParticleSpray
|
||||
import at.petrak.hexcasting.api.RenderedSpell
|
||||
import at.petrak.hexcasting.api.SpellDatum
|
||||
import at.petrak.hexcasting.api.SpellOperator
|
||||
|
@ -8,14 +9,16 @@ import at.petrak.hexcasting.common.casting.CastingContext
|
|||
import net.minecraft.world.effect.MobEffect
|
||||
import net.minecraft.world.effect.MobEffectInstance
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.phys.Vec3
|
||||
import kotlin.math.max
|
||||
|
||||
class OpPotionEffect(val effect: MobEffect, val baseCost: Int, val potency: Boolean) : SpellOperator {
|
||||
override val argc: Int
|
||||
get() = if (this.potency) 3 else 2
|
||||
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): Triple<RenderedSpell, Int, List<Vec3>> {
|
||||
override fun execute(
|
||||
args: List<SpellDatum<*>>,
|
||||
ctx: CastingContext
|
||||
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
|
||||
val target = args.getChecked<LivingEntity>(0)
|
||||
val duration = max(args.getChecked(1), 0.0)
|
||||
val potency = if (this.potency)
|
||||
|
@ -26,7 +29,7 @@ class OpPotionEffect(val effect: MobEffect, val baseCost: Int, val potency: Bool
|
|||
return Triple(
|
||||
Spell(effect, target, duration, potency),
|
||||
cost.toInt(),
|
||||
listOf(target.position())
|
||||
listOf(ParticleSpray.Cloud(target.position().add(0.0, target.eyeHeight / 2.0, 0.0), 1.0))
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.spells
|
||||
|
||||
import at.petrak.hexcasting.api.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.ParticleSpray
|
||||
import at.petrak.hexcasting.api.RenderedSpell
|
||||
import at.petrak.hexcasting.api.SpellDatum
|
||||
import at.petrak.hexcasting.api.SpellOperator
|
||||
|
@ -10,11 +11,13 @@ import at.petrak.hexcasting.common.casting.ManaHelper
|
|||
import at.petrak.hexcasting.common.items.magic.ItemManaHolder
|
||||
import net.minecraft.util.Mth
|
||||
import net.minecraft.world.entity.item.ItemEntity
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
object OpRecharge : SpellOperator {
|
||||
override val argc = 1
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): Triple<RenderedSpell, Int, List<Vec3>> {
|
||||
override fun execute(
|
||||
args: List<SpellDatum<*>>,
|
||||
ctx: CastingContext
|
||||
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
|
||||
val otherHandItem = ctx.caster.getItemInHand(ctx.otherHand)
|
||||
if (otherHandItem.item !is ItemManaHolder) {
|
||||
throw CastException(CastException.Reason.BAD_OFFHAND_ITEM, ItemManaHolder::class.java, otherHandItem)
|
||||
|
@ -22,7 +25,7 @@ object OpRecharge : SpellOperator {
|
|||
|
||||
val entity = args.getChecked<ItemEntity>(0)
|
||||
|
||||
return Triple(Spell(entity), 100_000, listOf(entity.position()))
|
||||
return Triple(Spell(entity), 100_000, listOf(ParticleSpray.Burst(entity.position(), 0.5)))
|
||||
}
|
||||
|
||||
private data class Spell(val itemEntity: ItemEntity) : RenderedSpell {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.spells
|
||||
|
||||
import at.petrak.hexcasting.api.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.ParticleSpray
|
||||
import at.petrak.hexcasting.api.RenderedSpell
|
||||
import at.petrak.hexcasting.api.SpellDatum
|
||||
import at.petrak.hexcasting.api.SpellOperator
|
||||
|
@ -17,14 +18,17 @@ import net.minecraft.world.phys.Vec3
|
|||
|
||||
object OpTheOnlyReasonAnyoneDownloadedPsi : SpellOperator {
|
||||
override val argc = 1
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): Triple<RenderedSpell, Int, List<Vec3>> {
|
||||
override fun execute(
|
||||
args: List<SpellDatum<*>>,
|
||||
ctx: CastingContext
|
||||
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
|
||||
val target = args.getChecked<Vec3>(0)
|
||||
ctx.assertVecInRange(target)
|
||||
|
||||
return Triple(
|
||||
Spell(target),
|
||||
10_000,
|
||||
listOf(target)
|
||||
listOf(ParticleSpray.Burst(Vec3.atCenterOf(BlockPos(target)), 1.0))
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package at.petrak.hexcasting.common.casting.operators.spells.great
|
|||
|
||||
import at.petrak.hexcasting.HexMod
|
||||
import at.petrak.hexcasting.api.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.ParticleSpray
|
||||
import at.petrak.hexcasting.api.RenderedSpell
|
||||
import at.petrak.hexcasting.api.SpellDatum
|
||||
import at.petrak.hexcasting.api.SpellOperator
|
||||
|
@ -14,14 +15,17 @@ import net.minecraft.world.phys.Vec3
|
|||
object OpCreateLava : SpellOperator {
|
||||
override val argc = 1
|
||||
override val isGreat = true
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): Triple<RenderedSpell, Int, List<Vec3>> {
|
||||
override fun execute(
|
||||
args: List<SpellDatum<*>>,
|
||||
ctx: CastingContext
|
||||
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
|
||||
val target = args.getChecked<Vec3>(0)
|
||||
ctx.assertVecInRange(target)
|
||||
|
||||
return Triple(
|
||||
Spell(target),
|
||||
100_000,
|
||||
listOf(target),
|
||||
listOf(ParticleSpray.Burst(Vec3.atCenterOf(BlockPos(target)), 1.0)),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package at.petrak.hexcasting.common.casting.operators.spells.great
|
|||
import at.petrak.hexcasting.HexUtils
|
||||
import at.petrak.hexcasting.HexUtils.serializeToNBT
|
||||
import at.petrak.hexcasting.api.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.ParticleSpray
|
||||
import at.petrak.hexcasting.api.RenderedSpell
|
||||
import at.petrak.hexcasting.api.SpellDatum
|
||||
import at.petrak.hexcasting.api.SpellOperator
|
||||
|
@ -26,7 +27,10 @@ import kotlin.math.roundToInt
|
|||
object OpFlight : SpellOperator {
|
||||
override val argc = 3
|
||||
override val isGreat = true
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): Triple<RenderedSpell, Int, List<Vec3>> {
|
||||
override fun execute(
|
||||
args: List<SpellDatum<*>>,
|
||||
ctx: CastingContext
|
||||
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
|
||||
val target = args.getChecked<ServerPlayer>(0)
|
||||
val timeRaw = max(args.getChecked(1), 0.0)
|
||||
val radiusRaw = max(args.getChecked(2), 0.0)
|
||||
|
@ -36,7 +40,7 @@ object OpFlight : SpellOperator {
|
|||
return Triple(
|
||||
Spell(target, time, radiusRaw, ctx.position),
|
||||
10_000 * (timeRaw * radiusRaw + 1.0).roundToInt(),
|
||||
listOf()
|
||||
listOf(ParticleSpray(target.position(), Vec3(0.0, 2.0, 0.0), 0.0, 0.1))
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.spells.great
|
||||
|
||||
import at.petrak.hexcasting.api.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.ParticleSpray
|
||||
import at.petrak.hexcasting.api.RenderedSpell
|
||||
import at.petrak.hexcasting.api.SpellDatum
|
||||
import at.petrak.hexcasting.api.SpellOperator
|
||||
|
@ -13,13 +14,16 @@ object OpLightning : SpellOperator {
|
|||
override val argc = 1
|
||||
override val isGreat = true
|
||||
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): Triple<RenderedSpell, Int, List<Vec3>> {
|
||||
override fun execute(
|
||||
args: List<SpellDatum<*>>,
|
||||
ctx: CastingContext
|
||||
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
|
||||
val target = args.getChecked<Vec3>(0)
|
||||
ctx.assertVecInRange(target)
|
||||
return Triple(
|
||||
Spell(target),
|
||||
150_000,
|
||||
listOf(target)
|
||||
listOf(ParticleSpray(target.add(0.0, 2.0, 0.0), Vec3(0.0, -1.0, 0.0), 0.5, 0.1))
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.spells.great
|
||||
|
||||
import at.petrak.hexcasting.api.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.ParticleSpray
|
||||
import at.petrak.hexcasting.api.RenderedSpell
|
||||
import at.petrak.hexcasting.api.SpellDatum
|
||||
import at.petrak.hexcasting.api.SpellOperator
|
||||
|
@ -15,15 +16,20 @@ import net.minecraftforge.network.PacketDistributor
|
|||
object OpTeleport : SpellOperator {
|
||||
override val argc = 2
|
||||
override val isGreat = true
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): Triple<RenderedSpell, Int, List<Vec3>> {
|
||||
override fun execute(
|
||||
args: List<SpellDatum<*>>,
|
||||
ctx: CastingContext
|
||||
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
|
||||
val teleportee = args.getChecked<Entity>(0)
|
||||
val delta = args.getChecked<Vec3>(1)
|
||||
|
||||
ctx.assertVecInRange(teleportee.position())
|
||||
|
||||
val targetMiddlePos = teleportee.position().add(0.0, teleportee.eyeHeight / 2.0, 0.0)
|
||||
|
||||
return Triple(
|
||||
Spell(teleportee, delta),
|
||||
1_000_000,
|
||||
listOf(teleportee.position().add(delta))
|
||||
listOf(ParticleSpray.Cloud(targetMiddlePos, 2.0), ParticleSpray.Burst(targetMiddlePos.add(delta), 2.0))
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,19 +1,24 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.spells.great
|
||||
|
||||
import at.petrak.hexcasting.api.OperationResult
|
||||
import at.petrak.hexcasting.api.ParticleSpray
|
||||
import at.petrak.hexcasting.api.RenderedSpell
|
||||
import at.petrak.hexcasting.api.SpellDatum
|
||||
import at.petrak.hexcasting.api.SpellOperator
|
||||
import at.petrak.hexcasting.common.casting.CastingContext
|
||||
import at.petrak.hexcasting.common.casting.OperatorSideEffect
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class OpWeather(val rain: Boolean) : SpellOperator {
|
||||
override val argc = 0
|
||||
override val isGreat = true
|
||||
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): Triple<RenderedSpell, Int, List<Vec3>> {
|
||||
return Triple(Spell(rain), ((if (this.rain) 2 else 1) * 50_000), listOf()) // return an empty list for shits and gigs ig
|
||||
override fun execute(
|
||||
args: List<SpellDatum<*>>,
|
||||
ctx: CastingContext
|
||||
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
|
||||
return Triple(
|
||||
Spell(rain),
|
||||
((if (this.rain) 2 else 1) * 50_000),
|
||||
listOf()
|
||||
)
|
||||
}
|
||||
|
||||
private data class Spell(val rain: Boolean) : RenderedSpell {
|
||||
|
@ -24,20 +29,4 @@ class OpWeather(val rain: Boolean) : SpellOperator {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun operate(stack: MutableList<SpellDatum<*>>, ctx: CastingContext): OperationResult {
|
||||
val args = stack.takeLast(this.argc)
|
||||
for (_i in 0 until this.argc) stack.removeLast()
|
||||
val (spell, mana, particlePoses) = this.execute(args, ctx)
|
||||
|
||||
val sideEffects = mutableListOf(
|
||||
OperatorSideEffect.ConsumeMana(mana),
|
||||
OperatorSideEffect.AttemptSpell(spell, this.isGreat)
|
||||
)
|
||||
for (pos in particlePoses) {
|
||||
sideEffects.add(OperatorSideEffect.Particles(pos))
|
||||
}
|
||||
|
||||
return OperationResult(stack, sideEffects)
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.spells.sentinel
|
||||
|
||||
import at.petrak.hexcasting.api.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.ParticleSpray
|
||||
import at.petrak.hexcasting.api.RenderedSpell
|
||||
import at.petrak.hexcasting.api.SpellDatum
|
||||
import at.petrak.hexcasting.api.SpellOperator
|
||||
|
@ -13,14 +14,17 @@ import net.minecraftforge.network.PacketDistributor
|
|||
|
||||
class OpCreateSentinel(val extendsRange: Boolean) : SpellOperator {
|
||||
override val argc = 1
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): Triple<RenderedSpell, Int, List<Vec3>> {
|
||||
override fun execute(
|
||||
args: List<SpellDatum<*>>,
|
||||
ctx: CastingContext
|
||||
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
|
||||
val target = args.getChecked<Vec3>(0)
|
||||
ctx.assertVecInRange(target)
|
||||
|
||||
return Triple(
|
||||
Spell(target, this.extendsRange),
|
||||
10_000,
|
||||
listOf(target)
|
||||
listOf(ParticleSpray.Burst(target, 2.0))
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.spells.sentinel
|
||||
|
||||
import at.petrak.hexcasting.api.ParticleSpray
|
||||
import at.petrak.hexcasting.api.RenderedSpell
|
||||
import at.petrak.hexcasting.api.SpellDatum
|
||||
import at.petrak.hexcasting.api.SpellOperator
|
||||
|
@ -7,16 +8,22 @@ import at.petrak.hexcasting.common.casting.CastingContext
|
|||
import at.petrak.hexcasting.common.lib.HexCapabilities
|
||||
import at.petrak.hexcasting.common.network.HexMessages
|
||||
import at.petrak.hexcasting.common.network.MsgSentinelStatusUpdateAck
|
||||
import net.minecraft.world.phys.Vec3
|
||||
import net.minecraftforge.network.PacketDistributor
|
||||
|
||||
object OpDestroySentinel : SpellOperator {
|
||||
override val argc = 0
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): Triple<RenderedSpell, Int, List<Vec3>> {
|
||||
override fun execute(
|
||||
args: List<SpellDatum<*>>,
|
||||
ctx: CastingContext
|
||||
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
|
||||
val particles = mutableListOf<ParticleSpray>()
|
||||
val maybeCap = ctx.caster.getCapability(HexCapabilities.SENTINEL).resolve()
|
||||
maybeCap.ifPresent { particles.add(ParticleSpray.Cloud(it.position, 2.0)) }
|
||||
|
||||
return Triple(
|
||||
Spell,
|
||||
1_000,
|
||||
listOf()
|
||||
particles
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -37,5 +37,7 @@ public class HexMessages {
|
|||
MsgSentinelStatusUpdateAck::deserialize, MsgSentinelStatusUpdateAck::handle);
|
||||
NETWORK.registerMessage(messageIdx++, MsgColorizerUpdateAck.class, MsgColorizerUpdateAck::serialize,
|
||||
MsgColorizerUpdateAck::deserialize, MsgColorizerUpdateAck::handle);
|
||||
NETWORK.registerMessage(messageIdx++, MsgCastParticleAck.class, MsgCastParticleAck::serialize,
|
||||
MsgCastParticleAck::deserialize, MsgCastParticleAck::handle);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
package at.petrak.hexcasting.common.network;
|
||||
|
||||
import at.petrak.hexcasting.api.ParticleSpray;
|
||||
import at.petrak.hexcasting.common.casting.colors.FrozenColorizer;
|
||||
import at.petrak.hexcasting.common.particles.ConjureParticleOptions;
|
||||
import com.mojang.math.Quaternion;
|
||||
import com.mojang.math.Vector3f;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
import net.minecraftforge.network.NetworkEvent;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Sent server->client to spray particles everywhere.
|
||||
*/
|
||||
public record MsgCastParticleAck(ParticleSpray spray, FrozenColorizer colorizer) {
|
||||
private static final Random RANDOM = new Random();
|
||||
|
||||
public static MsgCastParticleAck deserialize(ByteBuf buffer) {
|
||||
var buf = new FriendlyByteBuf(buffer);
|
||||
var posX = buf.readDouble();
|
||||
var posY = buf.readDouble();
|
||||
var posZ = buf.readDouble();
|
||||
var velX = buf.readDouble();
|
||||
var velY = buf.readDouble();
|
||||
var velZ = buf.readDouble();
|
||||
var fuzziness = buf.readDouble();
|
||||
var spread = buf.readDouble();
|
||||
var tag = buf.readAnySizeNbt();
|
||||
var colorizer = FrozenColorizer.deserialize(tag);
|
||||
return new MsgCastParticleAck(
|
||||
new ParticleSpray(new Vec3(posX, posY, posZ), new Vec3(velX, velY, velZ), fuzziness, spread), colorizer);
|
||||
}
|
||||
|
||||
public void serialize(ByteBuf buffer) {
|
||||
var buf = new FriendlyByteBuf(buffer);
|
||||
buf.writeDouble(this.spray.getPos().x);
|
||||
buf.writeDouble(this.spray.getPos().y);
|
||||
buf.writeDouble(this.spray.getPos().z);
|
||||
buf.writeDouble(this.spray.getVel().x);
|
||||
buf.writeDouble(this.spray.getVel().y);
|
||||
buf.writeDouble(this.spray.getVel().z);
|
||||
buf.writeDouble(this.spray.getFuzziness());
|
||||
buf.writeDouble(this.spray.getSpread());
|
||||
buf.writeNbt(this.colorizer.serialize());
|
||||
}
|
||||
|
||||
public void handle(Supplier<NetworkEvent.Context> ctx) {
|
||||
ctx.get().enqueueWork(() ->
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> {
|
||||
for (int i = 0; i < 20; i++) {
|
||||
// For the colors, pick any random time to get a mix of colors
|
||||
var color = colorizer.getColor(RANDOM.nextFloat() * 256f, Vec3.ZERO);
|
||||
|
||||
var offset = randomInCircle(Mth.TWO_PI).scale(spray.getSpread());
|
||||
var pos = spray.getPos().add(offset);
|
||||
|
||||
// https://math.stackexchange.com/questions/56784/generate-a-random-direction-within-a-cone
|
||||
var northCone = randomInCircle(spray.getSpread());
|
||||
var velNorm = spray.getVel().normalize();
|
||||
var zp = new Vec3(0.0, 0.0, 1.0);
|
||||
var rotAxis = velNorm.cross(zp);
|
||||
var th = Math.acos(velNorm.dot(zp));
|
||||
var dagn = new Quaternion(new Vector3f(rotAxis), (float) th, false);
|
||||
var velf = new Vector3f(northCone);
|
||||
velf.transform(dagn);
|
||||
var vel = new Vec3(velf).scale(spray.getVel().length());
|
||||
|
||||
Minecraft.getInstance().level.addParticle(
|
||||
new ConjureParticleOptions(color, false),
|
||||
pos.x, pos.y, pos.z,
|
||||
vel.x, vel.y, vel.z
|
||||
);
|
||||
}
|
||||
})
|
||||
);
|
||||
ctx.get().setPacketHandled(true);
|
||||
}
|
||||
|
||||
|
||||
// https://math.stackexchange.com/questions/44689/how-to-find-a-random-axis-or-unit-vector-in-3d
|
||||
private static Vec3 randomInCircle(double maxTh) {
|
||||
var th = RANDOM.nextDouble(0.0, maxTh + 0.001);
|
||||
var z = RANDOM.nextDouble(-1.0, 1.0);
|
||||
return new Vec3(Math.sqrt(1.0 - z * z) * Math.cos(th), Math.sqrt(1.0 - z * z) * Math.sin(th), z);
|
||||
}
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
package at.petrak.hexcasting.common.particles;
|
||||
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.particle.*;
|
||||
import net.minecraft.core.particles.SimpleParticleType;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class ConjureParticle extends TextureSheetParticle {
|
||||
private static final Random RANDOM = new Random();
|
||||
private final SpriteSet sprites;
|
||||
private final boolean light;
|
||||
|
||||
ConjureParticle(ClientLevel pLevel, double pX, double pY, double pZ, SpriteSet pSprites, boolean light) {
|
||||
super(pLevel, pX, pY, pZ, (0.5D - RANDOM.nextDouble()) * .002, 0, (0.5D - RANDOM.nextDouble()) * .002);
|
||||
this.friction = 0.96F;
|
||||
this.gravity = light ? -0.01F : 0F;
|
||||
this.speedUpWhenYMotionIsBlocked = true;
|
||||
this.sprites = pSprites;
|
||||
this.yd *= 0F;
|
||||
this.xd *= light ? 0.001f : 0.1F;
|
||||
this.zd *= light ? 0.001f : 0.1F;
|
||||
this.roll = RANDOM.nextFloat(360);
|
||||
this.oRoll = this.roll;
|
||||
this.light = light;
|
||||
this.quadSize *= light ? 0.9f : 0.75f;
|
||||
|
||||
this.lifetime = (int) ((light ? 64.0D : 32.0D) / ((Math.random() + 3f) * 0.25f));
|
||||
this.hasPhysics = false;
|
||||
this.setSpriteFromAge(pSprites);
|
||||
}
|
||||
|
||||
public @NotNull ParticleRenderType getRenderType() {
|
||||
return ParticleRenderType.PARTICLE_SHEET_TRANSLUCENT;
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
super.tick();
|
||||
this.setSpriteFromAge(this.sprites);
|
||||
if (light) this.quadSize *= 0.96f;
|
||||
}
|
||||
|
||||
public void setSpriteFromAge(@NotNull SpriteSet pSprite) {
|
||||
if (!this.removed) {
|
||||
int age = this.age * 4;
|
||||
if (age > this.lifetime) age /= 4;
|
||||
this.setSprite(pSprite.get(age, this.lifetime));
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class BlockProvider implements ParticleProvider<SimpleParticleType> {
|
||||
private final SpriteSet sprite;
|
||||
|
||||
public BlockProvider(SpriteSet pSprites) {
|
||||
this.sprite = pSprites;
|
||||
}
|
||||
|
||||
public Particle createParticle(@NotNull SimpleParticleType pType, @NotNull ClientLevel pLevel, double pX, double pY, double pZ, double pXSpeed, double pYSpeed, double pZSpeed) {
|
||||
ConjureParticle particle = new ConjureParticle(pLevel, pX, pY, pZ, this.sprite, false);
|
||||
particle.setColor((float) pXSpeed, (float) pYSpeed, (float) pZSpeed);
|
||||
return particle;
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class LightProvider implements ParticleProvider<SimpleParticleType> {
|
||||
private final SpriteSet sprite;
|
||||
|
||||
public LightProvider(SpriteSet pSprites) {
|
||||
this.sprite = pSprites;
|
||||
}
|
||||
|
||||
public Particle createParticle(@NotNull SimpleParticleType pType, @NotNull ClientLevel pLevel, double pX, double pY, double pZ, double pXSpeed, double pYSpeed, double pZSpeed) {
|
||||
ConjureParticle particle = new ConjureParticle(pLevel, pX, pY, pZ, this.sprite, true);
|
||||
particle.setColor((float) pXSpeed, (float) pYSpeed, (float) pZSpeed);
|
||||
return particle;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
package at.petrak.hexcasting.common.particles;
|
||||
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import net.minecraft.core.particles.ParticleOptions;
|
||||
import net.minecraft.core.particles.ParticleType;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public record ConjureParticleOptions(int color, boolean isLight) implements ParticleOptions {
|
||||
@Override
|
||||
public ParticleType<?> getType() {
|
||||
return (this.isLight ? HexParticles.LIGHT_PARTICLE : HexParticles.CONJURE_PARTICLE).get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToNetwork(FriendlyByteBuf buf) {
|
||||
buf.writeInt(this.color);
|
||||
buf.writeBoolean(this.isLight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String writeToString() {
|
||||
return String.format(Locale.ROOT, "%s %s", this.color, this.isLight);
|
||||
}
|
||||
|
||||
public static final Deserializer<ConjureParticleOptions> DESERIALIZER = new Deserializer<>() {
|
||||
@Override
|
||||
public ConjureParticleOptions fromCommand(ParticleType<ConjureParticleOptions> type,
|
||||
StringReader reader) throws CommandSyntaxException {
|
||||
|
||||
reader.expect(' ');
|
||||
var color = reader.readInt();
|
||||
reader.expect(' ');
|
||||
var isLight = reader.readBoolean();
|
||||
|
||||
return new ConjureParticleOptions(color, isLight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConjureParticleOptions fromNetwork(ParticleType<ConjureParticleOptions> type,
|
||||
FriendlyByteBuf buf) {
|
||||
var col = buf.readInt();
|
||||
var isLight = buf.readBoolean();
|
||||
return new ConjureParticleOptions(col, isLight);
|
||||
}
|
||||
};
|
||||
|
||||
public static class Type extends ParticleType<ConjureParticleOptions> {
|
||||
public Type(boolean pOverrideLimiter) {
|
||||
super(pOverrideLimiter, DESERIALIZER);
|
||||
}
|
||||
|
||||
public static final Codec<ConjureParticleOptions> CODEC = RecordCodecBuilder.create(
|
||||
instance -> instance.group(
|
||||
Codec.INT.fieldOf("color")
|
||||
.forGetter((ConjureParticleOptions o) -> o.color),
|
||||
Codec.BOOL.fieldOf("isLight").forGetter(ConjureParticleOptions::isLight)
|
||||
)
|
||||
.apply(instance, ConjureParticleOptions::new)
|
||||
);
|
||||
|
||||
@Override
|
||||
public Codec<ConjureParticleOptions> codec() {
|
||||
return CODEC;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,23 +1,17 @@
|
|||
package at.petrak.hexcasting.common.particles;
|
||||
|
||||
import at.petrak.hexcasting.HexMod;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.particle.FlameParticle;
|
||||
import net.minecraft.client.particle.ParticleEngine;
|
||||
import net.minecraft.core.particles.ParticleType;
|
||||
import net.minecraft.core.particles.SimpleParticleType;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.client.event.ParticleFactoryRegisterEvent;
|
||||
import net.minecraftforge.eventbus.api.EventPriority;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.registries.DeferredRegister;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
import net.minecraftforge.registries.RegistryObject;
|
||||
|
||||
public class HexParticles {
|
||||
public static final DeferredRegister<ParticleType<?>> PARTICLES = DeferredRegister.create(ForgeRegistries.PARTICLE_TYPES, HexMod.MOD_ID);
|
||||
public static final DeferredRegister<ParticleType<?>> PARTICLES = DeferredRegister.create(
|
||||
ForgeRegistries.PARTICLE_TYPES, HexMod.MOD_ID);
|
||||
|
||||
public static final RegistryObject<SimpleParticleType> CONJURE_LIGHT_PARTICLE = PARTICLES.register("conjure_light_particle", () -> new SimpleParticleType(true));
|
||||
public static final RegistryObject<SimpleParticleType> CONJURE_BLOCK_PARTICLE = PARTICLES.register("conjure_block_particle", () -> new SimpleParticleType(true));
|
||||
public static final RegistryObject<ConjureParticleOptions.Type> CONJURE_PARTICLE = PARTICLES.register(
|
||||
"conjure_block_particle", () -> new ConjureParticleOptions.Type(false));
|
||||
public static final RegistryObject<ConjureParticleOptions.Type> LIGHT_PARTICLE = PARTICLES.register(
|
||||
"conjure_light_particle", () -> new ConjureParticleOptions.Type(false));
|
||||
}
|
||||
|
|
|
@ -46,22 +46,22 @@ public class ItemModels extends ItemModelProvider {
|
|||
String[] focusTypes = new String[]{
|
||||
"empty", "entity", "double", "vec3", "widget", "list", "pattern"
|
||||
};
|
||||
for (int i = 0, stringsLength = focusTypes.length; i < stringsLength; i++) {
|
||||
String type = focusTypes[i];
|
||||
simpleItem(modLoc("focus_" + type));
|
||||
simpleItem(modLoc("focus_" + type + "_sealed"));
|
||||
getBuilder(HexItems.FOCUS.get().getRegistryName().getPath())
|
||||
.override()
|
||||
.predicate(ItemFocus.DATATYPE_PRED, -0.01f + i)
|
||||
.model(new ModelFile.UncheckedModelFile(modLoc("item/focus_" + type)))
|
||||
.end()
|
||||
.override()
|
||||
.predicate(ItemFocus.DATATYPE_PRED, -0.01f + 100 + i)
|
||||
.model(new ModelFile.UncheckedModelFile(modLoc("item/focus_" + type + "_sealed")))
|
||||
.end();
|
||||
|
||||
// For stupid bad reasons we need to do this in ascending order.
|
||||
for (int sealedIdx = 0; sealedIdx <= 1; sealedIdx++) {
|
||||
var sealed = sealedIdx == 1;
|
||||
for (int i = 0, stringsLength = focusTypes.length; i < stringsLength; i++) {
|
||||
var type = focusTypes[i];
|
||||
var name = "focus_" + type + (sealed ? "_sealed" : "");
|
||||
simpleItem(modLoc(name));
|
||||
getBuilder(HexItems.FOCUS.get().getRegistryName().getPath())
|
||||
.override()
|
||||
.predicate(ItemFocus.DATATYPE_PRED, -0.01f + i + (sealed ? 100 : 0))
|
||||
.model(new ModelFile.UncheckedModelFile(modLoc("item/" + name)))
|
||||
.end();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Pair<RegistryObject<Item>, String>[] packagers = new Pair[]{
|
||||
new Pair(HexItems.CYPHER, "cypher"),
|
||||
new Pair(HexItems.TRINKET, "trinket"),
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
"item.hexcasting.uuid_colorizer": "Soulglimmer Pigment",
|
||||
"block.hexcasting.conjured": "Conjured Block",
|
||||
"itemGroup.hexcasting": "Hexcasting",
|
||||
|
||||
|
||||
"hexcasting.subtitles.start_pattern": "Starting pattern",
|
||||
"hexcasting.subtitles.add_line": "Adding line",
|
||||
"hexcasting.subtitles.add_pattern": "Adding pattern",
|
||||
|
@ -302,6 +302,7 @@
|
|||
"hexcasting.page.focus2": "$(italic)Poison apples, poison worms./$",
|
||||
"hexcasting.page.focus3": "It occurs to me that I could conceivably store a whole list of patterns in a $(item)Focus/$, then recall them and evaluate them with $(l:patterns/meta#OpEval)$(action)Hermes' Gambit/$. This way I can cast complex spells, or parts of spells, without having to draw them over and over.$(br2)I could use this like a slightly less convenient $(l:items/hexcasting#artifact)$(item)Artifact/$, but I think I could get much better dividends by putting common \"phrases\" in a $(item)Focus/$, like the patterns for figuring out where I'm looking.",
|
||||
"hexcasting.page.focus4": "Also, if I store an entity in a $(item)Focus/$ and try to recall it after the referenced entity has died or otherwise disappeared, the $(action)Scribe's Reflection/$ will add Null to the stack instead.",
|
||||
"hexcasting.page.focus5": "Finally, it seems if I wish to protect a focus from accidentally being overwritten, I can seal it with wax by crafting it with a $(item)Honeycomb/$. Attempting to use $(action)Scribe's Gambit/$ on a sealed focus will fail.",
|
||||
|
||||
"hexcasting.entry.hexcasting": "Hexcasting Items",
|
||||
"hexcasting.page.hexcasting1": "Although the flexibility that casting _Hexes \"on the go\" with my $(l:items/staff)$(item)Staff/$ is quite helpful, it's a huge pain to have to wave it around repeatedly just to accomplish a common task. If I could save a common spell for later reuse, it would simplify things a lot-- and allow me to share my _Hexes with friends, too.",
|
||||
|
|
|
@ -1,26 +1,30 @@
|
|||
{
|
||||
"name": "hexcasting.entry.focus",
|
||||
"icon": "hexcasting:focus",
|
||||
"category": "hexcasting:items",
|
||||
"sortnum": 2,
|
||||
"advancement": "hexcasting:root",
|
||||
"pages": [
|
||||
{
|
||||
"type": "patchouli:text",
|
||||
"text": "hexcasting.page.focus1"
|
||||
},
|
||||
{
|
||||
"type": "patchouli:crafting",
|
||||
"recipe": "hexcasting:focus",
|
||||
"text": "hexcasting.page.focus2"
|
||||
},
|
||||
{
|
||||
"type": "patchouli:text",
|
||||
"text": "hexcasting.page.focus3"
|
||||
},
|
||||
{
|
||||
"type": "patchouli:text",
|
||||
"text": "hexcasting.page.focus4"
|
||||
}
|
||||
]
|
||||
"name": "hexcasting.entry.focus",
|
||||
"icon": "hexcasting:focus",
|
||||
"category": "hexcasting:items",
|
||||
"sortnum": 2,
|
||||
"advancement": "hexcasting:root",
|
||||
"pages": [
|
||||
{
|
||||
"type": "patchouli:text",
|
||||
"text": "hexcasting.page.focus1"
|
||||
},
|
||||
{
|
||||
"type": "patchouli:crafting",
|
||||
"recipe": "hexcasting:focus",
|
||||
"text": "hexcasting.page.focus2"
|
||||
},
|
||||
{
|
||||
"type": "patchouli:text",
|
||||
"text": "hexcasting.page.focus3"
|
||||
},
|
||||
{
|
||||
"type": "patchouli:text",
|
||||
"text": "hexcasting.page.focus4"
|
||||
},
|
||||
{
|
||||
"type": "patchouli:text",
|
||||
"text": "hexcasting.page.focus5"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue