87 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			87 lines
		
	
	
	
		
			3.7 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.EntitySpawnReason;
 | |
| 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, EntitySpawnReason.TRIGGERED);
 | |
| 		if (silverfish != null) {
 | |
| 			silverfish.snapTo(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;
 | |
| 		});
 | |
| 	}
 | |
| }
 |