mirror of
https://github.com/chylex/Hardcore-Ender-Expansion-2.git
synced 2025-09-15 14:32:09 +02:00
Compare commits
4 Commits
components
...
master
Author | SHA1 | Date | |
---|---|---|---|
2cb463f0aa
|
|||
2b343108bc
|
|||
65d8d709ab
|
|||
f73bcc6635
|
11
build.gradle
11
build.gradle
@@ -16,7 +16,7 @@ buildscript {
|
|||||||
ext {
|
ext {
|
||||||
forge_gradle_version = "4.1.+"
|
forge_gradle_version = "4.1.+"
|
||||||
mixin_gradle_version = "0.7-SNAPSHOT"
|
mixin_gradle_version = "0.7-SNAPSHOT"
|
||||||
kotlin_version = "1.5.20"
|
kotlin_version = "1.7.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
@@ -83,16 +83,13 @@ allprojects {
|
|||||||
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile) {
|
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile) {
|
||||||
kotlinOptions {
|
kotlinOptions {
|
||||||
jvmTarget = "1.8"
|
jvmTarget = "1.8"
|
||||||
apiVersion = "1.5"
|
apiVersion = "1.7"
|
||||||
languageVersion = "1.5"
|
languageVersion = "1.7"
|
||||||
useIR = true
|
|
||||||
freeCompilerArgs = [
|
freeCompilerArgs = [
|
||||||
"-Xno-call-assertions",
|
"-Xno-call-assertions",
|
||||||
"-Xno-param-assertions",
|
"-Xno-param-assertions",
|
||||||
"-Xno-receiver-assertions",
|
"-Xno-receiver-assertions",
|
||||||
"-Xjvm-default=all",
|
"-XXLanguage:+InlineClasses",
|
||||||
"-Xuse-experimental=kotlin.contracts.ExperimentalContracts",
|
|
||||||
"-XXLanguage:+InlineClasses"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -580,8 +580,6 @@ e66091a13a6e7593eb5bd971978d24a5a0e375b3 data/hee/loot_tables/blocks/whitebark.j
|
|||||||
9bd3a9e24162d2c81047b834f8f79d6cabec86be data/hee/loot_tables/blocks/whitebark_planks.json
|
9bd3a9e24162d2c81047b834f8f79d6cabec86be data/hee/loot_tables/blocks/whitebark_planks.json
|
||||||
7d84dc443a052e349593b71d2c0a523e75396cdf data/hee/loot_tables/blocks/whitebark_slab.json
|
7d84dc443a052e349593b71d2c0a523e75396cdf data/hee/loot_tables/blocks/whitebark_slab.json
|
||||||
83e0b81adb3f9dd488397e8459b95f7b0ce19927 data/hee/loot_tables/blocks/whitebark_stairs.json
|
83e0b81adb3f9dd488397e8459b95f7b0ce19927 data/hee/loot_tables/blocks/whitebark_stairs.json
|
||||||
37f3c55266db3db8dc6d22fdbaf3d53243016b77 data/hee/tags/blocks/gloomrock_particles.json
|
|
||||||
1a70c674d979a59cea18d92f2227ab8a5ed2ccc7 data/hee/tags/blocks/void_portal_frame_crafted.json
|
|
||||||
f5996244831ab38fe1fae2f304bbd7825d6ad98b data/minecraft/tags/blocks/bamboo_plantable_on.json
|
f5996244831ab38fe1fae2f304bbd7825d6ad98b data/minecraft/tags/blocks/bamboo_plantable_on.json
|
||||||
479189f9b35a3c8f795539daf6a1809130242c5b data/minecraft/tags/blocks/flower_pots.json
|
479189f9b35a3c8f795539daf6a1809130242c5b data/minecraft/tags/blocks/flower_pots.json
|
||||||
424e2e03cf62f23f4496468a97b9f0df060df9fe data/minecraft/tags/blocks/impermeable.json
|
424e2e03cf62f23f4496468a97b9f0df060df9fe data/minecraft/tags/blocks/impermeable.json
|
||||||
|
@@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
"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"
|
|
||||||
]
|
|
||||||
}
|
|
@@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"replace": false,
|
|
||||||
"values": [
|
|
||||||
"hee:void_portal_frame_crafted",
|
|
||||||
"hee:void_portal_storage_crafted"
|
|
||||||
]
|
|
||||||
}
|
|
@@ -37,7 +37,7 @@ import net.minecraftforge.common.data.ExistingFileHelper
|
|||||||
class BlockModels(generator: DataGenerator, modid: String, existingFileHelper: ExistingFileHelper) : BlockModelProvider(generator, modid, existingFileHelper) {
|
class BlockModels(generator: DataGenerator, modid: String, existingFileHelper: ExistingFileHelper) : BlockModelProvider(generator, modid, existingFileHelper) {
|
||||||
override fun registerModels() {
|
override fun registerModels() {
|
||||||
for (block in ModBlocks.ALL) {
|
for (block in ModBlocks.ALL) {
|
||||||
(block as? IHeeBlock)?.let { registerModel(block, it.model.generate(block).blockModel) { builder -> builder } }
|
(block as? IHeeBlock)?.model?.let { registerModel(block, it.blockModel) { builder -> builder } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -32,7 +32,7 @@ import net.minecraftforge.common.data.ExistingFileHelper
|
|||||||
class BlockStates(generator: DataGenerator, modid: String, existingFileHelper: ExistingFileHelper) : BlockStateProvider(generator, modid, existingFileHelper) {
|
class BlockStates(generator: DataGenerator, modid: String, existingFileHelper: ExistingFileHelper) : BlockStateProvider(generator, modid, existingFileHelper) {
|
||||||
override fun registerStatesAndModels() {
|
override fun registerStatesAndModels() {
|
||||||
for (block in ModBlocks.ALL) {
|
for (block in ModBlocks.ALL) {
|
||||||
(block as? IHeeBlock)?.let { registerState(block, it.model.generate(block).blockState) }
|
(block as? IHeeBlock)?.model?.let { registerState(block, it.blockState) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -39,13 +39,15 @@ import net.minecraftforge.common.data.ExistingFileHelper
|
|||||||
class ItemModels(generator: DataGenerator, modid: String, existingFileHelper: ExistingFileHelper) : ItemModelProvider(generator, modid, existingFileHelper) {
|
class ItemModels(generator: DataGenerator, modid: String, existingFileHelper: ExistingFileHelper) : ItemModelProvider(generator, modid, existingFileHelper) {
|
||||||
override fun registerModels() {
|
override fun registerModels() {
|
||||||
for (item in ModItems.ALL) {
|
for (item in ModItems.ALL) {
|
||||||
(item as? IHeeItem)?.let { registerModel(item, it.model) }
|
(item as? IHeeItem)?.model?.let {
|
||||||
|
registerModel(item, it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (block in ModBlocks.ALL) {
|
for (block in ModBlocks.ALL) {
|
||||||
(block as? IHeeBlock)
|
(block as? IHeeBlock)?.model?.itemModel?.let {
|
||||||
?.let { it.model.generate(block).itemModel }
|
registerModel(if (it.asItem) block.asItem() else block, it.model)
|
||||||
?.let { registerModel(if (it.asItem) block.asItem() else block, it.model) }
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -6,6 +6,8 @@ import chylex.hee.client.DebugMenu
|
|||||||
import chylex.hee.client.GameModeToggle
|
import chylex.hee.client.GameModeToggle
|
||||||
import chylex.hee.client.TerritoryVoidDebug
|
import chylex.hee.client.TerritoryVoidDebug
|
||||||
import chylex.hee.game.block.BlockScaffoldingDebug
|
import chylex.hee.game.block.BlockScaffoldingDebug
|
||||||
|
import chylex.hee.game.block.HeeBlock
|
||||||
|
import chylex.hee.game.block.properties.BlockBuilder
|
||||||
import chylex.hee.game.command.client.CommandClientDebugToggles
|
import chylex.hee.game.command.client.CommandClientDebugToggles
|
||||||
import chylex.hee.game.command.client.CommandClientScaffolding
|
import chylex.hee.game.command.client.CommandClientScaffolding
|
||||||
import chylex.hee.game.command.server.CommandServerInstability
|
import chylex.hee.game.command.server.CommandServerInstability
|
||||||
@@ -43,8 +45,9 @@ internal object Debug : IDebugModule {
|
|||||||
CommandServerTestWorld
|
CommandServerTestWorld
|
||||||
)
|
)
|
||||||
|
|
||||||
override val scaffoldingBlockBehavior
|
override fun createScaffoldingBlock(builder: BlockBuilder): HeeBlock {
|
||||||
get() = BlockScaffoldingDebug
|
return BlockScaffoldingDebug(builder)
|
||||||
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
fun onClientSetup(@Suppress("UNUSED_PARAMETER") e: FMLClientSetupEvent) {
|
fun onClientSetup(@Suppress("UNUSED_PARAMETER") e: FMLClientSetupEvent) {
|
||||||
|
@@ -2,7 +2,7 @@ package chylex.hee.game.block
|
|||||||
|
|
||||||
import chylex.hee.debug.PowerShell
|
import chylex.hee.debug.PowerShell
|
||||||
import chylex.hee.game.Environment
|
import chylex.hee.game.Environment
|
||||||
import chylex.hee.game.block.components.IPlayerUseBlockComponent
|
import chylex.hee.game.block.properties.BlockBuilder
|
||||||
import chylex.hee.game.command.client.CommandClientScaffolding
|
import chylex.hee.game.command.client.CommandClientScaffolding
|
||||||
import chylex.hee.game.world.generation.structure.file.StructureFile
|
import chylex.hee.game.world.generation.structure.file.StructureFile
|
||||||
import chylex.hee.game.world.generation.util.WorldToStructureWorldAdapter
|
import chylex.hee.game.world.generation.util.WorldToStructureWorldAdapter
|
||||||
@@ -27,13 +27,14 @@ import net.minecraft.util.Direction.WEST
|
|||||||
import net.minecraft.util.Hand
|
import net.minecraft.util.Hand
|
||||||
import net.minecraft.util.Util
|
import net.minecraft.util.Util
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
|
import net.minecraft.util.math.BlockRayTraceResult
|
||||||
import net.minecraft.util.text.StringTextComponent
|
import net.minecraft.util.text.StringTextComponent
|
||||||
import net.minecraft.util.text.TextFormatting
|
import net.minecraft.util.text.TextFormatting
|
||||||
import net.minecraft.world.World
|
import net.minecraft.world.World
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
|
|
||||||
object BlockScaffoldingDebug : IPlayerUseBlockComponent {
|
class BlockScaffoldingDebug(builder: BlockBuilder) : BlockScaffolding(builder) {
|
||||||
override fun use(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, hand: Hand): ActionResultType {
|
override fun onBlockActivated(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, hit: BlockRayTraceResult): ActionResultType {
|
||||||
if (world.isRemote && player.isSneaking && !player.abilities.isFlying) {
|
if (world.isRemote && player.isSneaking && !player.abilities.isFlying) {
|
||||||
val palette = CommandClientScaffolding.currentPalette
|
val palette = CommandClientScaffolding.currentPalette
|
||||||
|
|
||||||
@@ -53,7 +54,7 @@ object BlockScaffoldingDebug : IPlayerUseBlockComponent {
|
|||||||
val box = BoundingBox(minPos, maxPos)
|
val box = BoundingBox(minPos, maxPos)
|
||||||
val serverWorld = Environment.getDimension(world.dimensionKey)
|
val serverWorld = Environment.getDimension(world.dimensionKey)
|
||||||
|
|
||||||
val (structureTag, missingMappings) = StructureFile.save(WorldToStructureWorldAdapter(serverWorld, serverWorld.rand, box.min), box.size, palette, state.block)
|
val (structureTag, missingMappings) = StructureFile.save(WorldToStructureWorldAdapter(serverWorld, serverWorld.rand, box.min), box.size, palette, this)
|
||||||
val structureFile = Files.createTempDirectory("HardcoreEnderExpansion_Structure_").resolve(CommandClientScaffolding.currentFile).toFile()
|
val structureFile = Files.createTempDirectory("HardcoreEnderExpansion_Structure_").resolve(CommandClientScaffolding.currentFile).toFile()
|
||||||
|
|
||||||
CompressedStreamTools.write(structureTag, structureFile)
|
CompressedStreamTools.write(structureTag, structureFile)
|
||||||
|
@@ -5,7 +5,7 @@ import chylex.hee.game.block.properties.BlockDrop
|
|||||||
import net.minecraft.block.Block
|
import net.minecraft.block.Block
|
||||||
import net.minecraft.loot.LootTables
|
import net.minecraft.loot.LootTables
|
||||||
|
|
||||||
open class HeeBlock(builder: BlockBuilder) : Block(builder.p), IHeeBlock { // TODO abstract
|
open class HeeBlock(builder: BlockBuilder) : Block(builder.p), IHeeBlock {
|
||||||
override val drop
|
override val drop
|
||||||
get() = if (lootTable == LootTables.EMPTY) BlockDrop.Nothing else BlockDrop.Self
|
get() = if (lootTable == LootTables.EMPTY) BlockDrop.Nothing else BlockDrop.Self
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +0,0 @@
|
|||||||
package chylex.hee.game.block
|
|
||||||
|
|
||||||
import net.minecraft.block.Block
|
|
||||||
|
|
||||||
abstract class HeeBlock2(properties: Properties) : Block(properties), IHeeBlock
|
|
@@ -1,229 +0,0 @@
|
|||||||
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,13 +1,12 @@
|
|||||||
package chylex.hee.game.block
|
package chylex.hee.game.block
|
||||||
|
|
||||||
import chylex.hee.client.text.LocalizationStrategy
|
import chylex.hee.client.text.LocalizationStrategy
|
||||||
import chylex.hee.game.block.builder.AbstractHeeBlockBuilder
|
|
||||||
import chylex.hee.game.block.properties.BlockDrop
|
import chylex.hee.game.block.properties.BlockDrop
|
||||||
import chylex.hee.game.block.properties.BlockModel
|
import chylex.hee.game.block.properties.BlockModel
|
||||||
import chylex.hee.game.block.properties.BlockRenderLayer
|
import chylex.hee.game.block.properties.BlockRenderLayer
|
||||||
import chylex.hee.game.block.properties.BlockRenderLayer.SOLID
|
import chylex.hee.game.block.properties.BlockRenderLayer.SOLID
|
||||||
import chylex.hee.game.block.properties.BlockTint
|
import chylex.hee.game.block.properties.BlockTint
|
||||||
import chylex.hee.game.block.properties.IBlockStateModelSupplier
|
import chylex.hee.game.block.properties.IBlockStateModel
|
||||||
import net.minecraft.block.Block
|
import net.minecraft.block.Block
|
||||||
import net.minecraft.tags.ITag.INamedTag
|
import net.minecraft.tags.ITag.INamedTag
|
||||||
|
|
||||||
@@ -18,7 +17,7 @@ interface IHeeBlock {
|
|||||||
val localizationExtra: Map<String, String>
|
val localizationExtra: Map<String, String>
|
||||||
get() = emptyMap()
|
get() = emptyMap()
|
||||||
|
|
||||||
val model: IBlockStateModelSupplier
|
val model: IBlockStateModel
|
||||||
get() = BlockModel.Cube
|
get() = BlockModel.Cube
|
||||||
|
|
||||||
val renderLayer: BlockRenderLayer
|
val renderLayer: BlockRenderLayer
|
||||||
@@ -32,14 +31,4 @@ interface IHeeBlock {
|
|||||||
|
|
||||||
val tags: List<INamedTag<Block>>
|
val tags: List<INamedTag<Block>>
|
||||||
get() = emptyList()
|
get() = emptyList()
|
||||||
|
|
||||||
class FromBuilder(builder: AbstractHeeBlockBuilder<*>) : IHeeBlock {
|
|
||||||
override val localization = builder.localization ?: super.localization
|
|
||||||
override val localizationExtra = builder.localizationExtra.toMap()
|
|
||||||
override val model = builder.model ?: super.model
|
|
||||||
override val renderLayer = builder.renderLayer ?: super.renderLayer
|
|
||||||
override val tint = builder.tint
|
|
||||||
override val drop = builder.drop ?: super.drop
|
|
||||||
override val tags = builder.tags.toList()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -1,149 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
@@ -1,26 +0,0 @@
|
|||||||
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)
|
|
@@ -1,86 +0,0 @@
|
|||||||
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 }
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,23 +0,0 @@
|
|||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,50 +0,0 @@
|
|||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,9 +0,0 @@
|
|||||||
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)
|
|
||||||
}
|
|
@@ -1,10 +0,0 @@
|
|||||||
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) {}
|
|
||||||
}
|
|
@@ -1,10 +0,0 @@
|
|||||||
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)
|
|
||||||
}
|
|
@@ -1,15 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,7 +0,0 @@
|
|||||||
package chylex.hee.game.block.components
|
|
||||||
|
|
||||||
import net.minecraft.tileentity.TileEntity
|
|
||||||
|
|
||||||
fun interface IBlockEntityComponent {
|
|
||||||
fun create(): TileEntity
|
|
||||||
}
|
|
@@ -1,7 +0,0 @@
|
|||||||
package chylex.hee.game.block.components
|
|
||||||
|
|
||||||
import java.util.Random
|
|
||||||
|
|
||||||
fun interface IBlockExperienceComponent {
|
|
||||||
fun getExperience(rand: Random): Int
|
|
||||||
}
|
|
@@ -1,11 +0,0 @@
|
|||||||
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)
|
|
||||||
}
|
|
@@ -1,8 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
@@ -1,19 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,10 +0,0 @@
|
|||||||
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)
|
|
||||||
}
|
|
@@ -1,21 +0,0 @@
|
|||||||
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) {}
|
|
||||||
}
|
|
@@ -1,10 +0,0 @@
|
|||||||
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)
|
|
||||||
}
|
|
@@ -1,19 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
@@ -1,30 +0,0 @@
|
|||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,11 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
@@ -1,20 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,12 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
@@ -1,10 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
@@ -1,9 +0,0 @@
|
|||||||
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]
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,6 +0,0 @@
|
|||||||
package chylex.hee.game.block.interfaces
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Marks interfaces that can be attached to blocks.
|
|
||||||
*/
|
|
||||||
interface IBlockInterface
|
|
@@ -1,15 +0,0 @@
|
|||||||
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()
|
|
||||||
}
|
|
@@ -1,7 +0,0 @@
|
|||||||
package chylex.hee.game.block.interfaces
|
|
||||||
|
|
||||||
internal object NoBlockInterfaces : IBlockWithInterfaces {
|
|
||||||
override fun getInterface(type: Class<out IBlockInterface>): Any? {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,10 +1,9 @@
|
|||||||
package chylex.hee.game.block.logic
|
package chylex.hee.game.block.logic
|
||||||
|
|
||||||
import chylex.hee.game.block.interfaces.IBlockInterface
|
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.world.IBlockReader
|
import net.minecraft.world.IBlockReader
|
||||||
|
|
||||||
interface IBlockDynamicHardness : IBlockInterface {
|
interface IBlockDynamicHardness {
|
||||||
fun getBlockHardness(world: IBlockReader, pos: BlockPos, state: BlockState, originalHardness: Float): Float
|
fun getBlockHardness(world: IBlockReader, pos: BlockPos, state: BlockState, originalHardness: Float): Float
|
||||||
}
|
}
|
||||||
|
@@ -1,11 +0,0 @@
|
|||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,21 +0,0 @@
|
|||||||
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,13 +1,7 @@
|
|||||||
package chylex.hee.game.block.properties
|
package chylex.hee.game.block.properties
|
||||||
|
|
||||||
import net.minecraft.block.Block
|
interface IBlockStateModel {
|
||||||
|
|
||||||
interface IBlockStateModel : IBlockStateModelSupplier {
|
|
||||||
val blockState: BlockStatePreset
|
val blockState: BlockStatePreset
|
||||||
val blockModel: BlockModel
|
val blockModel: BlockModel
|
||||||
val itemModel: BlockItemModel?
|
val itemModel: BlockItemModel?
|
||||||
|
|
||||||
override fun generate(block: Block): IBlockStateModel {
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +0,0 @@
|
|||||||
package chylex.hee.game.block.properties
|
|
||||||
|
|
||||||
import net.minecraft.block.Block
|
|
||||||
|
|
||||||
fun interface IBlockStateModelSupplier {
|
|
||||||
fun generate(block: Block): IBlockStateModel
|
|
||||||
}
|
|
@@ -1,19 +0,0 @@
|
|||||||
package chylex.hee.game.block.properties
|
|
||||||
|
|
||||||
import net.minecraft.block.Block
|
|
||||||
import net.minecraft.util.math.BlockPos
|
|
||||||
import net.minecraft.world.World
|
|
||||||
|
|
||||||
sealed class TickSchedule {
|
|
||||||
abstract fun schedule(world: World, pos: BlockPos, block: Block)
|
|
||||||
|
|
||||||
object Never : TickSchedule() {
|
|
||||||
override fun schedule(world: World, pos: BlockPos, block: Block) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
class InTicks(private val ticks: Int) : TickSchedule() {
|
|
||||||
override fun schedule(world: World, pos: BlockPos, block: Block) {
|
|
||||||
world.pendingBlockTicks.scheduleTick(pos, block, ticks)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -2,8 +2,8 @@ package chylex.hee.game.item.components
|
|||||||
|
|
||||||
import net.minecraft.item.ItemStack
|
import net.minecraft.item.ItemStack
|
||||||
import net.minecraft.util.text.ITextComponent
|
import net.minecraft.util.text.ITextComponent
|
||||||
import net.minecraft.world.IBlockReader
|
import net.minecraft.world.World
|
||||||
|
|
||||||
fun interface ITooltipComponent {
|
fun interface ITooltipComponent {
|
||||||
fun add(lines: MutableList<ITextComponent>, stack: ItemStack, advanced: Boolean, world: IBlockReader?)
|
fun add(lines: MutableList<ITextComponent>, stack: ItemStack, advanced: Boolean, world: World?)
|
||||||
}
|
}
|
||||||
|
@@ -2,10 +2,10 @@ package chylex.hee.game.item.components
|
|||||||
|
|
||||||
import net.minecraft.item.ItemStack
|
import net.minecraft.item.ItemStack
|
||||||
import net.minecraft.util.text.ITextComponent
|
import net.minecraft.util.text.ITextComponent
|
||||||
import net.minecraft.world.IBlockReader
|
import net.minecraft.world.World
|
||||||
|
|
||||||
class StaticTooltipComponent(private vararg val lines: ITextComponent) : ITooltipComponent {
|
class StaticTooltipComponent(private vararg val lines: ITextComponent) : ITooltipComponent {
|
||||||
override fun add(lines: MutableList<ITextComponent>, stack: ItemStack, advanced: Boolean, world: IBlockReader?) {
|
override fun add(lines: MutableList<ITextComponent>, stack: ItemStack, advanced: Boolean, world: World?) {
|
||||||
lines.addAll(this.lines)
|
lines.addAll(this.lines)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,6 @@
|
|||||||
package chylex.hee.game.world.generation.noise
|
package chylex.hee.game.world.generation.noise
|
||||||
|
|
||||||
import chylex.hee.util.math.FloatRange
|
import chylex.hee.util.math.remap
|
||||||
import chylex.hee.util.math.range
|
|
||||||
import chylex.hee.util.math.remapRange
|
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
import kotlin.math.pow
|
import kotlin.math.pow
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
@@ -28,12 +26,12 @@ class NoiseValue(var value: Double) {
|
|||||||
it.coerceIn(minimum, maximum)
|
it.coerceIn(minimum, maximum)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun remap(oldRange: FloatRange, newRange: FloatRange) = then {
|
fun remap(fromMin: Double, fromMax: Double, toMin: Double, toMax: Double) = then {
|
||||||
remapRange(it, oldRange, newRange)
|
it.remap(fromMin, fromMax, toMin, toMax)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun remap(newRange: FloatRange) = then {
|
fun remap(toMin: Double, toMax: Double) = then {
|
||||||
remapRange(it, range(0F, 1F), newRange)
|
it.remap(fromMin = 0.0, fromMax = 1.0, toMin, toMax)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun ifNonZero(block: NoiseValue.() -> Unit) {
|
inline fun ifNonZero(block: NoiseValue.() -> Unit) {
|
||||||
|
@@ -1,11 +1,13 @@
|
|||||||
package chylex.hee.system
|
package chylex.hee.system
|
||||||
|
|
||||||
import chylex.hee.game.block.components.IPlayerUseBlockComponent
|
import chylex.hee.game.block.HeeBlock
|
||||||
|
import chylex.hee.game.block.properties.BlockBuilder
|
||||||
import chylex.hee.game.command.IClientCommand
|
import chylex.hee.game.command.IClientCommand
|
||||||
import chylex.hee.game.command.ICommand
|
import chylex.hee.game.command.ICommand
|
||||||
|
|
||||||
interface IDebugModule {
|
interface IDebugModule {
|
||||||
val clientCommands: List<IClientCommand>
|
val clientCommands: List<IClientCommand>
|
||||||
val serverCommands: List<ICommand>
|
val serverCommands: List<ICommand>
|
||||||
val scaffoldingBlockBehavior: IPlayerUseBlockComponent?
|
|
||||||
|
fun createScaffoldingBlock(builder: BlockBuilder): HeeBlock
|
||||||
}
|
}
|
||||||
|
@@ -18,54 +18,65 @@ import net.minecraft.util.math.BlockPos
|
|||||||
import net.minecraft.util.math.vector.Vector3d
|
import net.minecraft.util.math.vector.Vector3d
|
||||||
import org.apache.logging.log4j.Logger
|
import org.apache.logging.log4j.Logger
|
||||||
|
|
||||||
inline fun <T : PacketBuffer> T.use(block: T.() -> Unit) {
|
|
||||||
block()
|
|
||||||
}
|
|
||||||
|
|
||||||
// BlockPos
|
// BlockPos
|
||||||
|
|
||||||
inline fun PacketBuffer.writePos(pos: BlockPos) {
|
inline fun ByteBuf.writePos(pos: BlockPos) {
|
||||||
this.writeLong(pos.toLong())
|
this.writeLong(pos.toLong())
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun PacketBuffer.readPos(): BlockPos {
|
inline fun ByteBuf.readPos(): BlockPos {
|
||||||
return Pos(this.readLong())
|
return Pos(this.readLong())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vec3d (Full)
|
// Vec3d (Full)
|
||||||
|
|
||||||
fun PacketBuffer.writeVec(vec: Vector3d) {
|
fun ByteBuf.writeVec(vec: Vector3d) {
|
||||||
this.writeDouble(vec.x)
|
this.writeDouble(vec.x)
|
||||||
this.writeDouble(vec.y)
|
this.writeDouble(vec.y)
|
||||||
this.writeDouble(vec.z)
|
this.writeDouble(vec.z)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun PacketBuffer.readVec(): Vector3d {
|
fun ByteBuf.readVec(): Vector3d {
|
||||||
return Vec(readDouble(), readDouble(), readDouble())
|
return Vec(this.readDouble(), this.readDouble(), this.readDouble())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vec3d (Float)
|
// Vec3d (Float)
|
||||||
|
|
||||||
fun PacketBuffer.writeFloatVec(vec: Vector3d) {
|
fun ByteBuf.writeFloatVec(vec: Vector3d) {
|
||||||
this.writeFloat(vec.x.toFloat())
|
this.writeFloat(vec.x.toFloat())
|
||||||
this.writeFloat(vec.y.toFloat())
|
this.writeFloat(vec.y.toFloat())
|
||||||
this.writeFloat(vec.z.toFloat())
|
this.writeFloat(vec.z.toFloat())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun PacketBuffer.readFloatVec(): Vector3d {
|
fun ByteBuf.readFloatVec(): Vector3d {
|
||||||
return Vec(readFloat().toDouble(), readFloat().toDouble(), readFloat().toDouble())
|
return Vec(this.readFloat().toDouble(), this.readFloat().toDouble(), this.readFloat().toDouble())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vec3d (Compact)
|
// Vec3d (Compact)
|
||||||
|
|
||||||
fun PacketBuffer.writeCompactVec(vec: Vector3d) {
|
fun ByteBuf.writeCompactVec(vec: Vector3d) {
|
||||||
this.writeInt((vec.x * 8.0).floorToInt())
|
this.writeInt((vec.x * 8.0).floorToInt())
|
||||||
this.writeInt((vec.y * 8.0).floorToInt())
|
this.writeInt((vec.y * 8.0).floorToInt())
|
||||||
this.writeInt((vec.z * 8.0).floorToInt())
|
this.writeInt((vec.z * 8.0).floorToInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun PacketBuffer.readCompactVec(): Vector3d {
|
fun ByteBuf.readCompactVec(): Vector3d {
|
||||||
return Vec(readInt() * 0.125, readInt() * 0.125, readInt() * 0.125)
|
return Vec(this.readInt() * 0.125, this.readInt() * 0.125, this.readInt() * 0.125)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enum
|
||||||
|
|
||||||
|
fun <T : Enum<T>> PacketBuffer.writeEnum(value: T?) {
|
||||||
|
this.writeVarInt(value?.ordinal ?: -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified T : Enum<T>> PacketBuffer.readEnum(): T? {
|
||||||
|
val ordinal = this.readVarInt()
|
||||||
|
|
||||||
|
return if (ordinal >= 0)
|
||||||
|
T::class.java.enumConstants.getOrNull(ordinal)
|
||||||
|
else
|
||||||
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
// NBT
|
// NBT
|
||||||
|
@@ -1,16 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
@@ -46,17 +46,17 @@ fun lerp(from: Double, to: Double, progress: Double): Double {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps a range of values in [from] range to values in [to] range using linear interpolation.
|
* Remaps a value from the range [[fromMin], [fromMax]] to a value in the range [[toMin], [toMax]] using linear interpolation.
|
||||||
*/
|
*/
|
||||||
fun remapRange(value: Float, from: FloatRange, to: FloatRange): Float {
|
fun Float.remap(fromMin: Float, fromMax: Float, toMin: Float, toMax: Float): Float {
|
||||||
val remappedBetween0And1 = (value - from.start) / (from.end - from.start)
|
val remappedBetween0And1 = (this - fromMin) / (fromMax - fromMin)
|
||||||
return to.start + remappedBetween0And1 * (to.end - to.start)
|
return toMin + remappedBetween0And1 * (toMax - toMin)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps a range of values in [from] range to values in [to] range using linear interpolation.
|
* Remaps a value from the range [[fromMin], [fromMax]] to a value in the range [[toMin], [toMax]] using linear interpolation.
|
||||||
*/
|
*/
|
||||||
fun remapRange(value: Double, from: FloatRange, to: FloatRange): Double {
|
fun Double.remap(fromMin: Double, fromMax: Double, toMin: Double, toMax: Double): Double {
|
||||||
val remappedBetween0And1 = (value - from.start) / (from.end - from.start)
|
val remappedBetween0And1 = (this - fromMin) / (fromMax - fromMin)
|
||||||
return to.start + remappedBetween0And1 * (to.end - to.start)
|
return toMin + remappedBetween0And1 * (toMax - toMin)
|
||||||
}
|
}
|
||||||
|
@@ -1,14 +0,0 @@
|
|||||||
package chylex.hee.util.math
|
|
||||||
|
|
||||||
@JvmInline
|
|
||||||
value class FloatRange(private val combined: Long) {
|
|
||||||
constructor(start: Float, end: Float) : this((start.toRawBits() shlong 32) or (end.toRawBits().toLong() and 0xFFFF_FFFFL))
|
|
||||||
|
|
||||||
val start
|
|
||||||
get() = Float.fromBits((combined ushr 32).toInt())
|
|
||||||
|
|
||||||
val end
|
|
||||||
get() = Float.fromBits((combined and 0xFFFF_FFFFL).toInt())
|
|
||||||
}
|
|
||||||
|
|
||||||
fun range(start: Float, end: Float) = FloatRange(start, end)
|
|
@@ -15,6 +15,7 @@ import net.minecraftforge.common.util.Constants.NBT
|
|||||||
import org.apache.logging.log4j.Logger
|
import org.apache.logging.log4j.Logger
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
import kotlin.contracts.ExperimentalContracts
|
||||||
import kotlin.contracts.contract
|
import kotlin.contracts.contract
|
||||||
|
|
||||||
typealias NBTBase = net.minecraft.nbt.INBT
|
typealias NBTBase = net.minecraft.nbt.INBT
|
||||||
@@ -54,12 +55,14 @@ inline fun TagCompound.hasKey(key: String, type: Int): Boolean {
|
|||||||
return this.contains(key, type)
|
return this.contains(key, type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalContracts::class)
|
||||||
@JvmName("isNotNullAndHasKey")
|
@JvmName("isNotNullAndHasKey")
|
||||||
inline fun TagCompound?.hasKey(key: String): Boolean {
|
inline fun TagCompound?.hasKey(key: String): Boolean {
|
||||||
contract { returns(true) implies (this@hasKey != null) }
|
contract { returns(true) implies (this@hasKey != null) }
|
||||||
return this != null && this.hasKey(key)
|
return this != null && this.hasKey(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalContracts::class)
|
||||||
@JvmName("isNotNullAndHasKey")
|
@JvmName("isNotNullAndHasKey")
|
||||||
inline fun TagCompound?.hasKey(key: String, type: Int): Boolean {
|
inline fun TagCompound?.hasKey(key: String, type: Int): Boolean {
|
||||||
contract { returns(true) implies (this@hasKey != null) }
|
contract { returns(true) implies (this@hasKey != null) }
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
package chylex.hee.util.random
|
package chylex.hee.util.random
|
||||||
|
|
||||||
import chylex.hee.util.math.range
|
import chylex.hee.util.math.remap
|
||||||
import chylex.hee.util.math.remapRange
|
|
||||||
import java.util.Random
|
import java.util.Random
|
||||||
import kotlin.math.pow
|
import kotlin.math.pow
|
||||||
|
|
||||||
@@ -30,7 +29,7 @@ abstract class RandomDouble private constructor(val min: Double, val max: Double
|
|||||||
|
|
||||||
fun Exp(min: Double, max: Double, exp: Double) = object : RandomDouble(min, max) {
|
fun Exp(min: Double, max: Double, exp: Double) = object : RandomDouble(min, max) {
|
||||||
override fun invoke(rand: Random): Double {
|
override fun invoke(rand: Random): Double {
|
||||||
return remapRange(rand.nextDouble().pow(exp), range(0F, 1F), range(min.toFloat(), max.toFloat()))
|
return rand.nextDouble().pow(exp).remap(fromMin = 0.0, fromMax = 1.0, toMin = min, toMax = max)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +1,5 @@
|
|||||||
|
rootProject.name = "HEE"
|
||||||
|
|
||||||
include ":util"
|
include ":util"
|
||||||
include ":system"
|
include ":system"
|
||||||
include ":debug"
|
include ":debug"
|
||||||
|
@@ -10,7 +10,6 @@ import chylex.hee.client.util.MC
|
|||||||
import chylex.hee.game.Resource
|
import chylex.hee.game.Resource
|
||||||
import chylex.hee.game.block.BlockAbstractPortal
|
import chylex.hee.game.block.BlockAbstractPortal
|
||||||
import chylex.hee.game.block.entity.TileEntityEnergyCluster
|
import chylex.hee.game.block.entity.TileEntityEnergyCluster
|
||||||
import chylex.hee.game.block.interfaces.getHeeInterface
|
|
||||||
import chylex.hee.game.block.properties.Materials
|
import chylex.hee.game.block.properties.Materials
|
||||||
import chylex.hee.game.mechanics.energy.IClusterOracleItem
|
import chylex.hee.game.mechanics.energy.IClusterOracleItem
|
||||||
import chylex.hee.game.mechanics.energy.IEnergyQuantity
|
import chylex.hee.game.mechanics.energy.IEnergyQuantity
|
||||||
@@ -36,7 +35,7 @@ import net.minecraftforge.client.event.RenderGameOverlayEvent
|
|||||||
import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType.HELMET
|
import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType.HELMET
|
||||||
|
|
||||||
@SubscribeAllEvents(Side.CLIENT, modid = HEE.ID)
|
@SubscribeAllEvents(Side.CLIENT, modid = HEE.ID)
|
||||||
object OverlayRenderer { // TODO move to appropriate block builders
|
object OverlayRenderer {
|
||||||
private const val BORDER_SIZE = 4
|
private const val BORDER_SIZE = 4
|
||||||
private const val LINE_SPACING = 7
|
private const val LINE_SPACING = 7
|
||||||
|
|
||||||
@@ -148,7 +147,7 @@ object OverlayRenderer { // TODO move to appropriate block builders
|
|||||||
clusterLookedAt = pos.getTile(world)
|
clusterLookedAt = pos.getTile(world)
|
||||||
e.isCanceled = true
|
e.isCanceled = true
|
||||||
}
|
}
|
||||||
else if (block.getHeeInterface<BlockAbstractPortal.IInnerPortalBlock>() != null) {
|
else if (block is BlockAbstractPortal) {
|
||||||
e.isCanceled = true
|
e.isCanceled = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -25,8 +25,7 @@ import chylex.hee.util.forge.SubscribeAllEvents
|
|||||||
import chylex.hee.util.forge.SubscribeEvent
|
import chylex.hee.util.forge.SubscribeEvent
|
||||||
import chylex.hee.util.math.LerpedFloat
|
import chylex.hee.util.math.LerpedFloat
|
||||||
import chylex.hee.util.math.floorToInt
|
import chylex.hee.util.math.floorToInt
|
||||||
import chylex.hee.util.math.range
|
import chylex.hee.util.math.remap
|
||||||
import chylex.hee.util.math.remapRange
|
|
||||||
import chylex.hee.util.math.scale
|
import chylex.hee.util.math.scale
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack
|
import com.mojang.blaze3d.matrix.MatrixStack
|
||||||
import com.mojang.blaze3d.platform.GlStateManager.FogMode.EXP2
|
import com.mojang.blaze3d.platform.GlStateManager.FogMode.EXP2
|
||||||
@@ -118,7 +117,7 @@ object TerritoryRenderer {
|
|||||||
// Fog rendering
|
// Fog rendering
|
||||||
|
|
||||||
private val currentFogDensityMp
|
private val currentFogDensityMp
|
||||||
get() = 1F + (9F * remapRange(currentVoidFactor, range(-0.5F, 1F), range(0F, 1F)).coerceIn(0F, 1F).pow(1.5F))
|
get() = 1F + (9F * currentVoidFactor.remap(fromMin = -0.5F, fromMax = 1F, toMin = 0F, toMax = 1F).coerceIn(0F, 1F).pow(1.5F))
|
||||||
|
|
||||||
private val currentRenderDistanceMp
|
private val currentRenderDistanceMp
|
||||||
get() = MC.settings.renderDistanceChunks.let { if (it > 12) 0F else (1F - (it / 16.5F)).pow((it - 1) * 0.25F) }
|
get() = MC.settings.renderDistanceChunks.let { if (it > 12) 0F else (1F - (it / 16.5F)).pow((it - 1) * 0.25F) }
|
||||||
@@ -148,7 +147,7 @@ object TerritoryRenderer {
|
|||||||
get() = Void.voidFactor.get(MC.partialTicks)
|
get() = Void.voidFactor.get(MC.partialTicks)
|
||||||
|
|
||||||
val currentSkyAlpha
|
val currentSkyAlpha
|
||||||
get() = remapRange(currentVoidFactor, range(-1F, 0.5F), range(1F, 0F)).coerceIn(0F, 1F)
|
get() = currentVoidFactor.remap(fromMin = -1F, fromMax = 0.5F, toMin = 1F, toMax = 0F).coerceIn(0F, 1F)
|
||||||
|
|
||||||
private object Void {
|
private object Void {
|
||||||
private val VOID_PARTICLE = ParticleSpawnerCustom(
|
private val VOID_PARTICLE = ParticleSpawnerCustom(
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
package chylex.hee.client.render.block
|
package chylex.hee.client.render.block
|
||||||
|
|
||||||
import chylex.hee.game.block.BlockAbstractPortal
|
import chylex.hee.game.block.BlockAbstractPortal
|
||||||
|
import chylex.hee.game.block.BlockVoidPortalInner.Companion.TYPE
|
||||||
import chylex.hee.game.block.BlockVoidPortalInner.ITerritoryInstanceFactory
|
import chylex.hee.game.block.BlockVoidPortalInner.ITerritoryInstanceFactory
|
||||||
import chylex.hee.game.block.BlockVoidPortalInner.IVoidPortalController
|
import chylex.hee.game.block.BlockVoidPortalInner.IVoidPortalController
|
||||||
import chylex.hee.game.block.BlockVoidPortalInner.TYPE
|
|
||||||
import chylex.hee.game.block.BlockVoidPortalInner.Type.HUB
|
import chylex.hee.game.block.BlockVoidPortalInner.Type.HUB
|
||||||
import chylex.hee.game.block.BlockVoidPortalInner.Type.RETURN_ACTIVE
|
import chylex.hee.game.block.BlockVoidPortalInner.Type.RETURN_ACTIVE
|
||||||
import chylex.hee.game.block.entity.TileEntityPortalInner
|
import chylex.hee.game.block.entity.TileEntityPortalInner
|
||||||
|
@@ -49,13 +49,13 @@ class RenderEntityTokenHolder(manager: EntityRendererManager) : EntityRenderer<E
|
|||||||
matrix.rotateX(55F)
|
matrix.rotateX(55F)
|
||||||
matrix.rotateZ(55F)
|
matrix.rotateZ(55F)
|
||||||
|
|
||||||
ModelEntityTokenHolder.render(matrix, buffer.getBuffer(RenderType.getEntityTranslucent(getEntityTexture(entity) ?: textures.getValue(NORMAL))), combinedLight, OverlayTexture.NO_OVERLAY, 1F, 1F, 1F, alpha)
|
ModelEntityTokenHolder.render(matrix, buffer.getBuffer(RenderType.getEntityTranslucent(getEntityTexture(entity))), combinedLight, OverlayTexture.NO_OVERLAY, 1F, 1F, 1F, alpha)
|
||||||
|
|
||||||
matrix.pop()
|
matrix.pop()
|
||||||
matrix.pop()
|
matrix.pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getEntityTexture(entity: EntityTokenHolder): ResourceLocation? {
|
override fun getEntityTexture(entity: EntityTokenHolder): ResourceLocation {
|
||||||
return textures[entity.tokenType]
|
return textures.getValue(entity.tokenType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,51 +0,0 @@
|
|||||||
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,15 +1,11 @@
|
|||||||
package chylex.hee.game.block
|
package chylex.hee.game.block
|
||||||
|
|
||||||
import chylex.hee.client.text.LocalizationStrategy
|
import chylex.hee.client.text.LocalizationStrategy
|
||||||
import chylex.hee.game.block.builder.HeeBlockBuilder
|
import chylex.hee.game.block.properties.BlockBuilder
|
||||||
import chylex.hee.game.block.components.IBlockCollideWithEntityComponent
|
|
||||||
import chylex.hee.game.block.components.IBlockEntityComponent
|
|
||||||
import chylex.hee.game.block.components.IBlockShapeComponent
|
|
||||||
import chylex.hee.game.block.interfaces.IBlockInterface
|
|
||||||
import chylex.hee.game.block.properties.BlockModel
|
import chylex.hee.game.block.properties.BlockModel
|
||||||
import chylex.hee.game.block.properties.BlockStateModel
|
import chylex.hee.game.block.properties.BlockStateModel
|
||||||
import chylex.hee.game.block.properties.BlockStatePreset
|
import chylex.hee.game.block.properties.BlockStatePreset
|
||||||
import chylex.hee.game.entity.util.EntityPortalContact
|
import chylex.hee.game.block.util.asVoxelShape
|
||||||
import chylex.hee.game.world.util.Facing4
|
import chylex.hee.game.world.util.Facing4
|
||||||
import chylex.hee.game.world.util.allInBox
|
import chylex.hee.game.world.util.allInBox
|
||||||
import chylex.hee.game.world.util.allInBoxMutable
|
import chylex.hee.game.world.util.allInBoxMutable
|
||||||
@@ -28,27 +24,25 @@ import net.minecraft.block.Block
|
|||||||
import net.minecraft.block.BlockRenderType.INVISIBLE
|
import net.minecraft.block.BlockRenderType.INVISIBLE
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.block.Blocks
|
import net.minecraft.block.Blocks
|
||||||
import net.minecraft.block.SoundType
|
|
||||||
import net.minecraft.block.material.Material
|
|
||||||
import net.minecraft.block.material.MaterialColor
|
|
||||||
import net.minecraft.entity.Entity
|
import net.minecraft.entity.Entity
|
||||||
import net.minecraft.tags.BlockTags
|
import net.minecraft.tags.BlockTags
|
||||||
import net.minecraft.tileentity.TileEntity
|
import net.minecraft.tileentity.TileEntity
|
||||||
|
import net.minecraft.util.math.AxisAlignedBB
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
|
import net.minecraft.util.math.shapes.ISelectionContext
|
||||||
import net.minecraft.util.math.shapes.VoxelShape
|
import net.minecraft.util.math.shapes.VoxelShape
|
||||||
import net.minecraft.util.math.shapes.VoxelShapes
|
import net.minecraft.world.IBlockReader
|
||||||
import net.minecraft.world.World
|
import net.minecraft.world.World
|
||||||
|
|
||||||
class BlockAbstractPortal(impl: IInnerPortalBlock) : HeeBlockBuilder() {
|
abstract class BlockAbstractPortal(builder: BlockBuilder) : BlockSimpleShaped(builder, AxisAlignedBB(0.0, 0.0, 0.0, 1.0, 0.75, 1.0)) {
|
||||||
companion object {
|
companion object {
|
||||||
const val MAX_DISTANCE_FROM_FRAME = 6.0
|
const val MAX_DISTANCE_FROM_FRAME = 6.0
|
||||||
const val MAX_SIZE = 5
|
const val MAX_SIZE = 5
|
||||||
|
|
||||||
private const val TRANSLATION_SPEED_LONG = 600000L
|
const val TRANSLATION_SPEED_LONG = 600000L
|
||||||
const val TRANSLATION_SPEED_INV = 1.0 / TRANSLATION_SPEED_LONG
|
const val TRANSLATION_SPEED_INV = 1.0 / TRANSLATION_SPEED_LONG
|
||||||
|
|
||||||
private val SHAPE = VoxelShapes.create(0.0, 0.0, 0.0, 1.0, 0.75, 1.0)
|
private val COLLISION_AABB = AxisAlignedBB(0.0, 0.0, 0.0, 1.0, 0.025, 1.0).asVoxelShape
|
||||||
private val COLLISION_SHAPE = VoxelShapes.create(0.0, 0.0, 0.0, 1.0, 0.025, 1.0)
|
|
||||||
|
|
||||||
fun findInnerArea(world: World, controllerPos: BlockPos, frameBlock: Block): Pair<BlockPos, BlockPos>? {
|
fun findInnerArea(world: World, controllerPos: BlockPos, frameBlock: Block): Pair<BlockPos, BlockPos>? {
|
||||||
val mirrorRange = 1..(MAX_SIZE + 1)
|
val mirrorRange = 1..(MAX_SIZE + 1)
|
||||||
@@ -100,52 +94,36 @@ class BlockAbstractPortal(impl: IInnerPortalBlock) : HeeBlockBuilder() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
|
||||||
includeFrom(BlockIndestructible)
|
|
||||||
|
|
||||||
localization = LocalizationStrategy.DeleteWords("Inner")
|
|
||||||
|
|
||||||
model = BlockStateModel(BlockStatePreset.SimpleFrom(Blocks.END_PORTAL), BlockModel.Manual)
|
|
||||||
|
|
||||||
material = Material.PORTAL
|
|
||||||
color = MaterialColor.BLACK
|
|
||||||
sound = SoundType.STONE
|
|
||||||
light = 15
|
|
||||||
|
|
||||||
isSolid = false
|
|
||||||
|
|
||||||
tags.add(BlockTags.PORTALS)
|
|
||||||
|
|
||||||
components.shape = object : IBlockShapeComponent {
|
|
||||||
override fun getShape(state: BlockState): VoxelShape {
|
|
||||||
return SHAPE
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getCollisionShape(state: BlockState): VoxelShape? {
|
|
||||||
return COLLISION_SHAPE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
components.renderType = INVISIBLE
|
|
||||||
|
|
||||||
components.entity = IBlockEntityComponent(impl::createTileEntity)
|
|
||||||
|
|
||||||
components.collideWithEntity = IBlockCollideWithEntityComponent { _, world, pos, entity ->
|
|
||||||
if (!world.isRemote && !entity.isPassenger && !entity.isBeingRidden && entity.canChangeDimension() && entity.posY <= pos.y + 0.05 && EntityPortalContact.shouldTeleport(entity)) {
|
|
||||||
impl.teleportEntity(world, pos, entity)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
interfaces[IInnerPortalBlock::class.java] = impl
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IInnerPortalBlock : IBlockInterface {
|
|
||||||
fun createTileEntity(): TileEntity
|
|
||||||
fun teleportEntity(world: World, pos: BlockPos, entity: Entity)
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IPortalController {
|
interface IPortalController {
|
||||||
val clientAnimationProgress: LerpedFloat
|
val clientAnimationProgress: LerpedFloat
|
||||||
val clientPortalOffset: LerpedFloat
|
val clientPortalOffset: LerpedFloat
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final override val localization
|
||||||
|
get() = LocalizationStrategy.DeleteWords("Inner")
|
||||||
|
|
||||||
|
final override val model
|
||||||
|
get() = BlockStateModel(BlockStatePreset.SimpleFrom(Blocks.END_PORTAL), BlockModel.Manual)
|
||||||
|
|
||||||
|
final override val tags
|
||||||
|
get() = listOf(BlockTags.PORTALS)
|
||||||
|
|
||||||
|
override fun hasTileEntity(state: BlockState): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract override fun createTileEntity(state: BlockState, world: IBlockReader): TileEntity
|
||||||
|
protected abstract fun onEntityInside(world: World, pos: BlockPos, entity: Entity)
|
||||||
|
|
||||||
|
final override fun onEntityCollision(state: BlockState, world: World, pos: BlockPos, entity: Entity) {
|
||||||
|
if (!world.isRemote && !entity.isPassenger && !entity.isBeingRidden && entity.canChangeDimension() && entity.posY <= pos.y + 0.05) {
|
||||||
|
onEntityInside(world, pos, entity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getCollisionShape(state: BlockState, world: IBlockReader, pos: BlockPos, context: ISelectionContext): VoxelShape {
|
||||||
|
return COLLISION_AABB
|
||||||
|
}
|
||||||
|
|
||||||
|
final override fun getRenderType(state: BlockState) = INVISIBLE
|
||||||
}
|
}
|
||||||
|
@@ -5,18 +5,11 @@ import chylex.hee.game.Resource.location
|
|||||||
import chylex.hee.game.block.BlockCorruptedEnergy.SpawnResult.FAIL
|
import chylex.hee.game.block.BlockCorruptedEnergy.SpawnResult.FAIL
|
||||||
import chylex.hee.game.block.BlockCorruptedEnergy.SpawnResult.PASSTHROUGH
|
import chylex.hee.game.block.BlockCorruptedEnergy.SpawnResult.PASSTHROUGH
|
||||||
import chylex.hee.game.block.BlockCorruptedEnergy.SpawnResult.SUCCESS
|
import chylex.hee.game.block.BlockCorruptedEnergy.SpawnResult.SUCCESS
|
||||||
import chylex.hee.game.block.builder.HeeBlockBuilder
|
|
||||||
import chylex.hee.game.block.components.IBlockClientEffectsComponent
|
|
||||||
import chylex.hee.game.block.components.IBlockCollideWithEntityComponent
|
|
||||||
import chylex.hee.game.block.components.IBlockRandomTickComponent
|
|
||||||
import chylex.hee.game.block.components.IBlockScheduledTickComponent
|
|
||||||
import chylex.hee.game.block.entity.TileEntityEnergyCluster
|
import chylex.hee.game.block.entity.TileEntityEnergyCluster
|
||||||
import chylex.hee.game.block.properties.BlockDrop
|
import chylex.hee.game.block.properties.BlockBuilder
|
||||||
import chylex.hee.game.block.properties.BlockModel
|
import chylex.hee.game.block.properties.BlockModel
|
||||||
import chylex.hee.game.block.properties.BlockStateModel
|
import chylex.hee.game.block.properties.BlockStateModel
|
||||||
import chylex.hee.game.block.properties.BlockStatePreset
|
import chylex.hee.game.block.properties.BlockStatePreset
|
||||||
import chylex.hee.game.block.properties.Materials
|
|
||||||
import chylex.hee.game.block.properties.TickSchedule
|
|
||||||
import chylex.hee.game.block.util.Property
|
import chylex.hee.game.block.util.Property
|
||||||
import chylex.hee.game.block.util.with
|
import chylex.hee.game.block.util.with
|
||||||
import chylex.hee.game.entity.CustomCreatureType
|
import chylex.hee.game.entity.CustomCreatureType
|
||||||
@@ -42,123 +35,60 @@ import chylex.hee.game.world.util.getTile
|
|||||||
import chylex.hee.game.world.util.removeBlock
|
import chylex.hee.game.world.util.removeBlock
|
||||||
import chylex.hee.game.world.util.setState
|
import chylex.hee.game.world.util.setState
|
||||||
import chylex.hee.init.ModBlocks
|
import chylex.hee.init.ModBlocks
|
||||||
|
import chylex.hee.util.forge.Side
|
||||||
|
import chylex.hee.util.forge.Sided
|
||||||
import chylex.hee.util.random.nextInt
|
import chylex.hee.util.random.nextInt
|
||||||
import chylex.hee.util.random.removeItem
|
import chylex.hee.util.random.removeItem
|
||||||
|
import net.minecraft.block.Block
|
||||||
import net.minecraft.block.BlockRenderType.INVISIBLE
|
import net.minecraft.block.BlockRenderType.INVISIBLE
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.block.Blocks
|
import net.minecraft.block.Blocks
|
||||||
import net.minecraft.block.SoundType
|
import net.minecraft.entity.Entity
|
||||||
import net.minecraft.block.material.MaterialColor
|
|
||||||
import net.minecraft.entity.LivingEntity
|
import net.minecraft.entity.LivingEntity
|
||||||
|
import net.minecraft.state.StateContainer.Builder
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
|
import net.minecraft.world.IBlockReader
|
||||||
import net.minecraft.world.World
|
import net.minecraft.world.World
|
||||||
|
import net.minecraft.world.server.ServerWorld
|
||||||
import java.util.Random
|
import java.util.Random
|
||||||
|
|
||||||
object BlockCorruptedEnergy : HeeBlockBuilder() {
|
class BlockCorruptedEnergy(builder: BlockBuilder) : HeeBlock(builder) {
|
||||||
private const val MIN_LEVEL = 0
|
companion object {
|
||||||
private const val MAX_LEVEL = 20
|
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
|
|
||||||
|
|
||||||
material = Materials.CORRUPTED_ENERGY
|
private const val MAX_TICK_RATE = 5
|
||||||
color = MaterialColor.PURPLE
|
private const val MIN_TICK_RATE = 1
|
||||||
sound = SoundType.SAND
|
|
||||||
|
|
||||||
isSolid = false
|
val LEVEL = Property.int("level", MIN_LEVEL..MAX_LEVEL)
|
||||||
|
|
||||||
drop = BlockDrop.Nothing
|
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))
|
||||||
|
|
||||||
components.states.set(LEVEL, MIN_LEVEL)
|
private val PARTICLE_CORRUPTION = ParticleSpawnerCustom(
|
||||||
|
type = ParticleCorruptedEnergy,
|
||||||
|
pos = InBox(0.75F),
|
||||||
|
mot = InBox(0.05F),
|
||||||
|
hideOnMinimalSetting = false
|
||||||
|
)
|
||||||
|
|
||||||
components.renderType = INVISIBLE
|
private fun tickRateForLevel(level: Int): Int {
|
||||||
components.ambientOcclusionValue = 1F
|
return (MAX_TICK_RATE - (level / 2)).coerceAtLeast(MIN_TICK_RATE)
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
components.scheduledTick = object : IBlockScheduledTickComponent {
|
private fun isEntityTolerant(entity: LivingEntity): Boolean {
|
||||||
override fun onAdded(state: BlockState, world: World, pos: BlockPos, rand: Random): TickSchedule {
|
return CustomCreatureType.isDemon(entity) || CustomCreatureType.isShadow(entity) || entity is IImmuneToCorruptedEnergy
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isEntityTolerant(entity: LivingEntity): Boolean {
|
override val localization
|
||||||
return CustomCreatureType.isDemon(entity) || CustomCreatureType.isShadow(entity) || entity is IImmuneToCorruptedEnergy
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Utility methods
|
// Utility methods
|
||||||
@@ -167,19 +97,19 @@ object BlockCorruptedEnergy : HeeBlockBuilder() {
|
|||||||
SUCCESS, PASSTHROUGH, FAIL
|
SUCCESS, PASSTHROUGH, FAIL
|
||||||
}
|
}
|
||||||
|
|
||||||
fun spawn(world: World, pos: BlockPos, level: Int): SpawnResult {
|
fun spawnCorruptedEnergy(world: World, pos: BlockPos, level: Int): SpawnResult {
|
||||||
if (level < MIN_LEVEL) {
|
if (level < MIN_LEVEL) {
|
||||||
return FAIL
|
return FAIL
|
||||||
}
|
}
|
||||||
else if (level > MAX_LEVEL) {
|
else if (level > MAX_LEVEL) {
|
||||||
return spawn(world, pos, MAX_LEVEL)
|
return spawnCorruptedEnergy(world, pos, MAX_LEVEL)
|
||||||
}
|
}
|
||||||
|
|
||||||
val currentState = pos.getState(world)
|
val currentState = pos.getState(world)
|
||||||
val currentBlock = currentState.block
|
val currentBlock = currentState.block
|
||||||
var updateFlags = FLAG_SYNC_CLIENT
|
var updateFlags = FLAG_SYNC_CLIENT
|
||||||
|
|
||||||
if (currentBlock === ModBlocks.CORRUPTED_ENERGY) {
|
if (currentBlock === this) {
|
||||||
if (level - currentState[LEVEL] < 3 || world.rand.nextBoolean()) {
|
if (level - currentState[LEVEL] < 3 || world.rand.nextBoolean()) {
|
||||||
return FAIL
|
return FAIL
|
||||||
}
|
}
|
||||||
@@ -200,7 +130,88 @@ object BlockCorruptedEnergy : HeeBlockBuilder() {
|
|||||||
PASSTHROUGH
|
PASSTHROUGH
|
||||||
}
|
}
|
||||||
|
|
||||||
pos.setState(world, ModBlocks.CORRUPTED_ENERGY.with(LEVEL, level), updateFlags)
|
pos.setState(world, this.with(LEVEL, level), updateFlags)
|
||||||
return SUCCESS
|
return SUCCESS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tick handling
|
||||||
|
|
||||||
|
override fun onBlockAdded(state: BlockState, world: World, pos: BlockPos, oldState: BlockState, isMoving: Boolean) {
|
||||||
|
world.pendingBlockTicks.scheduleTick(pos, this, tickRateForLevel(state[LEVEL]))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun randomTick(state: BlockState, world: ServerWorld, pos: BlockPos, rand: Random) {
|
||||||
|
if (!world.pendingBlockTicks.isTickScheduled(pos, this)) {
|
||||||
|
pos.removeBlock(world)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun tick(state: BlockState, world: ServerWorld, pos: BlockPos, rand: Random) {
|
||||||
|
val level = state[LEVEL]
|
||||||
|
val remainingFacings = Facing6.toMutableList()
|
||||||
|
|
||||||
|
repeat(rand.nextInt(3, 5).coerceAtMost(level)) {
|
||||||
|
val facing = rand.removeItem(remainingFacings)
|
||||||
|
val adjacentPos = pos.offset(facing)
|
||||||
|
|
||||||
|
val spreadDecrease = if (rand.nextInt(3) == 0) 0 else 1
|
||||||
|
|
||||||
|
if (spawnCorruptedEnergy(world, adjacentPos, level - spreadDecrease) == PASSTHROUGH) {
|
||||||
|
spawnCorruptedEnergy(world, adjacentPos.offset(facing), level - spreadDecrease - 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rand.nextInt(4) != 0) {
|
||||||
|
val decreaseToLevel = level - rand.nextInt(1, 2)
|
||||||
|
|
||||||
|
if (decreaseToLevel < MIN_LEVEL) {
|
||||||
|
pos.removeBlock(world)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
pos.setState(world, state.with(LEVEL, decreaseToLevel), FLAG_NONE) // does not call onBlockAdded for the same Block instance
|
||||||
|
}
|
||||||
|
|
||||||
|
world.pendingBlockTicks.scheduleTick(pos, this, tickRateForLevel(level))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interactions
|
||||||
|
|
||||||
|
override fun isAir(state: BlockState, world: IBlockReader, pos: BlockPos): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun propagatesSkylightDown(state: BlockState, world: IBlockReader, pos: BlockPos): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onEntityCollision(state: BlockState, world: World, pos: BlockPos, entity: Entity) {
|
||||||
|
if (!world.isRemote && entity is LivingEntity && !isEntityTolerant(entity)) {
|
||||||
|
CombinedDamage(
|
||||||
|
DAMAGE_PART_NORMAL to 0.75F,
|
||||||
|
DAMAGE_PART_MAGIC to (0.75F + state[LEVEL] / 10F)
|
||||||
|
).dealTo(entity, TITLE_MAGIC)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Client side
|
||||||
|
|
||||||
|
@Sided(Side.CLIENT)
|
||||||
|
override fun animateTick(state: BlockState, world: World, pos: BlockPos, rand: Random) {
|
||||||
|
val amount = rand.nextInt(0, 2)
|
||||||
|
|
||||||
|
if (amount > 0) {
|
||||||
|
PARTICLE_CORRUPTION.spawn(Point(pos, amount), rand) // POLISH figure out how to show particles outside animateTick range
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Sided(Side.CLIENT)
|
||||||
|
override fun getAmbientOcclusionLightValue(state: BlockState, world: IBlockReader, pos: BlockPos): Float {
|
||||||
|
return 1F
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getRenderType(state: BlockState) = INVISIBLE
|
||||||
|
|
||||||
|
// Debugging
|
||||||
|
// override fun getRenderLayer() = CUTOUT
|
||||||
}
|
}
|
||||||
|
@@ -1,53 +1,56 @@
|
|||||||
package chylex.hee.game.block
|
package chylex.hee.game.block
|
||||||
|
|
||||||
import chylex.hee.game.block.builder.HeeBlockBuilder
|
|
||||||
import chylex.hee.game.block.components.IBlockAddedComponent
|
|
||||||
import chylex.hee.game.block.components.IBlockEntityComponent
|
|
||||||
import chylex.hee.game.block.components.IPlayerUseBlockComponent
|
|
||||||
import chylex.hee.game.block.components.ISetBlockStateFromNeighbor
|
|
||||||
import chylex.hee.game.block.entity.TileEntityEndPortalAcceptor
|
import chylex.hee.game.block.entity.TileEntityEndPortalAcceptor
|
||||||
|
import chylex.hee.game.block.properties.BlockBuilder
|
||||||
import chylex.hee.game.block.properties.BlockModel
|
import chylex.hee.game.block.properties.BlockModel
|
||||||
import chylex.hee.game.world.util.getTile
|
import chylex.hee.game.world.util.getTile
|
||||||
import chylex.hee.init.ModBlocks
|
import chylex.hee.init.ModBlocks
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.entity.player.PlayerEntity
|
import net.minecraft.entity.player.PlayerEntity
|
||||||
|
import net.minecraft.tileentity.TileEntity
|
||||||
import net.minecraft.util.ActionResultType
|
import net.minecraft.util.ActionResultType
|
||||||
import net.minecraft.util.ActionResultType.PASS
|
import net.minecraft.util.ActionResultType.PASS
|
||||||
import net.minecraft.util.ActionResultType.SUCCESS
|
import net.minecraft.util.ActionResultType.SUCCESS
|
||||||
|
import net.minecraft.util.Direction
|
||||||
import net.minecraft.util.Direction.UP
|
import net.minecraft.util.Direction.UP
|
||||||
import net.minecraft.util.Hand
|
import net.minecraft.util.Hand
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
|
import net.minecraft.util.math.BlockRayTraceResult
|
||||||
|
import net.minecraft.world.IBlockReader
|
||||||
|
import net.minecraft.world.IWorld
|
||||||
import net.minecraft.world.World
|
import net.minecraft.world.World
|
||||||
|
|
||||||
object BlockEndPortalAcceptor : HeeBlockBuilder() {
|
class BlockEndPortalAcceptor(builder: BlockBuilder) : BlockPortalFrame(builder) {
|
||||||
init {
|
override val model
|
||||||
includeFrom(BlockPortalFrameIndestructible)
|
get() = BlockModel.PortalFrame(ModBlocks.END_PORTAL_FRAME, "acceptor")
|
||||||
|
|
||||||
model = BlockModel.PortalFrame(ModBlocks.END_PORTAL_FRAME, "acceptor")
|
override fun hasTileEntity(state: BlockState): Boolean {
|
||||||
|
return true
|
||||||
components.entity = IBlockEntityComponent(::TileEntityEndPortalAcceptor)
|
}
|
||||||
|
|
||||||
components.onAdded = IBlockAddedComponent { _, world, pos ->
|
override fun createTileEntity(state: BlockState, world: IBlockReader): TileEntity {
|
||||||
BlockAbstractPortal.spawnInnerBlocks(world, pos, ModBlocks.END_PORTAL_FRAME, ModBlocks.END_PORTAL_INNER, minSize = 1)
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
components.setStateFromNeighbor = ISetBlockStateFromNeighbor { state, world, pos, neighborFacing, _ ->
|
return PASS
|
||||||
if (!world.isRemote && neighborFacing == UP) {
|
}
|
||||||
pos.getTile<TileEntityEndPortalAcceptor>(world)?.refreshClusterState()
|
|
||||||
} // TODO neighbor changed?
|
override fun updatePostPlacement(state: BlockState, facing: Direction, neighborState: BlockState, world: IWorld, pos: BlockPos, neighborPos: BlockPos): BlockState {
|
||||||
|
if (!world.isRemote && facing == UP) {
|
||||||
state
|
pos.getTile<TileEntityEndPortalAcceptor>(world)?.refreshClusterState()
|
||||||
}
|
}
|
||||||
|
|
||||||
components.playerUse = object : IPlayerUseBlockComponent {
|
@Suppress("DEPRECATION")
|
||||||
override fun use(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, hand: Hand): ActionResultType {
|
return super.updatePostPlacement(state, facing, neighborState, world, pos, neighborPos)
|
||||||
if (player.isCreative && player.isSneaking) {
|
|
||||||
pos.getTile<TileEntityEndPortalAcceptor>(world)?.toggleChargeFromCreativeMode()
|
|
||||||
return SUCCESS
|
|
||||||
}
|
|
||||||
|
|
||||||
return PASS
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
package chylex.hee.game.block
|
package chylex.hee.game.block
|
||||||
|
|
||||||
import chylex.hee.HEE
|
import chylex.hee.HEE
|
||||||
import chylex.hee.game.block.BlockAbstractPortal.IInnerPortalBlock
|
|
||||||
import chylex.hee.game.block.builder.HeeBlockBuilder
|
|
||||||
import chylex.hee.game.block.entity.TileEntityEndPortalAcceptor
|
import chylex.hee.game.block.entity.TileEntityEndPortalAcceptor
|
||||||
import chylex.hee.game.block.entity.TileEntityPortalInner
|
import chylex.hee.game.block.entity.TileEntityPortalInner
|
||||||
|
import chylex.hee.game.block.properties.BlockBuilder
|
||||||
|
import chylex.hee.game.entity.util.EntityPortalContact
|
||||||
import chylex.hee.game.mechanics.causatum.CausatumStage
|
import chylex.hee.game.mechanics.causatum.CausatumStage
|
||||||
import chylex.hee.game.mechanics.causatum.EnderCausatum
|
import chylex.hee.game.mechanics.causatum.EnderCausatum
|
||||||
import chylex.hee.game.world.isEndDimension
|
import chylex.hee.game.world.isEndDimension
|
||||||
@@ -12,39 +12,41 @@ import chylex.hee.game.world.server.DimensionTeleporter
|
|||||||
import chylex.hee.game.world.util.closestTickingTile
|
import chylex.hee.game.world.util.closestTickingTile
|
||||||
import chylex.hee.init.ModBlocks
|
import chylex.hee.init.ModBlocks
|
||||||
import chylex.hee.util.math.Pos
|
import chylex.hee.util.math.Pos
|
||||||
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.entity.Entity
|
import net.minecraft.entity.Entity
|
||||||
import net.minecraft.entity.player.PlayerEntity
|
import net.minecraft.entity.player.PlayerEntity
|
||||||
import net.minecraft.tileentity.TileEntity
|
import net.minecraft.tileentity.TileEntity
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
|
import net.minecraft.world.IBlockReader
|
||||||
import net.minecraft.world.World
|
import net.minecraft.world.World
|
||||||
|
|
||||||
object BlockEndPortalInner : HeeBlockBuilder() {
|
class BlockEndPortalInner(builder: BlockBuilder) : BlockAbstractPortal(builder) {
|
||||||
init {
|
override fun createTileEntity(state: BlockState, world: IBlockReader): TileEntity {
|
||||||
includeFrom(BlockAbstractPortal(object : IInnerPortalBlock {
|
return TileEntityPortalInner.End()
|
||||||
override fun createTileEntity(): TileEntity {
|
}
|
||||||
return TileEntityPortalInner.End()
|
|
||||||
}
|
override fun onEntityInside(world: World, pos: BlockPos, entity: Entity) {
|
||||||
|
if (!EntityPortalContact.shouldTeleport(entity)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (world.isEndDimension) {
|
||||||
|
DimensionTeleporter.changeDimension(entity, World.OVERWORLD, DimensionTeleporter.LastEndPortal)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
val acceptor = pos.closestTickingTile<TileEntityEndPortalAcceptor>(world, MAX_DISTANCE_FROM_FRAME)
|
||||||
|
|
||||||
override fun teleportEntity(world: World, pos: BlockPos, entity: Entity) {
|
if (acceptor != null && acceptor.isCharged) {
|
||||||
if (world.isEndDimension) {
|
findInnerArea(world, acceptor.pos, ModBlocks.END_PORTAL_FRAME)?.let { (min, max) ->
|
||||||
DimensionTeleporter.changeDimension(entity, World.OVERWORLD, DimensionTeleporter.LastEndPortal)
|
DimensionTeleporter.LastEndPortal.updateForEntity(entity, Pos((min.x + max.x) / 2, pos.y, (min.z + max.z) / 2))
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
val acceptor = pos.closestTickingTile<TileEntityEndPortalAcceptor>(world, BlockAbstractPortal.MAX_DISTANCE_FROM_FRAME)
|
if (entity is PlayerEntity) {
|
||||||
|
EnderCausatum.triggerStage(entity, CausatumStage.S2_ENTERED_END)
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DimensionTeleporter.changeDimension(entity, HEE.dim, DimensionTeleporter.EndSpawnPortal)
|
||||||
}
|
}
|
||||||
}))
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,23 +1,22 @@
|
|||||||
package chylex.hee.game.block
|
package chylex.hee.game.block
|
||||||
|
|
||||||
import chylex.hee.game.block.builder.HeeBlockBuilder
|
import chylex.hee.game.block.properties.BlockBuilder
|
||||||
import chylex.hee.game.block.components.IBlockExperienceComponent
|
|
||||||
import chylex.hee.game.block.properties.BlockDrop
|
import chylex.hee.game.block.properties.BlockDrop
|
||||||
import chylex.hee.game.block.properties.BlockHardness
|
|
||||||
import chylex.hee.game.block.properties.BlockHarvestTool
|
|
||||||
import chylex.hee.game.item.util.Tool.Level.STONE
|
|
||||||
import chylex.hee.util.random.nextInt
|
import chylex.hee.util.random.nextInt
|
||||||
import net.minecraftforge.common.ToolType.PICKAXE
|
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
|
||||||
|
|
||||||
object BlockEndPowderOre : HeeBlockBuilder() {
|
class BlockEndPowderOre(builder: BlockBuilder) : HeeBlock(builder) {
|
||||||
init {
|
override val drop
|
||||||
includeFrom(BlockEndOre)
|
get() = BlockDrop.Manual
|
||||||
|
|
||||||
drop = BlockDrop.Manual
|
override val tags
|
||||||
|
get() = listOf(Tags.Blocks.ORES)
|
||||||
tool = BlockHarvestTool.required(STONE, PICKAXE)
|
|
||||||
hardness = BlockHardness(hardness = 2F, resistance = 5.4F)
|
override fun getExpDrop(state: BlockState, world: IWorldReader, pos: BlockPos, fortune: Int, silktouch: Int): Int {
|
||||||
|
return ((world as? World)?.rand ?: RANDOM).nextInt(1, 2)
|
||||||
components.experience = IBlockExperienceComponent { rand -> rand.nextInt(1, 2) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,48 +2,22 @@ package chylex.hee.game.block
|
|||||||
|
|
||||||
import chylex.hee.client.text.LocalizationStrategy
|
import chylex.hee.client.text.LocalizationStrategy
|
||||||
import chylex.hee.game.Resource.location
|
import chylex.hee.game.Resource.location
|
||||||
import chylex.hee.game.block.builder.HeeBlockBuilder
|
import chylex.hee.game.block.properties.BlockBuilder
|
||||||
import chylex.hee.game.block.properties.BlockHardness
|
|
||||||
import chylex.hee.game.block.properties.BlockHarvestTool
|
|
||||||
import chylex.hee.game.block.properties.BlockModel
|
import chylex.hee.game.block.properties.BlockModel
|
||||||
import chylex.hee.game.block.properties.IBlockStateModelSupplier
|
|
||||||
import chylex.hee.game.item.util.Tool.Level.WOOD
|
|
||||||
import net.minecraft.block.Blocks
|
import net.minecraft.block.Blocks
|
||||||
import net.minecraft.block.material.MaterialColor
|
import net.minecraft.block.material.MaterialColor
|
||||||
import net.minecraftforge.common.Tags
|
import net.minecraftforge.common.Tags
|
||||||
import net.minecraftforge.common.ToolType.PICKAXE
|
|
||||||
|
|
||||||
object BlockEndStoneCustom : HeeBlockBuilder() {
|
class BlockEndStoneCustom(builder: BlockBuilder, mapColor: MaterialColor) : HeeBlock(builder.clone { color = mapColor }) {
|
||||||
init {
|
override val localization
|
||||||
includeFrom(BlockEndStoneBase)
|
get() = LocalizationStrategy.MoveToBeginning(wordCount = 1)
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
val INFESTED = HeeBlockBuilder {
|
override val model
|
||||||
includeFrom(BlockEndStoneCustom)
|
get() = BlockModel.WithTextures(
|
||||||
color = MaterialColor.RED
|
BlockModel.CubeBottomTop(bottom = Blocks.END_STONE.location),
|
||||||
}
|
mapOf("particle" to this.location("_top"))
|
||||||
|
)
|
||||||
|
|
||||||
val BURNED = HeeBlockBuilder {
|
override val tags
|
||||||
includeFrom(BlockEndStoneCustom)
|
get() = listOf(Tags.Blocks.END_STONES)
|
||||||
color = MaterialColor.ADOBE // RENAME ORANGE
|
|
||||||
}
|
|
||||||
|
|
||||||
val ENCHANTED = HeeBlockBuilder {
|
|
||||||
includeFrom(BlockEndStoneCustom)
|
|
||||||
color = MaterialColor.PURPLE
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -1,48 +1,26 @@
|
|||||||
package chylex.hee.game.block
|
package chylex.hee.game.block
|
||||||
|
|
||||||
import chylex.hee.game.block.builder.HeeBlockBuilder
|
import chylex.hee.game.block.properties.BlockBuilder
|
||||||
import chylex.hee.game.block.components.IBlockHarvestabilityComponent
|
import net.minecraft.block.BlockState
|
||||||
import chylex.hee.game.block.properties.BlockHardness
|
import net.minecraft.entity.player.PlayerEntity
|
||||||
import chylex.hee.game.block.properties.BlockHarvestTool
|
|
||||||
import chylex.hee.game.block.properties.Materials
|
|
||||||
import chylex.hee.game.item.util.Tool.Level.IRON
|
|
||||||
import chylex.hee.util.forge.EventResult
|
|
||||||
import net.minecraft.block.SoundType
|
|
||||||
import net.minecraft.block.material.MaterialColor
|
|
||||||
import net.minecraft.item.Items
|
import net.minecraft.item.Items
|
||||||
import net.minecraft.util.Hand.MAIN_HAND
|
import net.minecraft.util.Hand.MAIN_HAND
|
||||||
|
import net.minecraft.util.math.BlockPos
|
||||||
|
import net.minecraft.world.IBlockReader
|
||||||
import net.minecraftforge.common.Tags
|
import net.minecraftforge.common.Tags
|
||||||
import net.minecraftforge.common.ToolType.PICKAXE
|
|
||||||
|
|
||||||
abstract class BlockEndium : HeeBlockBuilder() {
|
sealed class BlockEndium(builder: BlockBuilder) : HeeBlock(builder) {
|
||||||
init {
|
override fun canHarvestBlock(state: BlockState, world: IBlockReader, pos: BlockPos, player: PlayerEntity): Boolean {
|
||||||
material = Materials.SOLID
|
return super.canHarvestBlock(state, world, pos, player) || player.getHeldItem(MAIN_HAND).item === Items.GOLDEN_PICKAXE
|
||||||
tool = BlockHarvestTool.required(IRON, PICKAXE)
|
|
||||||
|
|
||||||
components.harvestability = IBlockHarvestabilityComponent {
|
|
||||||
if (it.getHeldItem(MAIN_HAND).item === Items.GOLDEN_PICKAXE)
|
|
||||||
EventResult.ALLOW
|
|
||||||
else
|
|
||||||
EventResult.DEFAULT
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object Ore : BlockEndium() {
|
class Ore(builder: BlockBuilder) : BlockEndium(builder) {
|
||||||
init {
|
override val tags
|
||||||
includeFrom(BlockEndOre)
|
get() = listOf(Tags.Blocks.ORES)
|
||||||
|
|
||||||
hardness = BlockHardness(hardness = 5F, resistance = 9.9F)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object Block : BlockEndium() {
|
class Block(builder: BlockBuilder) : BlockEndium(builder) {
|
||||||
init {
|
override val tags
|
||||||
color = MaterialColor.LAPIS
|
get() = listOf(Tags.Blocks.STORAGE_BLOCKS)
|
||||||
sound = SoundType.METAL
|
|
||||||
|
|
||||||
tags.add(Tags.Blocks.STORAGE_BLOCKS)
|
|
||||||
|
|
||||||
hardness = BlockHardness(hardness = 6.2F, resistance = 12F)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -9,6 +9,7 @@ import chylex.hee.game.mechanics.instability.Instability
|
|||||||
import chylex.hee.game.world.util.allInCenteredSphereMutable
|
import chylex.hee.game.world.util.allInCenteredSphereMutable
|
||||||
import chylex.hee.game.world.util.getTile
|
import chylex.hee.game.world.util.getTile
|
||||||
import chylex.hee.game.world.util.removeBlock
|
import chylex.hee.game.world.util.removeBlock
|
||||||
|
import chylex.hee.init.ModBlocks
|
||||||
import chylex.hee.init.ModItems
|
import chylex.hee.init.ModItems
|
||||||
import chylex.hee.util.forge.Side
|
import chylex.hee.util.forge.Side
|
||||||
import chylex.hee.util.forge.Sided
|
import chylex.hee.util.forge.Sided
|
||||||
@@ -42,7 +43,7 @@ class BlockEnergyCluster(builder: BlockBuilder) : BlockSimpleShaped(builder, Axi
|
|||||||
val units = amount.units.value.toFloat()
|
val units = amount.units.value.toFloat()
|
||||||
val corruptedEnergyLevel = (2F + (units.pow(0.74F) / 9F)).ceilToInt()
|
val corruptedEnergyLevel = (2F + (units.pow(0.74F) / 9F)).ceilToInt()
|
||||||
|
|
||||||
BlockCorruptedEnergy.spawn(world, pos, corruptedEnergyLevel)
|
ModBlocks.CORRUPTED_ENERGY.spawnCorruptedEnergy(world, pos, corruptedEnergyLevel)
|
||||||
|
|
||||||
if (causeInstability) {
|
if (causeInstability) {
|
||||||
Instability.get(world).triggerAction((10 + 2 * corruptedEnergyLevel).toUShort(), pos)
|
Instability.get(world).triggerAction((10 + 2 * corruptedEnergyLevel).toUShort(), pos)
|
||||||
@@ -56,7 +57,7 @@ class BlockEnergyCluster(builder: BlockBuilder) : BlockSimpleShaped(builder, Axi
|
|||||||
val corruptedEnergyLevel = (2F + (units.pow(0.74F) / 9F)).ceilToInt()
|
val corruptedEnergyLevel = (2F + (units.pow(0.74F) / 9F)).ceilToInt()
|
||||||
|
|
||||||
for (testPos in pos.allInCenteredSphereMutable(corruptedEnergyRadius)) {
|
for (testPos in pos.allInCenteredSphereMutable(corruptedEnergyRadius)) {
|
||||||
BlockCorruptedEnergy.spawn(world, testPos, corruptedEnergyLevel)
|
ModBlocks.CORRUPTED_ENERGY.spawnCorruptedEnergy(world, testPos, corruptedEnergyLevel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,74 +1,35 @@
|
|||||||
package chylex.hee.game.block
|
package chylex.hee.game.block
|
||||||
|
|
||||||
import chylex.hee.HEE
|
import chylex.hee.HEE
|
||||||
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.ICreatureSpawningOnBlockComponent
|
|
||||||
import chylex.hee.game.block.properties.BlockHardness
|
|
||||||
import chylex.hee.game.block.properties.BlockHarvestTool
|
|
||||||
import chylex.hee.game.block.properties.Materials
|
|
||||||
import chylex.hee.game.entity.technical.EntityTechnicalTrigger
|
import chylex.hee.game.entity.technical.EntityTechnicalTrigger
|
||||||
import chylex.hee.game.entity.technical.EntityTechnicalTrigger.Types.ENERGY_SHRINE_GLOBAL
|
import chylex.hee.game.entity.technical.EntityTechnicalTrigger.Types.ENERGY_SHRINE_GLOBAL
|
||||||
import chylex.hee.game.entity.util.posVec
|
import chylex.hee.game.entity.util.posVec
|
||||||
import chylex.hee.game.entity.util.selectEntities
|
import chylex.hee.game.entity.util.selectEntities
|
||||||
import chylex.hee.game.item.util.Tool.Level.WOOD
|
|
||||||
import chylex.hee.game.item.util.Tool.Type.PICKAXE
|
|
||||||
import chylex.hee.game.world.generation.feature.energyshrine.EnergyShrinePieces
|
import chylex.hee.game.world.generation.feature.energyshrine.EnergyShrinePieces
|
||||||
import chylex.hee.init.ModTags
|
|
||||||
import chylex.hee.util.forge.EventResult
|
|
||||||
import chylex.hee.util.math.center
|
import chylex.hee.util.math.center
|
||||||
import net.minecraft.block.SoundType
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.block.material.MaterialColor
|
|
||||||
import net.minecraft.entity.EntitySpawnPlacementRegistry.PlacementType
|
import net.minecraft.entity.EntitySpawnPlacementRegistry.PlacementType
|
||||||
import net.minecraft.entity.EntityType
|
import net.minecraft.entity.EntityType
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.world.IBlockReader
|
import net.minecraft.world.IBlockReader
|
||||||
import net.minecraft.world.IEntityReader
|
import net.minecraft.world.IEntityReader
|
||||||
|
|
||||||
object BlockGloomrock : HeeBlockBuilder() {
|
open class BlockGloomrock(builder: BlockBuilder) : HeeBlock(builder) {
|
||||||
init {
|
override fun canCreatureSpawn(state: BlockState, world: IBlockReader, pos: BlockPos, type: PlacementType?, entityType: EntityType<*>?): Boolean {
|
||||||
material = Materials.SOLID
|
if (world !is IEntityReader) {
|
||||||
color = MaterialColor.BLACK
|
HEE.log.warn("[BlockGloomrock] attempted to check spawn on a world != IEntityReader (${world.javaClass})")
|
||||||
sound = SoundType.STONE
|
return false
|
||||||
|
|
||||||
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 BRICKS = HeeBlockBuilder {
|
val size = EnergyShrinePieces.STRUCTURE_SIZE
|
||||||
includeFrom(BlockGloomrock)
|
|
||||||
hardness = BlockHardness(hardness = 2.8F, resistance = 6F)
|
val trigger = world
|
||||||
}
|
.selectEntities
|
||||||
|
.inBox<EntityTechnicalTrigger>(size.toCenteredBoundingBox(center))
|
||||||
val SMOOTH = HeeBlockBuilder {
|
.find { it.triggerType == ENERGY_SHRINE_GLOBAL }
|
||||||
includeFrom(BlockGloomrock)
|
|
||||||
localization = LocalizationStrategy.MoveToBeginning(wordCount = 1)
|
return trigger == null || !size.toCenteredBoundingBox(trigger.posVec).contains(center)
|
||||||
hardness = BlockHardness(hardness = 2F, resistance = 4.8F)
|
|
||||||
}
|
|
||||||
|
|
||||||
val SMOOTH_COLORED = HeeBlockBuilder {
|
|
||||||
includeFrom(SMOOTH)
|
|
||||||
localization = LocalizationStrategy.MoveToBeginning(LocalizationStrategy.DeleteWords("Smooth"), wordCount = 1)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,9 @@
|
|||||||
|
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)
|
||||||
|
}
|
@@ -0,0 +1,9 @@
|
|||||||
|
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,37 +1,31 @@
|
|||||||
package chylex.hee.game.block
|
package chylex.hee.game.block
|
||||||
|
|
||||||
import chylex.hee.game.Resource.location
|
import chylex.hee.game.Resource.location
|
||||||
import chylex.hee.game.block.builder.HeeBlockBuilder
|
|
||||||
import chylex.hee.game.block.components.IBlockAddedComponent
|
|
||||||
import chylex.hee.game.block.components.IBlockEntityComponent
|
|
||||||
import chylex.hee.game.block.components.IBlockPlacementComponent
|
|
||||||
import chylex.hee.game.block.components.IBlockShapeComponent
|
|
||||||
import chylex.hee.game.block.components.IPlayerUseBlockComponent
|
|
||||||
import chylex.hee.game.block.components.ISetBlockStateFromNeighbor
|
|
||||||
import chylex.hee.game.block.entity.TileEntityIgneousPlate
|
import chylex.hee.game.block.entity.TileEntityIgneousPlate
|
||||||
import chylex.hee.game.block.logic.IBlockDynamicHardness
|
import chylex.hee.game.block.logic.IBlockDynamicHardness
|
||||||
|
import chylex.hee.game.block.properties.BlockBuilder
|
||||||
import chylex.hee.game.block.properties.BlockModel
|
import chylex.hee.game.block.properties.BlockModel
|
||||||
import chylex.hee.game.block.properties.BlockStateModel
|
import chylex.hee.game.block.properties.BlockStateModel
|
||||||
import chylex.hee.game.block.properties.BlockStatePreset
|
import chylex.hee.game.block.properties.BlockStatePreset
|
||||||
import chylex.hee.game.block.properties.IBlockStateModelSupplier
|
|
||||||
import chylex.hee.game.block.properties.Materials
|
|
||||||
import chylex.hee.game.block.util.FURNACE_FACING
|
import chylex.hee.game.block.util.FURNACE_FACING
|
||||||
import chylex.hee.game.block.util.Property
|
import chylex.hee.game.block.util.Property
|
||||||
|
import chylex.hee.game.block.util.asVoxelShape
|
||||||
import chylex.hee.game.entity.technical.EntityTechnicalIgneousPlateLogic
|
import chylex.hee.game.entity.technical.EntityTechnicalIgneousPlateLogic
|
||||||
import chylex.hee.game.item.properties.ItemModel
|
import chylex.hee.game.item.properties.ItemModel
|
||||||
import chylex.hee.game.world.util.Facing6
|
import chylex.hee.game.world.util.Facing6
|
||||||
import chylex.hee.game.world.util.getState
|
import chylex.hee.game.world.util.getState
|
||||||
import chylex.hee.game.world.util.getTile
|
import chylex.hee.game.world.util.getTile
|
||||||
|
import net.minecraft.block.Block
|
||||||
import net.minecraft.block.BlockRenderType.ENTITYBLOCK_ANIMATED
|
import net.minecraft.block.BlockRenderType.ENTITYBLOCK_ANIMATED
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.block.Blocks
|
import net.minecraft.block.Blocks
|
||||||
import net.minecraft.block.SoundType
|
|
||||||
import net.minecraft.block.material.MaterialColor
|
|
||||||
import net.minecraft.entity.player.PlayerEntity
|
import net.minecraft.entity.player.PlayerEntity
|
||||||
import net.minecraft.item.BlockItemUseContext
|
import net.minecraft.item.BlockItemUseContext
|
||||||
import net.minecraft.item.ItemStack
|
import net.minecraft.item.ItemStack
|
||||||
import net.minecraft.item.Items
|
import net.minecraft.item.Items
|
||||||
|
import net.minecraft.state.StateContainer.Builder
|
||||||
import net.minecraft.tileentity.FurnaceTileEntity
|
import net.minecraft.tileentity.FurnaceTileEntity
|
||||||
|
import net.minecraft.tileentity.TileEntity
|
||||||
import net.minecraft.util.ActionResultType
|
import net.minecraft.util.ActionResultType
|
||||||
import net.minecraft.util.ActionResultType.PASS
|
import net.minecraft.util.ActionResultType.PASS
|
||||||
import net.minecraft.util.ActionResultType.SUCCESS
|
import net.minecraft.util.ActionResultType.SUCCESS
|
||||||
@@ -43,114 +37,139 @@ import net.minecraft.util.Direction.SOUTH
|
|||||||
import net.minecraft.util.Direction.UP
|
import net.minecraft.util.Direction.UP
|
||||||
import net.minecraft.util.Direction.WEST
|
import net.minecraft.util.Direction.WEST
|
||||||
import net.minecraft.util.Hand
|
import net.minecraft.util.Hand
|
||||||
|
import net.minecraft.util.Mirror
|
||||||
|
import net.minecraft.util.Rotation
|
||||||
|
import net.minecraft.util.math.AxisAlignedBB
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
|
import net.minecraft.util.math.BlockRayTraceResult
|
||||||
|
import net.minecraft.util.math.shapes.ISelectionContext
|
||||||
import net.minecraft.util.math.shapes.VoxelShape
|
import net.minecraft.util.math.shapes.VoxelShape
|
||||||
import net.minecraft.util.math.shapes.VoxelShapes
|
|
||||||
import net.minecraft.world.IBlockReader
|
import net.minecraft.world.IBlockReader
|
||||||
|
import net.minecraft.world.IWorld
|
||||||
import net.minecraft.world.IWorldReader
|
import net.minecraft.world.IWorldReader
|
||||||
import net.minecraft.world.World
|
import net.minecraft.world.World
|
||||||
|
|
||||||
object BlockIgneousPlate : HeeBlockBuilder() {
|
class BlockIgneousPlate(builder: BlockBuilder) : HeeBlock(builder), IBlockDynamicHardness {
|
||||||
val FACING_NOT_DOWN = Property.facing("facing", Facing6.minusElement(DOWN))
|
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
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private const val BB_SIDE_MIN = 0.125
|
override val model
|
||||||
private const val BB_SIDE_MAX = 0.875
|
get() = BlockStateModel(BlockStatePreset.Simple, BlockModel.ParticleOnly(this.location), ItemModel.Simple)
|
||||||
private const val BB_TOP = 0.125
|
|
||||||
|
|
||||||
private val BOUNDING_BOX = mapOf(
|
|
||||||
UP to VoxelShapes.create(BB_SIDE_MIN, 0.0, BB_SIDE_MIN, BB_SIDE_MAX, BB_TOP, BB_SIDE_MAX),
|
|
||||||
NORTH to VoxelShapes.create(BB_SIDE_MIN, BB_SIDE_MIN, 1.0 - BB_TOP, BB_SIDE_MAX, BB_SIDE_MAX, 1.0),
|
|
||||||
SOUTH to VoxelShapes.create(BB_SIDE_MIN, BB_SIDE_MIN, 0.0, BB_SIDE_MAX, BB_SIDE_MAX, BB_TOP),
|
|
||||||
EAST to VoxelShapes.create(0.0, BB_SIDE_MIN, BB_SIDE_MIN, BB_TOP, BB_SIDE_MAX, BB_SIDE_MAX),
|
|
||||||
WEST to VoxelShapes.create(1.0 - BB_TOP, BB_SIDE_MIN, BB_SIDE_MIN, 1.0, BB_SIDE_MAX, BB_SIDE_MAX)
|
|
||||||
)
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
model = IBlockStateModelSupplier {
|
defaultState = stateContainer.baseState.with(FACING_NOT_DOWN, UP)
|
||||||
BlockStateModel(BlockStatePreset.Simple, BlockModel.ParticleOnly(it.location), ItemModel.Simple)
|
}
|
||||||
|
|
||||||
|
override fun fillStateContainer(container: Builder<Block, BlockState>) {
|
||||||
|
container.add(FACING_NOT_DOWN)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hasTileEntity(state: BlockState): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createTileEntity(state: BlockState, world: IBlockReader): TileEntity {
|
||||||
|
return TileEntityIgneousPlate()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Placement rules
|
||||||
|
|
||||||
|
override fun isValidPosition(state: BlockState, world: IWorldReader, pos: BlockPos): Boolean {
|
||||||
|
return FACING_NOT_DOWN.allowedValues.any { canPlacePlateAt(world, pos, it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getStateForPlacement(context: BlockItemUseContext): BlockState {
|
||||||
|
val world = context.world
|
||||||
|
val pos = context.pos
|
||||||
|
val facing = context.face
|
||||||
|
|
||||||
|
return if (canPlacePlateAt(world, pos, facing))
|
||||||
|
defaultState.with(FACING_NOT_DOWN, facing)
|
||||||
|
else
|
||||||
|
FACING_NOT_DOWN.allowedValues.firstOrNull { canPlacePlateAt(world, pos, it) }?.let { defaultState.with(FACING_NOT_DOWN, it) } ?: defaultState
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBlockAdded(state: BlockState, world: World, pos: BlockPos, oldState: BlockState, isMoving: Boolean) {
|
||||||
|
pos.offset(state[FACING_NOT_DOWN].opposite).getTile<FurnaceTileEntity>(world)?.let(EntityTechnicalIgneousPlateLogic.Companion::createForFurnace)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updatePostPlacement(state: BlockState, facing: Direction, neighborState: BlockState, world: IWorld, pos: BlockPos, neighborPos: BlockPos): BlockState {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
return if (!canPlacePlateAt(world, pos, state[FACING_NOT_DOWN]))
|
||||||
|
Blocks.AIR.defaultState
|
||||||
|
else
|
||||||
|
super.updatePostPlacement(state, facing, neighborState, world, pos, neighborPos)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interactions
|
||||||
|
|
||||||
|
override fun getBlockHardness(world: IBlockReader, pos: BlockPos, state: BlockState, originalHardness: Float): Float {
|
||||||
|
val tile = pos.getTile<TileEntityIgneousPlate>(world) ?: return 0F
|
||||||
|
|
||||||
|
return when {
|
||||||
|
tile.isOverheating -> 10F
|
||||||
|
tile.isWorking -> 4F
|
||||||
|
else -> 0F
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBlockActivated(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, hit: BlockRayTraceResult): ActionResultType {
|
||||||
|
val heldItem = player.getHeldItem(hand)
|
||||||
|
|
||||||
material = Materials.IGNEOUS_ROCK_PLATE
|
if (heldItem.item === Items.WATER_BUCKET) {
|
||||||
color = MaterialColor.AIR
|
if (!world.isRemote && tryCoolPlate(world, pos, state) && !player.abilities.isCreativeMode) {
|
||||||
sound = SoundType.STONE
|
player.setHeldItem(hand, ItemStack(Items.BUCKET))
|
||||||
|
|
||||||
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) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getPlacedState(defaultState: BlockState, world: World, pos: BlockPos, context: BlockItemUseContext): BlockState {
|
return SUCCESS
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
components.onAdded = IBlockAddedComponent { state, world, pos ->
|
return PASS
|
||||||
pos.offset(state[FACING_NOT_DOWN].opposite).getTile<FurnaceTileEntity>(world)?.let(EntityTechnicalIgneousPlateLogic.Companion::createForFurnace)
|
|
||||||
}
|
|
||||||
|
|
||||||
components.setStateFromNeighbor = ISetBlockStateFromNeighbor { state, world, pos, _, _ ->
|
|
||||||
if (!canPlacePlateAt(world, pos, state[FACING_NOT_DOWN]))
|
|
||||||
Blocks.AIR.defaultState
|
|
||||||
else
|
|
||||||
state
|
|
||||||
}
|
|
||||||
|
|
||||||
components.playerUse = object : IPlayerUseBlockComponent {
|
|
||||||
override fun use(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, hand: Hand): ActionResultType {
|
|
||||||
val heldItem = player.getHeldItem(hand)
|
|
||||||
if (heldItem.item !== Items.WATER_BUCKET) {
|
|
||||||
return PASS
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!world.isRemote && tryCoolPlate(world, pos, state) && !player.abilities.isCreativeMode) {
|
|
||||||
player.setHeldItem(hand, ItemStack(Items.BUCKET))
|
|
||||||
}
|
|
||||||
|
|
||||||
return SUCCESS
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
interfaces[IBlockDynamicHardness::class.java] = object : IBlockDynamicHardness {
|
|
||||||
override fun getBlockHardness(world: IBlockReader, pos: BlockPos, state: BlockState, originalHardness: Float): Float {
|
|
||||||
val tile = pos.getTile<TileEntityIgneousPlate>(world) ?: return 0F
|
|
||||||
|
|
||||||
return when {
|
|
||||||
tile.isOverheating -> 10F
|
|
||||||
tile.isWorking -> 4F
|
|
||||||
else -> 0F
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun tryCoolPlate(world: World, pos: BlockPos, state: BlockState): Boolean {
|
fun tryCoolPlate(world: World, pos: BlockPos, state: BlockState): Boolean {
|
||||||
return pos.offset(state[FACING_NOT_DOWN].opposite).getTile<FurnaceTileEntity>(world)?.let(EntityTechnicalIgneousPlateLogic.Companion::triggerCooling) == true
|
return pos.offset(state[FACING_NOT_DOWN].opposite).getTile<FurnaceTileEntity>(world)?.let(EntityTechnicalIgneousPlateLogic.Companion::triggerCooling) == true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun canPlacePlateAt(world: IWorldReader, pos: BlockPos, facing: Direction): Boolean {
|
// State handling
|
||||||
val furnacePos = pos.offset(facing.opposite)
|
|
||||||
val state = furnacePos.getState(world)
|
override fun rotate(state: BlockState, rot: Rotation): BlockState {
|
||||||
|
return state.with(FACING_NOT_DOWN, rot.rotate(state[FACING_NOT_DOWN]))
|
||||||
return (
|
|
||||||
state.properties.contains(FURNACE_FACING) &&
|
|
||||||
state[FURNACE_FACING] != facing &&
|
|
||||||
furnacePos.getTile<FurnaceTileEntity>(world) != null
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun mirror(state: BlockState, mirror: Mirror): BlockState {
|
||||||
|
return state.with(FACING_NOT_DOWN, mirror.mirror(state[FACING_NOT_DOWN]))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rendering
|
||||||
|
|
||||||
|
override fun getShape(state: BlockState, world: IBlockReader, pos: BlockPos, context: ISelectionContext): VoxelShape {
|
||||||
|
return BOUNDING_BOX[state[FACING_NOT_DOWN]] ?: BOUNDING_BOX.getValue(UP)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getRenderType(state: BlockState) = ENTITYBLOCK_ANIMATED
|
||||||
}
|
}
|
||||||
|
@@ -1,24 +1,14 @@
|
|||||||
package chylex.hee.game.block
|
package chylex.hee.game.block
|
||||||
|
|
||||||
import chylex.hee.client.text.LocalizationStrategy
|
import chylex.hee.client.text.LocalizationStrategy
|
||||||
import chylex.hee.game.block.builder.HeeBlockBuilder
|
|
||||||
import chylex.hee.game.block.components.IBlockDropsComponent
|
|
||||||
import chylex.hee.game.block.components.IBlockEntityComponent
|
|
||||||
import chylex.hee.game.block.components.IBlockExplodedComponent
|
|
||||||
import chylex.hee.game.block.components.IBlockPlacementComponent
|
|
||||||
import chylex.hee.game.block.components.IBlockShapeComponent
|
|
||||||
import chylex.hee.game.block.components.IPlayerUseBlockComponent
|
|
||||||
import chylex.hee.game.block.components.ISetBlockStateFromNeighbor
|
|
||||||
import chylex.hee.game.block.entity.TileEntityJarODust
|
import chylex.hee.game.block.entity.TileEntityJarODust
|
||||||
|
import chylex.hee.game.block.properties.BlockBuilder
|
||||||
import chylex.hee.game.block.properties.BlockDrop
|
import chylex.hee.game.block.properties.BlockDrop
|
||||||
import chylex.hee.game.block.properties.BlockHardness
|
|
||||||
import chylex.hee.game.block.properties.BlockModel
|
import chylex.hee.game.block.properties.BlockModel
|
||||||
import chylex.hee.game.block.properties.BlockRenderLayer.TRANSLUCENT
|
import chylex.hee.game.block.properties.BlockRenderLayer.TRANSLUCENT
|
||||||
import chylex.hee.game.block.properties.BlockStateModel
|
import chylex.hee.game.block.properties.BlockStateModel
|
||||||
import chylex.hee.game.block.properties.BlockStatePreset
|
import chylex.hee.game.block.properties.BlockStatePreset
|
||||||
import chylex.hee.game.block.properties.Materials
|
|
||||||
import chylex.hee.game.fx.util.playServer
|
import chylex.hee.game.fx.util.playServer
|
||||||
import chylex.hee.game.item.components.ITooltipComponent
|
|
||||||
import chylex.hee.game.item.util.size
|
import chylex.hee.game.item.util.size
|
||||||
import chylex.hee.game.mechanics.dust.DustLayers
|
import chylex.hee.game.mechanics.dust.DustLayers
|
||||||
import chylex.hee.game.mechanics.dust.DustLayers.Side.BOTTOM
|
import chylex.hee.game.mechanics.dust.DustLayers.Side.BOTTOM
|
||||||
@@ -26,165 +16,164 @@ import chylex.hee.game.mechanics.dust.DustLayers.Side.TOP
|
|||||||
import chylex.hee.game.mechanics.dust.DustType
|
import chylex.hee.game.mechanics.dust.DustType
|
||||||
import chylex.hee.game.world.util.getTile
|
import chylex.hee.game.world.util.getTile
|
||||||
import chylex.hee.game.world.util.isTopSolid
|
import chylex.hee.game.world.util.isTopSolid
|
||||||
import chylex.hee.init.ModBlocks
|
|
||||||
import chylex.hee.init.ModSounds
|
import chylex.hee.init.ModSounds
|
||||||
import chylex.hee.system.heeTag
|
import chylex.hee.system.heeTag
|
||||||
import chylex.hee.system.heeTagOrNull
|
import chylex.hee.system.heeTagOrNull
|
||||||
|
import chylex.hee.util.forge.Side
|
||||||
|
import chylex.hee.util.forge.Sided
|
||||||
import chylex.hee.util.math.center
|
import chylex.hee.util.math.center
|
||||||
import chylex.hee.util.nbt.getListOfCompounds
|
import chylex.hee.util.nbt.getListOfCompounds
|
||||||
import chylex.hee.util.nbt.putList
|
import chylex.hee.util.nbt.putList
|
||||||
import net.minecraft.block.Block
|
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.block.Blocks
|
import net.minecraft.block.Blocks
|
||||||
import net.minecraft.block.SoundType
|
import net.minecraft.client.util.ITooltipFlag
|
||||||
import net.minecraft.block.material.MaterialColor
|
|
||||||
import net.minecraft.entity.LivingEntity
|
import net.minecraft.entity.LivingEntity
|
||||||
import net.minecraft.entity.player.PlayerEntity
|
import net.minecraft.entity.player.PlayerEntity
|
||||||
import net.minecraft.item.ItemStack
|
import net.minecraft.item.ItemStack
|
||||||
import net.minecraft.loot.LootContext.Builder
|
import net.minecraft.loot.LootContext
|
||||||
import net.minecraft.loot.LootParameters
|
import net.minecraft.loot.LootParameters
|
||||||
|
import net.minecraft.tileentity.TileEntity
|
||||||
|
import net.minecraft.util.ActionResultType
|
||||||
import net.minecraft.util.ActionResultType.PASS
|
import net.minecraft.util.ActionResultType.PASS
|
||||||
import net.minecraft.util.ActionResultType.SUCCESS
|
import net.minecraft.util.ActionResultType.SUCCESS
|
||||||
|
import net.minecraft.util.Direction
|
||||||
import net.minecraft.util.Direction.DOWN
|
import net.minecraft.util.Direction.DOWN
|
||||||
import net.minecraft.util.Hand
|
import net.minecraft.util.Hand
|
||||||
import net.minecraft.util.SoundCategory
|
import net.minecraft.util.SoundCategory
|
||||||
|
import net.minecraft.util.math.AxisAlignedBB
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.util.math.shapes.VoxelShapes
|
import net.minecraft.util.math.BlockRayTraceResult
|
||||||
|
import net.minecraft.util.math.RayTraceResult
|
||||||
import net.minecraft.util.text.ITextComponent
|
import net.minecraft.util.text.ITextComponent
|
||||||
import net.minecraft.util.text.TranslationTextComponent
|
import net.minecraft.util.text.TranslationTextComponent
|
||||||
import net.minecraft.world.Explosion
|
import net.minecraft.world.Explosion
|
||||||
import net.minecraft.world.IBlockReader
|
import net.minecraft.world.IBlockReader
|
||||||
|
import net.minecraft.world.IWorld
|
||||||
import net.minecraft.world.IWorldReader
|
import net.minecraft.world.IWorldReader
|
||||||
import net.minecraft.world.World
|
import net.minecraft.world.World
|
||||||
|
|
||||||
object BlockJarODust : HeeBlockBuilder() {
|
class BlockJarODust(builder: BlockBuilder) : BlockSimpleShaped(builder, AABB) {
|
||||||
init {
|
companion object {
|
||||||
localization = LocalizationStrategy.ReplaceWords("O", "o'")
|
val AABB = AxisAlignedBB(0.1875, 0.0, 0.1875, 0.8125, 0.84375, 0.8125)
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ItemStack
|
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
|
||||||
|
|
||||||
fun getLayersFromStack(stack: ItemStack): DustLayers? {
|
fun getLayersFromStack(stack: ItemStack): DustLayers? {
|
||||||
return if (stack.item === ModBlocks.JAR_O_DUST.asItem())
|
return if (stack.item === this.asItem())
|
||||||
stack.heeTagOrNull?.getListOfCompounds(TileEntityJarODust.LAYERS_TAG)?.let { list -> DustLayers(TileEntityJarODust.DUST_CAPACITY).apply { deserializeNBT(list) } }
|
stack.heeTagOrNull?.getListOfCompounds(TileEntityJarODust.LAYERS_TAG)?.let { list -> DustLayers(TileEntityJarODust.DUST_CAPACITY).apply { deserializeNBT(list) } }
|
||||||
else
|
else
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setLayersInStack(stack: ItemStack, layers: DustLayers) {
|
fun setLayersInStack(stack: ItemStack, layers: DustLayers) {
|
||||||
if (stack.item === ModBlocks.JAR_O_DUST.asItem()) {
|
if (stack.item === this.asItem()) {
|
||||||
stack.heeTag.putList(TileEntityJarODust.LAYERS_TAG, layers.serializeNBT())
|
stack.heeTag.putList(TileEntityJarODust.LAYERS_TAG, layers.serializeNBT())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Placement
|
||||||
|
|
||||||
|
override fun isValidPosition(state: BlockState, world: IWorldReader, pos: BlockPos): Boolean {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
return super.isValidPosition(state, world, pos) && pos.down().isTopSolid(world)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updatePostPlacement(state: BlockState, facing: Direction, neighborState: BlockState, world: IWorld, pos: BlockPos, neighborPos: BlockPos): BlockState {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
return if (facing == DOWN && !isValidPosition(state, world, pos))
|
||||||
|
Blocks.AIR.defaultState
|
||||||
|
else
|
||||||
|
super.updatePostPlacement(state, facing, neighborState, world, pos, neighborPos)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBlockPlacedBy(world: World, pos: BlockPos, state: BlockState, placer: LivingEntity?, stack: ItemStack) {
|
||||||
|
val list = stack.heeTagOrNull?.getListOfCompounds(TileEntityJarODust.LAYERS_TAG)
|
||||||
|
|
||||||
|
if (list != null) {
|
||||||
|
pos.getTile<TileEntityJarODust>(world)?.layers?.deserializeNBT(list)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Drops
|
// Drops
|
||||||
|
|
||||||
private fun getDrop(tile: TileEntityJarODust): ItemStack {
|
private fun getDrop(tile: TileEntityJarODust): ItemStack {
|
||||||
return ItemStack(ModBlocks.JAR_O_DUST).also { setLayersInStack(it, tile.layers) }
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interaction
|
// Interaction
|
||||||
|
|
||||||
|
override fun onBlockActivated(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, hit: BlockRayTraceResult): ActionResultType {
|
||||||
|
val heldItem = player.getHeldItem(hand)
|
||||||
|
|
||||||
|
val result = if (heldItem.isEmpty)
|
||||||
|
tryExtractDust(world, pos, player, hand)
|
||||||
|
else
|
||||||
|
tryInsertDust(world, pos, player, heldItem)
|
||||||
|
|
||||||
|
return if (result) SUCCESS else PASS
|
||||||
|
}
|
||||||
|
|
||||||
private fun tryExtractDust(world: World, pos: BlockPos, player: PlayerEntity, hand: Hand): Boolean {
|
private fun tryExtractDust(world: World, pos: BlockPos, player: PlayerEntity, hand: Hand): Boolean {
|
||||||
if (world.isRemote) {
|
if (world.isRemote) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
val removed = pos.getTile<TileEntityJarODust>(world)?.layers?.removeDust(if (player.isSneaking) BOTTOM else TOP)
|
val removed = pos.getTile<TileEntityJarODust>(world)?.layers?.removeDust(if (player.isSneaking) BOTTOM else TOP)
|
||||||
|
|
||||||
if (removed != null) {
|
if (removed != null) {
|
||||||
player.setHeldItem(hand, removed)
|
player.setHeldItem(hand, removed)
|
||||||
}
|
}
|
||||||
@@ -208,4 +197,23 @@ object BlockJarODust : HeeBlockBuilder() {
|
|||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Client side
|
||||||
|
|
||||||
|
@Sided(Side.CLIENT)
|
||||||
|
override fun addInformation(stack: ItemStack, world: IBlockReader?, lines: MutableList<ITextComponent>, flags: ITooltipFlag) {
|
||||||
|
val contents = getLayersFromStack(stack)?.contents
|
||||||
|
|
||||||
|
if (contents != null) {
|
||||||
|
val entries = contents
|
||||||
|
.groupingBy { it.first }
|
||||||
|
.fold(0) { acc, entry -> acc + entry.second }
|
||||||
|
.entries
|
||||||
|
.sortedWith(compareBy({ -it.value }, { it.key.key }))
|
||||||
|
|
||||||
|
for ((dustType, dustAmount) in entries) {
|
||||||
|
lines.add(TranslationTextComponent("block.hee.jar_o_dust.tooltip.entry", dustAmount, TranslationTextComponent(dustType.item.translationKey)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,18 +1,26 @@
|
|||||||
package chylex.hee.game.block
|
package chylex.hee.game.block
|
||||||
|
|
||||||
import chylex.hee.client.text.LocalizationStrategy
|
import chylex.hee.client.text.LocalizationStrategy
|
||||||
import chylex.hee.game.block.builder.HeeBlockBuilder
|
|
||||||
import chylex.hee.game.block.components.IBlockEntityComponent
|
|
||||||
import chylex.hee.game.block.entity.TileEntityMinersBurialAltar
|
import chylex.hee.game.block.entity.TileEntityMinersBurialAltar
|
||||||
|
import chylex.hee.game.block.properties.BlockBuilder
|
||||||
import chylex.hee.game.block.properties.BlockModel
|
import chylex.hee.game.block.properties.BlockModel
|
||||||
|
import net.minecraft.block.BlockState
|
||||||
|
import net.minecraft.tileentity.TileEntity
|
||||||
|
import net.minecraft.util.math.AxisAlignedBB
|
||||||
|
import net.minecraft.world.IBlockReader
|
||||||
|
|
||||||
object BlockMinersBurialAltar : HeeBlockBuilder() {
|
class BlockMinersBurialAltar(builder: BlockBuilder) : BlockSimpleShaped(builder, AxisAlignedBB(0.0, 0.0, 0.0, 1.0, 0.75, 1.0)) {
|
||||||
init {
|
override val localization
|
||||||
includeFrom(BlockMinersBurialCube.INDESCRUCTIBLE)
|
get() = LocalizationStrategy.ReplaceWords("Miners", "Miner's")
|
||||||
|
|
||||||
localization = LocalizationStrategy.ReplaceWords("Miners", "Miner's")
|
override val model
|
||||||
model = BlockModel.Manual
|
get() = BlockModel.Manual
|
||||||
|
|
||||||
components.entity = IBlockEntityComponent(::TileEntityMinersBurialAltar)
|
override fun hasTileEntity(state: BlockState): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createTileEntity(state: BlockState, world: IBlockReader): TileEntity {
|
||||||
|
return TileEntityMinersBurialAltar()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,29 +1,9 @@
|
|||||||
package chylex.hee.game.block
|
package chylex.hee.game.block
|
||||||
|
|
||||||
import chylex.hee.client.text.LocalizationStrategy
|
import chylex.hee.client.text.LocalizationStrategy
|
||||||
import chylex.hee.game.block.builder.HeeBlockBuilder
|
import chylex.hee.game.block.properties.BlockBuilder
|
||||||
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
|
|
||||||
|
|
||||||
object BlockMinersBurialCube : HeeBlockBuilder() {
|
class BlockMinersBurialCube(builder: BlockBuilder) : HeeBlock(builder) {
|
||||||
init {
|
override val localization
|
||||||
localization = LocalizationStrategy.Parenthesized(LocalizationStrategy.DeleteWords(LocalizationStrategy.ReplaceWords("Miners", "Miner's"), "Plain"), wordCount = 1, wordOffset = 3, fromStart = true)
|
get() = 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,50 +1,28 @@
|
|||||||
package chylex.hee.game.block
|
package chylex.hee.game.block
|
||||||
|
|
||||||
import chylex.hee.client.text.LocalizationStrategy
|
import chylex.hee.client.text.LocalizationStrategy
|
||||||
import chylex.hee.game.block.builder.HeeBlockBuilder
|
import chylex.hee.game.block.properties.BlockBuilder
|
||||||
import chylex.hee.game.block.properties.BlockHardness
|
|
||||||
import chylex.hee.game.block.properties.BlockHarvestTool
|
|
||||||
import chylex.hee.game.block.properties.BlockStateModels
|
import chylex.hee.game.block.properties.BlockStateModels
|
||||||
import chylex.hee.game.block.properties.Materials
|
|
||||||
import chylex.hee.game.item.util.Tool.Level.DIAMOND
|
|
||||||
import net.minecraft.block.Block
|
import net.minecraft.block.Block
|
||||||
import net.minecraft.block.SoundType
|
|
||||||
import net.minecraft.block.material.MaterialColor
|
|
||||||
import net.minecraftforge.common.Tags
|
import net.minecraftforge.common.Tags
|
||||||
import net.minecraftforge.common.ToolType.PICKAXE
|
|
||||||
|
|
||||||
object BlockObsidianCube : HeeBlockBuilder() {
|
open class BlockObsidianCube(builder: BlockBuilder) : HeeBlock(builder) {
|
||||||
private val DEFAULT_LOCALIZATION = LocalizationStrategy.MoveToBeginning(wordCount = 1, wordOffset = 1, fromStart = true)
|
override val localization: LocalizationStrategy
|
||||||
|
get() = LocalizationStrategy.MoveToBeginning(wordCount = 1, wordOffset = 1, fromStart = true)
|
||||||
|
|
||||||
init {
|
final override val tags
|
||||||
localization = DEFAULT_LOCALIZATION
|
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)
|
||||||
|
|
||||||
tags.add(Tags.Blocks.OBSIDIAN)
|
override val model
|
||||||
|
get() = BlockStateModels.Cube(modelBlock)
|
||||||
material = Materials.SOLID
|
|
||||||
color = MaterialColor.BLACK
|
|
||||||
sound = SoundType.STONE
|
|
||||||
tool = BlockHarvestTool.required(DIAMOND, PICKAXE)
|
|
||||||
hardness = BlockHardness(hardness = 20F, resistance = 300F)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Lit(modelBlock: Block) : HeeBlockBuilder() {
|
class TowerTop(builder: BlockBuilder, modelBlock: Block) : Lit(builder, modelBlock) {
|
||||||
init {
|
override val localization
|
||||||
includeFrom(BlockObsidianCube)
|
get() = LocalizationStrategy.Default
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
10
src/main/java/chylex/hee/game/block/BlockPortalFrame.kt
Normal file
10
src/main/java/chylex/hee/game/block/BlockPortalFrame.kt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
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,20 +3,16 @@ package chylex.hee.game.block
|
|||||||
import chylex.hee.client.text.LocalizationStrategy
|
import chylex.hee.client.text.LocalizationStrategy
|
||||||
import chylex.hee.client.util.MC
|
import chylex.hee.client.util.MC
|
||||||
import chylex.hee.game.Resource
|
import chylex.hee.game.Resource
|
||||||
import chylex.hee.game.block.BlockPuzzleLogic.IPuzzleLogic
|
|
||||||
import chylex.hee.game.block.BlockPuzzleLogic.State.ACTIVE
|
import chylex.hee.game.block.BlockPuzzleLogic.State.ACTIVE
|
||||||
import chylex.hee.game.block.BlockPuzzleLogic.State.DISABLED
|
import chylex.hee.game.block.BlockPuzzleLogic.State.DISABLED
|
||||||
import chylex.hee.game.block.BlockPuzzleLogic.State.INACTIVE
|
import chylex.hee.game.block.BlockPuzzleLogic.State.INACTIVE
|
||||||
import chylex.hee.game.block.builder.HeeBlockBuilder
|
import chylex.hee.game.block.properties.BlockBuilder
|
||||||
import chylex.hee.game.block.components.IBlockPlacementComponent
|
|
||||||
import chylex.hee.game.block.interfaces.IBlockInterface
|
|
||||||
import chylex.hee.game.block.interfaces.getHeeInterface
|
|
||||||
import chylex.hee.game.block.properties.BlockModel
|
import chylex.hee.game.block.properties.BlockModel
|
||||||
import chylex.hee.game.block.properties.BlockRenderLayer.CUTOUT
|
import chylex.hee.game.block.properties.BlockRenderLayer.CUTOUT
|
||||||
import chylex.hee.game.block.properties.BlockStateModel
|
import chylex.hee.game.block.properties.BlockStateModel
|
||||||
import chylex.hee.game.block.properties.BlockStatePreset
|
import chylex.hee.game.block.properties.BlockStatePreset
|
||||||
import chylex.hee.game.block.properties.BlockTint
|
import chylex.hee.game.block.properties.BlockTint
|
||||||
import chylex.hee.game.block.properties.Materials
|
import chylex.hee.game.block.properties.IBlockStateModel
|
||||||
import chylex.hee.game.block.util.Property
|
import chylex.hee.game.block.util.Property
|
||||||
import chylex.hee.game.block.util.withFacing
|
import chylex.hee.game.block.util.withFacing
|
||||||
import chylex.hee.game.entity.util.posVec
|
import chylex.hee.game.entity.util.posVec
|
||||||
@@ -50,10 +46,9 @@ import chylex.hee.util.random.nextFloat
|
|||||||
import net.minecraft.block.Block
|
import net.minecraft.block.Block
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.block.HorizontalBlock.HORIZONTAL_FACING
|
import net.minecraft.block.HorizontalBlock.HORIZONTAL_FACING
|
||||||
import net.minecraft.block.SoundType
|
|
||||||
import net.minecraft.block.material.MaterialColor
|
|
||||||
import net.minecraft.entity.Entity
|
import net.minecraft.entity.Entity
|
||||||
import net.minecraft.item.BlockItemUseContext
|
import net.minecraft.item.BlockItemUseContext
|
||||||
|
import net.minecraft.state.StateContainer.Builder
|
||||||
import net.minecraft.util.Direction
|
import net.minecraft.util.Direction
|
||||||
import net.minecraft.util.Direction.NORTH
|
import net.minecraft.util.Direction.NORTH
|
||||||
import net.minecraft.util.Direction.SOUTH
|
import net.minecraft.util.Direction.SOUTH
|
||||||
@@ -65,7 +60,7 @@ import net.minecraft.world.IBlockDisplayReader
|
|||||||
import net.minecraft.world.World
|
import net.minecraft.world.World
|
||||||
import java.util.Random
|
import java.util.Random
|
||||||
|
|
||||||
class BlockPuzzleLogic(impl: IPuzzleLogic) : HeeBlockBuilder() {
|
sealed class BlockPuzzleLogic(builder: BlockBuilder) : HeeBlock(builder) {
|
||||||
companion object {
|
companion object {
|
||||||
val STATE = Property.enum<State>("state")
|
val STATE = Property.enum<State>("state")
|
||||||
|
|
||||||
@@ -106,7 +101,7 @@ class BlockPuzzleLogic(impl: IPuzzleLogic) : HeeBlockBuilder() {
|
|||||||
var closest = pos
|
var closest = pos
|
||||||
var closestDistSq = pos.distanceSqTo(player)
|
var closestDistSq = pos.distanceSqTo(player)
|
||||||
|
|
||||||
for (testPos in pos.floodFill(Facing4) { isPuzzleBlock(it.getBlock(world)) }) {
|
for (testPos in pos.floodFill(Facing4) { it.getBlock(world) is BlockPuzzleLogic }) {
|
||||||
PARTICLE_TOGGLE.spawn(Point(testPos, 3), rand)
|
PARTICLE_TOGGLE.spawn(Point(testPos, 3), rand)
|
||||||
|
|
||||||
val distSq = testPos.distanceSqTo(player)
|
val distSq = testPos.distanceSqTo(player)
|
||||||
@@ -128,12 +123,8 @@ class BlockPuzzleLogic(impl: IPuzzleLogic) : HeeBlockBuilder() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isPuzzleBlock(block: Block): Boolean {
|
private fun isPuzzleBlockEnabled(state: BlockState): Boolean {
|
||||||
return block.getHeeInterface<IPuzzleLogic>() != null
|
return state.block is BlockPuzzleLogic && state[STATE] != DISABLED
|
||||||
}
|
|
||||||
|
|
||||||
fun isPuzzleBlockEnabled(state: BlockState): Boolean {
|
|
||||||
return isPuzzleBlock(state.block) && state[STATE] != DISABLED
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun findAllBlocks(world: World, pos: BlockPos): List<BlockPos> {
|
fun findAllBlocks(world: World, pos: BlockPos): List<BlockPos> {
|
||||||
@@ -213,66 +204,6 @@ class BlockPuzzleLogic(impl: IPuzzleLogic) : HeeBlockBuilder() {
|
|||||||
mapOf("top" to Resource.Custom("block/puzzle_overlay_$itemSuffix"))
|
mapOf("top" to Resource.Custom("block/puzzle_overlay_$itemSuffix"))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
fun onToggled(world: World, pos: BlockPos, facing: Direction): List<Pair<BlockPos, Direction>> {
|
|
||||||
val state = pos.getState(world)
|
|
||||||
val logic = state.block.getHeeInterface<IPuzzleLogic>()
|
|
||||||
|
|
||||||
return if (logic != null && toggleState(world, pos, state))
|
|
||||||
logic.getNextChains(world, pos, facing)
|
|
||||||
else
|
|
||||||
emptyList()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun toggleState(world: World, pos: BlockPos, state: BlockState): Boolean {
|
|
||||||
val type = state[STATE]
|
|
||||||
|
|
||||||
if (type == DISABLED) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
pos.setState(world, state.with(STATE, type.toggled))
|
|
||||||
PacketClientFX(FX_TOGGLE, FxBlockData(pos)).sendToAllAround(world, pos, 24.0)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
includeFrom(BlockIndestructible)
|
|
||||||
|
|
||||||
renderLayer = CUTOUT
|
|
||||||
|
|
||||||
material = Materials.SOLID
|
|
||||||
color = MaterialColor.ADOBE /* RENAME ORANGE */
|
|
||||||
sound = SoundType.STONE
|
|
||||||
|
|
||||||
tint = object : BlockTint() {
|
|
||||||
@Sided(Side.CLIENT)
|
|
||||||
override fun tint(state: BlockState, world: IBlockDisplayReader?, pos: BlockPos?, tintIndex: Int): Int {
|
|
||||||
if (tintIndex != 1) {
|
|
||||||
return NO_TINT
|
|
||||||
}
|
|
||||||
|
|
||||||
if (world == null && pos == null) {
|
|
||||||
return RGB(104, 58, 16).i // make the color slightly more visible in inventory
|
|
||||||
}
|
|
||||||
|
|
||||||
return when (state[STATE]) {
|
|
||||||
ACTIVE -> RGB(117, 66, 19).i
|
|
||||||
INACTIVE -> RGB(212, 157, 102).i
|
|
||||||
DISABLED -> RGB( 58, 40, 23).i
|
|
||||||
else -> NO_TINT
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
components.states.set(STATE, ACTIVE)
|
|
||||||
|
|
||||||
interfaces[IPuzzleLogic::class.java] = impl
|
|
||||||
}
|
|
||||||
|
|
||||||
fun interface IPuzzleLogic : IBlockInterface {
|
|
||||||
fun getNextChains(world: World, pos: BlockPos, facing: Direction): List<Pair<BlockPos, Direction>>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class State(private val serializableName: String) : IStringSerializable {
|
enum class State(private val serializableName: String) : IStringSerializable {
|
||||||
@@ -292,101 +223,159 @@ class BlockPuzzleLogic(impl: IPuzzleLogic) : HeeBlockBuilder() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object Plain : HeeBlockBuilder() {
|
abstract override val model: IBlockStateModel
|
||||||
internal val LOGIC = IPuzzleLogic { _, pos, facing -> listOf(makePair(pos, facing)) }
|
|
||||||
|
final override val renderLayer
|
||||||
|
get() = CUTOUT
|
||||||
|
|
||||||
|
init {
|
||||||
|
defaultState = stateContainer.baseState.with(STATE, ACTIVE)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun fillStateContainer(container: Builder<Block, BlockState>) {
|
||||||
|
container.add(STATE)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Logic
|
||||||
|
|
||||||
|
fun onToggled(world: World, pos: BlockPos, facing: Direction): List<Pair<BlockPos, Direction>> {
|
||||||
|
val state = pos.getState(world)
|
||||||
|
|
||||||
init {
|
return if (toggleState(world, pos, state))
|
||||||
includeFrom(BlockPuzzleLogic(LOGIC))
|
getNextChains(world, pos, facing)
|
||||||
|
else
|
||||||
localization = LocalizationStrategy.Parenthesized(wordCount = 1, fromStart = false)
|
emptyList()
|
||||||
model = createPlainModel()
|
}
|
||||||
|
|
||||||
|
protected fun toggleState(world: World, pos: BlockPos, state: BlockState): Boolean {
|
||||||
|
val type = state[STATE]
|
||||||
|
|
||||||
|
if (type == DISABLED) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
pos.setState(world, state.with(STATE, type.toggled))
|
||||||
|
PacketClientFX(FX_TOGGLE, FxBlockData(pos)).sendToAllAround(world, pos, 24.0)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract fun getNextChains(world: World, pos: BlockPos, facing: Direction): List<Pair<BlockPos, Direction>>
|
||||||
|
|
||||||
|
// Variations
|
||||||
|
|
||||||
|
class Plain(builder: BlockBuilder) : BlockPuzzleLogic(builder) {
|
||||||
|
override val localization
|
||||||
|
get() = LocalizationStrategy.Parenthesized(wordCount = 1, fromStart = false)
|
||||||
|
|
||||||
|
override val model
|
||||||
|
get() = createPlainModel()
|
||||||
|
|
||||||
|
override fun getNextChains(world: World, pos: BlockPos, facing: Direction): List<Pair<BlockPos, Direction>> {
|
||||||
|
return listOf(makePair(pos, facing))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Burst(radius: Int) : HeeBlockBuilder() {
|
class Burst(builder: BlockBuilder, private val radius: Int) : BlockPuzzleLogic(builder) {
|
||||||
private val logic = IPuzzleLogic { world, pos, facing ->
|
override val localization
|
||||||
pos.allInCenteredBox(radius, 0, radius).toList().flatMap { toggleAndChain(world, it, facing) }.distinct()
|
get() = LocalizationStrategy.Parenthesized(LocalizationStrategy.ReplaceWords("$diameter", "${diameter}x${diameter}"), wordCount = 2, fromStart = false)
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
override val model
|
||||||
includeFrom(BlockPuzzleLogic(logic))
|
get() = createOverlayModel("burst_$diameter")
|
||||||
|
|
||||||
val diameter = 1 + (radius * 2)
|
private val diameter
|
||||||
localization = LocalizationStrategy.Parenthesized(LocalizationStrategy.ReplaceWords("$diameter", "${diameter}x${diameter}"), wordCount = 2, fromStart = false)
|
get() = 1 + (radius * 2)
|
||||||
model = createOverlayModel("burst_$diameter")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun toggleAndChain(world: World, pos: BlockPos, facing: Direction): List<Pair<BlockPos, Direction>> {
|
private fun toggleAndChain(world: World, pos: BlockPos, facing: Direction): List<Pair<BlockPos, Direction>> {
|
||||||
val state = pos.getState(world)
|
val state = pos.getState(world)
|
||||||
val logic = state.block.getHeeInterface<IPuzzleLogic>()
|
val block = state.block
|
||||||
|
|
||||||
return if (logic == null || !toggleState(world, pos, state) || logic === Plain.LOGIC || logic === this.logic)
|
return if (block !is BlockPuzzleLogic || !toggleState(world, pos, state) || block is Plain || block is Burst)
|
||||||
emptyList()
|
emptyList()
|
||||||
else
|
else
|
||||||
logic.getNextChains(world, pos, facing)
|
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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class RedirectSome(blockDirections: Array<String>, itemDirection: String, directions: Array<Direction>) : HeeBlockBuilder() {
|
sealed class RedirectSome private constructor(builder: BlockBuilder, private val blockDirections: Array<String>, private val itemDirection: String, private val directions: Array<Direction>) : BlockPuzzleLogic(builder) {
|
||||||
private val logic = BlockPuzzleLogic { world, pos, facing ->
|
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>> {
|
||||||
val rotation = pos.getState(world)[HORIZONTAL_FACING].horizontalIndex + NORTH.horizontalIndex
|
val rotation = pos.getState(world)[HORIZONTAL_FACING].horizontalIndex + NORTH.horizontalIndex
|
||||||
val exclude = facing.opposite
|
val exclude = facing.opposite
|
||||||
|
|
||||||
directions.map { Direction.byHorizontalIndex(it.horizontalIndex + rotation) }.filter { it != exclude }.map { makePair(pos, it) }
|
return 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)
|
||||||
|
|
||||||
init {
|
override val model
|
||||||
includeFrom(logic)
|
get() = createOverlayModel("redirect_4")
|
||||||
|
|
||||||
localization = LocalizationStrategy.Parenthesized(wordCount = 2, fromStart = false)
|
|
||||||
model = createOverlayModel("redirect_" + directions.size + itemDirection, blockDirections.map { "redirect_" + directions.size + it })
|
|
||||||
|
|
||||||
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 {
|
override fun getNextChains(world: World, pos: BlockPos, facing: Direction): List<Pair<BlockPos, Direction>> {
|
||||||
includeFrom(BlockPuzzleLogic(logic))
|
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
|
||||||
|
}
|
||||||
|
|
||||||
localization = LocalizationStrategy.Parenthesized(wordCount = 1, fromStart = false)
|
if (world == null && pos == null) {
|
||||||
model = createOverlayModel("teleport")
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,20 +1,9 @@
|
|||||||
package chylex.hee.game.block
|
package chylex.hee.game.block
|
||||||
|
|
||||||
import chylex.hee.client.text.LocalizationStrategy
|
import chylex.hee.client.text.LocalizationStrategy
|
||||||
import chylex.hee.game.block.builder.HeeBlockBuilder
|
import chylex.hee.game.block.properties.BlockBuilder
|
||||||
import chylex.hee.game.block.properties.Materials
|
|
||||||
import net.minecraft.block.SoundType
|
|
||||||
import net.minecraft.block.material.MaterialColor
|
|
||||||
|
|
||||||
object BlockPuzzleWall : HeeBlockBuilder() {
|
class BlockPuzzleWall(builder: BlockBuilder) : HeeBlock(builder) {
|
||||||
init {
|
override val localization
|
||||||
includeFrom(BlockIndestructible)
|
get() = LocalizationStrategy.Parenthesized(wordCount = 1, fromStart = false)
|
||||||
|
|
||||||
localization = LocalizationStrategy.Parenthesized(wordCount = 1, fromStart = false)
|
|
||||||
|
|
||||||
material = Materials.SOLID
|
|
||||||
color = MaterialColor.ADOBE // RENAME ORANGE
|
|
||||||
sound = SoundType.STONE
|
|
||||||
light = 14
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -2,55 +2,62 @@ package chylex.hee.game.block
|
|||||||
|
|
||||||
import chylex.hee.HEE
|
import chylex.hee.HEE
|
||||||
import chylex.hee.game.Environment
|
import chylex.hee.game.Environment
|
||||||
import chylex.hee.game.block.builder.HeeBlockBuilder
|
import chylex.hee.game.block.properties.BlockBuilder
|
||||||
import chylex.hee.game.block.components.IBlockShapeComponent
|
|
||||||
import chylex.hee.game.block.properties.BlockModel
|
import chylex.hee.game.block.properties.BlockModel
|
||||||
import chylex.hee.game.block.properties.BlockRenderLayer.CUTOUT
|
import chylex.hee.game.block.properties.BlockRenderLayer.CUTOUT
|
||||||
import chylex.hee.game.block.properties.Materials
|
import chylex.hee.util.forge.Side
|
||||||
|
import chylex.hee.util.forge.Sided
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.block.SoundType
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.block.material.MaterialColor
|
import net.minecraft.util.math.shapes.ISelectionContext
|
||||||
import net.minecraft.util.math.shapes.VoxelShape
|
import net.minecraft.util.math.shapes.VoxelShape
|
||||||
import net.minecraft.util.math.shapes.VoxelShapes
|
import net.minecraft.util.math.shapes.VoxelShapes
|
||||||
|
import net.minecraft.world.IBlockReader
|
||||||
|
|
||||||
object BlockScaffolding : HeeBlockBuilder() {
|
open class BlockScaffolding protected constructor(builder: BlockBuilder) : HeeBlock(builder) {
|
||||||
var enableShape = true
|
companion object {
|
||||||
|
var enableShape = true
|
||||||
init {
|
|
||||||
includeFrom(BlockIndestructible)
|
|
||||||
|
|
||||||
model = BlockModel.Manual
|
fun create(builder: BlockBuilder): HeeBlock {
|
||||||
renderLayer = CUTOUT
|
return HEE.debugModule?.createScaffoldingBlock(builder) ?: BlockScaffolding(builder)
|
||||||
|
|
||||||
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()
|
||||||
|
|
||||||
components.ambientOcclusionValue = 1F
|
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.playerUse = HEE.debugModule?.scaffoldingBlockBehavior
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,43 +2,42 @@ package chylex.hee.game.block
|
|||||||
|
|
||||||
import chylex.hee.game.Resource
|
import chylex.hee.game.Resource
|
||||||
import chylex.hee.game.Resource.location
|
import chylex.hee.game.Resource.location
|
||||||
import chylex.hee.game.block.builder.HeeBlockBuilder
|
import chylex.hee.game.block.properties.BlockBuilder
|
||||||
import chylex.hee.game.block.components.IBlockExperienceComponent
|
|
||||||
import chylex.hee.game.block.properties.BlockDrop
|
import chylex.hee.game.block.properties.BlockDrop
|
||||||
import chylex.hee.game.block.properties.BlockHardness
|
|
||||||
import chylex.hee.game.block.properties.BlockHarvestTool
|
|
||||||
import chylex.hee.game.block.properties.BlockModel
|
import chylex.hee.game.block.properties.BlockModel
|
||||||
import chylex.hee.game.block.properties.BlockRenderLayer.CUTOUT
|
import chylex.hee.game.block.properties.BlockRenderLayer.CUTOUT
|
||||||
import chylex.hee.game.block.properties.BlockStateModel
|
import chylex.hee.game.block.properties.BlockStateModel
|
||||||
import chylex.hee.game.block.properties.BlockStatePreset
|
import chylex.hee.game.block.properties.BlockStatePreset
|
||||||
import chylex.hee.game.block.properties.IBlockStateModelSupplier
|
import chylex.hee.init.ModBlocks
|
||||||
import chylex.hee.game.item.util.Tool.Level.STONE
|
|
||||||
import chylex.hee.game.item.util.Tool.Type.PICKAXE
|
|
||||||
import chylex.hee.util.math.ceilToInt
|
import chylex.hee.util.math.ceilToInt
|
||||||
import chylex.hee.util.random.nextBiasedFloat
|
import chylex.hee.util.random.nextBiasedFloat
|
||||||
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.block.Blocks
|
import net.minecraft.block.Blocks
|
||||||
|
import net.minecraft.util.math.BlockPos
|
||||||
|
import net.minecraft.world.IWorldReader
|
||||||
|
import net.minecraft.world.World
|
||||||
|
import net.minecraftforge.common.Tags
|
||||||
|
|
||||||
object BlockStardustOre : HeeBlockBuilder() {
|
class BlockStardustOre(builder: BlockBuilder) : HeeBlock(builder) {
|
||||||
init {
|
override val model
|
||||||
includeFrom(BlockEndOre)
|
get() = BlockStateModel(
|
||||||
|
BlockStatePreset.None,
|
||||||
model = IBlockStateModelSupplier {
|
BlockModel.WithTextures(BlockModel.FromParent(Resource.Custom("block/cube_overlay")), mapOf(
|
||||||
BlockStateModel(
|
"particle" to ModBlocks.STARDUST_ORE.location("_particle"),
|
||||||
BlockStatePreset.None,
|
"base" to Blocks.END_STONE.location,
|
||||||
BlockModel.WithTextures(BlockModel.FromParent(Resource.Custom("block/cube_overlay")), mapOf(
|
))
|
||||||
"particle" to it.location("_particle"),
|
)
|
||||||
"base" to Blocks.END_STONE.location,
|
|
||||||
))
|
override val renderLayer
|
||||||
)
|
get() = CUTOUT
|
||||||
}
|
|
||||||
|
override val drop
|
||||||
renderLayer = CUTOUT
|
get() = BlockDrop.Manual
|
||||||
|
|
||||||
drop = BlockDrop.Manual
|
override val tags
|
||||||
|
get() = listOf(Tags.Blocks.ORES)
|
||||||
tool = BlockHarvestTool.required(STONE, PICKAXE)
|
|
||||||
hardness = BlockHardness(hardness = 2.8F, resistance = 8.4F)
|
override fun getExpDrop(state: BlockState, world: IWorldReader, pos: BlockPos, fortune: Int, silktouch: Int): Int {
|
||||||
|
return (((world as? World)?.rand ?: RANDOM).nextBiasedFloat(4F) * 6F).ceilToInt()
|
||||||
components.experience = IBlockExperienceComponent { rand -> (rand.nextBiasedFloat(4F) * 6F).ceilToInt() }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,26 @@
|
|||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
@@ -1,48 +0,0 @@
|
|||||||
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,16 +1,14 @@
|
|||||||
package chylex.hee.game.block
|
package chylex.hee.game.block
|
||||||
|
|
||||||
import chylex.hee.game.block.BlockAbstractPortal.IInnerPortalBlock
|
|
||||||
import chylex.hee.game.block.BlockAbstractPortal.IPortalController
|
|
||||||
import chylex.hee.game.block.BlockVoidPortalInner.Type.HUB
|
import chylex.hee.game.block.BlockVoidPortalInner.Type.HUB
|
||||||
import chylex.hee.game.block.BlockVoidPortalInner.Type.RETURN_ACTIVE
|
import chylex.hee.game.block.BlockVoidPortalInner.Type.RETURN_ACTIVE
|
||||||
import chylex.hee.game.block.builder.HeeBlockBuilder
|
|
||||||
import chylex.hee.game.block.components.IBlockNeighborChanged
|
|
||||||
import chylex.hee.game.block.entity.TileEntityPortalInner
|
import chylex.hee.game.block.entity.TileEntityPortalInner
|
||||||
import chylex.hee.game.block.entity.TileEntityVoidPortalStorage
|
import chylex.hee.game.block.entity.TileEntityVoidPortalStorage
|
||||||
|
import chylex.hee.game.block.properties.BlockBuilder
|
||||||
import chylex.hee.game.block.util.Property
|
import chylex.hee.game.block.util.Property
|
||||||
import chylex.hee.game.entity.Teleporter
|
import chylex.hee.game.entity.Teleporter
|
||||||
import chylex.hee.game.entity.Teleporter.FxRange.Silent
|
import chylex.hee.game.entity.Teleporter.FxRange.Silent
|
||||||
|
import chylex.hee.game.entity.util.EntityPortalContact
|
||||||
import chylex.hee.game.mechanics.causatum.EnderCausatum
|
import chylex.hee.game.mechanics.causatum.EnderCausatum
|
||||||
import chylex.hee.game.territory.TerritoryType
|
import chylex.hee.game.territory.TerritoryType
|
||||||
import chylex.hee.game.territory.system.TerritoryInstance
|
import chylex.hee.game.territory.system.TerritoryInstance
|
||||||
@@ -26,67 +24,44 @@ import chylex.hee.game.world.util.max
|
|||||||
import chylex.hee.game.world.util.min
|
import chylex.hee.game.world.util.min
|
||||||
import chylex.hee.game.world.util.offsetUntil
|
import chylex.hee.game.world.util.offsetUntil
|
||||||
import chylex.hee.game.world.util.setAir
|
import chylex.hee.game.world.util.setAir
|
||||||
import chylex.hee.init.ModTags
|
|
||||||
import chylex.hee.util.math.Pos
|
import chylex.hee.util.math.Pos
|
||||||
import chylex.hee.util.math.Vec3
|
import chylex.hee.util.math.Vec3
|
||||||
import chylex.hee.util.math.center
|
import chylex.hee.util.math.center
|
||||||
import chylex.hee.util.math.subtractY
|
import chylex.hee.util.math.subtractY
|
||||||
|
import net.minecraft.block.Block
|
||||||
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.entity.Entity
|
import net.minecraft.entity.Entity
|
||||||
import net.minecraft.entity.LivingEntity
|
import net.minecraft.entity.LivingEntity
|
||||||
import net.minecraft.entity.player.PlayerEntity
|
import net.minecraft.entity.player.PlayerEntity
|
||||||
|
import net.minecraft.state.StateContainer.Builder
|
||||||
import net.minecraft.tileentity.TileEntity
|
import net.minecraft.tileentity.TileEntity
|
||||||
import net.minecraft.util.IStringSerializable
|
import net.minecraft.util.IStringSerializable
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
|
import net.minecraft.world.IBlockReader
|
||||||
import net.minecraft.world.World
|
import net.minecraft.world.World
|
||||||
|
|
||||||
object BlockVoidPortalInner : HeeBlockBuilder() {
|
class BlockVoidPortalInner(builder: BlockBuilder) : BlockAbstractPortal(builder) {
|
||||||
val TYPE = Property.enum<Type>("type")
|
companion object {
|
||||||
|
val TYPE = Property.enum<Type>("type")
|
||||||
private val TELEPORTER = Teleporter(postEvent = false, effectRange = Silent)
|
|
||||||
|
private val TELEPORTER = Teleporter(postEvent = false, effectRange = Silent)
|
||||||
init {
|
|
||||||
includeFrom(BlockAbstractPortal(object : IInnerPortalBlock {
|
fun teleportEntity(entity: Entity, info: SpawnInfo) {
|
||||||
override fun createTileEntity(): TileEntity {
|
val targetVec = info.pos.center.subtractY(0.45)
|
||||||
return TileEntityPortalInner.Void()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun teleportEntity(world: World, pos: BlockPos, entity: Entity) {
|
if (entity is LivingEntity) {
|
||||||
when (pos.getState(world)[TYPE]) {
|
if (entity is PlayerEntity) {
|
||||||
HUB -> {
|
TerritoryType.fromPos(info.pos)?.let { EnderCausatum.triggerStage(entity, it.stage) }
|
||||||
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 -> {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
info.yaw?.let { entity.rotationYaw = it }
|
||||||
|
entity.rotationPitch = 0F
|
||||||
|
|
||||||
|
TELEPORTER.toLocation(entity, targetVec)
|
||||||
}
|
}
|
||||||
}))
|
else {
|
||||||
|
entity.setPositionAndUpdate(targetVec.x, targetVec.y, targetVec.z)
|
||||||
components.states.set(TYPE, HUB)
|
entity.motion = Vec3.ZERO
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -110,29 +85,38 @@ object BlockVoidPortalInner : HeeBlockBuilder() {
|
|||||||
fun create(entity: Entity): TerritoryInstance?
|
fun create(entity: Entity): TerritoryInstance?
|
||||||
}
|
}
|
||||||
|
|
||||||
fun teleportEntity(entity: Entity, info: SpawnInfo) {
|
// Instance
|
||||||
val targetVec = info.pos.center.subtractY(0.45)
|
|
||||||
|
init {
|
||||||
if (entity is LivingEntity) {
|
defaultState = stateContainer.baseState.with(TYPE, HUB)
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun fillStateContainer(container: Builder<Block, BlockState>) {
|
||||||
|
container.add(TYPE)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createTileEntity(state: BlockState, world: IBlockReader): TileEntity {
|
||||||
|
return TileEntityPortalInner.Void()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Breaking
|
||||||
|
|
||||||
|
override fun neighborChanged(state: BlockState, world: World, pos: BlockPos, neighborBlock: Block, neighborPos: BlockPos, isMoving: Boolean) {
|
||||||
|
if (neighborBlock is BlockVoidPortalCrafted && neighborPos.getBlock(world) !is BlockVoidPortalCrafted) {
|
||||||
|
for (portalPos in pos.floodFill(Facing4) { it.getBlock(world) === this }) {
|
||||||
|
portalPos.setAir(world)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
super.neighborChanged(state, world, pos, neighborBlock, neighborPos, isMoving)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interaction
|
||||||
|
|
||||||
private fun findSpawnPortalCenter(entity: Entity, pos: BlockPos): BlockPos? {
|
private fun findSpawnPortalCenter(entity: Entity, pos: BlockPos): BlockPos? {
|
||||||
val world = entity.world
|
val world = entity.world
|
||||||
val block = pos.getBlock(world)
|
val offsets = Facing4.map { facing -> pos.offsetUntil(facing, 1..MAX_SIZE) { it.getBlock(world) !== this } ?: return null }
|
||||||
val offsets = Facing4.map { facing -> pos.offsetUntil(facing, 1..BlockAbstractPortal.MAX_SIZE) { it.getBlock(world) !== block } ?: return null }
|
|
||||||
|
|
||||||
val minPos = offsets.reduce(BlockPos::min)
|
val minPos = offsets.reduce(BlockPos::min)
|
||||||
val maxPos = offsets.reduce(BlockPos::max)
|
val maxPos = offsets.reduce(BlockPos::max)
|
||||||
@@ -150,4 +134,37 @@ object BlockVoidPortalInner : HeeBlockBuilder() {
|
|||||||
|
|
||||||
instance.updateSpawnPoint(entity, centerPos)
|
instance.updateSpawnPoint(entity, centerPos)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onEntityInside(world: World, pos: BlockPos, entity: Entity) {
|
||||||
|
if (!EntityPortalContact.shouldTeleport(entity)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
when(pos.getState(world)[TYPE]) {
|
||||||
|
HUB -> {
|
||||||
|
val info = pos.closestTickingTile<TileEntityVoidPortalStorage>(world, MAX_DISTANCE_FROM_FRAME)?.prepareSpawnPoint(entity)
|
||||||
|
|
||||||
|
if (info != null) {
|
||||||
|
if (entity.isInEndDimension) {
|
||||||
|
DimensionTeleporter.LastHubPortal.updateForEntity(entity, null)
|
||||||
|
updateSpawnPortal(entity, pos)
|
||||||
|
teleportEntity(entity, info)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DimensionTeleporter.LastHubPortal.updateForEntity(entity, pos)
|
||||||
|
DimensionTeleporter.changeDimension(entity, World.THE_END, DimensionTeleporter.EndTerritoryPortal(info))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RETURN_ACTIVE -> {
|
||||||
|
if (!DimensionTeleporter.LastHubPortal.tryOverrideTeleport(entity)) {
|
||||||
|
updateSpawnPortal(entity, pos)
|
||||||
|
teleportEntity(entity, TerritoryInstance.THE_HUB_INSTANCE.prepareSpawnPoint(entity as? PlayerEntity, clearanceRadius = 2))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,40 +1,47 @@
|
|||||||
package chylex.hee.game.block
|
package chylex.hee.game.block
|
||||||
|
|
||||||
import chylex.hee.game.block.builder.HeeBlockBuilder
|
|
||||||
import chylex.hee.game.block.components.IBlockAddedComponent
|
|
||||||
import chylex.hee.game.block.components.IBlockEntityComponent
|
|
||||||
import chylex.hee.game.block.components.IBlockNameComponent
|
|
||||||
import chylex.hee.game.block.components.IPlayerUseBlockComponent
|
|
||||||
import chylex.hee.game.block.entity.TileEntityVoidPortalStorage
|
import chylex.hee.game.block.entity.TileEntityVoidPortalStorage
|
||||||
|
import chylex.hee.game.block.properties.BlockBuilder
|
||||||
import chylex.hee.game.block.properties.BlockModel
|
import chylex.hee.game.block.properties.BlockModel
|
||||||
import chylex.hee.game.world.util.getTile
|
import chylex.hee.game.world.util.getTile
|
||||||
import chylex.hee.init.ModBlocks
|
import chylex.hee.init.ModBlocks
|
||||||
import chylex.hee.init.ModContainers
|
import chylex.hee.init.ModContainers
|
||||||
|
import net.minecraft.block.BlockState
|
||||||
|
import net.minecraft.entity.player.PlayerEntity
|
||||||
|
import net.minecraft.tileentity.TileEntity
|
||||||
|
import net.minecraft.util.ActionResultType
|
||||||
import net.minecraft.util.ActionResultType.SUCCESS
|
import net.minecraft.util.ActionResultType.SUCCESS
|
||||||
|
import net.minecraft.util.Hand
|
||||||
|
import net.minecraft.util.math.BlockPos
|
||||||
|
import net.minecraft.util.math.BlockRayTraceResult
|
||||||
|
import net.minecraft.world.IBlockReader
|
||||||
|
import net.minecraft.world.World
|
||||||
|
|
||||||
abstract class BlockVoidPortalStorage(base: HeeBlockBuilder, minPortalSize: Int) : HeeBlockBuilder() {
|
class BlockVoidPortalStorage(builder: BlockBuilder) : BlockPortalFrame(builder) {
|
||||||
init {
|
override val model
|
||||||
includeFrom(base)
|
get() = BlockModel.PortalFrame(ModBlocks.VOID_PORTAL_FRAME, "storage")
|
||||||
|
|
||||||
model = BlockModel.PortalFrame(ModBlocks.VOID_PORTAL_FRAME, "storage")
|
override fun hasTileEntity(state: BlockState): Boolean {
|
||||||
|
return true
|
||||||
components.entity = IBlockEntityComponent(::TileEntityVoidPortalStorage)
|
|
||||||
|
|
||||||
components.onAdded = IBlockAddedComponent { _, world, pos ->
|
|
||||||
BlockAbstractPortal.spawnInnerBlocks(world, pos, ModBlocks.VOID_PORTAL_FRAME, ModBlocks.VOID_PORTAL_INNER, minSize = minPortalSize)
|
|
||||||
}
|
|
||||||
|
|
||||||
components.playerUse = IPlayerUseBlockComponent { _, world, pos, player, _ ->
|
|
||||||
pos.getTile<TileEntityVoidPortalStorage>(world)?.let { ModContainers.open(player, it, pos) }
|
|
||||||
SUCCESS
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object Indestructible : BlockVoidPortalStorage(BlockVoidPortalFrame.Indestructible, minPortalSize = 1)
|
override fun createTileEntity(state: BlockState, world: IBlockReader): TileEntity {
|
||||||
|
return TileEntityVoidPortalStorage()
|
||||||
|
}
|
||||||
|
|
||||||
object Crafted : BlockVoidPortalStorage(BlockVoidPortalFrame.Crafted, minPortalSize = 3) {
|
override fun onBlockAdded(state: BlockState, world: World, pos: BlockPos, oldState: BlockState, isMoving: Boolean) {
|
||||||
init {
|
BlockAbstractPortal.spawnInnerBlocks(world, pos, ModBlocks.VOID_PORTAL_FRAME, ModBlocks.VOID_PORTAL_INNER, minSize = 1)
|
||||||
components.name = IBlockNameComponent.of(ModBlocks.VOID_PORTAL_STORAGE)
|
}
|
||||||
|
|
||||||
|
override fun onBlockActivated(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, hit: BlockRayTraceResult): ActionResultType {
|
||||||
|
if (world.isRemote) {
|
||||||
|
return SUCCESS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pos.getTile<TileEntityVoidPortalStorage>(world)?.let {
|
||||||
|
ModContainers.open(player, it, pos)
|
||||||
|
}
|
||||||
|
|
||||||
|
return SUCCESS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,39 @@
|
|||||||
|
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,47 +1,27 @@
|
|||||||
package chylex.hee.game.block
|
package chylex.hee.game.block
|
||||||
|
|
||||||
import chylex.hee.game.Resource.location
|
import chylex.hee.game.Resource.location
|
||||||
import chylex.hee.game.block.builder.HeeBlockBuilder
|
import chylex.hee.game.block.properties.BlockBuilder
|
||||||
import chylex.hee.game.block.components.IFlammableBlockComponent
|
|
||||||
import chylex.hee.game.block.properties.BlockHardness
|
|
||||||
import chylex.hee.game.block.properties.BlockHarvestTool
|
|
||||||
import chylex.hee.game.block.properties.BlockModel
|
import chylex.hee.game.block.properties.BlockModel
|
||||||
import chylex.hee.game.item.util.Tool.Level.WOOD
|
|
||||||
import chylex.hee.init.ModBlocks
|
import chylex.hee.init.ModBlocks
|
||||||
import net.minecraft.block.SoundType
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.block.material.Material
|
|
||||||
import net.minecraft.block.material.MaterialColor
|
|
||||||
import net.minecraft.tags.BlockTags
|
import net.minecraft.tags.BlockTags
|
||||||
import net.minecraftforge.common.ToolType.AXE
|
import net.minecraft.util.Direction
|
||||||
|
import net.minecraft.util.math.BlockPos
|
||||||
|
import net.minecraft.world.IBlockReader
|
||||||
|
|
||||||
object BlockWhitebark : HeeBlockBuilder() {
|
class BlockWhitebark(builder: BlockBuilder) : HeeBlock(builder) {
|
||||||
init {
|
override val model
|
||||||
material = Material.WOOD
|
get() = BlockModel.Cube(ModBlocks.WHITEBARK_LOG.location)
|
||||||
color = MaterialColor.SNOW
|
|
||||||
sound = SoundType.WOOD
|
override val tags
|
||||||
tool = BlockHarvestTool.optional(WOOD, AXE)
|
get() = listOf(BlockTags.LOGS, BlockTags.LOGS_THAT_BURN)
|
||||||
|
|
||||||
|
override fun getFlammability(state: BlockState, world: IBlockReader, pos: BlockPos, face: Direction): Int {
|
||||||
|
return 5
|
||||||
}
|
}
|
||||||
|
|
||||||
val BARK = HeeBlockBuilder {
|
override fun getFireSpreadSpeed(state: BlockState, world: IBlockReader, pos: BlockPos, face: Direction): Int {
|
||||||
includeFrom(BlockWhitebark)
|
return 5
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
21
src/main/java/chylex/hee/game/block/BlockWhitebarkPlanks.kt
Normal file
21
src/main/java/chylex/hee/game/block/BlockWhitebarkPlanks.kt
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
@@ -32,7 +32,6 @@ import chylex.hee.game.world.util.setState
|
|||||||
import chylex.hee.init.ModSounds
|
import chylex.hee.init.ModSounds
|
||||||
import chylex.hee.network.client.PacketClientFX
|
import chylex.hee.network.client.PacketClientFX
|
||||||
import chylex.hee.util.buffer.readPos
|
import chylex.hee.util.buffer.readPos
|
||||||
import chylex.hee.util.buffer.use
|
|
||||||
import chylex.hee.util.buffer.writePos
|
import chylex.hee.util.buffer.writePos
|
||||||
import chylex.hee.util.math.center
|
import chylex.hee.util.math.center
|
||||||
import chylex.hee.util.nbt.TagCompound
|
import chylex.hee.util.nbt.TagCompound
|
||||||
@@ -174,9 +173,9 @@ interface IBlockDeathFlowerDecaying {
|
|||||||
private val PARTICLE_MOT = Gaussian(0.02F)
|
private val PARTICLE_MOT = Gaussian(0.02F)
|
||||||
|
|
||||||
class FxHealData(private val pos: BlockPos, private val newLevel: Int) : IFxData {
|
class FxHealData(private val pos: BlockPos, private val newLevel: Int) : IFxData {
|
||||||
override fun write(buffer: PacketBuffer) = buffer.use {
|
override fun write(buffer: PacketBuffer) {
|
||||||
writePos(pos)
|
buffer.writePos(pos)
|
||||||
writeByte(newLevel)
|
buffer.writeByte(newLevel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
package chylex.hee.game.block.dispenser
|
package chylex.hee.game.block.dispenser
|
||||||
|
|
||||||
import chylex.hee.game.block.BlockIgneousPlate
|
|
||||||
import chylex.hee.game.block.util.DISPENSER_FACING
|
import chylex.hee.game.block.util.DISPENSER_FACING
|
||||||
import chylex.hee.game.world.util.getState
|
import chylex.hee.game.world.util.getState
|
||||||
import chylex.hee.init.ModBlocks
|
import chylex.hee.init.ModBlocks
|
||||||
@@ -17,7 +16,7 @@ class DispenseWaterExtinguishIgneousPlate(private val originalBehavior: IDispens
|
|||||||
val facingState = facingPos.getState(world)
|
val facingState = facingPos.getState(world)
|
||||||
|
|
||||||
if (facingState.block === ModBlocks.IGNEOUS_PLATE) {
|
if (facingState.block === ModBlocks.IGNEOUS_PLATE) {
|
||||||
return if (BlockIgneousPlate.tryCoolPlate(world, facingPos, facingState))
|
return if (ModBlocks.IGNEOUS_PLATE.tryCoolPlate(world, facingPos, facingState))
|
||||||
ItemStack(Items.BUCKET)
|
ItemStack(Items.BUCKET)
|
||||||
else
|
else
|
||||||
stack
|
stack
|
||||||
|
@@ -27,7 +27,6 @@ import chylex.hee.init.ModSounds
|
|||||||
import chylex.hee.init.ModTileEntities
|
import chylex.hee.init.ModTileEntities
|
||||||
import chylex.hee.network.client.PacketClientFX
|
import chylex.hee.network.client.PacketClientFX
|
||||||
import chylex.hee.util.buffer.readCompactVec
|
import chylex.hee.util.buffer.readCompactVec
|
||||||
import chylex.hee.util.buffer.use
|
|
||||||
import chylex.hee.util.buffer.writeCompactVec
|
import chylex.hee.util.buffer.writeCompactVec
|
||||||
import chylex.hee.util.collection.mutableWeightedListOf
|
import chylex.hee.util.collection.mutableWeightedListOf
|
||||||
import chylex.hee.util.collection.weightedListOf
|
import chylex.hee.util.collection.weightedListOf
|
||||||
@@ -119,17 +118,17 @@ class TileEntityMinersBurialAltar(type: TileEntityType<TileEntityMinersBurialAlt
|
|||||||
)
|
)
|
||||||
|
|
||||||
class FxSpawnData(private val pos: Vector3d, private val type: Byte) : IFxData {
|
class FxSpawnData(private val pos: Vector3d, private val type: Byte) : IFxData {
|
||||||
override fun write(buffer: PacketBuffer) = buffer.use {
|
override fun write(buffer: PacketBuffer) {
|
||||||
writeCompactVec(pos)
|
buffer.writeCompactVec(pos)
|
||||||
writeByte(type.toInt())
|
buffer.writeByte(type.toInt())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val FX_SPAWN = object : IFxHandler<FxSpawnData> {
|
val FX_SPAWN = object : IFxHandler<FxSpawnData> {
|
||||||
override fun handle(buffer: PacketBuffer, world: World, rand: Random) = buffer.use {
|
override fun handle(buffer: PacketBuffer, world: World, rand: Random) {
|
||||||
val pos = readCompactVec()
|
val pos = buffer.readCompactVec()
|
||||||
|
|
||||||
when (readByte()) {
|
when (buffer.readByte()) {
|
||||||
REDEEM_TYPE_TOKEN -> {
|
REDEEM_TYPE_TOKEN -> {
|
||||||
PARTICLE_SPAWN.spawn(Point(pos, 9), rand)
|
PARTICLE_SPAWN.spawn(Point(pos, 9), rand)
|
||||||
}
|
}
|
||||||
|
@@ -36,6 +36,7 @@ abstract class TileEntityBasePortalController(type: TileEntityType<out TileEntit
|
|||||||
when (clientRenderState) {
|
when (clientRenderState) {
|
||||||
Invisible -> clientAnimationProgress.update(max(0F, clientAnimationProgress - clientAnimationFadeOutSpeed))
|
Invisible -> clientAnimationProgress.update(max(0F, clientAnimationProgress - clientAnimationFadeOutSpeed))
|
||||||
is Animating -> clientAnimationProgress.update(min(1F, clientAnimationProgress + clientAnimationFadeInSpeed))
|
is Animating -> clientAnimationProgress.update(min(1F, clientAnimationProgress + clientAnimationFadeInSpeed))
|
||||||
|
else -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -46,6 +46,13 @@ object BlockBuilders {
|
|||||||
explosionResistance = 0.6F
|
explosionResistance = 0.6F
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val buildEndiumBlock = BlockBuilder(Materials.SOLID, MaterialColor.LAPIS, SoundType.METAL).apply {
|
||||||
|
requiresTool = true
|
||||||
|
harvestTool = Pair(IRON, PICKAXE)
|
||||||
|
harvestHardness = 6.2F
|
||||||
|
explosionResistance = 12.0F
|
||||||
|
}
|
||||||
|
|
||||||
val buildEnderSol = BlockBuilder(Materials.SOLID, MaterialColor.WOOD, SoundType.GROUND.clone(pitch = 0.85F)).apply {
|
val buildEnderSol = BlockBuilder(Materials.SOLID, MaterialColor.WOOD, SoundType.GROUND.clone(pitch = 0.85F)).apply {
|
||||||
requiresTool = true
|
requiresTool = true
|
||||||
harvestTool = Pair(WOOD, SHOVEL)
|
harvestTool = Pair(WOOD, SHOVEL)
|
||||||
@@ -69,6 +76,16 @@ object BlockBuilders {
|
|||||||
explosionResistance = 4.2F
|
explosionResistance = 4.2F
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val buildGloomrockBricks = buildGloomrock.clone {
|
||||||
|
harvestHardness = 2.8F
|
||||||
|
explosionResistance = 6.0F
|
||||||
|
}
|
||||||
|
|
||||||
|
val buildGloomrockSmooth = buildGloomrock.clone {
|
||||||
|
harvestHardness = 2.0F
|
||||||
|
explosionResistance = 4.8F
|
||||||
|
}
|
||||||
|
|
||||||
val buildGloomtorch = BlockBuilder(Materials.SOLID, MaterialColor.BLACK, SoundType.STONE).apply {
|
val buildGloomtorch = BlockBuilder(Materials.SOLID, MaterialColor.BLACK, SoundType.STONE).apply {
|
||||||
explosionResistance = 0.3F
|
explosionResistance = 0.3F
|
||||||
lightLevel = 13
|
lightLevel = 13
|
||||||
@@ -116,6 +133,19 @@ object BlockBuilders {
|
|||||||
lightLevel = 15
|
lightLevel = 15
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val buildObsidianTowerTop = buildObsidianVariationLit.clone {
|
||||||
|
makeIndestructible()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Building (End Stone)
|
||||||
|
|
||||||
|
val buildEndStone = BlockBuilder(Materials.SOLID, MaterialColor.SAND, SoundType.STONE).apply {
|
||||||
|
requiresTool = true
|
||||||
|
harvestTool = Pair(WOOD, PICKAXE)
|
||||||
|
harvestHardness = 3.0F
|
||||||
|
explosionResistance = 9.0F
|
||||||
|
}
|
||||||
|
|
||||||
// Building (Dark Loam)
|
// Building (Dark Loam)
|
||||||
|
|
||||||
val buildDarkLoam = BlockBuilder(Materials.SOLID, MaterialColor.BLACK, SoundType.GROUND).apply {
|
val buildDarkLoam = BlockBuilder(Materials.SOLID, MaterialColor.BLACK, SoundType.GROUND).apply {
|
||||||
@@ -132,6 +162,10 @@ object BlockBuilders {
|
|||||||
explosionResistance = 2.0F
|
explosionResistance = 2.0F
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val buildWhitebarkPlanks = buildWhitebark.clone {
|
||||||
|
explosionResistance = 3.0F
|
||||||
|
}
|
||||||
|
|
||||||
// Building (Miner's Burial)
|
// Building (Miner's Burial)
|
||||||
|
|
||||||
val buildMinersBurial = BlockBuilder(Materials.SOLID, MaterialColor.RED, SoundType.STONE).apply {
|
val buildMinersBurial = BlockBuilder(Materials.SOLID, MaterialColor.RED, SoundType.STONE).apply {
|
||||||
@@ -141,6 +175,10 @@ object BlockBuilders {
|
|||||||
explosionResistance = 120F
|
explosionResistance = 120F
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val buildMinersBurialIndestructible = buildMinersBurial.clone {
|
||||||
|
makeIndestructible()
|
||||||
|
}
|
||||||
|
|
||||||
// Fluids
|
// Fluids
|
||||||
|
|
||||||
val buildCauldron = BlockBuilder(Material.IRON, MaterialColor.STONE, SoundType.STONE).apply {
|
val buildCauldron = BlockBuilder(Material.IRON, MaterialColor.STONE, SoundType.STONE).apply {
|
||||||
@@ -150,11 +188,26 @@ object BlockBuilders {
|
|||||||
|
|
||||||
// Interactive (Storage)
|
// Interactive (Storage)
|
||||||
|
|
||||||
|
val buildJarODust = BlockBuilder(Materials.JAR_O_DUST, MaterialColor.ORANGE_TERRACOTTA, SoundType.METAL).apply {
|
||||||
|
harvestHardness = 0.4F
|
||||||
|
explosionResistance = 0F
|
||||||
|
}
|
||||||
|
|
||||||
val buildLootChest = BlockBuilder(Materials.SOLID, MaterialColor.BLACK, SoundType.METAL).apply {
|
val buildLootChest = BlockBuilder(Materials.SOLID, MaterialColor.BLACK, SoundType.METAL).apply {
|
||||||
makeIndestructible()
|
makeIndestructible()
|
||||||
lightLevel = 13
|
lightLevel = 13
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Interactive (Puzzle)
|
||||||
|
|
||||||
|
val buildPuzzleLogic = BlockBuilder(Materials.SOLID, MaterialColor.ADOBE /* RENAME ORANGE */, SoundType.STONE).apply {
|
||||||
|
makeIndestructible()
|
||||||
|
}
|
||||||
|
|
||||||
|
val buildPuzzleWall = buildPuzzleLogic.clone {
|
||||||
|
lightLevel = 14
|
||||||
|
}
|
||||||
|
|
||||||
// Interactive (Gates)
|
// Interactive (Gates)
|
||||||
|
|
||||||
val buildExperienceGate = BlockBuilder(Materials.SOLID, MaterialColor.GREEN, SoundType.METAL).apply {
|
val buildExperienceGate = BlockBuilder(Materials.SOLID, MaterialColor.GREEN, SoundType.METAL).apply {
|
||||||
@@ -164,6 +217,8 @@ object BlockBuilders {
|
|||||||
|
|
||||||
// Interactive (Uncategorized)
|
// Interactive (Uncategorized)
|
||||||
|
|
||||||
|
val buildIgneousPlate = BlockBuilder(Materials.IGNEOUS_ROCK_PLATE, MaterialColor.AIR, SoundType.STONE)
|
||||||
|
|
||||||
val buildBrewingStand = BlockBuilder(Material.IRON, MaterialColor.YELLOW, SoundType.STONE).apply {
|
val buildBrewingStand = BlockBuilder(Material.IRON, MaterialColor.YELLOW, SoundType.STONE).apply {
|
||||||
isSolid = false
|
isSolid = false
|
||||||
harvestHardness = 0.5F
|
harvestHardness = 0.5F
|
||||||
@@ -177,6 +232,24 @@ object BlockBuilders {
|
|||||||
requiresTool = true
|
requiresTool = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val buildEndPowderOre = buildEndOre.clone {
|
||||||
|
harvestTool = Pair(STONE, PICKAXE)
|
||||||
|
harvestHardness = 2.0F
|
||||||
|
explosionResistance = 5.4F
|
||||||
|
}
|
||||||
|
|
||||||
|
val buildEndiumOre = buildEndOre.clone {
|
||||||
|
harvestTool = Pair(IRON, PICKAXE)
|
||||||
|
harvestHardness = 5.0F
|
||||||
|
explosionResistance = 9.9F
|
||||||
|
}
|
||||||
|
|
||||||
|
val buildStardustOre = buildEndOre.clone {
|
||||||
|
harvestTool = Pair(STONE, PICKAXE)
|
||||||
|
harvestHardness = 2.8F
|
||||||
|
explosionResistance = 8.4F
|
||||||
|
}
|
||||||
|
|
||||||
val buildIgneousRockOre = buildEndOre.clone {
|
val buildIgneousRockOre = buildEndOre.clone {
|
||||||
harvestTool = Pair(DIAMOND, PICKAXE)
|
harvestTool = Pair(DIAMOND, PICKAXE)
|
||||||
harvestHardness = 1.6F
|
harvestHardness = 1.6F
|
||||||
@@ -242,6 +315,25 @@ object BlockBuilders {
|
|||||||
noDrops = true
|
noDrops = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Portals
|
||||||
|
|
||||||
|
val buildPortalInner = BlockBuilder(Material.PORTAL, MaterialColor.BLACK, SoundType.STONE).apply {
|
||||||
|
makeIndestructible()
|
||||||
|
isSolid = false
|
||||||
|
lightLevel = 15
|
||||||
|
}
|
||||||
|
|
||||||
|
val buildPortalFrame = BlockBuilder(Materials.SOLID, MaterialColor.SAND, SoundType.STONE).apply {
|
||||||
|
makeIndestructible()
|
||||||
|
}
|
||||||
|
|
||||||
|
val buildPortalFrameCrafted = BlockBuilder(Materials.SOLID, MaterialColor.SAND, SoundType.STONE).apply {
|
||||||
|
requiresTool = true
|
||||||
|
harvestTool = Pair(DIAMOND, PICKAXE)
|
||||||
|
harvestHardness = 1.7F
|
||||||
|
explosionResistance = 1.7F
|
||||||
|
}
|
||||||
|
|
||||||
// Energy
|
// Energy
|
||||||
|
|
||||||
val buildEnergyCluster = BlockBuilder(Materials.ENERGY_CLUSTER, MaterialColor.SNOW, SoundType.GLASS.clone(volume = 1.25F, pitch = 1.35F)).apply {
|
val buildEnergyCluster = BlockBuilder(Materials.ENERGY_CLUSTER, MaterialColor.SNOW, SoundType.GLASS.clone(volume = 1.25F, pitch = 1.35F)).apply {
|
||||||
@@ -250,6 +342,12 @@ object BlockBuilders {
|
|||||||
noDrops = true
|
noDrops = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val buildCorruptedEnergy = BlockBuilder(Materials.CORRUPTED_ENERGY, MaterialColor.PURPLE, SoundType.SAND).apply {
|
||||||
|
isSolid = false
|
||||||
|
randomTicks = true // just to be safe
|
||||||
|
noDrops = true
|
||||||
|
}
|
||||||
|
|
||||||
// Tables
|
// Tables
|
||||||
|
|
||||||
val buildTablePedestal = buildGloomrock.clone {
|
val buildTablePedestal = buildGloomrock.clone {
|
||||||
@@ -274,6 +372,14 @@ object BlockBuilders {
|
|||||||
lightLevel = 15
|
lightLevel = 15
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val buildScaffolding = BlockBuilder(Materials.SCAFFOLDING, MaterialColor.AIR, SoundType.STONE).apply {
|
||||||
|
makeIndestructible()
|
||||||
|
isSolid = false
|
||||||
|
isOpaque = false
|
||||||
|
suffocates = false
|
||||||
|
blocksVision = false
|
||||||
|
}
|
||||||
|
|
||||||
// Overrides
|
// Overrides
|
||||||
|
|
||||||
val buildEndPortalOverride = BlockBuilder(Material.PORTAL, MaterialColor.BLACK, SoundType.STONE).apply {
|
val buildEndPortalOverride = BlockBuilder(Material.PORTAL, MaterialColor.BLACK, SoundType.STONE).apply {
|
||||||
|
@@ -23,8 +23,9 @@ import chylex.hee.network.client.PacketClientMoveYourAss
|
|||||||
import chylex.hee.network.client.PacketClientRotateInstantly
|
import chylex.hee.network.client.PacketClientRotateInstantly
|
||||||
import chylex.hee.network.client.PacketClientTeleportInstantly
|
import chylex.hee.network.client.PacketClientTeleportInstantly
|
||||||
import chylex.hee.util.buffer.readCompactVec
|
import chylex.hee.util.buffer.readCompactVec
|
||||||
import chylex.hee.util.buffer.use
|
import chylex.hee.util.buffer.readEnum
|
||||||
import chylex.hee.util.buffer.writeCompactVec
|
import chylex.hee.util.buffer.writeCompactVec
|
||||||
|
import chylex.hee.util.buffer.writeEnum
|
||||||
import chylex.hee.util.math.Pos
|
import chylex.hee.util.math.Pos
|
||||||
import chylex.hee.util.math.Vec
|
import chylex.hee.util.math.Vec
|
||||||
import chylex.hee.util.math.addY
|
import chylex.hee.util.math.addY
|
||||||
@@ -78,16 +79,16 @@ class Teleporter(
|
|||||||
private val soundVolume: Float,
|
private val soundVolume: Float,
|
||||||
private val extraRange: Float = 0F,
|
private val extraRange: Float = 0F,
|
||||||
) : IFxData {
|
) : IFxData {
|
||||||
override fun write(buffer: PacketBuffer) = buffer.use {
|
override fun write(buffer: PacketBuffer) {
|
||||||
writeCompactVec(startPoint)
|
buffer.writeCompactVec(startPoint)
|
||||||
writeCompactVec(endPoint)
|
buffer.writeCompactVec(endPoint)
|
||||||
writeByte((width * 10F).floorToInt().coerceIn(0, 100))
|
buffer.writeByte((width * 10F).floorToInt().coerceIn(0, 100))
|
||||||
writeByte((height * 10F).floorToInt().coerceIn(0, 100))
|
buffer.writeByte((height * 10F).floorToInt().coerceIn(0, 100))
|
||||||
|
|
||||||
writeRegistryId(soundEvent)
|
buffer.writeRegistryId(soundEvent)
|
||||||
writeEnumValue(soundCategory)
|
buffer.writeEnum(soundCategory)
|
||||||
writeByte((soundVolume * 10F).floorToInt().coerceIn(0, 250))
|
buffer.writeByte((soundVolume * 10F).floorToInt().coerceIn(0, 250))
|
||||||
writeByte(extraRange.floorToInt().coerceIn(0, 255))
|
buffer.writeByte(extraRange.floorToInt().coerceIn(0, 255))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun send(world: World) {
|
fun send(world: World) {
|
||||||
@@ -99,20 +100,20 @@ class Teleporter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val FX_TELEPORT = object : IFxHandler<FxTeleportData> {
|
val FX_TELEPORT = object : IFxHandler<FxTeleportData> {
|
||||||
override fun handle(buffer: PacketBuffer, world: World, rand: Random) = buffer.use {
|
override fun handle(buffer: PacketBuffer, world: World, rand: Random) {
|
||||||
val player = MC.player ?: return
|
val player = MC.player ?: return
|
||||||
val playerPos = player.posVec
|
val playerPos = player.posVec
|
||||||
|
|
||||||
val startPoint = readCompactVec()
|
val startPoint = buffer.readCompactVec()
|
||||||
val endPoint = readCompactVec()
|
val endPoint = buffer.readCompactVec()
|
||||||
|
|
||||||
val halfWidth = (readByte() / 10F) * 0.5F
|
val halfWidth = (buffer.readByte() / 10F) * 0.5F
|
||||||
val halfHeight = (readByte() / 10F) * 0.5F
|
val halfHeight = (buffer.readByte() / 10F) * 0.5F
|
||||||
|
|
||||||
val soundEvent = readRegistryIdSafe(SoundEvent::class.java)
|
val soundEvent = buffer.readRegistryIdSafe(SoundEvent::class.java)
|
||||||
val soundCategory = readEnumValue(SoundCategory::class.java)
|
val soundCategory = buffer.readEnum() ?: SoundCategory.NEUTRAL
|
||||||
val soundVolume = readByte() / 10F
|
val soundVolume = buffer.readByte() / 10F
|
||||||
val soundRange = 16F + readByte()
|
val soundRange = 16F + buffer.readByte()
|
||||||
|
|
||||||
val soundPosition = if (playerPos.squareDistanceTo(startPoint) < playerPos.squareDistanceTo(endPoint))
|
val soundPosition = if (playerPos.squareDistanceTo(startPoint) < playerPos.squareDistanceTo(endPoint))
|
||||||
startPoint
|
startPoint
|
||||||
|
@@ -16,7 +16,6 @@ import chylex.hee.game.world.util.getTile
|
|||||||
import chylex.hee.game.world.util.removeBlock
|
import chylex.hee.game.world.util.removeBlock
|
||||||
import chylex.hee.game.world.util.setState
|
import chylex.hee.game.world.util.setState
|
||||||
import chylex.hee.init.ModEntities
|
import chylex.hee.init.ModEntities
|
||||||
import chylex.hee.util.buffer.use
|
|
||||||
import chylex.hee.util.math.Pos
|
import chylex.hee.util.math.Pos
|
||||||
import chylex.hee.util.math.Vec3
|
import chylex.hee.util.math.Vec3
|
||||||
import chylex.hee.util.math.subtractY
|
import chylex.hee.util.math.subtractY
|
||||||
@@ -86,12 +85,12 @@ open class EntityFallingBlockHeavy(type: EntityType<out EntityFallingBlockHeavy>
|
|||||||
return NetworkHooks.getEntitySpawningPacket(this)
|
return NetworkHooks.getEntitySpawningPacket(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun writeSpawnData(buffer: PacketBuffer) = buffer.use {
|
override fun writeSpawnData(buffer: PacketBuffer) {
|
||||||
writeInt(fallTile?.let(Block::getStateId) ?: 0)
|
buffer.writeInt(fallTile?.let(Block::getStateId) ?: 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun readSpawnData(buffer: PacketBuffer) = buffer.use {
|
override fun readSpawnData(buffer: PacketBuffer) {
|
||||||
fallTile = Block.getStateById(readInt())
|
fallTile = Block.getStateById(buffer.readInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun tick() {
|
override fun tick() {
|
||||||
|
@@ -18,7 +18,6 @@ import chylex.hee.init.ModEntities
|
|||||||
import chylex.hee.init.ModSounds
|
import chylex.hee.init.ModSounds
|
||||||
import chylex.hee.network.client.PacketClientFX
|
import chylex.hee.network.client.PacketClientFX
|
||||||
import chylex.hee.util.buffer.readPos
|
import chylex.hee.util.buffer.readPos
|
||||||
import chylex.hee.util.buffer.use
|
|
||||||
import chylex.hee.util.buffer.writePos
|
import chylex.hee.util.buffer.writePos
|
||||||
import chylex.hee.util.math.Pos
|
import chylex.hee.util.math.Pos
|
||||||
import chylex.hee.util.random.nextFloat
|
import chylex.hee.util.random.nextFloat
|
||||||
@@ -45,16 +44,16 @@ class EntityFallingObsidian : EntityFallingBlockHeavy {
|
|||||||
private val DAMAGE = Damage(PEACEFUL_EXCLUSION, ARMOR_PROTECTION(false), ENCHANTMENT_PROTECTION)
|
private val DAMAGE = Damage(PEACEFUL_EXCLUSION, ARMOR_PROTECTION(false), ENCHANTMENT_PROTECTION)
|
||||||
|
|
||||||
class FxFallData(private val pos: BlockPos, private val volume: Float) : IFxData {
|
class FxFallData(private val pos: BlockPos, private val volume: Float) : IFxData {
|
||||||
override fun write(buffer: PacketBuffer) = buffer.use {
|
override fun write(buffer: PacketBuffer) {
|
||||||
writePos(pos)
|
buffer.writePos(pos)
|
||||||
writeFloat(volume)
|
buffer.writeFloat(volume)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val FX_FALL = object : IFxHandler<FxFallData> {
|
val FX_FALL = object : IFxHandler<FxFallData> {
|
||||||
override fun handle(buffer: PacketBuffer, world: World, rand: Random) = buffer.use {
|
override fun handle(buffer: PacketBuffer, world: World, rand: Random) {
|
||||||
val pos = readPos()
|
val pos = buffer.readPos()
|
||||||
val volume = readFloat()
|
val volume = buffer.readFloat()
|
||||||
|
|
||||||
repeat(2) {
|
repeat(2) {
|
||||||
ModSounds.BLOCK_OBSIDIAN_LAND.playClient(pos, SoundCategory.BLOCKS, volume = volume, pitch = rand.nextFloat(0.8F, 1.2F))
|
ModSounds.BLOCK_OBSIDIAN_LAND.playClient(pos, SoundCategory.BLOCKS, volume = volume, pitch = rand.nextFloat(0.8F, 1.2F))
|
||||||
|
@@ -24,8 +24,7 @@ import chylex.hee.init.ModEntities
|
|||||||
import chylex.hee.system.heeTag
|
import chylex.hee.system.heeTag
|
||||||
import chylex.hee.util.math.Vec
|
import chylex.hee.util.math.Vec
|
||||||
import chylex.hee.util.math.center
|
import chylex.hee.util.math.center
|
||||||
import chylex.hee.util.math.range
|
import chylex.hee.util.math.remap
|
||||||
import chylex.hee.util.math.remapRange
|
|
||||||
import chylex.hee.util.nbt.TagCompound
|
import chylex.hee.util.nbt.TagCompound
|
||||||
import chylex.hee.util.nbt.use
|
import chylex.hee.util.nbt.use
|
||||||
import chylex.hee.util.random.nextFloat
|
import chylex.hee.util.random.nextFloat
|
||||||
@@ -269,9 +268,9 @@ class EntityInfusedTNT : TNTEntity {
|
|||||||
val waterRatio = foundWaterBlocks.size.toFloat() / totalCountedBlocks
|
val waterRatio = foundWaterBlocks.size.toFloat() / totalCountedBlocks
|
||||||
|
|
||||||
val dropAmount = when {
|
val dropAmount = when {
|
||||||
waterRatio < 0.1 -> remapRange(waterRatio, range(0.0F, 0.1F), range(1.0F, 1.6F))
|
waterRatio < 0.1 -> waterRatio.remap(fromMin = 0.0F, fromMax = 0.1F, toMin = 1.0F, toMax = 1.6F)
|
||||||
waterRatio < 0.4 -> remapRange(waterRatio, range(0.1F, 0.4F), range(1.6F, 4.0F))
|
waterRatio < 0.4 -> waterRatio.remap(fromMin = 0.1F, fromMax = 0.4F, toMin = 1.6F, toMax = 4.0F)
|
||||||
else -> remapRange(waterRatio, range(0.4F, 1.0F), range(4.0F, 5.8F))
|
else -> waterRatio.remap(fromMin = 0.4F, fromMax = 1.0F, toMin = 4.0F, toMax = 5.8F)
|
||||||
}
|
}
|
||||||
|
|
||||||
val lootTable = Environment.getLootTable(LootTables.GAMEPLAY_FISHING)
|
val lootTable = Environment.getLootTable(LootTables.GAMEPLAY_FISHING)
|
||||||
|
@@ -5,7 +5,6 @@ import chylex.hee.game.particle.spawner.properties.IOffset.Constant
|
|||||||
import chylex.hee.game.particle.spawner.properties.IOffset.InBox
|
import chylex.hee.game.particle.spawner.properties.IOffset.InBox
|
||||||
import chylex.hee.game.particle.spawner.properties.IShape.Point
|
import chylex.hee.game.particle.spawner.properties.IShape.Point
|
||||||
import chylex.hee.init.ModEntities
|
import chylex.hee.init.ModEntities
|
||||||
import chylex.hee.util.buffer.use
|
|
||||||
import chylex.hee.util.math.square
|
import chylex.hee.util.math.square
|
||||||
import net.minecraft.entity.EntityType
|
import net.minecraft.entity.EntityType
|
||||||
import net.minecraft.item.ItemStack
|
import net.minecraft.item.ItemStack
|
||||||
@@ -33,12 +32,12 @@ class EntityItemFreshlyCooked : EntityItemBase, IEntityAdditionalSpawnData {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun writeSpawnData(buffer: PacketBuffer) = buffer.use {
|
override fun writeSpawnData(buffer: PacketBuffer) {
|
||||||
writeShort(age)
|
buffer.writeShort(age)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun readSpawnData(buffer: PacketBuffer) = buffer.use {
|
override fun readSpawnData(buffer: PacketBuffer) {
|
||||||
age = readShort().toInt()
|
age = buffer.readShort().toInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun tick() {
|
override fun tick() {
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user