Merge branch 'master' of https://git.dbotthepony.ru/DBot/overdrive_that_matters
This commit is contained in:
commit
00b8e546b0
@ -14,7 +14,7 @@ import net.minecraftforge.fml.common.Mod
|
|||||||
import net.minecraftforge.data.event.GatherDataEvent
|
import net.minecraftforge.data.event.GatherDataEvent
|
||||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||||
import ru.dbotthepony.mc.otm.block.*
|
import ru.dbotthepony.mc.otm.block.*
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState
|
import ru.dbotthepony.mc.otm.block.entity.WorkerState
|
||||||
import ru.dbotthepony.mc.otm.block.matter.MatterBottlerBlock
|
import ru.dbotthepony.mc.otm.block.matter.MatterBottlerBlock
|
||||||
import ru.dbotthepony.mc.otm.block.matter.PatternStorageBlock
|
import ru.dbotthepony.mc.otm.block.matter.PatternStorageBlock
|
||||||
import ru.dbotthepony.mc.otm.block.storage.DriveViewerBlock
|
import ru.dbotthepony.mc.otm.block.storage.DriveViewerBlock
|
||||||
@ -30,7 +30,7 @@ import ru.dbotthepony.mc.otm.datagen.models.BlockMatteryModelProvider
|
|||||||
import ru.dbotthepony.mc.otm.datagen.recipes.MatteryRecipeProvider
|
import ru.dbotthepony.mc.otm.datagen.recipes.MatteryRecipeProvider
|
||||||
import ru.dbotthepony.mc.otm.datagen.recipes.has
|
import ru.dbotthepony.mc.otm.datagen.recipes.has
|
||||||
import ru.dbotthepony.mc.otm.registry.*
|
import ru.dbotthepony.mc.otm.registry.*
|
||||||
import ru.dbotthepony.mc.otm.*
|
import ru.dbotthepony.mc.otm.core.registryName
|
||||||
import ru.dbotthepony.mc.otm.datagen.lang.MatteryLanguageProvider
|
import ru.dbotthepony.mc.otm.datagen.lang.MatteryLanguageProvider
|
||||||
import ru.dbotthepony.mc.otm.datagen.loot.addLootModifiers
|
import ru.dbotthepony.mc.otm.datagen.loot.addLootModifiers
|
||||||
import ru.dbotthepony.mc.otm.datagen.recipes.addCraftingTableRecipes
|
import ru.dbotthepony.mc.otm.datagen.recipes.addCraftingTableRecipes
|
||||||
|
@ -7,12 +7,12 @@ import net.minecraftforge.client.model.generators.BlockStateProvider
|
|||||||
import net.minecraftforge.client.model.generators.ConfiguredModel
|
import net.minecraftforge.client.model.generators.ConfiguredModel
|
||||||
import net.minecraftforge.data.event.GatherDataEvent
|
import net.minecraftforge.data.event.GatherDataEvent
|
||||||
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
|
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState
|
import ru.dbotthepony.mc.otm.block.entity.WorkerState
|
||||||
import ru.dbotthepony.mc.otm.datagen.DataGen
|
import ru.dbotthepony.mc.otm.datagen.DataGen
|
||||||
import ru.dbotthepony.mc.otm.datagen.getValueNullable
|
import ru.dbotthepony.mc.otm.datagen.getValueNullable
|
||||||
import ru.dbotthepony.mc.otm.datagen.toXRotBlockstate
|
import ru.dbotthepony.mc.otm.datagen.toXRotBlockstate
|
||||||
import ru.dbotthepony.mc.otm.datagen.toYRotBlockstate
|
import ru.dbotthepony.mc.otm.datagen.toYRotBlockstate
|
||||||
import ru.dbotthepony.mc.otm.registryName
|
import ru.dbotthepony.mc.otm.core.registryName
|
||||||
|
|
||||||
typealias AdvancedBlockStateFunction = (BlockState, ConfiguredModel.Builder<*>, String) -> String?
|
typealias AdvancedBlockStateFunction = (BlockState, ConfiguredModel.Builder<*>, String) -> String?
|
||||||
private data class AdvancedBlockStateEntry(val block: Block, val func: AdvancedBlockStateFunction)
|
private data class AdvancedBlockStateEntry(val block: Block, val func: AdvancedBlockStateFunction)
|
||||||
|
@ -6,7 +6,7 @@ import net.minecraftforge.client.model.generators.ItemModelProvider
|
|||||||
import net.minecraftforge.data.event.GatherDataEvent
|
import net.minecraftforge.data.event.GatherDataEvent
|
||||||
import org.apache.logging.log4j.LogManager
|
import org.apache.logging.log4j.LogManager
|
||||||
import ru.dbotthepony.mc.otm.datagen.DataGen
|
import ru.dbotthepony.mc.otm.datagen.DataGen
|
||||||
import ru.dbotthepony.mc.otm.registryName
|
import ru.dbotthepony.mc.otm.core.registryName
|
||||||
|
|
||||||
private data class SimpleItemModel(val item: String, val path: ResourceLocation) {
|
private data class SimpleItemModel(val item: String, val path: ResourceLocation) {
|
||||||
val traceback = IllegalArgumentException("Failed to register model")
|
val traceback = IllegalArgumentException("Failed to register model")
|
||||||
|
@ -53,6 +53,10 @@ private fun misc(provider: MatteryLanguageProvider) {
|
|||||||
|
|
||||||
gui("exosuit.already_activated", "You already have exosuit following you")
|
gui("exosuit.already_activated", "You already have exosuit following you")
|
||||||
|
|
||||||
|
gui("power_supplier.active_nodes", "Currently demanding nodes: %s")
|
||||||
|
|
||||||
|
misc("battery.single_use", "Single use battery, can not be recharged.")
|
||||||
|
|
||||||
misc("exosuit.granted1", "As you keep pressing fingerprint reader, you are getting hurt in finger.")
|
misc("exosuit.granted1", "As you keep pressing fingerprint reader, you are getting hurt in finger.")
|
||||||
misc("exosuit.granted2", "After you raise your finger, fingerprint reader glows very bright.")
|
misc("exosuit.granted2", "After you raise your finger, fingerprint reader glows very bright.")
|
||||||
misc("exosuit.granted3", "Then, fingerprint reader fades, leaving faint trace not of your finger, but of your very soul.")
|
misc("exosuit.granted3", "Then, fingerprint reader fades, leaving faint trace not of your finger, but of your very soul.")
|
||||||
@ -128,6 +132,9 @@ private fun misc(provider: MatteryLanguageProvider) {
|
|||||||
misc("item.power.normal.storage", "Stored energy: %s / %s")
|
misc("item.power.normal.storage", "Stored energy: %s / %s")
|
||||||
misc("item.power.normal.throughput", "Max I/O %s / %s")
|
misc("item.power.normal.throughput", "Max I/O %s / %s")
|
||||||
|
|
||||||
|
misc("item.power.output_only", "Max output %s")
|
||||||
|
misc("item.power.input_only", "Max input %s")
|
||||||
|
|
||||||
misc("item.pattern.stored", "Stored patterns: %s / %s")
|
misc("item.pattern.stored", "Stored patterns: %s / %s")
|
||||||
misc("item.pattern.infinite.stored", "Stored patterns %s")
|
misc("item.pattern.infinite.stored", "Stored patterns %s")
|
||||||
misc("item.pattern.line", "%s [%s%%]")
|
misc("item.pattern.line", "%s [%s%%]")
|
||||||
@ -377,6 +384,9 @@ private fun items(provider: MatteryLanguageProvider) {
|
|||||||
add(MItems.TRITANIUM_ORE_CLUMP, "Raw Tritanium")
|
add(MItems.TRITANIUM_ORE_CLUMP, "Raw Tritanium")
|
||||||
add(MItems.PATTERN_DRIVE_NORMAL, "Pattern Drive")
|
add(MItems.PATTERN_DRIVE_NORMAL, "Pattern Drive")
|
||||||
add(MItems.PATTERN_DRIVE_CREATIVE, "Creative Pattern Drive")
|
add(MItems.PATTERN_DRIVE_CREATIVE, "Creative Pattern Drive")
|
||||||
|
|
||||||
|
add(MItems.ZPM_BATTERY, "Zero Point Module")
|
||||||
|
add(MItems.ZPM_BATTERY, "description", "Can be found in hands of those who travel between dimensions, if they ever reached different reality of origin of these constructs...")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,11 +39,12 @@ fun addLootModifiers(it: LootModifiers) {
|
|||||||
ItemStack(MItems.PILL_ANDROID, 1) to 0.5
|
ItemStack(MItems.PILL_ANDROID, 1) to 0.5
|
||||||
))
|
))
|
||||||
|
|
||||||
it.add("end_city_pill", LootTableBasicAppender(
|
it.add("end_city_modifications", LootTableBasicAppender(
|
||||||
arrayOf(LootTableIdCondition.Builder(ResourceLocation("chests/end_city_treasure")).build()),
|
arrayOf(LootTableIdCondition.Builder(ResourceLocation("chests/end_city_treasure")).build()),
|
||||||
ItemStack(MItems.PILL_ANDROID, 1) to 0.1,
|
ItemStack(MItems.PILL_ANDROID, 1) to 0.1,
|
||||||
ItemStack(MItems.PILL_HUMANE, 1) to 0.3,
|
ItemStack(MItems.PILL_HUMANE, 1) to 0.3,
|
||||||
ItemStack(MItems.PILL_OBLIVION, 1) to 0.5,
|
ItemStack(MItems.PILL_OBLIVION, 1) to 0.5,
|
||||||
|
ItemStack(MItems.ZPM_BATTERY, 1) to 0.005,
|
||||||
))
|
))
|
||||||
|
|
||||||
it.add("shipwreck_supply_pill", LootTableBasicAppender(
|
it.add("shipwreck_supply_pill", LootTableBasicAppender(
|
||||||
|
@ -9,7 +9,8 @@ import net.minecraft.core.Direction
|
|||||||
import net.minecraft.resources.ResourceLocation
|
import net.minecraft.resources.ResourceLocation
|
||||||
import net.minecraftforge.client.model.generators.ModelBuilder
|
import net.minecraftforge.client.model.generators.ModelBuilder
|
||||||
import net.minecraftforge.common.data.ExistingFileHelper
|
import net.minecraftforge.common.data.ExistingFileHelper
|
||||||
import ru.dbotthepony.mc.otm.set
|
import ru.dbotthepony.mc.otm.container.set
|
||||||
|
import ru.dbotthepony.mc.otm.core.set
|
||||||
|
|
||||||
data class TextureSize(val width: Float, val height: Float) {
|
data class TextureSize(val width: Float, val height: Float) {
|
||||||
constructor(arr: JsonArray) : this(arr[0].asFloat, arr[1].asFloat)
|
constructor(arr: JsonArray) : this(arr[0].asFloat, arr[1].asFloat)
|
||||||
|
@ -8,7 +8,7 @@ import net.minecraft.world.level.block.Block
|
|||||||
import net.minecraftforge.client.model.generators.ModelProvider
|
import net.minecraftforge.client.model.generators.ModelProvider
|
||||||
import net.minecraftforge.data.event.GatherDataEvent
|
import net.minecraftforge.data.event.GatherDataEvent
|
||||||
import ru.dbotthepony.mc.otm.datagen.DataGen
|
import ru.dbotthepony.mc.otm.datagen.DataGen
|
||||||
import ru.dbotthepony.mc.otm.registryName
|
import ru.dbotthepony.mc.otm.core.registryName
|
||||||
|
|
||||||
private typealias Callback = (MatteryModelProvider) -> Unit
|
private typealias Callback = (MatteryModelProvider) -> Unit
|
||||||
|
|
||||||
|
@ -4,8 +4,6 @@ import net.minecraft.data.recipes.FinishedRecipe
|
|||||||
import net.minecraft.data.recipes.ShapedRecipeBuilder
|
import net.minecraft.data.recipes.ShapedRecipeBuilder
|
||||||
import net.minecraft.data.recipes.ShapelessRecipeBuilder
|
import net.minecraft.data.recipes.ShapelessRecipeBuilder
|
||||||
import net.minecraft.resources.ResourceLocation
|
import net.minecraft.resources.ResourceLocation
|
||||||
import net.minecraft.tags.TagKey
|
|
||||||
import net.minecraft.world.item.Item
|
|
||||||
import net.minecraft.world.item.Items
|
import net.minecraft.world.item.Items
|
||||||
import net.minecraft.world.item.crafting.Ingredient
|
import net.minecraft.world.item.crafting.Ingredient
|
||||||
import net.minecraftforge.common.Tags
|
import net.minecraftforge.common.Tags
|
||||||
@ -15,7 +13,7 @@ import ru.dbotthepony.mc.otm.registry.MBlocks
|
|||||||
import ru.dbotthepony.mc.otm.registry.MItemTags
|
import ru.dbotthepony.mc.otm.registry.MItemTags
|
||||||
import ru.dbotthepony.mc.otm.registry.MItems
|
import ru.dbotthepony.mc.otm.registry.MItems
|
||||||
import ru.dbotthepony.mc.otm.registry.MRegistry
|
import ru.dbotthepony.mc.otm.registry.MRegistry
|
||||||
import ru.dbotthepony.mc.otm.registryName
|
import ru.dbotthepony.mc.otm.core.registryName
|
||||||
import java.util.function.Consumer
|
import java.util.function.Consumer
|
||||||
|
|
||||||
fun addCraftingTableRecipes(consumer: Consumer<FinishedRecipe>) {
|
fun addCraftingTableRecipes(consumer: Consumer<FinishedRecipe>) {
|
||||||
@ -55,6 +53,22 @@ fun addCraftingTableRecipes(consumer: Consumer<FinishedRecipe>) {
|
|||||||
.build(consumer)
|
.build(consumer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MatteryRecipe(MBlocks.PLATE_PRESS)
|
||||||
|
.row(MItems.ELECTRIC_PARTS, MItems.ENERGY_BUS, MItems.ELECTRIC_PARTS)
|
||||||
|
.row(MItemTags.INGOT_TRITANIUM, Items.BLAST_FURNACE, MItemTags.INGOT_TRITANIUM)
|
||||||
|
.row(MItemTags.PISTONS, MItemTags.INGOT_TRITANIUM, MItemTags.PISTONS)
|
||||||
|
.unlockedBy(MItemTags.INGOT_TRITANIUM)
|
||||||
|
.unlockedBy(MItems.ELECTRIC_PARTS)
|
||||||
|
.build(consumer)
|
||||||
|
|
||||||
|
MatteryRecipe(MBlocks.PLATE_PRESS)
|
||||||
|
.rowB(MItemTags.BASIC_CIRCUIT)
|
||||||
|
.row(MItemTags.PLATE_TRITANIUM, MItems.MACHINE_FRAME, MItemTags.PLATE_TRITANIUM)
|
||||||
|
.rowAC(MItemTags.PISTONS, MItemTags.PISTONS)
|
||||||
|
.unlockedBy(MItemTags.INGOT_TRITANIUM)
|
||||||
|
.unlockedBy(MItems.ELECTRIC_PARTS)
|
||||||
|
.build(consumer, "advanced")
|
||||||
|
|
||||||
MatteryRecipe(MBlocks.TRITANIUM_STRIPED_BLOCK, 24)
|
MatteryRecipe(MBlocks.TRITANIUM_STRIPED_BLOCK, 24)
|
||||||
.rowB(MItemTags.PLATE_TRITANIUM)
|
.rowB(MItemTags.PLATE_TRITANIUM)
|
||||||
.row(MItemTags.PLATE_TRITANIUM, COBBLESTONE, MItemTags.PLATE_TRITANIUM)
|
.row(MItemTags.PLATE_TRITANIUM, COBBLESTONE, MItemTags.PLATE_TRITANIUM)
|
||||||
|
@ -11,7 +11,7 @@ import net.minecraft.world.item.Item
|
|||||||
import net.minecraft.world.item.crafting.Ingredient
|
import net.minecraft.world.item.crafting.Ingredient
|
||||||
import net.minecraft.world.level.ItemLike
|
import net.minecraft.world.level.ItemLike
|
||||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||||
import ru.dbotthepony.mc.otm.registryName
|
import ru.dbotthepony.mc.otm.core.registryName
|
||||||
import java.util.function.Consumer
|
import java.util.function.Consumer
|
||||||
|
|
||||||
private interface RecipeCell {
|
private interface RecipeCell {
|
||||||
|
@ -7,7 +7,8 @@ import net.minecraft.resources.ResourceLocation
|
|||||||
import net.minecraft.world.item.crafting.RecipeSerializer
|
import net.minecraft.world.item.crafting.RecipeSerializer
|
||||||
import ru.dbotthepony.mc.otm.recipe.PlatePressRecipe
|
import ru.dbotthepony.mc.otm.recipe.PlatePressRecipe
|
||||||
import ru.dbotthepony.mc.otm.recipe.PlatePressRecipeFactory
|
import ru.dbotthepony.mc.otm.recipe.PlatePressRecipeFactory
|
||||||
import ru.dbotthepony.mc.otm.set
|
import ru.dbotthepony.mc.otm.container.set
|
||||||
|
import ru.dbotthepony.mc.otm.core.set
|
||||||
|
|
||||||
class PlatePressFinishedRecipe(private val recipe: PlatePressRecipe) : FinishedRecipe {
|
class PlatePressFinishedRecipe(private val recipe: PlatePressRecipe) : FinishedRecipe {
|
||||||
override fun serializeRecipeData(it: JsonObject) {
|
override fun serializeRecipeData(it: JsonObject) {
|
||||||
|
@ -2,8 +2,10 @@ package ru.dbotthepony.mc.otm;
|
|||||||
|
|
||||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
import net.minecraft.MethodsReturnNonnullByDefault;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.item.CreativeModeTab;
|
import net.minecraft.world.item.CreativeModeTab;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
import net.minecraftforge.eventbus.api.EventPriority;
|
import net.minecraftforge.eventbus.api.EventPriority;
|
||||||
import net.minecraftforge.fml.ModList;
|
import net.minecraftforge.fml.ModList;
|
||||||
@ -15,15 +17,15 @@ import org.apache.logging.log4j.LogManager;
|
|||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import ru.dbotthepony.mc.otm.block.entity.blackhole.ExplosionQueue;
|
import ru.dbotthepony.mc.otm.block.entity.blackhole.ExplosionQueue;
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability;
|
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability;
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
|
|
||||||
import ru.dbotthepony.mc.otm.capability.drive.DrivePool;
|
import ru.dbotthepony.mc.otm.capability.drive.DrivePool;
|
||||||
|
import ru.dbotthepony.mc.otm.client.ClientEventHandler;
|
||||||
import ru.dbotthepony.mc.otm.client.MatteryGUI;
|
import ru.dbotthepony.mc.otm.client.MatteryGUI;
|
||||||
import ru.dbotthepony.mc.otm.client.EventHandlerKt;
|
|
||||||
import ru.dbotthepony.mc.otm.client.model.GravitationStabilizerModel;
|
import ru.dbotthepony.mc.otm.client.model.GravitationStabilizerModel;
|
||||||
import ru.dbotthepony.mc.otm.client.model.TritaniumArmorModel;
|
import ru.dbotthepony.mc.otm.client.model.TritaniumArmorModel;
|
||||||
import ru.dbotthepony.mc.otm.compat.mekanism.QIOKt;
|
import ru.dbotthepony.mc.otm.compat.mekanism.QIOKt;
|
||||||
import ru.dbotthepony.mc.otm.compat.mekanism.TooltipsKt;
|
import ru.dbotthepony.mc.otm.compat.mekanism.TooltipsKt;
|
||||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction;
|
import ru.dbotthepony.mc.otm.core.ImpreciseFraction;
|
||||||
|
import ru.dbotthepony.mc.otm.item.QuantumBatteryItem;
|
||||||
import ru.dbotthepony.mc.otm.item.weapon.AbstractWeaponItem;
|
import ru.dbotthepony.mc.otm.item.weapon.AbstractWeaponItem;
|
||||||
import ru.dbotthepony.mc.otm.item.PortableCondensationDriveItem;
|
import ru.dbotthepony.mc.otm.item.PortableCondensationDriveItem;
|
||||||
import ru.dbotthepony.mc.otm.matter.MatterDataKt;
|
import ru.dbotthepony.mc.otm.matter.MatterDataKt;
|
||||||
@ -33,6 +35,8 @@ import ru.dbotthepony.mc.otm.registry.*;
|
|||||||
import ru.dbotthepony.mc.otm.storage.*;
|
import ru.dbotthepony.mc.otm.storage.*;
|
||||||
import ru.dbotthepony.mc.otm.worldgen.OreGen;
|
import ru.dbotthepony.mc.otm.worldgen.OreGen;
|
||||||
|
|
||||||
|
import static net.minecraftforge.common.MinecraftForge.EVENT_BUS;
|
||||||
|
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
// The value here should match an entry in the META-INF/mods.toml file
|
// The value here should match an entry in the META-INF/mods.toml file
|
||||||
@ -76,49 +80,78 @@ public final class OverdriveThatMatters {
|
|||||||
|
|
||||||
INSTANCE = this;
|
INSTANCE = this;
|
||||||
|
|
||||||
MRegistry.INSTANCE.initialize(FMLJavaModLoadingContext.get());
|
var modBus = FMLJavaModLoadingContext.get().getModEventBus();
|
||||||
|
|
||||||
FMLJavaModLoadingContext.get().getModEventBus().addListener(EventPriority.HIGHEST, this::setup);
|
MRegistry.INSTANCE.initialize(modBus);
|
||||||
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setupClient);
|
|
||||||
|
|
||||||
MinecraftForge.EVENT_BUS.register(this);
|
modBus.addListener(EventPriority.HIGHEST, this::setup);
|
||||||
MinecraftForge.EVENT_BUS.register(GlobalEventHandlerKt.class);
|
modBus.addListener(EventPriority.NORMAL, this::setupClient);
|
||||||
MinecraftForge.EVENT_BUS.register(MatteryPlayerCapability.Companion);
|
|
||||||
MinecraftForge.EVENT_BUS.register(MatterRegistryKt.class);
|
|
||||||
MinecraftForge.EVENT_BUS.register(MatterDataKt.class);
|
|
||||||
MinecraftForge.EVENT_BUS.register(ExplosionQueue.Companion);
|
|
||||||
MinecraftForge.EVENT_BUS.register(AbstractWeaponItem.Companion);
|
|
||||||
|
|
||||||
FMLJavaModLoadingContext.get().getModEventBus().register(MatteryCapability.class);
|
|
||||||
|
|
||||||
FMLJavaModLoadingContext.get().getModEventBus().register(MRecipes.class);
|
|
||||||
|
|
||||||
MinecraftForge.EVENT_BUS.register(DrivePool.INSTANCE);
|
|
||||||
MinecraftForge.EVENT_BUS.register(PortableCondensationDriveItem.Companion);
|
|
||||||
|
|
||||||
FMLJavaModLoadingContext.get().getModEventBus().addListener(MatteryPlayerCapability::registerEffects);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setup(final FMLCommonSetupEvent event) {
|
private void setup(final FMLCommonSetupEvent event) {
|
||||||
|
EVENT_BUS.addListener(EventPriority.LOWEST, DrivePool.INSTANCE::onServerPostTick);
|
||||||
|
EVENT_BUS.addListener(EventPriority.HIGHEST, DrivePool.INSTANCE::serverStopEvent);
|
||||||
|
EVENT_BUS.addListener(EventPriority.HIGHEST, DrivePool.INSTANCE::serverStartEvent);
|
||||||
|
EVENT_BUS.addListener(EventPriority.NORMAL, DrivePool.INSTANCE::onWorldSave);
|
||||||
|
|
||||||
|
EVENT_BUS.addListener(EventPriority.HIGHEST, GlobalEventHandlerKt::onServerStopped);
|
||||||
|
EVENT_BUS.addListener(EventPriority.HIGHEST, GlobalEventHandlerKt::onServerStopping);
|
||||||
|
EVENT_BUS.addListener(EventPriority.HIGHEST, GlobalEventHandlerKt::onServerStarting);
|
||||||
|
EVENT_BUS.addListener(EventPriority.LOWEST, GlobalEventHandlerKt::onWorldTick);
|
||||||
|
EVENT_BUS.addListener(EventPriority.LOWEST, GlobalEventHandlerKt::onServerTick);
|
||||||
|
|
||||||
|
EVENT_BUS.addListener(EventPriority.NORMAL, MatteryPlayerCapability.Companion::onLivingTick);
|
||||||
|
EVENT_BUS.addListener(EventPriority.NORMAL, MatteryPlayerCapability.Companion::onHurtEvent);
|
||||||
|
EVENT_BUS.addGenericListener(Entity.class, EventPriority.NORMAL, MatteryPlayerCapability.Companion::onAttachCapabilityEvent);
|
||||||
|
EVENT_BUS.addListener(EventPriority.NORMAL, MatteryPlayerCapability.Companion::onPlayerChangeDimensionEvent);
|
||||||
|
EVENT_BUS.addListener(EventPriority.LOWEST, MatteryPlayerCapability.Companion::onPlayerDeath);
|
||||||
|
EVENT_BUS.addListener(EventPriority.NORMAL, MatteryPlayerCapability.Companion::onPlayerCloneEvent);
|
||||||
|
EVENT_BUS.addListener(EventPriority.LOW, MatteryPlayerCapability.Companion::onPickupEvent);
|
||||||
|
|
||||||
|
EVENT_BUS.addListener(EventPriority.LOW, MatterDataKt::serverStartData);
|
||||||
|
EVENT_BUS.addListener(EventPriority.NORMAL, MatterRegistryKt::onPlayerJoin);
|
||||||
|
EVENT_BUS.addListener(EventPriority.NORMAL, ExplosionQueue.Companion::onWorldTick);
|
||||||
|
EVENT_BUS.addListener(EventPriority.NORMAL, AbstractWeaponItem.Companion::tick);
|
||||||
|
EVENT_BUS.addListener(EventPriority.NORMAL, QuantumBatteryItem.Companion::tick);
|
||||||
|
EVENT_BUS.addListener(EventPriority.LOWEST, PortableCondensationDriveItem.Companion::onPickupEvent);
|
||||||
|
|
||||||
|
MatteryPlayerCapability.Companion.registerEffects(event);
|
||||||
|
|
||||||
MatteryPlayerNetworkChannel.INSTANCE.register();
|
MatteryPlayerNetworkChannel.INSTANCE.register();
|
||||||
MenuNetworkChannel.INSTANCE.register();
|
MenuNetworkChannel.INSTANCE.register();
|
||||||
WeaponNetworkChannel.INSTANCE.register();
|
WeaponNetworkChannel.INSTANCE.register();
|
||||||
RegistryNetworkChannel.INSTANCE.register();
|
RegistryNetworkChannel.INSTANCE.register();
|
||||||
WorldNetworkChannel.INSTANCE.register();
|
WorldNetworkChannel.INSTANCE.register();
|
||||||
|
GenericNetworkChannel.INSTANCE.register();
|
||||||
|
|
||||||
ITEM_STORAGE = StorageRegistry.register(ItemStackWrapper.class, ItemStackWrapper.EMPTY, new ImpreciseFraction("3.125"));
|
ITEM_STORAGE = StorageRegistry.register(ItemStackWrapper.class, ItemStackWrapper.EMPTY, new ImpreciseFraction("3.125"));
|
||||||
|
|
||||||
if (ModList.get().isLoaded("mekanism")) {
|
if (ModList.get().isLoaded("mekanism")) {
|
||||||
MinecraftForge.EVENT_BUS.register(QIOKt.class);
|
EVENT_BUS.addGenericListener(BlockEntity.class, EventPriority.NORMAL, QIOKt::attachCapabilities);
|
||||||
MinecraftForge.EVENT_BUS.register(TooltipsKt.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OreGen.INSTANCE.register();
|
OreGen.INSTANCE.register();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupClient(final FMLClientSetupEvent event) {
|
private void setupClient(final FMLClientSetupEvent event) {
|
||||||
MinecraftForge.EVENT_BUS.register(MatteryGUI.INSTANCE);
|
EVENT_BUS.addListener(EventPriority.NORMAL, MatterRegistryKt::tooltipEvent);
|
||||||
MinecraftForge.EVENT_BUS.register(EventHandlerKt.class);
|
|
||||||
|
EVENT_BUS.addListener(EventPriority.NORMAL, AbstractWeaponItem.Companion::playerRenderHook);
|
||||||
|
EVENT_BUS.addListener(EventPriority.NORMAL, AbstractWeaponItem.Companion::fovHook);
|
||||||
|
EVENT_BUS.addListener(EventPriority.NORMAL, AbstractWeaponItem.Companion::clickHook);
|
||||||
|
EVENT_BUS.addListener(EventPriority.NORMAL, AbstractWeaponItem.Companion::renderViewModel);
|
||||||
|
|
||||||
|
EVENT_BUS.addListener(EventPriority.NORMAL, MatteryGUI.INSTANCE::onScreenRender);
|
||||||
|
EVENT_BUS.addListener(EventPriority.LOWEST, MatteryGUI.INSTANCE::onOpenGUIEvent);
|
||||||
|
EVENT_BUS.addListener(EventPriority.NORMAL, MatteryGUI.INSTANCE::onRenderGuiEvent);
|
||||||
|
EVENT_BUS.addListener(EventPriority.HIGH, MatteryGUI.INSTANCE::onLayerRenderEvent);
|
||||||
|
|
||||||
|
EVENT_BUS.addListener(EventPriority.NORMAL, ClientEventHandler.INSTANCE::inputEvent);
|
||||||
|
EVENT_BUS.addListener(EventPriority.NORMAL, ClientEventHandler.INSTANCE::screenOpen);
|
||||||
|
|
||||||
|
if (ModList.get().isLoaded("mekanism")) {
|
||||||
|
EVENT_BUS.addListener(EventPriority.NORMAL, TooltipsKt::tooltipEvent);
|
||||||
|
}
|
||||||
|
|
||||||
event.enqueueWork(GlobalEventHandlerKt::recordClientThread);
|
event.enqueueWork(GlobalEventHandlerKt::recordClientThread);
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import net.minecraftforge.common.capabilities.*;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import ru.dbotthepony.mc.otm.capability.drive.IMatteryDrive;
|
import ru.dbotthepony.mc.otm.capability.drive.IMatteryDrive;
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler;
|
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler;
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterTaskProvider;
|
import ru.dbotthepony.mc.otm.capability.matter.IReplicationTaskProvider;
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.IPatternStorage;
|
import ru.dbotthepony.mc.otm.capability.matter.IPatternStorage;
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode;
|
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode;
|
||||||
import ru.dbotthepony.mc.otm.graph.storage.IStorageGraphNode;
|
import ru.dbotthepony.mc.otm.graph.storage.IStorageGraphNode;
|
||||||
@ -36,7 +36,7 @@ public class MatteryCapability {
|
|||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@NotNull
|
@NotNull
|
||||||
public static final Capability<IMatterTaskProvider> TASK = CapabilityManager.get(new CapabilityToken<>() {});
|
public static final Capability<IReplicationTaskProvider> TASK = CapabilityManager.get(new CapabilityToken<>() {});
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@NotNull
|
@NotNull
|
||||||
@ -49,16 +49,4 @@ public class MatteryCapability {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
@NotNull
|
@NotNull
|
||||||
public static final Capability<IStrictEnergyHandler> MEKANISM_ENERGY = CapabilityManager.get(new CapabilityToken<>() {});
|
public static final Capability<IStrictEnergyHandler> MEKANISM_ENERGY = CapabilityManager.get(new CapabilityToken<>() {});
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public static void register(final RegisterCapabilitiesEvent event) {
|
|
||||||
event.register(IMatteryEnergyStorage.class);
|
|
||||||
event.register(MatteryPlayerCapability.class);
|
|
||||||
event.register(IMatterHandler.class);
|
|
||||||
event.register(IPatternStorage.class);
|
|
||||||
event.register(IMatterTaskProvider.class);
|
|
||||||
event.register(IMatteryDrive.class);
|
|
||||||
event.register(IStorageGraphNode.class);
|
|
||||||
event.register(IMatterGraphNode.class);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,147 +0,0 @@
|
|||||||
package ru.dbotthepony.mc.otm.capability.matter;
|
|
||||||
|
|
||||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
|
||||||
import net.minecraft.nbt.CompoundTag;
|
|
||||||
import net.minecraft.nbt.Tag;
|
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import net.minecraft.world.item.Item;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import net.minecraft.world.item.Items;
|
|
||||||
import net.minecraftforge.registries.ForgeRegistries;
|
|
||||||
import net.minecraftforge.registries.ForgeRegistry;
|
|
||||||
import net.minecraftforge.registries.RegistryManager;
|
|
||||||
import ru.dbotthepony.mc.otm.UnOverengineeringKt;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
@MethodsReturnNonnullByDefault
|
|
||||||
@ParametersAreNonnullByDefault
|
|
||||||
public record MatterTask(UUID id, @Nullable UUID pattern, Item item, int in_progress, int finished, int required) {
|
|
||||||
public MatterTask(UUID id, @Nullable UUID pattern, Item item, int in_progress, int finished, int required) {
|
|
||||||
this.id = id;
|
|
||||||
this.pattern = pattern;
|
|
||||||
this.item = item;
|
|
||||||
this.in_progress = Math.max(0, in_progress);
|
|
||||||
this.finished = Math.max(0, finished);
|
|
||||||
this.required = Math.max(0, required);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return id.hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (obj instanceof MatterTask obj1)
|
|
||||||
return obj1.id.equals(id);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ItemStack stack() {
|
|
||||||
return new ItemStack(item, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ItemStack stack(int amount) {
|
|
||||||
return new ItemStack(item, amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int total() {
|
|
||||||
return in_progress + finished + required;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MatterTask shrinkRequired(int amount) {
|
|
||||||
return new MatterTask(id, pattern, item, in_progress + amount, finished, required - amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
public MatterTask shrinkInProgress(int amount) {
|
|
||||||
return new MatterTask(id, pattern, item, in_progress - amount, finished + amount, required);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CompoundTag serializeNBT() {
|
|
||||||
CompoundTag tag = new CompoundTag();
|
|
||||||
|
|
||||||
tag.putLong("id_l", id.getLeastSignificantBits());
|
|
||||||
tag.putLong("id_u", id.getMostSignificantBits());
|
|
||||||
|
|
||||||
if (pattern != null) {
|
|
||||||
tag.putLong("pattern_l", pattern.getLeastSignificantBits());
|
|
||||||
tag.putLong("pattern_u", pattern.getMostSignificantBits());
|
|
||||||
}
|
|
||||||
|
|
||||||
tag.putString("item", Objects.requireNonNull(UnOverengineeringKt.getRegistryName(item)).toString());
|
|
||||||
tag.putInt("in_progress", in_progress);
|
|
||||||
tag.putInt("finished", finished);
|
|
||||||
tag.putInt("required", required);
|
|
||||||
|
|
||||||
return tag;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static MatterTask deserializeNBT(@Nullable Tag nbt) {
|
|
||||||
if (nbt == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (nbt instanceof CompoundTag tag) {
|
|
||||||
Item get_item = ForgeRegistries.ITEMS.getValue(new ResourceLocation(tag.getString("item")));
|
|
||||||
|
|
||||||
if (get_item != null && get_item != Items.AIR) {
|
|
||||||
long a = tag.getLong("pattern_u");
|
|
||||||
long b = tag.getLong("pattern_l");
|
|
||||||
|
|
||||||
UUID pattern = a != 0 && b != 0 ? new UUID(a, b) : null;
|
|
||||||
|
|
||||||
return new MatterTask(
|
|
||||||
new UUID(tag.getLong("id_u"), tag.getLong("id_l")),
|
|
||||||
pattern,
|
|
||||||
get_item,
|
|
||||||
tag.getInt("in_progress"),
|
|
||||||
tag.getInt("finished"),
|
|
||||||
tag.getInt("required")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void write(FriendlyByteBuf buffer) {
|
|
||||||
buffer.writeLong(id.getMostSignificantBits());
|
|
||||||
buffer.writeLong(id.getLeastSignificantBits());
|
|
||||||
|
|
||||||
if (pattern != null) {
|
|
||||||
buffer.writeBoolean(true);
|
|
||||||
|
|
||||||
buffer.writeLong(pattern.getMostSignificantBits());
|
|
||||||
buffer.writeLong(pattern.getLeastSignificantBits());
|
|
||||||
} else {
|
|
||||||
buffer.writeBoolean(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer.writeInt(((ForgeRegistry<Item>) ForgeRegistries.ITEMS).getID(item));
|
|
||||||
buffer.writeInt(in_progress);
|
|
||||||
buffer.writeInt(finished);
|
|
||||||
buffer.writeInt(required);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static MatterTask read(FriendlyByteBuf buffer) {
|
|
||||||
var id = new UUID(buffer.readLong(), buffer.readLong());
|
|
||||||
var pattern = buffer.readBoolean() ? new UUID(buffer.readLong(), buffer.readLong()) : null;
|
|
||||||
var item = ((ForgeRegistry<Item>) ForgeRegistries.ITEMS).getValue(buffer.readInt());
|
|
||||||
|
|
||||||
if (item == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
var in_progress = buffer.readInt();
|
|
||||||
var finished = buffer.readInt();
|
|
||||||
var required = buffer.readInt();
|
|
||||||
|
|
||||||
return new MatterTask(id, pattern, item, in_progress, finished, required);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,95 +0,0 @@
|
|||||||
package ru.dbotthepony.mc.otm.capability.matter;
|
|
||||||
|
|
||||||
import net.minecraft.nbt.CompoundTag;
|
|
||||||
import net.minecraft.nbt.Tag;
|
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import net.minecraft.world.item.Item;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import net.minecraftforge.registries.ForgeRegistries;
|
|
||||||
import net.minecraftforge.registries.ForgeRegistry;
|
|
||||||
import net.minecraftforge.registries.RegistryManager;
|
|
||||||
import ru.dbotthepony.mc.otm.UnOverengineeringKt;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public record PatternState(@Nonnull UUID id, @Nonnull Item item, double research) {
|
|
||||||
public PatternState(@Nonnull UUID id, @Nonnull Item item, double research) {
|
|
||||||
this.id = id;
|
|
||||||
this.item = item;
|
|
||||||
this.research = Math.max(0, Math.min(1, research));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object state) {
|
|
||||||
if (state instanceof PatternState state1)
|
|
||||||
return state1.id.equals(id);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ItemStack stack() {
|
|
||||||
return new ItemStack(item, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return id.hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
public CompoundTag serializeNBT() {
|
|
||||||
var tag = new CompoundTag();
|
|
||||||
|
|
||||||
tag.putLong("id_m", id.getMostSignificantBits());
|
|
||||||
tag.putLong("id_l", id.getLeastSignificantBits());
|
|
||||||
tag.putString("item", Objects.requireNonNull(UnOverengineeringKt.getRegistryName(item)).toString());
|
|
||||||
tag.putDouble("research_percent", research);
|
|
||||||
|
|
||||||
return tag;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static PatternState deserializeNBT(Tag nbt) {
|
|
||||||
if (nbt instanceof CompoundTag tag) {
|
|
||||||
var item = ForgeRegistries.ITEMS.getValue(new ResourceLocation(tag.getString("item")));
|
|
||||||
|
|
||||||
if (item == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
var id = new UUID(tag.getLong("id_m"), tag.getLong("id_l"));
|
|
||||||
var research_percent = tag.getDouble("research_percent");
|
|
||||||
|
|
||||||
return new PatternState(id, item, research_percent);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void write(FriendlyByteBuf buffer) {
|
|
||||||
buffer.writeLong(id.getMostSignificantBits());
|
|
||||||
buffer.writeLong(id.getLeastSignificantBits());
|
|
||||||
|
|
||||||
buffer.writeInt(((ForgeRegistry<Item>) ForgeRegistries.ITEMS).getID(item));
|
|
||||||
|
|
||||||
buffer.writeDouble(research);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static PatternState read(FriendlyByteBuf buffer) {
|
|
||||||
long ida = buffer.readLong();
|
|
||||||
long idb = buffer.readLong();
|
|
||||||
|
|
||||||
int item = buffer.readInt();
|
|
||||||
double percent = buffer.readDouble();
|
|
||||||
|
|
||||||
Item get_item = ((ForgeRegistry<Item>) ForgeRegistries.ITEMS).getValue(item);
|
|
||||||
|
|
||||||
if (get_item == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return new PatternState(new UUID(ida, idb), get_item, percent);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,401 +0,0 @@
|
|||||||
package ru.dbotthepony.mc.otm.client.screen;
|
|
||||||
|
|
||||||
import net.minecraft.ChatFormatting;
|
|
||||||
import net.minecraft.client.gui.components.EditBox;
|
|
||||||
import net.minecraft.network.chat.Component;
|
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.MatterTask;
|
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.PatternState;
|
|
||||||
import ru.dbotthepony.mc.otm.menu.MatterPanelMenu;
|
|
||||||
import ru.dbotthepony.mc.otm.menu.ReplicationRequestPacket;
|
|
||||||
import ru.dbotthepony.mc.otm.network.MenuNetworkChannel;
|
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.*;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static ru.dbotthepony.mc.otm.UnOverengineeringKt.TextComponent;
|
|
||||||
import static ru.dbotthepony.mc.otm.UnOverengineeringKt.TranslatableComponent;
|
|
||||||
|
|
||||||
public class MatterPanelScreen extends MatteryScreen<MatterPanelMenu> {
|
|
||||||
private static final int MODAL_WIDTH = 213;
|
|
||||||
private static final int MODAL_HEIGHT = 110;
|
|
||||||
|
|
||||||
public MatterPanelScreen(MatterPanelMenu p_97741_, Inventory p_97742_, Component p_97743_) {
|
|
||||||
super(p_97741_, p_97742_, p_97743_);
|
|
||||||
|
|
||||||
imageWidth = 176;
|
|
||||||
imageHeight = 187;
|
|
||||||
|
|
||||||
titleLabelY = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final int GRID_WIDTH = 8;
|
|
||||||
public static final int GRID_HEIGHT = 9;
|
|
||||||
|
|
||||||
private final ArrayList<AbstractSlotPanel> pattern_slots = new ArrayList<>();
|
|
||||||
private final ArrayList<AbstractSlotPanel> task_slots = new ArrayList<>();
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
protected FramePanel makeMainFrame() {
|
|
||||||
float width = GRID_WIDTH * AbstractSlotPanel.SIZE + ScrollBarConstants.WIDTH + FramePanel.PADDING * 2 + 8;
|
|
||||||
float height = GRID_HEIGHT * AbstractSlotPanel.SIZE + FramePanel.PADDING_TOP + FramePanel.PADDING;
|
|
||||||
|
|
||||||
var scroll_panel = new ContinuousScrollBarPanel(this, null, 0, 0, 0);
|
|
||||||
|
|
||||||
var frame = new FramePanel(this, null, 0, 0, width, height, getTitle()) {
|
|
||||||
@Override
|
|
||||||
protected boolean mouseScrolledInner(double x, double y, double scroll) {
|
|
||||||
return scroll_panel.mouseScrolledInner(x, y, scroll);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var patterns_tab = frame.addTab(FramePanel.Position.TOP, () -> {
|
|
||||||
for (var slot : pattern_slots) {
|
|
||||||
slot.setVisible(true);
|
|
||||||
}
|
|
||||||
}, () -> {
|
|
||||||
for (var slot : pattern_slots) {
|
|
||||||
slot.setVisible(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var tasks_tab = frame.addTab(FramePanel.Position.TOP, () -> {
|
|
||||||
for (var slot : task_slots) {
|
|
||||||
slot.setVisible(true);
|
|
||||||
}
|
|
||||||
}, () -> {
|
|
||||||
for (var slot : task_slots) {
|
|
||||||
slot.setVisible(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
scroll_panel.setParent(frame);
|
|
||||||
scroll_panel.setDock(Dock.RIGHT);
|
|
||||||
scroll_panel.setupRowMultiplier(() -> {
|
|
||||||
if (tasks_tab.isActive()) {
|
|
||||||
return menu.getTasks().size() / GRID_WIDTH;
|
|
||||||
}
|
|
||||||
|
|
||||||
return menu.getPatterns().size() / GRID_WIDTH;
|
|
||||||
});
|
|
||||||
|
|
||||||
var grid = new GridPanel(this, frame, 0, 0, GRID_WIDTH * AbstractSlotPanel.SIZE, 0, GRID_WIDTH, GRID_HEIGHT) {
|
|
||||||
@Override
|
|
||||||
protected boolean mouseScrolledInner(double x, double y, double scroll) {
|
|
||||||
return scroll_panel.mouseScrolledInner(x, y, scroll);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
grid.setDock(Dock.LEFT);
|
|
||||||
grid.setDockMargin(4, 0, 0, 0);
|
|
||||||
|
|
||||||
for (int i = 0; i < GRID_WIDTH * GRID_HEIGHT; i++) {
|
|
||||||
int slot = i;
|
|
||||||
|
|
||||||
pattern_slots.add(new AbstractSlotPanel(this, grid, 0, 0) {
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
protected ItemStack getItemStack() {
|
|
||||||
var slot1 = slot + scroll_panel.getScroll(menu.getPatterns().size() / GRID_WIDTH) * GRID_WIDTH;
|
|
||||||
|
|
||||||
if (slot1 >= menu.getPatterns().size()) {
|
|
||||||
return ItemStack.EMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
return menu.getPatterns().get(slot1).stack();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
protected List<Component> getItemStackTooltip(@Nonnull ItemStack stack) {
|
|
||||||
var slot1 = slot + scroll_panel.getScroll(menu.getPatterns().size() / GRID_WIDTH) * GRID_WIDTH;
|
|
||||||
|
|
||||||
if (slot1 >= menu.getPatterns().size()) {
|
|
||||||
return List.of();
|
|
||||||
}
|
|
||||||
|
|
||||||
return getPatternTooltip(super.getItemStackTooltip(stack), menu.getPatterns().get(slot1));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean mouseScrolledInner(double x, double y, double scroll) {
|
|
||||||
return scroll_panel.mouseScrolledInner(x, y, scroll);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean mouseClickedInner(double x, double y, int flag) {
|
|
||||||
if (slot >= menu.getPatterns().size()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
openPattern(menu.getPatterns().get(slot));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
task_slots.add(new AbstractSlotPanel(this, grid, 0, 0) {
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
protected ItemStack getItemStack() {
|
|
||||||
var slot1 = slot + scroll_panel.getScroll(menu.getTasks().size() / GRID_WIDTH) * GRID_WIDTH;
|
|
||||||
|
|
||||||
if (slot1 >= menu.getTasks().size()) {
|
|
||||||
return ItemStack.EMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
var task = menu.getTasks().get(slot1);
|
|
||||||
return task.stack(Math.max(task.required(), 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
protected List<Component> getItemStackTooltip(@Nonnull ItemStack stack) {
|
|
||||||
var slot1 = slot + scroll_panel.getScroll(menu.getTasks().size() / GRID_WIDTH) * GRID_WIDTH;
|
|
||||||
|
|
||||||
if (slot1 >= menu.getTasks().size()) {
|
|
||||||
return List.of();
|
|
||||||
}
|
|
||||||
|
|
||||||
return getTaskTooltip(super.getItemStackTooltip(stack), menu.getTasks().get(slot1));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean mouseScrolledInner(double x, double y, double scroll) {
|
|
||||||
return scroll_panel.mouseScrolledInner(x, y, scroll);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean mouseClickedInner(double x, double y, int flag) {
|
|
||||||
if (slot >= menu.getTasks().size()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
openTask(menu.getTasks().get(slot));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var slot : task_slots) {
|
|
||||||
slot.setVisible(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return frame;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Component> getTaskTooltip(List<Component> input, MatterTask task) {
|
|
||||||
input.add(TranslatableComponent("otm.gui.matter_task.total", task.total()).withStyle(ChatFormatting.GRAY));
|
|
||||||
input.add(TranslatableComponent("otm.gui.matter_task.required", task.required()).withStyle(ChatFormatting.GRAY));
|
|
||||||
input.add(TranslatableComponent("otm.gui.matter_task.in_progress", task.in_progress()).withStyle(ChatFormatting.GRAY));
|
|
||||||
input.add(TranslatableComponent("otm.gui.matter_task.finished", task.finished()).withStyle(ChatFormatting.GRAY));
|
|
||||||
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Component> getPatternTooltip(List<Component> input, PatternState pattern) {
|
|
||||||
input.add(TranslatableComponent("otm.item.pattern.research", String.format("%.2f", pattern.research() * 100d)).withStyle(ChatFormatting.AQUA));
|
|
||||||
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void openTask(MatterTask task) {
|
|
||||||
var task_frame = new FramePanel(this, null, 0, 0, 170, 40, TranslatableComponent("otm.container.matter_panel.task")) {
|
|
||||||
@Override
|
|
||||||
public void tick() {
|
|
||||||
super.tick();
|
|
||||||
|
|
||||||
if (!menu.getTasks().contains(task)) {
|
|
||||||
remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var slot = new AbstractSlotPanel(this, task_frame, 0, 0) {
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
protected ItemStack getItemStack() {
|
|
||||||
var task1_index = menu.getTasks().indexOf(task);
|
|
||||||
|
|
||||||
if (task1_index != -1) {
|
|
||||||
var task1 = menu.getTasks().get(task1_index);
|
|
||||||
return task1.stack(Math.max(task1.required(), 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
return ItemStack.EMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
protected List<Component> getItemStackTooltip(@Nonnull ItemStack stack) {
|
|
||||||
var task1_index = menu.getTasks().indexOf(task);
|
|
||||||
List<Component> get_list = super.getItemStackTooltip(stack);
|
|
||||||
|
|
||||||
if (task1_index != -1) {
|
|
||||||
getTaskTooltip(get_list, menu.getTasks().get(task1_index));
|
|
||||||
}
|
|
||||||
|
|
||||||
return get_list;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
slot.setDock(Dock.LEFT);
|
|
||||||
|
|
||||||
var button = new ButtonPanel(this, task_frame, 0, 0, 40, 20, TranslatableComponent("otm.container.matter_panel.close"));
|
|
||||||
button.setDock(Dock.RIGHT);
|
|
||||||
button.setDockMargin(2, 0, 0, 0);
|
|
||||||
button.bind(task_frame::remove);
|
|
||||||
|
|
||||||
button = new ButtonPanel(this, task_frame, 0, 0, 80, 20, TranslatableComponent("otm.container.matter_panel.cancel_task"));
|
|
||||||
button.setDock(Dock.RIGHT);
|
|
||||||
button.setDockMargin(2, 0, 0, 0);
|
|
||||||
button.bind(() -> {
|
|
||||||
menu.requestTaskCancel(task.id());
|
|
||||||
task_frame.remove();
|
|
||||||
});
|
|
||||||
|
|
||||||
task_frame.toScreenCenter();
|
|
||||||
addPanel(task_frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void openPattern(PatternState state) {
|
|
||||||
var pattern_frame = new FramePanel(this, null, 0, 0, MODAL_WIDTH, MODAL_HEIGHT, TranslatableComponent("otm.container.matter_panel.label")){
|
|
||||||
@Override
|
|
||||||
public void tick() {
|
|
||||||
super.tick();
|
|
||||||
|
|
||||||
if (!menu.getPatterns().contains(state)) {
|
|
||||||
remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var row_1 = new EditablePanel(this, pattern_frame);
|
|
||||||
var row_2 = new EditablePanel(this, pattern_frame);
|
|
||||||
var row_3 = new EditablePanel(this, pattern_frame);
|
|
||||||
var row_4 = new EditablePanel(this, pattern_frame);
|
|
||||||
|
|
||||||
row_1.setDock(Dock.TOP);
|
|
||||||
row_2.setDock(Dock.TOP);
|
|
||||||
row_3.setDock(Dock.TOP);
|
|
||||||
row_4.setDock(Dock.TOP);
|
|
||||||
|
|
||||||
row_1.setHeight(20);
|
|
||||||
row_2.setHeight(20);
|
|
||||||
row_3.setHeight(20);
|
|
||||||
row_4.setHeight(20);
|
|
||||||
|
|
||||||
row_1.setDockMargin(0, 2, 0, 0);
|
|
||||||
row_2.setDockMargin(0, 2, 0, 0);
|
|
||||||
row_3.setDockMargin(0, 2, 0, 0);
|
|
||||||
row_4.setDockMargin(0, 2, 0, 0);
|
|
||||||
|
|
||||||
var slot = new AbstractSlotPanel(this, row_2, 0, 0) {
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
protected ItemStack getItemStack() {
|
|
||||||
return new ItemStack(state.item(), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
protected List<Component> getItemStackTooltip(@Nonnull ItemStack stack) {
|
|
||||||
return getPatternTooltip(super.getItemStackTooltip(stack), state);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var input_amount = new EditBoxPanel(this, row_2, 0, 0, 10, 20, TextComponent("Input amount")) {
|
|
||||||
@Override
|
|
||||||
protected void configureNew(@Nonnull EditBox widget, boolean recreation) {
|
|
||||||
super.configureNew(widget, recreation);
|
|
||||||
|
|
||||||
widget.setMaxLength(6);
|
|
||||||
|
|
||||||
if (!recreation) {
|
|
||||||
widget.setValue("1");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void increase(int amount) {
|
|
||||||
int value = 1;
|
|
||||||
|
|
||||||
try {
|
|
||||||
value = Integer.parseInt(getOrCreateWidget().getValue());
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value == 1 && amount > 0)
|
|
||||||
getOrCreateWidget().setValue(Integer.toString(amount));
|
|
||||||
else
|
|
||||||
getOrCreateWidget().setValue(Integer.toString(Math.max(1, Math.min(99999, value + amount))));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var button = new ButtonPanel(this, row_1, 0, 0, 40, 20, TranslatableComponent("otm.container.matter_panel.increase_by", 8));
|
|
||||||
button.bind(() -> input_amount.increase(8));
|
|
||||||
button.setDock(Dock.RIGHT);
|
|
||||||
button.setDockMargin(2, 0, 0, 0);
|
|
||||||
|
|
||||||
button = new ButtonPanel(this, row_1, 0, 0, 40, 20, TranslatableComponent("otm.container.matter_panel.increase_by", 64));
|
|
||||||
button.setDock(Dock.RIGHT);
|
|
||||||
button.bind(() -> input_amount.increase(64));
|
|
||||||
button.setDockMargin(2, 0, 0, 0);
|
|
||||||
|
|
||||||
button = new ButtonPanel(this, row_1, 0, 0, 40, 20, TranslatableComponent("otm.container.matter_panel.increase_by", 256));
|
|
||||||
button.setDock(Dock.RIGHT);
|
|
||||||
button.bind(() -> input_amount.increase(256));
|
|
||||||
button.setDockMargin(2, 0, 0, 0);
|
|
||||||
|
|
||||||
slot.setDock(Dock.LEFT);
|
|
||||||
slot.setDockMargin(0, 0, 4, 0);
|
|
||||||
input_amount.setDock(Dock.FILL);
|
|
||||||
|
|
||||||
button = new ButtonPanel(this, row_3, 0, 0, 40, 20, TranslatableComponent("otm.container.matter_panel.decrease_by", 8));
|
|
||||||
button.bind(() -> input_amount.increase(-8));
|
|
||||||
button.setDock(Dock.RIGHT);
|
|
||||||
button.setDockMargin(2, 0, 0, 0);
|
|
||||||
|
|
||||||
button = new ButtonPanel(this, row_3, 0, 0, 40, 20, TranslatableComponent("otm.container.matter_panel.decrease_by", 64));
|
|
||||||
button.setDock(Dock.RIGHT);
|
|
||||||
button.bind(() -> input_amount.increase(-64));
|
|
||||||
button.setDockMargin(2, 0, 0, 0);
|
|
||||||
|
|
||||||
button = new ButtonPanel(this, row_3, 0, 0, 40, 20, TranslatableComponent("otm.container.matter_panel.decrease_by", 256));
|
|
||||||
button.setDock(Dock.RIGHT);
|
|
||||||
button.bind(() -> input_amount.increase(-256));
|
|
||||||
button.setDockMargin(2, 0, 0, 0);
|
|
||||||
|
|
||||||
button = new ButtonPanel(this, row_4, 0, 0, 40, 20, TranslatableComponent("otm.container.matter_panel.cancel"));
|
|
||||||
button.setDock(Dock.RIGHT);
|
|
||||||
button.bind(pattern_frame::remove);
|
|
||||||
button.setDockMargin(2, 0, 0, 0);
|
|
||||||
|
|
||||||
button = new ButtonPanel(this, row_4, 0, 0, 82, 20, TranslatableComponent("otm.container.matter_panel.send"));
|
|
||||||
button.setDock(Dock.RIGHT);
|
|
||||||
button.bind(() -> {
|
|
||||||
int value = 1;
|
|
||||||
|
|
||||||
try {
|
|
||||||
value = Integer.parseInt(input_amount.getOrCreateWidget().getValue());
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
MenuNetworkChannel.INSTANCE.sendToServer(new ReplicationRequestPacket(state, value));
|
|
||||||
pattern_frame.remove();
|
|
||||||
});
|
|
||||||
|
|
||||||
button.setDockMargin(2, 0, 0, 0);
|
|
||||||
|
|
||||||
addPanel(pattern_frame);
|
|
||||||
pattern_frame.toScreenCenter();
|
|
||||||
popup(pattern_frame);
|
|
||||||
}
|
|
||||||
}
|
|
@ -4,6 +4,7 @@ import net.minecraft.resources.ResourceLocation;
|
|||||||
import net.minecraft.world.item.crafting.Recipe;
|
import net.minecraft.world.item.crafting.Recipe;
|
||||||
import net.minecraft.world.item.crafting.RecipeSerializer;
|
import net.minecraft.world.item.crafting.RecipeSerializer;
|
||||||
import net.minecraft.world.item.crafting.RecipeType;
|
import net.minecraft.world.item.crafting.RecipeType;
|
||||||
|
import net.minecraftforge.eventbus.api.IEventBus;
|
||||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||||
import net.minecraftforge.registries.DeferredRegister;
|
import net.minecraftforge.registries.DeferredRegister;
|
||||||
import net.minecraftforge.registries.ForgeRegistries;
|
import net.minecraftforge.registries.ForgeRegistries;
|
||||||
@ -35,8 +36,8 @@ public class MRecipes {
|
|||||||
typesRegistry.register(MNames.PLATE_PRESS, () -> PLATE_PRESS);
|
typesRegistry.register(MNames.PLATE_PRESS, () -> PLATE_PRESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void register() {
|
public static void register(IEventBus bus) {
|
||||||
registry.register(FMLJavaModLoadingContext.get().getModEventBus());
|
registry.register(bus);
|
||||||
typesRegistry.register(FMLJavaModLoadingContext.get().getModEventBus());
|
typesRegistry.register(bus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,213 +0,0 @@
|
|||||||
|
|
||||||
@file:Suppress("unused")
|
|
||||||
|
|
||||||
package ru.dbotthepony.mc.otm
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList
|
|
||||||
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.LongArrayTag
|
|
||||||
import net.minecraft.nbt.Tag
|
|
||||||
import net.minecraft.world.Container
|
|
||||||
import net.minecraft.world.entity.Entity
|
|
||||||
import net.minecraft.world.item.ItemStack
|
|
||||||
import net.minecraft.world.phys.Vec3
|
|
||||||
import net.minecraftforge.common.util.LazyOptional
|
|
||||||
import net.minecraftforge.items.IItemHandler
|
|
||||||
import java.util.*
|
|
||||||
import kotlin.properties.ReadWriteProperty
|
|
||||||
import kotlin.reflect.KProperty
|
|
||||||
|
|
||||||
operator fun Direction.unaryMinus(): Direction = this.opposite
|
|
||||||
operator fun Vec3i.unaryMinus(): Vec3i = Vec3i(-x, -y, -z)
|
|
||||||
operator fun BlockPos.unaryMinus(): BlockPos = BlockPos(-x, -y, -z)
|
|
||||||
|
|
||||||
operator fun CompoundTag.set(index: String, value: Tag) = put(index, value)
|
|
||||||
operator fun CompoundTag.set(index: String, value: Int) = putInt(index, value)
|
|
||||||
operator fun CompoundTag.set(index: String, value: Byte) = putByte(index, value)
|
|
||||||
operator fun CompoundTag.set(index: String, value: Short) = putShort(index, value)
|
|
||||||
operator fun CompoundTag.set(index: String, value: Long) = putLong(index, value)
|
|
||||||
operator fun CompoundTag.set(index: String, value: Float) = putFloat(index, value)
|
|
||||||
operator fun CompoundTag.set(index: String, value: Double) = putDouble(index, value)
|
|
||||||
operator fun CompoundTag.set(index: String, value: String) = putString(index, value)
|
|
||||||
operator fun CompoundTag.set(index: String, value: Boolean) = putBoolean(index, value)
|
|
||||||
operator fun CompoundTag.set(index: String, value: ByteArray) = putByteArray(index, value)
|
|
||||||
operator fun CompoundTag.set(index: String, value: IntArray) = putIntArray(index, value)
|
|
||||||
operator fun CompoundTag.set(index: String, value: LongArray) = putLongArray(index, value)
|
|
||||||
|
|
||||||
@JvmInline
|
|
||||||
value class CompoundTagInt(val tag: CompoundTag) : ReadWriteProperty<Any, Int> {
|
|
||||||
override fun getValue(thisRef: Any, property: KProperty<*>) = tag.getInt(property.name)
|
|
||||||
override fun setValue(thisRef: Any, property: KProperty<*>, value: Int) = tag.putInt(property.name, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmInline
|
|
||||||
value class CompoundTagLong(val tag: CompoundTag) : ReadWriteProperty<Any, Long> {
|
|
||||||
override fun getValue(thisRef: Any, property: KProperty<*>) = tag.getLong(property.name)
|
|
||||||
override fun setValue(thisRef: Any, property: KProperty<*>, value: Long) = tag.putLong(property.name, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmInline
|
|
||||||
value class CompoundTagByte(val tag: CompoundTag) : ReadWriteProperty<Any, Byte> {
|
|
||||||
override fun getValue(thisRef: Any, property: KProperty<*>) = tag.getByte(property.name)
|
|
||||||
override fun setValue(thisRef: Any, property: KProperty<*>, value: Byte) = tag.putByte(property.name, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmInline
|
|
||||||
value class CompoundTagShort(val tag: CompoundTag) : ReadWriteProperty<Any, Short> {
|
|
||||||
override fun getValue(thisRef: Any, property: KProperty<*>) = tag.getShort(property.name)
|
|
||||||
override fun setValue(thisRef: Any, property: KProperty<*>, value: Short) = tag.putShort(property.name, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmInline
|
|
||||||
value class CompoundTagFloat(val tag: CompoundTag) : ReadWriteProperty<Any, Float> {
|
|
||||||
override fun getValue(thisRef: Any, property: KProperty<*>) = tag.getFloat(property.name)
|
|
||||||
override fun setValue(thisRef: Any, property: KProperty<*>, value: Float) = tag.putFloat(property.name, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmInline
|
|
||||||
value class CompoundTagBoolean(val tag: CompoundTag) : ReadWriteProperty<Any, Boolean> {
|
|
||||||
override fun getValue(thisRef: Any, property: KProperty<*>) = tag.getBoolean(property.name)
|
|
||||||
override fun setValue(thisRef: Any, property: KProperty<*>, value: Boolean) = tag.putBoolean(property.name, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmInline
|
|
||||||
value class CompoundTagDouble(val tag: CompoundTag) : ReadWriteProperty<Any, Double> {
|
|
||||||
override fun getValue(thisRef: Any, property: KProperty<*>) = tag.getDouble(property.name)
|
|
||||||
override fun setValue(thisRef: Any, property: KProperty<*>, value: Double) = tag.putDouble(property.name, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmInline
|
|
||||||
value class CompoundTagString(val tag: CompoundTag) : ReadWriteProperty<Any, String> {
|
|
||||||
override fun getValue(thisRef: Any, property: KProperty<*>): String = tag.getString(property.name)
|
|
||||||
override fun setValue(thisRef: Any, property: KProperty<*>, value: String) = tag.putString(property.name, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
val EMPTY_UUID = UUID(0L, 0L)
|
|
||||||
|
|
||||||
@JvmInline
|
|
||||||
value class CompoundTagUUID(val tag: CompoundTag) : ReadWriteProperty<Any, UUID> {
|
|
||||||
override fun getValue(thisRef: Any, property: KProperty<*>) = (tag.get(property.name) as LongArrayTag?)?.asLongArray?.let { UUID(it[0], it[1]) } ?: EMPTY_UUID
|
|
||||||
override fun setValue(thisRef: Any, property: KProperty<*>, value: UUID) = tag.putLongArray(property.name, longArrayOf(value.mostSignificantBits, value.leastSignificantBits))
|
|
||||||
}
|
|
||||||
|
|
||||||
val CompoundTag.ints get() = CompoundTagInt(this)
|
|
||||||
val CompoundTag.longs get() = CompoundTagLong(this)
|
|
||||||
val CompoundTag.bytes get() = CompoundTagByte(this)
|
|
||||||
val CompoundTag.shorts get() = CompoundTagShort(this)
|
|
||||||
val CompoundTag.floats get() = CompoundTagFloat(this)
|
|
||||||
val CompoundTag.doubles get() = CompoundTagDouble(this)
|
|
||||||
val CompoundTag.booleans get() = CompoundTagBoolean(this)
|
|
||||||
val CompoundTag.strings get() = CompoundTagString(this)
|
|
||||||
val CompoundTag.uuids get() = CompoundTagUUID(this)
|
|
||||||
|
|
||||||
operator fun Container.set(index: Int, value: ItemStack) = setItem(index, value)
|
|
||||||
operator fun Container.get(index: Int): ItemStack = getItem(index)
|
|
||||||
operator fun IItemHandler.get(index: Int): ItemStack = getStackInSlot(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)
|
|
||||||
|
|
||||||
if (tag != null) {
|
|
||||||
consumer(tag)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun CompoundTag.ifHas(s: String, type: Byte, consumer: (Tag) -> Unit) {
|
|
||||||
val tag = get(s)
|
|
||||||
|
|
||||||
if (tag != null && tag.id == type) {
|
|
||||||
consumer(tag)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun <reified T : Tag> CompoundTag.ifHas(s: String, type: Class<T>, consumer: (T) -> Unit) {
|
|
||||||
val tag = get(s)
|
|
||||||
|
|
||||||
if (tag != null && tag::class.java === type) {
|
|
||||||
consumer(tag as T)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <T> LazyOptional<T>.orNull(): T? {
|
|
||||||
if (!isPresent) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
return resolve().orElse(null)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <T> LazyOptional<T>.orThrow(): T {
|
|
||||||
if (!isPresent) {
|
|
||||||
throw IllegalStateException("Capability was expected to be not null")
|
|
||||||
}
|
|
||||||
|
|
||||||
return resolve().orElse(null) ?: throw IllegalStateException("Capability was expected to be not null")
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun <T> LazyOptional<T>.ifPresentK(lambda: (T) -> Unit) {
|
|
||||||
if (isPresent) {
|
|
||||||
val value = resolve().orElse(null) ?: throw IllegalStateException("Capability was expected to be not null")
|
|
||||||
lambda.invoke(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val ItemStack.tagNotNull: CompoundTag get() = orCreateTag
|
|
||||||
|
|
||||||
inline var Entity.position: Vec3
|
|
||||||
get() = position()
|
|
||||||
set(value) { setPos(value) }
|
|
||||||
|
|
||||||
inline val <reified T : Enum<T>> T.next: T get() {
|
|
||||||
val values = enumValues<T>()
|
|
||||||
val next = (ordinal + 1) % values.size
|
|
||||||
return values[next]
|
|
||||||
}
|
|
||||||
|
|
||||||
inline val <reified T : Enum<T>> T.prev: T get() {
|
|
||||||
val values = enumValues<T>()
|
|
||||||
var next = ordinal - 1
|
|
||||||
|
|
||||||
if (next < 0) {
|
|
||||||
next = values.size - 1
|
|
||||||
}
|
|
||||||
|
|
||||||
return values[next]
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <T : Enum<T>> T.next(values: Array<out T>): T {
|
|
||||||
val next = (ordinal + 1) % values.size
|
|
||||||
return values[next]
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <T : Enum<T>> T.prev(values: Array<out T>): T {
|
|
||||||
var next = ordinal - 1
|
|
||||||
|
|
||||||
if (next < 0) {
|
|
||||||
next = values.size - 1
|
|
||||||
}
|
|
||||||
|
|
||||||
return values[next]
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun <T> ImmutableList(size: Int, initializer: (index: Int) -> T): ImmutableList<T> {
|
|
||||||
require(size >= 0) { "Invalid list size $size" }
|
|
||||||
|
|
||||||
return when (size) {
|
|
||||||
0 -> ImmutableList.of()
|
|
||||||
1 -> ImmutableList.of(initializer(0))
|
|
||||||
else -> ImmutableList.Builder<T>().let {
|
|
||||||
for (i in 0 until size) {
|
|
||||||
it.add(initializer(i))
|
|
||||||
}
|
|
||||||
|
|
||||||
it.build()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -118,6 +118,8 @@ private var _server: MinecraftServer? = null
|
|||||||
private var _serverThread: Thread? = null
|
private var _serverThread: Thread? = null
|
||||||
private var _clientThread: Thread? = null
|
private var _clientThread: Thread? = null
|
||||||
|
|
||||||
|
val isClient: Boolean get() = _clientThread !== null
|
||||||
|
|
||||||
fun recordClientThread() {
|
fun recordClientThread() {
|
||||||
if (_clientThread != null) {
|
if (_clientThread != null) {
|
||||||
throw IllegalStateException("Already have client channel")
|
throw IllegalStateException("Already have client channel")
|
||||||
@ -127,13 +129,13 @@ fun recordClientThread() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun runIfClient(lambda: () -> Unit) {
|
fun runIfClient(lambda: () -> Unit) {
|
||||||
if (_clientThread !== null) {
|
if (isClient) {
|
||||||
lambda.invoke()
|
lambda.invoke()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <V> runIfClient(value: V, lambda: () -> V): V {
|
fun <V> runIfClient(value: V, lambda: () -> V): V {
|
||||||
if (_clientThread !== null) {
|
if (isClient) {
|
||||||
return lambda.invoke()
|
return lambda.invoke()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,7 +180,6 @@ interface IConditionalTickable : ITickable {
|
|||||||
val canTick: Boolean
|
val canTick: Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent(priority = EventPriority.LOWEST)
|
|
||||||
fun onServerTick(event: ServerTickEvent) {
|
fun onServerTick(event: ServerTickEvent) {
|
||||||
if (event.phase === TickEvent.Phase.START) {
|
if (event.phase === TickEvent.Phase.START) {
|
||||||
preServerTickTimers.tick()
|
preServerTickTimers.tick()
|
||||||
@ -253,7 +254,6 @@ fun addPostServerTickerOnce(ticker: ITickable) {
|
|||||||
postServerTickOnce.add(ticker)
|
postServerTickOnce.add(ticker)
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent(priority = EventPriority.LOWEST)
|
|
||||||
fun onWorldTick(event: LevelTickEvent) {
|
fun onWorldTick(event: LevelTickEvent) {
|
||||||
if (event.phase === TickEvent.Phase.START) {
|
if (event.phase === TickEvent.Phase.START) {
|
||||||
val it = preWorldTick[event.level]
|
val it = preWorldTick[event.level]
|
||||||
@ -353,7 +353,6 @@ private fun clear() {
|
|||||||
postWorldTickOnce.clear()
|
postWorldTickOnce.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent(priority = EventPriority.HIGHEST)
|
|
||||||
fun onServerStarting(event: ServerAboutToStartEvent) {
|
fun onServerStarting(event: ServerAboutToStartEvent) {
|
||||||
clear()
|
clear()
|
||||||
SERVER_IS_DYING = false
|
SERVER_IS_DYING = false
|
||||||
@ -361,13 +360,11 @@ fun onServerStarting(event: ServerAboutToStartEvent) {
|
|||||||
_serverThread = Thread.currentThread()
|
_serverThread = Thread.currentThread()
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent(priority = EventPriority.HIGHEST)
|
|
||||||
fun onServerStopping(event: ServerStoppingEvent) {
|
fun onServerStopping(event: ServerStoppingEvent) {
|
||||||
clear()
|
clear()
|
||||||
SERVER_IS_DYING = true
|
SERVER_IS_DYING = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent(priority = EventPriority.HIGHEST)
|
|
||||||
fun onServerStopped(event: ServerStoppedEvent) {
|
fun onServerStopped(event: ServerStoppedEvent) {
|
||||||
if (!SERVER_IS_DYING) {
|
if (!SERVER_IS_DYING) {
|
||||||
LOGGER.fatal("ServerStoppingEvent did not fire. If server has crashed this is normal. However, if server finished it's work 'gracefully' this is a bug.")
|
LOGGER.fatal("ServerStoppingEvent did not fire. If server has crashed this is normal. However, if server finished it's work 'gracefully' this is a bug.")
|
||||||
|
@ -4,9 +4,10 @@ import net.minecraft.nbt.CompoundTag
|
|||||||
import net.minecraftforge.common.util.INBTSerializable
|
import net.minecraftforge.common.util.INBTSerializable
|
||||||
import net.minecraftforge.event.entity.living.LivingHurtEvent
|
import net.minecraftforge.event.entity.living.LivingHurtEvent
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
|
||||||
import ru.dbotthepony.mc.otm.readNbt
|
import ru.dbotthepony.mc.otm.core.readNbt
|
||||||
import ru.dbotthepony.mc.otm.set
|
import ru.dbotthepony.mc.otm.container.set
|
||||||
import ru.dbotthepony.mc.otm.writeNbt
|
import ru.dbotthepony.mc.otm.core.set
|
||||||
|
import ru.dbotthepony.mc.otm.core.writeNbt
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import net.minecraft.network.chat.ComponentContents
|
|||||||
import net.minecraft.network.chat.MutableComponent
|
import net.minecraft.network.chat.MutableComponent
|
||||||
import net.minecraft.network.chat.contents.TranslatableContents
|
import net.minecraft.network.chat.contents.TranslatableContents
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
|
||||||
import ru.dbotthepony.mc.otm.getKeyNullable
|
import ru.dbotthepony.mc.otm.core.getKeyNullable
|
||||||
import ru.dbotthepony.mc.otm.registry.MRegistry
|
import ru.dbotthepony.mc.otm.registry.MRegistry
|
||||||
|
|
||||||
open class AndroidFeatureType<T : AndroidFeature> {
|
open class AndroidFeatureType<T : AndroidFeature> {
|
||||||
|
@ -7,9 +7,10 @@ import net.minecraft.world.item.ItemStack
|
|||||||
import net.minecraftforge.common.util.INBTSerializable
|
import net.minecraftforge.common.util.INBTSerializable
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
|
||||||
import ru.dbotthepony.mc.otm.client.render.SkinElement
|
import ru.dbotthepony.mc.otm.client.render.SkinElement
|
||||||
import ru.dbotthepony.mc.otm.readNbt
|
import ru.dbotthepony.mc.otm.core.readNbt
|
||||||
import ru.dbotthepony.mc.otm.set
|
import ru.dbotthepony.mc.otm.container.set
|
||||||
import ru.dbotthepony.mc.otm.writeNbt
|
import ru.dbotthepony.mc.otm.core.set
|
||||||
|
import ru.dbotthepony.mc.otm.core.writeNbt
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
|
|
||||||
|
@ -6,9 +6,10 @@ import net.minecraft.ChatFormatting
|
|||||||
import net.minecraft.network.chat.Component
|
import net.minecraft.network.chat.Component
|
||||||
import net.minecraft.resources.ResourceLocation
|
import net.minecraft.resources.ResourceLocation
|
||||||
import net.minecraft.world.item.ItemStack
|
import net.minecraft.world.item.ItemStack
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.client.render.SkinElement
|
import ru.dbotthepony.mc.otm.client.render.SkinElement
|
||||||
import ru.dbotthepony.mc.otm.container.iterator
|
import ru.dbotthepony.mc.otm.container.iterator
|
||||||
|
import ru.dbotthepony.mc.otm.core.nonEmpty
|
||||||
import ru.dbotthepony.mc.otm.registry.MRegistry
|
import ru.dbotthepony.mc.otm.registry.MRegistry
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
@ -260,7 +261,7 @@ class AndroidResearchBuilder(
|
|||||||
|
|
||||||
for (item in items) {
|
for (item in items) {
|
||||||
var required = item.count
|
var required = item.count
|
||||||
val iterator = capability.ply.inventory.iterator()
|
val iterator = capability.ply.inventory.iterator().nonEmpty()
|
||||||
|
|
||||||
for (invItem in iterator) {
|
for (invItem in iterator) {
|
||||||
if (ItemStack.isSameItemSameTags(invItem, item)) {
|
if (ItemStack.isSameItemSameTags(invItem, item)) {
|
||||||
@ -335,7 +336,8 @@ class AndroidResearchBuilder(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (experience != 0) {
|
if (experience != 0) {
|
||||||
builder.add(TranslatableComponent("otm.android_station.research.xp_cost", experience).withStyle(
|
builder.add(
|
||||||
|
TranslatableComponent("otm.android_station.research.xp_cost", experience).withStyle(
|
||||||
if (capability.ply.experienceLevel >= experience)
|
if (capability.ply.experienceLevel >= experience)
|
||||||
ChatFormatting.DARK_GREEN
|
ChatFormatting.DARK_GREEN
|
||||||
else
|
else
|
||||||
@ -346,7 +348,8 @@ class AndroidResearchBuilder(
|
|||||||
for (value in this.type.flatPrerequisites) {
|
for (value in this.type.flatPrerequisites) {
|
||||||
val instance = capability.getResearch(value)
|
val instance = capability.getResearch(value)
|
||||||
|
|
||||||
builder.add(TranslatableComponent("android_research.status.requires", instance.screenTooltipHeader).withStyle(
|
builder.add(
|
||||||
|
TranslatableComponent("android_research.status.requires", instance.screenTooltipHeader).withStyle(
|
||||||
if (instance.isResearched)
|
if (instance.isResearched)
|
||||||
ChatFormatting.DARK_GREEN
|
ChatFormatting.DARK_GREEN
|
||||||
else
|
else
|
||||||
|
@ -6,9 +6,9 @@ import net.minecraft.network.chat.Component
|
|||||||
import net.minecraft.network.chat.ComponentContents
|
import net.minecraft.network.chat.ComponentContents
|
||||||
import net.minecraft.network.chat.MutableComponent
|
import net.minecraft.network.chat.MutableComponent
|
||||||
import net.minecraft.network.chat.contents.TranslatableContents
|
import net.minecraft.network.chat.contents.TranslatableContents
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
|
||||||
import ru.dbotthepony.mc.otm.getKeyNullable
|
import ru.dbotthepony.mc.otm.core.getKeyNullable
|
||||||
import ru.dbotthepony.mc.otm.registry.MRegistry
|
import ru.dbotthepony.mc.otm.registry.MRegistry
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.collections.HashSet
|
import kotlin.collections.HashSet
|
||||||
|
@ -9,7 +9,8 @@ import ru.dbotthepony.mc.otm.capability.extractEnergyInnerExact
|
|||||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||||
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
||||||
import ru.dbotthepony.mc.otm.registry.StatNames
|
import ru.dbotthepony.mc.otm.registry.StatNames
|
||||||
import ru.dbotthepony.mc.otm.set
|
import ru.dbotthepony.mc.otm.container.set
|
||||||
|
import ru.dbotthepony.mc.otm.core.set
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
class NanobotsArmor(android: MatteryPlayerCapability) : AndroidFeature(AndroidFeatures.NANOBOTS_ARMOR, android) {
|
class NanobotsArmor(android: MatteryPlayerCapability) : AndroidFeature(AndroidFeatures.NANOBOTS_ARMOR, android) {
|
||||||
|
@ -8,7 +8,8 @@ import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
|
|||||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||||
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
||||||
import ru.dbotthepony.mc.otm.registry.StatNames
|
import ru.dbotthepony.mc.otm.registry.StatNames
|
||||||
import ru.dbotthepony.mc.otm.set
|
import ru.dbotthepony.mc.otm.container.set
|
||||||
|
import ru.dbotthepony.mc.otm.core.set
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
class NanobotsRegeneration(android: MatteryPlayerCapability) : AndroidFeature(AndroidFeatures.NANOBOTS_REGENERATION, android) {
|
class NanobotsRegeneration(android: MatteryPlayerCapability) : AndroidFeature(AndroidFeatures.NANOBOTS_REGENERATION, android) {
|
||||||
|
@ -16,7 +16,7 @@ import net.minecraft.world.phys.shapes.CollisionContext
|
|||||||
import net.minecraft.world.phys.shapes.VoxelShape
|
import net.minecraft.world.phys.shapes.VoxelShape
|
||||||
import ru.dbotthepony.mc.otm.block.entity.AndroidStationBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.AndroidStationBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.orNull
|
import ru.dbotthepony.mc.otm.core.orNull
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import ru.dbotthepony.mc.otm.shapes.BlockShapes
|
import ru.dbotthepony.mc.otm.shapes.BlockShapes
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ import net.minecraft.world.phys.shapes.CollisionContext
|
|||||||
import net.minecraft.world.phys.shapes.VoxelShape
|
import net.minecraft.world.phys.shapes.VoxelShape
|
||||||
import ru.dbotthepony.mc.otm.addPreWorldTickerOnce
|
import ru.dbotthepony.mc.otm.addPreWorldTickerOnce
|
||||||
import ru.dbotthepony.mc.otm.block.entity.ChemicalGeneratorBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.ChemicalGeneratorBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState
|
import ru.dbotthepony.mc.otm.block.entity.WorkerState
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import ru.dbotthepony.mc.otm.shapes.BlockShapes
|
import ru.dbotthepony.mc.otm.shapes.BlockShapes
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ import net.minecraft.world.phys.shapes.VoxelShape
|
|||||||
import ru.dbotthepony.mc.otm.addPreWorldTickerOnce
|
import ru.dbotthepony.mc.otm.addPreWorldTickerOnce
|
||||||
import ru.dbotthepony.mc.otm.block.entity.GravitationStabilizerBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.GravitationStabilizerBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.block.entity.blackhole.BlackHoleBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.blackhole.BlackHoleBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState
|
import ru.dbotthepony.mc.otm.block.entity.WorkerState
|
||||||
import ru.dbotthepony.mc.otm.core.plus
|
import ru.dbotthepony.mc.otm.core.plus
|
||||||
import ru.dbotthepony.mc.otm.core.times
|
import ru.dbotthepony.mc.otm.core.times
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
|
@ -14,7 +14,7 @@ import net.minecraft.world.level.block.state.StateDefinition
|
|||||||
import net.minecraft.world.phys.shapes.CollisionContext
|
import net.minecraft.world.phys.shapes.CollisionContext
|
||||||
import net.minecraft.world.phys.shapes.VoxelShape
|
import net.minecraft.world.phys.shapes.VoxelShape
|
||||||
import ru.dbotthepony.mc.otm.block.entity.PlatePressBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.PlatePressBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState
|
import ru.dbotthepony.mc.otm.block.entity.WorkerState
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import ru.dbotthepony.mc.otm.shapes.BlockShapes
|
import ru.dbotthepony.mc.otm.shapes.BlockShapes
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ import net.minecraft.world.entity.player.Player
|
|||||||
import net.minecraft.world.inventory.AbstractContainerMenu
|
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
import net.minecraft.world.phys.AABB
|
import net.minecraft.world.phys.AABB
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
|
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
|
||||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||||
|
@ -22,7 +22,7 @@ import ru.dbotthepony.mc.otm.block.BatteryBankBlock
|
|||||||
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
|
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
|
||||||
import ru.dbotthepony.mc.otm.capability.*
|
import ru.dbotthepony.mc.otm.capability.*
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
import ru.dbotthepony.mc.otm.core.*
|
||||||
import ru.dbotthepony.mc.otm.menu.BatteryBankMenu
|
import ru.dbotthepony.mc.otm.menu.BatteryBankMenu
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import javax.annotation.ParametersAreNonnullByDefault
|
import javax.annotation.ParametersAreNonnullByDefault
|
||||||
|
@ -12,13 +12,13 @@ import net.minecraft.world.level.block.state.BlockState
|
|||||||
import net.minecraftforge.common.capabilities.Capability
|
import net.minecraftforge.common.capabilities.Capability
|
||||||
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
||||||
import net.minecraftforge.common.util.LazyOptional
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.block.CargoCrateBlock
|
import ru.dbotthepony.mc.otm.block.CargoCrateBlock
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
import ru.dbotthepony.mc.otm.ifHas
|
|
||||||
import ru.dbotthepony.mc.otm.menu.CargoCrateMenu
|
import ru.dbotthepony.mc.otm.menu.CargoCrateMenu
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import ru.dbotthepony.mc.otm.set
|
import ru.dbotthepony.mc.otm.container.set
|
||||||
|
import ru.dbotthepony.mc.otm.core.set
|
||||||
|
|
||||||
class CargoCrateBlockEntity(
|
class CargoCrateBlockEntity(
|
||||||
p_155229_: BlockPos,
|
p_155229_: BlockPos,
|
||||||
|
@ -19,11 +19,9 @@ import net.minecraftforge.common.util.LazyOptional
|
|||||||
import net.minecraftforge.energy.IEnergyStorage
|
import net.minecraftforge.energy.IEnergyStorage
|
||||||
import ru.dbotthepony.mc.otm.*
|
import ru.dbotthepony.mc.otm.*
|
||||||
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
|
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState
|
|
||||||
import ru.dbotthepony.mc.otm.capability.*
|
import ru.dbotthepony.mc.otm.capability.*
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
import ru.dbotthepony.mc.otm.core.*
|
||||||
import ru.dbotthepony.mc.otm.core.plus
|
|
||||||
import ru.dbotthepony.mc.otm.menu.ChemicalGeneratorMenu
|
import ru.dbotthepony.mc.otm.menu.ChemicalGeneratorMenu
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
|
@ -25,7 +25,7 @@ import ru.dbotthepony.mc.otm.*
|
|||||||
import ru.dbotthepony.mc.otm.block.EnergyCounterBlock
|
import ru.dbotthepony.mc.otm.block.EnergyCounterBlock
|
||||||
import ru.dbotthepony.mc.otm.capability.*
|
import ru.dbotthepony.mc.otm.capability.*
|
||||||
import ru.dbotthepony.mc.otm.compat.mekanism.MatteryToMekanismEnergyWrapper
|
import ru.dbotthepony.mc.otm.compat.mekanism.MatteryToMekanismEnergyWrapper
|
||||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
import ru.dbotthepony.mc.otm.core.*
|
||||||
import ru.dbotthepony.mc.otm.menu.EnergyCounterMenu
|
import ru.dbotthepony.mc.otm.menu.EnergyCounterMenu
|
||||||
import ru.dbotthepony.mc.otm.network.MatteryPacket
|
import ru.dbotthepony.mc.otm.network.MatteryPacket
|
||||||
import ru.dbotthepony.mc.otm.network.WorldNetworkChannel
|
import ru.dbotthepony.mc.otm.network.WorldNetworkChannel
|
||||||
|
@ -9,12 +9,11 @@ import net.minecraft.world.level.Level
|
|||||||
import net.minecraft.world.level.block.Block
|
import net.minecraft.world.level.block.Block
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
import net.minecraft.world.phys.AABB
|
import net.minecraft.world.phys.AABB
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.block.BlockGravitationStabilizer
|
import ru.dbotthepony.mc.otm.block.BlockGravitationStabilizer
|
||||||
import ru.dbotthepony.mc.otm.block.BlockGravitationStabilizerLens
|
import ru.dbotthepony.mc.otm.block.BlockGravitationStabilizerLens
|
||||||
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
|
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
|
||||||
import ru.dbotthepony.mc.otm.block.entity.blackhole.BlackHoleBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.blackhole.BlackHoleBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState
|
|
||||||
import ru.dbotthepony.mc.otm.core.plus
|
import ru.dbotthepony.mc.otm.core.plus
|
||||||
import ru.dbotthepony.mc.otm.core.times
|
import ru.dbotthepony.mc.otm.core.times
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
|
@ -23,8 +23,9 @@ import net.minecraft.network.chat.Component
|
|||||||
import net.minecraft.world.level.Level
|
import net.minecraft.world.level.Level
|
||||||
import net.minecraftforge.common.capabilities.Capability
|
import net.minecraftforge.common.capabilities.Capability
|
||||||
import ru.dbotthepony.mc.otm.addPreWorldTickerOnce
|
import ru.dbotthepony.mc.otm.addPreWorldTickerOnce
|
||||||
import ru.dbotthepony.mc.otm.ifHas
|
import ru.dbotthepony.mc.otm.core.ifHas
|
||||||
import ru.dbotthepony.mc.otm.set
|
import ru.dbotthepony.mc.otm.container.set
|
||||||
|
import ru.dbotthepony.mc.otm.core.set
|
||||||
|
|
||||||
abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: BlockPos, p_155230_: BlockState) : BlockEntity(p_155228_, p_155229_, p_155230_), MenuProvider {
|
abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: BlockPos, p_155230_: BlockState) : BlockEntity(p_155228_, p_155229_, p_155230_), MenuProvider {
|
||||||
var customDisplayName: Component? = null
|
var customDisplayName: Component? = null
|
||||||
|
@ -8,13 +8,13 @@ import net.minecraft.world.level.block.state.BlockState
|
|||||||
import net.minecraftforge.common.capabilities.Capability
|
import net.minecraftforge.common.capabilities.Capability
|
||||||
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
||||||
import net.minecraftforge.common.util.LazyOptional
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
import net.minecraftforge.energy.CapabilityEnergy
|
|
||||||
import ru.dbotthepony.mc.otm.capability.*
|
import ru.dbotthepony.mc.otm.capability.*
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||||
import ru.dbotthepony.mc.otm.ifHas
|
import ru.dbotthepony.mc.otm.core.ifHas
|
||||||
import ru.dbotthepony.mc.otm.ifPresentK
|
import ru.dbotthepony.mc.otm.core.ifPresentK
|
||||||
import ru.dbotthepony.mc.otm.set
|
import ru.dbotthepony.mc.otm.container.set
|
||||||
|
import ru.dbotthepony.mc.otm.core.set
|
||||||
|
|
||||||
abstract class MatteryPoweredBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: BlockPos, p_155230_: BlockState) : MatteryBlockEntity(p_155228_, p_155229_, p_155230_) {
|
abstract class MatteryPoweredBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: BlockPos, p_155230_: BlockState) : MatteryBlockEntity(p_155228_, p_155229_, p_155230_) {
|
||||||
abstract val energy: BlockEnergyStorageImpl
|
abstract val energy: BlockEnergyStorageImpl
|
||||||
|
@ -0,0 +1,342 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.block.entity
|
||||||
|
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntityType
|
||||||
|
import net.minecraft.core.BlockPos
|
||||||
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
|
import net.minecraft.nbt.CompoundTag
|
||||||
|
import net.minecraft.world.item.ItemStack
|
||||||
|
import net.minecraft.world.level.block.Block
|
||||||
|
import ru.dbotthepony.mc.otm.core.*
|
||||||
|
import ru.dbotthepony.mc.otm.core.map
|
||||||
|
|
||||||
|
private fun isReason(status: Any?, reason: Any) = status == null || status == reason
|
||||||
|
|
||||||
|
abstract class MatteryWorkerBlockEntity<JobType : MatteryWorkerBlockEntity.Job>(
|
||||||
|
type: BlockEntityType<*>,
|
||||||
|
blockPos: BlockPos,
|
||||||
|
blockState: BlockState,
|
||||||
|
val jobDeserializer: (tag: CompoundTag) -> JobType?
|
||||||
|
) : MatteryPoweredBlockEntity(type, blockPos, blockState) {
|
||||||
|
open class Job(
|
||||||
|
open val ticks: Double,
|
||||||
|
open val powerUsage: ImpreciseFraction = ImpreciseFraction.ZERO
|
||||||
|
) {
|
||||||
|
constructor(
|
||||||
|
tag: CompoundTag
|
||||||
|
) : this(tag.getDouble("ticks"), tag.getImpreciseFraction("power"))
|
||||||
|
|
||||||
|
open fun serializeNBT(): CompoundTag {
|
||||||
|
return CompoundTag().also {
|
||||||
|
it["ticks"] = ticks
|
||||||
|
it["power"] = powerUsage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("LeakingThis")
|
||||||
|
open class ItemJob : Job {
|
||||||
|
open val itemStack: ItemStack
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
itemStack: ItemStack,
|
||||||
|
ticks: Double,
|
||||||
|
power: ImpreciseFraction = ImpreciseFraction.ZERO
|
||||||
|
) : super(ticks, power) {
|
||||||
|
this.itemStack = itemStack
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
tag: CompoundTag
|
||||||
|
) : super(tag) {
|
||||||
|
this.itemStack = (tag["item"] as? CompoundTag)?.let { ItemStack.of(it) } ?: ItemStack.EMPTY
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun serializeNBT(): CompoundTag {
|
||||||
|
return super.serializeNBT().also {
|
||||||
|
it["item"] = itemStack.serializeNBT()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class IdleReason {
|
||||||
|
ITEM,
|
||||||
|
POWER,
|
||||||
|
MATTER,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Observing external factor, such as waiting for matter/item network tasks
|
||||||
|
*/
|
||||||
|
OBSERVING
|
||||||
|
}
|
||||||
|
|
||||||
|
data class Status(val success: Boolean, val throttleTicks: Int = 0, val idleReason: IdleReason? = null) {
|
||||||
|
companion object {
|
||||||
|
val SUCCESS = Status(true)
|
||||||
|
val FAILURE = Status(false)
|
||||||
|
val FAILURE_ITEM = Status(false, 20, IdleReason.ITEM)
|
||||||
|
val FAILURE_MATTER = Status(false, 20, IdleReason.MATTER)
|
||||||
|
val FAILURE_WAIT = Status(false, 100)
|
||||||
|
val FAILURE_WAIT_FAST = Status(false, 20)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var workTicks = 0.0
|
||||||
|
protected set
|
||||||
|
|
||||||
|
var throttleTicks = 0
|
||||||
|
protected set
|
||||||
|
|
||||||
|
var currentJob: JobType? = null
|
||||||
|
protected set
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Can be whatever you want, but [IdleReason] certainly contains all cases
|
||||||
|
*/
|
||||||
|
var idleReason: Any? = null
|
||||||
|
private set
|
||||||
|
|
||||||
|
var isIdling = false
|
||||||
|
protected set
|
||||||
|
|
||||||
|
val isUnableToProcess: Boolean get() = throttleTicks > 0
|
||||||
|
|
||||||
|
val workProgress: Float
|
||||||
|
get() {
|
||||||
|
val currentJob = currentJob ?: return 0.0f
|
||||||
|
return (workTicks / currentJob.ticks).coerceAtMost(1.0).toFloat()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun saveAdditional(nbt: CompoundTag) {
|
||||||
|
super.saveAdditional(nbt)
|
||||||
|
nbt["work_ticks"] = workTicks
|
||||||
|
currentJob?.let { nbt["job"] = it.serializeNBT() }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun load(nbt: CompoundTag) {
|
||||||
|
super.load(nbt)
|
||||||
|
|
||||||
|
workTicks = nbt.getDouble("work_ticks")
|
||||||
|
currentJob = nbt.map("job", jobDeserializer::invoke)
|
||||||
|
|
||||||
|
if (currentJob == null)
|
||||||
|
workTicks = 0.0
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setChanged() {
|
||||||
|
super.setChanged()
|
||||||
|
isIdling = false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setChangedLight() {
|
||||||
|
super.setChangedLight()
|
||||||
|
isIdling = false
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun powerLevelUpdated() {
|
||||||
|
super.setChangedLight()
|
||||||
|
|
||||||
|
if (isReason(idleReason, IdleReason.POWER)) {
|
||||||
|
isIdling = false
|
||||||
|
throttleTicks = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun itemContainerUpdated() {
|
||||||
|
super.setChanged()
|
||||||
|
|
||||||
|
if (isReason(idleReason, IdleReason.ITEM)) {
|
||||||
|
isIdling = false
|
||||||
|
throttleTicks = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun matterLevelUpdated() {
|
||||||
|
super.setChangedLight()
|
||||||
|
|
||||||
|
if (isReason(idleReason, IdleReason.MATTER)) {
|
||||||
|
isIdling = false
|
||||||
|
throttleTicks = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called whenever reaching desired amount of ticks at job
|
||||||
|
*/
|
||||||
|
protected abstract fun onJobFinish(job: JobType): Status
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [Pair.second] is reason why job can't be performed
|
||||||
|
*
|
||||||
|
* If not null, it is written to [idleReason]
|
||||||
|
*/
|
||||||
|
protected abstract fun computeNextJob(): Pair<JobType?, Any?>
|
||||||
|
|
||||||
|
protected open fun onWorkTick(requiredPower: ImpreciseFraction, extractedPower: ImpreciseFraction, ticksAdvanced: Double): Status {
|
||||||
|
return Status.SUCCESS
|
||||||
|
}
|
||||||
|
|
||||||
|
private var idleTicksAnim = 0
|
||||||
|
private var workingTicksAnim = 0
|
||||||
|
private var errorTicksAnim = 0
|
||||||
|
|
||||||
|
override fun redstoneStatusUpdated(new_blocked: Boolean, old_blocked: Boolean) {
|
||||||
|
super.redstoneStatusUpdated(new_blocked, old_blocked)
|
||||||
|
isIdling = new_blocked
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun workerLoop() {
|
||||||
|
if (errorTicksAnim > 20 && blockState.hasProperty(WorkerState.WORKER_STATE) && blockState.getValue(WorkerState.WORKER_STATE) != WorkerState.ERROR) {
|
||||||
|
level?.setBlock(blockPos, blockState.setValue(WorkerState.WORKER_STATE, WorkerState.ERROR), Block.UPDATE_CLIENTS)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (throttleTicks > 0) {
|
||||||
|
workingTicksAnim = 0
|
||||||
|
idleTicksAnim = 0
|
||||||
|
throttleTicks--
|
||||||
|
errorTicksAnim++
|
||||||
|
|
||||||
|
if (throttleTicks > 0)
|
||||||
|
return
|
||||||
|
else
|
||||||
|
isIdling = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isIdling) {
|
||||||
|
workingTicksAnim = 0
|
||||||
|
errorTicksAnim = 0
|
||||||
|
idleTicksAnim++
|
||||||
|
|
||||||
|
if (idleTicksAnim > 20 && blockState.hasProperty(WorkerState.WORKER_STATE) && blockState.getValue(
|
||||||
|
WorkerState.WORKER_STATE
|
||||||
|
) != WorkerState.IDLE
|
||||||
|
) {
|
||||||
|
level?.setBlock(blockPos, blockState.setValue(WorkerState.WORKER_STATE, WorkerState.IDLE), Block.UPDATE_CLIENTS)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var availableTicks = 1.0
|
||||||
|
|
||||||
|
while (!isIdling && weakGreaterThan(availableTicks, 0.0)) {
|
||||||
|
if (isBlockedByRedstone) {
|
||||||
|
isIdling = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
var currentJob = currentJob
|
||||||
|
|
||||||
|
if (currentJob == null) {
|
||||||
|
if (isBlockedByRedstone) {
|
||||||
|
isIdling = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
val (job, reason) = computeNextJob()
|
||||||
|
|
||||||
|
if (job == null) {
|
||||||
|
idleReason = reason
|
||||||
|
isIdling = reason != null
|
||||||
|
workingTicksAnim = 0
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
this.currentJob = job
|
||||||
|
currentJob = job
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!currentJob.powerUsage.isZero && energy.batteryLevel.isZero) {
|
||||||
|
idleReason = IdleReason.POWER
|
||||||
|
isIdling = true
|
||||||
|
idleTicksAnim++
|
||||||
|
|
||||||
|
if (idleTicksAnim > 20 && blockState.hasProperty(WorkerState.WORKER_STATE) && blockState.getValue(
|
||||||
|
WorkerState.WORKER_STATE
|
||||||
|
) != WorkerState.IDLE
|
||||||
|
) {
|
||||||
|
level?.setBlock(blockPos, blockState.setValue(WorkerState.WORKER_STATE, WorkerState.IDLE), Block.UPDATE_CLIENTS)
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
idleTicksAnim = 0
|
||||||
|
|
||||||
|
if (weakLessThan(workTicks, currentJob.ticks)) {
|
||||||
|
val ticksLeft = currentJob.ticks - workTicks
|
||||||
|
val ticksAdvanced: Double
|
||||||
|
|
||||||
|
var requiredPower: ImpreciseFraction? = null
|
||||||
|
var extractedPower: ImpreciseFraction? = null
|
||||||
|
|
||||||
|
if (currentJob.powerUsage.isZero) {
|
||||||
|
ticksAdvanced = availableTicks.coerceAtMost(ticksLeft)
|
||||||
|
} else {
|
||||||
|
requiredPower = currentJob.powerUsage * ticksLeft.coerceAtMost(availableTicks)
|
||||||
|
extractedPower = energy.extractEnergyInner(requiredPower, true)
|
||||||
|
ticksAdvanced = (extractedPower / requiredPower).toDouble().coerceAtMost(ticksLeft).coerceAtMost(availableTicks)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weakEqualDoubles(ticksAdvanced, 0.0)) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
val status = onWorkTick(requiredPower ?: ImpreciseFraction.ZERO, extractedPower ?: ImpreciseFraction.ZERO, ticksAdvanced)
|
||||||
|
|
||||||
|
if (!status.success) {
|
||||||
|
throttleTicks += status.throttleTicks
|
||||||
|
|
||||||
|
if (status.idleReason != null) {
|
||||||
|
idleReason = status.idleReason
|
||||||
|
isIdling = true
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
workingTicksAnim++
|
||||||
|
errorTicksAnim = 0
|
||||||
|
|
||||||
|
workTicks += ticksAdvanced
|
||||||
|
availableTicks -= ticksAdvanced
|
||||||
|
|
||||||
|
if (extractedPower != null) {
|
||||||
|
energy.extractEnergyInner(extractedPower, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
val status = onJobFinish(currentJob)
|
||||||
|
|
||||||
|
if (status.success) {
|
||||||
|
this.currentJob = null
|
||||||
|
workTicks = 0.0
|
||||||
|
errorTicksAnim = 0
|
||||||
|
} else {
|
||||||
|
throttleTicks += status.throttleTicks
|
||||||
|
|
||||||
|
if (status.idleReason != null) {
|
||||||
|
idleReason = status.idleReason
|
||||||
|
isIdling = true
|
||||||
|
}
|
||||||
|
|
||||||
|
errorTicksAnim++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (workingTicksAnim > 20 &&
|
||||||
|
errorTicksAnim == 0 &&
|
||||||
|
blockState.hasProperty(WorkerState.WORKER_STATE) &&
|
||||||
|
blockState.getValue(WorkerState.WORKER_STATE) != WorkerState.WORKING
|
||||||
|
)
|
||||||
|
{
|
||||||
|
level?.setBlock(blockPos, blockState.setValue(WorkerState.WORKER_STATE, WorkerState.WORKING), Block.UPDATE_CLIENTS)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun basicTicker() {
|
||||||
|
batteryChargeLoop()
|
||||||
|
workerLoop()
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package ru.dbotthepony.mc.otm.block.entity
|
package ru.dbotthepony.mc.otm.block.entity
|
||||||
|
|
||||||
|
import com.google.common.collect.Streams
|
||||||
import javax.annotation.ParametersAreNonnullByDefault
|
import javax.annotation.ParametersAreNonnullByDefault
|
||||||
import net.minecraft.core.BlockPos
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
@ -9,7 +10,6 @@ import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
|||||||
import ru.dbotthepony.mc.otm.block.matter.PatternStorageBlock
|
import ru.dbotthepony.mc.otm.block.matter.PatternStorageBlock
|
||||||
import net.minecraft.nbt.CompoundTag
|
import net.minecraft.nbt.CompoundTag
|
||||||
import net.minecraftforge.common.util.LazyOptional
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
import net.minecraftforge.items.CapabilityItemHandler
|
|
||||||
import net.minecraft.world.entity.player.Inventory
|
import net.minecraft.world.entity.player.Inventory
|
||||||
import net.minecraft.world.entity.player.Player
|
import net.minecraft.world.entity.player.Player
|
||||||
import net.minecraft.world.inventory.AbstractContainerMenu
|
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||||
@ -21,15 +21,19 @@ import net.minecraft.server.level.ServerLevel
|
|||||||
import net.minecraft.world.level.Level
|
import net.minecraft.world.level.Level
|
||||||
import net.minecraft.world.level.block.Block
|
import net.minecraft.world.level.block.Block
|
||||||
import net.minecraftforge.common.capabilities.Capability
|
import net.minecraftforge.common.capabilities.Capability
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
||||||
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.*
|
import ru.dbotthepony.mc.otm.capability.matter.*
|
||||||
|
import ru.dbotthepony.mc.otm.container.forEachCapability
|
||||||
|
import ru.dbotthepony.mc.otm.core.iterator
|
||||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
||||||
import ru.dbotthepony.mc.otm.ifHas
|
import ru.dbotthepony.mc.otm.core.ifHas
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import ru.dbotthepony.mc.otm.set
|
import ru.dbotthepony.mc.otm.core.set
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
|
import java.util.stream.Stream
|
||||||
|
|
||||||
@MethodsReturnNonnullByDefault
|
@MethodsReturnNonnullByDefault
|
||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
@ -48,13 +52,13 @@ class PatternStorageBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
if (grid != null && !ItemStack.isSameItemSameTags(new, old)) {
|
if (grid != null && !ItemStack.isSameItemSameTags(new, old)) {
|
||||||
if (!old.isEmpty) {
|
if (!old.isEmpty) {
|
||||||
old.getCapability(MatteryCapability.PATTERN).ifPresent { cap: IPatternStorage ->
|
old.getCapability(MatteryCapability.PATTERN).ifPresent { cap: IPatternStorage ->
|
||||||
cap.storedPatterns.forEach { state: PatternState? -> grid.onPatternRemoved(state!!) }
|
cap.storedPatterns.forEach { grid.onPatternRemoved(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!new.isEmpty) {
|
if (!new.isEmpty) {
|
||||||
new.getCapability(MatteryCapability.PATTERN).ifPresent { cap: IPatternStorage ->
|
new.getCapability(MatteryCapability.PATTERN).ifPresent { cap: IPatternStorage ->
|
||||||
cap.storedPatterns.forEach { state: PatternState? -> grid.onPatternAdded(state!!) }
|
cap.storedPatterns.forEach { grid.onPatternAdded(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,9 +134,9 @@ class PatternStorageBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
|
|
||||||
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
if (cap === MatteryCapability.PATTERN) return resolverPatterns.cast()
|
if (cap == MatteryCapability.PATTERN) return resolverPatterns.cast()
|
||||||
if (cap === MatteryCapability.MATTER_NODE) return resolverNode.cast()
|
if (cap == MatteryCapability.MATTER_NODE) return resolverNode.cast()
|
||||||
if (cap === CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return resolverItem.get().cast()
|
if (cap == ForgeCapabilities.ITEM_HANDLER) return resolverItem.get().cast()
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.getCapability(cap, side)
|
return super.getCapability(cap, side)
|
||||||
@ -145,16 +149,20 @@ class PatternStorageBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
return PatternStorageMenu(containerID, inventory, this)
|
return PatternStorageMenu(containerID, inventory, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override val storedPatterns: Collection<PatternState> get() {
|
override val storedPatterns: Stream<out IPatternState> get() {
|
||||||
val list = ArrayList<PatternState>()
|
val streams = ArrayList<Stream<out IPatternState>>()
|
||||||
patterns.consumeCapability(MatteryCapability.PATTERN) { capability: IPatternStorage -> list.addAll(capability.storedPatterns) }
|
|
||||||
return list
|
for (provider in patterns.iterator(MatteryCapability.PATTERN)) {
|
||||||
|
streams.add(provider.second.storedPatterns)
|
||||||
|
}
|
||||||
|
|
||||||
|
return Streams.concat(*streams.toTypedArray())
|
||||||
}
|
}
|
||||||
|
|
||||||
override val capacity: Int get() {
|
override val capacity: Int get() {
|
||||||
var stored = 0L
|
var stored = 0L
|
||||||
|
|
||||||
for (pattern in patterns.capabilityIterator(MatteryCapability.PATTERN))
|
for ((_, pattern) in patterns.iterator(MatteryCapability.PATTERN))
|
||||||
stored += pattern.capacity.toLong()
|
stored += pattern.capacity.toLong()
|
||||||
|
|
||||||
return if (stored > Int.MAX_VALUE) Int.MAX_VALUE else stored.toInt()
|
return if (stored > Int.MAX_VALUE) Int.MAX_VALUE else stored.toInt()
|
||||||
@ -163,7 +171,7 @@ class PatternStorageBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
override val stored: Int get() {
|
override val stored: Int get() {
|
||||||
var stored = 0L
|
var stored = 0L
|
||||||
|
|
||||||
for (pattern in patterns.capabilityIterator(MatteryCapability.PATTERN))
|
for ((_, pattern) in patterns.iterator(MatteryCapability.PATTERN))
|
||||||
stored += pattern.stored.toLong()
|
stored += pattern.stored.toLong()
|
||||||
|
|
||||||
return if (stored > Int.MAX_VALUE) Int.MAX_VALUE else stored.toInt()
|
return if (stored > Int.MAX_VALUE) Int.MAX_VALUE else stored.toInt()
|
||||||
@ -174,9 +182,9 @@ class PatternStorageBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
matterNode.destroy(::MatterNetworkGraph)
|
matterNode.destroy(::MatterNetworkGraph)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun insertPattern(pattern: PatternState, only_update: Boolean, simulate: Boolean): PatternInsertStatus {
|
override fun insertPattern(pattern: IPatternState, onlyUpdate: Boolean, simulate: Boolean): PatternInsertStatus {
|
||||||
for (storage in patterns.capabilityIterator(MatteryCapability.PATTERN)) {
|
for (pair in patterns.iterator(MatteryCapability.PATTERN)) {
|
||||||
val status = storage.insertPattern(pattern, only_update, simulate)
|
val status = pair.second.insertPattern(pattern, onlyUpdate, simulate)
|
||||||
|
|
||||||
if (!status.isFailed) {
|
if (!status.isFailed) {
|
||||||
if (!simulate) {
|
if (!simulate) {
|
||||||
|
@ -10,12 +10,9 @@ import net.minecraft.world.inventory.AbstractContainerMenu
|
|||||||
import net.minecraft.world.item.ItemStack
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
import net.minecraftforge.common.capabilities.Capability
|
import net.minecraftforge.common.capabilities.Capability
|
||||||
|
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
||||||
import net.minecraftforge.common.util.LazyOptional
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
import net.minecraftforge.items.CapabilityItemHandler
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.MatteryWorkerBlockEntity
|
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerJob
|
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerJobStatus
|
|
||||||
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
|
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainerFilter
|
import ru.dbotthepony.mc.otm.container.MatteryContainerFilter
|
||||||
@ -23,9 +20,13 @@ import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
|||||||
import ru.dbotthepony.mc.otm.menu.PlatePressMenu
|
import ru.dbotthepony.mc.otm.menu.PlatePressMenu
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import ru.dbotthepony.mc.otm.registry.MRecipes
|
import ru.dbotthepony.mc.otm.registry.MRecipes
|
||||||
import ru.dbotthepony.mc.otm.set
|
import ru.dbotthepony.mc.otm.container.set
|
||||||
|
import ru.dbotthepony.mc.otm.core.set
|
||||||
|
|
||||||
class PlatePressBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : MatteryWorkerBlockEntity(MBlockEntities.PLATE_PRESS, p_155229_, p_155230_) {
|
class PlatePressBlockEntity(
|
||||||
|
p_155229_: BlockPos,
|
||||||
|
p_155230_: BlockState
|
||||||
|
) : MatteryWorkerBlockEntity<MatteryWorkerBlockEntity.ItemJob>(MBlockEntities.PLATE_PRESS, p_155229_, p_155230_, ::ItemJob) {
|
||||||
val container = MatteryContainer(this::setChangedLight, 2)
|
val container = MatteryContainer(this::setChangedLight, 2)
|
||||||
override val energy = WorkerEnergyStorage(this::setChangedLight)
|
override val energy = WorkerEnergyStorage(this::setChangedLight)
|
||||||
|
|
||||||
@ -50,7 +51,7 @@ class PlatePressBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matter
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
||||||
if (cap === CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
|
if (cap == ForgeCapabilities.ITEM_HANDLER)
|
||||||
return itemHandler.get().cast()
|
return itemHandler.get().cast()
|
||||||
|
|
||||||
return super.getCapability(cap, side)
|
return super.getCapability(cap, side)
|
||||||
@ -73,32 +74,24 @@ class PlatePressBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matter
|
|||||||
return PlatePressMenu(containerID, inventory, this)
|
return PlatePressMenu(containerID, inventory, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onJobFinish(job: WorkerJob): WorkerJobStatus {
|
override fun onJobFinish(job: ItemJob): Status {
|
||||||
val resultTag = job.data["result"] as? CompoundTag ?: return WorkerJobStatus()
|
if (job.itemStack.isEmpty)
|
||||||
val result = ItemStack.of(resultTag)
|
return Status.SUCCESS
|
||||||
|
|
||||||
if (result.isEmpty)
|
if (!container.fullyAddItem(job.itemStack, start = SLOT_OUTPUT, end = SLOT_OUTPUT))
|
||||||
return WorkerJobStatus()
|
return Status.FAILURE_ITEM
|
||||||
|
|
||||||
if (!container.fullyAddItem(result, start = SLOT_OUTPUT, end = SLOT_OUTPUT)) {
|
return Status.SUCCESS
|
||||||
return WorkerJobStatus(false, 20)
|
|
||||||
}
|
|
||||||
|
|
||||||
return WorkerJobStatus()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun computeNextJob(): WorkerJob? {
|
override fun computeNextJob(): Pair<ItemJob?, IdleReason?> {
|
||||||
val level = level ?: return null
|
if (energy.batteryLevel.isZero) {
|
||||||
val recipe = level.recipeManager.getRecipeFor(MRecipes.PLATE_PRESS, container, level).orElse(null) ?: return null
|
return null to IdleReason.POWER
|
||||||
|
}
|
||||||
|
|
||||||
val copy = container[SLOT_INPUT].copy()
|
val recipe = level?.recipeManager?.getRecipeFor(MRecipes.PLATE_PRESS, container, level!!)?.orElse(null) ?: return null to IdleReason.ITEM
|
||||||
container[SLOT_INPUT].shrink(1)
|
container[SLOT_INPUT].shrink(1)
|
||||||
container.setChanged(SLOT_INPUT)
|
return ItemJob(recipe.resultItem, recipe.workTime.toDouble(), BASELINE_CONSUMPTION) to null
|
||||||
copy.count = 1
|
|
||||||
|
|
||||||
return WorkerJob(copy, recipe.workTime.toDouble(), BASELINE_CONSUMPTION, CompoundTag().also {
|
|
||||||
it["result"] = recipe.resultItem.serializeNBT()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package ru.dbotthepony.mc.otm.block.entity
|
package ru.dbotthepony.mc.otm.block.entity
|
||||||
|
|
||||||
import net.minecraft.network.chat.Component
|
import net.minecraft.network.chat.Component
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
|
|
||||||
enum class RedstoneSetting(val label: Component, val description: Component) {
|
enum class RedstoneSetting(val label: Component, val description: Component) {
|
||||||
IGNORED(TranslatableComponent("otm.gui.redstone.ignored"), TranslatableComponent("otm.gui.redstone.ignored.description")),
|
IGNORED(TranslatableComponent("otm.gui.redstone.ignored"), TranslatableComponent("otm.gui.redstone.ignored.description")),
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.block.entity
|
||||||
|
|
||||||
|
import net.minecraft.util.StringRepresentable
|
||||||
|
import net.minecraft.world.level.block.state.properties.EnumProperty
|
||||||
|
|
||||||
|
enum class WorkerState : StringRepresentable {
|
||||||
|
IDLE,
|
||||||
|
WORKING,
|
||||||
|
ERROR;
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmField
|
||||||
|
val WORKER_STATE: EnumProperty<WorkerState> = EnumProperty.create("worker", WorkerState::class.java)
|
||||||
|
@JvmField
|
||||||
|
val SEMI_WORKER_STATE: EnumProperty<WorkerState> = EnumProperty.create("worker", WorkerState::class.java, IDLE, WORKING)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getSerializedName(): String {
|
||||||
|
return if (this == IDLE) "idle" else if (this == WORKING) "working" else "error"
|
||||||
|
}
|
||||||
|
}
|
@ -31,7 +31,8 @@ import ru.dbotthepony.mc.otm.matter.getMatterValue
|
|||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import ru.dbotthepony.mc.otm.registry.MItems
|
import ru.dbotthepony.mc.otm.registry.MItems
|
||||||
import ru.dbotthepony.mc.otm.registry.MRegistry
|
import ru.dbotthepony.mc.otm.registry.MRegistry
|
||||||
import ru.dbotthepony.mc.otm.set
|
import ru.dbotthepony.mc.otm.container.set
|
||||||
|
import ru.dbotthepony.mc.otm.core.set
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
import kotlin.math.sqrt
|
import kotlin.math.sqrt
|
||||||
|
|
||||||
|
@ -23,7 +23,6 @@ import ru.dbotthepony.mc.otm.block.BlockExplosionDebugger
|
|||||||
import ru.dbotthepony.mc.otm.core.*
|
import ru.dbotthepony.mc.otm.core.*
|
||||||
import ru.dbotthepony.mc.otm.core.Vector
|
import ru.dbotthepony.mc.otm.core.Vector
|
||||||
import ru.dbotthepony.mc.otm.registry.MRegistry
|
import ru.dbotthepony.mc.otm.registry.MRegistry
|
||||||
import ru.dbotthepony.mc.otm.set
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
import kotlin.collections.HashMap
|
import kotlin.collections.HashMap
|
||||||
|
@ -15,25 +15,22 @@ import net.minecraft.world.level.block.state.BlockState
|
|||||||
import net.minecraftforge.common.capabilities.Capability
|
import net.minecraftforge.common.capabilities.Capability
|
||||||
import net.minecraftforge.common.util.LazyOptional
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
import net.minecraftforge.items.CapabilityItemHandler
|
import net.minecraftforge.items.CapabilityItemHandler
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
|
||||||
import ru.dbotthepony.mc.otm.block.matter.MatterBottlerBlock
|
import ru.dbotthepony.mc.otm.block.matter.MatterBottlerBlock
|
||||||
import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState
|
import ru.dbotthepony.mc.otm.block.entity.WorkerState
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
|
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler
|
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.MatterDirection
|
import ru.dbotthepony.mc.otm.capability.matter.MatterDirection
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.MatterHandlerImpl
|
import ru.dbotthepony.mc.otm.capability.matter.MatterHandlerImpl
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
|
||||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
||||||
import ru.dbotthepony.mc.otm.ifHas
|
|
||||||
import ru.dbotthepony.mc.otm.menu.MatterBottlerMenu
|
import ru.dbotthepony.mc.otm.menu.MatterBottlerMenu
|
||||||
import ru.dbotthepony.mc.otm.orNull
|
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import ru.dbotthepony.mc.otm.set
|
import ru.dbotthepony.mc.otm.container.set
|
||||||
|
import ru.dbotthepony.mc.otm.core.*
|
||||||
|
|
||||||
class MatterBottlerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
class MatterBottlerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||||
MatteryPoweredBlockEntity(MBlockEntities.MATTER_BOTTLER, p_155229_, p_155230_), IMatterGraphNode {
|
MatteryPoweredBlockEntity(MBlockEntities.MATTER_BOTTLER, p_155229_, p_155230_), IMatterGraphNode {
|
||||||
|
@ -15,7 +15,7 @@ import net.minecraft.world.level.block.Block
|
|||||||
import net.minecraft.world.level.block.state.BlockState
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
import net.minecraftforge.common.capabilities.Capability
|
import net.minecraftforge.common.capabilities.Capability
|
||||||
import net.minecraftforge.common.util.LazyOptional
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.block.BatteryBankBlock
|
import ru.dbotthepony.mc.otm.block.BatteryBankBlock
|
||||||
import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
@ -28,7 +28,8 @@ import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
|||||||
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
||||||
import ru.dbotthepony.mc.otm.menu.MatterCapacitorBankMenu
|
import ru.dbotthepony.mc.otm.menu.MatterCapacitorBankMenu
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import ru.dbotthepony.mc.otm.set
|
import ru.dbotthepony.mc.otm.container.set
|
||||||
|
import ru.dbotthepony.mc.otm.core.set
|
||||||
import javax.annotation.ParametersAreNonnullByDefault
|
import javax.annotation.ParametersAreNonnullByDefault
|
||||||
|
|
||||||
@MethodsReturnNonnullByDefault
|
@MethodsReturnNonnullByDefault
|
||||||
|
@ -12,24 +12,22 @@ import net.minecraft.world.item.ItemStack
|
|||||||
import net.minecraft.world.level.Level
|
import net.minecraft.world.level.Level
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
import net.minecraftforge.common.capabilities.Capability
|
import net.minecraftforge.common.capabilities.Capability
|
||||||
|
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
||||||
import net.minecraftforge.common.util.LazyOptional
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
import net.minecraftforge.items.CapabilityItemHandler
|
|
||||||
import net.minecraftforge.items.IItemHandler
|
import net.minecraftforge.items.IItemHandler
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
import ru.dbotthepony.mc.otm.block.entity.MatteryWorkerBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.MatteryWorkerBlockEntity
|
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerJob
|
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerJobStatus
|
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
|
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler
|
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.MatterDirection
|
import ru.dbotthepony.mc.otm.capability.matter.MatterDirection
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.MatterHandlerImpl
|
import ru.dbotthepony.mc.otm.capability.matter.MatterHandlerImpl
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
import ru.dbotthepony.mc.otm.container.MatteryContainerFilter
|
||||||
|
import ru.dbotthepony.mc.otm.container.set
|
||||||
|
import ru.dbotthepony.mc.otm.core.*
|
||||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
||||||
import ru.dbotthepony.mc.otm.ifHas
|
|
||||||
import ru.dbotthepony.mc.otm.item.MatterDustItem
|
import ru.dbotthepony.mc.otm.item.MatterDustItem
|
||||||
import ru.dbotthepony.mc.otm.matter.baselineComplexityDecomposeTicks
|
import ru.dbotthepony.mc.otm.matter.baselineComplexityDecomposeTicks
|
||||||
import ru.dbotthepony.mc.otm.matter.canDecompose
|
import ru.dbotthepony.mc.otm.matter.canDecompose
|
||||||
@ -37,7 +35,6 @@ import ru.dbotthepony.mc.otm.matter.getMatterValue
|
|||||||
import ru.dbotthepony.mc.otm.menu.MatterDecomposerMenu
|
import ru.dbotthepony.mc.otm.menu.MatterDecomposerMenu
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import ru.dbotthepony.mc.otm.registry.MItems
|
import ru.dbotthepony.mc.otm.registry.MItems
|
||||||
import ru.dbotthepony.mc.otm.set
|
|
||||||
|
|
||||||
fun moveMatterAsDustIntoContainer(_matterValue: ImpreciseFraction, container: MatteryContainer, OUTPUT_DUST_MAIN: Int, OUTPUT_DUST_STACKING: Int): ImpreciseFraction {
|
fun moveMatterAsDustIntoContainer(_matterValue: ImpreciseFraction, container: MatteryContainer, OUTPUT_DUST_MAIN: Int, OUTPUT_DUST_STACKING: Int): ImpreciseFraction {
|
||||||
var matterValue = _matterValue
|
var matterValue = _matterValue
|
||||||
@ -93,7 +90,29 @@ fun moveMatterAsDustIntoContainer(_matterValue: ImpreciseFraction, container: Ma
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MatterDecomposerBlockEntity(pos: BlockPos, state: BlockState)
|
class MatterDecomposerBlockEntity(pos: BlockPos, state: BlockState)
|
||||||
: MatteryWorkerBlockEntity(MBlockEntities.MATTER_DECOMPOSER, pos, state), IMatterGraphNode {
|
: MatteryWorkerBlockEntity<MatterDecomposerBlockEntity.DecomposerJob>(MBlockEntities.MATTER_DECOMPOSER, pos, state, ::DecomposerJob), IMatterGraphNode {
|
||||||
|
|
||||||
|
class DecomposerJob : Job {
|
||||||
|
val toDust: Boolean
|
||||||
|
var matterValue: ImpreciseFraction
|
||||||
|
|
||||||
|
constructor(tag: CompoundTag) : super(tag) {
|
||||||
|
toDust = tag.getBoolean("to_dust")
|
||||||
|
matterValue = tag.getImpreciseFraction("value")
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(toDust: Boolean, matterValue: ImpreciseFraction, ticks: Double) : super(ticks, BASE_CONSUMPTION) {
|
||||||
|
this.toDust = toDust
|
||||||
|
this.matterValue = matterValue
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun serializeNBT(): CompoundTag {
|
||||||
|
return super.serializeNBT().also {
|
||||||
|
it["to_dust"] = toDust
|
||||||
|
it["value"] = matterValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override val energy = WorkerEnergyStorage(this, ENERGY_STORAGE, MAX_IO)
|
override val energy = WorkerEnergyStorage(this, ENERGY_STORAGE, MAX_IO)
|
||||||
private var valid = true
|
private var valid = true
|
||||||
@ -110,13 +129,18 @@ class MatterDecomposerBlockEntity(pos: BlockPos, state: BlockState)
|
|||||||
private var resolverNode = LazyOptional.of { this }
|
private var resolverNode = LazyOptional.of { this }
|
||||||
|
|
||||||
// вход, выход
|
// вход, выход
|
||||||
@JvmField
|
|
||||||
val container = MatteryContainer(this::setChangedLight, 3)
|
val container = MatteryContainer(this::setChangedLight, 3)
|
||||||
|
|
||||||
private val itemHandler = LazyOptional.of<IItemHandler> {
|
private val itemHandler = LazyOptional.of<IItemHandler> {
|
||||||
container.handler(
|
container.handler(object : MatteryContainerFilter {
|
||||||
{ slot: Int, stack: ItemStack -> slot == INPUT_SLOT && canDecompose(stack) },
|
override fun canInsert(slot: Int, stack: ItemStack): Boolean {
|
||||||
{ slot: Int, _: Int, _: ItemStack -> slot != INPUT_SLOT })
|
return slot == INPUT_SLOT && canDecompose(stack)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean {
|
||||||
|
return slot != INPUT_SLOT
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
override val defaultDisplayName: Component
|
override val defaultDisplayName: Component
|
||||||
@ -156,39 +180,35 @@ class MatterDecomposerBlockEntity(pos: BlockPos, state: BlockState)
|
|||||||
|
|
||||||
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
if (cap === MatteryCapability.MATTER) return resolverMatter.cast()
|
if (cap == MatteryCapability.MATTER) return resolverMatter.cast()
|
||||||
if (cap === MatteryCapability.MATTER_NODE) return resolverNode.cast()
|
if (cap == MatteryCapability.MATTER_NODE) return resolverNode.cast()
|
||||||
if (cap === CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return itemHandler.cast()
|
if (cap == ForgeCapabilities.ITEM_HANDLER) return itemHandler.cast()
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.getCapability(cap, side)
|
return super.getCapability(cap, side)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onJobFinish(job: WorkerJob): WorkerJobStatus {
|
override fun onJobFinish(job: DecomposerJob): Status {
|
||||||
var matterValue = ImpreciseFraction.deserializeNBT(job.data["value"])
|
if (job.toDust) {
|
||||||
|
job.matterValue = moveMatterAsDustIntoContainer(job.matterValue, container, OUTPUT_DUST_MAIN, OUTPUT_DUST_STACKING)
|
||||||
|
|
||||||
if (job.data.getBoolean("to_dust")) {
|
if (!job.matterValue.isZero) {
|
||||||
matterValue = moveMatterAsDustIntoContainer(matterValue, container, OUTPUT_DUST_MAIN, OUTPUT_DUST_STACKING)
|
return Status.FAILURE_WAIT_FAST
|
||||||
|
|
||||||
if (!matterValue.isZero) {
|
|
||||||
job.data["value"] = matterValue.serializeNBT()
|
|
||||||
return WorkerJobStatus(20)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return WorkerJobStatus()
|
return Status.SUCCESS
|
||||||
}
|
}
|
||||||
|
|
||||||
matterValue -= matter.receiveMatterInner(matterValue, false)
|
job.matterValue -= matter.receiveMatterInner(job.matterValue, false)
|
||||||
|
|
||||||
if (matterValue.isPositive) {
|
if (job.matterValue.isPositive) {
|
||||||
job.data["value"] = matterValue.serializeNBT()
|
return Status.FAILURE_MATTER
|
||||||
return WorkerJobStatus(false, 20)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return WorkerJobStatus()
|
return Status.SUCCESS
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun computeNextJob(): WorkerJob? {
|
override fun computeNextJob(): Pair<DecomposerJob?, IdleReason?> {
|
||||||
val stack = container[INPUT_SLOT]
|
val stack = container[INPUT_SLOT]
|
||||||
|
|
||||||
if (!stack.isEmpty) {
|
if (!stack.isEmpty) {
|
||||||
@ -197,19 +217,13 @@ class MatterDecomposerBlockEntity(pos: BlockPos, state: BlockState)
|
|||||||
|
|
||||||
if (canDecompose(copy)) {
|
if (canDecompose(copy)) {
|
||||||
val matter = getMatterValue(copy)
|
val matter = getMatterValue(copy)
|
||||||
|
stack.count--
|
||||||
|
|
||||||
if (!matter.isZero) {
|
return DecomposerJob((level?.random?.nextDouble() ?: 1.0) <= 0.2, matter.value, matter.complexity * baselineComplexityDecomposeTicks) to null
|
||||||
stack.count--
|
|
||||||
|
|
||||||
return WorkerJob(copy, matter.complexity * baselineComplexityDecomposeTicks, BASE_CONSUMPTION, CompoundTag().also {
|
|
||||||
it["to_dust"] = (level?.random?.nextDouble() ?: 1.0) <= 0.2
|
|
||||||
it["value"] = matter.value.serializeNBT()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
return null to IdleReason.ITEM
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setRemoved() {
|
override fun setRemoved() {
|
||||||
|
@ -3,7 +3,6 @@ package ru.dbotthepony.mc.otm.block.entity.matter
|
|||||||
import net.minecraft.core.BlockPos
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.core.Direction
|
import net.minecraft.core.Direction
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterTaskProvider
|
|
||||||
import ru.dbotthepony.mc.otm.menu.MatterPanelMenu
|
import ru.dbotthepony.mc.otm.menu.MatterPanelMenu
|
||||||
import net.minecraft.world.entity.player.Inventory
|
import net.minecraft.world.entity.player.Inventory
|
||||||
import net.minecraft.world.entity.player.Player
|
import net.minecraft.world.entity.player.Player
|
||||||
@ -12,10 +11,6 @@ import net.minecraftforge.common.util.LazyOptional
|
|||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import java.util.HashMap
|
import java.util.HashMap
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.MatterTask
|
|
||||||
import java.util.stream.Collectors
|
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.MatterTaskAllocation
|
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.PatternState
|
|
||||||
import net.minecraft.nbt.CompoundTag
|
import net.minecraft.nbt.CompoundTag
|
||||||
import net.minecraft.nbt.ListTag
|
import net.minecraft.nbt.ListTag
|
||||||
import net.minecraft.nbt.Tag
|
import net.minecraft.nbt.Tag
|
||||||
@ -23,17 +18,18 @@ import net.minecraft.network.chat.Component
|
|||||||
import net.minecraft.server.level.ServerLevel
|
import net.minecraft.server.level.ServerLevel
|
||||||
import net.minecraft.world.level.Level
|
import net.minecraft.world.level.Level
|
||||||
import net.minecraftforge.common.capabilities.Capability
|
import net.minecraftforge.common.capabilities.Capability
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity
|
||||||
|
import ru.dbotthepony.mc.otm.capability.matter.*
|
||||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
import java.util.List
|
import java.util.stream.Stream
|
||||||
|
|
||||||
class MatterPanelBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
class MatterPanelBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||||
MatteryBlockEntity(MBlockEntities.MATTER_PANEL, p_155229_, p_155230_), IMatterGraphNode, IMatterTaskProvider {
|
MatteryBlockEntity(MBlockEntities.MATTER_PANEL, p_155229_, p_155230_), IMatterGraphNode, IReplicationTaskProvider {
|
||||||
|
|
||||||
private val listeners = ArrayList<MatterPanelMenu>()
|
private val listeners = ArrayList<MatterPanelMenu>()
|
||||||
override val matterNode = Graph6Node<IMatterGraphNode>(this)
|
override val matterNode = Graph6Node<IMatterGraphNode>(this)
|
||||||
@ -88,61 +84,59 @@ class MatterPanelBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
matterNode.destroy(::MatterNetworkGraph)
|
matterNode.destroy(::MatterNetworkGraph)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getTaskHandler(): IMatterTaskProvider? {
|
override fun getTaskHandler(): IReplicationTaskProvider {
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
private val _tasks = HashMap<UUID, MatterTask>()
|
private val _tasks = HashMap<UUID, ReplicationTask>()
|
||||||
|
|
||||||
override val tasks: Collection<MatterTask> get() {
|
override val replicationTasks: Stream<ReplicationTask> get() {
|
||||||
return _tasks.values.stream().filter { task: MatterTask? -> task!!.required() > 0 }.collect(Collectors.toList()) as Collection<MatterTask>
|
return _tasks.values.stream().filter { it.required > 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
override val allTasks: Collection<MatterTask> get() {
|
override val allReplicationTasks: Stream<ReplicationTask> get() {
|
||||||
return List.copyOf(_tasks.values) as Collection<MatterTask>
|
return _tasks.values.stream()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun allocateTask(simulate: Boolean): MatterTaskAllocation? {
|
override fun allocateTask(simulate: Boolean): ReplicationTaskAllocation? {
|
||||||
val graph = matterNode.graph as MatterNetworkGraph? ?: return null
|
val graph = matterNode.graph as MatterNetworkGraph? ?: return null
|
||||||
|
|
||||||
for ((key, task) in _tasks) {
|
for ((key, task) in _tasks) {
|
||||||
if (task.required > 0) {
|
if (task.required > 0) {
|
||||||
val getPattern = graph.getPattern(task.pattern!!)
|
val pattern = task.patternId?.let(graph::getPattern) ?: continue
|
||||||
|
|
||||||
if (getPattern != null) {
|
if (!simulate) {
|
||||||
if (!simulate) {
|
val new = task.allocate()
|
||||||
val new = task.shrinkRequired(1)
|
_tasks[key] = new
|
||||||
_tasks[key] = new
|
listeners.forEach { it.taskUpdated(new) }
|
||||||
listeners.forEach { menu: MatterPanelMenu -> menu.taskUpdated(new) }
|
graph.onMatterTaskUpdated(new, task)
|
||||||
graph.onMatterTaskUpdated(new, task)
|
setChanged()
|
||||||
setChanged()
|
|
||||||
}
|
|
||||||
|
|
||||||
return MatterTaskAllocation(task, getPattern)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ReplicationTaskAllocation(task, pattern)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun notifyTaskCompletion(task: MatterTask): Boolean {
|
override fun notifyTaskCompletion(taskId: UUID): Boolean {
|
||||||
var localTask = _tasks[task.id] ?: return false
|
var localTask = _tasks[taskId] ?: return false
|
||||||
val oldTask = localTask
|
val oldTask = localTask
|
||||||
|
|
||||||
localTask = localTask.shrinkInProgress(1)
|
localTask = localTask.finish()
|
||||||
val graph = matterNode.graph as MatterNetworkGraph?
|
val graph = matterNode.graph as MatterNetworkGraph?
|
||||||
|
|
||||||
// Задача полностью выполнена
|
// Задача полностью выполнена
|
||||||
if (localTask.required <= 0 && localTask.in_progress <= 0) {
|
if (localTask.required <= 0 && localTask.inProgress <= 0) {
|
||||||
_tasks.remove(task.id)
|
_tasks.remove(taskId)
|
||||||
graph?.onMatterTaskCreated(task)
|
graph?.onMatterTaskFinished(localTask)
|
||||||
listeners.forEach { menu: MatterPanelMenu -> menu.taskRemoved(localTask) }
|
listeners.forEach { it.taskRemoved(localTask) }
|
||||||
} else {
|
} else {
|
||||||
// Задача обновлена
|
// Задача обновлена
|
||||||
_tasks[task.id()] = localTask
|
_tasks[taskId] = localTask
|
||||||
graph?.onMatterTaskUpdated(localTask, oldTask)
|
graph?.onMatterTaskUpdated(localTask, oldTask)
|
||||||
listeners.forEach { menu: MatterPanelMenu -> menu.taskUpdated(localTask) }
|
listeners.forEach { it.taskUpdated(localTask) }
|
||||||
}
|
}
|
||||||
|
|
||||||
setChanged()
|
setChanged()
|
||||||
@ -155,7 +149,7 @@ class MatterPanelBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
val list = ListTag()
|
val list = ListTag()
|
||||||
|
|
||||||
for (task in _tasks.values) {
|
for (task in _tasks.values) {
|
||||||
list.add(task!!.serializeNBT())
|
list.add(task.serializeNBT())
|
||||||
}
|
}
|
||||||
|
|
||||||
nbt.put("tasks", list)
|
nbt.put("tasks", list)
|
||||||
@ -167,16 +161,16 @@ class MatterPanelBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
val list = nbt.getList("tasks", Tag.TAG_COMPOUND.toInt())
|
val list = nbt.getList("tasks", Tag.TAG_COMPOUND.toInt())
|
||||||
|
|
||||||
for (tag in list) {
|
for (tag in list) {
|
||||||
val task = MatterTask.deserializeNBT(tag)
|
val task = ReplicationTask.deserializeNBT(tag)
|
||||||
|
|
||||||
if (task != null) {
|
if (task != null) {
|
||||||
_tasks[task.id()] = task
|
_tasks[task.id] = task
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getTask(id: UUID): MatterTask? {
|
override fun getTask(id: UUID): ReplicationTask? {
|
||||||
return _tasks[id]
|
return _tasks[id]?.asImmutable()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun removeTask(id: UUID) {
|
fun removeTask(id: UUID) {
|
||||||
@ -185,19 +179,17 @@ class MatterPanelBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
|
|
||||||
(matterNode.graph as MatterNetworkGraph?)?.onMatterTaskRemoved(task)
|
(matterNode.graph as MatterNetworkGraph?)?.onMatterTaskRemoved(task)
|
||||||
|
|
||||||
listeners.forEach { menu: MatterPanelMenu -> menu.taskRemoved(task) }
|
listeners.forEach { it.taskRemoved(task) }
|
||||||
setChanged()
|
setChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun removeTask(state: PatternState) = removeTask(state.id)
|
fun addTask(state: IPatternState, count: Int): IReplicationTask<*> {
|
||||||
|
val task = ReplicationTask(UUID.randomUUID(), state.id, state.item, 0, 0, count)
|
||||||
fun addTask(state: PatternState, how_much: Int): MatterTask {
|
_tasks[task.id] = task
|
||||||
val task = MatterTask(UUID.randomUUID(), state.id, state.item, 0, 0, how_much)
|
|
||||||
_tasks[task.id()] = task
|
|
||||||
|
|
||||||
(matterNode.graph as MatterNetworkGraph?)?.onMatterTaskCreated(task)
|
(matterNode.graph as MatterNetworkGraph?)?.onMatterTaskCreated(task)
|
||||||
|
|
||||||
listeners.forEach { menu: MatterPanelMenu -> menu.taskUpdated(task) }
|
listeners.forEach { it.taskUpdated(task) }
|
||||||
setChanged()
|
setChanged()
|
||||||
|
|
||||||
return task
|
return task
|
||||||
|
@ -12,13 +12,10 @@ import net.minecraft.world.item.ItemStack
|
|||||||
import net.minecraft.world.level.Level
|
import net.minecraft.world.level.Level
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
import net.minecraftforge.common.capabilities.Capability
|
import net.minecraftforge.common.capabilities.Capability
|
||||||
|
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
||||||
import net.minecraftforge.common.util.LazyOptional
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
import net.minecraftforge.items.CapabilityItemHandler
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
import ru.dbotthepony.mc.otm.block.entity.MatteryWorkerBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.MatteryWorkerBlockEntity
|
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerJob
|
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerJobStatus
|
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerTickContext
|
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
|
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler
|
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler
|
||||||
@ -30,26 +27,27 @@ import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
|||||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
||||||
import ru.dbotthepony.mc.otm.ifHas
|
|
||||||
import ru.dbotthepony.mc.otm.item.MatterDustItem
|
import ru.dbotthepony.mc.otm.item.MatterDustItem
|
||||||
|
import ru.dbotthepony.mc.otm.core.map
|
||||||
import ru.dbotthepony.mc.otm.menu.MatterRecyclerMenu
|
import ru.dbotthepony.mc.otm.menu.MatterRecyclerMenu
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import ru.dbotthepony.mc.otm.set
|
import ru.dbotthepony.mc.otm.container.set
|
||||||
|
import ru.dbotthepony.mc.otm.core.set
|
||||||
|
|
||||||
class MatterRecyclerBlockEntity(blockPos: BlockPos, blockState: BlockState)
|
class MatterRecyclerBlockEntity(blockPos: BlockPos, blockState: BlockState)
|
||||||
: MatteryWorkerBlockEntity(MBlockEntities.MATTER_RECYCLER, blockPos, blockState), IMatterGraphNode {
|
: MatteryWorkerBlockEntity<MatteryWorkerBlockEntity.Job>(MBlockEntities.MATTER_RECYCLER, blockPos, blockState, ::Job), IMatterGraphNode {
|
||||||
|
|
||||||
val matter = MatterHandlerImpl(
|
val matter = MatterHandlerImpl(
|
||||||
this::setChangedLight,
|
this::matterLevelUpdated,
|
||||||
MatterDirection.EXTRACT,
|
MatterDirection.EXTRACT,
|
||||||
STORAGE
|
STORAGE
|
||||||
)
|
)
|
||||||
|
|
||||||
val container = MatteryContainer(this::setChangedLight, 1)
|
val container = MatteryContainer(this::itemContainerUpdated, 1)
|
||||||
override val matterNode = Graph6Node<IMatterGraphNode>(this)
|
override val matterNode = Graph6Node<IMatterGraphNode>(this)
|
||||||
private var resolverNode = LazyOptional.of { this }
|
private var resolverNode = LazyOptional.of { this }
|
||||||
private var valid = true
|
private var valid = true
|
||||||
override val energy = WorkerEnergyStorage(this, MAX_POWER)
|
override val energy = WorkerEnergyStorage(this::powerLevelUpdated, MAX_POWER)
|
||||||
|
|
||||||
override fun getMatterHandler(): IMatterHandler {
|
override fun getMatterHandler(): IMatterHandler {
|
||||||
return matter
|
return matter
|
||||||
@ -99,7 +97,7 @@ class MatterRecyclerBlockEntity(blockPos: BlockPos, blockState: BlockState)
|
|||||||
|
|
||||||
override fun load(nbt: CompoundTag) {
|
override fun load(nbt: CompoundTag) {
|
||||||
super.load(nbt)
|
super.load(nbt)
|
||||||
nbt.ifHas("matter", CompoundTag::class.java, matter::deserializeNBT)
|
nbt.map("matter", matter::deserializeNBT)
|
||||||
container.deserializeNBT(nbt["container"])
|
container.deserializeNBT(nbt["container"])
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,15 +105,12 @@ class MatterRecyclerBlockEntity(blockPos: BlockPos, blockState: BlockState)
|
|||||||
if (!valid)
|
if (!valid)
|
||||||
return super.getCapability(cap, side)
|
return super.getCapability(cap, side)
|
||||||
|
|
||||||
if (cap === CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
|
return when (cap) {
|
||||||
return itemHandler.get().cast()
|
ForgeCapabilities.ITEM_HANDLER -> itemHandler.get().cast()
|
||||||
} else if (cap === MatteryCapability.MATTER) {
|
MatteryCapability.MATTER -> matter.get().cast()
|
||||||
return matter.get().cast()
|
MatteryCapability.MATTER_NODE -> resolverNode.cast()
|
||||||
} else if (cap === MatteryCapability.MATTER_NODE) {
|
else -> super.getCapability(cap, side)
|
||||||
return resolverNode.cast()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.getCapability(cap, side)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override val defaultDisplayName: Component
|
override val defaultDisplayName: Component
|
||||||
@ -125,41 +120,39 @@ class MatterRecyclerBlockEntity(blockPos: BlockPos, blockState: BlockState)
|
|||||||
return MatterRecyclerMenu(containerID, inventory, this)
|
return MatterRecyclerMenu(containerID, inventory, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onJobFinish(job: WorkerJob): WorkerJobStatus {
|
override fun onJobFinish(job: Job): Status {
|
||||||
// вся логика в onWorkTick
|
// вся логика в onWorkTick
|
||||||
return WorkerJobStatus()
|
return Status.SUCCESS
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun computeNextJob(): WorkerJob? {
|
override fun computeNextJob(): Pair<Job?, IdleReason?> {
|
||||||
if (matter.missingMatter.isZero)
|
if (matter.missingMatter.isZero)
|
||||||
return null
|
return null to IdleReason.ITEM
|
||||||
|
|
||||||
val stack = container[0]
|
val stack = container[0]
|
||||||
|
|
||||||
if (stack.isEmpty || stack.item !is MatterDustItem) {
|
if (stack.isEmpty || stack.item !is MatterDustItem) {
|
||||||
return null
|
return null to IdleReason.ITEM
|
||||||
}
|
}
|
||||||
|
|
||||||
val copy = stack.copy()
|
val dustMatter = (stack.item as MatterDustItem).getMatterValue(stack.copy().also { it.count = 1 }) ?: return null to IdleReason.ITEM
|
||||||
copy.count = 1
|
|
||||||
|
|
||||||
val dustMatter = (stack.item as MatterDustItem).getMatterValue(copy) ?: return null
|
|
||||||
stack.shrink(1)
|
stack.shrink(1)
|
||||||
return WorkerJob(copy, dustMatter.value.toDouble() * MATTER_TICKS, POWER_CONSUMPTION)
|
container.setChanged(0)
|
||||||
|
return Job(dustMatter.value.toDouble() * MATTER_TICKS, POWER_CONSUMPTION) to null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onWorkTick(context: WorkerTickContext): WorkerJobStatus {
|
override fun onWorkTick(requiredPower: ImpreciseFraction, extractedPower: ImpreciseFraction, ticksAdvanced: Double): Status {
|
||||||
if ((level?.random?.nextDouble() ?: 1.0) <= 0.4)
|
if ((level?.random?.nextDouble() ?: 1.0) <= 0.4)
|
||||||
return WorkerJobStatus()
|
return Status.SUCCESS
|
||||||
|
|
||||||
val receive = if (context.ticksAdvanced == 1.0) MATTER_PER_TICK else MATTER_PER_TICK * context.ticksAdvanced
|
val receive = MATTER_PER_TICK * ticksAdvanced
|
||||||
val received = matter.receiveMatterInner(receive, true)
|
val received = matter.receiveMatterInner(receive, true)
|
||||||
|
|
||||||
if (receive != received)
|
if (receive != received)
|
||||||
return WorkerJobStatus(false, 20)
|
return Status.FAILURE_MATTER
|
||||||
|
|
||||||
matter.receiveMatterInner(receive, false)
|
matter.receiveMatterInner(receive, false)
|
||||||
return WorkerJobStatus()
|
return Status.SUCCESS
|
||||||
}
|
}
|
||||||
|
|
||||||
fun tick() {
|
fun tick() {
|
||||||
|
@ -8,49 +8,93 @@ import net.minecraft.server.level.ServerLevel
|
|||||||
import net.minecraft.world.entity.player.Inventory
|
import net.minecraft.world.entity.player.Inventory
|
||||||
import net.minecraft.world.entity.player.Player
|
import net.minecraft.world.entity.player.Player
|
||||||
import net.minecraft.world.inventory.AbstractContainerMenu
|
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||||
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraft.world.level.Level
|
import net.minecraft.world.level.Level
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
import net.minecraftforge.common.capabilities.Capability
|
import net.minecraftforge.common.capabilities.Capability
|
||||||
|
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
||||||
import net.minecraftforge.common.util.LazyOptional
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
import net.minecraftforge.items.CapabilityItemHandler
|
import ru.dbotthepony.mc.otm.block.entity.MatteryWorkerBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.MatteryWorkerBlockEntity
|
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerJob
|
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerJobStatus
|
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerTickContext
|
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
|
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.*
|
import ru.dbotthepony.mc.otm.capability.matter.*
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainerFilterOnlyOut
|
import ru.dbotthepony.mc.otm.container.MatteryContainerFilterOnlyOut
|
||||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
|
||||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
||||||
import ru.dbotthepony.mc.otm.ifHas
|
|
||||||
import ru.dbotthepony.mc.otm.matter.baselineComplexityReplicateTicks
|
import ru.dbotthepony.mc.otm.matter.baselineComplexityReplicateTicks
|
||||||
import ru.dbotthepony.mc.otm.matter.getMatterValue
|
import ru.dbotthepony.mc.otm.matter.getMatterValue
|
||||||
import ru.dbotthepony.mc.otm.menu.MatterReplicatorMenu
|
import ru.dbotthepony.mc.otm.menu.MatterReplicatorMenu
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import ru.dbotthepony.mc.otm.set
|
import ru.dbotthepony.mc.otm.container.set
|
||||||
|
import ru.dbotthepony.mc.otm.core.*
|
||||||
|
|
||||||
class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||||
MatteryWorkerBlockEntity(MBlockEntities.MATTER_REPLICATOR, p_155229_, p_155230_), IMatterGraphNode {
|
MatteryWorkerBlockEntity<MatterReplicatorBlockEntity.ReplicatorJob>(MBlockEntities.MATTER_REPLICATOR, p_155229_, p_155230_, {
|
||||||
|
try {
|
||||||
|
ReplicatorJob(it)
|
||||||
|
} catch(err: NoSuchElementException) {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}), IMatterGraphNode {
|
||||||
|
|
||||||
override val energy = WorkerEnergyStorage(this, STORAGE, MAX_IO)
|
class ReplicatorJob : ItemJob {
|
||||||
|
val matterPerTick: ImpreciseFraction
|
||||||
|
val task: ReplicationTask
|
||||||
|
var matterValue: ImpreciseFraction
|
||||||
|
val pattern: PatternState?
|
||||||
|
val asDust: Boolean
|
||||||
|
|
||||||
|
constructor(tag: CompoundTag) : super(tag) {
|
||||||
|
matterPerTick = tag.getImpreciseFraction("matterPerTick")
|
||||||
|
matterValue = tag.getImpreciseFraction("matterValue")
|
||||||
|
pattern = tag.map("pattern", PatternState::deserializeNBT)
|
||||||
|
asDust = tag.getBoolean("asDust")
|
||||||
|
task = tag.map("task", ReplicationTask::deserializeNBT) ?: throw NoSuchElementException("Unable to deserialize matter task")
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
itemStack: ItemStack,
|
||||||
|
matterPerTick: ImpreciseFraction,
|
||||||
|
task: ReplicationTask,
|
||||||
|
matterValue: ImpreciseFraction,
|
||||||
|
pattern: PatternState?,
|
||||||
|
asDust: Boolean,
|
||||||
|
ticks: Double,
|
||||||
|
) : super(itemStack, ticks, BASE_CONSUMPTION) {
|
||||||
|
this.matterPerTick = matterPerTick
|
||||||
|
this.task = task
|
||||||
|
this.matterValue = matterValue
|
||||||
|
this.pattern = pattern
|
||||||
|
this.asDust = asDust
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun serializeNBT(): CompoundTag {
|
||||||
|
return super.serializeNBT().also {
|
||||||
|
it["matterPerTick"] = this.matterPerTick
|
||||||
|
it["task"] = this.task.serializeNBT()
|
||||||
|
it["matterValue"] = this.matterValue
|
||||||
|
|
||||||
|
if (this.pattern != null)
|
||||||
|
it["pattern"] = this.pattern.serializeNBT()
|
||||||
|
|
||||||
|
it["asDust"] = this.asDust
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override val energy = WorkerEnergyStorage(this::powerLevelUpdated, STORAGE, MAX_IO)
|
||||||
override val matterNode = Graph6Node<IMatterGraphNode>(this)
|
override val matterNode = Graph6Node<IMatterGraphNode>(this)
|
||||||
private val resolverNode = LazyOptional.of { this }
|
private val resolverNode = LazyOptional.of { this }
|
||||||
|
|
||||||
@JvmField
|
|
||||||
val matter = MatterHandlerImpl(
|
val matter = MatterHandlerImpl(
|
||||||
this::setChangedLight,
|
this::matterLevelUpdated,
|
||||||
MatterDirection.RECEIVE,
|
MatterDirection.RECEIVE,
|
||||||
ImpreciseFraction(2)
|
ImpreciseFraction(2)
|
||||||
)
|
)
|
||||||
|
|
||||||
// обычные запросы
|
val container = MatteryContainer(this::itemContainerUpdated, 5)
|
||||||
@JvmField
|
|
||||||
val container = MatteryContainer(this::setChangedLight, 5)
|
|
||||||
private val itemHandler = container.handler(MatteryContainerFilterOnlyOut)
|
private val itemHandler = container.handler(MatteryContainerFilterOnlyOut)
|
||||||
|
|
||||||
override val defaultDisplayName: Component
|
override val defaultDisplayName: Component
|
||||||
@ -60,38 +104,42 @@ class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
return MatterReplicatorMenu(containerID, inventory, this)
|
return MatterReplicatorMenu(containerID, inventory, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onJobFinish(job: WorkerJob): WorkerJobStatus {
|
override fun onJobFinish(job: ReplicatorJob): Status {
|
||||||
if (job.data.getBoolean("as_dust")) {
|
if (job.asDust) {
|
||||||
val matterValue = moveMatterAsDustIntoContainer(ImpreciseFraction.deserializeNBT(job["matter"]), container, OUTPUT_DUST_MAIN, OUTPUT_DUST_STACKING)
|
job.matterValue = moveMatterAsDustIntoContainer(job.matterValue, container, OUTPUT_DUST_MAIN, OUTPUT_DUST_STACKING)
|
||||||
|
|
||||||
if (!matterValue.isZero) {
|
if (!job.matterValue.isZero) {
|
||||||
job["matter"] = matterValue.serializeNBT()
|
return Status.FAILURE_WAIT
|
||||||
return WorkerJobStatus(false, 20)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(matterNode.graph as MatterNetworkGraph?)?.notifyTaskCompletion(MatterTask.deserializeNBT(job["task"])!!)
|
(matterNode.graph as MatterNetworkGraph?)?.notifyTaskCompletion(job.task.id)
|
||||||
|
return Status.SUCCESS
|
||||||
return WorkerJobStatus()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!container.fullyAddItem(job.stack, FIRST_ACTUAL_OUTPUT_SLOT .. LAST_ACTUAL_OUTPUT_SLOT)) {
|
if (!container.fullyAddItem(job.itemStack, FIRST_ACTUAL_OUTPUT_SLOT .. LAST_ACTUAL_OUTPUT_SLOT)) {
|
||||||
return WorkerJobStatus(false, 20)
|
return Status.FAILURE_ITEM
|
||||||
}
|
}
|
||||||
|
|
||||||
(matterNode.graph as MatterNetworkGraph?)?.notifyTaskCompletion(MatterTask.deserializeNBT(job["task"])!!)
|
(matterNode.graph as MatterNetworkGraph?)?.notifyTaskCompletion(job.task.id)
|
||||||
return WorkerJobStatus()
|
return Status.SUCCESS
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMatterTaskCreated(task: MatterTask) {
|
override fun onMatterTaskCreated(task: IReplicationTask<*>) {
|
||||||
isIdling = false
|
if (idleReason == IdleReason.OBSERVING) {
|
||||||
|
isIdling = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMatterTaskUpdated(new_state: MatterTask, old_state: MatterTask) {
|
override fun <T : IReplicationTask<*>> onMatterTaskUpdated(newState: T, oldState: T) {
|
||||||
isIdling = false
|
if (idleReason == IdleReason.OBSERVING) {
|
||||||
|
isIdling = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPatternAdded(state: PatternState) {
|
override fun onPatternAdded(state: IPatternState) {
|
||||||
isIdling = false
|
if (idleReason == IdleReason.OBSERVING) {
|
||||||
|
isIdling = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setRemoved() {
|
override fun setRemoved() {
|
||||||
@ -106,33 +154,35 @@ class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
MatterNetworkGraph.discoverFull(this, matterNode)
|
MatterNetworkGraph.discoverFull(this, matterNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun computeNextJob(): WorkerJob? {
|
override fun computeNextJob(): Pair<ReplicatorJob?, IdleReason?> {
|
||||||
val graph = matterNode.graph as MatterNetworkGraph? ?: return null
|
if (energy.batteryLevel < BASE_CONSUMPTION) {
|
||||||
val allocation = graph.allocateTask(false) ?: return null
|
return null to IdleReason.POWER
|
||||||
|
}
|
||||||
|
|
||||||
|
val graph = matterNode.graph as MatterNetworkGraph? ?: return null to null
|
||||||
|
val allocation = graph.allocateTask(simulate = false) ?: return null to IdleReason.OBSERVING
|
||||||
val stack = allocation.task.stack(1)
|
val stack = allocation.task.stack(1)
|
||||||
val matter = getMatterValue(stack)
|
val matter = getMatterValue(stack)
|
||||||
|
|
||||||
// ????????
|
// ????????
|
||||||
if (matter.isZero) return null
|
if (matter.isZero) return null to null
|
||||||
|
|
||||||
val ticks = matter.complexity * baselineComplexityReplicateTicks
|
val ticks = matter.complexity * baselineComplexityReplicateTicks
|
||||||
|
|
||||||
return WorkerJob(stack, ticks, BASE_CONSUMPTION, CompoundTag().also {
|
return ReplicatorJob(
|
||||||
it["matter_per_tick"] = (matter.value / ticks).serializeNBT()
|
itemStack = stack,
|
||||||
it["task"] = allocation.task.serializeNBT()
|
matterPerTick = matter.value / ticks,
|
||||||
it["matter"] = matter.value.serializeNBT()
|
task = allocation.task.asImmutable(),
|
||||||
|
matterValue = matter.value,
|
||||||
if (allocation.pattern != null)
|
pattern = allocation.pattern?.asImmutable(),
|
||||||
it["pattern"] = allocation.pattern.serializeNBT()
|
asDust = (level?.random?.nextDouble() ?: 1.0) > (allocation.pattern?.researchPercent ?: 2.0),
|
||||||
|
ticks = ticks,
|
||||||
if ((level?.random?.nextDouble() ?: 1.0) > (allocation.pattern?.research ?: 2.0))
|
) to null
|
||||||
it["as_dust"] = true
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onWorkTick(context: WorkerTickContext): WorkerJobStatus {
|
override fun onWorkTick(requiredPower: ImpreciseFraction, extractedPower: ImpreciseFraction, ticksAdvanced: Double): Status {
|
||||||
val drainPerTick = ImpreciseFraction.deserializeNBT(context.job.data["matter_per_tick"])
|
val drainPerTick = currentJob!!.matterPerTick * ticksAdvanced
|
||||||
val graph = matterNode.graph as MatterNetworkGraph? ?: return WorkerJobStatus(false, 20)
|
val graph = matterNode.graph as MatterNetworkGraph? ?: return Status.FAILURE_WAIT_FAST
|
||||||
|
|
||||||
if (matter.extractMatterInner(drainPerTick, true) < drainPerTick) {
|
if (matter.extractMatterInner(drainPerTick, true) < drainPerTick) {
|
||||||
// в машине недостаточно материи
|
// в машине недостаточно материи
|
||||||
@ -142,44 +192,42 @@ class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
val toExtract = drainPerTick - matter.extractMatterInner(drainPerTick, true)
|
val toExtract = drainPerTick - matter.extractMatterInner(drainPerTick, true)
|
||||||
val drain = graph.extractMatter(toExtract, true)
|
val drain = graph.extractMatter(toExtract, true)
|
||||||
|
|
||||||
if (drain < toExtract) {
|
if (drain != toExtract) {
|
||||||
// недостаточно материи в сети
|
// недостаточно материи в сети
|
||||||
return WorkerJobStatus(false, 200)
|
return Status.FAILURE_MATTER
|
||||||
}
|
}
|
||||||
|
|
||||||
// достаточно материи в сети + внутри машины
|
// достаточно материи в сети + внутри машины
|
||||||
matter.extractMatterInner(drainPerTick, false)
|
matter.extractMatterInner(drainPerTick, false)
|
||||||
graph.extractMatter(drain, false)
|
graph.extractMatter(drain, false)
|
||||||
return WorkerJobStatus()
|
return Status.SUCCESS
|
||||||
} else {
|
} else {
|
||||||
// в тик требуется меньше материи, чем её может хранить репликатор
|
// в тик требуется меньше материи, чем её может хранить репликатор
|
||||||
// примем из сети недостающее количество бака материи, или 200 тиков репликации, что меньше
|
// примем из сети недостающее количество бака материи, или 200 тиков репликации, что меньше
|
||||||
val toExtract =
|
val drain = graph.extractMatter(matter.missingMatter.coerceAtMost(drainPerTick * DRAIN_MULT), true)
|
||||||
matter.missingMatter.coerceAtMost(drainPerTick.times(DRAIN_MULT))
|
|
||||||
|
|
||||||
val drain = graph.extractMatter(toExtract, true)
|
|
||||||
|
|
||||||
if (drain.isZero) {
|
if (drain.isZero) {
|
||||||
// в сети нет материи
|
// в сети нет материи
|
||||||
return WorkerJobStatus(false, 200)
|
return Status.FAILURE_MATTER
|
||||||
}
|
}
|
||||||
|
|
||||||
val received = matter.receiveMatterOuter(drain, false)
|
val received = matter.receiveMatterOuter(drain, false)
|
||||||
graph.extractMatter(received, false)
|
graph.extractMatter(received, false)
|
||||||
|
|
||||||
// получили материю, проверяем возможность работы
|
// получили материю, проверяем возможность работы
|
||||||
if (matter.extractMatterInner(drainPerTick, false) >= drainPerTick) {
|
if (matter.extractMatterInner(drainPerTick, true) >= drainPerTick) {
|
||||||
return WorkerJobStatus()
|
matter.extractMatterInner(drainPerTick, false)
|
||||||
|
return Status.SUCCESS
|
||||||
} else {
|
} else {
|
||||||
// :(
|
// :(
|
||||||
return WorkerJobStatus(false, 200)
|
return Status.FAILURE_WAIT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// в машине достаточно материи
|
// в машине достаточно материи
|
||||||
matter.extractMatterInner(drainPerTick, false)
|
matter.extractMatterInner(drainPerTick, false)
|
||||||
return WorkerJobStatus()
|
return Status.SUCCESS
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun saveAdditional(nbt: CompoundTag) {
|
override fun saveAdditional(nbt: CompoundTag) {
|
||||||
@ -191,10 +239,7 @@ class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
override fun load(nbt: CompoundTag) {
|
override fun load(nbt: CompoundTag) {
|
||||||
super.load(nbt)
|
super.load(nbt)
|
||||||
container.deserializeNBT(nbt["container"])
|
container.deserializeNBT(nbt["container"])
|
||||||
|
nbt.map("matter", matter::deserializeNBT)
|
||||||
nbt.ifHas("matter", CompoundTag::class.java) {
|
|
||||||
matter.deserializeNBT(it)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private var valid = true
|
private var valid = true
|
||||||
@ -213,8 +258,8 @@ class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
|
|
||||||
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
if (cap === MatteryCapability.MATTER_NODE) return resolverNode.cast()
|
if (cap == MatteryCapability.MATTER_NODE) return resolverNode.cast()
|
||||||
if (cap === CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return itemHandler.get().cast()
|
if (cap == ForgeCapabilities.ITEM_HANDLER) return itemHandler.get().cast()
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.getCapability(cap, side)
|
return super.getCapability(cap, side)
|
||||||
|
@ -12,16 +12,16 @@ import net.minecraft.world.item.ItemStack
|
|||||||
import net.minecraft.world.level.Level
|
import net.minecraft.world.level.Level
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
import net.minecraftforge.common.capabilities.Capability
|
import net.minecraftforge.common.capabilities.Capability
|
||||||
|
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
||||||
import net.minecraftforge.common.util.LazyOptional
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
import net.minecraftforge.items.CapabilityItemHandler
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
import ru.dbotthepony.mc.otm.block.entity.MatteryWorkerBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.MatteryWorkerBlockEntity
|
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerJob
|
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerJobStatus
|
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
|
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
|
||||||
|
import ru.dbotthepony.mc.otm.capability.matter.IPatternState
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.PatternState
|
import ru.dbotthepony.mc.otm.capability.matter.PatternState
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
|
import ru.dbotthepony.mc.otm.container.MatteryContainerFilter
|
||||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
||||||
@ -32,26 +32,38 @@ import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class MatterScannerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
class MatterScannerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||||
MatteryWorkerBlockEntity(MBlockEntities.MATTER_SCANNER, p_155229_, p_155230_), IMatterGraphNode {
|
MatteryWorkerBlockEntity<MatteryWorkerBlockEntity.ItemJob>(MBlockEntities.MATTER_SCANNER, p_155229_, p_155230_, ::ItemJob), IMatterGraphNode {
|
||||||
|
|
||||||
val container = MatteryContainer(this::setChanged, 1)
|
val container = MatteryContainer(this::itemContainerUpdated, 1)
|
||||||
override val energy = WorkerEnergyStorage(this, STORAGE, MAX_IO)
|
override val energy = WorkerEnergyStorage(this::powerLevelUpdated, STORAGE, MAX_IO)
|
||||||
private val itemHandler = container.handler(
|
|
||||||
{ _: Int, stack: ItemStack -> canDecompose(stack) },
|
private val itemHandler = container.handler(object : MatteryContainerFilter {
|
||||||
{ _: Int, _: Int, _: ItemStack -> isIdling }
|
override fun canInsert(slot: Int, stack: ItemStack): Boolean {
|
||||||
)
|
return canDecompose(stack)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean {
|
||||||
|
return isIdling
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
// IMatterGraphNode
|
// IMatterGraphNode
|
||||||
override fun onPatternAdded(state: PatternState) {
|
override fun onPatternAdded(state: IPatternState) {
|
||||||
isIdling = false
|
if (idleReason == IdleReason.OBSERVING) {
|
||||||
|
isIdling = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPatternRemoved(state: PatternState) {
|
override fun onPatternRemoved(state: IPatternState) {
|
||||||
isIdling = false
|
if (idleReason == IdleReason.OBSERVING) {
|
||||||
|
isIdling = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPatternUpdated(new_state: PatternState, old_state: PatternState) {
|
override fun onPatternUpdated(newState: IPatternState, oldState: IPatternState) {
|
||||||
isIdling = false
|
if (idleReason == IdleReason.OBSERVING) {
|
||||||
|
isIdling = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// /IMatterGraphNode
|
// /IMatterGraphNode
|
||||||
|
|
||||||
@ -61,7 +73,7 @@ class MatterScannerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
|
|
||||||
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
if (cap === CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return itemHandler.get().cast()
|
if (cap == ForgeCapabilities.ITEM_HANDLER) return itemHandler.get().cast()
|
||||||
if (cap == MatteryCapability.MATTER_NODE) return resolverNode.cast()
|
if (cap == MatteryCapability.MATTER_NODE) return resolverNode.cast()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,72 +117,71 @@ class MatterScannerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
super.load(nbt)
|
super.load(nbt)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onJobFinish(job: WorkerJob): WorkerJobStatus {
|
override fun onJobFinish(job: ItemJob): Status {
|
||||||
val grid = matterNode.graph as MatterNetworkGraph? ?: return WorkerJobStatus(false, 100)
|
val grid = matterNode.graph as MatterNetworkGraph? ?: return Status.FAILURE_WAIT
|
||||||
|
|
||||||
val stack = job.stack
|
val stack = job.itemStack
|
||||||
if (stack.isEmpty || !hasMatterValue(stack)) return WorkerJobStatus()
|
if (stack.isEmpty || !hasMatterValue(stack)) return Status.SUCCESS
|
||||||
|
|
||||||
val getState = grid.findPatterns(stack.item)
|
var findState: IPatternState? = null
|
||||||
var findState: PatternState? = null
|
|
||||||
|
|
||||||
for (state in getState) {
|
for (state in grid.patterns.filter { it.item === stack.item }) {
|
||||||
if (state.item() === stack.item) {
|
if (findState == null && state.researchPercent < 1.0) {
|
||||||
if (findState == null && state.research() < 1.0) {
|
findState = state
|
||||||
findState = state
|
} else if (findState != null && findState.researchPercent < state.researchPercent) {
|
||||||
} else if (findState != null && findState.research() < state.research()) {
|
findState = state
|
||||||
findState = state
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val new =
|
val new =
|
||||||
if (findState != null) {
|
if (findState != null) {
|
||||||
PatternState(findState.id(), stack.item, findState.research() + 0.2)
|
PatternState(findState.id, stack.item, findState.researchPercent + 0.2)
|
||||||
} else {
|
} else {
|
||||||
PatternState(UUID.randomUUID(), stack.item, 0.2)
|
PatternState(UUID.randomUUID(), stack.item, 0.2)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!grid.insertPattern(new, onlyUpdate = false, simulate = false).isFailed) {
|
if (!grid.insertPattern(new, onlyUpdate = false, simulate = false).isFailed) {
|
||||||
return WorkerJobStatus()
|
return Status.SUCCESS
|
||||||
} else {
|
} else {
|
||||||
return WorkerJobStatus(false, 200)
|
return Status.FAILURE_WAIT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun computeNextJob(): WorkerJob? {
|
override fun computeNextJob(): Pair<ItemJob?, IdleReason?> {
|
||||||
val grid = matterNode.graph as MatterNetworkGraph? ?: return null
|
if (energy.batteryLevel.isZero) {
|
||||||
|
return null to IdleReason.POWER
|
||||||
|
}
|
||||||
|
|
||||||
|
val grid = matterNode.graph as MatterNetworkGraph? ?: return null to null
|
||||||
|
|
||||||
val stack = container.getItem(0)
|
val stack = container.getItem(0)
|
||||||
if (stack.isEmpty || !canDecompose(stack)) return null
|
if (stack.isEmpty || !canDecompose(stack)) return null to IdleReason.ITEM
|
||||||
|
|
||||||
val getState = grid.findPatterns(stack.item)
|
var findState: IPatternState? = null
|
||||||
var findState: PatternState? = null
|
|
||||||
|
|
||||||
for (state in getState) {
|
for (state in grid.patterns.filter { it.item === stack.item }) {
|
||||||
if (state.item === stack.item && state.research < 1.0) {
|
if (state.researchPercent < 1.0) {
|
||||||
findState = state
|
findState = state
|
||||||
} else if (state.item === stack.item && state.research >= 1.0) {
|
} else if (state.researchPercent >= 1.0) {
|
||||||
return null
|
return null to IdleReason.ITEM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val new: PatternState =
|
val new: IPatternState =
|
||||||
if (findState != null) {
|
if (findState != null) {
|
||||||
PatternState(findState.id, stack.item, findState.research + 0.2)
|
PatternState(findState.id, stack.item, findState.researchPercent + 0.2)
|
||||||
} else {
|
} else {
|
||||||
PatternState(UUID.randomUUID(), stack.item, 0.2)
|
PatternState(UUID.randomUUID(), stack.item, 0.2)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!grid.insertPattern(new, onlyUpdate = false, simulate = true).isFailed) {
|
if (!grid.insertPattern(new, onlyUpdate = false, simulate = true).isFailed) {
|
||||||
val copy = stack.copy()
|
val copy = stack.copy().also { it.count = 1 }
|
||||||
copy.count = 1
|
|
||||||
stack.shrink(1)
|
stack.shrink(1)
|
||||||
container.setChanged()
|
container.setChanged()
|
||||||
return WorkerJob(copy, getMatterValue(copy).complexity * baselineComplexityScanTicks, BASE_CONSUMPTION)
|
return ItemJob(copy, getMatterValue(copy).complexity * baselineComplexityScanTicks, BASE_CONSUMPTION) to null
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
return null to IdleReason.ITEM
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setLevel(p_155231_: Level) {
|
override fun setLevel(p_155231_: Level) {
|
||||||
|
@ -13,16 +13,17 @@ import net.minecraft.world.level.Level
|
|||||||
import net.minecraft.world.level.block.state.BlockState
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
import net.minecraftforge.common.capabilities.Capability
|
import net.minecraftforge.common.capabilities.Capability
|
||||||
import net.minecraftforge.common.util.LazyOptional
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.graph.storage.BasicStorageGraphNode
|
import ru.dbotthepony.mc.otm.graph.storage.BasicStorageGraphNode
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
|
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||||
import ru.dbotthepony.mc.otm.ifHas
|
import ru.dbotthepony.mc.otm.core.ifHas
|
||||||
import ru.dbotthepony.mc.otm.menu.DriveRackMenu
|
import ru.dbotthepony.mc.otm.menu.DriveRackMenu
|
||||||
import ru.dbotthepony.mc.otm.set
|
import ru.dbotthepony.mc.otm.container.set
|
||||||
|
import ru.dbotthepony.mc.otm.core.set
|
||||||
import ru.dbotthepony.mc.otm.graph.storage.StorageNetworkGraph
|
import ru.dbotthepony.mc.otm.graph.storage.StorageNetworkGraph
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import ru.dbotthepony.mc.otm.storage.*
|
import ru.dbotthepony.mc.otm.storage.*
|
||||||
|
@ -11,16 +11,17 @@ import net.minecraft.world.item.ItemStack
|
|||||||
import net.minecraft.world.level.block.Block
|
import net.minecraft.world.level.block.Block
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.block.storage.DriveViewerBlock
|
import ru.dbotthepony.mc.otm.block.storage.DriveViewerBlock
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState
|
import ru.dbotthepony.mc.otm.block.entity.WorkerState
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
|
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
import ru.dbotthepony.mc.otm.menu.DriveViewerMenu
|
import ru.dbotthepony.mc.otm.menu.DriveViewerMenu
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import ru.dbotthepony.mc.otm.set
|
import ru.dbotthepony.mc.otm.container.set
|
||||||
|
import ru.dbotthepony.mc.otm.core.set
|
||||||
import javax.annotation.ParametersAreNonnullByDefault
|
import javax.annotation.ParametersAreNonnullByDefault
|
||||||
|
|
||||||
@MethodsReturnNonnullByDefault
|
@MethodsReturnNonnullByDefault
|
||||||
|
@ -26,26 +26,26 @@ import net.minecraftforge.common.util.INBTSerializable
|
|||||||
import net.minecraftforge.common.util.LazyOptional
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
import net.minecraftforge.network.NetworkEvent
|
import net.minecraftforge.network.NetworkEvent
|
||||||
import org.apache.logging.log4j.LogManager
|
import org.apache.logging.log4j.LogManager
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
|
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
|
||||||
import ru.dbotthepony.mc.otm.client.minecraft
|
import ru.dbotthepony.mc.otm.client.minecraft
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
import ru.dbotthepony.mc.otm.get
|
import ru.dbotthepony.mc.otm.container.get
|
||||||
import ru.dbotthepony.mc.otm.graph.storage.BasicStorageGraphNode
|
import ru.dbotthepony.mc.otm.graph.storage.BasicStorageGraphNode
|
||||||
import ru.dbotthepony.mc.otm.graph.storage.StorageNetworkGraph
|
import ru.dbotthepony.mc.otm.graph.storage.StorageNetworkGraph
|
||||||
import ru.dbotthepony.mc.otm.ifHas
|
import ru.dbotthepony.mc.otm.core.ifHas
|
||||||
import ru.dbotthepony.mc.otm.menu.ItemMonitorMenu
|
import ru.dbotthepony.mc.otm.menu.ItemMonitorMenu
|
||||||
import ru.dbotthepony.mc.otm.network.MatteryPacket
|
import ru.dbotthepony.mc.otm.network.MatteryPacket
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import ru.dbotthepony.mc.otm.set
|
import ru.dbotthepony.mc.otm.container.set
|
||||||
|
import ru.dbotthepony.mc.otm.core.set
|
||||||
import ru.dbotthepony.mc.otm.storage.*
|
import ru.dbotthepony.mc.otm.storage.*
|
||||||
import java.math.BigInteger
|
import java.math.BigInteger
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.function.Supplier
|
import java.util.function.Supplier
|
||||||
import kotlin.collections.HashMap
|
import kotlin.collections.HashMap
|
||||||
import kotlin.collections.HashSet
|
|
||||||
|
|
||||||
class ItemMonitorPlayerSettings : INBTSerializable<CompoundTag>, MatteryPacket {
|
class ItemMonitorPlayerSettings : INBTSerializable<CompoundTag>, MatteryPacket {
|
||||||
enum class RefillSource(val component: Component) {
|
enum class RefillSource(val component: Component) {
|
||||||
@ -296,6 +296,7 @@ class ItemMonitorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
override fun stillValid(p_18946_: Player) = true
|
override fun stillValid(p_18946_: Player) = true
|
||||||
|
|
||||||
override fun getItem(p_18941_: Int): ItemStack {
|
override fun getItem(p_18941_: Int): ItemStack {
|
||||||
|
require(p_18941_ == 1) { "Invalid slot ID: $p_18941_" }
|
||||||
return craftingRecipe?.resultItem?.copy() ?: ItemStack.EMPTY
|
return craftingRecipe?.resultItem?.copy() ?: ItemStack.EMPTY
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -423,12 +424,13 @@ class ItemMonitorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun removeItemNoUpdate(p_18951_: Int): ItemStack {
|
override fun removeItemNoUpdate(p_18951_: Int): ItemStack {
|
||||||
// return removeItem(p_18951_, craftingRecipe?.resultItem?.count ?: Int.MAX_VALUE)
|
|
||||||
throw UnsupportedOperationException()
|
throw UnsupportedOperationException()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setItem(p_18944_: Int, p_18945_: ItemStack) {
|
override fun setItem(p_18944_: Int, p_18945_: ItemStack) {
|
||||||
throw UnsupportedOperationException()
|
if ((craftingRecipe != null && !craftingRecipe!!.resultItem.isEmpty) || !p_18945_.isEmpty) {
|
||||||
|
throw RuntimeException("BUG-DETECT: Tried to set crafting result slot item to something, and either we have crafting recipe which have valid result, or we are trying to set slot to non empty item: $p_18945_")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setChanged() {}
|
override fun setChanged() {}
|
||||||
|
@ -25,10 +25,7 @@ import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
|
|||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
|
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
|
||||||
import ru.dbotthepony.mc.otm.container.ItemFilter
|
import ru.dbotthepony.mc.otm.container.ItemFilter
|
||||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
import ru.dbotthepony.mc.otm.core.*
|
||||||
import ru.dbotthepony.mc.otm.core.isPositive
|
|
||||||
import ru.dbotthepony.mc.otm.core.isZero
|
|
||||||
import ru.dbotthepony.mc.otm.core.plus
|
|
||||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||||
import ru.dbotthepony.mc.otm.graph.GraphNodeListener
|
import ru.dbotthepony.mc.otm.graph.GraphNodeListener
|
||||||
import ru.dbotthepony.mc.otm.graph.storage.BasicStorageGraphNode
|
import ru.dbotthepony.mc.otm.graph.storage.BasicStorageGraphNode
|
||||||
|
@ -23,8 +23,7 @@ import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
|
|||||||
import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.capability.*
|
import ru.dbotthepony.mc.otm.capability.*
|
||||||
import ru.dbotthepony.mc.otm.container.ItemFilter
|
import ru.dbotthepony.mc.otm.container.ItemFilter
|
||||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
import ru.dbotthepony.mc.otm.core.*
|
||||||
import ru.dbotthepony.mc.otm.core.plus
|
|
||||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||||
import ru.dbotthepony.mc.otm.graph.GraphNodeListener
|
import ru.dbotthepony.mc.otm.graph.GraphNodeListener
|
||||||
import ru.dbotthepony.mc.otm.graph.storage.BasicStorageGraphNode
|
import ru.dbotthepony.mc.otm.graph.storage.BasicStorageGraphNode
|
||||||
|
@ -13,7 +13,7 @@ import net.minecraft.world.level.block.state.BlockState
|
|||||||
import net.minecraftforge.common.capabilities.Capability
|
import net.minecraftforge.common.capabilities.Capability
|
||||||
import net.minecraftforge.common.util.LazyOptional
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
|
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
|
||||||
@ -24,7 +24,8 @@ import ru.dbotthepony.mc.otm.graph.storage.StorageNetworkGraph
|
|||||||
import ru.dbotthepony.mc.otm.menu.StoragePowerSupplierMenu
|
import ru.dbotthepony.mc.otm.menu.StoragePowerSupplierMenu
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import ru.dbotthepony.mc.otm.registry.MNames
|
import ru.dbotthepony.mc.otm.registry.MNames
|
||||||
import ru.dbotthepony.mc.otm.set
|
import ru.dbotthepony.mc.otm.container.set
|
||||||
|
import ru.dbotthepony.mc.otm.core.set
|
||||||
|
|
||||||
class StoragePowerSupplierBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryPoweredBlockEntity(MBlockEntities.STORAGE_POWER_SUPPLIER, blockPos, blockState) {
|
class StoragePowerSupplierBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryPoweredBlockEntity(MBlockEntities.STORAGE_POWER_SUPPLIER, blockPos, blockState) {
|
||||||
override val defaultDisplayName: Component
|
override val defaultDisplayName: Component
|
||||||
|
@ -1,261 +0,0 @@
|
|||||||
package ru.dbotthepony.mc.otm.block.entity.worker
|
|
||||||
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType
|
|
||||||
import net.minecraft.core.BlockPos
|
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
|
||||||
import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
|
|
||||||
import net.minecraft.nbt.CompoundTag
|
|
||||||
import net.minecraft.nbt.DoubleTag
|
|
||||||
import net.minecraft.world.level.block.Block
|
|
||||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
|
||||||
import ru.dbotthepony.mc.otm.core.weakGreaterOrEqual
|
|
||||||
import ru.dbotthepony.mc.otm.core.weakLessThan
|
|
||||||
import ru.dbotthepony.mc.otm.ifHas
|
|
||||||
import ru.dbotthepony.mc.otm.set
|
|
||||||
|
|
||||||
abstract class MatteryWorkerBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: BlockPos, p_155230_: BlockState) :
|
|
||||||
MatteryPoweredBlockEntity(p_155228_, p_155229_, p_155230_) {
|
|
||||||
var workTicks = 0.0
|
|
||||||
protected set
|
|
||||||
|
|
||||||
var throttleTicks = 0
|
|
||||||
protected set
|
|
||||||
|
|
||||||
var currentJob: WorkerJob? = null
|
|
||||||
protected set
|
|
||||||
|
|
||||||
// если isIdling То ничего не делать
|
|
||||||
// isIdling должна быть выставлена в true если что то изменилось, что могло создать работу
|
|
||||||
var isIdling = false
|
|
||||||
protected set
|
|
||||||
|
|
||||||
val isUnableToProcess: Boolean get() = throttleTicks > 0
|
|
||||||
|
|
||||||
val workProgress: Float
|
|
||||||
get() {
|
|
||||||
val currentJob = currentJob ?: return 0.0f
|
|
||||||
return (workTicks / currentJob.ticks).coerceAtMost(1.0).toFloat()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun saveAdditional(nbt: CompoundTag) {
|
|
||||||
super.saveAdditional(nbt)
|
|
||||||
nbt["work_ticks"] = workTicks
|
|
||||||
currentJob?.let { nbt["current_job"] = it.serializeNBT() }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun load(nbt: CompoundTag) {
|
|
||||||
super.load(nbt)
|
|
||||||
|
|
||||||
nbt.ifHas("work_ticks", DoubleTag::class.java) {
|
|
||||||
workTicks = it.asDouble
|
|
||||||
}
|
|
||||||
|
|
||||||
currentJob = WorkerJob.deserializeNBT(nbt["current_job"])
|
|
||||||
|
|
||||||
if (currentJob == null)
|
|
||||||
workTicks = 0.0
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setChanged() {
|
|
||||||
super.setChanged()
|
|
||||||
isIdling = false
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setChangedLight() {
|
|
||||||
super.setChangedLight()
|
|
||||||
isIdling = false
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param job current job
|
|
||||||
* @return whenever machine can finish it's job. return false if machine for whatever reason can't finish it's job,
|
|
||||||
* waiting on conditions to be met
|
|
||||||
*/
|
|
||||||
protected abstract fun onJobFinish(job: WorkerJob): WorkerJobStatus
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param context context for current job
|
|
||||||
* @return whenever machine can perform it
|
|
||||||
*/
|
|
||||||
protected open fun onWorkTick(context: WorkerTickContext): WorkerJobStatus {
|
|
||||||
return WorkerJobStatus()
|
|
||||||
}
|
|
||||||
|
|
||||||
private var idleTicksAnim = 0
|
|
||||||
private var workingTicksAnim = 0
|
|
||||||
private var errorTicksAnim = 0
|
|
||||||
|
|
||||||
override fun redstoneStatusUpdated(new_blocked: Boolean, old_blocked: Boolean) {
|
|
||||||
super.redstoneStatusUpdated(new_blocked, old_blocked)
|
|
||||||
isIdling = new_blocked
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun workerLoop() {
|
|
||||||
if (errorTicksAnim > 20 && blockState.hasProperty(WorkerState.WORKER_STATE) && blockState.getValue(WorkerState.WORKER_STATE) != WorkerState.ERROR) {
|
|
||||||
level?.setBlock(blockPos, blockState.setValue(WorkerState.WORKER_STATE, WorkerState.ERROR), Block.UPDATE_CLIENTS)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (throttleTicks > 0) {
|
|
||||||
workingTicksAnim = 0
|
|
||||||
idleTicksAnim = 0
|
|
||||||
throttleTicks--
|
|
||||||
errorTicksAnim++
|
|
||||||
|
|
||||||
if (throttleTicks > 0)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isIdling) {
|
|
||||||
workingTicksAnim = 0
|
|
||||||
errorTicksAnim = 0
|
|
||||||
idleTicksAnim++
|
|
||||||
|
|
||||||
if (idleTicksAnim > 20 && blockState.hasProperty(WorkerState.WORKER_STATE) && blockState.getValue(WorkerState.WORKER_STATE) != WorkerState.IDLE) {
|
|
||||||
level?.setBlock(blockPos, blockState.setValue(WorkerState.WORKER_STATE, WorkerState.IDLE), Block.UPDATE_CLIENTS)
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var currentJob = currentJob
|
|
||||||
|
|
||||||
if (currentJob == null) {
|
|
||||||
if (isBlockedByRedstone) {
|
|
||||||
isIdling = true
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val input = computeNextJob()
|
|
||||||
|
|
||||||
if (input == null) {
|
|
||||||
isIdling = true
|
|
||||||
workingTicksAnim = 0
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
this.currentJob = input
|
|
||||||
currentJob = input
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isBlockedByRedstone) {
|
|
||||||
isIdling = true
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!currentJob.power.isZero && energy.batteryLevel.isZero) {
|
|
||||||
idleTicksAnim++
|
|
||||||
|
|
||||||
if (idleTicksAnim > 20 && blockState.hasProperty(WorkerState.WORKER_STATE) && blockState.getValue(WorkerState.WORKER_STATE) != WorkerState.IDLE) {
|
|
||||||
level?.setBlock(blockPos, blockState.setValue(WorkerState.WORKER_STATE, WorkerState.IDLE), Block.UPDATE_CLIENTS)
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
idleTicksAnim = 0
|
|
||||||
|
|
||||||
if (weakLessThan(workTicks, currentJob.ticks)) {
|
|
||||||
if (!currentJob.power.isZero) {
|
|
||||||
// сколько осталось тиков работать
|
|
||||||
val ticksLeft = currentJob.ticks - workTicks
|
|
||||||
val requiredPower: ImpreciseFraction
|
|
||||||
|
|
||||||
// запрос энергии на то количество, сколько действительно осталось работать
|
|
||||||
if (ticksLeft > 1.0) {
|
|
||||||
requiredPower = currentJob.power
|
|
||||||
} else {
|
|
||||||
requiredPower = currentJob.power * ticksLeft
|
|
||||||
}
|
|
||||||
|
|
||||||
val extractedPower = if (requiredPower.isZero) ImpreciseFraction.ZERO else energy.extractEnergyInner(requiredPower, true)
|
|
||||||
|
|
||||||
// сколько тиков мы "проработали"
|
|
||||||
// может быть меньше, чем единица, если недостаточно питания или мы завершаем работу,
|
|
||||||
// для которой осталось дробное количество тиков
|
|
||||||
val ticksAdvanced = (extractedPower / requiredPower).toDouble().coerceAtMost(ticksLeft)
|
|
||||||
val ticksAdvancedWeak = if (requiredPower.isZero) 1.0 else ticksAdvanced
|
|
||||||
val status = onWorkTick(WorkerTickContext(currentJob, requiredPower, extractedPower, ticksAdvanced))
|
|
||||||
|
|
||||||
if (!status.valid) {
|
|
||||||
throttleTicks += status.throttle
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
workingTicksAnim++
|
|
||||||
errorTicksAnim = 0
|
|
||||||
|
|
||||||
val updatedWorkTicks = (workTicks + ticksAdvancedWeak).coerceAtMost(currentJob.ticks)
|
|
||||||
|
|
||||||
if (weakGreaterOrEqual(updatedWorkTicks, currentJob.ticks)) {
|
|
||||||
workTicks = currentJob.ticks
|
|
||||||
energy.extractEnergyInner(extractedPower * (1.0 - (updatedWorkTicks - currentJob.ticks)), false)
|
|
||||||
|
|
||||||
val finish = onJobFinish(currentJob)
|
|
||||||
|
|
||||||
if (finish.valid) {
|
|
||||||
this.currentJob = null
|
|
||||||
workTicks = 0.0
|
|
||||||
} else {
|
|
||||||
throttleTicks += finish.throttle
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
workTicks = updatedWorkTicks
|
|
||||||
energy.extractEnergyInner(extractedPower, false)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
val ticksLeft = (currentJob.ticks - workTicks).coerceAtMost(1.0)
|
|
||||||
val status = onWorkTick(WorkerTickContext(currentJob, ImpreciseFraction.ZERO, ImpreciseFraction.ZERO, ticksLeft))
|
|
||||||
|
|
||||||
if (!status.valid) {
|
|
||||||
throttleTicks += status.throttle
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
workingTicksAnim++
|
|
||||||
errorTicksAnim = 0
|
|
||||||
workTicks = (workTicks + 1.0).coerceAtMost(currentJob.ticks)
|
|
||||||
|
|
||||||
if (weakGreaterOrEqual(workTicks, currentJob.ticks)) {
|
|
||||||
val finish = onJobFinish(currentJob)
|
|
||||||
|
|
||||||
if (finish.valid) {
|
|
||||||
this.currentJob = null
|
|
||||||
workTicks = 0.0
|
|
||||||
} else {
|
|
||||||
throttleTicks += finish.throttle
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
val finish = onJobFinish(currentJob)
|
|
||||||
|
|
||||||
if (finish.valid) {
|
|
||||||
this.currentJob = null
|
|
||||||
workTicks = 0.0
|
|
||||||
errorTicksAnim = 0
|
|
||||||
} else {
|
|
||||||
throttleTicks += finish.throttle
|
|
||||||
errorTicksAnim++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (workingTicksAnim > 20 &&
|
|
||||||
errorTicksAnim == 0 &&
|
|
||||||
blockState.hasProperty(WorkerState.WORKER_STATE) &&
|
|
||||||
blockState.getValue(WorkerState.WORKER_STATE) != WorkerState.WORKING)
|
|
||||||
{
|
|
||||||
level?.setBlock(blockPos, blockState.setValue(WorkerState.WORKER_STATE, WorkerState.WORKING), Block.UPDATE_CLIENTS)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine which item can be processed from input slots if idling
|
|
||||||
* @return any item in input slots. null if no work is available
|
|
||||||
*/
|
|
||||||
protected abstract fun computeNextJob(): WorkerJob?
|
|
||||||
|
|
||||||
fun basicTicker() {
|
|
||||||
batteryChargeLoop()
|
|
||||||
workerLoop()
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,85 +0,0 @@
|
|||||||
package ru.dbotthepony.mc.otm.block.entity.worker
|
|
||||||
|
|
||||||
import net.minecraft.nbt.CompoundTag
|
|
||||||
import net.minecraft.nbt.DoubleTag
|
|
||||||
import net.minecraft.nbt.Tag
|
|
||||||
import net.minecraft.util.StringRepresentable
|
|
||||||
import net.minecraft.world.item.ItemStack
|
|
||||||
import net.minecraft.world.level.block.state.properties.EnumProperty
|
|
||||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
|
||||||
import ru.dbotthepony.mc.otm.set
|
|
||||||
|
|
||||||
@JvmRecord
|
|
||||||
data class WorkerTickContext(
|
|
||||||
val job: WorkerJob,
|
|
||||||
val requiredPower: ImpreciseFraction,
|
|
||||||
val extractedPower: ImpreciseFraction,
|
|
||||||
val ticksAdvanced: Double
|
|
||||||
)
|
|
||||||
|
|
||||||
enum class WorkerState : StringRepresentable {
|
|
||||||
IDLE,
|
|
||||||
WORKING,
|
|
||||||
ERROR;
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
@JvmField
|
|
||||||
val WORKER_STATE: EnumProperty<WorkerState> = EnumProperty.create("worker", WorkerState::class.java)
|
|
||||||
@JvmField
|
|
||||||
val SEMI_WORKER_STATE: EnumProperty<WorkerState> = EnumProperty.create("worker", WorkerState::class.java, IDLE, WORKING)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getSerializedName(): String {
|
|
||||||
return if (this == IDLE) "idle" else if (this == WORKING) "working" else "error"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmRecord
|
|
||||||
data class WorkerJobStatus @JvmOverloads constructor(val valid: Boolean = true, val throttle: Int = 0) {
|
|
||||||
constructor(throttle: Int) : this(false, throttle)
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmRecord
|
|
||||||
data class WorkerJob @JvmOverloads constructor(
|
|
||||||
val stack: ItemStack,
|
|
||||||
val ticks: Double,
|
|
||||||
val power: ImpreciseFraction = ImpreciseFraction.ZERO,
|
|
||||||
val data: CompoundTag = CompoundTag()) {
|
|
||||||
|
|
||||||
fun serializeNBT(): CompoundTag {
|
|
||||||
return CompoundTag().also {
|
|
||||||
it["stack"] = stack.serializeNBT()
|
|
||||||
it["ticks"] = ticks
|
|
||||||
it["power"] = power.serializeNBT()
|
|
||||||
it["data"] = data
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
operator fun get(index: String) = data[index]
|
|
||||||
operator fun set(index: String, value: Tag) { data[index] = value }
|
|
||||||
operator fun set(index: String, value: Int) { data[index] = value }
|
|
||||||
operator fun set(index: String, value: Byte) { data[index] = value }
|
|
||||||
operator fun set(index: String, value: Short) { data[index] = value }
|
|
||||||
operator fun set(index: String, value: Long) { data[index] = value }
|
|
||||||
operator fun set(index: String, value: Float) { data[index] = value }
|
|
||||||
operator fun set(index: String, value: Double) { data[index] = value }
|
|
||||||
operator fun set(index: String, value: String) { data[index] = value }
|
|
||||||
operator fun set(index: String, value: Boolean) { data[index] = value }
|
|
||||||
operator fun set(index: String, value: ByteArray) { data[index] = value }
|
|
||||||
operator fun set(index: String, value: IntArray) { data[index] = value }
|
|
||||||
operator fun set(index: String, value: LongArray) { data[index] = value }
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
@JvmStatic
|
|
||||||
fun deserializeNBT(tag: Tag?): WorkerJob? {
|
|
||||||
val nbt = tag as? CompoundTag ?: return null
|
|
||||||
|
|
||||||
return WorkerJob(
|
|
||||||
ItemStack.of(nbt["stack"] as? CompoundTag ?: return null),
|
|
||||||
(nbt["ticks"] as? DoubleTag ?: return null).asDouble,
|
|
||||||
ImpreciseFraction.deserializeNBT(nbt["power"]),
|
|
||||||
nbt["data"] as? CompoundTag ?: return null
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -19,7 +19,7 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty
|
|||||||
import net.minecraft.world.phys.shapes.CollisionContext
|
import net.minecraft.world.phys.shapes.CollisionContext
|
||||||
import net.minecraft.world.phys.shapes.VoxelShape
|
import net.minecraft.world.phys.shapes.VoxelShape
|
||||||
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
|
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState
|
import ru.dbotthepony.mc.otm.block.entity.WorkerState
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import ru.dbotthepony.mc.otm.shapes.BlockShapes
|
import ru.dbotthepony.mc.otm.shapes.BlockShapes
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ import net.minecraft.world.level.block.Block
|
|||||||
import net.minecraft.world.phys.shapes.CollisionContext
|
import net.minecraft.world.phys.shapes.CollisionContext
|
||||||
import net.minecraft.world.phys.shapes.VoxelShape
|
import net.minecraft.world.phys.shapes.VoxelShape
|
||||||
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
|
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState
|
import ru.dbotthepony.mc.otm.block.entity.WorkerState
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import ru.dbotthepony.mc.otm.shapes.BlockShapes
|
import ru.dbotthepony.mc.otm.shapes.BlockShapes
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ import net.minecraft.world.phys.shapes.CollisionContext
|
|||||||
import net.minecraft.world.phys.shapes.VoxelShape
|
import net.minecraft.world.phys.shapes.VoxelShape
|
||||||
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
|
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
|
||||||
import ru.dbotthepony.mc.otm.block.entity.matter.MatterRecyclerBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.matter.MatterRecyclerBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState
|
import ru.dbotthepony.mc.otm.block.entity.WorkerState
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import ru.dbotthepony.mc.otm.shapes.BlockShapes
|
import ru.dbotthepony.mc.otm.shapes.BlockShapes
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ import net.minecraft.world.phys.shapes.CollisionContext
|
|||||||
import net.minecraft.world.phys.shapes.VoxelShape
|
import net.minecraft.world.phys.shapes.VoxelShape
|
||||||
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
|
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
|
||||||
import ru.dbotthepony.mc.otm.block.entity.matter.MatterReplicatorBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.matter.MatterReplicatorBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState
|
import ru.dbotthepony.mc.otm.block.entity.WorkerState
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import ru.dbotthepony.mc.otm.shapes.BlockShapes
|
import ru.dbotthepony.mc.otm.shapes.BlockShapes
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ import net.minecraft.world.phys.shapes.CollisionContext
|
|||||||
import net.minecraft.world.phys.shapes.VoxelShape
|
import net.minecraft.world.phys.shapes.VoxelShape
|
||||||
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
|
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
|
||||||
import ru.dbotthepony.mc.otm.block.entity.matter.MatterScannerBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.matter.MatterScannerBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState
|
import ru.dbotthepony.mc.otm.block.entity.WorkerState
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import ru.dbotthepony.mc.otm.shapes.BlockShapes
|
import ru.dbotthepony.mc.otm.shapes.BlockShapes
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ import net.minecraft.world.phys.shapes.CollisionContext
|
|||||||
import net.minecraft.world.phys.shapes.VoxelShape
|
import net.minecraft.world.phys.shapes.VoxelShape
|
||||||
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
|
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
|
||||||
import ru.dbotthepony.mc.otm.block.entity.storage.DriveViewerBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.storage.DriveViewerBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState
|
import ru.dbotthepony.mc.otm.block.entity.WorkerState
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import ru.dbotthepony.mc.otm.shapes.BlockShapes
|
import ru.dbotthepony.mc.otm.shapes.BlockShapes
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ import ru.dbotthepony.mc.otm.block.StorageCableBlock
|
|||||||
import ru.dbotthepony.mc.otm.block.entity.storage.StorageBusBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.storage.StorageBusBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import ru.dbotthepony.mc.otm.shapes.BlockShapes
|
import ru.dbotthepony.mc.otm.shapes.BlockShapes
|
||||||
import ru.dbotthepony.mc.otm.unaryMinus
|
import ru.dbotthepony.mc.otm.core.unaryMinus
|
||||||
|
|
||||||
class StorageBusBlock : RotatableMatteryBlock(), EntityBlock {
|
class StorageBusBlock : RotatableMatteryBlock(), EntityBlock {
|
||||||
override val hasFreeRotation: Boolean get() = true
|
override val hasFreeRotation: Boolean get() = true
|
||||||
|
@ -23,7 +23,7 @@ import ru.dbotthepony.mc.otm.block.entity.storage.StorageExporterBlockEntity
|
|||||||
import ru.dbotthepony.mc.otm.block.entity.storage.StorageImporterBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.storage.StorageImporterBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||||
import ru.dbotthepony.mc.otm.shapes.BlockShapes
|
import ru.dbotthepony.mc.otm.shapes.BlockShapes
|
||||||
import ru.dbotthepony.mc.otm.unaryMinus
|
import ru.dbotthepony.mc.otm.core.unaryMinus
|
||||||
|
|
||||||
class StorageImporterBlock : RotatableMatteryBlock(), EntityBlock {
|
class StorageImporterBlock : RotatableMatteryBlock(), EntityBlock {
|
||||||
override val hasFreeRotation: Boolean get() = true
|
override val hasFreeRotation: Boolean get() = true
|
||||||
|
@ -12,12 +12,12 @@ import net.minecraftforge.common.capabilities.ForgeCapabilities
|
|||||||
import net.minecraftforge.common.capabilities.ICapabilityProvider
|
import net.minecraftforge.common.capabilities.ICapabilityProvider
|
||||||
import net.minecraftforge.common.util.INBTSerializable
|
import net.minecraftforge.common.util.INBTSerializable
|
||||||
import net.minecraftforge.common.util.LazyOptional
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
import net.minecraftforge.energy.CapabilityEnergy
|
|
||||||
import ru.dbotthepony.mc.otm.compat.mekanism.MatteryToMekanismEnergyWrapper
|
import ru.dbotthepony.mc.otm.compat.mekanism.MatteryToMekanismEnergyWrapper
|
||||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||||
import ru.dbotthepony.mc.otm.ifHas
|
import ru.dbotthepony.mc.otm.core.ifHas
|
||||||
import ru.dbotthepony.mc.otm.set
|
import ru.dbotthepony.mc.otm.container.set
|
||||||
import ru.dbotthepony.mc.otm.tagNotNull
|
import ru.dbotthepony.mc.otm.core.set
|
||||||
|
import ru.dbotthepony.mc.otm.core.tagNotNull
|
||||||
|
|
||||||
private enum class EnergyFlow {
|
private enum class EnergyFlow {
|
||||||
INPUT, OUTPUT, BI_DIRECTIONAL
|
INPUT, OUTPUT, BI_DIRECTIONAL
|
||||||
@ -47,9 +47,9 @@ sealed class ItemEnergyStorageImpl(
|
|||||||
protected set
|
protected set
|
||||||
|
|
||||||
override var batteryLevel: ImpreciseFraction
|
override var batteryLevel: ImpreciseFraction
|
||||||
get() = itemStack.tag?.get("energy")?.let { ImpreciseFraction.deserializeNBT(it) } ?: ImpreciseFraction.ZERO
|
get() = itemStack.tag?.get(NBT_KEY)?.let { ImpreciseFraction.deserializeNBT(it) } ?: ImpreciseFraction.ZERO
|
||||||
protected set(value) {
|
protected set(value) {
|
||||||
itemStack.tagNotNull.put("energy", value.serializeNBT())
|
itemStack.tagNotNull.put(NBT_KEY, value.serializeNBT())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun extractEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
|
override fun extractEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
|
||||||
@ -127,6 +127,10 @@ sealed class ItemEnergyStorageImpl(
|
|||||||
override fun canReceive(): Boolean {
|
override fun canReceive(): Boolean {
|
||||||
return type != EnergyFlow.OUTPUT
|
return type != EnergyFlow.OUTPUT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val NBT_KEY = "energy"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open class EnergyConsumerItem(stack: ItemStack, maxBatteryLevel: ImpreciseFraction, maxInput: ImpreciseFraction? = null, maxOutput: ImpreciseFraction? = maxInput)
|
open class EnergyConsumerItem(stack: ItemStack, maxBatteryLevel: ImpreciseFraction, maxInput: ImpreciseFraction? = null, maxOutput: ImpreciseFraction? = maxInput)
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
package ru.dbotthepony.mc.otm.capability
|
package ru.dbotthepony.mc.otm.capability
|
||||||
|
|
||||||
import net.minecraft.core.Direction
|
import net.minecraft.core.Direction
|
||||||
import net.minecraft.world.entity.LivingEntity
|
import net.minecraft.world.entity.player.Player
|
||||||
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
||||||
import net.minecraftforge.common.capabilities.ICapabilityProvider
|
import net.minecraftforge.common.capabilities.ICapabilityProvider
|
||||||
import net.minecraftforge.common.util.LazyOptional
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
@ -9,8 +10,10 @@ import net.minecraftforge.energy.IEnergyStorage
|
|||||||
import net.minecraftforge.fml.ModList
|
import net.minecraftforge.fml.ModList
|
||||||
import ru.dbotthepony.mc.otm.compat.mekanism.getMekanismEnergySided
|
import ru.dbotthepony.mc.otm.compat.mekanism.getMekanismEnergySided
|
||||||
import ru.dbotthepony.mc.otm.compat.mekanism.mekanismEnergy
|
import ru.dbotthepony.mc.otm.compat.mekanism.mekanismEnergy
|
||||||
|
import ru.dbotthepony.mc.otm.container.iterator
|
||||||
|
import ru.dbotthepony.mc.otm.core.iterator
|
||||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||||
import ru.dbotthepony.mc.otm.orNull
|
import ru.dbotthepony.mc.otm.core.orNull
|
||||||
|
|
||||||
val ICapabilityProvider.matteryPlayer: MatteryPlayerCapability? get() = getCapability(MatteryCapability.MATTERY_PLAYER).orNull()
|
val ICapabilityProvider.matteryPlayer: MatteryPlayerCapability? get() = getCapability(MatteryCapability.MATTERY_PLAYER).orNull()
|
||||||
|
|
||||||
@ -117,3 +120,58 @@ fun ICapabilityProvider.getMatteryEnergySided(side: Direction? = null): LazyOpti
|
|||||||
|
|
||||||
return getCapability(MatteryCapability.ENERGY, side)
|
return getCapability(MatteryCapability.ENERGY, side)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Player.extendedItemIterator(): MutableIterator<ItemStack> {
|
||||||
|
return object : MutableIterator<ItemStack> {
|
||||||
|
private val regular = this@extendedItemIterator.inventory.iterator()
|
||||||
|
private val mattery: MutableIterator<ItemStack>
|
||||||
|
private var isSecond = false
|
||||||
|
|
||||||
|
init {
|
||||||
|
val get = this@extendedItemIterator.matteryPlayer
|
||||||
|
|
||||||
|
if (get != null && get.hasExoSuit) {
|
||||||
|
mattery = get.exoSuitContainer.iterator()
|
||||||
|
} else {
|
||||||
|
mattery = object : MutableIterator<ItemStack> {
|
||||||
|
override fun hasNext(): Boolean {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun next(): ItemStack {
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun remove() {
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hasNext(): Boolean {
|
||||||
|
return regular.hasNext() || mattery.hasNext()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun next(): ItemStack {
|
||||||
|
if (isSecond) {
|
||||||
|
return mattery.next()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!regular.hasNext()) {
|
||||||
|
isSecond = true
|
||||||
|
return mattery.next()
|
||||||
|
}
|
||||||
|
|
||||||
|
return regular.next()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun remove() {
|
||||||
|
if (isSecond) {
|
||||||
|
mattery.remove()
|
||||||
|
} else {
|
||||||
|
regular.remove()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -2,7 +2,6 @@ package ru.dbotthepony.mc.otm.capability
|
|||||||
|
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectArraySet
|
import it.unimi.dsi.fastutil.objects.ObjectArraySet
|
||||||
import net.minecraft.ChatFormatting
|
import net.minecraft.ChatFormatting
|
||||||
import net.minecraft.advancements.CriteriaTriggers
|
|
||||||
import net.minecraft.core.Direction
|
import net.minecraft.core.Direction
|
||||||
import net.minecraft.nbt.CompoundTag
|
import net.minecraft.nbt.CompoundTag
|
||||||
import net.minecraft.nbt.ListTag
|
import net.minecraft.nbt.ListTag
|
||||||
@ -39,7 +38,7 @@ import ru.dbotthepony.mc.otm.android.AndroidFeatureType
|
|||||||
import ru.dbotthepony.mc.otm.android.AndroidResearch
|
import ru.dbotthepony.mc.otm.android.AndroidResearch
|
||||||
import ru.dbotthepony.mc.otm.android.AndroidResearchType
|
import ru.dbotthepony.mc.otm.android.AndroidResearchType
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
import ru.dbotthepony.mc.otm.core.*
|
||||||
import ru.dbotthepony.mc.otm.menu.ExoSuitInventoryMenu
|
import ru.dbotthepony.mc.otm.menu.ExoSuitInventoryMenu
|
||||||
import ru.dbotthepony.mc.otm.network.*
|
import ru.dbotthepony.mc.otm.network.*
|
||||||
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
||||||
@ -79,6 +78,10 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, IMatteryEn
|
|||||||
private set(value) {
|
private set(value) {
|
||||||
_exoSuitMenu = null
|
_exoSuitMenu = null
|
||||||
|
|
||||||
|
if (ply.containerMenu.slots.any { it.container == field }) {
|
||||||
|
ply.closeContainer()
|
||||||
|
}
|
||||||
|
|
||||||
for (i in 0 until value.containerSize.coerceAtMost(field.containerSize)) {
|
for (i in 0 until value.containerSize.coerceAtMost(field.containerSize)) {
|
||||||
if (!field[i].isEmpty) {
|
if (!field[i].isEmpty) {
|
||||||
value[i] = field[i]
|
value[i] = field[i]
|
||||||
@ -627,7 +630,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, IMatteryEn
|
|||||||
shouldSendIteration = false
|
shouldSendIteration = false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasExoSuit && ply.containerMenu != exoSuitMenu) {
|
if (hasExoSuit && ply.containerMenu == ply.inventoryMenu) {
|
||||||
exoSuitMenu.broadcastChanges()
|
exoSuitMenu.broadcastChanges()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -762,10 +765,8 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, IMatteryEn
|
|||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
companion object {
|
companion object {
|
||||||
@JvmField
|
|
||||||
val UNAFFECTED_EFFECTS = ObjectArraySet<MobEffect>()
|
val UNAFFECTED_EFFECTS = ObjectArraySet<MobEffect>()
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun registerEffects(event: FMLCommonSetupEvent) {
|
fun registerEffects(event: FMLCommonSetupEvent) {
|
||||||
UNAFFECTED_EFFECTS.add(MobEffects.CONDUIT_POWER)
|
UNAFFECTED_EFFECTS.add(MobEffects.CONDUIT_POWER)
|
||||||
UNAFFECTED_EFFECTS.add(MobEffects.HEAL)
|
UNAFFECTED_EFFECTS.add(MobEffects.HEAL)
|
||||||
@ -782,7 +783,6 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, IMatteryEn
|
|||||||
UNAFFECTED_EFFECTS.add(MobEffects.DOLPHINS_GRACE)
|
UNAFFECTED_EFFECTS.add(MobEffects.DOLPHINS_GRACE)
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
fun onLivingTick(event: LivingTickEvent) {
|
fun onLivingTick(event: LivingTickEvent) {
|
||||||
val ent = event.entity
|
val ent = event.entity
|
||||||
|
|
||||||
@ -797,7 +797,6 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, IMatteryEn
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent(priority = EventPriority.LOWEST)
|
|
||||||
fun onHurtEvent(event: LivingHurtEvent) {
|
fun onHurtEvent(event: LivingHurtEvent) {
|
||||||
if (event.isCanceled) {
|
if (event.isCanceled) {
|
||||||
return
|
return
|
||||||
@ -809,8 +808,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, IMatteryEn
|
|||||||
const val CAPABILITY_KEY = "otm_player"
|
const val CAPABILITY_KEY = "otm_player"
|
||||||
val CAPABILITY_LOCATION = ResourceLocation(OverdriveThatMatters.MOD_ID, CAPABILITY_KEY)
|
val CAPABILITY_LOCATION = ResourceLocation(OverdriveThatMatters.MOD_ID, CAPABILITY_KEY)
|
||||||
|
|
||||||
@SubscribeEvent
|
fun onAttachCapabilityEvent(event: AttachCapabilitiesEvent<Entity>) {
|
||||||
fun onAttachCapabilityEvent(event: AttachCapabilitiesEvent<Entity?>) {
|
|
||||||
val ent = event.`object`
|
val ent = event.`object`
|
||||||
|
|
||||||
if (ent is Player) {
|
if (ent is Player) {
|
||||||
@ -818,18 +816,12 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, IMatteryEn
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
fun onPlayerChangeDimensionEvent(event: PlayerEvent.PlayerChangedDimensionEvent) {
|
fun onPlayerChangeDimensionEvent(event: PlayerEvent.PlayerChangedDimensionEvent) {
|
||||||
event.entity.getCapability(MatteryCapability.MATTERY_PLAYER)
|
event.entity.getCapability(MatteryCapability.MATTERY_PLAYER)
|
||||||
.ifPresentK { it.invalidateNetworkState() }
|
.ifPresentK { it.invalidateNetworkState() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent(priority = EventPriority.LOWEST)
|
|
||||||
fun onPlayerDeath(event: LivingDeathEvent) {
|
fun onPlayerDeath(event: LivingDeathEvent) {
|
||||||
if (event.isCanceled) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val ply = event.entity as? Player ?: return
|
val ply = event.entity as? Player ?: return
|
||||||
val mattery = ply.matteryPlayer ?: return
|
val mattery = ply.matteryPlayer ?: return
|
||||||
|
|
||||||
@ -856,7 +848,6 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, IMatteryEn
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
fun onPlayerCloneEvent(event: PlayerEvent.Clone) {
|
fun onPlayerCloneEvent(event: PlayerEvent.Clone) {
|
||||||
val it = event.entity.matteryPlayer ?: return
|
val it = event.entity.matteryPlayer ?: return
|
||||||
|
|
||||||
@ -889,7 +880,6 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, IMatteryEn
|
|||||||
|
|
||||||
private val itemPickupTicks = WeakHashMap<Player, WeakHashMap<ItemEntity, MutableInt>>()
|
private val itemPickupTicks = WeakHashMap<Player, WeakHashMap<ItemEntity, MutableInt>>()
|
||||||
|
|
||||||
@SubscribeEvent(priority = EventPriority.LOW)
|
|
||||||
fun onPickupEvent(event: EntityItemPickupEvent) {
|
fun onPickupEvent(event: EntityItemPickupEvent) {
|
||||||
if (event.item.owner != null && event.item.owner != event.entity.uuid && event.item.age < 200 || event.item.item.isEmpty) {
|
if (event.item.owner != null && event.item.owner != event.entity.uuid && event.item.age < 200 || event.item.item.isEmpty) {
|
||||||
return
|
return
|
||||||
|
@ -1,21 +1,14 @@
|
|||||||
package ru.dbotthepony.mc.otm.capability.drive
|
package ru.dbotthepony.mc.otm.capability.drive
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectAVLTreeMap
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectAVLTreeMap
|
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectArraySet
|
import it.unimi.dsi.fastutil.objects.ObjectArraySet
|
||||||
import kotlin.jvm.JvmOverloads
|
import kotlin.jvm.JvmOverloads
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import net.minecraft.nbt.CompoundTag
|
import net.minecraft.nbt.CompoundTag
|
||||||
import net.minecraft.nbt.ListTag
|
import net.minecraft.nbt.ListTag
|
||||||
import net.minecraft.nbt.LongTag
|
|
||||||
import net.minecraft.nbt.Tag
|
import net.minecraft.nbt.Tag
|
||||||
import org.apache.logging.log4j.LogManager
|
import org.apache.logging.log4j.LogManager
|
||||||
import ru.dbotthepony.mc.otm.core.BigInteger
|
import ru.dbotthepony.mc.otm.container.set
|
||||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
import ru.dbotthepony.mc.otm.core.*
|
||||||
import ru.dbotthepony.mc.otm.core.isPositive
|
|
||||||
import ru.dbotthepony.mc.otm.core.serializeNBT
|
|
||||||
import ru.dbotthepony.mc.otm.ifHas
|
|
||||||
import ru.dbotthepony.mc.otm.set
|
|
||||||
import ru.dbotthepony.mc.otm.storage.*
|
import ru.dbotthepony.mc.otm.storage.*
|
||||||
import java.math.BigInteger
|
import java.math.BigInteger
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
|
@ -36,7 +36,6 @@ import java.util.ArrayList
|
|||||||
* 5. Mods which check items for being stack-able even with stack size of 1 gonna compare nbt tag,
|
* 5. Mods which check items for being stack-able even with stack size of 1 gonna compare nbt tag,
|
||||||
* which will be performance tanking due to clause 1.
|
* which will be performance tanking due to clause 1.
|
||||||
*/
|
*/
|
||||||
@Suppress("unused")
|
|
||||||
object DrivePool {
|
object DrivePool {
|
||||||
private val LOGGER = LogManager.getLogger()
|
private val LOGGER = LogManager.getLogger()
|
||||||
private val pool = Object2ObjectAVLTreeMap<UUID, WeakDriveReference>()
|
private val pool = Object2ObjectAVLTreeMap<UUID, WeakDriveReference>()
|
||||||
@ -130,7 +129,6 @@ object DrivePool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent(priority = EventPriority.LOWEST)
|
|
||||||
fun onServerPostTick(event: ServerTickEvent) {
|
fun onServerPostTick(event: ServerTickEvent) {
|
||||||
if (event.phase == TickEvent.Phase.END) {
|
if (event.phase == TickEvent.Phase.END) {
|
||||||
if (exception != null) {
|
if (exception != null) {
|
||||||
@ -152,7 +150,6 @@ object DrivePool {
|
|||||||
return Thread.currentThread() === serverThread
|
return Thread.currentThread() === serverThread
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent(priority = EventPriority.HIGHEST)
|
|
||||||
fun serverStartEvent(event: ServerAboutToStartEvent) {
|
fun serverStartEvent(event: ServerAboutToStartEvent) {
|
||||||
if (thread?.isAlive == true) {
|
if (thread?.isAlive == true) {
|
||||||
LOGGER.error("FMLServerStartedEvent fired twice.")
|
LOGGER.error("FMLServerStartedEvent fired twice.")
|
||||||
@ -172,7 +169,6 @@ object DrivePool {
|
|||||||
thread = Thread(null, this::thread, "Overdrive That Matters DrivePool IO").also { it.start() }
|
thread = Thread(null, this::thread, "Overdrive That Matters DrivePool IO").also { it.start() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent(priority = EventPriority.HIGHEST)
|
|
||||||
fun serverStopEvent(event: ServerStoppingEvent) {
|
fun serverStopEvent(event: ServerStoppingEvent) {
|
||||||
val thread = thread
|
val thread = thread
|
||||||
|
|
||||||
@ -189,7 +185,6 @@ object DrivePool {
|
|||||||
pool.clear()
|
pool.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
fun onWorldSave(event: LevelEvent.Save) {
|
fun onWorldSave(event: LevelEvent.Save) {
|
||||||
writeBacklog()
|
writeBacklog()
|
||||||
}
|
}
|
||||||
|
@ -6,12 +6,11 @@ import net.minecraft.world.item.Item
|
|||||||
import net.minecraft.world.item.ItemStack
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraft.world.item.Items
|
import net.minecraft.world.item.Items
|
||||||
import net.minecraftforge.registries.ForgeRegistries
|
import net.minecraftforge.registries.ForgeRegistries
|
||||||
import net.minecraftforge.registries.RegistryManager
|
|
||||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||||
import ru.dbotthepony.mc.otm.core.BigInteger
|
import ru.dbotthepony.mc.otm.core.BigInteger
|
||||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
|
||||||
import ru.dbotthepony.mc.otm.core.serializeNBT
|
import ru.dbotthepony.mc.otm.core.serializeNBT
|
||||||
import ru.dbotthepony.mc.otm.set
|
import ru.dbotthepony.mc.otm.container.set
|
||||||
|
import ru.dbotthepony.mc.otm.core.set
|
||||||
import ru.dbotthepony.mc.otm.storage.IStorageTuple
|
import ru.dbotthepony.mc.otm.storage.IStorageTuple
|
||||||
import ru.dbotthepony.mc.otm.storage.ItemStackWrapper
|
import ru.dbotthepony.mc.otm.storage.ItemStackWrapper
|
||||||
import ru.dbotthepony.mc.otm.storage.StorageStackType
|
import ru.dbotthepony.mc.otm.storage.StorageStackType
|
||||||
|
@ -5,6 +5,7 @@ import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.function.Predicate
|
import java.util.function.Predicate
|
||||||
import java.util.stream.Collectors
|
import java.util.stream.Collectors
|
||||||
|
import java.util.stream.Stream
|
||||||
|
|
||||||
interface IMatterHandler {
|
interface IMatterHandler {
|
||||||
val storedMatter: ImpreciseFraction
|
val storedMatter: ImpreciseFraction
|
||||||
@ -14,6 +15,7 @@ interface IMatterHandler {
|
|||||||
fun receiveMatterInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction
|
fun receiveMatterInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction
|
||||||
fun extractMatterOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction
|
fun extractMatterOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction
|
||||||
fun extractMatterInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction
|
fun extractMatterInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction
|
||||||
|
|
||||||
val direction: MatterDirection
|
val direction: MatterDirection
|
||||||
val missingMatter: ImpreciseFraction
|
val missingMatter: ImpreciseFraction
|
||||||
get() = maxStoredMatter.minus(storedMatter).moreThanZero()
|
get() = maxStoredMatter.minus(storedMatter).moreThanZero()
|
||||||
@ -27,42 +29,44 @@ interface IMatterHandler {
|
|||||||
|
|
||||||
enum class MatterDirection { RECEIVE, EXTRACT, BIDIRECTIONAL }
|
enum class MatterDirection { RECEIVE, EXTRACT, BIDIRECTIONAL }
|
||||||
|
|
||||||
interface IMatterTaskProvider {
|
interface IReplicationTaskProvider {
|
||||||
/**
|
/**
|
||||||
* @return immutable collection of tasks that can be allocated by a worker
|
* It must return new stream each time
|
||||||
*/
|
*/
|
||||||
val tasks: Collection<MatterTask>
|
val replicationTasks: Stream<out IReplicationTask<*>>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return immutable collection of all stored tasks, even fully allocated by workers
|
* It must return new stream each time
|
||||||
*/
|
*/
|
||||||
val allTasks: Collection<MatterTask>
|
val allReplicationTasks: Stream<out IReplicationTask<*>>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocates (marks as work-in-progress) a task
|
* Allocates (marks as work-in-progress) a task
|
||||||
* by incrementing it's in_progress by 1
|
* by incrementing it's [IReplicationTask.inProgress] by 1
|
||||||
* and shrinking required by 1
|
* and shrinking [IReplicationTask.required] by 1
|
||||||
*
|
*
|
||||||
* If required == 0, it should not be returned by this method
|
* If [IReplicationTask.required] == 0, it should not be returned by this method
|
||||||
* @param simulate whenever to change internal state
|
* @param simulate whenever to change internal state
|
||||||
* @return MatterTaskAllocation(task, pattern) that should be performed, or null if no work is available
|
* @return MatterTaskAllocation(task, pattern) that should be performed, or null if no work is available
|
||||||
*/
|
*/
|
||||||
fun allocateTask(simulate: Boolean): MatterTaskAllocation?
|
fun allocateTask(simulate: Boolean): ReplicationTaskAllocation?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notify about task completion. If this provider indeed contain this task, it should
|
* Notify about task completion. If this provider indeed contain this task, it should
|
||||||
* shrink in_progress by 1
|
* shrink in_progress by 1
|
||||||
* If in_progress == 0 and required == 0, it should discard the task
|
* If in_progress == 0 and required == 0, it should discard the task
|
||||||
* @param task task being completed. this method should ignore tasks that are not owned by it.
|
* @param taskId task being completed. this method should ignore tasks that are not owned by it.
|
||||||
* @return whenever task indeed belong to this provider and internal state was updated
|
* @return whenever task indeed belong to this provider and internal state was updated
|
||||||
*/
|
*/
|
||||||
fun notifyTaskCompletion(task: MatterTask): Boolean
|
fun notifyTaskCompletion(taskId: UUID): Boolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param id uuid of task
|
* @param id uuid of task
|
||||||
* @return MatterTask that this capability holds with this id, or null
|
* @return MatterTask that this capability holds with this id, or null
|
||||||
*/
|
*/
|
||||||
fun getTask(id: UUID): MatterTask?
|
fun getTask(id: UUID): IReplicationTask<*>? {
|
||||||
|
return allReplicationTasks.filter { it.id == id }.findAny().orElse(null)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroys all tasks this capability contains
|
* Destroys all tasks this capability contains
|
||||||
@ -72,50 +76,36 @@ interface IMatterTaskProvider {
|
|||||||
|
|
||||||
interface IPatternStorage {
|
interface IPatternStorage {
|
||||||
/**
|
/**
|
||||||
* @return unmodifiable collection of stored patterns
|
* It must return new stream each time
|
||||||
*/
|
*/
|
||||||
val storedPatterns: Collection<PatternState>
|
val storedPatterns: Stream<out IPatternState>
|
||||||
|
|
||||||
fun findPatterns(item: Item): Collection<PatternState> {
|
fun findPatterns(item: Item): Collection<IPatternState> {
|
||||||
return findPatterns { item2: PatternState -> item == item2.item() }
|
return findPatterns { item == it.item }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun findPatterns(predicate: Predicate<PatternState>?): Collection<PatternState> {
|
fun findPatterns(predicate: Predicate<IPatternState>): Collection<IPatternState> {
|
||||||
return storedPatterns.stream().filter(predicate).collect(Collectors.toList())
|
return storedPatterns.filter(predicate).collect(Collectors.toList())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun findPattern(item: Item): PatternState? {
|
fun findPattern(item: Item): IPatternState? {
|
||||||
return findPattern { item2: PatternState -> item == item2.item() }
|
return storedPatterns.filter { it.item == item }.findAny().orElse(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun findPattern(predicate: Predicate<PatternState>): PatternState? {
|
fun getPattern(id: UUID?): IPatternState? {
|
||||||
for (pattern in storedPatterns) {
|
return storedPatterns.filter { it.id == id }.findAny().orElse(null)
|
||||||
if (predicate.test(pattern)) {
|
|
||||||
return pattern
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getPattern(id: UUID?): PatternState? {
|
fun hasPattern(item: Item): Boolean {
|
||||||
id ?: return null
|
return storedPatterns.filter { it.item == item }.findAny().isPresent
|
||||||
|
|
||||||
for (pattern in storedPatterns) {
|
|
||||||
if (pattern.id == id) {
|
|
||||||
return pattern
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hasPattern(state: PatternState): Boolean {
|
fun hasPattern(state: IPatternState): Boolean {
|
||||||
return getPattern(state.id) != null
|
return hasPattern(state.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hasPattern(id: UUID?): Boolean {
|
fun hasPattern(id: UUID?): Boolean {
|
||||||
return getPattern(id) != null
|
return storedPatterns.filter { it.id == id }.findAny().isPresent
|
||||||
}
|
}
|
||||||
|
|
||||||
val capacity: Int
|
val capacity: Int
|
||||||
@ -126,17 +116,17 @@ interface IPatternStorage {
|
|||||||
* and if it fail, try only_update = false
|
* and if it fail, try only_update = false
|
||||||
*
|
*
|
||||||
* @param pattern pattern to be inserted or update value from
|
* @param pattern pattern to be inserted or update value from
|
||||||
* @param only_update do not insert new pattern if this pattern's UUID is not matched
|
* @param onlyUpdate do not insert new pattern if this pattern's UUID is not matched
|
||||||
* @param simulate whenever to affect state
|
* @param simulate whenever to affect state
|
||||||
* @return record of status of the operation (at status() FAIL, UPDATED, INSERTED) as well as new_state and old_state
|
* @return record of status of the operation (at status() FAIL, UPDATED, INSERTED) as well as new_state and old_state
|
||||||
*/
|
*/
|
||||||
fun insertPattern(pattern: PatternState, only_update: Boolean, simulate: Boolean): PatternInsertStatus
|
fun insertPattern(pattern: IPatternState, onlyUpdate: Boolean, simulate: Boolean): PatternInsertStatus
|
||||||
|
|
||||||
fun insertPattern(pattern: PatternState, simulate: Boolean): PatternInsertStatus {
|
fun insertPattern(pattern: IPatternState, simulate: Boolean): PatternInsertStatus {
|
||||||
return insertPattern(pattern, false, simulate)
|
return insertPattern(pattern, false, simulate)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updatePattern(pattern: PatternState, simulate: Boolean): PatternInsertStatus {
|
fun updatePattern(pattern: IPatternState, simulate: Boolean): PatternInsertStatus {
|
||||||
return insertPattern(pattern, true, simulate)
|
return insertPattern(pattern, true, simulate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,17 +8,17 @@ private enum class PatternInsertResult {
|
|||||||
|
|
||||||
sealed class PatternInsertStatus(
|
sealed class PatternInsertStatus(
|
||||||
private val status: PatternInsertResult,
|
private val status: PatternInsertResult,
|
||||||
val newState: PatternState?,
|
val newState: IPatternState?,
|
||||||
val oldState: PatternState?
|
val oldState: IPatternState?
|
||||||
) {
|
) {
|
||||||
val isFailed get() = status === PatternInsertResult.FAIL
|
val isFailed get() = status == PatternInsertResult.FAIL
|
||||||
val isUpdated get() = status === PatternInsertResult.UPDATED
|
val isUpdated get() = status == PatternInsertResult.UPDATED
|
||||||
val isInserted get() = status === PatternInsertResult.INSERTED
|
val isInserted get() = status == PatternInsertResult.INSERTED
|
||||||
}
|
}
|
||||||
|
|
||||||
object PatternInsertFailure : PatternInsertStatus(PatternInsertResult.FAIL, null, null)
|
object PatternInsertFailure : PatternInsertStatus(PatternInsertResult.FAIL, null, null)
|
||||||
class PatternInsertUpdated(new: PatternState, old: PatternState) : PatternInsertStatus(PatternInsertResult.UPDATED, new, old)
|
class PatternInsertUpdated(new: IPatternState, old: IPatternState) : PatternInsertStatus(PatternInsertResult.UPDATED, new, old)
|
||||||
class PatternInsertInserted(new: PatternState) : PatternInsertStatus(PatternInsertResult.INSERTED, new, null)
|
class PatternInsertInserted(new: IPatternState) : PatternInsertStatus(PatternInsertResult.INSERTED, new, null)
|
||||||
|
|
||||||
@JvmRecord
|
@JvmRecord
|
||||||
data class MatterTaskAllocation(val task: MatterTask, val pattern: PatternState?)
|
data class ReplicationTaskAllocation(val task: IReplicationTask<*>, val pattern: IPatternState?)
|
||||||
|
@ -4,7 +4,8 @@ import net.minecraft.nbt.CompoundTag
|
|||||||
import net.minecraftforge.common.util.INBTSerializable
|
import net.minecraftforge.common.util.INBTSerializable
|
||||||
import net.minecraftforge.common.util.LazyOptional
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||||
import ru.dbotthepony.mc.otm.set
|
import ru.dbotthepony.mc.otm.container.set
|
||||||
|
import ru.dbotthepony.mc.otm.core.set
|
||||||
|
|
||||||
open class MatterHandlerImpl @JvmOverloads constructor(
|
open class MatterHandlerImpl @JvmOverloads constructor(
|
||||||
protected val listener: Runnable?,
|
protected val listener: Runnable?,
|
||||||
|
@ -0,0 +1,146 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.capability.matter
|
||||||
|
|
||||||
|
import net.minecraft.nbt.CompoundTag
|
||||||
|
import net.minecraft.nbt.Tag
|
||||||
|
import net.minecraft.network.FriendlyByteBuf
|
||||||
|
import net.minecraft.resources.ResourceLocation
|
||||||
|
import net.minecraft.world.item.Item
|
||||||
|
import net.minecraft.world.item.ItemStack
|
||||||
|
import net.minecraft.world.item.Items
|
||||||
|
import net.minecraftforge.registries.ForgeRegistries
|
||||||
|
import ru.dbotthepony.mc.otm.core.*
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
sealed interface IPatternState {
|
||||||
|
val id: UUID
|
||||||
|
val item: Item
|
||||||
|
val researchPercent: Double
|
||||||
|
|
||||||
|
fun asMutable(): MutablePatternState
|
||||||
|
fun asImmutable() : PatternState
|
||||||
|
|
||||||
|
fun matchId(other: IPatternState): Boolean {
|
||||||
|
return other.id == id
|
||||||
|
}
|
||||||
|
|
||||||
|
fun copyAsMutable(
|
||||||
|
id: UUID = this.id,
|
||||||
|
item: Item = this.item,
|
||||||
|
researchPercent: Double = this.researchPercent,
|
||||||
|
): MutablePatternState {
|
||||||
|
return MutablePatternState(id, item, researchPercent)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun copyAsImmutable(
|
||||||
|
id: UUID = this.id,
|
||||||
|
item: Item = this.item,
|
||||||
|
researchPercent: Double = this.researchPercent,
|
||||||
|
) : PatternState {
|
||||||
|
return PatternState(id, item, researchPercent)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun stack(count: Int = 1): ItemStack {
|
||||||
|
return ItemStack(item, count)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun serializeNBT(): CompoundTag {
|
||||||
|
return CompoundTag().also {
|
||||||
|
it["id"] = id
|
||||||
|
it["item"] = item.registryName!!.toString()
|
||||||
|
it["researchPercent"] = researchPercent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun write(buff: FriendlyByteBuf) {
|
||||||
|
buff.writeUUID(id)
|
||||||
|
buff.writeItemType(item)
|
||||||
|
buff.writeDouble(researchPercent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun deserializeNBT(nbt: Tag?, mutable: Boolean): IPatternState? {
|
||||||
|
if (nbt !is CompoundTag)
|
||||||
|
return null
|
||||||
|
|
||||||
|
if (!nbt.contains("id", "researchPercent", "item"))
|
||||||
|
return null
|
||||||
|
|
||||||
|
val id = nbt.getUUID("id")
|
||||||
|
val researchPercent = nbt.getDouble("researchPercent")
|
||||||
|
val item = ForgeRegistries.ITEMS.getValue(ResourceLocation(nbt.getString("item"))) ?: return null
|
||||||
|
|
||||||
|
if (item == Items.AIR)
|
||||||
|
return null
|
||||||
|
|
||||||
|
if (mutable) {
|
||||||
|
return MutablePatternState(id, item, researchPercent)
|
||||||
|
} else {
|
||||||
|
return PatternState(id, item, researchPercent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun read(buff: FriendlyByteBuf, mutable: Boolean): IPatternState? {
|
||||||
|
val id = buff.readUUID()
|
||||||
|
val item = buff.readItemType()
|
||||||
|
val researchPercent = buff.readDouble()
|
||||||
|
|
||||||
|
item ?: return null
|
||||||
|
|
||||||
|
if (mutable) {
|
||||||
|
return MutablePatternState(id, item, researchPercent)
|
||||||
|
} else {
|
||||||
|
return PatternState(id, item, researchPercent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class PatternState(
|
||||||
|
override val id: UUID,
|
||||||
|
override val item: Item,
|
||||||
|
override val researchPercent: Double,
|
||||||
|
) : IPatternState {
|
||||||
|
override fun asMutable(): MutablePatternState {
|
||||||
|
return MutablePatternState(id, item, researchPercent)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun asImmutable(): PatternState {
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun deserializeNBT(tag: Tag?): PatternState? {
|
||||||
|
return deserializeNBT(tag, false) as PatternState?
|
||||||
|
}
|
||||||
|
|
||||||
|
fun read(buff: FriendlyByteBuf): PatternState? {
|
||||||
|
return read(buff, false) as PatternState?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class MutablePatternState(
|
||||||
|
override val id: UUID,
|
||||||
|
override val item: Item,
|
||||||
|
override var researchPercent: Double,
|
||||||
|
) : IPatternState {
|
||||||
|
override fun asMutable(): MutablePatternState {
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun asImmutable(): PatternState {
|
||||||
|
return PatternState(id, item, researchPercent)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun deserializeNBT(tag: Tag?): MutablePatternState? {
|
||||||
|
return deserializeNBT(tag, true) as MutablePatternState?
|
||||||
|
}
|
||||||
|
|
||||||
|
fun read(buff: FriendlyByteBuf): MutablePatternState? {
|
||||||
|
return read(buff, true) as MutablePatternState?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun FriendlyByteBuf.writePatternState(state: IPatternState) = state.write(this)
|
||||||
|
fun FriendlyByteBuf.readPatternState() = PatternState.read(this)
|
||||||
|
fun FriendlyByteBuf.readMutablePatternState() = MutablePatternState.read(this)
|
@ -0,0 +1,210 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.capability.matter
|
||||||
|
|
||||||
|
import net.minecraft.nbt.CompoundTag
|
||||||
|
import net.minecraft.nbt.Tag
|
||||||
|
import net.minecraft.network.FriendlyByteBuf
|
||||||
|
import net.minecraft.resources.ResourceLocation
|
||||||
|
import net.minecraft.world.item.Item
|
||||||
|
import net.minecraft.world.item.ItemStack
|
||||||
|
import net.minecraft.world.item.Items
|
||||||
|
import net.minecraftforge.registries.ForgeRegistries
|
||||||
|
import ru.dbotthepony.mc.otm.core.readItemType
|
||||||
|
import ru.dbotthepony.mc.otm.core.registryName
|
||||||
|
import ru.dbotthepony.mc.otm.core.set
|
||||||
|
import ru.dbotthepony.mc.otm.core.writeItemType
|
||||||
|
import java.util.UUID
|
||||||
|
|
||||||
|
sealed interface IReplicationTask<S : IReplicationTask<S>> {
|
||||||
|
val id: UUID
|
||||||
|
val patternId: UUID?
|
||||||
|
val item: Item
|
||||||
|
val inProgress: Int
|
||||||
|
val finished: Int
|
||||||
|
val required: Int
|
||||||
|
|
||||||
|
fun asMutable(): MutableReplicationTask
|
||||||
|
fun asImmutable(): ReplicationTask
|
||||||
|
|
||||||
|
val total get() = inProgress + finished + required
|
||||||
|
|
||||||
|
fun copyAsMutable(
|
||||||
|
id: UUID = this.id,
|
||||||
|
patternId: UUID? = this.patternId,
|
||||||
|
item: Item = this.item,
|
||||||
|
inProgress: Int = this.inProgress,
|
||||||
|
finished: Int = this.finished,
|
||||||
|
required: Int = this.required,
|
||||||
|
): MutableReplicationTask {
|
||||||
|
return MutableReplicationTask(id, patternId, item, inProgress, finished, required)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun copyAsImmutable(
|
||||||
|
id: UUID = this.id,
|
||||||
|
patternId: UUID? = this.patternId,
|
||||||
|
item: Item = this.item,
|
||||||
|
inProgress: Int = this.inProgress,
|
||||||
|
finished: Int = this.finished,
|
||||||
|
required: Int = this.required,
|
||||||
|
): ReplicationTask {
|
||||||
|
return ReplicationTask(id, patternId, item, inProgress, finished, required)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun matchId(other: IReplicationTask<*>): Boolean {
|
||||||
|
return other.id == id
|
||||||
|
}
|
||||||
|
|
||||||
|
fun stack(count: Int = 1): ItemStack {
|
||||||
|
return ItemStack(item, count)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun allocate(amount: Int = 1): S
|
||||||
|
fun finish(amount: Int = 1): S
|
||||||
|
|
||||||
|
fun serializeNBT(): CompoundTag {
|
||||||
|
return CompoundTag().also {
|
||||||
|
it["id"] = id
|
||||||
|
|
||||||
|
if (patternId != null)
|
||||||
|
it["patternId"] = patternId!!
|
||||||
|
|
||||||
|
it["item"] = item.registryName!!.toString()
|
||||||
|
it["inProgress"] = inProgress
|
||||||
|
it["finished"] = finished
|
||||||
|
it["required"] = required
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun write(buff: FriendlyByteBuf) {
|
||||||
|
buff.writeUUID(id)
|
||||||
|
|
||||||
|
buff.writeBoolean(patternId != null)
|
||||||
|
patternId?.let(buff::writeUUID)
|
||||||
|
|
||||||
|
buff.writeItemType(item)
|
||||||
|
|
||||||
|
buff.writeInt(inProgress)
|
||||||
|
buff.writeInt(finished)
|
||||||
|
buff.writeInt(required)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun deserializeNBT(nbt: Tag?, mutable: Boolean): IReplicationTask<*>? {
|
||||||
|
if (nbt !is CompoundTag)
|
||||||
|
return null
|
||||||
|
|
||||||
|
if (!nbt.contains("id") || !nbt.contains("inProgress") || !nbt.contains("finished") || !nbt.contains("required") || !nbt.contains("item"))
|
||||||
|
return null
|
||||||
|
|
||||||
|
val item = ForgeRegistries.ITEMS.getValue(ResourceLocation(nbt.getString("item"))) ?: return null
|
||||||
|
|
||||||
|
if (item == Items.AIR)
|
||||||
|
return null
|
||||||
|
|
||||||
|
val id = nbt.getUUID("id")
|
||||||
|
val patternId = if (nbt.contains("patternId")) nbt.getUUID("patternId") else null
|
||||||
|
|
||||||
|
val inProgress = nbt.getInt("inProgress")
|
||||||
|
val finished = nbt.getInt("finished")
|
||||||
|
val required = nbt.getInt("required")
|
||||||
|
|
||||||
|
if (mutable) {
|
||||||
|
return MutableReplicationTask(id, patternId, item, inProgress, finished, required)
|
||||||
|
} else {
|
||||||
|
return ReplicationTask(id, patternId, item, inProgress, finished, required)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun read(buff: FriendlyByteBuf, mutable: Boolean): IReplicationTask<*>? {
|
||||||
|
val id = buff.readUUID()
|
||||||
|
val patternId: UUID? = if (buff.readBoolean()) buff.readUUID() else null
|
||||||
|
val item = buff.readItemType()
|
||||||
|
val inProgress = buff.readInt()
|
||||||
|
val finished = buff.readInt()
|
||||||
|
val required = buff.readInt()
|
||||||
|
|
||||||
|
item ?: return null
|
||||||
|
|
||||||
|
if (mutable) {
|
||||||
|
return MutableReplicationTask(id, patternId, item, inProgress, finished, required)
|
||||||
|
} else {
|
||||||
|
return ReplicationTask(id, patternId, item, inProgress, finished, required)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class ReplicationTask(
|
||||||
|
override val id: UUID,
|
||||||
|
override val patternId: UUID?,
|
||||||
|
override val item: Item,
|
||||||
|
override val inProgress: Int,
|
||||||
|
override val finished: Int,
|
||||||
|
override val required: Int
|
||||||
|
) : IReplicationTask<ReplicationTask> {
|
||||||
|
override fun asMutable(): MutableReplicationTask {
|
||||||
|
return MutableReplicationTask(id, patternId, item, inProgress, finished, required)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun asImmutable(): ReplicationTask {
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun allocate(amount: Int): ReplicationTask {
|
||||||
|
return ReplicationTask(id, patternId, item, inProgress + amount, finished, required - amount)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun finish(amount: Int): ReplicationTask {
|
||||||
|
return ReplicationTask(id, patternId, item, inProgress - amount, finished + amount, required)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun deserializeNBT(nbt: Tag?): ReplicationTask? {
|
||||||
|
return deserializeNBT(nbt, false) as ReplicationTask?
|
||||||
|
}
|
||||||
|
|
||||||
|
fun read(buff: FriendlyByteBuf): ReplicationTask? {
|
||||||
|
return read(buff, false) as ReplicationTask?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class MutableReplicationTask(
|
||||||
|
override val id: UUID,
|
||||||
|
override val patternId: UUID?,
|
||||||
|
override val item: Item,
|
||||||
|
override var inProgress: Int,
|
||||||
|
override var finished: Int,
|
||||||
|
override var required: Int
|
||||||
|
) : IReplicationTask<MutableReplicationTask> {
|
||||||
|
override fun asMutable(): MutableReplicationTask {
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun asImmutable(): ReplicationTask {
|
||||||
|
return ReplicationTask(id, patternId, item, inProgress, finished, required)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun allocate(amount: Int): MutableReplicationTask {
|
||||||
|
inProgress += amount
|
||||||
|
finished -= amount
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun finish(amount: Int): MutableReplicationTask {
|
||||||
|
finished += amount
|
||||||
|
inProgress -= amount
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun deserializeNBT(nbt: Tag?): MutableReplicationTask? {
|
||||||
|
return deserializeNBT(nbt, true) as MutableReplicationTask?
|
||||||
|
}
|
||||||
|
|
||||||
|
fun read(buff: FriendlyByteBuf): MutableReplicationTask? {
|
||||||
|
return read(buff, true) as MutableReplicationTask?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun FriendlyByteBuf.writeReplicationTask(task: IReplicationTask<*>) = task.write(this)
|
||||||
|
fun FriendlyByteBuf.readReplicationTask() = ReplicationTask.read(this)
|
||||||
|
fun FriendlyByteBuf.readMutableReplicationTask() = MutableReplicationTask.read(this)
|
@ -0,0 +1,53 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.client
|
||||||
|
|
||||||
|
import net.minecraft.client.gui.screens.inventory.InventoryScreen
|
||||||
|
import net.minecraftforge.client.event.MovementInputUpdateEvent
|
||||||
|
import net.minecraftforge.client.event.ScreenEvent
|
||||||
|
import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
||||||
|
import ru.dbotthepony.mc.otm.client.screen.ExoSuitInventoryScreen
|
||||||
|
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
||||||
|
|
||||||
|
object ClientEventHandler {
|
||||||
|
fun inputEvent(event: MovementInputUpdateEvent) {
|
||||||
|
val ply = event.entity
|
||||||
|
val input = event.input
|
||||||
|
|
||||||
|
val cap = ply.matteryPlayer ?: return
|
||||||
|
|
||||||
|
if (cap.hasFeature(AndroidFeatures.AIR_BAGS))
|
||||||
|
return
|
||||||
|
|
||||||
|
if (ply.abilities.mayfly) {
|
||||||
|
cap.lastJumpTicks = 14
|
||||||
|
} else {
|
||||||
|
if (ply.isInWater) {
|
||||||
|
if (ply.isOnGround) {
|
||||||
|
cap.lastJumpTicks = 14
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ply.isSwimming) {
|
||||||
|
ply.isSwimming = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cap.lastJumpTicks <= 0) {
|
||||||
|
input.jumping = false
|
||||||
|
input.up = false
|
||||||
|
} else {
|
||||||
|
cap.lastJumpTicks--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun screenOpen(event: ScreenEvent.Opening) {
|
||||||
|
if (minecraft.player?.isCreative == true) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val player = minecraft.player?.matteryPlayer ?: return
|
||||||
|
|
||||||
|
if (player.hasExoSuit && event.newScreen is InventoryScreen) {
|
||||||
|
event.newScreen = ExoSuitInventoryScreen(player.exoSuitMenu)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,56 +0,0 @@
|
|||||||
package ru.dbotthepony.mc.otm.client
|
|
||||||
|
|
||||||
import net.minecraft.client.gui.screens.inventory.InventoryScreen
|
|
||||||
import net.minecraftforge.client.event.MovementInputUpdateEvent
|
|
||||||
import net.minecraftforge.client.event.ScreenEvent
|
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent
|
|
||||||
import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
|
||||||
import ru.dbotthepony.mc.otm.client.screen.ExoSuitInventoryScreen
|
|
||||||
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
@Suppress("unused")
|
|
||||||
fun inputEvent(event: MovementInputUpdateEvent) {
|
|
||||||
val ply = event.entity
|
|
||||||
val input = event.input
|
|
||||||
|
|
||||||
val cap = ply.matteryPlayer ?: return
|
|
||||||
|
|
||||||
if (cap.hasFeature(AndroidFeatures.AIR_BAGS))
|
|
||||||
return
|
|
||||||
|
|
||||||
if (ply.abilities.mayfly) {
|
|
||||||
cap.lastJumpTicks = 14
|
|
||||||
} else {
|
|
||||||
if (ply.isInWater) {
|
|
||||||
if (ply.isOnGround) {
|
|
||||||
cap.lastJumpTicks = 14
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ply.isSwimming) {
|
|
||||||
ply.isSwimming = false
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cap.lastJumpTicks <= 0) {
|
|
||||||
input.jumping = false
|
|
||||||
input.up = false
|
|
||||||
} else {
|
|
||||||
cap.lastJumpTicks--
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
@Suppress("unused")
|
|
||||||
fun screenOpen(event: ScreenEvent.Opening) {
|
|
||||||
if (minecraft.player?.isCreative == true) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val player = minecraft.player?.matteryPlayer ?: return
|
|
||||||
|
|
||||||
if (player.hasExoSuit && event.newScreen is InventoryScreen) {
|
|
||||||
event.newScreen = ExoSuitInventoryScreen(player.exoSuitMenu)
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,6 +2,12 @@ package ru.dbotthepony.mc.otm.client
|
|||||||
|
|
||||||
import net.minecraft.client.Minecraft
|
import net.minecraft.client.Minecraft
|
||||||
import net.minecraft.client.gui.Font
|
import net.minecraft.client.gui.Font
|
||||||
|
import net.minecraft.client.resources.sounds.SimpleSoundInstance
|
||||||
|
import net.minecraft.sounds.SoundEvents
|
||||||
|
|
||||||
inline val minecraft: Minecraft get() = Minecraft.getInstance()
|
inline val minecraft: Minecraft get() = Minecraft.getInstance()
|
||||||
inline val font: Font get() = minecraft.font
|
inline val font: Font get() = minecraft.font
|
||||||
|
|
||||||
|
fun playGuiClickSound() {
|
||||||
|
minecraft.soundManager.play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0f))
|
||||||
|
}
|
||||||
|
@ -18,14 +18,13 @@ import net.minecraftforge.client.gui.overlay.GuiOverlayManager
|
|||||||
import net.minecraftforge.eventbus.api.EventPriority
|
import net.minecraftforge.eventbus.api.EventPriority
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent
|
import net.minecraftforge.eventbus.api.SubscribeEvent
|
||||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||||
import ru.dbotthepony.mc.otm.TextComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
|
||||||
import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
||||||
import ru.dbotthepony.mc.otm.client.render.*
|
import ru.dbotthepony.mc.otm.client.render.*
|
||||||
import ru.dbotthepony.mc.otm.core.RGBAColor
|
import ru.dbotthepony.mc.otm.core.RGBAColor
|
||||||
import ru.dbotthepony.mc.otm.ifPresentK
|
import ru.dbotthepony.mc.otm.core.ifPresentK
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
object MatteryGUI {
|
object MatteryGUI {
|
||||||
@ -40,8 +39,6 @@ object MatteryGUI {
|
|||||||
|
|
||||||
private val button_shaker = Random()
|
private val button_shaker = Random()
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
@Suppress("unused")
|
|
||||||
fun onScreenRender(event: ScreenEvent.Render.Pre) {
|
fun onScreenRender(event: ScreenEvent.Render.Pre) {
|
||||||
if (knownButtonScreen != null && knownButton == null) {
|
if (knownButtonScreen != null && knownButton == null) {
|
||||||
for (widget in knownButtonScreen!!.renderables) {
|
for (widget in knownButtonScreen!!.renderables) {
|
||||||
@ -88,8 +85,6 @@ object MatteryGUI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent(priority = EventPriority.LOWEST)
|
|
||||||
@Suppress("unused")
|
|
||||||
fun onOpenGUIEvent(event: ScreenEvent.Opening) {
|
fun onOpenGUIEvent(event: ScreenEvent.Opening) {
|
||||||
knownButtonX = -1
|
knownButtonX = -1
|
||||||
knownButtonY = -1
|
knownButtonY = -1
|
||||||
@ -199,14 +194,10 @@ object MatteryGUI {
|
|||||||
popScissorRect()
|
popScissorRect()
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
@Suppress("unused")
|
|
||||||
fun onRenderGuiEvent(event: RenderGuiEvent.Post) {
|
fun onRenderGuiEvent(event: RenderGuiEvent.Post) {
|
||||||
showIteration(event)
|
showIteration(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
|
||||||
@Suppress("unused")
|
|
||||||
fun onLayerRenderEvent(event: RenderGuiOverlayEvent.Pre) {
|
fun onLayerRenderEvent(event: RenderGuiOverlayEvent.Pre) {
|
||||||
if (event.overlay != FOOD_LEVEL_ELEMENT && event.overlay != AIR_LEVEL_ELEMENT) {
|
if (event.overlay != FOOD_LEVEL_ELEMENT && event.overlay != AIR_LEVEL_ELEMENT) {
|
||||||
return
|
return
|
||||||
|
@ -11,7 +11,7 @@ import net.minecraft.client.renderer.blockentity.BlockEntityRenderer
|
|||||||
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider
|
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider
|
||||||
import net.minecraft.world.phys.Vec3
|
import net.minecraft.world.phys.Vec3
|
||||||
import org.lwjgl.opengl.GL30
|
import org.lwjgl.opengl.GL30
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.block.entity.GravitationStabilizerBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.GravitationStabilizerBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.block.entity.blackhole.BlackHoleBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.blackhole.BlackHoleBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
||||||
|
@ -6,7 +6,7 @@ import net.minecraft.client.renderer.MultiBufferSource
|
|||||||
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer
|
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer
|
||||||
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider
|
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider
|
||||||
import net.minecraft.core.Direction
|
import net.minecraft.core.Direction
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.block.EnergyCounterBlock
|
import ru.dbotthepony.mc.otm.block.EnergyCounterBlock
|
||||||
import ru.dbotthepony.mc.otm.block.entity.EnergyCounterBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.EnergyCounterBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.client.render.*
|
import ru.dbotthepony.mc.otm.client.render.*
|
||||||
|
@ -10,12 +10,12 @@ import net.minecraft.client.renderer.blockentity.BlockEntityRenderer
|
|||||||
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider
|
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider
|
||||||
import net.minecraft.client.renderer.texture.OverlayTexture
|
import net.minecraft.client.renderer.texture.OverlayTexture
|
||||||
import net.minecraft.core.Direction
|
import net.minecraft.core.Direction
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.block.BlackHoleBlock
|
import ru.dbotthepony.mc.otm.block.BlackHoleBlock
|
||||||
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
|
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
|
||||||
import ru.dbotthepony.mc.otm.block.entity.GravitationStabilizerBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.GravitationStabilizerBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.block.entity.blackhole.BlackHoleBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.blackhole.BlackHoleBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState
|
import ru.dbotthepony.mc.otm.block.entity.WorkerState
|
||||||
import ru.dbotthepony.mc.otm.client.render.*
|
import ru.dbotthepony.mc.otm.client.render.*
|
||||||
import ru.dbotthepony.mc.otm.core.*
|
import ru.dbotthepony.mc.otm.core.*
|
||||||
import kotlin.math.PI
|
import kotlin.math.PI
|
||||||
|
@ -7,16 +7,14 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap
|
|||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectFunction
|
import it.unimi.dsi.fastutil.ints.Int2ObjectFunction
|
||||||
import net.minecraft.ChatFormatting
|
import net.minecraft.ChatFormatting
|
||||||
import net.minecraft.client.Minecraft
|
import net.minecraft.client.Minecraft
|
||||||
import net.minecraft.client.resources.sounds.SimpleSoundInstance
|
|
||||||
import net.minecraft.network.chat.Component
|
import net.minecraft.network.chat.Component
|
||||||
import net.minecraft.sounds.SoundEvents
|
|
||||||
import net.minecraft.world.entity.player.Inventory
|
import net.minecraft.world.entity.player.Inventory
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.android.AndroidResearch
|
import ru.dbotthepony.mc.otm.android.AndroidResearch
|
||||||
import ru.dbotthepony.mc.otm.android.AndroidResearchType
|
import ru.dbotthepony.mc.otm.android.AndroidResearchType
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.client.minecraft
|
import ru.dbotthepony.mc.otm.client.playGuiClickSound
|
||||||
import ru.dbotthepony.mc.otm.client.render.Widgets18
|
import ru.dbotthepony.mc.otm.client.render.Widgets18
|
||||||
import ru.dbotthepony.mc.otm.client.render.drawColor
|
import ru.dbotthepony.mc.otm.client.render.drawColor
|
||||||
import ru.dbotthepony.mc.otm.client.render.drawLine
|
import ru.dbotthepony.mc.otm.client.render.drawLine
|
||||||
@ -24,7 +22,7 @@ import ru.dbotthepony.mc.otm.client.render.drawRect
|
|||||||
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
||||||
import ru.dbotthepony.mc.otm.client.screen.widget.WidePowerGaugePanel
|
import ru.dbotthepony.mc.otm.client.screen.widget.WidePowerGaugePanel
|
||||||
import ru.dbotthepony.mc.otm.core.RGBAColor
|
import ru.dbotthepony.mc.otm.core.RGBAColor
|
||||||
import ru.dbotthepony.mc.otm.ifPresentK
|
import ru.dbotthepony.mc.otm.core.ifPresentK
|
||||||
import ru.dbotthepony.mc.otm.menu.AndroidStationMenu
|
import ru.dbotthepony.mc.otm.menu.AndroidStationMenu
|
||||||
import ru.dbotthepony.mc.otm.network.MatteryPlayerNetworkChannel
|
import ru.dbotthepony.mc.otm.network.MatteryPlayerNetworkChannel
|
||||||
import ru.dbotthepony.mc.otm.network.AndroidResearchRequestPacket
|
import ru.dbotthepony.mc.otm.network.AndroidResearchRequestPacket
|
||||||
@ -383,7 +381,7 @@ private class AndroidResearchButton(
|
|||||||
MatteryPlayerNetworkChannel.sendToServer(AndroidResearchRequestPacket(node.type))
|
MatteryPlayerNetworkChannel.sendToServer(AndroidResearchRequestPacket(node.type))
|
||||||
}
|
}
|
||||||
|
|
||||||
minecraft.soundManager.play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0f))
|
playGuiClickSound()
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
@ -479,6 +477,7 @@ class AndroidStationScreen constructor(p_97741_: AndroidStationMenu, p_97742_: I
|
|||||||
|
|
||||||
override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean {
|
override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean {
|
||||||
if (isPreview) {
|
if (isPreview) {
|
||||||
|
playGuiClickSound()
|
||||||
openResearchTree()
|
openResearchTree()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,8 @@ package ru.dbotthepony.mc.otm.client.screen
|
|||||||
|
|
||||||
import net.minecraft.network.chat.Component
|
import net.minecraft.network.chat.Component
|
||||||
import net.minecraft.world.entity.player.Inventory
|
import net.minecraft.world.entity.player.Inventory
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
||||||
import ru.dbotthepony.mc.otm.client.screen.widget.PowerGaugePanel
|
|
||||||
import ru.dbotthepony.mc.otm.client.screen.widget.ProgressGaugePanel
|
import ru.dbotthepony.mc.otm.client.screen.widget.ProgressGaugePanel
|
||||||
import ru.dbotthepony.mc.otm.client.screen.widget.WidePowerGaugePanel
|
import ru.dbotthepony.mc.otm.client.screen.widget.WidePowerGaugePanel
|
||||||
import ru.dbotthepony.mc.otm.menu.ChemicalGeneratorMenu
|
import ru.dbotthepony.mc.otm.menu.ChemicalGeneratorMenu
|
||||||
|
@ -4,9 +4,10 @@ import com.mojang.blaze3d.vertex.PoseStack
|
|||||||
import net.minecraft.network.chat.Component
|
import net.minecraft.network.chat.Component
|
||||||
import net.minecraft.world.entity.player.Inventory
|
import net.minecraft.world.entity.player.Inventory
|
||||||
import net.minecraft.world.item.ItemStack
|
import net.minecraft.world.item.ItemStack
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
||||||
import ru.dbotthepony.mc.otm.client.screen.widget.PowerGaugePanel
|
import ru.dbotthepony.mc.otm.client.screen.widget.PowerGaugePanel
|
||||||
|
import ru.dbotthepony.mc.otm.core.maxScrollDivision
|
||||||
import ru.dbotthepony.mc.otm.item.PortableCondensationDriveItem
|
import ru.dbotthepony.mc.otm.item.PortableCondensationDriveItem
|
||||||
import ru.dbotthepony.mc.otm.menu.DriveViewerMenu
|
import ru.dbotthepony.mc.otm.menu.DriveViewerMenu
|
||||||
|
|
||||||
@ -51,15 +52,15 @@ class DriveViewerScreen(menu: DriveViewerMenu, inventory: Inventory, title: Comp
|
|||||||
|
|
||||||
val grid = GridPanel(this, frame, 28f, 16f, GRID_WIDTH * 18f, GRID_HEIGHT * 18f, GRID_WIDTH, GRID_HEIGHT)
|
val grid = GridPanel(this, frame, 28f, 16f, GRID_WIDTH * 18f, GRID_HEIGHT * 18f, GRID_WIDTH, GRID_HEIGHT)
|
||||||
|
|
||||||
val scrollBar = ContinuousScrollBarPanel(this, frame, 192f, 14f, 92f)
|
val scrollBar = DiscreteScrollBarPanel(this, frame, { maxScrollDivision(menu.networkedItemView.itemCount, GRID_WIDTH) }, { _, _, _ -> }, 192f, 14f, 92f)
|
||||||
scrollBar.setupRowMultiplier { menu.networkedItemView.itemCount / GRID_WIDTH }
|
|
||||||
views.add(grid)
|
views.add(grid)
|
||||||
views.add(scrollBar)
|
views.add(scrollBar)
|
||||||
|
|
||||||
for (i in 0 until GRID_WIDTH * GRID_HEIGHT) {
|
for (i in 0 until GRID_WIDTH * GRID_HEIGHT) {
|
||||||
object : AbstractSlotPanel(this@DriveViewerScreen, grid, 0f, 0f) {
|
object : AbstractSlotPanel(this@DriveViewerScreen, grid, 0f, 0f) {
|
||||||
override fun getItemStack(): ItemStack {
|
override fun getItemStack(): ItemStack {
|
||||||
val index = i + scrollBar.getScroll(menu.networkedItemView.sortedView.size / GRID_WIDTH)
|
val index = i + scrollBar.scroll * GRID_WIDTH
|
||||||
return menu.networkedItemView.sortedView.getOrNull(index)?.stack?.item ?: ItemStack.EMPTY
|
return menu.networkedItemView.sortedView.getOrNull(index)?.stack?.item ?: ItemStack.EMPTY
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +69,7 @@ class DriveViewerScreen(menu: DriveViewerMenu, inventory: Inventory, title: Comp
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean {
|
override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean {
|
||||||
val index = i + scrollBar.getScroll(GRID_WIDTH)
|
val index = i + scrollBar.scroll * GRID_WIDTH
|
||||||
menu.networkedItemView.mouseClick(index, button)
|
menu.networkedItemView.mouseClick(index, button)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -81,7 +82,7 @@ class DriveViewerScreen(menu: DriveViewerMenu, inventory: Inventory, title: Comp
|
|||||||
override fun getItemStackTooltip(stack: ItemStack): List<Component> {
|
override fun getItemStackTooltip(stack: ItemStack): List<Component> {
|
||||||
return super.getItemStackTooltip(stack).also {
|
return super.getItemStackTooltip(stack).also {
|
||||||
it as MutableList<Component>
|
it as MutableList<Component>
|
||||||
val index = i + scrollBar.getScroll(menu.networkedItemView.sortedView.size / GRID_WIDTH)
|
val index = i + scrollBar.scroll * GRID_WIDTH
|
||||||
val realStack = menu.networkedItemView.sortedView.getOrNull(index)!!.stack
|
val realStack = menu.networkedItemView.sortedView.getOrNull(index)!!.stack
|
||||||
it.add(TranslatableComponent("otm.gui.item_amount", realStack.count.toString()))
|
it.add(TranslatableComponent("otm.gui.item_amount", realStack.count.toString()))
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ package ru.dbotthepony.mc.otm.client.screen
|
|||||||
|
|
||||||
import net.minecraft.network.chat.Component
|
import net.minecraft.network.chat.Component
|
||||||
import net.minecraft.world.entity.player.Inventory
|
import net.minecraft.world.entity.player.Inventory
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
||||||
import ru.dbotthepony.mc.otm.core.formatPower
|
import ru.dbotthepony.mc.otm.core.formatPower
|
||||||
import ru.dbotthepony.mc.otm.menu.EnergyCounterMenu
|
import ru.dbotthepony.mc.otm.menu.EnergyCounterMenu
|
||||||
|
@ -3,9 +3,8 @@ package ru.dbotthepony.mc.otm.client.screen
|
|||||||
import com.mojang.blaze3d.vertex.PoseStack
|
import com.mojang.blaze3d.vertex.PoseStack
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap
|
import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectFunction
|
import it.unimi.dsi.fastutil.ints.Int2ObjectFunction
|
||||||
import net.minecraft.client.gui.screens.inventory.InventoryScreen
|
|
||||||
import net.minecraft.world.inventory.Slot
|
import net.minecraft.world.inventory.Slot
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.client.render.element
|
import ru.dbotthepony.mc.otm.client.render.element
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
||||||
import ru.dbotthepony.mc.otm.menu.ExoSuitInventoryMenu
|
import ru.dbotthepony.mc.otm.menu.ExoSuitInventoryMenu
|
||||||
@ -13,36 +12,6 @@ import ru.dbotthepony.mc.otm.network.ExoSuitMenuOpen
|
|||||||
import ru.dbotthepony.mc.otm.network.MatteryPlayerNetworkChannel
|
import ru.dbotthepony.mc.otm.network.MatteryPlayerNetworkChannel
|
||||||
|
|
||||||
class ExoSuitInventoryScreen(menu: ExoSuitInventoryMenu) : MatteryScreen<ExoSuitInventoryMenu>(menu, TranslatableComponent("otm.gui.exosuit")) {
|
class ExoSuitInventoryScreen(menu: ExoSuitInventoryMenu) : MatteryScreen<ExoSuitInventoryMenu>(menu, TranslatableComponent("otm.gui.exosuit")) {
|
||||||
private val slotRows = Int2ObjectAVLTreeMap<EditablePanel>()
|
|
||||||
|
|
||||||
private fun getSlotsRow(index: Int): EditablePanel {
|
|
||||||
return slotRows.computeIfAbsent(index, Int2ObjectFunction {
|
|
||||||
val canvas = object : EditablePanel(this@ExoSuitInventoryScreen, null, width = AbstractSlotPanel.SIZE * 9f, height = AbstractSlotPanel.SIZE) {
|
|
||||||
override fun mouseScrolledInner(x: Double, y: Double, scroll: Double): Boolean {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val offset = it * 9
|
|
||||||
|
|
||||||
if (menu.combinedInventorySlots.size <= offset) {
|
|
||||||
return@Int2ObjectFunction canvas
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i in 0 .. (8).coerceAtMost(menu.combinedInventorySlots.size - offset - 1)) {
|
|
||||||
val slot = object : SlotPanel<Slot>(this@ExoSuitInventoryScreen, canvas, menu.combinedInventorySlots[offset + i]) {
|
|
||||||
override fun mouseScrolledInner(x: Double, y: Double, scroll: Double): Boolean {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
slot.dock = Dock.LEFT
|
|
||||||
}
|
|
||||||
|
|
||||||
return@Int2ObjectFunction canvas
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun makeMainFrame(): FramePanel {
|
override fun makeMainFrame(): FramePanel {
|
||||||
val frame = FramePanel(this, width = 200f, height = 180f, title = this.title)
|
val frame = FramePanel(this, width = 200f, height = 180f, title = this.title)
|
||||||
|
|
||||||
@ -53,16 +22,16 @@ class ExoSuitInventoryScreen(menu: ExoSuitInventoryMenu) : MatteryScreen<ExoSuit
|
|||||||
|
|
||||||
var mainInventoryLine: EditablePanel? = null
|
var mainInventoryLine: EditablePanel? = null
|
||||||
|
|
||||||
val scrollPanel = DiscreteScrollBarPanel(this, null, maxScroll = { ((menu.combinedInventorySlots.size - 27) + 8) / 9 },
|
val scrollPanel = DiscreteScrollBarPanel(this, null, maxScroll = { ((menu.playerCombinedInventorySlots.size - 27) + 8) / 9 },
|
||||||
scrollCallback = {
|
scrollCallback = {
|
||||||
_, old, new ->
|
_, old, new ->
|
||||||
|
|
||||||
for (i in old .. old + 2) {
|
for (i in old .. old + 2) {
|
||||||
getSlotsRow(i).visible = false
|
getInventorySlotsRow(i).visible = false
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i in new .. new + 2) {
|
for (i in new .. new + 2) {
|
||||||
val row = getSlotsRow(i)
|
val row = getInventorySlotsRow(i)
|
||||||
row.visible = true
|
row.visible = true
|
||||||
row.y = (i - new) * AbstractSlotPanel.SIZE
|
row.y = (i - new) * AbstractSlotPanel.SIZE
|
||||||
row.parent = mainInventoryLine
|
row.parent = mainInventoryLine
|
||||||
@ -83,7 +52,7 @@ class ExoSuitInventoryScreen(menu: ExoSuitInventoryMenu) : MatteryScreen<ExoSuit
|
|||||||
|
|
||||||
mainInventoryLine.dock = Dock.BOTTOM
|
mainInventoryLine.dock = Dock.BOTTOM
|
||||||
|
|
||||||
for (slot in menu.hotbarSlots) {
|
for (slot in menu.playerHotbarSlots) {
|
||||||
val panel = SlotPanel(this, toolbeltLine, slot)
|
val panel = SlotPanel(this, toolbeltLine, slot)
|
||||||
panel.dock = Dock.LEFT
|
panel.dock = Dock.LEFT
|
||||||
}
|
}
|
||||||
@ -92,7 +61,7 @@ class ExoSuitInventoryScreen(menu: ExoSuitInventoryMenu) : MatteryScreen<ExoSuit
|
|||||||
offhand.dock = Dock.RIGHT
|
offhand.dock = Dock.RIGHT
|
||||||
|
|
||||||
for (i in scrollPanel.scroll .. scrollPanel.scroll + 2) {
|
for (i in scrollPanel.scroll .. scrollPanel.scroll + 2) {
|
||||||
getSlotsRow(i).also {
|
getInventorySlotsRow(i).also {
|
||||||
it.parent = mainInventoryLine
|
it.parent = mainInventoryLine
|
||||||
it.y = AbstractSlotPanel.SIZE * (i - scrollPanel.scroll)
|
it.y = AbstractSlotPanel.SIZE * (i - scrollPanel.scroll)
|
||||||
}
|
}
|
||||||
|
@ -8,13 +8,14 @@ import net.minecraft.world.entity.player.Inventory
|
|||||||
import net.minecraft.world.item.ItemStack
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraft.world.item.Items
|
import net.minecraft.world.item.Items
|
||||||
import org.lwjgl.opengl.GL11
|
import org.lwjgl.opengl.GL11
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.block.entity.storage.ItemMonitorPlayerSettings
|
import ru.dbotthepony.mc.otm.block.entity.storage.ItemMonitorPlayerSettings
|
||||||
import ru.dbotthepony.mc.otm.client.render.UVWindingOrder
|
import ru.dbotthepony.mc.otm.client.render.UVWindingOrder
|
||||||
import ru.dbotthepony.mc.otm.client.render.Widgets8
|
import ru.dbotthepony.mc.otm.client.render.Widgets8
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
||||||
import ru.dbotthepony.mc.otm.client.screen.widget.ProgressGaugePanel
|
import ru.dbotthepony.mc.otm.client.screen.widget.ProgressGaugePanel
|
||||||
import ru.dbotthepony.mc.otm.core.equalDownDivision
|
import ru.dbotthepony.mc.otm.client.screen.widget.TallHorizontalPowerGaugePanel
|
||||||
|
import ru.dbotthepony.mc.otm.core.maxScrollDivision
|
||||||
import ru.dbotthepony.mc.otm.core.formatReadableNumber
|
import ru.dbotthepony.mc.otm.core.formatReadableNumber
|
||||||
import ru.dbotthepony.mc.otm.core.formatSiComponent
|
import ru.dbotthepony.mc.otm.core.formatSiComponent
|
||||||
import ru.dbotthepony.mc.otm.menu.ItemMonitorMenu
|
import ru.dbotthepony.mc.otm.menu.ItemMonitorMenu
|
||||||
@ -24,7 +25,7 @@ class ItemMonitorScreen(menu: ItemMonitorMenu, inventory: Inventory, title: Comp
|
|||||||
MatteryScreen<ItemMonitorMenu>(menu, inventory, title) {
|
MatteryScreen<ItemMonitorMenu>(menu, inventory, title) {
|
||||||
|
|
||||||
override fun makeMainFrame(): FramePanel {
|
override fun makeMainFrame(): FramePanel {
|
||||||
val frame = FramePanel(this@ItemMonitorScreen, null, 0f, 0f, FRAME_WIDTH, FRAME_HEIGHT, getTitle())
|
val frame = FramePanel(this@ItemMonitorScreen, null, 0f, 0f, 1f, 1f, getTitle())
|
||||||
|
|
||||||
val topPanel = EditablePanel(this, frame)
|
val topPanel = EditablePanel(this, frame)
|
||||||
topPanel.height = ITEM_GRID_HEIGHT * 18f
|
topPanel.height = ITEM_GRID_HEIGHT * 18f
|
||||||
@ -35,11 +36,13 @@ class ItemMonitorScreen(menu: ItemMonitorMenu, inventory: Inventory, title: Comp
|
|||||||
bottomPanel.dock = Dock.TOP
|
bottomPanel.dock = Dock.TOP
|
||||||
bottomPanel.setDockMargin(top = 6f)
|
bottomPanel.setDockMargin(top = 6f)
|
||||||
|
|
||||||
frame.height = topPanel.height + bottomPanel.height + frame.dockPadding.top + frame.dockPadding.bottom + 6f
|
frame.height = topPanel.height + bottomPanel.height + frame.dockPadding.top + frame.dockPadding.bottom + 26f
|
||||||
frame.width = 178f + frame.dockPadding.left + frame.dockPadding.right
|
frame.width = 178f + frame.dockPadding.left + frame.dockPadding.right
|
||||||
|
|
||||||
val viewScrollBar = ContinuousScrollBarPanel(this, topPanel, 28f + ITEM_GRID_WIDTH * 18f + 2f, 16f, ITEM_GRID_HEIGHT * 18f)
|
val viewScrollBar = DiscreteScrollBarPanel(this, topPanel,
|
||||||
viewScrollBar.setupRowMultiplier { equalDownDivision(menu.networkedItemView.itemCount, ITEM_GRID_WIDTH) }
|
{ maxScrollDivision(menu.networkedItemView.itemCount, ITEM_GRID_WIDTH) },
|
||||||
|
{ _, _, _ -> },
|
||||||
|
28f + ITEM_GRID_WIDTH * 18f + 2f, 16f, ITEM_GRID_HEIGHT * 18f)
|
||||||
|
|
||||||
viewScrollBar.dock = Dock.RIGHT
|
viewScrollBar.dock = Dock.RIGHT
|
||||||
viewScrollBar.setDockMargin(left = 2f)
|
viewScrollBar.setDockMargin(left = 2f)
|
||||||
@ -49,7 +52,7 @@ class ItemMonitorScreen(menu: ItemMonitorMenu, inventory: Inventory, title: Comp
|
|||||||
|
|
||||||
for (i in 0 until ITEM_GRID_WIDTH * ITEM_GRID_HEIGHT) {
|
for (i in 0 until ITEM_GRID_WIDTH * ITEM_GRID_HEIGHT) {
|
||||||
object : AbstractSlotPanel(this@ItemMonitorScreen, gridPanel) {
|
object : AbstractSlotPanel(this@ItemMonitorScreen, gridPanel) {
|
||||||
private val index get() = i + viewScrollBar.getScroll(equalDownDivision(menu.networkedItemView.itemCount, ITEM_GRID_WIDTH)) * ITEM_GRID_WIDTH
|
private val index get() = i + viewScrollBar.scroll * ITEM_GRID_WIDTH
|
||||||
|
|
||||||
override fun getItemStack(): ItemStack {
|
override fun getItemStack(): ItemStack {
|
||||||
return menu.networkedItemView.sortedView.getOrNull(index)?.stack?.item ?: ItemStack.EMPTY
|
return menu.networkedItemView.sortedView.getOrNull(index)?.stack?.item ?: ItemStack.EMPTY
|
||||||
@ -116,7 +119,7 @@ class ItemMonitorScreen(menu: ItemMonitorMenu, inventory: Inventory, title: Comp
|
|||||||
arrowAndButtons.dock = Dock.LEFT
|
arrowAndButtons.dock = Dock.LEFT
|
||||||
arrowAndButtons.setDockMargin(left = 4f)
|
arrowAndButtons.setDockMargin(left = 4f)
|
||||||
|
|
||||||
val arrowLineTop = EditablePanel(this, arrowAndButtons, y = 0f, height = 8f, width = arrowAndButtons.width)
|
EditablePanel(this, arrowAndButtons, y = 0f, height = 8f, width = arrowAndButtons.width)
|
||||||
|
|
||||||
val arrowLine = EditablePanel(this, arrowAndButtons, y = 38f, height = 8f, width = arrowAndButtons.width)
|
val arrowLine = EditablePanel(this, arrowAndButtons, y = 38f, height = 8f, width = arrowAndButtons.width)
|
||||||
|
|
||||||
@ -168,7 +171,7 @@ class ItemMonitorScreen(menu: ItemMonitorMenu, inventory: Inventory, title: Comp
|
|||||||
craftingHistory.dock = Dock.LEFT
|
craftingHistory.dock = Dock.LEFT
|
||||||
craftingHistory.setDockMargin(left = 4f)
|
craftingHistory.setDockMargin(left = 4f)
|
||||||
|
|
||||||
val craftingHistoryScroll = ContinuousScrollBarPanel(this, bottomPanel, 0f, 0f, 0f)
|
val craftingHistoryScroll = DiscreteScrollBarPanel(this, bottomPanel, { 0 }, { _, _, _ -> })
|
||||||
craftingHistoryScroll.dock = Dock.LEFT
|
craftingHistoryScroll.dock = Dock.LEFT
|
||||||
craftingHistoryScroll.setDockMargin(left = 2f)
|
craftingHistoryScroll.setDockMargin(left = 2f)
|
||||||
|
|
||||||
@ -184,13 +187,23 @@ class ItemMonitorScreen(menu: ItemMonitorMenu, inventory: Inventory, title: Comp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val bottomStrip = EditablePanel(this, frame, height = AbstractSlotPanel.SIZE)
|
||||||
|
bottomStrip.dock = Dock.BOTTOM
|
||||||
|
|
||||||
|
BatterySlotPanel(this, bottomStrip, menu.batterySlot).also {
|
||||||
|
it.dock = Dock.LEFT
|
||||||
|
it.dockRight = 3f
|
||||||
|
}
|
||||||
|
|
||||||
|
TallHorizontalPowerGaugePanel(this, bottomStrip, menu.powerWidget).also {
|
||||||
|
it.dock = Dock.FILL
|
||||||
|
it.dockResize = DockResizeMode.NONE
|
||||||
|
}
|
||||||
|
|
||||||
return frame
|
return frame
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val FRAME_WIDTH = 240f
|
|
||||||
const val FRAME_HEIGHT = 210f
|
|
||||||
|
|
||||||
const val ITEM_GRID_WIDTH = 9
|
const val ITEM_GRID_WIDTH = 9
|
||||||
const val ITEM_GRID_HEIGHT = 5
|
const val ITEM_GRID_HEIGHT = 5
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ package ru.dbotthepony.mc.otm.client.screen
|
|||||||
|
|
||||||
import net.minecraft.network.chat.Component
|
import net.minecraft.network.chat.Component
|
||||||
import net.minecraft.world.entity.player.Inventory
|
import net.minecraft.world.entity.player.Inventory
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
||||||
import ru.dbotthepony.mc.otm.client.screen.widget.MatterGaugePanel
|
import ru.dbotthepony.mc.otm.client.screen.widget.MatterGaugePanel
|
||||||
import ru.dbotthepony.mc.otm.client.screen.widget.PowerGaugePanel
|
import ru.dbotthepony.mc.otm.client.screen.widget.PowerGaugePanel
|
||||||
|
@ -0,0 +1,295 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.client.screen
|
||||||
|
|
||||||
|
import net.minecraft.ChatFormatting
|
||||||
|
import net.minecraft.client.gui.components.EditBox
|
||||||
|
import net.minecraft.network.chat.Component
|
||||||
|
import net.minecraft.world.entity.player.Inventory
|
||||||
|
import net.minecraft.world.item.ItemStack
|
||||||
|
import ru.dbotthepony.mc.otm.capability.matter.IPatternState
|
||||||
|
import ru.dbotthepony.mc.otm.capability.matter.IReplicationTask
|
||||||
|
import ru.dbotthepony.mc.otm.capability.matter.PatternState
|
||||||
|
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
||||||
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
|
import ru.dbotthepony.mc.otm.core.maxScrollDivision
|
||||||
|
import ru.dbotthepony.mc.otm.menu.MatterPanelMenu
|
||||||
|
import ru.dbotthepony.mc.otm.menu.ReplicationRequestPacket
|
||||||
|
import ru.dbotthepony.mc.otm.network.MenuNetworkChannel
|
||||||
|
|
||||||
|
class MatterPanelScreen(
|
||||||
|
menu: MatterPanelMenu,
|
||||||
|
inventory: Inventory,
|
||||||
|
title: Component
|
||||||
|
) : MatteryScreen<MatterPanelMenu>(menu, inventory, title) {
|
||||||
|
override fun makeMainFrame(): FramePanel {
|
||||||
|
var isPatternView = true
|
||||||
|
|
||||||
|
val frame = FramePanel.padded(this, null, GRID_WIDTH * AbstractSlotPanel.SIZE + ScrollBarConstants.WIDTH + 4f, GRID_HEIGHT * AbstractSlotPanel.SIZE, title)
|
||||||
|
|
||||||
|
val scrollBar = DiscreteScrollBarPanel(this, frame, {
|
||||||
|
if (isPatternView) {
|
||||||
|
maxScrollDivision(menu.patterns.size, GRID_WIDTH)
|
||||||
|
} else {
|
||||||
|
maxScrollDivision(menu.tasks.size, GRID_WIDTH)
|
||||||
|
}
|
||||||
|
}, { _, _, _ -> })
|
||||||
|
|
||||||
|
scrollBar.dock = Dock.RIGHT
|
||||||
|
|
||||||
|
frame.addTab(FramePanel.Position.TOP, open = { isPatternView = true })
|
||||||
|
frame.addTab(FramePanel.Position.TOP, open = { isPatternView = false })
|
||||||
|
|
||||||
|
val canvas = object : EditablePanel(this@MatterPanelScreen, frame, width = GRID_WIDTH * AbstractSlotPanel.SIZE) {
|
||||||
|
init {
|
||||||
|
dock = Dock.LEFT
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun mouseScrolledInner(x: Double, y: Double, scroll: Double): Boolean {
|
||||||
|
return scrollBar.mouseScrolledInner(x, y, scroll)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (row in 0 until GRID_HEIGHT) {
|
||||||
|
val rowCanvas = object : EditablePanel(this@MatterPanelScreen, canvas, height = AbstractSlotPanel.SIZE) {
|
||||||
|
init {
|
||||||
|
dock = Dock.TOP
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun mouseScrolledInner(x: Double, y: Double, scroll: Double): Boolean {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i in 0 until GRID_WIDTH) {
|
||||||
|
object : AbstractSlotPanel(this@MatterPanelScreen, rowCanvas) {
|
||||||
|
init {
|
||||||
|
dock = Dock.LEFT
|
||||||
|
}
|
||||||
|
|
||||||
|
private val index: Int get() = (scrollBar.scroll + row) * GRID_WIDTH + i
|
||||||
|
|
||||||
|
override fun getItemStack(): ItemStack {
|
||||||
|
if (isPatternView) {
|
||||||
|
return menu.patterns.getOrNull(index)?.stack() ?: ItemStack.EMPTY
|
||||||
|
} else {
|
||||||
|
return menu.tasks.getOrNull(index)?.let { it.stack(it.required + it.inProgress) } ?: ItemStack.EMPTY
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemStackTooltip(stack: ItemStack): List<Component> {
|
||||||
|
val list = super.getItemStackTooltip(stack).toMutableList()
|
||||||
|
|
||||||
|
if (isPatternView) {
|
||||||
|
menu.patterns.getOrNull(index)?.let {
|
||||||
|
list.add(TranslatableComponent(
|
||||||
|
"otm.item.pattern.research",
|
||||||
|
String.format("%.2f", it.researchPercent * 100.0)
|
||||||
|
).withStyle(ChatFormatting.AQUA)) }
|
||||||
|
} else {
|
||||||
|
menu.tasks.getOrNull(index)?.let {
|
||||||
|
list.add(TranslatableComponent("otm.gui.matter_task.total", it.total).withStyle(ChatFormatting.GRAY))
|
||||||
|
list.add(TranslatableComponent("otm.gui.matter_task.required", it.required).withStyle(ChatFormatting.GRAY))
|
||||||
|
list.add(TranslatableComponent("otm.gui.matter_task.in_progress", it.inProgress).withStyle(ChatFormatting.GRAY))
|
||||||
|
list.add(TranslatableComponent("otm.gui.matter_task.finished", it.finished).withStyle(ChatFormatting.GRAY))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean {
|
||||||
|
if (isPatternView) {
|
||||||
|
menu.patterns.getOrNull(index)?.let(this@MatterPanelScreen::openPattern)
|
||||||
|
} else {
|
||||||
|
menu.tasks.getOrNull(index)?.let(this@MatterPanelScreen::openTask)
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun mouseScrolledInner(x: Double, y: Double, scroll: Double): Boolean {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return frame
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun openTask(task: IReplicationTask<*>) {
|
||||||
|
val frame = FramePanel.padded(this, null, 170f, 20f, TranslatableComponent("otm.container.matter_panel.task"))
|
||||||
|
|
||||||
|
object : AbstractSlotPanel(this@MatterPanelScreen, frame) {
|
||||||
|
init {
|
||||||
|
dock = Dock.LEFT
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemStack(): ItemStack {
|
||||||
|
return menu.tasks.firstOrNull { it.id == task.id }?.let { it.stack((it.required + it.inProgress).coerceAtLeast(1)) } ?: task.stack((task.required + task.inProgress).coerceAtLeast(1))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun tick() {
|
||||||
|
super.tick()
|
||||||
|
|
||||||
|
if (!menu.tasks.any { it.id == task.id }) {
|
||||||
|
frame.remove()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtonPanel(this@MatterPanelScreen, frame, width = 40f, label = TranslatableComponent("otm.container.matter_panel.close"), onPress = frame::remove).also {
|
||||||
|
it.dock = Dock.RIGHT
|
||||||
|
it.dockLeft = 2f
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtonPanel(this@MatterPanelScreen, frame, width = 80f, label = TranslatableComponent("otm.container.matter_panel.cancel_task"), onPress = {
|
||||||
|
menu.requestTaskCancel(task.id)
|
||||||
|
frame.remove()
|
||||||
|
}).also {
|
||||||
|
it.dock = Dock.RIGHT
|
||||||
|
it.dockLeft = 2f
|
||||||
|
}
|
||||||
|
|
||||||
|
addPanel(frame)
|
||||||
|
popup(frame)
|
||||||
|
|
||||||
|
frame.toScreenCenter()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun openPattern(pattern: IPatternState) {
|
||||||
|
val frame = FramePanel.padded(this, null, 213f, (ButtonPanel.HEIGHT + 3f) * 4f, TranslatableComponent("otm.container.matter_panel.task"))
|
||||||
|
|
||||||
|
val rowTop = EditablePanel(this, frame, height = ButtonPanel.HEIGHT)
|
||||||
|
val rowInput = EditablePanel(this, frame, height = ButtonPanel.HEIGHT)
|
||||||
|
val rowBottom = EditablePanel(this, frame, height = ButtonPanel.HEIGHT)
|
||||||
|
val rowControls = EditablePanel(this, frame, height = ButtonPanel.HEIGHT)
|
||||||
|
|
||||||
|
rowTop.dock = Dock.TOP
|
||||||
|
rowTop.dockTop = 3f
|
||||||
|
rowInput.dock = Dock.TOP
|
||||||
|
rowInput.dockTop = 3f
|
||||||
|
rowBottom.dock = Dock.TOP
|
||||||
|
rowBottom.dockTop = 3f
|
||||||
|
rowControls.dock = Dock.TOP
|
||||||
|
rowControls.dockTop = 3f
|
||||||
|
|
||||||
|
object : AbstractSlotPanel(this@MatterPanelScreen, rowInput) {
|
||||||
|
init {
|
||||||
|
dock = Dock.LEFT
|
||||||
|
dockRight = 2f
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemStack(): ItemStack {
|
||||||
|
return pattern.stack()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemStackTooltip(stack: ItemStack): List<Component> {
|
||||||
|
return super.getItemStackTooltip(stack).toMutableList().also {
|
||||||
|
it.add(TranslatableComponent(
|
||||||
|
"otm.item.pattern.research",
|
||||||
|
String.format("%.2f", pattern.researchPercent * 100.0)
|
||||||
|
).withStyle(ChatFormatting.AQUA))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun tick() {
|
||||||
|
super.tick()
|
||||||
|
|
||||||
|
if (!menu.patterns.any { it.id == pattern.id }) {
|
||||||
|
frame.remove()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val input = object : EditBoxPanel(this@MatterPanelScreen, rowInput) {
|
||||||
|
init {
|
||||||
|
dock = Dock.FILL
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun configureNew(widget: EditBox, recreation: Boolean) {
|
||||||
|
super.configureNew(widget, recreation)
|
||||||
|
widget.setMaxLength(6)
|
||||||
|
|
||||||
|
if (!recreation) {
|
||||||
|
widget.value = "1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun increase(amount: Int) {
|
||||||
|
var value = 1
|
||||||
|
|
||||||
|
try {
|
||||||
|
value = getOrCreateWidget().value.toInt()
|
||||||
|
} catch (_: NumberFormatException) {
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value == 1 && amount > 0)
|
||||||
|
getOrCreateWidget().value = amount.toString()
|
||||||
|
else
|
||||||
|
getOrCreateWidget().value = 1.coerceAtLeast(99999.coerceAtMost(value + amount)).toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun send() {
|
||||||
|
var value = 1
|
||||||
|
|
||||||
|
try {
|
||||||
|
value = getOrCreateWidget().value.toInt()
|
||||||
|
} catch (_: NumberFormatException) {
|
||||||
|
}
|
||||||
|
|
||||||
|
MenuNetworkChannel.sendToServer(ReplicationRequestPacket(pattern.id, value))
|
||||||
|
frame.remove()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtonPanel(this, rowTop, width = 40f, label = TranslatableComponent("otm.container.matter_panel.increase_by", 8), onPress = { input.increase(8) }).also {
|
||||||
|
it.dock = Dock.RIGHT
|
||||||
|
it.dockLeft = 2f
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtonPanel(this, rowTop, width = 40f, label = TranslatableComponent("otm.container.matter_panel.increase_by", 64), onPress = { input.increase(64) }).also {
|
||||||
|
it.dock = Dock.RIGHT
|
||||||
|
it.dockLeft = 2f
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtonPanel(this, rowTop, width = 40f, label = TranslatableComponent("otm.container.matter_panel.increase_by", 256), onPress = { input.increase(256) }).also {
|
||||||
|
it.dock = Dock.RIGHT
|
||||||
|
it.dockLeft = 2f
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtonPanel(this, rowBottom, width = 40f, label = TranslatableComponent("otm.container.matter_panel.decrease_by", 8), onPress = { input.increase(-8) }).also {
|
||||||
|
it.dock = Dock.RIGHT
|
||||||
|
it.dockLeft = 2f
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtonPanel(this, rowBottom, width = 40f, label = TranslatableComponent("otm.container.matter_panel.decrease_by", 64), onPress = { input.increase(-64) }).also {
|
||||||
|
it.dock = Dock.RIGHT
|
||||||
|
it.dockLeft = 2f
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtonPanel(this, rowBottom, width = 40f, label = TranslatableComponent("otm.container.matter_panel.decrease_by", 256), onPress = { input.increase(-256) }).also {
|
||||||
|
it.dock = Dock.RIGHT
|
||||||
|
it.dockLeft = 2f
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtonPanel(this, rowControls, width = 40f, label = TranslatableComponent("otm.container.matter_panel.cancel"), onPress = frame::remove).also {
|
||||||
|
it.dock = Dock.RIGHT
|
||||||
|
it.dockLeft = 2f
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtonPanel(this, rowControls, width = 82f, label = TranslatableComponent("otm.container.matter_panel.send"), onPress = input::send).also {
|
||||||
|
it.dock = Dock.RIGHT
|
||||||
|
it.dockLeft = 2f
|
||||||
|
}
|
||||||
|
|
||||||
|
addPanel(frame)
|
||||||
|
popup(frame)
|
||||||
|
|
||||||
|
frame.toScreenCenter()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val GRID_HEIGHT = 8
|
||||||
|
const val GRID_WIDTH = 9
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,8 @@ package ru.dbotthepony.mc.otm.client.screen
|
|||||||
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem
|
import com.mojang.blaze3d.systems.RenderSystem
|
||||||
import com.mojang.blaze3d.vertex.PoseStack
|
import com.mojang.blaze3d.vertex.PoseStack
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectFunction
|
||||||
import net.minecraft.ChatFormatting
|
import net.minecraft.ChatFormatting
|
||||||
import net.minecraft.client.gui.Font
|
import net.minecraft.client.gui.Font
|
||||||
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen
|
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen
|
||||||
@ -14,9 +16,8 @@ import net.minecraftforge.client.event.ContainerScreenEvent.Render.Foreground
|
|||||||
import net.minecraftforge.common.MinecraftForge
|
import net.minecraftforge.common.MinecraftForge
|
||||||
import org.lwjgl.opengl.GL11
|
import org.lwjgl.opengl.GL11
|
||||||
import org.lwjgl.opengl.GL13
|
import org.lwjgl.opengl.GL13
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel
|
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.SlotPanel
|
|
||||||
import ru.dbotthepony.mc.otm.menu.MatteryMenu
|
import ru.dbotthepony.mc.otm.menu.MatteryMenu
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -50,16 +51,108 @@ abstract class MatteryScreen<T : MatteryMenu>(menu: T, inventory: Inventory, tit
|
|||||||
val quickCraftingType get() = quickCraftingType
|
val quickCraftingType get() = quickCraftingType
|
||||||
val isQuickCrafting get() = isQuickCrafting
|
val isQuickCrafting get() = isQuickCrafting
|
||||||
|
|
||||||
|
private val inventorySlotsRows = Int2ObjectAVLTreeMap<EditablePanel>()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if (menu.playerInventorySlots.isNotEmpty() && menu.autoCreateInventoryFrame) {
|
if (menu.playerInventorySlots.isNotEmpty() && menu.autoCreateInventoryFrame) {
|
||||||
inventoryFrame = FramePanel(this, null, 0f, 0f, INVENTORY_FRAME_WIDTH, INVENTORY_FRAME_HEIGHT, inventory.displayName).also(this::addPanel)
|
if (menu.playerExoSuitSlots.isEmpty()) {
|
||||||
|
inventoryFrame = FramePanel(this, null, 0f, 0f, INVENTORY_FRAME_WIDTH, INVENTORY_FRAME_HEIGHT, inventory.displayName).also(this::addPanel)
|
||||||
|
|
||||||
for (slot in menu.playerInventorySlots) {
|
val hotbarStrip = EditablePanel(this, inventoryFrame, height = AbstractSlotPanel.SIZE)
|
||||||
SlotPanel(this, inventoryFrame, slot, slot.x.toFloat(), slot.y.toFloat())
|
hotbarStrip.dock = Dock.BOTTOM
|
||||||
|
|
||||||
|
for (slot in menu.playerHotbarSlots) {
|
||||||
|
SlotPanel(this, hotbarStrip, slot).also { it.dock = Dock.LEFT }
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i in 0 .. 2) {
|
||||||
|
getInventorySlotsRow(i).also {
|
||||||
|
it.parent = inventoryFrame
|
||||||
|
it.y = i * AbstractSlotPanel.SIZE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
inventoryFrame = FramePanel(this, null, 0f, 0f, INVENTORY_FRAME_WIDTH_EXTENDED, INVENTORY_FRAME_HEIGHT, inventory.displayName).also(this::addPanel)
|
||||||
|
|
||||||
|
var slotListCanvas: EditablePanel? = null
|
||||||
|
|
||||||
|
val scrollbar = DiscreteScrollBarPanel(this, inventoryFrame, { ((menu.playerCombinedInventorySlots.size - 27) + 8) / 9 }, {
|
||||||
|
_, old, new ->
|
||||||
|
|
||||||
|
for (i in old .. old + 2) {
|
||||||
|
getInventorySlotsRow(i).visible = false
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i in new .. new + 2) {
|
||||||
|
getInventorySlotsRow(i).also {
|
||||||
|
it.visible = true
|
||||||
|
it.parent = slotListCanvas
|
||||||
|
it.y = (i - new) * AbstractSlotPanel.SIZE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
menu.ply.matteryPlayer?.exoSuitMenu?.lastScroll = new
|
||||||
|
})
|
||||||
|
|
||||||
|
slotListCanvas = object : EditablePanel(this@MatteryScreen, inventoryFrame, height = AbstractSlotPanel.SIZE * 3f) {
|
||||||
|
override fun mouseScrolledInner(x: Double, y: Double, scroll: Double): Boolean {
|
||||||
|
scrollbar.mouseScrolledInner(x, y, scroll)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
slotListCanvas.dock = Dock.TOP
|
||||||
|
|
||||||
|
val hotbarStrip = EditablePanel(this, inventoryFrame, height = AbstractSlotPanel.SIZE)
|
||||||
|
hotbarStrip.dock = Dock.BOTTOM
|
||||||
|
|
||||||
|
for (slot in menu.playerHotbarSlots) {
|
||||||
|
SlotPanel(this, hotbarStrip, slot).also { it.dock = Dock.LEFT }
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollbar.parent = slotListCanvas
|
||||||
|
scrollbar.dock = Dock.RIGHT
|
||||||
|
|
||||||
|
scrollbar.scroll = menu.ply.matteryPlayer?.exoSuitMenu?.lastScroll ?: 0
|
||||||
|
|
||||||
|
for (i in scrollbar.scroll .. scrollbar.scroll + 2) {
|
||||||
|
getInventorySlotsRow(i).also {
|
||||||
|
it.parent = slotListCanvas
|
||||||
|
it.y = (i - scrollbar.scroll) * AbstractSlotPanel.SIZE
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected fun getInventorySlotsRow(index: Int): EditablePanel {
|
||||||
|
return inventorySlotsRows.computeIfAbsent(index, Int2ObjectFunction {
|
||||||
|
val canvas = object : EditablePanel(this@MatteryScreen, null, width = AbstractSlotPanel.SIZE * 9f, height = AbstractSlotPanel.SIZE) {
|
||||||
|
override fun mouseScrolledInner(x: Double, y: Double, scroll: Double): Boolean {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val offset = it * 9
|
||||||
|
|
||||||
|
if (menu.playerCombinedInventorySlots.size <= offset) {
|
||||||
|
return@Int2ObjectFunction canvas
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i in 0 .. (8).coerceAtMost(menu.playerCombinedInventorySlots.size - offset - 1)) {
|
||||||
|
val slot = object : SlotPanel<Slot>(this@MatteryScreen, canvas, menu.playerCombinedInventorySlots[offset + i]) {
|
||||||
|
override fun mouseScrolledInner(x: Double, y: Double, scroll: Double): Boolean {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
slot.dock = Dock.LEFT
|
||||||
|
}
|
||||||
|
|
||||||
|
return@Int2ObjectFunction canvas
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
override fun init() {
|
override fun init() {
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
@ -102,7 +195,7 @@ abstract class MatteryScreen<T : MatteryMenu>(menu: T, inventory: Inventory, tit
|
|||||||
|
|
||||||
require(indexOf != -1) { "No such panel $panel" }
|
require(indexOf != -1) { "No such panel $panel" }
|
||||||
|
|
||||||
if (indexOf == panels.size - 1) {
|
if (indexOf == 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -354,10 +447,13 @@ abstract class MatteryScreen<T : MatteryMenu>(menu: T, inventory: Inventory, tit
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val DEFAULT_FRAME_WIDTH = 18f * 9f + 16f
|
const val DEFAULT_FRAME_WIDTH = AbstractSlotPanel.SIZE * 9f + 16f
|
||||||
const val DEFAULT_FRAME_HEIGHT = 100f
|
const val DEFAULT_FRAME_HEIGHT = 100f
|
||||||
|
|
||||||
const val INVENTORY_FRAME_WIDTH = DEFAULT_FRAME_WIDTH
|
const val INVENTORY_FRAME_WIDTH = DEFAULT_FRAME_WIDTH
|
||||||
const val INVENTORY_FRAME_HEIGHT = 3f * 18f + 18f + 24f
|
const val INVENTORY_FRAME_WIDTH_EXTENDED = DEFAULT_FRAME_WIDTH + ScrollBarConstants.WIDTH + 2f
|
||||||
|
const val INVENTORY_FRAME_HEIGHT = 3f * AbstractSlotPanel.SIZE + AbstractSlotPanel.SIZE + 24f
|
||||||
|
|
||||||
const val GAUGE_TOP_WITH_SLOT = 17f
|
const val GAUGE_TOP_WITH_SLOT = 17f
|
||||||
const val GAUGE_TOP_WITHOUT_SLOT = 26f
|
const val GAUGE_TOP_WITHOUT_SLOT = 26f
|
||||||
const val SLOT_TOP_UNDER_GAUGE = 70f
|
const val SLOT_TOP_UNDER_GAUGE = 70f
|
||||||
|
@ -2,9 +2,8 @@ package ru.dbotthepony.mc.otm.client.screen
|
|||||||
|
|
||||||
import net.minecraft.network.chat.Component
|
import net.minecraft.network.chat.Component
|
||||||
import net.minecraft.world.entity.player.Inventory
|
import net.minecraft.world.entity.player.Inventory
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
||||||
import ru.dbotthepony.mc.otm.client.screen.widget.PowerGaugePanel
|
|
||||||
import ru.dbotthepony.mc.otm.client.screen.widget.WidePowerGaugePanel
|
import ru.dbotthepony.mc.otm.client.screen.widget.WidePowerGaugePanel
|
||||||
|
|
||||||
import ru.dbotthepony.mc.otm.menu.StorageBusMenu
|
import ru.dbotthepony.mc.otm.menu.StorageBusMenu
|
||||||
|
@ -2,9 +2,8 @@ package ru.dbotthepony.mc.otm.client.screen
|
|||||||
|
|
||||||
import net.minecraft.network.chat.Component
|
import net.minecraft.network.chat.Component
|
||||||
import net.minecraft.world.entity.player.Inventory
|
import net.minecraft.world.entity.player.Inventory
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
||||||
import ru.dbotthepony.mc.otm.client.screen.widget.PowerGaugePanel
|
|
||||||
import ru.dbotthepony.mc.otm.client.screen.widget.WidePowerGaugePanel
|
import ru.dbotthepony.mc.otm.client.screen.widget.WidePowerGaugePanel
|
||||||
|
|
||||||
import ru.dbotthepony.mc.otm.menu.StorageExporterMenu
|
import ru.dbotthepony.mc.otm.menu.StorageExporterMenu
|
||||||
|
@ -2,9 +2,8 @@ package ru.dbotthepony.mc.otm.client.screen
|
|||||||
|
|
||||||
import net.minecraft.network.chat.Component
|
import net.minecraft.network.chat.Component
|
||||||
import net.minecraft.world.entity.player.Inventory
|
import net.minecraft.world.entity.player.Inventory
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
||||||
import ru.dbotthepony.mc.otm.client.screen.widget.PowerGaugePanel
|
|
||||||
import ru.dbotthepony.mc.otm.client.screen.widget.WidePowerGaugePanel
|
import ru.dbotthepony.mc.otm.client.screen.widget.WidePowerGaugePanel
|
||||||
|
|
||||||
import ru.dbotthepony.mc.otm.menu.StorageImporterMenu
|
import ru.dbotthepony.mc.otm.menu.StorageImporterMenu
|
||||||
|
@ -2,10 +2,9 @@ package ru.dbotthepony.mc.otm.client.screen
|
|||||||
|
|
||||||
import net.minecraft.network.chat.Component
|
import net.minecraft.network.chat.Component
|
||||||
import net.minecraft.world.entity.player.Inventory
|
import net.minecraft.world.entity.player.Inventory
|
||||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
||||||
import ru.dbotthepony.mc.otm.client.screen.widget.PowerGaugePanel
|
import ru.dbotthepony.mc.otm.client.screen.widget.HorizontalPowerGaugePanel
|
||||||
import ru.dbotthepony.mc.otm.client.screen.widget.WidePowerGaugePanel
|
|
||||||
import ru.dbotthepony.mc.otm.core.formatPower
|
import ru.dbotthepony.mc.otm.core.formatPower
|
||||||
|
|
||||||
import ru.dbotthepony.mc.otm.menu.StoragePowerSupplierMenu
|
import ru.dbotthepony.mc.otm.menu.StoragePowerSupplierMenu
|
||||||
@ -13,12 +12,32 @@ import ru.dbotthepony.mc.otm.menu.StoragePowerSupplierMenu
|
|||||||
class StoragePowerSupplierScreen(menu: StoragePowerSupplierMenu, inventory: Inventory, title: Component) :
|
class StoragePowerSupplierScreen(menu: StoragePowerSupplierMenu, inventory: Inventory, title: Component) :
|
||||||
MatteryScreen<StoragePowerSupplierMenu>(menu, inventory, title) {
|
MatteryScreen<StoragePowerSupplierMenu>(menu, inventory, title) {
|
||||||
override fun makeMainFrame(): FramePanel {
|
override fun makeMainFrame(): FramePanel {
|
||||||
val frame = super.makeMainFrame()!!
|
val frame = FramePanel(this, width = 200f, height = 60f, title)
|
||||||
|
|
||||||
WidePowerGaugePanel(this, frame, menu.powerWidget, LEFT_MARGIN, GAUGE_TOP_WITH_SLOT)
|
HorizontalPowerGaugePanel(this, frame, menu.powerWidget).also {
|
||||||
BatterySlotPanel(this, frame, menu.batterySlot, LEFT_MARGIN, SLOT_TOP_UNDER_GAUGE)
|
it.dock = Dock.BOTTOM
|
||||||
|
it.dockResize = DockResizeMode.NONE
|
||||||
|
}
|
||||||
|
|
||||||
|
val topStrip = EditablePanel(this, frame, height = AbstractSlotPanel.SIZE)
|
||||||
|
|
||||||
|
topStrip.dock = Dock.TOP
|
||||||
|
topStrip.dockTop = 3f
|
||||||
|
|
||||||
|
BatterySlotPanel(this, topStrip, menu.batterySlot).also {
|
||||||
|
it.dock = Dock.LEFT
|
||||||
|
it.dockRight = 3f
|
||||||
|
}
|
||||||
|
|
||||||
|
val labels = EditablePanel(this, topStrip)
|
||||||
|
|
||||||
|
labels.dock = Dock.FILL
|
||||||
|
|
||||||
|
object : Label(this@StoragePowerSupplierScreen, labels) {
|
||||||
|
init {
|
||||||
|
dock = Dock.TOP
|
||||||
|
}
|
||||||
|
|
||||||
object : Label(this@StoragePowerSupplierScreen, frame, 28f, 17f, width = 140f) {
|
|
||||||
override fun tick() {
|
override fun tick() {
|
||||||
super.tick()
|
super.tick()
|
||||||
|
|
||||||
@ -29,6 +48,21 @@ class StoragePowerSupplierScreen(menu: StoragePowerSupplierMenu, inventory: Inve
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object : Label(this@StoragePowerSupplierScreen, labels) {
|
||||||
|
init {
|
||||||
|
dock = Dock.TOP
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun tick() {
|
||||||
|
super.tick()
|
||||||
|
|
||||||
|
text = TranslatableComponent(
|
||||||
|
"otm.gui.power_supplier.active_nodes",
|
||||||
|
menu.activeNodes
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return frame
|
return frame
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,9 +23,8 @@ abstract class AbstractSlotPanel @JvmOverloads constructor(
|
|||||||
) : EditablePanel(
|
) : EditablePanel(
|
||||||
screen, parent, x, y, width, height
|
screen, parent, x, y, width, height
|
||||||
) {
|
) {
|
||||||
protected open fun renderSlotBackground(stack: PoseStack, mouse_x: Float, mouse_y: Float, flag: Float) {
|
protected open fun renderSlotBackground(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) {
|
||||||
RenderSystem.setShaderTexture(0, WidgetLocation.WIDGETS)
|
SLOT_BACKGROUND.render(stack, width = width, height = height)
|
||||||
drawTexturedRectAuto(stack, 0f, 0f, 18f, 18f, 0f, 96f, 256f, 256f)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun renderRegular(stack: PoseStack, itemstack: ItemStack, count_override: String? = null) {
|
protected open fun renderRegular(stack: PoseStack, itemstack: ItemStack, count_override: String? = null) {
|
||||||
@ -119,10 +118,9 @@ abstract class AbstractSlotPanel @JvmOverloads constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@JvmField
|
|
||||||
val SLOT_HIGHLIGHT = RGBAColor(255, 255, 255, 100)
|
val SLOT_HIGHLIGHT = RGBAColor(255, 255, 255, 100)
|
||||||
@JvmField
|
|
||||||
val SLOT_HIGHLIGHT_DRAG = RGBAColor(200, 200, 200, 150)
|
val SLOT_HIGHLIGHT_DRAG = RGBAColor(200, 200, 200, 150)
|
||||||
const val SIZE = 18f
|
const val SIZE = 18f
|
||||||
|
val SLOT_BACKGROUND = WidgetLocation.WIDGETS.element(0f, 0f, SIZE, SIZE)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,15 +5,13 @@ import com.mojang.blaze3d.vertex.PoseStack
|
|||||||
import net.minecraft.ChatFormatting
|
import net.minecraft.ChatFormatting
|
||||||
import net.minecraft.client.gui.components.Button
|
import net.minecraft.client.gui.components.Button
|
||||||
import net.minecraft.client.gui.components.Button.OnPress
|
import net.minecraft.client.gui.components.Button.OnPress
|
||||||
import net.minecraft.client.resources.sounds.SimpleSoundInstance
|
|
||||||
import net.minecraft.network.chat.Component
|
import net.minecraft.network.chat.Component
|
||||||
import net.minecraft.sounds.SoundEvents
|
import ru.dbotthepony.mc.otm.client.playGuiClickSound
|
||||||
import ru.dbotthepony.mc.otm.TextComponent
|
import ru.dbotthepony.mc.otm.core.TextComponent
|
||||||
import ru.dbotthepony.mc.otm.client.minecraft
|
|
||||||
import ru.dbotthepony.mc.otm.client.render.*
|
import ru.dbotthepony.mc.otm.client.render.*
|
||||||
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
|
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
|
||||||
import ru.dbotthepony.mc.otm.next
|
import ru.dbotthepony.mc.otm.core.next
|
||||||
import ru.dbotthepony.mc.otm.prev
|
import ru.dbotthepony.mc.otm.core.prev
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
import kotlin.reflect.KMutableProperty0
|
import kotlin.reflect.KMutableProperty0
|
||||||
@ -24,10 +22,22 @@ open class ButtonPanel(
|
|||||||
x: Float = 0f,
|
x: Float = 0f,
|
||||||
y: Float = 0f,
|
y: Float = 0f,
|
||||||
width: Float = 40f,
|
width: Float = 40f,
|
||||||
height: Float = 20f,
|
height: Float = HEIGHT,
|
||||||
label: Component
|
label: Component
|
||||||
) : MinecraftWidgetPanel<Button>(screen, parent, x, y, width, height) {
|
) : MinecraftWidgetPanel<Button>(screen, parent, x, y, width, height) {
|
||||||
constructor(screen: MatteryScreen<*>, parent: EditablePanel?, label: Component) : this(screen, parent, x = 0f, label = label)
|
constructor(screen: MatteryScreen<*>, parent: EditablePanel?, label: Component) : this(screen, parent, x = 0f, label = label)
|
||||||
|
constructor(
|
||||||
|
screen: MatteryScreen<*>,
|
||||||
|
parent: EditablePanel?,
|
||||||
|
x: Float = 0f,
|
||||||
|
y: Float = 0f,
|
||||||
|
width: Float = 40f,
|
||||||
|
height: Float = HEIGHT,
|
||||||
|
label: Component,
|
||||||
|
onPress: Runnable
|
||||||
|
) : this(screen, parent, x, y, width, height, label) {
|
||||||
|
this.callback = onPress
|
||||||
|
}
|
||||||
|
|
||||||
var label = label
|
var label = label
|
||||||
set(value) {
|
set(value) {
|
||||||
@ -55,6 +65,10 @@ open class ButtonPanel(
|
|||||||
protected open fun onPress() {
|
protected open fun onPress() {
|
||||||
callback?.run()
|
callback?.run()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val HEIGHT = 20f
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("PropertyName")
|
@Suppress("PropertyName")
|
||||||
@ -105,7 +119,7 @@ abstract class SquareButtonPanel(
|
|||||||
override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean {
|
override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean {
|
||||||
if (!isDisabled) {
|
if (!isDisabled) {
|
||||||
if (!pressed) {
|
if (!pressed) {
|
||||||
minecraft.soundManager.play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0f))
|
playGuiClickSound()
|
||||||
}
|
}
|
||||||
|
|
||||||
pressed = true
|
pressed = true
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user