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 ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||
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.PatternStorageBlock
|
||||
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.has
|
||||
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.loot.addLootModifiers
|
||||
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.data.event.GatherDataEvent
|
||||
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.getValueNullable
|
||||
import ru.dbotthepony.mc.otm.datagen.toXRotBlockstate
|
||||
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?
|
||||
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 org.apache.logging.log4j.LogManager
|
||||
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) {
|
||||
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("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.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.")
|
||||
@ -128,6 +132,9 @@ private fun misc(provider: MatteryLanguageProvider) {
|
||||
misc("item.power.normal.storage", "Stored energy: %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.infinite.stored", "Stored patterns %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.PATTERN_DRIVE_NORMAL, "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
|
||||
))
|
||||
|
||||
it.add("end_city_pill", LootTableBasicAppender(
|
||||
it.add("end_city_modifications", LootTableBasicAppender(
|
||||
arrayOf(LootTableIdCondition.Builder(ResourceLocation("chests/end_city_treasure")).build()),
|
||||
ItemStack(MItems.PILL_ANDROID, 1) to 0.1,
|
||||
ItemStack(MItems.PILL_HUMANE, 1) to 0.3,
|
||||
ItemStack(MItems.PILL_OBLIVION, 1) to 0.5,
|
||||
ItemStack(MItems.ZPM_BATTERY, 1) to 0.005,
|
||||
))
|
||||
|
||||
it.add("shipwreck_supply_pill", LootTableBasicAppender(
|
||||
|
@ -9,7 +9,8 @@ import net.minecraft.core.Direction
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraftforge.client.model.generators.ModelBuilder
|
||||
import net.minecraftforge.common.data.ExistingFileHelper
|
||||
import ru.dbotthepony.mc.otm.set
|
||||
import ru.dbotthepony.mc.otm.container.set
|
||||
import ru.dbotthepony.mc.otm.core.set
|
||||
|
||||
data class TextureSize(val width: Float, val height: Float) {
|
||||
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.data.event.GatherDataEvent
|
||||
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
|
||||
|
||||
|
@ -4,8 +4,6 @@ import net.minecraft.data.recipes.FinishedRecipe
|
||||
import net.minecraft.data.recipes.ShapedRecipeBuilder
|
||||
import net.minecraft.data.recipes.ShapelessRecipeBuilder
|
||||
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.crafting.Ingredient
|
||||
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.MItems
|
||||
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
|
||||
|
||||
fun addCraftingTableRecipes(consumer: Consumer<FinishedRecipe>) {
|
||||
@ -55,6 +53,22 @@ fun addCraftingTableRecipes(consumer: Consumer<FinishedRecipe>) {
|
||||
.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)
|
||||
.rowB(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.level.ItemLike
|
||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||
import ru.dbotthepony.mc.otm.registryName
|
||||
import ru.dbotthepony.mc.otm.core.registryName
|
||||
import java.util.function.Consumer
|
||||
|
||||
private interface RecipeCell {
|
||||
|
@ -7,7 +7,8 @@ import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.world.item.crafting.RecipeSerializer
|
||||
import ru.dbotthepony.mc.otm.recipe.PlatePressRecipe
|
||||
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 {
|
||||
override fun serializeRecipeData(it: JsonObject) {
|
||||
|
@ -2,8 +2,10 @@ package ru.dbotthepony.mc.otm;
|
||||
|
||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.item.CreativeModeTab;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.eventbus.api.EventPriority;
|
||||
import net.minecraftforge.fml.ModList;
|
||||
@ -15,15 +17,15 @@ import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import ru.dbotthepony.mc.otm.block.entity.blackhole.ExplosionQueue;
|
||||
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.client.ClientEventHandler;
|
||||
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.TritaniumArmorModel;
|
||||
import ru.dbotthepony.mc.otm.compat.mekanism.QIOKt;
|
||||
import ru.dbotthepony.mc.otm.compat.mekanism.TooltipsKt;
|
||||
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.PortableCondensationDriveItem;
|
||||
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.worldgen.OreGen;
|
||||
|
||||
import static net.minecraftforge.common.MinecraftForge.EVENT_BUS;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
// The value here should match an entry in the META-INF/mods.toml file
|
||||
@ -76,49 +80,78 @@ public final class OverdriveThatMatters {
|
||||
|
||||
INSTANCE = this;
|
||||
|
||||
MRegistry.INSTANCE.initialize(FMLJavaModLoadingContext.get());
|
||||
var modBus = FMLJavaModLoadingContext.get().getModEventBus();
|
||||
|
||||
FMLJavaModLoadingContext.get().getModEventBus().addListener(EventPriority.HIGHEST, this::setup);
|
||||
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setupClient);
|
||||
MRegistry.INSTANCE.initialize(modBus);
|
||||
|
||||
MinecraftForge.EVENT_BUS.register(this);
|
||||
MinecraftForge.EVENT_BUS.register(GlobalEventHandlerKt.class);
|
||||
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);
|
||||
modBus.addListener(EventPriority.HIGHEST, this::setup);
|
||||
modBus.addListener(EventPriority.NORMAL, this::setupClient);
|
||||
}
|
||||
|
||||
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();
|
||||
MenuNetworkChannel.INSTANCE.register();
|
||||
WeaponNetworkChannel.INSTANCE.register();
|
||||
RegistryNetworkChannel.INSTANCE.register();
|
||||
WorldNetworkChannel.INSTANCE.register();
|
||||
GenericNetworkChannel.INSTANCE.register();
|
||||
|
||||
ITEM_STORAGE = StorageRegistry.register(ItemStackWrapper.class, ItemStackWrapper.EMPTY, new ImpreciseFraction("3.125"));
|
||||
|
||||
if (ModList.get().isLoaded("mekanism")) {
|
||||
MinecraftForge.EVENT_BUS.register(QIOKt.class);
|
||||
MinecraftForge.EVENT_BUS.register(TooltipsKt.class);
|
||||
EVENT_BUS.addGenericListener(BlockEntity.class, EventPriority.NORMAL, QIOKt::attachCapabilities);
|
||||
}
|
||||
|
||||
OreGen.INSTANCE.register();
|
||||
}
|
||||
|
||||
private void setupClient(final FMLClientSetupEvent event) {
|
||||
MinecraftForge.EVENT_BUS.register(MatteryGUI.INSTANCE);
|
||||
MinecraftForge.EVENT_BUS.register(EventHandlerKt.class);
|
||||
EVENT_BUS.addListener(EventPriority.NORMAL, MatterRegistryKt::tooltipEvent);
|
||||
|
||||
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);
|
||||
|
||||
|
@ -5,7 +5,7 @@ import net.minecraftforge.common.capabilities.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import ru.dbotthepony.mc.otm.capability.drive.IMatteryDrive;
|
||||
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.graph.matter.IMatterGraphNode;
|
||||
import ru.dbotthepony.mc.otm.graph.storage.IStorageGraphNode;
|
||||
@ -36,7 +36,7 @@ public class MatteryCapability {
|
||||
|
||||
@Nonnull
|
||||
@NotNull
|
||||
public static final Capability<IMatterTaskProvider> TASK = CapabilityManager.get(new CapabilityToken<>() {});
|
||||
public static final Capability<IReplicationTaskProvider> TASK = CapabilityManager.get(new CapabilityToken<>() {});
|
||||
|
||||
@Nonnull
|
||||
@NotNull
|
||||
@ -49,16 +49,4 @@ public class MatteryCapability {
|
||||
@Nonnull
|
||||
@NotNull
|
||||
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.RecipeSerializer;
|
||||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
import net.minecraftforge.registries.DeferredRegister;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
@ -35,8 +36,8 @@ public class MRecipes {
|
||||
typesRegistry.register(MNames.PLATE_PRESS, () -> PLATE_PRESS);
|
||||
}
|
||||
|
||||
public static void register() {
|
||||
registry.register(FMLJavaModLoadingContext.get().getModEventBus());
|
||||
typesRegistry.register(FMLJavaModLoadingContext.get().getModEventBus());
|
||||
public static void register(IEventBus bus) {
|
||||
registry.register(bus);
|
||||
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 _clientThread: Thread? = null
|
||||
|
||||
val isClient: Boolean get() = _clientThread !== null
|
||||
|
||||
fun recordClientThread() {
|
||||
if (_clientThread != null) {
|
||||
throw IllegalStateException("Already have client channel")
|
||||
@ -127,13 +129,13 @@ fun recordClientThread() {
|
||||
}
|
||||
|
||||
fun runIfClient(lambda: () -> Unit) {
|
||||
if (_clientThread !== null) {
|
||||
if (isClient) {
|
||||
lambda.invoke()
|
||||
}
|
||||
}
|
||||
|
||||
fun <V> runIfClient(value: V, lambda: () -> V): V {
|
||||
if (_clientThread !== null) {
|
||||
if (isClient) {
|
||||
return lambda.invoke()
|
||||
}
|
||||
|
||||
@ -178,7 +180,6 @@ interface IConditionalTickable : ITickable {
|
||||
val canTick: Boolean
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.LOWEST)
|
||||
fun onServerTick(event: ServerTickEvent) {
|
||||
if (event.phase === TickEvent.Phase.START) {
|
||||
preServerTickTimers.tick()
|
||||
@ -253,7 +254,6 @@ fun addPostServerTickerOnce(ticker: ITickable) {
|
||||
postServerTickOnce.add(ticker)
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.LOWEST)
|
||||
fun onWorldTick(event: LevelTickEvent) {
|
||||
if (event.phase === TickEvent.Phase.START) {
|
||||
val it = preWorldTick[event.level]
|
||||
@ -353,7 +353,6 @@ private fun clear() {
|
||||
postWorldTickOnce.clear()
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGHEST)
|
||||
fun onServerStarting(event: ServerAboutToStartEvent) {
|
||||
clear()
|
||||
SERVER_IS_DYING = false
|
||||
@ -361,13 +360,11 @@ fun onServerStarting(event: ServerAboutToStartEvent) {
|
||||
_serverThread = Thread.currentThread()
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGHEST)
|
||||
fun onServerStopping(event: ServerStoppingEvent) {
|
||||
clear()
|
||||
SERVER_IS_DYING = true
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGHEST)
|
||||
fun onServerStopped(event: ServerStoppedEvent) {
|
||||
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.")
|
||||
|
@ -4,9 +4,10 @@ import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraftforge.common.util.INBTSerializable
|
||||
import net.minecraftforge.event.entity.living.LivingHurtEvent
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
|
||||
import ru.dbotthepony.mc.otm.readNbt
|
||||
import ru.dbotthepony.mc.otm.set
|
||||
import ru.dbotthepony.mc.otm.writeNbt
|
||||
import ru.dbotthepony.mc.otm.core.readNbt
|
||||
import ru.dbotthepony.mc.otm.container.set
|
||||
import ru.dbotthepony.mc.otm.core.set
|
||||
import ru.dbotthepony.mc.otm.core.writeNbt
|
||||
import java.io.InputStream
|
||||
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.contents.TranslatableContents
|
||||
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
|
||||
|
||||
open class AndroidFeatureType<T : AndroidFeature> {
|
||||
|
@ -7,9 +7,10 @@ import net.minecraft.world.item.ItemStack
|
||||
import net.minecraftforge.common.util.INBTSerializable
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
|
||||
import ru.dbotthepony.mc.otm.client.render.SkinElement
|
||||
import ru.dbotthepony.mc.otm.readNbt
|
||||
import ru.dbotthepony.mc.otm.set
|
||||
import ru.dbotthepony.mc.otm.writeNbt
|
||||
import ru.dbotthepony.mc.otm.core.readNbt
|
||||
import ru.dbotthepony.mc.otm.container.set
|
||||
import ru.dbotthepony.mc.otm.core.set
|
||||
import ru.dbotthepony.mc.otm.core.writeNbt
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
|
||||
|
@ -6,9 +6,10 @@ import net.minecraft.ChatFormatting
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
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.container.iterator
|
||||
import ru.dbotthepony.mc.otm.core.nonEmpty
|
||||
import ru.dbotthepony.mc.otm.registry.MRegistry
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
@ -260,7 +261,7 @@ class AndroidResearchBuilder(
|
||||
|
||||
for (item in items) {
|
||||
var required = item.count
|
||||
val iterator = capability.ply.inventory.iterator()
|
||||
val iterator = capability.ply.inventory.iterator().nonEmpty()
|
||||
|
||||
for (invItem in iterator) {
|
||||
if (ItemStack.isSameItemSameTags(invItem, item)) {
|
||||
@ -335,7 +336,8 @@ class AndroidResearchBuilder(
|
||||
}
|
||||
|
||||
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)
|
||||
ChatFormatting.DARK_GREEN
|
||||
else
|
||||
@ -346,7 +348,8 @@ class AndroidResearchBuilder(
|
||||
for (value in this.type.flatPrerequisites) {
|
||||
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)
|
||||
ChatFormatting.DARK_GREEN
|
||||
else
|
||||
|
@ -6,9 +6,9 @@ import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.chat.ComponentContents
|
||||
import net.minecraft.network.chat.MutableComponent
|
||||
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.getKeyNullable
|
||||
import ru.dbotthepony.mc.otm.core.getKeyNullable
|
||||
import ru.dbotthepony.mc.otm.registry.MRegistry
|
||||
import java.util.*
|
||||
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.registry.AndroidFeatures
|
||||
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
|
||||
|
||||
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.registry.AndroidFeatures
|
||||
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
|
||||
|
||||
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 ru.dbotthepony.mc.otm.block.entity.AndroidStationBlockEntity
|
||||
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.shapes.BlockShapes
|
||||
|
||||
|
@ -15,7 +15,7 @@ import net.minecraft.world.phys.shapes.CollisionContext
|
||||
import net.minecraft.world.phys.shapes.VoxelShape
|
||||
import ru.dbotthepony.mc.otm.addPreWorldTickerOnce
|
||||
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.shapes.BlockShapes
|
||||
|
||||
|
@ -25,7 +25,7 @@ import net.minecraft.world.phys.shapes.VoxelShape
|
||||
import ru.dbotthepony.mc.otm.addPreWorldTickerOnce
|
||||
import ru.dbotthepony.mc.otm.block.entity.GravitationStabilizerBlockEntity
|
||||
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.times
|
||||
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.VoxelShape
|
||||
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.shapes.BlockShapes
|
||||
|
||||
|
@ -9,7 +9,7 @@ import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
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.WorkerEnergyStorage
|
||||
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.capability.*
|
||||
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.registry.MBlockEntities
|
||||
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.ForgeCapabilities
|
||||
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.container.MatteryContainer
|
||||
import ru.dbotthepony.mc.otm.ifHas
|
||||
import ru.dbotthepony.mc.otm.menu.CargoCrateMenu
|
||||
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(
|
||||
p_155229_: BlockPos,
|
||||
|
@ -19,11 +19,9 @@ import net.minecraftforge.common.util.LazyOptional
|
||||
import net.minecraftforge.energy.IEnergyStorage
|
||||
import ru.dbotthepony.mc.otm.*
|
||||
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.container.MatteryContainer
|
||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||
import ru.dbotthepony.mc.otm.core.plus
|
||||
import ru.dbotthepony.mc.otm.core.*
|
||||
import ru.dbotthepony.mc.otm.menu.ChemicalGeneratorMenu
|
||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||
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.capability.*
|
||||
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.network.MatteryPacket
|
||||
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.state.BlockState
|
||||
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.BlockGravitationStabilizerLens
|
||||
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
|
||||
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.times
|
||||
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.minecraftforge.common.capabilities.Capability
|
||||
import ru.dbotthepony.mc.otm.addPreWorldTickerOnce
|
||||
import ru.dbotthepony.mc.otm.ifHas
|
||||
import ru.dbotthepony.mc.otm.set
|
||||
import ru.dbotthepony.mc.otm.core.ifHas
|
||||
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 {
|
||||
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.ForgeCapabilities
|
||||
import net.minecraftforge.common.util.LazyOptional
|
||||
import net.minecraftforge.energy.CapabilityEnergy
|
||||
import ru.dbotthepony.mc.otm.capability.*
|
||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||
import ru.dbotthepony.mc.otm.ifHas
|
||||
import ru.dbotthepony.mc.otm.ifPresentK
|
||||
import ru.dbotthepony.mc.otm.set
|
||||
import ru.dbotthepony.mc.otm.core.ifHas
|
||||
import ru.dbotthepony.mc.otm.core.ifPresentK
|
||||
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 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
|
||||
|
||||
import com.google.common.collect.Streams
|
||||
import javax.annotation.ParametersAreNonnullByDefault
|
||||
import net.minecraft.core.BlockPos
|
||||
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 net.minecraft.nbt.CompoundTag
|
||||
import net.minecraftforge.common.util.LazyOptional
|
||||
import net.minecraftforge.items.CapabilityItemHandler
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
import net.minecraft.world.entity.player.Player
|
||||
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.block.Block
|
||||
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.container.forEachCapability
|
||||
import ru.dbotthepony.mc.otm.core.iterator
|
||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
||||
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.set
|
||||
import ru.dbotthepony.mc.otm.core.set
|
||||
import java.util.ArrayList
|
||||
import java.util.stream.Stream
|
||||
|
||||
@MethodsReturnNonnullByDefault
|
||||
@ParametersAreNonnullByDefault
|
||||
@ -48,13 +52,13 @@ class PatternStorageBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||
if (grid != null && !ItemStack.isSameItemSameTags(new, old)) {
|
||||
if (!old.isEmpty) {
|
||||
old.getCapability(MatteryCapability.PATTERN).ifPresent { cap: IPatternStorage ->
|
||||
cap.storedPatterns.forEach { state: PatternState? -> grid.onPatternRemoved(state!!) }
|
||||
cap.storedPatterns.forEach { grid.onPatternRemoved(it) }
|
||||
}
|
||||
}
|
||||
|
||||
if (!new.isEmpty) {
|
||||
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> {
|
||||
if (valid) {
|
||||
if (cap === MatteryCapability.PATTERN) return resolverPatterns.cast()
|
||||
if (cap === MatteryCapability.MATTER_NODE) return resolverNode.cast()
|
||||
if (cap === CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return resolverItem.get().cast()
|
||||
if (cap == MatteryCapability.PATTERN) return resolverPatterns.cast()
|
||||
if (cap == MatteryCapability.MATTER_NODE) return resolverNode.cast()
|
||||
if (cap == ForgeCapabilities.ITEM_HANDLER) return resolverItem.get().cast()
|
||||
}
|
||||
|
||||
return super.getCapability(cap, side)
|
||||
@ -145,16 +149,20 @@ class PatternStorageBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||
return PatternStorageMenu(containerID, inventory, this)
|
||||
}
|
||||
|
||||
override val storedPatterns: Collection<PatternState> get() {
|
||||
val list = ArrayList<PatternState>()
|
||||
patterns.consumeCapability(MatteryCapability.PATTERN) { capability: IPatternStorage -> list.addAll(capability.storedPatterns) }
|
||||
return list
|
||||
override val storedPatterns: Stream<out IPatternState> get() {
|
||||
val streams = ArrayList<Stream<out IPatternState>>()
|
||||
|
||||
for (provider in patterns.iterator(MatteryCapability.PATTERN)) {
|
||||
streams.add(provider.second.storedPatterns)
|
||||
}
|
||||
|
||||
return Streams.concat(*streams.toTypedArray())
|
||||
}
|
||||
|
||||
override val capacity: Int get() {
|
||||
var stored = 0L
|
||||
|
||||
for (pattern in patterns.capabilityIterator(MatteryCapability.PATTERN))
|
||||
for ((_, pattern) in patterns.iterator(MatteryCapability.PATTERN))
|
||||
stored += pattern.capacity.toLong()
|
||||
|
||||
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() {
|
||||
var stored = 0L
|
||||
|
||||
for (pattern in patterns.capabilityIterator(MatteryCapability.PATTERN))
|
||||
for ((_, pattern) in patterns.iterator(MatteryCapability.PATTERN))
|
||||
stored += pattern.stored.toLong()
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
override fun insertPattern(pattern: PatternState, only_update: Boolean, simulate: Boolean): PatternInsertStatus {
|
||||
for (storage in patterns.capabilityIterator(MatteryCapability.PATTERN)) {
|
||||
val status = storage.insertPattern(pattern, only_update, simulate)
|
||||
override fun insertPattern(pattern: IPatternState, onlyUpdate: Boolean, simulate: Boolean): PatternInsertStatus {
|
||||
for (pair in patterns.iterator(MatteryCapability.PATTERN)) {
|
||||
val status = pair.second.insertPattern(pattern, onlyUpdate, simulate)
|
||||
|
||||
if (!status.isFailed) {
|
||||
if (!simulate) {
|
||||
|
@ -10,12 +10,9 @@ import net.minecraft.world.inventory.AbstractContainerMenu
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraftforge.common.capabilities.Capability
|
||||
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
||||
import net.minecraftforge.common.util.LazyOptional
|
||||
import net.minecraftforge.items.CapabilityItemHandler
|
||||
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.core.TranslatableComponent
|
||||
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
|
||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||
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.registry.MBlockEntities
|
||||
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)
|
||||
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> {
|
||||
if (cap === CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
|
||||
if (cap == ForgeCapabilities.ITEM_HANDLER)
|
||||
return itemHandler.get().cast()
|
||||
|
||||
return super.getCapability(cap, side)
|
||||
@ -73,32 +74,24 @@ class PlatePressBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matter
|
||||
return PlatePressMenu(containerID, inventory, this)
|
||||
}
|
||||
|
||||
override fun onJobFinish(job: WorkerJob): WorkerJobStatus {
|
||||
val resultTag = job.data["result"] as? CompoundTag ?: return WorkerJobStatus()
|
||||
val result = ItemStack.of(resultTag)
|
||||
override fun onJobFinish(job: ItemJob): Status {
|
||||
if (job.itemStack.isEmpty)
|
||||
return Status.SUCCESS
|
||||
|
||||
if (result.isEmpty)
|
||||
return WorkerJobStatus()
|
||||
if (!container.fullyAddItem(job.itemStack, start = SLOT_OUTPUT, end = SLOT_OUTPUT))
|
||||
return Status.FAILURE_ITEM
|
||||
|
||||
if (!container.fullyAddItem(result, start = SLOT_OUTPUT, end = SLOT_OUTPUT)) {
|
||||
return WorkerJobStatus(false, 20)
|
||||
}
|
||||
|
||||
return WorkerJobStatus()
|
||||
return Status.SUCCESS
|
||||
}
|
||||
|
||||
override fun computeNextJob(): WorkerJob? {
|
||||
val level = level ?: return null
|
||||
val recipe = level.recipeManager.getRecipeFor(MRecipes.PLATE_PRESS, container, level).orElse(null) ?: return null
|
||||
override fun computeNextJob(): Pair<ItemJob?, IdleReason?> {
|
||||
if (energy.batteryLevel.isZero) {
|
||||
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.setChanged(SLOT_INPUT)
|
||||
copy.count = 1
|
||||
|
||||
return WorkerJob(copy, recipe.workTime.toDouble(), BASELINE_CONSUMPTION, CompoundTag().also {
|
||||
it["result"] = recipe.resultItem.serializeNBT()
|
||||
})
|
||||
return ItemJob(recipe.resultItem, recipe.workTime.toDouble(), BASELINE_CONSUMPTION) to null
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
@ -1,7 +1,7 @@
|
||||
package ru.dbotthepony.mc.otm.block.entity
|
||||
|
||||
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) {
|
||||
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.MItems
|
||||
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.sqrt
|
||||
|
||||
|
@ -23,7 +23,6 @@ import ru.dbotthepony.mc.otm.block.BlockExplosionDebugger
|
||||
import ru.dbotthepony.mc.otm.core.*
|
||||
import ru.dbotthepony.mc.otm.core.Vector
|
||||
import ru.dbotthepony.mc.otm.registry.MRegistry
|
||||
import ru.dbotthepony.mc.otm.set
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
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.util.LazyOptional
|
||||
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.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.WorkerEnergyStorage
|
||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler
|
||||
import ru.dbotthepony.mc.otm.capability.matter.MatterDirection
|
||||
import ru.dbotthepony.mc.otm.capability.matter.MatterHandlerImpl
|
||||
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.matter.IMatterGraphNode
|
||||
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.orNull
|
||||
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) :
|
||||
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.minecraftforge.common.capabilities.Capability
|
||||
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.entity.MatteryBlockEntity
|
||||
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.menu.MatterCapacitorBankMenu
|
||||
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
|
||||
|
||||
@MethodsReturnNonnullByDefault
|
||||
|
@ -12,24 +12,22 @@ import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraftforge.common.capabilities.Capability
|
||||
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
||||
import net.minecraftforge.common.util.LazyOptional
|
||||
import net.minecraftforge.items.CapabilityItemHandler
|
||||
import net.minecraftforge.items.IItemHandler
|
||||
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.MatteryWorkerBlockEntity
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
|
||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler
|
||||
import ru.dbotthepony.mc.otm.capability.matter.MatterDirection
|
||||
import ru.dbotthepony.mc.otm.capability.matter.MatterHandlerImpl
|
||||
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.matter.IMatterGraphNode
|
||||
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.matter.baselineComplexityDecomposeTicks
|
||||
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.registry.MBlockEntities
|
||||
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 {
|
||||
var matterValue = _matterValue
|
||||
@ -93,7 +90,29 @@ fun moveMatterAsDustIntoContainer(_matterValue: ImpreciseFraction, container: Ma
|
||||
}
|
||||
|
||||
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)
|
||||
private var valid = true
|
||||
@ -110,13 +129,18 @@ class MatterDecomposerBlockEntity(pos: BlockPos, state: BlockState)
|
||||
private var resolverNode = LazyOptional.of { this }
|
||||
|
||||
// вход, выход
|
||||
@JvmField
|
||||
val container = MatteryContainer(this::setChangedLight, 3)
|
||||
|
||||
private val itemHandler = LazyOptional.of<IItemHandler> {
|
||||
container.handler(
|
||||
{ slot: Int, stack: ItemStack -> slot == INPUT_SLOT && canDecompose(stack) },
|
||||
{ slot: Int, _: Int, _: ItemStack -> slot != INPUT_SLOT })
|
||||
container.handler(object : MatteryContainerFilter {
|
||||
override fun canInsert(slot: Int, stack: ItemStack): Boolean {
|
||||
return slot == INPUT_SLOT && canDecompose(stack)
|
||||
}
|
||||
|
||||
override fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean {
|
||||
return slot != INPUT_SLOT
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
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> {
|
||||
if (valid) {
|
||||
if (cap === MatteryCapability.MATTER) return resolverMatter.cast()
|
||||
if (cap === MatteryCapability.MATTER_NODE) return resolverNode.cast()
|
||||
if (cap === CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return itemHandler.cast()
|
||||
if (cap == MatteryCapability.MATTER) return resolverMatter.cast()
|
||||
if (cap == MatteryCapability.MATTER_NODE) return resolverNode.cast()
|
||||
if (cap == ForgeCapabilities.ITEM_HANDLER) return itemHandler.cast()
|
||||
}
|
||||
|
||||
return super.getCapability(cap, side)
|
||||
}
|
||||
|
||||
override fun onJobFinish(job: WorkerJob): WorkerJobStatus {
|
||||
var matterValue = ImpreciseFraction.deserializeNBT(job.data["value"])
|
||||
override fun onJobFinish(job: DecomposerJob): Status {
|
||||
if (job.toDust) {
|
||||
job.matterValue = moveMatterAsDustIntoContainer(job.matterValue, container, OUTPUT_DUST_MAIN, OUTPUT_DUST_STACKING)
|
||||
|
||||
if (job.data.getBoolean("to_dust")) {
|
||||
matterValue = moveMatterAsDustIntoContainer(matterValue, container, OUTPUT_DUST_MAIN, OUTPUT_DUST_STACKING)
|
||||
|
||||
if (!matterValue.isZero) {
|
||||
job.data["value"] = matterValue.serializeNBT()
|
||||
return WorkerJobStatus(20)
|
||||
if (!job.matterValue.isZero) {
|
||||
return Status.FAILURE_WAIT_FAST
|
||||
}
|
||||
|
||||
return WorkerJobStatus()
|
||||
return Status.SUCCESS
|
||||
}
|
||||
|
||||
matterValue -= matter.receiveMatterInner(matterValue, false)
|
||||
job.matterValue -= matter.receiveMatterInner(job.matterValue, false)
|
||||
|
||||
if (matterValue.isPositive) {
|
||||
job.data["value"] = matterValue.serializeNBT()
|
||||
return WorkerJobStatus(false, 20)
|
||||
if (job.matterValue.isPositive) {
|
||||
return Status.FAILURE_MATTER
|
||||
}
|
||||
|
||||
return WorkerJobStatus()
|
||||
return Status.SUCCESS
|
||||
}
|
||||
|
||||
override fun computeNextJob(): WorkerJob? {
|
||||
override fun computeNextJob(): Pair<DecomposerJob?, IdleReason?> {
|
||||
val stack = container[INPUT_SLOT]
|
||||
|
||||
if (!stack.isEmpty) {
|
||||
@ -197,19 +217,13 @@ class MatterDecomposerBlockEntity(pos: BlockPos, state: BlockState)
|
||||
|
||||
if (canDecompose(copy)) {
|
||||
val matter = getMatterValue(copy)
|
||||
stack.count--
|
||||
|
||||
if (!matter.isZero) {
|
||||
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 DecomposerJob((level?.random?.nextDouble() ?: 1.0) <= 0.2, matter.value, matter.complexity * baselineComplexityDecomposeTicks) to null
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
return null to IdleReason.ITEM
|
||||
}
|
||||
|
||||
override fun setRemoved() {
|
||||
|
@ -3,7 +3,6 @@ package ru.dbotthepony.mc.otm.block.entity.matter
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.Direction
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterTaskProvider
|
||||
import ru.dbotthepony.mc.otm.menu.MatterPanelMenu
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
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 java.util.HashMap
|
||||
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.ListTag
|
||||
import net.minecraft.nbt.Tag
|
||||
@ -23,17 +18,18 @@ import net.minecraft.network.chat.Component
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.world.level.Level
|
||||
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.capability.matter.*
|
||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
||||
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||
import java.util.ArrayList
|
||||
import java.util.List
|
||||
import java.util.stream.Stream
|
||||
|
||||
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>()
|
||||
override val matterNode = Graph6Node<IMatterGraphNode>(this)
|
||||
@ -88,61 +84,59 @@ class MatterPanelBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||
matterNode.destroy(::MatterNetworkGraph)
|
||||
}
|
||||
|
||||
override fun getTaskHandler(): IMatterTaskProvider? {
|
||||
override fun getTaskHandler(): IReplicationTaskProvider {
|
||||
return this
|
||||
}
|
||||
|
||||
private val _tasks = HashMap<UUID, MatterTask>()
|
||||
private val _tasks = HashMap<UUID, ReplicationTask>()
|
||||
|
||||
override val tasks: Collection<MatterTask> get() {
|
||||
return _tasks.values.stream().filter { task: MatterTask? -> task!!.required() > 0 }.collect(Collectors.toList()) as Collection<MatterTask>
|
||||
override val replicationTasks: Stream<ReplicationTask> get() {
|
||||
return _tasks.values.stream().filter { it.required > 0 }
|
||||
}
|
||||
|
||||
override val allTasks: Collection<MatterTask> get() {
|
||||
return List.copyOf(_tasks.values) as Collection<MatterTask>
|
||||
override val allReplicationTasks: Stream<ReplicationTask> get() {
|
||||
return _tasks.values.stream()
|
||||
}
|
||||
|
||||
override fun allocateTask(simulate: Boolean): MatterTaskAllocation? {
|
||||
override fun allocateTask(simulate: Boolean): ReplicationTaskAllocation? {
|
||||
val graph = matterNode.graph as MatterNetworkGraph? ?: return null
|
||||
|
||||
for ((key, task) in _tasks) {
|
||||
if (task.required > 0) {
|
||||
val getPattern = graph.getPattern(task.pattern!!)
|
||||
val pattern = task.patternId?.let(graph::getPattern) ?: continue
|
||||
|
||||
if (getPattern != null) {
|
||||
if (!simulate) {
|
||||
val new = task.shrinkRequired(1)
|
||||
_tasks[key] = new
|
||||
listeners.forEach { menu: MatterPanelMenu -> menu.taskUpdated(new) }
|
||||
graph.onMatterTaskUpdated(new, task)
|
||||
setChanged()
|
||||
}
|
||||
|
||||
return MatterTaskAllocation(task, getPattern)
|
||||
if (!simulate) {
|
||||
val new = task.allocate()
|
||||
_tasks[key] = new
|
||||
listeners.forEach { it.taskUpdated(new) }
|
||||
graph.onMatterTaskUpdated(new, task)
|
||||
setChanged()
|
||||
}
|
||||
|
||||
return ReplicationTaskAllocation(task, pattern)
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
override fun notifyTaskCompletion(task: MatterTask): Boolean {
|
||||
var localTask = _tasks[task.id] ?: return false
|
||||
override fun notifyTaskCompletion(taskId: UUID): Boolean {
|
||||
var localTask = _tasks[taskId] ?: return false
|
||||
val oldTask = localTask
|
||||
|
||||
localTask = localTask.shrinkInProgress(1)
|
||||
localTask = localTask.finish()
|
||||
val graph = matterNode.graph as MatterNetworkGraph?
|
||||
|
||||
// Задача полностью выполнена
|
||||
if (localTask.required <= 0 && localTask.in_progress <= 0) {
|
||||
_tasks.remove(task.id)
|
||||
graph?.onMatterTaskCreated(task)
|
||||
listeners.forEach { menu: MatterPanelMenu -> menu.taskRemoved(localTask) }
|
||||
if (localTask.required <= 0 && localTask.inProgress <= 0) {
|
||||
_tasks.remove(taskId)
|
||||
graph?.onMatterTaskFinished(localTask)
|
||||
listeners.forEach { it.taskRemoved(localTask) }
|
||||
} else {
|
||||
// Задача обновлена
|
||||
_tasks[task.id()] = localTask
|
||||
_tasks[taskId] = localTask
|
||||
graph?.onMatterTaskUpdated(localTask, oldTask)
|
||||
listeners.forEach { menu: MatterPanelMenu -> menu.taskUpdated(localTask) }
|
||||
listeners.forEach { it.taskUpdated(localTask) }
|
||||
}
|
||||
|
||||
setChanged()
|
||||
@ -155,7 +149,7 @@ class MatterPanelBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||
val list = ListTag()
|
||||
|
||||
for (task in _tasks.values) {
|
||||
list.add(task!!.serializeNBT())
|
||||
list.add(task.serializeNBT())
|
||||
}
|
||||
|
||||
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())
|
||||
|
||||
for (tag in list) {
|
||||
val task = MatterTask.deserializeNBT(tag)
|
||||
val task = ReplicationTask.deserializeNBT(tag)
|
||||
|
||||
if (task != null) {
|
||||
_tasks[task.id()] = task
|
||||
_tasks[task.id] = task
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getTask(id: UUID): MatterTask? {
|
||||
return _tasks[id]
|
||||
override fun getTask(id: UUID): ReplicationTask? {
|
||||
return _tasks[id]?.asImmutable()
|
||||
}
|
||||
|
||||
fun removeTask(id: UUID) {
|
||||
@ -185,19 +179,17 @@ class MatterPanelBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||
|
||||
(matterNode.graph as MatterNetworkGraph?)?.onMatterTaskRemoved(task)
|
||||
|
||||
listeners.forEach { menu: MatterPanelMenu -> menu.taskRemoved(task) }
|
||||
listeners.forEach { it.taskRemoved(task) }
|
||||
setChanged()
|
||||
}
|
||||
|
||||
fun removeTask(state: PatternState) = removeTask(state.id)
|
||||
|
||||
fun addTask(state: PatternState, how_much: Int): MatterTask {
|
||||
val task = MatterTask(UUID.randomUUID(), state.id, state.item, 0, 0, how_much)
|
||||
_tasks[task.id()] = task
|
||||
fun addTask(state: IPatternState, count: Int): IReplicationTask<*> {
|
||||
val task = ReplicationTask(UUID.randomUUID(), state.id, state.item, 0, 0, count)
|
||||
_tasks[task.id] = task
|
||||
|
||||
(matterNode.graph as MatterNetworkGraph?)?.onMatterTaskCreated(task)
|
||||
|
||||
listeners.forEach { menu: MatterPanelMenu -> menu.taskUpdated(task) }
|
||||
listeners.forEach { it.taskUpdated(task) }
|
||||
setChanged()
|
||||
|
||||
return task
|
||||
|
@ -12,13 +12,10 @@ import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraftforge.common.capabilities.Capability
|
||||
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
||||
import net.minecraftforge.common.util.LazyOptional
|
||||
import net.minecraftforge.items.CapabilityItemHandler
|
||||
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.core.TranslatableComponent
|
||||
import ru.dbotthepony.mc.otm.block.entity.MatteryWorkerBlockEntity
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
|
||||
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.matter.IMatterGraphNode
|
||||
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.core.map
|
||||
import ru.dbotthepony.mc.otm.menu.MatterRecyclerMenu
|
||||
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)
|
||||
: MatteryWorkerBlockEntity(MBlockEntities.MATTER_RECYCLER, blockPos, blockState), IMatterGraphNode {
|
||||
: MatteryWorkerBlockEntity<MatteryWorkerBlockEntity.Job>(MBlockEntities.MATTER_RECYCLER, blockPos, blockState, ::Job), IMatterGraphNode {
|
||||
|
||||
val matter = MatterHandlerImpl(
|
||||
this::setChangedLight,
|
||||
this::matterLevelUpdated,
|
||||
MatterDirection.EXTRACT,
|
||||
STORAGE
|
||||
)
|
||||
|
||||
val container = MatteryContainer(this::setChangedLight, 1)
|
||||
val container = MatteryContainer(this::itemContainerUpdated, 1)
|
||||
override val matterNode = Graph6Node<IMatterGraphNode>(this)
|
||||
private var resolverNode = LazyOptional.of { this }
|
||||
private var valid = true
|
||||
override val energy = WorkerEnergyStorage(this, MAX_POWER)
|
||||
override val energy = WorkerEnergyStorage(this::powerLevelUpdated, MAX_POWER)
|
||||
|
||||
override fun getMatterHandler(): IMatterHandler {
|
||||
return matter
|
||||
@ -99,7 +97,7 @@ class MatterRecyclerBlockEntity(blockPos: BlockPos, blockState: BlockState)
|
||||
|
||||
override fun load(nbt: CompoundTag) {
|
||||
super.load(nbt)
|
||||
nbt.ifHas("matter", CompoundTag::class.java, matter::deserializeNBT)
|
||||
nbt.map("matter", matter::deserializeNBT)
|
||||
container.deserializeNBT(nbt["container"])
|
||||
}
|
||||
|
||||
@ -107,15 +105,12 @@ class MatterRecyclerBlockEntity(blockPos: BlockPos, blockState: BlockState)
|
||||
if (!valid)
|
||||
return super.getCapability(cap, side)
|
||||
|
||||
if (cap === CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
|
||||
return itemHandler.get().cast()
|
||||
} else if (cap === MatteryCapability.MATTER) {
|
||||
return matter.get().cast()
|
||||
} else if (cap === MatteryCapability.MATTER_NODE) {
|
||||
return resolverNode.cast()
|
||||
return when (cap) {
|
||||
ForgeCapabilities.ITEM_HANDLER -> itemHandler.get().cast()
|
||||
MatteryCapability.MATTER -> matter.get().cast()
|
||||
MatteryCapability.MATTER_NODE -> resolverNode.cast()
|
||||
else -> super.getCapability(cap, side)
|
||||
}
|
||||
|
||||
return super.getCapability(cap, side)
|
||||
}
|
||||
|
||||
override val defaultDisplayName: Component
|
||||
@ -125,41 +120,39 @@ class MatterRecyclerBlockEntity(blockPos: BlockPos, blockState: BlockState)
|
||||
return MatterRecyclerMenu(containerID, inventory, this)
|
||||
}
|
||||
|
||||
override fun onJobFinish(job: WorkerJob): WorkerJobStatus {
|
||||
override fun onJobFinish(job: Job): Status {
|
||||
// вся логика в onWorkTick
|
||||
return WorkerJobStatus()
|
||||
return Status.SUCCESS
|
||||
}
|
||||
|
||||
override fun computeNextJob(): WorkerJob? {
|
||||
override fun computeNextJob(): Pair<Job?, IdleReason?> {
|
||||
if (matter.missingMatter.isZero)
|
||||
return null
|
||||
return null to IdleReason.ITEM
|
||||
|
||||
val stack = container[0]
|
||||
|
||||
if (stack.isEmpty || stack.item !is MatterDustItem) {
|
||||
return null
|
||||
return null to IdleReason.ITEM
|
||||
}
|
||||
|
||||
val copy = stack.copy()
|
||||
copy.count = 1
|
||||
|
||||
val dustMatter = (stack.item as MatterDustItem).getMatterValue(copy) ?: return null
|
||||
val dustMatter = (stack.item as MatterDustItem).getMatterValue(stack.copy().also { it.count = 1 }) ?: return null to IdleReason.ITEM
|
||||
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)
|
||||
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)
|
||||
|
||||
if (receive != received)
|
||||
return WorkerJobStatus(false, 20)
|
||||
return Status.FAILURE_MATTER
|
||||
|
||||
matter.receiveMatterInner(receive, false)
|
||||
return WorkerJobStatus()
|
||||
return Status.SUCCESS
|
||||
}
|
||||
|
||||
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.Player
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraftforge.common.capabilities.Capability
|
||||
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
||||
import net.minecraftforge.common.util.LazyOptional
|
||||
import net.minecraftforge.items.CapabilityItemHandler
|
||||
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.block.entity.MatteryWorkerBlockEntity
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
|
||||
import ru.dbotthepony.mc.otm.capability.matter.*
|
||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||
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.matter.IMatterGraphNode
|
||||
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.getMatterValue
|
||||
import ru.dbotthepony.mc.otm.menu.MatterReplicatorMenu
|
||||
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) :
|
||||
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)
|
||||
private val resolverNode = LazyOptional.of { this }
|
||||
|
||||
@JvmField
|
||||
val matter = MatterHandlerImpl(
|
||||
this::setChangedLight,
|
||||
this::matterLevelUpdated,
|
||||
MatterDirection.RECEIVE,
|
||||
ImpreciseFraction(2)
|
||||
)
|
||||
|
||||
// обычные запросы
|
||||
@JvmField
|
||||
val container = MatteryContainer(this::setChangedLight, 5)
|
||||
val container = MatteryContainer(this::itemContainerUpdated, 5)
|
||||
private val itemHandler = container.handler(MatteryContainerFilterOnlyOut)
|
||||
|
||||
override val defaultDisplayName: Component
|
||||
@ -60,38 +104,42 @@ class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||
return MatterReplicatorMenu(containerID, inventory, this)
|
||||
}
|
||||
|
||||
override fun onJobFinish(job: WorkerJob): WorkerJobStatus {
|
||||
if (job.data.getBoolean("as_dust")) {
|
||||
val matterValue = moveMatterAsDustIntoContainer(ImpreciseFraction.deserializeNBT(job["matter"]), container, OUTPUT_DUST_MAIN, OUTPUT_DUST_STACKING)
|
||||
override fun onJobFinish(job: ReplicatorJob): Status {
|
||||
if (job.asDust) {
|
||||
job.matterValue = moveMatterAsDustIntoContainer(job.matterValue, container, OUTPUT_DUST_MAIN, OUTPUT_DUST_STACKING)
|
||||
|
||||
if (!matterValue.isZero) {
|
||||
job["matter"] = matterValue.serializeNBT()
|
||||
return WorkerJobStatus(false, 20)
|
||||
if (!job.matterValue.isZero) {
|
||||
return Status.FAILURE_WAIT
|
||||
}
|
||||
|
||||
(matterNode.graph as MatterNetworkGraph?)?.notifyTaskCompletion(MatterTask.deserializeNBT(job["task"])!!)
|
||||
|
||||
return WorkerJobStatus()
|
||||
(matterNode.graph as MatterNetworkGraph?)?.notifyTaskCompletion(job.task.id)
|
||||
return Status.SUCCESS
|
||||
}
|
||||
|
||||
if (!container.fullyAddItem(job.stack, FIRST_ACTUAL_OUTPUT_SLOT .. LAST_ACTUAL_OUTPUT_SLOT)) {
|
||||
return WorkerJobStatus(false, 20)
|
||||
if (!container.fullyAddItem(job.itemStack, FIRST_ACTUAL_OUTPUT_SLOT .. LAST_ACTUAL_OUTPUT_SLOT)) {
|
||||
return Status.FAILURE_ITEM
|
||||
}
|
||||
|
||||
(matterNode.graph as MatterNetworkGraph?)?.notifyTaskCompletion(MatterTask.deserializeNBT(job["task"])!!)
|
||||
return WorkerJobStatus()
|
||||
(matterNode.graph as MatterNetworkGraph?)?.notifyTaskCompletion(job.task.id)
|
||||
return Status.SUCCESS
|
||||
}
|
||||
|
||||
override fun onMatterTaskCreated(task: MatterTask) {
|
||||
isIdling = false
|
||||
override fun onMatterTaskCreated(task: IReplicationTask<*>) {
|
||||
if (idleReason == IdleReason.OBSERVING) {
|
||||
isIdling = false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMatterTaskUpdated(new_state: MatterTask, old_state: MatterTask) {
|
||||
isIdling = false
|
||||
override fun <T : IReplicationTask<*>> onMatterTaskUpdated(newState: T, oldState: T) {
|
||||
if (idleReason == IdleReason.OBSERVING) {
|
||||
isIdling = false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPatternAdded(state: PatternState) {
|
||||
isIdling = false
|
||||
override fun onPatternAdded(state: IPatternState) {
|
||||
if (idleReason == IdleReason.OBSERVING) {
|
||||
isIdling = false
|
||||
}
|
||||
}
|
||||
|
||||
override fun setRemoved() {
|
||||
@ -106,33 +154,35 @@ class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||
MatterNetworkGraph.discoverFull(this, matterNode)
|
||||
}
|
||||
|
||||
override fun computeNextJob(): WorkerJob? {
|
||||
val graph = matterNode.graph as MatterNetworkGraph? ?: return null
|
||||
val allocation = graph.allocateTask(false) ?: return null
|
||||
override fun computeNextJob(): Pair<ReplicatorJob?, IdleReason?> {
|
||||
if (energy.batteryLevel < BASE_CONSUMPTION) {
|
||||
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 matter = getMatterValue(stack)
|
||||
|
||||
// ????????
|
||||
if (matter.isZero) return null
|
||||
if (matter.isZero) return null to null
|
||||
|
||||
val ticks = matter.complexity * baselineComplexityReplicateTicks
|
||||
|
||||
return WorkerJob(stack, ticks, BASE_CONSUMPTION, CompoundTag().also {
|
||||
it["matter_per_tick"] = (matter.value / ticks).serializeNBT()
|
||||
it["task"] = allocation.task.serializeNBT()
|
||||
it["matter"] = matter.value.serializeNBT()
|
||||
|
||||
if (allocation.pattern != null)
|
||||
it["pattern"] = allocation.pattern.serializeNBT()
|
||||
|
||||
if ((level?.random?.nextDouble() ?: 1.0) > (allocation.pattern?.research ?: 2.0))
|
||||
it["as_dust"] = true
|
||||
})
|
||||
return ReplicatorJob(
|
||||
itemStack = stack,
|
||||
matterPerTick = matter.value / ticks,
|
||||
task = allocation.task.asImmutable(),
|
||||
matterValue = matter.value,
|
||||
pattern = allocation.pattern?.asImmutable(),
|
||||
asDust = (level?.random?.nextDouble() ?: 1.0) > (allocation.pattern?.researchPercent ?: 2.0),
|
||||
ticks = ticks,
|
||||
) to null
|
||||
}
|
||||
|
||||
override fun onWorkTick(context: WorkerTickContext): WorkerJobStatus {
|
||||
val drainPerTick = ImpreciseFraction.deserializeNBT(context.job.data["matter_per_tick"])
|
||||
val graph = matterNode.graph as MatterNetworkGraph? ?: return WorkerJobStatus(false, 20)
|
||||
override fun onWorkTick(requiredPower: ImpreciseFraction, extractedPower: ImpreciseFraction, ticksAdvanced: Double): Status {
|
||||
val drainPerTick = currentJob!!.matterPerTick * ticksAdvanced
|
||||
val graph = matterNode.graph as MatterNetworkGraph? ?: return Status.FAILURE_WAIT_FAST
|
||||
|
||||
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 drain = graph.extractMatter(toExtract, true)
|
||||
|
||||
if (drain < toExtract) {
|
||||
if (drain != toExtract) {
|
||||
// недостаточно материи в сети
|
||||
return WorkerJobStatus(false, 200)
|
||||
return Status.FAILURE_MATTER
|
||||
}
|
||||
|
||||
// достаточно материи в сети + внутри машины
|
||||
matter.extractMatterInner(drainPerTick, false)
|
||||
graph.extractMatter(drain, false)
|
||||
return WorkerJobStatus()
|
||||
return Status.SUCCESS
|
||||
} else {
|
||||
// в тик требуется меньше материи, чем её может хранить репликатор
|
||||
// примем из сети недостающее количество бака материи, или 200 тиков репликации, что меньше
|
||||
val toExtract =
|
||||
matter.missingMatter.coerceAtMost(drainPerTick.times(DRAIN_MULT))
|
||||
|
||||
val drain = graph.extractMatter(toExtract, true)
|
||||
val drain = graph.extractMatter(matter.missingMatter.coerceAtMost(drainPerTick * DRAIN_MULT), true)
|
||||
|
||||
if (drain.isZero) {
|
||||
// в сети нет материи
|
||||
return WorkerJobStatus(false, 200)
|
||||
return Status.FAILURE_MATTER
|
||||
}
|
||||
|
||||
val received = matter.receiveMatterOuter(drain, false)
|
||||
graph.extractMatter(received, false)
|
||||
|
||||
// получили материю, проверяем возможность работы
|
||||
if (matter.extractMatterInner(drainPerTick, false) >= drainPerTick) {
|
||||
return WorkerJobStatus()
|
||||
if (matter.extractMatterInner(drainPerTick, true) >= drainPerTick) {
|
||||
matter.extractMatterInner(drainPerTick, false)
|
||||
return Status.SUCCESS
|
||||
} else {
|
||||
// :(
|
||||
return WorkerJobStatus(false, 200)
|
||||
return Status.FAILURE_WAIT
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// в машине достаточно материи
|
||||
matter.extractMatterInner(drainPerTick, false)
|
||||
return WorkerJobStatus()
|
||||
return Status.SUCCESS
|
||||
}
|
||||
|
||||
override fun saveAdditional(nbt: CompoundTag) {
|
||||
@ -191,10 +239,7 @@ class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||
override fun load(nbt: CompoundTag) {
|
||||
super.load(nbt)
|
||||
container.deserializeNBT(nbt["container"])
|
||||
|
||||
nbt.ifHas("matter", CompoundTag::class.java) {
|
||||
matter.deserializeNBT(it)
|
||||
}
|
||||
nbt.map("matter", matter::deserializeNBT)
|
||||
}
|
||||
|
||||
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> {
|
||||
if (valid) {
|
||||
if (cap === MatteryCapability.MATTER_NODE) return resolverNode.cast()
|
||||
if (cap === CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return itemHandler.get().cast()
|
||||
if (cap == MatteryCapability.MATTER_NODE) return resolverNode.cast()
|
||||
if (cap == ForgeCapabilities.ITEM_HANDLER) return itemHandler.get().cast()
|
||||
}
|
||||
|
||||
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.block.state.BlockState
|
||||
import net.minecraftforge.common.capabilities.Capability
|
||||
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
||||
import net.minecraftforge.common.util.LazyOptional
|
||||
import net.minecraftforge.items.CapabilityItemHandler
|
||||
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.core.TranslatableComponent
|
||||
import ru.dbotthepony.mc.otm.block.entity.MatteryWorkerBlockEntity
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||
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.container.MatteryContainer
|
||||
import ru.dbotthepony.mc.otm.container.MatteryContainerFilter
|
||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
||||
@ -32,26 +32,38 @@ import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||
import java.util.*
|
||||
|
||||
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)
|
||||
override val energy = WorkerEnergyStorage(this, STORAGE, MAX_IO)
|
||||
private val itemHandler = container.handler(
|
||||
{ _: Int, stack: ItemStack -> canDecompose(stack) },
|
||||
{ _: Int, _: Int, _: ItemStack -> isIdling }
|
||||
)
|
||||
val container = MatteryContainer(this::itemContainerUpdated, 1)
|
||||
override val energy = WorkerEnergyStorage(this::powerLevelUpdated, STORAGE, MAX_IO)
|
||||
|
||||
private val itemHandler = container.handler(object : MatteryContainerFilter {
|
||||
override fun canInsert(slot: Int, stack: ItemStack): Boolean {
|
||||
return canDecompose(stack)
|
||||
}
|
||||
|
||||
override fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean {
|
||||
return isIdling
|
||||
}
|
||||
})
|
||||
|
||||
// IMatterGraphNode
|
||||
override fun onPatternAdded(state: PatternState) {
|
||||
isIdling = false
|
||||
override fun onPatternAdded(state: IPatternState) {
|
||||
if (idleReason == IdleReason.OBSERVING) {
|
||||
isIdling = false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPatternRemoved(state: PatternState) {
|
||||
isIdling = false
|
||||
override fun onPatternRemoved(state: IPatternState) {
|
||||
if (idleReason == IdleReason.OBSERVING) {
|
||||
isIdling = false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPatternUpdated(new_state: PatternState, old_state: PatternState) {
|
||||
isIdling = false
|
||||
override fun onPatternUpdated(newState: IPatternState, oldState: IPatternState) {
|
||||
if (idleReason == IdleReason.OBSERVING) {
|
||||
isIdling = false
|
||||
}
|
||||
}
|
||||
// /IMatterGraphNode
|
||||
|
||||
@ -61,7 +73,7 @@ class MatterScannerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||
|
||||
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
||||
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()
|
||||
}
|
||||
|
||||
@ -105,72 +117,71 @@ class MatterScannerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||
super.load(nbt)
|
||||
}
|
||||
|
||||
override fun onJobFinish(job: WorkerJob): WorkerJobStatus {
|
||||
val grid = matterNode.graph as MatterNetworkGraph? ?: return WorkerJobStatus(false, 100)
|
||||
override fun onJobFinish(job: ItemJob): Status {
|
||||
val grid = matterNode.graph as MatterNetworkGraph? ?: return Status.FAILURE_WAIT
|
||||
|
||||
val stack = job.stack
|
||||
if (stack.isEmpty || !hasMatterValue(stack)) return WorkerJobStatus()
|
||||
val stack = job.itemStack
|
||||
if (stack.isEmpty || !hasMatterValue(stack)) return Status.SUCCESS
|
||||
|
||||
val getState = grid.findPatterns(stack.item)
|
||||
var findState: PatternState? = null
|
||||
var findState: IPatternState? = null
|
||||
|
||||
for (state in getState) {
|
||||
if (state.item() === stack.item) {
|
||||
if (findState == null && state.research() < 1.0) {
|
||||
findState = state
|
||||
} else if (findState != null && findState.research() < state.research()) {
|
||||
findState = state
|
||||
}
|
||||
for (state in grid.patterns.filter { it.item === stack.item }) {
|
||||
if (findState == null && state.researchPercent < 1.0) {
|
||||
findState = state
|
||||
} else if (findState != null && findState.researchPercent < state.researchPercent) {
|
||||
findState = state
|
||||
}
|
||||
}
|
||||
|
||||
val new =
|
||||
if (findState != null) {
|
||||
PatternState(findState.id(), stack.item, findState.research() + 0.2)
|
||||
PatternState(findState.id, stack.item, findState.researchPercent + 0.2)
|
||||
} else {
|
||||
PatternState(UUID.randomUUID(), stack.item, 0.2)
|
||||
}
|
||||
|
||||
if (!grid.insertPattern(new, onlyUpdate = false, simulate = false).isFailed) {
|
||||
return WorkerJobStatus()
|
||||
return Status.SUCCESS
|
||||
} else {
|
||||
return WorkerJobStatus(false, 200)
|
||||
return Status.FAILURE_WAIT
|
||||
}
|
||||
}
|
||||
|
||||
override fun computeNextJob(): WorkerJob? {
|
||||
val grid = matterNode.graph as MatterNetworkGraph? ?: return null
|
||||
override fun computeNextJob(): Pair<ItemJob?, IdleReason?> {
|
||||
if (energy.batteryLevel.isZero) {
|
||||
return null to IdleReason.POWER
|
||||
}
|
||||
|
||||
val grid = matterNode.graph as MatterNetworkGraph? ?: return null to null
|
||||
|
||||
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: PatternState? = null
|
||||
var findState: IPatternState? = null
|
||||
|
||||
for (state in getState) {
|
||||
if (state.item === stack.item && state.research < 1.0) {
|
||||
for (state in grid.patterns.filter { it.item === stack.item }) {
|
||||
if (state.researchPercent < 1.0) {
|
||||
findState = state
|
||||
} else if (state.item === stack.item && state.research >= 1.0) {
|
||||
return null
|
||||
} else if (state.researchPercent >= 1.0) {
|
||||
return null to IdleReason.ITEM
|
||||
}
|
||||
}
|
||||
|
||||
val new: PatternState =
|
||||
val new: IPatternState =
|
||||
if (findState != null) {
|
||||
PatternState(findState.id, stack.item, findState.research + 0.2)
|
||||
PatternState(findState.id, stack.item, findState.researchPercent + 0.2)
|
||||
} else {
|
||||
PatternState(UUID.randomUUID(), stack.item, 0.2)
|
||||
}
|
||||
|
||||
if (!grid.insertPattern(new, onlyUpdate = false, simulate = true).isFailed) {
|
||||
val copy = stack.copy()
|
||||
copy.count = 1
|
||||
val copy = stack.copy().also { it.count = 1 }
|
||||
stack.shrink(1)
|
||||
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) {
|
||||
|
@ -13,16 +13,17 @@ import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraftforge.common.capabilities.Capability
|
||||
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.graph.storage.BasicStorageGraphNode
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
|
||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||
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.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.registry.MBlockEntities
|
||||
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.state.BlockState
|
||||
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.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.WorkerEnergyStorage
|
||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||
import ru.dbotthepony.mc.otm.menu.DriveViewerMenu
|
||||
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
|
||||
|
||||
@MethodsReturnNonnullByDefault
|
||||
|
@ -26,26 +26,26 @@ import net.minecraftforge.common.util.INBTSerializable
|
||||
import net.minecraftforge.common.util.LazyOptional
|
||||
import net.minecraftforge.network.NetworkEvent
|
||||
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.capability.MatteryCapability
|
||||
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
|
||||
import ru.dbotthepony.mc.otm.client.minecraft
|
||||
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.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.network.MatteryPacket
|
||||
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 java.math.BigInteger
|
||||
import java.util.*
|
||||
import java.util.function.Supplier
|
||||
import kotlin.collections.HashMap
|
||||
import kotlin.collections.HashSet
|
||||
|
||||
class ItemMonitorPlayerSettings : INBTSerializable<CompoundTag>, MatteryPacket {
|
||||
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 getItem(p_18941_: Int): ItemStack {
|
||||
require(p_18941_ == 1) { "Invalid slot ID: $p_18941_" }
|
||||
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 {
|
||||
// return removeItem(p_18951_, craftingRecipe?.resultItem?.count ?: Int.MAX_VALUE)
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
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() {}
|
||||
|
@ -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.WorkerEnergyStorage
|
||||
import ru.dbotthepony.mc.otm.container.ItemFilter
|
||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||
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.core.*
|
||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||
import ru.dbotthepony.mc.otm.graph.GraphNodeListener
|
||||
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.capability.*
|
||||
import ru.dbotthepony.mc.otm.container.ItemFilter
|
||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||
import ru.dbotthepony.mc.otm.core.plus
|
||||
import ru.dbotthepony.mc.otm.core.*
|
||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||
import ru.dbotthepony.mc.otm.graph.GraphNodeListener
|
||||
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.util.LazyOptional
|
||||
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.capability.MatteryCapability
|
||||
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.registry.MBlockEntities
|
||||
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) {
|
||||
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.VoxelShape
|
||||
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.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.VoxelShape
|
||||
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.shapes.BlockShapes
|
||||
|
||||
|
@ -15,7 +15,7 @@ import net.minecraft.world.phys.shapes.CollisionContext
|
||||
import net.minecraft.world.phys.shapes.VoxelShape
|
||||
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
|
||||
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.shapes.BlockShapes
|
||||
|
||||
|
@ -15,7 +15,7 @@ import net.minecraft.world.phys.shapes.CollisionContext
|
||||
import net.minecraft.world.phys.shapes.VoxelShape
|
||||
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
|
||||
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.shapes.BlockShapes
|
||||
|
||||
|
@ -15,7 +15,7 @@ import net.minecraft.world.phys.shapes.CollisionContext
|
||||
import net.minecraft.world.phys.shapes.VoxelShape
|
||||
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
|
||||
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.shapes.BlockShapes
|
||||
|
||||
|
@ -17,7 +17,7 @@ import net.minecraft.world.phys.shapes.CollisionContext
|
||||
import net.minecraft.world.phys.shapes.VoxelShape
|
||||
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
|
||||
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.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.registry.MBlockEntities
|
||||
import ru.dbotthepony.mc.otm.shapes.BlockShapes
|
||||
import ru.dbotthepony.mc.otm.unaryMinus
|
||||
import ru.dbotthepony.mc.otm.core.unaryMinus
|
||||
|
||||
class StorageBusBlock : RotatableMatteryBlock(), EntityBlock {
|
||||
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.registry.MBlockEntities
|
||||
import ru.dbotthepony.mc.otm.shapes.BlockShapes
|
||||
import ru.dbotthepony.mc.otm.unaryMinus
|
||||
import ru.dbotthepony.mc.otm.core.unaryMinus
|
||||
|
||||
class StorageImporterBlock : RotatableMatteryBlock(), EntityBlock {
|
||||
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.util.INBTSerializable
|
||||
import net.minecraftforge.common.util.LazyOptional
|
||||
import net.minecraftforge.energy.CapabilityEnergy
|
||||
import ru.dbotthepony.mc.otm.compat.mekanism.MatteryToMekanismEnergyWrapper
|
||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||
import ru.dbotthepony.mc.otm.ifHas
|
||||
import ru.dbotthepony.mc.otm.set
|
||||
import ru.dbotthepony.mc.otm.tagNotNull
|
||||
import ru.dbotthepony.mc.otm.core.ifHas
|
||||
import ru.dbotthepony.mc.otm.container.set
|
||||
import ru.dbotthepony.mc.otm.core.set
|
||||
import ru.dbotthepony.mc.otm.core.tagNotNull
|
||||
|
||||
private enum class EnergyFlow {
|
||||
INPUT, OUTPUT, BI_DIRECTIONAL
|
||||
@ -47,9 +47,9 @@ sealed class ItemEnergyStorageImpl(
|
||||
protected set
|
||||
|
||||
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) {
|
||||
itemStack.tagNotNull.put("energy", value.serializeNBT())
|
||||
itemStack.tagNotNull.put(NBT_KEY, value.serializeNBT())
|
||||
}
|
||||
|
||||
override fun extractEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
|
||||
@ -127,6 +127,10 @@ sealed class ItemEnergyStorageImpl(
|
||||
override fun canReceive(): Boolean {
|
||||
return type != EnergyFlow.OUTPUT
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val NBT_KEY = "energy"
|
||||
}
|
||||
}
|
||||
|
||||
open class EnergyConsumerItem(stack: ItemStack, maxBatteryLevel: ImpreciseFraction, maxInput: ImpreciseFraction? = null, maxOutput: ImpreciseFraction? = maxInput)
|
||||
|
@ -1,7 +1,8 @@
|
||||
package ru.dbotthepony.mc.otm.capability
|
||||
|
||||
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.ICapabilityProvider
|
||||
import net.minecraftforge.common.util.LazyOptional
|
||||
@ -9,8 +10,10 @@ import net.minecraftforge.energy.IEnergyStorage
|
||||
import net.minecraftforge.fml.ModList
|
||||
import ru.dbotthepony.mc.otm.compat.mekanism.getMekanismEnergySided
|
||||
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.orNull
|
||||
import ru.dbotthepony.mc.otm.core.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)
|
||||
}
|
||||
|
||||
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 net.minecraft.ChatFormatting
|
||||
import net.minecraft.advancements.CriteriaTriggers
|
||||
import net.minecraft.core.Direction
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
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.AndroidResearchType
|
||||
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.network.*
|
||||
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
||||
@ -79,6 +78,10 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, IMatteryEn
|
||||
private set(value) {
|
||||
_exoSuitMenu = null
|
||||
|
||||
if (ply.containerMenu.slots.any { it.container == field }) {
|
||||
ply.closeContainer()
|
||||
}
|
||||
|
||||
for (i in 0 until value.containerSize.coerceAtMost(field.containerSize)) {
|
||||
if (!field[i].isEmpty) {
|
||||
value[i] = field[i]
|
||||
@ -627,7 +630,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, IMatteryEn
|
||||
shouldSendIteration = false
|
||||
}
|
||||
|
||||
if (hasExoSuit && ply.containerMenu != exoSuitMenu) {
|
||||
if (hasExoSuit && ply.containerMenu == ply.inventoryMenu) {
|
||||
exoSuitMenu.broadcastChanges()
|
||||
}
|
||||
|
||||
@ -762,10 +765,8 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, IMatteryEn
|
||||
|
||||
@Suppress("unused")
|
||||
companion object {
|
||||
@JvmField
|
||||
val UNAFFECTED_EFFECTS = ObjectArraySet<MobEffect>()
|
||||
|
||||
@JvmStatic
|
||||
fun registerEffects(event: FMLCommonSetupEvent) {
|
||||
UNAFFECTED_EFFECTS.add(MobEffects.CONDUIT_POWER)
|
||||
UNAFFECTED_EFFECTS.add(MobEffects.HEAL)
|
||||
@ -782,7 +783,6 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, IMatteryEn
|
||||
UNAFFECTED_EFFECTS.add(MobEffects.DOLPHINS_GRACE)
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
fun onLivingTick(event: LivingTickEvent) {
|
||||
val ent = event.entity
|
||||
|
||||
@ -797,7 +797,6 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, IMatteryEn
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.LOWEST)
|
||||
fun onHurtEvent(event: LivingHurtEvent) {
|
||||
if (event.isCanceled) {
|
||||
return
|
||||
@ -809,8 +808,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, IMatteryEn
|
||||
const val CAPABILITY_KEY = "otm_player"
|
||||
val CAPABILITY_LOCATION = ResourceLocation(OverdriveThatMatters.MOD_ID, CAPABILITY_KEY)
|
||||
|
||||
@SubscribeEvent
|
||||
fun onAttachCapabilityEvent(event: AttachCapabilitiesEvent<Entity?>) {
|
||||
fun onAttachCapabilityEvent(event: AttachCapabilitiesEvent<Entity>) {
|
||||
val ent = event.`object`
|
||||
|
||||
if (ent is Player) {
|
||||
@ -818,18 +816,12 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, IMatteryEn
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
fun onPlayerChangeDimensionEvent(event: PlayerEvent.PlayerChangedDimensionEvent) {
|
||||
event.entity.getCapability(MatteryCapability.MATTERY_PLAYER)
|
||||
.ifPresentK { it.invalidateNetworkState() }
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.LOWEST)
|
||||
fun onPlayerDeath(event: LivingDeathEvent) {
|
||||
if (event.isCanceled) {
|
||||
return
|
||||
}
|
||||
|
||||
val ply = event.entity as? Player ?: return
|
||||
val mattery = ply.matteryPlayer ?: return
|
||||
|
||||
@ -856,7 +848,6 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, IMatteryEn
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
fun onPlayerCloneEvent(event: PlayerEvent.Clone) {
|
||||
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>>()
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.LOW)
|
||||
fun onPickupEvent(event: EntityItemPickupEvent) {
|
||||
if (event.item.owner != null && event.item.owner != event.entity.uuid && event.item.age < 200 || event.item.item.isEmpty) {
|
||||
return
|
||||
|
@ -1,21 +1,14 @@
|
||||
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 kotlin.jvm.JvmOverloads
|
||||
import java.util.UUID
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.nbt.ListTag
|
||||
import net.minecraft.nbt.LongTag
|
||||
import net.minecraft.nbt.Tag
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import ru.dbotthepony.mc.otm.core.BigInteger
|
||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||
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.container.set
|
||||
import ru.dbotthepony.mc.otm.core.*
|
||||
import ru.dbotthepony.mc.otm.storage.*
|
||||
import java.math.BigInteger
|
||||
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,
|
||||
* which will be performance tanking due to clause 1.
|
||||
*/
|
||||
@Suppress("unused")
|
||||
object DrivePool {
|
||||
private val LOGGER = LogManager.getLogger()
|
||||
private val pool = Object2ObjectAVLTreeMap<UUID, WeakDriveReference>()
|
||||
@ -130,7 +129,6 @@ object DrivePool {
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.LOWEST)
|
||||
fun onServerPostTick(event: ServerTickEvent) {
|
||||
if (event.phase == TickEvent.Phase.END) {
|
||||
if (exception != null) {
|
||||
@ -152,7 +150,6 @@ object DrivePool {
|
||||
return Thread.currentThread() === serverThread
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGHEST)
|
||||
fun serverStartEvent(event: ServerAboutToStartEvent) {
|
||||
if (thread?.isAlive == true) {
|
||||
LOGGER.error("FMLServerStartedEvent fired twice.")
|
||||
@ -172,7 +169,6 @@ object DrivePool {
|
||||
thread = Thread(null, this::thread, "Overdrive That Matters DrivePool IO").also { it.start() }
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGHEST)
|
||||
fun serverStopEvent(event: ServerStoppingEvent) {
|
||||
val thread = thread
|
||||
|
||||
@ -189,7 +185,6 @@ object DrivePool {
|
||||
pool.clear()
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
fun onWorldSave(event: LevelEvent.Save) {
|
||||
writeBacklog()
|
||||
}
|
||||
|
@ -6,12 +6,11 @@ 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.RegistryManager
|
||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||
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.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.ItemStackWrapper
|
||||
import ru.dbotthepony.mc.otm.storage.StorageStackType
|
||||
|
@ -5,6 +5,7 @@ import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||
import java.util.*
|
||||
import java.util.function.Predicate
|
||||
import java.util.stream.Collectors
|
||||
import java.util.stream.Stream
|
||||
|
||||
interface IMatterHandler {
|
||||
val storedMatter: ImpreciseFraction
|
||||
@ -14,6 +15,7 @@ interface IMatterHandler {
|
||||
fun receiveMatterInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction
|
||||
fun extractMatterOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction
|
||||
fun extractMatterInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction
|
||||
|
||||
val direction: MatterDirection
|
||||
val missingMatter: ImpreciseFraction
|
||||
get() = maxStoredMatter.minus(storedMatter).moreThanZero()
|
||||
@ -27,42 +29,44 @@ interface IMatterHandler {
|
||||
|
||||
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
|
||||
* by incrementing it's in_progress by 1
|
||||
* and shrinking required by 1
|
||||
* by incrementing it's [IReplicationTask.inProgress] 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
|
||||
* @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
|
||||
* shrink in_progress by 1
|
||||
* 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
|
||||
*/
|
||||
fun notifyTaskCompletion(task: MatterTask): Boolean
|
||||
fun notifyTaskCompletion(taskId: UUID): Boolean
|
||||
|
||||
/**
|
||||
* @param id uuid of task
|
||||
* @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
|
||||
@ -72,50 +76,36 @@ interface IMatterTaskProvider {
|
||||
|
||||
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> {
|
||||
return findPatterns { item2: PatternState -> item == item2.item() }
|
||||
fun findPatterns(item: Item): Collection<IPatternState> {
|
||||
return findPatterns { item == it.item }
|
||||
}
|
||||
|
||||
fun findPatterns(predicate: Predicate<PatternState>?): Collection<PatternState> {
|
||||
return storedPatterns.stream().filter(predicate).collect(Collectors.toList())
|
||||
fun findPatterns(predicate: Predicate<IPatternState>): Collection<IPatternState> {
|
||||
return storedPatterns.filter(predicate).collect(Collectors.toList())
|
||||
}
|
||||
|
||||
fun findPattern(item: Item): PatternState? {
|
||||
return findPattern { item2: PatternState -> item == item2.item() }
|
||||
fun findPattern(item: Item): IPatternState? {
|
||||
return storedPatterns.filter { it.item == item }.findAny().orElse(null)
|
||||
}
|
||||
|
||||
fun findPattern(predicate: Predicate<PatternState>): PatternState? {
|
||||
for (pattern in storedPatterns) {
|
||||
if (predicate.test(pattern)) {
|
||||
return pattern
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
fun getPattern(id: UUID?): IPatternState? {
|
||||
return storedPatterns.filter { it.id == id }.findAny().orElse(null)
|
||||
}
|
||||
|
||||
fun getPattern(id: UUID?): PatternState? {
|
||||
id ?: return null
|
||||
|
||||
for (pattern in storedPatterns) {
|
||||
if (pattern.id == id) {
|
||||
return pattern
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
fun hasPattern(item: Item): Boolean {
|
||||
return storedPatterns.filter { it.item == item }.findAny().isPresent
|
||||
}
|
||||
|
||||
fun hasPattern(state: PatternState): Boolean {
|
||||
return getPattern(state.id) != null
|
||||
fun hasPattern(state: IPatternState): Boolean {
|
||||
return hasPattern(state.id)
|
||||
}
|
||||
|
||||
fun hasPattern(id: UUID?): Boolean {
|
||||
return getPattern(id) != null
|
||||
return storedPatterns.filter { it.id == id }.findAny().isPresent
|
||||
}
|
||||
|
||||
val capacity: Int
|
||||
@ -126,17 +116,17 @@ interface IPatternStorage {
|
||||
* and if it fail, try only_update = false
|
||||
*
|
||||
* @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
|
||||
* @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)
|
||||
}
|
||||
|
||||
fun updatePattern(pattern: PatternState, simulate: Boolean): PatternInsertStatus {
|
||||
fun updatePattern(pattern: IPatternState, simulate: Boolean): PatternInsertStatus {
|
||||
return insertPattern(pattern, true, simulate)
|
||||
}
|
||||
}
|
||||
|
@ -8,17 +8,17 @@ private enum class PatternInsertResult {
|
||||
|
||||
sealed class PatternInsertStatus(
|
||||
private val status: PatternInsertResult,
|
||||
val newState: PatternState?,
|
||||
val oldState: PatternState?
|
||||
val newState: IPatternState?,
|
||||
val oldState: IPatternState?
|
||||
) {
|
||||
val isFailed get() = status === PatternInsertResult.FAIL
|
||||
val isUpdated get() = status === PatternInsertResult.UPDATED
|
||||
val isInserted get() = status === PatternInsertResult.INSERTED
|
||||
val isFailed get() = status == PatternInsertResult.FAIL
|
||||
val isUpdated get() = status == PatternInsertResult.UPDATED
|
||||
val isInserted get() = status == PatternInsertResult.INSERTED
|
||||
}
|
||||
|
||||
object PatternInsertFailure : PatternInsertStatus(PatternInsertResult.FAIL, null, null)
|
||||
class PatternInsertUpdated(new: PatternState, old: PatternState) : PatternInsertStatus(PatternInsertResult.UPDATED, new, old)
|
||||
class PatternInsertInserted(new: PatternState) : PatternInsertStatus(PatternInsertResult.INSERTED, new, null)
|
||||
class PatternInsertUpdated(new: IPatternState, old: IPatternState) : PatternInsertStatus(PatternInsertResult.UPDATED, new, old)
|
||||
class PatternInsertInserted(new: IPatternState) : PatternInsertStatus(PatternInsertResult.INSERTED, new, null)
|
||||
|
||||
@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.LazyOptional
|
||||
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(
|
||||
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.gui.Font
|
||||
import net.minecraft.client.resources.sounds.SimpleSoundInstance
|
||||
import net.minecraft.sounds.SoundEvents
|
||||
|
||||
inline val minecraft: Minecraft get() = Minecraft.getInstance()
|
||||
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.SubscribeEvent
|
||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||
import ru.dbotthepony.mc.otm.TextComponent
|
||||
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.MatteryPlayerCapability
|
||||
import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
||||
import ru.dbotthepony.mc.otm.client.render.*
|
||||
import ru.dbotthepony.mc.otm.core.RGBAColor
|
||||
import ru.dbotthepony.mc.otm.ifPresentK
|
||||
import ru.dbotthepony.mc.otm.core.ifPresentK
|
||||
import java.util.*
|
||||
|
||||
object MatteryGUI {
|
||||
@ -40,8 +39,6 @@ object MatteryGUI {
|
||||
|
||||
private val button_shaker = Random()
|
||||
|
||||
@SubscribeEvent
|
||||
@Suppress("unused")
|
||||
fun onScreenRender(event: ScreenEvent.Render.Pre) {
|
||||
if (knownButtonScreen != null && knownButton == null) {
|
||||
for (widget in knownButtonScreen!!.renderables) {
|
||||
@ -88,8 +85,6 @@ object MatteryGUI {
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.LOWEST)
|
||||
@Suppress("unused")
|
||||
fun onOpenGUIEvent(event: ScreenEvent.Opening) {
|
||||
knownButtonX = -1
|
||||
knownButtonY = -1
|
||||
@ -199,14 +194,10 @@ object MatteryGUI {
|
||||
popScissorRect()
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
@Suppress("unused")
|
||||
fun onRenderGuiEvent(event: RenderGuiEvent.Post) {
|
||||
showIteration(event)
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
@Suppress("unused")
|
||||
fun onLayerRenderEvent(event: RenderGuiOverlayEvent.Pre) {
|
||||
if (event.overlay != FOOD_LEVEL_ELEMENT && event.overlay != AIR_LEVEL_ELEMENT) {
|
||||
return
|
||||
|
@ -11,7 +11,7 @@ import net.minecraft.client.renderer.blockentity.BlockEntityRenderer
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider
|
||||
import net.minecraft.world.phys.Vec3
|
||||
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.blackhole.BlackHoleBlockEntity
|
||||
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.BlockEntityRendererProvider
|
||||
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.entity.EnergyCounterBlockEntity
|
||||
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.texture.OverlayTexture
|
||||
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.RotatableMatteryBlock
|
||||
import ru.dbotthepony.mc.otm.block.entity.GravitationStabilizerBlockEntity
|
||||
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.core.*
|
||||
import kotlin.math.PI
|
||||
|
@ -7,16 +7,14 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectFunction
|
||||
import net.minecraft.ChatFormatting
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.resources.sounds.SimpleSoundInstance
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.sounds.SoundEvents
|
||||
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.AndroidResearchType
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
|
||||
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.drawColor
|
||||
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.widget.WidePowerGaugePanel
|
||||
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.network.MatteryPlayerNetworkChannel
|
||||
import ru.dbotthepony.mc.otm.network.AndroidResearchRequestPacket
|
||||
@ -383,7 +381,7 @@ private class AndroidResearchButton(
|
||||
MatteryPlayerNetworkChannel.sendToServer(AndroidResearchRequestPacket(node.type))
|
||||
}
|
||||
|
||||
minecraft.soundManager.play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0f))
|
||||
playGuiClickSound()
|
||||
}
|
||||
|
||||
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 {
|
||||
if (isPreview) {
|
||||
playGuiClickSound()
|
||||
openResearchTree()
|
||||
return true
|
||||
}
|
||||
|
@ -2,9 +2,8 @@ package ru.dbotthepony.mc.otm.client.screen
|
||||
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
import ru.dbotthepony.mc.otm.TranslatableComponent
|
||||
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||
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.WidePowerGaugePanel
|
||||
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.world.entity.player.Inventory
|
||||
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.widget.PowerGaugePanel
|
||||
import ru.dbotthepony.mc.otm.core.maxScrollDivision
|
||||
import ru.dbotthepony.mc.otm.item.PortableCondensationDriveItem
|
||||
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 scrollBar = ContinuousScrollBarPanel(this, frame, 192f, 14f, 92f)
|
||||
scrollBar.setupRowMultiplier { menu.networkedItemView.itemCount / GRID_WIDTH }
|
||||
val scrollBar = DiscreteScrollBarPanel(this, frame, { maxScrollDivision(menu.networkedItemView.itemCount, GRID_WIDTH) }, { _, _, _ -> }, 192f, 14f, 92f)
|
||||
|
||||
views.add(grid)
|
||||
views.add(scrollBar)
|
||||
|
||||
for (i in 0 until GRID_WIDTH * GRID_HEIGHT) {
|
||||
object : AbstractSlotPanel(this@DriveViewerScreen, grid, 0f, 0f) {
|
||||
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
|
||||
}
|
||||
|
||||
@ -68,7 +69,7 @@ class DriveViewerScreen(menu: DriveViewerMenu, inventory: Inventory, title: Comp
|
||||
}
|
||||
|
||||
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)
|
||||
return true
|
||||
}
|
||||
@ -81,7 +82,7 @@ class DriveViewerScreen(menu: DriveViewerMenu, inventory: Inventory, title: Comp
|
||||
override fun getItemStackTooltip(stack: ItemStack): List<Component> {
|
||||
return super.getItemStackTooltip(stack).also {
|
||||
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
|
||||
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.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.core.formatPower
|
||||
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 it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectFunction
|
||||
import net.minecraft.client.gui.screens.inventory.InventoryScreen
|
||||
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.screen.panels.*
|
||||
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
|
||||
|
||||
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 {
|
||||
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
|
||||
|
||||
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 = {
|
||||
_, old, new ->
|
||||
|
||||
for (i in old .. old + 2) {
|
||||
getSlotsRow(i).visible = false
|
||||
getInventorySlotsRow(i).visible = false
|
||||
}
|
||||
|
||||
for (i in new .. new + 2) {
|
||||
val row = getSlotsRow(i)
|
||||
val row = getInventorySlotsRow(i)
|
||||
row.visible = true
|
||||
row.y = (i - new) * AbstractSlotPanel.SIZE
|
||||
row.parent = mainInventoryLine
|
||||
@ -83,7 +52,7 @@ class ExoSuitInventoryScreen(menu: ExoSuitInventoryMenu) : MatteryScreen<ExoSuit
|
||||
|
||||
mainInventoryLine.dock = Dock.BOTTOM
|
||||
|
||||
for (slot in menu.hotbarSlots) {
|
||||
for (slot in menu.playerHotbarSlots) {
|
||||
val panel = SlotPanel(this, toolbeltLine, slot)
|
||||
panel.dock = Dock.LEFT
|
||||
}
|
||||
@ -92,7 +61,7 @@ class ExoSuitInventoryScreen(menu: ExoSuitInventoryMenu) : MatteryScreen<ExoSuit
|
||||
offhand.dock = Dock.RIGHT
|
||||
|
||||
for (i in scrollPanel.scroll .. scrollPanel.scroll + 2) {
|
||||
getSlotsRow(i).also {
|
||||
getInventorySlotsRow(i).also {
|
||||
it.parent = mainInventoryLine
|
||||
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.Items
|
||||
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.client.render.UVWindingOrder
|
||||
import ru.dbotthepony.mc.otm.client.render.Widgets8
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
||||
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.formatSiComponent
|
||||
import ru.dbotthepony.mc.otm.menu.ItemMonitorMenu
|
||||
@ -24,7 +25,7 @@ class ItemMonitorScreen(menu: ItemMonitorMenu, inventory: Inventory, title: Comp
|
||||
MatteryScreen<ItemMonitorMenu>(menu, inventory, title) {
|
||||
|
||||
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)
|
||||
topPanel.height = ITEM_GRID_HEIGHT * 18f
|
||||
@ -35,11 +36,13 @@ class ItemMonitorScreen(menu: ItemMonitorMenu, inventory: Inventory, title: Comp
|
||||
bottomPanel.dock = Dock.TOP
|
||||
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
|
||||
|
||||
val viewScrollBar = ContinuousScrollBarPanel(this, topPanel, 28f + ITEM_GRID_WIDTH * 18f + 2f, 16f, ITEM_GRID_HEIGHT * 18f)
|
||||
viewScrollBar.setupRowMultiplier { equalDownDivision(menu.networkedItemView.itemCount, ITEM_GRID_WIDTH) }
|
||||
val viewScrollBar = DiscreteScrollBarPanel(this, topPanel,
|
||||
{ maxScrollDivision(menu.networkedItemView.itemCount, ITEM_GRID_WIDTH) },
|
||||
{ _, _, _ -> },
|
||||
28f + ITEM_GRID_WIDTH * 18f + 2f, 16f, ITEM_GRID_HEIGHT * 18f)
|
||||
|
||||
viewScrollBar.dock = Dock.RIGHT
|
||||
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) {
|
||||
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 {
|
||||
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.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)
|
||||
|
||||
@ -168,7 +171,7 @@ class ItemMonitorScreen(menu: ItemMonitorMenu, inventory: Inventory, title: Comp
|
||||
craftingHistory.dock = Dock.LEFT
|
||||
craftingHistory.setDockMargin(left = 4f)
|
||||
|
||||
val craftingHistoryScroll = ContinuousScrollBarPanel(this, bottomPanel, 0f, 0f, 0f)
|
||||
val craftingHistoryScroll = DiscreteScrollBarPanel(this, bottomPanel, { 0 }, { _, _, _ -> })
|
||||
craftingHistoryScroll.dock = Dock.LEFT
|
||||
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
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val FRAME_WIDTH = 240f
|
||||
const val FRAME_HEIGHT = 210f
|
||||
|
||||
const val ITEM_GRID_WIDTH = 9
|
||||
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.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.widget.MatterGaugePanel
|
||||
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.vertex.PoseStack
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectFunction
|
||||
import net.minecraft.ChatFormatting
|
||||
import net.minecraft.client.gui.Font
|
||||
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 org.lwjgl.opengl.GL11
|
||||
import org.lwjgl.opengl.GL13
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.SlotPanel
|
||||
import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
||||
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 isQuickCrafting get() = isQuickCrafting
|
||||
|
||||
private val inventorySlotsRows = Int2ObjectAVLTreeMap<EditablePanel>()
|
||||
|
||||
init {
|
||||
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) {
|
||||
SlotPanel(this, inventoryFrame, slot, slot.x.toFloat(), slot.y.toFloat())
|
||||
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 }
|
||||
}
|
||||
|
||||
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() {
|
||||
super.init()
|
||||
|
||||
@ -102,7 +195,7 @@ abstract class MatteryScreen<T : MatteryMenu>(menu: T, inventory: Inventory, tit
|
||||
|
||||
require(indexOf != -1) { "No such panel $panel" }
|
||||
|
||||
if (indexOf == panels.size - 1) {
|
||||
if (indexOf == 0) {
|
||||
return
|
||||
}
|
||||
|
||||
@ -354,10 +447,13 @@ abstract class MatteryScreen<T : MatteryMenu>(menu: T, inventory: Inventory, tit
|
||||
}
|
||||
|
||||
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 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_WITHOUT_SLOT = 26f
|
||||
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.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.widget.PowerGaugePanel
|
||||
import ru.dbotthepony.mc.otm.client.screen.widget.WidePowerGaugePanel
|
||||
|
||||
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.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.widget.PowerGaugePanel
|
||||
import ru.dbotthepony.mc.otm.client.screen.widget.WidePowerGaugePanel
|
||||
|
||||
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.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.widget.PowerGaugePanel
|
||||
import ru.dbotthepony.mc.otm.client.screen.widget.WidePowerGaugePanel
|
||||
|
||||
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.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.widget.PowerGaugePanel
|
||||
import ru.dbotthepony.mc.otm.client.screen.widget.WidePowerGaugePanel
|
||||
import ru.dbotthepony.mc.otm.client.screen.widget.HorizontalPowerGaugePanel
|
||||
import ru.dbotthepony.mc.otm.core.formatPower
|
||||
|
||||
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) :
|
||||
MatteryScreen<StoragePowerSupplierMenu>(menu, inventory, title) {
|
||||
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)
|
||||
BatterySlotPanel(this, frame, menu.batterySlot, LEFT_MARGIN, SLOT_TOP_UNDER_GAUGE)
|
||||
HorizontalPowerGaugePanel(this, frame, menu.powerWidget).also {
|
||||
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() {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@ -23,9 +23,8 @@ abstract class AbstractSlotPanel @JvmOverloads constructor(
|
||||
) : EditablePanel(
|
||||
screen, parent, x, y, width, height
|
||||
) {
|
||||
protected open fun renderSlotBackground(stack: PoseStack, mouse_x: Float, mouse_y: Float, flag: Float) {
|
||||
RenderSystem.setShaderTexture(0, WidgetLocation.WIDGETS)
|
||||
drawTexturedRectAuto(stack, 0f, 0f, 18f, 18f, 0f, 96f, 256f, 256f)
|
||||
protected open fun renderSlotBackground(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) {
|
||||
SLOT_BACKGROUND.render(stack, width = width, height = height)
|
||||
}
|
||||
|
||||
protected open fun renderRegular(stack: PoseStack, itemstack: ItemStack, count_override: String? = null) {
|
||||
@ -119,10 +118,9 @@ abstract class AbstractSlotPanel @JvmOverloads constructor(
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
val SLOT_HIGHLIGHT = RGBAColor(255, 255, 255, 100)
|
||||
@JvmField
|
||||
val SLOT_HIGHLIGHT_DRAG = RGBAColor(200, 200, 200, 150)
|
||||
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.client.gui.components.Button
|
||||
import net.minecraft.client.gui.components.Button.OnPress
|
||||
import net.minecraft.client.resources.sounds.SimpleSoundInstance
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.sounds.SoundEvents
|
||||
import ru.dbotthepony.mc.otm.TextComponent
|
||||
import ru.dbotthepony.mc.otm.client.minecraft
|
||||
import ru.dbotthepony.mc.otm.client.playGuiClickSound
|
||||
import ru.dbotthepony.mc.otm.core.TextComponent
|
||||
import ru.dbotthepony.mc.otm.client.render.*
|
||||
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
|
||||
import ru.dbotthepony.mc.otm.next
|
||||
import ru.dbotthepony.mc.otm.prev
|
||||
import ru.dbotthepony.mc.otm.core.next
|
||||
import ru.dbotthepony.mc.otm.core.prev
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.reflect.KMutableProperty0
|
||||
@ -24,10 +22,22 @@ open class ButtonPanel(
|
||||
x: Float = 0f,
|
||||
y: Float = 0f,
|
||||
width: Float = 40f,
|
||||
height: Float = 20f,
|
||||
height: Float = HEIGHT,
|
||||
label: Component
|
||||
) : 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?,
|
||||
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
|
||||
set(value) {
|
||||
@ -55,6 +65,10 @@ open class ButtonPanel(
|
||||
protected open fun onPress() {
|
||||
callback?.run()
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val HEIGHT = 20f
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("PropertyName")
|
||||
@ -105,7 +119,7 @@ abstract class SquareButtonPanel(
|
||||
override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean {
|
||||
if (!isDisabled) {
|
||||
if (!pressed) {
|
||||
minecraft.soundManager.play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0f))
|
||||
playGuiClickSound()
|
||||
}
|
||||
|
||||
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