Skip to content

Commit

Permalink
Particles and alpha fix
Browse files Browse the repository at this point in the history
  • Loading branch information
Direwolf20-MC committed Feb 26, 2024
1 parent a7293fe commit 86db12a
Show file tree
Hide file tree
Showing 8 changed files with 310 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ public void renderTextures(Direction direction, Level level, BlockPos pos, PoseS
renderTexturePattern(direction, level, pos, matrixStackIn, bufferIn, combinedOverlayIn, 1f, patternState, renderState);
}
BlockState patternState = Registration.GooPatternBlock.get().defaultBlockState().setValue(GooPatternBlock.GOOSTAGE, tensDigit);
float percentagePart = percentComplete % percentageDivisor;
float startOfCurrentStage = tensDigit * percentageDivisor; // This calculates the starting percentage of the current stage
float percentagePart = percentComplete - startOfCurrentStage; // This calculates how far into the current stage we are
float alpha = percentagePart / percentageDivisor;
renderTexturePattern(direction, level, pos, matrixStackIn, bufferIn, combinedOverlayIn, alpha, patternState, renderState);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.direwolf20.justdirethings.client.particles;


import com.direwolf20.justdirethings.JustDireThings;
import com.direwolf20.justdirethings.client.particles.itemparticle.ItemFlowParticleData;
import com.direwolf20.justdirethings.client.particles.itemparticle.ItemFlowParticleType;
import net.minecraft.core.particles.ParticleType;
import net.minecraft.core.registries.Registries;
import net.neoforged.neoforge.registries.DeferredRegister;

import java.util.function.Supplier;

