mirror of
https://github.com/chylex/Hardcore-Ender-Expansion-2.git
synced 2025-09-15 23:32:08 +02:00
Compare commits
2 Commits
5564fc4a24
...
components
Author | SHA1 | Date | |
---|---|---|---|
1135c192bb
|
|||
8933d8d8cc
|
@@ -580,6 +580,8 @@ e66091a13a6e7593eb5bd971978d24a5a0e375b3 data/hee/loot_tables/blocks/whitebark.j
|
|||||||
9bd3a9e24162d2c81047b834f8f79d6cabec86be data/hee/loot_tables/blocks/whitebark_planks.json
|
9bd3a9e24162d2c81047b834f8f79d6cabec86be data/hee/loot_tables/blocks/whitebark_planks.json
|
||||||
7d84dc443a052e349593b71d2c0a523e75396cdf data/hee/loot_tables/blocks/whitebark_slab.json
|
7d84dc443a052e349593b71d2c0a523e75396cdf data/hee/loot_tables/blocks/whitebark_slab.json
|
||||||
83e0b81adb3f9dd488397e8459b95f7b0ce19927 data/hee/loot_tables/blocks/whitebark_stairs.json
|
83e0b81adb3f9dd488397e8459b95f7b0ce19927 data/hee/loot_tables/blocks/whitebark_stairs.json
|
||||||
|
37f3c55266db3db8dc6d22fdbaf3d53243016b77 data/hee/tags/blocks/gloomrock_particles.json
|
||||||
|
1a70c674d979a59cea18d92f2227ab8a5ed2ccc7 data/hee/tags/blocks/void_portal_frame_crafted.json
|
||||||
f5996244831ab38fe1fae2f304bbd7825d6ad98b data/minecraft/tags/blocks/bamboo_plantable_on.json
|
f5996244831ab38fe1fae2f304bbd7825d6ad98b data/minecraft/tags/blocks/bamboo_plantable_on.json
|
||||||
479189f9b35a3c8f795539daf6a1809130242c5b data/minecraft/tags/blocks/flower_pots.json
|
479189f9b35a3c8f795539daf6a1809130242c5b data/minecraft/tags/blocks/flower_pots.json
|
||||||
424e2e03cf62f23f4496468a97b9f0df060df9fe data/minecraft/tags/blocks/impermeable.json
|
424e2e03cf62f23f4496468a97b9f0df060df9fe data/minecraft/tags/blocks/impermeable.json
|
||||||
|
17
data/gen/data/hee/tags/blocks/gloomrock_particles.json
Normal file
17
data/gen/data/hee/tags/blocks/gloomrock_particles.json
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"replace": false,
|
||||||
|
"values": [
|
||||||
|
"hee:gloomrock",
|
||||||
|
"hee:gloomrock_bricks",
|
||||||
|
"hee:gloomrock_smooth",
|
||||||
|
"hee:gloomrock_smooth_red",
|
||||||
|
"hee:gloomrock_smooth_orange",
|
||||||
|
"hee:gloomrock_smooth_yellow",
|
||||||
|
"hee:gloomrock_smooth_green",
|
||||||
|
"hee:gloomrock_smooth_cyan",
|
||||||
|
"hee:gloomrock_smooth_blue",
|
||||||
|
"hee:gloomrock_smooth_purple",
|
||||||
|
"hee:gloomrock_smooth_magenta",
|
||||||
|
"hee:gloomrock_smooth_white"
|
||||||
|
]
|
||||||
|
}
|
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"replace": false,
|
||||||
|
"values": [
|
||||||
|
"hee:void_portal_frame_crafted",
|
||||||
|
"hee:void_portal_storage_crafted"
|
||||||
|
]
|
||||||
|
}
|
@@ -37,7 +37,7 @@ import net.minecraftforge.common.data.ExistingFileHelper
|
|||||||
class BlockModels(generator: DataGenerator, modid: String, existingFileHelper: ExistingFileHelper) : BlockModelProvider(generator, modid, existingFileHelper) {
|
class BlockModels(generator: DataGenerator, modid: String, existingFileHelper: ExistingFileHelper) : BlockModelProvider(generator, modid, existingFileHelper) {
|
||||||
override fun registerModels() {
|
override fun registerModels() {
|
||||||
for (block in ModBlocks.ALL) {
|
for (block in ModBlocks.ALL) {
|
||||||
(block as? IHeeBlock)?.model?.let { registerModel(block, it.blockModel) { builder -> builder } }
|
(block as? IHeeBlock)?.let { registerModel(block, it.model.generate(block).blockModel) { builder -> builder } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -32,7 +32,7 @@ import net.minecraftforge.common.data.ExistingFileHelper
|
|||||||
class BlockStates(generator: DataGenerator, modid: String, existingFileHelper: ExistingFileHelper) : BlockStateProvider(generator, modid, existingFileHelper) {
|
class BlockStates(generator: DataGenerator, modid: String, existingFileHelper: ExistingFileHelper) : BlockStateProvider(generator, modid, existingFileHelper) {
|
||||||
override fun registerStatesAndModels() {
|
override fun registerStatesAndModels() {
|
||||||
for (block in ModBlocks.ALL) {
|
for (block in ModBlocks.ALL) {
|
||||||
(block as? IHeeBlock)?.model?.let { registerState(block, it.blockState) }
|
(block as? IHeeBlock)?.let { registerState(block, it.model.generate(block).blockState) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -39,15 +39,13 @@ import net.minecraftforge.common.data.ExistingFileHelper
|
|||||||
class ItemModels(generator: DataGenerator, modid: String, existingFileHelper: ExistingFileHelper) : ItemModelProvider(generator, modid, existingFileHelper) {
|
class ItemModels(generator: DataGenerator, modid: String, existingFileHelper: ExistingFileHelper) : ItemModelProvider(generator, modid, existingFileHelper) {
|
||||||
override fun registerModels() {
|
override fun registerModels() {
|
||||||
for (item in ModItems.ALL) {
|
for (item in ModItems.ALL) {
|
||||||
(item as? IHeeItem)?.model?.let {
|
(item as? IHeeItem)?.let { registerModel(item, it.model) }
|
||||||
registerModel(item, it)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (block in ModBlocks.ALL) {
|
for (block in ModBlocks.ALL) {
|
||||||
(block as? IHeeBlock)?.model?.itemModel?.let {
|
(block as? IHeeBlock)
|
||||||
registerModel(if (it.asItem) block.asItem() else block, it.model)
|
?.let { it.model.generate(block).itemModel }
|
||||||
}
|
?.let { registerModel(if (it.asItem) block.asItem() else block, it.model) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -6,8 +6,6 @@ import chylex.hee.client.DebugMenu
|
|||||||
import chylex.hee.client.GameModeToggle
|
import chylex.hee.client.GameModeToggle
|
||||||
import chylex.hee.client.TerritoryVoidDebug
|
import chylex.hee.client.TerritoryVoidDebug
|
||||||
import chylex.hee.game.block.BlockScaffoldingDebug
|
import chylex.hee.game.block.BlockScaffoldingDebug
|
||||||
import chylex.hee.game.block.HeeBlock
|
|
||||||
import chylex.hee.game.block.properties.BlockBuilder
|
|
||||||
import chylex.hee.game.command.client.CommandClientDebugToggles
|
import chylex.hee.game.command.client.CommandClientDebugToggles
|
||||||
import chylex.hee.game.command.client.CommandClientScaffolding
|
import chylex.hee.game.command.client.CommandClientScaffolding
|
||||||
import chylex.hee.game.command.server.CommandServerInstability
|
import chylex.hee.game.command.server.CommandServerInstability
|
||||||
@@ -45,9 +43,8 @@ internal object Debug : IDebugModule {
|
|||||||
CommandServerTestWorld
|
CommandServerTestWorld
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun createScaffoldingBlock(builder: BlockBuilder): HeeBlock {
|
override val scaffoldingBlockBehavior
|
||||||
return BlockScaffoldingDebug(builder)
|
get() = BlockScaffoldingDebug
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
fun onClientSetup(@Suppress("UNUSED_PARAMETER") e: FMLClientSetupEvent) {
|
fun onClientSetup(@Suppress("UNUSED_PARAMETER") e: FMLClientSetupEvent) {
|
||||||
|
@@ -2,7 +2,7 @@ package chylex.hee.game.block
|
|||||||
|
|
||||||
import chylex.hee.debug.PowerShell
|
import chylex.hee.debug.PowerShell
|
||||||
import chylex.hee.game.Environment
|
import chylex.hee.game.Environment
|
||||||
import chylex.hee.game.block.properties.BlockBuilder
|
import chylex.hee.game.block.components.IPlayerUseBlockComponent
|
||||||
import chylex.hee.game.command.client.CommandClientScaffolding
|
import chylex.hee.game.command.client.CommandClientScaffolding
|
||||||
import chylex.hee.game.world.generation.structure.file.StructureFile
|
import chylex.hee.game.world.generation.structure.file.StructureFile
|
||||||
import chylex.hee.game.world.generation.util.WorldToStructureWorldAdapter
|
import chylex.hee.game.world.generation.util.WorldToStructureWorldAdapter
|
||||||
@@ -27,14 +27,13 @@ import net.minecraft.util.Direction.WEST
|
|||||||
import net.minecraft.util.Hand
|
import net.minecraft.util.Hand
|
||||||
import net.minecraft.util.Util
|
import net.minecraft.util.Util
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.util.math.BlockRayTraceResult
|
|
||||||
import net.minecraft.util.text.StringTextComponent
|
import net.minecraft.util.text.StringTextComponent
|
||||||
import net.minecraft.util.text.TextFormatting
|
import net.minecraft.util.text.TextFormatting
|
||||||
import net.minecraft.world.World
|
import net.minecraft.world.World
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
|
|
||||||
class BlockScaffoldingDebug(builder: BlockBuilder) : BlockScaffolding(builder) {
|
object BlockScaffoldingDebug : IPlayerUseBlockComponent {
|
||||||
override fun onBlockActivated(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, hit: BlockRayTraceResult): ActionResultType {
|
override fun use(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, hand: Hand): ActionResultType {
|
||||||
if (world.isRemote && player.isSneaking && !player.abilities.isFlying) {
|
if (world.isRemote && player.isSneaking && !player.abilities.isFlying) {
|
||||||
val palette = CommandClientScaffolding.currentPalette
|
val palette = CommandClientScaffolding.currentPalette
|
||||||
|
|
||||||
@@ -54,7 +53,7 @@ class BlockScaffoldingDebug(builder: BlockBuilder) : BlockScaffolding(builder) {
|
|||||||
val box = BoundingBox(minPos, maxPos)
|
val box = BoundingBox(minPos, maxPos)
|
||||||
val serverWorld = Environment.getDimension(world.dimensionKey)
|
val serverWorld = Environment.getDimension(world.dimensionKey)
|
||||||
|
|
||||||
val (structureTag, missingMappings) = StructureFile.save(WorldToStructureWorldAdapter(serverWorld, serverWorld.rand, box.min), box.size, palette, this)
|
val (structureTag, missingMappings) = StructureFile.save(WorldToStructureWorldAdapter(serverWorld, serverWorld.rand, box.min), box.size, palette, state.block)
|
||||||
val structureFile = Files.createTempDirectory("HardcoreEnderExpansion_Structure_").resolve(CommandClientScaffolding.currentFile).toFile()
|
val structureFile = Files.createTempDirectory("HardcoreEnderExpansion_Structure_").resolve(CommandClientScaffolding.currentFile).toFile()
|
||||||
|
|
||||||
CompressedStreamTools.write(structureTag, structureFile)
|
CompressedStreamTools.write(structureTag, structureFile)
|
||||||
|
@@ -5,7 +5,7 @@ import chylex.hee.game.block.properties.BlockDrop
|
|||||||
import net.minecraft.block.Block
|
import net.minecraft.block.Block
|
||||||
import net.minecraft.loot.LootTables
|
import net.minecraft.loot.LootTables
|
||||||
|
|
||||||
open class HeeBlock(builder: BlockBuilder) : Block(builder.p), IHeeBlock {
|
open class HeeBlock(builder: BlockBuilder) : Block(builder.p), IHeeBlock { // TODO abstract
|
||||||
override val drop
|
override val drop
|
||||||
get() = if (lootTable == LootTables.EMPTY) BlockDrop.Nothing else BlockDrop.Self
|
get() = if (lootTable == LootTables.EMPTY) BlockDrop.Nothing else BlockDrop.Self
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,5 @@
|
|||||||
|
package chylex.hee.game.block
|
||||||
|
|
||||||
|
import net.minecraft.block.Block
|
||||||
|
|
||||||
|
abstract class HeeBlock2(properties: Properties) : Block(properties), IHeeBlock
|
@@ -0,0 +1,229 @@
|
|||||||
|
package chylex.hee.game.block
|
||||||
|
|
||||||
|
import chylex.hee.game.block.builder.HeeBlockComponents
|
||||||
|
import chylex.hee.game.world.util.getBlock
|
||||||
|
import chylex.hee.util.forge.Side
|
||||||
|
import chylex.hee.util.forge.Sided
|
||||||
|
import chylex.hee.util.forge.asBool
|
||||||
|
import net.minecraft.block.Block
|
||||||
|
import net.minecraft.block.BlockRenderType
|
||||||
|
import net.minecraft.block.BlockState
|
||||||
|
import net.minecraft.client.util.ITooltipFlag
|
||||||
|
import net.minecraft.entity.Entity
|
||||||
|
import net.minecraft.entity.EntitySpawnPlacementRegistry.PlacementType
|
||||||
|
import net.minecraft.entity.EntityType
|
||||||
|
import net.minecraft.entity.LivingEntity
|
||||||
|
import net.minecraft.entity.player.PlayerEntity
|
||||||
|
import net.minecraft.item.BlockItemUseContext
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
|
import net.minecraft.loot.LootContext
|
||||||
|
import net.minecraft.state.StateContainer.Builder
|
||||||
|
import net.minecraft.tileentity.TileEntity
|
||||||
|
import net.minecraft.util.ActionResultType
|
||||||
|
import net.minecraft.util.Direction
|
||||||
|
import net.minecraft.util.Hand
|
||||||
|
import net.minecraft.util.Mirror
|
||||||
|
import net.minecraft.util.Rotation
|
||||||
|
import net.minecraft.util.math.BlockPos
|
||||||
|
import net.minecraft.util.math.BlockRayTraceResult
|
||||||
|
import net.minecraft.util.math.RayTraceResult
|
||||||
|
import net.minecraft.util.math.shapes.ISelectionContext
|
||||||
|
import net.minecraft.util.math.shapes.VoxelShape
|
||||||
|
import net.minecraft.util.text.ITextComponent
|
||||||
|
import net.minecraft.world.Explosion
|
||||||
|
import net.minecraft.world.IBlockReader
|
||||||
|
import net.minecraft.world.IWorld
|
||||||
|
import net.minecraft.world.IWorldReader
|
||||||
|
import net.minecraft.world.World
|
||||||
|
import net.minecraft.world.server.ServerWorld
|
||||||
|
import java.util.Random
|
||||||
|
|
||||||
|
abstract class HeeBlockWithComponents(properties: Properties, components: HeeBlockComponents) : HeeBlock2(properties) {
|
||||||
|
private companion object {
|
||||||
|
private val RAND = Random()
|
||||||
|
}
|
||||||
|
|
||||||
|
private val states = components.states.build()
|
||||||
|
|
||||||
|
private val name = components.name
|
||||||
|
private val tooltip = components.tooltip
|
||||||
|
|
||||||
|
private val shape = components.shape
|
||||||
|
private val renderType = components.renderType
|
||||||
|
private val ambientOcclusionValue = components.ambientOcclusionValue
|
||||||
|
private val clientEffects = components.clientEffects
|
||||||
|
|
||||||
|
private val drops = components.drops
|
||||||
|
private val harvestability = components.harvestability
|
||||||
|
private val experience = components.experience
|
||||||
|
private val flammability = components.flammability
|
||||||
|
|
||||||
|
private val entity = components.entity
|
||||||
|
private val placement = components.placement
|
||||||
|
private val onAdded = components.onAdded
|
||||||
|
private val onNeighborChanged = components.onNeighborChanged
|
||||||
|
private val setStateFromNeighbor = components.setStateFromNeighbor
|
||||||
|
|
||||||
|
private val scheduledTick = components.scheduledTick
|
||||||
|
private val randomTick = components.randomTick
|
||||||
|
|
||||||
|
private val playerUse = components.playerUse
|
||||||
|
private val onExploded = components.onExploded
|
||||||
|
private val onCreatureSpawning = components.onCreatureSpawning
|
||||||
|
private val collideWithEntity = components.collideWithEntity
|
||||||
|
|
||||||
|
private var isAir = components.isAir
|
||||||
|
|
||||||
|
init {
|
||||||
|
defaultState = states.applyDefaults(stateContainer.baseState)
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract override fun fillStateContainer(builder: Builder<Block, BlockState>)
|
||||||
|
|
||||||
|
override fun rotate(state: BlockState, rotation: Rotation): BlockState {
|
||||||
|
return states.getRotatedState(state, rotation)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun mirror(state: BlockState, mirror: Mirror): BlockState {
|
||||||
|
return states.getMirroredState(state, mirror)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getTranslationKey(): String {
|
||||||
|
return name?.translationKey ?: super.getTranslationKey()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Sided(Side.CLIENT)
|
||||||
|
override fun addInformation(stack: ItemStack, world: IBlockReader?, lines: MutableList<ITextComponent>, flags: ITooltipFlag) {
|
||||||
|
tooltip?.add(lines, stack, flags.isAdvanced, world)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
override fun getShape(state: BlockState, worldIn: IBlockReader, pos: BlockPos, context: ISelectionContext): VoxelShape {
|
||||||
|
return shape?.getShape(state) ?: super.getShape(state, worldIn, pos, context)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
override fun getCollisionShape(state: BlockState, worldIn: IBlockReader, pos: BlockPos, context: ISelectionContext): VoxelShape {
|
||||||
|
return shape?.getCollisionShape(state) ?: super.getCollisionShape(state, worldIn, pos, context)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getRaytraceShape(state: BlockState, worldIn: IBlockReader, pos: BlockPos): VoxelShape {
|
||||||
|
return super.getRaytraceShape(state, worldIn, pos)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
override fun getRenderType(state: BlockState): BlockRenderType {
|
||||||
|
return renderType ?: super.getRenderType(state)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Sided(Side.CLIENT)
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
override fun getAmbientOcclusionLightValue(state: BlockState, worldIn: IBlockReader, pos: BlockPos): Float {
|
||||||
|
return ambientOcclusionValue ?: super.getAmbientOcclusionLightValue(state, worldIn, pos)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Sided(Side.CLIENT)
|
||||||
|
override fun animateTick(state: BlockState, world: World, pos: BlockPos, rand: Random) {
|
||||||
|
clientEffects?.randomTick(state, world, pos, rand)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
override fun getDrops(state: BlockState, context: LootContext.Builder): MutableList<ItemStack> {
|
||||||
|
return drops?.getDrops(state, context) ?: super.getDrops(state, context)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getPickBlock(state: BlockState, target: RayTraceResult, world: IBlockReader, pos: BlockPos, player: PlayerEntity): ItemStack {
|
||||||
|
return drops?.getPickBlock(state, world, pos) ?: super.getPickBlock(state, target, world, pos, player)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun canHarvestBlock(state: BlockState, world: IBlockReader, pos: BlockPos, player: PlayerEntity): Boolean {
|
||||||
|
return harvestability?.canHarvest(player)?.asBool ?: super.canHarvestBlock(state, world, pos, player)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getExpDrop(state: BlockState, world: IWorldReader, pos: BlockPos, fortune: Int, silktouch: Int): Int {
|
||||||
|
return experience?.getExperience((world as? World)?.rand ?: RAND) ?: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getFlammability(state: BlockState, world: IBlockReader, pos: BlockPos, face: Direction): Int {
|
||||||
|
return flammability?.takeIfFlammable(state)?.flammability ?: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getFireSpreadSpeed(state: BlockState, world: IBlockReader, pos: BlockPos, face: Direction): Int {
|
||||||
|
return flammability?.takeIfFlammable(state)?.fireSpread ?: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hasTileEntity(state: BlockState): Boolean {
|
||||||
|
return entity != null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createTileEntity(state: BlockState, world: IBlockReader): TileEntity? {
|
||||||
|
return entity?.create()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
override fun isValidPosition(state: BlockState, world: IWorldReader, pos: BlockPos): Boolean {
|
||||||
|
return placement?.isPositionValid(state, world, pos) ?: super.isValidPosition(state, world, pos)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getStateForPlacement(context: BlockItemUseContext): BlockState? {
|
||||||
|
return placement?.getPlacedState(defaultState, context.world, context.pos, context) ?: super.getStateForPlacement(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBlockPlacedBy(world: World, pos: BlockPos, state: BlockState, placer: LivingEntity?, stack: ItemStack) {
|
||||||
|
placement?.onPlacedBy(state, world, pos, placer, stack)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBlockAdded(state: BlockState, world: World, pos: BlockPos, oldState: BlockState, isMoving: Boolean) {
|
||||||
|
onAdded?.onAdded(state, world, pos)
|
||||||
|
scheduledTick?.onAdded(state, world, pos, world.rand)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
override fun neighborChanged(state: BlockState, world: World, pos: BlockPos, neighborBlock: Block, neighborPos: BlockPos, isMoving: Boolean) {
|
||||||
|
super.neighborChanged(state, world, pos, neighborBlock, neighborPos, isMoving)
|
||||||
|
onNeighborChanged?.onNeighborChanged(state, world, pos, neighborBlock, neighborPos.getBlock(world), neighborPos)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
override fun updatePostPlacement(state: BlockState, neighborFacing: Direction, neighborState: BlockState, world: IWorld, currentPos: BlockPos, neighborPos: BlockPos): BlockState {
|
||||||
|
return setStateFromNeighbor?.getNewState(state, world, currentPos, neighborFacing, neighborPos) ?: super.updatePostPlacement(state, neighborFacing, neighborState, world, currentPos, neighborPos)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun tick(state: BlockState, world: ServerWorld, pos: BlockPos, rand: Random) {
|
||||||
|
scheduledTick?.onTick(state, world, pos, rand)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun randomTick(state: BlockState, world: ServerWorld, pos: BlockPos, rand: Random) {
|
||||||
|
randomTick?.onTick(state, world, pos, rand)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
override fun onBlockActivated(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, hit: BlockRayTraceResult): ActionResultType {
|
||||||
|
return playerUse?.use(state, world, pos, player, hand) ?: super.onBlockActivated(state, world, pos, player, hand, hit)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun canDropFromExplosion(state: BlockState, world: IBlockReader, pos: BlockPos, explosion: Explosion): Boolean {
|
||||||
|
return onExploded?.canDrop(explosion) ?: super.canDropFromExplosion(state, world, pos, explosion)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBlockExploded(state: BlockState, world: World, pos: BlockPos, explosion: Explosion) {
|
||||||
|
onExploded?.onExploded(state, world, pos, explosion)
|
||||||
|
super.onBlockExploded(state, world, pos, explosion)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun canCreatureSpawn(state: BlockState, world: IBlockReader, pos: BlockPos, type: PlacementType?, entityType: EntityType<*>?): Boolean {
|
||||||
|
return onCreatureSpawning?.canSpawn(world, pos, type, entityType)?.asBool ?: super.canCreatureSpawn(state, world, pos, type, entityType)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onEntityCollision(state: BlockState, world: World, pos: BlockPos, entity: Entity) {
|
||||||
|
collideWithEntity?.collide(state, world, pos, entity)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isAir(state: BlockState, world: IBlockReader, pos: BlockPos): Boolean {
|
||||||
|
return isAir ?: super.isAir(state, world, pos)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun propagatesSkylightDown(state: BlockState, world: IBlockReader, pos: BlockPos): Boolean {
|
||||||
|
return isAir == true || super.propagatesSkylightDown(state, world, pos)
|
||||||
|
}
|
||||||
|
}
|
@@ -1,12 +1,13 @@
|
|||||||
package chylex.hee.game.block
|
package chylex.hee.game.block
|
||||||
|
|
||||||
import chylex.hee.client.text.LocalizationStrategy
|
import chylex.hee.client.text.LocalizationStrategy
|
||||||
|
import chylex.hee.game.block.builder.AbstractHeeBlockBuilder
|
||||||
import chylex.hee.game.block.properties.BlockDrop
|
import chylex.hee.game.block.properties.BlockDrop
|
||||||
import chylex.hee.game.block.properties.BlockModel
|
import chylex.hee.game.block.properties.BlockModel
|
||||||
import chylex.hee.game.block.properties.BlockRenderLayer
|
import chylex.hee.game.block.properties.BlockRenderLayer
|
||||||
import chylex.hee.game.block.properties.BlockRenderLayer.SOLID
|
import chylex.hee.game.block.properties.BlockRenderLayer.SOLID
|
||||||
import chylex.hee.game.block.properties.BlockTint
|
import chylex.hee.game.block.properties.BlockTint
|
||||||
import chylex.hee.game.block.properties.IBlockStateModel
|
import chylex.hee.game.block.properties.IBlockStateModelSupplier
|
||||||
import net.minecraft.block.Block
|
import net.minecraft.block.Block
|
||||||
import net.minecraft.tags.ITag.INamedTag
|
import net.minecraft.tags.ITag.INamedTag
|
||||||
|
|
||||||
@@ -17,7 +18,7 @@ interface IHeeBlock {
|
|||||||
val localizationExtra: Map<String, String>
|
val localizationExtra: Map<String, String>
|
||||||
get() = emptyMap()
|
get() = emptyMap()
|
||||||
|
|
||||||
val model: IBlockStateModel
|
val model: IBlockStateModelSupplier
|
||||||
get() = BlockModel.Cube
|
get() = BlockModel.Cube
|
||||||
|
|
||||||
val renderLayer: BlockRenderLayer
|
val renderLayer: BlockRenderLayer
|
||||||
@@ -31,4 +32,14 @@ interface IHeeBlock {
|
|||||||
|
|
||||||
val tags: List<INamedTag<Block>>
|
val tags: List<INamedTag<Block>>
|
||||||
get() = emptyList()
|
get() = emptyList()
|
||||||
|
|
||||||
|
class FromBuilder(builder: AbstractHeeBlockBuilder<*>) : IHeeBlock {
|
||||||
|
override val localization = builder.localization ?: super.localization
|
||||||
|
override val localizationExtra = builder.localizationExtra.toMap()
|
||||||
|
override val model = builder.model ?: super.model
|
||||||
|
override val renderLayer = builder.renderLayer ?: super.renderLayer
|
||||||
|
override val tint = builder.tint
|
||||||
|
override val drop = builder.drop ?: super.drop
|
||||||
|
override val tags = builder.tags.toList()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,149 @@
|
|||||||
|
package chylex.hee.game.block.builder
|
||||||
|
|
||||||
|
import chylex.hee.client.text.LocalizationStrategy
|
||||||
|
import chylex.hee.game.block.IHeeBlock
|
||||||
|
import chylex.hee.game.block.properties.BlockDrop
|
||||||
|
import chylex.hee.game.block.properties.BlockHardness
|
||||||
|
import chylex.hee.game.block.properties.BlockHarvestTool
|
||||||
|
import chylex.hee.game.block.properties.BlockRenderLayer
|
||||||
|
import chylex.hee.game.block.properties.BlockTint
|
||||||
|
import chylex.hee.game.block.properties.IBlockStateModelSupplier
|
||||||
|
import net.minecraft.block.AbstractBlock.IPositionPredicate
|
||||||
|
import net.minecraft.block.AbstractBlock.Properties
|
||||||
|
import net.minecraft.block.Block
|
||||||
|
import net.minecraft.block.SoundType
|
||||||
|
import net.minecraft.block.material.Material
|
||||||
|
import net.minecraft.block.material.MaterialColor
|
||||||
|
import net.minecraft.tags.ITag.INamedTag
|
||||||
|
|
||||||
|
abstract class AbstractHeeBlockBuilder<T : Block> {
|
||||||
|
private companion object {
|
||||||
|
private val DEFAULT_MATERIAL = Material.Builder(MaterialColor.AIR).build()
|
||||||
|
|
||||||
|
private fun always(value: Boolean): IPositionPredicate {
|
||||||
|
return IPositionPredicate { _, _, _ -> value }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var localization: LocalizationStrategy? = null
|
||||||
|
val localizationExtra = mutableMapOf<String, String>()
|
||||||
|
|
||||||
|
var model: IBlockStateModelSupplier? = null
|
||||||
|
var renderLayer: BlockRenderLayer? = null
|
||||||
|
|
||||||
|
var material: Material? = null
|
||||||
|
var color: MaterialColor? = null
|
||||||
|
var sound: SoundType? = null
|
||||||
|
var tint: BlockTint? = null
|
||||||
|
var light: Int? = null
|
||||||
|
|
||||||
|
var isSolid: Boolean? = null
|
||||||
|
var isOpaque: Boolean? = null
|
||||||
|
var suffocates: Boolean? = null
|
||||||
|
var blocksVision: Boolean? = null
|
||||||
|
|
||||||
|
var drop: BlockDrop? = null
|
||||||
|
var tool: BlockHarvestTool? = null
|
||||||
|
var hardness: BlockHardness? = null
|
||||||
|
|
||||||
|
private val lazyComponents = lazy(::HeeBlockComponents)
|
||||||
|
val components
|
||||||
|
get() = lazyComponents.value
|
||||||
|
|
||||||
|
val tags = mutableListOf<INamedTag<Block>>()
|
||||||
|
val interfaces = HeeBlockInterfaces()
|
||||||
|
|
||||||
|
fun includeFrom(source: AbstractHeeBlockBuilder<*>) {
|
||||||
|
source.localization?.let { this.localization = it }
|
||||||
|
this.localizationExtra.putAll(source.localizationExtra)
|
||||||
|
|
||||||
|
source.model?.let { this.model = it }
|
||||||
|
source.renderLayer?.let { this.renderLayer = it }
|
||||||
|
|
||||||
|
source.material?.let { this.material = it }
|
||||||
|
source.color?.let { this.color = it }
|
||||||
|
source.sound?.let { this.sound = it }
|
||||||
|
source.tint?.let { this.tint = it }
|
||||||
|
source.light?.let { this.light = it }
|
||||||
|
|
||||||
|
source.isSolid?.let { this.isSolid = it }
|
||||||
|
source.isOpaque?.let { this.isOpaque = it }
|
||||||
|
source.suffocates?.let { this.suffocates = it }
|
||||||
|
source.blocksVision?.let { this.blocksVision = it }
|
||||||
|
|
||||||
|
source.drop?.let { this.drop = it }
|
||||||
|
source.tool?.let { this.tool = it }
|
||||||
|
source.hardness?.let { this.hardness = it }
|
||||||
|
|
||||||
|
if (source.lazyComponents.isInitialized()) {
|
||||||
|
this.components.includeFrom(source.components)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.tags.addAll(source.tags)
|
||||||
|
this.interfaces.includeFrom(source.interfaces)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected val heeDelegate
|
||||||
|
get() = object : IHeeBlock {
|
||||||
|
override val localization = this@AbstractHeeBlockBuilder.localization ?: super.localization
|
||||||
|
override val localizationExtra = this@AbstractHeeBlockBuilder.localizationExtra.toMap()
|
||||||
|
override val model = this@AbstractHeeBlockBuilder.model ?: super.model
|
||||||
|
override val renderLayer = this@AbstractHeeBlockBuilder.renderLayer ?: super.renderLayer
|
||||||
|
override val tint = this@AbstractHeeBlockBuilder.tint
|
||||||
|
override val drop = this@AbstractHeeBlockBuilder.drop ?: super.drop
|
||||||
|
override val tags = this@AbstractHeeBlockBuilder.tags.toList()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildProperties(setup: ((Properties) -> Properties)?): Properties {
|
||||||
|
val material = material ?: DEFAULT_MATERIAL
|
||||||
|
val color = color ?: material.color
|
||||||
|
val tool = tool ?: BlockHarvestTool.NONE
|
||||||
|
|
||||||
|
var properties = Properties.create(material, color)
|
||||||
|
|
||||||
|
if (setup != null) {
|
||||||
|
properties = setup(properties)
|
||||||
|
}
|
||||||
|
|
||||||
|
properties = tool.applyTo(properties)
|
||||||
|
properties = properties.apply(sound, Properties::sound)
|
||||||
|
properties = properties.apply(light) { level -> setLightLevel { level } }
|
||||||
|
properties = properties.apply(isOpaque) { setOpaque(always(it)) }
|
||||||
|
properties = properties.apply(suffocates) { setSuffocates(always(it)) }
|
||||||
|
properties = properties.apply(blocksVision) { setBlocksVision(always(it)) }
|
||||||
|
properties = properties.apply(hardness) { it.applyTo(this) }
|
||||||
|
|
||||||
|
if (isSolid == false) {
|
||||||
|
properties = properties.notSolid()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!material.blocksMovement()) {
|
||||||
|
if (isSolid == true) {
|
||||||
|
throw UnsupportedOperationException("[AbstractHeeBlockBuilder] cannot create a block that does not block movement and is solid at the same time")
|
||||||
|
}
|
||||||
|
|
||||||
|
properties = properties.doesNotBlockMovement()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (drop === BlockDrop.Nothing) {
|
||||||
|
properties = properties.noDrops()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lazyComponents.isInitialized() && components.randomTick != null) {
|
||||||
|
properties = properties.tickRandomly()
|
||||||
|
}
|
||||||
|
|
||||||
|
return properties
|
||||||
|
}
|
||||||
|
|
||||||
|
private inline fun <T> Properties.apply(value: T?, function: Properties.(T) -> Properties): Properties {
|
||||||
|
return if (value == null) this else function(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun build(propertiesSetup: (Properties.() -> Properties)? = null): T {
|
||||||
|
val components = if (lazyComponents.isInitialized()) components else null
|
||||||
|
return buildBlock(buildProperties(propertiesSetup), components)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal abstract fun buildBlock(properties: Properties, components: HeeBlockComponents?): T
|
||||||
|
}
|
@@ -0,0 +1,26 @@
|
|||||||
|
package chylex.hee.game.block.builder
|
||||||
|
|
||||||
|
import chylex.hee.game.block.HeeBlock2
|
||||||
|
import chylex.hee.game.block.HeeBlockWithComponents
|
||||||
|
import chylex.hee.game.block.IHeeBlock
|
||||||
|
import chylex.hee.game.block.interfaces.IBlockWithInterfaces
|
||||||
|
import net.minecraft.block.AbstractBlock.Properties
|
||||||
|
import net.minecraft.block.Block
|
||||||
|
import net.minecraft.block.BlockState
|
||||||
|
import net.minecraft.state.StateContainer.Builder
|
||||||
|
|
||||||
|
open class HeeBlockBuilder : AbstractHeeBlockBuilder<HeeBlock2>() {
|
||||||
|
override fun buildBlock(properties: Properties, components: HeeBlockComponents?): HeeBlock2 {
|
||||||
|
if (components != null) {
|
||||||
|
return object : HeeBlockWithComponents(properties, components), IHeeBlock by IHeeBlock.FromBuilder(this@HeeBlockBuilder), IBlockWithInterfaces by interfaces.delegate {
|
||||||
|
override fun fillStateContainer(builder: Builder<Block, BlockState>) {
|
||||||
|
components.states.fillContainer(builder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return object : HeeBlock2(properties), IHeeBlock by IHeeBlock.FromBuilder(this), IBlockWithInterfaces by interfaces.delegate {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun HeeBlockBuilder(setup: HeeBlockBuilder.() -> Unit) = HeeBlockBuilder().apply(setup)
|
@@ -0,0 +1,86 @@
|
|||||||
|
package chylex.hee.game.block.builder
|
||||||
|
|
||||||
|
import chylex.hee.game.block.components.IBlockAddedComponent
|
||||||
|
import chylex.hee.game.block.components.IBlockClientEffectsComponent
|
||||||
|
import chylex.hee.game.block.components.IBlockCollideWithEntityComponent
|
||||||
|
import chylex.hee.game.block.components.IBlockDropsComponent
|
||||||
|
import chylex.hee.game.block.components.IBlockEntityComponent
|
||||||
|
import chylex.hee.game.block.components.IBlockExperienceComponent
|
||||||
|
import chylex.hee.game.block.components.IBlockExplodedComponent
|
||||||
|
import chylex.hee.game.block.components.IBlockHarvestabilityComponent
|
||||||
|
import chylex.hee.game.block.components.IBlockNameComponent
|
||||||
|
import chylex.hee.game.block.components.IBlockNeighborChanged
|
||||||
|
import chylex.hee.game.block.components.IBlockPlacementComponent
|
||||||
|
import chylex.hee.game.block.components.IBlockRandomTickComponent
|
||||||
|
import chylex.hee.game.block.components.IBlockScheduledTickComponent
|
||||||
|
import chylex.hee.game.block.components.IBlockShapeComponent
|
||||||
|
import chylex.hee.game.block.components.ICreatureSpawningOnBlockComponent
|
||||||
|
import chylex.hee.game.block.components.IFlammableBlockComponent
|
||||||
|
import chylex.hee.game.block.components.IPlayerUseBlockComponent
|
||||||
|
import chylex.hee.game.block.components.ISetBlockStateFromNeighbor
|
||||||
|
import chylex.hee.game.item.components.ITooltipComponent
|
||||||
|
import net.minecraft.block.BlockRenderType
|
||||||
|
|
||||||
|
class HeeBlockComponents {
|
||||||
|
val states = HeeBlockStates.Builder()
|
||||||
|
|
||||||
|
var name: IBlockNameComponent? = null
|
||||||
|
var tooltip: ITooltipComponent? = null
|
||||||
|
|
||||||
|
var shape: IBlockShapeComponent? = null
|
||||||
|
var renderType: BlockRenderType? = null
|
||||||
|
var ambientOcclusionValue: Float? = null
|
||||||
|
var clientEffects: IBlockClientEffectsComponent? = null
|
||||||
|
|
||||||
|
var drops: IBlockDropsComponent? = null
|
||||||
|
var harvestability: IBlockHarvestabilityComponent? = null
|
||||||
|
var experience: IBlockExperienceComponent? = null
|
||||||
|
var flammability: IFlammableBlockComponent? = null
|
||||||
|
|
||||||
|
var entity: IBlockEntityComponent? = null
|
||||||
|
var placement: IBlockPlacementComponent? = null
|
||||||
|
var onAdded: IBlockAddedComponent? = null
|
||||||
|
var onNeighborChanged: IBlockNeighborChanged? = null
|
||||||
|
var setStateFromNeighbor: ISetBlockStateFromNeighbor? = null
|
||||||
|
|
||||||
|
var scheduledTick: IBlockScheduledTickComponent? = null
|
||||||
|
var randomTick: IBlockRandomTickComponent? = null
|
||||||
|
|
||||||
|
var playerUse: IPlayerUseBlockComponent? = null
|
||||||
|
var onExploded: IBlockExplodedComponent? = null
|
||||||
|
var onCreatureSpawning: ICreatureSpawningOnBlockComponent? = null
|
||||||
|
var collideWithEntity: IBlockCollideWithEntityComponent? = null
|
||||||
|
|
||||||
|
var isAir: Boolean? = null
|
||||||
|
|
||||||
|
fun includeFrom(source: HeeBlockComponents) {
|
||||||
|
source.name?.let { this.name = it }
|
||||||
|
source.tooltip?.let { this.tooltip = it }
|
||||||
|
|
||||||
|
source.shape?.let { this.shape = it }
|
||||||
|
source.renderType?.let { this.renderType = it }
|
||||||
|
source.ambientOcclusionValue?.let { this.ambientOcclusionValue = it }
|
||||||
|
source.clientEffects?.let { this.clientEffects = it }
|
||||||
|
|
||||||
|
source.drops?.let { this.drops = it }
|
||||||
|
source.harvestability?.let { this.harvestability = it }
|
||||||
|
source.experience?.let { this.experience = it }
|
||||||
|
source.flammability?.let { this.flammability = it }
|
||||||
|
|
||||||
|
source.entity?.let { this.entity = it }
|
||||||
|
source.placement?.let { this.placement = it }
|
||||||
|
source.onAdded?.let { this.onAdded = it }
|
||||||
|
source.onNeighborChanged?.let { this.onNeighborChanged = it }
|
||||||
|
source.setStateFromNeighbor?.let { this.setStateFromNeighbor = it }
|
||||||
|
|
||||||
|
source.scheduledTick?.let { this.scheduledTick = it }
|
||||||
|
source.randomTick?.let { this.randomTick = it }
|
||||||
|
|
||||||
|
source.playerUse?.let { this.playerUse = it }
|
||||||
|
source.onExploded?.let { this.onExploded = it }
|
||||||
|
source.onCreatureSpawning?.let { this.onCreatureSpawning = it }
|
||||||
|
source.collideWithEntity?.let { this.collideWithEntity = it }
|
||||||
|
|
||||||
|
source.isAir?.let { this.isAir = it }
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,23 @@
|
|||||||
|
package chylex.hee.game.block.builder
|
||||||
|
|
||||||
|
import chylex.hee.game.block.interfaces.BlockInterfaceContainer
|
||||||
|
import chylex.hee.game.block.interfaces.IBlockInterface
|
||||||
|
import chylex.hee.game.block.interfaces.NoBlockInterfaces
|
||||||
|
|
||||||
|
class HeeBlockInterfaces {
|
||||||
|
private val interfaces = mutableMapOf<Class<out IBlockInterface>, Any>()
|
||||||
|
|
||||||
|
internal val delegate
|
||||||
|
get() = if (interfaces.isEmpty())
|
||||||
|
NoBlockInterfaces
|
||||||
|
else
|
||||||
|
BlockInterfaceContainer(interfaces)
|
||||||
|
|
||||||
|
operator fun <T : IBlockInterface> set(type: Class<T>, impl: T) {
|
||||||
|
interfaces[type] = impl
|
||||||
|
}
|
||||||
|
|
||||||
|
fun includeFrom(source: HeeBlockInterfaces) {
|
||||||
|
this.interfaces.putAll(source.interfaces)
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,50 @@
|
|||||||
|
package chylex.hee.game.block.builder
|
||||||
|
|
||||||
|
import chylex.hee.game.block.util.BlockStateGenerics
|
||||||
|
import net.minecraft.block.Block
|
||||||
|
import net.minecraft.block.BlockState
|
||||||
|
import net.minecraft.state.Property
|
||||||
|
import net.minecraft.state.StateContainer
|
||||||
|
import net.minecraft.util.Direction
|
||||||
|
import net.minecraft.util.Mirror
|
||||||
|
import net.minecraft.util.Rotation
|
||||||
|
|
||||||
|
class HeeBlockStates private constructor(private val statesWithDefaults: Map<Property<*>, Comparable<*>>, private val facingProperty: Property<Direction>?) {
|
||||||
|
fun applyDefaults(state: BlockState): BlockState {
|
||||||
|
if (statesWithDefaults.isEmpty()) {
|
||||||
|
return state
|
||||||
|
}
|
||||||
|
|
||||||
|
return statesWithDefaults.entries.fold(state) { acc, entry ->
|
||||||
|
BlockStateGenerics.withProperty(acc, entry.key, entry.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getRotatedState(state: BlockState, rotation: Rotation): BlockState {
|
||||||
|
return facingProperty?.let { state.with(it, rotation.rotate(state[it])) } ?: state
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getMirroredState(state: BlockState, mirror: Mirror): BlockState {
|
||||||
|
return facingProperty?.let { state.with(it, mirror.mirror(state[it])) } ?: state
|
||||||
|
}
|
||||||
|
|
||||||
|
class Builder {
|
||||||
|
private val statesWithDefaults = mutableMapOf<Property<*>, Comparable<*>>()
|
||||||
|
|
||||||
|
var facingProperty: Property<Direction>? = null
|
||||||
|
|
||||||
|
fun <T : Comparable<T>> set(state: Property<T>, default: T) {
|
||||||
|
statesWithDefaults[state] = default
|
||||||
|
}
|
||||||
|
|
||||||
|
fun fillContainer(builder: StateContainer.Builder<Block, BlockState>) {
|
||||||
|
for (property in statesWithDefaults.keys) {
|
||||||
|
builder.add(property)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun build(): HeeBlockStates {
|
||||||
|
return HeeBlockStates(statesWithDefaults.toMap(), facingProperty)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,9 @@
|
|||||||
|
package chylex.hee.game.block.components
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState
|
||||||
|
import net.minecraft.util.math.BlockPos
|
||||||
|
import net.minecraft.world.World
|
||||||
|
|
||||||
|
fun interface IBlockAddedComponent {
|
||||||
|
fun onAdded(state: BlockState, world: World, pos: BlockPos)
|
||||||
|
}
|
@@ -0,0 +1,10 @@
|
|||||||
|
package chylex.hee.game.block.components
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState
|
||||||
|
import net.minecraft.util.math.BlockPos
|
||||||
|
import net.minecraft.world.World
|
||||||
|
import java.util.Random
|
||||||
|
|
||||||
|
interface IBlockClientEffectsComponent {
|
||||||
|
fun randomTick(state: BlockState, world: World, pos: BlockPos, rand: Random) {}
|
||||||
|
}
|
@@ -0,0 +1,10 @@
|
|||||||
|
package chylex.hee.game.block.components
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState
|
||||||
|
import net.minecraft.entity.Entity
|
||||||
|
import net.minecraft.util.math.BlockPos
|
||||||
|
import net.minecraft.world.World
|
||||||
|
|
||||||
|
fun interface IBlockCollideWithEntityComponent {
|
||||||
|
fun collide(state: BlockState, world: World, pos: BlockPos, entity: Entity)
|
||||||
|
}
|
@@ -0,0 +1,15 @@
|
|||||||
|
package chylex.hee.game.block.components
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
|
import net.minecraft.loot.LootContext
|
||||||
|
import net.minecraft.util.math.BlockPos
|
||||||
|
import net.minecraft.world.IBlockReader
|
||||||
|
|
||||||
|
interface IBlockDropsComponent {
|
||||||
|
fun getDrops(state: BlockState, context: LootContext.Builder): MutableList<ItemStack>
|
||||||
|
|
||||||
|
fun getPickBlock(state: BlockState, world: IBlockReader, pos: BlockPos): ItemStack? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,7 @@
|
|||||||
|
package chylex.hee.game.block.components
|
||||||
|
|
||||||
|
import net.minecraft.tileentity.TileEntity
|
||||||
|
|
||||||
|
fun interface IBlockEntityComponent {
|
||||||
|
fun create(): TileEntity
|
||||||
|
}
|
@@ -0,0 +1,7 @@
|
|||||||
|
package chylex.hee.game.block.components
|
||||||
|
|
||||||
|
import java.util.Random
|
||||||
|
|
||||||
|
fun interface IBlockExperienceComponent {
|
||||||
|
fun getExperience(rand: Random): Int
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
package chylex.hee.game.block.components
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState
|
||||||
|
import net.minecraft.util.math.BlockPos
|
||||||
|
import net.minecraft.world.Explosion
|
||||||
|
import net.minecraft.world.World
|
||||||
|
|
||||||
|
interface IBlockExplodedComponent {
|
||||||
|
fun canDrop(explosion: Explosion): Boolean
|
||||||
|
fun onExploded(state: BlockState, world: World, pos: BlockPos, explosion: Explosion)
|
||||||
|
}
|
@@ -0,0 +1,8 @@
|
|||||||
|
package chylex.hee.game.block.components
|
||||||
|
|
||||||
|
import chylex.hee.util.forge.EventResult
|
||||||
|
import net.minecraft.entity.player.PlayerEntity
|
||||||
|
|
||||||
|
fun interface IBlockHarvestabilityComponent {
|
||||||
|
fun canHarvest(player: PlayerEntity): EventResult
|
||||||
|
}
|
@@ -0,0 +1,19 @@
|
|||||||
|
package chylex.hee.game.block.components
|
||||||
|
|
||||||
|
import net.minecraft.block.Block
|
||||||
|
|
||||||
|
interface IBlockNameComponent {
|
||||||
|
val translationKey: String
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun of(translationKey: String) = object : IBlockNameComponent {
|
||||||
|
override val translationKey
|
||||||
|
get() = translationKey
|
||||||
|
}
|
||||||
|
|
||||||
|
fun of(block: Block) = object : IBlockNameComponent {
|
||||||
|
override val translationKey
|
||||||
|
get() = block.translationKey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,10 @@
|
|||||||
|
package chylex.hee.game.block.components
|
||||||
|
|
||||||
|
import net.minecraft.block.Block
|
||||||
|
import net.minecraft.block.BlockState
|
||||||
|
import net.minecraft.util.math.BlockPos
|
||||||
|
import net.minecraft.world.World
|
||||||
|
|
||||||
|
fun interface IBlockNeighborChanged {
|
||||||
|
fun onNeighborChanged(state: BlockState, world: World, pos: BlockPos, oldNeighborBlock: Block, newNeighborBlock: Block, neighborPos: BlockPos)
|
||||||
|
}
|
@@ -0,0 +1,21 @@
|
|||||||
|
package chylex.hee.game.block.components
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState
|
||||||
|
import net.minecraft.entity.LivingEntity
|
||||||
|
import net.minecraft.item.BlockItemUseContext
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
|
import net.minecraft.util.math.BlockPos
|
||||||
|
import net.minecraft.world.IWorldReader
|
||||||
|
import net.minecraft.world.World
|
||||||
|
|
||||||
|
interface IBlockPlacementComponent {
|
||||||
|
fun isPositionValid(state: BlockState, world: IWorldReader, pos: BlockPos): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getPlacedState(defaultState: BlockState, world: World, pos: BlockPos, context: BlockItemUseContext): BlockState {
|
||||||
|
return defaultState
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onPlacedBy(state: BlockState, world: World, pos: BlockPos, placer: LivingEntity?, stack: ItemStack) {}
|
||||||
|
}
|
@@ -0,0 +1,10 @@
|
|||||||
|
package chylex.hee.game.block.components
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState
|
||||||
|
import net.minecraft.util.math.BlockPos
|
||||||
|
import net.minecraft.world.World
|
||||||
|
import java.util.Random
|
||||||
|
|
||||||
|
fun interface IBlockRandomTickComponent {
|
||||||
|
fun onTick(state: BlockState, world: World, pos: BlockPos, rand: Random)
|
||||||
|
}
|
@@ -0,0 +1,19 @@
|
|||||||
|
package chylex.hee.game.block.components
|
||||||
|
|
||||||
|
import chylex.hee.game.block.properties.TickSchedule
|
||||||
|
import net.minecraft.block.BlockState
|
||||||
|
import net.minecraft.util.math.BlockPos
|
||||||
|
import net.minecraft.world.World
|
||||||
|
import java.util.Random
|
||||||
|
|
||||||
|
interface IBlockScheduledTickComponent {
|
||||||
|
/**
|
||||||
|
* Return the amount of ticks before the first [onTick] call after the block is added to the world.
|
||||||
|
*/
|
||||||
|
fun onAdded(state: BlockState, world: World, pos: BlockPos, rand: Random): TickSchedule
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the amount of ticks before the next [onTick] call.
|
||||||
|
*/
|
||||||
|
fun onTick(state: BlockState, world: World, pos: BlockPos, rand: Random): TickSchedule
|
||||||
|
}
|
@@ -0,0 +1,30 @@
|
|||||||
|
package chylex.hee.game.block.components
|
||||||
|
|
||||||
|
import chylex.hee.game.block.util.asVoxelShape
|
||||||
|
import net.minecraft.block.BlockState
|
||||||
|
import net.minecraft.util.math.AxisAlignedBB
|
||||||
|
import net.minecraft.util.math.shapes.VoxelShape
|
||||||
|
|
||||||
|
interface IBlockShapeComponent {
|
||||||
|
fun getShape(state: BlockState): VoxelShape
|
||||||
|
|
||||||
|
fun getCollisionShape(state: BlockState): VoxelShape? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getRaytraceShape(state: BlockState): VoxelShape? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun of(shape: VoxelShape) = object : IBlockShapeComponent {
|
||||||
|
override fun getShape(state: BlockState): VoxelShape {
|
||||||
|
return shape
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun of(aabb: AxisAlignedBB): IBlockShapeComponent {
|
||||||
|
return of(aabb.asVoxelShape)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
package chylex.hee.game.block.components
|
||||||
|
|
||||||
|
import chylex.hee.util.forge.EventResult
|
||||||
|
import net.minecraft.entity.EntitySpawnPlacementRegistry.PlacementType
|
||||||
|
import net.minecraft.entity.EntityType
|
||||||
|
import net.minecraft.util.math.BlockPos
|
||||||
|
import net.minecraft.world.IBlockReader
|
||||||
|
|
||||||
|
fun interface ICreatureSpawningOnBlockComponent {
|
||||||
|
fun canSpawn(world: IBlockReader, pos: BlockPos, placementType: PlacementType?, entityType: EntityType<*>?): EventResult
|
||||||
|
}
|
@@ -0,0 +1,20 @@
|
|||||||
|
package chylex.hee.game.block.components
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState
|
||||||
|
import net.minecraft.state.properties.BlockStateProperties
|
||||||
|
|
||||||
|
interface IFlammableBlockComponent {
|
||||||
|
val flammability: Int
|
||||||
|
val fireSpread: Int
|
||||||
|
|
||||||
|
fun takeIfFlammable(state: BlockState): IFlammableBlockComponent? {
|
||||||
|
return this.takeUnless { state.hasProperty(BlockStateProperties.WATERLOGGED) && state[BlockStateProperties.WATERLOGGED] }
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun of(flammability: Int, fireSpread: Int) = object : IFlammableBlockComponent {
|
||||||
|
override val flammability = flammability
|
||||||
|
override val fireSpread = fireSpread
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,12 @@
|
|||||||
|
package chylex.hee.game.block.components
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState
|
||||||
|
import net.minecraft.entity.player.PlayerEntity
|
||||||
|
import net.minecraft.util.ActionResultType
|
||||||
|
import net.minecraft.util.Hand
|
||||||
|
import net.minecraft.util.math.BlockPos
|
||||||
|
import net.minecraft.world.World
|
||||||
|
|
||||||
|
fun interface IPlayerUseBlockComponent {
|
||||||
|
fun use(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, hand: Hand): ActionResultType
|
||||||
|
}
|
@@ -0,0 +1,10 @@
|
|||||||
|
package chylex.hee.game.block.components
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState
|
||||||
|
import net.minecraft.util.Direction
|
||||||
|
import net.minecraft.util.math.BlockPos
|
||||||
|
import net.minecraft.world.IWorld
|
||||||
|
|
||||||
|
fun interface ISetBlockStateFromNeighbor {
|
||||||
|
fun getNewState(state: BlockState, world: IWorld, pos: BlockPos, neighborFacing: Direction, neighborPos: BlockPos): BlockState
|
||||||
|
}
|
@@ -0,0 +1,9 @@
|
|||||||
|
package chylex.hee.game.block.interfaces
|
||||||
|
|
||||||
|
internal class BlockInterfaceContainer(interfaces: Map<Class<out IBlockInterface>, Any>) : IBlockWithInterfaces {
|
||||||
|
private val interfaces = interfaces.toMap()
|
||||||
|
|
||||||
|
override fun getInterface(type: Class<out IBlockInterface>): Any? {
|
||||||
|
return interfaces[type]
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,6 @@
|
|||||||
|
package chylex.hee.game.block.interfaces
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marks interfaces that can be attached to blocks.
|
||||||
|
*/
|
||||||
|
interface IBlockInterface
|
@@ -0,0 +1,15 @@
|
|||||||
|
package chylex.hee.game.block.interfaces
|
||||||
|
|
||||||
|
import net.minecraft.block.Block
|
||||||
|
|
||||||
|
interface IBlockWithInterfaces {
|
||||||
|
fun getInterface(type: Class<out IBlockInterface>): Any?
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified T : IBlockInterface> IBlockWithInterfaces.getHeeInterface(): T? {
|
||||||
|
return this.getInterface(T::class.java) as? T
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified T : IBlockInterface> Block.getHeeInterface(): T? {
|
||||||
|
return (this as? IBlockWithInterfaces)?.getHeeInterface()
|
||||||
|
}
|
@@ -0,0 +1,7 @@
|
|||||||
|
package chylex.hee.game.block.interfaces
|
||||||
|
|
||||||
|
internal object NoBlockInterfaces : IBlockWithInterfaces {
|
||||||
|
override fun getInterface(type: Class<out IBlockInterface>): Any? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
@@ -1,9 +1,10 @@
|
|||||||
package chylex.hee.game.block.logic
|
package chylex.hee.game.block.logic
|
||||||
|
|
||||||
|
import chylex.hee.game.block.interfaces.IBlockInterface
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.world.IBlockReader
|
import net.minecraft.world.IBlockReader
|
||||||
|
|
||||||
interface IBlockDynamicHardness {
|
interface IBlockDynamicHardness : IBlockInterface {
|
||||||
fun getBlockHardness(world: IBlockReader, pos: BlockPos, state: BlockState, originalHardness: Float): Float
|
fun getBlockHardness(world: IBlockReader, pos: BlockPos, state: BlockState, originalHardness: Float): Float
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,11 @@
|
|||||||
|
package chylex.hee.game.block.properties
|
||||||
|
|
||||||
|
import net.minecraft.block.AbstractBlock.Properties
|
||||||
|
|
||||||
|
data class BlockHardness(val hardness: Float, val resistance: Float) {
|
||||||
|
constructor(hardnessAndResistance: Float) : this(hardnessAndResistance, hardnessAndResistance)
|
||||||
|
|
||||||
|
fun applyTo(properties: Properties): Properties {
|
||||||
|
return properties.hardnessAndResistance(hardness, resistance)
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,21 @@
|
|||||||
|
package chylex.hee.game.block.properties
|
||||||
|
|
||||||
|
import net.minecraft.block.AbstractBlock.Properties
|
||||||
|
import net.minecraftforge.common.ToolType
|
||||||
|
|
||||||
|
@Suppress("DataClassPrivateConstructor")
|
||||||
|
data class BlockHarvestTool private constructor(val tier: Int, val toolType: ToolType?, val requiresTool: Boolean) {
|
||||||
|
fun applyTo(properties: Properties): Properties {
|
||||||
|
return properties
|
||||||
|
.harvestLevel(tier)
|
||||||
|
.let { if (toolType != null) it.harvestTool(toolType) else it }
|
||||||
|
.let { if (requiresTool) it.setRequiresTool() else it }
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val NONE = BlockHarvestTool(-1, null, requiresTool = false)
|
||||||
|
|
||||||
|
fun required(tier: Int, toolType: ToolType) = BlockHarvestTool(tier, toolType, requiresTool = true)
|
||||||
|
fun optional(tier: Int, toolType: ToolType) = BlockHarvestTool(tier, toolType, requiresTool = false)
|
||||||
|
}
|
||||||
|
}
|
@@ -1,7 +1,13 @@
|
|||||||
package chylex.hee.game.block.properties
|
package chylex.hee.game.block.properties
|
||||||
|
|
||||||
interface IBlockStateModel {
|
import net.minecraft.block.Block
|
||||||
|
|
||||||
|
interface IBlockStateModel : IBlockStateModelSupplier {
|
||||||
val blockState: BlockStatePreset
|
val blockState: BlockStatePreset
|
||||||
val blockModel: BlockModel
|
val blockModel: BlockModel
|
||||||
val itemModel: BlockItemModel?
|
val itemModel: BlockItemModel?
|
||||||
|
|
||||||
|
override fun generate(block: Block): IBlockStateModel {
|
||||||
|
return this
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,7 @@
|
|||||||
|
package chylex.hee.game.block.properties
|
||||||
|
|
||||||
|
import net.minecraft.block.Block
|
||||||
|
|
||||||
|
fun interface IBlockStateModelSupplier {
|
||||||
|
fun generate(block: Block): IBlockStateModel
|
||||||
|
}
|
@@ -0,0 +1,19 @@
|
|||||||
|
package chylex.hee.game.block.properties
|
||||||
|
|
||||||
|
import net.minecraft.block.Block
|
||||||
|
import net.minecraft.util.math.BlockPos
|
||||||
|
import net.minecraft.world.World
|
||||||
|
|
||||||
|
sealed class TickSchedule {
|
||||||
|
abstract fun schedule(world: World, pos: BlockPos, block: Block)
|
||||||
|
|
||||||
|
object Never : TickSchedule() {
|
||||||
|
override fun schedule(world: World, pos: BlockPos, block: Block) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class InTicks(private val ticks: Int) : TickSchedule() {
|
||||||
|
override fun schedule(world: World, pos: BlockPos, block: Block) {
|
||||||
|
world.pendingBlockTicks.scheduleTick(pos, block, ticks)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -2,8 +2,8 @@ package chylex.hee.game.item.components
|
|||||||
|
|
||||||
import net.minecraft.item.ItemStack
|
import net.minecraft.item.ItemStack
|
||||||
import net.minecraft.util.text.ITextComponent
|
import net.minecraft.util.text.ITextComponent
|
||||||
import net.minecraft.world.World
|
import net.minecraft.world.IBlockReader
|
||||||
|
|
||||||
fun interface ITooltipComponent {
|
fun interface ITooltipComponent {
|
||||||
fun add(lines: MutableList<ITextComponent>, stack: ItemStack, advanced: Boolean, world: World?)
|
fun add(lines: MutableList<ITextComponent>, stack: ItemStack, advanced: Boolean, world: IBlockReader?)
|
||||||
}
|
}
|
||||||
|
@@ -2,10 +2,10 @@ package chylex.hee.game.item.components
|
|||||||
|
|
||||||
import net.minecraft.item.ItemStack
|
import net.minecraft.item.ItemStack
|
||||||
import net.minecraft.util.text.ITextComponent
|
import net.minecraft.util.text.ITextComponent
|
||||||
import net.minecraft.world.World
|
import net.minecraft.world.IBlockReader
|
||||||
|
|
||||||
class StaticTooltipComponent(private vararg val lines: ITextComponent) : ITooltipComponent {
|
class StaticTooltipComponent(private vararg val lines: ITextComponent) : ITooltipComponent {
|
||||||
override fun add(lines: MutableList<ITextComponent>, stack: ItemStack, advanced: Boolean, world: World?) {
|
override fun add(lines: MutableList<ITextComponent>, stack: ItemStack, advanced: Boolean, world: IBlockReader?) {
|
||||||
lines.addAll(this.lines)
|
lines.addAll(this.lines)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,13 +1,11 @@
|
|||||||
package chylex.hee.system
|
package chylex.hee.system
|
||||||
|
|
||||||
import chylex.hee.game.block.HeeBlock
|
import chylex.hee.game.block.components.IPlayerUseBlockComponent
|
||||||
import chylex.hee.game.block.properties.BlockBuilder
|
|
||||||
import chylex.hee.game.command.IClientCommand
|
import chylex.hee.game.command.IClientCommand
|
||||||
import chylex.hee.game.command.ICommand
|
import chylex.hee.game.command.ICommand
|
||||||
|
|
||||||
interface IDebugModule {
|
interface IDebugModule {
|
||||||
val clientCommands: List<IClientCommand>
|
val clientCommands: List<IClientCommand>
|
||||||
val serverCommands: List<ICommand>
|
val serverCommands: List<ICommand>
|
||||||
|
val scaffoldingBlockBehavior: IPlayerUseBlockComponent?
|
||||||
fun createScaffoldingBlock(builder: BlockBuilder): HeeBlock
|
|
||||||
}
|
}
|
||||||
|
16
modules/util/src/main/java/chylex/hee/util/forge/ForgeExt.kt
Normal file
16
modules/util/src/main/java/chylex/hee/util/forge/ForgeExt.kt
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package chylex.hee.util.forge
|
||||||
|
|
||||||
|
import net.minecraftforge.eventbus.api.Event.Result.ALLOW
|
||||||
|
import net.minecraftforge.eventbus.api.Event.Result.DEFAULT
|
||||||
|
import net.minecraftforge.eventbus.api.Event.Result.DENY
|
||||||
|
|
||||||
|
val EventResult.asBool: Boolean?
|
||||||
|
get() = when (this) {
|
||||||
|
ALLOW -> true
|
||||||
|
DENY -> false
|
||||||
|
DEFAULT -> null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun EventResult(allow: Boolean): EventResult {
|
||||||
|
return if (allow) ALLOW else DENY
|
||||||
|
}
|
@@ -10,6 +10,7 @@ import chylex.hee.client.util.MC
|
|||||||
import chylex.hee.game.Resource
|
import chylex.hee.game.Resource
|
||||||
import chylex.hee.game.block.BlockAbstractPortal
|
import chylex.hee.game.block.BlockAbstractPortal
|
||||||
import chylex.hee.game.block.entity.TileEntityEnergyCluster
|
import chylex.hee.game.block.entity.TileEntityEnergyCluster
|
||||||
|
import chylex.hee.game.block.interfaces.getHeeInterface
|
||||||
import chylex.hee.game.block.properties.Materials
|
import chylex.hee.game.block.properties.Materials
|
||||||
import chylex.hee.game.mechanics.energy.IClusterOracleItem
|
import chylex.hee.game.mechanics.energy.IClusterOracleItem
|
||||||
import chylex.hee.game.mechanics.energy.IEnergyQuantity
|
import chylex.hee.game.mechanics.energy.IEnergyQuantity
|
||||||
@@ -35,7 +36,7 @@ import net.minecraftforge.client.event.RenderGameOverlayEvent
|
|||||||
import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType.HELMET
|
import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType.HELMET
|
||||||
|
|
||||||
@SubscribeAllEvents(Side.CLIENT, modid = HEE.ID)
|
@SubscribeAllEvents(Side.CLIENT, modid = HEE.ID)
|
||||||
object OverlayRenderer {
|
object OverlayRenderer { // TODO move to appropriate block builders
|
||||||
private const val BORDER_SIZE = 4
|
private const val BORDER_SIZE = 4
|
||||||
private const val LINE_SPACING = 7
|
private const val LINE_SPACING = 7
|
||||||
|
|
||||||
@@ -147,7 +148,7 @@ object OverlayRenderer {
|
|||||||
clusterLookedAt = pos.getTile(world)
|
clusterLookedAt = pos.getTile(world)
|
||||||
e.isCanceled = true
|
e.isCanceled = true
|
||||||
}
|
}
|
||||||
else if (block is BlockAbstractPortal) {
|
else if (block.getHeeInterface<BlockAbstractPortal.IInnerPortalBlock>() != null) {
|
||||||
e.isCanceled = true
|
e.isCanceled = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
package chylex.hee.client.render.block
|
package chylex.hee.client.render.block
|
||||||
|
|
||||||
import chylex.hee.game.block.BlockAbstractPortal
|
import chylex.hee.game.block.BlockAbstractPortal
|
||||||
import chylex.hee.game.block.BlockVoidPortalInner.Companion.TYPE
|
|
||||||
import chylex.hee.game.block.BlockVoidPortalInner.ITerritoryInstanceFactory
|
import chylex.hee.game.block.BlockVoidPortalInner.ITerritoryInstanceFactory
|
||||||
import chylex.hee.game.block.BlockVoidPortalInner.IVoidPortalController
|
import chylex.hee.game.block.BlockVoidPortalInner.IVoidPortalController
|
||||||
|
import chylex.hee.game.block.BlockVoidPortalInner.TYPE
|
||||||
import chylex.hee.game.block.BlockVoidPortalInner.Type.HUB
|
import chylex.hee.game.block.BlockVoidPortalInner.Type.HUB
|
||||||
import chylex.hee.game.block.BlockVoidPortalInner.Type.RETURN_ACTIVE
|
import chylex.hee.game.block.BlockVoidPortalInner.Type.RETURN_ACTIVE
|
||||||
import chylex.hee.game.block.entity.TileEntityPortalInner
|
import chylex.hee.game.block.entity.TileEntityPortalInner
|
||||||
|
51
src/main/java/chylex/hee/game/block/Block.kt
Normal file
51
src/main/java/chylex/hee/game/block/Block.kt
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
package chylex.hee.game.block
|
||||||
|
|
||||||
|
import chylex.hee.game.block.builder.HeeBlockBuilder
|
||||||
|
import chylex.hee.game.block.components.IBlockShapeComponent
|
||||||
|
import chylex.hee.game.block.properties.BlockDrop
|
||||||
|
import chylex.hee.game.block.properties.BlockHardness
|
||||||
|
import chylex.hee.game.block.properties.BlockHarvestTool
|
||||||
|
import chylex.hee.game.block.properties.BlockModel
|
||||||
|
import chylex.hee.game.block.properties.IBlockStateModelSupplier
|
||||||
|
import chylex.hee.game.block.properties.Materials
|
||||||
|
import net.minecraft.block.SoundType
|
||||||
|
import net.minecraft.block.material.MaterialColor
|
||||||
|
import net.minecraft.util.math.AxisAlignedBB
|
||||||
|
import net.minecraftforge.common.Tags
|
||||||
|
|
||||||
|
val BlockIndestructible
|
||||||
|
get() = HeeBlockBuilder {
|
||||||
|
drop = BlockDrop.Nothing
|
||||||
|
tool = BlockHarvestTool.NONE
|
||||||
|
hardness = BlockHardness(hardness = -1F, resistance = 3600000F)
|
||||||
|
}
|
||||||
|
|
||||||
|
val BlockEndStoneBase
|
||||||
|
get() = HeeBlockBuilder {
|
||||||
|
material = Materials.SOLID
|
||||||
|
color = MaterialColor.SAND
|
||||||
|
sound = SoundType.STONE
|
||||||
|
}
|
||||||
|
|
||||||
|
val BlockEndOre
|
||||||
|
get() = HeeBlockBuilder {
|
||||||
|
includeFrom(BlockEndStoneBase)
|
||||||
|
tags.add(Tags.Blocks.ORES)
|
||||||
|
}
|
||||||
|
|
||||||
|
val BlockPortalFrameBase
|
||||||
|
get() = HeeBlockBuilder {
|
||||||
|
model = IBlockStateModelSupplier { BlockModel.PortalFrame(it, "plain") }
|
||||||
|
|
||||||
|
material = Materials.SOLID
|
||||||
|
color = MaterialColor.SAND
|
||||||
|
sound = SoundType.STONE
|
||||||
|
|
||||||
|
components.shape = IBlockShapeComponent.of(AxisAlignedBB(0.0, 0.0, 0.0, 1.0, 0.8125, 1.0))
|
||||||
|
}
|
||||||
|
|
||||||
|
val BlockPortalFrameIndestructible
|
||||||
|
get() = HeeBlockBuilder {
|
||||||
|
includeFrom(BlockPortalFrameBase)
|
||||||
|
includeFrom(BlockIndestructible)
|
||||||
|
}
|
@@ -1,11 +1,15 @@
|
|||||||
package chylex.hee.game.block
|
package chylex.hee.game.block
|
||||||
|
|
||||||
import chylex.hee.client.text.LocalizationStrategy
|
import chylex.hee.client.text.LocalizationStrategy
|
||||||
import chylex.hee.game.block.properties.BlockBuilder
|
import chylex.hee.game.block.builder.HeeBlockBuilder
|
||||||
|
import chylex.hee.game.block.components.IBlockCollideWithEntityComponent
|
||||||
|
import chylex.hee.game.block.components.IBlockEntityComponent
|
||||||
|
import chylex.hee.game.block.components.IBlockShapeComponent
|
||||||
|
import chylex.hee.game.block.interfaces.IBlockInterface
|
||||||
import chylex.hee.game.block.properties.BlockModel
|
import chylex.hee.game.block.properties.BlockModel
|
||||||
import chylex.hee.game.block.properties.BlockStateModel
|
import chylex.hee.game.block.properties.BlockStateModel
|
||||||
import chylex.hee.game.block.properties.BlockStatePreset
|
import chylex.hee.game.block.properties.BlockStatePreset
|
||||||
import chylex.hee.game.block.util.asVoxelShape
|
import chylex.hee.game.entity.util.EntityPortalContact
|
||||||
import chylex.hee.game.world.util.Facing4
|
import chylex.hee.game.world.util.Facing4
|
||||||
import chylex.hee.game.world.util.allInBox
|
import chylex.hee.game.world.util.allInBox
|
||||||
import chylex.hee.game.world.util.allInBoxMutable
|
import chylex.hee.game.world.util.allInBoxMutable
|
||||||
@@ -24,25 +28,27 @@ import net.minecraft.block.Block
|
|||||||
import net.minecraft.block.BlockRenderType.INVISIBLE
|
import net.minecraft.block.BlockRenderType.INVISIBLE
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.block.Blocks
|
import net.minecraft.block.Blocks
|
||||||
|
import net.minecraft.block.SoundType
|
||||||
|
import net.minecraft.block.material.Material
|
||||||
|
import net.minecraft.block.material.MaterialColor
|
||||||
import net.minecraft.entity.Entity
|
import net.minecraft.entity.Entity
|
||||||
import net.minecraft.tags.BlockTags
|
import net.minecraft.tags.BlockTags
|
||||||
import net.minecraft.tileentity.TileEntity
|
import net.minecraft.tileentity.TileEntity
|
||||||
import net.minecraft.util.math.AxisAlignedBB
|
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.util.math.shapes.ISelectionContext
|
|
||||||
import net.minecraft.util.math.shapes.VoxelShape
|
import net.minecraft.util.math.shapes.VoxelShape
|
||||||
import net.minecraft.world.IBlockReader
|
import net.minecraft.util.math.shapes.VoxelShapes
|
||||||
import net.minecraft.world.World
|
import net.minecraft.world.World
|
||||||
|
|
||||||
abstract class BlockAbstractPortal(builder: BlockBuilder) : BlockSimpleShaped(builder, AxisAlignedBB(0.0, 0.0, 0.0, 1.0, 0.75, 1.0)) {
|
class BlockAbstractPortal(impl: IInnerPortalBlock) : HeeBlockBuilder() {
|
||||||
companion object {
|
companion object {
|
||||||
const val MAX_DISTANCE_FROM_FRAME = 6.0
|
const val MAX_DISTANCE_FROM_FRAME = 6.0
|
||||||
const val MAX_SIZE = 5
|
const val MAX_SIZE = 5
|
||||||
|
|
||||||
const val TRANSLATION_SPEED_LONG = 600000L
|
private const val TRANSLATION_SPEED_LONG = 600000L
|
||||||
const val TRANSLATION_SPEED_INV = 1.0 / TRANSLATION_SPEED_LONG
|
const val TRANSLATION_SPEED_INV = 1.0 / TRANSLATION_SPEED_LONG
|
||||||
|
|
||||||
private val COLLISION_AABB = AxisAlignedBB(0.0, 0.0, 0.0, 1.0, 0.025, 1.0).asVoxelShape
|
private val SHAPE = VoxelShapes.create(0.0, 0.0, 0.0, 1.0, 0.75, 1.0)
|
||||||
|
private val COLLISION_SHAPE = VoxelShapes.create(0.0, 0.0, 0.0, 1.0, 0.025, 1.0)
|
||||||
|
|
||||||
fun findInnerArea(world: World, controllerPos: BlockPos, frameBlock: Block): Pair<BlockPos, BlockPos>? {
|
fun findInnerArea(world: World, controllerPos: BlockPos, frameBlock: Block): Pair<BlockPos, BlockPos>? {
|
||||||
val mirrorRange = 1..(MAX_SIZE + 1)
|
val mirrorRange = 1..(MAX_SIZE + 1)
|
||||||
@@ -94,36 +100,52 @@ abstract class BlockAbstractPortal(builder: BlockBuilder) : BlockSimpleShaped(bu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
includeFrom(BlockIndestructible)
|
||||||
|
|
||||||
|
localization = LocalizationStrategy.DeleteWords("Inner")
|
||||||
|
|
||||||
|
model = BlockStateModel(BlockStatePreset.SimpleFrom(Blocks.END_PORTAL), BlockModel.Manual)
|
||||||
|
|
||||||
|
material = Material.PORTAL
|
||||||
|
color = MaterialColor.BLACK
|
||||||
|
sound = SoundType.STONE
|
||||||
|
light = 15
|
||||||
|
|
||||||
|
isSolid = false
|
||||||
|
|
||||||
|
tags.add(BlockTags.PORTALS)
|
||||||
|
|
||||||
|
components.shape = object : IBlockShapeComponent {
|
||||||
|
override fun getShape(state: BlockState): VoxelShape {
|
||||||
|
return SHAPE
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getCollisionShape(state: BlockState): VoxelShape? {
|
||||||
|
return COLLISION_SHAPE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
components.renderType = INVISIBLE
|
||||||
|
|
||||||
|
components.entity = IBlockEntityComponent(impl::createTileEntity)
|
||||||
|
|
||||||
|
components.collideWithEntity = IBlockCollideWithEntityComponent { _, world, pos, entity ->
|
||||||
|
if (!world.isRemote && !entity.isPassenger && !entity.isBeingRidden && entity.canChangeDimension() && entity.posY <= pos.y + 0.05 && EntityPortalContact.shouldTeleport(entity)) {
|
||||||
|
impl.teleportEntity(world, pos, entity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interfaces[IInnerPortalBlock::class.java] = impl
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IInnerPortalBlock : IBlockInterface {
|
||||||
|
fun createTileEntity(): TileEntity
|
||||||
|
fun teleportEntity(world: World, pos: BlockPos, entity: Entity)
|
||||||
|
}
|
||||||
|
|
||||||
interface IPortalController {
|
interface IPortalController {
|
||||||
val clientAnimationProgress: LerpedFloat
|
val clientAnimationProgress: LerpedFloat
|
||||||
val clientPortalOffset: LerpedFloat
|
val clientPortalOffset: LerpedFloat
|
||||||
}
|
}
|
||||||
|
|
||||||
final override val localization
|
|
||||||
get() = LocalizationStrategy.DeleteWords("Inner")
|
|
||||||
|
|
||||||
final override val model
|
|
||||||
get() = BlockStateModel(BlockStatePreset.SimpleFrom(Blocks.END_PORTAL), BlockModel.Manual)
|
|
||||||
|
|
||||||
final override val tags
|
|
||||||
get() = listOf(BlockTags.PORTALS)
|
|
||||||
|
|
||||||
override fun hasTileEntity(state: BlockState): Boolean {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract override fun createTileEntity(state: BlockState, world: IBlockReader): TileEntity
|
|
||||||
protected abstract fun onEntityInside(world: World, pos: BlockPos, entity: Entity)
|
|
||||||
|
|
||||||
final override fun onEntityCollision(state: BlockState, world: World, pos: BlockPos, entity: Entity) {
|
|
||||||
if (!world.isRemote && !entity.isPassenger && !entity.isBeingRidden && entity.canChangeDimension() && entity.posY <= pos.y + 0.05) {
|
|
||||||
onEntityInside(world, pos, entity)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getCollisionShape(state: BlockState, world: IBlockReader, pos: BlockPos, context: ISelectionContext): VoxelShape {
|
|
||||||
return COLLISION_AABB
|
|
||||||
}
|
|
||||||
|
|
||||||
final override fun getRenderType(state: BlockState) = INVISIBLE
|
|
||||||
}
|
}
|
||||||
|
@@ -5,11 +5,18 @@ import chylex.hee.game.Resource.location
|
|||||||
import chylex.hee.game.block.BlockCorruptedEnergy.SpawnResult.FAIL
|
import chylex.hee.game.block.BlockCorruptedEnergy.SpawnResult.FAIL
|
||||||
import chylex.hee.game.block.BlockCorruptedEnergy.SpawnResult.PASSTHROUGH
|
import chylex.hee.game.block.BlockCorruptedEnergy.SpawnResult.PASSTHROUGH
|
||||||
import chylex.hee.game.block.BlockCorruptedEnergy.SpawnResult.SUCCESS
|
import chylex.hee.game.block.BlockCorruptedEnergy.SpawnResult.SUCCESS
|
||||||
|
import chylex.hee.game.block.builder.HeeBlockBuilder
|
||||||
|
import chylex.hee.game.block.components.IBlockClientEffectsComponent
|
||||||
|
import chylex.hee.game.block.components.IBlockCollideWithEntityComponent
|
||||||
|
import chylex.hee.game.block.components.IBlockRandomTickComponent
|
||||||
|
import chylex.hee.game.block.components.IBlockScheduledTickComponent
|
||||||
import chylex.hee.game.block.entity.TileEntityEnergyCluster
|
import chylex.hee.game.block.entity.TileEntityEnergyCluster
|
||||||
import chylex.hee.game.block.properties.BlockBuilder
|
import chylex.hee.game.block.properties.BlockDrop
|
||||||
import chylex.hee.game.block.properties.BlockModel
|
import chylex.hee.game.block.properties.BlockModel
|
||||||
import chylex.hee.game.block.properties.BlockStateModel
|
import chylex.hee.game.block.properties.BlockStateModel
|
||||||
import chylex.hee.game.block.properties.BlockStatePreset
|
import chylex.hee.game.block.properties.BlockStatePreset
|
||||||
|
import chylex.hee.game.block.properties.Materials
|
||||||
|
import chylex.hee.game.block.properties.TickSchedule
|
||||||
import chylex.hee.game.block.util.Property
|
import chylex.hee.game.block.util.Property
|
||||||
import chylex.hee.game.block.util.with
|
import chylex.hee.game.block.util.with
|
||||||
import chylex.hee.game.entity.CustomCreatureType
|
import chylex.hee.game.entity.CustomCreatureType
|
||||||
@@ -35,60 +42,123 @@ import chylex.hee.game.world.util.getTile
|
|||||||
import chylex.hee.game.world.util.removeBlock
|
import chylex.hee.game.world.util.removeBlock
|
||||||
import chylex.hee.game.world.util.setState
|
import chylex.hee.game.world.util.setState
|
||||||
import chylex.hee.init.ModBlocks
|
import chylex.hee.init.ModBlocks
|
||||||
import chylex.hee.util.forge.Side
|
|
||||||
import chylex.hee.util.forge.Sided
|
|
||||||
import chylex.hee.util.random.nextInt
|
import chylex.hee.util.random.nextInt
|
||||||
import chylex.hee.util.random.removeItem
|
import chylex.hee.util.random.removeItem
|
||||||
import net.minecraft.block.Block
|
|
||||||
import net.minecraft.block.BlockRenderType.INVISIBLE
|
import net.minecraft.block.BlockRenderType.INVISIBLE
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.block.Blocks
|
import net.minecraft.block.Blocks
|
||||||
import net.minecraft.entity.Entity
|
import net.minecraft.block.SoundType
|
||||||
|
import net.minecraft.block.material.MaterialColor
|
||||||
import net.minecraft.entity.LivingEntity
|
import net.minecraft.entity.LivingEntity
|
||||||
import net.minecraft.state.StateContainer.Builder
|
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.world.IBlockReader
|
|
||||||
import net.minecraft.world.World
|
import net.minecraft.world.World
|
||||||
import net.minecraft.world.server.ServerWorld
|
|
||||||
import java.util.Random
|
import java.util.Random
|
||||||
|
|
||||||
class BlockCorruptedEnergy(builder: BlockBuilder) : HeeBlock(builder) {
|
object BlockCorruptedEnergy : HeeBlockBuilder() {
|
||||||
companion object {
|
private const val MIN_LEVEL = 0
|
||||||
private const val MIN_LEVEL = 0
|
private const val MAX_LEVEL = 20
|
||||||
private const val MAX_LEVEL = 20
|
|
||||||
|
private const val MAX_TICK_RATE = 5
|
||||||
|
private const val MIN_TICK_RATE = 1
|
||||||
|
|
||||||
|
val LEVEL = Property.int("level", MIN_LEVEL..MAX_LEVEL)
|
||||||
|
|
||||||
|
private val DAMAGE_PART_NORMAL = Damage(DIFFICULTY_SCALING, ARMOR_PROTECTION(false), ENCHANTMENT_PROTECTION)
|
||||||
|
private val DAMAGE_PART_MAGIC = Damage(MAGIC_TYPE, NUDITY_DANGER, RAPID_DAMAGE(2))
|
||||||
|
|
||||||
|
private val PARTICLE_CORRUPTION = ParticleSpawnerCustom(
|
||||||
|
type = ParticleCorruptedEnergy,
|
||||||
|
pos = InBox(0.75F),
|
||||||
|
mot = InBox(0.05F),
|
||||||
|
hideOnMinimalSetting = false
|
||||||
|
)
|
||||||
|
|
||||||
|
init {
|
||||||
|
localization = LocalizationStrategy.None
|
||||||
|
model = BlockStateModel(BlockStatePreset.Simple, BlockModel.NoAmbientOcclusion(BlockModel.Cross(Blocks.BARRIER.asItem().location)))
|
||||||
|
// renderLayer = CUTOUT // Debugging
|
||||||
|
|
||||||
private const val MAX_TICK_RATE = 5
|
material = Materials.CORRUPTED_ENERGY
|
||||||
private const val MIN_TICK_RATE = 1
|
color = MaterialColor.PURPLE
|
||||||
|
sound = SoundType.SAND
|
||||||
|
|
||||||
val LEVEL = Property.int("level", MIN_LEVEL..MAX_LEVEL)
|
isSolid = false
|
||||||
|
|
||||||
private val DAMAGE_PART_NORMAL = Damage(DIFFICULTY_SCALING, ARMOR_PROTECTION(false), ENCHANTMENT_PROTECTION)
|
drop = BlockDrop.Nothing
|
||||||
private val DAMAGE_PART_MAGIC = Damage(MAGIC_TYPE, NUDITY_DANGER, RAPID_DAMAGE(2))
|
|
||||||
|
|
||||||
private val PARTICLE_CORRUPTION = ParticleSpawnerCustom(
|
components.states.set(LEVEL, MIN_LEVEL)
|
||||||
type = ParticleCorruptedEnergy,
|
|
||||||
pos = InBox(0.75F),
|
|
||||||
mot = InBox(0.05F),
|
|
||||||
hideOnMinimalSetting = false
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun tickRateForLevel(level: Int): Int {
|
components.renderType = INVISIBLE
|
||||||
return (MAX_TICK_RATE - (level / 2)).coerceAtLeast(MIN_TICK_RATE)
|
components.ambientOcclusionValue = 1F
|
||||||
|
|
||||||
|
components.clientEffects = object : IBlockClientEffectsComponent {
|
||||||
|
override fun randomTick(state: BlockState, world: World, pos: BlockPos, rand: Random) {
|
||||||
|
val amount = rand.nextInt(0, 2)
|
||||||
|
if (amount > 0) {
|
||||||
|
PARTICLE_CORRUPTION.spawn(Point(pos, amount), rand) // POLISH figure out how to show particles outside animateTick range
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isEntityTolerant(entity: LivingEntity): Boolean {
|
components.scheduledTick = object : IBlockScheduledTickComponent {
|
||||||
return CustomCreatureType.isDemon(entity) || CustomCreatureType.isShadow(entity) || entity is IImmuneToCorruptedEnergy
|
override fun onAdded(state: BlockState, world: World, pos: BlockPos, rand: Random): TickSchedule {
|
||||||
|
return tickScheduleForLevel(state[LEVEL])
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTick(state: BlockState, world: World, pos: BlockPos, rand: Random): TickSchedule {
|
||||||
|
val level = state[LEVEL]
|
||||||
|
val remainingFacings = Facing6.toMutableList()
|
||||||
|
|
||||||
|
repeat(rand.nextInt(3, 5).coerceAtMost(level)) {
|
||||||
|
val facing = rand.removeItem(remainingFacings)
|
||||||
|
val adjacentPos = pos.offset(facing)
|
||||||
|
|
||||||
|
val spreadDecrease = if (rand.nextInt(3) == 0) 0 else 1
|
||||||
|
|
||||||
|
if (spawn(world, adjacentPos, level - spreadDecrease) == PASSTHROUGH) {
|
||||||
|
spawn(world, adjacentPos.offset(facing), level - spreadDecrease - 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rand.nextInt(4) != 0) {
|
||||||
|
val decreaseToLevel = level - rand.nextInt(1, 2)
|
||||||
|
|
||||||
|
if (decreaseToLevel < MIN_LEVEL) {
|
||||||
|
pos.removeBlock(world)
|
||||||
|
return TickSchedule.Never
|
||||||
|
}
|
||||||
|
|
||||||
|
pos.setState(world, state.with(LEVEL, decreaseToLevel), FLAG_NONE) // does not call onBlockAdded for the same Block instance
|
||||||
|
}
|
||||||
|
|
||||||
|
return tickScheduleForLevel(level)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun tickScheduleForLevel(level: Int): TickSchedule {
|
||||||
|
return TickSchedule.InTicks((MAX_TICK_RATE - (level / 2)).coerceAtLeast(MIN_TICK_RATE))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
components.randomTick = IBlockRandomTickComponent { state, world, pos, _ ->
|
||||||
|
if (!world.pendingBlockTicks.isTickScheduled(pos, state.block)) {
|
||||||
|
pos.removeBlock(world)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
components.collideWithEntity = IBlockCollideWithEntityComponent { state, world, pos, entity ->
|
||||||
|
if (!world.isRemote && entity is LivingEntity && !isEntityTolerant(entity)) {
|
||||||
|
CombinedDamage(
|
||||||
|
DAMAGE_PART_NORMAL to 0.75F,
|
||||||
|
DAMAGE_PART_MAGIC to (0.75F + state[LEVEL] / 10F)
|
||||||
|
).dealTo(entity, TITLE_MAGIC)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
components.isAir = true
|
||||||
}
|
}
|
||||||
|
|
||||||
override val localization
|
private fun isEntityTolerant(entity: LivingEntity): Boolean {
|
||||||
get() = LocalizationStrategy.None
|
return CustomCreatureType.isDemon(entity) || CustomCreatureType.isShadow(entity) || entity is IImmuneToCorruptedEnergy
|
||||||
|
|
||||||
override val model
|
|
||||||
get() = BlockStateModel(BlockStatePreset.Simple, BlockModel.NoAmbientOcclusion(BlockModel.Cross(Blocks.BARRIER.asItem().location)))
|
|
||||||
|
|
||||||
override fun fillStateContainer(container: Builder<Block, BlockState>) {
|
|
||||||
container.add(LEVEL)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Utility methods
|
// Utility methods
|
||||||
@@ -97,19 +167,19 @@ class BlockCorruptedEnergy(builder: BlockBuilder) : HeeBlock(builder) {
|
|||||||
SUCCESS, PASSTHROUGH, FAIL
|
SUCCESS, PASSTHROUGH, FAIL
|
||||||
}
|
}
|
||||||
|
|
||||||
fun spawnCorruptedEnergy(world: World, pos: BlockPos, level: Int): SpawnResult {
|
fun spawn(world: World, pos: BlockPos, level: Int): SpawnResult {
|
||||||
if (level < MIN_LEVEL) {
|
if (level < MIN_LEVEL) {
|
||||||
return FAIL
|
return FAIL
|
||||||
}
|
}
|
||||||
else if (level > MAX_LEVEL) {
|
else if (level > MAX_LEVEL) {
|
||||||
return spawnCorruptedEnergy(world, pos, MAX_LEVEL)
|
return spawn(world, pos, MAX_LEVEL)
|
||||||
}
|
}
|
||||||
|
|
||||||
val currentState = pos.getState(world)
|
val currentState = pos.getState(world)
|
||||||
val currentBlock = currentState.block
|
val currentBlock = currentState.block
|
||||||
var updateFlags = FLAG_SYNC_CLIENT
|
var updateFlags = FLAG_SYNC_CLIENT
|
||||||
|
|
||||||
if (currentBlock === this) {
|
if (currentBlock === ModBlocks.CORRUPTED_ENERGY) {
|
||||||
if (level - currentState[LEVEL] < 3 || world.rand.nextBoolean()) {
|
if (level - currentState[LEVEL] < 3 || world.rand.nextBoolean()) {
|
||||||
return FAIL
|
return FAIL
|
||||||
}
|
}
|
||||||
@@ -130,88 +200,7 @@ class BlockCorruptedEnergy(builder: BlockBuilder) : HeeBlock(builder) {
|
|||||||
PASSTHROUGH
|
PASSTHROUGH
|
||||||
}
|
}
|
||||||
|
|
||||||
pos.setState(world, this.with(LEVEL, level), updateFlags)
|
pos.setState(world, ModBlocks.CORRUPTED_ENERGY.with(LEVEL, level), updateFlags)
|
||||||
return SUCCESS
|
return SUCCESS
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tick handling
|
|
||||||
|
|
||||||
override fun onBlockAdded(state: BlockState, world: World, pos: BlockPos, oldState: BlockState, isMoving: Boolean) {
|
|
||||||
world.pendingBlockTicks.scheduleTick(pos, this, tickRateForLevel(state[LEVEL]))
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun randomTick(state: BlockState, world: ServerWorld, pos: BlockPos, rand: Random) {
|
|
||||||
if (!world.pendingBlockTicks.isTickScheduled(pos, this)) {
|
|
||||||
pos.removeBlock(world)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun tick(state: BlockState, world: ServerWorld, pos: BlockPos, rand: Random) {
|
|
||||||
val level = state[LEVEL]
|
|
||||||
val remainingFacings = Facing6.toMutableList()
|
|
||||||
|
|
||||||
repeat(rand.nextInt(3, 5).coerceAtMost(level)) {
|
|
||||||
val facing = rand.removeItem(remainingFacings)
|
|
||||||
val adjacentPos = pos.offset(facing)
|
|
||||||
|
|
||||||
val spreadDecrease = if (rand.nextInt(3) == 0) 0 else 1
|
|
||||||
|
|
||||||
if (spawnCorruptedEnergy(world, adjacentPos, level - spreadDecrease) == PASSTHROUGH) {
|
|
||||||
spawnCorruptedEnergy(world, adjacentPos.offset(facing), level - spreadDecrease - 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rand.nextInt(4) != 0) {
|
|
||||||
val decreaseToLevel = level - rand.nextInt(1, 2)
|
|
||||||
|
|
||||||
if (decreaseToLevel < MIN_LEVEL) {
|
|
||||||
pos.removeBlock(world)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
pos.setState(world, state.with(LEVEL, decreaseToLevel), FLAG_NONE) // does not call onBlockAdded for the same Block instance
|
|
||||||
}
|
|
||||||
|
|
||||||
world.pendingBlockTicks.scheduleTick(pos, this, tickRateForLevel(level))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Interactions
|
|
||||||
|
|
||||||
override fun isAir(state: BlockState, world: IBlockReader, pos: BlockPos): Boolean {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun propagatesSkylightDown(state: BlockState, world: IBlockReader, pos: BlockPos): Boolean {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onEntityCollision(state: BlockState, world: World, pos: BlockPos, entity: Entity) {
|
|
||||||
if (!world.isRemote && entity is LivingEntity && !isEntityTolerant(entity)) {
|
|
||||||
CombinedDamage(
|
|
||||||
DAMAGE_PART_NORMAL to 0.75F,
|
|
||||||
DAMAGE_PART_MAGIC to (0.75F + state[LEVEL] / 10F)
|
|
||||||
).dealTo(entity, TITLE_MAGIC)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Client side
|
|
||||||
|
|
||||||
@Sided(Side.CLIENT)
|
|
||||||
override fun animateTick(state: BlockState, world: World, pos: BlockPos, rand: Random) {
|
|
||||||
val amount = rand.nextInt(0, 2)
|
|
||||||
|
|
||||||
if (amount > 0) {
|
|
||||||
PARTICLE_CORRUPTION.spawn(Point(pos, amount), rand) // POLISH figure out how to show particles outside animateTick range
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Sided(Side.CLIENT)
|
|
||||||
override fun getAmbientOcclusionLightValue(state: BlockState, world: IBlockReader, pos: BlockPos): Float {
|
|
||||||
return 1F
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getRenderType(state: BlockState) = INVISIBLE
|
|
||||||
|
|
||||||
// Debugging
|
|
||||||
// override fun getRenderLayer() = CUTOUT
|
|
||||||
}
|
}
|
||||||
|
@@ -1,56 +1,53 @@
|
|||||||
package chylex.hee.game.block
|
package chylex.hee.game.block
|
||||||
|
|
||||||
|
import chylex.hee.game.block.builder.HeeBlockBuilder
|
||||||
|
import chylex.hee.game.block.components.IBlockAddedComponent
|
||||||
|
import chylex.hee.game.block.components.IBlockEntityComponent
|
||||||
|
import chylex.hee.game.block.components.IPlayerUseBlockComponent
|
||||||
|
import chylex.hee.game.block.components.ISetBlockStateFromNeighbor
|
||||||
import chylex.hee.game.block.entity.TileEntityEndPortalAcceptor
|
import chylex.hee.game.block.entity.TileEntityEndPortalAcceptor
|
||||||
import chylex.hee.game.block.properties.BlockBuilder
|
|
||||||
import chylex.hee.game.block.properties.BlockModel
|
import chylex.hee.game.block.properties.BlockModel
|
||||||
import chylex.hee.game.world.util.getTile
|
import chylex.hee.game.world.util.getTile
|
||||||
import chylex.hee.init.ModBlocks
|
import chylex.hee.init.ModBlocks
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.entity.player.PlayerEntity
|
import net.minecraft.entity.player.PlayerEntity
|
||||||
import net.minecraft.tileentity.TileEntity
|
|
||||||
import net.minecraft.util.ActionResultType
|
import net.minecraft.util.ActionResultType
|
||||||
import net.minecraft.util.ActionResultType.PASS
|
import net.minecraft.util.ActionResultType.PASS
|
||||||
import net.minecraft.util.ActionResultType.SUCCESS
|
import net.minecraft.util.ActionResultType.SUCCESS
|
||||||
import net.minecraft.util.Direction
|
|
||||||
import net.minecraft.util.Direction.UP
|
import net.minecraft.util.Direction.UP
|
||||||
import net.minecraft.util.Hand
|
import net.minecraft.util.Hand
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.util.math.BlockRayTraceResult
|
|
||||||
import net.minecraft.world.IBlockReader
|
|
||||||
import net.minecraft.world.IWorld
|
|
||||||
import net.minecraft.world.World
|
import net.minecraft.world.World
|
||||||
|
|
||||||
class BlockEndPortalAcceptor(builder: BlockBuilder) : BlockPortalFrame(builder) {
|
object BlockEndPortalAcceptor : HeeBlockBuilder() {
|
||||||
override val model
|
init {
|
||||||
get() = BlockModel.PortalFrame(ModBlocks.END_PORTAL_FRAME, "acceptor")
|
includeFrom(BlockPortalFrameIndestructible)
|
||||||
|
|
||||||
override fun hasTileEntity(state: BlockState): Boolean {
|
model = BlockModel.PortalFrame(ModBlocks.END_PORTAL_FRAME, "acceptor")
|
||||||
return true
|
|
||||||
}
|
components.entity = IBlockEntityComponent(::TileEntityEndPortalAcceptor)
|
||||||
|
|
||||||
override fun createTileEntity(state: BlockState, world: IBlockReader): TileEntity {
|
components.onAdded = IBlockAddedComponent { _, world, pos ->
|
||||||
return TileEntityEndPortalAcceptor()
|
BlockAbstractPortal.spawnInnerBlocks(world, pos, ModBlocks.END_PORTAL_FRAME, ModBlocks.END_PORTAL_INNER, minSize = 1)
|
||||||
}
|
|
||||||
|
|
||||||
override fun onBlockAdded(state: BlockState, world: World, pos: BlockPos, oldState: BlockState, isMoving: Boolean) {
|
|
||||||
BlockAbstractPortal.spawnInnerBlocks(world, pos, ModBlocks.END_PORTAL_FRAME, ModBlocks.END_PORTAL_INNER, minSize = 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onBlockActivated(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, hit: BlockRayTraceResult): ActionResultType {
|
|
||||||
if (player.isCreative && player.isSneaking) {
|
|
||||||
pos.getTile<TileEntityEndPortalAcceptor>(world)?.toggleChargeFromCreativeMode()
|
|
||||||
return SUCCESS
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return PASS
|
components.setStateFromNeighbor = ISetBlockStateFromNeighbor { state, world, pos, neighborFacing, _ ->
|
||||||
}
|
if (!world.isRemote && neighborFacing == UP) {
|
||||||
|
pos.getTile<TileEntityEndPortalAcceptor>(world)?.refreshClusterState()
|
||||||
override fun updatePostPlacement(state: BlockState, facing: Direction, neighborState: BlockState, world: IWorld, pos: BlockPos, neighborPos: BlockPos): BlockState {
|
} // TODO neighbor changed?
|
||||||
if (!world.isRemote && facing == UP) {
|
|
||||||
pos.getTile<TileEntityEndPortalAcceptor>(world)?.refreshClusterState()
|
state
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("DEPRECATION")
|
components.playerUse = object : IPlayerUseBlockComponent {
|
||||||
return super.updatePostPlacement(state, facing, neighborState, world, pos, neighborPos)
|
override fun use(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, hand: Hand): ActionResultType {
|
||||||
|
if (player.isCreative && player.isSneaking) {
|
||||||
|
pos.getTile<TileEntityEndPortalAcceptor>(world)?.toggleChargeFromCreativeMode()
|
||||||
|
return SUCCESS
|
||||||
|
}
|
||||||
|
|
||||||
|
return PASS
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
package chylex.hee.game.block
|
package chylex.hee.game.block
|
||||||
|
|
||||||
import chylex.hee.HEE
|
import chylex.hee.HEE
|
||||||
|
import chylex.hee.game.block.BlockAbstractPortal.IInnerPortalBlock
|
||||||
|
import chylex.hee.game.block.builder.HeeBlockBuilder
|
||||||
import chylex.hee.game.block.entity.TileEntityEndPortalAcceptor
|
import chylex.hee.game.block.entity.TileEntityEndPortalAcceptor
|
||||||
import chylex.hee.game.block.entity.TileEntityPortalInner
|
import chylex.hee.game.block.entity.TileEntityPortalInner
|
||||||
import chylex.hee.game.block.properties.BlockBuilder
|
|
||||||
import chylex.hee.game.entity.util.EntityPortalContact
|
|
||||||
import chylex.hee.game.mechanics.causatum.CausatumStage
|
import chylex.hee.game.mechanics.causatum.CausatumStage
|
||||||
import chylex.hee.game.mechanics.causatum.EnderCausatum
|
import chylex.hee.game.mechanics.causatum.EnderCausatum
|
||||||
import chylex.hee.game.world.isEndDimension
|
import chylex.hee.game.world.isEndDimension
|
||||||
@@ -12,41 +12,39 @@ import chylex.hee.game.world.server.DimensionTeleporter
|
|||||||
import chylex.hee.game.world.util.closestTickingTile
|
import chylex.hee.game.world.util.closestTickingTile
|
||||||
import chylex.hee.init.ModBlocks
|
import chylex.hee.init.ModBlocks
|
||||||
import chylex.hee.util.math.Pos
|
import chylex.hee.util.math.Pos
|
||||||
import net.minecraft.block.BlockState
|
|
||||||
import net.minecraft.entity.Entity
|
import net.minecraft.entity.Entity
|
||||||
import net.minecraft.entity.player.PlayerEntity
|
import net.minecraft.entity.player.PlayerEntity
|
||||||
import net.minecraft.tileentity.TileEntity
|
import net.minecraft.tileentity.TileEntity
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.world.IBlockReader
|
|
||||||
import net.minecraft.world.World
|
import net.minecraft.world.World
|
||||||
|
|
||||||
class BlockEndPortalInner(builder: BlockBuilder) : BlockAbstractPortal(builder) {
|
object BlockEndPortalInner : HeeBlockBuilder() {
|
||||||
override fun createTileEntity(state: BlockState, world: IBlockReader): TileEntity {
|
init {
|
||||||
return TileEntityPortalInner.End()
|
includeFrom(BlockAbstractPortal(object : IInnerPortalBlock {
|
||||||
}
|
override fun createTileEntity(): TileEntity {
|
||||||
|
return TileEntityPortalInner.End()
|
||||||
override fun onEntityInside(world: World, pos: BlockPos, entity: Entity) {
|
|
||||||
if (!EntityPortalContact.shouldTeleport(entity)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (world.isEndDimension) {
|
|
||||||
DimensionTeleporter.changeDimension(entity, World.OVERWORLD, DimensionTeleporter.LastEndPortal)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
val acceptor = pos.closestTickingTile<TileEntityEndPortalAcceptor>(world, MAX_DISTANCE_FROM_FRAME)
|
|
||||||
|
|
||||||
if (acceptor != null && acceptor.isCharged) {
|
|
||||||
findInnerArea(world, acceptor.pos, ModBlocks.END_PORTAL_FRAME)?.let { (min, max) ->
|
|
||||||
DimensionTeleporter.LastEndPortal.updateForEntity(entity, Pos((min.x + max.x) / 2, pos.y, (min.z + max.z) / 2))
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entity is PlayerEntity) {
|
|
||||||
EnderCausatum.triggerStage(entity, CausatumStage.S2_ENTERED_END)
|
|
||||||
}
|
|
||||||
|
|
||||||
DimensionTeleporter.changeDimension(entity, HEE.dim, DimensionTeleporter.EndSpawnPortal)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
override fun teleportEntity(world: World, pos: BlockPos, entity: Entity) {
|
||||||
|
if (world.isEndDimension) {
|
||||||
|
DimensionTeleporter.changeDimension(entity, World.OVERWORLD, DimensionTeleporter.LastEndPortal)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
val acceptor = pos.closestTickingTile<TileEntityEndPortalAcceptor>(world, BlockAbstractPortal.MAX_DISTANCE_FROM_FRAME)
|
||||||
|
|
||||||
|
if (acceptor != null && acceptor.isCharged) {
|
||||||
|
BlockAbstractPortal.findInnerArea(world, acceptor.pos, ModBlocks.END_PORTAL_FRAME)?.let { (min, max) ->
|
||||||
|
DimensionTeleporter.LastEndPortal.updateForEntity(entity, Pos((min.x + max.x) / 2, pos.y, (min.z + max.z) / 2))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity is PlayerEntity) {
|
||||||
|
EnderCausatum.triggerStage(entity, CausatumStage.S2_ENTERED_END)
|
||||||
|
}
|
||||||
|
|
||||||
|
DimensionTeleporter.changeDimension(entity, HEE.dim, DimensionTeleporter.EndSpawnPortal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,22 +1,23 @@
|
|||||||
package chylex.hee.game.block
|
package chylex.hee.game.block
|
||||||
|
|
||||||
import chylex.hee.game.block.properties.BlockBuilder
|
import chylex.hee.game.block.builder.HeeBlockBuilder
|
||||||
|
import chylex.hee.game.block.components.IBlockExperienceComponent
|
||||||
import chylex.hee.game.block.properties.BlockDrop
|
import chylex.hee.game.block.properties.BlockDrop
|
||||||
|
import chylex.hee.game.block.properties.BlockHardness
|
||||||
|
import chylex.hee.game.block.properties.BlockHarvestTool
|
||||||
|
import chylex.hee.game.item.util.Tool.Level.STONE
|
||||||
import chylex.hee.util.random.nextInt
|
import chylex.hee.util.random.nextInt
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraftforge.common.ToolType.PICKAXE
|
||||||
import net.minecraft.util.math.BlockPos
|
|
||||||
import net.minecraft.world.IWorldReader
|
|
||||||
import net.minecraft.world.World
|
|
||||||
import net.minecraftforge.common.Tags
|
|
||||||
|
|
||||||
class BlockEndPowderOre(builder: BlockBuilder) : HeeBlock(builder) {
|
object BlockEndPowderOre : HeeBlockBuilder() {
|
||||||
override val drop
|
init {
|
||||||
get() = BlockDrop.Manual
|
includeFrom(BlockEndOre)
|
||||||
|
|
||||||
override val tags
|
drop = BlockDrop.Manual
|
||||||
get() = listOf(Tags.Blocks.ORES)
|
|
||||||
|
tool = BlockHarvestTool.required(STONE, PICKAXE)
|
||||||
override fun getExpDrop(state: BlockState, world: IWorldReader, pos: BlockPos, fortune: Int, silktouch: Int): Int {
|
hardness = BlockHardness(hardness = 2F, resistance = 5.4F)
|
||||||
return ((world as? World)?.rand ?: RANDOM).nextInt(1, 2)
|
|
||||||
|
components.experience = IBlockExperienceComponent { rand -> rand.nextInt(1, 2) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,22 +2,48 @@ package chylex.hee.game.block
|
|||||||
|
|
||||||
import chylex.hee.client.text.LocalizationStrategy
|
import chylex.hee.client.text.LocalizationStrategy
|
||||||
import chylex.hee.game.Resource.location
|
import chylex.hee.game.Resource.location
|
||||||
import chylex.hee.game.block.properties.BlockBuilder
|
import chylex.hee.game.block.builder.HeeBlockBuilder
|
||||||
|
import chylex.hee.game.block.properties.BlockHardness
|
||||||
|
import chylex.hee.game.block.properties.BlockHarvestTool
|
||||||
import chylex.hee.game.block.properties.BlockModel
|
import chylex.hee.game.block.properties.BlockModel
|
||||||
|
import chylex.hee.game.block.properties.IBlockStateModelSupplier
|
||||||
|
import chylex.hee.game.item.util.Tool.Level.WOOD
|
||||||
import net.minecraft.block.Blocks
|
import net.minecraft.block.Blocks
|
||||||
import net.minecraft.block.material.MaterialColor
|
import net.minecraft.block.material.MaterialColor
|
||||||
import net.minecraftforge.common.Tags
|
import net.minecraftforge.common.Tags
|
||||||
|
import net.minecraftforge.common.ToolType.PICKAXE
|
||||||
|
|
||||||
class BlockEndStoneCustom(builder: BlockBuilder, mapColor: MaterialColor) : HeeBlock(builder.clone { color = mapColor }) {
|
object BlockEndStoneCustom : HeeBlockBuilder() {
|
||||||
override val localization
|
init {
|
||||||
get() = LocalizationStrategy.MoveToBeginning(wordCount = 1)
|
includeFrom(BlockEndStoneBase)
|
||||||
|
|
||||||
|
localization = LocalizationStrategy.MoveToBeginning(wordCount = 1)
|
||||||
|
|
||||||
|
model = IBlockStateModelSupplier {
|
||||||
|
BlockModel.WithTextures(
|
||||||
|
BlockModel.CubeBottomTop(bottom = Blocks.END_STONE.location),
|
||||||
|
mapOf("particle" to it.location("_top"))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
tags.add(Tags.Blocks.END_STONES)
|
||||||
|
|
||||||
|
tool = BlockHarvestTool.required(WOOD, PICKAXE)
|
||||||
|
hardness = BlockHardness(hardness = 3F, resistance = 9F)
|
||||||
|
}
|
||||||
|
|
||||||
override val model
|
val INFESTED = HeeBlockBuilder {
|
||||||
get() = BlockModel.WithTextures(
|
includeFrom(BlockEndStoneCustom)
|
||||||
BlockModel.CubeBottomTop(bottom = Blocks.END_STONE.location),
|
color = MaterialColor.RED
|
||||||
mapOf("particle" to this.location("_top"))
|
}
|
||||||
)
|
|
||||||
|
|
||||||
override val tags
|
val BURNED = HeeBlockBuilder {
|
||||||
get() = listOf(Tags.Blocks.END_STONES)
|
includeFrom(BlockEndStoneCustom)
|
||||||
|
color = MaterialColor.ADOBE // RENAME ORANGE
|
||||||
|
}
|
||||||
|
|
||||||
|
val ENCHANTED = HeeBlockBuilder {
|
||||||
|
includeFrom(BlockEndStoneCustom)
|
||||||
|
color = MaterialColor.PURPLE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,26 +1,48 @@
|
|||||||
package chylex.hee.game.block
|
package chylex.hee.game.block
|
||||||
|
|
||||||
import chylex.hee.game.block.properties.BlockBuilder
|
import chylex.hee.game.block.builder.HeeBlockBuilder
|
||||||
import net.minecraft.block.BlockState
|
import chylex.hee.game.block.components.IBlockHarvestabilityComponent
|
||||||
import net.minecraft.entity.player.PlayerEntity
|
import chylex.hee.game.block.properties.BlockHardness
|
||||||
|
import chylex.hee.game.block.properties.BlockHarvestTool
|
||||||
|
import chylex.hee.game.block.properties.Materials
|
||||||
|
import chylex.hee.game.item.util.Tool.Level.IRON
|
||||||
|
import chylex.hee.util.forge.EventResult
|
||||||
|
import net.minecraft.block.SoundType
|
||||||
|
import net.minecraft.block.material.MaterialColor
|
||||||
import net.minecraft.item.Items
|
import net.minecraft.item.Items
|
||||||
import net.minecraft.util.Hand.MAIN_HAND
|
import net.minecraft.util.Hand.MAIN_HAND
|
||||||
import net.minecraft.util.math.BlockPos
|
|
||||||
import net.minecraft.world.IBlockReader
|
|
||||||
import net.minecraftforge.common.Tags
|
import net.minecraftforge.common.Tags
|
||||||
|
import net.minecraftforge.common.ToolType.PICKAXE
|
||||||
|
|
||||||
sealed class BlockEndium(builder: BlockBuilder) : HeeBlock(builder) {
|
abstract class BlockEndium : HeeBlockBuilder() {
|
||||||
override fun canHarvestBlock(state: BlockState, world: IBlockReader, pos: BlockPos, player: PlayerEntity): Boolean {
|
init {
|
||||||
return super.canHarvestBlock(state, world, pos, player) || player.getHeldItem(MAIN_HAND).item === Items.GOLDEN_PICKAXE
|
material = Materials.SOLID
|
||||||
|
tool = BlockHarvestTool.required(IRON, PICKAXE)
|
||||||
|
|
||||||
|
components.harvestability = IBlockHarvestabilityComponent {
|
||||||
|
if (it.getHeldItem(MAIN_HAND).item === Items.GOLDEN_PICKAXE)
|
||||||
|
EventResult.ALLOW
|
||||||
|
else
|
||||||
|
EventResult.DEFAULT
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Ore(builder: BlockBuilder) : BlockEndium(builder) {
|
object Ore : BlockEndium() {
|
||||||
override val tags
|
init {
|
||||||
get() = listOf(Tags.Blocks.ORES)
|
includeFrom(BlockEndOre)
|
||||||
|
|
||||||
|
hardness = BlockHardness(hardness = 5F, resistance = 9.9F)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Block(builder: BlockBuilder) : BlockEndium(builder) {
|
object Block : BlockEndium() {
|
||||||
override val tags
|
init {
|
||||||
get() = listOf(Tags.Blocks.STORAGE_BLOCKS)
|
color = MaterialColor.LAPIS
|
||||||
|
sound = SoundType.METAL
|
||||||
|
|
||||||
|
tags.add(Tags.Blocks.STORAGE_BLOCKS)
|
||||||
|
|
||||||
|
hardness = BlockHardness(hardness = 6.2F, resistance = 12F)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -9,7 +9,6 @@ import chylex.hee.game.mechanics.instability.Instability
|
|||||||
import chylex.hee.game.world.util.allInCenteredSphereMutable
|
import chylex.hee.game.world.util.allInCenteredSphereMutable
|
||||||
import chylex.hee.game.world.util.getTile
|
import chylex.hee.game.world.util.getTile
|
||||||
import chylex.hee.game.world.util.removeBlock
|
import chylex.hee.game.world.util.removeBlock
|
||||||
import chylex.hee.init.ModBlocks
|
|
||||||
import chylex.hee.init.ModItems
|
import chylex.hee.init.ModItems
|
||||||
import chylex.hee.util.forge.Side
|
import chylex.hee.util.forge.Side
|
||||||
import chylex.hee.util.forge.Sided
|
import chylex.hee.util.forge.Sided
|
||||||
@@ -43,7 +42,7 @@ class BlockEnergyCluster(builder: BlockBuilder) : BlockSimpleShaped(builder, Axi
|
|||||||
val units = amount.units.value.toFloat()
|
val units = amount.units.value.toFloat()
|
||||||
val corruptedEnergyLevel = (2F + (units.pow(0.74F) / 9F)).ceilToInt()
|
val corruptedEnergyLevel = (2F + (units.pow(0.74F) / 9F)).ceilToInt()
|
||||||
|
|
||||||
ModBlocks.CORRUPTED_ENERGY.spawnCorruptedEnergy(world, pos, corruptedEnergyLevel)
|
BlockCorruptedEnergy.spawn(world, pos, corruptedEnergyLevel)
|
||||||
|
|
||||||
if (causeInstability) {
|
if (causeInstability) {
|
||||||
Instability.get(world).triggerAction((10 + 2 * corruptedEnergyLevel).toUShort(), pos)
|
Instability.get(world).triggerAction((10 + 2 * corruptedEnergyLevel).toUShort(), pos)
|
||||||
@@ -57,7 +56,7 @@ class BlockEnergyCluster(builder: BlockBuilder) : BlockSimpleShaped(builder, Axi
|
|||||||
val corruptedEnergyLevel = (2F + (units.pow(0.74F) / 9F)).ceilToInt()
|
val corruptedEnergyLevel = (2F + (units.pow(0.74F) / 9F)).ceilToInt()
|
||||||
|
|
||||||
for (testPos in pos.allInCenteredSphereMutable(corruptedEnergyRadius)) {
|
for (testPos in pos.allInCenteredSphereMutable(corruptedEnergyRadius)) {
|
||||||
ModBlocks.CORRUPTED_ENERGY.spawnCorruptedEnergy(world, testPos, corruptedEnergyLevel)
|
BlockCorruptedEnergy.spawn(world, testPos, corruptedEnergyLevel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,35 +1,74 @@
|
|||||||
package chylex.hee.game.block
|
package chylex.hee.game.block
|
||||||
|
|
||||||
import chylex.hee.HEE
|
import chylex.hee.HEE
|
||||||
import chylex.hee.game.block.properties.BlockBuilder
|
import chylex.hee.client.text.LocalizationStrategy
|
||||||
|
import chylex.hee.game.block.builder.HeeBlockBuilder
|
||||||
|
import chylex.hee.game.block.components.ICreatureSpawningOnBlockComponent
|
||||||
|
import chylex.hee.game.block.properties.BlockHardness
|
||||||
|
import chylex.hee.game.block.properties.BlockHarvestTool
|
||||||
|
import chylex.hee.game.block.properties.Materials
|
||||||
import chylex.hee.game.entity.technical.EntityTechnicalTrigger
|
import chylex.hee.game.entity.technical.EntityTechnicalTrigger
|
||||||
import chylex.hee.game.entity.technical.EntityTechnicalTrigger.Types.ENERGY_SHRINE_GLOBAL
|
import chylex.hee.game.entity.technical.EntityTechnicalTrigger.Types.ENERGY_SHRINE_GLOBAL
|
||||||
import chylex.hee.game.entity.util.posVec
|
import chylex.hee.game.entity.util.posVec
|
||||||
import chylex.hee.game.entity.util.selectEntities
|
import chylex.hee.game.entity.util.selectEntities
|
||||||
|
import chylex.hee.game.item.util.Tool.Level.WOOD
|
||||||
|
import chylex.hee.game.item.util.Tool.Type.PICKAXE
|
||||||
import chylex.hee.game.world.generation.feature.energyshrine.EnergyShrinePieces
|
import chylex.hee.game.world.generation.feature.energyshrine.EnergyShrinePieces
|
||||||
|
import chylex.hee.init.ModTags
|
||||||
|
import chylex.hee.util.forge.EventResult
|
||||||
import chylex.hee.util.math.center
|
import chylex.hee.util.math.center
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.SoundType
|
||||||
|
import net.minecraft.block.material.MaterialColor
|
||||||
import net.minecraft.entity.EntitySpawnPlacementRegistry.PlacementType
|
import net.minecraft.entity.EntitySpawnPlacementRegistry.PlacementType
|
||||||
import net.minecraft.entity.EntityType
|
import net.minecraft.entity.EntityType
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.world.IBlockReader
|
import net.minecraft.world.IBlockReader
|
||||||
import net.minecraft.world.IEntityReader
|
import net.minecraft.world.IEntityReader
|
||||||
|
|
||||||
open class BlockGloomrock(builder: BlockBuilder) : HeeBlock(builder) {
|
object BlockGloomrock : HeeBlockBuilder() {
|
||||||
override fun canCreatureSpawn(state: BlockState, world: IBlockReader, pos: BlockPos, type: PlacementType?, entityType: EntityType<*>?): Boolean {
|
init {
|
||||||
if (world !is IEntityReader) {
|
material = Materials.SOLID
|
||||||
HEE.log.warn("[BlockGloomrock] attempted to check spawn on a world != IEntityReader (${world.javaClass})")
|
color = MaterialColor.BLACK
|
||||||
return false
|
sound = SoundType.STONE
|
||||||
|
|
||||||
|
tool = BlockHarvestTool.required(WOOD, PICKAXE)
|
||||||
|
hardness = BlockHardness(hardness = 1.6F, resistance = 4.2F)
|
||||||
|
|
||||||
|
tags.add(ModTags.GLOOMROCK_PARTICLES)
|
||||||
|
|
||||||
|
components.onCreatureSpawning = object : ICreatureSpawningOnBlockComponent {
|
||||||
|
override fun canSpawn(world: IBlockReader, pos: BlockPos, placementType: PlacementType?, entityType: EntityType<*>?): EventResult {
|
||||||
|
if (world !is IEntityReader) {
|
||||||
|
HEE.log.warn("[BlockGloomrock] attempted to check spawn on a world != IEntityReader (${world.javaClass})")
|
||||||
|
return EventResult.DENY
|
||||||
|
}
|
||||||
|
|
||||||
|
val center = pos.center
|
||||||
|
val size = EnergyShrinePieces.STRUCTURE_SIZE
|
||||||
|
|
||||||
|
val trigger = world
|
||||||
|
.selectEntities
|
||||||
|
.inBox<EntityTechnicalTrigger>(size.toCenteredBoundingBox(center))
|
||||||
|
.find { it.triggerType == ENERGY_SHRINE_GLOBAL }
|
||||||
|
|
||||||
|
return EventResult(trigger == null || !size.toCenteredBoundingBox(trigger.posVec).contains(center))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
val center = pos.center
|
|
||||||
val size = EnergyShrinePieces.STRUCTURE_SIZE
|
val BRICKS = HeeBlockBuilder {
|
||||||
|
includeFrom(BlockGloomrock)
|
||||||
val trigger = world
|
hardness = BlockHardness(hardness = 2.8F, resistance = 6F)
|
||||||
.selectEntities
|
}
|
||||||
.inBox<EntityTechnicalTrigger>(size.toCenteredBoundingBox(center))
|
|
||||||
.find { it.triggerType == ENERGY_SHRINE_GLOBAL }
|
val SMOOTH = HeeBlockBuilder {
|
||||||
|
includeFrom(BlockGloomrock)
|
||||||
return trigger == null || !size.toCenteredBoundingBox(trigger.posVec).contains(center)
|
localization = LocalizationStrategy.MoveToBeginning(wordCount = 1)
|
||||||
|
hardness = BlockHardness(hardness = 2F, resistance = 4.8F)
|
||||||
|
}
|
||||||
|
|
||||||
|
val SMOOTH_COLORED = HeeBlockBuilder {
|
||||||
|
includeFrom(SMOOTH)
|
||||||
|
localization = LocalizationStrategy.MoveToBeginning(LocalizationStrategy.DeleteWords("Smooth"), wordCount = 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +0,0 @@
|
|||||||
package chylex.hee.game.block
|
|
||||||
|
|
||||||
import chylex.hee.client.text.LocalizationStrategy
|
|
||||||
import chylex.hee.game.block.properties.BlockBuilder
|
|
||||||
|
|
||||||
class BlockGloomrockSmooth(builder: BlockBuilder) : BlockGloomrock(builder) {
|
|
||||||
override val localization
|
|
||||||
get() = LocalizationStrategy.MoveToBeginning(wordCount = 1)
|
|
||||||
}
|
|
@@ -1,9 +0,0 @@
|
|||||||
package chylex.hee.game.block
|
|
||||||
|
|
||||||
import chylex.hee.client.text.LocalizationStrategy
|
|
||||||
import chylex.hee.game.block.properties.BlockBuilder
|
|
||||||
|
|
||||||
class BlockGloomrockSmoothColored(builder: BlockBuilder) : BlockGloomrock(builder) {
|
|
||||||
override val localization
|
|
||||||
get() = LocalizationStrategy.MoveToBeginning(LocalizationStrategy.DeleteWords("Smooth"), wordCount = 1)
|
|
||||||
}
|
|
@@ -1,31 +1,37 @@
|
|||||||
package chylex.hee.game.block
|
package chylex.hee.game.block
|
||||||
|
|
||||||
import chylex.hee.game.Resource.location
|
import chylex.hee.game.Resource.location
|
||||||
|
import chylex.hee.game.block.builder.HeeBlockBuilder
|
||||||
|
import chylex.hee.game.block.components.IBlockAddedComponent
|
||||||
|
import chylex.hee.game.block.components.IBlockEntityComponent
|
||||||
|
import chylex.hee.game.block.components.IBlockPlacementComponent
|
||||||
|
import chylex.hee.game.block.components.IBlockShapeComponent
|
||||||
|
import chylex.hee.game.block.components.IPlayerUseBlockComponent
|
||||||
|
import chylex.hee.game.block.components.ISetBlockStateFromNeighbor
|
||||||
import chylex.hee.game.block.entity.TileEntityIgneousPlate
|
import chylex.hee.game.block.entity.TileEntityIgneousPlate
|
||||||
import chylex.hee.game.block.logic.IBlockDynamicHardness
|
import chylex.hee.game.block.logic.IBlockDynamicHardness
|
||||||
import chylex.hee.game.block.properties.BlockBuilder
|
|
||||||
import chylex.hee.game.block.properties.BlockModel
|
import chylex.hee.game.block.properties.BlockModel
|
||||||
import chylex.hee.game.block.properties.BlockStateModel
|
import chylex.hee.game.block.properties.BlockStateModel
|
||||||
import chylex.hee.game.block.properties.BlockStatePreset
|
import chylex.hee.game.block.properties.BlockStatePreset
|
||||||
|
import chylex.hee.game.block.properties.IBlockStateModelSupplier
|
||||||
|
import chylex.hee.game.block.properties.Materials
|
||||||
import chylex.hee.game.block.util.FURNACE_FACING
|
import chylex.hee.game.block.util.FURNACE_FACING
|
||||||
import chylex.hee.game.block.util.Property
|
import chylex.hee.game.block.util.Property
|
||||||
import chylex.hee.game.block.util.asVoxelShape
|
|
||||||
import chylex.hee.game.entity.technical.EntityTechnicalIgneousPlateLogic
|
import chylex.hee.game.entity.technical.EntityTechnicalIgneousPlateLogic
|
||||||
import chylex.hee.game.item.properties.ItemModel
|
import chylex.hee.game.item.properties.ItemModel
|
||||||
import chylex.hee.game.world.util.Facing6
|
import chylex.hee.game.world.util.Facing6
|
||||||
import chylex.hee.game.world.util.getState
|
import chylex.hee.game.world.util.getState
|
||||||
import chylex.hee.game.world.util.getTile
|
import chylex.hee.game.world.util.getTile
|
||||||
import net.minecraft.block.Block
|
|
||||||
import net.minecraft.block.BlockRenderType.ENTITYBLOCK_ANIMATED
|
import net.minecraft.block.BlockRenderType.ENTITYBLOCK_ANIMATED
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.block.Blocks
|
import net.minecraft.block.Blocks
|
||||||
|
import net.minecraft.block.SoundType
|
||||||
|
import net.minecraft.block.material.MaterialColor
|
||||||
import net.minecraft.entity.player.PlayerEntity
|
import net.minecraft.entity.player.PlayerEntity
|
||||||
import net.minecraft.item.BlockItemUseContext
|
import net.minecraft.item.BlockItemUseContext
|
||||||
import net.minecraft.item.ItemStack
|
import net.minecraft.item.ItemStack
|
||||||
import net.minecraft.item.Items
|
import net.minecraft.item.Items
|
||||||
import net.minecraft.state.StateContainer.Builder
|
|
||||||
import net.minecraft.tileentity.FurnaceTileEntity
|
import net.minecraft.tileentity.FurnaceTileEntity
|
||||||
import net.minecraft.tileentity.TileEntity
|
|
||||||
import net.minecraft.util.ActionResultType
|
import net.minecraft.util.ActionResultType
|
||||||
import net.minecraft.util.ActionResultType.PASS
|
import net.minecraft.util.ActionResultType.PASS
|
||||||
import net.minecraft.util.ActionResultType.SUCCESS
|
import net.minecraft.util.ActionResultType.SUCCESS
|
||||||
@@ -37,139 +43,114 @@ import net.minecraft.util.Direction.SOUTH
|
|||||||
import net.minecraft.util.Direction.UP
|
import net.minecraft.util.Direction.UP
|
||||||
import net.minecraft.util.Direction.WEST
|
import net.minecraft.util.Direction.WEST
|
||||||
import net.minecraft.util.Hand
|
import net.minecraft.util.Hand
|
||||||
import net.minecraft.util.Mirror
|
|
||||||
import net.minecraft.util.Rotation
|
|
||||||
import net.minecraft.util.math.AxisAlignedBB
|
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.util.math.BlockRayTraceResult
|
|
||||||
import net.minecraft.util.math.shapes.ISelectionContext
|
|
||||||
import net.minecraft.util.math.shapes.VoxelShape
|
import net.minecraft.util.math.shapes.VoxelShape
|
||||||
|
import net.minecraft.util.math.shapes.VoxelShapes
|
||||||
import net.minecraft.world.IBlockReader
|
import net.minecraft.world.IBlockReader
|
||||||
import net.minecraft.world.IWorld
|
|
||||||
import net.minecraft.world.IWorldReader
|
import net.minecraft.world.IWorldReader
|
||||||
import net.minecraft.world.World
|
import net.minecraft.world.World
|
||||||
|
|
||||||
class BlockIgneousPlate(builder: BlockBuilder) : HeeBlock(builder), IBlockDynamicHardness {
|
object BlockIgneousPlate : HeeBlockBuilder() {
|
||||||
companion object {
|
val FACING_NOT_DOWN = Property.facing("facing", Facing6.minusElement(DOWN))
|
||||||
val FACING_NOT_DOWN = Property.facing("facing", Facing6.minusElement(DOWN))
|
|
||||||
|
|
||||||
private const val BB_SIDE_MIN = 0.125
|
|
||||||
private const val BB_SIDE_MAX = 0.875
|
|
||||||
private const val BB_TOP = 0.125
|
|
||||||
|
|
||||||
private val BOUNDING_BOX = mapOf(
|
|
||||||
UP to AxisAlignedBB(BB_SIDE_MIN, 0.0, BB_SIDE_MIN, BB_SIDE_MAX, BB_TOP, BB_SIDE_MAX).asVoxelShape,
|
|
||||||
NORTH to AxisAlignedBB(BB_SIDE_MIN, BB_SIDE_MIN, 1.0 - BB_TOP, BB_SIDE_MAX, BB_SIDE_MAX, 1.0).asVoxelShape,
|
|
||||||
SOUTH to AxisAlignedBB(BB_SIDE_MIN, BB_SIDE_MIN, 0.0, BB_SIDE_MAX, BB_SIDE_MAX, BB_TOP).asVoxelShape,
|
|
||||||
EAST to AxisAlignedBB(0.0, BB_SIDE_MIN, BB_SIDE_MIN, BB_TOP, BB_SIDE_MAX, BB_SIDE_MAX).asVoxelShape,
|
|
||||||
WEST to AxisAlignedBB(1.0 - BB_TOP, BB_SIDE_MIN, BB_SIDE_MIN, 1.0, BB_SIDE_MAX, BB_SIDE_MAX).asVoxelShape
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun canPlacePlateAt(world: IWorldReader, pos: BlockPos, facing: Direction): Boolean {
|
|
||||||
val furnacePos = pos.offset(facing.opposite)
|
|
||||||
val state = furnacePos.getState(world)
|
|
||||||
|
|
||||||
return (
|
|
||||||
state.properties.contains(FURNACE_FACING) &&
|
|
||||||
state[FURNACE_FACING] != facing &&
|
|
||||||
furnacePos.getTile<FurnaceTileEntity>(world) != null
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override val model
|
private const val BB_SIDE_MIN = 0.125
|
||||||
get() = BlockStateModel(BlockStatePreset.Simple, BlockModel.ParticleOnly(this.location), ItemModel.Simple)
|
private const val BB_SIDE_MAX = 0.875
|
||||||
|
private const val BB_TOP = 0.125
|
||||||
|
|
||||||
|
private val BOUNDING_BOX = mapOf(
|
||||||
|
UP to VoxelShapes.create(BB_SIDE_MIN, 0.0, BB_SIDE_MIN, BB_SIDE_MAX, BB_TOP, BB_SIDE_MAX),
|
||||||
|
NORTH to VoxelShapes.create(BB_SIDE_MIN, BB_SIDE_MIN, 1.0 - BB_TOP, BB_SIDE_MAX, BB_SIDE_MAX, 1.0),
|
||||||
|
SOUTH to VoxelShapes.create(BB_SIDE_MIN, BB_SIDE_MIN, 0.0, BB_SIDE_MAX, BB_SIDE_MAX, BB_TOP),
|
||||||
|
EAST to VoxelShapes.create(0.0, BB_SIDE_MIN, BB_SIDE_MIN, BB_TOP, BB_SIDE_MAX, BB_SIDE_MAX),
|
||||||
|
WEST to VoxelShapes.create(1.0 - BB_TOP, BB_SIDE_MIN, BB_SIDE_MIN, 1.0, BB_SIDE_MAX, BB_SIDE_MAX)
|
||||||
|
)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
defaultState = stateContainer.baseState.with(FACING_NOT_DOWN, UP)
|
model = IBlockStateModelSupplier {
|
||||||
}
|
BlockStateModel(BlockStatePreset.Simple, BlockModel.ParticleOnly(it.location), ItemModel.Simple)
|
||||||
|
|
||||||
override fun fillStateContainer(container: Builder<Block, BlockState>) {
|
|
||||||
container.add(FACING_NOT_DOWN)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun hasTileEntity(state: BlockState): Boolean {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun createTileEntity(state: BlockState, world: IBlockReader): TileEntity {
|
|
||||||
return TileEntityIgneousPlate()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Placement rules
|
|
||||||
|
|
||||||
override fun isValidPosition(state: BlockState, world: IWorldReader, pos: BlockPos): Boolean {
|
|
||||||
return FACING_NOT_DOWN.allowedValues.any { canPlacePlateAt(world, pos, it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getStateForPlacement(context: BlockItemUseContext): BlockState {
|
|
||||||
val world = context.world
|
|
||||||
val pos = context.pos
|
|
||||||
val facing = context.face
|
|
||||||
|
|
||||||
return if (canPlacePlateAt(world, pos, facing))
|
|
||||||
defaultState.with(FACING_NOT_DOWN, facing)
|
|
||||||
else
|
|
||||||
FACING_NOT_DOWN.allowedValues.firstOrNull { canPlacePlateAt(world, pos, it) }?.let { defaultState.with(FACING_NOT_DOWN, it) } ?: defaultState
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onBlockAdded(state: BlockState, world: World, pos: BlockPos, oldState: BlockState, isMoving: Boolean) {
|
|
||||||
pos.offset(state[FACING_NOT_DOWN].opposite).getTile<FurnaceTileEntity>(world)?.let(EntityTechnicalIgneousPlateLogic.Companion::createForFurnace)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun updatePostPlacement(state: BlockState, facing: Direction, neighborState: BlockState, world: IWorld, pos: BlockPos, neighborPos: BlockPos): BlockState {
|
|
||||||
@Suppress("DEPRECATION")
|
|
||||||
return if (!canPlacePlateAt(world, pos, state[FACING_NOT_DOWN]))
|
|
||||||
Blocks.AIR.defaultState
|
|
||||||
else
|
|
||||||
super.updatePostPlacement(state, facing, neighborState, world, pos, neighborPos)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Interactions
|
|
||||||
|
|
||||||
override fun getBlockHardness(world: IBlockReader, pos: BlockPos, state: BlockState, originalHardness: Float): Float {
|
|
||||||
val tile = pos.getTile<TileEntityIgneousPlate>(world) ?: return 0F
|
|
||||||
|
|
||||||
return when {
|
|
||||||
tile.isOverheating -> 10F
|
|
||||||
tile.isWorking -> 4F
|
|
||||||
else -> 0F
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun onBlockActivated(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, hit: BlockRayTraceResult): ActionResultType {
|
|
||||||
val heldItem = player.getHeldItem(hand)
|
|
||||||
|
|
||||||
if (heldItem.item === Items.WATER_BUCKET) {
|
material = Materials.IGNEOUS_ROCK_PLATE
|
||||||
if (!world.isRemote && tryCoolPlate(world, pos, state) && !player.abilities.isCreativeMode) {
|
color = MaterialColor.AIR
|
||||||
player.setHeldItem(hand, ItemStack(Items.BUCKET))
|
sound = SoundType.STONE
|
||||||
|
|
||||||
|
components.states.set(FACING_NOT_DOWN, default = UP)
|
||||||
|
components.states.facingProperty = FACING_NOT_DOWN
|
||||||
|
|
||||||
|
components.shape = object : IBlockShapeComponent {
|
||||||
|
override fun getShape(state: BlockState): VoxelShape {
|
||||||
|
return BOUNDING_BOX[state[FACING_NOT_DOWN]] ?: BOUNDING_BOX.getValue(UP)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
components.renderType = ENTITYBLOCK_ANIMATED
|
||||||
|
|
||||||
|
components.entity = IBlockEntityComponent(::TileEntityIgneousPlate)
|
||||||
|
|
||||||
|
components.placement = object : IBlockPlacementComponent {
|
||||||
|
override fun isPositionValid(state: BlockState, world: IWorldReader, pos: BlockPos): Boolean {
|
||||||
|
return FACING_NOT_DOWN.allowedValues.any { canPlacePlateAt(world, pos, it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
return SUCCESS
|
override fun getPlacedState(defaultState: BlockState, world: World, pos: BlockPos, context: BlockItemUseContext): BlockState {
|
||||||
|
return if (canPlacePlateAt(world, pos, context.face))
|
||||||
|
defaultState.with(FACING_NOT_DOWN, context.face)
|
||||||
|
else
|
||||||
|
FACING_NOT_DOWN.allowedValues.firstOrNull { canPlacePlateAt(world, pos, it) }?.let { defaultState.with(FACING_NOT_DOWN, it) } ?: defaultState
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return PASS
|
components.onAdded = IBlockAddedComponent { state, world, pos ->
|
||||||
|
pos.offset(state[FACING_NOT_DOWN].opposite).getTile<FurnaceTileEntity>(world)?.let(EntityTechnicalIgneousPlateLogic.Companion::createForFurnace)
|
||||||
|
}
|
||||||
|
|
||||||
|
components.setStateFromNeighbor = ISetBlockStateFromNeighbor { state, world, pos, _, _ ->
|
||||||
|
if (!canPlacePlateAt(world, pos, state[FACING_NOT_DOWN]))
|
||||||
|
Blocks.AIR.defaultState
|
||||||
|
else
|
||||||
|
state
|
||||||
|
}
|
||||||
|
|
||||||
|
components.playerUse = object : IPlayerUseBlockComponent {
|
||||||
|
override fun use(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, hand: Hand): ActionResultType {
|
||||||
|
val heldItem = player.getHeldItem(hand)
|
||||||
|
if (heldItem.item !== Items.WATER_BUCKET) {
|
||||||
|
return PASS
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!world.isRemote && tryCoolPlate(world, pos, state) && !player.abilities.isCreativeMode) {
|
||||||
|
player.setHeldItem(hand, ItemStack(Items.BUCKET))
|
||||||
|
}
|
||||||
|
|
||||||
|
return SUCCESS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interfaces[IBlockDynamicHardness::class.java] = object : IBlockDynamicHardness {
|
||||||
|
override fun getBlockHardness(world: IBlockReader, pos: BlockPos, state: BlockState, originalHardness: Float): Float {
|
||||||
|
val tile = pos.getTile<TileEntityIgneousPlate>(world) ?: return 0F
|
||||||
|
|
||||||
|
return when {
|
||||||
|
tile.isOverheating -> 10F
|
||||||
|
tile.isWorking -> 4F
|
||||||
|
else -> 0F
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun tryCoolPlate(world: World, pos: BlockPos, state: BlockState): Boolean {
|
fun tryCoolPlate(world: World, pos: BlockPos, state: BlockState): Boolean {
|
||||||
return pos.offset(state[FACING_NOT_DOWN].opposite).getTile<FurnaceTileEntity>(world)?.let(EntityTechnicalIgneousPlateLogic.Companion::triggerCooling) == true
|
return pos.offset(state[FACING_NOT_DOWN].opposite).getTile<FurnaceTileEntity>(world)?.let(EntityTechnicalIgneousPlateLogic.Companion::triggerCooling) == true
|
||||||
}
|
}
|
||||||
|
|
||||||
// State handling
|
private fun canPlacePlateAt(world: IWorldReader, pos: BlockPos, facing: Direction): Boolean {
|
||||||
|
val furnacePos = pos.offset(facing.opposite)
|
||||||
override fun rotate(state: BlockState, rot: Rotation): BlockState {
|
val state = furnacePos.getState(world)
|
||||||
return state.with(FACING_NOT_DOWN, rot.rotate(state[FACING_NOT_DOWN]))
|
|
||||||
|
return (
|
||||||
|
state.properties.contains(FURNACE_FACING) &&
|
||||||
|
state[FURNACE_FACING] != facing &&
|
||||||
|
furnacePos.getTile<FurnaceTileEntity>(world) != null
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun mirror(state: BlockState, mirror: Mirror): BlockState {
|
|
||||||
return state.with(FACING_NOT_DOWN, mirror.mirror(state[FACING_NOT_DOWN]))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rendering
|
|
||||||
|
|
||||||
override fun getShape(state: BlockState, world: IBlockReader, pos: BlockPos, context: ISelectionContext): VoxelShape {
|
|
||||||
return BOUNDING_BOX[state[FACING_NOT_DOWN]] ?: BOUNDING_BOX.getValue(UP)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getRenderType(state: BlockState) = ENTITYBLOCK_ANIMATED
|
|
||||||
}
|
}
|
||||||
|
@@ -1,14 +1,24 @@
|
|||||||
package chylex.hee.game.block
|
package chylex.hee.game.block
|
||||||
|
|
||||||
import chylex.hee.client.text.LocalizationStrategy
|
import chylex.hee.client.text.LocalizationStrategy
|
||||||
|
import chylex.hee.game.block.builder.HeeBlockBuilder
|
||||||
|
import chylex.hee.game.block.components.IBlockDropsComponent
|
||||||
|
import chylex.hee.game.block.components.IBlockEntityComponent
|
||||||
|
import chylex.hee.game.block.components.IBlockExplodedComponent
|
||||||
|
import chylex.hee.game.block.components.IBlockPlacementComponent
|
||||||
|
import chylex.hee.game.block.components.IBlockShapeComponent
|
||||||
|
import chylex.hee.game.block.components.IPlayerUseBlockComponent
|
||||||
|
import chylex.hee.game.block.components.ISetBlockStateFromNeighbor
|
||||||
import chylex.hee.game.block.entity.TileEntityJarODust
|
import chylex.hee.game.block.entity.TileEntityJarODust
|
||||||
import chylex.hee.game.block.properties.BlockBuilder
|
|
||||||
import chylex.hee.game.block.properties.BlockDrop
|
import chylex.hee.game.block.properties.BlockDrop
|
||||||
|
import chylex.hee.game.block.properties.BlockHardness
|
||||||
import chylex.hee.game.block.properties.BlockModel
|
import chylex.hee.game.block.properties.BlockModel
|
||||||
import chylex.hee.game.block.properties.BlockRenderLayer.TRANSLUCENT
|
import chylex.hee.game.block.properties.BlockRenderLayer.TRANSLUCENT
|
||||||
import chylex.hee.game.block.properties.BlockStateModel
|
import chylex.hee.game.block.properties.BlockStateModel
|
||||||
import chylex.hee.game.block.properties.BlockStatePreset
|
import chylex.hee.game.block.properties.BlockStatePreset
|
||||||
|
import chylex.hee.game.block.properties.Materials
|
||||||
import chylex.hee.game.fx.util.playServer
|
import chylex.hee.game.fx.util.playServer
|
||||||
|
import chylex.hee.game.item.components.ITooltipComponent
|
||||||
import chylex.hee.game.item.util.size
|
import chylex.hee.game.item.util.size
|
||||||
import chylex.hee.game.mechanics.dust.DustLayers
|
import chylex.hee.game.mechanics.dust.DustLayers
|
||||||
import chylex.hee.game.mechanics.dust.DustLayers.Side.BOTTOM
|
import chylex.hee.game.mechanics.dust.DustLayers.Side.BOTTOM
|
||||||
@@ -16,164 +26,165 @@ import chylex.hee.game.mechanics.dust.DustLayers.Side.TOP
|
|||||||
import chylex.hee.game.mechanics.dust.DustType
|
import chylex.hee.game.mechanics.dust.DustType
|
||||||
import chylex.hee.game.world.util.getTile
|
import chylex.hee.game.world.util.getTile
|
||||||
import chylex.hee.game.world.util.isTopSolid
|
import chylex.hee.game.world.util.isTopSolid
|
||||||
|
import chylex.hee.init.ModBlocks
|
||||||
import chylex.hee.init.ModSounds
|
import chylex.hee.init.ModSounds
|
||||||
import chylex.hee.system.heeTag
|
import chylex.hee.system.heeTag
|
||||||
import chylex.hee.system.heeTagOrNull
|
import chylex.hee.system.heeTagOrNull
|
||||||
import chylex.hee.util.forge.Side
|
|
||||||
import chylex.hee.util.forge.Sided
|
|
||||||
import chylex.hee.util.math.center
|
import chylex.hee.util.math.center
|
||||||
import chylex.hee.util.nbt.getListOfCompounds
|
import chylex.hee.util.nbt.getListOfCompounds
|
||||||
import chylex.hee.util.nbt.putList
|
import chylex.hee.util.nbt.putList
|
||||||
|
import net.minecraft.block.Block
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.block.Blocks
|
import net.minecraft.block.Blocks
|
||||||
import net.minecraft.client.util.ITooltipFlag
|
import net.minecraft.block.SoundType
|
||||||
|
import net.minecraft.block.material.MaterialColor
|
||||||
import net.minecraft.entity.LivingEntity
|
import net.minecraft.entity.LivingEntity
|
||||||
import net.minecraft.entity.player.PlayerEntity
|
import net.minecraft.entity.player.PlayerEntity
|
||||||
import net.minecraft.item.ItemStack
|
import net.minecraft.item.ItemStack
|
||||||
import net.minecraft.loot.LootContext
|
import net.minecraft.loot.LootContext.Builder
|
||||||
import net.minecraft.loot.LootParameters
|
import net.minecraft.loot.LootParameters
|
||||||
import net.minecraft.tileentity.TileEntity
|
|
||||||
import net.minecraft.util.ActionResultType
|
|
||||||
import net.minecraft.util.ActionResultType.PASS
|
import net.minecraft.util.ActionResultType.PASS
|
||||||
import net.minecraft.util.ActionResultType.SUCCESS
|
import net.minecraft.util.ActionResultType.SUCCESS
|
||||||
import net.minecraft.util.Direction
|
|
||||||
import net.minecraft.util.Direction.DOWN
|
import net.minecraft.util.Direction.DOWN
|
||||||
import net.minecraft.util.Hand
|
import net.minecraft.util.Hand
|
||||||
import net.minecraft.util.SoundCategory
|
import net.minecraft.util.SoundCategory
|
||||||
import net.minecraft.util.math.AxisAlignedBB
|
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.util.math.BlockRayTraceResult
|
import net.minecraft.util.math.shapes.VoxelShapes
|
||||||
import net.minecraft.util.math.RayTraceResult
|
|
||||||
import net.minecraft.util.text.ITextComponent
|
import net.minecraft.util.text.ITextComponent
|
||||||
import net.minecraft.util.text.TranslationTextComponent
|
import net.minecraft.util.text.TranslationTextComponent
|
||||||
import net.minecraft.world.Explosion
|
import net.minecraft.world.Explosion
|
||||||
import net.minecraft.world.IBlockReader
|
import net.minecraft.world.IBlockReader
|
||||||
import net.minecraft.world.IWorld
|
|
||||||
import net.minecraft.world.IWorldReader
|
import net.minecraft.world.IWorldReader
|
||||||
import net.minecraft.world.World
|
import net.minecraft.world.World
|
||||||
|
|
||||||
class BlockJarODust(builder: BlockBuilder) : BlockSimpleShaped(builder, AABB) {
|
object BlockJarODust : HeeBlockBuilder() {
|
||||||
companion object {
|
init {
|
||||||
val AABB = AxisAlignedBB(0.1875, 0.0, 0.1875, 0.8125, 0.84375, 0.8125)
|
localization = LocalizationStrategy.ReplaceWords("O", "o'")
|
||||||
|
localizationExtra["block.hee.jar_o_dust.tooltip.entry"] = "§7%sx %s"
|
||||||
|
|
||||||
|
model = BlockStateModel(BlockStatePreset.Simple, BlockModel.Manual)
|
||||||
|
renderLayer = TRANSLUCENT
|
||||||
|
|
||||||
|
material = Materials.JAR_O_DUST
|
||||||
|
color = MaterialColor.ORANGE_TERRACOTTA
|
||||||
|
sound = SoundType.METAL
|
||||||
|
|
||||||
|
drop = BlockDrop.Manual
|
||||||
|
hardness = BlockHardness(hardness = 0.4F, resistance = 0F)
|
||||||
|
|
||||||
|
components.tooltip = object : ITooltipComponent {
|
||||||
|
override fun add(lines: MutableList<ITextComponent>, stack: ItemStack, advanced: Boolean, world: IBlockReader?) {
|
||||||
|
val contents = getLayersFromStack(stack)?.contents ?: return
|
||||||
|
val entries = contents
|
||||||
|
.groupingBy { it.first }
|
||||||
|
.fold(0) { acc, entry -> acc + entry.second }
|
||||||
|
.entries
|
||||||
|
.sortedWith(compareBy({ -it.value }, { it.key.key }))
|
||||||
|
|
||||||
|
for ((dustType, dustAmount) in entries) {
|
||||||
|
lines.add(TranslationTextComponent("block.hee.jar_o_dust.tooltip.entry", dustAmount, TranslationTextComponent(dustType.item.translationKey)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
components.shape = IBlockShapeComponent.of(VoxelShapes.create(0.1875, 0.0, 0.1875, 0.8125, 0.84375, 0.8125))
|
||||||
|
|
||||||
|
components.drops = object : IBlockDropsComponent {
|
||||||
|
override fun getDrops(state: BlockState, context: Builder): MutableList<ItemStack> {
|
||||||
|
val drop = (context.get(LootParameters.BLOCK_ENTITY) as? TileEntityJarODust)?.let(::getDrop)
|
||||||
|
|
||||||
|
return if (drop == null)
|
||||||
|
mutableListOf()
|
||||||
|
else
|
||||||
|
mutableListOf(drop)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getPickBlock(state: BlockState, world: IBlockReader, pos: BlockPos): ItemStack? {
|
||||||
|
return pos.getTile<TileEntityJarODust>(world)?.let(::getDrop)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
components.entity = IBlockEntityComponent(::TileEntityJarODust)
|
||||||
|
|
||||||
|
components.placement = object : IBlockPlacementComponent {
|
||||||
|
override fun isPositionValid(state: BlockState, world: IWorldReader, pos: BlockPos): Boolean {
|
||||||
|
return pos.down().isTopSolid(world)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPlacedBy(state: BlockState, world: World, pos: BlockPos, placer: LivingEntity?, stack: ItemStack) {
|
||||||
|
val list = stack.heeTagOrNull?.getListOfCompounds(TileEntityJarODust.LAYERS_TAG)
|
||||||
|
if (list != null) {
|
||||||
|
pos.getTile<TileEntityJarODust>(world)?.layers?.deserializeNBT(list)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
components.setStateFromNeighbor = ISetBlockStateFromNeighbor { state, world, pos, neighborFacing, _ ->
|
||||||
|
if (neighborFacing == DOWN && !state.isValidPosition(world, pos))
|
||||||
|
Blocks.AIR.defaultState
|
||||||
|
else
|
||||||
|
state
|
||||||
|
}
|
||||||
|
|
||||||
|
components.playerUse = IPlayerUseBlockComponent { _, world, pos, player, hand ->
|
||||||
|
val heldItem = player.getHeldItem(hand)
|
||||||
|
|
||||||
|
val result = if (heldItem.isEmpty)
|
||||||
|
tryExtractDust(world, pos, player, hand)
|
||||||
|
else
|
||||||
|
tryInsertDust(world, pos, player, heldItem)
|
||||||
|
|
||||||
|
if (result) SUCCESS else PASS
|
||||||
|
}
|
||||||
|
|
||||||
|
components.onExploded = object : IBlockExplodedComponent {
|
||||||
|
override fun canDrop(explosion: Explosion): Boolean {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onExploded(state: BlockState, world: World, pos: BlockPos, explosion: Explosion) {
|
||||||
|
pos.getTile<TileEntityJarODust>(world)?.let {
|
||||||
|
val layers = it.layers
|
||||||
|
|
||||||
|
repeat(layers.contents.size) {
|
||||||
|
Block.spawnAsEntity(world, pos, layers.removeDust(BOTTOM))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ModSounds.BLOCK_JAR_O_DUST_SHATTER.playServer(world, pos.center, SoundCategory.BLOCKS)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val localization
|
// ItemStack
|
||||||
get() = LocalizationStrategy.ReplaceWords("O", "o'")
|
|
||||||
|
|
||||||
override val localizationExtra
|
|
||||||
get() = mapOf("block.hee.jar_o_dust.tooltip.entry" to "§7%sx %s")
|
|
||||||
|
|
||||||
override val model
|
|
||||||
get() = BlockStateModel(BlockStatePreset.Simple, BlockModel.Manual)
|
|
||||||
|
|
||||||
override val renderLayer
|
|
||||||
get() = TRANSLUCENT
|
|
||||||
|
|
||||||
override val drop
|
|
||||||
get() = BlockDrop.Manual
|
|
||||||
|
|
||||||
override fun hasTileEntity(state: BlockState): Boolean {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun createTileEntity(state: BlockState, world: IBlockReader): TileEntity {
|
|
||||||
return TileEntityJarODust()
|
|
||||||
}
|
|
||||||
|
|
||||||
// ItemStack serialization
|
|
||||||
|
|
||||||
fun getLayersFromStack(stack: ItemStack): DustLayers? {
|
fun getLayersFromStack(stack: ItemStack): DustLayers? {
|
||||||
return if (stack.item === this.asItem())
|
return if (stack.item === ModBlocks.JAR_O_DUST.asItem())
|
||||||
stack.heeTagOrNull?.getListOfCompounds(TileEntityJarODust.LAYERS_TAG)?.let { list -> DustLayers(TileEntityJarODust.DUST_CAPACITY).apply { deserializeNBT(list) } }
|
stack.heeTagOrNull?.getListOfCompounds(TileEntityJarODust.LAYERS_TAG)?.let { list -> DustLayers(TileEntityJarODust.DUST_CAPACITY).apply { deserializeNBT(list) } }
|
||||||
else
|
else
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setLayersInStack(stack: ItemStack, layers: DustLayers) {
|
fun setLayersInStack(stack: ItemStack, layers: DustLayers) {
|
||||||
if (stack.item === this.asItem()) {
|
if (stack.item === ModBlocks.JAR_O_DUST.asItem()) {
|
||||||
stack.heeTag.putList(TileEntityJarODust.LAYERS_TAG, layers.serializeNBT())
|
stack.heeTag.putList(TileEntityJarODust.LAYERS_TAG, layers.serializeNBT())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Placement
|
|
||||||
|
|
||||||
override fun isValidPosition(state: BlockState, world: IWorldReader, pos: BlockPos): Boolean {
|
|
||||||
@Suppress("DEPRECATION")
|
|
||||||
return super.isValidPosition(state, world, pos) && pos.down().isTopSolid(world)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun updatePostPlacement(state: BlockState, facing: Direction, neighborState: BlockState, world: IWorld, pos: BlockPos, neighborPos: BlockPos): BlockState {
|
|
||||||
@Suppress("DEPRECATION")
|
|
||||||
return if (facing == DOWN && !isValidPosition(state, world, pos))
|
|
||||||
Blocks.AIR.defaultState
|
|
||||||
else
|
|
||||||
super.updatePostPlacement(state, facing, neighborState, world, pos, neighborPos)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onBlockPlacedBy(world: World, pos: BlockPos, state: BlockState, placer: LivingEntity?, stack: ItemStack) {
|
|
||||||
val list = stack.heeTagOrNull?.getListOfCompounds(TileEntityJarODust.LAYERS_TAG)
|
|
||||||
|
|
||||||
if (list != null) {
|
|
||||||
pos.getTile<TileEntityJarODust>(world)?.layers?.deserializeNBT(list)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Drops
|
// Drops
|
||||||
|
|
||||||
private fun getDrop(tile: TileEntityJarODust): ItemStack {
|
private fun getDrop(tile: TileEntityJarODust): ItemStack {
|
||||||
return ItemStack(this).also { setLayersInStack(it, tile.layers) }
|
return ItemStack(ModBlocks.JAR_O_DUST).also { setLayersInStack(it, tile.layers) }
|
||||||
}
|
|
||||||
|
|
||||||
override fun getDrops(state: BlockState, context: LootContext.Builder): MutableList<ItemStack> {
|
|
||||||
val drop = (context.get(LootParameters.BLOCK_ENTITY) as? TileEntityJarODust)?.let(::getDrop)
|
|
||||||
|
|
||||||
return if (drop != null)
|
|
||||||
mutableListOf(drop)
|
|
||||||
else
|
|
||||||
mutableListOf()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getPickBlock(state: BlockState, target: RayTraceResult, world: IBlockReader, pos: BlockPos, player: PlayerEntity): ItemStack {
|
|
||||||
return pos.getTile<TileEntityJarODust>(world)?.let(::getDrop) ?: ItemStack(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun canDropFromExplosion(explosion: Explosion): Boolean {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onBlockExploded(state: BlockState, world: World, pos: BlockPos, explosion: Explosion) {
|
|
||||||
pos.getTile<TileEntityJarODust>(world)?.let {
|
|
||||||
val layers = it.layers
|
|
||||||
|
|
||||||
repeat(layers.contents.size) {
|
|
||||||
spawnAsEntity(world, pos, layers.removeDust(BOTTOM))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ModSounds.BLOCK_JAR_O_DUST_SHATTER.playServer(world, pos.center, SoundCategory.BLOCKS)
|
|
||||||
super.onBlockExploded(state, world, pos, explosion)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interaction
|
// Interaction
|
||||||
|
|
||||||
override fun onBlockActivated(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, hit: BlockRayTraceResult): ActionResultType {
|
|
||||||
val heldItem = player.getHeldItem(hand)
|
|
||||||
|
|
||||||
val result = if (heldItem.isEmpty)
|
|
||||||
tryExtractDust(world, pos, player, hand)
|
|
||||||
else
|
|
||||||
tryInsertDust(world, pos, player, heldItem)
|
|
||||||
|
|
||||||
return if (result) SUCCESS else PASS
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun tryExtractDust(world: World, pos: BlockPos, player: PlayerEntity, hand: Hand): Boolean {
|
private fun tryExtractDust(world: World, pos: BlockPos, player: PlayerEntity, hand: Hand): Boolean {
|
||||||
if (world.isRemote) {
|
if (world.isRemote) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
val removed = pos.getTile<TileEntityJarODust>(world)?.layers?.removeDust(if (player.isSneaking) BOTTOM else TOP)
|
val removed = pos.getTile<TileEntityJarODust>(world)?.layers?.removeDust(if (player.isSneaking) BOTTOM else TOP)
|
||||||
|
|
||||||
if (removed != null) {
|
if (removed != null) {
|
||||||
player.setHeldItem(hand, removed)
|
player.setHeldItem(hand, removed)
|
||||||
}
|
}
|
||||||
@@ -197,23 +208,4 @@ class BlockJarODust(builder: BlockBuilder) : BlockSimpleShaped(builder, AABB) {
|
|||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Client side
|
|
||||||
|
|
||||||
@Sided(Side.CLIENT)
|
|
||||||
override fun addInformation(stack: ItemStack, world: IBlockReader?, lines: MutableList<ITextComponent>, flags: ITooltipFlag) {
|
|
||||||
val contents = getLayersFromStack(stack)?.contents
|
|
||||||
|
|
||||||
if (contents != null) {
|
|
||||||
val entries = contents
|
|
||||||
.groupingBy { it.first }
|
|
||||||
.fold(0) { acc, entry -> acc + entry.second }
|
|
||||||
.entries
|
|
||||||
.sortedWith(compareBy({ -it.value }, { it.key.key }))
|
|
||||||
|
|
||||||
for ((dustType, dustAmount) in entries) {
|
|
||||||
lines.add(TranslationTextComponent("block.hee.jar_o_dust.tooltip.entry", dustAmount, TranslationTextComponent(dustType.item.translationKey)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -1,26 +1,18 @@
|
|||||||
package chylex.hee.game.block
|
package chylex.hee.game.block
|
||||||
|
|
||||||
import chylex.hee.client.text.LocalizationStrategy
|
import chylex.hee.client.text.LocalizationStrategy
|
||||||
|
import chylex.hee.game.block.builder.HeeBlockBuilder
|
||||||
|
import chylex.hee.game.block.components.IBlockEntityComponent
|
||||||
import chylex.hee.game.block.entity.TileEntityMinersBurialAltar
|
import chylex.hee.game.block.entity.TileEntityMinersBurialAltar
|
||||||
import chylex.hee.game.block.properties.BlockBuilder
|
|
||||||
import chylex.hee.game.block.properties.BlockModel
|
import chylex.hee.game.block.properties.BlockModel
|
||||||
import net.minecraft.block.BlockState
|
|
||||||
import net.minecraft.tileentity.TileEntity
|
|
||||||
import net.minecraft.util.math.AxisAlignedBB
|
|
||||||
import net.minecraft.world.IBlockReader
|
|
||||||
|
|
||||||
class BlockMinersBurialAltar(builder: BlockBuilder) : BlockSimpleShaped(builder, AxisAlignedBB(0.0, 0.0, 0.0, 1.0, 0.75, 1.0)) {
|
object BlockMinersBurialAltar : HeeBlockBuilder() {
|
||||||
override val localization
|
init {
|
||||||
get() = LocalizationStrategy.ReplaceWords("Miners", "Miner's")
|
includeFrom(BlockMinersBurialCube.INDESCRUCTIBLE)
|
||||||
|
|
||||||
override val model
|
localization = LocalizationStrategy.ReplaceWords("Miners", "Miner's")
|
||||||
get() = BlockModel.Manual
|
model = BlockModel.Manual
|
||||||
|
|
||||||
override fun hasTileEntity(state: BlockState): Boolean {
|
components.entity = IBlockEntityComponent(::TileEntityMinersBurialAltar)
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun createTileEntity(state: BlockState, world: IBlockReader): TileEntity {
|
|
||||||
return TileEntityMinersBurialAltar()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,29 @@
|
|||||||
package chylex.hee.game.block
|
package chylex.hee.game.block
|
||||||
|
|
||||||
import chylex.hee.client.text.LocalizationStrategy
|
import chylex.hee.client.text.LocalizationStrategy
|
||||||
import chylex.hee.game.block.properties.BlockBuilder
|
import chylex.hee.game.block.builder.HeeBlockBuilder
|
||||||
|
import chylex.hee.game.block.properties.BlockHardness
|
||||||
|
import chylex.hee.game.block.properties.BlockHarvestTool
|
||||||
|
import chylex.hee.game.block.properties.Materials
|
||||||
|
import chylex.hee.game.item.util.Tool.Level
|
||||||
|
import net.minecraft.block.SoundType
|
||||||
|
import net.minecraft.block.material.MaterialColor
|
||||||
|
import net.minecraftforge.common.ToolType
|
||||||
|
|
||||||
class BlockMinersBurialCube(builder: BlockBuilder) : HeeBlock(builder) {
|
object BlockMinersBurialCube : HeeBlockBuilder() {
|
||||||
override val localization
|
init {
|
||||||
get() = LocalizationStrategy.Parenthesized(LocalizationStrategy.DeleteWords(LocalizationStrategy.ReplaceWords("Miners", "Miner's"), "Plain"), wordCount = 1, wordOffset = 3, fromStart = true)
|
localization = LocalizationStrategy.Parenthesized(LocalizationStrategy.DeleteWords(LocalizationStrategy.ReplaceWords("Miners", "Miner's"), "Plain"), wordCount = 1, wordOffset = 3, fromStart = true)
|
||||||
|
|
||||||
|
material = Materials.SOLID
|
||||||
|
color = MaterialColor.RED
|
||||||
|
sound = SoundType.STONE
|
||||||
|
|
||||||
|
tool = BlockHarvestTool.required(Level.WOOD, ToolType.PICKAXE)
|
||||||
|
hardness = BlockHardness(hardness = 0.6F, resistance = 120F)
|
||||||
|
}
|
||||||
|
|
||||||
|
val INDESCRUCTIBLE = HeeBlockBuilder {
|
||||||
|
includeFrom(BlockIndestructible)
|
||||||
|
includeFrom(BlockMinersBurialCube)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,28 +1,50 @@
|
|||||||
package chylex.hee.game.block
|
package chylex.hee.game.block
|
||||||
|
|
||||||
import chylex.hee.client.text.LocalizationStrategy
|
import chylex.hee.client.text.LocalizationStrategy
|
||||||
import chylex.hee.game.block.properties.BlockBuilder
|
import chylex.hee.game.block.builder.HeeBlockBuilder
|
||||||
|
import chylex.hee.game.block.properties.BlockHardness
|
||||||
|
import chylex.hee.game.block.properties.BlockHarvestTool
|
||||||
import chylex.hee.game.block.properties.BlockStateModels
|
import chylex.hee.game.block.properties.BlockStateModels
|
||||||
|
import chylex.hee.game.block.properties.Materials
|
||||||
|
import chylex.hee.game.item.util.Tool.Level.DIAMOND
|
||||||
import net.minecraft.block.Block
|
import net.minecraft.block.Block
|
||||||
|
import net.minecraft.block.SoundType
|
||||||
|
import net.minecraft.block.material.MaterialColor
|
||||||
import net.minecraftforge.common.Tags
|
import net.minecraftforge.common.Tags
|
||||||
|
import net.minecraftforge.common.ToolType.PICKAXE
|
||||||
|
|
||||||
open class BlockObsidianCube(builder: BlockBuilder) : HeeBlock(builder) {
|
object BlockObsidianCube : HeeBlockBuilder() {
|
||||||
override val localization: LocalizationStrategy
|
private val DEFAULT_LOCALIZATION = LocalizationStrategy.MoveToBeginning(wordCount = 1, wordOffset = 1, fromStart = true)
|
||||||
get() = LocalizationStrategy.MoveToBeginning(wordCount = 1, wordOffset = 1, fromStart = true)
|
|
||||||
|
|
||||||
final override val tags
|
init {
|
||||||
get() = listOf(Tags.Blocks.OBSIDIAN)
|
localization = DEFAULT_LOCALIZATION
|
||||||
|
|
||||||
open class Lit(builder: BlockBuilder, private val modelBlock: Block) : BlockObsidianCube(builder) {
|
|
||||||
override val localization: LocalizationStrategy
|
|
||||||
get() = LocalizationStrategy.Parenthesized(super.localization, wordCount = 1, fromStart = false)
|
|
||||||
|
|
||||||
override val model
|
tags.add(Tags.Blocks.OBSIDIAN)
|
||||||
get() = BlockStateModels.Cube(modelBlock)
|
|
||||||
|
material = Materials.SOLID
|
||||||
|
color = MaterialColor.BLACK
|
||||||
|
sound = SoundType.STONE
|
||||||
|
tool = BlockHarvestTool.required(DIAMOND, PICKAXE)
|
||||||
|
hardness = BlockHardness(hardness = 20F, resistance = 300F)
|
||||||
}
|
}
|
||||||
|
|
||||||
class TowerTop(builder: BlockBuilder, modelBlock: Block) : Lit(builder, modelBlock) {
|
class Lit(modelBlock: Block) : HeeBlockBuilder() {
|
||||||
override val localization
|
init {
|
||||||
get() = LocalizationStrategy.Default
|
includeFrom(BlockObsidianCube)
|
||||||
|
|
||||||
|
localization = LocalizationStrategy.Parenthesized(DEFAULT_LOCALIZATION, wordCount = 1, fromStart = false)
|
||||||
|
model = BlockStateModels.Cube(modelBlock)
|
||||||
|
|
||||||
|
light = 15
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TowerTop(modelBlock: Block) : HeeBlockBuilder() {
|
||||||
|
init {
|
||||||
|
includeFrom(BlockIndestructible)
|
||||||
|
includeFrom(Lit(modelBlock))
|
||||||
|
|
||||||
|
localization = LocalizationStrategy.Default
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,10 +0,0 @@
|
|||||||
package chylex.hee.game.block
|
|
||||||
|
|
||||||
import chylex.hee.game.block.properties.BlockBuilder
|
|
||||||
import chylex.hee.game.block.properties.BlockModel
|
|
||||||
import net.minecraft.util.math.AxisAlignedBB
|
|
||||||
|
|
||||||
open class BlockPortalFrame(builder: BlockBuilder) : BlockSimpleShaped(builder, AxisAlignedBB(0.0, 0.0, 0.0, 1.0, 0.8125, 1.0)) {
|
|
||||||
override val model
|
|
||||||
get() = BlockModel.PortalFrame(this, "plain")
|
|
||||||
}
|
|
@@ -3,16 +3,20 @@ package chylex.hee.game.block
|
|||||||
import chylex.hee.client.text.LocalizationStrategy
|
import chylex.hee.client.text.LocalizationStrategy
|
||||||
import chylex.hee.client.util.MC
|
import chylex.hee.client.util.MC
|
||||||
import chylex.hee.game.Resource
|
import chylex.hee.game.Resource
|
||||||
|
import chylex.hee.game.block.BlockPuzzleLogic.IPuzzleLogic
|
||||||
import chylex.hee.game.block.BlockPuzzleLogic.State.ACTIVE
|
import chylex.hee.game.block.BlockPuzzleLogic.State.ACTIVE
|
||||||
import chylex.hee.game.block.BlockPuzzleLogic.State.DISABLED
|
import chylex.hee.game.block.BlockPuzzleLogic.State.DISABLED
|
||||||
import chylex.hee.game.block.BlockPuzzleLogic.State.INACTIVE
|
import chylex.hee.game.block.BlockPuzzleLogic.State.INACTIVE
|
||||||
import chylex.hee.game.block.properties.BlockBuilder
|
import chylex.hee.game.block.builder.HeeBlockBuilder
|
||||||
|
import chylex.hee.game.block.components.IBlockPlacementComponent
|
||||||
|
import chylex.hee.game.block.interfaces.IBlockInterface
|
||||||
|
import chylex.hee.game.block.interfaces.getHeeInterface
|
||||||
import chylex.hee.game.block.properties.BlockModel
|
import chylex.hee.game.block.properties.BlockModel
|
||||||
import chylex.hee.game.block.properties.BlockRenderLayer.CUTOUT
|
import chylex.hee.game.block.properties.BlockRenderLayer.CUTOUT
|
||||||
import chylex.hee.game.block.properties.BlockStateModel
|
import chylex.hee.game.block.properties.BlockStateModel
|
||||||
import chylex.hee.game.block.properties.BlockStatePreset
|
import chylex.hee.game.block.properties.BlockStatePreset
|
||||||
import chylex.hee.game.block.properties.BlockTint
|
import chylex.hee.game.block.properties.BlockTint
|
||||||
import chylex.hee.game.block.properties.IBlockStateModel
|
import chylex.hee.game.block.properties.Materials
|
||||||
import chylex.hee.game.block.util.Property
|
import chylex.hee.game.block.util.Property
|
||||||
import chylex.hee.game.block.util.withFacing
|
import chylex.hee.game.block.util.withFacing
|
||||||
import chylex.hee.game.entity.util.posVec
|
import chylex.hee.game.entity.util.posVec
|
||||||
@@ -46,9 +50,10 @@ import chylex.hee.util.random.nextFloat
|
|||||||
import net.minecraft.block.Block
|
import net.minecraft.block.Block
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.block.HorizontalBlock.HORIZONTAL_FACING
|
import net.minecraft.block.HorizontalBlock.HORIZONTAL_FACING
|
||||||
|
import net.minecraft.block.SoundType
|
||||||
|
import net.minecraft.block.material.MaterialColor
|
||||||
import net.minecraft.entity.Entity
|
import net.minecraft.entity.Entity
|
||||||
import net.minecraft.item.BlockItemUseContext
|
import net.minecraft.item.BlockItemUseContext
|
||||||
import net.minecraft.state.StateContainer.Builder
|
|
||||||
import net.minecraft.util.Direction
|
import net.minecraft.util.Direction
|
||||||
import net.minecraft.util.Direction.NORTH
|
import net.minecraft.util.Direction.NORTH
|
||||||
import net.minecraft.util.Direction.SOUTH
|
import net.minecraft.util.Direction.SOUTH
|
||||||
@@ -60,7 +65,7 @@ import net.minecraft.world.IBlockDisplayReader
|
|||||||
import net.minecraft.world.World
|
import net.minecraft.world.World
|
||||||
import java.util.Random
|
import java.util.Random
|
||||||
|
|
||||||
sealed class BlockPuzzleLogic(builder: BlockBuilder) : HeeBlock(builder) {
|
class BlockPuzzleLogic(impl: IPuzzleLogic) : HeeBlockBuilder() {
|
||||||
companion object {
|
companion object {
|
||||||
val STATE = Property.enum<State>("state")
|
val STATE = Property.enum<State>("state")
|
||||||
|
|
||||||
@@ -101,7 +106,7 @@ sealed class BlockPuzzleLogic(builder: BlockBuilder) : HeeBlock(builder) {
|
|||||||
var closest = pos
|
var closest = pos
|
||||||
var closestDistSq = pos.distanceSqTo(player)
|
var closestDistSq = pos.distanceSqTo(player)
|
||||||
|
|
||||||
for (testPos in pos.floodFill(Facing4) { it.getBlock(world) is BlockPuzzleLogic }) {
|
for (testPos in pos.floodFill(Facing4) { isPuzzleBlock(it.getBlock(world)) }) {
|
||||||
PARTICLE_TOGGLE.spawn(Point(testPos, 3), rand)
|
PARTICLE_TOGGLE.spawn(Point(testPos, 3), rand)
|
||||||
|
|
||||||
val distSq = testPos.distanceSqTo(player)
|
val distSq = testPos.distanceSqTo(player)
|
||||||
@@ -123,8 +128,12 @@ sealed class BlockPuzzleLogic(builder: BlockBuilder) : HeeBlock(builder) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isPuzzleBlockEnabled(state: BlockState): Boolean {
|
fun isPuzzleBlock(block: Block): Boolean {
|
||||||
return state.block is BlockPuzzleLogic && state[STATE] != DISABLED
|
return block.getHeeInterface<IPuzzleLogic>() != null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isPuzzleBlockEnabled(state: BlockState): Boolean {
|
||||||
|
return isPuzzleBlock(state.block) && state[STATE] != DISABLED
|
||||||
}
|
}
|
||||||
|
|
||||||
fun findAllBlocks(world: World, pos: BlockPos): List<BlockPos> {
|
fun findAllBlocks(world: World, pos: BlockPos): List<BlockPos> {
|
||||||
@@ -204,6 +213,66 @@ sealed class BlockPuzzleLogic(builder: BlockBuilder) : HeeBlock(builder) {
|
|||||||
mapOf("top" to Resource.Custom("block/puzzle_overlay_$itemSuffix"))
|
mapOf("top" to Resource.Custom("block/puzzle_overlay_$itemSuffix"))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fun onToggled(world: World, pos: BlockPos, facing: Direction): List<Pair<BlockPos, Direction>> {
|
||||||
|
val state = pos.getState(world)
|
||||||
|
val logic = state.block.getHeeInterface<IPuzzleLogic>()
|
||||||
|
|
||||||
|
return if (logic != null && toggleState(world, pos, state))
|
||||||
|
logic.getNextChains(world, pos, facing)
|
||||||
|
else
|
||||||
|
emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun toggleState(world: World, pos: BlockPos, state: BlockState): Boolean {
|
||||||
|
val type = state[STATE]
|
||||||
|
|
||||||
|
if (type == DISABLED) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
pos.setState(world, state.with(STATE, type.toggled))
|
||||||
|
PacketClientFX(FX_TOGGLE, FxBlockData(pos)).sendToAllAround(world, pos, 24.0)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
includeFrom(BlockIndestructible)
|
||||||
|
|
||||||
|
renderLayer = CUTOUT
|
||||||
|
|
||||||
|
material = Materials.SOLID
|
||||||
|
color = MaterialColor.ADOBE /* RENAME ORANGE */
|
||||||
|
sound = SoundType.STONE
|
||||||
|
|
||||||
|
tint = object : BlockTint() {
|
||||||
|
@Sided(Side.CLIENT)
|
||||||
|
override fun tint(state: BlockState, world: IBlockDisplayReader?, pos: BlockPos?, tintIndex: Int): Int {
|
||||||
|
if (tintIndex != 1) {
|
||||||
|
return NO_TINT
|
||||||
|
}
|
||||||
|
|
||||||
|
if (world == null && pos == null) {
|
||||||
|
return RGB(104, 58, 16).i // make the color slightly more visible in inventory
|
||||||
|
}
|
||||||
|
|
||||||
|
return when (state[STATE]) {
|
||||||
|
ACTIVE -> RGB(117, 66, 19).i
|
||||||
|
INACTIVE -> RGB(212, 157, 102).i
|
||||||
|
DISABLED -> RGB( 58, 40, 23).i
|
||||||
|
else -> NO_TINT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
components.states.set(STATE, ACTIVE)
|
||||||
|
|
||||||
|
interfaces[IPuzzleLogic::class.java] = impl
|
||||||
|
}
|
||||||
|
|
||||||
|
fun interface IPuzzleLogic : IBlockInterface {
|
||||||
|
fun getNextChains(world: World, pos: BlockPos, facing: Direction): List<Pair<BlockPos, Direction>>
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class State(private val serializableName: String) : IStringSerializable {
|
enum class State(private val serializableName: String) : IStringSerializable {
|
||||||
@@ -223,159 +292,101 @@ sealed class BlockPuzzleLogic(builder: BlockBuilder) : HeeBlock(builder) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract override val model: IBlockStateModel
|
object Plain : HeeBlockBuilder() {
|
||||||
|
internal val LOGIC = IPuzzleLogic { _, pos, facing -> listOf(makePair(pos, facing)) }
|
||||||
final override val renderLayer
|
|
||||||
get() = CUTOUT
|
|
||||||
|
|
||||||
init {
|
|
||||||
defaultState = stateContainer.baseState.with(STATE, ACTIVE)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun fillStateContainer(container: Builder<Block, BlockState>) {
|
|
||||||
container.add(STATE)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Logic
|
|
||||||
|
|
||||||
fun onToggled(world: World, pos: BlockPos, facing: Direction): List<Pair<BlockPos, Direction>> {
|
|
||||||
val state = pos.getState(world)
|
|
||||||
|
|
||||||
return if (toggleState(world, pos, state))
|
init {
|
||||||
getNextChains(world, pos, facing)
|
includeFrom(BlockPuzzleLogic(LOGIC))
|
||||||
else
|
|
||||||
emptyList()
|
localization = LocalizationStrategy.Parenthesized(wordCount = 1, fromStart = false)
|
||||||
}
|
model = createPlainModel()
|
||||||
|
|
||||||
protected fun toggleState(world: World, pos: BlockPos, state: BlockState): Boolean {
|
|
||||||
val type = state[STATE]
|
|
||||||
|
|
||||||
if (type == DISABLED) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
pos.setState(world, state.with(STATE, type.toggled))
|
|
||||||
PacketClientFX(FX_TOGGLE, FxBlockData(pos)).sendToAllAround(world, pos, 24.0)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract fun getNextChains(world: World, pos: BlockPos, facing: Direction): List<Pair<BlockPos, Direction>>
|
|
||||||
|
|
||||||
// Variations
|
|
||||||
|
|
||||||
class Plain(builder: BlockBuilder) : BlockPuzzleLogic(builder) {
|
|
||||||
override val localization
|
|
||||||
get() = LocalizationStrategy.Parenthesized(wordCount = 1, fromStart = false)
|
|
||||||
|
|
||||||
override val model
|
|
||||||
get() = createPlainModel()
|
|
||||||
|
|
||||||
override fun getNextChains(world: World, pos: BlockPos, facing: Direction): List<Pair<BlockPos, Direction>> {
|
|
||||||
return listOf(makePair(pos, facing))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Burst(builder: BlockBuilder, private val radius: Int) : BlockPuzzleLogic(builder) {
|
class Burst(radius: Int) : HeeBlockBuilder() {
|
||||||
override val localization
|
private val logic = IPuzzleLogic { world, pos, facing ->
|
||||||
get() = LocalizationStrategy.Parenthesized(LocalizationStrategy.ReplaceWords("$diameter", "${diameter}x${diameter}"), wordCount = 2, fromStart = false)
|
pos.allInCenteredBox(radius, 0, radius).toList().flatMap { toggleAndChain(world, it, facing) }.distinct()
|
||||||
|
}
|
||||||
|
|
||||||
override val model
|
init {
|
||||||
get() = createOverlayModel("burst_$diameter")
|
includeFrom(BlockPuzzleLogic(logic))
|
||||||
|
|
||||||
private val diameter
|
val diameter = 1 + (radius * 2)
|
||||||
get() = 1 + (radius * 2)
|
localization = LocalizationStrategy.Parenthesized(LocalizationStrategy.ReplaceWords("$diameter", "${diameter}x${diameter}"), wordCount = 2, fromStart = false)
|
||||||
|
model = createOverlayModel("burst_$diameter")
|
||||||
|
}
|
||||||
|
|
||||||
private fun toggleAndChain(world: World, pos: BlockPos, facing: Direction): List<Pair<BlockPos, Direction>> {
|
private fun toggleAndChain(world: World, pos: BlockPos, facing: Direction): List<Pair<BlockPos, Direction>> {
|
||||||
val state = pos.getState(world)
|
val state = pos.getState(world)
|
||||||
val block = state.block
|
val logic = state.block.getHeeInterface<IPuzzleLogic>()
|
||||||
|
|
||||||
return if (block !is BlockPuzzleLogic || !toggleState(world, pos, state) || block is Plain || block is Burst)
|
return if (logic == null || !toggleState(world, pos, state) || logic === Plain.LOGIC || logic === this.logic)
|
||||||
emptyList()
|
emptyList()
|
||||||
else
|
else
|
||||||
block.getNextChains(world, pos, facing)
|
logic.getNextChains(world, pos, facing)
|
||||||
}
|
|
||||||
|
|
||||||
override fun getNextChains(world: World, pos: BlockPos, facing: Direction): List<Pair<BlockPos, Direction>> {
|
|
||||||
return pos.allInCenteredBox(radius, 0, radius).toList().flatMap { toggleAndChain(world, it, facing) }.distinct()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class RedirectSome private constructor(builder: BlockBuilder, private val blockDirections: Array<String>, private val itemDirection: String, private val directions: Array<Direction>) : BlockPuzzleLogic(builder) {
|
private class RedirectSome(blockDirections: Array<String>, itemDirection: String, directions: Array<Direction>) : HeeBlockBuilder() {
|
||||||
class R1(builder: BlockBuilder) : RedirectSome(builder, arrayOf("n", "s", "e", "w"), "n", arrayOf(NORTH))
|
private val logic = BlockPuzzleLogic { world, pos, facing ->
|
||||||
class R2(builder: BlockBuilder) : RedirectSome(builder, arrayOf("ns", "ew"), "ns", arrayOf(NORTH, SOUTH))
|
|
||||||
|
|
||||||
override val localization
|
|
||||||
get() = LocalizationStrategy.Parenthesized(wordCount = 2, fromStart = false)
|
|
||||||
|
|
||||||
override val model
|
|
||||||
get() = createOverlayModel("redirect_" + directions.size + itemDirection, blockDirections.map { "redirect_" + directions.size + it })
|
|
||||||
|
|
||||||
init {
|
|
||||||
defaultState = stateContainer.baseState.with(STATE, ACTIVE).withFacing(NORTH)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun fillStateContainer(container: Builder<Block, BlockState>) {
|
|
||||||
container.add(STATE, HORIZONTAL_FACING)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getStateForPlacement(context: BlockItemUseContext): BlockState {
|
|
||||||
return this.withFacing(context.placementHorizontalFacing)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getNextChains(world: World, pos: BlockPos, facing: Direction): List<Pair<BlockPos, Direction>> {
|
|
||||||
val rotation = pos.getState(world)[HORIZONTAL_FACING].horizontalIndex + NORTH.horizontalIndex
|
val rotation = pos.getState(world)[HORIZONTAL_FACING].horizontalIndex + NORTH.horizontalIndex
|
||||||
val exclude = facing.opposite
|
val exclude = facing.opposite
|
||||||
|
|
||||||
return directions.map { Direction.byHorizontalIndex(it.horizontalIndex + rotation) }.filter { it != exclude }.map { makePair(pos, it) }
|
directions.map { Direction.byHorizontalIndex(it.horizontalIndex + rotation) }.filter { it != exclude }.map { makePair(pos, it) }
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
class RedirectAll(builder: BlockBuilder) : BlockPuzzleLogic(builder) {
|
|
||||||
override val localization
|
|
||||||
get() = LocalizationStrategy.Parenthesized(wordCount = 2, fromStart = false)
|
|
||||||
|
|
||||||
override val model
|
init {
|
||||||
get() = createOverlayModel("redirect_4")
|
includeFrom(logic)
|
||||||
|
|
||||||
override fun getNextChains(world: World, pos: BlockPos, facing: Direction): List<Pair<BlockPos, Direction>> {
|
|
||||||
return Facing4.filter { it != facing.opposite }.map { makePair(pos, it) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Teleport(builder: BlockBuilder) : BlockPuzzleLogic(builder) {
|
|
||||||
override val localization
|
|
||||||
get() = LocalizationStrategy.Parenthesized(wordCount = 1, fromStart = false)
|
|
||||||
|
|
||||||
override val model
|
|
||||||
get() = createOverlayModel("teleport")
|
|
||||||
|
|
||||||
override fun getNextChains(world: World, pos: BlockPos, facing: Direction): List<Pair<BlockPos, Direction>> {
|
|
||||||
return findAllBlocks(world, pos).filter { it != pos && it.getBlock(world) is Teleport }.map { makePair(it, facing) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Client side
|
|
||||||
|
|
||||||
override val tint: BlockTint
|
|
||||||
get() = Tint
|
|
||||||
|
|
||||||
private object Tint : BlockTint() {
|
|
||||||
@Sided(Side.CLIENT)
|
|
||||||
override fun tint(state: BlockState, world: IBlockDisplayReader?, pos: BlockPos?, tintIndex: Int): Int {
|
|
||||||
if (tintIndex != 1) {
|
|
||||||
return NO_TINT
|
|
||||||
}
|
|
||||||
|
|
||||||
if (world == null && pos == null) {
|
localization = LocalizationStrategy.Parenthesized(wordCount = 2, fromStart = false)
|
||||||
return RGB(104, 58, 16).i // make the color slightly more visible in inventory
|
model = createOverlayModel("redirect_" + directions.size + itemDirection, blockDirections.map { "redirect_" + directions.size + it })
|
||||||
}
|
|
||||||
|
|
||||||
return when (state[STATE]) {
|
components.states.set(HORIZONTAL_FACING, NORTH)
|
||||||
ACTIVE -> RGB(117, 66, 19).i
|
components.states.facingProperty = HORIZONTAL_FACING
|
||||||
INACTIVE -> RGB(212, 157, 102).i
|
|
||||||
DISABLED -> RGB( 58, 40, 23).i
|
components.placement = object : IBlockPlacementComponent {
|
||||||
else -> NO_TINT
|
override fun getPlacedState(defaultState: BlockState, world: World, pos: BlockPos, context: BlockItemUseContext): BlockState {
|
||||||
|
return defaultState.withFacing(context.placementHorizontalFacing)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object RedirectOne : HeeBlockBuilder() {
|
||||||
|
init {
|
||||||
|
includeFrom(RedirectSome(arrayOf("n", "s", "e", "w"), "n", arrayOf(NORTH)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object RedirectTwo : HeeBlockBuilder() {
|
||||||
|
init {
|
||||||
|
includeFrom(RedirectSome(arrayOf("ns", "ew"), "ns", arrayOf(NORTH, SOUTH)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object RedirectAll : HeeBlockBuilder() {
|
||||||
|
init {
|
||||||
|
includeFrom(BlockPuzzleLogic { _, pos, facing ->
|
||||||
|
Facing4.filter { it != facing.opposite }.map { makePair(pos, it) }
|
||||||
|
})
|
||||||
|
|
||||||
|
localization = LocalizationStrategy.Parenthesized(wordCount = 2, fromStart = false)
|
||||||
|
model = createOverlayModel("redirect_4")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object Teleport : HeeBlockBuilder() {
|
||||||
|
private val logic = object : IPuzzleLogic {
|
||||||
|
override fun getNextChains(world: World, pos: BlockPos, facing: Direction): List<Pair<BlockPos, Direction>> {
|
||||||
|
return findAllBlocks(world, pos).filter { it != pos && it.getBlock(world).getHeeInterface<IPuzzleLogic>() === this }.map { makePair(it, facing) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
includeFrom(BlockPuzzleLogic(logic))
|
||||||
|
|
||||||
|
localization = LocalizationStrategy.Parenthesized(wordCount = 1, fromStart = false)
|
||||||
|
model = createOverlayModel("teleport")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,20 @@
|
|||||||
package chylex.hee.game.block
|
package chylex.hee.game.block
|
||||||
|
|
||||||
import chylex.hee.client.text.LocalizationStrategy
|
import chylex.hee.client.text.LocalizationStrategy
|
||||||
import chylex.hee.game.block.properties.BlockBuilder
|
import chylex.hee.game.block.builder.HeeBlockBuilder
|
||||||
|
import chylex.hee.game.block.properties.Materials
|
||||||
|
import net.minecraft.block.SoundType
|
||||||
|
import net.minecraft.block.material.MaterialColor
|
||||||
|
|
||||||
class BlockPuzzleWall(builder: BlockBuilder) : HeeBlock(builder) {
|
object BlockPuzzleWall : HeeBlockBuilder() {
|
||||||
override val localization
|
init {
|
||||||
get() = LocalizationStrategy.Parenthesized(wordCount = 1, fromStart = false)
|
includeFrom(BlockIndestructible)
|
||||||
|
|
||||||
|
localization = LocalizationStrategy.Parenthesized(wordCount = 1, fromStart = false)
|
||||||
|
|
||||||
|
material = Materials.SOLID
|
||||||
|
color = MaterialColor.ADOBE // RENAME ORANGE
|
||||||
|
sound = SoundType.STONE
|
||||||
|
light = 14
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,62 +2,55 @@ package chylex.hee.game.block
|
|||||||
|
|
||||||
import chylex.hee.HEE
|
import chylex.hee.HEE
|
||||||
import chylex.hee.game.Environment
|
import chylex.hee.game.Environment
|
||||||
import chylex.hee.game.block.properties.BlockBuilder
|
import chylex.hee.game.block.builder.HeeBlockBuilder
|
||||||
|
import chylex.hee.game.block.components.IBlockShapeComponent
|
||||||
import chylex.hee.game.block.properties.BlockModel
|
import chylex.hee.game.block.properties.BlockModel
|
||||||
import chylex.hee.game.block.properties.BlockRenderLayer.CUTOUT
|
import chylex.hee.game.block.properties.BlockRenderLayer.CUTOUT
|
||||||
import chylex.hee.util.forge.Side
|
import chylex.hee.game.block.properties.Materials
|
||||||
import chylex.hee.util.forge.Sided
|
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.block.SoundType
|
||||||
import net.minecraft.util.math.shapes.ISelectionContext
|
import net.minecraft.block.material.MaterialColor
|
||||||
import net.minecraft.util.math.shapes.VoxelShape
|
import net.minecraft.util.math.shapes.VoxelShape
|
||||||
import net.minecraft.util.math.shapes.VoxelShapes
|
import net.minecraft.util.math.shapes.VoxelShapes
|
||||||
import net.minecraft.world.IBlockReader
|
|
||||||
|
|
||||||
open class BlockScaffolding protected constructor(builder: BlockBuilder) : HeeBlock(builder) {
|
object BlockScaffolding : HeeBlockBuilder() {
|
||||||
companion object {
|
var enableShape = true
|
||||||
var enableShape = true
|
|
||||||
|
init {
|
||||||
|
includeFrom(BlockIndestructible)
|
||||||
|
|
||||||
fun create(builder: BlockBuilder): HeeBlock {
|
model = BlockModel.Manual
|
||||||
return HEE.debugModule?.createScaffoldingBlock(builder) ?: BlockScaffolding(builder)
|
renderLayer = CUTOUT
|
||||||
|
|
||||||
|
material = Materials.SCAFFOLDING
|
||||||
|
color = MaterialColor.AIR
|
||||||
|
sound = SoundType.STONE
|
||||||
|
|
||||||
|
isSolid = false
|
||||||
|
isOpaque = false
|
||||||
|
suffocates = false
|
||||||
|
blocksVision = false
|
||||||
|
|
||||||
|
components.shape = object : IBlockShapeComponent {
|
||||||
|
override fun getShape(state: BlockState): VoxelShape {
|
||||||
|
return fullCubeIf(enableShape)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getCollisionShape(state: BlockState): VoxelShape {
|
||||||
|
return fullCubeIf(enableShape && Environment.getClientSidePlayer().let { it == null || !it.abilities.isFlying })
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getRaytraceShape(state: BlockState): VoxelShape {
|
||||||
|
return fullCubeIf(enableShape && Environment.getClientSidePlayer().let { it == null || it.isSneaking || it.abilities.isFlying })
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun fullCubeIf(condition: Boolean): VoxelShape {
|
||||||
|
return if (condition) VoxelShapes.fullCube() else VoxelShapes.empty()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override val model
|
|
||||||
get() = BlockModel.Manual
|
|
||||||
|
|
||||||
override val renderLayer
|
|
||||||
get() = CUTOUT
|
|
||||||
|
|
||||||
// Visuals and physics
|
|
||||||
|
|
||||||
override fun getShape(state: BlockState, world: IBlockReader, pos: BlockPos, context: ISelectionContext): VoxelShape {
|
|
||||||
return if (enableShape)
|
|
||||||
VoxelShapes.fullCube()
|
|
||||||
else
|
|
||||||
VoxelShapes.empty()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getCollisionShape(state: BlockState, world: IBlockReader, pos: BlockPos, context: ISelectionContext): VoxelShape {
|
|
||||||
val player = Environment.getClientSidePlayer()
|
|
||||||
|
|
||||||
return if ((player == null || !player.abilities.isFlying) && enableShape)
|
components.ambientOcclusionValue = 1F
|
||||||
VoxelShapes.fullCube()
|
|
||||||
else
|
|
||||||
VoxelShapes.empty()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getRaytraceShape(state: BlockState, world: IBlockReader, pos: BlockPos): VoxelShape {
|
|
||||||
val player = Environment.getClientSidePlayer()
|
|
||||||
|
|
||||||
return if ((player == null || player.isSneaking || player.abilities.isFlying) && enableShape)
|
components.playerUse = HEE.debugModule?.scaffoldingBlockBehavior
|
||||||
VoxelShapes.fullCube()
|
|
||||||
else
|
|
||||||
VoxelShapes.empty()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Sided(Side.CLIENT)
|
|
||||||
override fun getAmbientOcclusionLightValue(state: BlockState, world: IBlockReader, pos: BlockPos): Float {
|
|
||||||
return 1F
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,42 +2,43 @@ package chylex.hee.game.block
|
|||||||
|
|
||||||
import chylex.hee.game.Resource
|
import chylex.hee.game.Resource
|
||||||
import chylex.hee.game.Resource.location
|
import chylex.hee.game.Resource.location
|
||||||
import chylex.hee.game.block.properties.BlockBuilder
|
import chylex.hee.game.block.builder.HeeBlockBuilder
|
||||||
|
import chylex.hee.game.block.components.IBlockExperienceComponent
|
||||||
import chylex.hee.game.block.properties.BlockDrop
|
import chylex.hee.game.block.properties.BlockDrop
|
||||||
|
import chylex.hee.game.block.properties.BlockHardness
|
||||||
|
import chylex.hee.game.block.properties.BlockHarvestTool
|
||||||
import chylex.hee.game.block.properties.BlockModel
|
import chylex.hee.game.block.properties.BlockModel
|
||||||
import chylex.hee.game.block.properties.BlockRenderLayer.CUTOUT
|
import chylex.hee.game.block.properties.BlockRenderLayer.CUTOUT
|
||||||
import chylex.hee.game.block.properties.BlockStateModel
|
import chylex.hee.game.block.properties.BlockStateModel
|
||||||
import chylex.hee.game.block.properties.BlockStatePreset
|
import chylex.hee.game.block.properties.BlockStatePreset
|
||||||
import chylex.hee.init.ModBlocks
|
import chylex.hee.game.block.properties.IBlockStateModelSupplier
|
||||||
|
import chylex.hee.game.item.util.Tool.Level.STONE
|
||||||
|
import chylex.hee.game.item.util.Tool.Type.PICKAXE
|
||||||
import chylex.hee.util.math.ceilToInt
|
import chylex.hee.util.math.ceilToInt
|
||||||
import chylex.hee.util.random.nextBiasedFloat
|
import chylex.hee.util.random.nextBiasedFloat
|
||||||
import net.minecraft.block.BlockState
|
|
||||||
import net.minecraft.block.Blocks
|
import net.minecraft.block.Blocks
|
||||||
import net.minecraft.util.math.BlockPos
|
|
||||||
import net.minecraft.world.IWorldReader
|
|
||||||
import net.minecraft.world.World
|
|
||||||
import net.minecraftforge.common.Tags
|
|
||||||
|
|
||||||
class BlockStardustOre(builder: BlockBuilder) : HeeBlock(builder) {
|
object BlockStardustOre : HeeBlockBuilder() {
|
||||||
override val model
|
init {
|
||||||
get() = BlockStateModel(
|
includeFrom(BlockEndOre)
|
||||||
BlockStatePreset.None,
|
|
||||||
BlockModel.WithTextures(BlockModel.FromParent(Resource.Custom("block/cube_overlay")), mapOf(
|
model = IBlockStateModelSupplier {
|
||||||
"particle" to ModBlocks.STARDUST_ORE.location("_particle"),
|
BlockStateModel(
|
||||||
"base" to Blocks.END_STONE.location,
|
BlockStatePreset.None,
|
||||||
))
|
BlockModel.WithTextures(BlockModel.FromParent(Resource.Custom("block/cube_overlay")), mapOf(
|
||||||
)
|
"particle" to it.location("_particle"),
|
||||||
|
"base" to Blocks.END_STONE.location,
|
||||||
override val renderLayer
|
))
|
||||||
get() = CUTOUT
|
)
|
||||||
|
}
|
||||||
override val drop
|
|
||||||
get() = BlockDrop.Manual
|
renderLayer = CUTOUT
|
||||||
|
|
||||||
override val tags
|
drop = BlockDrop.Manual
|
||||||
get() = listOf(Tags.Blocks.ORES)
|
|
||||||
|
tool = BlockHarvestTool.required(STONE, PICKAXE)
|
||||||
override fun getExpDrop(state: BlockState, world: IWorldReader, pos: BlockPos, fortune: Int, silktouch: Int): Int {
|
hardness = BlockHardness(hardness = 2.8F, resistance = 8.4F)
|
||||||
return (((world as? World)?.rand ?: RANDOM).nextBiasedFloat(4F) * 6F).ceilToInt()
|
|
||||||
|
components.experience = IBlockExperienceComponent { rand -> (rand.nextBiasedFloat(4F) * 6F).ceilToInt() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,26 +0,0 @@
|
|||||||
package chylex.hee.game.block
|
|
||||||
|
|
||||||
import chylex.hee.game.block.logic.IBlockDynamicHardness
|
|
||||||
import chylex.hee.game.block.properties.BlockBuilder
|
|
||||||
import chylex.hee.game.world.util.Facing4
|
|
||||||
import chylex.hee.game.world.util.getBlock
|
|
||||||
import chylex.hee.init.ModBlocks
|
|
||||||
import net.minecraft.block.BlockState
|
|
||||||
import net.minecraft.util.math.BlockPos
|
|
||||||
import net.minecraft.world.IBlockReader
|
|
||||||
|
|
||||||
open class BlockVoidPortalCrafted(builder: BlockBuilder) : BlockPortalFrame(builder), IBlockDynamicHardness {
|
|
||||||
override val model
|
|
||||||
get() = ModBlocks.VOID_PORTAL_FRAME.model
|
|
||||||
|
|
||||||
override fun getBlockHardness(world: IBlockReader, pos: BlockPos, state: BlockState, originalHardness: Float): Float {
|
|
||||||
return if (Facing4.any { pos.offset(it).getBlock(world) === ModBlocks.VOID_PORTAL_INNER })
|
|
||||||
originalHardness * 20F
|
|
||||||
else
|
|
||||||
originalHardness
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getTranslationKey(): String {
|
|
||||||
return ModBlocks.VOID_PORTAL_FRAME.translationKey
|
|
||||||
}
|
|
||||||
}
|
|
48
src/main/java/chylex/hee/game/block/BlockVoidPortalFrame.kt
Normal file
48
src/main/java/chylex/hee/game/block/BlockVoidPortalFrame.kt
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
package chylex.hee.game.block
|
||||||
|
|
||||||
|
import chylex.hee.game.block.builder.HeeBlockBuilder
|
||||||
|
import chylex.hee.game.block.components.IBlockNameComponent
|
||||||
|
import chylex.hee.game.block.logic.IBlockDynamicHardness
|
||||||
|
import chylex.hee.game.block.properties.BlockHardness
|
||||||
|
import chylex.hee.game.block.properties.BlockHarvestTool
|
||||||
|
import chylex.hee.game.item.util.Tool.Level.DIAMOND
|
||||||
|
import chylex.hee.game.world.util.Facing4
|
||||||
|
import chylex.hee.game.world.util.getBlock
|
||||||
|
import chylex.hee.init.ModBlocks
|
||||||
|
import chylex.hee.init.ModTags
|
||||||
|
import net.minecraft.block.BlockState
|
||||||
|
import net.minecraft.util.math.BlockPos
|
||||||
|
import net.minecraft.world.IBlockReader
|
||||||
|
import net.minecraftforge.common.ToolType.PICKAXE
|
||||||
|
|
||||||
|
object BlockVoidPortalFrame {
|
||||||
|
object Indestructible : HeeBlockBuilder() {
|
||||||
|
init {
|
||||||
|
includeFrom(BlockPortalFrameIndestructible)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object Crafted : HeeBlockBuilder() {
|
||||||
|
init {
|
||||||
|
includeFrom(BlockPortalFrameBase)
|
||||||
|
|
||||||
|
model = ModBlocks.VOID_PORTAL_FRAME.model.generate(ModBlocks.VOID_PORTAL_FRAME)
|
||||||
|
|
||||||
|
tags.add(ModTags.VOID_PORTAL_FRAME_CRAFTED)
|
||||||
|
|
||||||
|
tool = BlockHarvestTool.required(DIAMOND, PICKAXE)
|
||||||
|
hardness = BlockHardness(hardnessAndResistance = 1.7F)
|
||||||
|
|
||||||
|
components.name = IBlockNameComponent.of(ModBlocks.VOID_PORTAL_FRAME)
|
||||||
|
|
||||||
|
interfaces[IBlockDynamicHardness::class.java] = object : IBlockDynamicHardness {
|
||||||
|
override fun getBlockHardness(world: IBlockReader, pos: BlockPos, state: BlockState, originalHardness: Float): Float {
|
||||||
|
return if (Facing4.any { pos.offset(it).getBlock(world) === ModBlocks.VOID_PORTAL_INNER })
|
||||||
|
originalHardness * 20F
|
||||||
|
else
|
||||||
|
originalHardness
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,14 +1,16 @@
|
|||||||
package chylex.hee.game.block
|
package chylex.hee.game.block
|
||||||
|
|
||||||
|
import chylex.hee.game.block.BlockAbstractPortal.IInnerPortalBlock
|
||||||
|
import chylex.hee.game.block.BlockAbstractPortal.IPortalController
|
||||||
import chylex.hee.game.block.BlockVoidPortalInner.Type.HUB
|
import chylex.hee.game.block.BlockVoidPortalInner.Type.HUB
|
||||||
import chylex.hee.game.block.BlockVoidPortalInner.Type.RETURN_ACTIVE
|
import chylex.hee.game.block.BlockVoidPortalInner.Type.RETURN_ACTIVE
|
||||||
|
import chylex.hee.game.block.builder.HeeBlockBuilder
|
||||||
|
import chylex.hee.game.block.components.IBlockNeighborChanged
|
||||||
import chylex.hee.game.block.entity.TileEntityPortalInner
|
import chylex.hee.game.block.entity.TileEntityPortalInner
|
||||||
import chylex.hee.game.block.entity.TileEntityVoidPortalStorage
|
import chylex.hee.game.block.entity.TileEntityVoidPortalStorage
|
||||||
import chylex.hee.game.block.properties.BlockBuilder
|
|
||||||
import chylex.hee.game.block.util.Property
|
import chylex.hee.game.block.util.Property
|
||||||
import chylex.hee.game.entity.Teleporter
|
import chylex.hee.game.entity.Teleporter
|
||||||
import chylex.hee.game.entity.Teleporter.FxRange.Silent
|
import chylex.hee.game.entity.Teleporter.FxRange.Silent
|
||||||
import chylex.hee.game.entity.util.EntityPortalContact
|
|
||||||
import chylex.hee.game.mechanics.causatum.EnderCausatum
|
import chylex.hee.game.mechanics.causatum.EnderCausatum
|
||||||
import chylex.hee.game.territory.TerritoryType
|
import chylex.hee.game.territory.TerritoryType
|
||||||
import chylex.hee.game.territory.system.TerritoryInstance
|
import chylex.hee.game.territory.system.TerritoryInstance
|
||||||
@@ -24,44 +26,67 @@ import chylex.hee.game.world.util.max
|
|||||||
import chylex.hee.game.world.util.min
|
import chylex.hee.game.world.util.min
|
||||||
import chylex.hee.game.world.util.offsetUntil
|
import chylex.hee.game.world.util.offsetUntil
|
||||||
import chylex.hee.game.world.util.setAir
|
import chylex.hee.game.world.util.setAir
|
||||||
|
import chylex.hee.init.ModTags
|
||||||
import chylex.hee.util.math.Pos
|
import chylex.hee.util.math.Pos
|
||||||
import chylex.hee.util.math.Vec3
|
import chylex.hee.util.math.Vec3
|
||||||
import chylex.hee.util.math.center
|
import chylex.hee.util.math.center
|
||||||
import chylex.hee.util.math.subtractY
|
import chylex.hee.util.math.subtractY
|
||||||
import net.minecraft.block.Block
|
|
||||||
import net.minecraft.block.BlockState
|
|
||||||
import net.minecraft.entity.Entity
|
import net.minecraft.entity.Entity
|
||||||
import net.minecraft.entity.LivingEntity
|
import net.minecraft.entity.LivingEntity
|
||||||
import net.minecraft.entity.player.PlayerEntity
|
import net.minecraft.entity.player.PlayerEntity
|
||||||
import net.minecraft.state.StateContainer.Builder
|
|
||||||
import net.minecraft.tileentity.TileEntity
|
import net.minecraft.tileentity.TileEntity
|
||||||
import net.minecraft.util.IStringSerializable
|
import net.minecraft.util.IStringSerializable
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.world.IBlockReader
|
|
||||||
import net.minecraft.world.World
|
import net.minecraft.world.World
|
||||||
|
|
||||||
class BlockVoidPortalInner(builder: BlockBuilder) : BlockAbstractPortal(builder) {
|
object BlockVoidPortalInner : HeeBlockBuilder() {
|
||||||
companion object {
|
val TYPE = Property.enum<Type>("type")
|
||||||
val TYPE = Property.enum<Type>("type")
|
|
||||||
|
private val TELEPORTER = Teleporter(postEvent = false, effectRange = Silent)
|
||||||
private val TELEPORTER = Teleporter(postEvent = false, effectRange = Silent)
|
|
||||||
|
init {
|
||||||
fun teleportEntity(entity: Entity, info: SpawnInfo) {
|
includeFrom(BlockAbstractPortal(object : IInnerPortalBlock {
|
||||||
val targetVec = info.pos.center.subtractY(0.45)
|
override fun createTileEntity(): TileEntity {
|
||||||
|
return TileEntityPortalInner.Void()
|
||||||
if (entity is LivingEntity) {
|
|
||||||
if (entity is PlayerEntity) {
|
|
||||||
TerritoryType.fromPos(info.pos)?.let { EnderCausatum.triggerStage(entity, it.stage) }
|
|
||||||
}
|
|
||||||
|
|
||||||
info.yaw?.let { entity.rotationYaw = it }
|
|
||||||
entity.rotationPitch = 0F
|
|
||||||
|
|
||||||
TELEPORTER.toLocation(entity, targetVec)
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
entity.setPositionAndUpdate(targetVec.x, targetVec.y, targetVec.z)
|
override fun teleportEntity(world: World, pos: BlockPos, entity: Entity) {
|
||||||
entity.motion = Vec3.ZERO
|
when (pos.getState(world)[TYPE]) {
|
||||||
|
HUB -> {
|
||||||
|
val info = pos.closestTickingTile<TileEntityVoidPortalStorage>(world, BlockAbstractPortal.MAX_DISTANCE_FROM_FRAME)?.prepareSpawnPoint(entity)
|
||||||
|
|
||||||
|
if (info != null) {
|
||||||
|
if (entity.isInEndDimension) {
|
||||||
|
DimensionTeleporter.LastHubPortal.updateForEntity(entity, null)
|
||||||
|
updateSpawnPortal(entity, pos)
|
||||||
|
teleportEntity(entity, info)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DimensionTeleporter.LastHubPortal.updateForEntity(entity, pos)
|
||||||
|
DimensionTeleporter.changeDimension(entity, World.THE_END, DimensionTeleporter.EndTerritoryPortal(info))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RETURN_ACTIVE -> {
|
||||||
|
if (!DimensionTeleporter.LastHubPortal.tryOverrideTeleport(entity)) {
|
||||||
|
updateSpawnPortal(entity, pos)
|
||||||
|
teleportEntity(entity, TerritoryInstance.THE_HUB_INSTANCE.prepareSpawnPoint(entity as? PlayerEntity, clearanceRadius = 2))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
components.states.set(TYPE, HUB)
|
||||||
|
|
||||||
|
components.onNeighborChanged = IBlockNeighborChanged { state, world, pos, oldNeighborBlock, newNeighborBlock, _ ->
|
||||||
|
if (ModTags.VOID_PORTAL_FRAME_CRAFTED.contains(oldNeighborBlock) && !ModTags.VOID_PORTAL_FRAME_CRAFTED.contains(newNeighborBlock)) {
|
||||||
|
for (portalPos in pos.floodFill(Facing4) { it.getBlock(world) === state.block }) {
|
||||||
|
portalPos.setAir(world)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -85,38 +110,29 @@ class BlockVoidPortalInner(builder: BlockBuilder) : BlockAbstractPortal(builder)
|
|||||||
fun create(entity: Entity): TerritoryInstance?
|
fun create(entity: Entity): TerritoryInstance?
|
||||||
}
|
}
|
||||||
|
|
||||||
// Instance
|
fun teleportEntity(entity: Entity, info: SpawnInfo) {
|
||||||
|
val targetVec = info.pos.center.subtractY(0.45)
|
||||||
init {
|
|
||||||
defaultState = stateContainer.baseState.with(TYPE, HUB)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun fillStateContainer(container: Builder<Block, BlockState>) {
|
|
||||||
container.add(TYPE)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun createTileEntity(state: BlockState, world: IBlockReader): TileEntity {
|
|
||||||
return TileEntityPortalInner.Void()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Breaking
|
|
||||||
|
|
||||||
override fun neighborChanged(state: BlockState, world: World, pos: BlockPos, neighborBlock: Block, neighborPos: BlockPos, isMoving: Boolean) {
|
|
||||||
if (neighborBlock is BlockVoidPortalCrafted && neighborPos.getBlock(world) !is BlockVoidPortalCrafted) {
|
|
||||||
for (portalPos in pos.floodFill(Facing4) { it.getBlock(world) === this }) {
|
|
||||||
portalPos.setAir(world)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("DEPRECATION")
|
if (entity is LivingEntity) {
|
||||||
super.neighborChanged(state, world, pos, neighborBlock, neighborPos, isMoving)
|
if (entity is PlayerEntity) {
|
||||||
|
TerritoryType.fromPos(info.pos)?.let { EnderCausatum.triggerStage(entity, it.stage) }
|
||||||
|
}
|
||||||
|
|
||||||
|
info.yaw?.let { entity.rotationYaw = it }
|
||||||
|
entity.rotationPitch = 0F
|
||||||
|
|
||||||
|
TELEPORTER.toLocation(entity, targetVec)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
entity.setPositionAndUpdate(targetVec.x, targetVec.y, targetVec.z)
|
||||||
|
entity.motion = Vec3.ZERO
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interaction
|
|
||||||
|
|
||||||
private fun findSpawnPortalCenter(entity: Entity, pos: BlockPos): BlockPos? {
|
private fun findSpawnPortalCenter(entity: Entity, pos: BlockPos): BlockPos? {
|
||||||
val world = entity.world
|
val world = entity.world
|
||||||
val offsets = Facing4.map { facing -> pos.offsetUntil(facing, 1..MAX_SIZE) { it.getBlock(world) !== this } ?: return null }
|
val block = pos.getBlock(world)
|
||||||
|
val offsets = Facing4.map { facing -> pos.offsetUntil(facing, 1..BlockAbstractPortal.MAX_SIZE) { it.getBlock(world) !== block } ?: return null }
|
||||||
|
|
||||||
val minPos = offsets.reduce(BlockPos::min)
|
val minPos = offsets.reduce(BlockPos::min)
|
||||||
val maxPos = offsets.reduce(BlockPos::max)
|
val maxPos = offsets.reduce(BlockPos::max)
|
||||||
@@ -134,37 +150,4 @@ class BlockVoidPortalInner(builder: BlockBuilder) : BlockAbstractPortal(builder)
|
|||||||
|
|
||||||
instance.updateSpawnPoint(entity, centerPos)
|
instance.updateSpawnPoint(entity, centerPos)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onEntityInside(world: World, pos: BlockPos, entity: Entity) {
|
|
||||||
if (!EntityPortalContact.shouldTeleport(entity)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
when(pos.getState(world)[TYPE]) {
|
|
||||||
HUB -> {
|
|
||||||
val info = pos.closestTickingTile<TileEntityVoidPortalStorage>(world, MAX_DISTANCE_FROM_FRAME)?.prepareSpawnPoint(entity)
|
|
||||||
|
|
||||||
if (info != null) {
|
|
||||||
if (entity.isInEndDimension) {
|
|
||||||
DimensionTeleporter.LastHubPortal.updateForEntity(entity, null)
|
|
||||||
updateSpawnPortal(entity, pos)
|
|
||||||
teleportEntity(entity, info)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DimensionTeleporter.LastHubPortal.updateForEntity(entity, pos)
|
|
||||||
DimensionTeleporter.changeDimension(entity, World.THE_END, DimensionTeleporter.EndTerritoryPortal(info))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_ACTIVE -> {
|
|
||||||
if (!DimensionTeleporter.LastHubPortal.tryOverrideTeleport(entity)) {
|
|
||||||
updateSpawnPortal(entity, pos)
|
|
||||||
teleportEntity(entity, TerritoryInstance.THE_HUB_INSTANCE.prepareSpawnPoint(entity as? PlayerEntity, clearanceRadius = 2))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -1,47 +1,40 @@
|
|||||||
package chylex.hee.game.block
|
package chylex.hee.game.block
|
||||||
|
|
||||||
|
import chylex.hee.game.block.builder.HeeBlockBuilder
|
||||||
|
import chylex.hee.game.block.components.IBlockAddedComponent
|
||||||
|
import chylex.hee.game.block.components.IBlockEntityComponent
|
||||||
|
import chylex.hee.game.block.components.IBlockNameComponent
|
||||||
|
import chylex.hee.game.block.components.IPlayerUseBlockComponent
|
||||||
import chylex.hee.game.block.entity.TileEntityVoidPortalStorage
|
import chylex.hee.game.block.entity.TileEntityVoidPortalStorage
|
||||||
import chylex.hee.game.block.properties.BlockBuilder
|
|
||||||
import chylex.hee.game.block.properties.BlockModel
|
import chylex.hee.game.block.properties.BlockModel
|
||||||
import chylex.hee.game.world.util.getTile
|
import chylex.hee.game.world.util.getTile
|
||||||
import chylex.hee.init.ModBlocks
|
import chylex.hee.init.ModBlocks
|
||||||
import chylex.hee.init.ModContainers
|
import chylex.hee.init.ModContainers
|
||||||
import net.minecraft.block.BlockState
|
|
||||||
import net.minecraft.entity.player.PlayerEntity
|
|
||||||
import net.minecraft.tileentity.TileEntity
|
|
||||||
import net.minecraft.util.ActionResultType
|
|
||||||
import net.minecraft.util.ActionResultType.SUCCESS
|
import net.minecraft.util.ActionResultType.SUCCESS
|
||||||
import net.minecraft.util.Hand
|
|
||||||
import net.minecraft.util.math.BlockPos
|
|
||||||
import net.minecraft.util.math.BlockRayTraceResult
|
|
||||||
import net.minecraft.world.IBlockReader
|
|
||||||
import net.minecraft.world.World
|
|
||||||
|
|
||||||
class BlockVoidPortalStorage(builder: BlockBuilder) : BlockPortalFrame(builder) {
|
abstract class BlockVoidPortalStorage(base: HeeBlockBuilder, minPortalSize: Int) : HeeBlockBuilder() {
|
||||||
override val model
|
init {
|
||||||
get() = BlockModel.PortalFrame(ModBlocks.VOID_PORTAL_FRAME, "storage")
|
includeFrom(base)
|
||||||
|
|
||||||
override fun hasTileEntity(state: BlockState): Boolean {
|
model = BlockModel.PortalFrame(ModBlocks.VOID_PORTAL_FRAME, "storage")
|
||||||
return true
|
|
||||||
}
|
components.entity = IBlockEntityComponent(::TileEntityVoidPortalStorage)
|
||||||
|
|
||||||
override fun createTileEntity(state: BlockState, world: IBlockReader): TileEntity {
|
components.onAdded = IBlockAddedComponent { _, world, pos ->
|
||||||
return TileEntityVoidPortalStorage()
|
BlockAbstractPortal.spawnInnerBlocks(world, pos, ModBlocks.VOID_PORTAL_FRAME, ModBlocks.VOID_PORTAL_INNER, minSize = minPortalSize)
|
||||||
}
|
|
||||||
|
|
||||||
override fun onBlockAdded(state: BlockState, world: World, pos: BlockPos, oldState: BlockState, isMoving: Boolean) {
|
|
||||||
BlockAbstractPortal.spawnInnerBlocks(world, pos, ModBlocks.VOID_PORTAL_FRAME, ModBlocks.VOID_PORTAL_INNER, minSize = 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onBlockActivated(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, hit: BlockRayTraceResult): ActionResultType {
|
|
||||||
if (world.isRemote) {
|
|
||||||
return SUCCESS
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pos.getTile<TileEntityVoidPortalStorage>(world)?.let {
|
components.playerUse = IPlayerUseBlockComponent { _, world, pos, player, _ ->
|
||||||
ModContainers.open(player, it, pos)
|
pos.getTile<TileEntityVoidPortalStorage>(world)?.let { ModContainers.open(player, it, pos) }
|
||||||
|
SUCCESS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object Indestructible : BlockVoidPortalStorage(BlockVoidPortalFrame.Indestructible, minPortalSize = 1)
|
||||||
|
|
||||||
|
object Crafted : BlockVoidPortalStorage(BlockVoidPortalFrame.Crafted, minPortalSize = 3) {
|
||||||
|
init {
|
||||||
|
components.name = IBlockNameComponent.of(ModBlocks.VOID_PORTAL_STORAGE)
|
||||||
}
|
}
|
||||||
|
|
||||||
return SUCCESS
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,39 +0,0 @@
|
|||||||
package chylex.hee.game.block
|
|
||||||
|
|
||||||
import chylex.hee.game.block.properties.BlockBuilder
|
|
||||||
import chylex.hee.init.ModBlocks
|
|
||||||
import net.minecraft.block.BlockState
|
|
||||||
import net.minecraft.entity.player.PlayerEntity
|
|
||||||
import net.minecraft.tileentity.TileEntity
|
|
||||||
import net.minecraft.util.ActionResultType
|
|
||||||
import net.minecraft.util.Hand
|
|
||||||
import net.minecraft.util.math.BlockPos
|
|
||||||
import net.minecraft.util.math.BlockRayTraceResult
|
|
||||||
import net.minecraft.world.IBlockReader
|
|
||||||
import net.minecraft.world.World
|
|
||||||
|
|
||||||
class BlockVoidPortalStorageCrafted(builder: BlockBuilder) : BlockVoidPortalCrafted(builder) {
|
|
||||||
override val model
|
|
||||||
get() = ModBlocks.VOID_PORTAL_STORAGE.model
|
|
||||||
|
|
||||||
override fun hasTileEntity(state: BlockState): Boolean {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun createTileEntity(state: BlockState, world: IBlockReader): TileEntity {
|
|
||||||
return ModBlocks.VOID_PORTAL_STORAGE.createTileEntity(state, world)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onBlockAdded(state: BlockState, world: World, pos: BlockPos, oldState: BlockState, isMoving: Boolean) {
|
|
||||||
BlockAbstractPortal.spawnInnerBlocks(world, pos, ModBlocks.VOID_PORTAL_FRAME_CRAFTED, ModBlocks.VOID_PORTAL_INNER, minSize = 3)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onBlockActivated(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, hit: BlockRayTraceResult): ActionResultType {
|
|
||||||
@Suppress("DEPRECATION")
|
|
||||||
return ModBlocks.VOID_PORTAL_STORAGE.onBlockActivated(state, world, pos, player, hand, hit)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getTranslationKey(): String {
|
|
||||||
return ModBlocks.VOID_PORTAL_STORAGE.translationKey
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,27 +1,47 @@
|
|||||||
package chylex.hee.game.block
|
package chylex.hee.game.block
|
||||||
|
|
||||||
import chylex.hee.game.Resource.location
|
import chylex.hee.game.Resource.location
|
||||||
import chylex.hee.game.block.properties.BlockBuilder
|
import chylex.hee.game.block.builder.HeeBlockBuilder
|
||||||
|
import chylex.hee.game.block.components.IFlammableBlockComponent
|
||||||
|
import chylex.hee.game.block.properties.BlockHardness
|
||||||
|
import chylex.hee.game.block.properties.BlockHarvestTool
|
||||||
import chylex.hee.game.block.properties.BlockModel
|
import chylex.hee.game.block.properties.BlockModel
|
||||||
|
import chylex.hee.game.item.util.Tool.Level.WOOD
|
||||||
import chylex.hee.init.ModBlocks
|
import chylex.hee.init.ModBlocks
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.SoundType
|
||||||
|
import net.minecraft.block.material.Material
|
||||||
|
import net.minecraft.block.material.MaterialColor
|
||||||
import net.minecraft.tags.BlockTags
|
import net.minecraft.tags.BlockTags
|
||||||
import net.minecraft.util.Direction
|
import net.minecraftforge.common.ToolType.AXE
|
||||||
import net.minecraft.util.math.BlockPos
|
|
||||||
import net.minecraft.world.IBlockReader
|
|
||||||
|
|
||||||
class BlockWhitebark(builder: BlockBuilder) : HeeBlock(builder) {
|
object BlockWhitebark : HeeBlockBuilder() {
|
||||||
override val model
|
init {
|
||||||
get() = BlockModel.Cube(ModBlocks.WHITEBARK_LOG.location)
|
material = Material.WOOD
|
||||||
|
color = MaterialColor.SNOW
|
||||||
override val tags
|
sound = SoundType.WOOD
|
||||||
get() = listOf(BlockTags.LOGS, BlockTags.LOGS_THAT_BURN)
|
tool = BlockHarvestTool.optional(WOOD, AXE)
|
||||||
|
|
||||||
override fun getFlammability(state: BlockState, world: IBlockReader, pos: BlockPos, face: Direction): Int {
|
|
||||||
return 5
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getFireSpreadSpeed(state: BlockState, world: IBlockReader, pos: BlockPos, face: Direction): Int {
|
val BARK = HeeBlockBuilder {
|
||||||
return 5
|
includeFrom(BlockWhitebark)
|
||||||
|
|
||||||
|
model = BlockModel.Cube(ModBlocks.WHITEBARK_LOG.location)
|
||||||
|
|
||||||
|
tags.add(BlockTags.LOGS)
|
||||||
|
tags.add(BlockTags.LOGS_THAT_BURN)
|
||||||
|
|
||||||
|
hardness = BlockHardness(hardnessAndResistance = 2F)
|
||||||
|
|
||||||
|
components.flammability = IFlammableBlockComponent.of(flammability = 5, fireSpread = 5)
|
||||||
|
}
|
||||||
|
|
||||||
|
val PLANKS = HeeBlockBuilder {
|
||||||
|
includeFrom(BlockWhitebark)
|
||||||
|
|
||||||
|
tags.add(BlockTags.PLANKS)
|
||||||
|
|
||||||
|
hardness = BlockHardness(hardness = 2F, resistance = 3F)
|
||||||
|
|
||||||
|
components.flammability = IFlammableBlockComponent.of(flammability = 20, fireSpread = 5)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,21 +0,0 @@
|
|||||||
package chylex.hee.game.block
|
|
||||||
|
|
||||||
import chylex.hee.game.block.properties.BlockBuilder
|
|
||||||
import net.minecraft.block.BlockState
|
|
||||||
import net.minecraft.tags.BlockTags
|
|
||||||
import net.minecraft.util.Direction
|
|
||||||
import net.minecraft.util.math.BlockPos
|
|
||||||
import net.minecraft.world.IBlockReader
|
|
||||||
|
|
||||||
class BlockWhitebarkPlanks(builder: BlockBuilder) : HeeBlock(builder) {
|
|
||||||
override val tags
|
|
||||||
get() = listOf(BlockTags.PLANKS)
|
|
||||||
|
|
||||||
override fun getFlammability(state: BlockState, world: IBlockReader, pos: BlockPos, face: Direction): Int {
|
|
||||||
return 20
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getFireSpreadSpeed(state: BlockState, world: IBlockReader, pos: BlockPos, face: Direction): Int {
|
|
||||||
return 5
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,5 +1,6 @@
|
|||||||
package chylex.hee.game.block.dispenser
|
package chylex.hee.game.block.dispenser
|
||||||
|
|
||||||
|
import chylex.hee.game.block.BlockIgneousPlate
|
||||||
import chylex.hee.game.block.util.DISPENSER_FACING
|
import chylex.hee.game.block.util.DISPENSER_FACING
|
||||||
import chylex.hee.game.world.util.getState
|
import chylex.hee.game.world.util.getState
|
||||||
import chylex.hee.init.ModBlocks
|
import chylex.hee.init.ModBlocks
|
||||||
@@ -16,7 +17,7 @@ class DispenseWaterExtinguishIgneousPlate(private val originalBehavior: IDispens
|
|||||||
val facingState = facingPos.getState(world)
|
val facingState = facingPos.getState(world)
|
||||||
|
|
||||||
if (facingState.block === ModBlocks.IGNEOUS_PLATE) {
|
if (facingState.block === ModBlocks.IGNEOUS_PLATE) {
|
||||||
return if (ModBlocks.IGNEOUS_PLATE.tryCoolPlate(world, facingPos, facingState))
|
return if (BlockIgneousPlate.tryCoolPlate(world, facingPos, facingState))
|
||||||
ItemStack(Items.BUCKET)
|
ItemStack(Items.BUCKET)
|
||||||
else
|
else
|
||||||
stack
|
stack
|
||||||
|
@@ -46,13 +46,6 @@ object BlockBuilders {
|
|||||||
explosionResistance = 0.6F
|
explosionResistance = 0.6F
|
||||||
}
|
}
|
||||||
|
|
||||||
val buildEndiumBlock = BlockBuilder(Materials.SOLID, MaterialColor.LAPIS, SoundType.METAL).apply {
|
|
||||||
requiresTool = true
|
|
||||||
harvestTool = Pair(IRON, PICKAXE)
|
|
||||||
harvestHardness = 6.2F
|
|
||||||
explosionResistance = 12.0F
|
|
||||||
}
|
|
||||||
|
|
||||||
val buildEnderSol = BlockBuilder(Materials.SOLID, MaterialColor.WOOD, SoundType.GROUND.clone(pitch = 0.85F)).apply {
|
val buildEnderSol = BlockBuilder(Materials.SOLID, MaterialColor.WOOD, SoundType.GROUND.clone(pitch = 0.85F)).apply {
|
||||||
requiresTool = true
|
requiresTool = true
|
||||||
harvestTool = Pair(WOOD, SHOVEL)
|
harvestTool = Pair(WOOD, SHOVEL)
|
||||||
@@ -76,16 +69,6 @@ object BlockBuilders {
|
|||||||
explosionResistance = 4.2F
|
explosionResistance = 4.2F
|
||||||
}
|
}
|
||||||
|
|
||||||
val buildGloomrockBricks = buildGloomrock.clone {
|
|
||||||
harvestHardness = 2.8F
|
|
||||||
explosionResistance = 6.0F
|
|
||||||
}
|
|
||||||
|
|
||||||
val buildGloomrockSmooth = buildGloomrock.clone {
|
|
||||||
harvestHardness = 2.0F
|
|
||||||
explosionResistance = 4.8F
|
|
||||||
}
|
|
||||||
|
|
||||||
val buildGloomtorch = BlockBuilder(Materials.SOLID, MaterialColor.BLACK, SoundType.STONE).apply {
|
val buildGloomtorch = BlockBuilder(Materials.SOLID, MaterialColor.BLACK, SoundType.STONE).apply {
|
||||||
explosionResistance = 0.3F
|
explosionResistance = 0.3F
|
||||||
lightLevel = 13
|
lightLevel = 13
|
||||||
@@ -133,19 +116,6 @@ object BlockBuilders {
|
|||||||
lightLevel = 15
|
lightLevel = 15
|
||||||
}
|
}
|
||||||
|
|
||||||
val buildObsidianTowerTop = buildObsidianVariationLit.clone {
|
|
||||||
makeIndestructible()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Building (End Stone)
|
|
||||||
|
|
||||||
val buildEndStone = BlockBuilder(Materials.SOLID, MaterialColor.SAND, SoundType.STONE).apply {
|
|
||||||
requiresTool = true
|
|
||||||
harvestTool = Pair(WOOD, PICKAXE)
|
|
||||||
harvestHardness = 3.0F
|
|
||||||
explosionResistance = 9.0F
|
|
||||||
}
|
|
||||||
|
|
||||||
// Building (Dark Loam)
|
// Building (Dark Loam)
|
||||||
|
|
||||||
val buildDarkLoam = BlockBuilder(Materials.SOLID, MaterialColor.BLACK, SoundType.GROUND).apply {
|
val buildDarkLoam = BlockBuilder(Materials.SOLID, MaterialColor.BLACK, SoundType.GROUND).apply {
|
||||||
@@ -162,10 +132,6 @@ object BlockBuilders {
|
|||||||
explosionResistance = 2.0F
|
explosionResistance = 2.0F
|
||||||
}
|
}
|
||||||
|
|
||||||
val buildWhitebarkPlanks = buildWhitebark.clone {
|
|
||||||
explosionResistance = 3.0F
|
|
||||||
}
|
|
||||||
|
|
||||||
// Building (Miner's Burial)
|
// Building (Miner's Burial)
|
||||||
|
|
||||||
val buildMinersBurial = BlockBuilder(Materials.SOLID, MaterialColor.RED, SoundType.STONE).apply {
|
val buildMinersBurial = BlockBuilder(Materials.SOLID, MaterialColor.RED, SoundType.STONE).apply {
|
||||||
@@ -175,10 +141,6 @@ object BlockBuilders {
|
|||||||
explosionResistance = 120F
|
explosionResistance = 120F
|
||||||
}
|
}
|
||||||
|
|
||||||
val buildMinersBurialIndestructible = buildMinersBurial.clone {
|
|
||||||
makeIndestructible()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fluids
|
// Fluids
|
||||||
|
|
||||||
val buildCauldron = BlockBuilder(Material.IRON, MaterialColor.STONE, SoundType.STONE).apply {
|
val buildCauldron = BlockBuilder(Material.IRON, MaterialColor.STONE, SoundType.STONE).apply {
|
||||||
@@ -188,26 +150,11 @@ object BlockBuilders {
|
|||||||
|
|
||||||
// Interactive (Storage)
|
// Interactive (Storage)
|
||||||
|
|
||||||
val buildJarODust = BlockBuilder(Materials.JAR_O_DUST, MaterialColor.ORANGE_TERRACOTTA, SoundType.METAL).apply {
|
|
||||||
harvestHardness = 0.4F
|
|
||||||
explosionResistance = 0F
|
|
||||||
}
|
|
||||||
|
|
||||||
val buildLootChest = BlockBuilder(Materials.SOLID, MaterialColor.BLACK, SoundType.METAL).apply {
|
val buildLootChest = BlockBuilder(Materials.SOLID, MaterialColor.BLACK, SoundType.METAL).apply {
|
||||||
makeIndestructible()
|
makeIndestructible()
|
||||||
lightLevel = 13
|
lightLevel = 13
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interactive (Puzzle)
|
|
||||||
|
|
||||||
val buildPuzzleLogic = BlockBuilder(Materials.SOLID, MaterialColor.ADOBE /* RENAME ORANGE */, SoundType.STONE).apply {
|
|
||||||
makeIndestructible()
|
|
||||||
}
|
|
||||||
|
|
||||||
val buildPuzzleWall = buildPuzzleLogic.clone {
|
|
||||||
lightLevel = 14
|
|
||||||
}
|
|
||||||
|
|
||||||
// Interactive (Gates)
|
// Interactive (Gates)
|
||||||
|
|
||||||
val buildExperienceGate = BlockBuilder(Materials.SOLID, MaterialColor.GREEN, SoundType.METAL).apply {
|
val buildExperienceGate = BlockBuilder(Materials.SOLID, MaterialColor.GREEN, SoundType.METAL).apply {
|
||||||
@@ -217,8 +164,6 @@ object BlockBuilders {
|
|||||||
|
|
||||||
// Interactive (Uncategorized)
|
// Interactive (Uncategorized)
|
||||||
|
|
||||||
val buildIgneousPlate = BlockBuilder(Materials.IGNEOUS_ROCK_PLATE, MaterialColor.AIR, SoundType.STONE)
|
|
||||||
|
|
||||||
val buildBrewingStand = BlockBuilder(Material.IRON, MaterialColor.YELLOW, SoundType.STONE).apply {
|
val buildBrewingStand = BlockBuilder(Material.IRON, MaterialColor.YELLOW, SoundType.STONE).apply {
|
||||||
isSolid = false
|
isSolid = false
|
||||||
harvestHardness = 0.5F
|
harvestHardness = 0.5F
|
||||||
@@ -232,24 +177,6 @@ object BlockBuilders {
|
|||||||
requiresTool = true
|
requiresTool = true
|
||||||
}
|
}
|
||||||
|
|
||||||
val buildEndPowderOre = buildEndOre.clone {
|
|
||||||
harvestTool = Pair(STONE, PICKAXE)
|
|
||||||
harvestHardness = 2.0F
|
|
||||||
explosionResistance = 5.4F
|
|
||||||
}
|
|
||||||
|
|
||||||
val buildEndiumOre = buildEndOre.clone {
|
|
||||||
harvestTool = Pair(IRON, PICKAXE)
|
|
||||||
harvestHardness = 5.0F
|
|
||||||
explosionResistance = 9.9F
|
|
||||||
}
|
|
||||||
|
|
||||||
val buildStardustOre = buildEndOre.clone {
|
|
||||||
harvestTool = Pair(STONE, PICKAXE)
|
|
||||||
harvestHardness = 2.8F
|
|
||||||
explosionResistance = 8.4F
|
|
||||||
}
|
|
||||||
|
|
||||||
val buildIgneousRockOre = buildEndOre.clone {
|
val buildIgneousRockOre = buildEndOre.clone {
|
||||||
harvestTool = Pair(DIAMOND, PICKAXE)
|
harvestTool = Pair(DIAMOND, PICKAXE)
|
||||||
harvestHardness = 1.6F
|
harvestHardness = 1.6F
|
||||||
@@ -315,25 +242,6 @@ object BlockBuilders {
|
|||||||
noDrops = true
|
noDrops = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Portals
|
|
||||||
|
|
||||||
val buildPortalInner = BlockBuilder(Material.PORTAL, MaterialColor.BLACK, SoundType.STONE).apply {
|
|
||||||
makeIndestructible()
|
|
||||||
isSolid = false
|
|
||||||
lightLevel = 15
|
|
||||||
}
|
|
||||||
|
|
||||||
val buildPortalFrame = BlockBuilder(Materials.SOLID, MaterialColor.SAND, SoundType.STONE).apply {
|
|
||||||
makeIndestructible()
|
|
||||||
}
|
|
||||||
|
|
||||||
val buildPortalFrameCrafted = BlockBuilder(Materials.SOLID, MaterialColor.SAND, SoundType.STONE).apply {
|
|
||||||
requiresTool = true
|
|
||||||
harvestTool = Pair(DIAMOND, PICKAXE)
|
|
||||||
harvestHardness = 1.7F
|
|
||||||
explosionResistance = 1.7F
|
|
||||||
}
|
|
||||||
|
|
||||||
// Energy
|
// Energy
|
||||||
|
|
||||||
val buildEnergyCluster = BlockBuilder(Materials.ENERGY_CLUSTER, MaterialColor.SNOW, SoundType.GLASS.clone(volume = 1.25F, pitch = 1.35F)).apply {
|
val buildEnergyCluster = BlockBuilder(Materials.ENERGY_CLUSTER, MaterialColor.SNOW, SoundType.GLASS.clone(volume = 1.25F, pitch = 1.35F)).apply {
|
||||||
@@ -342,12 +250,6 @@ object BlockBuilders {
|
|||||||
noDrops = true
|
noDrops = true
|
||||||
}
|
}
|
||||||
|
|
||||||
val buildCorruptedEnergy = BlockBuilder(Materials.CORRUPTED_ENERGY, MaterialColor.PURPLE, SoundType.SAND).apply {
|
|
||||||
isSolid = false
|
|
||||||
randomTicks = true // just to be safe
|
|
||||||
noDrops = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tables
|
// Tables
|
||||||
|
|
||||||
val buildTablePedestal = buildGloomrock.clone {
|
val buildTablePedestal = buildGloomrock.clone {
|
||||||
@@ -372,14 +274,6 @@ object BlockBuilders {
|
|||||||
lightLevel = 15
|
lightLevel = 15
|
||||||
}
|
}
|
||||||
|
|
||||||
val buildScaffolding = BlockBuilder(Materials.SCAFFOLDING, MaterialColor.AIR, SoundType.STONE).apply {
|
|
||||||
makeIndestructible()
|
|
||||||
isSolid = false
|
|
||||||
isOpaque = false
|
|
||||||
suffocates = false
|
|
||||||
blocksVision = false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Overrides
|
// Overrides
|
||||||
|
|
||||||
val buildEndPortalOverride = BlockBuilder(Material.PORTAL, MaterialColor.BLACK, SoundType.STONE).apply {
|
val buildEndPortalOverride = BlockBuilder(Material.PORTAL, MaterialColor.BLACK, SoundType.STONE).apply {
|
||||||
|
@@ -160,7 +160,7 @@ class EntityItemIgneousRock : EntityItemNoBob {
|
|||||||
if (!world.isRemote && age > 4 && (world.gameTime - 1L) % BlockPuzzleLogic.UPDATE_RATE == 0L) {
|
if (!world.isRemote && age > 4 && (world.gameTime - 1L) % BlockPuzzleLogic.UPDATE_RATE == 0L) {
|
||||||
val posBelow = currentPos.down()
|
val posBelow = currentPos.down()
|
||||||
|
|
||||||
if (posBelow.getBlock(world) is BlockPuzzleLogic) {
|
if (BlockPuzzleLogic.isPuzzleBlock(posBelow.getBlock(world))) {
|
||||||
val entity = EntityTechnicalPuzzle(world)
|
val entity = EntityTechnicalPuzzle(world)
|
||||||
|
|
||||||
if (entity.startChain(posBelow, throwFacing)) {
|
if (entity.startChain(posBelow, throwFacing)) {
|
||||||
|
@@ -2,11 +2,11 @@ package chylex.hee.game.entity.living
|
|||||||
|
|
||||||
import chylex.hee.client.text.LocalizationStrategy
|
import chylex.hee.client.text.LocalizationStrategy
|
||||||
import chylex.hee.game.Resource
|
import chylex.hee.game.Resource
|
||||||
|
import chylex.hee.game.block.BlockCorruptedEnergy
|
||||||
import chylex.hee.game.entity.util.DefaultEntityAttributes
|
import chylex.hee.game.entity.util.DefaultEntityAttributes
|
||||||
import chylex.hee.game.entity.util.with
|
import chylex.hee.game.entity.util.with
|
||||||
import chylex.hee.game.mechanics.instability.Instability
|
import chylex.hee.game.mechanics.instability.Instability
|
||||||
import chylex.hee.game.world.util.isPeaceful
|
import chylex.hee.game.world.util.isPeaceful
|
||||||
import chylex.hee.init.ModBlocks
|
|
||||||
import chylex.hee.init.ModEntities
|
import chylex.hee.init.ModEntities
|
||||||
import chylex.hee.system.heeTag
|
import chylex.hee.system.heeTag
|
||||||
import chylex.hee.util.forge.Side
|
import chylex.hee.util.forge.Side
|
||||||
@@ -78,7 +78,7 @@ class EntityMobEndermiteInstability(type: EntityType<EntityMobEndermiteInstabili
|
|||||||
val pos = Pos(this)
|
val pos = Pos(this)
|
||||||
|
|
||||||
Instability.get(world).triggerRelief(20u, pos)
|
Instability.get(world).triggerRelief(20u, pos)
|
||||||
ModBlocks.CORRUPTED_ENERGY.spawnCorruptedEnergy(world, pos, 2)
|
BlockCorruptedEnergy.spawn(world, pos, 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
super.remove()
|
super.remove()
|
||||||
|
@@ -83,13 +83,10 @@ class EntityTechnicalPuzzle(type: EntityType<EntityTechnicalPuzzle>, world: Worl
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun moveToBlockAndToggle(pos: BlockPos) {
|
private fun moveToBlockAndToggle(pos: BlockPos) {
|
||||||
val block = pos.getBlock(world)
|
if (BlockPuzzleLogic.isPuzzleBlock(pos.getBlock(world))) {
|
||||||
|
|
||||||
if (block is BlockPuzzleLogic) {
|
|
||||||
setPosition(pos)
|
setPosition(pos)
|
||||||
|
|
||||||
val nextChains = block.onToggled(world, pos, facing)
|
val nextChains = BlockPuzzleLogic.onToggled(world, pos, facing)
|
||||||
|
|
||||||
if (nextChains.isEmpty()) {
|
if (nextChains.isEmpty()) {
|
||||||
endChain()
|
endChain()
|
||||||
}
|
}
|
||||||
@@ -125,10 +122,7 @@ class EntityTechnicalPuzzle(type: EntityType<EntityTechnicalPuzzle>, world: Worl
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun startChain(pos: BlockPos, facing: Direction): Boolean {
|
fun startChain(pos: BlockPos, facing: Direction): Boolean {
|
||||||
val state = pos.getState(world)
|
if (!BlockPuzzleLogic.isPuzzleBlockEnabled(pos.getState(world))) {
|
||||||
val block = state.block
|
|
||||||
|
|
||||||
if (block !is BlockPuzzleLogic || state[BlockPuzzleLogic.STATE] == BlockPuzzleLogic.State.DISABLED) {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -10,7 +10,7 @@ import net.minecraft.item.ItemStack
|
|||||||
import net.minecraft.util.text.ITextComponent
|
import net.minecraft.util.text.ITextComponent
|
||||||
import net.minecraft.util.text.StringTextComponent
|
import net.minecraft.util.text.StringTextComponent
|
||||||
import net.minecraft.util.text.TranslationTextComponent
|
import net.minecraft.util.text.TranslationTextComponent
|
||||||
import net.minecraft.world.World
|
import net.minecraft.world.IBlockReader
|
||||||
|
|
||||||
class ItemAbstractTrinket(trinket: ITrinketItem) : HeeItemBuilder() {
|
class ItemAbstractTrinket(trinket: ITrinketItem) : HeeItemBuilder() {
|
||||||
private companion object {
|
private companion object {
|
||||||
@@ -27,7 +27,7 @@ class ItemAbstractTrinket(trinket: ITrinketItem) : HeeItemBuilder() {
|
|||||||
localizationExtra[LANG_TOOLTIP_NOT_IN_SLOT_UNCHARGED] = "§cMust be charged and placed in Trinket slot"
|
localizationExtra[LANG_TOOLTIP_NOT_IN_SLOT_UNCHARGED] = "§cMust be charged and placed in Trinket slot"
|
||||||
|
|
||||||
components.tooltip.add(object : ITooltipComponent {
|
components.tooltip.add(object : ITooltipComponent {
|
||||||
override fun add(lines: MutableList<ITextComponent>, stack: ItemStack, advanced: Boolean, world: World?) {
|
override fun add(lines: MutableList<ITextComponent>, stack: ItemStack, advanced: Boolean, world: IBlockReader?) {
|
||||||
val player = MC.player ?: return
|
val player = MC.player ?: return
|
||||||
|
|
||||||
if (lines.size > 1) { // first line is item name
|
if (lines.size > 1) { // first line is item name
|
||||||
|
@@ -19,7 +19,7 @@ import net.minecraft.item.Rarity
|
|||||||
import net.minecraft.util.text.ITextComponent
|
import net.minecraft.util.text.ITextComponent
|
||||||
import net.minecraft.util.text.StringTextComponent
|
import net.minecraft.util.text.StringTextComponent
|
||||||
import net.minecraft.util.text.TranslationTextComponent
|
import net.minecraft.util.text.TranslationTextComponent
|
||||||
import net.minecraft.world.World
|
import net.minecraft.world.IBlockReader
|
||||||
|
|
||||||
object ItemBindingEssence : HeeItemBuilder() {
|
object ItemBindingEssence : HeeItemBuilder() {
|
||||||
init {
|
init {
|
||||||
@@ -57,7 +57,7 @@ object ItemBindingEssence : HeeItemBuilder() {
|
|||||||
maxStackSize = 16
|
maxStackSize = 16
|
||||||
|
|
||||||
components.tooltip.add(object : ITooltipComponent {
|
components.tooltip.add(object : ITooltipComponent {
|
||||||
override fun add(lines: MutableList<ITextComponent>, stack: ItemStack, advanced: Boolean, world: World?) {
|
override fun add(lines: MutableList<ITextComponent>, stack: ItemStack, advanced: Boolean, world: IBlockReader?) {
|
||||||
val list = InfusionTag.getList(stack)
|
val list = InfusionTag.getList(stack)
|
||||||
if (list.isEmpty) {
|
if (list.isEmpty) {
|
||||||
return
|
return
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
package chylex.hee.game.recipe
|
package chylex.hee.game.recipe
|
||||||
|
|
||||||
|
import chylex.hee.game.block.BlockJarODust
|
||||||
import chylex.hee.game.inventory.util.nonEmptySlots
|
import chylex.hee.game.inventory.util.nonEmptySlots
|
||||||
import chylex.hee.game.inventory.util.size
|
import chylex.hee.game.inventory.util.size
|
||||||
import chylex.hee.game.mechanics.dust.DustLayers.Side.BOTTOM
|
import chylex.hee.game.mechanics.dust.DustLayers.Side.BOTTOM
|
||||||
import chylex.hee.init.ModBlocks
|
|
||||||
import net.minecraft.inventory.CraftingInventory
|
import net.minecraft.inventory.CraftingInventory
|
||||||
import net.minecraft.item.ItemStack
|
import net.minecraft.item.ItemStack
|
||||||
import net.minecraft.util.NonNullList
|
import net.minecraft.util.NonNullList
|
||||||
@@ -33,10 +33,10 @@ object RecipeJarODustExtract : RecipeBaseDynamic() {
|
|||||||
|
|
||||||
if (layers != null) {
|
if (layers != null) {
|
||||||
layers.removeDust(BOTTOM)
|
layers.removeDust(BOTTOM)
|
||||||
it[first.slot] = first.stack.copy().also { stack -> ModBlocks.JAR_O_DUST.setLayersInStack(stack, layers) }
|
it[first.slot] = first.stack.copy().also { stack -> BlockJarODust.setLayersInStack(stack, layers) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getLayers(stack: ItemStack) = ModBlocks.JAR_O_DUST.getLayersFromStack(stack)
|
private fun getLayers(stack: ItemStack) = BlockJarODust.getLayersFromStack(stack)
|
||||||
}
|
}
|
||||||
|
@@ -3,6 +3,7 @@ package chylex.hee.game.territory
|
|||||||
import chylex.hee.HEE
|
import chylex.hee.HEE
|
||||||
import chylex.hee.client.util.MC
|
import chylex.hee.client.util.MC
|
||||||
import chylex.hee.game.block.BlockAbstractPortal
|
import chylex.hee.game.block.BlockAbstractPortal
|
||||||
|
import chylex.hee.game.block.interfaces.getHeeInterface
|
||||||
import chylex.hee.game.entity.damage.Damage
|
import chylex.hee.game.entity.damage.Damage
|
||||||
import chylex.hee.game.entity.damage.IDamageDealer.Companion.TITLE_WITHER
|
import chylex.hee.game.entity.damage.IDamageDealer.Companion.TITLE_WITHER
|
||||||
import chylex.hee.game.entity.damage.IDamageProcessor.Companion.DEAL_CREATIVE
|
import chylex.hee.game.entity.damage.IDamageProcessor.Companion.DEAL_CREATIVE
|
||||||
@@ -149,7 +150,7 @@ object TerritoryVoid {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entity !is LivingEntity || Pos(entity).getBlock(world) is BlockAbstractPortal) { // protecting entities inside portals should help with server lag frustrations
|
if (entity !is LivingEntity || Pos(entity).getBlock(world).getHeeInterface<BlockAbstractPortal.IInnerPortalBlock>() != null) { // protecting entities inside portals should help with server lag frustrations
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
package chylex.hee.game.world.generation.feature.basic
|
package chylex.hee.game.world.generation.feature.basic
|
||||||
|
|
||||||
import chylex.hee.game.block.BlockVoidPortalInner.Companion.TYPE
|
import chylex.hee.game.block.BlockVoidPortalInner.TYPE
|
||||||
import chylex.hee.game.block.BlockVoidPortalInner.Type.HUB
|
import chylex.hee.game.block.BlockVoidPortalInner.Type.HUB
|
||||||
import chylex.hee.game.block.BlockVoidPortalInner.Type.RETURN_ACTIVE
|
import chylex.hee.game.block.BlockVoidPortalInner.Type.RETURN_ACTIVE
|
||||||
import chylex.hee.game.block.BlockVoidPortalInner.Type.RETURN_INACTIVE
|
import chylex.hee.game.block.BlockVoidPortalInner.Type.RETURN_INACTIVE
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
package chylex.hee.game.world.generation.feature.energyshrine.piece
|
package chylex.hee.game.world.generation.feature.energyshrine.piece
|
||||||
|
|
||||||
import chylex.hee.game.Environment
|
import chylex.hee.game.Environment
|
||||||
import chylex.hee.game.block.BlockGloomrock
|
|
||||||
import chylex.hee.game.entity.technical.EntityTechnicalTrigger
|
import chylex.hee.game.entity.technical.EntityTechnicalTrigger
|
||||||
import chylex.hee.game.entity.technical.EntityTechnicalTrigger.ITriggerHandler
|
import chylex.hee.game.entity.technical.EntityTechnicalTrigger.ITriggerHandler
|
||||||
import chylex.hee.game.entity.technical.EntityTechnicalTrigger.Types.ENERGY_SHRINE_GLOBAL
|
import chylex.hee.game.entity.technical.EntityTechnicalTrigger.Types.ENERGY_SHRINE_GLOBAL
|
||||||
@@ -17,6 +16,7 @@ import chylex.hee.game.world.generation.trigger.EntityStructureTrigger
|
|||||||
import chylex.hee.game.world.util.getBlock
|
import chylex.hee.game.world.util.getBlock
|
||||||
import chylex.hee.game.world.util.getState
|
import chylex.hee.game.world.util.getState
|
||||||
import chylex.hee.game.world.util.offsetUntil
|
import chylex.hee.game.world.util.offsetUntil
|
||||||
|
import chylex.hee.init.ModTags
|
||||||
import chylex.hee.util.color.IColorGenerator
|
import chylex.hee.util.color.IColorGenerator
|
||||||
import chylex.hee.util.color.RGB
|
import chylex.hee.util.color.RGB
|
||||||
import chylex.hee.util.math.Pos
|
import chylex.hee.util.math.Pos
|
||||||
@@ -69,11 +69,11 @@ class EnergyShrineRoom_Main_Start(file: String) : EnergyShrineRoom_Generic(file)
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if (targetPos.offsetUntil(UP, PARTICLE_GLOOMROCK_CHECK_RANGE) { it.getBlock(world) is BlockGloomrock } == null) {
|
if (targetPos.offsetUntil(UP, PARTICLE_GLOOMROCK_CHECK_RANGE) { ModTags.GLOOMROCK_PARTICLES.contains(it.getBlock(world)) } == null) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if (targetPos.offsetUntil(DOWN, PARTICLE_GLOOMROCK_CHECK_RANGE) { it.getBlock(world) is BlockGloomrock } == null) {
|
if (targetPos.offsetUntil(DOWN, PARTICLE_GLOOMROCK_CHECK_RANGE) { ModTags.GLOOMROCK_PARTICLES.contains(it.getBlock(world)) } == null) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -34,8 +34,6 @@ import chylex.hee.game.block.BlockFlowerPotCustom
|
|||||||
import chylex.hee.game.block.BlockFlowerPotDeathFlower
|
import chylex.hee.game.block.BlockFlowerPotDeathFlower
|
||||||
import chylex.hee.game.block.BlockFlowerPotDeathFlowerDecaying
|
import chylex.hee.game.block.BlockFlowerPotDeathFlowerDecaying
|
||||||
import chylex.hee.game.block.BlockGloomrock
|
import chylex.hee.game.block.BlockGloomrock
|
||||||
import chylex.hee.game.block.BlockGloomrockSmooth
|
|
||||||
import chylex.hee.game.block.BlockGloomrockSmoothColored
|
|
||||||
import chylex.hee.game.block.BlockGloomrockSmoothSlab
|
import chylex.hee.game.block.BlockGloomrockSmoothSlab
|
||||||
import chylex.hee.game.block.BlockGloomrockSmoothStairs
|
import chylex.hee.game.block.BlockGloomrockSmoothStairs
|
||||||
import chylex.hee.game.block.BlockGloomtorch
|
import chylex.hee.game.block.BlockGloomtorch
|
||||||
@@ -52,7 +50,7 @@ import chylex.hee.game.block.BlockMinersBurialCube
|
|||||||
import chylex.hee.game.block.BlockMinersBurialPillar
|
import chylex.hee.game.block.BlockMinersBurialPillar
|
||||||
import chylex.hee.game.block.BlockObsidianCube
|
import chylex.hee.game.block.BlockObsidianCube
|
||||||
import chylex.hee.game.block.BlockObsidianPillar
|
import chylex.hee.game.block.BlockObsidianPillar
|
||||||
import chylex.hee.game.block.BlockPortalFrame
|
import chylex.hee.game.block.BlockPortalFrameIndestructible
|
||||||
import chylex.hee.game.block.BlockPuzzleLogic
|
import chylex.hee.game.block.BlockPuzzleLogic
|
||||||
import chylex.hee.game.block.BlockPuzzleWall
|
import chylex.hee.game.block.BlockPuzzleWall
|
||||||
import chylex.hee.game.block.BlockScaffolding
|
import chylex.hee.game.block.BlockScaffolding
|
||||||
@@ -65,17 +63,17 @@ import chylex.hee.game.block.BlockStardustOre
|
|||||||
import chylex.hee.game.block.BlockTableBase
|
import chylex.hee.game.block.BlockTableBase
|
||||||
import chylex.hee.game.block.BlockTablePedestal
|
import chylex.hee.game.block.BlockTablePedestal
|
||||||
import chylex.hee.game.block.BlockTableTile
|
import chylex.hee.game.block.BlockTableTile
|
||||||
import chylex.hee.game.block.BlockVoidPortalCrafted
|
import chylex.hee.game.block.BlockVoidPortalFrame
|
||||||
import chylex.hee.game.block.BlockVoidPortalInner
|
import chylex.hee.game.block.BlockVoidPortalInner
|
||||||
import chylex.hee.game.block.BlockVoidPortalStorage
|
import chylex.hee.game.block.BlockVoidPortalStorage
|
||||||
import chylex.hee.game.block.BlockVoidPortalStorageCrafted
|
|
||||||
import chylex.hee.game.block.BlockWallCustom
|
import chylex.hee.game.block.BlockWallCustom
|
||||||
import chylex.hee.game.block.BlockWhitebark
|
import chylex.hee.game.block.BlockWhitebark
|
||||||
import chylex.hee.game.block.BlockWhitebarkLeaves
|
import chylex.hee.game.block.BlockWhitebarkLeaves
|
||||||
import chylex.hee.game.block.BlockWhitebarkLog
|
import chylex.hee.game.block.BlockWhitebarkLog
|
||||||
import chylex.hee.game.block.BlockWhitebarkPlanks
|
|
||||||
import chylex.hee.game.block.BlockWhitebarkSapling
|
import chylex.hee.game.block.BlockWhitebarkSapling
|
||||||
import chylex.hee.game.block.HeeBlock
|
import chylex.hee.game.block.HeeBlock
|
||||||
|
import chylex.hee.game.block.HeeBlock2
|
||||||
|
import chylex.hee.game.block.builder.HeeBlockBuilder
|
||||||
import chylex.hee.game.block.entity.TileEntityAccumulationTable
|
import chylex.hee.game.block.entity.TileEntityAccumulationTable
|
||||||
import chylex.hee.game.block.entity.TileEntityExperienceTable
|
import chylex.hee.game.block.entity.TileEntityExperienceTable
|
||||||
import chylex.hee.game.block.entity.TileEntityInfusionTable
|
import chylex.hee.game.block.entity.TileEntityInfusionTable
|
||||||
@@ -84,7 +82,6 @@ import chylex.hee.game.block.fluid.FluidEnderGooPurified
|
|||||||
import chylex.hee.game.block.properties.BlockBuilders.buildAncientCobweb
|
import chylex.hee.game.block.properties.BlockBuilders.buildAncientCobweb
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildBrewingStand
|
import chylex.hee.game.block.properties.BlockBuilders.buildBrewingStand
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildCauldron
|
import chylex.hee.game.block.properties.BlockBuilders.buildCauldron
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildCorruptedEnergy
|
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildDarkLoam
|
import chylex.hee.game.block.properties.BlockBuilders.buildDarkLoam
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildDragonEgg
|
import chylex.hee.game.block.properties.BlockBuilders.buildDragonEgg
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildDryVines
|
import chylex.hee.game.block.properties.BlockBuilders.buildDryVines
|
||||||
@@ -93,49 +90,31 @@ import chylex.hee.game.block.properties.BlockBuilders.buildDustyStoneBricks
|
|||||||
import chylex.hee.game.block.properties.BlockBuilders.buildDustyStoneCracked
|
import chylex.hee.game.block.properties.BlockBuilders.buildDustyStoneCracked
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildDustyStoneDamaged
|
import chylex.hee.game.block.properties.BlockBuilders.buildDustyStoneDamaged
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildEndPortalOverride
|
import chylex.hee.game.block.properties.BlockBuilders.buildEndPortalOverride
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildEndPowderOre
|
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildEndStone
|
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildEnderSol
|
import chylex.hee.game.block.properties.BlockBuilders.buildEnderSol
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildEndermanHead
|
import chylex.hee.game.block.properties.BlockBuilders.buildEndermanHead
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildEndiumBlock
|
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildEndiumOre
|
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildEnergyCluster
|
import chylex.hee.game.block.properties.BlockBuilders.buildEnergyCluster
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildEternalFire
|
import chylex.hee.game.block.properties.BlockBuilders.buildEternalFire
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildEtherealLantern
|
import chylex.hee.game.block.properties.BlockBuilders.buildEtherealLantern
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildExperienceGate
|
import chylex.hee.game.block.properties.BlockBuilders.buildExperienceGate
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildFlowerPot
|
import chylex.hee.game.block.properties.BlockBuilders.buildFlowerPot
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildGloomrock
|
import chylex.hee.game.block.properties.BlockBuilders.buildGloomrock
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildGloomrockBricks
|
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildGloomrockSmooth
|
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildGloomtorch
|
import chylex.hee.game.block.properties.BlockBuilders.buildGloomtorch
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildGraveDirt
|
import chylex.hee.game.block.properties.BlockBuilders.buildGraveDirt
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildHumus
|
import chylex.hee.game.block.properties.BlockBuilders.buildHumus
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildIgneousPlate
|
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildIgneousRockOre
|
import chylex.hee.game.block.properties.BlockBuilders.buildIgneousRockOre
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildInfusedGlass
|
import chylex.hee.game.block.properties.BlockBuilders.buildInfusedGlass
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildJarODust
|
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildLootChest
|
import chylex.hee.game.block.properties.BlockBuilders.buildLootChest
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildMinersBurial
|
import chylex.hee.game.block.properties.BlockBuilders.buildMinersBurial
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildMinersBurialIndestructible
|
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildObsidian
|
import chylex.hee.game.block.properties.BlockBuilders.buildObsidian
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildObsidianTowerTop
|
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildObsidianVariation
|
import chylex.hee.game.block.properties.BlockBuilders.buildObsidianVariation
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildObsidianVariationLit
|
import chylex.hee.game.block.properties.BlockBuilders.buildObsidianVariationLit
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildPlant
|
import chylex.hee.game.block.properties.BlockBuilders.buildPlant
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildPortalFrame
|
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildPortalFrameCrafted
|
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildPortalInner
|
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildPuzzleLogic
|
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildPuzzleWall
|
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildScaffolding
|
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildSpawnerObsidianTowers
|
import chylex.hee.game.block.properties.BlockBuilders.buildSpawnerObsidianTowers
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildStardustOre
|
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildTable
|
import chylex.hee.game.block.properties.BlockBuilders.buildTable
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildTablePedestal
|
import chylex.hee.game.block.properties.BlockBuilders.buildTablePedestal
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildVantablock
|
import chylex.hee.game.block.properties.BlockBuilders.buildVantablock
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildWhitebark
|
import chylex.hee.game.block.properties.BlockBuilders.buildWhitebark
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildWhitebarkLeaves
|
import chylex.hee.game.block.properties.BlockBuilders.buildWhitebarkLeaves
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildWhitebarkPlanks
|
|
||||||
import chylex.hee.game.block.properties.BlockBuilders.buildWhitebarkSapling
|
import chylex.hee.game.block.properties.BlockBuilders.buildWhitebarkSapling
|
||||||
import chylex.hee.game.block.properties.CustomSkull
|
import chylex.hee.game.block.properties.CustomSkull
|
||||||
import chylex.hee.game.item.ItemAncientCobweb
|
import chylex.hee.game.item.ItemAncientCobweb
|
||||||
@@ -176,28 +155,28 @@ object ModBlocks {
|
|||||||
@JvmField val STONE_BRICK_WALL = BlockWallCustom(Blocks.STONE_BRICKS) named "stone_brick_wall"
|
@JvmField val STONE_BRICK_WALL = BlockWallCustom(Blocks.STONE_BRICKS) named "stone_brick_wall"
|
||||||
@JvmField val INFUSED_GLASS = BlockInfusedGlass(buildInfusedGlass) named "infused_glass"
|
@JvmField val INFUSED_GLASS = BlockInfusedGlass(buildInfusedGlass) named "infused_glass"
|
||||||
@JvmField val VANTABLOCK = HeeBlock(buildVantablock) named "vantablock"
|
@JvmField val VANTABLOCK = HeeBlock(buildVantablock) named "vantablock"
|
||||||
@JvmField val ENDIUM_BLOCK = BlockEndium.Block(buildEndiumBlock) named "endium_block"
|
@JvmField val ENDIUM_BLOCK = BlockEndium.Block named "endium_block"
|
||||||
@JvmField val ENDERSOL = BlockEndersol(buildEnderSol, mergeBottom = Blocks.END_STONE) named "endersol"
|
@JvmField val ENDERSOL = BlockEndersol(buildEnderSol, mergeBottom = Blocks.END_STONE) named "endersol"
|
||||||
@JvmField val HUMUS = BlockHumus(buildHumus, mergeBottom = ENDERSOL) named "humus"
|
@JvmField val HUMUS = BlockHumus(buildHumus, mergeBottom = ENDERSOL) named "humus"
|
||||||
|
|
||||||
// Blocks: Building (Gloomrock)
|
// Blocks: Building (Gloomrock)
|
||||||
|
|
||||||
@JvmField val GLOOMROCK = BlockGloomrock(buildGloomrock) named "gloomrock"
|
@JvmField val GLOOMROCK = BlockGloomrock named "gloomrock"
|
||||||
@JvmField val GLOOMROCK_BRICKS = BlockGloomrock(buildGloomrockBricks) named "gloomrock_bricks"
|
@JvmField val GLOOMROCK_BRICKS = BlockGloomrock.BRICKS named "gloomrock_bricks"
|
||||||
@JvmField val GLOOMROCK_BRICK_STAIRS = BlockStairsCustom(GLOOMROCK_BRICKS) named "gloomrock_brick_stairs"
|
@JvmField val GLOOMROCK_BRICK_STAIRS = BlockStairsCustom(GLOOMROCK_BRICKS) named "gloomrock_brick_stairs" // TODO tags for all gloomrock?
|
||||||
@JvmField val GLOOMROCK_BRICK_SLAB = BlockSlabCustom(GLOOMROCK_BRICKS) named "gloomrock_brick_slab"
|
@JvmField val GLOOMROCK_BRICK_SLAB = BlockSlabCustom(GLOOMROCK_BRICKS) named "gloomrock_brick_slab"
|
||||||
@JvmField val GLOOMROCK_SMOOTH = BlockGloomrockSmooth(buildGloomrockSmooth) named "gloomrock_smooth"
|
@JvmField val GLOOMROCK_SMOOTH = BlockGloomrock.SMOOTH named "gloomrock_smooth"
|
||||||
@JvmField val GLOOMROCK_SMOOTH_STAIRS = BlockGloomrockSmoothStairs(GLOOMROCK_SMOOTH) named "gloomrock_smooth_stairs"
|
@JvmField val GLOOMROCK_SMOOTH_STAIRS = BlockGloomrockSmoothStairs(GLOOMROCK_SMOOTH) named "gloomrock_smooth_stairs"
|
||||||
@JvmField val GLOOMROCK_SMOOTH_SLAB = BlockGloomrockSmoothSlab(GLOOMROCK_SMOOTH) named "gloomrock_smooth_slab"
|
@JvmField val GLOOMROCK_SMOOTH_SLAB = BlockGloomrockSmoothSlab(GLOOMROCK_SMOOTH) named "gloomrock_smooth_slab"
|
||||||
@JvmField val GLOOMROCK_SMOOTH_RED = BlockGloomrockSmoothColored(buildGloomrockSmooth) named "gloomrock_smooth_red"
|
@JvmField val GLOOMROCK_SMOOTH_RED = BlockGloomrock.SMOOTH_COLORED named "gloomrock_smooth_red"
|
||||||
@JvmField val GLOOMROCK_SMOOTH_ORANGE = BlockGloomrockSmoothColored(buildGloomrockSmooth) named "gloomrock_smooth_orange"
|
@JvmField val GLOOMROCK_SMOOTH_ORANGE = BlockGloomrock.SMOOTH_COLORED named "gloomrock_smooth_orange"
|
||||||
@JvmField val GLOOMROCK_SMOOTH_YELLOW = BlockGloomrockSmoothColored(buildGloomrockSmooth) named "gloomrock_smooth_yellow"
|
@JvmField val GLOOMROCK_SMOOTH_YELLOW = BlockGloomrock.SMOOTH_COLORED named "gloomrock_smooth_yellow"
|
||||||
@JvmField val GLOOMROCK_SMOOTH_GREEN = BlockGloomrockSmoothColored(buildGloomrockSmooth) named "gloomrock_smooth_green"
|
@JvmField val GLOOMROCK_SMOOTH_GREEN = BlockGloomrock.SMOOTH_COLORED named "gloomrock_smooth_green"
|
||||||
@JvmField val GLOOMROCK_SMOOTH_CYAN = BlockGloomrockSmoothColored(buildGloomrockSmooth) named "gloomrock_smooth_cyan"
|
@JvmField val GLOOMROCK_SMOOTH_CYAN = BlockGloomrock.SMOOTH_COLORED named "gloomrock_smooth_cyan"
|
||||||
@JvmField val GLOOMROCK_SMOOTH_BLUE = BlockGloomrockSmoothColored(buildGloomrockSmooth) named "gloomrock_smooth_blue"
|
@JvmField val GLOOMROCK_SMOOTH_BLUE = BlockGloomrock.SMOOTH_COLORED named "gloomrock_smooth_blue"
|
||||||
@JvmField val GLOOMROCK_SMOOTH_PURPLE = BlockGloomrockSmoothColored(buildGloomrockSmooth) named "gloomrock_smooth_purple"
|
@JvmField val GLOOMROCK_SMOOTH_PURPLE = BlockGloomrock.SMOOTH_COLORED named "gloomrock_smooth_purple"
|
||||||
@JvmField val GLOOMROCK_SMOOTH_MAGENTA = BlockGloomrockSmoothColored(buildGloomrockSmooth) named "gloomrock_smooth_magenta"
|
@JvmField val GLOOMROCK_SMOOTH_MAGENTA = BlockGloomrock.SMOOTH_COLORED named "gloomrock_smooth_magenta"
|
||||||
@JvmField val GLOOMROCK_SMOOTH_WHITE = BlockGloomrockSmoothColored(buildGloomrockSmooth) named "gloomrock_smooth_white"
|
@JvmField val GLOOMROCK_SMOOTH_WHITE = BlockGloomrock.SMOOTH_COLORED named "gloomrock_smooth_white"
|
||||||
@JvmField val GLOOMTORCH = BlockGloomtorch(buildGloomtorch) named "gloomtorch"
|
@JvmField val GLOOMTORCH = BlockGloomtorch(buildGloomtorch) named "gloomtorch"
|
||||||
|
|
||||||
// Blocks: Building (Dusty Stone)
|
// Blocks: Building (Dusty Stone)
|
||||||
@@ -215,19 +194,19 @@ object ModBlocks {
|
|||||||
|
|
||||||
@JvmField val OBSIDIAN_STAIRS = BlockStairsCustom(Blocks.OBSIDIAN) named "obsidian_stairs"
|
@JvmField val OBSIDIAN_STAIRS = BlockStairsCustom(Blocks.OBSIDIAN) named "obsidian_stairs"
|
||||||
@JvmField val OBSIDIAN_FALLING = BlockFallingObsidian(buildObsidian) named "obsidian_falling"
|
@JvmField val OBSIDIAN_FALLING = BlockFallingObsidian(buildObsidian) named "obsidian_falling"
|
||||||
@JvmField val OBSIDIAN_SMOOTH = BlockObsidianCube(buildObsidianVariation) named "obsidian_smooth"
|
@JvmField val OBSIDIAN_SMOOTH = BlockObsidianCube named "obsidian_smooth"
|
||||||
@JvmField val OBSIDIAN_CHISELED = BlockObsidianCube(buildObsidianVariation) named "obsidian_chiseled"
|
@JvmField val OBSIDIAN_CHISELED = BlockObsidianCube named "obsidian_chiseled"
|
||||||
@JvmField val OBSIDIAN_PILLAR = BlockObsidianPillar(buildObsidianVariation) named "obsidian_pillar"
|
@JvmField val OBSIDIAN_PILLAR = BlockObsidianPillar(buildObsidianVariation) named "obsidian_pillar"
|
||||||
@JvmField val OBSIDIAN_SMOOTH_LIT = BlockObsidianCube.Lit(buildObsidianVariationLit, OBSIDIAN_SMOOTH) named "obsidian_smooth_lit"
|
@JvmField val OBSIDIAN_SMOOTH_LIT = BlockObsidianCube.Lit(OBSIDIAN_SMOOTH) named "obsidian_smooth_lit"
|
||||||
@JvmField val OBSIDIAN_CHISELED_LIT = BlockObsidianCube.Lit(buildObsidianVariationLit, OBSIDIAN_CHISELED) named "obsidian_chiseled_lit"
|
@JvmField val OBSIDIAN_CHISELED_LIT = BlockObsidianCube.Lit(OBSIDIAN_CHISELED) named "obsidian_chiseled_lit"
|
||||||
@JvmField val OBSIDIAN_PILLAR_LIT = BlockObsidianPillar.Lit(buildObsidianVariationLit, OBSIDIAN_PILLAR) named "obsidian_pillar_lit"
|
@JvmField val OBSIDIAN_PILLAR_LIT = BlockObsidianPillar.Lit(buildObsidianVariationLit, OBSIDIAN_PILLAR) named "obsidian_pillar_lit"
|
||||||
@JvmField val OBSIDIAN_TOWER_TOP = BlockObsidianCube.TowerTop(buildObsidianTowerTop, OBSIDIAN_CHISELED) named "obsidian_tower_top"
|
@JvmField val OBSIDIAN_TOWER_TOP = BlockObsidianCube.TowerTop(OBSIDIAN_CHISELED) named "obsidian_tower_top"
|
||||||
|
|
||||||
// Blocks: Building (End Stone)
|
// Blocks: Building (End Stone)
|
||||||
|
|
||||||
@JvmField val END_STONE_INFESTED = BlockEndStoneCustom(buildEndStone, MaterialColor.RED) named "end_stone_infested"
|
@JvmField val END_STONE_INFESTED = BlockEndStoneCustom.INFESTED named "end_stone_infested"
|
||||||
@JvmField val END_STONE_BURNED = BlockEndStoneCustom(buildEndStone, MaterialColor.ADOBE /* RENAME ORANGE */) named "end_stone_burned"
|
@JvmField val END_STONE_BURNED = BlockEndStoneCustom.BURNED named "end_stone_burned"
|
||||||
@JvmField val END_STONE_ENCHANTED = BlockEndStoneCustom(buildEndStone, MaterialColor.PURPLE) named "end_stone_enchanted"
|
@JvmField val END_STONE_ENCHANTED = BlockEndStoneCustom.ENCHANTED named "end_stone_enchanted"
|
||||||
|
|
||||||
// Blocks: Building (Dark Loam)
|
// Blocks: Building (Dark Loam)
|
||||||
|
|
||||||
@@ -243,18 +222,18 @@ object ModBlocks {
|
|||||||
// Blocks: Building (Wood)
|
// Blocks: Building (Wood)
|
||||||
|
|
||||||
@JvmField val WHITEBARK_LOG = BlockWhitebarkLog(buildWhitebark) named "whitebark_log"
|
@JvmField val WHITEBARK_LOG = BlockWhitebarkLog(buildWhitebark) named "whitebark_log"
|
||||||
@JvmField val WHITEBARK = BlockWhitebark(buildWhitebark) named "whitebark"
|
@JvmField val WHITEBARK = BlockWhitebark.BARK named "whitebark"
|
||||||
@JvmField val WHITEBARK_PLANKS = BlockWhitebarkPlanks(buildWhitebarkPlanks) named "whitebark_planks"
|
@JvmField val WHITEBARK_PLANKS = BlockWhitebark.PLANKS named "whitebark_planks"
|
||||||
@JvmField val WHITEBARK_STAIRS = BlockFlammableStairs(WHITEBARK_PLANKS) named "whitebark_stairs"
|
@JvmField val WHITEBARK_STAIRS = BlockFlammableStairs(WHITEBARK_PLANKS) named "whitebark_stairs"
|
||||||
@JvmField val WHITEBARK_SLAB = BlockFlammableSlab(WHITEBARK_PLANKS) named "whitebark_slab"
|
@JvmField val WHITEBARK_SLAB = BlockFlammableSlab(WHITEBARK_PLANKS) named "whitebark_slab"
|
||||||
|
|
||||||
// Blocks: Building (Miner's Burial)
|
// Blocks: Building (Miner's Burial)
|
||||||
|
|
||||||
@JvmField val MINERS_BURIAL_BLOCK_PLAIN = BlockMinersBurialCube(buildMinersBurial) named "miners_burial_block_plain"
|
@JvmField val MINERS_BURIAL_BLOCK_PLAIN = BlockMinersBurialCube named "miners_burial_block_plain"
|
||||||
@JvmField val MINERS_BURIAL_BLOCK_CHISELED = BlockMinersBurialCube(buildMinersBurial) named "miners_burial_block_chiseled"
|
@JvmField val MINERS_BURIAL_BLOCK_CHISELED = BlockMinersBurialCube named "miners_burial_block_chiseled"
|
||||||
@JvmField val MINERS_BURIAL_BLOCK_PILLAR = BlockMinersBurialPillar(buildMinersBurial) named "miners_burial_block_pillar"
|
@JvmField val MINERS_BURIAL_BLOCK_PILLAR = BlockMinersBurialPillar(buildMinersBurial) named "miners_burial_block_pillar"
|
||||||
@JvmField val MINERS_BURIAL_BLOCK_JAIL = BlockMinersBurialCube(buildMinersBurialIndestructible) named "miners_burial_block_jail"
|
@JvmField val MINERS_BURIAL_BLOCK_JAIL = BlockMinersBurialCube.INDESCRUCTIBLE named "miners_burial_block_jail"
|
||||||
@JvmField val MINERS_BURIAL_ALTAR = BlockMinersBurialAltar(buildMinersBurialIndestructible) named "miners_burial_altar"
|
@JvmField val MINERS_BURIAL_ALTAR = BlockMinersBurialAltar named "miners_burial_altar"
|
||||||
|
|
||||||
// Blocks: Fluids
|
// Blocks: Fluids
|
||||||
|
|
||||||
@@ -267,20 +246,20 @@ object ModBlocks {
|
|||||||
|
|
||||||
// Blocks: Interactive (Storage)
|
// Blocks: Interactive (Storage)
|
||||||
|
|
||||||
@JvmField val JAR_O_DUST = BlockJarODust(buildJarODust) named "jar_o_dust"
|
@JvmField val JAR_O_DUST = BlockJarODust named "jar_o_dust"
|
||||||
@JvmField val DARK_CHEST = BlockDarkChest(buildGloomrock) named "dark_chest"
|
@JvmField val DARK_CHEST = BlockDarkChest(buildGloomrock) named "dark_chest"
|
||||||
@JvmField val LOOT_CHEST = BlockLootChest(buildLootChest) named "loot_chest"
|
@JvmField val LOOT_CHEST = BlockLootChest(buildLootChest) named "loot_chest"
|
||||||
|
|
||||||
// Blocks: Interactive (Puzzle)
|
// Blocks: Interactive (Puzzle)
|
||||||
|
|
||||||
@JvmField val PUZZLE_WALL = BlockPuzzleWall(buildPuzzleWall) named "puzzle_block_wall"
|
@JvmField val PUZZLE_WALL = BlockPuzzleWall named "puzzle_block_wall"
|
||||||
@JvmField val PUZZLE_PLAIN = BlockPuzzleLogic.Plain(buildPuzzleLogic) named "puzzle_block_plain"
|
@JvmField val PUZZLE_PLAIN = BlockPuzzleLogic.Plain named "puzzle_block_plain"
|
||||||
@JvmField val PUZZLE_BURST_3 = BlockPuzzleLogic.Burst(buildPuzzleLogic, radius = 1) named "puzzle_block_burst_3"
|
@JvmField val PUZZLE_BURST_3 = BlockPuzzleLogic.Burst(radius = 1) named "puzzle_block_burst_3"
|
||||||
@JvmField val PUZZLE_BURST_5 = BlockPuzzleLogic.Burst(buildPuzzleLogic, radius = 2) named "puzzle_block_burst_5"
|
@JvmField val PUZZLE_BURST_5 = BlockPuzzleLogic.Burst(radius = 2) named "puzzle_block_burst_5"
|
||||||
@JvmField val PUZZLE_REDIRECT_1 = BlockPuzzleLogic.RedirectSome.R1(buildPuzzleLogic) named "puzzle_block_redirect_1"
|
@JvmField val PUZZLE_REDIRECT_1 = BlockPuzzleLogic.RedirectOne named "puzzle_block_redirect_1"
|
||||||
@JvmField val PUZZLE_REDIRECT_2 = BlockPuzzleLogic.RedirectSome.R2(buildPuzzleLogic) named "puzzle_block_redirect_2"
|
@JvmField val PUZZLE_REDIRECT_2 = BlockPuzzleLogic.RedirectTwo named "puzzle_block_redirect_2"
|
||||||
@JvmField val PUZZLE_REDIRECT_4 = BlockPuzzleLogic.RedirectAll(buildPuzzleLogic) named "puzzle_block_redirect_4"
|
@JvmField val PUZZLE_REDIRECT_4 = BlockPuzzleLogic.RedirectAll named "puzzle_block_redirect_4"
|
||||||
@JvmField val PUZZLE_TELEPORT = BlockPuzzleLogic.Teleport(buildPuzzleLogic) named "puzzle_block_teleport"
|
@JvmField val PUZZLE_TELEPORT = BlockPuzzleLogic.Teleport named "puzzle_block_teleport"
|
||||||
|
|
||||||
// Blocks: Interactive (Gates)
|
// Blocks: Interactive (Gates)
|
||||||
|
|
||||||
@@ -290,14 +269,14 @@ object ModBlocks {
|
|||||||
// Blocks: Interactive (Uncategorized)
|
// Blocks: Interactive (Uncategorized)
|
||||||
|
|
||||||
@JvmField val INFUSED_TNT = BlockInfusedTNT() named "infused_tnt"
|
@JvmField val INFUSED_TNT = BlockInfusedTNT() named "infused_tnt"
|
||||||
@JvmField val IGNEOUS_PLATE = BlockIgneousPlate(buildIgneousPlate) named "igneous_plate"
|
@JvmField val IGNEOUS_PLATE = BlockIgneousPlate named "igneous_plate"
|
||||||
@JvmField val ENHANCED_BREWING_STAND = BlockBrewingStandCustom(buildBrewingStand) named "enhanced_brewing_stand"
|
@JvmField val ENHANCED_BREWING_STAND = BlockBrewingStandCustom(buildBrewingStand) named "enhanced_brewing_stand"
|
||||||
|
|
||||||
// Blocks: Ores
|
// Blocks: Ores
|
||||||
|
|
||||||
@JvmField val END_POWDER_ORE = BlockEndPowderOre(buildEndPowderOre) named "end_powder_ore"
|
@JvmField val END_POWDER_ORE = BlockEndPowderOre named "end_powder_ore"
|
||||||
@JvmField val ENDIUM_ORE = BlockEndium.Ore(buildEndiumOre) named "endium_ore"
|
@JvmField val ENDIUM_ORE = BlockEndium.Ore named "endium_ore"
|
||||||
@JvmField val STARDUST_ORE = BlockStardustOre(buildStardustOre) named "stardust_ore"
|
@JvmField val STARDUST_ORE = BlockStardustOre named "stardust_ore"
|
||||||
@JvmField val IGNEOUS_ROCK_ORE = BlockIgneousRockOre(buildIgneousRockOre) named "igneous_rock_ore"
|
@JvmField val IGNEOUS_ROCK_ORE = BlockIgneousRockOre(buildIgneousRockOre) named "igneous_rock_ore"
|
||||||
|
|
||||||
// Blocks: Decorative (Trees)
|
// Blocks: Decorative (Trees)
|
||||||
@@ -340,21 +319,21 @@ object ModBlocks {
|
|||||||
|
|
||||||
// Blocks: Portals
|
// Blocks: Portals
|
||||||
|
|
||||||
@JvmField val END_PORTAL_INNER = BlockEndPortalInner(buildPortalInner) named "end_portal_inner"
|
@JvmField val END_PORTAL_INNER = BlockEndPortalInner named "end_portal_inner"
|
||||||
@JvmField val END_PORTAL_FRAME = BlockPortalFrame(buildPortalFrame) named "end_portal_frame"
|
@JvmField val END_PORTAL_FRAME = BlockPortalFrameIndestructible named "end_portal_frame"
|
||||||
@JvmField val END_PORTAL_ACCEPTOR = BlockEndPortalAcceptor(buildPortalFrame) named "end_portal_acceptor"
|
@JvmField val END_PORTAL_ACCEPTOR = BlockEndPortalAcceptor named "end_portal_acceptor"
|
||||||
|
|
||||||
@JvmField val VOID_PORTAL_INNER = BlockVoidPortalInner(buildPortalInner) named "void_portal_inner"
|
@JvmField val VOID_PORTAL_INNER = BlockVoidPortalInner named "void_portal_inner"
|
||||||
@JvmField val VOID_PORTAL_FRAME = BlockPortalFrame(buildPortalFrame) named "void_portal_frame"
|
@JvmField val VOID_PORTAL_FRAME = BlockVoidPortalFrame.Indestructible named "void_portal_frame"
|
||||||
@JvmField val VOID_PORTAL_STORAGE = BlockVoidPortalStorage(buildPortalFrame) named "void_portal_storage"
|
@JvmField val VOID_PORTAL_STORAGE = BlockVoidPortalStorage.Indestructible named "void_portal_storage"
|
||||||
|
|
||||||
@JvmField val VOID_PORTAL_FRAME_CRAFTED = BlockVoidPortalCrafted(buildPortalFrameCrafted) named "void_portal_frame_crafted"
|
@JvmField val VOID_PORTAL_FRAME_CRAFTED = BlockVoidPortalFrame.Crafted named "void_portal_frame_crafted"
|
||||||
@JvmField val VOID_PORTAL_STORAGE_CRAFTED = BlockVoidPortalStorageCrafted(buildPortalFrameCrafted) named "void_portal_storage_crafted"
|
@JvmField val VOID_PORTAL_STORAGE_CRAFTED = BlockVoidPortalStorage.Crafted named "void_portal_storage_crafted"
|
||||||
|
|
||||||
// Blocks: Energy
|
// Blocks: Energy
|
||||||
|
|
||||||
@JvmField val ENERGY_CLUSTER = BlockEnergyCluster(buildEnergyCluster) named "energy_cluster"
|
@JvmField val ENERGY_CLUSTER = BlockEnergyCluster(buildEnergyCluster) named "energy_cluster"
|
||||||
@JvmField val CORRUPTED_ENERGY = BlockCorruptedEnergy(buildCorruptedEnergy) named "corrupted_energy"
|
@JvmField val CORRUPTED_ENERGY = BlockCorruptedEnergy named "corrupted_energy"
|
||||||
|
|
||||||
// Blocks: Tables
|
// Blocks: Tables
|
||||||
|
|
||||||
@@ -375,7 +354,7 @@ object ModBlocks {
|
|||||||
// Blocks: Utilities
|
// Blocks: Utilities
|
||||||
|
|
||||||
@JvmField val ETERNAL_FIRE = BlockEternalFire(buildEternalFire) named "eternal_fire"
|
@JvmField val ETERNAL_FIRE = BlockEternalFire(buildEternalFire) named "eternal_fire"
|
||||||
@JvmField val SCAFFOLDING = BlockScaffolding.create(buildScaffolding) named "scaffolding"
|
@JvmField val SCAFFOLDING = BlockScaffolding named "scaffolding"
|
||||||
|
|
||||||
// Registry
|
// Registry
|
||||||
|
|
||||||
@@ -586,6 +565,10 @@ object ModBlocks {
|
|||||||
private val temporaryItemBlocks = mutableListOf<BlockItem>()
|
private val temporaryItemBlocks = mutableListOf<BlockItem>()
|
||||||
private val overrideBlocks = mutableListOf<Block>()
|
private val overrideBlocks = mutableListOf<Block>()
|
||||||
|
|
||||||
|
private infix fun HeeBlockBuilder.named(registryName: String): HeeBlock2 {
|
||||||
|
return this.build() named registryName
|
||||||
|
}
|
||||||
|
|
||||||
private inline fun Block.override(vanillaBlock: Block, itemBlockConstructor: ((Block) -> BlockItem?)) = apply {
|
private inline fun Block.override(vanillaBlock: Block, itemBlockConstructor: ((Block) -> BlockItem?)) = apply {
|
||||||
this.useVanillaName(vanillaBlock)
|
this.useVanillaName(vanillaBlock)
|
||||||
overrideBlocks.add(this)
|
overrideBlocks.add(this)
|
||||||
|
15
src/main/java/chylex/hee/init/ModTags.kt
Normal file
15
src/main/java/chylex/hee/init/ModTags.kt
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package chylex.hee.init
|
||||||
|
|
||||||
|
import chylex.hee.game.Resource
|
||||||
|
import net.minecraft.block.Block
|
||||||
|
import net.minecraft.tags.BlockTags
|
||||||
|
import net.minecraft.tags.ITag.INamedTag
|
||||||
|
|
||||||
|
object ModTags {
|
||||||
|
@JvmField val GLOOMROCK_PARTICLES = tag("gloomrock_particles")
|
||||||
|
@JvmField val VOID_PORTAL_FRAME_CRAFTED = tag("void_portal_frame_crafted")
|
||||||
|
|
||||||
|
private fun tag(name: String): INamedTag<Block> {
|
||||||
|
return BlockTags.createOptional(Resource.Custom(name))
|
||||||
|
}
|
||||||
|
}
|
@@ -1,5 +1,6 @@
|
|||||||
package chylex.hee.mixin;
|
package chylex.hee.mixin;
|
||||||
|
|
||||||
|
import chylex.hee.game.block.interfaces.IBlockWithInterfaces;
|
||||||
import chylex.hee.game.block.logic.IBlockDynamicHardness;
|
import chylex.hee.game.block.logic.IBlockDynamicHardness;
|
||||||
import net.minecraft.block.AbstractBlock.AbstractBlockState;
|
import net.minecraft.block.AbstractBlock.AbstractBlockState;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
@@ -19,8 +20,13 @@ public abstract class HookBlockHardness {
|
|||||||
final BlockState state = world.getBlockState(pos);
|
final BlockState state = world.getBlockState(pos);
|
||||||
final Block block = state.getBlock();
|
final Block block = state.getBlock();
|
||||||
|
|
||||||
if (block instanceof IBlockDynamicHardness) {
|
if (block instanceof IBlockWithInterfaces) {
|
||||||
ci.setReturnValue(Float.valueOf(((IBlockDynamicHardness)block).getBlockHardness(world, pos, state, ci.getReturnValueF())));
|
final IBlockWithInterfaces blockWithInterfaces = (IBlockWithInterfaces)block;
|
||||||
|
final IBlockDynamicHardness dynamicHardness = (IBlockDynamicHardness)blockWithInterfaces.getInterface(IBlockDynamicHardness.class);
|
||||||
|
|
||||||
|
if (dynamicHardness != null) {
|
||||||
|
ci.setReturnValue(Float.valueOf(dynamicHardness.getBlockHardness(world, pos, state, ci.getReturnValueF())));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user