diff --git a/src/generated/resources/data/create/loot_tables/blocks/cursed_bell.json b/src/generated/resources/data/create/loot_tables/blocks/cursed_bell.json new file mode 100644 index 000000000..ce719523e --- /dev/null +++ b/src/generated/resources/data/create/loot_tables/blocks/cursed_bell.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "create:cursed_bell" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/create/loot_tables/blocks/peculiar_bell.json b/src/generated/resources/data/create/loot_tables/blocks/peculiar_bell.json new file mode 100644 index 000000000..fd37d00df --- /dev/null +++ b/src/generated/resources/data/create/loot_tables/blocks/peculiar_bell.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "create:peculiar_bell" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/create/tags/blocks/brittle.json b/src/generated/resources/data/create/tags/blocks/brittle.json index 7970c3bf9..9372a9a4f 100644 --- a/src/generated/resources/data/create/tags/blocks/brittle.json +++ b/src/generated/resources/data/create/tags/blocks/brittle.json @@ -24,6 +24,8 @@ "create:pulley_magnet", "create:furnace_engine", "create:redstone_link", + "create:peculiar_bell", + "create:cursed_bell", "#minecraft:doors", "#minecraft:beds", "minecraft:flower_pot", diff --git a/src/main/java/com/simibubi/create/AllBlocks.java b/src/main/java/com/simibubi/create/AllBlocks.java index 13af7d571..82b2af2e2 100644 --- a/src/main/java/com/simibubi/create/AllBlocks.java +++ b/src/main/java/com/simibubi/create/AllBlocks.java @@ -114,7 +114,8 @@ import com.simibubi.create.content.contraptions.relays.gauge.GaugeBlock; import com.simibubi.create.content.contraptions.relays.gauge.GaugeGenerator; import com.simibubi.create.content.contraptions.relays.gearbox.GearboxBlock; import com.simibubi.create.content.curiosities.armor.CopperBacktankBlock; -import com.simibubi.create.content.curiosities.projector.ChromaticProjectorBlock; +import com.simibubi.create.content.curiosities.bell.CursedBellBlock; +import com.simibubi.create.content.curiosities.bell.PeculiarBellBlock; import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelBlock; import com.simibubi.create.content.logistics.block.belts.tunnel.BrassTunnelBlock; import com.simibubi.create.content.logistics.block.belts.tunnel.BrassTunnelCTBehaviour; @@ -1301,6 +1302,22 @@ public class AllBlocks { }) .register(); + public static final BlockEntry PECULIAR_BELL = + REGISTRATE.block("peculiar_bell", PeculiarBellBlock::new) + .initialProperties(SharedProperties::softMetal) + .tag(AllBlockTags.BRITTLE.tag) + .item() + .build() + .register(); + + public static final BlockEntry CURSED_BELL = + REGISTRATE.block("cursed_bell", CursedBellBlock::new) + .initialProperties(() -> PECULIAR_BELL.get()) + .tag(AllBlockTags.BRITTLE.tag) + .item() + .build() + .register(); + // Materials static { diff --git a/src/main/java/com/simibubi/create/AllParticleTypes.java b/src/main/java/com/simibubi/create/AllParticleTypes.java index 03726b2ef..23b3fdf0a 100644 --- a/src/main/java/com/simibubi/create/AllParticleTypes.java +++ b/src/main/java/com/simibubi/create/AllParticleTypes.java @@ -9,6 +9,8 @@ import com.simibubi.create.content.contraptions.particle.CubeParticleData; import com.simibubi.create.content.contraptions.particle.HeaterParticleData; import com.simibubi.create.content.contraptions.particle.ICustomParticleData; import com.simibubi.create.content.contraptions.particle.RotationIndicatorParticleData; +import com.simibubi.create.content.curiosities.bell.SoulBaseParticle; +import com.simibubi.create.content.curiosities.bell.SoulParticle; import com.simibubi.create.foundation.utility.Lang; import net.minecraft.client.Minecraft; @@ -31,8 +33,9 @@ public enum AllParticleTypes { CUBE(CubeParticleData::new), FLUID_PARTICLE(FluidParticleData::new), BASIN_FLUID(FluidParticleData::new), - FLUID_DRIP(FluidParticleData::new) - + FLUID_DRIP(FluidParticleData::new), + SOUL(SoulParticle.Data::new), + SOUL_BASE(SoulBaseParticle.Data::new) ; private ParticleEntry entry; diff --git a/src/main/java/com/simibubi/create/AllTileEntities.java b/src/main/java/com/simibubi/create/AllTileEntities.java index e0455c9c2..6037cb86c 100644 --- a/src/main/java/com/simibubi/create/AllTileEntities.java +++ b/src/main/java/com/simibubi/create/AllTileEntities.java @@ -119,6 +119,8 @@ import com.simibubi.create.content.contraptions.relays.gearbox.GearshiftTileEnti import com.simibubi.create.content.curiosities.armor.CopperBacktankInstance; import com.simibubi.create.content.curiosities.armor.CopperBacktankRenderer; import com.simibubi.create.content.curiosities.armor.CopperBacktankTileEntity; +import com.simibubi.create.content.curiosities.bell.CursedBellTileEntity; +import com.simibubi.create.content.curiosities.bell.PeculiarBellTileEntity; import com.simibubi.create.content.curiosities.projector.ChromaticProjectorInstance; import com.simibubi.create.content.curiosities.projector.ChromaticProjectorTileEntity; import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelInstance; @@ -658,6 +660,7 @@ public class AllTileEntities { .validBlocks(AllBlocks.ADJUSTABLE_PULSE_REPEATER) .renderer(() -> AdjustableRepeaterRenderer::new) .register(); + public static final TileEntityEntry COPPER_BACKTANK = Create.registrate() .tileEntity("copper_backtank", CopperBacktankTileEntity::new) .instance(() -> CopperBacktankInstance::new) @@ -665,5 +668,15 @@ public class AllTileEntities { .renderer(() -> CopperBacktankRenderer::new) .register(); + public static final TileEntityEntry PECULIAR_BELL = Create.registrate() + .tileEntity("peculiar_bell", PeculiarBellTileEntity::new) + .validBlocks(AllBlocks.PECULIAR_BELL) + .register(); + + public static final TileEntityEntry CURSED_BELL = Create.registrate() + .tileEntity("cursed_bell", CursedBellTileEntity::new) + .validBlocks(AllBlocks.CURSED_BELL) + .register(); + public static void register() {} } diff --git a/src/main/java/com/simibubi/create/content/curiosities/bell/AbstractBellBlock.java b/src/main/java/com/simibubi/create/content/curiosities/bell/AbstractBellBlock.java new file mode 100644 index 000000000..f9ff5c0c3 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/curiosities/bell/AbstractBellBlock.java @@ -0,0 +1,70 @@ +package com.simibubi.create.content.curiosities.bell; + +import javax.annotation.Nullable; + +import com.simibubi.create.foundation.block.ITE; + +import net.minecraft.block.BellBlock; +import net.minecraft.block.BlockState; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.Direction; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.SoundEvents; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.shapes.ISelectionContext; +import net.minecraft.util.math.shapes.VoxelShape; +import net.minecraft.util.math.shapes.VoxelShapes; +import net.minecraft.world.IBlockReader; +import net.minecraft.world.World; + +public abstract class AbstractBellBlock extends BellBlock implements ITE { + + public AbstractBellBlock(Properties properties) { + super(properties); + } + + @Override + @Nullable + public TileEntity createNewTileEntity(IBlockReader block) { + return null; + } + + protected VoxelShape getShape(BlockState state) { + return VoxelShapes.fullCube(); + } + + @Override + public VoxelShape getCollisionShape(BlockState state, IBlockReader reader, BlockPos pos, ISelectionContext selection) { + return this.getShape(state); + } + + @Override + public VoxelShape getShape(BlockState state, IBlockReader reader, BlockPos pos, ISelectionContext selection) { + return this.getShape(state); + } + + @Override + public boolean ring(World world, BlockPos pos, @Nullable Direction direction) { + if (direction == null) { + direction = world.getBlockState(pos).get(field_220133_a); + } + + if (!ringInner(world, pos, direction)) + return false; + + if (world.isRemote) + return false; + + playSound(world, pos, direction); + return true; + } + + public static void playSound(World world, BlockPos pos, Direction direction) { + world.playSound(null, pos, SoundEvents.BLOCK_BELL_USE, SoundCategory.BLOCKS, 2.0F, 1.0F); + } + + protected boolean ringInner(World world, BlockPos pos, Direction direction) { + TE te = getTileEntity(world, pos); + return te != null && te.ring(world, pos, direction); + } +} diff --git a/src/main/java/com/simibubi/create/content/curiosities/bell/AbstractBellTileEntity.java b/src/main/java/com/simibubi/create/content/curiosities/bell/AbstractBellTileEntity.java new file mode 100644 index 000000000..d024d395f --- /dev/null +++ b/src/main/java/com/simibubi/create/content/curiosities/bell/AbstractBellTileEntity.java @@ -0,0 +1,25 @@ +package com.simibubi.create.content.curiosities.bell; + +import com.simibubi.create.foundation.tileEntity.SmartTileEntity; + +import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; + +import net.minecraft.tileentity.TileEntityType; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import java.util.List; + +public abstract class AbstractBellTileEntity extends SmartTileEntity { + + public AbstractBellTileEntity(TileEntityType type) { + super(type); + } + + @Override + public void addBehaviours(List behaviours) { } + + public abstract boolean ring(World world, BlockPos pos, Direction direction); + +} diff --git a/src/main/java/com/simibubi/create/content/curiosities/bell/CursedBellBlock.java b/src/main/java/com/simibubi/create/content/curiosities/bell/CursedBellBlock.java new file mode 100644 index 000000000..9fbede200 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/curiosities/bell/CursedBellBlock.java @@ -0,0 +1,30 @@ +package com.simibubi.create.content.curiosities.bell; + +import com.simibubi.create.AllTileEntities; + +import com.simibubi.create.foundation.block.ITE; + +import net.minecraft.block.BlockState; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockReader; +import net.minecraft.world.World; + +public class CursedBellBlock extends AbstractBellBlock { + + public CursedBellBlock(Properties properties) { + super(properties); + } + + @Override + public TileEntity createTileEntity(BlockState state, IBlockReader world) { + return AllTileEntities.CURSED_BELL.create(); + } + + @Override + public Class getTileEntityClass() { + return CursedBellTileEntity.class; + } + +} diff --git a/src/main/java/com/simibubi/create/content/curiosities/bell/CursedBellTileEntity.java b/src/main/java/com/simibubi/create/content/curiosities/bell/CursedBellTileEntity.java new file mode 100644 index 000000000..e9523da48 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/curiosities/bell/CursedBellTileEntity.java @@ -0,0 +1,177 @@ +package com.simibubi.create.content.curiosities.bell; + +import java.util.ArrayList; +import java.util.List; + +import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; +import com.simibubi.create.foundation.utility.NBTHelper; + +import net.minecraft.block.BlockState; +import net.minecraft.entity.EntitySpawnPlacementRegistry; +import net.minecraft.entity.EntityType; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.tileentity.TileEntityType; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.vector.Vector3d; +import net.minecraft.world.LightType; +import net.minecraft.world.World; +import net.minecraft.world.spawner.WorldEntitySpawner; + +public class CursedBellTileEntity extends AbstractBellTileEntity { + + public static final int MAX_DISTANCE = 6; + private static final List> LAYERS = genLayers(); + + public enum Mode { + RUNNING, RECHARGING + } + + public static final int RECHARGE_TICKS = 16; + public static final int TICKS_PER_LAYER = 3; + public int ticks; + public Mode mode = Mode.RECHARGING; + + public CursedBellTileEntity(TileEntityType type) { + super(type); + } + + @Override + public void addBehaviours(List behaviours) { } + + @Override + protected void fromTag(BlockState state, CompoundNBT compound, boolean clientPacket) { + ticks = compound.getInt("Ticks"); + mode = NBTHelper.readEnum(compound, "Mode", Mode.class); + } + + @Override + public void write(CompoundNBT compound, boolean clientPacket) { + compound.putInt("Ticks", ticks); + NBTHelper.writeEnum(compound, "Mode", mode); + } + + @Override + public void tick() { + super.tick(); + + switch (mode) { + case RECHARGING: + if (ticks > 0) + ticks--; + break; + + case RUNNING: + if (ticks <= 0) + break; + + ticks--; + if (ticks % TICKS_PER_LAYER == 0) { + while (!trySpawnSouls(world, pos, MAX_DISTANCE - ticks / TICKS_PER_LAYER - 1) + && ticks > 0) { + ticks -= TICKS_PER_LAYER; + } + + if (ticks == 0) { + ticks = RECHARGE_TICKS; + mode = Mode.RECHARGING; + } + } + + break; + } + } + + public boolean tryStart() { + if (mode != Mode.RECHARGING || ticks > 0) + return false; + + ticks = TICKS_PER_LAYER*MAX_DISTANCE; + mode = Mode.RUNNING; + if (!world.isRemote) + sendData(); + + return true; + } + + @Override + public boolean ring(World world, BlockPos pos, Direction direction) { + return tryStart(); + } + + public static boolean trySpawnSouls(World world, BlockPos at, int layerIdx) { + if (world == null) + return false; + + boolean spawnedAny = false; + List layer = LAYERS.get(layerIdx); + for (BlockPos candidate : layer) { + candidate = candidate.add(at); + + if (!WorldEntitySpawner.canCreatureTypeSpawnAtLocation( + EntitySpawnPlacementRegistry.PlacementType.ON_GROUND, + world, candidate, EntityType.ZOMBIE)) + continue; + + if (world.getLightLevel(LightType.BLOCK, candidate) >= 8) + continue; + + if (!world.isRemote) + return true; + spawnedAny = true; + spawnParticles(world, candidate); + } + return spawnedAny; + } + + public static void spawnParticles(World world, BlockPos at) { + if (world == null || !world.isRemote) + return; + + Vector3d p = Vector3d.of(at); + world.addParticle(new SoulParticle.Data(), p.x + 0.5, p.y + 0.5, p.z + 0.5, 0, 0, 0); + world.addParticle(new SoulBaseParticle.Data(), p.x + 0.5, p.y + 0.01, p.z + 0.5, 0, 0, 0); + } + + private static List> genLayers() { + List> layers = new ArrayList<>(); + for (int i = 0; i < MAX_DISTANCE; i++) + layers.add(new ArrayList<>()); + + for (int x = 0; x < MAX_DISTANCE; x++) { + for (int y = 0; y < MAX_DISTANCE; y++) { + for (int z = 0; z < MAX_DISTANCE; z++) { + BlockPos candidate = new BlockPos(x,y,z); + int dist = 1 + (int)Math.sqrt(candidate.distanceSq(0,0,0,false)); + if (dist == 0 || dist > MAX_DISTANCE) + continue; + + List layer = layers.get(dist - 1); + int start = layer.size(), end = start + 1; + layer.add(candidate); + + if (candidate.getX() != 0) { + layer.add(new BlockPos(-candidate.getX(), candidate.getY(), candidate.getZ())); + end += 1; + } + if (candidate.getY() != 0) { + for (int i = start; i < end; i++) { + BlockPos prev = layer.get(i); + layer.add(new BlockPos(prev.getX(), -prev.getY(), prev.getZ())); + } + end += end - start; + } + if (candidate.getZ() != 0) { + for (int i = start; i < end; i++) { + BlockPos prev = layer.get(i); + layer.add(new BlockPos(prev.getX(), prev.getY(), -prev.getZ())); + } + } + } + } + } + + return layers; + } + +} diff --git a/src/main/java/com/simibubi/create/content/curiosities/bell/CustomRotationParticle.java b/src/main/java/com/simibubi/create/content/curiosities/bell/CustomRotationParticle.java new file mode 100644 index 000000000..224c1f3a6 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/curiosities/bell/CustomRotationParticle.java @@ -0,0 +1,57 @@ +package com.simibubi.create.content.curiosities.bell; + +import com.mojang.blaze3d.vertex.IVertexBuilder; + +import net.minecraft.client.particle.IAnimatedSprite; +import net.minecraft.client.particle.SimpleAnimatedParticle; +import net.minecraft.client.renderer.ActiveRenderInfo; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.vector.Quaternion; +import net.minecraft.util.math.vector.Vector3d; +import net.minecraft.util.math.vector.Vector3f; + +public class CustomRotationParticle extends SimpleAnimatedParticle { + + public CustomRotationParticle(ClientWorld worldIn, double x, double y, double z, IAnimatedSprite spriteSet, float yAccel) { + super(worldIn, x, y, z, spriteSet, yAccel); + } + + public Quaternion getCustomRotation(ActiveRenderInfo camera, float partialTicks) { + Quaternion quaternion = new Quaternion(camera.getRotation()); + if (this.particleAngle != 0.0F) { + float angle = MathHelper.lerp(partialTicks, this.prevParticleAngle, this.particleAngle); + quaternion.multiply(Vector3f.POSITIVE_Z.getRadialQuaternion(angle)); + } + return quaternion; + } + + @Override + public void buildGeometry(IVertexBuilder builder, ActiveRenderInfo camera, float partialTicks) { + Vector3d cameraPos = camera.getProjectedView(); + float originX = (float)(MathHelper.lerp(partialTicks, this.prevPosX, this.posX) - cameraPos.getX()); + float originY = (float)(MathHelper.lerp(partialTicks, this.prevPosY, this.posY) - cameraPos.getY()); + float originZ = (float)(MathHelper.lerp(partialTicks, this.prevPosZ, this.posZ) - cameraPos.getZ()); + + Vector3f[] vertices = new Vector3f[]{new Vector3f(-1.0F, -1.0F, 0.0F), new Vector3f(-1.0F, 1.0F, 0.0F), new Vector3f(1.0F, 1.0F, 0.0F), new Vector3f(1.0F, -1.0F, 0.0F)}; + float scale = this.getScale(partialTicks); + + Quaternion rotation = getCustomRotation(camera, partialTicks); + for(int i = 0; i < 4; ++i) { + Vector3f vertex = vertices[i]; + vertex.func_214905_a(rotation); + vertex.mul(scale); + vertex.add(originX, originY, originZ); + } + + float minU = this.getMinU(); + float maxU = this.getMaxU(); + float minV = this.getMinV(); + float maxV = this.getMaxV(); + int brightness = this.getBrightnessForRender(partialTicks); + builder.vertex(vertices[0].getX(), vertices[0].getY(), vertices[0].getZ()).texture(maxU, maxV).color(this.particleRed, this.particleGreen, this.particleBlue, this.particleAlpha).light(brightness).endVertex(); + builder.vertex(vertices[1].getX(), vertices[1].getY(), vertices[1].getZ()).texture(maxU, minV).color(this.particleRed, this.particleGreen, this.particleBlue, this.particleAlpha).light(brightness).endVertex(); + builder.vertex(vertices[2].getX(), vertices[2].getY(), vertices[2].getZ()).texture(minU, minV).color(this.particleRed, this.particleGreen, this.particleBlue, this.particleAlpha).light(brightness).endVertex(); + builder.vertex(vertices[3].getX(), vertices[3].getY(), vertices[3].getZ()).texture(minU, maxV).color(this.particleRed, this.particleGreen, this.particleBlue, this.particleAlpha).light(brightness).endVertex(); + } +} diff --git a/src/main/java/com/simibubi/create/content/curiosities/bell/PeculiarBellBlock.java b/src/main/java/com/simibubi/create/content/curiosities/bell/PeculiarBellBlock.java new file mode 100644 index 000000000..0c79bad5a --- /dev/null +++ b/src/main/java/com/simibubi/create/content/curiosities/bell/PeculiarBellBlock.java @@ -0,0 +1,29 @@ +package com.simibubi.create.content.curiosities.bell; + +import com.simibubi.create.AllTileEntities; +import com.simibubi.create.foundation.block.ITE; + +import net.minecraft.block.BlockState; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.shapes.VoxelShape; +import net.minecraft.util.math.shapes.VoxelShapes; +import net.minecraft.world.IBlockReader; +import net.minecraft.world.World; + +public class PeculiarBellBlock extends AbstractBellBlock { + + public PeculiarBellBlock(Properties properties) { + super(properties); + } + + @Override + public TileEntity createTileEntity(BlockState state, IBlockReader world) { + return AllTileEntities.PECULIAR_BELL.create(); + } + + @Override + public Class getTileEntityClass() { return PeculiarBellTileEntity.class; } + +} diff --git a/src/main/java/com/simibubi/create/content/curiosities/bell/PeculiarBellTileEntity.java b/src/main/java/com/simibubi/create/content/curiosities/bell/PeculiarBellTileEntity.java new file mode 100644 index 000000000..fa0a16e3e --- /dev/null +++ b/src/main/java/com/simibubi/create/content/curiosities/bell/PeculiarBellTileEntity.java @@ -0,0 +1,19 @@ +package com.simibubi.create.content.curiosities.bell; + +import net.minecraft.tileentity.TileEntityType; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +public class PeculiarBellTileEntity extends AbstractBellTileEntity { + + public PeculiarBellTileEntity(TileEntityType type) { + super(type); + } + + @Override + public boolean ring(World world, BlockPos pos, Direction direction) { + return true; + } + +} diff --git a/src/main/java/com/simibubi/create/content/curiosities/bell/SoulBaseParticle.java b/src/main/java/com/simibubi/create/content/curiosities/bell/SoulBaseParticle.java new file mode 100644 index 000000000..cddc02b44 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/curiosities/bell/SoulBaseParticle.java @@ -0,0 +1,52 @@ +package com.simibubi.create.content.curiosities.bell; + +import com.simibubi.create.AllParticleTypes; +import com.simibubi.create.foundation.data.BasicParticleData; + +import net.minecraft.client.particle.IAnimatedSprite; +import net.minecraft.client.renderer.ActiveRenderInfo; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.particles.ParticleType; +import net.minecraft.util.math.vector.Quaternion; +import net.minecraft.util.math.vector.Vector3f; + +public class SoulBaseParticle extends CustomRotationParticle { + + private final IAnimatedSprite animatedSprite; + + public SoulBaseParticle(ClientWorld worldIn, double x, double y, double z, double vx, double vy, double vz, + IAnimatedSprite spriteSet) { + super(worldIn, x, y, z, spriteSet, 0); + this.animatedSprite = spriteSet; + this.particleScale = 0.5f; + this.setSize(this.particleScale,this.particleScale); + this.maxAge = (int)(16.0F / (this.rand.nextFloat() * 0.36F + 0.64F)); + this.selectSpriteWithAge(animatedSprite); + this.field_21507 = true; // disable movement + } + + @Override + public void tick() { + if (this.age++ >= this.maxAge) { + this.setExpired(); + } else { + this.selectSpriteWithAge(animatedSprite); + } + } + + @Override + public Quaternion getCustomRotation(ActiveRenderInfo camera, float partialTicks) { + return Vector3f.POSITIVE_X.getDegreesQuaternion(90); + } + + public static class Data extends BasicParticleData { + @Override + public IBasicParticleFactory getBasicFactory() { + return SoulBaseParticle::new; + } + @Override + public ParticleType getType() { + return AllParticleTypes.SOUL_BASE.get(); + } + } +} diff --git a/src/main/java/com/simibubi/create/content/curiosities/bell/SoulParticle.java b/src/main/java/com/simibubi/create/content/curiosities/bell/SoulParticle.java new file mode 100644 index 000000000..9d2a1a017 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/curiosities/bell/SoulParticle.java @@ -0,0 +1,51 @@ +package com.simibubi.create.content.curiosities.bell; + +import com.simibubi.create.AllParticleTypes; +import com.simibubi.create.foundation.data.BasicParticleData; + +import net.minecraft.client.particle.IAnimatedSprite; +import net.minecraft.client.renderer.ActiveRenderInfo; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.particles.ParticleType; +import net.minecraft.util.math.vector.Quaternion; + +public class SoulParticle extends CustomRotationParticle { + + private final IAnimatedSprite animatedSprite; + + public SoulParticle(ClientWorld worldIn, double x, double y, double z, double vx, double vy, double vz, + IAnimatedSprite spriteSet) { + super(worldIn, x, y, z, spriteSet, 0); + this.animatedSprite = spriteSet; + this.particleScale = 0.5f; + this.setSize(this.particleScale,this.particleScale); + this.maxAge = (int)(16.0F / (this.rand.nextFloat() * 0.36F + 0.64F)); + this.selectSpriteWithAge(animatedSprite); + this.field_21507 = true; // disable movement + } + + @Override + public void tick() { + if (this.age++ >= this.maxAge) { + this.setExpired(); + } else { + this.selectSpriteWithAge(animatedSprite); + } + } + + @Override + public Quaternion getCustomRotation(ActiveRenderInfo camera, float partialTicks) { + return new Quaternion(0, -camera.getYaw(), 0, true); + } + + public static class Data extends BasicParticleData { + @Override + public IBasicParticleFactory getBasicFactory() { + return SoulParticle::new; + } + @Override + public ParticleType getType() { + return AllParticleTypes.SOUL.get(); + } + } +} diff --git a/src/main/java/com/simibubi/create/foundation/data/BasicParticleData.java b/src/main/java/com/simibubi/create/foundation/data/BasicParticleData.java new file mode 100644 index 000000000..7cb0ff2fc --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/data/BasicParticleData.java @@ -0,0 +1,71 @@ +package com.simibubi.create.foundation.data; + +import javax.annotation.ParametersAreNonnullByDefault; + +import com.mojang.brigadier.StringReader; +import com.mojang.serialization.Codec; +import com.simibubi.create.content.contraptions.particle.ICustomParticleDataWithSprite; + +import mcp.MethodsReturnNonnullByDefault; +import net.minecraft.client.particle.IAnimatedSprite; +import net.minecraft.client.particle.IParticleFactory; +import net.minecraft.client.particle.Particle; +import net.minecraft.client.particle.ParticleManager; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.network.PacketBuffer; +import net.minecraft.particles.IParticleData; +import net.minecraft.particles.ParticleType; +import net.minecraft.util.registry.Registry; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; + +import java.util.Map; + +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +public abstract class BasicParticleData implements IParticleData, ICustomParticleDataWithSprite> { + + public BasicParticleData() { } + + @Override + public IDeserializer> getDeserializer() { + BasicParticleData data = this; + return new IParticleData.IDeserializer>() { + @Override + public BasicParticleData deserialize(ParticleType> arg0, StringReader reader) { + return data; + } + @Override + public BasicParticleData read(ParticleType> type, PacketBuffer buffer) { + return data; + } + }; + } + + @Override + public Codec> getCodec(ParticleType> type) { + return Codec.unit(this); + } + + public interface IBasicParticleFactory { + U makeParticle(ClientWorld worldIn, double x, double y, double z, double vx, double vy, double vz, IAnimatedSprite sprite); + } + + @OnlyIn(Dist.CLIENT) + public abstract IBasicParticleFactory getBasicFactory(); + + @Override + @OnlyIn(Dist.CLIENT) + public ParticleManager.IParticleMetaFactory> getMetaFactory() { + return animatedSprite -> (data, worldIn, x, y, z, vx, vy, vz) -> + getBasicFactory().makeParticle(worldIn, x, y, z, vx, vy, vz, animatedSprite); + } + + @Override + public String getParameters() { + return Registry.PARTICLE_TYPE.getKey(getType()).toString(); + } + + @Override + public void write(PacketBuffer buffer) { } +} diff --git a/src/main/resources/assets/create/particles/soul.json b/src/main/resources/assets/create/particles/soul.json new file mode 100644 index 000000000..a0d30c4f8 --- /dev/null +++ b/src/main/resources/assets/create/particles/soul.json @@ -0,0 +1,20 @@ +{ + "textures": [ + "create:soul_particle_0", + "create:soul_particle_1", + "create:soul_particle_2", + "create:soul_particle_3", + "create:soul_particle_4", + "create:soul_particle_5", + "create:soul_particle_6", + "create:soul_particle_7", + "create:soul_particle_8", + "create:soul_particle_9", + "create:soul_particle_10", + "create:soul_particle_11", + "create:soul_particle_12", + "create:soul_particle_13", + "create:soul_particle_14", + "create:soul_particle_15" + ] +} diff --git a/src/main/resources/assets/create/particles/soul_base.json b/src/main/resources/assets/create/particles/soul_base.json new file mode 100644 index 000000000..92b9f65be --- /dev/null +++ b/src/main/resources/assets/create/particles/soul_base.json @@ -0,0 +1,12 @@ +{ + "textures": [ + "create:soul_base_0", + "create:soul_base_1", + "create:soul_base_2", + "create:soul_base_3", + "create:soul_base_4", + "create:soul_base_5", + "create:soul_base_6", + "create:soul_base_7" + ] +} diff --git a/src/main/resources/assets/create/textures/particle/soul_base_0.png b/src/main/resources/assets/create/textures/particle/soul_base_0.png new file mode 100644 index 000000000..9f5053af5 Binary files /dev/null and b/src/main/resources/assets/create/textures/particle/soul_base_0.png differ diff --git a/src/main/resources/assets/create/textures/particle/soul_base_1.png b/src/main/resources/assets/create/textures/particle/soul_base_1.png new file mode 100644 index 000000000..5e00fff62 Binary files /dev/null and b/src/main/resources/assets/create/textures/particle/soul_base_1.png differ diff --git a/src/main/resources/assets/create/textures/particle/soul_base_2.png b/src/main/resources/assets/create/textures/particle/soul_base_2.png new file mode 100644 index 000000000..1b5c6a7ec Binary files /dev/null and b/src/main/resources/assets/create/textures/particle/soul_base_2.png differ diff --git a/src/main/resources/assets/create/textures/particle/soul_base_3.png b/src/main/resources/assets/create/textures/particle/soul_base_3.png new file mode 100644 index 000000000..8f36415b3 Binary files /dev/null and b/src/main/resources/assets/create/textures/particle/soul_base_3.png differ diff --git a/src/main/resources/assets/create/textures/particle/soul_base_4.png b/src/main/resources/assets/create/textures/particle/soul_base_4.png new file mode 100644 index 000000000..dcf7bef26 Binary files /dev/null and b/src/main/resources/assets/create/textures/particle/soul_base_4.png differ diff --git a/src/main/resources/assets/create/textures/particle/soul_base_5.png b/src/main/resources/assets/create/textures/particle/soul_base_5.png new file mode 100644 index 000000000..2e1cb95f6 Binary files /dev/null and b/src/main/resources/assets/create/textures/particle/soul_base_5.png differ diff --git a/src/main/resources/assets/create/textures/particle/soul_base_6.png b/src/main/resources/assets/create/textures/particle/soul_base_6.png new file mode 100644 index 000000000..04e3e0b74 Binary files /dev/null and b/src/main/resources/assets/create/textures/particle/soul_base_6.png differ diff --git a/src/main/resources/assets/create/textures/particle/soul_base_7.png b/src/main/resources/assets/create/textures/particle/soul_base_7.png new file mode 100644 index 000000000..5e4988e6b Binary files /dev/null and b/src/main/resources/assets/create/textures/particle/soul_base_7.png differ diff --git a/src/main/resources/assets/create/textures/particle/soul_particle_0.png b/src/main/resources/assets/create/textures/particle/soul_particle_0.png new file mode 100644 index 000000000..cfcb70ee9 Binary files /dev/null and b/src/main/resources/assets/create/textures/particle/soul_particle_0.png differ diff --git a/src/main/resources/assets/create/textures/particle/soul_particle_1.png b/src/main/resources/assets/create/textures/particle/soul_particle_1.png new file mode 100644 index 000000000..475f70e60 Binary files /dev/null and b/src/main/resources/assets/create/textures/particle/soul_particle_1.png differ diff --git a/src/main/resources/assets/create/textures/particle/soul_particle_10.png b/src/main/resources/assets/create/textures/particle/soul_particle_10.png new file mode 100644 index 000000000..1e5974c1d Binary files /dev/null and b/src/main/resources/assets/create/textures/particle/soul_particle_10.png differ diff --git a/src/main/resources/assets/create/textures/particle/soul_particle_11.png b/src/main/resources/assets/create/textures/particle/soul_particle_11.png new file mode 100644 index 000000000..e169d4364 Binary files /dev/null and b/src/main/resources/assets/create/textures/particle/soul_particle_11.png differ diff --git a/src/main/resources/assets/create/textures/particle/soul_particle_12.png b/src/main/resources/assets/create/textures/particle/soul_particle_12.png new file mode 100644 index 000000000..d5f992fef Binary files /dev/null and b/src/main/resources/assets/create/textures/particle/soul_particle_12.png differ diff --git a/src/main/resources/assets/create/textures/particle/soul_particle_13.png b/src/main/resources/assets/create/textures/particle/soul_particle_13.png new file mode 100644 index 000000000..be8c3bd6d Binary files /dev/null and b/src/main/resources/assets/create/textures/particle/soul_particle_13.png differ diff --git a/src/main/resources/assets/create/textures/particle/soul_particle_14.png b/src/main/resources/assets/create/textures/particle/soul_particle_14.png new file mode 100644 index 000000000..ffa668a39 Binary files /dev/null and b/src/main/resources/assets/create/textures/particle/soul_particle_14.png differ diff --git a/src/main/resources/assets/create/textures/particle/soul_particle_15.png b/src/main/resources/assets/create/textures/particle/soul_particle_15.png new file mode 100644 index 000000000..ac95537af Binary files /dev/null and b/src/main/resources/assets/create/textures/particle/soul_particle_15.png differ diff --git a/src/main/resources/assets/create/textures/particle/soul_particle_2.png b/src/main/resources/assets/create/textures/particle/soul_particle_2.png new file mode 100644 index 000000000..1c4a756fc Binary files /dev/null and b/src/main/resources/assets/create/textures/particle/soul_particle_2.png differ diff --git a/src/main/resources/assets/create/textures/particle/soul_particle_3.png b/src/main/resources/assets/create/textures/particle/soul_particle_3.png new file mode 100644 index 000000000..0f98b122b Binary files /dev/null and b/src/main/resources/assets/create/textures/particle/soul_particle_3.png differ diff --git a/src/main/resources/assets/create/textures/particle/soul_particle_4.png b/src/main/resources/assets/create/textures/particle/soul_particle_4.png new file mode 100644 index 000000000..21862c96e Binary files /dev/null and b/src/main/resources/assets/create/textures/particle/soul_particle_4.png differ diff --git a/src/main/resources/assets/create/textures/particle/soul_particle_5.png b/src/main/resources/assets/create/textures/particle/soul_particle_5.png new file mode 100644 index 000000000..af675b791 Binary files /dev/null and b/src/main/resources/assets/create/textures/particle/soul_particle_5.png differ diff --git a/src/main/resources/assets/create/textures/particle/soul_particle_6.png b/src/main/resources/assets/create/textures/particle/soul_particle_6.png new file mode 100644 index 000000000..2aec05986 Binary files /dev/null and b/src/main/resources/assets/create/textures/particle/soul_particle_6.png differ diff --git a/src/main/resources/assets/create/textures/particle/soul_particle_7.png b/src/main/resources/assets/create/textures/particle/soul_particle_7.png new file mode 100644 index 000000000..cfbed1f95 Binary files /dev/null and b/src/main/resources/assets/create/textures/particle/soul_particle_7.png differ diff --git a/src/main/resources/assets/create/textures/particle/soul_particle_8.png b/src/main/resources/assets/create/textures/particle/soul_particle_8.png new file mode 100644 index 000000000..90f219c14 Binary files /dev/null and b/src/main/resources/assets/create/textures/particle/soul_particle_8.png differ diff --git a/src/main/resources/assets/create/textures/particle/soul_particle_9.png b/src/main/resources/assets/create/textures/particle/soul_particle_9.png new file mode 100644 index 000000000..a3e51c146 Binary files /dev/null and b/src/main/resources/assets/create/textures/particle/soul_particle_9.png differ