From ef60e26b70664eb0928f85e331a8d027de689d68 Mon Sep 17 00:00:00 2001 From: NinjaPhenix Date: Fri, 20 Mar 2020 12:40:12 +0000 Subject: [PATCH] Torcherino... --- .../java/ninjaphenix/chainmail/impl/Main.java | 2 + settings.gradle | 3 +- torcherino/build.gradle | 11 + torcherino/gradle.properties | 2 + .../src/main/java/torcherino/Torcherino.java | 89 ++++++++ .../java/torcherino/TorcherinoClient.java | 79 +++++++ .../src/main/java/torcherino/api/Tier.java | 21 ++ .../java/torcherino/api/TierSupplier.java | 8 + .../java/torcherino/api/TorcherinoAPI.java | 87 ++++++++ .../java/torcherino/api/TorcherinoLogic.java | 74 +++++++ .../api/blocks/JackoLanterinoBlock.java | 74 +++++++ .../torcherino/api/blocks/LanterinoBlock.java | 96 ++++++++ .../api/blocks/TorcherinoBlock.java | 92 ++++++++ .../api/blocks/WallTorcherinoBlock.java | 95 ++++++++ .../entity/TocherinoBlockEntityType.java | 17 ++ .../blocks/entity/TorcherinoBlockEntity.java | 175 +++++++++++++++ .../entrypoints/TorcherinoInitializer.java | 14 ++ .../torcherino/api/impl/TorcherinoImpl.java | 128 +++++++++++ .../java/torcherino/blocks/ModBlocks.java | 99 +++++++++ .../client/screen/TorcherinoScreen.java | 208 ++++++++++++++++++ .../screen/widgets/FixedSliderWidget.java | 35 +++ .../screen/widgets/StateButtonWidget.java | 53 +++++ .../main/java/torcherino/config/Config.java | 84 +++++++ .../java/torcherino/config/ConfigManager.java | 105 +++++++++ .../torcherino/mixins/PlayerManagerMixin.java | 41 ++++ .../blockstates/compressed_lanterino.json | 19 ++ .../blockstates/compressed_lantern.json | 10 + .../blockstates/compressed_torcherino.json | 7 + .../double_compressed_lanterino.json | 19 ++ .../double_compressed_lantern.json | 10 + .../double_compressed_torcherino.json | 7 + .../torcherino/blockstates/lanterino.json | 19 ++ .../torcherino/blockstates/lantern.json | 10 + .../torcherino/blockstates/torcherino.json | 7 + .../wall_compressed_torcherino.json | 19 ++ .../wall_double_compressed_torcherino.json | 19 ++ .../blockstates/wall_torcherino.json | 19 ++ .../main/resources/assets/torcherino/icon.png | Bin 0 -> 22002 bytes .../assets/torcherino/lang/en_us.json | 21 ++ .../assets/torcherino/lang/zh_cn.json | 18 ++ .../block/compressed_hanging_lantern.json | 7 + .../models/block/compressed_lanterino.json | 8 + .../models/block/compressed_lantern.json | 7 + .../models/block/compressed_torcherino.json | 6 + .../double_compressed_hanging_lantern.json | 7 + .../block/double_compressed_lanterino.json | 8 + .../block/double_compressed_lantern.json | 7 + .../block/double_compressed_torcherino.json | 6 + .../models/block/hanging_lantern.json | 7 + .../torcherino/models/block/lanterino.json | 8 + .../torcherino/models/block/lantern.json | 7 + .../torcherino/models/block/torcherino.json | 6 + .../block/wall_compressed_torcherino.json | 135 ++++++++++++ .../wall_double_compressed_torcherino.json | 135 ++++++++++++ .../models/block/wall_torcherino.json | 135 ++++++++++++ .../models/item/compressed_lanterino.json | 3 + .../models/item/compressed_lantern.json | 6 + .../models/item/compressed_torcherino.json | 6 + .../item/double_compressed_lanterino.json | 3 + .../item/double_compressed_lantern.json | 6 + .../item/double_compressed_torcherino.json | 6 + .../torcherino/models/item/lanterino.json | 3 + .../torcherino/models/item/lantern.json | 6 + .../torcherino/models/item/torcherino.json | 6 + .../particles/compressed_flame.json | 5 + .../particles/double_compressed_flame.json | 5 + .../assets/torcherino/particles/flame.json | 5 + .../textures/blocks/compressed_lanterino.png | Bin 0 -> 240 bytes .../blocks/compressed_lanterino_side.png | Bin 0 -> 183 bytes .../blocks/compressed_lanterino_top.png | Bin 0 -> 211 bytes .../textures/blocks/compressed_lantern.png | Bin 0 -> 284 bytes .../blocks/compressed_lantern.png.mcmeta | 5 + .../textures/blocks/compressed_torcherino.png | Bin 0 -> 163 bytes .../blocks/double_compressed_lanterino.png | Bin 0 -> 224 bytes .../double_compressed_lanterino_side.png | Bin 0 -> 183 bytes .../double_compressed_lanterino_top.png | Bin 0 -> 206 bytes .../blocks/double_compressed_lantern.png | Bin 0 -> 284 bytes .../double_compressed_lantern.png.mcmeta | 5 + .../blocks/double_compressed_torcherino.png | Bin 0 -> 150 bytes .../torcherino/textures/blocks/lanterino.png | Bin 0 -> 240 bytes .../torcherino/textures/blocks/lantern.png | Bin 0 -> 284 bytes .../textures/blocks/lantern.png.mcmeta | 5 + .../torcherino/textures/blocks/torcherino.png | Bin 0 -> 163 bytes .../textures/item/compressed_lantern.png | Bin 0 -> 170 bytes .../item/double_compressed_lantern.png | Bin 0 -> 170 bytes .../torcherino/textures/item/lantern.png | Bin 0 -> 170 bytes .../textures/particle/compressed_flame.png | Bin 0 -> 129 bytes .../particle/double_compressed_flame.png | Bin 0 -> 129 bytes .../torcherino/textures/particle/flame.png | Bin 0 -> 129 bytes .../textures/screens/torcherino.png | Bin 0 -> 287 bytes .../blocks/compressed_lanterino.json | 71 ++++++ .../blocks/compressed_lantern.json | 71 ++++++ .../blocks/compressed_torcherino.json | 25 +++ .../blocks/double_compressed_lanterino.json | 71 ++++++ .../blocks/double_compressed_lantern.json | 71 ++++++ .../blocks/double_compressed_torcherino.json | 25 +++ .../loot_tables/blocks/lanterino.json | 71 ++++++ .../loot_tables/blocks/lantern.json | 71 ++++++ .../loot_tables/blocks/torcherino.json | 25 +++ .../recipes/compressed_lanterino.json | 14 ++ .../recipes/compressed_lantern.json | 14 ++ .../recipes/compressed_torcherino.json | 16 ++ .../compressed_torcherino_to_single.json | 12 + .../recipes/double_compressed_lanterino.json | 14 ++ .../recipes/double_compressed_lantern.json | 14 ++ .../recipes/double_compressed_torcherino.json | 16 ++ ...e_compressed_torcherino_to_compressed.json | 12 + .../data/torcherino/recipes/lanterino.json | 14 ++ .../data/torcherino/recipes/lantern.json | 14 ++ .../data/torcherino/recipes/torcherino.json | 19 ++ torcherino/src/main/resources/fabric.mod.json | 39 ++++ .../src/main/resources/torcherino.mixins.json | 12 + 112 files changed, 3170 insertions(+), 1 deletion(-) create mode 100644 torcherino/build.gradle create mode 100644 torcherino/gradle.properties create mode 100644 torcherino/src/main/java/torcherino/Torcherino.java create mode 100644 torcherino/src/main/java/torcherino/TorcherinoClient.java create mode 100644 torcherino/src/main/java/torcherino/api/Tier.java create mode 100644 torcherino/src/main/java/torcherino/api/TierSupplier.java create mode 100644 torcherino/src/main/java/torcherino/api/TorcherinoAPI.java create mode 100644 torcherino/src/main/java/torcherino/api/TorcherinoLogic.java create mode 100644 torcherino/src/main/java/torcherino/api/blocks/JackoLanterinoBlock.java create mode 100644 torcherino/src/main/java/torcherino/api/blocks/LanterinoBlock.java create mode 100644 torcherino/src/main/java/torcherino/api/blocks/TorcherinoBlock.java create mode 100644 torcherino/src/main/java/torcherino/api/blocks/WallTorcherinoBlock.java create mode 100644 torcherino/src/main/java/torcherino/api/blocks/entity/TocherinoBlockEntityType.java create mode 100644 torcherino/src/main/java/torcherino/api/blocks/entity/TorcherinoBlockEntity.java create mode 100644 torcherino/src/main/java/torcherino/api/entrypoints/TorcherinoInitializer.java create mode 100644 torcherino/src/main/java/torcherino/api/impl/TorcherinoImpl.java create mode 100644 torcherino/src/main/java/torcherino/blocks/ModBlocks.java create mode 100644 torcherino/src/main/java/torcherino/client/screen/TorcherinoScreen.java create mode 100644 torcherino/src/main/java/torcherino/client/screen/widgets/FixedSliderWidget.java create mode 100644 torcherino/src/main/java/torcherino/client/screen/widgets/StateButtonWidget.java create mode 100644 torcherino/src/main/java/torcherino/config/Config.java create mode 100644 torcherino/src/main/java/torcherino/config/ConfigManager.java create mode 100644 torcherino/src/main/java/torcherino/mixins/PlayerManagerMixin.java create mode 100644 torcherino/src/main/resources/assets/torcherino/blockstates/compressed_lanterino.json create mode 100644 torcherino/src/main/resources/assets/torcherino/blockstates/compressed_lantern.json create mode 100644 torcherino/src/main/resources/assets/torcherino/blockstates/compressed_torcherino.json create mode 100644 torcherino/src/main/resources/assets/torcherino/blockstates/double_compressed_lanterino.json create mode 100644 torcherino/src/main/resources/assets/torcherino/blockstates/double_compressed_lantern.json create mode 100644 torcherino/src/main/resources/assets/torcherino/blockstates/double_compressed_torcherino.json create mode 100644 torcherino/src/main/resources/assets/torcherino/blockstates/lanterino.json create mode 100644 torcherino/src/main/resources/assets/torcherino/blockstates/lantern.json create mode 100644 torcherino/src/main/resources/assets/torcherino/blockstates/torcherino.json create mode 100644 torcherino/src/main/resources/assets/torcherino/blockstates/wall_compressed_torcherino.json create mode 100644 torcherino/src/main/resources/assets/torcherino/blockstates/wall_double_compressed_torcherino.json create mode 100644 torcherino/src/main/resources/assets/torcherino/blockstates/wall_torcherino.json create mode 100644 torcherino/src/main/resources/assets/torcherino/icon.png create mode 100644 torcherino/src/main/resources/assets/torcherino/lang/en_us.json create mode 100644 torcherino/src/main/resources/assets/torcherino/lang/zh_cn.json create mode 100644 torcherino/src/main/resources/assets/torcherino/models/block/compressed_hanging_lantern.json create mode 100644 torcherino/src/main/resources/assets/torcherino/models/block/compressed_lanterino.json create mode 100644 torcherino/src/main/resources/assets/torcherino/models/block/compressed_lantern.json create mode 100644 torcherino/src/main/resources/assets/torcherino/models/block/compressed_torcherino.json create mode 100644 torcherino/src/main/resources/assets/torcherino/models/block/double_compressed_hanging_lantern.json create mode 100644 torcherino/src/main/resources/assets/torcherino/models/block/double_compressed_lanterino.json create mode 100644 torcherino/src/main/resources/assets/torcherino/models/block/double_compressed_lantern.json create mode 100644 torcherino/src/main/resources/assets/torcherino/models/block/double_compressed_torcherino.json create mode 100644 torcherino/src/main/resources/assets/torcherino/models/block/hanging_lantern.json create mode 100644 torcherino/src/main/resources/assets/torcherino/models/block/lanterino.json create mode 100644 torcherino/src/main/resources/assets/torcherino/models/block/lantern.json create mode 100644 torcherino/src/main/resources/assets/torcherino/models/block/torcherino.json create mode 100644 torcherino/src/main/resources/assets/torcherino/models/block/wall_compressed_torcherino.json create mode 100644 torcherino/src/main/resources/assets/torcherino/models/block/wall_double_compressed_torcherino.json create mode 100644 torcherino/src/main/resources/assets/torcherino/models/block/wall_torcherino.json create mode 100644 torcherino/src/main/resources/assets/torcherino/models/item/compressed_lanterino.json create mode 100644 torcherino/src/main/resources/assets/torcherino/models/item/compressed_lantern.json create mode 100644 torcherino/src/main/resources/assets/torcherino/models/item/compressed_torcherino.json create mode 100644 torcherino/src/main/resources/assets/torcherino/models/item/double_compressed_lanterino.json create mode 100644 torcherino/src/main/resources/assets/torcherino/models/item/double_compressed_lantern.json create mode 100644 torcherino/src/main/resources/assets/torcherino/models/item/double_compressed_torcherino.json create mode 100644 torcherino/src/main/resources/assets/torcherino/models/item/lanterino.json create mode 100644 torcherino/src/main/resources/assets/torcherino/models/item/lantern.json create mode 100644 torcherino/src/main/resources/assets/torcherino/models/item/torcherino.json create mode 100644 torcherino/src/main/resources/assets/torcherino/particles/compressed_flame.json create mode 100644 torcherino/src/main/resources/assets/torcherino/particles/double_compressed_flame.json create mode 100644 torcherino/src/main/resources/assets/torcherino/particles/flame.json create mode 100644 torcherino/src/main/resources/assets/torcherino/textures/blocks/compressed_lanterino.png create mode 100644 torcherino/src/main/resources/assets/torcherino/textures/blocks/compressed_lanterino_side.png create mode 100644 torcherino/src/main/resources/assets/torcherino/textures/blocks/compressed_lanterino_top.png create mode 100644 torcherino/src/main/resources/assets/torcherino/textures/blocks/compressed_lantern.png create mode 100644 torcherino/src/main/resources/assets/torcherino/textures/blocks/compressed_lantern.png.mcmeta create mode 100644 torcherino/src/main/resources/assets/torcherino/textures/blocks/compressed_torcherino.png create mode 100644 torcherino/src/main/resources/assets/torcherino/textures/blocks/double_compressed_lanterino.png create mode 100644 torcherino/src/main/resources/assets/torcherino/textures/blocks/double_compressed_lanterino_side.png create mode 100644 torcherino/src/main/resources/assets/torcherino/textures/blocks/double_compressed_lanterino_top.png create mode 100644 torcherino/src/main/resources/assets/torcherino/textures/blocks/double_compressed_lantern.png create mode 100644 torcherino/src/main/resources/assets/torcherino/textures/blocks/double_compressed_lantern.png.mcmeta create mode 100644 torcherino/src/main/resources/assets/torcherino/textures/blocks/double_compressed_torcherino.png create mode 100644 torcherino/src/main/resources/assets/torcherino/textures/blocks/lanterino.png create mode 100644 torcherino/src/main/resources/assets/torcherino/textures/blocks/lantern.png create mode 100644 torcherino/src/main/resources/assets/torcherino/textures/blocks/lantern.png.mcmeta create mode 100644 torcherino/src/main/resources/assets/torcherino/textures/blocks/torcherino.png create mode 100644 torcherino/src/main/resources/assets/torcherino/textures/item/compressed_lantern.png create mode 100644 torcherino/src/main/resources/assets/torcherino/textures/item/double_compressed_lantern.png create mode 100644 torcherino/src/main/resources/assets/torcherino/textures/item/lantern.png create mode 100644 torcherino/src/main/resources/assets/torcherino/textures/particle/compressed_flame.png create mode 100644 torcherino/src/main/resources/assets/torcherino/textures/particle/double_compressed_flame.png create mode 100644 torcherino/src/main/resources/assets/torcherino/textures/particle/flame.png create mode 100644 torcherino/src/main/resources/assets/torcherino/textures/screens/torcherino.png create mode 100644 torcherino/src/main/resources/data/torcherino/loot_tables/blocks/compressed_lanterino.json create mode 100644 torcherino/src/main/resources/data/torcherino/loot_tables/blocks/compressed_lantern.json create mode 100644 torcherino/src/main/resources/data/torcherino/loot_tables/blocks/compressed_torcherino.json create mode 100644 torcherino/src/main/resources/data/torcherino/loot_tables/blocks/double_compressed_lanterino.json create mode 100644 torcherino/src/main/resources/data/torcherino/loot_tables/blocks/double_compressed_lantern.json create mode 100644 torcherino/src/main/resources/data/torcherino/loot_tables/blocks/double_compressed_torcherino.json create mode 100644 torcherino/src/main/resources/data/torcherino/loot_tables/blocks/lanterino.json create mode 100644 torcherino/src/main/resources/data/torcherino/loot_tables/blocks/lantern.json create mode 100644 torcherino/src/main/resources/data/torcherino/loot_tables/blocks/torcherino.json create mode 100644 torcherino/src/main/resources/data/torcherino/recipes/compressed_lanterino.json create mode 100644 torcherino/src/main/resources/data/torcherino/recipes/compressed_lantern.json create mode 100644 torcherino/src/main/resources/data/torcherino/recipes/compressed_torcherino.json create mode 100644 torcherino/src/main/resources/data/torcherino/recipes/compressed_torcherino_to_single.json create mode 100644 torcherino/src/main/resources/data/torcherino/recipes/double_compressed_lanterino.json create mode 100644 torcherino/src/main/resources/data/torcherino/recipes/double_compressed_lantern.json create mode 100644 torcherino/src/main/resources/data/torcherino/recipes/double_compressed_torcherino.json create mode 100644 torcherino/src/main/resources/data/torcherino/recipes/double_compressed_torcherino_to_compressed.json create mode 100644 torcherino/src/main/resources/data/torcherino/recipes/lanterino.json create mode 100644 torcherino/src/main/resources/data/torcherino/recipes/lantern.json create mode 100644 torcherino/src/main/resources/data/torcherino/recipes/torcherino.json create mode 100644 torcherino/src/main/resources/fabric.mod.json create mode 100644 torcherino/src/main/resources/torcherino.mixins.json diff --git a/chainmail/src/main/java/ninjaphenix/chainmail/impl/Main.java b/chainmail/src/main/java/ninjaphenix/chainmail/impl/Main.java index 1b6945d4..e253c534 100644 --- a/chainmail/src/main/java/ninjaphenix/chainmail/impl/Main.java +++ b/chainmail/src/main/java/ninjaphenix/chainmail/impl/Main.java @@ -15,6 +15,8 @@ public void onInitialize() // whilst may require some initial effort will mean there's no pre-release steps. // would also shrink mod size by an insignificant amount. // also would simplify the build process. + // negatives: delay switching between tests and code + // clutters root folder if (DEBUG) { final ClassLoader loader = this.getClass().getClassLoader(); diff --git a/settings.gradle b/settings.gradle index fc7aa891..1cb260e5 100644 --- a/settings.gradle +++ b/settings.gradle @@ -8,4 +8,5 @@ pluginManagement { } } -include 'chainmail' \ No newline at end of file +include 'chainmail' +include 'torcherino' \ No newline at end of file diff --git a/torcherino/build.gradle b/torcherino/build.gradle new file mode 100644 index 00000000..959dfe11 --- /dev/null +++ b/torcherino/build.gradle @@ -0,0 +1,11 @@ +repositories { + maven { url "http://server.bbkr.space:8081/artifactory/libs-release/" } +} + +dependencies { + compile project(path: ":chainmail") + include project(path: ":chainmail") + + modImplementation "io.github.cottonmc:Jankson-Fabric:2.0.0+j1.2.0" + include "io.github.cottonmc:Jankson-Fabric:2.0.0+j1.2.0" +} \ No newline at end of file diff --git a/torcherino/gradle.properties b/torcherino/gradle.properties new file mode 100644 index 00000000..ae8bf557 --- /dev/null +++ b/torcherino/gradle.properties @@ -0,0 +1,2 @@ +mod_id = torcherino +mod_version = 2.11.62 \ No newline at end of file diff --git a/torcherino/src/main/java/torcherino/Torcherino.java b/torcherino/src/main/java/torcherino/Torcherino.java new file mode 100644 index 00000000..ef43e8a8 --- /dev/null +++ b/torcherino/src/main/java/torcherino/Torcherino.java @@ -0,0 +1,89 @@ +package torcherino; + +import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.network.PacketContext; +import net.fabricmc.fabric.api.network.ServerSidePacketRegistry; +import net.fabricmc.fabric.api.particle.v1.FabricParticleTypes; +import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.block.Blocks; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.particle.DefaultParticleType; +import net.minecraft.util.Identifier; +import net.minecraft.util.PacketByteBuf; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.registry.Registry; +import net.minecraft.world.World; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import torcherino.api.TorcherinoAPI; +import torcherino.api.blocks.entity.TorcherinoBlockEntity; +import torcherino.api.entrypoints.TorcherinoInitializer; +import torcherino.blocks.ModBlocks; +import torcherino.config.Config; + +import java.util.ArrayList; +import java.util.HashSet; + +@SuppressWarnings("SpellCheckingInspection") +public class Torcherino implements ModInitializer, TorcherinoInitializer +{ + public static final String MOD_ID = "torcherino"; + public static final Logger LOGGER = LogManager.getLogger(MOD_ID); + private static final HashSet allowedUuids = new HashSet<>(); + public static ArrayList particles = new ArrayList<>(); + + public static void playerConnected(String uuid) { allowedUuids.add(uuid); } + + public static boolean hasIsOnline(String uuid) { return allowedUuids.contains(uuid); } + + public static void playerDisconnect(String uuid) { if (Config.INSTANCE.online_mode.equals("ONLINE")) { allowedUuids.remove(uuid); } } + + @Override + public void onInitialize() + { + Config.initialize(); + TorcherinoAPI.INSTANCE.registerTier(new Identifier("null"), 4, 4, 4); + TorcherinoAPI.INSTANCE.getTiers().forEach((id, tier) -> + { + if (!id.getNamespace().equals(MOD_ID)) { return; } + String path = id.getPath() + "_flame"; + if (path.equals("normal_flame")) { path = "flame"; } + particles.add(Registry.register(Registry.PARTICLE_TYPE, new Identifier(MOD_ID, path), FabricParticleTypes.simple())); + }); + ModBlocks.INSTANCE.initialize(); + ServerSidePacketRegistry.INSTANCE.register(new Identifier(Torcherino.MOD_ID, "utv"), (PacketContext context, PacketByteBuf buffer) -> + { + World world = context.getPlayer().getEntityWorld(); + BlockPos pos = buffer.readBlockPos(); + buffer.retain(); + context.getTaskQueue().execute(() -> + { + try + { + BlockEntity blockEntity = world.getBlockEntity(pos); + if (blockEntity instanceof TorcherinoBlockEntity) { ((TorcherinoBlockEntity) blockEntity).readClientData(buffer); } + } + finally + { + buffer.release(); + } + }); + }); + FabricLoader.getInstance().getEntrypoints("torcherinoInitializer", TorcherinoInitializer.class).forEach(TorcherinoInitializer::onTorcherinoInitialize); + } + + @Override + public void onTorcherinoInitialize() + { + TorcherinoAPI.INSTANCE.blacklistBlock(Blocks.WATER); + TorcherinoAPI.INSTANCE.blacklistBlock(Blocks.LAVA); + TorcherinoAPI.INSTANCE.blacklistBlock(Blocks.AIR); + TorcherinoAPI.INSTANCE.blacklistBlock(Blocks.CAVE_AIR); + TorcherinoAPI.INSTANCE.blacklistBlock(Blocks.VOID_AIR); + if (FabricLoader.getInstance().isModLoaded("computercraft")) + { + TorcherinoAPI.INSTANCE.blacklistBlockEntity(new Identifier("computercraft", "turtle_normal")); + TorcherinoAPI.INSTANCE.blacklistBlockEntity(new Identifier("computercraft", "turtle_advanced")); + } + } +} diff --git a/torcherino/src/main/java/torcherino/TorcherinoClient.java b/torcherino/src/main/java/torcherino/TorcherinoClient.java new file mode 100644 index 00000000..70b30dad --- /dev/null +++ b/torcherino/src/main/java/torcherino/TorcherinoClient.java @@ -0,0 +1,79 @@ +package torcherino; + +import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry; +import net.fabricmc.fabric.api.event.client.ClientSpriteRegistryCallback; +import net.fabricmc.fabric.api.network.ClientSidePacketRegistry; +import net.fabricmc.fabric.api.network.PacketContext; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.particle.FlameParticle; +import net.minecraft.client.texture.SpriteAtlasTexture; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; +import net.minecraft.util.PacketByteBuf; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import torcherino.api.Tier; +import torcherino.api.TierSupplier; +import torcherino.api.TorcherinoAPI; +import torcherino.api.blocks.entity.TorcherinoBlockEntity; +import torcherino.api.impl.TorcherinoImpl; +import torcherino.client.screen.TorcherinoScreen; + +import java.util.HashMap; + +import static torcherino.Torcherino.MOD_ID; + +@SuppressWarnings("SpellCheckingInspection") +public class TorcherinoClient implements ClientModInitializer +{ + @Override + public void onInitializeClient() + { + ClientSpriteRegistryCallback.event(SpriteAtlasTexture.PARTICLE_ATLAS_TEX).register(((spriteAtlasTexture, registry) -> + TorcherinoAPI.INSTANCE.getTiers().forEach((id, tier) -> { + if (!id.getNamespace().equals(MOD_ID)) { return; } + String path = id.getPath() + "_flame"; + if (path.equals("normal_flame")) { path = "flame"; } + registry.register(new Identifier("torcherino", "particle/" + path)); + }))); + Torcherino.particles.forEach((pt) -> ParticleFactoryRegistry.getInstance().register(pt, FlameParticle.Factory::new)); + // Open Torcherino Screen + ClientSidePacketRegistry.INSTANCE.register(new Identifier(MOD_ID, "ots"), (PacketContext context, PacketByteBuf buffer) -> + { + World world = MinecraftClient.getInstance().world; + BlockPos pos = buffer.readBlockPos(); + Text title = buffer.readText(); + int xRange = buffer.readInt(); + int zRange = buffer.readInt(); + int yRange = buffer.readInt(); + int speed = buffer.readInt(); + int redstoneMode = buffer.readInt(); + context.getTaskQueue().execute(() -> + { + BlockEntity blockEntity = world.getBlockEntity(pos); + if (blockEntity instanceof TorcherinoBlockEntity) + { + MinecraftClient.getInstance().openScreen(new TorcherinoScreen(title, xRange, zRange, yRange, speed, redstoneMode, pos, + ((TierSupplier) blockEntity).getTier())); + } + }); + }); + // Torcherino Tier Sync + ClientSidePacketRegistry.INSTANCE.register(new Identifier(MOD_ID, "tts"), (PacketContext context, PacketByteBuf buffer) -> + { + HashMap tiers = new HashMap<>(); + int count = buffer.readInt(); + for (int i = 0; i < count; i++) + { + Identifier id = buffer.readIdentifier(); + int maxSpeed = buffer.readInt(); + int xzRange = buffer.readInt(); + int yRange = buffer.readInt(); + tiers.put(id, new Tier(maxSpeed, xzRange, yRange)); + } + context.getTaskQueue().execute(() -> ((TorcherinoImpl) TorcherinoAPI.INSTANCE).setRemoteTiers(tiers)); + }); + } +} diff --git a/torcherino/src/main/java/torcherino/api/Tier.java b/torcherino/src/main/java/torcherino/api/Tier.java new file mode 100644 index 00000000..fff48341 --- /dev/null +++ b/torcherino/src/main/java/torcherino/api/Tier.java @@ -0,0 +1,21 @@ +package torcherino.api; + +public class Tier +{ + private final int MAX_SPEED; + private final int XZ_RANGE; + private final int Y_RANGE; + + public Tier(int maxSpeed, int xzRange, int yRange) + { + this.MAX_SPEED = maxSpeed; + this.XZ_RANGE = xzRange; + this.Y_RANGE = yRange; + } + + public int getMaxSpeed() { return MAX_SPEED; } + + public int getXZRange() { return XZ_RANGE; } + + public int getYRange() { return Y_RANGE; } +} \ No newline at end of file diff --git a/torcherino/src/main/java/torcherino/api/TierSupplier.java b/torcherino/src/main/java/torcherino/api/TierSupplier.java new file mode 100644 index 00000000..4d64e3c9 --- /dev/null +++ b/torcherino/src/main/java/torcherino/api/TierSupplier.java @@ -0,0 +1,8 @@ +package torcherino.api; + +import net.minecraft.util.Identifier; + +public interface TierSupplier +{ + Identifier getTier(); +} diff --git a/torcherino/src/main/java/torcherino/api/TorcherinoAPI.java b/torcherino/src/main/java/torcherino/api/TorcherinoAPI.java new file mode 100644 index 00000000..6f7d08e0 --- /dev/null +++ b/torcherino/src/main/java/torcherino/api/TorcherinoAPI.java @@ -0,0 +1,87 @@ +package torcherino.api; + +import com.google.common.collect.ImmutableMap; +import net.minecraft.block.Block; +import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.util.Identifier; +import torcherino.api.impl.TorcherinoImpl; + +/** + * @author NinjaPhenix + * @since 1.9.51 + */ +@SuppressWarnings({ "UnusedReturnValue", "unused", "SpellCheckingInspection" }) +public interface TorcherinoAPI +{ + /** + * The Implementation of the API, you should use this for all methods. e.g. TorcherinoAPI.INSTANCE.blacklistBlock(Blocks.STONE) + */ + TorcherinoAPI INSTANCE = TorcherinoImpl.INSTANCE; + + /** + * @return Immutable map of tierID -> tier + * @since 1.9.51 + */ + ImmutableMap getTiers(); + + /** + * Returns the tier for the given tierName. + * + * @param tierIdentifier The tier name to retrieve. + * @return The tier or null if it does not exist. + * @since 1.9.51 + */ + Tier getTier(Identifier tierIdentifier); + + /** + * @param tierIdentifier Identifier for the new tier. + * @param maxSpeed The max speed blocks of this tier should have. + * @param xzRange The max range horizontally blocks of this tier should have. + * @param yRange The max range vertically blocks of this tier should have. + * @return TRUE if the tier was registered, FALSE if tier with same name exists. + * @since 1.9.51 + */ + boolean registerTier(Identifier tierIdentifier, int maxSpeed, int xzRange, int yRange); + + /** + * @param blockIdentifier The Identifier of the block to be blacklisted. + * @return TRUE if added to blacklist, FALSE if already on blacklist. + * @since 1.9.51 + */ + boolean blacklistBlock(Identifier blockIdentifier); + + /** + * @param block The block to be blacklisted. + * @return TRUE if added to blacklist, FALSE if already on blacklist. + * @since 1.9.51 + */ + boolean blacklistBlock(Block block); + + /** + * @param blockEntityIdentifier The Identifier of the block entity to be blacklisted. + * @return TRUE if added to blacklist, FALSE if already on blacklist. + * @since 1.9.51 + */ + boolean blacklistBlockEntity(Identifier blockEntityIdentifier); + + /** + * @param blockEntityType The block entity type to be blacklisted. + * @return TRUE if added to blacklist, FALSE if already on blacklist. + * @since 1.9.51 + */ + boolean blacklistBlockEntity(BlockEntityType blockEntityType); + + /** + * @param block The block to check is blacklisted. + * @return TRUE if blacklisted, FALSE otherwise. + * @since 1.9.51 + */ + boolean isBlockBlacklisted(Block block); + + /** + * @param blockEntityType The block entity type to check is blacklisted. + * @return TRUE if blacklisted, FALSE otherwise. + * @since 1.9.51 + */ + boolean isBlockEntityBlacklisted(BlockEntityType blockEntityType); +} diff --git a/torcherino/src/main/java/torcherino/api/TorcherinoLogic.java b/torcherino/src/main/java/torcherino/api/TorcherinoLogic.java new file mode 100644 index 00000000..0620f9b0 --- /dev/null +++ b/torcherino/src/main/java/torcherino/api/TorcherinoLogic.java @@ -0,0 +1,74 @@ +package torcherino.api; + +import io.netty.buffer.Unpooled; +import net.fabricmc.fabric.api.network.ServerSidePacketRegistry; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.util.Identifier; +import net.minecraft.util.PacketByteBuf; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.registry.Registry; +import net.minecraft.world.World; +import torcherino.Torcherino; +import torcherino.api.blocks.entity.TorcherinoBlockEntity; +import torcherino.config.Config; + +import java.util.Random; +import java.util.function.Consumer; + +public class TorcherinoLogic +{ + + public static void scheduledTick(BlockState state, ServerWorld world, BlockPos pos, Random random) + { + if (world.isClient) { return; } + BlockEntity blockEntity = world.getBlockEntity(pos); + if (blockEntity instanceof TorcherinoBlockEntity) { ((TorcherinoBlockEntity) blockEntity).tick(); } + } + + public static ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) + { + if (world.isClient || hand == Hand.OFF_HAND) { return ActionResult.SUCCESS; } + BlockEntity blockEntity = world.getBlockEntity(pos); + if (blockEntity instanceof TorcherinoBlockEntity) + { + PacketByteBuf buffer = new PacketByteBuf(Unpooled.buffer()); + ((TorcherinoBlockEntity) blockEntity).writeClientData(buffer); + ServerSidePacketRegistry.INSTANCE.sendToPlayer(player, new Identifier(Torcherino.MOD_ID, "ots"), buffer); + } + return ActionResult.SUCCESS; + } + + public static void neighborUpdate(BlockState state, World world, BlockPos pos, Block neighborBlock, BlockPos neighborPos, boolean boolean_1, + Consumer func) + { + if (world.isClient) { return; } + BlockEntity blockEntity = world.getBlockEntity(pos); + if (blockEntity instanceof TorcherinoBlockEntity) { func.accept((TorcherinoBlockEntity) blockEntity); } + } + + public static void onPlaced(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack, Block block) + { + if (world.isClient) { return; } + BlockEntity blockEntity = world.getBlockEntity(pos); + if (blockEntity instanceof TorcherinoBlockEntity) + { + TorcherinoBlockEntity be = (TorcherinoBlockEntity) blockEntity; + if (stack.hasCustomName()) { be.setCustomName(stack.getName()); } + if (!Config.INSTANCE.online_mode.equals("")) { be.setOwner(placer == null ? "" : placer.getUuidAsString()); } + } + if (Config.INSTANCE.log_placement) + { + String prefix = placer == null ? "Something" : placer.getDisplayName().getString() + "(" + placer.getUuidAsString() + ")"; + Torcherino.LOGGER.info("[Torcherino] {} placed a {} at {}, {}, {}.", prefix, Registry.BLOCK.getId(block), pos.getX(), pos.getY(), pos.getZ()); + } + } +} diff --git a/torcherino/src/main/java/torcherino/api/blocks/JackoLanterinoBlock.java b/torcherino/src/main/java/torcherino/api/blocks/JackoLanterinoBlock.java new file mode 100644 index 00000000..c2b923c4 --- /dev/null +++ b/torcherino/src/main/java/torcherino/api/blocks/JackoLanterinoBlock.java @@ -0,0 +1,74 @@ +package torcherino.api.blocks; + +import net.fabricmc.fabric.api.block.FabricBlockSettings; +import net.minecraft.block.*; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.piston.PistonBehavior; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.util.Identifier; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.BlockView; +import net.minecraft.world.World; +import torcherino.api.TierSupplier; +import torcherino.api.TorcherinoLogic; +import torcherino.api.blocks.entity.TorcherinoBlockEntity; + +import java.util.Random; + +@SuppressWarnings({ "SpellCheckingInspection", "deprecation" }) +public class JackoLanterinoBlock extends CarvedPumpkinBlock implements BlockEntityProvider, TierSupplier +{ + private final Identifier tierID; + + public JackoLanterinoBlock(Identifier tier) + { + super(FabricBlockSettings.copy(Blocks.JACK_O_LANTERN).build()); + this.tierID = tier; + } + + @Override + public Identifier getTier() { return tierID; } + + @Override + public BlockEntity createBlockEntity(BlockView view) { return new TorcherinoBlockEntity(); } + + @Override + public PistonBehavior getPistonBehavior(BlockState state) { return PistonBehavior.IGNORE; } + + @Override + public void onBlockAdded(BlockState newState, World world, BlockPos pos, BlockState state, boolean boolean_1) + { + neighborUpdate(null, world, pos, null, null, false); + } + + @Override + public void scheduledTick(BlockState state, ServerWorld world, BlockPos pos, Random random) + { + TorcherinoLogic.scheduledTick(state, world, pos, random); + } + + @Override + public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) + { + return TorcherinoLogic.onUse(state, world, pos, player, hand, hit); + } + + @Override + public void neighborUpdate(BlockState state, World world, BlockPos pos, Block neighborBlock, BlockPos neighborPos, boolean boolean_1) + { + TorcherinoLogic.neighborUpdate(state, world, pos, neighborBlock, neighborPos, boolean_1, (be) -> + be.setPoweredByRedstone(world.isReceivingRedstonePower(pos))); + } + + @Override + public void onPlaced(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) + { + TorcherinoLogic.onPlaced(world, pos, state, placer, stack, this); + } +} diff --git a/torcherino/src/main/java/torcherino/api/blocks/LanterinoBlock.java b/torcherino/src/main/java/torcherino/api/blocks/LanterinoBlock.java new file mode 100644 index 00000000..5bca560d --- /dev/null +++ b/torcherino/src/main/java/torcherino/api/blocks/LanterinoBlock.java @@ -0,0 +1,96 @@ +package torcherino.api.blocks; + +import net.fabricmc.fabric.api.block.FabricBlockSettings; +import net.minecraft.block.*; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.piston.PistonBehavior; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.state.property.Properties; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.util.Identifier; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.world.BlockView; +import net.minecraft.world.World; +import torcherino.api.TierSupplier; +import torcherino.api.TorcherinoLogic; +import torcherino.api.blocks.entity.TorcherinoBlockEntity; + +import java.util.Random; + +public class LanterinoBlock extends LanternBlock implements BlockEntityProvider, TierSupplier +{ + private final Identifier tierID; + + public LanterinoBlock(Identifier tier) + { + super(FabricBlockSettings.copy(Blocks.LANTERN).build()); + this.tierID = tier; + } + + private static boolean isEmittingStrongRedstonePower(World world, BlockPos pos, Direction direction) + { + BlockState state = world.getBlockState(pos); + return state.getStrongRedstonePower(world, pos, direction) > 0; + } + + @Override + public Identifier getTier() { return tierID; } + + @Override + public BlockEntity createBlockEntity(BlockView view) { return new TorcherinoBlockEntity(); } + + @Override + public PistonBehavior getPistonBehavior(BlockState state) { return PistonBehavior.IGNORE; } + + @Override + public void onBlockAdded(BlockState newState, World world, BlockPos pos, BlockState state, boolean boolean_1) + { + neighborUpdate(null, world, pos, null, null, false); + } + + @Override + public void scheduledTick(BlockState state, ServerWorld world, BlockPos pos, Random random) + { + TorcherinoLogic.scheduledTick(state, world, pos, random); + } + + @Override + public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) + { + return TorcherinoLogic.onUse(state, world, pos, player, hand, hit); + } + + @Override + public void neighborUpdate(BlockState state, World world, BlockPos pos, Block neighborBlock, BlockPos neighborPos, boolean boolean_1) + { + TorcherinoLogic.neighborUpdate(state, world, pos, neighborBlock, neighborPos, boolean_1, (be) -> + { + if (state == null) { return; } + if (state.get(Properties.HANGING).equals(true)) + { + be.setPoweredByRedstone(world.isEmittingRedstonePower(pos.up(), Direction.UP)); + } + else + { + boolean powered = isEmittingStrongRedstonePower(world, pos.west(), Direction.WEST) || + isEmittingStrongRedstonePower(world, pos.east(), Direction.EAST) || + isEmittingStrongRedstonePower(world, pos.south(), Direction.SOUTH) || + isEmittingStrongRedstonePower(world, pos.north(), Direction.NORTH); + be.setPoweredByRedstone(powered); + } + }); + + } + + @Override + public void onPlaced(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) + { + TorcherinoLogic.onPlaced(world, pos, state, placer, stack, this); + } +} diff --git a/torcherino/src/main/java/torcherino/api/blocks/TorcherinoBlock.java b/torcherino/src/main/java/torcherino/api/blocks/TorcherinoBlock.java new file mode 100644 index 00000000..c4b65b4d --- /dev/null +++ b/torcherino/src/main/java/torcherino/api/blocks/TorcherinoBlock.java @@ -0,0 +1,92 @@ +package torcherino.api.blocks; + +import net.fabricmc.fabric.api.block.FabricBlockSettings; +import net.minecraft.block.*; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.piston.PistonBehavior; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.particle.DefaultParticleType; +import net.minecraft.particle.ParticleTypes; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.util.Identifier; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.registry.Registry; +import net.minecraft.world.BlockView; +import net.minecraft.world.World; +import torcherino.api.TierSupplier; +import torcherino.api.TorcherinoLogic; +import torcherino.api.blocks.entity.TorcherinoBlockEntity; + +import java.util.Random; + +@SuppressWarnings({ "SpellCheckingInspection", "deprecation" }) +public class TorcherinoBlock extends TorchBlock implements BlockEntityProvider, TierSupplier +{ + private final Identifier tierID; + private DefaultParticleType flameParticle; + + public TorcherinoBlock(Identifier tier) + { + super(FabricBlockSettings.copy(Blocks.TORCH).build()); + tierID = tier; + String path = tier.getPath() + "_flame"; + if (path.equals("normal_flame")) { path = "flame"; } + flameParticle = (DefaultParticleType) Registry.PARTICLE_TYPE.get(new Identifier(tier.getNamespace(), path)); + } + + @Override + public Identifier getTier() { return tierID; } + + @Override + public BlockEntity createBlockEntity(BlockView view) { return new TorcherinoBlockEntity(); } + + @Override + public PistonBehavior getPistonBehavior(BlockState state) { return PistonBehavior.IGNORE; } + + @Override + public void onBlockAdded(BlockState newState, World world, BlockPos pos, BlockState state, boolean boolean_1) + { + neighborUpdate(null, world, pos, null, null, false); + } + + @Override + public void scheduledTick(BlockState state, ServerWorld world, BlockPos pos, Random random) + { + TorcherinoLogic.scheduledTick(state, world, pos, random); + } + + @Override + public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) + { + return TorcherinoLogic.onUse(state, world, pos, player, hand, hit); + } + + @Override + public void neighborUpdate(BlockState state, World world, BlockPos pos, Block neighborBlock, BlockPos neighborPos, boolean boolean_1) + { + TorcherinoLogic.neighborUpdate(state, world, pos, neighborBlock, neighborPos, boolean_1, (be) -> + be.setPoweredByRedstone(world.isEmittingRedstonePower(pos.down(), Direction.UP))); + } + + @Override + public void onPlaced(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) + { + TorcherinoLogic.onPlaced(world, pos, state, placer, stack, this); + } + + @Override + public void randomDisplayTick(BlockState state, World world, BlockPos pos, Random rnd) + { + double d = pos.getX() + 0.5D; + double e = pos.getY() + 0.7D; + double f = pos.getZ() + 0.5D; + world.addParticle(ParticleTypes.SMOKE, d, e, f, 0.0D, 0.0D, 0.0D); + world.addParticle(flameParticle, d, e, f, 0.0D, 0.0D, 0.0D); + } +} diff --git a/torcherino/src/main/java/torcherino/api/blocks/WallTorcherinoBlock.java b/torcherino/src/main/java/torcherino/api/blocks/WallTorcherinoBlock.java new file mode 100644 index 00000000..4ea4b3ed --- /dev/null +++ b/torcherino/src/main/java/torcherino/api/blocks/WallTorcherinoBlock.java @@ -0,0 +1,95 @@ +package torcherino.api.blocks; + +import net.fabricmc.fabric.api.block.FabricBlockSettings; +import net.minecraft.block.*; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.piston.PistonBehavior; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.particle.DefaultParticleType; +import net.minecraft.particle.ParticleTypes; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.state.property.Properties; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.util.Identifier; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.registry.Registry; +import net.minecraft.world.BlockView; +import net.minecraft.world.World; +import torcherino.api.TierSupplier; +import torcherino.api.TorcherinoLogic; +import torcherino.api.blocks.entity.TorcherinoBlockEntity; + +import java.util.Random; + +@SuppressWarnings({ "SpellCheckingInspection", "deprecation" }) +public class WallTorcherinoBlock extends WallTorchBlock implements BlockEntityProvider, TierSupplier +{ + private final Identifier tierID; + private final DefaultParticleType flameParticle; + + public WallTorcherinoBlock(Identifier tier, Identifier dropID) + { + super(FabricBlockSettings.copy(Blocks.WALL_TORCH).drops(dropID).build()); + this.tierID = tier; + String path = tier.getPath() + "_flame"; + if (path.equals("normal_flame")) { path = "flame"; } + flameParticle = (DefaultParticleType) Registry.PARTICLE_TYPE.get(new Identifier(tier.getNamespace(), path)); + } + + @Override + public Identifier getTier() { return tierID; } + + @Override + public BlockEntity createBlockEntity(BlockView view) { return new TorcherinoBlockEntity(); } + + @Override + public PistonBehavior getPistonBehavior(BlockState state) { return PistonBehavior.IGNORE; } + + @Override + public void onBlockAdded(BlockState newState, World world, BlockPos pos, BlockState state, boolean boolean_1) + { + neighborUpdate(newState, world, pos, null, null, false); + } + + @Override + public void scheduledTick(BlockState state, ServerWorld world, BlockPos pos, Random random) + { + TorcherinoLogic.scheduledTick(state, world, pos, random); + } + + @Override + public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) + { + return TorcherinoLogic.onUse(state, world, pos, player, hand, hit); + } + + @Override + public void neighborUpdate(BlockState state, World world, BlockPos pos, Block neighborBlock, BlockPos neighborPos, boolean boolean_1) + { + TorcherinoLogic.neighborUpdate(state, world, pos, neighborBlock, neighborPos, boolean_1, (be) -> be.setPoweredByRedstone( + world.isEmittingRedstonePower(pos.offset(state.get(Properties.HORIZONTAL_FACING).getOpposite()), state.get(Properties.HORIZONTAL_FACING)))); + } + + @Override + public void onPlaced(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) + { + TorcherinoLogic.onPlaced(world, pos, state, placer, stack, this); + } + + @Override + public void randomDisplayTick(BlockState state, World world, BlockPos pos, Random rnd) + { + Direction direction = state.get(FACING); + double d = pos.getX() + 0.5D; + double e = pos.getY() + 0.7D; + double f = pos.getZ() + 0.5D; + Direction direction2 = direction.getOpposite(); + world.addParticle(ParticleTypes.SMOKE, d + 0.27D * direction2.getOffsetX(), e + 0.22D, f + 0.27D * direction2.getOffsetZ(), 0.0D, 0.0D, 0.0D); + world.addParticle(flameParticle, d + 0.27D * direction2.getOffsetX(), e + 0.22D, f + 0.27D * direction2.getOffsetZ(), 0.0D, 0.0D, 0.0D); + } +} diff --git a/torcherino/src/main/java/torcherino/api/blocks/entity/TocherinoBlockEntityType.java b/torcherino/src/main/java/torcherino/api/blocks/entity/TocherinoBlockEntityType.java new file mode 100644 index 00000000..c0c1cc9f --- /dev/null +++ b/torcherino/src/main/java/torcherino/api/blocks/entity/TocherinoBlockEntityType.java @@ -0,0 +1,17 @@ +package torcherino.api.blocks.entity; + +import com.mojang.datafixers.types.Type; +import net.minecraft.block.Block; +import net.minecraft.block.entity.BlockEntityType; +import torcherino.api.TierSupplier; + +import java.util.function.Supplier; + +@SuppressWarnings("SpellCheckingInspection") +public class TocherinoBlockEntityType extends BlockEntityType +{ + public TocherinoBlockEntityType(Supplier supplier, Type type) { super(supplier, null, type); } + + @Override + public boolean supports(Block block) { return block instanceof TierSupplier; } +} diff --git a/torcherino/src/main/java/torcherino/api/blocks/entity/TorcherinoBlockEntity.java b/torcherino/src/main/java/torcherino/api/blocks/entity/TorcherinoBlockEntity.java new file mode 100644 index 00000000..f0b17308 --- /dev/null +++ b/torcherino/src/main/java/torcherino/api/blocks/entity/TorcherinoBlockEntity.java @@ -0,0 +1,175 @@ +package torcherino.api.blocks.entity; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.text.Text; +import net.minecraft.text.TranslatableText; +import net.minecraft.util.Identifier; +import net.minecraft.util.Nameable; +import net.minecraft.util.PacketByteBuf; +import net.minecraft.util.Tickable; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.registry.Registry; +import net.minecraft.world.GameRules; +import torcherino.Torcherino; +import torcherino.api.Tier; +import torcherino.api.TierSupplier; +import torcherino.api.TorcherinoAPI; +import torcherino.config.Config; + +@SuppressWarnings("SpellCheckingInspection") +public class TorcherinoBlockEntity extends BlockEntity implements Nameable, Tickable, TierSupplier +{ + private static final String onlineMode = Config.INSTANCE.online_mode; + public static int randomTicks; + private Text customName; + private int xRange, yRange, zRange, speed, redstoneMode; + private Iterable area; + private boolean active; + private boolean loaded = false; + private Identifier tierID; + private String uuid = ""; + + public TorcherinoBlockEntity() { super(Registry.BLOCK_ENTITY_TYPE.get(new Identifier("torcherino", "torcherino"))); } + + @Override + public boolean hasCustomName() { return customName != null; } + + @Override + public Text getCustomName() { return customName; } + + public void setCustomName(Text name) { customName = name; } + + private String getOwner() { return uuid; } + + public void setOwner(String s) { uuid = s; } + + @Override + public Text getName() { return hasCustomName() ? customName : new TranslatableText(getCachedState().getBlock().getTranslationKey()); } + + @Override + public void tick() + { + if (!loaded) + { + area = BlockPos.iterate(pos.getX() - xRange, pos.getY() - yRange, pos.getZ() - zRange, + pos.getX() + xRange, pos.getY() + yRange, pos.getZ() + zRange); + getCachedState().getBlock().neighborUpdate(getCachedState(), world, pos, null, null, false); + randomTicks = world.getGameRules().getInt(GameRules.RANDOM_TICK_SPEED); // update via mixin + loaded = true; + } + if (!active || speed == 0 || (xRange == 0 && yRange == 0 && zRange == 0)) { return; } + if (!onlineMode.equals("")) + { + if (!Torcherino.hasIsOnline(getOwner())) { return; } + + } + area.forEach(this::tickBlock); + } + + private void tickBlock(BlockPos pos) + { + BlockState blockState = world.getBlockState(pos); + Block block = blockState.getBlock(); + if (TorcherinoAPI.INSTANCE.isBlockBlacklisted(block)) { return; } + if (world instanceof ServerWorld && block.hasRandomTicks(blockState) && + world.getRandom().nextInt(MathHelper.clamp(4096 / (speed * Config.INSTANCE.random_tick_rate), 1, 4096)) < randomTicks) + { + block.randomTick(blockState, (ServerWorld) world, pos, world.getRandom()); + } + if (!block.hasBlockEntity()) { return; } + BlockEntity blockEntity = world.getBlockEntity(pos); + if (blockEntity == null || blockEntity.isRemoved() || TorcherinoAPI.INSTANCE.isBlockEntityBlacklisted(blockEntity.getType()) || + !(blockEntity instanceof Tickable)) { return; } + for (int i = 0; i < speed; i++) + { + if (blockEntity.isRemoved()) { break; } + ((Tickable) blockEntity).tick(); + } + } + + public void writeClientData(PacketByteBuf buffer) + { + buffer.writeBlockPos(pos); + buffer.writeText(getName()); + buffer.writeInt(xRange); + buffer.writeInt(zRange); + buffer.writeInt(yRange); + buffer.writeInt(speed); + buffer.writeInt(redstoneMode); + } + + public void readClientData(PacketByteBuf buffer) + { + Tier tier = TorcherinoAPI.INSTANCE.getTiers().get(getTier()); + this.xRange = MathHelper.clamp(buffer.readInt(), 0, tier.getXZRange()); + this.zRange = MathHelper.clamp(buffer.readInt(), 0, tier.getXZRange()); + this.yRange = MathHelper.clamp(buffer.readInt(), 0, tier.getYRange()); + this.speed = MathHelper.clamp(buffer.readInt(), 1, tier.getMaxSpeed()); + this.redstoneMode = MathHelper.clamp(buffer.readInt(), 0, 3); + loaded = false; + } + + @Override + public Identifier getTier() + { + if (tierID == null) + { + Block block = getCachedState().getBlock(); + if (block instanceof TierSupplier) { tierID = ((TierSupplier) block).getTier(); } + } + return tierID; + } + + public void setPoweredByRedstone(boolean powered) + { + switch (redstoneMode) + { + case 0: + active = !powered; + break; + case 1: + active = powered; + break; + case 2: + active = true; + break; + case 3: + active = false; + break; + } + } + + @Override + public CompoundTag toTag(CompoundTag tag) + { + super.toTag(tag); + if (hasCustomName()) { tag.putString("CustomName", Text.Serializer.toJson(getCustomName())); } + tag.putInt("XRange", xRange); + tag.putInt("ZRange", zRange); + tag.putInt("YRange", yRange); + tag.putInt("Speed", speed); + tag.putInt("RedstoneMode", redstoneMode); + tag.putBoolean("Active", active); + tag.putString("Owner", getOwner() == null ? "" : getOwner()); + return tag; + } + + @Override + public void fromTag(CompoundTag tag) + { + super.fromTag(tag); + if (tag.contains("CustomName", 8)) { setCustomName(Text.Serializer.fromJson(tag.getString("CustomName"))); } + xRange = tag.getInt("XRange"); + zRange = tag.getInt("ZRange"); + yRange = tag.getInt("YRange"); + speed = tag.getInt("Speed"); + redstoneMode = tag.getInt("RedstoneMode"); + active = tag.getBoolean("Active"); + uuid = tag.getString("Owner"); + } +} diff --git a/torcherino/src/main/java/torcherino/api/entrypoints/TorcherinoInitializer.java b/torcherino/src/main/java/torcherino/api/entrypoints/TorcherinoInitializer.java new file mode 100644 index 00000000..d3d2343f --- /dev/null +++ b/torcherino/src/main/java/torcherino/api/entrypoints/TorcherinoInitializer.java @@ -0,0 +1,14 @@ +package torcherino.api.entrypoints; + +@SuppressWarnings("SpellCheckingInspection") +@FunctionalInterface +public interface TorcherinoInitializer +{ + /** + * Here you should only blacklist blocks or block entities, this can be done in your ModInitializer, however using this in a separate class will not need + * Torcherino API to be bundled at all. Please don't access the TorcherinoImpl class directly, use the TorcherinoAPI.INSTANCE field. + * + * @since 1.9.51 + */ + void onTorcherinoInitialize(); +} diff --git a/torcherino/src/main/java/torcherino/api/impl/TorcherinoImpl.java b/torcherino/src/main/java/torcherino/api/impl/TorcherinoImpl.java new file mode 100644 index 00000000..b5e2403e --- /dev/null +++ b/torcherino/src/main/java/torcherino/api/impl/TorcherinoImpl.java @@ -0,0 +1,128 @@ +package torcherino.api.impl; + +import com.google.common.collect.ImmutableMap; +import net.minecraft.block.Block; +import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.util.Identifier; +import net.minecraft.util.registry.Registry; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import torcherino.api.Tier; +import torcherino.api.TorcherinoAPI; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * DO NOT USE THIS CLASS DIRECTLY. Use TorcherinoAPI.INSTANCE instead. + */ +@SuppressWarnings("SpellCheckingInspection") +public class TorcherinoImpl implements TorcherinoAPI +{ + @Deprecated + public static final TorcherinoImpl INSTANCE = new TorcherinoImpl(); + + private final Logger LOGGER = LogManager.getLogger("torcherino-api"); + private final HashMap localTiers; + private final HashSet blacklistedBlocks; + private final HashSet blacklistedBlockEntities; + private HashMap remoteTiers; + + private TorcherinoImpl() + { + localTiers = new HashMap<>(); + blacklistedBlocks = new HashSet<>(); + blacklistedBlockEntities = new HashSet<>(); + } + + @Override + public ImmutableMap getTiers() { return ImmutableMap.copyOf(localTiers); } + + @Override + public Tier getTier(Identifier tierIdentifier) { return remoteTiers.getOrDefault(tierIdentifier, null); } + + @Override + public boolean registerTier(Identifier tierIdentifier, int maxSpeed, int xzRange, int yRange) + { + Tier tier = new Tier(maxSpeed, xzRange, yRange); + if (localTiers.containsKey(tierIdentifier)) + { + LOGGER.error("[Torcherino] Tier with id {} has already been declared.", tierIdentifier); + return false; + } + localTiers.put(tierIdentifier, tier); + return true; + } + + @Override + public boolean blacklistBlock(Identifier blockIdentifier) + { + if (blacklistedBlocks.contains(blockIdentifier)) + { + LOGGER.warn("[Torcherino] Block with id {} has already been blacklisted.", blockIdentifier); + return false; + } + blacklistedBlocks.add(blockIdentifier); + return true; + } + + @Override + public boolean blacklistBlock(Block block) + { + Identifier blockIdentifier = Registry.BLOCK.getId(block); + if (Registry.BLOCK.get(blockIdentifier) != block) + { + LOGGER.error("[Torcherino] Please register your block before attempting to blacklist."); + return false; + } + else if (blacklistedBlocks.contains(blockIdentifier)) + { + LOGGER.warn("[Torcherino] Block with id {} has already been blacklisted.", blockIdentifier); + return false; + } + blacklistedBlocks.add(blockIdentifier); + return true; + } + + @Override + public boolean blacklistBlockEntity(Identifier blockEntityIdentifier) + { + if (blacklistedBlockEntities.contains(blockEntityIdentifier)) + { + LOGGER.warn("[Torcherino] Block entity with id {} has already been blacklisted.", blockEntityIdentifier); + return false; + } + blacklistedBlockEntities.add(blockEntityIdentifier); + return true; + } + + @Override + public boolean blacklistBlockEntity(BlockEntityType blockEntityType) + { + Identifier blockEntityTypeIdentifier = Registry.BLOCK_ENTITY_TYPE.getId(blockEntityType); + if (blockEntityTypeIdentifier == null) + { + LOGGER.error("[Torcherino] Please register your block entity type before attempting to blacklist."); + return false; + } + else if (blacklistedBlockEntities.contains(blockEntityTypeIdentifier)) + { + LOGGER.warn("[Torcherino] Block entity with id {} has already been blacklisted.", blockEntityTypeIdentifier); + return false; + } + blacklistedBlockEntities.add(blockEntityTypeIdentifier); + return true; + } + + @Override + public boolean isBlockBlacklisted(Block block) { return blacklistedBlocks.contains(Registry.BLOCK.getId(block)); } + + @Override + public boolean isBlockEntityBlacklisted(BlockEntityType blockEntityType) + { + return blacklistedBlockEntities.contains(BlockEntityType.getId(blockEntityType)); + } + + // Internal do not use. + public void setRemoteTiers(HashMap tiers) { remoteTiers = tiers; } +} diff --git a/torcherino/src/main/java/torcherino/blocks/ModBlocks.java b/torcherino/src/main/java/torcherino/blocks/ModBlocks.java new file mode 100644 index 00000000..1918ec14 --- /dev/null +++ b/torcherino/src/main/java/torcherino/blocks/ModBlocks.java @@ -0,0 +1,99 @@ +package torcherino.blocks; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap; +import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.block.Block; +import net.minecraft.client.render.RenderLayer; +import net.minecraft.item.BlockItem; +import net.minecraft.item.Item; +import net.minecraft.item.ItemGroup; +import net.minecraft.item.WallStandingBlockItem; +import net.minecraft.util.Identifier; +import net.minecraft.util.registry.Registry; +import torcherino.Torcherino; +import torcherino.api.Tier; +import torcherino.api.TorcherinoAPI; +import torcherino.api.blocks.JackoLanterinoBlock; +import torcherino.api.blocks.LanterinoBlock; +import torcherino.api.blocks.TorcherinoBlock; +import torcherino.api.blocks.WallTorcherinoBlock; +import torcherino.api.blocks.entity.TocherinoBlockEntityType; +import torcherino.api.blocks.entity.TorcherinoBlockEntity; + +import java.util.HashMap; + +@SuppressWarnings("SpellCheckingInspection") +public class ModBlocks +{ + public static final ModBlocks INSTANCE = new ModBlocks(); + private HashMap blocks; + private HashMap items; + + public void initialize() + { + blocks = new HashMap<>(); + items = new HashMap<>(); + TorcherinoAPI.INSTANCE.getTiers().forEach(this::createBlocks); + registerBlocks(); + registerItems(); + registerBlockEntity(); + } + + private void createBlocks(Identifier tierID, Tier tier) + { + if (tierID.getNamespace().equals(Torcherino.MOD_ID)) + { + Identifier torcherinoID = getIdentifier(tierID, "torcherino"); + Identifier jackoLanterinoID = getIdentifier(tierID, "lanterino"); + Identifier lanterinoID = getIdentifier(tierID, "lantern"); + Block torcherinoBlock = new TorcherinoBlock(tierID); + Block torcherinoWallBlock = new WallTorcherinoBlock(tierID, new Identifier(Torcherino.MOD_ID, "blocks/" + torcherinoID.getPath())); + Block jackoLanterinoBlock = new JackoLanterinoBlock(tierID); + Block lanterinoBlock = new LanterinoBlock(tierID); + blocks.put(torcherinoID, torcherinoBlock); + if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) + { + SetRenderLayer(torcherinoBlock); + SetRenderLayer(torcherinoWallBlock); + SetRenderLayer(lanterinoBlock); + } + blocks.put(new Identifier(Torcherino.MOD_ID, "wall_" + torcherinoID.getPath()), torcherinoWallBlock); + blocks.put(jackoLanterinoID, jackoLanterinoBlock); + blocks.put(lanterinoID, lanterinoBlock); + Item torcherinoItem = new WallStandingBlockItem(torcherinoBlock, torcherinoWallBlock, new Item.Settings().group(ItemGroup.DECORATIONS)); + Item jackoLanterinoItem = new BlockItem(jackoLanterinoBlock, new Item.Settings().group(ItemGroup.BUILDING_BLOCKS)); + Item lanterinoItem = new BlockItem(lanterinoBlock, new Item.Settings().group(ItemGroup.BUILDING_BLOCKS)); + items.put(torcherinoID, torcherinoItem); + items.put(jackoLanterinoID, jackoLanterinoItem); + items.put(lanterinoID, lanterinoItem); + } + } + + @Environment(EnvType.CLIENT) + private void SetRenderLayer(Block block) { BlockRenderLayerMap.INSTANCE.putBlock(block, RenderLayer.getCutout()); } + + private void registerBlocks() + { + blocks.forEach((id, block) -> + { + Registry.register(Registry.BLOCK, id, block); + TorcherinoAPI.INSTANCE.blacklistBlock(id); + }); + } + + private void registerItems() { items.forEach((id, item) -> Registry.register(Registry.ITEM, id, item)); } + + private void registerBlockEntity() + { + Registry.register(Registry.BLOCK_ENTITY_TYPE, new Identifier(Torcherino.MOD_ID, "torcherino"), + new TocherinoBlockEntityType(TorcherinoBlockEntity::new, null)); + } + + private Identifier getIdentifier(Identifier tierID, String type) + { + if (tierID.getPath().equals("normal")) { return new Identifier(Torcherino.MOD_ID, type); } + return new Identifier(Torcherino.MOD_ID, tierID.getPath() + '_' + type); + } +} diff --git a/torcherino/src/main/java/torcherino/client/screen/TorcherinoScreen.java b/torcherino/src/main/java/torcherino/client/screen/TorcherinoScreen.java new file mode 100644 index 00000000..7f173554 --- /dev/null +++ b/torcherino/src/main/java/torcherino/client/screen/TorcherinoScreen.java @@ -0,0 +1,208 @@ +package torcherino.client.screen; + +import com.mojang.blaze3d.systems.RenderSystem; +import io.netty.buffer.Unpooled; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.network.ClientSidePacketRegistry; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.text.Text; +import net.minecraft.text.TranslatableText; +import net.minecraft.util.Identifier; +import net.minecraft.util.PacketByteBuf; +import net.minecraft.util.math.BlockPos; +import torcherino.Torcherino; +import torcherino.api.Tier; +import torcherino.api.TorcherinoAPI; +import torcherino.client.screen.widgets.FixedSliderWidget; +import torcherino.client.screen.widgets.StateButtonWidget; + +@Environment(EnvType.CLIENT) +@SuppressWarnings("SpellCheckingInspection") +public class TorcherinoScreen extends Screen +{ + private static final Identifier SCREEN_TEXTURE = new Identifier(Torcherino.MOD_ID, "textures/screens/torcherino.png"); + private static final int screenWidth = 245; + private static final int screenHeight = 123; + + private final BlockPos blockPos; + private final Tier tier; + private final String cached_title; + private int xRange, zRange, yRange, speed, redstoneMode, left, top; + + public TorcherinoScreen(Text title, int xRange, int zRange, int yRange, int speed, int redstoneMode, BlockPos pos, Identifier tierID) + { + super(title); + this.tier = TorcherinoAPI.INSTANCE.getTier(tierID); + this.blockPos = pos; + this.xRange = xRange; + this.zRange = zRange; + this.yRange = yRange; + this.speed = speed == 0 ? 1 : speed; + this.redstoneMode = redstoneMode; + this.cached_title = title.asString(); + } + + @Override + public boolean isPauseScreen() { return false; } + + @Override + protected void init() + { + left = (width - screenWidth) / 2; + top = (height - screenHeight) / 2; + addButton(new FixedSliderWidget(left + 8, top + 20, 205, (double) (speed - 1) / (tier.getMaxSpeed() - 1), tier.getMaxSpeed()) + { + @Override + protected void updateMessage() { setMessage(new TranslatableText("gui.torcherino.speed", 100 * TorcherinoScreen.this.speed).asString()); } + + @Override + protected void applyValue() + { + TorcherinoScreen.this.speed = 1 + (int) Math.round(value * (TorcherinoScreen.this.tier.getMaxSpeed() - 1)); + value = (double) (speed - 1) / (tier.getMaxSpeed() - 1); + } + }); + addButton(new FixedSliderWidget(left + 8, top + 45, 205, (double) xRange / tier.getXZRange(), tier.getXZRange()) + { + @Override + protected void updateMessage() { setMessage(new TranslatableText("gui.torcherino.x_range", TorcherinoScreen.this.xRange * 2 + 1).asString()); } + + @Override + protected void applyValue() + { + TorcherinoScreen.this.xRange = (int) Math.round(value * TorcherinoScreen.this.tier.getXZRange()); + value = (double) xRange / tier.getXZRange(); + } + }); + this.addButton(new FixedSliderWidget(left + 8, top + 70, 205, (double) zRange / tier.getXZRange(), tier.getXZRange()) + { + @Override + protected void updateMessage() { setMessage(new TranslatableText("gui.torcherino.z_range", TorcherinoScreen.this.zRange * 2 + 1).asString()); } + + @Override + protected void applyValue() + { + TorcherinoScreen.this.zRange = (int) Math.round(value * TorcherinoScreen.this.tier.getXZRange()); + value = (double) zRange / tier.getXZRange(); + } + }); + this.addButton(new FixedSliderWidget(left + 8, top + 95, 205, (double) yRange / tier.getYRange(), tier.getYRange()) + { + @Override + protected void updateMessage() { setMessage(new TranslatableText("gui.torcherino.y_range", TorcherinoScreen.this.yRange * 2 + 1).asString()); } + + @Override + protected void applyValue() + { + TorcherinoScreen.this.yRange = (int) Math.round(value * TorcherinoScreen.this.tier.getYRange()); + value = (double) yRange / tier.getYRange(); + } + }); + this.addButton(new StateButtonWidget(this, left + 217, top + 20) + { + ItemStack buttonIcon; + + @Override + protected void initialize() + { + setButtonMessage(); + setButtonIcon(); + } + + private void setButtonMessage() + { + String translationKey; + switch (TorcherinoScreen.this.redstoneMode) + { + case 0: + translationKey = "gui.torcherino.mode.normal"; + break; + case 1: + translationKey = "gui.torcherino.mode.inverted"; + break; + case 2: + translationKey = "gui.torcherino.mode.ignore"; + break; + case 3: + translationKey = "gui.torcherino.mode.off"; + break; + default: + translationKey = "gui.torcherino.mode.error"; + break; + } + setNarrationMessage(new TranslatableText("gui.torcherino.mode", new TranslatableText(translationKey)).asString()); + } + + private void setButtonIcon() + { + switch (TorcherinoScreen.this.redstoneMode) + { + case 0: + this.buttonIcon = new ItemStack(Items.REDSTONE); + break; + case 1: + this.buttonIcon = new ItemStack(Items.REDSTONE_TORCH); + break; + case 2: + this.buttonIcon = new ItemStack(Items.GUNPOWDER); + break; + case 3: + this.buttonIcon = new ItemStack(Items.REDSTONE_LAMP); + break; + default: + this.buttonIcon = new ItemStack(Items.FURNACE); + break; + } + } + + @Override + protected void nextState() + { + TorcherinoScreen.this.redstoneMode = (TorcherinoScreen.this.redstoneMode + 1) % 4; + initialize(); + } + + @Override + protected ItemStack getButtonIcon() { return buttonIcon; } + }); + } + + @Override + public void render(int x, int y, float partialTicks) + { + fillGradient(0, 0, this.width, this.height, -1072689136, -804253680); + minecraft.getTextureManager().bindTexture(SCREEN_TEXTURE); + RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F); + blit(left, top, 0, 0, screenWidth, screenHeight); + font.draw(cached_title, (width - font.getStringWidth(cached_title)) / 2.0f, top + 6, 4210752); + super.render(x, y, partialTicks); + } + + @Override + public boolean keyPressed(int keyCode, int scanCode, int modifiers) + { + if (keyCode == 256 || minecraft.options.keyInventory.matchesKey(keyCode, 0)) + { + this.onClose(); + return true; + } + return super.keyPressed(keyCode, scanCode, modifiers); + } + + @Override + public void onClose() + { + PacketByteBuf packetBuffer = new PacketByteBuf(Unpooled.buffer()); + packetBuffer.writeBlockPos(blockPos); + packetBuffer.writeInt(xRange); + packetBuffer.writeInt(zRange); + packetBuffer.writeInt(yRange); + packetBuffer.writeInt(speed); + packetBuffer.writeInt(redstoneMode); + ClientSidePacketRegistry.INSTANCE.sendToServer(new Identifier(Torcherino.MOD_ID, "utv"), packetBuffer); + super.onClose(); + } +} diff --git a/torcherino/src/main/java/torcherino/client/screen/widgets/FixedSliderWidget.java b/torcherino/src/main/java/torcherino/client/screen/widgets/FixedSliderWidget.java new file mode 100644 index 00000000..62bec3f3 --- /dev/null +++ b/torcherino/src/main/java/torcherino/client/screen/widgets/FixedSliderWidget.java @@ -0,0 +1,35 @@ +package torcherino.client.screen.widgets; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.gui.widget.SliderWidget; +import net.minecraft.util.math.MathHelper; + +@Environment(EnvType.CLIENT) +public abstract class FixedSliderWidget extends SliderWidget +{ + private final float nudgeAmount; + + protected FixedSliderWidget(int x, int y, int width, double progress, int permutations) + { + super(x, y, width, 20, progress); + nudgeAmount = 1.0F / permutations; + this.updateMessage(); + } + + @Override + public boolean keyPressed(int keyCode, int scanCode, int modifiers) + { + boolean pressedLeft = keyCode == 263; + if (pressedLeft || keyCode == 262) { this.setValue(this.value + (pressedLeft ? -nudgeAmount : nudgeAmount)); } + return false; + } + + private void setValue(double value) + { + double currentValue = this.value; + this.value = MathHelper.clamp(value, 0, 1); + if (currentValue != this.value) { this.applyValue(); } + this.updateMessage(); + } +} diff --git a/torcherino/src/main/java/torcherino/client/screen/widgets/StateButtonWidget.java b/torcherino/src/main/java/torcherino/client/screen/widgets/StateButtonWidget.java new file mode 100644 index 00000000..4e254acf --- /dev/null +++ b/torcherino/src/main/java/torcherino/client/screen/widgets/StateButtonWidget.java @@ -0,0 +1,53 @@ +package torcherino.client.screen.widgets; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.render.item.ItemRenderer; +import net.minecraft.item.ItemStack; +import net.minecraft.text.TranslatableText; + +@Environment(EnvType.CLIENT) +public abstract class StateButtonWidget extends ButtonWidget +{ + private static ItemRenderer itemRenderer = MinecraftClient.getInstance().getItemRenderer(); + private final Screen screen; + private String narrationMessage; + + public StateButtonWidget(Screen screen, int x, int y) + { + super(x, y, 20, 20, "", null); + this.screen = screen; + initialize(); + } + + protected abstract void initialize(); + + protected abstract void nextState(); + + protected abstract ItemStack getButtonIcon(); + + @Override + public void render(int mouseX, int mouseY, float partialTicks) + { + if (visible) + { + super.render(mouseX, mouseY, partialTicks); + itemRenderer.renderGuiItem(getButtonIcon(), x + 2, y + 2); + if (this.isHovered) + { + screen.renderTooltip(narrationMessage, x + 14, y + 18); + } + } + } + + @Override + public void onPress() { nextState(); } + + @Override + public String getNarrationMessage() { return new TranslatableText("gui.narrate.button", narrationMessage).asString(); } + + protected void setNarrationMessage(String narrationMessage) { this.narrationMessage = narrationMessage; } +} diff --git a/torcherino/src/main/java/torcherino/config/Config.java b/torcherino/src/main/java/torcherino/config/Config.java new file mode 100644 index 00000000..35d5bc0f --- /dev/null +++ b/torcherino/src/main/java/torcherino/config/Config.java @@ -0,0 +1,84 @@ +package torcherino.config; + +import blue.endless.jankson.Comment; +import net.fabricmc.api.EnvType; +import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.util.Identifier; +import torcherino.Torcherino; +import torcherino.api.TorcherinoAPI; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +public class Config +{ + public static Config INSTANCE; + + @Comment("\nDefines how much faster randoms ticks are applied compared to what they should be.\nValid Range: 1 to 4096") + public final int random_tick_rate = 4; + + @Comment("Log torcherino placement (Intended for server use)") public final boolean log_placement = FabricLoader.getInstance().getEnvironmentType() == + EnvType.SERVER; + + @Comment("\nAdd a block by identifier to the blacklist.\nExamples: \"minecraft:dirt\", \"minecraft:furnace\"") + private final Identifier[] blacklisted_blocks = new Identifier[]{}; + + @Comment("\nAdd a block entity by identifier to the blacklist.\nExamples: \"minecraft:furnace\", \"minecraft:mob_spawner\"") + private final Identifier[] blacklisted_blockentities = new Identifier[]{}; + + @Comment("\nAllows new custom torcherino tiers to be added.\nThis also allows for each tier to have their own max max_speed and ranges.") + private final Tier[] tiers = new Tier[]{ new Tier("normal", 4, 4, 1), new Tier("compressed", 36, 4, 1), new Tier("double_compressed", 324, 4, 1) }; + + @Comment("\nWhen set to ONLINE, Torcherino's only run if the player is currently online\nIf set to RESTART then Torcherino's will run for anyone who has logged in since the server started.\nAnything else then Torcherino's will act like previous versions.") + public String online_mode = ""; + + + public static void initialize() + { + Path sci4meDirectory = FabricLoader.getInstance().getConfigDirectory().toPath().resolve("sci4me"); + if (!sci4meDirectory.toFile().exists()) + { + try + { + Files.createDirectory(sci4meDirectory); + INSTANCE = ConfigManager.loadConfig(Config.class, sci4meDirectory.resolve("Torcherino.cfg").toFile()); + } + catch (IOException e) + { + Torcherino.LOGGER.error("Failed to create sci4me folder, config won't be saved."); + INSTANCE = new Config(); + } + } + else + { + INSTANCE = ConfigManager.loadConfig(Config.class, sci4meDirectory.resolve("Torcherino.cfg").toFile()); + } + INSTANCE.onConfigLoaded(); + } + + private void onConfigLoaded() + { + online_mode = online_mode.toUpperCase(); + if (!(online_mode.equals("ONLINE") || online_mode.equals("RESTART"))) { online_mode = ""; } + for (Tier tier : tiers) { TorcherinoAPI.INSTANCE.registerTier(new Identifier("torcherino", tier.name), tier.max_speed, tier.xz_range, tier.y_range); } + for (Identifier id : blacklisted_blocks) { TorcherinoAPI.INSTANCE.blacklistBlock(id); } + for (Identifier id : blacklisted_blockentities) { TorcherinoAPI.INSTANCE.blacklistBlockEntity(id); } + } + + static class Tier + { + final String name; + final int max_speed; + final int xz_range; + final int y_range; + + Tier(String name, int max_speed, int xz_range, int y_range) + { + this.name = name; + this.max_speed = max_speed; + this.xz_range = xz_range; + this.y_range = y_range; + } + } +} diff --git a/torcherino/src/main/java/torcherino/config/ConfigManager.java b/torcherino/src/main/java/torcherino/config/ConfigManager.java new file mode 100644 index 00000000..b4e78c22 --- /dev/null +++ b/torcherino/src/main/java/torcherino/config/ConfigManager.java @@ -0,0 +1,105 @@ +package torcherino.config; + +import blue.endless.jankson.Jankson; +import blue.endless.jankson.JsonElement; +import blue.endless.jankson.JsonObject; +import blue.endless.jankson.JsonPrimitive; +import blue.endless.jankson.api.SyntaxError; +import net.minecraft.util.Identifier; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import torcherino.config.Config.Tier; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; + +/** + * Modified version of CottonMC's Config Manager which can be found here: https://github.com/CottonMC/Cotton/blob/af5d07f01aebc50fc28203881a8a9dcc1a9987cc/src/main/java/io/github/cottonmc/cotton/config/ConfigManager.java + */ +@SuppressWarnings({ "SameParameterValue", "WeakerAccess" }) +public class ConfigManager +{ + private static final Logger LOGGER = LogManager.getLogger(); + private static final Jankson jankson = new Jankson.Builder() + .registerSerializer(Identifier.class, (identifier, marshaller) -> new JsonPrimitive(identifier)) + .registerDeserializer(String.class, Identifier.class, (it, marshaller) -> new Identifier(it)) + .registerDeserializer(JsonObject.class, Tier.class, (it, marshaller) -> { + String name = it.get(String.class, "name"); + Integer max_speed = it.get(Integer.class, "max_speed"); + Integer xz_range = it.get(Integer.class, "xz_range"); + Integer y_range = it.get(Integer.class, "y_range"); + return new Tier(name, max_speed < 1 ? 1 : max_speed, xz_range < 0 ? 0 : xz_range, y_range < 0 ? 0 : y_range); + }) + .build(); + + @SuppressWarnings("ConstantConditions") + static T loadConfig(Class clazz, File configFile) + { + try + { + if (!configFile.exists()) + { + T instance = clazz.newInstance(); + saveConfig(instance, configFile); + return instance; + } + try + { + JsonObject json = jankson.load(configFile); + T result = jankson.fromJson(json, clazz); + JsonElement jsonElementNew = jankson.toJson(clazz.newInstance()); + if (jsonElementNew instanceof JsonObject) + { + JsonObject jsonNew = (JsonObject) jsonElementNew; + if (json.getDelta(jsonNew).size() >= 0) + { + saveConfig(result, configFile); + } + } + return result; + } + catch (IOException e) + { + LOGGER.warn("Failed to load config File {}: {}", configFile.getName(), e); + } + } + catch (SyntaxError syntaxError) + { + LOGGER.warn("Failed to load config File {}: {}", configFile.getName(), syntaxError); + } + catch (IllegalAccessException | InstantiationException e) + { + LOGGER.warn("Failed to create new config file for {}: {}", configFile.getName(), e); + } + LOGGER.warn("Creating placeholder config for {}...", configFile.getName()); + try + { + return clazz.newInstance(); + } + catch (InstantiationException | IllegalAccessException e) + { + LOGGER.warn("Failed to create placeholder config for {}: {}", configFile.getName(), e); + } + return null; + } + + @SuppressWarnings("ResultOfMethodCallIgnored") + private static void saveConfig(Object object, File configFile) + { + JsonElement json = jankson.toJson(object); + String result = json.toJson(true, true); + try + { + if (!configFile.exists()) { configFile.createNewFile(); } + FileOutputStream out = new FileOutputStream(configFile, false); + out.write(result.getBytes()); + out.flush(); + out.close(); + } + catch (IOException e) + { + LOGGER.warn("Failed to write to config file {}: {}", configFile.getName(), e); + } + } +} \ No newline at end of file diff --git a/torcherino/src/main/java/torcherino/mixins/PlayerManagerMixin.java b/torcherino/src/main/java/torcherino/mixins/PlayerManagerMixin.java new file mode 100644 index 00000000..d90d1450 --- /dev/null +++ b/torcherino/src/main/java/torcherino/mixins/PlayerManagerMixin.java @@ -0,0 +1,41 @@ +package torcherino.mixins; + +import com.google.common.collect.ImmutableMap; +import io.netty.buffer.Unpooled; +import net.fabricmc.fabric.api.network.ServerSidePacketRegistry; +import net.minecraft.network.ClientConnection; +import net.minecraft.server.PlayerManager; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.util.Identifier; +import net.minecraft.util.PacketByteBuf; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import torcherino.Torcherino; +import torcherino.api.Tier; +import torcherino.api.TorcherinoAPI; + +@Mixin(PlayerManager.class) +public abstract class PlayerManagerMixin +{ + @Inject(method = "onPlayerConnect", at = @At("TAIL")) + private void onPlayerConnect(ClientConnection clientConnection, ServerPlayerEntity player, CallbackInfo info) + { + Torcherino.playerConnected(player.getUuidAsString()); + ImmutableMap tiers = TorcherinoAPI.INSTANCE.getTiers(); + PacketByteBuf packetBuffer = new PacketByteBuf(Unpooled.buffer()); + packetBuffer.writeInt(tiers.size()); + tiers.forEach((id, tier) -> + { + packetBuffer.writeIdentifier(id); + packetBuffer.writeInt(tier.getMaxSpeed()); + packetBuffer.writeInt(tier.getXZRange()); + packetBuffer.writeInt(tier.getYRange()); + }); + ServerSidePacketRegistry.INSTANCE.sendToPlayer(player, new Identifier(Torcherino.MOD_ID, "tts"), packetBuffer); + } + + @Inject(method = "remove", at = @At("HEAD")) + private void onPlayerDisconnect(ServerPlayerEntity player, CallbackInfo ci) { Torcherino.playerDisconnect(player.getUuidAsString()); } +} diff --git a/torcherino/src/main/resources/assets/torcherino/blockstates/compressed_lanterino.json b/torcherino/src/main/resources/assets/torcherino/blockstates/compressed_lanterino.json new file mode 100644 index 00000000..153545b4 --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/blockstates/compressed_lanterino.json @@ -0,0 +1,19 @@ +{ + "variants": { + "facing=north": { + "model": "torcherino:block/compressed_lanterino" + }, + "facing=south": { + "model": "torcherino:block/compressed_lanterino", + "y": 180 + }, + "facing=west": { + "model": "torcherino:block/compressed_lanterino", + "y": 270 + }, + "facing=east": { + "model": "torcherino:block/compressed_lanterino", + "y": 90 + } + } +} diff --git a/torcherino/src/main/resources/assets/torcherino/blockstates/compressed_lantern.json b/torcherino/src/main/resources/assets/torcherino/blockstates/compressed_lantern.json new file mode 100644 index 00000000..60a57c4c --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/blockstates/compressed_lantern.json @@ -0,0 +1,10 @@ +{ + "variants": { + "hanging=true": { + "model": "torcherino:block/compressed_hanging_lantern" + }, + "hanging=false": { + "model": "torcherino:block/compressed_lantern" + } + } +} diff --git a/torcherino/src/main/resources/assets/torcherino/blockstates/compressed_torcherino.json b/torcherino/src/main/resources/assets/torcherino/blockstates/compressed_torcherino.json new file mode 100644 index 00000000..7bfe7997 --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/blockstates/compressed_torcherino.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "torcherino:block/compressed_torcherino" + } + } +} diff --git a/torcherino/src/main/resources/assets/torcherino/blockstates/double_compressed_lanterino.json b/torcherino/src/main/resources/assets/torcherino/blockstates/double_compressed_lanterino.json new file mode 100644 index 00000000..b98d9a99 --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/blockstates/double_compressed_lanterino.json @@ -0,0 +1,19 @@ +{ + "variants": { + "facing=north": { + "model": "torcherino:block/double_compressed_lanterino" + }, + "facing=south": { + "model": "torcherino:block/double_compressed_lanterino", + "y": 180 + }, + "facing=west": { + "model": "torcherino:block/double_compressed_lanterino", + "y": 270 + }, + "facing=east": { + "model": "torcherino:block/double_compressed_lanterino", + "y": 90 + } + } +} diff --git a/torcherino/src/main/resources/assets/torcherino/blockstates/double_compressed_lantern.json b/torcherino/src/main/resources/assets/torcherino/blockstates/double_compressed_lantern.json new file mode 100644 index 00000000..59b19c9a --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/blockstates/double_compressed_lantern.json @@ -0,0 +1,10 @@ +{ + "variants": { + "hanging=true": { + "model": "torcherino:block/double_compressed_hanging_lantern" + }, + "hanging=false": { + "model": "torcherino:block/double_compressed_lantern" + } + } +} diff --git a/torcherino/src/main/resources/assets/torcherino/blockstates/double_compressed_torcherino.json b/torcherino/src/main/resources/assets/torcherino/blockstates/double_compressed_torcherino.json new file mode 100644 index 00000000..662b835f --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/blockstates/double_compressed_torcherino.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "torcherino:block/double_compressed_torcherino" + } + } +} diff --git a/torcherino/src/main/resources/assets/torcherino/blockstates/lanterino.json b/torcherino/src/main/resources/assets/torcherino/blockstates/lanterino.json new file mode 100644 index 00000000..0ee0b046 --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/blockstates/lanterino.json @@ -0,0 +1,19 @@ +{ + "variants": { + "facing=north": { + "model": "torcherino:block/lanterino" + }, + "facing=south": { + "model": "torcherino:block/lanterino", + "y": 180 + }, + "facing=west": { + "model": "torcherino:block/lanterino", + "y": 270 + }, + "facing=east": { + "model": "torcherino:block/lanterino", + "y": 90 + } + } +} diff --git a/torcherino/src/main/resources/assets/torcherino/blockstates/lantern.json b/torcherino/src/main/resources/assets/torcherino/blockstates/lantern.json new file mode 100644 index 00000000..37a71d63 --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/blockstates/lantern.json @@ -0,0 +1,10 @@ +{ + "variants": { + "hanging=true": { + "model": "torcherino:block/hanging_lantern" + }, + "hanging=false": { + "model": "torcherino:block/lantern" + } + } +} diff --git a/torcherino/src/main/resources/assets/torcherino/blockstates/torcherino.json b/torcherino/src/main/resources/assets/torcherino/blockstates/torcherino.json new file mode 100644 index 00000000..3aaf3f25 --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/blockstates/torcherino.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "torcherino:block/torcherino" + } + } +} diff --git a/torcherino/src/main/resources/assets/torcherino/blockstates/wall_compressed_torcherino.json b/torcherino/src/main/resources/assets/torcherino/blockstates/wall_compressed_torcherino.json new file mode 100644 index 00000000..bdbe7058 --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/blockstates/wall_compressed_torcherino.json @@ -0,0 +1,19 @@ +{ + "variants": { + "facing=east": { + "model": "torcherino:block/wall_compressed_torcherino" + }, + "facing=south": { + "model": "torcherino:block/wall_compressed_torcherino", + "y": 90 + }, + "facing=west": { + "model": "torcherino:block/wall_compressed_torcherino", + "y": 180 + }, + "facing=north": { + "model": "torcherino:block/wall_compressed_torcherino", + "y": 270 + } + } +} diff --git a/torcherino/src/main/resources/assets/torcherino/blockstates/wall_double_compressed_torcherino.json b/torcherino/src/main/resources/assets/torcherino/blockstates/wall_double_compressed_torcherino.json new file mode 100644 index 00000000..1f868246 --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/blockstates/wall_double_compressed_torcherino.json @@ -0,0 +1,19 @@ +{ + "variants": { + "facing=east": { + "model": "torcherino:block/wall_double_compressed_torcherino" + }, + "facing=south": { + "model": "torcherino:block/wall_double_compressed_torcherino", + "y": 90 + }, + "facing=west": { + "model": "torcherino:block/wall_double_compressed_torcherino", + "y": 180 + }, + "facing=north": { + "model": "torcherino:block/wall_double_compressed_torcherino", + "y": 270 + } + } +} diff --git a/torcherino/src/main/resources/assets/torcherino/blockstates/wall_torcherino.json b/torcherino/src/main/resources/assets/torcherino/blockstates/wall_torcherino.json new file mode 100644 index 00000000..07b0bc50 --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/blockstates/wall_torcherino.json @@ -0,0 +1,19 @@ +{ + "variants": { + "facing=east": { + "model": "torcherino:block/wall_torcherino" + }, + "facing=south": { + "model": "torcherino:block/wall_torcherino", + "y": 90 + }, + "facing=west": { + "model": "torcherino:block/wall_torcherino", + "y": 180 + }, + "facing=north": { + "model": "torcherino:block/wall_torcherino", + "y": 270 + } + } +} diff --git a/torcherino/src/main/resources/assets/torcherino/icon.png b/torcherino/src/main/resources/assets/torcherino/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..5d7f432e4945975f8575a2f03c6d752016584725 GIT binary patch literal 22002 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 Jt-e$2{{ZJk{Cofa literal 0 HcmV?d00001 diff --git a/torcherino/src/main/resources/assets/torcherino/lang/en_us.json b/torcherino/src/main/resources/assets/torcherino/lang/en_us.json new file mode 100644 index 00000000..e5cb5d8c --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/lang/en_us.json @@ -0,0 +1,21 @@ +{ + "block.torcherino.torcherino": "Torcherino", + "block.torcherino.compressed_torcherino": "Compressed Torcherino", + "block.torcherino.double_compressed_torcherino": "Double Compressed Torcherino", + "block.torcherino.lanterino": "Jack o'Lanterino", + "block.torcherino.compressed_lanterino": "Compressed Jack o'Lanterino", + "block.torcherino.double_compressed_lanterino": "Double Compressed Jack o'Lanterino", + "block.torcherino.lantern": "Lanterino", + "block.torcherino.compressed_lantern": "Compressed Lanterino", + "block.torcherino.double_compressed_lantern": "Double Compressed Lanterino", + "gui.torcherino.speed": "Speed: %s%%", + "gui.torcherino.x_range": "X Range: %s Blocks", + "gui.torcherino.z_range": "Z Range: %s Blocks", + "gui.torcherino.y_range": "Y Range: %s Blocks", + "gui.torcherino.mode": "Mode: %s", + "gui.torcherino.mode.normal": "Redstone Normal", + "gui.torcherino.mode.inverted": "Redstone Inverted", + "gui.torcherino.mode.ignore": "Redstone Ignored", + "gui.torcherino.mode.off": "Off" +} + diff --git a/torcherino/src/main/resources/assets/torcherino/lang/zh_cn.json b/torcherino/src/main/resources/assets/torcherino/lang/zh_cn.json new file mode 100644 index 00000000..cbfcb3ab --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/lang/zh_cn.json @@ -0,0 +1,18 @@ +{ + "block.torcherino.torcherino": "加速火把", + "block.torcherino.compressed_torcherino": "压缩加速火把", + "block.torcherino.double_compressed_torcherino": "二重压缩加速火把", + "block.torcherino.lanterino": "加速南瓜灯", + "block.torcherino.compressed_lanterino": "压缩加速南瓜灯", + "block.torcherino.double_compressed_lanterino": "二重压缩加速南瓜灯", + "screen.torcherino.area.stopped": "停止", + "screen.torcherino.area.n": "区域: %1$dx3x%1$d", + "screen.torcherino.speed": "速度: %d%%", + "screen.torcherino.redstoneinteraction.normal": "标准", + "screen.torcherino.redstoneinteraction.inverted": "反转", + "screen.torcherino.redstoneinteraction.ignore": "忽略", + "screen.torcherino.narrate.redstoneinteraction": "%s 红石互动按钮", + "screen.torcherino.narrate.area.stopped": "停止", + "screen.torcherino.narrate.area.n": "区域: %1$dx3x%1$d" +} + diff --git a/torcherino/src/main/resources/assets/torcherino/models/block/compressed_hanging_lantern.json b/torcherino/src/main/resources/assets/torcherino/models/block/compressed_hanging_lantern.json new file mode 100644 index 00000000..1e4804b3 --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/models/block/compressed_hanging_lantern.json @@ -0,0 +1,7 @@ +{ + "parent": "block/hanging_lantern", + "textures": { + "particle": "torcherino:blocks/compressed_lantern", + "all": "torcherino:blocks/compressed_lantern" + } +} diff --git a/torcherino/src/main/resources/assets/torcherino/models/block/compressed_lanterino.json b/torcherino/src/main/resources/assets/torcherino/models/block/compressed_lanterino.json new file mode 100644 index 00000000..01080cc2 --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/models/block/compressed_lanterino.json @@ -0,0 +1,8 @@ +{ + "parent": "block/orientable", + "textures": { + "top": "torcherino:blocks/compressed_lanterino_top", + "front": "torcherino:blocks/compressed_lanterino", + "side": "torcherino:blocks/compressed_lanterino_side" + } +} diff --git a/torcherino/src/main/resources/assets/torcherino/models/block/compressed_lantern.json b/torcherino/src/main/resources/assets/torcherino/models/block/compressed_lantern.json new file mode 100644 index 00000000..1a825cb7 --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/models/block/compressed_lantern.json @@ -0,0 +1,7 @@ +{ + "parent": "block/lantern", + "textures": { + "particle": "torcherino:blocks/compressed_lantern", + "all": "torcherino:blocks/compressed_lantern" + } +} diff --git a/torcherino/src/main/resources/assets/torcherino/models/block/compressed_torcherino.json b/torcherino/src/main/resources/assets/torcherino/models/block/compressed_torcherino.json new file mode 100644 index 00000000..57b4939e --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/models/block/compressed_torcherino.json @@ -0,0 +1,6 @@ +{ + "parent": "block/template_torch", + "textures": { + "torch": "torcherino:blocks/compressed_torcherino" + } +} diff --git a/torcherino/src/main/resources/assets/torcherino/models/block/double_compressed_hanging_lantern.json b/torcherino/src/main/resources/assets/torcherino/models/block/double_compressed_hanging_lantern.json new file mode 100644 index 00000000..3aaa894c --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/models/block/double_compressed_hanging_lantern.json @@ -0,0 +1,7 @@ +{ + "parent": "block/hanging_lantern", + "textures": { + "particle": "torcherino:blocks/double_compressed_lantern", + "all": "torcherino:blocks/double_compressed_lantern" + } +} diff --git a/torcherino/src/main/resources/assets/torcherino/models/block/double_compressed_lanterino.json b/torcherino/src/main/resources/assets/torcherino/models/block/double_compressed_lanterino.json new file mode 100644 index 00000000..898e79b5 --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/models/block/double_compressed_lanterino.json @@ -0,0 +1,8 @@ +{ + "parent": "block/orientable", + "textures": { + "top": "torcherino:blocks/double_compressed_lanterino_top", + "front": "torcherino:blocks/double_compressed_lanterino", + "side": "torcherino:blocks/double_compressed_lanterino_side" + } +} diff --git a/torcherino/src/main/resources/assets/torcherino/models/block/double_compressed_lantern.json b/torcherino/src/main/resources/assets/torcherino/models/block/double_compressed_lantern.json new file mode 100644 index 00000000..e4e05dac --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/models/block/double_compressed_lantern.json @@ -0,0 +1,7 @@ +{ + "parent": "block/lantern", + "textures": { + "particle": "torcherino:blocks/double_compressed_lantern", + "all": "torcherino:blocks/double_compressed_lantern" + } +} diff --git a/torcherino/src/main/resources/assets/torcherino/models/block/double_compressed_torcherino.json b/torcherino/src/main/resources/assets/torcherino/models/block/double_compressed_torcherino.json new file mode 100644 index 00000000..e060403c --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/models/block/double_compressed_torcherino.json @@ -0,0 +1,6 @@ +{ + "parent": "block/template_torch", + "textures": { + "torch": "torcherino:blocks/double_compressed_torcherino" + } +} diff --git a/torcherino/src/main/resources/assets/torcherino/models/block/hanging_lantern.json b/torcherino/src/main/resources/assets/torcherino/models/block/hanging_lantern.json new file mode 100644 index 00000000..008feefa --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/models/block/hanging_lantern.json @@ -0,0 +1,7 @@ +{ + "parent": "block/hanging_lantern", + "textures": { + "particle": "torcherino:blocks/lantern", + "all": "torcherino:blocks/lantern" + } +} diff --git a/torcherino/src/main/resources/assets/torcherino/models/block/lanterino.json b/torcherino/src/main/resources/assets/torcherino/models/block/lanterino.json new file mode 100644 index 00000000..23934cbb --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/models/block/lanterino.json @@ -0,0 +1,8 @@ +{ + "parent": "block/orientable", + "textures": { + "top": "block/pumpkin_top", + "front": "torcherino:blocks/lanterino", + "side": "block/pumpkin_side" + } +} diff --git a/torcherino/src/main/resources/assets/torcherino/models/block/lantern.json b/torcherino/src/main/resources/assets/torcherino/models/block/lantern.json new file mode 100644 index 00000000..c547c5b1 --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/models/block/lantern.json @@ -0,0 +1,7 @@ +{ + "parent": "block/lantern", + "textures": { + "particle": "torcherino:blocks/lantern", + "all": "torcherino:blocks/lantern" + } +} diff --git a/torcherino/src/main/resources/assets/torcherino/models/block/torcherino.json b/torcherino/src/main/resources/assets/torcherino/models/block/torcherino.json new file mode 100644 index 00000000..907f2f9d --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/models/block/torcherino.json @@ -0,0 +1,6 @@ +{ + "parent": "block/template_torch", + "textures": { + "torch": "torcherino:blocks/torcherino" + } +} diff --git a/torcherino/src/main/resources/assets/torcherino/models/block/wall_compressed_torcherino.json b/torcherino/src/main/resources/assets/torcherino/models/block/wall_compressed_torcherino.json new file mode 100644 index 00000000..374779d5 --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/models/block/wall_compressed_torcherino.json @@ -0,0 +1,135 @@ +{ + "ambientocclusion": false, + "textures": { + "torch": "torcherino:blocks/compressed_torcherino", + "particle": "torcherino:blocks/compressed_torcherino" + }, + "elements": [ + { + "from": [ + -1, + 3.5, + 7 + ], + "to": [ + 1, + 13.5, + 9 + ], + "rotation": { + "origin": [ + 0, + 3.5, + 8 + ], + "axis": "z", + "angle": -22.5 + }, + "shade": false, + "faces": { + "down": { + "uv": [ + 7, + 13, + 9, + 15 + ], + "texture": "#torch" + }, + "up": { + "uv": [ + 7, + 6, + 9, + 8 + ], + "texture": "#torch" + } + } + }, + { + "from": [ + -1, + 3.5, + 0 + ], + "to": [ + 1, + 19.5, + 16 + ], + "rotation": { + "origin": [ + 0, + 3.5, + 8 + ], + "axis": "z", + "angle": -22.5 + }, + "shade": false, + "faces": { + "west": { + "uv": [ + 0, + 0, + 16, + 16 + ], + "texture": "#torch" + }, + "east": { + "uv": [ + 0, + 0, + 16, + 16 + ], + "texture": "#torch" + } + } + }, + { + "from": [ + -8, + 3.5, + 7 + ], + "to": [ + 8, + 19.5, + 9 + ], + "rotation": { + "origin": [ + 0, + 3.5, + 8 + ], + "axis": "z", + "angle": -22.5 + }, + "shade": false, + "faces": { + "north": { + "uv": [ + 0, + 0, + 16, + 16 + ], + "texture": "#torch" + }, + "south": { + "uv": [ + 0, + 0, + 16, + 16 + ], + "texture": "#torch" + } + } + } + ] +} diff --git a/torcherino/src/main/resources/assets/torcherino/models/block/wall_double_compressed_torcherino.json b/torcherino/src/main/resources/assets/torcherino/models/block/wall_double_compressed_torcherino.json new file mode 100644 index 00000000..66b5aa91 --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/models/block/wall_double_compressed_torcherino.json @@ -0,0 +1,135 @@ +{ + "ambientocclusion": false, + "textures": { + "torch": "torcherino:blocks/double_compressed_torcherino", + "particle": "torcherino:blocks/double_compressed_torcherino" + }, + "elements": [ + { + "from": [ + -1, + 3.5, + 7 + ], + "to": [ + 1, + 13.5, + 9 + ], + "rotation": { + "origin": [ + 0, + 3.5, + 8 + ], + "axis": "z", + "angle": -22.5 + }, + "shade": false, + "faces": { + "down": { + "uv": [ + 7, + 13, + 9, + 15 + ], + "texture": "#torch" + }, + "up": { + "uv": [ + 7, + 6, + 9, + 8 + ], + "texture": "#torch" + } + } + }, + { + "from": [ + -1, + 3.5, + 0 + ], + "to": [ + 1, + 19.5, + 16 + ], + "rotation": { + "origin": [ + 0, + 3.5, + 8 + ], + "axis": "z", + "angle": -22.5 + }, + "shade": false, + "faces": { + "west": { + "uv": [ + 0, + 0, + 16, + 16 + ], + "texture": "#torch" + }, + "east": { + "uv": [ + 0, + 0, + 16, + 16 + ], + "texture": "#torch" + } + } + }, + { + "from": [ + -8, + 3.5, + 7 + ], + "to": [ + 8, + 19.5, + 9 + ], + "rotation": { + "origin": [ + 0, + 3.5, + 8 + ], + "axis": "z", + "angle": -22.5 + }, + "shade": false, + "faces": { + "north": { + "uv": [ + 0, + 0, + 16, + 16 + ], + "texture": "#torch" + }, + "south": { + "uv": [ + 0, + 0, + 16, + 16 + ], + "texture": "#torch" + } + } + } + ] +} diff --git a/torcherino/src/main/resources/assets/torcherino/models/block/wall_torcherino.json b/torcherino/src/main/resources/assets/torcherino/models/block/wall_torcherino.json new file mode 100644 index 00000000..bb2403ce --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/models/block/wall_torcherino.json @@ -0,0 +1,135 @@ +{ + "ambientocclusion": false, + "textures": { + "torch": "torcherino:blocks/torcherino", + "particle": "torcherino:blocks/torcherino" + }, + "elements": [ + { + "from": [ + -1, + 3.5, + 7 + ], + "to": [ + 1, + 13.5, + 9 + ], + "rotation": { + "origin": [ + 0, + 3.5, + 8 + ], + "axis": "z", + "angle": -22.5 + }, + "shade": false, + "faces": { + "down": { + "uv": [ + 7, + 13, + 9, + 15 + ], + "texture": "#torch" + }, + "up": { + "uv": [ + 7, + 6, + 9, + 8 + ], + "texture": "#torch" + } + } + }, + { + "from": [ + -1, + 3.5, + 0 + ], + "to": [ + 1, + 19.5, + 16 + ], + "rotation": { + "origin": [ + 0, + 3.5, + 8 + ], + "axis": "z", + "angle": -22.5 + }, + "shade": false, + "faces": { + "west": { + "uv": [ + 0, + 0, + 16, + 16 + ], + "texture": "#torch" + }, + "east": { + "uv": [ + 0, + 0, + 16, + 16 + ], + "texture": "#torch" + } + } + }, + { + "from": [ + -8, + 3.5, + 7 + ], + "to": [ + 8, + 19.5, + 9 + ], + "rotation": { + "origin": [ + 0, + 3.5, + 8 + ], + "axis": "z", + "angle": -22.5 + }, + "shade": false, + "faces": { + "north": { + "uv": [ + 0, + 0, + 16, + 16 + ], + "texture": "#torch" + }, + "south": { + "uv": [ + 0, + 0, + 16, + 16 + ], + "texture": "#torch" + } + } + } + ] +} diff --git a/torcherino/src/main/resources/assets/torcherino/models/item/compressed_lanterino.json b/torcherino/src/main/resources/assets/torcherino/models/item/compressed_lanterino.json new file mode 100644 index 00000000..2b77f902 --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/models/item/compressed_lanterino.json @@ -0,0 +1,3 @@ +{ + "parent": "torcherino:block/compressed_lanterino" +} diff --git a/torcherino/src/main/resources/assets/torcherino/models/item/compressed_lantern.json b/torcherino/src/main/resources/assets/torcherino/models/item/compressed_lantern.json new file mode 100644 index 00000000..42def787 --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/models/item/compressed_lantern.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "torcherino:item/compressed_lantern" + } +} diff --git a/torcherino/src/main/resources/assets/torcherino/models/item/compressed_torcherino.json b/torcherino/src/main/resources/assets/torcherino/models/item/compressed_torcherino.json new file mode 100644 index 00000000..75b88899 --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/models/item/compressed_torcherino.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "torcherino:blocks/compressed_torcherino" + } +} \ No newline at end of file diff --git a/torcherino/src/main/resources/assets/torcherino/models/item/double_compressed_lanterino.json b/torcherino/src/main/resources/assets/torcherino/models/item/double_compressed_lanterino.json new file mode 100644 index 00000000..d31b0f10 --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/models/item/double_compressed_lanterino.json @@ -0,0 +1,3 @@ +{ + "parent": "torcherino:block/double_compressed_lanterino" +} diff --git a/torcherino/src/main/resources/assets/torcherino/models/item/double_compressed_lantern.json b/torcherino/src/main/resources/assets/torcherino/models/item/double_compressed_lantern.json new file mode 100644 index 00000000..3bb388c4 --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/models/item/double_compressed_lantern.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "torcherino:item/double_compressed_lantern" + } +} diff --git a/torcherino/src/main/resources/assets/torcherino/models/item/double_compressed_torcherino.json b/torcherino/src/main/resources/assets/torcherino/models/item/double_compressed_torcherino.json new file mode 100644 index 00000000..0544c04b --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/models/item/double_compressed_torcherino.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "torcherino:blocks/double_compressed_torcherino" + } +} \ No newline at end of file diff --git a/torcherino/src/main/resources/assets/torcherino/models/item/lanterino.json b/torcherino/src/main/resources/assets/torcherino/models/item/lanterino.json new file mode 100644 index 00000000..1048d8bd --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/models/item/lanterino.json @@ -0,0 +1,3 @@ +{ + "parent": "torcherino:block/lanterino" +} diff --git a/torcherino/src/main/resources/assets/torcherino/models/item/lantern.json b/torcherino/src/main/resources/assets/torcherino/models/item/lantern.json new file mode 100644 index 00000000..645f1975 --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/models/item/lantern.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "torcherino:item/lantern" + } +} diff --git a/torcherino/src/main/resources/assets/torcherino/models/item/torcherino.json b/torcherino/src/main/resources/assets/torcherino/models/item/torcherino.json new file mode 100644 index 00000000..aa43eee9 --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/models/item/torcherino.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "torcherino:blocks/torcherino" + } +} \ No newline at end of file diff --git a/torcherino/src/main/resources/assets/torcherino/particles/compressed_flame.json b/torcherino/src/main/resources/assets/torcherino/particles/compressed_flame.json new file mode 100644 index 00000000..ae7118e6 --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/particles/compressed_flame.json @@ -0,0 +1,5 @@ +{ + "textures": [ + "torcherino:particle/compressed_flame" + ] +} \ No newline at end of file diff --git a/torcherino/src/main/resources/assets/torcherino/particles/double_compressed_flame.json b/torcherino/src/main/resources/assets/torcherino/particles/double_compressed_flame.json new file mode 100644 index 00000000..cc4d17f4 --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/particles/double_compressed_flame.json @@ -0,0 +1,5 @@ +{ + "textures": [ + "torcherino:particle/double_compressed_flame" + ] +} \ No newline at end of file diff --git a/torcherino/src/main/resources/assets/torcherino/particles/flame.json b/torcherino/src/main/resources/assets/torcherino/particles/flame.json new file mode 100644 index 00000000..68ecc664 --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/particles/flame.json @@ -0,0 +1,5 @@ +{ + "textures": [ + "torcherino:particle/flame" + ] +} \ No newline at end of file diff --git a/torcherino/src/main/resources/assets/torcherino/textures/blocks/compressed_lanterino.png b/torcherino/src/main/resources/assets/torcherino/textures/blocks/compressed_lanterino.png new file mode 100644 index 0000000000000000000000000000000000000000..d3bb8891b2659c997daf75ffa17e479772133cbd GIT binary patch literal 240 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPGa3-AeXb(3QV(`Se>X2`K+C=`F( z;LXsM#4s&_VW#l?4FZ?9aNO(pcb?qz1C2dW=M{HNVr?1<>o|W`q z<7L*Dr#~OotH}Sn`atSl={n;8YwyDH(?*LPFLPLVe!)D}+EbRt8IH7+^t5veq^~cD m>TQq;o5*F_P{8T-ga5%m8OlI2hVBvqMF9+hyYz`e>J9EdmIqN^l zR7!2kd2DNRtgLIP`@Kbr<{IbjjdE922x8!z!s4M(zS2}tbAs>7sLSsct$zM7vOn{j f-I4a%|8@Uj?rYCnbc3S}XcvR0tDnm{r-UW|_60*H literal 0 HcmV?d00001 diff --git a/torcherino/src/main/resources/assets/torcherino/textures/blocks/compressed_lanterino_top.png b/torcherino/src/main/resources/assets/torcherino/textures/blocks/compressed_lanterino_top.png new file mode 100644 index 0000000000000000000000000000000000000000..2e8c345765a870c49489ec159602fab991641191 GIT binary patch literal 211 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPGa2=EDUHIZfr(_)BmW{5Ln$gyB3 z3S($+WtbMh@bagwAy7@3r;B3tDnm{ Hr-UW|h9gMO literal 0 HcmV?d00001 diff --git a/torcherino/src/main/resources/assets/torcherino/textures/blocks/compressed_lantern.png b/torcherino/src/main/resources/assets/torcherino/textures/blocks/compressed_lantern.png new file mode 100644 index 0000000000000000000000000000000000000000..ae6fa394cdff7115565df296e8e32e0def6345e2 GIT binary patch literal 284 zcmeAS@N?(olHy`uVBq!ia0vp^0zhoQ!3-qz8@W<}lx2WVh%1n`a|xa)e1DVeuPrXW zw|V{f|NnoX_+uxpxGnnEHz{BB3`pG|aCx@M!@2s8PL=&XQ~Cc~&3{!L+lv40yMdY+ zOM?7@862M7NCR>vdb&7#6QX0`ofy;< zrFgbEt%6llVJ`P~t|iA`o96K5a%~XY+Ff}-azb89v3jnTMS01Qyp$M8<_CO=AEIQJ z^;f#rOzBfldcSo3b8UHVP45qZGrT_>+*SPH;O?Ri7bn(#-1uw{n|!1SyZoYd7WtwT fEb_8H9p(MKXL1~_TG_@9bR2`HtDnm{r-UW|Fh6fP literal 0 HcmV?d00001 diff --git a/torcherino/src/main/resources/assets/torcherino/textures/blocks/compressed_lantern.png.mcmeta b/torcherino/src/main/resources/assets/torcherino/textures/blocks/compressed_lantern.png.mcmeta new file mode 100644 index 00000000..5169aabd --- /dev/null +++ b/torcherino/src/main/resources/assets/torcherino/textures/blocks/compressed_lantern.png.mcmeta @@ -0,0 +1,5 @@ +{ + "animation": { + "frametime": 8 + } +} \ No newline at end of file diff --git a/torcherino/src/main/resources/assets/torcherino/textures/blocks/compressed_torcherino.png b/torcherino/src/main/resources/assets/torcherino/textures/blocks/compressed_torcherino.png new file mode 100644 index 0000000000000000000000000000000000000000..e2acc6e1fd3c40047e5a63104a2abd5142659769 GIT binary patch literal 163 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFv5AX?b1=7l5%&HQsYLaZ4GMuI= zysrAZ@pk+v&LV~4k7o+s-ym@L|NsAMZ=3?@WGo5t3ubV5b|VeQ(eiY04B?oWoS-0H z;M-udgWo|?hBJVzn!)D?<1r40=}E>7o|*?-SQ=Ou&Ui3SxVU(04^S6_r>mdKI;Vst E03{|XEal|AK%> literal 0 HcmV?d00001 diff --git a/torcherino/src/main/resources/assets/torcherino/textures/blocks/double_compressed_lanterino_side.png b/torcherino/src/main/resources/assets/torcherino/textures/blocks/double_compressed_lanterino_side.png new file mode 100644 index 0000000000000000000000000000000000000000..f408253e2a94befde2d75b87447b97f030ab0fcb GIT binary patch literal 183 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPE^3h)VWWoKvS;^N}w=H}ty5fBg% z5)#r_xa|;7Ho?=yF@!^w_25CqgAM`=2W~EHn9Q{0!NUJiUk=2Z*&I5&cIJ+AbJl;9 zsg&B7^VrttSXtLn_j`*L%{9*58|AL55X8Vag~daoe5I+P<^@4 literal 0 HcmV?d00001 diff --git a/torcherino/src/main/resources/assets/torcherino/textures/blocks/double_compressed_lanterino_top.png b/torcherino/src/main/resources/assets/torcherino/textures/blocks/double_compressed_lanterino_top.png new file mode 100644 index 0000000000000000000000000000000000000000..6e72fb759d2fb9a6dcd964e7cf97a27b9ef13a89 GIT binary patch literal 206 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPE^4e$wZWnp3A;^N}w=H}ty;p5{I z5D*X&60-Ukc>}1R#M8wwghQ6q!H};hfTz}tUqRsR(wFPj{xzO#oh!Hd;Q7D(2@k~d z^w^dMt!zrjU0Z!HI%w_rj+oj>S}yzbonP>M`~KeMSYJhqef)CAAG>r8M`T#q`uina zp0(_DOozwxtt{83MrjFbn|sCO$;3hrr!$vNzv0*7kxib#A)yYmpTX1B&t;ucLK6T? CNk#+! literal 0 HcmV?d00001 diff --git a/torcherino/src/main/resources/assets/torcherino/textures/blocks/double_compressed_lantern.png b/torcherino/src/main/resources/assets/torcherino/textures/blocks/double_compressed_lantern.png new file mode 100644 index 0000000000000000000000000000000000000000..3f8059dca5d6e7a81f1728408ad27b872b54c88f GIT binary patch literal 284 zcmV+%0ptFOP)F4>%$D`Iq@KKp-@WHxs@WH!s@X?Wf@v*kH1|LnN1s|e^ i1Rrv!1RovwK_5@r`v>cJe*KLA00001CD*Mg72dsZKtF82pu`dH!#Ng@b=d#Wzp$P!hPc;1i literal 0 HcmV?d00001 diff --git a/torcherino/src/main/resources/assets/torcherino/textures/blocks/lanterino.png b/torcherino/src/main/resources/assets/torcherino/textures/blocks/lanterino.png new file mode 100644 index 0000000000000000000000000000000000000000..527e7bbaeb2dfdbd813c7209474da3047b338cb3 GIT binary patch literal 240 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPGa3-AeX!u26H^To4e0d8*{Y8v?7 zO<1Feb!DY3Kk8d>onRZv8Ci-;Az9$Fla_hHFmzyZF^$Ony;XTni^}kG6%bU@} zx5i}60+u?HBx&)G^o`yUtam>h=8;W*U-x)ZleUis!#7JaPDyd64MJK|{v3R#zrt|e o*XJesO_D~><(vvS)n{m$Q>0jYw`KMiyKTNV5dKlMN6%>Tr5|5bHto0cxW3)IY5 z666=m;PC858jv&5)5S5QBJS=4OTNPfJS<0NTh%=M-|w4pctVGQ?yaRj^LAoXh>4Yx(ilr8&H{TpLzy>#qDDxgw{lczNC;i}I2q`6)4yhjWf8Ziwn# z-XH0nGo?>K>HX6A&$Z>f&v}2C$XN7&ag*~0#@!AdE>5ifxN+JhHu=^SEb=Pstnwus ftn#uy9p(K`f90I6w9Qcy=r{&XS3j3^P6tw1F>Z+F;ZZ@^lZGL^g|NsBbNpeL2l`@tD`2{mLJiCzwOSctx#5Sj}hs0(uFjQ?}JN|rK&k>+O N44$rjF6*2UngE5{IH>>t literal 0 HcmV?d00001 diff --git a/torcherino/src/main/resources/assets/torcherino/textures/item/lantern.png b/torcherino/src/main/resources/assets/torcherino/textures/item/lantern.png new file mode 100644 index 0000000000000000000000000000000000000000..3b7ec97a081bda459ede421c7e61f9a12f8daef0 GIT binary patch literal 170 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPGa4)6(a1=9SXp9PzL3a@~ literal 0 HcmV?d00001 diff --git a/torcherino/src/main/resources/assets/torcherino/textures/particle/compressed_flame.png b/torcherino/src/main/resources/assets/torcherino/textures/particle/compressed_flame.png new file mode 100644 index 0000000000000000000000000000000000000000..aebe2baea30b2b6f2ed6d26a8a2bb8391b5b28e4 GIT binary patch literal 129 zcmeAS@N?(olHy`uVBq!ia0vp^93afX3?$7I7w-U4`~f~8u0Xm_{P9fT`x^u<|NsAA zht*?0P>8W4$S;_|;n|HeAVmdKI;Vst0D#z6<^TWy literal 0 HcmV?d00001 diff --git a/torcherino/src/main/resources/data/torcherino/loot_tables/blocks/compressed_lanterino.json b/torcherino/src/main/resources/data/torcherino/loot_tables/blocks/compressed_lanterino.json new file mode 100644 index 00000000..e650c5c6 --- /dev/null +++ b/torcherino/src/main/resources/data/torcherino/loot_tables/blocks/compressed_lanterino.json @@ -0,0 +1,71 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:alternatives", + "children": [ + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "flags": { + "is_sneaking": true + } + } + } + ], + "name": "minecraft:carved_pumpkin" + }, + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "functions": [ + { + "function": "minecraft:copy_name", + "source": "block_entity" + } + ], + "name": "torcherino:compressed_lanterino" + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "flags": { + "is_sneaking": true + } + } + } + ], + "functions": [ + { + "function": "minecraft:copy_name", + "source": "block_entity" + } + ], + "name": "torcherino:compressed_torcherino" + } + ] + } + ] +} \ No newline at end of file diff --git a/torcherino/src/main/resources/data/torcherino/loot_tables/blocks/compressed_lantern.json b/torcherino/src/main/resources/data/torcherino/loot_tables/blocks/compressed_lantern.json new file mode 100644 index 00000000..f363a046 --- /dev/null +++ b/torcherino/src/main/resources/data/torcherino/loot_tables/blocks/compressed_lantern.json @@ -0,0 +1,71 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:alternatives", + "children": [ + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "flags": { + "is_sneaking": true + } + } + } + ], + "name": "minecraft:lantern" + }, + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "functions": [ + { + "function": "minecraft:copy_name", + "source": "block_entity" + } + ], + "name": "torcherino:compressed_lantern" + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "flags": { + "is_sneaking": true + } + } + } + ], + "functions": [ + { + "function": "minecraft:copy_name", + "source": "block_entity" + } + ], + "name": "torcherino:compressed_torcherino" + } + ] + } + ] +} \ No newline at end of file diff --git a/torcherino/src/main/resources/data/torcherino/loot_tables/blocks/compressed_torcherino.json b/torcherino/src/main/resources/data/torcherino/loot_tables/blocks/compressed_torcherino.json new file mode 100644 index 00000000..d6d8d57f --- /dev/null +++ b/torcherino/src/main/resources/data/torcherino/loot_tables/blocks/compressed_torcherino.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:copy_name", + "source": "block_entity" + } + ], + "name": "torcherino:compressed_torcherino" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/torcherino/src/main/resources/data/torcherino/loot_tables/blocks/double_compressed_lanterino.json b/torcherino/src/main/resources/data/torcherino/loot_tables/blocks/double_compressed_lanterino.json new file mode 100644 index 00000000..0884019b --- /dev/null +++ b/torcherino/src/main/resources/data/torcherino/loot_tables/blocks/double_compressed_lanterino.json @@ -0,0 +1,71 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:alternatives", + "children": [ + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "flags": { + "is_sneaking": true + } + } + } + ], + "name": "minecraft:carved_pumpkin" + }, + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "functions": [ + { + "function": "minecraft:copy_name", + "source": "block_entity" + } + ], + "name": "torcherino:double_compressed_lanterino" + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "flags": { + "is_sneaking": true + } + } + } + ], + "functions": [ + { + "function": "minecraft:copy_name", + "source": "block_entity" + } + ], + "name": "torcherino:double_compressed_torcherino" + } + ] + } + ] +} \ No newline at end of file diff --git a/torcherino/src/main/resources/data/torcherino/loot_tables/blocks/double_compressed_lantern.json b/torcherino/src/main/resources/data/torcherino/loot_tables/blocks/double_compressed_lantern.json new file mode 100644 index 00000000..a7c3c711 --- /dev/null +++ b/torcherino/src/main/resources/data/torcherino/loot_tables/blocks/double_compressed_lantern.json @@ -0,0 +1,71 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:alternatives", + "children": [ + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "flags": { + "is_sneaking": true + } + } + } + ], + "name": "minecraft:lantern" + }, + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "functions": [ + { + "function": "minecraft:copy_name", + "source": "block_entity" + } + ], + "name": "torcherino:double_compressed_lantern" + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "flags": { + "is_sneaking": true + } + } + } + ], + "functions": [ + { + "function": "minecraft:copy_name", + "source": "block_entity" + } + ], + "name": "torcherino:double_compressed_torcherino" + } + ] + } + ] +} \ No newline at end of file diff --git a/torcherino/src/main/resources/data/torcherino/loot_tables/blocks/double_compressed_torcherino.json b/torcherino/src/main/resources/data/torcherino/loot_tables/blocks/double_compressed_torcherino.json new file mode 100644 index 00000000..dde21f9e --- /dev/null +++ b/torcherino/src/main/resources/data/torcherino/loot_tables/blocks/double_compressed_torcherino.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:copy_name", + "source": "block_entity" + } + ], + "name": "torcherino:double_compressed_torcherino" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/torcherino/src/main/resources/data/torcherino/loot_tables/blocks/lanterino.json b/torcherino/src/main/resources/data/torcherino/loot_tables/blocks/lanterino.json new file mode 100644 index 00000000..041d37d7 --- /dev/null +++ b/torcherino/src/main/resources/data/torcherino/loot_tables/blocks/lanterino.json @@ -0,0 +1,71 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:alternatives", + "children": [ + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "flags": { + "is_sneaking": true + } + } + } + ], + "name": "minecraft:carved_pumpkin" + }, + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "functions": [ + { + "function": "minecraft:copy_name", + "source": "block_entity" + } + ], + "name": "torcherino:lanterino" + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "flags": { + "is_sneaking": true + } + } + } + ], + "functions": [ + { + "function": "minecraft:copy_name", + "source": "block_entity" + } + ], + "name": "torcherino:torcherino" + } + ] + } + ] +} \ No newline at end of file diff --git a/torcherino/src/main/resources/data/torcherino/loot_tables/blocks/lantern.json b/torcherino/src/main/resources/data/torcherino/loot_tables/blocks/lantern.json new file mode 100644 index 00000000..9d2af369 --- /dev/null +++ b/torcherino/src/main/resources/data/torcherino/loot_tables/blocks/lantern.json @@ -0,0 +1,71 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:alternatives", + "children": [ + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "flags": { + "is_sneaking": true + } + } + } + ], + "name": "minecraft:lantern" + }, + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "functions": [ + { + "function": "minecraft:copy_name", + "source": "block_entity" + } + ], + "name": "torcherino:lantern" + } + ] + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "flags": { + "is_sneaking": true + } + } + } + ], + "functions": [ + { + "function": "minecraft:copy_name", + "source": "block_entity" + } + ], + "name": "torcherino:torcherino" + } + ] + } + ] +} \ No newline at end of file diff --git a/torcherino/src/main/resources/data/torcherino/loot_tables/blocks/torcherino.json b/torcherino/src/main/resources/data/torcherino/loot_tables/blocks/torcherino.json new file mode 100644 index 00000000..fc78099e --- /dev/null +++ b/torcherino/src/main/resources/data/torcherino/loot_tables/blocks/torcherino.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:copy_name", + "source": "block_entity" + } + ], + "name": "torcherino:torcherino" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/torcherino/src/main/resources/data/torcherino/recipes/compressed_lanterino.json b/torcherino/src/main/resources/data/torcherino/recipes/compressed_lanterino.json new file mode 100644 index 00000000..000677e2 --- /dev/null +++ b/torcherino/src/main/resources/data/torcherino/recipes/compressed_lanterino.json @@ -0,0 +1,14 @@ +{ + "type": "crafting_shapeless", + "ingredients": [ + { + "item": "minecraft:carved_pumpkin" + }, + { + "item": "torcherino:compressed_torcherino" + } + ], + "result": { + "item": "torcherino:compressed_lanterino" + } +} \ No newline at end of file diff --git a/torcherino/src/main/resources/data/torcherino/recipes/compressed_lantern.json b/torcherino/src/main/resources/data/torcherino/recipes/compressed_lantern.json new file mode 100644 index 00000000..1693edbc --- /dev/null +++ b/torcherino/src/main/resources/data/torcherino/recipes/compressed_lantern.json @@ -0,0 +1,14 @@ +{ + "type": "crafting_shapeless", + "ingredients": [ + { + "item": "minecraft:lantern" + }, + { + "item": "torcherino:compressed_torcherino" + } + ], + "result": { + "item": "torcherino:compressed_lantern" + } +} \ No newline at end of file diff --git a/torcherino/src/main/resources/data/torcherino/recipes/compressed_torcherino.json b/torcherino/src/main/resources/data/torcherino/recipes/compressed_torcherino.json new file mode 100644 index 00000000..28a427e9 --- /dev/null +++ b/torcherino/src/main/resources/data/torcherino/recipes/compressed_torcherino.json @@ -0,0 +1,16 @@ +{ + "type": "crafting_shaped", + "pattern": [ + "TTT", + "TTT", + "TTT" + ], + "key": { + "T": { + "item": "torcherino:torcherino" + } + }, + "result": { + "item": "torcherino:compressed_torcherino" + } +} \ No newline at end of file diff --git a/torcherino/src/main/resources/data/torcherino/recipes/compressed_torcherino_to_single.json b/torcherino/src/main/resources/data/torcherino/recipes/compressed_torcherino_to_single.json new file mode 100644 index 00000000..c937b23d --- /dev/null +++ b/torcherino/src/main/resources/data/torcherino/recipes/compressed_torcherino_to_single.json @@ -0,0 +1,12 @@ +{ + "type": "crafting_shapeless", + "ingredients": [ + { + "item": "torcherino:compressed_torcherino" + } + ], + "result": { + "item": "torcherino:torcherino", + "count": 9 + } +} \ No newline at end of file diff --git a/torcherino/src/main/resources/data/torcherino/recipes/double_compressed_lanterino.json b/torcherino/src/main/resources/data/torcherino/recipes/double_compressed_lanterino.json new file mode 100644 index 00000000..3f88c042 --- /dev/null +++ b/torcherino/src/main/resources/data/torcherino/recipes/double_compressed_lanterino.json @@ -0,0 +1,14 @@ +{ + "type": "crafting_shapeless", + "ingredients": [ + { + "item": "minecraft:carved_pumpkin" + }, + { + "item": "torcherino:double_compressed_torcherino" + } + ], + "result": { + "item": "torcherino:double_compressed_lanterino" + } +} \ No newline at end of file diff --git a/torcherino/src/main/resources/data/torcherino/recipes/double_compressed_lantern.json b/torcherino/src/main/resources/data/torcherino/recipes/double_compressed_lantern.json new file mode 100644 index 00000000..48f04b4f --- /dev/null +++ b/torcherino/src/main/resources/data/torcherino/recipes/double_compressed_lantern.json @@ -0,0 +1,14 @@ +{ + "type": "crafting_shapeless", + "ingredients": [ + { + "item": "minecraft:lantern" + }, + { + "item": "torcherino:double_compressed_torcherino" + } + ], + "result": { + "item": "torcherino:double_compressed_lantern" + } +} \ No newline at end of file diff --git a/torcherino/src/main/resources/data/torcherino/recipes/double_compressed_torcherino.json b/torcherino/src/main/resources/data/torcherino/recipes/double_compressed_torcherino.json new file mode 100644 index 00000000..c5fd660c --- /dev/null +++ b/torcherino/src/main/resources/data/torcherino/recipes/double_compressed_torcherino.json @@ -0,0 +1,16 @@ +{ + "type": "crafting_shaped", + "pattern": [ + "TTT", + "TTT", + "TTT" + ], + "key": { + "T": { + "item": "torcherino:compressed_torcherino" + } + }, + "result": { + "item": "torcherino:double_compressed_torcherino" + } +} \ No newline at end of file diff --git a/torcherino/src/main/resources/data/torcherino/recipes/double_compressed_torcherino_to_compressed.json b/torcherino/src/main/resources/data/torcherino/recipes/double_compressed_torcherino_to_compressed.json new file mode 100644 index 00000000..f7550757 --- /dev/null +++ b/torcherino/src/main/resources/data/torcherino/recipes/double_compressed_torcherino_to_compressed.json @@ -0,0 +1,12 @@ +{ + "type": "crafting_shapeless", + "ingredients": [ + { + "item": "torcherino:double_compressed_torcherino" + } + ], + "result": { + "item": "torcherino:compressed_torcherino", + "count": 9 + } +} \ No newline at end of file diff --git a/torcherino/src/main/resources/data/torcherino/recipes/lanterino.json b/torcherino/src/main/resources/data/torcherino/recipes/lanterino.json new file mode 100644 index 00000000..6e832813 --- /dev/null +++ b/torcherino/src/main/resources/data/torcherino/recipes/lanterino.json @@ -0,0 +1,14 @@ +{ + "type": "crafting_shapeless", + "ingredients": [ + { + "item": "minecraft:carved_pumpkin" + }, + { + "item": "torcherino:torcherino" + } + ], + "result": { + "item": "torcherino:lanterino" + } +} \ No newline at end of file diff --git a/torcherino/src/main/resources/data/torcherino/recipes/lantern.json b/torcherino/src/main/resources/data/torcherino/recipes/lantern.json new file mode 100644 index 00000000..a35ce1eb --- /dev/null +++ b/torcherino/src/main/resources/data/torcherino/recipes/lantern.json @@ -0,0 +1,14 @@ +{ + "type": "crafting_shapeless", + "ingredients": [ + { + "item": "minecraft:lantern" + }, + { + "item": "torcherino:torcherino" + } + ], + "result": { + "item": "torcherino:lantern" + } +} \ No newline at end of file diff --git a/torcherino/src/main/resources/data/torcherino/recipes/torcherino.json b/torcherino/src/main/resources/data/torcherino/recipes/torcherino.json new file mode 100644 index 00000000..709fbc0f --- /dev/null +++ b/torcherino/src/main/resources/data/torcherino/recipes/torcherino.json @@ -0,0 +1,19 @@ +{ + "type": "crafting_shaped", + "pattern": [ + " C ", + "CTC", + " C " + ], + "key": { + "T": { + "item": "minecraft:torch" + }, + "C": { + "item": "minecraft:clock" + } + }, + "result": { + "item": "torcherino:torcherino" + } +} \ No newline at end of file diff --git a/torcherino/src/main/resources/fabric.mod.json b/torcherino/src/main/resources/fabric.mod.json new file mode 100644 index 00000000..c8ed366a --- /dev/null +++ b/torcherino/src/main/resources/fabric.mod.json @@ -0,0 +1,39 @@ +{ + "schemaVersion": 1, + "id": "torcherino", + "version": "${version}", + "name": "Torcherino", + "description": "Adds torches which speeds up block entities around them.", + "authors": [ + "NinjaPhenix" + ], + "contact": { + "homepage": "https://minecraft.curseforge.com/projects/torcherino", + "sources": "https://github.com/NinjaPhenix/Torcherino/tree/1.14.4-fabric" + }, + "license": "LGPL-3.0", + "icon": "assets/torcherino/icon.png", + "environment": "*", + "entrypoints": { + "main": [ + "torcherino.Torcherino" + ], + "client": [ + "torcherino.TorcherinoClient" + ], + "torcherinoInitializer": [ + "torcherino.Torcherino" + ] + }, + "depends": { + "fabricloader": ">=0.7.0", + "fabric": ">=0.4.28", + "minecraft": "1.15.2" + }, + "mixins": [ + { + "config": "torcherino.mixins.json", + "environment": "*" + } + ] +} \ No newline at end of file diff --git a/torcherino/src/main/resources/torcherino.mixins.json b/torcherino/src/main/resources/torcherino.mixins.json new file mode 100644 index 00000000..9685ad0c --- /dev/null +++ b/torcherino/src/main/resources/torcherino.mixins.json @@ -0,0 +1,12 @@ +{ + "required": true, + "package": "torcherino.mixins", + "compatibilityLevel": "JAVA_8", + "mixins": [ + "PlayerManagerMixin" + ], + "injectors": { + "defaultRequire": 1 + }, + "minVersion": "0.7.11" +} \ No newline at end of file