Implement shrine to reset skillpoints, custom shrine model, worldgen for the shrine, and other stuff

This commit is contained in:
2025-11-12 11:11:15 +01:00
parent 20ca8c3e43
commit f72c2a54fe
20 changed files with 709 additions and 8 deletions
+4
View File
@@ -211,3 +211,7 @@ publishing {
tasks.withType(JavaCompile).configureEach {
options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation
}
tasks.withType(ProcessResources).configureEach {
duplicatesStrategy = DuplicatesStrategy.INCLUDE
}
@@ -3,6 +3,7 @@ package net.fretux.ascend;
import net.fretux.ascend.command.AscendCommand;
import net.fretux.ascend.config.AscendConfig;
import net.fretux.ascend.network.PacketHandler;
import net.fretux.ascend.registry.ModBlocks;
import net.fretux.ascend.registry.ModItems;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.eventbus.api.SubscribeEvent;
@@ -24,6 +25,7 @@ public class AscendMod {
System.out.println("[Ascend] Mod loaded! Side=" + FMLEnvironment.dist);
net.minecraftforge.fml.ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, AscendConfig.COMMON_SPEC);
ModItems.register(modBus);
ModBlocks.register(modBus);
}
private void onCommonSetup(final FMLCommonSetupEvent event) {
@@ -0,0 +1,32 @@
package net.fretux.ascend.block;
import net.minecraft.core.BlockPos;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.RenderShape;
import net.minecraft.world.level.block.state.BlockState;
public class ShrineOfRemembranceBlock extends Block {
public ShrineOfRemembranceBlock(Properties props) {
super(props);
}
@Override
public RenderShape getRenderShape(BlockState state) {
return RenderShape.MODEL;
}
@Override
public InteractionResult use(BlockState state, Level level, BlockPos pos,
Player player, InteractionHand hand,
net.minecraft.world.phys.BlockHitResult hit) {
if (level.isClientSide) {
net.minecraft.client.Minecraft.getInstance().setScreen(new net.fretux.ascend.client.screen.ShrineScreen());
return InteractionResult.SUCCESS;
}
return InteractionResult.CONSUME;
}
}
@@ -0,0 +1,65 @@
package net.fretux.ascend.client.screen;
import com.mojang.blaze3d.systems.RenderSystem;
import net.fretux.ascend.network.PacketHandler;
import net.fretux.ascend.network.ServerboundShrineChoicePacket;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component;
public class ShrineScreen extends Screen {
private static final int WIDTH = 200;
private static final int HEIGHT = 120;
private int leftPos;
private int topPos;
public ShrineScreen() {
super(Component.literal("Shrine of Remembrance"));
}
@Override
protected void init() {
super.init();
this.leftPos = (this.width - WIDTH) / 2;
this.topPos = (this.height - HEIGHT) / 2;
this.clearWidgets();
// Dialogue text
int buttonY = topPos + 60;
Button forgetButton = Button.builder(Component.literal("I WISH TO FORGET"), (btn) -> {
PacketHandler.INSTANCE.sendToServer(new ServerboundShrineChoicePacket("forget"));
Minecraft.getInstance().setScreen(null);
}).bounds(leftPos + 20, buttonY, WIDTH - 40, 20).build();
Button cancelButton = Button.builder(Component.literal("LEAVE"), (btn) -> {
Minecraft.getInstance().setScreen(null);
}).bounds(leftPos + 20, buttonY + 25, WIDTH - 40, 20).build();
addRenderableWidget(forgetButton);
addRenderableWidget(cancelButton);
}
@Override
public void render(GuiGraphics gui, int mouseX, int mouseY, float partialTicks) {
this.renderBackground(gui);
RenderSystem.enableBlend();
gui.fill(leftPos - 6, topPos - 6, leftPos + WIDTH + 6, topPos + HEIGHT + 6, 0xAA000000);
RenderSystem.disableBlend();
gui.drawCenteredString(this.font, "SPEAK, LITTLE ONE.", this.width / 2, topPos + 10, 0xAA55FF);
gui.drawCenteredString(this.font, "WHAT IS IT YOU SEEK TO UNMAKE?", this.width / 2, topPos + 25, 0xAA55FF);
super.render(gui, mouseX, mouseY, partialTicks);
}
@Override
public boolean isPauseScreen() {
return false;
}
}
@@ -25,13 +25,13 @@ public class AscendConfig {
builder.push("Ascend Progression");
xpPerMobKill = builder.comment("Ascend XP gained for killing a mob.")
.defineInRange("xpPerMobKill", 5, 0, 1000);
.defineInRange("xpPerMobKill", 10, 0, 1000);
xpPerBlockBreak = builder.comment("Ascend XP gained for breaking a block (ore/stone/log).")
.defineInRange("xpPerBlockBreak", 2, 0, 1000);
xpPerCraft = builder.comment("Ascend XP gained for crafting items.")
.defineInRange("xpPerCraft", 3, 0, 1000);
.defineInRange("xpPerCraft", 1, 0, 1000);
xpPerSmelt = builder.comment("Ascend XP gained for smelting items.")
.defineInRange("xpPerSmelt", 2, 0, 1000);
.defineInRange("xpPerSmelt", 1, 0, 1000);
xpPerTrade = builder.comment("Ascend XP gained for trading with villagers.")
.defineInRange("xpPerTrade", 5, 0, 1000);
xpPerDamageTaken = builder.comment("Ascend XP gained for taking damage.")
@@ -1,6 +1,9 @@
package net.fretux.ascend.datagen;
import net.fretux.ascend.AscendMod;
import net.fretux.ascend.worldgen.ModWorldGenProvider;
import net.minecraft.data.DataGenerator;
import net.minecraft.data.PackOutput;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.data.ExistingFileHelper;
@@ -14,11 +17,13 @@ public class AscendDataGenerators {
@OnlyIn(Dist.CLIENT)
@SubscribeEvent
public static void gatherData(GatherDataEvent event) {
var generator = event.getGenerator();
ExistingFileHelper existingFileHelper = event.getExistingFileHelper();
DataGenerator generator = event.getGenerator();
PackOutput output = generator.getPackOutput();
ExistingFileHelper helper = event.getExistingFileHelper();
if (event.includeClient()) {
generator.addProvider(true, new AscendItemModelProvider(generator.getPackOutput(), existingFileHelper));
}
generator.addProvider(event.includeClient(), new ModBlockStateProvider(output, helper));
generator.addProvider(event.includeClient(), new AscendItemModelProvider(output, helper));
generator.addProvider(event.includeServer(), new ModLootTableProvider(output));
generator.addProvider(event.includeServer(), new ModWorldGenProvider(output, event.getLookupProvider()));
}
}
@@ -1,6 +1,7 @@
package net.fretux.ascend.datagen;
import net.fretux.ascend.AscendMod;
import net.fretux.ascend.registry.ModBlocks;
import net.fretux.ascend.registry.ModItems;
import net.minecraft.data.PackOutput;
import net.minecraftforge.client.model.generators.ItemModelProvider;
@@ -18,6 +19,8 @@ public class AscendItemModelProvider extends ItemModelProvider {
protected void registerModels() {
assert ModItems.MOONSEYE_TOME.getId() != null;
basicItem(ModItems.MOONSEYE_TOME.getId().getPath());
withExistingParent(ModBlocks.SHRINE_OF_REMEMBRANCE.getId().getPath(),
modLoc("block/" + ModBlocks.SHRINE_OF_REMEMBRANCE.getId().getPath()));
}
private void basicItem(String name) {
@@ -0,0 +1,24 @@
package net.fretux.ascend.datagen;
import net.fretux.ascend.registry.ModBlocks;
import net.minecraft.data.loot.BlockLootSubProvider;
import net.minecraft.world.flag.FeatureFlags;
import java.util.Set;
public class ModBlockLootProvider extends BlockLootSubProvider {
public ModBlockLootProvider() {
super(Set.of(), FeatureFlags.REGISTRY.allFlags());
}
@Override
protected void generate() {
}
@Override
protected Iterable<net.minecraft.world.level.block.Block> getKnownBlocks() {
return Set.of(ModBlocks.SHRINE_OF_REMEMBRANCE.get());
}
}
@@ -0,0 +1,21 @@
package net.fretux.ascend.datagen;
import net.fretux.ascend.AscendMod;
import net.fretux.ascend.registry.ModBlocks;
import net.minecraft.data.PackOutput;
import net.minecraftforge.client.model.generators.BlockStateProvider;
import net.minecraftforge.client.model.generators.ModelFile;
import net.minecraftforge.common.data.ExistingFileHelper;
public class ModBlockStateProvider extends BlockStateProvider {
public ModBlockStateProvider(PackOutput output, ExistingFileHelper exFileHelper) {
super(output, AscendMod.MODID, exFileHelper);
}
@Override
protected void registerStatesAndModels() {
ModelFile shrineModel = models().getExistingFile(modLoc("block/shrine_of_remembrance"));
simpleBlockWithItem(ModBlocks.SHRINE_OF_REMEMBRANCE.get(), shrineModel);
}
}
@@ -0,0 +1,16 @@
package net.fretux.ascend.datagen;
import net.minecraft.data.PackOutput;
import net.minecraft.data.loot.LootTableProvider;
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets;
import java.util.List;
import java.util.Set;
public class ModLootTableProvider extends LootTableProvider {
public ModLootTableProvider(PackOutput output) {
super(output, Set.of(), List.of(
new SubProviderEntry(ModBlockLootProvider::new, LootContextParamSets.BLOCK)
));
}
}
@@ -30,5 +30,10 @@ public class PacketHandler {
.decoder(ClientboundSyncStatsPacket::new)
.consumerMainThread(ClientboundSyncStatsPacket::handle)
.add();
INSTANCE.registerMessage(id++, ServerboundShrineChoicePacket.class,
ServerboundShrineChoicePacket::toBytes,
ServerboundShrineChoicePacket::new,
ServerboundShrineChoicePacket::handle);
}
}
@@ -0,0 +1,48 @@
package net.fretux.ascend.network;
import net.fretux.ascend.player.PlayerStatsProvider;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.network.NetworkEvent;
import net.minecraftforge.network.PacketDistributor;
import java.util.function.Supplier;
public class ServerboundShrineChoicePacket {
private final String choice;
public ServerboundShrineChoicePacket(String choice) {
this.choice = choice;
}
public ServerboundShrineChoicePacket(FriendlyByteBuf buf) {
this.choice = buf.readUtf();
}
public void toBytes(FriendlyByteBuf buf) {
buf.writeUtf(choice);
}
public void handle(Supplier<NetworkEvent.Context> ctx) {
ctx.get().enqueueWork(() -> {
ServerPlayer player = ctx.get().getSender();
if (player == null) return;
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
if ("forget".equals(choice)) {
if (stats.getKnowledge() >= 15) {
stats.addKnowledge(-15);
stats.refundAllPoints();
player.sendSystemMessage(Component.literal("FOOLISH... YET HONEST."));
} else {
player.sendSystemMessage(Component.literal("YOUR MIND IS TOO EMPTY TO BE WORTH MY TOUCH."));
player.kill();
}
PlayerStatsProvider.sync(player);
}
});
});
ctx.get().setPacketHandled(true);
}
}
@@ -109,6 +109,16 @@ public class PlayerStats {
knowledge = Math.max(0, knowledge + amount);
}
public void refundAllPoints() {
int totalSpent = 0;
for (String key : attributes.keySet()) {
int lvl = attributes.get(key);
totalSpent += lvl;
attributes.put(key, 0);
}
unspentPoints += totalSpent;
}
public boolean hasUsedMoonseye() {
return hasUsedMoonseye;
}
@@ -0,0 +1,35 @@
package net.fretux.ascend.registry;
import net.fretux.ascend.AscendMod;
import net.fretux.ascend.block.ShrineOfRemembranceBlock;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.material.MapColor;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject;
public class ModBlocks {
public static final DeferredRegister<Block> BLOCKS =
DeferredRegister.create(ForgeRegistries.BLOCKS, AscendMod.MODID);
public static final RegistryObject<Block> SHRINE_OF_REMEMBRANCE = BLOCKS.register(
"shrine_of_remembrance",
() -> new ShrineOfRemembranceBlock(
BlockBehaviour.Properties.of()
.mapColor(MapColor.COLOR_PURPLE)
.strength(-1.0F, 3600000.0F) // unbreakable
.noLootTable()
.lightLevel(s -> 6)
.noOcclusion()
.requiresCorrectToolForDrops()
)
);
public static void register(IEventBus bus) {
BLOCKS.register(bus);
}
}
@@ -0,0 +1,55 @@
package net.fretux.ascend.worldgen;
import com.mojang.serialization.Codec;
import net.fretux.ascend.AscendMod;
import net.fretux.ascend.registry.ModBlocks;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.RegistrySetBuilder;
import net.minecraft.core.registries.Registries;
import net.minecraft.data.PackOutput;
import net.minecraft.data.worldgen.BootstapContext;
import net.minecraft.data.worldgen.placement.PlacementUtils;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.levelgen.GenerationStep;
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
import net.minecraft.world.level.levelgen.feature.Feature;
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
import net.minecraft.world.level.levelgen.placement.RarityFilter;
import net.minecraftforge.common.data.DatapackBuiltinEntriesProvider;
import net.minecraftforge.registries.ForgeRegistries;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
/**
* Generates structure and worldgen JSON entries for the Shrine of Remembrance.
*/
public class ModWorldGenProvider extends DatapackBuiltinEntriesProvider {
public static final ResourceKey<ConfiguredFeature<?, ?>> SHRINE_CONFIGURED =
ResourceKey.create(Registries.CONFIGURED_FEATURE, new ResourceLocation(AscendMod.MODID, "shrine_of_remembrance"));
public static final ResourceKey<PlacedFeature> SHRINE_PLACED =
ResourceKey.create(Registries.PLACED_FEATURE, new ResourceLocation(AscendMod.MODID, "shrine_of_remembrance"));
public ModWorldGenProvider(PackOutput output, CompletableFuture<HolderLookup.Provider> registries) {
super(output, registries, new RegistrySetBuilder()
.add(Registries.CONFIGURED_FEATURE, ModWorldGenProvider::bootstrapConfigured)
.add(Registries.PLACED_FEATURE, ModWorldGenProvider::bootstrapPlaced),
Set.of(AscendMod.MODID));
}
private static void bootstrapConfigured(BootstapContext<ConfiguredFeature<?, ?>> ctx) {
ctx.register(SHRINE_CONFIGURED,
new ConfiguredFeature<>(Feature.NO_OP, NoneFeatureConfiguration.INSTANCE));
}
private static void bootstrapPlaced(BootstapContext<PlacedFeature> ctx) {
var configured = ctx.lookup(Registries.CONFIGURED_FEATURE).getOrThrow(SHRINE_CONFIGURED);
ctx.register(SHRINE_PLACED,
new PlacedFeature(configured, List.of(
RarityFilter.onAverageOnceEvery(400) // roughly like mineshafts
)));
}
}
@@ -0,0 +1,376 @@
{
"format_version": "1.9.0",
"credit": "Made with Blockbench",
"textures": {
"0": "ascend:block/cavity",
"1": "ascend:block/eye",
"2": "ascend:block/luminous_abyss_rock",
"3": "ascend:block/orb",
"particle": "ascend:block/cavity"
},
"elements": [
{
"from": [-5, 1, 1],
"to": [-4, 15, 15],
"rotation": {"angle": -22.5, "axis": "z", "origin": [-6, 1, 0]},
"faces": {
"north": {"uv": [14.85714, 0, 16, 2], "texture": "#2"},
"east": {"uv": [0, 0, 16, 16], "texture": "#2"},
"south": {"uv": [0, 0, 1.14286, 2], "texture": "#2"},
"west": {"uv": [0, 0, 16, 16], "texture": "#2"},
"up": {"uv": [0, 0, 1.14286, 16], "texture": "#2"},
"down": {"uv": [0, 0, 1.14286, 16], "texture": "#2"}
}
},
{
"from": [1, 0, 1],
"to": [15, 14, 15],
"faces": {
"north": {"uv": [16, 0.25, 0, 16], "texture": "#2"},
"east": {"uv": [16, 0.25, 0, 16], "texture": "#2"},
"south": {"uv": [16, 0.25, 0, 16], "texture": "#2"},
"west": {"uv": [16, 0.25, 0, 16], "texture": "#2"},
"up": {"uv": [16, 0.25, 0, 16], "texture": "#2"},
"down": {"uv": [16, 0.25, 0, 16], "texture": "#2"}
}
},
{
"from": [1, 0, 9],
"to": [15, 5, 23],
"rotation": {"angle": 0, "axis": "y", "origin": [0, -9, 8]},
"faces": {
"north": {"uv": [16, 0.25, 0, 5.875], "texture": "#2"},
"east": {"uv": [16, 0.25, 0, 5.875], "texture": "#2"},
"south": {"uv": [16, 0.25, 0, 5.875], "texture": "#2"},
"west": {"uv": [16, 0.25, 0, 5.875], "texture": "#2"},
"up": {"uv": [16, 0.25, 0, 16], "texture": "#2"},
"down": {"uv": [16, 0.25, 0, 16], "texture": "#2"}
}
},
{
"from": [-5, -4, 15],
"to": [1, 10, 16],
"rotation": {"angle": -22.5, "axis": "z", "origin": [7, -2, 15]},
"faces": {
"north": {"uv": [0, 0, 6, 14], "texture": "#2"},
"east": {"uv": [0, 0, 6, 14], "texture": "#2"},
"south": {"uv": [0, 0, 6, 14], "texture": "#2"},
"west": {"uv": [0, 0, 6, 14], "texture": "#2"},
"up": {"uv": [0, 0, 6, 14], "texture": "#2"},
"down": {"uv": [0, 0, 6, 14], "texture": "#2"}
}
},
{
"from": [-5, -4, 0],
"to": [1, 10, 1],
"rotation": {"angle": -22.5, "axis": "z", "origin": [7, -2, 0]},
"faces": {
"north": {"uv": [8, 0, 14, 14], "texture": "#2"},
"east": {"uv": [0, 0, 1, 14], "texture": "#2"},
"south": {"uv": [0, 0, 6, 14], "texture": "#2"},
"west": {"uv": [0, 0, 1, 14], "texture": "#2"},
"up": {"uv": [0, 0, 6, 1], "texture": "#2"},
"down": {"uv": [0, 0, 6, 1], "texture": "#2"}
}
},
{
"from": [14, 2, 15],
"to": [20, 16, 16],
"rotation": {"angle": 22.5, "axis": "z", "origin": [26, 4, 15]},
"faces": {
"north": {"uv": [0, 0, 6, 14], "texture": "#2"},
"east": {"uv": [0, 0, 6, 14], "texture": "#2"},
"south": {"uv": [0, 0, 6, 14], "texture": "#2"},
"west": {"uv": [0, 0, 6, 14], "texture": "#2"},
"up": {"uv": [0, 0, 6, 14], "texture": "#2"},
"down": {"uv": [0, 0, 6, 14], "texture": "#2"}
}
},
{
"from": [20, -1, 1],
"to": [21, 14, 15],
"rotation": {"angle": 22.5, "axis": "z", "origin": [20, 0, 1]},
"faces": {
"north": {"uv": [0, 0, 14, 15], "texture": "#2"},
"east": {"uv": [0, 0, 14, 15], "texture": "#2"},
"south": {"uv": [0, 0, 15, 16], "texture": "#2"},
"west": {"uv": [0, 0, 14, 15], "texture": "#2"},
"up": {"uv": [0, 0, 14, 15], "texture": "#2"},
"down": {"uv": [0, 0, 14, 15], "texture": "#2"}
}
},
{
"from": [14, 2, 0],
"to": [20, 16, 1],
"rotation": {"angle": 22.5, "axis": "z", "origin": [26, 4, 0]},
"faces": {
"north": {"uv": [8, 0, 14, 14], "texture": "#2"},
"east": {"uv": [0, 0, 1, 14], "texture": "#2"},
"south": {"uv": [0, 0, 6, 14], "texture": "#2"},
"west": {"uv": [0, 0, 1, 14], "texture": "#2"},
"up": {"uv": [0, 0, 6, 1], "texture": "#2"},
"down": {"uv": [0, 0, 6, 1], "texture": "#2"}
}
},
{
"from": [1, 14, 1],
"to": [15, 26, 8],
"rotation": {"angle": 0, "axis": "y", "origin": [1, 14, 1]},
"faces": {
"north": {"uv": [0, 0, 14, 12], "texture": "#2"},
"east": {"uv": [7, 0, 14, 12], "texture": "#2"},
"south": {"uv": [0, 0, 14, 12], "texture": "#0"},
"west": {"uv": [0, 0, 7, 12], "texture": "#2"},
"up": {"uv": [0, 0, 14, 7], "texture": "#2"},
"down": {"uv": [0, 7, 14, 14], "texture": "#2"}
}
},
{
"from": [1, 14, 8],
"to": [10, 19, 15],
"rotation": {"angle": 0, "axis": "y", "origin": [1, 14, 1]},
"faces": {
"north": {"uv": [7, 0, 16, 5], "texture": "#2"},
"east": {"uv": [9, 10, 16, 15], "texture": "#2"},
"south": {"uv": [7, 5, 16, 10], "texture": "#2"},
"west": {"uv": [9, 11, 16, 16], "texture": "#2"},
"up": {"uv": [9, 7, 0, 0], "texture": "#0"},
"down": {"uv": [9, 7, 0, 14], "texture": "#2"}
}
},
{
"from": [1, 19, 8],
"to": [3, 22, 15],
"rotation": {"angle": 0, "axis": "y", "origin": [1, 14, 1]},
"faces": {
"north": {"uv": [12, 4, 14, 7], "texture": "#2"},
"east": {"uv": [0, 4, 7, 7], "texture": "#0"},
"south": {"uv": [0, 4, 2, 7], "texture": "#2"},
"west": {"uv": [7, 4, 14, 7], "texture": "#2"},
"up": {"uv": [0, 7, 2, 14], "texture": "#2"},
"down": {"uv": [0, 0, 2, 7], "texture": "#2"}
}
},
{
"from": [3, 19, 8],
"to": [7, 21, 15],
"rotation": {"angle": 0, "axis": "y", "origin": [1, 14, 1]},
"faces": {
"north": {"uv": [8, 5, 12, 7], "texture": "#2"},
"east": {"uv": [0, 5, 7, 7], "texture": "#0"},
"south": {"uv": [2, 5, 6, 7], "texture": "#2"},
"west": {"uv": [7, 5, 14, 7], "texture": "#2"},
"up": {"uv": [2, 7, 6, 14], "texture": "#0"},
"down": {"uv": [2, 0, 6, 7], "texture": "#2"}
}
},
{
"from": [1, 22, 8],
"to": [3, 26, 15],
"rotation": {"angle": 0, "axis": "y", "origin": [1, 14, 1]},
"faces": {
"north": {"uv": [12, 0, 14, 4], "texture": "#2"},
"east": {"uv": [0, 0, 7, 4], "texture": "#0"},
"south": {"uv": [0, 0, 2, 4], "texture": "#2"},
"west": {"uv": [7, 0, 14, 4], "texture": "#2"},
"up": {"uv": [0, 7, 2, 14], "texture": "#2"},
"down": {"uv": [0, 0, 2, 7], "texture": "#2"}
}
},
{
"from": [5, 22, 8],
"to": [10, 24, 15],
"rotation": {"angle": 0, "axis": "y", "origin": [1, 14, 1]},
"faces": {
"north": {"uv": [5, 2, 10, 4], "texture": "#2"},
"east": {"uv": [0, 2, 7, 4], "texture": "#2"},
"south": {"uv": [4, 2, 9, 4], "texture": "#2"},
"west": {"uv": [7, 2, 14, 4], "texture": "#0"},
"up": {"uv": [4, 7, 9, 14], "texture": "#2"},
"down": {"uv": [4, 0, 9, 7], "texture": "#0"}
}
},
{
"from": [3, 24, 8],
"to": [10, 26, 15],
"rotation": {"angle": 0, "axis": "y", "origin": [1, 14, 1]},
"faces": {
"north": {"uv": [5, 0, 12, 2], "texture": "#2"},
"east": {"uv": [0, 0, 7, 2], "texture": "#2"},
"south": {"uv": [2, 0, 9, 2], "texture": "#2"},
"west": {"uv": [7, 0, 14, 2], "texture": "#2"},
"up": {"uv": [2, 7, 9, 14], "texture": "#2"},
"down": {"uv": [2, 0, 9, 7], "texture": "#0"}
}
},
{
"from": [5, 21, 8],
"to": [7, 22, 15],
"rotation": {"angle": 0, "axis": "y", "origin": [1, 14, 1]},
"faces": {
"north": {"uv": [8, 4, 10, 5], "texture": "#2"},
"east": {"uv": [0, 4, 7, 5], "texture": "#0"},
"south": {"uv": [4, 4, 6, 5], "texture": "#2"},
"west": {"uv": [7, 4, 14, 5], "texture": "#0"},
"up": {"uv": [4, 7, 6, 14], "texture": "#2"},
"down": {"uv": [4, 0, 6, 7], "texture": "#2"}
}
},
{
"from": [10, 22, 8],
"to": [15, 26, 15],
"rotation": {"angle": 0, "axis": "y", "origin": [1, 14, 1]},
"faces": {
"north": {"uv": [0, 0, 5, 4], "texture": "#2"},
"east": {"uv": [0, 0, 7, 4], "texture": "#2"},
"south": {"uv": [9, 0, 14, 4], "texture": "#2"},
"west": {"uv": [7, 0, 14, 4], "texture": "#2"},
"up": {"uv": [9, 7, 14, 14], "texture": "#2"},
"down": {"uv": [9, 0, 14, 7], "texture": "#2"}
}
},
{
"from": [10, 14, 8],
"to": [11, 22, 15],
"rotation": {"angle": 0, "axis": "y", "origin": [1, 14, 1]},
"faces": {
"north": {"uv": [9, 4, 10, 12], "texture": "#2"},
"east": {"uv": [9, 4, 10, 12], "texture": "#0"},
"south": {"uv": [9, 4, 10, 12], "texture": "#2"},
"west": {"uv": [9, 4, 10, 12], "texture": "#0"},
"up": {"uv": [9, 4, 10, 12], "texture": "#2"},
"down": {"uv": [9, 4, 10, 12], "texture": "#2"}
}
},
{
"from": [11, 14, 8],
"to": [14, 16, 15],
"rotation": {"angle": 0, "axis": "y", "origin": [1, 14, 1]},
"faces": {
"north": {"uv": [1, 10, 4, 12], "texture": "#2"},
"east": {"uv": [0, 10, 7, 12], "texture": "#2"},
"south": {"uv": [10, 10, 13, 12], "texture": "#2"},
"west": {"uv": [7, 10, 14, 12], "texture": "#2"},
"up": {"uv": [10, 7, 13, 14], "texture": "#0"},
"down": {"uv": [10, 0, 13, 7], "texture": "#2"}
}
},
{
"from": [14, 14, 8],
"to": [15, 19, 15],
"rotation": {"angle": 0, "axis": "y", "origin": [1, 14, 1]},
"faces": {
"north": {"uv": [0, 7, 1, 12], "texture": "#2"},
"east": {"uv": [0, 7, 7, 12], "texture": "#2"},
"south": {"uv": [13, 7, 14, 12], "texture": "#2"},
"west": {"uv": [7, 7, 14, 12], "texture": "#0"},
"up": {"uv": [13, 7, 14, 14], "texture": "#2"},
"down": {"uv": [13, 0, 14, 7], "texture": "#2"}
}
},
{
"from": [11, 19, 8],
"to": [15, 22, 15],
"rotation": {"angle": 0, "axis": "y", "origin": [1, 14, 1]},
"faces": {
"north": {"uv": [0, 4, 4, 7], "texture": "#2"},
"east": {"uv": [0, 4, 7, 7], "texture": "#2"},
"south": {"uv": [10, 4, 14, 7], "texture": "#2"},
"west": {"uv": [7, 4, 14, 7], "texture": "#2"},
"up": {"uv": [10, 7, 14, 14], "texture": "#2"},
"down": {"uv": [10, 0, 14, 7], "texture": "#0"}
}
},
{
"from": [8, 20, 11],
"to": [9, 21, 12],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 20, 11]},
"faces": {
"north": {"uv": [2, 2, 0, 0], "texture": "#1"},
"east": {"uv": [2, 2, 0, 0], "texture": "#1"},
"south": {"uv": [2, 2, 0, 0], "texture": "#1"},
"west": {"uv": [2, 2, 0, 0], "texture": "#1"},
"up": {"uv": [2, 2, 0, 0], "texture": "#1"},
"down": {"uv": [2, 2, 0, 0], "texture": "#1"}
}
},
{
"from": [12, 17, 11],
"to": [13, 18, 12],
"rotation": {"angle": 0, "axis": "y", "origin": [12, 17, 11]},
"faces": {
"north": {"uv": [0, 0, 2, 2], "texture": "#1"},
"east": {"uv": [0, 0, 2, 2], "texture": "#1"},
"south": {"uv": [0, 0, 2, 2], "texture": "#1"},
"west": {"uv": [0, 0, 2, 2], "texture": "#1"},
"up": {"uv": [0, 0, 2, 2], "texture": "#1"},
"down": {"uv": [0, 0, 2, 2], "texture": "#1"}
}
},
{
"from": [3, 22, 11],
"to": [4, 23, 12],
"rotation": {"angle": 0, "axis": "y", "origin": [3, 22, 11]},
"faces": {
"north": {"uv": [0, 0, 2, 2], "texture": "#1"},
"east": {"uv": [0, 0, 2, 2], "texture": "#1"},
"south": {"uv": [0, 0, 2, 2], "texture": "#1"},
"west": {"uv": [0, 0, 2, 2], "texture": "#1"},
"up": {"uv": [0, 0, 2, 2], "texture": "#1"},
"down": {"uv": [0, 0, 2, 2], "texture": "#1"}
}
},
{
"from": [7, 10, 18],
"to": [9, 12, 20],
"rotation": {"angle": -45, "axis": "z", "origin": [7, 10, 18]},
"faces": {
"north": {"uv": [0, 0, 2, 2], "texture": "#3"},
"east": {"uv": [0, 2, 2, 4], "texture": "#3"},
"south": {"uv": [2, 0, 4, 2], "texture": "#3"},
"west": {"uv": [2, 2, 4, 4], "texture": "#3"},
"up": {"uv": [2, 6, 0, 4], "texture": "#3"},
"down": {"uv": [6, 0, 4, 2], "texture": "#3"}
}
}
],
"display": {
"thirdperson_righthand": {
"rotation": [75, 45, 0],
"translation": [0, 2.5, 0],
"scale": [0.375, 0.375, 0.375]
},
"thirdperson_lefthand": {
"rotation": [75, 45, 0],
"translation": [0, 2.5, 0],
"scale": [0.375, 0.375, 0.375]
},
"firstperson_righthand": {
"rotation": [0, 45, 0],
"scale": [0.4, 0.4, 0.4]
},
"firstperson_lefthand": {
"rotation": [0, -135, 0],
"scale": [0.4, 0.4, 0.4]
},
"ground": {
"translation": [0, 3, 0],
"scale": [0.25, 0.25, 0.25]
},
"gui": {
"rotation": [30, -135, 0],
"scale": [0.625, 0.625, 0.625]
},
"fixed": {
"scale": [0.5, 0.5, 0.5]
}
},
"groups": [
{
"name": "group",
"origin": [-6, 1, 0],
"color": 0,
"children": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]
}
]
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 106 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 869 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 B