下面列出了怎么用net.minecraftforge.common.property.IExtendedBlockState的API类实例代码及写法,或者点击链接到github查看源代码。
@Override
protected void renderWorldBlockWoodStatic(ITessellator tess, IExtendedBlockState state, BlockGrate block, EnumFacing side, TextureAtlasSprite sprite) {
// Setup
final TileEntityGrate.EnumOffset offset = AgriProperties.OFFSET.getValue(state);
final EnumFacing.Axis axis = AgriProperties.AXIS.getValue(state);
// Rotate
RenderUtilBase.rotateBlock(tess, EnumFacing.getFacingFromAxis(EnumFacing.AxisDirection.POSITIVE, axis));
// Offset
tess.translate(0, 0, offset.getOffset());
// Draw Grate
tess.drawScaledPrism(1, 0, 0, 3, 16, 2, sprite);
tess.drawScaledPrism(5, 0, 0, 7, 16, 2, sprite);
tess.drawScaledPrism(9, 0, 0, 11, 16, 2, sprite);
tess.drawScaledPrism(13, 0, 0, 15, 16, 2, sprite);
tess.drawScaledPrism(0, 1, 0, 16, 3, 2, sprite);
tess.drawScaledPrism(0, 5, 0, 16, 7, 2, sprite);
tess.drawScaledPrism(0, 9, 0, 16, 11, 2, sprite);
tess.drawScaledPrism(0, 13, 0, 16, 15, 2, sprite);
}
@Override
public void renderWorldBlockStatic(ITessellator tessellator, IBlockState state, BlockCrop block, EnumFacing side) {
TextureAtlasSprite sprite = RenderCrop.getIcon(TEXTURE);
this.renderBaseQuads(tessellator, side, sprite);
if (state instanceof IExtendedBlockState) {
IExtendedBlockState extendedState = (IExtendedBlockState) state;
IAgriPlant plant = extendedState.getValue(AgriProperties.CROP_PLANT);
int growthstage = extendedState.getValue(AgriProperties.GROWTH_STAGE);
if (extendedState.getValue(AgriProperties.CROSS_CROP)) {
tessellator.drawScaledPrism(0, 10, 2, 16, 11, 3, sprite);
tessellator.drawScaledPrism(0, 10, 13, 16, 11, 14, sprite);
tessellator.drawScaledPrism(2, 10, 0, 3, 11, 16, sprite);
tessellator.drawScaledPrism(13, 10, 0, 14, 11, 16, sprite);
}
if (plant != null) {
tessellator.addQuads(plant.getPlantQuads(extendedState, growthstage, side, tessellator));
}
}
}
@Override
public IBlockState getExtendedState(IBlockState oldState, IBlockAccess world, BlockPos pos)
{
if (this.isCamoBlock())
{
TileEntityEnderUtilities te = getTileEntitySafely(world, pos, TileEntityEnderUtilities.class);
if (te != null)
{
IExtendedBlockState state = (IExtendedBlockState) oldState;
state = state.withProperty(CAMOBLOCKSTATE, te.getCamoState());
state = state.withProperty(CAMOBLOCKSTATEEXTENDED, te.getCamoExtendedState());
return state;
}
}
return oldState;
}
@SuppressWarnings("deprecation")
@Override
public int getLightValue(IBlockState state, IBlockAccess world, BlockPos pos)
{
if (this.isCamoBlock())
{
IExtendedBlockState extendedState = (IExtendedBlockState) this.getExtendedState(state.getActualState(world, pos), world, pos);
IBlockState stateCamo = extendedState.getValue(CAMOBLOCKSTATE);
if (stateCamo != null)
{
// Can't call this same world sensitive method here, because it might/will recurse back here!
return stateCamo.getLightValue();
}
}
return super.getLightValue(state, world, pos);
}
@Override
public IBakedModel bake(IModelState state, VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter) {
final IModel model = loadBaseModel(state, format, bakedTextureGetter);
IBlockState blockState = null;
if (defaultBlockState.isPresent()) {
final Block defaultBlock = Block.REGISTRY.getObject(defaultBlockState.get());
if (defaultBlock != Blocks.AIR) {
blockState = defaultBlock.getDefaultState();
if (!(blockState instanceof IExtendedBlockState) ||
!((IExtendedBlockState)blockState).getUnlistedNames().contains(EvalModelState.PROPERTY)) {
Log.warn("State %s does not contain eval state property", blockState);
}
} else {
Log.warn("Can't find default block: %s", defaultBlockState.get());
}
}
final IVarExpander expander = evaluatorFactory.createExpander();
return new BakedEvalExpandModel(model, state, format, bakedTextureGetter, blockState, expander);
}
@Override
public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos) {
MetaTileEntity metaTileEntity = getMetaTileEntity(worldIn, pos);
if (metaTileEntity == null)
return state;
return ((IExtendedBlockState) state)
.withProperty(HARVEST_TOOL, metaTileEntity.getHarvestTool())
.withProperty(HARVEST_LEVEL, metaTileEntity.getHarvestLevel());
}
@Override
public <V> IExtendedBlockState withProperty(IUnlistedProperty<V> property, @Nullable V value) {
Optional<?> oldValue = unlistedProperties.get(property);
if (oldValue == null) {
throw new IllegalArgumentException("Cannot set unlisted property " + property + " as it does not exist in " + getBlock().getBlockState());
}
if (Objects.equals(oldValue.orElse(null), value)) {
return this;
}
if (!property.isValid(value)) {
throw new IllegalArgumentException("Cannot set unlisted property " + property + " to " + value + " on block " + Block.REGISTRY.getNameForObject(getBlock()) + ", it is not an allowed value");
}
boolean clean = true;
ImmutableMap.Builder<IUnlistedProperty<?>, Optional<?>> builder = ImmutableMap.builder();
for (Map.Entry<IUnlistedProperty<?>, Optional<?>> entry : unlistedProperties.entrySet()) {
IUnlistedProperty<?> key = entry.getKey();
Optional<?> newValue = key.equals(property) ? Optional.ofNullable(value) : entry.getValue();
if (newValue.isPresent()) clean = false;
builder.put(key, newValue);
}
if (clean) { // no dynamic properties, lookup normal state
return cleanState;
}
return new NumericalExtendedBlockState(normalState, builder.build(), cleanState);
}
@Override
public IBlockState getExtendedState(IBlockState state, IBlockAccess world, BlockPos pos) {
if(world.getTileEntity(pos) != null && world.getTileEntity(pos) instanceof TileRoutedPipe) {
TileRoutedPipe te = (TileRoutedPipe)world.getTileEntity(pos);
te.checkConnections(world, pos);
ArrayList<String> check = te.checkConnections(world, pos);
if(!hidden.equals(check)) {
hidden.clear();
hidden.addAll(check);
}
return ((IExtendedBlockState) state).withProperty(Properties.AnimationProperty, this.state);
}
return state;
}
@Override
public IBlockState getExtendedState(IBlockState state, IBlockAccess world, BlockPos pos) {
if(world.getTileEntity(pos) != null && world.getTileEntity(pos) instanceof TileChassisMkI) {
TileChassisMkI te = (TileChassisMkI)world.getTileEntity(pos);
ArrayList<String> check = te.checkConnections(world, pos);
if(!hidden.equals(check)) {
hidden.clear();
hidden.addAll(check);
}
return ((IExtendedBlockState) state).withProperty(Properties.AnimationProperty, this.state);
}
return state;
}
@Override
public IBlockState getExtendedState(IBlockState state, IBlockAccess world, BlockPos pos) {
if(world.getTileEntity(pos) != null && world.getTileEntity(pos) instanceof TileBlockingPipe) {
TileBlockingPipe te = (TileBlockingPipe)world.getTileEntity(pos);
ArrayList<String> check = te.checkConnections(world, pos);
if(!hidden.equals(check)) {
hidden.clear();
hidden.addAll(check);
}
return ((IExtendedBlockState) state).withProperty(Properties.AnimationProperty, this.state);
}
return state;
}
@Override
public IBlockState getExtendedState(IBlockState state, IBlockAccess world, BlockPos pos) {
if(world.getTileEntity(pos) != null && world.getTileEntity(pos) instanceof TileBasicPipe) {
TileBasicPipe te = (TileBasicPipe)world.getTileEntity(pos);
ArrayList<String> check = te.checkConnections(world, pos);
if(!hidden.equals(check)) {
hidden.clear();
hidden.addAll(check);
}
return ((IExtendedBlockState) state).withProperty(Properties.AnimationProperty, this.state);
}
return state;
}
@Override
public List<BakedQuad> getQuads(IBlockState state, EnumFacing side, long rand)
{
List<PropertyItem.PItem> items = Collections.emptyList();
if(state instanceof IExtendedBlockState) {
IExtendedBlockState extendedState = (IExtendedBlockState) state;
if(extendedState.getUnlistedNames().contains(BlockSmallVessel.INVENTORY)) {
if(extendedState.getValue(BlockSmallVessel.INVENTORY) != null) {
items = extendedState.getValue(BlockSmallVessel.INVENTORY).items;
}
}
// remove all world specific data
// This is so that the next call to getQuads from the transformed TRSRModel doesn't do this again
// otherwise table models inside table model items recursively calls this with the state of the original table
state = extendedState.withProperty(BlockSmallVessel.INVENTORY, PropertyItem.PropItems.EMPTY);
}
// models are symmetric, no need to rotate if there's nothing on it where rotation matters, so we just use default
if(items == null) {
return standard.getQuads(state, side, rand);
}
// the model returned by getActualModel should be a simple model with no special handling
return getActualModel(state, items).getQuads(state, side, rand);
}
@Override
public List<BakedQuad> getQuads(IBlockState state, EnumFacing side, long rand)
{
List<PropertyItem.PItem> items = Collections.emptyList();
if(state instanceof IExtendedBlockState) {
IExtendedBlockState extendedState = (IExtendedBlockState) state;
if(extendedState.getUnlistedNames().contains(BlockPitKiln.INVENTORY)) {
if(extendedState.getValue(BlockPitKiln.INVENTORY) != null) {
items = extendedState.getValue(BlockPitKiln.INVENTORY).items;
}
}
// remove all world specific data
// This is so that the next call to getQuads from the transformed TRSRModel doesn't do this again
// otherwise table models inside table model items recursively calls this with the state of the original table
state = extendedState.withProperty(BlockPitKiln.INVENTORY, PropertyItem.PropItems.EMPTY);
}
// models are symmetric, no need to rotate if there's nothing on it where rotation matters, so we just use default
if(items == null) {
return standard.getQuads(state, side, rand);
}
// the model returned by getActualModel should be a simple model with no special handling
return getActualModel(state, items).getQuads(state, side, rand);
}
@Override
public List<BakedQuad> getQuads(IBlockState state, EnumFacing side, long rand)
{
List<PropertyItem.PItem> items = Collections.emptyList();
EnumFacing face = EnumFacing.SOUTH;
if(state instanceof IExtendedBlockState) {
IExtendedBlockState extendedState = (IExtendedBlockState) state;
if(/*Config.renderTableItems &&*/ extendedState.getUnlistedNames().contains(BlockAnvil.INVENTORY)) {
if(extendedState.getValue(BlockAnvil.INVENTORY) != null) {
items = extendedState.getValue(BlockAnvil.INVENTORY).items;
}
}
// remove all world specific data
// This is so that the next call to getQuads from the transformed TRSRModel doesn't do this again
// otherwise table models inside table model items recursively calls this with the state of the original table
state = extendedState.withProperty(BlockAnvil.INVENTORY, PropertyItem.PropItems.EMPTY);
}
// models are symmetric, no need to rotate if there's nothing on it where rotation matters, so we just use default
if(items == null) {
return standard.getQuads(state, side, rand);
}
// the model returned by getActualModel should be a simple model with no special handling
return getActualModel(state, items, face).getQuads(state, side, rand);
}
@Override
public IBlockState getExtendedState(IBlockState state, IBlockAccess world, BlockPos pos)
{
if(state.getValue(META_PROPERTY) == WoodType.Palm)
{
B3DLoader.B3DState newState = new B3DLoader.B3DState(null, 1);
return ((IExtendedBlockState) state).withProperty(B3DLoader.B3DFrameProperty.INSTANCE, newState);
}
return state;
}
/*******************************************************************************
* 3. Blockstate
*******************************************************************************/
@Override
public IBlockState getExtendedState(IBlockState state, IBlockAccess world, BlockPos pos)
{
TileSmallVessel te = (TileSmallVessel) world.getTileEntity(pos);
if(te != null)
return te.writeExtendedBlockState((IExtendedBlockState) state);
return state;
}
/*******************************************************************************
* 3. Blockstate
*******************************************************************************/
@Override
public IBlockState getExtendedState(IBlockState state, IBlockAccess world, BlockPos pos)
{
TilePitKiln te = (TilePitKiln) world.getTileEntity(pos);
if(te != null)
return te.writeExtendedBlockState((IExtendedBlockState) state);
return state;
}
/*******************************************************************************
* 3. Blockstate
*******************************************************************************/
@Override
public IBlockState getExtendedState(IBlockState state, IBlockAccess world, BlockPos pos)
{
TileAnvil te = (TileAnvil) world.getTileEntity(pos);
if(te != null)
return te.writeExtendedBlockState((IExtendedBlockState) state);
return state;
}
protected IExtendedBlockState setInventoryDisplay(IExtendedBlockState state)
{
PropertyItem.PropItems toDisplay = new PropertyItem.PropItems();
ItemStack stack = getStackInSlot(0);
float x = 0, z = 0;
if(stack != ItemStack.EMPTY)
{
PropertyItem.PItem item = getDisplayItem(stack, world, null, x, z);
if(item != null) {
toDisplay.items.add(item);
}
}
// add inventory if needed
return state.withProperty(BlockPitKiln.INVENTORY, toDisplay);
}
public byte getValue(@Nonnull IBlockState state, byte orElse) {
Preconditions.checkNotNull(state);
if (state instanceof IExtendedBlockState) {
final Byte wrapped = ((IExtendedBlockState) state).getValue(this);
if (wrapped != null) {
return wrapped;
}
}
return orElse;
}
@Nonnull
public <T extends IBlockState> T setValue(@Nonnull T state, byte value) {
Preconditions.checkNotNull(state);
if (state instanceof IExtendedBlockState) {
return (T)((IExtendedBlockState)state).withProperty(this, value);
} else {
return state;
}
}
@Override
public IBlockState getExtendedState(IBlockState state, IBlockAccess world, BlockPos pos) {
Optional<TileEntityCrop> tile = getCropTile(world, pos);
return ((IExtendedBlockState) state)
.withProperty(AgriProperties.CROP_PLANT, tile.map(TileEntityCrop::getSeed).map(s -> s.getPlant()).orElse(null))
.withProperty(AgriProperties.GROWTH_STAGE, tile.map(TileEntityCrop::getGrowthStage).orElse(0))
.withProperty(AgriProperties.CROSS_CROP, tile.map(TileEntityCrop::isCrossCrop).orElse(false));
}
@Override
public void renderWorldBlockStatic(ITessellator tessellator, IBlockState state, B block, EnumFacing side) {
if (state instanceof IExtendedBlockState) {
// Get the custom Wood Type.
final CustomWoodType type = CustomWoodTypeRegistry.getFromState(state).orElse(CustomWoodTypeRegistry.DEFAULT);
// Render the block with the given wood type.
this.renderWorldBlockWoodStatic(tessellator, (IExtendedBlockState) state, block, side, type.getIcon());
}
}
@Override
protected void renderWorldBlockWoodStatic(ITessellator tess, IExtendedBlockState state, BlockSeedStorage block, EnumFacing side, TextureAtlasSprite icon) {
tess.pushMatrix();
rotateBlock(tess, AgriProperties.FACING.getValue(state));
renderSides(tess, icon);
tess.popMatrix();
}
@Override
protected void renderWorldBlockWoodStatic(ITessellator tess, IExtendedBlockState state, BlockWaterTank block, EnumFacing face, TextureAtlasSprite sprite) {
final AgriSideMetaMatrix connections = new AgriSideMetaMatrix();
connections.readFromBlockState(state);
for (EnumFacing side : EnumFacing.HORIZONTALS) {
renderSide(tess, side, connections.get(side), sprite);
}
renderBottom(tess, connections.get(EnumFacing.DOWN), sprite);
}
@Override
public void renderWorldBlockStatic(ITessellator tessellator, IBlockState state, BlockSprinkler block, EnumFacing side) {
if (state instanceof IExtendedBlockState) {
// Resolve the wood type.
final CustomWoodType type = CustomWoodTypeRegistry.getFromState(state).orElse(CustomWoodTypeRegistry.DEFAULT);
// Render the connector.
this.renderConnector(tessellator, type.getIcon());
}
}
@Override
@SideOnly(Side.CLIENT)
public List<BakedQuad> getPlantQuads(IExtendedBlockState state, int growthStage, EnumFacing direction, Function<ResourceLocation, TextureAtlasSprite> textureToIcon) {
//The quads returned from this method are added to the tessellator,
// however the plant renderer directly adds them to the tessellator, so an empty list is returned
if (textureToIcon instanceof ITessellator) {
PlantRenderer.renderPlant((ITessellator) textureToIcon, this, growthStage);
}
return Collections.emptyList();
}
@Override
synchronized public List<BakedQuad> getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, long rand)
{
// Item model
if (state == null)
{
return this.itemQuads;
}
IExtendedBlockState extendedState = (IExtendedBlockState) state;
IBlockState actualState = extendedState.getClean();
IBlockState camoState = extendedState.getValue(BlockEnderUtilitiesTileEntity.CAMOBLOCKSTATE);
boolean validCamo = camoState != null && camoState.getBlock() != Blocks.AIR;
Optional<IBlockState> key = Optional.of(actualState);
Map<Optional<IBlockState>, ImmutableMap<Optional<EnumFacing>, ImmutableList<BakedQuad>>> cache = validCamo ? QUAD_CACHE_CAMO : QUAD_CACHE_NORMAL;
ImmutableMap<Optional<EnumFacing>, ImmutableList<BakedQuad>> map = cache.get(key);
if (map == null)
{
IBakedModel bakedModel = validCamo ? this.getBakedOverlayModel(actualState) : this.getBakedBaseModel(actualState);
map = this.getQuadsForState(bakedModel, extendedState, rand, validCamo);
cache.put(key, map);
}
return map.get(Optional.ofNullable(side));
}
private ImmutableMap<Optional<EnumFacing>, ImmutableList<BakedQuad>> getQuadsForState(
IBakedModel bakedModel, IExtendedBlockState extendedState, long rand, boolean validCamo)
{
ImmutableMap.Builder<Optional<EnumFacing>, ImmutableList<BakedQuad>> mapBuilder = ImmutableMap.builder();
for (EnumFacing side : EnumFacing.values())
{
ImmutableList.Builder<BakedQuad> quads = ImmutableList.builder();
// Camo model, only add the quads if there is a label on this side
if (validCamo)
{
quads.addAll(this.getQuadsForCamoModelSide(side, extendedState, bakedModel, rand));
}
// Not a camo model, always return the quads of the normal model
else
{
quads.addAll(bakedModel.getQuads(extendedState, side, rand));
}
mapBuilder.put(Optional.ofNullable(side), quads.build());
}
mapBuilder.put(Optional.ofNullable(null), ImmutableList.copyOf(bakedModel.getQuads(extendedState, null, rand)));
return mapBuilder.build();
}
private static VariantModelState getModelSelectors(IBlockState state) {
if (state instanceof IExtendedBlockState) {
final IExtendedBlockState extendedState = (IExtendedBlockState)state;
if (extendedState.getUnlistedNames().contains(VariantModelState.PROPERTY)) {
final VariantModelState result = extendedState.getValue(VariantModelState.PROPERTY);
if (result != null)
return result;
}
}
return VariantModelState.EMPTY;
}