/// <inheritdoc /> public override void RandomUpdate(World world, Vector3i position, uint data) { var orientation = (Orientation)(data & 0b00_0011); var age = (int)((data & 0b1_1100) >> 2); if (age < 7) { world.SetBlock(this.AsInstance((uint)(((age + 1) << 2) | (int)orientation)), position); } else if (world.GetBlock(position.Below())?.Block == Air) { world.SetBlock(this.AsInstance((uint)orientation), position.Below()); } }
/// <summary> /// Check if a given block is lowered exactly one height step. /// </summary> public static bool IsLowered(this World world, Vector3i position) { BlockInstance?below = world.GetBlock(position.Below()); return(below?.Block is IHeightVariable block && block.GetHeight(below.Data) == IHeightVariable.MaximumHeight - 1); }
/// <inheritdoc /> public override void RandomUpdate(World world, Vector3i position, uint data) { var age = (int)(data & 0b00_0111); if (age < 7) { world.SetBlock(this.AsInstance((uint)(age + 1)), position); } else { if (!(world.GetBlock(position.Above())?.Block.IsReplaceable ?? false)) { return; } var height = 0; for (var offset = 0; offset < maxHeight; offset++) { if (world.GetBlock(position.Below(offset))?.Block == this) { height++; } else { break; } } if (height < maxHeight) { Place(world, position.Above()); } } }
/// <inheritdoc /> protected override void DoDestroy(World world, Vector3i position, uint data, PhysicsEntity?entity) { bool isBase = (data & 0b1) == 0; world.SetDefaultBlock(position); world.SetDefaultBlock(isBase ? position.Above() : position.Below()); }
/// <inheritdoc /> public override void BlockUpdate(World world, Vector3i position, uint data, BlockSide side) { // Check if this block is the lower part and if the ground supports plant growth. if (side == BlockSide.Bottom && (data & 0b1) == 0 && (world.GetBlock(position.Below())?.Block ?? Air) is not IPlantable) { Destroy(world, position); } }
/// <inheritdoc /> public override void BlockUpdate(World world, Vector3i position, uint data, BlockSide side) { if (side == BlockSide.Bottom) { Block below = world.GetBlock(position.Below())?.Block ?? Air; if (below != requiredGround && below != this) { ScheduleDestroy(world, position); } } }
/// <summary> /// Check if a given position has solid ground below it. /// </summary> public static bool HasSolidGround(this World world, Vector3i position, bool solidify = false) { Vector3i groundPosition = position.Below(); bool isSolid = world.IsSolid(groundPosition, out BlockInstance ground); if (!solidify || isSolid || ground.Block is not IPotentiallySolid solidifiable) { return(isSolid); } solidifiable.BecomeSolid(world, groundPosition); return(true); }
/// <inheritdoc /> public override bool CanPlace(World world, Vector3i position, PhysicsEntity?entity) { Block down = world.GetBlock(position.Below())?.Block ?? Air; return(down == requiredGround || down == this); }
/// <inheritdoc /> public override bool CanPlace(World world, Vector3i position, PhysicsEntity?entity) { return(world.GetBlock(position.Above())?.Block.IsReplaceable == true && (world.GetBlock(position.Below())?.Block ?? Air) is IPlantable); }