finished env collector

This commit is contained in:
Robin 2024-06-08 18:25:56 +02:00
parent 5373cfc84f
commit 9bcddc4858
33 changed files with 761 additions and 165 deletions

View File

@ -63,6 +63,7 @@ val junitRuntimeOnly: Configuration by configurations.getting {
} }
configurations["junitImplementation"].extendsFrom(configurations.implementation.get()) configurations["junitImplementation"].extendsFrom(configurations.implementation.get())
@ -71,6 +72,7 @@ configurations["junitImplementation"].extendsFrom(configurations.implementation.
//minecraft.accessTransformers.file rootProject.file("src/main/resources/META-INF/accesstransformer.cfg") //minecraft.accessTransformers.file rootProject.file("src/main/resources/META-INF/accesstransformer.cfg")
//minecraft.accessTransformers.entry public net.minecraft.client.Minecraft textureManager # textureManager //minecraft.accessTransformers.entry public net.minecraft.client.Minecraft textureManager # textureManager
// Default run configurations. // Default run configurations.
// These can be tweaked, removed, or duplicated as needed. // These can be tweaked, removed, or duplicated as needed.
runs { runs {
@ -113,8 +115,10 @@ runs {
// The gametest system is also enabled by default for other run configs under the /test command. // The gametest system is also enabled by default for other run configs under the /test command.
create("gameTestServer") { create("gameTestServer") {
systemProperty ("forge.enabledGameTestNamespaces", modId) systemProperty ("forge.enabledGameTestNamespaces", modId)
} }
create("data") { create("data") {
// example of overriding the workingDirectory set in configureEach above, uncomment if you want to use it // example of overriding the workingDirectory set in configureEach above, uncomment if you want to use it
// workingDirectory project.file("run-data") // workingDirectory project.file("run-data")
@ -147,7 +151,6 @@ dependencies {
junitImplementation("org.junit.jupiter:junit-jupiter-params") junitImplementation("org.junit.jupiter:junit-jupiter-params")
junitRuntimeOnly("org.junit.jupiter:junit-jupiter-engine") junitRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
junitImplementation("org.assertj:assertj-core:3.25.1") junitImplementation("org.assertj:assertj-core:3.25.1")
// "junitImplementation"(platform("org.junit:junit-bom:5.10.2")) // "junitImplementation"(platform("org.junit:junit-bom:5.10.2"))

View File

@ -1,2 +0,0 @@
// 1.20.6 2024-06-04T18:17:38.371046381 Item Models: environmenttech
7da758340fb853d580031041c9f27152a54ec971 assets/environmenttech/models/item/env_collector.json

View File

@ -1,3 +0,0 @@
// 1.20.6 2024-06-04T16:17:04.985464 Block States: environmenttech
1e105612311484ccb5c962a0d36f211c56dd86df assets/environmenttech/blockstates/env_collector.json
42508b5c76d779fdb052a9e72a5377745684f5da assets/environmenttech/models/block/env_collector_main.json

View File

@ -1,3 +0,0 @@
// 1.20.6 2024-06-04T18:17:38.370569743 Recipes
375ee3cb8eaf222bd0d5576061d1741b5b3d5cff data/environmenttech/advancements/recipes/environmental_essence.json
d462a41d1b0fda35660ed3e4c807f83f6dc0e0cd data/environmenttech/recipes/environmental_essence.json

View File

@ -1,9 +0,0 @@
{
"multipart": [
{
"apply": {
"model": "environmenttech:block/env_collector_main"
}
}
]
}

View File

@ -1,42 +0,0 @@
{
"parent": "minecraft:block/cube",
"elements": [
{
"faces": {
"down": {
"texture": "#txt"
},
"east": {
"texture": "#txt"
},
"north": {
"texture": "#txt"
},
"south": {
"texture": "#txt"
},
"up": {
"texture": "#txt"
},
"west": {
"texture": "#txt"
}
},
"from": [
0,
0,
0
],
"to": [
16,
16,
16
]
}
],
"render_type": "minecraft:solid",
"textures": {
"particle": "environmenttech:block/env_collector_main",
"txt": "environmenttech:block/env_collector_main"
}
}

View File

@ -1,3 +0,0 @@
{
"parent": "environmenttech:block/env_collector_main"
}

View File

@ -1,43 +0,0 @@
{
"parent": "minecraft:recipes/root",
"criteria": {
"env_collector": {
"conditions": {
"items": [
{
"items": "environmenttech:env_collector"
}
]
},
"trigger": "minecraft:inventory_changed"
},
"has_the_recipe": {
"conditions": {
"recipe": "environmenttech:environmental_essence"
},
"trigger": "minecraft:recipe_unlocked"
},
"iron_ingot": {
"conditions": {
"items": [
{
"items": "minecraft:iron_ingot"
}
]
},
"trigger": "minecraft:inventory_changed"
}
},
"requirements": [
[
"has_the_recipe",
"iron_ingot",
"env_collector"
]
],
"rewards": {
"recipes": [
"environmenttech:environmental_essence"
]
}
}

View File

@ -1,11 +0,0 @@
{
"type": "environmenttech:env_collector",
"envUsed": 10,
"ingredient": {
"item": "minecraft:iron_ingot"
},
"output": {
"count": 1,
"id": "environmenttech:environmental_essence"
}
}

View File

@ -1,18 +1,18 @@
package robaertschi.environmenttech.unittest; package robaertschi.environmenttech.unittest;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import robaertschi.environmenttech.client.screen.ProgressArrowComponent; import robaertschi.environmenttech.client.screen.ProgressArrowUtils;
import static org.assertj.core.api.Assertions.*; import static org.assertj.core.api.Assertions.*;
public class TestProgressBar { public class TestProgressBar {
int gsp(int progress, int maxProgress) { int gsp(int progress, int maxProgress) {
return ProgressArrowComponent.getScaledProgress(progress, maxProgress); return ProgressArrowUtils.getScaledProgress(progress, maxProgress);
} }
@Test @Test
void testScales() { void testScales() {
int scale1 = ProgressArrowComponent.getScaledProgress(1, 24); int scale1 = ProgressArrowUtils.getScaledProgress(1, 24);
assertThat(scale1).isEqualTo(1); assertThat(scale1).isEqualTo(1);
assertThat(gsp(24, 24)).isEqualTo(24); assertThat(gsp(24, 24)).isEqualTo(24);
assertThat(gsp(1, 12)).isEqualTo(2); assertThat(gsp(1, 12)).isEqualTo(2);

View File

@ -1,6 +1,7 @@
package robaertschi.environmenttech; package robaertschi.environmenttech;
import com.mojang.logging.LogUtils; import com.mojang.logging.LogUtils;
import net.minecraft.client.Minecraft;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.IEventBus; import net.neoforged.bus.api.IEventBus;
@ -11,22 +12,29 @@ import net.neoforged.fml.common.Mod;
import net.neoforged.fml.config.ModConfig; import net.neoforged.fml.config.ModConfig;
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent; import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
import net.neoforged.fml.loading.FMLEnvironment;
import net.neoforged.fml.loading.FMLLoader;
import net.neoforged.neoforge.common.NeoForge; import net.neoforged.neoforge.common.NeoForge;
import net.neoforged.neoforge.event.RegisterCommandsEvent;
import net.neoforged.neoforge.event.server.ServerStartingEvent; import net.neoforged.neoforge.event.server.ServerStartingEvent;
import net.neoforged.neoforge.event.tick.PlayerTickEvent; import net.neoforged.neoforge.event.tick.PlayerTickEvent;
import net.neoforged.neoforge.gametest.GameTestHooks;
import org.slf4j.Logger; import org.slf4j.Logger;
import robaertschi.environmenttech.client.ETClient;
import robaertschi.environmenttech.command.EnvironmenttechCommand;
import robaertschi.environmenttech.data.attachments.ETAttachments; import robaertschi.environmenttech.data.attachments.ETAttachments;
import robaertschi.environmenttech.data.capabilities.ETCapabilities; import robaertschi.environmenttech.data.capabilities.ETCapabilities;
import robaertschi.environmenttech.data.recipes.ETRecipes; import robaertschi.environmenttech.data.recipes.ETRecipes;
import robaertschi.environmenttech.level.block.ETBlocks; import robaertschi.environmenttech.level.block.ETBlocks;
import robaertschi.environmenttech.level.block.entity.ETBlockEntities; import robaertschi.environmenttech.level.block.entity.ETBlockEntities;
import robaertschi.environmenttech.level.item.ETItems; import robaertschi.environmenttech.level.item.ETItems;
import robaertschi.environmenttech.level.particle.ETParticles;
import robaertschi.environmenttech.menu.ETMenus; import robaertschi.environmenttech.menu.ETMenus;
@Mod(EnvironmentTech.MODID) @Mod(EnvironmentTech.MODID)
public class EnvironmentTech public class EnvironmentTech
{ {
public static final boolean DEBUG;
public static final String MODID = "environmenttech"; public static final String MODID = "environmenttech";
public static final Logger LOGGER = LogUtils.getLogger(); public static final Logger LOGGER = LogUtils.getLogger();
@ -35,11 +43,20 @@ public class EnvironmentTech
return new ResourceLocation(MODID, name); return new ResourceLocation(MODID, name);
} }
static {
// Why a static block? Because I can.
// Enable debugging Tools and Screen
// TODO: Add a config entry for modpack devs and so on.
DEBUG = !FMLLoader.isProduction();
}
// The constructor for the mod class is the first code that is run when your mod is loaded. // The constructor for the mod class is the first code that is run when your mod is loaded.
// FML will recognize some parameter types like IEventBus or ModContainer and pass them in automatically. // FML will recognize some parameter types like IEventBus or ModContainer and pass them in automatically.
public EnvironmentTech(IEventBus modEventBus, ModContainer modContainer) public EnvironmentTech(IEventBus modEventBus, ModContainer modContainer)
{ {
modEventBus.addListener(this::commonSetup); modEventBus.addListener(this::commonSetup);
NeoForge.EVENT_BUS.addListener(ETClient::onClientTickEnd);
modContainer.registerConfig(ModConfig.Type.COMMON, Config.SPEC); modContainer.registerConfig(ModConfig.Type.COMMON, Config.SPEC);
@ -50,6 +67,7 @@ public class EnvironmentTech
ETAttachments.init(modEventBus); ETAttachments.init(modEventBus);
ETCapabilities.init(modEventBus); ETCapabilities.init(modEventBus);
ETMenus.init(modEventBus); ETMenus.init(modEventBus);
ETParticles.init(modEventBus);
NeoForge.EVENT_BUS.register(this); NeoForge.EVENT_BUS.register(this);
@ -59,6 +77,11 @@ public class EnvironmentTech
{ {
} }
@SubscribeEvent
private void registerCommands(RegisterCommandsEvent event) {
new EnvironmenttechCommand(event.getDispatcher());
}
@SubscribeEvent @SubscribeEvent
public void onServerStarting(ServerStartingEvent event) public void onServerStarting(ServerStartingEvent event)

View File

@ -1,20 +1,59 @@
package robaertschi.environmenttech.client; package robaertschi.environmenttech.client;
import com.mojang.blaze3d.platform.InputConstants;
import net.minecraft.client.KeyMapping;
import net.minecraft.client.Minecraft;
import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent; import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
import net.neoforged.neoforge.client.event.RegisterMenuScreensEvent; import net.neoforged.jarjar.nio.util.Lazy;
import net.neoforged.neoforge.client.event.*;
import org.lwjgl.glfw.GLFW;
import robaertschi.environmenttech.EnvironmentTech;
import robaertschi.environmenttech.client.particle.EnvParticleProvider;
import robaertschi.environmenttech.client.screen.EnvCollectorScreen; import robaertschi.environmenttech.client.screen.EnvCollectorScreen;
import robaertschi.environmenttech.level.block.entity.ETBlockEntities;
import robaertschi.environmenttech.level.block.entity.renderer.EnvCollectorRenderer;
import robaertschi.environmenttech.level.particle.ETParticles;
import robaertschi.environmenttech.menu.ETMenus; import robaertschi.environmenttech.menu.ETMenus;
@EventBusSubscriber(bus = EventBusSubscriber.Bus.MOD) @EventBusSubscriber(bus = EventBusSubscriber.Bus.MOD)
public class ETClient { public class ETClient {
public static final Lazy<KeyMapping> OPEN_DEBUG_MENU = Lazy.of(() -> new KeyMapping(
"key.environmenttech.open_debug_menu",
InputConstants.Type.KEYSYM,
GLFW.GLFW_KEY_U,
"key.categories.environmenttech"
));
@SubscribeEvent @SubscribeEvent
public static void setup(FMLClientSetupEvent event) { public static void setup(FMLClientSetupEvent event) {
} }
@SubscribeEvent @SubscribeEvent
public static void registerMenu(RegisterMenuScreensEvent event) { public static void registerMenu(RegisterMenuScreensEvent event) {
event.register(ETMenus.ENV_COLLECTOR_MENU.get(), EnvCollectorScreen::new); event.register(ETMenus.ENV_COLLECTOR_MENU.get(), EnvCollectorScreen::new);
} }
@SubscribeEvent
public static void registerRenderers(EntityRenderersEvent.RegisterRenderers event) {
event.registerBlockEntityRenderer(ETBlockEntities.ENV_COLLECTOR_BLOCK_ENTITY.get(), EnvCollectorRenderer::new);
}
@SubscribeEvent
public static void registerParticleProviders(RegisterParticleProvidersEvent event) {
event.registerSpriteSet(ETParticles.ENV_PARTICLE.get(), EnvParticleProvider::new);
}
@SubscribeEvent
public static void registerBindings(RegisterKeyMappingsEvent event) {
if (EnvironmentTech.DEBUG) {
event.register(OPEN_DEBUG_MENU.get());
}
}
public static void onClientTickEnd(ClientTickEvent.Post event) {
}
} }

View File

@ -0,0 +1,32 @@
package robaertschi.environmenttech.client.particle;
import lombok.AllArgsConstructor;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.particle.Particle;
import net.minecraft.client.particle.ParticleProvider;
import net.minecraft.client.particle.SpriteSet;
import net.minecraft.core.particles.SimpleParticleType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import robaertschi.environmenttech.level.particle.EnvParticle;
@AllArgsConstructor()
public class EnvParticleProvider implements ParticleProvider<SimpleParticleType> {
private final double SPEED_FACTOR = 0.25;
private final SpriteSet spriteSet;
@Nullable
@Override
public Particle createParticle(
@NotNull SimpleParticleType pType,
@NotNull ClientLevel pLevel,
double pX,
double pY,
double pZ,
double pXSpeed,
double pYSpeed,
double pZSpeed) {
return new EnvParticle(pLevel, pX, pY, pZ, spriteSet);
}
}

View File

@ -0,0 +1,30 @@
package robaertschi.environmenttech.client.renderer;
import lombok.AllArgsConstructor;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.util.FastColor;
/**
* @author RoBaertschi
*
* A ContentBoxRender that renders a box with the typical MC colors.
* @implNote The x, y, width and height are for the content, that means, the border is drawn around these values.
*/
@AllArgsConstructor
public class ContentBoxRenderer {
private final int x;
private final int y;
private final int width;
private final int height;
public void render(GuiGraphics guiGraphics) {
int cornerAndBackground = FastColor.ARGB32.color(139, 139, 139);
int dark = FastColor.ARGB32.color(55, 55, 55);
int bright = FastColor.ARGB32.color(255, 255, 255);
guiGraphics.fill(x - 1, y - 1, x + width + 1, y + height + 1, cornerAndBackground);
guiGraphics.fill(x - 1, y - 1, x + width, y, dark);
guiGraphics.fill(x - 1, y - 1, x, y + height, dark);
guiGraphics.fill(x + width, y + height, x + width + 1, y, bright);
guiGraphics.fill(x, y + height, x + width + 1, y + height + 1, bright);
}
}

View File

@ -0,0 +1,80 @@
package robaertschi.environmenttech.client.renderer;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Lombok;
import lombok.RequiredArgsConstructor;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.network.chat.Component;
import net.minecraft.util.FastColor;
import robaertschi.environmenttech.data.capabilities.IEnvStorage;
import robaertschi.environmenttech.utils.MouseUtils;
import java.util.List;
import java.util.Optional;
/*
* BluSunrize
* Copyright (c) 2021
*
* This code is licensed under "Blu's License of Common Sense"
* https://github.com/BluSunrize/ImmersiveEngineering/blob/1.19.2/LICENSE
*
* Slightly Modified Version by: Kaupenjoe
* Modified by RoBaertschi to fit personal needs.
*/
/**
* @author BluSunrize, Kaupenjoe, RoBaertschi
* @since 0.1.0
*/
public class EnvStorageRenderer {
private final int x;
private final int y;
private final int width;
private final int height;
private final IEnvStorage storage;
private final ContentBoxRenderer boxRenderer;
public EnvStorageRenderer(int x, int y, int width, int height, IEnvStorage storage) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.storage = storage;
boxRenderer = new ContentBoxRenderer(x, y, width, height);
}
public EnvStorageRenderer(int x, int y, IEnvStorage storage) {
this(x, y, 8, 64, storage);
}
public List<Component> getTooltips() {
return List.of(Component.literal(storage.getEnvStored() + " / " + storage.getMaxEnv() + " ENV"));
}
public void render(GuiGraphics guiGraphics) {
int stored = (int)(height * (storage.getEnvStored() / (float)storage.getMaxEnv()));
boxRenderer.render(guiGraphics);
int from = FastColor.ARGB32.color(0, 103, 29);
int to = FastColor.ARGB32.color(0,191, 38);
guiGraphics.fillGradient(x, y + (height - stored), x + width, y + height,
from, to);
}
public void renderTooltip(GuiGraphics guiGraphics, int mouseX, int mouseY, int leftPos, int topPos, Font font) {
if (isMouseAboveArea(mouseX, mouseY, x, y)) {
guiGraphics.renderTooltip(font, getTooltips(), Optional.empty(), mouseX - leftPos, mouseY - topPos);
}
}
private boolean isMouseAboveArea(int pMouseX, int pMouseY, int x, int y) {
return MouseUtils.isMouseOver(pMouseX, pMouseY, x, y, width, height);
}
}

View File

@ -1,42 +1,57 @@
package robaertschi.environmenttech.client.screen; package robaertschi.environmenttech.client.screen;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Inventory;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import robaertschi.environmenttech.EnvironmentTech; import robaertschi.environmenttech.EnvironmentTech;
import robaertschi.environmenttech.client.renderer.EnvStorageRenderer;
import robaertschi.environmenttech.menu.EnvCollectorMenu; import robaertschi.environmenttech.menu.EnvCollectorMenu;
public class EnvCollectorScreen extends AbstractContainerScreen<EnvCollectorMenu> { public class EnvCollectorScreen extends AbstractContainerScreen<EnvCollectorMenu> {
private final ResourceLocation GUI = EnvironmentTech.id("textures/gui/container/env_collector.png"); private final ResourceLocation GUI = EnvironmentTech.id("textures/gui/container/env_collector.png");
private EnvStorageRenderer storageRenderer;
public EnvCollectorScreen(EnvCollectorMenu pMenu, Inventory pPlayerInventory, Component pTitle) { public EnvCollectorScreen(EnvCollectorMenu pMenu, Inventory pPlayerInventory, Component pTitle) {
super(pMenu, pPlayerInventory, pTitle); super(pMenu, pPlayerInventory, pTitle);
this.inventoryLabelY = this.imageHeight - 94; this.inventoryLabelY = this.imageHeight - 94;
} }
@Override
protected void init() {
super.init();
storageRenderer = new EnvStorageRenderer(leftPos + 8, topPos + 11, menu.getBlockEntity().getEnvStorage());
}
@Override @Override
protected void renderBg(@NotNull GuiGraphics pGuiGraphics, float pPartialTick, int pMouseX, int pMouseY) { protected void renderBg(@NotNull GuiGraphics pGuiGraphics, float pPartialTick, int pMouseX, int pMouseY) {
int relX = (this.width - this.imageWidth) / 2; int relX = (this.width - this.imageWidth) / 2;
int relY = (this.height - this.imageHeight) / 2; int relY = (this.height - this.imageHeight) / 2;
pGuiGraphics.blit(GUI, relX, relY, 0, 0, this.imageWidth, this.imageHeight); pGuiGraphics.blit(GUI, relX, relY, 0, 0, this.imageWidth, this.imageHeight);
pGuiGraphics.blit(ProgressArrowComponent.SPRITE, pGuiGraphics.blit(ProgressArrowUtils.SPRITE,
relX + 78, relY + 35, relX + 78, relY + 35,
0, 0, 0, 0,
ProgressArrowComponent.getScaledProgress(menu.getProgress(), menu.getMaxProgress()),16, ProgressArrowUtils.getScaledProgress(menu.getProgress(), menu.getMaxProgress()),16,
24, 24,
16 16
); );
storageRenderer.render(pGuiGraphics);
}
@Override
protected void renderLabels(@NotNull GuiGraphics pGuiGraphics, int pMouseX, int pMouseY) {
storageRenderer.renderTooltip(pGuiGraphics, pMouseX, pMouseY, leftPos, topPos, font);
} }
@Override @Override
public void render(@NotNull GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) { public void render(@NotNull GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) {
renderBackground(pGuiGraphics, pMouseX, pMouseY, pPartialTick);
super.render(pGuiGraphics, pMouseX, pMouseY, pPartialTick); super.render(pGuiGraphics, pMouseX, pMouseY, pPartialTick);
this.renderTooltip(pGuiGraphics, pMouseX, pMouseY); this.renderTooltip(pGuiGraphics, pMouseX, pMouseY);
} }
} }

View File

@ -5,7 +5,7 @@ import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import robaertschi.environmenttech.EnvironmentTech; import robaertschi.environmenttech.EnvironmentTech;
public class ProgressArrowComponent { public class ProgressArrowUtils {
public static final ResourceLocation SPRITE = EnvironmentTech.id("textures/gui/sprites/component/progress_arrow.png"); public static final ResourceLocation SPRITE = EnvironmentTech.id("textures/gui/sprites/component/progress_arrow.png");
public static void draw(GuiGraphics guiGraphics, int x, int y, int progress) { public static void draw(GuiGraphics guiGraphics, int x, int y, int progress) {

View File

@ -0,0 +1,45 @@
package robaertschi.environmenttech.command;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.LongArgumentType;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.chunk.ChunkAccess;
import robaertschi.environmenttech.data.attachments.ETAttachments;
import static net.minecraft.commands.Commands.*;
public class EnvironmenttechCommand {
public EnvironmenttechCommand(CommandDispatcher<CommandSourceStack> dispatcher) {
dispatcher.register(
literal("environmenttech")
.requires(commandSourceStack -> commandSourceStack.hasPermission(1) && commandSourceStack.isPlayer())
.then(literal("set_chunk_env").then(argument("amount", LongArgumentType.longArg(0)).executes(
context -> {
long amount = context.getArgument("amount", Long.class);
Player player = context.getSource().getPlayerOrException();
Level level = player.level();
ChunkAccess chunk = level.getChunkAt(player.blockPosition());
chunk.setData(ETAttachments.ENV, amount);
context.getSource().sendSuccess(() -> Component.literal("Updated chunk at position " + chunk.getPos() + " to have " + amount + "ENV"), true);
return 1;
}
)))
.then(literal("get_chunk_env").executes(context -> {
Player player = context.getSource().getPlayerOrException();
Level level = player.level();
ChunkAccess chunk = level.getChunkAt(player.blockPosition());
long env = chunk.getData(ETAttachments.ENV);
context.getSource().sendSuccess(() -> Component.literal("The current Chunk contains " + env + "ENV"), true);
return 1;
}))
);
}
}

View File

@ -4,6 +4,7 @@ import net.minecraft.data.PackOutput;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.neoforged.neoforge.client.model.generators.BlockModelBuilder; import net.neoforged.neoforge.client.model.generators.BlockModelBuilder;
import net.neoforged.neoforge.client.model.generators.BlockStateProvider; import net.neoforged.neoforge.client.model.generators.BlockStateProvider;
import net.neoforged.neoforge.client.model.generators.ModelFile;
import net.neoforged.neoforge.client.model.generators.MultiPartBlockStateBuilder; import net.neoforged.neoforge.client.model.generators.MultiPartBlockStateBuilder;
import net.neoforged.neoforge.common.data.ExistingFileHelper; import net.neoforged.neoforge.common.data.ExistingFileHelper;
import robaertschi.environmenttech.level.block.ETBlocks; import robaertschi.environmenttech.level.block.ETBlocks;
@ -17,7 +18,8 @@ public class ETBlockStateProvider extends BlockStateProvider {
@Override @Override
protected void registerStatesAndModels() { protected void registerStatesAndModels() {
registerEnvCollector(); // registerEnvCollector();
horizontalBlock(ETBlocks.ENV_COLLECTOR_BLOCK.get(), new ModelFile.UncheckedModelFile(modLoc("block/env_collector")));
} }
private void registerEnvCollector() { private void registerEnvCollector() {

View File

@ -14,7 +14,7 @@ public class ETItemModelProvider extends ItemModelProvider {
@Override @Override
protected void registerModels() { protected void registerModels() {
withExistingParent(ETBlocks.ENV_COLLECTOR_BLOCK.getId().getPath(), modLoc("block/" + "env_collector_main")); withExistingParent(ETBlocks.ENV_COLLECTOR_BLOCK.getId().getPath(), modLoc("block/" + "env_collector"));
} }
} }

View File

@ -14,14 +14,23 @@ import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.BaseEntityBlock; import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.RenderShape; import net.minecraft.world.level.block.*;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityTicker; import net.minecraft.world.level.block.entity.BlockEntityTicker;
import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.DirectionProperty;
import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.shapes.BooleanOp;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import robaertschi.environmenttech.level.block.entity.ETBlockEntities; import robaertschi.environmenttech.level.block.entity.ETBlockEntities;
@ -35,12 +44,33 @@ import static robaertschi.environmenttech.EnvironmentTech.MODID;
@ParametersAreNonnullByDefault() @ParametersAreNonnullByDefault()
@Slf4j @Slf4j
public class EnvCollectorBlock extends BaseEntityBlock { public class EnvCollectorBlock extends BaseEntityBlock {
public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING;
public static final MapCodec<EnvCollectorBlock> CODEC = simpleCodec(EnvCollectorBlock::new); public static final MapCodec<EnvCollectorBlock> CODEC = simpleCodec(EnvCollectorBlock::new);
public EnvCollectorBlock(Properties properties) { public EnvCollectorBlock(Properties properties) {
super(properties); super(properties);
} }
public static VoxelShape makeShape(){
VoxelShape shape = Shapes.empty();
shape = Shapes.join(shape, Shapes.box(0, 0, 0, 1, 0.125, 1), BooleanOp.OR);
shape = Shapes.join(shape, Shapes.box(0, 0.8125, 0, 0.1875, 1, 0.8125), BooleanOp.OR);
shape = Shapes.join(shape, Shapes.box(0.1875, 0.8125, 0, 1, 1, 0.1875), BooleanOp.OR);
shape = Shapes.join(shape, Shapes.box(0, 0.8125, 0.8125, 0.8125, 1, 1), BooleanOp.OR);
shape = Shapes.join(shape, Shapes.box(0.8125, 0.8125, 0.1875, 1, 1, 1), BooleanOp.OR);
shape = Shapes.join(shape, Shapes.box(0.1875, 0.625, 0.1875, 0.8125, 0.8125, 0.8125), BooleanOp.OR);
shape = Shapes.join(shape, Shapes.box(0.375, 0.4375, 0.375, 0.625, 0.625, 0.625), BooleanOp.OR);
shape = Shapes.join(shape, Shapes.box(0.0625, 0.125, 0.0625, 0.1875, 0.8125, 0.1875), BooleanOp.OR);
shape = Shapes.join(shape, Shapes.box(0.8125, 0.125, 0.8125, 0.9375, 0.8125, 0.9375), BooleanOp.OR);
shape = Shapes.join(shape, Shapes.box(0.0625, 0.125, 0.8125, 0.1875, 0.8125, 0.9375), BooleanOp.OR);
shape = Shapes.join(shape, Shapes.box(0.8125, 0.125, 0.0625, 0.9375, 0.8125, 0.1875), BooleanOp.OR);
return shape;
}
public static VoxelShape SHAPE = makeShape();
@Override @Override
protected @NotNull MapCodec<? extends BaseEntityBlock> codec() { protected @NotNull MapCodec<? extends BaseEntityBlock> codec() {
return CODEC; return CODEC;
@ -52,6 +82,38 @@ public class EnvCollectorBlock extends BaseEntityBlock {
return RenderShape.MODEL; return RenderShape.MODEL;
} }
@Override
protected @NotNull VoxelShape getShape(BlockState pState, BlockGetter pLevel, BlockPos pPos, CollisionContext pContext) {
return SHAPE;
}
@Override
public @NotNull BlockState rotate(BlockState state, LevelAccessor level, BlockPos pos, Rotation direction) {
return state.setValue(FACING, direction.rotate(state.getValue(FACING)));
}
@Override
protected @NotNull BlockState mirror(BlockState pState, Mirror pMirror) {
return pState.rotate(pMirror.getRotation(pState.getValue(FACING)));
}
@Nullable
@Override
public BlockState getStateForPlacement(BlockPlaceContext pContext) {
return this.defaultBlockState().setValue(FACING, pContext.getHorizontalDirection().getOpposite());
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> pBuilder) {
pBuilder.add(FACING);
}
@Override
protected void onRemove(BlockState pState, Level pLevel, BlockPos pPos, BlockState pNewState, boolean pMovedByPiston) {
pLevel.updateNeighborsAt(pPos, this);
super.onRemove(pState, pLevel, pPos, pNewState, pMovedByPiston);
}
@Nullable @Nullable
@Override @Override
public BlockEntity newBlockEntity(BlockPos pPos, BlockState pState) { public BlockEntity newBlockEntity(BlockPos pPos, BlockState pState) {

View File

@ -3,7 +3,6 @@ package robaertschi.environmenttech.level.block.entity;
import lombok.Getter; import lombok.Getter;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.HolderLookup; import net.minecraft.core.HolderLookup;
import net.minecraft.core.registries.Registries;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.Connection; import net.minecraft.network.Connection;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
@ -42,6 +41,10 @@ public class EnvCollectorBlockEntity extends BlockEntity implements MenuProvider
public static final int SLOT_OUTPUT_COUNT = 1; public static final int SLOT_OUTPUT_COUNT = 1;
public static final int SLOT_COUNT = SLOT_INPUT_COUNT + SLOT_OUTPUT_COUNT; public static final int SLOT_COUNT = SLOT_INPUT_COUNT + SLOT_OUTPUT_COUNT;
public static final String INVENTORY_KEY = "Inventory";
public static final String ENV_KEY = "ENV";
public static final String PROGRESS_KEY = "Progress";
public static final String MAX_PROGRESS_KEY = "MaxProgress";
@Getter @Getter
private final ItemStackHandler inventory = new ItemStackHandler(2) { private final ItemStackHandler inventory = new ItemStackHandler(2) {
@ -76,12 +79,12 @@ public class EnvCollectorBlockEntity extends BlockEntity implements MenuProvider
}; };
@Getter @Getter
private ContainerData data; private final ContainerData data;
@Getter @Getter
private int progress = 0; private int progress = 0;
@Getter @Getter
private int maxProgress = 10; private int maxProgress = 100;
// Every 20 ticks, we take ENV from the current Chunk // Every 20 ticks, we take ENV from the current Chunk
private int takeEnv = 0; private int takeEnv = 0;
@Nullable @Nullable
@ -115,23 +118,30 @@ public class EnvCollectorBlockEntity extends BlockEntity implements MenuProvider
}; };
} }
@Override @Override
protected void loadAdditional(@NotNull CompoundTag pTag, HolderLookup.@NotNull Provider provider) { protected void loadAdditional(@NotNull CompoundTag pTag, HolderLookup.@NotNull Provider provider) {
super.loadAdditional(pTag, provider); super.loadAdditional(pTag, provider);
CompoundTag modData = pTag.getCompound(MODID); CompoundTag modData = pTag.getCompound(MODID);
this.inventory.deserializeNBT(provider, modData.getCompound("Inventory")); this.inventory.deserializeNBT(provider, modData.getCompound(INVENTORY_KEY));
this.envStorage.setEnvStored(modData.getLong("ENV")); this.envStorage.setEnvStored(modData.getLong(ENV_KEY));
this.progress = modData.getInt(PROGRESS_KEY);
// this.maxProgress = modData.getInt(MAX_PROGRESS_KEY);
} }
@Override @Override
protected void saveAdditional(@NotNull CompoundTag pTag, HolderLookup.@NotNull Provider provider) { protected void saveAdditional(@NotNull CompoundTag pTag, HolderLookup.@NotNull Provider provider) {
super.saveAdditional(pTag, provider); super.saveAdditional(pTag, provider);
CompoundTag modData = new CompoundTag(); CompoundTag modData = new CompoundTag();
modData.put("Inventory", inventory.serializeNBT(provider)); modData.put(INVENTORY_KEY, inventory.serializeNBT(provider));
modData.putLong("ENV", envStorage.getEnvStored()); modData.putLong(ENV_KEY, envStorage.getEnvStored());
modData.putInt(PROGRESS_KEY, progress);
// modData.putInt(MAX_PROGRESS_KEY, maxProgress);
pTag.put(MODID, modData); pTag.put(MODID, modData);
} }
public ItemStack getInputItem() { public ItemStack getInputItem() {
return this.inventory.getStackInSlot(0); return this.inventory.getStackInSlot(0);
} }
@ -166,20 +176,22 @@ public class EnvCollectorBlockEntity extends BlockEntity implements MenuProvider
if (hasRecipe(level)) { if (hasRecipe(level)) {
if (progress > 0 && progress < getMaxProgress()) { if (progress > 0 && progress < getMaxProgress()) {
progress++; progress++;
// setChanged();
// level.sendBlockUpdated(getBlockPos(), blockState, blockState, Block.UPDATE_CLIENTS);
} else if (progress > 0) { } else if (progress > 0) {
produce(level); produce(level);
progress = 0; progress = 0;
} else if (getOutputItem().getCount() < getOutputItem().getMaxStackSize()){ } else if (getOutputItem().getCount() < getOutputItem().getMaxStackSize()){
assert currentRecipe != null; assert currentRecipe != null;
// if (envStorage.getEnvStored() >= currentRecipe.envUsed()) { if (envStorage.getEnvStored() >= currentRecipe.envUsed()) {
// envStorage.setEnvStored(envStorage.getEnvStored() - currentRecipe.envUsed()); envStorage.setEnvStored(envStorage.getEnvStored() - currentRecipe.envUsed());
// progress = 1; progress = 1;
// } }
progress = 1;
} }
} }
} }
private void produce(ServerLevel level) { private void produce(ServerLevel level) {

View File

@ -0,0 +1,76 @@
package robaertschi.environmenttech.level.block.entity.renderer;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Axis;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.client.renderer.entity.ItemRenderer;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.core.BlockPos;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.world.item.ItemDisplayContext;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LightLayer;
import robaertschi.environmenttech.level.block.EnvCollectorBlock;
import robaertschi.environmenttech.level.block.entity.EnvCollectorBlockEntity;
import robaertschi.environmenttech.level.particle.ETParticles;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.Objects;
@ParametersAreNonnullByDefault
public class EnvCollectorRenderer implements BlockEntityRenderer<EnvCollectorBlockEntity> {
public EnvCollectorRenderer(BlockEntityRendererProvider.Context context) {}
public int spawnParticle = 0;
@Override
public void render(EnvCollectorBlockEntity pBlockEntity, float pPartialTick, PoseStack pPoseStack, MultiBufferSource pBuffer, int pPackedLight, int pPackedOverlay) {
ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer();
ItemStack inputItem = pBlockEntity.getInputItem();
pPoseStack.pushPose();
pPoseStack.translate(0.5, 0.125, 0.5);
pPoseStack.scale(0.35f, 0.35f, 0.35f);
finishItemRender(pBlockEntity, pPoseStack, pBuffer, inputItem, itemRenderer);
ItemStack outputItem = pBlockEntity.getOutputItem();
pPoseStack.pushPose();
pPoseStack.translate(0.5, 0.125, 0.8);
pPoseStack.scale(0.3f, 0.3f, 0.3f);
finishItemRender(pBlockEntity, pPoseStack, pBuffer, outputItem, itemRenderer);
var pos = pBlockEntity.getBlockPos();
//level.sendParticles(ParticleTypes.GLOW, blockPos.getX() + 0.5, blockPos.getY() + 0.5, blockPos.getZ() + 0.5, 1, 0, 0, 0, -1);
if (pBlockEntity.getProgress() > 0) {
if (spawnParticle <= 0) {
Objects.requireNonNull(pBlockEntity.getLevel()).addParticle(ETParticles.ENV_PARTICLE.get(), pos.getX() + 0.5, pos.getY() + 0.4, pos.getZ() + 0.5, 0, -10, 0);
spawnParticle = 30;
} else {
spawnParticle--;
}
}
}
private void finishItemRender(EnvCollectorBlockEntity pBlockEntity, PoseStack pPoseStack, MultiBufferSource pBuffer, ItemStack itemStack1, ItemRenderer itemRenderer) {
pPoseStack.mulPose(Axis.YN.rotationDegrees(pBlockEntity.getBlockState().getValue(EnvCollectorBlock.FACING).toYRot()));
pPoseStack.mulPose(Axis.XP.rotationDegrees(270));
itemRenderer.renderStatic(itemStack1, ItemDisplayContext.FIXED, getLightLevel(Objects.requireNonNull(pBlockEntity.getLevel()), pBlockEntity.getBlockPos()),
OverlayTexture.NO_OVERLAY, pPoseStack, pBuffer, pBlockEntity.getLevel(), 1);
pPoseStack.popPose();
}
private int getLightLevel(Level level, BlockPos pos) {
int bLight = level.getBrightness(LightLayer.BLOCK, pos);
int sLight = level.getBrightness(LightLayer.SKY, pos);
return LightTexture.pack(bLight, sLight);
}
}

View File

@ -0,0 +1,22 @@
package robaertschi.environmenttech.level.particle;
import net.minecraft.core.particles.ParticleType;
import net.minecraft.core.particles.SimpleParticleType;
import net.minecraft.core.registries.BuiltInRegistries;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.neoforge.registries.DeferredHolder;
import net.neoforged.neoforge.registries.DeferredRegister;
import static robaertschi.environmenttech.EnvironmentTech.MODID;
public class ETParticles {
public static final DeferredRegister<ParticleType<?>> PARTICLES = DeferredRegister.create(BuiltInRegistries.PARTICLE_TYPE, MODID);
public static final DeferredHolder<ParticleType<?>, SimpleParticleType> ENV_PARTICLE = PARTICLES.register("env_particle",
() -> new SimpleParticleType(false)
);
public static void init(IEventBus modEventBus) {
PARTICLES.register(modEventBus);
}
}

View File

@ -0,0 +1,44 @@
package robaertschi.environmenttech.level.particle;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.particle.ParticleRenderType;
import net.minecraft.client.particle.SpriteSet;
import net.minecraft.client.particle.TextureSheetParticle;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.ParticleType;
import org.jetbrains.annotations.NotNull;
public class EnvParticle extends TextureSheetParticle implements ParticleOptions {
private final SpriteSet spriteSet;
public EnvParticle(ClientLevel pLevel, double pX, double pY, double pZ, SpriteSet spriteSet) {
super(pLevel, pX, pY, pZ);
this.friction = 0.8f;
this.spriteSet = spriteSet;
// this.gravity = 0;
this.gravity = 0.025f;
lifetime = 50;
this.quadSize *= 0.35f;
this.setSpriteFromAge(spriteSet);
this.rCol = 1f;
this.gCol = 1f;
this.bCol = 1f;
}
@Override
public @NotNull ParticleRenderType getRenderType() {
return ParticleRenderType.PARTICLE_SHEET_LIT;
}
@Override
public void tick() {
super.tick();
setSpriteFromAge(spriteSet);
}
@Override
public @NotNull ParticleType<?> getType() {
return ETParticles.ENV_PARTICLE.get();
}
}

View File

@ -1,6 +1,6 @@
package robaertschi.environmenttech.menu; package robaertschi.environmenttech.menu;
import net.minecraft.core.BlockPos; import lombok.Getter;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.Container; import net.minecraft.world.Container;
import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Inventory;
@ -9,7 +9,6 @@ import net.minecraft.world.inventory.*;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.neoforged.neoforge.items.SlotItemHandler; import net.neoforged.neoforge.items.SlotItemHandler;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import robaertschi.environmenttech.level.block.ETBlocks; import robaertschi.environmenttech.level.block.ETBlocks;
import robaertschi.environmenttech.level.block.entity.EnvCollectorBlockEntity; import robaertschi.environmenttech.level.block.entity.EnvCollectorBlockEntity;
@ -18,6 +17,7 @@ import static robaertschi.environmenttech.level.block.entity.EnvCollectorBlockEn
public class EnvCollectorMenu extends AbstractContainerMenu { public class EnvCollectorMenu extends AbstractContainerMenu {
@Getter
private final EnvCollectorBlockEntity blockEntity; private final EnvCollectorBlockEntity blockEntity;
private final ContainerData data; private final ContainerData data;

View File

@ -0,0 +1,15 @@
package robaertschi.environmenttech.utils;
public class MouseUtils {
public static boolean isMouseOver(double mouseX, double mouseY, int x, int y) {
return isMouseOver(mouseX, mouseY, x, y, 16);
}
public static boolean isMouseOver(double mouseX, double mouseY, int x, int y, int size) {
return isMouseOver(mouseX, mouseY, x, y, size, size);
}
public static boolean isMouseOver(double mouseX, double mouseY, int x, int y, int sizeX, int sizeY) {
return (mouseX >= x && mouseX <= x + sizeX) && (mouseY >= y && mouseY <= y + sizeY);
}
}

View File

@ -3,5 +3,8 @@
"item.environmenttech.environmental_essence": "Environmental Essence", "item.environmenttech.environmental_essence": "Environmental Essence",
"itemGroup.environmenttech": "Environment Tech", "itemGroup.environmenttech": "Environment Tech",
"screen.environmenttech.env_collector": "ENV Collector" "screen.environmenttech.env_collector": "ENV Collector",
"screen.environmenttech.debug": "Debug Menu",
"key.environmenttech.open_debug_menu": "Open Debug Menu",
"key.categories.environmenttech": "Environment Tech"
} }

View File

@ -0,0 +1,217 @@
{
"credit": "Made with Blockbench",
"texture_size": [128, 128],
"textures": {
"1": "environmenttech:block/env_collector",
"particle": "#1"
},
"elements": [
{
"name": "base",
"from": [0, 0, 0],
"to": [16, 2, 16],
"faces": {
"north": {"uv": [2, 2, 4, 2.25], "texture": "#1"},
"east": {"uv": [0, 2, 2, 2.25], "texture": "#1"},
"south": {"uv": [6, 2, 8, 2.25], "texture": "#1"},
"west": {"uv": [4, 2, 6, 2.25], "texture": "#1"},
"up": {"uv": [4, 2, 2, 0], "texture": "#1"},
"down": {"uv": [6, 0, 4, 2], "texture": "#1"}
}
},
{
"from": [0, 13, 0],
"to": [3, 16, 13],
"rotation": {"angle": 0, "axis": "y", "origin": [0, 17, 0]},
"faces": {
"north": {"uv": [1.625, 5.75, 2, 6.125], "texture": "#1"},
"east": {"uv": [0, 5.75, 1.625, 6.125], "texture": "#1"},
"south": {"uv": [3.625, 5.75, 4, 6.125], "texture": "#1"},
"west": {"uv": [2, 5.75, 3.625, 6.125], "texture": "#1"},
"up": {"uv": [2, 5.75, 1.625, 4.125], "texture": "#1"},
"down": {"uv": [2.375, 4.125, 2, 5.75], "texture": "#1"}
}
},
{
"from": [13, 13, 3],
"to": [16, 16, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [13, 17, 3]},
"faces": {
"north": {"uv": [5.125, 4.125, 5.5, 4.5], "texture": "#1"},
"east": {"uv": [3.5, 4.125, 5.125, 4.5], "texture": "#1"},
"south": {"uv": [7.125, 4.125, 7.5, 4.5], "texture": "#1"},
"west": {"uv": [5.5, 4.125, 7.125, 4.5], "texture": "#1"},
"up": {"uv": [5.5, 4.125, 5.125, 2.5], "texture": "#1"},
"down": {"uv": [5.875, 2.5, 5.5, 4.125], "texture": "#1"}
}
},
{
"from": [3, 13, 0],
"to": [16, 16, 3],
"rotation": {"angle": 0, "axis": "y", "origin": [3, 17, 3]},
"faces": {
"north": {"uv": [4.5, 5.875, 6.125, 6.25], "texture": "#1"},
"east": {"uv": [4.125, 5.875, 4.5, 6.25], "texture": "#1"},
"south": {"uv": [6.5, 5.875, 8.125, 6.25], "texture": "#1"},
"west": {"uv": [6.125, 5.875, 6.5, 6.25], "texture": "#1"},
"up": {"uv": [6.125, 5.875, 4.5, 5.5], "texture": "#1"},
"down": {"uv": [7.75, 5.5, 6.125, 5.875], "texture": "#1"}
}
},
{
"from": [0, 13, 13],
"to": [13, 16, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [0, 17, 16]},
"faces": {
"north": {"uv": [2.875, 5, 4.5, 5.375], "texture": "#1"},
"east": {"uv": [2.5, 5, 2.875, 5.375], "texture": "#1"},
"south": {"uv": [4.875, 5, 6.5, 5.375], "texture": "#1"},
"west": {"uv": [4.5, 5, 4.875, 5.375], "texture": "#1"},
"up": {"uv": [4.5, 5, 2.875, 4.625], "texture": "#1"},
"down": {"uv": [6.125, 4.625, 4.5, 5], "texture": "#1"}
}
},
{
"name": "middle",
"from": [3, 10, 3],
"to": [13, 13, 13],
"rotation": {"angle": 0, "axis": "y", "origin": [3, 10, 3]},
"faces": {
"north": {"uv": [1.25, 3.625, 2.5, 4], "texture": "#1"},
"east": {"uv": [0, 3.625, 1.25, 4], "texture": "#1"},
"south": {"uv": [3.75, 3.625, 5, 4], "texture": "#1"},
"west": {"uv": [2.5, 3.625, 3.75, 4], "texture": "#1"},
"up": {"uv": [2.5, 3.625, 1.25, 2.375], "texture": "#1"},
"down": {"uv": [3.75, 2.375, 2.5, 3.625], "texture": "#1"}
}
},
{
"name": "bottom",
"from": [6, 7, 6],
"to": [10, 10, 10],
"rotation": {"angle": 0, "axis": "y", "origin": [6, 7, 7]},
"faces": {
"north": {"uv": [6.5, 2.875, 7, 3.25], "texture": "#1"},
"east": {"uv": [6, 2.875, 6.5, 3.25], "texture": "#1"},
"south": {"uv": [7.5, 2.875, 8, 3.25], "texture": "#1"},
"west": {"uv": [7, 2.875, 7.5, 3.25], "texture": "#1"},
"up": {"uv": [7, 2.875, 6.5, 2.375], "texture": "#1"},
"down": {"uv": [7.5, 2.375, 7, 2.875], "texture": "#1"}
}
},
{
"from": [1, 2, 1],
"to": [3, 13, 3],
"rotation": {"angle": 0, "axis": "y", "origin": [1, 2, 1]},
"faces": {
"north": {"uv": [1.375, 6.5, 1.625, 7.875], "texture": "#1"},
"east": {"uv": [1.125, 6.5, 1.375, 7.875], "texture": "#1"},
"south": {"uv": [1.875, 6.5, 2.125, 7.875], "texture": "#1"},
"west": {"uv": [1.625, 6.5, 1.875, 7.875], "texture": "#1"},
"up": {"uv": [1.625, 6.5, 1.375, 6.25], "texture": "#1"},
"down": {"uv": [1.875, 6.25, 1.625, 6.5], "texture": "#1"}
}
},
{
"from": [13, 2, 13],
"to": [15, 13, 15],
"rotation": {"angle": 0, "axis": "y", "origin": [13, 2, 13]},
"faces": {
"north": {"uv": [0.25, 6.5, 0.5, 7.875], "texture": "#1"},
"east": {"uv": [0, 6.5, 0.25, 7.875], "texture": "#1"},
"south": {"uv": [0.75, 6.5, 1, 7.875], "texture": "#1"},
"west": {"uv": [0.5, 6.5, 0.75, 7.875], "texture": "#1"},
"up": {"uv": [0.5, 6.5, 0.25, 6.25], "texture": "#1"},
"down": {"uv": [0.75, 6.25, 0.5, 6.5], "texture": "#1"}
}
},
{
"from": [13, 2, 1],
"to": [15, 13, 3],
"rotation": {"angle": 0, "axis": "y", "origin": [13, 2, 1]},
"faces": {
"north": {"uv": [6.375, 0.25, 6.625, 1.625], "texture": "#1"},
"east": {"uv": [6.125, 0.25, 6.375, 1.625], "texture": "#1"},
"south": {"uv": [6.875, 0.25, 7.125, 1.625], "texture": "#1"},
"west": {"uv": [6.625, 0.25, 6.875, 1.625], "texture": "#1"},
"up": {"uv": [6.625, 0.25, 6.375, 0], "texture": "#1"},
"down": {"uv": [6.875, 0, 6.625, 0.25], "texture": "#1"}
}
},
{
"from": [1, 2, 13],
"to": [3, 13, 15],
"rotation": {"angle": 0, "axis": "y", "origin": [1, 2, 13]},
"faces": {
"north": {"uv": [0.25, 0.25, 0.5, 1.625], "texture": "#1"},
"east": {"uv": [0, 0.25, 0.25, 1.625], "texture": "#1"},
"south": {"uv": [0.75, 0.25, 1, 1.625], "texture": "#1"},
"west": {"uv": [0.5, 0.25, 0.75, 1.625], "texture": "#1"},
"up": {"uv": [0.5, 0.25, 0.25, 0], "texture": "#1"},
"down": {"uv": [0.75, 0, 0.5, 0.25], "texture": "#1"}
}
}
],
"display": {
"thirdperson_righthand": {
"rotation": [75, 45, 0],
"translation": [0, 2.5, 0],
"scale": [0.375, 0.375, 0.375]
},
"thirdperson_lefthand": {
"rotation": [75, 45, 0],
"translation": [0, 2.5, 0],
"scale": [0.375, 0.375, 0.375]
},
"firstperson_righthand": {
"rotation": [0, 45, 0],
"scale": [0.4, 0.4, 0.4]
},
"firstperson_lefthand": {
"rotation": [0, 225, 0],
"scale": [0.4, 0.4, 0.4]
},
"ground": {
"translation": [0, 3, 0],
"scale": [0.25, 0.25, 0.25]
},
"gui": {
"rotation": [30, 225, 0],
"scale": [0.625, 0.625, 0.625]
},
"fixed": {
"scale": [0.5, 0.5, 0.5]
}
},
"groups": [
{
"name": "main",
"origin": [8, 8, 8],
"color": 0,
"children": [
0,
{
"name": "hopper",
"origin": [8, 8, 8],
"color": 3,
"children": [
{
"name": "top",
"origin": [8, 8, 8],
"color": 3,
"children": [1, 2, 3, 4]
},
5,
6
]
},
{
"name": "pillars",
"origin": [8, 8, 8],
"color": 1,
"children": [7, 8, 9, 10]
}
]
}
]
}

View File

@ -0,0 +1,9 @@
{
"textures": [
"environmenttech:env_particle_0",
"environmenttech:env_particle_1",
"environmenttech:env_particle_2",
"environmenttech:env_particle_3",
"environmenttech:env_particle_4"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 B

View File

@ -1,17 +0,0 @@
package robaertschi.environmenttech.test;
import net.neoforged.testframework.conf.ClientConfiguration;
import net.neoforged.testframework.conf.FrameworkConfiguration;
import net.neoforged.testframework.impl.MutableTestFramework;
import org.lwjgl.glfw.GLFW;
import robaertschi.environmenttech.EnvironmentTech;
public class TestMain {
final MutableTestFramework framework = FrameworkConfiguration.builder(EnvironmentTech.id("tests"))
.clientConfiguration(() -> ClientConfiguration.builder()
.toggleOverlayKey(GLFW.GLFW_KEY_J)
.openManagerKey(GLFW.GLFW_KEY_N)
.build())
.build().create();
}