Compare commits
89 commits
Author | SHA1 | Date | |
---|---|---|---|
|
7d01f14808 | ||
|
67c4decf8e | ||
|
70b109758d | ||
|
befdd2c10a | ||
|
e7841b1b27 | ||
|
447a199379 | ||
|
b54b14782e | ||
|
1d64b215f4 | ||
|
622f611624 | ||
|
3725ed9367 | ||
|
ad40784871 | ||
|
51aa7b5aff | ||
|
64c27a10b7 | ||
|
bdab309726 | ||
|
72e7be7ace | ||
|
ec4b105f09 | ||
|
5340a50f0c | ||
|
3313663a3f | ||
|
9a378bb69c | ||
|
5512ece14e | ||
|
986dc2c7a0 | ||
|
307486a32c | ||
|
3c5661aed9 | ||
|
cf2e0e012d | ||
|
a39989b331 | ||
|
3143de77c3 | ||
|
947b790138 | ||
|
02068df82d | ||
|
7d79452220 | ||
|
dccb49f51c | ||
|
d7b82c3a17 | ||
|
0a29192bfe | ||
|
e60f8f7d9d | ||
|
ce4f3f329d | ||
|
8db49ab4f1 | ||
|
a37f1275c5 | ||
|
d3fbb660a7 | ||
|
e536edfccf | ||
|
425458f0bd | ||
|
2686089835 | ||
|
508ae317fe | ||
|
553afd872a | ||
|
6e601179c5 | ||
|
849b28f7d3 | ||
|
cbc91f4523 | ||
|
570e65ca47 | ||
|
417156fd55 | ||
|
42feb6d4b8 | ||
|
b53d513dec | ||
|
52750fdffa | ||
|
c39d11e3dd | ||
|
ef0bbcbf58 | ||
|
429fe90cb7 | ||
|
f4a036b1e7 | ||
|
2b38d1ca6b | ||
|
3a2b837be3 | ||
|
52777aca89 | ||
|
93094e0390 | ||
|
74196a9894 | ||
|
c6a527714e | ||
|
5cef3a03eb | ||
|
e0a9d21d59 | ||
|
29e6e5edbf | ||
|
f650f22648 | ||
|
8a31310a75 | ||
|
dcc6229769 | ||
|
72b1b237f2 | ||
|
da1c27a14d | ||
|
809e913683 | ||
|
9b0303f1d7 | ||
|
0dca63cfcc | ||
|
cc1df4a290 | ||
|
72e14a5e53 | ||
|
0f012d0886 | ||
|
a2a3671d20 | ||
|
1a5f57968d | ||
|
25b1ce5e67 | ||
|
c91d788dfe | ||
|
25fbadba6a | ||
|
1e20595ab5 | ||
|
cfaf8263d6 | ||
|
6e882d08d9 | ||
|
6487efb3de | ||
|
0d63530136 | ||
|
c6bb88fdc8 | ||
|
5a08b23fb2 | ||
|
4ff79c2b60 | ||
|
4230fb7e6c | ||
|
4427700b7a |
123 changed files with 2697 additions and 1472 deletions
15
README.md
15
README.md
|
@ -1,26 +1,33 @@
|
|||
[](https://jitpack.io/#paulevsGitch/BCLib)
|
||||
# BCLib
|
||||
BCLib is a library mod for BetterX team mods, developed for Fabric, MC 1.16.4+
|
||||
BCLib is a library mod for BetterX team mods, developed for Fabric, MC 1.16.5
|
||||
|
||||
## Features:
|
||||
### API:
|
||||
* Simple Mod Integration API;
|
||||
* Structure Features API;
|
||||
* World Data API;
|
||||
* Bonemeal API;
|
||||
* Features API;
|
||||
* Biome API;
|
||||
* Tag API;
|
||||
* Tag API.
|
||||
|
||||
### Libs:
|
||||
* Spline library (simple);
|
||||
* Recipe manager;
|
||||
* Noise library;
|
||||
* Math library;
|
||||
* SDF library;
|
||||
* SDF library.
|
||||
|
||||
### Helpers And Utils:
|
||||
* Custom surface builders;
|
||||
* Translation helper;
|
||||
* Weighted list;
|
||||
* Block helper;
|
||||
* Block helper.
|
||||
|
||||
### Rendering:
|
||||
* Procedural block models (from paterns or from code);
|
||||
* Block render layer interface.
|
||||
|
||||
## Importing:
|
||||
* Clone repo
|
||||
|
|
BIN
bclib_banner.png
Normal file
BIN
bclib_banner.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 35 KiB |
13
build.gradle
13
build.gradle
|
@ -7,12 +7,12 @@ buildscript {
|
|||
plugins {
|
||||
id 'idea'
|
||||
id 'eclipse'
|
||||
id 'fabric-loom' version '0.7-SNAPSHOT'
|
||||
id 'fabric-loom' version '0.8-SNAPSHOT'
|
||||
id 'maven-publish'
|
||||
}
|
||||
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
sourceCompatibility = JavaVersion.VERSION_16
|
||||
targetCompatibility = JavaVersion.VERSION_16
|
||||
|
||||
archivesBaseName = project.archives_base_name
|
||||
version = project.mod_version
|
||||
|
@ -20,7 +20,7 @@ group = project.maven_group
|
|||
|
||||
repositories {
|
||||
maven { url "https://maven.dblsaiko.net/" }
|
||||
maven { url "http://server.bbkr.space:8081/artifactory/libs-release/" }
|
||||
maven { url "https://server.bbkr.space:8081/artifactory/libs-release/" }
|
||||
maven { url "https://maven.fabricmc.net/" }
|
||||
maven { url 'https://maven.blamejared.com' }
|
||||
maven { url "https://maven.shedaniel.me/" }
|
||||
|
@ -33,7 +33,7 @@ dependencies {
|
|||
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
||||
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
||||
|
||||
useApi "vazkii.patchouli:Patchouli:1.16.4-${project.patchouli_version}"
|
||||
//useApi "vazkii.patchouli:Patchouli:1.16.4-${project.patchouli_version}"
|
||||
}
|
||||
|
||||
def useOptional(String dep) {
|
||||
|
@ -65,6 +65,7 @@ def useApi(String dep) {
|
|||
|
||||
processResources {
|
||||
inputs.property "version", project.version
|
||||
duplicatesStrategy = 'EXCLUDE'
|
||||
|
||||
from(sourceSets.main.resources.srcDirs) {
|
||||
include "fabric.mod.json"
|
||||
|
@ -114,7 +115,7 @@ def env = System.getenv()
|
|||
import org.kohsuke.github.GHReleaseBuilder
|
||||
import org.kohsuke.github.GitHub
|
||||
|
||||
task github(dependsOn: [remapJar, sourcesJar, javadocJar]) {
|
||||
task release(dependsOn: [remapJar, sourcesJar, javadocJar]) {
|
||||
onlyIf {
|
||||
env.GITHUB_TOKEN
|
||||
}
|
||||
|
|
|
@ -3,16 +3,16 @@ org.gradle.jvmargs=-Xmx2G
|
|||
|
||||
# Fabric Properties
|
||||
# check these on https://fabricmc.net/use
|
||||
minecraft_version=1.16.5
|
||||
yarn_mappings=6
|
||||
loader_version=0.11.3
|
||||
minecraft_version= 1.17
|
||||
yarn_mappings= 6
|
||||
loader_version= 0.11.6
|
||||
|
||||
# Mod Properties
|
||||
mod_version = 0.1.15
|
||||
mod_version = 0.2.0
|
||||
maven_group = ru.bclib
|
||||
archives_base_name = bclib
|
||||
|
||||
# Dependencies
|
||||
# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api
|
||||
patchouli_version = 50-FABRIC
|
||||
fabric_version = 0.32.9+1.16
|
||||
fabric_version = 0.36.0+1.17
|
||||
|
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,5 +1,5 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
|
|
@ -5,6 +5,8 @@ import net.fabricmc.api.ModInitializer;
|
|||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import ru.bclib.api.TagAPI;
|
||||
import ru.bclib.config.Configs;
|
||||
import ru.bclib.recipes.CraftingRecipes;
|
||||
import ru.bclib.registry.BaseBlockEntities;
|
||||
import ru.bclib.registry.BaseRegistry;
|
||||
import ru.bclib.util.Logger;
|
||||
|
@ -20,6 +22,8 @@ public class BCLib implements ModInitializer {
|
|||
BaseBlockEntities.register();
|
||||
BCLSurfaceBuilders.register();
|
||||
TagAPI.init();
|
||||
CraftingRecipes.init();
|
||||
Configs.save();
|
||||
}
|
||||
|
||||
public static boolean isDevEnvironment() {
|
||||
|
|
|
@ -25,7 +25,7 @@ public class BiomeAPI {
|
|||
* Empty biome used as default value if requested biome doesn't exist or linked. Shouldn't be registered anywhere to prevent bugs.
|
||||
* Have {@code Biomes.THE_VOID} as the reference biome.
|
||||
*/
|
||||
public static final BCLBiome EMPTY_BIOME = new BCLBiome(Biomes.THE_VOID.location(), BuiltinRegistries.BIOME.get(Biomes.THE_VOID), 0, 0);
|
||||
public static final BCLBiome EMPTY_BIOME = new BCLBiome(Biomes.THE_VOID.location(), BuiltinRegistries.BIOME.get(Biomes.THE_VOID), 1, 0);
|
||||
|
||||
private static final HashMap<ResourceLocation, BCLBiome> ID_MAP = Maps.newHashMap();
|
||||
private static final HashMap<Biome, BCLBiome> CLIENT = Maps.newHashMap();
|
||||
|
@ -37,10 +37,14 @@ public class BiomeAPI {
|
|||
*/
|
||||
public static void initRegistry(MinecraftServer server) {
|
||||
biomeRegistry = server.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY);
|
||||
CLIENT.clear();
|
||||
}
|
||||
|
||||
public static void registerBiomeDirectly(BCLBiome biome) {
|
||||
Registry.register(BuiltinRegistries.BIOME, biome.getID(), biome.getBiome());
|
||||
public static void registerBiome(BCLBiome biome) {
|
||||
if (BuiltinRegistries.BIOME.get(biome.getID()) == null) {
|
||||
Registry.register(BuiltinRegistries.BIOME, biome.getID(), biome.getBiome());
|
||||
}
|
||||
ID_MAP.put(biome.getID(), biome);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -87,6 +91,9 @@ public class BiomeAPI {
|
|||
* @return {@link BCLBiome} or {@code BiomeAPI.EMPTY_BIOME}.
|
||||
*/
|
||||
public static BCLBiome getFromBiome(Biome biome) {
|
||||
if (biomeRegistry == null) {
|
||||
return EMPTY_BIOME;
|
||||
}
|
||||
return ID_MAP.getOrDefault(biomeRegistry.getKey(biome), EMPTY_BIOME);
|
||||
}
|
||||
|
||||
|
@ -143,7 +150,7 @@ public class BiomeAPI {
|
|||
/**
|
||||
* Check if biome with {@link ResourceLocation} exists in API registry.
|
||||
* @param biomeID - biome {@link ResourceLocation}.
|
||||
* @return
|
||||
* @return {@code true} if biome exists in API registry and {@code false} if not.
|
||||
*/
|
||||
public static boolean hasBiome(ResourceLocation biomeID) {
|
||||
return ID_MAP.containsKey(biomeID);
|
||||
|
|
|
@ -24,6 +24,7 @@ public class DataFixerAPI {
|
|||
private static final Map<String, Integer> FIX_VERSIONS = Maps.newHashMap();
|
||||
|
||||
public static void fixData(File dir) {
|
||||
REPLACEMENT.clear(); // API is not finished yet!
|
||||
if (REPLACEMENT.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
@ -32,9 +33,11 @@ public class DataFixerAPI {
|
|||
Collection<ModContainer> mods = FabricLoader.getInstance().getAllMods();
|
||||
for (ModContainer mod: mods) {
|
||||
String name = mod.getMetadata().getId();
|
||||
int preVersion = WorldDataAPI.getIntModVersion(name);
|
||||
int version = getModVersion(mod.getMetadata().getVersion().toString());
|
||||
if (version > 0) {
|
||||
shoudFix |= FIX_VERSIONS.getOrDefault(name, version) < version;
|
||||
if (version > preVersion) {
|
||||
int fixVersion = FIX_VERSIONS.getOrDefault(name, version);
|
||||
shoudFix |= fixVersion < version && fixVersion >= preVersion;
|
||||
}
|
||||
};
|
||||
if (!shoudFix) {
|
||||
|
@ -117,7 +120,7 @@ public class DataFixerAPI {
|
|||
/**
|
||||
* Get mod version from string. String should be in format: %d.%d.%d
|
||||
* @param version - {@link String} mod version.
|
||||
* @return
|
||||
* @return int mod version.
|
||||
*/
|
||||
public static int getModVersion(String version) {
|
||||
if (version.isEmpty()) {
|
||||
|
@ -134,8 +137,8 @@ public class DataFixerAPI {
|
|||
|
||||
/**
|
||||
* Get mod version from integer. String will be in format %d.%d.%d
|
||||
* @param version
|
||||
* @return
|
||||
* @param version - mod version in integer form.
|
||||
* @return {@link String} mod version.
|
||||
*/
|
||||
public static String getModVersion(int version) {
|
||||
int a = (version >> 12) & 63;
|
||||
|
|
40
src/main/java/ru/bclib/api/ModIntegrationAPI.java
Normal file
40
src/main/java/ru/bclib/api/ModIntegrationAPI.java
Normal file
|
@ -0,0 +1,40 @@
|
|||
package ru.bclib.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import ru.bclib.integration.ModIntegration;
|
||||
|
||||
public class ModIntegrationAPI {
|
||||
private static final List<ModIntegration> INTEGRATIONS = Lists.newArrayList();
|
||||
|
||||
/**
|
||||
* Registers mod integration
|
||||
* @param integration
|
||||
* @return
|
||||
*/
|
||||
public static ModIntegration register(ModIntegration integration) {
|
||||
INTEGRATIONS.add(integration);
|
||||
return integration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all registered mod integrations.
|
||||
* @return {@link List} of {@link ModIntegration}.
|
||||
*/
|
||||
public static List<ModIntegration> getIntegrations() {
|
||||
return INTEGRATIONS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize all integrations, only for internal usage.
|
||||
*/
|
||||
public static void registerAll() {
|
||||
INTEGRATIONS.forEach(integration -> {
|
||||
if (integration.modIsInstalled()) {
|
||||
integration.init();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -4,10 +4,13 @@ import java.io.File;
|
|||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.fabricmc.loader.api.ModContainer;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtIo;
|
||||
import ru.bclib.BCLib;
|
||||
|
@ -20,8 +23,9 @@ public class WorldDataAPI {
|
|||
public static void load(File dataDir) {
|
||||
WorldDataAPI.dataDir = dataDir;
|
||||
MODS.stream().parallel().forEach(modID -> {
|
||||
File file = new File(dataDir, modID);
|
||||
File file = new File(dataDir, modID + ".nbt");
|
||||
CompoundTag root = new CompoundTag();
|
||||
TAGS.put(modID, root);
|
||||
if (file.exists()) {
|
||||
try {
|
||||
root = NbtIo.readCompressed(file);
|
||||
|
@ -30,7 +34,19 @@ public class WorldDataAPI {
|
|||
BCLib.LOGGER.error("World data loading failed", e);
|
||||
}
|
||||
}
|
||||
TAGS.put(modID, root);
|
||||
else {
|
||||
Optional<ModContainer> optional = FabricLoader.getInstance().getModContainer(modID);
|
||||
if (optional.isPresent()) {
|
||||
ModContainer modContainer = optional.get();
|
||||
if (BCLib.isDevEnvironment()) {
|
||||
root.putString("version", "63.63.63");
|
||||
}
|
||||
else {
|
||||
root.putString("version", modContainer.getMetadata().getVersion().toString());
|
||||
}
|
||||
saveFile(modID);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -77,6 +93,10 @@ public class WorldDataAPI {
|
|||
return tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces mod cache file to be saved.
|
||||
* @param modID {@link String} mod ID.
|
||||
*/
|
||||
public static void saveFile(String modID) {
|
||||
try {
|
||||
NbtIo.writeCompressed(getRootTag(modID), new File(dataDir, modID + ".nbt"));
|
||||
|
@ -85,4 +105,20 @@ public class WorldDataAPI {
|
|||
BCLib.LOGGER.error("World data saving failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get stored mod version (only for mods with registered cache).
|
||||
* @return {@link String} mod version.
|
||||
*/
|
||||
public static String getModVersion(String modID) {
|
||||
return getRootTag(modID).getString("version");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get stored mod version as integer (only for mods with registered cache).
|
||||
* @return {@code int} mod version.
|
||||
*/
|
||||
public static int getIntModVersion(String modID) {
|
||||
return DataFixerAPI.getModVersion(getModVersion(modID));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package ru.bclib.blockentities;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.core.Vec3i;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
@ -26,13 +27,13 @@ public class BaseBarrelBlockEntity extends RandomizableContainerBlockEntity {
|
|||
private NonNullList<ItemStack> inventory;
|
||||
private int viewerCount;
|
||||
|
||||
private BaseBarrelBlockEntity(BlockEntityType<?> type) {
|
||||
super(type);
|
||||
private BaseBarrelBlockEntity(BlockEntityType<?> type, BlockPos blockPos, BlockState blockState) {
|
||||
super(type, blockPos, blockState);
|
||||
this.inventory = NonNullList.withSize(27, ItemStack.EMPTY);
|
||||
}
|
||||
|
||||
public BaseBarrelBlockEntity() {
|
||||
this(BaseBlockEntities.BARREL);
|
||||
public BaseBarrelBlockEntity(BlockPos blockPos, BlockState blockState) {
|
||||
this(BaseBlockEntities.BARREL, blockPos, blockState);
|
||||
}
|
||||
|
||||
public CompoundTag save(CompoundTag tag) {
|
||||
|
@ -44,8 +45,8 @@ public class BaseBarrelBlockEntity extends RandomizableContainerBlockEntity {
|
|||
return tag;
|
||||
}
|
||||
|
||||
public void load(BlockState state, CompoundTag tag) {
|
||||
super.load(state, tag);
|
||||
public void load(CompoundTag tag) {
|
||||
super.load(tag);
|
||||
this.inventory = NonNullList.withSize(this.getContainerSize(), ItemStack.EMPTY);
|
||||
if (!this.tryLoadLootTable(tag)) {
|
||||
ContainerHelper.loadAllItems(tag, this.inventory);
|
||||
|
@ -97,10 +98,7 @@ public class BaseBarrelBlockEntity extends RandomizableContainerBlockEntity {
|
|||
|
||||
public void tick() {
|
||||
if (level != null) {
|
||||
int x = worldPosition.getX();
|
||||
int y = worldPosition.getY();
|
||||
int z = worldPosition.getZ();
|
||||
viewerCount = ChestBlockEntity.getOpenCount(level, this, x, y, z);
|
||||
viewerCount = ChestBlockEntity.getOpenCount(level, worldPosition);
|
||||
if (viewerCount > 0) {
|
||||
scheduleUpdate();
|
||||
} else {
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
package ru.bclib.blockentities;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.block.entity.ChestBlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import ru.bclib.registry.BaseBlockEntities;
|
||||
|
||||
public class BaseChestBlockEntity extends ChestBlockEntity {
|
||||
public BaseChestBlockEntity() {
|
||||
super(BaseBlockEntities.CHEST);
|
||||
public BaseChestBlockEntity(BlockPos blockPos, BlockState blockState) {
|
||||
super(BaseBlockEntities.CHEST, blockPos, blockState);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package ru.bclib.blockentities;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.TranslatableComponent;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
|
@ -7,11 +8,12 @@ import net.minecraft.world.inventory.AbstractContainerMenu;
|
|||
import net.minecraft.world.inventory.FurnaceMenu;
|
||||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import ru.bclib.registry.BaseBlockEntities;
|
||||
|
||||
public class BaseFurnaceBlockEntity extends AbstractFurnaceBlockEntity {
|
||||
public BaseFurnaceBlockEntity() {
|
||||
super(BaseBlockEntities.FURNACE, RecipeType.SMELTING);
|
||||
public BaseFurnaceBlockEntity(BlockPos blockPos, BlockState blockState) {
|
||||
super(BaseBlockEntities.FURNACE, blockPos, blockState, RecipeType.SMELTING);
|
||||
}
|
||||
|
||||
protected Component getDefaultName() {
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
package ru.bclib.blockentities;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.entity.SignBlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import ru.bclib.registry.BaseBlockEntities;
|
||||
|
||||
public class BaseSignBlockEntity extends SignBlockEntity {
|
||||
public BaseSignBlockEntity() {
|
||||
super();
|
||||
public BaseSignBlockEntity(BlockPos blockPos, BlockState blockState) {
|
||||
super(blockPos, blockState);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,28 +1,45 @@
|
|||
package ru.bclib.blockentities;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class DynamicBlockEntityType<T extends BlockEntity> extends BlockEntityType<T> {
|
||||
|
||||
private final Set<Block> validBlocks = Sets.newHashSet();
|
||||
private final BlockEntitySupplier<? extends T> factory;
|
||||
|
||||
public DynamicBlockEntityType(Supplier<? extends T> supplier) {
|
||||
super(supplier, Collections.emptySet(), null);
|
||||
public DynamicBlockEntityType(BlockEntitySupplier<? extends T> supplier) {
|
||||
super(null, Collections.emptySet(), null);
|
||||
this.factory = supplier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(Block block) {
|
||||
return validBlocks.contains(block);
|
||||
@Nullable public T create(BlockPos blockPos, BlockState blockState) {
|
||||
return factory.create(blockPos, blockState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(BlockState blockState) {
|
||||
return validBlocks.contains(blockState.getBlock());
|
||||
}
|
||||
|
||||
public void registerBlock(Block block) {
|
||||
validBlocks.add(block);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public
|
||||
interface BlockEntitySupplier<T extends BlockEntity> {
|
||||
T create(BlockPos blockPos, BlockState blockState);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,90 +1,96 @@
|
|||
package ru.bclib.blocks;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.client.resources.model.UnbakedModel;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.AnvilBlock;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.block.state.properties.IntegerProperty;
|
||||
import net.minecraft.world.level.material.MaterialColor;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import ru.bclib.client.models.BasePatterns;
|
||||
import ru.bclib.client.models.BlockModelProvider;
|
||||
import ru.bclib.client.models.ModelsHelper;
|
||||
import ru.bclib.client.models.PatternsHelper;
|
||||
|
||||
public class BaseAnvilBlock extends AnvilBlock implements BlockModelProvider {
|
||||
private static final IntegerProperty DESTRUCTION = BlockProperties.DESTRUCTION;
|
||||
|
||||
public BaseAnvilBlock(MaterialColor color) {
|
||||
super(FabricBlockSettings.copyOf(Blocks.ANVIL).materialColor(color));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
|
||||
super.createBlockStateDefinition(builder);
|
||||
builder.add(getDestructionProperty());
|
||||
}
|
||||
|
||||
public IntegerProperty getDestructionProperty() {
|
||||
return DESTRUCTION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
ItemStack stack = new ItemStack(this);
|
||||
int level = state.getValue(getDestructionProperty());
|
||||
stack.getOrCreateTag().putInt("level", level);
|
||||
return Collections.singletonList(stack);
|
||||
}
|
||||
|
||||
protected String getTop(ResourceLocation blockId, String block) {
|
||||
if (block.contains("item")) {
|
||||
return blockId.getPath() + "_top_0";
|
||||
}
|
||||
char last = block.charAt(block.length() - 1);
|
||||
return blockId.getPath() + "_top_" + last;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockModel getItemModel(ResourceLocation blockId) {
|
||||
return getBlockModel(blockId, defaultBlockState());
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable BlockModel getBlockModel(ResourceLocation blockId, BlockState blockState) {
|
||||
IntegerProperty destructionProperty = getDestructionProperty();
|
||||
int destruction = blockState.getValue(destructionProperty);
|
||||
String name = blockId.getPath();
|
||||
Map<String, String> textures = Maps.newHashMap();
|
||||
textures.put("%anvil%", name);
|
||||
textures.put("%top%", name + "_top_" + destruction);
|
||||
Optional<String> pattern = PatternsHelper.createJson(BasePatterns.BLOCK_ANVIL, textures);
|
||||
return ModelsHelper.fromPattern(pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
|
||||
IntegerProperty destructionProperty = getDestructionProperty();
|
||||
int destruction = blockState.getValue(destructionProperty);
|
||||
String modId = stateId.getNamespace();
|
||||
String modelId = "block/" + stateId.getPath() + "_top_" + destruction;
|
||||
ResourceLocation modelLocation = new ResourceLocation(modId, modelId);
|
||||
registerBlockModel(stateId, modelLocation, blockState, modelCache);
|
||||
return ModelsHelper.createFacingModel(modelLocation, blockState.getValue(FACING), false, false);
|
||||
}
|
||||
}
|
||||
package ru.bclib.blocks;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.client.resources.model.UnbakedModel;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.AnvilBlock;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.block.state.properties.IntegerProperty;
|
||||
import net.minecraft.world.level.material.MaterialColor;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import ru.bclib.client.models.BasePatterns;
|
||||
import ru.bclib.client.models.BlockModelProvider;
|
||||
import ru.bclib.client.models.ModelsHelper;
|
||||
import ru.bclib.client.models.PatternsHelper;
|
||||
import ru.bclib.items.BaseAnvilItem;
|
||||
|
||||
public abstract class BaseAnvilBlock extends AnvilBlock implements BlockModelProvider {
|
||||
public static final IntegerProperty DESTRUCTION = BlockProperties.DESTRUCTION;
|
||||
|
||||
public BaseAnvilBlock(MaterialColor color) {
|
||||
super(FabricBlockSettings.copyOf(Blocks.ANVIL).mapColor(color));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
|
||||
super.createBlockStateDefinition(builder);
|
||||
builder.add(DESTRUCTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
ItemStack dropStack = new ItemStack(this);
|
||||
int destruction = state.getValue(DESTRUCTION);
|
||||
dropStack.getOrCreateTag().putInt(BaseAnvilItem.DESTRUCTION, destruction);
|
||||
return Lists.newArrayList(dropStack);
|
||||
}
|
||||
|
||||
protected String getTop(ResourceLocation blockId, String block) {
|
||||
if (block.contains("item")) {
|
||||
return blockId.getPath() + "_top_0";
|
||||
}
|
||||
char last = block.charAt(block.length() - 1);
|
||||
return blockId.getPath() + "_top_" + last;
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract Item asItem();
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public BlockModel getItemModel(ResourceLocation blockId) {
|
||||
return getBlockModel(blockId, defaultBlockState());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public @Nullable BlockModel getBlockModel(ResourceLocation blockId, BlockState blockState) {
|
||||
int destruction = blockState.getValue(DESTRUCTION);
|
||||
String name = blockId.getPath();
|
||||
Map<String, String> textures = Maps.newHashMap();
|
||||
textures.put("%modid%", blockId.getNamespace());
|
||||
textures.put("%anvil%", name);
|
||||
textures.put("%top%", name + "_top_" + destruction);
|
||||
Optional<String> pattern = PatternsHelper.createJson(BasePatterns.BLOCK_ANVIL, textures);
|
||||
return ModelsHelper.fromPattern(pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
|
||||
int destruction = blockState.getValue(DESTRUCTION);
|
||||
String modId = stateId.getNamespace();
|
||||
String modelId = "block/" + stateId.getPath() + "_top_" + destruction;
|
||||
ResourceLocation modelLocation = new ResourceLocation(modId, modelId);
|
||||
registerBlockModel(stateId, modelLocation, blockState, modelCache);
|
||||
return ModelsHelper.createFacingModel(modelLocation, blockState.getValue(FACING), false, false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,12 +16,13 @@ import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
|||
import net.minecraft.world.level.block.state.properties.DirectionProperty;
|
||||
import ru.bclib.util.BlocksHelper;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public abstract class BaseAttachedBlock extends BaseBlockNotFull {
|
||||
public static final DirectionProperty FACING = BlockStateProperties.FACING;
|
||||
|
||||
public BaseAttachedBlock(Properties settings) {
|
||||
super(settings);
|
||||
this.registerDefaultState(this.defaultBlockState().setValue(FACING, Direction.UP));
|
||||
registerDefaultState(defaultBlockState().setValue(FACING, Direction.UP));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -31,7 +32,7 @@ public abstract class BaseAttachedBlock extends BaseBlockNotFull {
|
|||
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockPlaceContext ctx) {
|
||||
BlockState blockState = this.defaultBlockState();
|
||||
BlockState blockState = defaultBlockState();
|
||||
LevelReader worldView = ctx.getLevel();
|
||||
BlockPos blockPos = ctx.getClickedPos();
|
||||
Direction[] directions = ctx.getNearestLookingDirections();
|
||||
|
@ -47,7 +48,7 @@ public abstract class BaseAttachedBlock extends BaseBlockNotFull {
|
|||
|
||||
@Override
|
||||
public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) {
|
||||
Direction direction = (Direction) state.getValue(FACING);
|
||||
Direction direction = state.getValue(FACING);
|
||||
BlockPos blockPos = pos.relative(direction.getOpposite());
|
||||
return canSupportCenter(world, blockPos, direction) || world.getBlockState(blockPos).is(BlockTags.LEAVES);
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@ import java.util.Random;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.client.resources.model.BlockModelRotation;
|
||||
|
@ -44,11 +46,12 @@ public class BaseBarrelBlock extends BarrelBlock implements BlockModelProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
public BlockEntity newBlockEntity(BlockGetter world) {
|
||||
return BaseBlockEntities.BARREL.create();
|
||||
public BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) {
|
||||
return BaseBlockEntities.BARREL.create(blockPos, blockState);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
List<ItemStack> drop = super.getDrops(state, builder);
|
||||
drop.add(new ItemStack(this.asItem()));
|
||||
|
@ -97,11 +100,13 @@ public class BaseBarrelBlock extends BarrelBlock implements BlockModelProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public BlockModel getItemModel(ResourceLocation blockId) {
|
||||
return getBlockModel(blockId, defaultBlockState());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public @Nullable BlockModel getBlockModel(ResourceLocation blockId, BlockState blockState) {
|
||||
Optional<String> pattern;
|
||||
if (blockState.getValue(OPEN)) {
|
||||
|
@ -113,6 +118,7 @@ public class BaseBarrelBlock extends BarrelBlock implements BlockModelProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
|
||||
String open = blockState.getValue(OPEN) ? "_open" : "";
|
||||
ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(),
|
||||
|
@ -125,8 +131,8 @@ public class BaseBarrelBlock extends BarrelBlock implements BlockModelProvider {
|
|||
case EAST: rotation = BlockModelRotation.X90_Y90; break;
|
||||
case SOUTH: rotation = BlockModelRotation.X90_Y180; break;
|
||||
case WEST: rotation = BlockModelRotation.X90_Y270; break;
|
||||
case DOWN:
|
||||
default: rotation = BlockModelRotation.X180_Y0; break;
|
||||
case DOWN: rotation = BlockModelRotation.X180_Y0; break;
|
||||
default: break;
|
||||
}
|
||||
return ModelsHelper.createMultiVariant(modelId, rotation.getRotation(), false);
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ public class BaseBlock extends Block implements BlockModelProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
return Collections.singletonList(new ItemStack(this));
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package ru.bclib.blocks;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.block.BaseEntityBlock;
|
||||
|
@ -16,11 +17,12 @@ public class BaseBlockWithEntity extends BaseEntityBlock {
|
|||
}
|
||||
|
||||
@Override
|
||||
public BlockEntity newBlockEntity(BlockGetter world) {
|
||||
public BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
return Collections.singletonList(new ItemStack(this));
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@ import java.util.Optional;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
@ -39,6 +41,7 @@ public class BaseBookshelfBlock extends BaseBlock {
|
|||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public @Nullable BlockModel getBlockModel(ResourceLocation blockId, BlockState blockState) {
|
||||
Optional<String> pattern = PatternsHelper.createJson(BasePatterns.BLOCK_BOOKSHELF, replacePath(blockId));
|
||||
return ModelsHelper.fromPattern(pattern);
|
||||
|
|
|
@ -7,6 +7,8 @@ import java.util.Optional;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.client.resources.model.BlockModelRotation;
|
||||
import net.minecraft.client.resources.model.UnbakedModel;
|
||||
|
@ -33,11 +35,13 @@ public abstract class BaseButtonBlock extends ButtonBlock implements BlockModelP
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
return Collections.singletonList(new ItemStack(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public BlockModel getItemModel(ResourceLocation blockId) {
|
||||
ResourceLocation parentId = Registry.BLOCK.getKey(parent);
|
||||
Optional<String> pattern = PatternsHelper.createJson(BasePatterns.ITEM_BUTTON, parentId);
|
||||
|
@ -45,6 +49,7 @@ public abstract class BaseButtonBlock extends ButtonBlock implements BlockModelP
|
|||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) {
|
||||
ResourceLocation parentId = Registry.BLOCK.getKey(parent);
|
||||
Optional<String> pattern = blockState.getValue(POWERED) ?
|
||||
|
@ -54,6 +59,7 @@ public abstract class BaseButtonBlock extends ButtonBlock implements BlockModelP
|
|||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
|
||||
String powered = blockState.getValue(POWERED) ? "_powered" : "";
|
||||
ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(),
|
||||
|
|
|
@ -7,6 +7,8 @@ import java.util.Optional;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.client.resources.model.UnbakedModel;
|
||||
|
@ -22,31 +24,35 @@ import ru.bclib.client.models.BasePatterns;
|
|||
import ru.bclib.client.models.BlockModelProvider;
|
||||
import ru.bclib.client.models.ModelsHelper;
|
||||
import ru.bclib.client.models.PatternsHelper;
|
||||
import ru.bclib.client.render.ERenderLayer;
|
||||
import ru.bclib.client.render.BCLRenderLayer;
|
||||
import ru.bclib.interfaces.IRenderTyped;
|
||||
|
||||
public class BaseChainBlock extends ChainBlock implements BlockModelProvider, IRenderTyped {
|
||||
public BaseChainBlock(MaterialColor color) {
|
||||
super(FabricBlockSettings.copyOf(Blocks.CHAIN).materialColor(color));
|
||||
super(FabricBlockSettings.copyOf(Blocks.CHAIN).mapColor(color));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
return Collections.singletonList(new ItemStack(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public BlockModel getItemModel(ResourceLocation blockId) {
|
||||
return ModelsHelper.createItemModel(blockId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public @Nullable BlockModel getBlockModel(ResourceLocation blockId, BlockState blockState) {
|
||||
Optional<String> pattern = PatternsHelper.createJson(BasePatterns.BLOCK_CHAIN, blockId);
|
||||
return ModelsHelper.fromPattern(pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
|
||||
Direction.Axis axis = blockState.getValue(AXIS);
|
||||
ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(),
|
||||
|
@ -56,7 +62,7 @@ public class BaseChainBlock extends ChainBlock implements BlockModelProvider, IR
|
|||
}
|
||||
|
||||
@Override
|
||||
public ERenderLayer getRenderLayer() {
|
||||
return ERenderLayer.CUTOUT;
|
||||
public BCLRenderLayer getRenderLayer() {
|
||||
return BCLRenderLayer.CUTOUT;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,11 @@ package ru.bclib.blocks;
|
|||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.core.Registry;
|
||||
|
@ -31,12 +34,12 @@ public class BaseChestBlock extends ChestBlock implements BlockModelProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
public BlockEntity newBlockEntity(BlockGetter world)
|
||||
{
|
||||
return BaseBlockEntities.CHEST.create();
|
||||
public BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) {
|
||||
return BaseBlockEntities.CHEST.create(blockPos, blockState);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder)
|
||||
{
|
||||
List<ItemStack> drop = super.getDrops(state, builder);
|
||||
|
@ -45,12 +48,14 @@ public class BaseChestBlock extends ChestBlock implements BlockModelProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public BlockModel getItemModel(ResourceLocation blockId) {
|
||||
Optional<String> pattern = PatternsHelper.createJson(BasePatterns.ITEM_CHEST, blockId);
|
||||
return ModelsHelper.fromPattern(pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) {
|
||||
ResourceLocation parentId = Registry.BLOCK.getKey(parent);
|
||||
return ModelsHelper.createBlockEmpty(parentId);
|
||||
|
|
|
@ -7,6 +7,8 @@ import java.util.Optional;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.client.resources.model.UnbakedModel;
|
||||
|
@ -26,24 +28,28 @@ public class BaseComposterBlock extends ComposterBlock implements BlockModelProv
|
|||
public BaseComposterBlock(Block source) {
|
||||
super(FabricBlockSettings.copyOf(source));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
return Collections.singletonList(new ItemStack(this.asItem()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public BlockModel getItemModel(ResourceLocation resourceLocation) {
|
||||
return getBlockModel(resourceLocation, defaultBlockState());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public @Nullable BlockModel getBlockModel(ResourceLocation blockId, BlockState blockState) {
|
||||
Optional<String> pattern = PatternsHelper.createJson(BasePatterns.BLOCK_COMPOSTER, blockId);
|
||||
return ModelsHelper.fromPattern(pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
|
||||
ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(), "block/" + stateId.getPath());
|
||||
registerBlockModel(stateId, modelId, blockState, modelCache);
|
||||
|
|
|
@ -1,55 +1,61 @@
|
|||
package ru.bclib.blocks;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.CraftingTableBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import ru.bclib.client.models.BasePatterns;
|
||||
import ru.bclib.client.models.BlockModelProvider;
|
||||
import ru.bclib.client.models.ModelsHelper;
|
||||
import ru.bclib.client.models.PatternsHelper;
|
||||
|
||||
public class BaseCraftingTableBlock extends CraftingTableBlock implements BlockModelProvider {
|
||||
public BaseCraftingTableBlock(Block source) {
|
||||
super(FabricBlockSettings.copyOf(source));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
return Collections.singletonList(new ItemStack(this.asItem()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockModel getItemModel(ResourceLocation resourceLocation) {
|
||||
return getBlockModel(resourceLocation, defaultBlockState());
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable BlockModel getBlockModel(ResourceLocation blockId, BlockState blockState) {
|
||||
String blockName = blockId.getPath();
|
||||
Optional<String> pattern = PatternsHelper.createJson(BasePatterns.BLOCK_SIDED, new HashMap<String, String>() {
|
||||
private static final long serialVersionUID = 1L;
|
||||
{
|
||||
put("%particle%", blockName + "_front");
|
||||
put("%down%", blockName + "_bottom");
|
||||
put("%up%", blockName + "_top");
|
||||
put("%north%", blockName + "_front");
|
||||
put("%south%", blockName + "_side");
|
||||
put("%west%", blockName + "_front");
|
||||
put("%east%", blockName + "_side");
|
||||
}
|
||||
});
|
||||
return ModelsHelper.fromPattern(pattern);
|
||||
}
|
||||
}
|
||||
package ru.bclib.blocks;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.CraftingTableBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import ru.bclib.client.models.BasePatterns;
|
||||
import ru.bclib.client.models.BlockModelProvider;
|
||||
import ru.bclib.client.models.ModelsHelper;
|
||||
import ru.bclib.client.models.PatternsHelper;
|
||||
|
||||
public class BaseCraftingTableBlock extends CraftingTableBlock implements BlockModelProvider {
|
||||
public BaseCraftingTableBlock(Block source) {
|
||||
super(FabricBlockSettings.copyOf(source));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
return Collections.singletonList(new ItemStack(this.asItem()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public BlockModel getItemModel(ResourceLocation resourceLocation) {
|
||||
return getBlockModel(resourceLocation, defaultBlockState());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public @Nullable BlockModel getBlockModel(ResourceLocation blockId, BlockState blockState) {
|
||||
String blockName = blockId.getPath();
|
||||
Optional<String> pattern = PatternsHelper.createJson(BasePatterns.BLOCK_SIDED, new HashMap<String, String>() {
|
||||
private static final long serialVersionUID = 1L;
|
||||
{
|
||||
put("%modid%", blockId.getNamespace());
|
||||
put("%particle%", blockName + "_front");
|
||||
put("%down%", blockName + "_bottom");
|
||||
put("%up%", blockName + "_top");
|
||||
put("%north%", blockName + "_front");
|
||||
put("%south%", blockName + "_side");
|
||||
put("%west%", blockName + "_front");
|
||||
put("%east%", blockName + "_side");
|
||||
}
|
||||
});
|
||||
return ModelsHelper.fromPattern(pattern);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,8 +106,9 @@ public class BaseCropBlock extends BasePlantBlock {
|
|||
public boolean isBonemealSuccess(Level world, Random random, BlockPos pos, BlockState state) {
|
||||
return state.getValue(AGE) < 3;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public void tick(BlockState state, ServerLevel world, BlockPos pos, Random random) {
|
||||
super.tick(state, world, pos, random);
|
||||
if (isBonemealSuccess(world, random, pos, state) && random.nextInt(8) == 0) {
|
||||
|
|
|
@ -7,6 +7,8 @@ import java.util.Optional;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.client.resources.model.BlockModelRotation;
|
||||
|
@ -25,7 +27,7 @@ import ru.bclib.client.models.BasePatterns;
|
|||
import ru.bclib.client.models.BlockModelProvider;
|
||||
import ru.bclib.client.models.ModelsHelper;
|
||||
import ru.bclib.client.models.PatternsHelper;
|
||||
import ru.bclib.client.render.ERenderLayer;
|
||||
import ru.bclib.client.render.BCLRenderLayer;
|
||||
import ru.bclib.interfaces.IRenderTyped;
|
||||
|
||||
public class BaseDoorBlock extends DoorBlock implements IRenderTyped, BlockModelProvider {
|
||||
|
@ -34,6 +36,7 @@ public class BaseDoorBlock extends DoorBlock implements IRenderTyped, BlockModel
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
if (state.getValue(HALF) == DoubleBlockHalf.LOWER)
|
||||
return Collections.singletonList(new ItemStack(this.asItem()));
|
||||
|
@ -42,11 +45,12 @@ public class BaseDoorBlock extends DoorBlock implements IRenderTyped, BlockModel
|
|||
}
|
||||
|
||||
@Override
|
||||
public ERenderLayer getRenderLayer() {
|
||||
return ERenderLayer.CUTOUT;
|
||||
public BCLRenderLayer getRenderLayer() {
|
||||
return BCLRenderLayer.CUTOUT;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) {
|
||||
DoorType doorType = getDoorType(blockState);
|
||||
Optional<String> pattern = PatternsHelper.createJson(BasePatterns.BLOCK_DOOR_BOTTOM, resourceLocation);
|
||||
|
@ -66,6 +70,7 @@ public class BaseDoorBlock extends DoorBlock implements IRenderTyped, BlockModel
|
|||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
|
||||
Direction facing = blockState.getValue(FACING);
|
||||
DoorType doorType = getDoorType(blockState);
|
||||
|
|
|
@ -1,149 +1,150 @@
|
|||
package ru.bclib.blocks;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.item.ItemEntity;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.world.item.enchantment.Enchantments;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.LevelReader;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.BonemealableBlock;
|
||||
import net.minecraft.world.level.block.SoundType;
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
||||
import net.minecraft.world.level.block.state.properties.IntegerProperty;
|
||||
import net.minecraft.world.level.material.Material;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import ru.bclib.client.render.ERenderLayer;
|
||||
import ru.bclib.interfaces.IRenderTyped;
|
||||
import ru.bclib.util.BlocksHelper;
|
||||
|
||||
public abstract class DoublePlantBlock extends BaseBlockNotFull implements IRenderTyped, BonemealableBlock {
|
||||
private static final VoxelShape SHAPE = Block.box(4, 2, 4, 12, 16, 12);
|
||||
public static final IntegerProperty ROTATION = BlockProperties.ROTATION;
|
||||
public static final BooleanProperty TOP = BooleanProperty.create("top");
|
||||
|
||||
public DoublePlantBlock() {
|
||||
super(FabricBlockSettings.of(Material.PLANT)
|
||||
.breakByTool(FabricToolTags.SHEARS)
|
||||
.breakByHand(true)
|
||||
.sound(SoundType.WET_GRASS)
|
||||
.noCollission());
|
||||
this.registerDefaultState(this.stateDefinition.any().setValue(TOP, false));
|
||||
}
|
||||
|
||||
public DoublePlantBlock(int light) {
|
||||
super(FabricBlockSettings.of(Material.PLANT)
|
||||
.breakByTool(FabricToolTags.SHEARS)
|
||||
.breakByHand(true)
|
||||
.sound(SoundType.WET_GRASS)
|
||||
.lightLevel((state) -> state.getValue(TOP) ? light : 0)
|
||||
.noCollission());
|
||||
this.registerDefaultState(this.stateDefinition.any().setValue(TOP, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> stateManager) {
|
||||
stateManager.add(TOP, ROTATION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) {
|
||||
Vec3 vec3d = state.getOffset(view, pos);
|
||||
return SHAPE.move(vec3d.x, vec3d.y, vec3d.z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockBehaviour.OffsetType getOffsetType() {
|
||||
return BlockBehaviour.OffsetType.XZ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) {
|
||||
BlockState down = world.getBlockState(pos.below());
|
||||
BlockState up = world.getBlockState(pos.above());
|
||||
return state.getValue(TOP) ? down.getBlock() == this : isTerrain(down) && (up.getMaterial().isReplaceable());
|
||||
}
|
||||
|
||||
public boolean canStayAt(BlockState state, LevelReader world, BlockPos pos) {
|
||||
BlockState down = world.getBlockState(pos.below());
|
||||
BlockState up = world.getBlockState(pos.above());
|
||||
return state.getValue(TOP) ? down.getBlock() == this : isTerrain(down) && (up.getBlock() == this);
|
||||
}
|
||||
|
||||
protected abstract boolean isTerrain(BlockState state);
|
||||
|
||||
@Override
|
||||
public BlockState updateShape(BlockState state, Direction facing, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) {
|
||||
if (!canStayAt(state, world, pos)) {
|
||||
return Blocks.AIR.defaultBlockState();
|
||||
}
|
||||
else {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
if (state.getValue(TOP)) {
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
|
||||
ItemStack tool = builder.getParameter(LootContextParams.TOOL);
|
||||
if (tool != null && tool.getItem().is(FabricToolTags.SHEARS) || EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0) {
|
||||
return Lists.newArrayList(new ItemStack(this));
|
||||
}
|
||||
else {
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ERenderLayer getRenderLayer() {
|
||||
return ERenderLayer.CUTOUT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidBonemealTarget(BlockGetter world, BlockPos pos, BlockState state, boolean isClient) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBonemealSuccess(Level world, Random random, BlockPos pos, BlockState state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performBonemeal(ServerLevel world, Random random, BlockPos pos, BlockState state) {
|
||||
ItemEntity item = new ItemEntity(world, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, new ItemStack(this));
|
||||
world.addFreshEntity(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlacedBy(Level world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack itemStack) {
|
||||
int rot = world.random.nextInt(4);
|
||||
BlockState bs = this.defaultBlockState().setValue(ROTATION, rot);
|
||||
BlocksHelper.setWithoutUpdate(world, pos, bs);
|
||||
BlocksHelper.setWithoutUpdate(world, pos.above(), bs.setValue(TOP, true));
|
||||
}
|
||||
}
|
||||
package ru.bclib.blocks;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.item.ItemEntity;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.world.item.enchantment.Enchantments;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.LevelReader;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.BonemealableBlock;
|
||||
import net.minecraft.world.level.block.SoundType;
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
||||
import net.minecraft.world.level.block.state.properties.IntegerProperty;
|
||||
import net.minecraft.world.level.material.Material;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import ru.bclib.client.render.BCLRenderLayer;
|
||||
import ru.bclib.interfaces.IRenderTyped;
|
||||
import ru.bclib.util.BlocksHelper;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public abstract class BaseDoublePlantBlock extends BaseBlockNotFull implements IRenderTyped, BonemealableBlock {
|
||||
private static final VoxelShape SHAPE = Block.box(4, 2, 4, 12, 16, 12);
|
||||
public static final IntegerProperty ROTATION = BlockProperties.ROTATION;
|
||||
public static final BooleanProperty TOP = BooleanProperty.create("top");
|
||||
|
||||
public BaseDoublePlantBlock() {
|
||||
super(FabricBlockSettings.of(Material.PLANT)
|
||||
.breakByTool(FabricToolTags.SHEARS)
|
||||
.breakByHand(true)
|
||||
.sound(SoundType.WET_GRASS)
|
||||
.noCollission());
|
||||
this.registerDefaultState(this.stateDefinition.any().setValue(TOP, false));
|
||||
}
|
||||
|
||||
public BaseDoublePlantBlock(int light) {
|
||||
super(FabricBlockSettings.of(Material.PLANT)
|
||||
.breakByTool(FabricToolTags.SHEARS)
|
||||
.breakByHand(true)
|
||||
.sound(SoundType.WET_GRASS)
|
||||
.lightLevel((state) -> state.getValue(TOP) ? light : 0)
|
||||
.noCollission());
|
||||
this.registerDefaultState(this.stateDefinition.any().setValue(TOP, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> stateManager) {
|
||||
stateManager.add(TOP, ROTATION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) {
|
||||
Vec3 vec3d = state.getOffset(view, pos);
|
||||
return SHAPE.move(vec3d.x, vec3d.y, vec3d.z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockBehaviour.OffsetType getOffsetType() {
|
||||
return BlockBehaviour.OffsetType.XZ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) {
|
||||
BlockState down = world.getBlockState(pos.below());
|
||||
BlockState up = world.getBlockState(pos.above());
|
||||
return state.getValue(TOP) ? down.getBlock() == this : isTerrain(down) && (up.getMaterial().isReplaceable());
|
||||
}
|
||||
|
||||
public boolean canStayAt(BlockState state, LevelReader world, BlockPos pos) {
|
||||
BlockState down = world.getBlockState(pos.below());
|
||||
BlockState up = world.getBlockState(pos.above());
|
||||
return state.getValue(TOP) ? down.getBlock() == this : isTerrain(down) && (up.getBlock() == this);
|
||||
}
|
||||
|
||||
protected abstract boolean isTerrain(BlockState state);
|
||||
|
||||
@Override
|
||||
public BlockState updateShape(BlockState state, Direction facing, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) {
|
||||
if (!canStayAt(state, world, pos)) {
|
||||
return Blocks.AIR.defaultBlockState();
|
||||
}
|
||||
else {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
if (state.getValue(TOP)) {
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
|
||||
ItemStack tool = builder.getParameter(LootContextParams.TOOL);
|
||||
if (tool != null && FabricToolTags.SHEARS.contains(tool.getItem()) || EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0) {
|
||||
return Lists.newArrayList(new ItemStack(this));
|
||||
}
|
||||
else {
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BCLRenderLayer getRenderLayer() {
|
||||
return BCLRenderLayer.CUTOUT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidBonemealTarget(BlockGetter world, BlockPos pos, BlockState state, boolean isClient) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBonemealSuccess(Level world, Random random, BlockPos pos, BlockState state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performBonemeal(ServerLevel world, Random random, BlockPos pos, BlockState state) {
|
||||
ItemEntity item = new ItemEntity(world, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, new ItemStack(this));
|
||||
world.addFreshEntity(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlacedBy(Level world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack itemStack) {
|
||||
int rot = world.random.nextInt(4);
|
||||
BlockState bs = this.defaultBlockState().setValue(ROTATION, rot);
|
||||
BlocksHelper.setWithoutUpdate(world, pos, bs);
|
||||
BlocksHelper.setWithoutUpdate(world, pos.above(), bs.setValue(TOP, true));
|
||||
}
|
||||
}
|
|
@ -7,6 +7,8 @@ import java.util.Optional;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.client.resources.model.BlockModelRotation;
|
||||
|
@ -33,11 +35,13 @@ public class BaseFenceBlock extends FenceBlock implements BlockModelProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
return Collections.singletonList(new ItemStack(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public BlockModel getItemModel(ResourceLocation blockId) {
|
||||
ResourceLocation parentId = Registry.BLOCK.getKey(parent);
|
||||
Optional<String> pattern = PatternsHelper.createJson(BasePatterns.ITEM_FENCE, parentId);
|
||||
|
@ -45,6 +49,7 @@ public class BaseFenceBlock extends FenceBlock implements BlockModelProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public @Nullable BlockModel getBlockModel(ResourceLocation blockId, BlockState blockState) {
|
||||
ResourceLocation parentId = Registry.BLOCK.getKey(parent);
|
||||
String path = blockId.getPath();
|
||||
|
@ -59,6 +64,7 @@ public class BaseFenceBlock extends FenceBlock implements BlockModelProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
|
||||
ResourceLocation postId = new ResourceLocation(stateId.getNamespace(),
|
||||
"block/" + stateId.getPath() + "_post");
|
||||
|
|
|
@ -1,14 +1,9 @@
|
|||
package ru.bclib.blocks;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.client.resources.model.UnbakedModel;
|
||||
|
@ -18,21 +13,29 @@ import net.minecraft.stats.Stats;
|
|||
import net.minecraft.world.MenuProvider;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.FurnaceBlock;
|
||||
import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityTicker;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import ru.bclib.blockentities.BaseFurnaceBlockEntity;
|
||||
import ru.bclib.client.models.BasePatterns;
|
||||
import ru.bclib.client.models.BlockModelProvider;
|
||||
import ru.bclib.client.models.ModelsHelper;
|
||||
import ru.bclib.client.models.PatternsHelper;
|
||||
import ru.bclib.client.render.ERenderLayer;
|
||||
import ru.bclib.client.render.BCLRenderLayer;
|
||||
import ru.bclib.interfaces.IRenderTyped;
|
||||
import ru.bclib.registry.BaseBlockEntities;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class BaseFurnaceBlock extends FurnaceBlock implements BlockModelProvider, IRenderTyped {
|
||||
public BaseFurnaceBlock(Block source) {
|
||||
|
@ -40,8 +43,8 @@ public class BaseFurnaceBlock extends FurnaceBlock implements BlockModelProvider
|
|||
}
|
||||
|
||||
@Override
|
||||
public BlockEntity newBlockEntity(BlockGetter world) {
|
||||
return new BaseFurnaceBlockEntity();
|
||||
public BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) {
|
||||
return new BaseFurnaceBlockEntity(blockPos, blockState);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -54,6 +57,7 @@ public class BaseFurnaceBlock extends FurnaceBlock implements BlockModelProvider
|
|||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public @Nullable BlockModel getBlockModel(ResourceLocation blockId, BlockState blockState) {
|
||||
String blockName = blockId.getPath();
|
||||
Map<String, String> textures = Maps.newHashMap();
|
||||
|
@ -73,11 +77,13 @@ public class BaseFurnaceBlock extends FurnaceBlock implements BlockModelProvider
|
|||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public BlockModel getItemModel(ResourceLocation resourceLocation) {
|
||||
return getBlockModel(resourceLocation, defaultBlockState());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
|
||||
String lit = blockState.getValue(LIT) ? "_lit" : "";
|
||||
ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(),
|
||||
|
@ -87,11 +93,12 @@ public class BaseFurnaceBlock extends FurnaceBlock implements BlockModelProvider
|
|||
}
|
||||
|
||||
@Override
|
||||
public ERenderLayer getRenderLayer() {
|
||||
return ERenderLayer.CUTOUT;
|
||||
public BCLRenderLayer getRenderLayer() {
|
||||
return BCLRenderLayer.CUTOUT;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
List<ItemStack> drop = Lists.newArrayList(new ItemStack(this));
|
||||
BlockEntity blockEntity = builder.getOptionalParameter(LootContextParams.BLOCK_ENTITY);
|
||||
|
@ -103,4 +110,15 @@ public class BaseFurnaceBlock extends FurnaceBlock implements BlockModelProvider
|
|||
}
|
||||
return drop;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, BlockState blockState, BlockEntityType<T> blockEntityType) {
|
||||
return createFurnaceTicker(level, blockEntityType, BaseBlockEntities.FURNACE);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected static <T extends BlockEntity> BlockEntityTicker<T> createFurnaceTicker(Level level, BlockEntityType<T> blockEntityType, BlockEntityType<? extends AbstractFurnaceBlockEntity> blockEntityType2) {
|
||||
return level.isClientSide ? null : createTickerHelper(blockEntityType, blockEntityType2, AbstractFurnaceBlockEntity::serverTick);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@ import java.util.Optional;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.client.resources.model.UnbakedModel;
|
||||
|
@ -31,16 +33,19 @@ public class BaseGateBlock extends FenceGateBlock implements BlockModelProvider
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
return Collections.singletonList(new ItemStack(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public BlockModel getItemModel(ResourceLocation resourceLocation) {
|
||||
return getBlockModel(resourceLocation, defaultBlockState());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public @Nullable BlockModel getBlockModel(ResourceLocation blockId, BlockState blockState) {
|
||||
boolean inWall = blockState.getValue(IN_WALL);
|
||||
boolean isOpen = blockState.getValue(OPEN);
|
||||
|
@ -57,6 +62,7 @@ public class BaseGateBlock extends FenceGateBlock implements BlockModelProvider
|
|||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
|
||||
boolean inWall = blockState.getValue(IN_WALL);
|
||||
boolean isOpen = blockState.getValue(OPEN);
|
||||
|
|
|
@ -5,6 +5,8 @@ import java.util.Optional;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.client.resources.model.UnbakedModel;
|
||||
|
@ -33,10 +35,11 @@ import ru.bclib.client.models.BasePatterns;
|
|||
import ru.bclib.client.models.BlockModelProvider;
|
||||
import ru.bclib.client.models.ModelsHelper;
|
||||
import ru.bclib.client.models.PatternsHelper;
|
||||
import ru.bclib.client.render.ERenderLayer;
|
||||
import ru.bclib.client.render.BCLRenderLayer;
|
||||
import ru.bclib.interfaces.IRenderTyped;
|
||||
import ru.bclib.util.BlocksHelper;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class BaseLadderBlock extends BaseBlockNotFull implements IRenderTyped, BlockModelProvider {
|
||||
public static final DirectionProperty FACING = HorizontalDirectionalBlock.FACING;
|
||||
public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
|
||||
|
@ -55,17 +58,14 @@ public class BaseLadderBlock extends BaseBlockNotFull implements IRenderTyped, B
|
|||
stateManager.add(WATERLOGGED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) {
|
||||
switch (state.getValue(FACING)) {
|
||||
case SOUTH:
|
||||
return SOUTH_SHAPE;
|
||||
case WEST:
|
||||
return WEST_SHAPE;
|
||||
case EAST:
|
||||
return EAST_SHAPE;
|
||||
default:
|
||||
return NORTH_SHAPE;
|
||||
}
|
||||
return switch (state.getValue(FACING)) {
|
||||
case SOUTH -> SOUTH_SHAPE;
|
||||
case WEST -> WEST_SHAPE;
|
||||
case EAST -> EAST_SHAPE;
|
||||
default -> NORTH_SHAPE;
|
||||
};
|
||||
}
|
||||
|
||||
private boolean canPlaceOn(BlockGetter world, BlockPos pos, Direction side) {
|
||||
|
@ -76,7 +76,7 @@ public class BaseLadderBlock extends BaseBlockNotFull implements IRenderTyped, B
|
|||
@Override
|
||||
public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) {
|
||||
Direction direction = state.getValue(FACING);
|
||||
return this.canPlaceOn(world, pos.relative(direction.getOpposite()), direction);
|
||||
return canPlaceOn(world, pos.relative(direction.getOpposite()), direction);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -137,22 +137,25 @@ public class BaseLadderBlock extends BaseBlockNotFull implements IRenderTyped, B
|
|||
}
|
||||
|
||||
@Override
|
||||
public ERenderLayer getRenderLayer() {
|
||||
return ERenderLayer.CUTOUT;
|
||||
public BCLRenderLayer getRenderLayer() {
|
||||
return BCLRenderLayer.CUTOUT;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public BlockModel getItemModel(ResourceLocation blockId) {
|
||||
return ModelsHelper.createBlockItem(blockId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public @Nullable BlockModel getBlockModel(ResourceLocation blockId, BlockState blockState) {
|
||||
Optional<String> pattern = PatternsHelper.createJson(BasePatterns.BLOCK_LADDER, blockId);
|
||||
return ModelsHelper.fromPattern(pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
|
||||
ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(), "block/" + stateId.getPath());
|
||||
registerBlockModel(stateId, modelId, blockState, modelCache);
|
||||
|
|
|
@ -20,7 +20,7 @@ import net.minecraft.world.level.material.MaterialColor;
|
|||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||
import ru.bclib.client.models.BlockModelProvider;
|
||||
import ru.bclib.client.render.ERenderLayer;
|
||||
import ru.bclib.client.render.BCLRenderLayer;
|
||||
import ru.bclib.interfaces.IRenderTyped;
|
||||
import ru.bclib.util.MHelper;
|
||||
|
||||
|
@ -29,7 +29,7 @@ public class BaseLeavesBlock extends LeavesBlock implements BlockModelProvider,
|
|||
|
||||
public BaseLeavesBlock(Block sapling, MaterialColor color) {
|
||||
super(FabricBlockSettings.copyOf(Blocks.OAK_LEAVES)
|
||||
.materialColor(color)
|
||||
.mapColor(color)
|
||||
.breakByTool(FabricToolTags.HOES)
|
||||
.breakByTool(FabricToolTags.SHEARS)
|
||||
.breakByHand(true)
|
||||
|
@ -41,7 +41,7 @@ public class BaseLeavesBlock extends LeavesBlock implements BlockModelProvider,
|
|||
|
||||
public BaseLeavesBlock(Block sapling, MaterialColor color, int light) {
|
||||
super(FabricBlockSettings.copyOf(Blocks.OAK_LEAVES)
|
||||
.materialColor(color)
|
||||
.mapColor(color)
|
||||
.luminance(light)
|
||||
.breakByTool(FabricToolTags.HOES)
|
||||
.breakByTool(FabricToolTags.SHEARS)
|
||||
|
@ -52,15 +52,16 @@ public class BaseLeavesBlock extends LeavesBlock implements BlockModelProvider,
|
|||
}
|
||||
|
||||
@Override
|
||||
public ERenderLayer getRenderLayer() {
|
||||
return ERenderLayer.CUTOUT;
|
||||
public BCLRenderLayer getRenderLayer() {
|
||||
return BCLRenderLayer.CUTOUT;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
ItemStack tool = builder.getParameter(LootContextParams.TOOL);
|
||||
if (tool != null) {
|
||||
if (tool.getItem().is(FabricToolTags.SHEARS) || EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0) {
|
||||
if (FabricToolTags.SHEARS.contains(tool.getItem()) || EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0) {
|
||||
return Collections.singletonList(new ItemStack(this));
|
||||
}
|
||||
int fortune = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.BLOCK_FORTUNE, tool);
|
||||
|
|
|
@ -25,7 +25,7 @@ import ru.bclib.client.models.BasePatterns;
|
|||
import ru.bclib.client.models.BlockModelProvider;
|
||||
import ru.bclib.client.models.ModelsHelper;
|
||||
import ru.bclib.client.models.PatternsHelper;
|
||||
import ru.bclib.client.render.ERenderLayer;
|
||||
import ru.bclib.client.render.BCLRenderLayer;
|
||||
import ru.bclib.interfaces.IRenderTyped;
|
||||
|
||||
public class BaseMetalBarsBlock extends IronBarsBlock implements BlockModelProvider, IRenderTyped {
|
||||
|
@ -34,6 +34,7 @@ public class BaseMetalBarsBlock extends IronBarsBlock implements BlockModelProvi
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
return Collections.singletonList(new ItemStack(this));
|
||||
}
|
||||
|
@ -52,11 +53,13 @@ public class BaseMetalBarsBlock extends IronBarsBlock implements BlockModelProvi
|
|||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public BlockModel getItemModel(ResourceLocation resourceLocation) {
|
||||
return ModelsHelper.createBlockItem(resourceLocation);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public @Nullable BlockModel getBlockModel(ResourceLocation blockId, BlockState blockState) {
|
||||
ResourceLocation thisId = Registry.BLOCK.getKey(this);
|
||||
String path = blockId.getPath();
|
||||
|
@ -71,6 +74,7 @@ public class BaseMetalBarsBlock extends IronBarsBlock implements BlockModelProvi
|
|||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
|
||||
ResourceLocation postId = new ResourceLocation(stateId.getNamespace(),
|
||||
"block/" + stateId.getPath() + "_post");
|
||||
|
@ -96,14 +100,14 @@ public class BaseMetalBarsBlock extends IronBarsBlock implements BlockModelProvi
|
|||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public boolean skipRendering(BlockState state, BlockState stateFrom, Direction direction) {
|
||||
if (direction.getAxis().isVertical() && stateFrom.getBlock().is(this) && !stateFrom.equals(state)) {
|
||||
if (direction.getAxis().isVertical() && stateFrom.getBlock() == this && !stateFrom.equals(state)) {
|
||||
return false;
|
||||
}
|
||||
return super.skipRendering(state, stateFrom, direction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ERenderLayer getRenderLayer() {
|
||||
return ERenderLayer.CUTOUT;
|
||||
public BCLRenderLayer getRenderLayer() {
|
||||
return BCLRenderLayer.CUTOUT;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
|||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.util.valueproviders.UniformInt;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.enchantment.EnchantmentHelper;
|
||||
|
@ -26,26 +27,20 @@ public class BaseOreBlock extends OreBlock implements BlockModelProvider {
|
|||
private final Item dropItem;
|
||||
private final int minCount;
|
||||
private final int maxCount;
|
||||
private final int experience;
|
||||
|
||||
public BaseOreBlock(Item drop, int minCount, int maxCount, int experience) {
|
||||
super(FabricBlockSettings.of(Material.STONE, MaterialColor.SAND)
|
||||
.hardness(3F)
|
||||
.resistance(9F)
|
||||
.requiresCorrectToolForDrops()
|
||||
.sound(SoundType.STONE));
|
||||
.sound(SoundType.STONE), UniformInt.of(1, experience));
|
||||
this.dropItem = drop;
|
||||
this.minCount = minCount;
|
||||
this.maxCount = maxCount;
|
||||
this.experience = experience;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int xpOnDrop(Random random) {
|
||||
return this.experience > 0 ? random.nextInt(experience) + 1 : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
ItemStack tool = builder.getParameter(LootContextParams.TOOL);
|
||||
if (tool != null && tool.isCorrectToolForDrops(state)) {
|
||||
|
|
|
@ -1,92 +1,98 @@
|
|||
package ru.bclib.blocks;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.client.resources.model.UnbakedModel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.world.item.enchantment.Enchantments;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import ru.bclib.client.models.BasePatterns;
|
||||
import ru.bclib.client.models.ModelsHelper;
|
||||
import ru.bclib.client.models.PatternsHelper;
|
||||
|
||||
public abstract class BasePathBlock extends BaseBlockNotFull {
|
||||
private static final VoxelShape SHAPE = Block.box(0, 0, 0, 16, 15, 16);
|
||||
|
||||
private Block baseBlock;
|
||||
|
||||
public BasePathBlock(Block source) {
|
||||
super(FabricBlockSettings.copyOf(source).isValidSpawn((state, world, pos, type) -> { return false; }));
|
||||
this.baseBlock = Blocks.DIRT;
|
||||
if (source instanceof BaseTerrainBlock) {
|
||||
BaseTerrainBlock terrain = (BaseTerrainBlock) source;
|
||||
this.baseBlock = terrain.getBaseBlock();
|
||||
terrain.setPathBlock(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
ItemStack tool = builder.getParameter(LootContextParams.TOOL);
|
||||
if (tool != null && EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0) {
|
||||
return Collections.singletonList(new ItemStack(this));
|
||||
}
|
||||
return Collections.singletonList(new ItemStack(Blocks.END_STONE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) {
|
||||
return SHAPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getCollisionShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) {
|
||||
return SHAPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockModel getItemModel(ResourceLocation blockId) {
|
||||
return getBlockModel(blockId, defaultBlockState());
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable BlockModel getBlockModel(ResourceLocation blockId, BlockState blockState) {
|
||||
String name = blockId.getPath();
|
||||
ResourceLocation bottomId = Registry.BLOCK.getKey(baseBlock);
|
||||
String bottom = bottomId.getNamespace() + ":block/" + bottomId.getPath();
|
||||
Map<String, String> textures = Maps.newHashMap();
|
||||
textures.put("%modid%", blockId.getNamespace());
|
||||
textures.put("%top%", name + "_top");
|
||||
textures.put("%side%", name.replace("_path", "") + "_side");
|
||||
textures.put("%bottom%", bottom);
|
||||
Optional<String> pattern = PatternsHelper.createJson(BasePatterns.BLOCK_PATH, textures);
|
||||
return ModelsHelper.fromPattern(pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
|
||||
ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(), "block/" + stateId.getPath());
|
||||
registerBlockModel(stateId, modelId, blockState, modelCache);
|
||||
return ModelsHelper.createRandomTopModel(modelId);
|
||||
}
|
||||
}
|
||||
package ru.bclib.blocks;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.client.resources.model.UnbakedModel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.world.item.enchantment.Enchantments;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import ru.bclib.client.models.BasePatterns;
|
||||
import ru.bclib.client.models.ModelsHelper;
|
||||
import ru.bclib.client.models.PatternsHelper;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class BasePathBlock extends BaseBlockNotFull {
|
||||
private static final VoxelShape SHAPE = Block.box(0, 0, 0, 16, 15, 16);
|
||||
|
||||
private Block baseBlock;
|
||||
|
||||
public BasePathBlock(Block source) {
|
||||
super(FabricBlockSettings.copyOf(source).isValidSpawn((state, world, pos, type) -> false));
|
||||
this.baseBlock = Blocks.DIRT;
|
||||
if (source instanceof BaseTerrainBlock) {
|
||||
BaseTerrainBlock terrain = (BaseTerrainBlock) source;
|
||||
this.baseBlock = terrain.getBaseBlock();
|
||||
terrain.setPathBlock(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
ItemStack tool = builder.getParameter(LootContextParams.TOOL);
|
||||
if (tool != null && EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0) {
|
||||
return Collections.singletonList(new ItemStack(this));
|
||||
}
|
||||
return Collections.singletonList(new ItemStack(Blocks.END_STONE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) {
|
||||
return SHAPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getCollisionShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) {
|
||||
return SHAPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public BlockModel getItemModel(ResourceLocation blockId) {
|
||||
return getBlockModel(blockId, defaultBlockState());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public @Nullable BlockModel getBlockModel(ResourceLocation blockId, BlockState blockState) {
|
||||
String name = blockId.getPath();
|
||||
ResourceLocation bottomId = Registry.BLOCK.getKey(baseBlock);
|
||||
String bottom = bottomId.getNamespace() + ":block/" + bottomId.getPath();
|
||||
Map<String, String> textures = Maps.newHashMap();
|
||||
textures.put("%modid%", blockId.getNamespace());
|
||||
textures.put("%top%", name + "_top");
|
||||
textures.put("%side%", name.replace("_path", "") + "_side");
|
||||
textures.put("%bottom%", bottom);
|
||||
Optional<String> pattern = PatternsHelper.createJson(BasePatterns.BLOCK_PATH, textures);
|
||||
return ModelsHelper.fromPattern(pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
|
||||
ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(), "block/" + stateId.getPath());
|
||||
registerBlockModel(stateId, modelId, blockState, modelCache);
|
||||
return ModelsHelper.createRandomTopModel(modelId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,9 +30,10 @@ import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
|||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import ru.bclib.client.render.ERenderLayer;
|
||||
import ru.bclib.client.render.BCLRenderLayer;
|
||||
import ru.bclib.interfaces.IRenderTyped;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public abstract class BasePlantBlock extends BaseBlockNotFull implements IRenderTyped, BonemealableBlock {
|
||||
private static final VoxelShape SHAPE = Block.box(4, 0, 4, 12, 14, 12);
|
||||
|
||||
|
@ -97,7 +98,7 @@ public abstract class BasePlantBlock extends BaseBlockNotFull implements IRender
|
|||
@Override
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
ItemStack tool = builder.getParameter(LootContextParams.TOOL);
|
||||
if (tool != null && tool.getItem().is(FabricToolTags.SHEARS) || EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0) {
|
||||
if (tool != null && FabricToolTags.SHEARS.contains(tool.getItem()) || EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0) {
|
||||
return Lists.newArrayList(new ItemStack(this));
|
||||
}
|
||||
else {
|
||||
|
@ -106,8 +107,8 @@ public abstract class BasePlantBlock extends BaseBlockNotFull implements IRender
|
|||
}
|
||||
|
||||
@Override
|
||||
public ERenderLayer getRenderLayer() {
|
||||
return ERenderLayer.CUTOUT;
|
||||
public BCLRenderLayer getRenderLayer() {
|
||||
return BCLRenderLayer.CUTOUT;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -53,8 +53,9 @@ public abstract class BasePlantWithAgeBlock extends BasePlantBlock {
|
|||
public boolean isBonemealSuccess(Level world, Random random, BlockPos pos, BlockState state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public void tick(BlockState state, ServerLevel world, BlockPos pos, Random random) {
|
||||
super.tick(state, world, pos, random);
|
||||
if (random.nextInt(8) == 0) {
|
||||
|
|
|
@ -7,6 +7,8 @@ import java.util.Optional;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.client.resources.model.UnbakedModel;
|
||||
|
@ -31,16 +33,19 @@ public class BasePressurePlateBlock extends PressurePlateBlock implements BlockM
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
return Collections.singletonList(new ItemStack(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public BlockModel getItemModel(ResourceLocation resourceLocation) {
|
||||
return getBlockModel(resourceLocation, defaultBlockState());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) {
|
||||
ResourceLocation parentId = Registry.BLOCK.getKey(parent);
|
||||
Optional<String> pattern;
|
||||
|
@ -53,6 +58,7 @@ public class BasePressurePlateBlock extends PressurePlateBlock implements BlockM
|
|||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
|
||||
String state = blockState.getValue(POWERED) ? "_down" : "_up";
|
||||
ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(),
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
package ru.bclib.blocks;
|
||||
|
||||
import net.minecraft.world.level.block.Block;
|
||||
|
||||
public class BasePressureStonePlateBlock extends BasePressurePlateBlock {
|
||||
public BasePressureStonePlateBlock(Block source) {
|
||||
super(Sensitivity.MOBS, source);
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
package ru.bclib.blocks;
|
||||
|
||||
import net.minecraft.world.level.block.Block;
|
||||
|
||||
public class BasePressureWoodenPlateBlock extends BasePressurePlateBlock {
|
||||
public BasePressureWoodenPlateBlock(Block source) {
|
||||
super(Sensitivity.EVERYTHING, source);
|
||||
}
|
||||
}
|
|
@ -7,6 +7,8 @@ import java.util.Optional;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.client.resources.model.UnbakedModel;
|
||||
|
@ -28,27 +30,30 @@ public class BaseRotatedPillarBlock extends RotatedPillarBlock implements BlockM
|
|||
public BaseRotatedPillarBlock(Block block) {
|
||||
super(FabricBlockSettings.copyOf(block));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
return Collections.singletonList(new ItemStack(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public BlockModel getItemModel(ResourceLocation blockId) {
|
||||
return getBlockModel(blockId, defaultBlockState());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public @Nullable BlockModel getBlockModel(ResourceLocation blockId, BlockState blockState) {
|
||||
Optional<String> pattern = createBlockPattern(blockId);
|
||||
return ModelsHelper.fromPattern(pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
|
||||
ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(),
|
||||
"block/" + stateId.getPath());
|
||||
ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(), "block/" + stateId.getPath());
|
||||
registerBlockModel(stateId, modelId, blockState, modelCache);
|
||||
return ModelsHelper.createRotatedModel(modelId, blockState.getValue(AXIS));
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ import java.util.List;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
@ -46,6 +48,7 @@ import ru.bclib.client.models.ModelsHelper;
|
|||
import ru.bclib.interfaces.ISpetialItem;
|
||||
import ru.bclib.util.BlocksHelper;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class BaseSignBlock extends SignBlock implements BlockModelProvider, ISpetialItem {
|
||||
public static final IntegerProperty ROTATION = BlockStateProperties.ROTATION_16;
|
||||
public static final BooleanProperty FLOOR = BooleanProperty.create("floor");
|
||||
|
@ -75,8 +78,8 @@ public class BaseSignBlock extends SignBlock implements BlockModelProvider, ISpe
|
|||
}
|
||||
|
||||
@Override
|
||||
public BlockEntity newBlockEntity(BlockGetter world) {
|
||||
return new BaseSignBlockEntity();
|
||||
public BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) {
|
||||
return new BaseSignBlockEntity(blockPos, blockState);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -85,7 +88,7 @@ public class BaseSignBlock extends SignBlock implements BlockModelProvider, ISpe
|
|||
BaseSignBlockEntity sign = (BaseSignBlockEntity) world.getBlockEntity(pos);
|
||||
if (sign != null) {
|
||||
if (!world.isClientSide) {
|
||||
sign.setAllowedPlayerEditor((Player) placer);
|
||||
sign.setAllowedPlayerEditor(placer.getUUID());
|
||||
((ServerPlayer) placer).connection.send(new ClientboundOpenSignEditorPacket(pos));
|
||||
} else {
|
||||
sign.setEditable(true);
|
||||
|
@ -146,6 +149,7 @@ public class BaseSignBlock extends SignBlock implements BlockModelProvider, ISpe
|
|||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) {
|
||||
ResourceLocation parentId = Registry.BLOCK.getKey(parent);
|
||||
return ModelsHelper.createBlockEmpty(parentId);
|
||||
|
@ -166,12 +170,6 @@ public class BaseSignBlock extends SignBlock implements BlockModelProvider, ISpe
|
|||
return Collections.singletonList(new ItemStack(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fluid takeLiquid(LevelAccessor world, BlockPos pos, BlockState state) {
|
||||
// TODO Auto-generated method stub
|
||||
return super.takeLiquid(world, pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlaceLiquid(BlockGetter world, BlockPos pos, BlockState state, Fluid fluid) {
|
||||
// TODO Auto-generated method stub
|
||||
|
|
|
@ -7,6 +7,8 @@ import java.util.Optional;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.client.resources.model.BlockModelRotation;
|
||||
|
@ -33,23 +35,32 @@ public class BaseSlabBlock extends SlabBlock implements BlockModelProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
return Collections.singletonList(new ItemStack(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public BlockModel getItemModel(ResourceLocation resourceLocation) {
|
||||
return getBlockModel(resourceLocation, defaultBlockState());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public @Nullable BlockModel getBlockModel(ResourceLocation blockId, BlockState blockState) {
|
||||
ResourceLocation parentId = Registry.BLOCK.getKey(parent);
|
||||
Optional<String> pattern = PatternsHelper.createJson(BasePatterns.BLOCK_SLAB, parentId);
|
||||
Optional<String> pattern;
|
||||
if (blockState.getValue(TYPE) == SlabType.DOUBLE) {
|
||||
pattern = PatternsHelper.createBlockSimple(parentId);
|
||||
} else {
|
||||
pattern = PatternsHelper.createJson(BasePatterns.BLOCK_SLAB, parentId);
|
||||
}
|
||||
return ModelsHelper.fromPattern(pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
|
||||
SlabType type = blockState.getValue(TYPE);
|
||||
ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(),
|
||||
|
|
|
@ -7,6 +7,8 @@ import java.util.Optional;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.client.resources.model.BlockModelRotation;
|
||||
|
@ -35,16 +37,19 @@ public class BaseStairsBlock extends StairBlock implements BlockModelProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
return Collections.singletonList(new ItemStack(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public BlockModel getItemModel(ResourceLocation resourceLocation) {
|
||||
return getBlockModel(resourceLocation, defaultBlockState());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public @Nullable BlockModel getBlockModel(ResourceLocation blockId, BlockState blockState) {
|
||||
ResourceLocation parentId = Registry.BLOCK.getKey(parent);
|
||||
Optional<String> pattern = Optional.empty();
|
||||
|
@ -65,6 +70,7 @@ public class BaseStairsBlock extends StairBlock implements BlockModelProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
|
||||
String state;
|
||||
StairsShape shape = blockState.getValue(SHAPE);
|
||||
|
|
|
@ -1,41 +1,42 @@
|
|||
package ru.bclib.blocks;
|
||||
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
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.RotatedPillarBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.material.MaterialColor;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
|
||||
public class BaseStripableLogBlock extends BaseRotatedPillarBlock {
|
||||
private final Block striped;
|
||||
|
||||
public BaseStripableLogBlock(MaterialColor color, Block striped) {
|
||||
super(FabricBlockSettings.copyOf(striped).materialColor(color));
|
||||
this.striped = striped;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
|
||||
if (player.getMainHandItem().getItem().is(FabricToolTags.AXES)) {
|
||||
world.playSound(player, pos, SoundEvents.AXE_STRIP, SoundSource.BLOCKS, 1.0F, 1.0F);
|
||||
if (!world.isClientSide) {
|
||||
world.setBlock(pos, striped.defaultBlockState().setValue(RotatedPillarBlock.AXIS, state.getValue(RotatedPillarBlock.AXIS)), 11);
|
||||
if (!player.isCreative()) {
|
||||
player.getMainHandItem().hurt(1, world.random, (ServerPlayer) player);
|
||||
}
|
||||
}
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
}
|
||||
package ru.bclib.blocks;
|
||||
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
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.RotatedPillarBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.material.MaterialColor;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
|
||||
public class BaseStripableLogBlock extends BaseRotatedPillarBlock {
|
||||
private final Block striped;
|
||||
|
||||
public BaseStripableLogBlock(MaterialColor color, Block striped) {
|
||||
super(FabricBlockSettings.copyOf(striped).mapColor(color));
|
||||
this.striped = striped;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
|
||||
if (FabricToolTags.AXES.contains(player.getMainHandItem().getItem())) {
|
||||
world.playSound(player, pos, SoundEvents.AXE_STRIP, SoundSource.BLOCKS, 1.0F, 1.0F);
|
||||
if (!world.isClientSide) {
|
||||
world.setBlock(pos, striped.defaultBlockState().setValue(RotatedPillarBlock.AXIS, state.getValue(RotatedPillarBlock.AXIS)), 11);
|
||||
if (!player.isCreative()) {
|
||||
player.getMainHandItem().hurt(1, world.random, (ServerPlayer) player);
|
||||
}
|
||||
}
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,136 +1,142 @@
|
|||
package ru.bclib.blocks;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.client.resources.model.UnbakedModel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.world.item.enchantment.Enchantments;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelReader;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.SnowLayerBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.lighting.LayerLightEngine;
|
||||
import net.minecraft.world.level.material.MaterialColor;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import ru.bclib.client.models.BasePatterns;
|
||||
import ru.bclib.client.models.ModelsHelper;
|
||||
import ru.bclib.client.models.PatternsHelper;
|
||||
import ru.bclib.client.sound.BlockSounds;
|
||||
|
||||
public class BaseTerrainBlock extends BaseBlock {
|
||||
|
||||
private final Block baseBlock;
|
||||
private Block pathBlock;
|
||||
|
||||
public BaseTerrainBlock(Block baseBlock, MaterialColor color) {
|
||||
super(FabricBlockSettings.copyOf(baseBlock).materialColor(color).sound(BlockSounds.TERRAIN_SOUND).randomTicks());
|
||||
this.baseBlock = baseBlock;
|
||||
}
|
||||
|
||||
public void setPathBlock(Block roadBlock) {
|
||||
this.pathBlock = roadBlock;
|
||||
}
|
||||
|
||||
public Block getBaseBlock() {
|
||||
return baseBlock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
|
||||
if (pathBlock != null && player.getMainHandItem().getItem().is(FabricToolTags.SHOVELS)) {
|
||||
world.playSound(player, pos, SoundEvents.SHOVEL_FLATTEN, SoundSource.BLOCKS, 1.0F, 1.0F);
|
||||
if (!world.isClientSide) {
|
||||
world.setBlockAndUpdate(pos, pathBlock.defaultBlockState());
|
||||
if (!player.isCreative()) {
|
||||
player.getMainHandItem().hurt(1, world.random, (ServerPlayer) player);
|
||||
}
|
||||
}
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
ItemStack tool = builder.getParameter(LootContextParams.TOOL);
|
||||
if (tool != null && EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0) {
|
||||
return Collections.singletonList(new ItemStack(this));
|
||||
}
|
||||
return Collections.singletonList(new ItemStack(Blocks.END_STONE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void randomTick(BlockState state, ServerLevel world, BlockPos pos, Random random) {
|
||||
if (random.nextInt(16) == 0 && !canStay(state, world, pos)) {
|
||||
world.setBlockAndUpdate(pos, Blocks.END_STONE.defaultBlockState());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canStay(BlockState state, LevelReader worldView, BlockPos pos) {
|
||||
BlockPos blockPos = pos.above();
|
||||
BlockState blockState = worldView.getBlockState(blockPos);
|
||||
if (blockState.is(Blocks.SNOW) && (Integer) blockState.getValue(SnowLayerBlock.LAYERS) == 1) {
|
||||
return true;
|
||||
}
|
||||
else if (blockState.getFluidState().getAmount() == 8) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
int i = LayerLightEngine.getLightBlockInto(worldView, state, pos, blockState, blockPos, Direction.UP, blockState.getLightBlock(worldView, blockPos));
|
||||
return i < 5;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockModel getItemModel(ResourceLocation blockId) {
|
||||
return getBlockModel(blockId, defaultBlockState());
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable BlockModel getBlockModel(ResourceLocation blockId, BlockState blockState) {
|
||||
ResourceLocation baseId = Registry.BLOCK.getKey(baseBlock);
|
||||
String modId = blockId.getNamespace();
|
||||
String path = blockId.getPath();
|
||||
String bottom = baseId.getNamespace() + ":block/" + baseId.getPath();
|
||||
Map<String, String> textures = Maps.newHashMap();
|
||||
textures.put("%top%", modId + ":block/" + path + "_top");
|
||||
textures.put("%side%", modId + ":block/" + path + "_side");
|
||||
textures.put("%bottom%", bottom);
|
||||
Optional<String> pattern = PatternsHelper.createJson(BasePatterns.BLOCK_TOP_SIDE_BOTTOM, textures);
|
||||
return ModelsHelper.fromPattern(pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
|
||||
ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(), "block/" + stateId.getPath());
|
||||
registerBlockModel(stateId, modelId, blockState, modelCache);
|
||||
return ModelsHelper.createRandomTopModel(modelId);
|
||||
}
|
||||
}
|
||||
package ru.bclib.blocks;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.client.resources.model.UnbakedModel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.world.item.enchantment.Enchantments;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelReader;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.SnowLayerBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.lighting.LayerLightEngine;
|
||||
import net.minecraft.world.level.material.MaterialColor;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import ru.bclib.client.models.BasePatterns;
|
||||
import ru.bclib.client.models.ModelsHelper;
|
||||
import ru.bclib.client.models.PatternsHelper;
|
||||
import ru.bclib.client.sound.BlockSounds;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class BaseTerrainBlock extends BaseBlock {
|
||||
|
||||
private final Block baseBlock;
|
||||
private Block pathBlock;
|
||||
|
||||
public BaseTerrainBlock(Block baseBlock, MaterialColor color) {
|
||||
super(FabricBlockSettings.copyOf(baseBlock).materialColor(color).sound(BlockSounds.TERRAIN_SOUND).randomTicks());
|
||||
this.baseBlock = baseBlock;
|
||||
}
|
||||
|
||||
public void setPathBlock(Block roadBlock) {
|
||||
this.pathBlock = roadBlock;
|
||||
}
|
||||
|
||||
public Block getBaseBlock() {
|
||||
return baseBlock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
|
||||
if (pathBlock != null && FabricToolTags.SHOVELS.contains(player.getMainHandItem().getItem())) {
|
||||
world.playSound(player, pos, SoundEvents.SHOVEL_FLATTEN, SoundSource.BLOCKS, 1.0F, 1.0F);
|
||||
if (!world.isClientSide) {
|
||||
world.setBlockAndUpdate(pos, pathBlock.defaultBlockState());
|
||||
if (!player.isCreative()) {
|
||||
player.getMainHandItem().hurt(1, world.random, (ServerPlayer) player);
|
||||
}
|
||||
}
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
ItemStack tool = builder.getParameter(LootContextParams.TOOL);
|
||||
if (tool != null && EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0) {
|
||||
return Collections.singletonList(new ItemStack(this));
|
||||
}
|
||||
return Collections.singletonList(new ItemStack(Blocks.END_STONE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void randomTick(BlockState state, ServerLevel world, BlockPos pos, Random random) {
|
||||
if (random.nextInt(16) == 0 && !canStay(state, world, pos)) {
|
||||
world.setBlockAndUpdate(pos, Blocks.END_STONE.defaultBlockState());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canStay(BlockState state, LevelReader worldView, BlockPos pos) {
|
||||
BlockPos blockPos = pos.above();
|
||||
BlockState blockState = worldView.getBlockState(blockPos);
|
||||
if (blockState.is(Blocks.SNOW) && blockState.getValue(SnowLayerBlock.LAYERS) == 1) {
|
||||
return true;
|
||||
}
|
||||
else if (blockState.getFluidState().getAmount() == 8) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
int i = LayerLightEngine.getLightBlockInto(worldView, state, pos, blockState, blockPos, Direction.UP, blockState.getLightBlock(worldView, blockPos));
|
||||
return i < 5;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public BlockModel getItemModel(ResourceLocation blockId) {
|
||||
return getBlockModel(blockId, defaultBlockState());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public @Nullable BlockModel getBlockModel(ResourceLocation blockId, BlockState blockState) {
|
||||
ResourceLocation baseId = Registry.BLOCK.getKey(baseBlock);
|
||||
String modId = blockId.getNamespace();
|
||||
String path = blockId.getPath();
|
||||
String bottom = baseId.getNamespace() + ":block/" + baseId.getPath();
|
||||
Map<String, String> textures = Maps.newHashMap();
|
||||
textures.put("%top%", modId + ":block/" + path + "_top");
|
||||
textures.put("%side%", modId + ":block/" + path + "_side");
|
||||
textures.put("%bottom%", bottom);
|
||||
Optional<String> pattern = PatternsHelper.createJson(BasePatterns.BLOCK_TOP_SIDE_BOTTOM, textures);
|
||||
return ModelsHelper.fromPattern(pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
|
||||
ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(), "block/" + stateId.getPath());
|
||||
registerBlockModel(stateId, modelId, blockState, modelCache);
|
||||
return ModelsHelper.createRandomTopModel(modelId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,88 +1,95 @@
|
|||
package ru.bclib.blocks;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.client.resources.model.BlockModelRotation;
|
||||
import net.minecraft.client.resources.model.UnbakedModel;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.TrapDoorBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.properties.Half;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import ru.bclib.client.models.BasePatterns;
|
||||
import ru.bclib.client.models.BlockModelProvider;
|
||||
import ru.bclib.client.models.ModelsHelper;
|
||||
import ru.bclib.client.models.PatternsHelper;
|
||||
import ru.bclib.client.render.ERenderLayer;
|
||||
import ru.bclib.interfaces.IRenderTyped;
|
||||
|
||||
public class BaseTrapdoorBlock extends TrapDoorBlock implements IRenderTyped, BlockModelProvider {
|
||||
public BaseTrapdoorBlock(Block source) {
|
||||
super(FabricBlockSettings.copyOf(source).strength(3.0F, 3.0F).noOcclusion());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
return Collections.singletonList(new ItemStack(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ERenderLayer getRenderLayer() {
|
||||
return ERenderLayer.CUTOUT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockModel getItemModel(ResourceLocation resourceLocation) {
|
||||
return getBlockModel(resourceLocation, defaultBlockState());
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) {
|
||||
String name = resourceLocation.getPath();
|
||||
Optional<String> pattern = PatternsHelper.createJson(BasePatterns.BLOCK_TRAPDOOR, new HashMap<String, String>() {
|
||||
private static final long serialVersionUID = 1L;
|
||||
{
|
||||
put("%texture%", name);
|
||||
put("%side%", name.replace("trapdoor", "door_side"));
|
||||
}
|
||||
});
|
||||
return ModelsHelper.fromPattern(pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
|
||||
ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(), "block/" + stateId.getPath());
|
||||
registerBlockModel(stateId, modelId, blockState, modelCache);
|
||||
boolean isTop = blockState.getValue(HALF) == Half.TOP;
|
||||
boolean isOpen = blockState.getValue(OPEN);
|
||||
int y = 0;
|
||||
int x = (isTop && isOpen) ? 270 : isTop ? 180 : isOpen ? 90 : 0;
|
||||
switch (blockState.getValue(FACING)) {
|
||||
case EAST:
|
||||
y = (isTop && isOpen) ? 270 : 90;
|
||||
break;
|
||||
case NORTH:
|
||||
if (isTop && isOpen) y = 180;
|
||||
break;
|
||||
case SOUTH:
|
||||
y = (isTop && isOpen) ? 0 : 180;
|
||||
break;
|
||||
case WEST:
|
||||
y = (isTop && isOpen) ? 90 : 270;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
BlockModelRotation rotation = BlockModelRotation.by(x, y);
|
||||
return ModelsHelper.createMultiVariant(modelId, rotation.getRotation(), false);
|
||||
}
|
||||
}
|
||||
package ru.bclib.blocks;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.client.resources.model.BlockModelRotation;
|
||||
import net.minecraft.client.resources.model.UnbakedModel;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.TrapDoorBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.properties.Half;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import ru.bclib.client.models.BasePatterns;
|
||||
import ru.bclib.client.models.BlockModelProvider;
|
||||
import ru.bclib.client.models.ModelsHelper;
|
||||
import ru.bclib.client.models.PatternsHelper;
|
||||
import ru.bclib.client.render.BCLRenderLayer;
|
||||
import ru.bclib.interfaces.IRenderTyped;
|
||||
|
||||
public class BaseTrapdoorBlock extends TrapDoorBlock implements IRenderTyped, BlockModelProvider {
|
||||
public BaseTrapdoorBlock(Block source) {
|
||||
super(FabricBlockSettings.copyOf(source).strength(3.0F, 3.0F).noOcclusion());
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
return Collections.singletonList(new ItemStack(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BCLRenderLayer getRenderLayer() {
|
||||
return BCLRenderLayer.CUTOUT;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public BlockModel getItemModel(ResourceLocation resourceLocation) {
|
||||
return getBlockModel(resourceLocation, defaultBlockState());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) {
|
||||
String name = resourceLocation.getPath();
|
||||
Optional<String> pattern = PatternsHelper.createJson(BasePatterns.BLOCK_TRAPDOOR, new HashMap<String, String>() {
|
||||
private static final long serialVersionUID = 1L;
|
||||
{
|
||||
put("%modid%", resourceLocation.getNamespace());
|
||||
put("%texture%", name);
|
||||
put("%side%", name.replace("trapdoor", "door_side"));
|
||||
}
|
||||
});
|
||||
return ModelsHelper.fromPattern(pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
|
||||
ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(), "block/" + stateId.getPath());
|
||||
registerBlockModel(stateId, modelId, blockState, modelCache);
|
||||
boolean isTop = blockState.getValue(HALF) == Half.TOP;
|
||||
boolean isOpen = blockState.getValue(OPEN);
|
||||
int y = 0;
|
||||
int x = (isTop && isOpen) ? 270 : isTop ? 180 : isOpen ? 90 : 0;
|
||||
switch (blockState.getValue(FACING)) {
|
||||
case EAST:
|
||||
y = (isTop && isOpen) ? 270 : 90;
|
||||
break;
|
||||
case NORTH:
|
||||
if (isTop && isOpen) y = 180;
|
||||
break;
|
||||
case SOUTH:
|
||||
y = (isTop && isOpen) ? 0 : 180;
|
||||
break;
|
||||
case WEST:
|
||||
y = (isTop && isOpen) ? 90 : 270;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
BlockModelRotation rotation = BlockModelRotation.by(x, y);
|
||||
return ModelsHelper.createMultiVariant(modelId, rotation.getRotation(), false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ public abstract class BaseUnderwaterWallPlantBlock extends BaseWallPlantBlock im
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public FluidState getFluidState(BlockState state) {
|
||||
return Fluids.WATER.getSource(false);
|
||||
}
|
||||
|
|
|
@ -1,146 +1,147 @@
|
|||
package ru.bclib.blocks;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.world.item.enchantment.Enchantments;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.LevelReader;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.BonemealableBlock;
|
||||
import net.minecraft.world.level.block.SoundType;
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.block.state.properties.EnumProperty;
|
||||
import net.minecraft.world.level.material.Material;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import ru.bclib.blocks.BlockProperties.TripleShape;
|
||||
import ru.bclib.client.render.ERenderLayer;
|
||||
import ru.bclib.interfaces.IRenderTyped;
|
||||
import ru.bclib.util.BlocksHelper;
|
||||
|
||||
public class VineBlock extends BaseBlockNotFull implements IRenderTyped, BonemealableBlock {
|
||||
public static final EnumProperty<TripleShape> SHAPE = BlockProperties.TRIPLE_SHAPE;
|
||||
private static final VoxelShape VOXEL_SHAPE = Block.box(2, 0, 2, 14, 16, 14);
|
||||
|
||||
public VineBlock() {
|
||||
this(0, false);
|
||||
}
|
||||
|
||||
public VineBlock(int light) {
|
||||
this(light, false);
|
||||
}
|
||||
|
||||
public VineBlock(int light, boolean bottomOnly) {
|
||||
super(FabricBlockSettings.of(Material.PLANT)
|
||||
.breakByTool(FabricToolTags.SHEARS)
|
||||
.breakByHand(true)
|
||||
.sound(SoundType.GRASS)
|
||||
.lightLevel((state) -> bottomOnly ? state.getValue(SHAPE) == TripleShape.BOTTOM ? light : 0 : light)
|
||||
.noCollission());
|
||||
this.registerDefaultState(this.stateDefinition.any().setValue(SHAPE, TripleShape.BOTTOM));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> stateManager) {
|
||||
stateManager.add(SHAPE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) {
|
||||
Vec3 vec3d = state.getOffset(view, pos);
|
||||
return VOXEL_SHAPE.move(vec3d.x, vec3d.y, vec3d.z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockBehaviour.OffsetType getOffsetType() {
|
||||
return BlockBehaviour.OffsetType.XZ;
|
||||
}
|
||||
|
||||
public boolean canGenerate(BlockState state, LevelReader world, BlockPos pos) {
|
||||
return isSupport(state, world, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) {
|
||||
return isSupport(state, world, pos);
|
||||
}
|
||||
|
||||
protected boolean isSupport(BlockState state, LevelReader world, BlockPos pos) {
|
||||
BlockState up = world.getBlockState(pos.above());
|
||||
return up.is(this) || up.is(BlockTags.LEAVES) || canSupportCenter(world, pos.above(), Direction.DOWN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState updateShape(BlockState state, Direction facing, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) {
|
||||
if (!canSurvive(state, world, pos)) {
|
||||
return Blocks.AIR.defaultBlockState();
|
||||
}
|
||||
else {
|
||||
if (world.getBlockState(pos.below()).getBlock() != this)
|
||||
return state.setValue(SHAPE, TripleShape.BOTTOM);
|
||||
else if (world.getBlockState(pos.above()).getBlock() != this)
|
||||
return state.setValue(SHAPE, TripleShape.TOP);
|
||||
return state.setValue(SHAPE, TripleShape.MIDDLE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
ItemStack tool = builder.getParameter(LootContextParams.TOOL);
|
||||
if (tool != null && tool.getItem().is(FabricToolTags.SHEARS) || EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0) {
|
||||
return Lists.newArrayList(new ItemStack(this));
|
||||
}
|
||||
else {
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ERenderLayer getRenderLayer() {
|
||||
return ERenderLayer.CUTOUT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidBonemealTarget(BlockGetter world, BlockPos pos, BlockState state, boolean isClient) {
|
||||
while (world.getBlockState(pos).getBlock() == this) {
|
||||
pos = pos.below();
|
||||
}
|
||||
return world.getBlockState(pos).isAir();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBonemealSuccess(Level world, Random random, BlockPos pos, BlockState state) {
|
||||
while (world.getBlockState(pos).getBlock() == this) {
|
||||
pos = pos.below();
|
||||
}
|
||||
return world.isEmptyBlock(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performBonemeal(ServerLevel world, Random random, BlockPos pos, BlockState state) {
|
||||
while (world.getBlockState(pos).getBlock() == this) {
|
||||
pos = pos.below();
|
||||
}
|
||||
world.setBlockAndUpdate(pos, defaultBlockState());
|
||||
BlocksHelper.setWithoutUpdate(world, pos, defaultBlockState());
|
||||
}
|
||||
}
|
||||
package ru.bclib.blocks;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.world.item.enchantment.Enchantments;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.LevelReader;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.BonemealableBlock;
|
||||
import net.minecraft.world.level.block.SoundType;
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.block.state.properties.EnumProperty;
|
||||
import net.minecraft.world.level.material.Material;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import ru.bclib.blocks.BlockProperties.TripleShape;
|
||||
import ru.bclib.client.render.BCLRenderLayer;
|
||||
import ru.bclib.interfaces.IRenderTyped;
|
||||
import ru.bclib.util.BlocksHelper;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class BaseVineBlock extends BaseBlockNotFull implements IRenderTyped, BonemealableBlock {
|
||||
public static final EnumProperty<TripleShape> SHAPE = BlockProperties.TRIPLE_SHAPE;
|
||||
private static final VoxelShape VOXEL_SHAPE = Block.box(2, 0, 2, 14, 16, 14);
|
||||
|
||||
public BaseVineBlock() {
|
||||
this(0, false);
|
||||
}
|
||||
|
||||
public BaseVineBlock(int light) {
|
||||
this(light, false);
|
||||
}
|
||||
|
||||
public BaseVineBlock(int light, boolean bottomOnly) {
|
||||
super(FabricBlockSettings.of(Material.PLANT)
|
||||
.breakByTool(FabricToolTags.SHEARS)
|
||||
.breakByHand(true)
|
||||
.sound(SoundType.GRASS)
|
||||
.lightLevel((state) -> bottomOnly ? state.getValue(SHAPE) == TripleShape.BOTTOM ? light : 0 : light)
|
||||
.noCollission());
|
||||
this.registerDefaultState(this.stateDefinition.any().setValue(SHAPE, TripleShape.BOTTOM));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> stateManager) {
|
||||
stateManager.add(SHAPE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) {
|
||||
Vec3 vec3d = state.getOffset(view, pos);
|
||||
return VOXEL_SHAPE.move(vec3d.x, vec3d.y, vec3d.z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockBehaviour.OffsetType getOffsetType() {
|
||||
return BlockBehaviour.OffsetType.XZ;
|
||||
}
|
||||
|
||||
public boolean canGenerate(BlockState state, LevelReader world, BlockPos pos) {
|
||||
return isSupport(state, world, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) {
|
||||
return isSupport(state, world, pos);
|
||||
}
|
||||
|
||||
protected boolean isSupport(BlockState state, LevelReader world, BlockPos pos) {
|
||||
BlockState up = world.getBlockState(pos.above());
|
||||
return up.is(this) || up.is(BlockTags.LEAVES) || canSupportCenter(world, pos.above(), Direction.DOWN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState updateShape(BlockState state, Direction facing, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) {
|
||||
if (!canSurvive(state, world, pos)) {
|
||||
return Blocks.AIR.defaultBlockState();
|
||||
}
|
||||
else {
|
||||
if (world.getBlockState(pos.below()).getBlock() != this)
|
||||
return state.setValue(SHAPE, TripleShape.BOTTOM);
|
||||
else if (world.getBlockState(pos.above()).getBlock() != this)
|
||||
return state.setValue(SHAPE, TripleShape.TOP);
|
||||
return state.setValue(SHAPE, TripleShape.MIDDLE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
ItemStack tool = builder.getParameter(LootContextParams.TOOL);
|
||||
if (tool != null && FabricToolTags.SHEARS.contains(tool.getItem()) || EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0) {
|
||||
return Lists.newArrayList(new ItemStack(this));
|
||||
}
|
||||
else {
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BCLRenderLayer getRenderLayer() {
|
||||
return BCLRenderLayer.CUTOUT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidBonemealTarget(BlockGetter world, BlockPos pos, BlockState state, boolean isClient) {
|
||||
while (world.getBlockState(pos).getBlock() == this) {
|
||||
pos = pos.below();
|
||||
}
|
||||
return world.getBlockState(pos).isAir();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBonemealSuccess(Level world, Random random, BlockPos pos, BlockState state) {
|
||||
while (world.getBlockState(pos).getBlock() == this) {
|
||||
pos = pos.below();
|
||||
}
|
||||
return world.isEmptyBlock(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performBonemeal(ServerLevel world, Random random, BlockPos pos, BlockState state) {
|
||||
while (world.getBlockState(pos).getBlock() == this) {
|
||||
pos = pos.below();
|
||||
}
|
||||
world.setBlockAndUpdate(pos, defaultBlockState());
|
||||
BlocksHelper.setWithoutUpdate(world, pos, defaultBlockState());
|
||||
}
|
||||
}
|
|
@ -7,6 +7,8 @@ import java.util.Optional;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.client.resources.model.BlockModelRotation;
|
||||
|
@ -34,11 +36,13 @@ public class BaseWallBlock extends WallBlock implements BlockModelProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
return Collections.singletonList(new ItemStack(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public BlockModel getItemModel(ResourceLocation blockId) {
|
||||
ResourceLocation parentId = Registry.BLOCK.getKey(parent);
|
||||
Optional<String> pattern = PatternsHelper.createJson(BasePatterns.ITEM_WALL, parentId);
|
||||
|
@ -46,6 +50,7 @@ public class BaseWallBlock extends WallBlock implements BlockModelProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public @Nullable BlockModel getBlockModel(ResourceLocation blockId, BlockState blockState) {
|
||||
ResourceLocation parentId = Registry.BLOCK.getKey(parent);
|
||||
String path = blockId.getPath();
|
||||
|
@ -63,6 +68,7 @@ public class BaseWallBlock extends WallBlock implements BlockModelProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
|
||||
ResourceLocation postId = new ResourceLocation(stateId.getNamespace(),
|
||||
"block/" + stateId.getPath() + "_post");
|
||||
|
|
|
@ -113,11 +113,13 @@ public abstract class BaseWallPlantBlock extends BasePlantBlock {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState rotate(BlockState state, Rotation rotation) {
|
||||
return BlocksHelper.rotateHorizontal(state, rotation, FACING);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public BlockState mirror(BlockState state, Mirror mirror) {
|
||||
return BlocksHelper.mirrorHorizontal(state, mirror, FACING);
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@ import java.util.Optional;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.client.resources.model.UnbakedModel;
|
||||
|
@ -31,16 +33,19 @@ public class BaseWeightedPlateBlock extends WeightedPressurePlateBlock implement
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
return Collections.singletonList(new ItemStack(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public BlockModel getItemModel(ResourceLocation resourceLocation) {
|
||||
return getBlockModel(resourceLocation, defaultBlockState());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) {
|
||||
ResourceLocation parentId = Registry.BLOCK.getKey(parent);
|
||||
Optional<String> pattern;
|
||||
|
@ -53,6 +58,7 @@ public class BaseWeightedPlateBlock extends WeightedPressurePlateBlock implement
|
|||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
|
||||
String state = blockState.getValue(POWER) > 0 ? "_down" : "_up";
|
||||
ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(),
|
||||
|
|
|
@ -6,7 +6,6 @@ import net.minecraft.world.level.block.state.properties.EnumProperty;
|
|||
import net.minecraft.world.level.block.state.properties.IntegerProperty;
|
||||
|
||||
public class BlockProperties {
|
||||
public static final EnumProperty<CactusBottom> CACTUS_BOTTOM = EnumProperty.create("bottom", CactusBottom.class);
|
||||
public static final EnumProperty<TripleShape> TRIPLE_SHAPE = EnumProperty.create("shape", TripleShape.class);
|
||||
public static final EnumProperty<PentaShape> PENTA_SHAPE = EnumProperty.create("shape", PentaShape.class);
|
||||
|
||||
|
@ -17,7 +16,6 @@ public class BlockProperties {
|
|||
public static final BooleanProperty ACTIVE = BooleanProperty.create("active");
|
||||
public static final BooleanProperty SMALL = BooleanProperty.create("small");
|
||||
|
||||
public static final IntegerProperty DESTRUCTION_LONG = IntegerProperty.create("destruction", 0, 8);
|
||||
public static final IntegerProperty DESTRUCTION = IntegerProperty.create("destruction", 0, 2);
|
||||
public static final IntegerProperty ROTATION = IntegerProperty.create("rotation", 0, 3);
|
||||
public static final IntegerProperty FULLNESS = IntegerProperty.create("fullness", 0, 3);
|
||||
|
@ -80,26 +78,4 @@ public class BlockProperties {
|
|||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
public enum CactusBottom implements StringRepresentable {
|
||||
EMPTY("empty"),
|
||||
SAND("sand"),
|
||||
MOSS("moss");
|
||||
|
||||
private final String name;
|
||||
|
||||
CactusBottom(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSerializedName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,11 @@ import java.util.List;
|
|||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
@ -31,9 +34,10 @@ import ru.bclib.client.models.BasePatterns;
|
|||
import ru.bclib.client.models.BlockModelProvider;
|
||||
import ru.bclib.client.models.ModelsHelper;
|
||||
import ru.bclib.client.models.PatternsHelper;
|
||||
import ru.bclib.client.render.ERenderLayer;
|
||||
import ru.bclib.client.render.BCLRenderLayer;
|
||||
import ru.bclib.interfaces.IRenderTyped;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public abstract class FeatureSaplingBlock extends SaplingBlock implements IRenderTyped, BlockModelProvider {
|
||||
private static final VoxelShape SHAPE = Block.box(4, 0, 4, 12, 14, 12);
|
||||
|
||||
|
@ -83,7 +87,8 @@ public abstract class FeatureSaplingBlock extends SaplingBlock implements IRende
|
|||
|
||||
@Override
|
||||
public void advanceTree(ServerLevel world, BlockPos pos, BlockState blockState, Random random) {
|
||||
getFeature().place(world, world.getChunkSource().getGenerator(), random, pos, null);
|
||||
FeaturePlaceContext context = new FeaturePlaceContext(world, world.getChunkSource().getGenerator(), random, pos, null);
|
||||
getFeature().place(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -100,16 +105,18 @@ public abstract class FeatureSaplingBlock extends SaplingBlock implements IRende
|
|||
}
|
||||
|
||||
@Override
|
||||
public ERenderLayer getRenderLayer() {
|
||||
return ERenderLayer.CUTOUT;
|
||||
public BCLRenderLayer getRenderLayer() {
|
||||
return BCLRenderLayer.CUTOUT;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public BlockModel getItemModel(ResourceLocation resourceLocation) {
|
||||
return ModelsHelper.createBlockItem(resourceLocation);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) {
|
||||
Optional<String> pattern = PatternsHelper.createJson(BasePatterns.BLOCK_CROSS, resourceLocation);
|
||||
return ModelsHelper.fromPattern(pattern);
|
||||
|
|
|
@ -4,14 +4,14 @@ import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
|||
import net.minecraft.world.level.block.SoundType;
|
||||
import net.minecraft.world.level.material.Material;
|
||||
import net.minecraft.world.level.material.MaterialColor;
|
||||
import ru.bclib.client.render.ERenderLayer;
|
||||
import ru.bclib.client.render.BCLRenderLayer;
|
||||
import ru.bclib.interfaces.IRenderTyped;
|
||||
|
||||
public class SimpleLeavesBlock extends BaseBlockNotFull implements IRenderTyped {
|
||||
public SimpleLeavesBlock(MaterialColor color) {
|
||||
super(FabricBlockSettings.of(Material.LEAVES)
|
||||
.strength(0.2F)
|
||||
.materialColor(color)
|
||||
.mapColor(color)
|
||||
.sound(SoundType.GRASS)
|
||||
.noOcclusion()
|
||||
.isValidSpawn((state, world, pos, type) -> false)
|
||||
|
@ -22,7 +22,7 @@ public class SimpleLeavesBlock extends BaseBlockNotFull implements IRenderTyped
|
|||
public SimpleLeavesBlock(MaterialColor color, int light) {
|
||||
super(FabricBlockSettings.of(Material.LEAVES)
|
||||
.luminance(light)
|
||||
.materialColor(color)
|
||||
.mapColor(color)
|
||||
.strength(0.2F)
|
||||
.sound(SoundType.GRASS)
|
||||
.noOcclusion()
|
||||
|
@ -32,7 +32,7 @@ public class SimpleLeavesBlock extends BaseBlockNotFull implements IRenderTyped
|
|||
}
|
||||
|
||||
@Override
|
||||
public ERenderLayer getRenderLayer() {
|
||||
return ERenderLayer.CUTOUT;
|
||||
public BCLRenderLayer getRenderLayer() {
|
||||
return BCLRenderLayer.CUTOUT;
|
||||
}
|
||||
}
|
|
@ -5,6 +5,8 @@ import java.util.Optional;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.client.resources.model.BlockModelRotation;
|
||||
|
@ -38,9 +40,10 @@ import net.minecraft.world.phys.shapes.VoxelShape;
|
|||
import ru.bclib.client.models.BasePatterns;
|
||||
import ru.bclib.client.models.ModelsHelper;
|
||||
import ru.bclib.client.models.PatternsHelper;
|
||||
import ru.bclib.client.render.ERenderLayer;
|
||||
import ru.bclib.client.render.BCLRenderLayer;
|
||||
import ru.bclib.interfaces.IRenderTyped;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class StalactiteBlock extends BaseBlockNotFull implements SimpleWaterloggedBlock, LiquidBlockContainer, IRenderTyped {
|
||||
public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
|
||||
public static final BooleanProperty IS_FLOOR = BlockProperties.IS_FLOOR;
|
||||
|
@ -200,12 +203,14 @@ public class StalactiteBlock extends BaseBlockNotFull implements SimpleWaterlogg
|
|||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) {
|
||||
Optional<String> pattern = PatternsHelper.createJson(BasePatterns.BLOCK_CROSS_SHADED, resourceLocation);
|
||||
return ModelsHelper.fromPattern(pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
|
||||
BlockModelRotation rotation = blockState.getValue(IS_FLOOR) ? BlockModelRotation.X0_Y0 : BlockModelRotation.X180_Y0;
|
||||
ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(),
|
||||
|
@ -230,8 +235,8 @@ public class StalactiteBlock extends BaseBlockNotFull implements SimpleWaterlogg
|
|||
}
|
||||
|
||||
@Override
|
||||
public ERenderLayer getRenderLayer() {
|
||||
return ERenderLayer.CUTOUT;
|
||||
public BCLRenderLayer getRenderLayer() {
|
||||
return BCLRenderLayer.CUTOUT;
|
||||
}
|
||||
|
||||
static {
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
package ru.bclib.blocks;
|
||||
|
||||
import net.minecraft.world.level.block.Block;
|
||||
|
||||
public class StonePressurePlateBlock extends BasePressurePlateBlock {
|
||||
public StonePressurePlateBlock(Block source) {
|
||||
super(Sensitivity.MOBS, source);
|
||||
}
|
||||
}
|
|
@ -1,41 +1,42 @@
|
|||
package ru.bclib.blocks;
|
||||
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
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.RotatedPillarBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.material.MaterialColor;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
|
||||
public class StrippableBarkBlock extends BaseBarkBlock {
|
||||
private final Block striped;
|
||||
|
||||
public StrippableBarkBlock(MaterialColor color, Block striped) {
|
||||
super(FabricBlockSettings.copyOf(striped).materialColor(color));
|
||||
this.striped = striped;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
|
||||
if (player.getMainHandItem().getItem().is(FabricToolTags.AXES)) {
|
||||
world.playSound(player, pos, SoundEvents.AXE_STRIP, SoundSource.BLOCKS, 1.0F, 1.0F);
|
||||
if (!world.isClientSide) {
|
||||
world.setBlock(pos, striped.defaultBlockState().setValue(RotatedPillarBlock.AXIS, state.getValue(RotatedPillarBlock.AXIS)), 11);
|
||||
if (!player.isCreative()) {
|
||||
player.getMainHandItem().hurt(1, world.random, (ServerPlayer) player);
|
||||
}
|
||||
}
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
}
|
||||
package ru.bclib.blocks;
|
||||
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
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.RotatedPillarBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.material.MaterialColor;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
|
||||
public class StripableBarkBlock extends BaseBarkBlock {
|
||||
private final Block striped;
|
||||
|
||||
public StripableBarkBlock(MaterialColor color, Block striped) {
|
||||
super(FabricBlockSettings.copyOf(striped).mapColor(color));
|
||||
this.striped = striped;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
|
||||
if (FabricToolTags.AXES.contains(player.getMainHandItem().getItem())) {
|
||||
world.playSound(player, pos, SoundEvents.AXE_STRIP, SoundSource.BLOCKS, 1.0F, 1.0F);
|
||||
if (!world.isClientSide) {
|
||||
world.setBlock(pos, striped.defaultBlockState().setValue(RotatedPillarBlock.AXIS, state.getValue(RotatedPillarBlock.AXIS)), 11);
|
||||
if (!player.isCreative()) {
|
||||
player.getMainHandItem().hurt(1, world.random, (ServerPlayer) player);
|
||||
}
|
||||
}
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
}
|
|
@ -1,155 +1,165 @@
|
|||
package ru.bclib.blocks;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.client.renderer.block.model.MultiVariant;
|
||||
import net.minecraft.client.renderer.block.model.Variant;
|
||||
import net.minecraft.client.resources.model.BlockModelRotation;
|
||||
import net.minecraft.client.resources.model.UnbakedModel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelReader;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.block.state.properties.EnumProperty;
|
||||
import net.minecraft.world.level.material.MaterialColor;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import ru.bclib.blocks.BlockProperties.TripleShape;
|
||||
import ru.bclib.client.models.BasePatterns;
|
||||
import ru.bclib.client.models.ModelsHelper;
|
||||
import ru.bclib.client.models.PatternsHelper;
|
||||
|
||||
public class TripleTerrainBlock extends BaseTerrainBlock {
|
||||
public static final EnumProperty<TripleShape> SHAPE = BlockProperties.TRIPLE_SHAPE;
|
||||
|
||||
public TripleTerrainBlock(Block baseBlock, MaterialColor color) {
|
||||
super(baseBlock, color);
|
||||
this.registerDefaultState(defaultBlockState().setValue(SHAPE, TripleShape.BOTTOM));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> stateManager) {
|
||||
stateManager.add(SHAPE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockPlaceContext ctx) {
|
||||
Direction dir = ctx.getClickedFace();
|
||||
TripleShape shape = dir == Direction.UP ? TripleShape.BOTTOM : dir == Direction.DOWN ? TripleShape.TOP : TripleShape.MIDDLE;
|
||||
return defaultBlockState().setValue(SHAPE, shape);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
|
||||
TripleShape shape = state.getValue(SHAPE);
|
||||
if (shape == TripleShape.BOTTOM) {
|
||||
return super.use(state, world, pos, player, hand, hit);
|
||||
}
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void randomTick(BlockState state, ServerLevel world, BlockPos pos, Random random) {
|
||||
TripleShape shape = state.getValue(SHAPE);
|
||||
if (shape == TripleShape.BOTTOM) {
|
||||
super.randomTick(state, world, pos, random);
|
||||
} else if (random.nextInt(16) == 0) {
|
||||
boolean bottom = canStayBottom(world, pos);
|
||||
if (shape == TripleShape.TOP) {
|
||||
if (!bottom) {
|
||||
world.setBlockAndUpdate(pos, Blocks.END_STONE.defaultBlockState());
|
||||
}
|
||||
}
|
||||
else {
|
||||
boolean top = canStay(state, world, pos) || isMiddle(world.getBlockState(pos.above()));
|
||||
if (!top && !bottom) {
|
||||
world.setBlockAndUpdate(pos, Blocks.END_STONE.defaultBlockState());
|
||||
} else if (top && !bottom) {
|
||||
world.setBlockAndUpdate(pos, state.setValue(SHAPE, TripleShape.BOTTOM));
|
||||
} else if (!top) {
|
||||
world.setBlockAndUpdate(pos, state.setValue(SHAPE, TripleShape.TOP));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean canStayBottom(LevelReader world, BlockPos pos) {
|
||||
BlockPos blockPos = pos.below();
|
||||
BlockState blockState = world.getBlockState(blockPos);
|
||||
if (isMiddle(blockState)) {
|
||||
return true;
|
||||
} else if (blockState.getFluidState().getAmount() == 8) {
|
||||
return false;
|
||||
} else {
|
||||
return !blockState.isFaceSturdy(world, blockPos, Direction.UP);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockModel getItemModel(ResourceLocation blockId) {
|
||||
return getBlockModel(blockId, defaultBlockState());
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable BlockModel getBlockModel(ResourceLocation blockId, BlockState blockState) {
|
||||
String path = blockId.getPath();
|
||||
Optional<String> pattern;
|
||||
if (isMiddle(blockState)) {
|
||||
ResourceLocation topId = new ResourceLocation(blockId.getNamespace(), path + "_top");
|
||||
pattern = PatternsHelper.createBlockSimple(topId);
|
||||
} else {
|
||||
Map<String, String> textures = Maps.newHashMap();
|
||||
textures.put("%top%", "betterend:block/" + path + "_top");
|
||||
textures.put("%side%", "betterend:block/" + path + "_side");
|
||||
textures.put("%bottom%", "minecraft:block/end_stone");
|
||||
pattern = PatternsHelper.createJson(BasePatterns.BLOCK_TOP_SIDE_BOTTOM, textures);
|
||||
}
|
||||
return ModelsHelper.fromPattern(pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
|
||||
boolean isMiddle = isMiddle(blockState);
|
||||
String middle = isMiddle ? "_middle" : "";
|
||||
ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(),
|
||||
"block/" + stateId.getPath() + middle);
|
||||
registerBlockModel(stateId, modelId, blockState, modelCache);
|
||||
if (isMiddle) {
|
||||
List<Variant> variants = Lists.newArrayList();
|
||||
for (BlockModelRotation rotation : BlockModelRotation.values()) {
|
||||
variants.add(new Variant(modelId, rotation.getRotation(), false, 1));
|
||||
}
|
||||
return new MultiVariant(variants);
|
||||
} else if (blockState.getValue(SHAPE) == TripleShape.TOP) {
|
||||
return new MultiVariant(Lists.newArrayList(
|
||||
new Variant(modelId, BlockModelRotation.X180_Y0.getRotation(), false, 1),
|
||||
new Variant(modelId, BlockModelRotation.X180_Y90.getRotation(), false, 1),
|
||||
new Variant(modelId, BlockModelRotation.X180_Y180.getRotation(), false, 1),
|
||||
new Variant(modelId, BlockModelRotation.X180_Y270.getRotation(), false, 1)
|
||||
));
|
||||
}
|
||||
return ModelsHelper.createRandomTopModel(modelId);
|
||||
}
|
||||
|
||||
protected boolean isMiddle(BlockState blockState) {
|
||||
return blockState.is(this) && blockState.getValue(SHAPE) == TripleShape.MIDDLE;
|
||||
}
|
||||
}
|
||||
package ru.bclib.blocks;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.client.renderer.block.model.MultiVariant;
|
||||
import net.minecraft.client.renderer.block.model.Variant;
|
||||
import net.minecraft.client.resources.model.BlockModelRotation;
|
||||
import net.minecraft.client.resources.model.UnbakedModel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelReader;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.block.state.properties.EnumProperty;
|
||||
import net.minecraft.world.level.material.MaterialColor;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import ru.bclib.blocks.BlockProperties.TripleShape;
|
||||
import ru.bclib.client.models.BasePatterns;
|
||||
import ru.bclib.client.models.ModelsHelper;
|
||||
import ru.bclib.client.models.PatternsHelper;
|
||||
|
||||
public class TripleTerrainBlock extends BaseTerrainBlock {
|
||||
public static final EnumProperty<TripleShape> SHAPE = BlockProperties.TRIPLE_SHAPE;
|
||||
|
||||
public TripleTerrainBlock(Block baseBlock) {
|
||||
super(baseBlock, baseBlock.defaultMaterialColor());
|
||||
this.registerDefaultState(defaultBlockState().setValue(SHAPE, TripleShape.BOTTOM));
|
||||
}
|
||||
|
||||
public TripleTerrainBlock(Block baseBlock, MaterialColor color) {
|
||||
super(baseBlock, color);
|
||||
this.registerDefaultState(defaultBlockState().setValue(SHAPE, TripleShape.BOTTOM));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> stateManager) {
|
||||
stateManager.add(SHAPE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockPlaceContext ctx) {
|
||||
Direction dir = ctx.getClickedFace();
|
||||
TripleShape shape = dir == Direction.UP ? TripleShape.BOTTOM : dir == Direction.DOWN ? TripleShape.TOP : TripleShape.MIDDLE;
|
||||
return defaultBlockState().setValue(SHAPE, shape);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
|
||||
TripleShape shape = state.getValue(SHAPE);
|
||||
if (shape == TripleShape.BOTTOM) {
|
||||
return super.use(state, world, pos, player, hand, hit);
|
||||
}
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void randomTick(BlockState state, ServerLevel world, BlockPos pos, Random random) {
|
||||
TripleShape shape = state.getValue(SHAPE);
|
||||
if (shape == TripleShape.BOTTOM) {
|
||||
super.randomTick(state, world, pos, random);
|
||||
} else if (random.nextInt(16) == 0) {
|
||||
boolean bottom = canStayBottom(world, pos);
|
||||
if (shape == TripleShape.TOP) {
|
||||
if (!bottom) {
|
||||
world.setBlockAndUpdate(pos, Blocks.END_STONE.defaultBlockState());
|
||||
}
|
||||
}
|
||||
else {
|
||||
boolean top = canStay(state, world, pos) || isMiddle(world.getBlockState(pos.above()));
|
||||
if (!top && !bottom) {
|
||||
world.setBlockAndUpdate(pos, Blocks.END_STONE.defaultBlockState());
|
||||
} else if (top && !bottom) {
|
||||
world.setBlockAndUpdate(pos, state.setValue(SHAPE, TripleShape.BOTTOM));
|
||||
} else if (!top) {
|
||||
world.setBlockAndUpdate(pos, state.setValue(SHAPE, TripleShape.TOP));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean canStayBottom(LevelReader world, BlockPos pos) {
|
||||
BlockPos blockPos = pos.below();
|
||||
BlockState blockState = world.getBlockState(blockPos);
|
||||
if (isMiddle(blockState)) {
|
||||
return true;
|
||||
} else if (blockState.getFluidState().getAmount() == 8) {
|
||||
return false;
|
||||
} else {
|
||||
return !blockState.isFaceSturdy(world, blockPos, Direction.UP);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public BlockModel getItemModel(ResourceLocation blockId) {
|
||||
return getBlockModel(blockId, defaultBlockState());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public @Nullable BlockModel getBlockModel(ResourceLocation blockId, BlockState blockState) {
|
||||
String path = blockId.getPath();
|
||||
Optional<String> pattern;
|
||||
if (isMiddle(blockState)) {
|
||||
ResourceLocation topId = new ResourceLocation(blockId.getNamespace(), path + "_top");
|
||||
pattern = PatternsHelper.createBlockSimple(topId);
|
||||
} else {
|
||||
Map<String, String> textures = Maps.newHashMap();
|
||||
textures.put("%top%", "betterend:block/" + path + "_top");
|
||||
textures.put("%side%", "betterend:block/" + path + "_side");
|
||||
textures.put("%bottom%", "minecraft:block/end_stone");
|
||||
pattern = PatternsHelper.createJson(BasePatterns.BLOCK_TOP_SIDE_BOTTOM, textures);
|
||||
}
|
||||
return ModelsHelper.fromPattern(pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
|
||||
boolean isMiddle = isMiddle(blockState);
|
||||
String middle = isMiddle ? "_middle" : "";
|
||||
ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(),
|
||||
"block/" + stateId.getPath() + middle);
|
||||
registerBlockModel(stateId, modelId, blockState, modelCache);
|
||||
if (isMiddle) {
|
||||
List<Variant> variants = Lists.newArrayList();
|
||||
for (BlockModelRotation rotation : BlockModelRotation.values()) {
|
||||
variants.add(new Variant(modelId, rotation.getRotation(), false, 1));
|
||||
}
|
||||
return new MultiVariant(variants);
|
||||
} else if (blockState.getValue(SHAPE) == TripleShape.TOP) {
|
||||
return new MultiVariant(Lists.newArrayList(
|
||||
new Variant(modelId, BlockModelRotation.X180_Y0.getRotation(), false, 1),
|
||||
new Variant(modelId, BlockModelRotation.X180_Y90.getRotation(), false, 1),
|
||||
new Variant(modelId, BlockModelRotation.X180_Y180.getRotation(), false, 1),
|
||||
new Variant(modelId, BlockModelRotation.X180_Y270.getRotation(), false, 1)
|
||||
));
|
||||
}
|
||||
return ModelsHelper.createRandomTopModel(modelId);
|
||||
}
|
||||
|
||||
protected boolean isMiddle(BlockState blockState) {
|
||||
return blockState.is(this) && blockState.getValue(SHAPE) == TripleShape.MIDDLE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,9 +34,10 @@ import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
|||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import ru.bclib.client.render.ERenderLayer;
|
||||
import ru.bclib.client.render.BCLRenderLayer;
|
||||
import ru.bclib.interfaces.IRenderTyped;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public abstract class UnderwaterPlantBlock extends BaseBlockNotFull implements IRenderTyped, BonemealableBlock, LiquidBlockContainer {
|
||||
private static final VoxelShape SHAPE = Block.box(4, 0, 4, 12, 14, 12);
|
||||
|
||||
|
@ -95,7 +96,7 @@ public abstract class UnderwaterPlantBlock extends BaseBlockNotFull implements I
|
|||
@Override
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
ItemStack tool = builder.getParameter(LootContextParams.TOOL);
|
||||
if (tool != null && tool.getItem().is(FabricToolTags.SHEARS) || EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0) {
|
||||
if (tool != null && FabricToolTags.SHEARS.contains(tool.getItem()) || EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0) {
|
||||
return Lists.newArrayList(new ItemStack(this));
|
||||
}
|
||||
else {
|
||||
|
@ -104,8 +105,8 @@ public abstract class UnderwaterPlantBlock extends BaseBlockNotFull implements I
|
|||
}
|
||||
|
||||
@Override
|
||||
public ERenderLayer getRenderLayer() {
|
||||
return ERenderLayer.CUTOUT;
|
||||
public BCLRenderLayer getRenderLayer() {
|
||||
return BCLRenderLayer.CUTOUT;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -47,6 +47,7 @@ public abstract class UnderwaterPlantWithAgeBlock extends UnderwaterPlantBlock {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public void tick(BlockState state, ServerLevel world, BlockPos pos, Random random) {
|
||||
super.tick(state, world, pos, random);
|
||||
if (isBonemealSuccess(world, random, pos, state)) {
|
||||
|
|
|
@ -26,9 +26,10 @@ import net.minecraft.world.level.storage.loot.LootContext;
|
|||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import ru.bclib.client.render.ERenderLayer;
|
||||
import ru.bclib.client.render.BCLRenderLayer;
|
||||
import ru.bclib.interfaces.IRenderTyped;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public abstract class UpDownPlantBlock extends BaseBlockNotFull implements IRenderTyped {
|
||||
private static final VoxelShape SHAPE = Block.box(4, 0, 4, 12, 16, 12);
|
||||
|
||||
|
@ -71,7 +72,7 @@ public abstract class UpDownPlantBlock extends BaseBlockNotFull implements IRend
|
|||
@Override
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
ItemStack tool = builder.getParameter(LootContextParams.TOOL);
|
||||
if (tool != null && tool.getItem().is(FabricToolTags.SHEARS) || EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0) {
|
||||
if (tool != null && FabricToolTags.SHEARS.contains(tool.getItem()) || EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0) {
|
||||
return Lists.newArrayList(new ItemStack(this));
|
||||
}
|
||||
else {
|
||||
|
@ -80,8 +81,8 @@ public abstract class UpDownPlantBlock extends BaseBlockNotFull implements IRend
|
|||
}
|
||||
|
||||
@Override
|
||||
public ERenderLayer getRenderLayer() {
|
||||
return ERenderLayer.CUTOUT;
|
||||
public BCLRenderLayer getRenderLayer() {
|
||||
return BCLRenderLayer.CUTOUT;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
package ru.bclib.blocks;
|
||||
|
||||
import net.minecraft.world.level.block.Block;
|
||||
|
||||
public class WoodenPressurePlateBlock extends BasePressurePlateBlock {
|
||||
public WoodenPressurePlateBlock(Block source) {
|
||||
super(Sensitivity.EVERYTHING, source);
|
||||
}
|
||||
}
|
|
@ -1,11 +1,33 @@
|
|||
package ru.bclib.client;
|
||||
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.core.Registry;
|
||||
import ru.bclib.api.ModIntegrationAPI;
|
||||
import ru.bclib.client.render.BCLRenderLayer;
|
||||
import ru.bclib.interfaces.IRenderTyped;
|
||||
import ru.bclib.registry.BaseBlockEntityRenders;
|
||||
|
||||
public class BCLibClient implements ClientModInitializer {
|
||||
@Override
|
||||
public void onInitializeClient() {
|
||||
ModIntegrationAPI.registerAll();
|
||||
BaseBlockEntityRenders.register();
|
||||
registerRenderLayers();
|
||||
}
|
||||
|
||||
private void registerRenderLayers() {
|
||||
RenderType cutout = RenderType.cutout();
|
||||
RenderType translucent = RenderType.translucent();
|
||||
Registry.BLOCK.forEach(block -> {
|
||||
if (block instanceof IRenderTyped) {
|
||||
BCLRenderLayer layer = ((IRenderTyped) block).getRenderLayer();
|
||||
if (layer == BCLRenderLayer.CUTOUT)
|
||||
BlockRenderLayerMap.INSTANCE.putBlock(block, cutout);
|
||||
else if (layer == BCLRenderLayer.TRANSLUCENT)
|
||||
BlockRenderLayerMap.INSTANCE.putBlock(block, translucent);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package ru.bclib.client.gui;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.platform.Lighting;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
@ -11,8 +9,8 @@ import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
|||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.Tesselator;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import com.mojang.math.Matrix4f;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.Util;
|
||||
|
@ -20,22 +18,25 @@ import net.minecraft.client.gui.GuiComponent;
|
|||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.font.TextFieldHelper;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.model.geom.ModelLayers;
|
||||
import net.minecraft.client.multiplayer.ClientPacketListener;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.blockentity.SignRenderer.SignModel;
|
||||
import net.minecraft.client.renderer.blockentity.SignRenderer;
|
||||
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.TextComponent;
|
||||
import net.minecraft.network.chat.TranslatableComponent;
|
||||
import net.minecraft.network.protocol.game.ServerboundSignUpdatePacket;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.properties.WoodType;
|
||||
import ru.bclib.blockentities.BaseSignBlockEntity;
|
||||
import ru.bclib.blocks.BaseSignBlock;
|
||||
import ru.bclib.client.render.BaseSignBlockEntityRenderer;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class BlockSignEditScreen extends Screen {
|
||||
private final SignModel model = new SignModel();
|
||||
private final BaseSignBlockEntity sign;
|
||||
private int ticksSinceOpened;
|
||||
private int currentRow;
|
||||
|
@ -43,6 +44,7 @@ public class BlockSignEditScreen extends Screen {
|
|||
private final String[] text = (String[]) Util.make(new String[4], (strings) -> {
|
||||
Arrays.fill(strings, "");
|
||||
});
|
||||
private SignRenderer.SignModel model;
|
||||
|
||||
public BlockSignEditScreen(BaseSignBlockEntity sign) {
|
||||
super(new TranslatableComponent("sign.edit"));
|
||||
|
@ -50,8 +52,11 @@ public class BlockSignEditScreen extends Screen {
|
|||
}
|
||||
|
||||
protected void init() {
|
||||
//set up a default model
|
||||
model = new SignRenderer.SignModel(this.minecraft.getEntityModels().bakeLayer(ModelLayers.createSignModelName(WoodType.OAK)));
|
||||
|
||||
minecraft.keyboardHandler.setSendRepeatsToGui(true);
|
||||
this.addButton(new Button(this.width / 2 - 100, this.height / 4 + 120, 200, 20, CommonComponents.GUI_DONE,
|
||||
this.addRenderableWidget(new Button(this.width / 2 - 100, this.height / 4 + 120, 200, 20, CommonComponents.GUI_DONE,
|
||||
(buttonWidget) -> {
|
||||
this.finishEditing();
|
||||
}));
|
||||
|
@ -80,7 +85,7 @@ public class BlockSignEditScreen extends Screen {
|
|||
|
||||
public void tick() {
|
||||
++this.ticksSinceOpened;
|
||||
if (!this.sign.getType().isValid(this.sign.getBlockState().getBlock())) {
|
||||
if (!this.sign.getType().isValid(this.sign.getBlockState())) {
|
||||
this.finishEditing();
|
||||
}
|
||||
}
|
||||
|
@ -135,7 +140,7 @@ public class BlockSignEditScreen extends Screen {
|
|||
matrices.scale(0.6666667F, -0.6666667F, -0.6666667F);
|
||||
MultiBufferSource.BufferSource immediate = minecraft.renderBuffers().bufferSource();
|
||||
VertexConsumer vertexConsumer = BaseSignBlockEntityRenderer.getConsumer(immediate, blockState.getBlock());
|
||||
model.sign.render(matrices, vertexConsumer, 15728880, OverlayTexture.NO_OVERLAY);
|
||||
model.root.getChild("sign").render(matrices, vertexConsumer, 15728880, OverlayTexture.NO_OVERLAY);
|
||||
|
||||
if (bl) {
|
||||
model.stick.render(matrices, vertexConsumer, 15728880, OverlayTexture.NO_OVERLAY);
|
||||
|
@ -206,7 +211,7 @@ public class BlockSignEditScreen extends Screen {
|
|||
RenderSystem.disableTexture();
|
||||
RenderSystem.enableColorLogicOp();
|
||||
RenderSystem.logicOp(GlStateManager.LogicOp.OR_REVERSE);
|
||||
bufferBuilder.begin(7, DefaultVertexFormat.POSITION_COLOR);
|
||||
bufferBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR);
|
||||
float var32 = (float) x;
|
||||
bufferBuilder.vertex(matrix4f, var32, (float) (l + 9), 0.0F).color(0, 0, 255, 255).endVertex();
|
||||
var32 = (float) y;
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
package ru.bclib.client.models;
|
||||
|
||||
import net.minecraft.client.model.geom.ModelPart;
|
||||
import net.minecraft.client.model.geom.PartPose;
|
||||
import net.minecraft.client.model.geom.builders.*;
|
||||
|
||||
public class BaseChestBlockModel {
|
||||
public final ModelPart partA;
|
||||
public final ModelPart partC;
|
||||
public final ModelPart partB;
|
||||
public final ModelPart partRightA;
|
||||
public final ModelPart partRightC;
|
||||
public final ModelPart partRightB;
|
||||
public final ModelPart partLeftA;
|
||||
public final ModelPart partLeftC;
|
||||
public final ModelPart partLeftB;
|
||||
|
||||
public static LayerDefinition getTexturedModelData() {
|
||||
MeshDefinition modelData = new MeshDefinition();
|
||||
PartDefinition modelPartData = modelData.getRoot();
|
||||
CubeDeformation deformation_partC = new CubeDeformation(0.0f);
|
||||
modelPartData.addOrReplaceChild("partC", CubeListBuilder.create()
|
||||
.texOffs(0, 19)
|
||||
.addBox(1.0f, 0.0f, 1.0f, 14.0f, 9.0f, 14.0f, deformation_partC),
|
||||
PartPose.ZERO);
|
||||
|
||||
CubeDeformation deformation_partA = new CubeDeformation(0.0f);
|
||||
modelPartData.addOrReplaceChild("partA", CubeListBuilder.create()
|
||||
.texOffs(0, 0)
|
||||
.addBox(1.0f, 0.0f, 0.0f, 14.0f, 5.0f, 14.0f, deformation_partA),
|
||||
PartPose.offset(0.0f, 9.0f, 1.0f));
|
||||
|
||||
CubeDeformation deformation_partB = new CubeDeformation(0.0f);
|
||||
modelPartData.addOrReplaceChild("partB", CubeListBuilder.create()
|
||||
.texOffs(0, 0)
|
||||
.addBox(7.0f, -1.0f, 15.0f, 2.0f, 4.0f, 1.0f, deformation_partB),
|
||||
PartPose.offset(0.0f, 8.0f, 0.0f));
|
||||
|
||||
CubeDeformation deformation_partRightC = new CubeDeformation(0.0f);
|
||||
modelPartData.addOrReplaceChild("partRightC", CubeListBuilder.create()
|
||||
.texOffs(0, 19)
|
||||
.addBox(1.0f, 0.0f, 1.0f, 15.0f, 9.0f, 14.0f, deformation_partRightC),
|
||||
PartPose.ZERO);
|
||||
|
||||
CubeDeformation deformation_partRightA = new CubeDeformation(0.0f);
|
||||
modelPartData.addOrReplaceChild("partRightA", CubeListBuilder.create()
|
||||
.texOffs(0, 0)
|
||||
.addBox(1.0f, 0.0f, 0.0f, 15.0f, 5.0f, 14.0f, deformation_partRightA),
|
||||
PartPose.offset(0.0f, 9.0f, 1.0f));
|
||||
|
||||
CubeDeformation deformation_partRightB = new CubeDeformation(0.0f);
|
||||
PartDefinition partRightB = modelPartData.addOrReplaceChild("partRightB", CubeListBuilder.create()
|
||||
.texOffs(0, 0)
|
||||
.addBox(15.0f, -1.0f, 15.0f, 1.0f, 4.0f, 1.0f, deformation_partRightB),
|
||||
PartPose.offset(0.0f, 8.0f, 0.0f));
|
||||
|
||||
CubeDeformation deformation_partLeftC = new CubeDeformation(0.0f);
|
||||
modelPartData.addOrReplaceChild("partLeftC", CubeListBuilder.create()
|
||||
.texOffs(0, 19)
|
||||
.addBox(0.0f, 0.0f, 1.0f, 15.0f, 9.0f, 14.0f, deformation_partLeftC),
|
||||
PartPose.ZERO);
|
||||
|
||||
CubeDeformation deformation_partLeftA = new CubeDeformation(0.0f);
|
||||
modelPartData.addOrReplaceChild("partLeftA", CubeListBuilder.create()
|
||||
.texOffs(0, 0)
|
||||
.addBox(0.0f, 0.0f, 0.0f, 15.0f, 5.0f, 14.0f, deformation_partLeftA),
|
||||
PartPose.offset(0.0f, 9.0f, 1.0f));
|
||||
|
||||
CubeDeformation deformation_partLeftB = new CubeDeformation(0.0f);
|
||||
modelPartData.addOrReplaceChild("partLeftB", CubeListBuilder.create()
|
||||
.texOffs(0, 0)
|
||||
.addBox(0.0f, -1.0f, 15.0f, 1.0f, 4.0f, 1.0f, deformation_partLeftB),
|
||||
PartPose.offset(0.0f, 8.0f, 0.0f));
|
||||
|
||||
return LayerDefinition.create(modelData, 64, 64);
|
||||
}
|
||||
|
||||
public BaseChestBlockModel(ModelPart modelPart) {
|
||||
super();
|
||||
|
||||
partC = modelPart.getChild("partC");
|
||||
partA = modelPart.getChild("partA");
|
||||
partB = modelPart.getChild("partB");
|
||||
partRightC = modelPart.getChild("partRightC");
|
||||
partRightA = modelPart.getChild("partRightA");
|
||||
partRightB = modelPart.getChild("partRightB");
|
||||
partLeftC = modelPart.getChild("partLeftC");
|
||||
partLeftA = modelPart.getChild("partLeftA");
|
||||
partLeftB = modelPart.getChild("partLeftB");
|
||||
}
|
||||
}
|
|
@ -7,6 +7,8 @@ import java.util.Optional;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.client.resources.model.UnbakedModel;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
@ -14,17 +16,20 @@ import net.minecraft.world.level.block.state.BlockState;
|
|||
import ru.bclib.BCLib;
|
||||
|
||||
public interface BlockModelProvider extends ItemModelProvider {
|
||||
@Environment(EnvType.CLIENT)
|
||||
default @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) {
|
||||
Optional<String> pattern = PatternsHelper.createBlockSimple(resourceLocation);
|
||||
return ModelsHelper.fromPattern(pattern);
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
default UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
|
||||
ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(), "block/" + stateId.getPath());
|
||||
registerBlockModel(stateId, modelId, blockState, modelCache);
|
||||
return ModelsHelper.createBlockSimple(modelId);
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
default void registerBlockModel(ResourceLocation stateId, ResourceLocation modelId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
|
||||
if (!modelCache.containsKey(modelId)) {
|
||||
BlockModel model = getBlockModel(stateId, blockState);
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
package ru.bclib.client.models;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public interface ItemModelProvider {
|
||||
@Environment(EnvType.CLIENT)
|
||||
default BlockModel getItemModel(ResourceLocation resourceLocation) {
|
||||
return ModelsHelper.createItemModel(resourceLocation);
|
||||
}
|
||||
|
|
|
@ -67,7 +67,8 @@ public class ModelsHelper {
|
|||
BlockModelRotation rotation = BlockModelRotation.X0_Y0;
|
||||
switch (axis) {
|
||||
case X: rotation = BlockModelRotation.X90_Y90; break;
|
||||
case Z: default: rotation = BlockModelRotation.X90_Y0; break;
|
||||
case Z: rotation = BlockModelRotation.X90_Y0; break;
|
||||
default: break;
|
||||
}
|
||||
return createMultiVariant(resourceLocation, rotation.getRotation(), false);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package ru.bclib.client.render;
|
||||
|
||||
public enum ERenderLayer {
|
||||
public enum BCLRenderLayer {
|
||||
CUTOUT,
|
||||
TRANSLUCENT;
|
||||
}
|
|
@ -1,12 +1,9 @@
|
|||
package ru.bclib.client.render;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import com.mojang.math.Vector3f;
|
||||
|
||||
import it.unimi.dsi.fastutil.floats.Float2FloatFunction;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
|
||||
import net.fabricmc.api.EnvType;
|
||||
|
@ -14,28 +11,25 @@ import net.fabricmc.api.Environment;
|
|||
import net.minecraft.client.model.geom.ModelPart;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRenderDispatcher;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
|
||||
import net.minecraft.client.renderer.blockentity.BrightnessCombiner;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.AbstractChestBlock;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.ChestBlock;
|
||||
import net.minecraft.world.level.block.DoubleBlockCombiner;
|
||||
import net.minecraft.world.level.block.*;
|
||||
import net.minecraft.world.level.block.DoubleBlockCombiner.NeighborCombineResult;
|
||||
import net.minecraft.world.level.block.entity.ChestBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.LidBlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.properties.ChestType;
|
||||
import ru.bclib.blockentities.BaseChestBlockEntity;
|
||||
import ru.bclib.blocks.BaseChestBlock;
|
||||
import ru.bclib.client.models.BaseChestBlockModel;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class BaseChestBlockEntityRenderer extends BlockEntityRenderer<BaseChestBlockEntity> {
|
||||
public class BaseChestBlockEntityRenderer implements BlockEntityRenderer<BaseChestBlockEntity> {
|
||||
private static final HashMap<Block, RenderType[]> LAYERS = Maps.newHashMap();
|
||||
private static final RenderType[] defaultLayer;
|
||||
|
||||
|
@ -43,53 +37,17 @@ public class BaseChestBlockEntityRenderer extends BlockEntityRenderer<BaseChestB
|
|||
private static final int ID_LEFT = 1;
|
||||
private static final int ID_RIGHT = 2;
|
||||
|
||||
private final ModelPart partA;
|
||||
private final ModelPart partC;
|
||||
private final ModelPart partB;
|
||||
private final ModelPart partRightA;
|
||||
private final ModelPart partRightC;
|
||||
private final ModelPart partRightB;
|
||||
private final ModelPart partLeftA;
|
||||
private final ModelPart partLeftC;
|
||||
private final ModelPart partLeftB;
|
||||
|
||||
public BaseChestBlockEntityRenderer(BlockEntityRenderDispatcher blockEntityRenderDispatcher) {
|
||||
super(blockEntityRenderDispatcher);
|
||||
|
||||
this.partC = new ModelPart(64, 64, 0, 19);
|
||||
this.partC.addBox(1.0F, 0.0F, 1.0F, 14.0F, 9.0F, 14.0F, 0.0F);
|
||||
this.partA = new ModelPart(64, 64, 0, 0);
|
||||
this.partA.addBox(1.0F, 0.0F, 0.0F, 14.0F, 5.0F, 14.0F, 0.0F);
|
||||
this.partA.y = 9.0F;
|
||||
this.partA.z = 1.0F;
|
||||
this.partB = new ModelPart(64, 64, 0, 0);
|
||||
this.partB.addBox(7.0F, -1.0F, 15.0F, 2.0F, 4.0F, 1.0F, 0.0F);
|
||||
this.partB.y = 8.0F;
|
||||
this.partRightC = new ModelPart(64, 64, 0, 19);
|
||||
this.partRightC.addBox(1.0F, 0.0F, 1.0F, 15.0F, 9.0F, 14.0F, 0.0F);
|
||||
this.partRightA = new ModelPart(64, 64, 0, 0);
|
||||
this.partRightA.addBox(1.0F, 0.0F, 0.0F, 15.0F, 5.0F, 14.0F, 0.0F);
|
||||
this.partRightA.y = 9.0F;
|
||||
this.partRightA.z = 1.0F;
|
||||
this.partRightB = new ModelPart(64, 64, 0, 0);
|
||||
this.partRightB.addBox(15.0F, -1.0F, 15.0F, 1.0F, 4.0F, 1.0F, 0.0F);
|
||||
this.partRightB.y = 8.0F;
|
||||
this.partLeftC = new ModelPart(64, 64, 0, 19);
|
||||
this.partLeftC.addBox(0.0F, 0.0F, 1.0F, 15.0F, 9.0F, 14.0F, 0.0F);
|
||||
this.partLeftA = new ModelPart(64, 64, 0, 0);
|
||||
this.partLeftA.addBox(0.0F, 0.0F, 0.0F, 15.0F, 5.0F, 14.0F, 0.0F);
|
||||
this.partLeftA.y = 9.0F;
|
||||
this.partLeftA.z = 1.0F;
|
||||
this.partLeftB = new ModelPart(64, 64, 0, 0);
|
||||
this.partLeftB.addBox(0.0F, -1.0F, 15.0F, 1.0F, 4.0F, 1.0F, 0.0F);
|
||||
this.partLeftB.y = 8.0F;
|
||||
private final BaseChestBlockModel chestModel;
|
||||
public BaseChestBlockEntityRenderer(BlockEntityRendererProvider.Context ctx) {
|
||||
super();
|
||||
chestModel = new BaseChestBlockModel(BaseChestBlockModel.getTexturedModelData().bakeRoot());
|
||||
}
|
||||
|
||||
public void render(BaseChestBlockEntity entity, float tickDelta, PoseStack matrices, MultiBufferSource vertexConsumers, int light, int overlay) {
|
||||
Level world = entity.getLevel();
|
||||
boolean worldExists = world != null;
|
||||
BlockState blockState = worldExists ? entity.getBlockState() : (BlockState) Blocks.CHEST.defaultBlockState().setValue(ChestBlock.FACING, Direction.SOUTH);
|
||||
ChestType chestType = blockState.hasProperty(ChestBlock.TYPE) ? (ChestType) blockState.getValue(ChestBlock.TYPE) : ChestType.SINGLE;
|
||||
BlockState blockState = worldExists ? entity.getBlockState() : Blocks.CHEST.defaultBlockState().setValue(ChestBlock.FACING, Direction.SOUTH);
|
||||
ChestType chestType = blockState.hasProperty(ChestBlock.TYPE) ? blockState.getValue(ChestBlock.TYPE) : ChestType.SINGLE;
|
||||
Block block = blockState.getBlock();
|
||||
if (block instanceof AbstractChestBlock) {
|
||||
AbstractChestBlock<?> abstractChestBlock = (AbstractChestBlock<?>) block;
|
||||
|
@ -108,7 +66,7 @@ public class BaseChestBlockEntityRenderer extends BlockEntityRenderer<BaseChestB
|
|||
propertySource = DoubleBlockCombiner.Combiner::acceptNone;
|
||||
}
|
||||
|
||||
float pitch = ((Float2FloatFunction) propertySource.apply(ChestBlock.opennessCombiner((LidBlockEntity) entity))).get(tickDelta);
|
||||
float pitch = ((Float2FloatFunction) propertySource.apply(ChestBlock.opennessCombiner(entity))).get(tickDelta);
|
||||
pitch = 1.0F - pitch;
|
||||
pitch = 1.0F - pitch * pitch * pitch;
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
|
@ -118,12 +76,12 @@ public class BaseChestBlockEntityRenderer extends BlockEntityRenderer<BaseChestB
|
|||
|
||||
if (isDouble) {
|
||||
if (chestType == ChestType.LEFT) {
|
||||
renderParts(matrices, vertexConsumer, this.partLeftA, this.partLeftB, this.partLeftC, pitch, blockLight, overlay);
|
||||
renderParts(matrices, vertexConsumer, chestModel.partLeftA, chestModel.partLeftB, chestModel.partLeftC, pitch, blockLight, overlay);
|
||||
} else {
|
||||
renderParts(matrices, vertexConsumer, this.partRightA, this.partRightB, this.partRightC, pitch, blockLight, overlay);
|
||||
renderParts(matrices, vertexConsumer, chestModel.partRightA, chestModel.partRightB, chestModel.partRightC, pitch, blockLight, overlay);
|
||||
}
|
||||
} else {
|
||||
renderParts(matrices, vertexConsumer, this.partA, this.partB, this.partC, pitch, blockLight, overlay);
|
||||
renderParts(matrices, vertexConsumer, chestModel.partA, chestModel.partB, chestModel.partC, pitch, blockLight, overlay);
|
||||
}
|
||||
|
||||
matrices.popPose();
|
||||
|
@ -139,15 +97,11 @@ public class BaseChestBlockEntityRenderer extends BlockEntityRenderer<BaseChestB
|
|||
}
|
||||
|
||||
private static RenderType getChestTexture(ChestType type, RenderType[] layers) {
|
||||
switch (type) {
|
||||
case LEFT:
|
||||
return layers[ID_LEFT];
|
||||
case RIGHT:
|
||||
return layers[ID_RIGHT];
|
||||
case SINGLE:
|
||||
default:
|
||||
return layers[ID_NORMAL];
|
||||
}
|
||||
return switch (type) {
|
||||
case LEFT -> layers[ID_LEFT];
|
||||
case RIGHT -> layers[ID_RIGHT];
|
||||
default -> layers[ID_NORMAL];
|
||||
};
|
||||
}
|
||||
|
||||
public static VertexConsumer getConsumer(MultiBufferSource provider, Block block, ChestType chestType) {
|
||||
|
|
|
@ -1,68 +1,84 @@
|
|||
package ru.bclib.client.render;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.mojang.blaze3d.platform.NativeImage;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import com.mojang.math.Vector3f;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.model.geom.ModelLayers;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.Sheets;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRenderDispatcher;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
|
||||
import net.minecraft.client.renderer.blockentity.SignRenderer;
|
||||
import net.minecraft.client.renderer.blockentity.SignRenderer.SignModel;
|
||||
import net.minecraft.client.resources.model.Material;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.FormattedCharSequence;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.item.DyeColor;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.SignBlock;
|
||||
import net.minecraft.world.level.block.StandingSignBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.properties.WoodType;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import ru.bclib.blockentities.BaseSignBlockEntity;
|
||||
import ru.bclib.blocks.BaseSignBlock;
|
||||
|
||||
public class BaseSignBlockEntityRenderer extends BlockEntityRenderer<BaseSignBlockEntity> {
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class BaseSignBlockEntityRenderer implements BlockEntityRenderer<BaseSignBlockEntity> {
|
||||
private static final HashMap<Block, RenderType> LAYERS = Maps.newHashMap();
|
||||
private static final RenderType defaultLayer;
|
||||
private final SignModel model = new SignRenderer.SignModel();
|
||||
private final Font font;
|
||||
private final SignRenderer.SignModel model;
|
||||
|
||||
public BaseSignBlockEntityRenderer(BlockEntityRenderDispatcher dispatcher) {
|
||||
super(dispatcher);
|
||||
|
||||
private static final int OUTLINE_RENDER_DISTANCE = Mth.square(16);
|
||||
|
||||
public BaseSignBlockEntityRenderer(BlockEntityRendererProvider.Context ctx) {
|
||||
super();
|
||||
this.font = ctx.getFont();
|
||||
|
||||
//set up a default model
|
||||
model = new SignRenderer.SignModel(ctx.bakeLayer(ModelLayers.createSignModelName(WoodType.OAK)));
|
||||
}
|
||||
|
||||
public void render(BaseSignBlockEntity signBlockEntity, float tickDelta, PoseStack matrixStack,
|
||||
MultiBufferSource provider, int light, int overlay) {
|
||||
BlockState state = signBlockEntity.getBlockState();
|
||||
|
||||
matrixStack.pushPose();
|
||||
|
||||
|
||||
matrixStack.translate(0.5D, 0.5D, 0.5D);
|
||||
float angle = -((float) (state.getValue(StandingSignBlock.ROTATION) * 360) / 16.0F);
|
||||
|
||||
BlockState blockState = signBlockEntity.getBlockState();
|
||||
if (blockState.getValue(BaseSignBlock.FLOOR)) {
|
||||
matrixStack.mulPose(Vector3f.YP.rotationDegrees(angle));
|
||||
this.model.stick.visible = true;
|
||||
model.stick.visible = true;
|
||||
} else {
|
||||
matrixStack.mulPose(Vector3f.YP.rotationDegrees(angle + 180));
|
||||
matrixStack.translate(0.0D, -0.3125D, -0.4375D);
|
||||
this.model.stick.visible = false;
|
||||
model.stick.visible = false;
|
||||
}
|
||||
|
||||
matrixStack.pushPose();
|
||||
matrixStack.scale(0.6666667F, -0.6666667F, -0.6666667F);
|
||||
VertexConsumer vertexConsumer = getConsumer(provider, state.getBlock());
|
||||
model.sign.render(matrixStack, vertexConsumer, light, overlay);
|
||||
model.stick.render(matrixStack, vertexConsumer, light, overlay);
|
||||
|
||||
model.root.render(matrixStack, vertexConsumer, light, overlay);
|
||||
//model.stick.render(matrixStack, vertexConsumer, light, overlay);
|
||||
matrixStack.popPose();
|
||||
Font textRenderer = renderer.getFont();
|
||||
//Font textRenderer = renderer.getFont();
|
||||
matrixStack.translate(0.0D, 0.3333333432674408D, 0.046666666865348816D);
|
||||
matrixStack.scale(0.010416667F, -0.010416667F, 0.010416667F);
|
||||
int m = signBlockEntity.getColor().getTextColor();
|
||||
|
@ -71,21 +87,59 @@ public class BaseSignBlockEntityRenderer extends BlockEntityRenderer<BaseSignBlo
|
|||
int p = (int) (NativeImage.getB(m) * 0.4D);
|
||||
int q = NativeImage.combine(0, p, o, n);
|
||||
|
||||
FormattedCharSequence[] formattedCharSequences = signBlockEntity
|
||||
.getRenderMessages(Minecraft.getInstance().isTextFilteringEnabled(), (component) -> {
|
||||
List<FormattedCharSequence> list = this.font.split(component, 90);
|
||||
return list.isEmpty() ? FormattedCharSequence.EMPTY : (FormattedCharSequence) list.get(0);
|
||||
});
|
||||
int drawColor;
|
||||
boolean drawOutlined;
|
||||
int drawLight;
|
||||
if (signBlockEntity.hasGlowingText()) {
|
||||
drawColor = signBlockEntity.getColor().getTextColor();
|
||||
drawOutlined = isOutlineVisible(signBlockEntity, drawColor);
|
||||
drawLight = 15728880;
|
||||
} else {
|
||||
drawColor = m;
|
||||
drawOutlined = false;
|
||||
drawLight = light;
|
||||
}
|
||||
|
||||
for (int s = 0; s < 4; ++s) {
|
||||
FormattedCharSequence orderedText = signBlockEntity.getRenderMessage(s, (text) -> {
|
||||
List<FormattedCharSequence> list = textRenderer.split(text, 90);
|
||||
return list.isEmpty() ? FormattedCharSequence.EMPTY : list.get(0);
|
||||
});
|
||||
if (orderedText != null) {
|
||||
float t = (float) (-textRenderer.width(orderedText) / 2);
|
||||
textRenderer.drawInBatch(orderedText, t, (float) (s * 10 - 20), q, false, matrixStack.last().pose(), provider, false, 0, light);
|
||||
FormattedCharSequence formattedCharSequence = formattedCharSequences[s];
|
||||
float t = (float) (-this.font.width(formattedCharSequence) / 2);
|
||||
if (drawOutlined) {
|
||||
this.font.drawInBatch8xOutline(formattedCharSequence, t, (float) (s * 10 - 20), drawColor, m,
|
||||
matrixStack.last().pose(), provider, drawLight);
|
||||
} else {
|
||||
this.font.drawInBatch((FormattedCharSequence) formattedCharSequence, t, (float) (s * 10 - 20), drawColor, false,
|
||||
matrixStack.last().pose(), provider, false, 0, drawLight);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
matrixStack.popPose();
|
||||
}
|
||||
|
||||
public static Material getModelTexture(Block block) {
|
||||
|
||||
|
||||
private static boolean isOutlineVisible(BaseSignBlockEntity signBlockEntity, int i) {
|
||||
if (i == DyeColor.BLACK.getTextColor()) {
|
||||
return true;
|
||||
} else {
|
||||
Minecraft minecraft = Minecraft.getInstance();
|
||||
LocalPlayer localPlayer = minecraft.player;
|
||||
if (localPlayer != null && minecraft.options.getCameraType().isFirstPerson() && localPlayer.isScoping()) {
|
||||
return true;
|
||||
} else {
|
||||
Entity entity = minecraft.getCameraEntity();
|
||||
return entity != null && entity.distanceToSqr(
|
||||
Vec3.atCenterOf(signBlockEntity.getBlockPos())) < (double) OUTLINE_RENDER_DISTANCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static WoodType getSignType(Block block) {
|
||||
WoodType signType2;
|
||||
if (block instanceof SignBlock) {
|
||||
signType2 = ((SignBlock) block).type();
|
||||
|
@ -93,7 +147,11 @@ public class BaseSignBlockEntityRenderer extends BlockEntityRenderer<BaseSignBlo
|
|||
signType2 = WoodType.OAK;
|
||||
}
|
||||
|
||||
return Sheets.signTexture(signType2);
|
||||
return signType2;
|
||||
}
|
||||
|
||||
public static Material getModelTexture(Block block) {
|
||||
return Sheets.getSignMaterial(getSignType(block));
|
||||
}
|
||||
|
||||
public static VertexConsumer getConsumer(MultiBufferSource provider, Block block) {
|
||||
|
|
11
src/main/java/ru/bclib/config/Configs.java
Normal file
11
src/main/java/ru/bclib/config/Configs.java
Normal file
|
@ -0,0 +1,11 @@
|
|||
package ru.bclib.config;
|
||||
|
||||
import ru.bclib.BCLib;
|
||||
|
||||
public class Configs {
|
||||
public static final PathConfig RECIPE_CONFIG = new PathConfig(BCLib.MOD_ID, "recipes");
|
||||
|
||||
public static void save() {
|
||||
RECIPE_CONFIG.saveChanges();
|
||||
}
|
||||
}
|
209
src/main/java/ru/bclib/integration/ModIntegration.java
Normal file
209
src/main/java/ru/bclib/integration/ModIntegration.java
Normal file
|
@ -0,0 +1,209 @@
|
|||
package ru.bclib.integration;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import net.fabricmc.fabric.api.tag.TagRegistry;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.data.BuiltinRegistries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.tags.ItemTags;
|
||||
import net.minecraft.tags.Tag;
|
||||
import net.minecraft.tags.Tag.Named;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.levelgen.GenerationStep;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.level.levelgen.feature.Feature;
|
||||
import ru.bclib.BCLib;
|
||||
import ru.bclib.world.features.BCLFeature;
|
||||
|
||||
public abstract class ModIntegration {
|
||||
private final String modID;
|
||||
|
||||
public void init() {}
|
||||
|
||||
public ModIntegration(String modID) {
|
||||
this.modID = modID;
|
||||
}
|
||||
|
||||
public ResourceLocation getID(String name) {
|
||||
return new ResourceLocation(modID, name);
|
||||
}
|
||||
|
||||
public Block getBlock(String name) {
|
||||
return Registry.BLOCK.get(getID(name));
|
||||
}
|
||||
|
||||
public Item getItem(String name) {
|
||||
return Registry.ITEM.get(getID(name));
|
||||
}
|
||||
|
||||
public BlockState getDefaultState(String name) {
|
||||
return getBlock(name).defaultBlockState();
|
||||
}
|
||||
|
||||
public ResourceKey<Biome> getKey(String name) {
|
||||
return ResourceKey.create(Registry.BIOME_REGISTRY, getID(name));
|
||||
}
|
||||
|
||||
public boolean modIsInstalled() {
|
||||
return FabricLoader.getInstance().isModLoaded(modID);
|
||||
}
|
||||
|
||||
public BCLFeature getFeature(String featureID, String configuredFeatureID, GenerationStep.Decoration featureStep) {
|
||||
Feature<?> feature = Registry.FEATURE.get(getID(featureID));
|
||||
ConfiguredFeature<?, ?> featureConfigured = BuiltinRegistries.CONFIGURED_FEATURE.get(getID(configuredFeatureID));
|
||||
return new BCLFeature(feature, featureConfigured, featureStep);
|
||||
}
|
||||
|
||||
public BCLFeature getFeature(String name, GenerationStep.Decoration featureStep) {
|
||||
return getFeature(name, name, featureStep);
|
||||
}
|
||||
|
||||
public ConfiguredFeature<?, ?> getConfiguredFeature(String name) {
|
||||
return BuiltinRegistries.CONFIGURED_FEATURE.get(getID(name));
|
||||
}
|
||||
|
||||
public Biome getBiome(String name) {
|
||||
return BuiltinRegistries.BIOME.get(getID(name));
|
||||
}
|
||||
|
||||
public Class<?> getClass(String path) {
|
||||
Class<?> cl = null;
|
||||
try {
|
||||
cl = Class.forName(path);
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
BCLib.LOGGER.error(e.getMessage());
|
||||
if (BCLib.isDevEnvironment()) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return cl;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Object> T getStaticFieldValue(Class<?> cl, String name) {
|
||||
if (cl != null) {
|
||||
try {
|
||||
Field field = cl.getDeclaredField(name);
|
||||
if (field != null) {
|
||||
return (T) field.get(null);
|
||||
}
|
||||
}
|
||||
catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object getFieldValue(Class<?> cl, String name, Object classInstance) {
|
||||
if (cl != null) {
|
||||
try {
|
||||
Field field = cl.getDeclaredField(name);
|
||||
if (field != null) {
|
||||
return field.get(classInstance);
|
||||
}
|
||||
}
|
||||
catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Method getMethod(Class<?> cl, String functionName, Class<?>... args) {
|
||||
if (cl != null) {
|
||||
try {
|
||||
return cl.getMethod(functionName, args);
|
||||
}
|
||||
catch (NoSuchMethodException | SecurityException e) {
|
||||
BCLib.LOGGER.error(e.getMessage());
|
||||
if (BCLib.isDevEnvironment()) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object executeMethod(Object instance, Method method, Object... args) {
|
||||
if (method != null) {
|
||||
try {
|
||||
return method.invoke(instance, args);
|
||||
}
|
||||
catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
|
||||
BCLib.LOGGER.error(e.getMessage());
|
||||
if (BCLib.isDevEnvironment()) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object getAndExecuteStatic(Class<?> cl, String functionName, Object... args) {
|
||||
if (cl != null) {
|
||||
Class<?>[] classes = new Class<?>[args.length];
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
classes[i] = args[i].getClass();
|
||||
}
|
||||
Method method = getMethod(cl, functionName, classes);
|
||||
return executeMethod(null, method, args);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Object> T getAndExecuteRuntime(Class<?> cl, Object instance, String functionName, Object... args) {
|
||||
if (instance != null) {
|
||||
Class<?>[] classes = new Class<?>[args.length];
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
classes[i] = args[i].getClass();
|
||||
}
|
||||
Method method = getMethod(cl, functionName, classes);
|
||||
return (T) executeMethod(instance, method, args);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object newInstance(Class<?> cl, Object... args) {
|
||||
if (cl != null) {
|
||||
for (Constructor<?> constructor: cl.getConstructors()) {
|
||||
if (constructor.getParameterCount() == args.length) {
|
||||
try {
|
||||
return constructor.newInstance(args);
|
||||
}
|
||||
catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
|
||||
BCLib.LOGGER.error(e.getMessage());
|
||||
if (BCLib.isDevEnvironment()) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Tag.Named<Item> getItemTag(String name) {
|
||||
ResourceLocation id = getID(name);
|
||||
Tag<Item> tag = ItemTags.getAllTags().getTag(id);
|
||||
return tag == null ? (Named<Item>) TagRegistry.item(id) : (Named<Item>) tag;
|
||||
}
|
||||
|
||||
public Tag.Named<Block> getBlockTag(String name) {
|
||||
ResourceLocation id = getID(name);
|
||||
Tag<Block> tag = BlockTags.getAllTags().getTag(id);
|
||||
return tag == null ? (Named<Block>) TagRegistry.block(id) : (Named<Block>) tag;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
package ru.bclib.interfaces;
|
||||
|
||||
import ru.bclib.client.render.ERenderLayer;
|
||||
import ru.bclib.client.render.BCLRenderLayer;
|
||||
|
||||
public interface IRenderTyped {
|
||||
ERenderLayer getRenderLayer();
|
||||
BCLRenderLayer getRenderLayer();
|
||||
}
|
||||
|
|
60
src/main/java/ru/bclib/items/BaseAnvilItem.java
Normal file
60
src/main/java/ru/bclib/items/BaseAnvilItem.java
Normal file
|
@ -0,0 +1,60 @@
|
|||
package ru.bclib.items;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.TranslatableComponent;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.TooltipFlag;
|
||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import ru.bclib.blocks.BaseAnvilBlock;
|
||||
import ru.bclib.client.models.ItemModelProvider;
|
||||
|
||||
public class BaseAnvilItem extends BlockItem implements ItemModelProvider {
|
||||
|
||||
public final static String DESTRUCTION = "destruction";
|
||||
|
||||
public BaseAnvilItem(Block block, Properties properties) {
|
||||
super(block, properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockState getPlacementState(BlockPlaceContext blockPlaceContext) {
|
||||
BlockState blockState = super.getPlacementState(blockPlaceContext);
|
||||
ItemStack stack = blockPlaceContext.getItemInHand();
|
||||
int destruction = stack.getOrCreateTag().getInt(DESTRUCTION);
|
||||
if (blockState != null) {
|
||||
blockState = blockState.setValue(BaseAnvilBlock.DESTRUCTION, destruction);
|
||||
}
|
||||
return blockState;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public void appendHoverText(ItemStack itemStack, @Nullable Level level, List<Component> list, TooltipFlag tooltipFlag) {
|
||||
super.appendHoverText(itemStack, level, list, tooltipFlag);
|
||||
int l = itemStack.getOrCreateTag().getInt(DESTRUCTION);
|
||||
if (l > 0) {
|
||||
list.add(new TranslatableComponent("message.bclib.anvil_damage").append(": " + l));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public BlockModel getItemModel(ResourceLocation resourceLocation) {
|
||||
Block anvilBlock = getBlock();
|
||||
ResourceLocation blockId = Registry.BLOCK.getKey(anvilBlock);
|
||||
return ((ItemModelProvider) anvilBlock).getItemModel(blockId);
|
||||
}
|
||||
}
|
|
@ -1,13 +1,14 @@
|
|||
package ru.bclib.items;
|
||||
|
||||
import net.fabricmc.fabric.api.item.v1.FabricItemSettings;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.item.FishBucketItem;
|
||||
import net.minecraft.world.item.MobBucketItem;
|
||||
import net.minecraft.world.level.material.Fluids;
|
||||
import ru.bclib.client.models.ItemModelProvider;
|
||||
|
||||
public class BaseBucketItem extends FishBucketItem implements ItemModelProvider {
|
||||
public class BaseBucketItem extends MobBucketItem implements ItemModelProvider {
|
||||
public BaseBucketItem(EntityType<?> type, FabricItemSettings settings) {
|
||||
super(type, Fluids.WATER, settings.stacksTo(1));
|
||||
super(type, Fluids.WATER, SoundEvents.BUCKET_EMPTY_FISH, settings.stacksTo(1));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@ import net.minecraft.sounds.SoundEvent;
|
|||
import net.minecraft.world.item.RecordItem;
|
||||
import ru.bclib.client.models.ItemModelProvider;
|
||||
|
||||
public class EndDiscItem extends RecordItem implements ItemModelProvider {
|
||||
public EndDiscItem(int comparatorOutput, SoundEvent sound, Properties settings) {
|
||||
public class BaseDiscItem extends RecordItem implements ItemModelProvider {
|
||||
public BaseDiscItem(int comparatorOutput, SoundEvent sound, Properties settings) {
|
||||
super(comparatorOutput, sound, settings);
|
||||
}
|
||||
}
|
|
@ -30,22 +30,27 @@ public class BaseDrinkItem extends ModelProviderItem {
|
|||
|
||||
@Override
|
||||
public InteractionResultHolder<ItemStack> use(Level world, Player user, InteractionHand hand) {
|
||||
return ItemUtils.useDrink(world, user, hand);
|
||||
return ItemUtils.startUsingInstantly(world, user, hand);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack finishUsingItem(ItemStack stack, Level world, LivingEntity user) {
|
||||
if (user instanceof ServerPlayer) {
|
||||
ServerPlayer serverPlayerEntity = (ServerPlayer) user;
|
||||
public ItemStack finishUsingItem(ItemStack stack, Level level, LivingEntity user) {
|
||||
if (this.isEdible()) {
|
||||
int count = stack.getCount();
|
||||
user.eat(level, stack);
|
||||
stack.setCount(count);
|
||||
}
|
||||
|
||||
if (user instanceof ServerPlayer serverPlayerEntity) {
|
||||
CriteriaTriggers.CONSUME_ITEM.trigger(serverPlayerEntity, stack);
|
||||
serverPlayerEntity.awardStat(Stats.ITEM_USED.get(this));
|
||||
}
|
||||
|
||||
if (user instanceof Player && !((Player) user).abilities.instabuild) {
|
||||
if (user instanceof Player && !((Player) user).getAbilities().instabuild) {
|
||||
stack.shrink(1);
|
||||
}
|
||||
|
||||
if (!world.isClientSide) {
|
||||
if (!level.isClientSide) {
|
||||
user.removeAllEffects();
|
||||
}
|
||||
|
||||
|
|
|
@ -2,9 +2,12 @@ package ru.bclib.items;
|
|||
|
||||
import java.util.Optional;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
import net.minecraft.world.item.SpawnEggItem;
|
||||
import ru.bclib.client.models.BasePatterns;
|
||||
import ru.bclib.client.models.ItemModelProvider;
|
||||
|
@ -12,11 +15,12 @@ import ru.bclib.client.models.ModelsHelper;
|
|||
import ru.bclib.client.models.PatternsHelper;
|
||||
|
||||
public class BaseSpawnEggItem extends SpawnEggItem implements ItemModelProvider {
|
||||
public BaseSpawnEggItem(EntityType<?> type, int primaryColor, int secondaryColor, Properties settings) {
|
||||
public BaseSpawnEggItem(EntityType<? extends Mob> type, int primaryColor, int secondaryColor, Properties settings) {
|
||||
super(type, primaryColor, secondaryColor, settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public BlockModel getItemModel(ResourceLocation resourceLocation) {
|
||||
Optional<String> pattern = PatternsHelper.createJson(BasePatterns.ITEM_SPAWN_EGG, resourceLocation);
|
||||
return ModelsHelper.fromPattern(pattern);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package ru.bclib.items;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.Item;
|
||||
|
@ -12,6 +14,7 @@ public class ModelProviderItem extends Item implements ItemModelProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public BlockModel getItemModel(ResourceLocation resourceLocation) {
|
||||
return ModelsHelper.createItemModel(resourceLocation);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package ru.bclib.items.tool;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.DynamicAttributeTool;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
|
@ -28,6 +30,7 @@ public class BaseAxeItem extends AxeItem implements DynamicAttributeTool, ItemMo
|
|||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public BlockModel getItemModel(ResourceLocation resourceLocation) {
|
||||
return ModelsHelper.createHandheldItem(resourceLocation);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package ru.bclib.items.tool;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.HoeItem;
|
||||
|
@ -13,6 +15,7 @@ public class BaseHoeItem extends HoeItem implements ItemModelProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public BlockModel getItemModel(ResourceLocation resourceLocation) {
|
||||
return ModelsHelper.createHandheldItem(resourceLocation);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package ru.bclib.items.tool;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.DynamicAttributeTool;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||
import net.fabricmc.fabric.impl.tool.attribute.ToolManagerImpl;
|
||||
|
@ -36,6 +38,7 @@ public class BasePickaxeItem extends PickaxeItem implements DynamicAttributeTool
|
|||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public BlockModel getItemModel(ResourceLocation resourceLocation) {
|
||||
return ModelsHelper.createHandheldItem(resourceLocation);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package ru.bclib.items.tool;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.DynamicAttributeTool;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||
import net.fabricmc.fabric.impl.tool.attribute.ToolManagerImpl;
|
||||
|
@ -36,6 +38,7 @@ public class BaseShovelItem extends ShovelItem implements DynamicAttributeTool,
|
|||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public BlockModel getItemModel(ResourceLocation resourceLocation) {
|
||||
return ModelsHelper.createHandheldItem(resourceLocation);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package ru.bclib.items.tool;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.DynamicAttributeTool;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
@ -14,6 +16,7 @@ public class BaseSwordItem extends SwordItem implements DynamicAttributeTool, It
|
|||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public BlockModel getItemModel(ResourceLocation resourceLocation) {
|
||||
return ModelsHelper.createHandheldItem(resourceLocation);
|
||||
}
|
||||
|
|
142
src/main/java/ru/bclib/mixin/client/BackgroundRendererMixin.java
Normal file
142
src/main/java/ru/bclib/mixin/client/BackgroundRendererMixin.java
Normal file
|
@ -0,0 +1,142 @@
|
|||
package ru.bclib.mixin.client;
|
||||
|
||||
import net.minecraft.world.level.material.FogType;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.renderer.FogRenderer;
|
||||
import net.minecraft.core.BlockPos.MutableBlockPos;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.effect.MobEffectInstance;
|
||||
import net.minecraft.world.effect.MobEffects;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import ru.bclib.api.BiomeAPI;
|
||||
import ru.bclib.util.BackgroundInfo;
|
||||
import ru.bclib.util.MHelper;
|
||||
import ru.bclib.world.biomes.BCLBiome;
|
||||
|
||||
@Mixin(FogRenderer.class)
|
||||
public class BackgroundRendererMixin {
|
||||
private static final MutableBlockPos BCL_LAST_POS = new MutableBlockPos(0, -100, 0);
|
||||
private static final MutableBlockPos BCL_MUT_POS = new MutableBlockPos();
|
||||
private static final float[] BCL_FOG_DENSITY = new float[8];
|
||||
|
||||
@Shadow
|
||||
private static float fogRed;
|
||||
@Shadow
|
||||
private static float fogGreen;
|
||||
@Shadow
|
||||
private static float fogBlue;
|
||||
|
||||
@Inject(method = "setupColor", at = @At("RETURN"))
|
||||
private static void bcl_onRender(Camera camera, float tickDelta, ClientLevel world, int i, float f, CallbackInfo info) {
|
||||
FogType fogType = camera.getFluidInCamera();
|
||||
if (fogType != FogType.WATER && world.dimension().equals(Level.END)) {
|
||||
Entity entity = camera.getEntity();
|
||||
boolean skip = false;
|
||||
if (entity instanceof LivingEntity) {
|
||||
MobEffectInstance effect = ((LivingEntity) entity).getEffect(MobEffects.NIGHT_VISION);
|
||||
skip = effect != null && effect.getDuration() > 0;
|
||||
}
|
||||
if (!skip) {
|
||||
fogRed *= 4;
|
||||
fogGreen *= 4;
|
||||
fogBlue *= 4;
|
||||
}
|
||||
}
|
||||
|
||||
BackgroundInfo.fogColorRed = fogRed;
|
||||
BackgroundInfo.fogColorGreen = fogGreen;
|
||||
BackgroundInfo.fogColorBlue = fogBlue;
|
||||
}
|
||||
|
||||
@Inject(method = "setupFog", at = @At("HEAD"), cancellable = true)
|
||||
private static void bcl_fogDensity(Camera camera, FogRenderer.FogMode fogMode, float viewDistance, boolean thickFog, CallbackInfo info) {
|
||||
Entity entity = camera.getEntity();
|
||||
FogType fogType = camera.getFluidInCamera();
|
||||
if (fogType != FogType.WATER) {
|
||||
float fog = bcl_getFogDensity(entity.level, entity.getX(), entity.getEyeY(), entity.getZ());
|
||||
BackgroundInfo.fogDensity = fog;
|
||||
float start = viewDistance * 0.75F / fog;
|
||||
float end = viewDistance / fog;
|
||||
|
||||
if (entity instanceof LivingEntity) {
|
||||
LivingEntity le = (LivingEntity) entity;
|
||||
MobEffectInstance effect = le.getEffect(MobEffects.BLINDNESS);
|
||||
if (effect != null) {
|
||||
int duration = effect.getDuration();
|
||||
if (duration > 20) {
|
||||
start = 0;
|
||||
end *= 0.03F;
|
||||
BackgroundInfo.blindness = 1;
|
||||
}
|
||||
else {
|
||||
float delta = (float) duration / 20F;
|
||||
BackgroundInfo.blindness = delta;
|
||||
start = Mth.lerp(delta, start, 0);
|
||||
end = Mth.lerp(delta, end, end * 0.03F);
|
||||
}
|
||||
}
|
||||
else {
|
||||
BackgroundInfo.blindness = 0;
|
||||
}
|
||||
}
|
||||
|
||||
RenderSystem.setShaderFogStart(start);
|
||||
RenderSystem.setShaderFogEnd(end);
|
||||
info.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
private static float bcl_getFogDensityI(Level level, int x, int y, int z) {
|
||||
Biome biome = level.getBiome(BCL_MUT_POS.set(x, y, z));
|
||||
BCLBiome renderBiome = BiomeAPI.getRenderBiome(biome);
|
||||
return renderBiome.getFogDensity();
|
||||
}
|
||||
|
||||
private static float bcl_getFogDensity(Level level, double x, double y, double z) {
|
||||
int x1 = (MHelper.floor(x) >> 3) << 3;
|
||||
int y1 = (MHelper.floor(y) >> 3) << 3;
|
||||
int z1 = (MHelper.floor(z) >> 3) << 3;
|
||||
float dx = (float) (x - x1) / 8F;
|
||||
float dy = (float) (y - y1) / 8F;
|
||||
float dz = (float) (z - z1) / 8F;
|
||||
|
||||
if (BCL_LAST_POS.getX() != x1 || BCL_LAST_POS.getY() != y1 || BCL_LAST_POS.getZ() != z1) {
|
||||
int x2 = x1 + 8;
|
||||
int y2 = y1 + 8;
|
||||
int z2 = z1 + 8;
|
||||
BCL_LAST_POS.set(x1, y1, z1);
|
||||
BCL_FOG_DENSITY[0] = bcl_getFogDensityI(level, x1, y1, z1);
|
||||
BCL_FOG_DENSITY[1] = bcl_getFogDensityI(level, x2, y1, z1);
|
||||
BCL_FOG_DENSITY[2] = bcl_getFogDensityI(level, x1, y2, z1);
|
||||
BCL_FOG_DENSITY[3] = bcl_getFogDensityI(level, x2, y2, z1);
|
||||
BCL_FOG_DENSITY[4] = bcl_getFogDensityI(level, x1, y1, z2);
|
||||
BCL_FOG_DENSITY[5] = bcl_getFogDensityI(level, x2, y1, z2);
|
||||
BCL_FOG_DENSITY[6] = bcl_getFogDensityI(level, x1, y2, z2);
|
||||
BCL_FOG_DENSITY[7] = bcl_getFogDensityI(level, x2, y2, z2);
|
||||
}
|
||||
|
||||
float a = Mth.lerp(dx, BCL_FOG_DENSITY[0], BCL_FOG_DENSITY[1]);
|
||||
float b = Mth.lerp(dx, BCL_FOG_DENSITY[2], BCL_FOG_DENSITY[3]);
|
||||
float c = Mth.lerp(dx, BCL_FOG_DENSITY[4], BCL_FOG_DENSITY[5]);
|
||||
float d = Mth.lerp(dx, BCL_FOG_DENSITY[6], BCL_FOG_DENSITY[7]);
|
||||
|
||||
a = Mth.lerp(dy, a, b);
|
||||
b = Mth.lerp(dy, c, d);
|
||||
|
||||
return Mth.lerp(dz, a, b);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package ru.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.data.worldgen.Features;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.crafting.Recipe;
|
||||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
import net.minecraft.world.level.block.ComposterBlock;
|
||||
import net.minecraft.world.level.levelgen.placement.ConfiguredDecorator;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(targets = "net.minecraft.data.worldgen.Features$Decorators")
|
||||
public interface FeatureDecoratorsAccessor {
|
||||
@Accessor("HEIGHTMAP_SQUARE")
|
||||
ConfiguredDecorator<?> bcl_getHeightmapSquare();
|
||||
}
|
|
@ -22,24 +22,27 @@ import net.minecraft.world.level.dimension.DimensionType;
|
|||
import net.minecraft.world.level.storage.LevelStorageSource;
|
||||
import net.minecraft.world.level.storage.ServerLevelData;
|
||||
import net.minecraft.world.level.storage.WritableLevelData;
|
||||
import ru.bclib.api.BiomeAPI;
|
||||
import ru.bclib.api.DataFixerAPI;
|
||||
import ru.bclib.api.WorldDataAPI;
|
||||
|
||||
@Mixin(ServerLevel.class)
|
||||
public abstract class ServerLevelMixin extends Level {
|
||||
private static String be_lastWorld = null;
|
||||
private static String bcl_lastWorld = null;
|
||||
|
||||
protected ServerLevelMixin(WritableLevelData writableLevelData, ResourceKey<Level> resourceKey, DimensionType dimensionType, Supplier<ProfilerFiller> supplier, boolean bl, boolean bl2, long l) {
|
||||
super(writableLevelData, resourceKey, dimensionType, supplier, bl, bl2, l);
|
||||
}
|
||||
|
||||
@Inject(method = "<init>*", at = @At("TAIL"))
|
||||
private void be_onServerWorldInit(MinecraftServer server, Executor workerExecutor, LevelStorageSource.LevelStorageAccess session, ServerLevelData properties, ResourceKey<Level> registryKey, DimensionType dimensionType, ChunkProgressListener worldGenerationProgressListener, ChunkGenerator chunkGenerator, boolean debugWorld, long l, List<CustomSpawner> list, boolean bl, CallbackInfo info) {
|
||||
if (be_lastWorld != null && be_lastWorld.equals(session.getLevelId())) {
|
||||
private void bcl_onServerWorldInit(MinecraftServer server, Executor workerExecutor, LevelStorageSource.LevelStorageAccess session, ServerLevelData properties, ResourceKey<Level> registryKey, DimensionType dimensionType, ChunkProgressListener worldGenerationProgressListener, ChunkGenerator chunkGenerator, boolean debugWorld, long l, List<CustomSpawner> list, boolean bl, CallbackInfo info) {
|
||||
BiomeAPI.initRegistry(server);
|
||||
|
||||
if (bcl_lastWorld != null && bcl_lastWorld.equals(session.getLevelId())) {
|
||||
return;
|
||||
}
|
||||
|
||||
be_lastWorld = session.getLevelId();
|
||||
bcl_lastWorld = session.getLevelId();
|
||||
|
||||
ServerLevel world = ServerLevel.class.cast(this);
|
||||
File dir = session.getDimensionPath(world.dimension());
|
||||
|
@ -48,6 +51,6 @@ public abstract class ServerLevelMixin extends Level {
|
|||
}
|
||||
|
||||
DataFixerAPI.fixData(dir);
|
||||
WorldDataAPI.load(dir);
|
||||
WorldDataAPI.load(new File(dir, "data"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,26 +1,23 @@
|
|||
package ru.bclib.mixin.common;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.Tag;
|
||||
import net.minecraft.tags.TagLoader;
|
||||
import ru.bclib.util.TagHelper;
|
||||
|
||||
@Mixin(TagLoader.class)
|
||||
public class TagLoaderMixin {
|
||||
@Shadow
|
||||
private String name;
|
||||
|
||||
@ModifyArg(method = "prepare", at = @At(value = "INVOKE", target = "Ljava/util/concurrent/CompletableFuture;supplyAsync(Ljava/util/function/Supplier;Ljava/util/concurrent/Executor;)Ljava/util/concurrent/CompletableFuture;"))
|
||||
public Supplier<Map<ResourceLocation, Tag.Builder>> be_modifyTags(Supplier<Map<ResourceLocation, Tag.Builder>> supplier, Executor executor) {
|
||||
return () -> TagHelper.apply(name, supplier.get());
|
||||
}
|
||||
}
|
||||
package ru.bclib.mixin.common;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.Tag;
|
||||
import net.minecraft.tags.TagLoader;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
import ru.bclib.util.TagHelper;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(TagLoader.class)
|
||||
public class TagLoaderMixin {
|
||||
@Shadow
|
||||
private String directory;
|
||||
|
||||
@ModifyArg(method = "loadAndBuild", at = @At(value = "INVOKE", target = "Lnet/minecraft/tags/TagLoader;build(Ljava/util/Map;)Lnet/minecraft/tags/TagCollection;"))
|
||||
public Map<ResourceLocation, Tag.Builder> be_modifyTags(Map<ResourceLocation, Tag.Builder> tagsMap) {
|
||||
return TagHelper.apply(directory, tagsMap);
|
||||
}
|
||||
}
|
||||
|
|
37
src/main/java/ru/bclib/recipes/CraftingRecipes.java
Normal file
37
src/main/java/ru/bclib/recipes/CraftingRecipes.java
Normal file
|
@ -0,0 +1,37 @@
|
|||
package ru.bclib.recipes;
|
||||
|
||||
import net.minecraft.tags.ItemTags;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import ru.bclib.BCLib;
|
||||
import ru.bclib.api.TagAPI;
|
||||
import ru.bclib.config.Configs;
|
||||
|
||||
public class CraftingRecipes {
|
||||
public static void init() {
|
||||
GridRecipe.make(BCLib.MOD_ID, "tag_smith_table", Blocks.SMITHING_TABLE).setShape("II", "##", "##").addMaterial('#', ItemTags.PLANKS).addMaterial('I', TagAPI.IRON_INGOTS).checkConfig(Configs.RECIPE_CONFIG).build();
|
||||
GridRecipe.make(BCLib.MOD_ID, "tag_cauldron", Blocks.CAULDRON).setShape("I I", "I I", "III").addMaterial('I', TagAPI.IRON_INGOTS).checkConfig(Configs.RECIPE_CONFIG).build();
|
||||
GridRecipe.make(BCLib.MOD_ID, "tag_hopper", Blocks.HOPPER).setShape("I I", "ICI", " I ").addMaterial('I', TagAPI.IRON_INGOTS).addMaterial('C', TagAPI.ITEM_CHEST).checkConfig(Configs.RECIPE_CONFIG).build();
|
||||
GridRecipe.make(BCLib.MOD_ID, "tag_piston", Blocks.PISTON).setShape("WWW", "CIC", "CDC").addMaterial('I', TagAPI.IRON_INGOTS).addMaterial('D', Items.REDSTONE).addMaterial('C', Items.COBBLESTONE).addMaterial('W', ItemTags.PLANKS).checkConfig(Configs.RECIPE_CONFIG).build();
|
||||
GridRecipe.make(BCLib.MOD_ID, "tag_rail", Blocks.RAIL).setOutputCount(16).setShape("I I", "ISI", "I I").addMaterial('I', TagAPI.IRON_INGOTS).addMaterial('S', Items.STICK).checkConfig(Configs.RECIPE_CONFIG).build();
|
||||
GridRecipe.make(BCLib.MOD_ID, "tag_stonecutter", Blocks.STONECUTTER).setShape(" I ", "SSS").addMaterial('I', TagAPI.IRON_INGOTS).addMaterial('S', Items.STONE).checkConfig(Configs.RECIPE_CONFIG).build();
|
||||
GridRecipe.make(BCLib.MOD_ID, "tag_bucket", Items.BUCKET).setShape("I I", " I ").addMaterial('I', TagAPI.IRON_INGOTS).checkConfig(Configs.RECIPE_CONFIG).build();
|
||||
GridRecipe.make(BCLib.MOD_ID, "tag_compass", Items.COMPASS).setShape(" I ", "IDI", " I ").addMaterial('I', TagAPI.IRON_INGOTS).addMaterial('D', Items.REDSTONE).checkConfig(Configs.RECIPE_CONFIG).build();
|
||||
GridRecipe.make(BCLib.MOD_ID, "tag_minecart", Items.MINECART).setShape("I I", "III").addMaterial('I', TagAPI.IRON_INGOTS).checkConfig(Configs.RECIPE_CONFIG).build();
|
||||
GridRecipe.make(BCLib.MOD_ID, "tag_shield", Items.SHIELD).setShape("WIW", "WWW", " W ").addMaterial('I', TagAPI.IRON_INGOTS).addMaterial('W', ItemTags.PLANKS).checkConfig(Configs.RECIPE_CONFIG).build();
|
||||
|
||||
GridRecipe.make(BCLib.MOD_ID, "tag_hopper", Blocks.HOPPER)
|
||||
.setShape("I I", "ICI", " I ")
|
||||
.addMaterial('I', TagAPI.IRON_INGOTS)
|
||||
.addMaterial('C', TagAPI.ITEM_CHEST)
|
||||
.checkConfig(Configs.RECIPE_CONFIG)
|
||||
.build();
|
||||
|
||||
GridRecipe.make(BCLib.MOD_ID, "tag_shulker_box", Blocks.SHULKER_BOX)
|
||||
.setShape("S", "C", "S")
|
||||
.addMaterial('S', Items.SHULKER_SHELL)
|
||||
.addMaterial('C', TagAPI.ITEM_CHEST)
|
||||
.checkConfig(Configs.RECIPE_CONFIG)
|
||||
.build();
|
||||
}
|
||||
}
|
|
@ -39,7 +39,7 @@ public class FurnaceRecipe {
|
|||
}
|
||||
|
||||
public FurnaceRecipe checkConfig(PathConfig config) {
|
||||
exist = config.getBoolean("furnace", id.getPath(), true);
|
||||
exist |= config.getBoolean("furnace", id.getPath(), true);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ public class GridRecipe {
|
|||
}
|
||||
|
||||
public GridRecipe checkConfig(PathConfig config) {
|
||||
exist = config.getBoolean("grid", id.getPath(), true);
|
||||
exist |= config.getBoolean("grid", id.getPath(), true);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ public class SmithingTableRecipe {
|
|||
private SmithingTableRecipe() {}
|
||||
|
||||
public SmithingTableRecipe checkConfig(PathConfig config) {
|
||||
exist = config.getBoolean("smithing", id.getPath(), true);
|
||||
exist |= config.getBoolean("smithing", id.getPath(), true);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,28 +1,31 @@
|
|||
package ru.bclib.registry;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import ru.bclib.BCLib;
|
||||
import ru.bclib.blockentities.*;
|
||||
import ru.bclib.blockentities.BaseBarrelBlockEntity;
|
||||
import ru.bclib.blockentities.BaseChestBlockEntity;
|
||||
import ru.bclib.blockentities.BaseFurnaceBlockEntity;
|
||||
import ru.bclib.blockentities.BaseSignBlockEntity;
|
||||
import ru.bclib.blockentities.DynamicBlockEntityType;
|
||||
import ru.bclib.blockentities.DynamicBlockEntityType.BlockEntitySupplier;
|
||||
import ru.bclib.blocks.BaseBarrelBlock;
|
||||
import ru.bclib.blocks.BaseChestBlock;
|
||||
import ru.bclib.blocks.BaseFurnaceBlock;
|
||||
import ru.bclib.blocks.BaseSignBlock;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class BaseBlockEntities {
|
||||
public static final DynamicBlockEntityType<BaseChestBlockEntity> CHEST = registerBlockEntityType(BCLib.makeID("chest"), BaseChestBlockEntity::new);
|
||||
public static final DynamicBlockEntityType<BaseBarrelBlockEntity> BARREL = registerBlockEntityType(BCLib.makeID("barrel"), BaseBarrelBlockEntity::new);
|
||||
public static final DynamicBlockEntityType<BaseSignBlockEntity> SIGN = registerBlockEntityType(BCLib.makeID("sign"), BaseSignBlockEntity::new);
|
||||
public static final DynamicBlockEntityType<BaseFurnaceBlockEntity> FURNACE = registerBlockEntityType(BCLib.makeID("furnace"), BaseFurnaceBlockEntity::new);
|
||||
|
||||
public static <T extends BlockEntity> DynamicBlockEntityType<T> registerBlockEntityType(ResourceLocation typeId, Supplier<? extends T> supplier) {
|
||||
public static <T extends BlockEntity> DynamicBlockEntityType<T> registerBlockEntityType(ResourceLocation typeId, BlockEntitySupplier<? extends T> supplier) {
|
||||
return Registry.register(Registry.BLOCK_ENTITY_TYPE, typeId, new DynamicBlockEntityType<>(supplier));
|
||||
}
|
||||
|
||||
|
@ -34,7 +37,7 @@ public class BaseBlockEntities {
|
|||
.map(item -> ((BlockItem) item).getBlock()).toArray(Block[]::new);
|
||||
}
|
||||
|
||||
private static Block[] getBarrels() {
|
||||
public static Block[] getBarrels() {
|
||||
return BaseRegistry.getRegisteredBlocks().values().stream()
|
||||
.filter(item -> item instanceof BlockItem && ((BlockItem) item).getBlock() instanceof BaseBarrelBlock)
|
||||
.map(item -> ((BlockItem) item).getBlock()).toArray(Block[]::new);
|
||||
|
@ -46,7 +49,7 @@ public class BaseBlockEntities {
|
|||
.map(item -> ((BlockItem) item).getBlock()).toArray(Block[]::new);
|
||||
}
|
||||
|
||||
private static Block[] getFurnaces() {
|
||||
public static Block[] getFurnaces() {
|
||||
return BaseRegistry.getRegisteredBlocks().values().stream()
|
||||
.filter(item -> item instanceof BlockItem && ((BlockItem) item).getBlock() instanceof BaseFurnaceBlock)
|
||||
.map(item -> ((BlockItem) item).getBlock()).toArray(Block[]::new);
|
||||
|
|
|
@ -9,6 +9,7 @@ import net.minecraft.sounds.SoundEvent;
|
|||
import net.minecraft.tags.Tag;
|
||||
import net.minecraft.world.effect.MobEffectInstance;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
import net.minecraft.world.entity.MobSpawnType;
|
||||
import net.minecraft.world.food.FoodProperties;
|
||||
import net.minecraft.world.item.CreativeModeTab;
|
||||
|
@ -19,9 +20,9 @@ import net.minecraft.world.item.SpawnEggItem;
|
|||
import net.minecraft.world.item.SwordItem;
|
||||
import net.minecraft.world.item.TieredItem;
|
||||
import net.minecraft.world.level.block.DispenserBlock;
|
||||
import ru.bclib.items.BaseDiscItem;
|
||||
import ru.bclib.items.BaseDrinkItem;
|
||||
import ru.bclib.items.BaseSpawnEggItem;
|
||||
import ru.bclib.items.EndDiscItem;
|
||||
import ru.bclib.items.ModelProviderItem;
|
||||
import ru.bclib.items.tool.BaseAxeItem;
|
||||
import ru.bclib.items.tool.BaseHoeItem;
|
||||
|
@ -35,7 +36,7 @@ public abstract class ItemsRegistry extends BaseRegistry<Item> {
|
|||
}
|
||||
|
||||
public Item registerDisc(String name, int power, SoundEvent sound) {
|
||||
return register(name, new EndDiscItem(power, sound, makeItemSettings()));
|
||||
return register(name, new BaseDiscItem(power, sound, makeItemSettings().stacksTo(1)));
|
||||
}
|
||||
|
||||
public Item registerItem(String name) {
|
||||
|
@ -67,7 +68,7 @@ public abstract class ItemsRegistry extends BaseRegistry<Item> {
|
|||
return item;
|
||||
}
|
||||
|
||||
public Item registerEgg(String name, EntityType<?> type, int background, int dots) {
|
||||
public Item registerEgg(String name, EntityType<? extends Mob> type, int background, int dots) {
|
||||
SpawnEggItem item = new BaseSpawnEggItem(type, background, dots, makeItemSettings());
|
||||
DefaultDispenseItemBehavior behavior = new DefaultDispenseItemBehavior() {
|
||||
public ItemStack execute(BlockSource pointer, ItemStack stack) {
|
||||
|
|
11
src/main/java/ru/bclib/server/BCLibServer.java
Normal file
11
src/main/java/ru/bclib/server/BCLibServer.java
Normal file
|
@ -0,0 +1,11 @@
|
|||
package ru.bclib.server;
|
||||
|
||||
import net.fabricmc.api.DedicatedServerModInitializer;
|
||||
import ru.bclib.api.ModIntegrationAPI;
|
||||
|
||||
public class BCLibServer implements DedicatedServerModInitializer {
|
||||
@Override
|
||||
public void onInitializeServer() {
|
||||
ModIntegrationAPI.registerAll();
|
||||
}
|
||||
}
|
9
src/main/java/ru/bclib/util/BackgroundInfo.java
Normal file
9
src/main/java/ru/bclib/util/BackgroundInfo.java
Normal file
|
@ -0,0 +1,9 @@
|
|||
package ru.bclib.util;
|
||||
|
||||
public class BackgroundInfo {
|
||||
public static float fogColorRed;
|
||||
public static float fogColorGreen;
|
||||
public static float fogColorBlue;
|
||||
public static float fogDensity = 1;
|
||||
public static float blindness;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue