CreateMod/src/main/java/com/simibubi/create/item/SymmetryHandler.java
simibubi ddc846d860 Setup Infrastructure
- Relevant Mod files
- Relevant Classes
- Resources
- Added Symmetry Wand from TMA
2019-07-11 09:03:08 +02:00

178 lines
6.2 KiB
Java

package com.simibubi.create.item;
import java.util.Random;
import org.lwjgl.opengl.GL11;
import com.mojang.blaze3d.platform.GlStateManager;
import com.simibubi.create.AllItems;
import com.simibubi.create.item.symmetry.SymmetryElement;
import com.simibubi.create.item.symmetry.SymmetryEmptySlot;
import com.simibubi.create.utility.TessellatorHelper;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.player.ClientPlayerEntity;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.particles.ParticleTypes;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.event.RenderWorldLastEvent;
import net.minecraftforge.client.model.data.EmptyModelData;
import net.minecraftforge.event.world.BlockEvent.BreakEvent;
import net.minecraftforge.event.world.BlockEvent.EntityPlaceEvent;
import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent;
@EventBusSubscriber(bus = Bus.FORGE)
public class SymmetryHandler {
private static int tickCounter = 0;
@SubscribeEvent(priority = EventPriority.LOWEST)
public static void onBlockPlaced(EntityPlaceEvent event) {
if (event.getWorld().isRemote())
return;
if (!(event.getEntity() instanceof PlayerEntity))
return;
PlayerEntity player = (PlayerEntity) event.getEntity();
PlayerInventory inv = player.inventory;
for (int i = 0; i < PlayerInventory.getHotbarSize(); i++) {
if (!inv.getStackInSlot(i).isEmpty() && inv.getStackInSlot(i).getItem() == AllItems.SYMMETRY_WAND.get()) {
ItemWandSymmetry.apply(player.world, inv.getStackInSlot(i), player, event.getPos(),
event.getPlacedBlock());
}
}
}
@SubscribeEvent(priority = EventPriority.LOWEST)
public static void onBlockDestroyed(BreakEvent event) {
if (event.getWorld().isRemote())
return;
PlayerEntity player = event.getPlayer();
PlayerInventory inv = player.inventory;
for (int i = 0; i < PlayerInventory.getHotbarSize(); i++) {
if (!inv.getStackInSlot(i).isEmpty() && AllItems.SYMMETRY_WAND.typeOf(inv.getStackInSlot(i))) {
ItemWandSymmetry.remove(player.world, inv.getStackInSlot(i), player, event.getPos());
}
}
}
@OnlyIn(Dist.CLIENT)
@SubscribeEvent
public static void render(RenderWorldLastEvent event) {
Minecraft mc = Minecraft.getInstance();
ClientPlayerEntity player = mc.player;
GL11.glEnable(GL11.GL_BLEND);
for (int i = 0; i < PlayerInventory.getHotbarSize(); i++) {
ItemStack stackInSlot = player.inventory.getStackInSlot(i);
if (stackInSlot != null && AllItems.SYMMETRY_WAND.typeOf(stackInSlot)
&& ItemWandSymmetry.isEnabled(stackInSlot)) {
SymmetryElement mirror = ItemWandSymmetry.getMirror(stackInSlot);
if (mirror instanceof SymmetryEmptySlot)
continue;
TessellatorHelper.prepareForDrawing();
BlockPos pos = new BlockPos(mirror.getPosition());
float yShift = 0;
double speed = 1 / 16d;
yShift = MathHelper.sin((float) ((tickCounter + event.getPartialTicks()) * speed)) / 5f;
BufferBuilder buffer = Tessellator.getInstance().getBuffer();
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
GlStateManager.pushMatrix();
GlStateManager.translated(0, yShift + .2f, 0);
mc.getBlockRendererDispatcher().renderBlock(mirror.getModel(), pos, player.world, buffer, player.world.getRandom(),
EmptyModelData.INSTANCE);
Tessellator.getInstance().draw();
GlStateManager.popMatrix();
TessellatorHelper.cleanUpAfterDrawing();
}
}
GL11.glDisable(GL11.GL_BLEND);
}
@OnlyIn(Dist.CLIENT)
@SubscribeEvent
public static void onClientTick(ClientTickEvent event) {
Minecraft mc = Minecraft.getInstance();
ClientPlayerEntity player = mc.player;
if (mc.world == null)
return;
if (mc.isGamePaused())
return;
tickCounter++;
if (tickCounter % 10 == 0) {
for (int i = 0; i < PlayerInventory.getHotbarSize(); i++) {
ItemStack stackInSlot = player.inventory.getStackInSlot(i);
if (stackInSlot != null && AllItems.SYMMETRY_WAND.typeOf(stackInSlot)
&& ItemWandSymmetry.isEnabled(stackInSlot)) {
SymmetryElement mirror = ItemWandSymmetry.getMirror(stackInSlot);
if (mirror instanceof SymmetryEmptySlot)
continue;
Random r = new Random();
double offsetX = (r.nextDouble() - 0.5) * 0.3;
double offsetZ = (r.nextDouble() - 0.5) * 0.3;
Vec3d pos = mirror.getPosition().add(0.5 + offsetX, 1 / 4d, 0.5 + offsetZ);
Vec3d speed = new Vec3d(0, r.nextDouble() * 1 / 8f, 0);
mc.world.addParticle(ParticleTypes.END_ROD, pos.x, pos.y, pos.z, speed.x, speed.y, speed.z);
}
}
}
}
public static void drawEffect(BlockPos from, BlockPos to) {
double density = 0.3f;
Vec3d start = new Vec3d(from).add(0.5, 0.5, 0.5);
Vec3d end = new Vec3d(to).add(0.5, 0.5, 0.5);
Vec3d diff = end.subtract(start);
Vec3d step = diff.normalize().scale(density);
int steps = (int) (diff.length() / step.length());
Random r = new Random();
for (int i = 5; i < steps - 1; i++) {
Vec3d pos = start.add(step.scale(i));
Vec3d speed = new Vec3d(0, r.nextDouble() * -40f, 0);
Minecraft.getInstance().world.addParticle(ParticleTypes.WITCH, pos.x, pos.y, pos.z, speed.x,
speed.y, speed.z);
}
Vec3d speed = new Vec3d(0, r.nextDouble() * 1 / 32f, 0);
Vec3d pos = start.add(step.scale(5));
Minecraft.getInstance().world.addParticle(ParticleTypes.END_ROD, pos.x, pos.y, pos.z, speed.x, speed.y,
speed.z);
speed = new Vec3d(0, r.nextDouble() * 1 / 32f, 0);
pos = start.add(step.scale(steps));
Minecraft.getInstance().world.addParticle(ParticleTypes.END_ROD, pos.x, pos.y, pos.z, speed.x, speed.y,
speed.z);
}
}