public class ModParticles {
public static final DeferredRegister<ParticleType<?>> PARTICLE_TYPES = DeferredRegister.create(Registries.PARTICLE_TYPE, JustDireThings.MODID);
public static final Supplier<ParticleType<ItemFlowParticleData>> ITEMFLOWPARTICLE = PARTICLE_TYPES.register("itemflowparticle", ItemFlowParticleType::new);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.direwolf20.justdirethings.client.particles;


import com.direwolf20.justdirethings.JustDireThings;
import com.direwolf20.justdirethings.client.particles.itemparticle.ItemFlowParticle;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.Mod;
import net.neoforged.neoforge.client.event.RegisterParticleProvidersEvent;

@Mod.EventBusSubscriber(modid = JustDireThings.MODID, value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.MOD)
public class ParticleRenderDispatcher {

@SubscribeEvent
public static void registerProviders(RegisterParticleProvidersEvent evt) {
evt.registerSpecial(ModParticles.ITEMFLOWPARTICLE.get(), ItemFlowParticle.FACTORY);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
package com.direwolf20.justdirethings.client.particles.itemparticle;


import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.particle.BreakingItemParticle;
import net.minecraft.client.particle.ParticleProvider;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.Blocks;

import java.util.Random;

public class ItemFlowParticle extends BreakingItemParticle {

private double targetX, targetY, targetZ;
Random random = new Random();
private float partSize;
private boolean doGravity;
private boolean shrinking;

public ItemFlowParticle(ClientLevel world, double x, double y, double z, ItemStack itemStack, boolean gravity, boolean shrinking) {
super(world, x, y, z, itemStack);
this.doGravity = gravity;
this.shrinking = shrinking;
float minSize = 0.25f;
float maxSize = 0.5f;
this.partSize = minSize + random.nextFloat() * (maxSize - minSize);
this.lifetime = 30;
int longLifeChance = random.nextInt(20);
if (longLifeChance == 0)
this.lifetime = 120;

this.scale(partSize);
this.partSize = quadSize;
if (this.sprite == null) {
this.setSprite(Minecraft.getInstance().getItemRenderer().getModel(new ItemStack(Blocks.COBBLESTONE), world, (LivingEntity) null, 0).getParticleIcon());
}
//this.xd = 0;
//this.yd = 0;
//this.zd = 0;
/*if (shrinking) {
this.targetX = x + 1.75f;
this.targetY = y + 1.75f;
this.targetZ = z + 1.75f;
} else {
if (!gravity) {
double randomX = random.nextFloat();
double randomY = random.nextFloat();
double randomZ = random.nextFloat();
this.xo = x + randomX;
this.yo = y + randomY;
this.zo = z + randomZ;
this.setPos(xo, yo, zo);
this.targetX = x;
this.targetY = y;
this.targetZ = z;
}
}*/

/*Vec3 target = new Vec3(targetX, targetY, targetZ);
Vec3 source = new Vec3(this.x, this.y, this.z);
Vec3 path = target.subtract(source).normalize().multiply(1, 1, 1);
float speedModifier = (1f - 0.5f) * (partSize - minSize) / (maxSize - minSize) + 0.25f;
int ticksPerBlock = 15;
float speedAdjust = ticksPerBlock * (1 / speedModifier);
this.xd += path.x / speedAdjust;
this.yd += path.y / speedAdjust;
this.zd += path.z / speedAdjust;
if (gravity) {
this.xd = 0;
this.yd = 0;
this.zd = 0;
this.gravity = 0.0625f;
this.hasPhysics = true;
this.age = this.lifetime / 2;
this.scale(2f);
this.partSize = quadSize;
updateColorAndGravity();
} else {
this.gravity = 0.0f;
this.hasPhysics = false;
}
if (!shrinking)
updateColorAndGravity();*/
}

@Override
public void tick() {
super.tick();
/*this.xo = this.x;
this.yo = this.y;
this.zo = this.z;
if (this.age++ >= this.lifetime) {
this.remove();
} else {
this.yd -= 0.04D * (double) this.gravity;
this.move(this.xd, this.yd, this.zd);
}
if (!shrinking && this.y <= targetY)
this.remove();*/
updateColorAndGravity();
}

public void updateColorAndGravity() {
float relativeAge = (float) ((this.lifetime - this.age)) / this.lifetime; //1.0 -> 0.0
//float shrink = Mth.lerp(relativeAge, 0.1f, 1);
//this.quadSize = partSize * shrink;

float adjustedAge = (float) Math.pow(relativeAge, 2);
/*float darkness;
if (shrinking)
darkness = Mth.lerp(adjustedAge, 0, 1);
else
darkness = Mth.lerp(adjustedAge, 1, 0.15f);
this.rCol = darkness;
this.gCol = darkness;
this.bCol = darkness;*/

if (relativeAge < 0.5f) {
adjustedAge = (float) Math.pow(relativeAge / 0.5f, 2);
//if (shrinking)
this.alpha = Mth.lerp(adjustedAge, 0.25f, 1);
//else
// this.alpha = Mth.lerp(adjustedAge, 1f, 0.2f);
}
/*if (!doGravity) {
int gravityChance = random.nextInt(2);
if (relativeAge < 0.75f && gravityChance == 0) {
this.gravity = 0.05f;
}
}*/
}

@Override //Performance Reasons
protected int getLightColor(float pPartialTick) {
return 0xF00080;
}

public static ParticleProvider<ItemFlowParticleData> FACTORY =
(data, world, x, y, z, xSpeed, ySpeed, zSpeed) ->
new ItemFlowParticle(world, x, y, z, data.getItemStack(), data.doGravity, data.shrinking);
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package com.direwolf20.justdirethings.client.particles.itemparticle;

import com.direwolf20.justdirethings.client.particles.ModParticles;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.minecraft.commands.arguments.item.ItemInput;
import net.minecraft.commands.arguments.item.ItemParser;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.ParticleType;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.item.ItemStack;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;

import javax.annotation.Nonnull;
import java.util.Locale;

public class ItemFlowParticleData implements ParticleOptions {
private final ItemStack itemStack;
public final boolean doGravity;
public final boolean shrinking;

public ItemFlowParticleData(ItemStack itemStack, boolean doGravity, boolean shrinking) {
this.itemStack = itemStack.copy(); //Forge: Fix stack updating after the fact causing particle changes.
this.doGravity = doGravity;
this.shrinking = shrinking;
}

@Nonnull
@Override
public ParticleType<ItemFlowParticleData> getType() {
return ModParticles.ITEMFLOWPARTICLE.get();
}

@Override
public void writeToNetwork(FriendlyByteBuf buffer) {
buffer.writeItem(this.itemStack);
}

@Nonnull
@Override
public String writeToString() {
return String.format(Locale.ROOT, "%s %b %b",
this.getType(), this.doGravity, this.shrinking);
}

@OnlyIn(Dist.CLIENT)
public ItemStack getItemStack() {
return this.itemStack;
}

public static final Deserializer<ItemFlowParticleData> DESERIALIZER = new Deserializer<ItemFlowParticleData>() {
@Nonnull
@Override
public ItemFlowParticleData fromCommand(ParticleType<ItemFlowParticleData> particleTypeIn, StringReader reader) throws CommandSyntaxException {
reader.expect(' ');
ItemParser.ItemResult itemparser$itemresult = ItemParser.parseForItem(BuiltInRegistries.ITEM.asLookup(), reader);
ItemStack itemstack = (new ItemInput(itemparser$itemresult.item(), itemparser$itemresult.nbt())).createItemStack(1, false);

reader.expect(' ');
boolean doGravity = reader.readBoolean();
reader.expect(' ');
boolean building = reader.readBoolean();

return new ItemFlowParticleData(itemstack, doGravity, building);
}

@Override
public ItemFlowParticleData fromNetwork(ParticleType<ItemFlowParticleData> particleTypeIn, FriendlyByteBuf buffer) {
return new ItemFlowParticleData(buffer.readItem(), buffer.readBoolean(), buffer.readBoolean());
}
};
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.direwolf20.justdirethings.client.particles.itemparticle;


import com.mojang.serialization.Codec;
import net.minecraft.core.particles.ParticleType;

public class ItemFlowParticleType extends ParticleType<ItemFlowParticleData> {
public ItemFlowParticleType() {
super(false, ItemFlowParticleData.DESERIALIZER);
}

@Override
public Codec<ItemFlowParticleData> codec() {
return null;
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.direwolf20.justdirethings.common.blockentities.gooblocks;

import com.direwolf20.justdirethings.client.particles.itemparticle.ItemFlowParticleData;
import com.direwolf20.justdirethings.datagen.recipes.GooSpreadRecipe;
import com.direwolf20.justdirethings.setup.Registration;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
Expand All @@ -12,6 +13,7 @@
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.RecipeHolder;
import net.minecraft.world.item.crafting.RecipeManager;
import net.minecraft.world.level.block.entity.BlockEntity;
Expand All @@ -20,6 +22,7 @@
import org.jetbrains.annotations.Nullable;

import java.util.Map;
import java.util.Random;

public class GooBlockBE_Base extends BlockEntity {
public final Map<Direction, Integer> sidedCounters = new Object2IntOpenHashMap<>();
Expand All @@ -33,6 +36,14 @@ public GooBlockBE_Base(BlockEntityType<?> type, BlockPos pos, BlockState state)
}
}

public void updateSideCounter(Direction direction, int newCounter) {
int oldCounter = sidedCounters.get(direction);
sidedCounters.put(direction, newCounter);
if (oldCounter >= 0 && newCounter == -1 && level.isClientSide) {
spawnParticles(direction);
}
}

public int getTier() {
return 0;
}
Expand All @@ -49,6 +60,21 @@ public void tickClient() {
tickCounters(); //We tick on client side too, just for rendering of course!
}

public void spawnParticles(Direction side) {
Random random = new Random();
BlockPos startPos = getBlockPos().relative(side);
ItemStack itemStack = new ItemStack(getBlockState().getBlock());
ItemFlowParticleData data = new ItemFlowParticleData(itemStack, true, false);
for (Direction direction : Direction.values()) {
for (int i = 0; i < 100; i++) {
double randomX = 0.5 + (0.6 * direction.getNormal().getX()) + (direction.getNormal().getX() == 0 ? random.nextDouble() - 0.5 : 0);
double randomY = 0.5 + (0.6 * direction.getNormal().getY()) + (direction.getNormal().getY() == 0 ? random.nextDouble() - 0.5 : 0);
double randomZ = 0.5 + (0.6 * direction.getNormal().getZ()) + (direction.getNormal().getZ() == 0 ? random.nextDouble() - 0.5 : 0);
level.addParticle(data, startPos.getX() + randomX, startPos.getY() + randomY, startPos.getZ() + randomZ, 0, 0, 0);
}
}
}

public void tickServer() {
checkSides();
tickCounters();
Expand All @@ -58,8 +84,9 @@ public void tickCounters() {
for (Direction direction : Direction.values()) {
int sideCounter = sidedCounters.get(direction);
if (sideCounter > 0) {
//sideCounter = Math.max(sideCounter-40, 0);
sideCounter--;
sidedCounters.put(direction, sideCounter);
updateSideCounter(direction, sideCounter);
}
}
}
Expand All @@ -71,7 +98,7 @@ public void checkSides() {
if (gooSpreadRecipe != null) {
if (sideCounter == -1) { //Valid Recipe and not running yet
sideCounter = gooSpreadRecipe.getCraftingDuration();
sidedCounters.put(direction, sideCounter);
updateSideCounter(direction, sideCounter);
sidedDurations.put(direction, sideCounter);
markDirtyClient(); //Either way, update the client with the new sideCounters
} else if (sideCounter == 0) { //Craftings done!
Expand All @@ -81,7 +108,7 @@ public void checkSides() {
} else { //If the recipe is null, it means this isn't a valid input block (or its already been converted!)
if (sideCounter != -1) { //If we have a timer running, cancel it
sideCounter = -1;
sidedCounters.put(direction, sideCounter);
updateSideCounter(direction, sideCounter);
sidedDurations.put(direction, sideCounter);
markDirtyClient();
}
Expand All @@ -91,7 +118,7 @@ public void checkSides() {

public void setBlockToTarget(GooSpreadRecipe gooSpreadRecipe, Direction direction) {
level.setBlockAndUpdate(getBlockPos().relative(direction), gooSpreadRecipe.getOutput());
sidedCounters.put(direction, -1);
updateSideCounter(direction, -1);
sidedDurations.put(direction, -1);
level.playSound(null, getBlockPos(), SoundEvents.SCULK_BLOCK_BREAK, SoundSource.BLOCKS, 1.0F, 1.0F);
}
Expand Down Expand Up @@ -140,7 +167,7 @@ public void load(CompoundTag tag) {
CompoundTag sideCounterTag = listNBT.getCompound(i);
int direction = sideCounterTag.getInt("side");
int counter = sideCounterTag.getInt("counter");
this.sidedCounters.put(Direction.values()[direction], counter);
this.updateSideCounter(Direction.values()[direction], counter);
}
}
if (tag.contains("sideDurations")) {
Expand Down
Loading

0 comments on commit 86db12a

Please sign in to comment.