86 lines
3.6 KiB
Java
86 lines
3.6 KiB
Java
package net.minecraft.world.level.block;
|
|
|
|
import com.google.common.collect.Maps;
|
|
import com.mojang.serialization.MapCodec;
|
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
|
import java.util.Map;
|
|
import java.util.function.Supplier;
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.core.registries.BuiltInRegistries;
|
|
import net.minecraft.server.level.ServerLevel;
|
|
import net.minecraft.tags.EnchantmentTags;
|
|
import net.minecraft.world.entity.EntityType;
|
|
import net.minecraft.world.entity.monster.Silverfish;
|
|
import net.minecraft.world.item.ItemStack;
|
|
import net.minecraft.world.item.enchantment.EnchantmentHelper;
|
|
import net.minecraft.world.level.GameRules;
|
|
import net.minecraft.world.level.block.state.BlockBehaviour;
|
|
import net.minecraft.world.level.block.state.BlockState;
|
|
import net.minecraft.world.level.block.state.properties.Property;
|
|
|
|
public class InfestedBlock extends Block {
|
|
public static final MapCodec<InfestedBlock> CODEC = RecordCodecBuilder.mapCodec(
|
|
instance -> instance.group(BuiltInRegistries.BLOCK.byNameCodec().fieldOf("host").forGetter(InfestedBlock::getHostBlock), propertiesCodec())
|
|
.apply(instance, InfestedBlock::new)
|
|
);
|
|
private final Block hostBlock;
|
|
private static final Map<Block, Block> BLOCK_BY_HOST_BLOCK = Maps.<Block, Block>newIdentityHashMap();
|
|
private static final Map<BlockState, BlockState> HOST_TO_INFESTED_STATES = Maps.<BlockState, BlockState>newIdentityHashMap();
|
|
private static final Map<BlockState, BlockState> INFESTED_TO_HOST_STATES = Maps.<BlockState, BlockState>newIdentityHashMap();
|
|
|
|
@Override
|
|
public MapCodec<? extends InfestedBlock> codec() {
|
|
return CODEC;
|
|
}
|
|
|
|
public InfestedBlock(Block hostBlock, BlockBehaviour.Properties properties) {
|
|
super(properties.destroyTime(hostBlock.defaultDestroyTime() / 2.0F).explosionResistance(0.75F));
|
|
this.hostBlock = hostBlock;
|
|
BLOCK_BY_HOST_BLOCK.put(hostBlock, this);
|
|
}
|
|
|
|
public Block getHostBlock() {
|
|
return this.hostBlock;
|
|
}
|
|
|
|
public static boolean isCompatibleHostBlock(BlockState state) {
|
|
return BLOCK_BY_HOST_BLOCK.containsKey(state.getBlock());
|
|
}
|
|
|
|
private void spawnInfestation(ServerLevel level, BlockPos pos) {
|
|
Silverfish silverfish = EntityType.SILVERFISH.create(level);
|
|
if (silverfish != null) {
|
|
silverfish.moveTo(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, 0.0F, 0.0F);
|
|
level.addFreshEntity(silverfish);
|
|
silverfish.spawnAnim();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected void spawnAfterBreak(BlockState state, ServerLevel level, BlockPos pos, ItemStack stack, boolean dropExperience) {
|
|
super.spawnAfterBreak(state, level, pos, stack, dropExperience);
|
|
if (level.getGameRules().getBoolean(GameRules.RULE_DOBLOCKDROPS) && !EnchantmentHelper.hasTag(stack, EnchantmentTags.PREVENTS_INFESTED_SPAWNS)) {
|
|
this.spawnInfestation(level, pos);
|
|
}
|
|
}
|
|
|
|
public static BlockState infestedStateByHost(BlockState host) {
|
|
return getNewStateWithProperties(HOST_TO_INFESTED_STATES, host, () -> ((Block)BLOCK_BY_HOST_BLOCK.get(host.getBlock())).defaultBlockState());
|
|
}
|
|
|
|
public BlockState hostStateByInfested(BlockState infested) {
|
|
return getNewStateWithProperties(INFESTED_TO_HOST_STATES, infested, () -> this.getHostBlock().defaultBlockState());
|
|
}
|
|
|
|
private static BlockState getNewStateWithProperties(Map<BlockState, BlockState> stateMap, BlockState state, Supplier<BlockState> supplier) {
|
|
return (BlockState)stateMap.computeIfAbsent(state, blockState -> {
|
|
BlockState blockState2 = (BlockState)supplier.get();
|
|
|
|
for (Property property : blockState.getProperties()) {
|
|
blockState2 = blockState2.hasProperty(property) ? blockState2.setValue(property, blockState.getValue(property)) : blockState2;
|
|
}
|
|
|
|
return blockState2;
|
|
});
|
|
}
|
|
}
|