Plate Press

initial datagen for recipes
fix addItem ranges in MatteryContainer
This commit is contained in:
DBotThePony 2022-01-14 17:19:09 +07:00
parent 81e6a8e616
commit c016b8850d
Signed by: DBot
GPG Key ID: DCC23B5715498507
20 changed files with 555 additions and 22 deletions

View File

@ -2,6 +2,9 @@ package ru.dbotthepony.mc.otm.datagen
import net.minecraft.core.Direction
import net.minecraft.resources.ResourceLocation
import net.minecraft.tags.Tag
import net.minecraft.world.item.Item
import net.minecraft.world.item.crafting.Ingredient
import net.minecraft.world.level.block.Block
import net.minecraftforge.eventbus.api.SubscribeEvent
import net.minecraftforge.fml.common.Mod
@ -15,10 +18,13 @@ import ru.dbotthepony.mc.otm.block.BlockMatteryRotatable
import ru.dbotthepony.mc.otm.block.BlockPatternStorage
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState
import ru.dbotthepony.mc.otm.datagen.blocks.*
import ru.dbotthepony.mc.otm.datagen.items.DummyItemTag
import ru.dbotthepony.mc.otm.datagen.items.MatteryItemModelProvider
import ru.dbotthepony.mc.otm.datagen.loot.MatteryLootTableProvider
import ru.dbotthepony.mc.otm.datagen.loot.TileNbtCopy
import ru.dbotthepony.mc.otm.datagen.models.BlockMatteryModelProvider
import ru.dbotthepony.mc.otm.datagen.recipes.MatteryRecipeProvider
import ru.dbotthepony.mc.otm.recipes.PlatePressRecipe
@Mod.EventBusSubscriber(modid = DataGen.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD)
object DataGen {
@ -28,6 +34,7 @@ object DataGen {
private lateinit var itemModelProvider: MatteryItemModelProvider
private lateinit var blockStateProvider: MatteryBlockStateProvider
private lateinit var lootTableProvider: MatteryLootTableProvider
private lateinit var recipeProvider: MatteryRecipeProvider
private fun decorativeCubeAll(vararg blocks: Block) {
blockModelProvider.decorativeCubeAll(*blocks)
@ -52,11 +59,13 @@ object DataGen {
blockStateProvider = MatteryBlockStateProvider(event)
itemModelProvider = MatteryItemModelProvider(event)
lootTableProvider = MatteryLootTableProvider(event.generator)
recipeProvider = MatteryRecipeProvider(event.generator)
event.generator.addProvider(blockModelProvider)
event.generator.addProvider(itemModelProvider)
event.generator.addProvider(blockStateProvider)
event.generator.addProvider(blockStateProvider)
event.generator.addProvider(recipeProvider)
decorativeCubeAll(*Blocks.CRATES)
decorativeCubeAll(Blocks.CARBON_FIBRE_BLOCK)
@ -279,5 +288,10 @@ object DataGen {
tile(Blocks.MATTER_CAPACITOR_BANK, TileNbtCopy("matter_container"))
tile(Blocks.MATTER_BOTTLER, TileNbtCopy("energy_cap"), TileNbtCopy("battery_container"), TileNbtCopy("work_slots"), TileNbtCopy("work_flow"), TileNbtCopy("matter_capability"))
}
with(recipeProvider) {
plate("iron")
plate("tritanium")
}
}
}

View File

@ -25,6 +25,3 @@ fun <T : Comparable<T>> BlockState.getValueNullable(prop: Property<T>): T? {
return null
}
operator fun JsonObject.set(s: String, value: JsonArray) = add(s, value)

View File

@ -0,0 +1,11 @@
package ru.dbotthepony.mc.otm.datagen.items
import net.minecraft.resources.ResourceLocation
import net.minecraft.tags.Tag
import net.minecraft.world.item.Item
class DummyItemTag(private val name: ResourceLocation) : Tag.Named<Item> {
override fun contains(p_13287_: Item) = false
override fun getValues() = emptyList<Item>()
override fun getName() = name
}

View File

@ -9,7 +9,7 @@ import net.minecraft.core.Direction
import net.minecraft.resources.ResourceLocation
import net.minecraftforge.client.model.generators.ModelBuilder
import net.minecraftforge.common.data.ExistingFileHelper
import ru.dbotthepony.mc.otm.datagen.set
import ru.dbotthepony.mc.otm.set
data class TextureSize(val width: Float, val height: Float) {
constructor(arr: JsonArray) : this(arr[0].asFloat, arr[1].asFloat)

View File

@ -0,0 +1,43 @@
package ru.dbotthepony.mc.otm.datagen.recipes
import net.minecraft.data.DataGenerator
import net.minecraft.data.recipes.FinishedRecipe
import net.minecraft.data.recipes.RecipeProvider
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.crafting.Ingredient
import ru.dbotthepony.mc.otm.datagen.DataGen
import ru.dbotthepony.mc.otm.recipes.PlatePressRecipe
import java.util.function.Consumer
private typealias RecipeLambda = (MatteryRecipeProvider, Consumer<FinishedRecipe>) -> Unit
class MatteryRecipeProvider(generatorIn: DataGenerator) : RecipeProvider(generatorIn) {
private val lambdas = ArrayList<RecipeLambda>()
fun lambda(lambda: RecipeLambda) = lambdas.add(lambda)
override fun buildCraftingRecipes(callback: Consumer<FinishedRecipe>) {
for (lambda in lambdas) {
lambda(this, callback)
}
}
fun plate(id: String, count: Int = 1, workTicks: Int = 200) {
lambda { it, callback ->
callback.accept(PlatePressShallowFinishedRecipe(
ResourceLocation(DataGen.MOD_ID, "plate_$id"),
ResourceLocation("forge", "ingots/$id"),
ResourceLocation("forge", "plates/$id"),
count,
workTicks
))
}
}
fun plate(id: String, ingredient: Ingredient, result: Ingredient, count: Int = 1, workTicks: Int = 200) {
lambda { it, callback ->
callback.accept(PlatePressFinishedRecipe(PlatePressRecipe(ResourceLocation(DataGen.MOD_ID, "plate_$id"), ingredient, result, count, workTicks)))
}
}
}

View File

@ -0,0 +1,78 @@
package ru.dbotthepony.mc.otm.datagen.recipes
import com.google.gson.JsonObject
import com.google.gson.JsonPrimitive
import net.minecraft.data.recipes.FinishedRecipe
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.item.crafting.RecipeSerializer
import ru.dbotthepony.mc.otm.recipes.PlatePressRecipe
import ru.dbotthepony.mc.otm.recipes.PlatePressRecipeFactory
import ru.dbotthepony.mc.otm.set
class PlatePressFinishedRecipe(private val recipe: PlatePressRecipe) : FinishedRecipe {
override fun serializeRecipeData(it: JsonObject) {
it["input"] = recipe.input.toJson()
it["result"] = recipe.output.toJson().also {
if (it is JsonObject && recipe.count != 1)
it["count"] = JsonPrimitive(recipe.count)
}
it["work_time"] = JsonPrimitive(recipe.workTime)
}
override fun getId(): ResourceLocation {
return recipe.id
}
override fun getType(): RecipeSerializer<*> {
return PlatePressRecipeFactory
}
override fun serializeAdvancement(): JsonObject? {
return null
}
override fun getAdvancementId(): ResourceLocation? {
return null
}
}
class PlatePressShallowFinishedRecipe(
private val id: ResourceLocation,
private val input: ResourceLocation,
private val output: ResourceLocation,
private val count: Int = 1,
private val workTime: Int = 200
) : FinishedRecipe {
override fun serializeRecipeData(it: JsonObject) {
it["input"] = JsonObject().also {
it["tag"] = JsonPrimitive(input.toString())
}
it["result"] = JsonObject().also {
it["tag"] = JsonPrimitive(output.toString())
if (count != 1)
it["count"] = JsonPrimitive(count)
}
it["work_time"] = JsonPrimitive(workTime)
}
override fun getId(): ResourceLocation {
return id
}
override fun getType(): RecipeSerializer<*> {
return PlatePressRecipeFactory
}
override fun serializeAdvancement(): JsonObject? {
return null
}
override fun getAdvancementId(): ResourceLocation? {
return null
}
}

View File

@ -142,6 +142,7 @@ public class OverdriveThatMatters {
FMLJavaModLoadingContext.get().getModEventBus().register(Registry.AndroidFeatures.class);
FMLJavaModLoadingContext.get().getModEventBus().register(Registry.AndroidResearch.class);
FMLJavaModLoadingContext.get().getModEventBus().register(Registry.Stats.class);
FMLJavaModLoadingContext.get().getModEventBus().register(Registry.Recipes.class);
MinecraftForge.EVENT_BUS.register(DrivePool.INSTANCE);
MinecraftForge.EVENT_BUS.register(ItemPortableCondensationDrive.Companion);

View File

@ -8,11 +8,15 @@ import net.minecraft.resources.ResourceLocation;
import net.minecraft.stats.StatFormatter;
import net.minecraft.tags.BlockTags;
import net.minecraft.util.valueproviders.UniformInt;
import net.minecraft.world.Container;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.food.FoodProperties;
import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.item.*;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.crafting.RecipeSerializer;
import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.OreBlock;
import net.minecraft.world.level.block.SoundType;
@ -46,6 +50,8 @@ import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.item.*;
import ru.dbotthepony.mc.otm.menu.*;
import ru.dbotthepony.mc.otm.client.screen.*;
import ru.dbotthepony.mc.otm.recipes.PlatePressRecipe;
import ru.dbotthepony.mc.otm.recipes.PlatePressRecipeFactory;
public class Registry {
public static final DamageSource DAMAGE_BECOME_ANDROID = new DamageSource("otm_become_android");
@ -121,6 +127,7 @@ public class Registry {
public static final ResourceLocation ITEM_MONITOR = loc("item_monitor"); // нужен рецепт (после улучшений)
public static final ResourceLocation ENERGY_COUNTER = loc("energy_counter"); // нужен рецепт
public static final ResourceLocation CHEMICAL_GENERATOR = loc("chemical_generator"); // нужен рецепт
public static final ResourceLocation PLATE_PRESS = loc("plate_press"); // нужен рецепт
public static final ResourceLocation DEBUG_EXPLOSION_SMALL = loc("debug_explosion_small");
@ -271,6 +278,7 @@ public class Registry {
public static final BlockItemMonitor ITEM_MONITOR = new BlockItemMonitor();
public static final BlockEnergyCounter ENERGY_COUNTER = new BlockEnergyCounter();
public static final BlockChemicalGenerator CHEMICAL_GENERATOR = new BlockChemicalGenerator();
public static final BlockPlatePress PLATE_PRESS = new BlockPlatePress();
public static final BlockExplosionDebugger DEBUG_EXPLOSION_SMALL = new BlockExplosionDebugger();
public static final BlockSphereDebugger DEBUG_SPHERE_POINTS = new BlockSphereDebugger();
@ -353,6 +361,7 @@ public class Registry {
ITEM_MONITOR.setRegistryName(Names.ITEM_MONITOR);
ENERGY_COUNTER.setRegistryName(Names.ENERGY_COUNTER);
CHEMICAL_GENERATOR.setRegistryName(Names.CHEMICAL_GENERATOR);
PLATE_PRESS.setRegistryName(Names.PLATE_PRESS);
DEBUG_EXPLOSION_SMALL.setRegistryName(Names.DEBUG_EXPLOSION_SMALL);
DEBUG_SPHERE_POINTS.setRegistryName(Names.DEBUG_SPHERE_POINTS);
@ -388,6 +397,7 @@ public class Registry {
event.getRegistry().register(ITEM_MONITOR);
event.getRegistry().register(ENERGY_COUNTER);
event.getRegistry().register(CHEMICAL_GENERATOR);
event.getRegistry().register(PLATE_PRESS);
event.getRegistry().register(DEBUG_EXPLOSION_SMALL);
event.getRegistry().register(DEBUG_SPHERE_POINTS);
@ -420,6 +430,7 @@ public class Registry {
public static final BlockItem ITEM_MONITOR = new BlockItem(Blocks.ITEM_MONITOR, new Item.Properties().stacksTo(64).tab(OverdriveThatMatters.CREATIVE_TAB));
public static final BlockItem ENERGY_COUNTER = new BlockItem(Blocks.ENERGY_COUNTER, new Item.Properties().stacksTo(64).tab(OverdriveThatMatters.CREATIVE_TAB));
public static final BlockItem CHEMICAL_GENERATOR = new BlockItem(Blocks.CHEMICAL_GENERATOR, new Item.Properties().stacksTo(64).tab(OverdriveThatMatters.CREATIVE_TAB));
public static final BlockItem PLATE_PRESS = new BlockItem(Blocks.PLATE_PRESS, new Item.Properties().stacksTo(64).tab(OverdriveThatMatters.CREATIVE_TAB));
public static final BlockItem DEBUG_EXPLOSION_SMALL = new BlockItem(Blocks.DEBUG_EXPLOSION_SMALL, new Item.Properties().stacksTo(64).tab(OverdriveThatMatters.CREATIVE_TAB));
public static final BlockItem DEBUG_SPHERE_POINTS = new BlockItem(Blocks.DEBUG_SPHERE_POINTS, new Item.Properties().stacksTo(64).tab(OverdriveThatMatters.CREATIVE_TAB));
@ -555,6 +566,7 @@ public class Registry {
ITEM_MONITOR.setRegistryName(Names.ITEM_MONITOR);
ENERGY_COUNTER.setRegistryName(Names.ENERGY_COUNTER);
CHEMICAL_GENERATOR.setRegistryName(Names.CHEMICAL_GENERATOR);
PLATE_PRESS.setRegistryName(Names.PLATE_PRESS);
DEBUG_EXPLOSION_SMALL.setRegistryName(Names.DEBUG_EXPLOSION_SMALL);
DEBUG_SPHERE_POINTS.setRegistryName(Names.DEBUG_SPHERE_POINTS);
@ -635,6 +647,7 @@ public class Registry {
event.getRegistry().register(ITEM_MONITOR);
event.getRegistry().register(ENERGY_COUNTER);
event.getRegistry().register(CHEMICAL_GENERATOR);
event.getRegistry().register(PLATE_PRESS);
event.getRegistry().register(DEBUG_EXPLOSION_SMALL);
event.getRegistry().register(DEBUG_SPHERE_POINTS);
@ -721,6 +734,7 @@ public class Registry {
public static final BlockEntityType<BlockEntityItemMonitor> ITEM_MONITOR = BlockEntityType.Builder.of(BlockEntityItemMonitor::new, Blocks.ITEM_MONITOR).build(null);
public static final BlockEntityType<BlockEntityEnergyCounter> ENERGY_COUNTER = BlockEntityType.Builder.of(BlockEntityEnergyCounter::new, Blocks.ENERGY_COUNTER).build(null);
public static final BlockEntityType<BlockEntityChemicalGenerator> CHEMICAL_GENERATOR = BlockEntityType.Builder.of(BlockEntityChemicalGenerator::new, Blocks.CHEMICAL_GENERATOR).build(null);
public static final BlockEntityType<BlockEntityPlatePress> PLATE_PRESS = BlockEntityType.Builder.of(BlockEntityPlatePress::new, Blocks.PLATE_PRESS).build(null);
public static final BlockEntityType<BlockEntityExplosionDebugger> DEBUG_EXPLOSION_SMALL = BlockEntityType.Builder.of(BlockEntityExplosionDebugger::new, Blocks.DEBUG_EXPLOSION_SMALL).build(null);
public static final BlockEntityType<BlockEntitySphereDebugger> DEBUG_SPHERE_POINTS = BlockEntityType.Builder.of(BlockEntitySphereDebugger::new, Blocks.DEBUG_SPHERE_POINTS).build(null);
@ -743,6 +757,7 @@ public class Registry {
ITEM_MONITOR.setRegistryName(Names.ITEM_MONITOR);
ENERGY_COUNTER.setRegistryName(Names.ENERGY_COUNTER);
CHEMICAL_GENERATOR.setRegistryName(Names.CHEMICAL_GENERATOR);
PLATE_PRESS.setRegistryName(Names.PLATE_PRESS);
DEBUG_EXPLOSION_SMALL.setRegistryName(Names.DEBUG_EXPLOSION_SMALL);
DEBUG_SPHERE_POINTS.setRegistryName(Names.DEBUG_SPHERE_POINTS);
@ -768,6 +783,8 @@ public class Registry {
event.getRegistry().register(ITEM_MONITOR);
event.getRegistry().register(ENERGY_COUNTER);
event.getRegistry().register(CHEMICAL_GENERATOR);
event.getRegistry().register(PLATE_PRESS);
event.getRegistry().register(DEBUG_EXPLOSION_SMALL);
event.getRegistry().register(DEBUG_SPHERE_POINTS);
@ -1040,6 +1057,7 @@ public class Registry {
public static final MenuType<ItemMonitorMenu> ITEM_MONITOR = new MenuType<>(ItemMonitorMenu::new);
public static final MenuType<EnergyCounterMenu> ENERGY_COUNTER = new MenuType<>(EnergyCounterMenu::new);
public static final MenuType<ChemicalGeneratorMenu> CHEMICAL_GENERATOR = new MenuType<>(ChemicalGeneratorMenu::new);
public static final MenuType<PlatePressMenu> PLATE_PRESS = new MenuType<>(PlatePressMenu::new);
static {
ANDROID_STATION.setRegistryName(Names.ANDROID_STATION);
@ -1057,6 +1075,7 @@ public class Registry {
ITEM_MONITOR.setRegistryName(Names.ITEM_MONITOR);
ENERGY_COUNTER.setRegistryName(Names.ENERGY_COUNTER);
CHEMICAL_GENERATOR.setRegistryName(Names.CHEMICAL_GENERATOR);
PLATE_PRESS.setRegistryName(Names.PLATE_PRESS);
}
@SubscribeEvent
@ -1077,6 +1096,7 @@ public class Registry {
event.getRegistry().register(ITEM_MONITOR);
event.getRegistry().register(ENERGY_COUNTER);
event.getRegistry().register(CHEMICAL_GENERATOR);
event.getRegistry().register(PLATE_PRESS);
// OverdriveThatMatters.LOGGER.info("Registered menus");
}
@ -1099,6 +1119,7 @@ public class Registry {
MenuScreens.register(ITEM_MONITOR, ItemMonitorScreen::new);
MenuScreens.register(ENERGY_COUNTER, EnergyCounterScreen::new);
MenuScreens.register(CHEMICAL_GENERATOR, ChemicalGeneratorScreen::new);
MenuScreens.register(PLATE_PRESS, PlatePressScreen::new);
// OverdriveThatMatters.LOGGER.info("Registered screens");
}
@ -1117,4 +1138,37 @@ public class Registry {
net.minecraft.stats.Stats.CUSTOM.get(Names.POWER_CONSUMED, StatFormatter.DIVIDE_BY_TEN);
}
}
public static class Recipes {
public static class MatteryRecipeType<T extends Recipe<?>> implements RecipeType<T> {
public final ResourceLocation name;
private MatteryRecipeType(ResourceLocation name) {
this.name = name;
}
private void register() {
net.minecraft.core.Registry.register(net.minecraft.core.Registry.RECIPE_TYPE, name, this);
}
@Override
public String toString() {
return name.toString();
}
}
public static final MatteryRecipeType<PlatePressRecipe> PLATE_PRESS = new MatteryRecipeType<>(Names.PLATE_PRESS);
@SubscribeEvent
@SuppressWarnings("unused")
public static void register(final FMLCommonSetupEvent event) {
PLATE_PRESS.register();
}
@SubscribeEvent
@SuppressWarnings("unused")
public static void register(final RegistryEvent.Register<RecipeSerializer<?>> event) {
event.getRegistry().register(PlatePressRecipeFactory.INSTANCE);
}
}
}

View File

@ -12,14 +12,13 @@ import javax.annotation.ParametersAreNonnullByDefault;
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
public record MachineJob(ItemStack stack, double ticks, Fraction power,
CompoundTag data) {
public MachineJob(ItemStack stack, double ticks_processing_time, Fraction power_consumption_multiplier) {
this(stack, ticks_processing_time, power_consumption_multiplier, new CompoundTag());
public record MachineJob(ItemStack stack, double ticks, Fraction power, CompoundTag data) {
public MachineJob(ItemStack stack, double ticks, Fraction power) {
this(stack, ticks, power, new CompoundTag());
}
public MachineJob(ItemStack stack, double ticks_processing_time) {
this(stack, ticks_processing_time, Fraction.ZERO);
public MachineJob(ItemStack stack, double ticks) {
this(stack, ticks, Fraction.ZERO);
}
public CompoundTag serializeNBT() {

View File

@ -1,11 +1,16 @@
package ru.dbotthepony.mc.otm
import com.google.gson.JsonArray
import com.google.gson.JsonElement
import com.google.gson.JsonObject
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.core.Vec3i
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.ListTag
import net.minecraft.nbt.Tag
import net.minecraft.world.Container
import net.minecraft.world.item.ItemStack
import net.minecraft.world.phys.Vec3
import java.util.function.Consumer
@ -25,6 +30,11 @@ operator fun CompoundTag.set(s: String, value: Boolean) = putBoolean(s, value)
operator fun CompoundTag.set(s: String, value: ByteArray) = putByteArray(s, value)
operator fun CompoundTag.set(s: String, value: LongArray) = putLongArray(s, value)
operator fun Container.set(index: Int, value: ItemStack) = setItem(index, value)
operator fun Container.get(index: Int): ItemStack = getItem(index)
operator fun JsonObject.set(s: String, value: JsonElement) = add(s, value)
inline fun CompoundTag.ifHas(s: String, consumer: (Tag) -> Unit) {
val tag = get(s)

View File

@ -0,0 +1,28 @@
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.Registry
import ru.dbotthepony.mc.otm.block.entity.BlockEntityPlatePress
class BlockPlatePress(properties: Properties = DEFAULT_PROPERTIES) : BlockMatteryRotatable(properties), EntityBlock {
override fun newBlockEntity(p_153215_: BlockPos, p_153216_: BlockState): BlockEntity {
return BlockEntityPlatePress(p_153215_, p_153216_)
}
override fun <T : BlockEntity?> getTicker(
p_153212_: Level,
p_153213_: BlockState,
p_153214_: BlockEntityType<T>
): BlockEntityTicker<T>? {
if (p_153212_.isClientSide || p_153214_ !== Registry.BlockEntities.PLATE_PRESS)
return null
return BlockEntityTicker { _, _, _, tile -> if (tile is BlockEntityPlatePress) tile.basicTicker() }
}
}

View File

@ -0,0 +1,79 @@
package ru.dbotthepony.mc.otm.block.entity
import net.minecraft.core.BlockPos
import net.minecraft.nbt.CompoundTag
import net.minecraft.network.chat.TranslatableComponent
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.level.block.state.BlockState
import ru.dbotthepony.mc.otm.Registry
import ru.dbotthepony.mc.otm.block.entity.worker.BlockEntityMatteryWorker
import ru.dbotthepony.mc.otm.block.entity.worker.MachineJob
import ru.dbotthepony.mc.otm.block.entity.worker.MachineJobStatus
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage
import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.container.MatteryContainerFilter
import ru.dbotthepony.mc.otm.core.Fraction
import ru.dbotthepony.mc.otm.menu.PlatePressMenu
import ru.dbotthepony.mc.otm.set
class BlockEntityPlatePress(p_155229_: BlockPos, p_155230_: BlockState) : BlockEntityMatteryWorker(Registry.BlockEntities.PLATE_PRESS, p_155229_, p_155230_) {
val container = MatteryContainer(this::setChangedLight, 2)
val handler = container.handler(object : MatteryContainerFilter {
override fun canInsert(slot: Int, stack: ItemStack): Boolean {
return slot != SLOT_OUTPUT
}
override fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean {
return slot != SLOT_INPUT
}
})
init {
energy = MatteryMachineEnergyStorage(this::setChangedLight, MatteryMachineEnergyStorage.MachineType.WORKER)
}
override fun getDefaultDisplayName() = NAME
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
return PlatePressMenu(containerID, inventory, this)
}
override fun onJobFinish(job: MachineJob): MachineJobStatus {
val resultTag = job.data["result"] as? CompoundTag ?: return MachineJobStatus()
val result = ItemStack.of(resultTag)
if (result.isEmpty)
return MachineJobStatus()
if (!container.fullyAddItem(result, start = SLOT_OUTPUT, end = SLOT_OUTPUT)) {
return MachineJobStatus(false, 20)
}
return MachineJobStatus()
}
override fun computeNextJob(): MachineJob? {
val level = level ?: return null
val recipe = level.recipeManager.getRecipeFor(Registry.Recipes.PLATE_PRESS, container, level).orElse(null) ?: return null
val copy = container[SLOT_INPUT].copy()
container[SLOT_INPUT].shrink(1)
container.setChanged(SLOT_INPUT)
copy.count = 1
return MachineJob(copy, recipe.workTime.toDouble(), BASELINE_CONSUMPTION, CompoundTag().also {
it["result"] = recipe.resultItem.serializeNBT()
})
}
companion object {
private val BASELINE_CONSUMPTION = Fraction(15)
private val NAME = TranslatableComponent("block.overdrive_that_matters.plate_press")
const val SLOT_INPUT = 0
const val SLOT_OUTPUT = 1
}
}

View File

@ -33,10 +33,10 @@ abstract class BlockEntityMatteryWorker(p_155228_: BlockEntityType<*>, p_155229_
val isUnableToProcess: Boolean get() = throttleTicks > 0
val workProgress: Double
val workProgress: Float
get() {
val currentJob = currentJob ?: return 0.0
return (workTicks / currentJob.ticks()).coerceAtMost(1.0)
val currentJob = currentJob ?: return 0.0f
return (workTicks / currentJob.ticks).coerceAtMost(1.0).toFloat()
}
override fun saveAdditional(nbt: CompoundTag) {

View File

@ -21,7 +21,7 @@ open class MatteryMachineEnergyStorage @JvmOverloads constructor(
type: MachineType,
maxBatteryLevel: Fraction = DEFAULT_MAX_CAPACITY,
maxInput: Fraction = DEFAULT_MAX_RECEIVE,
maxOutput: Fraction = maxInput) : this({listener.setChanged()}, type, maxBatteryLevel, maxInput, maxOutput)
maxOutput: Fraction = DEFAULT_MAX_EXTRACT) : this({listener.setChanged()}, type, maxBatteryLevel, maxInput, maxOutput)
enum class MachineType {
WORKER, GENERATOR, CAPACITOR
@ -97,7 +97,7 @@ open class MatteryMachineEnergyStorage @JvmOverloads constructor(
companion object {
val DEFAULT_MAX_RECEIVE = Fraction(200)
val DEFAULT_MAX_EXTRACT = Fraction(200)
val DEFAULT_MAX_EXTRACT = DEFAULT_MAX_RECEIVE
val DEFAULT_MAX_CAPACITY = Fraction(60000)
}
}

View File

@ -0,0 +1,25 @@
package ru.dbotthepony.mc.otm.client.screen
import net.minecraft.network.chat.Component
import net.minecraft.world.entity.player.Inventory
import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel
import ru.dbotthepony.mc.otm.client.screen.panels.SlotPanel
import ru.dbotthepony.mc.otm.client.screen.widget.PowerGaugePanel
import ru.dbotthepony.mc.otm.client.screen.widget.ProgressGaugePanel
import ru.dbotthepony.mc.otm.menu.PlatePressMenu
class PlatePressScreen(menu: PlatePressMenu, inventory: Inventory, title: Component) :
MatteryScreen<PlatePressMenu>(menu, inventory, title) {
override fun makeMainFrame(): FramePanel {
val frame = super.makeMainFrame()!!
PowerGaugePanel(this, frame, menu.powerWidget, LEFT_MARGIN, GAUGE_TOP_WITH_SLOT)
SlotPanel(this, frame, menu.batterySlot, LEFT_MARGIN, SLOT_TOP_UNDER_GAUGE)
SlotPanel(this, frame, menu.inputSlot, 56f, PROGRESS_SLOT_TOP)
ProgressGaugePanel(this, frame, menu.progressGauge, 78f, PROGRESS_ARROW_TOP)
SlotPanel(this, frame, menu.outputSlot, 104f, PROGRESS_SLOT_TOP)
return frame
}
}

View File

@ -157,14 +157,14 @@ open class MatteryContainer(val watcher: Runnable, private val size: Int) : Cont
open fun getMaxStackSize(slot: Int) = maxStackSize
@JvmOverloads
fun addItem(stack: ItemStack, start: Int = 0, end: Int = size, simulate: Boolean = false): ItemStack {
if (stack.isEmpty || start < 0 || end > size || start >= end)
return ItemStack.EMPTY
fun addItem(stack: ItemStack, start: Int = 0, end: Int = size - 1, simulate: Boolean = false): ItemStack {
if (stack.isEmpty || start < 0 || end >= size || start > end)
return stack
val copy = stack.copy()
// двигаем в одинаковые слоты
for (slot in start until end) {
for (slot in start .. end) {
if (ItemStack.isSameItemSameTags(slots[slot], copy)) {
val slotStack = slots[slot]
val slotLimit = Math.min(getMaxStackSize(slot), slotStack.maxStackSize)
@ -190,7 +190,7 @@ open class MatteryContainer(val watcher: Runnable, private val size: Int) : Cont
}
// двигаем в пустые слоты
for (slot in start until end) {
for (slot in start .. end) {
if (slots[slot].isEmpty) {
val diff = Math.min(copy.count, Math.min(getMaxStackSize(slot), copy.maxStackSize))
@ -212,11 +212,11 @@ open class MatteryContainer(val watcher: Runnable, private val size: Int) : Cont
}
fun addItem(stack: ItemStack, simulate: Boolean): ItemStack {
return addItem(stack, 0, size, simulate)
return addItem(stack, 0, size - 1, simulate)
}
@JvmOverloads
fun fullyAddItem(stack: ItemStack, start: Int = 0, end: Int = size): Boolean {
fun fullyAddItem(stack: ItemStack, start: Int = 0, end: Int = size - 1): Boolean {
if (!addItem(stack, start, end, true).isEmpty)
return false

View File

@ -0,0 +1,29 @@
package ru.dbotthepony.mc.otm.menu
import net.minecraft.world.SimpleContainer
import net.minecraft.world.entity.player.Inventory
import ru.dbotthepony.mc.otm.Registry
import ru.dbotthepony.mc.otm.block.entity.BlockEntityPlatePress
import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget
class PlatePressMenu @JvmOverloads constructor(
containerID: Int,
inventory: Inventory,
tile: BlockEntityPlatePress? = null
) : PoweredMatteryMenu(Registry.Menus.PLATE_PRESS, containerID, inventory, tile) {
val container = tile?.container ?: SimpleContainer(2)
val inputSlot = MatterySlot(container, BlockEntityPlatePress.SLOT_INPUT)
val outputSlot = MachineOutputSlot(container, BlockEntityPlatePress.SLOT_OUTPUT)
val progressGauge = if (tile != null) ProgressGaugeWidget(this, tile::workProgress, tile::isUnableToProcess) else ProgressGaugeWidget(this)
init {
addSlot(inputSlot)
addSlot(outputSlot)
addInventorySlots()
}
override fun getWorkingSlotStart() = 0
override fun getWorkingSlotEnd() = 2
}

View File

@ -0,0 +1,57 @@
package ru.dbotthepony.mc.otm.recipes
import com.google.gson.JsonElement
import com.google.gson.JsonObject
import com.google.gson.JsonPrimitive
import net.minecraft.data.structures.SnbtToNbt
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items
import net.minecraftforge.registries.ForgeRegistries
import ru.dbotthepony.mc.otm.set
fun stackFromJson(obj: JsonElement, field: String = "<unknown>"): ItemStack {
if (obj is JsonPrimitive) {
check(obj.isString) { "Field $field is supposed to be an Item, but it is malformed (not a string and not an object)" }
val item = ForgeRegistries.ITEMS.getValue(ResourceLocation(obj.asString)) ?: return ItemStack.EMPTY
if (item === Items.AIR) {
return ItemStack.EMPTY
}
return ItemStack(item, 1)
}
if (obj is JsonObject) {
val name = obj["name"] as? JsonPrimitive ?: throw IllegalStateException("Invalid name of $field")
check(name.isString) { "Invalid name of $field (supposed to be a string)" }
val item = ForgeRegistries.ITEMS.getValue(ResourceLocation(name.asString)) ?: return ItemStack.EMPTY
val count = (obj["count"] as? JsonPrimitive)?.let {
try {
return@let it.asInt
} catch(err: Throwable) {
throw IllegalStateException("Invalid format of count of $field (supposed to be a number)", err)
}
} ?: 1
check(count > 0) { "Field count of $field does not make any sense" }
return ItemStack(item, count)
}
throw IllegalStateException("Invalid or missing $field")
}
fun stackToJson(stack: ItemStack, field: String = "<unknown>"): JsonElement {
check(stack.count > 0) { "ItemStack $field is empty" }
if (stack.count == 1) {
return JsonPrimitive(stack.item.registryName!!.toString())
}
return JsonObject().also {
it["name"] = JsonPrimitive(stack.item.registryName!!.toString())
it["count"] = JsonPrimitive(stack.count)
}
}

View File

@ -0,0 +1,107 @@
package ru.dbotthepony.mc.otm.recipes
import com.google.gson.JsonObject
import com.google.gson.JsonPrimitive
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.Container
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.crafting.Ingredient
import net.minecraft.world.item.crafting.Recipe
import net.minecraft.world.item.crafting.RecipeSerializer
import net.minecraft.world.item.crafting.RecipeType
import net.minecraft.world.level.Level
import net.minecraftforge.registries.ForgeRegistryEntry
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.Registry
import ru.dbotthepony.mc.otm.block.entity.BlockEntityPlatePress
import ru.dbotthepony.mc.otm.get
class PlatePressRecipe(
private val id: ResourceLocation,
val input: Ingredient,
val output: Ingredient,
val count: Int,
val workTime: Int = 200
) : Recipe<Container> {
override fun matches(container: Container, p_44003_: Level): Boolean {
if (output.isEmpty || input.isEmpty)
return false
return input.test(container[BlockEntityPlatePress.SLOT_INPUT])
}
private var outputStack: ItemStack? = null
override fun assemble(p_44001_: Container): ItemStack = resultItem.copy()
override fun canCraftInDimensions(p_43999_: Int, p_44000_: Int) = true
override fun getResultItem(): ItemStack {
if (outputStack == null) {
if (output.isEmpty) {
outputStack = ItemStack.EMPTY
} else {
val items = output.items
var bestMatch = items[0]
// прежде всего выдавать предметы из OTM
for (item in items) {
if (item.item.registryName?.namespace == OverdriveThatMatters.MOD_ID) {
bestMatch = item
break
}
}
outputStack = bestMatch.copy()
outputStack!!.count = this.count
}
}
return outputStack!!
}
override fun getId() = id
override fun getSerializer(): RecipeSerializer<*> {
return PlatePressRecipeFactory
}
override fun getType(): RecipeType<PlatePressRecipe> = Registry.Recipes.PLATE_PRESS
}
object PlatePressRecipeFactory : ForgeRegistryEntry<RecipeSerializer<*>>(), RecipeSerializer<PlatePressRecipe> {
init {
registryName = Registry.Names.PLATE_PRESS
}
override fun fromJson(loc: ResourceLocation, obj: JsonObject): PlatePressRecipe {
val input = try {
Ingredient.fromJson(obj["input"] ?: throw IllegalStateException("Recipe $loc has no input field defined"))
} catch (err: Throwable) {
throw IllegalStateException("Input of $loc is malformed", err)
}
val result = try {
Ingredient.fromJson(obj["result"] ?: throw IllegalStateException("Recipe $loc has no result field defined"))
} catch (err: Throwable) {
throw IllegalStateException("Result of $loc is malformed", err)
}
val workTime = (obj["work_time"] as? JsonPrimitive)?.let { return@let try {it.asInt} catch(err: Throwable) {throw IllegalStateException("Invalid work_time")} } ?: 200
check(workTime >= 0) { "work_time of $loc does not make any sense" }
val count = ((obj["result"] as JsonObject)["count"] as? JsonPrimitive)?.let { return@let try {it.asInt} catch(err: Throwable) {throw IllegalStateException("Invalid result.count")} } ?: 1
return PlatePressRecipe(loc, input, result, count, workTime)
}
override fun fromNetwork(loc: ResourceLocation, buff: FriendlyByteBuf): PlatePressRecipe {
return PlatePressRecipe(loc, Ingredient.fromNetwork(buff), Ingredient.fromNetwork(buff), buff.readInt())
}
override fun toNetwork(buff: FriendlyByteBuf, recipe: PlatePressRecipe) {
recipe.input.toNetwork(buff)
recipe.output.toNetwork(buff)
buff.writeInt(recipe.workTime)
}
}

View File

@ -165,6 +165,7 @@
"block.overdrive_that_matters.chemical_generator": "Chemical Generator",
"block.overdrive_that_matters.drive_rack": "Condensation Drive Rack",
"block.overdrive_that_matters.item_monitor": "Item Monitor",
"block.overdrive_that_matters.plate_press": "Plate Press",
"otm.container.matter_panel.number_input": "Input replication task count",