diff --git a/.gitignore b/.gitignore index f3d7e9e..77de4b6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +### Minecraft +/src/generated/resources/.cache/* + ### Java template # Compiled class file *.class diff --git a/src/generated/resources/assets/firefly_bush_backport/blockstates/firefly_bush.json b/src/generated/resources/assets/firefly_bush_backport/blockstates/firefly_bush.json new file mode 100644 index 0000000..54c7074 --- /dev/null +++ b/src/generated/resources/assets/firefly_bush_backport/blockstates/firefly_bush.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "firefly_bush_backport:block/firefly_bush" + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/firefly_bush_backport/models/block/firefly_bush.json b/src/generated/resources/assets/firefly_bush_backport/models/block/firefly_bush.json new file mode 100644 index 0000000..253a2d4 --- /dev/null +++ b/src/generated/resources/assets/firefly_bush_backport/models/block/firefly_bush.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/cross_emissive", + "render_type": "minecraft:cutout", + "textures": { + "cross": "firefly_bush_backport:block/firefly_bush", + "cross_emissive": "firefly_bush_backport:block/firefly_bush_emissive" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/firefly_bush_backport/models/item/firefly_bush.json b/src/generated/resources/assets/firefly_bush_backport/models/item/firefly_bush.json new file mode 100644 index 0000000..124a962 --- /dev/null +++ b/src/generated/resources/assets/firefly_bush_backport/models/item/firefly_bush.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "firefly_bush_backport:item/firefly_bush" + } +} \ No newline at end of file diff --git a/src/main/java/dev/micle/firefly_bush_backport/block/FireflyBushBlock.java b/src/main/java/dev/micle/firefly_bush_backport/block/FireflyBushBlock.java new file mode 100644 index 0000000..3d1f952 --- /dev/null +++ b/src/main/java/dev/micle/firefly_bush_backport/block/FireflyBushBlock.java @@ -0,0 +1,64 @@ +package dev.micle.firefly_bush_backport.block; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.BonemealableBlock; +import net.minecraft.world.level.block.BushBlock; +import net.minecraft.world.level.block.state.BlockState; + +import java.util.List; +import java.util.Optional; + +public class FireflyBushBlock extends BushBlock implements BonemealableBlock { + private static final double FIREFLY_CHANCE_PER_TICK = 0.7; + private static final double FIREFLY_HORIZONTAL_RANGE = 10.0; + private static final double FIREFLY_VERTICAL_RANGE = 5.0; + private static final int FIREFLY_SPAWN_MAX_BRIGHTNESS_LEVEL = 13; + private static final int FIREFLY_AMBIENT_SOUND_CHANCE_ONE_IN = 30; + + public FireflyBushBlock(Properties pProperties) { + super(pProperties); + } + + @Override + public void animateTick(BlockState pState, Level pLevel, BlockPos pPos, RandomSource pRandom) { + super.animateTick(pState, pLevel, pPos, pRandom); + } + + @Override + public boolean isValidBonemealTarget(LevelReader pLevel, BlockPos pPos, BlockState pState, boolean pIsClient) { + return hasSpreadableNeighbourPos(pLevel, pPos, pState); + } + + @Override + public boolean isBonemealSuccess(Level pLevel, RandomSource pRandom, BlockPos pPos, BlockState pState) { + return true; + } + + @Override + public void performBonemeal(ServerLevel pLevel, RandomSource pRandom, BlockPos pPos, BlockState pState) { + findSpreadableNeighbourPos(pLevel, pPos, pState).ifPresent(x -> pLevel.setBlockAndUpdate(x, this.defaultBlockState())); + } + + static boolean hasSpreadableNeighbourPos(LevelReader levelReader, BlockPos blockPos, BlockState blockState) { + return getSpreadableNeighbourPos(Direction.Plane.HORIZONTAL.stream().toList(), levelReader, blockPos, blockState).isPresent(); + } + + static Optional findSpreadableNeighbourPos(Level level, BlockPos blockPos, BlockState blockState) { + return getSpreadableNeighbourPos(Direction.Plane.HORIZONTAL.shuffledCopy(level.random), level, blockPos, blockState); + } + + static Optional getSpreadableNeighbourPos(List directions, LevelReader levelReader, BlockPos blockPos, BlockState blockState) { + for (Direction direction : directions) { + BlockPos blockPosDirection = blockPos.relative(direction); + if (levelReader.isEmptyBlock(blockPosDirection) && blockState.canSurvive(levelReader, blockPosDirection)) { + return Optional.of(blockPosDirection); + } + } + return Optional.empty(); + } +} diff --git a/src/main/java/dev/micle/firefly_bush_backport/block/ModBlocks.java b/src/main/java/dev/micle/firefly_bush_backport/block/ModBlocks.java new file mode 100644 index 0000000..2ab4c4b --- /dev/null +++ b/src/main/java/dev/micle/firefly_bush_backport/block/ModBlocks.java @@ -0,0 +1,46 @@ +package dev.micle.firefly_bush_backport.block; + +import dev.micle.firefly_bush_backport.FireflyBushBackport; +import dev.micle.firefly_bush_backport.item.ModItems; +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.SoundType; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.material.MapColor; +import net.minecraft.world.level.material.PushReaction; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.RegistryObject; + +import java.util.function.Supplier; + +public class ModBlocks { + public static final DeferredRegister BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, FireflyBushBackport.MOD_ID); + + public static RegistryObject FIREFLY_BUSH = registerBlock("firefly_bush", + () -> new FireflyBushBlock(BlockBehaviour.Properties.of() + .mapColor(MapColor.PLANT) + .ignitedByLava() + .lightLevel(blockState -> 2) + .noCollission() + .instabreak() + .sound(SoundType.SWEET_BERRY_BUSH) + .pushReaction(PushReaction.DESTROY)) + ); + + public static void register(IEventBus modEventBus) { + BLOCKS.register(modEventBus); + } + + private static RegistryObject registerBlockItem(String name, RegistryObject block) { + return ModItems.ITEMS.register(name, () -> new BlockItem(block.get(), new Item.Properties())); + } + + private static RegistryObject registerBlock(String name, Supplier block) { + RegistryObject ret = BLOCKS.register(name, block); + registerBlockItem(name, ret); + return ret; + } +} diff --git a/src/main/java/dev/micle/firefly_bush_backport/creative_mode_tab/ModCreativeModeTabs.java b/src/main/java/dev/micle/firefly_bush_backport/creative_mode_tab/ModCreativeModeTabs.java new file mode 100644 index 0000000..0b126a0 --- /dev/null +++ b/src/main/java/dev/micle/firefly_bush_backport/creative_mode_tab/ModCreativeModeTabs.java @@ -0,0 +1,28 @@ +package dev.micle.firefly_bush_backport.creative_mode_tab; + +import dev.micle.firefly_bush_backport.FireflyBushBackport; +import dev.micle.firefly_bush_backport.block.ModBlocks; +import net.minecraft.core.registries.Registries; +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.CreativeModeTab; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.RegistryObject; + +public class ModCreativeModeTabs { + public static final DeferredRegister CREATIVE_MODE_TABS = DeferredRegister.create(Registries.CREATIVE_MODE_TAB, FireflyBushBackport.MOD_ID); + + public static final RegistryObject MAIN_TAB = CREATIVE_MODE_TABS.register( "main", + () -> CreativeModeTab.builder() + .title(Component.translatable(String.format("itemGroup.%s.main", FireflyBushBackport.MOD_ID))) + .icon(ModBlocks.FIREFLY_BUSH.get().asItem()::getDefaultInstance) + .displayItems((itemDisplayParams, output) -> { + output.accept(ModBlocks.FIREFLY_BUSH.get()); + }) + .build() + ); + + public static void register(IEventBus modEventBus) { + CREATIVE_MODE_TABS.register(modEventBus); + } +} diff --git a/src/main/java/dev/micle/firefly_bush_backport/data/DataGenerators.java b/src/main/java/dev/micle/firefly_bush_backport/data/DataGenerators.java new file mode 100644 index 0000000..18c0024 --- /dev/null +++ b/src/main/java/dev/micle/firefly_bush_backport/data/DataGenerators.java @@ -0,0 +1,22 @@ +package dev.micle.firefly_bush_backport.data; + +import dev.micle.firefly_bush_backport.FireflyBushBackport; +import dev.micle.firefly_bush_backport.data.client.ModBlockStateProvider; +import dev.micle.firefly_bush_backport.data.client.ModItemModelProvider; +import net.minecraft.data.DataGenerator; +import net.minecraftforge.common.data.ExistingFileHelper; +import net.minecraftforge.data.event.GatherDataEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; + +@Mod.EventBusSubscriber(modid = FireflyBushBackport.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD) +public class DataGenerators { + @SubscribeEvent + public static void gatherData(GatherDataEvent event) { + DataGenerator generator = event.getGenerator(); + ExistingFileHelper existingFileHelper = event.getExistingFileHelper(); + + generator.addProvider(event.includeServer(), new ModBlockStateProvider(generator, existingFileHelper)); + generator.addProvider(event.includeServer(), new ModItemModelProvider(generator, existingFileHelper)); + } +} diff --git a/src/main/java/dev/micle/firefly_bush_backport/data/client/ModBlockStateProvider.java b/src/main/java/dev/micle/firefly_bush_backport/data/client/ModBlockStateProvider.java new file mode 100644 index 0000000..f0c2a38 --- /dev/null +++ b/src/main/java/dev/micle/firefly_bush_backport/data/client/ModBlockStateProvider.java @@ -0,0 +1,32 @@ +package dev.micle.firefly_bush_backport.data.client; + +import dev.micle.firefly_bush_backport.FireflyBushBackport; +import dev.micle.firefly_bush_backport.block.ModBlocks; +import net.minecraft.data.DataGenerator; +import net.minecraft.world.level.block.Block; +import net.minecraftforge.client.model.generators.BlockStateProvider; +import net.minecraftforge.common.data.ExistingFileHelper; +import net.minecraftforge.registries.RegistryObject; + +import java.util.Objects; + +public class ModBlockStateProvider extends BlockStateProvider { + public ModBlockStateProvider(DataGenerator generator, ExistingFileHelper existingFileHelper) { + super(generator.getPackOutput(), FireflyBushBackport.MOD_ID, existingFileHelper); + } + + @Override + protected void registerStatesAndModels() { + crossEmissiveBlock(ModBlocks.FIREFLY_BUSH); + } + + private void crossEmissiveBlock(RegistryObject block) { + String name = Objects.requireNonNull(block.getId()).getPath(); + simpleBlock(block.get(), models() + .withExistingParent(name, "block/cross_emissive") + .texture("cross", "block/" + name) + .texture("cross_emissive", "block/" + name + "_emissive") + .renderType("cutout") + ); + } +} diff --git a/src/main/java/dev/micle/firefly_bush_backport/data/client/ModItemModelProvider.java b/src/main/java/dev/micle/firefly_bush_backport/data/client/ModItemModelProvider.java new file mode 100644 index 0000000..2277e06 --- /dev/null +++ b/src/main/java/dev/micle/firefly_bush_backport/data/client/ModItemModelProvider.java @@ -0,0 +1,40 @@ +package dev.micle.firefly_bush_backport.data.client; + +import dev.micle.firefly_bush_backport.FireflyBushBackport; +import dev.micle.firefly_bush_backport.block.ModBlocks; +import net.minecraft.data.DataGenerator; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.block.Block; +import net.minecraftforge.client.model.generators.ItemModelBuilder; +import net.minecraftforge.client.model.generators.ItemModelProvider; +import net.minecraftforge.client.model.generators.ModelFile; +import net.minecraftforge.common.data.ExistingFileHelper; +import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.RegistryObject; + +import java.util.Objects; + +public class ModItemModelProvider extends ItemModelProvider { + public ModItemModelProvider(DataGenerator generator, ExistingFileHelper existingFileHelper) { + super(generator.getPackOutput(), FireflyBushBackport.MOD_ID, existingFileHelper); + } + + @Override + protected void registerModels() { + ModBlocks.BLOCKS.getEntries().stream().map(RegistryObject::get).forEach(this::blockItemModel); + } + + private void blockItemModel(Block block) { + String name = Objects.requireNonNull(ForgeRegistries.BLOCKS.getKey(block)).getPath(); + + if (block == ModBlocks.FIREFLY_BUSH.get()) { + builder(getExistingFile(mcLoc("item/generated")), name); + } else if (block.asItem() != Items.AIR) { + withExistingParent(name, modLoc("block/" + name)); + } + } + + private ItemModelBuilder builder(ModelFile itemGenerated, String name) { + return getBuilder(name).parent(itemGenerated).texture("layer0", "item/" + name); + } +} diff --git a/src/main/java/dev/micle/firefly_bush_backport/item/ModItems.java b/src/main/java/dev/micle/firefly_bush_backport/item/ModItems.java new file mode 100644 index 0000000..2904912 --- /dev/null +++ b/src/main/java/dev/micle/firefly_bush_backport/item/ModItems.java @@ -0,0 +1,15 @@ +package dev.micle.firefly_bush_backport.item; + +import dev.micle.firefly_bush_backport.FireflyBushBackport; +import net.minecraft.world.item.Item; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; + +public class ModItems { + public static final DeferredRegister ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, FireflyBushBackport.MOD_ID); + + public static void register(IEventBus modEventBus) { + ITEMS.register(modEventBus); + } +} diff --git a/src/main/java/dev/micle/firefly_bush_backport/proxy/Proxy.java b/src/main/java/dev/micle/firefly_bush_backport/proxy/Proxy.java index 1c05c97..23ab063 100644 --- a/src/main/java/dev/micle/firefly_bush_backport/proxy/Proxy.java +++ b/src/main/java/dev/micle/firefly_bush_backport/proxy/Proxy.java @@ -1,7 +1,10 @@ package dev.micle.firefly_bush_backport.proxy; import dev.micle.firefly_bush_backport.FireflyBushBackport; +import dev.micle.firefly_bush_backport.block.ModBlocks; import dev.micle.firefly_bush_backport.config.Config; +import dev.micle.firefly_bush_backport.creative_mode_tab.ModCreativeModeTabs; +import dev.micle.firefly_bush_backport.item.ModItems; import net.minecraft.client.Minecraft; import net.minecraft.server.MinecraftServer; import net.minecraft.world.entity.player.Player; @@ -20,10 +23,14 @@ public class Proxy implements IProxy { // Common setup public Proxy() { + IEventBus modEventBus = FireflyBushBackport.getFMLJavaModLoadingContext().getModEventBus(); + Config.register(); + ModBlocks.register(modEventBus); + ModItems.register(modEventBus); + ModCreativeModeTabs.register(modEventBus); // Register mod event bus listeners - IEventBus modEventBus = FireflyBushBackport.getFMLJavaModLoadingContext().getModEventBus(); modEventBus.addListener(Proxy::setup); modEventBus.addListener(Proxy::imcEnqueue); modEventBus.addListener(Proxy::imcProcess); diff --git a/src/main/resources/assets/firefly_bush_backport/lang/en_us.json b/src/main/resources/assets/firefly_bush_backport/lang/en_us.json new file mode 100644 index 0000000..33d8437 --- /dev/null +++ b/src/main/resources/assets/firefly_bush_backport/lang/en_us.json @@ -0,0 +1,4 @@ +{ + "itemGroup.firefly_bush_backport.main": "Firefly Bush Backport", + "block.firefly_bush_backport.firefly_bush": "Firefly Bush" +} \ No newline at end of file diff --git a/src/main/resources/assets/firefly_bush_backport/sounds/block/firefly_bush/firefly_bush1.ogg b/src/main/resources/assets/firefly_bush_backport/sounds/block/firefly_bush/firefly_bush1.ogg new file mode 100644 index 0000000..7864296 Binary files /dev/null and b/src/main/resources/assets/firefly_bush_backport/sounds/block/firefly_bush/firefly_bush1.ogg differ diff --git a/src/main/resources/assets/firefly_bush_backport/sounds/block/firefly_bush/firefly_bush10.ogg b/src/main/resources/assets/firefly_bush_backport/sounds/block/firefly_bush/firefly_bush10.ogg new file mode 100644 index 0000000..ecb4aa9 Binary files /dev/null and b/src/main/resources/assets/firefly_bush_backport/sounds/block/firefly_bush/firefly_bush10.ogg differ diff --git a/src/main/resources/assets/firefly_bush_backport/sounds/block/firefly_bush/firefly_bush11.ogg b/src/main/resources/assets/firefly_bush_backport/sounds/block/firefly_bush/firefly_bush11.ogg new file mode 100644 index 0000000..acf00ef Binary files /dev/null and b/src/main/resources/assets/firefly_bush_backport/sounds/block/firefly_bush/firefly_bush11.ogg differ diff --git a/src/main/resources/assets/firefly_bush_backport/sounds/block/firefly_bush/firefly_bush2.ogg b/src/main/resources/assets/firefly_bush_backport/sounds/block/firefly_bush/firefly_bush2.ogg new file mode 100644 index 0000000..d2ffa07 Binary files /dev/null and b/src/main/resources/assets/firefly_bush_backport/sounds/block/firefly_bush/firefly_bush2.ogg differ diff --git a/src/main/resources/assets/firefly_bush_backport/sounds/block/firefly_bush/firefly_bush3.ogg b/src/main/resources/assets/firefly_bush_backport/sounds/block/firefly_bush/firefly_bush3.ogg new file mode 100644 index 0000000..ac3fc89 Binary files /dev/null and b/src/main/resources/assets/firefly_bush_backport/sounds/block/firefly_bush/firefly_bush3.ogg differ diff --git a/src/main/resources/assets/firefly_bush_backport/sounds/block/firefly_bush/firefly_bush4.ogg b/src/main/resources/assets/firefly_bush_backport/sounds/block/firefly_bush/firefly_bush4.ogg new file mode 100644 index 0000000..3d8a94c Binary files /dev/null and b/src/main/resources/assets/firefly_bush_backport/sounds/block/firefly_bush/firefly_bush4.ogg differ diff --git a/src/main/resources/assets/firefly_bush_backport/sounds/block/firefly_bush/firefly_bush5.ogg b/src/main/resources/assets/firefly_bush_backport/sounds/block/firefly_bush/firefly_bush5.ogg new file mode 100644 index 0000000..2514cba Binary files /dev/null and b/src/main/resources/assets/firefly_bush_backport/sounds/block/firefly_bush/firefly_bush5.ogg differ diff --git a/src/main/resources/assets/firefly_bush_backport/sounds/block/firefly_bush/firefly_bush6.ogg b/src/main/resources/assets/firefly_bush_backport/sounds/block/firefly_bush/firefly_bush6.ogg new file mode 100644 index 0000000..19a5e7b Binary files /dev/null and b/src/main/resources/assets/firefly_bush_backport/sounds/block/firefly_bush/firefly_bush6.ogg differ diff --git a/src/main/resources/assets/firefly_bush_backport/sounds/block/firefly_bush/firefly_bush7.ogg b/src/main/resources/assets/firefly_bush_backport/sounds/block/firefly_bush/firefly_bush7.ogg new file mode 100644 index 0000000..515ca29 Binary files /dev/null and b/src/main/resources/assets/firefly_bush_backport/sounds/block/firefly_bush/firefly_bush7.ogg differ diff --git a/src/main/resources/assets/firefly_bush_backport/sounds/block/firefly_bush/firefly_bush8.ogg b/src/main/resources/assets/firefly_bush_backport/sounds/block/firefly_bush/firefly_bush8.ogg new file mode 100644 index 0000000..e1ca3b1 Binary files /dev/null and b/src/main/resources/assets/firefly_bush_backport/sounds/block/firefly_bush/firefly_bush8.ogg differ diff --git a/src/main/resources/assets/firefly_bush_backport/sounds/block/firefly_bush/firefly_bush9.ogg b/src/main/resources/assets/firefly_bush_backport/sounds/block/firefly_bush/firefly_bush9.ogg new file mode 100644 index 0000000..ed35ad0 Binary files /dev/null and b/src/main/resources/assets/firefly_bush_backport/sounds/block/firefly_bush/firefly_bush9.ogg differ diff --git a/src/main/resources/assets/firefly_bush_backport/textures/block/firefly_bush.png b/src/main/resources/assets/firefly_bush_backport/textures/block/firefly_bush.png new file mode 100644 index 0000000..e08a032 Binary files /dev/null and b/src/main/resources/assets/firefly_bush_backport/textures/block/firefly_bush.png differ diff --git a/src/main/resources/assets/firefly_bush_backport/textures/block/firefly_bush_emissive.png b/src/main/resources/assets/firefly_bush_backport/textures/block/firefly_bush_emissive.png new file mode 100644 index 0000000..fd4011d Binary files /dev/null and b/src/main/resources/assets/firefly_bush_backport/textures/block/firefly_bush_emissive.png differ diff --git a/src/main/resources/assets/firefly_bush_backport/textures/block/firefly_bush_emissive.png.mcmeta b/src/main/resources/assets/firefly_bush_backport/textures/block/firefly_bush_emissive.png.mcmeta new file mode 100644 index 0000000..8e55e43 --- /dev/null +++ b/src/main/resources/assets/firefly_bush_backport/textures/block/firefly_bush_emissive.png.mcmeta @@ -0,0 +1,5 @@ +{ + "animation": { + "frametime": 3 + } +} diff --git a/src/main/resources/assets/firefly_bush_backport/textures/item/firefly_bush.png b/src/main/resources/assets/firefly_bush_backport/textures/item/firefly_bush.png new file mode 100644 index 0000000..eaad03a Binary files /dev/null and b/src/main/resources/assets/firefly_bush_backport/textures/item/firefly_bush.png differ diff --git a/src/main/resources/assets/minecraft/models/block/cross_emissive.json b/src/main/resources/assets/minecraft/models/block/cross_emissive.json new file mode 100644 index 0000000..5882091 --- /dev/null +++ b/src/main/resources/assets/minecraft/models/block/cross_emissive.json @@ -0,0 +1,46 @@ +{ + "ambientocclusion": false, + "textures": { + "particle": "#cross" + }, + "elements": [ + { "from": [ 0.8, 0, 8 ], + "to": [ 15.2, 16, 8 ], + "rotation": { "origin": [ 8, 8, 8 ], "axis": "y", "angle": 45, "rescale": true }, + "shade": false, + "faces": { + "north": { "uv": [ 0, 0, 16, 16 ], "texture": "#cross" }, + "south": { "uv": [ 0, 0, 16, 16 ], "texture": "#cross" } + } + }, + { "from": [ 8, 0, 0.8 ], + "to": [ 8, 16, 15.2 ], + "rotation": { "origin": [ 8, 8, 8 ], "axis": "y", "angle": 45, "rescale": true }, + "shade": false, + "faces": { + "west": { "uv": [ 0, 0, 16, 16 ], "texture": "#cross" }, + "east": { "uv": [ 0, 0, 16, 16 ], "texture": "#cross" } + } + }, + { "from": [ 0.8, 0, 8 ], + "to": [ 15.2, 16, 8 ], + "rotation": { "origin": [ 8, 8, 8 ], "axis": "y", "angle": 45, "rescale": true }, + "shade": false, + "light_emission": 15, + "faces": { + "north": { "uv": [ 0, 0, 16, 16 ], "texture": "#cross_emissive" }, + "south": { "uv": [ 0, 0, 16, 16 ], "texture": "#cross_emissive" } + } + }, + { "from": [ 8, 0, 0.8 ], + "to": [ 8, 16, 15.2 ], + "rotation": { "origin": [ 8, 8, 8 ], "axis": "y", "angle": 45, "rescale": true }, + "shade": false, + "light_emission": 15, + "faces": { + "west": { "uv": [ 0, 0, 16, 16 ], "texture": "#cross_emissive" }, + "east": { "uv": [ 0, 0, 16, 16 ], "texture": "#cross_emissive" } + } + } + ] +}