Merge branch '1.19.4' of https://git.dbotthepony.ru/DBot/overdrive_that_matters into 1.19.3
This commit is contained in:
commit
53b9a7ec02
@ -10,12 +10,20 @@ fun addBlockModels(provider: MatteryBlockModelProvider) {
|
||||
resourceCubeAll(MBlocks.DEEPSLATE_TRITANIUM_ORE)
|
||||
resourceCubeAll(MBlocks.TRITANIUM_INGOT_BLOCK)
|
||||
|
||||
cable("crude_energy_cable", "block/power_cable_0")
|
||||
cable("regular_energy_cable", "block/power_cable_1")
|
||||
cable("advanced_energy_cable", "block/power_cable_2")
|
||||
cable("superconductor_energy_cable", "block/power_cable_3")
|
||||
cable("storage_cable", "block/storage_cable")
|
||||
|
||||
colored(MBlocks.COBBLESTONE_GENERATOR, listOf("0", "particle"))
|
||||
colored(MBlocks.ESSENCE_STORAGE, listOf("0", "particle"))
|
||||
colored(MBlocks.ITEM_MONITOR, listOf("0", "particle"))
|
||||
colored(MBlocks.MATTER_RECONSTRUCTOR, listOf("0", "particle"))
|
||||
colored(MBlocks.ENERGY_SERVO, listOf("0", "particle"))
|
||||
|
||||
colored("essence_storage", "_empty", listOf("0"))
|
||||
colored("essence_storage", "_filled", listOf("0"))
|
||||
|
||||
colored("matter_capacitor_bank", listOf("1", "particle"), "mattercapacitorbank_frame")
|
||||
colored("battery_bank", listOf("0", "particle"), "batterybank_frame")
|
||||
|
||||
|
@ -8,6 +8,7 @@ import ru.dbotthepony.mc.otm.block.decorative.CargoCrateBlock
|
||||
import ru.dbotthepony.mc.otm.block.entity.WorkerState
|
||||
import ru.dbotthepony.mc.otm.block.matter.MatterBottlerBlock
|
||||
import ru.dbotthepony.mc.otm.block.tech.AndroidChargerBlock
|
||||
import ru.dbotthepony.mc.otm.block.tech.EssenceStorageBlock
|
||||
import ru.dbotthepony.mc.otm.core.math.BlockRotationFreedom
|
||||
import ru.dbotthepony.mc.otm.core.math.xRotationBlockstateNorth
|
||||
import ru.dbotthepony.mc.otm.core.math.xRotationBlockstateSouth
|
||||
@ -112,7 +113,22 @@ fun addBlockStates(provider: MatteryBlockStateProvider) {
|
||||
provider.block(MBlocks.MATTER_RECONSTRUCTOR.values)
|
||||
provider.block(MBlocks.ENERGY_SERVO.values)
|
||||
provider.block(MBlocks.COBBLESTONE_GENERATOR.values)
|
||||
provider.block(MBlocks.ESSENCE_STORAGE.values)
|
||||
|
||||
provider.exec {
|
||||
for (block in MBlocks.ESSENCE_STORAGE.values) {
|
||||
provider.getVariantBuilder(block).forAllStates {
|
||||
return@forAllStates arrayOf(
|
||||
ConfiguredModel.builder()
|
||||
.modelFile(provider.models().getExistingFile(
|
||||
modLocation("${block.registryName!!.path}_${if (it.getValue(
|
||||
EssenceStorageBlock.FILLED)) "filled" else "empty"}")
|
||||
))
|
||||
.rotationY(it.getValue(BlockRotationFreedom.HORIZONTAL.property).front.yRotationBlockstateNorth())
|
||||
.buildLast()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider.exec {
|
||||
for (crate in MRegistry.CARGO_CRATES.allBlocks.values) {
|
||||
@ -191,5 +207,49 @@ fun addBlockStates(provider: MatteryBlockStateProvider) {
|
||||
part().modelFile(provider.models().getExistingFile(modLocation("storage_cable_core")))
|
||||
.addModel().end()
|
||||
}
|
||||
|
||||
with(provider.getMultipartBuilder(MBlocks.MATTER_CABLE)) {
|
||||
for (dir in BlockRotationFreedom.DIRECTIONAL.possibleValues) {
|
||||
part().modelFile(provider.models().getExistingFile(modLocation("matter_cable_connection")))
|
||||
.rotationX(dir.front.xRotationBlockstateSouth())
|
||||
.rotationY(dir.front.yRotationBlockstateSouth())
|
||||
.addModel()
|
||||
.condition(CableBlock.MAPPING_CONNECTION_PROP[dir.front]!!, true)
|
||||
.end()
|
||||
}
|
||||
|
||||
part().modelFile(provider.models().getExistingFile(modLocation("matter_cable_core")))
|
||||
.addModel().end()
|
||||
}
|
||||
|
||||
with(provider.getMultipartBuilder(MBlocks.STORAGE_CABLE)) {
|
||||
for (dir in BlockRotationFreedom.DIRECTIONAL.possibleValues) {
|
||||
part().modelFile(provider.models().getExistingFile(modLocation("storage_cable_connection")))
|
||||
.rotationX(dir.front.xRotationBlockstateSouth())
|
||||
.rotationY(dir.front.yRotationBlockstateSouth())
|
||||
.addModel()
|
||||
.condition(CableBlock.MAPPING_CONNECTION_PROP[dir.front]!!, true)
|
||||
.end()
|
||||
}
|
||||
|
||||
part().modelFile(provider.models().getExistingFile(modLocation("storage_cable_core")))
|
||||
.addModel().end()
|
||||
}
|
||||
|
||||
for (block in MBlocks.ENERGY_CABLES) {
|
||||
with(provider.getMultipartBuilder(block.value)) {
|
||||
for (dir in BlockRotationFreedom.DIRECTIONAL.possibleValues) {
|
||||
part().modelFile(provider.models().getExistingFile(modLocation("${block.value.registryName!!.path}_connection")))
|
||||
.rotationX(dir.front.xRotationBlockstateSouth())
|
||||
.rotationY(dir.front.yRotationBlockstateSouth())
|
||||
.addModel()
|
||||
.condition(CableBlock.MAPPING_CONNECTION_PROP[dir.front]!!, true)
|
||||
.end()
|
||||
}
|
||||
|
||||
part().modelFile(provider.models().getExistingFile(modLocation("${block.value.registryName!!.path}_core")))
|
||||
.addModel().end()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -172,10 +172,8 @@ fun addItemModels(provider: MatteryItemModelProvider) {
|
||||
provider.coloredWithBaseBlock(MItems.MATTER_SCANNER, "matter_scanner", "_idle")
|
||||
provider.coloredWithBaseBlock(MItems.MATTER_REPLICATOR, "matter_replicator", "_idle")
|
||||
provider.coloredWithBaseBlock(MItems.DRIVE_VIEWER, "drive_viewer", "_idle")
|
||||
provider.block(MItems.MATTER_CABLE, "matter_cable_core")
|
||||
provider.coloredWithBaseBlock(MItems.MATTER_DECOMPOSER, "matter_decomposer", "_idle")
|
||||
provider.coloredWithBaseBlock(MItems.ENERGY_SERVO, "energy_servo")
|
||||
provider.coloredWithBaseBlock(MItems.ESSENCE_STORAGE, "essence_storage")
|
||||
provider.coloredWithBaseBlock(MItems.MATTER_RECONSTRUCTOR, "matter_reconstructor")
|
||||
|
||||
provider.coloredWithBaseBlock(MItems.POWERED_BLAST_FURNACE, "powered_blast_furnace", "_idle")
|
||||
@ -188,10 +186,23 @@ fun addItemModels(provider: MatteryItemModelProvider) {
|
||||
provider.coloredWithBaseBlock(MItems.MATTER_RECYCLER, "matter_recycler", "_idle")
|
||||
provider.coloredWithBaseBlock(MItems.COBBLESTONE_GENERATOR, "cobblestone_generator")
|
||||
|
||||
provider.exec {
|
||||
provider.withExistingParent("essence_storage", modLocation("block/essence_storage_empty"))
|
||||
.override()
|
||||
.predicate(modLocation("is_filled"), 1f)
|
||||
.model(provider.withExistingParent("essence_storage_filled", modLocation("block/essence_storage_filled")))
|
||||
.end()
|
||||
}
|
||||
|
||||
for (dye in DyeColor.entries) {
|
||||
provider.exec {
|
||||
provider.withExistingParent("android_charger_${dye.name.lowercase()}", modLocation("item/android_charger")).texture("0", modLocation("block/android_charger/${dye.name.lowercase()}"))
|
||||
provider.withExistingParent("matter_panel_${dye.name.lowercase()}", modLocation("item/matter_panel")).texture("texture", modLocation("block/matter_panel/${dye.name.lowercase()}"))
|
||||
provider.withExistingParent("essence_storage_${dye.name.lowercase()}", modLocation("block/essence_storage_${dye.name.lowercase()}_empty"))
|
||||
.override()
|
||||
.predicate(modLocation("is_filled"), 1f)
|
||||
.model(provider.withExistingParent("essence_storage_${dye.name.lowercase()}_filled", modLocation("block/essence_storage_${dye.name.lowercase()}_filled")))
|
||||
.end()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -608,8 +608,8 @@ private fun items(provider: MatteryLanguageProvider) {
|
||||
add(MItems.ESSENCE_CAPSULE, "Essence Capsule")
|
||||
add(MItems.ESSENCE_DRIVE, "Essence Memory Holotape")
|
||||
add(MItems.ESSENCE_SERVO, "Essence Servo")
|
||||
add(MItems.ESSENCE_SERVO, "desc", "Allows to 'pump' essence involving fleshy humanoids")
|
||||
add(MItems.ESSENCE_SERVO, "desc2", "Can be used standalone, or as tool inside Essence Servo")
|
||||
add(MItems.ESSENCE_SERVO, "desc", "Allows to absorb nearby experience orbs directly into essence storage")
|
||||
add(MItems.ESSENCE_SERVO, "desc2", "Can be used as a tool to pump essence manually")
|
||||
|
||||
add(MItems.NUTRIENT_PASTE, "Nutrient Paste")
|
||||
|
||||
|
@ -612,8 +612,8 @@ private fun items(provider: MatteryLanguageProvider) {
|
||||
add(MItems.ESSENCE_CAPSULE, "Капсула эссенции")
|
||||
add(MItems.ESSENCE_DRIVE, "Голодиск воспоминаний андроида")
|
||||
add(MItems.ESSENCE_SERVO, "Помпа эссенции")
|
||||
add(MItems.ESSENCE_SERVO, "desc", "Позволяет 'перекачивать' эссенцию гуманоидов из плоти")
|
||||
add(MItems.ESSENCE_SERVO, "desc2", "Может быть использовано напрямую, или как инструмент внутри хранилища эссенции")
|
||||
add(MItems.ESSENCE_SERVO, "desc", "Позволяет всасывать близлежащие сферы опыта напрямую в хранилище эссенции")
|
||||
add(MItems.ESSENCE_SERVO, "desc2", "Может использоваться как инструмент для ручной перекачки эссенции")
|
||||
|
||||
add(MItems.NUTRIENT_PASTE, "Питательная паста")
|
||||
|
||||
|
@ -142,4 +142,17 @@ class MatteryBlockModelProvider(event: GatherDataEvent) : BlockModelProvider(eve
|
||||
colored(modelName, state, textureKeys.associateWith { modelName })
|
||||
}
|
||||
}
|
||||
|
||||
fun cable(modelName: String, textureName: String) {
|
||||
exec {
|
||||
withExistingParent("block/${modelName}_core", modLocation("block/base_cable_core"))
|
||||
.texture("0", textureName)
|
||||
|
||||
withExistingParent("block/${modelName}_connection", modLocation("block/base_cable_connection"))
|
||||
.texture("0", textureName)
|
||||
|
||||
withExistingParent("item/${modelName}", modLocation("item/base_cable"))
|
||||
.texture("0", textureName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,24 @@
|
||||
package ru.dbotthepony.mc.otm.mixin;
|
||||
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import ru.dbotthepony.mc.otm.core.MultiblockKt;
|
||||
|
||||
// because i know
|
||||
// someone
|
||||
// somewhere
|
||||
// will try to break the system
|
||||
// either on purpose or accidentally because of other mod
|
||||
@Mixin(BlockEntity.class)
|
||||
public abstract class BlockEntityMixin {
|
||||
@Inject(
|
||||
at = @At("TAIL"),
|
||||
method = "setRemoved()V"
|
||||
)
|
||||
public void setRemovedListener(CallbackInfo ci) {
|
||||
MultiblockKt.onBlockEntityInvalidated((BlockEntity) (Object) this);
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package ru.dbotthepony.mc.otm.mixin;
|
||||
|
||||
import net.minecraft.client.resources.SplashManager;
|
||||
import net.minecraft.server.packs.resources.ResourceManager;
|
||||
import net.minecraft.util.profiling.ProfilerFiller;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mixin(SplashManager.class)
|
||||
public abstract class SplashManagerMixin {
|
||||
@Shadow
|
||||
public List<String> splashes;
|
||||
|
||||
@Inject(
|
||||
at = @At("TAIL"),
|
||||
method = "apply(Ljava/util/List;Lnet/minecraft/server/packs/resources/ResourceManager;Lnet/minecraft/util/profiling/ProfilerFiller;)V"
|
||||
)
|
||||
public void otmSplashes(List<String> splashes, ResourceManager p_118879_, ProfilerFiller p_118880_, CallbackInfo ci) {
|
||||
this.splashes.add("42 is the answer!");
|
||||
this.splashes.add("Now with matter!");
|
||||
this.splashes.add("Now with four dimensions!");
|
||||
this.splashes.add("Now with more ways to slice Creepers!");
|
||||
this.splashes.add("Batteries not included!");
|
||||
this.splashes.add("As it was 13 nanoseconds ago!");
|
||||
this.splashes.add("Smart AI is smart enough to fail Turing test!");
|
||||
this.splashes.add("Neural computing!");
|
||||
this.splashes.add("Swimming through quantum field!");
|
||||
this.splashes.add("For biological and digital alike!");
|
||||
this.splashes.add("Digital is the next form of Biological!");
|
||||
|
||||
this.splashes.add("Also try Starbound!");
|
||||
this.splashes.add("Also try No Man's Sky!");
|
||||
this.splashes.add("Also try Factorio!");
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package ru.dbotthepony.mc.otm.block
|
||||
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.block.EntityBlock
|
||||
import net.minecraft.world.level.block.entity.BlockEntity
|
||||
import net.minecraft.world.level.block.entity.BlockEntityTicker
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import ru.dbotthepony.mc.otm.block.entity.MultiblockTestBlockEntity
|
||||
|
||||
class MultiblockTestBlock : MatteryBlock(), EntityBlock {
|
||||
override fun newBlockEntity(blockPos: BlockPos, blockState: BlockState): BlockEntity {
|
||||
return MultiblockTestBlockEntity(blockPos, blockState)
|
||||
}
|
||||
|
||||
override fun <T : BlockEntity?> getTicker(level: Level, blockState: BlockState, blockEntityType: BlockEntityType<T>): BlockEntityTicker<T>? {
|
||||
if (level.isClientSide)
|
||||
return null
|
||||
|
||||
return BlockEntityTicker { _, _, _, tile -> if (tile is MultiblockTestBlockEntity) tile.tick() }
|
||||
}
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
package ru.dbotthepony.mc.otm.block.entity
|
||||
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.tags.BlockTags
|
||||
import net.minecraft.world.level.block.Blocks
|
||||
import net.minecraft.world.level.block.entity.BlockEntity
|
||||
import net.minecraft.world.level.block.entity.FurnaceBlockEntity
|
||||
import net.minecraft.world.level.block.entity.HopperBlockEntity
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import ru.dbotthepony.mc.otm.core.multiblockConfiguration
|
||||
import ru.dbotthepony.mc.otm.core.multiblockEntity
|
||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||
import ru.dbotthepony.mc.otm.registry.MBlocks
|
||||
|
||||
class MultiblockTestBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryBlockEntity(MBlockEntities.MULTIBLOCK_TEST, blockPos, blockState) {
|
||||
val config = CONFIG.create(blockPos)
|
||||
|
||||
override fun tick() {
|
||||
super.tick()
|
||||
|
||||
if (config.update(level!!)) {
|
||||
println("It matches!")
|
||||
println("hopper block entities: ${config.blockEntities(HOPPERS)}")
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val HOPPERS = multiblockEntity<HopperBlockEntity>()
|
||||
private val FURNACES = multiblockEntity<FurnaceBlockEntity>()
|
||||
|
||||
val CONFIG = multiblockConfiguration {
|
||||
block(MBlocks.MULTIBLOCK_TEST)
|
||||
|
||||
and {
|
||||
top {
|
||||
or {
|
||||
block(Blocks.HOPPER)
|
||||
block(Blocks.CHEST)
|
||||
block(BlockTags.PLANKS)
|
||||
}
|
||||
|
||||
tag(HOPPERS)
|
||||
}
|
||||
|
||||
left(Blocks.FURNACE) {
|
||||
tag(FURNACES)
|
||||
|
||||
top {
|
||||
or {
|
||||
block(Blocks.HOPPER)
|
||||
block(Blocks.CHEST)
|
||||
block(BlockTags.PLANKS)
|
||||
}
|
||||
|
||||
tag(HOPPERS)
|
||||
}
|
||||
}
|
||||
|
||||
right(Blocks.FURNACE) {
|
||||
tag(FURNACES)
|
||||
|
||||
top {
|
||||
or {
|
||||
block(Blocks.HOPPER)
|
||||
block(Blocks.CHEST)
|
||||
block(BlockTags.PLANKS)
|
||||
}
|
||||
|
||||
tag(HOPPERS)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -66,8 +66,8 @@ class PainterBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryDe
|
||||
}
|
||||
|
||||
override fun fill(resource: FluidStack, action: IFluidHandler.FluidAction): Int {
|
||||
if (resource.isEmpty || resource.fluid != Fluids.WATER || waterStored() >= MAX_WATER_STORAGE) return 0
|
||||
val diff = (waterStored() + resource.amount).coerceAtMost(MAX_WATER_STORAGE) - waterStored()
|
||||
if (resource.amount <= 0 || resource.fluid != Fluids.WATER || waterStored() >= MAX_WATER_STORAGE) return 0
|
||||
val diff = ((waterStored().toLong() + resource.amount.toLong()).coerceAtMost(MAX_WATER_STORAGE.toLong()) - waterStored().toLong()).toInt()
|
||||
if (action.simulate() || diff == 0) return diff
|
||||
dyeStored[null] = waterStored() + diff
|
||||
return diff
|
||||
|
@ -143,8 +143,8 @@ sealed class AbstractPoweredFurnaceBlockEntity<P : AbstractCookingRecipe, S : Ma
|
||||
return JobContainer.success(
|
||||
ItemJob(
|
||||
recipe.getResultItem().copyWithCount(toProcess),
|
||||
recipe.workTime * MachinesConfig.PLATE_PRESS.workTimeMultiplier,
|
||||
MachinesConfig.PLATE_PRESS.energyConsumption * toProcess,
|
||||
recipe.workTime * config.workTimeMultiplier,
|
||||
config.energyConsumption * toProcess,
|
||||
experience = recipe.experience.sample(level.random) * toProcess))
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,31 @@
|
||||
package ru.dbotthepony.mc.otm.block.entity.tech
|
||||
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.sounds.SoundEvents
|
||||
import net.minecraft.sounds.SoundSource
|
||||
import net.minecraft.world.entity.ExperienceOrb
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.enchantment.Enchantments
|
||||
import net.minecraft.world.level.block.Block
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraftforge.fluids.FluidStack
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler
|
||||
import ru.dbotthepony.mc.otm.block.entity.ExperienceStorage.Companion.XP_TO_LIQUID_RATIO
|
||||
import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity
|
||||
import ru.dbotthepony.mc.otm.block.tech.EssenceStorageBlock
|
||||
import ru.dbotthepony.mc.otm.capability.item.CombinedItemHandler
|
||||
import ru.dbotthepony.mc.otm.config.MachinesConfig
|
||||
import ru.dbotthepony.mc.otm.container.HandlerFilter
|
||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||
import ru.dbotthepony.mc.otm.core.getEntitiesInEllipsoid
|
||||
import ru.dbotthepony.mc.otm.core.math.Vector
|
||||
import ru.dbotthepony.mc.otm.core.util.countingLazy
|
||||
import ru.dbotthepony.mc.otm.item.EssenceCapsuleItem
|
||||
import ru.dbotthepony.mc.otm.item.EssenceServoItem
|
||||
import ru.dbotthepony.mc.otm.menu.tech.EssenceStorageMenu
|
||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||
import ru.dbotthepony.mc.otm.registry.MFluids
|
||||
@ -119,6 +130,14 @@ class EssenceStorageBlockEntity(blockPos: BlockPos, blockState: BlockState) : Ma
|
||||
return FluidStack(MFluids.LIQUID_XP, actualDrain)
|
||||
}
|
||||
|
||||
private val hasFillState by countingLazy(blockStateChangesCounter) {
|
||||
this.blockState.hasProperty(EssenceStorageBlock.FILLED)
|
||||
}
|
||||
|
||||
private val isFilledState by countingLazy(blockStateChangesCounter) {
|
||||
hasFillState && this.blockState.getValue(EssenceStorageBlock.FILLED)
|
||||
}
|
||||
|
||||
override fun tick() {
|
||||
super.tick()
|
||||
|
||||
@ -146,6 +165,45 @@ class EssenceStorageBlockEntity(blockPos: BlockPos, blockState: BlockState) : Ma
|
||||
repairStack.damageValue -= repairPoints
|
||||
}
|
||||
}
|
||||
|
||||
val servo = servoContainer[0]
|
||||
|
||||
if (!servo.isEmpty && servo.item is EssenceServoItem && level is ServerLevel) {
|
||||
val entities = level!!.getEntitiesInEllipsoid(
|
||||
blockPos.center,
|
||||
Vector(
|
||||
MachinesConfig.EssenceStorage.RADIUS_HORIZONTAL,
|
||||
MachinesConfig.EssenceStorage.RADIUS_VERTICAL,
|
||||
MachinesConfig.EssenceStorage.RADIUS_HORIZONTAL
|
||||
)
|
||||
) { it is ExperienceOrb }
|
||||
|
||||
for ((ent, _) in entities) {
|
||||
ent as ExperienceOrb
|
||||
|
||||
for (i in 1 .. ent.count) {
|
||||
experienceStored += ent.value
|
||||
ent.count--
|
||||
|
||||
level!!.playSound(null, ent.x, ent.y, ent.z,
|
||||
SoundEvents.EXPERIENCE_ORB_PICKUP, SoundSource.BLOCKS,
|
||||
0.1F, 0.5F + level!!.random.nextFloat() * 0.25F
|
||||
)
|
||||
}
|
||||
|
||||
if (ent.count <= 0) {
|
||||
ent.discard()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasFillState) {
|
||||
val filled = experienceStored > 0
|
||||
|
||||
if (isFilledState != filled) {
|
||||
level?.setBlock(blockPos, blockState.setValue(EssenceStorageBlock.FILLED, filled), Block.UPDATE_CLIENTS)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,11 +9,14 @@ import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.item.DyeColor
|
||||
import net.minecraft.world.level.BlockGetter
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.block.Block
|
||||
import net.minecraft.world.level.block.EntityBlock
|
||||
import net.minecraft.world.level.block.entity.BlockEntity
|
||||
import net.minecraft.world.level.block.entity.BlockEntityTicker
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraft.world.level.block.state.StateDefinition
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty
|
||||
import net.minecraft.world.level.material.Material
|
||||
import net.minecraft.world.level.material.PushReaction
|
||||
import net.minecraft.world.phys.BlockHitResult
|
||||
@ -44,6 +47,8 @@ class EssenceStorageBlock(val color: DyeColor?) : RotatableMatteryBlock(Properti
|
||||
acceptor(TranslatableComponent("otm.gui.experience_levels", getLevelFromXp(l.asLong)).withStyle(ChatFormatting.GRAY))
|
||||
}
|
||||
}
|
||||
|
||||
registerDefaultState(getStateDefinition().any().setValue(FILLED, false))
|
||||
}
|
||||
override fun newBlockEntity(pPos: BlockPos, pState: BlockState): BlockEntity {
|
||||
return EssenceStorageBlockEntity(pPos, pState)
|
||||
@ -70,6 +75,11 @@ class EssenceStorageBlock(val color: DyeColor?) : RotatableMatteryBlock(Properti
|
||||
return PushReaction.BLOCK
|
||||
}
|
||||
|
||||
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
|
||||
super.createBlockStateDefinition(builder)
|
||||
builder.add(FILLED)
|
||||
}
|
||||
|
||||
private val shapes = getShapeForEachState(rotationProperty) { BlockShapes.ESSENCE_STORAGE.rotateFromNorth(it[rotationProperty]).computeShape() }
|
||||
|
||||
@Suppress("override_deprecation")
|
||||
@ -81,4 +91,8 @@ class EssenceStorageBlock(val color: DyeColor?) : RotatableMatteryBlock(Properti
|
||||
): VoxelShape {
|
||||
return shapes[state]!!
|
||||
}
|
||||
|
||||
companion object {
|
||||
val FILLED = BooleanProperty.create("filled")
|
||||
}
|
||||
}
|
||||
|
@ -157,8 +157,8 @@ object Widgets18 {
|
||||
}
|
||||
}
|
||||
|
||||
val LEFT_CONTROLS = SideControls()
|
||||
val RIGHT_CONTROLS = SideControls()
|
||||
val LEFT_CONTROLS = SideControls()
|
||||
val TOP_CONTROLS = SideControls()
|
||||
val BOTTOM_CONTROLS = SideControls()
|
||||
val FRONT_CONTROLS = SideControls()
|
||||
|
@ -219,7 +219,21 @@ object MachinesConfig : AbstractConfig("machines") {
|
||||
}
|
||||
}
|
||||
|
||||
object EssenceStorage {
|
||||
init {
|
||||
builder.push(MNames.ESSENCE_STORAGE)
|
||||
}
|
||||
|
||||
val RADIUS_HORIZONTAL: Double by builder.defineInRange("RADIUS_HORIZONTAL", 5.0, 0.0, Double.MAX_VALUE / 4.0)
|
||||
val RADIUS_VERTICAL: Double by builder.defineInRange("RADIUS_VERTICAL", 2.0, 0.0, Double.MAX_VALUE / 4.0)
|
||||
|
||||
init {
|
||||
builder.pop()
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
Upgrades
|
||||
EssenceStorage
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ import net.minecraft.world.item.ItemStack
|
||||
import ru.dbotthepony.mc.otm.container.util.IContainerSlot
|
||||
import ru.dbotthepony.mc.otm.container.util.containerSlot
|
||||
import ru.dbotthepony.mc.otm.container.util.iterator
|
||||
import ru.dbotthepony.mc.otm.container.util.slotIterator
|
||||
import ru.dbotthepony.mc.otm.core.collect.concatIterators
|
||||
import ru.dbotthepony.mc.otm.core.collect.filter
|
||||
import ru.dbotthepony.mc.otm.core.collect.flatMap
|
||||
@ -154,6 +155,9 @@ class CombinedContainer(containers: Stream<Pair<Container, Iterable<Int>>>) : IM
|
||||
}
|
||||
|
||||
override fun iterator(nonEmpty: Boolean): Iterator<ItemStack> {
|
||||
if (notFullCoverage.isEmpty())
|
||||
return fullCoverage.iterator().flatMap { it.iterator(nonEmpty) }
|
||||
|
||||
return concatIterators(
|
||||
fullCoverage.iterator().flatMap { it.iterator(nonEmpty) },
|
||||
notFullCoverage.values.iterator().flatMap { it.iterator() }.map { it.item }.let { if (nonEmpty) it.filter { it.isNotEmpty } else it }
|
||||
|
@ -66,6 +66,44 @@ interface ISubscriptable<V> {
|
||||
}
|
||||
}
|
||||
|
||||
interface IUnitSubscripable : ISubscriptable<Unit> {
|
||||
fun addListener(listener: Runnable): ISubscriptable.L
|
||||
|
||||
override fun addListener(listener: Consumer<Unit>): ISubscriptable.L {
|
||||
return addListener(Runnable { listener.accept(Unit) })
|
||||
}
|
||||
|
||||
class Impl : IUnitSubscripable, Runnable {
|
||||
private inner class L(val callback: Runnable) : ISubscriptable.L {
|
||||
private var isRemoved = false
|
||||
|
||||
init {
|
||||
subscribers.add(this)
|
||||
}
|
||||
|
||||
override fun remove() {
|
||||
if (!isRemoved) {
|
||||
isRemoved = true
|
||||
queue.add(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val subscribers = ReferenceLinkedOpenHashSet<L>(0)
|
||||
private val queue = ReferenceArraySet<L>(0)
|
||||
|
||||
override fun addListener(listener: Runnable): ISubscriptable.L {
|
||||
return L(listener)
|
||||
}
|
||||
|
||||
override fun run() {
|
||||
queue.forEach { subscribers.remove(it) }
|
||||
queue.clear()
|
||||
subscribers.forEach { it.callback.run() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface IFloatSubcripable : ISubscriptable<Float> {
|
||||
@Deprecated("Use type specific listener")
|
||||
override fun addListener(listener: Consumer<Float>): ISubscriptable.L {
|
||||
|
681
src/main/kotlin/ru/dbotthepony/mc/otm/core/Multiblock.kt
Normal file
681
src/main/kotlin/ru/dbotthepony/mc/otm/core/Multiblock.kt
Normal file
@ -0,0 +1,681 @@
|
||||
package ru.dbotthepony.mc.otm.core
|
||||
|
||||
import com.google.common.collect.ImmutableList
|
||||
import com.google.common.collect.ImmutableSet
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectFunction
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArraySet
|
||||
import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.Direction
|
||||
import net.minecraft.core.Vec3i
|
||||
import net.minecraft.tags.TagKey
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.LevelAccessor
|
||||
import net.minecraft.world.level.block.Block
|
||||
import net.minecraft.world.level.block.Rotation
|
||||
import net.minecraft.world.level.block.entity.BlockEntity
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import ru.dbotthepony.mc.otm.core.collect.WeakHashSet
|
||||
import ru.dbotthepony.mc.otm.core.collect.collect
|
||||
import ru.dbotthepony.mc.otm.core.collect.map
|
||||
import ru.dbotthepony.mc.otm.core.math.RelativeSide
|
||||
import ru.dbotthepony.mc.otm.core.math.plus
|
||||
import java.util.Collections
|
||||
import java.util.WeakHashMap
|
||||
import java.util.function.Predicate
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
private val blockEntityListeners = WeakHashMap<Level, WeakHashMap<BlockEntity, WeakHashSet<Multiblock>>>()
|
||||
|
||||
fun onBlockEntityInvalidated(blockEntity: BlockEntity) {
|
||||
blockEntityListeners[blockEntity.level]?.get(blockEntity)?.forEach { it.blockEntityRemoved(blockEntity) }
|
||||
blockEntityListeners[blockEntity.level]?.remove(blockEntity)
|
||||
}
|
||||
|
||||
fun interface BlockPredicate {
|
||||
fun test(pos: BlockPos, access: LevelAccessor): Boolean
|
||||
|
||||
fun and(other: BlockPredicate): BlockPredicate {
|
||||
return BlockPredicate { pos, access -> test(pos, access) && other.test(pos, access) }
|
||||
}
|
||||
|
||||
fun or(other: BlockPredicate): BlockPredicate {
|
||||
return BlockPredicate { pos, access -> test(pos, access) || other.test(pos, access) }
|
||||
}
|
||||
|
||||
fun offset(offset: BlockPos): Positioned {
|
||||
return Positioned(offset, this)
|
||||
}
|
||||
|
||||
fun offset(offset: Vec3i): Positioned {
|
||||
return offset(BlockPos(offset))
|
||||
}
|
||||
|
||||
data class Positioned(val offset: BlockPos, val parent: BlockPredicate) : BlockPredicate {
|
||||
override fun test(pos: BlockPos, access: LevelAccessor): Boolean {
|
||||
return parent.test(offset + pos, access)
|
||||
}
|
||||
|
||||
override fun offset(offset: BlockPos): Positioned {
|
||||
return Positioned(this.offset + offset, parent)
|
||||
}
|
||||
}
|
||||
|
||||
data class And(val nodes: ImmutableSet<BlockPredicate>) : BlockPredicate {
|
||||
constructor(vararg nodes: BlockPredicate) : this(ImmutableSet.copyOf(nodes))
|
||||
constructor(nodes: Set<BlockPredicate>) : this(ImmutableSet.copyOf(nodes))
|
||||
|
||||
override fun test(pos: BlockPos, access: LevelAccessor): Boolean {
|
||||
return nodes.all { it.test(pos, access) }
|
||||
}
|
||||
}
|
||||
|
||||
data class Or(val nodes: ImmutableSet<BlockPredicate>) : BlockPredicate {
|
||||
constructor(vararg nodes: BlockPredicate) : this(ImmutableSet.copyOf(nodes))
|
||||
constructor(nodes: Set<BlockPredicate>) : this(ImmutableSet.copyOf(nodes))
|
||||
|
||||
override fun test(pos: BlockPos, access: LevelAccessor): Boolean {
|
||||
return nodes.any { it.test(pos, access) }
|
||||
}
|
||||
}
|
||||
|
||||
object Air : BlockPredicate {
|
||||
override fun test(pos: BlockPos, access: LevelAccessor): Boolean {
|
||||
return access.isEmptyBlock(pos)
|
||||
}
|
||||
}
|
||||
|
||||
object NotAir : BlockPredicate {
|
||||
override fun test(pos: BlockPos, access: LevelAccessor): Boolean {
|
||||
return !access.isEmptyBlock(pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline fun multiblockConfiguration(configurator: MultiblockBuilder.Node.() -> Unit): MultiblockFactory {
|
||||
val builder = MultiblockBuilder()
|
||||
configurator.invoke(builder.root())
|
||||
return builder.build()
|
||||
}
|
||||
|
||||
inline fun <reified T : BlockEntity> multiblockEntity(): MultiblockBuilder.EntityTag<T> {
|
||||
return MultiblockBuilder.EntityTag(T::class)
|
||||
}
|
||||
|
||||
class MultiblockBuilder {
|
||||
private val nodes = Object2ObjectOpenHashMap<BlockPos, Node>()
|
||||
|
||||
// not data classes to allow having multiple tags with same target
|
||||
class EntityTag<T : BlockEntity>(val clazz: KClass<T>) : Predicate<BlockEntity> {
|
||||
override fun test(t: BlockEntity): Boolean {
|
||||
return clazz.isInstance(t)
|
||||
}
|
||||
}
|
||||
|
||||
enum class Strategy {
|
||||
OR, AND
|
||||
}
|
||||
|
||||
@Suppress("unchecked_cast")
|
||||
abstract class BlockPredicates<T : BlockPredicates<T>> {
|
||||
val predicates = ObjectArraySet<BlockPredicate>()
|
||||
val children = ObjectArraySet<BlockPredicates<*>>()
|
||||
|
||||
val blockStateTags = ObjectArraySet<Any>()
|
||||
val blockTags = ObjectArraySet<Any>()
|
||||
val blockEntityTags = ObjectArraySet<EntityTag<*>>()
|
||||
|
||||
fun tagBlockState(value: Any): T {
|
||||
blockStateTags.add(value)
|
||||
return this as T
|
||||
}
|
||||
|
||||
fun tagBlock(value: Any): T {
|
||||
blockTags.add(value)
|
||||
return this as T
|
||||
}
|
||||
|
||||
fun tag(value: EntityTag<*>): T {
|
||||
blockEntityTags.add(value)
|
||||
return this as T
|
||||
}
|
||||
|
||||
fun clear(): T {
|
||||
predicates.clear()
|
||||
return this as T
|
||||
}
|
||||
|
||||
fun predicate(predicate: BlockPredicate): T {
|
||||
predicates.add(predicate)
|
||||
return this as T
|
||||
}
|
||||
|
||||
fun block(block: Block): T {
|
||||
predicates.add { pos, access -> access.getBlockState(pos).`is`(block) }
|
||||
return this as T
|
||||
}
|
||||
|
||||
fun block(block: TagKey<Block>): T {
|
||||
predicates.add { pos, access -> access.getBlockState(pos).`is`(block) }
|
||||
return this as T
|
||||
}
|
||||
|
||||
fun air(): T {
|
||||
predicate(BlockPredicate.Air)
|
||||
return this as T
|
||||
}
|
||||
|
||||
fun block(state: BlockState): T {
|
||||
predicates.add { pos, access -> access.getBlockState(pos) == state }
|
||||
return this as T
|
||||
}
|
||||
|
||||
fun and(): And<T> {
|
||||
return And(this as T)
|
||||
}
|
||||
|
||||
fun or(): Or<T> {
|
||||
return Or(this as T)
|
||||
}
|
||||
|
||||
fun and(configurator: And<T>.() -> Unit): And<T> {
|
||||
return And(this as T).also(configurator)
|
||||
}
|
||||
|
||||
fun or(configurator: Or<T>.() -> Unit): Or<T> {
|
||||
return Or(this as T).also(configurator)
|
||||
}
|
||||
|
||||
protected fun build(pos: BlockPos): MultiblockFactory.Part {
|
||||
return MultiblockFactory.Part(
|
||||
pos, strategy, ImmutableList.copyOf(predicates),
|
||||
children.stream().map { it.build(pos) }.collect(ImmutableList.toImmutableList()),
|
||||
ImmutableSet.copyOf(blockStateTags),
|
||||
ImmutableSet.copyOf(blockTags),
|
||||
ImmutableSet.copyOf(blockEntityTags),
|
||||
)
|
||||
}
|
||||
|
||||
abstract val strategy: Strategy
|
||||
}
|
||||
|
||||
class And<P : BlockPredicates<P>>(val parent: P) : BlockPredicates<And<P>>() {
|
||||
init {
|
||||
parent.children.add(this)
|
||||
}
|
||||
|
||||
fun end() = parent
|
||||
|
||||
override val strategy: Strategy
|
||||
get() = Strategy.AND
|
||||
}
|
||||
|
||||
class Or<P : BlockPredicates<P>>(val parent: P) : BlockPredicates<Or<P>>() {
|
||||
init {
|
||||
parent.children.add(this)
|
||||
}
|
||||
|
||||
fun end() = parent
|
||||
|
||||
override val strategy: Strategy
|
||||
get() = Strategy.OR
|
||||
}
|
||||
|
||||
/**
|
||||
* Behaves as if being [Or] node
|
||||
*/
|
||||
inner class Node(val pos: BlockPos) : BlockPredicates<Node>() {
|
||||
init {
|
||||
check(nodes.put(pos, this) == null) { "Trying to create new node at $pos while already having one" }
|
||||
}
|
||||
|
||||
fun relative(diff: Vec3i): Node {
|
||||
return node(pos + diff)
|
||||
}
|
||||
|
||||
fun relative(dir: Direction): Node {
|
||||
return relative(dir.normal)
|
||||
}
|
||||
|
||||
fun relative(dir: RelativeSide): Node {
|
||||
return relative(dir.default)
|
||||
}
|
||||
|
||||
fun front() = relative(RelativeSide.FRONT)
|
||||
fun back() = relative(RelativeSide.BACK)
|
||||
fun left() = relative(RelativeSide.LEFT)
|
||||
fun right() = relative(RelativeSide.RIGHT)
|
||||
fun top() = relative(RelativeSide.TOP)
|
||||
fun bottom() = relative(RelativeSide.BOTTOM)
|
||||
|
||||
fun front(block: Block) = relative(RelativeSide.FRONT).also { it.block(block) }
|
||||
fun back(block: Block) = relative(RelativeSide.BACK).also { it.block(block) }
|
||||
fun left(block: Block) = relative(RelativeSide.LEFT).also { it.block(block) }
|
||||
fun right(block: Block) = relative(RelativeSide.RIGHT).also { it.block(block) }
|
||||
fun top(block: Block) = relative(RelativeSide.TOP).also { it.block(block) }
|
||||
fun bottom(block: Block) = relative(RelativeSide.BOTTOM).also { it.block(block) }
|
||||
|
||||
fun front(block: BlockState) = relative(RelativeSide.FRONT).also { it.block(block) }
|
||||
fun back(block: BlockState) = relative(RelativeSide.BACK).also { it.block(block) }
|
||||
fun left(block: BlockState) = relative(RelativeSide.LEFT).also { it.block(block) }
|
||||
fun right(block: BlockState) = relative(RelativeSide.RIGHT).also { it.block(block) }
|
||||
fun top(block: BlockState) = relative(RelativeSide.TOP).also { it.block(block) }
|
||||
fun bottom(block: BlockState) = relative(RelativeSide.BOTTOM).also { it.block(block) }
|
||||
|
||||
fun front(predicate: BlockPredicate) = relative(RelativeSide.FRONT).also { it.predicate(predicate) }
|
||||
fun back(predicate: BlockPredicate) = relative(RelativeSide.BACK).also { it.predicate(predicate) }
|
||||
fun left(predicate: BlockPredicate) = relative(RelativeSide.LEFT).also { it.predicate(predicate) }
|
||||
fun right(predicate: BlockPredicate) = relative(RelativeSide.RIGHT).also { it.predicate(predicate) }
|
||||
fun top(predicate: BlockPredicate) = relative(RelativeSide.TOP).also { it.predicate(predicate) }
|
||||
fun bottom(predicate: BlockPredicate) = relative(RelativeSide.BOTTOM).also { it.predicate(predicate) }
|
||||
|
||||
fun front(configurator: Node.() -> Unit) = relative(RelativeSide.FRONT).also(configurator)
|
||||
fun back(configurator: Node.() -> Unit) = relative(RelativeSide.BACK).also(configurator)
|
||||
fun left(configurator: Node.() -> Unit) = relative(RelativeSide.LEFT).also(configurator)
|
||||
fun right(configurator: Node.() -> Unit) = relative(RelativeSide.RIGHT).also(configurator)
|
||||
fun top(configurator: Node.() -> Unit) = relative(RelativeSide.TOP).also(configurator)
|
||||
fun bottom(configurator: Node.() -> Unit) = relative(RelativeSide.BOTTOM).also(configurator)
|
||||
|
||||
fun front(block: Block, configurator: Node.() -> Unit) = relative(RelativeSide.FRONT).also { it.block(block) }.also(configurator)
|
||||
fun back(block: Block, configurator: Node.() -> Unit) = relative(RelativeSide.BACK).also { it.block(block) }.also(configurator)
|
||||
fun left(block: Block, configurator: Node.() -> Unit) = relative(RelativeSide.LEFT).also { it.block(block) }.also(configurator)
|
||||
fun right(block: Block, configurator: Node.() -> Unit) = relative(RelativeSide.RIGHT).also { it.block(block) }.also(configurator)
|
||||
fun top(block: Block, configurator: Node.() -> Unit) = relative(RelativeSide.TOP).also { it.block(block) }.also(configurator)
|
||||
fun bottom(block: Block, configurator: Node.() -> Unit) = relative(RelativeSide.BOTTOM).also { it.block(block) }.also(configurator)
|
||||
|
||||
fun front(block: BlockState, configurator: Node.() -> Unit) = relative(RelativeSide.FRONT).also { it.block(block) }.also(configurator)
|
||||
fun back(block: BlockState, configurator: Node.() -> Unit) = relative(RelativeSide.BACK).also { it.block(block) }.also(configurator)
|
||||
fun left(block: BlockState, configurator: Node.() -> Unit) = relative(RelativeSide.LEFT).also { it.block(block) }.also(configurator)
|
||||
fun right(block: BlockState, configurator: Node.() -> Unit) = relative(RelativeSide.RIGHT).also { it.block(block) }.also(configurator)
|
||||
fun top(block: BlockState, configurator: Node.() -> Unit) = relative(RelativeSide.TOP).also { it.block(block) }.also(configurator)
|
||||
fun bottom(block: BlockState, configurator: Node.() -> Unit) = relative(RelativeSide.BOTTOM).also { it.block(block) }.also(configurator)
|
||||
|
||||
fun front(predicate: BlockPredicate, configurator: Node.() -> Unit) = relative(RelativeSide.FRONT).also { it.predicate(predicate) }.also(configurator)
|
||||
fun back(predicate: BlockPredicate, configurator: Node.() -> Unit) = relative(RelativeSide.BACK).also { it.predicate(predicate) }.also(configurator)
|
||||
fun left(predicate: BlockPredicate, configurator: Node.() -> Unit) = relative(RelativeSide.LEFT).also { it.predicate(predicate) }.also(configurator)
|
||||
fun right(predicate: BlockPredicate, configurator: Node.() -> Unit) = relative(RelativeSide.RIGHT).also { it.predicate(predicate) }.also(configurator)
|
||||
fun top(predicate: BlockPredicate, configurator: Node.() -> Unit) = relative(RelativeSide.TOP).also { it.predicate(predicate) }.also(configurator)
|
||||
fun bottom(predicate: BlockPredicate, configurator: Node.() -> Unit) = relative(RelativeSide.BOTTOM).also { it.predicate(predicate) }.also(configurator)
|
||||
|
||||
fun build(): MultiblockFactory.Part {
|
||||
return build(pos)
|
||||
}
|
||||
|
||||
override var strategy: Strategy = Strategy.OR
|
||||
}
|
||||
|
||||
fun node(at: BlockPos): Node {
|
||||
return nodes[at] ?: Node(at)
|
||||
}
|
||||
|
||||
fun root() = node(BlockPos.ZERO)
|
||||
fun root(configurator: Node.() -> Unit) = node(BlockPos.ZERO).also(configurator)
|
||||
|
||||
fun copy(): MultiblockBuilder {
|
||||
val copied = MultiblockBuilder()
|
||||
|
||||
for ((k, v) in nodes) {
|
||||
val node = copied.Node(k)
|
||||
copied.nodes[k] = node
|
||||
node.predicates.addAll(v.predicates)
|
||||
}
|
||||
|
||||
return copied
|
||||
}
|
||||
|
||||
fun build(): MultiblockFactory {
|
||||
return MultiblockFactory(nodes.values.iterator().map { it.build() }.collect(ImmutableSet.toImmutableSet()))
|
||||
}
|
||||
}
|
||||
|
||||
class MultiblockFactory(val north: ImmutableSet<Part>) {
|
||||
data class Part(
|
||||
val pos: BlockPos,
|
||||
val strategy: MultiblockBuilder.Strategy,
|
||||
val predicate: ImmutableList<BlockPredicate>,
|
||||
val children: ImmutableList<Part>,
|
||||
val blockStateTags: ImmutableSet<Any>,
|
||||
val blockTags: ImmutableSet<Any>,
|
||||
val blockEntityTags: ImmutableSet<MultiblockBuilder.EntityTag<*>>,
|
||||
)
|
||||
|
||||
fun create(pos: BlockPos): Multiblock {
|
||||
return Multiblock(
|
||||
pos,
|
||||
north,
|
||||
south,
|
||||
west,
|
||||
east,
|
||||
)
|
||||
}
|
||||
|
||||
val south: ImmutableSet<Part> = north.iterator().map { it.copy(pos = it.pos.rotate(Rotation.CLOCKWISE_180)) }.collect(ImmutableSet.toImmutableSet())
|
||||
val west: ImmutableSet<Part> = north.iterator().map { it.copy(pos = it.pos.rotate(Rotation.COUNTERCLOCKWISE_90)) }.collect(ImmutableSet.toImmutableSet())
|
||||
val east: ImmutableSet<Part> = north.iterator().map { it.copy(pos = it.pos.rotate(Rotation.CLOCKWISE_90)) }.collect(ImmutableSet.toImmutableSet())
|
||||
}
|
||||
|
||||
class Multiblock(
|
||||
pos: BlockPos,
|
||||
north: Collection<MultiblockFactory.Part>,
|
||||
south: Collection<MultiblockFactory.Part>,
|
||||
west: Collection<MultiblockFactory.Part>,
|
||||
east: Collection<MultiblockFactory.Part>,
|
||||
) {
|
||||
var isValid = false
|
||||
private set
|
||||
|
||||
private val configurations = ArrayList<Config>()
|
||||
|
||||
private inner class BEList<T : BlockEntity>(val tag: MultiblockBuilder.EntityTag<T>) {
|
||||
val list = ArrayList<T>()
|
||||
val set = ObjectArraySet<T>()
|
||||
val setView: Set<T> = Collections.unmodifiableSet(set)
|
||||
|
||||
fun add(blockEntity: BlockEntity) {
|
||||
if (tag.test(blockEntity)) {
|
||||
if (set.add(blockEntity as T)) {
|
||||
blockEntityListeners
|
||||
.computeIfAbsent(blockEntity.level) { WeakHashMap() }
|
||||
.computeIfAbsent(blockEntity) { WeakHashSet() }
|
||||
.add(this@Multiblock)
|
||||
}
|
||||
|
||||
list.add(blockEntity)
|
||||
}
|
||||
}
|
||||
|
||||
fun remove(blockEntity: BlockEntity) {
|
||||
if (tag.test(blockEntity)) {
|
||||
check(list.remove(blockEntity as T)) { "Unable to remove $blockEntity from tag $tag" }
|
||||
|
||||
if (blockEntity !in list) {
|
||||
set.remove(blockEntity)
|
||||
|
||||
val getSet = blockEntityListeners[blockEntity.level]?.get(blockEntity)
|
||||
|
||||
if (getSet != null) {
|
||||
getSet.remove(this@Multiblock)
|
||||
|
||||
if (getSet.isEmpty()) {
|
||||
blockEntityListeners[blockEntity.level]?.remove(blockEntity)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun blockEntityRemoved(blockEntity: BlockEntity): Boolean {
|
||||
if (blockEntity in list) {
|
||||
while (list.remove(blockEntity)) {}
|
||||
set.remove(blockEntity)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
set.forEach {
|
||||
val getSet = checkNotNull(blockEntityListeners[it.level]) { "Consistency check failed: No subscriber lists for level ${it.level}" }.get(it)
|
||||
checkNotNull(getSet) { "Consistency check failed: No subscriber list for $it" }
|
||||
check(getSet.remove(this@Multiblock)) { "Consistency check failed: Can't remove ${this@Multiblock} from $it subscriber list" }
|
||||
|
||||
if (getSet.isEmpty()) {
|
||||
blockEntityListeners[it.level]?.remove(it)
|
||||
}
|
||||
}
|
||||
|
||||
list.clear()
|
||||
set.clear()
|
||||
}
|
||||
}
|
||||
|
||||
private inner class Config(val pos: BlockPos, parts: Collection<MultiblockFactory.Part>) {
|
||||
private inner class Part(val pos: BlockPos, val prototype: MultiblockFactory.Part) {
|
||||
private var blockEntity: BlockEntity? = null
|
||||
private var blockState: BlockState? = null
|
||||
private val assignedBlockEntityLists = ArrayList<BEList<*>>(prototype.blockEntityTags.size)
|
||||
private val assignedBlockStateLists = ArrayList<Reference2IntOpenHashMap<BlockState>>()
|
||||
private val assignedBlockLists = ArrayList<Object2IntOpenHashMap<Block>>()
|
||||
private val children: ImmutableList<Part> = prototype.children.stream().map { Part(pos, it) }.collect(ImmutableList.toImmutableList())
|
||||
|
||||
init {
|
||||
prototype.blockEntityTags.forEach {
|
||||
assignedBlockEntityLists.add(tag2BlockEntity.computeIfAbsent(it, Object2ObjectFunction { _ -> BEList(it as MultiblockBuilder.EntityTag<BlockEntity>).also { blockEntityLists.add(it) } }))
|
||||
}
|
||||
|
||||
prototype.blockStateTags.forEach {
|
||||
assignedBlockStateLists.add(tag2BlockState.computeIfAbsent(it, Object2ObjectFunction { Reference2IntOpenHashMap<BlockState>().also { blockStateLists.add(it) } }))
|
||||
}
|
||||
|
||||
prototype.blockTags.forEach {
|
||||
assignedBlockLists.add(tag2Block.computeIfAbsent(it, Object2ObjectFunction { Object2IntOpenHashMap<Block>().also { blockLists.add(it) } }))
|
||||
}
|
||||
}
|
||||
|
||||
private var lastSuccessfulPathPredicate = -1
|
||||
private var lastSuccessfulPathChildren = -1
|
||||
|
||||
fun test(levelAccessor: LevelAccessor): Boolean {
|
||||
val test = when (prototype.strategy) {
|
||||
MultiblockBuilder.Strategy.OR -> {
|
||||
var status = true
|
||||
|
||||
if (prototype.predicate.isNotEmpty()) {
|
||||
if (lastSuccessfulPathPredicate != -1 && !prototype.predicate[lastSuccessfulPathPredicate].test(pos, levelAccessor)) {
|
||||
lastSuccessfulPathPredicate = -1
|
||||
}
|
||||
|
||||
if (lastSuccessfulPathPredicate == -1) {
|
||||
lastSuccessfulPathPredicate = prototype.predicate.indexOfFirst { it.test(pos, levelAccessor) }
|
||||
status = lastSuccessfulPathPredicate != -1
|
||||
}
|
||||
}
|
||||
|
||||
if (status && children.isNotEmpty()) {
|
||||
if (lastSuccessfulPathChildren != -1 && !children[lastSuccessfulPathChildren].test(levelAccessor)) {
|
||||
lastSuccessfulPathChildren = -1
|
||||
}
|
||||
|
||||
if (lastSuccessfulPathChildren == -1) {
|
||||
lastSuccessfulPathChildren = children.indexOfFirst { it.test(levelAccessor) }
|
||||
status = lastSuccessfulPathChildren != -1
|
||||
}
|
||||
}
|
||||
|
||||
status
|
||||
}
|
||||
|
||||
MultiblockBuilder.Strategy.AND -> prototype.predicate.all { it.test(pos, levelAccessor) } && children.all { it.test(levelAccessor) }
|
||||
}
|
||||
|
||||
if (test) {
|
||||
if (assignedBlockEntityLists.isNotEmpty()) {
|
||||
val be1 = blockEntity
|
||||
val be2 = levelAccessor.getBlockEntity(pos)
|
||||
|
||||
if (be1 != be2) {
|
||||
if (be1 != null) {
|
||||
assignedBlockEntityLists.forEach { it.remove(be1) }
|
||||
}
|
||||
|
||||
if (be2 != null) {
|
||||
assignedBlockEntityLists.forEach { it.add(be2) }
|
||||
}
|
||||
|
||||
blockEntity = be2
|
||||
}
|
||||
}
|
||||
|
||||
if (assignedBlockStateLists.isNotEmpty() || assignedBlockLists.isNotEmpty()) {
|
||||
val state = levelAccessor.getBlockState(pos)
|
||||
val old = blockState
|
||||
|
||||
if (state != old) {
|
||||
if (old != null) {
|
||||
assignedBlockStateLists.forEach {
|
||||
it[old] = it.getInt(old) - 1
|
||||
check(it.getInt(old) >= 0) { "Consistency check failed: Counter for block state $old turned negative" }
|
||||
}
|
||||
|
||||
assignedBlockLists.forEach {
|
||||
it[old.block] = it.getInt(old.block) - 1
|
||||
check(it.getInt(old.block) >= 0) { "Consistency check failed: Counter for block ${old.block.registryName} turned negative" }
|
||||
}
|
||||
}
|
||||
|
||||
assignedBlockStateLists.forEach {
|
||||
it[state] = it.getInt(state) + 1
|
||||
}
|
||||
|
||||
assignedBlockLists.forEach {
|
||||
it[state.block] = it.getInt(state.block) + 1
|
||||
}
|
||||
|
||||
blockState = state
|
||||
}
|
||||
}
|
||||
} else {
|
||||
clearFull()
|
||||
}
|
||||
|
||||
return test
|
||||
}
|
||||
|
||||
private fun clearFull() {
|
||||
val blockEntity = blockEntity
|
||||
|
||||
if (blockEntity != null) {
|
||||
assignedBlockEntityLists.forEach { it.remove(blockEntity) }
|
||||
}
|
||||
|
||||
val blockState = blockState
|
||||
|
||||
if (blockState != null) {
|
||||
assignedBlockStateLists.forEach {
|
||||
it[blockState] = it.getInt(blockState) - 1
|
||||
check(it.getInt(blockState) >= 0) { "Consistency check failed: Counter for block state $blockState turned negative" }
|
||||
}
|
||||
|
||||
assignedBlockLists.forEach {
|
||||
it[blockState.block] = it.getInt(blockState.block) - 1
|
||||
check(it.getInt(blockState.block) >= 0) { "Consistency check failed: Counter for block ${blockState.block.registryName} turned negative" }
|
||||
}
|
||||
}
|
||||
|
||||
this.blockEntity = null
|
||||
this.blockState = null
|
||||
|
||||
lastSuccessfulPathPredicate = -1
|
||||
lastSuccessfulPathChildren = -1
|
||||
|
||||
// avoid allocating iterator when empty
|
||||
if (children.isNotEmpty())
|
||||
children.forEach { it.clearFull() }
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
blockEntity = null
|
||||
blockState = null
|
||||
|
||||
lastSuccessfulPathPredicate = -1
|
||||
lastSuccessfulPathChildren = -1
|
||||
|
||||
children.forEach { it.clear() }
|
||||
}
|
||||
}
|
||||
|
||||
private val tag2BlockEntity = Object2ObjectOpenHashMap<MultiblockBuilder.EntityTag<*>, BEList<*>>()
|
||||
private val tag2BlockState = Object2ObjectOpenHashMap<Any, Reference2IntOpenHashMap<BlockState>>()
|
||||
private val tag2Block = Object2ObjectOpenHashMap<Any, Object2IntOpenHashMap<Block>>()
|
||||
|
||||
private val blockEntityLists = ArrayList<BEList<*>>()
|
||||
private val blockStateLists = ArrayList<Reference2IntOpenHashMap<BlockState>>()
|
||||
private val blockLists = ArrayList<Object2IntOpenHashMap<Block>>()
|
||||
|
||||
private val parts: ImmutableSet<Part> = parts.stream().map { Part(it.pos + pos, it) }.collect(ImmutableSet.toImmutableSet())
|
||||
|
||||
fun clear() {
|
||||
blockEntityLists.forEach { it.clear() }
|
||||
blockStateLists.forEach { it.clear() }
|
||||
blockLists.forEach { it.clear() }
|
||||
parts.forEach { it.clear() }
|
||||
}
|
||||
|
||||
fun update(levelAccessor: LevelAccessor): Boolean {
|
||||
var valid = true
|
||||
|
||||
for (part in parts) {
|
||||
valid = part.test(levelAccessor)
|
||||
if (!valid) break
|
||||
}
|
||||
|
||||
if (!valid)
|
||||
clear()
|
||||
|
||||
return valid
|
||||
}
|
||||
|
||||
fun <T : BlockEntity> blockEntities(tag: MultiblockBuilder.EntityTag<T>): Set<T> {
|
||||
return (tag2BlockEntity[tag]?.setView ?: setOf()) as Set<T>
|
||||
}
|
||||
|
||||
fun blockEntityRemoved(blockEntity: BlockEntity): Boolean {
|
||||
var any = false
|
||||
|
||||
blockEntityLists.forEach {
|
||||
any = it.blockEntityRemoved(blockEntity) || any
|
||||
}
|
||||
|
||||
return any
|
||||
}
|
||||
}
|
||||
|
||||
private val north = Config(pos, north).also { configurations.add(it) }
|
||||
private val south = Config(pos, south).also { configurations.add(it) }
|
||||
private val west = Config(pos, west).also { configurations.add(it) }
|
||||
private val east = Config(pos, east).also { configurations.add(it) }
|
||||
|
||||
private var activeConfig: Config? = null
|
||||
|
||||
fun <T : BlockEntity> blockEntities(tag: MultiblockBuilder.EntityTag<T>): Set<T> {
|
||||
if (!isValid) return emptySet()
|
||||
return activeConfig?.blockEntities(tag) ?: setOf()
|
||||
}
|
||||
|
||||
fun blockEntityRemoved(blockEntity: BlockEntity) {
|
||||
activeConfig?.blockEntityRemoved(blockEntity)
|
||||
}
|
||||
|
||||
fun update(levelAccessor: LevelAccessor): Boolean {
|
||||
val activeConfig = activeConfig
|
||||
|
||||
if (activeConfig != null && activeConfig.update(levelAccessor)) {
|
||||
return true
|
||||
} else if (activeConfig != null) {
|
||||
for (config in configurations) {
|
||||
if (config !== activeConfig && config.update(levelAccessor)) {
|
||||
this.activeConfig = config
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
this.activeConfig = null
|
||||
this.isValid = false
|
||||
return false
|
||||
} else {
|
||||
for (config in configurations) {
|
||||
if (config.update(levelAccessor)) {
|
||||
this.activeConfig = config
|
||||
this.isValid = true
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
package ru.dbotthepony.mc.otm.core.math
|
||||
|
||||
import com.google.common.collect.ImmutableMap
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.Direction
|
||||
import net.minecraft.core.Vec3i
|
||||
@ -27,8 +26,8 @@ operator fun BlockPos.plus(other: BlockRotation): BlockPos {
|
||||
return this + other.normal
|
||||
}
|
||||
|
||||
enum class RelativeSide {
|
||||
FRONT, BACK, LEFT, RIGHT, TOP, BOTTOM
|
||||
enum class RelativeSide(val default: Direction) {
|
||||
FRONT(Direction.NORTH), BACK(Direction.SOUTH), LEFT(Direction.WEST), RIGHT(Direction.EAST), TOP(Direction.UP), BOTTOM(Direction.DOWN)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -44,6 +44,10 @@ object MBlockEntities {
|
||||
return registry.register(name) { BlockEntityType.Builder.of(factory, *blocks.map { it.get() }.toTypedArray()).build(null) }
|
||||
}
|
||||
|
||||
private fun <T : BlockEntity> register(name: String, factory: BlockEntityType.BlockEntitySupplier<T>, blocks: Supplier<Block>): MDeferredRegister<*>.Entry<BlockEntityType<T>> {
|
||||
return registry.register(name) { BlockEntityType.Builder.of(factory, blocks.get()).build(null) }
|
||||
}
|
||||
|
||||
private fun <T : BlockEntity> register(name: String, factory: BlockEntityType.BlockEntitySupplier<T>, blocks: Map<*, Block>): MDeferredRegister<*>.Entry<BlockEntityType<T>> {
|
||||
return registry.register(name) { BlockEntityType.Builder.of(factory, *blocks.values.toTypedArray()).build(null) }
|
||||
}
|
||||
@ -87,6 +91,8 @@ object MBlockEntities {
|
||||
val POWERED_BLAST_FURNACE by register(MNames.POWERED_BLAST_FURNACE, ::PoweredBlastFurnaceBlockEntity, MBlocks.POWERED_BLAST_FURNACE)
|
||||
val POWERED_SMOKER by register(MNames.POWERED_SMOKER, ::PoweredSmokerBlockEntity, MBlocks.POWERED_SMOKER)
|
||||
|
||||
val MULTIBLOCK_TEST by register("multiblock_test", ::MultiblockTestBlockEntity, MBlocks::MULTIBLOCK_TEST)
|
||||
|
||||
val ENERGY_CABLES: Map<CablesConfig.E, BlockEntityType<*>> = SupplierMap(CablesConfig.E.entries.map { conf ->
|
||||
var selfFeed: Supplier<BlockEntityType<*>> = Supplier { TODO() }
|
||||
selfFeed = register("${conf.name.lowercase()}_energy_cable", { a, b -> SimpleEnergyCableBlockEntity(selfFeed.get(), a, b, conf) }) as Supplier<BlockEntityType<*>>
|
||||
|
@ -31,6 +31,7 @@ import ru.dbotthepony.mc.otm.block.BlockSphereDebugger
|
||||
import ru.dbotthepony.mc.otm.block.EnergyCableBlock
|
||||
import ru.dbotthepony.mc.otm.block.MatterCableBlock
|
||||
import ru.dbotthepony.mc.otm.block.MatteryBlock
|
||||
import ru.dbotthepony.mc.otm.block.MultiblockTestBlock
|
||||
import ru.dbotthepony.mc.otm.block.StorageCableBlock
|
||||
import ru.dbotthepony.mc.otm.block.addSimpleDescription
|
||||
import ru.dbotthepony.mc.otm.block.decorative.DevChestBlock
|
||||
@ -220,7 +221,7 @@ object MBlocks {
|
||||
.sound(SoundType.BASALT)
|
||||
.requiresCorrectToolForDrops()
|
||||
.explosionResistance(80f)
|
||||
.strength(4f)
|
||||
.destroyTime(2.5f)
|
||||
) }
|
||||
|
||||
val TRITANIUM_STRIPED_STAIRS: Block by registry.register(MNames.TRITANIUM_STRIPED_STAIRS) { StairBlock(
|
||||
@ -241,9 +242,11 @@ object MBlocks {
|
||||
.sound(SoundType.BASALT)
|
||||
.requiresCorrectToolForDrops()
|
||||
.explosionResistance(40f)
|
||||
.strength(3f)
|
||||
.destroyTime(1.5f)
|
||||
) }
|
||||
|
||||
val MULTIBLOCK_TEST by registry.register("multiblock_test") { MultiblockTestBlock() }
|
||||
|
||||
init {
|
||||
MRegistry.registerBlocks(registry)
|
||||
}
|
||||
|
@ -161,6 +161,7 @@ object MItems {
|
||||
|
||||
val DEBUG_EXPLOSION_SMALL: Item by registry.register(MNames.DEBUG_EXPLOSION_SMALL) { BlockItem(MBlocks.DEBUG_EXPLOSION_SMALL, Item.Properties().stacksTo(64)) }
|
||||
val DEBUG_SPHERE_POINTS: Item by registry.register(MNames.DEBUG_SPHERE_POINTS) { BlockItem(MBlocks.DEBUG_SPHERE_POINTS, Item.Properties().stacksTo(64)) }
|
||||
val MULTIBLOCK_TEST by registry.register("multiblock_test") { BlockItem(MBlocks.MULTIBLOCK_TEST, Properties().stacksTo(64)) }
|
||||
|
||||
val TRITANIUM_ANVIL: List<BlockItem>
|
||||
|
||||
|
@ -10,10 +10,12 @@ import net.minecraft.client.renderer.item.ItemProperties
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.cauldron.CauldronInteraction
|
||||
import net.minecraft.core.registries.Registries
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.world.entity.EntityType
|
||||
import net.minecraft.world.entity.ai.village.poi.PoiType
|
||||
import net.minecraft.world.entity.ai.village.poi.PoiTypes
|
||||
import net.minecraft.world.item.BlockItem
|
||||
import net.minecraft.world.item.DyeColor
|
||||
import net.minecraft.world.item.DyeableArmorItem
|
||||
import net.minecraft.world.item.ItemStack
|
||||
@ -393,6 +395,18 @@ object MRegistry : IBlockItemRegistryAcceptor {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (item in MItems.ESSENCE_STORAGE.values) {
|
||||
ItemProperties.register(item, ResourceLocation(OverdriveThatMatters.MOD_ID, "is_filled")) { stack, _, _, _ ->
|
||||
val tag = (stack.tag?.get(BlockItem.BLOCK_ENTITY_TAG) as? CompoundTag)?: return@register 0f
|
||||
|
||||
if (tag.contains("experienceStored") && tag.getLong("experienceStored") > 0.0) {
|
||||
1f
|
||||
} else {
|
||||
0f
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -168,6 +168,8 @@ public net.minecraft.world.entity.boss.wither.WitherBoss f_31432_ # TARGETING_CO
|
||||
public-f net.minecraft.world.entity.boss.wither.WitherBoss f_31431_ # LIVING_ENTITY_SELECTOR
|
||||
public net.minecraft.world.entity.ai.targeting.TargetingConditions f_26879_ # selector
|
||||
|
||||
public net.minecraft.world.entity.ExperienceOrb f_147072_ # count
|
||||
|
||||
public net.minecraft.advancements.critereon.InventoryChangeTrigger$TriggerInstance f_43179_
|
||||
public net.minecraft.advancements.critereon.InventoryChangeTrigger$TriggerInstance f_43178_
|
||||
public net.minecraft.advancements.critereon.InventoryChangeTrigger$TriggerInstance f_43177_
|
||||
|
@ -1,74 +0,0 @@
|
||||
{
|
||||
"multipart": [
|
||||
{
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/storage_cable_core"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_south": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/storage_cable_connection"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_west": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/storage_cable_connection",
|
||||
"y": 90
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_north": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/storage_cable_connection",
|
||||
"y": 180
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_east": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/storage_cable_connection",
|
||||
"y": 270
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_up": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/storage_cable_connection",
|
||||
"x": 90
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_down": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/storage_cable_connection",
|
||||
"x": 270
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
{
|
||||
"multipart": [
|
||||
{
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/storage_cable_core"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_south": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/storage_cable_connection"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_west": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/storage_cable_connection",
|
||||
"y": 90
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_north": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/storage_cable_connection",
|
||||
"y": 180
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_east": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/storage_cable_connection",
|
||||
"y": 270
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_up": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/storage_cable_connection",
|
||||
"x": 90
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_down": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/storage_cable_connection",
|
||||
"x": 270
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
{
|
||||
"multipart": [
|
||||
{
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/matter_cable_core"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_south": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/matter_cable_connection"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_west": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/matter_cable_connection",
|
||||
"y": 90
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_north": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/matter_cable_connection",
|
||||
"y": 180
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_east": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/matter_cable_connection",
|
||||
"y": 270
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_up": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/matter_cable_connection",
|
||||
"x": 90
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_down": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/matter_cable_connection",
|
||||
"x": 270
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
{
|
||||
"multipart": [
|
||||
{
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/storage_cable_core"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_south": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/storage_cable_connection"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_west": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/storage_cable_connection",
|
||||
"y": 90
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_north": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/storage_cable_connection",
|
||||
"y": 180
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_east": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/storage_cable_connection",
|
||||
"y": 270
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_up": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/storage_cable_connection",
|
||||
"x": 90
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_down": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/storage_cable_connection",
|
||||
"x": 270
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
{
|
||||
"multipart": [
|
||||
{
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/storage_cable_core"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_south": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/storage_cable_connection"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_west": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/storage_cable_connection",
|
||||
"y": 90
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_north": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/storage_cable_connection",
|
||||
"y": 180
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_east": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/storage_cable_connection",
|
||||
"y": 270
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_up": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/storage_cable_connection",
|
||||
"x": 90
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_down": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/storage_cable_connection",
|
||||
"x": 270
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
{
|
||||
"multipart": [
|
||||
{
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/storage_cable_core"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_south": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/storage_cable_connection"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_west": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/storage_cable_connection",
|
||||
"y": 90
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_north": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/storage_cable_connection",
|
||||
"y": 180
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_east": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/storage_cable_connection",
|
||||
"y": 270
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_up": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/storage_cable_connection",
|
||||
"x": 90
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"when": {
|
||||
"connect_down": true
|
||||
},
|
||||
|
||||
"apply": {
|
||||
"model": "overdrive_that_matters:block/storage_cable_connection",
|
||||
"x": 270
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
{
|
||||
"parent": "block/block",
|
||||
"texture_size": [16, 16],
|
||||
"textures": {
|
||||
"particle": "#0"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [ 5, 5, 11 ],
|
||||
"to": [ 11, 11, 16 ],
|
||||
"faces": {
|
||||
"down": {"uv": [6, 0, 11, 6],"rotation": 90, "texture": "#0" },
|
||||
"up": {"uv": [6, 0, 11, 6],"rotation": 90, "texture": "#0" },
|
||||
"west": {"uv": [6, 0, 11, 6], "texture": "#0" },
|
||||
"east": {"uv": [6, 0, 11, 6], "texture": "#0" }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
{
|
||||
"parent": "block/block",
|
||||
"texture_size": [16, 16],
|
||||
"textures": {
|
||||
"particle": "#0"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [ 5, 5, 5 ],
|
||||
"to": [ 11, 11, 11 ],
|
||||
"faces": {
|
||||
"down": {"uv": [0, 0, 6, 6], "texture": "#0" },
|
||||
"up": {"uv": [0, 0, 6, 6], "texture": "#0" },
|
||||
"north": {"uv": [0, 0, 6, 6], "texture": "#0" },
|
||||
"south": {"uv": [0, 0, 6, 6], "texture": "#0" },
|
||||
"west": {"uv": [0, 0, 6, 6], "texture": "#0" },
|
||||
"east": {"uv": [0, 0, 6, 6], "texture": "#0" }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,124 @@
|
||||
{
|
||||
"parent": "block/block",
|
||||
"credit": "Made with Blockbench",
|
||||
"render_type": "cutout",
|
||||
"texture_size": [32, 64],
|
||||
"textures": {
|
||||
"0": "overdrive_that_matters:block/essence_storage",
|
||||
"particle": "#0"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "body",
|
||||
"from": [0, 0, 0],
|
||||
"to": [16, 2, 16],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 4, 8, 4.5], "texture": "#0"},
|
||||
"east": {"uv": [0, 4, 8, 4.5], "texture": "#0"},
|
||||
"south": {"uv": [0, 4, 8, 4.5], "texture": "#0"},
|
||||
"west": {"uv": [0, 4, 8, 4.5], "texture": "#0"},
|
||||
"up": {"uv": [0, 0, 8, 4], "texture": "#0"},
|
||||
"down": {"uv": [0, 0, 8, 4], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"from": [0, 3, 0],
|
||||
"to": [16, 5, 16],
|
||||
"faces": {
|
||||
"north": {"uv": [8, 7.25, 16, 7.75], "texture": "#0"},
|
||||
"east": {"uv": [8, 7.25, 16, 7.75], "texture": "#0"},
|
||||
"south": {"uv": [8, 7.25, 16, 7.75], "texture": "#0"},
|
||||
"west": {"uv": [8, 7.25, 16, 7.75], "texture": "#0"},
|
||||
"up": {"uv": [0, 7.25, 8, 11.25], "rotation": 180, "texture": "#0"},
|
||||
"down": {"uv": [0, 0, 8, 4], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"from": [9, 5, 0],
|
||||
"to": [16, 16, 14],
|
||||
"faces": {
|
||||
"north": {"uv": [12, 0, 15.5, 2.75], "texture": "#0"},
|
||||
"east": {"uv": [9, 7.75, 16, 10.5], "texture": "#0"},
|
||||
"south": {"uv": [11, 4.5, 14.5, 7.25], "texture": "#0"},
|
||||
"west": {"uv": [0, 4.5, 7, 7.25], "texture": "#0"},
|
||||
"up": {"uv": [0, 7.75, 3.5, 11.25], "rotation": 180, "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"from": [0, 10, 14],
|
||||
"to": [16, 16, 16],
|
||||
"faces": {
|
||||
"east": {"uv": [8, 7.75, 9, 9.25], "texture": "#0"},
|
||||
"south": {"uv": [0, 11.25, 8, 12.75], "texture": "#0"},
|
||||
"west": {"uv": [14.5, 4.5, 15.5, 6], "texture": "#0"},
|
||||
"up": {"uv": [0, 7.25, 8, 7.75], "rotation": 180, "texture": "#0"},
|
||||
"down": {"uv": [0, 7.25, 8, 7.75], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"from": [0, 5, 9],
|
||||
"to": [9, 16, 14],
|
||||
"faces": {
|
||||
"north": {"uv": [7, 4.5, 11.5, 7.25], "texture": "#0"},
|
||||
"south": {"uv": [5, 4.5, 9.5, 7.25], "texture": "#0"},
|
||||
"west": {"uv": [12, 4.5, 14.5, 7.25], "texture": "#0"},
|
||||
"up": {"uv": [3.5, 7.75, 8, 9], "rotation": 180, "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"from": [1, 2, 1],
|
||||
"to": [15, 3, 15],
|
||||
"faces": {
|
||||
"north": {"uv": [0.5, 4.25, 7.5, 4.5], "texture": "#0"},
|
||||
"east": {"uv": [0.5, 4.25, 7.5, 4.5], "texture": "#0"},
|
||||
"south": {"uv": [0.5, 4.25, 7.5, 4.5], "texture": "#0"},
|
||||
"west": {"uv": [0.5, 4.25, 7.5, 4.5], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"from": [1, 5, 14],
|
||||
"to": [15, 10, 15],
|
||||
"faces": {
|
||||
"east": {"uv": [15.5, 10.5, 16, 11.75], "texture": "#0"},
|
||||
"south": {"uv": [8.5, 10.5, 15.5, 11.75], "texture": "#0"},
|
||||
"west": {"uv": [8, 10.5, 8.5, 11.75], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "bottle",
|
||||
"from": [1, 13, 1],
|
||||
"to": [9, 15, 9],
|
||||
"faces": {
|
||||
"north": {"uv": [8, 2, 12, 2.5], "texture": "#0"},
|
||||
"west": {"uv": [8, 2, 12, 2.5], "texture": "#0"},
|
||||
"up": {"uv": [8, 0, 12, 2], "texture": "#0"},
|
||||
"down": {"uv": [8, 0, 12, 2], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "bottle",
|
||||
"from": [1, 5, 1],
|
||||
"to": [9, 6, 9],
|
||||
"faces": {
|
||||
"north": {"uv": [8, 4.25, 12, 4.5], "texture": "#0"},
|
||||
"west": {"uv": [8, 4.25, 12, 4.5], "texture": "#0"},
|
||||
"up": {"uv": [8, 0, 12, 2], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "bottle",
|
||||
"from": [1, 6, 1],
|
||||
"to": [9, 13, 9],
|
||||
"faces": {
|
||||
"north": {"uv": [8, 2.5, 12, 4.25], "texture": "#0"},
|
||||
"west": {"uv": [8, 2.5, 12, 4.25], "texture": "#0"}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -1,10 +1,12 @@
|
||||
{
|
||||
"parent": "block/block",
|
||||
"credit": "Made with Blockbench",
|
||||
"render_type": "cutout",
|
||||
"texture_size": [32, 64],
|
||||
"textures": {
|
||||
"0": "overdrive_that_matters:block/essence_storage",
|
||||
"particle": "overdrive_that_matters:block/essence_storage"
|
||||
"1": "overdrive_that_matters:block/liquid_xp_still",
|
||||
"particle": "#0"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
@ -92,15 +94,15 @@
|
||||
{
|
||||
"name": "experience",
|
||||
"from": [1.5, 5, 1.5],
|
||||
"to": [8.5, 11, 8.5],
|
||||
"to": [8.5, 13, 8.5],
|
||||
"faces": {
|
||||
"north": {"uv": [8, 14.5, 11.5, 16], "texture": "#0"},
|
||||
"east": {"uv": [12.5, 12, 16, 13.5], "texture": "#0"},
|
||||
"south": {"uv": [9, 12, 12.5, 13.5], "texture": "#0"},
|
||||
"west": {"uv": [11.5, 14.5, 15, 16], "texture": "#0"},
|
||||
"up": {"uv": [9.5, 12.5, 13, 14.25], "texture": "#0"}
|
||||
"north": {"uv": [7.5, 3, 14.5, 11], "texture": "#1"},
|
||||
"west": {"uv": [1.5, 3, 8.5, 11], "texture": "#1"}
|
||||
},
|
||||
"forge_data": { "block_light": 15, "sky_light": 15 }
|
||||
"forge_data": {
|
||||
"block_light": 15,
|
||||
"sky_light": 15
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "bottle",
|
||||
@ -132,36 +134,5 @@
|
||||
"west": {"uv": [8, 2.5, 12, 4.25], "texture": "#0"}
|
||||
}
|
||||
}
|
||||
],
|
||||
"display": {
|
||||
"thirdperson_righthand": {
|
||||
"rotation": [75, 45, 0],
|
||||
"translation": [0, 2.5, 0],
|
||||
"scale": [0.375, 0.375, 0.375]
|
||||
},
|
||||
"thirdperson_lefthand": {
|
||||
"rotation": [75, 45, 0],
|
||||
"translation": [0, 2.5, 0],
|
||||
"scale": [0.375, 0.375, 0.375]
|
||||
},
|
||||
"firstperson_righthand": {
|
||||
"rotation": [0, 45, 0],
|
||||
"scale": [0.4, 0.4, 0.4]
|
||||
},
|
||||
"firstperson_lefthand": {
|
||||
"rotation": [0, 225, 0],
|
||||
"scale": [0.4, 0.4, 0.4]
|
||||
},
|
||||
"ground": {
|
||||
"translation": [0, 3, 0],
|
||||
"scale": [0.25, 0.25, 0.25]
|
||||
},
|
||||
"gui": {
|
||||
"rotation": [30, 225, 0],
|
||||
"scale": [0.625, 0.625, 0.625]
|
||||
},
|
||||
"fixed": {
|
||||
"scale": [0.5, 0.5, 0.5]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
{
|
||||
"parent": "block/block",
|
||||
"texture_size": [16, 16],
|
||||
"textures": {
|
||||
"connection": "overdrive_that_matters:block/storage_cable",
|
||||
"particle": "overdrive_that_matters:block/storage_cable"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [ 5, 5, 11 ],
|
||||
"to": [ 11, 11, 16 ],
|
||||
"faces": {
|
||||
"down": {"uv": [6, 0, 11, 6],"rotation": 90, "texture": "#connection" },
|
||||
"up": {"uv": [6, 0, 11, 6],"rotation": 90, "texture": "#connection" },
|
||||
"west": {"uv": [6, 0, 11, 6], "texture": "#connection" },
|
||||
"east": {"uv": [6, 0, 11, 6], "texture": "#connection" }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
{
|
||||
"parent": "block/block",
|
||||
"texture_size": [16, 16],
|
||||
"textures": {
|
||||
"core": "overdrive_that_matters:block/storage_cable",
|
||||
"particle": "overdrive_that_matters:block/storage_cable"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [ 5, 5, 5 ],
|
||||
"to": [ 11, 11, 11 ],
|
||||
"faces": {
|
||||
"down": {"uv": [0, 0, 6, 6], "texture": "#core" },
|
||||
"up": {"uv": [0, 0, 6, 6], "texture": "#core" },
|
||||
"north": {"uv": [0, 0, 6, 6], "texture": "#core" },
|
||||
"south": {"uv": [0, 0, 6, 6], "texture": "#core" },
|
||||
"west": {"uv": [0, 0, 6, 6], "texture": "#core" },
|
||||
"east": {"uv": [0, 0, 6, 6], "texture": "#core" }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
{
|
||||
"parent": "block/block",
|
||||
"texture_size": [16, 16],
|
||||
"textures": {
|
||||
"particle": "#0"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [5, 5, 5],
|
||||
"to": [11, 11, 11],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 6, 6], "texture": "#0"},
|
||||
"south": {"uv": [0, 0, 6, 6], "texture": "#0"},
|
||||
"up": {"uv": [0, 0, 6, 6], "rotation": 180, "texture": "#0"},
|
||||
"down": {"uv": [0, 0, 6, 6], "rotation": 180, "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [0, 5, 5],
|
||||
"to": [5, 11, 11],
|
||||
"faces": {
|
||||
"north": {"uv": [6, 0, 11, 6], "texture": "#0"},
|
||||
"south": {"uv": [6, 6, 11, 0], "rotation": 180, "texture": "#0"},
|
||||
"west": {"uv": [0, 0, 6, 6], "texture": "#0"},
|
||||
"up": {"uv": [6, 0, 11, 6], "rotation": 180, "texture": "#0"},
|
||||
"down": {"uv": [6, 0, 11, 6], "rotation": 180, "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [11, 5, 5],
|
||||
"to": [16, 11, 11],
|
||||
"faces": {
|
||||
"north": {"uv": [11, 0, 16, 6], "texture": "#0"},
|
||||
"east": {"uv": [0, 0, 6, 6], "texture": "#0"},
|
||||
"south": {"uv": [11, 6, 16, 0], "rotation": 180, "texture": "#0"},
|
||||
"up": {"uv": [11, 0, 16, 6], "rotation": 180, "texture": "#0"},
|
||||
"down": {"uv": [11, 0, 16, 6], "rotation": 180, "texture": "#0"}
|
||||
}
|
||||
}
|
||||
],
|
||||
"gui_light": "front",
|
||||
"display": {
|
||||
"gui": {
|
||||
"rotation": [0, 0, 0],
|
||||
"translation": [0, 0, 0],
|
||||
"scale": [1, 1, 1]
|
||||
}
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
{
|
||||
"parent": "block/block",
|
||||
"texture_size": [16, 16],
|
||||
"textures": {
|
||||
"core": "overdrive_that_matters:block/storage_cable",
|
||||
"particle": "overdrive_that_matters:block/storage_cable"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [ 6, 6, 6 ],
|
||||
"to": [ 10, 10, 10 ],
|
||||
"faces": {
|
||||
"down": {"uv": [0, 0, 4, 4], "texture": "#core" },
|
||||
"up": {"uv": [0, 0, 4, 4], "texture": "#core" },
|
||||
"north": {"uv": [0, 0, 4, 4], "texture": "#core" },
|
||||
"south": {"uv": [0, 0, 4, 4], "texture": "#core" },
|
||||
"west": {"uv": [0, 0, 4, 4], "texture": "#core" },
|
||||
"east": {"uv": [0, 0, 4, 4], "texture": "#core" }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -6,6 +6,7 @@
|
||||
"minVersion": "0.8",
|
||||
"refmap": "overdrive_that_matters.refmap.json",
|
||||
"mixins": [
|
||||
"BlockEntityMixin",
|
||||
"EnchantmentHelperMixin",
|
||||
"FoodDataMixin",
|
||||
"MixinPatchProjectileFinder",
|
||||
@ -21,6 +22,7 @@
|
||||
],
|
||||
"client": [
|
||||
"MixinGameRenderer",
|
||||
"MixinMinecraft"
|
||||
"MixinMinecraft",
|
||||
"SplashManagerMixin"
|
||||
]
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user