mirror of
https://github.com/chylex/Hardcore-Ender-Expansion-2.git
synced 2025-09-15 14:32:09 +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
|
||||
7d84dc443a052e349593b71d2c0a523e75396cdf data/hee/loot_tables/blocks/whitebark_slab.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
|
||||
479189f9b35a3c8f795539daf6a1809130242c5b data/minecraft/tags/blocks/flower_pots.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) {
|
||||
override fun registerModels() {
|
||||
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) {
|
||||
override fun registerStatesAndModels() {
|
||||
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) {
|
||||
override fun registerModels() {
|
||||
for (item in ModItems.ALL) {
|
||||
(item as? IHeeItem)?.model?.let {
|
||||
registerModel(item, it)
|
||||
}
|
||||
(item as? IHeeItem)?.let { registerModel(item, it.model) }
|
||||
}
|
||||
|
||||
for (block in ModBlocks.ALL) {
|
||||
(block as? IHeeBlock)?.model?.itemModel?.let {
|
||||
registerModel(if (it.asItem) block.asItem() else block, it.model)
|
||||
}
|
||||
(block as? IHeeBlock)
|
||||
?.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.TerritoryVoidDebug
|
||||
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.CommandClientScaffolding
|
||||
import chylex.hee.game.command.server.CommandServerInstability
|
||||
@@ -45,9 +43,8 @@ internal object Debug : IDebugModule {
|
||||
CommandServerTestWorld
|
||||
)
|
||||
|
||||
override fun createScaffoldingBlock(builder: BlockBuilder): HeeBlock {
|
||||
return BlockScaffoldingDebug(builder)
|
||||
}
|
||||
override val scaffoldingBlockBehavior
|
||||
get() = BlockScaffoldingDebug
|
||||
|
||||
@SubscribeEvent
|
||||
fun onClientSetup(@Suppress("UNUSED_PARAMETER") e: FMLClientSetupEvent) {
|
||||
|
@@ -2,7 +2,7 @@ package chylex.hee.game.block
|
||||
|
||||
import chylex.hee.debug.PowerShell
|
||||
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.world.generation.structure.file.StructureFile
|
||||
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.Util
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.util.math.BlockRayTraceResult
|
||||
import net.minecraft.util.text.StringTextComponent
|
||||
import net.minecraft.util.text.TextFormatting
|
||||
import net.minecraft.world.World
|
||||
import java.nio.file.Files
|
||||
|
||||
class BlockScaffoldingDebug(builder: BlockBuilder) : BlockScaffolding(builder) {
|
||||
override fun onBlockActivated(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, hit: BlockRayTraceResult): ActionResultType {
|
||||
object BlockScaffoldingDebug : IPlayerUseBlockComponent {
|
||||
override fun use(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, hand: Hand): ActionResultType {
|
||||
if (world.isRemote && player.isSneaking && !player.abilities.isFlying) {
|
||||
val palette = CommandClientScaffolding.currentPalette
|
||||
|
||||
@@ -54,7 +53,7 @@ class BlockScaffoldingDebug(builder: BlockBuilder) : BlockScaffolding(builder) {
|
||||
val box = BoundingBox(minPos, maxPos)
|
||||
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()
|
||||
|
||||
CompressedStreamTools.write(structureTag, structureFile)
|
||||
|
@@ -5,7 +5,7 @@ import chylex.hee.game.block.properties.BlockDrop
|
||||
import net.minecraft.block.Block
|
||||
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
|
||||
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
|
||||
|
||||
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.BlockModel
|
||||
import chylex.hee.game.block.properties.BlockRenderLayer
|
||||
import chylex.hee.game.block.properties.BlockRenderLayer.SOLID
|
||||
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.tags.ITag.INamedTag
|
||||
|
||||
@@ -17,7 +18,7 @@ interface IHeeBlock {
|
||||
val localizationExtra: Map<String, String>
|
||||
get() = emptyMap()
|
||||
|
||||
val model: IBlockStateModel
|
||||
val model: IBlockStateModelSupplier
|
||||
get() = BlockModel.Cube
|
||||
|
||||
val renderLayer: BlockRenderLayer
|
||||
@@ -31,4 +32,14 @@ interface IHeeBlock {
|
||||
|
||||
val tags: List<INamedTag<Block>>
|
||||
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
|
||||
|
||||
import chylex.hee.game.block.interfaces.IBlockInterface
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.IBlockReader
|
||||
|
||||
interface IBlockDynamicHardness {
|
||||
interface IBlockDynamicHardness : IBlockInterface {
|
||||
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
|
||||
|
||||
interface IBlockStateModel {
|
||||
import net.minecraft.block.Block
|
||||
|
||||
interface IBlockStateModel : IBlockStateModelSupplier {
|
||||
val blockState: BlockStatePreset
|
||||
val blockModel: BlockModel
|
||||
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.util.text.ITextComponent
|
||||
import net.minecraft.world.World
|
||||
import net.minecraft.world.IBlockReader
|
||||
|
||||
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.util.text.ITextComponent
|
||||
import net.minecraft.world.World
|
||||
import net.minecraft.world.IBlockReader
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
@@ -1,13 +1,11 @@
|
||||
package chylex.hee.system
|
||||
|
||||
import chylex.hee.game.block.HeeBlock
|
||||
import chylex.hee.game.block.properties.BlockBuilder
|
||||
import chylex.hee.game.block.components.IPlayerUseBlockComponent
|
||||
import chylex.hee.game.command.IClientCommand
|
||||
import chylex.hee.game.command.ICommand
|
||||
|
||||
interface IDebugModule {
|
||||
val clientCommands: List<IClientCommand>
|
||||
val serverCommands: List<ICommand>
|
||||
|
||||
fun createScaffoldingBlock(builder: BlockBuilder): HeeBlock
|
||||
val scaffoldingBlockBehavior: IPlayerUseBlockComponent?
|
||||
}
|
||||
|
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.block.BlockAbstractPortal
|
||||
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.mechanics.energy.IClusterOracleItem
|
||||
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
|
||||
|
||||
@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 LINE_SPACING = 7
|
||||
|
||||
@@ -147,7 +148,7 @@ object OverlayRenderer {
|
||||
clusterLookedAt = pos.getTile(world)
|
||||
e.isCanceled = true
|
||||
}
|
||||
else if (block is BlockAbstractPortal) {
|
||||
else if (block.getHeeInterface<BlockAbstractPortal.IInnerPortalBlock>() != null) {
|
||||
e.isCanceled = true
|
||||
}
|
||||
}
|
||||
|
@@ -1,9 +1,9 @@
|
||||
package chylex.hee.client.render.block
|
||||
|
||||
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.IVoidPortalController
|
||||
import chylex.hee.game.block.BlockVoidPortalInner.TYPE
|
||||
import chylex.hee.game.block.BlockVoidPortalInner.Type.HUB
|
||||
import chylex.hee.game.block.BlockVoidPortalInner.Type.RETURN_ACTIVE
|
||||
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
|
||||
|
||||
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.BlockStateModel
|
||||
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.allInBox
|
||||
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.BlockState
|
||||
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.tags.BlockTags
|
||||
import net.minecraft.tileentity.TileEntity
|
||||
import net.minecraft.util.math.AxisAlignedBB
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.util.math.shapes.ISelectionContext
|
||||
import net.minecraft.util.math.shapes.VoxelShape
|
||||
import net.minecraft.world.IBlockReader
|
||||
import net.minecraft.util.math.shapes.VoxelShapes
|
||||
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 {
|
||||
const val MAX_DISTANCE_FROM_FRAME = 6.0
|
||||
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
|
||||
|
||||
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>? {
|
||||
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 {
|
||||
val clientAnimationProgress: 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.PASSTHROUGH
|
||||
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.properties.BlockBuilder
|
||||
import chylex.hee.game.block.properties.BlockDrop
|
||||
import chylex.hee.game.block.properties.BlockModel
|
||||
import chylex.hee.game.block.properties.BlockStateModel
|
||||
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.with
|
||||
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.setState
|
||||
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.removeItem
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.block.BlockRenderType.INVISIBLE
|
||||
import net.minecraft.block.BlockState
|
||||
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.state.StateContainer.Builder
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.IBlockReader
|
||||
import net.minecraft.world.World
|
||||
import net.minecraft.world.server.ServerWorld
|
||||
import java.util.Random
|
||||
|
||||
class BlockCorruptedEnergy(builder: BlockBuilder) : HeeBlock(builder) {
|
||||
companion object {
|
||||
private const val MIN_LEVEL = 0
|
||||
private const val MAX_LEVEL = 20
|
||||
object BlockCorruptedEnergy : HeeBlockBuilder() {
|
||||
private const val MIN_LEVEL = 0
|
||||
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
|
||||
private const val MIN_TICK_RATE = 1
|
||||
material = Materials.CORRUPTED_ENERGY
|
||||
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)
|
||||
private val DAMAGE_PART_MAGIC = Damage(MAGIC_TYPE, NUDITY_DANGER, RAPID_DAMAGE(2))
|
||||
drop = BlockDrop.Nothing
|
||||
|
||||
private val PARTICLE_CORRUPTION = ParticleSpawnerCustom(
|
||||
type = ParticleCorruptedEnergy,
|
||||
pos = InBox(0.75F),
|
||||
mot = InBox(0.05F),
|
||||
hideOnMinimalSetting = false
|
||||
)
|
||||
components.states.set(LEVEL, MIN_LEVEL)
|
||||
|
||||
private fun tickRateForLevel(level: Int): Int {
|
||||
return (MAX_TICK_RATE - (level / 2)).coerceAtLeast(MIN_TICK_RATE)
|
||||
components.renderType = INVISIBLE
|
||||
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 {
|
||||
return CustomCreatureType.isDemon(entity) || CustomCreatureType.isShadow(entity) || entity is IImmuneToCorruptedEnergy
|
||||
components.scheduledTick = object : IBlockScheduledTickComponent {
|
||||
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
|
||||
get() = LocalizationStrategy.None
|
||||
|
||||
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)
|
||||
private fun isEntityTolerant(entity: LivingEntity): Boolean {
|
||||
return CustomCreatureType.isDemon(entity) || CustomCreatureType.isShadow(entity) || entity is IImmuneToCorruptedEnergy
|
||||
}
|
||||
|
||||
// Utility methods
|
||||
@@ -97,19 +167,19 @@ class BlockCorruptedEnergy(builder: BlockBuilder) : HeeBlock(builder) {
|
||||
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) {
|
||||
return FAIL
|
||||
}
|
||||
else if (level > MAX_LEVEL) {
|
||||
return spawnCorruptedEnergy(world, pos, MAX_LEVEL)
|
||||
return spawn(world, pos, MAX_LEVEL)
|
||||
}
|
||||
|
||||
val currentState = pos.getState(world)
|
||||
val currentBlock = currentState.block
|
||||
var updateFlags = FLAG_SYNC_CLIENT
|
||||
|
||||
if (currentBlock === this) {
|
||||
if (currentBlock === ModBlocks.CORRUPTED_ENERGY) {
|
||||
if (level - currentState[LEVEL] < 3 || world.rand.nextBoolean()) {
|
||||
return FAIL
|
||||
}
|
||||
@@ -130,88 +200,7 @@ class BlockCorruptedEnergy(builder: BlockBuilder) : HeeBlock(builder) {
|
||||
PASSTHROUGH
|
||||
}
|
||||
|
||||
pos.setState(world, this.with(LEVEL, level), updateFlags)
|
||||
pos.setState(world, ModBlocks.CORRUPTED_ENERGY.with(LEVEL, level), updateFlags)
|
||||
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
|
||||
|
||||
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.properties.BlockBuilder
|
||||
import chylex.hee.game.block.properties.BlockModel
|
||||
import chylex.hee.game.world.util.getTile
|
||||
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.ActionResultType.PASS
|
||||
import net.minecraft.util.ActionResultType.SUCCESS
|
||||
import net.minecraft.util.Direction
|
||||
import net.minecraft.util.Direction.UP
|
||||
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.IWorld
|
||||
import net.minecraft.world.World
|
||||
|
||||
class BlockEndPortalAcceptor(builder: BlockBuilder) : BlockPortalFrame(builder) {
|
||||
override val model
|
||||
get() = BlockModel.PortalFrame(ModBlocks.END_PORTAL_FRAME, "acceptor")
|
||||
|
||||
override fun hasTileEntity(state: BlockState): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun createTileEntity(state: BlockState, world: IBlockReader): TileEntity {
|
||||
return TileEntityEndPortalAcceptor()
|
||||
}
|
||||
|
||||
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
|
||||
object BlockEndPortalAcceptor : HeeBlockBuilder() {
|
||||
init {
|
||||
includeFrom(BlockPortalFrameIndestructible)
|
||||
|
||||
model = BlockModel.PortalFrame(ModBlocks.END_PORTAL_FRAME, "acceptor")
|
||||
|
||||
components.entity = IBlockEntityComponent(::TileEntityEndPortalAcceptor)
|
||||
|
||||
components.onAdded = IBlockAddedComponent { _, world, pos ->
|
||||
BlockAbstractPortal.spawnInnerBlocks(world, pos, ModBlocks.END_PORTAL_FRAME, ModBlocks.END_PORTAL_INNER, minSize = 1)
|
||||
}
|
||||
|
||||
return PASS
|
||||
}
|
||||
|
||||
override fun updatePostPlacement(state: BlockState, facing: Direction, neighborState: BlockState, world: IWorld, pos: BlockPos, neighborPos: BlockPos): BlockState {
|
||||
if (!world.isRemote && facing == UP) {
|
||||
pos.getTile<TileEntityEndPortalAcceptor>(world)?.refreshClusterState()
|
||||
components.setStateFromNeighbor = ISetBlockStateFromNeighbor { state, world, pos, neighborFacing, _ ->
|
||||
if (!world.isRemote && neighborFacing == UP) {
|
||||
pos.getTile<TileEntityEndPortalAcceptor>(world)?.refreshClusterState()
|
||||
} // TODO neighbor changed?
|
||||
|
||||
state
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
return super.updatePostPlacement(state, facing, neighborState, world, pos, neighborPos)
|
||||
components.playerUse = object : IPlayerUseBlockComponent {
|
||||
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
|
||||
|
||||
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.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.EnderCausatum
|
||||
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.init.ModBlocks
|
||||
import chylex.hee.util.math.Pos
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.entity.Entity
|
||||
import net.minecraft.entity.player.PlayerEntity
|
||||
import net.minecraft.tileentity.TileEntity
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.IBlockReader
|
||||
import net.minecraft.world.World
|
||||
|
||||
class BlockEndPortalInner(builder: BlockBuilder) : BlockAbstractPortal(builder) {
|
||||
override fun createTileEntity(state: BlockState, world: IBlockReader): 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)
|
||||
object BlockEndPortalInner : HeeBlockBuilder() {
|
||||
init {
|
||||
includeFrom(BlockAbstractPortal(object : IInnerPortalBlock {
|
||||
override fun createTileEntity(): TileEntity {
|
||||
return TileEntityPortalInner.End()
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
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.BlockHardness
|
||||
import chylex.hee.game.block.properties.BlockHarvestTool
|
||||
import chylex.hee.game.item.util.Tool.Level.STONE
|
||||
import chylex.hee.util.random.nextInt
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.IWorldReader
|
||||
import net.minecraft.world.World
|
||||
import net.minecraftforge.common.Tags
|
||||
import net.minecraftforge.common.ToolType.PICKAXE
|
||||
|
||||
class BlockEndPowderOre(builder: BlockBuilder) : HeeBlock(builder) {
|
||||
override val drop
|
||||
get() = BlockDrop.Manual
|
||||
|
||||
override val tags
|
||||
get() = listOf(Tags.Blocks.ORES)
|
||||
|
||||
override fun getExpDrop(state: BlockState, world: IWorldReader, pos: BlockPos, fortune: Int, silktouch: Int): Int {
|
||||
return ((world as? World)?.rand ?: RANDOM).nextInt(1, 2)
|
||||
object BlockEndPowderOre : HeeBlockBuilder() {
|
||||
init {
|
||||
includeFrom(BlockEndOre)
|
||||
|
||||
drop = BlockDrop.Manual
|
||||
|
||||
tool = BlockHarvestTool.required(STONE, PICKAXE)
|
||||
hardness = BlockHardness(hardness = 2F, resistance = 5.4F)
|
||||
|
||||
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.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.IBlockStateModelSupplier
|
||||
import chylex.hee.game.item.util.Tool.Level.WOOD
|
||||
import net.minecraft.block.Blocks
|
||||
import net.minecraft.block.material.MaterialColor
|
||||
import net.minecraftforge.common.Tags
|
||||
import net.minecraftforge.common.ToolType.PICKAXE
|
||||
|
||||
class BlockEndStoneCustom(builder: BlockBuilder, mapColor: MaterialColor) : HeeBlock(builder.clone { color = mapColor }) {
|
||||
override val localization
|
||||
get() = LocalizationStrategy.MoveToBeginning(wordCount = 1)
|
||||
object BlockEndStoneCustom : HeeBlockBuilder() {
|
||||
init {
|
||||
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
|
||||
get() = BlockModel.WithTextures(
|
||||
BlockModel.CubeBottomTop(bottom = Blocks.END_STONE.location),
|
||||
mapOf("particle" to this.location("_top"))
|
||||
)
|
||||
val INFESTED = HeeBlockBuilder {
|
||||
includeFrom(BlockEndStoneCustom)
|
||||
color = MaterialColor.RED
|
||||
}
|
||||
|
||||
override val tags
|
||||
get() = listOf(Tags.Blocks.END_STONES)
|
||||
val BURNED = HeeBlockBuilder {
|
||||
includeFrom(BlockEndStoneCustom)
|
||||
color = MaterialColor.ADOBE // RENAME ORANGE
|
||||
}
|
||||
|
||||
val ENCHANTED = HeeBlockBuilder {
|
||||
includeFrom(BlockEndStoneCustom)
|
||||
color = MaterialColor.PURPLE
|
||||
}
|
||||
}
|
||||
|
@@ -1,26 +1,48 @@
|
||||
package chylex.hee.game.block
|
||||
|
||||
import chylex.hee.game.block.properties.BlockBuilder
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.entity.player.PlayerEntity
|
||||
import chylex.hee.game.block.builder.HeeBlockBuilder
|
||||
import chylex.hee.game.block.components.IBlockHarvestabilityComponent
|
||||
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.util.Hand.MAIN_HAND
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.IBlockReader
|
||||
import net.minecraftforge.common.Tags
|
||||
import net.minecraftforge.common.ToolType.PICKAXE
|
||||
|
||||
sealed class BlockEndium(builder: BlockBuilder) : HeeBlock(builder) {
|
||||
override fun canHarvestBlock(state: BlockState, world: IBlockReader, pos: BlockPos, player: PlayerEntity): Boolean {
|
||||
return super.canHarvestBlock(state, world, pos, player) || player.getHeldItem(MAIN_HAND).item === Items.GOLDEN_PICKAXE
|
||||
abstract class BlockEndium : HeeBlockBuilder() {
|
||||
init {
|
||||
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) {
|
||||
override val tags
|
||||
get() = listOf(Tags.Blocks.ORES)
|
||||
object Ore : BlockEndium() {
|
||||
init {
|
||||
includeFrom(BlockEndOre)
|
||||
|
||||
hardness = BlockHardness(hardness = 5F, resistance = 9.9F)
|
||||
}
|
||||
}
|
||||
|
||||
class Block(builder: BlockBuilder) : BlockEndium(builder) {
|
||||
override val tags
|
||||
get() = listOf(Tags.Blocks.STORAGE_BLOCKS)
|
||||
object Block : BlockEndium() {
|
||||
init {
|
||||
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.getTile
|
||||
import chylex.hee.game.world.util.removeBlock
|
||||
import chylex.hee.init.ModBlocks
|
||||
import chylex.hee.init.ModItems
|
||||
import chylex.hee.util.forge.Side
|
||||
import chylex.hee.util.forge.Sided
|
||||
@@ -43,7 +42,7 @@ class BlockEnergyCluster(builder: BlockBuilder) : BlockSimpleShaped(builder, Axi
|
||||
val units = amount.units.value.toFloat()
|
||||
val corruptedEnergyLevel = (2F + (units.pow(0.74F) / 9F)).ceilToInt()
|
||||
|
||||
ModBlocks.CORRUPTED_ENERGY.spawnCorruptedEnergy(world, pos, corruptedEnergyLevel)
|
||||
BlockCorruptedEnergy.spawn(world, pos, corruptedEnergyLevel)
|
||||
|
||||
if (causeInstability) {
|
||||
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()
|
||||
|
||||
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
|
||||
|
||||
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.Types.ENERGY_SHRINE_GLOBAL
|
||||
import chylex.hee.game.entity.util.posVec
|
||||
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.init.ModTags
|
||||
import chylex.hee.util.forge.EventResult
|
||||
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.EntityType
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.IBlockReader
|
||||
import net.minecraft.world.IEntityReader
|
||||
|
||||
open class BlockGloomrock(builder: BlockBuilder) : HeeBlock(builder) {
|
||||
override fun canCreatureSpawn(state: BlockState, world: IBlockReader, pos: BlockPos, type: PlacementType?, entityType: EntityType<*>?): Boolean {
|
||||
if (world !is IEntityReader) {
|
||||
HEE.log.warn("[BlockGloomrock] attempted to check spawn on a world != IEntityReader (${world.javaClass})")
|
||||
return false
|
||||
object BlockGloomrock : HeeBlockBuilder() {
|
||||
init {
|
||||
material = Materials.SOLID
|
||||
color = MaterialColor.BLACK
|
||||
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 trigger = world
|
||||
.selectEntities
|
||||
.inBox<EntityTechnicalTrigger>(size.toCenteredBoundingBox(center))
|
||||
.find { it.triggerType == ENERGY_SHRINE_GLOBAL }
|
||||
|
||||
return trigger == null || !size.toCenteredBoundingBox(trigger.posVec).contains(center)
|
||||
}
|
||||
|
||||
val BRICKS = HeeBlockBuilder {
|
||||
includeFrom(BlockGloomrock)
|
||||
hardness = BlockHardness(hardness = 2.8F, resistance = 6F)
|
||||
}
|
||||
|
||||
val SMOOTH = HeeBlockBuilder {
|
||||
includeFrom(BlockGloomrock)
|
||||
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
|
||||
|
||||
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.logic.IBlockDynamicHardness
|
||||
import chylex.hee.game.block.properties.BlockBuilder
|
||||
import chylex.hee.game.block.properties.BlockModel
|
||||
import chylex.hee.game.block.properties.BlockStateModel
|
||||
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.Property
|
||||
import chylex.hee.game.block.util.asVoxelShape
|
||||
import chylex.hee.game.entity.technical.EntityTechnicalIgneousPlateLogic
|
||||
import chylex.hee.game.item.properties.ItemModel
|
||||
import chylex.hee.game.world.util.Facing6
|
||||
import chylex.hee.game.world.util.getState
|
||||
import chylex.hee.game.world.util.getTile
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.block.BlockRenderType.ENTITYBLOCK_ANIMATED
|
||||
import net.minecraft.block.BlockState
|
||||
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.item.BlockItemUseContext
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.item.Items
|
||||
import net.minecraft.state.StateContainer.Builder
|
||||
import net.minecraft.tileentity.FurnaceTileEntity
|
||||
import net.minecraft.tileentity.TileEntity
|
||||
import net.minecraft.util.ActionResultType
|
||||
import net.minecraft.util.ActionResultType.PASS
|
||||
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.WEST
|
||||
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.BlockRayTraceResult
|
||||
import net.minecraft.util.math.shapes.ISelectionContext
|
||||
import net.minecraft.util.math.shapes.VoxelShape
|
||||
import net.minecraft.util.math.shapes.VoxelShapes
|
||||
import net.minecraft.world.IBlockReader
|
||||
import net.minecraft.world.IWorld
|
||||
import net.minecraft.world.IWorldReader
|
||||
import net.minecraft.world.World
|
||||
|
||||
class BlockIgneousPlate(builder: BlockBuilder) : HeeBlock(builder), IBlockDynamicHardness {
|
||||
companion object {
|
||||
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
|
||||
)
|
||||
}
|
||||
}
|
||||
object BlockIgneousPlate : HeeBlockBuilder() {
|
||||
val FACING_NOT_DOWN = Property.facing("facing", Facing6.minusElement(DOWN))
|
||||
|
||||
override val model
|
||||
get() = BlockStateModel(BlockStatePreset.Simple, BlockModel.ParticleOnly(this.location), ItemModel.Simple)
|
||||
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 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 {
|
||||
defaultState = stateContainer.baseState.with(FACING_NOT_DOWN, UP)
|
||||
}
|
||||
|
||||
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
|
||||
model = IBlockStateModelSupplier {
|
||||
BlockStateModel(BlockStatePreset.Simple, BlockModel.ParticleOnly(it.location), ItemModel.Simple)
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
if (!world.isRemote && tryCoolPlate(world, pos, state) && !player.abilities.isCreativeMode) {
|
||||
player.setHeldItem(hand, ItemStack(Items.BUCKET))
|
||||
material = Materials.IGNEOUS_ROCK_PLATE
|
||||
color = MaterialColor.AIR
|
||||
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 {
|
||||
return pos.offset(state[FACING_NOT_DOWN].opposite).getTile<FurnaceTileEntity>(world)?.let(EntityTechnicalIgneousPlateLogic.Companion::triggerCooling) == true
|
||||
}
|
||||
|
||||
// State handling
|
||||
|
||||
override fun rotate(state: BlockState, rot: Rotation): BlockState {
|
||||
return state.with(FACING_NOT_DOWN, rot.rotate(state[FACING_NOT_DOWN]))
|
||||
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 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
|
||||
|
||||
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.properties.BlockBuilder
|
||||
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.BlockRenderLayer.TRANSLUCENT
|
||||
import chylex.hee.game.block.properties.BlockStateModel
|
||||
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.item.components.ITooltipComponent
|
||||
import chylex.hee.game.item.util.size
|
||||
import chylex.hee.game.mechanics.dust.DustLayers
|
||||
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.world.util.getTile
|
||||
import chylex.hee.game.world.util.isTopSolid
|
||||
import chylex.hee.init.ModBlocks
|
||||
import chylex.hee.init.ModSounds
|
||||
import chylex.hee.system.heeTag
|
||||
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.nbt.getListOfCompounds
|
||||
import chylex.hee.util.nbt.putList
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.block.BlockState
|
||||
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.player.PlayerEntity
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.loot.LootContext
|
||||
import net.minecraft.loot.LootContext.Builder
|
||||
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.SUCCESS
|
||||
import net.minecraft.util.Direction
|
||||
import net.minecraft.util.Direction.DOWN
|
||||
import net.minecraft.util.Hand
|
||||
import net.minecraft.util.SoundCategory
|
||||
import net.minecraft.util.math.AxisAlignedBB
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.util.math.BlockRayTraceResult
|
||||
import net.minecraft.util.math.RayTraceResult
|
||||
import net.minecraft.util.math.shapes.VoxelShapes
|
||||
import net.minecraft.util.text.ITextComponent
|
||||
import net.minecraft.util.text.TranslationTextComponent
|
||||
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
|
||||
|
||||
class BlockJarODust(builder: BlockBuilder) : BlockSimpleShaped(builder, AABB) {
|
||||
companion object {
|
||||
val AABB = AxisAlignedBB(0.1875, 0.0, 0.1875, 0.8125, 0.84375, 0.8125)
|
||||
object BlockJarODust : HeeBlockBuilder() {
|
||||
init {
|
||||
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
|
||||
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
|
||||
// ItemStack
|
||||
|
||||
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) } }
|
||||
else
|
||||
null
|
||||
}
|
||||
|
||||
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())
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
private fun getDrop(tile: TileEntityJarODust): ItemStack {
|
||||
return ItemStack(this).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)
|
||||
return ItemStack(ModBlocks.JAR_O_DUST).also { setLayersInStack(it, tile.layers) }
|
||||
}
|
||||
|
||||
// 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 {
|
||||
if (world.isRemote) {
|
||||
return true
|
||||
}
|
||||
|
||||
val removed = pos.getTile<TileEntityJarODust>(world)?.layers?.removeDust(if (player.isSneaking) BOTTOM else TOP)
|
||||
|
||||
if (removed != null) {
|
||||
player.setHeldItem(hand, removed)
|
||||
}
|
||||
@@ -197,23 +208,4 @@ class BlockJarODust(builder: BlockBuilder) : BlockSimpleShaped(builder, AABB) {
|
||||
|
||||
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
|
||||
|
||||
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.properties.BlockBuilder
|
||||
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)) {
|
||||
override val localization
|
||||
get() = LocalizationStrategy.ReplaceWords("Miners", "Miner's")
|
||||
|
||||
override val model
|
||||
get() = BlockModel.Manual
|
||||
|
||||
override fun hasTileEntity(state: BlockState): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun createTileEntity(state: BlockState, world: IBlockReader): TileEntity {
|
||||
return TileEntityMinersBurialAltar()
|
||||
object BlockMinersBurialAltar : HeeBlockBuilder() {
|
||||
init {
|
||||
includeFrom(BlockMinersBurialCube.INDESCRUCTIBLE)
|
||||
|
||||
localization = LocalizationStrategy.ReplaceWords("Miners", "Miner's")
|
||||
model = BlockModel.Manual
|
||||
|
||||
components.entity = IBlockEntityComponent(::TileEntityMinersBurialAltar)
|
||||
}
|
||||
}
|
||||
|
@@ -1,9 +1,29 @@
|
||||
package chylex.hee.game.block
|
||||
|
||||
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) {
|
||||
override val localization
|
||||
get() = LocalizationStrategy.Parenthesized(LocalizationStrategy.DeleteWords(LocalizationStrategy.ReplaceWords("Miners", "Miner's"), "Plain"), wordCount = 1, wordOffset = 3, fromStart = true)
|
||||
object BlockMinersBurialCube : HeeBlockBuilder() {
|
||||
init {
|
||||
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
|
||||
|
||||
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.Materials
|
||||
import chylex.hee.game.item.util.Tool.Level.DIAMOND
|
||||
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.ToolType.PICKAXE
|
||||
|
||||
open class BlockObsidianCube(builder: BlockBuilder) : HeeBlock(builder) {
|
||||
override val localization: LocalizationStrategy
|
||||
get() = LocalizationStrategy.MoveToBeginning(wordCount = 1, wordOffset = 1, fromStart = true)
|
||||
object BlockObsidianCube : HeeBlockBuilder() {
|
||||
private val DEFAULT_LOCALIZATION = LocalizationStrategy.MoveToBeginning(wordCount = 1, wordOffset = 1, fromStart = true)
|
||||
|
||||
final override val tags
|
||||
get() = listOf(Tags.Blocks.OBSIDIAN)
|
||||
|
||||
open class Lit(builder: BlockBuilder, private val modelBlock: Block) : BlockObsidianCube(builder) {
|
||||
override val localization: LocalizationStrategy
|
||||
get() = LocalizationStrategy.Parenthesized(super.localization, wordCount = 1, fromStart = false)
|
||||
init {
|
||||
localization = DEFAULT_LOCALIZATION
|
||||
|
||||
override val model
|
||||
get() = BlockStateModels.Cube(modelBlock)
|
||||
tags.add(Tags.Blocks.OBSIDIAN)
|
||||
|
||||
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) {
|
||||
override val localization
|
||||
get() = LocalizationStrategy.Default
|
||||
class Lit(modelBlock: Block) : HeeBlockBuilder() {
|
||||
init {
|
||||
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.util.MC
|
||||
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.DISABLED
|
||||
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.BlockRenderLayer.CUTOUT
|
||||
import chylex.hee.game.block.properties.BlockStateModel
|
||||
import chylex.hee.game.block.properties.BlockStatePreset
|
||||
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.withFacing
|
||||
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.BlockState
|
||||
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.item.BlockItemUseContext
|
||||
import net.minecraft.state.StateContainer.Builder
|
||||
import net.minecraft.util.Direction
|
||||
import net.minecraft.util.Direction.NORTH
|
||||
import net.minecraft.util.Direction.SOUTH
|
||||
@@ -60,7 +65,7 @@ import net.minecraft.world.IBlockDisplayReader
|
||||
import net.minecraft.world.World
|
||||
import java.util.Random
|
||||
|
||||
sealed class BlockPuzzleLogic(builder: BlockBuilder) : HeeBlock(builder) {
|
||||
class BlockPuzzleLogic(impl: IPuzzleLogic) : HeeBlockBuilder() {
|
||||
companion object {
|
||||
val STATE = Property.enum<State>("state")
|
||||
|
||||
@@ -101,7 +106,7 @@ sealed class BlockPuzzleLogic(builder: BlockBuilder) : HeeBlock(builder) {
|
||||
var closest = pos
|
||||
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)
|
||||
|
||||
val distSq = testPos.distanceSqTo(player)
|
||||
@@ -123,8 +128,12 @@ sealed class BlockPuzzleLogic(builder: BlockBuilder) : HeeBlock(builder) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun isPuzzleBlockEnabled(state: BlockState): Boolean {
|
||||
return state.block is BlockPuzzleLogic && state[STATE] != DISABLED
|
||||
fun isPuzzleBlock(block: Block): Boolean {
|
||||
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> {
|
||||
@@ -204,6 +213,66 @@ sealed class BlockPuzzleLogic(builder: BlockBuilder) : HeeBlock(builder) {
|
||||
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 {
|
||||
@@ -223,159 +292,101 @@ sealed class BlockPuzzleLogic(builder: BlockBuilder) : HeeBlock(builder) {
|
||||
}
|
||||
}
|
||||
|
||||
abstract override val model: IBlockStateModel
|
||||
|
||||
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)
|
||||
object Plain : HeeBlockBuilder() {
|
||||
internal val LOGIC = IPuzzleLogic { _, pos, facing -> listOf(makePair(pos, facing)) }
|
||||
|
||||
return if (toggleState(world, pos, state))
|
||||
getNextChains(world, pos, facing)
|
||||
else
|
||||
emptyList()
|
||||
}
|
||||
|
||||
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))
|
||||
init {
|
||||
includeFrom(BlockPuzzleLogic(LOGIC))
|
||||
|
||||
localization = LocalizationStrategy.Parenthesized(wordCount = 1, fromStart = false)
|
||||
model = createPlainModel()
|
||||
}
|
||||
}
|
||||
|
||||
class Burst(builder: BlockBuilder, private val radius: Int) : BlockPuzzleLogic(builder) {
|
||||
override val localization
|
||||
get() = LocalizationStrategy.Parenthesized(LocalizationStrategy.ReplaceWords("$diameter", "${diameter}x${diameter}"), wordCount = 2, fromStart = false)
|
||||
class Burst(radius: Int) : HeeBlockBuilder() {
|
||||
private val logic = IPuzzleLogic { world, pos, facing ->
|
||||
pos.allInCenteredBox(radius, 0, radius).toList().flatMap { toggleAndChain(world, it, facing) }.distinct()
|
||||
}
|
||||
|
||||
override val model
|
||||
get() = createOverlayModel("burst_$diameter")
|
||||
|
||||
private val diameter
|
||||
get() = 1 + (radius * 2)
|
||||
init {
|
||||
includeFrom(BlockPuzzleLogic(logic))
|
||||
|
||||
val diameter = 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>> {
|
||||
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()
|
||||
else
|
||||
block.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()
|
||||
logic.getNextChains(world, pos, facing)
|
||||
}
|
||||
}
|
||||
|
||||
sealed class RedirectSome private constructor(builder: BlockBuilder, private val blockDirections: Array<String>, private val itemDirection: String, private val directions: Array<Direction>) : BlockPuzzleLogic(builder) {
|
||||
class R1(builder: BlockBuilder) : RedirectSome(builder, arrayOf("n", "s", "e", "w"), "n", arrayOf(NORTH))
|
||||
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>> {
|
||||
private class RedirectSome(blockDirections: Array<String>, itemDirection: String, directions: Array<Direction>) : HeeBlockBuilder() {
|
||||
private val logic = BlockPuzzleLogic { world, pos, facing ->
|
||||
val rotation = pos.getState(world)[HORIZONTAL_FACING].horizontalIndex + NORTH.horizontalIndex
|
||||
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
|
||||
get() = createOverlayModel("redirect_4")
|
||||
|
||||
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
|
||||
}
|
||||
init {
|
||||
includeFrom(logic)
|
||||
|
||||
if (world == null && pos == null) {
|
||||
return RGB(104, 58, 16).i // make the color slightly more visible in inventory
|
||||
}
|
||||
localization = LocalizationStrategy.Parenthesized(wordCount = 2, fromStart = false)
|
||||
model = createOverlayModel("redirect_" + directions.size + itemDirection, blockDirections.map { "redirect_" + directions.size + it })
|
||||
|
||||
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(HORIZONTAL_FACING, NORTH)
|
||||
components.states.facingProperty = HORIZONTAL_FACING
|
||||
|
||||
components.placement = object : IBlockPlacementComponent {
|
||||
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
|
||||
|
||||
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) {
|
||||
override val localization
|
||||
get() = LocalizationStrategy.Parenthesized(wordCount = 1, fromStart = false)
|
||||
object BlockPuzzleWall : HeeBlockBuilder() {
|
||||
init {
|
||||
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.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.BlockRenderLayer.CUTOUT
|
||||
import chylex.hee.util.forge.Side
|
||||
import chylex.hee.util.forge.Sided
|
||||
import chylex.hee.game.block.properties.Materials
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.util.math.shapes.ISelectionContext
|
||||
import net.minecraft.block.SoundType
|
||||
import net.minecraft.block.material.MaterialColor
|
||||
import net.minecraft.util.math.shapes.VoxelShape
|
||||
import net.minecraft.util.math.shapes.VoxelShapes
|
||||
import net.minecraft.world.IBlockReader
|
||||
|
||||
open class BlockScaffolding protected constructor(builder: BlockBuilder) : HeeBlock(builder) {
|
||||
companion object {
|
||||
var enableShape = true
|
||||
object BlockScaffolding : HeeBlockBuilder() {
|
||||
var enableShape = true
|
||||
|
||||
init {
|
||||
includeFrom(BlockIndestructible)
|
||||
|
||||
fun create(builder: BlockBuilder): HeeBlock {
|
||||
return HEE.debugModule?.createScaffoldingBlock(builder) ?: BlockScaffolding(builder)
|
||||
model = BlockModel.Manual
|
||||
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)
|
||||
VoxelShapes.fullCube()
|
||||
else
|
||||
VoxelShapes.empty()
|
||||
}
|
||||
|
||||
override fun getRaytraceShape(state: BlockState, world: IBlockReader, pos: BlockPos): VoxelShape {
|
||||
val player = Environment.getClientSidePlayer()
|
||||
components.ambientOcclusionValue = 1F
|
||||
|
||||
return if ((player == null || player.isSneaking || player.abilities.isFlying) && enableShape)
|
||||
VoxelShapes.fullCube()
|
||||
else
|
||||
VoxelShapes.empty()
|
||||
}
|
||||
|
||||
@Sided(Side.CLIENT)
|
||||
override fun getAmbientOcclusionLightValue(state: BlockState, world: IBlockReader, pos: BlockPos): Float {
|
||||
return 1F
|
||||
components.playerUse = HEE.debugModule?.scaffoldingBlockBehavior
|
||||
}
|
||||
}
|
||||
|
@@ -2,42 +2,43 @@ package chylex.hee.game.block
|
||||
|
||||
import chylex.hee.game.Resource
|
||||
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.BlockHardness
|
||||
import chylex.hee.game.block.properties.BlockHarvestTool
|
||||
import chylex.hee.game.block.properties.BlockModel
|
||||
import chylex.hee.game.block.properties.BlockRenderLayer.CUTOUT
|
||||
import chylex.hee.game.block.properties.BlockStateModel
|
||||
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.random.nextBiasedFloat
|
||||
import net.minecraft.block.BlockState
|
||||
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) {
|
||||
override val model
|
||||
get() = BlockStateModel(
|
||||
BlockStatePreset.None,
|
||||
BlockModel.WithTextures(BlockModel.FromParent(Resource.Custom("block/cube_overlay")), mapOf(
|
||||
"particle" to ModBlocks.STARDUST_ORE.location("_particle"),
|
||||
"base" to Blocks.END_STONE.location,
|
||||
))
|
||||
)
|
||||
|
||||
override val renderLayer
|
||||
get() = CUTOUT
|
||||
|
||||
override val drop
|
||||
get() = BlockDrop.Manual
|
||||
|
||||
override val tags
|
||||
get() = listOf(Tags.Blocks.ORES)
|
||||
|
||||
override fun getExpDrop(state: BlockState, world: IWorldReader, pos: BlockPos, fortune: Int, silktouch: Int): Int {
|
||||
return (((world as? World)?.rand ?: RANDOM).nextBiasedFloat(4F) * 6F).ceilToInt()
|
||||
object BlockStardustOre : HeeBlockBuilder() {
|
||||
init {
|
||||
includeFrom(BlockEndOre)
|
||||
|
||||
model = IBlockStateModelSupplier {
|
||||
BlockStateModel(
|
||||
BlockStatePreset.None,
|
||||
BlockModel.WithTextures(BlockModel.FromParent(Resource.Custom("block/cube_overlay")), mapOf(
|
||||
"particle" to it.location("_particle"),
|
||||
"base" to Blocks.END_STONE.location,
|
||||
))
|
||||
)
|
||||
}
|
||||
|
||||
renderLayer = CUTOUT
|
||||
|
||||
drop = BlockDrop.Manual
|
||||
|
||||
tool = BlockHarvestTool.required(STONE, PICKAXE)
|
||||
hardness = BlockHardness(hardness = 2.8F, resistance = 8.4F)
|
||||
|
||||
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
|
||||
|
||||
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.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.TileEntityVoidPortalStorage
|
||||
import chylex.hee.game.block.properties.BlockBuilder
|
||||
import chylex.hee.game.block.util.Property
|
||||
import chylex.hee.game.entity.Teleporter
|
||||
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.territory.TerritoryType
|
||||
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.offsetUntil
|
||||
import chylex.hee.game.world.util.setAir
|
||||
import chylex.hee.init.ModTags
|
||||
import chylex.hee.util.math.Pos
|
||||
import chylex.hee.util.math.Vec3
|
||||
import chylex.hee.util.math.center
|
||||
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.LivingEntity
|
||||
import net.minecraft.entity.player.PlayerEntity
|
||||
import net.minecraft.state.StateContainer.Builder
|
||||
import net.minecraft.tileentity.TileEntity
|
||||
import net.minecraft.util.IStringSerializable
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.IBlockReader
|
||||
import net.minecraft.world.World
|
||||
|
||||
class BlockVoidPortalInner(builder: BlockBuilder) : BlockAbstractPortal(builder) {
|
||||
companion object {
|
||||
val TYPE = Property.enum<Type>("type")
|
||||
|
||||
private val TELEPORTER = Teleporter(postEvent = false, effectRange = Silent)
|
||||
|
||||
fun teleportEntity(entity: Entity, info: SpawnInfo) {
|
||||
val targetVec = info.pos.center.subtractY(0.45)
|
||||
|
||||
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)
|
||||
object BlockVoidPortalInner : HeeBlockBuilder() {
|
||||
val TYPE = Property.enum<Type>("type")
|
||||
|
||||
private val TELEPORTER = Teleporter(postEvent = false, effectRange = Silent)
|
||||
|
||||
init {
|
||||
includeFrom(BlockAbstractPortal(object : IInnerPortalBlock {
|
||||
override fun createTileEntity(): TileEntity {
|
||||
return TileEntityPortalInner.Void()
|
||||
}
|
||||
else {
|
||||
entity.setPositionAndUpdate(targetVec.x, targetVec.y, targetVec.z)
|
||||
entity.motion = Vec3.ZERO
|
||||
|
||||
override fun teleportEntity(world: World, pos: BlockPos, entity: Entity) {
|
||||
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?
|
||||
}
|
||||
|
||||
// Instance
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
fun teleportEntity(entity: Entity, info: SpawnInfo) {
|
||||
val targetVec = info.pos.center.subtractY(0.45)
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
super.neighborChanged(state, world, pos, neighborBlock, neighborPos, isMoving)
|
||||
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)
|
||||
entity.motion = Vec3.ZERO
|
||||
}
|
||||
}
|
||||
|
||||
// Interaction
|
||||
|
||||
private fun findSpawnPortalCenter(entity: Entity, pos: BlockPos): BlockPos? {
|
||||
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 maxPos = offsets.reduce(BlockPos::max)
|
||||
@@ -134,37 +150,4 @@ class BlockVoidPortalInner(builder: BlockBuilder) : BlockAbstractPortal(builder)
|
||||
|
||||
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
|
||||
|
||||
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.properties.BlockBuilder
|
||||
import chylex.hee.game.block.properties.BlockModel
|
||||
import chylex.hee.game.world.util.getTile
|
||||
import chylex.hee.init.ModBlocks
|
||||
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.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) {
|
||||
override val model
|
||||
get() = BlockModel.PortalFrame(ModBlocks.VOID_PORTAL_FRAME, "storage")
|
||||
|
||||
override fun hasTileEntity(state: BlockState): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun createTileEntity(state: BlockState, world: IBlockReader): TileEntity {
|
||||
return TileEntityVoidPortalStorage()
|
||||
}
|
||||
|
||||
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
|
||||
abstract class BlockVoidPortalStorage(base: HeeBlockBuilder, minPortalSize: Int) : HeeBlockBuilder() {
|
||||
init {
|
||||
includeFrom(base)
|
||||
|
||||
model = BlockModel.PortalFrame(ModBlocks.VOID_PORTAL_FRAME, "storage")
|
||||
|
||||
components.entity = IBlockEntityComponent(::TileEntityVoidPortalStorage)
|
||||
|
||||
components.onAdded = IBlockAddedComponent { _, world, pos ->
|
||||
BlockAbstractPortal.spawnInnerBlocks(world, pos, ModBlocks.VOID_PORTAL_FRAME, ModBlocks.VOID_PORTAL_INNER, minSize = minPortalSize)
|
||||
}
|
||||
|
||||
pos.getTile<TileEntityVoidPortalStorage>(world)?.let {
|
||||
ModContainers.open(player, it, pos)
|
||||
components.playerUse = IPlayerUseBlockComponent { _, world, pos, player, _ ->
|
||||
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
|
||||
|
||||
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.item.util.Tool.Level.WOOD
|
||||
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.util.Direction
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.IBlockReader
|
||||
import net.minecraftforge.common.ToolType.AXE
|
||||
|
||||
class BlockWhitebark(builder: BlockBuilder) : HeeBlock(builder) {
|
||||
override val model
|
||||
get() = BlockModel.Cube(ModBlocks.WHITEBARK_LOG.location)
|
||||
|
||||
override val tags
|
||||
get() = listOf(BlockTags.LOGS, BlockTags.LOGS_THAT_BURN)
|
||||
|
||||
override fun getFlammability(state: BlockState, world: IBlockReader, pos: BlockPos, face: Direction): Int {
|
||||
return 5
|
||||
object BlockWhitebark : HeeBlockBuilder() {
|
||||
init {
|
||||
material = Material.WOOD
|
||||
color = MaterialColor.SNOW
|
||||
sound = SoundType.WOOD
|
||||
tool = BlockHarvestTool.optional(WOOD, AXE)
|
||||
}
|
||||
|
||||
override fun getFireSpreadSpeed(state: BlockState, world: IBlockReader, pos: BlockPos, face: Direction): Int {
|
||||
return 5
|
||||
val BARK = HeeBlockBuilder {
|
||||
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
|
||||
|
||||
import chylex.hee.game.block.BlockIgneousPlate
|
||||
import chylex.hee.game.block.util.DISPENSER_FACING
|
||||
import chylex.hee.game.world.util.getState
|
||||
import chylex.hee.init.ModBlocks
|
||||
@@ -16,7 +17,7 @@ class DispenseWaterExtinguishIgneousPlate(private val originalBehavior: IDispens
|
||||
val facingState = facingPos.getState(world)
|
||||
|
||||
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)
|
||||
else
|
||||
stack
|
||||
|
@@ -46,13 +46,6 @@ object BlockBuilders {
|
||||
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 {
|
||||
requiresTool = true
|
||||
harvestTool = Pair(WOOD, SHOVEL)
|
||||
@@ -76,16 +69,6 @@ object BlockBuilders {
|
||||
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 {
|
||||
explosionResistance = 0.3F
|
||||
lightLevel = 13
|
||||
@@ -133,19 +116,6 @@ object BlockBuilders {
|
||||
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)
|
||||
|
||||
val buildDarkLoam = BlockBuilder(Materials.SOLID, MaterialColor.BLACK, SoundType.GROUND).apply {
|
||||
@@ -162,10 +132,6 @@ object BlockBuilders {
|
||||
explosionResistance = 2.0F
|
||||
}
|
||||
|
||||
val buildWhitebarkPlanks = buildWhitebark.clone {
|
||||
explosionResistance = 3.0F
|
||||
}
|
||||
|
||||
// Building (Miner's Burial)
|
||||
|
||||
val buildMinersBurial = BlockBuilder(Materials.SOLID, MaterialColor.RED, SoundType.STONE).apply {
|
||||
@@ -175,10 +141,6 @@ object BlockBuilders {
|
||||
explosionResistance = 120F
|
||||
}
|
||||
|
||||
val buildMinersBurialIndestructible = buildMinersBurial.clone {
|
||||
makeIndestructible()
|
||||
}
|
||||
|
||||
// Fluids
|
||||
|
||||
val buildCauldron = BlockBuilder(Material.IRON, MaterialColor.STONE, SoundType.STONE).apply {
|
||||
@@ -188,26 +150,11 @@ object BlockBuilders {
|
||||
|
||||
// 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 {
|
||||
makeIndestructible()
|
||||
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)
|
||||
|
||||
val buildExperienceGate = BlockBuilder(Materials.SOLID, MaterialColor.GREEN, SoundType.METAL).apply {
|
||||
@@ -217,8 +164,6 @@ object BlockBuilders {
|
||||
|
||||
// Interactive (Uncategorized)
|
||||
|
||||
val buildIgneousPlate = BlockBuilder(Materials.IGNEOUS_ROCK_PLATE, MaterialColor.AIR, SoundType.STONE)
|
||||
|
||||
val buildBrewingStand = BlockBuilder(Material.IRON, MaterialColor.YELLOW, SoundType.STONE).apply {
|
||||
isSolid = false
|
||||
harvestHardness = 0.5F
|
||||
@@ -232,24 +177,6 @@ object BlockBuilders {
|
||||
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 {
|
||||
harvestTool = Pair(DIAMOND, PICKAXE)
|
||||
harvestHardness = 1.6F
|
||||
@@ -315,25 +242,6 @@ object BlockBuilders {
|
||||
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
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
val buildCorruptedEnergy = BlockBuilder(Materials.CORRUPTED_ENERGY, MaterialColor.PURPLE, SoundType.SAND).apply {
|
||||
isSolid = false
|
||||
randomTicks = true // just to be safe
|
||||
noDrops = true
|
||||
}
|
||||
|
||||
// Tables
|
||||
|
||||
val buildTablePedestal = buildGloomrock.clone {
|
||||
@@ -372,14 +274,6 @@ object BlockBuilders {
|
||||
lightLevel = 15
|
||||
}
|
||||
|
||||
val buildScaffolding = BlockBuilder(Materials.SCAFFOLDING, MaterialColor.AIR, SoundType.STONE).apply {
|
||||
makeIndestructible()
|
||||
isSolid = false
|
||||
isOpaque = false
|
||||
suffocates = false
|
||||
blocksVision = false
|
||||
}
|
||||
|
||||
// Overrides
|
||||
|
||||
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) {
|
||||
val posBelow = currentPos.down()
|
||||
|
||||
if (posBelow.getBlock(world) is BlockPuzzleLogic) {
|
||||
if (BlockPuzzleLogic.isPuzzleBlock(posBelow.getBlock(world))) {
|
||||
val entity = EntityTechnicalPuzzle(world)
|
||||
|
||||
if (entity.startChain(posBelow, throwFacing)) {
|
||||
|
@@ -2,11 +2,11 @@ package chylex.hee.game.entity.living
|
||||
|
||||
import chylex.hee.client.text.LocalizationStrategy
|
||||
import chylex.hee.game.Resource
|
||||
import chylex.hee.game.block.BlockCorruptedEnergy
|
||||
import chylex.hee.game.entity.util.DefaultEntityAttributes
|
||||
import chylex.hee.game.entity.util.with
|
||||
import chylex.hee.game.mechanics.instability.Instability
|
||||
import chylex.hee.game.world.util.isPeaceful
|
||||
import chylex.hee.init.ModBlocks
|
||||
import chylex.hee.init.ModEntities
|
||||
import chylex.hee.system.heeTag
|
||||
import chylex.hee.util.forge.Side
|
||||
@@ -78,7 +78,7 @@ class EntityMobEndermiteInstability(type: EntityType<EntityMobEndermiteInstabili
|
||||
val pos = Pos(this)
|
||||
|
||||
Instability.get(world).triggerRelief(20u, pos)
|
||||
ModBlocks.CORRUPTED_ENERGY.spawnCorruptedEnergy(world, pos, 2)
|
||||
BlockCorruptedEnergy.spawn(world, pos, 2)
|
||||
}
|
||||
|
||||
super.remove()
|
||||
|
@@ -83,13 +83,10 @@ class EntityTechnicalPuzzle(type: EntityType<EntityTechnicalPuzzle>, world: Worl
|
||||
}
|
||||
|
||||
private fun moveToBlockAndToggle(pos: BlockPos) {
|
||||
val block = pos.getBlock(world)
|
||||
|
||||
if (block is BlockPuzzleLogic) {
|
||||
if (BlockPuzzleLogic.isPuzzleBlock(pos.getBlock(world))) {
|
||||
setPosition(pos)
|
||||
|
||||
val nextChains = block.onToggled(world, pos, facing)
|
||||
|
||||
val nextChains = BlockPuzzleLogic.onToggled(world, pos, facing)
|
||||
if (nextChains.isEmpty()) {
|
||||
endChain()
|
||||
}
|
||||
@@ -125,10 +122,7 @@ class EntityTechnicalPuzzle(type: EntityType<EntityTechnicalPuzzle>, world: Worl
|
||||
}
|
||||
|
||||
fun startChain(pos: BlockPos, facing: Direction): Boolean {
|
||||
val state = pos.getState(world)
|
||||
val block = state.block
|
||||
|
||||
if (block !is BlockPuzzleLogic || state[BlockPuzzleLogic.STATE] == BlockPuzzleLogic.State.DISABLED) {
|
||||
if (!BlockPuzzleLogic.isPuzzleBlockEnabled(pos.getState(world))) {
|
||||
return false
|
||||
}
|
||||
|
||||
|
@@ -10,7 +10,7 @@ import net.minecraft.item.ItemStack
|
||||
import net.minecraft.util.text.ITextComponent
|
||||
import net.minecraft.util.text.StringTextComponent
|
||||
import net.minecraft.util.text.TranslationTextComponent
|
||||
import net.minecraft.world.World
|
||||
import net.minecraft.world.IBlockReader
|
||||
|
||||
class ItemAbstractTrinket(trinket: ITrinketItem) : HeeItemBuilder() {
|
||||
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"
|
||||
|
||||
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
|
||||
|
||||
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.StringTextComponent
|
||||
import net.minecraft.util.text.TranslationTextComponent
|
||||
import net.minecraft.world.World
|
||||
import net.minecraft.world.IBlockReader
|
||||
|
||||
object ItemBindingEssence : HeeItemBuilder() {
|
||||
init {
|
||||
@@ -57,7 +57,7 @@ object ItemBindingEssence : HeeItemBuilder() {
|
||||
maxStackSize = 16
|
||||
|
||||
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)
|
||||
if (list.isEmpty) {
|
||||
return
|
||||
|
@@ -1,9 +1,9 @@
|
||||
package chylex.hee.game.recipe
|
||||
|
||||
import chylex.hee.game.block.BlockJarODust
|
||||
import chylex.hee.game.inventory.util.nonEmptySlots
|
||||
import chylex.hee.game.inventory.util.size
|
||||
import chylex.hee.game.mechanics.dust.DustLayers.Side.BOTTOM
|
||||
import chylex.hee.init.ModBlocks
|
||||
import net.minecraft.inventory.CraftingInventory
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.util.NonNullList
|
||||
@@ -33,10 +33,10 @@ object RecipeJarODustExtract : RecipeBaseDynamic() {
|
||||
|
||||
if (layers != null) {
|
||||
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.client.util.MC
|
||||
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.IDamageDealer.Companion.TITLE_WITHER
|
||||
import chylex.hee.game.entity.damage.IDamageProcessor.Companion.DEAL_CREATIVE
|
||||
@@ -149,7 +150,7 @@ object TerritoryVoid {
|
||||
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
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
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.RETURN_ACTIVE
|
||||
import chylex.hee.game.block.BlockVoidPortalInner.Type.RETURN_INACTIVE
|
||||
|
@@ -1,7 +1,6 @@
|
||||
package chylex.hee.game.world.generation.feature.energyshrine.piece
|
||||
|
||||
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.ITriggerHandler
|
||||
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.getState
|
||||
import chylex.hee.game.world.util.offsetUntil
|
||||
import chylex.hee.init.ModTags
|
||||
import chylex.hee.util.color.IColorGenerator
|
||||
import chylex.hee.util.color.RGB
|
||||
import chylex.hee.util.math.Pos
|
||||
@@ -69,11 +69,11 @@ class EnergyShrineRoom_Main_Start(file: String) : EnergyShrineRoom_Generic(file)
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
@@ -34,8 +34,6 @@ import chylex.hee.game.block.BlockFlowerPotCustom
|
||||
import chylex.hee.game.block.BlockFlowerPotDeathFlower
|
||||
import chylex.hee.game.block.BlockFlowerPotDeathFlowerDecaying
|
||||
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.BlockGloomrockSmoothStairs
|
||||
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.BlockObsidianCube
|
||||
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.BlockPuzzleWall
|
||||
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.BlockTablePedestal
|
||||
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.BlockVoidPortalStorage
|
||||
import chylex.hee.game.block.BlockVoidPortalStorageCrafted
|
||||
import chylex.hee.game.block.BlockWallCustom
|
||||
import chylex.hee.game.block.BlockWhitebark
|
||||
import chylex.hee.game.block.BlockWhitebarkLeaves
|
||||
import chylex.hee.game.block.BlockWhitebarkLog
|
||||
import chylex.hee.game.block.BlockWhitebarkPlanks
|
||||
import chylex.hee.game.block.BlockWhitebarkSapling
|
||||
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.TileEntityExperienceTable
|
||||
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.buildBrewingStand
|
||||
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.buildDragonEgg
|
||||
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.buildDustyStoneDamaged
|
||||
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.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.buildEternalFire
|
||||
import chylex.hee.game.block.properties.BlockBuilders.buildEtherealLantern
|
||||
import chylex.hee.game.block.properties.BlockBuilders.buildExperienceGate
|
||||
import chylex.hee.game.block.properties.BlockBuilders.buildFlowerPot
|
||||
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.buildGraveDirt
|
||||
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.buildInfusedGlass
|
||||
import chylex.hee.game.block.properties.BlockBuilders.buildJarODust
|
||||
import chylex.hee.game.block.properties.BlockBuilders.buildLootChest
|
||||
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.buildObsidianTowerTop
|
||||
import chylex.hee.game.block.properties.BlockBuilders.buildObsidianVariation
|
||||
import chylex.hee.game.block.properties.BlockBuilders.buildObsidianVariationLit
|
||||
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.buildStardustOre
|
||||
import chylex.hee.game.block.properties.BlockBuilders.buildTable
|
||||
import chylex.hee.game.block.properties.BlockBuilders.buildTablePedestal
|
||||
import chylex.hee.game.block.properties.BlockBuilders.buildVantablock
|
||||
import chylex.hee.game.block.properties.BlockBuilders.buildWhitebark
|
||||
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.CustomSkull
|
||||
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 INFUSED_GLASS = BlockInfusedGlass(buildInfusedGlass) named "infused_glass"
|
||||
@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 HUMUS = BlockHumus(buildHumus, mergeBottom = ENDERSOL) named "humus"
|
||||
|
||||
// Blocks: Building (Gloomrock)
|
||||
|
||||
@JvmField val GLOOMROCK = BlockGloomrock(buildGloomrock) named "gloomrock"
|
||||
@JvmField val GLOOMROCK_BRICKS = BlockGloomrock(buildGloomrockBricks) named "gloomrock_bricks"
|
||||
@JvmField val GLOOMROCK_BRICK_STAIRS = BlockStairsCustom(GLOOMROCK_BRICKS) named "gloomrock_brick_stairs"
|
||||
@JvmField val GLOOMROCK = BlockGloomrock named "gloomrock"
|
||||
@JvmField val GLOOMROCK_BRICKS = BlockGloomrock.BRICKS named "gloomrock_bricks"
|
||||
@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_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_SLAB = BlockGloomrockSmoothSlab(GLOOMROCK_SMOOTH) named "gloomrock_smooth_slab"
|
||||
@JvmField val GLOOMROCK_SMOOTH_RED = BlockGloomrockSmoothColored(buildGloomrockSmooth) named "gloomrock_smooth_red"
|
||||
@JvmField val GLOOMROCK_SMOOTH_ORANGE = BlockGloomrockSmoothColored(buildGloomrockSmooth) named "gloomrock_smooth_orange"
|
||||
@JvmField val GLOOMROCK_SMOOTH_YELLOW = BlockGloomrockSmoothColored(buildGloomrockSmooth) named "gloomrock_smooth_yellow"
|
||||
@JvmField val GLOOMROCK_SMOOTH_GREEN = BlockGloomrockSmoothColored(buildGloomrockSmooth) named "gloomrock_smooth_green"
|
||||
@JvmField val GLOOMROCK_SMOOTH_CYAN = BlockGloomrockSmoothColored(buildGloomrockSmooth) named "gloomrock_smooth_cyan"
|
||||
@JvmField val GLOOMROCK_SMOOTH_BLUE = BlockGloomrockSmoothColored(buildGloomrockSmooth) named "gloomrock_smooth_blue"
|
||||
@JvmField val GLOOMROCK_SMOOTH_PURPLE = BlockGloomrockSmoothColored(buildGloomrockSmooth) named "gloomrock_smooth_purple"
|
||||
@JvmField val GLOOMROCK_SMOOTH_MAGENTA = BlockGloomrockSmoothColored(buildGloomrockSmooth) named "gloomrock_smooth_magenta"
|
||||
@JvmField val GLOOMROCK_SMOOTH_WHITE = BlockGloomrockSmoothColored(buildGloomrockSmooth) named "gloomrock_smooth_white"
|
||||
@JvmField val GLOOMROCK_SMOOTH_RED = BlockGloomrock.SMOOTH_COLORED named "gloomrock_smooth_red"
|
||||
@JvmField val GLOOMROCK_SMOOTH_ORANGE = BlockGloomrock.SMOOTH_COLORED named "gloomrock_smooth_orange"
|
||||
@JvmField val GLOOMROCK_SMOOTH_YELLOW = BlockGloomrock.SMOOTH_COLORED named "gloomrock_smooth_yellow"
|
||||
@JvmField val GLOOMROCK_SMOOTH_GREEN = BlockGloomrock.SMOOTH_COLORED named "gloomrock_smooth_green"
|
||||
@JvmField val GLOOMROCK_SMOOTH_CYAN = BlockGloomrock.SMOOTH_COLORED named "gloomrock_smooth_cyan"
|
||||
@JvmField val GLOOMROCK_SMOOTH_BLUE = BlockGloomrock.SMOOTH_COLORED named "gloomrock_smooth_blue"
|
||||
@JvmField val GLOOMROCK_SMOOTH_PURPLE = BlockGloomrock.SMOOTH_COLORED named "gloomrock_smooth_purple"
|
||||
@JvmField val GLOOMROCK_SMOOTH_MAGENTA = BlockGloomrock.SMOOTH_COLORED named "gloomrock_smooth_magenta"
|
||||
@JvmField val GLOOMROCK_SMOOTH_WHITE = BlockGloomrock.SMOOTH_COLORED named "gloomrock_smooth_white"
|
||||
@JvmField val GLOOMTORCH = BlockGloomtorch(buildGloomtorch) named "gloomtorch"
|
||||
|
||||
// Blocks: Building (Dusty Stone)
|
||||
@@ -215,19 +194,19 @@ object ModBlocks {
|
||||
|
||||
@JvmField val OBSIDIAN_STAIRS = BlockStairsCustom(Blocks.OBSIDIAN) named "obsidian_stairs"
|
||||
@JvmField val OBSIDIAN_FALLING = BlockFallingObsidian(buildObsidian) named "obsidian_falling"
|
||||
@JvmField val OBSIDIAN_SMOOTH = BlockObsidianCube(buildObsidianVariation) named "obsidian_smooth"
|
||||
@JvmField val OBSIDIAN_CHISELED = BlockObsidianCube(buildObsidianVariation) named "obsidian_chiseled"
|
||||
@JvmField val OBSIDIAN_SMOOTH = BlockObsidianCube named "obsidian_smooth"
|
||||
@JvmField val OBSIDIAN_CHISELED = BlockObsidianCube named "obsidian_chiseled"
|
||||
@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_CHISELED_LIT = BlockObsidianCube.Lit(buildObsidianVariationLit, OBSIDIAN_CHISELED) named "obsidian_chiseled_lit"
|
||||
@JvmField val OBSIDIAN_SMOOTH_LIT = BlockObsidianCube.Lit(OBSIDIAN_SMOOTH) named "obsidian_smooth_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_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)
|
||||
|
||||
@JvmField val END_STONE_INFESTED = BlockEndStoneCustom(buildEndStone, MaterialColor.RED) named "end_stone_infested"
|
||||
@JvmField val END_STONE_BURNED = BlockEndStoneCustom(buildEndStone, MaterialColor.ADOBE /* RENAME ORANGE */) named "end_stone_burned"
|
||||
@JvmField val END_STONE_ENCHANTED = BlockEndStoneCustom(buildEndStone, MaterialColor.PURPLE) named "end_stone_enchanted"
|
||||
@JvmField val END_STONE_INFESTED = BlockEndStoneCustom.INFESTED named "end_stone_infested"
|
||||
@JvmField val END_STONE_BURNED = BlockEndStoneCustom.BURNED named "end_stone_burned"
|
||||
@JvmField val END_STONE_ENCHANTED = BlockEndStoneCustom.ENCHANTED named "end_stone_enchanted"
|
||||
|
||||
// Blocks: Building (Dark Loam)
|
||||
|
||||
@@ -243,18 +222,18 @@ object ModBlocks {
|
||||
// Blocks: Building (Wood)
|
||||
|
||||
@JvmField val WHITEBARK_LOG = BlockWhitebarkLog(buildWhitebark) named "whitebark_log"
|
||||
@JvmField val WHITEBARK = BlockWhitebark(buildWhitebark) named "whitebark"
|
||||
@JvmField val WHITEBARK_PLANKS = BlockWhitebarkPlanks(buildWhitebarkPlanks) named "whitebark_planks"
|
||||
@JvmField val WHITEBARK = BlockWhitebark.BARK named "whitebark"
|
||||
@JvmField val WHITEBARK_PLANKS = BlockWhitebark.PLANKS named "whitebark_planks"
|
||||
@JvmField val WHITEBARK_STAIRS = BlockFlammableStairs(WHITEBARK_PLANKS) named "whitebark_stairs"
|
||||
@JvmField val WHITEBARK_SLAB = BlockFlammableSlab(WHITEBARK_PLANKS) named "whitebark_slab"
|
||||
|
||||
// Blocks: Building (Miner's Burial)
|
||||
|
||||
@JvmField val MINERS_BURIAL_BLOCK_PLAIN = BlockMinersBurialCube(buildMinersBurial) named "miners_burial_block_plain"
|
||||
@JvmField val MINERS_BURIAL_BLOCK_CHISELED = BlockMinersBurialCube(buildMinersBurial) named "miners_burial_block_chiseled"
|
||||
@JvmField val MINERS_BURIAL_BLOCK_PLAIN = BlockMinersBurialCube named "miners_burial_block_plain"
|
||||
@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_JAIL = BlockMinersBurialCube(buildMinersBurialIndestructible) named "miners_burial_block_jail"
|
||||
@JvmField val MINERS_BURIAL_ALTAR = BlockMinersBurialAltar(buildMinersBurialIndestructible) named "miners_burial_altar"
|
||||
@JvmField val MINERS_BURIAL_BLOCK_JAIL = BlockMinersBurialCube.INDESCRUCTIBLE named "miners_burial_block_jail"
|
||||
@JvmField val MINERS_BURIAL_ALTAR = BlockMinersBurialAltar named "miners_burial_altar"
|
||||
|
||||
// Blocks: Fluids
|
||||
|
||||
@@ -267,20 +246,20 @@ object ModBlocks {
|
||||
|
||||
// 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 LOOT_CHEST = BlockLootChest(buildLootChest) named "loot_chest"
|
||||
|
||||
// Blocks: Interactive (Puzzle)
|
||||
|
||||
@JvmField val PUZZLE_WALL = BlockPuzzleWall(buildPuzzleWall) named "puzzle_block_wall"
|
||||
@JvmField val PUZZLE_PLAIN = BlockPuzzleLogic.Plain(buildPuzzleLogic) named "puzzle_block_plain"
|
||||
@JvmField val PUZZLE_BURST_3 = BlockPuzzleLogic.Burst(buildPuzzleLogic, 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_REDIRECT_1 = BlockPuzzleLogic.RedirectSome.R1(buildPuzzleLogic) named "puzzle_block_redirect_1"
|
||||
@JvmField val PUZZLE_REDIRECT_2 = BlockPuzzleLogic.RedirectSome.R2(buildPuzzleLogic) named "puzzle_block_redirect_2"
|
||||
@JvmField val PUZZLE_REDIRECT_4 = BlockPuzzleLogic.RedirectAll(buildPuzzleLogic) named "puzzle_block_redirect_4"
|
||||
@JvmField val PUZZLE_TELEPORT = BlockPuzzleLogic.Teleport(buildPuzzleLogic) named "puzzle_block_teleport"
|
||||
@JvmField val PUZZLE_WALL = BlockPuzzleWall named "puzzle_block_wall"
|
||||
@JvmField val PUZZLE_PLAIN = BlockPuzzleLogic.Plain named "puzzle_block_plain"
|
||||
@JvmField val PUZZLE_BURST_3 = BlockPuzzleLogic.Burst(radius = 1) named "puzzle_block_burst_3"
|
||||
@JvmField val PUZZLE_BURST_5 = BlockPuzzleLogic.Burst(radius = 2) named "puzzle_block_burst_5"
|
||||
@JvmField val PUZZLE_REDIRECT_1 = BlockPuzzleLogic.RedirectOne named "puzzle_block_redirect_1"
|
||||
@JvmField val PUZZLE_REDIRECT_2 = BlockPuzzleLogic.RedirectTwo named "puzzle_block_redirect_2"
|
||||
@JvmField val PUZZLE_REDIRECT_4 = BlockPuzzleLogic.RedirectAll named "puzzle_block_redirect_4"
|
||||
@JvmField val PUZZLE_TELEPORT = BlockPuzzleLogic.Teleport named "puzzle_block_teleport"
|
||||
|
||||
// Blocks: Interactive (Gates)
|
||||
|
||||
@@ -290,14 +269,14 @@ object ModBlocks {
|
||||
// Blocks: Interactive (Uncategorized)
|
||||
|
||||
@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"
|
||||
|
||||
// Blocks: Ores
|
||||
|
||||
@JvmField val END_POWDER_ORE = BlockEndPowderOre(buildEndPowderOre) named "end_powder_ore"
|
||||
@JvmField val ENDIUM_ORE = BlockEndium.Ore(buildEndiumOre) named "endium_ore"
|
||||
@JvmField val STARDUST_ORE = BlockStardustOre(buildStardustOre) named "stardust_ore"
|
||||
@JvmField val END_POWDER_ORE = BlockEndPowderOre named "end_powder_ore"
|
||||
@JvmField val ENDIUM_ORE = BlockEndium.Ore named "endium_ore"
|
||||
@JvmField val STARDUST_ORE = BlockStardustOre named "stardust_ore"
|
||||
@JvmField val IGNEOUS_ROCK_ORE = BlockIgneousRockOre(buildIgneousRockOre) named "igneous_rock_ore"
|
||||
|
||||
// Blocks: Decorative (Trees)
|
||||
@@ -340,21 +319,21 @@ object ModBlocks {
|
||||
|
||||
// Blocks: Portals
|
||||
|
||||
@JvmField val END_PORTAL_INNER = BlockEndPortalInner(buildPortalInner) named "end_portal_inner"
|
||||
@JvmField val END_PORTAL_FRAME = BlockPortalFrame(buildPortalFrame) named "end_portal_frame"
|
||||
@JvmField val END_PORTAL_ACCEPTOR = BlockEndPortalAcceptor(buildPortalFrame) named "end_portal_acceptor"
|
||||
@JvmField val END_PORTAL_INNER = BlockEndPortalInner named "end_portal_inner"
|
||||
@JvmField val END_PORTAL_FRAME = BlockPortalFrameIndestructible named "end_portal_frame"
|
||||
@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_FRAME = BlockPortalFrame(buildPortalFrame) named "void_portal_frame"
|
||||
@JvmField val VOID_PORTAL_STORAGE = BlockVoidPortalStorage(buildPortalFrame) named "void_portal_storage"
|
||||
@JvmField val VOID_PORTAL_INNER = BlockVoidPortalInner named "void_portal_inner"
|
||||
@JvmField val VOID_PORTAL_FRAME = BlockVoidPortalFrame.Indestructible named "void_portal_frame"
|
||||
@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_STORAGE_CRAFTED = BlockVoidPortalStorageCrafted(buildPortalFrameCrafted) named "void_portal_storage_crafted"
|
||||
@JvmField val VOID_PORTAL_FRAME_CRAFTED = BlockVoidPortalFrame.Crafted named "void_portal_frame_crafted"
|
||||
@JvmField val VOID_PORTAL_STORAGE_CRAFTED = BlockVoidPortalStorage.Crafted named "void_portal_storage_crafted"
|
||||
|
||||
// Blocks: Energy
|
||||
|
||||
@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
|
||||
|
||||
@@ -375,7 +354,7 @@ object ModBlocks {
|
||||
// Blocks: Utilities
|
||||
|
||||
@JvmField val ETERNAL_FIRE = BlockEternalFire(buildEternalFire) named "eternal_fire"
|
||||
@JvmField val SCAFFOLDING = BlockScaffolding.create(buildScaffolding) named "scaffolding"
|
||||
@JvmField val SCAFFOLDING = BlockScaffolding named "scaffolding"
|
||||
|
||||
// Registry
|
||||
|
||||
@@ -586,6 +565,10 @@ object ModBlocks {
|
||||
private val temporaryItemBlocks = mutableListOf<BlockItem>()
|
||||
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 {
|
||||
this.useVanillaName(vanillaBlock)
|
||||
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;
|
||||
|
||||
import chylex.hee.game.block.interfaces.IBlockWithInterfaces;
|
||||
import chylex.hee.game.block.logic.IBlockDynamicHardness;
|
||||
import net.minecraft.block.AbstractBlock.AbstractBlockState;
|
||||
import net.minecraft.block.Block;
|
||||
@@ -19,8 +20,13 @@ public abstract class HookBlockHardness {
|
||||
final BlockState state = world.getBlockState(pos);
|
||||
final Block block = state.getBlock();
|
||||
|
||||
if (block instanceof IBlockDynamicHardness) {
|
||||
ci.setReturnValue(Float.valueOf(((IBlockDynamicHardness)block).getBlockHardness(world, pos, state, ci.getReturnValueF())));
|
||||
if (block instanceof IBlockWithInterfaces) {
|
||||
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